aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml34
-rw-r--r--.eslintrc1
-rw-r--r--.gitignore1
-rw-r--r--.jshintrc27
-rw-r--r--CHANGELOG.md29
-rw-r--r--CONTRIBUTING.md6
-rw-r--r--README.md2
-rw-r--r--app/_locales/cs/messages.json912
-rw-r--r--app/_locales/en/messages.json32
-rw-r--r--app/_locales/hn/messages.json20
-rw-r--r--app/_locales/index.json3
-rw-r--r--app/_locales/ja/messages.json99
-rw-r--r--app/_locales/sl/messages.json8
-rw-r--r--app/_locales/tml/messages.json912
-rw-r--r--app/_locales/tr/messages.json912
-rw-r--r--app/images/copy-to-clipboard.svg24
-rw-r--r--app/images/download.svg41
-rw-r--r--app/images/warning.svg22
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/background.js255
-rw-r--r--app/scripts/config.js44
-rw-r--r--app/scripts/contentscript.js43
-rw-r--r--app/scripts/controllers/address-book.js66
-rw-r--r--app/scripts/controllers/balance.js56
-rw-r--r--app/scripts/controllers/blacklist.js54
-rw-r--r--app/scripts/controllers/computed-balances.js45
-rw-r--r--app/scripts/controllers/currency.js68
-rw-r--r--app/scripts/controllers/infura.js1
-rw-r--r--app/scripts/controllers/network/enums.js56
-rw-r--r--app/scripts/controllers/network/index.js2
-rw-r--r--app/scripts/controllers/network/network.js (renamed from app/scripts/controllers/network.js)30
-rw-r--r--app/scripts/controllers/network/util.js65
-rw-r--r--app/scripts/controllers/preferences.js124
-rw-r--r--app/scripts/controllers/recent-blocks.js69
-rw-r--r--app/scripts/controllers/shapeshift.js75
-rw-r--r--app/scripts/controllers/token-rates.js81
-rw-r--r--app/scripts/controllers/transactions/README.md92
-rw-r--r--app/scripts/controllers/transactions/index.js (renamed from app/scripts/controllers/transactions.js)318
-rw-r--r--app/scripts/controllers/transactions/lib/tx-state-history-helper.js (renamed from app/scripts/lib/tx-state-history-helper.js)27
-rw-r--r--app/scripts/controllers/transactions/lib/util.js99
-rw-r--r--app/scripts/controllers/transactions/nonce-tracker.js (renamed from app/scripts/lib/nonce-tracker.js)44
-rw-r--r--app/scripts/controllers/transactions/pending-tx-tracker.js (renamed from app/scripts/lib/pending-tx-tracker.js)77
-rw-r--r--app/scripts/controllers/transactions/tx-gas-utils.js (renamed from app/scripts/lib/tx-gas-utils.js)69
-rw-r--r--app/scripts/controllers/transactions/tx-state-manager.js (renamed from app/scripts/lib/tx-state-manager.js)217
-rw-r--r--app/scripts/edge-encryptor.js142
-rw-r--r--app/scripts/first-time-state.js19
-rw-r--r--app/scripts/inpage.js20
-rw-r--r--app/scripts/lib/ComposableObservableStore.js49
-rw-r--r--app/scripts/lib/account-tracker.js81
-rw-r--r--app/scripts/lib/buy-eth-url.js11
-rw-r--r--app/scripts/lib/config-manager.js23
-rw-r--r--app/scripts/lib/createLoggerMiddleware.js16
-rw-r--r--app/scripts/lib/createOriginMiddleware.js12
-rw-r--r--app/scripts/lib/createProviderMiddleware.js6
-rw-r--r--app/scripts/lib/enums.js9
-rw-r--r--app/scripts/lib/environment-type.js10
-rw-r--r--app/scripts/lib/events-proxy.js25
-rw-r--r--app/scripts/lib/extractEthjsErrorMessage.js23
-rw-r--r--app/scripts/lib/get-first-preferred-lang-code.js13
-rw-r--r--app/scripts/lib/getObjStructure.js50
-rw-r--r--app/scripts/lib/hex-to-bn.js7
-rw-r--r--app/scripts/lib/is-popup-or-notification.js11
-rw-r--r--app/scripts/lib/local-store.js38
-rw-r--r--app/scripts/lib/message-manager.js137
-rw-r--r--app/scripts/lib/migrator/index.js62
-rw-r--r--app/scripts/lib/nodeify.js8
-rw-r--r--app/scripts/lib/notification-manager.js44
-rw-r--r--app/scripts/lib/pending-balance-calculator.js38
-rw-r--r--app/scripts/lib/personal-message-manager.js143
-rw-r--r--app/scripts/lib/port-stream.js37
-rw-r--r--app/scripts/lib/seed-phrase-verifier.js19
-rw-r--r--app/scripts/lib/setupMetamaskMeshMetrics.js3
-rw-r--r--app/scripts/lib/setupRaven.js61
-rw-r--r--app/scripts/lib/stream-utils.js18
-rw-r--r--app/scripts/lib/typed-message-manager.js137
-rw-r--r--app/scripts/lib/util.js81
-rw-r--r--app/scripts/metamask-controller.js585
-rw-r--r--app/scripts/migrations/013.js7
-rw-r--r--app/scripts/migrations/015.js15
-rw-r--r--app/scripts/migrations/016.js22
-rw-r--r--app/scripts/migrations/017.js21
-rw-r--r--app/scripts/migrations/018.js41
-rw-r--r--app/scripts/migrations/019.js44
-rw-r--r--app/scripts/migrations/022.js17
-rw-r--r--app/scripts/migrations/023.js38
-rw-r--r--app/scripts/migrations/024.js41
-rw-r--r--app/scripts/migrations/025.js61
-rw-r--r--app/scripts/migrations/index.js2
-rw-r--r--app/scripts/migrations/template.js29
-rw-r--r--app/scripts/platforms/sw.js27
-rw-r--r--app/scripts/platforms/window.js23
-rw-r--r--app/scripts/popup-core.js25
-rw-r--r--app/scripts/ui.js8
-rw-r--r--development/mock-dev.js21
-rw-r--r--development/sourcemap-validator.js49
-rw-r--r--development/states/currency-localization.json134
-rw-r--r--development/states/tx-list-items.json (renamed from development/states/tx-list-items.js)0
-rw-r--r--development/tools/.jsdoc.json25
-rw-r--r--development/tools/README.md15
-rw-r--r--development/tools/appveyor.txt21
-rw-r--r--docs/QA_Guide.md48
-rw-r--r--docs/team.md78
-rw-r--r--docs/transaction-flow.pngbin0 -> 141125 bytes
-rw-r--r--gulpfile.js22
-rw-r--r--mascara/src/app/first-time/confirm-seed-screen.js161
-rw-r--r--mascara/src/app/first-time/create-password-screen.js279
-rw-r--r--mascara/src/app/first-time/import-account-screen.js4
-rw-r--r--mascara/src/app/first-time/import-seed-phrase-screen.js17
-rw-r--r--mascara/src/app/first-time/index.js187
-rw-r--r--mascara/src/app/first-time/notice-screen.js105
-rw-r--r--mascara/src/app/first-time/seed-screen.js (renamed from mascara/src/app/first-time/backup-phrase-screen.js)147
-rw-r--r--mascara/src/app/first-time/unique-image-screen.js18
-rw-r--r--notices/archive/notice_2.md2
-rw-r--r--notices/notices.json2
-rw-r--r--old-ui/app/accounts/import/json.js2
-rw-r--r--old-ui/app/accounts/import/private-key.js2
-rw-r--r--old-ui/app/app.js3
-rw-r--r--old-ui/app/components/buy-button-subview.js4
-rw-r--r--old-ui/app/components/ens-input.js1
-rw-r--r--old-ui/app/components/pending-tx.js4
-rw-r--r--old-ui/app/components/shapeshift-form.js2
-rw-r--r--old-ui/app/components/token-list.js1
-rw-r--r--old-ui/app/conf-tx.js6
-rw-r--r--old-ui/app/util.js1
-rw-r--r--old-ui/lib/tx-helper.js1
-rw-r--r--package-lock.json6125
-rw-r--r--package.json43
-rw-r--r--test/integration/lib/confirm-sig-requests.js18
-rw-r--r--test/integration/lib/currency-localization.js28
-rw-r--r--test/integration/lib/mascara-first-time.js3
-rw-r--r--test/integration/lib/send-new-ui.js95
-rw-r--r--test/integration/lib/tx-list-items.js2
-rw-r--r--test/setup.js5
-rw-r--r--test/stub/provider.js24
-rw-r--r--test/unit/ComposableObservableStore.js35
-rw-r--r--test/unit/account-import-strategies.spec.js30
-rw-r--r--test/unit/balance-formatter-test.js27
-rw-r--r--test/unit/metamask-controller-test.js299
-rw-r--r--test/unit/migrations/024-test.js49
-rw-r--r--test/unit/migrations/025-test.js49
-rw-r--r--test/unit/migrations/template-test.js17
-rw-r--r--test/unit/migrator-test.js33
-rw-r--r--test/unit/network-contoller-test.js42
-rw-r--r--test/unit/nonce-tracker-test.js2
-rw-r--r--test/unit/pending-tx-test.js2
-rw-r--r--test/unit/token-rates-controller.js29
-rw-r--r--test/unit/tx-controller-test.js83
-rw-r--r--test/unit/tx-gas-util-test.js109
-rw-r--r--test/unit/tx-state-history-helper-test.js2
-rw-r--r--test/unit/tx-state-history-helper.js2
-rw-r--r--test/unit/tx-state-manager-test.js4
-rw-r--r--test/unit/tx-utils-test.js145
-rw-r--r--ui/app/actions.js295
-rw-r--r--ui/app/app.js921
-rw-r--r--ui/app/components/account-dropdowns.js5
-rw-r--r--ui/app/components/account-menu/index.js54
-rw-r--r--ui/app/components/balance-component.js18
-rw-r--r--ui/app/components/buy-button-subview.js6
-rw-r--r--ui/app/components/customize-gas-modal/index.js4
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js5
-rw-r--r--ui/app/components/dropdowns/network-dropdown.js14
-rw-r--r--ui/app/components/ens-input.js5
-rw-r--r--ui/app/components/export-text-container/export-text-container.component.js45
-rw-r--r--ui/app/components/export-text-container/export-text-container.scss52
-rw-r--r--ui/app/components/export-text-container/index.js2
-rw-r--r--ui/app/components/loading-screen/index.js2
-rw-r--r--ui/app/components/loading-screen/loading-screen.component.js35
-rw-r--r--ui/app/components/loading.js30
-rw-r--r--ui/app/components/modals/buy-options-modal.js4
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js4
-rw-r--r--ui/app/components/modals/export-private-key-modal.js7
-rw-r--r--ui/app/components/modals/modal.js11
-rw-r--r--ui/app/components/pages/add-token.js (renamed from ui/app/add-token.js)25
-rw-r--r--ui/app/components/pages/authenticated.js34
-rw-r--r--ui/app/components/pages/create-account/import-account/index.js (renamed from ui/app/accounts/import/index.js)0
-rw-r--r--ui/app/components/pages/create-account/import-account/json.js (renamed from ui/app/accounts/import/json.js)18
-rw-r--r--ui/app/components/pages/create-account/import-account/private-key.js (renamed from ui/app/accounts/import/private-key.js)26
-rw-r--r--ui/app/components/pages/create-account/import-account/seed.js (renamed from ui/app/accounts/import/seed.js)0
-rw-r--r--ui/app/components/pages/create-account/index.js81
-rw-r--r--ui/app/components/pages/create-account/new-account.js (renamed from ui/app/accounts/new-account/create-form.js)30
-rw-r--r--ui/app/components/pages/home.js333
-rw-r--r--ui/app/components/pages/initialized.js25
-rw-r--r--ui/app/components/pages/keychains/restore-vault.js178
-rw-r--r--ui/app/components/pages/keychains/reveal-seed.js164
-rw-r--r--ui/app/components/pages/metamask-route.js28
-rw-r--r--ui/app/components/pages/notice.js203
-rw-r--r--ui/app/components/pages/settings/index.js59
-rw-r--r--ui/app/components/pages/settings/info.js120
-rw-r--r--ui/app/components/pages/settings/settings.js (renamed from ui/app/settings.js)163
-rw-r--r--ui/app/components/pages/unlock.js194
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js47
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js51
-rw-r--r--ui/app/components/pending-tx/index.js69
-rw-r--r--ui/app/components/qr-code.js13
-rw-r--r--ui/app/components/send/account-list-item.js3
-rw-r--r--ui/app/components/send/currency-display.js50
-rw-r--r--ui/app/components/send/send-constants.js4
-rw-r--r--ui/app/components/send/send-v2-container.js9
-rw-r--r--ui/app/components/shapeshift-form.js13
-rw-r--r--ui/app/components/signature-request.js17
-rw-r--r--ui/app/components/spinner/index.js2
-rw-r--r--ui/app/components/spinner/spinner.component.js78
-rw-r--r--ui/app/components/tab-bar.js26
-rw-r--r--ui/app/components/token-balance.js1
-rw-r--r--ui/app/components/token-cell.js20
-rw-r--r--ui/app/components/token-list.js1
-rw-r--r--ui/app/components/tx-list-item.js23
-rw-r--r--ui/app/components/tx-list.js18
-rw-r--r--ui/app/components/tx-view.js21
-rw-r--r--ui/app/components/wallet-view.js27
-rw-r--r--ui/app/conf-tx.js77
-rw-r--r--ui/app/css/index.scss6
-rw-r--r--ui/app/css/itcss/components/add-token.scss1
-rw-r--r--ui/app/css/itcss/components/index.scss4
-rw-r--r--ui/app/css/itcss/components/loading-overlay.scss33
-rw-r--r--ui/app/css/itcss/components/network.scss2
-rw-r--r--ui/app/css/itcss/components/new-account.scss5
-rw-r--r--ui/app/css/itcss/components/pages/index.scss3
-rw-r--r--ui/app/css/itcss/components/pages/reveal-seed.scss17
-rw-r--r--ui/app/css/itcss/components/pages/unlock.scss9
-rw-r--r--ui/app/css/itcss/components/sections.scss6
-rw-r--r--ui/app/css/itcss/components/send.scss1
-rw-r--r--ui/app/css/itcss/generic/index.scss67
-rw-r--r--ui/app/css/itcss/settings/variables.scss1
-rw-r--r--ui/app/first-time/init-menu.js352
-rw-r--r--ui/app/i18n-provider.js7
-rw-r--r--ui/app/keychains/hd/recover-seed/confirmation.js126
-rw-r--r--ui/app/keychains/hd/restore-vault.js1
-rw-r--r--ui/app/main-container.js5
-rw-r--r--ui/app/reducers/app.js1
-rw-r--r--ui/app/reducers/metamask.js19
-rw-r--r--ui/app/root.js33
-rw-r--r--ui/app/routes.js49
-rw-r--r--ui/app/select-app.js12
-rw-r--r--ui/app/selectors.js19
-rw-r--r--ui/app/send-v2.js35
-rw-r--r--ui/app/token-util.js46
-rw-r--r--ui/app/unlock.js7
-rw-r--r--ui/app/util.js16
-rw-r--r--ui/app/welcome-screen.js35
-rw-r--r--ui/i18n-helper.js3
-rw-r--r--ui/index.js7
-rw-r--r--ui/lib/icon-factory.js4
-rw-r--r--ui/lib/tx-helper.js1
-rw-r--r--yarn.lock3587
245 files changed, 19016 insertions, 5461 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index ee2054130..88a611af3 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,19 +15,13 @@ workflows:
- test-lint:
requires:
- prep-deps-npm
- - test-e2e:
+ - test-deps:
requires:
- prep-deps-npm
- - prep-build
- - job-screens:
- requires:
- - prep-deps-npm
- - prep-build
- - job-publish:
+ - test-e2e:
requires:
- prep-deps-npm
- prep-build
- - job-screens
- test-unit:
requires:
- prep-deps-npm
@@ -52,13 +46,24 @@ workflows:
- all-tests-pass:
requires:
- test-lint
+ - test-deps
- test-unit
- test-e2e
- - job-screens
- test-integration-mascara-chrome
- test-integration-mascara-firefox
- test-integration-flat-chrome
- test-integration-flat-firefox
+ - job-screens:
+ requires:
+ - prep-deps-npm
+ - prep-build
+ - all-tests-pass
+ - job-publish:
+ requires:
+ - prep-deps-npm
+ - prep-build
+ - job-screens
+ - all-tests-pass
jobs:
prep-deps-npm:
@@ -144,6 +149,17 @@ jobs:
name: Test
command: npm run lint
+ test-deps:
+ docker:
+ - image: circleci/node:8-browsers
+ steps:
+ - checkout
+ - restore_cache:
+ key: dependency-cache-{{ .Revision }}
+ - run:
+ name: Test
+ command: npx nsp check
+
test-e2e:
docker:
- image: circleci/node:8-browsers
diff --git a/.eslintrc b/.eslintrc
index 8af71bf4e..511d6f216 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -35,7 +35,6 @@
"globals": {
"document": false,
- "log": true,
"navigator": false,
"web3": true,
"window": false
diff --git a/.gitignore b/.gitignore
index dee5ec220..0e91a7d04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ dist
builds/
disc/
builds.zip
+docs/jsdocs
development/bundle.js
development/states.js
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index 6dc5ecc6b..000000000
--- a/.jshintrc
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "node": true,
- "browser": true,
- "esnext": true,
- "bitwise": true,
- "camelcase": true,
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "indent": 2,
- "latedef": true,
- "newcap": true,
- "noarg": true,
- "quotmark": "single",
- "regexp": true,
- "undef": true,
- "unused": true,
- "strict": true,
- "trailing": true,
- "smarttabs": true,
- "globals" : {
- "chrome": true,
- "crypto": true,
- "describe": true,
- "it": true
- }
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95aebf37d..0bb50fd5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,35 @@
## Current Master
+## 4.6.0 Thu Apr 26 2018
+
+- Correctly format currency conversion for locally selected preferred currency.
+- Improved performance of 3D fox logo.
+- Fetch token prices based on contract address, not symbol
+- Fix bug that prevents setting language locale in settings.
+- Show checksum addresses throughout the UI
+- Allow transactions with a 0 gwei gas price
+
+## 4.5.5 Fri Apr 06 2018
+
+- Graceful handling of unknown keys in txParams
+- Fixes buggy handling of historical transactions with unknown keys in txParams
+- Fix link for 'Learn More' in the Add Token Screen to open to a new tab.
+- Fix Download State Logs button [#3791](https://github.com/MetaMask/metamask-extension/issues/3791)
+- Enhanced migration error handling + reporting
+
+## 4.5.4 (aborted) Thu Apr 05 2018
+
+- Graceful handling of unknown keys in txParams
+- Fix link for 'Learn More' in the Add Token Screen to open to a new tab.
+- Fix Download State Logs button [#3791](https://github.com/MetaMask/metamask-extension/issues/3791)
+- Fix migration error reporting
+
+## 4.5.3 Wed Apr 04 2018
+
+- Fix bug where checksum address are messing with balance issue [#3843](https://github.com/MetaMask/metamask-extension/issues/3843)
+- new ui: fix the confirm transaction screen
+
## 4.5.2 Wed Apr 04 2018
- Fix overly strict validation where transactions were rejected with hex encoded "chainId"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5d2e5207b..8517eed70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,12 +12,14 @@ For any new programmatic functionality, we like unit tests when possible, so if
### PR Format
-We use [waffle](https://waffle.io/) for project management, and it will automatically keep us organized if you do one simple thing:
-
If this PR closes the issue, add the line `Fixes #$ISSUE_NUMBER`. Ex. For closing issue 418, include the line `Fixes #418`.
If it doesn't close the issue but addresses it partially, just include a reference to the issue number, like `#418`.
+Submit your PR against the `develop` branch. This is where we merge new features so they get some time to receive extra testing before being pushed to `master` for production.
+
+If your PR is a hot-fix that needs to be published urgently, you may submit a PR against the `master` branch, but this PR will receive tighter scrutiny before merging.
+
## Before Merging
Make sure you get a `:thumbsup`, `:+1`, or `LGTM` from another collaborator before merging.
diff --git a/README.md b/README.md
index 2e68991b5..ca25fc0b9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# MetaMask Browser Extension
[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](https://waffle.io/MetaMask/metamask-extension)
+[Internal documentation](./docs/jsdocs)
## Support
@@ -68,6 +69,7 @@ To write tests that will be run in the browser using QUnit, add your test files
- [How to develop a live-reloading UI](./docs/ui-dev-mode.md)
- [How to add a new translation to MetaMask](./docs/translating-guide.md)
- [Publishing Guide](./docs/publishing.md)
+- [The MetaMask Team](./docs/team.md)
- [How to develop an in-browser mocked UI](./docs/ui-mock-mode.md)
- [How to live reload on local dependency changes](./docs/developing-on-deps.md)
- [How to add new networks to the Provider Menu](./docs/adding-new-networks.md)
diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json
new file mode 100644
index 000000000..6a4ebc8a5
--- /dev/null
+++ b/app/_locales/cs/messages.json
@@ -0,0 +1,912 @@
+{
+ "accept": {
+ "message": "Přijmout"
+ },
+ "account": {
+ "message": "Účet"
+ },
+ "accountDetails": {
+ "message": "Detaily účtu"
+ },
+ "accountName": {
+ "message": "Název účtu"
+ },
+ "address": {
+ "message": "Adresa"
+ },
+ "addCustomToken": {
+ "message": "Přidat vlastní token"
+ },
+ "addToken": {
+ "message": "Přidat token"
+ },
+ "addTokens": {
+ "message": "Přidat tokeny"
+ },
+ "amount": {
+ "message": "Částka"
+ },
+ "amountPlusGas": {
+ "message": "Částka + palivo"
+ },
+ "appDescription": {
+ "message": "Ethereum rozšíření prohlížeče",
+ "description": "The description of the application"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "The name of the application"
+ },
+ "approved": {
+ "message": "Schváleno"
+ },
+ "attemptingConnect": {
+ "message": "Pokouším se připojit k blockchainu."
+ },
+ "attributions": {
+ "message": "Zásluhy"
+ },
+ "available": {
+ "message": "Dostupné"
+ },
+ "back": {
+ "message": "Zpět"
+ },
+ "balance": {
+ "message": "Zůstatek:"
+ },
+ "balances": {
+ "message": "Zůstatek tokenu"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Nedostatek prostředků pro aktuální množství paliva"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "musí být větší nebo roven $1 a menší nebo roven $2.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "blockiesIdenticon": {
+ "message": "Použít Blockies Identicon"
+ },
+ "borrowDharma": {
+ "message": "Pújčit si přes Dharma (Beta)"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask je navržen a vytvořen v Kalifornii."
+ },
+ "buy": {
+ "message": "Koupit"
+ },
+ "buyCoinbase": {
+ "message": "Nákup na Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase je světově nejoblíbenější místo k nákupu a prodeji bitcoinu, etherea nebo litecoinu."
+ },
+ "ok": {
+ "message": "Ok"
+ },
+ "cancel": {
+ "message": "Zrušit"
+ },
+ "classicInterface": {
+ "message": "Použít klasické rozhraní"
+ },
+ "clickCopy": {
+ "message": "Kliknutím zkopírovat"
+ },
+ "confirm": {
+ "message": "Potvrdit"
+ },
+ "confirmed": {
+ "message": "Potvrzeno"
+ },
+ "confirmContract": {
+ "message": "Potvrdit kontrakt"
+ },
+ "confirmPassword": {
+ "message": "Potvrdit heslo"
+ },
+ "confirmTransaction": {
+ "message": "Potvrdit transakci"
+ },
+ "continue": {
+ "message": "Pokračovat"
+ },
+ "continueToCoinbase": {
+ "message": "Přejít na Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Nasazení kontraktu"
+ },
+ "conversionProgress": {
+ "message": "Provádí se převod"
+ },
+ "copiedButton": {
+ "message": "Zkopírováno"
+ },
+ "copiedClipboard": {
+ "message": "Zkopírováno do schránky"
+ },
+ "copiedExclamation": {
+ "message": "Zkopírováno!"
+ },
+ "copiedSafe": {
+ "message": "Zkopíroval jsem to na bezpečné místo"
+ },
+ "copy": {
+ "message": "Kopírovat"
+ },
+ "copyToClipboard": {
+ "message": "Kopírovat do schránky"
+ },
+ "copyButton": {
+ "message": " Kopírovat "
+ },
+ "copyPrivateKey": {
+ "message": "Toto je váš privátní klíč (kliknutím zkopírujte)"
+ },
+ "create": {
+ "message": "Vytvořit"
+ },
+ "createAccount": {
+ "message": "Vytvořit účet"
+ },
+ "createDen": {
+ "message": "Vytvořit"
+ },
+ "crypto": {
+ "message": "Krypto",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "currentConversion": {
+ "message": "Aktuální převod"
+ },
+ "currentNetwork": {
+ "message": "Aktuální síť"
+ },
+ "customGas": {
+ "message": "Nastavit palivo"
+ },
+ "customToken": {
+ "message": "Vlastní token"
+ },
+ "customize": {
+ "message": "Nastavit"
+ },
+ "customRPC": {
+ "message": "Vlastní RPC"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Desetinných míst musí být od 0 do 36."
+ },
+ "decimal": {
+ "message": "Počet desetinných míst přesnosti"
+ },
+ "defaultNetwork": {
+ "message": "Výchozí síť pro Etherové transakce je Main Net."
+ },
+ "denExplainer": {
+ "message": "Váš DEN je heslem šifrované uložiště v MetaMasku."
+ },
+ "deposit": {
+ "message": "Vklad"
+ },
+ "depositBTC": {
+ "message": "Vložte BTC na níže uvedenou adresu:"
+ },
+ "depositCoin": {
+ "message": "Vložte $1 na níže uvedenou adresu",
+ "description": "Tells the user what coin they have selected to deposit with shapeshift"
+ },
+ "depositEth": {
+ "message": "Vložit Eth"
+ },
+ "depositEther": {
+ "message": "Vložit Ether"
+ },
+ "depositFiat": {
+ "message": "Vklad s fiat měnou"
+ },
+ "depositFromAccount": {
+ "message": "Vložte z jiného účtu"
+ },
+ "depositShapeShift": {
+ "message": "Vklad přes ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Pokud vlastníte jiné kryptoměny, můžete je směnit Ether a vložit ho přímo do peněženky MetaMask. Bez založení účtu."
+ },
+ "details": {
+ "message": "Podrobnosti"
+ },
+ "directDeposit": {
+ "message": "Přímý vklad"
+ },
+ "directDepositEther": {
+ "message": "Vložit Ether přímo"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Pokud už vlastníte nějaký Ether, nejrychleji ho dostanete do peněženky přímým vkladem."
+ },
+ "done": {
+ "message": "Hotovo"
+ },
+ "downloadStateLogs": {
+ "message": "Stáhnout stavové protokoly"
+ },
+ "dropped": {
+ "message": "Zrušeno"
+ },
+ "edit": {
+ "message": "Upravit"
+ },
+ "editAccountName": {
+ "message": "Upravit název účtu"
+ },
+ "emailUs": {
+ "message": "Napište nám e-mail!"
+ },
+ "encryptNewDen": {
+ "message": "Zašifrujte svůj nový DEN"
+ },
+ "enterPassword": {
+ "message": "Zadejte heslo"
+ },
+ "enterPasswordConfirm": {
+ "message": "Zadejte heslo k potvrzení"
+ },
+ "passwordNotLongEnough": {
+ "message": "Heslo není dost dlouhé"
+ },
+ "passwordsDontMatch": {
+ "message": "Hesla nejsou stejná"
+ },
+ "etherscanView": {
+ "message": "Prohlédněte si účet na Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Směnný kurz"
+ },
+ "exportPrivateKey": {
+ "message": "Exportovat privátní klíč"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Exportujte privátní klíč na vlastní riziko."
+ },
+ "failed": {
+ "message": "Neúspěšné"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "Import souboru nefunguje? Klikněte sem!",
+ "description": "Helps user import their account from a JSON file"
+ },
+ "followTwitter": {
+ "message": "Sledujte nás na Twitteru"
+ },
+ "from": {
+ "message": "Od"
+ },
+ "fromToSame": {
+ "message": "Adresy odesílatele a příjemce nemohou být stejné"
+ },
+ "fromShapeShift": {
+ "message": "Z ShapeShift"
+ },
+ "gas": {
+ "message": "Palivo",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "Poplatek za palivo"
+ },
+ "gasLimit": {
+ "message": "Limit paliva"
+ },
+ "gasLimitCalculation": {
+ "message": "Počítáme doporučený limit paliva na základě úspěšnosti v síti."
+ },
+ "gasLimitRequired": {
+ "message": "Limit paliva je povinný"
+ },
+ "gasLimitTooLow": {
+ "message": "Limit paliva musí být alespoň 21000"
+ },
+ "generatingSeed": {
+ "message": "Generuji klíčovou frázi..."
+ },
+ "gasPrice": {
+ "message": "Cena paliva (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Počítáme doporučenou cenu paliva na základě úspěšnosti v síti."
+ },
+ "gasPriceRequired": {
+ "message": "Cena paliva je povinná"
+ },
+ "getEther": {
+ "message": "Získejte Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Získejte Ether z faucetu za $1.",
+ "description": "Displays network name for Ether faucet"
+ },
+ "greaterThanMin": {
+ "message": "musí být větší nebo roven $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "here": {
+ "message": "zde",
+ "description": "as in -click here- for more information (goes with troubleTokenBalances)"
+ },
+ "hereList": {
+ "message": "Tady je seznam!!!!"
+ },
+ "hide": {
+ "message": "Skrýt"
+ },
+ "hideToken": {
+ "message": "Skrýt token"
+ },
+ "hideTokenPrompt": {
+ "message": "Skrýt token?"
+ },
+ "howToDeposit": {
+ "message": "Jakým způsobem chcete vložit Ether?"
+ },
+ "holdEther": {
+ "message": "Dovoluje vám držet ether a tokeny a slouží jako most k decentralizovaným aplikacím."
+ },
+ "import": {
+ "message": "Import",
+ "description": "Button to import an account from a selected file"
+ },
+ "importAccount": {
+ "message": "Import účtu"
+ },
+ "importAccountMsg": {
+ "message":"Importované účty nebudou spojeny s vaší původní MetaMaskovou klíčovou frází. Zjistěte více o importovaných účtech "
+ },
+ "importAnAccount": {
+ "message": "Import účtu"
+ },
+ "importDen": {
+ "message": "Import existujícího DEN"
+ },
+ "imported": {
+ "message": "Importováno",
+ "description": "status showing that an account has been fully loaded into the keyring"
+ },
+ "infoHelp": {
+ "message": "Informace a nápověda"
+ },
+ "insufficientFunds": {
+ "message": "Nedostatek finančních prostředků."
+ },
+ "insufficientTokens": {
+ "message": "Nedostatek tokenů."
+ },
+ "invalidAddress": {
+ "message": "Neplatná adresa"
+ },
+ "invalidAddressRecipient": {
+ "message": "Adresa příjemce je neplatná"
+ },
+ "invalidGasParams": {
+ "message": "Neplatná parametry paliva"
+ },
+ "invalidInput": {
+ "message": "Neplatný vstup."
+ },
+ "invalidRequest": {
+ "message": "Neplatný požadavek"
+ },
+ "invalidRPC": {
+ "message": "Neplatné RPC URI"
+ },
+ "jsonFail": {
+ "message": "Něco se pokazilo. Prosím, ujistěte se, že váš JSON soubor má správný formát."
+ },
+ "jsonFile": {
+ "message": "JSON soubor",
+ "description": "format for importing an account"
+ },
+ "keepTrackTokens": {
+ "message": "Udržujte si záznamy o tokenech, které jste koupili s účtem v MetaMasku."
+ },
+ "kovan": {
+ "message": "Kovan Test Network"
+ },
+ "knowledgeDataBase": {
+ "message": "Navštivte naši Knowledge Base"
+ },
+ "max": {
+ "message": "Max"
+ },
+ "learnMore": {
+ "message": "Zjistěte více."
+ },
+ "lessThanMax": {
+ "message": "musí být menší nebo roven $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "likeToAddTokens": {
+ "message": "Chcete přidat tyto tokeny?"
+ },
+ "links": {
+ "message": "Odkazy"
+ },
+ "limit": {
+ "message": "Limit"
+ },
+ "loading": {
+ "message": "Načítám..."
+ },
+ "loadingTokens": {
+ "message": "Načítám tokeny..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Přihlásit"
+ },
+ "logout": {
+ "message": "Odhlásit"
+ },
+ "loose": {
+ "message": "Nevázané"
+ },
+ "loweCaseWords": {
+ "message": "slova klíčové fráze mají pouze malá písmena"
+ },
+ "mainnet": {
+ "message": "Main Ethereum Network"
+ },
+ "message": {
+ "message": "Zpráva"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask je bezpečný osobní trezor pro Ethereum."
+ },
+ "min": {
+ "message": "Minimum"
+ },
+ "myAccounts": {
+ "message": "Moje účty"
+ },
+ "mustSelectOne": {
+ "message": "Musíte zvolit aspoň 1 token."
+ },
+ "needEtherInWallet": {
+ "message": "Potřebujete Ether v peněžence, abyste mohli pomocí MetaMasku interagovat s decentralizovanými aplikacemi."
+ },
+ "needImportFile": {
+ "message": "Musíte zvolit soubor k importu.",
+ "description": "User is important an account and needs to add a file to continue"
+ },
+ "needImportPassword": {
+ "message": "Musíte zadat heslo pro zvolený soubor.",
+ "description": "Password and file needed to import an account"
+ },
+ "negativeETH": {
+ "message": "Nelze odeslat zápornou částku ETH."
+ },
+ "networks": {
+ "message": "Sítě"
+ },
+ "newAccount": {
+ "message": "Nový účet"
+ },
+ "newAccountNumberName": {
+ "message": "Účet $1",
+ "description": "Default name of next account to be created on create account screen"
+ },
+ "newContract": {
+ "message": "Nový kontrakt"
+ },
+ "newPassword": {
+ "message": "Nové heslo (min 8 znaků)"
+ },
+ "newRecipient": {
+ "message": "Nový příjemce"
+ },
+ "newRPC": {
+ "message": "Nová RPC URL"
+ },
+ "next": {
+ "message": "Další"
+ },
+ "noAddressForName": {
+ "message": "Pro toto jméno nebyla nastavena žádná adresa."
+ },
+ "noDeposits": {
+ "message": "Žádný vklad"
+ },
+ "noTransactionHistory": {
+ "message": "Žádná historie transakcí."
+ },
+ "noTransactions": {
+ "message": "Žádné transakce"
+ },
+ "notStarted": {
+ "message": "Nezačalo"
+ },
+ "oldUI": {
+ "message": "Staré rozhraní"
+ },
+ "oldUIMessage": {
+ "message": "Vrátili jste se ke starému rozhraní. Můžete přepnout na nové rozhraní v nastavení v pravém horním menu."
+ },
+ "or": {
+ "message": "nebo",
+ "description": "choice between creating or importing a new account"
+ },
+ "passwordCorrect": {
+ "message": "Ujistěte se, že je vaše heslo správně."
+ },
+ "passwordMismatch": {
+ "message": "hesla nesouhlasí",
+ "description": "in password creation process, the two new password fields did not match"
+ },
+ "passwordShort": {
+ "message": "heslo je krátké",
+ "description": "in password creation process, the password is not long enough to be secure"
+ },
+ "pastePrivateKey": {
+ "message": "Vložte zde svůj privátní klíč:",
+ "description": "For importing an account from a private key"
+ },
+ "pasteSeed": {
+ "message": "Svou klíčovou frázi vložte zde!"
+ },
+ "personalAddressDetected": {
+ "message": "Detekována osobní adresa. Zadejte adresu kontraktu tokenu."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Zkontrolujte si transakci."
+ },
+ "popularTokens": {
+ "message": "Oblíbené tokeny"
+ },
+ "privacyMsg": {
+ "message": "Zásady ochrany osobních údajů"
+ },
+ "privateKey": {
+ "message": "Privátní klíč",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "Upozornění: Nikdy nezveřejněte tento klíč. Kdokoli může s vaším privátním klíčem odcizit vaše aktiva z účtu."
+ },
+ "privateNetwork": {
+ "message": "Soukromá síť"
+ },
+ "qrCode": {
+ "message": "Ukázat QR kód"
+ },
+ "readdToken": {
+ "message": "Tento token můžete v budoucnu přidat zpět s „Přidat token“ v nastavení účtu."
+ },
+ "readMore": {
+ "message": "Přečtěte si více zde."
+ },
+ "readMore2": {
+ "message": "Přečtěte si více."
+ },
+ "receive": {
+ "message": "Obrdžet"
+ },
+ "recipientAddress": {
+ "message": "Adresa příjemce"
+ },
+ "refundAddress": {
+ "message": "Adresa pro vrácení peněz"
+ },
+ "rejected": {
+ "message": "Odmítnuto"
+ },
+ "resetAccount": {
+ "message": "Resetovat účet"
+ },
+ "restoreFromSeed": {
+ "message": "Obnovit z seed fráze"
+ },
+ "restoreVault": {
+ "message": "Obnovit trezor"
+ },
+ "required": {
+ "message": "Povinné"
+ },
+ "retryWithMoreGas": {
+ "message": "Opakujte s vyšší cenou paliva"
+ },
+ "walletSeed": {
+ "message": "Klíčová fráze peněženky"
+ },
+ "revealSeedWords": {
+ "message": "Zobrazit slova klíčové fráze"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Nebnovujte slova klíčové fráze na veřejnosti! Tato slova mohou být použita k odcizení veškerých vyašich účtů."
+ },
+ "revert": {
+ "message": "Zvrátit"
+ },
+ "rinkeby": {
+ "message": "Rinkeby Test Network"
+ },
+ "ropsten": {
+ "message": "Ropsten Test Network"
+ },
+ "currentRpc": {
+ "message": "Současné RPC"
+ },
+ "connectingToMainnet": {
+ "message": "Připojuji se k Main Ethereum Network"
+ },
+ "connectingToRopsten": {
+ "message": "Připojuji se k Ropsten Test Network"
+ },
+ "connectingToKovan": {
+ "message": "Připojuji se k Kovan Test Network"
+ },
+ "connectingToRinkeby": {
+ "message": "Připojuji se k Rinkeby Test Network"
+ },
+ "connectingToUnknown": {
+ "message": "Připojuji se k neznámé síti"
+ },
+ "sampleAccountName": {
+ "message": "Např. můj nový účet",
+ "description": "Help user understand concept of adding a human-readable name to their account"
+ },
+ "save": {
+ "message": "Uložit"
+ },
+ "reprice_title": {
+ "message": "Změnit cenu transakce"
+ },
+ "reprice_subtitle": {
+ "message": "Navyšte cenu paliva ve snaze k přepsání a urychlení vyší transakce"
+ },
+ "saveAsFile": {
+ "message": "Uložit do souboru",
+ "description": "Account export process"
+ },
+ "saveSeedAsFile": {
+ "message": "Uložit slova klíčové fráze do souboru"
+ },
+ "search": {
+ "message": "Hledat"
+ },
+ "secretPhrase": {
+ "message": "Zadejte svých 12 slov tajné fráze k obnovení trezoru."
+ },
+ "newPassword8Chars": {
+ "message": "Nové heslo (min 8 znaků)"
+ },
+ "seedPhraseReq": {
+ "message": "klíčové fráze mají 12 slov"
+ },
+ "select": {
+ "message": "Vybrat"
+ },
+ "selectCurrency": {
+ "message": "Vybrat měnu"
+ },
+ "selectService": {
+ "message": "Vybrat službu"
+ },
+ "selectType": {
+ "message": "Vybrat typ"
+ },
+ "send": {
+ "message": "Odeslat"
+ },
+ "sendETH": {
+ "message": "Odeslat ETH"
+ },
+ "sendTokens": {
+ "message": "Odeslat tokeny"
+ },
+ "onlySendToEtherAddress": {
+ "message": "Posílejte jen ETH na Ethereum adresu."
+ },
+ "searchTokens": {
+ "message": "Hledat tokeny"
+ },
+ "sendTokensAnywhere": {
+ "message": "Posílejte tokeny komukoli s Ethereum účtem"
+ },
+ "settings": {
+ "message": "Nastavení"
+ },
+ "info": {
+ "message": "Informace"
+ },
+ "shapeshiftBuy": {
+ "message": "Nakoupit na ShapeShift"
+ },
+ "showPrivateKeys": {
+ "message": "Zobrazit privátní klíče"
+ },
+ "showQRCode": {
+ "message": "Zobrazit QR kód"
+ },
+ "sign": {
+ "message": "Podepsat"
+ },
+ "signed": {
+ "message": "Podepsáno"
+ },
+ "signMessage": {
+ "message": "Podepsat zprávu"
+ },
+ "signNotice": {
+ "message": "Podepsání zprávy může mít \nnebezpečný vedlejší učinek. Podepisujte zprávy pouze ze \nstránek, kterým plně důvěřujete celým svým účtem.\n Tato nebezpečná metoda bude odebrána v budoucí verzi. "
+ },
+ "sigRequest": {
+ "message": "Požadavek podpisu"
+ },
+ "sigRequested": {
+ "message": "Požádáno o podpis"
+ },
+ "spaceBetween": {
+ "message": "mezi slovy může být pouze mezera"
+ },
+ "status": {
+ "message": "Stav"
+ },
+ "stateLogs": {
+ "message": "Stavové protokoly"
+ },
+ "stateLogsDescription": {
+ "message": "Stavové protokoly obsahují vaše veřejné adresy účtů a odeslané transakce."
+ },
+ "stateLogError": {
+ "message": "Chyba během získávání stavových protokolů."
+ },
+ "submit": {
+ "message": "Odeslat"
+ },
+ "submitted": {
+ "message": "Odesláno"
+ },
+ "supportCenter": {
+ "message": "Navštivte naše centrum podpory"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Symbol musí být mezi 0 a 10 znaky."
+ },
+ "takesTooLong": {
+ "message": "Trvá to dlouho?"
+ },
+ "terms": {
+ "message": "Podmínky použití"
+ },
+ "testFaucet": {
+ "message": "Testovací faucet"
+ },
+ "to": {
+ "message": "Komu: "
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 na ETH přes ShapeShift",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenAddress": {
+ "message": "Adresa tokenu"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Token byl už přidán."
+ },
+ "tokenBalance": {
+ "message": "Váš zůstatek tokenu je:"
+ },
+ "tokenSelection": {
+ "message": "Vyhledejte token nebo je vyberte z našeho seznamu oblíbených tokenů."
+ },
+ "tokenSymbol": {
+ "message": "Symbol tokenu"
+ },
+ "tokenWarning1": {
+ "message": "Mějte přehled o tokenech, které jste koupili s účtem MetaMasku. Pokud jste koupili tokeny s jiným účtem, tyto tokeny se zde nezobrazí."
+ },
+ "total": {
+ "message": "Celkem"
+ },
+ "transactions": {
+ "message": "transakce"
+ },
+ "transactionError": {
+ "message": "Chyba transakce. Vyhozena výjimka v kódu kontraktu."
+ },
+ "transactionMemo": {
+ "message": "Poznámka transakce (nepovinné)"
+ },
+ "transactionNumber": {
+ "message": "Číslo transakce"
+ },
+ "transfers": {
+ "message": "Převody"
+ },
+ "troubleTokenBalances": {
+ "message": "Měli jsme problém s načtením vašich tokenových zůstatků. Můžete je vidět ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "twelveWords": {
+ "message": "Těchto 12 slov je jedinou možností, jak obnovit MetaMask účet. \nUložte je na bezpečné a neveřejné místo."
+ },
+ "typePassword": {
+ "message": "Zadejte své heslo"
+ },
+ "uiWelcome": {
+ "message": "Vítejte v novém rozhraní (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Používáte nyní nové rozhraní MetaMasku. Rozhlédněte se kolem, vyzkoušejte nové funkce, jako jsou zasílání tokenů, a dejte nám vědět, pokud narazíte na problém."
+ },
+ "unapproved": {
+ "message": "Neschváleno"
+ },
+ "unavailable": {
+ "message": "Nedostupné"
+ },
+ "unknown": {
+ "message": "Neznámé"
+ },
+ "unknownNetwork": {
+ "message": "Neznámá soukromá síť"
+ },
+ "unknownNetworkId": {
+ "message": "Neznámé ID sítě"
+ },
+ "uriErrorMsg": {
+ "message": "URI vyžadují korektní HTTP/HTTPS prefix."
+ },
+ "usaOnly": {
+ "message": "jen v USA",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "Používána různými klienty"
+ },
+ "useOldUI": {
+ "message": "Použijte staré rozhraní"
+ },
+ "validFileImport": {
+ "message": "Musíte vybrat validní soubor k importu."
+ },
+ "vaultCreated": {
+ "message": "Trezor vytvořen"
+ },
+ "viewAccount": {
+ "message": "Zobrazit účet"
+ },
+ "visitWebSite": {
+ "message": "Navštivte naši stránku"
+ },
+ "warning": {
+ "message": "Varování"
+ },
+ "welcomeBeta": {
+ "message": "Vítejte v MetaMask Beta"
+ },
+ "whatsThis": {
+ "message": "Co to je?"
+ },
+ "yourSigRequested": {
+ "message": "Je vyžadován váš podpis"
+ },
+ "youSign": {
+ "message": "Podepisujete"
+ }
+}
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index b372326ee..a40c2635c 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -98,6 +98,9 @@
"clickCopy": {
"message": "Click to Copy"
},
+ "close": {
+ "message": "Close"
+ },
"confirm": {
"message": "Confirm"
},
@@ -259,6 +262,9 @@
"enterPasswordConfirm": {
"message": "Enter your password to confirm"
},
+ "enterPasswordContinue": {
+ "message": "Enter password to continue"
+ },
"passwordNotLongEnough": {
"message": "Password not long enough"
},
@@ -331,6 +337,9 @@
"gasPriceRequired": {
"message": "Gas Price Required"
},
+ "generatingTransaction": {
+ "message": "Generating transaction"
+ },
"getEther": {
"message": "Get Ether"
},
@@ -476,6 +485,9 @@
"metamaskDescription": {
"message": "MetaMask is a secure identity vault for Ethereum."
},
+ "metamaskSeedWords": {
+ "message": "MetaMask Seed Words"
+ },
"min": {
"message": "Minimum"
},
@@ -549,6 +561,9 @@
"message": "or",
"description": "choice between creating or importing a new account"
},
+ "password": {
+ "message": "Password"
+ },
"passwordCorrect": {
"message": "Please make sure your password is correct."
},
@@ -634,8 +649,17 @@
"revealSeedWords": {
"message": "Reveal Seed Words"
},
+ "revealSeedWordsTitle": {
+ "message": "Seed Phrase"
+ },
+ "revealSeedWordsDescription": {
+ "message": "If you ever change browsers or move computers, you will need this seed phrase to access your accounts. Save them somewhere safe and secret."
+ },
+ "revealSeedWordsWarningTitle": {
+ "message": "DO NOT share this phrase with anyone!"
+ },
"revealSeedWordsWarning": {
- "message": "Do not recover your seed words in a public place! These words can be used to steal all your accounts."
+ "message": "These words can be used to steal all your accounts."
},
"revert": {
"message": "Revert"
@@ -677,6 +701,9 @@
"reprice_subtitle": {
"message": "Increase your gas price to attempt to overwrite and speed up your transaction"
},
+ "saveAsCsvFile": {
+ "message": "Save as CSV File"
+ },
"saveAsFile": {
"message": "Save as File",
"description": "Account export process"
@@ -908,5 +935,8 @@
},
"youSign": {
"message": "You are signing"
+ },
+ "yourPrivateSeedPhrase": {
+ "message": "Your private seed phrase"
}
}
diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json
index 323f4b4b3..b869560e5 100644
--- a/app/_locales/hn/messages.json
+++ b/app/_locales/hn/messages.json
@@ -9,7 +9,7 @@
"message": "खाता विवरण"
},
"accountName": {
- "message": "खाता का नाम"
+ "message": "खाते का नाम"
},
"address": {
"message": "खाते का पता"
@@ -21,7 +21,7 @@
"message": "टोकन जोड़ें"
},
"addTokens": {
- "message": "टोकनो को जोड़ें"
+ "message": "टोकनों को जोड़ें"
},
"amount": {
"message": "राशि"
@@ -30,7 +30,7 @@
"message": "राशि + गैस"
},
"appDescription": {
- "message": "एथरेम ब्राउज़र एक्सटेंशन",
+ "message": "इथीरियम ब्राउज़र एक्सटेंशन",
"description": "आवेदन का विवरण"
},
"appName": {
@@ -53,7 +53,7 @@
"message": "उपलब्ध बैलेंस।"
},
"balances": {
- "message": "ापके उपलब्ध बैलेंस"
+ "message": "आपके उपलब्ध बैलेंस"
},
"balanceIsInsufficientGas": {
"message": "वर्तमान गैस कुल के लिए अपर्याप्त शेष"
@@ -78,10 +78,10 @@
"message": "खरीदें"
},
"buyCoinbase": {
- "message": "कॉनबेस पर खरीदें"
+ "message": "कॉइनबेस पर खरीदें"
},
"buyCoinbaseExplainer": {
- "message": "बिल्टकोइन, एथरेम और लाइटकोइन खरीदने और बेचने के लिए दुनिया का सबसे लोकप्रिय तरीका Coinbase है।"
+ "message": "बिल्टकोइन, इथीरियम और लाइटकोइन खरीदने और बेचने के लिए दुनिया का सबसे लोकप्रिय तरीका कॉइनबेस है।"
},
"cancel": {
"message": "रद्द करें"
@@ -108,7 +108,7 @@
"message": "जारी रखें"
},
"continueToCoinbase": {
- "message": "कॉ्ोनबेस को ब्हेजना जारी रखें"
+ "message": "कॉइनबेस को ब्हेजना जारी रखें"
},
"contractDeployment": {
"message": "अनुबंध परिनियोजन व तैनाती"
@@ -435,13 +435,13 @@
"message": "बीज शब्द में केवल लोअरकेस वर्ण होते हैं"
},
"mainnet": {
- "message": "मुख्य ईथरम नेटवर्क"
+ "message": "मुख्य इथीरियम नेटवर्क"
},
"message": {
"message": "संदेश"
},
"metamaskDescription": {
- "message": "मेटामास्क एथर्मम के लिए एक सुरक्षित पहचान वॉल्ट है।"
+ "message": "मेटामास्क इथीरियम के लिए एक सुरक्षित पहचान वॉल्ट है।"
},
"min": {
"message": "न्यूनतम"
@@ -649,7 +649,7 @@
"message": "भेजें टोकन"
},
"sendTokensAnywhere": {
- "message": "इटोरम खाते वाले किसी को भी टोकन भेजें"
+ "message": "इथीरियम खाते वाले किसी को भी टोकन भेजें"
},
"settings": {
"message": "सेटिंग्स"
diff --git a/app/_locales/index.json b/app/_locales/index.json
index c085deb72..7717502b7 100644
--- a/app/_locales/index.json
+++ b/app/_locales/index.json
@@ -1,4 +1,5 @@
[
+ { "code": "cs", "name": "Czech" },
{ "code": "de", "name": "German" },
{ "code": "en", "name": "English" },
{ "code": "es", "name": "Spanish" },
@@ -13,6 +14,8 @@
{ "code": "ru", "name": "Russian" },
{ "code": "sl", "name": "Slovenian" },
{ "code": "th", "name": "Thai" },
+ { "code": "tml", "name": "Tamil" },
+ { "code": "tr", "name": "Turkish" },
{ "code": "vi", "name": "Vietnamese" },
{ "code": "zh_CN", "name": "Mandarin" },
{ "code": "zh_TW", "name": "Taiwanese" }
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index d9762a3e9..3a664ec00 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -20,6 +20,9 @@
"addToken": {
"message": "トークンを追加"
},
+ "addTokens": {
+ "message": "トークンを追加"
+ },
"amount": {
"message": "金額"
},
@@ -46,6 +49,9 @@
"balance": {
"message": "残高:"
},
+ "balances": {
+ "message": "トークン残高"
+ },
"balanceIsInsufficientGas": {
"message": "現在のガス総量に対して残高が不足しています"
},
@@ -63,10 +69,10 @@
"message": "購入"
},
"buyCoinbase": {
- "message": "Coinbaseで購入"
+ "message": "Coinbaseのサイトで購入"
},
"buyCoinbaseExplainer": {
- "message": "Coinbaseは、世界的なBitcoin、Ethereum、そしてLitecoinの取引所です。"
+ "message": "Etherを購入できます。Coinbaseは、世界的なBitcoin、Ethereum、そしてLitecoinの取引所です。"
},
"cancel": {
"message": "キャンセル"
@@ -90,7 +96,7 @@
"message": "トランザクションの確認"
},
"continueToCoinbase": {
- "message": "Coinbaseで続行"
+ "message": "Coinbaseを開く"
},
"contractDeployment": {
"message": "コントラクトのデプロイ"
@@ -138,6 +144,9 @@
"customGas": {
"message": "ガスのカスタマイズ"
},
+ "customToken": {
+ "message": "カスタムトークン"
+ },
"customize": {
"message": "カスタマイズ"
},
@@ -154,20 +163,20 @@
"message": "DENとは、あなたのパスワードが暗号化されたMetaMask内のストレージです。"
},
"deposit": {
- "message": "受取り"
+ "message": "振込"
},
"depositBTC": {
- "message": "あなたのBTCを次のアドレスへデポジット:"
+ "message": "BTCを下記のアドレスへ振込んでください:"
},
"depositCoin": {
- "message": "あなたの $1を次のアドレスへデポジット",
+ "message": "$1を下記のアドレスへ振込んでください",
"description": "Tells the user what coin they have selected to deposit with shapeshift"
},
"depositEth": {
- "message": "ETHをデポジット"
+ "message": "ETHを入金"
},
"depositEther": {
- "message": "Etherをデポジット"
+ "message": "Etherを振込"
},
"depositFiat": {
"message": "法定通貨でデポジット"
@@ -176,10 +185,10 @@
"message": "別のアカウントから入金"
},
"depositShapeShift": {
- "message": "ShapeShiftで入金"
+ "message": "ShapeShiftで交換"
},
"depositShapeShiftExplainer": {
- "message": "他の暗号通貨をEtherと交換してMetaMaskのウォレットへ入金できます。アカウント作成は不要です。"
+ "message": "他の暗号通貨とEtherを交換して、MetaMaskのウォレットへ入金できます。アカウント作成は不要です。"
},
"details": {
"message": "詳細"
@@ -188,10 +197,10 @@
"message": "ダイレクトデポジット"
},
"directDepositEther": {
- "message": "Etherを直接受け取り"
+ "message": "Etherを直接入金"
},
"directDepositEtherExplainer": {
- "message": "Etherをすでにお持ちなら、MetaMaskの新しいウォレットにEtherを送信することができます。"
+ "message": "既にEtherをお持ちなら、MetaMaskの新しいウォレットにEtherを送信することができます。"
},
"done": {
"message": "完了"
@@ -209,7 +218,7 @@
"message": "パスワードを入力"
},
"etherscanView": {
- "message": "Etherscanでアカウントを参照"
+ "message": "Etherscanでアカウントを確認"
},
"exchangeRate": {
"message": "交換レート"
@@ -266,7 +275,7 @@
"message": "必要ガスプライス"
},
"getEther": {
- "message": "Etherをゲット"
+ "message": "Etherを取得する"
},
"getEtherFromFaucet": {
"message": "フォーセットで $1のEtherを得ることができます。",
@@ -287,7 +296,7 @@
"message": "トークンを隠す"
},
"hideTokenPrompt": {
- "message": "トークンを隠しますか??"
+ "message": "トークンを隠しますか?"
},
"howToDeposit": {
"message": "どのようにEtherをデポジットしますか?"
@@ -300,7 +309,7 @@
"message": "アカウントのインポート"
},
"importAccountMsg": {
- "message":"追加したアカウントはMetaMaskのアカウントシードフレーズとは関連付けられません。インポートしたアカウントについての詳細は"
+ "message":"追加したアカウントはMetaMaskのアカウントパスフレーズとは関連付けられません。インポートしたアカウントについての詳細は"
},
"importAnAccount": {
"message": "アカウントをインポート"
@@ -334,13 +343,22 @@
"message": "JSONファイル",
"description": "format for importing an account"
},
+ "keepTrackTokens": {
+ "message": "MetaMaskアカウントで入手したトークンを検索できます。"
+ },
"kovan": {
"message": "Kovanテストネットワーク"
},
+ "learnMore": {
+ "message": "詳細"
+ },
"lessThanMax": {
"message": " $1以下にして下さい。",
"description": "helper for inputting hex as decimal input"
},
+ "likeToAddTokens": {
+ "message": "トークンを追加しますか?"
+ },
"limit": {
"message": "リミット"
},
@@ -371,8 +389,11 @@
"myAccounts": {
"message": "マイアカウント"
},
+ "mustSelectOne": {
+ "message": "一つ以上のトークンを選択してください。"
+ },
"needEtherInWallet": {
- "message": "MetaMaskを使って分散型アプリケーションを使用するためには、このウォレットにEtherが必要です。"
+ "message": "MetaMaskで分散型アプリケーションを使用するためには、このウォレットにEtherが必要です。"
},
"needImportFile": {
"message": "インポートするファイルを選択してください。",
@@ -411,7 +432,7 @@
"message": "この名前にはアドレスが設定されていません。"
},
"noDeposits": {
- "message": "デポジットがありません。"
+ "message": "振込みがありません。"
},
"noTransactionHistory": {
"message": "トランザクション履歴がありません。"
@@ -445,10 +466,13 @@
"description": "For importing an account from a private key"
},
"pasteSeed": {
- "message": "シードをここにペーストして下さい!"
+ "message": "パスフレーズをここにペーストして下さい!"
},
"pleaseReviewTransaction": {
- "message": "トランザクションをレビューして下さい。"
+ "message": "トランザクションを確認して下さい。"
+ },
+ "popularTokens": {
+ "message": "人気のトークン"
},
"privateKey": {
"message": "秘密鍵",
@@ -470,13 +494,13 @@
"message": "もっと読む"
},
"receive": {
- "message": "受け取る"
+ "message": "受取"
},
"recipientAddress": {
"message": "受取人アドレス"
},
"refundAddress": {
- "message": "あなたの返金先アドレス"
+ "message": "受取アドレス"
},
"rejected": {
"message": "拒否されました"
@@ -487,12 +511,18 @@
"restoreFromSeed": {
"message": "パスフレーズから復元する"
},
+ "restoreVault": {
+ "message": "ウォレットを復元する"
+ },
"required": {
"message": "必要です。"
},
"retryWithMoreGas": {
"message": "より高いガスプライスで再度試して下さい。"
},
+ "walletSeed": {
+ "message": "ウォレットのパスフレーズ"
+ },
"revealSeedWords": {
"message": "パスフレーズを表示"
},
@@ -519,23 +549,35 @@
"selectService": {
"message": "サービスを選択"
},
+ "selectType": {
+ "message": "キーの種類"
+ },
"send": {
"message": "送信"
},
+ "sendETH": {
+ "message": "ETHの送信"
+ },
"sendTokens": {
"message": "トークンを送る"
},
"onlySendToEtherAddress": {
"message": "ETHはイーサリウムアカウントのみに送信できます。"
},
+ "searchTokens": {
+ "message": "トークンの検索"
+ },
"sendTokensAnywhere": {
"message": "イーサリアムアカウントを持っている人にトークンを送る"
},
"settings": {
"message": "設定"
},
+ "info": {
+ "message": "情報"
+ },
"shapeshiftBuy": {
- "message": "Shapeshiftで買う"
+ "message": "Shapeshiftで交換"
},
"showPrivateKeys": {
"message": "秘密鍵を表示"
@@ -565,13 +607,13 @@
"message": "送信"
},
"takesTooLong": {
- "message": "長くかかりすぎていますか?"
+ "message": "送信に時間がかかりますか?"
},
"testFaucet": {
"message": "Faucetをテスト"
},
"to": {
- "message": "宛先"
+ "message": "送信先"
},
"toETHviaShapeShift": {
"message": "ShapeShiftで $1をETHにする",
@@ -595,6 +637,9 @@
"total": {
"message": "合計"
},
+ "transactions": {
+ "message": "トランザクション"
+ },
"transactionMemo": {
"message": "トランザクションメモ (オプション)"
},
@@ -609,7 +654,7 @@
"description": "Followed by a link (here) to view token balances"
},
"typePassword": {
- "message": "パスワードタイプ"
+ "message": "パスワードの入力"
},
"uiWelcome": {
"message": "新UIへようこそ!(ベータ版)"
@@ -646,7 +691,7 @@
"message": "警告"
},
"whatsThis": {
- "message": "これは何でしょう?"
+ "message": "この機能について"
},
"yourSigRequested": {
"message": "あなたの署名がリクエストされています。"
diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json
index b089f3476..25bd0bcbb 100644
--- a/app/_locales/sl/messages.json
+++ b/app/_locales/sl/messages.json
@@ -181,7 +181,7 @@
"message": "DEN je vaša šifrirana shramba v MetaMasku."
},
"deposit": {
- "message": "Vplačilo"
+ "message": "Vplačaj"
},
"depositBTC": {
"message": "Vplačajte vaš BTC na spodnji naslov:"
@@ -507,10 +507,10 @@
"message": "Ni se začelo"
},
"oldUI": {
- "message": "Starejši uporabniški vmesnik"
+ "message": "Star UI"
},
"oldUIMessage": {
- "message": "Vrnili ste se v starejši uporabniški vmesnik. V novega se lahko vrnete z možnostjo v spustnem meniju v zgornjem desnem kotu."
+ "message": "Vrnili ste se v star uporabniški vmesnik. V novega se lahko vrnete z možnostjo v spustnem meniju v zgornjem desnem kotu."
},
"or": {
"message": "ali",
@@ -759,7 +759,7 @@
"message": "Vpišite vaše geslo"
},
"uiWelcome": {
- "message": "Dobrodošli v novem uporabniškem vmesniku (Beta)"
+ "message": "Dobrodošli v nov UI (Beta)"
},
"uiWelcomeMessage": {
"message": "Zdaj uporabljate novi MetaMask uporabniški vmesnik. Razglejte se, preizkusite nove funkcije, kot so pošiljanje žetonov, in nas obvestite, če imate kakšne težave."
diff --git a/app/_locales/tml/messages.json b/app/_locales/tml/messages.json
new file mode 100644
index 000000000..fcc418bac
--- /dev/null
+++ b/app/_locales/tml/messages.json
@@ -0,0 +1,912 @@
+{
+ "accept": {
+ "message": "ஏற்கவும்"
+ },
+ "account": {
+ "message": "கணக்கு"
+ },
+ "accountDetails": {
+ "message": "கணக்கு விவரங்கள்"
+ },
+ "accountName": {
+ "message": "கணக்கின் பெயர்"
+ },
+ "address": {
+ "message": "முகவரி"
+ },
+ "addCustomToken": {
+ "message": "தனிப்பயன் டோக்கனைச் சேர்க்கவும்"
+ },
+ "addToken": {
+ "message": "டோக்கனைச் சேர்"
+ },
+ "addTokens": {
+ "message": "டோக்கன்களைச் சேர்"
+ },
+ "amount": {
+ "message": "தொகை"
+ },
+ "amountPlusGas": {
+ "message": "தொகை + எரிவாயு"
+ },
+ "appDescription": {
+ "message": "எதெரியும் பிரௌசர் நீட்டிப்பு",
+ "description": "பயன்பாட்டின் விளக்கம்"
+ },
+ "appName": {
+ "message": "மேடமஸ்க் ",
+ "description": "பயன்பாட்டின் பெயர்"
+ },
+ "approved": {
+ "message": "அங்கீகரிக்கப்பட்ட"
+ },
+ "attemptingConnect": {
+ "message": "இணைக்க முயற்சி செய்க ப்ளாக்சைன்"
+ },
+ "attributions": {
+ "message": "பண்புகளும்"
+ },
+ "available": {
+ "message": "கிடைக்கும்"
+ },
+ "back": {
+ "message": "மீண்டும்"
+ },
+ "balance": {
+ "message": "இருப்பு:"
+ },
+ "balances": {
+ "message": "உங்கள் இருப்பு"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "நடப்பு வாயு மொத்தம் போதுமான சமநிலை"
+ },
+ "beta": {
+ "message": "பீட்டா"
+ },
+ "betweenMinAndMax": {
+ "message": "$ 1 க்கும் அதிகமாகவும் அல்லது $ 2 க்கு சமமாகவும் இருக்க வேண்டும்.",
+ "description": "ஹெக்ஸ் உள்ளீடு தசம உள்ளீடு என உதவி"
+ },
+ "blockiesIdenticon": {
+ "message": "ப்ளாக்கிஸ் ஐடென்டிகோன் பயன்பாட்டு"
+ },
+ "borrowDharma": {
+ "message": "தர்மத்துடன் கடன் வாங்குங்கள் (பீட்டா)"
+ },
+ "builtInCalifornia": {
+ "message": "மேடமஸ்க் வடிவமைக்கப்பட்டு கலிபோர்னியாவில் கட்டப்பட்டுள்ளது."
+ },
+ "buy": {
+ "message": "வாங்க"
+ },
+ "buyCoinbase": {
+ "message": "கோஇன்பசே வாங்கவும்"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "கோஇன்பசே பிறகாய்ன் , எதெரியும் மற்றும் ளிட்டசோன் வாங்க மற்றும் விற்க உலகின் மிகவும் பிரபலமான வழி"
+ },
+ "ok": {
+ "message": "சரி"
+ },
+ "cancel": {
+ "message": "ரத்து"
+ },
+ "classicInterface": {
+ "message": "கிளாசிக் இடைமுகத்தைப் பயன்படுத்தவும்"
+ },
+ "clickCopy": {
+ "message": "நகலெடுக்க கிளிக் செய்யவும்"
+ },
+ "confirm": {
+ "message": "உறுதிப்படுத்தவும்"
+ },
+ "confirmed": {
+ "message": "உறுதி"
+ },
+ "confirmContract": {
+ "message": "ஒப்பந்தத்தை உறுதிப்படுத்துக"
+ },
+ "confirmPassword": {
+ "message": "கடவுச்சொல்லை உறுதிப்படுத்துக"
+ },
+ "confirmTransaction": {
+ "message": "பரிவர்த்தனை உறுதிபடுத்தவும்"
+ },
+ "continue": {
+ "message": "தொடர்ந்து"
+ },
+ "continueToCoinbase": {
+ "message": "கோஇன்பசே ஐத் தொடரவும்"
+ },
+ "contractDeployment": {
+ "message": "ஒப்பந்த வரிசைப்படுத்தல்"
+ },
+ "conversionProgress": {
+ "message": "மாற்றம் முன்னேற்றம்"
+ },
+ "copiedButton": {
+ "message": "நகலெடுக்கப்பட்டன"
+ },
+ "copiedClipboard": {
+ "message": "கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது"
+ },
+ "copiedExclamation": {
+ "message": "நகலெடுக்கப்பட்டன!"
+ },
+ "copiedSafe": {
+ "message": "நான் எங்காவது பாதுகாப்பாக நகலெடுத்திருக்கிறேன்"
+ },
+ "copy": {
+ "message": "நகல்"
+ },
+ "copyToClipboard": {
+ "message": "கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது"
+ },
+ "copyButton": {
+ "message": " நகல் "
+ },
+ "copyPrivateKey": {
+ "message": "இது உங்கள் தனிப்பட்ட விசை (நகலெடுக்க கிளிக் செய்யவும்)"
+ },
+ "create": {
+ "message": "உருவாக்கவும்"
+ },
+ "createAccount": {
+ "message": "உங்கள் கணக்கை துவங்குங்கள்"
+ },
+ "createDen": {
+ "message": "உருவாக்கவும்"
+ },
+ "crypto": {
+ "message": "கிரிப்டோ",
+ "description": "பரிமாற்ற வகை (கிரிப்டோசுர்ரென்சிஸ்)"
+ },
+ "currentConversion": {
+ "message": "தற்போதைய மாற்றம்"
+ },
+ "currentNetwork": {
+ "message": "தற்போதைய நெட்வொர்க்"
+ },
+ "customGas": {
+ "message": "எரிவாயுவைத் தனிப்பயனாக்குங்கள்"
+ },
+ "customToken": {
+ "message": "தனிப்பயன் டோக்கன்"
+ },
+ "customize": {
+ "message": "தனிப்பயனாக்கலாம்"
+ },
+ "customRPC": {
+ "message": "விருப்ப RPC ஐ"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "தசமங்கள் குறைந்தபட்சம் 0, மற்றும் 36 க்கு மேல் இருக்க வேண்டும்."
+ },
+ "decimal": {
+ "message": "துல்லியத்தின் முடிவு"
+ },
+ "defaultNetwork": {
+ "message": "எதிர் பரிவர்த்தனைகளுக்கான முன்னிருப்பு வலையமைப்பு முதன்மை நிகரமாகும்."
+ },
+ "denExplainer": {
+ "message": "உங்கள் DEN என்பது உங்கள் கடவுச்சொல்-மறைகுறியாக்கப்பட்ட சேமிப்பகம் மெட்டாமாஸ்க்கிற்குள்."
+ },
+ "deposit": {
+ "message": "வைப்புத்தொகை"
+ },
+ "depositBTC": {
+ "message": "கீழே உங்கள் முகவரிக்கு உங்கள் BTC வைப்போம்:"
+ },
+ "depositCoin": {
+ "message": "உங்கள் முகவரிக்கு $ 1 ஐ கீழே உள்ளிடவும்",
+ "description": "சேபஷிபிட் உடன் வைப்புக்குத் தேர்ந்தெடுக்கப்பட்ட நாணயத்தை பயனரிடம் கூறுகிறார்"
+ },
+ "depositEth": {
+ "message": "வைப்புத்தொகை எது "
+ },
+ "depositEther": {
+ "message": "வைப்புத்தொகை எதிர் "
+ },
+ "depositFiat": {
+ "message": "ஃபியட் உடன் வைப்பு"
+ },
+ "depositFromAccount": {
+ "message": "மற்றொரு கணக்கிலிருந்து வைப்பு"
+ },
+ "depositShapeShift": {
+ "message": "ShapeShift உடன் வைப்பு"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "நீங்கள் மற்ற கிரிப்டோகிராரன்கள் சொந்தமாக வைத்திருந்தால், உங்கள் மெட்டாமாஸ்க் பணப்பையில் நேரடியாக ஈதரை வர்த்தகம் செய்யலாம் மற்றும் வைப்பு செய்யலாம். கணக்கு தேவையில்லை."
+ },
+ "details": {
+ "message": "விவரங்கள்"
+ },
+ "directDeposit": {
+ "message": "நேரடி வைப்பு"
+ },
+ "directDepositEther": {
+ "message": "நேரடியாக வைப்புத்தொகை"
+ },
+ "directDepositEtherExplainer": {
+ "message": "நீங்கள் ஏற்கனவே ஏதெர் இருந்தால், நேரடி வைப்பு மூலம் உங்கள் புதிய பணப்பையில் ஈத்தர் பெற விரைவான வழி."
+ },
+ "done": {
+ "message": "முடிந்தது"
+ },
+ "downloadStateLogs": {
+ "message": "மாநில பதிவுகள் பதிவிறக்க"
+ },
+ "dropped": {
+ "message": "நீக்கப்பட்டார்"
+ },
+ "edit": {
+ "message": "தொகு"
+ },
+ "editAccountName": {
+ "message": "கணக்கு பெயரை மாற்றுக"
+ },
+ "emailUs": {
+ "message": "எங்களுக்கு மின்னஞ்சல்!"
+ },
+ "encryptNewDen": {
+ "message": "உங்கள் புதிய DEN ஐ குறியாக்குக"
+ },
+ "enterPassword": {
+ "message": "கடவுச்சொல்லை உள்ளிடவும்"
+ },
+ "enterPasswordConfirm": {
+ "message": "உறுதிப்படுத்த உங்கள் கடவுச்சொல்லை உள்ளிடவும்"
+ },
+ "passwordNotLongEnough": {
+ "message": "கடவுச்சொல் போதாது"
+ },
+ "passwordsDontMatch": {
+ "message": "கடவுச்சொற்கள் பொருந்தாதே"
+ },
+ "etherscanView": {
+ "message": "Etherscan கணக்கைப் பார்க்கவும்"
+ },
+ "exchangeRate": {
+ "message": "மாற்று விகிதம்"
+ },
+ "exportPrivateKey": {
+ "message": "தனியார் விசை ஐ ஏற்றுமதி செய்க"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "தனிப்பட்ட விசைகளை உங்கள் சொந்த ஆபத்தில் ஏற்றுமதி செய்யுங்கள்."
+ },
+ "failed": {
+ "message": "தோல்வி"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "பரிமாற்ற வகை"
+ },
+ "fileImportFail": {
+ "message": "கோப்பு இறக்குமதி வேலை செய்யவில்லையா? இங்கே கிளிக் செய்யவும்!",
+ "description": "JSON கோப்பில் பயனர் கணக்கை தங்கள் கணக்கை இறக்குமதி செய்ய உதவுகிறது"
+ },
+ "followTwitter": {
+ "message": "Twitter இல் எங்களைப் பின்தொடரவும்"
+ },
+ "from": {
+ "message": "இருந்து"
+ },
+ "fromToSame": {
+ "message": "இருந்து மற்றும் முகவரி அதே இருக்க முடியாது"
+ },
+ "fromShapeShift": {
+ "message": "ShapeShift இலிருந்து"
+ },
+ "gas": {
+ "message": "எரிவாயு",
+ "description": "எரிவாயு விலை குறையும்"
+ },
+ "gasFee": {
+ "message": "எரிவாயு கட்டணம்"
+ },
+ "gasLimit": {
+ "message": "எரிவாயு வரம்பு"
+ },
+ "gasLimitCalculation": {
+ "message": "நெட்வொர்க் வெற்றி விகிதங்களின் அடிப்படையில் பரிந்துரைக்கப்பட்ட எரிவாயு வரம்பை நாங்கள் கணக்கிடுகிறோம்."
+ },
+ "gasLimitRequired": {
+ "message": "எரிவாயு வரம்பு தேவை"
+ },
+ "gasLimitTooLow": {
+ "message": "எரிவாயு வரம்பு குறைந்தது 21000 ஆக இருக்க வேண்டும்"
+ },
+ "generatingSeed": {
+ "message": "விதை உருவாக்குகிறது ..."
+ },
+ "gasPrice": {
+ "message": "எரிவாயு விலை (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "நெட்வொர்க் வெற்றி விகிதங்களின் அடிப்படையில் பரிந்துரைக்கப்பட்ட எரிவாயு விலைகளை நாங்கள் கணக்கிடுகிறோம்."
+ },
+ "gasPriceRequired": {
+ "message": "எரிவாயு விலை தேவைப்படுகிறது"
+ },
+ "getEther": {
+ "message": "ஈத்தர் கிடைக்கும்"
+ },
+ "getEtherFromFaucet": {
+ "message": "$ 1 க்கு ஒரு குழாய் இருந்து ஈதர் கிடைக்கும்$1",
+ "description": "ஈத்தர் குழாய் ஐந்து பிணைய பெயர் காட்டுகிறது"
+ },
+ "greaterThanMin": {
+ "message": "$ 1 க்கும் அதிகமாகவோ அல்லது சமமாகவோ இருக்க வேண்டும்",
+ "description": "ஹெக்ஸ் உள்ளீடு தசம உள்ளீடு என உதவி"
+ },
+ "here": {
+ "message": "இங்கே",
+ "description": "இங்கே-கிளிக் செய்யவும்- மேலும் தகவலுக்கு (troubleTokenBalances செல்கிறது)"
+ },
+ "hereList": {
+ "message": "இங்கே ஒரு பட்டியல் !!!!"
+ },
+ "hide": {
+ "message": "மறை"
+ },
+ "hideToken": {
+ "message": "டோக்கனை மறை"
+ },
+ "hideTokenPrompt": {
+ "message": "டோக்கனை மறை?"
+ },
+ "howToDeposit": {
+ "message": "எப்படி ஈத்தர் வைப்பது?"
+ },
+ "holdEther": {
+ "message": "இது நீங்கள் ஈத்தர் மற்றும் டோக்கன்களை வைத்திருக்க உதவுகிறது, மற்றும் பரவலாக்கப்பட்ட பயன்பாடுகளுக்கு உங்கள் பாலமாக செயல்படுகிறது."
+ },
+ "import": {
+ "message": "இறக்குமதி",
+ "description": "தேர்ந்தெடுக்கப்பட்ட கோப்பிலிருந்து ஒரு கணக்கை இறக்குமதி செய்ய பொத்தானை அழுத்தவும்"
+ },
+ "importAccount": {
+ "message": "கணக்கை இறக்குமதி செய்க"
+ },
+ "importAccountMsg": {
+ "message":" இறக்குமதி செய்யப்பட்ட கணக்கு உங்கள் முதலில் உருவாக்கப்பட்ட மெட்டாமாஸ்க் கணக்கு விதை மூலம் தொடர்புடையதாக இருக்காது. இறக்குமதி செய்யப்பட்ட கணக்குகள் பற்றி மேலும் அறிக "
+ },
+ "importAnAccount": {
+ "message": "ஒரு கணக்கை இறக்குமதி செய்க"
+ },
+ "importDen": {
+ "message": "இறக்குமதி DEN இறக்குமதி"
+ },
+ "imported": {
+ "message": "இறக்குமதி",
+ "description": "ஒரு கணக்கு முழுமையாக விசைப்பலகையில் ஏற்றப்பட்டதைக் காட்டுகிறது"
+ },
+ "infoHelp": {
+ "message": "தகவல் மற்றும் உதவி"
+ },
+ "insufficientFunds": {
+ "message": "போதுமான பணம் இல்லை."
+ },
+ "insufficientTokens": {
+ "message": "போதுமான டோக்கன்கள்."
+ },
+ "invalidAddress": {
+ "message": "தவறான முகவரி"
+ },
+ "invalidAddressRecipient": {
+ "message": "பெறுநர் முகவரி தவறானது"
+ },
+ "invalidGasParams": {
+ "message": "தவறான எரிவாயு அளவுருக்கள்"
+ },
+ "invalidInput": {
+ "message": "தவறான உள்ளீடு.."
+ },
+ "invalidRequest": {
+ "message": "தவறான கோரிக்கை"
+ },
+ "invalidRPC": {
+ "message": "தவறான RPC URI"
+ },
+ "jsonFail": {
+ "message": "ஏதோ தவறு நடந்துவிட்டது. உங்கள் JSON கோப்பு ஒழுங்காக வடிவமைக்கப்பட்டுள்ளது என்பதை உறுதிப்படுத்தவும்"
+ },
+ "jsonFile": {
+ "message": "JSON கோப்பு",
+ "description": "ஒரு கணக்கை இறக்குமதி செய்ய வடிவமைக்கப்பட்டுள்ளது"
+ },
+ "keepTrackTokens": {
+ "message": "உங்கள் மேடமஸ்க் கணக்குடன் நீங்கள் வாங்கிய டோக்கன்களை கண்காணியுங்கள்."
+ },
+ "kovan": {
+ "message": "கோவன் டெஸ்ட் நெட்வொர்க்"
+ },
+ "knowledgeDataBase": {
+ "message": "எங்கள் அறிவுத் தளத்தைப் பார்வையிடவும்"
+ },
+ "max": {
+ "message": "மேக்ஸ்"
+ },
+ "learnMore": {
+ "message": "மேலும் அறிக"
+ },
+ "lessThanMax": {
+ "message": "$ 1 க்கும் குறைவாகவோ அல்லது சமமாகவோ இருக்க வேண்டும்.",
+ "description": "ஹெக்ஸ் உள்ளீடு தசம உள்ளீடு என உதவி"
+ },
+ "likeToAddTokens": {
+ "message": "இந்த டோக்கன்களைச் சேர்க்க விரும்புகிறீர்களா?"
+ },
+ "links": {
+ "message": "இணைப்புகள்"
+ },
+ "limit": {
+ "message": "அளவு"
+ },
+ "loading": {
+ "message": "ஏற்றுதல் ..."
+ },
+ "loadingTokens": {
+ "message": "டோக்கன்களை ஏற்றுகிறது ..."
+ },
+ "localhost": {
+ "message": "லோக்கல் ஹோஸ்ட் 8545"
+ },
+ "login": {
+ "message": "உள் நுழை"
+ },
+ "logout": {
+ "message": "வெளியேறு"
+ },
+ "loose": {
+ "message": "லூஸ்"
+ },
+ "loweCaseWords": {
+ "message": "விதை வார்த்தைகள் ஸ்மால் எழுத்துகள் மட்டுமே"
+ },
+ "mainnet": {
+ "message": "முதன்மை எதெரியும் நெட்வொர்க்"
+ },
+ "message": {
+ "message": "செய்தி"
+ },
+ "metamaskDescription": {
+ "message": "மேடமஸ்க் என்பது ஒரு பாதுகாப்பான அடையாள வால்ட் எதெரியும்"
+ },
+ "min": {
+ "message": "குறைந்தபட்ச"
+ },
+ "myAccounts": {
+ "message": "எனது கணக்குகள்"
+ },
+ "mustSelectOne": {
+ "message": "குறைந்தது 1 டோக்கனை தேர்ந்தெடுக்க வேண்டும்."
+ },
+ "needEtherInWallet": {
+ "message": "மேடமஸ்க் ஐ பயன்படுத்தி பரவலாக்கப்பட்ட பயன்பாடுகளுடன் தொடர்பு கொள்ள, உங்கள் பணப்பரிமாற்றத்தில் ஈதர் தேவை."
+ },
+ "needImportFile": {
+ "message": "இறக்குமதி செய்ய ஒரு கோப்பை நீங்கள் தேர்ந்தெடுக்க வேண்டும்.",
+ "description": "பயனர் ஒரு கணக்கு முக்கியம் மற்றும் தொடர ஒரு கோப்பு சேர்க்க வேண்டும்"
+ },
+ "needImportPassword": {
+ "message": "நீங்கள் தேர்ந்தெடுத்த கோப்புக்கு ஒரு கடவுச்சொல்லை உள்ளிட வேண்டும்.",
+ "description": "ஒரு கணக்கை இறக்குமதி செய்ய கடவுச்சொல் மற்றும் கோப்பு தேவை"
+ },
+ "negativeETH": {
+ "message": "ETH எதிர்மறை அளவுகளை அனுப்ப முடியாது."
+ },
+ "networks": {
+ "message": "நெட்வொர்க்ஸ்"
+ },
+ "newAccount": {
+ "message": "புதிய கணக்கு"
+ },
+ "newAccountNumberName": {
+ "message": "கணக்கு $ 1",
+ "description": "கணக்கு கணக்கை உருவாக்குவதற்கு அடுத்த கணக்கின் இயல்புநிலை பெயர் உருவாக்கப்படும்"
+ },
+ "newContract": {
+ "message": "புதிய ஒப்பந்தம்"
+ },
+ "newPassword": {
+ "message": "புதிய கடவுச்சொல் (min 8 எழுத்துகள்)"
+ },
+ "newRecipient": {
+ "message": "புதிய பெறுநர்"
+ },
+ "newRPC": {
+ "message": "புதிய RPC URL"
+ },
+ "next": {
+ "message": "அடுத்த"
+ },
+ "noAddressForName": {
+ "message": "இந்த பெயருக்கான முகவரி அமைக்கப்படவில்லை."
+ },
+ "noDeposits": {
+ "message": "எந்த வைப்புகளும் கிடைக்கவில்லை"
+ },
+ "noTransactionHistory": {
+ "message": "பரிவர்த்தனை வரலாறு இல்லை."
+ },
+ "noTransactions": {
+ "message": "பரிவர்த்தனைகள் இல்லை"
+ },
+ "notStarted": {
+ "message": "துவங்கவில்லை"
+ },
+ "oldUI": {
+ "message": "பழைய UI"
+ },
+ "oldUIMessage": {
+ "message": "நீங்கள் பழைய UI க்கு திரும்பியுள்ளீர்கள். மேல் வலது கீழ்தோன்றும் மெனுவில் உள்ள விருப்பத்தின் மூலம் புதிய UI ஐ மீண்டும் மாறலாம்."
+ },
+ "or": {
+ "message": "அல்லது",
+ "description": "ஒரு புதிய கணக்கை உருவாக்க அல்லது இறக்குமதி செய்வதற்கு இடையே தேர்வு"
+ },
+ "passwordCorrect": {
+ "message": "தயவுசெய்து உங்கள் கடவுச்சொல் சரியானதா என உறுதிப்படுத்தவும்."
+ },
+ "passwordMismatch": {
+ "message": "கடவுச்சொற்கள் பொருந்தவில்லை",
+ "description": "கடவுச்சொல் உருவாக்கத்தில், இரண்டு புதிய கடவுச்சொல் புலங்கள் பொருந்தவில்லை"
+ },
+ "passwordShort": {
+ "message": "கடவுச்சொல் நீண்ட காலமாக இல்லை",
+ "description": "கடவுச்சொல் உருவாக்கத்தில், பாதுகாப்பானதாக இருக்கும் கடவுச்சொல் போதும்"
+ },
+ "pastePrivateKey": {
+ "message": "இங்கே உங்கள் தனிப்பட்ட விசை சரத்தை ஒட்டுக:",
+ "description": "ஒரு தனிப்பட்ட விசை ஒரு கணக்கை இறக்குமதி செய்ய"
+ },
+ "pasteSeed": {
+ "message": "இங்கே உங்கள் விதை சொற்றொடரை ஒட்டவும்!"
+ },
+ "personalAddressDetected": {
+ "message": "தனிப்பட்ட முகவரி கண்டறியப்பட்டது. டோக்கன் ஒப்பந்த முகவரியை உள்ளிடவும்."
+ },
+ "pleaseReviewTransaction": {
+ "message": "உங்கள் பரிவர்த்தனை மதிப்பாய்வு செய்யவும்."
+ },
+ "popularTokens": {
+ "message": "பிரபலமான டோக்கன்கள்"
+ },
+ "privacyMsg": {
+ "message": "தனியுரிமை கொள்கை"
+ },
+ "privateKey": {
+ "message": "தனிப்பட்ட விசை",
+ "description": "ஒரு கணக்கை இறக்குமதி செய்ய பயன்படுத்த இந்த வகை கோப்பை தேர்ந்தெடுக்கவும்"
+ },
+ "privateKeyWarning": {
+ "message": "எச்சரிக்கை: இந்த விசையை எப்போதும் வெளியிட வேண்டாம். உங்கள் தனிப்பட்ட விசைகளைக் கொண்ட எவரும் உங்கள் கணக்கில் உள்ள எந்த சொத்துக்களையும் திருடலாம்."
+ },
+ "privateNetwork": {
+ "message": "தனியார் நெட்வொர்க்"
+ },
+ "qrCode": {
+ "message": "QR குறியீட்டைக் காட்டு"
+ },
+ "readdToken": {
+ "message": "உங்கள் கணக்கு விருப்பங்கள் மெனுவில் \"டோக்கனைச் சேர்\" என்பதன் மூலம் நீங்கள் எதிர்காலத்தில் இந்த டோக்கனை மீண்டும் சேர்க்கலாம்."
+ },
+ "readMore": {
+ "message": "மேலும் வாசிக்க இங்கே."
+ },
+ "readMore2": {
+ "message": "மேலும் வாசிக்க."
+ },
+ "receive": {
+ "message": "பெறுக"
+ },
+ "recipientAddress": {
+ "message": "பெறுநர் முகவரி"
+ },
+ "refundAddress": {
+ "message": "உங்கள் பணத்தை திருப்பி அனுப்பும் முகவரி"
+ },
+ "rejected": {
+ "message": "நிராகரிக்கப்பட்டது"
+ },
+ "resetAccount": {
+ "message": "கணக்கை மீட்டமை"
+ },
+ "restoreFromSeed": {
+ "message": "விதை வாக்கியத்திலிருந்து மீட்கவும்"
+ },
+ "restoreVault": {
+ "message": "வால்ட் மீட்கவும்"
+ },
+ "required": {
+ "message": "தேவையான"
+ },
+ "retryWithMoreGas": {
+ "message": "இங்கே அதிக எரிவாயு விலை மீண்டும் முயற்சிக்கவும்"
+ },
+ "walletSeed": {
+ "message": "வால்ட் விதை"
+ },
+ "revealSeedWords": {
+ "message": "விதை வார்த்தைகள் வெளிப்படுத்த"
+ },
+ "revealSeedWordsWarning": {
+ "message": "உங்கள் விதை வார்த்தைகள் ஒரு பொது இடத்தில் மீட்க வேண்டாம்! உங்கள் எல்லா கணக்குகளையும் திருட இந்த வார்த்தைகள் பயன்படுத்தப்படலாம்."
+ },
+ "revert": {
+ "message": "மாற்றியமை"
+ },
+ "rinkeby": {
+ "message": "ரிங்கெப்ய டெஸ்ட் நெட்வொர்க்"
+ },
+ "ropsten": {
+ "message": "ரொப்ஸ்டென் டெஸ்ட் நெட்வொர்க்"
+ },
+ "currentRpc": {
+ "message": "தற்போதைய RPC"
+ },
+ "connectingToMainnet": {
+ "message": "முக்கிய எதெரியும் நெட்வொர்க் இணைக்கும்"
+ },
+ "connectingToRopsten": {
+ "message": "ரொப்ஸ்டென் டெஸ்ட் நெட்வொர்க்குடன் இணைக்கிறது"
+ },
+ "connectingToKovan": {
+ "message": "கோவன் டெஸ்ட் நெட்வொர்க்குடன் இணைத்தல்"
+ },
+ "connectingToRinkeby": {
+ "message": "ரிங்கெப்ய டெஸ்ட் நெட்வொர்க்குடன் இணைக்கிறது"
+ },
+ "connectingToUnknown": {
+ "message": "தெரியாத நெட்வொர்க்குடன் இணைக்கிறது"
+ },
+ "sampleAccountName": {
+ "message": "உதாரணமாக எனது புதிய கணக்கு",
+ "description": "தங்கள் கணக்கில் மனிதர் படிக்கக்கூடிய பெயரைச் சேர்க்கும் கருத்தை பயனர் புரிந்து கொள்ள உதவுங்கள்"
+ },
+ "save": {
+ "message": "சேமி"
+ },
+ "reprice_title": {
+ "message": "ரெப்ரிஸ் பரிவர்த்தனை"
+ },
+ "reprice_subtitle": {
+ "message": "உங்கள் பரிவர்த்தனைகளை மேலெழுதும் முயற்சியை அதிகரிக்க உங்கள் எரிவாயு விலையை அதிகரிக்கவும்"
+ },
+ "saveAsFile": {
+ "message": "கோப்பாக சேமிக்கவும்",
+ "description": "கணக்கு ஏற்றுமதி செயல்முறை"
+ },
+ "saveSeedAsFile": {
+ "message": "கோப்பு என விதை வார்த்தைகள் சேமிக்கவும்"
+ },
+ "search": {
+ "message": "தேடல்"
+ },
+ "secretPhrase": {
+ "message": "உங்கள் பெட்டகத்தை மீட்டெடுப்பதற்காக இங்கே உங்கள் ரகசிய பன்னிரண்டு வார்த்தை சொற்றொடரை உள்ளிடவும்."
+ },
+ "newPassword8Chars": {
+ "message": "புதிய கடவுச்சொல் (குறைந்தபட்சம் 8 எழுத்துகள்)"
+ },
+ "seedPhraseReq": {
+ "message": "விதை வாக்கியங்கள் 12 வார்த்தைகள் நீண்டவை"
+ },
+ "select": {
+ "message": "தேர்வு"
+ },
+ "selectCurrency": {
+ "message": "நாணயத்தைத் தேர்ந்தெடு"
+ },
+ "selectService": {
+ "message": "சேவை தேர்ந்தெடுக்கவும்"
+ },
+ "selectType": {
+ "message": "வகை தேர்ந்தெடு"
+ },
+ "send": {
+ "message": "அனுப்பு"
+ },
+ "sendETH": {
+ "message": "ETH ஐ அனுப்பு"
+ },
+ "sendTokens": {
+ "message": "டோக்கன்களை அனுப்பவும்"
+ },
+ "onlySendToEtherAddress": {
+ "message": "ETH ஐ ஒரு எதரியும் முகவரிக்கு மட்டும் அனுப்பவும்."
+ },
+ "searchTokens": {
+ "message": "தேடல் டோக்கன்ஸ்"
+ },
+ "sendTokensAnywhere": {
+ "message": "யாருடனும் டோக்கன்களை அனுப்பவும் எதெரியும் கணக்கு"
+ },
+ "settings": {
+ "message": "அமைப்புகள்"
+ },
+ "info": {
+ "message": "தகவல்"
+ },
+ "shapeshiftBuy": {
+ "message": "Shapeshift உடன் வாங்கவும்"
+ },
+ "showPrivateKeys": {
+ "message": "தனிப்பட்ட விசைகளைக் காண்பி"
+ },
+ "showQRCode": {
+ "message": "QR குறியீட்டைக் காட்டு"
+ },
+ "sign": {
+ "message": "உள்நுழை"
+ },
+ "signed": {
+ "message": "கையொப்பமிடப்பட்ட"
+ },
+ "signMessage": {
+ "message": "செய்தியை பதிவு செய்க"
+ },
+ "signNotice": {
+ "message": "இந்த செய்தியில் கையொப்பமிடலாம் \nஆபத்தான பக்க விளைவுகள் இருக்கலாம். \n உங்கள் மொத்த கணக்கில் முழுமையாக நம்பக்கூடிய தளங்களில் செய்திகளை மட்டுமே கையொப்பமிடுங்கள். \n இந்த ஆபத்தான முறை எதிர்கால பதிப்பில் அகற்றப்படும்."
+ },
+ "sigRequest": {
+ "message": "கையொப்பம் கோரிக்கை"
+ },
+ "sigRequested": {
+ "message": "கையொப்பம் கோரப்பட்டது"
+ },
+ "spaceBetween": {
+ "message": "வார்த்தைகள் இடையே இடைவெளி மட்டுமே இருக்க முடியும்"
+ },
+ "status": {
+ "message": "நிலைமை"
+ },
+ "stateLogs": {
+ "message": "மாநில பதிவுகள்"
+ },
+ "stateLogsDescription": {
+ "message": "மாநில பதிவுகள் உங்கள் பொது கணக்கு முகவரிகள் மற்றும் பரிமாற்றங்களை அனுப்பியுள்ளன."
+ },
+ "stateLogError": {
+ "message": "மாநில பதிவுகளை மீட்டெடுப்பதில் பிழை."
+ },
+ "submit": {
+ "message": "சமர்ப்பி"
+ },
+ "submitted": {
+ "message": "சமர்ப்பிக்கப்பட்டது"
+ },
+ "supportCenter": {
+ "message": "எங்கள் ஆதரவு மையத்தைப் பார்வையிடவும்"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "குறியீடு 0 மற்றும் 10 எழுத்துகளுக்கு இடையில் இருக்க வேண்டும்."
+ },
+ "takesTooLong": {
+ "message": "நீண்ட நேரம் எடுத்துக்கொள்கிறது?"
+ },
+ "terms": {
+ "message": "பயன்பாட்டு விதிமுறைகளை"
+ },
+ "testFaucet": {
+ "message": "சோதனை குழாய்"
+ },
+ "to": {
+ "message": "பெறுநர்: "
+ },
+ "toETHviaShapeShift": {
+ "message": "$ 1 முதல் ETH வரை வடிவம்",
+ "description": "செய்தி தொடக்கத்தில் வைப்பு வகைகளில் நிரப்பப்படும்"
+ },
+ "tokenAddress": {
+ "message": "டோக்கன் முகவரி"
+ },
+ "tokenAlreadyAdded": {
+ "message": "டோக்கன் ஏற்கனவே சேர்க்கப்பட்டது."
+ },
+ "tokenBalance": {
+ "message": "உங்கள் டோக்கன் இருப்பு:"
+ },
+ "tokenSelection": {
+ "message": "டோக்கன்களைத் தேடு அல்லது பிரபல டோக்கன்களின் பட்டியலிலிருந்து தேர்ந்தெடுக்கவும்."
+ },
+ "tokenSymbol": {
+ "message": "டோக்கன் சின்னம்"
+ },
+ "tokenWarning1": {
+ "message": "உங்கள் மேடமஸ்க் கணக்குடன் நீங்கள் வாங்கிய டோக்கன்களை கண்காணியுங்கள். வேறு கணக்கைப் பயன்படுத்தி டோக்கன்களை வாங்கிவிட்டால், அந்த டோக்கன்கள் இங்கே தோன்றாது."
+ },
+ "total": {
+ "message": "மொத்த"
+ },
+ "transactions": {
+ "message": "பரிவர்த்தனைகள்"
+ },
+ "transactionError": {
+ "message": "பரிவர்த்தனை பிழை. விதிமுறை ஒப்பந்தத்தில் விதிவிலக்கு."
+ },
+ "transactionMemo": {
+ "message": "பரிவர்த்தனை குறிப்பு (விருப்பம்)"
+ },
+ "transactionNumber": {
+ "message": "பரிவர்த்தனை எண்"
+ },
+ "transfers": {
+ "message": "இடமாற்றங்கள்"
+ },
+ "troubleTokenBalances": {
+ "message": "உங்கள் டோக்கன் நிலுவைகளை ஏற்றுவதில் சிக்கல் ஏற்பட்டது. நீங்கள் அவர்களை பார்க்க முடியும்.",
+ "description": "டோக்கன் நிலுவைகளை காண ஒரு இணைப்பு (இங்கே) தொடர்ந்து"
+ },
+ "twelveWords": {
+ "message": "இந்த 12 வார்த்தைகள் உங்கள் மெட்டாமாஸ்க் கணக்கை மீட்க ஒரே வழி. \n அவற்றை எங்காவது பாதுகாப்பாகவும் ரகசியமாகவும் சேமிக்கவும்."
+ },
+ "typePassword": {
+ "message": "உங்கள் கடவுச்சொல்லை தட்டச்சு செய்யவும்"
+ },
+ "uiWelcome": {
+ "message": "புதிய UI (பீட்டா) க்கு வரவேற்கிறோம்"
+ },
+ "uiWelcomeMessage": {
+ "message": "இப்போது நீங்கள் புதிய மெட்டாமாஸ்க்கு UI ஐ பயன்படுத்துகிறீர்கள். சுற்றி பாருங்கள், டோக்கன்களை அனுப்பும் புதிய அம்சங்களை முயற்சிக்கவும், உங்களிடம் ஏதேனும் சிக்கல் இருந்தால் எங்களுக்குத் தெரியப்படுத்தவும்."
+ },
+ "unapproved": {
+ "message": "அங்கீகரிக்கப்படாத"
+ },
+ "unavailable": {
+ "message": "கிடைக்கவில்லை"
+ },
+ "unknown": {
+ "message": "தெரியாத"
+ },
+ "unknownNetwork": {
+ "message": "அறியப்படாத தனியார் நெட்வொர்க்"
+ },
+ "unknownNetworkId": {
+ "message": "தெரியாத நெட்வொர்க் ஐடி"
+ },
+ "uriErrorMsg": {
+ "message": "URI கள் சரியான HTTP / HTTPS முன்னொட்டு தேவை."
+ },
+ "usaOnly": {
+ "message": "அமெரிக்கா மட்டும்",
+ "description": "இந்த பரிமாற்றத்தைப் பயன்படுத்தி அமெரிக்காவில் உள்ளவர்களுக்கு மட்டுமே இது வரையறுக்கப்படுகிறது"
+ },
+ "usedByClients": {
+ "message": "பல்வேறு வாடிக்கையாளர்கள் பல்வேறு பயன்படுத்திய"
+ },
+ "useOldUI": {
+ "message": "உஸ் ஓல்ட் உய் "
+ },
+ "validFileImport": {
+ "message": "இறக்குமதி செய்ய சரியான கோப்பு தேர்ந்தெடுக்க வேண்டும்."
+ },
+ "vaultCreated": {
+ "message": "வால்ட் உருவாக்கப்பட்டது"
+ },
+ "viewAccount": {
+ "message": "கணக்கைக் காட்டு"
+ },
+ "visitWebSite": {
+ "message": "எங்கள் வலைத்தளத்தைப் பார்வையிடவும்"
+ },
+ "warning": {
+ "message": "எச்சரிக்கை"
+ },
+ "welcomeBeta": {
+ "message": "மெட்டாமாஸ்க் பீட்டாவுக்கு வருக"
+ },
+ "whatsThis": {
+ "message": "இது என்ன?"
+ },
+ "yourSigRequested": {
+ "message": "உங்கள் கையொப்பம் கோரப்படுகிறது"
+ },
+ "youSign": {
+ "message": "நீங்கள் கையெழுத்திடுகிறீர்கள்"
+ }
+}
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
new file mode 100644
index 000000000..c2c09bc91
--- /dev/null
+++ b/app/_locales/tr/messages.json
@@ -0,0 +1,912 @@
+{
+ "accept": {
+ "message": "Kabul et"
+ },
+ "account": {
+ "message": "Hesap"
+ },
+ "accountDetails": {
+ "message": "Hesap Detayları"
+ },
+ "accountName": {
+ "message": "Hesap İsmi"
+ },
+ "address": {
+ "message": "Adres"
+ },
+ "addCustomToken": {
+ "message": "Özel jeton ekle"
+ },
+ "addToken": {
+ "message": "Jeton ekle"
+ },
+ "addTokens": {
+ "message": "Jetonlar ekle"
+ },
+ "amount": {
+ "message": "Tutar"
+ },
+ "amountPlusGas": {
+ "message": "Tutar + Gas"
+ },
+ "appDescription": {
+ "message": "Ethereum Tarayıcı Uzantısı",
+ "description": "Uygulama açıklaması"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "Uygulama ismi"
+ },
+ "approved": {
+ "message": "Onaylandı"
+ },
+ "attemptingConnect": {
+ "message": "Blockchain'e bağlanmayı deniyor"
+ },
+ "attributions": {
+ "message": "Atıflar"
+ },
+ "available": {
+ "message": "Müsait"
+ },
+ "back": {
+ "message": "Geri"
+ },
+ "balance": {
+ "message": "Bakiye:"
+ },
+ "balances": {
+ "message": "Jeton bakiyesi"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Toplam gas için yetersiz bakiye"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "$1'e eşit veya daha büyük olmalı ve $2'den küçük veya eşit olmalı",
+ "description": "Onaltılık sayının ondalık sayı olarak girişi için yardımcı"
+ },
+ "blockiesIdenticon": {
+ "message": "Blockies Identicon kullan"
+ },
+ "borrowDharma": {
+ "message": "Dharma (Beta) ile ödünç al"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask California'da tasarlandı ve yaratıldı"
+ },
+ "buy": {
+ "message": "Satın al"
+ },
+ "buyCoinbase": {
+ "message": "Coinbase'de satın al"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase bitcoin, ethereum, and litecoin alıp satmanın dünyadaki en popüler yolu"
+ },
+ "ok": {
+ "message": "Tamam"
+ },
+ "cancel": {
+ "message": "Vazgeç"
+ },
+ "classicInterface": {
+ "message": "Klasik arayüzü kullan"
+ },
+ "clickCopy": {
+ "message": "Kopyalamak için tıkla"
+ },
+ "confirm": {
+ "message": "Onayla"
+ },
+ "confirmed": {
+ "message": "Onaylandı"
+ },
+ "confirmContract": {
+ "message": "Sözleşmeyi onayla"
+ },
+ "confirmPassword": {
+ "message": "Şifreyi onayla"
+ },
+ "confirmTransaction": {
+ "message": "İşlemi onayla"
+ },
+ "continue": {
+ "message": "Devam et"
+ },
+ "continueToCoinbase": {
+ "message": "Coinbase'e devam et"
+ },
+ "contractDeployment": {
+ "message": "Sözleşme kurulumu"
+ },
+ "conversionProgress": {
+ "message": "Çevirim devam ediyor"
+ },
+ "copiedButton": {
+ "message": "Kopyalandı"
+ },
+ "copiedClipboard": {
+ "message": "Panoya kopyalandı"
+ },
+ "copiedExclamation": {
+ "message": "Kopyalandı!"
+ },
+ "copiedSafe": {
+ "message": "Güvenli bir yere kopyaladım"
+ },
+ "copy": {
+ "message": "Kopyala"
+ },
+ "copyToClipboard": {
+ "message": "Panoya kopyala"
+ },
+ "copyButton": {
+ "message": " Kopyala "
+ },
+ "copyPrivateKey": {
+ "message": "Bu sizin özel anahtarınız (kopyalamak için tıklayın)"
+ },
+ "create": {
+ "message": "Yarat"
+ },
+ "createAccount": {
+ "message": "Hesap Oluştur"
+ },
+ "createDen": {
+ "message": "Yarat"
+ },
+ "crypto": {
+ "message": "Kripto",
+ "description": "Kambiyo tipi (kripto para)"
+ },
+ "currentConversion": {
+ "message": "Geçerli çevirme"
+ },
+ "currentNetwork": {
+ "message": "Geçerli Ağ"
+ },
+ "customGas": {
+ "message": "Gas'i özelleştir"
+ },
+ "customToken": {
+ "message": "Özel Jeton"
+ },
+ "customize": {
+ "message": "Özelleştir"
+ },
+ "customRPC": {
+ "message": "Özel RPC"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Ondalıklar en azından 0 olmalı ve 36'dan büyük olmamalı."
+ },
+ "decimal": {
+ "message": "Ondalık hassasiyeti"
+ },
+ "defaultNetwork": {
+ "message": "Ether işlemleri için varsayılan ağ Main Net."
+ },
+ "denExplainer": {
+ "message": "DEN'iniz MetaMask içersinde parola-şifrelenmiş deponuzdur."
+ },
+ "deposit": {
+ "message": "Yatır"
+ },
+ "depositBTC": {
+ "message": "BTC'inizi aşağıdaki adrese yatırın:"
+ },
+ "depositCoin": {
+ "message": "$1'nızı aşağıdaki adrese yatırın",
+ "description": "Kullanıcıya hangi jetonu seçtiyse onu yatırmasını shapeshift ile söyler."
+ },
+ "depositEth": {
+ "message": "Eth yatır"
+ },
+ "depositEther": {
+ "message": "Ether yatır"
+ },
+ "depositFiat": {
+ "message": "Para yatır"
+ },
+ "depositFromAccount": {
+ "message": "Başka bir hesaptan yatır"
+ },
+ "depositShapeShift": {
+ "message": "ShapeShift ile yatır"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Eğer başka kripto paralara sahipseniz, MetaMask cüzdanınıza direk olarak Ether yatırabilirsiniz. Hesaba gerek yoktur."
+ },
+ "details": {
+ "message": "Ayrıntılar"
+ },
+ "directDeposit": {
+ "message": "Direk Yatırma"
+ },
+ "directDepositEther": {
+ "message": "Direk Ether Yatırma"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Eğer çoktan Etheriniz varsa, yeni hesabınıza Ether aktarmanın en kolay yolu direk yatırmadır."
+ },
+ "done": {
+ "message": "Bitti"
+ },
+ "downloadStateLogs": {
+ "message": "Durum kayıtlarını indir"
+ },
+ "dropped": {
+ "message": "Bırakıldı"
+ },
+ "edit": {
+ "message": "Düzenle"
+ },
+ "editAccountName": {
+ "message": "Hesap ismini düzenle"
+ },
+ "emailUs": {
+ "message": "Bize e-posta atın!"
+ },
+ "encryptNewDen": {
+ "message": "Yeni DEN'inizi şifreleyin"
+ },
+ "enterPassword": {
+ "message": "Parolanızı girin"
+ },
+ "enterPasswordConfirm": {
+ "message": "Onaylamak için parolanızı girin"
+ },
+ "passwordNotLongEnough": {
+ "message": "Parola yeterince uzun değil"
+ },
+ "passwordsDontMatch": {
+ "message": "Parolalar eşleşmiyor"
+ },
+ "etherscanView": {
+ "message": "Hesabı Etherscan üzerinde izle"
+ },
+ "exchangeRate": {
+ "message": "Döviz kuru"
+ },
+ "exportPrivateKey": {
+ "message": "Özel anahtarı ver"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Özel anahtarınızı vermek sizin sorumluluğunuzdadır."
+ },
+ "failed": {
+ "message": "Başarısız oldu"
+ },
+ "fiat": {
+ "message": "Para",
+ "description": "Döviz türü"
+ },
+ "fileImportFail": {
+ "message": "Dosya alma çalışmıyor mu? Buraya tıklayın!",
+ "description": "Kullanıcıların hesaplarını JSON dosyasından almalarına yardım eder"
+ },
+ "followTwitter": {
+ "message": "Bizi twitter'da takip edin"
+ },
+ "from": {
+ "message": "Kimden"
+ },
+ "fromToSame": {
+ "message": "Kimden ve kime adresi aynı olamaz"
+ },
+ "fromShapeShift": {
+ "message": "ShapeShift'den"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Gas maliyetinin kısa indikatörü"
+ },
+ "gasFee": {
+ "message": "Gas Ücreti"
+ },
+ "gasLimit": {
+ "message": "Gas Limiti"
+ },
+ "gasLimitCalculation": {
+ "message": "Önerilen gas limitini ağ başarı oranını baz alarak hesaplıyoruz."
+ },
+ "gasLimitRequired": {
+ "message": "Gas limiti gereklidir"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas limiti en az 21000 olmalıdır"
+ },
+ "generatingSeed": {
+ "message": "Kaynak Oluşturuyor..."
+ },
+ "gasPrice": {
+ "message": "Gas Fiyatı (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Önerilen gas fiyatını ağ başarı oranını baz alarak hesaplıyoruz."
+ },
+ "gasPriceRequired": {
+ "message": "Gas Fiyatı Gereklidir"
+ },
+ "getEther": {
+ "message": "Ether Al"
+ },
+ "getEtherFromFaucet": {
+ "message": "Musluktan $1 karşılığı Ether alın",
+ "description": "Ether musluğunun ağ ismini gösterir"
+ },
+ "greaterThanMin": {
+ "message": "must be greater than or equal to $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "here": {
+ "message": "burada",
+ "description": "daha fazla bilgi için -buraya tıklayın- (troubleTokenBalances ile gidiyor)"
+ },
+ "hereList": {
+ "message": "İşte bir liste!!!!"
+ },
+ "hide": {
+ "message": "Gizle"
+ },
+ "hideToken": {
+ "message": "Jetonu gizle"
+ },
+ "hideTokenPrompt": {
+ "message": "Jetonu gizle?"
+ },
+ "howToDeposit": {
+ "message": "Ether'i nasıl yatırmak istersiniz?"
+ },
+ "holdEther": {
+ "message": "Ether ve jeton tutmanızı sağlar ve merkezi olmayan uygulamalar ve sizin aranızda köprü vazifesi görür."
+ },
+ "import": {
+ "message": "Al",
+ "description": "Seçilen dosyadan hesap alma düğmesi. "
+ },
+ "importAccount": {
+ "message": "Hesap Al"
+ },
+ "importAccountMsg": {
+ "message":" Alınan hesaplar orjinal kaynakifadenizle yarattığınız MetaMask hesabınızla ilişkilendirilmez. Alınan hesaplar ile ilgili daha fazla bilgi edinin "
+ },
+ "importAnAccount": {
+ "message": "Hesap al"
+ },
+ "importDen": {
+ "message": "Varolan DEN al"
+ },
+ "imported": {
+ "message": "Alındı",
+ "description": "Hesabın keyringe başarı ile alındığını gösteren durum"
+ },
+ "infoHelp": {
+ "message": "Bilgi ve yardım"
+ },
+ "insufficientFunds": {
+ "message": "Yetersiz kaynak."
+ },
+ "insufficientTokens": {
+ "message": "Yetersiz Jeton."
+ },
+ "invalidAddress": {
+ "message": "Geçersiz adres"
+ },
+ "invalidAddressRecipient": {
+ "message": "Alıcı adresi geçersiz"
+ },
+ "invalidGasParams": {
+ "message": "Geçersiz gas parametreleri"
+ },
+ "invalidInput": {
+ "message": "Geçersiz giriş."
+ },
+ "invalidRequest": {
+ "message": "Geçersiz istek"
+ },
+ "invalidRPC": {
+ "message": "Geçersiz RPC URI"
+ },
+ "jsonFail": {
+ "message": "Birşeyler yanlış gitti. JSON dosyanızın düzgün derlendiğinden emin olun."
+ },
+ "jsonFile": {
+ "message": "JSON Dosyası",
+ "description": "Hesap alımı için düzenle"
+ },
+ "keepTrackTokens": {
+ "message": "MetaMask hesabınızla satın aldığınız jetonların kaydını tutun."
+ },
+ "kovan": {
+ "message": "Kovan Test Ağı"
+ },
+ "knowledgeDataBase": {
+ "message": "Bilgi veritabanımızı ziyaret edin"
+ },
+ "max": {
+ "message": "Maksimum"
+ },
+ "learnMore": {
+ "message": "Daha fazla bilgi."
+ },
+ "lessThanMax": {
+ "message": "$1'den az veya eşit olmalıdır.",
+ "description": "Onaltılık sayıyı ondalık olarak girmek için yardımcı"
+ },
+ "likeToAddTokens": {
+ "message": "Bu jetonlara adres eklemek ister misiniz?"
+ },
+ "links": {
+ "message": "Bağlantılar"
+ },
+ "limit": {
+ "message": "Limit"
+ },
+ "loading": {
+ "message": "Yükleniyor..."
+ },
+ "loadingTokens": {
+ "message": "Jetonlar yükleniyor..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Giriş yap"
+ },
+ "logout": {
+ "message": "Çıkış"
+ },
+ "loose": {
+ "message": "Gevşek"
+ },
+ "loweCaseWords": {
+ "message": "kaynak kelimeleri sadece küçük harflerden oluşabilir."
+ },
+ "mainnet": {
+ "message": "Main Ethereum Ağı"
+ },
+ "message": {
+ "message": "Mesaj"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask Ethereum için güvenli bir kimlik kasasıdır."
+ },
+ "min": {
+ "message": "Minimum"
+ },
+ "myAccounts": {
+ "message": "Hesaplarım"
+ },
+ "mustSelectOne": {
+ "message": "En az bir jeton seçilmeli"
+ },
+ "needEtherInWallet": {
+ "message": "MetaMask kullanarak merkezi olamayan uygulamalarla etkileşmek için cüzdanınızda Ether bulunmalıdır."
+ },
+ "needImportFile": {
+ "message": "Almak için bir dosya seçmelisiniz.",
+ "description": "Kullanıcı bir hesap alır ve devam etmek içinbir dosya seçmelidir."
+ },
+ "needImportPassword": {
+ "message": "Seçilen dosya için bir parola girmelisiniz.",
+ "description": "Hesap almak için parola ve dosya gerekiyor."
+ },
+ "negativeETH": {
+ "message": "Negatif ETH miktarları gönderilemez."
+ },
+ "networks": {
+ "message": "Ağlar"
+ },
+ "newAccount": {
+ "message": "Yeni Hesap"
+ },
+ "newAccountNumberName": {
+ "message": "Hesap $1",
+ "description": "Hesap yaratma ekranındaki bir sonraki hesabın varsayılan ismi"
+ },
+ "newContract": {
+ "message": "Yeni Sözleşme"
+ },
+ "newPassword": {
+ "message": "Yeni Parola (min 8 karakter)"
+ },
+ "newRecipient": {
+ "message": "Yeni alıcı"
+ },
+ "newRPC": {
+ "message": "Yeni RPC URL"
+ },
+ "next": {
+ "message": "Sonraki"
+ },
+ "noAddressForName": {
+ "message": "Bu isim için bir adres tanımlanmamış."
+ },
+ "noDeposits": {
+ "message": "Yatırma alınmadı"
+ },
+ "noTransactionHistory": {
+ "message": "İşlem geçmişi yok."
+ },
+ "noTransactions": {
+ "message": "İşlem yok"
+ },
+ "notStarted": {
+ "message": "Başlamadı"
+ },
+ "oldUI": {
+ "message": "Eski UI"
+ },
+ "oldUIMessage": {
+ "message": "Eski UI'a döndünüz. Yeni UI'a üst sağ sekme menüsündeki seçenek ile dönebilirsiniz."
+ },
+ "or": {
+ "message": "veya",
+ "description": "Yeni bir hesap yaratmak veya almak arasındaki seçim"
+ },
+ "passwordCorrect": {
+ "message": "Lütfen parolanın doğru olduğuna emin olun."
+ },
+ "passwordMismatch": {
+ "message": "parolalar eşleşmiyor",
+ "description": "parola yaratma işleminde, iki yeni parola alanı eşleşmiyor."
+ },
+ "passwordShort": {
+ "message": "parola yeterince uzun değil",
+ "description": "parola yaratma işleminde, parola güvenli olacak kadar uzun değil."
+ },
+ "pastePrivateKey": {
+ "message": "Özel anahtar dizinizi buraya yapıştırın:",
+ "description": "Özel anahtardan hesap almak için"
+ },
+ "pasteSeed": {
+ "message": "Kaynak ifadenizi buraya yapıştırın!"
+ },
+ "personalAddressDetected": {
+ "message": "Kişisel adres tespit edilidi. Jeton sözleşme adresini girin."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Lütfen işleminizi gözden geçirin."
+ },
+ "popularTokens": {
+ "message": "Popüler Jetonlar"
+ },
+ "privacyMsg": {
+ "message": "Gizlilik Şartları"
+ },
+ "privateKey": {
+ "message": "Özel Anahtar",
+ "description": "Hesap alırken bu tip bir dosya seçin"
+ },
+ "privateKeyWarning": {
+ "message": "Uyarı: Bu anahtarı kimse ile paylaşmayın. Özel anahtarlarınıza sahip herkes hesaplarınızıdaki tüm varlığınızı çalabilir."
+ },
+ "privateNetwork": {
+ "message": "Özel Ağ"
+ },
+ "qrCode": {
+ "message": "QR Kodunu göster"
+ },
+ "readdToken": {
+ "message": "Gelecekte Bu jetonu hesap seçenekleri menüsünde “Jeton ekle”'ye giderek geri ekleyebilirsiniz."
+ },
+ "readMore": {
+ "message": "Burada daha fazla okuyun."
+ },
+ "readMore2": {
+ "message": "Daha fazla okuyun."
+ },
+ "receive": {
+ "message": "Al"
+ },
+ "recipientAddress": {
+ "message": "Alıcı adresi"
+ },
+ "refundAddress": {
+ "message": "İade adresiniz"
+ },
+ "rejected": {
+ "message": "Rededildi"
+ },
+ "resetAccount": {
+ "message": "Hesabı sıfıla"
+ },
+ "restoreFromSeed": {
+ "message": "Kaynak ifadeden geri getir. Restore from seed phrase"
+ },
+ "restoreVault": {
+ "message": "Kasayı geri getir"
+ },
+ "required": {
+ "message": "Gerekli"
+ },
+ "retryWithMoreGas": {
+ "message": "Daha yüksek bir gas fiyatı ile tekrar dene"
+ },
+ "walletSeed": {
+ "message": "Cüzdan Kaynağı"
+ },
+ "revealSeedWords": {
+ "message": "Kaynak kelimelerini göster"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Açık bir yerde kaynak kelimeliriniz geri getirmeyin! Bu kelimeler tüm hesaplarınızı çalmak için kullanılabilir."
+ },
+ "revert": {
+ "message": "Geri döndür"
+ },
+ "rinkeby": {
+ "message": "Rinkeby Test Ağı"
+ },
+ "ropsten": {
+ "message": "Ropsten Test Ağı"
+ },
+ "currentRpc": {
+ "message": "Geçerli RPC"
+ },
+ "connectingToMainnet": {
+ "message": "Main Ethereum Ağına bağlanıyor"
+ },
+ "connectingToRopsten": {
+ "message": "Ropsten Test Ağına bağlanıyor"
+ },
+ "connectingToKovan": {
+ "message": "Kovan Test Ağına bağlanıyor"
+ },
+ "connectingToRinkeby": {
+ "message": "Rinkeby Test Ağına bağlanıyor"
+ },
+ "connectingToUnknown": {
+ "message": "Bilinmeyen Ağa bağlanıyor"
+ },
+ "sampleAccountName": {
+ "message": "E.g. Yeni hesabım",
+ "description": "Kullanıcının hesabına okunabilir isim ekleme konseptini anlamasına yardımcı olmak."
+ },
+ "save": {
+ "message": "Kaydet"
+ },
+ "reprice_title": {
+ "message": "İşlemi Yeniden Fiyatlandır"
+ },
+ "reprice_subtitle": {
+ "message": "İşlemizi hızlandırmayı denemek için gas fiyatınızı yükseltin."
+ },
+ "saveAsFile": {
+ "message": "Dosya olarak kaydet",
+ "description": "Hesap verme işlemi"
+ },
+ "saveSeedAsFile": {
+ "message": "Kaynak Kelimelerini Dosya olarak Kaydet"
+ },
+ "search": {
+ "message": "Ara"
+ },
+ "secretPhrase": {
+ "message": "Kasanızı geri getirmek için gizli 12 kelimelik ifadenizi giriniz."
+ },
+ "newPassword8Chars": {
+ "message": "Yeni Parola (minumum 8 karakter)"
+ },
+ "seedPhraseReq": {
+ "message": "Kaynak ifadeleri 12 kelimedir."
+ },
+ "select": {
+ "message": "Seç"
+ },
+ "selectCurrency": {
+ "message": "Döviz Seç"
+ },
+ "selectService": {
+ "message": "Servis Seç"
+ },
+ "selectType": {
+ "message": "Tip Seç"
+ },
+ "send": {
+ "message": "Gönder"
+ },
+ "sendETH": {
+ "message": "ETH Gönder"
+ },
+ "sendTokens": {
+ "message": "Jeton Gönder"
+ },
+ "onlySendToEtherAddress": {
+ "message": "Ethereum adresine sadece ETH gönder."
+ },
+ "searchTokens": {
+ "message": "Jeton ara"
+ },
+ "sendTokensAnywhere": {
+ "message": "Ethereum hesabı olan birine Jeton gönder"
+ },
+ "settings": {
+ "message": "Ayarlar"
+ },
+ "info": {
+ "message": "Bilgi"
+ },
+ "shapeshiftBuy": {
+ "message": "Shapeshift ile satın al"
+ },
+ "showPrivateKeys": {
+ "message": "Özel anahtarları göster"
+ },
+ "showQRCode": {
+ "message": "QR Kodu göster"
+ },
+ "sign": {
+ "message": "İmza"
+ },
+ "signed": {
+ "message": "İmzalandı"
+ },
+ "signMessage": {
+ "message": "Mesajı İmzala"
+ },
+ "signNotice": {
+ "message": "Bu mesajı imzalamanın tehlikeli \nyan etkileri olabilir. Tamamen güvendiğiniz sitelerden \ngelen mesajları hesabınızla imzalayınız.\n Bu tehlikeli metod gelecek versiyonlarda çıkarılacaktır. "
+ },
+ "sigRequest": {
+ "message": "İmza isteği"
+ },
+ "sigRequested": {
+ "message": "İmza isteniyor"
+ },
+ "spaceBetween": {
+ "message": "Kelimeler arası sadece bir boşluk olabilir."
+ },
+ "status": {
+ "message": "Durum"
+ },
+ "stateLogs": {
+ "message": "Durum Kayıtları"
+ },
+ "stateLogsDescription": {
+ "message": "Durum kayıtları açık hesap adresinizi ve gönderilen işlemleri içerir."
+ },
+ "stateLogError": {
+ "message": "Durum kayıtlarını alma hatası"
+ },
+ "submit": {
+ "message": "Gönder"
+ },
+ "submitted": {
+ "message": "Gönderildi"
+ },
+ "supportCenter": {
+ "message": "Destek merkezimizi ziyaret edin"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Sembol 0 ve 10 karakter aralığında olmalıdır."
+ },
+ "takesTooLong": {
+ "message": "Çok mu uzun sürüyor?"
+ },
+ "terms": {
+ "message": "Kullanım şartları"
+ },
+ "testFaucet": {
+ "message": "Test Musluğu"
+ },
+ "to": {
+ "message": "Kime: "
+ },
+ "toETHviaShapeShift": {
+ "message": "ShapeShift üstünden $1'dan ETH'e",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenAddress": {
+ "message": "Jeton Adresi"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Jeton çoktan eklenmiş."
+ },
+ "tokenBalance": {
+ "message": "Jeton bakiyeniz:"
+ },
+ "tokenSelection": {
+ "message": "Jeton arayın veya popüler jeton listemizden seçin."
+ },
+ "tokenSymbol": {
+ "message": "Jeton Sembolü"
+ },
+ "tokenWarning1": {
+ "message": "MetaMask hesabınızla aldığınız jetonların kaydını tutun. Başka bir hesapla jetonlar satın aldıysanız, o jetonlar burada gözükmeyecektir."
+ },
+ "total": {
+ "message": "Toplam"
+ },
+ "transactions": {
+ "message": "işlemler"
+ },
+ "transactionError": {
+ "message": "İşlem Hatası. Sözleşme kodundan kural dışı durum fırlatıldı."
+ },
+ "transactionMemo": {
+ "message": "İşlem notu (opsiyonel)"
+ },
+ "transactionNumber": {
+ "message": "İşlem numarası"
+ },
+ "transfers": {
+ "message": "Transferler"
+ },
+ "troubleTokenBalances": {
+ "message": "Jeton bakiyelerinizi yüklerken sorun yaşadık. Buradan izleyebilirsiniz ",
+ "description": "Jeton bakiyelerini görmek için bir link (burası) ile takip ediliyor"
+ },
+ "twelveWords": {
+ "message": "MetaMask hesaplarınızı geri getirmenin tek yolu bu 12 kelimedir.\nBu kelimeleri güvenli ve gizli bir yerde saklayın."
+ },
+ "typePassword": {
+ "message": "Parolanızı girin"
+ },
+ "uiWelcome": {
+ "message": "Yeni UI (Beta)'ya hoşgeldiniz"
+ },
+ "uiWelcomeMessage": {
+ "message": "Şu anda yeni Metamask UI kullanmaktasınız. Gözatın, jeton gönderme gibi yeni özellikleri deneyin ve herhangi bir sorunlar karşılaşırsanız bize haber verin"
+ },
+ "unapproved": {
+ "message": "Onaylanmadı"
+ },
+ "unavailable": {
+ "message": "Mevcut değil"
+ },
+ "unknown": {
+ "message": "Bilinmeyen"
+ },
+ "unknownNetwork": {
+ "message": "Bilinmeyen özel ağ"
+ },
+ "unknownNetworkId": {
+ "message": "Bilinmeyen ağ IDsi"
+ },
+ "uriErrorMsg": {
+ "message": "URIler için HTTP/HTTPS öneki gerekmektedir."
+ },
+ "usaOnly": {
+ "message": "Sadece ABD",
+ "description": "Bu dövizi sadece ABD ikamet edenler kullanabilir"
+ },
+ "usedByClients": {
+ "message": "Farklı istemciler tarafından kullanılmakta"
+ },
+ "useOldUI": {
+ "message": "Eski UI kullan"
+ },
+ "validFileImport": {
+ "message": "Almak için geçerli bir dosya seçmelisiniz"
+ },
+ "vaultCreated": {
+ "message": "Kasa Yaratıldı"
+ },
+ "viewAccount": {
+ "message": "Hesabı İncele"
+ },
+ "visitWebSite": {
+ "message": "Web sitemizi ziyaret edin"
+ },
+ "warning": {
+ "message": "Uyarı"
+ },
+ "welcomeBeta": {
+ "message": "MetaMask Beta'ya Hoşgeldiniz"
+ },
+ "whatsThis": {
+ "message": "Bu nedir?"
+ },
+ "yourSigRequested": {
+ "message": "İmzanız isteniyor"
+ },
+ "youSign": {
+ "message": "İmzalıyorsunuz"
+ }
+} \ No newline at end of file
diff --git a/app/images/copy-to-clipboard.svg b/app/images/copy-to-clipboard.svg
new file mode 100644
index 000000000..c67c2aa84
--- /dev/null
+++ b/app/images/copy-to-clipboard.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="18px" height="17px" viewBox="0 0 18 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: sketchtool 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
+ <title>374E58A5-C29E-4921-83E7-889FA06D6408</title>
+ <desc>Created with sketchtool.</desc>
+ <defs></defs>
+ <g id="Reveal-Seedphrase" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Seed-phrase-2" transform="translate(-39.000000, -379.000000)">
+ <g id="Group-2">
+ <g id="Group-8" transform="translate(16.000000, 248.000000)">
+ <g id="Group-6" transform="translate(23.336478, 120.000000)">
+ <g id="Group-5" transform="translate(0.408805, 11.000000)">
+ <g id="copy-to-clipboard">
+ <rect id="Rectangle-18" stroke="#3098DC" stroke-width="2" x="1" y="1" width="12.0220126" height="12"></rect>
+ <rect id="Rectangle-18-Copy-2" fill="#FFFFFF" x="2.1572327" y="2" width="14.0220126" height="14"></rect>
+ <rect id="Rectangle-18-Copy" stroke="#3098DC" stroke-width="2" x="4.23584906" y="4" width="12.0220126" height="12"></rect>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/download.svg b/app/images/download.svg
index 137a1190e..b55066414 100644
--- a/app/images/download.svg
+++ b/app/images/download.svg
@@ -1,15 +1,26 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="24.088px" height="24px" viewBox="138.01 0 24.088 24" enable-background="new 138.01 0 24.088 24" xml:space="preserve" fill="#F7861C">
-<g>
- <polygon fill="#F7861C" points="157.551,17.075 156.55,17.075 156.55,19.149 142.569,19.149 142.569,17.075 141.568,17.075
- 141.568,20.145 141.955,20.145 141.955,20.15 157.006,20.15 157.006,20.145 157.551,20.145 "/>
- <polygon fill="#F7861C" points="152.555,10.275 152.555,11.26 152.555,11.268 151.562,11.268 151.562,12.252 150.565,12.252
- 150.565,4.171 149.564,4.171 149.564,12.236 148.564,12.236 148.564,11.252 147.564,11.252 147.564,11.236 147.564,11.221
- 147.564,10.236 146.563,10.236 146.563,11.221 146.563,11.236 146.563,12.221 147.563,12.221 147.563,12.236 147.563,12.252
- 147.563,13.236 148.563,13.236 148.563,14.221 149.564,14.221 149.564,15.725 150.565,15.725 150.565,14.236 151.563,14.236
- 151.563,13.252 152.563,13.252 152.563,12.268 152.563,12.26 153.556,12.26 153.556,11.275 153.556,11.26 153.556,10.275 "/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="18px" viewBox="0 0 20 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: sketchtool 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
+ <title>50559280-0739-419A-8E87-3CDD16A6996A</title>
+ <desc>Created with sketchtool.</desc>
+ <defs></defs>
+ <g id="Reveal-Seedphrase" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Seed-phrase-2" transform="translate(-212.000000, -379.000000)" stroke="#259DE5" stroke-width="2">
+ <g id="Group-2">
+ <g id="Group-8" transform="translate(16.000000, 248.000000)">
+ <g id="Group-6" transform="translate(23.336478, 120.000000)">
+ <g id="Group-3" transform="translate(174.000000, 11.000000)">
+ <g id="Group-4">
+ <g id="download">
+ <polyline id="Path-5" points="0 11 0 17 17 17 17 11"></polyline>
+ <path d="M8.5,0 L8.5,11" id="Path-6"></path>
+ <polyline id="Path-7" points="3.1875 7 8.5 11 13.8125 7"></polyline>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/warning.svg b/app/images/warning.svg
new file mode 100644
index 000000000..9c8d697d7
--- /dev/null
+++ b/app/images/warning.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="33px" height="32px" viewBox="0 0 33 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
+ <title>Group 7</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="Reveal-Seedphrase" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Seed-phrase-2" transform="translate(-29.000000, -155.000000)">
+ <g id="Group-2" transform="translate(0.000000, 132.000000)">
+ <g id="Group" transform="translate(28.000000, 19.000000)">
+ <g id="Group-19-Copy-2" transform="translate(0.000000, 3.000000)">
+ <g id="Group-7">
+ <path d="M20.1321134,3.85444772 L32.5721829,26.6020033 C33.367162,28.0556794 32.8331826,29.8785746 31.3795065,30.6735537 C30.9381289,30.9149321 30.4431378,31.0414403 29.9400695,31.0414403 L5.05993054,31.0414403 C3.40307629,31.0414403 2.05993054,29.6982946 2.05993054,28.0414403 C2.05993054,27.538372 2.18643873,27.0433809 2.42781712,26.6020033 L14.8678866,3.85444772 C15.6628657,2.40077162 17.4857609,1.86679221 18.939437,2.66177133 C19.442875,2.93708896 19.8567958,3.35100977 20.1321134,3.85444772 Z" id="Triangle-2-Copy" stroke="#FF001F" stroke-width="2"></path>
+ <rect id="Rectangle-5" fill="#FF001F" x="16" y="9" width="3" height="13"></rect>
+ <rect id="Rectangle-5-Copy" fill="#FF001F" x="16" y="24" width="3" height="3"></rect>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/manifest.json b/app/manifest.json
index 2a18bdb2d..3e5eed205 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "__MSG_appName__",
- "version": "4.5.2",
+ "version": "4.6.0",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "__MSG_appDescription__",
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 3ad0a7863..69d549c85 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,3 +1,7 @@
+/**
+ * @file The entry point for the web extension singleton process.
+ */
+
const urlUtil = require('url')
const endOfStream = require('end-of-stream')
const pump = require('pump')
@@ -20,12 +24,17 @@ const reportFailedTxToSentry = require('./lib/reportFailedTxToSentry')
const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics')
const EdgeEncryptor = require('./edge-encryptor')
const getFirstPreferredLangCode = require('./lib/get-first-preferred-lang-code')
+const getObjStructure = require('./lib/getObjStructure')
+const {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+} = require('./lib/enums')
const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
-window.log = log
-log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn')
+log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn')
const platform = new ExtensionPlatform()
const notificationManager = new NotificationManager()
@@ -43,7 +52,7 @@ const isEdge = !isIE && !!window.StyleMedia
let popupIsOpen = false
let notificationIsOpen = false
-let openMetamaskTabsIDs = {}
+const openMetamaskTabsIDs = {}
// state persistence
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
@@ -56,6 +65,90 @@ initialize().catch(log.error)
// setup metamask mesh testing container
setupMetamaskMeshMetrics()
+/**
+ * An object representing a transaction, in whatever state it is in.
+ * @typedef TransactionMeta
+ *
+ * @property {number} id - An internally unique tx identifier.
+ * @property {number} time - Time the tx was first suggested, in unix epoch time (ms).
+ * @property {string} status - The current transaction status (unapproved, signed, submitted, dropped, failed, rejected), as defined in `tx-state-manager.js`.
+ * @property {string} metamaskNetworkId - The transaction's network ID, used for EIP-155 compliance.
+ * @property {boolean} loadingDefaults - TODO: Document
+ * @property {Object} txParams - The tx params as passed to the network provider.
+ * @property {Object[]} history - A history of mutations to this TransactionMeta object.
+ * @property {boolean} gasPriceSpecified - True if the suggesting dapp specified a gas price, prevents auto-estimation.
+ * @property {boolean} gasLimitSpecified - True if the suggesting dapp specified a gas limit, prevents auto-estimation.
+ * @property {string} estimatedGas - A hex string represented the estimated gas limit required to complete the transaction.
+ * @property {string} origin - A string representing the interface that suggested the transaction.
+ * @property {Object} nonceDetails - A metadata object containing information used to derive the suggested nonce, useful for debugging nonce issues.
+ * @property {string} rawTx - A hex string of the final signed transaction, ready to submit to the network.
+ * @property {string} hash - A hex string of the transaction hash, used to identify the transaction on the network.
+ * @property {number} submittedTime - The time the transaction was submitted to the network, in Unix epoch time (ms).
+ */
+
+/**
+ * The data emitted from the MetaMaskController.store EventEmitter, also used to initialize the MetaMaskController. Available in UI on React state as state.metamask.
+ * @typedef MetaMaskState
+ * @property {boolean} isInitialized - Whether the first vault has been created.
+ * @property {boolean} isUnlocked - Whether the vault is currently decrypted and accounts are available for selection.
+ * @property {boolean} isAccountMenuOpen - Represents whether the main account selection UI is currently displayed.
+ * @property {boolean} isMascara - True if the current context is the extensionless MetaMascara project.
+ * @property {boolean} isPopup - Returns true if the current view is an externally-triggered notification.
+ * @property {string} rpcTarget - DEPRECATED - The URL of the current RPC provider.
+ * @property {Object} identities - An object matching lower-case hex addresses to Identity objects with "address" and "name" (nickname) keys.
+ * @property {Object} unapprovedTxs - An object mapping transaction hashes to unapproved transactions.
+ * @property {boolean} noActiveNotices - False if there are notices the user should confirm before using the application.
+ * @property {Array} frequentRpcList - A list of frequently used RPCs, including custom user-provided ones.
+ * @property {Array} addressBook - A list of previously sent to addresses.
+ * @property {address} selectedTokenAddress - Used to indicate if a token is globally selected. Should be deprecated in favor of UI-centric token selection.
+ * @property {Object} tokenExchangeRates - Info about current token prices.
+ * @property {Array} tokens - Tokens held by the current user, including their balances.
+ * @property {Object} send - TODO: Document
+ * @property {Object} coinOptions - TODO: Document
+ * @property {boolean} useBlockie - Indicates preferred user identicon format. True for blockie, false for Jazzicon.
+ * @property {Object} featureFlags - An object for optional feature flags.
+ * @property {string} networkEndpointType - TODO: Document
+ * @property {boolean} isRevealingSeedWords - True if seed words are currently being recovered, and should be shown to user.
+ * @property {boolean} welcomeScreen - True if welcome screen should be shown.
+ * @property {string} currentLocale - A locale string matching the user's preferred display language.
+ * @property {Object} provider - The current selected network provider.
+ * @property {string} provider.rpcTarget - The address for the RPC API, if using an RPC API.
+ * @property {string} provider.type - An identifier for the type of network selected, allows MetaMask to use custom provider strategies for known networks.
+ * @property {string} network - A stringified number of the current network ID.
+ * @property {Object} accounts - An object mapping lower-case hex addresses to objects with "balance" and "address" keys, both storing hex string values.
+ * @property {hex} currentBlockGasLimit - The most recently seen block gas limit, in a lower case hex prefixed string.
+ * @property {TransactionMeta[]} selectedAddressTxList - An array of transactions associated with the currently selected account.
+ * @property {Object} unapprovedMsgs - An object of messages associated with the currently selected account, mapping a unique ID to the options.
+ * @property {number} unapprovedMsgCount - The number of messages in unapprovedMsgs.
+ * @property {Object} unapprovedPersonalMsgs - An object of messages associated with the currently selected account, mapping a unique ID to the options.
+ * @property {number} unapprovedPersonalMsgCount - The number of messages in unapprovedPersonalMsgs.
+ * @property {Object} unapprovedTypedMsgs - An object of messages associated with the currently selected account, mapping a unique ID to the options.
+ * @property {number} unapprovedTypedMsgCount - The number of messages in unapprovedTypedMsgs.
+ * @property {string[]} keyringTypes - An array of unique keyring identifying strings, representing available strategies for creating accounts.
+ * @property {Keyring[]} keyrings - An array of keyring descriptions, summarizing the accounts that are available for use, and what keyrings they belong to.
+ * @property {Object} computedBalances - Maps accounts to their balances, accounting for balance changes from pending transactions.
+ * @property {string} currentAccountTab - A view identifying string for displaying the current displayed view, allows user to have a preferred tab in the old UI (between tokens and history).
+ * @property {string} selectedAddress - A lower case hex string of the currently selected address.
+ * @property {string} currentCurrency - A string identifying the user's preferred display currency, for use in showing conversion rates.
+ * @property {number} conversionRate - A number representing the current exchange rate from the user's preferred currency to Ether.
+ * @property {number} conversionDate - A unix epoch date (ms) for the time the current conversion rate was last retrieved.
+ * @property {Object} infuraNetworkStatus - An object of infura network status checks.
+ * @property {Block[]} recentBlocks - An array of recent blocks, used to calculate an effective but cheap gas price.
+ * @property {Array} shapeShiftTxList - An array of objects describing shapeshift exchange attempts.
+ * @property {Array} lostAccounts - TODO: Remove this feature. A leftover from the version-3 migration where our seed-phrase library changed to fix a bug where some accounts were mis-generated, but we recovered the old accounts as "lost" instead of losing them.
+ * @property {boolean} forgottenPassword - Returns true if the user has initiated the password recovery screen, is recovering from seed phrase.
+ */
+
+/**
+ * @typedef VersionedData
+ * @property {MetaMaskState} data - The data emitted from MetaMask controller, or used to initialize it.
+ * @property {Number} version - The latest migration version that has been run.
+ */
+
+/**
+ * Initializes the MetaMask controller, and sets up all platform configuration.
+ * @returns {Promise} Setup complete.
+ */
async function initialize () {
const initState = await loadStateFromPersistence()
const initLangCode = await getFirstPreferredLangCode()
@@ -67,6 +160,11 @@ async function initialize () {
// State and Persistence
//
+/**
+ * Loads any stored data, prioritizing the latest storage strategy.
+ * Migrates that data schema in case it was last loaded on an older version.
+ * @returns {Promise<MetaMaskState>} Last data emitted from previous instance of MetaMask.
+ */
async function loadStateFromPersistence () {
// migrations
const migrator = new Migrator({ migrations })
@@ -77,6 +175,38 @@ async function loadStateFromPersistence () {
diskStore.getState() ||
migrator.generateInitialState(firstTimeState)
+ // check if somehow state is empty
+ // this should never happen but new error reporting suggests that it has
+ // for a small number of users
+ // https://github.com/metamask/metamask-extension/issues/3919
+ if (versionedData && !versionedData.data) {
+ // try to recover from diskStore incase only localStore is bad
+ const diskStoreState = diskStore.getState()
+ if (diskStoreState && diskStoreState.data) {
+ // we were able to recover (though it might be old)
+ versionedData = diskStoreState
+ const vaultStructure = getObjStructure(versionedData)
+ raven.captureMessage('MetaMask - Empty vault found - recovered from diskStore', {
+ // "extra" key is required by Sentry
+ extra: { vaultStructure },
+ })
+ } else {
+ // unable to recover, clear state
+ versionedData = migrator.generateInitialState(firstTimeState)
+ raven.captureMessage('MetaMask - Empty vault found - unable to recover')
+ }
+ }
+
+ // report migration errors to sentry
+ migrator.on('error', (err) => {
+ // get vault structure without secrets
+ const vaultStructure = getObjStructure(versionedData)
+ raven.captureException(err, {
+ // "extra" key is required by Sentry
+ extra: { vaultStructure },
+ })
+ })
+
// migrate data
versionedData = await migrator.migrateData(versionedData)
if (!versionedData) {
@@ -84,12 +214,29 @@ async function loadStateFromPersistence () {
}
// write to disk
- if (localStore.isSupported) localStore.set(versionedData)
+ if (localStore.isSupported) {
+ localStore.set(versionedData)
+ } else {
+ // throw in setTimeout so as to not block boot
+ setTimeout(() => {
+ throw new Error('MetaMask - Localstore not supported')
+ })
+ }
// return just the data
return versionedData.data
}
+/**
+ * Initializes the MetaMask Controller with any initial state and default language.
+ * Configures platform-specific error reporting strategy.
+ * Streams emitted state updates to platform-specific storage strategy.
+ * Creates platform listeners for new Dapps/Contexts, and sets up their data connections to the controller.
+ *
+ * @param {Object} initState - The initial state to start the controller with, matches the state that is emitted from the controller.
+ * @param {String} initLangCode - The region code for the language preferred by the current user.
+ * @returns {Promise} After setup is complete.
+ */
function setupController (initState, initLangCode) {
//
// MetaMask Controller
@@ -114,7 +261,11 @@ function setupController (initState, initLangCode) {
controller.txController.on(`tx:status-update`, (txId, status) => {
if (status !== 'failed') return
const txMeta = controller.txController.txStateManager.getTx(txId)
- reportFailedTxToSentry({ raven, txMeta })
+ try {
+ reportFailedTxToSentry({ raven, txMeta })
+ } catch (e) {
+ console.error(e)
+ }
})
// setup state persistence
@@ -122,18 +273,29 @@ function setupController (initState, initLangCode) {
asStream(controller.store),
debounce(1000),
storeTransform(versionifyData),
- storeTransform(syncDataWithExtension),
+ storeTransform(persistData),
(error) => {
- log.error('pump hit error', error)
+ log.error('MetaMask - Persistence pipeline failed', error)
}
)
+ /**
+ * Assigns the given state to the versioned object (with metadata), and returns that.
+ * @param {Object} state - The state object as emitted by the MetaMaskController.
+ * @returns {VersionedData} The state object wrapped in an object that includes a metadata key.
+ */
function versionifyData (state) {
versionedData.data = state
return versionedData
}
- function syncDataWithExtension(state) {
+ function persistData (state) {
+ if (!state) {
+ throw new Error('MetaMask - updated state is missing', state)
+ }
+ if (!state.data) {
+ throw new Error('MetaMask - updated state does not have data', state)
+ }
if (localStore.isSupported) {
localStore.set(state)
.catch((err) => {
@@ -146,30 +308,65 @@ function setupController (initState, initLangCode) {
//
// connect to other contexts
//
-
extension.runtime.onConnect.addListener(connectRemote)
+
+ const metamaskInternalProcessHash = {
+ [ENVIRONMENT_TYPE_POPUP]: true,
+ [ENVIRONMENT_TYPE_NOTIFICATION]: true,
+ [ENVIRONMENT_TYPE_FULLSCREEN]: true,
+ }
+
+ const isClientOpenStatus = () => {
+ return popupIsOpen || Boolean(Object.keys(openMetamaskTabsIDs).length) || notificationIsOpen
+ }
+
+ /**
+ * A runtime.Port object, as provided by the browser:
+ * @link https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/Port
+ * @typedef Port
+ * @type Object
+ */
+
+ /**
+ * Connects a Port to the MetaMask controller via a multiplexed duplex stream.
+ * This method identifies trusted (MetaMask) interfaces, and connects them differently from untrusted (web pages).
+ * @param {Port} remotePort - The port provided by a new context.
+ */
function connectRemote (remotePort) {
- const isMetaMaskInternalProcess = remotePort.name === 'popup' || remotePort.name === 'notification'
+ const processName = remotePort.name
+ const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]
const portStream = new PortStream(remotePort)
+
if (isMetaMaskInternalProcess) {
// communication with popup
- popupIsOpen = popupIsOpen || (remotePort.name === 'popup')
+ controller.isClientOpen = true
controller.setupTrustedCommunication(portStream, 'MetaMask')
- // record popup as closed
- if (remotePort.sender.url.match(/home.html$/)) {
- openMetamaskTabsIDs[remotePort.sender.tab.id] = true
- }
- if (remotePort.name === 'popup') {
+
+ if (processName === ENVIRONMENT_TYPE_POPUP) {
+ popupIsOpen = true
+
endOfStream(portStream, () => {
popupIsOpen = false
- if (remotePort.sender.url.match(/home.html$/)) {
- openMetamaskTabsIDs[remotePort.sender.tab.id] = false
- }
+ controller.isClientOpen = isClientOpenStatus()
})
}
- if (remotePort.name === 'notification') {
+
+ if (processName === ENVIRONMENT_TYPE_NOTIFICATION) {
+ notificationIsOpen = true
+
endOfStream(portStream, () => {
notificationIsOpen = false
+ controller.isClientOpen = isClientOpenStatus()
+ })
+ }
+
+ if (processName === ENVIRONMENT_TYPE_FULLSCREEN) {
+ const tabId = remotePort.sender.tab.id
+ openMetamaskTabsIDs[tabId] = true
+
+ endOfStream(portStream, () => {
+ delete openMetamaskTabsIDs[tabId]
+ controller.isClientOpen = isClientOpenStatus()
})
}
} else {
@@ -188,7 +385,10 @@ function setupController (initState, initLangCode) {
controller.messageManager.on('updateBadge', updateBadge)
controller.personalMessageManager.on('updateBadge', updateBadge)
- // plugin badge text
+ /**
+ * Updates the Web Extension's "badge" number, on the little fox in the toolbar.
+ * The number reflects the current number of pending transactions or message signatures needing user approval.
+ */
function updateBadge () {
var label = ''
var unapprovedTxCount = controller.txController.getUnapprovedTxCount()
@@ -210,12 +410,15 @@ function setupController (initState, initLangCode) {
// Etc...
//
-// popup trigger
+/**
+ * Opens the browser popup for user confirmation
+ */
function triggerUi () {
- extension.tabs.query({ active: true }, (tabs) => {
- const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id])
- if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) notificationManager.showPopup()
- notificationIsOpen = true
+ extension.tabs.query({ active: true }, tabs => {
+ const currentlyActiveMetamaskTab = Boolean(tabs.find(tab => openMetamaskTabsIDs[tab.id]))
+ if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) {
+ notificationManager.showPopup()
+ }
})
}
diff --git a/app/scripts/config.js b/app/scripts/config.js
deleted file mode 100644
index a8470ed82..000000000
--- a/app/scripts/config.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask'
-const ROPSTEN_RPC_URL = 'https://ropsten.infura.io/metamask'
-const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask'
-const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask'
-const LOCALHOST_RPC_URL = 'http://localhost:8545'
-
-const MAINET_RPC_URL_BETA = 'https://mainnet.infura.io/metamask2'
-const ROPSTEN_RPC_URL_BETA = 'https://ropsten.infura.io/metamask2'
-const KOVAN_RPC_URL_BETA = 'https://kovan.infura.io/metamask2'
-const RINKEBY_RPC_URL_BETA = 'https://rinkeby.infura.io/metamask2'
-
-const DEFAULT_RPC = 'rinkeby'
-const OLD_UI_NETWORK_TYPE = 'network'
-const BETA_UI_NETWORK_TYPE = 'networkBeta'
-
-global.METAMASK_DEBUG = process.env.METAMASK_DEBUG
-
-module.exports = {
- network: {
- localhost: LOCALHOST_RPC_URL,
- mainnet: MAINET_RPC_URL,
- ropsten: ROPSTEN_RPC_URL,
- kovan: KOVAN_RPC_URL,
- rinkeby: RINKEBY_RPC_URL,
- },
- // Used for beta UI
- networkBeta: {
- localhost: LOCALHOST_RPC_URL,
- mainnet: MAINET_RPC_URL_BETA,
- ropsten: ROPSTEN_RPC_URL_BETA,
- kovan: KOVAN_RPC_URL_BETA,
- rinkeby: RINKEBY_RPC_URL_BETA,
- },
- networkNames: {
- 3: 'Ropsten',
- 4: 'Rinkeby',
- 42: 'Kovan',
- },
- enums: {
- DEFAULT_RPC,
- OLD_UI_NETWORK_TYPE,
- BETA_UI_NETWORK_TYPE,
- },
-}
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index fe1766273..ddf1a9432 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -23,6 +23,9 @@ if (shouldInjectWeb3()) {
setupStreams()
}
+/**
+ * Creates a script tag that injects inpage.js
+ */
function setupInjection () {
try {
// inject in-page script
@@ -37,6 +40,10 @@ function setupInjection () {
}
}
+/**
+ * Sets up two-way communication streams between the
+ * browser extension and local per-page browser context
+ */
function setupStreams () {
// setup communication to page and plugin
const pageStream = new LocalMessageDuplexStream({
@@ -89,17 +96,34 @@ function setupStreams () {
mux.ignoreStream('publicConfig')
}
+
+/**
+ * Error handler for page to plugin stream disconnections
+ *
+ * @param {string} remoteLabel Remote stream name
+ * @param {Error} err Stream connection error
+ */
function logStreamDisconnectWarning (remoteLabel, err) {
let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`
if (err) warningMsg += '\n' + err.stack
console.warn(warningMsg)
}
+/**
+ * Determines if Web3 should be injected
+ *
+ * @returns {boolean} {@code true} if Web3 should be injected
+ */
function shouldInjectWeb3 () {
return doctypeCheck() && suffixCheck()
&& documentElementCheck() && !blacklistedDomainCheck()
}
+/**
+ * Checks the doctype of the current document if it exists
+ *
+ * @returns {boolean} {@code true} if the doctype is html or if none exists
+ */
function doctypeCheck () {
const doctype = window.document.doctype
if (doctype) {
@@ -109,6 +133,11 @@ function doctypeCheck () {
}
}
+/**
+ * Checks the current document extension
+ *
+ * @returns {boolean} {@code true} if the current extension is not prohibited
+ */
function suffixCheck () {
var prohibitedTypes = ['xml', 'pdf']
var currentUrl = window.location.href
@@ -122,6 +151,11 @@ function suffixCheck () {
return true
}
+/**
+ * Checks the documentElement of the current document
+ *
+ * @returns {boolean} {@code true} if the documentElement is an html node or if none exists
+ */
function documentElementCheck () {
var documentElement = document.documentElement.nodeName
if (documentElement) {
@@ -130,11 +164,17 @@ function documentElementCheck () {
return true
}
+/**
+ * Checks if the current domain is blacklisted
+ *
+ * @returns {boolean} {@code true} if the current domain is blacklisted
+ */
function blacklistedDomainCheck () {
var blacklistedDomains = [
'uscourts.gov',
'dropbox.com',
'webbyawards.com',
+ 'cdn.shopify.com/s/javascripts/tricorder/xtld-read-only-frame.html',
]
var currentUrl = window.location.href
var currentRegex
@@ -148,6 +188,9 @@ function blacklistedDomainCheck () {
return false
}
+/**
+ * Redirects the current page to a phishing information page
+ */
function redirectToPhishingWarning () {
console.log('MetaMask - redirecting to phishing warning')
window.location.href = 'https://metamask.io/phishing.html'
diff --git a/app/scripts/controllers/address-book.js b/app/scripts/controllers/address-book.js
index 6fb4ee114..c91e6b2e4 100644
--- a/app/scripts/controllers/address-book.js
+++ b/app/scripts/controllers/address-book.js
@@ -4,9 +4,22 @@ const extend = require('xtend')
class AddressBookController {
- // Controller in charge of managing the address book functionality from the
- // recipients field on the send screen. Manages a history of all saved
- // addresses and all currently owned addresses.
+ /**
+ * Controller in charge of managing the address book functionality from the
+ * recipients field on the send screen. Manages a history of all saved
+ * addresses and all currently owned addresses.
+ *
+ * @typedef {Object} AddressBookController
+ * @param {object} opts Overrides the defaults for the initial state of this.store
+ * @property {array} opts.initState initializes the the state of the AddressBookController. Can contain an
+ * addressBook property to initialize the addressBook array
+ * @param {KeyringController} keyringController (Soon to be deprecated) The keyringController used in the current
+ * MetamaskController. Contains the identities used in this AddressBookController.
+ * @property {object} store The the store of the current users address book
+ * @property {array} store.addressBook An array of addresses and nicknames. These are set by the user when sending
+ * to a new address.
+ *
+ */
constructor (opts = {}, keyringController) {
const initState = extend({
addressBook: [],
@@ -19,7 +32,14 @@ class AddressBookController {
// PUBLIC METHODS
//
- // Sets a new address book in store by accepting a new address and nickname.
+ /**
+ * Sets a new address book in store by accepting a new address and nickname.
+ *
+ * @param {string} address A hex address of a new account that the user is sending to.
+ * @param {string} name The name the user wishes to associate with the new account
+ * @returns {Promise<void>} Promise resolves with undefined
+ *
+ */
setAddressBook (address, name) {
return this._addToAddressBook(address, name)
.then((addressBook) => {
@@ -30,14 +50,16 @@ class AddressBookController {
})
}
- //
- // PRIVATE METHODS
- //
-
-
- // Performs the logic to add the address and name into the address book. The
- // pushed object is an object of two fields. Current behavior does not set an
- // upper limit to the number of addresses.
+ /**
+ * Performs the logic to add the address and name into the address book. The pushed object is an object of two
+ * fields. Current behavior does not set an upper limit to the number of addresses.
+ *
+ * @private
+ * @param {string} address A hex address of a new account that the user is sending to.
+ * @param {string} name The name the user wishes to associate with the new account
+ * @returns {Promise<array>} Promises the updated addressBook array
+ *
+ */
_addToAddressBook (address, name) {
const addressBook = this._getAddressBook()
const identities = this._getIdentities()
@@ -62,14 +84,26 @@ class AddressBookController {
return Promise.resolve(addressBook)
}
- // Internal method to get the address book. Current persistence behavior
- // should not require that this method be called from the UI directly.
+ /**
+ * Internal method to get the address book. Current persistence behavior should not require that this method be
+ * called from the UI directly.
+ *
+ * @private
+ * @returns {array} The addressBook array from the store.
+ *
+ */
_getAddressBook () {
return this.store.getState().addressBook
}
- // Retrieves identities from the keyring controller in order to avoid
- // duplication
+ /**
+ * Retrieves identities from the keyring controller in order to avoid
+ * duplication
+ *
+ * @deprecated
+ * @returns {array} Returns the identies array from the keyringContoller's state
+ *
+ */
_getIdentities () {
return this.keyringController.memStore.getState().identities
}
diff --git a/app/scripts/controllers/balance.js b/app/scripts/controllers/balance.js
index f83f294cc..86619fce1 100644
--- a/app/scripts/controllers/balance.js
+++ b/app/scripts/controllers/balance.js
@@ -4,6 +4,24 @@ const BN = require('ethereumjs-util').BN
class BalanceController {
+ /**
+ * Controller responsible for storing and updating an account's balance.
+ *
+ * @typedef {Object} BalanceController
+ * @param {Object} opts Initialize various properties of the class.
+ * @property {string} address A base 16 hex string. The account address which has the balance managed by this
+ * BalanceController.
+ * @property {AccountTracker} accountTracker Stores and updates the users accounts
+ * for which this BalanceController manages balance.
+ * @property {TransactionController} txController Stores, tracks and manages transactions. Here used to create a listener for
+ * transaction updates.
+ * @property {BlockTracker} blockTracker Tracks updates to blocks. On new blocks, this BalanceController updates its balance
+ * @property {Object} store The store for the ethBalance
+ * @property {string} store.ethBalance A base 16 hex string. The balance for the current account.
+ * @property {PendingBalanceCalculator} balanceCalc Used to calculate the accounts balance with possible pending
+ * transaction costs taken into account.
+ *
+ */
constructor (opts = {}) {
this._validateParams(opts)
const { address, accountTracker, txController, blockTracker } = opts
@@ -26,6 +44,11 @@ class BalanceController {
this._registerUpdates()
}
+ /**
+ * Updates the ethBalance property to the current pending balance
+ *
+ * @returns {Promise<void>} Promises undefined
+ */
async updateBalance () {
const balance = await this.balanceCalc.getBalance()
this.store.updateState({
@@ -33,6 +56,15 @@ class BalanceController {
})
}
+ /**
+ * Sets up listeners and subscriptions which should trigger an update of ethBalance. These updates include:
+ * - when a transaction changes state to 'submitted', 'confirmed' or 'failed'
+ * - when the current account changes (i.e. a new account is selected)
+ * - when there is a block update
+ *
+ * @private
+ *
+ */
_registerUpdates () {
const update = this.updateBalance.bind(this)
@@ -51,6 +83,14 @@ class BalanceController {
this.blockTracker.on('block', update)
}
+ /**
+ * Gets the balance, as a base 16 hex string, of the account at this BalanceController's current address.
+ * If the current account has no balance, returns undefined.
+ *
+ * @returns {Promise<BN|void>} Promises a BN with a value equal to the balance of the current account, or undefined
+ * if the current account has no balance
+ *
+ */
async _getBalance () {
const { accounts } = this.accountTracker.store.getState()
const entry = accounts[this.address]
@@ -58,6 +98,14 @@ class BalanceController {
return balance ? new BN(balance.substring(2), 16) : undefined
}
+ /**
+ * Gets the pending transactions (i.e. those with a 'submitted' status). These are accessed from the
+ * TransactionController passed to this BalanceController during construction.
+ *
+ * @private
+ * @returns {Promise<array>} Promises an array of transaction objects.
+ *
+ */
async _getPendingTransactions () {
const pending = this.txController.getFilteredTxList({
from: this.address,
@@ -67,6 +115,14 @@ class BalanceController {
return pending
}
+ /**
+ * Validates that the passed options have all required properties.
+ *
+ * @param {Object} opts The options object to validate
+ * @throws {string} Throw a custom error indicating that address, accountTracker, txController and blockTracker are
+ * missing and at least one is required
+ *
+ */
_validateParams (opts) {
const { address, accountTracker, txController, blockTracker } = opts
if (!address || !accountTracker || !txController || !blockTracker) {
diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js
index df41c90c0..f100c4525 100644
--- a/app/scripts/controllers/blacklist.js
+++ b/app/scripts/controllers/blacklist.js
@@ -1,6 +1,7 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
const PhishingDetector = require('eth-phishing-detect/src/detector')
+const log = require('loglevel')
// compute phishing lists
const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json')
@@ -9,6 +10,22 @@ const POLLING_INTERVAL = 4 * 60 * 1000
class BlacklistController {
+ /**
+ * Responsible for polling for and storing an up to date 'eth-phishing-detect' config.json file, while
+ * exposing a method that can check whether a given url is a phishing attempt. The 'eth-phishing-detect'
+ * config.json file contains a fuzzylist, whitelist and blacklist.
+ *
+ *
+ * @typedef {Object} BlacklistController
+ * @param {object} opts Overrides the defaults for the initial state of this.store
+ * @property {object} store The the store of the current phishing config
+ * @property {object} store.phishing Contains fuzzylist, whitelist and blacklist arrays. @see
+ * {@link https://github.com/MetaMask/eth-phishing-detect/blob/master/src/config.json}
+ * @property {object} _phishingDetector The PhishingDetector instantiated by passing store.phishing to
+ * PhishingDetector.
+ * @property {object} _phishingUpdateIntervalRef Id of the interval created to periodically update the blacklist
+ *
+ */
constructor (opts = {}) {
const initState = extend({
phishing: PHISHING_DETECTION_CONFIG,
@@ -21,16 +38,28 @@ class BlacklistController {
this._phishingUpdateIntervalRef = null
}
- //
- // PUBLIC METHODS
- //
-
+ /**
+ * Given a url, returns the result of checking if that url is in the store.phishing blacklist
+ *
+ * @param {string} hostname The hostname portion of a url; the one that will be checked against the white and
+ * blacklists of store.phishing
+ * @returns {boolean} Whether or not the passed hostname is on our phishing blacklist
+ *
+ */
checkForPhishing (hostname) {
if (!hostname) return false
const { result } = this._phishingDetector.check(hostname)
return result
}
+ /**
+ * Queries `https://api.infura.io/v2/blacklist` for an updated blacklist config. This is passed to this._phishingDetector
+ * to update our phishing detector instance, and is updated in the store. The new phishing config is returned
+ *
+ *
+ * @returns {Promise<object>} Promises the updated blacklist config for the phishingDetector
+ *
+ */
async updatePhishingList () {
const response = await fetch('https://api.infura.io/v2/blacklist')
const phishing = await response.json()
@@ -39,6 +68,11 @@ class BlacklistController {
return phishing
}
+ /**
+ * Initiates the updating of the local blacklist at a set interval. The update is done via this.updatePhishingList().
+ * Also, this method store a reference to that interval at this._phishingUpdateIntervalRef
+ *
+ */
scheduleUpdates () {
if (this._phishingUpdateIntervalRef) return
this.updatePhishingList().catch(log.warn)
@@ -47,10 +81,14 @@ class BlacklistController {
}, POLLING_INTERVAL)
}
- //
- // PRIVATE METHODS
- //
-
+ /**
+ * Sets this._phishingDetector to a new PhishingDetector instance.
+ * @see {@link https://github.com/MetaMask/eth-phishing-detect}
+ *
+ * @private
+ * @param {object} config A config object like that found at {@link https://github.com/MetaMask/eth-phishing-detect/blob/master/src/config.json}
+ *
+ */
_setupPhishingDetector (config) {
this._phishingDetector = new PhishingDetector(config)
}
diff --git a/app/scripts/controllers/computed-balances.js b/app/scripts/controllers/computed-balances.js
index 907b087cf..1a6802f9a 100644
--- a/app/scripts/controllers/computed-balances.js
+++ b/app/scripts/controllers/computed-balances.js
@@ -2,8 +2,24 @@ const ObservableStore = require('obs-store')
const extend = require('xtend')
const BalanceController = require('./balance')
-class ComputedbalancesController {
+/**
+ * @typedef {Object} ComputedBalancesOptions
+ * @property {Object} accountTracker Account tracker store reference
+ * @property {Object} txController Token controller reference
+ * @property {Object} blockTracker Block tracker reference
+ * @property {Object} initState Initial state to populate this internal store with
+ */
+/**
+ * Background controller responsible for syncing
+ * and computing ETH balances for all accounts
+ */
+class ComputedbalancesController {
+ /**
+ * Creates a new controller instance
+ *
+ * @param {ComputedBalancesOptions} [opts] Controller configuration parameters
+ */
constructor (opts = {}) {
const { accountTracker, txController, blockTracker } = opts
this.accountTracker = accountTracker
@@ -19,6 +35,9 @@ class ComputedbalancesController {
this._initBalanceUpdating()
}
+ /**
+ * Updates balances associated with each internal address
+ */
updateAllBalances () {
Object.keys(this.balances).forEach((balance) => {
const address = balance.address
@@ -26,12 +45,23 @@ class ComputedbalancesController {
})
}
+ /**
+ * Initializes internal address tracking
+ *
+ * @private
+ */
_initBalanceUpdating () {
const store = this.accountTracker.store.getState()
this.syncAllAccountsFromStore(store)
this.accountTracker.store.subscribe(this.syncAllAccountsFromStore.bind(this))
}
+ /**
+ * Uses current account state to sync and track all
+ * addresses associated with the current account
+ *
+ * @param {{ accounts: Object }} store Account tracking state
+ */
syncAllAccountsFromStore (store) {
const upstream = Object.keys(store.accounts)
const balances = Object.keys(this.balances)
@@ -50,6 +80,13 @@ class ComputedbalancesController {
})
}
+ /**
+ * Conditionally establishes a new subscription
+ * to track an address associated with the current
+ * account
+ *
+ * @param {string} address Address to conditionally subscribe to
+ */
trackAddressIfNotAlready (address) {
const state = this.store.getState()
if (!(address in state.computedBalances)) {
@@ -57,6 +94,12 @@ class ComputedbalancesController {
}
}
+ /**
+ * Establishes a new subscription to track an
+ * address associated with the current account
+ *
+ * @param {string} address Address to conditionally subscribe to
+ */
trackAddress (address) {
const updater = new BalanceController({
address,
diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js
index 36b8808aa..480c08b1c 100644
--- a/app/scripts/controllers/currency.js
+++ b/app/scripts/controllers/currency.js
@@ -1,11 +1,28 @@
-const ObservableStore = require('obs-store')
+ const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every ten minutes
const POLLING_INTERVAL = 600000
class CurrencyController {
+ /**
+ * Controller responsible for managing data associated with the currently selected currency.
+ *
+ * @typedef {Object} CurrencyController
+ * @param {object} opts Overrides the defaults for the initial state of this.store
+ * @property {array} opts.initState initializes the the state of the CurrencyController. Can contain an
+ * currentCurrency, conversionRate and conversionDate properties
+ * @property {string} currentCurrency A 2-4 character shorthand that describes a specific currency, currently
+ * selected by the user
+ * @property {number} conversionRate The conversion rate from ETH to the selected currency.
+ * @property {string} conversionDate The date at which the conversion rate was set. Expressed in in milliseconds
+ * since midnight of January 1, 1970
+ * @property {number} conversionInterval The id of the interval created by the scheduleConversionInterval method.
+ * Used to clear an existing interval on subsequent calls of that method.
+ *
+ */
constructor (opts = {}) {
const initState = extend({
currentCurrency: 'usd',
@@ -19,30 +36,73 @@ class CurrencyController {
// PUBLIC METHODS
//
+ /**
+ * A getter for the currentCurrency property
+ *
+ * @returns {string} A 2-4 character shorthand that describes a specific currency, currently selected by the user
+ *
+ */
getCurrentCurrency () {
return this.store.getState().currentCurrency
}
+ /**
+ * A setter for the currentCurrency property
+ *
+ * @param {string} currentCurrency The new currency to set as the currentCurrency in the store
+ *
+ */
setCurrentCurrency (currentCurrency) {
this.store.updateState({ currentCurrency })
}
+ /**
+ * A getter for the conversionRate property
+ *
+ * @returns {string} The conversion rate from ETH to the selected currency.
+ *
+ */
getConversionRate () {
return this.store.getState().conversionRate
}
+ /**
+ * A setter for the conversionRate property
+ *
+ * @param {number} conversionRate The new rate to set as the conversionRate in the store
+ *
+ */
setConversionRate (conversionRate) {
this.store.updateState({ conversionRate })
}
+ /**
+ * A getter for the conversionDate property
+ *
+ * @returns {string} The date at which the conversion rate was set. Expressed in milliseconds since midnight of
+ * January 1, 1970
+ *
+ */
getConversionDate () {
return this.store.getState().conversionDate
}
+ /**
+ * A setter for the conversionDate property
+ *
+ * @param {number} conversionDate The date, expressed in milliseconds since midnight of January 1, 1970, that the
+ * conversionRate was set
+ *
+ */
setConversionDate (conversionDate) {
this.store.updateState({ conversionDate })
}
+ /**
+ * Updates the conversionRate and conversionDate properties associated with the currentCurrency. Updated info is
+ * fetched from an external API
+ *
+ */
async updateConversionRate () {
let currentCurrency
try {
@@ -58,6 +118,12 @@ class CurrencyController {
}
}
+ /**
+ * Creates a new poll, using setInterval, to periodically call updateConversionRate. The id of the interval is
+ * stored at the controller's conversionInterval property. If it is called and such an id already exists, the
+ * previous interval is clear and a new one is created.
+ *
+ */
scheduleConversionInterval () {
if (this.conversionInterval) {
clearInterval(this.conversionInterval)
diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js
index c6b4c9de2..8f6dd837e 100644
--- a/app/scripts/controllers/infura.js
+++ b/app/scripts/controllers/infura.js
@@ -1,5 +1,6 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every ten minutes
const POLLING_INTERVAL = 10 * 60 * 1000
diff --git a/app/scripts/controllers/network/enums.js b/app/scripts/controllers/network/enums.js
new file mode 100644
index 000000000..4f29e301b
--- /dev/null
+++ b/app/scripts/controllers/network/enums.js
@@ -0,0 +1,56 @@
+const ROPSTEN = 'ropsten'
+const RINKEBY = 'rinkeby'
+const KOVAN = 'kovan'
+const MAINNET = 'mainnet'
+const LOCALHOST = 'localhost'
+
+const ROPSTEN_CODE = 3
+const RINKEYBY_CODE = 4
+const KOVAN_CODE = 42
+
+const ROPSTEN_DISPLAY_NAME = 'Ropsten'
+const RINKEBY_DISPLAY_NAME = 'Rinkeby'
+const KOVAN_DISPLAY_NAME = 'Kovan'
+const MAINNET_DISPLAY_NAME = 'Main Ethereum Network'
+
+const MAINNET_RPC_URL = 'https://mainnet.infura.io/metamask'
+const ROPSTEN_RPC_URL = 'https://ropsten.infura.io/metamask'
+const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask'
+const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask'
+const LOCALHOST_RPC_URL = 'http://localhost:8545'
+
+const MAINNET_RPC_URL_BETA = 'https://mainnet.infura.io/metamask2'
+const ROPSTEN_RPC_URL_BETA = 'https://ropsten.infura.io/metamask2'
+const KOVAN_RPC_URL_BETA = 'https://kovan.infura.io/metamask2'
+const RINKEBY_RPC_URL_BETA = 'https://rinkeby.infura.io/metamask2'
+
+const DEFAULT_NETWORK = 'rinkeby'
+const OLD_UI_NETWORK_TYPE = 'network'
+const BETA_UI_NETWORK_TYPE = 'networkBeta'
+
+module.exports = {
+ ROPSTEN,
+ RINKEBY,
+ KOVAN,
+ MAINNET,
+ LOCALHOST,
+ ROPSTEN_CODE,
+ RINKEYBY_CODE,
+ KOVAN_CODE,
+ ROPSTEN_DISPLAY_NAME,
+ RINKEBY_DISPLAY_NAME,
+ KOVAN_DISPLAY_NAME,
+ MAINNET_DISPLAY_NAME,
+ MAINNET_RPC_URL,
+ ROPSTEN_RPC_URL,
+ KOVAN_RPC_URL,
+ RINKEBY_RPC_URL,
+ LOCALHOST_RPC_URL,
+ MAINNET_RPC_URL_BETA,
+ ROPSTEN_RPC_URL_BETA,
+ KOVAN_RPC_URL_BETA,
+ RINKEBY_RPC_URL_BETA,
+ DEFAULT_NETWORK,
+ OLD_UI_NETWORK_TYPE,
+ BETA_UI_NETWORK_TYPE,
+}
diff --git a/app/scripts/controllers/network/index.js b/app/scripts/controllers/network/index.js
new file mode 100644
index 000000000..fb095bf33
--- /dev/null
+++ b/app/scripts/controllers/network/index.js
@@ -0,0 +1,2 @@
+const NetworkController = require('./network')
+module.exports = NetworkController
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network/network.js
index 617456cd7..2f5b81cd2 100644
--- a/app/scripts/controllers/network.js
+++ b/app/scripts/controllers/network/network.js
@@ -1,16 +1,24 @@
const assert = require('assert')
const EventEmitter = require('events')
const createMetamaskProvider = require('web3-provider-engine/zero.js')
-const SubproviderFromProvider = require('web3-provider-engine/subproviders/web3.js')
+const SubproviderFromProvider = require('web3-provider-engine/subproviders/provider.js')
const createInfuraProvider = require('eth-json-rpc-infura/src/createProvider')
const ObservableStore = require('obs-store')
const ComposedStore = require('obs-store/lib/composed')
const extend = require('xtend')
const EthQuery = require('eth-query')
-const createEventEmitterProxy = require('../lib/events-proxy.js')
-const networkConfig = require('../config.js')
-const { OLD_UI_NETWORK_TYPE, DEFAULT_RPC } = networkConfig.enums
-const INFURA_PROVIDER_TYPES = ['ropsten', 'rinkeby', 'kovan', 'mainnet']
+const createEventEmitterProxy = require('../../lib/events-proxy.js')
+const log = require('loglevel')
+const {
+ ROPSTEN,
+ RINKEBY,
+ KOVAN,
+ MAINNET,
+ OLD_UI_NETWORK_TYPE,
+ DEFAULT_NETWORK,
+} = require('./enums')
+const { getNetworkEndpoints } = require('./util')
+const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]
module.exports = class NetworkController extends EventEmitter {
@@ -18,8 +26,8 @@ module.exports = class NetworkController extends EventEmitter {
super()
this._networkEndpointVersion = OLD_UI_NETWORK_TYPE
- this._networkEndpoints = this.getNetworkEndpoints(OLD_UI_NETWORK_TYPE)
- this._defaultRpc = this._networkEndpoints[DEFAULT_RPC]
+ this._networkEndpoints = getNetworkEndpoints(OLD_UI_NETWORK_TYPE)
+ this._defaultRpc = this._networkEndpoints[DEFAULT_NETWORK]
config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider)
this.networkStore = new ObservableStore('loading')
@@ -36,17 +44,13 @@ module.exports = class NetworkController extends EventEmitter {
}
this._networkEndpointVersion = version
- this._networkEndpoints = this.getNetworkEndpoints(version)
- this._defaultRpc = this._networkEndpoints[DEFAULT_RPC]
+ this._networkEndpoints = getNetworkEndpoints(version)
+ this._defaultRpc = this._networkEndpoints[DEFAULT_NETWORK]
const { type } = this.getProviderConfig()
return this.setProviderType(type, true)
}
- getNetworkEndpoints (version = OLD_UI_NETWORK_TYPE) {
- return networkConfig[version]
- }
-
initializeProvider (_providerParams) {
this._baseProviderParams = _providerParams
const { type, rpcTarget } = this.providerStore.getState()
diff --git a/app/scripts/controllers/network/util.js b/app/scripts/controllers/network/util.js
new file mode 100644
index 000000000..4f38ccda4
--- /dev/null
+++ b/app/scripts/controllers/network/util.js
@@ -0,0 +1,65 @@
+const {
+ ROPSTEN,
+ RINKEBY,
+ KOVAN,
+ MAINNET,
+ LOCALHOST,
+ ROPSTEN_CODE,
+ RINKEYBY_CODE,
+ KOVAN_CODE,
+ ROPSTEN_DISPLAY_NAME,
+ RINKEBY_DISPLAY_NAME,
+ KOVAN_DISPLAY_NAME,
+ MAINNET_DISPLAY_NAME,
+ MAINNET_RPC_URL,
+ ROPSTEN_RPC_URL,
+ KOVAN_RPC_URL,
+ RINKEBY_RPC_URL,
+ LOCALHOST_RPC_URL,
+ MAINNET_RPC_URL_BETA,
+ ROPSTEN_RPC_URL_BETA,
+ KOVAN_RPC_URL_BETA,
+ RINKEBY_RPC_URL_BETA,
+ OLD_UI_NETWORK_TYPE,
+ BETA_UI_NETWORK_TYPE,
+} = require('./enums')
+
+const networkToNameMap = {
+ [ROPSTEN]: ROPSTEN_DISPLAY_NAME,
+ [RINKEBY]: RINKEBY_DISPLAY_NAME,
+ [KOVAN]: KOVAN_DISPLAY_NAME,
+ [MAINNET]: MAINNET_DISPLAY_NAME,
+ [ROPSTEN_CODE]: ROPSTEN_DISPLAY_NAME,
+ [RINKEYBY_CODE]: RINKEBY_DISPLAY_NAME,
+ [KOVAN_CODE]: KOVAN_DISPLAY_NAME,
+}
+
+const networkEndpointsMap = {
+ [OLD_UI_NETWORK_TYPE]: {
+ [LOCALHOST]: LOCALHOST_RPC_URL,
+ [MAINNET]: MAINNET_RPC_URL,
+ [ROPSTEN]: ROPSTEN_RPC_URL,
+ [KOVAN]: KOVAN_RPC_URL,
+ [RINKEBY]: RINKEBY_RPC_URL,
+ },
+ [BETA_UI_NETWORK_TYPE]: {
+ [LOCALHOST]: LOCALHOST_RPC_URL,
+ [MAINNET]: MAINNET_RPC_URL_BETA,
+ [ROPSTEN]: ROPSTEN_RPC_URL_BETA,
+ [KOVAN]: KOVAN_RPC_URL_BETA,
+ [RINKEBY]: RINKEBY_RPC_URL_BETA,
+ },
+}
+
+const getNetworkDisplayName = key => networkToNameMap[key]
+
+const getNetworkEndpoints = (networkType = OLD_UI_NETWORK_TYPE) => {
+ return {
+ ...networkEndpointsMap[networkType],
+ }
+}
+
+module.exports = {
+ getNetworkDisplayName,
+ getNetworkEndpoints,
+}
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index b4819d951..1d3308d36 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -4,6 +4,21 @@ const extend = require('xtend')
class PreferencesController {
+ /**
+ *
+ * @typedef {Object} PreferencesController
+ * @param {object} opts Overrides the defaults for the initial state of this.store
+ * @property {object} store The stored object containing a users preferences, stored in local storage
+ * @property {array} store.frequentRpcList A list of custom rpcs to provide the user
+ * @property {string} store.currentAccountTab Indicates the selected tab in the ui
+ * @property {array} store.tokens The tokens the user wants display in their token lists
+ * @property {boolean} store.useBlockie The users preference for blockie identicons within the UI
+ * @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the
+ * user wishes to see that feature
+ * @property {string} store.currentLocale The preferred language locale key
+ * @property {string} store.selectedAddress A hex string that matches the currently selected address in the app
+ *
+ */
constructor (opts = {}) {
const initState = extend({
frequentRpcList: [],
@@ -17,18 +32,43 @@ class PreferencesController {
}
// PUBLIC METHODS
+ /**
+ * Setter for the `useBlockie` property
+ *
+ * @param {boolean} val Whether or not the user prefers blockie indicators
+ *
+ */
setUseBlockie (val) {
this.store.updateState({ useBlockie: val })
}
+ /**
+ * Getter for the `useBlockie` property
+ *
+ * @returns {boolean} this.store.useBlockie
+ *
+ */
getUseBlockie () {
return this.store.getState().useBlockie
}
+ /**
+ * Setter for the `currentLocale` property
+ *
+ * @param {string} key he preferred language locale key
+ *
+ */
setCurrentLocale (key) {
this.store.updateState({ currentLocale: key })
}
+ /**
+ * Setter for the `selectedAddress` property
+ *
+ * @param {string} _address A new hex address for an account
+ * @returns {Promise<void>} Promise resolves with undefined
+ *
+ */
setSelectedAddress (_address) {
return new Promise((resolve, reject) => {
const address = normalizeAddress(_address)
@@ -37,10 +77,37 @@ class PreferencesController {
})
}
+ /**
+ * Getter for the `selectedAddress` property
+ *
+ * @returns {string} The hex address for the currently selected account
+ *
+ */
getSelectedAddress () {
return this.store.getState().selectedAddress
}
+ /**
+ * Contains data about tokens users add to their account.
+ * @typedef {Object} AddedToken
+ * @property {string} address - The hex address for the token contract. Will be all lower cased and hex-prefixed.
+ * @property {string} symbol - The symbol of the token, usually 3 or 4 capitalized letters
+ * {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#symbol}
+ * @property {boolean} decimals - The number of decimals the token uses.
+ * {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#decimals}
+ */
+
+ /**
+ * Adds a new token to the token array, or updates the token if passed an address that already exists.
+ * Modifies the existing tokens array from the store. All objects in the tokens array array AddedToken objects.
+ * @see AddedToken {@link AddedToken}
+ *
+ * @param {string} rawAddress Hex address of the token contract. May or may not be a checksum address.
+ * @param {string} symbol The symbol of the token
+ * @param {number} decimals The number of decimals the token uses.
+ * @returns {Promise<array>} Promises the new array of AddedToken objects.
+ *
+ */
async addToken (rawAddress, symbol, decimals) {
const address = normalizeAddress(rawAddress)
const newEntry = { address, symbol, decimals }
@@ -62,6 +129,13 @@ class PreferencesController {
return Promise.resolve(tokens)
}
+ /**
+ * Removes a specified token from the tokens array.
+ *
+ * @param {string} rawAddress Hex address of the token contract to remove.
+ * @returns {Promise<array>} The new array of AddedToken objects
+ *
+ */
removeToken (rawAddress) {
const tokens = this.store.getState().tokens
@@ -71,10 +145,23 @@ class PreferencesController {
return Promise.resolve(updatedTokens)
}
+ /**
+ * A getter for the `tokens` property
+ *
+ * @returns {array} The current array of AddedToken objects
+ *
+ */
getTokens () {
return this.store.getState().tokens
}
+ /**
+ * Gets an updated rpc list from this.addToFrequentRpcList() and sets the `frequentRpcList` to this update list.
+ *
+ * @param {string} _url The the new rpc url to add to the updated list
+ * @returns {Promise<void>} Promise resolves with undefined
+ *
+ */
updateFrequentRpcList (_url) {
return this.addToFrequentRpcList(_url)
.then((rpcList) => {
@@ -83,6 +170,13 @@ class PreferencesController {
})
}
+ /**
+ * Setter for the `currentAccountTab` property
+ *
+ * @param {string} currentAccountTab Specifies the new tab to be marked as current
+ * @returns {Promise<void>} Promise resolves with undefined
+ *
+ */
setCurrentAccountTab (currentAccountTab) {
return new Promise((resolve, reject) => {
this.store.updateState({ currentAccountTab })
@@ -90,6 +184,15 @@ class PreferencesController {
})
}
+ /**
+ * Returns an updated rpcList based on the passed url and the current list.
+ * The returned list will have a max length of 2. If the _url currently exists it the list, it will be moved to the
+ * end of the list. The current list is modified and returned as a promise.
+ *
+ * @param {string} _url The rpc url to add to the frequentRpcList.
+ * @returns {Promise<array>} The updated frequentRpcList.
+ *
+ */
addToFrequentRpcList (_url) {
const rpcList = this.getFrequentRpcList()
const index = rpcList.findIndex((element) => { return element === _url })
@@ -105,10 +208,24 @@ class PreferencesController {
return Promise.resolve(rpcList)
}
+ /**
+ * Getter for the `frequentRpcList` property.
+ *
+ * @returns {array<string>} An array of one or two rpc urls.
+ *
+ */
getFrequentRpcList () {
return this.store.getState().frequentRpcList
}
+ /**
+ * Updates the `featureFlags` property, which is an object. One property within that object will be set to a boolean.
+ *
+ * @param {string} feature A key that corresponds to a UI feature.
+ * @param {boolean} activated Indicates whether or not the UI feature should be displayed
+ * @returns {Promise<object>} Promises a new object; the updated featureFlags object.
+ *
+ */
setFeatureFlag (feature, activated) {
const currentFeatureFlags = this.store.getState().featureFlags
const updatedFeatureFlags = {
@@ -121,6 +238,13 @@ class PreferencesController {
return Promise.resolve(updatedFeatureFlags)
}
+ /**
+ * A getter for the `featureFlags` property
+ *
+ * @returns {object} A key-boolean map, where keys refer to features and booleans to whether the
+ * user wishes to see that feature
+ *
+ */
getFeatureFlags () {
return this.store.getState().featureFlags
}
diff --git a/app/scripts/controllers/recent-blocks.js b/app/scripts/controllers/recent-blocks.js
index 4ae3810eb..1377c1ba9 100644
--- a/app/scripts/controllers/recent-blocks.js
+++ b/app/scripts/controllers/recent-blocks.js
@@ -2,9 +2,27 @@ const ObservableStore = require('obs-store')
const extend = require('xtend')
const BN = require('ethereumjs-util').BN
const EthQuery = require('eth-query')
+const log = require('loglevel')
class RecentBlocksController {
+ /**
+ * Controller responsible for storing, updating and managing the recent history of blocks. Blocks are back filled
+ * upon the controller's construction and then the list is updated when the given block tracker gets a 'block' event
+ * (indicating that there is a new block to process).
+ *
+ * @typedef {Object} RecentBlocksController
+ * @param {object} opts Contains objects necessary for tracking blocks and querying the blockchain
+ * @param {BlockTracker} opts.blockTracker Contains objects necessary for tracking blocks and querying the blockchain
+ * @param {BlockTracker} opts.provider The provider used to create a new EthQuery instance.
+ * @property {BlockTracker} blockTracker Points to the passed BlockTracker. On RecentBlocksController construction,
+ * listens for 'block' events so that new blocks can be processed and added to storage.
+ * @property {EthQuery} ethQuery Points to the EthQuery instance created with the passed provider
+ * @property {number} historyLength The maximum length of blocks to track
+ * @property {object} store Stores the recentBlocks
+ * @property {array} store.recentBlocks Contains all recent blocks, up to a total that is equal to this.historyLength
+ *
+ */
constructor (opts = {}) {
const { blockTracker, provider } = opts
this.blockTracker = blockTracker
@@ -20,12 +38,23 @@ class RecentBlocksController {
this.backfill()
}
+ /**
+ * Sets store.recentBlocks to an empty array
+ *
+ */
resetState () {
this.store.updateState({
recentBlocks: [],
})
}
+ /**
+ * Receives a new block and modifies it with this.mapTransactionsToPrices. Then adds that block to the recentBlocks
+ * array in storage. If the recentBlocks array contains the maximum number of blocks, the oldest block is removed.
+ *
+ * @param {object} newBlock The new block to modify and add to the recentBlocks array
+ *
+ */
processBlock (newBlock) {
const block = this.mapTransactionsToPrices(newBlock)
@@ -39,6 +68,15 @@ class RecentBlocksController {
this.store.updateState(state)
}
+ /**
+ * Receives a new block and modifies it with this.mapTransactionsToPrices. Adds that block to the recentBlocks
+ * array in storage, but only if the recentBlocks array contains fewer than the maximum permitted.
+ *
+ * Unlike this.processBlock, backfillBlock adds the modified new block to the beginning of the recent block array.
+ *
+ * @param {object} newBlock The new block to modify and add to the beginning of the recentBlocks array
+ *
+ */
backfillBlock (newBlock) {
const block = this.mapTransactionsToPrices(newBlock)
@@ -51,6 +89,14 @@ class RecentBlocksController {
this.store.updateState(state)
}
+ /**
+ * Receives a block and gets the gasPrice of each of its transactions. These gas prices are added to the block at a
+ * new property, and the block's transactions are removed.
+ *
+ * @param {object} newBlock The block to modify. It's transaction array will be replaced by a gasPrices array.
+ * @returns {object} The modified block.
+ *
+ */
mapTransactionsToPrices (newBlock) {
const block = extend(newBlock, {
gasPrices: newBlock.transactions.map((tx) => {
@@ -61,6 +107,16 @@ class RecentBlocksController {
return block
}
+ /**
+ * On this.blockTracker's first 'block' event after this RecentBlocksController's instantiation, the store.recentBlocks
+ * array is populated with this.historyLength number of blocks. The block number of the this.blockTracker's first
+ * 'block' event is used to iteratively generate all the numbers of the previous blocks, which are obtained by querying
+ * the blockchain. These blocks are backfilled so that the recentBlocks array is ordered from oldest to newest.
+ *
+ * Each iteration over the block numbers is delayed by 100 milliseconds.
+ *
+ * @returns {Promise<void>} Promises undefined
+ */
async backfill() {
this.blockTracker.once('block', async (block) => {
let blockNum = block.number
@@ -89,12 +145,25 @@ class RecentBlocksController {
})
}
+ /**
+ * A helper for this.backfill. Provides an easy way to ensure a 100 millisecond delay using await
+ *
+ * @returns {Promise<void>} Promises undefined
+ *
+ */
async wait () {
return new Promise((resolve) => {
setTimeout(resolve, 100)
})
}
+ /**
+ * Uses EthQuery to get a block that has a given block number.
+ *
+ * @param {number} number The number of the block to get
+ * @returns {Promise<object>} Promises A block with the passed number
+ *
+ */
async getBlockByNumber (number) {
const bn = new BN(number)
return new Promise((resolve, reject) => {
diff --git a/app/scripts/controllers/shapeshift.js b/app/scripts/controllers/shapeshift.js
index 3bbfaa1c5..b2a1462c2 100644
--- a/app/scripts/controllers/shapeshift.js
+++ b/app/scripts/controllers/shapeshift.js
@@ -1,11 +1,23 @@
const ObservableStore = require('obs-store')
const extend = require('xtend')
+const log = require('loglevel')
// every three seconds when an incomplete tx is waiting
const POLLING_INTERVAL = 3000
class ShapeshiftController {
+ /**
+ * Controller responsible for managing the list of shapeshift transactions. On construction, it initiates a poll
+ * that queries a shapeshift.io API for updates to any pending shapeshift transactions
+ *
+ * @typedef {Object} ShapeshiftController
+ * @param {object} opts Overrides the defaults for the initial state of this.store
+ * @property {array} opts.initState initializes the the state of the ShapeshiftController. Can contain an
+ * shapeShiftTxList array.
+ * @property {array} shapeShiftTxList An array of ShapeShiftTx objects
+ *
+ */
constructor (opts = {}) {
const initState = extend({
shapeShiftTxList: [],
@@ -14,21 +26,54 @@ class ShapeshiftController {
this.pollForUpdates()
}
+ /**
+ * Represents, and contains data about, a single shapeshift transaction.
+ * @typedef {Object} ShapeShiftTx
+ * @property {string} depositAddress - An address at which to send a crypto deposit, so that eth can be sent to the
+ * user's Metamask account
+ * @property {string} depositType - An abbreviation of the type of crypto currency to be deposited.
+ * @property {string} key - The 'shapeshift' key differentiates this from other types of txs in Metamask
+ * @property {number} time - The time at which the tx was created
+ * @property {object} response - Initiated as an empty object, which will be replaced by a Response object. @see {@link
+ * https://developer.mozilla.org/en-US/docs/Web/API/Response}
+ */
+
//
// PUBLIC METHODS
//
+ /**
+ * A getter for the shapeShiftTxList property
+ *
+ * @returns {array<ShapeShiftTx>}
+ *
+ */
getShapeShiftTxList () {
const shapeShiftTxList = this.store.getState().shapeShiftTxList
return shapeShiftTxList
}
+ /**
+ * A getter for all ShapeShiftTx in the shapeShiftTxList that have not successfully completed a deposit.
+ *
+ * @returns {array<ShapeShiftTx>} Only includes ShapeShiftTx which has a response property with a status !== complete
+ *
+ */
getPendingTxs () {
const txs = this.getShapeShiftTxList()
const pending = txs.filter(tx => tx.response && tx.response.status !== 'complete')
return pending
}
+ /**
+ * A poll that exists as long as there are pending transactions. Each call attempts to update the data of any
+ * pendingTxs, and then calls itself again. If there are no pending txs, the recursive call is not made and
+ * the polling stops.
+ *
+ * this.updateTx is used to attempt the update to the pendingTxs in the ShapeShiftTxList, and that updated data
+ * is saved with saveTx.
+ *
+ */
pollForUpdates () {
const pendingTxs = this.getPendingTxs()
@@ -45,6 +90,15 @@ class ShapeshiftController {
})
}
+ /**
+ * Attempts to update a ShapeShiftTx with data from a shapeshift.io API. Both the response and time properties
+ * can be updated. The response property is updated with every call, but the time property is only updated when
+ * the response status updates to 'complete'. This will occur once the user makes a deposit as the ShapeShiftTx
+ * depositAddress
+ *
+ * @param {ShapeShiftTx} tx The tx to update
+ *
+ */
async updateTx (tx) {
try {
const url = `https://shapeshift.io/txStat/${tx.depositAddress}`
@@ -60,6 +114,13 @@ class ShapeshiftController {
}
}
+ /**
+ * Saves an updated to a ShapeShiftTx in the shapeShiftTxList. If the passed ShapeShiftTx is not in the
+ * shapeShiftTxList, nothing happens.
+ *
+ * @param {ShapeShiftTx} tx The updated tx to save, if it exists in the current shapeShiftTxList
+ *
+ */
saveTx (tx) {
const { shapeShiftTxList } = this.store.getState()
const index = shapeShiftTxList.indexOf(tx)
@@ -69,6 +130,12 @@ class ShapeshiftController {
}
}
+ /**
+ * Removes a ShapeShiftTx from the shapeShiftTxList
+ *
+ * @param {ShapeShiftTx} tx The tx to remove
+ *
+ */
removeShapeShiftTx (tx) {
const { shapeShiftTxList } = this.store.getState()
const index = shapeShiftTxList.indexOf(index)
@@ -78,6 +145,14 @@ class ShapeshiftController {
this.updateState({ shapeShiftTxList })
}
+ /**
+ * Creates a new ShapeShiftTx, adds it to the shapeShiftTxList, and initiates a new poll for updates of pending txs
+ *
+ * @param {string} depositAddress - An address at which to send a crypto deposit, so that eth can be sent to the
+ * user's Metamask account
+ * @param {string} depositType - An abbreviation of the type of crypto currency to be deposited.
+ *
+ */
createShapeShiftTx (depositAddress, depositType) {
const state = this.store.getState()
let { shapeShiftTxList } = state
diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js
new file mode 100644
index 000000000..87d716aa6
--- /dev/null
+++ b/app/scripts/controllers/token-rates.js
@@ -0,0 +1,81 @@
+const ObservableStore = require('obs-store')
+const { warn } = require('loglevel')
+
+// By default, poll every 3 minutes
+const DEFAULT_INTERVAL = 180 * 1000
+
+/**
+ * A controller that polls for token exchange
+ * rates based on a user's current token list
+ */
+class TokenRatesController {
+ /**
+ * Creates a TokenRatesController
+ *
+ * @param {Object} [config] - Options to configure controller
+ */
+ constructor ({ interval = DEFAULT_INTERVAL, preferences } = {}) {
+ this.store = new ObservableStore()
+ this.preferences = preferences
+ this.interval = interval
+ }
+
+ /**
+ * Updates exchange rates for all tokens
+ */
+ async updateExchangeRates () {
+ if (!this.isActive) { return }
+ const contractExchangeRates = {}
+ for (const i in this._tokens) {
+ const address = this._tokens[i].address
+ contractExchangeRates[address] = await this.fetchExchangeRate(address)
+ }
+ this.store.putState({ contractExchangeRates })
+ }
+
+ /**
+ * Fetches a token exchange rate by address
+ *
+ * @param {String} address - Token contract address
+ */
+ async fetchExchangeRate (address) {
+ try {
+ const response = await fetch(`https://metamask.balanc3.net/prices?from=${address}&to=ETH&autoConversion=false&summaryOnly=true`)
+ const json = await response.json()
+ return json && json.length ? json[0].averagePrice : 0
+ } catch (error) {
+ warn(`MetaMask - TokenRatesController exchange rate fetch failed for ${address}.`, error)
+ return 0
+ }
+ }
+
+ /**
+ * @type {Number}
+ */
+ set interval (interval) {
+ this._handle && clearInterval(this._handle)
+ if (!interval) { return }
+ this._handle = setInterval(() => { this.updateExchangeRates() }, interval)
+ }
+
+ /**
+ * @type {Object}
+ */
+ set preferences (preferences) {
+ this._preferences && this._preferences.unsubscribe()
+ if (!preferences) { return }
+ this._preferences = preferences
+ this.tokens = preferences.getState().tokens
+ preferences.subscribe(({ tokens = [] }) => { this.tokens = tokens })
+ }
+
+ /**
+ * @type {Array}
+ */
+ set tokens (tokens) {
+ this._tokens = tokens
+ this.updateExchangeRates()
+ }
+}
+
+module.exports = TokenRatesController
diff --git a/app/scripts/controllers/transactions/README.md b/app/scripts/controllers/transactions/README.md
new file mode 100644
index 000000000..b414762dc
--- /dev/null
+++ b/app/scripts/controllers/transactions/README.md
@@ -0,0 +1,92 @@
+# Transaction Controller
+
+Transaction Controller is an aggregate of sub-controllers and trackers
+exposed to the MetaMask controller.
+
+- txStateManager
+ responsible for the state of a transaction and
+ storing the transaction
+- pendingTxTracker
+ watching blocks for transactions to be include
+ and emitting confirmed events
+- txGasUtil
+ gas calculations and safety buffering
+- nonceTracker
+ calculating nonces
+
+## Flow diagram of processing a transaction
+
+![transaction-flow](../../../../docs/transaction-flow.png)
+
+## txMeta's & txParams
+
+A txMeta is the "meta" object it has all the random bits of info we need about a transaction on it. txParams are sacred every thing on txParams gets signed so it must
+be a valid key and be hex prefixed except for the network number. Extra stuff must go on the txMeta!
+
+Here is a txMeta too look at:
+
+```js
+txMeta = {
+ "id": 2828415030114568, // unique id for this txMeta used for look ups
+ "time": 1524094064821, // time of creation
+ "status": "confirmed",
+ "metamaskNetworkId": "1524091532133", //the network id for the transaction
+ "loadingDefaults": false, // used to tell the ui when we are done calculatyig gass defaults
+ "txParams": { // the txParams object
+ "from": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "to": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0c",
+ "nonce": "0x0"
+ },
+ "history": [{ //debug
+ "id": 2828415030114568,
+ "time": 1524094064821,
+ "status": "unapproved",
+ "metamaskNetworkId": "1524091532133",
+ "loadingDefaults": true,
+ "txParams": {
+ "from": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "to": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "value": "0x0"
+ }
+ },
+ [
+ {
+ "op": "add",
+ "path": "/txParams/gasPrice",
+ "value": "0x3b9aca00"
+ },
+ ...], // I've removed most of history for this
+ "gasPriceSpecified": false, //whether or not the user/dapp has specified gasPrice
+ "gasLimitSpecified": false, //whether or not the user/dapp has specified gas
+ "estimatedGas": "5208",
+ "origin": "MetaMask", //debug
+ "nonceDetails": {
+ "params": {
+ "highestLocallyConfirmed": 0,
+ "highestSuggested": 0,
+ "nextNetworkNonce": 0
+ },
+ "local": {
+ "name": "local",
+ "nonce": 0,
+ "details": {
+ "startPoint": 0,
+ "highest": 0
+ }
+ },
+ "network": {
+ "name": "network",
+ "nonce": 0,
+ "details": {
+ "baseCount": 0
+ }
+ }
+ },
+ "rawTx": "0xf86980843b9aca00827b0c948acce2391c0d510a6c5e5d8f819a678f79b7e67580808602c5b5de66eea05c01a320b96ac730cb210ca56d2cb71fa360e1fc2c21fa5cf333687d18eb323fa02ed05987a6e5fd0f2459fcff80710b76b83b296454ad9a37594a0ccb4643ea90", // used for rebroadcast
+ "hash": "0xa45ba834b97c15e6ff4ed09badd04ecd5ce884b455eb60192cdc73bcc583972a",
+ "submittedTime": 1524094077902 // time of the attempt to submit the raw tx to the network, used in the ui to show the retry button
+}
+```
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions/index.js
index 31e53554d..a1588cfef 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions/index.js
@@ -3,27 +3,42 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const Transaction = require('ethereumjs-tx')
const EthQuery = require('ethjs-query')
-const TransactionStateManager = require('../lib/tx-state-manager')
-const TxGasUtil = require('../lib/tx-gas-utils')
-const PendingTransactionTracker = require('../lib/pending-tx-tracker')
-const NonceTracker = require('../lib/nonce-tracker')
-
-/*
+const TransactionStateManager = require('./tx-state-manager')
+const TxGasUtil = require('./tx-gas-utils')
+const PendingTransactionTracker = require('./pending-tx-tracker')
+const NonceTracker = require('./nonce-tracker')
+const txUtils = require('./lib/util')
+const log = require('loglevel')
+
+/**
Transaction Controller is an aggregate of sub-controllers and trackers
composing them in a way to be exposed to the metamask controller
- - txStateManager
+ <br>- txStateManager
responsible for the state of a transaction and
storing the transaction
- - pendingTxTracker
+ <br>- pendingTxTracker
watching blocks for transactions to be include
and emitting confirmed events
- - txGasUtil
+ <br>- txGasUtil
gas calculations and safety buffering
- - nonceTracker
+ <br>- nonceTracker
calculating nonces
+
+
+ @class
+ @param {object} - opts
+ @param {object} opts.initState - initial transaction list default is an empty array
+ @param {Object} opts.networkStore - an observable store for network number
+ @param {Object} opts.blockTracker - An instance of eth-blocktracker
+ @param {Object} opts.provider - A network provider.
+ @param {Function} opts.signTransaction - function the signs an ethereumjs-tx
+ @param {Function} [opts.getGasPrice] - optional gas price calculator
+ @param {Function} opts.signTransaction - ethTx signer that returns a rawTx
+ @param {Number} [opts.txHistoryLimit] - number *optional* for limiting how many transactions are in state
+ @param {Object} opts.preferencesStore
*/
-module.exports = class TransactionController extends EventEmitter {
+class TransactionController extends EventEmitter {
constructor (opts) {
super()
this.networkStore = opts.networkStore || new ObservableStore({})
@@ -37,45 +52,19 @@ module.exports = class TransactionController extends EventEmitter {
this.query = new EthQuery(this.provider)
this.txGasUtil = new TxGasUtil(this.provider)
+ this._mapMethods()
this.txStateManager = new TransactionStateManager({
initState: opts.initState,
txHistoryLimit: opts.txHistoryLimit,
getNetwork: this.getNetwork.bind(this),
})
-
- this.txStateManager.getFilteredTxList({
- status: 'unapproved',
- loadingDefaults: true,
- }).forEach((tx) => {
- this.addTxDefaults(tx)
- .then((txMeta) => {
- txMeta.loadingDefaults = false
- this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot')
- }).catch((error) => {
- this.txStateManager.setTxStatusFailed(tx.id, error)
- })
- })
-
- this.txStateManager.getFilteredTxList({
- status: 'approved',
- }).forEach((txMeta) => {
- const txSignError = new Error('Transaction found as "approved" during boot - possibly stuck during signing')
- this.txStateManager.setTxStatusFailed(txMeta.id, txSignError)
- })
-
+ this._onBootCleanUp()
this.store = this.txStateManager.store
- this.txStateManager.on('tx:status-update', this.emit.bind(this, 'tx:status-update'))
this.nonceTracker = new NonceTracker({
provider: this.provider,
getPendingTransactions: this.txStateManager.getPendingTransactions.bind(this.txStateManager),
- getConfirmedTransactions: (address) => {
- return this.txStateManager.getFilteredTxList({
- from: address,
- status: 'confirmed',
- err: undefined,
- })
- },
+ getConfirmedTransactions: this.txStateManager.getConfirmedTransactions.bind(this.txStateManager),
})
this.pendingTxTracker = new PendingTransactionTracker({
@@ -87,60 +76,14 @@ module.exports = class TransactionController extends EventEmitter {
})
this.txStateManager.store.subscribe(() => this.emit('update:badge'))
-
- this.pendingTxTracker.on('tx:warning', (txMeta) => {
- this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:warning')
- })
- this.pendingTxTracker.on('tx:confirmed', (txId) => this._markNonceDuplicatesDropped(txId))
- this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
- this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => {
- if (!txMeta.firstRetryBlockNumber) {
- txMeta.firstRetryBlockNumber = latestBlockNumber
- this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:block-update')
- }
- })
- this.pendingTxTracker.on('tx:retry', (txMeta) => {
- if (!('retryCount' in txMeta)) txMeta.retryCount = 0
- txMeta.retryCount++
- this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:retry')
- })
-
- this.blockTracker.on('block', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
- // this is a little messy but until ethstore has been either
- // removed or redone this is to guard against the race condition
- this.blockTracker.on('latest', this.pendingTxTracker.resubmitPendingTxs.bind(this.pendingTxTracker))
- this.blockTracker.on('sync', this.pendingTxTracker.queryPendingTxs.bind(this.pendingTxTracker))
+ this._setupListners()
// memstore is computed from a few different stores
this._updateMemstore()
this.txStateManager.store.subscribe(() => this._updateMemstore())
this.networkStore.subscribe(() => this._updateMemstore())
this.preferencesStore.subscribe(() => this._updateMemstore())
}
-
- getState () {
- return this.memStore.getState()
- }
-
- getNetwork () {
- return this.networkStore.getState()
- }
-
- getSelectedAddress () {
- return this.preferencesStore.getState().selectedAddress
- }
-
- getUnapprovedTxCount () {
- return Object.keys(this.txStateManager.getUnapprovedTxList()).length
- }
-
- getPendingTxCount (account) {
- return this.txStateManager.getPendingTransactions(account).length
- }
-
- getFilteredTxList (opts) {
- return this.txStateManager.getFilteredTxList(opts)
- }
-
+ /** @returns {number} the chainId*/
getChainId () {
const networkState = this.networkStore.getState()
const getChainId = parseInt(networkState)
@@ -151,16 +94,45 @@ module.exports = class TransactionController extends EventEmitter {
}
}
+/**
+ Adds a tx to the txlist
+ @emits ${txMeta.id}:unapproved
+*/
+ addTx (txMeta) {
+ this.txStateManager.addTx(txMeta)
+ this.emit(`${txMeta.id}:unapproved`, txMeta)
+ }
+
+ /**
+ Wipes the transactions for a given account
+ @param {string} address - hex string of the from address for txs being removed
+ */
wipeTransactions (address) {
this.txStateManager.wipeTransactions(address)
}
- // Adds a tx to the txlist
- addTx (txMeta) {
- this.txStateManager.addTx(txMeta)
- this.emit(`${txMeta.id}:unapproved`, txMeta)
+ /**
+ Check if a txMeta in the list with the same nonce has been confirmed in a block
+ if the txParams dont have a nonce will return false
+ @returns {boolean} weather the nonce has been used in a transaction confirmed in a block
+ @param {object} txMeta - the txMeta object
+ */
+ async isNonceTaken (txMeta) {
+ const { from, nonce } = txMeta.txParams
+ if ('nonce' in txMeta.txParams) {
+ const sameNonceTxList = this.txStateManager.getFilteredTxList({from, nonce, status: 'confirmed'})
+ return (sameNonceTxList.length >= 1)
+ }
+ return false
}
+ /**
+ add a new unapproved transaction to the pipeline
+
+ @returns {Promise<string>} the hash of the transaction after being submitted to the network
+ @param txParams {object} - txParams for the transaction
+ @param opts {object} - with the key origin to put the origin on the txMeta
+ */
async newUnapprovedTransaction (txParams, opts = {}) {
log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
const initialTxMeta = await this.addUnapprovedTransaction(txParams)
@@ -183,16 +155,24 @@ module.exports = class TransactionController extends EventEmitter {
})
}
+ /**
+ Validates and generates a txMeta with defaults and puts it in txStateManager
+ store
+
+ @returns {txMeta}
+ */
+
async addUnapprovedTransaction (txParams) {
// validate
- await this.txGasUtil.validateTxParams(txParams)
+ const normalizedTxParams = txUtils.normalizeTxParams(txParams)
+ txUtils.validateTxParams(normalizedTxParams)
// construct txMeta
- let txMeta = this.txStateManager.generateTxMeta({txParams})
+ let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams })
this.addTx(txMeta)
this.emit('newUnapprovedTx', txMeta)
// add default tx params
try {
- txMeta = await this.addTxDefaults(txMeta)
+ txMeta = await this.addTxGasDefaults(txMeta)
} catch (error) {
console.log(error)
this.txStateManager.setTxStatusFailed(txMeta.id, error)
@@ -204,22 +184,33 @@ module.exports = class TransactionController extends EventEmitter {
return txMeta
}
-
- async addTxDefaults (txMeta) {
+/**
+ adds the tx gas defaults: gas && gasPrice
+ @param txMeta {Object} - the txMeta object
+ @returns {Promise<object>} resolves with txMeta
+*/
+ async addTxGasDefaults (txMeta) {
const txParams = txMeta.txParams
// ensure value
+ txParams.value = txParams.value ? ethUtil.addHexPrefix(txParams.value) : '0x0'
txMeta.gasPriceSpecified = Boolean(txParams.gasPrice)
let gasPrice = txParams.gasPrice
if (!gasPrice) {
gasPrice = this.getGasPrice ? this.getGasPrice() : await this.query.gasPrice()
}
txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
- txParams.value = txParams.value || '0x0'
- if (txParams.to === null) delete txParams.to
// set gasLimit
return await this.txGasUtil.analyzeGasUsage(txMeta)
}
+ /**
+ Creates a new txMeta with the same txParams as the original
+ to allow the user to resign the transaction with a higher gas values
+ @param originalTxId {number} - the id of the txMeta that
+ you want to attempt to retry
+ @return {txMeta}
+ */
+
async retryTransaction (originalTxId) {
const originalTxMeta = this.txStateManager.getTx(originalTxId)
const lastGasPrice = originalTxMeta.txParams.gasPrice
@@ -233,15 +224,31 @@ module.exports = class TransactionController extends EventEmitter {
return txMeta
}
+ /**
+ updates the txMeta in the txStateManager
+ @param txMeta {Object} - the updated txMeta
+ */
async updateTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction')
}
+ /**
+ updates and approves the transaction
+ @param txMeta {Object}
+ */
async updateAndApproveTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction')
await this.approveTransaction(txMeta.id)
}
+ /**
+ sets the tx status to approved
+ auto fills the nonce
+ signs the transaction
+ publishes the transaction
+ if any of these steps fails the tx status will be set to failed
+ @param txId {number} - the tx's Id
+ */
async approveTransaction (txId) {
let nonceLock
try {
@@ -273,7 +280,11 @@ module.exports = class TransactionController extends EventEmitter {
throw err
}
}
-
+ /**
+ adds the chain id and signs the transaction and set the status to signed
+ @param txId {number} - the tx's Id
+ @returns - rawTx {string}
+ */
async signTransaction (txId) {
const txMeta = this.txStateManager.getTx(txId)
// add network/chain id
@@ -289,6 +300,12 @@ module.exports = class TransactionController extends EventEmitter {
return rawTx
}
+ /**
+ publishes the raw tx and sets the txMeta to submitted
+ @param txId {number} - the tx's Id
+ @param rawTx {string} - the hex string of the serialized signed transaction
+ @returns {Promise<void>}
+ */
async publishTransaction (txId, rawTx) {
const txMeta = this.txStateManager.getTx(txId)
txMeta.rawTx = rawTx
@@ -298,11 +315,20 @@ module.exports = class TransactionController extends EventEmitter {
this.txStateManager.setTxStatusSubmitted(txId)
}
+ /**
+ Convenience method for the ui thats sets the transaction to rejected
+ @param txId {number} - the tx's Id
+ @returns {Promise<void>}
+ */
async cancelTransaction (txId) {
this.txStateManager.setTxStatusRejected(txId)
}
- // receives a txHash records the tx as signed
+ /**
+ Sets the txHas on the txMeta
+ @param txId {number} - the tx's Id
+ @param txHash {string} - the hash for the txMeta
+ */
setTxHash (txId, txHash) {
// Add the tx hash to the persisted meta-tx object
const txMeta = this.txStateManager.getTx(txId)
@@ -313,9 +339,92 @@ module.exports = class TransactionController extends EventEmitter {
//
// PRIVATE METHODS
//
+ /** maps methods for convenience*/
+ _mapMethods () {
+ /** @returns the state in transaction controller */
+ this.getState = () => this.memStore.getState()
+ /** @returns the network number stored in networkStore */
+ this.getNetwork = () => this.networkStore.getState()
+ /** @returns the user selected address */
+ this.getSelectedAddress = () => this.preferencesStore.getState().selectedAddress
+ /** Returns an array of transactions whos status is unapproved */
+ this.getUnapprovedTxCount = () => Object.keys(this.txStateManager.getUnapprovedTxList()).length
+ /**
+ @returns a number that represents how many transactions have the status submitted
+ @param account {String} - hex prefixed account
+ */
+ this.getPendingTxCount = (account) => this.txStateManager.getPendingTransactions(account).length
+ /** see txStateManager */
+ this.getFilteredTxList = (opts) => this.txStateManager.getFilteredTxList(opts)
+ }
+
+ /**
+ If transaction controller was rebooted with transactions that are uncompleted
+ in steps of the transaction signing or user confirmation process it will either
+ transition txMetas to a failed state or try to redo those tasks.
+ */
+
+ _onBootCleanUp () {
+ this.txStateManager.getFilteredTxList({
+ status: 'unapproved',
+ loadingDefaults: true,
+ }).forEach((tx) => {
+ this.addTxGasDefaults(tx)
+ .then((txMeta) => {
+ txMeta.loadingDefaults = false
+ this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot')
+ }).catch((error) => {
+ this.txStateManager.setTxStatusFailed(tx.id, error)
+ })
+ })
+ this.txStateManager.getFilteredTxList({
+ status: 'approved',
+ }).forEach((txMeta) => {
+ const txSignError = new Error('Transaction found as "approved" during boot - possibly stuck during signing')
+ this.txStateManager.setTxStatusFailed(txMeta.id, txSignError)
+ })
+ }
+
+ /**
+ is called in constructor applies the listeners for pendingTxTracker txStateManager
+ and blockTracker
+ */
+ _setupListners () {
+ this.txStateManager.on('tx:status-update', this.emit.bind(this, 'tx:status-update'))
+ this.pendingTxTracker.on('tx:warning', (txMeta) => {
+ this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:warning')
+ })
+ this.pendingTxTracker.on('tx:confirmed', (txId) => this.txStateManager.setTxStatusConfirmed(txId))
+ this.pendingTxTracker.on('tx:confirmed', (txId) => this._markNonceDuplicatesDropped(txId))
+ this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
+ this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => {
+ if (!txMeta.firstRetryBlockNumber) {
+ txMeta.firstRetryBlockNumber = latestBlockNumber
+ this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:block-update')
+ }
+ })
+ this.pendingTxTracker.on('tx:retry', (txMeta) => {
+ if (!('retryCount' in txMeta)) txMeta.retryCount = 0
+ txMeta.retryCount++
+ this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:retry')
+ })
+
+ this.blockTracker.on('block', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
+ // this is a little messy but until ethstore has been either
+ // removed or redone this is to guard against the race condition
+ this.blockTracker.on('latest', this.pendingTxTracker.resubmitPendingTxs.bind(this.pendingTxTracker))
+ this.blockTracker.on('sync', this.pendingTxTracker.queryPendingTxs.bind(this.pendingTxTracker))
+
+ }
+
+ /**
+ Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
+ in the list have the same nonce
+
+ @param txId {Number} - the txId of the transaction that has been confirmed in a block
+ */
_markNonceDuplicatesDropped (txId) {
- this.txStateManager.setTxStatusConfirmed(txId)
// get the confirmed transactions nonce and from address
const txMeta = this.txStateManager.getTx(txId)
const { nonce, from } = txMeta.txParams
@@ -330,6 +439,9 @@ module.exports = class TransactionController extends EventEmitter {
})
}
+ /**
+ Updates the memStore in transaction controller
+ */
_updateMemstore () {
const unapprovedTxs = this.txStateManager.getUnapprovedTxList()
const selectedAddressTxList = this.txStateManager.getFilteredTxList({
@@ -339,3 +451,5 @@ module.exports = class TransactionController extends EventEmitter {
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
}
}
+
+module.exports = TransactionController
diff --git a/app/scripts/lib/tx-state-history-helper.js b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
index 94c7b6792..59a4b562c 100644
--- a/app/scripts/lib/tx-state-history-helper.js
+++ b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
@@ -1,6 +1,6 @@
const jsonDiffer = require('fast-json-patch')
const clone = require('clone')
-
+/** @module*/
module.exports = {
generateHistoryEntry,
replayHistory,
@@ -8,7 +8,11 @@ module.exports = {
migrateFromSnapshotsToDiffs,
}
-
+/**
+ converts non-initial history entries into diffs
+ @param longHistory {array}
+ @returns {array}
+*/
function migrateFromSnapshotsToDiffs (longHistory) {
return (
longHistory
@@ -20,6 +24,17 @@ function migrateFromSnapshotsToDiffs (longHistory) {
)
}
+/**
+ generates an array of history objects sense the previous state.
+ The object has the keys opp(the operation preformed),
+ path(the key and if a nested object then each key will be seperated with a `/`)
+ value
+ with the first entry having the note
+ @param previousState {object} - the previous state of the object
+ @param newState {object} - the update object
+ @param note {string} - a optional note for the state change
+ @reurns {array}
+*/
function generateHistoryEntry (previousState, newState, note) {
const entry = jsonDiffer.compare(previousState, newState)
// Add a note to the first op, since it breaks if we append it to the entry
@@ -27,11 +42,19 @@ function generateHistoryEntry (previousState, newState, note) {
return entry
}
+/**
+ Recovers previous txMeta state obj
+ @return {object}
+*/
function replayHistory (_shortHistory) {
const shortHistory = clone(_shortHistory)
return shortHistory.reduce((val, entry) => jsonDiffer.applyPatch(val, entry).newDocument)
}
+/**
+ @param txMeta {Object}
+ @returns {object} a clone object of the txMeta with out history
+*/
function snapshotFromTxMeta (txMeta) {
// create txMeta snapshot for history
const snapshot = clone(txMeta)
diff --git a/app/scripts/controllers/transactions/lib/util.js b/app/scripts/controllers/transactions/lib/util.js
new file mode 100644
index 000000000..84f7592a0
--- /dev/null
+++ b/app/scripts/controllers/transactions/lib/util.js
@@ -0,0 +1,99 @@
+const {
+ addHexPrefix,
+ isValidAddress,
+} = require('ethereumjs-util')
+
+/**
+@module
+*/
+module.exports = {
+ normalizeTxParams,
+ validateTxParams,
+ validateFrom,
+ validateRecipient,
+ getFinalStates,
+}
+
+
+// functions that handle normalizing of that key in txParams
+const normalizers = {
+ from: from => addHexPrefix(from).toLowerCase(),
+ to: to => addHexPrefix(to).toLowerCase(),
+ nonce: nonce => addHexPrefix(nonce),
+ value: value => addHexPrefix(value),
+ data: data => addHexPrefix(data),
+ gas: gas => addHexPrefix(gas),
+ gasPrice: gasPrice => addHexPrefix(gasPrice),
+}
+
+ /**
+ normalizes txParams
+ @param txParams {object}
+ @returns {object} normalized txParams
+ */
+function normalizeTxParams (txParams) {
+ // apply only keys in the normalizers
+ const normalizedTxParams = {}
+ for (const key in normalizers) {
+ if (txParams[key]) normalizedTxParams[key] = normalizers[key](txParams[key])
+ }
+ return normalizedTxParams
+}
+
+ /**
+ validates txParams
+ @param txParams {object}
+ */
+function validateTxParams (txParams) {
+ validateFrom(txParams)
+ validateRecipient(txParams)
+ if ('value' in txParams) {
+ const value = txParams.value.toString()
+ if (value.includes('-')) {
+ throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
+ }
+
+ if (value.includes('.')) {
+ throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
+ }
+ }
+}
+
+ /**
+ validates the from field in txParams
+ @param txParams {object}
+ */
+function validateFrom (txParams) {
+ if (!(typeof txParams.from === 'string')) throw new Error(`Invalid from address ${txParams.from} not a string`)
+ if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
+}
+
+ /**
+ validates the to field in txParams
+ @param txParams {object}
+ */
+function validateRecipient (txParams) {
+ if (txParams.to === '0x' || txParams.to === null) {
+ if (txParams.data) {
+ delete txParams.to
+ } else {
+ throw new Error('Invalid recipient address')
+ }
+ } else if (txParams.to !== undefined && !isValidAddress(txParams.to)) {
+ throw new Error('Invalid recipient address')
+ }
+ return txParams
+}
+
+ /**
+ @returns an {array} of states that can be considered final
+ */
+function getFinalStates () {
+ return [
+ 'rejected', // the user has responded no!
+ 'confirmed', // the tx has been included in a block.
+ 'failed', // the tx failed for some reason, included on tx data.
+ 'dropped', // the tx nonce was already used
+ ]
+}
+
diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/controllers/transactions/nonce-tracker.js
index 5b1cd7f43..f8cdc5523 100644
--- a/app/scripts/lib/nonce-tracker.js
+++ b/app/scripts/controllers/transactions/nonce-tracker.js
@@ -1,7 +1,15 @@
const EthQuery = require('ethjs-query')
const assert = require('assert')
const Mutex = require('await-semaphore').Mutex
-
+/**
+ @param opts {Object}
+ @param {Object} opts.provider a ethereum provider
+ @param {Function} opts.getPendingTransactions a function that returns an array of txMeta
+ whosee status is `submitted`
+ @param {Function} opts.getConfirmedTransactions a function that returns an array of txMeta
+ whose status is `confirmed`
+ @class
+*/
class NonceTracker {
constructor ({ provider, getPendingTransactions, getConfirmedTransactions }) {
@@ -12,6 +20,9 @@ class NonceTracker {
this.lockMap = {}
}
+ /**
+ @returns {Promise<Object>} with the key releaseLock (the gloabl mutex)
+ */
async getGlobalLock () {
const globalMutex = this._lookupMutex('global')
// await global mutex free
@@ -19,8 +30,20 @@ class NonceTracker {
return { releaseLock }
}
- // releaseLock must be called
- // releaseLock must be called after adding signed tx to pending transactions (or discarding)
+ /**
+ * @typedef NonceDetails
+ * @property {number} highestLocallyConfirmed - A hex string of the highest nonce on a confirmed transaction.
+ * @property {number} nextNetworkNonce - The next nonce suggested by the eth_getTransactionCount method.
+ * @property {number} highetSuggested - The maximum between the other two, the number returned.
+ */
+
+ /**
+ this will return an object with the `nextNonce` `nonceDetails` of type NonceDetails, and the releaseLock
+ Note: releaseLock must be called after adding a signed tx to pending transactions (or discarding).
+
+ @param address {string} the hex string for the address whose nonce we are calculating
+ @returns {Promise<NonceDetails>}
+ */
async getNonceLock (address) {
// await global mutex free
await this._globalMutexFree()
@@ -123,6 +146,17 @@ class NonceTracker {
return highestNonce
}
+ /**
+ @typedef {object} highestContinuousFrom
+ @property {string} - name the name for how the nonce was calculated based on the data used
+ @property {number} - nonce the next suggested nonce
+ @property {object} - details the provided starting nonce that was used (for debugging)
+ */
+ /**
+ @param txList {array} - list of txMeta's
+ @param startPoint {number} - the highest known locally confirmed nonce
+ @returns {highestContinuousFrom}
+ */
_getHighestContinuousFrom (txList, startPoint) {
const nonces = txList.map((txMeta) => {
const nonce = txMeta.txParams.nonce
@@ -140,6 +174,10 @@ class NonceTracker {
// this is a hotfix for the fact that the blockTracker will
// change when the network changes
+
+ /**
+ @returns {Object} the current blockTracker
+ */
_getBlockTracker () {
return this.provider._blockTracker
}
diff --git a/app/scripts/lib/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js
index e8869e6b8..6e2fcb40b 100644
--- a/app/scripts/lib/pending-tx-tracker.js
+++ b/app/scripts/controllers/transactions/pending-tx-tracker.js
@@ -1,23 +1,24 @@
const EventEmitter = require('events')
+const log = require('loglevel')
const EthQuery = require('ethjs-query')
-/*
-
- Utility class for tracking the transactions as they
- go from a pending state to a confirmed (mined in a block) state
+/**
+ Event emitter utility class for tracking the transactions as they<br>
+ go from a pending state to a confirmed (mined in a block) state<br>
+<br>
As well as continues broadcast while in the pending state
+<br>
+@param config {object} - non optional configuration object consists of:
+ @param {Object} config.provider - A network provider.
+ @param {Object} config.nonceTracker see nonce tracker
+ @param {function} config.getPendingTransactions a function for getting an array of transactions,
+ @param {function} config.publishTransaction a async function for publishing raw transactions,
- ~config is not optional~
- requires a: {
- provider: //,
- nonceTracker: //see nonce tracker,
- getPendingTransactions: //() a function for getting an array of transactions,
- publishTransaction: //(rawTx) a async function for publishing raw transactions,
- }
+@class
*/
-module.exports = class PendingTransactionTracker extends EventEmitter {
+class PendingTransactionTracker extends EventEmitter {
constructor (config) {
super()
this.query = new EthQuery(config.provider)
@@ -29,8 +30,13 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
this._checkPendingTxs()
}
- // checks if a signed tx is in a block and
- // if included sets the tx status as 'confirmed'
+ /**
+ checks if a signed tx is in a block and
+ if it is included emits tx status as 'confirmed'
+ @param block {object}, a full block
+ @emits tx:confirmed
+ @emits tx:failed
+ */
checkForTxInBlock (block) {
const signedTxList = this.getPendingTransactions()
if (!signedTxList.length) return
@@ -52,6 +58,11 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
})
}
+ /**
+ asks the network for the transaction to see if a block number is included on it
+ if we have skipped/missed blocks
+ @param object - oldBlock newBlock
+ */
queryPendingTxs ({ oldBlock, newBlock }) {
// check pending transactions on start
if (!oldBlock) {
@@ -63,7 +74,11 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
if (diff > 1) this._checkPendingTxs()
}
-
+ /**
+ Will resubmit any transactions who have not been confirmed in a block
+ @param block {object} - a block object
+ @emits tx:warning
+ */
resubmitPendingTxs (block) {
const pending = this.getPendingTransactions()
// only try resubmitting if their are transactions to resubmit
@@ -100,6 +115,13 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
}))
}
+ /**
+ resubmits the individual txMeta used in resubmitPendingTxs
+ @param txMeta {Object} - txMeta object
+ @param latestBlockNumber {string} - hex string for the latest block number
+ @emits tx:retry
+ @returns txHash {string}
+ */
async _resubmitTx (txMeta, latestBlockNumber) {
if (!txMeta.firstRetryBlockNumber) {
this.emit('tx:block-update', txMeta, latestBlockNumber)
@@ -123,7 +145,13 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
this.emit('tx:retry', txMeta)
return txHash
}
-
+ /**
+ Ask the network for the transaction to see if it has been include in a block
+ @param txMeta {Object} - the txMeta object
+ @emits tx:failed
+ @emits tx:confirmed
+ @emits tx:warning
+ */
async _checkPendingTx (txMeta) {
const txHash = txMeta.hash
const txId = txMeta.id
@@ -162,8 +190,9 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
}
}
- // checks the network for signed txs and
- // if confirmed sets the tx status as 'confirmed'
+ /**
+ checks the network for signed txs and releases the nonce global lock if it is
+ */
async _checkPendingTxs () {
const signedTxList = this.getPendingTransactions()
// in order to keep the nonceTracker accurate we block it while updating pending transactions
@@ -171,12 +200,17 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
try {
await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta)))
} catch (err) {
- console.error('PendingTransactionWatcher - Error updating pending transactions')
- console.error(err)
+ log.error('PendingTransactionWatcher - Error updating pending transactions')
+ log.error(err)
}
nonceGlobalLock.releaseLock()
}
+ /**
+ checks to see if a confirmed txMeta has the same nonce
+ @param txMeta {Object} - txMeta object
+ @returns {boolean}
+ */
async _checkIfNonceIsTaken (txMeta) {
const address = txMeta.txParams.from
const completed = this.getCompletedTransactions(address)
@@ -185,5 +219,6 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
})
return sameNonce.length > 0
}
-
}
+
+module.exports = PendingTransactionTracker
diff --git a/app/scripts/lib/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js
index 829b4c421..36b5cdbc9 100644
--- a/app/scripts/lib/tx-gas-utils.js
+++ b/app/scripts/controllers/transactions/tx-gas-utils.js
@@ -3,22 +3,27 @@ const {
hexToBn,
BnMultiplyByFraction,
bnToHex,
-} = require('./util')
-const { addHexPrefix, isValidAddress } = require('ethereumjs-util')
+} = require('../../lib/util')
+const { addHexPrefix } = require('ethereumjs-util')
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
-/*
-tx-utils are utility methods for Transaction manager
+/**
+tx-gas-utils are gas utility methods for Transaction manager
its passed ethquery
and used to do things like calculate gas of a tx.
+@param {Object} provider - A network provider.
*/
-module.exports = class TxGasUtil {
+class TxGasUtil {
constructor (provider) {
this.query = new EthQuery(provider)
}
+ /**
+ @param txMeta {Object} - the txMeta object
+ @returns {object} the txMeta object with the gas written to the txParams
+ */
async analyzeGasUsage (txMeta) {
const block = await this.query.getBlockByNumber('latest', true)
let estimatedGasHex
@@ -38,6 +43,12 @@ module.exports = class TxGasUtil {
return txMeta
}
+ /**
+ Estimates the tx's gas usage
+ @param txMeta {Object} - the txMeta object
+ @param blockGasLimitHex {string} - hex string of the block's gas limit
+ @returns {string} the estimated gas limit as a hex string
+ */
async estimateTxGas (txMeta, blockGasLimitHex) {
const txParams = txMeta.txParams
@@ -70,6 +81,12 @@ module.exports = class TxGasUtil {
return await this.query.estimateGas(txParams)
}
+ /**
+ Writes the gas on the txParams in the txMeta
+ @param txMeta {Object} - the txMeta object to write to
+ @param blockGasLimitHex {string} - the block gas limit hex
+ @param estimatedGasHex {string} - the estimated gas hex
+ */
setTxGas (txMeta, blockGasLimitHex, estimatedGasHex) {
txMeta.estimatedGas = addHexPrefix(estimatedGasHex)
const txParams = txMeta.txParams
@@ -87,6 +104,13 @@ module.exports = class TxGasUtil {
return
}
+ /**
+ Adds a gas buffer with out exceeding the block gas limit
+
+ @param initialGasLimitHex {string} - the initial gas limit to add the buffer too
+ @param blockGasLimitHex {string} - the block gas limit
+ @returns {string} the buffered gas limit as a hex string
+ */
addGasBuffer (initialGasLimitHex, blockGasLimitHex) {
const initialGasLimitBn = hexToBn(initialGasLimitHex)
const blockGasLimitBn = hexToBn(blockGasLimitHex)
@@ -100,37 +124,6 @@ module.exports = class TxGasUtil {
// otherwise use blockGasLimit
return bnToHex(upperGasLimitBn)
}
+}
- async validateTxParams (txParams) {
- this.validateFrom(txParams)
- this.validateRecipient(txParams)
- if ('value' in txParams) {
- const value = txParams.value.toString()
- if (value.includes('-')) {
- throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
- }
-
- if (value.includes('.')) {
- throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
- }
- }
- }
-
- validateFrom (txParams) {
- if ( !(typeof txParams.from === 'string') ) throw new Error(`Invalid from address ${txParams.from} not a string`)
- if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
- }
-
- validateRecipient (txParams) {
- if (txParams.to === '0x' || txParams.to === null ) {
- if (txParams.data) {
- delete txParams.to
- } else {
- throw new Error('Invalid recipient address')
- }
- } else if ( txParams.to !== undefined && !isValidAddress(txParams.to) ) {
- throw new Error('Invalid recipient address')
- }
- return txParams
- }
-} \ No newline at end of file
+module.exports = TxGasUtil \ No newline at end of file
diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js
index 2ab24d6a0..380214c1d 100644
--- a/app/scripts/lib/tx-state-manager.js
+++ b/app/scripts/controllers/transactions/tx-state-manager.js
@@ -1,22 +1,33 @@
const extend = require('xtend')
const EventEmitter = require('events')
const ObservableStore = require('obs-store')
-const createId = require('./random-id')
const ethUtil = require('ethereumjs-util')
-const txStateHistoryHelper = require('./tx-state-history-helper')
-
-// STATUS METHODS
- // statuses:
- // - `'unapproved'` the user has not responded
- // - `'rejected'` the user has responded no!
- // - `'approved'` the user has approved the tx
- // - `'signed'` the tx is signed
- // - `'submitted'` the tx is sent to a server
- // - `'confirmed'` the tx has been included in a block.
- // - `'failed'` the tx failed for some reason, included on tx data.
- // - `'dropped'` the tx nonce was already used
-
-module.exports = class TransactionStateManager extends EventEmitter {
+const txStateHistoryHelper = require('./lib/tx-state-history-helper')
+const createId = require('../../lib/random-id')
+const { getFinalStates } = require('./lib/util')
+/**
+ TransactionStateManager is responsible for the state of a transaction and
+ storing the transaction
+ it also has some convenience methods for finding subsets of transactions
+ *
+ *STATUS METHODS
+ <br>statuses:
+ <br> - `'unapproved'` the user has not responded
+ <br> - `'rejected'` the user has responded no!
+ <br> - `'approved'` the user has approved the tx
+ <br> - `'signed'` the tx is signed
+ <br> - `'submitted'` the tx is sent to a server
+ <br> - `'confirmed'` the tx has been included in a block.
+ <br> - `'failed'` the tx failed for some reason, included on tx data.
+ <br> - `'dropped'` the tx nonce was already used
+ @param opts {object}
+ @param {object} [opts.initState={ transactions: [] }] initial transactions list with the key transaction {array}
+ @param {number} [opts.txHistoryLimit] limit for how many finished
+ transactions can hang around in state
+ @param {function} opts.getNetwork return network number
+ @class
+*/
+class TransactionStateManager extends EventEmitter {
constructor ({ initState, txHistoryLimit, getNetwork }) {
super()
@@ -28,6 +39,10 @@ module.exports = class TransactionStateManager extends EventEmitter {
this.getNetwork = getNetwork
}
+ /**
+ @param opts {object} - the object to use when overwriting defaults
+ @returns {txMeta} the default txMeta object
+ */
generateTxMeta (opts) {
return extend({
id: createId(),
@@ -38,17 +53,25 @@ module.exports = class TransactionStateManager extends EventEmitter {
}, opts)
}
+ /**
+ @returns {array} of txMetas that have been filtered for only the current network
+ */
getTxList () {
const network = this.getNetwork()
const fullTxList = this.getFullTxList()
return fullTxList.filter((txMeta) => txMeta.metamaskNetworkId === network)
}
+ /**
+ @returns {array} of all the txMetas in store
+ */
getFullTxList () {
return this.store.getState().transactions
}
- // Returns the tx list
+ /**
+ @returns {array} the tx list whos status is unapproved
+ */
getUnapprovedTxList () {
const txList = this.getTxsByMetaData('status', 'unapproved')
return txList.reduce((result, tx) => {
@@ -57,18 +80,37 @@ module.exports = class TransactionStateManager extends EventEmitter {
}, {})
}
+ /**
+ @param [address] {string} - hex prefixed address to sort the txMetas for [optional]
+ @returns {array} the tx list whos status is submitted if no address is provide
+ returns all txMetas who's status is submitted for the current network
+ */
getPendingTransactions (address) {
const opts = { status: 'submitted' }
if (address) opts.from = address
return this.getFilteredTxList(opts)
}
+ /**
+ @param [address] {string} - hex prefixed address to sort the txMetas for [optional]
+ @returns {array} the tx list whos status is confirmed if no address is provide
+ returns all txMetas who's status is confirmed for the current network
+ */
getConfirmedTransactions (address) {
const opts = { status: 'confirmed' }
if (address) opts.from = address
return this.getFilteredTxList(opts)
}
+ /**
+ Adds the txMeta to the list of transactions in the store.
+ if the list is over txHistoryLimit it will remove a transaction that
+ is in its final state
+ it will allso add the key `history` to the txMeta with the snap shot of the original
+ object
+ @param txMeta {Object}
+ @returns {object} the txMeta
+ */
addTx (txMeta) {
this.once(`${txMeta.id}:signed`, function (txId) {
this.removeAllListeners(`${txMeta.id}:rejected`)
@@ -92,22 +134,39 @@ module.exports = class TransactionStateManager extends EventEmitter {
// or rejected tx's.
// not tx's that are pending or unapproved
if (txCount > txHistoryLimit - 1) {
- const index = transactions.findIndex((metaTx) => metaTx.status === 'confirmed' || metaTx.status === 'rejected')
- transactions.splice(index, 1)
+ const index = transactions.findIndex((metaTx) => {
+ return getFinalStates().includes(metaTx.status)
+ })
+ if (index !== -1) {
+ transactions.splice(index, 1)
+ }
}
transactions.push(txMeta)
this._saveTxList(transactions)
return txMeta
}
- // gets tx by Id and returns it
+ /**
+ @param txId {number}
+ @returns {object} the txMeta who matches the given id if none found
+ for the network returns undefined
+ */
getTx (txId) {
const txMeta = this.getTxsByMetaData('id', txId)[0]
return txMeta
}
+ /**
+ updates the txMeta in the list and adds a history entry
+ @param txMeta {Object} - the txMeta to update
+ @param [note] {string} - a not about the update for history
+ */
updateTx (txMeta, note) {
// validate txParams
if (txMeta.txParams) {
+ if (typeof txMeta.txParams.data === 'undefined') {
+ delete txMeta.txParams.data
+ }
+
this.validateTxParams(txMeta.txParams)
}
@@ -128,16 +187,23 @@ module.exports = class TransactionStateManager extends EventEmitter {
}
- // merges txParams obj onto txData.txParams
- // use extend to ensure that all fields are filled
+ /**
+ merges txParams obj onto txMeta.txParams
+ use extend to ensure that all fields are filled
+ @param txId {number} - the id of the txMeta
+ @param txParams {object} - the updated txParams
+ */
updateTxParams (txId, txParams) {
const txMeta = this.getTx(txId)
txMeta.txParams = extend(txMeta.txParams, txParams)
this.updateTx(txMeta, `txStateManager#updateTxParams`)
}
- // validates txParams members by type
- validateTxParams(txParams) {
+ /**
+ validates txParams members by type
+ @param txParams {object} - txParams to validate
+ */
+ validateTxParams (txParams) {
Object.keys(txParams).forEach((key) => {
const value = txParams[key]
// validate types
@@ -153,17 +219,19 @@ module.exports = class TransactionStateManager extends EventEmitter {
})
}
-/*
- Takes an object of fields to search for eg:
- let thingsToLookFor = {
- to: '0x0..',
- from: '0x0..',
- status: 'signed',
- err: undefined,
- }
- and returns a list of tx with all
+/**
+ @param opts {object} - an object of fields to search for eg:<br>
+ let <code>thingsToLookFor = {<br>
+ to: '0x0..',<br>
+ from: '0x0..',<br>
+ status: 'signed',<br>
+ err: undefined,<br>
+ }<br></code>
+ @param [initialList=this.getTxList()]
+ @returns a {array} of txMeta with all
options matching
-
+ */
+ /*
****************HINT****************
| `err: undefined` is like looking |
| for a tx with no err |
@@ -184,10 +252,17 @@ module.exports = class TransactionStateManager extends EventEmitter {
})
return filteredTxList
}
+ /**
+ @param key {string} - the key to check
+ @param value - the value your looking for
+ @param [txList=this.getTxList()] {array} - the list to search. default is the txList
+ from txStateManager#getTxList
+ @returns {array} a list of txMetas who matches the search params
+ */
getTxsByMetaData (key, value, txList = this.getTxList()) {
return txList.filter((txMeta) => {
- if (txMeta.txParams[key]) {
+ if (key in txMeta.txParams) {
return txMeta.txParams[key] === value
} else {
return txMeta[key] === value
@@ -197,33 +272,51 @@ module.exports = class TransactionStateManager extends EventEmitter {
// get::set status
- // should return the status of the tx.
+ /**
+ @param txId {number} - the txMeta Id
+ @return {string} the status of the tx.
+ */
getTxStatus (txId) {
const txMeta = this.getTx(txId)
return txMeta.status
}
- // should update the status of the tx to 'rejected'.
+ /**
+ should update the status of the tx to 'rejected'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusRejected (txId) {
this._setTxStatus(txId, 'rejected')
}
- // should update the status of the tx to 'unapproved'.
+ /**
+ should update the status of the tx to 'unapproved'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusUnapproved (txId) {
this._setTxStatus(txId, 'unapproved')
}
- // should update the status of the tx to 'approved'.
+ /**
+ should update the status of the tx to 'approved'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusApproved (txId) {
this._setTxStatus(txId, 'approved')
}
- // should update the status of the tx to 'signed'.
+ /**
+ should update the status of the tx to 'signed'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusSigned (txId) {
this._setTxStatus(txId, 'signed')
}
- // should update the status of the tx to 'submitted'.
- // and add a time stamp for when it was called
+ /**
+ should update the status of the tx to 'submitted'.
+ and add a time stamp for when it was called
+ @param txId {number} - the txMeta Id
+ */
setTxStatusSubmitted (txId) {
const txMeta = this.getTx(txId)
txMeta.submittedTime = (new Date()).getTime()
@@ -231,17 +324,29 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._setTxStatus(txId, 'submitted')
}
- // should update the status of the tx to 'confirmed'.
+ /**
+ should update the status of the tx to 'confirmed'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusConfirmed (txId) {
this._setTxStatus(txId, 'confirmed')
}
- // should update the status dropped
+ /**
+ should update the status of the tx to 'dropped'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusDropped (txId) {
this._setTxStatus(txId, 'dropped')
}
+ /**
+ should update the status of the tx to 'failed'.
+ and put the error on the txMeta
+ @param txId {number} - the txMeta Id
+ @param err {erroObject} - error object
+ */
setTxStatusFailed (txId, err) {
const txMeta = this.getTx(txId)
txMeta.err = {
@@ -252,6 +357,11 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._setTxStatus(txId, 'failed')
}
+ /**
+ Removes transaction from the given address for the current network
+ from the txList
+ @param address {string} - hex string of the from address on the txParams to remove
+ */
wipeTransactions (address) {
// network only tx
const txs = this.getFullTxList()
@@ -267,9 +377,8 @@ module.exports = class TransactionStateManager extends EventEmitter {
// PRIVATE METHODS
//
- // Should find the tx in the tx list and
- // update it.
- // should set the status in txData
+ // STATUS METHODS
+ // statuses:
// - `'unapproved'` the user has not responded
// - `'rejected'` the user has responded no!
// - `'approved'` the user has approved the tx
@@ -277,6 +386,15 @@ module.exports = class TransactionStateManager extends EventEmitter {
// - `'submitted'` the tx is sent to a server
// - `'confirmed'` the tx has been included in a block.
// - `'failed'` the tx failed for some reason, included on tx data.
+ // - `'dropped'` the tx nonce was already used
+
+ /**
+ @param txId {number} - the txMeta Id
+ @param status {string} - the status to set on the txMeta
+ @emits tx:status-update - passes txId and status
+ @emits ${txMeta.id}:finished - if it is a finished state. Passes the txMeta
+ @emits update:badge
+ */
_setTxStatus (txId, status) {
const txMeta = this.getTx(txId)
txMeta.status = status
@@ -289,9 +407,14 @@ module.exports = class TransactionStateManager extends EventEmitter {
this.emit('update:badge')
}
- // Saves the new/updated txList.
+ /**
+ Saves the new/updated txList.
+ @param transactions {array} - the list of transactions to save
+ */
// Function is intended only for internal use
_saveTxList (transactions) {
this.store.updateState({ transactions })
}
}
+
+module.exports = TransactionStateManager
diff --git a/app/scripts/edge-encryptor.js b/app/scripts/edge-encryptor.js
index 24c0c93a8..dcb06873b 100644
--- a/app/scripts/edge-encryptor.js
+++ b/app/scripts/edge-encryptor.js
@@ -1,69 +1,97 @@
const asmcrypto = require('asmcrypto.js')
const Unibabel = require('browserify-unibabel')
+/**
+ * A Microsoft Edge-specific encryption class that exposes
+ * the interface expected by eth-keykeyring-controller
+ */
class EdgeEncryptor {
+ /**
+ * Encrypts an arbitrary object to ciphertext
+ *
+ * @param {string} password Used to generate a key to encrypt the data
+ * @param {Object} dataObject Data to encrypt
+ * @returns {Promise<string>} Promise resolving to an object with ciphertext
+ */
+ encrypt (password, dataObject) {
+ var salt = this._generateSalt()
+ return this._keyFromPassword(password, salt)
+ .then(function (key) {
+ var data = JSON.stringify(dataObject)
+ var dataBuffer = Unibabel.utf8ToBuffer(data)
+ var vector = global.crypto.getRandomValues(new Uint8Array(16))
+ var resultbuffer = asmcrypto.AES_GCM.encrypt(dataBuffer, key, vector)
- encrypt (password, dataObject) {
+ var buffer = new Uint8Array(resultbuffer)
+ var vectorStr = Unibabel.bufferToBase64(vector)
+ var vaultStr = Unibabel.bufferToBase64(buffer)
+ return JSON.stringify({
+ data: vaultStr,
+ iv: vectorStr,
+ salt: salt,
+ })
+ })
+ }
- var salt = this._generateSalt()
- return this._keyFromPassword(password, salt)
- .then(function (key) {
+ /**
+ * Decrypts an arbitrary object from ciphertext
+ *
+ * @param {string} password Used to generate a key to decrypt the data
+ * @param {string} text Ciphertext of an encrypted object
+ * @returns {Promise<Object>} Promise resolving to copy of decrypted object
+ */
+ decrypt (password, text) {
+ const payload = JSON.parse(text)
+ const salt = payload.salt
+ return this._keyFromPassword(password, salt)
+ .then(function (key) {
+ const encryptedData = Unibabel.base64ToBuffer(payload.data)
+ const vector = Unibabel.base64ToBuffer(payload.iv)
+ return new Promise((resolve, reject) => {
+ var result
+ try {
+ result = asmcrypto.AES_GCM.decrypt(encryptedData, key, vector)
+ } catch (err) {
+ return reject(new Error('Incorrect password'))
+ }
+ const decryptedData = new Uint8Array(result)
+ const decryptedStr = Unibabel.bufferToUtf8(decryptedData)
+ const decryptedObj = JSON.parse(decryptedStr)
+ resolve(decryptedObj)
+ })
+ })
+ }
- var data = JSON.stringify(dataObject)
- var dataBuffer = Unibabel.utf8ToBuffer(data)
- var vector = global.crypto.getRandomValues(new Uint8Array(16))
- var resultbuffer = asmcrypto.AES_GCM.encrypt(dataBuffer, key, vector)
+ /**
+ * Retrieves a cryptographic key using a password
+ *
+ * @private
+ * @param {string} password Password used to unlock a cryptographic key
+ * @param {string} salt Random base64 data
+ * @returns {Promise<Object>} Promise resolving to a derived key
+ */
+ _keyFromPassword (password, salt) {
- var buffer = new Uint8Array(resultbuffer)
- var vectorStr = Unibabel.bufferToBase64(vector)
- var vaultStr = Unibabel.bufferToBase64(buffer)
- return JSON.stringify({
- data: vaultStr,
- iv: vectorStr,
- salt: salt,
- })
- })
- }
+ var passBuffer = Unibabel.utf8ToBuffer(password)
+ var saltBuffer = Unibabel.base64ToBuffer(salt)
+ return new Promise((resolve) => {
+ var key = asmcrypto.PBKDF2_HMAC_SHA256.bytes(passBuffer, saltBuffer, 10000)
+ resolve(key)
+ })
+ }
- decrypt (password, text) {
-
- const payload = JSON.parse(text)
- const salt = payload.salt
- return this._keyFromPassword(password, salt)
- .then(function (key) {
- const encryptedData = Unibabel.base64ToBuffer(payload.data)
- const vector = Unibabel.base64ToBuffer(payload.iv)
- return new Promise((resolve, reject) => {
- var result
- try {
- result = asmcrypto.AES_GCM.decrypt(encryptedData, key, vector)
- } catch (err) {
- return reject(new Error('Incorrect password'))
- }
- const decryptedData = new Uint8Array(result)
- const decryptedStr = Unibabel.bufferToUtf8(decryptedData)
- const decryptedObj = JSON.parse(decryptedStr)
- resolve(decryptedObj)
- })
- })
- }
-
- _keyFromPassword (password, salt) {
-
- var passBuffer = Unibabel.utf8ToBuffer(password)
- var saltBuffer = Unibabel.base64ToBuffer(salt)
- return new Promise((resolve) => {
- var key = asmcrypto.PBKDF2_HMAC_SHA256.bytes(passBuffer, saltBuffer, 10000)
- resolve(key)
- })
- }
-
- _generateSalt (byteCount = 32) {
- var view = new Uint8Array(byteCount)
- global.crypto.getRandomValues(view)
- var b64encoded = btoa(String.fromCharCode.apply(null, view))
- return b64encoded
- }
+ /**
+ * Generates random base64 encoded data
+ *
+ * @private
+ * @returns {string} Randomized base64 encoded data
+ */
+ _generateSalt (byteCount = 32) {
+ var view = new Uint8Array(byteCount)
+ global.crypto.getRandomValues(view)
+ var b64encoded = btoa(String.fromCharCode.apply(null, view))
+ return b64encoded
+ }
}
module.exports = EdgeEncryptor
diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js
index 3063df627..c49d89288 100644
--- a/app/scripts/first-time-state.js
+++ b/app/scripts/first-time-state.js
@@ -1,15 +1,24 @@
// test and development environment variables
const env = process.env.METAMASK_ENV
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
+const { DEFAULT_NETWORK, MAINNET } = require('./controllers/network/enums')
-//
-// The default state of MetaMask
-//
-module.exports = {
+/**
+ * @typedef {Object} FirstTimeState
+ * @property {Object} config Initial configuration parameters
+ * @property {Object} NetworkController Network controller state
+ */
+
+/**
+ * @type {FirstTimeState}
+ */
+const initialState = {
config: {},
NetworkController: {
provider: {
- type: (METAMASK_DEBUG || env === 'test') ? 'rinkeby' : 'mainnet',
+ type: (METAMASK_DEBUG || env === 'test') ? DEFAULT_NETWORK : MAINNET,
},
},
}
+
+module.exports = initialState
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index ec99bfc35..6d16eebd4 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -3,16 +3,11 @@ cleanContextForImports()
require('web3/dist/web3.min.js')
const log = require('loglevel')
const LocalMessageDuplexStream = require('post-message-stream')
-// const PingStream = require('ping-pong-stream/ping')
-// const endOfStream = require('end-of-stream')
const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
-const METAMASK_DEBUG = process.env.METAMASK_DEBUG
-window.log = log
-log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn')
-
+log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'warn')
//
// setup plugin communication
@@ -47,20 +42,20 @@ log.debug('MetaMask - injected web3')
setupDappAutoReload(web3, inpageProvider.publicConfigStore)
// set web3 defaultAccount
-
inpageProvider.publicConfigStore.subscribe(function (state) {
web3.eth.defaultAccount = state.selectedAddress
})
-//
-// util
-//
-
// need to make sure we aren't affected by overlapping namespaces
// and that we dont affect the app with our namespace
// mostly a fix for web3's BigNumber if AMD's "define" is defined...
var __define
+/**
+ * Caches reference to global define object and deletes it to
+ * avoid conflicts with other global define objects, such as
+ * AMD's define function
+ */
function cleanContextForImports () {
__define = global.define
try {
@@ -70,6 +65,9 @@ function cleanContextForImports () {
}
}
+/**
+ * Restores global define object from cached reference
+ */
function restoreContextAfterImports () {
try {
global.define = __define
diff --git a/app/scripts/lib/ComposableObservableStore.js b/app/scripts/lib/ComposableObservableStore.js
new file mode 100644
index 000000000..d5ee708a1
--- /dev/null
+++ b/app/scripts/lib/ComposableObservableStore.js
@@ -0,0 +1,49 @@
+const ObservableStore = require('obs-store')
+
+/**
+ * An ObservableStore that can composes a flat
+ * structure of child stores based on configuration
+ */
+class ComposableObservableStore extends ObservableStore {
+ /**
+ * Create a new store
+ *
+ * @param {Object} [initState] - The initial store state
+ * @param {Object} [config] - Map of internal state keys to child stores
+ */
+ constructor (initState, config) {
+ super(initState)
+ this.updateStructure(config)
+ }
+
+ /**
+ * Composes a new internal store subscription structure
+ *
+ * @param {Object} [config] - Map of internal state keys to child stores
+ */
+ updateStructure (config) {
+ this.config = config
+ this.removeAllListeners()
+ for (const key in config) {
+ config[key].subscribe((state) => {
+ this.updateState({ [key]: state })
+ })
+ }
+ }
+
+ /**
+ * Merges all child store state into a single object rather than
+ * returning an object keyed by child store class name
+ *
+ * @returns {Object} - Object containing merged child store state
+ */
+ getFlatState () {
+ let flatState = {}
+ for (const key in this.config) {
+ flatState = { ...flatState, ...this.config[key].getState() }
+ }
+ return flatState
+ }
+}
+
+module.exports = ComposableObservableStore
diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js
index 8c3dd8c71..0f7b3d865 100644
--- a/app/scripts/lib/account-tracker.js
+++ b/app/scripts/lib/account-tracker.js
@@ -16,6 +16,24 @@ function noop () {}
class AccountTracker extends EventEmitter {
+ /**
+ * This module is responsible for tracking any number of accounts and caching their current balances & transaction
+ * counts.
+ *
+ * It also tracks transaction hashes, and checks their inclusion status on each new block.
+ *
+ * @typedef {Object} AccountTracker
+ * @param {Object} opts Initialize various properties of the class.
+ * @property {Object} store The stored object containing all accounts to track, as well as the current block's gas limit.
+ * @property {Object} store.accounts The accounts currently stored in this AccountTracker
+ * @property {string} store.currentBlockGasLimit A hex string indicating the gas limit of the current block
+ * @property {Object} _provider A provider needed to create the EthQuery instance used within this AccountTracker.
+ * @property {EthQuery} _query An EthQuery instance used to access account information from the blockchain
+ * @property {BlockTracker} _blockTracker A BlockTracker instance. Needed to ensure that accounts and their info updates
+ * when a new block is created.
+ * @property {Object} _currentBlockNumber Reference to a property on the _blockTracker: the number (i.e. an id) of the the current block
+ *
+ */
constructor (opts = {}) {
super()
@@ -34,10 +52,17 @@ class AccountTracker extends EventEmitter {
this._currentBlockNumber = this._blockTracker.currentBlock
}
- //
- // public
- //
-
+ /**
+ * Ensures that the locally stored accounts are in sync with a set of accounts stored externally to this
+ * AccountTracker.
+ *
+ * Once this AccountTracker's accounts are up to date with those referenced by the passed addresses, each
+ * of these accounts are given an updated balance via EthQuery.
+ *
+ * @param {array} address The array of hex addresses for accounts with which this AccountTracker's accounts should be
+ * in sync
+ *
+ */
syncWithAddresses (addresses) {
const accounts = this.store.getState().accounts
const locals = Object.keys(accounts)
@@ -61,6 +86,13 @@ class AccountTracker extends EventEmitter {
this._updateAccounts()
}
+ /**
+ * Adds a new address to this AccountTracker's accounts object, which points to an empty object. This object will be
+ * given a balance as long this._currentBlockNumber is defined.
+ *
+ * @param {string} address A hex address of a new account to store in this AccountTracker's accounts object
+ *
+ */
addAccount (address) {
const accounts = this.store.getState().accounts
accounts[address] = {}
@@ -69,16 +101,27 @@ class AccountTracker extends EventEmitter {
this._updateAccount(address)
}
+ /**
+ * Removes an account from this AccountTracker's accounts object
+ *
+ * @param {string} address A hex address of a the account to remove
+ *
+ */
removeAccount (address) {
const accounts = this.store.getState().accounts
delete accounts[address]
this.store.updateState({ accounts })
}
- //
- // private
- //
-
+ /**
+ * Given a block, updates this AccountTracker's currentBlockGasLimit, and then updates each local account's balance
+ * via EthQuery
+ *
+ * @private
+ * @param {object} block Data about the block that contains the data to update to.
+ * @fires 'block' The updated state, if all account updates are successful
+ *
+ */
_updateForBlock (block) {
this._currentBlockNumber = block.number
const currentBlockGasLimit = block.gasLimit
@@ -93,12 +136,26 @@ class AccountTracker extends EventEmitter {
})
}
+ /**
+ * Calls this._updateAccount for each account in this.store
+ *
+ * @param {Function} cb A callback to pass to this._updateAccount, called after each account is successfully updated
+ *
+ */
_updateAccounts (cb = noop) {
const accounts = this.store.getState().accounts
const addresses = Object.keys(accounts)
async.each(addresses, this._updateAccount.bind(this), cb)
}
+ /**
+ * Updates the current balance of an account. Gets an updated balance via this._getAccount.
+ *
+ * @private
+ * @param {string} address A hex address of a the account to be updated
+ * @param {Function} cb A callback to call once the account at address is successfully update
+ *
+ */
_updateAccount (address, cb = noop) {
this._getAccount(address, (err, result) => {
if (err) return cb(err)
@@ -113,6 +170,14 @@ class AccountTracker extends EventEmitter {
})
}
+ /**
+ * Gets the current balance of an account via EthQuery.
+ *
+ * @private
+ * @param {string} address A hex address of a the account to query
+ * @param {Function} cb A callback to call once the account at address is successfully update
+ *
+ */
_getAccount (address, cb = noop) {
const query = this._query
async.parallel({
diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js
index b9dde3c28..4e2d0bc79 100644
--- a/app/scripts/lib/buy-eth-url.js
+++ b/app/scripts/lib/buy-eth-url.js
@@ -1,5 +1,16 @@
module.exports = getBuyEthUrl
+/**
+ * Gives the caller a url at which the user can acquire eth, depending on the network they are in
+ *
+ * @param {object} opts Options required to determine the correct url
+ * @param {string} opts.network The network for which to return a url
+ * @param {string} opts.amount The amount of ETH to buy on coinbase. Only relevant if network === '1'.
+ * @param {string} opts.address The address the bought ETH should be sent to. Only relevant if network === '1'.
+ * @returns {string|undefined} The url at which the user can access ETH, while in the given network. If the passed
+ * network does not match any of the specified cases, or if no network is given, returns undefined.
+ *
+ */
function getBuyEthUrl ({ network, amount, address }) {
let url
switch (network) {
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index 34b603b96..221746467 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -1,12 +1,11 @@
const ethUtil = require('ethereumjs-util')
const normalize = require('eth-sig-util').normalize
-const MetamaskConfig = require('../config.js')
-
-
-const MAINNET_RPC = MetamaskConfig.network.mainnet
-const ROPSTEN_RPC = MetamaskConfig.network.ropsten
-const KOVAN_RPC = MetamaskConfig.network.kovan
-const RINKEBY_RPC = MetamaskConfig.network.rinkeby
+const {
+ MAINNET_RPC_URL,
+ ROPSTEN_RPC_URL,
+ KOVAN_RPC_URL,
+ RINKEBY_RPC_URL,
+} = require('../controllers/network/enums')
/* The config-manager is a convenience object
* wrapping a pojo-migrator.
@@ -154,19 +153,19 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
switch (provider.type) {
case 'mainnet':
- return MAINNET_RPC
+ return MAINNET_RPC_URL
case 'ropsten':
- return ROPSTEN_RPC
+ return ROPSTEN_RPC_URL
case 'kovan':
- return KOVAN_RPC
+ return KOVAN_RPC_URL
case 'rinkeby':
- return RINKEBY_RPC
+ return RINKEBY_RPC_URL
default:
- return provider && provider.rpcTarget ? provider.rpcTarget : RINKEBY_RPC
+ return provider && provider.rpcTarget ? provider.rpcTarget : RINKEBY_RPC_URL
}
}
diff --git a/app/scripts/lib/createLoggerMiddleware.js b/app/scripts/lib/createLoggerMiddleware.js
index 2707cbd9e..996c3477c 100644
--- a/app/scripts/lib/createLoggerMiddleware.js
+++ b/app/scripts/lib/createLoggerMiddleware.js
@@ -1,14 +1,20 @@
-// log rpc activity
+const log = require('loglevel')
+
module.exports = createLoggerMiddleware
-function createLoggerMiddleware ({ origin }) {
- return function loggerMiddleware (req, res, next, end) {
- next((cb) => {
+/**
+ * Returns a middleware that logs RPC activity
+ * @param {{ origin: string }} opts - The middleware options
+ * @returns {Function}
+ */
+function createLoggerMiddleware (opts) {
+ return function loggerMiddleware (/** @type {any} */ req, /** @type {any} */ res, /** @type {Function} */ next) {
+ next((/** @type {Function} */ cb) => {
if (res.error) {
log.error('Error in RPC response:\n', res)
}
if (req.isMetamaskInternal) return
- log.info(`RPC (${origin}):`, req, '->', res)
+ log.info(`RPC (${opts.origin}):`, req, '->', res)
cb()
})
}
diff --git a/app/scripts/lib/createOriginMiddleware.js b/app/scripts/lib/createOriginMiddleware.js
index f8bdb2dc2..98bb0e3b3 100644
--- a/app/scripts/lib/createOriginMiddleware.js
+++ b/app/scripts/lib/createOriginMiddleware.js
@@ -1,9 +1,13 @@
-// append dapp origin domain to request
module.exports = createOriginMiddleware
-function createOriginMiddleware ({ origin }) {
- return function originMiddleware (req, res, next, end) {
- req.origin = origin
+/**
+ * Returns a middleware that appends the DApp origin to request
+ * @param {{ origin: string }} opts - The middleware options
+ * @returns {Function}
+ */
+function createOriginMiddleware (opts) {
+ return function originMiddleware (/** @type {any} */ req, /** @type {any} */ _, /** @type {Function} */ next) {
+ req.origin = opts.origin
next()
}
}
diff --git a/app/scripts/lib/createProviderMiddleware.js b/app/scripts/lib/createProviderMiddleware.js
index 4e667bac2..8a939ba4e 100644
--- a/app/scripts/lib/createProviderMiddleware.js
+++ b/app/scripts/lib/createProviderMiddleware.js
@@ -1,6 +1,10 @@
module.exports = createProviderMiddleware
-// forward requests to provider
+/**
+ * Forwards an HTTP request to the current Web3 provider
+ *
+ * @param {{ provider: Object }} config Configuration containing current Web3 provider
+ */
function createProviderMiddleware ({ provider }) {
return (req, res, next, end) => {
provider.sendAsync(req, (err, _res) => {
diff --git a/app/scripts/lib/enums.js b/app/scripts/lib/enums.js
new file mode 100644
index 000000000..0a3afca47
--- /dev/null
+++ b/app/scripts/lib/enums.js
@@ -0,0 +1,9 @@
+const ENVIRONMENT_TYPE_POPUP = 'popup'
+const ENVIRONMENT_TYPE_NOTIFICATION = 'notification'
+const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen'
+
+module.exports = {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+}
diff --git a/app/scripts/lib/environment-type.js b/app/scripts/lib/environment-type.js
deleted file mode 100644
index 7966926eb..000000000
--- a/app/scripts/lib/environment-type.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = function environmentType () {
- const url = window.location.href
- if (url.match(/popup.html$/)) {
- return 'popup'
- } else if (url.match(/home.html$/)) {
- return 'responsive'
- } else {
- return 'notification'
- }
-}
diff --git a/app/scripts/lib/events-proxy.js b/app/scripts/lib/events-proxy.js
index c0a490b05..f83773ccc 100644
--- a/app/scripts/lib/events-proxy.js
+++ b/app/scripts/lib/events-proxy.js
@@ -1,26 +1,37 @@
+/**
+ * Returns an EventEmitter that proxies events from the given event emitter
+ * @param {any} eventEmitter
+ * @param {object} listeners - The listeners to proxy to
+ * @returns {any}
+ */
module.exports = function createEventEmitterProxy (eventEmitter, listeners) {
let target = eventEmitter
const eventHandlers = listeners || {}
- const proxy = new Proxy({}, {
- get: (obj, name) => {
+ const proxy = /** @type {any} */ (new Proxy({}, {
+ get: (_, name) => {
// intercept listeners
if (name === 'on') return addListener
if (name === 'setTarget') return setTarget
if (name === 'proxyEventHandlers') return eventHandlers
- return target[name]
+ return (/** @type {any} */ (target))[name]
},
- set: (obj, name, value) => {
+ set: (_, name, value) => {
target[name] = value
return true
},
- })
- function setTarget (eventEmitter) {
+ }))
+ function setTarget (/** @type {EventEmitter} */ eventEmitter) {
target = eventEmitter
// migrate listeners
Object.keys(eventHandlers).forEach((name) => {
- eventHandlers[name].forEach((handler) => target.on(name, handler))
+ /** @type {Array<Function>} */ (eventHandlers[name]).forEach((handler) => target.on(name, handler))
})
}
+ /**
+ * Attaches a function to be called whenever the specified event is emitted
+ * @param {string} name
+ * @param {Function} handler
+ */
function addListener (name, handler) {
if (!eventHandlers[name]) eventHandlers[name] = []
eventHandlers[name].push(handler)
diff --git a/app/scripts/lib/extractEthjsErrorMessage.js b/app/scripts/lib/extractEthjsErrorMessage.js
index bac541735..0f100756f 100644
--- a/app/scripts/lib/extractEthjsErrorMessage.js
+++ b/app/scripts/lib/extractEthjsErrorMessage.js
@@ -4,17 +4,18 @@ const errorLabelPrefix = 'Error: '
module.exports = extractEthjsErrorMessage
-//
-// ethjs-rpc provides overly verbose error messages
-// if we detect this type of message, we extract the important part
-// Below is an example input and output
-//
-// Error: [ethjs-rpc] rpc error with payload {"id":3947817945380,"jsonrpc":"2.0","params":["0xf8eb8208708477359400830398539406012c8cf97bead5deae237070f9587f8e7a266d80b8843d7d3f5a0000000000000000000000000000000000000000000000000000000000081d1a000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000003f48025a04c32a9b630e0d9e7ff361562d850c86b7a884908135956a7e4a336fa0300d19ca06830776423f25218e8d19b267161db526e66895567147015b1f3fc47aef9a3c7"],"method":"eth_sendRawTransaction"} Error: replacement transaction underpriced
-//
-// Transaction Failed: replacement transaction underpriced
-//
-
-
+/**
+ * Extracts the important part of an ethjs-rpc error message. If the passed error is not an isEthjsRpcError, the error
+ * is returned unchanged.
+ *
+ * @param {string} errorMessage The error message to parse
+ * @returns {string} Returns an error message, either the same as was passed, or the ending message portion of an isEthjsRpcError
+ *
+ * @example
+ * // returns 'Transaction Failed: replacement transaction underpriced'
+ * extractEthjsErrorMessage(`Error: [ethjs-rpc] rpc error with payload {"id":3947817945380,"jsonrpc":"2.0","params":["0xf8eb8208708477359400830398539406012c8cf97bead5deae237070f9587f8e7a266d80b8843d7d3f5a0000000000000000000000000000000000000000000000000000000000081d1a000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000003f48025a04c32a9b630e0d9e7ff361562d850c86b7a884908135956a7e4a336fa0300d19ca06830776423f25218e8d19b267161db526e66895567147015b1f3fc47aef9a3c7"],"method":"eth_sendRawTransaction"} Error: replacement transaction underpriced`)
+ *
+*/
function extractEthjsErrorMessage(errorMessage) {
const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug)
if (isEthjsRpcError) {
diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js
index 28612f763..5473fccf0 100644
--- a/app/scripts/lib/get-first-preferred-lang-code.js
+++ b/app/scripts/lib/get-first-preferred-lang-code.js
@@ -2,14 +2,23 @@ const extension = require('extensionizer')
const promisify = require('pify')
const allLocales = require('../../_locales/index.json')
-const existingLocaleCodes = allLocales.map(locale => locale.code)
+const existingLocaleCodes = allLocales.map(locale => locale.code.toLowerCase().replace('_', '-'))
+/**
+ * Returns a preferred language code, based on settings within the user's browser. If we have no translations for the
+ * users preferred locales, 'en' is returned.
+ *
+ * @returns {Promise<string>} Promises a locale code, either one from the user's preferred list that we have a translation for, or 'en'
+ *
+ */
async function getFirstPreferredLangCode () {
const userPreferredLocaleCodes = await promisify(
extension.i18n.getAcceptLanguages,
{ errorFirst: false }
)()
- const firstPreferredLangCode = userPreferredLocaleCodes.find(code => existingLocaleCodes.includes(code))
+ const firstPreferredLangCode = userPreferredLocaleCodes
+ .map(code => code.toLowerCase())
+ .find(code => existingLocaleCodes.includes(code))
return firstPreferredLangCode || 'en'
}
diff --git a/app/scripts/lib/getObjStructure.js b/app/scripts/lib/getObjStructure.js
new file mode 100644
index 000000000..52250d3fb
--- /dev/null
+++ b/app/scripts/lib/getObjStructure.js
@@ -0,0 +1,50 @@
+const clone = require('clone')
+
+module.exports = getObjStructure
+
+// This will create an object that represents the structure of the given object
+// it replaces all values with the result of their type
+
+// {
+// "data": {
+// "CurrencyController": {
+// "conversionDate": "number",
+// "conversionRate": "number",
+// "currentCurrency": "string"
+// }
+// }
+
+/**
+ * Creates an object that represents the structure of the given object. It replaces all values with the result of their
+ * type.
+ *
+ * @param {object} obj The object for which a 'structure' will be returned. Usually a plain object and not a class.
+ * @returns {object} The "mapped" version of a deep clone of the passed object, with each non-object property value
+ * replaced with the javascript type of that value.
+ *
+ */
+function getObjStructure(obj) {
+ const structure = clone(obj)
+ return deepMap(structure, (value) => {
+ return value === null ? 'null' : typeof value
+ })
+}
+
+/**
+ * Modifies all the properties and deeply nested of a passed object. Iterates recursively over all nested objects and
+ * their properties, and covers the entire depth of the object. At each property value which is not an object is modified.
+ *
+ * @param {object} target The object to modify
+ * @param {Function} visit The modifier to apply to each non-object property value
+ * @returns {object} The modified object
+ */
+function deepMap(target = {}, visit) {
+ Object.entries(target).forEach(([key, value]) => {
+ if (typeof value === 'object' && value !== null) {
+ target[key] = deepMap(value, visit)
+ } else {
+ target[key] = visit(value)
+ }
+ })
+ return target
+}
diff --git a/app/scripts/lib/hex-to-bn.js b/app/scripts/lib/hex-to-bn.js
index 184217279..b28746920 100644
--- a/app/scripts/lib/hex-to-bn.js
+++ b/app/scripts/lib/hex-to-bn.js
@@ -1,6 +1,11 @@
-const ethUtil = require('ethereumjs-util')
+const ethUtil = (/** @type {object} */ (require('ethereumjs-util')))
const BN = ethUtil.BN
+/**
+ * Returns a [BinaryNumber]{@link BN} representation of the given hex value
+ * @param {string} hex
+ * @return {any}
+ */
module.exports = function hexToBn (hex) {
return new BN(ethUtil.stripHexPrefix(hex), 16)
}
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
deleted file mode 100644
index e2999411f..000000000
--- a/app/scripts/lib/is-popup-or-notification.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = function isPopupOrNotification () {
- const url = window.location.href
- // if (url.match(/popup.html$/) || url.match(/home.html$/)) {
- // Below regexes needed for feature toggles (e.g. see line ~340 in ui/app/app.js)
- // Revert below regexes to above commented out regexes before merge to master
- if (url.match(/popup.html(?:\?.+)*$/) || url.match(/home.html(?:\?.+)*$/)) {
- return 'popup'
- } else {
- return 'notification'
- }
-}
diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js
index 5b47985f6..139ff86bd 100644
--- a/app/scripts/lib/local-store.js
+++ b/app/scripts/lib/local-store.js
@@ -1,10 +1,13 @@
-// We should not rely on local storage in an extension!
-// We should use this instead!
-// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local
-
const extension = require('extensionizer')
+const log = require('loglevel')
+/**
+ * A wrapper around the extension's storage local API
+ */
module.exports = class ExtensionStore {
+ /**
+ * @constructor
+ */
constructor() {
this.isSupported = !!(extension.storage.local)
if (!this.isSupported) {
@@ -12,6 +15,10 @@ module.exports = class ExtensionStore {
}
}
+ /**
+ * Returns all of the keys currently saved
+ * @return {Promise<*>}
+ */
async get() {
if (!this.isSupported) return undefined
const result = await this._get()
@@ -24,14 +31,24 @@ module.exports = class ExtensionStore {
}
}
+ /**
+ * Sets the key in local state
+ * @param {object} state - The state to set
+ * @return {Promise<void>}
+ */
async set(state) {
return this._set(state)
}
+ /**
+ * Returns all of the keys currently saved
+ * @private
+ * @return {object} the key-value map from local storage
+ */
_get() {
const local = extension.storage.local
return new Promise((resolve, reject) => {
- local.get(null, (result) => {
+ local.get(null, (/** @type {any} */ result) => {
const err = extension.runtime.lastError
if (err) {
reject(err)
@@ -42,6 +59,12 @@ module.exports = class ExtensionStore {
})
}
+ /**
+ * Sets the key in local state
+ * @param {object} obj - The key to set
+ * @return {Promise<void>}
+ * @private
+ */
_set(obj) {
const local = extension.storage.local
return new Promise((resolve, reject) => {
@@ -57,6 +80,11 @@ module.exports = class ExtensionStore {
}
}
+/**
+ * Returns whether or not the given object contains no keys
+ * @param {object} obj - The object to check
+ * @returns {boolean}
+ */
function isEmpty(obj) {
return Object.keys(obj).length === 0
}
diff --git a/app/scripts/lib/message-manager.js b/app/scripts/lib/message-manager.js
index f52e048e0..901367f04 100644
--- a/app/scripts/lib/message-manager.js
+++ b/app/scripts/lib/message-manager.js
@@ -3,8 +3,37 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const createId = require('./random-id')
+/**
+ * Represents, and contains data about, an 'eth_sign' type signature request. These are created when a signature for
+ * an eth_sign call is requested.
+ *
+ * @see {@link https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign}
+ *
+ * @typedef {Object} Message
+ * @property {number} id An id to track and identify the message object
+ * @property {Object} msgParams The parameters to pass to the eth_sign method once the signature request is approved.
+ * @property {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @property {string} msgParams.data A hex string conversion of the raw buffer data of the signature request
+ * @property {number} time The epoch time at which the this message was created
+ * @property {string} status Indicates whether the signature request is 'unapproved', 'approved', 'signed' or 'rejected'
+ * @property {string} type The json-prc signing method for which a signature request has been made. A 'Message' with
+ * always have a 'eth_sign' type.
+ *
+ */
module.exports = class MessageManager extends EventEmitter {
+
+ /**
+ * Controller in charge of managing - storing, adding, removing, updating - Messages.
+ *
+ * @typedef {Object} MessageManager
+ * @param {Object} opts @deprecated
+ * @property {Object} memStore The observable store where Messages are saved.
+ * @property {Object} memStore.unapprovedMsgs A collection of all Messages in the 'unapproved' state
+ * @property {number} memStore.unapprovedMsgCount The count of all Messages in this.memStore.unapprobedMsgs
+ * @property {array} messages Holds all messages that have been created by this MessageManager
+ *
+ */
constructor (opts) {
super()
this.memStore = new ObservableStore({
@@ -14,15 +43,35 @@ module.exports = class MessageManager extends EventEmitter {
this.messages = []
}
+ /**
+ * A getter for the number of 'unapproved' Messages in this.messages
+ *
+ * @returns {number} The number of 'unapproved' Messages in this.messages
+ *
+ */
get unapprovedMsgCount () {
return Object.keys(this.getUnapprovedMsgs()).length
}
+ /**
+ * A getter for the 'unapproved' Messages in this.messages
+ *
+ * @returns {Object} An index of Message ids to Messages, for all 'unapproved' Messages in this.messages
+ *
+ */
getUnapprovedMsgs () {
return this.messages.filter(msg => msg.status === 'unapproved')
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
}
+ /**
+ * Creates a new Message with an 'unapproved' status using the passed msgParams. this.addMsg is called to add the
+ * new Message to this.messages, and to save the unapproved Messages from that list to this.memStore.
+ *
+ * @param {Object} msgParams The params for the eth_sign call to be made after the message is approved.
+ * @returns {number} The id of the newly created message.
+ *
+ */
addUnapprovedMessage (msgParams) {
msgParams.data = normalizeMsgData(msgParams.data)
// create txData obj with parameters and meta data
@@ -42,24 +91,61 @@ module.exports = class MessageManager extends EventEmitter {
return msgId
}
+ /**
+ * Adds a passed Message to this.messages, and calls this._saveMsgList() to save the unapproved Messages from that
+ * list to this.memStore.
+ *
+ * @param {Message} msg The Message to add to this.messages
+ *
+ */
addMsg (msg) {
this.messages.push(msg)
this._saveMsgList()
}
+ /**
+ * Returns a specified Message.
+ *
+ * @param {number} msgId The id of the Message to get
+ * @returns {Message|undefined} The Message with the id that matches the passed msgId, or undefined if no Message has that id.
+ *
+ */
getMsg (msgId) {
return this.messages.find(msg => msg.id === msgId)
}
+ /**
+ * Approves a Message. Sets the message status via a call to this.setMsgStatusApproved, and returns a promise with
+ * any the message params modified for proper signing.
+ *
+ * @param {Object} msgParams The msgParams to be used when eth_sign is called, plus data added by MetaMask.
+ * @param {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @returns {Promise<object>} Promises the msgParams object with metamaskId removed.
+ *
+ */
approveMessage (msgParams) {
this.setMsgStatusApproved(msgParams.metamaskId)
return this.prepMsgForSigning(msgParams)
}
+ /**
+ * Sets a Message status to 'approved' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the Message to approve.
+ *
+ */
setMsgStatusApproved (msgId) {
this._setMsgStatus(msgId, 'approved')
}
+ /**
+ * Sets a Message status to 'signed' via a call to this._setMsgStatus and updates that Message in this.messages by
+ * adding the raw signature data of the signature request to the Message
+ *
+ * @param {number} msgId The id of the Message to sign.
+ * @param {buffer} rawSig The raw data of the signature request
+ *
+ */
setMsgStatusSigned (msgId, rawSig) {
const msg = this.getMsg(msgId)
msg.rawSig = rawSig
@@ -67,19 +153,40 @@ module.exports = class MessageManager extends EventEmitter {
this._setMsgStatus(msgId, 'signed')
}
+ /**
+ * Removes the metamaskId property from passed msgParams and returns a promise which resolves the updated msgParams
+ *
+ * @param {Object} msgParams The msgParams to modify
+ * @returns {Promise<object>} Promises the msgParams with the metamaskId property removed
+ *
+ */
prepMsgForSigning (msgParams) {
delete msgParams.metamaskId
return Promise.resolve(msgParams)
}
+ /**
+ * Sets a Message status to 'rejected' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the Message to reject.
+ *
+ */
rejectMsg (msgId) {
this._setMsgStatus(msgId, 'rejected')
}
- //
- // PRIVATE METHODS
- //
-
+ /**
+ * Updates the status of a Message in this.messages via a call to this._updateMsg
+ *
+ * @private
+ * @param {number} msgId The id of the Message to update.
+ * @param {string} status The new status of the Message.
+ * @throws A 'MessageManager - Message not found for id: "${msgId}".' if there is no Message in this.messages with an
+ * id equal to the passed msgId
+ * @fires An event with a name equal to `${msgId}:${status}`. The Message is also fired.
+ * @fires If status is 'rejected' or 'signed', an event with a name equal to `${msgId}:finished` is fired along with the message
+ *
+ */
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) throw new Error('MessageManager - Message not found for id: "${msgId}".')
@@ -91,6 +198,14 @@ module.exports = class MessageManager extends EventEmitter {
}
}
+ /**
+ * Sets a Message in this.messages to the passed Message if the ids are equal. Then saves the unapprovedMsg list to
+ * storage via this._saveMsgList
+ *
+ * @private
+ * @param {msg} Message A Message that will replace an existing Message (with the same id) in this.messages
+ *
+ */
_updateMsg (msg) {
const index = this.messages.findIndex((message) => message.id === msg.id)
if (index !== -1) {
@@ -99,6 +214,13 @@ module.exports = class MessageManager extends EventEmitter {
this._saveMsgList()
}
+ /**
+ * Saves the unapproved messages, and their count, to this.memStore
+ *
+ * @private
+ * @fires 'updateBadge'
+ *
+ */
_saveMsgList () {
const unapprovedMsgs = this.getUnapprovedMsgs()
const unapprovedMsgCount = Object.keys(unapprovedMsgs).length
@@ -108,6 +230,13 @@ module.exports = class MessageManager extends EventEmitter {
}
+/**
+ * A helper function that converts raw buffer data to a hex, or just returns the data if it is already formatted as a hex.
+ *
+ * @param {any} data The buffer data to convert to a hex
+ * @returns {string} A hex string conversion of the buffer data
+ *
+ */
function normalizeMsgData (data) {
if (data.slice(0, 2) === '0x') {
// data is already hex
diff --git a/app/scripts/lib/migrator/index.js b/app/scripts/lib/migrator/index.js
index 4fd2cae92..345ca8001 100644
--- a/app/scripts/lib/migrator/index.js
+++ b/app/scripts/lib/migrator/index.js
@@ -1,6 +1,25 @@
-class Migrator {
+const EventEmitter = require('events')
+/**
+ * @typedef {object} Migration
+ * @property {number} version - The migration version
+ * @property {Function} migrate - Returns a promise of the migrated data
+ */
+
+/**
+ * @typedef {object} MigratorOptions
+ * @property {Array<Migration>} [migrations] - The list of migrations to apply
+ * @property {number} [defaultVersion] - The version to use in the initial state
+ */
+
+class Migrator extends EventEmitter {
+
+ /**
+ * @constructor
+ * @param {MigratorOptions} opts
+ */
constructor (opts = {}) {
+ super()
const migrations = opts.migrations || []
// sort migrations by version
this.migrations = migrations.sort((a, b) => a.version - b.version)
@@ -12,30 +31,57 @@ class Migrator {
// run all pending migrations on meta in place
async migrateData (versionedData = this.generateInitialState()) {
+ // get all migrations that have not yet been run
const pendingMigrations = this.migrations.filter(migrationIsPending)
+ // perform each migration
for (const index in pendingMigrations) {
const migration = pendingMigrations[index]
- versionedData = await migration.migrate(versionedData)
- if (!versionedData.data) throw new Error('Migrator - migration returned empty data')
- if (versionedData.version !== undefined && versionedData.meta.version !== migration.version) throw new Error('Migrator - Migration did not update version number correctly')
+ try {
+ // attempt migration and validate
+ const migratedData = await migration.migrate(versionedData)
+ if (!migratedData.data) throw new Error('Migrator - migration returned empty data')
+ if (migratedData.version !== undefined && migratedData.meta.version !== migration.version) throw new Error('Migrator - Migration did not update version number correctly')
+ // accept the migration as good
+ versionedData = migratedData
+ } catch (err) {
+ // rewrite error message to add context without clobbering stack
+ const originalErrorMessage = err.message
+ err.message = `MetaMask Migration Error #${migration.version}: ${originalErrorMessage}`
+ console.warn(err.stack)
+ // emit error instead of throw so as to not break the run (gracefully fail)
+ this.emit('error', err)
+ // stop migrating and use state as is
+ return versionedData
+ }
}
return versionedData
- // migration is "pending" if it has a higher
- // version number than currentVersion
+ /**
+ * Returns whether or not the migration is pending
+ *
+ * A migration is considered "pending" if it has a higher
+ * version number than the current version.
+ * @param {Migration} migration
+ * @returns {boolean}
+ */
function migrationIsPending (migration) {
return migration.version > versionedData.meta.version
}
}
- generateInitialState (initState) {
+ /**
+ * Returns the initial state for the migrator
+ * @param {object} [data] - The data for the initial state
+ * @returns {{meta: {version: number}, data: any}}
+ */
+ generateInitialState (data) {
return {
meta: {
version: this.defaultVersion,
},
- data: initState,
+ data,
}
}
diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js
index 9b595d93c..25be6537b 100644
--- a/app/scripts/lib/nodeify.js
+++ b/app/scripts/lib/nodeify.js
@@ -1,6 +1,14 @@
const promiseToCallback = require('promise-to-callback')
const noop = function () {}
+/**
+ * A generator that returns a function which, when passed a promise, can treat that promise as a node style callback.
+ * The prime advantage being that callbacks are better for error handling.
+ *
+ * @param {Function} fn The function to handle as a callback
+ * @param {Object} context The context in which the fn is to be called, most often a this reference
+ *
+ */
module.exports = function nodeify (fn, context) {
return function () {
const args = [].slice.call(arguments)
diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js
index 1fcb7cf69..5dfb42078 100644
--- a/app/scripts/lib/notification-manager.js
+++ b/app/scripts/lib/notification-manager.js
@@ -5,10 +5,18 @@ const width = 360
class NotificationManager {
- //
- // Public
- //
+ /**
+ * A collection of methods for controlling the showing and hiding of the notification popup.
+ *
+ * @typedef {Object} NotificationManager
+ *
+ */
+ /**
+ * Either brings an existing MetaMask notification window into focus, or creates a new notification window. New
+ * notification windows are given a 'popup' type.
+ *
+ */
showPopup () {
this._getPopup((err, popup) => {
if (err) throw err
@@ -29,6 +37,10 @@ class NotificationManager {
})
}
+ /**
+ * Closes a MetaMask notification if it window exists.
+ *
+ */
closePopup () {
// closes notification popup
this._getPopup((err, popup) => {
@@ -38,10 +50,14 @@ class NotificationManager {
})
}
- //
- // Private
- //
-
+ /**
+ * Checks all open MetaMask windows, and returns the first one it finds that is a notification window (i.e. has the
+ * type 'popup')
+ *
+ * @private
+ * @param {Function} cb A node style callback that to whcih the found notification window will be passed.
+ *
+ */
_getPopup (cb) {
this._getWindows((err, windows) => {
if (err) throw err
@@ -49,6 +65,13 @@ class NotificationManager {
})
}
+ /**
+ * Returns all open MetaMask windows.
+ *
+ * @private
+ * @param {Function} cb A node style callback that to which the windows will be passed.
+ *
+ */
_getWindows (cb) {
// Ignore in test environment
if (!extension.windows) {
@@ -60,6 +83,13 @@ class NotificationManager {
})
}
+ /**
+ * Given an array of windows, returns the first that has a 'popup' type, or null if no such window exists.
+ *
+ * @private
+ * @param {array} windows An array of objects containing data about the open MetaMask extension windows.
+ *
+ */
_getPopupIn (windows) {
return windows ? windows.find((win) => {
// Returns notification popup
diff --git a/app/scripts/lib/pending-balance-calculator.js b/app/scripts/lib/pending-balance-calculator.js
index 6ae526463..0f1dc19a9 100644
--- a/app/scripts/lib/pending-balance-calculator.js
+++ b/app/scripts/lib/pending-balance-calculator.js
@@ -3,16 +3,28 @@ const normalize = require('eth-sig-util').normalize
class PendingBalanceCalculator {
- // Must be initialized with two functions:
- // getBalance => Returns a promise of a BN of the current balance in Wei
- // getPendingTransactions => Returns an array of TxMeta Objects,
- // which have txParams properties, which include value, gasPrice, and gas,
- // all in a base=16 hex format.
+ /**
+ * Used for calculating a users "pending balance": their current balance minus the total possible cost of all their
+ * pending transactions.
+ *
+ * @typedef {Object} PendingBalanceCalculator
+ * @param {Function} getBalance Returns a promise of a BN of the current balance in Wei
+ * @param {Function} getPendingTransactions Returns an array of TxMeta Objects, which have txParams properties,
+ * which include value, gasPrice, and gas, all in a base=16 hex format.
+ *
+ */
constructor ({ getBalance, getPendingTransactions }) {
this.getPendingTransactions = getPendingTransactions
this.getNetworkBalance = getBalance
}
+ /**
+ * Returns the users "pending balance": their current balance minus the total possible cost of all their
+ * pending transactions.
+ *
+ * @returns {Promise<string>} Promises a base 16 hex string that contains the user's "pending balance"
+ *
+ */
async getBalance () {
const results = await Promise.all([
this.getNetworkBalance(),
@@ -29,6 +41,15 @@ class PendingBalanceCalculator {
return `0x${balance.sub(pendingValue).toString(16)}`
}
+ /**
+ * Calculates the maximum possible cost of a single transaction, based on the value, gas price and gas limit.
+ *
+ * @param {object} tx Contains all that data about a transaction.
+ * @property {object} tx.txParams Contains data needed to calculate the maximum cost of the transaction: gas,
+ * gasLimit and value.
+ *
+ * @returns {string} Returns a base 16 hex string that contains the maximum possible cost of the transaction.
+ */
calculateMaxCost (tx) {
const txValue = tx.txParams.value
const value = this.hexToBn(txValue)
@@ -42,6 +63,13 @@ class PendingBalanceCalculator {
return value.add(gasCost)
}
+ /**
+ * Converts a hex string to a BN object
+ *
+ * @param {string} hex A number represented as a hex string
+ * @returns {Object} A BN object
+ *
+ */
hexToBn (hex) {
return new BN(normalize(hex).substring(2), 16)
}
diff --git a/app/scripts/lib/personal-message-manager.js b/app/scripts/lib/personal-message-manager.js
index 6602f5aa8..e96ced1f2 100644
--- a/app/scripts/lib/personal-message-manager.js
+++ b/app/scripts/lib/personal-message-manager.js
@@ -3,9 +3,39 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const createId = require('./random-id')
const hexRe = /^[0-9A-Fa-f]+$/g
+const log = require('loglevel')
+/**
+ * Represents, and contains data about, an 'personal_sign' type signature request. These are created when a
+ * signature for an personal_sign call is requested.
+ *
+ * @see {@link https://web3js.readthedocs.io/en/1.0/web3-eth-personal.html#sign}
+ *
+ * @typedef {Object} PersonalMessage
+ * @property {number} id An id to track and identify the message object
+ * @property {Object} msgParams The parameters to pass to the personal_sign method once the signature request is
+ * approved.
+ * @property {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @property {string} msgParams.data A hex string conversion of the raw buffer data of the signature request
+ * @property {number} time The epoch time at which the this message was created
+ * @property {string} status Indicates whether the signature request is 'unapproved', 'approved', 'signed' or 'rejected'
+ * @property {string} type The json-prc signing method for which a signature request has been made. A 'Message' will
+ * always have a 'personal_sign' type.
+ *
+ */
module.exports = class PersonalMessageManager extends EventEmitter {
+ /**
+ * Controller in charge of managing - storing, adding, removing, updating - PersonalMessage.
+ *
+ * @typedef {Object} PersonalMessageManager
+ * @param {Object} opts @deprecated
+ * @property {Object} memStore The observable store where PersonalMessage are saved with persistance.
+ * @property {Object} memStore.unapprovedPersonalMsgs A collection of all PersonalMessages in the 'unapproved' state
+ * @property {number} memStore.unapprovedPersonalMsgCount The count of all PersonalMessages in this.memStore.unapprobedMsgs
+ * @property {array} messages Holds all messages that have been created by this PersonalMessageManager
+ *
+ */
constructor (opts) {
super()
this.memStore = new ObservableStore({
@@ -15,15 +45,37 @@ module.exports = class PersonalMessageManager extends EventEmitter {
this.messages = []
}
+ /**
+ * A getter for the number of 'unapproved' PersonalMessages in this.messages
+ *
+ * @returns {number} The number of 'unapproved' PersonalMessages in this.messages
+ *
+ */
get unapprovedPersonalMsgCount () {
return Object.keys(this.getUnapprovedMsgs()).length
}
+ /**
+ * A getter for the 'unapproved' PersonalMessages in this.messages
+ *
+ * @returns {Object} An index of PersonalMessage ids to PersonalMessages, for all 'unapproved' PersonalMessages in
+ * this.messages
+ *
+ */
getUnapprovedMsgs () {
return this.messages.filter(msg => msg.status === 'unapproved')
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
}
+ /**
+ * Creates a new PersonalMessage with an 'unapproved' status using the passed msgParams. this.addMsg is called to add
+ * the new PersonalMessage to this.messages, and to save the unapproved PersonalMessages from that list to
+ * this.memStore.
+ *
+ * @param {Object} msgParams The params for the eth_sign call to be made after the message is approved.
+ * @returns {number} The id of the newly created PersonalMessage.
+ *
+ */
addUnapprovedMessage (msgParams) {
log.debug(`PersonalMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`)
msgParams.data = this.normalizeMsgData(msgParams.data)
@@ -44,24 +96,62 @@ module.exports = class PersonalMessageManager extends EventEmitter {
return msgId
}
+ /**
+ * Adds a passed PersonalMessage to this.messages, and calls this._saveMsgList() to save the unapproved PersonalMessages from that
+ * list to this.memStore.
+ *
+ * @param {Message} msg The PersonalMessage to add to this.messages
+ *
+ */
addMsg (msg) {
this.messages.push(msg)
this._saveMsgList()
}
+ /**
+ * Returns a specified PersonalMessage.
+ *
+ * @param {number} msgId The id of the PersonalMessage to get
+ * @returns {PersonalMessage|undefined} The PersonalMessage with the id that matches the passed msgId, or undefined
+ * if no PersonalMessage has that id.
+ *
+ */
getMsg (msgId) {
return this.messages.find(msg => msg.id === msgId)
}
+ /**
+ * Approves a PersonalMessage. Sets the message status via a call to this.setMsgStatusApproved, and returns a promise
+ * with any the message params modified for proper signing.
+ *
+ * @param {Object} msgParams The msgParams to be used when eth_sign is called, plus data added by MetaMask.
+ * @param {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @returns {Promise<object>} Promises the msgParams object with metamaskId removed.
+ *
+ */
approveMessage (msgParams) {
this.setMsgStatusApproved(msgParams.metamaskId)
return this.prepMsgForSigning(msgParams)
}
+ /**
+ * Sets a PersonalMessage status to 'approved' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the PersonalMessage to approve.
+ *
+ */
setMsgStatusApproved (msgId) {
this._setMsgStatus(msgId, 'approved')
}
+ /**
+ * Sets a PersonalMessage status to 'signed' via a call to this._setMsgStatus and updates that PersonalMessage in
+ * this.messages by adding the raw signature data of the signature request to the PersonalMessage
+ *
+ * @param {number} msgId The id of the PersonalMessage to sign.
+ * @param {buffer} rawSig The raw data of the signature request
+ *
+ */
setMsgStatusSigned (msgId, rawSig) {
const msg = this.getMsg(msgId)
msg.rawSig = rawSig
@@ -69,19 +159,41 @@ module.exports = class PersonalMessageManager extends EventEmitter {
this._setMsgStatus(msgId, 'signed')
}
+ /**
+ * Removes the metamaskId property from passed msgParams and returns a promise which resolves the updated msgParams
+ *
+ * @param {Object} msgParams The msgParams to modify
+ * @returns {Promise<object>} Promises the msgParams with the metamaskId property removed
+ *
+ */
prepMsgForSigning (msgParams) {
delete msgParams.metamaskId
return Promise.resolve(msgParams)
}
+ /**
+ * Sets a PersonalMessage status to 'rejected' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the PersonalMessage to reject.
+ *
+ */
rejectMsg (msgId) {
this._setMsgStatus(msgId, 'rejected')
}
- //
- // PRIVATE METHODS
- //
-
+ /**
+ * Updates the status of a PersonalMessage in this.messages via a call to this._updateMsg
+ *
+ * @private
+ * @param {number} msgId The id of the PersonalMessage to update.
+ * @param {string} status The new status of the PersonalMessage.
+ * @throws A 'PersonalMessageManager - PersonalMessage not found for id: "${msgId}".' if there is no PersonalMessage
+ * in this.messages with an id equal to the passed msgId
+ * @fires An event with a name equal to `${msgId}:${status}`. The PersonalMessage is also fired.
+ * @fires If status is 'rejected' or 'signed', an event with a name equal to `${msgId}:finished` is fired along
+ * with the PersonalMessage
+ *
+ */
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) throw new Error('PersonalMessageManager - Message not found for id: "${msgId}".')
@@ -93,6 +205,15 @@ module.exports = class PersonalMessageManager extends EventEmitter {
}
}
+ /**
+ * Sets a PersonalMessage in this.messages to the passed PersonalMessage if the ids are equal. Then saves the
+ * unapprovedPersonalMsgs index to storage via this._saveMsgList
+ *
+ * @private
+ * @param {msg} PersonalMessage A PersonalMessage that will replace an existing PersonalMessage (with the same
+ * id) in this.messages
+ *
+ */
_updateMsg (msg) {
const index = this.messages.findIndex((message) => message.id === msg.id)
if (index !== -1) {
@@ -101,6 +222,13 @@ module.exports = class PersonalMessageManager extends EventEmitter {
this._saveMsgList()
}
+ /**
+ * Saves the unapproved PersonalMessages, and their count, to this.memStore
+ *
+ * @private
+ * @fires 'updateBadge'
+ *
+ */
_saveMsgList () {
const unapprovedPersonalMsgs = this.getUnapprovedMsgs()
const unapprovedPersonalMsgCount = Object.keys(unapprovedPersonalMsgs).length
@@ -108,6 +236,13 @@ module.exports = class PersonalMessageManager extends EventEmitter {
this.emit('updateBadge')
}
+ /**
+ * A helper function that converts raw buffer data to a hex, or just returns the data if it is already formatted as a hex.
+ *
+ * @param {any} data The buffer data to convert to a hex
+ * @returns {string} A hex string conversion of the buffer data
+ *
+ */
normalizeMsgData (data) {
try {
const stripped = ethUtil.stripHexPrefix(data)
diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js
index a9716fb00..5c4224fd9 100644
--- a/app/scripts/lib/port-stream.js
+++ b/app/scripts/lib/port-stream.js
@@ -6,6 +6,13 @@ module.exports = PortDuplexStream
inherits(PortDuplexStream, Duplex)
+/**
+ * Creates a stream that's both readable and writable.
+ * The stream supports arbitrary objects.
+ *
+ * @class
+ * @param {Object} port Remote Port object
+ */
function PortDuplexStream (port) {
Duplex.call(this, {
objectMode: true,
@@ -15,8 +22,13 @@ function PortDuplexStream (port) {
port.onDisconnect.addListener(this._onDisconnect.bind(this))
}
-// private
-
+/**
+ * Callback triggered when a message is received from
+ * the remote Port associated with this Stream.
+ *
+ * @private
+ * @param {Object} msg - Payload from the onMessage listener of Port
+ */
PortDuplexStream.prototype._onMessage = function (msg) {
if (Buffer.isBuffer(msg)) {
delete msg._isBuffer
@@ -27,14 +39,31 @@ PortDuplexStream.prototype._onMessage = function (msg) {
}
}
+/**
+ * Callback triggered when the remote Port
+ * associated with this Stream disconnects.
+ *
+ * @private
+ */
PortDuplexStream.prototype._onDisconnect = function () {
this.destroy()
}
-// stream plumbing
-
+/**
+ * Explicitly sets read operations to a no-op
+ */
PortDuplexStream.prototype._read = noop
+
+/**
+ * Called internally when data should be written to
+ * this writable stream.
+ *
+ * @private
+ * @param {*} msg Arbitrary object to write
+ * @param {string} encoding Encoding to use when writing payload
+ * @param {Function} cb Called when writing is complete or an error occurs
+ */
PortDuplexStream.prototype._write = function (msg, encoding, cb) {
try {
if (Buffer.isBuffer(msg)) {
diff --git a/app/scripts/lib/seed-phrase-verifier.js b/app/scripts/lib/seed-phrase-verifier.js
index 9cea22029..3b5afb800 100644
--- a/app/scripts/lib/seed-phrase-verifier.js
+++ b/app/scripts/lib/seed-phrase-verifier.js
@@ -1,12 +1,21 @@
const KeyringController = require('eth-keyring-controller')
+const log = require('loglevel')
const seedPhraseVerifier = {
- // Verifies if the seed words can restore the accounts.
- //
- // The seed words can recreate the primary keyring and the accounts belonging to it.
- // The created accounts in the primary keyring are always the same.
- // The keyring always creates the accounts in the same sequence.
+ /**
+ * Verifies if the seed words can restore the accounts.
+ *
+ * Key notes:
+ * - The seed words can recreate the primary keyring and the accounts belonging to it.
+ * - The created accounts in the primary keyring are always the same.
+ * - The keyring always creates the accounts in the same sequence.
+ *
+ * @param {array} createdAccounts The accounts to restore
+ * @param {string} seedWords The seed words to verify
+ * @returns {Promise<void>} Promises undefined
+ *
+ */
verifyAccounts (createdAccounts, seedWords) {
return new Promise((resolve, reject) => {
diff --git a/app/scripts/lib/setupMetamaskMeshMetrics.js b/app/scripts/lib/setupMetamaskMeshMetrics.js
index 40343f017..02690a948 100644
--- a/app/scripts/lib/setupMetamaskMeshMetrics.js
+++ b/app/scripts/lib/setupMetamaskMeshMetrics.js
@@ -1,6 +1,9 @@
module.exports = setupMetamaskMeshMetrics
+/**
+ * Injects an iframe into the current document for testing
+ */
function setupMetamaskMeshMetrics() {
const testingContainer = document.createElement('iframe')
testingContainer.src = 'https://metamask.github.io/mesh-testing/'
diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupRaven.js
index 9ec9a256f..b1b67f771 100644
--- a/app/scripts/lib/setupRaven.js
+++ b/app/scripts/lib/setupRaven.js
@@ -23,22 +23,16 @@ function setupRaven(opts) {
release,
transport: function(opts) {
const report = opts.data
- // simplify certain complex error messages
- report.exception.values.forEach(item => {
- let errorMessage = item.value
- // simplify ethjs error messages
- errorMessage = extractEthjsErrorMessage(errorMessage)
- // simplify 'Transaction Failed: known transaction'
- if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) {
- // cut the hash from the error message
- errorMessage = 'Transaction Failed: known transaction'
- }
- // finalize
- item.value = errorMessage
- })
-
- // modify report urls
- rewriteReportUrls(report)
+ try {
+ // handle error-like non-error exceptions
+ nonErrorException(report)
+ // simplify certain complex error messages (e.g. Ethjs)
+ simplifyErrorMessages(report)
+ // modify report urls
+ rewriteReportUrls(report)
+ } catch (err) {
+ console.warn(err)
+ }
// make request normally
client._makeRequest(opts)
},
@@ -48,15 +42,42 @@ function setupRaven(opts) {
return Raven
}
+function nonErrorException(report) {
+ // handle errors that lost their error-ness in serialization
+ if (report.message.includes('Non-Error exception captured with keys: message')) {
+ if (!(report.extra && report.extra.__serialized__)) return
+ report.message = `Non-Error Exception: ${report.extra.__serialized__.message}`
+ }
+}
+
+function simplifyErrorMessages(report) {
+ if (report.exception && report.exception.values) {
+ report.exception.values.forEach(item => {
+ let errorMessage = item.value
+ // simplify ethjs error messages
+ errorMessage = extractEthjsErrorMessage(errorMessage)
+ // simplify 'Transaction Failed: known transaction'
+ if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) {
+ // cut the hash from the error message
+ errorMessage = 'Transaction Failed: known transaction'
+ }
+ // finalize
+ item.value = errorMessage
+ })
+ }
+}
+
function rewriteReportUrls(report) {
// update request url
report.request.url = toMetamaskUrl(report.request.url)
// update exception stack trace
- report.exception.values.forEach(item => {
- item.stacktrace.frames.forEach(frame => {
- frame.filename = toMetamaskUrl(frame.filename)
+ if (report.exception && report.exception.values) {
+ report.exception.values.forEach(item => {
+ item.stacktrace.frames.forEach(frame => {
+ frame.filename = toMetamaskUrl(frame.filename)
+ })
})
- })
+ }
}
function toMetamaskUrl(origUrl) {
diff --git a/app/scripts/lib/stream-utils.js b/app/scripts/lib/stream-utils.js
index 8bb0b4f3c..3dbc064b5 100644
--- a/app/scripts/lib/stream-utils.js
+++ b/app/scripts/lib/stream-utils.js
@@ -8,20 +8,34 @@ module.exports = {
setupMultiplex: setupMultiplex,
}
+/**
+ * Returns a stream transform that parses JSON strings passing through
+ * @return {stream.Transform}
+ */
function jsonParseStream () {
- return Through.obj(function (serialized, encoding, cb) {
+ return Through.obj(function (serialized, _, cb) {
this.push(JSON.parse(serialized))
cb()
})
}
+/**
+ * Returns a stream transform that calls {@code JSON.stringify}
+ * on objects passing through
+ * @return {stream.Transform} the stream transform
+ */
function jsonStringifyStream () {
- return Through.obj(function (obj, encoding, cb) {
+ return Through.obj(function (obj, _, cb) {
this.push(JSON.stringify(obj))
cb()
})
}
+/**
+ * Sets up stream multiplexing for the given stream
+ * @param {any} connectionStream - the stream to mux
+ * @return {stream.Stream} the multiplexed stream
+ */
function setupMultiplex (connectionStream) {
const mux = new ObjectMultiplex()
pump(
diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js
index 8b760790e..c58921610 100644
--- a/app/scripts/lib/typed-message-manager.js
+++ b/app/scripts/lib/typed-message-manager.js
@@ -3,9 +3,38 @@ const ObservableStore = require('obs-store')
const createId = require('./random-id')
const assert = require('assert')
const sigUtil = require('eth-sig-util')
+const log = require('loglevel')
+/**
+ * Represents, and contains data about, an 'eth_signTypedData' type signature request. These are created when a
+ * signature for an eth_signTypedData call is requested.
+ *
+ * @typedef {Object} TypedMessage
+ * @property {number} id An id to track and identify the message object
+ * @property {Object} msgParams The parameters to pass to the eth_signTypedData method once the signature request is
+ * approved.
+ * @property {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @property {Object} msgParams.from The address that is making the signature request.
+ * @property {string} msgParams.data A hex string conversion of the raw buffer data of the signature request
+ * @property {number} time The epoch time at which the this message was created
+ * @property {string} status Indicates whether the signature request is 'unapproved', 'approved', 'signed' or 'rejected'
+ * @property {string} type The json-prc signing method for which a signature request has been made. A 'Message' will
+ * always have a 'eth_signTypedData' type.
+ *
+ */
module.exports = class TypedMessageManager extends EventEmitter {
+ /**
+ * Controller in charge of managing - storing, adding, removing, updating - TypedMessage.
+ *
+ * @typedef {Object} TypedMessage
+ * @param {Object} opts @deprecated
+ * @property {Object} memStore The observable store where TypedMessage are saved.
+ * @property {Object} memStore.unapprovedTypedMessages A collection of all TypedMessages in the 'unapproved' state
+ * @property {number} memStore.unapprovedTypedMessagesCount The count of all TypedMessages in this.memStore.unapprobedMsgs
+ * @property {array} messages Holds all messages that have been created by this TypedMessage
+ *
+ */
constructor (opts) {
super()
this.memStore = new ObservableStore({
@@ -15,15 +44,37 @@ module.exports = class TypedMessageManager extends EventEmitter {
this.messages = []
}
+ /**
+ * A getter for the number of 'unapproved' TypedMessages in this.messages
+ *
+ * @returns {number} The number of 'unapproved' TypedMessages in this.messages
+ *
+ */
get unapprovedTypedMessagesCount () {
return Object.keys(this.getUnapprovedMsgs()).length
}
+ /**
+ * A getter for the 'unapproved' TypedMessages in this.messages
+ *
+ * @returns {Object} An index of TypedMessage ids to TypedMessages, for all 'unapproved' TypedMessages in
+ * this.messages
+ *
+ */
getUnapprovedMsgs () {
return this.messages.filter(msg => msg.status === 'unapproved')
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
}
+ /**
+ * Creates a new TypedMessage with an 'unapproved' status using the passed msgParams. this.addMsg is called to add
+ * the new TypedMessage to this.messages, and to save the unapproved TypedMessages from that list to
+ * this.memStore. Before any of this is done, msgParams are validated
+ *
+ * @param {Object} msgParams The params for the eth_sign call to be made after the message is approved.
+ * @returns {number} The id of the newly created TypedMessage.
+ *
+ */
addUnapprovedMessage (msgParams) {
this.validateParams(msgParams)
@@ -45,6 +96,12 @@ module.exports = class TypedMessageManager extends EventEmitter {
return msgId
}
+ /**
+ * Helper method for this.addUnapprovedMessage. Validates that the passed params have the required properties.
+ *
+ * @param {Object} params The params to validate
+ *
+ */
validateParams (params) {
assert.equal(typeof params, 'object', 'Params should ben an object.')
assert.ok('data' in params, 'Params must include a data field.')
@@ -56,24 +113,62 @@ module.exports = class TypedMessageManager extends EventEmitter {
}, 'Expected EIP712 typed data')
}
+ /**
+ * Adds a passed TypedMessage to this.messages, and calls this._saveMsgList() to save the unapproved TypedMessages from that
+ * list to this.memStore.
+ *
+ * @param {Message} msg The TypedMessage to add to this.messages
+ *
+ */
addMsg (msg) {
this.messages.push(msg)
this._saveMsgList()
}
+ /**
+ * Returns a specified TypedMessage.
+ *
+ * @param {number} msgId The id of the TypedMessage to get
+ * @returns {TypedMessage|undefined} The TypedMessage with the id that matches the passed msgId, or undefined
+ * if no TypedMessage has that id.
+ *
+ */
getMsg (msgId) {
return this.messages.find(msg => msg.id === msgId)
}
+ /**
+ * Approves a TypedMessage. Sets the message status via a call to this.setMsgStatusApproved, and returns a promise
+ * with any the message params modified for proper signing.
+ *
+ * @param {Object} msgParams The msgParams to be used when eth_sign is called, plus data added by MetaMask.
+ * @param {Object} msgParams.metamaskId Added to msgParams for tracking and identification within MetaMask.
+ * @returns {Promise<object>} Promises the msgParams object with metamaskId removed.
+ *
+ */
approveMessage (msgParams) {
this.setMsgStatusApproved(msgParams.metamaskId)
return this.prepMsgForSigning(msgParams)
}
+ /**
+ * Sets a TypedMessage status to 'approved' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the TypedMessage to approve.
+ *
+ */
setMsgStatusApproved (msgId) {
this._setMsgStatus(msgId, 'approved')
}
+ /**
+ * Sets a TypedMessage status to 'signed' via a call to this._setMsgStatus and updates that TypedMessage in
+ * this.messages by adding the raw signature data of the signature request to the TypedMessage
+ *
+ * @param {number} msgId The id of the TypedMessage to sign.
+ * @param {buffer} rawSig The raw data of the signature request
+ *
+ */
setMsgStatusSigned (msgId, rawSig) {
const msg = this.getMsg(msgId)
msg.rawSig = rawSig
@@ -81,11 +176,24 @@ module.exports = class TypedMessageManager extends EventEmitter {
this._setMsgStatus(msgId, 'signed')
}
+ /**
+ * Removes the metamaskId property from passed msgParams and returns a promise which resolves the updated msgParams
+ *
+ * @param {Object} msgParams The msgParams to modify
+ * @returns {Promise<object>} Promises the msgParams with the metamaskId property removed
+ *
+ */
prepMsgForSigning (msgParams) {
delete msgParams.metamaskId
return Promise.resolve(msgParams)
}
+ /**
+ * Sets a TypedMessage status to 'rejected' via a call to this._setMsgStatus.
+ *
+ * @param {number} msgId The id of the TypedMessage to reject.
+ *
+ */
rejectMsg (msgId) {
this._setMsgStatus(msgId, 'rejected')
}
@@ -94,6 +202,19 @@ module.exports = class TypedMessageManager extends EventEmitter {
// PRIVATE METHODS
//
+ /**
+ * Updates the status of a TypedMessage in this.messages via a call to this._updateMsg
+ *
+ * @private
+ * @param {number} msgId The id of the TypedMessage to update.
+ * @param {string} status The new status of the TypedMessage.
+ * @throws A 'TypedMessageManager - TypedMessage not found for id: "${msgId}".' if there is no TypedMessage
+ * in this.messages with an id equal to the passed msgId
+ * @fires An event with a name equal to `${msgId}:${status}`. The TypedMessage is also fired.
+ * @fires If status is 'rejected' or 'signed', an event with a name equal to `${msgId}:finished` is fired along
+ * with the TypedMessage
+ *
+ */
_setMsgStatus (msgId, status) {
const msg = this.getMsg(msgId)
if (!msg) throw new Error('TypedMessageManager - Message not found for id: "${msgId}".')
@@ -105,6 +226,15 @@ module.exports = class TypedMessageManager extends EventEmitter {
}
}
+ /**
+ * Sets a TypedMessage in this.messages to the passed TypedMessage if the ids are equal. Then saves the
+ * unapprovedTypedMsgs index to storage via this._saveMsgList
+ *
+ * @private
+ * @param {msg} TypedMessage A TypedMessage that will replace an existing TypedMessage (with the same
+ * id) in this.messages
+ *
+ */
_updateMsg (msg) {
const index = this.messages.findIndex((message) => message.id === msg.id)
if (index !== -1) {
@@ -113,6 +243,13 @@ module.exports = class TypedMessageManager extends EventEmitter {
this._saveMsgList()
}
+ /**
+ * Saves the unapproved TypedMessages, and their count, to this.memStore
+ *
+ * @private
+ * @fires 'updateBadge'
+ *
+ */
_saveMsgList () {
const unapprovedTypedMessages = this.getUnapprovedMsgs()
const unapprovedTypedMessagesCount = Object.keys(unapprovedTypedMessages).length
diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js
index 6dee9edf0..431d1e59c 100644
--- a/app/scripts/lib/util.js
+++ b/app/scripts/lib/util.js
@@ -1,20 +1,53 @@
const ethUtil = require('ethereumjs-util')
const assert = require('assert')
const BN = require('bn.js')
+const {
+ ENVIRONMENT_TYPE_POPUP,
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_FULLSCREEN,
+} = require('./enums')
-module.exports = {
- getStack,
- sufficientBalance,
- hexToBn,
- bnToHex,
- BnMultiplyByFraction,
-}
-
+/**
+ * Generates an example stack trace
+ *
+ * @returns {string} A stack trace
+ *
+ */
function getStack () {
const stack = new Error('Stack trace generator - not an error').stack
return stack
}
+/**
+ * Used to determine the window type through which the app is being viewed.
+ * - 'popup' refers to the extension opened through the browser app icon (in top right corner in chrome and firefox)
+ * - 'responsive' refers to the main browser window
+ * - 'notification' refers to the popup that appears in its own window when taking action outside of metamask
+ *
+ * @returns {string} A single word label that represents the type of window through which the app is being viewed
+ *
+ */
+const getEnvironmentType = (url = window.location.href) => {
+ if (url.match(/popup.html(?:\?.+)*$/)) {
+ return ENVIRONMENT_TYPE_POPUP
+ } else if (url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
+ return ENVIRONMENT_TYPE_FULLSCREEN
+ } else {
+ return ENVIRONMENT_TYPE_NOTIFICATION
+ }
+}
+
+/**
+ * Checks whether a given balance of ETH, represented as a hex string, is sufficient to pay a value plus a gas fee
+ *
+ * @param {object} txParams Contains data about a transaction
+ * @param {string} txParams.gas The gas for a transaction
+ * @param {string} txParams.gasPrice The price per gas for the transaction
+ * @param {string} txParams.value The value of ETH to send
+ * @param {string} hexBalance A balance of ETH represented as a hex string
+ * @returns {boolean} Whether the balance is greater than or equal to the value plus the value of gas times gasPrice
+ *
+ */
function sufficientBalance (txParams, hexBalance) {
// validate hexBalance is a hex string
assert.equal(typeof hexBalance, 'string', 'sufficientBalance - hexBalance is not a hex string')
@@ -29,16 +62,48 @@ function sufficientBalance (txParams, hexBalance) {
return balance.gte(maxCost)
}
+/**
+ * Converts a BN object to a hex string with a '0x' prefix
+ *
+ * @param {BN} inputBn The BN to convert to a hex string
+ * @returns {string} A '0x' prefixed hex string
+ *
+ */
function bnToHex (inputBn) {
return ethUtil.addHexPrefix(inputBn.toString(16))
}
+/**
+ * Converts a hex string to a BN object
+ *
+ * @param {string} inputHex A number represented as a hex string
+ * @returns {Object} A BN object
+ *
+ */
function hexToBn (inputHex) {
return new BN(ethUtil.stripHexPrefix(inputHex), 16)
}
+/**
+ * Used to multiply a BN by a fraction
+ *
+ * @param {BN} targetBN The number to multiply by a fraction
+ * @param {number|string} numerator The numerator of the fraction multiplier
+ * @param {number|string} denominator The denominator of the fraction multiplier
+ * @returns {BN} The product of the multiplication
+ *
+ */
function BnMultiplyByFraction (targetBN, numerator, denominator) {
const numBN = new BN(numerator)
const denomBN = new BN(denominator)
return targetBN.mul(numBN).div(denomBN)
}
+
+module.exports = {
+ getStack,
+ getEnvironmentType,
+ sufficientBalance,
+ hexToBn,
+ bnToHex,
+ BnMultiplyByFraction,
+}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index b96acc9da..a90acb4d5 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -5,10 +5,10 @@
*/
const EventEmitter = require('events')
-const extend = require('xtend')
const pump = require('pump')
const Dnode = require('dnode')
const ObservableStore = require('obs-store')
+const ComposableObservableStore = require('./lib/ComposableObservableStore')
const asStream = require('obs-store/lib/asStream')
const AccountTracker = require('./lib/account-tracker')
const RpcEngine = require('json-rpc-engine')
@@ -34,6 +34,7 @@ const PersonalMessageManager = require('./lib/personal-message-manager')
const TypedMessageManager = require('./lib/typed-message-manager')
const TransactionController = require('./controllers/transactions')
const BalancesController = require('./controllers/computed-balances')
+const TokenRatesController = require('./controllers/token-rates')
const ConfigManager = require('./lib/config-manager')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
@@ -44,6 +45,7 @@ const BN = require('ethereumjs-util').BN
const GWEI_BN = new BN('1000000000')
const percentile = require('percentile')
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
+const log = require('loglevel')
module.exports = class MetamaskController extends EventEmitter {
@@ -65,7 +67,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.platform = opts.platform
// observable state store
- this.store = new ObservableStore(initState)
+ this.store = new ComposableObservableStore(initState)
// lock to ensure only one vault created at once
this.createVaultMutex = new Mutex()
@@ -104,6 +106,11 @@ module.exports = class MetamaskController extends EventEmitter {
this.provider = this.initializeProvider()
this.blockTracker = this.provider._blockTracker
+ // token exchange rate tracker
+ this.tokenRatesController = new TokenRatesController({
+ preferences: this.preferencesController.store,
+ })
+
this.recentBlocksController = new RecentBlocksController({
blockTracker: this.blockTracker,
provider: this.provider,
@@ -184,53 +191,37 @@ module.exports = class MetamaskController extends EventEmitter {
this.typedMessageManager = new TypedMessageManager()
this.publicConfigStore = this.initPublicConfigStore()
- // manual disk state subscriptions
- this.txController.store.subscribe((state) => {
- this.store.updateState({ TransactionController: state })
- })
- this.keyringController.store.subscribe((state) => {
- this.store.updateState({ KeyringController: state })
- })
- this.preferencesController.store.subscribe((state) => {
- this.store.updateState({ PreferencesController: state })
- })
- this.addressBookController.store.subscribe((state) => {
- this.store.updateState({ AddressBookController: state })
- })
- this.currencyController.store.subscribe((state) => {
- this.store.updateState({ CurrencyController: state })
- })
- this.noticeController.store.subscribe((state) => {
- this.store.updateState({ NoticeController: state })
- })
- this.shapeshiftController.store.subscribe((state) => {
- this.store.updateState({ ShapeShiftController: state })
- })
- this.networkController.store.subscribe((state) => {
- this.store.updateState({ NetworkController: state })
+ this.store.updateStructure({
+ TransactionController: this.txController.store,
+ KeyringController: this.keyringController.store,
+ PreferencesController: this.preferencesController.store,
+ AddressBookController: this.addressBookController.store,
+ CurrencyController: this.currencyController.store,
+ NoticeController: this.noticeController.store,
+ ShapeShiftController: this.shapeshiftController.store,
+ NetworkController: this.networkController.store,
+ InfuraController: this.infuraController.store,
})
- this.infuraController.store.subscribe((state) => {
- this.store.updateState({ InfuraController: state })
+ this.memStore = new ComposableObservableStore(null, {
+ NetworkController: this.networkController.store,
+ AccountTracker: this.accountTracker.store,
+ TxController: this.txController.memStore,
+ BalancesController: this.balancesController.store,
+ TokenRatesController: this.tokenRatesController.store,
+ MessageManager: this.messageManager.memStore,
+ PersonalMessageManager: this.personalMessageManager.memStore,
+ TypesMessageManager: this.typedMessageManager.memStore,
+ KeyringController: this.keyringController.memStore,
+ PreferencesController: this.preferencesController.store,
+ RecentBlocksController: this.recentBlocksController.store,
+ AddressBookController: this.addressBookController.store,
+ CurrencyController: this.currencyController.store,
+ NoticeController: this.noticeController.memStore,
+ ShapeshiftController: this.shapeshiftController.store,
+ InfuraController: this.infuraController.store,
})
-
- // manual mem state subscriptions
- const sendUpdate = this.sendUpdate.bind(this)
- this.networkController.store.subscribe(sendUpdate)
- this.accountTracker.store.subscribe(sendUpdate)
- this.txController.memStore.subscribe(sendUpdate)
- this.balancesController.store.subscribe(sendUpdate)
- this.messageManager.memStore.subscribe(sendUpdate)
- this.personalMessageManager.memStore.subscribe(sendUpdate)
- this.typedMessageManager.memStore.subscribe(sendUpdate)
- this.keyringController.memStore.subscribe(sendUpdate)
- this.preferencesController.store.subscribe(sendUpdate)
- this.recentBlocksController.store.subscribe(sendUpdate)
- this.addressBookController.store.subscribe(sendUpdate)
- this.currencyController.store.subscribe(sendUpdate)
- this.noticeController.memStore.subscribe(sendUpdate)
- this.shapeshiftController.store.subscribe(sendUpdate)
- this.infuraController.store.subscribe(sendUpdate)
+ this.memStore.subscribe(this.sendUpdate.bind(this))
}
/**
@@ -272,6 +263,7 @@ module.exports = class MetamaskController extends EventEmitter {
/**
* Constructor helper: initialize a public config store.
+ * This store is used to make some config info available to Dapps synchronously.
*/
initPublicConfigStore () {
// get init state
@@ -279,6 +271,7 @@ module.exports = class MetamaskController extends EventEmitter {
// memStore -> transform -> publicConfigStore
this.on('update', (memState) => {
+ this.isClientOpenAndUnlocked = memState.isUnlocked && this._isClientOpen
const publicState = selectPublicState(memState)
publicConfigStore.putState(publicState)
})
@@ -308,39 +301,24 @@ module.exports = class MetamaskController extends EventEmitter {
const vault = this.keyringController.store.getState().vault
const isInitialized = (!!wallet || !!vault)
- return extend(
- {
- isInitialized,
- },
- this.networkController.store.getState(),
- this.accountTracker.store.getState(),
- this.txController.memStore.getState(),
- this.messageManager.memStore.getState(),
- this.personalMessageManager.memStore.getState(),
- this.typedMessageManager.memStore.getState(),
- this.keyringController.memStore.getState(),
- this.balancesController.store.getState(),
- this.preferencesController.store.getState(),
- this.addressBookController.store.getState(),
- this.currencyController.store.getState(),
- this.noticeController.memStore.getState(),
- this.infuraController.store.getState(),
- this.recentBlocksController.store.getState(),
- // config manager
- this.configManager.getConfig(),
- this.shapeshiftController.store.getState(),
- {
+ return {
+ ...{ isInitialized },
+ ...this.memStore.getFlatState(),
+ ...this.configManager.getConfig(),
+ ...{
lostAccounts: this.configManager.getLostAccounts(),
seedWords: this.configManager.getSeedWords(),
forgottenPassword: this.configManager.getPasswordForgotten(),
- }
- )
+ },
+ }
}
/**
- * Returns an api-object which is consumed by the UI
+ * Returns an Object containing API Callback Functions.
+ * These functions are the interface for the UI.
+ * The API object can be transmitted over a stream with dnode.
*
- * @returns {Object}
+ * @returns {Object} Object containing API functions.
*/
getApi () {
const keyringController = this.keyringController
@@ -404,6 +382,7 @@ module.exports = class MetamaskController extends EventEmitter {
updateTransaction: nodeify(txController.updateTransaction, txController),
updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController),
retryTransaction: nodeify(this.retryTransaction, this),
+ isNonceTaken: nodeify(txController.isNonceTaken, txController),
// messageManager
signMessage: nodeify(this.signMessage, this),
@@ -430,16 +409,18 @@ module.exports = class MetamaskController extends EventEmitter {
//=============================================================================
/**
- * Creates a new Vault(?) and create a new keychain(?)
- *
- * A vault is ...
+ * Creates a new Vault and create a new keychain.
*
- * A keychain is ...
+ * A vault, or KeyringController, is a controller that contains
+ * many different account strategies, currently called Keyrings.
+ * Creating it new means wiping all previous keyrings.
*
+ * A keychain, or keyring, controls many accounts with a single backup and signing strategy.
+ * For example, a mnemonic phrase can generate many accounts, and is a keyring.
*
- * @param {} password
+ * @param {string} password
*
- * @returns {} vault
+ * @returns {Object} vault
*/
async createNewVaultAndKeychain (password) {
const release = await this.createVaultMutex.acquire()
@@ -465,7 +446,7 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * Create a new Vault and restore an existent keychain
+ * Create a new Vault and restore an existent keyring.
* @param {} password
* @param {} seed
*/
@@ -483,10 +464,16 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
+ * @type Identity
+ * @property {string} name - The account nickname.
+ * @property {string} address - The account's ethereum address, in lower case.
+ * @property {boolean} mayBeFauceting - Whether this account is currently
+ * receiving funds from our automatic Ropsten faucet.
+ */
+
+ /**
* Retrieves the first Identiy from the passed Vault and selects the related address
*
- * An Identity is ...
- *
* @param {} vault
*/
selectFirstIdentity (vault) {
@@ -495,12 +482,12 @@ module.exports = class MetamaskController extends EventEmitter {
this.preferencesController.setSelectedAddress(address)
}
- // ?
- // Opinionated Keyring Management
+ //
+ // Account Management
//
/**
- * Adds a new account to ...
+ * Adds a new account to the default (first) HD seed phrase Keyring.
*
* @returns {} keyState
*/
@@ -530,6 +517,8 @@ module.exports = class MetamaskController extends EventEmitter {
*
* Used when creating a first vault, to allow confirmation.
* Also used when revealing the seed words in the confirmation view.
+ *
+ * @param {Function} cb - A callback called on completion.
*/
placeSeedWords (cb) {
@@ -549,6 +538,8 @@ module.exports = class MetamaskController extends EventEmitter {
* Validity: seed phrase restores the accounts belonging to the current vault.
*
* Called when the first account is created and on unlocking the vault.
+ *
+ * @returns {Promise<string>} Seed phrase to be confirmed by the user.
*/
async verifySeedPhrase () {
@@ -579,6 +570,7 @@ module.exports = class MetamaskController extends EventEmitter {
*
* The seed phrase remains available in the background process.
*
+ * @param {function} cb Callback function called with the current address.
*/
clearSeedWordCache (cb) {
this.configManager.setSeedWords(null)
@@ -586,9 +578,13 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * ?
+ * Clears the transaction history, to allow users to force-reset their nonces.
+ * Mostly used in development environments, when networks are restarted with
+ * the same network ID.
+ *
+ * @returns Promise<string> The current selected address.
*/
- async resetAccount (cb) {
+ async resetAccount () {
const selectedAddress = this.preferencesController.getSelectedAddress()
this.txController.wipeTransactions(selectedAddress)
@@ -600,11 +596,13 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * Imports an account ... ?
+ * Imports an account with the specified import strategy.
+ * These are defined in app/scripts/account-import-strategies
+ * Each strategy represents a different way of serializing an Ethereum key pair.
*
- * @param {} strategy
- * @param {} args
- * @param {} cb
+ * @param {string} strategy - A unique identifier for an account import strategy.
+ * @param {any} args - The data required by that strategy to import an account.
+ * @param {Function} cb - A callback function called with a state update on success.
*/
importAccountWithStrategy (strategy, args, cb) {
accountImporter.importAccount(strategy, args)
@@ -618,13 +616,42 @@ module.exports = class MetamaskController extends EventEmitter {
}
// ---------------------------------------------------------------------------
- // Identity Management (sign)
+ // Identity Management (signature operations)
+
+ // eth_sign methods:
+
+ /**
+ * Called when a Dapp uses the eth_sign method, to request user approval.
+ * eth_sign is a pure signature of arbitrary data. It is on a deprecation
+ * path, since this data can be a transaction, or can leak private key
+ * information.
+ *
+ * @param {Object} msgParams - The params passed to eth_sign.
+ * @param {Function} cb = The callback function called with the signature.
+ */
+ newUnsignedMessage (msgParams, cb) {
+ const msgId = this.messageManager.addUnapprovedMessage(msgParams)
+ this.sendUpdate()
+ this.opts.showUnconfirmedMessage()
+ this.messageManager.once(`${msgId}:finished`, (data) => {
+ switch (data.status) {
+ case 'signed':
+ return cb(null, data.rawSig)
+ case 'rejected':
+ return cb(new Error('MetaMask Message Signature: User denied message signature.'))
+ default:
+ return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
+ }
+ })
+ }
/**
- * @param {} msgParams
- * @param {} cb
+ * Signifies user intent to complete an eth_sign method.
+ *
+ * @param {Object} msgParams The params passed to eth_call.
+ * @returns {Promise<Object>} Full state update.
*/
- signMessage (msgParams, cb) {
+ signMessage (msgParams) {
log.info('MetaMaskController - signMessage')
const msgId = msgParams.metamaskId
@@ -643,14 +670,37 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
- // Prefixed Style Message Signing Methods:
+ /**
+ * Used to cancel a message submitted via eth_sign.
+ *
+ * @param {string} msgId - The id of the message to cancel.
+ */
+ cancelMessage (msgId, cb) {
+ const messageManager = this.messageManager
+ messageManager.rejectMsg(msgId)
+ if (cb && typeof cb === 'function') {
+ cb(null, this.getState())
+ }
+ }
+
+ // personal_sign methods:
/**
+ * Called when a dapp uses the personal_sign method.
+ * This is identical to the Geth eth_sign method, and may eventually replace
+ * eth_sign.
*
- * @param {} msgParams
- * @param {} cb
+ * We currently define our eth_sign and personal_sign mostly for legacy Dapps.
+ *
+ * @param {Object} msgParams - The params of the message to sign & return to the Dapp.
+ * @param {Function} cb - The callback function called with the signature.
+ * Passed back to the requesting Dapp.
*/
- approvePersonalMessage (msgParams, cb) {
+ newUnsignedPersonalMessage (msgParams, cb) {
+ if (!msgParams.from) {
+ return cb(new Error('MetaMask Message Signature: from field is required.'))
+ }
+
const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams)
this.sendUpdate()
this.opts.showUnconfirmedMessage()
@@ -659,7 +709,7 @@ module.exports = class MetamaskController extends EventEmitter {
case 'signed':
return cb(null, data.rawSig)
case 'rejected':
- return cb(new Error('MetaMask Message Signature: User denied transaction signature.'))
+ return cb(new Error('MetaMask Message Signature: User denied message signature.'))
default:
return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
}
@@ -667,7 +717,11 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * @param {} msgParams
+ * Signifies a user's approval to sign a personal_sign message in queue.
+ * Triggers signing, and the callback function from newUnsignedPersonalMessage.
+ *
+ * @param {Object} msgParams - The params of the message to sign & return to the Dapp.
+ * @returns {Promise<Object>} - A full state update.
*/
signPersonalMessage (msgParams) {
log.info('MetaMaskController - signPersonalMessage')
@@ -688,7 +742,54 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * @param {} msgParams
+ * Used to cancel a personal_sign type message.
+ * @param {string} msgId - The ID of the message to cancel.
+ * @param {Function} cb - The callback function called with a full state update.
+ */
+ cancelPersonalMessage (msgId, cb) {
+ const messageManager = this.personalMessageManager
+ messageManager.rejectMsg(msgId)
+ if (cb && typeof cb === 'function') {
+ cb(null, this.getState())
+ }
+ }
+
+ // eth_signTypedData methods
+
+ /**
+ * Called when a dapp uses the eth_signTypedData method, per EIP 712.
+ *
+ * @param {Object} msgParams - The params passed to eth_signTypedData.
+ * @param {Function} cb - The callback function, called with the signature.
+ */
+ newUnsignedTypedMessage (msgParams, cb) {
+ let msgId
+ try {
+ msgId = this.typedMessageManager.addUnapprovedMessage(msgParams)
+ this.sendUpdate()
+ this.opts.showUnconfirmedMessage()
+ } catch (e) {
+ return cb(e)
+ }
+
+ this.typedMessageManager.once(`${msgId}:finished`, (data) => {
+ switch (data.status) {
+ case 'signed':
+ return cb(null, data.rawSig)
+ case 'rejected':
+ return cb(new Error('MetaMask Message Signature: User denied message signature.'))
+ default:
+ return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
+ }
+ })
+ }
+
+ /**
+ * The method for a user approving a call to eth_signTypedData, per EIP 712.
+ * Triggers the callback in newUnsignedTypedMessage.
+ *
+ * @param {Object} msgParams - The params passed to eth_signTypedData.
+ * @returns {Object} Full state update.
*/
signTypedMessage (msgParams) {
log.info('MetaMaskController - signTypedMessage')
@@ -708,12 +809,30 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
+ /**
+ * Used to cancel a eth_signTypedData type message.
+ * @param {string} msgId - The ID of the message to cancel.
+ * @param {Function} cb - The callback function called with a full state update.
+ */
+ cancelTypedMessage (msgId, cb) {
+ const messageManager = this.typedMessageManager
+ messageManager.rejectMsg(msgId)
+ if (cb && typeof cb === 'function') {
+ cb(null, this.getState())
+ }
+ }
+
// ---------------------------------------------------------------------------
- // Account Restauration
+ // MetaMask Version 3 Migration Account Restauration Methods
/**
- * ?
+ * A legacy method (probably dead code) that was used when we swapped out our
+ * key management library that we depended on.
*
+ * Described in:
+ * https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd
+ *
+ * @deprecated
* @param {} migratorOutput
*/
restoreOldVaultAccounts (migratorOutput) {
@@ -723,8 +842,26 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * ?
+ * A legacy method used to record user confirmation that they understand
+ * that some of their accounts have been recovered but should be backed up.
+ *
+ * @deprecated
+ * @param {Function} cb - A callback function called with a full state update.
+ */
+ markAccountsFound (cb) {
+ this.configManager.setLostAccounts([])
+ this.sendUpdate()
+ cb(null, this.getState())
+ }
+
+ /**
+ * A legacy method (probably dead code) that was used when we swapped out our
+ * key management library that we depended on.
+ *
+ * Described in:
+ * https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd
*
+ * @deprecated
* @param {} migratorOutput
*/
restoreOldLostAccounts (migratorOutput) {
@@ -737,12 +874,23 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
- * Import (lost) Accounts
+ * An account object
+ * @typedef Account
+ * @property string privateKey - The private key of the account.
+ */
+
+ /**
+ * Probably no longer needed, related to the Version 3 migration.
+ * Imports a hash of accounts to private keys into the vault.
*
- * @param {Object} {lostAccounts} @Array accounts <{ address, privateKey }>
+ * Described in:
+ * https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd
*
* Uses the array's private keys to create a new Simple Key Pair keychain
* and add it to the keyring controller.
+ * @deprecated
+ * @param {Account[]} lostAccounts -
+ * @returns {Keyring[]} An array of the restored keyrings.
*/
importLostAccounts ({ lostAccounts }) {
const privKeys = lostAccounts.map(acct => acct.privateKey)
@@ -756,113 +904,37 @@ module.exports = class MetamaskController extends EventEmitter {
// END (VAULT / KEYRING RELATED METHODS)
//=============================================================================
-//
-
-//=============================================================================
-// MESSAGES
-//=============================================================================
-
+ /**
+ * Allows a user to try to speed up a transaction by retrying it
+ * with higher gas.
+ *
+ * @param {string} txId - The ID of the transaction to speed up.
+ * @param {Function} cb - The callback function called with a full state update.
+ */
async retryTransaction (txId, cb) {
await this.txController.retryTransaction(txId)
const state = await this.getState()
return state
}
+//=============================================================================
+// PASSWORD MANAGEMENT
+//=============================================================================
- newUnsignedMessage (msgParams, cb) {
- const msgId = this.messageManager.addUnapprovedMessage(msgParams)
- this.sendUpdate()
- this.opts.showUnconfirmedMessage()
- this.messageManager.once(`${msgId}:finished`, (data) => {
- switch (data.status) {
- case 'signed':
- return cb(null, data.rawSig)
- case 'rejected':
- return cb(new Error('MetaMask Message Signature: User denied message signature.'))
- default:
- return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
- }
- })
- }
-
- newUnsignedPersonalMessage (msgParams, cb) {
- if (!msgParams.from) {
- return cb(new Error('MetaMask Message Signature: from field is required.'))
- }
-
- const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams)
- this.sendUpdate()
- this.opts.showUnconfirmedMessage()
- this.personalMessageManager.once(`${msgId}:finished`, (data) => {
- switch (data.status) {
- case 'signed':
- return cb(null, data.rawSig)
- case 'rejected':
- return cb(new Error('MetaMask Message Signature: User denied message signature.'))
- default:
- return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
- }
- })
- }
-
- newUnsignedTypedMessage (msgParams, cb) {
- let msgId
- try {
- msgId = this.typedMessageManager.addUnapprovedMessage(msgParams)
- this.sendUpdate()
- this.opts.showUnconfirmedMessage()
- } catch (e) {
- return cb(e)
- }
-
- this.typedMessageManager.once(`${msgId}:finished`, (data) => {
- switch (data.status) {
- case 'signed':
- return cb(null, data.rawSig)
- case 'rejected':
- return cb(new Error('MetaMask Message Signature: User denied message signature.'))
- default:
- return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
- }
- })
- }
-
- cancelMessage (msgId, cb) {
- const messageManager = this.messageManager
- messageManager.rejectMsg(msgId)
- if (cb && typeof cb === 'function') {
- cb(null, this.getState())
- }
- }
-
- cancelPersonalMessage (msgId, cb) {
- const messageManager = this.personalMessageManager
- messageManager.rejectMsg(msgId)
- if (cb && typeof cb === 'function') {
- cb(null, this.getState())
- }
- }
-
- cancelTypedMessage (msgId, cb) {
- const messageManager = this.typedMessageManager
- messageManager.rejectMsg(msgId)
- if (cb && typeof cb === 'function') {
- cb(null, this.getState())
- }
- }
-
- markAccountsFound (cb) {
- this.configManager.setLostAccounts([])
- this.sendUpdate()
- cb(null, this.getState())
- }
-
+ /**
+ * Allows a user to begin the seed phrase recovery process.
+ * @param {Function} cb - A callback function called when complete.
+ */
markPasswordForgotten(cb) {
this.configManager.setPasswordForgotten(true)
this.sendUpdate()
cb()
}
+ /**
+ * Allows a user to end the seed phrase recovery process.
+ * @param {Function} cb - A callback function called when complete.
+ */
unMarkPasswordForgotten(cb) {
this.configManager.setPasswordForgotten(false)
this.sendUpdate()
@@ -873,6 +945,13 @@ module.exports = class MetamaskController extends EventEmitter {
// SETUP
//=============================================================================
+ /**
+ * Used to create a multiplexed stream for connecting to an untrusted context
+ * like a Dapp or other extension.
+ * @param {*} connectionStream - The Duplex stream to connect to.
+ * @param {string} originDomain - The domain requesting the stream, which
+ * may trigger a blacklist reload.
+ */
setupUntrustedCommunication (connectionStream, originDomain) {
// Check if new connection is blacklisted
if (this.blacklistController.checkForPhishing(originDomain)) {
@@ -888,6 +967,16 @@ module.exports = class MetamaskController extends EventEmitter {
this.setupPublicConfig(mux.createStream('publicConfig'))
}
+ /**
+ * Used to create a multiplexed stream for connecting to a trusted context,
+ * like our own user interfaces, which have the provider APIs, but also
+ * receive the exported API from this controller, which includes trusted
+ * functions, like the ability to approve transactions or sign messages.
+ *
+ * @param {*} connectionStream - The duplex stream to connect to.
+ * @param {string} originDomain - The domain requesting the connection,
+ * used in logging and error reporting.
+ */
setupTrustedCommunication (connectionStream, originDomain) {
// setup multiplexing
const mux = setupMultiplex(connectionStream)
@@ -896,12 +985,25 @@ module.exports = class MetamaskController extends EventEmitter {
this.setupProviderConnection(mux.createStream('provider'), originDomain)
}
+ /**
+ * Called when we detect a suspicious domain. Requests the browser redirects
+ * to our anti-phishing page.
+ *
+ * @private
+ * @param {*} connectionStream - The duplex stream to the per-page script,
+ * for sending the reload attempt to.
+ * @param {string} hostname - The URL that triggered the suspicion.
+ */
sendPhishingWarning (connectionStream, hostname) {
const mux = setupMultiplex(connectionStream)
const phishingStream = mux.createStream('phishing')
phishingStream.write({ hostname })
}
+ /**
+ * A method for providing our API over a stream using Dnode.
+ * @param {*} outStream - The stream to provide our API over.
+ */
setupControllerConnection (outStream) {
const api = this.getApi()
const dnode = Dnode(api)
@@ -920,6 +1022,11 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
+ /**
+ * A method for serving our ethereum provider over a given stream.
+ * @param {*} outStream - The stream to provide over.
+ * @param {string} origin - The URI of the requesting resource.
+ */
setupProviderConnection (outStream, origin) {
// setup json rpc engine stack
const engine = new RpcEngine()
@@ -949,6 +1056,16 @@ module.exports = class MetamaskController extends EventEmitter {
)
}
+ /**
+ * A method for providing our public config info over a stream.
+ * This includes info we like to be synchronous if possible, like
+ * the current selected account, and network ID.
+ *
+ * Since synchronous methods have been deprecated in web3,
+ * this is a good candidate for deprecation.
+ *
+ * @param {*} outStream - The stream to provide public config over.
+ */
setupPublicConfig (outStream) {
pump(
asStream(this.publicConfigStore),
@@ -959,10 +1076,21 @@ module.exports = class MetamaskController extends EventEmitter {
)
}
+ /**
+ * A method for emitting the full MetaMask state to all registered listeners.
+ * @private
+ */
privateSendUpdate () {
this.emit('update', this.getState())
}
+ /**
+ * A method for estimating a good gas price at recent prices.
+ * Returns the lowest price that would have been included in
+ * 50% of recent blocks.
+ *
+ * @returns {string} A hex representation of the suggested wei gas price.
+ */
getGasPrice () {
const { recentBlocksController } = this
const { recentBlocks } = recentBlocksController.store.getState()
@@ -996,6 +1124,11 @@ module.exports = class MetamaskController extends EventEmitter {
// Log blocks
+ /**
+ * A method for setting the user's preferred display currency.
+ * @param {string} currencyCode - The code of the preferred currency.
+ * @param {Function} cb - A callback function returning currency info.
+ */
setCurrentCurrency (currencyCode, cb) {
try {
this.currencyController.setCurrentCurrency(currencyCode)
@@ -1011,6 +1144,13 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ /**
+ * A method for forwarding the user to the easiest way to obtain ether,
+ * or the network "gas" currency, for the current selected network.
+ *
+ * @param {string} address - The address to fund.
+ * @param {string} amount - The amount of ether desired, as a base 10 string.
+ */
buyEth (address, amount) {
if (!amount) amount = '5'
const network = this.networkController.getNetworkState()
@@ -1018,18 +1158,33 @@ module.exports = class MetamaskController extends EventEmitter {
if (url) this.platform.openWindow({ url })
}
+ /**
+ * A method for triggering a shapeshift currency transfer.
+ * @param {string} depositAddress - The address to deposit to.
+ * @property {string} depositType - An abbreviation of the type of crypto currency to be deposited.
+ */
createShapeShiftTx (depositAddress, depositType) {
this.shapeshiftController.createShapeShiftTx(depositAddress, depositType)
}
// network
- async setCustomRpc (rpcTarget, rpcList) {
+ /**
+ * A method for selecting a custom URL for an ethereum RPC provider.
+ * @param {string} rpcTarget - A URL for a valid Ethereum RPC API.
+ * @returns {Promise<String>} - The RPC Target URL confirmed.
+ */
+ async setCustomRpc (rpcTarget) {
this.networkController.setRpcTarget(rpcTarget)
await this.preferencesController.updateFrequentRpcList(rpcTarget)
return rpcTarget
}
+ /**
+ * Sets whether or not to use the blockie identicon format.
+ * @param {boolean} val - True for bockie, false for jazzicon.
+ * @param {Function} cb - A callback function called when complete.
+ */
setUseBlockie (val, cb) {
try {
this.preferencesController.setUseBlockie(val)
@@ -1039,6 +1194,11 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ /**
+ * A method for setting a user's current locale, affecting the language rendered.
+ * @param {string} key - Locale identifier.
+ * @param {Function} cb - A callback function called when complete.
+ */
setCurrentLocale (key, cb) {
try {
this.preferencesController.setCurrentLocale(key)
@@ -1048,6 +1208,11 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ /**
+ * A method for initializing storage the first time.
+ * @param {Object} initState - The default state to initialize with.
+ * @private
+ */
recordFirstTimeInfo (initState) {
if (!('firstTimeInfo' in initState)) {
initState.firstTimeInfo = {
@@ -1057,4 +1222,22 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ /**
+ * A method for recording whether the MetaMask user interface is open or not.
+ * @private
+ * @param {boolean} open
+ */
+ set isClientOpen (open) {
+ this._isClientOpen = open
+ this.isClientOpenAndUnlocked = this.getState().isUnlocked && open
+ }
+
+ /**
+ * A method for activating the retrieval of price data, which should only be fetched when the UI is visible.
+ * @private
+ * @param {boolean} active - True if price data should be getting fetched.
+ */
+ set isClientOpenAndUnlocked (active) {
+ this.tokenRatesController.isActive = active
+ }
}
diff --git a/app/scripts/migrations/013.js b/app/scripts/migrations/013.js
index 8f11e510e..15a9b28d4 100644
--- a/app/scripts/migrations/013.js
+++ b/app/scripts/migrations/013.js
@@ -27,8 +27,11 @@ module.exports = {
function transformState (state) {
const newState = state
- if (newState.config.provider.type === 'testnet') {
- newState.config.provider.type = 'ropsten'
+ const { config } = newState
+ if ( config && config.provider ) {
+ if (config.provider.type === 'testnet') {
+ newState.config.provider.type = 'ropsten'
+ }
}
return newState
}
diff --git a/app/scripts/migrations/015.js b/app/scripts/migrations/015.js
index 4b839580b..5e2f9e63b 100644
--- a/app/scripts/migrations/015.js
+++ b/app/scripts/migrations/015.js
@@ -28,11 +28,14 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.err) return txMeta
- else if (txMeta.err.message === 'Gave up submitting tx.') txMeta.status = 'failed'
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.err) return txMeta
+ else if (txMeta.err.message === 'Gave up submitting tx.') txMeta.status = 'failed'
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/016.js b/app/scripts/migrations/016.js
index 4fc534f1c..048c7a40e 100644
--- a/app/scripts/migrations/016.js
+++ b/app/scripts/migrations/016.js
@@ -28,14 +28,18 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.err) return txMeta
- if (txMeta.err === 'transaction with the same hash was already imported.') {
- txMeta.status = 'submitted'
- delete txMeta.err
- }
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.err) return txMeta
+ if (txMeta.err === 'transaction with the same hash was already imported.') {
+ txMeta.status = 'submitted'
+ delete txMeta.err
+ }
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/017.js b/app/scripts/migrations/017.js
index 24959cd3a..5f6d906d6 100644
--- a/app/scripts/migrations/017.js
+++ b/app/scripts/migrations/017.js
@@ -27,14 +27,17 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (!txMeta.status === 'failed') return txMeta
- if (txMeta.retryCount > 0 && txMeta.retryCount < 2) {
- txMeta.status = 'submitted'
- delete txMeta.err
- }
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (!txMeta.status === 'failed') return txMeta
+ if (txMeta.retryCount > 0 && txMeta.retryCount < 2) {
+ txMeta.status = 'submitted'
+ delete txMeta.err
+ }
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/018.js b/app/scripts/migrations/018.js
index d27fe3f46..ffbf24a4b 100644
--- a/app/scripts/migrations/018.js
+++ b/app/scripts/migrations/018.js
@@ -7,7 +7,7 @@ This migration updates "transaction state history" to diffs style
*/
const clone = require('clone')
-const txStateHistoryHelper = require('../lib/tx-state-history-helper')
+const txStateHistoryHelper = require('../controllers/transactions/lib/tx-state-history-helper')
module.exports = {
@@ -29,24 +29,27 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- // no history: initialize
- if (!txMeta.history || txMeta.history.length === 0) {
- const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
- txMeta.history = [snapshot]
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ // no history: initialize
+ if (!txMeta.history || txMeta.history.length === 0) {
+ const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
+ txMeta.history = [snapshot]
+ return txMeta
+ }
+ // has history: migrate
+ const newHistory = (
+ txStateHistoryHelper.migrateFromSnapshotsToDiffs(txMeta.history)
+ // remove empty diffs
+ .filter((entry) => {
+ return !Array.isArray(entry) || entry.length > 0
+ })
+ )
+ txMeta.history = newHistory
return txMeta
- }
- // has history: migrate
- const newHistory = (
- txStateHistoryHelper.migrateFromSnapshotsToDiffs(txMeta.history)
- // remove empty diffs
- .filter((entry) => {
- return !Array.isArray(entry) || entry.length > 0
- })
- )
- txMeta.history = newHistory
- return txMeta
- })
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/019.js b/app/scripts/migrations/019.js
index 072c96370..ce5da6859 100644
--- a/app/scripts/migrations/019.js
+++ b/app/scripts/migrations/019.js
@@ -29,32 +29,36 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
- newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
- if (txMeta.status !== 'submitted') return txMeta
+ const transactions = newState.TransactionController.transactions
- const confirmedTxs = txList.filter((tx) => tx.status === 'confirmed')
- .filter((tx) => tx.txParams.from === txMeta.txParams.from)
- .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
- const highestConfirmedNonce = getHighestNonce(confirmedTxs)
+ newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
+ if (txMeta.status !== 'submitted') return txMeta
- const pendingTxs = txList.filter((tx) => tx.status === 'submitted')
- .filter((tx) => tx.txParams.from === txMeta.txParams.from)
- .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
- const highestContinuousNonce = getHighestContinuousFrom(pendingTxs, highestConfirmedNonce)
+ const confirmedTxs = txList.filter((tx) => tx.status === 'confirmed')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestConfirmedNonce = getHighestNonce(confirmedTxs)
- const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce)
+ const pendingTxs = txList.filter((tx) => tx.status === 'submitted')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestContinuousNonce = getHighestContinuousFrom(pendingTxs, highestConfirmedNonce)
- if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) {
- txMeta.status = 'failed'
- txMeta.err = {
- message: 'nonce too high',
- note: 'migration 019 custom error',
+ const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce)
+
+ if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) {
+ txMeta.status = 'failed'
+ txMeta.err = {
+ message: 'nonce too high',
+ note: 'migration 019 custom error',
+ }
}
- }
- return txMeta
- })
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/022.js b/app/scripts/migrations/022.js
index c3c0d53ef..1fbe241e6 100644
--- a/app/scripts/migrations/022.js
+++ b/app/scripts/migrations/022.js
@@ -28,12 +28,15 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
-
- newState.TransactionController.transactions = transactions.map((txMeta) => {
- if (txMeta.status !== 'submitted' || txMeta.submittedTime) return txMeta
- txMeta.submittedTime = (new Date()).getTime()
- return txMeta
- })
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (txMeta.status !== 'submitted' || txMeta.submittedTime) return txMeta
+ txMeta.submittedTime = (new Date()).getTime()
+ return txMeta
+ })
+ }
return newState
}
diff --git a/app/scripts/migrations/023.js b/app/scripts/migrations/023.js
index bce0a5bea..151496b06 100644
--- a/app/scripts/migrations/023.js
+++ b/app/scripts/migrations/023.js
@@ -28,23 +28,27 @@ module.exports = {
function transformState (state) {
const newState = state
- const transactions = newState.TransactionController.transactions
-
- if (transactions.length <= 40) return newState
-
- let reverseTxList = transactions.reverse()
- let stripping = true
- while (reverseTxList.length > 40 && stripping) {
- let txIndex = reverseTxList.findIndex((txMeta) => {
- return (txMeta.status === 'failed' ||
- txMeta.status === 'rejected' ||
- txMeta.status === 'confirmed' ||
- txMeta.status === 'dropped')
- })
- if (txIndex < 0) stripping = false
- else reverseTxList.splice(txIndex, 1)
- }
- newState.TransactionController.transactions = reverseTxList.reverse()
+ const { TransactionController } = newState
+ if (TransactionController && TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+
+ if (transactions.length <= 40) return newState
+
+ let reverseTxList = transactions.reverse()
+ let stripping = true
+ while (reverseTxList.length > 40 && stripping) {
+ let txIndex = reverseTxList.findIndex((txMeta) => {
+ return (txMeta.status === 'failed' ||
+ txMeta.status === 'rejected' ||
+ txMeta.status === 'confirmed' ||
+ txMeta.status === 'dropped')
+ })
+ if (txIndex < 0) stripping = false
+ else reverseTxList.splice(txIndex, 1)
+ }
+
+ newState.TransactionController.transactions = reverseTxList.reverse()
+ }
return newState
}
diff --git a/app/scripts/migrations/024.js b/app/scripts/migrations/024.js
new file mode 100644
index 000000000..d0b276a79
--- /dev/null
+++ b/app/scripts/migrations/024.js
@@ -0,0 +1,41 @@
+
+const version = 24
+
+/*
+
+This migration ensures that the from address in txParams is to lower case for
+all unapproved transactions
+
+*/
+
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: async function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ return versionedData
+ },
+}
+
+function transformState (state) {
+ const newState = state
+ if (!newState.TransactionController) return newState
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
+ if (
+ txMeta.status === 'unapproved' &&
+ txMeta.txParams &&
+ txMeta.txParams.from
+ ) {
+ txMeta.txParams.from = txMeta.txParams.from.toLowerCase()
+ }
+ return txMeta
+ })
+ return newState
+}
diff --git a/app/scripts/migrations/025.js b/app/scripts/migrations/025.js
new file mode 100644
index 000000000..fc3b20a44
--- /dev/null
+++ b/app/scripts/migrations/025.js
@@ -0,0 +1,61 @@
+// next version number
+const version = 25
+
+/*
+
+normalizes txParams on unconfirmed txs
+
+*/
+const ethUtil = require('ethereumjs-util')
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: async function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ return versionedData
+ },
+}
+
+function transformState (state) {
+ const newState = state
+
+ if (newState.TransactionController) {
+ if (newState.TransactionController.transactions) {
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ if (txMeta.status !== 'unapproved') return txMeta
+ txMeta.txParams = normalizeTxParams(txMeta.txParams)
+ return txMeta
+ })
+ }
+ }
+
+ return newState
+}
+
+function normalizeTxParams (txParams) {
+ // functions that handle normalizing of that key in txParams
+ const whiteList = {
+ from: from => ethUtil.addHexPrefix(from).toLowerCase(),
+ to: to => ethUtil.addHexPrefix(txParams.to).toLowerCase(),
+ nonce: nonce => ethUtil.addHexPrefix(nonce),
+ value: value => ethUtil.addHexPrefix(value),
+ data: data => ethUtil.addHexPrefix(data),
+ gas: gas => ethUtil.addHexPrefix(gas),
+ gasPrice: gasPrice => ethUtil.addHexPrefix(gasPrice),
+ }
+
+ // apply only keys in the whiteList
+ const normalizedTxParams = {}
+ Object.keys(whiteList).forEach((key) => {
+ if (txParams[key]) normalizedTxParams[key] = whiteList[key](txParams[key])
+ })
+
+ return normalizedTxParams
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 811e06b6b..6c4a51b32 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -34,4 +34,6 @@ module.exports = [
require('./021'),
require('./022'),
require('./023'),
+ require('./024'),
+ require('./025'),
]
diff --git a/app/scripts/migrations/template.js b/app/scripts/migrations/template.js
new file mode 100644
index 000000000..0915c6bdf
--- /dev/null
+++ b/app/scripts/migrations/template.js
@@ -0,0 +1,29 @@
+// next version number
+const version = 0
+
+/*
+
+description of migration and what it does
+
+*/
+
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: async function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ return versionedData
+ },
+}
+
+function transformState (state) {
+ const newState = state
+ // transform state here
+ return newState
+}
diff --git a/app/scripts/platforms/sw.js b/app/scripts/platforms/sw.js
index 007d8dc5b..56c5f2774 100644
--- a/app/scripts/platforms/sw.js
+++ b/app/scripts/platforms/sw.js
@@ -1,20 +1,25 @@
-
class SwPlatform {
-
- //
- // Public
- //
-
+ /**
+ * Reloads the platform
+ */
reload () {
- // you cant actually do this
- global.location.reload()
+ // TODO: you can't actually do this
+ /** @type {any} */ (global).location.reload()
}
- openWindow ({ url }) {
- // this doesnt actually work
- global.open(url, '_blank')
+ /**
+ * Opens a window
+ * @param {{url: string}} opts - The window options
+ */
+ openWindow (opts) {
+ // TODO: this doesn't actually work
+ /** @type {any} */ (global).open(opts.url, '_blank')
}
+ /**
+ * Returns the platform version
+ * @returns {string}
+ */
getVersion () {
return '<unable to read version>'
}
diff --git a/app/scripts/platforms/window.js b/app/scripts/platforms/window.js
index 1527c008b..943b2a703 100644
--- a/app/scripts/platforms/window.js
+++ b/app/scripts/platforms/window.js
@@ -1,18 +1,23 @@
-
class WindowPlatform {
-
- //
- // Public
- //
-
+ /**
+ * Reload the platform
+ */
reload () {
- global.location.reload()
+ /** @type {any} */ (global).location.reload()
}
- openWindow ({ url }) {
- global.open(url, '_blank')
+ /**
+ * Opens a window
+ * @param {{url: string}} opts - The window options
+ */
+ openWindow (opts) {
+ /** @type {any} */ (global).open(opts.url, '_blank')
}
+ /**
+ * Returns the platform version
+ * @returns {string}
+ */
getVersion () {
return '<unable to read version>'
}
diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js
index 2e4334bb1..6325b8a8d 100644
--- a/app/scripts/popup-core.js
+++ b/app/scripts/popup-core.js
@@ -7,10 +7,14 @@ const launchMetamaskUi = require('../../ui')
const StreamProvider = require('web3-stream-provider')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
-
module.exports = initializePopup
-
+/**
+ * Asynchronously initializes the MetaMask popup UI
+ *
+ * @param {{ container: Element, connectionStream: * }} config Popup configuration object
+ * @param {Function} cb Called when initialization is complete
+ */
function initializePopup ({ container, connectionStream }, cb) {
// setup app
async.waterfall([
@@ -19,6 +23,12 @@ function initializePopup ({ container, connectionStream }, cb) {
], cb)
}
+/**
+ * Establishes streamed connections to background scripts and a Web3 provider
+ *
+ * @param {PortDuplexStream} connectionStream PortStream instance establishing a background connection
+ * @param {Function} cb Called when controller connection is established
+ */
function connectToAccountManager (connectionStream, cb) {
// setup communication with background
// setup multiplexing
@@ -28,6 +38,11 @@ function connectToAccountManager (connectionStream, cb) {
setupWeb3Connection(mx.createStream('provider'))
}
+/**
+ * Establishes a streamed connection to a Web3 provider
+ *
+ * @param {PortDuplexStream} connectionStream PortStream instance establishing a background connection
+ */
function setupWeb3Connection (connectionStream) {
var providerStream = new StreamProvider()
providerStream.pipe(connectionStream).pipe(providerStream)
@@ -38,6 +53,12 @@ function setupWeb3Connection (connectionStream) {
global.eth = new Eth(providerStream)
}
+/**
+ * Establishes a streamed connection to the background account manager
+ *
+ * @param {PortDuplexStream} connectionStream PortStream instance establishing a background connection
+ * @param {Function} cb Called when the remote account manager connection is established
+ */
function setupControllerConnection (connectionStream, cb) {
// this is a really sneaky way of adding EventEmitter api
// to a bi-directional dnode instance
diff --git a/app/scripts/ui.js b/app/scripts/ui.js
index 13c7ac5ec..bdab29c1e 100644
--- a/app/scripts/ui.js
+++ b/app/scripts/ui.js
@@ -3,12 +3,14 @@ const OldMetaMaskUiCss = require('../../old-ui/css')
const NewMetaMaskUiCss = require('../../ui/css')
const startPopup = require('./popup-core')
const PortStream = require('./lib/port-stream.js')
-const isPopupOrNotification = require('./lib/is-popup-or-notification')
+const { getEnvironmentType } = require('./lib/util')
+const { ENVIRONMENT_TYPE_NOTIFICATION } = require('./lib/enums')
const extension = require('extensionizer')
const ExtensionPlatform = require('./platforms/extension')
const NotificationManager = require('./lib/notification-manager')
const notificationManager = new NotificationManager()
const setupRaven = require('./lib/setupRaven')
+const log = require('loglevel')
start().catch(log.error)
@@ -26,7 +28,7 @@ async function start() {
// injectCss(css)
// identify window type (popup, notification)
- const windowType = isPopupOrNotification()
+ const windowType = getEnvironmentType(window.location.href)
global.METAMASK_UI_TYPE = windowType
closePopupIfOpen(windowType)
@@ -68,7 +70,7 @@ async function start() {
function closePopupIfOpen (windowType) {
- if (windowType !== 'notification') {
+ if (windowType !== ENVIRONMENT_TYPE_NOTIFICATION) {
// should close only chrome popup
notificationManager.closePopup()
}
diff --git a/development/mock-dev.js b/development/mock-dev.js
index a1fb3a86d..f332633d5 100644
--- a/development/mock-dev.js
+++ b/development/mock-dev.js
@@ -36,15 +36,28 @@ log.setLevel('debug')
//
const qs = require('qs')
-let queryString = qs.parse(window.location.href.split('#')[1])
-let selectedView = queryString.view || 'first time'
+const routerPath = window.location.href.split('#')[1]
+let queryString = {}
+let selectedView
+
+if (routerPath) {
+ queryString = qs.parse(routerPath.split('?')[1])
+}
+
+selectedView = queryString.view || 'first time'
const firstState = states[selectedView]
updateQueryParams(selectedView)
-function updateQueryParams(newView) {
+function updateQueryParams (newView) {
queryString.view = newView
const params = qs.stringify(queryString)
- window.location.href = window.location.href.split('#')[0] + `#${params}`
+ const locationPaths = window.location.href.split('#')
+ const routerPath = locationPaths[1] || ''
+ const newPath = locationPaths[0] + '#' + routerPath.split('?')[0] + `?${params}`
+
+ if (window.location.href !== newPath) {
+ window.location.href = newPath
+ }
}
//
diff --git a/development/sourcemap-validator.js b/development/sourcemap-validator.js
new file mode 100644
index 000000000..edc97667a
--- /dev/null
+++ b/development/sourcemap-validator.js
@@ -0,0 +1,49 @@
+const fs = require('fs')
+const { SourceMapConsumer } = require('source-map')
+
+//
+// Utility to help check if sourcemaps are working
+//
+// searches `dist/chrome/inpage.js` for "new Error" statements
+// and prints their source lines using the sourcemaps.
+// if not working it may error or print minified garbage
+//
+
+start()
+
+async function start() {
+ const rawBuild = fs.readFileSync(__dirname + '/../dist/chrome/inpage.js', 'utf8')
+ const rawSourceMap = fs.readFileSync(__dirname + '/../dist/sourcemaps/inpage.js.map', 'utf8')
+ const consumer = await new SourceMapConsumer(rawSourceMap)
+
+ console.log('hasContentsOfAllSources:', consumer.hasContentsOfAllSources(), '\n')
+ console.log('sources:')
+ consumer.sources.map((sourcePath) => console.log(sourcePath))
+
+ console.log('\nexamining "new Error" statements:\n')
+ const sourceLines = rawBuild.split('\n')
+ sourceLines.map(line => indicesOf('new Error', line))
+ .forEach((errorIndices, lineIndex) => {
+ // if (errorIndex === null) return console.log('line does not contain "new Error"')
+ errorIndices.forEach((errorIndex) => {
+ const position = { line: lineIndex + 1, column: errorIndex }
+ const result = consumer.originalPositionFor(position)
+ if (!result.source) return console.warn(`!! missing source for position: ${position}`)
+ // filter out deps distributed minified without sourcemaps
+ if (result.source === 'node_modules/browserify/node_modules/browser-pack/_prelude.js') return // minified mess
+ if (result.source === 'node_modules/web3/dist/web3.min.js') return // minified mess
+ const sourceContent = consumer.sourceContentFor(result.source)
+ const sourceLines = sourceContent.split('\n')
+ const line = sourceLines[result.line-1]
+ console.log(`\n========================== ${result.source} ====================================\n`)
+ console.log(line)
+ console.log(`\n==============================================================================\n`)
+ })
+ })
+}
+
+function indicesOf(substring, string) {
+ var a=[],i=-1;
+ while((i=string.indexOf(substring,i+1)) >= 0) a.push(i);
+ return a;
+}
diff --git a/development/states/currency-localization.json b/development/states/currency-localization.json
new file mode 100644
index 000000000..302e24c11
--- /dev/null
+++ b/development/states/currency-localization.json
@@ -0,0 +1,134 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "currentCurrency": "USD",
+ "conversionRate": 19855,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedMsgs": {},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ ]
+ }
+ ],
+ "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "currentCurrency": "PHP",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": null,
+ "gasPrice": null,
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": "",
+ "to": "",
+ "amount": "0x0",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ },
+ "currentLocale": "en"
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail",
+ "detailView": null,
+ "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/states/tx-list-items.js b/development/states/tx-list-items.json
index d567e3fed..d567e3fed 100644
--- a/development/states/tx-list-items.js
+++ b/development/states/tx-list-items.json
diff --git a/development/tools/.jsdoc.json b/development/tools/.jsdoc.json
new file mode 100644
index 000000000..fd90bf89f
--- /dev/null
+++ b/development/tools/.jsdoc.json
@@ -0,0 +1,25 @@
+{
+ "tags": {
+ "allowUnknownTags": false
+ },
+ "source": {
+ "include": "app/scripts/",
+ "includePattern": ".js$",
+ "excludePattern": "(node_modules/|docs)"
+ },
+ "plugins": [
+ "plugins/markdown"
+ ],
+ "opts": {
+ "template": "node_modules/radgrad-jsdoc-template/",
+ "encoding": "utf8",
+ "destination": "docs/jsdocs",
+ "recurse": true,
+ "verbose": true
+ },
+ "templates": {
+ "cleverLinks": false,
+ "monospaceLinks": false
+ }
+}
+
diff --git a/development/tools/README.md b/development/tools/README.md
new file mode 100644
index 000000000..caef51fe6
--- /dev/null
+++ b/development/tools/README.md
@@ -0,0 +1,15 @@
+# Development Tools & Configurations
+
+This folder contains configuration files which are used by the the different
+development-tools, like e.g. JsDoc.
+
+
+## Appveyor
+
+
+https://www.appveyor.com/docs/build-configuration/#alternative-yaml-file-location
+
+Withtin the configuration, point to a weblocation of a txt config file:
+
+https://ci.appveyor.com/project/lazaridiscom/mm-vault/settings
+https://raw.githubusercontent.com/lazaridiscom/mm-vault/master/dev/tools/appveyor.txt
diff --git a/development/tools/appveyor.txt b/development/tools/appveyor.txt
new file mode 100644
index 000000000..4ed974079
--- /dev/null
+++ b/development/tools/appveyor.txt
@@ -0,0 +1,21 @@
+# Test against the latest version of this Node.js version
+environment:
+ nodejs_version: "8"
+
+# Install scripts. (runs after repo cloning)
+install:
+ # Get the latest stable version of Node.js or io.js
+ - ps: Install-Product node $env:nodejs_version
+ # install modules
+ - npm install
+
+# Post-install test scripts.
+test_script:
+ # Output useful info for debugging.
+ - node --version
+ - npm --version
+ # run tests
+ - npm test
+
+# Don't actually build.
+build: off
diff --git a/docs/QA_Guide.md b/docs/QA_Guide.md
new file mode 100644
index 000000000..0b7c0e023
--- /dev/null
+++ b/docs/QA_Guide.md
@@ -0,0 +1,48 @@
+# QA Guide
+
+Steps to mark a full pass of QA complete.
+* Browsers: Opera, Chrome, Firefox, Edge.
+* OS: Ubuntu, Mac OSX, Windows
+* Load older version of MetaMask and attempt to simulate updating the extension.
+* Open Developer Console in background and popup, inspect errors.
+* Watch the state logs
+ * Transactions (unapproved txs -> rejected/submitted -> confirmed)
+ * Nonces/LocalNonces
+* Vault integrity
+ * create vault
+ * Log out
+ * Log in again
+ * Log out
+ * Restore from seed
+ * Create a second account
+ * Import a loose account (not related to HD Wallet)
+ * Import old existing vault seed phrase (pref with test Ether)
+ * Download State Logs, Priv key file, seed phrase file.
+* Send Ether
+ * by address
+ * by ens name
+* Web3 API Stability
+ * Create a contract from a Ðapp (remix)
+ * Load a Ðapp that reads using events/logs (ENS)
+ * Connect to MEW/MyCypto
+ * Send a transaction from any Ðapp
+ - MEW
+ - EtherDelta
+ - Leeroy
+ - Aragon
+ - (https://tmashuang.github.io/demo-dapp)
+ * Check account balances
+* Token Management
+ * create a token with tokenfactory (http://tokenfactory.surge.sh/#/factory)
+ * Add that token to the token view
+ * Send that token to another metamask address.
+ * confirm the token arrived.
+* Send a transaction and sign a message (https://danfinlay.github.io/js-eth-personal-sign-examples/) for each keyring type
+ * hd keyring
+ * imported keyring
+* Change network from mainnet → ropsten → rinkeby → localhost (ganache)
+* Ganache set blocktime to simulate retryTx in MetaMask
+* Copy public key to clipboard
+* Export private key
+
+* Explore changes in master, target features that have been changed and break.
diff --git a/docs/team.md b/docs/team.md
new file mode 100644
index 000000000..72f9d3226
--- /dev/null
+++ b/docs/team.md
@@ -0,0 +1,78 @@
+# The Team
+
+Here is an overview of the current MetaMask team, and their primary roles and responsibilities, in the order they joined the team.
+
+## Core Team Members
+
+The core team maintains aspects of the main product (the extension) and the core libraries (the MetaMask Controller, provider-engine, etc).
+
+### Aaron Davis
+
+@kumavis
+Founder / Technical Lead
+
+Especially in charge of connection to the blockchain. Wrote [provider-engine](https://github.com/MetaMask/provider-engine), and is currently working with @hermanjunge on our JavaScript light-client.
+
+### Dan Finlay
+
+@danfinlay
+Software Engineer / Product Lead
+
+Focused on the deliverable, user-valuable aspects of MetaMask, including usability and documentation. Coordinates efforts between different branches of the team, and integrations with other projects.
+
+### Frankie Pangilinan
+
+@frankiebee
+Software Engineer / Transaction Manager Lead
+
+Frankie contributes code throughout MetaMask, but has become especially specialized in the way MetaMask manages transactions. She is also the original lead of the [Mascara](https://github.com/MetaMask/mascara) project.
+
+### Kevin Serrano
+
+@Zanibas
+Software Engineer / Project Management Lead
+
+Kevin is a software engineer, but also spends a lot of his time keeping the team's administrative operations running smoothly.
+
+### Thomas Huang
+
+@tmashuang
+QA Engineer
+
+Thomas is the head of MetaMask Quality Assurance. He both takes the final pass of branches of code before we ship to production, and is also in charge of continuously improving our automated quality assurance process.
+
+### Christian Jeria
+
+@cjeria
+User Experience Designer
+
+Christian is the lead of MetaMask's user experience. He is continuously designing prototypes, testing them with users, and refining them with our developers for production.
+
+### Paul Bouchon
+
+@bitpshr
+Software Engineer
+
+The newest member of the team! Paul is currently being onboarded, and finding his niche within the team.
+
+## Laboratory Team Members
+
+These team members are working on projects that will benefit MetaMask, but are not directly working on the product itself.
+
+### Herman Junge
+
+@hermanjunge
+Software Engineer
+
+Herman is currently leading the Mustekala project, a JavaScript, IPFS-based Ethereum light client.
+
+## Kyokan Team Members
+
+[Kyokan](http://kyokan.io/) is a consulting firm that has been working closely with the MetaMask team on the latest version of our user interface. Their team members are not members of ConsenSys LLC, but they contribute a lot to the project.
+
+- Daniel Tsui (@sdsui)
+- Chi Kei Chan (@chikeichan)
+- Dan Miller (@danjm)
+- David Yoo (@yookd)
+- Whymarrh Whitby (@whymarrh)
+
diff --git a/docs/transaction-flow.png b/docs/transaction-flow.png
new file mode 100644
index 000000000..1059b60d8
--- /dev/null
+++ b/docs/transaction-flow.png
Binary files differ
diff --git a/gulpfile.js b/gulpfile.js
index 4f0da9d60..4dca7089f 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -247,7 +247,7 @@ gulp.task('dev:scss', createScssBuildTask({
src: 'ui/app/css/index.scss',
dest: 'ui/app/css/output',
devMode: true,
- pattern: 'ui/app/css/**/*.scss',
+ pattern: 'ui/app/**/*.scss',
}))
function createScssBuildTask({ src, dest, devMode, pattern }) {
@@ -484,16 +484,6 @@ function generateBundler(opts, performBundle) {
NODE_ENV: opts.devMode ? 'development' : 'production',
}))
- // Minification
- if (opts.minifyBuild) {
- bundler.transform('uglifyify', {
- global: true,
- mangle: {
- reserved: [ 'MetamaskInpageProvider' ]
- },
- })
- }
-
if (opts.watch) {
bundler = watchify(bundler)
// on any file update, re-runs the bundler
@@ -567,6 +557,16 @@ function bundleTask(opts) {
.pipe(sourcemaps.init({ loadMaps: true }))
}
+ // Minification
+ if (opts.minifyBuild) {
+ buildStream = buildStream
+ .pipe(uglify({
+ mangle: {
+ reserved: [ 'MetamaskInpageProvider' ]
+ },
+ }))
+ }
+
// Finalize Source Maps (writes .map file)
if (opts.buildSourceMaps) {
buildStream = buildStream
diff --git a/mascara/src/app/first-time/confirm-seed-screen.js b/mascara/src/app/first-time/confirm-seed-screen.js
new file mode 100644
index 000000000..7c0431431
--- /dev/null
+++ b/mascara/src/app/first-time/confirm-seed-screen.js
@@ -0,0 +1,161 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import classnames from 'classnames'
+import shuffle from 'lodash.shuffle'
+import { compose } from 'recompose'
+import Identicon from '../../../../ui/app/components/identicon'
+import { confirmSeedWords, showModal } from '../../../../ui/app/actions'
+import Breadcrumbs from './breadcrumbs'
+import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE, INITIALIZE_BACKUP_PHRASE_ROUTE } from '../../../../ui/app/routes'
+
+class ConfirmSeedScreen extends Component {
+ static propTypes = {
+ isLoading: PropTypes.bool,
+ address: PropTypes.string,
+ seedWords: PropTypes.string,
+ confirmSeedWords: PropTypes.func,
+ history: PropTypes.object,
+ openBuyEtherModal: PropTypes.func,
+ };
+
+ static defaultProps = {
+ seedWords: '',
+ }
+
+ constructor (props) {
+ super(props)
+ const { seedWords } = props
+ this.state = {
+ selectedSeeds: [],
+ shuffledSeeds: seedWords && shuffle(seedWords.split(' ')) || [],
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ handleClick () {
+ const { confirmSeedWords, history, openBuyEtherModal } = this.props
+
+ confirmSeedWords()
+ .then(() => {
+ history.push(DEFAULT_ROUTE)
+ openBuyEtherModal()
+ })
+ }
+
+ render () {
+ const { seedWords, history } = this.props
+ const { selectedSeeds, shuffledSeeds } = this.state
+ const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
+
+ return (
+ <div className="first-time-flow">
+ {
+ this.props.isLoading
+ ? <LoadingScreen loadingMessage="Creating your new account" />
+ : (
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div className="backup-phrase">
+ <a
+ className="backup-phrase__back-button"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
+ }}
+ href="#"
+ >
+ {`< Back`}
+ </a>
+ <Identicon address={this.props.address} diameter={70} />
+ <div className="backup-phrase__content-wrapper">
+ <div>
+ <div className="backup-phrase__title">
+ Confirm your Secret Backup Phrase
+ </div>
+ <div className="backup-phrase__body-text">
+ Please select each phrase in order to make sure it is correct.
+ </div>
+ <div className="backup-phrase__confirm-secret">
+ {selectedSeeds.map(([_, word], i) => (
+ <button
+ key={i}
+ className="backup-phrase__confirm-seed-option"
+ >
+ {word}
+ </button>
+ ))}
+ </div>
+ <div className="backup-phrase__confirm-seed-options">
+ {shuffledSeeds.map((word, i) => {
+ const isSelected = selectedSeeds
+ .filter(([index, seed]) => seed === word && index === i)
+ .length
+
+ return (
+ <button
+ key={i}
+ className={classnames('backup-phrase__confirm-seed-option', {
+ 'backup-phrase__confirm-seed-option--selected': isSelected,
+ })}
+ onClick={() => {
+ if (!isSelected) {
+ this.setState({
+ selectedSeeds: [...selectedSeeds, [i, word]],
+ })
+ } else {
+ this.setState({
+ selectedSeeds: selectedSeeds
+ .filter(([index, seed]) => !(seed === word && index === i)),
+ })
+ }
+ }}
+ >
+ {word}
+ </button>
+ )
+ })}
+ </div>
+ <button
+ className="first-time-flow__button"
+ onClick={() => isValid && this.handleClick()}
+ disabled={!isValid}
+ >
+ Confirm
+ </button>
+ </div>
+ </div>
+ <Breadcrumbs total={3} currentIndex={1} />
+ </div>
+ </div>
+ </div>
+ )
+ }
+ </div>
+ )
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
+ seedWords,
+ isLoading,
+ address: selectedAddress,
+ }),
+ dispatch => ({
+ confirmSeedWords: () => dispatch(confirmSeedWords()),
+ openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})),
+ })
+ )
+)(ConfirmSeedScreen)
diff --git a/mascara/src/app/first-time/create-password-screen.js b/mascara/src/app/first-time/create-password-screen.js
index 192da3399..6ec05e11d 100644
--- a/mascara/src/app/first-time/create-password-screen.js
+++ b/mascara/src/app/first-time/create-password-screen.js
@@ -1,20 +1,26 @@
-import EventEmitter from 'events'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
-import classnames from 'classnames'
-import {createNewVaultAndKeychain} from '../../../../ui/app/actions'
-import LoadingScreen from './loading-screen'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
+import { createNewVaultAndKeychain } from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
+import EventEmitter from 'events'
import Mascot from '../../../../ui/app/components/mascot'
+import classnames from 'classnames'
+import {
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+} from '../../../../ui/app/routes'
class CreatePasswordScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
createAccount: PropTypes.func.isRequired,
- goToImportWithSeedPhrase: PropTypes.func.isRequired,
- goToImportAccount: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired,
+ history: PropTypes.object.isRequired,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
isMascara: PropTypes.bool.isRequired,
}
@@ -23,13 +29,21 @@ class CreatePasswordScreen extends Component {
confirmPassword: '',
}
- constructor () {
- super()
+ constructor (props) {
+ super(props)
this.animationEventEmitter = new EventEmitter()
}
+ componentWillMount () {
+ const { isInitialized, history } = this.props
+
+ if (isInitialized) {
+ history.push(INITIALIZE_NOTICE_ROUTE)
+ }
+ }
+
isValid () {
- const {password, confirmPassword} = this.state
+ const { password, confirmPassword } = this.state
if (!password || !confirmPassword) {
return false
@@ -47,93 +61,182 @@ class CreatePasswordScreen extends Component {
return
}
- const {password} = this.state
- const {createAccount, next} = this.props
+ const { password } = this.state
+ const { createAccount, history } = this.props
+ this.setState({ isLoading: true })
createAccount(password)
- .then(next)
+ .then(() => history.push(INITIALIZE_UNIQUE_IMAGE_ROUTE))
+ }
+
+ renderFields () {
+ const { isMascara, history } = this.props
+
+ return (
+ <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
+ <div className={classnames({
+ 'first-view-main': !isMascara,
+ 'first-view-main__mascara': isMascara,
+ })}>
+ {isMascara && <div className="mascara-info first-view-phone-invisible">
+ <Mascot
+ animationEventEmitter={this.animationEventEmitter}
+ width="225"
+ height="225"
+ />
+ <div className="info">
+ MetaMask is a secure identity vault for Ethereum.
+ </div>
+ <div className="info">
+ It allows you to hold ether & tokens, and interact with decentralized applications.
+ </div>
+ </div>}
+ <div className="create-password">
+ <div className="create-password__title">
+ Create Password
+ </div>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ <input
+ className="first-time-flow__input create-password__confirm-input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ <button
+ className="first-time-flow__button"
+ disabled={!this.isValid()}
+ onClick={this.createAccount}
+ >
+ Create
+ </button>
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
+ }}
+ >
+ Import with seed phrase
+ </a>
+ { /* }
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
+ }}
+ >
+ Import an account
+ </a>
+ { */ }
+ <Breadcrumbs total={3} currentIndex={0} />
+ </div>
+ </div>
+ </div>
+ )
}
render () {
- const { isLoading, goToImportWithSeedPhrase, isMascara } = this.props
-
- return isLoading
- ? <LoadingScreen loadingMessage="Creating your new account" />
- : (
- <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
- <div className={classnames({
- 'first-view-main': !isMascara,
- 'first-view-main__mascara': isMascara,
- })}>
- {isMascara && <div className="mascara-info first-view-phone-invisible">
- <Mascot
- animationEventEmitter={this.animationEventEmitter}
- width="225"
- height="225"
- />
- <div className="info">
- MetaMask is a secure identity vault for Ethereum.
- </div>
- <div className="info">
- It allows you to hold ether & tokens, and interact with decentralized applications.
- </div>
- </div>}
- <div className="create-password">
- <div className="create-password__title">
- Create Password
- </div>
- <input
- className="first-time-flow__input"
- type="password"
- placeholder="New Password (min 8 characters)"
- onChange={e => this.setState({password: e.target.value})}
- />
- <input
- className="first-time-flow__input create-password__confirm-input"
- type="password"
- placeholder="Confirm Password"
- onChange={e => this.setState({confirmPassword: e.target.value})}
- />
- <button
- className="first-time-flow__button"
- disabled={!this.isValid()}
- onClick={this.createAccount}
- >
- Create
- </button>
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportWithSeedPhrase()
- }}
- >
- Import with seed phrase
- </a>
- { /* }
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportAccount()
- }}
- >
- Import an account
- </a>
- { */ }
- <Breadcrumbs total={3} currentIndex={0} />
+ const { history, isMascara } = this.props
+
+ return (
+ <div className={classnames({ 'first-view-main-wrapper': !isMascara })}>
+ <div className={classnames({
+ 'first-view-main': !isMascara,
+ 'first-view-main__mascara': isMascara,
+ })}>
+ {isMascara && <div className="mascara-info first-view-phone-invisible">
+ <Mascot
+ animationEventEmitter={this.animationEventEmitter}
+ width="225"
+ height="225"
+ />
+ <div className="info">
+ MetaMask is a secure identity vault for Ethereum.
+ </div>
+ <div className="info">
+ It allows you to hold ether & tokens, and interact with decentralized applications.
</div>
+ </div>}
+ <div className="create-password">
+ <div className="create-password__title">
+ Create Password
+ </div>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ <input
+ className="first-time-flow__input create-password__confirm-input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ <button
+ className="first-time-flow__button"
+ disabled={!this.isValid()}
+ onClick={this.createAccount}
+ >
+ Create
+ </button>
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE)
+ }}
+ >
+ Import with seed phrase
+ </a>
+ { /* }
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ history.push(INITIALIZE_IMPORT_ACCOUNT_ROUTE)
+ }}
+ >
+ Import an account
+ </a>
+ { */ }
+ <Breadcrumbs total={3} currentIndex={0} />
</div>
</div>
- )
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = ({ metamask, appState }) => {
+ const { isInitialized, isUnlocked, isMascara, noActiveNotices } = metamask
+ const { isLoading } = appState
+
+ return {
+ isLoading,
+ isInitialized,
+ isUnlocked,
+ isMascara,
+ noActiveNotices,
}
}
-export default connect(
- ({ appState: { isLoading }, metamask: { isMascara } }) => ({ isLoading, isMascara }),
- dispatch => ({
- createAccount: password => dispatch(createNewVaultAndKeychain(password)),
- })
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ createAccount: password => dispatch(createNewVaultAndKeychain(password)),
+ })
+ )
)(CreatePasswordScreen)
diff --git a/mascara/src/app/first-time/import-account-screen.js b/mascara/src/app/first-time/import-account-screen.js
index ab0aca0f0..555a26386 100644
--- a/mascara/src/app/first-time/import-account-screen.js
+++ b/mascara/src/app/first-time/import-account-screen.js
@@ -70,10 +70,14 @@ class ImportAccountScreen extends Component {
switch (this.state.selectedOption) {
case OPTIONS.JSON_FILE:
return importNewAccount('JSON File', [ jsonFile, password ])
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
.then(next)
case OPTIONS.PRIVATE_KEY:
default:
return importNewAccount('Private Key', [ privateKey ])
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
.then(next)
}
}
diff --git a/mascara/src/app/first-time/import-seed-phrase-screen.js b/mascara/src/app/first-time/import-seed-phrase-screen.js
index 86f02ceac..5834919de 100644
--- a/mascara/src/app/first-time/import-seed-phrase-screen.js
+++ b/mascara/src/app/first-time/import-seed-phrase-screen.js
@@ -8,16 +8,16 @@ import {
displayWarning,
unMarkPasswordForgotten,
} from '../../../../ui/app/actions'
+import { DEFAULT_ROUTE, INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
class ImportSeedPhraseScreen extends Component {
static propTypes = {
warning: PropTypes.string,
- back: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired,
createNewVaultAndRestore: PropTypes.func.isRequired,
hideWarning: PropTypes.func.isRequired,
displayWarning: PropTypes.func,
leaveImportSeedScreenState: PropTypes.func,
+ history: PropTypes.object,
};
state = {
@@ -64,20 +64,21 @@ class ImportSeedPhraseScreen extends Component {
const { password, seedPhrase } = this.state
const {
createNewVaultAndRestore,
- next,
displayWarning,
leaveImportSeedScreenState,
+ history,
} = this.props
leaveImportSeedScreenState()
createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase))
- .then(next)
+ .then(() => history.push(INITIALIZE_NOTICE_ROUTE))
}
render () {
const { seedPhrase, password, confirmPassword } = this.state
- const { warning } = this.props
- const importDisabled = warning || !seedPhrase || !password || !confirmPassword
+ const { warning, isLoading } = this.props
+ const importDisabled = warning || !seedPhrase || !password || !confirmPassword || isLoading
+
return (
<div className="first-view-main-wrapper">
<div className="first-view-main">
@@ -86,7 +87,7 @@ class ImportSeedPhraseScreen extends Component {
className="import-account__back-button"
onClick={e => {
e.preventDefault()
- this.props.back()
+ this.props.history.goBack()
}}
href="#"
>
@@ -152,7 +153,7 @@ class ImportSeedPhraseScreen extends Component {
}
export default connect(
- ({ appState: { warning } }) => ({ warning }),
+ ({ appState: { warning, isLoading } }) => ({ warning, isLoading }),
dispatch => ({
leaveImportSeedScreenState: () => {
dispatch(unMarkPasswordForgotten())
diff --git a/mascara/src/app/first-time/index.js b/mascara/src/app/first-time/index.js
index 0cc3b4b0e..01e5d67a6 100644
--- a/mascara/src/app/first-time/index.js
+++ b/mascara/src/app/first-time/index.js
@@ -1,17 +1,26 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
+import { withRouter, Switch, Route } from 'react-router-dom'
+import { compose } from 'recompose'
import CreatePasswordScreen from './create-password-screen'
import UniqueImageScreen from './unique-image-screen'
import NoticeScreen from './notice-screen'
-import BackupPhraseScreen from './backup-phrase-screen'
+import BackupPhraseScreen from './seed-screen'
import ImportAccountScreen from './import-account-screen'
import ImportSeedPhraseScreen from './import-seed-phrase-screen'
+import ConfirmSeed from './confirm-seed-screen'
import {
- onboardingBuyEthView,
- unMarkPasswordForgotten,
- showModal,
-} from '../../../../ui/app/actions'
+ INITIALIZE_ROUTE,
+ INITIALIZE_IMPORT_ACCOUNT_ROUTE,
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+ INITIALIZE_CONFIRM_SEED_ROUTE,
+ INITIALIZE_CREATE_PASSWORD_ROUTE,
+} from '../../../../ui/app/routes'
+import WelcomeScreen from '../../../../ui/app/welcome-screen'
class FirstTimeFlow extends Component {
@@ -20,6 +29,10 @@ class FirstTimeFlow extends Component {
seedWords: PropTypes.string,
address: PropTypes.string,
noActiveNotices: PropTypes.bool,
+ goToBuyEtherView: PropTypes.func,
+ isUnlocked: PropTypes.bool,
+ history: PropTypes.object,
+ welcomeScreenSeen: PropTypes.bool,
};
static defaultProps = {
@@ -28,145 +41,53 @@ class FirstTimeFlow extends Component {
noActiveNotices: false,
};
- static SCREEN_TYPE = {
- CREATE_PASSWORD: 'create_password',
- IMPORT_ACCOUNT: 'import_account',
- IMPORT_SEED_PHRASE: 'import_seed_phrase',
- UNIQUE_IMAGE: 'unique_image',
- NOTICE: 'notice',
- BACK_UP_PHRASE: 'back_up_phrase',
- CONFIRM_BACK_UP_PHRASE: 'confirm_back_up_phrase',
- LOADING: 'loading',
- };
-
- constructor (props) {
- super(props)
- this.state = {
- screenType: this.getScreenType(),
- }
- }
-
- setScreenType (screenType) {
- this.setState({ screenType })
- }
-
- getScreenType () {
- const {
- isInitialized,
- seedWords,
- noActiveNotices,
- forgottenPassword,
- } = this.props
- const {SCREEN_TYPE} = FirstTimeFlow
-
- // return SCREEN_TYPE.NOTICE
-
- if (forgottenPassword) {
- return SCREEN_TYPE.IMPORT_SEED_PHRASE
- }
- if (!isInitialized) {
- return SCREEN_TYPE.CREATE_PASSWORD
- }
-
- if (!noActiveNotices) {
- return SCREEN_TYPE.NOTICE
- }
-
- if (seedWords) {
- return SCREEN_TYPE.BACK_UP_PHRASE
- }
- };
-
- renderScreen () {
- const {SCREEN_TYPE} = FirstTimeFlow
- const {
- openBuyEtherModal,
- address,
- restoreCreatePasswordScreen,
- forgottenPassword,
- leaveImportSeedScreenState,
- } = this.props
-
- switch (this.state.screenType) {
- case SCREEN_TYPE.CREATE_PASSWORD:
- return (
- <CreatePasswordScreen
- next={() => this.setScreenType(SCREEN_TYPE.UNIQUE_IMAGE)}
- goToImportAccount={() => this.setScreenType(SCREEN_TYPE.IMPORT_ACCOUNT)}
- goToImportWithSeedPhrase={() => this.setScreenType(SCREEN_TYPE.IMPORT_SEED_PHRASE)}
- />
- )
- case SCREEN_TYPE.IMPORT_ACCOUNT:
- return (
- <ImportAccountScreen
- back={() => this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)}
- next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
- />
- )
- case SCREEN_TYPE.IMPORT_SEED_PHRASE:
- return (
- <ImportSeedPhraseScreen
- back={() => {
- leaveImportSeedScreenState()
- this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)
- }}
- next={() => {
- const newScreenType = forgottenPassword ? null : SCREEN_TYPE.NOTICE
- this.setScreenType(newScreenType)
- }}
- />
- )
- case SCREEN_TYPE.UNIQUE_IMAGE:
- return (
- <UniqueImageScreen
- next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
- />
- )
- case SCREEN_TYPE.NOTICE:
- return (
- <NoticeScreen
- next={() => this.setScreenType(SCREEN_TYPE.BACK_UP_PHRASE)}
- />
- )
- case SCREEN_TYPE.BACK_UP_PHRASE:
- return (
- <BackupPhraseScreen
- next={() => openBuyEtherModal()}
- />
- )
- default:
- return <noscript />
- }
- }
-
render () {
return (
<div className="first-time-flow">
- {this.renderScreen()}
+ <Switch>
+ <Route exact path={INITIALIZE_IMPORT_ACCOUNT_ROUTE} component={ImportAccountScreen} />
+ <Route
+ exact
+ path={INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE}
+ component={ImportSeedPhraseScreen}
+ />
+ <Route exact path={INITIALIZE_UNIQUE_IMAGE_ROUTE} component={UniqueImageScreen} />
+ <Route exact path={INITIALIZE_NOTICE_ROUTE} component={NoticeScreen} />
+ <Route exact path={INITIALIZE_BACKUP_PHRASE_ROUTE} component={BackupPhraseScreen} />
+ <Route exact path={INITIALIZE_CONFIRM_SEED_ROUTE} component={ConfirmSeed} />
+ <Route exact path={INITIALIZE_CREATE_PASSWORD_ROUTE} component={CreatePasswordScreen} />
+ <Route exact path={INITIALIZE_ROUTE} component={WelcomeScreen} />
+ </Switch>
</div>
)
}
-
}
-export default connect(
- ({
- metamask: {
- isInitialized,
- seedWords,
- noActiveNotices,
- selectedAddress,
- forgottenPassword,
- }
- }) => ({
+const mapStateToProps = ({ metamask }) => {
+ const {
+ isInitialized,
+ seedWords,
+ noActiveNotices,
+ selectedAddress,
+ forgottenPassword,
+ isMascara,
+ isUnlocked,
+ welcomeScreenSeen,
+ } = metamask
+
+ return {
+ isMascara,
isInitialized,
seedWords,
noActiveNotices,
address: selectedAddress,
forgottenPassword,
- }),
- dispatch => ({
- leaveImportSeedScreenState: () => dispatch(unMarkPasswordForgotten()),
- openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})),
- })
+ isUnlocked,
+ welcomeScreenSeen,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(mapStateToProps)
)(FirstTimeFlow)
diff --git a/mascara/src/app/first-time/notice-screen.js b/mascara/src/app/first-time/notice-screen.js
index cbd8f9f5b..a449ccfa9 100644
--- a/mascara/src/app/first-time/notice-screen.js
+++ b/mascara/src/app/first-time/notice-screen.js
@@ -1,11 +1,14 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Markdown from 'react-markdown'
-import {connect} from 'react-redux'
+import { connect } from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import debounce from 'lodash.debounce'
-import {markNoticeRead} from '../../../../ui/app/actions'
+import { markNoticeRead } from '../../../../ui/app/actions'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import { INITIALIZE_BACKUP_PHRASE_ROUTE } from '../../../../ui/app/routes'
import LoadingScreen from './loading-screen'
class NoticeScreen extends Component {
@@ -16,8 +19,15 @@ class NoticeScreen extends Component {
date: PropTypes.string,
body: PropTypes.string,
}),
- next: PropTypes.func.isRequired,
+ location: PropTypes.shape({
+ state: PropTypes.shape({
+ next: PropTypes.func.isRequired,
+ }),
+ }),
markNoticeRead: PropTypes.func,
+ history: PropTypes.object,
+ isLoading: PropTypes.bool,
+ noActiveNotices: PropTypes.bool,
};
static defaultProps = {
@@ -29,17 +39,24 @@ class NoticeScreen extends Component {
}
componentDidMount () {
+ if (this.props.noActiveNotices) {
+ this.props.history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
+ }
+
this.onScroll()
}
acceptTerms = () => {
- const { markNoticeRead, lastUnreadNotice, next } = this.props
- const defer = markNoticeRead(lastUnreadNotice)
- .then(() => this.setState({ atBottom: false }))
-
- if ((/terms/gi).test(lastUnreadNotice.title)) {
- defer.then(next)
- }
+ const { markNoticeRead, lastUnreadNotice, history } = this.props
+ markNoticeRead(lastUnreadNotice)
+ .then(hasActiveNotices => {
+ if (!hasActiveNotices) {
+ history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
+ } else {
+ this.setState({ atBottom: false })
+ this.onScroll()
+ }
+ })
}
onScroll = debounce(() => {
@@ -64,27 +81,29 @@ class NoticeScreen extends Component {
isLoading
? <LoadingScreen />
: (
- <div className="first-view-main-wrapper">
- <div className="first-view-main">
- <div
- className="tou"
- onScroll={this.onScroll}
- >
- <Identicon address={address} diameter={70} />
- <div className="tou__title">{title}</div>
- <Markdown
- className="tou__body markdown"
- source={body}
- skipHtml
- />
- <button
- className="first-time-flow__button"
- onClick={atBottom && this.acceptTerms}
- disabled={!atBottom}
+ <div className="first-time-flow">
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div
+ className="tou"
+ onScroll={this.onScroll}
>
- Accept
- </button>
- <Breadcrumbs total={3} currentIndex={2} />
+ <Identicon address={address} diameter={70} />
+ <div className="tou__title">{title}</div>
+ <Markdown
+ className="tou__body markdown"
+ source={body}
+ skipHtml
+ />
+ <button
+ className="first-time-flow__button"
+ onClick={atBottom && this.acceptTerms}
+ disabled={!atBottom}
+ >
+ Accept
+ </button>
+ <Breadcrumbs total={3} currentIndex={2} />
+ </div>
</div>
</div>
</div>
@@ -93,12 +112,24 @@ class NoticeScreen extends Component {
}
}
-export default connect(
- ({ metamask: { selectedAddress, lastUnreadNotice }, appState: { isLoading } }) => ({
- lastUnreadNotice,
+const mapStateToProps = ({ metamask, appState }) => {
+ const { selectedAddress, lastUnreadNotice, noActiveNotices } = metamask
+ const { isLoading } = appState
+
+ return {
address: selectedAddress,
- }),
- dispatch => ({
- markNoticeRead: notice => dispatch(markNoticeRead(notice)),
- })
+ lastUnreadNotice,
+ noActiveNotices,
+ isLoading,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ markNoticeRead: notice => dispatch(markNoticeRead(notice)),
+ })
+ )
)(NoticeScreen)
diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/seed-screen.js
index 6819abcf3..d004be77b 100644
--- a/mascara/src/app/first-time/backup-phrase-screen.js
+++ b/mascara/src/app/first-time/seed-screen.js
@@ -1,13 +1,13 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import {connect} from 'react-redux'
+import { connect } from 'react-redux'
import classnames from 'classnames'
-import shuffle from 'lodash.shuffle'
-import {compose, onlyUpdateForPropTypes} from 'recompose'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import Identicon from '../../../../ui/app/components/identicon'
-import {confirmSeedWords} from '../../../../ui/app/actions'
import Breadcrumbs from './breadcrumbs'
import LoadingScreen from './loading-screen'
+import { DEFAULT_ROUTE, INITIALIZE_CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes'
const LockIcon = props => (
<svg
@@ -36,34 +36,32 @@ const LockIcon = props => (
/>
</g>
</svg>
-);
+)
class BackupPhraseScreen extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
address: PropTypes.string.isRequired,
- seedWords: PropTypes.string.isRequired,
- next: PropTypes.func.isRequired,
- confirmSeedWords: PropTypes.func.isRequired,
+ seedWords: PropTypes.string,
+ history: PropTypes.object,
};
static defaultProps = {
- seedWords: ''
- };
-
- static PAGE = {
- SECRET: 'secret',
- CONFIRM: 'confirm'
- };
+ seedWords: '',
+ }
- constructor(props) {
- const {seedWords} = props
+ constructor (props) {
super(props)
this.state = {
isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.SECRET,
- selectedSeeds: [],
- shuffledSeeds: seedWords && shuffle(seedWords.split(' ')),
+ }
+ }
+
+ componentWillMount () {
+ const { seedWords, history } = this.props
+
+ if (!seedWords) {
+ history.push(DEFAULT_ROUTE)
}
}
@@ -73,7 +71,7 @@ class BackupPhraseScreen extends Component {
return (
<div className="backup-phrase__secret">
<div className={classnames('backup-phrase__secret-words', {
- 'backup-phrase__secret-words--hidden': !isShowingSecret
+ 'backup-phrase__secret-words--hidden': !isShowingSecret,
})}>
{this.props.seedWords}
</div>
@@ -96,6 +94,7 @@ class BackupPhraseScreen extends Component {
renderSecretScreen () {
const { isShowingSecret } = this.state
+ const { history } = this.props
return (
<div className="backup-phrase__content-wrapper">
@@ -124,10 +123,7 @@ class BackupPhraseScreen extends Component {
<div className="backup-phrase__next-button">
<button
className="first-time-flow__button"
- onClick={() => isShowingSecret && this.setState({
- isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.CONFIRM,
- })}
+ onClick={() => isShowingSecret && history.push(INITIALIZE_CONFIRM_SEED_ROUTE)}
disabled={!isShowingSecret}
>
Next
@@ -138,99 +134,6 @@ class BackupPhraseScreen extends Component {
)
}
- renderConfirmationScreen() {
- const { seedWords, confirmSeedWords, next } = this.props;
- const { selectedSeeds, shuffledSeeds } = this.state;
- const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ')
-
- return (
- <div className="backup-phrase__content-wrapper">
- <div>
- <div className="backup-phrase__title">Confirm your Secret Backup Phrase</div>
- <div className="backup-phrase__body-text">
- Please select each phrase in order to make sure it is correct.
- </div>
- <div className="backup-phrase__confirm-secret">
- {selectedSeeds.map(([_, word], i) => (
- <button
- key={i}
- className="backup-phrase__confirm-seed-option"
- >
- {word}
- </button>
- ))}
- </div>
- <div className="backup-phrase__confirm-seed-options">
- {shuffledSeeds.map((word, i) => {
- const isSelected = selectedSeeds
- .filter(([index, seed]) => seed === word && index === i)
- .length
-
- return (
- <button
- key={i}
- className={classnames('backup-phrase__confirm-seed-option', {
- 'backup-phrase__confirm-seed-option--selected': isSelected
- })}
- onClick={() => {
- if (!isSelected) {
- this.setState({
- selectedSeeds: [...selectedSeeds, [i, word]]
- })
- } else {
- this.setState({
- selectedSeeds: selectedSeeds
- .filter(([index, seed]) => !(seed === word && index === i))
- })
- }
- }}
- >
- {word}
- </button>
- )
- })}
- </div>
- <button
- className="first-time-flow__button"
- onClick={() => isValid && confirmSeedWords().then(next)}
- disabled={!isValid}
- >
- Confirm
- </button>
- </div>
- </div>
- )
- }
-
- renderBack () {
- return this.state.page === BackupPhraseScreen.PAGE.CONFIRM
- ? (
- <a
- className="backup-phrase__back-button"
- onClick={e => {
- e.preventDefault()
- this.setState({
- page: BackupPhraseScreen.PAGE.SECRET
- })
- }}
- href="#"
- >
- {`< Back`}
- </a>
- )
- : null
- }
-
- renderContent () {
- switch (this.state.page) {
- case BackupPhraseScreen.PAGE.CONFIRM:
- return this.renderConfirmationScreen()
- case BackupPhraseScreen.PAGE.SECRET:
- default:
- return this.renderSecretScreen()
- }
- }
-
render () {
return this.props.isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
@@ -238,9 +141,8 @@ class BackupPhraseScreen extends Component {
<div className="first-view-main-wrapper">
<div className="first-view-main">
<div className="backup-phrase">
- {this.renderBack()}
<Identicon address={this.props.address} diameter={70} />
- {this.renderContent()}
+ {this.renderSecretScreen()}
</div>
</div>
</div>
@@ -249,15 +151,12 @@ class BackupPhraseScreen extends Component {
}
export default compose(
- onlyUpdateForPropTypes,
+ withRouter,
connect(
({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({
seedWords,
isLoading,
address: selectedAddress,
- }),
- dispatch => ({
- confirmSeedWords: () => dispatch(confirmSeedWords()),
})
)
)(BackupPhraseScreen)
diff --git a/mascara/src/app/first-time/unique-image-screen.js b/mascara/src/app/first-time/unique-image-screen.js
index ede17ee3d..9555e5318 100644
--- a/mascara/src/app/first-time/unique-image-screen.js
+++ b/mascara/src/app/first-time/unique-image-screen.js
@@ -1,13 +1,16 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import {connect} from 'react-redux'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import { INITIALIZE_NOTICE_ROUTE } from '../../../../ui/app/routes'
class UniqueImageScreen extends Component {
static propTypes = {
address: PropTypes.string,
- next: PropTypes.func.isRequired,
+ history: PropTypes.object,
}
render () {
@@ -25,7 +28,7 @@ class UniqueImageScreen extends Component {
</div>
<button
className="first-time-flow__button"
- onClick={this.props.next}
+ onClick={() => this.props.history.push(INITIALIZE_NOTICE_ROUTE)}
>
Next
</button>
@@ -37,8 +40,11 @@ class UniqueImageScreen extends Component {
}
}
-export default connect(
- ({ metamask: { selectedAddress } }) => ({
- address: selectedAddress,
- })
+export default compose(
+ withRouter,
+ connect(
+ ({ metamask: { selectedAddress } }) => ({
+ address: selectedAddress,
+ })
+ )
)(UniqueImageScreen)
diff --git a/notices/archive/notice_2.md b/notices/archive/notice_2.md
index 4cea97b4f..62f368c50 100644
--- a/notices/archive/notice_2.md
+++ b/notices/archive/notice_2.md
@@ -1,6 +1,6 @@
MetaMask is beta software.
-When you log in to MetaMask, your current account is visible to every new site you visit.
+When you log in to MetaMask, your current account's address is visible to every new site you visit. This can be used to look up your account balances of Ether and other tokens.
For your privacy, for now, please sign out of MetaMask when you're done using a site.
diff --git a/notices/notices.json b/notices/notices.json
index ddadea1b0..68201581d 100644
--- a/notices/notices.json
+++ b/notices/notices.json
@@ -1 +1 @@
-[{"read":false,"date":"Thu Feb 09 2017","title":"Terms of Use","body":"# Terms of Use #\n\n**THIS AGREEMENT IS SUBJECT TO BINDING ARBITRATION AND A WAIVER OF CLASS ACTION RIGHTS AS DETAILED IN SECTION 13. PLEASE READ THE AGREEMENT CAREFULLY.**\n\n_Our Terms of Use have been updated as of September 5, 2016_\n\n## 1. Acceptance of Terms ##\n\nMetaMask provides a platform for managing Ethereum (or \"ETH\") accounts, and allowing ordinary websites to interact with the Ethereum blockchain, while keeping the user in control over what transactions they approve, through our website located at[ ](http://metamask.io)[https://metamask.io/](https://metamask.io/) and browser plugin (the \"Site\") — which includes text, images, audio, code and other materials (collectively, the “Content”) and all of the features, and services provided. The Site, and any other features, tools, materials, or other services offered from time to time by MetaMask are referred to here as the “Service.” Please read these Terms of Use (the “Terms” or “Terms of Use”) carefully before using the Service. By using or otherwise accessing the Services, or clicking to accept or agree to these Terms where that option is made available, you (1) accept and agree to these Terms (2) consent to the collection, use, disclosure and other handling of information as described in our Privacy Policy and (3) any additional terms, rules and conditions of participation issued by MetaMask from time to time. If you do not agree to the Terms, then you may not access or use the Content or Services.\n\n## 2. Modification of Terms of Use ##\n\nExcept for Section 13, providing for binding arbitration and waiver of class action rights, MetaMask reserves the right, at its sole discretion, to modify or replace the Terms of Use at any time. The most current version of these Terms will be posted on our Site. You shall be responsible for reviewing and becoming familiar with any such modifications. Use of the Services by you after any modification to the Terms constitutes your acceptance of the Terms of Use as modified.\n\n\n\n## 3. Eligibility ##\n\nYou hereby represent and warrant that you are fully able and competent to enter into the terms, conditions, obligations, affirmations, representations and warranties set forth in these Terms and to abide by and comply with these Terms.\n\nMetaMask is a global platform and by accessing the Content or Services, you are representing and warranting that, you are of the legal age of majority in your jurisdiction as is required to access such Services and Content and enter into arrangements as provided by the Service. You further represent that you are otherwise legally permitted to use the service in your jurisdiction including owning cryptographic tokens of value, and interacting with the Services or Content in any way. You further represent you are responsible for ensuring compliance with the laws of your jurisdiction and acknowledge that MetaMask is not liable for your compliance with such laws.\n\n## 4 Account Password and Security ##\n\nWhen setting up an account within MetaMask, you will be responsible for keeping your own account secrets, which may be a twelve-word seed phrase, an account file, or other locally stored secret information. MetaMask encrypts this information locally with a password you provide, that we never send to our servers. You agree to (a) never use the same password for MetaMask that you have ever used outside of this service; (b) keep your secret information and password confidential and do not share them with anyone else; (c) immediately notify MetaMask of any unauthorized use of your account or breach of security. MetaMask cannot and will not be liable for any loss or damage arising from your failure to comply with this section.\n\n## 5. Representations, Warranties, and Risks ##\n\n### 5.1. Warranty Disclaimer ###\n\nYou expressly understand and agree that your use of the Service is at your sole risk. The Service (including the Service and the Content) are provided on an \"AS IS\" and \"as available\" basis, without warranties of any kind, either express or implied, including, without limitation, implied warranties of merchantability, fitness for a particular purpose or non-infringement. You acknowledge that MetaMask has no control over, and no duty to take any action regarding: which users gain access to or use the Service; what effects the Content may have on you; how you may interpret or use the Content; or what actions you may take as a result of having been exposed to the Content. You release MetaMask from all liability for you having acquired or not acquired Content through the Service. MetaMask makes no representations concerning any Content contained in or accessed through the Service, and MetaMask will not be responsible or liable for the accuracy, copyright compliance, legality or decency of material contained in or accessed through the Service.\n\n### 5.2 Sophistication and Risk of Cryptographic Systems ###\n\nBy utilizing the Service or interacting with the Content or platform in any way, you represent that you understand the inherent risks associated with cryptographic systems; and warrant that you have an understanding of the usage and intricacies of native cryptographic tokens, like Ether (ETH) and Bitcoin (BTC), smart contract based tokens such as those that follow the Ethereum Token Standard (https://github.com/ethereum/EIPs/issues/20), and blockchain-based software systems.\n\n### 5.3 Risk of Regulatory Actions in One or More Jurisdictions ###\n\nMetaMask and ETH could be impacted by one or more regulatory inquiries or regulatory action, which could impede or limit the ability of MetaMask to continue to develop, or which could impede or limit your ability to access or use the Service or Ethereum blockchain.\n\n### 5.4 Risk of Weaknesses or Exploits in the Field of Cryptography ###\n\nYou acknowledge and understand that Cryptography is a progressing field. Advances in code cracking or technical advances such as the development of quantum computers may present risks to cryptocurrencies and Services of Content, which could result in the theft or loss of your cryptographic tokens or property. To the extent possible, MetaMask intends to update the protocol underlying Services to account for any advances in cryptography and to incorporate additional security measures, but does not guarantee or otherwise represent full security of the system. By using the Service or accessing Content, you acknowledge these inherent risks.\n\n### 5.5 Volatility of Crypto Currencies ###\n\nYou understand that Ethereum and other blockchain technologies and associated currencies or tokens are highly volatile due to many factors including but not limited to adoption, speculation, technology and security risks. You also acknowledge that the cost of transacting on such technologies is variable and may increase at any time causing impact to any activities taking place on the Ethereum blockchain. You acknowledge these risks and represent that MetaMask cannot be held liable for such fluctuations or increased costs.\n\n### 5.6 Application Security ###\n\nYou acknowledge that Ethereum applications are code subject to flaws and acknowledge that you are solely responsible for evaluating any code provided by the Services or Content and the trustworthiness of any third-party websites, products, smart-contracts, or Content you access or use through the Service. You further expressly acknowledge and represent that Ethereum applications can be written maliciously or negligently, that MetaMask cannot be held liable for your interaction with such applications and that such applications may cause the loss of property or even identity. This warning and others later provided by MetaMask in no way evidence or represent an on-going duty to alert you to all of the potential risks of utilizing the Service or Content.\n\n## 6. Indemnity ##\n\nYou agree to release and to indemnify, defend and hold harmless MetaMask and its parents, subsidiaries, affiliates and agencies, as well as the officers, directors, employees, shareholders and representatives of any of the foregoing entities, from and against any and all losses, liabilities, expenses, damages, costs (including attorneys’ fees and court costs) claims or actions of any kind whatsoever arising or resulting from your use of the Service, your violation of these Terms of Use, and any of your acts or omissions that implicate publicity rights, defamation or invasion of privacy. MetaMask reserves the right, at its own expense, to assume exclusive defense and control of any matter otherwise subject to indemnification by you and, in such case, you agree to cooperate with MetaMask in the defense of such matter.\n\n## 7. Limitation on liability ##\n\nYOU ACKNOWLEDGE AND AGREE THAT YOU ASSUME FULL RESPONSIBILITY FOR YOUR USE OF THE SITE AND SERVICE. YOU ACKNOWLEDGE AND AGREE THAT ANY INFORMATION YOU SEND OR RECEIVE DURING YOUR USE OF THE SITE AND SERVICE MAY NOT BE SECURE AND MAY BE INTERCEPTED OR LATER ACQUIRED BY UNAUTHORIZED PARTIES. YOU ACKNOWLEDGE AND AGREE THAT YOUR USE OF THE SITE AND SERVICE IS AT YOUR OWN RISK. RECOGNIZING SUCH, YOU UNDERSTAND AND AGREE THAT, TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, NEITHER METAMASK NOR ITS SUPPLIERS OR LICENSORS WILL BE LIABLE TO YOU FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY OR OTHER DAMAGES OF ANY KIND, INCLUDING WITHOUT LIMITATION DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER TANGIBLE OR INTANGIBLE LOSSES OR ANY OTHER DAMAGES BASED ON CONTRACT, TORT, STRICT LIABILITY OR ANY OTHER THEORY (EVEN IF METAMASK HAD BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES), RESULTING FROM THE SITE OR SERVICE; THE USE OR THE INABILITY TO USE THE SITE OR SERVICE; UNAUTHORIZED ACCESS TO OR ALTERATION OF YOUR TRANSMISSIONS OR DATA; STATEMENTS OR CONDUCT OF ANY THIRD PARTY ON THE SITE OR SERVICE; ANY ACTIONS WE TAKE OR FAIL TO TAKE AS A RESULT OF COMMUNICATIONS YOU SEND TO US; HUMAN ERRORS; TECHNICAL MALFUNCTIONS; FAILURES, INCLUDING PUBLIC UTILITY OR TELEPHONE OUTAGES; OMISSIONS, INTERRUPTIONS, LATENCY, DELETIONS OR DEFECTS OF ANY DEVICE OR NETWORK, PROVIDERS, OR SOFTWARE (INCLUDING, BUT NOT LIMITED TO, THOSE THAT DO NOT PERMIT PARTICIPATION IN THE SERVICE); ANY INJURY OR DAMAGE TO COMPUTER EQUIPMENT; INABILITY TO FULLY ACCESS THE SITE OR SERVICE OR ANY OTHER WEBSITE; THEFT, TAMPERING, DESTRUCTION, OR UNAUTHORIZED ACCESS TO, IMAGES OR OTHER CONTENT OF ANY KIND; DATA THAT IS PROCESSED LATE OR INCORRECTLY OR IS INCOMPLETE OR LOST; TYPOGRAPHICAL, PRINTING OR OTHER ERRORS, OR ANY COMBINATION THEREOF; OR ANY OTHER MATTER RELATING TO THE SITE OR SERVICE.\n\nSOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.\n\n## 8. Our Proprietary Rights ##\n\nAll title, ownership and intellectual property rights in and to the Service are owned by MetaMask or its licensors. You acknowledge and agree that the Service contains proprietary and confidential information that is protected by applicable intellectual property and other laws. Except as expressly authorized by MetaMask, you agree not to copy, modify, rent, lease, loan, sell, distribute, perform, display or create derivative works based on the Service, in whole or in part. MetaMask issues a license for MetaMask, found [here](https://github.com/MetaMask/metamask-plugin/blob/master/LICENSE). For information on other licenses utilized in the development of MetaMask, please see our attribution page at: [https://metamask.io/attributions.html](https://metamask.io/attributions.html)\n\n## 9. Links ##\n\nThe Service provides, or third parties may provide, links to other World Wide Web or accessible sites, applications or resources. Because MetaMask has no control over such sites, applications and resources, you acknowledge and agree that MetaMask is not responsible for the availability of such external sites, applications or resources, and does not endorse and is not responsible or liable for any content, advertising, products or other materials on or available from such sites or resources. You further acknowledge and agree that MetaMask shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with use of or reliance on any such content, goods or services available on or through any such site or resource.\n\n## 10. Termination and Suspension ##\n\nMetaMask may terminate or suspend all or part of the Service and your MetaMask access immediately, without prior notice or liability, if you breach any of the terms or conditions of the Terms. Upon termination of your access, your right to use the Service will immediately cease.\n\nThe following provisions of the Terms survive any termination of these Terms: INDEMNITY; WARRANTY DISCLAIMERS; LIMITATION ON LIABILITY; OUR PROPRIETARY RIGHTS; LINKS; TERMINATION; NO THIRD PARTY BENEFICIARIES; BINDING ARBITRATION AND CLASS ACTION WAIVER; GENERAL INFORMATION.\n\n## 11. No Third Party Beneficiaries ##\n\nYou agree that, except as otherwise expressly provided in these Terms, there shall be no third party beneficiaries to the Terms.\n\n## 12. Notice and Procedure For Making Claims of Copyright Infringement ##\n\nIf you believe that your copyright or the copyright of a person on whose behalf you are authorized to act has been infringed, please provide MetaMask’s Copyright Agent a written Notice containing the following information:\n\n· an electronic or physical signature of the person authorized to act on behalf of the owner of the copyright or other intellectual property interest;\n\n· a description of the copyrighted work or other intellectual property that you claim has been infringed;\n\n· a description of where the material that you claim is infringing is located on the Service;\n\n· your address, telephone number, and email address;\n\n· a statement by you that you have a good faith belief that the disputed use is not authorized by the copyright owner, its agent, or the law;\n\n· a statement by you, made under penalty of perjury, that the above information in your Notice is accurate and that you are the copyright or intellectual property owner or authorized to act on the copyright or intellectual property owner's behalf.\n\nMetaMask’s Copyright Agent can be reached at:\n\nEmail: copyright [at] metamask [dot] io\n\nMail:\n\nAttention:\n\nMetaMask Copyright ℅ ConsenSys\n\n49 Bogart Street\n\nBrooklyn, NY 11206\n\n## 13. Binding Arbitration and Class Action Waiver ##\n\nPLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT\n\n### 13.1 Initial Dispute Resolution ###\n\nThe parties shall use their best efforts to engage directly to settle any dispute, claim, question, or disagreement and engage in good faith negotiations which shall be a condition to either party initiating a lawsuit or arbitration.\n\n### 13.2 Binding Arbitration ###\n\nIf the parties do not reach an agreed upon solution within a period of 30 days from the time informal dispute resolution under the Initial Dispute Resolution provision begins, then either party may initiate binding arbitration as the sole means to resolve claims, subject to the terms set forth below. Specifically, all claims arising out of or relating to these Terms (including their formation, performance and breach), the parties’ relationship with each other and/or your use of the Service shall be finally settled by binding arbitration administered by the American Arbitration Association in accordance with the provisions of its Commercial Arbitration Rules and the supplementary procedures for consumer related disputes of the American Arbitration Association (the \"AAA\"), excluding any rules or procedures governing or permitting class actions.\n\nThe arbitrator, and not any federal, state or local court or agency, shall have exclusive authority to resolve all disputes arising out of or relating to the interpretation, applicability, enforceability or formation of these Terms, including, but not limited to any claim that all or any part of these Terms are void or voidable, or whether a claim is subject to arbitration. The arbitrator shall be empowered to grant whatever relief would be available in a court under law or in equity. The arbitrator’s award shall be written, and binding on the parties and may be entered as a judgment in any court of competent jurisdiction.\n\nThe parties understand that, absent this mandatory provision, they would have the right to sue in court and have a jury trial. They further understand that, in some instances, the costs of arbitration could exceed the costs of litigation and the right to discovery may be more limited in arbitration than in court.\n\n### 13.3 Location ###\n\nBinding arbitration shall take place in New York. You agree to submit to the personal jurisdiction of any federal or state court in New York County, New York, in order to compel arbitration, to stay proceedings pending arbitration, or to confirm, modify, vacate or enter judgment on the award entered by the arbitrator.\n\n### 13.4 Class Action Waiver ###\n\nThe parties further agree that any arbitration shall be conducted in their individual capacities only and not as a class action or other representative action, and the parties expressly waive their right to file a class action or seek relief on a class basis. YOU AND METAMASK AGREE THAT EACH MAY BRING CLAIMS AGAINST THE OTHER ONLY IN YOUR OR ITS INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS OR REPRESENTATIVE PROCEEDING. If any court or arbitrator determines that the class action waiver set forth in this paragraph is void or unenforceable for any reason or that an arbitration can proceed on a class basis, then the arbitration provision set forth above shall be deemed null and void in its entirety and the parties shall be deemed to have not agreed to arbitrate disputes.\n\n### 13.5 Exception - Litigation of Intellectual Property and Small Claims Court Claims ###\n\nNotwithstanding the parties' decision to resolve all disputes through arbitration, either party may bring an action in state or federal court to protect its intellectual property rights (\"intellectual property rights\" means patents, copyrights, moral rights, trademarks, and trade secrets, but not privacy or publicity rights). Either party may also seek relief in a small claims court for disputes or claims within the scope of that court’s jurisdiction.\n\n### 13.6 30-Day Right to Opt Out ###\n\nYou have the right to opt-out and not be bound by the arbitration and class action waiver provisions set forth above by sending written notice of your decision to opt-out to the following address: MetaMask ℅ ConsenSys, 49 Bogart Street, Brooklyn NY 11206 and via email at legal-opt@metamask.io. The notice must be sent within 30 days of September 6, 2016 or your first use of the Service, whichever is later, otherwise you shall be bound to arbitrate disputes in accordance with the terms of those paragraphs. If you opt-out of these arbitration provisions, MetaMask also will not be bound by them.\n\n### 13.7 Changes to This Section ###\n\nMetaMask will provide 60-days’ notice of any changes to this section. Changes will become effective on the 60th day, and will apply prospectively only to any claims arising after the 60th day.\n\nFor any dispute not subject to arbitration you and MetaMask agree to submit to the personal and exclusive jurisdiction of and venue in the federal and state courts located in New York, New York. You further agree to accept service of process by mail, and hereby waive any and all jurisdictional and venue defenses otherwise available.\n\nThe Terms and the relationship between you and MetaMask shall be governed by the laws of the State of New York without regard to conflict of law provisions.\n\n## 14. General Information ##\n\n### 14.1 Entire Agreement ###\n\nThese Terms (and any additional terms, rules and conditions of participation that MetaMask may post on the Service) constitute the entire agreement between you and MetaMask with respect to the Service and supersedes any prior agreements, oral or written, between you and MetaMask. In the event of a conflict between these Terms and the additional terms, rules and conditions of participation, the latter will prevail over the Terms to the extent of the conflict.\n\n### 14.2 Waiver and Severability of Terms ###\n\nThe failure of MetaMask to exercise or enforce any right or provision of the Terms shall not constitute a waiver of such right or provision. If any provision of the Terms is found by an arbitrator or court of competent jurisdiction to be invalid, the parties nevertheless agree that the arbitrator or court should endeavor to give effect to the parties' intentions as reflected in the provision, and the other provisions of the Terms remain in full force and effect.\n\n### 14.3 Statute of Limitations ###\n\nYou agree that regardless of any statute or law to the contrary, any claim or cause of action arising out of or related to the use of the Service or the Terms must be filed within one (1) year after such claim or cause of action arose or be forever barred.\n\n### 14.4 Section Titles ###\n\nThe section titles in the Terms are for convenience only and have no legal or contractual effect.\n\n### 14.5 Communications ###\n\nUsers with questions, complaints or claims with respect to the Service may contact us using the relevant contact information set forth above and at communications@metamask.io.\n\n## 15 Related Links ##\n\n**[Terms of Use](https://metamask.io/terms.html)**\n\n**[Privacy](https://metamask.io/privacy.html)**\n\n**[Attributions](https://metamask.io/attributions.html)**\n\n","id":0},{"read":false,"date":"Mon May 08 2017","title":"Privacy Notice","body":"MetaMask is beta software. \n\nWhen you log in to MetaMask, your current account is visible to every new site you visit.\n\nFor your privacy, for now, please sign out of MetaMask when you're done using a site.\n\n","id":2},{"read":false,"date":"Tue Nov 28 2017","title":"Seed Phrase Alert","firstVersion":"<=3.12.0","body":"Please take a moment to [back up your seed phrase again](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up).\n\nMetaMask has become aware of a previous issue where a very small number of users were shown the wrong seed phrase to back up. The only way to protect yourself from this issue, is to back up your seed phrase again now.\n\nYou can follow the guide at this link:\n\n[https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up)\n\nWe have fixed the known issue, but will be issuing ongoing bug bounties to help prevent this kind of problem in the future.\n\nFor more information on this issue, [see this blog post](https://medium.com/metamask/seed-phrase-issue-bounty-awarded-e1986e811021)","id":3}]
+[{"read":false,"date":"Thu Feb 09 2017","title":"Terms of Use","body":"# Terms of Use #\n\n**THIS AGREEMENT IS SUBJECT TO BINDING ARBITRATION AND A WAIVER OF CLASS ACTION RIGHTS AS DETAILED IN SECTION 13. PLEASE READ THE AGREEMENT CAREFULLY.**\n\n_Our Terms of Use have been updated as of September 5, 2016_\n\n## 1. Acceptance of Terms ##\n\nMetaMask provides a platform for managing Ethereum (or \"ETH\") accounts, and allowing ordinary websites to interact with the Ethereum blockchain, while keeping the user in control over what transactions they approve, through our website located at[ ](http://metamask.io)[https://metamask.io/](https://metamask.io/) and browser plugin (the \"Site\") — which includes text, images, audio, code and other materials (collectively, the “Content”) and all of the features, and services provided. The Site, and any other features, tools, materials, or other services offered from time to time by MetaMask are referred to here as the “Service.” Please read these Terms of Use (the “Terms” or “Terms of Use”) carefully before using the Service. By using or otherwise accessing the Services, or clicking to accept or agree to these Terms where that option is made available, you (1) accept and agree to these Terms (2) consent to the collection, use, disclosure and other handling of information as described in our Privacy Policy and (3) any additional terms, rules and conditions of participation issued by MetaMask from time to time. If you do not agree to the Terms, then you may not access or use the Content or Services.\n\n## 2. Modification of Terms of Use ##\n\nExcept for Section 13, providing for binding arbitration and waiver of class action rights, MetaMask reserves the right, at its sole discretion, to modify or replace the Terms of Use at any time. The most current version of these Terms will be posted on our Site. You shall be responsible for reviewing and becoming familiar with any such modifications. Use of the Services by you after any modification to the Terms constitutes your acceptance of the Terms of Use as modified.\n\n\n\n## 3. Eligibility ##\n\nYou hereby represent and warrant that you are fully able and competent to enter into the terms, conditions, obligations, affirmations, representations and warranties set forth in these Terms and to abide by and comply with these Terms.\n\nMetaMask is a global platform and by accessing the Content or Services, you are representing and warranting that, you are of the legal age of majority in your jurisdiction as is required to access such Services and Content and enter into arrangements as provided by the Service. You further represent that you are otherwise legally permitted to use the service in your jurisdiction including owning cryptographic tokens of value, and interacting with the Services or Content in any way. You further represent you are responsible for ensuring compliance with the laws of your jurisdiction and acknowledge that MetaMask is not liable for your compliance with such laws.\n\n## 4 Account Password and Security ##\n\nWhen setting up an account within MetaMask, you will be responsible for keeping your own account secrets, which may be a twelve-word seed phrase, an account file, or other locally stored secret information. MetaMask encrypts this information locally with a password you provide, that we never send to our servers. You agree to (a) never use the same password for MetaMask that you have ever used outside of this service; (b) keep your secret information and password confidential and do not share them with anyone else; (c) immediately notify MetaMask of any unauthorized use of your account or breach of security. MetaMask cannot and will not be liable for any loss or damage arising from your failure to comply with this section.\n\n## 5. Representations, Warranties, and Risks ##\n\n### 5.1. Warranty Disclaimer ###\n\nYou expressly understand and agree that your use of the Service is at your sole risk. The Service (including the Service and the Content) are provided on an \"AS IS\" and \"as available\" basis, without warranties of any kind, either express or implied, including, without limitation, implied warranties of merchantability, fitness for a particular purpose or non-infringement. You acknowledge that MetaMask has no control over, and no duty to take any action regarding: which users gain access to or use the Service; what effects the Content may have on you; how you may interpret or use the Content; or what actions you may take as a result of having been exposed to the Content. You release MetaMask from all liability for you having acquired or not acquired Content through the Service. MetaMask makes no representations concerning any Content contained in or accessed through the Service, and MetaMask will not be responsible or liable for the accuracy, copyright compliance, legality or decency of material contained in or accessed through the Service.\n\n### 5.2 Sophistication and Risk of Cryptographic Systems ###\n\nBy utilizing the Service or interacting with the Content or platform in any way, you represent that you understand the inherent risks associated with cryptographic systems; and warrant that you have an understanding of the usage and intricacies of native cryptographic tokens, like Ether (ETH) and Bitcoin (BTC), smart contract based tokens such as those that follow the Ethereum Token Standard (https://github.com/ethereum/EIPs/issues/20), and blockchain-based software systems.\n\n### 5.3 Risk of Regulatory Actions in One or More Jurisdictions ###\n\nMetaMask and ETH could be impacted by one or more regulatory inquiries or regulatory action, which could impede or limit the ability of MetaMask to continue to develop, or which could impede or limit your ability to access or use the Service or Ethereum blockchain.\n\n### 5.4 Risk of Weaknesses or Exploits in the Field of Cryptography ###\n\nYou acknowledge and understand that Cryptography is a progressing field. Advances in code cracking or technical advances such as the development of quantum computers may present risks to cryptocurrencies and Services of Content, which could result in the theft or loss of your cryptographic tokens or property. To the extent possible, MetaMask intends to update the protocol underlying Services to account for any advances in cryptography and to incorporate additional security measures, but does not guarantee or otherwise represent full security of the system. By using the Service or accessing Content, you acknowledge these inherent risks.\n\n### 5.5 Volatility of Crypto Currencies ###\n\nYou understand that Ethereum and other blockchain technologies and associated currencies or tokens are highly volatile due to many factors including but not limited to adoption, speculation, technology and security risks. You also acknowledge that the cost of transacting on such technologies is variable and may increase at any time causing impact to any activities taking place on the Ethereum blockchain. You acknowledge these risks and represent that MetaMask cannot be held liable for such fluctuations or increased costs.\n\n### 5.6 Application Security ###\n\nYou acknowledge that Ethereum applications are code subject to flaws and acknowledge that you are solely responsible for evaluating any code provided by the Services or Content and the trustworthiness of any third-party websites, products, smart-contracts, or Content you access or use through the Service. You further expressly acknowledge and represent that Ethereum applications can be written maliciously or negligently, that MetaMask cannot be held liable for your interaction with such applications and that such applications may cause the loss of property or even identity. This warning and others later provided by MetaMask in no way evidence or represent an on-going duty to alert you to all of the potential risks of utilizing the Service or Content.\n\n## 6. Indemnity ##\n\nYou agree to release and to indemnify, defend and hold harmless MetaMask and its parents, subsidiaries, affiliates and agencies, as well as the officers, directors, employees, shareholders and representatives of any of the foregoing entities, from and against any and all losses, liabilities, expenses, damages, costs (including attorneys’ fees and court costs) claims or actions of any kind whatsoever arising or resulting from your use of the Service, your violation of these Terms of Use, and any of your acts or omissions that implicate publicity rights, defamation or invasion of privacy. MetaMask reserves the right, at its own expense, to assume exclusive defense and control of any matter otherwise subject to indemnification by you and, in such case, you agree to cooperate with MetaMask in the defense of such matter.\n\n## 7. Limitation on liability ##\n\nYOU ACKNOWLEDGE AND AGREE THAT YOU ASSUME FULL RESPONSIBILITY FOR YOUR USE OF THE SITE AND SERVICE. YOU ACKNOWLEDGE AND AGREE THAT ANY INFORMATION YOU SEND OR RECEIVE DURING YOUR USE OF THE SITE AND SERVICE MAY NOT BE SECURE AND MAY BE INTERCEPTED OR LATER ACQUIRED BY UNAUTHORIZED PARTIES. YOU ACKNOWLEDGE AND AGREE THAT YOUR USE OF THE SITE AND SERVICE IS AT YOUR OWN RISK. RECOGNIZING SUCH, YOU UNDERSTAND AND AGREE THAT, TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, NEITHER METAMASK NOR ITS SUPPLIERS OR LICENSORS WILL BE LIABLE TO YOU FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY OR OTHER DAMAGES OF ANY KIND, INCLUDING WITHOUT LIMITATION DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER TANGIBLE OR INTANGIBLE LOSSES OR ANY OTHER DAMAGES BASED ON CONTRACT, TORT, STRICT LIABILITY OR ANY OTHER THEORY (EVEN IF METAMASK HAD BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES), RESULTING FROM THE SITE OR SERVICE; THE USE OR THE INABILITY TO USE THE SITE OR SERVICE; UNAUTHORIZED ACCESS TO OR ALTERATION OF YOUR TRANSMISSIONS OR DATA; STATEMENTS OR CONDUCT OF ANY THIRD PARTY ON THE SITE OR SERVICE; ANY ACTIONS WE TAKE OR FAIL TO TAKE AS A RESULT OF COMMUNICATIONS YOU SEND TO US; HUMAN ERRORS; TECHNICAL MALFUNCTIONS; FAILURES, INCLUDING PUBLIC UTILITY OR TELEPHONE OUTAGES; OMISSIONS, INTERRUPTIONS, LATENCY, DELETIONS OR DEFECTS OF ANY DEVICE OR NETWORK, PROVIDERS, OR SOFTWARE (INCLUDING, BUT NOT LIMITED TO, THOSE THAT DO NOT PERMIT PARTICIPATION IN THE SERVICE); ANY INJURY OR DAMAGE TO COMPUTER EQUIPMENT; INABILITY TO FULLY ACCESS THE SITE OR SERVICE OR ANY OTHER WEBSITE; THEFT, TAMPERING, DESTRUCTION, OR UNAUTHORIZED ACCESS TO, IMAGES OR OTHER CONTENT OF ANY KIND; DATA THAT IS PROCESSED LATE OR INCORRECTLY OR IS INCOMPLETE OR LOST; TYPOGRAPHICAL, PRINTING OR OTHER ERRORS, OR ANY COMBINATION THEREOF; OR ANY OTHER MATTER RELATING TO THE SITE OR SERVICE.\n\nSOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES. ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.\n\n## 8. Our Proprietary Rights ##\n\nAll title, ownership and intellectual property rights in and to the Service are owned by MetaMask or its licensors. You acknowledge and agree that the Service contains proprietary and confidential information that is protected by applicable intellectual property and other laws. Except as expressly authorized by MetaMask, you agree not to copy, modify, rent, lease, loan, sell, distribute, perform, display or create derivative works based on the Service, in whole or in part. MetaMask issues a license for MetaMask, found [here](https://github.com/MetaMask/metamask-plugin/blob/master/LICENSE). For information on other licenses utilized in the development of MetaMask, please see our attribution page at: [https://metamask.io/attributions.html](https://metamask.io/attributions.html)\n\n## 9. Links ##\n\nThe Service provides, or third parties may provide, links to other World Wide Web or accessible sites, applications or resources. Because MetaMask has no control over such sites, applications and resources, you acknowledge and agree that MetaMask is not responsible for the availability of such external sites, applications or resources, and does not endorse and is not responsible or liable for any content, advertising, products or other materials on or available from such sites or resources. You further acknowledge and agree that MetaMask shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with use of or reliance on any such content, goods or services available on or through any such site or resource.\n\n## 10. Termination and Suspension ##\n\nMetaMask may terminate or suspend all or part of the Service and your MetaMask access immediately, without prior notice or liability, if you breach any of the terms or conditions of the Terms. Upon termination of your access, your right to use the Service will immediately cease.\n\nThe following provisions of the Terms survive any termination of these Terms: INDEMNITY; WARRANTY DISCLAIMERS; LIMITATION ON LIABILITY; OUR PROPRIETARY RIGHTS; LINKS; TERMINATION; NO THIRD PARTY BENEFICIARIES; BINDING ARBITRATION AND CLASS ACTION WAIVER; GENERAL INFORMATION.\n\n## 11. No Third Party Beneficiaries ##\n\nYou agree that, except as otherwise expressly provided in these Terms, there shall be no third party beneficiaries to the Terms.\n\n## 12. Notice and Procedure For Making Claims of Copyright Infringement ##\n\nIf you believe that your copyright or the copyright of a person on whose behalf you are authorized to act has been infringed, please provide MetaMask’s Copyright Agent a written Notice containing the following information:\n\n· an electronic or physical signature of the person authorized to act on behalf of the owner of the copyright or other intellectual property interest;\n\n· a description of the copyrighted work or other intellectual property that you claim has been infringed;\n\n· a description of where the material that you claim is infringing is located on the Service;\n\n· your address, telephone number, and email address;\n\n· a statement by you that you have a good faith belief that the disputed use is not authorized by the copyright owner, its agent, or the law;\n\n· a statement by you, made under penalty of perjury, that the above information in your Notice is accurate and that you are the copyright or intellectual property owner or authorized to act on the copyright or intellectual property owner's behalf.\n\nMetaMask’s Copyright Agent can be reached at:\n\nEmail: copyright [at] metamask [dot] io\n\nMail:\n\nAttention:\n\nMetaMask Copyright ℅ ConsenSys\n\n49 Bogart Street\n\nBrooklyn, NY 11206\n\n## 13. Binding Arbitration and Class Action Waiver ##\n\nPLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT\n\n### 13.1 Initial Dispute Resolution ###\n\nThe parties shall use their best efforts to engage directly to settle any dispute, claim, question, or disagreement and engage in good faith negotiations which shall be a condition to either party initiating a lawsuit or arbitration.\n\n### 13.2 Binding Arbitration ###\n\nIf the parties do not reach an agreed upon solution within a period of 30 days from the time informal dispute resolution under the Initial Dispute Resolution provision begins, then either party may initiate binding arbitration as the sole means to resolve claims, subject to the terms set forth below. Specifically, all claims arising out of or relating to these Terms (including their formation, performance and breach), the parties’ relationship with each other and/or your use of the Service shall be finally settled by binding arbitration administered by the American Arbitration Association in accordance with the provisions of its Commercial Arbitration Rules and the supplementary procedures for consumer related disputes of the American Arbitration Association (the \"AAA\"), excluding any rules or procedures governing or permitting class actions.\n\nThe arbitrator, and not any federal, state or local court or agency, shall have exclusive authority to resolve all disputes arising out of or relating to the interpretation, applicability, enforceability or formation of these Terms, including, but not limited to any claim that all or any part of these Terms are void or voidable, or whether a claim is subject to arbitration. The arbitrator shall be empowered to grant whatever relief would be available in a court under law or in equity. The arbitrator’s award shall be written, and binding on the parties and may be entered as a judgment in any court of competent jurisdiction.\n\nThe parties understand that, absent this mandatory provision, they would have the right to sue in court and have a jury trial. They further understand that, in some instances, the costs of arbitration could exceed the costs of litigation and the right to discovery may be more limited in arbitration than in court.\n\n### 13.3 Location ###\n\nBinding arbitration shall take place in New York. You agree to submit to the personal jurisdiction of any federal or state court in New York County, New York, in order to compel arbitration, to stay proceedings pending arbitration, or to confirm, modify, vacate or enter judgment on the award entered by the arbitrator.\n\n### 13.4 Class Action Waiver ###\n\nThe parties further agree that any arbitration shall be conducted in their individual capacities only and not as a class action or other representative action, and the parties expressly waive their right to file a class action or seek relief on a class basis. YOU AND METAMASK AGREE THAT EACH MAY BRING CLAIMS AGAINST THE OTHER ONLY IN YOUR OR ITS INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS OR REPRESENTATIVE PROCEEDING. If any court or arbitrator determines that the class action waiver set forth in this paragraph is void or unenforceable for any reason or that an arbitration can proceed on a class basis, then the arbitration provision set forth above shall be deemed null and void in its entirety and the parties shall be deemed to have not agreed to arbitrate disputes.\n\n### 13.5 Exception - Litigation of Intellectual Property and Small Claims Court Claims ###\n\nNotwithstanding the parties' decision to resolve all disputes through arbitration, either party may bring an action in state or federal court to protect its intellectual property rights (\"intellectual property rights\" means patents, copyrights, moral rights, trademarks, and trade secrets, but not privacy or publicity rights). Either party may also seek relief in a small claims court for disputes or claims within the scope of that court’s jurisdiction.\n\n### 13.6 30-Day Right to Opt Out ###\n\nYou have the right to opt-out and not be bound by the arbitration and class action waiver provisions set forth above by sending written notice of your decision to opt-out to the following address: MetaMask ℅ ConsenSys, 49 Bogart Street, Brooklyn NY 11206 and via email at legal-opt@metamask.io. The notice must be sent within 30 days of September 6, 2016 or your first use of the Service, whichever is later, otherwise you shall be bound to arbitrate disputes in accordance with the terms of those paragraphs. If you opt-out of these arbitration provisions, MetaMask also will not be bound by them.\n\n### 13.7 Changes to This Section ###\n\nMetaMask will provide 60-days’ notice of any changes to this section. Changes will become effective on the 60th day, and will apply prospectively only to any claims arising after the 60th day.\n\nFor any dispute not subject to arbitration you and MetaMask agree to submit to the personal and exclusive jurisdiction of and venue in the federal and state courts located in New York, New York. You further agree to accept service of process by mail, and hereby waive any and all jurisdictional and venue defenses otherwise available.\n\nThe Terms and the relationship between you and MetaMask shall be governed by the laws of the State of New York without regard to conflict of law provisions.\n\n## 14. General Information ##\n\n### 14.1 Entire Agreement ###\n\nThese Terms (and any additional terms, rules and conditions of participation that MetaMask may post on the Service) constitute the entire agreement between you and MetaMask with respect to the Service and supersedes any prior agreements, oral or written, between you and MetaMask. In the event of a conflict between these Terms and the additional terms, rules and conditions of participation, the latter will prevail over the Terms to the extent of the conflict.\n\n### 14.2 Waiver and Severability of Terms ###\n\nThe failure of MetaMask to exercise or enforce any right or provision of the Terms shall not constitute a waiver of such right or provision. If any provision of the Terms is found by an arbitrator or court of competent jurisdiction to be invalid, the parties nevertheless agree that the arbitrator or court should endeavor to give effect to the parties' intentions as reflected in the provision, and the other provisions of the Terms remain in full force and effect.\n\n### 14.3 Statute of Limitations ###\n\nYou agree that regardless of any statute or law to the contrary, any claim or cause of action arising out of or related to the use of the Service or the Terms must be filed within one (1) year after such claim or cause of action arose or be forever barred.\n\n### 14.4 Section Titles ###\n\nThe section titles in the Terms are for convenience only and have no legal or contractual effect.\n\n### 14.5 Communications ###\n\nUsers with questions, complaints or claims with respect to the Service may contact us using the relevant contact information set forth above and at communications@metamask.io.\n\n## 15 Related Links ##\n\n**[Terms of Use](https://metamask.io/terms.html)**\n\n**[Privacy](https://metamask.io/privacy.html)**\n\n**[Attributions](https://metamask.io/attributions.html)**\n\n","id":0},{"read":false,"date":"Mon May 08 2017","title":"Privacy Notice","body":"MetaMask is beta software. \n\nWhen you log in to MetaMask, your current account's address is visible to every new site you visit. This can be used to look up your account balances of Ether and other tokens.\n\nFor your privacy, for now, please sign out of MetaMask when you're done using a site.\n\n","id":2},{"read":false,"date":"Tue Nov 28 2017","title":"Seed Phrase Alert","firstVersion":"<=3.12.0","body":"Please take a moment to [back up your seed phrase again](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up).\n\nMetaMask has become aware of a previous issue where a very small number of users were shown the wrong seed phrase to back up. The only way to protect yourself from this issue, is to back up your seed phrase again now.\n\nYou can follow the guide at this link:\n\n[https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up](https://support.metamask.io/kb/article/28-abbu-always-be-backed-up-how-to-make-sure-your-12-word-metamask-seed-phrase-is-backed-up)\n\nWe have fixed the known issue, but will be issuing ongoing bug bounties to help prevent this kind of problem in the future.\n\nFor more information on this issue, [see this blog post](https://medium.com/metamask/seed-phrase-issue-bounty-awarded-e1986e811021)","id":3}]
diff --git a/old-ui/app/accounts/import/json.js b/old-ui/app/accounts/import/json.js
index 3ee3b95df..8388f17a7 100644
--- a/old-ui/app/accounts/import/json.js
+++ b/old-ui/app/accounts/import/json.js
@@ -96,6 +96,8 @@ class JsonImportSubview extends Component {
}
this.props.importNewAccount([ fileContents, password ])
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
}
}
diff --git a/old-ui/app/accounts/import/private-key.js b/old-ui/app/accounts/import/private-key.js
index 105191105..92e42549d 100644
--- a/old-ui/app/accounts/import/private-key.js
+++ b/old-ui/app/accounts/import/private-key.js
@@ -64,4 +64,6 @@ PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ]))
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
}
diff --git a/old-ui/app/app.js b/old-ui/app/app.js
index 37611987f..3aa845b3a 100644
--- a/old-ui/app/app.js
+++ b/old-ui/app/app.js
@@ -3,6 +3,7 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('../../ui/app/actions')
+const log = require('loglevel')
// mascara
const MascaraFirstTime = require('../../mascara/src/app/first-time').default
const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
@@ -34,7 +35,7 @@ const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
-const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
module.exports = connect(mapStateToProps)(App)
diff --git a/old-ui/app/components/buy-button-subview.js b/old-ui/app/components/buy-button-subview.js
index 56d173839..8bb73ae3e 100644
--- a/old-ui/app/components/buy-button-subview.js
+++ b/old-ui/app/components/buy-button-subview.js
@@ -8,7 +8,7 @@ const ShapeshiftForm = require('./shapeshift-form')
const Loading = require('./loading')
const AccountPanel = require('./account-panel')
const RadioList = require('./custom-radio-list')
-const networkNames = require('../../../app/scripts/config.js').networkNames
+const { getNetworkDisplayName } = require('../../../app/scripts/controllers/network/util')
module.exports = connect(mapStateToProps)(BuyButtonSubview)
@@ -142,7 +142,7 @@ BuyButtonSubview.prototype.primarySubview = function () {
case '3':
case '4':
case '42':
- const networkName = networkNames[network]
+ const networkName = getNetworkDisplayName(network)
const label = `${networkName} Test Faucet`
return (
h('div.flex-column', {
diff --git a/old-ui/app/components/ens-input.js b/old-ui/app/components/ens-input.js
index c85a23514..d09c30644 100644
--- a/old-ui/app/components/ens-input.js
+++ b/old-ui/app/components/ens-input.js
@@ -8,6 +8,7 @@ const ENS = require('ethjs-ens')
const networkMap = require('ethjs-ens/lib/network-map.json')
const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
+const log = require('loglevel')
module.exports = EnsInput
diff --git a/old-ui/app/components/pending-tx.js b/old-ui/app/components/pending-tx.js
index 7f63d9fdf..c8132539c 100644
--- a/old-ui/app/components/pending-tx.js
+++ b/old-ui/app/components/pending-tx.js
@@ -3,6 +3,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const actions = require('../../../ui/app/actions')
const clone = require('clone')
+const log = require('loglevel')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
@@ -15,8 +16,7 @@ const addressSummary = util.addressSummary
const nameForAddress = require('../../lib/contract-namer')
const BNInput = require('./bn-as-decimal-input')
-// corresponds with 0.1 GWEI
-const MIN_GAS_PRICE_BN = new BN('100000000')
+const MIN_GAS_PRICE_BN = new BN('0')
const MIN_GAS_LIMIT_BN = new BN('21000')
module.exports = PendingTx
diff --git a/old-ui/app/components/shapeshift-form.js b/old-ui/app/components/shapeshift-form.js
index a54987c04..97068db0a 100644
--- a/old-ui/app/components/shapeshift-form.js
+++ b/old-ui/app/components/shapeshift-form.js
@@ -138,7 +138,7 @@ ShapeshiftForm.prototype.renderMain = function () {
width: '229px',
height: '82px',
},
- }, this.props.warning)
+ }, this.props.warning + '')
: this.renderInfo(),
this.renderRefundAddressForCoin(coin),
diff --git a/old-ui/app/components/token-list.js b/old-ui/app/components/token-list.js
index 149733b89..e20594b61 100644
--- a/old-ui/app/components/token-list.js
+++ b/old-ui/app/components/token-list.js
@@ -3,6 +3,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const TokenTracker = require('eth-token-tracker')
const TokenCell = require('./token-cell.js')
+const log = require('loglevel')
module.exports = TokenList
diff --git a/old-ui/app/conf-tx.js b/old-ui/app/conf-tx.js
index 1bb8eb97c..dc1dc0538 100644
--- a/old-ui/app/conf-tx.js
+++ b/old-ui/app/conf-tx.js
@@ -6,7 +6,9 @@ const actions = require('../../ui/app/actions')
const NetworkIndicator = require('./components/network')
const LoadingIndicator = require('./components/loading')
const txHelper = require('../lib/tx-helper')
-const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
+const log = require('loglevel')
+const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../app/scripts/lib/enums')
+const { getEnvironmentType } = require('../../app/scripts/lib/util')
const PendingTx = require('./components/pending-tx')
const PendingMsg = require('./components/pending-msg')
@@ -50,7 +52,7 @@ ConfirmTxScreen.prototype.render = function () {
var txData = unconfTxList[props.index] || {}
var txParams = txData.params || {}
- var isNotification = isPopupOrNotification() === 'notification'
+ var isNotification = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION
log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
if (unconfTxList.length === 0) return h(Loading, { isLoading: true })
diff --git a/old-ui/app/util.js b/old-ui/app/util.js
index 3f8b4dcc3..962832ce7 100644
--- a/old-ui/app/util.js
+++ b/old-ui/app/util.js
@@ -231,6 +231,7 @@ function exportAsFile (filename, data) {
window.navigator.msSaveBlob(blob, filename)
} else {
const elem = window.document.createElement('a')
+ elem.target = '_blank'
elem.href = window.URL.createObjectURL(blob)
elem.download = filename
document.body.appendChild(elem)
diff --git a/old-ui/lib/tx-helper.js b/old-ui/lib/tx-helper.js
index de3f00d2d..0a6f55a63 100644
--- a/old-ui/lib/tx-helper.js
+++ b/old-ui/lib/tx-helper.js
@@ -1,4 +1,5 @@
const valuesFor = require('../app/util').valuesFor
+const log = require('loglevel')
module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network) {
log.debug('tx-helper called with params:')
diff --git a/package-lock.json b/package-lock.json
index 2c1589bec..11e79ff3d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -344,6 +344,11 @@
"negotiator": "0.6.1"
}
},
+ "accounting": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/accounting/-/accounting-0.4.1.tgz",
+ "integrity": "sha1-h91BA+/39EYPHhhvXGd+1s9WaIM="
+ },
"acorn": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
@@ -414,6 +419,63 @@
"dev": true,
"optional": true
},
+ "adjust-sourcemap-loader": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz",
+ "integrity": "sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ==",
+ "dev": true,
+ "requires": {
+ "assert": "1.4.1",
+ "camelcase": "1.2.1",
+ "loader-utils": "1.1.0",
+ "lodash.assign": "4.2.0",
+ "lodash.defaults": "3.1.2",
+ "object-path": "0.9.2",
+ "regex-parser": "2.2.9"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ },
+ "lodash.defaults": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz",
+ "integrity": "sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw=",
+ "dev": true,
+ "requires": {
+ "lodash.assign": "3.2.0",
+ "lodash.restparam": "3.6.1"
+ },
+ "dependencies": {
+ "lodash.assign": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz",
+ "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=",
+ "dev": true,
+ "requires": {
+ "lodash._baseassign": "3.2.0",
+ "lodash._createassigner": "3.1.1",
+ "lodash.keys": "3.1.2"
+ }
+ }
+ }
+ }
+ }
+ },
"aes-js": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz",
@@ -469,6 +531,11 @@
"repeat-string": "1.6.1"
}
},
+ "alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM="
+ },
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
@@ -632,6 +699,11 @@
"sprintf-js": "1.0.3"
}
},
+ "argsarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz",
+ "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs="
+ },
"arr-diff": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
@@ -645,7 +717,7 @@
"resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
"integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
"requires": {
- "make-iterator": "1.0.0"
+ "make-iterator": "1.0.1"
}
},
"arr-flatten": {
@@ -658,7 +730,7 @@
"resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
"integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
"requires": {
- "make-iterator": "1.0.0"
+ "make-iterator": "1.0.1"
}
},
"arr-union": {
@@ -903,8 +975,7 @@
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
- "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
- "dev": true
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
"async-reduce": {
"version": "0.0.1",
@@ -2075,6 +2146,14 @@
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
"dev": true
},
+ "backoff": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz",
+ "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=",
+ "requires": {
+ "precond": "0.2.3"
+ }
+ },
"bail": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.2.tgz",
@@ -2500,8 +2579,7 @@
"browser-stdout": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
- "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
- "dev": true
+ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8="
},
"browser-unpack": {
"version": "1.2.0",
@@ -2800,29 +2878,56 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz",
"integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==",
- "dev": true,
"requires": {
"base64-js": "1.2.1",
"ieee754": "1.1.8"
}
},
+ "buffer-alloc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz",
+ "integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=",
+ "requires": {
+ "buffer-alloc-unsafe": "0.1.1",
+ "buffer-fill": "0.1.1"
+ }
+ },
+ "buffer-alloc-unsafe": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz",
+ "integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo="
+ },
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
- "dev": true
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
},
"buffer-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
"integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74="
},
+ "buffer-fill": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.1.tgz",
+ "integrity": "sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q=="
+ },
+ "buffer-from": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz",
+ "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg=="
+ },
"buffer-more-ints": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz",
"integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=",
"dev": true
},
+ "buffer-to-arraybuffer": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
+ "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo="
+ },
"buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
@@ -2864,6 +2969,23 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
+ "bytewise": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz",
+ "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=",
+ "requires": {
+ "bytewise-core": "1.2.3",
+ "typewise": "1.0.3"
+ }
+ },
+ "bytewise-core": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz",
+ "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=",
+ "requires": {
+ "typewise-core": "1.2.0"
+ }
+ },
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -2916,6 +3038,25 @@
"integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=",
"dev": true
},
+ "cachedown": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz",
+ "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=",
+ "requires": {
+ "abstract-leveldown": "2.6.3",
+ "lru-cache": "3.2.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+ "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
+ "requires": {
+ "pseudomap": "1.0.2"
+ }
+ }
+ }
+ },
"caller-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
@@ -2956,11 +3097,32 @@
}
}
},
+ "caniuse-api": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
+ "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000808",
+ "lodash.memoize": "4.1.2",
+ "lodash.uniq": "4.5.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "requires": {
+ "caniuse-db": "1.0.30000808",
+ "electron-to-chromium": "1.3.30"
+ }
+ }
+ }
+ },
"caniuse-db": {
"version": "1.0.30000808",
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000808.tgz",
- "integrity": "sha1-MN/YMAnVcE8C3/s3clBo7RKjZrs=",
- "dev": true
+ "integrity": "sha1-MN/YMAnVcE8C3/s3clBo7RKjZrs="
},
"caniuse-lite": {
"version": "1.0.30000786",
@@ -2972,6 +3134,15 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
+ "catharsis": {
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
+ "integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=",
+ "dev": true,
+ "requires": {
+ "underscore-contrib": "0.3.0"
+ }
+ },
"center-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
@@ -3088,7 +3259,7 @@
"requires": {
"anymatch": "1.3.2",
"async-each": "1.0.1",
- "fsevents": "1.1.3",
+ "fsevents": "1.2.2",
"glob-parent": "2.0.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -3124,6 +3295,14 @@
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A=="
},
+ "clap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
+ "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
+ "requires": {
+ "chalk": "1.1.3"
+ }
+ },
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -3247,6 +3426,32 @@
}
}
},
+ "cli-table2": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz",
+ "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=",
+ "dev": true,
+ "requires": {
+ "colors": "1.2.3",
+ "lodash": "3.10.1",
+ "string-width": "1.0.2"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.3.tgz",
+ "integrity": "sha512-qTfM2pNFeMZcLvf/RbrVAzDEVttZjFhaApfx9dplNjvHSX88Ui66zBRb/4YGob/xUWxDceirgoC1lT676asfCQ==",
+ "dev": true,
+ "optional": true
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
"cli-truncate": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
@@ -3290,6 +3495,35 @@
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg="
},
+ "clone-deep": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
+ "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
+ "dev": true,
+ "requires": {
+ "for-own": "1.0.0",
+ "is-plain-object": "2.0.4",
+ "kind-of": "6.0.2",
+ "shallow-clone": "1.0.0"
+ },
+ "dependencies": {
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
"clone-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.0.tgz",
@@ -3329,6 +3563,14 @@
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
+ "coa": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
+ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
+ "requires": {
+ "q": "1.5.1"
+ }
+ },
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -3362,7 +3604,7 @@
"requires": {
"arr-map": "2.0.2",
"for-own": "1.0.0",
- "make-iterator": "1.0.0"
+ "make-iterator": "1.0.1"
},
"dependencies": {
"for-own": {
@@ -3504,6 +3746,23 @@
}
}
},
+ "colormin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
+ "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
+ "requires": {
+ "color": "0.11.4",
+ "css-color-names": "0.0.4",
+ "has": "1.0.1"
+ },
+ "dependencies": {
+ "css-color-names": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+ "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA="
+ }
+ }
+ },
"colors": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
@@ -3534,6 +3793,14 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
"integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8="
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
}
}
},
@@ -3727,9 +3994,9 @@
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
},
"copy-props": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.1.tgz",
- "integrity": "sha1-Zl/DIEbKhKiYq6o8WUXn8kjMugA=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.2.tgz",
+ "integrity": "sha512-/W7IE8h4Zj1jdyf26YhdEjTS/xO42ltxtlH6B9+rmFNeXO+LL7KhzqqJdKJUwwO+4ZZ4IRw7rFhm8VEw95T25A==",
"requires": {
"each-props": "1.3.1",
"is-plain-object": "2.0.4"
@@ -3753,6 +4020,15 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
+ "cors": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
+ "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "vary": "1.1.2"
+ }
+ },
"cosmiconfig": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
@@ -3834,6 +4110,22 @@
"is-windows": "1.0.2"
}
},
+ "cross-fetch": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.1.0.tgz",
+ "integrity": "sha512-FTIt2WK44RiafWQ62xIvd+oBoVd392abh1lF872trLlA74JCR1s4oTHlixwoIKy44ehn8WbQ0Ds2P16sw7ZQxg==",
+ "requires": {
+ "node-fetch": "2.1.1",
+ "whatwg-fetch": "2.0.3"
+ },
+ "dependencies": {
+ "node-fetch": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.1.tgz",
+ "integrity": "sha1-NpynC4L1DIZJYQSmx3bSdPTkotQ="
+ }
+ }
+ },
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@@ -3947,6 +4239,68 @@
"integrity": "sha1-XQVI+iVkVu3kqaDCrHqxnT6xrYE=",
"dev": true
},
+ "css-loader": {
+ "version": "0.28.11",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz",
+ "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==",
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "css-selector-tokenizer": "0.7.0",
+ "cssnano": "3.10.0",
+ "icss-utils": "2.1.0",
+ "loader-utils": "1.1.0",
+ "lodash.camelcase": "4.3.0",
+ "object-assign": "4.1.1",
+ "postcss": "5.2.18",
+ "postcss-modules-extract-imports": "1.2.0",
+ "postcss-modules-local-by-default": "1.2.0",
+ "postcss-modules-scope": "1.1.0",
+ "postcss-modules-values": "1.3.0",
+ "postcss-value-parser": "3.3.0",
+ "source-list-map": "2.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
"css-rule-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz",
@@ -4007,6 +4361,28 @@
"nth-check": "1.0.1"
}
},
+ "css-selector-tokenizer": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
+ "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+ "requires": {
+ "cssesc": "0.1.0",
+ "fastparse": "1.1.1",
+ "regexpu-core": "1.0.0"
+ },
+ "dependencies": {
+ "regexpu-core": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+ "requires": {
+ "regenerate": "1.3.3",
+ "regjsgen": "0.2.0",
+ "regjsparser": "0.1.5"
+ }
+ }
+ }
+ },
"css-tokenize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz",
@@ -4058,6 +4434,119 @@
"through": "2.3.8"
}
},
+ "cssesc": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+ "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q="
+ },
+ "cssnano": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
+ "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+ "requires": {
+ "autoprefixer": "6.7.7",
+ "decamelize": "1.2.0",
+ "defined": "1.0.0",
+ "has": "1.0.1",
+ "object-assign": "4.1.1",
+ "postcss": "5.2.18",
+ "postcss-calc": "5.3.1",
+ "postcss-colormin": "2.2.2",
+ "postcss-convert-values": "2.6.1",
+ "postcss-discard-comments": "2.0.4",
+ "postcss-discard-duplicates": "2.1.0",
+ "postcss-discard-empty": "2.1.0",
+ "postcss-discard-overridden": "0.1.1",
+ "postcss-discard-unused": "2.2.3",
+ "postcss-filter-plugins": "2.0.2",
+ "postcss-merge-idents": "2.1.7",
+ "postcss-merge-longhand": "2.0.2",
+ "postcss-merge-rules": "2.1.2",
+ "postcss-minify-font-values": "1.0.5",
+ "postcss-minify-gradients": "1.0.5",
+ "postcss-minify-params": "1.2.2",
+ "postcss-minify-selectors": "2.1.1",
+ "postcss-normalize-charset": "1.1.1",
+ "postcss-normalize-url": "3.0.8",
+ "postcss-ordered-values": "2.2.3",
+ "postcss-reduce-idents": "2.4.0",
+ "postcss-reduce-initial": "1.0.1",
+ "postcss-reduce-transforms": "1.0.4",
+ "postcss-svgo": "2.1.6",
+ "postcss-unique-selectors": "2.0.2",
+ "postcss-value-parser": "3.3.0",
+ "postcss-zindex": "2.2.0"
+ },
+ "dependencies": {
+ "autoprefixer": {
+ "version": "6.7.7",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000808",
+ "normalize-range": "0.1.2",
+ "num2fraction": "1.2.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "requires": {
+ "caniuse-db": "1.0.30000808",
+ "electron-to-chromium": "1.3.30"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "csso": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
+ "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
+ "requires": {
+ "clap": "1.2.3",
+ "source-map": "0.5.7"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
"cssom": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
@@ -4073,6 +4562,16 @@
"cssom": "0.3.2"
}
},
+ "currency-formatter": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/currency-formatter/-/currency-formatter-1.4.2.tgz",
+ "integrity": "sha512-rQ5HB3DenCZwfVPdpVTuVcAORodVO0VoqIbjhdUSuy0sE2b9jBdCaVKbA355NUc2KhPbu5ojHs3WypuEwPLfNg==",
+ "requires": {
+ "accounting": "0.4.1",
+ "locale-currency": "0.0.1",
+ "object-assign": "4.1.1"
+ }
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -4087,6 +4586,12 @@
"integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
"dev": true
},
+ "cvss": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cvss/-/cvss-1.0.2.tgz",
+ "integrity": "sha1-32fpK/EqeW9J6Sh5nI2zunS5/NY=",
+ "dev": true
+ },
"cycle": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
@@ -4106,6 +4611,11 @@
"resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
"integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g="
},
+ "d64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz",
+ "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA="
+ },
"dargs": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz",
@@ -4204,15 +4714,116 @@
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
+ "decompress": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz",
+ "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=",
+ "requires": {
+ "decompress-tar": "4.1.1",
+ "decompress-tarbz2": "4.1.1",
+ "decompress-targz": "4.1.1",
+ "decompress-unzip": "4.0.1",
+ "graceful-fs": "4.1.11",
+ "make-dir": "1.2.0",
+ "pify": "2.3.0",
+ "strip-dirs": "2.1.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ }
+ }
+ },
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
- "dev": true,
"requires": {
"mimic-response": "1.0.0"
}
},
+ "decompress-tar": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+ "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+ "requires": {
+ "file-type": "5.2.0",
+ "is-stream": "1.1.0",
+ "tar-stream": "1.6.0"
+ }
+ },
+ "decompress-tarbz2": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+ "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+ "requires": {
+ "decompress-tar": "4.1.1",
+ "file-type": "6.2.0",
+ "is-stream": "1.1.0",
+ "seek-bzip": "1.0.5",
+ "unbzip2-stream": "1.2.5"
+ },
+ "dependencies": {
+ "file-type": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+ "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="
+ }
+ }
+ },
+ "decompress-targz": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+ "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+ "requires": {
+ "decompress-tar": "4.1.1",
+ "file-type": "5.2.0",
+ "is-stream": "1.1.0"
+ }
+ },
+ "decompress-unzip": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+ "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+ "requires": {
+ "file-type": "3.9.0",
+ "get-stream": "2.3.1",
+ "pify": "2.3.0",
+ "yauzl": "2.9.1"
+ },
+ "dependencies": {
+ "file-type": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
+ },
+ "get-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "yauzl": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz",
+ "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=",
+ "requires": {
+ "buffer-crc32": "0.2.13",
+ "fd-slicer": "1.0.1"
+ }
+ }
+ }
+ },
"deep-diff": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz",
@@ -4623,6 +5234,15 @@
"string_decoder": "0.10.31"
}
},
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
@@ -4808,8 +5428,7 @@
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
},
"duplexify": {
"version": "3.5.1",
@@ -5112,7 +5731,7 @@
"lodash": "4.17.4",
"object.assign": "4.1.0",
"object.values": "1.0.4",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"enzyme-adapter-utils": {
@@ -5123,7 +5742,7 @@
"requires": {
"lodash": "4.17.4",
"object.assign": "4.1.0",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"errno": {
@@ -5454,7 +6073,7 @@
"doctrine": "2.0.2",
"has": "1.0.1",
"jsx-ast-utils": "2.0.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"eslint-scope": {
@@ -5647,37 +6266,13 @@
}
},
"eth-json-rpc-filters": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.5.tgz",
- "integrity": "sha512-MUcUzwDy0cPso1BEnY5T5DtlI8r8gA7lNqn+BOFzDX1Ll6C8mCPz8pzSKrTkbKV9KTfgQYJ/M4vJbR83TqhROg==",
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.6.tgz",
+ "integrity": "sha512-6G9t43s3lxJckeSfNduc3Ww/40BGm1Cf8MU1nL8rrumZbEg44ZSexWUowB00D4kJ9qSOH+CbzdI+m3oVMi4xFw==",
"requires": {
"await-semaphore": "0.1.3",
- "eth-json-rpc-middleware": "1.5.0",
- "json-rpc-engine": "3.4.0",
+ "json-rpc-engine": "3.6.1",
"lodash.flatmap": "4.5.0"
- },
- "dependencies": {
- "babelify": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
- "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
- "requires": {
- "babel-core": "6.26.0",
- "object-assign": "4.1.1"
- }
- },
- "json-rpc-engine": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.4.0.tgz",
- "integrity": "sha1-ihZHp/LMcBj0gC9B7III0oH3i/w=",
- "requires": {
- "async": "2.6.0",
- "babel-preset-env": "1.6.1",
- "babelify": "7.3.0",
- "json-rpc-error": "2.0.0",
- "promise-to-callback": "1.0.0"
- }
- }
}
},
"eth-json-rpc-infura": {
@@ -5685,25 +6280,26 @@
"resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.0.0.tgz",
"integrity": "sha512-Ab6170AxlF4DK+HDImh52+AetwHPHstgg8uWtX4im26rqK7u4ziSfvUIUK2+/LK0pi0wbIFb8hZm5jPKAXDmBA==",
"requires": {
- "eth-json-rpc-middleware": "1.5.0",
+ "eth-json-rpc-middleware": "1.6.0",
"json-rpc-engine": "3.6.1",
"json-rpc-error": "2.0.0",
"tape": "4.8.0"
}
},
"eth-json-rpc-middleware": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz",
- "integrity": "sha1-FrEFM4aqOAOxJXMqpt4H6t8Ghyk=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz",
+ "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==",
"requires": {
"async": "2.6.0",
"eth-query": "2.1.2",
- "eth-tx-summary": "3.1.2",
+ "eth-tx-summary": "3.2.1",
"ethereumjs-block": "1.7.0",
"ethereumjs-tx": "1.3.3",
- "ethereumjs-util": "5.1.5",
+ "ethereumjs-util": "5.2.0",
"ethereumjs-vm": "2.3.2",
"fetch-ponyfill": "4.1.0",
+ "json-rpc-engine": "3.6.1",
"json-rpc-error": "2.0.0",
"json-stable-stringify": "1.0.1",
"promise-to-callback": "1.0.0",
@@ -5711,9 +6307,9 @@
},
"dependencies": {
"ethereumjs-util": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
- "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
"requires": {
"bn.js": "4.11.8",
"create-hash": "1.1.3",
@@ -5727,9 +6323,9 @@
}
},
"eth-keyring-controller": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/eth-keyring-controller/-/eth-keyring-controller-2.1.4.tgz",
- "integrity": "sha1-BRjZ2Jrw2K82Kigh5NVQqL4UqAc=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eth-keyring-controller/-/eth-keyring-controller-2.2.0.tgz",
+ "integrity": "sha512-f/g1ZrxciWJs2aHgpfvYmZ3ImP48GA+pobTU0EFNF/y5Yylf1zQyDw671W5opGpIt5TgV4F9sYXcvyjlgbL0Pg==",
"requires": {
"bip39": "2.4.0",
"bluebird": "3.5.1",
@@ -5737,7 +6333,7 @@
"eth-hd-keyring": "1.2.2",
"eth-sig-util": "1.4.2",
"eth-simple-keyring": "1.2.1",
- "ethereumjs-util": "5.1.3",
+ "ethereumjs-util": "5.1.5",
"loglevel": "1.6.0",
"obs-store": "2.4.1",
"promise-filter": "1.1.0"
@@ -5752,35 +6348,10 @@
"object-assign": "4.1.1"
}
},
- "eth-hd-keyring": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz",
- "integrity": "sha1-rV9HkHRDapO0ObC5XHkJXCh5GII=",
- "requires": {
- "bip39": "2.4.0",
- "eth-sig-util": "1.4.2",
- "ethereumjs-util": "5.1.3",
- "ethereumjs-wallet": "0.6.0",
- "events": "1.1.1",
- "xtend": "4.0.1"
- }
- },
- "eth-simple-keyring": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/eth-simple-keyring/-/eth-simple-keyring-1.2.1.tgz",
- "integrity": "sha1-bXs1LcWppQINYfafryHvsvY2P0U=",
- "requires": {
- "eth-sig-util": "1.4.2",
- "ethereumjs-util": "5.1.3",
- "ethereumjs-wallet": "0.6.0",
- "events": "1.1.1",
- "xtend": "4.0.1"
- }
- },
"ethereumjs-util": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.3.tgz",
- "integrity": "sha512-U/wmHagElZVxnpo3bFsvk5beFADegUcEzqtA/NfQbitAPOs6JoYq8M4SY9NfH4HD8236i63UOkkXafd7bqBL9A==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
+ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
"requires": {
"bn.js": "4.11.8",
"create-hash": "1.1.3",
@@ -5805,6 +6376,20 @@
}
}
},
+ "eth-lib": {
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
+ "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "elliptic": "6.4.0",
+ "keccakjs": "0.2.1",
+ "nano-json-stream-parser": "0.1.2",
+ "servify": "0.1.12",
+ "ws": "3.3.3",
+ "xhr-request-promise": "0.1.2"
+ }
+ },
"eth-phishing-detect": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/eth-phishing-detect/-/eth-phishing-detect-1.1.12.tgz",
@@ -5827,29 +6412,15 @@
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
"requires": {
- "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#71f123b676f2b2d81bc20f343670d90045a3d3d8",
+ "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf",
"ethereumjs-util": "5.1.3"
},
"dependencies": {
"ethereumjs-abi": {
- "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#71f123b676f2b2d81bc20f343670d90045a3d3d8",
+ "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf",
"requires": {
"bn.js": "4.11.8",
- "ethereumjs-util": "4.5.0"
- },
- "dependencies": {
- "ethereumjs-util": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz",
- "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=",
- "requires": {
- "bn.js": "4.11.8",
- "create-hash": "1.1.3",
- "keccakjs": "0.2.1",
- "rlp": "2.0.0",
- "secp256k1": "3.4.0"
- }
- }
+ "ethereumjs-util": "5.1.3"
}
},
"ethereumjs-util": {
@@ -5868,6 +6439,34 @@
}
}
},
+ "eth-simple-keyring": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/eth-simple-keyring/-/eth-simple-keyring-1.2.1.tgz",
+ "integrity": "sha1-bXs1LcWppQINYfafryHvsvY2P0U=",
+ "requires": {
+ "eth-sig-util": "1.4.2",
+ "ethereumjs-util": "5.1.5",
+ "ethereumjs-wallet": "0.6.0",
+ "events": "1.1.1",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
+ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "create-hash": "1.1.3",
+ "ethjs-util": "0.1.4",
+ "keccak": "1.4.0",
+ "rlp": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "secp256k1": "3.4.0"
+ }
+ }
+ }
+ },
"eth-token-tracker": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/eth-token-tracker/-/eth-token-tracker-1.1.4.tgz",
@@ -5915,6 +6514,83 @@
}
}
},
+ "ethjs": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/ethjs/-/ethjs-0.2.9.tgz",
+ "integrity": "sha1-yagNR7ydVg9Z53gEnSIlXlgfMSs=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "ethjs-abi": "0.2.0",
+ "ethjs-contract": "0.1.9",
+ "ethjs-filter": "0.1.5",
+ "ethjs-provider-http": "0.1.6",
+ "ethjs-query": "0.3.0",
+ "ethjs-unit": "0.1.6",
+ "ethjs-util": "0.1.3",
+ "js-sha3": "0.5.5",
+ "number-to-bn": "1.7.0"
+ },
+ "dependencies": {
+ "ethjs-format": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.3.tgz",
+ "integrity": "sha1-m9hnyu6CstvtmEYAuzAiDPPLWDA=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "ethjs-schema": "0.1.9",
+ "ethjs-util": "0.1.3",
+ "is-hex-prefixed": "1.0.0",
+ "number-to-bn": "1.7.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
+ "ethjs-query": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/ethjs-query/-/ethjs-query-0.3.0.tgz",
+ "integrity": "sha1-CAmNYQ+BvV+VSnpXq0mJ9+mBX8Q=",
+ "requires": {
+ "ethjs-format": "0.2.3",
+ "ethjs-rpc": "0.1.5"
+ }
+ },
+ "ethjs-schema": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/ethjs-schema/-/ethjs-schema-0.1.9.tgz",
+ "integrity": "sha1-hYwqXacGrgSBK0zosetLSSHjMJI="
+ },
+ "ethjs-util": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.3.tgz",
+ "integrity": "sha1-39XqSkANxeQhqInK9H4IGtp4u1U=",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ }
+ }
+ },
+ "ethjs-contract": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/ethjs-contract/-/ethjs-contract-0.1.9.tgz",
+ "integrity": "sha1-HCdmiWpW1H7B1tZhgpxJzDilUgo=",
+ "requires": {
+ "ethjs-abi": "0.2.0",
+ "ethjs-filter": "0.1.5",
+ "ethjs-util": "0.1.3",
+ "js-sha3": "0.5.5"
+ },
+ "dependencies": {
+ "ethjs-util": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.3.tgz",
+ "integrity": "sha1-39XqSkANxeQhqInK9H4IGtp4u1U=",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ }
+ }
+ },
"ethjs-format": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.2.tgz",
@@ -5952,15 +6628,21 @@
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/ethjs-schema/-/ethjs-schema-0.1.5.tgz",
"integrity": "sha1-WXQOOzl3vNu5sRvDBoIB6Kzquw0="
+ },
+ "js-sha3": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz",
+ "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko="
}
}
},
"eth-tx-summary": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.1.2.tgz",
- "integrity": "sha1-44g2/J+LVvFNdZUvD15XD4j7IiA=",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.1.tgz",
+ "integrity": "sha512-mu8g5tDkQxlFah58ggFhTzolE4OnYTj6j8SVsnGsiWT7WxN722RwnEsk/bco2foy+PLSEF2Mnoiw+wCqKoY72A==",
"requires": {
"async": "2.6.0",
+ "bn.js": "4.11.8",
"clone": "2.1.1",
"concat-stream": "1.6.0",
"end-of-stream": "1.4.0",
@@ -5968,10 +6650,88 @@
"ethereumjs-block": "1.7.0",
"ethereumjs-tx": "1.3.3",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
- "ethereumjs-vm": "2.3.2",
+ "ethereumjs-vm": "2.3.5",
"through2": "2.0.3",
"treeify": "1.1.0",
"web3-provider-engine": "13.8.0"
+ },
+ "dependencies": {
+ "ethereumjs-vm": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz",
+ "integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==",
+ "requires": {
+ "async": "2.6.0",
+ "async-eventemitter": "0.2.4",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-account": "2.0.4",
+ "ethereumjs-block": "1.7.0",
+ "ethereumjs-util": "5.2.0",
+ "fake-merkle-patricia-tree": "1.0.1",
+ "functional-red-black-tree": "1.0.1",
+ "merkle-patricia-tree": "2.3.0",
+ "rustbn.js": "0.1.1",
+ "safe-buffer": "5.1.1"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "create-hash": "1.1.3",
+ "ethjs-util": "0.1.4",
+ "keccak": "1.4.0",
+ "rlp": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "secp256k1": "3.4.0"
+ }
+ }
+ }
+ },
+ "web3-provider-engine": {
+ "version": "13.8.0",
+ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz",
+ "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==",
+ "requires": {
+ "async": "2.6.0",
+ "clone": "2.1.1",
+ "eth-block-tracker": "2.3.0",
+ "eth-sig-util": "1.4.2",
+ "ethereumjs-block": "1.7.0",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "5.2.0",
+ "ethereumjs-vm": "2.3.5",
+ "fetch-ponyfill": "4.1.0",
+ "json-rpc-error": "2.0.0",
+ "json-stable-stringify": "1.0.1",
+ "promise-to-callback": "1.0.0",
+ "readable-stream": "2.3.3",
+ "request": "2.83.0",
+ "semaphore": "1.1.0",
+ "solc": "0.4.23",
+ "tape": "4.8.0",
+ "xhr": "2.4.1",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "create-hash": "1.1.3",
+ "ethjs-util": "0.1.4",
+ "keccak": "1.4.0",
+ "rlp": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "secp256k1": "3.4.0"
+ }
+ }
+ }
+ }
}
},
"ethereum-common": {
@@ -6134,16 +6894,16 @@
"integrity": "sha1-x7kULEtZUJsziiBLYyiupA3Txk4="
},
"ethjs": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/ethjs/-/ethjs-0.2.9.tgz",
- "integrity": "sha1-yagNR7ydVg9Z53gEnSIlXlgfMSs=",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/ethjs/-/ethjs-0.3.6.tgz",
+ "integrity": "sha512-9ojnSkV5XXSM5vo0pKgZpE+SNBPxqSUN0dZmMP5dBZVFOYctRd9tfaZ80Jnde3M4JrfUhhkbG5QFvewitaAY7Q==",
"requires": {
"bn.js": "4.11.6",
- "ethjs-abi": "0.2.0",
+ "ethjs-abi": "0.2.1",
"ethjs-contract": "0.1.9",
"ethjs-filter": "0.1.5",
"ethjs-provider-http": "0.1.6",
- "ethjs-query": "0.3.0",
+ "ethjs-query": "0.3.4",
"ethjs-unit": "0.1.6",
"ethjs-util": "0.1.3",
"js-sha3": "0.5.5",
@@ -6155,13 +6915,37 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
},
- "ethjs-query": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/ethjs-query/-/ethjs-query-0.3.0.tgz",
- "integrity": "sha1-CAmNYQ+BvV+VSnpXq0mJ9+mBX8Q=",
+ "ethjs-abi": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz",
+ "integrity": "sha1-4KepOn6BFjqUR3utVu3lJKtt5TM=",
"requires": {
- "ethjs-format": "0.2.3",
- "ethjs-rpc": "0.1.5"
+ "bn.js": "4.11.6",
+ "js-sha3": "0.5.5",
+ "number-to-bn": "1.7.0"
+ }
+ },
+ "ethjs-contract": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/ethjs-contract/-/ethjs-contract-0.1.9.tgz",
+ "integrity": "sha1-HCdmiWpW1H7B1tZhgpxJzDilUgo=",
+ "requires": {
+ "ethjs-abi": "0.2.0",
+ "ethjs-filter": "0.1.5",
+ "ethjs-util": "0.1.3",
+ "js-sha3": "0.5.5"
+ },
+ "dependencies": {
+ "ethjs-abi": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.0.tgz",
+ "integrity": "sha1-0+LCIQEVIPxJm3FoIDbBT8wvWyU=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "js-sha3": "0.5.5",
+ "number-to-bn": "1.7.0"
+ }
+ }
}
},
"ethjs-util": {
@@ -6203,16 +6987,24 @@
}
},
"ethjs-contract": {
- "version": "0.1.9",
- "resolved": "https://registry.npmjs.org/ethjs-contract/-/ethjs-contract-0.1.9.tgz",
- "integrity": "sha1-HCdmiWpW1H7B1tZhgpxJzDilUgo=",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/ethjs-contract/-/ethjs-contract-0.2.0.tgz",
+ "integrity": "sha512-jkQrDvoeaFI4oxatkwRDZrCVCszGZ02WJgiWX2RhQA9ifNw+oSUNBj5DJ7/sc0iiR3w4fJG0fPjLwC6HkYYNzg==",
"requires": {
"ethjs-abi": "0.2.0",
- "ethjs-filter": "0.1.5",
+ "ethjs-filter": "0.1.7",
"ethjs-util": "0.1.3",
"js-sha3": "0.5.5"
},
"dependencies": {
+ "ethjs-filter": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/ethjs-filter/-/ethjs-filter-0.1.7.tgz",
+ "integrity": "sha512-oQb9pjLfg1jeBtn1Pt6kONj7X4rFNX/n55IakxFWJiCAU7n9IVGpp//FU7rO7WTkYLiQLj+7L3fAJmdSWNnSWg==",
+ "requires": {
+ "ganache-core": "2.1.0"
+ }
+ },
"ethjs-util": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.3.tgz",
@@ -6245,6 +7037,17 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
},
+ "ethjs-contract": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/ethjs-contract/-/ethjs-contract-0.1.9.tgz",
+ "integrity": "sha1-HCdmiWpW1H7B1tZhgpxJzDilUgo=",
+ "requires": {
+ "ethjs-abi": "0.2.0",
+ "ethjs-filter": "0.1.5",
+ "ethjs-util": "0.1.3",
+ "js-sha3": "0.5.5"
+ }
+ },
"ethjs-format": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.2.tgz",
@@ -6280,6 +7083,11 @@
"is-hex-prefixed": "1.0.0",
"strip-hex-prefix": "1.0.0"
}
+ },
+ "js-sha3": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz",
+ "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko="
}
}
},
@@ -6288,35 +7096,6 @@
"resolved": "https://registry.npmjs.org/ethjs-filter/-/ethjs-filter-0.1.5.tgz",
"integrity": "sha1-ARKvYBfCRnfjK4/esg5hlgGbdZg="
},
- "ethjs-format": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.3.tgz",
- "integrity": "sha1-m9hnyu6CstvtmEYAuzAiDPPLWDA=",
- "requires": {
- "bn.js": "4.11.6",
- "ethjs-schema": "0.1.9",
- "ethjs-util": "0.1.3",
- "is-hex-prefixed": "1.0.0",
- "number-to-bn": "1.7.0",
- "strip-hex-prefix": "1.0.0"
- },
- "dependencies": {
- "bn.js": {
- "version": "4.11.6",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
- "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
- },
- "ethjs-util": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.3.tgz",
- "integrity": "sha1-39XqSkANxeQhqInK9H4IGtp4u1U=",
- "requires": {
- "is-hex-prefixed": "1.0.0",
- "strip-hex-prefix": "1.0.0"
- }
- }
- }
- },
"ethjs-provider-http": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-provider-http/-/ethjs-provider-http-0.1.6.tgz",
@@ -6378,11 +7157,6 @@
"resolved": "https://registry.npmjs.org/ethjs-rpc/-/ethjs-rpc-0.1.5.tgz",
"integrity": "sha1-CZ4i8n3EwYtpeKSF/DaxsPeWkIA="
},
- "ethjs-schema": {
- "version": "0.1.9",
- "resolved": "https://registry.npmjs.org/ethjs-schema/-/ethjs-schema-0.1.9.tgz",
- "integrity": "sha1-hYwqXacGrgSBK0zosetLSSHjMJI="
- },
"ethjs-unit": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
@@ -6767,6 +7541,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
+ "fastparse": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
+ "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg="
+ },
"faye-websocket": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz",
@@ -6801,7 +7580,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
- "dev": true,
"requires": {
"pend": "1.2.0"
}
@@ -6831,6 +7609,27 @@
"object-assign": "4.1.1"
}
},
+ "file-loader": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
+ "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
+ "requires": {
+ "loader-utils": "1.1.0",
+ "schema-utils": "0.4.5"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ }
+ }
+ },
"file-tree": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-tree/-/file-tree-1.0.0.tgz",
@@ -6841,6 +7640,11 @@
"flat": "1.0.0"
}
},
+ "file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY="
+ },
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
@@ -6927,7 +7731,7 @@
"requires": {
"detect-file": "1.0.0",
"is-glob": "3.1.0",
- "micromatch": "3.1.9",
+ "micromatch": "3.1.10",
"resolve-dir": "1.0.1"
},
"dependencies": {
@@ -6942,32 +7746,22 @@
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
},
"braces": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
- "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
"requires": {
"arr-flatten": "1.1.0",
"array-unique": "0.3.2",
- "define-property": "1.0.0",
"extend-shallow": "2.0.1",
"fill-range": "4.0.0",
"isobject": "3.0.1",
- "kind-of": "6.0.2",
"repeat-element": "1.1.2",
"snapdragon": "0.8.1",
"snapdragon-node": "2.1.1",
"split-string": "3.1.0",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "1.0.2"
- }
- },
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
@@ -6998,7 +7792,7 @@
"posix-character-classes": "0.1.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
@@ -7065,7 +7859,7 @@
"fragment-cache": "0.2.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
@@ -7174,21 +7968,6 @@
}
}
},
- "is-odd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
- "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
- "requires": {
- "is-number": "4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
- }
- }
- },
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@@ -7200,13 +7979,13 @@
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
},
"micromatch": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz",
- "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==",
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
- "braces": "2.3.1",
+ "braces": "2.3.2",
"define-property": "2.0.2",
"extend-shallow": "3.0.2",
"extglob": "2.0.4",
@@ -7216,26 +7995,29 @@
"object.pick": "1.3.0",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
}
},
- "nanomatch": {
- "version": "1.2.9",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
- "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
"requires": {
- "arr-diff": "4.0.0",
- "array-unique": "0.3.2",
"define-property": "2.0.2",
"extend-shallow": "3.0.2",
- "fragment-cache": "0.2.1",
- "is-odd": "2.0.0",
- "is-windows": "1.0.2",
- "kind-of": "6.0.2",
- "object.pick": "1.3.0",
- "regex-not": "1.0.0",
- "snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ },
+ "dependencies": {
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ }
}
}
}
@@ -7347,9 +8129,9 @@
"dev": true
},
"flush-write-stream": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz",
- "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+ "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
"requires": {
"inherits": "2.0.3",
"readable-stream": "2.3.3"
@@ -7458,6 +8240,11 @@
"null-check": "1.0.0"
}
},
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
"fs-exists-sync": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
@@ -7489,7 +8276,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz",
"integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=",
- "dev": true,
"requires": {
"any-promise": "1.3.0",
"fs-extra": "2.1.2",
@@ -7500,14 +8286,12 @@
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
- "dev": true
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
},
"fs-extra": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
"integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
- "dev": true,
"requires": {
"graceful-fs": "4.1.11",
"jsonfile": "2.4.0"
@@ -7521,195 +8305,75 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
- "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.2.tgz",
+ "integrity": "sha512-iownA+hC4uHFp+7gwP/y5SzaiUo7m2vpa0dhpzw8YuKtiZsz7cIXsFbXpLEeBM6WuCQyw1MH4RRe6XI8GFUctQ==",
"optional": true,
"requires": {
- "nan": "2.8.0",
- "node-pre-gyp": "0.6.39"
+ "nan": "2.10.0",
+ "node-pre-gyp": "0.9.1"
},
"dependencies": {
"abbrev": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
- "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=",
+ "version": "1.1.1",
+ "bundled": true,
"optional": true
},
- "ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
- "optional": true,
- "requires": {
- "co": "4.6.0",
- "json-stable-stringify": "1.0.1"
- }
- },
"ansi-regex": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ "bundled": true
},
"aproba": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz",
- "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=",
+ "version": "1.2.0",
+ "bundled": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
- "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+ "bundled": true,
"optional": true,
"requires": {
"delegates": "1.0.0",
- "readable-stream": "2.2.9"
+ "readable-stream": "2.3.6"
}
},
- "asn1": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
- "optional": true
- },
- "assert-plus": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
- "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
- "optional": true
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
- "optional": true
- },
- "aws-sign2": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
- "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
- "optional": true
- },
- "aws4": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
- "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
- "optional": true
- },
"balanced-match": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
- "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
- },
- "bcrypt-pbkdf": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
- "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
- "optional": true,
- "requires": {
- "tweetnacl": "0.14.5"
- }
- },
- "block-stream": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
- "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
- "requires": {
- "inherits": "2.0.3"
- }
- },
- "boom": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
- "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
- "requires": {
- "hoek": "2.16.3"
- }
+ "version": "1.0.0",
+ "bundled": true
},
"brace-expansion": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
- "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
+ "version": "1.1.11",
+ "bundled": true,
"requires": {
- "balanced-match": "0.4.2",
+ "balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
- "buffer-shims": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
- "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
- },
- "caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
- "optional": true
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "chownr": {
+ "version": "1.0.1",
+ "bundled": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
- },
- "combined-stream": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
- "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
- "requires": {
- "delayed-stream": "1.0.0"
- }
+ "bundled": true
},
"concat-map": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "bundled": true
},
"console-control-strings": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+ "bundled": true
},
"core-util-is": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "cryptiles": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
- "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
- "requires": {
- "boom": "2.10.1"
- }
- },
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "optional": true,
- "requires": {
- "assert-plus": "1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "optional": true
- }
- }
+ "bundled": true,
+ "optional": true
},
"debug": {
- "version": "2.6.8",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
- "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "version": "2.6.9",
+ "bundled": true,
"optional": true,
"requires": {
"ms": "2.0.0"
@@ -7717,98 +8381,38 @@
},
"deep-extend": {
"version": "0.4.2",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
- "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
+ "bundled": true,
"optional": true
},
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
"delegates": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "bundled": true,
"optional": true
},
"detect-libc": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.2.tgz",
- "integrity": "sha1-ca1dIEvxempsqPRQxhRUBm70YeE=",
- "optional": true
- },
- "ecc-jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
- "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
- "optional": true,
- "requires": {
- "jsbn": "0.1.1"
- }
- },
- "extend": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
- "optional": true
- },
- "extsprintf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
- "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA="
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "version": "1.0.3",
+ "bundled": true,
"optional": true
},
- "form-data": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
- "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "fs-minipass": {
+ "version": "1.2.5",
+ "bundled": true,
"optional": true,
"requires": {
- "asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.15"
+ "minipass": "2.2.4"
}
},
"fs.realpath": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "fstream": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
- "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
- "requires": {
- "graceful-fs": "4.1.11",
- "inherits": "2.0.3",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.1"
- }
- },
- "fstream-ignore": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
- "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
- "optional": true,
- "requires": {
- "fstream": "1.0.11",
- "inherits": "2.0.3",
- "minimatch": "3.0.4"
- }
+ "bundled": true,
+ "optional": true
},
"gauge": {
"version": "2.7.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "bundled": true,
"optional": true,
"requires": {
- "aproba": "1.1.1",
+ "aproba": "1.2.0",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
@@ -7818,27 +8422,10 @@
"wide-align": "1.1.2"
}
},
- "getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "optional": true,
- "requires": {
- "assert-plus": "1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "optional": true
- }
- }
- },
"glob": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "bundled": true,
+ "optional": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
@@ -7848,64 +8435,31 @@
"path-is-absolute": "1.0.1"
}
},
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
- },
- "har-schema": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
- "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
- "optional": true
- },
- "har-validator": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
- "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
- "optional": true,
- "requires": {
- "ajv": "4.11.8",
- "har-schema": "1.0.5"
- }
- },
"has-unicode": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "bundled": true,
"optional": true
},
- "hawk": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
- "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "iconv-lite": {
+ "version": "0.4.21",
+ "bundled": true,
+ "optional": true,
"requires": {
- "boom": "2.10.1",
- "cryptiles": "2.0.5",
- "hoek": "2.16.3",
- "sntp": "1.0.9"
+ "safer-buffer": "2.1.2"
}
},
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
- },
- "http-signature": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
- "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "ignore-walk": {
+ "version": "3.0.1",
+ "bundled": true,
"optional": true,
"requires": {
- "assert-plus": "0.2.0",
- "jsprim": "1.4.0",
- "sshpk": "1.13.0"
+ "minimatch": "3.0.4"
}
},
"inflight": {
"version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "bundled": true,
+ "optional": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
@@ -7913,175 +8467,123 @@
},
"inherits": {
"version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "bundled": true
},
"ini": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
- "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "version": "1.3.5",
+ "bundled": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "bundled": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
- "is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
- "optional": true
- },
"isarray": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "bundled": true,
"optional": true
},
- "jodid25519": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
- "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=",
- "optional": true,
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
"requires": {
- "jsbn": "0.1.1"
+ "brace-expansion": "1.1.11"
}
},
- "jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "optional": true
- },
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
- "optional": true
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true
},
- "json-stable-stringify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
- "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
- "optional": true,
+ "minipass": {
+ "version": "2.2.4",
+ "bundled": true,
"requires": {
- "jsonify": "0.0.0"
+ "safe-buffer": "5.1.1",
+ "yallist": "3.0.2"
}
},
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
- "optional": true
- },
- "jsonify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
- "optional": true
- },
- "jsprim": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
- "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
+ "minizlib": {
+ "version": "1.1.0",
+ "bundled": true,
"optional": true,
"requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.0.2",
- "json-schema": "0.2.3",
- "verror": "1.3.6"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "optional": true
- }
+ "minipass": "2.2.4"
}
},
- "mime-db": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
- "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE="
- },
- "mime-types": {
- "version": "2.1.15",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
- "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
- "requires": {
- "mime-db": "1.27.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "1.1.7"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
- },
"mkdirp": {
"version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "bundled": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "bundled": true,
+ "optional": true
+ },
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
"optional": true
},
+ "needle": {
+ "version": "2.2.0",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.9",
+ "iconv-lite": "0.4.21",
+ "sax": "1.2.4"
+ }
+ },
"node-pre-gyp": {
- "version": "0.6.39",
- "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz",
- "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==",
+ "version": "0.9.1",
+ "bundled": true,
"optional": true,
"requires": {
- "detect-libc": "1.0.2",
- "hawk": "3.1.3",
+ "detect-libc": "1.0.3",
"mkdirp": "0.5.1",
+ "needle": "2.2.0",
"nopt": "4.0.1",
- "npmlog": "4.1.0",
- "rc": "1.2.1",
- "request": "2.81.0",
- "rimraf": "2.6.1",
- "semver": "5.3.0",
- "tar": "2.2.1",
- "tar-pack": "3.4.0"
+ "npm-packlist": "1.1.10",
+ "npmlog": "4.1.2",
+ "rc": "1.2.6",
+ "rimraf": "2.6.2",
+ "semver": "5.5.0",
+ "tar": "4.4.1"
}
},
"nopt": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
- "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "bundled": true,
"optional": true,
"requires": {
- "abbrev": "1.1.0",
- "osenv": "0.1.4"
+ "abbrev": "1.1.1",
+ "osenv": "0.1.5"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.3",
+ "bundled": true,
+ "optional": true
+ },
+ "npm-packlist": {
+ "version": "1.1.10",
+ "bundled": true,
+ "optional": true,
+ "requires": {
+ "ignore-walk": "3.0.1",
+ "npm-bundled": "1.0.3"
}
},
"npmlog": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz",
- "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==",
+ "version": "4.1.2",
+ "bundled": true,
"optional": true,
"requires": {
"are-we-there-yet": "1.1.4",
@@ -8092,45 +8594,33 @@
},
"number-is-nan": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
- },
- "oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
- "optional": true
+ "bundled": true
},
"object-assign": {
"version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "bundled": true,
"optional": true
},
"once": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "bundled": true,
"requires": {
"wrappy": "1.0.2"
}
},
"os-homedir": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "bundled": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "bundled": true,
"optional": true
},
"osenv": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
- "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+ "version": "0.1.5",
+ "bundled": true,
"optional": true,
"requires": {
"os-homedir": "1.0.2",
@@ -8139,164 +8629,86 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "performance-now": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
- "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+ "bundled": true,
"optional": true
},
"process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
- },
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "optional": true
- },
- "qs": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
- "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+ "version": "2.0.0",
+ "bundled": true,
"optional": true
},
"rc": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
- "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+ "version": "1.2.6",
+ "bundled": true,
"optional": true,
"requires": {
"deep-extend": "0.4.2",
- "ini": "1.3.4",
+ "ini": "1.3.5",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "bundled": true,
"optional": true
}
}
},
"readable-stream": {
- "version": "2.2.9",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz",
- "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=",
+ "version": "2.3.6",
+ "bundled": true,
+ "optional": true,
"requires": {
- "buffer-shims": "1.0.0",
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "string_decoder": "1.0.1",
+ "process-nextick-args": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.1.1",
"util-deprecate": "1.0.2"
}
},
- "request": {
- "version": "2.81.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
- "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
- "optional": true,
- "requires": {
- "aws-sign2": "0.6.0",
- "aws4": "1.6.0",
- "caseless": "0.12.0",
- "combined-stream": "1.0.5",
- "extend": "3.0.1",
- "forever-agent": "0.6.1",
- "form-data": "2.1.4",
- "har-validator": "4.2.1",
- "hawk": "3.1.3",
- "http-signature": "1.1.1",
- "is-typedarray": "1.0.0",
- "isstream": "0.1.2",
- "json-stringify-safe": "5.0.1",
- "mime-types": "2.1.15",
- "oauth-sign": "0.8.2",
- "performance-now": "0.2.0",
- "qs": "6.4.0",
- "safe-buffer": "5.0.1",
- "stringstream": "0.0.5",
- "tough-cookie": "2.3.2",
- "tunnel-agent": "0.6.0",
- "uuid": "3.0.1"
- }
- },
"rimraf": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
- "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
+ "version": "2.6.2",
+ "bundled": true,
+ "optional": true,
"requires": {
"glob": "7.1.2"
}
},
"safe-buffer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
- "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c="
+ "version": "5.1.1",
+ "bundled": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true,
+ "optional": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true,
+ "optional": true
},
"semver": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
- "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "version": "5.5.0",
+ "bundled": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "bundled": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "bundled": true,
"optional": true
},
- "sntp": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
- "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
- "requires": {
- "hoek": "2.16.3"
- }
- },
- "sshpk": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz",
- "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=",
- "optional": true,
- "requires": {
- "asn1": "0.2.3",
- "assert-plus": "1.0.0",
- "bcrypt-pbkdf": "1.0.1",
- "dashdash": "1.14.1",
- "ecc-jsbn": "0.1.1",
- "getpass": "0.1.7",
- "jodid25519": "1.0.2",
- "jsbn": "0.1.1",
- "tweetnacl": "0.14.5"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "optional": true
- }
- }
- },
"string-width": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "bundled": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
@@ -8304,113 +8716,47 @@
}
},
"string_decoder": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz",
- "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=",
+ "version": "1.1.1",
+ "bundled": true,
+ "optional": true,
"requires": {
- "safe-buffer": "5.0.1"
+ "safe-buffer": "5.1.1"
}
},
- "stringstream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
- "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
- "optional": true
- },
"strip-ansi": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "bundled": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"strip-json-comments": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "bundled": true,
"optional": true
},
"tar": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
- "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
- "requires": {
- "block-stream": "0.0.9",
- "fstream": "1.0.11",
- "inherits": "2.0.3"
- }
- },
- "tar-pack": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz",
- "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=",
- "optional": true,
- "requires": {
- "debug": "2.6.8",
- "fstream": "1.0.11",
- "fstream-ignore": "1.0.5",
- "once": "1.4.0",
- "readable-stream": "2.2.9",
- "rimraf": "2.6.1",
- "tar": "2.2.1",
- "uid-number": "0.0.6"
- }
- },
- "tough-cookie": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
- "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
+ "version": "4.4.1",
+ "bundled": true,
"optional": true,
"requires": {
- "punycode": "1.4.1"
- }
- },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "optional": true,
- "requires": {
- "safe-buffer": "5.0.1"
+ "chownr": "1.0.1",
+ "fs-minipass": "1.2.5",
+ "minipass": "2.2.4",
+ "minizlib": "1.1.0",
+ "mkdirp": "0.5.1",
+ "safe-buffer": "5.1.1",
+ "yallist": "3.0.2"
}
},
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "optional": true
- },
- "uid-number": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
- "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=",
- "optional": true
- },
"util-deprecate": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "uuid": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
- "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=",
+ "bundled": true,
"optional": true
},
- "verror": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
- "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
- "optional": true,
- "requires": {
- "extsprintf": "1.0.2"
- }
- },
"wide-align": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
- "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+ "bundled": true,
"optional": true,
"requires": {
"string-width": "1.0.2"
@@ -8418,8 +8764,11 @@
},
"wrappy": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "bundled": true
+ },
+ "yallist": {
+ "version": "3.0.2",
+ "bundled": true
}
}
},
@@ -8527,6 +8876,380 @@
}
}
},
+ "ganache-core": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.1.0.tgz",
+ "integrity": "sha512-zUO61d23XHBCYOUjEQjIuENcfa6EQNBHKuG2oXWdTdGyu5Gbm4fXX9klZ2jjl9ZnBD2T4BaeBXycsLmL0S/d2w==",
+ "requires": {
+ "abstract-leveldown": "3.0.0",
+ "async": "2.6.0",
+ "bip39": "2.4.0",
+ "bn.js": "4.11.6",
+ "cachedown": "1.0.0",
+ "chai": "3.5.0",
+ "clone": "2.1.1",
+ "ethereumjs-account": "2.0.4",
+ "ethereumjs-block": "1.2.2",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "5.2.0",
+ "ethereumjs-vm": "2.3.3",
+ "ethereumjs-wallet": "0.6.0",
+ "fake-merkle-patricia-tree": "1.0.1",
+ "heap": "0.2.6",
+ "js-scrypt": "0.2.0",
+ "level-sublevel": "6.6.1",
+ "levelup": "1.3.9",
+ "localstorage-down": "0.6.7",
+ "lodash": "4.17.10",
+ "merkle-patricia-tree": "2.3.0",
+ "mocha": "3.3.0",
+ "pify": "3.0.0",
+ "prepend-file": "1.3.1",
+ "seedrandom": "2.4.3",
+ "shebang-loader": "0.0.1",
+ "solc": "0.4.18",
+ "temp": "0.8.3",
+ "tmp": "0.0.31",
+ "web3": "1.0.0-beta.34",
+ "web3-provider-engine": "13.8.0",
+ "websocket": "1.0.26",
+ "yargs": "7.1.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz",
+ "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==",
+ "requires": {
+ "xtend": "4.0.1"
+ }
+ },
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ },
+ "chai": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
+ "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
+ "requires": {
+ "assertion-error": "1.0.2",
+ "deep-eql": "0.1.3",
+ "type-detect": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+ "requires": {
+ "graceful-readlink": "1.0.1"
+ }
+ },
+ "debug": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
+ "integrity": "sha1-vFlryr52F/Edn6FTYe3tVgi4SZs=",
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "deep-eql": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+ "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
+ "requires": {
+ "type-detect": "0.1.1"
+ },
+ "dependencies": {
+ "type-detect": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
+ "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI="
+ }
+ }
+ },
+ "diff": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
+ "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k="
+ },
+ "ethereum-common": {
+ "version": "0.0.16",
+ "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.16.tgz",
+ "integrity": "sha1-mh4Wnq00q3XgifUMpRK/0PvRJlU="
+ },
+ "ethereumjs-block": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.2.2.tgz",
+ "integrity": "sha1-LsdTSlkCG47JuDww5JaQxuuu3aE=",
+ "requires": {
+ "async": "1.5.2",
+ "ethereum-common": "0.0.16",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "4.5.0",
+ "merkle-patricia-tree": "2.3.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "ethereumjs-util": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz",
+ "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "create-hash": "1.1.3",
+ "keccakjs": "0.2.1",
+ "rlp": "2.0.0",
+ "secp256k1": "3.4.0"
+ }
+ }
+ }
+ },
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "4.11.6",
+ "create-hash": "1.1.3",
+ "ethjs-util": "0.1.4",
+ "keccak": "1.4.0",
+ "rlp": "2.0.0",
+ "safe-buffer": "5.1.1",
+ "secp256k1": "3.4.0"
+ }
+ },
+ "ethereumjs-vm": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.3.tgz",
+ "integrity": "sha512-yIWJqTEcrF9vJTCvNMxacRkAx6zIZTOW0SmSA+hSFiU1x8JyVZDi9o5udwsRVECT5RkPgQzm62kpL6Pf4qemsw==",
+ "requires": {
+ "async": "2.6.0",
+ "async-eventemitter": "0.2.4",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-account": "2.0.4",
+ "ethereumjs-block": "1.7.1",
+ "ethereumjs-util": "5.2.0",
+ "fake-merkle-patricia-tree": "1.0.1",
+ "functional-red-black-tree": "1.0.1",
+ "merkle-patricia-tree": "2.3.0",
+ "rustbn.js": "0.1.1",
+ "safe-buffer": "5.1.1"
+ },
+ "dependencies": {
+ "ethereum-common": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz",
+ "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA=="
+ },
+ "ethereumjs-block": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz",
+ "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==",
+ "requires": {
+ "async": "2.6.0",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "5.2.0",
+ "merkle-patricia-tree": "2.3.0"
+ }
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "growl": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
+ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8="
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "lodash": {
+ "version": "4.17.10",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
+ },
+ "mocha": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.3.0.tgz",
+ "integrity": "sha1-0pt0KNP1LILi5l3x7LcGThqrv7U=",
+ "requires": {
+ "browser-stdout": "1.3.0",
+ "commander": "2.9.0",
+ "debug": "2.6.0",
+ "diff": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.1",
+ "growl": "1.9.2",
+ "json3": "3.3.2",
+ "lodash.create": "3.1.1",
+ "mkdirp": "0.5.1",
+ "supports-color": "3.1.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
+ },
+ "solc": {
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.18.tgz",
+ "integrity": "sha512-Kq+O3PNF9Pfq7fB+lDYAuoqRdghLmZyfngsg0h1Hj38NKAeVHeGPOGeZasn5KqdPeCzbMFvaGyTySxzGv6aXCg==",
+ "requires": {
+ "fs-extra": "0.30.0",
+ "memorystream": "0.3.1",
+ "require-from-string": "1.2.1",
+ "semver": "5.4.1",
+ "yargs": "4.8.1"
+ },
+ "dependencies": {
+ "yargs": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
+ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
+ "requires": {
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "lodash.assign": "4.2.0",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "1.0.2",
+ "which-module": "1.0.0",
+ "window-size": "0.2.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "2.4.1"
+ }
+ }
+ }
+ },
+ "supports-color": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
+ "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
+ "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
+ "requires": {
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "type-detect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
+ "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI="
+ },
+ "web3": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.34.tgz",
+ "integrity": "sha1-NH5WG3hAmMtVYzFfSQR5odkfKrE=",
+ "requires": {
+ "web3-bzz": "1.0.0-beta.34",
+ "web3-core": "1.0.0-beta.34",
+ "web3-eth": "1.0.0-beta.34",
+ "web3-eth-personal": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-shh": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-provider-engine": {
+ "version": "13.8.0",
+ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz",
+ "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==",
+ "requires": {
+ "async": "2.6.0",
+ "clone": "2.1.1",
+ "eth-block-tracker": "2.3.0",
+ "eth-sig-util": "1.4.2",
+ "ethereumjs-block": "1.2.2",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "5.2.0",
+ "ethereumjs-vm": "2.3.3",
+ "fetch-ponyfill": "4.1.0",
+ "json-rpc-error": "2.0.0",
+ "json-stable-stringify": "1.0.1",
+ "promise-to-callback": "1.0.0",
+ "readable-stream": "2.3.3",
+ "request": "2.83.0",
+ "semaphore": "1.1.0",
+ "solc": "0.4.18",
+ "tape": "4.8.0",
+ "xhr": "2.4.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "requires": {
+ "camelcase": "3.0.0",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "1.0.2",
+ "which-module": "1.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "5.0.0"
+ },
+ "dependencies": {
+ "yargs-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+ "requires": {
+ "camelcase": "3.0.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
+ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
+ "requires": {
+ "camelcase": "3.0.0",
+ "lodash.assign": "4.2.0"
+ }
+ }
+ }
+ },
"gather-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz",
@@ -8569,6 +9292,11 @@
"is-property": "1.0.2"
}
},
+ "generic-pool": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.0.4.tgz",
+ "integrity": "sha1-+XGN7agvoSXtXEPjQcmiFadm2aM="
+ },
"get-caller-file": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
@@ -8594,8 +9322,7 @@
"get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"get-uri": {
"version": "2.0.1",
@@ -8945,8 +9672,7 @@
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
- "dev": true
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
},
"grouped-queue": {
"version": "0.3.3",
@@ -8988,7 +9714,7 @@
"array-sort": "1.0.0",
"color-support": "1.1.3",
"concat-stream": "1.6.0",
- "copy-props": "2.0.1",
+ "copy-props": "2.0.2",
"fancy-log": "1.3.2",
"gulplog": "1.0.0",
"interpret": "1.1.0",
@@ -9370,15 +10096,336 @@
}
},
"gulp-sass": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz",
- "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.1.tgz",
+ "integrity": "sha512-OMQEgWNggpog8Tc5v1MuI6eo+5iiPkVeLL76iBhDoEEScLUPfZlpvzmgTnLkpcqdrNodZxpz5qcv6mS2rulk3g==",
"requires": {
- "gulp-util": "3.0.8",
+ "chalk": "2.3.2",
"lodash.clonedeep": "4.5.0",
- "node-sass": "4.7.2",
+ "node-sass": "4.8.3",
+ "plugin-error": "1.0.1",
+ "replace-ext": "1.0.0",
+ "strip-ansi": "4.0.0",
"through2": "2.0.3",
"vinyl-sourcemaps-apply": "0.2.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
+ },
+ "chalk": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
+ "requires": {
+ "ansi-styles": "3.2.1",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "5.3.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+ "requires": {
+ "lru-cache": "4.1.1",
+ "which": "1.3.0"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ }
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.11.0",
+ "is-my-json-valid": "2.17.2",
+ "pinkie-promise": "2.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ }
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ },
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
+ },
+ "node-sass": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.8.3.tgz",
+ "integrity": "sha512-tfFWhUsCk/Y19zarDcPo5xpj+IW3qCfOjVdHtYeG6S1CKbQOh1zqylnQK6cV3z9k80yxAnFX9Y+a9+XysDhhfg==",
+ "requires": {
+ "async-foreach": "0.1.3",
+ "chalk": "1.1.3",
+ "cross-spawn": "3.0.1",
+ "gaze": "1.1.2",
+ "get-stdin": "4.0.1",
+ "glob": "7.1.2",
+ "in-publish": "2.0.0",
+ "lodash.assign": "4.2.0",
+ "lodash.clonedeep": "4.5.0",
+ "lodash.mergewith": "4.6.1",
+ "meow": "3.7.0",
+ "mkdirp": "0.5.1",
+ "nan": "2.10.0",
+ "node-gyp": "3.6.2",
+ "npmlog": "4.1.2",
+ "request": "2.79.0",
+ "sass-graph": "2.2.4",
+ "stdout-stream": "1.4.0",
+ "true-case-path": "1.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ }
+ }
+ },
+ "plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "requires": {
+ "ansi-colors": "1.0.1",
+ "arr-diff": "4.0.0",
+ "arr-union": "3.1.0",
+ "extend-shallow": "3.0.2"
+ }
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw="
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "qs": "6.3.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.4.3",
+ "uuid": "3.2.1"
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ }
+ }
+ },
+ "supports-color": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
+ "requires": {
+ "has-flag": "3.0.0"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us="
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+ }
}
},
"gulp-sourcemaps": {
@@ -9395,7 +10442,7 @@
"debug-fabulous": "1.0.0",
"detect-newline": "2.1.0",
"graceful-fs": "4.1.11",
- "source-map": "0.4.4",
+ "source-map": "0.7.2",
"strip-bom-string": "1.0.0",
"through2": "2.0.3"
},
@@ -9826,7 +10873,7 @@
"anymatch": "2.0.0",
"async-each": "1.0.1",
"braces": "2.3.1",
- "fsevents": "1.1.3",
+ "fsevents": "1.2.2",
"glob-parent": "3.1.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -10256,11 +11303,15 @@
"sparkles": "1.0.0"
}
},
+ "has-localstorage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-localstorage/-/has-localstorage-1.0.1.tgz",
+ "integrity": "sha1-/mJAbEdn+9bXhNrGkFkoEIuClxs="
+ },
"has-symbol-support-x": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
- "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
- "dev": true
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
},
"has-symbols": {
"version": "1.0.0",
@@ -10271,7 +11322,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
"integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
- "dev": true,
"requires": {
"has-symbol-support-x": "1.4.2"
}
@@ -10383,6 +11433,11 @@
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
+ "heap": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
+ "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
+ },
"hipchat-notifier": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz",
@@ -10394,6 +11449,18 @@
"request": "2.83.0"
}
},
+ "history": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
+ "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
+ "requires": {
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "resolve-pathname": "2.2.0",
+ "value-equal": "0.4.0",
+ "warning": "3.0.0"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -10436,6 +11503,11 @@
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
"integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
},
+ "html-comment-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
+ "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4="
+ },
"html-encoding-sniffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
@@ -10622,6 +11694,11 @@
}
}
},
+ "http-https": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
+ "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs="
+ },
"http-parser-js": {
"version": "0.4.9",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz",
@@ -10704,6 +11781,15 @@
"resolved": "https://registry.npmjs.org/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz",
"integrity": "sha1-IH14Rnlu5buF/dM252nLOARbKuA="
},
+ "humble-localstorage": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/humble-localstorage/-/humble-localstorage-1.4.2.tgz",
+ "integrity": "sha1-0Fqw1SbE7b3b98amDfb/WAUoNGk=",
+ "requires": {
+ "has-localstorage": "1.0.1",
+ "localstorage-memory": "1.0.2"
+ }
+ },
"i": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
@@ -10715,6 +11801,19 @@
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
+ "icss-replace-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+ "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0="
+ },
+ "icss-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
+ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
+ "requires": {
+ "postcss": "6.0.19"
+ }
+ },
"idb-global": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/idb-global/-/idb-global-2.1.0.tgz",
@@ -10827,8 +11926,7 @@
"indexes-of": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
- "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
- "dev": true
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc="
},
"indexof": {
"version": "0.0.1",
@@ -10872,6 +11970,16 @@
"integrity": "sha1-Skxd2OT7Xps82mDIIt+tyu5m4K8=",
"requires": {
"source-map": "0.4.4"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
}
},
"inquirer": {
@@ -11092,6 +12200,11 @@
"is-windows": "1.0.2"
}
},
+ "is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY="
+ },
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
@@ -11290,6 +12403,11 @@
"xtend": "4.0.1"
}
},
+ "is-natural-number": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+ "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg="
+ },
"is-negated-glob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
@@ -11317,8 +12435,7 @@
"is-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
- "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
- "dev": true
+ "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
},
"is-observable": {
"version": "0.2.0",
@@ -11341,7 +12458,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
"integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
- "dev": true,
"requires": {
"is-number": "4.0.0"
},
@@ -11349,8 +12465,7 @@
"is-number": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
- "dev": true
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
}
}
},
@@ -11444,8 +12559,7 @@
"is-retry-allowed": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
- "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
- "dev": true
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
},
"is-scoped": {
"version": "1.0.0",
@@ -11479,6 +12593,14 @@
"integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=",
"dev": true
},
+ "is-svg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
+ "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
+ "requires": {
+ "html-comment-regex": "1.1.1"
+ }
+ },
"is-symbol": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
@@ -11583,7 +12705,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
"integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
- "dev": true,
"requires": {
"has-to-string-tag-x": "1.4.1",
"is-object": "1.0.1"
@@ -11621,6 +12742,14 @@
"integrity": "sha1-fPLLaYGWaEeQNQ0MTKB/Su2ewX4=",
"dev": true
},
+ "js-scrypt": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/js-scrypt/-/js-scrypt-0.2.0.tgz",
+ "integrity": "sha1-emK3AbRhbnCtDN5URiequ5nX/jk=",
+ "requires": {
+ "generic-pool": "2.0.4"
+ }
+ },
"js-sha3": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz",
@@ -11640,6 +12769,15 @@
"esprima": "4.0.0"
}
},
+ "js2xmlparser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz",
+ "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=",
+ "dev": true,
+ "requires": {
+ "xmlcreate": "1.0.2"
+ }
+ },
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -11746,6 +12884,49 @@
}
}
},
+ "jsdoc": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
+ "integrity": "sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg==",
+ "dev": true,
+ "requires": {
+ "babylon": "7.0.0-beta.19",
+ "bluebird": "3.5.1",
+ "catharsis": "0.8.9",
+ "escape-string-regexp": "1.0.5",
+ "js2xmlparser": "3.0.0",
+ "klaw": "2.0.0",
+ "marked": "0.3.19",
+ "mkdirp": "0.5.1",
+ "requizzle": "0.2.1",
+ "strip-json-comments": "2.0.1",
+ "taffydb": "2.6.2",
+ "underscore": "1.8.3"
+ },
+ "dependencies": {
+ "babylon": {
+ "version": "7.0.0-beta.19",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz",
+ "integrity": "sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A==",
+ "dev": true
+ },
+ "klaw": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz",
+ "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
+ "dev": true
+ }
+ }
+ },
"jsdom": {
"version": "11.5.1",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.5.1.tgz",
@@ -12058,8 +13239,7 @@
"json3": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
- "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
- "dev": true
+ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE="
},
"json5": {
"version": "0.5.1",
@@ -12705,7 +13885,7 @@
"resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
"integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
"requires": {
- "flush-write-stream": "1.0.2"
+ "flush-write-stream": "1.0.3"
}
},
"left-pad": {
@@ -12767,6 +13947,118 @@
}
}
},
+ "level-post": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz",
+ "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==",
+ "requires": {
+ "ltgt": "2.2.0"
+ }
+ },
+ "level-sublevel": {
+ "version": "6.6.1",
+ "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.1.tgz",
+ "integrity": "sha1-+ad/dSGrcKj46S7VbyGjx4hqRIU=",
+ "requires": {
+ "bytewise": "1.1.0",
+ "levelup": "0.19.1",
+ "ltgt": "2.1.3",
+ "pull-level": "2.0.4",
+ "pull-stream": "3.6.7",
+ "typewiselite": "1.0.0",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz",
+ "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=",
+ "requires": {
+ "xtend": "3.0.0"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+ "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo="
+ }
+ }
+ },
+ "bl": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz",
+ "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=",
+ "requires": {
+ "readable-stream": "1.0.34"
+ }
+ },
+ "deferred-leveldown": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz",
+ "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=",
+ "requires": {
+ "abstract-leveldown": "0.12.4"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "levelup": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz",
+ "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=",
+ "requires": {
+ "bl": "0.8.2",
+ "deferred-leveldown": "0.2.0",
+ "errno": "0.1.6",
+ "prr": "0.0.0",
+ "readable-stream": "1.0.34",
+ "semver": "5.1.1",
+ "xtend": "3.0.0"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+ "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo="
+ }
+ }
+ },
+ "ltgt": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz",
+ "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ="
+ },
+ "prr": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
+ "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo="
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "semver": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz",
+ "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk="
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
"level-ws": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz",
@@ -13074,6 +14366,45 @@
"object-assign": "4.1.1"
}
},
+ "locale-currency": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/locale-currency/-/locale-currency-0.0.1.tgz",
+ "integrity": "sha1-yeFaIv9XW0tLuUekv5KsI2vR/ps="
+ },
+ "localstorage-down": {
+ "version": "0.6.7",
+ "resolved": "https://registry.npmjs.org/localstorage-down/-/localstorage-down-0.6.7.tgz",
+ "integrity": "sha1-0Hmak7MebF+lGI7AYkLrHM6dbRU=",
+ "requires": {
+ "abstract-leveldown": "0.12.3",
+ "argsarray": "0.0.1",
+ "buffer-from": "0.1.2",
+ "d64": "1.0.0",
+ "humble-localstorage": "1.4.2",
+ "inherits": "2.0.3",
+ "tiny-queue": "0.2.0"
+ },
+ "dependencies": {
+ "abstract-leveldown": {
+ "version": "0.12.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.3.tgz",
+ "integrity": "sha1-EWsexcdxDvei1XBnaLvbREC+EHA=",
+ "requires": {
+ "xtend": "3.0.0"
+ }
+ },
+ "xtend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+ "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo="
+ }
+ }
+ },
+ "localstorage-memory": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/localstorage-memory/-/localstorage-memory-1.0.2.tgz",
+ "integrity": "sha1-zUqPIQ5V3VGckp9LTMgoKbWPmlE="
+ },
"locate-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
@@ -13106,7 +14437,6 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
"integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
- "dev": true,
"requires": {
"lodash._basecopy": "3.0.1",
"lodash.keys": "3.1.2"
@@ -13117,6 +14447,11 @@
"resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
"integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY="
},
+ "lodash._basecreate": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
+ "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE="
+ },
"lodash._baseflatten": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz",
@@ -13195,6 +14530,11 @@
"integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=",
"dev": true
},
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
+ },
"lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
@@ -13206,11 +14546,27 @@
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
},
+ "lodash.create": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
+ "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
+ "requires": {
+ "lodash._baseassign": "3.2.0",
+ "lodash._basecreate": "3.0.3",
+ "lodash._isiterateecall": "3.0.9"
+ }
+ },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
},
+ "lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=",
+ "dev": true
+ },
"lodash.escape": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
@@ -13298,6 +14654,12 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
+ "lodash.tail": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
+ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
+ "dev": true
+ },
"lodash.template": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
@@ -13323,6 +14685,11 @@
"lodash.escape": "3.2.0"
}
},
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
+ },
"lodash.uniqby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
@@ -13636,6 +15003,11 @@
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
},
+ "looper": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz",
+ "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew="
+ },
"loose-envify": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
@@ -13656,8 +15028,7 @@
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "dev": true
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
},
"lru-cache": {
"version": "4.1.1",
@@ -13682,6 +15053,11 @@
"resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.0.tgz",
"integrity": "sha1-tlul/LNJopkkyOMz98alVi8uSEI="
},
+ "macaddress": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
+ "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI="
+ },
"mailcomposer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz",
@@ -13763,7 +15139,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
"integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
- "dev": true,
"requires": {
"pify": "3.0.0"
}
@@ -13784,11 +15159,18 @@
}
},
"make-iterator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz",
- "integrity": "sha1-V7713IXSOSO6I3ZzJNjo+PPZaUs=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
"requires": {
- "kind-of": "3.2.2"
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
}
},
"map-async": {
@@ -13825,13 +15207,19 @@
"resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.1.tgz",
"integrity": "sha1-GZTfLTr0gR3lmmcUk0wrIpJzRRg="
},
+ "marked": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
+ "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
+ "dev": true
+ },
"matchdep": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
"integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
"requires": {
"findup-sync": "2.0.0",
- "micromatch": "3.1.9",
+ "micromatch": "3.1.10",
"resolve": "1.4.0",
"stack-trace": "0.0.10"
},
@@ -13847,32 +15235,22 @@
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
},
"braces": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
- "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
"requires": {
"arr-flatten": "1.1.0",
"array-unique": "0.3.2",
- "define-property": "1.0.0",
"extend-shallow": "2.0.1",
"fill-range": "4.0.0",
"isobject": "3.0.1",
- "kind-of": "6.0.2",
"repeat-element": "1.1.2",
"snapdragon": "0.8.1",
"snapdragon-node": "2.1.1",
"split-string": "3.1.0",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "requires": {
- "is-descriptor": "1.0.2"
- }
- },
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
@@ -13903,7 +15281,7 @@
"posix-character-classes": "0.1.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
@@ -13970,7 +15348,7 @@
"fragment-cache": "0.2.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
@@ -14066,21 +15444,6 @@
}
}
},
- "is-odd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
- "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
- "requires": {
- "is-number": "4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
- }
- }
- },
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@@ -14092,13 +15455,13 @@
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
},
"micromatch": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz",
- "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==",
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
- "braces": "2.3.1",
+ "braces": "2.3.2",
"define-property": "2.0.2",
"extend-shallow": "3.0.2",
"extglob": "2.0.4",
@@ -14108,26 +15471,29 @@
"object.pick": "1.3.0",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
}
},
- "nanomatch": {
- "version": "1.2.9",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
- "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
"requires": {
- "arr-diff": "4.0.0",
- "array-unique": "0.3.2",
"define-property": "2.0.2",
"extend-shallow": "3.0.2",
- "fragment-cache": "0.2.1",
- "is-odd": "2.0.0",
- "is-windows": "1.0.2",
- "kind-of": "6.0.2",
- "object.pick": "1.3.0",
- "regex-not": "1.0.0",
- "snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ },
+ "dependencies": {
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ }
}
}
}
@@ -14141,6 +15507,11 @@
"minimatch": "3.0.4"
}
},
+ "math-expression-evaluator": {
+ "version": "1.2.17",
+ "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
+ "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw="
+ },
"mathml-tag-names": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.0.1.tgz",
@@ -14423,9 +15794,9 @@
}
},
"metamask-logo": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/metamask-logo/-/metamask-logo-2.1.3.tgz",
- "integrity": "sha1-F1zleuUMc0Szsdwy0v0LCOOXj9A=",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/metamask-logo/-/metamask-logo-2.1.4.tgz",
+ "integrity": "sha512-hg/FzMfijpzGgLdZWH+KJKS56cRYaMEwcOq8UcnL/MznpgK4OMlJEaIfO8lg7P2F4Z74Ki+ulrTrFW6jf9L2bw==",
"requires": {
"gl-mat4": "1.1.4",
"gl-vec3": "1.0.3"
@@ -14491,8 +15862,7 @@
"mimic-response": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
- "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=",
- "dev": true
+ "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
},
"min-document": {
"version": "2.19.0",
@@ -14648,6 +16018,24 @@
}
}
},
+ "mixin-object": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
+ "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
+ "dev": true,
+ "requires": {
+ "for-in": "0.1.8",
+ "is-extendable": "0.1.1"
+ },
+ "dependencies": {
+ "for-in": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
+ "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
+ "dev": true
+ }
+ }
+ },
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
@@ -14663,6 +16051,14 @@
}
}
},
+ "mkdirp-promise": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz",
+ "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=",
+ "requires": {
+ "mkdirp": "0.5.1"
+ }
+ },
"mocha": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz",
@@ -14725,6 +16121,11 @@
"integrity": "sha1-cjqTEOfXN9e3fHpmghI3QlsDLUg=",
"dev": true
},
+ "mock-fs": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.4.2.tgz",
+ "integrity": "sha512-dF+yxZSojSiI8AXGoxj5qdFWpucndc54Ug+TwlpHFaV7j22MGG+OML2+FVa6xAZtjb/OFFQhOC37Jegx2GbEwA=="
+ },
"module-deps": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.0.0.tgz",
@@ -14770,6 +16171,11 @@
}
}
},
+ "mout": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz",
+ "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k="
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -14827,7 +16233,6 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dev": true,
"requires": {
"any-promise": "1.3.0",
"object-assign": "4.1.1",
@@ -14837,8 +16242,7 @@
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
- "dev": true
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
}
}
},
@@ -14847,11 +16251,15 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
"integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
},
+ "nano-json-stream-parser": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz",
+ "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18="
+ },
"nanomatch": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
"integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
- "dev": true,
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
@@ -14870,20 +16278,17 @@
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
},
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
},
"define-property": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
"integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "dev": true,
"requires": {
"is-descriptor": "1.0.2",
"isobject": "3.0.1"
@@ -14893,7 +16298,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
"integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "dev": true,
"requires": {
"assign-symbols": "1.0.0",
"is-extendable": "1.0.1"
@@ -14903,7 +16307,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
"requires": {
"is-plain-object": "2.0.4"
}
@@ -14911,14 +16314,12 @@
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
},
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
}
}
},
@@ -15170,6 +16571,7 @@
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz",
"integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==",
+ "dev": true,
"requires": {
"async-foreach": "0.1.3",
"chalk": "1.1.3",
@@ -15195,17 +16597,20 @@
"assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
- "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ="
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
},
"aws-sign2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
- "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8="
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
},
"boom": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
"requires": {
"hoek": "2.16.3"
}
@@ -15213,12 +16618,14 @@
"caseless": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
- "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
},
"cross-spawn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
"integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+ "dev": true,
"requires": {
"lru-cache": "4.1.1",
"which": "1.3.0"
@@ -15228,6 +16635,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
"requires": {
"boom": "2.10.1"
}
@@ -15236,6 +16644,7 @@
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
@@ -15245,12 +16654,14 @@
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
},
"har-validator": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
"requires": {
"chalk": "1.1.3",
"commander": "2.11.0",
@@ -15262,6 +16673,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
"requires": {
"boom": "2.10.1",
"cryptiles": "2.0.5",
@@ -15272,12 +16684,14 @@
"hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
},
"http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
"requires": {
"assert-plus": "0.2.0",
"jsprim": "1.4.1",
@@ -15287,12 +16701,14 @@
"qs": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
- "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw="
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
},
"request": {
"version": "2.79.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
"integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
"requires": {
"aws-sign2": "0.6.0",
"aws4": "1.6.0",
@@ -15320,6 +16736,7 @@
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
"requires": {
"hoek": "2.16.3"
}
@@ -15327,12 +16744,14 @@
"tunnel-agent": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
- "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us="
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
},
"uuid": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
- "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
+ "dev": true
}
}
},
@@ -15435,6 +16854,12 @@
"integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=",
"dev": true
},
+ "nodesecurity-npm-utils": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nodesecurity-npm-utils/-/nodesecurity-npm-utils-6.0.0.tgz",
+ "integrity": "sha512-NLRle1woNaT2orR6fue2jNqkhxDTktgJj3sZxvR/8kp21pvOY7Gwlx5wvo0H8ZVPqdgd2nE2ADB9wDu5Cl8zNg==",
+ "dev": true
+ },
"nomnom": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz",
@@ -15522,6 +16947,250 @@
"set-blocking": "2.0.0"
}
},
+ "nsp": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/nsp/-/nsp-3.2.1.tgz",
+ "integrity": "sha512-dLmGi7IGixJEHKetErIH460MYiYIzAoxuVsloZFu9e1p9U8K0yULx7YQ1+VzrjZbB+wqq67ES1SfOvKVb/qMDQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.4.1",
+ "cli-table2": "0.2.0",
+ "cvss": "1.0.2",
+ "https-proxy-agent": "2.2.1",
+ "inquirer": "3.3.0",
+ "nodesecurity-npm-utils": "6.0.0",
+ "semver": "5.4.1",
+ "wreck": "12.5.1",
+ "yargs": "9.0.1"
+ },
+ "dependencies": {
+ "agent-base": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
+ "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
+ "dev": true,
+ "requires": {
+ "es6-promisify": "5.0.0"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.1",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "5.4.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "https-proxy-agent": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+ "dev": true,
+ "requires": {
+ "agent-base": "4.2.0",
+ "debug": "3.1.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "0.7.0",
+ "lcid": "1.0.0",
+ "mem": "1.1.0"
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "2.0.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "read-pkg": "2.0.0"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "3.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz",
+ "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "read-pkg-up": "2.0.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "7.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+ "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ }
+ }
+ }
+ },
"nth-check": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
@@ -17471,6 +19140,12 @@
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
},
+ "object-path": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz",
+ "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=",
+ "dev": true
+ },
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -17541,7 +19216,7 @@
"integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
"requires": {
"for-own": "1.0.0",
- "make-iterator": "1.0.0"
+ "make-iterator": "1.0.1"
},
"dependencies": {
"for-own": {
@@ -17584,7 +19259,7 @@
"integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
"requires": {
"for-own": "1.0.0",
- "make-iterator": "1.0.0"
+ "make-iterator": "1.0.1"
},
"dependencies": {
"for-own": {
@@ -17609,6 +19284,14 @@
"has": "1.0.1"
}
},
+ "oboe": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz",
+ "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=",
+ "requires": {
+ "http-https": "1.0.0"
+ }
+ },
"obs-store": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/obs-store/-/obs-store-3.0.0.tgz",
@@ -17827,8 +19510,7 @@
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
},
"p-is-promise": {
"version": "1.1.0",
@@ -18056,6 +19738,24 @@
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
},
+ "path": {
+ "version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+ "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=",
+ "dev": true,
+ "requires": {
+ "process": "0.11.10",
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ }
+ }
+ },
"path-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
@@ -18185,8 +19885,7 @@
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
- "dev": true
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
},
"percentile": {
"version": "1.2.0",
@@ -18563,6 +20262,364 @@
}
}
},
+ "postcss-calc": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
+ "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-message-helpers": "2.0.0",
+ "reduce-css-calc": "1.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-colormin": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
+ "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
+ "requires": {
+ "colormin": "1.1.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-convert-values": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
+ "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
+ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-duplicates": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
+ "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-empty": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
+ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
+ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-unused": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
+ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
+ "requires": {
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-filter-plugins": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz",
+ "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
+ "requires": {
+ "postcss": "5.2.18",
+ "uniqid": "4.1.1"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
"postcss-less": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz",
@@ -18613,6 +20670,617 @@
"integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=",
"dev": true
},
+ "postcss-merge-idents": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
+ "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-merge-longhand": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
+ "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
+ "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-api": "1.6.1",
+ "postcss": "5.2.18",
+ "postcss-selector-parser": "2.2.3",
+ "vendors": "1.0.2"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "requires": {
+ "caniuse-db": "1.0.30000808",
+ "electron-to-chromium": "1.3.30"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-message-helpers": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
+ "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4="
+ },
+ "postcss-minify-font-values": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
+ "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-minify-params": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
+ "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0",
+ "uniqs": "2.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
+ "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-selector-parser": "2.2.3"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-modules-extract-imports": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz",
+ "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=",
+ "requires": {
+ "postcss": "6.0.19"
+ }
+ },
+ "postcss-modules-local-by-default": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
+ "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
+ "requires": {
+ "css-selector-tokenizer": "0.7.0",
+ "postcss": "6.0.19"
+ }
+ },
+ "postcss-modules-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
+ "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
+ "requires": {
+ "css-selector-tokenizer": "0.7.0",
+ "postcss": "6.0.19"
+ }
+ },
+ "postcss-modules-values": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
+ "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
+ "requires": {
+ "icss-replace-symbols": "1.1.0",
+ "postcss": "6.0.19"
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
+ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
+ "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
+ "requires": {
+ "is-absolute-url": "2.1.0",
+ "normalize-url": "1.9.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "normalize-url": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+ "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "prepend-http": "1.0.4",
+ "query-string": "4.3.4",
+ "sort-keys": "1.1.2"
+ }
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "query-string": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+ "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+ "requires": {
+ "object-assign": "4.1.1",
+ "strict-uri-encode": "1.1.0"
+ }
+ },
+ "sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+ "requires": {
+ "is-plain-obj": "1.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
+ "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-idents": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
+ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
+ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
+ "requires": {
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
+ "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
"postcss-reporter": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz",
@@ -18714,7 +21382,6 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
"integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
- "dev": true,
"requires": {
"flatten": "1.0.2",
"indexes-of": "1.0.1",
@@ -18724,8 +21391,7 @@
"flatten": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
- "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
- "dev": true
+ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I="
}
}
},
@@ -18774,16 +21440,163 @@
}
}
},
+ "postcss-svgo": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
+ "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
+ "requires": {
+ "is-svg": "2.1.0",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0",
+ "svgo": "0.7.2"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-unique-selectors": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
+ "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
"postcss-value-parser": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
"integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU="
},
+ "postcss-zindex": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
+ "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "precond": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
+ "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw="
+ },
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
+ "prepend-file": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz",
+ "integrity": "sha1-g7FuC0rBkB/OiNvZRaIvTMgd9Xk=",
+ "requires": {
+ "tmp": "0.0.31"
+ },
+ "dependencies": {
+ "tmp": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
+ "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
+ "requires": {
+ "os-tmpdir": "1.0.2"
+ }
+ }
+ }
+ },
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
@@ -18886,9 +21699,9 @@
}
},
"prop-types": {
- "version": "15.6.0",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
- "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+ "version": "15.6.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
+ "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"requires": {
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
@@ -18979,6 +21792,52 @@
"randombytes": "2.0.5"
}
},
+ "pull-cat": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz",
+ "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs="
+ },
+ "pull-level": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz",
+ "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==",
+ "requires": {
+ "level-post": "1.0.7",
+ "pull-cat": "1.1.11",
+ "pull-live": "1.0.1",
+ "pull-pushable": "2.2.0",
+ "pull-stream": "3.6.7",
+ "pull-window": "2.1.4",
+ "stream-to-pull-stream": "1.7.2"
+ }
+ },
+ "pull-live": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz",
+ "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=",
+ "requires": {
+ "pull-cat": "1.1.11",
+ "pull-stream": "3.6.7"
+ }
+ },
+ "pull-pushable": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz",
+ "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE="
+ },
+ "pull-stream": {
+ "version": "3.6.7",
+ "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.7.tgz",
+ "integrity": "sha512-XdE2/o1I2lK7A+sbbA/HjYnd5Xk7wL5CwAKzqHIgcBsluDb0LiKHNTl1K0it3/RKPshQljLf4kl1aJ12YsCCGQ=="
+ },
+ "pull-window": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz",
+ "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=",
+ "requires": {
+ "looper": "2.0.0"
+ }
+ },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -19039,7 +21898,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
- "dev": true,
"requires": {
"decode-uri-component": "0.2.0",
"object-assign": "4.1.1",
@@ -19079,7 +21937,7 @@
"requires": {
"anymatch": "1.3.2",
"async-each": "1.0.1",
- "fsevents": "1.1.3",
+ "fsevents": "1.2.2",
"glob-parent": "2.0.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -19195,6 +22053,12 @@
}
}
},
+ "radgrad-jsdoc-template": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/radgrad-jsdoc-template/-/radgrad-jsdoc-template-1.1.3.tgz",
+ "integrity": "sha512-yk1XB6NlrP6JIr3xHzCrNwCmkONNgqM+sZxFAdmTU/CsaT7N/lns2/Wfa048li3wrao5b6KwYrdu6KgiGh9nIQ==",
+ "dev": true
+ },
"raf": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz",
@@ -19278,6 +22142,11 @@
"safe-buffer": "5.1.1"
}
},
+ "randomhex": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
+ "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU="
+ },
"range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
@@ -19292,9 +22161,9 @@
}
},
"raven-js": {
- "version": "3.24.0",
- "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.0.tgz",
- "integrity": "sha512-+/ygcWib8PXAE7Xq53j1tYxCgkzFyp9z05LYAKp2PA9KwO4Ek74q1tkGwZyPWI/FoXOgas6jNtQ7O3tdPif6uA=="
+ "version": "3.24.2",
+ "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.2.tgz",
+ "integrity": "sha512-Dy/FHDxuo5pXywVf8Nrs5utB2juMATpkxWGqHjVbpFD3m8CaWYLvkB5SEXjWFUZ5GvUsrBVVQ+Dfcp0x6Z7SOg=="
},
"raw-body": {
"version": "2.3.2",
@@ -19316,7 +22185,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-addons-css-transition-group": {
@@ -19335,7 +22204,7 @@
"chain-function": "1.0.0",
"dom-helpers": "3.3.1",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"warning": "3.0.0"
}
}
@@ -19355,7 +22224,7 @@
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-hyperscript": {
@@ -19368,7 +22237,7 @@
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.1.2.tgz",
"integrity": "sha512-uAfIE4XEfBNXqjqQvd31Eoo20UkVk0xHJpfgP8HRT8gLczaN4LEmB1e2d8CJ5ziEt4clWnsk/1+QhTN27iO/EA==",
"requires": {
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-markdown": {
@@ -19376,7 +22245,7 @@
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-3.1.4.tgz",
"integrity": "sha512-i8WueytRXbYzyJ2GemIOTMRx/NigPo8r4m3R/KvWD7r+PxPyc9ke66cI3DR7MBRSS+nVG82VWEgRDE1VaZUCqA==",
"requires": {
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"remark-parse": "4.0.0",
"unified": "6.1.6",
"unist-util-visit": "1.3.0",
@@ -19389,7 +22258,7 @@
"integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==",
"requires": {
"performance-now": "0.2.0",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"raf": "3.4.0"
},
"dependencies": {
@@ -19410,7 +22279,49 @@
"lodash": "4.17.4",
"lodash-es": "4.17.4",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
+ }
+ },
+ "react-router": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
+ "integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==",
+ "requires": {
+ "history": "4.7.2",
+ "hoist-non-react-statics": "2.3.1",
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "path-to-regexp": "1.7.0",
+ "prop-types": "15.6.1",
+ "warning": "3.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz",
+ "integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==",
+ "requires": {
+ "history": "4.7.2",
+ "invariant": "2.2.2",
+ "loose-envify": "1.3.1",
+ "prop-types": "15.6.1",
+ "react-router": "4.2.0",
+ "warning": "3.0.0"
}
},
"react-select": {
@@ -19419,7 +22330,7 @@
"integrity": "sha512-c4CdxweEHN9ra85HGWjSjIMBlJ5c0fsIXOymLFZS5UbZEQCiJGHnZTVLTt6/wDh8RKQnxl85gHUwzhG5XZLcyw==",
"requires": {
"classnames": "2.2.5",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"react-input-autosize": "2.1.2"
}
},
@@ -19428,7 +22339,7 @@
"resolved": "https://registry.npmjs.org/react-simple-file-input/-/react-simple-file-input-2.0.1.tgz",
"integrity": "sha1-Fa1P/Hj+sbiCZJrWsBwDPvJ1ceY=",
"requires": {
- "prop-types": "15.6.0"
+ "prop-types": "15.6.1"
}
},
"react-test-renderer": {
@@ -19472,7 +22383,7 @@
"resolved": "https://registry.npmjs.org/react-toggle-button/-/react-toggle-button-2.2.0.tgz",
"integrity": "sha1-obkhQ6oN9BRkL8sUHwh59UW8Wok=",
"requires": {
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"react-motion": "0.5.2"
}
},
@@ -19499,7 +22410,7 @@
"classnames": "2.2.5",
"dom-helpers": "3.3.1",
"loose-envify": "1.3.1",
- "prop-types": "15.6.0",
+ "prop-types": "15.6.1",
"warning": "3.0.0"
}
},
@@ -19710,6 +22621,38 @@
"dev": true,
"optional": true
},
+ "reduce-css-calc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
+ "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
+ "requires": {
+ "balanced-match": "0.4.2",
+ "math-expression-evaluator": "1.2.17",
+ "reduce-function-call": "1.0.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
+ }
+ }
+ },
+ "reduce-function-call": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
+ "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
+ "requires": {
+ "balanced-match": "0.4.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
+ }
+ }
+ },
"redux": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
@@ -19776,6 +22719,12 @@
"extend-shallow": "2.0.1"
}
},
+ "regex-parser": {
+ "version": "2.2.9",
+ "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.9.tgz",
+ "integrity": "sha512-VncXxOF6uFlYog5prG2j+e2UGJeam5MfNiJnB/qEgo4KTnMm2XrELCg4rNZ6IlaEUZnGlb8aB6lXowCRQtTkkA==",
+ "dev": true
+ },
"regexpu-core": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
@@ -20011,6 +22960,23 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
+ "requizzle": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz",
+ "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=",
+ "dev": true,
+ "requires": {
+ "underscore": "1.6.0"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+ "dev": true
+ }
+ }
+ },
"resolve": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
@@ -20058,11 +23024,64 @@
"value-or-function": "3.0.0"
}
},
+ "resolve-pathname": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
+ "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
},
+ "resolve-url-loader": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-2.3.0.tgz",
+ "integrity": "sha512-RaEUWgF/B6aTg9VKaOv2o6dfm5f75/lGh8S+SQwoMcBm48WkA2nhLR+V7KEawkxXjU4lLB16IVeHCe7F69nyVw==",
+ "dev": true,
+ "requires": {
+ "adjust-sourcemap-loader": "1.2.0",
+ "camelcase": "4.1.0",
+ "convert-source-map": "1.5.1",
+ "loader-utils": "1.1.0",
+ "lodash.defaults": "4.2.0",
+ "rework": "1.0.1",
+ "rework-visit": "1.0.0",
+ "source-map": "0.5.7",
+ "urix": "0.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
"response-stream": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/response-stream/-/response-stream-0.0.0.tgz",
@@ -20098,8 +23117,7 @@
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
"revalidator": {
"version": "0.1.8",
@@ -20107,6 +23125,30 @@
"integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=",
"dev": true
},
+ "rework": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
+ "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "0.3.5",
+ "css": "2.2.1"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
+ "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=",
+ "dev": true
+ }
+ }
+ },
+ "rework-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz",
+ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=",
+ "dev": true
+ },
"right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -20199,7 +23241,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "dev": true,
"requires": {
"ret": "0.1.15"
}
@@ -20282,11 +23323,63 @@
}
}
},
+ "sass-loader": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.0.1.tgz",
+ "integrity": "sha512-MeVVJFejJELlAbA7jrRchi88PGP6U9yIfqyiG+bBC4a9s2PX+ulJB9h8bbEohtPBfZmlLhNZ0opQM9hovRXvlw==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "2.0.2",
+ "loader-utils": "1.1.0",
+ "lodash.tail": "4.1.1",
+ "neo-async": "2.5.0",
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ }
+ }
+ },
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
- "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "schema-utils": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
+ "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
+ "requires": {
+ "ajv": "6.4.0",
+ "ajv-keywords": "3.2.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz",
+ "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=",
+ "requires": {
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1",
+ "uri-js": "3.0.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
+ }
+ }
},
"scoped-regex": {
"version": "1.0.0",
@@ -20373,6 +23466,16 @@
"requires": {
"js-base64": "2.4.3",
"source-map": "0.4.4"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
}
},
"secp256k1": {
@@ -20390,6 +23493,29 @@
"safe-buffer": "5.1.1"
}
},
+ "seedrandom": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
+ "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw="
+ },
+ "seek-bzip": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
+ "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
+ "requires": {
+ "commander": "2.8.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+ "requires": {
+ "graceful-readlink": "1.0.1"
+ }
+ }
+ }
+ },
"selenium-webdriver": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
@@ -20462,6 +23588,18 @@
"send": "0.16.1"
}
},
+ "servify": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz",
+ "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==",
+ "requires": {
+ "body-parser": "1.18.2",
+ "cors": "2.8.4",
+ "express": "4.16.2",
+ "request": "2.83.0",
+ "xhr": "2.4.1"
+ }
+ },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -20518,6 +23656,25 @@
"nan": "2.8.0"
}
},
+ "shallow-clone": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
+ "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1",
+ "kind-of": "5.1.0",
+ "mixin-object": "2.0.1"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
"shallow-copy": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
@@ -20552,6 +23709,11 @@
"shebang-regex": "1.0.0"
}
},
+ "shebang-loader": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/shebang-loader/-/shebang-loader-0.0.1.tgz",
+ "integrity": "sha1-pAAEldRMzu++xjQ157FphWn6Uuw="
+ },
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
@@ -20724,6 +23886,21 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
+ "simple-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
+ },
+ "simple-get": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+ "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
+ "requires": {
+ "decompress-response": "3.3.0",
+ "once": "1.4.0",
+ "simple-concat": "1.0.0"
+ }
+ },
"sinon": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-5.0.0.tgz",
@@ -21122,9 +24299,9 @@
}
},
"solc": {
- "version": "0.4.21",
- "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.21.tgz",
- "integrity": "sha512-8lJmimVjOG9AJOQRWS2ph4rSctPMsPGZ4H360HLs5iI+euUlt7iAvUxSLeFZZzwk0kas4Qta7HmlMXNU3yYwhw==",
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.23.tgz",
+ "integrity": "sha512-AT7anLHY6uIRg2It6N0UlCHeZ7YeecIkUhnlirrCgCPCUevtnoN48BxvgigN/4jJTRljv5oFhAJtI6gvHzT5DQ==",
"requires": {
"fs-extra": "0.30.0",
"memorystream": "0.3.1",
@@ -21180,12 +24357,10 @@
"integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A=="
},
"source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "requires": {
- "amdefine": "1.0.1"
- }
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.2.tgz",
+ "integrity": "sha512-NDJB/R2BS7YJG0tP9SbE4DKwKj1idLT5RJqfVYZ7dreFX7wulZT3xxVhbYKrQo9n0JkRptl51TrX/5VK3HodMA==",
+ "dev": true
},
"source-map-resolve": {
"version": "0.5.1",
@@ -21382,7 +24557,7 @@
"requires": {
"esprima": "1.0.4",
"estraverse": "1.3.2",
- "source-map": "0.4.4"
+ "source-map": "0.7.2"
}
},
"esprima": {
@@ -21705,6 +24880,22 @@
"any-observable": "0.2.0"
}
},
+ "stream-to-pull-stream": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz",
+ "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=",
+ "requires": {
+ "looper": "3.0.0",
+ "pull-stream": "3.6.7"
+ },
+ "dependencies": {
+ "looper": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
+ "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k="
+ }
+ }
+ },
"streamroller": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz",
@@ -21731,8 +24922,7 @@
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
- "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
- "dev": true
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
},
"string-length": {
"version": "1.0.1",
@@ -21824,6 +25014,14 @@
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
"dev": true
},
+ "strip-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+ "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+ "requires": {
+ "is-natural-number": "4.0.1"
+ }
+ },
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@@ -21858,6 +25056,29 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
+ "style-loader": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz",
+ "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "1.1.0",
+ "schema-utils": "0.4.5"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ }
+ }
+ },
"style-search": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -22393,6 +25614,41 @@
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
"dev": true
},
+ "svgo": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
+ "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
+ "requires": {
+ "coa": "1.0.4",
+ "colors": "1.1.2",
+ "csso": "2.3.2",
+ "js-yaml": "3.7.0",
+ "mkdirp": "0.5.1",
+ "sax": "1.2.4",
+ "whet.extend": "0.9.9"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM="
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
+ },
+ "js-yaml": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
+ "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "2.7.3"
+ }
+ }
+ }
+ },
"sw-controller": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sw-controller/-/sw-controller-1.0.3.tgz",
@@ -22448,6 +25704,84 @@
}
}
},
+ "swarm-js": {
+ "version": "0.1.37",
+ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz",
+ "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==",
+ "requires": {
+ "bluebird": "3.5.1",
+ "buffer": "5.1.0",
+ "decompress": "4.2.0",
+ "eth-lib": "0.1.27",
+ "fs-extra": "2.1.2",
+ "fs-promise": "2.0.3",
+ "got": "7.1.0",
+ "mime-types": "2.1.17",
+ "mkdirp-promise": "5.0.1",
+ "mock-fs": "4.4.2",
+ "setimmediate": "1.0.5",
+ "tar.gz": "1.0.7",
+ "xhr-request-promise": "0.1.2"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
+ "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "2.4.0"
+ }
+ },
+ "got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "requires": {
+ "decompress-response": "3.3.0",
+ "duplexer3": "0.1.4",
+ "get-stream": "3.0.0",
+ "is-plain-obj": "1.1.0",
+ "is-retry-allowed": "1.1.0",
+ "is-stream": "1.1.0",
+ "isurl": "1.0.0",
+ "lowercase-keys": "1.0.1",
+ "p-cancelable": "0.3.0",
+ "p-timeout": "1.2.1",
+ "safe-buffer": "5.1.1",
+ "timed-out": "4.0.1",
+ "url-parse-lax": "1.0.0",
+ "url-to-options": "1.0.1"
+ }
+ },
+ "p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
+ },
+ "p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+ "requires": {
+ "p-finally": "1.0.0"
+ }
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "1.0.4"
+ }
+ }
+ }
+ },
"symbol-observable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.1.0.tgz",
@@ -22553,6 +25887,12 @@
}
}
},
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
"tap-parser": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz",
@@ -22599,11 +25939,43 @@
"inherits": "2.0.3"
}
},
+ "tar-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz",
+ "integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==",
+ "requires": {
+ "bl": "1.2.1",
+ "buffer-alloc": "1.1.0",
+ "end-of-stream": "1.4.0",
+ "fs-constants": "1.0.0",
+ "readable-stream": "2.3.3",
+ "to-buffer": "1.1.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "tar.gz": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz",
+ "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==",
+ "requires": {
+ "bluebird": "2.11.0",
+ "commander": "2.11.0",
+ "fstream": "1.0.11",
+ "mout": "0.11.1",
+ "tar": "2.2.1"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
+ "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
+ }
+ }
+ },
"temp": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
"integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
- "dev": true,
"requires": {
"os-tmpdir": "1.0.2",
"rimraf": "2.2.8"
@@ -22612,8 +25984,7 @@
"rimraf": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
- "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
- "dev": true
+ "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
}
}
},
@@ -22832,7 +26203,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
"integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=",
- "dev": true,
"requires": {
"any-promise": "1.3.0"
},
@@ -22840,8 +26210,7 @@
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
- "dev": true
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
}
}
},
@@ -22849,7 +26218,6 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
"integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
- "dev": true,
"requires": {
"thenify": "3.3.0"
}
@@ -22900,8 +26268,7 @@
"timed-out": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
},
"timers-browserify": {
"version": "1.4.2",
@@ -22937,6 +26304,11 @@
"dev": true,
"optional": true
},
+ "tiny-queue": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.0.tgz",
+ "integrity": "sha1-xJ/LXIdVW+G0pd9+uHEB1beLydw="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -22965,6 +26337,11 @@
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
},
+ "to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
+ },
"to-fast-properties": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
@@ -23267,62 +26644,43 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "requires": {
+ "is-typedarray": "1.0.0"
+ }
+ },
+ "typewise": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz",
+ "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=",
+ "requires": {
+ "typewise-core": "1.2.0"
+ }
+ },
+ "typewise-core": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz",
+ "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU="
+ },
+ "typewiselite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz",
+ "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4="
+ },
"ua-parser-js": {
"version": "0.7.17",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
},
- "uglify-es": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.4.tgz",
- "integrity": "sha512-vDOyDaf7LcABZI5oJt8bin5FD8kYONux5jd8FY6SsV2SfD+MMXaPeGUotysbycSxdu170y5IQ8FvlKzU/TUryw==",
- "dev": true,
- "requires": {
- "commander": "2.12.2",
- "source-map": "0.6.1"
- },
- "dependencies": {
- "commander": {
- "version": "2.12.2",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
- "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
"uglify-to-browserify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"optional": true
},
- "uglifyify": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/uglifyify/-/uglifyify-4.0.5.tgz",
- "integrity": "sha512-vVvJjL5rxAbvUs5m0zfxLCwy5fu6+6HBRY06cpWfOGTtKgAONWy7HDovTr28Y7kwXFNAAt+OMbRGP6ulqWqakA==",
- "dev": true,
- "requires": {
- "convert-source-map": "1.1.3",
- "extend": "1.3.0",
- "minimatch": "3.0.4",
- "through": "2.3.8",
- "uglify-es": "3.3.4"
- },
- "dependencies": {
- "extend": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extend/-/extend-1.3.0.tgz",
- "integrity": "sha1-0VFvsP9WJNLr+RI+odrFoZlABPg=",
- "dev": true
- }
- }
- },
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
@@ -23334,6 +26692,32 @@
"resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz",
"integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4="
},
+ "unbzip2-stream": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz",
+ "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==",
+ "requires": {
+ "buffer": "3.6.0",
+ "through": "2.3.8"
+ },
+ "dependencies": {
+ "base64-js": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+ "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg="
+ },
+ "buffer": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
+ "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
+ "requires": {
+ "base64-js": "0.0.8",
+ "ieee754": "1.1.8",
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
"unc-path-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
@@ -23345,6 +26729,23 @@
"integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=",
"dev": true
},
+ "underscore-contrib": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/underscore-contrib/-/underscore-contrib-0.3.0.tgz",
+ "integrity": "sha1-ZltmwkeD+PorGMn4y7Dix9SMJsc=",
+ "dev": true,
+ "requires": {
+ "underscore": "1.6.0"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+ "dev": true
+ }
+ }
+ },
"undertaker": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz",
@@ -23418,6 +26819,19 @@
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
},
+ "uniqid": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
+ "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=",
+ "requires": {
+ "macaddress": "0.2.8"
+ }
+ },
+ "uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI="
+ },
"unique-stream": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz",
@@ -23516,6 +26930,21 @@
"integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==",
"dev": true
},
+ "uri-js": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz",
+ "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=",
+ "requires": {
+ "punycode": "2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+ "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0="
+ }
+ }
+ },
"urix": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
@@ -23546,11 +26975,15 @@
"prepend-http": "2.0.0"
}
},
+ "url-set-query": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
+ "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk="
+ },
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
- "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
- "dev": true
+ "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
},
"use": {
"version": "2.0.2",
@@ -23736,6 +27169,11 @@
"spdx-expression-parse": "1.0.4"
}
},
+ "value-equal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
+ "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
+ },
"value-or-function": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
@@ -23751,6 +27189,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
+ "vendors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
+ "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ=="
+ },
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@@ -24193,32 +27636,386 @@
}
}
},
+ "web3-bzz": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.34.tgz",
+ "integrity": "sha1-Bo03d3q2Xlxg+OyLmlDP5FJ3kpw=",
+ "requires": {
+ "got": "7.1.0",
+ "swarm-js": "0.1.37",
+ "underscore": "1.8.3"
+ },
+ "dependencies": {
+ "got": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+ "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+ "requires": {
+ "decompress-response": "3.3.0",
+ "duplexer3": "0.1.4",
+ "get-stream": "3.0.0",
+ "is-plain-obj": "1.1.0",
+ "is-retry-allowed": "1.1.0",
+ "is-stream": "1.1.0",
+ "isurl": "1.0.0",
+ "lowercase-keys": "1.0.1",
+ "p-cancelable": "0.3.0",
+ "p-timeout": "1.2.1",
+ "safe-buffer": "5.1.1",
+ "timed-out": "4.0.1",
+ "url-parse-lax": "1.0.0",
+ "url-to-options": "1.0.1"
+ }
+ },
+ "p-cancelable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+ "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
+ },
+ "p-timeout": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+ "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+ "requires": {
+ "p-finally": "1.0.0"
+ }
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "requires": {
+ "prepend-http": "1.0.4"
+ }
+ }
+ }
+ },
+ "web3-core": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.34.tgz",
+ "integrity": "sha1-EhvoVV6fsA0sXQXd0zgdDJ5GmH4=",
+ "requires": {
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-requestmanager": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-core-helpers": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz",
+ "integrity": "sha1-sWjaANPhnhVrwVriAyA91N/uLQM=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-eth-iban": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-core-method": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz",
+ "integrity": "sha1-7BY8iixJD6AqfsFVWfpzB/x8xt0=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-promievent": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-core-promievent": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz",
+ "integrity": "sha1-pPT6Z4S7KT6CxglgrltWqUzQPtw=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "eventemitter3": "1.1.1"
+ },
+ "dependencies": {
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "eventemitter3": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz",
+ "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA="
+ }
+ }
+ },
+ "web3-core-requestmanager": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz",
+ "integrity": "sha1-Afj2zyrmtvC3DDi64e90G1urIVw=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-providers-http": "1.0.0-beta.34",
+ "web3-providers-ipc": "1.0.0-beta.34",
+ "web3-providers-ws": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-core-subscriptions": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz",
+ "integrity": "sha1-n+0UQDPyIcPPIQYDAv/a9e8t4t4=",
+ "requires": {
+ "eventemitter3": "1.1.1",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "eventemitter3": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz",
+ "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA="
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-eth": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.34.tgz",
+ "integrity": "sha1-dAhgAIUMb+b1Ne9Jg31tS7YRMmg=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-eth-abi": "1.0.0-beta.34",
+ "web3-eth-accounts": "1.0.0-beta.34",
+ "web3-eth-contract": "1.0.0-beta.34",
+ "web3-eth-iban": "1.0.0-beta.34",
+ "web3-eth-personal": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-eth-abi": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz",
+ "integrity": "sha1-A0Uz46ovfln/MXk+rqaFwO1a9no=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-eth-accounts": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz",
+ "integrity": "sha1-4JFC7uzHl6w0WbdemyOUbTaV8zM=",
+ "requires": {
+ "any-promise": "1.3.0",
+ "crypto-browserify": "3.12.0",
+ "eth-lib": "0.2.7",
+ "scrypt.js": "0.2.0",
+ "underscore": "1.8.3",
+ "uuid": "2.0.1",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ },
+ "eth-lib": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
+ "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "elliptic": "6.4.0",
+ "xhr-request-promise": "0.1.2"
+ }
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "uuid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
+ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w="
+ }
+ }
+ },
+ "web3-eth-contract": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz",
+ "integrity": "sha1-nbs4+udkOoCEJ6IBgEcOx0FckeY=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-promievent": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-eth-abi": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-eth-iban": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz",
+ "integrity": "sha1-mvRYYFhnzPdOqXmq8yazi6alugw=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "web3-utils": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ }
+ }
+ },
+ "web3-eth-personal": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz",
+ "integrity": "sha1-mvuhZzQuveVCC81YlcP2w0OI8gU=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
+ "web3-net": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.34.tgz",
+ "integrity": "sha1-QnzqL0MYgUScjjjVIykPFz+f9j0=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-utils": "1.0.0-beta.34"
+ }
+ },
"web3-provider-engine": {
- "version": "13.8.0",
- "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz",
- "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==",
+ "version": "14.0.5",
+ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.0.5.tgz",
+ "integrity": "sha512-1W/ue7VOwOMnmKgMY3HCpbixi6qhfl4r1dK8W597AwJLbrQ+twJKwWlFAedDpJjCc9MwRCCB3pyexW4HJVSiBg==",
"requires": {
"async": "2.6.0",
+ "backoff": "2.5.0",
"clone": "2.1.1",
- "eth-block-tracker": "2.3.0",
+ "cross-fetch": "2.1.0",
+ "eth-block-tracker": "3.0.0",
+ "eth-json-rpc-infura": "3.1.0",
"eth-sig-util": "1.4.2",
"ethereumjs-block": "1.7.0",
"ethereumjs-tx": "1.3.3",
"ethereumjs-util": "5.1.5",
- "ethereumjs-vm": "2.3.2",
- "fetch-ponyfill": "4.1.0",
+ "ethereumjs-vm": "2.3.5",
"json-rpc-error": "2.0.0",
"json-stable-stringify": "1.0.1",
"promise-to-callback": "1.0.0",
"readable-stream": "2.3.3",
"request": "2.83.0",
"semaphore": "1.1.0",
- "solc": "0.4.21",
"tape": "4.8.0",
+ "ws": "5.1.1",
"xhr": "2.4.1",
"xtend": "4.0.1"
},
"dependencies": {
+ "eth-block-tracker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.0.tgz",
+ "integrity": "sha512-Lhhu/+1GOeekMRDRhUcM7VSJRmX279DByrwzEbmG0JL1tcT3xRo6GLNXnidyJ7ahHJm+0JFhw/RqtTeIxagQwA==",
+ "requires": {
+ "eth-query": "2.1.2",
+ "ethereumjs-tx": "1.3.3",
+ "ethereumjs-util": "5.1.5",
+ "ethjs-util": "0.1.4",
+ "json-rpc-engine": "3.6.1",
+ "pify": "2.3.0",
+ "tape": "4.8.0"
+ }
+ },
+ "eth-json-rpc-infura": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.1.0.tgz",
+ "integrity": "sha512-uMYkEP6fga8CyNo8TMoA/7cxi6bL3V8pTvjKQikOi9iYl6/AO5xlfgniyAMElSiq2mmXz3lYa/9VYDMzt/J5aA==",
+ "requires": {
+ "cross-fetch": "2.1.0",
+ "eth-json-rpc-middleware": "1.6.0",
+ "json-rpc-engine": "3.6.1",
+ "json-rpc-error": "2.0.0",
+ "tape": "4.8.0"
+ }
+ },
"ethereumjs-util": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
@@ -24232,9 +28029,110 @@
"safe-buffer": "5.1.1",
"secp256k1": "3.4.0"
}
+ },
+ "ethereumjs-vm": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz",
+ "integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==",
+ "requires": {
+ "async": "2.6.0",
+ "async-eventemitter": "0.2.4",
+ "ethereum-common": "0.2.0",
+ "ethereumjs-account": "2.0.4",
+ "ethereumjs-block": "1.7.0",
+ "ethereumjs-util": "5.1.5",
+ "fake-merkle-patricia-tree": "1.0.1",
+ "functional-red-black-tree": "1.0.1",
+ "merkle-patricia-tree": "2.3.0",
+ "rustbn.js": "0.1.1",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "ws": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.1.1.tgz",
+ "integrity": "sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw==",
+ "requires": {
+ "async-limiter": "1.0.0"
+ }
+ }
+ }
+ },
+ "web3-providers-http": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz",
+ "integrity": "sha1-5WG1K7tDdmKCAH1AKFv+NVDCfno=",
+ "requires": {
+ "web3-core-helpers": "1.0.0-beta.34",
+ "xhr2": "0.1.4"
+ },
+ "dependencies": {
+ "xhr2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz",
+ "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8="
}
}
},
+ "web3-providers-ipc": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz",
+ "integrity": "sha1-obd/GjBtc2SanAOQUuQMtxMo0Ao=",
+ "requires": {
+ "oboe": "2.1.3",
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ }
+ }
+ },
+ "web3-providers-ws": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz",
+ "integrity": "sha1-fecPG4Py3jZHZ3IVa+z+9uNRbrM=",
+ "requires": {
+ "underscore": "1.8.3",
+ "web3-core-helpers": "1.0.0-beta.34",
+ "websocket": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "websocket": {
+ "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c",
+ "requires": {
+ "debug": "2.6.9",
+ "nan": "2.8.0",
+ "typedarray-to-buffer": "3.1.5",
+ "yaeti": "0.0.6"
+ }
+ }
+ }
+ },
+ "web3-shh": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.34.tgz",
+ "integrity": "sha1-l1Bh1x6uxCzO5Xb3vY9w8DhEr+A=",
+ "requires": {
+ "web3-core": "1.0.0-beta.34",
+ "web3-core-method": "1.0.0-beta.34",
+ "web3-core-subscriptions": "1.0.0-beta.34",
+ "web3-net": "1.0.0-beta.34"
+ }
+ },
"web3-stream-provider": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/web3-stream-provider/-/web3-stream-provider-3.0.1.tgz",
@@ -24243,6 +28141,37 @@
"readable-stream": "2.3.3"
}
},
+ "web3-utils": {
+ "version": "1.0.0-beta.34",
+ "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.34.tgz",
+ "integrity": "sha1-lBH8OarvOcpOBhafdiKX2f8CCXA=",
+ "requires": {
+ "bn.js": "4.11.6",
+ "eth-lib": "0.1.27",
+ "ethjs-unit": "0.1.6",
+ "number-to-bn": "1.7.0",
+ "randomhex": "0.1.5",
+ "underscore": "1.8.3",
+ "utf8": "2.1.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "utf8": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz",
+ "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g="
+ }
+ }
+ },
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
@@ -24780,6 +28709,17 @@
}
}
},
+ "websocket": {
+ "version": "1.0.26",
+ "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.26.tgz",
+ "integrity": "sha512-fjcrYDPIQxpTnqFQ9JjxUQcdvR89MFAOjPBlF+vjOt49w/XW4fJknUoMz/mDIn2eK1AdslVojcaOxOqyZZV8rw==",
+ "requires": {
+ "debug": "2.6.9",
+ "nan": "2.8.0",
+ "typedarray-to-buffer": "3.1.5",
+ "yaeti": "0.0.6"
+ }
+ },
"websocket-driver": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
@@ -24828,6 +28768,11 @@
"dev": true,
"optional": true
},
+ "whet.extend": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
+ "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE="
+ },
"which": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
@@ -24908,6 +28853,27 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
+ "wreck": {
+ "version": "12.5.1",
+ "resolved": "https://registry.npmjs.org/wreck/-/wreck-12.5.1.tgz",
+ "integrity": "sha512-l5DUGrc+yDyIflpty1x9XuMj1ehVjC/dTbF3/BasOO77xk0EdEa4M/DuOY8W88MQDAD0fEDqyjc8bkIMHd2E9A==",
+ "dev": true,
+ "requires": {
+ "boom": "5.2.0",
+ "hoek": "4.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ }
+ }
+ },
"write": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
@@ -24937,7 +28903,6 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
- "dev": true,
"requires": {
"async-limiter": "1.0.0",
"safe-buffer": "5.1.1",
@@ -24947,8 +28912,7 @@
"ultron": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
- "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
- "dev": true
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
}
}
},
@@ -24979,6 +28943,28 @@
"xtend": "4.0.1"
}
},
+ "xhr-request": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
+ "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
+ "requires": {
+ "buffer-to-arraybuffer": "0.0.5",
+ "object-assign": "4.1.1",
+ "query-string": "5.1.1",
+ "simple-get": "2.8.1",
+ "timed-out": "4.0.1",
+ "url-set-query": "1.0.0",
+ "xhr": "2.4.1"
+ }
+ },
+ "xhr-request-promise": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz",
+ "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=",
+ "requires": {
+ "xhr-request": "1.1.0"
+ }
+ },
"xhr2": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.3.tgz",
@@ -25006,6 +28992,12 @@
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"dev": true
},
+ "xmlcreate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
+ "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8=",
+ "dev": true
+ },
"xmldom": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
@@ -25040,6 +29032,11 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
},
+ "yaeti": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
+ "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
+ },
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
diff --git a/package.json b/package.json
index 310e357ca..315008330 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,9 @@
"start": "gulp dev:extension",
"mascara": "gulp dev:mascara & node ./mascara/example/server",
"dist": "gulp dist",
+ "doc": "jsdoc -c development/tools/.jsdoc.json",
"test": "npm run test:unit && npm run test:integration && npm run lint",
- "test:unit": "cross-env METAMASK_ENV=test mocha --exit --require babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"",
+ "test:unit": "cross-env METAMASK_ENV=test mocha --exit --require test/setup.js --recursive \"test/unit/**/*.js\"",
"test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js",
"test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara",
"test:integration:build": "gulp build:scss",
@@ -75,6 +76,8 @@
"classnames": "^2.2.5",
"clone": "^2.1.1",
"copy-to-clipboard": "^3.0.8",
+ "css-loader": "^0.28.11",
+ "currency-formatter": "^1.4.2",
"debounce": "^1.0.0",
"debounce-stream": "^2.0.0",
"deep-extend": "^0.5.0",
@@ -85,12 +88,11 @@
"ensnare": "^1.0.0",
"eslint-plugin-react": "^7.4.0",
"eth-bin-to-ops": "^1.0.1",
- "eth-block-tracker": "^2.3.0",
"eth-contract-metadata": "^1.1.5",
"eth-hd-keyring": "^1.2.1",
- "eth-json-rpc-filters": "^1.2.5",
+ "eth-json-rpc-filters": "^1.2.6",
"eth-json-rpc-infura": "^3.0.0",
- "eth-keyring-controller": "^2.1.4",
+ "eth-keyring-controller": "^2.2.0",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.4.2",
@@ -100,8 +102,8 @@
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
"etherscan-link": "^1.0.2",
- "ethjs": "^0.2.8",
- "ethjs-contract": "^0.1.9",
+ "ethjs": "^0.3.4",
+ "ethjs-contract": "^0.2.0",
"ethjs-ens": "^2.0.0",
"ethjs-query": "^0.3.4",
"express": "^4.15.5",
@@ -109,12 +111,13 @@
"extensionizer": "^1.0.0",
"fast-json-patch": "^2.0.4",
"fast-levenshtein": "^2.0.6",
+ "file-loader": "^1.1.11",
"fuse.js": "^3.2.0",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-autoprefixer": "^5.0.0",
"gulp-debug": "^3.2.0",
"gulp-eslint": "^4.0.0",
- "gulp-sass": "^3.1.0",
+ "gulp-sass": "^4.0.0",
"hat": "0.0.3",
"human-standard-token-abi": "^1.0.2",
"idb-global": "^2.1.0",
@@ -131,7 +134,7 @@
"lodash.uniqby": "^4.7.0",
"loglevel": "^1.4.1",
"metamascara": "^2.0.0",
- "metamask-logo": "^2.1.2",
+ "metamask-logo": "^2.1.4",
"mkdirp": "^0.5.1",
"multiplex": "^6.7.0",
"number-to-bn": "^1.7.0",
@@ -145,17 +148,19 @@
"post-message-stream": "^3.0.0",
"promise-filter": "^1.1.0",
"promise-to-callback": "^1.0.0",
+ "prop-types": "^15.6.1",
"pump": "^3.0.0",
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
"ramda": "^0.24.1",
- "raven-js": "^3.24.0",
+ "raven-js": "^3.24.2",
"react": "^15.6.2",
"react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.2",
"react-hyperscript": "^3.0.0",
"react-markdown": "^3.0.0",
"react-redux": "^5.0.5",
+ "react-router-dom": "^4.2.2",
"react-select": "^1.0.0",
"react-simple-file-input": "^2.0.0",
"react-tippy": "^1.2.2",
@@ -177,11 +182,10 @@
"sw-controller": "^1.0.3",
"sw-stream": "^2.0.2",
"textarea-caret": "^3.0.1",
- "through2": "^2.0.3",
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "^0.20.1",
- "web3-provider-engine": "^13.8.0",
+ "web3-provider-engine": "^14.0.5",
"web3-stream-provider": "^3.0.1",
"xtend": "^4.0.1"
},
@@ -200,7 +204,7 @@
"brfs": "^1.4.3",
"browserify": "^16.1.1",
"chai": "^4.1.0",
- "chromedriver": "^2.34.1",
+ "chromedriver": "2.36.0",
"compression": "^1.7.1",
"coveralls": "^3.0.0",
"cross-env": "^5.1.4",
@@ -213,9 +217,10 @@
"eslint-plugin-json": "^1.2.0",
"eslint-plugin-mocha": "^5.0.0",
"eslint-plugin-react": "^7.4.0",
- "eth-json-rpc-middleware": "^1.2.7",
+ "eth-json-rpc-middleware": "^1.6.0",
"fs-promise": "^2.0.3",
"ganache-cli": "^6.1.0",
+ "ganache-core": "^2.1.0",
"gifencoder": "^1.1.0",
"gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed",
"gulp-babel": "^7.0.0",
@@ -234,6 +239,7 @@
"gulp-zip": "^4.0.0",
"image-size": "^0.6.2",
"isomorphic-fetch": "^2.2.1",
+ "jsdoc": "^3.5.5",
"jsdom": "^11.2.0",
"jsdom-global": "^3.0.2",
"jshint-stylish": "~2.2.1",
@@ -249,29 +255,36 @@
"mocha-sinon": "^2.0.0",
"nock": "^9.0.14",
"node-sass": "^4.7.2",
+ "nsp": "^3.2.1",
"nyc": "^11.0.3",
"open": "0.0.5",
+ "path": "^0.12.7",
"png-file-stream": "^1.0.0",
"prompt": "^1.0.0",
"qs": "^6.2.0",
"qunitjs": "^2.4.1",
+ "radgrad-jsdoc-template": "^1.1.3",
"react-addons-test-utils": "^15.5.1",
"react-test-renderer": "^15.6.2",
"react-testutils-additions": "^15.2.0",
"redux-test-utils": "^0.2.2",
+ "resolve-url-loader": "^2.3.0",
"rimraf": "^2.6.2",
+ "sass-loader": "^7.0.1",
"selenium-webdriver": "^3.5.0",
"shell-parallel": "^1.0.3",
"sinon": "^5.0.0",
+ "source-map": "^0.7.2",
+ "style-loader": "^0.21.0",
"stylelint-config-standard": "^18.2.0",
"tape": "^4.5.1",
"testem": "^2.0.0",
- "uglifyify": "^4.0.5",
+ "through2": "^2.0.3",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"watchify": "^3.9.0"
},
"engines": {
- "node": ">=0.8.0"
+ "node": ">=8.0.0"
}
}
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
index f1116d1a6..3936ac5fa 100644
--- a/test/integration/lib/confirm-sig-requests.js
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -21,11 +21,22 @@ async function runConfirmSigRequestsTest(assert, done) {
selectState.val('confirm sig requests')
reactTriggerChange(selectState[0])
+ // await timeout(1000000)
+
+ const pendingRequestItem = $.find('.tx-list-item.tx-list-pending-item-container.tx-list-clickable')
+
+ if (pendingRequestItem[0]) {
+ pendingRequestItem[0].click()
+ }
+
let confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+ let confirmSigMessage = await queryAsync($, '.request-signature__notice')
+ assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
+
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
+ assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
@@ -33,11 +44,8 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
- let confirmSigMessage = await queryAsync($, '.request-signature__notice')
- assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
-
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
- assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
+ assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
diff --git a/test/integration/lib/currency-localization.js b/test/integration/lib/currency-localization.js
new file mode 100644
index 000000000..7705c9720
--- /dev/null
+++ b/test/integration/lib/currency-localization.js
@@ -0,0 +1,28 @@
+const reactTriggerChange = require('../../lib/react-trigger-change')
+const {
+ timeout,
+ queryAsync,
+ findAsync,
+} = require('../../lib/util')
+
+QUnit.module('currency localization')
+
+QUnit.test('renders localized currency', (assert) => {
+ const done = assert.async()
+ runCurrencyLocalizationTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+async function runCurrencyLocalizationTest(assert, done) {
+ console.log('*** start runCurrencyLocalizationTest')
+ const selectState = await queryAsync($, 'select')
+ selectState.val('currency localization')
+ reactTriggerChange(selectState[0])
+ await timeout(1000)
+ const txView = await queryAsync($, '.tx-view')
+ const heroBalance = await findAsync($(txView), '.hero-balance')
+ const fiatAmount = await findAsync($(heroBalance), '.fiat-amount')
+ assert.equal(fiatAmount[0].textContent, '₱102,707.97')
+}
diff --git a/test/integration/lib/mascara-first-time.js b/test/integration/lib/mascara-first-time.js
index 564852585..5e07ab0b4 100644
--- a/test/integration/lib/mascara-first-time.js
+++ b/test/integration/lib/mascara-first-time.js
@@ -13,6 +13,9 @@ async function runFirstTimeUsageTest (assert, done) {
await skipNotices(app)
+ const welcomeButton = (await findAsync(app, '.welcome-screen__button'))[0]
+ welcomeButton.click()
+
// Scroll through terms
const title = (await findAsync(app, '.create-password__title')).text()
assert.equal(title, 'Create Password', 'create password screen')
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 163f3658c..3da3f4f95 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -23,6 +23,37 @@ global.ethQuery = {
global.ethereumProvider = {}
+async function customizeGas (assert, price, limit, ethFee, usdFee) {
+ const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container')
+ sendGasOpenCustomizeModalButton[0].click()
+
+ const customizeGasModal = await queryAsync($, '.send-v2__customize-gas')
+ assert.ok(customizeGasModal[0], 'should render the customize gas modal')
+
+ const customizeGasPriceInput = (await queryAsync($, '.send-v2__gas-modal-card')).first().find('input')
+ customizeGasPriceInput.val(price)
+ reactTriggerChange(customizeGasPriceInput[0])
+ const customizeGasLimitInput = (await queryAsync($, '.send-v2__gas-modal-card')).last().find('input')
+ customizeGasLimitInput.val(limit)
+ reactTriggerChange(customizeGasLimitInput[0])
+
+ const customizeGasSaveButton = await queryAsync($, '.send-v2__customize-gas__save')
+ customizeGasSaveButton[0].click()
+ const sendGasField = await queryAsync($, '.send-v2__gas-fee-display')
+
+ assert.equal(
+ (await findAsync(sendGasField, '.currency-display__input-wrapper > input')).val(),
+ ethFee,
+ 'send gas field should show customized gas total'
+ )
+
+ assert.equal(
+ (await findAsync(sendGasField, '.currency-display__converted-value'))[0].textContent,
+ usdFee,
+ 'send gas field should show customized gas total converted to USD'
+ )
+}
+
async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select')
@@ -53,7 +84,7 @@ async function runSendFlowTest(assert, done) {
assert.equal(sendFromDropdownList.children().length, 4, 'send from dropdown shows all accounts')
sendFromDropdownList.children()[1].click()
- sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
+ sendFromFieldItemAddress = await queryAsync($, '.account-list-item__account-name')
assert.equal(sendFromFieldItemAddress[0].textContent, 'Send Account 2', 'send from field dropdown changes account name')
let sendToFieldInput = await queryAsync($, '.send-v2__to-autocomplete__input')
@@ -91,36 +122,12 @@ async function runSendFlowTest(assert, done) {
)
assert.equal(
sendGasField.find('.currency-display__converted-value')[0].textContent,
- '0.24 USD',
+ '$0.24 USD',
'send gas field should show estimated gas total converted to USD'
)
- const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container')
- sendGasOpenCustomizeModalButton[0].click()
-
- const customizeGasModal = await queryAsync($, '.send-v2__customize-gas')
- assert.ok(customizeGasModal[0], 'should render the customize gas modal')
-
- const customizeGasPriceInput = (await queryAsync($, '.send-v2__gas-modal-card')).first().find('input')
- customizeGasPriceInput.val(50)
- reactTriggerChange(customizeGasPriceInput[0])
- const customizeGasLimitInput = (await queryAsync($, '.send-v2__gas-modal-card')).last().find('input')
- customizeGasLimitInput.val(60000)
- reactTriggerChange(customizeGasLimitInput[0])
-
- const customizeGasSaveButton = await queryAsync($, '.send-v2__customize-gas__save')
- customizeGasSaveButton[0].click()
-
- assert.equal(
- (await findAsync(sendGasField, '.currency-display__input-wrapper > input')).val(),
- '0.003',
- 'send gas field should show customized gas total'
- )
- assert.equal(
- (await findAsync(sendGasField, '.currency-display__converted-value'))[0].textContent,
- '3.60 USD',
- 'send gas field should show customized gas total converted to USD'
- )
+ await customizeGas(assert, 0, 21000, '0', '$0.00 USD')
+ await customizeGas(assert, 500, 60000, '0.003', '$3.60 USD')
const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
@@ -138,9 +145,9 @@ async function runSendFlowTest(assert, done) {
const confirmScreenRows = await queryAsync($, '.confirm-screen-rows')
const confirmScreenGas = confirmScreenRows.find('.currency-display__converted-value')[0]
- assert.equal(confirmScreenGas.textContent, '3.60 USD', 'confirm screen should show correct gas')
+ assert.equal(confirmScreenGas.textContent, '$3.60 USD', 'confirm screen should show correct gas')
const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[2]
- assert.equal(confirmScreenTotal.textContent, '2405.36 USD', 'confirm screen should show correct total')
+ assert.equal(confirmScreenTotal.textContent, '$2,405.36 USD', 'confirm screen should show correct total')
const confirmScreenBackButton = await queryAsync($, '.page-container__back-button')
confirmScreenBackButton[0].click()
@@ -164,17 +171,27 @@ async function runSendFlowTest(assert, done) {
const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
- sendButtonInEdit[0].click()
- // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
- selectState.val('confirm new ui')
+ selectState.val('send new ui')
reactTriggerChange(selectState[0])
- const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
- console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
- confirmScreenConfirmButton[0].click()
- const txView = await queryAsync($, '.tx-view')
- console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
+ const cancelButtonInEdit = await queryAsync($, '.btn-secondary--lg.page-container__footer-button')
+ cancelButtonInEdit[0].click()
+ // sendButtonInEdit[0].click()
+
+ // // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
+ // selectState.val('confirm new ui')
+ // reactTriggerChange(selectState[0])
+
+
+ // const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
+ // console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
+ // confirmScreenConfirmButton[0].click()
+
+ // await timeout(10000000)
+
+ // const txView = await queryAsync($, '.tx-view')
+ // console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
- assert.ok(txView[0], 'Should return to the account details screen after confirming')
+ // assert.ok(txView[0], 'Should return to the account details screen after confirming')
}
diff --git a/test/integration/lib/tx-list-items.js b/test/integration/lib/tx-list-items.js
index d0056eb94..0c0c5a77f 100644
--- a/test/integration/lib/tx-list-items.js
+++ b/test/integration/lib/tx-list-items.js
@@ -53,7 +53,7 @@ async function runTxListItemsTest(assert, done) {
const confirmedTokenTx = txListItems[6]
const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.tx-list-account')
- assert.equal(confirmedTokenTxAddress[0].textContent, '0xe7884118...81a9', 'confirmedTokenTx has correct address')
+ assert.equal(confirmedTokenTxAddress[0].textContent, '0xE7884118...81a9', 'confirmedTokenTx has correct address')
const rejectedTx = txListItems[7]
const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.tx-list-status')
diff --git a/test/setup.js b/test/setup.js
new file mode 100644
index 000000000..8e7965a37
--- /dev/null
+++ b/test/setup.js
@@ -0,0 +1,5 @@
+require('babel-register')({
+ ignore: name => name.includes('node_modules') && !name.includes('obs-store'),
+})
+
+require('./helper')
diff --git a/test/stub/provider.js b/test/stub/provider.js
index e77db4e28..a1c70486d 100644
--- a/test/stub/provider.js
+++ b/test/stub/provider.js
@@ -1,14 +1,28 @@
const JsonRpcEngine = require('json-rpc-engine')
const scaffoldMiddleware = require('eth-json-rpc-middleware/scaffold')
-const TestBlockchain = require('eth-block-tracker/test/util/testBlockMiddleware')
+const providerAsMiddleware = require('eth-json-rpc-middleware/providerAsMiddleware')
+const GanacheCore = require('ganache-core')
module.exports = {
createEngineForTestData,
providerFromEngine,
scaffoldMiddleware,
createTestProviderTools,
+ getTestSeed,
+ getTestAccounts,
}
+function getTestSeed () {
+ return 'people carpet cluster attract ankle motor ozone mass dove original primary mask'
+}
+
+function getTestAccounts () {
+ return [
+ { address: '0x88bb7F89eB5e5b30D3e15a57C68DBe03C6aCCB21', key: Buffer.from('254A8D551474F35CCC816388B4ED4D20B945C96B7EB857A68064CB9E9FB2C092', 'hex') },
+ { address: '0x1fe9aAB565Be19629fF4e8541ca2102fb42D7724', key: Buffer.from('6BAB5A4F2A6911AF8EE2BD32C6C05F6643AC48EF6C939CDEAAAE6B1620805A9B', 'hex') },
+ { address: '0xbda5c89aa6bA1b352194291AD6822C92AbC87c7B', key: Buffer.from('9B11D7F833648F26CE94D544855558D7053ECD396E4F4563968C232C012879B0', 'hex') },
+ ]
+}
function createEngineForTestData () {
return new JsonRpcEngine()
@@ -21,11 +35,13 @@ function providerFromEngine (engine) {
function createTestProviderTools (opts = {}) {
const engine = createEngineForTestData()
- const testBlockchain = new TestBlockchain()
// handle provided hooks
engine.push(scaffoldMiddleware(opts.scaffold || {}))
// handle block tracker methods
- engine.push(testBlockchain.createMiddleware())
+ engine.push(providerAsMiddleware(GanacheCore.provider({
+ mnemonic: getTestSeed(),
+ })))
+ // wrap in standard provider interface
const provider = providerFromEngine(engine)
- return { provider, engine, testBlockchain }
+ return { provider, engine }
}
diff --git a/test/unit/ComposableObservableStore.js b/test/unit/ComposableObservableStore.js
new file mode 100644
index 000000000..3fba200c1
--- /dev/null
+++ b/test/unit/ComposableObservableStore.js
@@ -0,0 +1,35 @@
+const assert = require('assert')
+const ComposableObservableStore = require('../../app/scripts/lib/ComposableObservableStore')
+const ObservableStore = require('obs-store')
+
+describe('ComposableObservableStore', () => {
+ it('should register initial state', () => {
+ const store = new ComposableObservableStore('state')
+ assert.strictEqual(store.getState(), 'state')
+ })
+
+ it('should register initial structure', () => {
+ const testStore = new ObservableStore()
+ const store = new ComposableObservableStore(null, { TestStore: testStore })
+ testStore.putState('state')
+ assert.deepEqual(store.getState(), { TestStore: 'state' })
+ })
+
+ it('should update structure', () => {
+ const testStore = new ObservableStore()
+ const store = new ComposableObservableStore()
+ store.updateStructure({ TestStore: testStore })
+ testStore.putState('state')
+ assert.deepEqual(store.getState(), { TestStore: 'state' })
+ })
+
+ it('should return flattened state', () => {
+ const fooStore = new ObservableStore({ foo: 'foo' })
+ const barStore = new ObservableStore({ bar: 'bar' })
+ const store = new ComposableObservableStore(null, {
+ FooStore: fooStore,
+ BarStore: barStore,
+ })
+ assert.deepEqual(store.getFlatState(), { foo: 'foo', bar: 'bar' })
+ })
+})
diff --git a/test/unit/account-import-strategies.spec.js b/test/unit/account-import-strategies.spec.js
new file mode 100644
index 000000000..acc39c88c
--- /dev/null
+++ b/test/unit/account-import-strategies.spec.js
@@ -0,0 +1,30 @@
+const assert = require('assert')
+const accountImporter = require('../../app/scripts/account-import-strategies/index')
+const ethUtil = require('ethereumjs-util')
+
+describe('Account Import Strategies', function () {
+ const privkey = '0x4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553'
+ const json = '{"version":3,"id":"dbb54385-0a99-437f-83c0-647de9f244c3","address":"a7f92ce3fba24196cf6f4bd2e1eb3db282ba998c","Crypto":{"ciphertext":"bde13d9ade5c82df80281ca363320ce254a8a3a06535bbf6ffdeaf0726b1312c","cipherparams":{"iv":"fbf93718a57f26051b292f072f2e5b41"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"7ffe00488319dec48e4c49a120ca49c6afbde9272854c64d9541c83fc6acdffe","n":8192,"r":8,"p":1},"mac":"2adfd9c4bc1cdac4c85bddfb31d9e21a684e0e050247a70c5698facf6b7d4681"}}'
+
+ it('imports a private key and strips 0x prefix', async function () {
+ const importPrivKey = await accountImporter.importAccount('Private Key', [ privkey ])
+ assert.equal(importPrivKey, ethUtil.stripHexPrefix(privkey))
+ })
+
+ it('fails when password is incorrect for keystore', async function () {
+ const wrongPassword = 'password2'
+
+ try {
+ await accountImporter.importAccount('JSON File', [ json, wrongPassword])
+ } catch (error) {
+ assert.equal(error.message, 'Key derivation failed - possibly wrong passphrase')
+ }
+ })
+
+ it('imports json string and password to return a private key', async function () {
+ const fileContentsPassword = 'password1'
+ const importJson = await accountImporter.importAccount('JSON File', [ json, fileContentsPassword])
+ assert.equal(importJson, '0x5733876abe94146069ce8bcbabbde2677f2e35fa33e875e92041ed2ac87e5bc7')
+ })
+
+})
diff --git a/test/unit/balance-formatter-test.js b/test/unit/balance-formatter-test.js
new file mode 100644
index 000000000..ab6daa19c
--- /dev/null
+++ b/test/unit/balance-formatter-test.js
@@ -0,0 +1,27 @@
+const assert = require('assert')
+const currencyFormatter = require('currency-formatter')
+const infuraConversion = require('../../ui/app/infura-conversion.json')
+
+describe('currencyFormatting', function () {
+ it('be able to format any infura currency', function (done) {
+ const number = 10000
+
+ infuraConversion.objects.forEach((conversion) => {
+ const code = conversion.quote.code.toUpperCase()
+ const result = currencyFormatter.format(number, { code })
+
+ switch (code) {
+ case 'USD':
+ assert.equal(result, '$10,000.00')
+ break
+ case 'JPY':
+ assert.equal(result, '¥10,000')
+ break
+ default:
+ assert.ok(result, `Currency ${code} formatted as ${result}`)
+ }
+ })
+
+ done()
+ })
+})
diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js
index 61707a759..332ccfdb8 100644
--- a/test/unit/metamask-controller-test.js
+++ b/test/unit/metamask-controller-test.js
@@ -2,10 +2,18 @@ const assert = require('assert')
const sinon = require('sinon')
const clone = require('clone')
const nock = require('nock')
+const createThoughStream = require('through2').obj
const MetaMaskController = require('../../app/scripts/metamask-controller')
const blacklistJSON = require('../stub/blacklist')
const firstTimeState = require('../../app/scripts/first-time-state')
+const currentNetworkId = 42
+const DEFAULT_LABEL = 'Account 1'
+const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'
+const TEST_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+const TEST_SEED_ALT = 'setup olympic issue mobile velvet surge alcohol burger horse view reopen gentle'
+const TEST_ADDRESS_ALT = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'
+
describe('MetaMaskController', function () {
let metamaskController
const sandbox = sinon.createSandbox()
@@ -33,6 +41,7 @@ describe('MetaMaskController', function () {
metamaskController = new MetaMaskController({
showUnapprovedTx: noop,
+ showUnconfirmedMessage: noop,
encryptor: {
encrypt: function (password, object) {
this.object = object
@@ -96,18 +105,29 @@ describe('MetaMaskController', function () {
describe('#createNewVaultAndRestore', function () {
it('should be able to call newVaultAndRestore despite a mistake.', async function () {
-
const password = 'what-what-what'
- const wrongSeed = 'debris dizzy just program just float decrease vacant alarm reduce speak stadiu'
- const rightSeed = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'
- await metamaskController.createNewVaultAndRestore(password, wrongSeed)
- .catch((e) => {
- return
- })
- await metamaskController.createNewVaultAndRestore(password, rightSeed)
+ await metamaskController.createNewVaultAndRestore(password, TEST_SEED.slice(0, -1)).catch((e) => null)
+ await metamaskController.createNewVaultAndRestore(password, TEST_SEED)
assert(metamaskController.keyringController.createNewVaultAndRestore.calledTwice)
})
+
+ it('should clear previous identities after vault restoration', async () => {
+ await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED)
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS]: { address: TEST_ADDRESS, name: DEFAULT_LABEL },
+ })
+
+ await metamaskController.keyringController.saveAccountLabel(TEST_ADDRESS, 'Account Foo')
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS]: { address: TEST_ADDRESS, name: 'Account Foo' },
+ })
+
+ await metamaskController.createNewVaultAndRestore('foobar1337', TEST_SEED_ALT)
+ assert.deepEqual(metamaskController.getState().identities, {
+ [TEST_ADDRESS_ALT]: { address: TEST_ADDRESS_ALT, name: DEFAULT_LABEL },
+ })
+ })
})
describe('#getApi', function () {
@@ -137,7 +157,7 @@ describe('MetaMaskController', function () {
assert.equal(metamaskController.preferencesController.store.getState().useBlockie, false)
})
- it('setUseBlockie to true', async function () {
+ it('setUseBlockie to true', function () {
metamaskController.setUseBlockie(true, noop)
assert.equal(metamaskController.preferencesController.store.getState().useBlockie, true)
})
@@ -184,6 +204,10 @@ describe('MetaMaskController', function () {
rpcTarget = metamaskController.setCustomRpc(customRPC)
})
+ afterEach(function () {
+ nock.cleanAll()
+ })
+
it('returns custom RPC that when called', async function () {
assert.equal(await rpcTarget, customRPC)
})
@@ -213,6 +237,7 @@ describe('MetaMaskController', function () {
describe('#createShapeshifttx', function () {
let depositAddress, depositType, shapeShiftTxList
+
beforeEach(function () {
nock('https://shapeshift.io')
.get('/txStat/3EevLFfB4H4XMWQwYCgjLie1qCAGpd2WBc')
@@ -223,10 +248,11 @@ describe('MetaMaskController', function () {
shapeShiftTxList = metamaskController.shapeshiftController.store.getState().shapeShiftTxList
})
- it('creates', async function () {
+ it('creates a shapeshift tx', async function () {
metamaskController.createShapeShiftTx(depositAddress, depositType)
assert.equal(shapeShiftTxList[0].depositAddress, depositAddress)
})
+
})
describe('#addNewAccount', function () {
@@ -245,4 +271,257 @@ describe('MetaMaskController', function () {
}
})
})
+
+ describe('#verifyseedPhrase', function () {
+ let seedPhrase, getConfigSeed
+
+ it('errors when no keying is provided', async function () {
+ try {
+ await metamaskController.verifySeedPhrase()
+ } catch (error) {
+ assert.equal(error.message, 'MetamaskController - No HD Key Tree found')
+ }
+ })
+
+ beforeEach(async function () {
+ await metamaskController.createNewVaultAndKeychain('password')
+ seedPhrase = await metamaskController.verifySeedPhrase()
+ })
+
+ it('#placeSeedWords should match the initially created vault seed', function () {
+
+ metamaskController.placeSeedWords((err, result) => {
+ if (err) {
+ console.log(err)
+ } else {
+ getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(result, seedPhrase)
+ assert.equal(result, getConfigSeed)
+ }
+ })
+ assert.equal(getConfigSeed, undefined)
+ })
+
+ it('#addNewAccount', async function () {
+ await metamaskController.addNewAccount()
+ const getAccounts = await metamaskController.keyringController.getAccounts()
+ assert.equal(getAccounts.length, 2)
+ })
+ })
+
+ describe('#resetAccount', function () {
+
+ beforeEach(function () {
+ const selectedAddressStub = sinon.stub(metamaskController.preferencesController, 'getSelectedAddress')
+ const getNetworkstub = sinon.stub(metamaskController.txController.txStateManager, 'getNetwork')
+
+ selectedAddressStub.returns('0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc')
+ getNetworkstub.returns(42)
+
+ metamaskController.txController.txStateManager._saveTxList([
+ { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'} },
+ { id: 2, status: 'rejected', metamaskNetworkId: 32, txParams: {} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {from: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4'} },
+ ])
+ })
+
+ it('wipes transactions from only the correct network id and with the selected address', async function () {
+ await metamaskController.resetAccount()
+ assert.equal(metamaskController.txController.txStateManager.getTx(1), undefined)
+ })
+ })
+
+ describe('#clearSeedWordCache', function () {
+
+ it('should have set seed words', function () {
+ metamaskController.configManager.setSeedWords('test words')
+ const getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(getConfigSeed, 'test words')
+ })
+
+ it('should clear config seed phrase', function () {
+ metamaskController.configManager.setSeedWords('test words')
+ metamaskController.clearSeedWordCache((err, result) => {
+ if (err) console.log(err)
+ })
+ const getConfigSeed = metamaskController.configManager.getSeedWords()
+ assert.equal(getConfigSeed, null)
+ })
+
+ })
+
+ describe('#setCurrentLocale', function () {
+
+ it('checks the default currentLocale', function () {
+ const preferenceCurrentLocale = metamaskController.preferencesController.store.getState().currentLocale
+ assert.equal(preferenceCurrentLocale, undefined)
+ })
+
+ it('sets current locale in preferences controller', function () {
+ metamaskController.setCurrentLocale('ja', noop)
+ const preferenceCurrentLocale = metamaskController.preferencesController.store.getState().currentLocale
+ assert.equal(preferenceCurrentLocale, 'ja')
+ })
+
+ })
+
+ describe('#newUnsignedMessage', function () {
+
+ let msgParams, metamaskMsgs, messages, msgId
+
+ const address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+ const data = '0x43727970746f6b697474696573'
+
+ beforeEach(function () {
+
+ msgParams = {
+ 'from': address,
+ 'data': data,
+ }
+
+ metamaskController.newUnsignedMessage(msgParams, noop)
+ metamaskMsgs = metamaskController.messageManager.getUnapprovedMsgs()
+ messages = metamaskController.messageManager.messages
+ msgId = Object.keys(metamaskMsgs)[0]
+ })
+
+ it('persists address from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.from, address)
+ })
+
+ it('persists data from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.data, data)
+ })
+
+ it('sets the status to unapproved', function () {
+ assert.equal(metamaskMsgs[msgId].status, 'unapproved')
+ })
+
+ it('sets the type to eth_sign', function () {
+ assert.equal(metamaskMsgs[msgId].type, 'eth_sign')
+ })
+
+ it('rejects the message', function () {
+ const msgIdInt = parseInt(msgId)
+ metamaskController.cancelMessage(msgIdInt, noop)
+ assert.equal(messages[0].status, 'rejected')
+ })
+ })
+
+ describe('#newUnsignedPersonalMessage', function () {
+
+ it('errors with no from in msgParams', function () {
+ const msgParams = {
+ 'data': data,
+ }
+ metamaskController.newUnsignedPersonalMessage(msgParams, function (error) {
+ assert.equal(error.message, 'MetaMask Message Signature: from field is required.')
+ })
+ })
+
+ let msgParams, metamaskMsgs, messages, msgId
+
+ const address = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
+ const data = '0x43727970746f6b697474696573'
+
+ beforeEach(function () {
+
+ msgParams = {
+ 'from': address,
+ 'data': data,
+ }
+
+ metamaskController.newUnsignedPersonalMessage(msgParams, noop)
+ metamaskMsgs = metamaskController.personalMessageManager.getUnapprovedMsgs()
+ messages = metamaskController.personalMessageManager.messages
+ msgId = Object.keys(metamaskMsgs)[0]
+ })
+
+ it('persists address from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.from, address)
+ })
+
+ it('persists data from msg params', function () {
+ assert.equal(metamaskMsgs[msgId].msgParams.data, data)
+ })
+
+ it('sets the status to unapproved', function () {
+ assert.equal(metamaskMsgs[msgId].status, 'unapproved')
+ })
+
+ it('sets the type to personal_sign', function () {
+ assert.equal(metamaskMsgs[msgId].type, 'personal_sign')
+ })
+
+ it('rejects the message', function () {
+ const msgIdInt = parseInt(msgId)
+ metamaskController.cancelPersonalMessage(msgIdInt, noop)
+ assert.equal(messages[0].status, 'rejected')
+ })
+ })
+
+ describe('#setupUntrustedCommunication', function () {
+ let streamTest
+
+ const phishingUrl = 'decentral.market'
+
+ afterEach(function () {
+ streamTest.end()
+ })
+
+ it('sets up phishing stream for untrusted communication ', async function () {
+ await metamaskController.blacklistController.updatePhishingList()
+
+ streamTest = createThoughStream((chunk, enc, cb) => {
+ assert.equal(chunk.name, 'phishing')
+ assert.equal(chunk.data.hostname, phishingUrl)
+ cb()
+ })
+ // console.log(streamTest)
+ metamaskController.setupUntrustedCommunication(streamTest, phishingUrl)
+ })
+ })
+
+ describe('#setupTrustedCommunication', function () {
+ let streamTest
+
+ afterEach(function () {
+ streamTest.end()
+ })
+
+ it('sets up controller dnode api for trusted communication', function (done) {
+ streamTest = createThoughStream((chunk, enc, cb) => {
+ assert.equal(chunk.name, 'controller')
+ cb()
+ done()
+ })
+
+ metamaskController.setupTrustedCommunication(streamTest, 'mycrypto.com')
+ })
+ })
+
+ describe('#markAccountsFound', function () {
+ it('adds lost accounts to config manager data', function () {
+ metamaskController.markAccountsFound(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.deepEqual(configManagerData.lostAccounts, [])
+ })
+ })
+
+ describe('#markPasswordForgotten', function () {
+ it('adds and sets forgottenPassword to config data to true', function () {
+ metamaskController.markPasswordForgotten(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.equal(configManagerData.forgottenPassword, true)
+ })
+ })
+
+ describe('#unMarkPasswordForgotten', function () {
+ it('adds and sets forgottenPassword to config data to false', function () {
+ metamaskController.unMarkPasswordForgotten(noop)
+ const configManagerData = metamaskController.configManager.getData()
+ assert.equal(configManagerData.forgottenPassword, false)
+ })
+ })
+
})
diff --git a/test/unit/migrations/024-test.js b/test/unit/migrations/024-test.js
new file mode 100644
index 000000000..c3c03d06b
--- /dev/null
+++ b/test/unit/migrations/024-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration24 = require('../../../app/scripts/migrations/024')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+const properTime = (new Date()).getTime()
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration24.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert.equal(tx.txParams.from, '0x8acce2391c0d510a6c5e5d8f819a678f79b7e675')
+ else assert.equal(tx.txParams.from, '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675')
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration24.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 24)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/025-test.js b/test/unit/migrations/025-test.js
new file mode 100644
index 000000000..76c25dbb6
--- /dev/null
+++ b/test/unit/migrations/025-test.js
@@ -0,0 +1,49 @@
+const assert = require('assert')
+const migration25 = require('../../../app/scripts/migrations/025')
+const firstTimeState = {
+ meta: {},
+ data: require('../../../app/scripts/first-time-state'),
+}
+
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+
+
+while (transactions.length <= 10) {
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675', random: 'stuff', chainId: 2 }, status: 'unapproved' })
+ transactions.push({ txParams: { from: '0x8aCce2391c0d510a6c5E5d8f819a678f79b7e675' }, status: 'confirmed' })
+}
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the txParams.from are lowercase', () => {
+ it('should lowercase the from for unapproved txs', (done) => {
+ migration25.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (tx.status === 'unapproved') assert(!tx.txParams.random)
+ if (tx.status === 'unapproved') assert(!tx.txParams.chainId)
+ })
+ done()
+ }).catch(done)
+ })
+
+ it('should migrate first time state', (done) => {
+ migration25.migrate(firstTimeState)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 25)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/template-test.js b/test/unit/migrations/template-test.js
new file mode 100644
index 000000000..35060e2fe
--- /dev/null
+++ b/test/unit/migrations/template-test.js
@@ -0,0 +1,17 @@
+const assert = require('assert')
+const migrationTemplate = require('../../../app/scripts/migrations/template')
+const properTime = (new Date()).getTime()
+const storage = {
+ meta: {},
+ data: {},
+}
+
+describe('storage is migrated successfully', () => {
+ it('should work', (done) => {
+ migrationTemplate.migrate(storage)
+ .then((migratedData) => {
+ assert.equal(migratedData.meta.version, 0)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrator-test.js b/test/unit/migrator-test.js
index 16066fefe..4404e1dc4 100644
--- a/test/unit/migrator-test.js
+++ b/test/unit/migrator-test.js
@@ -1,7 +1,8 @@
const assert = require('assert')
const clone = require('clone')
const Migrator = require('../../app/scripts/lib/migrator/')
-const migrations = [
+const liveMigrations = require('../../app/scripts/migrations/')
+const stubMigrations = [
{
version: 1,
migrate: (data) => {
@@ -29,13 +30,39 @@ const migrations = [
},
]
const versionedData = {meta: {version: 0}, data: {hello: 'world'}}
+
+const firstTimeState = {
+ meta: { version: 0 },
+ data: require('../../app/scripts/first-time-state'),
+}
+
describe('Migrator', () => {
- const migrator = new Migrator({ migrations })
+ const migrator = new Migrator({ migrations: stubMigrations })
it('migratedData version should be version 3', (done) => {
migrator.migrateData(versionedData)
.then((migratedData) => {
- assert.equal(migratedData.meta.version, migrations[2].version)
+ assert.equal(migratedData.meta.version, stubMigrations[2].version)
done()
}).catch(done)
})
+
+ it('should match the last version in live migrations', (done) => {
+ const migrator = new Migrator({ migrations: liveMigrations })
+ migrator.migrateData(firstTimeState)
+ .then((migratedData) => {
+ const last = liveMigrations.length - 1
+ assert.equal(migratedData.meta.version, liveMigrations[last].version)
+ done()
+ }).catch(done)
+ })
+
+ it('should emit an error', function (done) {
+ this.timeout(15000)
+ const migrator = new Migrator({ migrations: [{ version: 1, migrate: async () => { throw new Error('test') } } ] })
+ migrator.on('error', () => done())
+ migrator.migrateData({ meta: {version: 0} })
+ .then((migratedData) => {
+ }).catch(done)
+ })
+
})
diff --git a/test/unit/network-contoller-test.js b/test/unit/network-contoller-test.js
index dd0b52365..2b905718b 100644
--- a/test/unit/network-contoller-test.js
+++ b/test/unit/network-contoller-test.js
@@ -1,6 +1,10 @@
const assert = require('assert')
const nock = require('nock')
const NetworkController = require('../../app/scripts/controllers/network')
+const {
+ getNetworkDisplayName,
+ getNetworkEndpoints,
+} = require('../../app/scripts/controllers/network/util')
const { createTestProviderTools } = require('../stub/provider')
const providerResultStub = {}
@@ -79,4 +83,40 @@ describe('# Network Controller', function () {
})
})
})
-}) \ No newline at end of file
+})
+
+describe('# Network utils', () => {
+ it('getNetworkDisplayName should return the correct network name', () => {
+ const tests = [
+ {
+ input: 3,
+ expected: 'Ropsten',
+ }, {
+ input: 4,
+ expected: 'Rinkeby',
+ }, {
+ input: 42,
+ expected: 'Kovan',
+ }, {
+ input: 'ropsten',
+ expected: 'Ropsten',
+ }, {
+ input: 'rinkeby',
+ expected: 'Rinkeby',
+ }, {
+ input: 'kovan',
+ expected: 'Kovan',
+ }, {
+ input: 'mainnet',
+ expected: 'Main Ethereum Network',
+ },
+ ]
+
+ tests.forEach(({ input, expected }) => assert.equal(getNetworkDisplayName(input), expected))
+ })
+
+ it('getNetworkEndpoints should return the correct endpoints', () => {
+ assert.equal(getNetworkEndpoints('networkBeta').ropsten, 'https://ropsten.infura.io/metamask2')
+ assert.equal(getNetworkEndpoints('network').rinkeby, 'https://rinkeby.infura.io/metamask')
+ })
+})
diff --git a/test/unit/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js
index 5a27882ef..cf26945d3 100644
--- a/test/unit/nonce-tracker-test.js
+++ b/test/unit/nonce-tracker-test.js
@@ -1,5 +1,5 @@
const assert = require('assert')
-const NonceTracker = require('../../app/scripts/lib/nonce-tracker')
+const NonceTracker = require('../../app/scripts/controllers/transactions/nonce-tracker')
const MockTxGen = require('../lib/mock-tx-gen')
let providerResultStub = {}
diff --git a/test/unit/pending-tx-test.js b/test/unit/pending-tx-test.js
index 62f4f28a8..97ac8524b 100644
--- a/test/unit/pending-tx-test.js
+++ b/test/unit/pending-tx-test.js
@@ -4,7 +4,7 @@ const EthTx = require('ethereumjs-tx')
const ObservableStore = require('obs-store')
const clone = require('clone')
const { createTestProviderTools } = require('../stub/provider')
-const PendingTransactionTracker = require('../../app/scripts/lib/pending-tx-tracker')
+const PendingTransactionTracker = require('../../app/scripts/controllers/transactions/pending-tx-tracker')
const MockTxGen = require('../lib/mock-tx-gen')
const sinon = require('sinon')
const noop = () => true
diff --git a/test/unit/token-rates-controller.js b/test/unit/token-rates-controller.js
new file mode 100644
index 000000000..a49547313
--- /dev/null
+++ b/test/unit/token-rates-controller.js
@@ -0,0 +1,29 @@
+const assert = require('assert')
+const sinon = require('sinon')
+const TokenRatesController = require('../../app/scripts/controllers/token-rates')
+const ObservableStore = require('obs-store')
+
+describe('TokenRatesController', () => {
+ it('should listen for preferences store updates', () => {
+ const preferences = new ObservableStore({ tokens: [] })
+ const controller = new TokenRatesController({ preferences })
+ preferences.putState({ tokens: ['foo'] })
+ assert.deepEqual(controller._tokens, ['foo'])
+ })
+
+ it('should poll on correct interval', async () => {
+ const stub = sinon.stub(global, 'setInterval')
+ new TokenRatesController({ interval: 1337 }) // eslint-disable-line no-new
+ assert.strictEqual(stub.getCall(0).args[1], 1337)
+ stub.restore()
+ })
+
+ it('should fetch each token rate based on address', async () => {
+ const controller = new TokenRatesController()
+ controller.isActive = true
+ controller.fetchExchangeRate = address => address
+ controller.tokens = [{ address: 'foo' }, { address: 'bar' }]
+ await controller.updateExchangeRates()
+ assert.deepEqual(controller.store.getState().contractExchangeRates, { foo: 'foo', bar: 'bar' })
+ })
+})
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index 6bd010e7a..ddd921652 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -5,17 +5,16 @@ const EthjsQuery = require('ethjs-query')
const ObservableStore = require('obs-store')
const sinon = require('sinon')
const TransactionController = require('../../app/scripts/controllers/transactions')
-const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
-const { createTestProviderTools } = require('../stub/provider')
+const TxGasUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
+const { createTestProviderTools, getTestAccounts } = require('../stub/provider')
const noop = () => true
const currentNetworkId = 42
const otherNetworkId = 36
-const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
describe('Transaction Controller', function () {
- let txController, provider, providerResultStub, testBlockchain
+ let txController, provider, providerResultStub, query, fromAccount
beforeEach(function () {
providerResultStub = {
@@ -24,9 +23,9 @@ describe('Transaction Controller', function () {
// by default, all accounts are external accounts (not contracts)
eth_getCode: '0x',
}
- const providerTools = createTestProviderTools({ scaffold: providerResultStub })
- provider = providerTools.provider
- testBlockchain = providerTools.testBlockchain
+ provider = createTestProviderTools({ scaffold: providerResultStub }).provider
+ query = new EthjsQuery(provider)
+ fromAccount = getTestAccounts()[0]
txController = new TransactionController({
provider,
@@ -34,13 +33,43 @@ describe('Transaction Controller', function () {
txHistoryLimit: 10,
blockTracker: { getCurrentBlock: noop, on: noop, once: noop },
signTransaction: (ethTx) => new Promise((resolve) => {
- ethTx.sign(privKey)
+ ethTx.sign(fromAccount.key)
resolve()
}),
})
txController.nonceTracker.getNonceLock = () => Promise.resolve({ nextNonce: 0, releaseLock: noop })
})
+ describe('#isNonceTaken', function () {
+ it('should return true', function (done) {
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 2, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ ])
+ txController.isNonceTaken({txParams: {nonce:0, from:'0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'}})
+ .then((isNonceTaken) => {
+ assert(isNonceTaken)
+ done()
+ }).catch(done)
+
+ })
+ it('should return false', function (done) {
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 2, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {nonce: 0, from: '0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'} },
+ ])
+
+ txController.isNonceTaken({txParams: {nonce:0, from:'0x8ACCE2391C0d510a6C5E5D8f819A678F79B7E675'}})
+ .then((isNonceTaken) => {
+ assert(!isNonceTaken)
+ done()
+ }).catch(done)
+
+ })
+ })
+
describe('#getState', function () {
it('should return a state object with the right keys and datat types', function () {
const exposedState = txController.getState()
@@ -188,7 +217,7 @@ describe('Transaction Controller', function () {
})
- describe('#addTxDefaults', function () {
+ describe('#addTxGasDefaults', function () {
it('should add the tx defaults if their are none', function (done) {
const txMeta = {
'txParams': {
@@ -199,7 +228,7 @@ describe('Transaction Controller', function () {
providerResultStub.eth_gasPrice = '4a817c800'
providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }
providerResultStub.eth_estimateGas = '5209'
- txController.addTxDefaults(txMeta)
+ txController.addTxGasDefaults(txMeta)
.then((txMetaWithDefaults) => {
assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value')
assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price')
@@ -210,31 +239,6 @@ describe('Transaction Controller', function () {
})
})
- describe('#validateTxParams', function () {
- it('does not throw for positive values', function (done) {
- var sample = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- value: '0x01',
- }
- txController.txGasUtil.validateTxParams(sample).then(() => {
- done()
- }).catch(done)
- })
-
- it('returns error for negative values', function (done) {
- var sample = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- value: '-0x01',
- }
- txController.txGasUtil.validateTxParams(sample)
- .then(() => done('expected to thrown on negativity values but didn\'t'))
- .catch((err) => {
- assert.ok(err, 'error')
- done()
- })
- })
- })
-
describe('#addTx', function () {
it('should emit updates', function (done) {
const txMeta = {
@@ -323,12 +327,12 @@ describe('Transaction Controller', function () {
describe('#updateAndApproveTransaction', function () {
let txMeta
- beforeEach(function () {
+ beforeEach(() => {
txMeta = {
id: 1,
status: 'unapproved',
txParams: {
- from: '0xc684832530fcbddae4b4230a47e991ddcec2831d',
+ from: fromAccount.address,
to: '0x1678a085c290ebd122dc42cba69373b5953b831d',
gasPrice: '0x77359400',
gas: '0x7b0d',
@@ -337,11 +341,12 @@ describe('Transaction Controller', function () {
metamaskNetworkId: currentNetworkId,
}
})
- it('should update and approve transactions', function () {
+ it('should update and approve transactions', async () => {
txController.txStateManager.addTx(txMeta)
- txController.updateAndApproveTransaction(txMeta)
+ const approvalPromise = txController.updateAndApproveTransaction(txMeta)
const tx = txController.txStateManager.getTx(1)
assert.equal(tx.status, 'approved')
+ await approvalPromise
})
})
diff --git a/test/unit/tx-gas-util-test.js b/test/unit/tx-gas-util-test.js
index 15d412c72..c1d5966da 100644
--- a/test/unit/tx-gas-util-test.js
+++ b/test/unit/tx-gas-util-test.js
@@ -1,56 +1,77 @@
const assert = require('assert')
-const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
-const { createTestProviderTools } = require('../stub/provider')
-
-describe('Tx Gas Util', function () {
- let txGasUtil, provider, providerResultStub
- beforeEach(function () {
- providerResultStub = {}
- provider = createTestProviderTools({ scaffold: providerResultStub }).provider
- txGasUtil = new TxGasUtils({
- provider,
- })
- })
+const Transaction = require('ethereumjs-tx')
+const BN = require('bn.js')
- it('removes recipient for txParams with 0x when contract data is provided', function () {
- const zeroRecipientandDataTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- data: 'bytecode',
- }
- const sanitizedTxParams = txGasUtil.validateRecipient(zeroRecipientandDataTxParams)
- assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
- })
- it('should error when recipient is 0x', function () {
- const zeroRecipientTxParams = {
- from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
- to: '0x',
- }
- assert.throws(() => { txGasUtil.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
- })
+const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
+const TxUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
- it('should error when from is not a hex string', function () {
- // where from is undefined
- const txParams = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+describe('txUtils', function () {
+ let txUtils
- // where from is array
- txParams.from = []
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+ before(function () {
+ txUtils = new TxUtils(new Proxy({}, {
+ get: (obj, name) => {
+ return () => {}
+ },
+ }))
+ })
- // where from is a object
- txParams.from = {}
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+ describe('chain Id', function () {
+ it('prepares a transaction with the provided chainId', function () {
+ const txParams = {
+ to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
+ from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
+ value: '0x0',
+ gas: '0x7b0c',
+ gasPrice: '0x199c82cc00',
+ data: '0x',
+ nonce: '0x3',
+ chainId: 42,
+ }
+ const ethTx = new Transaction(txParams)
+ assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
+ })
+ })
- // where from is a invalid address
- txParams.from = 'im going to fail'
- assert.throws(() => { txGasUtil.validateFrom(txParams) }, Error, `Invalid from address`)
+ describe('addGasBuffer', function () {
+ it('multiplies by 1.5, when within block gas limit', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x3d4c52 (4 mil)
+ const blockGasLimitHex = '0x3d4c52'
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ const inputBn = hexToBn(inputHex)
+ const outputBn = hexToBn(output)
+ const expectedBn = inputBn.muln(1.5)
+ assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
+ })
- // should run
- txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
- txGasUtil.validateFrom(txParams)
+ it('uses original estimatedGas, when above block gas limit', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x0f4240 (1 mil)
+ const blockGasLimitHex = '0x0f4240'
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ // const inputBn = hexToBn(inputHex)
+ const outputBn = hexToBn(output)
+ const expectedBn = hexToBn(inputHex)
+ assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
})
+ it('buffers up to recommend gas limit recommended ceiling', function () {
+ // naive estimatedGas: 0x16e360 (1.5 mil)
+ const inputHex = '0x16e360'
+ // dummy gas limit: 0x1e8480 (2 mil)
+ const blockGasLimitHex = '0x1e8480'
+ const blockGasLimitBn = hexToBn(blockGasLimitHex)
+ const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
+ const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
+ // const inputBn = hexToBn(inputHex)
+ // const outputBn = hexToBn(output)
+ const expectedHex = bnToHex(ceilGasLimitBn)
+ assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
+ })
+ })
})
diff --git a/test/unit/tx-state-history-helper-test.js b/test/unit/tx-state-history-helper-test.js
index 90cb10713..35e9ef188 100644
--- a/test/unit/tx-state-history-helper-test.js
+++ b/test/unit/tx-state-history-helper-test.js
@@ -1,6 +1,6 @@
const assert = require('assert')
const clone = require('clone')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
describe('deepCloneFromTxMeta', function () {
it('should clone deep', function () {
diff --git a/test/unit/tx-state-history-helper.js b/test/unit/tx-state-history-helper.js
index 79ee26d6e..35f7dac57 100644
--- a/test/unit/tx-state-history-helper.js
+++ b/test/unit/tx-state-history-helper.js
@@ -1,5 +1,5 @@
const assert = require('assert')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const testVault = require('../data/v17-long-history.json')
diff --git a/test/unit/tx-state-manager-test.js b/test/unit/tx-state-manager-test.js
index a5ac13664..e5fe68d0b 100644
--- a/test/unit/tx-state-manager-test.js
+++ b/test/unit/tx-state-manager-test.js
@@ -1,8 +1,8 @@
const assert = require('assert')
const clone = require('clone')
const ObservableStore = require('obs-store')
-const TxStateManager = require('../../app/scripts/lib/tx-state-manager')
-const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const TxStateManager = require('../../app/scripts/controllers/transactions/tx-state-manager')
+const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const noop = () => true
describe('TransactionStateManager', function () {
diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js
index 8ca13412e..be16225ba 100644
--- a/test/unit/tx-utils-test.js
+++ b/test/unit/tx-utils-test.js
@@ -1,77 +1,98 @@
const assert = require('assert')
-const Transaction = require('ethereumjs-tx')
-const BN = require('bn.js')
-
-
-const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
-const TxUtils = require('../../app/scripts/lib/tx-gas-utils')
+const txUtils = require('../../app/scripts/controllers/transactions/lib/util')
describe('txUtils', function () {
- let txUtils
-
- before(function () {
- txUtils = new TxUtils(new Proxy({}, {
- get: (obj, name) => {
- return () => {}
- },
- }))
- })
+ describe('#validateTxParams', function () {
+ it('does not throw for positive values', function () {
+ var sample = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ value: '0x01',
+ }
+ txUtils.validateTxParams(sample)
+ })
- describe('chain Id', function () {
- it('prepares a transaction with the provided chainId', function () {
- const txParams = {
- to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
- from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
- value: '0x0',
- gas: '0x7b0c',
- gasPrice: '0x199c82cc00',
- data: '0x',
- nonce: '0x3',
- chainId: 42,
+ it('returns error for negative values', function () {
+ var sample = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ value: '-0x01',
+ }
+ try {
+ txUtils.validateTxParams(sample)
+ } catch (err) {
+ assert.ok(err, 'error')
}
- const ethTx = new Transaction(txParams)
- assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
})
})
- describe('addGasBuffer', function () {
- it('multiplies by 1.5, when within block gas limit', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x3d4c52 (4 mil)
- const blockGasLimitHex = '0x3d4c52'
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- const inputBn = hexToBn(inputHex)
- const outputBn = hexToBn(output)
- const expectedBn = inputBn.muln(1.5)
- assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
+ describe('#normalizeTxParams', () => {
+ it('should normalize txParams', () => {
+ let txParams = {
+ chainId: '0x1',
+ from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
+ to: null,
+ data: '68656c6c6f20776f726c64',
+ random: 'hello world',
+ }
+
+ let normalizedTxParams = txUtils.normalizeTxParams(txParams)
+
+ assert(!normalizedTxParams.chainId, 'their should be no chainId')
+ assert(!normalizedTxParams.to, 'their should be no to address if null')
+ assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd')
+ assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd')
+ assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams')
+
+ txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
+ normalizedTxParams = txUtils.normalizeTxParams(txParams)
+ assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd')
+
})
+ })
- it('uses original estimatedGas, when above block gas limit', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x0f4240 (1 mil)
- const blockGasLimitHex = '0x0f4240'
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- // const inputBn = hexToBn(inputHex)
- const outputBn = hexToBn(output)
- const expectedBn = hexToBn(inputHex)
- assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
+ describe('#validateRecipient', () => {
+ it('removes recipient for txParams with 0x when contract data is provided', function () {
+ const zeroRecipientandDataTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ data: 'bytecode',
+ }
+ const sanitizedTxParams = txUtils.validateRecipient(zeroRecipientandDataTxParams)
+ assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
})
- it('buffers up to recommend gas limit recommended ceiling', function () {
- // naive estimatedGas: 0x16e360 (1.5 mil)
- const inputHex = '0x16e360'
- // dummy gas limit: 0x1e8480 (2 mil)
- const blockGasLimitHex = '0x1e8480'
- const blockGasLimitBn = hexToBn(blockGasLimitHex)
- const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
- const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
- // const inputBn = hexToBn(inputHex)
- // const outputBn = hexToBn(output)
- const expectedHex = bnToHex(ceilGasLimitBn)
- assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
+ it('should error when recipient is 0x', function () {
+ const zeroRecipientTxParams = {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ to: '0x',
+ }
+ assert.throws(() => { txUtils.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
})
})
-}) \ No newline at end of file
+
+
+ describe('#validateFrom', () => {
+ it('should error when from is not a hex string', function () {
+
+ // where from is undefined
+ const txParams = {}
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is array
+ txParams.from = []
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a object
+ txParams.from = {}
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
+
+ // where from is a invalid address
+ txParams.from = 'im going to fail'
+ assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address`)
+
+ // should run
+ txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
+ txUtils.validateFrom(txParams)
+ })
+ })
+})
diff --git a/ui/app/actions.js b/ui/app/actions.js
index ad4270cef..f060e40bd 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1,8 +1,10 @@
const abi = require('human-standard-token-abi')
+const pify = require('pify')
const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
const { getTokenAddressFromTokenObject } = require('./util')
const ethUtil = require('ethereumjs-util')
const { fetchLocale } = require('../i18n-helper')
+const log = require('loglevel')
var actions = {
_setBackgroundConnection: _setBackgroundConnection,
@@ -82,7 +84,7 @@ var actions = {
REVEAL_SEED_CONFIRMATION: 'REVEAL_SEED_CONFIRMATION',
revealSeedConfirmation: revealSeedConfirmation,
requestRevealSeed: requestRevealSeed,
-
+ requestRevealSeedWords,
// unlock screen
UNLOCK_IN_PROGRESS: 'UNLOCK_IN_PROGRESS',
UNLOCK_FAILED: 'UNLOCK_FAILED',
@@ -220,8 +222,6 @@ var actions = {
coinBaseSubview: coinBaseSubview,
SHAPESHIFT_SUBVIEW: 'SHAPESHIFT_SUBVIEW',
shapeShiftSubview: shapeShiftSubview,
- UPDATE_TOKEN_EXCHANGE_RATE: 'UPDATE_TOKEN_EXCHANGE_RATE',
- updateTokenExchangeRate,
PAIR_UPDATE: 'PAIR_UPDATE',
pairUpdate: pairUpdate,
coinShiftRquest: coinShiftRquest,
@@ -347,7 +347,7 @@ function transitionBackward () {
}
function confirmSeedWords () {
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
log.debug(`background.clearSeedWordCache`)
return new Promise((resolve, reject) => {
@@ -355,7 +355,7 @@ function confirmSeedWords () {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.displayWarning(err.message))
- reject(err)
+ return reject(err)
}
log.info('Seed word cache cleared. ' + account)
@@ -428,6 +428,30 @@ function revealSeedConfirmation () {
}
}
+function verifyPassword (password) {
+ return new Promise((resolve, reject) => {
+ background.submitPassword(password, error => {
+ if (error) {
+ return reject(error)
+ }
+
+ resolve(true)
+ })
+ })
+}
+
+function verifySeedPhrase () {
+ return new Promise((resolve, reject) => {
+ background.verifySeedPhrase((error, seedWords) => {
+ if (error) {
+ return reject(error)
+ }
+
+ resolve(seedWords)
+ })
+ })
+}
+
function requestRevealSeed (password) {
return dispatch => {
dispatch(actions.showLoadingIndication())
@@ -455,6 +479,24 @@ function requestRevealSeed (password) {
}
}
+function requestRevealSeedWords (password) {
+ return async dispatch => {
+ dispatch(actions.showLoadingIndication())
+ log.debug(`background.submitPassword`)
+
+ try {
+ await verifyPassword(password)
+ const seedWords = await verifySeedPhrase()
+ dispatch(actions.hideLoadingIndication())
+ return seedWords
+ } catch (error) {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.displayWarning(error.message))
+ throw new Error(error.message)
+ }
+ }
+}
+
function resetAccount () {
return (dispatch) => {
background.resetAccount((err, account) => {
@@ -482,31 +524,26 @@ function addNewKeyring (type, opts) {
}
function importNewAccount (strategy, args) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication('This may take a while, be patient.'))
- log.debug(`background.importAccountWithStrategy`)
- return new Promise((resolve, reject) => {
- background.importAccountWithStrategy(strategy, args, (err) => {
- if (err) {
- dispatch(actions.displayWarning(err.message))
- return reject(err)
- }
- log.debug(`background.getState`)
- background.getState((err, newState) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.displayWarning(err.message))
- return reject(err)
- }
- dispatch(actions.updateMetamaskState(newState))
- dispatch({
- type: actions.SHOW_ACCOUNT_DETAIL,
- value: newState.selectedAddress,
- })
- resolve(newState)
- })
- })
+ return async (dispatch) => {
+ let newState
+ dispatch(actions.showLoadingIndication('This may take a while, please be patient.'))
+ try {
+ log.debug(`background.importAccountWithStrategy`)
+ await pify(background.importAccountWithStrategy).call(background, strategy, args)
+ log.debug(`background.getState`)
+ newState = await pify(background.getState).call(background)
+ } catch (err) {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.displayWarning(err.message))
+ throw err
+ }
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch({
+ type: actions.SHOW_ACCOUNT_DETAIL,
+ value: newState.selectedAddress,
})
+ return newState
}
}
@@ -571,35 +608,47 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signMessage`)
- background.signMessage(msgData, (err, newState) => {
- log.debug('signMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signMessage`)
+ background.signMessage(msgData, (err, newState) => {
+ log.debug('signMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
function signPersonalMsg (msgData) {
log.debug('action - signPersonalMsg')
- return (dispatch) => {
+ return dispatch => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signPersonalMessage`)
- background.signPersonalMessage(msgData, (err, newState) => {
- log.debug('signPersonalMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signPersonalMessage`)
+ background.signPersonalMessage(msgData, (err, newState) => {
+ log.debug('signPersonalMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -609,16 +658,22 @@ function signTypedMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- log.debug(`actions calling background.signTypedMessage`)
- background.signTypedMessage(msgData, (err, newState) => {
- log.debug('signTypedMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
+ return new Promise((resolve, reject) => {
+ log.debug(`actions calling background.signTypedMessage`)
+ background.signTypedMessage(msgData, (err, newState) => {
+ log.debug('signTypedMessage called back')
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
+ if (err) {
+ log.error(err)
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
- dispatch(actions.completedTx(msgData.metamaskId))
+ dispatch(actions.completedTx(msgData.metamaskId))
+ return resolve(msgData)
+ })
})
}
}
@@ -798,17 +853,24 @@ function updateTransaction (txData) {
function updateAndApproveTx (txData) {
log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData))
return (dispatch) => {
- log.debug(`actions calling background.updateAndApproveTx.`)
- background.updateAndApproveTransaction(txData, (err) => {
- dispatch(actions.hideLoadingIndication())
- dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
- dispatch(actions.clearSend())
- if (err) {
- dispatch(actions.txError(err))
- dispatch(actions.goHome())
- return log.error(err.message)
- }
- dispatch(actions.completedTx(txData.id))
+ log.debug(`actions calling background.updateAndApproveTx`)
+
+ return new Promise((resolve, reject) => {
+ background.updateAndApproveTransaction(txData, err => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
+ dispatch(actions.clearSend())
+
+ if (err) {
+ dispatch(actions.txError(err))
+ dispatch(actions.goHome())
+ log.error(err.message)
+ reject(err)
+ }
+
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -836,29 +898,77 @@ function txError (err) {
}
function cancelMsg (msgData) {
- log.debug(`background.cancelMessage`)
- background.cancelMessage(msgData.id)
- return actions.completedTx(msgData.id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ log.debug(`background.cancelMessage`)
+ background.cancelMessage(msgData.id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(msgData.id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelPersonalMsg (msgData) {
- const id = msgData.id
- background.cancelPersonalMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelPersonalMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTypedMsg (msgData) {
- const id = msgData.id
- background.cancelTypedMessage(id)
- return actions.completedTx(id)
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return new Promise((resolve, reject) => {
+ const id = msgData.id
+ background.cancelTypedMessage(id, (err, newState) => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ return reject(err)
+ }
+
+ dispatch(actions.completedTx(id))
+ return resolve(msgData)
+ })
+ })
+ }
}
function cancelTx (txData) {
- return (dispatch) => {
+ return dispatch => {
log.debug(`background.cancelTransaction`)
- background.cancelTransaction(txData.id, () => {
- dispatch(actions.clearSend())
- dispatch(actions.completedTx(txData.id))
+ return new Promise((resolve, reject) => {
+ background.cancelTransaction(txData.id, () => {
+ dispatch(actions.clearSend())
+ dispatch(actions.completedTx(txData.id))
+ resolve(txData)
+ })
})
}
}
@@ -1249,12 +1359,13 @@ function markNoticeRead (notice) {
dispatch(actions.displayWarning(err))
return reject(err)
}
+
if (notice) {
dispatch(actions.showNotice(notice))
- resolve()
+ resolve(true)
} else {
dispatch(actions.clearNotices())
- resolve()
+ resolve(false)
}
})
})
@@ -1677,28 +1788,6 @@ function shapeShiftRequest (query, options, cb) {
}
}
-function updateTokenExchangeRate (token = '') {
- const pair = `${token.toLowerCase()}_eth`
-
- return dispatch => {
- if (!token) {
- return
- }
-
- shapeShiftRequest('marketinfo', { pair }, marketinfo => {
- if (!marketinfo.error) {
- dispatch({
- type: actions.UPDATE_TOKEN_EXCHANGE_RATE,
- payload: {
- pair,
- marketinfo,
- },
- })
- }
- })
- }
-}
-
function setFeatureFlag (feature, activated, notificationType) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
@@ -1773,7 +1862,7 @@ function forceUpdateMetamaskState (dispatch) {
}
dispatch(actions.updateMetamaskState(newState))
- resolve()
+ resolve(newState)
})
})
}
diff --git a/ui/app/app.js b/ui/app/app.js
index 0b7a7a1e0..c93a6314c 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -1,62 +1,410 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
+const { Component } = require('react')
+const PropTypes = require('prop-types')
const connect = require('react-redux').connect
+const { Route, Switch, withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const h = require('react-hyperscript')
-const PropTypes = require('prop-types')
const actions = require('./actions')
const classnames = require('classnames')
+const log = require('loglevel')
-// mascara
-const MascaraFirstTime = require('../../mascara/src/app/first-time').default
-const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
// init
-const OldUIInitializeMenuScreen = require('./first-time/init-menu')
-const InitializeMenuScreen = MascaraFirstTime
-const NewKeyChainScreen = require('./new-keychain')
-const WelcomeScreen = require('./welcome-screen').default
-
+const InitializeScreen = require('../../mascara/src/app/first-time').default
// accounts
-const MainContainer = require('./main-container')
const SendTransactionScreen2 = require('./components/send/send-v2-container')
const ConfirmTxScreen = require('./conf-tx')
-// notice
-const NoticeScreen = require('./components/notice')
-const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
// slideout menu
const WalletView = require('./components/wallet-view')
// other views
-const Settings = require('./settings')
-const AddTokenScreen = require('./add-token')
-const Import = require('./accounts/import')
-const NewAccount = require('./accounts/new-account')
-const Loading = require('./components/loading')
+const Home = require('./components/pages/home')
+const Authenticated = require('./components/pages/authenticated')
+const Initialized = require('./components/pages/initialized')
+const Settings = require('./components/pages/settings')
+const UnlockPage = require('./components/pages/unlock')
+const RestoreVaultPage = require('./components/pages/keychains/restore-vault')
+const RevealSeedConfirmation = require('./components/pages/keychains/reveal-seed')
+const AddTokenPage = require('./components/pages/add-token')
+const CreateAccountPage = require('./components/pages/create-account')
+const NoticeScreen = require('./components/pages/notice')
+
+const Loading = require('./components/loading-screen')
const NetworkIndicator = require('./components/network')
const Identicon = require('./components/identicon')
-const BuyView = require('./components/buy-button-subview')
-const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
-const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
-const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const NetworkDropdown = require('./components/dropdowns/network-dropdown')
const AccountMenu = require('./components/account-menu')
-const QrView = require('./components/qr-code')
// Global Modals
const Modal = require('./components/modals/index').Modal
-App.contextTypes = {
- t: PropTypes.func,
-}
+// Routes
+const {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ REVEAL_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ INITIALIZE_ROUTE,
+ NOTICE_ROUTE,
+} = require('./routes')
+
+class App extends Component {
+ componentWillMount () {
+ const { currentCurrency, setCurrentCurrencyToUSD } = this.props
+
+ if (!currentCurrency) {
+ setCurrentCurrencyToUSD()
+ }
+ }
-module.exports = connect(mapStateToProps, mapDispatchToProps)(App)
+ renderRoutes () {
+ const exact = true
+
+ return (
+ h(Switch, [
+ h(Route, { path: INITIALIZE_ROUTE, component: InitializeScreen }),
+ h(Initialized, { path: REVEAL_SEED_ROUTE, exact, component: RevealSeedConfirmation }),
+ h(Initialized, { path: UNLOCK_ROUTE, exact, component: UnlockPage }),
+ h(Initialized, { path: SETTINGS_ROUTE, component: Settings }),
+ h(Initialized, { path: RESTORE_VAULT_ROUTE, exact, component: RestoreVaultPage }),
+ h(Initialized, { path: NOTICE_ROUTE, exact, component: NoticeScreen }),
+ h(Authenticated, { path: CONFIRM_TRANSACTION_ROUTE, component: ConfirmTxScreen }),
+ h(Authenticated, { path: SEND_ROUTE, exact, component: SendTransactionScreen2 }),
+ h(Authenticated, { path: ADD_TOKEN_ROUTE, exact, component: AddTokenPage }),
+ h(Authenticated, { path: NEW_ACCOUNT_ROUTE, component: CreateAccountPage }),
+ h(Authenticated, { path: DEFAULT_ROUTE, exact, component: Home }),
+ ])
+ )
+ }
+
+ render () {
+ const {
+ isLoading,
+ loadingMessage,
+ network,
+ isMouseUser,
+ provider,
+ frequentRpcList,
+ currentView,
+ setMouseUserState,
+ } = this.props
+ const isLoadingNetwork = network === 'loading' && currentView.name !== 'config'
+ const loadMessage = loadingMessage || isLoadingNetwork ?
+ this.getConnectingLabel() : null
+ log.debug('Main ui render function')
+
+ return (
+ h('.flex-column.full-height', {
+ className: classnames({ 'mouse-user-styles': isMouseUser }),
+ style: {
+ overflowX: 'hidden',
+ position: 'relative',
+ alignItems: 'center',
+ },
+ tabIndex: '0',
+ onClick: () => setMouseUserState(true),
+ onKeyDown: (e) => {
+ if (e.keyCode === 9) {
+ setMouseUserState(false)
+ }
+ },
+ }, [
+ // global modal
+ h(Modal, {}, []),
-inherits(App, Component)
-function App () { Component.call(this) }
+ // app bar
+ this.renderAppBar(),
+
+ // sidebar
+ this.renderSidebar(),
+
+ // network dropdown
+ h(NetworkDropdown, {
+ provider,
+ frequentRpcList,
+ }, []),
+
+ h(AccountMenu),
+
+ (isLoading || isLoadingNetwork) && h(Loading, {
+ loadingMessage: loadMessage,
+ fullScreen: true,
+ }),
+
+ // content
+ this.renderRoutes(),
+ ])
+ )
+ }
+
+ renderGlobalModal () {
+ return h(Modal, {
+ ref: 'modalRef',
+ }, [
+ // h(BuyOptions, {}, []),
+ ])
+ }
+
+ renderSidebar () {
+ return h('div', [
+ h('style', `
+ .sidebar-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(-100%);
+ }
+ .sidebar-enter.sidebar-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave.sidebar-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(-100%);
+ }
+ `),
+
+ h(ReactCSSTransitionGroup, {
+ transitionName: 'sidebar',
+ transitionEnterTimeout: 300,
+ transitionLeaveTimeout: 200,
+ }, [
+ // A second instance of Walletview is used for non-mobile viewports
+ this.props.sidebarOpen ? h(WalletView, {
+ responsiveDisplayClassname: '.sidebar',
+ style: {},
+ }) : undefined,
+
+ ]),
+
+ // overlay
+ // TODO: add onClick for overlay to close sidebar
+ this.props.sidebarOpen ? h('div.sidebar-overlay', {
+ style: {},
+ onClick: () => {
+ this.props.hideSidebar()
+ },
+ }, []) : undefined,
+ ])
+ }
+
+ renderAppBar () {
+ const {
+ isUnlocked,
+ network,
+ provider,
+ networkDropdownOpen,
+ showNetworkDropdown,
+ hideNetworkDropdown,
+ isInitialized,
+ welcomeScreenSeen,
+ isPopup,
+ betaUI,
+ } = this.props
+
+ if (window.METAMASK_UI_TYPE === 'notification') {
+ return null
+ }
+
+ const props = this.props
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
+ return (
+
+ h('.full-width', {
+ style: {},
+ }, [
+
+ (isInitialized || welcomeScreenSeen || isPopup || !betaUI) && h('.app-header.flex-row.flex-space-between', {
+ className: classnames({
+ 'app-header--initialized': !isOnboarding,
+ }),
+ }, [
+ h('div.app-header-contents', {}, [
+ h('div.left-menu-wrapper', {
+ onClick: () => props.history.push(DEFAULT_ROUTE),
+ }, [
+ // mini logo
+ h('img.metafox-icon', {
+ height: 42,
+ width: 42,
+ src: '/images/metamask-fox.svg',
+ }),
+
+ // metamask name
+ h('.flex-row', [
+ h('h1', this.context.t('appName')),
+ h('div.beta-label', this.context.t('beta')),
+ ]),
+
+ ]),
+
+ betaUI && isInitialized && h('div.header__right-actions', [
+ h('div.network-component-wrapper', {
+ style: {},
+ }, [
+ // Network Indicator
+ h(NetworkIndicator, {
+ network,
+ provider,
+ disabled: this.props.location.pathname === CONFIRM_TRANSACTION_ROUTE,
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ return networkDropdownOpen === false
+ ? showNetworkDropdown()
+ : hideNetworkDropdown()
+ },
+ }),
+
+ ]),
+
+ isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
+ h(Identicon, {
+ address: this.props.selectedAddress,
+ diameter: 32,
+ }),
+ ]),
+ ]),
+ ]),
+ ]),
+
+ !isInitialized && !isPopup && betaUI && h('.alpha-warning__container', {}, [
+ h('h2', {
+ className: classnames({
+ 'alpha-warning': welcomeScreenSeen,
+ 'alpha-warning-welcome-screen': !welcomeScreenSeen,
+ }),
+ }, 'Please be aware that this version is still under development'),
+ ]),
+
+ ])
+ )
+ }
+
+ toggleMetamaskActive () {
+ if (!this.props.isUnlocked) {
+ // currently inactive: redirect to password box
+ var passwordBox = document.querySelector('input[type=password]')
+ if (!passwordBox) return
+ passwordBox.focus()
+ } else {
+ // currently active: deactivate
+ this.props.dispatch(actions.lockMetamask(false))
+ }
+ }
+
+ getConnectingLabel = function () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = this.context.t('connectingToMainnet')
+ } else if (providerName === 'ropsten') {
+ name = this.context.t('connectingToRopsten')
+ } else if (providerName === 'kovan') {
+ name = this.context.t('connectingToRopsten')
+ } else if (providerName === 'rinkeby') {
+ name = this.context.t('connectingToRinkeby')
+ } else {
+ name = this.context.t('connectingToUnknown')
+ }
+
+ return name
+ }
+
+ getNetworkName () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = this.context.t('mainnet')
+ } else if (providerName === 'ropsten') {
+ name = this.context.t('ropsten')
+ } else if (providerName === 'kovan') {
+ name = this.context.t('kovan')
+ } else if (providerName === 'rinkeby') {
+ name = this.context.t('rinkeby')
+ } else {
+ name = this.context.t('unknownNetwork')
+ }
+
+ return name
+ }
+}
+
+App.propTypes = {
+ currentCurrency: PropTypes.string,
+ setCurrentCurrencyToUSD: PropTypes.func,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcList: PropTypes.array,
+ currentView: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ hideSidebar: PropTypes.func,
+ isMascara: PropTypes.bool,
+ isOnboarding: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ networkDropdownOpen: PropTypes.bool,
+ showNetworkDropdown: PropTypes.func,
+ hideNetworkDropdown: PropTypes.func,
+ history: PropTypes.object,
+ location: PropTypes.object,
+ dispatch: PropTypes.func,
+ toggleAccountMenu: PropTypes.func,
+ selectedAddress: PropTypes.string,
+ noActiveNotices: PropTypes.bool,
+ lostAccounts: PropTypes.array,
+ isInitialized: PropTypes.bool,
+ forgottenPassword: PropTypes.bool,
+ activeAddress: PropTypes.string,
+ unapprovedTxs: PropTypes.object,
+ seedWords: PropTypes.string,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+ welcomeScreenSeen: PropTypes.bool,
+ isPopup: PropTypes.bool,
+ betaUI: PropTypes.bool,
+ isMouseUser: PropTypes.bool,
+ setMouseUserState: PropTypes.func,
+ t: PropTypes.func,
+}
function mapStateToProps (state) {
+ const { appState, metamask } = state
+ const {
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ } = appState
+
const {
identities,
accounts,
@@ -65,17 +413,23 @@ function mapStateToProps (state) {
isInitialized,
noActiveNotices,
seedWords,
- } = state.metamask
+ unapprovedTxs,
+ lastUnreadNotice,
+ lostAccounts,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
const selected = address || Object.keys(accounts)[0]
return {
// state from plugin
- networkDropdownOpen: state.appState.networkDropdownOpen,
- sidebarOpen: state.appState.sidebarOpen,
- isLoading: state.appState.isLoading,
- loadingMessage: state.appState.loadingMessage,
- noActiveNotices: state.metamask.noActiveNotices,
- isInitialized: state.metamask.isInitialized,
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ noActiveNotices,
+ isInitialized,
isUnlocked: state.metamask.isUnlocked,
selectedAddress: state.metamask.selectedAddress,
currentView: state.appState.currentView,
@@ -85,14 +439,17 @@ function mapStateToProps (state) {
isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
isPopup: state.metamask.isPopup,
seedWords: state.metamask.seedWords,
- unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedTxs,
unapprovedMsgs: state.metamask.unapprovedMsgs,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
menuOpen: state.appState.menuOpen,
network: state.metamask.network,
provider: state.metamask.provider,
- forgottenPassword: state.metamask.forgottenPassword,
- lastUnreadNotice: state.metamask.lastUnreadNotice,
- lostAccounts: state.metamask.lostAccounts,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice,
+ lostAccounts,
frequentRpcList: state.metamask.frequentRpcList || [],
currentCurrency: state.metamask.currentCurrency,
isMouseUser: state.appState.isMouseUser,
@@ -120,479 +477,11 @@ function mapDispatchToProps (dispatch, ownProps) {
}
}
-App.prototype.componentWillMount = function () {
- if (!this.props.currentCurrency) {
- this.props.setCurrentCurrencyToUSD()
- }
-}
-
-App.prototype.render = function () {
- var props = this.props
- const {
- isLoading,
- loadingMessage,
- network,
- isMouseUser,
- setMouseUserState,
- } = props
- const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
- const loadMessage = loadingMessage || isLoadingNetwork ?
- this.getConnectingLabel() : null
- log.debug('Main ui render function')
-
- return (
- h('.flex-column.full-height', {
- className: classnames({ 'mouse-user-styles': isMouseUser }),
- style: {
- overflowX: 'hidden',
- position: 'relative',
- alignItems: 'center',
- },
- tabIndex: '0',
- onClick: () => setMouseUserState(true),
- onKeyDown: (e) => {
- if (e.keyCode === 9) {
- setMouseUserState(false)
- }
- },
- }, [
-
- // global modal
- h(Modal, {}, []),
-
- // app bar
- this.renderAppBar(),
-
- // sidebar
- this.renderSidebar(),
-
- // network dropdown
- h(NetworkDropdown, {
- provider: this.props.provider,
- frequentRpcList: this.props.frequentRpcList,
- }, []),
-
- h(AccountMenu),
-
- (isLoading || isLoadingNetwork) && h(Loading, {
- loadingMessage: loadMessage,
- }),
-
- // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
-
- // content
- this.renderPrimary(),
- ])
- )
-}
-
-App.prototype.renderGlobalModal = function () {
- return h(Modal, {
- ref: 'modalRef',
- }, [
- // h(BuyOptions, {}, []),
- ])
-}
-
-App.prototype.renderSidebar = function () {
-
- return h('div', {
- }, [
- h('style', `
- .sidebar-enter {
- transition: transform 300ms ease-in-out;
- transform: translateX(-100%);
- }
- .sidebar-enter.sidebar-enter-active {
- transition: transform 300ms ease-in-out;
- transform: translateX(0%);
- }
- .sidebar-leave {
- transition: transform 200ms ease-out;
- transform: translateX(0%);
- }
- .sidebar-leave.sidebar-leave-active {
- transition: transform 200ms ease-out;
- transform: translateX(-100%);
- }
- `),
-
- h(ReactCSSTransitionGroup, {
- transitionName: 'sidebar',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 200,
- }, [
- // A second instance of Walletview is used for non-mobile viewports
- this.props.sidebarOpen ? h(WalletView, {
- responsiveDisplayClassname: '.sidebar',
- style: {},
- }) : undefined,
-
- ]),
-
- // overlay
- // TODO: add onClick for overlay to close sidebar
- this.props.sidebarOpen ? h('div.sidebar-overlay', {
- style: {},
- onClick: () => {
- this.props.hideSidebar()
- },
- }, []) : undefined,
- ])
-}
-
-App.prototype.renderAppBar = function () {
- const {
- isUnlocked,
- network,
- provider,
- networkDropdownOpen,
- showNetworkDropdown,
- hideNetworkDropdown,
- currentView,
- isInitialized,
- betaUI,
- isPopup,
- welcomeScreenSeen,
- } = this.props
-
- if (window.METAMASK_UI_TYPE === 'notification') {
- return null
- }
-
- const props = this.props
- const {isMascara, isOnboarding} = props
-
- // Do not render header if user is in mascara onboarding
- if (isMascara && isOnboarding) {
- return null
- }
-
- // Do not render header if user is in mascara buy ether
- if (isMascara && props.currentView.name === 'buyEth') {
- return null
- }
-
- return (
-
- h('.full-width', {
- style: {},
- }, [
-
- (isInitialized || welcomeScreenSeen || isPopup || !betaUI) && h('.app-header.flex-row.flex-space-between', {
- className: classnames({
- 'app-header--initialized': !isOnboarding,
- }),
- }, [
- h('div.app-header-contents', {}, [
- h('div.left-menu-wrapper', {
- onClick: () => {
- props.dispatch(actions.backToAccountDetail(props.activeAddress))
- },
- }, [
- // mini logo
- h('img.metafox-icon', {
- height: 42,
- width: 42,
- src: './images/metamask-fox.svg',
- }),
-
- // metamask name
- h('.flex-row', [
- h('h1', this.context.t('appName')),
- h('div.beta-label', this.context.t('beta')),
- ]),
- ]),
-
- betaUI && isInitialized && h('div.header__right-actions', [
- h('div.network-component-wrapper', {
- style: {},
- }, [
- // Network Indicator
- h(NetworkIndicator, {
- network,
- provider,
- disabled: currentView.name === 'confTx',
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- return networkDropdownOpen === false
- ? showNetworkDropdown()
- : hideNetworkDropdown()
- },
- }),
-
- ]),
-
- isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
- h(Identicon, {
- address: this.props.selectedAddress,
- diameter: 32,
- }),
- ]),
- ]),
- ]),
- ]),
-
- !isInitialized && !isPopup && betaUI && h('.alpha-warning__container', {}, [
- h('h2', {
- className: classnames({
- 'alpha-warning': welcomeScreenSeen,
- 'alpha-warning-welcome-screen': !welcomeScreenSeen,
- }),
- }, 'Please be aware that this version is still under development'),
- ]),
-
- ])
- )
-}
-
-App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
- const { isMascara } = this.props
-
- return isMascara
- ? null
- : h(Loading, {
- isLoading: isLoading || isLoadingNetwork,
- loadingMessage: loadMessage,
- })
-}
-
-App.prototype.renderBackButton = function (style, justArrow = false) {
- var props = this.props
- return (
- h('.flex-row', {
- key: 'leftArrow',
- style: style,
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, [
- h('i.fa.fa-arrow-left.cursor-pointer'),
- justArrow ? null : h('div.cursor-pointer', {
- style: {
- marginLeft: '3px',
- },
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, 'BACK'),
- ])
- )
-}
-
-App.prototype.renderPrimary = function () {
- log.debug('rendering primary')
- var props = this.props
- const {
- isMascara,
- isOnboarding,
- betaUI,
- isRevealingSeedWords,
- welcomeScreenSeen,
- Qr,
- isInitialized,
- isUnlocked,
- } = props
- const isMascaraOnboarding = isMascara && isOnboarding
- const isBetaUIOnboarding = betaUI && isOnboarding
-
- if (!welcomeScreenSeen && betaUI && !isInitialized && !isUnlocked) {
- return h(WelcomeScreen)
- }
-
- if (isMascaraOnboarding || isBetaUIOnboarding) {
- return h(MascaraFirstTime)
- }
-
- // notices
- if (!props.noActiveNotices && !betaUI) {
- log.debug('rendering notice screen for unread notices.')
- return h(NoticeScreen, {
- notice: props.lastUnreadNotice,
- key: 'NoticeScreen',
- onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
- })
- } else if (props.lostAccounts && props.lostAccounts.length > 0) {
- log.debug('rendering notice screen for lost accounts view.')
- return h(NoticeScreen, {
- notice: generateLostAccountsNotice(props.lostAccounts),
- key: 'LostAccountsNotice',
- onConfirm: () => props.dispatch(actions.markAccountsFound()),
- })
- }
-
- if (props.isInitialized && props.forgottenPassword) {
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
- } else if (!props.isInitialized && !props.isUnlocked && !isRevealingSeedWords) {
- log.debug('rendering menu screen')
- return !betaUI
- ? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'})
- : h(InitializeMenuScreen, {key: 'menuScreenInit'})
- }
-
- // show unlock screen
- if (!props.isUnlocked) {
- return h(MainContainer, {
- currentViewName: props.currentView.name,
- isUnlocked: props.isUnlocked,
- })
- }
-
- // show seed words screen
- if (props.seedWords) {
- log.debug('rendering seed words')
- return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
- }
-
- // show current view
- switch (props.currentView.name) {
-
- case 'accountDetail':
- log.debug('rendering main container')
- return h(MainContainer, {key: 'account-detail'})
-
- case 'sendTransaction':
- log.debug('rendering send tx screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTransactionScreen
-
- return h(SendTransactionScreen2, {key: 'send-transaction'})
-
- case 'sendToken':
- log.debug('rendering send token screen')
-
- // Going to leave this here until we are ready to delete SendTransactionScreen v1
- // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
- // ? SendTransactionScreen2
- // : SendTokenScreen
-
- return h(SendTransactionScreen2, {key: 'sendToken'})
-
- case 'newKeychain':
- log.debug('rendering new keychain screen')
- return h(NewKeyChainScreen, {key: 'new-keychain'})
-
- case 'confTx':
- log.debug('rendering confirm tx screen')
- return h(ConfirmTxScreen, {key: 'confirm-tx'})
-
- case 'add-token':
- log.debug('rendering add-token screen from unlock screen.')
- return h(AddTokenScreen, {key: 'add-token'})
-
- case 'config':
- log.debug('rendering config screen')
- return h(Settings, {key: 'config'})
-
- case 'import-menu':
- log.debug('rendering import screen')
- return h(Import, {key: 'import-menu'})
-
- case 'new-account-page':
- log.debug('rendering new account screen')
- return h(NewAccount, {key: 'new-account'})
-
- case 'reveal-seed-conf':
- log.debug('rendering reveal seed confirmation screen')
- return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
-
- case 'info':
- log.debug('rendering info screen')
- return h(Settings, {key: 'info', tab: 'info'})
-
- case 'buyEth':
- log.debug('rendering buy ether screen')
- return h(BuyView, {key: 'buyEthView'})
-
- case 'onboardingBuyEth':
- log.debug('rendering onboarding buy ether screen')
- return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
-
- case 'qr':
- log.debug('rendering show qr screen')
- return h('div', {
- style: {
- position: 'absolute',
- height: '100%',
- top: '0px',
- left: '0px',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
- style: {
- marginLeft: '10px',
- marginTop: '50px',
- },
- }),
- h('div', {
- style: {
- position: 'absolute',
- left: '44px',
- width: '285px',
- },
- }, [
- h(QrView, {key: 'qr', Qr}),
- ]),
- ])
-
- default:
- log.debug('rendering default, account detail screen')
- return h(MainContainer, {key: 'account-detail'})
- }
-}
-
-App.prototype.toggleMetamaskActive = function () {
- if (!this.props.isUnlocked) {
- // currently inactive: redirect to password box
- var passwordBox = document.querySelector('input[type=password]')
- if (!passwordBox) return
- passwordBox.focus()
- } else {
- // currently active: deactivate
- this.props.dispatch(actions.lockMetamask(false))
- }
-}
-
-App.prototype.getConnectingLabel = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('connectingToMainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('connectingToRopsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('connectingToRopsten')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('connectingToRinkeby')
- } else {
- name = this.context.t('connectingToUnknown')
- }
-
- return name
+App.contextTypes = {
+ t: PropTypes.func,
}
-App.prototype.getNetworkName = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = this.context.t('mainnet')
- } else if (providerName === 'ropsten') {
- name = this.context.t('ropsten')
- } else if (providerName === 'kovan') {
- name = this.context.t('kovan')
- } else if (providerName === 'rinkeby') {
- name = this.context.t('rinkeby')
- } else {
- name = this.context.t('unknownNetwork')
- }
-
- return name
-}
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(App)
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index 03955e077..043008a36 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -7,8 +7,8 @@ const connect = require('react-redux').connect
const Dropdown = require('./dropdown').Dropdown
const DropdownMenuItem = require('./dropdown').DropdownMenuItem
const Identicon = require('./identicon')
-const ethUtil = require('ethereumjs-util')
const copyToClipboard = require('copy-to-clipboard')
+const { checksumAddress } = require('../util')
class AccountDropdowns extends Component {
constructor (props) {
@@ -212,8 +212,7 @@ class AccountDropdowns extends Component {
closeMenu: () => {},
onClick: () => {
const { selected } = this.props
- const checkSumAddress = selected && ethUtil.toChecksumAddress(selected)
- copyToClipboard(checkSumAddress)
+ copyToClipboard(checksumAddress(selected))
},
},
this.context.t('copyAddress'),
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
index 21de358d6..7638995ea 100644
--- a/ui/app/components/account-menu/index.js
+++ b/ui/app/components/account-menu/index.js
@@ -1,20 +1,31 @@
const inherits = require('util').inherits
const Component = require('react').Component
-const PropTypes = require('prop-types')
const connect = require('react-redux').connect
+const { compose } = require('recompose')
+const { withRouter } = require('react-router-dom')
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../../actions')
const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
const Identicon = require('../identicon')
const { formatBalance } = require('../../util')
+const {
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ DEFAULT_ROUTE,
+} = require('../../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(AccountMenu)
AccountMenu.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountMenu)
-
-
inherits(AccountMenu, Component)
function AccountMenu () { Component.call(this) }
@@ -25,7 +36,6 @@ function mapStateToProps (state) {
keyrings: state.metamask.keyrings,
identities: state.metamask.identities,
accounts: state.metamask.accounts,
-
}
}
@@ -48,11 +58,6 @@ function mapDispatchToProps (dispatch) {
dispatch(actions.hideSidebar())
dispatch(actions.toggleAccountMenu())
},
- showNewAccountPage: (formToSelect) => {
- dispatch(actions.showNewAccountPage(formToSelect))
- dispatch(actions.hideSidebar())
- dispatch(actions.toggleAccountMenu())
- },
showInfoPage: () => {
dispatch(actions.showInfoPage())
dispatch(actions.hideSidebar())
@@ -65,10 +70,8 @@ AccountMenu.prototype.render = function () {
const {
isAccountMenuOpen,
toggleAccountMenu,
- showNewAccountPage,
lockMetamask,
- showConfigPage,
- showInfoPage,
+ history,
} = this.props
return h(Menu, { className: 'account-menu', isShowing: isAccountMenuOpen }, [
@@ -78,30 +81,45 @@ AccountMenu.prototype.render = function () {
}, [
this.context.t('myAccounts'),
h('button.account-menu__logout-button', {
- onClick: lockMetamask,
+ onClick: () => {
+ lockMetamask()
+ history.push(DEFAULT_ROUTE)
+ },
}, this.context.t('logout')),
]),
h(Divider),
h('div.account-menu__accounts', this.renderAccounts()),
h(Divider),
h(Item, {
- onClick: () => showNewAccountPage('CREATE'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(NEW_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }),
text: this.context.t('createAccount'),
}),
h(Item, {
- onClick: () => showNewAccountPage('IMPORT'),
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(IMPORT_ACCOUNT_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }),
text: this.context.t('importAccount'),
}),
h(Divider),
h(Item, {
- onClick: showInfoPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(INFO_ROUTE)
+ },
icon: h('img', { src: 'images/mm-info-icon.svg' }),
text: this.context.t('infoHelp'),
}),
h(Item, {
- onClick: showConfigPage,
+ onClick: () => {
+ toggleAccountMenu()
+ history.push(SETTINGS_ROUTE)
+ },
icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
text: this.context.t('settings'),
}),
diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js
index d591ab455..e31552f2d 100644
--- a/ui/app/components/balance-component.js
+++ b/ui/app/components/balance-component.js
@@ -4,6 +4,8 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const TokenBalance = require('./token-balance')
const Identicon = require('./identicon')
+const currencyFormatter = require('currency-formatter')
+const currencies = require('currency-formatter/currencies')
const { formatBalance, generateBalanceObject } = require('../util')
@@ -97,9 +99,17 @@ BalanceComponent.prototype.renderFiatAmount = function (fiatDisplayNumber, fiatS
const shouldNotRenderFiat = fiatDisplayNumber === 'N/A' || Number(fiatDisplayNumber) === 0
if (shouldNotRenderFiat) return null
+ const upperCaseFiatSuffix = fiatSuffix.toUpperCase()
+
+ const display = currencies.find(currency => currency.code === upperCaseFiatSuffix)
+ ? currencyFormatter.format(Number(fiatDisplayNumber), {
+ code: upperCaseFiatSuffix,
+ })
+ : `${fiatPrefix}${fiatDisplayNumber} ${upperCaseFiatSuffix}`
+
return h('div.fiat-amount', {
style: {},
- }, `${fiatPrefix}${fiatDisplayNumber} ${fiatSuffix}`)
+ }, display)
}
BalanceComponent.prototype.getTokenBalance = function (formattedBalance, shorten) {
@@ -117,5 +127,9 @@ BalanceComponent.prototype.getFiatDisplayNumber = function (formattedBalance, co
const splitBalance = formattedBalance.split(' ')
- return (Number(splitBalance[0]) * conversionRate).toFixed(2)
+ const convertedNumber = (Number(splitBalance[0]) * conversionRate)
+ const wholePart = Math.floor(convertedNumber)
+ const decimalPart = convertedNumber - wholePart
+
+ return wholePart + Number(decimalPart.toPrecision(2))
}
diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js
index 9ac565cf4..c6957d2aa 100644
--- a/ui/app/components/buy-button-subview.js
+++ b/ui/app/components/buy-button-subview.js
@@ -6,10 +6,10 @@ const connect = require('react-redux').connect
const actions = require('../actions')
const CoinbaseForm = require('./coinbase-form')
const ShapeshiftForm = require('./shapeshift-form')
-const Loading = require('./loading')
+const Loading = require('./loading-screen')
const AccountPanel = require('./account-panel')
const RadioList = require('./custom-radio-list')
-const networkNames = require('../../../app/scripts/config.js').networkNames
+const { getNetworkDisplayName } = require('../../../app/scripts/controllers/network/util')
BuyButtonSubview.contextTypes = {
t: PropTypes.func,
@@ -148,7 +148,7 @@ BuyButtonSubview.prototype.primarySubview = function () {
case '3':
case '4':
case '42':
- const networkName = networkNames[network]
+ const networkName = getNetworkDisplayName(network)
const label = `${networkName} ${this.context.t('testFaucet')}`
return (
h('div.flex-column', {
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
index 4c693d1c3..1ff8eea87 100644
--- a/ui/app/components/customize-gas-modal/index.js
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -280,8 +280,7 @@ CustomizeGasModal.prototype.render = function () {
h(GasModalCard, {
value: convertedGasPrice,
min: forceGasMin || MIN_GAS_PRICE_GWEI,
- // max: 1000,
- step: multiplyCurrencies(MIN_GAS_PRICE_GWEI, 10),
+ step: 1,
onChange: value => this.convertAndSetGasPrice(value),
title: this.context.t('gasPrice'),
copy: this.context.t('gasPriceCalculation'),
@@ -290,7 +289,6 @@ CustomizeGasModal.prototype.render = function () {
h(GasModalCard, {
value: convertedGasLimit,
min: 1,
- // max: 100000,
step: 1,
onChange: value => this.convertAndSetGasLimit(value),
title: this.context.t('gasLimit'),
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
index a133f0e29..179b6617f 100644
--- a/ui/app/components/dropdowns/components/account-dropdowns.js
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -7,7 +7,7 @@ const connect = require('react-redux').connect
const Dropdown = require('./dropdown').Dropdown
const DropdownMenuItem = require('./dropdown').DropdownMenuItem
const Identicon = require('../../identicon')
-const ethUtil = require('ethereumjs-util')
+const { checksumAddress } = require('../../../util')
const copyToClipboard = require('copy-to-clipboard')
const { formatBalance } = require('../../../util')
@@ -311,8 +311,7 @@ class AccountDropdowns extends Component {
closeMenu: () => {},
onClick: () => {
const { selected } = this.props
- const checkSumAddress = selected && ethUtil.toChecksumAddress(selected)
- copyToClipboard(checkSumAddress)
+ copyToClipboard(checksumAddress(selected))
},
style: Object.assign(
dropdownMenuItemStyle,
diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js
index 9e47f38ef..dcd6b4370 100644
--- a/ui/app/components/dropdowns/network-dropdown.js
+++ b/ui/app/components/dropdowns/network-dropdown.js
@@ -3,12 +3,14 @@ const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('../../actions')
const Dropdown = require('./components/dropdown').Dropdown
const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
const NetworkDropdownIcon = require('./components/network-dropdown-icon')
const R = require('ramda')
-
+const { SETTINGS_ROUTE } = require('../../routes')
// classes from nodes of the toggle element.
const notToggleElementClassnames = [
@@ -41,9 +43,6 @@ function mapDispatchToProps (dispatch) {
setRpcTarget: (target) => {
dispatch(actions.setRpcTarget(target))
},
- showConfigPage: () => {
- dispatch(actions.showConfigPage())
- },
showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
}
@@ -59,7 +58,10 @@ NetworkDropdown.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(NetworkDropdown)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(NetworkDropdown)
// TODO: specify default props and proptypes
@@ -227,7 +229,7 @@ NetworkDropdown.prototype.render = function () {
DropdownMenuItem,
{
closeMenu: () => this.props.hideNetworkDropdown(),
- onClick: () => this.props.showConfigPage(),
+ onClick: () => this.props.history.push(SETTINGS_ROUTE),
style: dropdownMenuItemStyle,
},
[
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index 1f3946817..aff4b6ef6 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -11,6 +11,7 @@ const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const connect = require('react-redux').connect
const ToAutoComplete = require('./send/to-autocomplete')
+const log = require('loglevel')
EnsInput.contextTypes = {
t: PropTypes.func,
@@ -32,10 +33,10 @@ EnsInput.prototype.render = function () {
const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network)
- if (!networkHasEnsSupport) return
-
props.onChange(recipient)
+ if (!networkHasEnsSupport) return
+
if (recipient.match(ensRE) === null) {
return this.setState({
loadingEns: false,
diff --git a/ui/app/components/export-text-container/export-text-container.component.js b/ui/app/components/export-text-container/export-text-container.component.js
new file mode 100644
index 000000000..c2546fa9b
--- /dev/null
+++ b/ui/app/components/export-text-container/export-text-container.component.js
@@ -0,0 +1,45 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const copyToClipboard = require('copy-to-clipboard')
+const { exportAsFile } = require('../../util')
+
+class ExportTextContainer extends Component {
+ render () {
+ const { text = '', filename = '' } = this.props
+ const { t } = this.context
+
+ return (
+ h('.export-text-container', [
+ h('.export-text-container__text-container', [
+ h('.export-text-container__text', text),
+ ]),
+ h('.export-text-container__buttons-container', [
+ h('.export-text-container__button.export-text-container__button--copy', {
+ onClick: () => copyToClipboard(text),
+ }, [
+ h('img', { src: 'images/copy-to-clipboard.svg' }),
+ h('.export-text-container__button-text', t('copyToClipboard')),
+ ]),
+ h('.export-text-container__button', {
+ onClick: () => exportAsFile(filename, text),
+ }, [
+ h('img', { src: 'images/download.svg' }),
+ h('.export-text-container__button-text', t('saveAsCsvFile')),
+ ]),
+ ]),
+ ])
+ )
+ }
+}
+
+ExportTextContainer.propTypes = {
+ text: PropTypes.string,
+ filename: PropTypes.string,
+}
+
+ExportTextContainer.contextTypes = {
+ t: PropTypes.func,
+}
+
+module.exports = ExportTextContainer
diff --git a/ui/app/components/export-text-container/export-text-container.scss b/ui/app/components/export-text-container/export-text-container.scss
new file mode 100644
index 000000000..a42de8233
--- /dev/null
+++ b/ui/app/components/export-text-container/export-text-container.scss
@@ -0,0 +1,52 @@
+.export-text-container {
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ border: 1px solid $alto;
+ border-radius: 4px;
+ font-weight: 400;
+
+ &__text-container {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 20px;
+ border-radius: 4px;
+ background: $alabaster;
+ }
+
+ &__text {
+ resize: none;
+ border: none;
+ background: $alabaster;
+ font-size: 20px;
+ text-align: center;
+ }
+
+ &__buttons-container {
+ display: flex;
+ flex-direction: row;
+ border-top: 1px solid $alto;
+ width: 100%;
+ }
+
+ &__button {
+ padding: 10px;
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 14px;
+ cursor: pointer;
+ color: $curious-blue;
+
+ &--copy {
+ border-right: 1px solid $alto;
+ }
+ }
+
+ &__button-text {
+ padding-left: 10px;
+ }
+}
diff --git a/ui/app/components/export-text-container/index.js b/ui/app/components/export-text-container/index.js
new file mode 100644
index 000000000..b2864a717
--- /dev/null
+++ b/ui/app/components/export-text-container/index.js
@@ -0,0 +1,2 @@
+const ExportTextContainer = require('./export-text-container.component')
+module.exports = ExportTextContainer
diff --git a/ui/app/components/loading-screen/index.js b/ui/app/components/loading-screen/index.js
new file mode 100644
index 000000000..191d953f7
--- /dev/null
+++ b/ui/app/components/loading-screen/index.js
@@ -0,0 +1,2 @@
+const LoadingScreen = require('./loading-screen.component')
+module.exports = LoadingScreen
diff --git a/ui/app/components/loading-screen/loading-screen.component.js b/ui/app/components/loading-screen/loading-screen.component.js
new file mode 100644
index 000000000..bce2a4aac
--- /dev/null
+++ b/ui/app/components/loading-screen/loading-screen.component.js
@@ -0,0 +1,35 @@
+const { Component } = require('react')
+const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
+const classnames = require('classnames')
+const Spinner = require('../spinner')
+
+class LoadingScreen extends Component {
+ renderMessage () {
+ const { loadingMessage } = this.props
+ return loadingMessage && h('span', loadingMessage)
+ }
+
+ render () {
+ return (
+ h('.loading-overlay', {
+ className: classnames({ 'loading-overlay--full-screen': this.props.fullScreen }),
+ }, [
+ h('.loading-overlay__container', [
+ h(Spinner, {
+ color: '#F7C06C',
+ }),
+
+ this.renderMessage(),
+ ]),
+ ])
+ )
+ }
+}
+
+LoadingScreen.propTypes = {
+ loadingMessage: PropTypes.string,
+ fullScreen: PropTypes.bool,
+}
+
+module.exports = LoadingScreen
diff --git a/ui/app/components/loading.js b/ui/app/components/loading.js
deleted file mode 100644
index cb6fa51fb..000000000
--- a/ui/app/components/loading.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const { Component } = require('react')
-const h = require('react-hyperscript')
-const PropTypes = require('prop-types')
-
-class LoadingIndicator extends Component {
- renderMessage () {
- const { loadingMessage } = this.props
- return loadingMessage && h('span', loadingMessage)
- }
-
- render () {
- return (
- h('.full-flex-height.loading-overlay', {}, [
- h('img', {
- src: 'images/loading.svg',
- }),
-
- h('br'),
-
- this.renderMessage(),
- ])
- )
- }
-}
-
-LoadingIndicator.propTypes = {
- loadingMessage: PropTypes.string,
-}
-
-module.exports = LoadingIndicator
diff --git a/ui/app/components/modals/buy-options-modal.js b/ui/app/components/modals/buy-options-modal.js
index d871e7516..c70510b5f 100644
--- a/ui/app/components/modals/buy-options-modal.js
+++ b/ui/app/components/modals/buy-options-modal.js
@@ -4,7 +4,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../actions')
-const networkNames = require('../../../../app/scripts/config.js').networkNames
+const { getNetworkDisplayName } = require('../../../../app/scripts/controllers/network/util')
function mapStateToProps (state) {
return {
@@ -52,7 +52,7 @@ BuyOptions.prototype.renderModalContentOption = function (title, header, onClick
BuyOptions.prototype.render = function () {
const { network, toCoinbase, address, toFaucet } = this.props
const isTestNetwork = ['3', '4', '42'].find(n => n === network)
- const networkName = networkNames[network]
+ const networkName = getNetworkDisplayName(network)
return h('div', {}, [
h('div.buy-modal-content.transfers-subview', {
diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js
index 0dc611f50..ad5f9b695 100644
--- a/ui/app/components/modals/deposit-ether-modal.js
+++ b/ui/app/components/modals/deposit-ether-modal.js
@@ -4,7 +4,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
const actions = require('../../actions')
-const networkNames = require('../../../../app/scripts/config.js').networkNames
+const { getNetworkDisplayName } = require('../../../../app/scripts/controllers/network/util')
const ShapeshiftForm = require('../shapeshift-form')
let DIRECT_DEPOSIT_ROW_TITLE
@@ -122,7 +122,7 @@ DepositEtherModal.prototype.render = function () {
const { buyingWithShapeshift } = this.state
const isTestNetwork = ['3', '4', '42'].find(n => n === network)
- const networkName = networkNames[network]
+ const networkName = getNetworkDisplayName(network)
return h('div.page-container.page-container--full-width.page-container--full-height', {}, [
diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js
index 1f80aed39..447e43b7a 100644
--- a/ui/app/components/modals/export-private-key-modal.js
+++ b/ui/app/components/modals/export-private-key-modal.js
@@ -3,12 +3,13 @@ const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
-const ethUtil = require('ethereumjs-util')
+const { stripHexPrefix } = require('ethereumjs-util')
const actions = require('../../actions')
const AccountModalContainer = require('./account-modal-container')
const { getSelectedIdentity } = require('../../selectors')
const ReadOnlyInput = require('../readonly-input')
const copyToClipboard = require('copy-to-clipboard')
+const { checksumAddress } = require('../../util')
function mapStateToProps (state) {
return {
@@ -60,7 +61,7 @@ ExportPrivateKeyModal.prototype.renderPasswordLabel = function (privateKey) {
}
ExportPrivateKeyModal.prototype.renderPasswordInput = function (privateKey) {
- const plainKey = privateKey && ethUtil.stripHexPrefix(privateKey)
+ const plainKey = privateKey && stripHexPrefix(privateKey)
return privateKey
? h(ReadOnlyInput, {
@@ -121,7 +122,7 @@ ExportPrivateKeyModal.prototype.render = function () {
h(ReadOnlyInput, {
wrapperClass: 'ellip-address-wrapper',
inputClass: 'qr-ellip-address ellip-address',
- value: address,
+ value: checksumAddress(address),
}),
h('div.account-modal-divider'),
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
index 9250cc77e..43dcd20ae 100644
--- a/ui/app/components/modals/modal.js
+++ b/ui/app/components/modals/modal.js
@@ -5,7 +5,8 @@ const connect = require('react-redux').connect
const FadeModal = require('boron').FadeModal
const actions = require('../../actions')
const isMobileView = require('../../../lib/is-mobile-view')
-const isPopupOrNotification = require('../../../../app/scripts/lib/is-popup-or-notification')
+const { getEnvironmentType } = require('../../../../app/scripts/lib/util')
+const { ENVIRONMENT_TYPE_POPUP } = require('../../../../app/scripts/lib/enums')
// Modal Components
const BuyOptions = require('./buy-options-modal')
@@ -162,7 +163,7 @@ const MODALS = {
],
mobileModalStyle: {
width: '95%',
- top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh',
},
laptopModalStyle: {
width: '449px',
@@ -179,7 +180,7 @@ const MODALS = {
],
mobileModalStyle: {
width: '95%',
- top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh',
},
laptopModalStyle: {
width: '449px',
@@ -196,7 +197,7 @@ const MODALS = {
],
mobileModalStyle: {
width: '95%',
- top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh',
},
laptopModalStyle: {
width: '449px',
@@ -208,7 +209,7 @@ const MODALS = {
contents: h(ConfirmResetAccount),
mobileModalStyle: {
width: '95%',
- top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ top: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP ? '52vh' : '36.5vh',
},
laptopModalStyle: {
width: '473px',
diff --git a/ui/app/add-token.js b/ui/app/components/pages/add-token.js
index a73874320..8d52571d0 100644
--- a/ui/app/add-token.js
+++ b/ui/app/components/pages/add-token.js
@@ -7,8 +7,8 @@ const connect = require('react-redux').connect
const R = require('ramda')
const Fuse = require('fuse.js')
const contractMap = require('eth-contract-metadata')
-const TokenBalance = require('./components/token-balance')
-const Identicon = require('./components/identicon')
+const TokenBalance = require('../../components/token-balance')
+const Identicon = require('../../components/identicon')
const contractList = Object.entries(contractMap)
.map(([ _, tokenData]) => tokenData)
.filter(tokenData => Boolean(tokenData.erc20))
@@ -24,9 +24,10 @@ const fuse = new Fuse(contractList, {
{ name: 'symbol', weight: 0.5 },
],
})
-const actions = require('./actions')
+const actions = require('../../actions')
const ethUtil = require('ethereumjs-util')
-const { tokenInfoGetter } = require('./token-util')
+const { tokenInfoGetter } = require('../../token-util')
+const { DEFAULT_ROUTE } = require('../../routes')
const emptyAddr = '0x0000000000000000000000000000000000000000'
@@ -47,7 +48,6 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
addTokens: tokens => dispatch(actions.addTokens(tokens)),
}
}
@@ -192,7 +192,7 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address)
if (symbol && decimals) {
this.setState({
customSymbol: symbol,
- customDecimals: decimals.toString(),
+ customDecimals: decimals,
autoFilled: true,
})
}
@@ -296,7 +296,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
selectedTokens,
} = this.state
- const { addTokens, goHome } = this.props
+ const { addTokens, history } = this.props
const customToken = {
address,
@@ -333,7 +333,7 @@ AddTokenScreen.prototype.renderConfirmation = function () {
onClick: () => this.setState({ isShowingConfirmation: false }),
}, this.context.t('back')),
h('button.btn-primary--lg', {
- onClick: () => addTokens(tokens).then(goHome),
+ onClick: () => addTokens(tokens).then(() => history.push(DEFAULT_ROUTE)),
}, this.context.t('addTokens')),
]),
])
@@ -360,6 +360,7 @@ AddTokenScreen.prototype.renderTabs = function () {
h('div.add-token__info-box__copy', this.context.t('keepTrackTokens')),
h('a.add-token__info-box__copy--blue', {
href: 'http://metamask.helpscoutdocs.com/article/16-managing-erc20-tokens',
+ target: '_blank',
}, this.context.t('learnMore')),
]),
h('div.add-token__input-container', [
@@ -381,12 +382,12 @@ AddTokenScreen.prototype.render = function () {
isShowingConfirmation,
displayedTab,
} = this.state
- const { goHome } = this.props
+ const { history } = this.props
return h('div.add-token', [
h('div.add-token__header', [
h('div.add-token__header__cancel', {
- onClick: () => goHome(),
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
h('i.fa.fa-angle-left.fa-lg'),
h('span', this.context.t('cancel')),
@@ -413,14 +414,14 @@ AddTokenScreen.prototype.render = function () {
]),
]),
-//
+
isShowingConfirmation
? this.renderConfirmation()
: this.renderTabs(),
!isShowingConfirmation && h('div.add-token__buttons', [
h('button.btn-secondary--lg.add-token__cancel-button', {
- onClick: goHome,
+ onClick: () => history.push(DEFAULT_ROUTE),
}, this.context.t('cancel')),
h('button.btn-primary--lg.add-token__confirm-button', {
onClick: this.onNext,
diff --git a/ui/app/components/pages/authenticated.js b/ui/app/components/pages/authenticated.js
new file mode 100644
index 000000000..1f6b0be49
--- /dev/null
+++ b/ui/app/components/pages/authenticated.js
@@ -0,0 +1,34 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const MetamaskRoute = require('./metamask-route')
+const { UNLOCK_ROUTE, INITIALIZE_ROUTE } = require('../../routes')
+
+const Authenticated = props => {
+ const { isUnlocked, isInitialized } = props
+
+ switch (true) {
+ case isUnlocked && isInitialized:
+ return h(MetamaskRoute, { ...props })
+ case !isInitialized:
+ return h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+ default:
+ return h(Redirect, { to: { pathname: UNLOCK_ROUTE } })
+ }
+}
+
+Authenticated.propTypes = {
+ isUnlocked: PropTypes.bool,
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked, isInitialized } } = state
+ return {
+ isUnlocked,
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Authenticated)
diff --git a/ui/app/accounts/import/index.js b/ui/app/components/pages/create-account/import-account/index.js
index 52d3dcde9..52d3dcde9 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/components/pages/create-account/import-account/index.js
diff --git a/ui/app/accounts/import/json.js b/ui/app/components/pages/create-account/import-account/json.js
index e53c1c9ca..0a3314b2a 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/components/pages/create-account/import-account/json.js
@@ -1,11 +1,12 @@
const Component = require('react').Component
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../../actions')
const FileInput = require('react-simple-file-input').default
-
-
+const { DEFAULT_ROUTE } = require('../../../../routes')
const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
class JsonImportSubview extends Component {
@@ -51,7 +52,7 @@ class JsonImportSubview extends Component {
h('div.new-account-create-form__buttons', {}, [
h('button.btn-secondary.new-account-create-form__button', {
- onClick: () => this.props.goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
@@ -104,6 +105,8 @@ class JsonImportSubview extends Component {
}
this.props.importNewJsonAccount([ fileContents, password ])
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
}
}
@@ -112,6 +115,7 @@ JsonImportSubview.propTypes = {
goHome: PropTypes.func,
displayWarning: PropTypes.func,
importNewJsonAccount: PropTypes.func,
+ history: PropTypes.object,
t: PropTypes.func,
}
@@ -133,5 +137,7 @@ JsonImportSubview.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(JsonImportSubview)
-
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(JsonImportSubview)
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/components/pages/create-account/import-account/private-key.js
index 006131bdc..df7ac910a 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/components/pages/create-account/import-account/private-key.js
@@ -1,15 +1,21 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../../actions')
+const { DEFAULT_ROUTE } = require('../../../../routes')
PrivateKeyImportView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(PrivateKeyImportView)
function mapStateToProps (state) {
@@ -20,9 +26,8 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- goHome: () => dispatch(actions.goHome()),
importNewAccount: (strategy, [ privateKey ]) => {
- dispatch(actions.importNewAccount(strategy, [ privateKey ]))
+ return dispatch(actions.importNewAccount(strategy, [ privateKey ]))
},
displayWarning: () => dispatch(actions.displayWarning(null)),
}
@@ -30,11 +35,12 @@ function mapDispatchToProps (dispatch) {
inherits(PrivateKeyImportView, Component)
function PrivateKeyImportView () {
+ this.createKeyringOnEnter = this.createKeyringOnEnter.bind(this)
Component.call(this)
}
PrivateKeyImportView.prototype.render = function () {
- const { error, goHome } = this.props
+ const { error } = this.props
return (
h('div.new-account-import-form__private-key', [
@@ -46,7 +52,7 @@ PrivateKeyImportView.prototype.render = function () {
h('input.new-account-import-form__input-password', {
type: 'password',
id: 'private-key-box',
- onKeyPress: () => this.createKeyringOnEnter(),
+ onKeyPress: e => this.createKeyringOnEnter(e),
}),
]),
@@ -54,7 +60,7 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [
h('button.btn-secondary--lg.new-account-create-form__button', {
- onClick: () => goHome(),
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
@@ -82,6 +88,10 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
+ const { importNewAccount, history } = this.props
- this.props.importNewAccount('Private Key', [ privateKey ])
+ importNewAccount('Private Key', [ privateKey ])
+ // JS runtime requires caught rejections but failures are handled by Redux
+ .catch()
+ .then(() => history.push(DEFAULT_ROUTE))
}
diff --git a/ui/app/accounts/import/seed.js b/ui/app/components/pages/create-account/import-account/seed.js
index d98909baa..d98909baa 100644
--- a/ui/app/accounts/import/seed.js
+++ b/ui/app/components/pages/create-account/import-account/seed.js
diff --git a/ui/app/components/pages/create-account/index.js b/ui/app/components/pages/create-account/index.js
new file mode 100644
index 000000000..0962477d8
--- /dev/null
+++ b/ui/app/components/pages/create-account/index.js
@@ -0,0 +1,81 @@
+const Component = require('react').Component
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../actions')
+const { getCurrentViewContext } = require('../../../selectors')
+const classnames = require('classnames')
+const NewAccountCreateForm = require('./new-account')
+const NewAccountImportForm = require('./import-account')
+const { NEW_ACCOUNT_ROUTE, IMPORT_ACCOUNT_ROUTE } = require('../../../routes')
+
+class CreateAccountPage extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.new-account__tabs', [
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: NEW_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(NEW_ACCOUNT_ROUTE),
+ }, 'Create'),
+
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': matchPath(location.pathname, {
+ path: IMPORT_ACCOUNT_ROUTE, exact: true,
+ }),
+ }),
+ onClick: () => history.push(IMPORT_ACCOUNT_ROUTE),
+ }, 'Import'),
+ ])
+ }
+
+ render () {
+ return h('div.new-account', {}, [
+ h('div.new-account__header', [
+ h('div.new-account__title', 'New Account'),
+ this.renderTabs(),
+ ]),
+ h('div.new-account__form', [
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: NEW_ACCOUNT_ROUTE,
+ component: NewAccountCreateForm,
+ }),
+ h(Route, {
+ exact: true,
+ path: IMPORT_ACCOUNT_ROUTE,
+ component: NewAccountImportForm,
+ }),
+ ]),
+ ]),
+ ])
+ }
+}
+
+CreateAccountPage.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => ({
+ displayedForm: getCurrentViewContext(state),
+})
+
+const mapDispatchToProps = dispatch => ({
+ displayForm: form => dispatch(actions.setNewAccountForm(form)),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
+})
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(CreateAccountPage)
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/components/pages/create-account/new-account.js
index 48c74192a..40fa584be 100644
--- a/ui/app/accounts/new-account/create-form.js
+++ b/ui/app/components/pages/create-account/new-account.js
@@ -2,7 +2,8 @@ const { Component } = require('react')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('../../actions')
+const actions = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
class NewAccountCreateForm extends Component {
constructor (props, context) {
@@ -19,7 +20,7 @@ class NewAccountCreateForm extends Component {
render () {
const { newAccountName, defaultAccountName } = this.state
-
+ const { history, createAccount } = this.props
return h('div.new-account-create-form', [
@@ -38,13 +39,16 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [
h('button.btn-secondary--lg.new-account-create-form__button', {
- onClick: () => this.props.goHome(),
+ onClick: () => history.push(DEFAULT_ROUTE),
}, [
this.context.t('cancel'),
]),
h('button.btn-primary--lg.new-account-create-form__button', {
- onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
+ onClick: () => {
+ createAccount(newAccountName || defaultAccountName)
+ .then(() => history.push(DEFAULT_ROUTE))
+ },
}, [
this.context.t('create'),
]),
@@ -59,8 +63,8 @@ NewAccountCreateForm.propTypes = {
hideModal: PropTypes.func,
showImportPage: PropTypes.func,
createAccount: PropTypes.func,
- goHome: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
+ history: PropTypes.object,
t: PropTypes.func,
}
@@ -77,23 +81,17 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- toCoinbase: (address) => {
- dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
- },
- hideModal: () => {
- dispatch(actions.hideModal())
- },
- createAccount: (newAccountName) => {
- dispatch(actions.addNewAccount())
- .then((newAccountAddress) => {
+ toCoinbase: address => dispatch(actions.buyEth({ network: '1', address, amount: 0 })),
+ hideModal: () => dispatch(actions.hideModal()),
+ createAccount: newAccountName => {
+ return dispatch(actions.addNewAccount())
+ .then(newAccountAddress => {
if (newAccountName) {
dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName))
}
- dispatch(actions.goHome())
})
},
showImportPage: () => dispatch(actions.showImportPage()),
- goHome: () => dispatch(actions.goHome()),
}
}
diff --git a/ui/app/components/pages/home.js b/ui/app/components/pages/home.js
new file mode 100644
index 000000000..9110f8202
--- /dev/null
+++ b/ui/app/components/pages/home.js
@@ -0,0 +1,333 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const connect = require('../../metamask-connect')
+const { Redirect, withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const h = require('react-hyperscript')
+const actions = require('../../actions')
+const log = require('loglevel')
+
+// init
+const NewKeyChainScreen = require('../../new-keychain')
+// mascara
+const MascaraBuyEtherScreen = require('../../../../mascara/src/app/first-time/buy-ether-screen').default
+
+// accounts
+const MainContainer = require('../../main-container')
+
+// other views
+const BuyView = require('../../components/buy-button-subview')
+const QrView = require('../../components/qr-code')
+
+// Routes
+const {
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ NOTICE_ROUTE,
+} = require('../../routes')
+
+class Home extends Component {
+ componentDidMount () {
+ const {
+ history,
+ unapprovedTxs = {},
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ // unapprovedTxs and unapproved messages
+ if (Object.keys(unapprovedTxs).length ||
+ unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount > 0) {
+ history.push(CONFIRM_TRANSACTION_ROUTE)
+ }
+ }
+
+ render () {
+ log.debug('rendering primary')
+ const {
+ noActiveNotices,
+ lostAccounts,
+ forgottenPassword,
+ currentView,
+ activeAddress,
+ seedWords,
+ } = this.props
+
+ // notices
+ if (!noActiveNotices || (lostAccounts && lostAccounts.length > 0)) {
+ return h(Redirect, {
+ to: {
+ pathname: NOTICE_ROUTE,
+ },
+ })
+ }
+
+ // seed words
+ if (seedWords) {
+ log.debug('rendering seed words')
+ return h(Redirect, {
+ to: {
+ pathname: INITIALIZE_BACKUP_PHRASE_ROUTE,
+ },
+ })
+ }
+
+ if (forgottenPassword) {
+ log.debug('rendering restore vault screen')
+ return h(Redirect, {
+ to: {
+ pathname: RESTORE_VAULT_ROUTE,
+ },
+ })
+ }
+
+ // if (!props.noActiveNotices) {
+ // log.debug('rendering notice screen for unread notices.')
+ // return h(NoticeScreen, {
+ // notice: props.lastUnreadNotice,
+ // key: 'NoticeScreen',
+ // onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ // })
+ // } else if (props.lostAccounts && props.lostAccounts.length > 0) {
+ // log.debug('rendering notice screen for lost accounts view.')
+ // return h(NoticeScreen, {
+ // notice: generateLostAccountsNotice(props.lostAccounts),
+ // key: 'LostAccountsNotice',
+ // onConfirm: () => props.dispatch(actions.markAccountsFound()),
+ // })
+ // }
+
+ // if (props.seedWords) {
+ // log.debug('rendering seed words')
+ // return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
+ // }
+
+ // show initialize screen
+ // if (!isInitialized || forgottenPassword) {
+ // // show current view
+ // log.debug('rendering an initialize screen')
+ // // switch (props.currentView.name) {
+
+ // // case 'restoreVault':
+ // // log.debug('rendering restore vault screen')
+ // // return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ // // default:
+ // // log.debug('rendering menu screen')
+ // // return h(InitializeScreen, {key: 'menuScreenInit'})
+ // // }
+ // }
+
+ // // show unlock screen
+ // if (!props.isUnlocked) {
+ // return h(MainContainer, {
+ // currentViewName: props.currentView.name,
+ // isUnlocked: props.isUnlocked,
+ // })
+ // }
+
+ // show current view
+ switch (currentView.name) {
+
+ case 'accountDetail':
+ log.debug('rendering main container')
+ return h(MainContainer, {key: 'account-detail'})
+
+ // case 'sendTransaction':
+ // log.debug('rendering send tx screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTransactionScreen
+
+ // return h(SendTransactionScreen2, {key: 'send-transaction'})
+
+ // case 'sendToken':
+ // log.debug('rendering send token screen')
+
+ // // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
+ // // ? SendTransactionScreen2
+ // // : SendTokenScreen
+
+ // return h(SendTransactionScreen2, {key: 'sendToken'})
+
+ case 'newKeychain':
+ log.debug('rendering new keychain screen')
+ return h(NewKeyChainScreen, {key: 'new-keychain'})
+
+ // case 'confTx':
+ // log.debug('rendering confirm tx screen')
+ // return h(Redirect, {
+ // to: {
+ // pathname: CONFIRM_TRANSACTION_ROUTE,
+ // },
+ // })
+ // return h(ConfirmTxScreen, {key: 'confirm-tx'})
+
+ // case 'add-token':
+ // log.debug('rendering add-token screen from unlock screen.')
+ // return h(AddTokenScreen, {key: 'add-token'})
+
+ // case 'config':
+ // log.debug('rendering config screen')
+ // return h(Settings, {key: 'config'})
+
+ // case 'import-menu':
+ // log.debug('rendering import screen')
+ // return h(Import, {key: 'import-menu'})
+
+ // case 'reveal-seed-conf':
+ // log.debug('rendering reveal seed confirmation screen')
+ // return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
+
+ // case 'info':
+ // log.debug('rendering info screen')
+ // return h(Settings, {key: 'info', tab: 'info'})
+
+ case 'buyEth':
+ log.debug('rendering buy ether screen')
+ return h(BuyView, {key: 'buyEthView'})
+
+ case 'onboardingBuyEth':
+ log.debug('rendering onboarding buy ether screen')
+ return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+
+ case 'qr':
+ log.debug('rendering show qr screen')
+ return h('div', {
+ style: {
+ position: 'absolute',
+ height: '100%',
+ top: '0px',
+ left: '0px',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: () => this.props.dispatch(actions.backToAccountDetail(activeAddress)),
+ style: {
+ marginLeft: '10px',
+ marginTop: '50px',
+ },
+ }),
+ h('div', {
+ style: {
+ position: 'absolute',
+ left: '44px',
+ width: '285px',
+ },
+ }, [
+ h(QrView, {key: 'qr'}),
+ ]),
+ ])
+
+ default:
+ log.debug('rendering default, account detail screen')
+ return h(MainContainer, {key: 'account-detail'})
+ }
+ }
+}
+
+Home.propTypes = {
+ currentCurrency: PropTypes.string,
+ isLoading: PropTypes.bool,
+ loadingMessage: PropTypes.string,
+ network: PropTypes.string,
+ provider: PropTypes.object,
+ frequentRpcList: PropTypes.array,
+ currentView: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ isMascara: PropTypes.bool,
+ isOnboarding: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ networkDropdownOpen: PropTypes.bool,
+ history: PropTypes.object,
+ dispatch: PropTypes.func,
+ selectedAddress: PropTypes.string,
+ noActiveNotices: PropTypes.bool,
+ lostAccounts: PropTypes.array,
+ isInitialized: PropTypes.bool,
+ forgottenPassword: PropTypes.bool,
+ activeAddress: PropTypes.string,
+ unapprovedTxs: PropTypes.object,
+ seedWords: PropTypes.string,
+ unapprovedMsgCount: PropTypes.number,
+ unapprovedPersonalMsgCount: PropTypes.number,
+ unapprovedTypedMessagesCount: PropTypes.number,
+ welcomeScreenSeen: PropTypes.bool,
+ isPopup: PropTypes.bool,
+ isMouseUser: PropTypes.bool,
+ t: PropTypes.func,
+}
+
+function mapStateToProps (state) {
+ const { appState, metamask } = state
+ const {
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ } = appState
+
+ const {
+ accounts,
+ address,
+ isInitialized,
+ noActiveNotices,
+ seedWords,
+ unapprovedTxs,
+ lastUnreadNotice,
+ lostAccounts,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+ const selected = address || Object.keys(accounts)[0]
+
+ return {
+ // state from plugin
+ networkDropdownOpen,
+ sidebarOpen,
+ isLoading,
+ loadingMessage,
+ noActiveNotices,
+ isInitialized,
+ isUnlocked: state.metamask.isUnlocked,
+ selectedAddress: state.metamask.selectedAddress,
+ currentView: state.appState.currentView,
+ activeAddress: state.appState.activeAddress,
+ transForward: state.appState.transForward,
+ isMascara: state.metamask.isMascara,
+ isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ isPopup: state.metamask.isPopup,
+ seedWords: state.metamask.seedWords,
+ unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ menuOpen: state.appState.menuOpen,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice,
+ lostAccounts,
+ frequentRpcList: state.metamask.frequentRpcList || [],
+ currentCurrency: state.metamask.currentCurrency,
+ isMouseUser: state.appState.isMouseUser,
+ isRevealingSeedWords: state.metamask.isRevealingSeedWords,
+ Qr: state.appState.Qr,
+ welcomeScreenSeen: state.metamask.welcomeScreenSeen,
+
+ // state needed to get account dropdown temporarily rendering from app bar
+ selected,
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(Home)
diff --git a/ui/app/components/pages/initialized.js b/ui/app/components/pages/initialized.js
new file mode 100644
index 000000000..3adf67b28
--- /dev/null
+++ b/ui/app/components/pages/initialized.js
@@ -0,0 +1,25 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Redirect } = require('react-router-dom')
+const h = require('react-hyperscript')
+const { INITIALIZE_ROUTE } = require('../../routes')
+const MetamaskRoute = require('./metamask-route')
+
+const Initialized = props => {
+ return props.isInitialized
+ ? h(MetamaskRoute, { ...props })
+ : h(Redirect, { to: { pathname: INITIALIZE_ROUTE } })
+}
+
+Initialized.propTypes = {
+ isInitialized: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isInitialized } } = state
+ return {
+ isInitialized,
+ }
+}
+
+module.exports = connect(mapStateToProps)(Initialized)
diff --git a/ui/app/components/pages/keychains/restore-vault.js b/ui/app/components/pages/keychains/restore-vault.js
new file mode 100644
index 000000000..33575bfbb
--- /dev/null
+++ b/ui/app/components/pages/keychains/restore-vault.js
@@ -0,0 +1,178 @@
+const { withRouter } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const { compose } = require('recompose')
+const PersistentForm = require('../../../../lib/persistent-form')
+const connect = require('../../../metamask-connect')
+const h = require('react-hyperscript')
+const { createNewVaultAndRestore, unMarkPasswordForgotten } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+const log = require('loglevel')
+
+class RestoreVaultPage extends PersistentForm {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+ }
+
+ createOnEnter (event) {
+ if (event.key === 'Enter') {
+ this.createNewVaultAndRestore()
+ }
+ }
+
+ cancel () {
+ this.props.unMarkPasswordForgotten()
+ .then(this.props.history.push(DEFAULT_ROUTE))
+ }
+
+ createNewVaultAndRestore () {
+ this.setState({ error: null })
+
+ // check password
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ if (password.length < 8) {
+ this.setState({ error: 'Password not long enough' })
+ return
+ }
+
+ if (password !== passwordConfirm) {
+ this.setState({ error: 'Passwords don\'t match' })
+ return
+ }
+
+ // check seed
+ var seedBox = document.querySelector('textarea.twelve-word-phrase')
+ var seed = seedBox.value.trim()
+ if (seed.split(' ').length !== 12) {
+ this.setState({ error: 'Seed phrases are 12 words long' })
+ return
+ }
+
+ // submit
+ this.props.createNewVaultAndRestore(password, seed)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => {
+ this.setState({ error: message })
+ log.error(message)
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ this.persistentFormParentId = 'restore-vault-form'
+
+ return (
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ this.props.t('restoreVault'),
+ ]),
+
+ // wallet seed entry
+ h('h3', 'Wallet Seed'),
+ h('textarea.twelve-word-phrase.letter-spacey', {
+ dataset: {
+ persistentFormId: 'wallet-seed',
+ },
+ placeholder: this.props.t('secretPhrase'),
+ }),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: this.props.t('newPassword8Chars'),
+ dataset: {
+ persistentFormId: 'password',
+ },
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: this.props.t('confirmPassword'),
+ onKeyPress: this.createOnEnter.bind(this),
+ dataset: {
+ persistentFormId: 'password-confirmation',
+ },
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
+
+ error && (
+ h('span.error.in-progress-notification', error)
+ ),
+
+ // submit
+ h('.flex-row.flex-space-between', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+
+ // cancel
+ h('button.primary', {
+ onClick: () => this.cancel(),
+ }, this.props.t('cancel')),
+
+ // submit
+ h('button.primary', {
+ onClick: this.createNewVaultAndRestore.bind(this),
+ }, this.props.t('ok')),
+
+ ]),
+ ])
+ )
+ }
+}
+
+RestoreVaultPage.propTypes = {
+ history: PropTypes.object,
+}
+
+const mapStateToProps = state => {
+ const { appState: { warning, forgottenPassword } } = state
+
+ return {
+ warning,
+ forgottenPassword,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndRestore: (password, seed) => {
+ return dispatch(createNewVaultAndRestore(password, seed))
+ },
+ unMarkPasswordForgotten: () => dispatch(unMarkPasswordForgotten()),
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(RestoreVaultPage)
diff --git a/ui/app/components/pages/keychains/reveal-seed.js b/ui/app/components/pages/keychains/reveal-seed.js
new file mode 100644
index 000000000..685c81074
--- /dev/null
+++ b/ui/app/components/pages/keychains/reveal-seed.js
@@ -0,0 +1,164 @@
+const { Component } = require('react')
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const classnames = require('classnames')
+
+const { requestRevealSeedWords } = require('../../../actions')
+const { DEFAULT_ROUTE } = require('../../../routes')
+const ExportTextContainer = require('../../export-text-container')
+
+const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN'
+const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN'
+
+class RevealSeedPage extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ screen: PASSWORD_PROMPT_SCREEN,
+ password: '',
+ seedWords: null,
+ error: null,
+ }
+ }
+
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ handleSubmit (event) {
+ event.preventDefault()
+ this.setState({ seedWords: null, error: null })
+ this.props.requestRevealSeedWords(this.state.password)
+ .then(seedWords => this.setState({ seedWords, screen: REVEAL_SEED_SCREEN }))
+ .catch(error => this.setState({ error: error.message }))
+ }
+
+ renderWarning () {
+ return (
+ h('.page-container__warning-container', [
+ h('img.page-container__warning-icon', {
+ src: 'images/warning.svg',
+ }),
+ h('.page-container__warning-message', [
+ h('.page-container__warning-title', [this.context.t('revealSeedWordsWarningTitle')]),
+ h('div', [this.context.t('revealSeedWordsWarning')]),
+ ]),
+ ])
+ )
+ }
+
+ renderContent () {
+ return this.state.screen === PASSWORD_PROMPT_SCREEN
+ ? this.renderPasswordPromptContent()
+ : this.renderRevealSeedContent()
+ }
+
+ renderPasswordPromptContent () {
+ const { t } = this.context
+
+ return (
+ h('form', {
+ onSubmit: event => this.handleSubmit(event),
+ }, [
+ h('label.input-label', {
+ htmlFor: 'password-box',
+ }, t('enterPasswordContinue')),
+ h('.input-group', [
+ h('input.form-control', {
+ type: 'password',
+ placeholder: t('password'),
+ id: 'password-box',
+ value: this.state.password,
+ onChange: event => this.setState({ password: event.target.value }),
+ className: classnames({ 'form-control--error': this.state.error }),
+ }),
+ ]),
+ this.state.error && h('.reveal-seed__error', this.state.error),
+ ])
+ )
+ }
+
+ renderRevealSeedContent () {
+ const { t } = this.context
+
+ return (
+ h('div', [
+ h('label.reveal-seed__label', t('yourPrivateSeedPhrase')),
+ h(ExportTextContainer, {
+ text: this.state.seedWords,
+ filename: t('metamaskSeedWords'),
+ }),
+ ])
+ )
+ }
+
+ renderFooter () {
+ return this.state.screen === PASSWORD_PROMPT_SCREEN
+ ? this.renderPasswordPromptFooter()
+ : this.renderRevealSeedFooter()
+ }
+
+ renderPasswordPromptFooter () {
+ return (
+ h('.page-container__footer', [
+ h('button.btn-secondary--lg.page-container__footer-button', {
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
+ }, this.context.t('cancel')),
+ h('button.btn-primary--lg.page-container__footer-button', {
+ onClick: event => this.handleSubmit(event),
+ disabled: this.state.password === '',
+ }, this.context.t('next')),
+ ])
+ )
+ }
+
+ renderRevealSeedFooter () {
+ return (
+ h('.page-container__footer', [
+ h('button.btn-secondary--lg.page-container__footer-button', {
+ onClick: () => this.props.history.push(DEFAULT_ROUTE),
+ }, this.context.t('close')),
+ ])
+ )
+ }
+
+ render () {
+ return (
+ h('.page-container', [
+ h('.page-container__header', [
+ h('.page-container__title', this.context.t('revealSeedWordsTitle')),
+ h('.page-container__subtitle', this.context.t('revealSeedWordsDescription')),
+ ]),
+ h('.page-container__content', [
+ this.renderWarning(),
+ h('.reveal-seed__content', [
+ this.renderContent(),
+ ]),
+ ]),
+ this.renderFooter(),
+ ])
+ )
+ }
+}
+
+RevealSeedPage.propTypes = {
+ requestRevealSeedWords: PropTypes.func,
+ history: PropTypes.object,
+}
+
+RevealSeedPage.contextTypes = {
+ t: PropTypes.func,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ requestRevealSeedWords: password => dispatch(requestRevealSeedWords(password)),
+ }
+}
+
+module.exports = connect(null, mapDispatchToProps)(RevealSeedPage)
diff --git a/ui/app/components/pages/metamask-route.js b/ui/app/components/pages/metamask-route.js
new file mode 100644
index 000000000..23c5b5199
--- /dev/null
+++ b/ui/app/components/pages/metamask-route.js
@@ -0,0 +1,28 @@
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const { Route } = require('react-router-dom')
+const h = require('react-hyperscript')
+
+const MetamaskRoute = ({ component, mascaraComponent, isMascara, ...props }) => {
+ return (
+ h(Route, {
+ ...props,
+ component: isMascara && mascaraComponent ? mascaraComponent : component,
+ })
+ )
+}
+
+MetamaskRoute.propTypes = {
+ component: PropTypes.func,
+ mascaraComponent: PropTypes.func,
+ isMascara: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isMascara } } = state
+ return {
+ isMascara,
+ }
+}
+
+module.exports = connect(mapStateToProps)(MetamaskRoute)
diff --git a/ui/app/components/pages/notice.js b/ui/app/components/pages/notice.js
new file mode 100644
index 000000000..2329a9147
--- /dev/null
+++ b/ui/app/components/pages/notice.js
@@ -0,0 +1,203 @@
+const { Component } = require('react')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const PropTypes = require('prop-types')
+const ReactMarkdown = require('react-markdown')
+const linker = require('extension-link-enabler')
+const generateLostAccountsNotice = require('../../../lib/lost-accounts-notice')
+const findDOMNode = require('react-dom').findDOMNode
+const actions = require('../../actions')
+const { DEFAULT_ROUTE } = require('../../routes')
+
+class Notice extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ disclaimerDisabled: true,
+ }
+ }
+
+ componentWillMount () {
+ if (!this.props.notice) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentDidMount () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+ if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
+ this.setState({ disclaimerDisabled: false })
+ }
+ }
+
+ componentWillReceiveProps (nextProps) {
+ if (!nextProps.notice) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentWillUnmount () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+ }
+
+ handleAccept () {
+ this.setState({ disclaimerDisabled: true })
+ this.props.onConfirm()
+ }
+
+ render () {
+ const { notice = {} } = this.props
+ const { title, date, body } = notice
+ const { disclaimerDisabled } = this.state
+
+ return (
+ h('.flex-column.flex-center.flex-grow', {
+ style: {
+ width: '100%',
+ },
+ }, [
+ h('h3.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ title,
+ ]),
+
+ h('h5.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ date,
+ ]),
+
+ h('style', `
+
+ .markdown {
+ overflow-x: hidden;
+ }
+
+ .markdown h1, .markdown h2, .markdown h3 {
+ margin: 10px 0;
+ font-weight: bold;
+ }
+
+ .markdown strong {
+ font-weight: bold;
+ }
+ .markdown em {
+ font-style: italic;
+ }
+
+ .markdown p {
+ margin: 10px 0;
+ }
+
+ .markdown a {
+ color: #df6b0e;
+ }
+
+ `),
+
+ h('div.markdown', {
+ onScroll: (e) => {
+ var object = e.currentTarget
+ if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
+ this.setState({ disclaimerDisabled: false })
+ }
+ },
+ style: {
+ background: 'rgb(235, 235, 235)',
+ height: '310px',
+ padding: '6px',
+ width: '90%',
+ overflowY: 'scroll',
+ scroll: 'auto',
+ },
+ }, [
+ h(ReactMarkdown, {
+ className: 'notice-box',
+ source: body,
+ skipHtml: true,
+ }),
+ ]),
+
+ h('button.primary', {
+ disabled: disclaimerDisabled,
+ onClick: () => this.handleAccept(),
+ style: {
+ marginTop: '18px',
+ },
+ }, 'Accept'),
+ ])
+ )
+ }
+
+}
+
+const mapStateToProps = state => {
+ const { metamask } = state
+ const { noActiveNotices, lastUnreadNotice, lostAccounts } = metamask
+
+ return {
+ noActiveNotices,
+ lastUnreadNotice,
+ lostAccounts,
+ }
+}
+
+Notice.propTypes = {
+ notice: PropTypes.object,
+ onConfirm: PropTypes.func,
+ history: PropTypes.object,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ markNoticeRead: lastUnreadNotice => dispatch(actions.markNoticeRead(lastUnreadNotice)),
+ markAccountsFound: () => dispatch(actions.markAccountsFound()),
+ }
+}
+
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const { noActiveNotices, lastUnreadNotice, lostAccounts } = stateProps
+ const { markNoticeRead, markAccountsFound } = dispatchProps
+
+ let notice
+ let onConfirm
+
+ if (!noActiveNotices) {
+ notice = lastUnreadNotice
+ onConfirm = () => markNoticeRead(lastUnreadNotice)
+ } else if (lostAccounts && lostAccounts.length > 0) {
+ notice = generateLostAccountsNotice(lostAccounts)
+ onConfirm = () => markAccountsFound()
+ }
+
+ return {
+ ...stateProps,
+ ...dispatchProps,
+ ...ownProps,
+ notice,
+ onConfirm,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notice)
diff --git a/ui/app/components/pages/settings/index.js b/ui/app/components/pages/settings/index.js
new file mode 100644
index 000000000..384ae4b41
--- /dev/null
+++ b/ui/app/components/pages/settings/index.js
@@ -0,0 +1,59 @@
+const { Component } = require('react')
+const { Switch, Route, matchPath } = require('react-router-dom')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const TabBar = require('../../tab-bar')
+const Settings = require('./settings')
+const Info = require('./info')
+const { DEFAULT_ROUTE, SETTINGS_ROUTE, INFO_ROUTE } = require('../../../routes')
+
+class Config extends Component {
+ renderTabs () {
+ const { history, location } = this.props
+
+ return h('div.settings__tabs', [
+ h(TabBar, {
+ tabs: [
+ { content: 'Settings', key: SETTINGS_ROUTE },
+ { content: 'Info', key: INFO_ROUTE },
+ ],
+ isActive: key => matchPath(location.pathname, { path: key, exact: true }),
+ onSelect: key => history.push(key),
+ }),
+ ])
+ }
+
+ render () {
+ const { history } = this.props
+
+ return (
+ h('.main-container.settings', {}, [
+ h('.settings__header', [
+ h('div.settings__close-button', {
+ onClick: () => history.push(DEFAULT_ROUTE),
+ }),
+ this.renderTabs(),
+ ]),
+ h(Switch, [
+ h(Route, {
+ exact: true,
+ path: INFO_ROUTE,
+ component: Info,
+ }),
+ h(Route, {
+ exact: true,
+ path: SETTINGS_ROUTE,
+ component: Settings,
+ }),
+ ]),
+ ])
+ )
+ }
+}
+
+Config.propTypes = {
+ location: PropTypes.object,
+ history: PropTypes.object,
+}
+
+module.exports = Config
diff --git a/ui/app/components/pages/settings/info.js b/ui/app/components/pages/settings/info.js
new file mode 100644
index 000000000..bd9040499
--- /dev/null
+++ b/ui/app/components/pages/settings/info.js
@@ -0,0 +1,120 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+
+class Info extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ version: global.platform.getVersion(),
+ }
+ }
+
+ renderLogo () {
+ return (
+ h('div.settings__info-logo-wrapper', [
+ h('img.settings__info-logo', { src: 'images/info-logo.png' }),
+ ])
+ )
+ }
+
+ renderInfoLinks () {
+ return (
+ h('div.settings__content-item.settings__content-item--without-height', [
+ h('div.settings__info-link-header', this.context.t('links')),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('privacyMsg')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('terms')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('attributions')),
+ ]),
+ ]),
+ h('hr.settings__info-separator'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('supportCenter')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', this.context.t('visitWebSite')),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ target: '_blank',
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, [
+ h('span.settings__info-link', this.context.t('emailUs')),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ return (
+ h('div.settings__content', [
+ h('div.settings__content-row', [
+ h('div.settings__content-item.settings__content-item--without-height', [
+ this.renderLogo(),
+ h('div.settings__info-item', [
+ h('div.settings__info-version-header', 'MetaMask Version'),
+ h('div.settings__info-version-number', this.state.version),
+ ]),
+ h('div.settings__info-item', [
+ h(
+ 'div.settings__info-about',
+ this.context.t('builtInCalifornia')
+ ),
+ ]),
+ ]),
+ this.renderInfoLinks(),
+ ]),
+ ])
+ )
+ }
+}
+
+Info.propTypes = {
+ tab: PropTypes.string,
+ metamask: PropTypes.object,
+ setCurrentCurrency: PropTypes.func,
+ setRpcTarget: PropTypes.func,
+ displayWarning: PropTypes.func,
+ revealSeedConfirmation: PropTypes.func,
+ warning: PropTypes.string,
+ location: PropTypes.object,
+ history: PropTypes.object,
+ t: PropTypes.func,
+}
+
+Info.contextTypes = {
+ t: PropTypes.func,
+}
+
+module.exports = Info
diff --git a/ui/app/settings.js b/ui/app/components/pages/settings/settings.js
index 3aa7b9c6b..bdefe56f8 100644
--- a/ui/app/settings.js
+++ b/ui/app/components/pages/settings/settings.js
@@ -1,16 +1,18 @@
const { Component } = require('react')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('./actions')
-const infuraCurrencies = require('./infura-conversion.json')
+const actions = require('../../../actions')
+const infuraCurrencies = require('../../../infura-conversion.json')
const validUrl = require('valid-url')
-const { exportAsFile } = require('./util')
-const TabBar = require('./components/tab-bar')
-const SimpleDropdown = require('./components/dropdowns/simple-dropdown')
+const { exportAsFile } = require('../../../util')
+const SimpleDropdown = require('../../dropdowns/simple-dropdown')
const ToggleButton = require('react-toggle-button')
-const locales = require('../../app/_locales/index.json')
-const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const { REVEAL_SEED_ROUTE } = require('../../../routes')
+const locales = require('../../../../../app/_locales/index.json')
+const { OLD_UI_NETWORK_TYPE } = require('../../../../../app/scripts/controllers/network/enums')
const getInfuraCurrencyOptions = () => {
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
@@ -40,30 +42,11 @@ class Settings extends Component {
constructor (props) {
super(props)
- const { tab } = props
- const activeTab = tab === 'info' ? 'info' : 'settings'
-
this.state = {
- activeTab,
newRpc: '',
}
}
- renderTabs () {
- const { activeTab } = this.state
-
- return h('div.settings__tabs', [
- h(TabBar, {
- tabs: [
- { content: this.context.t('settings'), key: 'settings' },
- { content: this.context.t('info'), key: 'info' },
- ],
- defaultTab: activeTab,
- tabSelected: key => this.setState({ activeTab: key }),
- }),
- ])
- }
-
renderBlockieOptIn () {
const { metamask: { useBlockie }, setUseBlockie } = this.props
@@ -253,7 +236,7 @@ class Settings extends Component {
}
renderSeedWords () {
- const { revealSeedConfirmation } = this.props
+ const { history } = this.props
return (
h('div.settings__content-row', [
@@ -261,9 +244,9 @@ class Settings extends Component {
h('div.settings__content-item', [
h('div.settings__content-item-col', [
h('button.btn-primary--lg.settings__button--red', {
- onClick (event) {
+ onClick: event => {
event.preventDefault()
- revealSeedConfirmation()
+ history.push(REVEAL_SEED_ROUTE)
},
}, this.context.t('revealSeedWords')),
]),
@@ -310,7 +293,7 @@ class Settings extends Component {
])
}
- renderSettingsContent () {
+ render () {
const { warning, isMascara } = this.props
return (
@@ -328,120 +311,9 @@ class Settings extends Component {
])
)
}
-
- renderLogo () {
- return (
- h('div.settings__info-logo-wrapper', [
- h('img.settings__info-logo', { src: 'images/info-logo.png' }),
- ])
- )
- }
-
- renderInfoLinks () {
- return (
- h('div.settings__content-item.settings__content-item--without-height', [
- h('div.settings__info-link-header', this.context.t('links')),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('privacyMsg')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('terms')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('attributions')),
- ]),
- ]),
- h('hr.settings__info-separator'),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://support.metamask.io',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('supportCenter')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('span.settings__info-link', this.context.t('visitWebSite')),
- ]),
- ]),
- h('div.settings__info-link-item', [
- h('a', {
- target: '_blank',
- href: 'mailto:help@metamask.io?subject=Feedback',
- }, [
- h('span.settings__info-link', this.context.t('emailUs')),
- ]),
- ]),
- ])
- )
- }
-
- renderInfoContent () {
- const version = global.platform.getVersion()
-
- return (
- h('div.settings__content', [
- h('div.settings__content-row', [
- h('div.settings__content-item.settings__content-item--without-height', [
- this.renderLogo(),
- h('div.settings__info-item', [
- h('div.settings__info-version-header', 'MetaMask Version'),
- h('div.settings__info-version-number', `${version}`),
- ]),
- h('div.settings__info-item', [
- h(
- 'div.settings__info-about',
- this.context.t('builtInCalifornia')
- ),
- ]),
- ]),
- this.renderInfoLinks(),
- ]),
- ])
- )
- }
-
- render () {
- const { goHome } = this.props
- const { activeTab } = this.state
-
- return (
- h('.main-container.settings', {}, [
- h('.settings__header', [
- h('div.settings__close-button', {
- onClick: goHome,
- }),
- this.renderTabs(),
- ]),
-
- activeTab === 'settings'
- ? this.renderSettingsContent()
- : this.renderInfoContent(),
- ])
- )
- }
}
Settings.propTypes = {
- tab: PropTypes.string,
metamask: PropTypes.object,
setUseBlockie: PropTypes.func,
setCurrentCurrency: PropTypes.func,
@@ -451,7 +323,7 @@ Settings.propTypes = {
setFeatureFlagToBeta: PropTypes.func,
showResetAccountConfirmationModal: PropTypes.func,
warning: PropTypes.string,
- goHome: PropTypes.func,
+ history: PropTypes.object,
isMascara: PropTypes.bool,
updateCurrentLocale: PropTypes.func,
currentLocale: PropTypes.string,
@@ -469,7 +341,6 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => {
return {
- goHome: () => dispatch(actions.goHome()),
setCurrentCurrency: currency => dispatch(actions.setCurrentCurrency(currency)),
setRpcTarget: newRpc => dispatch(actions.setRpcTarget(newRpc)),
displayWarning: warning => dispatch(actions.displayWarning(warning)),
@@ -490,5 +361,7 @@ Settings.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings)
-
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(Settings)
diff --git a/ui/app/components/pages/unlock.js b/ui/app/components/pages/unlock.js
new file mode 100644
index 000000000..30144b978
--- /dev/null
+++ b/ui/app/components/pages/unlock.js
@@ -0,0 +1,194 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const connect = require('../../metamask-connect')
+const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const {
+ tryUnlockMetamask,
+ forgotPassword,
+ markPasswordForgotten,
+ setNetworkEndpoints,
+ setFeatureFlag,
+} = require('../../actions')
+const { ENVIRONMENT_TYPE_POPUP } = require('../../../../app/scripts/lib/enums')
+const { getEnvironmentType } = require('../../../../app/scripts/lib/util')
+const getCaretCoordinates = require('textarea-caret')
+const EventEmitter = require('events').EventEmitter
+const Mascot = require('../mascot')
+const { OLD_UI_NETWORK_TYPE } = require('../../../../app/scripts/controllers/network/enums')
+const { DEFAULT_ROUTE, RESTORE_VAULT_ROUTE } = require('../../routes')
+
+class UnlockScreen extends Component {
+ constructor (props) {
+ super(props)
+
+ this.state = {
+ error: null,
+ }
+
+ this.animationEventEmitter = new EventEmitter()
+ }
+
+ componentWillMount () {
+ const { isUnlocked, history } = this.props
+
+ if (isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
+ }
+
+ componentDidMount () {
+ const passwordBox = document.getElementById('password-box')
+
+ if (passwordBox) {
+ passwordBox.focus()
+ }
+ }
+
+ tryUnlockMetamask (password) {
+ const { tryUnlockMetamask, history } = this.props
+ tryUnlockMetamask(password)
+ .then(() => history.push(DEFAULT_ROUTE))
+ .catch(({ message }) => this.setState({ error: message }))
+ }
+
+ onSubmit (event) {
+ const input = document.getElementById('password-box')
+ const password = input.value
+ this.tryUnlockMetamask(password)
+ }
+
+ onKeyPress (event) {
+ if (event.key === 'Enter') {
+ this.submitPassword(event)
+ }
+ }
+
+ submitPassword (event) {
+ var element = event.target
+ var password = element.value
+ // reset input
+ element.value = ''
+ this.tryUnlockMetamask(password)
+ }
+
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
+
+ render () {
+ const { error } = this.state
+ return (
+ h('.unlock-screen', [
+
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
+
+ h('h1', {
+ style: {
+ fontSize: '1.4em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ },
+ }, this.props.t('appName')),
+
+ h('input.large-input', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'enter password',
+ style: {
+ background: 'white',
+ },
+ onKeyPress: this.onKeyPress.bind(this),
+ onInput: this.inputChanged.bind(this),
+ }),
+
+ h('.error', {
+ style: {
+ display: error ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, error),
+
+ h('button.primary.cursor-pointer', {
+ onClick: this.onSubmit.bind(this),
+ style: {
+ margin: 10,
+ },
+ }, this.props.t('login')),
+
+ h('p.pointer', {
+ onClick: () => {
+ this.props.markPasswordForgotten()
+ this.props.history.push(RESTORE_VAULT_ROUTE)
+
+ if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
+ global.platform.openExtensionInBrowser()
+ }
+ },
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, this.props.t('restoreFromSeed')),
+
+ h('p.pointer', {
+ onClick: () => {
+ this.props.useOldInterface()
+ .then(() => this.props.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))
+ },
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, this.props.t('classicInterface')),
+ ])
+ )
+ }
+}
+
+UnlockScreen.propTypes = {
+ forgotPassword: PropTypes.func,
+ tryUnlockMetamask: PropTypes.func,
+ markPasswordForgotten: PropTypes.func,
+ history: PropTypes.object,
+ isUnlocked: PropTypes.bool,
+ t: PropTypes.func,
+ useOldInterface: PropTypes.func,
+ setNetworkEndpoints: PropTypes.func,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { isUnlocked } } = state
+ return {
+ isUnlocked,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ forgotPassword: () => dispatch(forgotPassword()),
+ tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)),
+ markPasswordForgotten: () => dispatch(markPasswordForgotten()),
+ useOldInterface: () => dispatch(setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')),
+ setNetworkEndpoints: type => dispatch(setNetworkEndpoints(type)),
+ }
+}
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(UnlockScreen)
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index d007e6661..16dbd273b 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -1,4 +1,6 @@
const Component = require('react').Component
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -21,14 +23,20 @@ const {
const GasFeeDisplay = require('../send/gas-fee-display-v2')
const SenderToRecipient = require('../sender-to-recipient')
const NetworkDisplay = require('../network-display')
+const currencyFormatter = require('currency-formatter')
+const currencies = require('currency-formatter/currencies')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
ConfirmSendEther.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendEther)
function mapStateToProps (state) {
@@ -72,7 +80,6 @@ function mapDispatchToProps (dispatch) {
errors: { to: null, amount: null },
editingTransactionId: id,
}))
- dispatch(actions.showSendPage())
},
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
showCustomizeGasModal: (txMeta, sendGasLimit, sendGasPrice, sendGasTotal) => {
@@ -237,6 +244,7 @@ ConfirmSendEther.prototype.getData = function () {
const { identities } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
+ const account = identities ? identities[txParams.from] || {} : {}
const { FIAT: gasFeeInFIAT, ETH: gasFeeInETH, gasFeeInHex } = this.getGasFee()
const { FIAT: amountInFIAT, ETH: amountInETH } = this.getAmount()
@@ -252,7 +260,7 @@ ConfirmSendEther.prototype.getData = function () {
return {
from: {
address: txParams.from,
- name: identities[txParams.from].name,
+ name: account.name,
},
to: {
address: txParams.to,
@@ -269,9 +277,24 @@ ConfirmSendEther.prototype.getData = function () {
}
}
+ConfirmSendEther.prototype.convertToRenderableCurrency = function (value, currencyCode) {
+ const upperCaseCurrencyCode = currencyCode.toUpperCase()
+
+ return currencies.find(currency => currency.code === upperCaseCurrencyCode)
+ ? currencyFormatter.format(Number(value), {
+ code: upperCaseCurrencyCode,
+ })
+ : value
+}
+
+ConfirmSendEther.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendEther.prototype.render = function () {
const {
- editTransaction,
currentCurrency,
clearSend,
conversionRate,
@@ -308,6 +331,9 @@ ConfirmSendEther.prototype.render = function () {
? 'Increase your gas fee to attempt to overwrite and speed up your transaction'
: 'Please review your transaction.'
+ const convertedAmountInFiat = this.convertToRenderableCurrency(amountInFIAT, currentCurrency)
+ const convertedTotalInFiat = this.convertToRenderableCurrency(totalInFIAT, currentCurrency)
+
// This is from the latest master
// It handles some of the errors that we are not currently handling
// Leaving as comments fo reference
@@ -327,7 +353,7 @@ ConfirmSendEther.prototype.render = function () {
h('.page-container__header', [
h('.page-container__header-row', [
h('span.page-container__back-button', {
- onClick: () => editTransaction(txMeta),
+ onClick: () => this.editTransaction(txMeta),
style: {
visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden',
},
@@ -354,7 +380,7 @@ ConfirmSendEther.prototype.render = function () {
// `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
// ]),
- h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]),
+ h('h3.flex-center.confirm-screen-send-amount', [`${convertedAmountInFiat}`]),
h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]),
h('div.flex-center.confirm-memo-wrapper', [
h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
@@ -401,7 +427,7 @@ ConfirmSendEther.prototype.render = function () {
]),
h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`),
+ h('div.confirm-screen-row-info', `${convertedTotalInFiat} ${currentCurrency.toUpperCase()}`),
h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
]),
@@ -505,7 +531,9 @@ ConfirmSendEther.prototype.render = function () {
}, this.context.t('cancel')),
// Accept Button
- h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]),
+ h('button.btn-confirm.page-container__footer-button.allcaps', {
+ onClick: event => this.onSubmit(event),
+ }, this.context.t('confirm')),
]),
]),
])
@@ -543,6 +571,7 @@ ConfirmSendEther.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendEther.prototype.isBalanceSufficient = function (txMeta) {
@@ -630,4 +659,4 @@ ConfirmSendEther.prototype.bnMultiplyByFraction = function (targetBN, numerator,
const numBN = new BN(numerator)
const denomBN = new BN(denominator)
return targetBN.mul(numBN).div(denomBN)
-} \ No newline at end of file
+}
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 19e591fd6..656093b3d 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -1,4 +1,6 @@
const Component = require('react').Component
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -25,6 +27,8 @@ const {
calcTokenAmount,
} = require('../../token-util')
const classnames = require('classnames')
+const currencyFormatter = require('currency-formatter')
+const currencies = require('currency-formatter/currencies')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
@@ -33,16 +37,20 @@ const {
getSelectedAddress,
getSelectedTokenContract,
} = require('../../selectors')
+const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
ConfirmSendToken.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(ConfirmSendToken)
function mapStateToProps (state, ownProps) {
- const { token: { symbol }, txData } = ownProps
+ const { token: { address }, txData } = ownProps
const { txParams } = txData || {}
const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
@@ -53,7 +61,7 @@ function mapStateToProps (state, ownProps) {
} = state.metamask
const accounts = state.metamask.accounts
const selectedAddress = getSelectedAddress(state)
- const tokenExchangeRate = getTokenExchangeRate(state, symbol)
+ const tokenExchangeRate = getTokenExchangeRate(state, address)
const { balance } = accounts[selectedAddress]
return {
conversionRate,
@@ -69,12 +77,9 @@ function mapStateToProps (state, ownProps) {
}
function mapDispatchToProps (dispatch, ownProps) {
- const { token: { symbol } } = ownProps
-
return {
backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
- updateTokenExchangeRate: () => dispatch(actions.updateTokenExchangeRate(symbol)),
editTransaction: txMeta => {
const { token: { address } } = ownProps
const { txParams = {}, id } = txMeta
@@ -147,6 +152,12 @@ function ConfirmSendToken () {
this.onSubmit = this.onSubmit.bind(this)
}
+ConfirmSendToken.prototype.editTransaction = function (txMeta) {
+ const { editTransaction, history } = this.props
+ editTransaction(txMeta)
+ history.push(SEND_ROUTE)
+}
+
ConfirmSendToken.prototype.updateComponentSendErrors = function (prevProps) {
const {
balance: oldBalance,
@@ -191,7 +202,6 @@ ConfirmSendToken.prototype.componentWillMount = function () {
.balanceOf(selectedAddress)
.then(usersToken => {
})
- this.props.updateTokenExchangeRate()
this.updateComponentSendErrors({})
}
@@ -310,10 +320,12 @@ ConfirmSendToken.prototype.renderHeroAmount = function () {
const txParams = txMeta.txParams || {}
const { memo = '' } = txParams
+ const convertedAmountInFiat = this.convertToRenderableCurrency(fiatAmount, currentCurrency)
+
return fiatAmount
? (
h('div.confirm-send-token__hero-amount-wrapper', [
- h('h3.flex-center.confirm-screen-send-amount', `${fiatAmount}`),
+ h('h3.flex-center.confirm-screen-send-amount', `${convertedAmountInFiat}`),
h('h3.flex-center.confirm-screen-send-amount-currency', currentCurrency),
h('div.flex-center.confirm-memo-wrapper', [
h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
@@ -361,6 +373,9 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
const { fiat: fiatGas, token: tokenGas } = this.getGasFee()
+ const totalInFIAT = fiatAmount && fiatGas && addCurrencies(fiatAmount, fiatGas)
+ const convertedTotalInFiat = this.convertToRenderableCurrency(totalInFIAT, currentCurrency)
+
return fiatAmount && fiatGas
? (
h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
@@ -370,7 +385,7 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
]),
h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${addCurrencies(fiatAmount, fiatGas)} ${currentCurrency}`),
+ h('div.confirm-screen-row-info', `${convertedTotalInFiat} ${currentCurrency}`),
h('div.confirm-screen-row-detail', `${addCurrencies(tokenAmount, tokenGas || '0')} ${symbol}`),
]),
])
@@ -405,8 +420,17 @@ ConfirmSendToken.prototype.renderErrorMessage = function (message) {
: null
}
+ConfirmSendToken.prototype.convertToRenderableCurrency = function (value, currencyCode) {
+ const upperCaseCurrencyCode = currencyCode.toUpperCase()
+
+ return currencies.find(currency => currency.code === upperCaseCurrencyCode)
+ ? currencyFormatter.format(Number(value), {
+ code: upperCaseCurrencyCode,
+ })
+ : value
+}
+
ConfirmSendToken.prototype.render = function () {
- const { editTransaction } = this.props
const txMeta = this.gatherTxMeta()
const {
from: {
@@ -433,7 +457,7 @@ ConfirmSendToken.prototype.render = function () {
h('div.page-container', [
h('div.page-container__header', [
!txMeta.lastGasPrice && h('button.confirm-screen-back-button', {
- onClick: () => editTransaction(txMeta),
+ onClick: () => this.editTransaction(txMeta),
}, this.context.t('edit')),
h('div.page-container__title', title),
h('div.page-container__subtitle', subtitle),
@@ -513,7 +537,9 @@ ConfirmSendToken.prototype.render = function () {
}, this.context.t('cancel')),
// Accept Button
- h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]),
+ h('button.btn-confirm.page-container__footer-button.allcaps', {
+ onClick: event => this.onSubmit(event),
+ }, [this.context.t('confirm')]),
]),
]),
]),
@@ -566,6 +592,7 @@ ConfirmSendToken.prototype.cancel = function (event, txMeta) {
const { cancelTransaction } = this.props
cancelTransaction(txMeta)
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmSendToken.prototype.checkValidity = function () {
diff --git a/ui/app/components/pending-tx/index.js b/ui/app/components/pending-tx/index.js
index acdd99364..893538bcf 100644
--- a/ui/app/components/pending-tx/index.js
+++ b/ui/app/components/pending-tx/index.js
@@ -1,16 +1,18 @@
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
const clone = require('clone')
const abi = require('human-standard-token-abi')
const abiDecoder = require('abi-decoder')
abiDecoder.addABI(abi)
const inherits = require('util').inherits
const actions = require('../../actions')
-const util = require('../../util')
+const { getSymbolAndDecimals } = require('../../token-util')
const ConfirmSendEther = require('./confirm-send-ether')
const ConfirmSendToken = require('./confirm-send-token')
const ConfirmDeployContract = require('./confirm-deploy-contract')
+const Loading = require('../loading-screen')
const TX_TYPES = {
DEPLOY_CONTRACT: 'deploy_contract',
@@ -24,6 +26,7 @@ function mapStateToProps (state) {
const {
conversionRate,
identities,
+ tokens: existingTokens,
} = state.metamask
const accounts = state.metamask.accounts
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
@@ -31,6 +34,7 @@ function mapStateToProps (state) {
conversionRate,
identities,
selectedAddress,
+ existingTokens,
}
}
@@ -53,10 +57,25 @@ function PendingTx () {
}
}
-PendingTx.prototype.componentWillMount = async function () {
+PendingTx.prototype.componentDidMount = function () {
+ this.setTokenData()
+}
+
+PendingTx.prototype.componentDidUpdate = function (prevProps, prevState) {
+ if (prevState.isFetching) {
+ this.setTokenData()
+ }
+}
+
+PendingTx.prototype.setTokenData = async function () {
+ const { existingTokens } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
+ if (txMeta.loadingDefaults) {
+ return
+ }
+
if (!txParams.to) {
return this.setState({
transactionType: TX_TYPES.DEPLOY_CONTRACT,
@@ -73,30 +92,15 @@ PendingTx.prototype.componentWillMount = async function () {
}
if (isTokenTransaction) {
- const token = util.getContractAtAddress(txParams.to)
- const results = await Promise.all([
- token.symbol(),
- token.decimals(),
- ])
- const [ symbol, decimals ] = results
-
- if (symbol[0] && decimals[0]) {
- this.setState({
- transactionType: TX_TYPES.SEND_TOKEN,
- tokenAddress: txParams.to,
- tokenSymbol: symbol[0],
- tokenDecimals: decimals[0],
- isFetching: false,
- })
- } else {
- this.setState({
- transactionType: TX_TYPES.SEND_TOKEN,
- tokenAddress: txParams.to,
- tokenSymbol: null,
- tokenDecimals: null,
- isFetching: false,
- })
- }
+ const { symbol, decimals } = await getSymbolAndDecimals(txParams.to, existingTokens)
+
+ this.setState({
+ transactionType: TX_TYPES.SEND_TOKEN,
+ tokenAddress: txParams.to,
+ tokenSymbol: symbol,
+ tokenDecimals: decimals,
+ isFetching: false,
+ })
} else {
this.setState({
transactionType: TX_TYPES.SEND_ETHER,
@@ -125,7 +129,10 @@ PendingTx.prototype.render = function () {
const { sendTransaction } = this.props
if (isFetching) {
- return h('noscript')
+ return h(Loading, {
+ fullScreen: true,
+ loadingMessage: this.context.t('generatingTransaction'),
+ })
}
switch (transactionType) {
@@ -150,6 +157,12 @@ PendingTx.prototype.render = function () {
sendTransaction,
})
default:
- return h('noscript')
+ return h(Loading, {
+ fullScreen: true,
+ })
}
}
+
+PendingTx.contextTypes = {
+ t: PropTypes.func,
+}
diff --git a/ui/app/components/qr-code.js b/ui/app/components/qr-code.js
index 83885539c..3b2c62f49 100644
--- a/ui/app/components/qr-code.js
+++ b/ui/app/components/qr-code.js
@@ -3,8 +3,9 @@ const h = require('react-hyperscript')
const qrCode = require('qrcode-npm').qrcode
const inherits = require('util').inherits
const connect = require('react-redux').connect
-const isHexPrefixed = require('ethereumjs-util').isHexPrefixed
+const { isHexPrefixed } = require('ethereumjs-util')
const ReadOnlyInput = require('./readonly-input')
+const { checksumAddress } = require('../util')
module.exports = connect(mapStateToProps)(QrCodeView)
@@ -24,16 +25,16 @@ function QrCodeView () {
QrCodeView.prototype.render = function () {
const props = this.props
- const Qr = props.Qr
- const address = `${isHexPrefixed(Qr.data) ? 'ethereum:' : ''}${Qr.data}`
+ const { message, data } = props.Qr
+ const address = `${isHexPrefixed(data) ? 'ethereum:' : ''}${data}`
const qrImage = qrCode(4, 'M')
qrImage.addData(address)
qrImage.make()
return h('.div.flex-column.flex-center', [
- Array.isArray(Qr.message)
+ Array.isArray(message)
? h('.message-container', this.renderMultiMessage())
- : Qr.message && h('.qr-header', Qr.message),
+ : message && h('.qr-header', message),
this.props.warning ? this.props.warning && h('span.error.flex-center', {
style: {
@@ -50,7 +51,7 @@ QrCodeView.prototype.render = function () {
h(ReadOnlyInput, {
wrapperClass: 'ellip-address-wrapper',
inputClass: 'qr-ellip-address',
- value: Qr.data,
+ value: checksumAddress(data),
}),
])
}
diff --git a/ui/app/components/send/account-list-item.js b/ui/app/components/send/account-list-item.js
index 1ad3f69c1..b5e604a6e 100644
--- a/ui/app/components/send/account-list-item.js
+++ b/ui/app/components/send/account-list-item.js
@@ -2,6 +2,7 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const connect = require('react-redux').connect
+const { checksumAddress } = require('../../util')
const Identicon = require('../identicon')
const CurrencyDisplay = require('./currency-display')
const { conversionRateSelector, getCurrentCurrency } = require('../../selectors')
@@ -56,7 +57,7 @@ AccountListItem.prototype.render = function () {
]),
- displayAddress && name && h('div.account-list-item__account-address', address),
+ displayAddress && name && h('div.account-list-item__account-address', checksumAddress(address)),
displayBalance && h(CurrencyDisplay, {
primaryCurrency: 'ETH',
diff --git a/ui/app/components/send/currency-display.js b/ui/app/components/send/currency-display.js
index 819fee0a0..90fb2b66c 100644
--- a/ui/app/components/send/currency-display.js
+++ b/ui/app/components/send/currency-display.js
@@ -3,6 +3,8 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const CurrencyInput = require('../currency-input')
const { conversionUtil, multiplyCurrencies } = require('../../conversion-util')
+const currencyFormatter = require('currency-formatter')
+const currencies = require('currency-formatter/currencies')
module.exports = CurrencyDisplay
@@ -53,12 +55,32 @@ CurrencyDisplay.prototype.getValueToRender = function () {
})
}
+CurrencyDisplay.prototype.getConvertedValueToRender = function (nonFormattedValue) {
+ const { primaryCurrency, convertedCurrency, conversionRate } = this.props
+
+ let convertedValue = conversionUtil(nonFormattedValue, {
+ fromNumericBase: 'dec',
+ fromCurrency: primaryCurrency,
+ toCurrency: convertedCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ convertedValue = Number(convertedValue).toFixed(2)
+
+ const upperCaseCurrencyCode = convertedCurrency.toUpperCase()
+
+ return currencies.find(currency => currency.code === upperCaseCurrencyCode)
+ ? currencyFormatter.format(Number(convertedValue), {
+ code: upperCaseCurrencyCode,
+ })
+ : convertedValue
+}
+
CurrencyDisplay.prototype.render = function () {
const {
className = 'currency-display',
primaryBalanceClassName = 'currency-display__input',
convertedBalanceClassName = 'currency-display__converted-value',
- conversionRate,
primaryCurrency,
convertedCurrency,
readOnly = false,
@@ -67,37 +89,31 @@ CurrencyDisplay.prototype.render = function () {
} = this.props
const valueToRender = this.getValueToRender()
-
- let convertedValue = conversionUtil(valueToRender, {
- fromNumericBase: 'dec',
- fromCurrency: primaryCurrency,
- toCurrency: convertedCurrency,
- numberOfDecimals: 2,
- conversionRate,
- })
- convertedValue = Number(convertedValue).toFixed(2)
+ const convertedValueToRender = this.getConvertedValueToRender(valueToRender)
return h('div', {
className,
style: {
borderColor: inError ? 'red' : null,
},
- onClick: () => this.currencyInput.focus(),
+ onClick: () => this.currencyInput && this.currencyInput.focus(),
}, [
h('div.currency-display__primary-row', [
h('div.currency-display__input-wrapper', [
- h(CurrencyInput, {
+ h(readOnly ? 'input' : CurrencyInput, {
className: primaryBalanceClassName,
value: `${valueToRender}`,
placeholder: '0',
readOnly,
- onInputChange: newValue => {
- handleChange(this.getAmount(newValue))
- },
- inputRef: input => { this.currencyInput = input },
+ ...(!readOnly ? {
+ onInputChange: newValue => {
+ handleChange(this.getAmount(newValue))
+ },
+ inputRef: input => { this.currencyInput = input },
+ } : {}),
}),
h('span.currency-display__currency-symbol', primaryCurrency),
@@ -108,7 +124,7 @@ CurrencyDisplay.prototype.render = function () {
h('div', {
className: convertedBalanceClassName,
- }, `${convertedValue} ${convertedCurrency.toUpperCase()}`),
+ }, `${convertedValueToRender} ${convertedCurrency.toUpperCase()}`),
])
diff --git a/ui/app/components/send/send-constants.js b/ui/app/components/send/send-constants.js
index b3ee0899a..5d89c74aa 100644
--- a/ui/app/components/send/send-constants.js
+++ b/ui/app/components/send/send-constants.js
@@ -1,8 +1,8 @@
const ethUtil = require('ethereumjs-util')
const { conversionUtil, multiplyCurrencies } = require('../../conversion-util')
-const MIN_GAS_PRICE_HEX = (100000000).toString(16)
-const MIN_GAS_PRICE_DEC = '100000000'
+const MIN_GAS_PRICE_DEC = '0'
+const MIN_GAS_PRICE_HEX = (parseInt(MIN_GAS_PRICE_DEC)).toString(16)
const MIN_GAS_LIMIT_DEC = '21000'
const MIN_GAS_LIMIT_HEX = (parseInt(MIN_GAS_LIMIT_DEC)).toString(16)
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index 08c26a91f..adfc91240 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -2,6 +2,8 @@ const connect = require('react-redux').connect
const actions = require('../../actions')
const abi = require('ethereumjs-abi')
const SendEther = require('../../send-v2')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const {
accountsWithSendEtherInfoSelector,
@@ -16,7 +18,10 @@ const {
getSelectedTokenContract,
} = require('../../selectors')
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(SendEther)
function mapStateToProps (state) {
const fromAccounts = accountsWithSendEtherInfoSelector(state)
@@ -61,7 +66,6 @@ function mapDispatchToProps (dispatch) {
showCustomizeGasModal: () => dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })),
estimateGas: params => dispatch(actions.estimateGas(params)),
getGasPrice: () => dispatch(actions.getGasPrice()),
- updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
signTokenTx: (tokenAddress, toAddress, amount, txData) => (
dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
),
@@ -79,7 +83,6 @@ function mapDispatchToProps (dispatch) {
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
- goHome: () => dispatch(actions.goHome()),
clearSend: () => dispatch(actions.clearSend()),
setMaxModeTo: bool => dispatch(actions.setMaxModeTo(bool)),
}
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index fd4a80a4a..22ab64426 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -55,6 +55,10 @@ function ShapeshiftForm () {
}
}
+ShapeshiftForm.prototype.getCoinPair = function () {
+ return `${this.state.depositCoin.toUpperCase()}_ETH`
+}
+
ShapeshiftForm.prototype.componentWillMount = function () {
this.props.shapeShiftSubview()
}
@@ -120,14 +124,12 @@ ShapeshiftForm.prototype.renderMetadata = function (label, value) {
}
ShapeshiftForm.prototype.renderMarketInfo = function () {
- const { depositCoin } = this.state
- const coinPair = `${depositCoin}_eth`
const { tokenExchangeRates } = this.props
const {
limit,
rate,
minimum,
- } = tokenExchangeRates[coinPair] || {}
+ } = tokenExchangeRates[this.getCoinPair()] || {}
return h('div.shapeshift-form__metadata', {}, [
@@ -172,10 +174,9 @@ ShapeshiftForm.prototype.renderQrCode = function () {
ShapeshiftForm.prototype.render = function () {
const { coinOptions, btnClass, warning } = this.props
- const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state
- const coinPair = `${depositCoin}_eth`
+ const { errorMessage, showQrCode, depositAddress } = this.state
const { tokenExchangeRates } = this.props
- const token = tokenExchangeRates[coinPair]
+ const token = tokenExchangeRates[this.getCoinPair()]
return h('div.shapeshift-form-wrapper', [
showQrCode
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
index 41415411e..b958a2d2d 100644
--- a/ui/app/components/signature-request.js
+++ b/ui/app/components/signature-request.js
@@ -6,6 +6,8 @@ const Identicon = require('./identicon')
const connect = require('react-redux').connect
const ethUtil = require('ethereumjs-util')
const classnames = require('classnames')
+const { compose } = require('recompose')
+const { withRouter } = require('react-router-dom')
const AccountDropdownMini = require('./dropdowns/account-dropdown-mini')
@@ -20,6 +22,8 @@ const {
conversionRateSelector,
} = require('../selectors.js')
+const { DEFAULT_ROUTE } = require('../routes')
+
function mapStateToProps (state) {
return {
balance: getSelectedAccount(state).balance,
@@ -42,7 +46,10 @@ SignatureRequest.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(SignatureRequest)
inherits(SignatureRequest, Component)
@@ -229,10 +236,14 @@ SignatureRequest.prototype.renderFooter = function () {
return h('div.request-signature__footer', [
h('button.btn-secondary--lg.request-signature__footer__cancel-button', {
- onClick: cancel,
+ onClick: event => {
+ cancel(event).then(() => this.props.history.push(DEFAULT_ROUTE))
+ },
}, this.context.t('cancel')),
h('button.btn-primary--lg', {
- onClick: sign,
+ onClick: event => {
+ sign(event).then(() => this.props.history.push(DEFAULT_ROUTE))
+ },
}, this.context.t('sign')),
])
}
diff --git a/ui/app/components/spinner/index.js b/ui/app/components/spinner/index.js
new file mode 100644
index 000000000..9589efcf0
--- /dev/null
+++ b/ui/app/components/spinner/index.js
@@ -0,0 +1,2 @@
+const Spinner = require('./spinner.component')
+module.exports = Spinner
diff --git a/ui/app/components/spinner/spinner.component.js b/ui/app/components/spinner/spinner.component.js
new file mode 100644
index 000000000..b9a2eb52a
--- /dev/null
+++ b/ui/app/components/spinner/spinner.component.js
@@ -0,0 +1,78 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+const Spinner = ({ className = '', color = '#000000' }) => {
+ return (
+ <div className={`spinner ${className}`}>
+ <svg className="lds-spinner" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" style={{background: 'none'}}>
+ <g transform="rotate(0 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(30 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(60 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.75s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(90 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(120 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(150 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.5s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(180 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(210 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(240 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.25s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(270 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(300 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ <g transform="rotate(330 50 50)">
+ <rect x={45} y={0} rx={0} ry={0} width={10} height={30} fill={color}>
+ <animate attributeName="opacity" values="1;0" dur="1s" begin="0s" repeatCount="indefinite" />
+ </rect>
+ </g>
+ </svg>
+ </div>
+ )
+}
+
+Spinner.propTypes = {
+ className: PropTypes.string,
+ color: PropTypes.string,
+}
+
+module.exports = Spinner
diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js
index a80640116..0016a09c1 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -4,31 +4,17 @@ const PropTypes = require('prop-types')
const classnames = require('classnames')
class TabBar extends Component {
- constructor (props) {
- super(props)
- const { defaultTab, tabs } = props
-
- this.state = {
- subview: defaultTab || tabs[0].key,
- }
- }
-
render () {
- const { tabs = [], tabSelected } = this.props
- const { subview } = this.state
+ const { tabs = [], onSelect, isActive } = this.props
return (
h('.tab-bar', {}, [
- tabs.map((tab) => {
- const { key, content } = tab
+ tabs.map(({ key, content }) => {
return h('div', {
className: classnames('tab-bar__tab pointer', {
- 'tab-bar__tab--active': subview === key,
+ 'tab-bar__tab--active': isActive(key, content),
}),
- onClick: () => {
- this.setState({ subview: key })
- tabSelected(key)
- },
+ onClick: () => onSelect(key),
key,
}, content)
}),
@@ -39,9 +25,9 @@ class TabBar extends Component {
}
TabBar.propTypes = {
- defaultTab: PropTypes.string,
+ isActive: PropTypes.func.isRequired,
tabs: PropTypes.array,
- tabSelected: PropTypes.func,
+ onSelect: PropTypes.func,
}
module.exports = TabBar
diff --git a/ui/app/components/token-balance.js b/ui/app/components/token-balance.js
index 2f71c0687..1900ccec7 100644
--- a/ui/app/components/token-balance.js
+++ b/ui/app/components/token-balance.js
@@ -4,6 +4,7 @@ const inherits = require('util').inherits
const TokenTracker = require('eth-token-tracker')
const connect = require('react-redux').connect
const selectors = require('../selectors')
+const log = require('loglevel')
function mapStateToProps (state) {
return {
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
index 0332fde88..c84117d84 100644
--- a/ui/app/components/token-cell.js
+++ b/ui/app/components/token-cell.js
@@ -16,7 +16,7 @@ function mapStateToProps (state) {
currentCurrency: state.metamask.currentCurrency,
selectedTokenAddress: state.metamask.selectedTokenAddress,
userAddress: selectors.getSelectedAddress(state),
- tokenExchangeRates: state.metamask.tokenExchangeRates,
+ contractExchangeRates: state.metamask.contractExchangeRates,
conversionRate: state.metamask.conversionRate,
sidebarOpen: state.appState.sidebarOpen,
}
@@ -25,7 +25,6 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
setSelectedToken: address => dispatch(actions.setSelectedToken(address)),
- updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
hideSidebar: () => dispatch(actions.hideSidebar()),
}
}
@@ -41,15 +40,6 @@ function TokenCell () {
}
}
-TokenCell.prototype.componentWillMount = function () {
- const {
- updateTokenExchangeRate,
- symbol,
- } = this.props
-
- updateTokenExchangeRate(symbol)
-}
-
TokenCell.prototype.render = function () {
const { tokenMenuOpen } = this.state
const props = this.props
@@ -60,7 +50,7 @@ TokenCell.prototype.render = function () {
network,
setSelectedToken,
selectedTokenAddress,
- tokenExchangeRates,
+ contractExchangeRates,
conversionRate,
hideSidebar,
sidebarOpen,
@@ -68,15 +58,13 @@ TokenCell.prototype.render = function () {
// userAddress,
} = props
- const pair = `${symbol.toLowerCase()}_eth`
-
let currentTokenToFiatRate
let currentTokenInFiat
let formattedFiat = ''
- if (tokenExchangeRates[pair]) {
+ if (contractExchangeRates[address]) {
currentTokenToFiatRate = multiplyCurrencies(
- tokenExchangeRates[pair].rate,
+ contractExchangeRates[address],
conversionRate
)
currentTokenInFiat = conversionUtil(string, {
diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js
index 150a3762d..4189cf801 100644
--- a/ui/app/components/token-list.js
+++ b/ui/app/components/token-list.js
@@ -6,6 +6,7 @@ const TokenTracker = require('eth-token-tracker')
const TokenCell = require('./token-cell.js')
const connect = require('react-redux').connect
const selectors = require('../selectors')
+const log = require('loglevel')
function mapStateToProps (state) {
return {
diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js
index 42c008798..bd4ea80a6 100644
--- a/ui/app/components/tx-list-item.js
+++ b/ui/app/components/tx-list-item.js
@@ -9,6 +9,7 @@ const abiDecoder = require('abi-decoder')
abiDecoder.addABI(abi)
const Identicon = require('./identicon')
const contractMap = require('eth-contract-metadata')
+const { checksumAddress } = require('../util')
const actions = require('../actions')
const { conversionUtil, multiplyCurrencies } = require('../conversion-util')
@@ -27,7 +28,7 @@ function mapStateToProps (state) {
return {
tokens: state.metamask.tokens,
currentCurrency: getCurrentCurrency(state),
- tokenExchangeRates: state.metamask.tokenExchangeRates,
+ contractExchangeRates: state.metamask.contractExchangeRates,
selectedAddressTxList: state.metamask.selectedAddressTxList,
}
}
@@ -74,10 +75,12 @@ TxListItem.prototype.getAddressText = function () {
const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { name: txDataName, params = [] } = decodedData || {}
const { value } = params[0] || {}
+ const checksummedAddress = checksumAddress(address)
+ const checksummedValue = checksumAddress(value)
let addressText
if (txDataName === 'transfer' || address) {
- const addressToRender = txDataName === 'transfer' ? value : address
+ const addressToRender = txDataName === 'transfer' ? checksummedValue : checksummedAddress
addressText = `${addressToRender.slice(0, 10)}...${addressToRender.slice(-4)}`
} else if (isMsg) {
addressText = this.context.t('sigRequest')
@@ -142,31 +145,29 @@ TxListItem.prototype.getTokenInfo = async function () {
({ decimals, symbol } = await tokenInfoGetter(toAddress))
}
- return { decimals, symbol }
+ return { decimals, symbol, address: toAddress }
}
TxListItem.prototype.getSendTokenTotal = async function () {
const {
txParams = {},
conversionRate,
- tokenExchangeRates,
+ contractExchangeRates,
currentCurrency,
} = this.props
const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { params = [] } = decodedData || {}
const { value } = params[1] || {}
- const { decimals, symbol } = await this.getTokenInfo()
+ const { decimals, symbol, address } = await this.getTokenInfo()
const total = calcTokenAmount(value, decimals)
- const pair = symbol && `${symbol.toLowerCase()}_eth`
-
let tokenToFiatRate
let totalInFiat
- if (tokenExchangeRates[pair]) {
+ if (contractExchangeRates[address]) {
tokenToFiatRate = multiplyCurrencies(
- tokenExchangeRates[pair].rate,
+ contractExchangeRates[address],
conversionRate
)
@@ -220,7 +221,6 @@ TxListItem.prototype.resubmit = function () {
TxListItem.prototype.render = function () {
const {
transactionStatus,
- transactionAmount,
onClick,
transactionId,
dateString,
@@ -229,7 +229,6 @@ TxListItem.prototype.render = function () {
txParams,
} = this.props
const { total, fiatTotal, isTokenTx } = this.state
- const showFiatTotal = transactionAmount !== '0x0' && fiatTotal
return h(`div${className || ''}`, {
key: transactionId,
@@ -288,7 +287,7 @@ TxListItem.prototype.render = function () {
h('span.tx-list-value', total),
- showFiatTotal && h('span.tx-list-fiat-value', fiatTotal),
+ fiatTotal && h('span.tx-list-fiat-value', fiatTotal),
]),
]),
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index 740c4a4ab..554febcff 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -11,14 +11,19 @@ const { formatDate } = require('../util')
const { showConfTxPage } = require('../actions')
const classnames = require('classnames')
const { tokenInfoGetter } = require('../token-util')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
+const { CONFIRM_TRANSACTION_ROUTE } = require('../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxList)
TxList.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxList)
-
-
function mapStateToProps (state) {
return {
txsToRender: selectors.transactionsSelector(state),
@@ -96,7 +101,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
transactionNetworkId,
transactionSubmittedTime,
} = props
- const { showConfTxPage } = this.props
+ const { history } = this.props
const opts = {
key: transactionId || transactionHash,
@@ -116,7 +121,10 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
const isUnapproved = transactionStatus === 'unapproved'
if (isUnapproved) {
- opts.onClick = () => showConfTxPage({ id: transactionId })
+ opts.onClick = () => {
+ this.props.showConfTxPage({ id: transactionId })
+ history.push(CONFIRM_TRANSACTION_ROUTE)
+ }
opts.transactionStatus = this.context.t('notStarted')
} else if (transactionHash) {
opts.onClick = () => this.view(transactionHash, transactionNetworkId)
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
index ca24e813f..263f992c0 100644
--- a/ui/app/components/tx-view.js
+++ b/ui/app/components/tx-view.js
@@ -2,22 +2,27 @@ const Component = require('react').Component
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
-const ethUtil = require('ethereumjs-util')
const inherits = require('util').inherits
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('../actions')
const selectors = require('../selectors')
+const { SEND_ROUTE } = require('../routes')
+const { checksumAddress: toChecksumAddress } = require('../util')
const BalanceComponent = require('./balance-component')
const TxList = require('./tx-list')
const Identicon = require('./identicon')
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(TxView)
+
TxView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView)
-
-
function mapStateToProps (state) {
const sidebarOpen = state.appState.sidebarOpen
const isMascara = state.appState.isMascara
@@ -27,7 +32,7 @@ function mapStateToProps (state) {
const network = state.metamask.network
const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
- const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress)
+ const checksumAddress = toChecksumAddress(selectedAddress)
const identity = identities[selectedAddress]
return {
@@ -69,7 +74,7 @@ TxView.prototype.renderHeroBalance = function () {
}
TxView.prototype.renderButtons = function () {
- const {selectedToken, showModal, showSendPage, showSendTokenPage } = this.props
+ const {selectedToken, showModal, history } = this.props
return !selectedToken
? (
@@ -84,14 +89,14 @@ TxView.prototype.renderButtons = function () {
style: {
marginLeft: '0.8em',
},
- onClick: showSendPage,
+ onClick: () => history.push(SEND_ROUTE),
}, this.context.t('send')),
])
)
: (
h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-primary.hero-balance-button', {
- onClick: showSendTokenPage,
+ onClick: () => history.push(SEND_ROUTE),
}, this.context.t('send')),
])
)
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index e6b94ad12..9e430f87b 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -2,8 +2,11 @@ const Component = require('react').Component
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const inherits = require('util').inherits
const classnames = require('classnames')
+const { checksumAddress } = require('../util')
const Identicon = require('./identicon')
// const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns
const Tooltip = require('./tooltip-v2.js')
@@ -12,14 +15,17 @@ const actions = require('../actions')
const BalanceComponent = require('./balance-component')
const TokenList = require('./token-list')
const selectors = require('../selectors')
+const { ADD_TOKEN_ROUTE } = require('../routes')
+
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps, mapDispatchToProps)
+)(WalletView)
WalletView.contextTypes = {
t: PropTypes.func,
}
-module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView)
-
-
function mapStateToProps (state) {
return {
@@ -97,11 +103,13 @@ WalletView.prototype.render = function () {
keyrings,
showAccountDetailModal,
hideSidebar,
- showAddTokenPage,
+ history,
} = this.props
// temporary logs + fake extra wallets
// console.log('walletview, selectedAccount:', selectedAccount)
+ const checksummedAddress = checksumAddress(selectedAddress)
+
const keyring = keyrings.find((kr) => {
return kr.accounts.includes(selectedAddress) ||
kr.accounts.includes(selectedIdentity.address)
@@ -130,7 +138,7 @@ WalletView.prototype.render = function () {
}, [
h(Identicon, {
diameter: 54,
- address: selectedAddress,
+ address: checksummedAddress,
}),
h('span.account-name', {
@@ -153,7 +161,7 @@ WalletView.prototype.render = function () {
'wallet-view__address__pressed': this.state.copyToClipboardPressed,
}),
onClick: () => {
- copyToClipboard(selectedAddress)
+ copyToClipboard(checksummedAddress)
this.setState({ hasCopied: true })
setTimeout(() => this.setState({ hasCopied: false }), 3000)
},
@@ -164,7 +172,7 @@ WalletView.prototype.render = function () {
this.setState({ copyToClipboardPressed: false })
},
}, [
- `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`,
+ `${checksummedAddress.slice(0, 4)}...${checksummedAddress.slice(-4)}`,
h('i.fa.fa-clipboard', { style: { marginLeft: '8px' } }),
]),
]),
@@ -174,10 +182,7 @@ WalletView.prototype.render = function () {
h(TokenList),
h('button.btn-primary.wallet-view__add-token-button', {
- onClick: () => {
- showAddTokenPage()
- hideSidebar()
- },
+ onClick: () => history.push(ADD_TOKEN_ROUTE),
}, this.context.t('addToken')),
])
}
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 1070436c3..fb38aaa76 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -2,28 +2,33 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const actions = require('./actions')
const txHelper = require('../lib/tx-helper')
+const log = require('loglevel')
const PendingTx = require('./components/pending-tx')
const SignatureRequest = require('./components/signature-request')
// const PendingMsg = require('./components/pending-msg')
// const PendingPersonalMsg = require('./components/pending-personal-msg')
// const PendingTypedMsg = require('./components/pending-typed-msg')
-const Loading = require('./components/loading')
+const Loading = require('./components/loading-screen')
+const { DEFAULT_ROUTE } = require('./routes')
-// const contentDivider = h('div', {
-// style: {
-// marginLeft: '16px',
-// marginRight: '16px',
-// height:'1px',
-// background:'#E7E7E7',
-// },
-// })
-
-module.exports = connect(mapStateToProps)(ConfirmTxScreen)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(ConfirmTxScreen)
function mapStateToProps (state) {
+ const { metamask } = state
+ const {
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ } = metamask
+
return {
identities: state.metamask.identities,
accounts: state.metamask.accounts,
@@ -40,6 +45,10 @@ function mapStateToProps (state) {
currentCurrency: state.metamask.currentCurrency,
blockGasLimit: state.metamask.currentBlockGasLimit,
computedBalances: state.metamask.computedBalances,
+ unapprovedMsgCount,
+ unapprovedPersonalMsgCount,
+ unapprovedTypedMessagesCount,
+ send: state.metamask.send,
selectedAddressTxList: state.metamask.selectedAddressTxList,
}
}
@@ -49,11 +58,35 @@ function ConfirmTxScreen () {
Component.call(this)
}
+ConfirmTxScreen.prototype.getUnapprovedMessagesTotal = function () {
+ const {
+ unapprovedMsgCount = 0,
+ unapprovedPersonalMsgCount = 0,
+ unapprovedTypedMessagesCount = 0,
+ } = this.props
+
+ return unapprovedTypedMessagesCount + unapprovedMsgCount + unapprovedPersonalMsgCount
+}
+
+ConfirmTxScreen.prototype.componentDidMount = function () {
+ const {
+ unapprovedTxs = {},
+ network,
+ send,
+ } = this.props
+ const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network)
+
+ if (unconfTxList.length === 0 && !send.to && this.getUnapprovedMessagesTotal() === 0) {
+ this.props.history.push(DEFAULT_ROUTE)
+ }
+}
+
ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) {
const {
- unapprovedTxs,
+ unapprovedTxs = {},
network,
selectedAddressTxList,
+ send,
} = this.props
const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevProps
const prevUnconfTxList = txHelper(prevUnapprovedTxs, {}, {}, {}, network)
@@ -61,8 +94,9 @@ ConfirmTxScreen.prototype.componentDidUpdate = function (prevProps) {
const prevTx = selectedAddressTxList.find(({ id }) => id === prevTxData.id) || {}
const unconfTxList = txHelper(unapprovedTxs, {}, {}, {}, network)
- if (prevTx.status === 'dropped' && unconfTxList.length === 0) {
- this.goHome({})
+ if (unconfTxList.length === 0 &&
+ (prevTx.status === 'dropped' || !send.to && this.getUnapprovedMessagesTotal() === 0)) {
+ this.props.history.push(DEFAULT_ROUTE)
}
}
@@ -103,7 +137,6 @@ ConfirmTxScreen.prototype.render = function () {
*/
log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
- if (unconfTxList.length === 0) return h(Loading)
return currentTxView({
// Properties
@@ -152,6 +185,7 @@ function currentTxView (opts) {
// return h(PendingTypedMsg, opts)
// }
}
+
return h(Loading)
}
@@ -163,6 +197,7 @@ ConfirmTxScreen.prototype.buyEth = function (address, event) {
ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
this.stopPropagation(event)
this.props.dispatch(actions.updateAndApproveTx(txData))
+ .then(() => this.props.history.push(DEFAULT_ROUTE))
}
ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
@@ -182,7 +217,7 @@ ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signMsg(params))
+ return this.props.dispatch(actions.signMsg(params))
}
ConfirmTxScreen.prototype.stopPropagation = function (event) {
@@ -196,7 +231,7 @@ ConfirmTxScreen.prototype.signPersonalMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signPersonalMsg(params))
+ return this.props.dispatch(actions.signPersonalMsg(params))
}
ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
@@ -204,25 +239,25 @@ ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
var params = msgData.msgParams
params.metamaskId = msgData.id
this.stopPropagation(event)
- this.props.dispatch(actions.signTypedMsg(params))
+ return this.props.dispatch(actions.signTypedMsg(params))
}
ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
log.info('canceling message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelMsg(msgData))
+ return this.props.dispatch(actions.cancelMsg(msgData))
}
ConfirmTxScreen.prototype.cancelPersonalMessage = function (msgData, event) {
log.info('canceling personal message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelPersonalMsg(msgData))
+ return this.props.dispatch(actions.cancelPersonalMsg(msgData))
}
ConfirmTxScreen.prototype.cancelTypedMessage = function (msgData, event) {
log.info('canceling typed message')
this.stopPropagation(event)
- this.props.dispatch(actions.cancelTypedMsg(msgData))
+ return this.props.dispatch(actions.cancelTypedMsg(msgData))
}
ConfirmTxScreen.prototype.goHome = function (event) {
diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss
index 445c819ff..c068028f8 100644
--- a/ui/app/css/index.scss
+++ b/ui/app/css/index.scss
@@ -6,9 +6,15 @@
*/
@import './itcss/settings/index.scss';
+
@import './itcss/tools/index.scss';
+
@import './itcss/generic/index.scss';
+
@import './itcss/base/index.scss';
+
@import './itcss/objects/index.scss';
+
@import './itcss/components/index.scss';
+
@import './itcss/trumps/index.scss';
diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss
index 2fdda6f43..01579c27c 100644
--- a/ui/app/css/itcss/components/add-token.scss
+++ b/ui/app/css/itcss/components/add-token.scss
@@ -36,6 +36,7 @@
font-weight: 400;
line-height: 21px;
margin-left: 8px;
+ cursor:pointer;
}
}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index ffd43ecbf..1c544e162 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -52,6 +52,8 @@
@import './editable-label.scss';
+@import './pages/index.scss';
+
@import './new-account.scss';
@import './tooltip.scss';
@@ -59,3 +61,5 @@
@import './welcome-screen.scss';
@import './sender-to-recipient.scss';
+
+@import '../../../components/export-text-container/export-text-container.scss';
diff --git a/ui/app/css/itcss/components/loading-overlay.scss b/ui/app/css/itcss/components/loading-overlay.scss
index 15009c1e6..c18b7fa59 100644
--- a/ui/app/css/itcss/components/loading-overlay.scss
+++ b/ui/app/css/itcss/components/loading-overlay.scss
@@ -1,13 +1,14 @@
.loading-overlay {
- left: 0px;
+ left: 0;
z-index: 50;
position: absolute;
flex-direction: column;
display: flex;
justify-content: center;
align-items: center;
+ flex: 1 1 auto;
width: 100%;
- background: rgba(255, 255, 255, 0.8);
+ background: rgba(255, 255, 255, .8);
@media screen and (max-width: 575px) {
margin-top: 56px;
@@ -18,4 +19,32 @@
margin-top: 75px;
height: calc(100% - 75px);
}
+
+ &--full-screen {
+ position: fixed;
+ height: 100vh;
+ width: 100vw;
+ margin-top: 0;
+ }
+
+ &__container {
+ position: absolute;
+ top: 33%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ }
+
+ &__message {
+ margin-top: 32px;
+ font-weight: 400;
+ font-size: 20px;
+ color: $manatee;
+ }
+}
+
+.spinner {
+ height: 58px;
+ width: 58px;
}
diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss
index c34b5cd06..6c8be0b6d 100644
--- a/ui/app/css/itcss/components/network.scss
+++ b/ui/app/css/itcss/components/network.scss
@@ -139,7 +139,7 @@
.network-dropdown-title {
height: 25px;
- width: 75px;
+ width: 120px;
color: $white;
font-family: Roboto;
font-size: 18px;
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index aa7fed956..293579058 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -35,13 +35,14 @@
font-size: 18px;
line-height: 24px;
text-align: center;
+ cursor: pointer;
}
&__tab:first-of-type {
margin-right: 20px;
}
- &__unselected:hover {
+ &__tab:hover {
color: $black;
border-bottom: none;
}
@@ -49,9 +50,9 @@
&__selected {
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
+ cursor: initial;
}
}
-
}
.new-account-import-disclaimer {
diff --git a/ui/app/css/itcss/components/pages/index.scss b/ui/app/css/itcss/components/pages/index.scss
new file mode 100644
index 000000000..d0b59da53
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/index.scss
@@ -0,0 +1,3 @@
+@import './unlock.scss';
+
+@import './reveal-seed.scss';
diff --git a/ui/app/css/itcss/components/pages/reveal-seed.scss b/ui/app/css/itcss/components/pages/reveal-seed.scss
new file mode 100644
index 000000000..b8f13af4a
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/reveal-seed.scss
@@ -0,0 +1,17 @@
+.reveal-seed {
+ &__content {
+ padding: 20px;
+ }
+
+ &__label {
+ padding-bottom: 10px;
+ font-weight: 400;
+ display: inline-block;
+ }
+
+ &__error {
+ color: $crimson;
+ font-size: 14px;
+ padding-top: 5px;
+ }
+}
diff --git a/ui/app/css/itcss/components/pages/unlock.scss b/ui/app/css/itcss/components/pages/unlock.scss
new file mode 100644
index 000000000..5d438377b
--- /dev/null
+++ b/ui/app/css/itcss/components/pages/unlock.scss
@@ -0,0 +1,9 @@
+.unlock-page {
+ box-shadow: none;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background: rgb(247, 247, 247);
+ width: 100%;
+}
diff --git a/ui/app/css/itcss/components/sections.scss b/ui/app/css/itcss/components/sections.scss
index 388aea175..ace46bd8a 100644
--- a/ui/app/css/itcss/components/sections.scss
+++ b/ui/app/css/itcss/components/sections.scss
@@ -17,6 +17,12 @@ textarea.twelve-word-phrase {
resize: none;
}
+.initialize-screen {
+ width: 100%;
+ z-index: $main-container-z-index;
+ background: #f7f7f7;
+}
+
.initialize-screen hr {
width: 60px;
margin: 12px;
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
index 89d2be891..362feeec8 100644
--- a/ui/app/css/itcss/components/send.scss
+++ b/ui/app/css/itcss/components/send.scss
@@ -789,6 +789,7 @@
display: flex;
justify-content: center;
align-items: center;
+ padding: 0 3px;
cursor: pointer;
}
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 92321394b..7a64810c4 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -207,6 +207,27 @@ input.large-input {
&__content {
height: 100%;
overflow-y: auto;
+ min-height: 250px;
+ max-height: 400px;
+ }
+
+ &__warning-container {
+ background: $linen;
+ padding: 20px;
+ display: flex;
+ align-items: start;
+ }
+
+ &__warning-message {
+ padding-left: 15px;
+ }
+
+ &__warning-title {
+ font-weight: 500;
+ }
+
+ &__warning-icon {
+ padding-top: 5px;
}
}
@@ -237,3 +258,49 @@ input.large-input {
border-radius: 0;
}
}
+
+@media screen and (min-width: 576px) {
+ .page-container {
+ height: 600px;
+ flex: 0 0 auto;
+ }
+}
+
+.input-label {
+ padding-bottom: 10px;
+ font-weight: 400;
+ display: inline-block;
+}
+
+input.form-control {
+ padding-left: 10px;
+ font-size: 14px;
+ height: 40px;
+ border: 1px solid $alto;
+ border-radius: 3px;
+ width: 100%;
+
+ &::-webkit-input-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+ }
+
+ &::-moz-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+ }
+
+ &:-ms-input-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+ }
+
+ &:-moz-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+ }
+
+ &--error {
+ border: 1px solid $monzo;
+ }
+}
diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss
index 51548306f..814d7a382 100644
--- a/ui/app/css/itcss/settings/variables.scss
+++ b/ui/app/css/itcss/settings/variables.scss
@@ -54,6 +54,7 @@ $saffron: #f6c343;
$dodger-blue: #3099f2;
$zumthor: #edf7ff;
$ecstasy: #f7861c;
+$linen: #fdf4f4;
/*
Z-Indicies
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 4ab5f06c0..6cb548bb9 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -1,6 +1,5 @@
-const inherits = require('util').inherits
-const EventEmitter = require('events').EventEmitter
-const Component = require('react').Component
+const { EventEmitter } = require('events')
+const { Component } = require('react')
const PropTypes = require('prop-types')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
@@ -8,205 +7,220 @@ const Mascot = require('../components/mascot')
const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const getCaretCoordinates = require('textarea-caret')
-const environmentType = require('../../../app/scripts/lib/environment-type')
-const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
-
-let isSubmitting = false
-
-InitializeMenuScreen.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps)(InitializeMenuScreen)
-
-
-inherits(InitializeMenuScreen, Component)
-function InitializeMenuScreen () {
- Component.call(this)
- this.animationEventEmitter = new EventEmitter()
-}
-
-function mapStateToProps (state) {
- return {
- // state from plugin
- currentView: state.appState.currentView,
- warning: state.appState.warning,
+const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes')
+const { getEnvironmentType } = require('../../../app/scripts/lib/util')
+const { ENVIRONMENT_TYPE_POPUP } = require('../../../app/scripts/lib/enums')
+const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/controllers/network/enums')
+
+class InitializeMenuScreen extends Component {
+ constructor (props) {
+ super(props)
+
+ this.animationEventEmitter = new EventEmitter()
+ this.state = {
+ warning: null,
+ }
}
-}
-
-InitializeMenuScreen.prototype.render = function () {
- var state = this.props
-
- switch (state.currentView.name) {
-
- default:
- return this.renderMenu(state)
+ componentWillMount () {
+ const { isInitialized, isUnlocked, history } = this.props
+ if (isInitialized || isUnlocked) {
+ history.push(DEFAULT_ROUTE)
+ }
}
-}
-
-// InitializeMenuScreen.prototype.componentDidMount = function(){
-// document.getElementById('password-box').focus()
-// }
-InitializeMenuScreen.prototype.renderMenu = function (state) {
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
+ componentDidMount () {
+ document.getElementById('password-box').focus()
+ }
- h(Mascot, {
- animationEventEmitter: this.animationEventEmitter,
- }),
+ render () {
+ const { warning } = this.state
- h('h1', {
- style: {
- fontSize: '1.3em',
- textTransform: 'uppercase',
- color: '#7F8082',
- marginBottom: 10,
- },
- }, this.context.t('appName')),
+ return (
+ h('.initialize-screen.flex-column.flex-center', [
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
- h('div', [
- h('h3', {
+ h('h1', {
style: {
- fontSize: '0.8em',
+ fontSize: '1.3em',
+ textTransform: 'uppercase',
color: '#7F8082',
- display: 'inline',
+ marginBottom: 10,
},
- }, this.context.t('encryptNewDen')),
+ }, this.context.t('appName')),
- h(Tooltip, {
- title: this.context.t('denExplainer'),
- }, [
- h('i.fa.fa-question-circle.pointer', {
+ h('div', [
+ h('h3', {
style: {
- fontSize: '18px',
- position: 'relative',
- color: 'rgb(247, 134, 28)',
- top: '2px',
- marginLeft: '4px',
+ fontSize: '0.8em',
+ color: '#7F8082',
+ display: 'inline',
},
- }),
+ }, this.context.t('encryptNewDen')),
+
+ h(Tooltip, {
+ title: this.context.t('denExplainer'),
+ }, [
+ h('i.fa.fa-question-circle.pointer', {
+ style: {
+ fontSize: '18px',
+ position: 'relative',
+ color: 'rgb(247, 134, 28)',
+ top: '2px',
+ marginLeft: '4px',
+ },
+ }),
+ ]),
]),
- ]),
-
- h('span.in-progress-notification', state.warning),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: this.context.t('newPassword'),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: this.context.t('confirmPassword'),
- onKeyPress: this.createVaultOnEnter.bind(this),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
-
- h('button.primary', {
- onClick: this.createNewVaultAndKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, this.context.t('createDen')),
-
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showRestoreVault.bind(this),
+
+ h('span.error.in-progress-notification', warning),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: this.context.t('newPassword'),
+ onInput: this.inputChanged.bind(this),
style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
+ width: 260,
+ marginTop: 12,
},
- }, this.context.t('importDen')),
- ]),
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: this.context.t('confirmPassword'),
+ onKeyPress: this.createVaultOnEnter.bind(this),
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showOldUI.bind(this),
+
+ h('button.primary', {
+ onClick: this.createNewVaultAndKeychain.bind(this),
style: {
- fontSize: '0.8em',
- color: '#aeaeae',
- textDecoration: 'underline',
- marginTop: '32px',
+ margin: 12,
},
- }, 'Use classic interface'),
- ]),
+ }, this.context.t('createDen')),
- ])
- )
-}
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => this.showRestoreVault(),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, this.context.t('importDen')),
+ ]),
-InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewVaultAndKeychain()
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showOldUI.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Use classic interface'),
+ ]),
+
+ ])
+ )
}
-}
-InitializeMenuScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
+ createVaultOnEnter (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewVaultAndKeychain()
+ }
+ }
+
+ createNewVaultAndKeychain () {
+ const { history } = this.props
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ this.setState({ warning: null })
+
+ if (password.length < 8) {
+ this.setState({ warning: this.context.t('passwordShort') })
+ return
+ }
-InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.markPasswordForgotten())
- if (environmentType() === 'popup') {
- global.platform.openExtensionInBrowser()
+ if (password !== passwordConfirm) {
+ this.setState({ warning: this.context.t('passwordMismatch') })
+ return
+ }
+
+ this.props.createNewVaultAndKeychain(password)
+ .then(() => history.push(DEFAULT_ROUTE))
}
-}
-InitializeMenuScreen.prototype.showOldUI = function () {
- this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
- .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
-}
+ inputChanged (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+ }
-InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
+ showRestoreVault () {
+ this.props.markPasswordForgotten()
+ if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
+ global.platform.openExtensionInBrowser()
+ }
- if (password.length < 8) {
- this.warning = this.context.t('passwordShort')
- this.props.dispatch(actions.displayWarning(this.warning))
- return
+ this.props.history.push(RESTORE_VAULT_ROUTE)
}
- if (password !== passwordConfirm) {
- this.warning = this.context.t('passwordMismatch')
- this.props.dispatch(actions.displayWarning(this.warning))
- return
+
+ showOldUI () {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
}
+}
+
+InitializeMenuScreen.propTypes = {
+ history: PropTypes.object,
+ isInitialized: PropTypes.bool,
+ isUnlocked: PropTypes.bool,
+ createNewVaultAndKeychain: PropTypes.func,
+ markPasswordForgotten: PropTypes.func,
+ dispatch: PropTypes.func,
+}
+
+InitializeMenuScreen.contextTypes = {
+ t: PropTypes.func,
+}
- if (!isSubmitting) {
- isSubmitting = true
- this.props.dispatch(actions.createNewVaultAndKeychain(password))
+const mapStateToProps = state => {
+ const { metamask: { isInitialized, isUnlocked } } = state
+
+ return {
+ isInitialized,
+ isUnlocked,
}
}
-InitializeMenuScreen.prototype.inputChanged = function (event) {
- // tell mascot to look at page action
- var element = event.target
- var boundingRect = element.getBoundingClientRect()
- var coordinates = getCaretCoordinates(element, element.selectionEnd)
- this.animationEventEmitter.emit('point', {
- x: boundingRect.left + coordinates.left - element.scrollLeft,
- y: boundingRect.top + coordinates.top - element.scrollTop,
- })
+const mapDispatchToProps = dispatch => {
+ return {
+ createNewVaultAndKeychain: password => dispatch(actions.createNewVaultAndKeychain(password)),
+ markPasswordForgotten: () => dispatch(actions.markPasswordForgotten()),
+ }
}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(InitializeMenuScreen)
diff --git a/ui/app/i18n-provider.js b/ui/app/i18n-provider.js
index fe6d62c67..4ef618018 100644
--- a/ui/app/i18n-provider.js
+++ b/ui/app/i18n-provider.js
@@ -1,6 +1,8 @@
const { Component } = require('react')
const connect = require('react-redux').connect
const PropTypes = require('prop-types')
+const { withRouter } = require('react-router-dom')
+const { compose } = require('recompose')
const t = require('../i18n-helper').getMessage
class I18nProvider extends Component {
@@ -32,5 +34,8 @@ const mapStateToProps = state => {
}
}
-module.exports = connect(mapStateToProps)(I18nProvider)
+module.exports = compose(
+ withRouter,
+ connect(mapStateToProps)
+)(I18nProvider)
diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js
deleted file mode 100644
index 02183f096..000000000
--- a/ui/app/keychains/hd/recover-seed/confirmation.js
+++ /dev/null
@@ -1,126 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const PropTypes = require('prop-types')
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../../actions')
-
-RevealSeedConfirmation.contextTypes = {
- t: PropTypes.func,
-}
-
-module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
-
-
-inherits(RevealSeedConfirmation, Component)
-function RevealSeedConfirmation () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-RevealSeedConfirmation.prototype.render = function () {
- const props = this.props
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', {
- style: { maxWidth: '420px' },
- }, [
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Reveal Seed Words',
- ]),
-
- h('.div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- padding: '20px',
- justifyContent: 'center',
- },
- }, [
-
- h('h4', this.context.t('revealSeedWordsWarning')),
-
- // confirmation
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: this.context.t('enterPasswordConfirm'),
- onKeyPress: this.checkConfirmation.bind(this),
- style: {
- width: 260,
- marginTop: '12px',
- },
- }),
-
- h('.flex-row.flex-start', {
- style: {
- marginTop: 30,
- width: '50%',
- },
- }, [
- // cancel
- h('button.primary', {
- onClick: this.goHome.bind(this),
- }, 'CANCEL'),
-
- // submit
- h('button.primary', {
- style: { marginLeft: '10px' },
- onClick: this.revealSeedWords.bind(this),
- }, 'OK'),
-
- ]),
-
- (props.warning) && (
- h('span.error', {
- style: {
- margin: '20px',
- },
- }, props.warning.split('-'))
- ),
-
- props.inProgress && (
- h('span.in-progress-notification', this.context.t('generatingSeed'))
- ),
- ]),
- ])
- )
-}
-
-RevealSeedConfirmation.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-RevealSeedConfirmation.prototype.goHome = function () {
- this.props.dispatch(actions.showConfigPage(false))
-}
-
-// create vault
-
-RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.revealSeedWords()
- }
-}
-
-RevealSeedConfirmation.prototype.revealSeedWords = function () {
- var password = document.getElementById('password-box').value
- this.props.dispatch(actions.requestRevealSeed(password))
-}
diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index 38ad14adb..913d20505 100644
--- a/ui/app/keychains/hd/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -4,6 +4,7 @@ const PersistentForm = require('../../../lib/persistent-form')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('../../actions')
+const log = require('loglevel')
RestoreVaultScreen.contextTypes = {
t: PropTypes.func,
diff --git a/ui/app/main-container.js b/ui/app/main-container.js
index eed4bd164..c305687ea 100644
--- a/ui/app/main-container.js
+++ b/ui/app/main-container.js
@@ -2,8 +2,9 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const AccountAndTransactionDetails = require('./account-and-transaction-details')
-const Settings = require('./settings')
-const UnlockScreen = require('./unlock')
+const Settings = require('./components/pages/settings')
+const UnlockScreen = require('./components/pages/unlock')
+const log = require('loglevel')
module.exports = MainContainer
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 74a0f9299..2b39eb8db 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -1,6 +1,7 @@
const extend = require('xtend')
const actions = require('../actions')
const txHelper = require('../../lib/tx-helper')
+const log = require('loglevel')
module.exports = reduceApp
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 6d0a5bb10..bb35cf990 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -1,8 +1,9 @@
const extend = require('xtend')
const actions = require('../actions')
const MetamascaraPlatform = require('../../../app/scripts/platforms/window')
-const environmentType = require('../../../app/scripts/lib/environment-type')
-const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
+const { getEnvironmentType } = require('../../../app/scripts/lib/util')
+const { ENVIRONMENT_TYPE_POPUP } = require('../../../app/scripts/lib/enums')
+const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/controllers/network/enums')
module.exports = reduceMetamask
@@ -15,7 +16,7 @@ function reduceMetamask (state, action) {
isUnlocked: false,
isAccountMenuOpen: false,
isMascara: window.platform instanceof MetamascaraPlatform,
- isPopup: environmentType() === 'popup',
+ isPopup: getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP,
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
unapprovedTxs: {},
@@ -24,6 +25,7 @@ function reduceMetamask (state, action) {
frequentRpcList: [],
addressBook: [],
selectedTokenAddress: null,
+ contractExchangeRates: {},
tokenExchangeRates: {},
tokens: [],
send: {
@@ -176,15 +178,6 @@ function reduceMetamask (state, action) {
conversionDate: action.value.conversionDate,
})
- case actions.UPDATE_TOKEN_EXCHANGE_RATE:
- const { payload: { pair, marketinfo } } = action
- return extend(metamaskState, {
- tokenExchangeRates: {
- ...metamaskState.tokenExchangeRates,
- [pair]: marketinfo,
- },
- })
-
case actions.UPDATE_TOKENS:
return extend(metamaskState, {
tokens: action.newTokens,
@@ -358,7 +351,7 @@ function reduceMetamask (state, action) {
welcomeScreenSeen: true,
})
- case action.SET_CURRENT_LOCALE:
+ case actions.SET_CURRENT_LOCALE:
return extend(metamaskState, {
currentLocale: action.value,
})
diff --git a/ui/app/root.js b/ui/app/root.js
index 21d6d1829..09deae1b1 100644
--- a/ui/app/root.js
+++ b/ui/app/root.js
@@ -1,22 +1,23 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const Provider = require('react-redux').Provider
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const { Provider } = require('react-redux')
const h = require('react-hyperscript')
const SelectedApp = require('./select-app')
-module.exports = Root
-
-inherits(Root, Component)
-function Root () { Component.call(this) }
-
-Root.prototype.render = function () {
- return (
+class Root extends Component {
+ render () {
+ const { store } = this.props
- h(Provider, {
- store: this.props.store,
- }, [
- h(SelectedApp),
- ])
+ return (
+ h(Provider, { store }, [
+ h(SelectedApp),
+ ])
+ )
+ }
+}
- )
+Root.propTypes = {
+ store: PropTypes.object,
}
+
+module.exports = Root
diff --git a/ui/app/routes.js b/ui/app/routes.js
new file mode 100644
index 000000000..4b3f8f4d8
--- /dev/null
+++ b/ui/app/routes.js
@@ -0,0 +1,49 @@
+const DEFAULT_ROUTE = '/'
+const UNLOCK_ROUTE = '/unlock'
+const SETTINGS_ROUTE = '/settings'
+const INFO_ROUTE = '/settings/info'
+const REVEAL_SEED_ROUTE = '/seed'
+const CONFIRM_SEED_ROUTE = '/confirm-seed'
+const RESTORE_VAULT_ROUTE = '/restore-vault'
+const ADD_TOKEN_ROUTE = '/add-token'
+const NEW_ACCOUNT_ROUTE = '/new-account'
+const IMPORT_ACCOUNT_ROUTE = '/new-account/import'
+const SEND_ROUTE = '/send'
+const CONFIRM_TRANSACTION_ROUTE = '/confirm-transaction'
+const SIGNATURE_REQUEST_ROUTE = '/confirm-transaction/signature-request'
+const NOTICE_ROUTE = '/notice'
+const WELCOME_ROUTE = '/welcome'
+const INITIALIZE_ROUTE = '/initialize'
+const INITIALIZE_CREATE_PASSWORD_ROUTE = '/initialize/create-password'
+const INITIALIZE_IMPORT_ACCOUNT_ROUTE = '/initialize/import-account'
+const INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE = '/initialize/import-with-seed-phrase'
+const INITIALIZE_UNIQUE_IMAGE_ROUTE = '/initialize/unique-image'
+const INITIALIZE_NOTICE_ROUTE = '/initialize/notice'
+const INITIALIZE_BACKUP_PHRASE_ROUTE = '/initialize/backup-phrase'
+const INITIALIZE_CONFIRM_SEED_ROUTE = '/initialize/confirm-phrase'
+
+module.exports = {
+ DEFAULT_ROUTE,
+ UNLOCK_ROUTE,
+ SETTINGS_ROUTE,
+ INFO_ROUTE,
+ REVEAL_SEED_ROUTE,
+ CONFIRM_SEED_ROUTE,
+ RESTORE_VAULT_ROUTE,
+ ADD_TOKEN_ROUTE,
+ NEW_ACCOUNT_ROUTE,
+ IMPORT_ACCOUNT_ROUTE,
+ SEND_ROUTE,
+ CONFIRM_TRANSACTION_ROUTE,
+ NOTICE_ROUTE,
+ SIGNATURE_REQUEST_ROUTE,
+ WELCOME_ROUTE,
+ INITIALIZE_ROUTE,
+ INITIALIZE_CREATE_PASSWORD_ROUTE,
+ INITIALIZE_IMPORT_ACCOUNT_ROUTE,
+ INITIALIZE_IMPORT_WITH_SEED_PHRASE_ROUTE,
+ INITIALIZE_UNIQUE_IMAGE_ROUTE,
+ INITIALIZE_NOTICE_ROUTE,
+ INITIALIZE_BACKUP_PHRASE_ROUTE,
+ INITIALIZE_CONFIRM_SEED_ROUTE,
+}
diff --git a/ui/app/select-app.js b/ui/app/select-app.js
index 101eb1cf6..808f9ba56 100644
--- a/ui/app/select-app.js
+++ b/ui/app/select-app.js
@@ -2,11 +2,12 @@ const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
+const { HashRouter } = require('react-router-dom')
const App = require('./app')
const OldApp = require('../../old-ui/app/app')
const { autoAddToBetaUI } = require('./selectors')
const { setFeatureFlag, setNetworkEndpoints } = require('./actions')
-const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
const I18nProvider = require('./i18n-provider')
function mapStateToProps (state) {
@@ -63,7 +64,12 @@ SelectedApp.prototype.render = function () {
// const Selected = betaUI || isMascara || firstTime ? App : OldApp
const { betaUI, isMascara } = this.props
- const Selected = betaUI || isMascara ? h(I18nProvider, [ h(App) ]) : h(OldApp)
- return Selected
+ return betaUI || isMascara
+ ? h(HashRouter, {
+ hashType: 'noslash',
+ }, [
+ h(I18nProvider, [ h(App) ]),
+ ])
+ : h(OldApp)
}
diff --git a/ui/app/selectors.js b/ui/app/selectors.js
index 2bdc39004..60cc264da 100644
--- a/ui/app/selectors.js
+++ b/ui/app/selectors.js
@@ -62,22 +62,15 @@ function getSelectedToken (state) {
}
function getSelectedTokenExchangeRate (state) {
- const tokenExchangeRates = state.metamask.tokenExchangeRates
+ const contractExchangeRates = state.metamask.contractExchangeRates
const selectedToken = getSelectedToken(state) || {}
- const { symbol = '' } = selectedToken
-
- const pair = `${symbol.toLowerCase()}_eth`
- const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
-
- return tokenExchangeRate
+ const { address } = selectedToken
+ return contractExchangeRates[address] || 0
}
-function getTokenExchangeRate (state, tokenSymbol) {
- const pair = `${tokenSymbol.toLowerCase()}_eth`
- const tokenExchangeRates = state.metamask.tokenExchangeRates
- const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
-
- return tokenExchangeRate
+function getTokenExchangeRate (state, address) {
+ const contractExchangeRates = state.metamask.contractExchangeRates
+ return contractExchangeRates[address] || 0
}
function conversionRateSelector (state) {
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index 0f2997fb2..bd00b186e 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -30,6 +30,7 @@ const {
getGasTotal,
} = require('./components/send/send-utils')
const { isValidAddress } = require('./util')
+const { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } = require('./routes')
SendTransactionScreen.contextTypes = {
t: PropTypes.func,
@@ -87,17 +88,6 @@ SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
}
SendTransactionScreen.prototype.componentWillMount = function () {
- const {
- updateTokenExchangeRate,
- selectedToken = {},
- } = this.props
-
- const { symbol } = selectedToken || {}
-
- if (symbol) {
- updateTokenExchangeRate(symbol)
- }
-
this.updateGas()
}
@@ -182,7 +172,7 @@ SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) {
}
SendTransactionScreen.prototype.renderHeader = function () {
- const { selectedToken, clearSend, goHome } = this.props
+ const { selectedToken, clearSend, history } = this.props
return h('div.page-container__header', [
@@ -193,7 +183,7 @@ SendTransactionScreen.prototype.renderHeader = function () {
h('div.page-container__header-close', {
onClick: () => {
clearSend()
- goHome()
+ history.push(DEFAULT_ROUTE)
},
}),
@@ -254,7 +244,6 @@ SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
const {
updateSendTo,
updateSendErrors,
- from: {address: from},
} = this.props
let toError = null
@@ -262,8 +251,6 @@ SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
toError = this.context.t('required')
} else if (!isValidAddress(to)) {
toError = this.context.t('invalidAddressRecipient')
- } else if (to === from) {
- toError = this.context.t('fromToSame')
}
updateSendTo(to, nickname)
@@ -498,22 +485,22 @@ SendTransactionScreen.prototype.renderForm = function () {
SendTransactionScreen.prototype.renderFooter = function () {
const {
- goHome,
clearSend,
gasTotal,
tokenBalance,
selectedToken,
errors: { amount: amountError, to: toError },
+ history,
} = this.props
- const missingTokenBalance = selectedToken && !tokenBalance
+ const missingTokenBalance = selectedToken && (tokenBalance === null || tokenBalance === undefined)
const noErrors = !amountError && toError === null
return h('div.page-container__footer', [
h('button.btn-secondary--lg.page-container__footer-button', {
onClick: () => {
clearSend()
- goHome()
+ history.push(DEFAULT_ROUTE)
},
}, this.context.t('cancel')),
h('button.btn-primary--lg.page-container__footer-button', {
@@ -579,12 +566,17 @@ SendTransactionScreen.prototype.getEditedTx = function () {
data,
})
} else {
- const data = unapprovedTxs[editingTransactionId].txParams.data
+ const { data } = unapprovedTxs[editingTransactionId].txParams
+
Object.assign(editingTx.txParams, {
value: ethUtil.addHexPrefix(amount),
to: ethUtil.addHexPrefix(to),
data,
})
+
+ if (typeof editingTx.txParams.data === 'undefined') {
+ delete editingTx.txParams.data
+ }
}
return editingTx
@@ -619,7 +611,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
if (editingTransactionId) {
const editedTx = this.getEditedTx()
-
updateTx(editedTx)
} else {
@@ -643,4 +634,6 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
? signTokenTx(selectedToken.address, to, amount, txParams)
: signTx(txParams)
}
+
+ this.props.history.push(CONFIRM_TRANSACTION_ROUTE)
}
diff --git a/ui/app/token-util.js b/ui/app/token-util.js
index f84051ef5..920442bfc 100644
--- a/ui/app/token-util.js
+++ b/ui/app/token-util.js
@@ -1,14 +1,6 @@
-const abi = require('human-standard-token-abi')
-const Eth = require('ethjs-query')
-const EthContract = require('ethjs-contract')
-
-const tokenInfoGetter = function () {
- if (typeof global.ethereumProvider === 'undefined') return
-
- const eth = new Eth(global.ethereumProvider)
- const contract = new EthContract(eth)
- const TokenContract = contract(abi)
+const util = require('./util')
+function tokenInfoGetter () {
const tokens = {}
return async (address) => {
@@ -16,18 +8,35 @@ const tokenInfoGetter = function () {
return tokens[address]
}
- const contract = TokenContract.at(address)
+ tokens[address] = await getSymbolAndDecimals(address)
- const result = await Promise.all([
- contract.symbol(),
- contract.decimals(),
- ])
+ return tokens[address]
+ }
+}
- const [ symbol = [], decimals = [] ] = result
+async function getSymbolAndDecimals (tokenAddress, existingTokens = []) {
+ const existingToken = existingTokens.find(({ address }) => tokenAddress === address)
+ if (existingToken) {
+ return existingToken
+ }
+
+ let result = []
+ try {
+ const token = util.getContractAtAddress(tokenAddress)
+
+ result = await Promise.all([
+ token.symbol(),
+ token.decimals(),
+ ])
+ } catch (err) {
+ console.log(`symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, err)
+ }
- tokens[address] = { symbol: symbol[0], decimals: decimals[0] }
+ const [ symbol = [], decimals = [] ] = result
- return tokens[address]
+ return {
+ symbol: symbol[0] || null,
+ decimals: decimals[0] && decimals[0].toString() || null,
}
}
@@ -42,4 +51,5 @@ function calcTokenAmount (value, decimals) {
module.exports = {
tokenInfoGetter,
calcTokenAmount,
+ getSymbolAndDecimals,
}
diff --git a/ui/app/unlock.js b/ui/app/unlock.js
index 84d8b7e7c..099e5f9c6 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -6,8 +6,9 @@ const connect = require('react-redux').connect
const actions = require('./actions')
const getCaretCoordinates = require('textarea-caret')
const EventEmitter = require('events').EventEmitter
-const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
-const environmentType = require('../../app/scripts/lib/environment-type')
+const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
+const { getEnvironmentType } = require('../../app/scripts/lib/util')
+const { ENVIRONMENT_TYPE_POPUP } = require('../../app/scripts/lib/enums')
const Mascot = require('./components/mascot')
@@ -77,7 +78,7 @@ UnlockScreen.prototype.render = function () {
h('p.pointer', {
onClick: () => {
this.props.dispatch(actions.markPasswordForgotten())
- if (environmentType() === 'popup') {
+ if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) {
global.platform.openExtensionInBrowser()
}
},
diff --git a/ui/app/util.js b/ui/app/util.js
index 800ccb218..8e9390dfb 100644
--- a/ui/app/util.js
+++ b/ui/app/util.js
@@ -57,6 +57,7 @@ module.exports = {
isInvalidChecksumAddress,
allNull,
getTokenAddressFromTokenObject,
+ checksumAddress,
}
function valuesFor (obj) {
@@ -67,7 +68,7 @@ function valuesFor (obj) {
function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includeHex = true) {
if (!address) return ''
- let checked = ethUtil.toChecksumAddress(address)
+ let checked = checksumAddress(address)
if (!includeHex) {
checked = ethUtil.stripHexPrefix(checked)
}
@@ -76,7 +77,7 @@ function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includ
function miniAddressSummary (address) {
if (!address) return ''
- var checked = ethUtil.toChecksumAddress(address)
+ var checked = checksumAddress(address)
return checked ? checked.slice(0, 4) + '...' + checked.slice(-4) : '...'
}
@@ -271,6 +272,7 @@ function exportAsFile (filename, data) {
window.navigator.msSaveBlob(blob, filename)
} else {
const elem = window.document.createElement('a')
+ elem.target = '_blank'
elem.href = window.URL.createObjectURL(blob)
elem.download = filename
document.body.appendChild(elem)
@@ -286,3 +288,13 @@ function allNull (obj) {
function getTokenAddressFromTokenObject (token) {
return Object.values(token)[0].address.toLowerCase()
}
+
+/**
+ * Safely checksumms a potentially-null address
+ *
+ * @param {String} [address] - address to checksum
+ * @returns {String} - checksummed address
+ */
+function checksumAddress (address) {
+ return address ? ethUtil.toChecksumAddress(address) : ''
+}
diff --git a/ui/app/welcome-screen.js b/ui/app/welcome-screen.js
index cdbb6dba8..2fa244d9f 100644
--- a/ui/app/welcome-screen.js
+++ b/ui/app/welcome-screen.js
@@ -3,21 +3,35 @@ import h from 'react-hyperscript'
import { Component } from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
+import { withRouter } from 'react-router-dom'
+import { compose } from 'recompose'
import {closeWelcomeScreen} from './actions'
import Mascot from './components/mascot'
+import { INITIALIZE_CREATE_PASSWORD_ROUTE } from './routes'
class WelcomeScreen extends Component {
static propTypes = {
closeWelcomeScreen: PropTypes.func.isRequired,
+ welcomeScreenSeen: PropTypes.bool,
+ history: PropTypes.object,
}
- constructor(props) {
+ constructor (props) {
super(props)
this.animationEventEmitter = new EventEmitter()
}
+ componentWillMount () {
+ const { history, welcomeScreenSeen } = this.props
+
+ if (welcomeScreenSeen) {
+ history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
+ }
+ }
+
initiateAccountCreation = () => {
this.props.closeWelcomeScreen()
+ this.props.history.push(INITIALIZE_CREATE_PASSWORD_ROUTE)
}
render () {
@@ -48,9 +62,18 @@ class WelcomeScreen extends Component {
}
}
-export default connect(
- null,
- dispatch => ({
- closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
- })
+const mapStateToProps = ({ metamask: { welcomeScreenSeen } }) => {
+ return {
+ welcomeScreenSeen,
+ }
+}
+
+export default compose(
+ withRouter,
+ connect(
+ mapStateToProps,
+ dispatch => ({
+ closeWelcomeScreen: () => dispatch(closeWelcomeScreen()),
+ })
+ )
)(WelcomeScreen)
diff --git a/ui/i18n-helper.js b/ui/i18n-helper.js
index 3eee55ae9..79aa93116 100644
--- a/ui/i18n-helper.js
+++ b/ui/i18n-helper.js
@@ -11,8 +11,9 @@ const getMessage = (locale, key, substitutions) => {
const { current, en } = locale
const entry = current[key] || en[key]
if (!entry) {
- log.error(`Translator - Unable to find value for "${key}"`)
// throw new Error(`Translator - Unable to find value for "${key}"`)
+ log.error(`Translator - Unable to find value for "${key}"`)
+ return `[${key}]`
}
let phrase = entry.message
// perform substitutions
diff --git a/ui/index.js b/ui/index.js
index 746e28eab..075faf66d 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -5,9 +5,12 @@ const actions = require('./app/actions')
const configureStore = require('./app/store')
const txHelper = require('./lib/tx-helper')
const { fetchLocale } = require('./i18n-helper')
-const { OLD_UI_NETWORK_TYPE, BETA_UI_NETWORK_TYPE } = require('../app/scripts/config').enums
+const {
+ OLD_UI_NETWORK_TYPE,
+ BETA_UI_NETWORK_TYPE,
+} = require('../app/scripts/controllers/network/enums')
-global.log = require('loglevel')
+const log = require('loglevel')
module.exports = launchMetamaskUi
diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js
index 31498a3a9..7fadbceff 100644
--- a/ui/lib/icon-factory.js
+++ b/ui/lib/icon-factory.js
@@ -1,6 +1,6 @@
var iconFactory
const isValidAddress = require('ethereumjs-util').isValidAddress
-const toChecksumAddress = require('ethereumjs-util').toChecksumAddress
+const { checksumAddress } = require('../app/util')
const contractMap = require('eth-contract-metadata')
module.exports = function (jazzicon) {
@@ -16,7 +16,7 @@ function IconFactory (jazzicon) {
}
IconFactory.prototype.iconForAddress = function (address, diameter) {
- const addr = toChecksumAddress(address)
+ const addr = checksumAddress(address)
if (iconExistsFor(addr)) {
return imageElFor(addr)
}
diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js
index de3f00d2d..0a6f55a63 100644
--- a/ui/lib/tx-helper.js
+++ b/ui/lib/tx-helper.js
@@ -1,4 +1,5 @@
const valuesFor = require('../app/util').valuesFor
+const log = require('loglevel')
module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network) {
log.debug('tx-helper called with params:')
diff --git a/yarn.lock b/yarn.lock
index cda23f3c3..026e0d0d1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,54 +2,77 @@
# yarn lockfile v1
-"@babel/code-frame@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz#473d021ecc573a2cce1c07d5b509d5215f46ba35"
+"@babel/code-frame@7.0.0-beta.44", "@babel/code-frame@^7.0.0-beta.40":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9"
dependencies:
- chalk "^2.0.0"
- esutils "^2.0.2"
- js-tokens "^3.0.0"
+ "@babel/highlight" "7.0.0-beta.44"
+
+"@babel/generator@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42"
+ dependencies:
+ "@babel/types" "7.0.0-beta.44"
+ jsesc "^2.5.1"
+ lodash "^4.2.0"
+ source-map "^0.5.0"
+ trim-right "^1.0.1"
+
+"@babel/helper-function-name@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd"
+ dependencies:
+ "@babel/helper-get-function-arity" "7.0.0-beta.44"
+ "@babel/template" "7.0.0-beta.44"
+ "@babel/types" "7.0.0-beta.44"
-"@babel/helper-function-name@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz#afe63ad799209989348b1109b44feb66aa245f57"
+"@babel/helper-get-function-arity@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15"
dependencies:
- "@babel/helper-get-function-arity" "7.0.0-beta.31"
- "@babel/template" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.44"
-"@babel/helper-get-function-arity@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz#1176d79252741218e0aec872ada07efb2b37a493"
+"@babel/helper-split-export-declaration@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc"
dependencies:
- "@babel/types" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.44"
-"@babel/template@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
+"@babel/highlight@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ chalk "^2.0.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
+"@babel/template@7.0.0-beta.44":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.44"
+ "@babel/types" "7.0.0-beta.44"
+ babylon "7.0.0-beta.44"
lodash "^4.2.0"
-"@babel/traverse@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.31.tgz#db399499ad74aefda014f0c10321ab255134b1df"
+"@babel/traverse@^7.0.0-beta.40":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/helper-function-name" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
- debug "^3.0.1"
- globals "^10.0.0"
+ "@babel/code-frame" "7.0.0-beta.44"
+ "@babel/generator" "7.0.0-beta.44"
+ "@babel/helper-function-name" "7.0.0-beta.44"
+ "@babel/helper-split-export-declaration" "7.0.0-beta.44"
+ "@babel/types" "7.0.0-beta.44"
+ babylon "7.0.0-beta.44"
+ debug "^3.1.0"
+ globals "^11.1.0"
invariant "^2.2.0"
lodash "^4.2.0"
-"@babel/types@7.0.0-beta.31":
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.31.tgz#42c9c86784f674c173fb21882ca9643334029de4"
+"@babel/types@7.0.0-beta.44", "@babel/types@^7.0.0-beta.40":
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757"
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
@@ -81,9 +104,19 @@
progress "2.0.0"
proxy-from-env "^1.0.0"
+"@sindresorhus/is@^0.7.0":
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
+
+"@sinonjs/formatio@^2.0.0":
+ version "2.0.0"
+ resolved "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
+ dependencies:
+ samsam "1.3.0"
+
"@types/node@*":
- version "8.5.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
+ version "9.6.2"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.2.tgz#e49ac1adb458835e95ca6487bc20f916b37aff23"
JSONStream@^0.8.4:
version "0.8.4"
@@ -108,17 +141,18 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
abi-decoder@^1.0.9:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/abi-decoder/-/abi-decoder-1.0.9.tgz#6bcfd86f7f63fbec8573d9778b3a4f92bb92e01f"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/abi-decoder/-/abi-decoder-1.1.0.tgz#07f063e2a8f0ca1750fe4cd0dd112f6103ce3455"
dependencies:
babel-core "^6.23.1"
babel-loader "^6.3.2"
babel-plugin-add-module-exports "^0.2.1"
babel-plugin-transform-es2015-modules-amd "^6.22.0"
+ babel-plugin-transform-runtime "^6.23.0"
babel-preset-es2015 "^6.22.0"
chai "^3.5.0"
web3 "^0.18.4"
- webpack "^2.2.1"
+ webpack "^2.7.0"
abstract-leveldown@~2.6.0:
version "2.6.3"
@@ -132,19 +166,16 @@ abstract-leveldown@~2.7.1:
dependencies:
xtend "~4.0.0"
-accepts@1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca"
+accepts@~1.3.4, accepts@~1.3.5:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
dependencies:
- mime-types "~2.1.11"
+ mime-types "~2.1.18"
negotiator "0.6.1"
-accepts@~1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f"
- dependencies:
- mime-types "~2.1.16"
- negotiator "0.6.1"
+accounting@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/accounting/-/accounting-0.4.1.tgz#87dd4103eff7f4460f1e186f5c677ed6cf566883"
acorn-dynamic-import@^2.0.0:
version "2.0.2"
@@ -164,16 +195,16 @@ acorn-jsx@^3.0.0:
dependencies:
acorn "^3.0.4"
-acorn-node@^1.3.0:
+acorn-node@^1.2.0, acorn-node@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.3.0.tgz#5f86d73346743810ef1269b901dbcbded020861b"
dependencies:
acorn "^5.4.1"
xtend "^4.0.1"
-acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.2.1:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
+acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.3.0, acorn@^5.4.1, acorn@^5.5.0:
+ version "5.5.3"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
acorn@^3.0.4:
version "3.3.0"
@@ -183,10 +214,6 @@ acorn@^4.0.3:
version "4.0.13"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
-acorn@^5.3.0, acorn@^5.4.1:
- version "5.5.3"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
-
addressparser@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746"
@@ -195,10 +222,6 @@ aes-js@^0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d"
-after@0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627"
-
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
@@ -224,6 +247,10 @@ ajv-keywords@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+ajv-keywords@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
+
ajv@^4.7.0, ajv@^4.9.1:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
@@ -240,6 +267,15 @@ ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
+ajv@^6.0.1:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.4.0.tgz#d3aff78e9277549771daf0164cff48482b754fc6"
+ dependencies:
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+ uri-js "^3.0.2"
+
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@@ -263,14 +299,24 @@ amqplib@^0.5.2:
safe-buffer "^5.0.1"
ansi-colors@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.0.1.tgz#e94c6c306005af8b482240241e2f3dea4b855ff3"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9"
dependencies:
ansi-wrap "^0.1.0"
+ansi-cyan@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873"
+ dependencies:
+ ansi-wrap "0.1.0"
+
+ansi-escapes@^1.0.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
ansi-escapes@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
ansi-gray@^0.1.1:
version "0.1.1"
@@ -278,6 +324,12 @@ ansi-gray@^0.1.1:
dependencies:
ansi-wrap "0.1.0"
+ansi-red@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c"
+ dependencies:
+ ansi-wrap "0.1.0"
+
ansi-regex@^0.2.0, ansi-regex@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9"
@@ -298,18 +350,16 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
-ansi-styles@^3.1.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
- dependencies:
- color-convert "^1.9.0"
-
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"
+ansi-styles@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
+
ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
@@ -318,6 +368,10 @@ ansicolors@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
+any-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
+
any-promise@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-0.1.0.tgz#830b680aa7e56f33451d4b049f3bd8044498ee27"
@@ -368,11 +422,18 @@ are-we-there-yet@~1.1.2:
readable-stream "^2.0.6"
argparse@^1.0.7:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
dependencies:
sprintf-js "~1.0.2"
+arr-diff@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
+ dependencies:
+ arr-flatten "^1.0.1"
+ array-slice "^0.2.3"
+
arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@@ -399,6 +460,10 @@ arr-map@^2.0.0, arr-map@^2.0.2:
dependencies:
make-iterator "^1.0.0"
+arr-union@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d"
+
arr-union@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
@@ -489,10 +554,6 @@ array-unique@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
-arraybuffer.slice@0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca"
-
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
@@ -510,8 +571,8 @@ asmcrypto.js@0.22.0:
resolved "https://registry.yarnpkg.com/asmcrypto.js/-/asmcrypto.js-0.22.0.tgz#38fc1440884d802c7bd37d1d23c2b26a5cd5d2d2"
asn1.js@^4.0.0:
- version "4.9.2"
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
+ version "4.10.1"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
dependencies:
bn.js "^4.0.0"
inherits "^2.0.1"
@@ -536,21 +597,25 @@ assert@^1.1.1, assert@^1.4.0:
util "0.10.3"
assertion-error@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+ast-types@0.10.1:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd"
+
+ast-types@0.11.3, ast-types@0.x.x:
+ version "0.11.3"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8"
+
ast-types@0.9.6:
version "0.9.6"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
-ast-types@0.x.x:
- version "0.11.2"
- resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.2.tgz#cc4e1d15a36b39979a1986fe1e91321cbfae7783"
-
astw@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917"
@@ -558,8 +623,8 @@ astw@^2.0.0:
acorn "^4.0.3"
async-done@^1.2.0, async-done@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.3.tgz#6c7abc7d61ca27fe6f1f2ba3206ea9ae60a43983"
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.4.tgz#17b0fcefb9a33cb9de63daa8904c0a65bd535fa0"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.2"
@@ -576,7 +641,7 @@ async-eventemitter@^0.2.2:
dependencies:
async "^2.4.0"
-async-eventemitter@ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c:
+"async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c":
version "0.2.3"
resolved "https://codeload.github.com/ahultgren/async-eventemitter/tar.gz/fa06e39e56786ba541c180061dbf2c0a5bbf951c"
dependencies:
@@ -600,11 +665,52 @@ async-settle@^1.0.0:
dependencies:
async-done "^1.2.2"
-async@^1.4.0, async@^1.4.2:
+async.queue@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.queue/-/async.queue-0.5.2.tgz#8d5d90812e1481066bc0904e8cc1712b17c3bd7c"
+ dependencies:
+ async.util.queue "0.5.2"
+
+async.util.arrayeach@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz#58c4e98028d55d69bfb05aeb3af44e0a555a829c"
+
+async.util.isarray@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.isarray/-/async.util.isarray-0.5.2.tgz#e62dac8f2636f65875dcf7521c2d24d0dfb2bbdf"
+
+async.util.map@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.map/-/async.util.map-0.5.2.tgz#e588ef86e0b3ab5f027d97af4d6835d055ca69d6"
+
+async.util.noop@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.noop/-/async.util.noop-0.5.2.tgz#bdd62b97cb0aa3f60b586ad148468698975e58b9"
+
+async.util.onlyonce@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz#b8e6fc004adc923164d79e32f2813ee465c24ff2"
+
+async.util.queue@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.queue/-/async.util.queue-0.5.2.tgz#57f65abe1a3cdf273d31abd28ab95425f8222ee5"
+ dependencies:
+ async.util.arrayeach "0.5.2"
+ async.util.isarray "0.5.2"
+ async.util.map "0.5.2"
+ async.util.noop "0.5.2"
+ async.util.onlyonce "0.5.2"
+ async.util.setimmediate "0.5.2"
+
+async.util.setimmediate@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz#2812ebabf2a58027758d4bc7793d1ccfaf10255f"
+
+async@^1.4.0, async@^1.4.2, async@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
+async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
@@ -633,8 +739,8 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
atob@^2.0.0:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.0.tgz#ab2b150e51d7b122b9efc8d7340c06b6c41076bc"
atob@~1.1.0:
version "1.1.3"
@@ -652,14 +758,14 @@ autoprefixer@^6.0.0:
postcss-value-parser "^3.2.3"
autoprefixer@^8.0.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-8.1.0.tgz#374cf35be1c0e8fce97408d876f95f66f5cb4641"
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-8.2.0.tgz#1e49b611b31a5259b86b7a6b2b1b8faf091abe2a"
dependencies:
- browserslist "^3.1.1"
- caniuse-lite "^1.0.30000810"
+ browserslist "^3.2.0"
+ caniuse-lite "^1.0.30000817"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
- postcss "^6.0.19"
+ postcss "^6.0.20"
postcss-value-parser "^3.2.3"
await-semaphore@^0.1.1:
@@ -675,8 +781,8 @@ aws-sign2@~0.7.0:
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.2.1, aws4@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289"
axios@^0.15.3:
version "0.15.3"
@@ -717,19 +823,19 @@ babel-core@^6.0.14, babel-core@^6.23.1, babel-core@^6.24.1, babel-core@^6.26.0:
source-map "^0.5.6"
babel-eslint@^8.0.0:
- version "8.1.2"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.1.2.tgz#a39230b0c20ecbaa19a35d5633bf9b9ca2c8116f"
+ version "8.2.2"
+ resolved "http://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.2.tgz#1102273354c6f0b29b4ea28a65f97d122296b68b"
dependencies:
- "@babel/code-frame" "7.0.0-beta.31"
- "@babel/traverse" "7.0.0-beta.31"
- "@babel/types" "7.0.0-beta.31"
- babylon "7.0.0-beta.31"
+ "@babel/code-frame" "^7.0.0-beta.40"
+ "@babel/traverse" "^7.0.0-beta.40"
+ "@babel/types" "^7.0.0-beta.40"
+ babylon "^7.0.0-beta.40"
eslint-scope "~3.7.1"
eslint-visitor-keys "^1.0.0"
babel-generator@^6.18.0, babel-generator@^6.26.0:
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5"
+ version "6.26.1"
+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
dependencies:
babel-messages "^6.23.0"
babel-runtime "^6.26.0"
@@ -737,7 +843,7 @@ babel-generator@^6.18.0, babel-generator@^6.26.0:
detect-indent "^4.0.0"
jsesc "^1.3.0"
lodash "^4.17.4"
- source-map "^0.5.6"
+ source-map "^0.5.7"
trim-right "^1.0.1"
babel-helper-bindify-decorators@^6.24.1:
@@ -1180,7 +1286,7 @@ babel-plugin-transform-export-extensions@^6.22.0:
babel-plugin-syntax-export-extensions "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-flow-strip-types@^6.22.0:
+babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.8.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
dependencies:
@@ -1291,7 +1397,7 @@ babel-preset-env@^1.3.2:
invariant "^2.2.2"
semver "^5.3.0"
-babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.24.0, babel-preset-es2015@^6.6.0:
+babel-preset-es2015@^6.22.0, babel-preset-es2015@^6.6.0, babel-preset-es2015@^6.9.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
dependencies:
@@ -1345,7 +1451,7 @@ babel-preset-stage-0@^6.24.1:
babel-plugin-transform-function-bind "^6.22.0"
babel-preset-stage-1 "^6.24.1"
-babel-preset-stage-1@^6.24.1:
+babel-preset-stage-1@^6.24.1, babel-preset-stage-1@^6.5.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0"
dependencies:
@@ -1372,7 +1478,7 @@ babel-preset-stage-3@^6.24.1:
babel-plugin-transform-exponentiation-operator "^6.24.1"
babel-plugin-transform-object-rest-spread "^6.22.0"
-babel-register@^6.26.0, babel-register@^6.7.2:
+babel-register@^6.26.0, babel-register@^6.7.2, babel-register@^6.9.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
dependencies:
@@ -1435,11 +1541,11 @@ babelify@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3"
-babylon@7.0.0-beta.31:
- version "7.0.0-beta.31"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f"
+babylon@7.0.0-beta.44, babylon@^7.0.0-beta.30, babylon@^7.0.0-beta.40:
+ version "7.0.0-beta.44"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d"
-babylon@^6.18.0:
+babylon@^6.17.3, babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
@@ -1492,12 +1598,8 @@ base64-arraybuffer@0.1.5:
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
base64-js@^1.0.2:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
-
-base64id@0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/base64id/-/base64id-0.1.0.tgz#02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f"
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801"
base64id@1.0.0:
version "1.0.0"
@@ -1574,6 +1676,10 @@ binary-extensions@^1.0.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
+binaryextensions@2:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
+
binaryextensions@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-1.0.1.tgz#1e637488b35b58bda5f4774bf96a5212a8c90755"
@@ -1583,8 +1689,8 @@ bindings@^1.2.1:
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7"
bip39@^2.2.0, bip39@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.4.0.tgz#a0b8adbf163f53495f00f05d9ede7c25369ccf13"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235"
dependencies:
create-hash "^1.1.0"
pbkdf2 "^3.0.9"
@@ -1605,10 +1711,11 @@ bitsyntax@~0.0.4:
buffer-more-ints "0.0.2"
bl@^1.2.0, bl@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
dependencies:
- readable-stream "^2.0.5"
+ readable-stream "^2.3.5"
+ safe-buffer "^5.1.1"
bl@~1.1.2:
version "1.1.2"
@@ -1634,7 +1741,7 @@ bn.js@4.11.6:
version "4.11.6"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.3, bn.js@^4.11.7, bn.js@^4.4.0, bn.js@^4.8.0:
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.7, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
@@ -1696,9 +1803,9 @@ boron@^0.2.3:
dependencies:
domkit "^0.0.1"
-brace-expansion@^1.1.7:
- version "1.1.8"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+brace-expansion@^1.0.0, brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
@@ -1717,33 +1824,15 @@ braces@^1.8.2:
preserve "^0.2.0"
repeat-element "^1.1.2"
-braces@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e"
- dependencies:
- arr-flatten "^1.1.0"
- array-unique "^0.3.2"
- define-property "^1.0.0"
- extend-shallow "^2.0.1"
- fill-range "^4.0.0"
- isobject "^3.0.1"
- repeat-element "^1.1.2"
- snapdragon "^0.8.1"
- snapdragon-node "^2.0.1"
- split-string "^3.0.2"
- to-regex "^3.0.1"
-
-braces@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb"
+braces@^2.3.0, braces@^2.3.1:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
dependencies:
arr-flatten "^1.1.0"
array-unique "^0.3.2"
- define-property "^1.0.0"
extend-shallow "^2.0.1"
fill-range "^4.0.0"
isobject "^3.0.1"
- kind-of "^6.0.2"
repeat-element "^1.1.2"
snapdragon "^0.8.1"
snapdragon-node "^2.0.1"
@@ -1751,12 +1840,12 @@ braces@^2.3.1:
to-regex "^3.0.1"
brfs@^1.4.3:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.4.3.tgz#db675d6f5e923e6df087fca5859c9090aaed3216"
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.5.0.tgz#a3822ed7a65723e056f89ff4b58e8abc63658f03"
dependencies:
quote-stream "^1.0.1"
resolve "^1.1.5"
- static-module "^1.1.0"
+ static-module "^2.2.0"
through2 "^2.0.0"
brorand@^1.0.1:
@@ -1774,12 +1863,13 @@ browser-pack@^5.0.1:
umd "^3.0.0"
browser-pack@^6.0.1:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531"
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.1.0.tgz#c34ba10d0b9ce162b5af227c7131c92c2ecd5774"
dependencies:
JSONStream "^1.0.3"
- combine-source-map "~0.7.1"
+ combine-source-map "~0.8.0"
defined "^1.0.0"
+ safe-buffer "^5.1.1"
through2 "^2.0.0"
umd "^3.0.0"
@@ -1799,9 +1889,9 @@ browser-resolve@^1.11.0, browser-resolve@^1.7.0:
dependencies:
resolve "1.1.7"
-browser-stdout@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
+browser-stdout@1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
browser-unpack@^1.2.0:
version "1.2.0"
@@ -1813,8 +1903,8 @@ browser-unpack@^1.2.0:
minimist "^1.1.1"
browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
dependencies:
buffer-xor "^1.0.3"
cipher-base "^1.0.0"
@@ -1881,7 +1971,7 @@ browserify-zlib@^0.2.0, browserify-zlib@~0.2.0:
dependencies:
pako "~1.0.5"
-browserify@^14.0.0, browserify@^14.5.0:
+browserify@^14.5.0:
version "14.5.0"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5"
dependencies:
@@ -1933,7 +2023,7 @@ browserify@^14.0.0, browserify@^14.5.0:
vm-browserify "~0.0.1"
xtend "^4.0.0"
-browserify@^16.1.1:
+browserify@^16.1.0, browserify@^16.1.1:
version "16.1.1"
resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.1.1.tgz#7905ec07e0147c4d90f92001944050a6e1c2844e"
dependencies:
@@ -1994,18 +2084,18 @@ browserslist@^1.1.1, browserslist@^1.1.3, browserslist@^1.7.6:
electron-to-chromium "^1.2.7"
browserslist@^2.1.2:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346"
+ version "2.11.3"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2"
dependencies:
- caniuse-lite "^1.0.30000780"
- electron-to-chromium "^1.3.28"
+ caniuse-lite "^1.0.30000792"
+ electron-to-chromium "^1.3.30"
-browserslist@^3.1.1:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.1.2.tgz#893f29399d640ed35fe06bacd7eb1d78609a47e5"
+browserslist@^3.2.0:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.4.tgz#fb9ad70fd09875137ae943a31ab815ed76896031"
dependencies:
- caniuse-lite "^1.0.30000813"
- electron-to-chromium "^1.3.36"
+ caniuse-lite "^1.0.30000821"
+ electron-to-chromium "^1.3.41"
bs58@^2.0.1:
version "2.0.1"
@@ -2036,6 +2126,10 @@ buffer-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
+buffer-from@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531"
+
buffer-more-ints@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz#26b3885d10fa13db7fc01aae3aab870199e0124c"
@@ -2053,8 +2147,8 @@ buffer@^4.3.0:
isarray "^1.0.0"
buffer@^5.0.2:
- version "5.0.8"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.8.tgz#84daa52e7cf2fa8ce4195bc5cf0f7809e0930b24"
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe"
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
@@ -2109,6 +2203,18 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
+cacheable-request@^2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d"
+ dependencies:
+ clone-response "1.0.2"
+ get-stream "3.0.0"
+ http-cache-semantics "3.8.1"
+ keyv "3.0.0"
+ lowercase-keys "1.0.0"
+ normalize-url "2.0.1"
+ responselike "1.0.2"
+
cached-path-relative@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7"
@@ -2159,16 +2265,12 @@ camelcase@^4.1.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000784.tgz#1be95012d9489c7719074f81aee57dbdffe6361b"
-
-caniuse-lite@^1.0.30000780:
- version "1.0.30000784"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0"
+ version "1.0.30000824"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000824.tgz#bba3ff425296e04caa37fe426259206a7056551b"
-caniuse-lite@^1.0.30000810, caniuse-lite@^1.0.30000813:
- version "1.0.30000814"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000814.tgz#73eb6925ac2e54d495218f1ea0007da3940e488b"
+caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000817, caniuse-lite@^1.0.30000821:
+ version "1.0.30000824"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000824.tgz#de3bc1ba0bff4937302f8cb2a8632a8cc1c07f9a"
caseless@~0.11.0:
version "0.11.0"
@@ -2185,7 +2287,7 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
-"chai@>=1.9.2 <4.0.0", chai@^3.5.0:
+chai@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247"
dependencies:
@@ -2193,7 +2295,7 @@ center-align@^0.1.1:
deep-eql "^0.1.3"
type-detect "^1.0.0"
-chai@^4.1.0:
+chai@^4.1.0, chai@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c"
dependencies:
@@ -2228,15 +2330,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
- dependencies:
- ansi-styles "^3.1.0"
- escape-string-regexp "^1.0.5"
- supports-color "^4.0.0"
-
-chalk@^2.3.1:
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
dependencies:
@@ -2244,6 +2338,14 @@ chalk@^2.3.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+chalk@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
+ dependencies:
+ ansi-styles "~1.0.0"
+ has-color "~0.1.0"
+ strip-ansi "~0.1.0"
+
change-emitter@^0.1.2:
version "0.1.6"
resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515"
@@ -2306,7 +2408,7 @@ chokidar@1.6.1:
optionalDependencies:
fsevents "^1.0.0"
-chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.7.0:
+chokidar@^1.0.0, chokidar@^1.4.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
@@ -2321,9 +2423,9 @@ chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.7.0:
optionalDependencies:
fsevents "^1.0.0"
-chokidar@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7"
+chokidar@^2.0.0, chokidar@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176"
dependencies:
anymatch "^2.0.0"
async-each "^1.0.0"
@@ -2337,7 +2439,7 @@ chokidar@^2.0.0:
readdirp "^2.0.0"
upath "^1.0.0"
optionalDependencies:
- fsevents "^1.0.0"
+ fsevents "^1.1.2"
chromedriver@^2.34.1:
version "2.37.0"
@@ -2365,29 +2467,58 @@ circular-json@^0.5.1:
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.1.tgz#b8942a09e535863dc21b04417a91971e1d9cd91f"
class-utils@^0.3.5:
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.5.tgz#17e793103750f9627b2176ea34cfd1b565903c80"
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
dependencies:
arr-union "^3.1.0"
define-property "^0.2.5"
isobject "^3.0.0"
- lazy-cache "^2.0.2"
static-extend "^0.1.1"
classnames@^2.2.4, classnames@^2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
+cli-cursor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
+cli-spinners@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
+
+cli-table@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+ dependencies:
+ colors "1.0.3"
+
+cli-truncate@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
+ dependencies:
+ slice-ansi "0.0.4"
+ string-width "^1.0.1"
+
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
+cli@~1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14"
+ dependencies:
+ exit "0.1.2"
+ glob "^7.1.1"
+
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -2404,17 +2535,31 @@ cliui@^3.0.3, cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+cliui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
+ dependencies:
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+ wrap-ansi "^2.0.0"
+
clone-buffer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
clone-regexp@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.1.tgz#051805cd33173375d82118fc0918606da39fd60f"
dependencies:
is-regexp "^1.0.0"
is-supported-regexp-flag "^1.0.0"
+clone-response@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
+ dependencies:
+ mimic-response "^1.0.0"
+
clone-stats@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
@@ -2424,20 +2569,20 @@ clone-stats@^1.0.0:
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
clone@^1.0.0, clone@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
clone@^2.0.0, clone@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
cloneable-readable@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117"
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65"
dependencies:
inherits "^2.0.1"
- process-nextick-args "^1.0.6"
- through2 "^2.0.1"
+ process-nextick-args "^2.0.0"
+ readable-stream "^2.3.5"
co@^4.6.0:
version "4.6.0"
@@ -2528,13 +2673,13 @@ colors@0.5.x:
version "0.5.1"
resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
-colors@1.0.x:
+colors@1.0.3, colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@^1.1.0, colors@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794"
combine-lists@^1.0.0:
version "1.0.1"
@@ -2542,6 +2687,15 @@ combine-lists@^1.0.0:
dependencies:
lodash "^4.5.0"
+combine-source-map@^0.8.0, combine-source-map@~0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b"
+ dependencies:
+ convert-source-map "~1.1.0"
+ inline-source-map "~0.6.0"
+ lodash.memoize "~3.0.3"
+ source-map "~0.5.3"
+
combine-source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.6.1.tgz#9b4a09c316033d768e0f11e029fa2730e079ad96"
@@ -2551,18 +2705,9 @@ combine-source-map@~0.6.1:
lodash.memoize "~3.0.3"
source-map "~0.4.2"
-combine-source-map@~0.7.1:
- version "0.7.2"
- resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e"
- dependencies:
- convert-source-map "~1.1.0"
- inline-source-map "~0.6.0"
- lodash.memoize "~3.0.3"
- source-map "~0.5.3"
-
-combined-stream@^1.0.5, combined-stream@~1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
dependencies:
delayed-stream "~1.0.0"
@@ -2576,13 +2721,9 @@ commander@2.9.0:
dependencies:
graceful-readlink ">= 1.0.0"
-commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.12.1:
- version "2.12.2"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
-
-commander@~2.13.0:
- version "2.13.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
+commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.15.0:
+ version "2.15.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
commander@~2.14.1:
version "2.14.1"
@@ -2614,10 +2755,6 @@ component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
-component-emitter@1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3"
-
component-emitter@1.2.1, component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
@@ -2626,19 +2763,19 @@ component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
-compressible@~2.0.11:
- version "2.0.12"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
+compressible@~2.0.13:
+ version "2.0.13"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9"
dependencies:
- mime-db ">= 1.30.0 < 2"
+ mime-db ">= 1.33.0 < 2"
compression@^1.7.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db"
+ version "1.7.2"
+ resolved "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz#aaffbcd6aaf854b44ebb280353d5ad1651f59a69"
dependencies:
accepts "~1.3.4"
bytes "3.0.0"
- compressible "~2.0.11"
+ compressible "~2.0.13"
debug "2.6.9"
on-headers "~1.0.1"
safe-buffer "5.1.1"
@@ -2648,7 +2785,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-concat-stream@1.6.0, concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@~1.6.0:
+concat-stream@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
dependencies:
@@ -2656,6 +2793,15 @@ concat-stream@1.6.0, concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^
readable-stream "^2.2.2"
typedarray "^0.0.6"
+concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.1, concat-stream@~1.6.0:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
+ dependencies:
+ buffer-from "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^2.2.2"
+ typedarray "^0.0.6"
+
concat-stream@~1.5.0, concat-stream@~1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
@@ -2672,15 +2818,15 @@ config-chain@~1.1.5:
proto-list "~1.2.1"
connect@^3.6.0:
- version "3.6.5"
- resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.5.tgz#fb8dde7ba0763877d0ec9df9dac0b4b40e72c7da"
+ version "3.6.6"
+ resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524"
dependencies:
debug "2.6.9"
- finalhandler "1.0.6"
+ finalhandler "1.1.0"
parseurl "~1.3.2"
utils-merge "1.0.1"
-console-browserify@^1.1.0:
+console-browserify@1.1.x, console-browserify@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
dependencies:
@@ -2704,15 +2850,11 @@ content-disposition@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
-content-type-parser@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
-
content-type@~1.0.1, content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-convert-source-map@1.X, convert-source-map@^1.3.0, convert-source-map@^1.5.0:
+convert-source-map@1.X, convert-source-map@^1.5.0, convert-source-map@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
@@ -2749,9 +2891,9 @@ core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
-core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0:
- version "2.5.3"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
+core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
+ version "2.5.5"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b"
core-js@~2.3.0:
version "2.3.0"
@@ -2811,8 +2953,8 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
sha.js "^2.4.8"
create-react-class@^15.6.0:
- version "15.6.2"
- resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
+ version "15.6.3"
+ resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
@@ -2847,6 +2989,16 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
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"
+ dependencies:
+ nice-try "^1.0.4"
+ path-key "^2.0.1"
+ semver "^5.5.0"
+ shebang-command "^1.2.0"
+ which "^1.2.9"
+
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -2947,6 +3099,14 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
dependencies:
cssom "0.3.x"
+currency-formatter@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/currency-formatter/-/currency-formatter-1.4.2.tgz#9da20b3706f7a42daf73b356b09a2a2b76ff3870"
+ dependencies:
+ accounting "^0.4.1"
+ locale-currency "0.0.1"
+ object-assign "^4.1.1"
+
currently-unhandled@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -2971,6 +3131,10 @@ d@1:
dependencies:
es5-ext "^0.10.9"
+dargs@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829"
+
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -2981,6 +3145,18 @@ data-uri-to-buffer@1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835"
+data-urls@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f"
+ dependencies:
+ abab "^1.0.4"
+ whatwg-mimetype "^2.0.0"
+ whatwg-url "^6.4.0"
+
+date-fns@^1.27.2:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
+
date-format@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8"
@@ -2993,6 +3169,10 @@ dateformat@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
+dateformat@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
+
debounce-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/debounce-stream/-/debounce-stream-2.0.0.tgz#1e33400ccff015abd8ec330661a562b68410b08f"
@@ -3006,8 +3186,8 @@ debounce@^1.0.0:
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.1.0.tgz#6a1a4ee2a9dc4b7c24bb012558dbcdb05b37f408"
debug-fabulous@1.X:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.0.0.tgz#57f6648646097b1b0849dcda0017362c1ec00f8b"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e"
dependencies:
debug "3.X"
memoizee "0.4.X"
@@ -3023,24 +3203,18 @@ debug@2, debug@2.6.9, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, de
dependencies:
ms "2.0.0"
-debug@2.2.0, debug@~2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
- dependencies:
- ms "0.7.1"
-
-debug@2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c"
- dependencies:
- ms "0.7.2"
-
-debug@3.1.0, debug@3.X, debug@^3.0.1, debug@^3.1.0, debug@~3.1.0:
+debug@3.1.0, debug@3.X, debug@^3.1.0, debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
ms "2.0.0"
+debug@~2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
+ dependencies:
+ ms "0.7.1"
+
decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -3049,6 +3223,12 @@ decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+decompress-response@^3.2.0, decompress-response@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
+ dependencies:
+ mimic-response "^1.0.0"
+
deep-diff@^0.3.5:
version "0.3.8"
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
@@ -3073,14 +3253,14 @@ deep-equal@~0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d"
+deep-extend@^0.4.0, deep-extend@~0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
+
deep-extend@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803"
-deep-extend@~0.4.0:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
-
deep-freeze-strict@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-freeze-strict/-/deep-freeze-strict-1.1.1.tgz#77d0583ca24a69be4bbd9ac2fae415d55523e5b0"
@@ -3089,9 +3269,9 @@ deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
-deepmerge@~0.2.7:
- version "0.2.10"
- resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-0.2.10.tgz#8906bf9e525a4fbf1b203b2afcb4640249821219"
+deepmerge@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.1.0.tgz#511a54fff405fc346f0240bb270a3e9533a31102"
default-compare@^1.0.0:
version "1.0.0"
@@ -3184,10 +3364,14 @@ delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-depd@1.1.1, depd@~1.1.0, depd@~1.1.1:
+depd@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+depd@~1.1.0, depd@~1.1.1, depd@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+
deps-sort@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5"
@@ -3218,6 +3402,10 @@ destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+detect-conflict@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
+
detect-file@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63"
@@ -3228,20 +3416,16 @@ detect-file@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
-detect-indent@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-2.0.0.tgz#720ff51e4d97b76884f6bf57292348b13dfde939"
- dependencies:
- get-stdin "^3.0.0"
- minimist "^1.1.0"
- repeating "^1.1.0"
-
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
dependencies:
repeating "^2.0.0"
+detect-indent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
+
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
@@ -3273,13 +3457,9 @@ di@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
-diff@3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75"
-
-diff@^3.1.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+diff@3.5.0, diff@^3.1.0, diff@^3.3.1, diff@^3.5.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
diffie-hellman@^5.0.0:
version "5.0.2"
@@ -3328,9 +3508,9 @@ dnode@^1.2.2:
optionalDependencies:
weak "^1.0.0"
-doctrine@^2.0.0, doctrine@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
+doctrine@^2.0.2, doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
dependencies:
esutils "^2.0.2"
@@ -3375,14 +3555,14 @@ dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
-domain-browser@^1.1.1, domain-browser@~1.1.0:
- version "1.1.7"
- resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
-
-domain-browser@^1.2.0:
+domain-browser@^1.1.1, domain-browser@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+domain-browser@~1.1.0:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
+
domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
@@ -3392,8 +3572,16 @@ domelementtype@~1.1.1:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
domexception@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.0.tgz#81fe5df81b3f057052cde3a9fa9bf536a85b9ab0"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ dependencies:
+ webidl-conversions "^4.0.2"
+
+domhandler@2.3:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738"
+ dependencies:
+ domelementtype "1"
domhandler@^2.3.0:
version "2.4.1"
@@ -3405,7 +3593,7 @@ domkit@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/domkit/-/domkit-0.0.1.tgz#88399d586794efc1154fec6c22cfe50f19bd4dbb"
-domutils@1.5.1:
+domutils@1.5, domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
dependencies:
@@ -3413,8 +3601,8 @@ domutils@1.5.1:
domelementtype "1"
domutils@^1.5.1:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.6.2.tgz#1958cc0b4c9426e9ed367fb1c8e854891b0fa3ff"
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
dependencies:
dom-serializer "0"
domelementtype "1"
@@ -3437,19 +3625,23 @@ duplexer2@0.0.2, duplexer2@~0.0.2:
dependencies:
readable-stream "~1.1.9"
-duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2:
+duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2, duplexer2@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
dependencies:
readable-stream "^2.0.2"
+duplexer3@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
+
duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
-duplexify@^3.1.2, duplexify@^3.4.2:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd"
+duplexify@^3.4.2, duplexify@^3.5.3:
+ version "3.5.4"
+ resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4"
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
@@ -3469,6 +3661,10 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
+editions@^1.3.3:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
+
editorconfig@^0.13.2:
version "0.13.3"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.13.3.tgz#e5219e587951d60958fd94ea9a9a008cdeff1b34"
@@ -3483,19 +3679,17 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-releases@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e"
+ejs@^2.3.1:
+ version "2.5.8"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.8.tgz#2ab6954619f225e6193b7ac5f7c39c48fefe4380"
-electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.28:
- version "1.3.30"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80"
- dependencies:
- electron-releases "^2.1.0"
+electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.41:
+ version "1.3.42"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz#95c33bf01d0cc405556aec899fe61fd4d76ea0f9"
-electron-to-chromium@^1.3.36:
- version "1.3.37"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.37.tgz#4a92734e0044c8cf0b1553be57eae21a4c6e5fab"
+elegant-spinner@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
elliptic@^6.0.0, elliptic@^6.2.3:
version "6.4.0"
@@ -3513,9 +3707,9 @@ emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
-encodeurl@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
+encodeurl@~1.0.1, encodeurl@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
encoding@^0.1.11:
version "0.1.12"
@@ -3524,31 +3718,30 @@ encoding@^0.1.11:
iconv-lite "~0.4.13"
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
dependencies:
once "^1.4.0"
-engine.io-client@1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.0.tgz#7b730e4127414087596d9be3c88d2bc5fdb6cf5c"
+engine.io-client@~3.1.0:
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.6.tgz#5bdeb130f8b94a50ac5cbeb72583e7a4a063ddfd"
dependencies:
component-emitter "1.2.1"
component-inherit "0.0.3"
- debug "2.3.3"
- engine.io-parser "1.3.1"
+ debug "~3.1.0"
+ engine.io-parser "~2.1.1"
has-cors "1.1.0"
indexof "0.0.1"
- parsejson "0.0.3"
parseqs "0.0.5"
parseuri "0.0.5"
- ws "1.1.1"
- xmlhttprequest-ssl "1.5.3"
+ ws "~3.3.1"
+ xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
-engine.io-client@~3.1.0:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.5.tgz#85de17666560327ef1817978f6e3f8101ded2c47"
+engine.io-client@~3.2.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36"
dependencies:
component-emitter "1.2.1"
component-inherit "0.0.3"
@@ -3562,17 +3755,6 @@ engine.io-client@~3.1.0:
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
-engine.io-parser@1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.1.tgz#9554f1ae33107d6fbd170ca5466d2f833f6a07cf"
- dependencies:
- after "0.8.1"
- arraybuffer.slice "0.0.6"
- base64-arraybuffer "0.1.5"
- blob "0.0.4"
- has-binary "0.1.6"
- wtf-8 "1.0.0"
-
engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196"
@@ -3583,17 +3765,6 @@ engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
blob "0.0.4"
has-binary2 "~1.0.2"
-engine.io@1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.0.tgz#3eeb5f264cb75dbbec1baaea26d61f5a4eace2aa"
- dependencies:
- accepts "1.3.3"
- base64id "0.1.0"
- cookie "0.3.1"
- debug "2.3.3"
- engine.io-parser "1.3.1"
- ws "1.1.1"
-
engine.io@~3.1.0:
version "3.1.5"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.1.5.tgz#0e7ef9d690eb0b35597f1d4ad02a26ca2dba3845"
@@ -3607,6 +3778,17 @@ engine.io@~3.1.0:
optionalDependencies:
uws "~9.14.0"
+engine.io@~3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.0.tgz#54332506f42f2edc71690d2f2a42349359f3bf7d"
+ dependencies:
+ accepts "~1.3.4"
+ base64id "1.0.0"
+ cookie "0.3.1"
+ debug "~3.1.0"
+ engine.io-parser "~2.1.0"
+ ws "~3.3.1"
+
enhanced-resolve@^3.3.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
@@ -3616,6 +3798,14 @@ enhanced-resolve@^3.3.0:
object-assign "^4.0.1"
tapable "^0.2.7"
+enhanced-resolve@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ memory-fs "^0.4.0"
+ tapable "^1.0.0"
+
ensnare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ensnare/-/ensnare-1.0.0.tgz#72d2bf7ef48aba21f66adf29d00a0904eddb61c7"
@@ -3630,6 +3820,10 @@ ent@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
+entities@1.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26"
+
entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -3641,6 +3835,10 @@ envify@^4.0.0:
esprima "^4.0.0"
through "~2.3.4"
+envinfo@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-4.4.2.tgz#472c49f3a8b9bca73962641ce7cb692bf623cd1c"
+
enzyme-adapter-react-15@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-15/-/enzyme-adapter-react-15-1.0.5.tgz#99f9a03ff2c2303e517342935798a6bdfbb75fac"
@@ -3681,20 +3879,27 @@ enzyme@^3.3.0:
rst-selector-parser "^2.2.3"
errno@^0.1.3, errno@~0.1.1:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026"
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
dependencies:
prr "~1.0.1"
-error-ex@^1.2.0:
+error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
+error@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
+ dependencies:
+ string-template "~0.2.1"
+ xtend "~4.0.0"
+
es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681"
dependencies:
es-to-primitive "^1.1.1"
function-bind "^1.1.1"
@@ -3711,13 +3916,14 @@ es-to-primitive@^1.1.1:
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
- version "0.10.37"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
+ version "0.10.42"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d"
dependencies:
- es6-iterator "~2.0.1"
+ es6-iterator "~2.0.3"
es6-symbol "~3.1.1"
+ next-tick "1"
-es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+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"
dependencies:
@@ -3784,7 +3990,7 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-escodegen@1.x.x:
+escodegen@1.x.x, escodegen@^1.8.1, escodegen@^1.9.0, escodegen@~1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2"
dependencies:
@@ -3795,36 +4001,6 @@ escodegen@1.x.x:
optionalDependencies:
source-map "~0.6.1"
-escodegen@^1.9.0:
- version "1.9.0"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852"
- dependencies:
- esprima "^3.1.3"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.5.6"
-
-escodegen@~0.0.24:
- version "0.0.28"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3"
- dependencies:
- esprima "~1.0.2"
- estraverse "~1.3.0"
- optionalDependencies:
- source-map ">= 0.1.2"
-
-escodegen@~1.3.2:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23"
- dependencies:
- esprima "~1.1.1"
- estraverse "~1.5.0"
- esutils "~1.0.0"
- optionalDependencies:
- source-map "~0.1.33"
-
escope@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
@@ -3838,6 +4014,12 @@ eslint-plugin-chai@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-chai/-/eslint-plugin-chai-0.0.1.tgz#9a1dea58b335c31242219d059b37ffb14309f6e1"
+eslint-plugin-json@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz#9ba73bb0be99d50093e889f5b968463d2a30efae"
+ dependencies:
+ jshint "^2.8.0"
+
eslint-plugin-mocha@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.0.0.tgz#43946a7ecaf39039eb3ee20635ebd4cc19baf6dd"
@@ -3845,12 +4027,12 @@ eslint-plugin-mocha@^5.0.0:
ramda "^0.25.0"
eslint-plugin-react@^7.4.0:
- version "7.5.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b"
+ version "7.7.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz#f606c719dbd8a1a2b3d25c16299813878cca0160"
dependencies:
- doctrine "^2.0.0"
+ doctrine "^2.0.2"
has "^1.0.1"
- jsx-ast-utils "^2.0.0"
+ jsx-ast-utils "^2.0.1"
prop-types "^15.6.0"
eslint-scope@^3.7.1, eslint-scope@~3.7.1:
@@ -3865,8 +4047,8 @@ eslint-visitor-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^4.0.0, eslint@^4.2.0:
- version "4.14.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82"
+ version "4.19.1"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
@@ -3874,10 +4056,10 @@ eslint@^4.0.0, eslint@^4.2.0:
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.1.0"
- doctrine "^2.0.2"
+ doctrine "^2.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
- espree "^3.5.2"
+ espree "^3.5.4"
esquery "^1.0.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
@@ -3899,18 +4081,19 @@ eslint@^4.0.0, eslint@^4.2.0:
path-is-inside "^1.0.2"
pluralize "^7.0.0"
progress "^2.0.0"
+ regexpp "^1.0.1"
require-uncached "^1.0.3"
semver "^5.3.0"
strip-ansi "^4.0.0"
strip-json-comments "~2.0.1"
- table "^4.0.1"
+ table "4.0.2"
text-table "~0.2.0"
-espree@^3.5.2:
- version "3.5.2"
- resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca"
+espree@^3.5.4:
+ version "3.5.4"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
dependencies:
- acorn "^5.2.1"
+ acorn "^5.5.0"
acorn-jsx "^3.0.0"
esprima-fb@13001.1001.0-dev-harmony-fb:
@@ -3921,51 +4104,30 @@ esprima@3.x.x, esprima@^3.1.3, esprima@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
-esprima@^4.0.0:
+esprima@^4.0.0, esprima@~4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
-esprima@~1.0.2:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad"
-
-esprima@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549"
-
esquery@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
dependencies:
estraverse "^4.0.0"
esrecurse@^4.1.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163"
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
dependencies:
estraverse "^4.1.0"
- object-assign "^4.0.1"
estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
-estraverse@~1.3.0:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42"
-
-estraverse@~1.5.0:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71"
-
esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
-esutils@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570"
-
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@@ -3988,18 +4150,7 @@ eth-block-tracker@^1.0.7:
pify "^2.3.0"
tape "^4.6.3"
-eth-block-tracker@^2.1.2, eth-block-tracker@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.2.2.tgz#b3d72cd82ba5ee37471d22bac4f56387ee4137cf"
- dependencies:
- async-eventemitter ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c
- babelify "^7.3.0"
- eth-query "^2.1.0"
- ethjs-util "^0.1.3"
- pify "^2.3.0"
- tape "^4.6.3"
-
-eth-block-tracker@^2.3.0:
+eth-block-tracker@^2.1.2, eth-block-tracker@^2.2.2, eth-block-tracker@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.3.0.tgz#4cb782c8ef8fde2f5dc894921ae1f5c1077c35a4"
dependencies:
@@ -4013,8 +4164,8 @@ eth-block-tracker@^2.3.0:
tape "^4.6.3"
eth-contract-metadata@^1.1.5:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.3.0.tgz#caf3cdc3d69995b6d7532c9d96fedbad46361ca8"
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.7.0.tgz#8d094043bf97019a2355b1e4d864ab33c9efe792"
eth-ens-namehash@^1.0.2:
version "1.0.2"
@@ -4023,17 +4174,7 @@ eth-ens-namehash@^1.0.2:
idna-uts46 "^1.0.1"
js-sha3 "^0.5.7"
-eth-hd-keyring@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.1.tgz#15ab3919b4153a8497e14673e8e8039e5965131c"
- dependencies:
- bip39 "^2.2.0"
- eth-sig-util "^1.3.0"
- ethereumjs-util "^5.1.1"
- ethereumjs-wallet "^0.6.0"
- events "^1.1.1"
-
-eth-hd-keyring@^1.2.2:
+eth-hd-keyring@^1.2.1, eth-hd-keyring@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz#ad5f479074436a93b439b0b95c79095c28791882"
dependencies:
@@ -4063,8 +4204,8 @@ eth-json-rpc-infura@^3.0.0:
tape "^4.8.0"
eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-middleware@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz#16b1053386aa3803b125732aa6de07eadf068729"
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.2.tgz#14cb0af1e9910c24dd063beabbbb7142d39d9bb9"
dependencies:
async "^2.5.0"
eth-query "^2.1.2"
@@ -4074,6 +4215,7 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-mid
ethereumjs-util "^5.1.2"
ethereumjs-vm "^2.1.0"
fetch-ponyfill "^4.0.0"
+ json-rpc-engine "^3.6.0"
json-rpc-error "^2.0.0"
json-stable-stringify "^1.0.1"
promise-to-callback "^1.0.0"
@@ -4095,8 +4237,8 @@ eth-keyring-controller@^2.1.4:
promise-filter "^1.1.0"
eth-phishing-detect@^1.1.4:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/eth-phishing-detect/-/eth-phishing-detect-1.1.12.tgz#3db7e88c754510c94e6736db85108b90e227fe41"
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/eth-phishing-detect/-/eth-phishing-detect-1.1.13.tgz#ed718b933c8a69fef0cefa6604538824b472dbea"
dependencies:
fast-levenshtein "^2.0.6"
@@ -4107,14 +4249,7 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
json-rpc-random-id "^1.0.0"
xtend "^4.0.1"
-eth-sig-util@^1.3.0, eth-sig-util@^1.4.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.1.tgz#dfcde3cbd03c38d429ad8695938a2678ec56f1ae"
- dependencies:
- ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
- ethereumjs-util "^5.1.1"
-
-eth-sig-util@^1.4.2:
+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"
dependencies:
@@ -4143,10 +4278,11 @@ eth-token-tracker@^1.1.4:
human-standard-token-abi "^1.0.2"
eth-tx-summary@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.1.2.tgz#e38836fc9f8b56f14d75952f0f5e570f88fb2220"
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.1.tgz#0c2d5e4c57d2511614f85b9b583c32fa2924166c"
dependencies:
async "^2.1.2"
+ bn.js "^4.11.8"
clone "^2.0.0"
concat-stream "^1.5.1"
end-of-stream "^1.1.0"
@@ -4154,7 +4290,7 @@ eth-tx-summary@^3.1.2:
ethereumjs-block "^1.4.1"
ethereumjs-tx "^1.1.1"
ethereumjs-util "^5.0.1"
- ethereumjs-vm "^2.0.2"
+ ethereumjs-vm "^2.3.4"
through2 "^2.0.3"
treeify "^1.0.1"
web3-provider-engine "^13.3.2"
@@ -4171,13 +4307,20 @@ ethereum-ens-network-map@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ethereum-ens-network-map/-/ethereum-ens-network-map-1.0.0.tgz#43cd7669ce950a789e151001118d4d65f210eeb7"
-ethereumjs-abi@^0.6.4, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
+ethereumjs-abi@^0.6.4:
version "0.6.5"
- resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#71f123b676f2b2d81bc20f343670d90045a3d3d8"
+ resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241"
dependencies:
bn.js "^4.10.0"
ethereumjs-util "^4.3.0"
+"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
+ version "0.6.5"
+ resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf"
+ dependencies:
+ bn.js "^4.10.0"
+ ethereumjs-util "^5.0.0"
+
ethereumjs-account@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.4.tgz#f8c30231bcb707f4514d8a052c1f9da103624d47"
@@ -4186,8 +4329,8 @@ ethereumjs-account@^2.0.3:
rlp "^2.0.0"
ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0, ethereumjs-block@~1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.0.tgz#23d6a765b069500a9f35d1c093ab6b216cbbeb06"
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f"
dependencies:
async "^2.0.1"
ethereum-common "0.2.0"
@@ -4196,13 +4339,13 @@ ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0, ether
merkle-patricia-tree "^2.1.2"
ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.0, ethereumjs-tx@^1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.3.tgz#ece051d3efdbe771ad2a518d61632ca2ab75ecbb"
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz#c2304912f6c07af03237ad8675ac036e290dad48"
dependencies:
ethereum-common "^0.0.18"
ethereumjs-util "^5.0.0"
-ethereumjs-util@4.5.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0:
+ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6"
dependencies:
@@ -4212,24 +4355,11 @@ ethereumjs-util@4.5.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumj
rlp "^2.0.0"
secp256k1 "^3.0.1"
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz#25ba0215cbb4c2f0b108a6f96af2a2e62e45921f"
+ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3:
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz#2f02575852627d45622426f25ee4a0b5f377f27a"
dependencies:
- babel-preset-es2015 "^6.24.0"
- babelify "^7.3.0"
- bn.js "^4.8.0"
- create-hash "^1.1.2"
- ethjs-util "^0.1.3"
- keccak "^1.0.2"
- rlp "^2.0.0"
- secp256k1 "^3.0.1"
-
-ethereumjs-util@^5.1.3:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.3.tgz#0c1f6efb1da9c5b6720a65697859fc0be6672df0"
- dependencies:
- bn.js "^4.8.0"
+ bn.js "^4.11.0"
create-hash "^1.1.2"
ethjs-util "^0.1.3"
keccak "^1.0.2"
@@ -4247,16 +4377,16 @@ ethereumjs-util@^5.1.3:
rlp "^2.0.0"
secp256k1 "^3.0.1"
-ethereumjs-vm@^2.0.0, ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.2.tgz#4f939e22b89e9b298f0c87a7e0f0d8949f485abd"
+ethereumjs-vm@^2.0.0, ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.4.tgz#f635d7cb047571a1840a6e9a74d29de4488f8ad6"
dependencies:
async "^2.1.2"
async-eventemitter "^0.2.2"
ethereum-common "0.2.0"
ethereumjs-account "^2.0.3"
ethereumjs-block "~1.7.0"
- ethereumjs-util "4.5.0"
+ ethereumjs-util "^5.1.3"
fake-merkle-patricia-tree "^1.0.1"
functional-red-black-tree "^1.0.1"
merkle-patricia-tree "^2.1.2"
@@ -4436,9 +4566,9 @@ event-emitter@^0.3.5, event-emitter@~0.3.5:
d "1"
es5-ext "~0.10.14"
-event-stream@^3.1.7:
+event-stream@^3.1.7, event-stream@~3.3.0:
version "3.3.4"
- resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
+ resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
dependencies:
duplexer "~0.1.1"
from "~0"
@@ -4471,11 +4601,11 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
-execa@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
+execa@^0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
dependencies:
- cross-spawn "^5.0.1"
+ cross-spawn "^6.0.0"
get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
@@ -4483,9 +4613,9 @@ execa@^0.7.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
-execa@^0.9.0:
- version "0.9.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01"
+execa@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
dependencies:
cross-spawn "^5.0.1"
get-stream "^3.0.0"
@@ -4505,6 +4635,14 @@ exists-stat@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/exists-stat/-/exists-stat-1.0.0.tgz#0660e3525a2e89d9e446129440c272edfa24b529"
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+exit@0.1.2, exit@0.1.x:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+
expand-braces@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
@@ -4557,10 +4695,10 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
homedir-polyfill "^1.0.1"
express@^4.10.7, express@^4.15.5:
- version "4.16.2"
- resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
+ version "4.16.3"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
dependencies:
- accepts "~1.3.4"
+ accepts "~1.3.5"
array-flatten "1.1.1"
body-parser "1.18.2"
content-disposition "0.5.2"
@@ -4568,29 +4706,35 @@ express@^4.10.7, express@^4.15.5:
cookie "0.3.1"
cookie-signature "1.0.6"
debug "2.6.9"
- depd "~1.1.1"
- encodeurl "~1.0.1"
+ depd "~1.1.2"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
- finalhandler "1.1.0"
+ finalhandler "1.1.1"
fresh "0.5.2"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
parseurl "~1.3.2"
path-to-regexp "0.1.7"
- proxy-addr "~2.0.2"
+ proxy-addr "~2.0.3"
qs "6.5.1"
range-parser "~1.2.0"
safe-buffer "5.1.1"
- send "0.16.1"
- serve-static "1.13.1"
+ send "0.16.2"
+ serve-static "1.13.2"
setprototypeof "1.1.0"
- statuses "~1.3.1"
- type-is "~1.6.15"
+ statuses "~1.4.0"
+ type-is "~1.6.16"
utils-merge "1.0.1"
vary "~1.1.2"
+extend-shallow@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
+ dependencies:
+ kind-of "^1.1.0"
+
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@@ -4619,12 +4763,12 @@ extension-link-enabler@^1.0.0:
extensionizer "^1.0.0"
extensionizer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.0.tgz#01c209bbea6d9c0acba77129c3aa4a9a98fc3538"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.1.tgz#504544239a7610ba8404b15c1832091a37768d09"
-external-editor@^2.0.4:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
+external-editor@^2.0.4, external-editor@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
dependencies:
chardet "^0.4.0"
iconv-lite "^0.4.17"
@@ -4636,19 +4780,6 @@ extglob@^0.3.1:
dependencies:
is-extglob "^1.0.0"
-extglob@^2.0.2:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.3.tgz#55e019d0c95bf873949c737b7e5172dba84ebb29"
- dependencies:
- array-unique "^0.3.2"
- define-property "^1.0.0"
- expand-brackets "^2.1.4"
- extend-shallow "^2.0.1"
- fragment-cache "^0.2.1"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
@@ -4707,8 +4838,8 @@ fancy-log@^1.1.0, fancy-log@^1.3.2:
time-stamp "^1.0.0"
fast-deep-equal@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
fast-json-patch@^2.0.4:
version "2.0.6"
@@ -4754,6 +4885,13 @@ fetch-ponyfill@^4.0.0:
dependencies:
node-fetch "~1.7.1"
+figures@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
figures@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -4802,9 +4940,9 @@ fill-range@^4.0.0:
repeat-string "^1.6.1"
to-regex-range "^2.1.0"
-finalhandler@1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.6.tgz#007aea33d1a4d3e42017f624848ad58d212f814f"
+finalhandler@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
dependencies:
debug "2.6.9"
encodeurl "~1.0.1"
@@ -4814,16 +4952,16 @@ finalhandler@1.0.6:
statuses "~1.3.1"
unpipe "~1.0.0"
-finalhandler@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
+finalhandler@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
dependencies:
debug "2.6.9"
- encodeurl "~1.0.1"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "~2.3.0"
parseurl "~1.3.2"
- statuses "~1.3.1"
+ statuses "~1.4.0"
unpipe "~1.0.0"
find-cache-dir@^0.1.1:
@@ -4840,6 +4978,10 @@ find-global-packages@0.0.1:
dependencies:
which "^1.0.5"
+find-index@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
+
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@@ -4847,7 +4989,7 @@ find-up@^1.0.0:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
-find-up@^2.1.0:
+find-up@^2.0.0, find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
dependencies:
@@ -4922,9 +5064,13 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
-flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
+flow-parser@^0.*:
+ version "0.69.0"
+ resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.69.0.tgz#378b5128d6d0b554a8b2f16a4ca3e1ab9649f00e"
+
+flush-write-stream@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd"
dependencies:
inherits "^2.0.1"
readable-stream "^2.0.4"
@@ -4989,14 +5135,14 @@ form-data@~2.1.1:
mime-types "^2.1.12"
form-data@~2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
dependencies:
asynckit "^0.4.0"
- combined-stream "^1.0.5"
+ combined-stream "1.0.6"
mime-types "^2.1.12"
-formatio@1.2.0, formatio@^1.2.0:
+formatio@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
dependencies:
@@ -5016,6 +5162,13 @@ fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+from2@^2.1.1:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@@ -5067,7 +5220,7 @@ fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-fsevents@^1.0.0:
+fsevents@^1.0.0, fsevents@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
dependencies:
@@ -5098,16 +5251,16 @@ ftp@~0.3.10:
readable-stream "1.1.x"
xregexp "2.0.0"
-function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@~1.1.0:
+function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
function.prototype.name@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
dependencies:
define-properties "^1.1.2"
- function-bind "^1.1.0"
+ function-bind "^1.1.1"
is-callable "^1.1.3"
functional-red-black-tree@^1.0.1:
@@ -5118,6 +5271,13 @@ fuse.js@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.2.0.tgz#f0448e8069855bf2a3e683cdc1d320e7e2a07ef4"
+ganache-cli@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.0.tgz#486c846497204b644166b5f0f74c9b41d02bdc25"
+ dependencies:
+ source-map-support "^0.5.3"
+ webpack-cli "^2.0.9"
+
gather-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b"
@@ -5163,10 +5323,6 @@ get-own-enumerable-property-symbols@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b"
-get-stdin@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-3.0.2.tgz#c1ced24b9039b38ded85bdf161e57713b6dd4abe"
-
get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
@@ -5175,7 +5331,7 @@ get-stdin@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
-get-stream@^3.0.0:
+get-stream@3.0.0, get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@@ -5200,6 +5356,23 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
+gh-got@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0"
+ dependencies:
+ got "^7.0.0"
+ is-plain-obj "^1.1.0"
+
+gifencoder@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/gifencoder/-/gifencoder-1.1.0.tgz#50e7d98c4b0cf97edd0d885d7e1b997f88802de3"
+
+github-username@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
+ dependencies:
+ gh-got "^6.0.0"
+
gl-mat4@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.1.4.tgz#1e895b55892e56a896867abd837d38f37a178086"
@@ -5208,7 +5381,7 @@ gl-vec3@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/gl-vec3/-/gl-vec3-1.0.3.tgz#110fd897d0729f6398307381567d0944941bf22b"
-glob-all@^3.0.1:
+glob-all@^3.0.1, glob-all@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab"
dependencies:
@@ -5250,15 +5423,32 @@ glob-stream@^6.1.0:
to-absolute-glob "^2.0.0"
unique-stream "^2.0.2"
-glob-watcher@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-4.0.0.tgz#9e63a8ff6e61e932de6cc2caece5071a6d737329"
+glob-stream@~3.1.9:
+ version "3.1.18"
+ resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b"
+ dependencies:
+ glob "^4.3.1"
+ glob2base "^0.0.12"
+ minimatch "^2.0.1"
+ ordered-read-streams "^0.1.0"
+ through2 "^0.6.1"
+ unique-stream "^1.0.0"
+
+glob-watcher@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.1.tgz#239aaa621b6bd843b288fdf6b155f50963c7d7ea"
dependencies:
async-done "^1.2.0"
- chokidar "^1.4.3"
+ chokidar "^2.0.0"
just-debounce "^1.0.0"
object.defaults "^1.1.0"
+glob2base@^0.0.12:
+ version "0.0.12"
+ resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56"
+ dependencies:
+ find-index "^0.1.1"
+
glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -5270,6 +5460,15 @@ glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glo
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^4.3.1:
+ version "4.5.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^2.0.1"
+ once "^1.3.0"
+
glob@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
@@ -5331,13 +5530,9 @@ global@~4.3.0:
min-document "^2.19.0"
process "~0.5.1"
-globals@^10.0.0:
- version "10.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7"
-
-globals@^11.0.1:
- version "11.1.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
+globals@^11.0.1, globals@^11.1.0:
+ version "11.4.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.4.0.tgz#b85c793349561c16076a3c13549238a27945f1bc"
globals@^9.18.0:
version "9.18.0"
@@ -5377,11 +5572,52 @@ globule@^1.0.0:
minimatch "~3.0.2"
glogg@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
dependencies:
sparkles "^1.0.0"
+got@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
+ dependencies:
+ decompress-response "^3.2.0"
+ duplexer3 "^0.1.4"
+ get-stream "^3.0.0"
+ is-plain-obj "^1.1.0"
+ is-retry-allowed "^1.0.0"
+ is-stream "^1.0.0"
+ isurl "^1.0.0-alpha5"
+ lowercase-keys "^1.0.0"
+ p-cancelable "^0.3.0"
+ p-timeout "^1.1.1"
+ safe-buffer "^5.0.1"
+ timed-out "^4.0.0"
+ url-parse-lax "^1.0.0"
+ url-to-options "^1.0.1"
+
+got@^8.2.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-8.3.0.tgz#6ba26e75f8a6cc4c6b3eb1fe7ce4fec7abac8533"
+ dependencies:
+ "@sindresorhus/is" "^0.7.0"
+ cacheable-request "^2.1.1"
+ decompress-response "^3.3.0"
+ duplexer3 "^0.1.4"
+ get-stream "^3.0.0"
+ into-stream "^3.1.0"
+ is-retry-allowed "^1.1.0"
+ isurl "^1.0.0-alpha5"
+ lowercase-keys "^1.0.0"
+ mimic-response "^1.0.0"
+ p-cancelable "^0.4.0"
+ p-timeout "^2.0.1"
+ pify "^3.0.0"
+ safe-buffer "^5.1.1"
+ timed-out "^4.0.1"
+ url-parse-lax "^3.0.0"
+ url-to-options "^1.0.1"
+
graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -5390,6 +5626,12 @@ graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, gr
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
+grouped-queue@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c"
+ dependencies:
+ lodash "^4.17.2"
+
growl@1.10.3:
version "1.10.3"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f"
@@ -5410,17 +5652,17 @@ gulp-autoprefixer@^5.0.0:
vinyl-sourcemaps-apply "^0.2.0"
gulp-babel@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.0.tgz#7b93c975159f7a0553e4263b4a55100ccc239b28"
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.1.tgz#b9c8e29fa376b36c57989db820fc1c1715bb47cb"
dependencies:
- gulp-util "^3.0.0"
+ plugin-error "^1.0.1"
replace-ext "0.0.1"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-cli@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.0.tgz#7f049ad298ed388cda9bd813b5d7062407d62cad"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.1.tgz#7847e220cb3662f2be8a6d572bf14e17be5a994b"
dependencies:
ansi-colors "^1.0.1"
archy "^1.0.0"
@@ -5428,16 +5670,16 @@ gulp-cli@^2.0.0:
color-support "^1.1.3"
concat-stream "^1.6.0"
copy-props "^2.0.1"
- fancy-log "^1.1.0"
+ fancy-log "^1.3.2"
gulplog "^1.0.0"
- interpret "^1.0.0"
+ interpret "^1.1.0"
isobject "^3.0.1"
- liftoff "^2.3.0"
+ liftoff "^2.5.0"
matchdep "^2.0.0"
mute-stdout "^1.0.0"
pretty-hrtime "^1.0.0"
replace-homedir "^1.0.0"
- semver-greatest-satisfied-range "^1.0.0"
+ semver-greatest-satisfied-range "^1.1.0"
v8flags "^3.0.1"
yargs "^7.1.0"
@@ -5453,21 +5695,22 @@ gulp-debug@^3.2.0:
tildify "^1.1.2"
gulp-eslint@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.0.tgz#16d9ea4d696e7b7a9d65eeb1aa5bc4ba0a22c7f7"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.2.tgz#18a2a6768e4404cbf3e203239cb57474168fa606"
dependencies:
eslint "^4.0.0"
- gulp-util "^3.0.8"
+ fancy-log "^1.3.2"
+ plugin-error "^1.0.0"
gulp-json-editor@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/gulp-json-editor/-/gulp-json-editor-2.2.1.tgz#7c4dd7477e8d06dc5dc49c0b81e745cdb04f97bb"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/gulp-json-editor/-/gulp-json-editor-2.3.0.tgz#a9c8d7d4b23b2a810cf0ca4a93b5ad549608459d"
dependencies:
- deepmerge "~0.2.7"
- detect-indent "^2.0.0"
- gulp-util "~3.0.0"
- js-beautify "~1.5.4"
- through2 "~0.5.0"
+ deepmerge "^2.1.0"
+ detect-indent "^5.0.0"
+ js-beautify "^1.7.5"
+ plugin-error "^1.0.1"
+ through2 "^2.0.3"
gulp-livereload@^3.8.1:
version "3.8.1"
@@ -5480,6 +5723,12 @@ gulp-livereload@^3.8.1:
lodash.assign "^3.0.0"
mini-lr "^0.1.8"
+gulp-multi-process@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/gulp-multi-process/-/gulp-multi-process-1.3.1.tgz#e12aa818e4c234357ad99d5caff8df8a18f46e9e"
+ dependencies:
+ async.queue "^0.5.2"
+
gulp-replace@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-0.6.1.tgz#11bf8c8fce533e33e2f6a8f2f430b955ba0be066"
@@ -5489,18 +5738,18 @@ gulp-replace@^0.6.1:
replacestream "^4.0.0"
gulp-sass@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.1.0.tgz#53dc4b68a1f5ddfe4424ab4c247655269a8b74b7"
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.2.1.tgz#2e3688a96fd8be1c0c01340750c191b2e79fab94"
dependencies:
gulp-util "^3.0"
lodash.clonedeep "^4.3.2"
- node-sass "^4.2.0"
+ node-sass "^4.8.3"
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-sourcemaps@^2.6.0:
- version "2.6.2"
- resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.2.tgz#4f41c72b35a7ea06b666d2e3f57917e2c0e71c4e"
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz#cbb2008450b1bcce6cd23bf98337be751bf6e30a"
dependencies:
"@gulp-sourcemaps/identity-map" "1.X"
"@gulp-sourcemaps/map-sources" "1.X"
@@ -5510,7 +5759,7 @@ gulp-sourcemaps@^2.6.0:
debug-fabulous "1.X"
detect-newline "2.X"
graceful-fs "4.X"
- source-map "0.X"
+ source-map "~0.6.0"
strip-bom-string "1.X"
through2 "2.X"
@@ -5560,7 +5809,7 @@ gulp-uglify@^3.0.0:
uglify-js "^3.0.5"
vinyl-sourcemaps-apply "^0.2.0"
-gulp-util@^3.0, gulp-util@^3.0.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
+gulp-util@^3.0, gulp-util@^3.0.2, gulp-util@^3.0.7:
version "3.0.8"
resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
dependencies:
@@ -5599,19 +5848,20 @@ gulp-watch@^5.0.0:
vinyl-file "^2.0.0"
gulp-zip@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.0.0.tgz#1cefc08b4bf36df4b5b1e7c6b36ee55ebbe4a881"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.1.0.tgz#dab178bd99afa190923f1eb78abaf0db47817704"
dependencies:
get-stream "^3.0.0"
- gulp-util "^3.0.0"
+ plugin-error "^0.1.2"
through2 "^2.0.1"
+ vinyl "^2.1.0"
yazl "^2.1.0"
"gulp@github:gulpjs/gulp#4.0":
- version "4.0.0-alpha.3"
- resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/71c094a51c7972d26f557899ddecab0210ef3776"
+ version "4.0.0"
+ resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/55eb23a268dcc7340bb40808600fd4802848c06f"
dependencies:
- glob-watcher "^4.0.0"
+ glob-watcher "^5.0.0"
gulp-cli "^2.0.0"
undertaker "^1.0.0"
vinyl-fs "^3.0.0"
@@ -5681,17 +5931,9 @@ has-binary2@~1.0.2:
dependencies:
isarray "2.0.1"
-has-binary@0.1.6:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.6.tgz#25326f39cfa4f616ad8787894e3af2cfbc7b6e10"
- dependencies:
- isarray "0.0.1"
-
-has-binary@0.1.7:
+has-color@~0.1.0:
version "0.1.7"
- resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c"
- dependencies:
- isarray "0.0.1"
+ resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
has-cors@1.1.0:
version "1.1.0"
@@ -5715,10 +5957,20 @@ has-gulplog@^0.1.0:
dependencies:
sparkles "^1.0.0"
+has-symbol-support-x@^1.4.1:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
+
has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+has-to-string-tag-x@^1.2.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
+ dependencies:
+ has-symbol-support-x "^1.4.1"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -5816,6 +6068,16 @@ hipchat-notifier@^1.1.0:
lodash "^4.0.0"
request "^2.0.0"
+history@^4.7.2:
+ version "4.7.2"
+ resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
+ dependencies:
+ invariant "^2.2.1"
+ loose-envify "^1.2.0"
+ resolve-pathname "^2.2.0"
+ value-equal "^0.4.0"
+ warning "^3.0.0"
+
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -5829,12 +6091,12 @@ hoek@2.x.x:
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoek@4.x.x:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
-hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
+hoist-non-react-statics@^2.3.0, hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40"
home-or-tmp@^2.0.0:
version "2.0.0"
@@ -5850,8 +6112,8 @@ homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
parse-passwd "^1.0.0"
hosted-git-info@^2.1.4:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222"
html-encoding-sniffer@^1.0.2:
version "1.0.2"
@@ -5889,6 +6151,16 @@ htmlescape@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351"
+htmlparser2@3.8.x:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
+ dependencies:
+ domelementtype "1"
+ domhandler "2.3"
+ domutils "1.5"
+ entities "1.0"
+ readable-stream "1.1"
+
htmlparser2@^3.9.1:
version "3.9.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
@@ -5900,7 +6172,11 @@ htmlparser2@^3.9.1:
inherits "^2.0.1"
readable-stream "^2.0.2"
-http-errors@1.6.2, http-errors@~1.6.2:
+http-cache-semantics@3.8.1:
+ version "3.8.1"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
+
+http-errors@1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
dependencies:
@@ -5916,9 +6192,18 @@ http-errors@~1.3.1:
inherits "~2.0.1"
statuses "1"
+http-errors@~1.6.2:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
+ dependencies:
+ depd "~1.1.2"
+ inherits "2.0.3"
+ setprototypeof "1.1.0"
+ statuses ">= 1.4.0 < 2"
+
http-parser-js@>=0.4.0:
- version "0.4.9"
- resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1"
+ version "0.4.11"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.11.tgz#5b720849c650903c27e521633d94696ee95f3529"
http-proxy-agent@1:
version "1.0.0"
@@ -5975,8 +6260,8 @@ https-proxy-agent@1:
extend "3"
https-proxy-agent@^2.1.1:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz#7fbba856be8cd677986f42ebd3664f6317257887"
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
@@ -5997,10 +6282,16 @@ iconv-lite@0.4.15:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
-iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@^0.4.5, 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"
+iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
+ version "0.4.21"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798"
+ dependencies:
+ safer-buffer "^2.1.0"
+
idb-global@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/idb-global/-/idb-global-2.1.0.tgz#2a3e09d1ed9df3a836d59aeea99bf74047b8cc8d"
@@ -6008,8 +6299,8 @@ idb-global@^2.1.0:
obs-store "^2.4.1"
identicon.js@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/identicon.js/-/identicon.js-2.3.1.tgz#0f16a0dd5e61e1a89699400cc192af4445506e5b"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/identicon.js/-/identicon.js-2.3.2.tgz#bfebb66c8047f386333ffa595fe2912345a0708d"
idna-uts46@^1.0.1:
version "1.1.0"
@@ -6018,8 +6309,8 @@ idna-uts46@^1.0.1:
punycode "^2.1.0"
ieee754@^1.1.4:
- version "1.1.8"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455"
iframe-stream@^3.0.0:
version "3.0.0"
@@ -6039,6 +6330,10 @@ ignorepatterns@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ignorepatterns/-/ignorepatterns-1.1.0.tgz#ac8f436f2239b5dfb66d5f0d3a904a87ac67cc5e"
+image-size@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4"
+
immediate@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c"
@@ -6047,6 +6342,13 @@ immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
+import-local@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
+ dependencies:
+ pkg-dir "^2.0.0"
+ resolve-cwd "^2.0.0"
+
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -6061,6 +6363,10 @@ indent-string@^2.1.0:
dependencies:
repeating "^2.0.0"
+indent-string@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
@@ -6097,8 +6403,8 @@ ini@^1.3.4, ini@~1.3.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
inject-css@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/inject-css/-/inject-css-0.1.1.tgz#ef3ffc78ec026c96e2355da0df32917e3526415c"
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/inject-css/-/inject-css-0.1.2.tgz#94943e3944c409ba8a11f22e9de322ef0865e45a"
inline-source-map@~0.5.0:
version "0.5.0"
@@ -6112,7 +6418,7 @@ inline-source-map@~0.6.0:
dependencies:
source-map "~0.5.3"
-inquirer@^3.0.6:
+inquirer@^3.0.6, inquirer@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
dependencies:
@@ -6131,26 +6437,52 @@ inquirer@^3.0.6:
strip-ansi "^4.0.0"
through "^2.3.6"
+inquirer@^5.1.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726"
+ dependencies:
+ ansi-escapes "^3.0.0"
+ chalk "^2.0.0"
+ cli-cursor "^2.1.0"
+ cli-width "^2.0.0"
+ external-editor "^2.1.0"
+ figures "^2.0.0"
+ lodash "^4.3.0"
+ mute-stream "0.0.7"
+ run-async "^2.2.0"
+ rxjs "^5.5.2"
+ string-width "^2.1.0"
+ strip-ansi "^4.0.0"
+ through "^2.3.6"
+
insert-module-globals@^7.0.0:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3"
+ version "7.0.6"
+ resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.6.tgz#15a31d9d394e76d08838b9173016911d7fd4ea1b"
dependencies:
JSONStream "^1.0.3"
- combine-source-map "~0.7.1"
- concat-stream "~1.5.1"
+ combine-source-map "^0.8.0"
+ concat-stream "^1.6.1"
is-buffer "^1.1.0"
lexical-scope "^1.2.0"
+ path-is-absolute "^1.0.1"
process "~0.11.0"
through2 "^2.0.0"
xtend "^4.0.0"
-interpret@^1.0.0:
+interpret@^1.0.0, interpret@^1.0.4, interpret@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
-invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
+into-stream@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
+ dependencies:
+ from2 "^2.1.1"
+ p-is-promise "^1.1.0"
+
+invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
loose-envify "^1.0.0"
@@ -6166,9 +6498,9 @@ ip@^1.1.2, ip@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
-ipaddr.js@1.5.2:
- version "1.5.2"
- resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0"
+ipaddr.js@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b"
irregular-plurals@^1.0.0:
version "1.4.0"
@@ -6350,12 +6682,17 @@ is-hexadecimal@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69"
+is-my-ip-valid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
+
is-my-json-valid@^2.12.4:
- version "2.17.1"
- resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471"
+ version "2.17.2"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
+ is-my-ip-valid "^1.0.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
@@ -6391,11 +6728,15 @@ is-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
-is-odd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088"
+is-object@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
+
+is-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2"
dependencies:
- is-number "^3.0.0"
+ symbol-observable "^0.2.2"
is-odd@^2.0.0:
version "2.0.0"
@@ -6408,8 +6749,8 @@ is-path-cwd@^1.0.0:
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
is-path-in-cwd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
dependencies:
is-path-inside "^1.0.0"
@@ -6419,7 +6760,7 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
-is-plain-obj@^1.1.0:
+is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@@ -6462,10 +6803,20 @@ is-relative@^1.0.0:
is-unc-path "^1.0.0"
is-resolvable@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
-is-stream@^1.0.1, is-stream@^1.1.0:
+is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
+
+is-scoped@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30"
+ dependencies:
+ scoped-regex "^1.0.0"
+
+is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -6478,8 +6829,8 @@ is-subset@^0.1.1:
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
is-supported-regexp-flag@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz#21ee16518d2c1dd3edd3e9a0d57e50207ac364ca"
is-symbol@^1.0.1:
version "1.0.1"
@@ -6517,14 +6868,10 @@ is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
-is-windows@^1.0.0, is-windows@^1.0.2:
+is-windows@^1.0.0, 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"
-is-windows@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
-
is-word-character@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb"
@@ -6541,6 +6888,10 @@ isarray@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
+isarray@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7"
+
isbinaryfile@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621"
@@ -6570,50 +6921,50 @@ isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-istanbul-lib-coverage@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
+istanbul-lib-coverage@^1.1.2, istanbul-lib-coverage@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341"
istanbul-lib-hook@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz#ae556fd5a41a6e8efa0b1002b1e416dfeaf9816c"
dependencies:
append-transform "^0.4.0"
-istanbul-lib-instrument@^1.9.1:
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e"
+istanbul-lib-instrument@^1.10.0:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babylon "^6.18.0"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.2.0"
semver "^5.3.0"
-istanbul-lib-report@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425"
+istanbul-lib-report@^1.1.3:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5"
dependencies:
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.2.0"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c"
+istanbul-lib-source-maps@^1.2.3:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz#cc7ccad61629f4efff8e2f78adb8c522c9976ec7"
dependencies:
debug "^3.1.0"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.2.0"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10"
+istanbul-reports@^1.1.4:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554"
dependencies:
handlebars "^4.0.3"
@@ -6624,6 +6975,21 @@ istextorbinary@1.0.2:
binaryextensions "~1.0.0"
textextensions "~1.0.0"
+istextorbinary@^2.1.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53"
+ dependencies:
+ binaryextensions "2"
+ editions "^1.3.3"
+ textextensions "2"
+
+isurl@^1.0.0-alpha5:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
+ dependencies:
+ has-to-string-tag-x "^1.2.0"
+ is-object "^1.0.1"
+
jazzicon@^1.2.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/jazzicon/-/jazzicon-1.5.0.tgz#d7f36b516023db39ee6eac117f4054e937b65e99"
@@ -6633,14 +6999,15 @@ jazzicon@^1.2.0:
raphael "^2.2.0"
js-base64@^2.1.8, js-base64@^2.1.9:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582"
-js-beautify@~1.5.4:
- version "1.5.10"
- resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.5.10.tgz#4d95371702699344a516ca26bf59f0a27bb75719"
+js-beautify@^1.7.5:
+ version "1.7.5"
+ resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.7.5.tgz#69d9651ef60dbb649f65527b53674950138a7919"
dependencies:
config-chain "~1.1.5"
+ editorconfig "^0.13.2"
mkdirp "~0.5.0"
nopt "~3.0.1"
@@ -6665,8 +7032,8 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
js-yaml@^3.2.5, js-yaml@^3.2.7, js-yaml@^3.4.3, js-yaml@^3.6.1, js-yaml@^3.9.1:
- version "3.10.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
@@ -6675,22 +7042,61 @@ jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+jscodeshift@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a"
+ dependencies:
+ async "^1.5.0"
+ babel-plugin-transform-flow-strip-types "^6.8.0"
+ babel-preset-es2015 "^6.9.0"
+ babel-preset-stage-1 "^6.5.0"
+ babel-register "^6.9.0"
+ babylon "^6.17.3"
+ colors "^1.1.2"
+ flow-parser "^0.*"
+ lodash "^4.13.1"
+ micromatch "^2.3.7"
+ node-dir "0.1.8"
+ nomnom "^1.8.1"
+ recast "^0.12.5"
+ temp "^0.8.1"
+ write-file-atomic "^1.2.0"
+
+jscodeshift@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.5.0.tgz#bdb7b6cc20dd62c16aa728c3fa2d2fe66ca7c748"
+ dependencies:
+ babel-plugin-transform-flow-strip-types "^6.8.0"
+ babel-preset-es2015 "^6.9.0"
+ babel-preset-stage-1 "^6.5.0"
+ babel-register "^6.9.0"
+ babylon "^7.0.0-beta.30"
+ colors "^1.1.2"
+ flow-parser "^0.*"
+ lodash "^4.13.1"
+ micromatch "^2.3.7"
+ neo-async "^2.5.0"
+ node-dir "0.1.8"
+ nomnom "^1.8.1"
+ recast "^0.14.1"
+ temp "^0.8.1"
+ write-file-atomic "^1.2.0"
+
jsdom-global@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"
jsdom@^11.2.0:
- version "11.6.2"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb"
+ version "11.7.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.7.0.tgz#8b45b657dae90d6d2d3a5f5d1126bb7102d0a172"
dependencies:
abab "^1.0.4"
acorn "^5.3.0"
acorn-globals "^4.1.0"
array-equal "^1.0.0"
- browser-process-hrtime "^0.1.2"
- content-type-parser "^1.0.2"
cssom ">= 0.3.2 < 0.4.0"
cssstyle ">= 0.2.37 < 0.3.0"
+ data-urls "^1.0.0"
domexception "^1.0.0"
escodegen "^1.9.0"
html-encoding-sniffer "^1.0.2"
@@ -6706,6 +7112,7 @@ jsdom@^11.2.0:
w3c-hr-time "^1.0.1"
webidl-conversions "^4.0.2"
whatwg-encoding "^1.0.3"
+ whatwg-mimetype "^2.1.0"
whatwg-url "^6.4.0"
ws "^4.0.0"
xml-name-validator "^3.0.0"
@@ -6714,6 +7121,10 @@ jsesc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+jsesc@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
+
jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
@@ -6729,31 +7140,32 @@ jshint-stylish@~2.2.1:
string-length "^1.0.0"
text-table "^0.2.0"
+jshint@^2.8.0:
+ version "2.9.5"
+ resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.5.tgz#1e7252915ce681b40827ee14248c46d34e9aa62c"
+ dependencies:
+ cli "~1.0.0"
+ console-browserify "1.1.x"
+ exit "0.1.x"
+ htmlparser2 "3.8.x"
+ lodash "3.7.x"
+ minimatch "~3.0.2"
+ shelljs "0.3.x"
+ strip-json-comments "1.0.x"
+
+json-buffer@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
+
json-loader@^0.5.4:
version "0.5.7"
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
-json-rpc-engine@^3.0.1, json-rpc-engine@^3.1.0, json-rpc-engine@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.4.0.tgz#8a1647a7f2cc7018f4802f41ec8208d281f78bfc"
- dependencies:
- async "^2.0.1"
- babel-preset-env "^1.3.2"
- babelify "^7.3.0"
- json-rpc-error "^2.0.0"
- promise-to-callback "^1.0.0"
-
-json-rpc-engine@^3.6.0:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.0.tgz#0cc673dcb4b71103523fec81d1bba195a457f993"
- dependencies:
- async "^2.0.1"
- babel-preset-env "^1.3.2"
- babelify "^7.3.0"
- json-rpc-error "^2.0.0"
- promise-to-callback "^1.0.0"
+json-parse-better-errors@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
-json-rpc-engine@^3.6.1:
+json-rpc-engine@^3.0.1, json-rpc-engine@^3.1.0, json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0, json-rpc-engine@^3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz#f53084726dc6dedeead0e2c457eeb997135f1e25"
dependencies:
@@ -6811,10 +7223,6 @@ json-stringify-safe@5.0.x, json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-json3@3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
-
json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
@@ -6867,7 +7275,7 @@ jstransform@^10.1.0:
esprima-fb "13001.1001.0-dev-harmony-fb"
source-map "0.1.31"
-jsx-ast-utils@^2.0.0:
+jsx-ast-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
dependencies:
@@ -6887,7 +7295,7 @@ just-debounce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea"
-just-extend@^1.1.26:
+just-extend@^1.1.27:
version "1.1.27"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905"
@@ -6965,7 +7373,17 @@ kew@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b"
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
+keyv@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
+ dependencies:
+ json-buffer "3.0.0"
+
+kind-of@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44"
+
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
@@ -6996,11 +7414,11 @@ known-css-properties@^0.2.0:
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.2.0.tgz#899c94be368e55b42d7db8d5be7d73a4a4a41454"
labeled-stream-splicer@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz#9cffa32fd99e1612fd1d86a8db962416d5292926"
dependencies:
inherits "^2.0.1"
- isarray "~0.0.1"
+ isarray "^2.0.4"
stream-splicer "^2.0.0"
last-run@^1.1.0:
@@ -7014,12 +7432,6 @@ lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
-lazy-cache@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
- dependencies:
- set-getter "^0.1.0"
-
lazystream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
@@ -7050,8 +7462,8 @@ lead@^1.0.0:
flush-write-stream "^1.0.2"
left-pad@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee"
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
leftpad@0.0.0:
version "0.0.0"
@@ -7136,7 +7548,7 @@ lie@~3.1.0:
dependencies:
immediate "~3.0.5"
-liftoff@^2.3.0:
+liftoff@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
dependencies:
@@ -7149,9 +7561,57 @@ liftoff@^2.3.0:
rechoir "^0.6.2"
resolve "^1.1.7"
+listr-silent-renderer@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
+
+listr-update-renderer@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ elegant-spinner "^1.0.1"
+ figures "^1.7.0"
+ indent-string "^3.0.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ strip-ansi "^3.0.1"
+
+listr-verbose-renderer@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
+ dependencies:
+ chalk "^1.1.3"
+ cli-cursor "^1.0.2"
+ date-fns "^1.27.2"
+ figures "^1.7.0"
+
+listr@^0.13.0:
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ figures "^1.7.0"
+ indent-string "^2.1.0"
+ is-observable "^0.2.0"
+ is-promise "^2.1.0"
+ is-stream "^1.1.0"
+ listr-silent-renderer "^1.1.1"
+ listr-update-renderer "^0.4.0"
+ listr-verbose-renderer "^0.4.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ ora "^0.2.3"
+ p-map "^1.1.1"
+ rxjs "^5.4.2"
+ stream-to-observable "^0.2.0"
+ strip-ansi "^3.0.1"
+
livereload-js@^2.2.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a"
load-json-file@^1.0.0:
version "1.1.0"
@@ -7163,6 +7623,15 @@ load-json-file@^1.0.0:
pinkie-promise "^2.0.0"
strip-bom "^2.0.0"
+load-json-file@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^4.0.0"
+ pify "^3.0.0"
+ strip-bom "^3.0.0"
+
loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
@@ -7176,6 +7645,18 @@ loader-utils@^0.2.16:
json5 "^0.5.0"
object-assign "^4.0.1"
+loader-utils@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
+ dependencies:
+ big.js "^3.1.3"
+ emojis-list "^2.0.0"
+ json5 "^0.5.0"
+
+locale-currency@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/locale-currency/-/locale-currency-0.0.1.tgz#c9e15a22ff575b4b4bb947a4bf92ac236bd1fe9b"
+
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -7183,9 +7664,9 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"
-lodash-es@^4.2.0, lodash-es@^4.2.1:
- version "4.17.4"
- resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
+lodash-es@^4.17.5, lodash-es@^4.2.1:
+ version "4.17.8"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.8.tgz#6fa8c8c5d337481df0bdf1c0d899d42473121e45"
lodash._baseassign@^3.0.0:
version "3.2.0"
@@ -7337,8 +7818,8 @@ lodash.memoize@~3.0.3:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
lodash.mergewith@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55"
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
lodash.restparam@^3.0.0:
version "3.6.1"
@@ -7377,13 +7858,17 @@ lodash.uniqby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
-lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.2, lodash@~4.17.4:
- version "4.17.4"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+lodash@3.7.x:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.7.0.tgz#3678bd8ab995057c07ade836ed2ef087da811d45"
+
+lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.4:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
log-driver@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8"
log-symbols@^1.0.0, log-symbols@^1.0.2:
version "1.0.2"
@@ -7391,6 +7876,19 @@ log-symbols@^1.0.0, log-symbols@^1.0.2:
dependencies:
chalk "^1.0.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"
+ dependencies:
+ chalk "^2.0.1"
+
+log-update@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
+ dependencies:
+ ansi-escapes "^1.0.0"
+ cli-cursor "^1.0.2"
+
log4js@^2.3.9:
version "2.5.3"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-2.5.3.tgz#38bb7bde5e9c1c181bd75e8bc128c5cd0409caf1"
@@ -7419,22 +7917,18 @@ loggly@^1.1.0:
timespan "2.3.x"
loglevel@^1.4.1, loglevel@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934"
-
-lolex@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
-lolex@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.1.tgz#3d2319894471ea0950ef64692ead2a5318cff362"
+lolex@^2.2.0, lolex@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
@@ -7447,9 +7941,20 @@ loud-rejection@^1.0.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"
-lru-cache@2.2.x:
- version "2.2.4"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
+lowercase-keys@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
+
+lowercase-keys@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
+
+lru-cache@4.1.x, lru-cache@^4.0.1:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f"
+ dependencies:
+ pseudomap "^1.0.2"
+ yallist "^2.1.2"
lru-cache@^3.2.0:
version "3.2.0"
@@ -7457,13 +7962,6 @@ lru-cache@^3.2.0:
dependencies:
pseudomap "^1.0.1"
-lru-cache@^4.0.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
- dependencies:
- pseudomap "^1.0.2"
- yallist "^2.1.2"
-
lru-cache@~2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5"
@@ -7475,8 +7973,14 @@ lru-queue@0.1:
es5-ext "~0.10.2"
ltgt@~2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.0.tgz#b65ba5fcb349a29924c8e333f7c6a5562f2e4842"
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5"
+
+magic-string@^0.22.4:
+ version "0.22.5"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
+ dependencies:
+ vlq "^0.2.2"
mailcomposer@4.0.1:
version "4.0.1"
@@ -7499,6 +8003,12 @@ mailgun-js@^0.7.0:
q "~1.4.0"
tsscmp "~1.0.0"
+make-dir@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b"
+ dependencies:
+ pify "^3.0.0"
+
make-error-cause@^1.1.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
@@ -7506,14 +8016,14 @@ make-error-cause@^1.1.1:
make-error "^1.2.0"
make-error@^1.2.0:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.2.tgz#8762ffad2444dd8ff1f7c819629fa28e24fea1c4"
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535"
make-iterator@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.0.tgz#57bef5dc85d23923ba23767324d8e8f8f3d9694b"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
dependencies:
- kind-of "^3.1.0"
+ kind-of "^6.0.2"
map-async@^0.1.1:
version "0.1.1"
@@ -7581,6 +8091,29 @@ media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+mem-fs-editor@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz#dd0a6eaf2bb8a6b37740067aa549eb530105af9f"
+ dependencies:
+ commondir "^1.0.1"
+ deep-extend "^0.4.0"
+ ejs "^2.3.1"
+ glob "^7.0.3"
+ globby "^6.1.0"
+ mkdirp "^0.5.0"
+ multimatch "^2.0.0"
+ rimraf "^2.2.8"
+ through2 "^2.0.0"
+ vinyl "^2.0.1"
+
+mem-fs@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc"
+ dependencies:
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+ vinyl-file "^2.0.0"
+
mem@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
@@ -7599,8 +8132,8 @@ memdown@^1.0.0:
safe-buffer "~5.1.1"
memoizee@0.4.X:
- version "0.4.11"
- resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.11.tgz#bde9817663c9e40fdb2a4ea1c367296087ae8c8f"
+ version "0.4.12"
+ resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.12.tgz#780e99a219c50c549be6d0fc61765080975c58fb"
dependencies:
d "1"
es5-ext "^0.10.30"
@@ -7641,6 +8174,12 @@ merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+merge-source-map@1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f"
+ dependencies:
+ source-map "^0.5.6"
+
merge-source-map@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646"
@@ -7648,8 +8187,8 @@ merge-source-map@^1.0.2:
source-map "^0.6.1"
merkle-patricia-tree@^2.1.2:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.0.tgz#84c606232ef343f1b96fc972e697708754f08573"
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz#7d4e7263a9c85c1679187cad4a6d71f48d524c71"
dependencies:
async "^1.4.2"
ethereumjs-util "^5.0.0"
@@ -7677,8 +8216,8 @@ metamascara@^2.0.0:
pump "^1.0.2"
metamask-logo@^2.1.2:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/metamask-logo/-/metamask-logo-2.1.3.tgz#175ce57ae50c7344b3b1dc32d2fd0b08e3978fd0"
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/metamask-logo/-/metamask-logo-2.1.4.tgz#0612b2b0ffc7eeb6be480c310785426ad9599e3c"
dependencies:
gl-mat4 "1.1.4"
gl-vec3 "1.0.3"
@@ -7705,27 +8244,9 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
-micromatch@^3.0.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.4.tgz#bb812e741a41f982c854e42b421a7eac458796f4"
- dependencies:
- arr-diff "^4.0.0"
- array-unique "^0.3.2"
- braces "^2.3.0"
- define-property "^1.0.0"
- extend-shallow "^2.0.1"
- extglob "^2.0.2"
- fragment-cache "^0.2.1"
- kind-of "^6.0.0"
- nanomatch "^1.2.5"
- object.pick "^1.3.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
-
-micromatch@^3.1.4:
- version "3.1.9"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.9.tgz#15dc93175ae39e52e93087847096effc73efcf89"
+micromatch@^3.0.4, micromatch@^3.1.4, micromatch@^3.1.8:
+ version "3.1.10"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
dependencies:
arr-diff "^4.0.0"
array-unique "^0.3.2"
@@ -7739,7 +8260,7 @@ micromatch@^3.1.4:
object.pick "^1.3.0"
regex-not "^1.0.0"
snapdragon "^0.8.1"
- to-regex "^3.0.1"
+ to-regex "^3.0.2"
miller-rabin@^4.0.0:
version "4.0.1"
@@ -7748,30 +8269,16 @@ miller-rabin@^4.0.0:
bn.js "^4.0.0"
brorand "^1.0.1"
-"mime-db@>= 1.30.0 < 2":
- version "1.32.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414"
-
-mime-db@~1.30.0:
- version "1.30.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
-
-mime-db@~1.33.0:
+"mime-db@>= 1.33.0 < 2", mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
-mime-types@^2.1.11:
+mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies:
mime-db "~1.33.0"
-mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
- version "2.1.17"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
- dependencies:
- mime-db "~1.30.0"
-
mime@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
@@ -7785,8 +8292,12 @@ mime@~1.2.9:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10"
mimic-fn@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
+
+mimic-response@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
min-document@^2.19.0:
version "2.19.0"
@@ -7819,6 +8330,12 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
dependencies:
brace-expansion "^1.1.7"
+minimatch@^2.0.1:
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
+ dependencies:
+ brace-expansion "^1.0.0"
+
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
@@ -7836,8 +8353,8 @@ minimist@~0.0.1, minimist@~0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
mixin-deep@^1.2.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a"
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
dependencies:
for-in "^1.0.2"
is-extendable "^1.0.1"
@@ -7876,13 +8393,13 @@ mocha-sinon@^2.0.0:
resolved "https://registry.yarnpkg.com/mocha-sinon/-/mocha-sinon-2.0.0.tgz#723a9310e7d737d7b77c7a66821237425b032d48"
mocha@^5.0.0:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.1.tgz#759b62c836b0732382a62b6b1fb245ec1bc943ac"
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.5.tgz#e228e3386b9387a4710007a641f127b00be44b52"
dependencies:
- browser-stdout "1.3.0"
+ browser-stdout "1.3.1"
commander "2.11.0"
debug "3.1.0"
- diff "3.3.1"
+ diff "3.5.0"
escape-string-regexp "1.0.5"
glob "7.1.2"
growl "1.10.3"
@@ -7911,8 +8428,8 @@ module-deps@^4.0.8:
xtend "^4.0.0"
module-deps@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.0.0.tgz#4417b49a4f4d7af79b104186e5389ea99b1dc837"
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.0.2.tgz#660217d1602b863ac8d4d16951a3720dd9aa4c80"
dependencies:
JSONStream "^1.0.3"
browser-resolve "^1.7.0"
@@ -7934,10 +8451,6 @@ ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
-ms@0.7.2:
- version "0.7.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
-
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -7987,25 +8500,9 @@ mz@^2.6.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
-nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.2:
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
-
-nanomatch@^1.2.5:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.6.tgz#f27233e97c34a8706b7e781a4bc611c957a81625"
- dependencies:
- arr-diff "^4.0.0"
- array-unique "^0.3.2"
- define-property "^1.0.0"
- extend-shallow "^2.0.1"
- fragment-cache "^0.2.1"
- is-odd "^1.0.0"
- kind-of "^5.0.2"
- object.pick "^1.3.0"
- regex-not "^1.0.0"
- snapdragon "^0.8.1"
- to-regex "^3.0.1"
+nan@^2.0.5, nan@^2.0.8, nan@^2.10.0, nan@^2.2.1, nan@^2.3.0:
+ version "2.10.0"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
nanomatch@^1.2.9:
version "1.2.9"
@@ -8033,17 +8530,22 @@ ncp@1.0.x:
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
nearley@^2.7.10:
- version "2.11.0"
- resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.11.0.tgz#5e626c79a6cd2f6ab9e7e5d5805e7668967757ae"
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.13.0.tgz#6e7b0f4e68bfc3e74c99eaef2eda39e513143439"
dependencies:
nomnom "~1.6.2"
railroad-diagrams "^1.0.0"
- randexp "^0.4.2"
+ randexp "0.4.6"
+ semver "^5.4.1"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+neo-async@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f"
+
netmask@~1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
@@ -8052,29 +8554,37 @@ next-tick@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
+nice-try@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
+
nise@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.3.2.tgz#fd6fd8dc040dfb3c0a45252feb6ff21832309b14"
dependencies:
- formatio "^1.2.0"
- just-extend "^1.1.26"
- lolex "^1.6.0"
+ "@sinonjs/formatio" "^2.0.0"
+ just-extend "^1.1.27"
+ lolex "^2.3.2"
path-to-regexp "^1.7.0"
text-encoding "^0.6.4"
nock@^9.0.14:
- version "9.1.5"
- resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.5.tgz#9e4878e0e1c050bdd93ae1e326e89461ea15618b"
+ version "9.2.3"
+ resolved "https://registry.yarnpkg.com/nock/-/nock-9.2.3.tgz#39738087d6a0497d3a165fb352612b38a2f9b92f"
dependencies:
- chai ">=1.9.2 <4.0.0"
- debug "^2.2.0"
+ chai "^4.1.2"
+ debug "^3.1.0"
deep-equal "^1.0.0"
json-stringify-safe "^5.0.1"
- lodash "~4.17.2"
+ lodash "^4.17.5"
mkdirp "^0.5.0"
- propagate "0.4.0"
+ propagate "^1.0.0"
qs "^6.5.1"
- semver "^5.3.0"
+ semver "^5.5.0"
+
+node-dir@0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
node-fetch@^1.0.1, node-fetch@^1.7.3, node-fetch@~1.7.1:
version "1.7.3"
@@ -8130,13 +8640,13 @@ node-libs-browser@^2.0.0:
vm-browserify "0.0.4"
node-notifier@^5.0.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea"
dependencies:
growly "^1.3.0"
- semver "^5.3.0"
- shellwords "^0.1.0"
- which "^1.2.12"
+ semver "^5.4.1"
+ shellwords "^0.1.1"
+ which "^1.3.0"
node-pre-gyp@^0.6.39:
version "0.6.39"
@@ -8154,9 +8664,9 @@ node-pre-gyp@^0.6.39:
tar "^2.2.1"
tar-pack "^3.4.0"
-node-sass@^4.2.0, node-sass@^4.7.2:
- version "4.7.2"
- resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e"
+node-sass@^4.7.2, node-sass@^4.8.3:
+ version "4.8.3"
+ resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.8.3.tgz#d077cc20a08ac06f661ca44fb6f19cd2ed41debb"
dependencies:
async-foreach "^0.1.3"
chalk "^1.1.1"
@@ -8170,7 +8680,7 @@ node-sass@^4.2.0, node-sass@^4.7.2:
lodash.mergewith "^4.6.0"
meow "^3.7.0"
mkdirp "^0.5.1"
- nan "^2.3.2"
+ nan "^2.10.0"
node-gyp "^3.3.1"
npmlog "^4.0.0"
request "~2.79.0"
@@ -8231,6 +8741,13 @@ nodemailer@^2.5.0:
nodemailer-smtp-transport "2.7.2"
socks "1.1.9"
+nomnom@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
+ dependencies:
+ chalk "~0.4.0"
+ underscore "~1.6.0"
+
nomnom@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
@@ -8274,6 +8791,14 @@ normalize-selector@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
+normalize-url@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6"
+ dependencies:
+ prepend-http "^2.0.0"
+ query-string "^5.0.1"
+ sort-keys "^2.0.0"
+
now-and-later@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee"
@@ -8321,29 +8846,29 @@ number-to-bn@1.7.0, number-to-bn@^1.7.0:
strip-hex-prefix "1.0.0"
nwmatcher@^1.4.3:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e"
nyc@^11.0.3:
- version "11.4.1"
- resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.4.1.tgz#13fdf7e7ef22d027c61d174758f6978a68f4f5e5"
+ version "11.6.0"
+ resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.6.0.tgz#d9c7b51ffceb6bba099a4683a6adc1b331b98853"
dependencies:
archy "^1.0.0"
arrify "^1.0.1"
caching-transform "^1.0.0"
- convert-source-map "^1.3.0"
+ convert-source-map "^1.5.1"
debug-log "^1.0.1"
default-require-extensions "^1.0.0"
find-cache-dir "^0.1.1"
find-up "^2.1.0"
foreground-child "^1.5.3"
glob "^7.0.6"
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.1.2"
istanbul-lib-hook "^1.1.0"
- istanbul-lib-instrument "^1.9.1"
- istanbul-lib-report "^1.1.2"
- istanbul-lib-source-maps "^1.2.2"
- istanbul-reports "^1.1.3"
+ istanbul-lib-instrument "^1.10.0"
+ istanbul-lib-report "^1.1.3"
+ istanbul-lib-source-maps "^1.2.3"
+ istanbul-reports "^1.1.4"
md5-hex "^1.2.0"
merge-source-map "^1.0.2"
micromatch "^2.3.11"
@@ -8352,8 +8877,8 @@ nyc@^11.0.3:
rimraf "^2.5.4"
signal-exit "^3.0.1"
spawn-wrap "^1.4.2"
- test-exclude "^4.1.1"
- yargs "^10.0.3"
+ test-exclude "^4.2.0"
+ yargs "11.1.0"
yargs-parser "^8.0.0"
o-stream@^0.2.2:
@@ -8376,10 +8901,6 @@ object-assign@3.0.0, object-assign@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
-object-assign@4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
-
object-assign@4.X, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -8396,17 +8917,13 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-inspect@^1.5.0:
+object-inspect@^1.5.0, object-inspect@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.5.0.tgz#9d876c11e40f485c79215670281b767488f9bfe3"
-object-inspect@~0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec"
-
-object-inspect@~1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d"
+object-inspect@~1.4.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.4.1.tgz#37ffb10e71adaf3748d05f713b4c9452f402cbc4"
object-is@^1.0.1:
version "1.0.1"
@@ -8529,6 +9046,10 @@ onecolor@^3.0.4:
version "3.0.5"
resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.5.tgz#36eff32201379efdf1180fb445e51a8e2425f9f6"
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -8565,9 +9086,18 @@ optionator@^0.8.1, optionator@^0.8.2:
type-check "~0.3.2"
wordwrap "~1.0.0"
-options@>=0.0.5:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
+ora@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
+ dependencies:
+ chalk "^1.1.1"
+ cli-cursor "^1.0.2"
+ cli-spinners "^0.1.2"
+ object-assign "^4.0.1"
+
+ordered-read-streams@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126"
ordered-read-streams@^1.0.0:
version "1.0.1"
@@ -8602,8 +9132,8 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
osenv@0, osenv@^0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
@@ -8614,13 +9144,37 @@ outpipe@^1.1.0:
dependencies:
shell-quote "^1.4.2"
+p-cancelable@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
+
+p-cancelable@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0"
+
+p-each-series@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71"
+ dependencies:
+ p-reduce "^1.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"
-p-limit@^1.1.0:
+p-is-promise@^1.1.0:
version "1.1.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
+ resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e"
+
+p-lazy@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835"
+
+p-limit@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
+ dependencies:
+ p-try "^1.0.0"
p-locate@^2.0.0:
version "2.0.0"
@@ -8632,6 +9186,26 @@ p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
+p-reduce@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
+
+p-timeout@^1.1.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
+ dependencies:
+ p-finally "^1.0.0"
+
+p-timeout@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
+ dependencies:
+ p-finally "^1.0.0"
+
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+
pac-proxy-agent@1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d"
@@ -8676,7 +9250,7 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
-parse-entities@^1.0.2:
+parse-entities@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890"
dependencies:
@@ -8717,6 +9291,13 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
@@ -8731,12 +9312,6 @@ parse5@^3.0.1:
dependencies:
"@types/node" "*"
-parsejson@0.0.3:
- version "0.0.3"
- resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab"
- dependencies:
- better-assert "~1.0.0"
-
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
@@ -8783,7 +9358,7 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
-path-key@^2.0.0:
+path-key@^2.0.0, path-key@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
@@ -8829,6 +9404,12 @@ path-type@^1.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+path-type@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+ dependencies:
+ pify "^3.0.0"
+
pathval@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
@@ -8904,6 +9485,12 @@ pkg-dir@^1.0.0:
dependencies:
find-up "^1.0.0"
+pkg-dir@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
+ dependencies:
+ find-up "^2.1.0"
+
pkginfo@0.3.x:
version "0.3.1"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
@@ -8916,7 +9503,17 @@ plucker@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/plucker/-/plucker-0.0.0.tgz#2ffa24e03ab2cffa4e75adc1df70f25623c45d09"
-plugin-error@^1.0.1:
+plugin-error@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace"
+ dependencies:
+ ansi-cyan "^0.1.1"
+ ansi-red "^0.1.1"
+ arr-diff "^1.0.1"
+ arr-union "^2.0.1"
+ extend-shallow "^1.1.2"
+
+plugin-error@^1.0.0, plugin-error@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c"
dependencies:
@@ -8939,6 +9536,18 @@ pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
+png-file-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/png-file-stream/-/png-file-stream-1.0.0.tgz#e083d0fe56e097a5cbd0d341a1387379052cad35"
+ dependencies:
+ glob-stream "~3.1.9"
+ png-js "~0.1.1"
+ through2 "~0.2.3"
+
+png-js@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/png-js/-/png-js-0.1.1.tgz#1cc7c212303acabe74263ec3ac78009580242d93"
+
pojo-migrator@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/pojo-migrator/-/pojo-migrator-2.1.0.tgz#3c2a3b9f80ba5a9fb7ebb921d3344db4efa5f669"
@@ -8950,8 +9559,8 @@ polyfill-crypto.getrandomvalues@^1.0.0:
mersenne-twister "^1.0.1"
popper.js@^1.11.1:
- version "1.13.0"
- resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.13.0.tgz#e1e7ff65cc43f7cf9cf16f1510a75e81f84f4565"
+ version "1.14.3"
+ resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.3.tgz#1438f98d046acf7b4d78cd502bf418ac64d4f095"
portfinder@~0.2.1:
version "0.2.1"
@@ -9035,30 +9644,38 @@ postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.
source-map "^0.5.6"
supports-color "^3.2.3"
-postcss@^6.0.1:
- version "6.0.14"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885"
- dependencies:
- chalk "^2.3.0"
- source-map "^0.6.1"
- supports-color "^4.4.0"
-
-postcss@^6.0.19:
- version "6.0.19"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.19.tgz#76a78386f670b9d9494a655bf23ac012effd1555"
+postcss@^6.0.1, postcss@^6.0.20:
+ version "6.0.21"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.21.tgz#8265662694eddf9e9a5960db6da33c39e4cd069d"
dependencies:
- chalk "^2.3.1"
+ chalk "^2.3.2"
source-map "^0.6.1"
- supports-color "^5.2.0"
+ supports-color "^5.3.0"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+prepend-http@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+
+prepend-http@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
+
preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+prettier@^1.5.3:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"
+
+pretty-bytes@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
+
pretty-bytes@~0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-0.1.2.tgz#cd90294d58a1ca4e8a5d0fb9c8225998881acf00"
@@ -9075,11 +9692,11 @@ private@^0.1.6, private@^0.1.7, private@~0.1.5:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
-process-nextick-args@^1.0.6, process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
+process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
-process-nextick-args@~2.0.0:
+process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
@@ -9131,28 +9748,28 @@ prompt@^1.0.0:
utile "0.3.x"
winston "2.1.x"
-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:
- version "15.6.0"
- resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
+prop-types@^15.5.10, prop-types@^15.5.4, 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:
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.3.1"
object-assign "^4.1.1"
-propagate@0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/propagate/-/propagate-0.4.0.tgz#f3fcca0a6fe06736a7ba572966069617c130b481"
+propagate@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/propagate/-/propagate-1.0.0.tgz#00c2daeedda20e87e3782b344adba1cddd6ad709"
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
-proxy-addr@~2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
+proxy-addr@~2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
dependencies:
forwarded "~0.1.2"
- ipaddr.js "1.5.2"
+ ipaddr.js "1.6.0"
proxy-agent@~2.0.0:
version "2.0.0"
@@ -9175,6 +9792,12 @@ prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
+ps-tree@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014"
+ dependencies:
+ event-stream "~3.3.0"
+
pseudomap@^1.0.1, pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@@ -9189,13 +9812,20 @@ public-encrypt@^4.0.0:
parse-asn1 "^5.0.0"
randombytes "^2.0.1"
-pump@^1.0.0, pump@^1.0.2:
+pump@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
+pump@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@@ -9204,12 +9834,12 @@ pump@^3.0.0:
once "^1.3.1"
pumpify@^1.3.4, pumpify@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb"
dependencies:
- duplexify "^3.1.2"
- inherits "^2.0.1"
- pump "^1.0.0"
+ duplexify "^3.5.3"
+ inherits "^2.0.3"
+ pump "^2.0.0"
punycode@1.3.2:
version "1.3.2"
@@ -9232,8 +9862,8 @@ q@~1.4.0:
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
qjobs@^1.1.4:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
qrcode-npm@0.0.3:
version "0.0.3"
@@ -9263,6 +9893,14 @@ qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+query-string@^5.0.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
+ dependencies:
+ decode-uri-component "^0.2.0"
+ object-assign "^4.1.0"
+ strict-uri-encode "^1.0.0"
+
querystring-es3@^0.2.0, querystring-es3@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -9283,7 +9921,7 @@ qunitjs@^2.4.1:
resolve "1.3.2"
walk-sync "0.3.1"
-quote-stream@^1.0.1:
+quote-stream@^1.0.1, quote-stream@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-1.0.2.tgz#84963f8c9c26b942e153feeb53aae74652b7e0b2"
dependencies:
@@ -9291,13 +9929,6 @@ quote-stream@^1.0.1:
minimist "^1.1.3"
through2 "^2.0.0"
-quote-stream@~0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-0.0.0.tgz#cde29e94c409b16e19dc7098b89b6658f9721d3b"
- dependencies:
- minimist "0.0.8"
- through2 "~0.4.1"
-
raf@^3.1.0, raf@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
@@ -9316,7 +9947,7 @@ ramda@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
-randexp@^0.4.2:
+randexp@0.4.6:
version "0.4.6"
resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
dependencies:
@@ -9331,14 +9962,14 @@ randomatic@^1.1.3:
kind-of "^4.0.0"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
dependencies:
safe-buffer "^5.1.0"
randomfill@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
dependencies:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
@@ -9354,8 +9985,8 @@ raphael@^2.2.0:
eve-raphael "0.5.0"
raven-js@^3.24.0:
- version "3.24.0"
- resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
+ version "3.24.1"
+ resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.1.tgz#7327e08786248517eedd36205bf50f1047821ffa"
raw-body@2, raw-body@2.3.2:
version "2.3.2"
@@ -9375,8 +10006,8 @@ raw-body@~2.1.5:
unpipe "1.0.0"
rc@^1.1.7:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
@@ -9409,23 +10040,23 @@ react-hyperscript@^2.4.0:
react ">= 0.12.0 < 16.0.0"
react-hyperscript@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.0.0.tgz#3c16010b33175de6bc01fd1ebad0a16a9a6dc9ab"
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.2.0.tgz#24144ff6b1beb07af7154794a782a74b34920868"
-react-input-autosize@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.1.2.tgz#a3dc11a5517c434db25229925541309de3f7a8f5"
+react-input-autosize@^2.1.2:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
dependencies:
prop-types "^15.5.8"
react-markdown@^3.0.0:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.3.tgz#5ac1f20cb5a3e8c47b6ae3c8522e813b08f58c34"
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.3.0.tgz#a87cdd822aa9302d6add9687961dd1a82a45d02e"
dependencies:
- prop-types "^15.6.0"
- remark-parse "^4.0.0"
+ prop-types "^15.6.1"
+ remark-parse "^5.0.0"
unified "^6.1.5"
- unist-util-visit "^1.1.3"
+ unist-util-visit "^1.3.0"
xtend "^4.0.1"
react-motion@^0.5.2:
@@ -9437,27 +10068,50 @@ react-motion@^0.5.2:
raf "^3.1.0"
react-redux@^5.0.5:
- version "5.0.6"
- resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
+ version "5.0.7"
+ resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
dependencies:
- hoist-non-react-statics "^2.2.1"
+ hoist-non-react-statics "^2.5.0"
invariant "^2.0.0"
- lodash "^4.2.0"
- lodash-es "^4.2.0"
+ lodash "^4.17.5"
+ lodash-es "^4.17.5"
loose-envify "^1.1.0"
- prop-types "^15.5.10"
+ prop-types "^15.6.0"
+
+react-router-dom@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d"
+ dependencies:
+ history "^4.7.2"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ prop-types "^15.5.4"
+ react-router "^4.2.0"
+ warning "^3.0.0"
+
+react-router@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986"
+ dependencies:
+ history "^4.7.2"
+ hoist-non-react-statics "^2.3.0"
+ invariant "^2.2.2"
+ loose-envify "^1.3.1"
+ path-to-regexp "^1.7.0"
+ prop-types "^15.5.4"
+ warning "^3.0.0"
react-select@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.1.0.tgz#626a2de839fdea2ade74dd1b143a9bde34be6c82"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.2.1.tgz#a2fe58a569eb14dcaa6543816260b97e538120d1"
dependencies:
classnames "^2.2.4"
prop-types "^15.5.8"
- react-input-autosize "^2.1.0"
+ react-input-autosize "^2.1.2"
react-simple-file-input@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/react-simple-file-input/-/react-simple-file-input-2.0.1.tgz#15ad4ffc78feb1b882649ad6b01c033ef27571e6"
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/react-simple-file-input/-/react-simple-file-input-2.1.0.tgz#d0742be5acd781bf746e6f792b0bc724cd5c09f2"
dependencies:
prop-types "^15.5.7"
@@ -9469,8 +10123,8 @@ react-test-renderer@^15.6.2:
object-assign "^4.1.0"
react-testutils-additions@^15.2.0:
- version "15.3.0"
- resolved "https://registry.yarnpkg.com/react-testutils-additions/-/react-testutils-additions-15.3.0.tgz#0ee96a5998f54e2bda2cf0a3430a345df04b7f64"
+ version "15.3.1"
+ resolved "https://registry.yarnpkg.com/react-testutils-additions/-/react-testutils-additions-15.3.1.tgz#265a804a90935330c5c5fc90aafb43c0a6780cf4"
dependencies:
object-assign "3.0.0"
sizzle "2.3.3"
@@ -9510,11 +10164,10 @@ react-transition-group@^1.2.0:
warning "^3.0.0"
react-transition-group@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.3.0.tgz#8dd1af58f6af284b19fd057f512e74f20438ad31"
dependencies:
chain-function "^1.0.0"
- classnames "^2.2.5"
dom-helpers "^3.2.0"
loose-envify "^1.3.1"
prop-types "^15.5.8"
@@ -9541,6 +10194,13 @@ reactify@^1.1.1:
react-tools "~0.13.0"
through "~2.3.4"
+read-chunk@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655"
+ dependencies:
+ pify "^3.0.0"
+ safe-buffer "^5.1.1"
+
read-file-stdin@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/read-file-stdin/-/read-file-stdin-0.2.1.tgz#25eccff3a153b6809afacb23ee15387db9e0ee61"
@@ -9560,6 +10220,13 @@ read-pkg-up@^1.0.1:
find-up "^1.0.0"
read-pkg "^1.0.0"
+read-pkg-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
+ dependencies:
+ find-up "^2.0.0"
+ read-pkg "^3.0.0"
+
read-pkg@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
@@ -9568,12 +10235,29 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
+read-pkg@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+ dependencies:
+ load-json-file "^4.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^3.0.0"
+
read@1.0.x:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
dependencies:
mute-stream "~0.0.4"
+readable-stream@1.1:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
readable-stream@1.1.x, "readable-stream@1.x >=1.1.9", "readable-stream@>=1.1.13-1 <1.2.0-0", readable-stream@^1.0.27-1, readable-stream@^1.0.33, readable-stream@^1.1.13-1, readable-stream@~1.1.9:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
@@ -9583,16 +10267,16 @@ readable-stream@1.1.x, "readable-stream@1.x >=1.1.9", "readable-stream@>=1.1.13-
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@2, readable-stream@^2.3.0:
- version "2.3.5"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d"
+readable-stream@2, readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@~2.3.3:
+ version "2.3.6"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
- string_decoder "~1.0.3"
+ string_decoder "~1.1.1"
util-deprecate "~1.0.1"
"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.15, readable-stream@~1.0.17, readable-stream@~1.0.27-1:
@@ -9604,18 +10288,6 @@ readable-stream@2, readable-stream@^2.3.0:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~1.0.6"
- safe-buffer "~5.1.1"
- string_decoder "~1.0.3"
- util-deprecate "~1.0.1"
-
readable-stream@~2.0.0, readable-stream@~2.0.5, readable-stream@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
@@ -9651,6 +10323,25 @@ recast@^0.11.17:
private "~0.1.5"
source-map "~0.5.0"
+recast@^0.12.5:
+ version "0.12.9"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1"
+ dependencies:
+ ast-types "0.10.1"
+ core-js "^2.4.1"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
+recast@^0.14.1:
+ version "0.14.7"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.7.tgz#4f1497c2b5826d42a66e8e3c9d80c512983ff61d"
+ dependencies:
+ ast-types "0.11.3"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@@ -9738,11 +10429,16 @@ regex-cache@^0.4.2:
dependencies:
is-equal-shallow "^0.1.3"
-regex-not@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9"
+regex-not@^1.0.0, regex-not@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
dependencies:
- extend-shallow "^2.0.1"
+ extend-shallow "^3.0.2"
+ safe-regex "^1.1.0"
+
+regexpp@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab"
regexpu-core@^2.0.0:
version "2.0.0"
@@ -9762,9 +10458,9 @@ regjsparser@^0.1.4:
dependencies:
jsesc "~0.5.0"
-remark-parse@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-4.0.0.tgz#99f1f049afac80382366e2e0d0bd55429dd45d8b"
+remark-parse@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
dependencies:
collapse-white-space "^1.0.2"
is-alphabetical "^1.0.0"
@@ -9772,7 +10468,7 @@ remark-parse@^4.0.0:
is-whitespace-character "^1.0.0"
is-word-character "^1.0.0"
markdown-escapes "^1.0.0"
- parse-entities "^1.0.2"
+ parse-entities "^1.1.0"
repeat-string "^1.5.4"
state-toggle "^1.0.0"
trim "0.0.1"
@@ -9813,12 +10509,6 @@ repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
-repeating@^1.1.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac"
- dependencies:
- is-finite "^1.0.0"
-
repeating@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
@@ -9877,8 +10567,8 @@ request-promise@^4.2.1:
tough-cookie ">=2.3.3"
request@2, request@^2.0.0, request@^2.67.0, request@^2.74.0, request@^2.79.0, request@^2.83.0:
- version "2.83.0"
- resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
+ version "2.85.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa"
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
@@ -10013,6 +10703,12 @@ requires-port@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ dependencies:
+ resolve-from "^3.0.0"
+
resolve-dir@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
@@ -10045,6 +10741,10 @@ resolve-options@^1.1.0:
dependencies:
value-or-function "^3.0.0"
+resolve-pathname@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
+
resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@@ -10064,14 +10764,14 @@ resolve@^0.6.1:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46"
resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.0.tgz#2bdf5374811207285df0df652b78f118ab8f3c5e"
dependencies:
path-parse "^1.0.5"
-resolve@~1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86"
+resolve@~1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies:
path-parse "^1.0.5"
@@ -10079,6 +10779,19 @@ response-stream@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/response-stream/-/response-stream-0.0.0.tgz#da4b17cc7684c98c962beb4d95f668c8dcad09d5"
+responselike@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
+ dependencies:
+ lowercase-keys "^1.0.0"
+
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -10112,6 +10825,10 @@ rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5
dependencies:
glob "^7.0.5"
+rimraf@~2.2.6:
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
+
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
@@ -10130,15 +10847,15 @@ rst-selector-parser@^2.2.3:
lodash.flattendeep "^4.4.0"
nearley "^2.7.10"
-run-async@^2.2.0:
+run-async@^2.0.0, run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
dependencies:
is-promise "^2.1.0"
rustbn.js@~0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.1.1.tgz#088b8c29d5f6d7d9f56ffb545f5d110e4a6801eb"
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.1.2.tgz#979fa0f9562216dd667c9d2cd179ae5d13830eff"
rx-lite-aggregates@^4.0.8:
version "4.0.8"
@@ -10150,11 +10867,27 @@ rx-lite@*, rx-lite@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
+rxjs@^5.4.2, rxjs@^5.5.2:
+ version "5.5.8"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.8.tgz#b2b0809a57614ad6254c03d7446dea0d83ca3791"
+ dependencies:
+ symbol-observable "1.0.1"
+
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
-samsam@1.x:
+safe-regex@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
+ dependencies:
+ ret "~0.1.10"
+
+safer-buffer@^2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+
+samsam@1.3.0, samsam@1.x:
version "1.3.0"
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
@@ -10181,6 +10914,10 @@ sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
+scoped-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
+
script-injector@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/script-injector/-/script-injector-1.0.0.tgz#f6f4c7f6a5dcc59e08246e76bdfc83a0a1406926"
@@ -10216,8 +10953,8 @@ scss-tokenizer@^0.2.3:
source-map "^0.4.2"
secp256k1@^3.0.1:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.4.0.tgz#1c905b256fa4ae5b9cc170e672dd59b4c5de46a4"
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0"
dependencies:
bindings "^1.2.1"
bip66 "^1.1.3"
@@ -10241,15 +10978,15 @@ semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
-semver-greatest-satisfied-range@^1.0.0:
+semver-greatest-satisfied-range@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b"
dependencies:
sver-compat "^1.5.0"
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@~5.4.1:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
semver@~5.0.1:
version "5.0.3"
@@ -10259,14 +10996,18 @@ semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
-send@0.16.1:
- version "0.16.1"
- resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
+semver@~5.4.1:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+
+send@0.16.2:
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
dependencies:
debug "2.6.9"
- depd "~1.1.1"
+ depd "~1.1.2"
destroy "~1.0.4"
- encodeurl "~1.0.1"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
@@ -10275,27 +11016,21 @@ send@0.16.1:
ms "2.0.0"
on-finished "~2.3.0"
range-parser "~1.2.0"
- statuses "~1.3.1"
+ statuses "~1.4.0"
-serve-static@1.13.1:
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
+serve-static@1.13.2:
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1"
dependencies:
- encodeurl "~1.0.1"
+ encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.2"
- send "0.16.1"
+ send "0.16.2"
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
-set-getter@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
- dependencies:
- to-object-path "^0.3.0"
-
set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
@@ -10331,8 +11066,8 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
- version "2.4.9"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
+ version "2.4.11"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"
@@ -10364,6 +11099,15 @@ shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+shell-parallel@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/shell-parallel/-/shell-parallel-1.0.3.tgz#bf262bf25967ca38546d77f1e2de3be1100fcdbe"
+ dependencies:
+ once "^1.4.0"
+ pify "^3.0.0"
+ ps-tree "^1.1.0"
+ yargs "^11.0.0"
+
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"
@@ -10373,7 +11117,19 @@ shell-quote@^1.4.2, shell-quote@^1.6.1:
array-reduce "~0.0.0"
jsonify "~0.0.0"
-shellwords@^0.1.0:
+shelljs@0.3.x:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1"
+
+shelljs@^0.8.0:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.1.tgz#729e038c413a2254c4078b95ed46e0397154a9f1"
+ dependencies:
+ glob "^7.0.0"
+ interpret "^1.0.0"
+ rechoir "^0.6.2"
+
+shellwords@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@@ -10411,6 +11167,10 @@ slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+slice-ansi@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@@ -10447,8 +11207,8 @@ snapdragon-util@^3.0.1:
kind-of "^3.2.0"
snapdragon@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370"
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d"
dependencies:
base "^0.11.1"
debug "^2.2.0"
@@ -10457,7 +11217,7 @@ snapdragon@^0.8.1:
map-cache "^0.2.2"
source-map "^0.5.6"
source-map-resolve "^0.5.0"
- use "^2.0.0"
+ use "^3.1.0"
sntp@1.x.x:
version "1.0.9"
@@ -10471,60 +11231,47 @@ sntp@2.x.x:
dependencies:
hoek "4.x.x"
-socket.io-adapter@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b"
- dependencies:
- debug "2.3.3"
- socket.io-parser "2.3.1"
-
socket.io-adapter@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
-socket.io-client@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.6.0.tgz#5b668f4f771304dfeed179064708386fa6717853"
+socket.io-client@2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e"
dependencies:
backo2 "1.0.2"
+ base64-arraybuffer "0.1.5"
component-bind "1.0.0"
component-emitter "1.2.1"
- debug "2.3.3"
- engine.io-client "1.8.0"
- has-binary "0.1.7"
+ debug "~2.6.4"
+ engine.io-client "~3.1.0"
+ has-cors "1.1.0"
indexof "0.0.1"
object-component "0.0.3"
+ parseqs "0.0.5"
parseuri "0.0.5"
- socket.io-parser "2.3.1"
+ socket.io-parser "~3.1.1"
to-array "0.1.4"
-socket.io-client@2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e"
+socket.io-client@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.0.tgz#0d0b21d460dc4ed36e57085136f2be0137ff20ff"
dependencies:
backo2 "1.0.2"
base64-arraybuffer "0.1.5"
component-bind "1.0.0"
component-emitter "1.2.1"
- debug "~2.6.4"
- engine.io-client "~3.1.0"
+ debug "~3.1.0"
+ engine.io-client "~3.2.0"
+ has-binary2 "~1.0.2"
has-cors "1.1.0"
indexof "0.0.1"
object-component "0.0.3"
parseqs "0.0.5"
parseuri "0.0.5"
- socket.io-parser "~3.1.1"
+ socket.io-parser "~3.2.0"
to-array "0.1.4"
-socket.io-parser@2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0"
- dependencies:
- component-emitter "1.1.2"
- debug "2.2.0"
- isarray "0.0.1"
- json3 "3.3.2"
-
socket.io-parser@~3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.3.tgz#ed2da5ee79f10955036e3da413bfd7f1e4d86c8e"
@@ -10534,17 +11281,13 @@ socket.io-parser@~3.1.1:
has-binary2 "~1.0.2"
isarray "2.0.1"
-socket.io@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.6.0.tgz#3e40d932637e6bd923981b25caf7c53e83b6e2e1"
+socket.io-parser@~3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077"
dependencies:
- debug "2.3.3"
- engine.io "1.8.0"
- has-binary "0.1.7"
- object-assign "4.1.0"
- socket.io-adapter "0.5.0"
- socket.io-client "1.6.0"
- socket.io-parser "2.3.1"
+ component-emitter "1.2.1"
+ debug "~3.1.0"
+ isarray "2.0.1"
socket.io@2.0.4:
version "2.0.4"
@@ -10556,6 +11299,17 @@ socket.io@2.0.4:
socket.io-client "2.0.4"
socket.io-parser "~3.1.1"
+socket.io@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.0.tgz#de77161795b6303e7aefc982ea04acb0cec17395"
+ dependencies:
+ debug "~3.1.0"
+ engine.io "~3.2.0"
+ has-binary2 "~1.0.2"
+ socket.io-adapter "~1.1.0"
+ socket.io-client "2.1.0"
+ socket.io-parser "~3.2.0"
+
socks-proxy-agent@2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3"
@@ -10579,8 +11333,8 @@ socks@~1.1.5:
smart-buffer "^1.0.13"
solc@^0.4.2:
- version "0.4.19"
- resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.19.tgz#1af1c4c292a0365a6977d4cbe3fbee7139b4b561"
+ version "0.4.21"
+ resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.21.tgz#6a7ecd505bfa0fc268330d5de6b9ae65c8c68264"
dependencies:
fs-extra "^0.30.0"
memorystream "^0.3.1"
@@ -10588,6 +11342,12 @@ solc@^0.4.2:
semver "^5.3.0"
yargs "^4.7.1"
+sort-keys@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
+ dependencies:
+ is-plain-obj "^1.0.0"
+
source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
@@ -10617,6 +11377,12 @@ source-map-support@^0.4.15:
dependencies:
source-map "^0.5.6"
+source-map-support@^0.5.3:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8"
+ dependencies:
+ 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"
@@ -10631,11 +11397,7 @@ source-map@0.1.31:
dependencies:
amdefine ">=0.0.4"
-source-map@0.X, "source-map@>= 0.1.2", source-map@^0.6.1, source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
-
-source-map@^0.1.38, source-map@~0.1.33:
+source-map@^0.1.38:
version "0.1.43"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
dependencies:
@@ -10647,10 +11409,14 @@ source-map@^0.4.2, source-map@^0.4.4, source-map@~0.4.0, source-map@~0.4.2:
dependencies:
amdefine ">=0.0.4"
-source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6:
+source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+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"
+
sparkles@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
@@ -10670,19 +11436,27 @@ spawn-wrap@^1.4.2:
signal-exit "^3.0.2"
which "^1.3.0"
-spdx-correct@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
+spdx-correct@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
dependencies:
- spdx-license-ids "^1.0.2"
+ spdx-expression-parse "^3.0.0"
+ spdx-license-ids "^3.0.0"
-spdx-expression-parse@~1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
+spdx-exceptions@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
-spdx-license-ids@^1.0.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+spdx-expression-parse@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
+ dependencies:
+ spdx-exceptions "^2.1.0"
+ spdx-license-ids "^3.0.0"
+
+spdx-license-ids@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
specificity@^0.3.0:
version "0.3.2"
@@ -10711,8 +11485,8 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
sshpk@^1.7.0:
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
@@ -10732,11 +11506,11 @@ state-toggle@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425"
-static-eval@~0.2.0:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b"
+static-eval@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.0.tgz#0e821f8926847def7b4b50cda5d55c04a9b13864"
dependencies:
- escodegen "~0.0.24"
+ escodegen "^1.8.1"
static-extend@^0.1.1:
version "0.1.2"
@@ -10745,30 +11519,37 @@ static-extend@^0.1.1:
define-property "^0.2.5"
object-copy "^0.1.0"
-static-module@^1.1.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.5.0.tgz#27da9883c41a8cd09236f842f0c1ebc6edf63d86"
+static-module@^2.2.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/static-module/-/static-module-2.2.3.tgz#72cf34b2ccb77d261f702da1dfda5df7853db14a"
dependencies:
concat-stream "~1.6.0"
- duplexer2 "~0.0.2"
- escodegen "~1.3.2"
+ convert-source-map "^1.5.1"
+ duplexer2 "~0.1.4"
+ escodegen "~1.9.0"
falafel "^2.1.0"
- has "^1.0.0"
- object-inspect "~0.4.0"
- quote-stream "~0.0.0"
- readable-stream "~1.0.27-1"
+ has "^1.0.1"
+ magic-string "^0.22.4"
+ merge-source-map "1.0.4"
+ object-inspect "~1.4.0"
+ quote-stream "~1.0.2"
+ readable-stream "~2.3.3"
shallow-copy "~0.0.1"
- static-eval "~0.2.0"
- through2 "~0.4.1"
+ static-eval "^2.0.0"
+ through2 "~2.0.3"
-statuses@1, "statuses@>= 1.3.1 < 2":
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+statuses@1, "statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
statuses@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+statuses@~1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+
stdin@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/stdin/-/stdin-0.0.1.tgz#d3041981aaec3dfdbc77a1b38d6372e38f5fb71e"
@@ -10815,12 +11596,12 @@ stream-exhaust@^1.0.1:
resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d"
stream-http@^2.0.0, stream-http@^2.7.2:
- version "2.7.2"
- resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.1.tgz#d0441be1a457a73a733a8a7b53570bebd9ef66a4"
dependencies:
builtin-status-codes "^3.0.0"
inherits "^2.0.1"
- readable-stream "^2.2.6"
+ readable-stream "^2.3.3"
to-arraybuffer "^1.0.0"
xtend "^4.0.0"
@@ -10846,6 +11627,12 @@ stream-splicer@^2.0.0:
inherits "^2.0.1"
readable-stream "^2.0.2"
+stream-to-observable@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10"
+ dependencies:
+ any-observable "^0.2.0"
+
streamroller@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b"
@@ -10855,12 +11642,20 @@ streamroller@^0.7.0:
mkdirp "^0.5.1"
readable-stream "^2.3.0"
+strict-uri-encode@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
+
string-length@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac"
dependencies:
strip-ansi "^3.0.0"
+string-template@~0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
+
string-width@^1.0.1, string-width@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -10884,9 +11679,9 @@ string.prototype.trim@~1.1.2:
es-abstract "^1.5.0"
function-bind "^1.0.2"
-string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+string_decoder@^1.0.0, string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
dependencies:
safe-buffer "~5.1.0"
@@ -10894,6 +11689,12 @@ string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+string_decoder@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+ dependencies:
+ safe-buffer "~5.1.0"
+
stringify-object@^3.0.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd"
@@ -10924,6 +11725,10 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
+strip-ansi@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
+
strip-bom-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
@@ -10941,6 +11746,10 @@ strip-bom@^2.0.0:
dependencies:
is-utf8 "^0.2.0"
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@@ -10957,6 +11766,10 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
+strip-json-comments@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
+
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -11097,13 +11910,13 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
dependencies:
has-flag "^1.0.0"
-supports-color@^4.0.0, supports-color@^4.4.0:
+supports-color@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
dependencies:
has-flag "^2.0.0"
-supports-color@^5.2.0, supports-color@^5.3.0:
+supports-color@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0"
dependencies:
@@ -11140,9 +11953,17 @@ sw-stream@^2.0.2:
readable-stream "^2.2.2"
through2 "^2.0.3"
+symbol-observable@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
+
+symbol-observable@^0.2.2:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40"
+
symbol-observable@^1.0.3, symbol-observable@^1.0.4:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
symbol-tree@^3.2.2:
version "3.2.2"
@@ -11155,12 +11976,12 @@ synesthesia@^1.0.1:
css-color-names "0.0.3"
syntax-error@^1.1.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.3.0.tgz#1ed9266c4d40be75dc55bf9bb1cb77062bb96ca1"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c"
dependencies:
- acorn "^4.0.3"
+ acorn-node "^1.2.0"
-table@^4.0.1:
+table@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
dependencies:
@@ -11171,6 +11992,17 @@ table@^4.0.1:
slice-ansi "1.0.0"
string-width "^2.1.1"
+table@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
+ dependencies:
+ ajv "^6.0.1"
+ ajv-keywords "^3.0.0"
+ chalk "^2.1.0"
+ lodash "^4.17.4"
+ slice-ansi "1.0.0"
+ string-width "^2.1.1"
+
tap-parser@^5.1.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-5.4.0.tgz#6907e89725d7b7fa6ae41ee2c464c3db43188aec"
@@ -11184,20 +12016,24 @@ tapable@^0.2.7, tapable@~0.2.5:
version "0.2.8"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
+tapable@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2"
+
tape@^4.4.0, tape@^4.5.1, tape@^4.6.0, tape@^4.6.2, tape@^4.6.3, tape@^4.8.0:
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e"
+ version "4.9.0"
+ resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.0.tgz#855c08360395133709d34d3fbf9ef341eb73ca6a"
dependencies:
deep-equal "~1.0.1"
defined "~1.0.0"
for-each "~0.3.2"
- function-bind "~1.1.0"
+ function-bind "~1.1.1"
glob "~7.1.2"
has "~1.0.1"
inherits "~2.0.3"
minimist "~1.2.0"
- object-inspect "~1.3.0"
- resolve "~1.4.0"
+ object-inspect "~1.5.0"
+ resolve "~1.5.0"
resumer "~0.0.0"
string.prototype.trim "~1.1.2"
through "~2.3.8"
@@ -11223,26 +12059,33 @@ tar@^2.0.0, tar@^2.2.1:
fstream "^1.0.2"
inherits "2"
-test-exclude@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
+temp@^0.8.1:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59"
+ dependencies:
+ os-tmpdir "^1.0.0"
+ rimraf "~2.2.6"
+
+test-exclude@^4.2.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa"
dependencies:
arrify "^1.0.1"
- micromatch "^2.3.11"
+ micromatch "^3.1.8"
object-assign "^4.1.0"
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
testem@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/testem/-/testem-2.0.0.tgz#b05c96200c7ac98bae998d71c94c0c5345907d13"
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/testem/-/testem-2.2.1.tgz#7bcda44eeb34287d918b3c8b9c6863d26a616557"
dependencies:
backbone "^1.1.2"
bluebird "^3.4.6"
charm "^1.0.0"
commander "^2.6.0"
consolidate "^0.14.0"
- execa "^0.9.0"
+ execa "^0.10.0"
express "^4.10.7"
fireworm "^0.7.0"
glob "^7.0.4"
@@ -11259,7 +12102,7 @@ testem@^2.0.0:
npmlog "^4.0.0"
printf "^0.2.3"
rimraf "^2.4.4"
- socket.io "1.6.0"
+ socket.io "^2.1.0"
spawn-args "^0.2.0"
styled_string "0.0.1"
tap-parser "^5.1.0"
@@ -11274,8 +12117,12 @@ text-table@^0.2.0, text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
textarea-caret@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.0.2.tgz#f360c48699aa1abf718680a43a31a850665c2caf"
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.1.0.tgz#5d5a35bb035fd06b2ff0e25d5359e97f2655087f"
+
+textextensions@2:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286"
textextensions@~1.0.0:
version "1.0.2"
@@ -11300,7 +12147,7 @@ through2-filter@^2.0.0:
through2 "~2.0.0"
xtend "~4.0.0"
-through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3, through2@~2.0.0:
+through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3, through2@~2.0.0, through2@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
dependencies:
@@ -11321,6 +12168,13 @@ through2@^1.0.0, through2@^1.1.1:
readable-stream ">=1.1.13-1 <1.2.0-0"
xtend ">=4.0.0 <4.1.0-0"
+through2@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f"
+ dependencies:
+ readable-stream "~1.1.9"
+ xtend "~2.1.1"
+
through2@~0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b"
@@ -11328,13 +12182,6 @@ through2@~0.4.1:
readable-stream "~1.0.17"
xtend "~2.1.1"
-through2@~0.5.0:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7"
- dependencies:
- readable-stream "~1.0.17"
- xtend "~3.0.0"
-
through@2, "through@>=2.2.7 <3", through@X.X.X, through@^2.3.4, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.4, through@~2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -11357,6 +12204,10 @@ time-stamp@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
+timed-out@^4.0.0, timed-out@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
+
timers-browserify@^1.0.1:
version "1.4.2"
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
@@ -11364,14 +12215,14 @@ timers-browserify@^1.0.1:
process "~0.11.0"
timers-browserify@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae"
dependencies:
setimmediate "^1.0.4"
timers-ext@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204"
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.5.tgz#77147dd4e76b660c2abb8785db96574cbbd12922"
dependencies:
es5-ext "~0.10.14"
next-tick "1"
@@ -11428,13 +12279,14 @@ to-regex-range@^2.1.0:
is-number "^3.0.0"
repeat-string "^1.6.1"
-to-regex@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae"
+to-regex@^3.0.1, to-regex@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
dependencies:
- define-property "^0.2.5"
- extend-shallow "^2.0.1"
- regex-not "^1.0.0"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ regex-not "^1.0.2"
+ safe-regex "^1.1.0"
to-through@^2.0.0:
version "2.0.0"
@@ -11447,8 +12299,8 @@ toggle-selection@^1.0.3:
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
dependencies:
punycode "^1.4.1"
@@ -11463,8 +12315,8 @@ traverse@~0.6.3:
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"
treeify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.0.1.tgz#69b3cd022022a168424e7cfa1ced44c939d3eb2f"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8"
trim-newlines@^1.0.0:
version "1.0.0"
@@ -11507,11 +12359,11 @@ tsscmp@~1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97"
-tty-browserify@0.0.0, tty-browserify@~0.0.0:
+tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
-tty-browserify@0.0.1:
+tty-browserify@0.0.1, tty-browserify@~0.0.0:
version "0.0.1"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
@@ -11544,15 +12396,15 @@ type-detect@^1.0.0:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
type-detect@^4.0.0, type-detect@^4.0.5:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2"
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
-type-is@~1.6.10, type-is@~1.6.15:
- version "1.6.15"
- resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
+type-is@~1.6.10, type-is@~1.6.15, type-is@~1.6.16:
+ version "1.6.16"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
dependencies:
media-typer "0.3.0"
- mime-types "~2.1.15"
+ mime-types "~2.1.18"
typedarray@^0.0.6, typedarray@~0.0.5:
version "0.0.6"
@@ -11562,14 +12414,7 @@ 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"
-uglify-es@^3.0.15:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.3.tgz#095f5314d2a5d27e215390e50fa90751473dac2f"
- dependencies:
- commander "~2.12.1"
- source-map "~0.6.1"
-
-uglify-es@^3.3.9:
+uglify-es@^3.0.15, uglify-es@^3.3.9:
version "3.3.10"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.10.tgz#8b0b7992cebe20edc26de1bf325cef797b8f3fa5"
dependencies:
@@ -11586,17 +12431,17 @@ uglify-js@^2.6, uglify-js@^2.8.27:
uglify-to-browserify "~1.0.0"
uglify-js@^3.0.5:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.7.tgz#28463e7c7451f89061d2b235e30925bf5625e14d"
+ version "3.3.20"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.20.tgz#dc8bdee7d454c7d31dddc36f922d170bfcee3a0a"
dependencies:
- commander "~2.13.0"
+ commander "~2.15.0"
source-map "~0.6.1"
uglify-to-browserify@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
-uglifyify@^4.0.2:
+uglifyify@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/uglifyify/-/uglifyify-4.0.5.tgz#49c1fca9828c10a5a8e8d70f191a95f7ab475911"
dependencies:
@@ -11610,17 +12455,13 @@ uid-number@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
-ultron@1.0.x:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
-
ultron@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
umd@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf"
unc-path-regex@^0.1.2:
version "0.1.2"
@@ -11634,6 +12475,10 @@ underscore@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+underscore@~1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
+
underscore@~1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
@@ -11688,6 +12533,10 @@ uniq@^1.0.0, uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
+unique-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
+
unique-stream@^2.0.2:
version "2.2.1"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369"
@@ -11709,7 +12558,7 @@ 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"
-unist-util-visit@^1.1.0, unist-util-visit@^1.1.3:
+unist-util-visit@^1.1.0, unist-util-visit@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444"
dependencies:
@@ -11730,14 +12579,40 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
+untildify@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1"
+
upath@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d"
+uri-js@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-3.0.2.tgz#f90b858507f81dea4dcfbb3c4c3dbfa2b557faaa"
+ dependencies:
+ punycode "^2.1.0"
+
urix@^0.1.0, urix@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
+url-parse-lax@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
+ dependencies:
+ prepend-http "^1.0.1"
+
+url-parse-lax@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
+ dependencies:
+ prepend-http "^2.0.0"
+
+url-to-options@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
+
url@^0.11.0, url@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -11745,19 +12620,17 @@ url@^0.11.0, url@~0.11.0:
punycode "1.3.2"
querystring "0.2.0"
-use@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8"
+use@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544"
dependencies:
- define-property "^0.2.5"
- isobject "^3.0.0"
- lazy-cache "^2.0.2"
+ kind-of "^6.0.2"
useragent@^2.1.12:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
dependencies:
- lru-cache "2.2.x"
+ lru-cache "4.1.x"
tmp "0.0.x"
utf8@^2.1.1:
@@ -11794,16 +12667,20 @@ uuid@^2.0.1:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
uuid@^3.0.0, uuid@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
uws@~9.14.0:
version "9.14.0"
resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95"
+v8-compile-cache@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4"
+
v8flags@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b"
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.2.tgz#ad6a78a20a6b23d03a8debc11211e3cc23149477"
dependencies:
homedir-polyfill "^1.0.1"
@@ -11812,11 +12689,15 @@ valid-url@^1.0.9:
resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200"
validate-npm-package-license@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338"
dependencies:
- spdx-correct "~1.0.0"
- spdx-expression-parse "~1.0.0"
+ spdx-correct "^3.0.0"
+ spdx-expression-parse "^3.0.0"
+
+value-equal@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
value-or-function@^3.0.0:
version "3.0.0"
@@ -11876,10 +12757,9 @@ vinyl-file@^2.0.0:
vinyl "^1.1.0"
vinyl-fs@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.1.tgz#74af5f6836a1cf414d35eeb3c10f2e65fc2a2c10"
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.2.tgz#1b86258844383f57581fcaac081fe09ef6d6d752"
dependencies:
- flush-write-stream "^1.0.0"
fs-mkdirp-stream "^1.0.0"
glob-stream "^6.1.0"
graceful-fs "^4.0.0"
@@ -11888,6 +12768,7 @@ vinyl-fs@^3.0.0:
lead "^1.0.0"
object.assign "^4.0.4"
pumpify "^1.3.5"
+ readable-stream "^2.3.3"
remove-bom-buffer "^3.0.0"
remove-bom-stream "^1.2.0"
resolve-options "^1.1.0"
@@ -11938,7 +12819,7 @@ vinyl@^1.1.0:
clone-stats "^0.0.1"
replace-ext "0.0.1"
-vinyl@^2.0.0, vinyl@^2.1.0:
+vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c"
dependencies:
@@ -11949,6 +12830,10 @@ vinyl@^2.0.0, vinyl@^2.1.0:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
+vlq@^0.2.2:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
+
vm-browserify@0.0.4, vm-browserify@~0.0.1:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
@@ -11983,11 +12868,11 @@ warning@^3.0.0:
loose-envify "^1.0.0"
watchify@^3.9.0:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.9.0.tgz#f075fd2e8a86acde84cedba6e5c2a0bedd523d9e"
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.11.0.tgz#03f1355c643955e7ab8dcbf399f624644221330f"
dependencies:
anymatch "^1.3.0"
- browserify "^14.0.0"
+ browserify "^16.1.0"
chokidar "^1.0.0"
defined "^1.0.0"
outpipe "^1.1.0"
@@ -11995,12 +12880,12 @@ watchify@^3.9.0:
xtend "^4.0.0"
watchpack@^1.3.1:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed"
dependencies:
- async "^2.1.2"
- chokidar "^1.7.0"
+ chokidar "^2.0.2"
graceful-fs "^4.1.2"
+ neo-async "^2.5.0"
weak@^1.0.0:
version "1.0.1"
@@ -12009,31 +12894,7 @@ weak@^1.0.0:
bindings "^1.2.1"
nan "^2.0.5"
-web3-provider-engine@^13.3.2:
- version "13.4.0"
- resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.4.0.tgz#78c2794ba926d0c5b94c6e8955abb994bb8e8854"
- dependencies:
- async "^2.5.0"
- clone "^2.0.0"
- eth-block-tracker "^2.2.2"
- eth-sig-util "^1.3.0"
- ethereumjs-block "^1.2.2"
- ethereumjs-tx "^1.2.0"
- ethereumjs-util "^5.1.1"
- ethereumjs-vm "^2.0.2"
- fetch-ponyfill "^4.0.0"
- json-rpc-error "^2.0.0"
- json-stable-stringify "^1.0.1"
- promise-to-callback "^1.0.0"
- readable-stream "^2.2.9"
- request "^2.67.0"
- semaphore "^1.0.3"
- solc "^0.4.2"
- tape "^4.4.0"
- xhr "^2.2.0"
- xtend "^4.0.1"
-
-web3-provider-engine@^13.8.0:
+web3-provider-engine@^13.3.2, web3-provider-engine@^13.8.0:
version "13.8.0"
resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz#4c7c1ad2af5f1fe10343b8a65495879a2f9c00df"
dependencies:
@@ -12074,8 +12935,8 @@ web3@^0.18.4:
xmlhttprequest "*"
web3@^0.20.1:
- version "0.20.3"
- resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.3.tgz#caa44373dc8815ac8767bddb6ba73073964caa8b"
+ version "0.20.6"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.6.tgz#3e97306ae024fb24e10a3d75c884302562215120"
dependencies:
bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
crypto-js "^3.1.4"
@@ -12087,6 +12948,43 @@ webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+webpack-addons@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a"
+ dependencies:
+ jscodeshift "^0.4.0"
+
+webpack-cli@^2.0.9:
+ version "2.0.14"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.0.14.tgz#71d03d8c10547c1dfd674f71ff3b0457c33a74cd"
+ dependencies:
+ chalk "^2.3.2"
+ cross-spawn "^6.0.5"
+ diff "^3.5.0"
+ enhanced-resolve "^4.0.0"
+ envinfo "^4.4.2"
+ glob-all "^3.1.0"
+ global-modules "^1.0.0"
+ got "^8.2.0"
+ import-local "^1.0.0"
+ inquirer "^5.1.0"
+ interpret "^1.0.4"
+ jscodeshift "^0.5.0"
+ listr "^0.13.0"
+ loader-utils "^1.1.0"
+ lodash "^4.17.5"
+ log-symbols "^2.2.0"
+ mkdirp "^0.5.1"
+ p-each-series "^1.0.0"
+ p-lazy "^1.0.0"
+ prettier "^1.5.3"
+ supports-color "^5.3.0"
+ v8-compile-cache "^1.1.2"
+ webpack-addons "^1.1.5"
+ yargs "^11.1.0"
+ yeoman-environment "^2.0.0"
+ yeoman-generator "^2.0.3"
+
webpack-sources@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
@@ -12094,7 +12992,7 @@ webpack-sources@^1.0.1:
source-list-map "^2.0.0"
source-map "~0.6.1"
-webpack@^2.2.1:
+webpack@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.7.0.tgz#b2a1226804373ffd3d03ea9c6bd525067034f6b1"
dependencies:
@@ -12138,8 +13036,12 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
iconv-lite "0.4.19"
whatwg-fetch@>=0.10.0:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
+
+whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4"
whatwg-url@^6.4.0:
version "6.4.0"
@@ -12224,7 +13126,7 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-write-file-atomic@^1.1.4:
+write-file-atomic@^1.1.4, write-file-atomic@^1.2.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
dependencies:
@@ -12242,13 +13144,6 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"
-ws@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018"
- dependencies:
- options ">=0.0.5"
- ultron "1.0.x"
-
ws@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289"
@@ -12264,10 +13159,6 @@ ws@~3.3.1:
safe-buffer "~5.1.0"
ultron "~1.1.0"
-wtf-8@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"
-
x-is-function@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e"
@@ -12312,10 +13203,6 @@ xmldom@^0.1.19:
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
-xmlhttprequest-ssl@1.5.3:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d"
-
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
@@ -12338,10 +13225,6 @@ xtend@~2.1.1, xtend@~2.1.2:
dependencies:
object-keys "~0.4.0"
-xtend@~3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"
-
y18n@^3.2.0, y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
@@ -12375,15 +13258,17 @@ yargs-parser@^8.0.0:
dependencies:
camelcase "^4.1.0"
-yargs@^1.2.6:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
+yargs-parser@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
+ dependencies:
+ camelcase "^4.1.0"
-yargs@^10.0.3:
- version "10.0.3"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"
+yargs@11.1.0, yargs@^11.0.0, yargs@^11.1.0:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
dependencies:
- cliui "^3.2.0"
+ cliui "^4.0.0"
decamelize "^1.1.1"
find-up "^2.1.0"
get-caller-file "^1.0.1"
@@ -12394,7 +13279,11 @@ yargs@^10.0.3:
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
- yargs-parser "^8.0.0"
+ yargs-parser "^9.0.2"
+
+yargs@^1.2.6:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
yargs@^3.5.4:
version "3.32.0"
@@ -12493,3 +13382,51 @@ yazl@^2.1.0:
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
+
+yeoman-environment@^2.0.0, yeoman-environment@^2.0.5:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.0.6.tgz#ae1b21d826b363f3d637f88a7fc9ea7414cb5377"
+ dependencies:
+ chalk "^2.1.0"
+ debug "^3.1.0"
+ diff "^3.3.1"
+ escape-string-regexp "^1.0.2"
+ globby "^6.1.0"
+ grouped-queue "^0.3.3"
+ inquirer "^3.3.0"
+ is-scoped "^1.0.0"
+ lodash "^4.17.4"
+ log-symbols "^2.1.0"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^3.0.2"
+
+yeoman-generator@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-2.0.3.tgz#19426ed22687ffe05d31526c3f1c2cf67ba768f3"
+ dependencies:
+ async "^2.6.0"
+ chalk "^2.3.0"
+ cli-table "^0.3.1"
+ cross-spawn "^5.1.0"
+ dargs "^5.1.0"
+ dateformat "^3.0.2"
+ debug "^3.1.0"
+ detect-conflict "^1.0.0"
+ error "^7.0.2"
+ find-up "^2.1.0"
+ github-username "^4.0.0"
+ istextorbinary "^2.1.0"
+ lodash "^4.17.4"
+ make-dir "^1.1.0"
+ mem-fs-editor "^3.0.2"
+ minimist "^1.2.0"
+ pretty-bytes "^4.0.2"
+ read-chunk "^2.1.0"
+ read-pkg-up "^3.0.0"
+ rimraf "^2.6.2"
+ run-async "^2.0.0"
+ shelljs "^0.8.0"
+ text-table "^0.2.0"
+ through2 "^2.0.0"
+ yeoman-environment "^2.0.5"