diff --git a/.circleci/config.yml b/.circleci/config.yml index c14909783..ee2054130 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,12 +6,28 @@ workflows: jobs: - prep-deps-npm - prep-deps-firefox + - prep-build: + requires: + - prep-deps-npm - prep-scss: requires: - prep-deps-npm - test-lint: requires: - prep-deps-npm + - test-e2e: + requires: + - prep-deps-npm + - prep-build + - job-screens: + requires: + - prep-deps-npm + - prep-build + - job-publish: + requires: + - prep-deps-npm + - prep-build + - job-screens - test-unit: requires: - prep-deps-npm @@ -33,6 +49,16 @@ workflows: - prep-deps-npm - prep-deps-firefox - prep-scss + - all-tests-pass: + requires: + - test-lint + - test-unit + - test-e2e + - job-screens + - test-integration-mascara-chrome + - test-integration-mascara-firefox + - test-integration-flat-chrome + - test-integration-flat-firefox jobs: prep-deps-npm: @@ -41,7 +67,7 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Install deps via npm command: npm install @@ -49,6 +75,10 @@ jobs: key: dependency-cache-{{ checksum "package-lock.json" }} paths: - node_modules + - save_cache: + key: dependency-cache-{{ .Revision }} + paths: + - node_modules prep-deps-firefox: docker: @@ -65,6 +95,24 @@ jobs: paths: - firefox + prep-build: + docker: + - image: circleci/node:8-browsers + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ .Revision }} + - run: + name: build:dist + command: npm run dist + - run: + name: build:debug + command: find dist/ -type f -exec md5sum {} \; | sort -k 2 + - save_cache: + key: build-cache-{{ .Revision }} + paths: + - dist + - builds prep-scss: docker: @@ -72,7 +120,7 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Get Scss Cache key # this allows us to checksum against a whole directory @@ -91,18 +139,81 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Test command: npm run lint + test-e2e: + docker: + - image: circleci/node:8-browsers + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ .Revision }} + - restore_cache: + key: build-cache-{{ .Revision }} + - run: + name: Test + command: npm run test:e2e + - store_artifacts: + path: test-artifacts + destination: test-artifacts + + job-screens: + docker: + - image: circleci/node:8-browsers + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ .Revision }} + - restore_cache: + key: build-cache-{{ .Revision }} + - run: + name: Test + command: npm run test:screens + - save_cache: + key: job-screens-{{ .Revision }} + paths: + - test-artifacts + + job-publish: + docker: + - image: circleci/node:8-browsers + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ .Revision }} + - restore_cache: + key: build-cache-{{ .Revision }} + - restore_cache: + key: job-screens-{{ .Revision }} + - store_artifacts: + path: dist/mascara + destination: builds/mascara + - store_artifacts: + path: dist/sourcemaps + destination: builds/sourcemaps + - store_artifacts: + path: builds + destination: builds + - store_artifacts: + path: test-artifacts + destination: test-artifacts + - run: + name: build:announce + command: ./development/metamaskbot-build-announce.js + - run: + name: sentry sourcemaps upload + command: npm run sentry:publish + test-unit: docker: - image: circleci/node:8-browsers steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: test:coverage command: npm run test:coverage @@ -124,7 +235,7 @@ jobs: && sudo mv /usr/bin/firefox /usr/bin/firefox-old && sudo ln -s /opt/firefox58/firefox /usr/bin/firefox - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Get Scss Cache key # this allows us to checksum against a whole directory @@ -143,7 +254,7 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Get Scss Cache key # this allows us to checksum against a whole directory @@ -171,7 +282,7 @@ jobs: && sudo mv /usr/bin/firefox /usr/bin/firefox-old && sudo ln -s /opt/firefox58/firefox /usr/bin/firefox - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Get Scss Cache key # this allows us to checksum against a whole directory @@ -190,7 +301,7 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ .Revision }} - run: name: Get Scss Cache key # this allows us to checksum against a whole directory @@ -200,3 +311,11 @@ jobs: - run: name: test:integration:mascara command: npm run test:mascara + + all-tests-pass: + docker: + - image: circleci/node:8-browsers + steps: + - run: + name: All Tests Passed + command: echo 'weew - everything passed!' diff --git a/.eslintrc b/.eslintrc index 4fa7c2d7f..8af71bf4e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -29,7 +29,8 @@ "plugins": [ "mocha", "chai", - "react" + "react", + "json" ], "globals": { @@ -41,6 +42,7 @@ }, "rules": { + "no-restricted-globals": ["error", "event"], "accessor-pairs": 2, "arrow-spacing": [2, { "before": true, "after": true }], "block-spacing": [2, "always"], diff --git a/.gitignore b/.gitignore index f2a678777..dee5ec220 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,8 @@ test/background.js test/bundle.js test/test-bundle.js +test-artifacts + #ignore css output and sourcemaps ui/app/css/output/ diff --git a/CHANGELOG.md b/CHANGELOG.md index fa4493278..45eaa6908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,42 @@ ## Current Master +## 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" + +## 4.5.1 Tue Apr 03 2018 + +- Fix default network (should be mainnet not Rinkeby) +- Fix Sentry automated error reporting endpoint + +## 4.5.0 Mon Apr 02 2018 + +- (beta ui) Internationalization: Select your preferred language in the settings screen +- Internationalization: various locale improvements +- Fix bug where the "Reset account" feature would not clear the network cache. +- Increase maximum gas limit, to allow very gas heavy transactions, since block gas limits have been stable. + ## 4.4.0 Mon Mar 26 2018 - Internationalization: Taiwanese, Thai, Slovenian diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index 0bdce516c..1d2619672 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -14,9 +14,15 @@ "address": { "message": "Adresse" }, + "addCustomToken": { + "message": "Eigenen Token hinzufügen" + }, "addToken": { "message": "Token hinzufügen" }, + "addTokens": { + "message": "Token hinzufügen" + }, "amount": { "message": "Betrag" }, @@ -31,9 +37,15 @@ "message": "MetaMask", "description": "Der Name der Erweiterung" }, + "approved": { + "message": "Genehmigt" + }, "attemptingConnect": { "message": "Versuch mit der Blockchain zu verbinden." }, + "attributions": { + "message": "Was wir verwenden" + }, "available": { "message": "Verfügbar" }, @@ -43,6 +55,9 @@ "balance": { "message": "Guthaben:" }, + "balances": { + "message": "Deine Guthaben" + }, "balanceIsInsufficientGas": { "message": "Guthaben unzureichend für den aktuellen gesamten Gasbetrag" }, @@ -69,7 +84,7 @@ "message": "Auf Coinbase kaufen" }, "buyCoinbaseExplainer": { - "message": "Coinbase ist die weltweit bekannteste Möglichkeit bitcoin, ethereum und litecoin zu kaufen und verkaufen." + "message": "Coinbase ist die weltweit bekannteste Art und Weise um bitcoin, ethereum und litecoin zu kaufen und verkaufen." }, "ok": { "message": "Ok" @@ -105,7 +120,7 @@ "message": "Zu Coinbase fortfahren" }, "contractDeployment": { - "message": "Smart Contract ausführen" + "message": "Smart Contract Ausführung" }, "conversionProgress": { "message": "Umtausch in Arbeit" @@ -148,7 +163,7 @@ "description": "Börsentyp (Kryptowährungen)" }, "currentConversion": { - "message": "Aktueller Umtausch" + "message": "Aktuelle Tauschwährung" }, "currentNetwork": { "message": "Aktuelles Netzwerk" @@ -185,7 +200,7 @@ "description": "Teilt dem Benutzer mit welchen Token er beim Einzahlen mit Shapeshift ausgewählt hat" }, "depositEth": { - "message": "Eth einzahlen" + "message": "Eth kaufen" }, "depositEther": { "message": "Ether einzahlen" @@ -217,7 +232,7 @@ "done": { "message": "Fertig" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Statelogs herunterladen" }, "dropped": { @@ -274,7 +289,7 @@ "message": "Folge uns auf Twitter" }, "from": { - "message": "von" + "message": "Von" }, "fromToSame": { "message": "Ziel- und Ursprungsadresse dürfen nicht identisch sein" @@ -347,14 +362,14 @@ "message": "Es erlaubt dir ether & Token zu halten und dient dir als Verbindung zu dezentralisierten Applikationen." }, "import": { - "message": "Import", + "message": "Importieren", "description": "Button um den Account aus einer ausgewählten Datei zu importieren" }, "importAccount": { "message": "Account importieren" }, "importAccountMsg": { - "message":" Importierte Accounts werden nicht mit der Seed Wörterfolge deines ursprünglichen MetaMask Accounts verknüpft. Erfahre mehr über importierte Accounts." + "message":" Importierte Accounts werden nicht mit der Seed-Wörterfolge deines ursprünglichen MetaMask Accounts verknüpft. Erfahre mehr über importierte Accounts." }, "importAnAccount": { "message": "Einen Account importieren" @@ -369,7 +384,7 @@ "infoHelp": { "message": "Info & Hilfe" }, - "insufficientFunds": { + "insufficientFunds": { "message": "Nicht genügend Guthaben." }, "insufficientTokens": { @@ -441,10 +456,10 @@ "message": "Frei" }, "loweCaseWords": { - "message": "Die Wörter der Seed Wörterfolgen sind alle kleingeschrieben" + "message": "Die Wörter der Seed-Wörterfolgen sind alle kleingeschrieben" }, "mainnet": { - "message": "Ethereum Hauptnetzwerk (Main Net)" + "message": "Ethereum Main Net" }, "message": { "message": "Nachricht" @@ -541,7 +556,7 @@ "description": "Für den Import eine Accounts mit Hilfe eines Private Keys" }, "pasteSeed": { - "message": "Füge deine Seed Wörterfolge hier ein!" + "message": "Füge deine Seed-Wörterfolge hier ein!" }, "personalAddressDetected": { "message": "Personalisierte Adresse identifiziert. Bitte füge die Token Contract Adresse ein." @@ -557,7 +572,7 @@ "description": "Wähle diesen Dateityp um damit einen Account zu importieren" }, "privateKeyWarning": { - "message": "Warnung: Niemals jemanden deinen Private Key mitteilen. Jeder der im Besitz deines Private Keys ist, kann jegliches Guthaben deines Accounts stehlen." + "message": "Warnung: Niemals jemanden deinen Private Key mitteilen. Jeder der im Besitz deines Private Keys ist, kann jegliches Guthaben deines Accounts stehlen." }, "privateNetwork": { "message": "Privates Netzwerk" @@ -566,7 +581,7 @@ "message": "QR Code anzeigen" }, "readdToken": { - "message": "Du kannst diesen Token zukünftig wieder hinzufügen indem du in den Menüpunkt \"Token hinzufügen\" in den Einstellungen deines Accounts gehst." + "message": "Du kannst diesen Token immer erneut hinzufügen, indem du in den Menüpunkt \"Token hinzufügen\" in den Einstellungen deines Accounts gehst." }, "readMore": { "message": "Hier mehr erfahren." @@ -590,7 +605,7 @@ "message": "Account zurücksetzten" }, "restoreFromSeed": { - "message": "Mit Hilfe der Seed Wörterfolge wiederherstellen." + "message": "Mit Hilfe der Seed-Wörterfolge wiederherstellen." }, "restoreVault": { "message": "Vault wiederherstellen" @@ -605,13 +620,13 @@ "message": "Wallet Seed" }, "revealSeedWords": { - "message": "Seed Wörterfolge anzeigen" + "message": "Seed-Wörterfolge anzeigen" }, "revealSeedWordsWarning": { - "message": "Bitte niemals deine Seed Wörterfolge an einem öffentlichen Ort kenntlich machen. Mit diesen Wörtern können alle deine Accounts gestohlen werden." + "message": "Bitte niemals deine Seed-Wörterfolge an einem öffentlichen Ort kenntlich machen. Mit diesen Wörtern können alle deine Accounts gestohlen werden." }, "revert": { - "message": "Zurück gehen" + "message": "Rückgängig machen" }, "rinkeby": { "message": "Rinkeby Testnetzwerk" @@ -623,7 +638,7 @@ "message": "Aktueller RPC" }, "connectingToMainnet": { - "message": "Verbinde zum Ethereum Hauptnetzwerk (Main Net)" + "message": "Verbinde zum Ethereum Main Net" }, "connectingToRopsten": { "message": " Verbinde zum Ropsten Testnetzwerk" @@ -649,7 +664,7 @@ "description": "Prozess des Exportieren eines Accounts" }, "saveSeedAsFile": { - "message": "Seed Wörterfolge als Datei speichern" + "message": "Seed-Wörterfolge als Datei speichern" }, "search": { "message": "Suche" @@ -661,7 +676,7 @@ "message": "Neues Passwort (min. 8 Zeichen)" }, "seedPhraseReq": { - "message": "Seed Wörterfolgen bestehen aus 12 Wörtern" + "message": "Seed-Wörterfolgen bestehen aus 12 Wörtern" }, "select": { "message": "Auswählen" @@ -685,7 +700,7 @@ "message": "Token senden" }, "onlySendToEtherAddress": { - "message": "ETH nur zu einer Ethereum Adresse senden." + "message": "ETH unbedingt nur zu einer Ethereum Adresse senden." }, "sendTokensAnywhere": { "message": "Token zu einer beliebigen Person mit einem Ethereumaccount senden" @@ -742,7 +757,7 @@ "message": "Einreichen" }, "submitted": { - "message": "Eingereicht" + "message": "Abgeschickt" }, "supportCenter": { "message": "Gehe zu unserem Support Center" @@ -782,7 +797,7 @@ "message": "Tokensymbol" }, "tokenWarning1": { - "message": "Behalte die Token die du mit deinem MetaMask Account gekauft hast im Auge. Wenn du Token mit einem anderen Account gekauft hast, werden diese hier nicht angezeigt." + "message": "Behalte die Token die du mit deinem MetaMask Account gekauft hast im Blick. Wenn du Token mit einem anderen Account gekauft hast, werden diese hier nicht angezeigt." }, "total": { "message": "Gesamt" @@ -853,7 +868,7 @@ "message": " Account einsehen" }, "visitWebSite": { - "message": "Gehe zu unsere Webseite" + "message": "Gehe zu unserer Webseite" }, "warning": { "message": "Warnung" diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 0bfa992b4..b372326ee 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -56,7 +56,7 @@ "message": "Balance:" }, "balances": { - "message": "Your balances" + "message": "Token balance(s)" }, "balanceIsInsufficientGas": { "message": "Insufficient balance for current gas total" @@ -185,7 +185,7 @@ }, "decimal": { "message": "Decimals of Precision" - }, + }, "defaultNetwork": { "message": "The default network for Ether transactions is Main Net." }, @@ -235,7 +235,7 @@ "done": { "message": "Done" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Download State Logs" }, "dropped": { @@ -671,6 +671,12 @@ "save": { "message": "Save" }, + "reprice_title": { + "message": "Reprice Transaction" + }, + "reprice_subtitle": { + "message": "Increase your gas price to attempt to overwrite and speed up your transaction" + }, "saveAsFile": { "message": "Save as File", "description": "Account export process" @@ -820,6 +826,9 @@ "transactions": { "message": "transactions" }, + "transactionError": { + "message": "Transaction Error. Exception thrown in contract code." + }, "transactionMemo": { "message": "Transaction memo (optional)" }, @@ -884,7 +893,7 @@ }, "visitWebSite": { "message": "Visit our web site" - }, + }, "warning": { "message": "Warning" }, diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index fa28b09da..f287674f1 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -247,7 +247,7 @@ "done": { "message": "Completo" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Descargar logs de estado" }, "dropped": { diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json index 3703faa13..323f4b4b3 100644 --- a/app/_locales/hn/messages.json +++ b/app/_locales/hn/messages.json @@ -223,7 +223,7 @@ "done": { "message": "संपन्न" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "राज्य लॉग डाउनलोड करें" }, "edit": { diff --git a/app/_locales/index.json b/app/_locales/index.json new file mode 100644 index 000000000..c085deb72 --- /dev/null +++ b/app/_locales/index.json @@ -0,0 +1,19 @@ +[ + { "code": "de", "name": "German" }, + { "code": "en", "name": "English" }, + { "code": "es", "name": "Spanish" }, + { "code": "fr", "name": "French" }, + { "code": "hn", "name": "Hindi" }, + { "code": "it", "name": "Italian" }, + { "code": "ja", "name": "Japanese" }, + { "code": "ko", "name": "Korean" }, + { "code": "nl", "name": "Dutch" }, + { "code": "ph", "name": "Tagalog" }, + { "code": "pt", "name": "Portuguese" }, + { "code": "ru", "name": "Russian" }, + { "code": "sl", "name": "Slovenian" }, + { "code": "th", "name": "Thai" }, + { "code": "vi", "name": "Vietnamese" }, + { "code": "zh_CN", "name": "Mandarin" }, + { "code": "zh_TW", "name": "Taiwanese" } +] diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index f54ef98ca..ef3ed4025 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -223,7 +223,7 @@ "done": { "message": "Finito" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Scarica i log di Stato" }, "edit": { diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 2c4f271b7..3a664ec00 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -49,6 +49,9 @@ "balance": { "message": "残高:" }, + "balances": { + "message": "トークン残高" + }, "balanceIsInsufficientGas": { "message": "現在のガス総量に対して残高が不足しています" }, @@ -160,20 +163,20 @@ "message": "DENとは、あなたのパスワードが暗号化されたMetaMask内のストレージです。" }, "deposit": { - "message": "お振込み" + "message": "振込" }, "depositBTC": { "message": "BTCを下記のアドレスへ振込んでください:" }, "depositCoin": { - "message": "あなたの $1を下記のアドレスへ振込んでください", + "message": "$1を下記のアドレスへ振込んでください", "description": "Tells the user what coin they have selected to deposit with shapeshift" }, "depositEth": { "message": "ETHを入金" }, "depositEther": { - "message": "Etherを入金" + "message": "Etherを振込" }, "depositFiat": { "message": "法定通貨でデポジット" @@ -215,7 +218,7 @@ "message": "パスワードを入力" }, "etherscanView": { - "message": "Etherscanでアカウントを参照" + "message": "Etherscanでアカウントを確認" }, "exchangeRate": { "message": "交換レート" @@ -293,7 +296,7 @@ "message": "トークンを隠す" }, "hideTokenPrompt": { - "message": "トークンを隠しますか??" + "message": "トークンを隠しますか?" }, "howToDeposit": { "message": "どのようにEtherをデポジットしますか?" @@ -306,7 +309,7 @@ "message": "アカウントのインポート" }, "importAccountMsg": { - "message":"追加したアカウントはMetaMaskのアカウントシードフレーズとは関連付けられません。インポートしたアカウントについての詳細は" + "message":"追加したアカウントはMetaMaskのアカウントパスフレーズとは関連付けられません。インポートしたアカウントについての詳細は" }, "importAnAccount": { "message": "アカウントをインポート" @@ -341,7 +344,7 @@ "description": "format for importing an account" }, "keepTrackTokens": { - "message": "MetaMaskアカウントで入手したトークンを追跡でできます。" + "message": "MetaMaskアカウントで入手したトークンを検索できます。" }, "kovan": { "message": "Kovanテストネットワーク" @@ -386,6 +389,9 @@ "myAccounts": { "message": "マイアカウント" }, + "mustSelectOne": { + "message": "一つ以上のトークンを選択してください。" + }, "needEtherInWallet": { "message": "MetaMaskで分散型アプリケーションを使用するためには、このウォレットにEtherが必要です。" }, @@ -426,7 +432,7 @@ "message": "この名前にはアドレスが設定されていません。" }, "noDeposits": { - "message": "お振込みがありません。" + "message": "振込みがありません。" }, "noTransactionHistory": { "message": "トランザクション履歴がありません。" @@ -460,11 +466,14 @@ "description": "For importing an account from a private key" }, "pasteSeed": { - "message": "シードをここにペーストして下さい!" + "message": "パスフレーズをここにペーストして下さい!" }, "pleaseReviewTransaction": { "message": "トランザクションを確認して下さい。" }, + "popularTokens": { + "message": "人気のトークン" + }, "privateKey": { "message": "秘密鍵", "description": "select this type of file to use to import an account" @@ -485,13 +494,13 @@ "message": "もっと読む" }, "receive": { - "message": "お受取り" + "message": "受取" }, "recipientAddress": { "message": "受取人アドレス" }, "refundAddress": { - "message": "お受取りアドレス" + "message": "受取アドレス" }, "rejected": { "message": "拒否されました" @@ -502,12 +511,18 @@ "restoreFromSeed": { "message": "パスフレーズから復元する" }, + "restoreVault": { + "message": "ウォレットを復元する" + }, "required": { "message": "必要です。" }, "retryWithMoreGas": { "message": "より高いガスプライスで再度試して下さい。" }, + "walletSeed": { + "message": "ウォレットのパスフレーズ" + }, "revealSeedWords": { "message": "パスフレーズを表示" }, @@ -534,6 +549,9 @@ "selectService": { "message": "サービスを選択" }, + "selectType": { + "message": "キーの種類" + }, "send": { "message": "送信" }, @@ -555,8 +573,11 @@ "settings": { "message": "設定" }, + "info": { + "message": "情報" + }, "shapeshiftBuy": { - "message": "Shapeshiftで取引" + "message": "Shapeshiftで交換" }, "showPrivateKeys": { "message": "秘密鍵を表示" @@ -616,6 +637,9 @@ "total": { "message": "合計" }, + "transactions": { + "message": "トランザクション" + }, "transactionMemo": { "message": "トランザクションメモ (オプション)" }, diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json index aacb81fee..38289f602 100644 --- a/app/_locales/nl/messages.json +++ b/app/_locales/nl/messages.json @@ -223,7 +223,7 @@ "done": { "message": "Gedaan" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Staatslogboeken downloaden" }, "edit": { @@ -299,7 +299,7 @@ "message": "De gaslimiet moet minstens 21000 zijn" }, "generatingSeed": { - "message": "Zaad produceren ..." + "message": "Back-up woorden produceren ..." }, "gasPrice": { "message": "Gasprijs (GWEI)" @@ -432,7 +432,7 @@ "message": "Los" }, "loweCaseWords": { - "message": "zaadwoorden hebben alleen kleine letters" + "message": "back-up woorden hebben alleen kleine letters" }, "mainnet": { "message": "belangrijkste ethereum-netwerk" @@ -532,7 +532,7 @@ "description": "Voor het importeren van een account vanaf een privésleutel" }, "pasteSeed": { - "message": "Plak je zaadzin hier!" + "message": "Plak je back-up woorden hier!" }, "personalAddressDetected": { "message": "Persoonlijk adres gedetecteerd. Voer het tokencontractadres in." @@ -581,7 +581,7 @@ "message": "Account opnieuw instellen" }, "restoreFromSeed": { - "message": "Herstel van zaaduitdrukking" + "message": "Herstel vanuit back-up woorden" }, "required": { "message": "Verplicht" @@ -590,10 +590,10 @@ "message": "Probeer hier opnieuw met een hogere gasprijs" }, "revealSeedWords": { - "message": "Onthul zaadwoorden" + "message": "Onthul back-up woorden" }, "revealSeedWordsWarning": { - "message": "Herstel je zaadwoorden niet op een openbare plaats! Deze woorden kunnen worden gebruikt om al uw accounts te stelen." + "message": "Zorg dat je back-up woorden niet op een openbare plaats bekijkt! Deze woorden kunnen worden gebruikt om al uw accounts opnieuw te genereren (en dus uw account te stelen)." }, "revert": { "message": "terugkeren" @@ -616,7 +616,7 @@ "description": "Account export proces" }, "saveSeedAsFile": { - "message": "Bewaar zaadwoorden als bestand" + "message": "Bewaar back-up woorden als bestand" }, "search": { "message": "Zoeken" @@ -625,7 +625,7 @@ "message": "Voer hier je geheime twaalfwoordfrase in om je kluis te herstellen." }, "seedPhraseReq": { - "message": "zaadzinnen zijn 12 woorden lang" + "message": "Back-up woorden zijn 12 woorden lang" }, "select": { "message": "kiezen" diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index c9eb178f9..e770392d0 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -223,7 +223,7 @@ "done": { "message": "Finalizado" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Descarregar Registos de Estado" }, "edit": { diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index e3a1935f5..b43251064 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -3,13 +3,13 @@ "message": "Принять" }, "account": { - "message": "Аккаунт" + "message": "Счет" }, "accountDetails": { - "message": "Детали Аккаунта" + "message": "Детали счета" }, "accountName": { - "message": "Имя Пользователя" + "message": "Название счета" }, "address": { "message": "Адрес" @@ -21,13 +21,13 @@ "message": "Добавить токен" }, "addTokens": { - "message": "Добавить Токены" + "message": "Добавить токены" }, "amount": { - "message": "Количество" + "message": "Сумма" }, "amountPlusGas": { - "message": "Количество + газ" + "message": "Сумма + газ" }, "appDescription": { "message": "Расширение браузера для Ethereum", @@ -37,11 +37,14 @@ "message": "MetaMask", "description": "The name of the application" }, + "approved": { + "message": "Одобрена" + }, "attemptingConnect": { "message": "Попытка подключиться к блокчейн сети." }, "attributions": { - "message": "Опознания" + "message": "Атрибуция" }, "available": { "message": "Доступный" @@ -53,13 +56,13 @@ "message": "Баланс:" }, "balances": { - "message": "Ваши балансы" + "message": "Ваш баланс" }, "balanceIsInsufficientGas": { "message": "Недостаточный баланс для текущего объема газа" }, "beta": { - "message": "БЕТА" + "message": "BETA" }, "betweenMinAndMax": { "message": "должно быть больше или равно $1 и меньше или равно $2.", @@ -69,10 +72,10 @@ "message": "Использовать Blockies Identicon" }, "borrowDharma": { - "message": "Заимствовать с Dharma (бета)" + "message": "Взять в долг на Dharma (Beta)" }, "builtInCalifornia": { - "message": "MetaMask спроектирован и построен в Калифорнии." + "message": "MetaMask спроектирован и разработан в Калифорнии." }, "buy": { "message": "Купить" @@ -81,7 +84,10 @@ "message": "Купить на Coinbase" }, "buyCoinbaseExplainer": { - "message": "Coinbase - самый популярный в мире способ купить и продать биткойн, ethereum и litecoin." + "message": "Биржа Coinbase – это наиболее популярный способ купить или продать bitcoin, ethereum и litecoin." + }, + "ok": { + "message": "ОК" }, "cancel": { "message": "Отмена" @@ -95,14 +101,17 @@ "confirm": { "message": "Подтвердить" }, + "confirmed": { + "message": "Подтверждена" + }, "confirmContract": { - "message": "Подтвердить Контракт" + "message": "Подтвердить контракт" }, "confirmPassword": { - "message": "Подтвердите Пароль" + "message": "Подтвердите пароль" }, "confirmTransaction": { - "message": "Подтвердить Транзакцию" + "message": "Подтвердить транзакцию" }, "continue": { "message": "Продолжить" @@ -114,7 +123,7 @@ "message": "Развертывание контракта" }, "conversionProgress": { - "message": "Выполняется конверсия" + "message": "Выполняется конвертация" }, "copiedButton": { "message": "Скопировано" @@ -126,7 +135,7 @@ "message": "Скопировано!" }, "copiedSafe": { - "message": "Я скопировал его где-то в безопасности" + "message": "Я скопировал это в безопасное место" }, "copy": { "message": "Скопировать" @@ -138,29 +147,32 @@ "message": " Скопировать " }, "copyPrivateKey": { - "message": "Это ваш личный ключ (нажмите, чтобы скопировать)" + "message": "Это ваш закрытый ключ (нажмите, чтобы скопировать)" }, "create": { "message": "Создать" }, "createAccount": { - "message": "Регистрация" + "message": "Создать счет" }, "createDen": { "message": "Создать" }, "crypto": { - "message": "Крипто", + "message": "Криптовалюта", "description": "Exchange type (cryptocurrencies)" }, "currentConversion": { - "message": "Текущая конверсия" + "message": "Текущая конвертация" }, "currentNetwork": { "message": "Текущая сеть" }, "customGas": { - "message": "Настроить Газ" + "message": "Настроить газ" + }, + "customToken": { + "message": "Пользовательский токен" }, "customize": { "message": "Настроить" @@ -169,112 +181,115 @@ "message": "Пользовательский RPC" }, "decimalsMustZerotoTen": { - "message": "Десятичные числа должны быть не менее 0, и не более 36." + "message": "Количество десятичных разрядов должно быть минимум 0 и максимум 36." }, "decimal": { - "message": "Десятичные значения точности" + "message": "Количество десятичных разрядов" }, "defaultNetwork": { - "message": "Сеть по умолчанию для транзакций Ether - это Main Net." + "message": "Основная сеть Ethereum – это сеть по умолчанию для Ether транзакций." }, "denExplainer": { - "message": "Ваш DEN - это ваше зашифрованное паролем хранилище в MetaMask." + "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": "Депозит Эфир" + "message": "Пополнить Ether" }, "depositFiat": { - "message": "Депозит с деньгами" + "message": "Пополнить деньгами" }, "depositFromAccount": { - "message": "Депозит с другого счета" + "message": "Пополнить с другого счета" }, "depositShapeShift": { - "message": "Депозит с ShapeShift" + "message": "Пополнить через ShapeShift" }, "depositShapeShiftExplainer": { - "message": "Если у вас есть другие крипторесурсы, вы можете торговать и вносить Эфир непосредственно в кошелек MetaMask. Нет необходимости в аккаунте." + "message": "Если у вас есть другие криптовалюты, вы можете торговать и пополнять Ether напрямую в ваш MetaMask кошелек. Нет необходимости в счете." }, "details": { "message": "Детали" }, "directDeposit": { - "message": "Прямой Депозит" + "message": "Прямое пополнение" }, "directDepositEther": { - "message": "Прямой Депозит Эфира" + "message": "Прямое пополнение Ether" }, "directDepositEtherExplainer": { - "message": "Если у вас уже есть Эфир, самый быстрый способ получить Эфир в вашем новом кошельке это прямым депозитом." + "message": "Если у вас уже есть Ether, то самый быстрый способ получить Ether в ваш новый кошелек – это прямое пополнение." }, "done": { "message": "Готово" }, - "downloadStatelogs": { - "message": "Загрузить логи статус" + "downloadStateLogs": { + "message": "Скачать журнал состояния" + }, + "dropped": { + "message": "Отброшена" }, "edit": { "message": "Редактировать" }, "editAccountName": { - "message": "Изменить Имя Аккаунта" + "message": "Редактировать название счета" }, "emailUs": { "message": "Свяжитесь с нами по электронной почте!" }, "encryptNewDen": { - "message": "Шифруйте новый DEN" + "message": "Зашифровать ваш новый DEN" }, "enterPassword": { "message": "Введите пароль" }, "enterPasswordConfirm": { - "message": "Введите свой пароль для подтверждения" + "message": "Введите ваш пароль для подтверждения" }, "etherscanView": { - "message": "Просмотреть аккаунт на Etherscan" + "message": "Просмотреть счет на Etherscan" }, "exchangeRate": { - "message": "Обменный Курс" + "message": "Обменный курс" }, "exportPrivateKey": { - "message": "Экспорт закрытого ключа" + "message": "Экспортировать закрытый ключ" }, "exportPrivateKeyWarning": { - "message": "Экспорт секретных ключей на свой страх и риск." + "message": "Вы экспортируете закрытые ключи на свой страх и риск." }, "failed": { - "message": "Не смогли" + "message": "Неудачна" }, "fiat": { - "message": "Бумажные деньги", + "message": "Валюта", "description": "Exchange type" }, "fileImportFail": { - "message": "Ошибка импорта файлов? Кликните сюда!", + "message": "Не работает импорт файла? Нажмите тут!", "description": "Helps user import their account from a JSON file" }, "followTwitter": { - "message": "Следуйте за нами на Twitter" + "message": "Читайте нас в Twitter" }, "from": { - "message": "Из" + "message": "Отправитель" }, "fromToSame": { - "message": "От и до адреса не могут быть одинаковым" + "message": "Адрес отправителя и получателя не могут быть одинаковыми" }, "fromShapeShift": { "message": "Из ShapeShift" @@ -284,37 +299,37 @@ "description": "Short indication of gas cost" }, "gasFee": { - "message": "Плата за Газ" + "message": "Комиссия за газ" }, "gasLimit": { - "message": "Газовый Предел" + "message": "Лимит газа" }, "gasLimitCalculation": { - "message": "Мы рассчитываем предполагаемый предел газа на основе коэффициентов успешности сети." + "message": "Мы расчитываем предлагаемый лимит газа на основании успешных ставок в сети." }, "gasLimitRequired": { - "message": "Требуется ограничение на Газ" + "message": "Установите лимит газа" }, "gasLimitTooLow": { - "message": "Предел газа должен быть не менее 21000" + "message": "Лимит газа должен быть как минимум 21000" }, "generatingSeed": { - "message": "Создание Семян ..." + "message": "Генерируем фразу..." }, "gasPrice": { - "message": "Цена на Газ (GWEI)" + "message": "Цена за газ (GWEI)" }, "gasPriceCalculation": { - "message": "Мы вычисляем предлагаемые цены на газ на основе коэффициентов успеха сети." + "message": "Мы расчитываем предлагаемые цены за газ на основании успешных ставок в сети." }, "gasPriceRequired": { - "message": "Требуется цена на Газ" + "message": "Установите стоимость газа" }, "getEther": { - "message": "Получить Эфир" + "message": "Получить Ether" }, "getEtherFromFaucet": { - "message": "Получите Эфир из крана $1", + "message": "Получить Ether из крана для $1", "description": "Displays network name for Ether faucet" }, "greaterThanMin": { @@ -322,14 +337,14 @@ "description": "helper for inputting hex as decimal input" }, "here": { - "message": "здесь", + "message": "тут", "description": "as in -click here- for more information (goes with troubleTokenBalances)" }, "hereList": { - "message": "Вот список !!!!" + "message": "Вот список!!!!" }, "hide": { - "message": "Спрятать" + "message": "Скрыть" }, "hideToken": { "message": "Скрыть токен" @@ -338,33 +353,33 @@ "message": "Скрыть токен?" }, "howToDeposit": { - "message": "Как бы вы хотели поместить Эфир?" + "message": "Как бы вы хотели пополнить Ether?" }, "holdEther": { - "message": "Это позволяет вам использовать эфир и токены и служит мостом для децентрализованных приложений." + "message": "Позволяет вам хранить ether и токены и служит в качестве моста в децентрализированные приложения." }, "import": { "message": "Импортировать", "description": "Button to import an account from a selected file" }, "importAccount": { - "message": "Импорт Аккаунта" + "message": "Импортировать счет" }, "importAccountMsg": { - "message": " Импортированные аккаунты не будут связаны с вашей первоначально созданным аккаунтом MetaMask. Подробнее о импортированных аккаунтах " + "message":" Импортированные счета не будут ассоциированы с вашей ключевой фразой, созданной MetaMask. Узнать больше про импорт счетов " }, "importAnAccount": { "message": "Импортировать аккаунт" }, "importDen": { - "message": "Импорт существующих DEN" + "message": "Импортировать существующий DEN" }, "imported": { "message": "Импортирован", "description": "status showing that an account has been fully loaded into the keyring" }, "infoHelp": { - "message": "Информация и Помощь" + "message": "Информация и помощь" }, "insufficientFunds": { "message": "Недостаточно средств." @@ -373,35 +388,44 @@ "message": "Недостаточно токенов." }, "invalidAddress": { - "message": "Недействительный адрес" + "message": "Неверный адрес" }, "invalidAddressRecipient": { - "message": "Недопустимый адрес получателя." + "message": "Неверный адрес получателя" }, "invalidGasParams": { - "message": "Недопустимые параметры Газа" + "message": "Неверные параметры газа" }, "invalidInput": { - "message": "Неправильный ввод." + "message": "Неверный ввод." }, "invalidRequest": { - "message": "Неверный Запрос" + "message": "Неверный запрос" }, "invalidRPC": { - "message": "Недопустимый URI RPC" + "message": "Неверный RPC URI" }, "jsonFail": { - "message": "Что-то пошло не так. Убедитесь, что ваш файл JSON правильно отформатирован." + "message": "Что-то пошло не так. Убедитесь, что ваш JSON файл правильно отформатирован." }, "jsonFile": { - "message": "Файл JSON", + "message": "JSON файл", "description": "format for importing an account" }, + "keepTrackTokens": { + "message": "Следите за купленными вами токенами с помощью аккаунта MetaMask." + }, "kovan": { - "message": "Kovan тестовая сеть" + "message": "Тестовая сеть Kovan" }, "knowledgeDataBase": { - "message": "Посетите нашу базу знаний" + "message": "Посмотрите нашу Базу Знаний" + }, + "max": { + "message": "Максимум" + }, + "learnMore": { + "message": "Узнать больше." }, "lessThanMax": { "message": "должно быть меньше или равно $1.", @@ -410,29 +434,32 @@ "likeToAddTokens": { "message": "Вы хотите добавить эти токены?" }, + "links": { + "message": "Ссылки" + }, "limit": { - "message": "Предел" + "message": "Лимит" }, "loading": { "message": "Загрузка..." }, "loadingTokens": { - "message": "Загрузка токенов ..." + "message": "Загрузка токенов..." }, "localhost": { - "message": "Локальный адрес 8545" + "message": "Localhost 8545" }, "login": { - "message": "Авторизоваться" + "message": "Вход" }, "logout": { - "message": "Выйти" + "message": "Выход" }, "loose": { - "message": "Рыхлый" + "message": "Несвязанный" }, "loweCaseWords": { - "message": "семенные слова имеют только символы нижнего регистра" + "message": "ключевая фраза может содержать только символы нижнего регистра" }, "mainnet": { "message": "Основная сеть Ethereum" @@ -441,19 +468,19 @@ "message": "Сообщение" }, "metamaskDescription": { - "message": "MetaMask - это безопасное хранилище для Ethereum." + "message": "MetaMask – безопасный кошелек для Ethereum." }, "min": { "message": "Минимум" }, "myAccounts": { - "message": "Мои Аккаунты" + "message": "Мои счета" }, "mustSelectOne": { - "message": "Необходимо выбрать не менее 1 токена." + "message": "Необходимо выбрать как минимум 1 токен." }, "needEtherInWallet": { - "message": "Чтобы взаимодействовать с децентрализованными приложениями с помощью MetaMask, вам понадобится Эфир в вашем кошельке." + "message": "Для взаимодействия с децентрализованными приложениями с помощью MetaMask нужен Ether в вашем кошельке." }, "needImportFile": { "message": "Вы должны выбрать файл для импорта.", @@ -464,60 +491,60 @@ "description": "Password and file needed to import an account" }, "negativeETH": { - "message": "Невозможно отправить отрицательные количества ETH." + "message": "Невозможно отправить отрицательную сумму ETH." }, "networks": { "message": "Сети" }, "newAccount": { - "message": "Новый Аккаунт" + "message": "Новый счет" }, "newAccountNumberName": { - "message": "Аккаунт $1", + "message": "Счет $1", "description": "Default name of next account to be created on create account screen" }, "newContract": { - "message": "Новый Контракт" + "message": "Новый контракт" }, "newPassword": { "message": "Новый пароль (мин. 8 символов)" }, "newRecipient": { - "message": "Новый Получатель" + "message": "Новый получатель" }, "newRPC": { - "message": "Новый URL-адрес RPC" + "message": "Новый RPC URL" }, "next": { "message": "Далее" }, "noAddressForName": { - "message": "Для этого имени не задан адрес." + "message": "Дла этого названия не установлен адрес." }, "noDeposits": { - "message": "Не было получено никаких депозитов" + "message": "Пополнения не получены" }, "noTransactionHistory": { "message": "Нет истории транзакций." }, "noTransactions": { - "message": "Нет Транзакций" + "message": "Нет транзакций" }, "notStarted": { - "message": "Не Начался" + "message": "Не запущен" }, "oldUI": { - "message": "Старый Интерфейс" + "message": "Старая версия интерфейса" }, "oldUIMessage": { - "message": "Вы вернулись к старому интерфейсу. Вы можете вернуться к новому с помощью опции в раскрывающемся меню в правом верхнем углу." + "message": "Вы вернулись к старой версии интерфейса пользователя. Вы можете переключиться на новую с помощью опции выпадающего меню в правом верхнем углу." }, "or": { "message": "или", "description": "choice between creating or importing a new account" }, "passwordCorrect": { - "message": "Убедитесь, что ваш пароль правильный." + "message": "Убедитесь, что ваш пароль верный." }, "passwordMismatch": { "message": "пароли не совпадают", @@ -528,27 +555,30 @@ "description": "in password creation process, the password is not long enough to be secure" }, "pastePrivateKey": { - "message": "Вставьте свою личную строку:", + "message": "Вставьте ваш закрытый ключ тут:", "description": "For importing an account from a private key" }, "pasteSeed": { - "message": "Вставьте здесь свою семенную фразу!" + "message": "Вставьте вашу ключевую фразу!" }, "personalAddressDetected": { - "message": "Персональный адрес обнаружен. Введите адрес контракта токена." + "message": "Обнаружен персональный адрес. Введите адрес контракта токена." }, "pleaseReviewTransaction": { "message": "Проверьте транзакцию." }, + "popularTokens": { + "message": "Популярные токены" + }, "privacyMsg": { - "message": "Политика Конфиденциальности" + "message": "Политика конфиденциальности" }, "privateKey": { "message": "Закрытый ключ", "description": "select this type of file to use to import an account" }, "privateKeyWarning": { - "message": "Предупреждение: никогда не раскрывайте этот ключ. Любой, у кого есть ваши личные ключи, может украсть любые активы, хранящиеся в вашем аккаунте." + "message": "Предупреждение: Никогда не раскрывайте этот ключ. Любой, у кого есть ваши закрытые ключи, может украсть любые активы, хранящиеся на счету." }, "privateNetwork": { "message": "Частная сеть" @@ -557,126 +587,165 @@ "message": "Показать QR-код" }, "readdToken": { - "message": "Вы можете добавить этот токен в будущем, перейдя в “Добавить токен” в меню параметров вашего аккаунта." + "message": "Вы можете в будущем добавить обратно этот токен, выбрав пункт меню “Добавить токен”." }, "readMore": { - "message": "Подробнее читайте здесь." + "message": "Узнать больше тут." }, "readMore2": { - "message": "Прочитайте больше." + "message": "Узнать больше." }, "receive": { "message": "Получить" }, "recipientAddress": { - "message": "Адрес Получателя" + "message": "Адрес получателя" }, "refundAddress": { - "message": "Ваш Адрес Возврата" + "message": "Ваш адрес для возврата средств" }, "rejected": { - "message": "Отклонено" + "message": "Отклонена" }, "resetAccount": { "message": "Сбросить аккаунт" }, "restoreFromSeed": { - "message": "Восстановить от семенной фразы" + "message": "Восстановить из ключевой фразы" + }, + "restoreVault": { + "message": "Восстановить кошелек" }, "required": { - "message": "Необходимо" + "message": "Обязательное поле" }, "retryWithMoreGas": { - "message": "Повторите попытку с более высокой ценой на газ здесь" + "message": "Повторите попытку с большей ценой за газRetry with a higher gas price here" + }, + "walletSeed": { + "message": "Ключевая фраза кошелька" }, "revealSeedWords": { - "message": "Раскрыть семенные слова" + "message": "Показать ключевую фразу" }, "revealSeedWordsWarning": { - "message": "Не восстанавливайте семенные слова в общественном месте! Эти слова могут использоваться для кражи всех ваших аккаунтах." + "message": "Не восстанавливайте ключевую фразу в общественном месте! Она может быть использована для кражи всех ваших счетов." }, "revert": { - "message": "Откат" + "message": "Восстановить" }, "rinkeby": { - "message": "Rinkeby тестовая сеть" + "message": "Тестовая сеть Rinkeby" }, "ropsten": { - "message": "Ropsten тестовая сеть" + "message": "Тестовая сеть Ropsten" + }, + "currentRpc": { + "message": "Current RPC" + }, + "connectingToMainnet": { + "message": "Соединение с основной сетью Ethereum" + }, + "connectingToRopsten": { + "message": "Соединение с тестовой сетью Ropsten" + }, + "connectingToKovan": { + "message": "Соединение с тестовой сетью Kovan" + }, + "connectingToRinkeby": { + "message": "Соединение с тестовой сетью Rinkeby" + }, + "connectingToUnknown": { + "message": "Соединение с неизвестной сетью" }, "sampleAccountName": { - "message": "Например, Мой новый аккаунт", + "message": "Например, Мой новый счет", "description": "Help user understand concept of adding a human-readable name to their account" }, "save": { "message": "Сохранить" }, "saveAsFile": { - "message": "Сохранить как Файл", + "message": "Сохранить в виде файла", "description": "Account export process" }, "saveSeedAsFile": { - "message": "Сохранить Семенные Слова Как Файл" + "message": "Сохранить ключевую фразу в виде файла" }, "search": { "message": "Поиск" }, "secretPhrase": { - "message": "Введите свою секретную двенадцатисловную фразу здесь, чтобы восстановить хранилище." + "message": "Введите вашу ключевую фразу из 12 слов, чтобы восстановить кошелек." + }, + "newPassword8Chars": { + "message": "Новый пароль (мин. 8 символов)" }, "seedPhraseReq": { - "message": "семенные фразы длиной 12 слов" + "message": "ключевые фразы имеют длину 12 слов" }, "select": { "message": "Выбрать" }, "selectCurrency": { - "message": "Выберите Валюту" + "message": "Выберите валюту" }, "selectService": { - "message": "Выберите Сервис" + "message": "Выберите сервис" }, "selectType": { - "message": "Выберите Тип" + "message": "Выберите тип" }, "send": { - "message": "Послать" + "message": "Отправить" }, "sendETH": { "message": "Отправить ETH" }, "sendTokens": { - "message": "Отправить Токены" + "message": "Отправить токены" + }, + "onlySendToEtherAddress": { + "message": "Отправляйте ETH только на Ethereum адреса." + }, + "searchTokens": { + "message": "Поиск токенов" }, "sendTokensAnywhere": { - "message": "Отправить Токены кому-либо с аккаунтом Ethereum" + "message": "Отправить токены любому, у кого есть счет Ethereum" }, "settings": { "message": "Настройки" }, + "info": { + "message": "Информация" + }, "shapeshiftBuy": { - "message": "Купить с помощью Shapeshift" + "message": "Купить через Shapeshift" }, "showPrivateKeys": { - "message": "Показать приватные ключи" + "message": "Показать закрытые ключи" }, "showQRCode": { "message": "Показать QR-код" }, "sign": { - "message": "Знак" + "message": "Подпись" + }, + "signed": { + "message": "Подписана" }, "signMessage": { - "message": "Нодписать сообщение" + "message": "Подписать сообщение" }, "signNotice": { - "message": "Подписание этого сообщения может иметь \nопасные побочные эффекты. Только подписывайте сообщения \nс сайтов, которым вы полностью доверяете своим аккаунтом. Этот опасный метод будет удален в будущей версии." + "message": "Подпись этого сообщения может иметь \nопасные побочные эффекты. Подписывайте только сообщения \nс сайтов, которым вы полностью доверяете свой аккаунт. Этот опасный метод будет удален в будущей версии." }, "sigRequest": { - "message": "Запрос на подпись" + "message": "Запрос подписи" }, "sigRequested": { - "message": "Подпись Запрошена" + "message": "Подпись запрошена" }, "spaceBetween": { "message": "между словами может быть только пробел" @@ -685,53 +754,59 @@ "message": "Статус" }, "stateLogs": { - "message": "Логи Статуса" + "message": "Журнал состояния" }, "stateLogsDescription": { - "message": "Логи статуса содержат ваши общедоступные адреса и отправленные транзакции." + "message": "Журнал состояния содержит ваши публичные адреса счетов и совершенные транзакции." + }, + "stateLogError": { + "message": "Ошибка при получении журнала состояния." }, "submit": { "message": "Отправить" }, + "submitted": { + "message": "Отправлена" + }, "supportCenter": { - "message": "Посетите наш Центр поддержки" + "message": "Перейти в наш Центр поддержки" }, "symbolBetweenZeroTen": { "message": "Символ должен быть от 0 до 10 символов." }, "takesTooLong": { - "message": "Занимает слишком долго?" + "message": "Слишком долго?" }, "terms": { - "message": "Условия Эксплуатации" + "message": "Условия пользования" }, "testFaucet": { - "message": "Тестовый Кран" + "message": "Тестовый кран" }, "to": { - "message": "К" + "message": "Получатель: " }, "toETHviaShapeShift": { "message": "$1 в ETH через ShapeShift", "description": "system will fill in deposit type in start of message" }, "tokenAddress": { - "message": "Адрес Токена" + "message": "Адрес токена" }, "tokenAlreadyAdded": { - "message": "Токен уже добавлен." + "message": "Токен уже был добавлен." }, "tokenBalance": { - "message": "Баланс Вашых Tокенов:" + "message": "Баланс ваших токенов:" }, "tokenSelection": { - "message": "Поиск токенов или выбор из нашего списка популярных токенов." + "message": "Поищите токен или выберите из нашего списка популярных токенов." }, "tokenSymbol": { - "message": "Символ Токена" + "message": "Символ токена" }, "tokenWarning1": { - "message": "Следите за токенами, которые вы купили с помощью аккаунта MetaMask. Если вы купили токены, используя другой аккаунт, эти токены здесь не появятся." + "message": "Отслеживаются токены, купленные на счет в MetaMask. Если вы купили токены, используя другой счет, такие токены не будут тут отображены." }, "total": { "message": "Всего" @@ -740,35 +815,38 @@ "message": "транзакции" }, "transactionMemo": { - "message": "Транзакционная записка (необязательно)" + "message": "Транзакционные данные (необязательный)" }, "transactionNumber": { - "message": "Номер Транзакции" + "message": "Номер транзакции" }, "transfers": { "message": "Переводы" }, "troubleTokenBalances": { - "message": "У нас были проблемы с загрузкой ваших токенов. Вы можете просмотреть их ", + "message": "Возникли проблемы при загрузке балансов токенов. Вы можете посмотреть их ", "description": "Followed by a link (here) to view token balances" }, "twelveWords": { - "message": "Эти 12 слов - единственный способ восстановить ваши учетные записи MetaMask.\nСохраните их где-нибудь в безопасности и в тайне." + "message": "Эти 12 слов являются единственной возможностью восстановить ваши счета в MetaMask.\nСохраните из в надежном секретном месте." }, "typePassword": { - "message": "Введите Пароль" + "message": "Введите пароль" }, "uiWelcome": { - "message": "Добро пожаловать в новый интерфейс (бета-версия)" + "message": "Новый интерфейс (Beta)" }, "uiWelcomeMessage": { - "message": "Теперь вы используете новый интерфейс Metamask. Осмотритесь, попробуйте новые функции, такие как отправку токенов, и сообщите нам, есть ли у вас какие-либо проблемы." + "message": "Теперь вы используете новый интерфейс пользователя MetaMask. Осмотритесь, попробуйте новые функции, например, отправить токены и, если возникнут проблемы, сообщите нам." + }, + "unapproved": { + "message": "Не одобрена" }, "unavailable": { - "message": "Недоступен" + "message": "Недоступный" }, "unknown": { - "message": "Неизвестный" + "message": "Неизвестно" }, "unknownNetwork": { "message": "Неизвестная частная сеть" @@ -777,7 +855,7 @@ "message": "Неизвестный идентификатор сети" }, "uriErrorMsg": { - "message": "Для URI требуется соответствующий префикс HTTP / HTTPS." + "message": "Для URI требуется соответствующий префикс HTTP/HTTPS." }, "usaOnly": { "message": "Только США", @@ -787,19 +865,19 @@ "message": "Используется различными клиентами" }, "useOldUI": { - "message": "Использовать старый интерфейс" + "message": "Использовать старый интерфейс пользователя" }, "validFileImport": { - "message": "Вы должны выбрать действительный файл для импорта." + "message": "Вам нужно выбрать правильный файл для импорта." }, "vaultCreated": { - "message": "Создано хранилище" + "message": "Кошелек был создан" }, "viewAccount": { - "message": "Посмотреть аккаунт" + "message": "Посмотреть счет" }, "visitWebSite": { - "message": "Посетите наш сайт" + "message": "Перейти на наш сайт" }, "warning": { "message": "Предупреждение" @@ -811,7 +889,7 @@ "message": "Что это?" }, "yourSigRequested": { - "message": "Ваша подпись запрашивается" + "message": "Запрашивается ваша подпись" }, "youSign": { "message": "Вы подписываете" diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json index 0532f11b2..b089f3476 100644 --- a/app/_locales/sl/messages.json +++ b/app/_locales/sl/messages.json @@ -223,7 +223,7 @@ "done": { "message": "Končano" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "Prenesi state dnevnike" }, "edit": { diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json index 887714f3f..3d7dec226 100644 --- a/app/_locales/th/messages.json +++ b/app/_locales/th/messages.json @@ -223,7 +223,7 @@ "done": { "message": "เสร็จสิ้น" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "ดาวน์โหลดล็อกสถานะ" }, "edit": { diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 90f63c6a6..9aaee0e16 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -171,6 +171,9 @@ "customGas": { "message": "自訂 Gas" }, + "customToken": { + "message": "自訂代幣" + }, "customize": { "message": "自訂" }, @@ -184,7 +187,7 @@ "message": "小數點精度" }, "defaultNetwork": { - "message": "預設Ether交易網路為主網(Main Net)。" + "message": "預設 Ether 交易網路為主網路(Main Net)。" }, "denExplainer": { "message": "你的 DEN 是在你的 MetaMask 中的加密密碼儲存庫。" @@ -215,7 +218,7 @@ "message": "從 ShapeShift 存入" }, "depositShapeShiftExplainer": { - "message": "如果你擁有其他加密貨幣,你可以直接交易並存入 Ether 到你的MetaMask錢包。不需要開帳戶。" + "message": "如果你擁有其他加密貨幣,你可以直接交易並存入 Ether 到你的 MetaMask 錢包。不需要開帳戶。" }, "details": { "message": "詳情" @@ -227,12 +230,12 @@ "message": "直接存入 Ether" }, "directDepositEtherExplainer": { - "message": "如果你已經擁有了一些Ether,使用直接存入功能是讓你的新錢包最快取得Ether的方式。" + "message": "如果你已經擁有了一些 Ether,使用直接存入功能是讓你的新錢包最快取得 Ether 的方式。" }, "done": { "message": "完成" }, - "downloadStatelogs": { + "downloadStateLogs": { "message": "下載狀態紀錄" }, "dropped": { @@ -285,6 +288,9 @@ "message": "檔案導入失敗?點擊這裡!", "description": "Helps user import their account from a JSON file" }, + "followTwitter": { + "message": "追蹤 Twitter" + }, "from": { "message": "來源地址" }, @@ -313,6 +319,9 @@ "gasLimitTooLow": { "message": "Gas 上限至少為 21000" }, + "generatingSeed": { + "message": "產生助憶詞中..." + }, "gasPrice": { "message": "Gas 價格 (GWEI)" }, @@ -362,6 +371,9 @@ "importAccount": { "message": "導入帳戶" }, + "importAccountMsg": { + "message":" 匯入的帳戶與您原有 MetaMask 帳戶的助憶詞並無關聯. 請查看與導入帳戶相關的資料 " + }, "importAnAccount": { "message": "導入一個帳戶" }, @@ -400,12 +412,15 @@ "message": "無效的 RPC URI" }, "jsonFail": { - "message": "有東西出錯了. 請確認你的 JSON 檔案格式正確." + "message": "有東西出錯了. 請確認你的 JSON 檔案格式正確。" }, "jsonFile": { "message": "JSON 檔案", "description": "format for importing an account" }, + "keepTrackTokens": { + "message": "持續追蹤您 MetaMask 帳戶中的代幣。" + }, "kovan": { "message": "Kovan 測試網路" }, @@ -415,6 +430,9 @@ "max": { "message": "最大值" }, + "learnMore": { + "message": "了解更多。" + }, "lessThanMax": { "message": "必須小於等於 $1.", "description": "helper for inputting hex as decimal input" @@ -437,17 +455,20 @@ "localhost": { "message": "Localhost 8545" }, + "login": { + "message": "登入" + }, "logout": { "message": "登出" }, "loose": { - "message": "非Metamask帳號" + "message": "非 MetaMask 帳號" }, "loweCaseWords": { "message": "助憶詞僅包含小寫字元" }, "mainnet": { - "message": "主乙太坊網路" + "message": "乙太坊 主網路" }, "message": { "message": "訊息" @@ -465,7 +486,7 @@ "message": "必須選擇至少 1 代幣." }, "needEtherInWallet": { - "message": "要使用 MetaMask 存取 DAPP時,您的錢包中需要有 Ether。" + "message": "要使用 MetaMask 存取 DAPP 時,您的錢包中需要有 Ether。" }, "needImportFile": { "message": "您必須選擇一個檔案來導入。", @@ -475,6 +496,9 @@ "message": "您必須為選擇好的檔案輸入密碼。", "description": "Password and file needed to import an account" }, + "negativeETH": { + "message": "不能送出負值的 ETH。" + }, "networks": { "message": "網路" }, @@ -525,6 +549,9 @@ "message": "或", "description": "choice between creating or importing a new account" }, + "passwordCorrect": { + "message": "請確認您的密碼是正確的。" + }, "passwordMismatch": { "message": "密碼不一致", "description": "in password creation process, the two new password fields did not match" @@ -546,6 +573,12 @@ "pleaseReviewTransaction": { "message": "請檢查你的交易。" }, + "popularTokens": { + "message": "常見的代幣" + }, + "privacyMsg": { + "message": "隱私政策" + }, "privateKey": { "message": "私鑰", "description": "select this type of file to use to import an account" @@ -681,6 +714,9 @@ "onlySendToEtherAddress": { "message": "只發送 ETH 到乙太坊地址." }, + "searchTokens": { + "message": "搜尋代幣" + }, "sendTokensAnywhere": { "message": "發送代幣給擁有乙太坊帳戶的任何人" }, @@ -700,13 +736,16 @@ "message": "顯示 QR Code" }, "sign": { - "message": "簽名" + "message": "簽署" + }, + "signed": { + "message": "已簽署" }, "signMessage": { "message": "簽署訊息" }, "signNotice": { - "message": "簽署此訊息可能會產生危險的副作用。 \n只從你完全信任的網站上簽名。這種危險的方法;將在未來的版本中被移除。" + "message": "簽署此訊息可能會產生危險地副作用。 \n只從你完全信任的網站上簽署。這種危險的方法;將在未來的版本中被移除。" }, "sigRequest": { "message": "請求簽署" @@ -767,7 +806,7 @@ "message": "代幣餘額:" }, "tokenSelection": { - "message": "搜尋代幣或是從熱門代幣列表中選擇。" + "message": "搜尋代幣或是從常見代幣列表中選擇。" }, "tokenSymbol": { "message": "代幣代號" @@ -804,7 +843,7 @@ "message": "歡迎使用新版界面 (Beta)" }, "uiWelcomeMessage": { - "message": "你現在正在使用新的 Metamask 界面。試試諸如發送代幣等新功能,有任何問題請告知我們。" + "message": "你現在正在使用新版 MetaMask 界面。試試諸如發送代幣等新功能吧,有任何問題請告知我們。" }, "unapproved": { "message": "未同意" diff --git a/app/home.html b/app/home.html index cfb4b00a0..4fad0f993 100644 --- a/app/home.html +++ b/app/home.html @@ -3,10 +3,10 @@ - MetaMask Plugin + MetaMask
- + diff --git a/app/manifest.json b/app/manifest.json index a20f9b976..dc46f1ca4 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "__MSG_appName__", - "version": "4.4.0", + "version": "4.5.5", "manifest_version": 2, "author": "https://metamask.io", "description": "__MSG_appDescription__", @@ -27,8 +27,8 @@ "default_locale": "en", "background": { "scripts": [ - "scripts/chromereload.js", - "scripts/background.js" + "chromereload.js", + "background.js" ], "persistent": true }, @@ -48,7 +48,7 @@ "https://*/*" ], "js": [ - "scripts/contentscript.js" + "contentscript.js" ], "run_at": "document_start", "all_frames": true @@ -62,7 +62,7 @@ "https://*.infura.io/" ], "web_accessible_resources": [ - "scripts/inpage.js" + "inpage.js" ], "externally_connectable": { "matches": [ diff --git a/app/notification.html b/app/notification.html index f10cbbf41..457ba7137 100644 --- a/app/notification.html +++ b/app/notification.html @@ -11,6 +11,6 @@
- + diff --git a/app/popup.html b/app/popup.html index bf09b97ca..3acfd8c55 100644 --- a/app/popup.html +++ b/app/popup.html @@ -3,10 +3,10 @@ - MetaMask Plugin + MetaMask
- + diff --git a/app/scripts/background.js b/app/scripts/background.js index 7bbaa89d6..ec586f642 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -19,10 +19,11 @@ const setupRaven = require('./lib/setupRaven') 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 STORAGE_KEY = 'metamask-config' -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +const METAMASK_DEBUG = process.env.METAMASK_DEBUG window.log = log log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') @@ -58,7 +59,8 @@ setupMetamaskMeshMetrics() async function initialize () { const initState = await loadStateFromPersistence() - await setupController(initState) + const initLangCode = await getFirstPreferredLangCode() + await setupController(initState, initLangCode) log.debug('MetaMask initialization complete.') } @@ -76,6 +78,16 @@ async function loadStateFromPersistence () { diskStore.getState() || migrator.generateInitialState(firstTimeState) + // 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) { @@ -83,13 +95,20 @@ 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 } -function setupController (initState) { +function setupController (initState, initLangCode) { // // MetaMask Controller // @@ -101,6 +120,8 @@ function setupController (initState) { showUnapprovedTx: triggerUi, // initial state initState, + // initial locale code + initLangCode, // platform specific api platform, encryptor: isEdge ? new EdgeEncryptor() : undefined, diff --git a/app/scripts/config.js b/app/scripts/config.js index 74c5b576e..a8470ed82 100644 --- a/app/scripts/config.js +++ b/app/scripts/config.js @@ -13,7 +13,7 @@ const DEFAULT_RPC = 'rinkeby' const OLD_UI_NETWORK_TYPE = 'network' const BETA_UI_NETWORK_TYPE = 'networkBeta' -global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +global.METAMASK_DEBUG = process.env.METAMASK_DEBUG module.exports = { network: { diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 7abbc60e7..fe1766273 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -7,8 +7,8 @@ const ObjectMultiplex = require('obj-multiplex') const extension = require('extensionizer') const PortStream = require('./lib/port-stream.js') -const inpageContent = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', 'chrome', 'scripts', 'inpage.js')).toString() -const inpageSuffix = '//# sourceURL=' + extension.extension.getURL('scripts/inpage.js') + '\n' +const inpageContent = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', 'chrome', 'inpage.js')).toString() +const inpageSuffix = '//# sourceURL=' + extension.extension.getURL('inpage.js') + '\n' const inpageBundle = inpageContent + inpageSuffix // Eventually this streaming injection could be replaced with: @@ -96,7 +96,7 @@ function logStreamDisconnectWarning (remoteLabel, err) { } function shouldInjectWeb3 () { - return doctypeCheck() && suffixCheck() + return doctypeCheck() && suffixCheck() && documentElementCheck() && !blacklistedDomainCheck() } @@ -131,7 +131,11 @@ function documentElementCheck () { } function blacklistedDomainCheck () { - var blacklistedDomains = ['uscourts.gov', 'dropbox.com'] + var blacklistedDomains = [ + 'uscourts.gov', + 'dropbox.com', + 'webbyawards.com', + ] var currentUrl = window.location.href var currentRegex for (let i = 0; i < blacklistedDomains.length; i++) { diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js index 33c31dab9..df41c90c0 100644 --- a/app/scripts/controllers/blacklist.js +++ b/app/scripts/controllers/blacklist.js @@ -41,9 +41,9 @@ class BlacklistController { scheduleUpdates () { if (this._phishingUpdateIntervalRef) return - this.updatePhishingList() + this.updatePhishingList().catch(log.warn) this._phishingUpdateIntervalRef = setInterval(() => { - this.updatePhishingList() + this.updatePhishingList().catch(log.warn) }, POLLING_INTERVAL) } @@ -57,4 +57,3 @@ class BlacklistController { } module.exports = BlacklistController - diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index 25a7a942e..36b8808aa 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -43,20 +43,19 @@ class CurrencyController { this.store.updateState({ conversionDate }) } - updateConversionRate () { - const currentCurrency = this.getCurrentCurrency() - return fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) - .then(response => response.json()) - .then((parsedResponse) => { + async updateConversionRate () { + let currentCurrency + try { + currentCurrency = this.getCurrentCurrency() + const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) + const parsedResponse = await response.json() this.setConversionRate(Number(parsedResponse.bid)) this.setConversionDate(Number(parsedResponse.timestamp)) - }).catch((err) => { - if (err) { - console.warn('MetaMask - Failed to query currency conversion.') - this.setConversionRate(0) - this.setConversionDate('N/A') - } - }) + } catch (err) { + log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err) + this.setConversionRate(0) + this.setConversionDate('N/A') + } } scheduleConversionInterval () { diff --git a/app/scripts/controllers/infura.js b/app/scripts/controllers/infura.js index 10adb1004..c6b4c9de2 100644 --- a/app/scripts/controllers/infura.js +++ b/app/scripts/controllers/infura.js @@ -19,15 +19,13 @@ class InfuraController { // Responsible for retrieving the status of Infura's nodes. Can return either // ok, degraded, or down. - checkInfuraNetworkStatus () { - return fetch('https://api.infura.io/v1/status/metamask') - .then(response => response.json()) - .then((parsedResponse) => { - this.store.updateState({ - infuraNetworkStatus: parsedResponse, - }) - return parsedResponse - }) + async checkInfuraNetworkStatus () { + const response = await fetch('https://api.infura.io/v1/status/metamask') + const parsedResponse = await response.json() + this.store.updateState({ + infuraNetworkStatus: parsedResponse, + }) + return parsedResponse } scheduleInfuraNetworkCheck () { @@ -35,7 +33,7 @@ class InfuraController { clearInterval(this.conversionInterval) } this.conversionInterval = setInterval(() => { - this.checkInfuraNetworkStatus() + this.checkInfuraNetworkStatus().catch(log.warn) }, POLLING_INTERVAL) } } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 39d15fd83..b4819d951 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -11,6 +11,7 @@ class PreferencesController { tokens: [], useBlockie: false, featureFlags: {}, + currentLocale: opts.initLangCode, }, opts.initState) this.store = new ObservableStore(initState) } @@ -24,6 +25,10 @@ class PreferencesController { return this.store.getState().useBlockie } + setCurrentLocale (key) { + this.store.updateState({ currentLocale: key }) + } + setSelectedAddress (_address) { return new Promise((resolve, reject) => { const address = normalizeAddress(_address) diff --git a/app/scripts/controllers/shapeshift.js b/app/scripts/controllers/shapeshift.js index 3d955c01f..3bbfaa1c5 100644 --- a/app/scripts/controllers/shapeshift.js +++ b/app/scripts/controllers/shapeshift.js @@ -45,18 +45,19 @@ class ShapeshiftController { }) } - updateTx (tx) { - const url = `https://shapeshift.io/txStat/${tx.depositAddress}` - return fetch(url) - .then((response) => { - return response.json() - }).then((json) => { + async updateTx (tx) { + try { + const url = `https://shapeshift.io/txStat/${tx.depositAddress}` + const response = await fetch(url) + const json = await response.json() tx.response = json if (tx.response.status === 'complete') { tx.time = new Date().getTime() } return tx - }) + } catch (err) { + log.warn(err) + } } saveTx (tx) { diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 3e3909361..336b0d8f7 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -161,9 +161,11 @@ module.exports = class TransactionController extends EventEmitter { this.emit(`${txMeta.id}:unapproved`, txMeta) } - async newUnapprovedTransaction (txParams) { + async newUnapprovedTransaction (txParams, opts = {}) { log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`) const initialTxMeta = await this.addUnapprovedTransaction(txParams) + initialTxMeta.origin = opts.origin + this.txStateManager.updateTx(initialTxMeta, '#newUnapprovedTransaction - adding the origin') // listen for tx completion (success, fail) return new Promise((resolve, reject) => { this.txStateManager.once(`${initialTxMeta.id}:finished`, (finishedTxMeta) => { @@ -183,14 +185,15 @@ module.exports = class TransactionController extends EventEmitter { async addUnapprovedTransaction (txParams) { // validate - await this.txGasUtil.validateTxParams(txParams) + const normalizedTxParams = this._normalizeTxParams(txParams) + this._validateTxParams(normalizedTxParams) // construct txMeta - const txMeta = this.txStateManager.generateTxMeta({txParams}) + let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams }) this.addTx(txMeta) this.emit('newUnapprovedTx', txMeta) // add default tx params try { - await this.addTxDefaults(txMeta) + txMeta = await this.addTxDefaults(txMeta) } catch (error) { console.log(error) this.txStateManager.setTxStatusFailed(txMeta.id, error) @@ -250,7 +253,7 @@ module.exports = class TransactionController extends EventEmitter { // wait for a nonce nonceLock = await this.nonceTracker.getNonceLock(fromAddress) // add nonce to txParams - // if txMeta has lastGasPrice then it is a retry at same nonce with higher + // if txMeta has lastGasPrice then it is a retry at same nonce with higher // gas price transaction and their for the nonce should not be calculated const nonce = txMeta.lastGasPrice ? txMeta.txParams.nonce : nonceLock.nextNonce txMeta.txParams.nonce = ethUtil.addHexPrefix(nonce.toString(16)) @@ -273,12 +276,14 @@ module.exports = class TransactionController extends EventEmitter { async signTransaction (txId) { const txMeta = this.txStateManager.getTx(txId) - const txParams = txMeta.txParams - const fromAddress = txParams.from // add network/chain id - txParams.chainId = ethUtil.addHexPrefix(this.getChainId().toString(16)) + const chainId = this.getChainId() + const txParams = Object.assign({}, txMeta.txParams, { chainId }) + // sign tx + const fromAddress = txParams.from const ethTx = new Transaction(txParams) await this.signEthTx(ethTx, fromAddress) + // set state to signed this.txStateManager.setTxStatusSigned(txMeta.id) const rawTx = ethUtil.bufferToHex(ethTx.serialize()) return rawTx @@ -309,6 +314,60 @@ module.exports = class TransactionController extends EventEmitter { // PRIVATE METHODS // + _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 + } + + _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 (!ethUtil.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 && !ethUtil.isValidAddress(txParams.to) ) { + throw new Error('Invalid recipient address') + } + return txParams + } + _markNonceDuplicatesDropped (txId) { this.txStateManager.setTxStatusConfirmed(txId) // get the confirmed transactions nonce and from address diff --git a/app/scripts/first-time-state.js b/app/scripts/first-time-state.js index 5e8577100..3063df627 100644 --- a/app/scripts/first-time-state.js +++ b/app/scripts/first-time-state.js @@ -1,6 +1,6 @@ // test and development environment variables const env = process.env.METAMASK_ENV -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +const METAMASK_DEBUG = process.env.METAMASK_DEBUG // // The default state of MetaMask diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 9261e7d64..ec99bfc35 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -9,7 +9,7 @@ const setupDappAutoReload = require('./lib/auto-reload.js') const MetamaskInpageProvider = require('./lib/inpage-provider.js') restoreContextAfterImports() -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +const METAMASK_DEBUG = process.env.METAMASK_DEBUG window.log = log log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn') diff --git a/app/scripts/lib/extractEthjsErrorMessage.js b/app/scripts/lib/extractEthjsErrorMessage.js new file mode 100644 index 000000000..bac541735 --- /dev/null +++ b/app/scripts/lib/extractEthjsErrorMessage.js @@ -0,0 +1,27 @@ +const ethJsRpcSlug = 'Error: [ethjs-rpc] rpc error with payload ' +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 +// + + +function extractEthjsErrorMessage(errorMessage) { + const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug) + if (isEthjsRpcError) { + const payloadAndError = errorMessage.slice(ethJsRpcSlug.length) + const originalError = payloadAndError.slice(payloadAndError.indexOf(errorLabelPrefix) + errorLabelPrefix.length) + return originalError + } else { + return errorMessage + } +} diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js new file mode 100644 index 000000000..e3635434e --- /dev/null +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -0,0 +1,18 @@ +const extension = require('extensionizer') +const promisify = require('pify') +const allLocales = require('../../_locales/index.json') + +const existingLocaleCodes = allLocales.map(locale => locale.code.toLowerCase().replace('_', '-')) + +async function getFirstPreferredLangCode () { + const userPreferredLocaleCodes = await promisify( + extension.i18n.getAcceptLanguages, + { errorFirst: false } + )() + const firstPreferredLangCode = userPreferredLocaleCodes + .map(code => code.toLowerCase()) + .find(code => existingLocaleCodes.includes(code)) + return firstPreferredLangCode || 'en' +} + +module.exports = getFirstPreferredLangCode diff --git a/app/scripts/lib/getObjStructure.js b/app/scripts/lib/getObjStructure.js new file mode 100644 index 000000000..3db389507 --- /dev/null +++ b/app/scripts/lib/getObjStructure.js @@ -0,0 +1,33 @@ +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" +// } +// } + +function getObjStructure(obj) { + const structure = clone(obj) + return deepMap(structure, (value) => { + return value === null ? 'null' : typeof value + }) +} + +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/migrator/index.js b/app/scripts/lib/migrator/index.js index 4fd2cae92..85c2717ea 100644 --- a/app/scripts/lib/migrator/index.js +++ b/app/scripts/lib/migrator/index.js @@ -1,6 +1,9 @@ -class Migrator { +const EventEmitter = require('events') + +class Migrator extends EventEmitter { constructor (opts = {}) { + super() const migrations = opts.migrations || [] // sort migrations by version this.migrations = migrations.sort((a, b) => a.version - b.version) @@ -12,13 +15,29 @@ 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 diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index ed9dd3f11..5b1cd7f43 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -31,14 +31,13 @@ class NonceTracker { const networkNonceResult = await this._getNetworkNextNonce(address) const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address) const nextNetworkNonce = networkNonceResult.nonce - const highestLocalNonce = highestLocallyConfirmed - const highestSuggested = Math.max(nextNetworkNonce, highestLocalNonce) + const highestSuggested = Math.max(nextNetworkNonce, highestLocallyConfirmed) const pendingTxs = this.getPendingTransactions(address) const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0 nonceDetails.params = { - highestLocalNonce, + highestLocallyConfirmed, highestSuggested, nextNetworkNonce, } diff --git a/app/scripts/lib/reportFailedTxToSentry.js b/app/scripts/lib/reportFailedTxToSentry.js index ee73f6845..e09f4f1f8 100644 --- a/app/scripts/lib/reportFailedTxToSentry.js +++ b/app/scripts/lib/reportFailedTxToSentry.js @@ -1,5 +1,4 @@ -const ethJsRpcSlug = 'Error: [ethjs-rpc] rpc error with payload ' -const errorLabelPrefix = 'Error: ' +const extractEthjsErrorMessage = require('./extractEthjsErrorMessage') module.exports = reportFailedTxToSentry @@ -9,30 +8,9 @@ module.exports = reportFailedTxToSentry // function reportFailedTxToSentry({ raven, txMeta }) { - const errorMessage = extractErrorMessage(txMeta.err.message) + const errorMessage = 'Transaction Failed: ' + extractEthjsErrorMessage(txMeta.err.message) raven.captureMessage(errorMessage, { // "extra" key is required by Sentry extra: txMeta, }) } - -// -// 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 -// - -function extractErrorMessage(errorMessage) { - const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug) - if (isEthjsRpcError) { - const payloadAndError = errorMessage.slice(ethJsRpcSlug.length) - const originalError = payloadAndError.slice(payloadAndError.indexOf(errorLabelPrefix) + errorLabelPrefix.length) - return `Transaction Failed: ${originalError}` - } else { - return `Transaction Failed: ${errorMessage}` - } -} diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupRaven.js index 02c01b755..9ec9a256f 100644 --- a/app/scripts/lib/setupRaven.js +++ b/app/scripts/lib/setupRaven.js @@ -1,5 +1,6 @@ const Raven = require('raven-js') -const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +const METAMASK_DEBUG = process.env.METAMASK_DEBUG +const extractEthjsErrorMessage = require('./extractEthjsErrorMessage') const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' @@ -21,8 +22,22 @@ function setupRaven(opts) { const client = Raven.config(ravenTarget, { release, transport: function(opts) { - // modify report urls 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) // make request normally client._makeRequest(opts) diff --git a/app/scripts/lib/tx-gas-utils.js b/app/scripts/lib/tx-gas-utils.js index 0fa9dd8d4..c579e462a 100644 --- a/app/scripts/lib/tx-gas-utils.js +++ b/app/scripts/lib/tx-gas-utils.js @@ -4,7 +4,7 @@ const { BnMultiplyByFraction, bnToHex, } = require('./util') -const { addHexPrefix, isValidAddress } = require('ethereumjs-util') +const { addHexPrefix } = require('ethereumjs-util') const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send. /* @@ -52,7 +52,9 @@ module.exports = class TxGasUtil { // if recipient has no code, gas is 21k max: const recipient = txParams.to const hasRecipient = Boolean(recipient) - const code = await this.query.getCode(recipient) + let code + if (recipient) code = await this.query.getCode(recipient) + if (hasRecipient && (!code || code === '0x')) { txParams.gas = SIMPLE_GAS_COST txMeta.simpleSend = true // Prevents buffer addition @@ -98,30 +100,4 @@ module.exports = class TxGasUtil { // otherwise use blockGasLimit return bnToHex(upperGasLimitBn) } - - async validateTxParams (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`) - } - } - } - 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 diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js index ad07c813f..d8ea17400 100644 --- a/app/scripts/lib/tx-state-manager.js +++ b/app/scripts/lib/tx-state-manager.js @@ -38,11 +38,6 @@ module.exports = class TransactionStateManager extends EventEmitter { }, opts) } - // Returns the number of txs for the current network. - getTxCount () { - return this.getTxList().length - } - getTxList () { const network = this.getNetwork() const fullTxList = this.getFullTxList() @@ -88,7 +83,7 @@ module.exports = class TransactionStateManager extends EventEmitter { txMeta.history.push(snapshot) const transactions = this.getFullTxList() - const txCount = this.getTxCount() + const txCount = transactions.length const txHistoryLimit = this.txHistoryLimit // checks if the length of the tx history is @@ -111,12 +106,13 @@ module.exports = class TransactionStateManager extends EventEmitter { } updateTx (txMeta, note) { + // validate txParams if (txMeta.txParams) { - Object.keys(txMeta.txParams).forEach((key) => { - const value = txMeta.txParams[key] - if (typeof value !== 'string') console.error(`${key}: ${value} in txParams is not a string`) - if (!ethUtil.isHexPrefixed(value)) console.error('is not hex prefixed, anything on txParams must be hex prefixed') - }) + if (typeof txMeta.txParams.data === 'undefined') { + delete txMeta.txParams.data + } + + this.validateTxParams(txMeta.txParams) } // create txMeta snapshot for history @@ -144,6 +140,23 @@ module.exports = class TransactionStateManager extends EventEmitter { this.updateTx(txMeta, `txStateManager#updateTxParams`) } + // validates txParams members by type + validateTxParams(txParams) { + Object.keys(txParams).forEach((key) => { + const value = txParams[key] + // validate types + switch (key) { + case 'chainId': + if (typeof value !== 'number' && typeof value !== 'string') throw new Error(`${key} in txParams is not a Number or hex string. got: (${value})`) + break + default: + if (typeof value !== 'string') throw new Error(`${key} in txParams is not a string. got: (${value})`) + if (!ethUtil.isHexPrefixed(value)) throw new Error(`${key} in txParams is not hex prefixed. got: (${value})`) + break + } + }) + } + /* Takes an object of fields to search for eg: let thingsToLookFor = { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 18d71874a..b96acc9da 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -49,7 +49,7 @@ module.exports = class MetamaskController extends EventEmitter { /** * @constructor - * @param {Object} opts + * @param {Object} opts */ constructor (opts) { super() @@ -57,7 +57,6 @@ module.exports = class MetamaskController extends EventEmitter { this.defaultMaxListeners = 20 this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200) - this.opts = opts const initState = opts.initState || {} this.recordFirstTimeInfo(initState) @@ -82,6 +81,7 @@ module.exports = class MetamaskController extends EventEmitter { // preferences controller this.preferencesController = new PreferencesController({ initState: initState.PreferencesController, + initLangCode: opts.initLangCode, }) // currency controller @@ -241,6 +241,11 @@ module.exports = class MetamaskController extends EventEmitter { static: { eth_syncing: false, web3_clientVersion: `MetaMask/v${version}`, + eth_sendTransaction: (payload, next, end) => { + const origin = payload.origin + const txParams = payload.params[0] + nodeify(this.txController.newUnapprovedTransaction, this.txController)(txParams, { origin }, end) + }, }, // account mgmt getAccounts: (cb) => { @@ -255,7 +260,6 @@ module.exports = class MetamaskController extends EventEmitter { cb(null, result) }, // tx signing - processTransaction: nodeify(async (txParams) => await this.txController.newUnapprovedTransaction(txParams), this), // old style msg signing processMessage: this.newUnsignedMessage.bind(this), // personal_sign msg signing @@ -296,8 +300,8 @@ module.exports = class MetamaskController extends EventEmitter { /** * The metamask-state of the various controllers, made available to the UI - * - * @returns {Object} status + * + * @returns {Object} status */ getState () { const wallet = this.configManager.getWallet() @@ -335,8 +339,8 @@ module.exports = class MetamaskController extends EventEmitter { /** * Returns an api-object which is consumed by the UI - * - * @returns {Object} + * + * @returns {Object} */ getApi () { const keyringController = this.keyringController @@ -351,6 +355,7 @@ module.exports = class MetamaskController extends EventEmitter { getState: (cb) => cb(null, this.getState()), setCurrentCurrency: this.setCurrentCurrency.bind(this), setUseBlockie: this.setUseBlockie.bind(this), + setCurrentLocale: this.setCurrentLocale.bind(this), markAccountsFound: this.markAccountsFound.bind(this), markPasswordForgotten: this.markPasswordForgotten.bind(this), unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this), @@ -365,7 +370,7 @@ module.exports = class MetamaskController extends EventEmitter { placeSeedWords: this.placeSeedWords.bind(this), verifySeedPhrase: nodeify(this.verifySeedPhrase, this), clearSeedWordCache: this.clearSeedWordCache.bind(this), - resetAccount: this.resetAccount.bind(this), + resetAccount: nodeify(this.resetAccount, this), importAccountWithStrategy: this.importAccountWithStrategy.bind(this), // vault management @@ -426,14 +431,14 @@ module.exports = class MetamaskController extends EventEmitter { /** * Creates a new Vault(?) and create a new keychain(?) - * + * * A vault is ... - * + * * A keychain is ... - * + * * * @param {} password - * + * * @returns {} vault */ async createNewVaultAndKeychain (password) { @@ -479,9 +484,9 @@ module.exports = class MetamaskController extends EventEmitter { /** * Retrieves the first Identiy from the passed Vault and selects the related address - * + * * An Identity is ... - * + * * @param {} vault */ selectFirstIdentity (vault) { @@ -495,8 +500,8 @@ module.exports = class MetamaskController extends EventEmitter { // /** - * Adds a new account to ... - * + * Adds a new account to ... + * * @returns {} keyState */ async addNewAccount () { @@ -522,10 +527,10 @@ module.exports = class MetamaskController extends EventEmitter { /** * Adds the current vault's seed words to the UI's state tree. - * + * * Used when creating a first vault, to allow confirmation. * Also used when revealing the seed words in the confirmation view. - */ + */ placeSeedWords (cb) { this.verifySeedPhrase() @@ -540,7 +545,7 @@ module.exports = class MetamaskController extends EventEmitter { /** * Verifies the validity of the current vault's seed phrase. - * + * * Validity: seed phrase restores the accounts belonging to the current vault. * * Called when the first account is created and on unlocking the vault. @@ -571,27 +576,32 @@ module.exports = class MetamaskController extends EventEmitter { /** * Remove the primary account seed phrase from the UI's state tree. - * + * * The seed phrase remains available in the background process. - * + * */ clearSeedWordCache (cb) { this.configManager.setSeedWords(null) cb(null, this.preferencesController.getSelectedAddress()) } - + /** * ? */ - resetAccount (cb) { + async resetAccount (cb) { const selectedAddress = this.preferencesController.getSelectedAddress() this.txController.wipeTransactions(selectedAddress) - cb(null, selectedAddress) + + const networkController = this.networkController + const oldType = networkController.getProviderConfig().type + await networkController.setProviderType(oldType, true) + + return selectedAddress } /** * Imports an account ... ? - * + * * @param {} strategy * @param {} args * @param {} cb @@ -634,9 +644,9 @@ module.exports = class MetamaskController extends EventEmitter { } // Prefixed Style Message Signing Methods: - + /** - * + * * @param {} msgParams * @param {} cb */ @@ -655,7 +665,7 @@ module.exports = class MetamaskController extends EventEmitter { } }) } - + /** * @param {} msgParams */ @@ -676,7 +686,7 @@ module.exports = class MetamaskController extends EventEmitter { return this.getState() }) } - + /** * @param {} msgParams */ @@ -697,13 +707,13 @@ module.exports = class MetamaskController extends EventEmitter { return this.getState() }) } - + // --------------------------------------------------------------------------- // Account Restauration /** * ? - * + * * @param {} migratorOutput */ restoreOldVaultAccounts (migratorOutput) { @@ -714,7 +724,7 @@ module.exports = class MetamaskController extends EventEmitter { /** * ? - * + * * @param {} migratorOutput */ restoreOldLostAccounts (migratorOutput) { @@ -728,9 +738,9 @@ module.exports = class MetamaskController extends EventEmitter { /** * Import (lost) Accounts - * + * * @param {Object} {lostAccounts} @Array accounts <{ address, privateKey }> - * + * * Uses the array's private keys to create a new Simple Key Pair keychain * and add it to the keyring controller. */ @@ -823,7 +833,7 @@ module.exports = class MetamaskController extends EventEmitter { if (cb && typeof cb === 'function') { cb(null, this.getState()) } - } + } cancelPersonalMessage (msgId, cb) { const messageManager = this.personalMessageManager @@ -978,7 +988,7 @@ module.exports = class MetamaskController extends EventEmitter { const percentileNum = percentile(50, lowestPrices) const percentileNumBn = new BN(percentileNum) return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) - } + } //============================================================================= // CONFIG @@ -1029,6 +1039,15 @@ module.exports = class MetamaskController extends EventEmitter { } } + setCurrentLocale (key, cb) { + try { + this.preferencesController.setCurrentLocale(key) + cb(null) + } catch (err) { + cb(err) + } + } + recordFirstTimeInfo (initState) { if (!('firstTimeInfo' in initState)) { initState.firstTimeInfo = { 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..bea1fe3da 100644 --- a/app/scripts/migrations/018.js +++ b/app/scripts/migrations/018.js @@ -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 + 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 - }) + 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 new file mode 100644 index 000000000..151496b06 --- /dev/null +++ b/app/scripts/migrations/023.js @@ -0,0 +1,54 @@ + +const version = 23 + +/* + +This migration removes transactions that are no longer usefull down to 40 total + +*/ + +const clone = require('clone') + +module.exports = { + version, + + migrate: function (originalVersionedData) { + const versionedData = clone(originalVersionedData) + versionedData.meta.version = version + try { + const state = versionedData.data + const newState = transformState(state) + versionedData.data = newState + } catch (err) { + console.warn(`MetaMask Migration #${version}` + err.stack) + } + return Promise.resolve(versionedData) + }, +} + +function transformState (state) { + const newState = state + + 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 b49a40c65..6c4a51b32 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -33,4 +33,7 @@ module.exports = [ require('./020'), 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/popup.js b/app/scripts/popup.js deleted file mode 100644 index e78981f06..000000000 --- a/app/scripts/popup.js +++ /dev/null @@ -1,78 +0,0 @@ -const injectCss = require('inject-css') -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 extension = require('extensionizer') -const ExtensionPlatform = require('./platforms/extension') -const NotificationManager = require('./lib/notification-manager') -const notificationManager = new NotificationManager() -const setupRaven = require('./lib/setupRaven') - -// create platform global -global.platform = new ExtensionPlatform() - -// setup sentry error reporting -const release = global.platform.getVersion() -setupRaven({ release }) - -// inject css -// const css = MetaMaskUiCss() -// injectCss(css) - -// identify window type (popup, notification) -const windowType = isPopupOrNotification() -global.METAMASK_UI_TYPE = windowType -closePopupIfOpen(windowType) - -// setup stream to background -const extensionPort = extension.runtime.connect({ name: windowType }) -const connectionStream = new PortStream(extensionPort) - -// start ui -const container = document.getElementById('app-content') -startPopup({ container, connectionStream }, (err, store) => { - if (err) return displayCriticalError(err) - - // Code commented out until we begin auto adding users to NewUI - // const { isMascara, identities = {}, featureFlags = {} } = store.getState().metamask - // const firstTime = Object.keys(identities).length === 0 - const { isMascara, featureFlags = {} } = store.getState().metamask - let betaUIState = featureFlags.betaUI - - // Code commented out until we begin auto adding users to NewUI - // const useBetaCss = isMascara || firstTime || betaUIState - const useBetaCss = isMascara || betaUIState - - let css = useBetaCss ? NewMetaMaskUiCss() : OldMetaMaskUiCss() - let deleteInjectedCss = injectCss(css) - let newBetaUIState - - store.subscribe(() => { - const state = store.getState() - newBetaUIState = state.metamask.featureFlags.betaUI - if (newBetaUIState !== betaUIState) { - deleteInjectedCss() - betaUIState = newBetaUIState - css = betaUIState ? NewMetaMaskUiCss() : OldMetaMaskUiCss() - deleteInjectedCss = injectCss(css) - } - if (state.appState.shouldClose) notificationManager.closePopup() - }) -}) - - -function closePopupIfOpen (windowType) { - if (windowType !== 'notification') { - // should close only chrome popup - notificationManager.closePopup() - } -} - -function displayCriticalError (err) { - container.innerHTML = '
The MetaMask app failed to load: please open and close MetaMask again to restart.
' - container.style.height = '80px' - log.error(err.stack) - throw err -} diff --git a/app/scripts/ui.js b/app/scripts/ui.js new file mode 100644 index 000000000..13c7ac5ec --- /dev/null +++ b/app/scripts/ui.js @@ -0,0 +1,84 @@ +const injectCss = require('inject-css') +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 extension = require('extensionizer') +const ExtensionPlatform = require('./platforms/extension') +const NotificationManager = require('./lib/notification-manager') +const notificationManager = new NotificationManager() +const setupRaven = require('./lib/setupRaven') + +start().catch(log.error) + +async function start() { + + // create platform global + global.platform = new ExtensionPlatform() + + // setup sentry error reporting + const release = global.platform.getVersion() + setupRaven({ release }) + + // inject css + // const css = MetaMaskUiCss() + // injectCss(css) + + // identify window type (popup, notification) + const windowType = isPopupOrNotification() + global.METAMASK_UI_TYPE = windowType + closePopupIfOpen(windowType) + + // setup stream to background + const extensionPort = extension.runtime.connect({ name: windowType }) + const connectionStream = new PortStream(extensionPort) + + // start ui + const container = document.getElementById('app-content') + startPopup({ container, connectionStream }, (err, store) => { + if (err) return displayCriticalError(err) + + // Code commented out until we begin auto adding users to NewUI + // const { isMascara, identities = {}, featureFlags = {} } = store.getState().metamask + // const firstTime = Object.keys(identities).length === 0 + const { isMascara, featureFlags = {} } = store.getState().metamask + let betaUIState = featureFlags.betaUI + + // Code commented out until we begin auto adding users to NewUI + // const useBetaCss = isMascara || firstTime || betaUIState + const useBetaCss = isMascara || betaUIState + + let css = useBetaCss ? NewMetaMaskUiCss() : OldMetaMaskUiCss() + let deleteInjectedCss = injectCss(css) + let newBetaUIState + + store.subscribe(() => { + const state = store.getState() + newBetaUIState = state.metamask.featureFlags.betaUI + if (newBetaUIState !== betaUIState) { + deleteInjectedCss() + betaUIState = newBetaUIState + css = betaUIState ? NewMetaMaskUiCss() : OldMetaMaskUiCss() + deleteInjectedCss = injectCss(css) + } + if (state.appState.shouldClose) notificationManager.closePopup() + }) + }) + + + function closePopupIfOpen (windowType) { + if (windowType !== 'notification') { + // should close only chrome popup + notificationManager.closePopup() + } + } + + function displayCriticalError (err) { + container.innerHTML = '
The MetaMask app failed to load: please open and close MetaMask again to restart.
' + container.style.height = '80px' + log.error(err.stack) + throw err + } + +} diff --git a/development/genStates.js b/development/genStates.js index bc274c757..0ac1059be 100644 --- a/development/genStates.js +++ b/development/genStates.js @@ -1,6 +1,8 @@ const fs = require('fs') const path = require('path') const promisify = require('pify') +const enLocaleMessages = require('../app/_locales/en/messages.json') + start().catch(console.error) @@ -12,6 +14,9 @@ async function start () { const stateFilePath = path.join(__dirname, 'states', stateFileName) const stateFileContent = await promisify(fs.readFile)(stateFilePath, 'utf8') const state = JSON.parse(stateFileContent) + + state.localeMessages = { en: enLocaleMessages, current: {} } + const stateName = stateFileName.split('.')[0].replace(/-/g, ' ', 'g') states[stateName] = state })) diff --git a/development/metamaskbot-build-announce.js b/development/metamaskbot-build-announce.js new file mode 100755 index 000000000..88614ca5c --- /dev/null +++ b/development/metamaskbot-build-announce.js @@ -0,0 +1,62 @@ +#!/usr/bin/env node +const request = require('request-promise') +const VERSION = require('../dist/chrome/manifest.json').version + +start().catch(console.error) + +async function start() { + + const GITHUB_COMMENT_TOKEN = process.env.GITHUB_COMMENT_TOKEN + const CIRCLE_PULL_REQUEST = process.env.CIRCLE_PULL_REQUEST + console.log('CIRCLE_PULL_REQUEST', CIRCLE_PULL_REQUEST) + const CIRCLE_SHA1 = process.env.CIRCLE_SHA1 + console.log('CIRCLE_SHA1', CIRCLE_SHA1) + const CIRCLE_BUILD_NUM = process.env.CIRCLE_BUILD_NUM + console.log('CIRCLE_BUILD_NUM', CIRCLE_BUILD_NUM) + + if (!CIRCLE_PULL_REQUEST) { + console.warn(`No pull request detected for commit "${CIRCLE_SHA1}"`) + return + } + + const CIRCLE_PR_NUMBER = CIRCLE_PULL_REQUEST.split('/').pop() + const SHORT_SHA1 = CIRCLE_SHA1.slice(0,7) + const BUILD_LINK_BASE = `https://${CIRCLE_BUILD_NUM}-42009758-gh.circle-artifacts.com/0` + + const MASCARA = `${BUILD_LINK_BASE}/builds/mascara/home.html` + const CHROME = `${BUILD_LINK_BASE}/builds/metamask-chrome-${VERSION}.zip` + const FIREFOX = `${BUILD_LINK_BASE}/builds/metamask-firefox-${VERSION}.zip` + const EDGE = `${BUILD_LINK_BASE}/builds/metamask-edge-${VERSION}.zip` + const OPERA = `${BUILD_LINK_BASE}/builds/metamask-opera-${VERSION}.zip` + const WALKTHROUGH = `${BUILD_LINK_BASE}/test-artifacts/screens/walkthrough%20%28en%29.gif` + + const commentBody = ` +
+ + Builds ready [${SHORT_SHA1}]: + mascara, + chrome, + firefox, + edge, + opera + + +
+ ` + + const JSON_PAYLOAD = JSON.stringify({ body: commentBody }) + const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${CIRCLE_PR_NUMBER}/comments` + console.log(`Announcement:\n${commentBody}`) + console.log(`Posting to: ${POST_COMMENT_URI}`) + + await request({ + method: 'POST', + uri: POST_COMMENT_URI, + body: JSON_PAYLOAD, + headers: { + 'User-Agent': 'metamaskbot', + 'Authorization': `token ${GITHUB_COMMENT_TOKEN}`, + }, + }) + +} diff --git a/development/sentry-publish.js b/development/sentry-publish.js new file mode 100644 index 000000000..ab3acabbd --- /dev/null +++ b/development/sentry-publish.js @@ -0,0 +1,55 @@ +#!/usr/bin/env node +const pify = require('pify') +const exec = pify(require('child_process').exec, { multiArgs: true }) +const VERSION = require('../dist/chrome/manifest.json').version + +start().catch(console.error) + +async function start(){ + const authWorked = await checkIfAuthWorks() + if (!authWorked) { + console.log(`Sentry auth failed...`) + } + // check if version exists or not + const versionAlreadyExists = await checkIfVersionExists() + // abort if versions exists + if (versionAlreadyExists) { + console.log(`Version "${VERSION}" already exists on Sentry, aborting sourcemap upload.`) + return + } + + // create sentry release + console.log(`creating Sentry release for "${VERSION}"...`) + await exec(`sentry-cli releases --org 'metamask' --project 'metamask' new ${VERSION}`) + console.log(`removing any existing files from Sentry release "${VERSION}"...`) + await exec(`sentry-cli releases --org 'metamask' --project 'metamask' files ${VERSION} delete --all`) + // upload sentry source and sourcemaps + console.log(`uploading source files Sentry release "${VERSION}"...`) + await exec(`for FILEPATH in ./dist/chrome/*.js; do [ -e $FILEPATH ] || continue; export FILE=\`basename $FILEPATH\` && echo uploading $FILE && sentry-cli releases --org 'metamask' --project 'metamask' files ${VERSION} upload $FILEPATH metamask/$FILE; done;`) + console.log(`uploading sourcemaps Sentry release "${VERSION}"...`) + await exec(`sentry-cli releases --org 'metamask' --project 'metamask' files ${VERSION} upload-sourcemaps ./dist/sourcemaps/ --url-prefix 'sourcemaps'`) + console.log('all done!') +} + +async function checkIfAuthWorks() { + const itWorked = await doesNotFail(async () => { + await exec(`sentry-cli releases --org 'metamask' --project 'metamask' list`) + }) + return itWorked +} + +async function checkIfVersionExists() { + const versionAlreadyExists = await doesNotFail(async () => { + await exec(`sentry-cli releases --org 'metamask' --project 'metamask' info ${VERSION}`) + }) + return versionAlreadyExists +} + +async function doesNotFail(asyncFn) { + try { + await asyncFn() + return true + } catch (err) { + return false + } +} diff --git a/development/states/add-token.json b/development/states/add-token.json index e78393b7f..9c0f16372 100644 --- a/development/states/add-token.json +++ b/development/states/add-token.json @@ -106,7 +106,8 @@ "errors": {}, "maxModeOn": false, "editingTransactionId": null - } + }, + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/confirm-new-ui.json b/development/states/confirm-new-ui.json index 6981781a9..ae3098ecb 100644 --- a/development/states/confirm-new-ui.json +++ b/development/states/confirm-new-ui.json @@ -128,7 +128,8 @@ "errors": {}, "maxModeOn": false, "editingTransactionId": null - } + }, + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/confirm-sig-requests.json b/development/states/confirm-sig-requests.json index 0a691e948..b51003d11 100644 --- a/development/states/confirm-sig-requests.json +++ b/development/states/confirm-sig-requests.json @@ -149,7 +149,8 @@ "errors": {}, "maxModeOn": false, "editingTransactionId": null - } + }, + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/first-time.json b/development/states/first-time.json index 4f5352992..fe9188b80 100644 --- a/development/states/first-time.json +++ b/development/states/first-time.json @@ -36,7 +36,8 @@ }, "shapeShiftTxList": [], "lostAccounts": [], - "tokens": [] + "tokens": [], + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/send-edit.json b/development/states/send-edit.json index 6981781a9..ae3098ecb 100644 --- a/development/states/send-edit.json +++ b/development/states/send-edit.json @@ -128,7 +128,8 @@ "errors": {}, "maxModeOn": false, "editingTransactionId": null - } + }, + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json index a0a2c66e4..1297a9139 100644 --- a/development/states/send-new-ui.json +++ b/development/states/send-new-ui.json @@ -107,7 +107,8 @@ "errors": {}, "maxModeOn": false, "editingTransactionId": null - } + }, + "currentLocale": "en" }, "appState": { "menuOpen": false, diff --git a/development/states/tx-list-items.js b/development/states/tx-list-items.js new file mode 100644 index 000000000..d567e3fed --- /dev/null +++ b/development/states/tx-list-items.js @@ -0,0 +1,128 @@ +{ + "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" + } + }, + "currentCurrency": "USD", + "conversionRate": 1200.88200327, + "conversionDate": 1489013762, + "noActiveNotices": true, + "frequentRpcList": [], + "network": "1", + "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": [ + {"err":{"message":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low","stack":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:72360:28\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103521:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27180:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27024:25)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106691:25\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103501:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27033:9\n at eachLimit (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26723:36)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26937:16\n at end (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103498:5)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106913:40"},"estimatedGas":"0xcf08","gasLimitSpecified":true,"gasPriceSpecified":true,"history":[{"id":4068311466147836,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522378334455,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0xcf08","gasPrice":"0x77359400","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[{"note":"confTx: user approved transaction","op":"replace","path":"/txParams/gas","value":"0x0"}],[{"note":"txStateManager: setting status to approved","op":"replace","path":"/status","value":"approved"}],[{"note":"transactions#approveTransaction","op":"add","path":"/txParams/nonce","value":"0x3"},{"op":"add","path":"/nonceDetails","value":{"local":{"details":{"highest":3,"startPoint":3},"name":"local","nonce":3},"network":{"details":{"baseCount":3},"name":"network","nonce":3},"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3}}}],[{"note":"txStateManager: setting status to signed","op":"add","path":"/txParams/chainId","value":"0x3"},{"op":"replace","path":"/status","value":"signed"}],[{"note":"transactions#publishTransaction","op":"add","path":"/rawTx","value":"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f"}],[{"op":"add","path":"/err","value":{"message":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low","stack":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:72360:28\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103521:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27180:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27024:25)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106691:25\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103501:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27033:9\n at eachLimit (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26723:36)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26937:16\n at end (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103498:5)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106913:40"}}]],"id":4068311466147836,"loadingDefaults":false,"metamaskNetworkId":"1","nonceDetails":{"local":{"details":{"highest":3,"startPoint":3},"name":"local","nonce":3},"network":{"details":{"baseCount":3},"name":"network","nonce":3},"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3}},"rawTx":"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f","status":"failed","time":1522378334455,"txParams":{"chainId":"0x3","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0x0","gasPrice":"0x77359400","nonce":"0x3","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0"}}, + {"id":2315363930841933,"time":1522378572149,"status":"approved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0x0","gasPrice":"0x5f5e100"},"history":[{"id":2315363930841933,"time":1522378572149,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[{"op":"replace","path":"/txParams/gas","value":"0x0","note":"confTx: user approved transaction"}],[{"op":"replace","path":"/status","value":"approved","note":"txStateManager: setting status to approved"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"}, + {"estimatedGas":"8d41","firstRetryBlockNumber":"0x2cbc70","gasLimitSpecified":false,"gasPriceSpecified":false,"hash":"0xfbd997bf9bb85ca1598952ca23e7910502d527e06cb6ee1bbe7e7dd59d6909cd","history":[{"id":2079438776801906,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522346270251,"txParams":{"data":"0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb"}},[{"op":"add","path":"/txParams/gasPrice","value":"0x37e11d600"},{"op":"add","path":"/txParams/value","value":"0x0"},{"op":"add","path":"/txParams/gas","value":"0xd3e1"},{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":false},{"op":"add","path":"/gasLimitSpecified","value":false},{"op":"add","path":"/estimatedGas","value":"8d41"}],[{"note":"confTx: user approved transaction","op":"replace","path":"/txParams/gasPrice","value":"0x5f5e100"}],[{"note":"txStateManager: setting status to approved","op":"replace","path":"/status","value":"approved"}],[{"note":"transactions#approveTransaction","op":"add","path":"/txParams/nonce","value":"0x2"},{"op":"add","path":"/nonceDetails","value":{"local":{"details":{"highest":2,"startPoint":2},"name":"local","nonce":2},"network":{"details":{"baseCount":2},"name":"network","nonce":2},"params":{"highestLocalNonce":2,"highestSuggested":2,"nextNetworkNonce":2}}}],[{"note":"txStateManager: setting status to signed","op":"add","path":"/txParams/chainId","value":"0x3"},{"op":"replace","path":"/status","value":"signed"}],[{"note":"transactions#publishTransaction","op":"add","path":"/rawTx","value":"0xf8a8028405f5e10082d3e19466f30b996a7d345cd00badcfe75e81e25dc5e1eb80b844a9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b2aa05cb38a3a68e49008da2e93839f6dedeb96b1630c2a73c4cf5eb3fcc74299a100a039f17c0807469bd101165fa0749dc7065832b4a7c3a382b6cf7e29228c2a683d"}],[{"note":"transactions#setTxHash","op":"add","path":"/hash","value":"0xfbd997bf9bb85ca1598952ca23e7910502d527e06cb6ee1bbe7e7dd59d6909cd"}],[{"note":"txStateManager - add submitted time stamp","op":"add","path":"/submittedTime","value":1522346282571}],[{"note":"txStateManager: setting status to submitted","op":"replace","path":"/status","value":"submitted"}],[{"note":"transactions/pending-tx-tracker#event: tx:block-update","op":"add","path":"/firstRetryBlockNumber","value":"0x2cbc70"}],[{"note":"txStateManager: setting status to confirmed","op":"replace","path":"/status","value":"confirmed"}]],"id":2079438776801906,"loadingDefaults":false,"metamaskNetworkId":"1","nonceDetails":{"local":{"details":{"highest":2,"startPoint":2},"name":"local","nonce":2},"network":{"details":{"baseCount":2},"name":"network","nonce":2},"params":{"highestLocalNonce":2,"highestSuggested":2,"nextNetworkNonce":2}},"rawTx":"0xf8a8028405f5e10082d3e19466f30b996a7d345cd00badcfe75e81e25dc5e1eb80b844a9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b2aa05cb38a3a68e49008da2e93839f6dedeb96b1630c2a73c4cf5eb3fcc74299a100a039f17c0807469bd101165fa0749dc7065832b4a7c3a382b6cf7e29228c2a683d","status":"confirmed","submittedTime":1522346282571,"time":1522346270251,"txParams":{"chainId":"0x3","data":"0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0xd3e1","gasPrice":"0x5f5e100","nonce":"0x2","to":"0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb","value":"0x0"}}, + {"id":4087002078467524,"time":1522379587999,"status":"submitted","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100","nonce":"0x3","chainId":"0x3"},"history":[{"id":4087002078467524,"time":1522379587999,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[],[{"op":"replace","path":"/status","value":"approved","note":"txStateManager: setting status to approved"}],[{"op":"add","path":"/txParams/nonce","value":"0x3","note":"transactions#approveTransaction"},{"op":"add","path":"/nonceDetails","value":{"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3},"local":{"name":"local","nonce":3,"details":{"startPoint":3,"highest":3}},"network":{"name":"network","nonce":3,"details":{"baseCount":3}}}}],[{"op":"add","path":"/txParams/chainId","value":"0x3","note":"txStateManager: setting status to signed"},{"op":"replace","path":"/status","value":"signed"}],[{"op":"add","path":"/rawTx","value":"0xf863038405f5e10082cf0894f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a0d64ed427733ef67fe788fe85d3cfe51c43cfc83d07fa4ab8af5d3bc8c8199895a02699c131cc0ffcf842b54776ac611bdd165fdb87dd3ecff1554ec8da1bf3ff39","note":"transactions#publishTransaction"}],[{"op":"add","path":"/hash","value":"0x52f0929fc143d76f4e6255d95cebfc76b74f43726191bd4081a5ae9bd6c1fa4a","note":"transactions#setTxHash"}],[{"op":"add","path":"/submittedTime","value":1522379590158,"note":"txStateManager - add submitted time stamp"}],[{"op":"replace","path":"/status","value":"submitted","note":"txStateManager: setting status to submitted"}],[{"op":"add","path":"/firstRetryBlockNumber","value":"0x2cc718","note":"transactions/pending-tx-tracker#event: tx:block-update"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08","nonceDetails":{"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3},"local":{"name":"local","nonce":3,"details":{"startPoint":3,"highest":3}},"network":{"name":"network","nonce":3,"details":{"baseCount":3}}},"rawTx":"0xf863038405f5e10082cf0894f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a0d64ed427733ef67fe788fe85d3cfe51c43cfc83d07fa4ab8af5d3bc8c8199895a02699c131cc0ffcf842b54776ac611bdd165fdb87dd3ecff1554ec8da1bf3ff39","hash":"0x52f0929fc143d76f4e6255d95cebfc76b74f43726191bd4081a5ae9bd6c1fa4a","submittedTime":1522379590158,"firstRetryBlockNumber":"0x2cc718"}, + {"estimatedGas":"0x5208","gasLimitSpecified":false,"gasPriceSpecified":false,"history":[{"id":6301441591225658,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522346051227,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0x81b7e08f65bdf5648606c89998a9cc8164397647","value":"0xde0b6b3a7640000"}},[{"op":"add","path":"/txParams/gasPrice","value":"0x4a817c800"},{"op":"add","path":"/txParams/gas","value":"0x5208"},{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":false},{"op":"add","path":"/gasLimitSpecified","value":false},{"op":"add","path":"/simpleSend","value":true},{"op":"add","path":"/estimatedGas","value":"0x5208"}],[{"note":"txStateManager: setting status to rejected","op":"replace","path":"/status","value":"rejected"}]],"id":6301441591225658,"loadingDefaults":false,"metamaskNetworkId":"1","simpleSend":true,"status":"rejected","time":1522346051227,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0x5208","gasPrice":"0x4a817c800","to":"0x81b7e08f65bdf5648606c89998a9cc8164397647","value":"0xde0b6b3a7640000"}}, + {"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"},"history":[{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"} + ], + "unapprovedTxs": {"2699829174766090":{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"},"history":[{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"}}, + "unapprovedMsgs": {"2315363930841932":{"id":2315363930841932,"msgParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","data":"0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0"},"time":1522378539686,"status":"unapproved","type":"eth_sign"}}, + "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": [ + "0xd85a4b6a394794842887b8284293d69163007bbb" + ] + } + ], + "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb", + "provider": { + "type": "testnet" + }, + "shapeShiftTxList": [{"depositAddress":"34vJ3AfmNcLiziA4VFgEVcQTwxVLD1qkke","depositType":"BTC","key":"shapeshift","response":{"status":"no_deposits","address":"34vJ3AfmNcLiziA4VFgEVcQTwxVLD1qkke"},"time":1522377459106}], + "lostAccounts": [], + "send": {}, + "currentLocale": "en" + }, + "appState": { + "menuOpen": false, + "currentView": { + "name": "confTx", + "detailView": null, + "context": 0 + }, + "accountDetail": { + "subview": "transactions" + }, + "modal": { + "modalState": {}, + "previousModalState": {} + }, + "transForward": true, + "isLoading": false, + "warning": null, + "scrollToBottom": false, + "forgottenPassword": null + }, + "identities": {} +} diff --git a/development/verify-locale-strings.js b/development/verify-locale-strings.js index b8fe5a7dc..8dc0a30f1 100644 --- a/development/verify-locale-strings.js +++ b/development/verify-locale-strings.js @@ -10,87 +10,88 @@ // //////////////////////////////////////////////////////////////////////////////// -var fs = require('fs') -var path = require('path') +const fs = require('fs') +const path = require('path') +const localeIndex = require('../app/_locales/index.json') console.log('Locale Verification') -var locale = process.argv[2] -if (!locale || locale == '') { - console.log('Must enter a locale as argument. exitting') - process.exit(1) -} - -console.log("verifying for locale " + locale) - -localeFilePath = path.join(process.cwd(), 'app', '_locales', locale, 'messages.json') -try { - localeObj = JSON.parse(fs.readFileSync(localeFilePath, 'utf8')); -} catch (e) { - if(e.code == 'ENOENT') { - console.log('Locale file not found') - } else { - console.log('Error opening your locale file: ', e) - } - process.exit(1) -} - -englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json') -try { - englishObj = JSON.parse(fs.readFileSync(englishFilePath, 'utf8')); -} catch (e) { - if(e.code == 'ENOENT') { - console.log("English File not found") - } else { - console.log("Error opening english locale file: ", e) - } - process.exit(1) -} - -console.log('\tverifying whether all your locale strings are contained in the english one') - -var counter = 0 -var foundErrorA = false -var notFound = []; -Object.keys(localeObj).forEach(function(key){ - if (!englishObj[key]) { - foundErrorA = true - notFound.push(key) - } - counter++ -}) - -if (foundErrorA) { - console.log('\nThe following string(s) is(are) not found in the english locale:') - notFound.forEach(function(key) { - console.log(key) - }) +const specifiedLocale = process.argv[2] +if (specifiedLocale) { + console.log(`Verifying selected locale "${specifiedLocale}":\n\n`) + const locale = localeIndex.find(localeMeta => localeMeta.code === specifiedLocale) + verifyLocale({ localeMeta }) } else { - console.log('\tall ' + counter +' strings declared in your locale were found in the english one') -} - -console.log('\n\tverifying whether your locale contains all english strings') - -var counter = 0 -var foundErrorB = false -var notFound = []; -Object.keys(englishObj).forEach(function(key){ - if (!localeObj[key]) { - foundErrorB = true - notFound.push(key) - } - counter++ -}) - -if (foundErrorB) { - console.log('\nThe following string(s) is(are) not found in the your locale:') - notFound.forEach(function(key) { - console.log(key) + console.log('Verifying all locales:\n\n') + localeIndex.forEach(localeMeta => { + verifyLocale({ localeMeta }) + console.log('\n') }) -} else { - console.log('\tall ' + counter +' english strings were found in your locale!') } -if (!foundErrorA && !foundErrorB) { - console.log('You are good to go') -} \ No newline at end of file + + +function verifyLocale({ localeMeta }) { + const localeCode = localeMeta.code + const localeName = localeMeta.name + + try { + const localeFilePath = path.join(process.cwd(), 'app', '_locales', localeCode, 'messages.json') + targetLocale = JSON.parse(fs.readFileSync(localeFilePath, 'utf8')); + } catch (e) { + if (e.code == 'ENOENT') { + console.log('Locale file not found') + } else { + console.log(`Error opening your locale ("${localeCode}") file: `, e) + } + process.exit(1) + } + + try { + const englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json') + englishLocale = JSON.parse(fs.readFileSync(englishFilePath, 'utf8')); + } catch (e) { + if(e.code == 'ENOENT') { + console.log('English File not found') + } else { + console.log('Error opening english locale file: ', e) + } + process.exit(1) + } + + // console.log(' verifying whether all your locale ("${localeCode}") strings are contained in the english one') + const extraItems = compareLocalesForMissingItems({ base: targetLocale, subject: englishLocale }) + // console.log('\n verifying whether your locale ("${localeCode}") contains all english strings') + const missingItems = compareLocalesForMissingItems({ base: englishLocale, subject: targetLocale }) + + const englishEntryCount = Object.keys(englishLocale).length + const coveragePercent = 100 * (englishEntryCount - missingItems.length) / englishEntryCount + + console.log(`Status of **${localeName} (${localeCode})** ${coveragePercent.toFixed(2)}% coverage:`) + + if (extraItems.length) { + console.log('\nMissing from english locale:') + extraItems.forEach(function(key) { + console.log(` - [ ] ${key}`) + }) + } else { + // console.log(` all ${counter} strings declared in your locale ("${localeCode}") were found in the english one`) + } + + if (missingItems.length) { + console.log(`\nMissing:`) + missingItems.forEach(function(key) { + console.log(` - [ ] ${key}`) + }) + } else { + // console.log(` all ${counter} english strings were found in your locale ("${localeCode}")!`) + } + + if (!extraItems.length && !missingItems.length) { + console.log('Full coverage : )') + } +} + +function compareLocalesForMissingItems({ base, subject }) { + return Object.keys(base).filter((key) => !subject[key]) +} 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/translating-guide.md b/docs/translating-guide.md index ae2dfecd3..8b2bc1785 100644 --- a/docs/translating-guide.md +++ b/docs/translating-guide.md @@ -6,9 +6,12 @@ The MetaMask browser extension supports new translations added in the form of ne ## Adding a new Language -Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag ([look up a language subtag using this tool](https://r12a.github.io/app-subtags/)). +- Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag (example: `app/_locales/es/`). (look up a language subtag using the [r12a "Find" tool](https://r12a.github.io/app-subtags/) or this [wikipedia list](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)). +- Inside that folder there should be a `messages.json`. +- An easy way to start your translation is to first **make a copy** of `app/_locales/en/messages.json` (the english translation), and then **translate the `message` key** for each in-app message. +- **The `description` key** is just to add context for what the translation is about, it **does not need to be translated**. +- Add the language to the [locales index](https://github.com/MetaMask/metamask-extension/blob/master/app/_locales/index.json) `app/_locales/index.json` -Inside that folder there should be a `messages.json` file that follows the specified format. An easy way to start your translation is to first duplicate `app/_locales/en/messages.json` (the english translation), and then update the `message` key for each in-app message. That's it! When MetaMask is loaded on a computer with that language set as the system language, they will see your translation instead of the default one. @@ -20,7 +23,7 @@ To automatically see if you are missing any phrases to translate, we have a scri node development/verify-locale-strings.js $YOUR_LOCALE ``` -Where `$YOUR_LOCALE` is your [locale string](https://r12a.github.io/app-subtags/), i.e. the name of your language folder. +Where `$YOUR_LOCALE` is your locale string (example: `es`), i.e. the name of your language folder. To verify that your translation works in the app, you will need to [build a local copy](https://github.com/MetaMask/metamask-extension#building-locally) of MetaMask. You will need to change your browser language, your operating system language, and restart your browser (sorry it's so much work!). diff --git a/gulpfile.js b/gulpfile.js index f57ea6206..4f0da9d60 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,37 +1,55 @@ -var watchify = require('watchify') -var browserify = require('browserify') -var disc = require('disc') -var gulp = require('gulp') -var source = require('vinyl-source-stream') -var buffer = require('vinyl-buffer') -var gutil = require('gulp-util') -var watch = require('gulp-watch') -var sourcemaps = require('gulp-sourcemaps') -var jsoneditor = require('gulp-json-editor') -var zip = require('gulp-zip') -var assign = require('lodash.assign') -var livereload = require('gulp-livereload') -var del = require('del') -var eslint = require('gulp-eslint') -var fs = require('fs') -var path = require('path') -var manifest = require('./app/manifest.json') -var gulpif = require('gulp-if') -var replace = require('gulp-replace') -var mkdirp = require('mkdirp') -var asyncEach = require('async/each') -var exec = require('child_process').exec -var sass = require('gulp-sass') -var autoprefixer = require('gulp-autoprefixer') -var gulpStylelint = require('gulp-stylelint') -var stylefmt = require('gulp-stylefmt') -var uglify = require('gulp-uglify-es').default -var babel = require('gulp-babel') +const watchify = require('watchify') +const browserify = require('browserify') +const envify = require('envify/custom') +const disc = require('disc') +const gulp = require('gulp') +const source = require('vinyl-source-stream') +const buffer = require('vinyl-buffer') +const gutil = require('gulp-util') +const watch = require('gulp-watch') +const sourcemaps = require('gulp-sourcemaps') +const jsoneditor = require('gulp-json-editor') +const zip = require('gulp-zip') +const assign = require('lodash.assign') +const livereload = require('gulp-livereload') +const del = require('del') +const eslint = require('gulp-eslint') +const fs = require('fs') +const path = require('path') +const manifest = require('./app/manifest.json') +const replace = require('gulp-replace') +const mkdirp = require('mkdirp') +const asyncEach = require('async/each') +const exec = require('child_process').exec +const sass = require('gulp-sass') +const autoprefixer = require('gulp-autoprefixer') +const gulpStylelint = require('gulp-stylelint') +const stylefmt = require('gulp-stylefmt') +const uglify = require('gulp-uglify-es').default +const babel = require('gulp-babel') +const debug = require('gulp-debug') +const pify = require('pify') +const gulpMultiProcess = require('gulp-multi-process') +const endOfStream = pify(require('end-of-stream')) +function gulpParallel (...args) { + return function spawnGulpChildProcess(cb) { + return gulpMultiProcess(args, cb, true) + } +} -var disableDebugTools = gutil.env.disableDebugTools -var debug = gutil.env.debug - +const browserPlatforms = [ + 'firefox', + 'chrome', + 'edge', + 'opera', +] +const commonPlatforms = [ + // browser webapp + 'mascara', + // browser extensions + ...browserPlatforms +] // browser reload @@ -41,65 +59,98 @@ gulp.task('dev:reload', function() { }) }) +// copy universal -// copy static +const copyTaskNames = [] +const copyDevTaskNames = [] -gulp.task('copy:locales', copyTask({ +createCopyTasks('locales', { source: './app/_locales/', - destinations: [ - './dist/firefox/_locales', - './dist/chrome/_locales', - './dist/edge/_locales', - './dist/opera/_locales', - ] -})) -gulp.task('copy:images', copyTask({ + destinations: commonPlatforms.map(platform => `./dist/${platform}/_locales`), +}) +createCopyTasks('images', { source: './app/images/', - destinations: [ - './dist/firefox/images', - './dist/chrome/images', - './dist/edge/images', - './dist/opera/images', - ], -})) -gulp.task('copy:contractImages', copyTask({ + destinations: commonPlatforms.map(platform => `./dist/${platform}/images`), +}) +createCopyTasks('contractImages', { source: './node_modules/eth-contract-metadata/images/', - destinations: [ - './dist/firefox/images/contract', - './dist/chrome/images/contract', - './dist/edge/images/contract', - './dist/opera/images/contract', - ], -})) -gulp.task('copy:fonts', copyTask({ + destinations: commonPlatforms.map(platform => `./dist/${platform}/images/contract`), +}) +createCopyTasks('fonts', { source: './app/fonts/', - destinations: [ - './dist/firefox/fonts', - './dist/chrome/fonts', - './dist/edge/fonts', - './dist/opera/fonts', - ], -})) -gulp.task('copy:reload', copyTask({ + destinations: commonPlatforms.map(platform => `./dist/${platform}/fonts`), +}) +createCopyTasks('reload', { + devOnly: true, source: './app/scripts/', - destinations: [ - './dist/firefox/scripts', - './dist/chrome/scripts', - './dist/edge/scripts', - './dist/opera/scripts', - ], pattern: '/chromereload.js', -})) -gulp.task('copy:root', copyTask({ + destinations: commonPlatforms.map(platform => `./dist/${platform}`), +}) +createCopyTasks('html', { source: './app/', - destinations: [ - './dist/firefox', - './dist/chrome', - './dist/edge', - './dist/opera', - ], - pattern: '/*', -})) + pattern: '/*.html', + destinations: commonPlatforms.map(platform => `./dist/${platform}`), +}) + +// copy extension + +createCopyTasks('manifest', { + source: './app/', + pattern: '/*.json', + destinations: browserPlatforms.map(platform => `./dist/${platform}`), +}) + +// copy mascara + +createCopyTasks('html:mascara', { + source: './mascara/', + pattern: 'proxy/index.html', + destinations: [`./dist/mascara/`], +}) + +function createCopyTasks(label, opts) { + if (!opts.devOnly) { + const copyTaskName = `copy:${label}` + copyTask(copyTaskName, opts) + copyTaskNames.push(copyTaskName) + } + const copyDevTaskName = `dev:copy:${label}` + copyTask(copyDevTaskName, Object.assign({ devMode: true }, opts)) + copyDevTaskNames.push(copyDevTaskName) +} + +function copyTask(taskName, opts){ + const source = opts.source + const destination = opts.destination + const destinations = opts.destinations || [destination] + const pattern = opts.pattern || '/**/*' + const devMode = opts.devMode + + return gulp.task(taskName, function () { + if (devMode) { + watch(source + pattern, (event) => { + livereload.changed(event.path) + performCopy() + }) + } + + return performCopy() + }) + + function performCopy() { + // stream from source + let stream = gulp.src(source + pattern, { base: source }) + + // copy to destinations + destinations.forEach(function(destination) { + stream = stream.pipe(gulp.dest(destination)) + }) + + return stream + } +} + +// manifest tinkering gulp.task('manifest:chrome', function() { return gulp.src('./dist/chrome/manifest.json') @@ -134,52 +185,40 @@ gulp.task('manifest:production', function() { ],{base: './dist/'}) // Exclude chromereload script in production: - .pipe(gulpif(!debug,jsoneditor(function(json) { + .pipe(jsoneditor(function(json) { json.background.scripts = json.background.scripts.filter((script) => { return !script.includes('chromereload') }) return json - }))) + })) .pipe(gulp.dest('./dist/', { overwrite: true })) }) -const staticFiles = [ - 'locales', - 'images', - 'fonts', - 'root' -] +gulp.task('copy', + gulp.series( + gulp.parallel(...copyTaskNames), + 'manifest:production', + 'manifest:chrome', + 'manifest:opera' + ) +) -var copyStrings = staticFiles.map(staticFile => `copy:${staticFile}`) -copyStrings.push('copy:contractImages') - -if (debug) { - copyStrings.push('copy:reload') -} - -gulp.task('copy', gulp.series(gulp.parallel(...copyStrings), 'manifest:production', 'manifest:chrome', 'manifest:opera')) -gulp.task('copy:watch', function(){ - gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy')) -}) - -// record deps - -gulp.task('deps', function (cb) { - exec('npm ls', (err, stdoutOutput, stderrOutput) => { - if (err) return cb(err) - const browsers = ['firefox','chrome','edge','opera'] - asyncEach(browsers, (target, done) => { - fs.writeFile(`./dist/${target}/deps.txt`, stdoutOutput, done) - }, cb) - }) -}) +gulp.task('dev:copy', + gulp.series( + gulp.parallel(...copyDevTaskNames), + 'manifest:chrome', + 'manifest:opera' + ) +) // lint js +const lintTargets = ['app/**/*.json', 'app/**/*.js', '!app/scripts/vendor/**/*.js', 'ui/**/*.js', 'old-ui/**/*.js', 'mascara/src/*.js', 'mascara/server/*.js', '!node_modules/**', '!dist/firefox/**', '!docs/**', '!app/scripts/chromereload.js', '!mascara/test/jquery-3.1.0.min.js'] + gulp.task('lint', function () { // Ignoring node_modules, dist/firefox, and docs folders: - return gulp.src(['app/**/*.js', '!app/scripts/vendor/**/*.js', 'ui/**/*.js', 'mascara/src/*.js', 'mascara/server/*.js', '!node_modules/**', '!dist/firefox/**', '!docs/**', '!app/scripts/chromereload.js', '!mascara/test/jquery-3.1.0.min.js']) + return gulp.src(lintTargets) .pipe(eslint(fs.readFileSync(path.join(__dirname, '.eslintrc')))) // eslint.format() outputs the lint results to the console. // Alternatively use eslint.formatEach() (see Docs). @@ -190,47 +229,55 @@ gulp.task('lint', function () { }); gulp.task('lint:fix', function () { - return gulp.src(['app/**/*.js', 'ui/**/*.js', 'mascara/src/*.js', 'mascara/server/*.js', '!node_modules/**', '!dist/firefox/**', '!docs/**', '!app/scripts/chromereload.js', '!mascara/test/jquery-3.1.0.min.js']) + return gulp.src(lintTargets) .pipe(eslint(Object.assign(fs.readFileSync(path.join(__dirname, '.eslintrc')), {fix: true}))) .pipe(eslint.format()) .pipe(eslint.failAfterError()) }); -/* -gulp.task('default', ['lint'], function () { - // This will only run if the lint task is successful... -}); -*/ - -// build js - -const jsFiles = [ - 'inpage', - 'contentscript', - 'background', - 'popup', -] - // scss compilation and autoprefixing tasks -gulp.task('build:scss', function () { - return gulp.src('ui/app/css/index.scss') - .pipe(sourcemaps.init()) - .pipe(sass().on('error', sass.logError)) - .pipe(sourcemaps.write()) - .pipe(autoprefixer()) - .pipe(gulp.dest('ui/app/css/output')) -}) -gulp.task('watch:scss', function() { - gulp.watch(['ui/app/css/**/*.scss'], gulp.series(['build:scss'])) -}) +gulp.task('build:scss', createScssBuildTask({ + src: 'ui/app/css/index.scss', + dest: 'ui/app/css/output', + devMode: false, +})) + +gulp.task('dev:scss', createScssBuildTask({ + src: 'ui/app/css/index.scss', + dest: 'ui/app/css/output', + devMode: true, + pattern: 'ui/app/css/**/*.scss', +})) + +function createScssBuildTask({ src, dest, devMode, pattern }) { + return function () { + if (devMode) { + watch(pattern, async (event) => { + const stream = buildScss() + await endOfStream(stream) + livereload.changed(event.path) + }) + } + return buildScss() + } + + function buildScss() { + return gulp.src(src) + .pipe(sourcemaps.init()) + .pipe(sass().on('error', sass.logError)) + .pipe(sourcemaps.write()) + .pipe(autoprefixer()) + .pipe(gulp.dest(dest)) + } +} gulp.task('lint-scss', function() { return gulp .src('ui/app/css/itcss/**/*.scss') .pipe(gulpStylelint({ reporters: [ - {formatter: 'string', console: true} + { formatter: 'string', console: true } ], fix: true, })); @@ -242,46 +289,84 @@ gulp.task('fmt-scss', function () { .pipe(gulp.dest('ui/app/css/itcss')); }); +// build js + +const buildJsFiles = [ + 'inpage', + 'contentscript', + 'background', + 'ui', +] + // bundle tasks +createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'dev:extension:js', devMode: true }) +createTasksForBuildJsExtension({ buildJsFiles, taskPrefix: 'build:extension:js' }) +createTasksForBuildJsMascara({ taskPrefix: 'build:mascara:js' }) +createTasksForBuildJsMascara({ taskPrefix: 'dev:mascara:js', devMode: true }) -var jsDevStrings = jsFiles.map(jsFile => `dev:js:${jsFile}`) -var jsBuildStrings = jsFiles.map(jsFile => `build:js:${jsFile}`) +function createTasksForBuildJsExtension({ buildJsFiles, taskPrefix, devMode, bundleTaskOpts = {} }) { + // inpage must be built before all other scripts: + const rootDir = './app/scripts' + const nonInpageFiles = buildJsFiles.filter(file => file !== 'inpage') + const buildPhase1 = ['inpage'] + const buildPhase2 = nonInpageFiles + const destinations = browserPlatforms.map(platform => `./dist/${platform}`) + bundleTaskOpts = Object.assign({ + buildSourceMaps: true, + sourceMapDir: devMode ? './' : '../sourcemaps', + minifyBuild: !devMode, + buildWithFullPaths: devMode, + watch: devMode, + devMode, + }, bundleTaskOpts) + createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1, buildPhase2 }) +} -jsFiles.forEach((jsFile) => { - gulp.task(`dev:js:${jsFile}`, bundleTask({ - watch: true, - label: jsFile, - filename: `${jsFile}.js`, - isBuild: false - })) - gulp.task(`build:js:${jsFile}`, bundleTask({ - watch: false, - label: jsFile, - filename: `${jsFile}.js`, - isBuild: true - })) -}) +function createTasksForBuildJsMascara({ taskPrefix, devMode, bundleTaskOpts = {} }) { + // inpage must be built before all other scripts: + const rootDir = './mascara/src/' + const buildPhase1 = ['ui', 'proxy', 'background', 'metamascara'] + const destinations = ['./dist/mascara'] + bundleTaskOpts = Object.assign({ + buildSourceMaps: true, + sourceMapDir: './', + minifyBuild: !devMode, + buildWithFullPaths: devMode, + watch: devMode, + devMode, + }, bundleTaskOpts) + createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1 }) +} -// inpage must be built before all other scripts: -const firstDevString = jsDevStrings.shift() -gulp.task('dev:js', gulp.series(firstDevString, gulp.parallel(...jsDevStrings))) +function createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1 = [], buildPhase2 = [] }) { + // bundle task for each file + const jsFiles = [].concat(buildPhase1, buildPhase2) + jsFiles.forEach((jsFile) => { + gulp.task(`${taskPrefix}:${jsFile}`, bundleTask(Object.assign({ + label: jsFile, + filename: `${jsFile}.js`, + filepath: `${rootDir}/${jsFile}.js`, + destinations, + }, bundleTaskOpts))) + }) + // compose into larger task + const subtasks = [] + subtasks.push(gulp.parallel(buildPhase1.map(file => `${taskPrefix}:${file}`))) + if (buildPhase2.length) subtasks.push(gulp.parallel(buildPhase2.map(file => `${taskPrefix}:${file}`))) -// inpage must be built before all other scripts: -const firstBuildString = jsBuildStrings.shift() -gulp.task('build:js', gulp.series(firstBuildString, gulp.parallel(...jsBuildStrings))) + gulp.task(taskPrefix, gulp.series(subtasks)) +} // disc bundle analyzer tasks -jsFiles.forEach((jsFile) => { - gulp.task(`disc:${jsFile}`, discTask({ label: jsFile, filename: `${jsFile}.js` })) +buildJsFiles.forEach((jsFile) => { + gulp.task(`disc:${jsFile}`, discTask({ label: jsFile, filename: `${jsFile}.js` })) }) -gulp.task('disc', gulp.parallel(jsFiles.map(jsFile => `disc:${jsFile}`))) - +gulp.task('disc', gulp.parallel(buildJsFiles.map(jsFile => `disc:${jsFile}`))) // clean dist - gulp.task('clean', function clean() { return del(['./dist/*']) }) @@ -293,40 +378,88 @@ gulp.task('zip:edge', zipTask('edge')) gulp.task('zip:opera', zipTask('opera')) gulp.task('zip', gulp.parallel('zip:chrome', 'zip:firefox', 'zip:edge', 'zip:opera')) -// set env var for production -gulp.task('apply-prod-environment', function(done) { - process.env.NODE_ENV = 'production' - done() -}); - // high level tasks -gulp.task('dev', gulp.series('build:scss', 'dev:js', 'copy', gulp.parallel('watch:scss', 'copy:watch', 'dev:reload'))) +gulp.task('dev', + gulp.series( + 'clean', + 'dev:scss', + gulp.parallel( + 'dev:extension:js', + 'dev:mascara:js', + 'dev:copy', + 'dev:reload' + ) + ) +) -gulp.task('build', gulp.series('clean', 'build:scss', gulp.parallel('build:js', 'copy'))) -gulp.task('dist', gulp.series('apply-prod-environment', 'build', 'zip')) +gulp.task('dev:extension', + gulp.series( + 'clean', + 'dev:scss', + gulp.parallel( + 'dev:extension:js', + 'dev:copy', + 'dev:reload' + ) + ) +) + +gulp.task('dev:mascara', + gulp.series( + 'clean', + 'dev:scss', + gulp.parallel( + 'dev:mascara:js', + 'dev:copy', + 'dev:reload' + ) + ) +) + +gulp.task('build', + gulp.series( + 'clean', + 'build:scss', + gulpParallel( + 'build:extension:js', + 'build:mascara:js', + 'copy' + ) + ) +) + +gulp.task('build:extension', + gulp.series( + 'clean', + 'build:scss', + gulp.parallel( + 'build:extension:js', + 'copy' + ) + ) +) + +gulp.task('build:mascara', + gulp.series( + 'clean', + 'build:scss', + gulp.parallel( + 'build:mascara:js', + 'copy' + ) + ) +) + +gulp.task('dist', + gulp.series( + 'build', + 'zip' + ) +) // task generators -function copyTask(opts){ - var source = opts.source - var destination = opts.destination - var destinations = opts.destinations || [ destination ] - var pattern = opts.pattern || '/**/*' - - return performCopy - - function performCopy(){ - let stream = gulp.src(source + pattern, { base: source }) - destinations.forEach(function(destination) { - stream = stream.pipe(gulp.dest(destination)) - }) - stream.pipe(gulpif(debug,livereload())) - - return stream - } -} - function zipTask(target) { return () => { return gulp.src(`dist/${target}/**`) @@ -337,24 +470,48 @@ function zipTask(target) { function generateBundler(opts, performBundle) { const browserifyOpts = assign({}, watchify.args, { - entries: ['./app/scripts/'+opts.filename], + entries: [opts.filepath], plugin: 'browserify-derequire', - debug: true, - fullPaths: debug, + debug: opts.buildSourceMaps, + fullPaths: opts.buildWithFullPaths, }) let bundler = browserify(browserifyOpts) + // inject variables into bundle + bundler.transform(envify({ + METAMASK_DEBUG: opts.devMode, + 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 - bundler.on('update', performBundle) + bundler.on('update', async (ids) => { + const stream = performBundle() + await endOfStream(stream) + livereload.changed(`${ids}`) + }) } return bundler } function discTask(opts) { + opts = Object.assign({ + buildWithFullPaths: true, + }, opts) + const bundler = generateBundler(opts, performBundle) // output build logs to terminal bundler.on('log', gutil.log) @@ -363,9 +520,9 @@ function discTask(opts) { function performBundle(){ // start "disc" build - let discDir = path.join(__dirname, 'disc') + const discDir = path.join(__dirname, 'disc') mkdirp.sync(discDir) - let discPath = path.join(discDir, `${opts.label}.html`) + const discPath = path.join(discDir, `${opts.label}.html`) return ( bundler.bundle() @@ -384,43 +541,45 @@ function bundleTask(opts) { return performBundle function performBundle(){ - return ( + let buildStream = bundler.bundle() - bundler.bundle() + // handle errors + buildStream.on('error', (err) => { + beep() + if (opts.watch) { + console.warn(err.stack) + } else { + throw err + } + }) - // handle errors - .on('error', (err) => { - beep() - if (opts.watch) { - console.warn(err.stack) - } else { - throw err - } - }) + // process bundles + buildStream = buildStream // convert bundle stream to gulp vinyl stream .pipe(source(opts.filename)) - // inject variables into bundle - .pipe(replace('\'GULP_METAMASK_DEBUG\'', debug)) // buffer file contents (?) .pipe(buffer()) - // sourcemaps - // loads map from browserify file - .pipe(sourcemaps.init({ loadMaps: true })) - // Minification - .pipe(gulpif(opts.isBuild, uglify({ - mangle: { reserved: [ 'MetamaskInpageProvider' ] }, - }))) - // writes .map file - .pipe(sourcemaps.write(debug ? './' : '../../sourcemaps')) - // write completed bundles - .pipe(gulp.dest('./dist/firefox/scripts')) - .pipe(gulp.dest('./dist/chrome/scripts')) - .pipe(gulp.dest('./dist/edge/scripts')) - .pipe(gulp.dest('./dist/opera/scripts')) - // finally, trigger live reload - .pipe(gulpif(debug, livereload())) - ) + // Initialize Source Maps + if (opts.buildSourceMaps) { + buildStream = buildStream + // loads map from browserify file + .pipe(sourcemaps.init({ loadMaps: true })) + } + + // Finalize Source Maps (writes .map file) + if (opts.buildSourceMaps) { + buildStream = buildStream + .pipe(sourcemaps.write(opts.sourceMapDir)) + } + + // write completed bundles + opts.destinations.forEach((dest) => { + buildStream = buildStream.pipe(gulp.dest(dest)) + }) + + return buildStream + } } diff --git a/mascara/proxy/index.html b/mascara/proxy/index.html index b83fc41af..4e167db72 100644 --- a/mascara/proxy/index.html +++ b/mascara/proxy/index.html @@ -17,4 +17,4 @@ Hello! I am the MetaMask iframe. - \ No newline at end of file + diff --git a/mascara/server/index.js b/mascara/server/index.js index 6fb1287cc..a30120438 100644 --- a/mascara/server/index.js +++ b/mascara/server/index.js @@ -1,7 +1,5 @@ const path = require('path') const express = require('express') -const createBundle = require('./util').createBundle -const serveBundle = require('./util').serveBundle const compression = require('compression') module.exports = createMetamascaraServer @@ -9,27 +7,14 @@ module.exports = createMetamascaraServer function createMetamascaraServer () { - // start bundlers - const metamascaraBundle = createBundle(path.join(__dirname, '/../src/mascara.js')) - const proxyBundle = createBundle(path.join(__dirname, '/../src/proxy.js')) - const uiBundle = createBundle(path.join(__dirname, '/../src/ui.js')) - const backgroundBuild = createBundle(path.join(__dirname, '/../src/background.js')) - - // serve bundles + // setup server const server = express() server.use(compression()) - // ui window - serveBundle(server, '/ui.js', uiBundle) + // serve assets server.use(express.static(path.join(__dirname, '/../ui/'), { setHeaders: (res) => res.set('X-Frame-Options', 'DENY') })) - server.use(express.static(path.join(__dirname, '/../../dist/chrome'))) - // metamascara - serveBundle(server, '/metamascara.js', metamascaraBundle) - // proxy - serveBundle(server, '/proxy/proxy.js', proxyBundle) - server.use('/proxy/', express.static(path.join(__dirname, '/../proxy'))) - // background - serveBundle(server, '/background.js', backgroundBuild) + server.use(express.static(path.join(__dirname, '/../../dist/mascara'))) + server.use(express.static(path.join(__dirname, '/../proxy'))) return server diff --git a/mascara/src/app/first-time/index.js b/mascara/src/app/first-time/index.js index c0bba53d6..0cc3b4b0e 100644 --- a/mascara/src/app/first-time/index.js +++ b/mascara/src/app/first-time/index.js @@ -20,7 +20,6 @@ class FirstTimeFlow extends Component { seedWords: PropTypes.string, address: PropTypes.string, noActiveNotices: PropTypes.bool, - goToBuyEtherView: PropTypes.func.isRequired, }; static defaultProps = { @@ -171,4 +170,3 @@ export default connect( openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})), }) )(FirstTimeFlow) - diff --git a/mascara/src/background.js b/mascara/src/background.js index 8aa1d8fe2..40a684f3d 100644 --- a/mascara/src/background.js +++ b/mascara/src/background.js @@ -30,15 +30,19 @@ global.addEventListener('activate', function (event) { log.debug('inside:open') - -// // state persistence +// state persistence const dbController = new DbController({ key: STORAGE_KEY, }) -loadStateFromPersistence() -.then((initState) => setupController(initState)) -.then(() => log.debug('MetaMask initialization complete.')) -.catch((err) => console.error('WHILE SETTING UP:', err)) + +start().catch(log.error) + +async function start() { + log.debug('MetaMask initializing...') + const initState = await loadStateFromPersistence() + await setupController(initState) + log.debug('MetaMask initialization complete.') +} // // State and Persistence diff --git a/mascara/src/mascara.js b/mascara/src/metamascara.js similarity index 100% rename from mascara/src/mascara.js rename to mascara/src/metamascara.js diff --git a/mascara/src/proxy.js b/mascara/src/proxy.js index 54c5d5cf4..80b4dc516 100644 --- a/mascara/src/proxy.js +++ b/mascara/src/proxy.js @@ -1,13 +1,13 @@ const createParentStream = require('iframe-stream').ParentStream -const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') +const SwController = require('sw-controller') const SwStream = require('sw-stream/lib/sw-stream.js') -const intervalDelay = Math.floor(Math.random() * (30000 - 1000)) + 1000 -const background = new SWcontroller({ - fileName: '/background.js', - letBeIdle: false, - wakeUpInterval: 30000, - intervalDelay, +const keepAliveDelay = Math.floor(Math.random() * (30000 - 1000)) + 1000 +const background = new SwController({ + fileName: './scripts/background.js', + keepAlive: true, + keepAliveInterval: 30000, + keepAliveDelay, }) const pageStream = createParentStream() diff --git a/mascara/src/ui.js b/mascara/src/ui.js index b272a2e06..f35a11fc4 100644 --- a/mascara/src/ui.js +++ b/mascara/src/ui.js @@ -1,6 +1,6 @@ const injectCss = require('inject-css') -const SWcontroller = require('client-sw-ready-event/lib/sw-client.js') -const SwStream = require('sw-stream/lib/sw-stream.js') +const SwController = require('sw-controller') +const SwStream = require('sw-stream') const MetaMaskUiCss = require('../../ui/css') const MetamascaraPlatform = require('../../app/scripts/platforms/window') const startPopup = require('../../app/scripts/popup-core') @@ -8,27 +8,44 @@ const startPopup = require('../../app/scripts/popup-core') // create platform global global.platform = new MetamascaraPlatform() - var css = MetaMaskUiCss() injectCss(css) const container = document.getElementById('app-content') -var name = 'popup' +const name = 'popup' window.METAMASK_UI_TYPE = name window.METAMASK_PLATFORM_TYPE = 'mascara' -const intervalDelay = Math.floor(Math.random() * (30000 - 1000)) + 1000 +const keepAliveDelay = Math.floor(Math.random() * (30000 - 1000)) + 1000 -const background = new SWcontroller({ - fileName: '/background.js', - letBeIdle: false, - intervalDelay, - wakeUpInterval: 20000, +const swController = new SwController({ + fileName: './background.js', + keepAlive: true, + keepAliveDelay, + keepAliveInterval: 20000, }) + +swController.once('updatefound', windowReload) +swController.once('ready', async () => { + try { + swController.removeListener('updatefound', windowReload) + console.log('swController ready') + await timeout(1000) + console.log('connecting to app') + await connectApp() + console.log('app connected') + } catch (err) { + console.error(err) + } +}) + +console.log('starting service worker') +swController.startWorker() + // Setup listener for when the service worker is read -const connectApp = function (readSw) { +function connectApp() { const connectionStream = SwStream({ - serviceWorker: background.controller, + serviceWorker: swController.getWorker(), context: name, }) return new Promise((resolve, reject) => { @@ -43,19 +60,6 @@ const connectApp = function (readSw) { }) }) } -background.on('ready', async (sw) => { - try { - background.removeListener('updatefound', connectApp) - await timeout(1000) - await connectApp(sw) - console.log('hello from cb ready event!') - } catch (e) { - console.error(e) - } -}) -background.on('updatefound', windowReload) - -background.startWorker() function windowReload () { if (window.METAMASK_SKIP_RELOAD) return diff --git a/mascara/ui/index.html b/mascara/ui/index.html index eac8e4898..dbc445891 100644 --- a/mascara/ui/index.html +++ b/mascara/ui/index.html @@ -7,6 +7,6 @@
- + - \ No newline at end of file + diff --git a/old-ui/app/app.js b/old-ui/app/app.js index c79ac633a..37611987f 100644 --- a/old-ui/app/app.js +++ b/old-ui/app/app.js @@ -171,7 +171,7 @@ App.prototype.renderAppBar = function () { h('img', { height: 24, width: 24, - src: '/images/icon-128.png', + src: './images/icon-128.png', }), h(NetworkIndicator, { @@ -581,7 +581,6 @@ App.prototype.renderPrimary = function () { case 'qr': log.debug('rendering show qr screen') - console.log(`QrView`, QrView); return h('div', { style: { position: 'absolute', diff --git a/old-ui/app/components/buy-button-subview.js b/old-ui/app/components/buy-button-subview.js index 843627c33..56d173839 100644 --- a/old-ui/app/components/buy-button-subview.js +++ b/old-ui/app/components/buy-button-subview.js @@ -247,7 +247,6 @@ BuyButtonSubview.prototype.backButtonContext = function () { if (this.props.context === 'confTx') { this.props.dispatch(actions.showConfTxPage(false)) } else { - console.log(`actions.goHome`, actions.goHome); this.props.dispatch(actions.goHome()) } } diff --git a/old-ui/app/components/pending-tx.js b/old-ui/app/components/pending-tx.js index 720df2243..7f63d9fdf 100644 --- a/old-ui/app/components/pending-tx.js +++ b/old-ui/app/components/pending-tx.js @@ -62,8 +62,8 @@ PendingTx.prototype.render = function () { const gasBn = hexToBn(gas) // default to 8MM gas limit const gasLimit = new BN(parseInt(blockGasLimit) || '8000000') - const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 19, 20) - const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 18, 20) + const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 99, 100) + const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 98, 100) const safeGasLimit = safeGasLimitBN.toString(10) // Gas Price @@ -311,7 +311,7 @@ PendingTx.prototype.render = function () { style: { fontSize: '0.9em', }, - }, 'Gas limit set dangerously high. Approving this transaction is likely to fail.') + }, 'Gas limit set dangerously high. Approving this transaction is liable to fail.') : null, ]), diff --git a/old-ui/app/components/qr-code.js b/old-ui/app/components/qr-code.js index fa38dcd92..06b9aed9b 100644 --- a/old-ui/app/components/qr-code.js +++ b/old-ui/app/components/qr-code.js @@ -25,7 +25,6 @@ function QrCodeView () { QrCodeView.prototype.render = function () { const props = this.props const Qr = props.Qr - console.log(`QrCodeView Qr`, Qr); const address = `${isHexPrefixed(Qr.data) ? 'ethereum:' : ''}${Qr.data}` const qrImage = qrCode(4, 'M') qrImage.addData(address) diff --git a/old-ui/app/components/range-slider.js b/old-ui/app/components/range-slider.js index 823f5eb01..bae740a74 100644 --- a/old-ui/app/components/range-slider.js +++ b/old-ui/app/components/range-slider.js @@ -35,7 +35,7 @@ RangeSlider.prototype.render = function () { step: increment, style: range, value: state.value || defaultValue, - onChange: mirrorInput ? this.mirrorInputs.bind(this, event) : onInput, + onChange: mirrorInput ? this.mirrorInputs.bind(this) : onInput, }), // Mirrored input for range @@ -47,7 +47,7 @@ RangeSlider.prototype.render = function () { value: state.value || defaultValue, step: increment, style: input, - onChange: this.mirrorInputs.bind(this, event), + onChange: this.mirrorInputs.bind(this), }) : null, ]) ) diff --git a/old-ui/app/components/transaction-list-item.js b/old-ui/app/components/transaction-list-item.js index 7ab3414e5..b9f82c668 100644 --- a/old-ui/app/components/transaction-list-item.js +++ b/old-ui/app/components/transaction-list-item.js @@ -30,7 +30,12 @@ function TransactionListItem () { TransactionListItem.prototype.showRetryButton = function () { const { transaction = {}, transactions } = this.props - const { status, submittedTime, txParams } = transaction + const { submittedTime, txParams } = transaction + + if (!txParams) { + return false + } + const currentNonce = txParams.nonce const currentNonceTxs = transactions.filter(tx => tx.txParams.nonce === currentNonce) const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted') diff --git a/old-ui/app/config.js b/old-ui/app/config.js index 9e07cf348..508770bd4 100644 --- a/old-ui/app/config.js +++ b/old-ui/app/config.js @@ -42,7 +42,7 @@ ConfigScreen.prototype.render = function () { // subtitle and nav h('.section-title.flex-row.flex-center', [ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: (event) => { + onClick: () => { state.dispatch(actions.goHome()) }, }), @@ -168,7 +168,6 @@ ConfigScreen.prototype.render = function () { h('a', { href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account', target: '_blank', - onClick (event) { this.navigateTo(event.target.href) }, }, 'Read more.'), ]), h('br'), @@ -260,7 +259,3 @@ function currentProviderDisplay (metamaskState) { h('span', value), ]) } - -ConfigScreen.prototype.navigateTo = function (url) { - global.platform.openWindow({ url }) -} 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/css.js b/old-ui/css.js index 21b311c28..5e2572e29 100644 --- a/old-ui/css.js +++ b/old-ui/css.js @@ -11,7 +11,7 @@ var cssFiles = { 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'), 'first-time.css': fs.readFileSync(path.join(__dirname, '../mascara/src/app/first-time/index.css'), 'utf8'), 'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'), - 'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'), + 'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8') } function bundleCss () { @@ -19,7 +19,7 @@ function bundleCss () { var fileContent = cssFiles[fileName] var output = String() - output += '/*========== ' + fileName + ' ==========*/\n\n' + output += '/ *========== ' + fileName + ' ========== * /\n\n' output += fileContent output += '\n\n' diff --git a/package-lock.json b/package-lock.json index 314ae8df7..eafc1c2ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,108 +5,160 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz", - "integrity": "sha512-yd7CkUughvHQoEahQqcMdrZw6o/6PwUxiRkfZuVDVHCDe77mysD/suoNyk5mK6phTnRW1kyIbPHyCJgxw++LXg==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz", + "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==", "dev": true, "requires": { - "chalk": "2.3.0", + "@babel/highlight": "7.0.0-beta.44" + } + }, + "@babel/generator": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz", + "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44", + "jsesc": "2.5.1", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz", + "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==", + "dev": true, + "requires": { + "@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-get-function-arity": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz", + "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz", + "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.44" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz", + "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==", + "dev": true, + "requires": { + "chalk": "2.3.2", "esutils": "2.0.2", "js-tokens": "3.0.2" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "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" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "5.3.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 + }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } }, - "@babel/helper-function-name": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz", - "integrity": "sha512-c+DAyp8LMm2nzSs2uXEuxp4LYGSUYEyHtU3fU57avFChjsnTmmpWmXj2dv0yUxHTEydgVAv5fIzA+4KJwoqWDA==", - "dev": true, - "requires": { - "@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/helper-get-function-arity": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz", - "integrity": "sha512-m7rVVX/dMLbbB9NCzKYRrrFb0qZxgpmQ4Wv6y7zEsB6skoJHRuXVeb/hAFze79vXBbuD63ci7AVHXzAdZSk9KQ==", - "dev": true, - "requires": { - "@babel/types": "7.0.0-beta.31" - } - }, "@babel/template": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.31.tgz", - "integrity": "sha512-97IRmLvoDhIDSQkqklVt3UCxJsv0LUEVb/0DzXWtc8Lgiyxj567qZkmTG9aR21CmcJVVIvq2Y/moZj4oEpl5AA==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz", + "integrity": "sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng==", "dev": true, "requires": { - "@babel/code-frame": "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.44", + "@babel/types": "7.0.0-beta.44", + "babylon": "7.0.0-beta.44", "lodash": "4.17.4" }, "dependencies": { "babylon": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.31.tgz", - "integrity": "sha512-6lm2mV3S51yEnKmQQNnswoABL1U1H1KHoCCVwdwI3hvIv+W7ya4ki7Aw4o4KxtUHjNKkK5WpZb22rrMMOcJXJQ==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", "dev": true } } }, "@babel/traverse": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.31.tgz", - "integrity": "sha512-3N+VJW+KlezEjFBG7WSYeMyC5kIqVLPb/PGSzCDPFcJrnArluD1GIl7Y3xC7cjKiTq2/JohaLWHVPjJWHlo9Gg==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz", + "integrity": "sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA==", "dev": true, "requires": { - "@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", + "@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": "10.4.0", + "globals": "11.4.0", "invariant": "2.2.2", "lodash": "4.17.4" }, "dependencies": { "babylon": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.31.tgz", - "integrity": "sha512-6lm2mV3S51yEnKmQQNnswoABL1U1H1KHoCCVwdwI3hvIv+W7ya4ki7Aw4o4KxtUHjNKkK5WpZb22rrMMOcJXJQ==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", "dev": true }, "debug": { @@ -119,17 +171,17 @@ } }, "globals": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-10.4.0.tgz", - "integrity": "sha512-uNUtxIZpGyuaq+5BqGGQHsL4wUlJAXRqOm6g3Y48/CWNGTLONgBibI0lh6lGxjR2HljFYUfszb+mk4WkgMntsA==", + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz", + "integrity": "sha512-Dyzmifil8n/TmSqYDEXbm+C8yitzJQqQIlJQLNRMwa+BOUJpRC19pyVeN12JAjt61xonvXjtff+hJruTRXn5HA==", "dev": true } } }, "@babel/types": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.31.tgz", - "integrity": "sha512-exAHB+NeFGxkfQ5dSUD03xl3zYGneeSk2Mw2ldTt/nTvYxuDiuSp3DlxgUBgzbdTFG4fbwPk0WtKWOoTXCmNGg==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz", + "integrity": "sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ==", "dev": true, "requires": { "esutils": "2.0.2", @@ -151,7 +203,7 @@ "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.3.0", + "acorn": "5.5.3", "css": "2.2.1", "normalize-path": "2.1.1", "source-map": "0.5.7", @@ -159,9 +211,9 @@ }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "source-map": { @@ -188,7 +240,7 @@ "integrity": "sha1-AtD3eBwe5eG+WkMSoyX76LGzcjE=", "dev": true, "requires": { - "https-proxy-agent": "2.2.0", + "https-proxy-agent": "2.2.1", "node-fetch": "1.7.3", "progress": "2.0.0", "proxy-from-env": "1.0.0" @@ -213,9 +265,9 @@ } }, "https-proxy-agent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz", - "integrity": "sha512-uUWcfXHvy/dwfM9bqa6AozvAjS32dZSTUYd/4SEpYKRg6LEcPLshksnQYRudM9AyNvUARMfAg5TLjUDyX/K4vA==", + "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", @@ -224,6 +276,21 @@ } } }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true + }, + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, "@types/node": { "version": "8.5.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", @@ -251,14 +318,15 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "abi-decoder": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-1.0.9.tgz", - "integrity": "sha1-a8/Yb39j++yFc9l3izpPkruS4B8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-1.1.0.tgz", + "integrity": "sha512-nvLArBx0XOJufWyaghMKtIofZDBwEMdVZoqcetQOIe1qYeKZk4+kRYGPEJ5lt7dD3MLulw//amUzOJLM8eW5RA==", "requires": { "babel-core": "6.26.0", "babel-loader": "6.4.1", "babel-plugin-add-module-exports": "0.2.1", "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-runtime": "6.23.0", "babel-preset-es2015": "6.24.1", "chai": "3.5.0", "web3": "0.18.4", @@ -324,6 +392,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "dev": true, "requires": { "mime-types": "2.1.17", "negotiator": "0.6.1" @@ -348,13 +417,13 @@ "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", "dev": true, "requires": { - "acorn": "5.3.0" + "acorn": "5.5.3" }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true } } @@ -363,6 +432,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, "requires": { "acorn": "3.3.0" }, @@ -370,7 +440,8 @@ "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true } } }, @@ -442,7 +513,8 @@ "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=" + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true }, "align-text": { "version": "0.1.4", @@ -522,7 +594,8 @@ "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==" + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true }, "ansi-gray": { "version": "0.1.1", @@ -562,6 +635,12 @@ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", "dev": true }, + "any-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", + "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", + "dev": true + }, "any-promise": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-0.1.0.tgz", @@ -571,6 +650,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, "requires": { "micromatch": "2.3.11", "normalize-path": "2.1.1" @@ -580,8 +660,17 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, "requires": { "buffer-equal": "1.0.0" + }, + "dependencies": { + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + } } }, "aproba": { @@ -592,7 +681,8 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true }, "are-we-there-yet": { "version": "1.1.4", @@ -600,13 +690,14 @@ "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "requires": { "delegates": "1.0.0", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, "requires": { "sprintf-js": "1.0.3" } @@ -615,6 +706,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, "requires": { "arr-flatten": "1.1.0" } @@ -623,6 +715,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, "requires": { "make-iterator": "1.0.1" } @@ -636,6 +729,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, "requires": { "make-iterator": "1.0.1" } @@ -653,7 +747,8 @@ "array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true }, "array-equal": { "version": "1.0.0", @@ -681,6 +776,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, "requires": { "define-properties": "1.1.2", "es-abstract": "1.10.0" @@ -690,6 +786,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, "requires": { "array-slice": "1.1.0", "is-number": "4.0.0" @@ -698,7 +795,8 @@ "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==" + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, @@ -706,6 +804,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, "requires": { "is-number": "4.0.0" }, @@ -713,7 +812,8 @@ "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==" + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, @@ -732,12 +832,14 @@ "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true }, "array-sort": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, "requires": { "default-compare": "1.0.0", "get-value": "2.0.6", @@ -747,7 +849,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -755,6 +858,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, "requires": { "array-uniq": "1.0.3" } @@ -767,18 +871,14 @@ "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" - }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true }, "asap": { "version": "2.0.6", @@ -854,8 +954,9 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.2.4.tgz", "integrity": "sha512-mxc+yISkb0vjsuvG3dJCIZXzRWjKndQ9Zo9zNDJ1K2wh9eP0E0oGmOWm+4cFOvW4dA0tGFImTW5tQJHCtn1kIQ==", + "dev": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0", "process-nextick-args": "1.0.7", "stream-exhaust": "1.0.2" @@ -894,10 +995,70 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, "requires": { "async-done": "1.2.4" } }, + "async.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz", + "integrity": "sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw=", + "dev": true, + "requires": { + "async.util.queue": "0.5.2" + } + }, + "async.util.arrayeach": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz", + "integrity": "sha1-WMTpgCjVXWm/sFrrOvROClVagpw=", + "dev": true + }, + "async.util.isarray": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", + "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=", + "dev": true + }, + "async.util.map": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz", + "integrity": "sha1-5YjvhuCzq18CfZevTWg10FXKadY=", + "dev": true + }, + "async.util.noop": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", + "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=", + "dev": true + }, + "async.util.onlyonce": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", + "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=", + "dev": true + }, + "async.util.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz", + "integrity": "sha1-V/Zavho83yc9MavSirlUJfgiLuU=", + "dev": true, + "requires": { + "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": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz", + "integrity": "sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8=", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1016,23 +1177,23 @@ } }, "babel-eslint": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.1.2.tgz", - "integrity": "sha512-IE+glF8t0lLoldylN7JyR8gT7e3jwyuNH2ds8g3UVUwGob/U4iT7Xpsiq2kQ8QGLb0eX4RcQXNqeW6mgPysu9A==", + "version": "8.2.2", + "resolved": "http://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.2.tgz", + "integrity": "sha512-Qt2lz2egBxNYWqN9JIO2z4NOOf8i4b5JS6CFoYrOZZTDssueiV1jH/jsefyg+86SeNY3rB361/mi3kE1WK2WYQ==", "dev": true, "requires": { - "@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.44", + "@babel/traverse": "7.0.0-beta.44", + "@babel/types": "7.0.0-beta.44", + "babylon": "7.0.0-beta.44", "eslint-scope": "3.7.1", "eslint-visitor-keys": "1.0.0" }, "dependencies": { "babylon": { - "version": "7.0.0-beta.31", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.31.tgz", - "integrity": "sha512-6lm2mV3S51yEnKmQQNnswoABL1U1H1KHoCCVwdwI3hvIv+W7ya4ki7Aw4o4KxtUHjNKkK5WpZb22rrMMOcJXJQ==", + "version": "7.0.0-beta.44", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", + "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", "dev": true } } @@ -1712,7 +1873,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true, "requires": { "babel-runtime": "6.26.0" } @@ -1779,7 +1939,7 @@ "babel-plugin-transform-regenerator": "6.26.0", "browserslist": "2.11.0", "invariant": "2.2.2", - "semver": "5.4.1" + "semver": "5.5.0" } }, "babel-preset-es2015": { @@ -1960,6 +2120,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, "requires": { "arr-filter": "1.1.2", "arr-flatten": "1.1.0", @@ -2206,9 +2367,9 @@ "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "bip39": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.4.0.tgz", - "integrity": "sha512-1++HywqIyPtWDo7gm4v0ylYbwkLvHkuwVSKbBlZBbTCP/mnkyrlARBny906VLAwxJbC5xw9EvuJasHFIZaIFMQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", + "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", "requires": { "create-hash": "1.1.3", "pbkdf2": "3.0.14", @@ -2240,7 +2401,7 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "blob": { @@ -2319,6 +2480,7 @@ "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, "requires": { "expand-range": "1.8.2", "preserve": "0.2.0", @@ -2326,14 +2488,14 @@ } }, "brfs": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.4.3.tgz", - "integrity": "sha1-22ddb16SPm3wh/ylhZyQkKrtMhY=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.5.0.tgz", + "integrity": "sha512-PscWJn5IGjcK5g5lqEeRPYJ5efZk93YbopLu6UXZcb9dPZUfMN/UMyyT/tddpi7A9yIDM9TEdCOA3A4WGST1hg==", "dev": true, "requires": { "quote-stream": "1.0.2", "resolve": "1.4.0", - "static-module": "1.5.0", + "static-module": "2.2.3", "through2": "2.0.3" } }, @@ -2418,9 +2580,9 @@ } }, "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "browser-unpack": { @@ -2472,7 +2634,7 @@ "punycode": "1.4.1", "querystring-es3": "0.2.1", "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "resolve": "1.4.0", "shasum": "1.0.2", "shell-quote": "1.6.1", @@ -2528,7 +2690,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "events": { @@ -2733,9 +2895,10 @@ "dev": true }, "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", + "dev": true }, "buffer-more-ints": { "version": "0.0.2", @@ -2807,6 +2970,29 @@ } } }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + } + } + }, "cached-path-relative": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", @@ -2817,6 +3003,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, "requires": { "callsites": "0.2.0" } @@ -2830,7 +3017,8 @@ "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true }, "camelcase": { "version": "3.0.0", @@ -2939,7 +3127,8 @@ "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true }, "charm": { "version": "1.0.2", @@ -2982,6 +3171,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", @@ -2994,6 +3184,19 @@ "readdirp": "2.1.0" } }, + "chromedriver": { + "version": "2.37.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.37.0.tgz", + "integrity": "sha512-Dz3ktXp+9T0ygMIEZX3SNL3grXywi2kC1swiD9cjISlLcoenzhOpsj/R/Gr2hJvrC49aGE2BhSpuUevdGq6J4w==", + "dev": true, + "requires": { + "del": "3.0.0", + "extract-zip": "1.6.6", + "kew": "0.7.0", + "mkdirp": "0.5.1", + "request": "2.83.0" + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -3006,7 +3209,8 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true }, "class-utils": { "version": "0.3.6", @@ -3090,23 +3294,71 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.2" + } + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, "requires": { "restore-cursor": "2.0.0" } }, + "cli-spinners": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "dev": true, + "requires": { + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "1.0.2" + }, + "dependencies": { + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + } + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" - }, - "client-sw-ready-event": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/client-sw-ready-event/-/client-sw-ready-event-3.4.0.tgz", - "integrity": "sha1-/0hkYXaQVed0hXDxrvECuGdbZtA=" + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true }, "cliui": { "version": "3.2.0", @@ -3119,14 +3371,15 @@ } }, "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" }, "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true }, "clone-regexp": { "version": "1.0.0", @@ -3138,15 +3391,26 @@ "is-supported-regexp-flag": "1.0.0" } }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "1.0.0" + } + }, "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true }, "cloneable-readable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "dev": true, "requires": { "inherits": "2.0.3", "process-nextick-args": "1.0.7", @@ -3188,6 +3452,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, "requires": { "arr-map": "2.0.2", "for-own": "1.0.0", @@ -3198,6 +3463,7 @@ "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" } @@ -3432,23 +3698,31 @@ "dev": true }, "compressible": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", - "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz", + "integrity": "sha1-DRAgq5JLL9tNYnmHXH1tq6a6p6k=", "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" + }, + "dependencies": { + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + } } }, "compression": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz", - "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=", + "version": "1.7.2", + "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", + "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", "dev": true, "requires": { "accepts": "1.3.4", "bytes": "3.0.0", - "compressible": "2.0.12", + "compressible": "2.0.13", "debug": "2.6.9", "on-headers": "1.0.1", "safe-buffer": "5.1.1", @@ -3466,7 +3740,7 @@ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "typedarray": "0.0.6" } }, @@ -3529,12 +3803,6 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, - "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", - "dev": true - }, "convert-source-map": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", @@ -3559,6 +3827,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.1.tgz", "integrity": "sha1-Zl/DIEbKhKiYq6o8WUXn8kjMugA=", + "dev": true, "requires": { "each-props": "1.3.1", "is-plain-object": "2.0.4" @@ -3667,6 +3936,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, "requires": { "lru-cache": "4.1.1", "shebang-command": "1.2.0", @@ -3935,6 +4205,12 @@ "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=" }, + "dargs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz", + "integrity": "sha1-7H6lDHhWTNNsnV7Bj2Yyn63ieCk=", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -3950,6 +4226,23 @@ "dev": true, "optional": true }, + "data-urls": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", + "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", + "dev": true, + "requires": { + "abab": "1.0.4", + "whatwg-mimetype": "2.1.0", + "whatwg-url": "6.4.0" + } + }, + "date-fns": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", + "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==", + "dev": true + }, "date-format": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", @@ -3990,13 +4283,13 @@ } }, "debug-fabulous": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.0.0.tgz", - "integrity": "sha512-dsd50qQ1atDeurcxL7XOjPp4nZCGZzWIONDujDXzl1atSyC3hMbZD+v6440etw+Vt0Pr8ce4TQzHfX3KZM05Mw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", "dev": true, "requires": { "debug": "3.1.0", - "memoizee": "0.4.11", + "memoizee": "0.4.12", "object-assign": "4.1.1" }, "dependencies": { @@ -4021,6 +4314,15 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, + "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" + } + }, "deep-diff": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", @@ -4054,18 +4356,20 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true }, "deepmerge": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-0.2.10.tgz", - "integrity": "sha1-iQa/nlJaT78bIDsq/LRkAkmCEhk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz", + "integrity": "sha512-Q89Z26KAfA3lpPGhbF6XMfYAm3jIV3avViy6KOJ2JLzFbeWHOvPQUu5aSJIWXap3gDZC2y1eF5HXEPI2wGqgvw==", "dev": true }, "default-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, "requires": { "kind-of": "5.1.0" }, @@ -4073,14 +4377,16 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, "default-resolution": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=" + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true }, "deferred-leveldown": { "version": "1.2.2", @@ -4229,10 +4535,17 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detect-conflict": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", + "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=", + "dev": true + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true }, "detect-indent": { "version": "4.0.0", @@ -4341,6 +4654,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, "requires": { "esutils": "2.0.2" } @@ -4525,10 +4839,13 @@ "dev": true }, "domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.0.tgz", - "integrity": "sha512-WpwuBlZ2lQRFa4H/4w49deb9rJLot9KmqrKKjMc9qBl7CID+DdC2swoa34ccRl+anL2B6bLp6TjFdIdnzekMBQ==", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "4.0.2" + } }, "domhandler": { "version": "2.4.1", @@ -4607,14 +4924,20 @@ } } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-shift": "1.0.0" } }, @@ -4622,6 +4945,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.1.tgz", "integrity": "sha1-/BOPUeOid0KG1IWOAtbn3kYt4Vg=", + "dev": true, "requires": { "is-plain-object": "2.0.4", "object.defaults": "1.1.0" @@ -4636,6 +4960,12 @@ "jsbn": "0.1.1" } }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", + "dev": true + }, "editorconfig": { "version": "0.13.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz", @@ -4645,7 +4975,7 @@ "bluebird": "3.5.1", "commander": "2.11.0", "lru-cache": "3.2.0", - "semver": "5.4.1", + "semver": "5.5.0", "sigmund": "1.0.1" }, "dependencies": { @@ -4665,6 +4995,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "ejs": { + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.8.tgz", + "integrity": "sha512-QIDZL54fyV8MDcAsO91BMH1ft2qGGaHIJsJIA/+t+7uvXol1dm413fPcUgUb4k8F/9457rx4/KFE4XfDifrQxQ==", + "dev": true + }, "electron-releases": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", @@ -4678,6 +5014,12 @@ "electron-releases": "2.1.0" } }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, "elliptic": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", @@ -4700,7 +5042,8 @@ "encodeurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true }, "encoding": { "version": "0.1.12", @@ -4711,9 +5054,9 @@ } }, "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { "once": "1.4.0" } @@ -4817,7 +5160,7 @@ "resolved": "https://registry.npmjs.org/ensnare/-/ensnare-1.0.0.tgz", "integrity": "sha1-ctK/fvSKuiH2at8p0AoJBO3bYcc=", "requires": { - "tape": "4.8.0" + "tape": "4.9.0" } }, "ensure-posix-path": { @@ -4912,6 +5255,16 @@ "prr": "1.0.1" } }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "dev": true, + "requires": { + "string-template": "0.2.1", + "xtend": "4.0.1" + } + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -5036,6 +5389,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz", "integrity": "sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM=", "dev": true, + "optional": true, "requires": { "esprima": "1.1.1", "estraverse": "1.5.1", @@ -5047,19 +5401,22 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz", "integrity": "sha1-W28VR/TRAuZw4UDFCb5ncdautUk=", - "dev": true + "dev": true, + "optional": true }, "estraverse": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=", - "dev": true + "dev": true, + "optional": true }, "esutils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=", - "dev": true + "dev": true, + "optional": true }, "source-map": { "version": "0.1.43", @@ -5088,6 +5445,7 @@ "version": "4.14.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz", "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==", + "dev": true, "requires": { "ajv": "5.5.2", "babel-code-frame": "6.26.0", @@ -5121,7 +5479,7 @@ "pluralize": "7.0.0", "progress": "2.0.0", "require-uncached": "1.0.3", - "semver": "5.4.1", + "semver": "5.5.0", "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", "table": "4.0.2", @@ -5131,12 +5489,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "1.9.1" } @@ -5145,6 +5505,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", @@ -5155,6 +5516,7 @@ "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" } @@ -5162,12 +5524,14 @@ "globals": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", - "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==" + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true }, "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" } @@ -5176,6 +5540,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "2.0.0" } @@ -5188,19 +5553,37 @@ "integrity": "sha1-mh3qWLM1wxJCIZ0Fmzf/sUMJ9uE=", "dev": true }, - "eslint-plugin-mocha": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.11.0.tgz", - "integrity": "sha1-kRk6L1XiCl41l0BUoAidMBmO5Xg=", + "eslint-plugin-json": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz", + "integrity": "sha1-m6c7sL6Z1QCT6In1uWhGPSow764=", "dev": true, "requires": { - "ramda": "0.24.1" + "jshint": "2.9.5" + } + }, + "eslint-plugin-mocha": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-5.0.0.tgz", + "integrity": "sha512-mpRWWsjxRco2bY4qE5DL8SmGoVF0Onb6DZrbgOjFoNo1YNN299K2voIozd8Kce3qC/neWNr2XF27E1ZDMl1yZg==", + "dev": true, + "requires": { + "ramda": "0.25.0" + }, + "dependencies": { + "ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", + "dev": true + } } }, "eslint-plugin-react": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz", - "integrity": "sha512-YGSjB9Qu6QbVTroUZi66pYky3DfoIPLdHQ/wmrBGyBRnwxQsBXAov9j2rpXt/55i8nyMv6IRWJv2s4d4YnduzQ==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", + "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", + "dev": true, "requires": { "doctrine": "2.0.2", "has": "1.0.1", @@ -5212,6 +5595,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, "requires": { "esrecurse": "4.2.0", "estraverse": "4.2.0" @@ -5220,12 +5604,14 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true }, "espree": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, "requires": { "acorn": "5.3.0", "acorn-jsx": "3.0.1" @@ -5234,19 +5620,22 @@ "acorn": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==" + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true } } }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true }, "esquery": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, "requires": { "estraverse": "4.2.0" } @@ -5281,7 +5670,7 @@ "integrity": "sha1-TScDuYeIJbw4xiWZEOkLTbAFx94=", "requires": { "ethereumjs-vm": "2.3.2", - "tape": "4.8.0" + "tape": "4.9.0" } }, "eth-block-tracker": { @@ -5291,12 +5680,12 @@ "requires": { "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", "eth-query": "2.1.2", - "ethereumjs-tx": "1.3.3", + "ethereumjs-tx": "1.3.4", "ethereumjs-util": "5.1.3", "ethjs-util": "0.1.4", "json-rpc-engine": "3.6.0", "pify": "2.3.0", - "tape": "4.8.0" + "tape": "4.9.0" }, "dependencies": { "async-eventemitter": { @@ -5339,13 +5728,18 @@ "json-rpc-error": "2.0.0", "promise-to-callback": "1.0.0" } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, "eth-contract-metadata": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eth-contract-metadata/-/eth-contract-metadata-1.3.0.tgz", - "integrity": "sha1-yvPNw9aZlbbXUyydlv7brUY2HKg=" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eth-contract-metadata/-/eth-contract-metadata-1.7.0.tgz", + "integrity": "sha512-CzAnYSEd+xMcCImt6xWoiKXi5Wc4A/r2vDV9ZNxBOHgVdO9w9K2JmWMFKJ0axUSXjAvClpPlCimLXJudlyjA9g==" }, "eth-ens-namehash": { "version": "1.0.2", @@ -5368,7 +5762,7 @@ "resolved": "https://registry.npmjs.org/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz", "integrity": "sha1-rV9HkHRDapO0ObC5XHkJXCh5GII=", "requires": { - "bip39": "2.4.0", + "bip39": "2.5.0", "eth-sig-util": "1.4.2", "ethereumjs-util": "5.1.4", "ethereumjs-wallet": "0.6.0", @@ -5398,7 +5792,7 @@ "integrity": "sha512-MUcUzwDy0cPso1BEnY5T5DtlI8r8gA7lNqn+BOFzDX1Ll6C8mCPz8pzSKrTkbKV9KTfgQYJ/M4vJbR83TqhROg==", "requires": { "await-semaphore": "0.1.3", - "eth-json-rpc-middleware": "1.5.0", + "eth-json-rpc-middleware": "1.6.0", "json-rpc-engine": "3.4.0", "lodash.flatmap": "4.5.0" }, @@ -5431,29 +5825,30 @@ "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" + "tape": "4.9.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-tx": "1.3.4", "ethereumjs-util": "5.1.5", "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", - "tape": "4.8.0" + "tape": "4.9.0" }, "dependencies": { "ethereumjs-util": { @@ -5477,14 +5872,14 @@ "resolved": "https://registry.npmjs.org/eth-keyring-controller/-/eth-keyring-controller-2.1.4.tgz", "integrity": "sha1-BRjZ2Jrw2K82Kigh5NVQqL4UqAc=", "requires": { - "bip39": "2.4.0", + "bip39": "2.5.0", "bluebird": "3.5.1", "browser-passworder": "2.0.3", "eth-hd-keyring": "1.2.2", "eth-sig-util": "1.4.2", "eth-simple-keyring": "1.2.1", "ethereumjs-util": "5.1.3", - "loglevel": "1.6.0", + "loglevel": "1.6.1", "obs-store": "2.4.1", "promise-filter": "1.1.0" }, @@ -5503,7 +5898,7 @@ "resolved": "https://registry.npmjs.org/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz", "integrity": "sha1-rV9HkHRDapO0ObC5XHkJXCh5GII=", "requires": { - "bip39": "2.4.0", + "bip39": "2.5.0", "eth-sig-util": "1.4.2", "ethereumjs-util": "5.1.3", "ethereumjs-wallet": "0.6.0", @@ -5544,7 +5939,7 @@ "requires": { "babel-preset-es2015": "6.24.1", "babelify": "7.3.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "through2": "2.0.3", "xtend": "4.0.1" } @@ -5552,9 +5947,9 @@ } }, "eth-phishing-detect": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/eth-phishing-detect/-/eth-phishing-detect-1.1.12.tgz", - "integrity": "sha512-wzEqAB4mUY0gkrn+ZOlzyxHmsouKT6rrzYIxy/FFalqoZVvX/9McPdFwWkHCYrv4KzTKgJJh8tKzvMnTae8Naw==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/eth-phishing-detect/-/eth-phishing-detect-1.1.13.tgz", + "integrity": "sha512-1KQcKvAQIjJgFMVwxaw2+BlzM9Momzl0e+/torPdMjg7WGq6LmCIS7ddg84diH5zIQp9quGyRVIEawCCuErgVQ==", "requires": { "fast-levenshtein": "2.0.6" } @@ -5651,7 +6046,14 @@ "eth-query": "2.1.2", "ethjs-util": "0.1.4", "pify": "2.3.0", - "tape": "4.8.0" + "tape": "4.9.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } } }, "ethjs-format": { @@ -5695,22 +6097,59 @@ } }, "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", - "clone": "2.1.1", + "bn.js": "4.11.8", + "clone": "2.1.2", "concat-stream": "1.6.0", - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "eth-query": "2.1.2", "ethereumjs-block": "1.7.0", - "ethereumjs-tx": "1.3.3", + "ethereumjs-tx": "1.3.4", "ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", - "ethereumjs-vm": "2.3.2", + "ethereumjs-vm": "2.3.4", "through2": "2.0.3", "treeify": "1.1.0", - "web3-provider-engine": "13.6.0" + "web3-provider-engine": "13.8.0" + }, + "dependencies": { + "ethereumjs-vm": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.4.tgz", + "integrity": "sha512-Y4SlzNDqxrCO58jhp98HdnZVdjOqB+HC0hoU+N/DEp1aU+hFkRX/nru5F7/HkQRPIlA6aJlQp/xIA6xZs1kspw==", + "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" + }, + "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" + } + } + } + } } }, "ethereum-common": { @@ -5776,15 +6215,15 @@ "requires": { "async": "2.6.0", "ethereum-common": "0.2.0", - "ethereumjs-tx": "1.3.3", + "ethereumjs-tx": "1.3.4", "ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "merkle-patricia-tree": "2.3.0" } }, "ethereumjs-tx": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.3.tgz", - "integrity": "sha1-7OBR0+/b53GtKlGNYWMsoqt17Ls=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", + "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", "requires": { "ethereum-common": "0.0.18", "ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9" @@ -6065,12 +6504,12 @@ } }, "ethjs-query": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ethjs-query/-/ethjs-query-0.3.2.tgz", - "integrity": "sha1-9IikjOGZTNTHfsy3tSkCxvKc/YU=", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/ethjs-query/-/ethjs-query-0.3.4.tgz", + "integrity": "sha512-RkeLtBwuXJkBIf/U+Az0GOT203UiBLmN7WA6WZIwSTbmhH2yNicggwaWKvN3TOtpErOsXnzYTZp82mElHdORUQ==", "requires": { - "ethjs-format": "0.2.4", - "ethjs-rpc": "0.1.8" + "ethjs-format": "0.2.5", + "ethjs-rpc": "0.1.9" }, "dependencies": { "bn.js": { @@ -6079,12 +6518,12 @@ "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" }, "ethjs-format": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.4.tgz", - "integrity": "sha1-W7vESlrSTmirOTMS/5A5pztlv4E=", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/ethjs-format/-/ethjs-format-0.2.5.tgz", + "integrity": "sha1-RPMKvuF7B01xYtLIhqv/0GWCiSU=", "requires": { "bn.js": "4.11.6", - "ethjs-schema": "0.1.9", + "ethjs-schema": "0.2.0", "ethjs-util": "0.1.3", "is-hex-prefixed": "1.0.0", "number-to-bn": "1.7.0", @@ -6092,9 +6531,14 @@ } }, "ethjs-rpc": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/ethjs-rpc/-/ethjs-rpc-0.1.8.tgz", - "integrity": "sha1-FnZ0DkHHIoGWpxGJ0z8VychbWZ0=" + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/ethjs-rpc/-/ethjs-rpc-0.1.9.tgz", + "integrity": "sha512-KJqT7cgTeCJQ2RY1AlVmTZVnKIUXMPg+niPN5VJKwRSzpjgfr3LTVHlGbkRCqZtOMDi0ogB2vHZaRQiZBXZTUg==" + }, + "ethjs-schema": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ethjs-schema/-/ethjs-schema-0.2.0.tgz", + "integrity": "sha1-B7RtT1W3kqhGyQp58zDTHREsyjg=" }, "ethjs-util": { "version": "0.1.3", @@ -6198,18 +6642,33 @@ } }, "execa": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", - "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", "dev": true, "requires": { - "cross-spawn": "5.1.0", + "cross-spawn": "6.0.5", "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" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.5.0", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + } } }, "execall": { @@ -6227,6 +6686,18 @@ "integrity": "sha1-BmDjUlouidnkRhKUQMJy7foktSk=", "dev": true }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, "expand-braces": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", @@ -6281,6 +6752,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, "requires": { "is-posix-bracket": "0.1.1" } @@ -6289,6 +6761,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, "requires": { "fill-range": "2.2.3" } @@ -6297,16 +6770,17 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, "requires": { "homedir-polyfill": "1.0.1" } }, "express": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", - "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "requires": { - "accepts": "1.3.4", + "accepts": "1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", @@ -6314,28 +6788,90 @@ "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" + }, + "dependencies": { + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "2.1.18", + "negotiator": "0.6.1" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" + } + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "1.33.0" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + } + } } }, "extend": { @@ -6356,18 +6892,19 @@ "resolved": "https://registry.npmjs.org/extension-link-enabler/-/extension-link-enabler-1.0.0.tgz", "integrity": "sha1-V7kZru7fOL6XJwuYmM7nimN+RvM=", "requires": { - "extensionizer": "1.0.0" + "extensionizer": "1.0.1" } }, "extensionizer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/extensionizer/-/extensionizer-1.0.0.tgz", - "integrity": "sha1-AcIJu+ptnArLp3Epw6pKmpj8NTg=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/extensionizer/-/extensionizer-1.0.1.tgz", + "integrity": "sha512-UES5CSOYqshNsWFrpORcQR47+ph6UvQK25mguD44IyeMemt40CG+LTZrH1PgpGUHX3w7ACtNQnmM0J+qEe8G0Q==" }, "external-editor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, "requires": { "chardet": "0.4.2", "iconv-lite": "0.4.19", @@ -6378,10 +6915,40 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, "requires": { "is-extglob": "1.0.0" } }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -6407,16 +6974,16 @@ "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", "dev": true, "requires": { - "acorn": "5.3.0", + "acorn": "5.5.3", "foreach": "2.0.5", "isarray": "0.0.1", "object-keys": "1.0.11" }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "isarray": { @@ -6490,6 +7057,15 @@ } } }, + "fd-slicer": { + "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" + } + }, "fetch-ponyfill": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", @@ -6502,6 +7078,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, "requires": { "escape-string-regexp": "1.0.5" } @@ -6510,6 +7087,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, "requires": { "flat-cache": "1.3.0", "object-assign": "4.1.1" @@ -6535,12 +7113,14 @@ "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true }, "fill-range": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, "requires": { "is-number": "2.1.0", "isobject": "2.1.0", @@ -6553,6 +7133,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "1.0.1", @@ -6589,6 +7170,12 @@ "which": "1.3.0" } }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "dev": true + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -6602,6 +7189,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, "requires": { "detect-file": "1.0.0", "is-glob": "3.1.0", @@ -6612,17 +7200,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, "requires": { "arr-flatten": "1.1.0", "array-unique": "0.3.2", @@ -6640,6 +7231,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -6650,6 +7242,7 @@ "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" @@ -6659,6 +7252,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, "requires": { "debug": "2.6.9", "define-property": "0.2.5", @@ -6673,6 +7267,7 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -6681,6 +7276,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -6689,6 +7285,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", "is-data-descriptor": "0.1.4", @@ -6698,7 +7295,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -6706,6 +7304,7 @@ "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" @@ -6715,6 +7314,7 @@ "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" } @@ -6725,6 +7325,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, "requires": { "array-unique": "0.3.2", "define-property": "1.0.0", @@ -6740,6 +7341,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, "requires": { "is-descriptor": "1.0.2" } @@ -6748,6 +7350,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -6758,6 +7361,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, "requires": { "extend-shallow": "2.0.1", "is-number": "3.0.0", @@ -6769,6 +7373,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -6779,6 +7384,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -6787,6 +7393,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -6797,6 +7404,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -6805,6 +7413,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -6814,12 +7423,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, "requires": { "is-extglob": "2.1.1" } @@ -6828,6 +7439,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -6836,41 +7448,30 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.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", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", @@ -6887,29 +7488,11 @@ "to-regex": "3.0.2" } }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "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.2" - } - }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, "requires": { "define-property": "2.0.2", "extend-shallow": "3.0.2", @@ -6921,6 +7504,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, "requires": { "extend-shallow": "3.0.2", "safe-regex": "1.1.0" @@ -6934,6 +7518,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "dev": true, "requires": { "expand-tilde": "2.0.2", "is-plain-object": "2.0.4", @@ -6978,13 +7563,14 @@ "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "flagged-respawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", - "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", + "dev": true }, "flat": { "version": "1.0.0", @@ -6995,6 +7581,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, "requires": { "circular-json": "0.3.3", "del": "2.2.2", @@ -7006,6 +7593,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, "requires": { "globby": "5.0.0", "is-path-cwd": "1.0.0", @@ -7014,6 +7602,14 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } } } @@ -7023,13 +7619,20 @@ "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz", "integrity": "sha1-VURAdm2goNYDmZ9DNFP2wvxqdcE=" }, + "flow-parser": { + "version": "0.69.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.69.0.tgz", + "integrity": "sha1-N4tRKNbQtVSosvFqTKPhq5ZJ8A4=", + "dev": true + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "follow-redirects": { @@ -7059,6 +7662,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, "requires": { "for-in": "1.0.2" } @@ -7073,12 +7677,6 @@ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, - "fork-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", - "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=", - "dev": true - }, "form-data": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", @@ -7122,6 +7720,16 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6" + } + }, "fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", @@ -7153,6 +7761,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, "requires": { "graceful-fs": "4.1.11", "through2": "2.0.3" @@ -7205,12 +7814,14 @@ "dependencies": { "abbrev": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", "optional": true }, "ajv": { "version": "4.11.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "optional": true, "requires": { "co": "4.6.0", @@ -7219,16 +7830,19 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "optional": true, "requires": { "delegates": "1.0.0", @@ -7237,36 +7851,43 @@ }, "asn1": { "version": "0.2.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", "optional": true }, "assert-plus": { "version": "0.2.0", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "optional": true }, "aws-sign2": { "version": "0.6.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", "optional": true }, "aws4": { "version": "1.6.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", "optional": true }, "balanced-match": { "version": "0.4.2", - "bundled": true + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, "bcrypt-pbkdf": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { "tweetnacl": "0.14.5" @@ -7274,21 +7895,24 @@ }, "block-stream": { "version": "0.0.9", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "requires": { "hoek": "2.16.3" } }, "brace-expansion": { "version": "1.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", "requires": { "balanced-match": "0.4.2", "concat-map": "0.0.1" @@ -7296,51 +7920,61 @@ }, "buffer-shims": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, "caseless": { "version": "0.12.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "optional": true }, "co": { "version": "4.6.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "combined-stream": { "version": "1.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", "requires": { "delayed-stream": "1.0.0" } }, "concat-map": { "version": "0.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cryptiles": { "version": "2.0.5", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "optional": true, "requires": { "assert-plus": "1.0.0" @@ -7348,14 +7982,16 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } } }, "debug": { "version": "2.6.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "optional": true, "requires": { "ms": "2.0.0" @@ -7363,26 +7999,31 @@ }, "deep-extend": { "version": "0.4.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", "optional": true }, "delayed-stream": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "optional": true }, "detect-libc": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.2.tgz", + "integrity": "sha1-ca1dIEvxempsqPRQxhRUBm70YeE=", "optional": true }, "ecc-jsbn": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { "jsbn": "0.1.1" @@ -7390,21 +8031,25 @@ }, "extend": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "optional": true }, "extsprintf": { "version": "1.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" }, "forever-agent": { "version": "0.6.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "optional": true }, "form-data": { "version": "2.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", "optional": true, "requires": { "asynckit": "0.4.0", @@ -7414,11 +8059,13 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fstream": { "version": "1.0.11", - "bundled": true, + "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", @@ -7428,7 +8075,8 @@ }, "fstream-ignore": { "version": "1.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", "optional": true, "requires": { "fstream": "1.0.11", @@ -7438,7 +8086,8 @@ }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "requires": { "aproba": "1.1.1", @@ -7453,7 +8102,8 @@ }, "getpass": { "version": "0.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "optional": true, "requires": { "assert-plus": "1.0.0" @@ -7461,14 +8111,16 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } } }, "glob": { "version": "7.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -7480,16 +8132,19 @@ }, "graceful-fs": { "version": "4.1.11", - "bundled": true + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "har-schema": { "version": "1.0.5", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", "optional": true, "requires": { "ajv": "4.11.8", @@ -7498,12 +8153,14 @@ }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "optional": true }, "hawk": { "version": "3.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", "requires": { "boom": "2.10.1", "cryptiles": "2.0.5", @@ -7513,11 +8170,13 @@ }, "hoek": { "version": "2.16.3", - "bundled": true + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, "http-signature": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", "optional": true, "requires": { "assert-plus": "0.2.0", @@ -7527,7 +8186,8 @@ }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -7535,37 +8195,44 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "1.0.1" } }, "is-typedarray": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "optional": true }, "isarray": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isstream": { "version": "0.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "optional": true }, "jodid25519": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", "optional": true, "requires": { "jsbn": "0.1.1" @@ -7573,17 +8240,20 @@ }, "jsbn": { "version": "0.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, "json-schema": { "version": "0.2.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "optional": true }, "json-stable-stringify": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "optional": true, "requires": { "jsonify": "0.0.0" @@ -7591,17 +8261,20 @@ }, "json-stringify-safe": { "version": "5.0.1", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "optional": true }, "jsprim": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", "optional": true, "requires": { "assert-plus": "1.0.0", @@ -7612,48 +8285,56 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } } }, "mime-db": { "version": "1.27.0", - "bundled": true + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" }, "mime-types": { "version": "2.1.15", - "bundled": true, + "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", - "bundled": true, + "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", - "bundled": true + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "optional": true }, "node-pre-gyp": { "version": "0.6.39", - "bundled": true, + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", + "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==", "optional": true, "requires": { "detect-libc": "1.0.2", @@ -7671,7 +8352,8 @@ }, "nopt": { "version": "4.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "optional": true, "requires": { "abbrev": "1.1.0", @@ -7680,7 +8362,8 @@ }, "npmlog": { "version": "4.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz", + "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==", "optional": true, "requires": { "are-we-there-yet": "1.1.4", @@ -7691,38 +8374,45 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { "version": "0.8.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", "optional": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1.0.2" } }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "optional": true }, "osenv": { "version": "0.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", "optional": true, "requires": { "os-homedir": "1.0.2", @@ -7731,30 +8421,36 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "performance-now": { "version": "0.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "optional": true }, "process-nextick-args": { "version": "1.0.7", - "bundled": true + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "punycode": { "version": "1.4.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "optional": true }, "qs": { "version": "6.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "optional": true }, "rc": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", "optional": true, "requires": { "deep-extend": "0.4.2", @@ -7765,14 +8461,16 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "optional": true } } }, "readable-stream": { "version": "2.2.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", "requires": { "buffer-shims": "1.0.0", "core-util-is": "1.0.2", @@ -7785,7 +8483,8 @@ }, "request": { "version": "2.81.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", "optional": true, "requires": { "aws-sign2": "0.6.0", @@ -7814,40 +8513,47 @@ }, "rimraf": { "version": "2.6.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "requires": { "glob": "7.1.2" } }, "safe-buffer": { "version": "5.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" }, "semver": { "version": "5.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "optional": true }, "sntp": { "version": "1.0.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", "requires": { "hoek": "2.16.3" } }, "sshpk": { "version": "1.13.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", + "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", "optional": true, "requires": { "asn1": "0.2.3", @@ -7863,14 +8569,16 @@ "dependencies": { "assert-plus": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "optional": true } } }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -7879,31 +8587,36 @@ }, "string_decoder": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", "requires": { "safe-buffer": "5.0.1" } }, "stringstream": { "version": "0.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", "optional": true }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "2.1.1" } }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "optional": true }, "tar": { "version": "2.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "requires": { "block-stream": "0.0.9", "fstream": "1.0.11", @@ -7912,7 +8625,8 @@ }, "tar-pack": { "version": "3.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz", + "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=", "optional": true, "requires": { "debug": "2.6.8", @@ -7927,7 +8641,8 @@ }, "tough-cookie": { "version": "2.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", "optional": true, "requires": { "punycode": "1.4.1" @@ -7935,7 +8650,8 @@ }, "tunnel-agent": { "version": "0.6.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "optional": true, "requires": { "safe-buffer": "5.0.1" @@ -7943,26 +8659,31 @@ }, "tweetnacl": { "version": "0.14.5", - "bundled": true, + "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", - "bundled": true, + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", "optional": true }, "util-deprecate": { "version": "1.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", "optional": true }, "verror": { "version": "1.3.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", "optional": true, "requires": { "extsprintf": "1.0.2" @@ -7970,7 +8691,8 @@ }, "wide-align": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "optional": true, "requires": { "string-width": "1.0.2" @@ -7978,7 +8700,8 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } }, @@ -8059,6 +8782,33 @@ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.2.0.tgz", "integrity": "sha1-8ESOgGmFW/Kj5oPNwdMg5+KgfvQ=" }, + "ganache-cli": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.0.tgz", + "integrity": "sha512-FdTeyk4uLRHGeFiMe+Qnh4Hc5KiTVqvRVVvLDFJEVVKC1P1yHhEgZeh9sp1KhuvxSrxToxgJS25UapYQwH4zHw==", + "dev": true, + "requires": { + "source-map-support": "0.5.4", + "webpack-cli": "2.0.13" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", + "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", + "dev": true, + "requires": { + "source-map": "0.6.1" + } + } + } + }, "gather-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz", @@ -8112,11 +8862,15 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-own-enumerable-property-symbols": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz", + "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==" + }, "get-stdin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz", - "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4=", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" }, "get-stream": { "version": "3.0.0", @@ -8136,7 +8890,7 @@ "extend": "3.0.1", "file-uri-to-path": "1.0.0", "ftp": "0.3.10", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "get-value": { @@ -8152,6 +8906,85 @@ "assert-plus": "1.0.0" } }, + "gh-got": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gh-got/-/gh-got-6.0.0.tgz", + "integrity": "sha512-F/mS+fsWQMo1zfgG9MD8KWvTWPPzzhuVwY++fhQ5Ggd+0P+CAMHtzMZhNxG+TqGfHDChJKsbh6otfMGqO2AKBw==", + "dev": true, + "requires": { + "got": "7.1.0", + "is-plain-obj": "1.1.0" + }, + "dependencies": { + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "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==", + "dev": true + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "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=", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "prepend-http": "1.0.4" + } + } + } + }, + "gifencoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gifencoder/-/gifencoder-1.1.0.tgz", + "integrity": "sha512-MVh++nximxsp8NaNRfS1+MmCviZ4wi7HhuvX8eHrfNn//1mqi8Eb03tKs6Z+lIIcSEySJ6PmS1VPZ+HdtEMlfg==", + "dev": true + }, + "github-username": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/github-username/-/github-username-4.1.0.tgz", + "integrity": "sha1-y+KABBiDIG2kISrp5LXxacML9Bc=", + "dev": true, + "requires": { + "gh-got": "6.0.0" + } + }, "gl-mat4": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/gl-mat4/-/gl-mat4-1.1.4.tgz", @@ -8206,6 +9039,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, "requires": { "glob-parent": "2.0.0", "is-glob": "2.0.1" @@ -8215,6 +9049,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, "requires": { "is-glob": "2.0.1" } @@ -8223,14 +9058,15 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, "requires": { "extend": "3.0.1", "glob": "7.1.2", "glob-parent": "3.1.0", "is-negated-glob": "1.0.0", "ordered-read-streams": "1.0.1", - "pumpify": "1.3.5", - "readable-stream": "2.3.3", + "pumpify": "1.4.0", + "readable-stream": "2.3.6", "remove-trailing-separator": "1.1.0", "to-absolute-glob": "2.0.2", "unique-stream": "2.2.1" @@ -8240,6 +9076,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, "requires": { "is-glob": "3.1.0", "path-dirname": "1.0.2" @@ -8248,12 +9085,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, "requires": { "is-extglob": "2.1.1" } @@ -8264,6 +9103,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-4.0.0.tgz", "integrity": "sha1-nmOo/25h6TLebMLK7OUHGm1zcyk=", + "dev": true, "requires": { "async-done": "1.2.4", "chokidar": "1.7.0", @@ -8271,6 +9111,15 @@ "object.defaults": "1.1.0" } }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true, + "requires": { + "find-index": "0.1.1" + } + }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", @@ -8284,6 +9133,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, "requires": { "global-prefix": "1.0.2", "is-windows": "1.0.2", @@ -8294,6 +9144,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, "requires": { "expand-tilde": "2.0.2", "homedir-polyfill": "1.0.1", @@ -8311,6 +9162,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, "requires": { "array-union": "1.0.2", "arrify": "1.0.1", @@ -8318,6 +9170,14 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "globjoin": { @@ -8344,6 +9204,31 @@ "sparkles": "1.0.0" } }, + "got": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.0.tgz", + "integrity": "sha512-kBNy/S2CGwrYgDSec5KTWGKUvupwkkTVAjIsVFF2shXO13xpZdFP4d4kxa//CLX2tN/rV0aYwK8vY6UKWGn2vQ==", + "dev": true, + "requires": { + "@sindresorhus/is": "0.7.0", + "cacheable-request": "2.1.4", + "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", + "lowercase-keys": "1.0.1", + "mimic-response": "1.0.0", + "p-cancelable": "0.4.1", + "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": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -8355,6 +9240,15 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, + "grouped-queue": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz", + "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, "growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", @@ -8369,6 +9263,7 @@ }, "gulp": { "version": "github:gulpjs/gulp#71c094a51c7972d26f557899ddecab0210ef3776", + "dev": true, "requires": { "glob-watcher": "4.0.0", "gulp-cli": "2.0.1", @@ -8380,6 +9275,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz", "integrity": "sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ==", + "dev": true, "requires": { "ansi-colors": "1.0.1", "archy": "1.0.0", @@ -8404,12 +9300,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, "requires": { "camelcase": "3.0.0", "cliui": "3.2.0", @@ -8430,6 +9328,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, "requires": { "camelcase": "3.0.0" } @@ -8541,98 +9440,157 @@ } } }, - "gulp-eslint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.0.tgz", - "integrity": "sha512-+qsePo04v1O3JshpNvww9+bOgZEJ6Cc2/w3mEktfKz0NL0zsh1SWzjyIL2FIM2zzy6IYQYv+j8REZORF8dKX4g==", + "gulp-debug": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/gulp-debug/-/gulp-debug-3.2.0.tgz", + "integrity": "sha512-2LZzP+ydczqz1rhqq/NYxvVvYTmOa0IgBl2B1sQTdkQgku9ayOUM/KHuGPjF4QA5aO1VcG+Sskw7iCcRUqHKkA==", "requires": { - "eslint": "4.14.0", - "gulp-util": "3.0.8" + "chalk": "2.3.2", + "fancy-log": "1.3.2", + "plur": "2.1.2", + "stringify-object": "3.2.2", + "through2": "2.0.3", + "tildify": "1.2.0" + }, + "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" + } + }, + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "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" + } + } } }, - "gulp-if": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz", - "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=", + "gulp-eslint": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.2.tgz", + "integrity": "sha512-fcFUQzFsN6dJ6KZlG+qPOEkqfcevRUXgztkYCvhNvJeSvOicC8ucutN4qR/ID8LmNZx9YPIkBzazTNnVvbh8wg==", "dev": true, "requires": { - "gulp-match": "1.0.3", - "ternary-stream": "2.0.1", - "through2": "2.0.3" + "eslint": "4.14.0", + "fancy-log": "1.3.2", + "plugin-error": "1.0.1" + }, + "dependencies": { + "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 + }, + "extend-shallow": { + "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" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "1.0.1", + "arr-diff": "4.0.0", + "arr-union": "3.1.0", + "extend-shallow": "3.0.2" + } + } } }, "gulp-json-editor": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.2.1.tgz", - "integrity": "sha1-fE3XR36NBtxdxJwLgedFzbBPl7s=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.3.0.tgz", + "integrity": "sha512-W5zv75lkZoLk/comlLZA0yriusdKCYqAPnUWWByAMiZE1QspCl67RIFlLGII1EasMvzrXbaqcG98ftK3hORe7g==", "dev": true, "requires": { - "deepmerge": "0.2.10", - "detect-indent": "2.0.0", - "gulp-util": "3.0.8", - "js-beautify": "1.5.10", - "through2": "0.5.1" + "deepmerge": "2.1.0", + "detect-indent": "5.0.0", + "js-beautify": "1.7.5", + "plugin-error": "1.0.1", + "through2": "2.0.3" }, "dependencies": { + "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 + }, "detect-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-2.0.0.tgz", - "integrity": "sha1-cg/1Hk2Xt2iE9r9XKSNIsT396Tk=", - "dev": true, - "requires": { - "get-stdin": "3.0.2", - "minimist": "1.2.0", - "repeating": "1.1.3" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", "dev": true }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" } }, - "repeating": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-plain-object": "2.0.4" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", "dev": true, "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" + "ansi-colors": "1.0.1", + "arr-diff": "4.0.0", + "arr-union": "3.1.0", + "extend-shallow": "3.0.2" } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true } } }, @@ -8712,13 +9670,13 @@ } } }, - "gulp-match": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz", - "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=", + "gulp-multi-process": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/gulp-multi-process/-/gulp-multi-process-1.3.1.tgz", + "integrity": "sha512-okxYy3mxUkekM0RNjkBg8OPuzpnD2yXMAdnGOaQPSJ2wzBdE9R9pkTV+tzPZ65ORK7b57YUc6s+gROA4+EIOLg==", "dev": true, "requires": { - "minimatch": "3.0.4" + "async.queue": "0.5.2" } }, "gulp-replace": { @@ -8728,45 +9686,51 @@ "dev": true, "requires": { "istextorbinary": "1.0.2", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "replacestream": "4.0.3" } }, "gulp-sass": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz", - "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.2.1.tgz", + "integrity": "sha512-UATbRpSDsyXCnpYSPBUEvdvtSEzksJs7/oQ0CujIpzKqKrO6vlnYwhX2UTsGrf4rNLwqlSSaM271It0uHYvJ3Q==", "requires": { "gulp-util": "3.0.8", "lodash.clonedeep": "4.5.0", - "node-sass": "4.7.2", + "node-sass": "4.8.3", "through2": "2.0.3", "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-sourcemaps": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.3.tgz", - "integrity": "sha1-EbAz91n5CeCl8Vt730esKcxU76Q=", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz", + "integrity": "sha1-y7IAhFCxvM5s0jv5gze+dRv24wo=", "dev": true, "requires": { "@gulp-sourcemaps/identity-map": "1.0.1", "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "5.3.0", + "acorn": "5.5.3", "convert-source-map": "1.1.3", "css": "2.2.1", - "debug-fabulous": "1.0.0", + "debug-fabulous": "1.1.0", "detect-newline": "2.1.0", "graceful-fs": "4.1.11", - "source-map": "0.4.4", + "source-map": "0.6.1", "strip-bom-string": "1.0.0", "through2": "2.0.3" }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "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 } } @@ -9117,12 +10081,12 @@ "dev": true, "requires": { "anymatch": "1.3.2", - "chokidar": "2.0.1", + "chokidar": "2.0.3", "glob-parent": "3.1.0", "gulp-util": "3.0.8", "object-assign": "4.1.1", "path-is-absolute": "1.0.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "slash": "1.0.0", "vinyl": "2.1.0", "vinyl-file": "2.0.0" @@ -9141,9 +10105,9 @@ "dev": true }, "braces": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", - "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", + "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", "dev": true, "requires": { "arr-flatten": "1.1.0", @@ -9152,22 +10116,43 @@ "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=", + "dev": true, + "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", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "chokidar": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.1.tgz", - "integrity": "sha512-rv5iP8ENhpqvDWr677rAXcB+SMoPQ1urd4ch79+PhM4lQwbATdJUQK69t0lJIKNB+VXpqxt5V1gvqs59XEPKnw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "dev": true, "requires": { "anymatch": "2.0.0", "async-each": "1.0.1", - "braces": "2.3.0", + "braces": "2.3.1", "fsevents": "1.1.3", "glob-parent": "3.1.0", "inherits": "2.0.3", @@ -9176,7 +10161,7 @@ "normalize-path": "2.1.1", "path-is-absolute": "1.0.1", "readdirp": "2.1.0", - "upath": "1.0.0" + "upath": "1.0.4" }, "dependencies": { "anymatch": { @@ -9185,12 +10170,22 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.5", + "micromatch": "3.1.10", "normalize-path": "2.1.1" } } } }, + "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" + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -9203,7 +10198,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": { @@ -9214,6 +10209,53 @@ "requires": { "is-descriptor": "0.1.6" } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "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 + } + } + }, + "extend-shallow": { + "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" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } } } }, @@ -9230,7 +10272,27 @@ "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": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "fill-range": { @@ -9243,6 +10305,17 @@ "is-number": "3.0.0", "repeat-string": "1.6.1", "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "glob-parent": { @@ -9306,25 +10379,6 @@ } } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -9373,24 +10427,48 @@ "dev": true }, "micromatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", - "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", - "braces": "2.3.0", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", + "braces": "2.3.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", "extglob": "2.0.4", "fragment-cache": "0.2.1", "kind-of": "6.0.2", - "nanomatch": "1.2.7", + "nanomatch": "1.2.9", "object.pick": "1.3.0", "regex-not": "1.0.0", "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "to-regex": "3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + }, + "dependencies": { + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + } } } } @@ -9446,23 +10524,6 @@ "ansi-regex": "2.1.1" } }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "has-binary2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz", @@ -9480,6 +10541,12 @@ } } }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", @@ -9489,7 +10556,8 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true }, "has-gulplog": { "version": "0.1.0", @@ -9499,10 +10567,26 @@ "sparkles": "1.0.0" } }, + "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 + }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-to-string-tag-x": { + "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" + } }, "has-unicode": { "version": "2.0.1", @@ -9655,6 +10739,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, "requires": { "parse-passwd": "1.0.0" } @@ -9823,9 +10908,15 @@ "domutils": "1.5.1", "entities": "1.1.1", "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, "http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", @@ -9961,7 +11052,7 @@ "requires": { "babel-preset-es2015": "6.24.1", "babelify": "7.3.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "through2": "2.0.3", "xtend": "4.0.1" } @@ -9969,9 +11060,9 @@ } }, "identicon.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/identicon.js/-/identicon.js-2.3.1.tgz", - "integrity": "sha512-PsxOTpq2Mwj2dgpHW50vcBdSebozcL9xKLIqRVkh2c4lqbCB75pkpdDKoKkVtTfpha/rl4BubXm3Q90vxlmUxQ==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/identicon.js/-/identicon.js-2.3.2.tgz", + "integrity": "sha1-v+u2bIBH84YzP/pZX+KRI0WgcI0=" }, "idna-uts46": { "version": "1.1.0", @@ -10009,7 +11100,8 @@ "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true }, "ignorepatterns": { "version": "1.1.0", @@ -10017,6 +11109,12 @@ "integrity": "sha1-rI9DbyI5td+2bV8NOpBKh6xnzF4=", "dev": true }, + "image-size": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.2.tgz", + "integrity": "sha512-pH3vDzpczdsKHdZ9xxR3O46unSjisgVx0IImay7Zz2EdhRVbCkj+nthx9OuuWEhakx9FAO+fNVGrF0rZ2oMOvw==", + "dev": true + }, "immediate": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", @@ -10025,7 +11123,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "in-publish": { "version": "2.0.0", @@ -10075,12 +11174,13 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true }, "inject-css": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inject-css/-/inject-css-0.1.1.tgz", - "integrity": "sha1-7z/8eOwCbJbiNV2g3zKRfjUmQVw=" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/inject-css/-/inject-css-0.1.2.tgz", + "integrity": "sha1-lJQ+OUTECbqKEfIuneMi7whl5Fo=" }, "inline-source-map": { "version": "0.5.0", @@ -10094,6 +11194,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, "requires": { "ansi-escapes": "3.0.0", "chalk": "2.3.0", @@ -10114,12 +11215,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "1.9.1" } @@ -10128,6 +11231,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", @@ -10137,12 +11241,14 @@ "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=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "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" @@ -10152,6 +11258,7 @@ "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" } @@ -10160,6 +11267,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "2.0.0" } @@ -10259,6 +11367,16 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "2.3.0", + "p-is-promise": "1.1.0" + } + }, "invariant": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", @@ -10280,20 +11398,20 @@ "optional": true }, "ipaddr.js": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", - "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" }, "irregular-plurals": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", - "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", - "dev": true + "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=" }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, "requires": { "is-relative": "1.0.0", "is-windows": "1.0.2" @@ -10416,12 +11534,14 @@ "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true }, "is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, "requires": { "is-primitive": "2.0.0" } @@ -10434,7 +11554,8 @@ "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true }, "is-finite": { "version": "1.0.2", @@ -10466,6 +11587,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, "requires": { "is-extglob": "1.0.0" } @@ -10500,12 +11622,14 @@ "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, "requires": { "kind-of": "3.2.2" } @@ -10516,35 +11640,60 @@ "integrity": "sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=", "dev": true }, - "is-odd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", - "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "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 + }, + "is-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", "dev": true, "requires": { - "is-number": "3.0.0" + "symbol-observable": "0.2.4" + }, + "dependencies": { + "symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true + } + } + }, + "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": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" } } }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true }, "is-path-in-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, "requires": { "is-path-inside": "1.0.1" } @@ -10553,6 +11702,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, "requires": { "path-is-inside": "1.0.2" } @@ -10580,17 +11730,20 @@ "is-posix-bracket": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true }, "is-property": { "version": "1.0.2", @@ -10608,13 +11761,13 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, "requires": { "is-unc-path": "1.0.0" } @@ -10622,7 +11775,23 @@ "is-resolvable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==" + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "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 + }, + "is-scoped": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-scoped/-/is-scoped-1.0.0.tgz", + "integrity": "sha1-RJypgpnnEwOCViieyytUDcQ3yzA=", + "dev": true, + "requires": { + "scoped-regex": "1.0.0" + } }, "is-stream": { "version": "1.1.0", @@ -10670,6 +11839,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, "requires": { "unc-path-regex": "0.1.2" } @@ -10682,7 +11852,8 @@ "is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=" + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true }, "is-whitespace-character": { "version": "1.0.1", @@ -10719,6 +11890,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, "requires": { "isarray": "1.0.0" } @@ -10747,6 +11919,16 @@ "textextensions": "1.0.2" } }, + "isurl": { + "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" + } + }, "jazzicon": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/jazzicon/-/jazzicon-1.5.0.tgz", @@ -10763,12 +11945,13 @@ "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==" }, "js-beautify": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.5.10.tgz", - "integrity": "sha1-TZU3FwJpk0SlFsomv1nwonu3Vxk=", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.5.tgz", + "integrity": "sha512-9OhfAqGOrD7hoQBLJMTA+BKuKmoEtTJXzZ7WDF/9gvjtey1koVLuZqIY6c51aPDjbNdNtIXAkiWKVhziawE9Og==", "dev": true, "requires": { "config-chain": "1.1.11", + "editorconfig": "0.13.3", "mkdirp": "0.5.1", "nopt": "3.0.6" } @@ -10793,6 +11976,7 @@ "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, "requires": { "argparse": "1.0.9", "esprima": "4.0.0" @@ -10804,55 +11988,157 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, + "jscodeshift": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.0.tgz", + "integrity": "sha512-JAcQINNMFpdzzpKJN8k5xXjF3XDuckB1/48uScSzcnNyK199iWEc9AxKL9OoX5144M2w5zEx9Qs4/E/eBZZUlw==", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "6.22.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-1": "6.24.1", + "babel-register": "6.26.0", + "babylon": "7.0.0-beta.43", + "colors": "1.2.1", + "flow-parser": "0.69.0", + "lodash": "4.17.4", + "micromatch": "2.3.11", + "neo-async": "2.5.0", + "node-dir": "0.1.8", + "nomnom": "1.8.1", + "recast": "0.14.7", + "temp": "0.8.3", + "write-file-atomic": "1.3.4" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "ast-types": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", + "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", + "dev": true + }, + "babylon": { + "version": "7.0.0-beta.43", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.43.tgz", + "integrity": "sha512-kvgnRG/fXBtvezILk/oxGGMHKUznYqRDrnNfj/aJ1r3b1Mqx4PO3vaUrkkJIfqxLM+uwzKGcmornX3NT4pu5xw==", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "colors": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", + "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", + "dev": true + }, + "nomnom": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", + "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "dev": true, + "requires": { + "chalk": "0.4.0", + "underscore": "1.6.0" + } + }, + "recast": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", + "integrity": "sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A==", + "dev": true, + "requires": { + "ast-types": "0.11.3", + "esprima": "4.0.0", + "private": "0.1.8", + "source-map": "0.6.1" + } + }, + "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 + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + } + } + }, "jsdom": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.5.1.tgz", - "integrity": "sha512-89ztIZ03aYK9f1uUrLXLsZndRge/JnZjzjpaN+lrse3coqz+8PR/dX4WLHpbF5fIKTXhDjFODOJw2328lPJ90g==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.7.0.tgz", + "integrity": "sha512-9NzSc4Iz4gN9p4uoPbBUzro21QdgL32swaWIaWS8eEVQ2I69fRJAy/MKyvlEIk0V7HtKgfMbbOKyTZUrzR2Hsw==", "dev": true, "requires": { "abab": "1.0.4", - "acorn": "5.3.0", + "acorn": "5.5.3", "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", "cssstyle": "0.2.37", - "domexception": "1.0.0", - "escodegen": "1.9.0", + "data-urls": "1.0.0", + "domexception": "1.0.1", + "escodegen": "1.9.1", "html-encoding-sniffer": "1.0.2", - "left-pad": "1.2.0", - "nwmatcher": "1.4.3", - "parse5": "3.0.3", + "left-pad": "1.3.0", + "nwmatcher": "1.4.4", + "parse5": "4.0.0", "pn": "1.1.0", "request": "2.83.0", "request-promise-native": "1.0.5", "sax": "1.2.4", "symbol-tree": "3.2.2", "tough-cookie": "2.3.3", + "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", - "xml-name-validator": "2.0.1" + "ws": "4.1.0", + "xml-name-validator": "3.0.0" }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "requires": { "esprima": "3.1.3", "estraverse": "4.2.0", "esutils": "2.0.2", "optionator": "0.8.2", - "source-map": "0.5.7" + "source-map": "0.6.1" } }, "esprima": { @@ -10861,12 +12147,28 @@ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true + }, + "ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "dev": true, + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1" + } } } }, @@ -10881,6 +12183,88 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" }, + "jshint": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", + "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "dev": true, + "requires": { + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.4", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" + }, + "dependencies": { + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + } + } + }, "jshint-stylish": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-2.2.1.tgz", @@ -10895,11 +12279,23 @@ "text-table": "0.2.0" } }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, "json-loader": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-rpc-engine": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz", @@ -10936,11 +12332,11 @@ "resolved": "https://registry.npmjs.org/json-rpc-middleware-stream/-/json-rpc-middleware-stream-1.0.1.tgz", "integrity": "sha512-IR6cOO6B21NdLpiYblueB3O+g3UAYLIZd6ZgZfddVPl0z6vSECcpuiYnV5MmIMJY3D0fLYpJqOxYaEmLYQqTtA==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "eth-block-tracker": "2.3.0", "ethjs-query": "0.2.9", "json-rpc-engine": "3.6.1", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "bn.js": { @@ -11012,19 +12408,14 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "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=" }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -11167,14 +12558,63 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, "requires": { "array-includes": "3.0.3" } }, + "jszip": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", + "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "dev": true, + "requires": { + "core-js": "2.3.0", + "es6-promise": "3.0.2", + "lie": "3.1.1", + "pako": "1.0.6", + "readable-stream": "2.0.6" + }, + "dependencies": { + "core-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", + "dev": true + }, + "es6-promise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "just-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "dev": true }, "just-extend": { "version": "1.1.27", @@ -11269,7 +12709,7 @@ "punycode": "1.4.1", "querystring-es3": "0.2.1", "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "resolve": "1.4.0", "shasum": "1.0.2", "shell-quote": "1.6.1", @@ -11352,7 +12792,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "inline-source-map": { @@ -11393,7 +12833,7 @@ "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "resolve": "1.4.0", "stream-combiner2": "1.1.1", "subarg": "1.0.0", @@ -11466,6 +12906,21 @@ "sha3": "1.2.0" } }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -11512,7 +12967,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } } } @@ -11521,6 +12976,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, "requires": { "default-resolution": "2.0.0", "es6-weak-map": "2.0.2" @@ -11538,8 +12994,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "lcid": { @@ -11606,14 +13063,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, "requires": { "flush-write-stream": "1.0.3" } }, "left-pad": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", - "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", "dev": true }, "leftpad": { @@ -11726,12 +13184,20 @@ "prr": "1.0.1", "semver": "5.4.1", "xtend": "4.0.1" + }, + "dependencies": { + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + } } }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, "requires": { "prelude-ls": "1.1.2", "type-check": "0.3.2" @@ -11777,10 +13243,28 @@ "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", "dev": true }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "dev": true, + "requires": { + "immediate": "3.0.6" + }, + "dependencies": { + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + } + } + }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, "requires": { "extend": "3.0.1", "findup-sync": "2.0.0", @@ -11792,6 +13276,132 @@ "resolve": "1.4.0" } }, + "listr": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz", + "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", + "dev": true, + "requires": { + "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.1", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "ora": "0.2.3", + "p-map": "1.2.0", + "rxjs": "5.5.8", + "stream-to-observable": "0.2.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz", + "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-truncate": "0.2.1", + "elegant-spinner": "1.0.1", + "figures": "1.7.0", + "indent-string": "3.2.0", + "log-symbols": "1.0.2", + "log-update": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "date-fns": "1.29.0", + "figures": "1.7.0" + }, + "dependencies": { + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + } + } + }, "livereload-js": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", @@ -11808,6 +13418,13 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "strip-bom": "2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } } }, "loader-runner": { @@ -11826,6 +13443,24 @@ "object-assign": "4.1.1" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -12077,6 +13712,49 @@ "chalk": "1.1.3" } }, + "log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "cli-cursor": "1.0.2" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + } + } + }, "log4js": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz", @@ -12093,7 +13771,7 @@ "mailgun-js": "0.7.15", "nodemailer": "2.7.2", "redis": "2.8.0", - "semver": "5.4.1", + "semver": "5.5.0", "slack-node": "0.2.0", "streamroller": "0.7.0" }, @@ -12312,14 +13990,14 @@ } }, "loglevel": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.0.tgz", - "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ=" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=" }, "lolex": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.1.tgz", - "integrity": "sha512-mQuW55GhduF3ppo+ZRUTz1PRjEh1hS5BbqU7d8D0ez2OKxHDod7StPPeAVKisZR5aLkHZjdGWSL42LSONUJsZw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", + "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", "dev": true }, "longest": { @@ -12344,6 +14022,12 @@ "signal-exit": "3.0.2" } }, + "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 + }, "lru-cache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", @@ -12367,6 +14051,15 @@ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.0.tgz", "integrity": "sha1-tlul/LNJopkkyOMz98alVi8uSEI=" }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "dev": true, + "requires": { + "vlq": "0.2.3" + } + }, "mailcomposer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", @@ -12444,6 +14137,15 @@ } } }, + "make-dir": { + "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" + } + }, "make-error": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", @@ -12463,6 +14165,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, "requires": { "kind-of": "6.0.2" }, @@ -12470,7 +14173,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -12512,6 +14216,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, "requires": { "findup-sync": "2.0.0", "micromatch": "3.1.10", @@ -12522,17 +14227,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, "requires": { "arr-flatten": "1.1.0", "array-unique": "0.3.2", @@ -12550,6 +14258,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -12560,6 +14269,7 @@ "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" @@ -12569,6 +14279,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, "requires": { "debug": "2.6.9", "define-property": "0.2.5", @@ -12583,6 +14294,7 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -12591,6 +14303,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -12599,6 +14312,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", "is-data-descriptor": "0.1.4", @@ -12608,7 +14322,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -12616,6 +14331,7 @@ "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" @@ -12625,6 +14341,7 @@ "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" } @@ -12635,6 +14352,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, "requires": { "array-unique": "0.3.2", "define-property": "1.0.0", @@ -12650,6 +14368,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, "requires": { "is-descriptor": "1.0.2" } @@ -12658,6 +14377,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -12668,6 +14388,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, "requires": { "extend-shallow": "2.0.1", "is-number": "3.0.0", @@ -12679,6 +14400,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, "requires": { "is-extendable": "0.1.1" } @@ -12689,6 +14411,7 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -12697,6 +14420,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -12707,6 +14431,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -12715,6 +14440,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -12725,6 +14451,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -12733,41 +14460,30 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.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", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", @@ -12784,29 +14500,11 @@ "to-regex": "3.0.2" } }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "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.2" - } - }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, "requires": { "define-property": "2.0.2", "extend-shallow": "3.0.2", @@ -12818,6 +14516,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, "requires": { "extend-shallow": "3.0.2", "safe-regex": "1.1.0" @@ -12867,6 +14566,108 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "mem-fs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz", + "integrity": "sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw=", + "dev": true, + "requires": { + "through2": "2.0.3", + "vinyl": "1.2.0", + "vinyl-file": "2.0.0" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.4", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "mem-fs-editor": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz", + "integrity": "sha1-3Qpuryu4prN3QAZ6pUnrUwEFr58=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "deep-extend": "0.4.2", + "ejs": "2.5.8", + "glob": "7.1.2", + "globby": "6.1.0", + "mkdirp": "0.5.1", + "multimatch": "2.1.0", + "rimraf": "2.6.2", + "through2": "2.0.3", + "vinyl": "2.1.0" + }, + "dependencies": { + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "dev": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "memdown": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", @@ -12891,9 +14692,9 @@ } }, "memoizee": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz", - "integrity": "sha1-vemBdmPJ5A/bKk6hw2cpYIeujI8=", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.12.tgz", + "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", "dev": true, "requires": { "d": "1.0.0", @@ -12903,7 +14704,7 @@ "is-promise": "2.1.0", "lru-queue": "0.1.0", "next-tick": "1.0.0", - "timers-ext": "0.1.2" + "timers-ext": "0.1.5" } }, "memory-fs": { @@ -12912,7 +14713,7 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "requires": { "errno": "0.1.6", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "memorystream": { @@ -12942,13 +14743,21 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", "dev": true, "requires": { - "readable-stream": "2.3.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=", + "dev": true + } } }, "merkle-patricia-tree": { @@ -12961,7 +14770,7 @@ "level-ws": "0.0.0", "levelup": "1.3.9", "memdown": "1.4.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "rlp": "2.0.0", "semaphore": "1.1.0" }, @@ -13008,7 +14817,7 @@ "requires": { "babel-preset-es2015": "6.24.1", "babelify": "7.3.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "through2": "2.0.3", "xtend": "4.0.1" } @@ -13018,16 +14827,16 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0" } } } }, "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" @@ -13042,6 +14851,7 @@ "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, "requires": { "arr-diff": "2.0.0", "array-unique": "0.2.1", @@ -13088,7 +14898,14 @@ "mimic-fn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "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 }, "min-document": { "version": "2.19.0", @@ -13260,15 +15077,15 @@ } }, "mocha": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz", - "integrity": "sha512-ukB2dF+u4aeJjc6IGtPNnJXfeby5d4ZqySlIBT0OEyva/DrMjVm5HkQxKnHDLKEfEQBsEnwTg9HHhtPHJdTd8w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", + "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", "dev": true, "requires": { - "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", @@ -13286,6 +15103,12 @@ "ms": "2.0.0" } }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", @@ -13336,7 +15159,7 @@ "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "resolve": "1.4.0", "stream-combiner2": "1.1.1", "subarg": "1.0.0", @@ -13361,7 +15184,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } } } @@ -13398,7 +15221,7 @@ "requires": { "duplexify": "3.5.1", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "varint": "4.0.1", "xtend": "4.0.1" } @@ -13412,12 +15235,14 @@ "mute-stdout": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.0.tgz", - "integrity": "sha1-WzLqB+tDyd7WEwQ0z5JvRrKn/U0=" + "integrity": "sha1-WzLqB+tDyd7WEwQ0z5JvRrKn/U0=", + "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true }, "mz": { "version": "2.7.0", @@ -13444,18 +15269,18 @@ "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=" }, "nanomatch": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", - "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", - "dev": true, + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", "fragment-cache": "0.2.1", - "is-odd": "1.0.0", - "kind-of": "5.1.0", + "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", @@ -13465,27 +15290,56 @@ "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==", + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.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" + } + }, + "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" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "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 + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "ncp": { "version": "1.0.1", @@ -13509,6 +15363,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "neo-async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", + "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==" + }, "netmask": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", @@ -13522,15 +15381,21 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "nice-try": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", + "dev": true + }, "nise": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.2.0.tgz", - "integrity": "sha512-q9jXh3UNsMV28KeqI43ILz5+c3l+RiNW8mhurEwCKckuHQbL+hTJIKKTiUlCPKlgQ/OukFvSnKB/Jk3+sFbkGA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.2.tgz", + "integrity": "sha512-KPKb+wvETBiwb4eTwtR/OsA2+iijXP+VnlSFYJo3EHjm2yjek1NWxHOUQat3i7xNLm1Bm18UA5j5Wor0yO2GtA==", "dev": true, "requires": { - "formatio": "1.2.0", + "@sinonjs/formatio": "2.0.0", "just-extend": "1.1.27", - "lolex": "1.6.0", + "lolex": "2.3.2", "path-to-regexp": "1.7.0", "text-encoding": "0.6.4" }, @@ -13541,12 +15406,6 @@ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -13559,58 +15418,45 @@ } }, "nock": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/nock/-/nock-9.1.5.tgz", - "integrity": "sha512-ukkBUhGU73CmSKTpTl6N/Qjvb7Hev4rCEjgOuEBKvHmsOqz7jGh2vUXL3dPnX3ndfcmVjsFBPfKpNuJbK94SKg==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.2.4.tgz", + "integrity": "sha512-asFxV9kWqELM1/7nixgH+tbCJdSHhFycwgkah7uaFHHVM+bHuCNJeJEgoijZEL5wy91kD4JSirWNmohbUGFZaA==", "dev": true, "requires": { - "chai": "3.5.0", - "debug": "2.6.9", + "chai": "4.1.2", + "debug": "3.1.0", "deep-equal": "1.0.1", "json-stringify-safe": "5.0.1", - "lodash": "4.17.4", + "lodash": "4.17.5", "mkdirp": "0.5.1", - "propagate": "0.4.0", + "propagate": "1.0.0", "qs": "6.5.1", - "semver": "5.4.1" + "semver": "5.5.0" }, "dependencies": { - "chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "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": { - "assertion-error": "1.0.2", - "deep-eql": "0.1.3", - "type-detect": "1.0.0" + "ms": "2.0.0" } }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "dev": true, - "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=", - "dev": true - } - } - }, - "type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true } } }, + "node-dir": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.8.tgz", + "integrity": "sha1-VfuN62mQcHB/tn+RpGDwRIKUx30=", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -13666,7 +15512,7 @@ "process": "0.11.10", "punycode": "1.4.1", "querystring-es3": "0.2.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-browserify": "2.0.1", "stream-http": "2.7.2", "string_decoder": "1.0.3", @@ -13709,15 +15555,15 @@ "dev": true, "requires": { "growly": "1.3.0", - "semver": "5.4.1", + "semver": "5.5.0", "shellwords": "0.1.1", "which": "1.3.0" } }, "node-sass": { - "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==", + "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", @@ -13731,7 +15577,7 @@ "lodash.mergewith": "4.6.1", "meow": "3.7.0", "mkdirp": "0.5.1", - "nan": "2.8.0", + "nan": "2.10.0", "node-gyp": "3.6.2", "npmlog": "4.1.2", "request": "2.79.0", @@ -13790,11 +15636,6 @@ "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", @@ -13832,6 +15673,11 @@ "sshpk": "1.13.1" } }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + }, "qs": { "version": "6.3.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", @@ -14008,7 +15854,7 @@ "requires": { "hosted-git-info": "2.5.0", "is-builtin-module": "1.0.0", - "semver": "5.4.1", + "semver": "5.5.0", "validate-npm-package-license": "3.0.1" } }, @@ -14031,10 +15877,22 @@ "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", "dev": true }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "2.0.0", + "query-string": "5.1.1", + "sort-keys": "2.0.0" + } + }, "now-and-later": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "dev": true, "requires": { "once": "1.4.0" } @@ -14101,15 +15959,15 @@ } }, "nwmatcher": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", - "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", "dev": true }, "nyc": { - "version": "11.4.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.4.1.tgz", - "integrity": "sha512-5eCZpvaksFVjP2rt1r60cfXmt3MUtsQDw8bAzNqNEr4WLvUMLgiVENMf/B9bE9YAX0mGVvaGA3v9IS9ekNqB1Q==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.6.0.tgz", + "integrity": "sha512-ZaXCh0wmbk2aSBH2B5hZGGvK2s9aM8DIm2rVY+BG3Fx8tUS+bpJSswUVZqOD1YfCmnYRFSqgYJSr7UeeUcW0jg==", "dev": true, "requires": { "archy": "1.0.0", @@ -14122,23 +15980,23 @@ "find-up": "2.1.0", "foreground-child": "1.5.6", "glob": "7.1.2", - "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-coverage": "1.2.0", "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.1", + "istanbul-lib-report": "1.1.3", + "istanbul-lib-source-maps": "1.2.3", + "istanbul-reports": "1.3.0", "md5-hex": "1.3.0", - "merge-source-map": "1.0.4", + "merge-source-map": "1.1.0", "micromatch": "2.3.11", "mkdirp": "0.5.1", "resolve-from": "2.0.0", "rimraf": "2.6.2", "signal-exit": "3.0.2", "spawn-wrap": "1.4.2", - "test-exclude": "4.1.1", - "yargs": "10.0.3", - "yargs-parser": "8.0.0" + "test-exclude": "4.2.1", + "yargs": "11.1.0", + "yargs-parser": "8.1.0" }, "dependencies": { "align-text": { @@ -14192,6 +16050,11 @@ "bundled": true, "dev": true }, + "arr-union": { + "version": "3.1.0", + "bundled": true, + "dev": true + }, "array-unique": { "version": "0.2.1", "bundled": true, @@ -14202,11 +16065,21 @@ "bundled": true, "dev": true }, + "assign-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, "async": { "version": "1.5.2", "bundled": true, "dev": true }, + "atob": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, "babel-code-frame": { "version": "6.26.0", "bundled": true, @@ -14218,7 +16091,7 @@ } }, "babel-generator": { - "version": "6.26.0", + "version": "6.26.1", "bundled": true, "dev": true, "requires": { @@ -14227,7 +16100,7 @@ "babel-types": "6.26.0", "detect-indent": "4.0.0", "jsesc": "1.3.0", - "lodash": "4.17.4", + "lodash": "4.17.5", "source-map": "0.5.7", "trim-right": "1.0.1" } @@ -14258,7 +16131,7 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "lodash": "4.17.4" + "lodash": "4.17.5" } }, "babel-traverse": { @@ -14273,8 +16146,8 @@ "babylon": "6.18.0", "debug": "2.6.9", "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" + "invariant": "2.2.3", + "lodash": "4.17.5" } }, "babel-types": { @@ -14284,7 +16157,7 @@ "requires": { "babel-runtime": "6.26.0", "esutils": "2.0.2", - "lodash": "4.17.4", + "lodash": "4.17.5", "to-fast-properties": "1.0.3" } }, @@ -14298,8 +16171,37 @@ "bundled": true, "dev": true }, + "base": { + "version": "0.11.2", + "bundled": true, + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "brace-expansion": { - "version": "1.1.8", + "version": "1.1.11", "bundled": true, "dev": true, "requires": { @@ -14322,6 +16224,29 @@ "bundled": true, "dev": true }, + "cache-base": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "caching-transform": { "version": "1.0.1", "bundled": true, @@ -14360,6 +16285,83 @@ "supports-color": "2.0.0" } }, + "class-utils": { + "version": "0.3.6", + "bundled": true, + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, "cliui": { "version": "2.1.0", "bundled": true, @@ -14384,11 +16386,25 @@ "bundled": true, "dev": true }, + "collection-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, "commondir": { "version": "1.0.1", "bundled": true, "dev": true }, + "component-emitter": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, "concat-map": { "version": "0.0.1", "bundled": true, @@ -14399,6 +16415,11 @@ "bundled": true, "dev": true }, + "copy-descriptor": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, "core-js": { "version": "2.5.3", "bundled": true, @@ -14409,7 +16430,7 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "which": "1.3.0" } }, @@ -14431,6 +16452,11 @@ "bundled": true, "dev": true }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, "default-require-extensions": { "version": "1.0.0", "bundled": true, @@ -14439,6 +16465,22 @@ "strip-bom": "2.0.0" } }, + "define-property": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "detect-indent": { "version": "4.0.0", "bundled": true, @@ -14484,7 +16526,7 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "shebang-command": "1.2.0", "which": "1.3.0" } @@ -14507,6 +16549,25 @@ "fill-range": "2.2.3" } }, + "extend-shallow": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, "extglob": { "version": "0.3.2", "bundled": true, @@ -14572,6 +16633,14 @@ "signal-exit": "3.0.2" } }, + "fragment-cache": { + "version": "0.2.1", + "bundled": true, + "dev": true, + "requires": { + "map-cache": "0.2.2" + } + }, "fs.realpath": { "version": "1.0.0", "bundled": true, @@ -14587,6 +16656,11 @@ "bundled": true, "dev": true }, + "get-value": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, "glob": { "version": "7.1.2", "bundled": true, @@ -14661,8 +16735,62 @@ "bundled": true, "dev": true }, + "has-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "hosted-git-info": { - "version": "2.5.0", + "version": "2.6.0", "bundled": true, "dev": true }, @@ -14686,7 +16814,7 @@ "dev": true }, "invariant": { - "version": "2.2.2", + "version": "2.2.3", "bundled": true, "dev": true, "requires": { @@ -14698,6 +16826,21 @@ "bundled": true, "dev": true }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, "is-arrayish": { "version": "0.2.1", "bundled": true, @@ -14716,6 +16859,38 @@ "builtin-modules": "1.1.1" } }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, "is-dotfile": { "version": "1.0.3", "bundled": true, @@ -14748,12 +16923,9 @@ } }, "is-fullwidth-code-point": { - "version": "1.0.0", + "version": "2.0.0", "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } + "dev": true }, "is-glob": { "version": "2.0.1", @@ -14771,6 +16943,36 @@ "kind-of": "3.2.2" } }, + "is-odd": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "bundled": true, + "dev": true + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "is-posix-bracket": { "version": "0.1.1", "bundled": true, @@ -14791,6 +16993,11 @@ "bundled": true, "dev": true }, + "is-windows": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, "isarray": { "version": "1.0.0", "bundled": true, @@ -14810,7 +17017,7 @@ } }, "istanbul-lib-coverage": { - "version": "1.1.1", + "version": "1.2.0", "bundled": true, "dev": true }, @@ -14823,25 +17030,25 @@ } }, "istanbul-lib-instrument": { - "version": "1.9.1", + "version": "1.10.1", "bundled": true, "dev": true, "requires": { - "babel-generator": "6.26.0", + "babel-generator": "6.26.1", "babel-template": "6.26.0", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "istanbul-lib-coverage": "1.1.1", - "semver": "5.4.1" + "istanbul-lib-coverage": "1.2.0", + "semver": "5.5.0" } }, "istanbul-lib-report": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "requires": { - "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-coverage": "1.2.0", "mkdirp": "0.5.1", "path-parse": "1.0.5", "supports-color": "3.2.3" @@ -14858,12 +17065,12 @@ } }, "istanbul-lib-source-maps": { - "version": "1.2.2", + "version": "1.2.3", "bundled": true, "dev": true, "requires": { "debug": "3.1.0", - "istanbul-lib-coverage": "1.1.1", + "istanbul-lib-coverage": "1.2.0", "mkdirp": "0.5.1", "rimraf": "2.6.2", "source-map": "0.5.7" @@ -14880,7 +17087,7 @@ } }, "istanbul-reports": { - "version": "1.1.3", + "version": "1.3.0", "bundled": true, "dev": true, "requires": { @@ -14948,7 +17155,7 @@ } }, "lodash": { - "version": "4.17.4", + "version": "4.17.5", "bundled": true, "dev": true }, @@ -14966,7 +17173,7 @@ } }, "lru-cache": { - "version": "4.1.1", + "version": "4.1.2", "bundled": true, "dev": true, "requires": { @@ -14974,6 +17181,19 @@ "yallist": "2.1.2" } }, + "map-cache": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, "md5-hex": { "version": "1.3.0", "bundled": true, @@ -14992,15 +17212,22 @@ "bundled": true, "dev": true, "requires": { - "mimic-fn": "1.1.0" + "mimic-fn": "1.2.0" } }, "merge-source-map": { - "version": "1.0.4", + "version": "1.1.0", "bundled": true, "dev": true, "requires": { - "source-map": "0.5.7" + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } } }, "micromatch": { @@ -15024,7 +17251,7 @@ } }, "mimic-fn": { - "version": "1.1.0", + "version": "1.2.0", "bundled": true, "dev": true }, @@ -15033,7 +17260,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -15041,6 +17268,25 @@ "bundled": true, "dev": true }, + "mixin-deep": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", "bundled": true, @@ -15054,15 +17300,51 @@ "bundled": true, "dev": true }, + "nanomatch": { + "version": "1.2.9", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, "normalize-package-data": { "version": "2.4.0", "bundled": true, "dev": true, "requires": { - "hosted-git-info": "2.5.0", + "hosted-git-info": "2.6.0", "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -15091,6 +17373,74 @@ "bundled": true, "dev": true }, + "object-copy": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "object.omit": { "version": "2.0.1", "bundled": true, @@ -15100,6 +17450,21 @@ "is-extendable": "0.1.1" } }, + "object.pick": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, "once": { "version": "1.4.0", "bundled": true, @@ -15138,18 +17503,26 @@ "dev": true }, "p-limit": { - "version": "1.1.0", + "version": "1.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "p-try": "1.0.0" + } }, "p-locate": { "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "p-limit": "1.1.0" + "p-limit": "1.2.0" } }, + "p-try": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, "parse-glob": { "version": "3.0.4", "bundled": true, @@ -15169,6 +17542,11 @@ "error-ex": "1.3.1" } }, + "pascalcase": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, "path-exists": { "version": "2.1.0", "bundled": true, @@ -15239,6 +17617,11 @@ } } }, + "posix-character-classes": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, "preserve": { "version": "0.2.0", "bundled": true, @@ -15329,6 +17712,15 @@ "is-equal-shallow": "0.1.3" } }, + "regex-not": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + }, "remove-trailing-separator": { "version": "1.1.0", "bundled": true, @@ -15367,6 +17759,16 @@ "bundled": true, "dev": true }, + "resolve-url": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "ret": { + "version": "0.1.15", + "bundled": true, + "dev": true + }, "right-align": { "version": "0.1.3", "bundled": true, @@ -15384,8 +17786,16 @@ "glob": "7.1.2" } }, + "safe-regex": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, "semver": { - "version": "5.4.1", + "version": "5.5.0", "bundled": true, "dev": true }, @@ -15394,6 +17804,27 @@ "bundled": true, "dev": true }, + "set-value": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, "shebang-command": { "version": "1.2.0", "bundled": true, @@ -15417,11 +17848,145 @@ "bundled": true, "dev": true }, + "snapdragon": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.1", + "use": "3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, "source-map": { "version": "0.5.7", "bundled": true, "dev": true }, + "source-map-resolve": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "atob": "2.0.3", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, "spawn-wrap": { "version": "1.4.2", "bundled": true, @@ -15436,23 +18001,111 @@ } }, "spdx-correct": { - "version": "1.0.2", + "version": "3.0.0", "bundled": true, "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", + "spdx-exceptions": { + "version": "2.1.0", "bundled": true, "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", + "version": "3.0.0", "bundled": true, "dev": true }, + "split-string": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, + "static-extend": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, "string-width": { "version": "2.1.1", "bundled": true, @@ -15467,11 +18120,6 @@ "bundled": true, "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, "strip-ansi": { "version": "4.0.0", "bundled": true, @@ -15509,15 +18157,249 @@ "dev": true }, "test-exclude": { - "version": "4.1.1", + "version": "4.2.1", "bundled": true, "dev": true, "requires": { "arrify": "1.0.1", - "micromatch": "2.3.11", + "micromatch": "3.1.9", "object-assign": "4.1.1", "read-pkg-up": "1.0.1", "require-main-filename": "1.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "braces": { + "version": "2.3.1", + "bundled": true, + "dev": true, + "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.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "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.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + }, + "micromatch": { + "version": "3.1.9", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + } + } } }, "to-fast-properties": { @@ -15525,6 +18407,44 @@ "bundled": true, "dev": true }, + "to-object-path": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "to-regex": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + } + } + }, "trim-right": { "version": "1.0.1", "bundled": true, @@ -15561,13 +18481,106 @@ "dev": true, "optional": true }, - "validate-npm-package-license": { - "version": "3.0.1", + "union-value": { + "version": "1.0.0", "bundled": true, "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "bundled": true, + "dev": true + }, + "use": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "which": { @@ -15603,6 +18616,14 @@ "strip-ansi": "3.0.1" }, "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, "string-width": { "version": "1.0.2", "bundled": true, @@ -15641,11 +18662,11 @@ "dev": true }, "yargs": { - "version": "10.0.3", + "version": "11.1.0", "bundled": true, "dev": true, "requires": { - "cliui": "3.2.0", + "cliui": "4.0.0", "decamelize": "1.2.0", "find-up": "2.1.0", "get-caller-file": "1.0.2", @@ -15656,35 +18677,49 @@ "string-width": "2.1.1", "which-module": "2.0.0", "y18n": "3.2.1", - "yargs-parser": "8.0.0" + "yargs-parser": "9.0.2" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, "cliui": { - "version": "3.2.0", + "version": "4.0.0", "bundled": true, "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" } } } }, "yargs-parser": { - "version": "8.0.0", + "version": "8.1.0", "bundled": true, "dev": true, "requires": { @@ -15716,9 +18751,9 @@ "resolved": "https://registry.npmjs.org/obj-multiplex/-/obj-multiplex-1.0.0.tgz", "integrity": "sha1-Lyrmv9SuEb7+dC6p6ls2Y26r/8E=", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "object-assign": { @@ -15786,9 +18821,10 @@ } }, "object-inspect": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", - "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", + "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==", + "dev": true }, "object-is": { "version": "1.0.1", @@ -15820,6 +18856,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, "requires": { "define-properties": "1.1.2", "function-bind": "1.1.1", @@ -15831,6 +18868,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, "requires": { "array-each": "1.0.1", "array-slice": "1.1.0", @@ -15842,6 +18880,7 @@ "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" } @@ -15849,7 +18888,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -15869,6 +18909,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, "requires": { "for-own": "1.0.0", "make-iterator": "1.0.1" @@ -15878,6 +18919,7 @@ "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" } @@ -15888,6 +18930,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, "requires": { "for-own": "0.1.5", "is-extendable": "0.1.1" @@ -15912,6 +18955,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, "requires": { "for-own": "1.0.0", "make-iterator": "1.0.1" @@ -15921,6 +18965,7 @@ "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" } @@ -15946,7 +18991,7 @@ "requires": { "babel-preset-es2015": "6.24.1", "babelify": "7.3.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "through2": "2.0.3", "xtend": "4.0.1" }, @@ -15994,6 +19039,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, "requires": { "mimic-fn": "1.1.0" } @@ -16029,6 +19075,7 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, "requires": { "deep-is": "0.1.3", "fast-levenshtein": "2.0.6", @@ -16041,22 +19088,57 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true } } }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true + "ora": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", + "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-spinners": "0.1.2", + "object-assign": "4.1.1" + }, + "dependencies": { + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + } + } }, "ordered-read-streams": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "os-browserify": { @@ -16100,18 +19182,84 @@ "shell-quote": "1.6.1" } }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true + }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "1.0.0" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, + "p-lazy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-lazy/-/p-lazy-1.0.0.tgz", + "integrity": "sha1-7FPIAvLuOsKPFmzILQsrAt4nqDU=", + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", "dev": true }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "pac-proxy-agent": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz", @@ -16196,6 +19344,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, "requires": { "is-absolute": "1.0.0", "map-cache": "0.2.2", @@ -16206,6 +19355,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, "requires": { "glob-base": "0.3.0", "is-dotfile": "1.0.3", @@ -16233,7 +19383,8 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true }, "parse5": { "version": "3.0.3", @@ -16244,15 +19395,6 @@ "@types/node": "8.5.5" } }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "1.0.2" - } - }, "parseqs": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", @@ -16307,7 +19449,8 @@ "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -16349,6 +19492,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, "requires": { "path-root-regex": "0.1.2" } @@ -16356,7 +19500,8 @@ "path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -16371,6 +19516,13 @@ "graceful-fs": "4.1.11", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } } }, "pathval": { @@ -16400,6 +19552,12 @@ "sha.js": "2.4.9" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "percentile": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/percentile/-/percentile-1.2.0.tgz", @@ -16411,18 +19569,18 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "ping-pong-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ping-pong-stream/-/ping-pong-stream-1.0.0.tgz", "integrity": "sha1-TF6wm6atsCGInawNyr+45XcGhUo=", "requires": { - "end-of-stream": "1.4.0", - "readable-stream": "2.3.3", - "tape": "4.8.0" + "end-of-stream": "1.4.1", + "readable-stream": "2.3.6", + "tape": "4.9.0" } }, "pinkie": { @@ -16523,7 +19681,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, "requires": { "irregular-plurals": "1.4.0" } @@ -16531,7 +19688,8 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true }, "pn": { "version": "1.1.0", @@ -16539,6 +19697,147 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, + "png-file-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/png-file-stream/-/png-file-stream-1.0.0.tgz", + "integrity": "sha1-4IPQ/lbgl6XL0NNBoThzeQUsrTU=", + "dev": true, + "requires": { + "glob-stream": "3.1.18", + "png-js": "0.1.1", + "through2": "0.2.3" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dev": true, + "requires": { + "glob": "4.5.3", + "glob2base": "0.0.12", + "minimatch": "2.0.10", + "ordered-read-streams": "0.1.0", + "through2": "0.6.5", + "unique-stream": "1.0.0" + }, + "dependencies": { + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", + "dev": true, + "requires": { + "readable-stream": "1.1.14", + "xtend": "2.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "0.4.0" + } + } + } + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "dev": true + } + } + }, + "png-js": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/png-js/-/png-js-0.1.1.tgz", + "integrity": "sha1-HMfCEjA6yr50Jj7DrHgAlYAkLZM=", + "dev": true + }, "pojo-migrator": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pojo-migrator/-/pojo-migrator-2.1.0.tgz", @@ -16584,7 +19883,7 @@ "resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz", "integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=", "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "postcss": { @@ -16854,12 +20153,26 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "prettier": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.11.1.tgz", + "integrity": "sha512-T/KD65Ot0PB97xTrG8afQ46x3oiVhnfGjGESSI9NWYcG92+OUPZKkwHqGWXH2t9jK1crnQjubECW0FuOth+hxw==", + "dev": true }, "pretty-bytes": { "version": "0.1.2", @@ -16870,7 +20183,8 @@ "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true }, "printf": { "version": "0.2.5", @@ -16891,12 +20205,14 @@ "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=" + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true }, "progress": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true }, "promise": { "version": "7.3.1", @@ -16956,9 +20272,9 @@ } }, "propagate": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", - "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", + "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", "dev": true }, "proto-list": { @@ -16968,12 +20284,12 @@ "dev": true }, "proxy-addr": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", - "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "requires": { "forwarded": "0.1.2", - "ipaddr.js": "1.5.2" + "ipaddr.js": "1.6.0" } }, "proxy-agent": { @@ -17013,6 +20329,15 @@ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, + "ps-tree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "dev": true, + "requires": { + "event-stream": "3.3.4" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -17035,26 +20360,37 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0" } }, "pumpify": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz", - "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz", + "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", "requires": { - "duplexify": "3.5.1", + "duplexify": "3.5.4", "inherits": "2.0.3", - "pump": "1.0.3" + "pump": "2.0.1" }, "dependencies": { - "pump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", - "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "duplexify": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", + "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "stream-shift": "1.0.0" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "1.4.1", "once": "1.4.0" } } @@ -17086,6 +20422,17 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, + "query-string": { + "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", + "strict-uri-encode": "1.1.0" + } + }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -17225,14 +20572,6 @@ "buffer-equal": "0.0.1", "minimist": "1.2.0", "through2": "2.0.3" - }, - "dependencies": { - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", - "dev": true - } } }, "raf": { @@ -17268,6 +20607,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, "requires": { "is-number": "3.0.0", "kind-of": "4.0.0" @@ -17277,6 +20617,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -17285,6 +20626,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -17295,6 +20637,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -17332,9 +20675,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.1", + "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.1.tgz", + "integrity": "sha512-p+e+yoQbq4YgXDonYIRZNL/Kov6+t5L0UNEHZeYNzjOkNNCXcwQ1Vi3pulgGBaOjqXNipkFsbpmnH7YI+GPSjw==" }, "raw-body": { "version": "2.3.2", @@ -17399,28 +20742,40 @@ } }, "react-hyperscript": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-hyperscript/-/react-hyperscript-3.0.0.tgz", - "integrity": "sha1-PBYBCzMXXea8Af0eutChapptyas=" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-hyperscript/-/react-hyperscript-3.2.0.tgz", + "integrity": "sha512-kf9VmxwCNqAImT3uDrCPJ8H5XdNzfSLps9x0qgJCH6OUCBiGAy1m9wHpedfr7GSuFqowhkNwv4ZuC40k3E/zRQ==" }, "react-input-autosize": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.1.2.tgz", - "integrity": "sha512-uAfIE4XEfBNXqjqQvd31Eoo20UkVk0xHJpfgP8HRT8gLczaN4LEmB1e2d8CJ5ziEt4clWnsk/1+QhTN27iO/EA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.1.tgz", + "integrity": "sha512-3+K4CD13iE4lQQ2WlF8PuV5htfmTRLH6MDnfndHM6LuBRszuXnuyIfE7nhSKt8AzRBZ50bu0sAhkNMeS5pxQQA==", "requires": { "prop-types": "15.6.0" } }, "react-markdown": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-3.1.4.tgz", - "integrity": "sha512-i8WueytRXbYzyJ2GemIOTMRx/NigPo8r4m3R/KvWD7r+PxPyc9ke66cI3DR7MBRSS+nVG82VWEgRDE1VaZUCqA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-3.3.0.tgz", + "integrity": "sha512-eVpQZ8D7NBnms95OhpIrNj6QSuiguSLm27hh1gOeBKZzap6Cr9gl+RXAzpEQpljIqopF6FS0EVkSDCiJEAp77A==", "requires": { - "prop-types": "15.6.0", - "remark-parse": "4.0.0", + "prop-types": "15.6.1", + "remark-parse": "5.0.0", "unified": "6.1.6", "unist-util-visit": "1.3.0", "xtend": "4.0.1" + }, + "dependencies": { + "prop-types": { + "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", + "object-assign": "4.1.1" + } + } } }, "react-motion": { @@ -17441,32 +20796,49 @@ } }, "react-redux": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz", - "integrity": "sha512-8taaaGu+J7PMJQDJrk/xiWEYQmdo3mkXw6wPr3K3LxvXis3Fymiq7c13S+Tpls/AyNUAsoONkU81AP0RA6y6Vw==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz", + "integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==", "requires": { - "hoist-non-react-statics": "2.3.1", + "hoist-non-react-statics": "2.5.0", "invariant": "2.2.2", - "lodash": "4.17.4", - "lodash-es": "4.17.4", + "lodash": "4.17.5", + "lodash-es": "4.17.8", "loose-envify": "1.3.1", "prop-types": "15.6.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz", + "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w==" + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "lodash-es": { + "version": "4.17.8", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.8.tgz", + "integrity": "sha512-I9mjAxengFAleSThFhhAhvba6fsO0hunb9/0sQ6qQihSZsJRBofv2rYH58WXaOb/O++eUmYpCLywSQ22GfU+sA==" + } } }, "react-select": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-1.1.0.tgz", - "integrity": "sha512-c4CdxweEHN9ra85HGWjSjIMBlJ5c0fsIXOymLFZS5UbZEQCiJGHnZTVLTt6/wDh8RKQnxl85gHUwzhG5XZLcyw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-1.2.1.tgz", + "integrity": "sha512-vaCgT2bEl+uTyE/uKOEgzE5Dc/wLtzhnBvoHCeuLoJWc4WuadN6WQDhoL42DW+TziniZK2Gaqe/wUXydI3NSaQ==", "requires": { "classnames": "2.2.5", "prop-types": "15.6.0", - "react-input-autosize": "2.1.2" + "react-input-autosize": "2.2.1" } }, "react-simple-file-input": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/react-simple-file-input/-/react-simple-file-input-2.0.1.tgz", - "integrity": "sha1-Fa1P/Hj+sbiCZJrWsBwDPvJ1ceY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-simple-file-input/-/react-simple-file-input-2.1.0.tgz", + "integrity": "sha1-0HQr5azXgb90bm95KwvHJM1cCfI=", "requires": { "prop-types": "15.6.0" } @@ -17482,9 +20854,9 @@ } }, "react-testutils-additions": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/react-testutils-additions/-/react-testutils-additions-15.3.0.tgz", - "integrity": "sha1-DulqWZj1TivaLPCjQwo0XfBLf2Q=", + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/react-testutils-additions/-/react-testutils-additions-15.3.1.tgz", + "integrity": "sha1-JlqASpCTUzDFxfyQqvtDwKZ4DPQ=", "dev": true, "requires": { "object-assign": "3.0.0", @@ -17531,12 +20903,11 @@ "integrity": "sha1-+z7HjDJw/pGWkrwx8UBBCLz0eF4=" }, "react-transition-group": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz", - "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.3.0.tgz", + "integrity": "sha512-OU3/swEL8y233u5ajTn3FIcQQ/b3XWjLXB6e2LnM1OK5JATtsyfJvPTZ8c/dawHNqjUltcdHRSpgMtPe7v07pw==", "requires": { "chain-function": "1.0.0", - "classnames": "2.2.5", "dom-helpers": "3.3.1", "loose-envify": "1.3.1", "prop-types": "15.6.0", @@ -17566,6 +20937,16 @@ "mute-stream": "0.0.7" } }, + "read-chunk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", + "integrity": "sha1-agTAkoAF7Z1C4aasVgDhnLx/9lU=", + "dev": true, + "requires": { + "pify": "3.0.0", + "safe-buffer": "5.1.1" + } + }, "read-file-stdin": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz", @@ -17581,7 +20962,7 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "read-pkg": { @@ -17604,17 +20985,32 @@ } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "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.2" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.1" + } + } } }, "readable-wrap": { @@ -17659,7 +21055,7 @@ "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "set-immediate-shim": "1.0.1" } }, @@ -17690,6 +21086,7 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, "requires": { "resolve": "1.4.0" } @@ -17794,6 +21191,7 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, "requires": { "is-equal-shallow": "0.1.3" } @@ -17837,9 +21235,9 @@ } }, "remark-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", "requires": { "collapse-white-space": "1.0.3", "is-alphabetical": "1.0.1", @@ -17862,6 +21260,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, "requires": { "is-buffer": "1.1.6", "is-utf8": "0.2.1" @@ -17871,6 +21270,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, "requires": { "remove-bom-buffer": "3.0.0", "safe-buffer": "5.1.1", @@ -17909,6 +21309,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, "requires": { "homedir-polyfill": "1.0.1", "is-absolute": "1.0.0", @@ -17929,7 +21330,7 @@ "requires": { "escape-string-regexp": "1.0.5", "object-assign": "4.1.1", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "request": { @@ -18030,6 +21431,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, "requires": { "caller-path": "0.1.0", "resolve-from": "1.0.1" @@ -18045,14 +21447,33 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, "requires": { "path-parse": "1.0.5" } }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, "requires": { "expand-tilde": "2.0.2", "global-modules": "1.0.0" @@ -18061,12 +21482,14 @@ "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true }, "resolve-options": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, "requires": { "value-or-function": "3.0.0" } @@ -18082,10 +21505,20 @@ "integrity": "sha1-2ksXzHaEyYyWK+tNlfZoyNytCdU=", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "1.0.1" + } + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, "requires": { "onetime": "2.0.1", "signal-exit": "3.0.2" @@ -18154,6 +21587,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, "requires": { "is-promise": "2.1.0" } @@ -18166,16 +21600,35 @@ "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true }, "rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, "requires": { "rx-lite": "4.0.8" } }, + "rxjs": { + "version": "5.5.8", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.8.tgz", + "integrity": "sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + }, + "dependencies": { + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + } + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -18273,6 +21726,12 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "scoped-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz", + "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", + "dev": true + }, "script-injector": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/script-injector/-/script-injector-1.0.0.tgz", @@ -18369,33 +21828,57 @@ "safe-buffer": "5.1.1" } }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "requires": { + "jszip": "3.1.5", + "rimraf": "2.6.2", + "tmp": "0.0.30", + "xml2js": "0.4.19" + }, + "dependencies": { + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + } + } + }, "semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "semver-greatest-satisfied-range": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, "requires": { "sver-compat": "1.5.0" } }, "send": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", - "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "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", @@ -18404,18 +21887,42 @@ "ms": "2.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", - "statuses": "1.3.1" + "statuses": "1.4.0" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } } }, "serve-static": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", - "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "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" + }, + "dependencies": { + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + } } }, "set-blocking": { @@ -18504,6 +22011,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, "requires": { "shebang-regex": "1.0.0" } @@ -18511,7 +22019,140 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-parallel": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/shell-parallel/-/shell-parallel-1.0.3.tgz", + "integrity": "sha512-h8uh4DChqYYstF2QXEyU1DaWIy0S9MaeH1HHWQfV91BV2ORJftRw3XjJtVHL9GopTpKXvTUYJ6uvcdwkxSFr9w==", + "dev": true, + "requires": { + "once": "1.4.0", + "pify": "3.0.0", + "ps-tree": "1.1.0", + "yargs": "11.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=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.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" + } + }, + "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 + }, + "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" + } + }, + "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" + } + }, + "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": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.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": "9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } }, "shell-quote": { "version": "1.6.1", @@ -18525,6 +22166,12 @@ "jsonify": "0.0.0" } }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", @@ -18543,16 +22190,16 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "sinon": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.1.3.tgz", - "integrity": "sha512-c7u0ZuvBRX1eXuB4jN3BRCAOGiUTlM8SE3TxbJHrNiHUKL7wonujMOB6Fi1gQc00U91IscFORQHDga/eccqpbw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.0.0.tgz", + "integrity": "sha512-dMX7ZB2E1iQ5DOEOePoNJQp03uyhdMfb+kLXlNPbquv2FwfezD+0GbbHSgCw4MFhpSSS9NMoYJfOPMjCMJtXWA==", "dev": true, "requires": { "diff": "3.3.1", "formatio": "1.2.0", "lodash.get": "4.4.2", - "lolex": "2.3.1", - "nise": "1.2.0", + "lolex": "2.3.2", + "nise": "1.3.2", "supports-color": "4.5.0", "type-detect": "4.0.5" }, @@ -18593,6 +22240,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, "requires": { "is-fullwidth-code-point": "2.0.0" }, @@ -18600,10 +22248,17 @@ "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=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true } } }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, "smart-buffer": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", @@ -18785,31 +22440,10 @@ } }, "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true }, "socket.io-client": { "version": "2.0.4", @@ -18864,42 +22498,29 @@ } }, "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" + "component-emitter": "1.2.1", + "debug": "3.1.0", + "isarray": "2.0.1" }, "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "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": "0.7.1" + "ms": "2.0.0" } }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", "dev": true } } @@ -18934,14 +22555,14 @@ } }, "solc": { - "version": "0.4.20", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.20.tgz", - "integrity": "sha512-LrP3Jp4FS3y8sduIR67y8Ss1riR3fggk5sMnx4OSCcU88Ro0e51+KVXyfH3NP6ghLo7COrLx/lGUaDDugCzdgA==", + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.21.tgz", + "integrity": "sha512-8lJmimVjOG9AJOQRWS2ph4rSctPMsPGZ4H360HLs5iI+euUlt7iAvUxSLeFZZzwk0kas4Qta7HmlMXNU3yYwhw==", "requires": { "fs-extra": "0.30.0", "memorystream": "0.3.1", "require-from-string": "1.2.1", - "semver": "5.4.1", + "semver": "5.5.0", "yargs": "4.8.1" }, "dependencies": { @@ -18977,6 +22598,15 @@ } } }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", @@ -19141,7 +22771,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "sshpk": { "version": "1.13.1", @@ -19161,7 +22792,8 @@ "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true }, "state-toggle": { "version": "1.0.0", @@ -19169,36 +22801,39 @@ "integrity": "sha1-0g+aYWu08MO5i5GSLSW2QKorxCU=" }, "static-eval": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-0.2.4.tgz", - "integrity": "sha1-t9NNg4k3uWn5ZBygfUj47eJj6ns=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz", + "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==", "dev": true, "requires": { - "escodegen": "0.0.28" + "escodegen": "1.9.1" }, "dependencies": { "escodegen": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.28.tgz", - "integrity": "sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "requires": { - "esprima": "1.0.4", - "estraverse": "1.3.2", - "source-map": "0.4.4" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" } }, "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, - "estraverse": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz", - "integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI=", - "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, + "optional": true } } }, @@ -19273,94 +22908,67 @@ } }, "static-module": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/static-module/-/static-module-1.5.0.tgz", - "integrity": "sha1-J9qYg8QajNCSNvhC8MHrxu32PYY=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.3.tgz", + "integrity": "sha512-OdNOIoJGjYH2OW9KZoGg4RfiBmtKkGijUFTH8w9oCRe8Q+CfVUuY/nlPZmqdsCFWMz2Ho0euzaJA/a6pUpCmZA==", "dev": true, "requires": { "concat-stream": "1.6.0", - "duplexer2": "0.0.2", - "escodegen": "1.3.3", + "convert-source-map": "1.5.1", + "duplexer2": "0.1.4", + "escodegen": "1.9.1", "falafel": "2.1.0", "has": "1.0.1", - "object-inspect": "0.4.0", - "quote-stream": "0.0.0", - "readable-stream": "1.0.34", + "magic-string": "0.22.5", + "merge-source-map": "1.0.4", + "object-inspect": "1.4.1", + "quote-stream": "1.0.2", + "readable-stream": "2.3.6", "shallow-copy": "0.0.1", - "static-eval": "0.2.4", - "through2": "0.4.2" + "static-eval": "2.0.0", + "through2": "2.0.3" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "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 }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "object-inspect": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-0.4.0.tgz", - "integrity": "sha1-9RV8EWwUVbJDsG7pdwM5LFrYn+w=", - "dev": true - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "quote-stream": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-0.0.0.tgz", - "integrity": "sha1-zeKelMQJsW4Z3HCYuJtmWPlyHTs=", + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "minimist": "0.0.8", - "through2": "0.4.2" + "readable-stream": "2.3.6" } }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "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, - "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" - } - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "0.4.0" - } + "optional": true } } }, @@ -19380,7 +22988,7 @@ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "stealthy-require": { @@ -19394,7 +23002,7 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "stream-combiner": { @@ -19413,7 +23021,7 @@ "dev": true, "requires": { "duplexer2": "0.1.4", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "duplexer2": { @@ -19422,7 +23030,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } } } @@ -19430,7 +23038,8 @@ "stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true }, "stream-http": { "version": "2.7.2", @@ -19439,7 +23048,7 @@ "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "to-arraybuffer": "1.0.1", "xtend": "4.0.1" } @@ -19499,6 +23108,15 @@ } } }, + "stream-to-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz", + "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", + "dev": true, + "requires": { + "any-observable": "0.2.0" + } + }, "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", @@ -19508,7 +23126,7 @@ "date-format": "1.2.0", "debug": "3.1.0", "mkdirp": "0.5.1", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "debug": { @@ -19522,6 +23140,12 @@ } } }, + "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 + }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -19531,6 +23155,12 @@ "strip-ansi": "3.0.1" } }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -19559,6 +23189,16 @@ "safe-buffer": "5.1.1" } }, + "stringify-object": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.2.tgz", + "integrity": "sha512-O696NF21oLiDy8PhpWu8AEqoZHw++QW6mUv0UvKZe8gWSdSvMXkiLufK7OmnP27Dro4GU5kb9U7JIO0mBuCRQg==", + "requires": { + "get-own-enumerable-property-symbols": "2.0.1", + "is-obj": "1.0.1", + "is-regexp": "1.0.0" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -19628,7 +23268,8 @@ "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=" + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true }, "style-search": { "version": "0.1.0", @@ -19674,6 +23315,14 @@ "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "has-flag": { @@ -19938,6 +23587,12 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", @@ -20140,6 +23795,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, "requires": { "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" @@ -20151,6 +23807,27 @@ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", "dev": true }, + "sw-controller": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sw-controller/-/sw-controller-1.0.3.tgz", + "integrity": "sha512-q+rS4v7kj1MPDxFRyl8GAICw/BbQzewd5HhVDNIPLnyvKtcpxi26fVXReUeUMRl4CRL/fX56PvKKqxtKhAaMpg==", + "requires": { + "babel-preset-es2015": "6.24.1", + "babel-runtime": "6.26.0", + "babelify": "7.3.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" + } + } + } + }, "sw-stream": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/sw-stream/-/sw-stream-2.0.2.tgz", @@ -20159,9 +23836,9 @@ "babel-preset-es2015": "6.24.1", "babel-runtime": "6.26.0", "babelify": "7.3.0", - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "pump": "1.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "through2": "2.0.3" }, "dependencies": { @@ -20179,7 +23856,7 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0" } } @@ -20226,6 +23903,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, "requires": { "ajv": "5.5.2", "ajv-keywords": "2.1.1", @@ -20238,12 +23916,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "1.9.1" } @@ -20252,6 +23932,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", @@ -20261,12 +23942,14 @@ "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=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "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" @@ -20276,6 +23959,7 @@ "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" } @@ -20284,6 +23968,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "2.0.0" } @@ -20298,7 +23983,7 @@ "requires": { "events-to-array": "1.1.2", "js-yaml": "3.10.0", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "tapable": { @@ -20307,9 +23992,9 @@ "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" }, "tape": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", - "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", + "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", "requires": { "deep-equal": "1.0.1", "defined": "1.0.0", @@ -20319,11 +24004,26 @@ "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" + }, + "dependencies": { + "object-inspect": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.5.0.tgz", + "integrity": "sha512-UmOFbHbwvv+XHj7BerrhVq+knjceBdkvU5AriwLMvhv2qi+e7DJzxfBeFpILEjVzCp+xA+W/pIf06RGPWlZNfw==" + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + } } }, "tar": { @@ -20336,22 +24036,28 @@ "inherits": "2.0.3" } }, - "ternary-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz", - "integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=", + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "dev": true, "requires": { - "duplexify": "3.5.1", - "fork-stream": "0.0.4", - "merge-stream": "1.0.1", - "through2": "2.0.3" + "os-tmpdir": "1.0.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } } }, "testem": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/testem/-/testem-2.0.0.tgz", - "integrity": "sha1-sFyWIAx6yYuumY1xyUwMU0WQfRM=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/testem/-/testem-2.2.1.tgz", + "integrity": "sha512-UqqvbvTUARxrp1F3+xi/3Bs+oj3f3nO4fskAnfGDgII6A3ebDw0kCYgLzwpb3PhWPt7NWyjRNlYckYrXZ2BaQg==", "dev": true, "requires": { "backbone": "1.3.3", @@ -20359,8 +24065,8 @@ "charm": "1.0.2", "commander": "2.11.0", "consolidate": "0.14.5", - "execa": "0.9.0", - "express": "4.16.2", + "execa": "0.10.0", + "express": "4.16.3", "fireworm": "0.7.1", "glob": "7.1.2", "http-proxy": "1.16.2", @@ -20376,164 +24082,90 @@ "npmlog": "4.1.2", "printf": "0.2.5", "rimraf": "2.6.2", - "socket.io": "1.6.0", + "socket.io": "2.1.0", "spawn-args": "0.2.0", "styled_string": "0.0.1", "tap-parser": "5.4.0", "xmldom": "0.1.27" }, "dependencies": { - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", - "dev": true, - "requires": { - "mime-types": "2.1.17", - "negotiator": "0.6.1" - } - }, - "after": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.1.tgz", - "integrity": "sha1-q11PuIP1loFtNRX495HAr0ht1ic=", - "dev": true - }, - "base64id": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz", - "integrity": "sha1-As4P3u4M709ACA4ec+g08LG/zj8=", - "dev": true - }, "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "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": "0.7.2" + "ms": "2.0.0" } }, "engine.io": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.0.tgz", - "integrity": "sha1-PutfJky3XbvsG6rqJtYfWk6s4qo=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", + "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", "dev": true, "requires": { - "accepts": "1.3.3", - "base64id": "0.1.0", + "accepts": "1.3.4", + "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.1", - "ws": "1.1.1" + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "ws": "3.3.3" } }, "engine.io-client": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.0.tgz", - "integrity": "sha1-e3MOQSdBQIdZbZvjyI0rxf22z1w=", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { "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.2", "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.3", + "xmlhttprequest-ssl": "1.5.5", "yeast": "0.1.2" } }, - "engine.io-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.1.tgz", - "integrity": "sha1-lVTxrjMQfW+9FwylRm0vgz9qB88=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "has-binary": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.6.tgz", - "integrity": "sha1-JTJvOc+k9hath4eJTjryz7x7bhA=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - }, "socket.io": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.6.0.tgz", - "integrity": "sha1-PkDZMmN+a9kjmBslyvfFPoO24uE=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.0.tgz", + "integrity": "sha512-KS+3CNWWNtLbVN5j0/B+1hjxRzey+oTK6ejpAOoxMZis6aXeB8cUtfuvjHl97tuZx+t/qD/VyqFMjuzu2Js6uQ==", "dev": true, "requires": { - "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" + "debug": "3.1.0", + "engine.io": "3.2.0", + "has-binary2": "1.0.2", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.1.0", + "socket.io-parser": "3.2.0" } }, "socket.io-client": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.6.0.tgz", - "integrity": "sha1-W2aPT3cTBN/u0XkGRwg4b6ZxeFM=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.0.tgz", + "integrity": "sha512-TvKPpL0cBON5LduQfR8Rxrr+ktj70bLXGvqHCL3er5avBXruB3gpnbaud5ikFYVfANH1gCABAvo0qN8Axpg2ew==", "dev": true, "requires": { "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": "3.1.0", + "engine.io-client": "3.2.1", + "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": "2.3.1", + "socket.io-parser": "3.2.0", "to-array": "0.1.4" } - }, - "ws": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.1.tgz", - "integrity": "sha1-CC3bbGQehdS7RR8D1S8G6r2x8Bg=", - "dev": true, - "requires": { - "options": "0.0.6", - "ultron": "1.0.2" - } } } }, @@ -20546,12 +24178,13 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "textarea-caret": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.0.2.tgz", - "integrity": "sha1-82DEhpmqGr9xhoCkOjGoUGZcLK8=" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz", + "integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q==" }, "textextensions": { "version": "1.0.2", @@ -20595,7 +24228,7 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "requires": { - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "xtend": "4.0.1" } }, @@ -20603,6 +24236,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, "requires": { "through2": "2.0.3", "xtend": "4.0.1" @@ -20615,11 +24249,25 @@ "dev": true, "optional": true }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "1.0.2" + } + }, "time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" }, + "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 + }, "timers-browserify": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", @@ -20638,9 +24286,9 @@ } }, "timers-ext": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", - "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.5.tgz", + "integrity": "sha512-tsEStd7kmACHENhsUPaxb8Jf8/+GZZxyNFQbZD07HQOyooOa6At1rQqjffgvg7n+dxscQa9cjjMdWhJtsP2sxg==", "dev": true, "requires": { "es5-ext": "0.10.37", @@ -20658,6 +24306,7 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, "requires": { "os-tmpdir": "1.0.2" } @@ -20666,6 +24315,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, "requires": { "is-absolute": "1.0.0", "is-negated-glob": "1.0.0" @@ -20699,7 +24349,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", - "dev": true, "requires": { "define-property": "0.2.5", "extend-shallow": "2.0.1", @@ -20710,7 +24359,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "0.1.6" } @@ -20719,7 +24367,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -20728,7 +24375,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -20739,7 +24385,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "3.2.2" }, @@ -20748,7 +24393,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "1.1.6" } @@ -20759,7 +24403,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", "is-data-descriptor": "0.1.4", @@ -20769,8 +24412,7 @@ "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 + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -20797,6 +24439,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, "requires": { "through2": "2.0.3" } @@ -20968,6 +24611,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, "requires": { "prelude-ls": "1.1.2" } @@ -21048,12 +24692,6 @@ } } }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, "umd": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", @@ -21062,7 +24700,8 @@ "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true }, "underscore": { "version": "1.4.4", @@ -21070,16 +24709,11 @@ "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=", "dev": true }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - }, "undertaker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", "integrity": "sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=", + "dev": true, "requires": { "arr-flatten": "1.1.0", "arr-map": "2.0.2", @@ -21095,7 +24729,8 @@ "undertaker-registry": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=" + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true }, "unherit": { "version": "1.1.0", @@ -21153,6 +24788,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, "requires": { "json-stable-stringify": "1.0.1", "through2-filter": "2.0.0" @@ -21235,23 +24871,16 @@ } } }, + "untildify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", + "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=", + "dev": true + }, "upath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.0.tgz", - "integrity": "sha1-tHBrlGHKhHOt+JEz0jVonKF/NlY=", - "dev": true, - "requires": { - "lodash": "3.10.1", - "underscore.string": "2.3.3" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", + "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==" }, "urix": { "version": "0.1.0", @@ -21274,6 +24903,21 @@ } } }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "2.0.0" + } + }, + "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 + }, "use": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", @@ -21430,10 +25074,17 @@ "dev": true, "optional": true }, + "v8-compile-cache": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz", + "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==", + "dev": true + }, "v8flags": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz", "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==", + "dev": true, "requires": { "homedir-polyfill": "1.0.1" } @@ -21455,7 +25106,8 @@ "value-or-function": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true }, "varint": { "version": "4.0.1", @@ -21505,8 +25157,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, "requires": { - "clone": "2.1.1", + "clone": "2.1.2", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", "cloneable-readable": "1.0.0", @@ -21539,9 +25192,9 @@ }, "dependencies": { "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-stats": { @@ -21550,6 +25203,12 @@ "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", "dev": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", @@ -21562,7 +25221,7 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -21573,6 +25232,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.2.tgz", "integrity": "sha512-AUSFda1OukBwuLPBTbyuO4IRWgfXmqC4UTW0f8xrCa8Hkv9oyIU+NSqBlgfOLZRoUt7cHdo75hKQghCywpIyIw==", + "dev": true, "requires": { "fs-mkdirp-stream": "1.0.0", "glob-stream": "6.1.0", @@ -21581,8 +25241,8 @@ "lazystream": "1.0.0", "lead": "1.0.0", "object.assign": "4.1.0", - "pumpify": "1.3.5", - "readable-stream": "2.3.3", + "pumpify": "1.4.0", + "readable-stream": "2.3.6", "remove-bom-buffer": "3.0.0", "remove-bom-stream": "1.2.0", "resolve-options": "1.1.0", @@ -21607,6 +25267,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, "requires": { "append-buffer": "1.0.2", "convert-source-map": "1.5.1", @@ -21620,7 +25281,8 @@ "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=" + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true } } }, @@ -21639,6 +25301,12 @@ } } }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", @@ -21658,6 +25326,15 @@ "resolved": "https://registry.npmjs.org/vreme/-/vreme-3.0.2.tgz", "integrity": "sha1-RyE3a0SUV/796KhJ0zQJM7kLVoY=" }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "0.1.2" + } + }, "walk-sync": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.1.tgz", @@ -21677,203 +25354,362 @@ } }, "watchify": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.9.0.tgz", - "integrity": "sha1-8HX9LoqGrN6Eztum5cKgvt1SPZ4=", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.0.tgz", + "integrity": "sha512-7jWG0c3cKKm2hKScnSAMUEUjRJKXUShwMPk0ASVhICycQhwND3IMAdhJYmc1mxxKzBUJTSF5HZizfrKrS6BzkA==", "dev": true, "requires": { "anymatch": "1.3.2", - "browserify": "14.5.0", + "browserify": "16.1.1", "chokidar": "1.7.0", "defined": "1.0.0", "outpipe": "1.1.1", "through2": "2.0.3", "xtend": "4.0.1" - }, - "dependencies": { - "browser-pack": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", - "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.8.0", - "defined": "1.0.0", - "safe-buffer": "5.1.1", - "through2": "2.0.3", - "umd": "3.0.1" - } - }, - "browserify": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", - "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "assert": "1.4.1", - "browser-pack": "6.0.4", - "browser-resolve": "1.11.2", - "browserify-zlib": "0.2.0", - "buffer": "5.1.0", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "defined": "1.0.0", - "deps-sort": "2.0.0", - "domain-browser": "1.1.7", - "duplexer2": "0.1.4", - "events": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "htmlescape": "1.1.1", - "https-browserify": "1.0.0", - "inherits": "2.0.3", - "insert-module-globals": "7.0.2", - "labeled-stream-splicer": "2.0.0", - "module-deps": "4.1.1", - "os-browserify": "0.3.0", - "parents": "1.0.1", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", - "resolve": "1.4.0", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.7.2", - "string_decoder": "1.0.3", - "subarg": "1.0.0", - "syntax-error": "1.4.0", - "through2": "2.0.3", - "timers-browserify": "1.4.2", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4", - "xtend": "4.0.1" - } - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", - "dev": true, - "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" - } - }, - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, - "module-deps": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", - "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "browser-resolve": "1.11.2", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "defined": "1.0.0", - "detective": "4.7.1", - "duplexer2": "0.1.4", - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.3", - "resolve": "1.4.0", - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", - "xtend": "4.0.1" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "watchpack": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", - "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", + "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", "requires": { - "async": "2.6.0", - "chokidar": "1.7.0", - "graceful-fs": "4.1.11" + "chokidar": "2.0.3", + "graceful-fs": "4.1.11", + "neo-async": "2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "3.1.10", + "normalize-path": "2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "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=" + }, + "braces": { + "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", + "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.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "chokidar": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.1.3", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.0.4" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "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==" + } + } + }, + "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" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "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.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", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "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==" + }, + "micromatch": { + "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.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.2" + } + }, + "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": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "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" + } + } + } + } } }, "weak": { @@ -21887,9 +25723,9 @@ } }, "web3": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", - "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", + "version": "0.20.6", + "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", + "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "3.1.8", @@ -21904,35 +25740,35 @@ } }, "web3-provider-engine": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.0.tgz", - "integrity": "sha512-iCsAlAeLWHxgx6EXuBm5GNg5VBqKtzmnrhEOfJBv8Cetukush7yOvo4RPjDZIynKxg9jfAlMmWqCk6wLxA6coQ==", + "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", + "clone": "2.1.2", "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.1.4", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.1.5", "ethereumjs-vm": "2.3.2", "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", + "readable-stream": "2.3.6", "request": "2.83.0", "semaphore": "1.1.0", - "solc": "0.4.20", - "tape": "4.8.0", + "solc": "0.4.21", + "tape": "4.9.0", "xhr": "2.4.1", "xtend": "4.0.1" }, "dependencies": { "ethereumjs-util": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.4.tgz", - "integrity": "sha512-wbeTc5prEzIWFSQUcEsCAZbqubtJKy6yS+oZMY1cGG6GLYzLjm4YhC2RNrWIg8hRYnclWpnZmx2zkiufQkmd3w==", + "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", @@ -21950,7 +25786,7 @@ "resolved": "https://registry.npmjs.org/web3-stream-provider/-/web3-stream-provider-3.0.1.tgz", "integrity": "sha1-9aWTqO7+gI+F61+x80Tlg4BQ+BQ=", "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "webidl-conversions": { @@ -21964,7 +25800,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.7.0.tgz", "integrity": "sha512-MjAA0ZqO1ba7ZQJRnoCdbM56mmFpipOPUv/vQpwwfSI42p5PVDdoiuK2AL2FwFUVgT859Jr43bFZXRg/LNsqvg==", "requires": { - "acorn": "5.4.1", + "acorn": "5.5.3", "acorn-dynamic-import": "2.0.2", "ajv": "4.11.8", "ajv-keywords": "1.5.1", @@ -21982,15 +25818,15 @@ "supports-color": "3.2.3", "tapable": "0.2.8", "uglify-js": "2.8.29", - "watchpack": "1.4.0", + "watchpack": "1.5.0", "webpack-sources": "1.1.0", "yargs": "6.6.0" }, "dependencies": { "acorn": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz", - "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==" + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==" }, "ajv": { "version": "4.11.8", @@ -22074,6 +25910,406 @@ } } }, + "webpack-addons": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/webpack-addons/-/webpack-addons-1.1.5.tgz", + "integrity": "sha512-MGO0nVniCLFAQz1qv22zM02QPjcpAoJdy7ED0i3Zy7SY1IecgXCm460ib7H/Wq7e9oL5VL6S2BxaObxwIcag0g==", + "dev": true, + "requires": { + "jscodeshift": "0.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "ast-types": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz", + "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "colors": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", + "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", + "dev": true + }, + "jscodeshift": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.4.1.tgz", + "integrity": "sha512-iOX6If+hsw0q99V3n31t4f5VlD1TQZddH08xbT65ZqA7T4Vkx68emrDZMUOLVvCEAJ6NpAk7DECe3fjC/t52AQ==", + "dev": true, + "requires": { + "async": "1.5.2", + "babel-plugin-transform-flow-strip-types": "6.22.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-1": "6.24.1", + "babel-register": "6.26.0", + "babylon": "6.18.0", + "colors": "1.2.1", + "flow-parser": "0.69.0", + "lodash": "4.17.4", + "micromatch": "2.3.11", + "node-dir": "0.1.8", + "nomnom": "1.8.1", + "recast": "0.12.9", + "temp": "0.8.3", + "write-file-atomic": "1.3.4" + } + }, + "nomnom": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", + "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", + "dev": true, + "requires": { + "chalk": "0.4.0", + "underscore": "1.6.0" + } + }, + "recast": { + "version": "0.12.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz", + "integrity": "sha512-y7ANxCWmMW8xLOaiopiRDlyjQ9ajKRENBH+2wjntIbk3A6ZR1+BLQttkmSHMY7Arl+AAZFwJ10grg2T6f1WI8A==", + "dev": true, + "requires": { + "ast-types": "0.10.1", + "core-js": "2.5.3", + "esprima": "4.0.0", + "private": "0.1.8", + "source-map": "0.6.1" + } + }, + "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 + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + } + } + }, + "webpack-cli": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.0.13.tgz", + "integrity": "sha512-0lnOi3yla8FsZVuMsbfnNRB/8DlfuDugKdekC+4ykydZG0+UOidMi5J5LLWN4c0VJ8PqC19yMXXkYyCq78OuqA==", + "dev": true, + "requires": { + "chalk": "2.3.2", + "cross-spawn": "6.0.5", + "diff": "3.5.0", + "enhanced-resolve": "4.0.0", + "glob-all": "3.1.0", + "global-modules": "1.0.0", + "got": "8.3.0", + "inquirer": "5.2.0", + "interpret": "1.1.0", + "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.11.1", + "resolve-cwd": "2.0.0", + "supports-color": "5.3.0", + "v8-compile-cache": "1.1.2", + "webpack-addons": "1.1.5", + "yargs": "11.0.0", + "yeoman-environment": "2.0.6", + "yeoman-generator": "2.0.3" + }, + "dependencies": { + "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.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" + } + }, + "cliui": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.5.0", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "enhanced-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz", + "integrity": "sha512-jox/62b2GofV1qTUQTMPEJSDIGycS43evqYzD/KVtEb9OCoki9cnacUPxCrZa7JfPzZSYOCZhu9O9luaMxAX8g==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "tapable": "1.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" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.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 + }, + "inquirer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", + "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.2", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.5", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rxjs": "5.5.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "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 + }, + "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": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "2.3.2" + } + }, + "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" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "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" + } + }, + "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==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "dev": true + }, + "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": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.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": "9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, "webpack-sources": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", @@ -22120,6 +26356,12 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" }, + "whatwg-mimetype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", + "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", + "dev": true + }, "whatwg-url": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz", @@ -22222,10 +26464,22 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, "requires": { "mkdirp": "0.5.1" } }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, "write-file-stdout": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/write-file-stdout/-/write-file-stdout-0.0.2.tgz", @@ -22251,12 +26505,6 @@ } } }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, "x-is-function": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", @@ -22284,9 +26532,25 @@ "integrity": "sha1-y/xHWaabSoiOeM9PILBRA4dXvRE=" }, "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.7" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, "xmldom": { @@ -22301,9 +26565,9 @@ "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" }, "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", "dev": true }, "xregexp": { @@ -22356,6 +26620,15 @@ "camelcase": "3.0.0" } }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "1.0.1" + } + }, "yazl": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz", @@ -22370,6 +26643,293 @@ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", "dev": true + }, + "yeoman-environment": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.6.tgz", + "integrity": "sha512-jzHBTTy8EPI4ImV8dpUMt+Q5zELkSU5xvGpndHcHudQ4tqN6YgIWaCGmRFl+HDchwRUkcgyjQ+n6/w5zlJBCPg==", + "dev": true, + "requires": { + "chalk": "2.3.2", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "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.2.0", + "mem-fs": "1.1.3", + "text-table": "0.2.0", + "untildify": "3.0.2" + }, + "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==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.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" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "2.3.2" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "yeoman-generator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.3.tgz", + "integrity": "sha512-mODmrZ26a94djmGZZuIiomSGlN4wULdou29ZwcySupb2e9FdvoCl7Ps2FqHFjEHio3kOl/iBeaNqrnx3C3NwWg==", + "dev": true, + "requires": { + "async": "2.6.0", + "chalk": "2.3.2", + "cli-table": "0.3.1", + "cross-spawn": "5.1.0", + "dargs": "5.1.0", + "dateformat": "3.0.3", + "debug": "3.1.0", + "detect-conflict": "1.0.1", + "error": "7.0.2", + "find-up": "2.1.0", + "github-username": "4.1.0", + "istextorbinary": "2.2.1", + "lodash": "4.17.4", + "make-dir": "1.2.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.3.0", + "shelljs": "0.8.1", + "text-table": "0.2.0", + "through2": "2.0.3", + "yeoman-environment": "2.0.6" + }, + "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==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "binaryextensions": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.1.tgz", + "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", + "dev": true + }, + "chalk": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "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" + } + }, + "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 + }, + "istextorbinary": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", + "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", + "dev": true, + "requires": { + "binaryextensions": "2.1.1", + "editions": "1.3.4", + "textextensions": "2.2.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "3.0.0" + } + }, + "shelljs": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.1.tgz", + "integrity": "sha512-YA/iYtZpzFe5HyWVGrb02FjPxc4EMCfpoU/Phg9fQoyMC72u9598OUBrsU8IrtwAKG0tO8IYaqbaLIw+k3IRGA==", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "textextensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.2.0.tgz", + "integrity": "sha512-j5EMxnryTvKxwH2Cq+Pb43tsf6sdEgw6Pdwxk83mPaq0ToeFJt6WE4J3s5BqY7vmjlLgkgXvhtXUxo80FyBhCA==", + "dev": true + } + } } } } diff --git a/package.json b/package.json index ac4758f57..d154db1ec 100644 --- a/package.json +++ b/package.json @@ -4,40 +4,39 @@ "public": false, "private": true, "scripts": { - "start": "npm run dev", - "dev": "gulp dev --debug", - "ui": "npm run test:flat:build:states && beefy development/ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", - "mock": "beefy development/mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", - "watch": "mocha watch --recursive \"test/unit/**/*.js\"", - "mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server", - "dist": "npm run dist:clear && npm install && gulp dist", - "dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect", + "start": "gulp dev:extension", + "mascara": "gulp dev:mascara & node ./mascara/example/server", + "dist": "gulp dist", "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: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", + "test:e2e": "shell-parallel -s 'npm run ganache:start' -x 'sleep 3 && npm run test:e2e:run'", + "test:e2e:run": "mocha test/e2e/metamask.spec --recursive", + "test:screens": "shell-parallel -s 'npm run ganache:start' -x 'sleep 3 && npm run test:screens:run'", + "test:screens:run": "node test/screens/new-ui.js", "test:coverage": "nyc npm run test:unit && npm run test:coveralls-upload", "test:coveralls-upload": "if [ $COVERALLS_REPO_TOKEN ]; then nyc report --reporter=text-lcov | coveralls; fi", "test:flat": "npm run test:flat:build && karma start test/flat.conf.js", - "test:flat:build": "npm run test:flat:build:ui && npm run test:flat:build:tests", + "test:flat:build": "npm run test:flat:build:ui && npm run test:flat:build:tests && npm run test:flat:build:locales", "test:flat:build:tests": "node test/integration/index.js", "test:flat:build:states": "node development/genStates.js", + "test:flat:build:locales": "mkdirp dist/chrome && cp -R app/_locales dist/chrome/_locales", "test:flat:build:ui": "npm run test:flat:build:states && browserify ./development/mock-dev.js -o ./development/bundle.js", "test:mascara": "npm run test:mascara:build && karma start test/mascara.conf.js", - "test:mascara:build": "mkdirp dist/mascara && npm run test:mascara:build:ui && npm run test:mascara:build:background && npm run test:mascara:build:tests", + "test:mascara:build": "mkdirp dist/mascara && npm run test:mascara:build:ui && npm run test:mascara:build:background && npm run test:mascara:build:tests && npm run test:mascara:build:locales", "test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js", + "test:mascara:build:locales": "mkdirp dist/chrome && cp -R app/_locales dist/chrome/_locales", "test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js", "test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js", - "sentry": "export RELEASE=`cat app/manifest.json| jq -r .version` && npm run sentry:release && npm run sentry:upload", - "sentry:release": "npm run sentry:release:new && npm run sentry:release:clean", - "sentry:release:new": "sentry-cli releases --org 'metamask' --project 'metamask' new $RELEASE", - "sentry:release:clean": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE delete --all", - "sentry:upload": "npm run sentry:upload:source && npm run sentry:upload:maps", - "sentry:upload:source": "for FILEPATH in ./dist/chrome/scripts/*.js; do [ -e $FILEPATH ] || continue; export FILE=`basename $FILEPATH` && echo uploading $FILE && sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload $FILEPATH metamask/scripts/$FILE; done;", - "sentry:upload:maps": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload-sourcemaps ./dist/sourcemaps/ --url-prefix 'sourcemaps' --rewrite", + "ganache:start": "ganache-cli -m 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'", + "sentry:publish": "node ./development/sentry-publish.js", "lint": "gulp lint", "lint:fix": "gulp lint:fix", + "ui": "npm run test:flat:build:states && beefy development/ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", + "mock": "beefy development/mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", + "watch": "mocha watch --recursive \"test/unit/**/*.js\"", "disc": "gulp disc --debug", "announce": "node development/announcer.js", "version:bump": "node development/run-version-bump.js", @@ -56,18 +55,17 @@ } ], "reactify", - "envify", "brfs" ] }, "dependencies": { - "abi-decoder": "^1.0.9", + "abi-decoder": "^1.1.0", "asmcrypto.js": "0.22.0", "async": "^2.5.0", "await-semaphore": "^0.1.1", "babel-runtime": "^6.23.0", "bignumber.js": "^4.1.0", - "bip39": "^2.2.0", + "bip39": "^2.5.0", "bluebird": "^3.5.0", "bn.js": "^4.11.7", "boron": "^0.2.3", @@ -75,8 +73,7 @@ "browserify-derequire": "^0.9.4", "browserify-unibabel": "^3.0.0", "classnames": "^2.2.5", - "client-sw-ready-event": "^3.3.0", - "clone": "^2.1.1", + "clone": "^2.1.2", "copy-to-clipboard": "^3.0.8", "debounce": "^1.0.0", "debounce-stream": "^2.0.0", @@ -84,46 +81,44 @@ "detect-node": "^2.0.3", "disc": "^1.3.2", "dnode": "^1.2.2", - "end-of-stream": "^1.1.0", + "end-of-stream": "^1.4.1", "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-contract-metadata": "^1.7.0", "eth-hd-keyring": "^1.2.1", "eth-json-rpc-filters": "^1.2.5", "eth-json-rpc-infura": "^3.0.0", "eth-keyring-controller": "^2.1.4", - "eth-phishing-detect": "^1.1.4", + "eth-phishing-detect": "^1.1.13", "eth-query": "^2.1.2", "eth-sig-util": "^1.4.2", "eth-token-tracker": "^1.1.4", "ethereumjs-abi": "^0.6.4", - "ethereumjs-tx": "^1.3.0", + "ethereumjs-tx": "^1.3.4", "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-ens": "^2.0.0", - "ethjs-query": "^0.3.1", - "express": "^4.15.5", + "ethjs-query": "^0.3.4", + "express": "^4.16.3", "extension-link-enabler": "^1.0.0", - "extensionizer": "^1.0.0", + "extensionizer": "^1.0.1", "fast-json-patch": "^2.0.4", "fast-levenshtein": "^2.0.6", "fuse.js": "^3.2.0", - "gulp": "github:gulpjs/gulp#4.0", "gulp-autoprefixer": "^5.0.0", - "gulp-eslint": "^4.0.0", - "gulp-sass": "^3.1.0", + "gulp-debug": "^3.2.0", + "gulp-sass": "^3.2.1", "hat": "0.0.3", "human-standard-token-abi": "^1.0.2", "idb-global": "^2.1.0", - "identicon.js": "^2.3.1", + "identicon.js": "^2.3.2", "iframe": "^1.0.0", "iframe-stream": "^3.0.0", - "inject-css": "^0.1.1", + "inject-css": "^0.1.2", "jazzicon": "^1.2.0", "json-rpc-engine": "^3.6.1", "json-rpc-middleware-stream": "^1.0.1", @@ -131,16 +126,16 @@ "lodash.memoize": "^4.1.2", "lodash.shuffle": "^4.2.0", "lodash.uniqby": "^4.7.0", - "loglevel": "^1.4.1", + "loglevel": "^1.6.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", "obj-multiplex": "^1.0.0", "obs-store": "^3.0.0", - "once": "^1.3.3", "percentile": "^1.2.0", + "pify": "^3.0.0", "ping-pong-stream": "^1.0.0", "pojo-migrator": "^2.1.0", "polyfill-crypto.getrandomvalues": "^1.0.0", @@ -148,25 +143,25 @@ "promise-filter": "^1.1.0", "promise-to-callback": "^1.0.0", "pump": "^3.0.0", - "pumpify": "^1.3.4", + "pumpify": "^1.4.0", "qrcode-npm": "0.0.3", "ramda": "^0.24.1", - "raven-js": "^3.24.0", + "raven-js": "^3.24.1", "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-select": "^1.0.0", - "react-simple-file-input": "^2.0.0", + "react-hyperscript": "^3.2.0", + "react-markdown": "^3.3.0", + "react-redux": "^5.0.7", + "react-select": "^1.2.1", + "react-simple-file-input": "^2.1.0", "react-tippy": "^1.2.2", "react-toggle-button": "^2.2.0", "react-tooltip-component": "^0.3.0", - "react-transition-group": "^2.2.1", + "react-transition-group": "^2.3.0", "react-trigger-change": "^1.0.2", "reactify": "^1.1.1", - "readable-stream": "^2.3.3", + "readable-stream": "^2.3.6", "recompose": "^0.25.0", "redux": "^3.0.5", "redux-logger": "^3.0.6", @@ -174,22 +169,23 @@ "request-promise": "^4.2.1", "sandwich-expando": "^1.1.3", "semaphore": "^1.0.5", - "semver": "^5.4.1", + "semver": "^5.5.0", "shallow-copy": "0.0.1", - "sw-stream": "^2.0.0", - "textarea-caret": "^3.0.1", + "sw-controller": "^1.0.3", + "sw-stream": "^2.0.2", + "textarea-caret": "^3.1.0", "through2": "^2.0.3", "valid-url": "^1.0.9", "vreme": "^3.0.2", - "web3": "^0.20.1", - "web3-provider-engine": "^13.5.6", + "web3": "^0.20.6", + "web3-provider-engine": "^13.8.0", "web3-stream-provider": "^3.0.1", "xtend": "^4.0.1" }, "devDependencies": { "@sentry/cli": "^1.30.3", "babel-core": "^6.24.1", - "babel-eslint": "^8.0.0", + "babel-eslint": "^8.2.2", "babel-plugin-transform-async-to-generator": "^6.24.1", "babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.23.0", @@ -198,10 +194,11 @@ "babel-register": "^6.7.2", "babelify": "^8.0.0", "beefy": "^2.1.5", - "brfs": "^1.4.3", + "brfs": "^1.5.0", "browserify": "^16.1.1", "chai": "^4.1.0", - "compression": "^1.7.1", + "chromedriver": "^2.37.0", + "compression": "^1.7.2", "coveralls": "^3.0.0", "cross-env": "^5.1.4", "deep-freeze-strict": "^1.1.1", @@ -210,18 +207,21 @@ "enzyme": "^3.3.0", "enzyme-adapter-react-15": "^1.0.5", "eslint-plugin-chai": "0.0.1", - "eslint-plugin-mocha": "^4.9.0", - "eslint-plugin-react": "^7.4.0", - "eth-json-rpc-middleware": "^1.2.7", + "eslint-plugin-json": "^1.2.0", + "eslint-plugin-mocha": "^5.0.0", + "eslint-plugin-react": "^7.7.0", + "eth-json-rpc-middleware": "^1.6.0", "fs-promise": "^2.0.3", - "gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed", + "ganache-cli": "^6.1.0", + "gifencoder": "^1.1.0", + "gulp": "github:gulpjs/gulp#4.0", "gulp-babel": "^7.0.0", - "gulp-eslint": "^4.0.0", - "gulp-if": "^2.0.2", - "gulp-json-editor": "^2.2.1", + "gulp-eslint": "^4.0.2", + "gulp-json-editor": "^2.3.0", "gulp-livereload": "^3.8.1", + "gulp-multi-process": "^1.3.1", "gulp-replace": "^0.6.1", - "gulp-sourcemaps": "^2.6.0", + "gulp-sourcemaps": "^2.6.4", "gulp-stylefmt": "^1.1.0", "gulp-stylelint": "^7.0.0", "gulp-uglify": "^3.0.0", @@ -229,8 +229,9 @@ "gulp-util": "^3.0.7", "gulp-watch": "^5.0.0", "gulp-zip": "^4.0.0", + "image-size": "^0.6.2", "isomorphic-fetch": "^2.2.1", - "jsdom": "^11.1.0", + "jsdom": "^11.7.0", "jsdom-global": "^3.0.2", "jshint-stylish": "~2.2.1", "karma": "^2.0.0", @@ -239,29 +240,33 @@ "karma-firefox-launcher": "^1.0.1", "karma-qunit": "^1.2.1", "lodash.assign": "^4.0.6", - "mocha": "^5.0.0", + "mocha": "^5.0.5", "mocha-eslint": "^4.0.0", "mocha-jsdom": "^1.1.0", "mocha-sinon": "^2.0.0", - "nock": "^9.0.14", - "node-sass": "^4.7.2", - "nyc": "^11.0.3", + "nock": "^9.2.4", + "node-sass": "^4.8.3", + "nyc": "^11.6.0", "open": "0.0.5", + "png-file-stream": "^1.0.0", "prompt": "^1.0.0", "qs": "^6.2.0", "qunitjs": "^2.4.1", "react-addons-test-utils": "^15.5.1", "react-test-renderer": "^15.6.2", - "react-testutils-additions": "^15.2.0", + "react-testutils-additions": "^15.3.1", "redux-test-utils": "^0.2.2", - "sinon": "^4.0.0", + "rimraf": "^2.6.2", + "selenium-webdriver": "^3.5.0", + "shell-parallel": "^1.0.3", + "sinon": "^5.0.0", "stylelint-config-standard": "^18.2.0", - "tape": "^4.5.1", - "testem": "^2.0.0", - "uglifyify": "^4.0.2", + "tape": "^4.9.0", + "testem": "^2.2.1", + "uglifyify": "^4.0.5", "vinyl-buffer": "^1.0.1", "vinyl-source-stream": "^2.0.0", - "watchify": "^3.9.0" + "watchify": "^3.11.0" }, "engines": { "node": ">=0.8.0" diff --git a/test/base.conf.js b/test/base.conf.js index adb5357e8..e2e9d44ba 100644 --- a/test/base.conf.js +++ b/test/base.conf.js @@ -19,11 +19,13 @@ module.exports = function(config) { 'test/integration/jquery-3.1.0.min.js', { pattern: 'dist/chrome/images/**/*.*', watched: false, included: false, served: true }, { pattern: 'dist/chrome/fonts/**/*.*', watched: false, included: false, served: true }, + { pattern: 'dist/chrome/_locales/**/*.*', watched: false, included: false, served: true }, ], proxies: { '/images/': '/base/dist/chrome/images/', '/fonts/': '/base/dist/chrome/fonts/', + '/_locales/': '/base/dist/chrome/_locales/', }, // test results reporter to use diff --git a/test/e2e/func.js b/test/e2e/func.js new file mode 100644 index 000000000..733225565 --- /dev/null +++ b/test/e2e/func.js @@ -0,0 +1,18 @@ +require('chromedriver') +const webdriver = require('selenium-webdriver') + +exports.delay = function delay (time) { + return new Promise(resolve => setTimeout(resolve, time)) +} + + +exports.buildWebDriver = function buildWebDriver (extPath) { + return new webdriver.Builder() + .withCapabilities({ + chromeOptions: { + args: [`load-extension=${extPath}`], + }, + }) + .forBrowser('chrome') + .build() +} diff --git a/test/e2e/metamask.spec.js b/test/e2e/metamask.spec.js new file mode 100644 index 000000000..e0ff2a57e --- /dev/null +++ b/test/e2e/metamask.spec.js @@ -0,0 +1,145 @@ +const fs = require('fs') +const mkdirp = require('mkdirp') +const path = require('path') +const assert = require('assert') +const pify = require('pify') +const webdriver = require('selenium-webdriver') +const By = webdriver.By +const { delay, buildWebDriver } = require('./func') + +describe('Metamask popup page', function () { + let driver + this.seedPhase + this.accountAddress + this.timeout(0) + + before(async function () { + const extPath = path.resolve('dist/chrome') + driver = buildWebDriver(extPath) + await driver.get('chrome://extensions-frame') + const elems = await driver.findElements(By.css('.extension-list-item-wrapper')) + const extensionId = await elems[1].getAttribute('id') + await driver.get(`chrome-extension://${extensionId}/popup.html`) + await delay(500) + }) + + afterEach(async function () { + if (this.currentTest.state === 'failed') { + await verboseReportOnFailure(this.currentTest) + } + }) + + after(async function () { + await driver.quit() + }) + + describe('#onboarding', () => { + it('should open Metamask.io', async function () { + const tabs = await driver.getAllWindowHandles() + await driver.switchTo().window(tabs[0]) + await delay(300) + await setProviderType('localhost') + await delay(300) + }) + + it('should match title', async () => { + const title = await driver.getTitle() + assert.equal(title, 'MetaMask', 'title matches MetaMask') + }) + + it('should show privacy notice', async () => { + const privacy = await driver.findElement(By.css('.terms-header')).getText() + assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice') + driver.findElement(By.css('button')).click() + await delay(300) + }) + + it('should show terms of use', async () => { + await delay(300) + const terms = await driver.findElement(By.css('.terms-header')).getText() + assert.equal(terms, 'TERMS OF USE', 'shows terms of use') + await delay(300) + }) + + it('should be unable to continue without scolling throught the terms of use', async () => { + const button = await driver.findElement(By.css('button')).isEnabled() + assert.equal(button, false, 'disabled continue button') + const element = driver.findElement(By.linkText( + 'Attributions' + )) + await driver.executeScript('arguments[0].scrollIntoView(true)', element) + await delay(300) + }) + + it('should be able to continue when scrolled to the bottom of terms of use', async () => { + const button = await driver.findElement(By.css('button')) + const buttonEnabled = await button.isEnabled() + await delay(500) + assert.equal(buttonEnabled, true, 'enabled continue button') + await button.click() + await delay(300) + }) + + it('should accept password with length of eight', async () => { + const passwordBox = await driver.findElement(By.id('password-box')) + const passwordBoxConfirm = await driver.findElement(By.id('password-box-confirm')) + const button = driver.findElement(By.css('button')) + + passwordBox.sendKeys('123456789') + passwordBoxConfirm.sendKeys('123456789') + await delay(500) + await button.click() + }) + + it('should show value was created and seed phrase', async () => { + await delay(700) + this.seedPhase = await driver.findElement(By.css('.twelve-word-phrase')).getText() + const continueAfterSeedPhrase = await driver.findElement(By.css('button')) + await continueAfterSeedPhrase.click() + await delay(300) + }) + + it('should show lock account', async () => { + await driver.findElement(By.css('.sandwich-expando')).click() + await delay(500) + await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)')).click() + }) + + it('should accept account password after lock', async () => { + await delay(500) + await driver.findElement(By.id('password-box')).sendKeys('123456789') + await driver.findElement(By.css('button')).click() + await delay(500) + }) + + it('should show QR code option', async () => { + await delay(300) + await driver.findElement(By.css('.fa-ellipsis-h')).click() + await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div:nth-child(1) > flex-column > div.name-label > div > span > i > div > div > li:nth-child(3)')).click() + await delay(300) + }) + + it('should show the account address', async () => { + this.accountAddress = await driver.findElement(By.css('.ellip-address')).getText() + await driver.findElement(By.css('.fa-arrow-left')).click() + await delay(500) + }) + }) + + async function setProviderType(type) { + await driver.executeScript('window.metamask.setProviderType(arguments[0])', type) + } + + async function verboseReportOnFailure(test) { + const artifactDir = `./test-artifacts/${test.title}` + const filepathBase = `${artifactDir}/test-failure` + await pify(mkdirp)(artifactDir) + // capture screenshot + const screenshot = await driver.takeScreenshot() + await pify(fs.writeFile)(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' }) + // capture dom source + const htmlSource = await driver.getPageSource() + await pify(fs.writeFile)(`${filepathBase}-dom.html`, htmlSource) + } + +}) diff --git a/test/integration/lib/add-token.js b/test/integration/lib/add-token.js index cc04beb21..1840bdd39 100644 --- a/test/integration/lib/add-token.js +++ b/test/integration/lib/add-token.js @@ -75,7 +75,7 @@ async function runAddTokenFlowTest (assert, done) { // Confirm Add token assert.equal( $('.add-token__description')[0].textContent, - 'Would you like to add these tokens?', + 'Token balance(s)', 'confirm add token rendered' ) assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found') diff --git a/test/integration/lib/tx-list-items.js b/test/integration/lib/tx-list-items.js new file mode 100644 index 000000000..d0056eb94 --- /dev/null +++ b/test/integration/lib/tx-list-items.js @@ -0,0 +1,61 @@ +const reactTriggerChange = require('../../lib/react-trigger-change') +const { + timeout, + queryAsync, + findAsync, +} = require('../../lib/util') + +QUnit.module('tx list items') + +QUnit.test('renders list items successfully', (assert) => { + const done = assert.async() + runTxListItemsTest(assert).then(done).catch((err) => { + assert.notOk(err, `Error was thrown: ${err.stack}`) + done() + }) +}) + +async function runTxListItemsTest(assert, done) { + console.log('*** start runTxListItemsTest') + const selectState = await queryAsync($, 'select') + selectState.val('tx list items') + reactTriggerChange(selectState[0]) + + const metamaskLogo = await queryAsync($, '.left-menu-wrapper') + assert.ok(metamaskLogo[0], 'metamask logo present') + metamaskLogo[0].click() + + const txListItems = await queryAsync($, '.tx-list-item') + assert.equal(txListItems.length, 8, 'all tx list items are rendered') + + const unapprovedTx = txListItems[0] + assert.equal($(unapprovedTx).hasClass('tx-list-pending-item-container'), true, 'unapprovedTx has the correct class') + + const retryTx = txListItems[1] + const retryTxLink = await findAsync($(retryTx), '.tx-list-item-retry-link') + assert.equal(retryTxLink[0].textContent, 'Increase the gas price on your transaction', 'retryTx has expected link') + + const approvedTx = txListItems[2] + const approvedTxRenderedStatus = await findAsync($(approvedTx), '.tx-list-status') + assert.equal(approvedTxRenderedStatus[0].textContent, 'Approved', 'approvedTx has correct label') + + const unapprovedMsg = txListItems[3] + const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.tx-list-account') + assert.equal(unapprovedMsgDescription[0].textContent, 'Signature Request', 'unapprovedMsg has correct description') + + const failedTx = txListItems[4] + const failedTxRenderedStatus = await findAsync($(failedTx), '.tx-list-status') + assert.equal(failedTxRenderedStatus[0].textContent, 'Failed', 'failedTx has correct label') + + const shapeShiftTx = txListItems[5] + const shapeShiftTxStatus = await findAsync($(shapeShiftTx), '.flex-column div:eq(1)') + assert.equal(shapeShiftTxStatus[0].textContent, 'No deposits received', 'shapeShiftTx has correct status') + + const confirmedTokenTx = txListItems[6] + const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.tx-list-account') + assert.equal(confirmedTokenTxAddress[0].textContent, '0xe7884118...81a9', 'confirmedTokenTx has correct address') + + const rejectedTx = txListItems[7] + const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.tx-list-status') + assert.equal(rejectedTxRenderedStatus[0].textContent, 'Rejected', 'rejectedTx has correct label') +} diff --git a/test/screens/func.js b/test/screens/func.js new file mode 100644 index 000000000..733225565 --- /dev/null +++ b/test/screens/func.js @@ -0,0 +1,18 @@ +require('chromedriver') +const webdriver = require('selenium-webdriver') + +exports.delay = function delay (time) { + return new Promise(resolve => setTimeout(resolve, time)) +} + + +exports.buildWebDriver = function buildWebDriver (extPath) { + return new webdriver.Builder() + .withCapabilities({ + chromeOptions: { + args: [`load-extension=${extPath}`], + }, + }) + .forBrowser('chrome') + .build() +} diff --git a/test/screens/new-ui.js b/test/screens/new-ui.js new file mode 100644 index 000000000..91b3a9633 --- /dev/null +++ b/test/screens/new-ui.js @@ -0,0 +1,230 @@ +const path = require('path') +const fs = require('fs') +const pify = require('pify') +const mkdirp = require('mkdirp') +const rimraf = require('rimraf') +const webdriver = require('selenium-webdriver') +const endOfStream = require('end-of-stream') +const GIFEncoder = require('gifencoder') +const pngFileStream = require('png-file-stream') +const sizeOfPng = require('image-size/lib/types/png') +const By = webdriver.By +const { delay, buildWebDriver } = require('./func') +const localesIndex = require('../../app/_locales/index.json') + +let driver + +captureAllScreens().catch((err) => { + try { + console.error(err) + verboseReportOnFailure() + driver.quit() + } catch (err) { + console.error(err) + } + process.exit(1) +}) + +async function captureAllScreens() { + let screenshotCount = 0 + + // common names + let button + let tabs + let element + + await cleanScreenShotDir() + + // setup selenium and install extension + const extPath = path.resolve('dist/chrome') + driver = buildWebDriver(extPath) + await driver.get('chrome://extensions-frame') + const elems = await driver.findElements(By.css('.extension-list-item-wrapper')) + const extensionId = await elems[1].getAttribute('id') + await driver.get(`chrome-extension://${extensionId}/home.html`) + await delay(500) + tabs = await driver.getAllWindowHandles() + await driver.switchTo().window(tabs[0]) + await delay(1000) + await setProviderType('localhost') + await delay(300) + + // click try new ui + await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-row.flex-center.flex-grow > p')).click() + await delay(300) + + // close metamask homepage and extra home.html + tabs = await driver.getAllWindowHandles() + // metamask homepage is opened on prod, not dev + if (tabs.length > 2) { + await driver.switchTo().window(tabs[2]) + driver.close() + } + await driver.switchTo().window(tabs[1]) + driver.close() + await driver.switchTo().window(tabs[0]) + await delay(300) + await captureLanguageScreenShots('welcome-new-ui') + + // setup account + await delay(1000) + await driver.findElement(By.css('body')).click() + await delay(300) + await captureLanguageScreenShots('welcome') + + await driver.findElement(By.css('button')).click() + await captureLanguageScreenShots('create password') + + const passwordBox = await driver.findElement(By.css('input[type=password]:nth-of-type(1)')) + const passwordBoxConfirm = await driver.findElement(By.css('input[type=password]:nth-of-type(2)')) + passwordBox.sendKeys('123456789') + passwordBoxConfirm.sendKeys('123456789') + await delay(500) + await captureLanguageScreenShots('choose-password-filled') + + await driver.findElement(By.css('button')).click() + await delay(500) + await captureLanguageScreenShots('unique account image') + + await driver.findElement(By.css('button')).click() + await delay(500) + await captureLanguageScreenShots('privacy note') + + await driver.findElement(By.css('button')).click() + await delay(300) + await captureLanguageScreenShots('terms') + + await delay(300) + element = driver.findElement(By.linkText('Attributions')) + await driver.executeScript('arguments[0].scrollIntoView(true)', element) + await delay(300) + await captureLanguageScreenShots('terms-scrolled') + + await driver.findElement(By.css('button')).click() + await delay(300) + await captureLanguageScreenShots('secret backup phrase') + + await driver.findElement(By.css('button')).click() + await delay(300) + await captureLanguageScreenShots('secret backup phrase') + + await driver.findElement(By.css('.backup-phrase__reveal-button')).click() + await delay(300) + await captureLanguageScreenShots('secret backup phrase - reveal') + + await driver.findElement(By.css('button')).click() + await delay(300) + await captureLanguageScreenShots('confirm secret backup phrase') + + // finish up + console.log('building gif...') + await generateGif() + await driver.quit() + return + + // + // await button.click() + // await delay(700) + // this.seedPhase = await driver.findElement(By.css('.twelve-word-phrase')).getText() + // await captureScreenShot('seed phrase') + // + // const continueAfterSeedPhrase = await driver.findElement(By.css('button')) + // await continueAfterSeedPhrase.click() + // await delay(300) + // await captureScreenShot('main screen') + // + // await driver.findElement(By.css('.sandwich-expando')).click() + // await delay(500) + // await captureScreenShot('menu') + + // await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)')).click() + // await captureScreenShot('main screen') + // it('should accept account password after lock', async () => { + // await delay(500) + // await driver.findElement(By.id('password-box')).sendKeys('123456789') + // await driver.findElement(By.css('button')).click() + // await delay(500) + // }) + // + // it('should show QR code option', async () => { + // await delay(300) + // await driver.findElement(By.css('.fa-ellipsis-h')).click() + // await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div:nth-child(1) > flex-column > div.name-label > div > span > i > div > div > li:nth-child(3)')).click() + // await delay(300) + // }) + // + // it('should show the account address', async () => { + // this.accountAddress = await driver.findElement(By.css('.ellip-address')).getText() + // await driver.findElement(By.css('.fa-arrow-left')).click() + // await delay(500) + // }) + + async function captureLanguageScreenShots(label) { + const nonEnglishLocales = localesIndex.filter(localeMeta => localeMeta.code !== 'en') + // take english shot + await captureScreenShot(`${label} (en)`) + for (let localeMeta of nonEnglishLocales) { + // set locale and take shot + await setLocale(localeMeta.code) + await delay(300) + await captureScreenShot(`${label} (${localeMeta.code})`) + } + // return locale to english + await setLocale('en') + await delay(300) + } + + async function setLocale(code) { + await driver.executeScript('window.metamask.updateCurrentLocale(arguments[0])', code) + } + + async function setProviderType(type) { + await driver.executeScript('window.metamask.setProviderType(arguments[0])', type) + } + + // cleanup + await driver.quit() + + async function cleanScreenShotDir() { + await pify(rimraf)(`./test-artifacts/screens/`) + } + + async function captureScreenShot(label) { + const shotIndex = screenshotCount.toString().padStart(4, '0') + screenshotCount++ + const artifactDir = `./test-artifacts/screens/` + await pify(mkdirp)(artifactDir) + // capture screenshot + const screenshot = await driver.takeScreenshot() + await pify(fs.writeFile)(`${artifactDir}/${shotIndex} - ${label}.png`, screenshot, { encoding: 'base64' }) + } + + async function generateGif(){ + // calculate screenshot size + const screenshot = await driver.takeScreenshot() + const pngBuffer = Buffer.from(screenshot, 'base64') + const size = sizeOfPng.calculate(pngBuffer) + + // read only the english pngs into gif + const encoder = new GIFEncoder(size.width, size.height) + const stream = pngFileStream('./test-artifacts/screens/* (en).png') + .pipe(encoder.createWriteStream({ repeat: 0, delay: 1000, quality: 10 })) + .pipe(fs.createWriteStream('./test-artifacts/screens/walkthrough (en).gif')) + + // wait for end + await pify(endOfStream)(stream) + } + +} + +async function verboseReportOnFailure(test) { + const artifactDir = `./test-artifacts/${test.title}` + const filepathBase = `${artifactDir}/test-failure` + await pify(mkdirp)(artifactDir) + // capture screenshot + const screenshot = await driver.takeScreenshot() + await pify(fs.writeFile)(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' }) + // capture dom source + const htmlSource = await driver.getPageSource() + await pify(fs.writeFile)(`${filepathBase}-dom.html`, htmlSource) +} diff --git a/test/unit/migrations/023-test.js b/test/unit/migrations/023-test.js new file mode 100644 index 000000000..be432d9fa --- /dev/null +++ b/test/unit/migrations/023-test.js @@ -0,0 +1,99 @@ +const assert = require('assert') +const migration23 = require('../../../app/scripts/migrations/023') +const properTime = (new Date()).getTime() +const storage = { + "meta": {}, + "data": { + "TransactionController": { + "transactions": [ + ] + }, + }, +} + +const transactions = [] +const transactions40 = [] +const transactions20 = [] + +const txStates = [ + 'unapproved', + 'approved', + 'signed', + 'submitted', + 'confirmed', + 'rejected', + 'failed', + 'dropped', +] + +const deletableTxStates = [ + 'confirmed', + 'rejected', + 'failed', + 'dropped', +] + +let nonDeletableCount = 0 + +let status +while (transactions.length <= 100) { + status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] + if (!deletableTxStates.find((s) => s === status)) nonDeletableCount++ + transactions.push({status}) +} + +while (transactions40.length < 40) { + status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] + transactions40.push({status}) +} + +while (transactions20.length < 20) { + status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))] + transactions20.push({status}) +} + + + +storage.data.TransactionController.transactions = transactions + +describe('storage is migrated successfully and the proper transactions are remove from state', () => { + it('should remove transactions that are unneeded', (done) => { + migration23.migrate(storage) + .then((migratedData) => { + let leftoverNonDeletableTxCount = 0 + const migratedTransactions = migratedData.data.TransactionController.transactions + migratedTransactions.forEach((tx) => { + if (!deletableTxStates.find((s) => s === tx.status)) { + leftoverNonDeletableTxCount++ + } + }) + assert.equal(leftoverNonDeletableTxCount, nonDeletableCount, 'migration shouldnt delete transactions we want to keep') + assert((migratedTransactions.length >= 40), `should be equal or greater to 40 if they are non deletable states got ${migratedTransactions.length} transactions`) + done() + }).catch(done) + }) + + it('should not remove any transactions because 40 is the expectable limit', (done) => { + storage.meta.version = 22 + storage.data.TransactionController.transactions = transactions40 + migration23.migrate(storage) + .then((migratedData) => { + const migratedTransactions = migratedData.data.TransactionController.transactions + + assert.equal(migratedTransactions.length, 40, 'migration shouldnt delete when at limit') + done() + }).catch(done) + }) + + it('should not remove any transactions because 20 txs is under the expectable limit', (done) => { + storage.meta.version = 22 + storage.data.TransactionController.transactions = transactions20 + migration23.migrate(storage) + .then((migratedData) => { + const migratedTransactions = migratedData.data.TransactionController.transactions + assert.equal(migratedTransactions.length, 20, 'migration shouldnt delete when under limit') + done() + }).catch(done) + }) + +}) 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/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js index 8970cf84d..5a27882ef 100644 --- a/test/unit/nonce-tracker-test.js +++ b/test/unit/nonce-tracker-test.js @@ -33,6 +33,42 @@ describe('Nonce Tracker', function () { }) }) + describe('sentry issue 476304902', function () { + beforeEach(function () { + const txGen = new MockTxGen() + pendingTxs = txGen.generate({ status: 'submitted' }, { + fromNonce: 3, + count: 29, + }) + nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x3') + }) + + it('should return 9', async function () { + this.timeout(15000) + const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926') + assert.equal(nonceLock.nextNonce, '32', `nonce should be 32 got ${nonceLock.nextNonce}`) + await nonceLock.releaseLock() + }) + }) + + describe('issue 3670', function () { + beforeEach(function () { + const txGen = new MockTxGen() + pendingTxs = txGen.generate({ status: 'submitted' }, { + fromNonce: 6, + count: 3, + }) + nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x6') + }) + + it('should return 9', async function () { + this.timeout(15000) + const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926') + assert.equal(nonceLock.nextNonce, '9', `nonce should be 9 got ${nonceLock.nextNonce}`) + await nonceLock.releaseLock() + }) + }) + describe('with no previous txs', function () { beforeEach(function () { nonceTracker = generateNonceTrackerWith([], []) diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js index 712097fce..824574ff2 100644 --- a/test/unit/tx-controller-test.js +++ b/test/unit/tx-controller-test.js @@ -162,7 +162,7 @@ describe('Transaction Controller', function () { describe('#addUnapprovedTransaction', function () { it('should add an unapproved transaction and return a valid txMeta', function (done) { - txController.addUnapprovedTransaction({}) + txController.addUnapprovedTransaction({ from: '0x1678a085c290ebd122dc42cba69373b5953b831d' }) .then((txMeta) => { assert(('id' in txMeta), 'should have a id') assert(('time' in txMeta), 'should have a time stamp') @@ -182,7 +182,7 @@ describe('Transaction Controller', function () { assert(txMetaFromEmit, 'txMeta is falsey') done() }) - txController.addUnapprovedTransaction({}) + txController.addUnapprovedTransaction({ from: '0x1678a085c290ebd122dc42cba69373b5953b831d' }) .catch(done) }) @@ -210,29 +210,99 @@ describe('Transaction Controller', function () { }) }) - describe('#validateTxParams', function () { - it('does not throw for positive values', function (done) { + describe('#_validateTxParams', function () { + it('does not throw for positive values', function () { var sample = { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', value: '0x01', } - txController.txGasUtil.validateTxParams(sample).then(() => { - done() - }).catch(done) + txController._validateTxParams(sample) }) - it('returns error for negative values', function (done) { + it('returns error for negative values', function () { var sample = { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', value: '-0x01', } - txController.txGasUtil.validateTxParams(sample) - .then(() => done('expected to thrown on negativity values but didn\'t')) - .catch((err) => { + try { + txController._validateTxParams(sample) + } catch (err) { assert.ok(err, 'error') - done() - }) + } }) }) + describe('#_normalizeTxParams', () => { + it('should normalize txParams', () => { + let txParams = { + chainId: '0x1', + from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402', + to: null, + data: '68656c6c6f20776f726c64', + random: 'hello world', + } + + let normalizedTxParams = txController._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 = txController._normalizeTxParams(txParams) + assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd') + + }) + }) + + 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 = txController._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(() => { txController._validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address') + }) + }) + + + describe('#_validateFrom', () => { + it('should error when from is not a hex string', function () { + + // where from is undefined + const txParams = {} + assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`) + + // where from is array + txParams.from = [] + assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`) + + // where from is a object + txParams.from = {} + assert.throws(() => { txController._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(() => { txController._validateFrom(txParams) }, Error, `Invalid from address`) + + // should run + txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d' + txController._validateFrom(txParams) + }) + }) + describe('#addTx', function () { it('should emit updates', function (done) { const txMeta = { diff --git a/test/unit/tx-gas-util-test.js b/test/unit/tx-gas-util-test.js index d9a12d1c3..40ea8a7d6 100644 --- a/test/unit/tx-gas-util-test.js +++ b/test/unit/tx-gas-util-test.js @@ -11,22 +11,4 @@ describe('Tx Gas Util', function () { provider, }) }) - - 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') - }) }) diff --git a/test/unit/tx-state-manager-test.js b/test/unit/tx-state-manager-test.js index 220bf501f..a5ac13664 100644 --- a/test/unit/tx-state-manager-test.js +++ b/test/unit/tx-state-manager-test.js @@ -240,12 +240,12 @@ describe('TransactionStateManager', function () { }) describe('#wipeTransactions', function () { - + const specificAddress = '0xaa' const otherAddress = '0xbb' it('should remove only the transactions from a specific address', function () { - + const txMetas = [ { id: 0, status: 'unapproved', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: currentNetworkId }, { id: 1, status: 'confirmed', txParams: { from: otherAddress, to: specificAddress }, metamaskNetworkId: currentNetworkId }, @@ -268,7 +268,7 @@ describe('TransactionStateManager', function () { { id: 1, status: 'confirmed', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: otherNetworkId }, { id: 2, status: 'confirmed', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: otherNetworkId }, ] - + txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop)) txStateManager.wipeTransactions(specificAddress) diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js index fc9031a65..52d3dcde9 100644 --- a/ui/app/accounts/import/index.js +++ b/ui/app/accounts/import/index.js @@ -1,43 +1,44 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') +const PropTypes = require('prop-types') const connect = require('react-redux').connect -const t = require('../../../i18n') import Select from 'react-select' // Subviews const JsonImportView = require('./json.js') const PrivateKeyImportView = require('./private-key.js') -const menuItems = [ - t('privateKey'), - t('jsonFile'), -] -module.exports = connect(mapStateToProps)(AccountImportSubview) - -function mapStateToProps (state) { - return { - menuItems, - } +AccountImportSubview.contextTypes = { + t: PropTypes.func, } +module.exports = connect()(AccountImportSubview) + + inherits(AccountImportSubview, Component) function AccountImportSubview () { Component.call(this) } +AccountImportSubview.prototype.getMenuItemTexts = function () { + return [ + this.context.t('privateKey'), + this.context.t('jsonFile'), + ] +} + AccountImportSubview.prototype.render = function () { - const props = this.props const state = this.state || {} - const { menuItems } = props + const menuItems = this.getMenuItemTexts() const { type } = state return ( h('div.new-account-import-form', [ h('.new-account-import-disclaimer', [ - h('span', t('importAccountMsg')), + h('span', this.context.t('importAccountMsg')), h('span', { style: { cursor: 'pointer', @@ -48,12 +49,12 @@ AccountImportSubview.prototype.render = function () { url: 'https://metamask.helpscoutdocs.com/article/17-what-are-loose-accounts', }) }, - }, t('here')), + }, this.context.t('here')), ]), h('div.new-account-import-form__select-section', [ - h('div.new-account-import-form__select-label', t('selectType')), + h('div.new-account-import-form__select-label', this.context.t('selectType')), h(Select, { className: 'new-account-import-form__select', @@ -79,16 +80,15 @@ AccountImportSubview.prototype.render = function () { } AccountImportSubview.prototype.renderImportView = function () { - const props = this.props const state = this.state || {} const { type } = state - const { menuItems } = props + const menuItems = this.getMenuItemTexts() const current = type || menuItems[0] switch (current) { - case t('privateKey'): + case this.context.t('privateKey'): return h(PrivateKeyImportView) - case t('jsonFile'): + case this.context.t('jsonFile'): return h(JsonImportView) default: return h(JsonImportView) diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js index eeba73e77..e53c1c9ca 100644 --- a/ui/app/accounts/import/json.js +++ b/ui/app/accounts/import/json.js @@ -4,7 +4,7 @@ const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('../../actions') const FileInput = require('react-simple-file-input').default -const t = require('../../../i18n') + const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts' @@ -24,11 +24,11 @@ class JsonImportSubview extends Component { return ( h('div.new-account-import-form__json', [ - h('p', t('usedByClients')), + h('p', this.context.t('usedByClients')), h('a.warning', { href: HELP_LINK, target: '_blank', - }, t('fileImportFail')), + }, this.context.t('fileImportFail')), h(FileInput, { readAs: 'text', @@ -43,7 +43,7 @@ class JsonImportSubview extends Component { h('input.new-account-import-form__input-password', { type: 'password', - placeholder: t('enterPassword'), + placeholder: this.context.t('enterPassword'), id: 'json-password-box', onKeyPress: this.createKeyringOnEnter.bind(this), }), @@ -53,13 +53,13 @@ class JsonImportSubview extends Component { h('button.btn-secondary.new-account-create-form__button', { onClick: () => this.props.goHome(), }, [ - t('cancel'), + this.context.t('cancel'), ]), h('button.btn-primary.new-account-create-form__button', { onClick: () => this.createNewKeychain(), }, [ - t('import'), + this.context.t('import'), ]), ]), @@ -84,14 +84,14 @@ class JsonImportSubview extends Component { const state = this.state if (!state) { - const message = t('validFileImport') + const message = this.context.t('validFileImport') return this.props.displayWarning(message) } const { fileContents } = state if (!fileContents) { - const message = t('needImportFile') + const message = this.context.t('needImportFile') return this.props.displayWarning(message) } @@ -99,7 +99,7 @@ class JsonImportSubview extends Component { const password = passwordInput.value if (!password) { - const message = t('needImportPassword') + const message = this.context.t('needImportPassword') return this.props.displayWarning(message) } @@ -112,6 +112,7 @@ JsonImportSubview.propTypes = { goHome: PropTypes.func, displayWarning: PropTypes.func, importNewJsonAccount: PropTypes.func, + t: PropTypes.func, } const mapStateToProps = state => { @@ -128,4 +129,9 @@ const mapDispatchToProps = dispatch => { } } +JsonImportSubview.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(JsonImportSubview) + diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js index 13c8da722..0d2898cda 100644 --- a/ui/app/accounts/import/private-key.js +++ b/ui/app/accounts/import/private-key.js @@ -1,12 +1,17 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') +const PropTypes = require('prop-types') const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') + +PrivateKeyImportView.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView) + function mapStateToProps (state) { return { error: state.appState.warning, @@ -25,6 +30,7 @@ function mapDispatchToProps (dispatch) { inherits(PrivateKeyImportView, Component) function PrivateKeyImportView () { + this.createKeyringOnEnter = this.createKeyringOnEnter.bind(this) Component.call(this) } @@ -34,14 +40,14 @@ PrivateKeyImportView.prototype.render = function () { return ( h('div.new-account-import-form__private-key', [ - h('span.new-account-create-form__instruction', t('pastePrivateKey')), + h('span.new-account-create-form__instruction', this.context.t('pastePrivateKey')), h('div.new-account-import-form__private-key-password-container', [ h('input.new-account-import-form__input-password', { type: 'password', id: 'private-key-box', - onKeyPress: () => this.createKeyringOnEnter(), + onKeyPress: e => this.createKeyringOnEnter(e), }), ]), @@ -51,13 +57,13 @@ PrivateKeyImportView.prototype.render = function () { h('button.btn-secondary--lg.new-account-create-form__button', { onClick: () => goHome(), }, [ - t('cancel'), + this.context.t('cancel'), ]), h('button.btn-primary--lg.new-account-create-form__button', { onClick: () => this.createNewKeychain(), }, [ - t('import'), + this.context.t('import'), ]), ]), diff --git a/ui/app/accounts/import/seed.js b/ui/app/accounts/import/seed.js index 9ffc669a2..d98909baa 100644 --- a/ui/app/accounts/import/seed.js +++ b/ui/app/accounts/import/seed.js @@ -1,11 +1,16 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') +const PropTypes = require('prop-types') const connect = require('react-redux').connect -const t = require('../../../i18n') + +SeedImportSubview.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps)(SeedImportSubview) + function mapStateToProps (state) { return {} } @@ -21,10 +26,10 @@ SeedImportSubview.prototype.render = function () { style: { }, }, [ - t('pasteSeed'), + this.context.t('pasteSeed'), h('textarea'), h('br'), - h('button', t('submit')), + h('button', this.context.t('submit')), ]) ) } diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/accounts/new-account/create-form.js index c820cdf6d..48c74192a 100644 --- a/ui/app/accounts/new-account/create-form.js +++ b/ui/app/accounts/new-account/create-form.js @@ -1,12 +1,11 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') class NewAccountCreateForm extends Component { - constructor (props) { + constructor (props, context) { super(props) const { numberOfExistingAccounts = 0 } = props @@ -14,7 +13,7 @@ class NewAccountCreateForm extends Component { this.state = { newAccountName: '', - defaultAccountName: t('newAccountNumberName', [newAccountNumber]), + defaultAccountName: context.t('newAccountNumberName', [newAccountNumber]), } } @@ -25,7 +24,7 @@ class NewAccountCreateForm extends Component { return h('div.new-account-create-form', [ h('div.new-account-create-form__input-label', {}, [ - t('accountName'), + this.context.t('accountName'), ]), h('div.new-account-create-form__input-wrapper', {}, [ @@ -41,13 +40,13 @@ class NewAccountCreateForm extends Component { h('button.btn-secondary--lg.new-account-create-form__button', { onClick: () => this.props.goHome(), }, [ - t('cancel'), + this.context.t('cancel'), ]), h('button.btn-primary--lg.new-account-create-form__button', { onClick: () => this.props.createAccount(newAccountName || defaultAccountName), }, [ - t('create'), + this.context.t('create'), ]), ]), @@ -62,6 +61,7 @@ NewAccountCreateForm.propTypes = { createAccount: PropTypes.func, goHome: PropTypes.func, numberOfExistingAccounts: PropTypes.number, + t: PropTypes.func, } const mapStateToProps = state => { @@ -97,4 +97,9 @@ const mapDispatchToProps = dispatch => { } } +NewAccountCreateForm.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm) + diff --git a/ui/app/accounts/new-account/index.js b/ui/app/accounts/new-account/index.js index 854568c77..207cf7760 100644 --- a/ui/app/accounts/new-account/index.js +++ b/ui/app/accounts/new-account/index.js @@ -1,9 +1,9 @@ const Component = require('react').Component const h = require('react-hyperscript') +const PropTypes = require('prop-types') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') const { getCurrentViewContext } = require('../../selectors') const classnames = require('classnames') @@ -37,8 +37,13 @@ function AccountDetailsModal (props) { } } +AccountDetailsModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) + AccountDetailsModal.prototype.render = function () { const { displayedForm, displayForm } = this.props @@ -46,7 +51,7 @@ AccountDetailsModal.prototype.render = function () { h('div.new-account__header', [ - h('div.new-account__title', t('newAccount')), + h('div.new-account__title', this.context.t('newAccount')), h('div.new-account__tabs', [ @@ -56,7 +61,7 @@ AccountDetailsModal.prototype.render = function () { 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'CREATE', }), onClick: () => displayForm('CREATE'), - }, t('createDen')), + }, this.context.t('createDen')), h('div.new-account__tabs__tab', { className: classnames('new-account__tabs__tab', { @@ -64,7 +69,7 @@ AccountDetailsModal.prototype.render = function () { 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'IMPORT', }), onClick: () => displayForm('IMPORT'), - }, t('import')), + }, this.context.t('import')), ]), diff --git a/ui/app/actions.js b/ui/app/actions.js index 4a5962610..ad4270cef 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -2,6 +2,7 @@ const abi = require('human-standard-token-abi') const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url') const { getTokenAddressFromTokenObject } = require('./util') const ethUtil = require('ethereumjs-util') +const { fetchLocale } = require('../i18n-helper') var actions = { _setBackgroundConnection: _setBackgroundConnection, @@ -23,7 +24,7 @@ var actions = { NETWORK_DROPDOWN_CLOSE: 'UI_NETWORK_DROPDOWN_CLOSE', showNetworkDropdown: showNetworkDropdown, hideNetworkDropdown: hideNetworkDropdown, - // menu state + // menu state/ getNetworkStatus: 'getNetworkStatus', // transition state TRANSITION_FORWARD: 'TRANSITION_FORWARD', @@ -254,6 +255,13 @@ var actions = { SET_USE_BLOCKIE: 'SET_USE_BLOCKIE', setUseBlockie, + // locale + SET_CURRENT_LOCALE: 'SET_CURRENT_LOCALE', + SET_LOCALE_MESSAGES: 'SET_LOCALE_MESSAGES', + setCurrentLocale, + updateCurrentLocale, + setLocaleMessages, + // // Feature Flags setFeatureFlag, updateFeatureFlags, @@ -1292,7 +1300,7 @@ function retryTransaction (txId) { function setProviderType (type) { return (dispatch) => { - log.debug(`background.setProviderType`) + log.debug(`background.setProviderType`, type) background.setProviderType(type, (err, result) => { if (err) { log.error(err) @@ -1313,13 +1321,14 @@ function updateProviderType (type) { } function setRpcTarget (newRpc) { - log.debug(`background.setRpcTarget: ${newRpc}`) return (dispatch) => { + log.debug(`background.setRpcTarget: ${newRpc}`) background.setCustomRpc(newRpc, (err, result) => { if (err) { log.error(err) return dispatch(self.displayWarning('Had a problem changing networks!')) } + dispatch(actions.setSelectedToken()) }) } } @@ -1792,6 +1801,38 @@ function setUseBlockie (val) { } } +function updateCurrentLocale (key) { + return (dispatch) => { + dispatch(actions.showLoadingIndication()) + fetchLocale(key) + .then((localeMessages) => { + log.debug(`background.setCurrentLocale`) + background.setCurrentLocale(key, (err) => { + dispatch(actions.hideLoadingIndication()) + if (err) { + return dispatch(actions.displayWarning(err.message)) + } + dispatch(actions.setCurrentLocale(key)) + dispatch(actions.setLocaleMessages(localeMessages)) + }) + }) + } +} + +function setCurrentLocale (key) { + return { + type: actions.SET_CURRENT_LOCALE, + value: key, + } +} + +function setLocaleMessages (localeMessages) { + return { + type: actions.SET_LOCALE_MESSAGES, + value: localeMessages, + } +} + function setNetworkEndpoints (networkEndpointType) { return dispatch => { log.debug('background.setNetworkEndpoints') diff --git a/ui/app/add-token.js b/ui/app/add-token.js index b4ea4a532..46564a5e5 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -2,6 +2,7 @@ const inherits = require('util').inherits const Component = require('react').Component const classnames = require('classnames') const h = require('react-hyperscript') +const PropTypes = require('prop-types') const connect = require('react-redux').connect const R = require('ramda') const Fuse = require('fuse.js') @@ -26,12 +27,16 @@ const fuse = new Fuse(contractList, { const actions = require('./actions') const ethUtil = require('ethereumjs-util') const { tokenInfoGetter } = require('./token-util') -const t = require('../i18n') const emptyAddr = '0x0000000000000000000000000000000000000000' +AddTokenScreen.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(AddTokenScreen) + function mapStateToProps (state) { const { identities, tokens } = state.metamask return { @@ -51,6 +56,7 @@ inherits(AddTokenScreen, Component) function AddTokenScreen () { this.state = { isShowingConfirmation: false, + isShowingInfoBox: true, customAddress: '', customSymbol: '', customDecimals: '', @@ -140,28 +146,31 @@ AddTokenScreen.prototype.validate = function () { if (customAddress) { const validAddress = ethUtil.isValidAddress(customAddress) if (!validAddress) { - errors.customAddress = t('invalidAddress') + errors.customAddress = this.context.t('invalidAddress') } - const validDecimals = customDecimals !== null && customDecimals >= 0 && customDecimals < 36 + const validDecimals = customDecimals !== null + && customDecimals !== '' + && customDecimals >= 0 + && customDecimals < 36 if (!validDecimals) { - errors.customDecimals = t('decimalsMustZerotoTen') + errors.customDecimals = this.context.t('decimalsMustZerotoTen') } const symbolLen = customSymbol.trim().length const validSymbol = symbolLen > 0 && symbolLen < 10 if (!validSymbol) { - errors.customSymbol = t('symbolBetweenZeroTen') + errors.customSymbol = this.context.t('symbolBetweenZeroTen') } const ownAddress = identitiesList.includes(standardAddress) if (ownAddress) { - errors.customAddress = t('personalAddressDetected') + errors.customAddress = this.context.t('personalAddressDetected') } const tokenAlreadyAdded = this.checkExistingAddresses(customAddress) if (tokenAlreadyAdded) { - errors.customAddress = t('tokenAlreadyAdded') + errors.customAddress = this.context.t('tokenAlreadyAdded') } } else if ( Object.entries(selectedTokens) @@ -169,7 +178,7 @@ AddTokenScreen.prototype.validate = function () { isEmpty && !isSelected ), true) ) { - errors.tokenSelector = t('mustSelectOne') + errors.tokenSelector = this.context.t('mustSelectOne') } return { @@ -199,7 +208,7 @@ AddTokenScreen.prototype.renderCustomForm = function () { 'add-token__add-custom-field--error': errors.customAddress, }), }, [ - h('div.add-token__add-custom-label', t('tokenAddress')), + h('div.add-token__add-custom-label', this.context.t('tokenAddress')), h('input.add-token__add-custom-input', { type: 'text', onChange: this.tokenAddressDidChange, @@ -212,7 +221,7 @@ AddTokenScreen.prototype.renderCustomForm = function () { 'add-token__add-custom-field--error': errors.customSymbol, }), }, [ - h('div.add-token__add-custom-label', t('tokenSymbol')), + h('div.add-token__add-custom-label', this.context.t('tokenSymbol')), h('input.add-token__add-custom-input', { type: 'text', onChange: this.tokenSymbolDidChange, @@ -226,7 +235,7 @@ AddTokenScreen.prototype.renderCustomForm = function () { 'add-token__add-custom-field--error': errors.customDecimals, }), }, [ - h('div.add-token__add-custom-label', t('decimal')), + h('div.add-token__add-custom-label', this.context.t('decimal')), h('input.add-token__add-custom-input', { type: 'number', onChange: this.tokenDecimalsDidChange, @@ -248,7 +257,7 @@ AddTokenScreen.prototype.renderTokenList = function () { const results = [...addressSearchResult, ...fuseSearchResult] return h('div', [ - results.length > 0 && h('div.add-token__token-icons-title', t('popularTokens')), + results.length > 0 && h('div.add-token__token-icons-title', this.context.t('popularTokens')), h('div.add-token__token-icons-container', Array(6).fill(undefined) .map((_, i) => { const { logo, symbol, name, address } = results[i] || {} @@ -302,11 +311,8 @@ AddTokenScreen.prototype.renderConfirmation = function () { return ( h('div.add-token', [ h('div.add-token__wrapper', [ - h('div.add-token__title-container.add-token__confirmation-title', [ - h('div.add-token__description', t('likeToAddTokens')), - ]), h('div.add-token__content-container.add-token__confirmation-content', [ - h('div.add-token__description.add-token__confirmation-description', t('balances')), + h('div.add-token__description.add-token__confirmation-description', this.context.t('balances')), h('div.add-token__confirmation-token-list', Object.entries(tokens) .map(([ address, token ]) => ( @@ -325,10 +331,10 @@ AddTokenScreen.prototype.renderConfirmation = function () { h('div.add-token__buttons', [ h('button.btn-secondary--lg.add-token__cancel-button', { onClick: () => this.setState({ isShowingConfirmation: false }), - }, t('back')), + }, this.context.t('back')), h('button.btn-primary--lg', { onClick: () => addTokens(tokens).then(goHome), - }, t('addTokens')), + }, this.context.t('addTokens')), ]), ]) ) @@ -339,23 +345,28 @@ AddTokenScreen.prototype.displayTab = function (selectedTab) { } AddTokenScreen.prototype.renderTabs = function () { - const { displayedTab, errors } = this.state + const { isShowingInfoBox, displayedTab, errors } = this.state return displayedTab === 'CUSTOM_TOKEN' ? this.renderCustomForm() : h('div', [ h('div.add-token__wrapper', [ h('div.add-token__content-container', [ - h('div.add-token__info-box', [ - h('div.add-token__info-box__close'), - h('div.add-token__info-box__title', t('whatsThis')), - h('div.add-token__info-box__copy', t('keepTrackTokens')), - h('div.add-token__info-box__copy--blue', t('learnMore')), + isShowingInfoBox && h('div.add-token__info-box', [ + h('div.add-token__info-box__close', { + onClick: () => this.setState({ isShowingInfoBox: false }), + }), + h('div.add-token__info-box__title', this.context.t('whatsThis')), + 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', [ h('input.add-token__input', { type: 'text', - placeholder: t('searchTokens'), + placeholder: this.context.t('searchTokens'), onChange: e => this.setState({ searchQuery: e.target.value }), }), h('div.add-token__search-input-error-message', errors.tokenSelector), @@ -379,26 +390,27 @@ AddTokenScreen.prototype.render = function () { onClick: () => goHome(), }, [ h('i.fa.fa-angle-left.fa-lg'), - h('span', t('cancel')), + h('span', this.context.t('cancel')), ]), - h('div.add-token__header__title', t('addTokens')), + h('div.add-token__header__title', this.context.t('addTokens')), + isShowingConfirmation && h('div.add-token__header__subtitle', this.context.t('likeToAddTokens')), !isShowingConfirmation && h('div.add-token__header__tabs', [ h('div.add-token__header__tabs__tab', { className: classnames('add-token__header__tabs__tab', { 'add-token__header__tabs__selected': displayedTab === 'SEARCH', - 'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'SEARCH', + 'add-token__header__tabs__unselected': displayedTab !== 'SEARCH', }), onClick: () => this.displayTab('SEARCH'), - }, t('search')), + }, this.context.t('search')), h('div.add-token__header__tabs__tab', { className: classnames('add-token__header__tabs__tab', { 'add-token__header__tabs__selected': displayedTab === 'CUSTOM_TOKEN', - 'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'CUSTOM_TOKEN', + 'add-token__header__tabs__unselected': displayedTab !== 'CUSTOM_TOKEN', }), onClick: () => this.displayTab('CUSTOM_TOKEN'), - }, t('customToken')), + }, this.context.t('customToken')), ]), ]), @@ -410,10 +422,10 @@ AddTokenScreen.prototype.render = function () { !isShowingConfirmation && h('div.add-token__buttons', [ h('button.btn-secondary--lg.add-token__cancel-button', { onClick: goHome, - }, t('cancel')), + }, this.context.t('cancel')), h('button.btn-primary--lg.add-token__confirm-button', { onClick: this.onNext, - }, t('next')), + }, this.context.t('next')), ]), ]) } diff --git a/ui/app/app.js b/ui/app/app.js index d1b17ab5d..0b7a7a1e0 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -2,9 +2,9 @@ const inherits = require('util').inherits const Component = require('react').Component const connect = require('react-redux').connect const h = require('react-hyperscript') +const PropTypes = require('prop-types') const actions = require('./actions') const classnames = require('classnames') -const t = require('../i18n') // mascara const MascaraFirstTime = require('../../mascara/src/app/first-time').default @@ -46,8 +46,13 @@ const QrView = require('./components/qr-code') // Global Modals const Modal = require('./components/modals/index').Modal +App.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(App) + inherits(App, Component) function App () { Component.call(this) } @@ -289,13 +294,13 @@ App.prototype.renderAppBar = function () { h('img.metafox-icon', { height: 42, width: 42, - src: '/images/metamask-fox.svg', + src: './images/metamask-fox.svg', }), // metamask name h('.flex-row', [ - h('h1', t('appName')), - h('div.beta-label', t('beta')), + h('h1', this.context.t('appName')), + h('div.beta-label', this.context.t('beta')), ]), ]), @@ -557,15 +562,15 @@ App.prototype.getConnectingLabel = function () { let name if (providerName === 'mainnet') { - name = t('connectingToMainnet') + name = this.context.t('connectingToMainnet') } else if (providerName === 'ropsten') { - name = t('connectingToRopsten') + name = this.context.t('connectingToRopsten') } else if (providerName === 'kovan') { - name = t('connectingToRopsten') + name = this.context.t('connectingToRopsten') } else if (providerName === 'rinkeby') { - name = t('connectingToRinkeby') + name = this.context.t('connectingToRinkeby') } else { - name = t('connectingToUnknown') + name = this.context.t('connectingToUnknown') } return name @@ -578,15 +583,15 @@ App.prototype.getNetworkName = function () { let name if (providerName === 'mainnet') { - name = t('mainnet') + name = this.context.t('mainnet') } else if (providerName === 'ropsten') { - name = t('ropsten') + name = this.context.t('ropsten') } else if (providerName === 'kovan') { - name = t('kovan') + name = this.context.t('kovan') } else if (providerName === 'rinkeby') { - name = t('rinkeby') + name = this.context.t('rinkeby') } else { - name = t('unknownNetwork') + name = this.context.t('unknownNetwork') } return name diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js index 1612d7b6a..03955e077 100644 --- a/ui/app/components/account-dropdowns.js +++ b/ui/app/components/account-dropdowns.js @@ -9,7 +9,6 @@ const DropdownMenuItem = require('./dropdown').DropdownMenuItem const Identicon = require('./identicon') const ethUtil = require('ethereumjs-util') const copyToClipboard = require('copy-to-clipboard') -const t = require('../../i18n') class AccountDropdowns extends Component { constructor (props) { @@ -80,7 +79,7 @@ class AccountDropdowns extends Component { try { // Sometimes keyrings aren't loaded yet: const type = keyring.type const isLoose = type !== 'HD Key Tree' - return isLoose ? h('.keyring-label.allcaps', t('loose')) : null + return isLoose ? h('.keyring-label.allcaps', this.context.t('loose')) : null } catch (e) { return } } @@ -130,7 +129,7 @@ class AccountDropdowns extends Component { diameter: 32, }, ), - h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, t('createAccount')), + h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, this.context.t('createAccount')), ], ), h( @@ -155,7 +154,7 @@ class AccountDropdowns extends Component { fontSize: '24px', marginBottom: '5px', }, - }, t('importAccount')), + }, this.context.t('importAccount')), ] ), ] @@ -193,7 +192,7 @@ class AccountDropdowns extends Component { global.platform.openWindow({ url }) }, }, - t('etherscanView'), + this.context.t('etherscanView'), ), h( DropdownMenuItem, @@ -205,7 +204,7 @@ class AccountDropdowns extends Component { actions.showQrView(selected, identity ? identity.name : '') }, }, - t('showQRCode'), + this.context.t('showQRCode'), ), h( DropdownMenuItem, @@ -217,7 +216,7 @@ class AccountDropdowns extends Component { copyToClipboard(checkSumAddress) }, }, - t('copyAddress'), + this.context.t('copyAddress'), ), h( DropdownMenuItem, @@ -227,7 +226,7 @@ class AccountDropdowns extends Component { actions.requestAccountExport() }, }, - t('exportPrivateKey'), + this.context.t('exportPrivateKey'), ), ] ) @@ -301,6 +300,7 @@ AccountDropdowns.propTypes = { style: PropTypes.object, enableAccountOptions: PropTypes.bool, enableAccountsSelector: PropTypes.bool, + t: PropTypes.func, } const mapDispatchToProps = (dispatch) => { @@ -316,6 +316,10 @@ const mapDispatchToProps = (dispatch) => { } } +AccountDropdowns.contextTypes = { + t: PropTypes.func, +} + module.exports = { AccountDropdowns: connect(null, mapDispatchToProps)(AccountDropdowns), } diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js index 5637bc8d0..865207487 100644 --- a/ui/app/components/account-export.js +++ b/ui/app/components/account-export.js @@ -1,15 +1,20 @@ const Component = require('react').Component const h = require('react-hyperscript') +const PropTypes = require('prop-types') const inherits = require('util').inherits const exportAsFile = require('../util').exportAsFile const copyToClipboard = require('copy-to-clipboard') const actions = require('../actions') const ethUtil = require('ethereumjs-util') const connect = require('react-redux').connect -const t = require('../../i18n') + +ExportAccountView.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps)(ExportAccountView) + inherits(ExportAccountView, Component) function ExportAccountView () { Component.call(this) @@ -36,7 +41,7 @@ ExportAccountView.prototype.render = function () { if (notExporting) return h('div') if (exportRequested) { - const warning = t('exportPrivateKeyWarning') + const warning = this.context.t('exportPrivateKeyWarning') return ( h('div', { style: { @@ -54,7 +59,7 @@ ExportAccountView.prototype.render = function () { h('p.error', warning), h('input#exportAccount.sizing-input', { type: 'password', - placeholder: t('confirmPassword').toLowerCase(), + placeholder: this.context.t('confirmPassword').toLowerCase(), onKeyPress: this.onExportKeyPress.bind(this), style: { position: 'relative', @@ -75,10 +80,10 @@ ExportAccountView.prototype.render = function () { style: { marginRight: '10px', }, - }, t('submit')), + }, this.context.t('submit')), h('button', { onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)), - }, t('cancel')), + }, this.context.t('cancel')), ]), (this.props.warning) && ( h('span.error', { @@ -99,7 +104,7 @@ ExportAccountView.prototype.render = function () { margin: '0 20px', }, }, [ - h('label', t('copyPrivateKey') + ':'), + h('label', this.context.t('copyPrivateKey') + ':'), h('p.error.cursor-pointer', { style: { textOverflow: 'ellipsis', @@ -113,13 +118,13 @@ ExportAccountView.prototype.render = function () { }, plainKey), h('button', { onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)), - }, t('done')), + }, this.context.t('done')), h('button', { style: { marginLeft: '10px', }, onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey), - }, t('saveAsFile')), + }, this.context.t('saveAsFile')), ]) } } diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index e838e8916..21de358d6 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -1,15 +1,20 @@ 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') const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu') const Identicon = require('../identicon') const { formatBalance } = require('../../util') -const t = require('../../../i18n') + +AccountMenu.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountMenu) + inherits(AccountMenu, Component) function AccountMenu () { Component.call(this) } @@ -71,10 +76,10 @@ AccountMenu.prototype.render = function () { h(Item, { className: 'account-menu__header', }, [ - t('myAccounts'), + this.context.t('myAccounts'), h('button.account-menu__logout-button', { onClick: lockMetamask, - }, t('logout')), + }, this.context.t('logout')), ]), h(Divider), h('div.account-menu__accounts', this.renderAccounts()), @@ -82,23 +87,23 @@ AccountMenu.prototype.render = function () { h(Item, { onClick: () => showNewAccountPage('CREATE'), icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }), - text: t('createAccount'), + text: this.context.t('createAccount'), }), h(Item, { onClick: () => showNewAccountPage('IMPORT'), icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }), - text: t('importAccount'), + text: this.context.t('importAccount'), }), h(Divider), h(Item, { onClick: showInfoPage, icon: h('img', { src: 'images/mm-info-icon.svg' }), - text: t('infoHelp'), + text: this.context.t('infoHelp'), }), h(Item, { onClick: showConfigPage, icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }), - text: t('settings'), + text: this.context.t('settings'), }), ]) } @@ -156,6 +161,6 @@ AccountMenu.prototype.indicateIfLoose = function (keyring) { try { // Sometimes keyrings aren't loaded yet: const type = keyring.type const isLoose = type !== 'HD Key Tree' - return isLoose ? h('.keyring-label.allcaps', t('imported')) : null + return isLoose ? h('.keyring-label.allcaps', this.context.t('imported')) : null } catch (e) { return } } diff --git a/ui/app/components/bn-as-decimal-input.js b/ui/app/components/bn-as-decimal-input.js index 70701b039..9a033f893 100644 --- a/ui/app/components/bn-as-decimal-input.js +++ b/ui/app/components/bn-as-decimal-input.js @@ -1,12 +1,18 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const extend = require('xtend') -const t = require('../../i18n') +const connect = require('react-redux').connect + +BnAsDecimalInput.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(BnAsDecimalInput) -module.exports = BnAsDecimalInput inherits(BnAsDecimalInput, Component) function BnAsDecimalInput () { @@ -137,13 +143,13 @@ BnAsDecimalInput.prototype.constructWarning = function () { let message = name ? name + ' ' : '' if (min && max) { - message += t('betweenMinAndMax', [`${newMin} ${suffix}`, `${newMax} ${suffix}`]) + message += this.context.t('betweenMinAndMax', [`${newMin} ${suffix}`, `${newMax} ${suffix}`]) } else if (min) { - message += t('greaterThanMin', [`${newMin} ${suffix}`]) + message += this.context.t('greaterThanMin', [`${newMin} ${suffix}`]) } else if (max) { - message += t('lessThanMax', [`${newMax} ${suffix}`]) + message += this.context.t('lessThanMax', [`${newMax} ${suffix}`]) } else { - message += t('invalidInput') + message += this.context.t('invalidInput') } return message diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js index 1e277a94b..9ac565cf4 100644 --- a/ui/app/components/buy-button-subview.js +++ b/ui/app/components/buy-button-subview.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect @@ -9,10 +10,14 @@ const Loading = require('./loading') const AccountPanel = require('./account-panel') const RadioList = require('./custom-radio-list') const networkNames = require('../../../app/scripts/config.js').networkNames -const t = require('../../i18n') + +BuyButtonSubview.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps)(BuyButtonSubview) + function mapStateToProps (state) { return { identity: state.appState.identity, @@ -77,7 +82,7 @@ BuyButtonSubview.prototype.headerSubview = function () { paddingTop: '4px', paddingBottom: '4px', }, - }, t('depositEth')), + }, this.context.t('depositEth')), ]), // loading indication @@ -119,7 +124,7 @@ BuyButtonSubview.prototype.headerSubview = function () { paddingTop: '4px', paddingBottom: '4px', }, - }, t('selectService')), + }, this.context.t('selectService')), ]), ]) @@ -144,7 +149,7 @@ BuyButtonSubview.prototype.primarySubview = function () { case '4': case '42': const networkName = networkNames[network] - const label = `${networkName} ${t('testFaucet')}` + const label = `${networkName} ${this.context.t('testFaucet')}` return ( h('div.flex-column', { style: { @@ -165,14 +170,14 @@ BuyButtonSubview.prototype.primarySubview = function () { style: { marginTop: '15px', }, - }, t('borrowDharma')) + }, this.context.t('borrowDharma')) ) : null, ]) ) default: return ( - h('h2.error', t('unknownNetworkId')) + h('h2.error', this.context.t('unknownNetworkId')) ) } @@ -204,8 +209,8 @@ BuyButtonSubview.prototype.mainnetSubview = function () { 'ShapeShift', ], subtext: { - 'Coinbase': `${t('crypto')}/${t('fiat')} (${t('usaOnly')})`, - 'ShapeShift': t('crypto'), + 'Coinbase': `${this.context.t('crypto')}/${this.context.t('fiat')} (${this.context.t('usaOnly')})`, + 'ShapeShift': this.context.t('crypto'), }, onClick: this.radioHandler.bind(this), }), diff --git a/ui/app/components/coinbase-form.js b/ui/app/components/coinbase-form.js index e442b43d5..d5915292e 100644 --- a/ui/app/components/coinbase-form.js +++ b/ui/app/components/coinbase-form.js @@ -1,12 +1,17 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../actions') -const t = require('../../i18n') + +CoinbaseForm.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps)(CoinbaseForm) + function mapStateToProps (state) { return { warning: state.appState.warning, @@ -38,11 +43,11 @@ CoinbaseForm.prototype.render = function () { }, [ h('button.btn-green', { onClick: this.toCoinbase.bind(this), - }, t('continueToCoinbase')), + }, this.context.t('continueToCoinbase')), h('button.btn-red', { onClick: () => props.dispatch(actions.goHome()), - }, t('cancel')), + }, this.context.t('cancel')), ]), ]) } diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js index 355f78d45..a60d33523 100644 --- a/ui/app/components/copyButton.js +++ b/ui/app/components/copyButton.js @@ -1,12 +1,18 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const copyToClipboard = require('copy-to-clipboard') -const t = require('../../i18n') +const connect = require('react-redux').connect const Tooltip = require('./tooltip') -module.exports = CopyButton +CopyButton.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(CopyButton) + inherits(CopyButton, Component) function CopyButton () { @@ -23,7 +29,7 @@ CopyButton.prototype.render = function () { const value = props.value const copied = state.copied - const message = copied ? t('copiedButton') : props.title || t('copyButton') + const message = copied ? this.context.t('copiedButton') : props.title || this.context.t('copyButton') return h('.copy-button', { style: { diff --git a/ui/app/components/copyable.js b/ui/app/components/copyable.js index fca7d3863..ad504deb8 100644 --- a/ui/app/components/copyable.js +++ b/ui/app/components/copyable.js @@ -1,12 +1,18 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const Tooltip = require('./tooltip') const copyToClipboard = require('copy-to-clipboard') -const t = require('../../i18n') +const connect = require('react-redux').connect + +Copyable.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(Copyable) -module.exports = Copyable inherits(Copyable, Component) function Copyable () { @@ -23,7 +29,7 @@ Copyable.prototype.render = function () { const { copied } = state return h(Tooltip, { - title: copied ? t('copiedExclamation') : t('copy'), + title: copied ? this.context.t('copiedExclamation') : this.context.t('copy'), position: 'bottom', }, h('span', { style: { diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js index 22ad98ce4..4c693d1c3 100644 --- a/ui/app/components/customize-gas-modal/index.js +++ b/ui/app/components/customize-gas-modal/index.js @@ -1,9 +1,9 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') const GasModalCard = require('./gas-modal-card') const ethUtil = require('ethereumjs-util') @@ -65,6 +65,7 @@ function mapDispatchToProps (dispatch) { updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)), updateGasTotal: newGasTotal => dispatch(actions.updateGasTotal(newGasTotal)), updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)), + updateSendErrors: error => dispatch(actions.updateSendErrors(error)), } } @@ -95,8 +96,13 @@ function CustomizeGasModal (props) { this.state = getOriginalState(props) } +CustomizeGasModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(CustomizeGasModal) + CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) { const { updateGasPrice, @@ -107,6 +113,7 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) { selectedToken, balance, updateSendAmount, + updateSendErrors, } = this.props if (maxModeOn && !selectedToken) { @@ -121,6 +128,7 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) { updateGasPrice(ethUtil.addHexPrefix(gasPrice)) updateGasLimit(ethUtil.addHexPrefix(gasLimit)) updateGasTotal(ethUtil.addHexPrefix(gasTotal)) + updateSendErrors({ insufficientFunds: false }) hideModal() } @@ -150,7 +158,7 @@ CustomizeGasModal.prototype.validate = function ({ gasTotal, gasLimit }) { }) if (!balanceIsSufficient) { - error = t('balanceIsInsufficientGas') + error = this.context.t('balanceIsInsufficientGas') } const gasLimitTooLow = gasLimit && conversionGreaterThan( @@ -166,7 +174,7 @@ CustomizeGasModal.prototype.validate = function ({ gasTotal, gasLimit }) { ) if (gasLimitTooLow) { - error = t('gasLimitTooLow') + error = this.context.t('gasLimitTooLow') } this.setState({ error }) @@ -259,7 +267,7 @@ CustomizeGasModal.prototype.render = function () { }, [ h('div.send-v2__customize-gas__header', {}, [ - h('div.send-v2__customize-gas__title', t('customGas')), + h('div.send-v2__customize-gas__title', this.context.t('customGas')), h('div.send-v2__customize-gas__close', { onClick: hideModal, @@ -275,8 +283,8 @@ CustomizeGasModal.prototype.render = function () { // max: 1000, step: multiplyCurrencies(MIN_GAS_PRICE_GWEI, 10), onChange: value => this.convertAndSetGasPrice(value), - title: t('gasPrice'), - copy: t('gasPriceCalculation'), + title: this.context.t('gasPrice'), + copy: this.context.t('gasPriceCalculation'), }), h(GasModalCard, { @@ -285,8 +293,8 @@ CustomizeGasModal.prototype.render = function () { // max: 100000, step: 1, onChange: value => this.convertAndSetGasLimit(value), - title: t('gasLimit'), - copy: t('gasLimitCalculation'), + title: this.context.t('gasLimit'), + copy: this.context.t('gasLimitCalculation'), }), ]), @@ -299,7 +307,7 @@ CustomizeGasModal.prototype.render = function () { h('div.send-v2__customize-gas__revert', { onClick: () => this.revert(), - }, [t('revert')]), + }, [this.context.t('revert')]), h('div.send-v2__customize-gas__buttons', [ h('button.btn-secondary.send-v2__customize-gas__cancel', { @@ -307,12 +315,12 @@ CustomizeGasModal.prototype.render = function () { style: { marginRight: '10px', }, - }, [t('cancel')]), + }, [this.context.t('cancel')]), h('button.btn-primary.send-v2__customize-gas__save', { onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal), className: error && 'btn-primary--disabled', - }, [t('save')]), + }, [this.context.t('save')]), ]), ]), diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js index e5359c1d6..a133f0e29 100644 --- a/ui/app/components/dropdowns/components/account-dropdowns.js +++ b/ui/app/components/dropdowns/components/account-dropdowns.js @@ -10,7 +10,7 @@ const Identicon = require('../../identicon') const ethUtil = require('ethereumjs-util') const copyToClipboard = require('copy-to-clipboard') const { formatBalance } = require('../../../util') -const t = require('../../../../i18n') + class AccountDropdowns extends Component { constructor (props) { @@ -130,7 +130,7 @@ class AccountDropdowns extends Component { actions.showEditAccountModal(identity) }, }, [ - t('edit'), + this.context.t('edit'), ]), ]), @@ -144,7 +144,7 @@ class AccountDropdowns extends Component { try { // Sometimes keyrings aren't loaded yet: const type = keyring.type const isLoose = type !== 'HD Key Tree' - return isLoose ? h('.keyring-label.allcaps', t('loose')) : null + return isLoose ? h('.keyring-label.allcaps', this.context.t('loose')) : null } catch (e) { return } } @@ -202,7 +202,7 @@ class AccountDropdowns extends Component { fontSize: '16px', lineHeight: '23px', }, - }, t('createAccount')), + }, this.context.t('createAccount')), ], ), h( @@ -236,7 +236,7 @@ class AccountDropdowns extends Component { fontSize: '16px', lineHeight: '23px', }, - }, t('importAccount')), + }, this.context.t('importAccount')), ] ), ] @@ -287,7 +287,7 @@ class AccountDropdowns extends Component { menuItemStyles, ), }, - t('accountDetails'), + this.context.t('accountDetails'), ), h( DropdownMenuItem, @@ -303,7 +303,7 @@ class AccountDropdowns extends Component { menuItemStyles, ), }, - t('etherscanView'), + this.context.t('etherscanView'), ), h( DropdownMenuItem, @@ -319,7 +319,7 @@ class AccountDropdowns extends Component { menuItemStyles, ), }, - t('copyAddress'), + this.context.t('copyAddress'), ), h( DropdownMenuItem, @@ -331,7 +331,7 @@ class AccountDropdowns extends Component { menuItemStyles, ), }, - t('exportPrivateKey'), + this.context.t('exportPrivateKey'), ), h( DropdownMenuItem, @@ -346,7 +346,7 @@ class AccountDropdowns extends Component { menuItemStyles, ), }, - t('addToken'), + this.context.t('addToken'), ), ] @@ -425,6 +425,7 @@ AccountDropdowns.propTypes = { enableAccountsSelector: PropTypes.bool, enableAccountOption: PropTypes.bool, enableAccountOptions: PropTypes.bool, + t: PropTypes.func, } const mapDispatchToProps = (dispatch) => { @@ -463,4 +464,9 @@ function mapStateToProps (state) { } } +AccountDropdowns.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDropdowns) + diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js index 5afe730c1..9e47f38ef 100644 --- a/ui/app/components/dropdowns/network-dropdown.js +++ b/ui/app/components/dropdowns/network-dropdown.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect @@ -6,9 +7,9 @@ const actions = require('../../actions') const Dropdown = require('./components/dropdown').Dropdown const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem const NetworkDropdownIcon = require('./components/network-dropdown-icon') -const t = require('../../../i18n') const R = require('ramda') + // classes from nodes of the toggle element. const notToggleElementClassnames = [ 'menu-icon', @@ -54,8 +55,13 @@ function NetworkDropdown () { Component.call(this) } +NetworkDropdown.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(NetworkDropdown) + // TODO: specify default props and proptypes NetworkDropdown.prototype.render = function () { const props = this.props @@ -94,13 +100,13 @@ NetworkDropdown.prototype.render = function () { }, [ h('div.network-dropdown-header', {}, [ - h('div.network-dropdown-title', {}, t('networks')), + h('div.network-dropdown-title', {}, this.context.t('networks')), h('div.network-dropdown-divider'), h('div.network-dropdown-content', {}, - t('defaultNetwork') + this.context.t('defaultNetwork') ), ]), @@ -122,7 +128,7 @@ NetworkDropdown.prototype.render = function () { style: { color: providerType === 'mainnet' ? '#ffffff' : '#9b9b9b', }, - }, t('mainnet')), + }, this.context.t('mainnet')), ] ), @@ -144,7 +150,7 @@ NetworkDropdown.prototype.render = function () { style: { color: providerType === 'ropsten' ? '#ffffff' : '#9b9b9b', }, - }, t('ropsten')), + }, this.context.t('ropsten')), ] ), @@ -166,7 +172,7 @@ NetworkDropdown.prototype.render = function () { style: { color: providerType === 'kovan' ? '#ffffff' : '#9b9b9b', }, - }, t('kovan')), + }, this.context.t('kovan')), ] ), @@ -188,7 +194,7 @@ NetworkDropdown.prototype.render = function () { style: { color: providerType === 'rinkeby' ? '#ffffff' : '#9b9b9b', }, - }, t('rinkeby')), + }, this.context.t('rinkeby')), ] ), @@ -197,20 +203,20 @@ NetworkDropdown.prototype.render = function () { { key: 'default', closeMenu: () => this.props.hideNetworkDropdown(), - onClick: () => props.setRpcTarget('http://localhost:8545'), + onClick: () => props.setProviderType('localhost'), style: dropdownMenuItemStyle, }, [ - activeNetwork === 'http://localhost:8545' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'), + providerType === 'localhost' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'), h(NetworkDropdownIcon, { - isSelected: activeNetwork === 'http://localhost:8545', + isSelected: providerType === 'localhost', innerBorder: '1px solid #9b9b9b', }), h('span.network-name-item', { style: { - color: activeNetwork === 'http://localhost:8545' ? '#ffffff' : '#9b9b9b', + color: providerType === 'localhost' ? '#ffffff' : '#9b9b9b', }, - }, t('localhost')), + }, this.context.t('localhost')), ] ), @@ -234,7 +240,7 @@ NetworkDropdown.prototype.render = function () { style: { color: activeNetwork === 'custom' ? '#ffffff' : '#9b9b9b', }, - }, t('customRPC')), + }, this.context.t('customRPC')), ] ), @@ -249,15 +255,15 @@ NetworkDropdown.prototype.getNetworkName = function () { let name if (providerName === 'mainnet') { - name = t('mainnet') + name = this.context.t('mainnet') } else if (providerName === 'ropsten') { - name = t('ropsten') + name = this.context.t('ropsten') } else if (providerName === 'kovan') { - name = t('kovan') + name = this.context.t('kovan') } else if (providerName === 'rinkeby') { - name = t('rinkeby') + name = this.context.t('rinkeby') } else { - name = t('unknownNetwork') + name = this.context.t('unknownNetwork') } return name diff --git a/ui/app/components/dropdowns/token-menu-dropdown.js b/ui/app/components/dropdowns/token-menu-dropdown.js index a4f93b505..b70d0b893 100644 --- a/ui/app/components/dropdowns/token-menu-dropdown.js +++ b/ui/app/components/dropdowns/token-menu-dropdown.js @@ -1,12 +1,18 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') + + +TokenMenuDropdown.contextTypes = { + t: PropTypes.func, +} module.exports = connect(null, mapDispatchToProps)(TokenMenuDropdown) + function mapDispatchToProps (dispatch) { return { showHideTokenConfirmationModal: (token) => { @@ -44,7 +50,7 @@ TokenMenuDropdown.prototype.render = function () { showHideTokenConfirmationModal(this.props.token) this.props.onClose() }, - }, t('hideToken')), + }, this.context.t('hideToken')), ]), ]), diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js index 1b2d4009d..feb0a7037 100644 --- a/ui/app/components/ens-input.js +++ b/ui/app/components/ens-input.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const extend = require('xtend') @@ -8,11 +9,15 @@ const ENS = require('ethjs-ens') const networkMap = require('ethjs-ens/lib/network-map.json') const ensRE = /.+\..+$/ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' -const t = require('../../i18n') +const connect = require('react-redux').connect const ToAutoComplete = require('./send/to-autocomplete') +EnsInput.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(EnsInput) -module.exports = EnsInput inherits(EnsInput, Component) function EnsInput () { @@ -27,10 +32,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, @@ -71,13 +76,13 @@ EnsInput.prototype.lookupEnsName = function (recipient) { log.info(`ENS attempting to resolve name: ${recipient}`) this.ens.lookup(recipient.trim()) .then((address) => { - if (address === ZERO_ADDRESS) throw new Error(t('noAddressForName')) + if (address === ZERO_ADDRESS) throw new Error(this.context.t('noAddressForName')) if (address !== ensResolution) { this.setState({ loadingEns: false, ensResolution: address, nickname: recipient.trim(), - hoverText: address + '\n' + t('clickCopy'), + hoverText: address + '\n' + this.context.t('clickCopy'), ensFailure: false, }) } diff --git a/ui/app/components/hex-as-decimal-input.js b/ui/app/components/hex-as-decimal-input.js index a43d44f89..75303a34a 100644 --- a/ui/app/components/hex-as-decimal-input.js +++ b/ui/app/components/hex-as-decimal-input.js @@ -1,12 +1,18 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const extend = require('xtend') -const t = require('../../i18n') +const connect = require('react-redux').connect + +HexAsDecimalInput.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(HexAsDecimalInput) -module.exports = HexAsDecimalInput inherits(HexAsDecimalInput, Component) function HexAsDecimalInput () { @@ -127,13 +133,13 @@ HexAsDecimalInput.prototype.constructWarning = function () { let message = name ? name + ' ' : '' if (min && max) { - message += t('betweenMinAndMax', [min, max]) + message += this.context.t('betweenMinAndMax', [min, max]) } else if (min) { - message += t('greaterThanMin', [min]) + message += this.context.t('greaterThanMin', [min]) } else if (max) { - message += t('lessThanMax', [max]) + message += this.context.t('lessThanMax', [max]) } else { - message += t('invalidInput') + message += this.context.t('invalidInput') } return message diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js index b803b7ceb..dce9b0449 100644 --- a/ui/app/components/identicon.js +++ b/ui/app/components/identicon.js @@ -47,7 +47,7 @@ IdenticonComponent.prototype.render = function () { ) : ( h('img.balance-icon', { - src: '../images/eth_logo.svg', + src: './images/eth_logo.svg', style: { height: diameter, width: diameter, @@ -105,9 +105,8 @@ IdenticonComponent.prototype.componentDidUpdate = function () { function _generateBlockie (container, address, diameter) { const img = new Image() img.src = toDataUrl(address) - const dia = !diameter || diameter < 50 ? 50 : diameter - img.height = dia * 1.25 - img.width = dia * 1.25 + img.height = diameter + img.width = diameter container.appendChild(img) } diff --git a/ui/app/components/modals/account-details-modal.js b/ui/app/components/modals/account-details-modal.js index 927d73482..d9885daf5 100644 --- a/ui/app/components/modals/account-details-modal.js +++ b/ui/app/components/modals/account-details-modal.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect @@ -8,7 +9,6 @@ const { getSelectedIdentity } = require('../../selectors') const genAccountLink = require('../../../lib/account-link.js') const QrView = require('../qr-code') const EditableLabel = require('../editable-label') -const t = require('../../../i18n') function mapStateToProps (state) { return { @@ -34,8 +34,13 @@ function AccountDetailsModal () { Component.call(this) } +AccountDetailsModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) + // Not yet pixel perfect todos: // fonts of qr-header @@ -65,12 +70,12 @@ AccountDetailsModal.prototype.render = function () { h('button.btn-primary.account-modal__button', { onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }), - }, t('etherscanView')), + }, this.context.t('etherscanView')), // Holding on redesign for Export Private Key functionality h('button.btn-primary.account-modal__button', { onClick: () => showExportPrivateKeyModal(), - }, t('exportPrivateKey')), + }, this.context.t('exportPrivateKey')), ]) } diff --git a/ui/app/components/modals/account-modal-container.js b/ui/app/components/modals/account-modal-container.js index 08540aa76..a9856b20f 100644 --- a/ui/app/components/modals/account-modal-container.js +++ b/ui/app/components/modals/account-modal-container.js @@ -1,11 +1,11 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') const { getSelectedIdentity } = require('../../selectors') const Identicon = require('../identicon') -const t = require('../../../i18n') function mapStateToProps (state) { return { @@ -26,8 +26,13 @@ function AccountModalContainer () { Component.call(this) } +AccountModalContainer.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountModalContainer) + AccountModalContainer.prototype.render = function () { const { selectedIdentity, @@ -60,7 +65,7 @@ AccountModalContainer.prototype.render = function () { h('i.fa.fa-angle-left.fa-lg'), - h('span.account-modal-back__text', ' ' + t('back')), + h('span.account-modal-back__text', ' ' + this.context.t('back')), ]), diff --git a/ui/app/components/modals/buy-options-modal.js b/ui/app/components/modals/buy-options-modal.js index 7eb73c3a6..d871e7516 100644 --- a/ui/app/components/modals/buy-options-modal.js +++ b/ui/app/components/modals/buy-options-modal.js @@ -1,10 +1,10 @@ const Component = require('react').Component +const PropTypes = require('prop-types') 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 t = require('../../../i18n') function mapStateToProps (state) { return { @@ -33,8 +33,13 @@ function BuyOptions () { Component.call(this) } +BuyOptions.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(BuyOptions) + BuyOptions.prototype.renderModalContentOption = function (title, header, onClick) { return h('div.buy-modal-content-option', { onClick, @@ -57,15 +62,15 @@ BuyOptions.prototype.render = function () { }, [ h('div.buy-modal-content-title', { style: {}, - }, t('transfers')), - h('div', {}, t('howToDeposit')), + }, this.context.t('transfers')), + h('div', {}, this.context.t('howToDeposit')), ]), h('div.buy-modal-content-options.flex-column.flex-center', {}, [ isTestNetwork - ? this.renderModalContentOption(networkName, t('testFaucet'), () => toFaucet(network)) - : this.renderModalContentOption('Coinbase', t('depositFiat'), () => toCoinbase(address)), + ? this.renderModalContentOption(networkName, this.context.t('testFaucet'), () => toFaucet(network)) + : this.renderModalContentOption('Coinbase', this.context.t('depositFiat'), () => toCoinbase(address)), // h('div.buy-modal-content-option', {}, [ // h('div.buy-modal-content-option-title', {}, 'Shapeshift'), @@ -73,8 +78,8 @@ BuyOptions.prototype.render = function () { // ]),, this.renderModalContentOption( - t('directDeposit'), - t('depositFromAccount'), + this.context.t('directDeposit'), + this.context.t('depositFromAccount'), () => this.goToAccountDetailsModal() ), @@ -85,7 +90,7 @@ BuyOptions.prototype.render = function () { background: 'white', }, onClick: () => { this.props.hideModal() }, - }, h('div.buy-modal-content-footer#buy-modal-content-footer-text', {}, t('cancel'))), + }, h('div.buy-modal-content-footer#buy-modal-content-footer-text', {}, this.context.t('cancel'))), ]), ]) } diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js index 2de1240fc..0dc611f50 100644 --- a/ui/app/components/modals/deposit-ether-modal.js +++ b/ui/app/components/modals/deposit-ether-modal.js @@ -1,22 +1,19 @@ const Component = require('react').Component +const PropTypes = require('prop-types') 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 ShapeshiftForm = require('../shapeshift-form') -const t = require('../../../i18n') -const DIRECT_DEPOSIT_ROW_TITLE = t('directDepositEther') -const DIRECT_DEPOSIT_ROW_TEXT = t('directDepositEtherExplainer') -const COINBASE_ROW_TITLE = t('buyCoinbase') -const COINBASE_ROW_TEXT = t('buyCoinbaseExplainer') -const SHAPESHIFT_ROW_TITLE = t('depositShapeShift') -const SHAPESHIFT_ROW_TEXT = t('depositShapeShiftExplainer') -const FAUCET_ROW_TITLE = t('testFaucet') -const facuetRowText = (networkName) => { - return t('getEtherFromFaucet', [networkName]) -} +let DIRECT_DEPOSIT_ROW_TITLE +let DIRECT_DEPOSIT_ROW_TEXT +let COINBASE_ROW_TITLE +let COINBASE_ROW_TEXT +let SHAPESHIFT_ROW_TITLE +let SHAPESHIFT_ROW_TEXT +let FAUCET_ROW_TITLE function mapStateToProps (state) { return { @@ -44,16 +41,34 @@ function mapDispatchToProps (dispatch) { } inherits(DepositEtherModal, Component) -function DepositEtherModal () { +function DepositEtherModal (props, context) { Component.call(this) + // need to set after i18n locale has loaded + DIRECT_DEPOSIT_ROW_TITLE = context.t('directDepositEther') + DIRECT_DEPOSIT_ROW_TEXT = context.t('directDepositEtherExplainer') + COINBASE_ROW_TITLE = context.t('buyCoinbase') + COINBASE_ROW_TEXT = context.t('buyCoinbaseExplainer') + SHAPESHIFT_ROW_TITLE = context.t('depositShapeShift') + SHAPESHIFT_ROW_TEXT = context.t('depositShapeShiftExplainer') + FAUCET_ROW_TITLE = context.t('testFaucet') + this.state = { buyingWithShapeshift: false, } } +DepositEtherModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal) + +DepositEtherModal.prototype.facuetRowText = function (networkName) { + return this.context.t('getEtherFromFaucet', [networkName]) +} + DepositEtherModal.prototype.renderRow = function ({ logo, title, @@ -113,10 +128,10 @@ DepositEtherModal.prototype.render = function () { h('div.page-container__header', [ - h('div.page-container__title', [t('depositEther')]), + h('div.page-container__title', [this.context.t('depositEther')]), h('div.page-container__subtitle', [ - t('needEtherInWallet'), + this.context.t('needEtherInWallet'), ]), h('div.page-container__header-close', { @@ -135,11 +150,11 @@ DepositEtherModal.prototype.render = function () { this.renderRow({ logo: h('img.deposit-ether-modal__logo', { - src: '../../../images/deposit-eth.svg', + src: './images/deposit-eth.svg', }), title: DIRECT_DEPOSIT_ROW_TITLE, text: DIRECT_DEPOSIT_ROW_TEXT, - buttonLabel: t('viewAccount'), + buttonLabel: this.context.t('viewAccount'), onButtonClick: () => this.goToAccountDetailsModal(), hide: buyingWithShapeshift, }), @@ -147,8 +162,8 @@ DepositEtherModal.prototype.render = function () { this.renderRow({ logo: h('i.fa.fa-tint.fa-2x'), title: FAUCET_ROW_TITLE, - text: facuetRowText(networkName), - buttonLabel: t('getEther'), + text: this.facuetRowText(networkName), + buttonLabel: this.context.t('getEther'), onButtonClick: () => toFaucet(network), hide: !isTestNetwork || buyingWithShapeshift, }), @@ -156,13 +171,13 @@ DepositEtherModal.prototype.render = function () { this.renderRow({ logo: h('div.deposit-ether-modal__logo', { style: { - backgroundImage: 'url(\'../../../images/coinbase logo.png\')', + backgroundImage: 'url(\'./images/coinbase logo.png\')', height: '40px', }, }), title: COINBASE_ROW_TITLE, text: COINBASE_ROW_TEXT, - buttonLabel: t('continueToCoinbase'), + buttonLabel: this.context.t('continueToCoinbase'), onButtonClick: () => toCoinbase(address), hide: isTestNetwork || buyingWithShapeshift, }), @@ -170,12 +185,12 @@ DepositEtherModal.prototype.render = function () { this.renderRow({ logo: h('div.deposit-ether-modal__logo', { style: { - backgroundImage: 'url(\'../../../images/shapeshift logo.png\')', + backgroundImage: 'url(\'./images/shapeshift logo.png\')', }, }), title: SHAPESHIFT_ROW_TITLE, text: SHAPESHIFT_ROW_TEXT, - buttonLabel: t('shapeshiftBuy'), + buttonLabel: this.context.t('shapeshiftBuy'), onButtonClick: () => this.setState({ buyingWithShapeshift: true }), hide: isTestNetwork, hideButton: buyingWithShapeshift, diff --git a/ui/app/components/modals/edit-account-name-modal.js b/ui/app/components/modals/edit-account-name-modal.js index 6efa8d476..c79645dbf 100644 --- a/ui/app/components/modals/edit-account-name-modal.js +++ b/ui/app/components/modals/edit-account-name-modal.js @@ -1,10 +1,10 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') const { getSelectedAccount } = require('../../selectors') -const t = require('../../../i18n') function mapStateToProps (state) { return { @@ -33,8 +33,13 @@ function EditAccountNameModal (props) { } } +EditAccountNameModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(EditAccountNameModal) + EditAccountNameModal.prototype.render = function () { const { hideModal, saveAccountLabel, identity } = this.props @@ -51,7 +56,7 @@ EditAccountNameModal.prototype.render = function () { ]), h('div.edit-account-name-modal-title', { - }, [t('editAccountName')]), + }, [this.context.t('editAccountName')]), h('input.edit-account-name-modal-input', { placeholder: identity.name, @@ -70,7 +75,7 @@ EditAccountNameModal.prototype.render = function () { }, disabled: this.state.inputText.length === 0, }, [ - t('save'), + this.context.t('save'), ]), ]), diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js index cf42e4fa2..1f80aed39 100644 --- a/ui/app/components/modals/export-private-key-modal.js +++ b/ui/app/components/modals/export-private-key-modal.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect @@ -7,7 +8,6 @@ const actions = require('../../actions') const AccountModalContainer = require('./account-modal-container') const { getSelectedIdentity } = require('../../selectors') const ReadOnlyInput = require('../readonly-input') -const t = require('../../../i18n') const copyToClipboard = require('copy-to-clipboard') function mapStateToProps (state) { @@ -38,8 +38,13 @@ function ExportPrivateKeyModal () { } } +ExportPrivateKeyModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(ExportPrivateKeyModal) + ExportPrivateKeyModal.prototype.exportAccountAndGetPrivateKey = function (password, address) { const { exportAccount } = this.props @@ -49,8 +54,8 @@ ExportPrivateKeyModal.prototype.exportAccountAndGetPrivateKey = function (passwo ExportPrivateKeyModal.prototype.renderPasswordLabel = function (privateKey) { return h('span.private-key-password-label', privateKey - ? t('copyPrivateKey') - : t('typePassword') + ? this.context.t('copyPrivateKey') + : this.context.t('typePassword') ) } @@ -87,8 +92,8 @@ ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, ), (privateKey - ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), t('done')) - : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm')) + ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), this.context.t('done')) + : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), this.context.t('confirm')) ), ]) @@ -121,7 +126,7 @@ ExportPrivateKeyModal.prototype.render = function () { h('div.account-modal-divider'), - h('span.modal-body-title', t('showPrivateKeys')), + h('span.modal-body-title', this.context.t('showPrivateKeys')), h('div.private-key-password', {}, [ this.renderPasswordLabel(privateKey), @@ -131,7 +136,7 @@ ExportPrivateKeyModal.prototype.render = function () { !warning ? null : h('span.private-key-password-error', warning), ]), - h('div.private-key-password-warning', t('privateKeyWarning')), + h('div.private-key-password-warning', this.context.t('privateKeyWarning')), this.renderButtons(privateKey, this.state.password, address, hideModal), diff --git a/ui/app/components/modals/hide-token-confirmation-modal.js b/ui/app/components/modals/hide-token-confirmation-modal.js index 33d8062c6..72e9c84eb 100644 --- a/ui/app/components/modals/hide-token-confirmation-modal.js +++ b/ui/app/components/modals/hide-token-confirmation-modal.js @@ -1,10 +1,10 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const connect = require('react-redux').connect const actions = require('../../actions') const Identicon = require('../identicon') -const t = require('../../../i18n') function mapStateToProps (state) { return { @@ -32,8 +32,13 @@ function HideTokenConfirmationModal () { this.state = {} } +HideTokenConfirmationModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(HideTokenConfirmationModal) + HideTokenConfirmationModal.prototype.render = function () { const { token, network, hideToken, hideModal } = this.props const { symbol, address } = token @@ -42,7 +47,7 @@ HideTokenConfirmationModal.prototype.render = function () { h('div.hide-token-confirmation__container', { }, [ h('div.hide-token-confirmation__title', {}, [ - t('hideTokenPrompt'), + this.context.t('hideTokenPrompt'), ]), h(Identicon, { @@ -55,19 +60,19 @@ HideTokenConfirmationModal.prototype.render = function () { h('div.hide-token-confirmation__symbol', {}, symbol), h('div.hide-token-confirmation__copy', {}, [ - t('readdToken'), + this.context.t('readdToken'), ]), h('div.hide-token-confirmation__buttons', {}, [ h('button.btn-cancel.hide-token-confirmation__button.allcaps', { onClick: () => hideModal(), }, [ - t('cancel'), + this.context.t('cancel'), ]), h('button.btn-clear.hide-token-confirmation__button.allcaps', { onClick: () => hideToken(address), }, [ - t('hide'), + this.context.t('hide'), ]), ]), ]), diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 501b83430..9250cc77e 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -6,7 +6,6 @@ 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 t = require('../../../i18n') // Modal Components const BuyOptions = require('./buy-options-modal') @@ -174,8 +173,8 @@ const MODALS = { BETA_UI_NOTIFICATION_MODAL: { contents: [ h(NotifcationModal, { - header: t('uiWelcome'), - message: t('uiWelcomeMessage'), + header: 'uiWelcome', + message: 'uiWelcomeMessage', }), ], mobileModalStyle: { @@ -191,8 +190,8 @@ const MODALS = { OLD_UI_NOTIFICATION_MODAL: { contents: [ h(NotifcationModal, { - header: t('oldUI'), - message: t('oldUIMessage'), + header: 'oldUI', + message: 'oldUIMessage', }), ], mobileModalStyle: { diff --git a/ui/app/components/modals/new-account-modal.js b/ui/app/components/modals/new-account-modal.js index 298b76af4..0635b3f72 100644 --- a/ui/app/components/modals/new-account-modal.js +++ b/ui/app/components/modals/new-account-modal.js @@ -1,9 +1,8 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const actions = require('../../actions') -const t = require('../../../i18n') class NewAccountModal extends Component { constructor (props) { @@ -12,7 +11,7 @@ class NewAccountModal extends Component { const newAccountNumber = numberOfExistingAccounts + 1 this.state = { - newAccountName: `${t('account')} ${newAccountNumber}`, + newAccountName: `${this.context.t('account')} ${newAccountNumber}`, } } @@ -23,7 +22,7 @@ class NewAccountModal extends Component { h('div.new-account-modal-wrapper', { }, [ h('div.new-account-modal-header', {}, [ - t('newAccount'), + this.context.t('newAccount'), ]), h('div.modal-close-x', { @@ -31,19 +30,19 @@ class NewAccountModal extends Component { }), h('div.new-account-modal-content', {}, [ - t('accountName'), + this.context.t('accountName'), ]), h('div.new-account-input-wrapper', {}, [ h('input.new-account-input', { value: this.state.newAccountName, - placeholder: t('sampleAccountName'), + placeholder: this.context.t('sampleAccountName'), onChange: event => this.setState({ newAccountName: event.target.value }), }, []), ]), h('div.new-account-modal-content.after-input', {}, [ - t('or'), + this.context.t('or'), ]), h('div.new-account-modal-content.after-input.pointer', { @@ -51,13 +50,13 @@ class NewAccountModal extends Component { this.props.hideModal() this.props.showImportPage() }, - }, t('importAnAccount')), + }, this.context.t('importAnAccount')), h('div.new-account-modal-content.button.allcaps', {}, [ h('button.btn-clear', { onClick: () => this.props.createAccount(newAccountName), }, [ - t('save'), + this.context.t('save'), ]), ]), ]), @@ -70,6 +69,7 @@ NewAccountModal.propTypes = { showImportPage: PropTypes.func, createAccount: PropTypes.func, numberOfExistingAccounts: PropTypes.number, + t: PropTypes.func, } const mapStateToProps = state => { @@ -104,4 +104,9 @@ const mapDispatchToProps = dispatch => { } } +NewAccountModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountModal) + diff --git a/ui/app/components/modals/notification-modal.js b/ui/app/components/modals/notification-modal.js index 621a974d0..46a4c8a21 100644 --- a/ui/app/components/modals/notification-modal.js +++ b/ui/app/components/modals/notification-modal.js @@ -1,7 +1,7 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const actions = require('../../actions') class NotificationModal extends Component { @@ -22,12 +22,12 @@ class NotificationModal extends Component { }, [ h('div.notification-modal__header', {}, [ - header, + this.context.t(header), ]), h('div.notification-modal__message-wrapper', {}, [ h('div.notification-modal__message', {}, [ - message, + this.context.t(message), ]), ]), @@ -62,6 +62,7 @@ NotificationModal.propTypes = { showCancelButton: PropTypes.bool, showConfirmButton: PropTypes.bool, onConfirm: PropTypes.func, + t: PropTypes.func, } const mapDispatchToProps = dispatch => { @@ -72,4 +73,9 @@ const mapDispatchToProps = dispatch => { } } +NotificationModal.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(null, mapDispatchToProps)(NotificationModal) + diff --git a/ui/app/components/modals/notification-modals/confirm-reset-account.js b/ui/app/components/modals/notification-modals/confirm-reset-account.js index e1bc91b24..89fa9bef1 100644 --- a/ui/app/components/modals/notification-modals/confirm-reset-account.js +++ b/ui/app/components/modals/notification-modals/confirm-reset-account.js @@ -1,7 +1,7 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const actions = require('../../../actions') const NotifcationModal = require('../notification-modal') diff --git a/ui/app/components/network-display.js b/ui/app/components/network-display.js index 9dc31b5c7..59719d9a4 100644 --- a/ui/app/components/network-display.js +++ b/ui/app/components/network-display.js @@ -1,9 +1,8 @@ const { Component } = require('react') const h = require('react-hyperscript') const PropTypes = require('prop-types') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const NetworkDropdownIcon = require('./dropdowns/components/network-dropdown-icon') -const t = require('../../i18n') const networkToColorHash = { 1: '#038789', @@ -31,7 +30,7 @@ class NetworkDisplay extends Component { const { provider: { type } } = this.props return h('.network-display__container', [ this.renderNetworkIcon(), - h('.network-name', t(type)), + h('.network-name', this.context.t(type)), ]) } } @@ -39,6 +38,7 @@ class NetworkDisplay extends Component { NetworkDisplay.propTypes = { network: PropTypes.string, provider: PropTypes.object, + t: PropTypes.func, } const mapStateToProps = ({ metamask: { network, provider } }) => { @@ -48,4 +48,9 @@ const mapStateToProps = ({ metamask: { network, provider } }) => { } } +NetworkDisplay.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps)(NetworkDisplay) + diff --git a/ui/app/components/network.js b/ui/app/components/network.js index f3df2242a..83297c4f2 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -1,11 +1,17 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') +const connect = require('react-redux').connect const classnames = require('classnames') const inherits = require('util').inherits const NetworkDropdownIcon = require('./dropdowns/components/network-dropdown-icon') -const t = require('../../i18n') -module.exports = Network +Network.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(Network) + inherits(Network, Component) @@ -15,6 +21,7 @@ function Network () { Network.prototype.render = function () { const props = this.props + const context = this.context const networkNumber = props.network let providerName try { @@ -34,7 +41,7 @@ Network.prototype.render = function () { onClick: (event) => this.props.onClick(event), }, [ h('img', { - title: t('attemptingConnect'), + title: context.t('attemptingConnect'), style: { width: '27px', }, @@ -42,22 +49,22 @@ Network.prototype.render = function () { }), ]) } else if (providerName === 'mainnet') { - hoverText = t('mainnet') + hoverText = context.t('mainnet') iconName = 'ethereum-network' } else if (providerName === 'ropsten') { - hoverText = t('ropsten') + hoverText = context.t('ropsten') iconName = 'ropsten-test-network' } else if (parseInt(networkNumber) === 3) { - hoverText = t('ropsten') + hoverText = context.t('ropsten') iconName = 'ropsten-test-network' } else if (providerName === 'kovan') { - hoverText = t('kovan') + hoverText = context.t('kovan') iconName = 'kovan-test-network' } else if (providerName === 'rinkeby') { - hoverText = t('rinkeby') + hoverText = context.t('rinkeby') iconName = 'rinkeby-test-network' } else { - hoverText = t('unknownNetwork') + hoverText = context.t('unknownNetwork') iconName = 'unknown-private-network' } @@ -85,7 +92,7 @@ Network.prototype.render = function () { backgroundColor: '#038789', // $blue-lagoon nonSelectBackgroundColor: '#15afb2', }), - h('.network-name', t('mainnet')), + h('.network-name', context.t('mainnet')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'ropsten-test-network': @@ -94,7 +101,7 @@ Network.prototype.render = function () { backgroundColor: '#e91550', // $crimson nonSelectBackgroundColor: '#ec2c50', }), - h('.network-name', t('ropsten')), + h('.network-name', context.t('ropsten')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'kovan-test-network': @@ -103,7 +110,7 @@ Network.prototype.render = function () { backgroundColor: '#690496', // $purple nonSelectBackgroundColor: '#b039f3', }), - h('.network-name', t('kovan')), + h('.network-name', context.t('kovan')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) case 'rinkeby-test-network': @@ -112,7 +119,7 @@ Network.prototype.render = function () { backgroundColor: '#ebb33f', // $tulip-tree nonSelectBackgroundColor: '#ecb23e', }), - h('.network-name', t('rinkeby')), + h('.network-name', context.t('rinkeby')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) default: @@ -124,7 +131,7 @@ Network.prototype.render = function () { }, }), - h('.network-name', t('privateNetwork')), + h('.network-name', context.t('privateNetwork')), h('i.fa.fa-chevron-down.fa-lg.network-caret'), ]) } diff --git a/ui/app/components/notice.js b/ui/app/components/notice.js index 8b0ce1e8b..bb7e0814c 100644 --- a/ui/app/components/notice.js +++ b/ui/app/components/notice.js @@ -1,12 +1,18 @@ const inherits = require('util').inherits const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const ReactMarkdown = require('react-markdown') const linker = require('extension-link-enabler') const findDOMNode = require('react-dom').findDOMNode -const t = require('../../i18n') +const connect = require('react-redux').connect + +Notice.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(Notice) -module.exports = Notice inherits(Notice, Component) function Notice () { @@ -111,7 +117,7 @@ Notice.prototype.render = function () { style: { marginTop: '18px', }, - }, t('accept')), + }, this.context.t('accept')), ]) ) } diff --git a/ui/app/components/pending-msg-details.js b/ui/app/components/pending-msg-details.js index 87e66855d..f16fcb1c7 100644 --- a/ui/app/components/pending-msg-details.js +++ b/ui/app/components/pending-msg-details.js @@ -1,11 +1,17 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits -const t = require('../../i18n') +const connect = require('react-redux').connect const AccountPanel = require('./account-panel') -module.exports = PendingMsgDetails +PendingMsgDetails.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(PendingMsgDetails) + inherits(PendingMsgDetails, Component) function PendingMsgDetails () { @@ -40,7 +46,7 @@ PendingMsgDetails.prototype.render = function () { // message data h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [ h('.flex-column.flex-space-between', [ - h('label.font-small.allcaps', t('message')), + h('label.font-small.allcaps', this.context.t('message')), h('span.font-small', msgParams.data), ]), ]), diff --git a/ui/app/components/pending-msg.js b/ui/app/components/pending-msg.js index dc406b955..21a7864e4 100644 --- a/ui/app/components/pending-msg.js +++ b/ui/app/components/pending-msg.js @@ -1,10 +1,16 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const PendingTxDetails = require('./pending-msg-details') -const t = require('../../i18n') +const connect = require('react-redux').connect + +PendingMsg.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(PendingMsg) -module.exports = PendingMsg inherits(PendingMsg, Component) function PendingMsg () { @@ -30,14 +36,14 @@ PendingMsg.prototype.render = function () { fontWeight: 'bold', textAlign: 'center', }, - }, t('signMessage')), + }, this.context.t('signMessage')), h('.error', { style: { margin: '10px', }, }, [ - t('signNotice'), + this.context.t('signNotice'), h('a', { href: 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527', style: { color: 'rgb(247, 134, 28)' }, @@ -46,7 +52,7 @@ PendingMsg.prototype.render = function () { const url = 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527' global.platform.openWindow({ url }) }, - }, t('readMore')), + }, this.context.t('readMore')), ]), // message details @@ -56,10 +62,10 @@ PendingMsg.prototype.render = function () { h('.flex-row.flex-space-around', [ h('button', { onClick: state.cancelMessage, - }, t('cancel')), + }, this.context.t('cancel')), h('button', { onClick: state.signMessage, - }, t('sign')), + }, this.context.t('sign')), ]), ]) diff --git a/ui/app/components/pending-tx/confirm-deploy-contract.js b/ui/app/components/pending-tx/confirm-deploy-contract.js index b75f3a964..aa68a9eb0 100644 --- a/ui/app/components/pending-tx/confirm-deploy-contract.js +++ b/ui/app/components/pending-tx/confirm-deploy-contract.js @@ -1,5 +1,5 @@ const { Component } = require('react') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const h = require('react-hyperscript') const PropTypes = require('prop-types') const actions = require('../../actions') @@ -8,7 +8,6 @@ const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const hexToBn = require('../../../../app/scripts/lib/hex-to-bn') const { conversionUtil } = require('../../conversion-util') -const t = require('../../../i18n') const SenderToRecipient = require('../sender-to-recipient') const NetworkDisplay = require('../network-display') @@ -33,7 +32,7 @@ class ConfirmDeployContract extends Component { if (valid && this.verifyGasParams()) { this.props.sendTransaction(txMeta, event) } else { - this.props.displayWarning('invalidGasParams') + this.props.displayWarning(this.context.t('invalidGasParams')) this.setState({ submitting: false }) } } @@ -178,7 +177,7 @@ class ConfirmDeployContract extends Component { return ( h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('gasFee') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency.toUpperCase()}`), @@ -217,8 +216,8 @@ class ConfirmDeployContract extends Component { return ( h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ h('div.confirm-screen-section-column', [ - h('span.confirm-screen-label', [ t('total') + ' ' ]), - h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]), + h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]), + h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]), ]), h('div.confirm-screen-section-column', [ @@ -248,11 +247,11 @@ class ConfirmDeployContract extends Component { h('.page-container__header-row', [ h('span.page-container__back-button', { onClick: () => backToAccountDetail(selectedAddress), - }, t('back')), + }, this.context.t('back')), window.METAMASK_UI_TYPE === 'notification' && h(NetworkDisplay), ]), - h('.page-container__title', t('confirmContract')), - h('.page-container__subtitle', t('pleaseReviewTransaction')), + h('.page-container__title', this.context.t('confirmContract')), + h('.page-container__subtitle', this.context.t('pleaseReviewTransaction')), ]), // Main Send token Card h('.page-container__content', [ @@ -275,7 +274,7 @@ class ConfirmDeployContract extends Component { h('div.confirm-screen-rows', [ h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('from') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', fromName), h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`), @@ -283,9 +282,9 @@ class ConfirmDeployContract extends Component { ]), h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('to') ]), h('div.confirm-screen-section-column', [ - h('div.confirm-screen-row-info', t('newContract')), + h('div.confirm-screen-row-info', this.context.t('newContract')), ]), ]), @@ -303,12 +302,12 @@ class ConfirmDeployContract extends Component { // Cancel Button h('button.btn-cancel.page-container__footer-button.allcaps', { onClick: event => this.cancel(event, txMeta), - }, t('cancel')), + }, this.context.t('cancel')), // Accept Button h('button.btn-confirm.page-container__footer-button.allcaps', { onClick: event => this.onSubmit(event), - }, t('confirm')), + }, this.context.t('confirm')), ]), ]), ]) @@ -325,6 +324,7 @@ ConfirmDeployContract.propTypes = { conversionRate: PropTypes.number, currentCurrency: PropTypes.string, selectedAddress: PropTypes.string, + t: PropTypes.func, } const mapStateToProps = state => { @@ -347,8 +347,12 @@ const mapDispatchToProps = dispatch => { return { backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)), cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })), - displayWarning: warning => actions.displayWarning(t(warning)), + displayWarning: warning => actions.displayWarning(warning), } } +ConfirmDeployContract.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract) diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index d1ce25cbf..7bf20bced 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -1,5 +1,6 @@ const Component = require('react').Component -const { connect } = require('react-redux') +const PropTypes = require('prop-types') +const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits const actions = require('../../actions') @@ -7,20 +8,29 @@ const clone = require('clone') const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const hexToBn = require('../../../../app/scripts/lib/hex-to-bn') +const classnames = require('classnames') const { conversionUtil, addCurrencies, multiplyCurrencies, } = require('../../conversion-util') +const { + getGasTotal, + isBalanceSufficient, +} = require('../send/send-utils') const GasFeeDisplay = require('../send/gas-fee-display-v2') -const t = require('../../../i18n') const SenderToRecipient = require('../sender-to-recipient') const NetworkDisplay = require('../network-display') const { MIN_GAS_PRICE_HEX } = require('../send/send-constants') +ConfirmSendEther.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendEther) + function mapStateToProps (state) { const { conversionRate, @@ -30,12 +40,14 @@ function mapStateToProps (state) { } = state.metamask const accounts = state.metamask.accounts const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0] + const { balance } = accounts[selectedAddress] return { conversionRate, identities, selectedAddress, currentCurrency, send, + balance, } } @@ -86,6 +98,7 @@ function mapDispatchToProps (dispatch) { })) dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })) }, + updateSendErrors: error => dispatch(actions.updateSendErrors(error)), } } @@ -96,6 +109,52 @@ function ConfirmSendEther () { this.onSubmit = this.onSubmit.bind(this) } +ConfirmSendEther.prototype.updateComponentSendErrors = function (prevProps) { + const { + balance: oldBalance, + conversionRate: oldConversionRate, + } = prevProps + const { + updateSendErrors, + balance, + conversionRate, + send: { + errors: { + simulationFails, + }, + }, + } = this.props + const txMeta = this.gatherTxMeta() + + const shouldUpdateBalanceSendErrors = balance && [ + balance !== oldBalance, + conversionRate !== oldConversionRate, + ].some(x => Boolean(x)) + + if (shouldUpdateBalanceSendErrors) { + const balanceIsSufficient = this.isBalanceSufficient(txMeta) + updateSendErrors({ + insufficientFunds: balanceIsSufficient ? false : this.context.t('insufficientFunds'), + }) + } + + const shouldUpdateSimulationSendError = Boolean(txMeta.simulationFails) !== Boolean(simulationFails) + + if (shouldUpdateSimulationSendError) { + updateSendErrors({ + simulationFails: !txMeta.simulationFails ? false : this.context.t('transactionError'), + }) + } +} + +ConfirmSendEther.prototype.componentWillMount = function () { + this.updateComponentSendErrors({}) +} + +ConfirmSendEther.prototype.componentDidUpdate = function (prevProps) { + this.updateComponentSendErrors(prevProps) +} + ConfirmSendEther.prototype.getAmount = function () { const { conversionRate, currentCurrency } = this.props const txMeta = this.gatherTxMeta() @@ -178,6 +237,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() @@ -193,11 +253,11 @@ ConfirmSendEther.prototype.getData = function () { return { from: { address: txParams.from, - name: identities[txParams.from].name, + name: account.name, }, to: { address: txParams.to, - name: identities[txParams.to] ? identities[txParams.to].name : t('newRecipient'), + name: identities[txParams.to] ? identities[txParams.to].name : this.context.t('newRecipient'), }, memo: txParams.memo || '', gasFeeInFIAT, @@ -218,7 +278,12 @@ ConfirmSendEther.prototype.render = function () { conversionRate, currentCurrency: convertedCurrency, showCustomizeGasModal, - send: { gasTotal, gasLimit: sendGasLimit, gasPrice: sendGasPrice }, + send: { + gasTotal, + gasLimit: sendGasLimit, + gasPrice: sendGasPrice, + errors, + }, } = this.props const txMeta = this.gatherTxMeta() const txParams = txMeta.txParams || {} @@ -298,7 +363,7 @@ ConfirmSendEther.prototype.render = function () { h('div.confirm-screen-rows', [ h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('from') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', fromName), h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`), @@ -306,7 +371,7 @@ ConfirmSendEther.prototype.render = function () { ]), h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('to') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', toName), h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`), @@ -314,7 +379,7 @@ ConfirmSendEther.prototype.render = function () { ]), h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('gasFee') ]), h('div.confirm-screen-section-column', [ h(GasFeeDisplay, { gasTotal: gasTotal || gasFeeInHex, @@ -326,15 +391,22 @@ ConfirmSendEther.prototype.render = function () { ]), h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ - h('div.confirm-screen-section-column', [ - h('span.confirm-screen-label', [ t('total') + ' ' ]), - h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]), + h('div', { + className: classnames({ + 'confirm-screen-section-column--with-error': errors['insufficientFunds'], + 'confirm-screen-section-column': !errors['insufficientFunds'], + }), + }, [ + h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]), + h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]), ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`), h('div.confirm-screen-row-detail', `${totalInETH} ETH`), ]), + + this.renderErrorMessage('insufficientFunds'), ]), ]), @@ -420,8 +492,10 @@ ConfirmSendEther.prototype.render = function () { ]), h('form#pending-tx-form', { + className: 'confirm-screen-form', onSubmit: this.onSubmit, }, [ + this.renderErrorMessage('simulationFails'), h('.page-container__footer', [ // Cancel Button h('button.btn-cancel.page-container__footer-button.allcaps', { @@ -429,26 +503,38 @@ ConfirmSendEther.prototype.render = function () { clearSend() this.cancel(event, txMeta) }, - }, t('cancel')), + }, this.context.t('cancel')), // Accept Button - h('button.btn-confirm.page-container__footer-button.allcaps', [t('confirm')]), + h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]), ]), ]), ]) ) } +ConfirmSendEther.prototype.renderErrorMessage = function (message) { + const { send: { errors } } = this.props + + return errors[message] + ? h('div.confirm-screen-error', [ errors[message] ]) + : null +} + ConfirmSendEther.prototype.onSubmit = function (event) { event.preventDefault() + const { updateSendErrors } = this.props const txMeta = this.gatherTxMeta() const valid = this.checkValidity() + const balanceIsSufficient = this.isBalanceSufficient(txMeta) this.setState({ valid, submitting: true }) - if (valid && this.verifyGasParams()) { + if (valid && this.verifyGasParams() && balanceIsSufficient) { this.props.sendTransaction(txMeta, event) + } else if (!balanceIsSufficient) { + updateSendErrors({ insufficientFunds: this.context.t('insufficientFunds') }) } else { - this.props.dispatch(actions.displayWarning(t('invalidGasParams'))) + updateSendErrors({ invalidGasParams: this.context.t('invalidGasParams') }) this.setState({ submitting: false }) } } @@ -460,6 +546,28 @@ ConfirmSendEther.prototype.cancel = function (event, txMeta) { cancelTransaction(txMeta) } +ConfirmSendEther.prototype.isBalanceSufficient = function (txMeta) { + const { + balance, + conversionRate, + } = this.props + const { + txParams: { + gas, + gasPrice, + value: amount, + }, + } = txMeta + const gasTotal = getGasTotal(gas, gasPrice) + + return isBalanceSufficient({ + amount, + gasTotal, + balance, + conversionRate, + }) +} + ConfirmSendEther.prototype.checkValidity = function () { const form = this.getFormEl() const valid = form.checkValidity() @@ -523,4 +631,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 f9276e8a5..19e591fd6 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -1,12 +1,12 @@ const Component = require('react').Component -const { connect } = require('react-redux') +const PropTypes = require('prop-types') +const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits const tokenAbi = require('human-standard-token-abi') const abiDecoder = require('abi-decoder') abiDecoder.addABI(tokenAbi) const actions = require('../../actions') -const t = require('../../../i18n') const clone = require('clone') const Identicon = require('../identicon') const GasFeeDisplay = require('../send/gas-fee-display-v2.js') @@ -17,9 +17,14 @@ const { multiplyCurrencies, addCurrencies, } = require('../../conversion-util') +const { + getGasTotal, + isBalanceSufficient, +} = require('../send/send-utils') const { calcTokenAmount, } = require('../../token-util') +const classnames = require('classnames') const { MIN_GAS_PRICE_HEX } = require('../send/send-constants') @@ -29,8 +34,13 @@ const { getSelectedTokenContract, } = require('../../selectors') +ConfirmSendToken.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken) + function mapStateToProps (state, ownProps) { const { token: { symbol }, txData } = ownProps const { txParams } = txData || {} @@ -41,9 +51,10 @@ function mapStateToProps (state, ownProps) { identities, currentCurrency, } = state.metamask + const accounts = state.metamask.accounts const selectedAddress = getSelectedAddress(state) const tokenExchangeRate = getTokenExchangeRate(state, symbol) - + const { balance } = accounts[selectedAddress] return { conversionRate, identities, @@ -53,6 +64,7 @@ function mapStateToProps (state, ownProps) { currentCurrency: currentCurrency.toUpperCase(), send: state.metamask.send, tokenContract: getSelectedTokenContract(state), + balance, } } @@ -102,7 +114,7 @@ function mapDispatchToProps (dispatch, ownProps) { fromNumericBase: 'dec', toNumericBase: 'hex', }) - + let forceGasMin if (lastGasPrice) { forceGasMin = ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, { @@ -124,6 +136,7 @@ function mapDispatchToProps (dispatch, ownProps) { })) dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })) }, + updateSendErrors: error => dispatch(actions.updateSendErrors(error)), } } @@ -134,6 +147,44 @@ function ConfirmSendToken () { this.onSubmit = this.onSubmit.bind(this) } +ConfirmSendToken.prototype.updateComponentSendErrors = function (prevProps) { + const { + balance: oldBalance, + conversionRate: oldConversionRate, + } = prevProps + const { + updateSendErrors, + balance, + conversionRate, + send: { + errors: { + simulationFails, + }, + }, + } = this.props + const txMeta = this.gatherTxMeta() + + const shouldUpdateBalanceSendErrors = balance && [ + balance !== oldBalance, + conversionRate !== oldConversionRate, + ].some(x => Boolean(x)) + + if (shouldUpdateBalanceSendErrors) { + const balanceIsSufficient = this.isBalanceSufficient(txMeta) + updateSendErrors({ + insufficientFunds: balanceIsSufficient ? false : this.context.t('insufficientFunds'), + }) + } + + const shouldUpdateSimulationSendError = Boolean(txMeta.simulationFails) !== Boolean(simulationFails) + + if (shouldUpdateSimulationSendError) { + updateSendErrors({ + simulationFails: !txMeta.simulationFails ? false : this.context.t('transactionError'), + }) + } +} + ConfirmSendToken.prototype.componentWillMount = function () { const { tokenContract, selectedAddress } = this.props tokenContract && tokenContract @@ -141,6 +192,11 @@ ConfirmSendToken.prototype.componentWillMount = function () { .then(usersToken => { }) this.props.updateTokenExchangeRate() + this.updateComponentSendErrors({}) +} + +ConfirmSendToken.prototype.componentDidUpdate = function (prevProps) { + this.updateComponentSendErrors(prevProps) } ConfirmSendToken.prototype.getAmount = function () { @@ -169,7 +225,7 @@ ConfirmSendToken.prototype.getAmount = function () { ? +(sendTokenAmount * tokenExchangeRate * conversionRate).toFixed(2) : null, token: typeof value === 'undefined' - ? t('unknown') + ? this.context.t('unknown') : +sendTokenAmount.toFixed(decimals), } @@ -241,7 +297,7 @@ ConfirmSendToken.prototype.getData = function () { }, to: { address: value, - name: identities[value] ? identities[value].name : t('newRecipient'), + name: identities[value] ? identities[value].name : this.context.t('newRecipient'), }, memo: txParams.memo || '', } @@ -287,7 +343,7 @@ ConfirmSendToken.prototype.renderGasFee = function () { return ( h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('gasFee') ]), h('div.confirm-screen-section-column', [ h(GasFeeDisplay, { gasTotal: gasTotal || gasFeeInHex, @@ -301,7 +357,7 @@ ConfirmSendToken.prototype.renderGasFee = function () { } ConfirmSendToken.prototype.renderTotalPlusGas = function () { - const { token: { symbol }, currentCurrency } = this.props + const { token: { symbol }, currentCurrency, send: { errors } } = this.props const { fiat: fiatAmount, token: tokenAmount } = this.getAmount() const { fiat: fiatGas, token: tokenGas } = this.getGasFee() @@ -309,8 +365,8 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () { ? ( h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ h('div.confirm-screen-section-column', [ - h('span.confirm-screen-label', [ t('total') + ' ' ]), - h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]), + h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]), + h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]), ]), h('div.confirm-screen-section-column', [ @@ -321,19 +377,34 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () { ) : ( h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ - h('div.confirm-screen-section-column', [ - h('span.confirm-screen-label', [ t('total') + ' ' ]), - h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]), + h('div', { + className: classnames({ + 'confirm-screen-section-column--with-error': errors['insufficientFunds'], + 'confirm-screen-section-column': !errors['insufficientFunds'], + }), + }, [ + h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]), + h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]), ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', `${tokenAmount} ${symbol}`), - h('div.confirm-screen-row-detail', `+ ${fiatGas} ${currentCurrency} ${t('gas')}`), + h('div.confirm-screen-row-detail', `+ ${fiatGas} ${currentCurrency} ${this.context.t('gas')}`), ]), + + this.renderErrorMessage('insufficientFunds'), ]) ) } +ConfirmSendToken.prototype.renderErrorMessage = function (message) { + const { send: { errors } } = this.props + + return errors[message] + ? h('div.confirm-screen-error', [ errors[message] ]) + : null +} + ConfirmSendToken.prototype.render = function () { const { editTransaction } = this.props const txMeta = this.gatherTxMeta() @@ -350,10 +421,11 @@ ConfirmSendToken.prototype.render = function () { this.inputs = [] - const title = txMeta.lastGasPrice ? 'Reprice Transaction' : t('confirm') - const subtitle = txMeta.lastGasPrice - ? 'Increase your gas fee to attempt to overwrite and speed up your transaction' - : t('pleaseReviewTransaction') + const isTxReprice = Boolean(txMeta.lastGasPrice) + const title = isTxReprice ? this.context.t('reprice_title') : this.context.t('confirm') + const subtitle = isTxReprice + ? this.context.t('reprice_subtitle') + : this.context.t('pleaseReviewTransaction') return ( h('div.confirm-screen-container.confirm-send-token', [ @@ -362,7 +434,7 @@ ConfirmSendToken.prototype.render = function () { h('div.page-container__header', [ !txMeta.lastGasPrice && h('button.confirm-screen-back-button', { onClick: () => editTransaction(txMeta), - }, t('edit')), + }, this.context.t('edit')), h('div.page-container__title', title), h('div.page-container__subtitle', subtitle), ]), @@ -406,7 +478,7 @@ ConfirmSendToken.prototype.render = function () { h('div.confirm-screen-rows', [ h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('from') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', fromName), h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`), @@ -414,7 +486,7 @@ ConfirmSendToken.prototype.render = function () { ]), toAddress && h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]), + h('span.confirm-screen-label.confirm-screen-section-column', [ this.context.t('to') ]), h('div.confirm-screen-section-column', [ h('div.confirm-screen-row-info', toName), h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`), @@ -428,17 +500,20 @@ ConfirmSendToken.prototype.render = function () { ]), ]), + h('form#pending-tx-form', { + className: 'confirm-screen-form', onSubmit: this.onSubmit, }, [ + this.renderErrorMessage('simulationFails'), h('.page-container__footer', [ // Cancel Button h('button.btn-cancel.page-container__footer-button.allcaps', { onClick: (event) => this.cancel(event, txMeta), - }, t('cancel')), + }, this.context.t('cancel')), // Accept Button - h('button.btn-confirm.page-container__footer-button.allcaps', [t('confirm')]), + h('button.btn-confirm.page-container__footer-button.allcaps', [this.context.t('confirm')]), ]), ]), ]), @@ -448,18 +523,44 @@ ConfirmSendToken.prototype.render = function () { ConfirmSendToken.prototype.onSubmit = function (event) { event.preventDefault() + const { updateSendErrors } = this.props const txMeta = this.gatherTxMeta() const valid = this.checkValidity() + const balanceIsSufficient = this.isBalanceSufficient(txMeta) this.setState({ valid, submitting: true }) - if (valid && this.verifyGasParams()) { + if (valid && this.verifyGasParams() && balanceIsSufficient) { this.props.sendTransaction(txMeta, event) + } else if (!balanceIsSufficient) { + updateSendErrors({ insufficientFunds: this.context.t('insufficientFunds') }) } else { - this.props.dispatch(actions.displayWarning(t('invalidGasParams'))) + updateSendErrors({ invalidGasParams: this.context.t('invalidGasParams') }) this.setState({ submitting: false }) } } +ConfirmSendToken.prototype.isBalanceSufficient = function (txMeta) { + const { + balance, + conversionRate, + } = this.props + const { + txParams: { + gas, + gasPrice, + }, + } = txMeta + const gasTotal = getGasTotal(gas, gasPrice) + + return isBalanceSufficient({ + amount: '0', + gasTotal, + balance, + conversionRate, + }) +} + + ConfirmSendToken.prototype.cancel = function (event, txMeta) { event.preventDefault() const { cancelTransaction } = this.props diff --git a/ui/app/components/pending-tx/index.js b/ui/app/components/pending-tx/index.js index 9c0453a3b..acdd99364 100644 --- a/ui/app/components/pending-tx/index.js +++ b/ui/app/components/pending-tx/index.js @@ -1,5 +1,5 @@ const Component = require('react').Component -const { connect } = require('react-redux') +const connect = require('react-redux').connect const h = require('react-hyperscript') const clone = require('clone') const abi = require('human-standard-token-abi') diff --git a/ui/app/components/send/gas-fee-display-v2.js b/ui/app/components/send/gas-fee-display-v2.js index f6af13454..1423aa84d 100644 --- a/ui/app/components/send/gas-fee-display-v2.js +++ b/ui/app/components/send/gas-fee-display-v2.js @@ -1,10 +1,16 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const CurrencyDisplay = require('./currency-display') -const t = require('../../../i18n') +const connect = require('react-redux').connect + +GasFeeDisplay.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(GasFeeDisplay) -module.exports = GasFeeDisplay inherits(GasFeeDisplay, Component) function GasFeeDisplay () { @@ -33,8 +39,8 @@ GasFeeDisplay.prototype.render = function () { readOnly: true, }) : gasLoadingError - ? h('div..currency-display.currency-display--message', 'Set with the gas price customizer.') - : h('div.currency-display', t('loading')), + ? h('div.currency-display.currency-display--message', this.context.t('setGasPrice')) + : h('div.currency-display', this.context.t('loading')), h('button.sliders-icon-container', { onClick, diff --git a/ui/app/components/send/gas-tooltip.js b/ui/app/components/send/gas-tooltip.js index d925d3ed8..62cdc1cad 100644 --- a/ui/app/components/send/gas-tooltip.js +++ b/ui/app/components/send/gas-tooltip.js @@ -1,10 +1,16 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const InputNumber = require('../input-number.js') -const t = require('../../../i18n') +const connect = require('react-redux').connect + +GasTooltip.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(GasTooltip) -module.exports = GasTooltip inherits(GasTooltip, Component) function GasTooltip () { @@ -82,7 +88,7 @@ GasTooltip.prototype.render = function () { 'marginTop': '81px', }, }, [ - h('span.gas-tooltip-label', {}, [t('gasLimit')]), + h('span.gas-tooltip-label', {}, [this.context.t('gasLimit')]), h('i.fa.fa-info-circle'), ]), h(InputNumber, { diff --git a/ui/app/components/send/send-utils.js b/ui/app/components/send/send-utils.js index d8211930d..71bfb2668 100644 --- a/ui/app/components/send/send-utils.js +++ b/ui/app/components/send/send-utils.js @@ -2,6 +2,7 @@ const { addCurrencies, conversionUtil, conversionGTE, + multiplyCurrencies, } = require('../../conversion-util') const { calcTokenAmount, @@ -31,7 +32,7 @@ function isBalanceSufficient ({ { value: totalAmount, fromNumericBase: 'hex', - conversionRate: amountConversionRate, + conversionRate: amountConversionRate || conversionRate, fromCurrency: primaryCurrency, }, ) @@ -62,7 +63,16 @@ function isTokenBalanceSufficient ({ return tokenBalanceIsSufficient } +function getGasTotal (gasLimit, gasPrice) { + return multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) +} + module.exports = { + getGasTotal, isBalanceSufficient, isTokenBalanceSufficient, } diff --git a/ui/app/components/send/to-autocomplete.js b/ui/app/components/send/to-autocomplete.js index 72074229e..5ea17f9a2 100644 --- a/ui/app/components/send/to-autocomplete.js +++ b/ui/app/components/send/to-autocomplete.js @@ -1,10 +1,16 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const AccountListItem = require('./account-list-item') -const t = require('../../../i18n') +const connect = require('react-redux').connect + +ToAutoComplete.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(ToAutoComplete) -module.exports = ToAutoComplete inherits(ToAutoComplete, Component) function ToAutoComplete () { @@ -93,7 +99,7 @@ ToAutoComplete.prototype.render = function () { return h('div.send-v2__to-autocomplete', {}, [ h('input.send-v2__to-autocomplete__input', { - placeholder: t('recipientAddress'), + placeholder: this.context.t('recipientAddress'), className: inError ? `send-v2__error-border` : '', value: to, onChange: event => onChange(event.target.value), diff --git a/ui/app/components/sender-to-recipient.js b/ui/app/components/sender-to-recipient.js index f35c353ad..9cef8e401 100644 --- a/ui/app/components/sender-to-recipient.js +++ b/ui/app/components/sender-to-recipient.js @@ -1,7 +1,7 @@ const { Component } = require('react') const h = require('react-hyperscript') +const connect = require('react-redux').connect const PropTypes = require('prop-types') -const t = require('../../i18n') const Identicon = require('./identicon') class SenderToRecipient extends Component { @@ -21,7 +21,7 @@ class SenderToRecipient extends Component { this.renderRecipientIcon(), h( '.sender-to-recipient__name.sender-to-recipient__recipient-name', - recipientName || t('newContract') + recipientName || this.context.t('newContract') ), ]) ) @@ -46,7 +46,7 @@ class SenderToRecipient extends Component { h('img', { height: 15, width: 15, - src: '/images/arrow-right.svg', + src: './images/arrow-right.svg', }), ]), ]), @@ -61,6 +61,12 @@ SenderToRecipient.propTypes = { senderAddress: PropTypes.string, recipientName: PropTypes.string, recipientAddress: PropTypes.string, + t: PropTypes.func, } -module.exports = SenderToRecipient +SenderToRecipient.contextTypes = { + t: PropTypes.func, +} + +module.exports = connect()(SenderToRecipient) + diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js index 5729f893c..fd4a80a4a 100644 --- a/ui/app/components/shapeshift-form.js +++ b/ui/app/components/shapeshift-form.js @@ -1,5 +1,6 @@ const h = require('react-hyperscript') const inherits = require('util').inherits +const PropTypes = require('prop-types') const Component = require('react').Component const connect = require('react-redux').connect const classnames = require('classnames') @@ -7,7 +8,6 @@ const { qrcode } = require('qrcode-npm') const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../actions') const { isValidAddress } = require('../util') const SimpleDropdown = require('./dropdowns/simple-dropdown') -const t = require('../../i18n') function mapStateToProps (state) { const { @@ -33,8 +33,13 @@ function mapDispatchToProps (dispatch) { } } +ShapeshiftForm.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm) + inherits(ShapeshiftForm, Component) function ShapeshiftForm () { Component.call(this) @@ -94,7 +99,7 @@ ShapeshiftForm.prototype.onBuyWithShapeShift = function () { })) .catch(() => this.setState({ showQrCode: false, - errorMessage: t('invalidRequest'), + errorMessage: this.context.t('invalidRequest'), isLoading: false, })) } @@ -126,10 +131,10 @@ ShapeshiftForm.prototype.renderMarketInfo = function () { return h('div.shapeshift-form__metadata', {}, [ - this.renderMetadata(t('status'), limit ? t('available') : t('unavailable')), - this.renderMetadata(t('limit'), limit), - this.renderMetadata(t('exchangeRate'), rate), - this.renderMetadata(t('min'), minimum), + this.renderMetadata(this.context.t('status'), limit ? this.context.t('available') : this.context.t('unavailable')), + this.renderMetadata(this.context.t('limit'), limit), + this.renderMetadata(this.context.t('exchangeRate'), rate), + this.renderMetadata(this.context.t('min'), minimum), ]) } @@ -143,7 +148,7 @@ ShapeshiftForm.prototype.renderQrCode = function () { return h('div.shapeshift-form', {}, [ h('div.shapeshift-form__deposit-instruction', [ - t('depositCoin', [depositCoin.toUpperCase()]), + this.context.t('depositCoin', [depositCoin.toUpperCase()]), ]), h('div', depositAddress), @@ -180,7 +185,7 @@ ShapeshiftForm.prototype.render = function () { h('div.shapeshift-form__selector', [ - h('div.shapeshift-form__selector-label', t('deposit')), + h('div.shapeshift-form__selector-label', this.context.t('deposit')), h(SimpleDropdown, { selectedOption: this.state.depositCoin, @@ -200,7 +205,7 @@ ShapeshiftForm.prototype.render = function () { h('div.shapeshift-form__selector', [ h('div.shapeshift-form__selector-label', [ - t('receive'), + this.context.t('receive'), ]), h('div.shapeshift-form__selector-input', ['ETH']), @@ -218,7 +223,7 @@ ShapeshiftForm.prototype.render = function () { }, [ h('div.shapeshift-form__address-input-label', [ - t('refundAddress'), + this.context.t('refundAddress'), ]), h('input.shapeshift-form__address-input', { @@ -240,7 +245,7 @@ ShapeshiftForm.prototype.render = function () { className: btnClass, disabled: !token, onClick: () => this.onBuyWithShapeShift(), - }, [t('buy')]), + }, [this.context.t('buy')]), ]) } diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js index fddbc6821..4334aacba 100644 --- a/ui/app/components/shift-list-item.js +++ b/ui/app/components/shift-list-item.js @@ -1,20 +1,25 @@ const inherits = require('util').inherits const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const connect = require('react-redux').connect const vreme = new (require('vreme'))() const explorerLink = require('etherscan-link').createExplorerLink const actions = require('../actions') const addressSummary = require('../util').addressSummary -const t = require('../../i18n') const CopyButton = require('./copyButton') const EthBalance = require('./eth-balance') const Tooltip = require('./tooltip') +ShiftListItem.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps)(ShiftListItem) + function mapStateToProps (state) { return { selectedAddress: state.metamask.selectedAddress, @@ -76,7 +81,7 @@ ShiftListItem.prototype.renderUtilComponents = function () { value: this.props.depositAddress, }), h(Tooltip, { - title: t('qrCode'), + title: this.context.t('qrCode'), }, [ h('i.fa.fa-qrcode.pointer.pop-hover', { onClick: () => props.dispatch(actions.reshowQrCode(props.depositAddress, props.depositType)), @@ -136,8 +141,8 @@ ShiftListItem.prototype.renderInfo = function () { color: '#ABA9AA', width: '100%', }, - }, t('toETHviaShapeShift', [props.depositType])), - h('div', t('noDeposits')), + }, this.context.t('toETHviaShapeShift', [props.depositType])), + h('div', this.context.t('noDeposits')), h('div', { style: { fontSize: 'x-small', @@ -159,8 +164,8 @@ ShiftListItem.prototype.renderInfo = function () { color: '#ABA9AA', width: '100%', }, - }, t('toETHviaShapeShift', [props.depositType])), - h('div', t('conversionProgress')), + }, this.context.t('toETHviaShapeShift', [props.depositType])), + h('div', this.context.t('conversionProgress')), h('div', { style: { fontSize: 'x-small', @@ -185,7 +190,7 @@ ShiftListItem.prototype.renderInfo = function () { color: '#ABA9AA', width: '100%', }, - }, t('fromShapeShift')), + }, this.context.t('fromShapeShift')), h('div', formatDate(props.time)), h('div', { style: { @@ -197,7 +202,7 @@ ShiftListItem.prototype.renderInfo = function () { ]) case 'failed': - return h('span.error', '(' + t('failed') + ')') + return h('span.error', '(' + this.context.t('failed') + ')') default: return '' } diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js index 810a52e55..41415411e 100644 --- a/ui/app/components/signature-request.js +++ b/ui/app/components/signature-request.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const Identicon = require('./identicon') @@ -9,7 +10,6 @@ const classnames = require('classnames') const AccountDropdownMini = require('./dropdowns/account-dropdown-mini') const actions = require('../actions') -const t = require('../../i18n') const { conversionUtil } = require('../conversion-util') const { @@ -38,8 +38,13 @@ function mapDispatchToProps (dispatch) { } } +SignatureRequest.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest) + inherits(SignatureRequest, Component) function SignatureRequest (props) { Component.call(this) @@ -55,7 +60,7 @@ SignatureRequest.prototype.renderHeader = function () { h('div.request-signature__header-background'), - h('div.request-signature__header__text', t('sigRequest')), + h('div.request-signature__header__text', this.context.t('sigRequest')), h('div.request-signature__header__tip-container', [ h('div.request-signature__header__tip'), @@ -76,7 +81,7 @@ SignatureRequest.prototype.renderAccountDropdown = function () { return h('div.request-signature__account', [ - h('div.request-signature__account-text', [t('account') + ':']), + h('div.request-signature__account-text', [this.context.t('account') + ':']), h(AccountDropdownMini, { selectedAccount, @@ -103,7 +108,7 @@ SignatureRequest.prototype.renderBalance = function () { return h('div.request-signature__balance', [ - h('div.request-signature__balance-text', [t('balance')]), + h('div.request-signature__balance-text', [this.context.t('balance')]), h('div.request-signature__balance-value', `${balanceInEther} ETH`), @@ -137,7 +142,7 @@ SignatureRequest.prototype.renderRequestInfo = function () { return h('div.request-signature__request-info', [ h('div.request-signature__headline', [ - t('yourSigRequested'), + this.context.t('yourSigRequested'), ]), ]) @@ -155,18 +160,18 @@ SignatureRequest.prototype.msgHexToText = function (hex) { SignatureRequest.prototype.renderBody = function () { let rows - let notice = t('youSign') + ':' + let notice = this.context.t('youSign') + ':' const { txData } = this.props const { type, msgParams: { data } } = txData if (type === 'personal_sign') { - rows = [{ name: t('message'), value: this.msgHexToText(data) }] + rows = [{ name: this.context.t('message'), value: this.msgHexToText(data) }] } else if (type === 'eth_signTypedData') { rows = data } else if (type === 'eth_sign') { - rows = [{ name: t('message'), value: data }] - notice = t('signNotice') + rows = [{ name: this.context.t('message'), value: data }] + notice = this.context.t('signNotice') } return h('div.request-signature__body', {}, [ @@ -225,10 +230,10 @@ SignatureRequest.prototype.renderFooter = function () { return h('div.request-signature__footer', [ h('button.btn-secondary--lg.request-signature__footer__cancel-button', { onClick: cancel, - }, t('cancel')), + }, this.context.t('cancel')), h('button.btn-primary--lg', { onClick: sign, - }, t('sign')), + }, this.context.t('sign')), ]) } diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js index 01529aeda..150a3762d 100644 --- a/ui/app/components/token-list.js +++ b/ui/app/components/token-list.js @@ -1,11 +1,11 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const inherits = require('util').inherits const TokenTracker = require('eth-token-tracker') const TokenCell = require('./token-cell.js') const connect = require('react-redux').connect const selectors = require('../selectors') -const t = require('../../i18n') function mapStateToProps (state) { return { @@ -25,8 +25,13 @@ for (const address in contracts) { } } +TokenList.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps)(TokenList) + inherits(TokenList, Component) function TokenList () { this.state = { @@ -43,7 +48,7 @@ TokenList.prototype.render = function () { const { tokens, isLoading, error } = state if (isLoading) { - return this.message(t('loadingTokens')) + return this.message(this.context.t('loadingTokens')) } if (error) { @@ -53,7 +58,7 @@ TokenList.prototype.render = function () { padding: '80px', }, }, [ - t('troubleTokenBalances'), + this.context.t('troubleTokenBalances'), h('span.hotFix', { style: { color: 'rgba(247, 134, 28, 1)', @@ -64,7 +69,7 @@ TokenList.prototype.render = function () { url: `https://ethplorer.io/address/${userAddress}`, }) }, - }, t('here')), + }, this.context.t('here')), ]) } diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js index d104eda88..42c008798 100644 --- a/ui/app/components/tx-list-item.js +++ b/ui/app/components/tx-list-item.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const connect = require('react-redux').connect const inherits = require('util').inherits @@ -14,10 +15,14 @@ const { conversionUtil, multiplyCurrencies } = require('../conversion-util') const { calcTokenAmount } = require('../token-util') const { getCurrentCurrency } = require('../selectors') -const t = require('../../i18n') + +TxListItem.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps, mapDispatchToProps)(TxListItem) + function mapStateToProps (state) { return { tokens: state.metamask.tokens, @@ -63,20 +68,24 @@ TxListItem.prototype.getAddressText = function () { const { address, txParams = {}, + isMsg, } = this.props const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data) const { name: txDataName, params = [] } = decodedData || {} const { value } = params[0] || {} - switch (txDataName) { - case 'transfer': - return `${value.slice(0, 10)}...${value.slice(-4)}` - default: - return address - ? `${address.slice(0, 10)}...${address.slice(-4)}` - : t('contractDeployment') + let addressText + if (txDataName === 'transfer' || address) { + const addressToRender = txDataName === 'transfer' ? value : address + addressText = `${addressToRender.slice(0, 10)}...${addressToRender.slice(-4)}` + } else if (isMsg) { + addressText = this.context.t('sigRequest') + } else { + addressText = this.context.t('contractDeployment') } + + return addressText } TxListItem.prototype.getSendEtherTotal = function () { @@ -186,6 +195,9 @@ TxListItem.prototype.showRetryButton = function () { transactionId, txParams, } = this.props + if (!txParams) { + return false + } const currentNonce = txParams.nonce const currentNonceTxs = selectedAddressTxList.filter(tx => tx.txParams.nonce === currentNonce) const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted') @@ -307,21 +319,21 @@ TxListItem.prototype.txStatusIndicator = function () { let name if (transactionStatus === 'unapproved') { - name = t('unapproved') + name = this.context.t('unapproved') } else if (transactionStatus === 'rejected') { - name = t('rejected') + name = this.context.t('rejected') } else if (transactionStatus === 'approved') { - name = t('approved') + name = this.context.t('approved') } else if (transactionStatus === 'signed') { - name = t('signed') + name = this.context.t('signed') } else if (transactionStatus === 'submitted') { - name = t('submitted') + name = this.context.t('submitted') } else if (transactionStatus === 'confirmed') { - name = t('confirmed') + name = this.context.t('confirmed') } else if (transactionStatus === 'failed') { - name = t('failed') + name = this.context.t('failed') } else if (transactionStatus === 'dropped') { - name = t('dropped') + name = this.context.t('dropped') } return name } diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js index 037c7de8c..740c4a4ab 100644 --- a/ui/app/components/tx-list.js +++ b/ui/app/components/tx-list.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits @@ -10,10 +11,14 @@ const { formatDate } = require('../util') const { showConfTxPage } = require('../actions') const classnames = require('classnames') const { tokenInfoGetter } = require('../token-util') -const t = require('../../i18n') + +TxList.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps, mapDispatchToProps)(TxList) + function mapStateToProps (state) { return { txsToRender: selectors.transactionsSelector(state), @@ -40,7 +45,7 @@ TxList.prototype.render = function () { return h('div.flex-column', [ h('div.flex-row.tx-list-header-wrapper', [ h('div.flex-row.tx-list-header', [ - h('div', t('transactions')), + h('div', this.context.t('transactions')), ]), ]), h('div.flex-column.tx-list-container', {}, [ @@ -57,7 +62,7 @@ TxList.prototype.renderTransaction = function () { : [h( 'div.tx-list-item.tx-list-item--empty', { key: 'tx-list-none' }, - [ t('noTransactions') ], + [ this.context.t('noTransactions') ], )] } @@ -72,9 +77,9 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa const props = { dateString: formatDate(transaction.time), - address: transaction.txParams.to, + address: transaction.txParams && transaction.txParams.to, transactionStatus: transaction.status, - transactionAmount: transaction.txParams.value, + transactionAmount: transaction.txParams && transaction.txParams.value, transactionId: transaction.id, transactionHash: transaction.hash, transactionNetworkId: transaction.metamaskNetworkId, @@ -96,6 +101,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa const opts = { key: transactionId || transactionHash, txParams: transaction.txParams, + isMsg: Boolean(transaction.msgParams), transactionStatus, transactionId, dateString, @@ -110,8 +116,8 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa const isUnapproved = transactionStatus === 'unapproved' if (isUnapproved) { - opts.onClick = () => showConfTxPage({id: transactionId}) - opts.transactionStatus = t('Not Started') + opts.onClick = () => showConfTxPage({ id: transactionId }) + 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 bf2065106..ca24e813f 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -1,18 +1,23 @@ 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 actions = require('../actions') const selectors = require('../selectors') -const t = require('../../i18n') const BalanceComponent = require('./balance-component') const TxList = require('./tx-list') const Identicon = require('./identicon') +TxView.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView) + function mapStateToProps (state) { const sidebarOpen = state.appState.sidebarOpen const isMascara = state.appState.isMascara @@ -73,21 +78,21 @@ TxView.prototype.renderButtons = function () { onClick: () => showModal({ name: 'DEPOSIT_ETHER', }), - }, t('deposit')), + }, this.context.t('deposit')), h('button.btn-primary.hero-balance-button', { style: { marginLeft: '0.8em', }, onClick: showSendPage, - }, t('send')), + }, this.context.t('send')), ]) ) : ( h('div.flex-row.flex-center.hero-balance-buttons', [ h('button.btn-primary.hero-balance-button', { onClick: showSendTokenPage, - }, t('send')), + }, this.context.t('send')), ]) ) } diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 2c6d7f784..e6b94ad12 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -1,4 +1,5 @@ const Component = require('react').Component +const PropTypes = require('prop-types') const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits @@ -11,10 +12,14 @@ const actions = require('../actions') const BalanceComponent = require('./balance-component') const TokenList = require('./token-list') const selectors = require('../selectors') -const t = require('../../i18n') + +WalletView.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView) + function mapStateToProps (state) { return { @@ -117,7 +122,7 @@ WalletView.prototype.render = function () { onClick: hideSidebar, }), - h('div.wallet-view__keyring-label.allcaps', isLoose ? t('imported') : ''), + h('div.wallet-view__keyring-label.allcaps', isLoose ? this.context.t('imported') : ''), h('div.flex-column.flex-center.wallet-view__name-container', { style: { margin: '0 auto' }, @@ -134,13 +139,13 @@ WalletView.prototype.render = function () { selectedIdentity.name, ]), - h('button.btn-clear.wallet-view__details-button.allcaps', t('details')), + h('button.btn-clear.wallet-view__details-button.allcaps', this.context.t('details')), ]), ]), h(Tooltip, { position: 'bottom', - title: this.state.hasCopied ? t('copiedExclamation') : t('copyToClipboard'), + title: this.state.hasCopied ? this.context.t('copiedExclamation') : this.context.t('copyToClipboard'), wrapperClassName: 'wallet-view__tooltip', }, [ h('button.wallet-view__address', { @@ -173,7 +178,7 @@ WalletView.prototype.render = function () { showAddTokenPage() hideSidebar() }, - }, t('addToken')), + }, this.context.t('addToken')), ]) } diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss index f5c1de67c..2fdda6f43 100644 --- a/ui/app/css/itcss/components/add-token.scss +++ b/ui/app/css/itcss/components/add-token.scss @@ -8,6 +8,7 @@ font-family: 'Roboto'; background: white; border-radius: 8px; + box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); &__wrapper { background-color: $white; @@ -20,7 +21,7 @@ &__header { display: flex; flex-flow: column nowrap; - padding: 16px 16px 0px; + padding: 20px 20px 0px; border-bottom: 1px solid $geyser; flex: 0 0 auto; @@ -31,7 +32,8 @@ span { font-family: Roboto; - font-size: 16px; + font-size: 16px; + font-weight: 400; line-height: 21px; margin-left: 8px; } @@ -44,8 +46,13 @@ margin-top: 4px; } + &__subtitle { + font-weight: 400; + margin-top: 15px; + margin-bottom: 21px; + } + &__tabs { - margin-left: 22px; display: flex; &__tab { @@ -54,6 +61,7 @@ color: $dusty-gray; font-family: Roboto; font-size: 18px; + font-weight: 400; line-height: 24px; text-align: center; } @@ -65,6 +73,7 @@ &__unselected:hover { color: $black; border-bottom: none; + cursor: pointer; } &__selected { @@ -76,7 +85,7 @@ &__info-box { height: 96px; - margin: 20px 24px 0px; + margin: 20px 20px 0px; border-radius: 4px; background-color: $alabaster; position: relative; @@ -98,6 +107,7 @@ color: $mid-gray; font-family: Roboto; font-size: 14px; + font-weight: 400; margin-top: 15px; margin-bottom: 9px; } @@ -107,6 +117,7 @@ color: $mid-gray; font-family: Roboto; font-size: 12px; + font-weight: 400; line-height: 18px; } @@ -124,7 +135,8 @@ } &__confirmation-description { - margin: 12px 0; + font-weight: 400; + margin: 20px 0 40px 0; } &__content-container { @@ -151,7 +163,7 @@ &__input, &__add-custom-input { height: 54px; - padding: 21px 6px; + padding: 0px 20px; border: 1px solid $geyser; border-radius: 4px; margin: 22px 24px; @@ -232,6 +244,7 @@ &__add-custom-label { font-size: 16px; + font-weight: 400; line-height: 21px; margin-left: 22px; color: $scorpion; @@ -274,9 +287,11 @@ color: #5B5D67; font-family: Roboto; font-size: 18px; + font-weight: 400; line-height: 24px; margin-left: 24px; margin-top: 8px; + margin-bottom: 20px; } &__token-icons-container { @@ -317,6 +332,7 @@ } &__token-name { + font-weight: 400; font-size: 14px; line-height: 19px; } @@ -368,6 +384,7 @@ &__symbol { color: $scorpion; font-size: 16px; + font-weight: 400; line-height: 24px; } } diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss index abe138f54..47762e8de 100644 --- a/ui/app/css/itcss/components/confirm.scss +++ b/ui/app/css/itcss/components/confirm.scss @@ -266,6 +266,7 @@ section .confirm-screen-account-number, .confirm-screen-total-box { background-color: $wild-sand; + position: relative; .confirm-screen-label { line-height: 21px; @@ -287,6 +288,41 @@ section .confirm-screen-account-number, } } +.confirm-screen-error { + font-size: 12px; + line-height: 12px; + color: #f00; + position: absolute; + right: 12px; + width: 80px; + text-align: right; +} + +.confirm-screen-row.confirm-screen-total-box { + .confirm-screen-section-column--with-error { + flex: 0.6; + } +} + +@media screen and (max-width: 379px) { + .confirm-screen-row.confirm-screen-total-box { + .confirm-screen-section-column--with-error { + flex: 0.4; + } + } +} + +.confirm-screen-form { + position: relative; + + .confirm-screen-error { + right: 0; + width: 100%; + margin-top: 7px; + text-align: center; + } +} + .confirm-screen-confirm-button { height: 50px; border-radius: 4px; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index 9dc4f1055..e8de317e3 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -10,9 +10,14 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( transition: linear 200ms; background-color: rgba($wallet-balance-bg, 0); position: relative; + flex: 1; + min-width: 0; &__token-balance { font-size: 1.5rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; @media #{$wallet-balance-breakpoint-range} { font-size: 95%; @@ -51,7 +56,8 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( &__balance-ellipsis { display: flex; align-items: center; - width: 100%; + min-width: 0; + flex: 1; } &__ellipsis { @@ -61,6 +67,7 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( &__balance-wrapper { flex: 1 1 auto; + min-width: 0; } } diff --git a/ui/app/css/itcss/settings/typography.scss b/ui/app/css/itcss/settings/typography.scss index 8a56d9c6c..18c444c8a 100644 --- a/ui/app/css/itcss/settings/typography.scss +++ b/ui/app/css/itcss/settings/typography.scss @@ -1,4 +1,4 @@ -@import url('/fonts/Font_Awesome/font-awesome.min.css'); +@import url('./fonts/Font_Awesome/font-awesome.min.css'); @font-face { font-family: 'Roboto'; @@ -338,8 +338,8 @@ @font-face { font-family: 'Montserrat Regular'; - src: url('/fonts/Montserrat/Montserrat-Regular.woff') format('woff'); - src: url('/fonts/Montserrat/Montserrat-Regular.ttf') format('truetype'); + src: url('./fonts/Montserrat/Montserrat-Regular.woff') format('woff'); + src: url('./fonts/Montserrat/Montserrat-Regular.ttf') format('truetype'); font-weight: 400; font-style: normal; font-size: 'small'; @@ -347,59 +347,59 @@ @font-face { font-family: 'Montserrat Bold'; - src: url('/fonts/Montserrat/Montserrat-Bold.woff') format('woff'); - src: url('/fonts/Montserrat/Montserrat-Bold.ttf') format('truetype'); + src: url('./fonts/Montserrat/Montserrat-Bold.woff') format('woff'); + src: url('./fonts/Montserrat/Montserrat-Bold.ttf') format('truetype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'Montserrat Light'; - src: url('/fonts/Montserrat/Montserrat-Light.woff') format('woff'); - src: url('/fonts/Montserrat/Montserrat-Light.ttf') format('truetype'); + src: url('./fonts/Montserrat/Montserrat-Light.woff') format('woff'); + src: url('./fonts/Montserrat/Montserrat-Light.ttf') format('truetype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'Montserrat UltraLight'; - src: url('/fonts/Montserrat/Montserrat-UltraLight.woff') format('woff'); - src: url('/fonts/Montserrat/Montserrat-UltraLight.ttf') format('truetype'); + src: url('./fonts/Montserrat/Montserrat-UltraLight.woff') format('woff'); + src: url('./fonts/Montserrat/Montserrat-UltraLight.ttf') format('truetype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'DIN OT'; - src: url('/fonts/DIN_OT/DINOT-2.otf') format('opentype'); + src: url('./fonts/DIN_OT/DINOT-2.otf') format('opentype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'DIN OT Light'; - src: url('/fonts/DIN_OT/DINOT-2.otf') format('opentype'); + src: url('./fonts/DIN_OT/DINOT-2.otf') format('opentype'); font-weight: 200; font-style: normal; } @font-face { font-family: 'DIN NEXT'; - src: url('/fonts/DIN Next/DIN Next W01 Regular.otf') format('opentype'); + src: url('./fonts/DIN Next/DIN Next W01 Regular.otf') format('opentype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'DIN NEXT Light'; - src: url('/fonts/DIN Next/DIN Next W10 Light.otf') format('opentype'); + src: url('./fonts/DIN Next/DIN Next W10 Light.otf') format('opentype'); font-weight: 400; font-style: normal; } @font-face { font-family: 'Lato'; - src: url('/fonts/Lato/Lato-Regular.ttf') format('truetype'); + src: url('./fonts/Lato/Lato-Regular.ttf') format('truetype'); font-weight: 400; font-style: normal; } diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js index 370fdd5b7..4ab5f06c0 100644 --- a/ui/app/first-time/init-menu.js +++ b/ui/app/first-time/init-menu.js @@ -1,20 +1,25 @@ const inherits = require('util').inherits const EventEmitter = require('events').EventEmitter const Component = require('react').Component +const PropTypes = require('prop-types') const connect = require('react-redux').connect const h = require('react-hyperscript') const Mascot = require('../components/mascot') const actions = require('../actions') const Tooltip = require('../components/tooltip') -const t = require('../../i18n') 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) @@ -60,7 +65,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { color: '#7F8082', marginBottom: 10, }, - }, t('appName')), + }, this.context.t('appName')), h('div', [ @@ -70,10 +75,10 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { color: '#7F8082', display: 'inline', }, - }, t('encryptNewDen')), + }, this.context.t('encryptNewDen')), h(Tooltip, { - title: t('denExplainer'), + title: this.context.t('denExplainer'), }, [ h('i.fa.fa-question-circle.pointer', { style: { @@ -93,7 +98,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { h('input.large-input.letter-spacey', { type: 'password', id: 'password-box', - placeholder: t('newPassword'), + placeholder: this.context.t('newPassword'), onInput: this.inputChanged.bind(this), style: { width: 260, @@ -105,7 +110,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { h('input.large-input.letter-spacey', { type: 'password', id: 'password-box-confirm', - placeholder: t('confirmPassword'), + placeholder: this.context.t('confirmPassword'), onKeyPress: this.createVaultOnEnter.bind(this), onInput: this.inputChanged.bind(this), style: { @@ -120,7 +125,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { style: { margin: 12, }, - }, t('createDen')), + }, this.context.t('createDen')), h('.flex-row.flex-center.flex-grow', [ h('p.pointer', { @@ -130,7 +135,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) { color: 'rgb(247, 134, 28)', textDecoration: 'underline', }, - }, t('importDen')), + }, this.context.t('importDen')), ]), h('.flex-row.flex-center.flex-grow', [ @@ -179,12 +184,12 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () { var passwordConfirm = passwordConfirmBox.value if (password.length < 8) { - this.warning = t('passwordShort') + this.warning = this.context.t('passwordShort') this.props.dispatch(actions.displayWarning(this.warning)) return } if (password !== passwordConfirm) { - this.warning = t('passwordMismatch') + this.warning = this.context.t('passwordMismatch') this.props.dispatch(actions.displayWarning(this.warning)) return } diff --git a/ui/app/i18n-provider.js b/ui/app/i18n-provider.js new file mode 100644 index 000000000..fe6d62c67 --- /dev/null +++ b/ui/app/i18n-provider.js @@ -0,0 +1,36 @@ +const { Component } = require('react') +const connect = require('react-redux').connect +const PropTypes = require('prop-types') +const t = require('../i18n-helper').getMessage + +class I18nProvider extends Component { + getChildContext() { + const { localeMessages } = this.props + return { + t: t.bind(null, localeMessages), + } + } + + render() { + return this.props.children + } +} + +I18nProvider.propTypes = { + localeMessages: PropTypes.object, + children: PropTypes.object, +} + +I18nProvider.childContextTypes = { + t: PropTypes.func, +} + +const mapStateToProps = state => { + const { localeMessages } = state + return { + localeMessages, + } +} + +module.exports = connect(mapStateToProps)(I18nProvider) + diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js index bc5339549..02183f096 100644 --- a/ui/app/keychains/hd/recover-seed/confirmation.js +++ b/ui/app/keychains/hd/recover-seed/confirmation.js @@ -1,13 +1,17 @@ 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') -const t = require('../../../../i18n') + +RevealSeedConfirmation.contextTypes = { + t: PropTypes.func, +} module.exports = connect(mapStateToProps)(RevealSeedConfirmation) + inherits(RevealSeedConfirmation, Component) function RevealSeedConfirmation () { Component.call(this) @@ -50,13 +54,13 @@ RevealSeedConfirmation.prototype.render = function () { }, }, [ - h('h4', t('revealSeedWordsWarning')), + h('h4', this.context.t('revealSeedWordsWarning')), // confirmation h('input.large-input.letter-spacey', { type: 'password', id: 'password-box', - placeholder: t('enterPasswordConfirm'), + placeholder: this.context.t('enterPasswordConfirm'), onKeyPress: this.checkConfirmation.bind(this), style: { width: 260, @@ -92,7 +96,7 @@ RevealSeedConfirmation.prototype.render = function () { ), props.inProgress && ( - h('span.in-progress-notification', t('generatingSeed')) + h('span.in-progress-notification', this.context.t('generatingSeed')) ), ]), ]) diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 5e4e004cf..38ad14adb 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -1,12 +1,17 @@ const inherits = require('util').inherits +const PropTypes = require('prop-types') const PersistentForm = require('../../../lib/persistent-form') const connect = require('react-redux').connect const h = require('react-hyperscript') -const t = require('../../../i18n') const actions = require('../../actions') +RestoreVaultScreen.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps)(RestoreVaultScreen) + inherits(RestoreVaultScreen, PersistentForm) function RestoreVaultScreen () { PersistentForm.call(this) @@ -37,23 +42,23 @@ RestoreVaultScreen.prototype.render = function () { padding: 6, }, }, [ - t('restoreVault'), + this.context.t('restoreVault'), ]), // wallet seed entry - h('h3', t('walletSeed')), + h('h3', this.context.t('walletSeed')), h('textarea.twelve-word-phrase.letter-spacey', { dataset: { persistentFormId: 'wallet-seed', }, - placeholder: t('secretPhrase'), + placeholder: this.context.t('secretPhrase'), }), // password h('input.large-input.letter-spacey', { type: 'password', id: 'password-box', - placeholder: t('newPassword8Chars'), + placeholder: this.context.t('newPassword8Chars'), dataset: { persistentFormId: 'password', }, @@ -67,7 +72,7 @@ RestoreVaultScreen.prototype.render = function () { h('input.large-input.letter-spacey', { type: 'password', id: 'password-box-confirm', - placeholder: t('confirmPassword'), + placeholder: this.context.t('confirmPassword'), onKeyPress: this.createOnEnter.bind(this), dataset: { persistentFormId: 'password-confirmation', @@ -97,7 +102,7 @@ RestoreVaultScreen.prototype.render = function () { style: { textTransform: 'uppercase', }, - }, t('cancel')), + }, this.context.t('cancel')), // submit h('button.primary', { @@ -105,7 +110,7 @@ RestoreVaultScreen.prototype.render = function () { style: { textTransform: 'uppercase', }, - }, t('ok')), + }, this.context.t('ok')), ]), ]) ) @@ -136,13 +141,13 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () { var passwordConfirmBox = document.getElementById('password-box-confirm') var passwordConfirm = passwordConfirmBox.value if (password.length < 8) { - this.warning = t('passwordNotLongEnough') + this.warning = this.context.t('passwordNotLongEnough') this.props.dispatch(actions.displayWarning(this.warning)) return } if (password !== passwordConfirm) { - this.warning = t('passwordsDontMatch') + this.warning = this.context.t('passwordsDontMatch') this.props.dispatch(actions.displayWarning(this.warning)) return } @@ -152,18 +157,18 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () { // true if the string has more than a space between words. if (seed.split(' ').length > 1) { - this.warning = t('spaceBetween') + this.warning = this.context.t('spaceBetween') this.props.dispatch(actions.displayWarning(this.warning)) return } // true if seed contains a character that is not between a-z or a space if (!seed.match(/^[a-z ]+$/)) { - this.warning = t('loweCaseWords') + this.warning = this.context.t('loweCaseWords') this.props.dispatch(actions.displayWarning(this.warning)) return } if (seed.split(' ').length !== 12) { - this.warning = t('seedPhraseReq') + this.warning = this.context.t('seedPhraseReq') this.props.dispatch(actions.displayWarning(this.warning)) return } diff --git a/ui/app/metamask-connect.js b/ui/app/metamask-connect.js new file mode 100644 index 000000000..8da594635 --- /dev/null +++ b/ui/app/metamask-connect.js @@ -0,0 +1,27 @@ +const connect = require('react-redux').connect +const t = require('../i18n-helper').getMessage + +const metamaskConnect = (mapStateToProps, mapDispatchToProps) => { + return connect( + _higherOrderMapStateToProps(mapStateToProps), + mapDispatchToProps + ) +} + +const _higherOrderMapStateToProps = (mapStateToProps) => { + let _t + let currentLocale + return (state, ownProps = {}) => { + const stateProps = mapStateToProps + ? mapStateToProps(state, ownProps) + : ownProps + if (currentLocale !== state.metamask.currentLocale) { + currentLocale = state.metamask.currentLocale + _t = t.bind(null, state.localeMessages) + } + stateProps.t = _t + return stateProps + } +} + +module.exports = metamaskConnect \ No newline at end of file diff --git a/ui/app/reducers.js b/ui/app/reducers.js index 70b7e71dc..f155b2bf3 100644 --- a/ui/app/reducers.js +++ b/ui/app/reducers.js @@ -7,6 +7,7 @@ const copyToClipboard = require('copy-to-clipboard') const reduceIdentities = require('./reducers/identities') const reduceMetamask = require('./reducers/metamask') const reduceApp = require('./reducers/app') +const reduceLocale = require('./reducers/locale') window.METAMASK_CACHED_LOG_STATE = null @@ -38,6 +39,12 @@ function rootReducer (state, action) { state.appState = reduceApp(state, action) + // + // LocaleMessages + // + + state.localeMessages = reduceLocale(state, action) + window.METAMASK_CACHED_LOG_STATE = state return state } diff --git a/ui/app/reducers/locale.js b/ui/app/reducers/locale.js new file mode 100644 index 000000000..bdd97acb4 --- /dev/null +++ b/ui/app/reducers/locale.js @@ -0,0 +1,17 @@ +const extend = require('xtend') +const actions = require('../actions') + +module.exports = reduceMetamask + +function reduceMetamask (state, action) { + const localeMessagesState = extend({}, state.localeMessages) + + switch (action.type) { + case actions.SET_LOCALE_MESSAGES: + return extend(localeMessagesState, { + current: action.value, + }) + default: + return localeMessagesState + } +} diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 9cba5e83b..6d0a5bb10 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -47,6 +47,7 @@ function reduceMetamask (state, action) { networkEndpointType: OLD_UI_NETWORK_TYPE, isRevealingSeedWords: false, welcomeScreenSeen: false, + currentLocale: '', }, state.metamask) switch (action.type) { @@ -357,6 +358,11 @@ function reduceMetamask (state, action) { welcomeScreenSeen: true, }) + case action.SET_CURRENT_LOCALE: + return extend(metamaskState, { + currentLocale: action.value, + }) + default: return metamaskState diff --git a/ui/app/select-app.js b/ui/app/select-app.js index 193c98353..101eb1cf6 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -7,6 +7,7 @@ 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 I18nProvider = require('./i18n-provider') function mapStateToProps (state) { return { @@ -62,7 +63,7 @@ SelectedApp.prototype.render = function () { // const Selected = betaUI || isMascara || firstTime ? App : OldApp const { betaUI, isMascara } = this.props - const Selected = betaUI || isMascara ? App : OldApp + const Selected = betaUI || isMascara ? h(I18nProvider, [ h(App) ]) : h(OldApp) - return h(Selected) + return Selected } diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 620da73f8..094743ff0 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -1,7 +1,7 @@ const { inherits } = require('util') +const PropTypes = require('prop-types') const PersistentForm = require('../lib/persistent-form') const h = require('react-hyperscript') -const t = require('../i18n') const ethAbi = require('ethereumjs-abi') const ethUtil = require('ethereumjs-util') @@ -27,9 +27,14 @@ const { const { isBalanceSufficient, isTokenBalanceSufficient, + getGasTotal, } = require('./components/send/send-utils') const { isValidAddress } = require('./util') +SendTransactionScreen.contextTypes = { + t: PropTypes.func, +} + module.exports = SendTransactionScreen inherits(SendTransactionScreen, PersistentForm) @@ -128,7 +133,7 @@ SendTransactionScreen.prototype.updateGas = function () { estimateGas(estimateGasParams), ]) .then(([gasPrice, gas]) => { - const newGasTotal = this.getGasTotal(gas, gasPrice) + const newGasTotal = getGasTotal(gas, gasPrice) updateGasTotal(newGasTotal) this.setState({ gasLoadingError: false }) }) @@ -136,19 +141,11 @@ SendTransactionScreen.prototype.updateGas = function () { this.setState({ gasLoadingError: true }) }) } else { - const newGasTotal = this.getGasTotal(gasLimit, gasPrice) + const newGasTotal = getGasTotal(gasLimit, gasPrice) updateGasTotal(newGasTotal) } } -SendTransactionScreen.prototype.getGasTotal = function (gasLimit, gasPrice) { - return multiplyCurrencies(gasLimit, gasPrice, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }) -} - SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) { const { from: { balance }, @@ -189,9 +186,9 @@ SendTransactionScreen.prototype.renderHeader = function () { return h('div.page-container__header', [ - h('div.page-container__title', selectedToken ? t('sendTokens') : t('sendETH')), + h('div.page-container__title', selectedToken ? this.context.t('sendTokens') : this.context.t('sendETH')), - h('div.page-container__subtitle', t('onlySendToEtherAddress')), + h('div.page-container__subtitle', this.context.t('onlySendToEtherAddress')), h('div.page-container__header-close', { onClick: () => { @@ -257,16 +254,13 @@ SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') { const { updateSendTo, updateSendErrors, - from: {address: from}, } = this.props let toError = null if (!to) { - toError = t('required') + toError = this.context.t('required') } else if (!isValidAddress(to)) { - toError = t('invalidAddressRecipient') - } else if (to === from) { - toError = t('fromToSame') + toError = this.context.t('invalidAddressRecipient') } updateSendTo(to, nickname) @@ -282,9 +276,9 @@ SendTransactionScreen.prototype.renderToRow = function () { h('div.send-v2__form-label', [ - t('to'), + this.context.t('to'), - this.renderErrorMessage(t('to')), + this.renderErrorMessage(this.context.t('to')), ]), @@ -385,11 +379,11 @@ SendTransactionScreen.prototype.validateAmount = function (value) { ) if (conversionRate && !sufficientBalance) { - amountError = t('insufficientFunds') + amountError = this.context.t('insufficientFunds') } else if (verifyTokenBalance && !sufficientTokens) { - amountError = t('insufficientTokens') + amountError = this.context.t('insufficientTokens') } else if (amountLessThanZero) { - amountError = t('negativeETH') + amountError = this.context.t('negativeETH') } updateSendErrors({ amount: amountError }) @@ -419,7 +413,7 @@ SendTransactionScreen.prototype.renderAmountRow = function () { setMaxModeTo(true) this.setAmountToMax() }, - }, [ !maxModeOn ? t('max') : '' ]), + }, [ !maxModeOn ? this.context.t('max') : '' ]), ]), h('div.send-v2__form-field', [ @@ -448,7 +442,7 @@ SendTransactionScreen.prototype.renderGasRow = function () { return h('div.send-v2__form-row', [ - h('div.send-v2__form-label', h('gasFee')), + h('div.send-v2__form-label', this.context.t('gasFee')), h('div.send-v2__form-field', [ @@ -518,11 +512,11 @@ SendTransactionScreen.prototype.renderFooter = function () { clearSend() goHome() }, - }, t('cancel')), + }, this.context.t('cancel')), h('button.btn-primary--lg.page-container__footer-button', { disabled: !noErrors || !gasTotal || missingTokenBalance, onClick: event => this.onSubmit(event), - }, t('next')), + }, this.context.t('next')), ]) } @@ -582,12 +576,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 @@ -597,7 +596,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) { event.preventDefault() const { from: {address: from}, - to, + to: _to, amount, gasLimit: gas, gasPrice, @@ -616,6 +615,8 @@ SendTransactionScreen.prototype.onSubmit = function (event) { return } + const to = ethUtil.addHexPrefix(_to) + this.addToAddressBookIfNew(to, toNickname) if (editingTransactionId) { @@ -636,6 +637,10 @@ SendTransactionScreen.prototype.onSubmit = function (event) { txParams.to = to } + Object.keys(txParams).forEach(key => { + txParams[key] = ethUtil.addHexPrefix(txParams[key]) + }) + selectedToken ? signTokenTx(selectedToken.address, to, amount, txParams) : signTx(txParams) diff --git a/ui/app/settings.js b/ui/app/settings.js index 78ca6c94b..3aa7b9c6b 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -1,7 +1,7 @@ const { Component } = require('react') const PropTypes = require('prop-types') const h = require('react-hyperscript') -const { connect } = require('react-redux') +const connect = require('react-redux').connect const actions = require('./actions') const infuraCurrencies = require('./infura-conversion.json') const validUrl = require('valid-url') @@ -9,8 +9,8 @@ const { exportAsFile } = require('./util') const TabBar = require('./components/tab-bar') const SimpleDropdown = require('./components/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 t = require('../i18n') const getInfuraCurrencyOptions = () => { const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => { @@ -26,6 +26,16 @@ const getInfuraCurrencyOptions = () => { }) } +const getLocaleOptions = () => { + return locales.map((locale) => { + return { + displayValue: `${locale.name}`, + key: locale.code, + value: locale.code, + } + }) +} + class Settings extends Component { constructor (props) { super(props) @@ -45,8 +55,8 @@ class Settings extends Component { return h('div.settings__tabs', [ h(TabBar, { tabs: [ - { content: t('settings'), key: 'settings' }, - { content: t('info'), key: 'info' }, + { content: this.context.t('settings'), key: 'settings' }, + { content: this.context.t('info'), key: 'info' }, ], defaultTab: activeTab, tabSelected: key => this.setState({ activeTab: key }), @@ -59,7 +69,7 @@ class Settings extends Component { return h('div.settings__content-row', [ h('div.settings__content-item', [ - h('span', t('blockiesIdenticon')), + h('span', this.context.t('blockiesIdenticon')), ]), h('div.settings__content-item', [ h('div.settings__content-item-col', [ @@ -79,13 +89,13 @@ class Settings extends Component { return h('div.settings__content-row', [ h('div.settings__content-item', [ - h('span', t('currentConversion')), + h('span', this.context.t('currentConversion')), h('span.settings__content-description', `Updated ${Date(conversionDate)}`), ]), h('div.settings__content-item', [ h('div.settings__content-item-col', [ h(SimpleDropdown, { - placeholder: t('selectCurrency'), + placeholder: this.context.t('selectCurrency'), options: getInfuraCurrencyOptions(), selectedOption: currentCurrency, onSelect: newCurrency => setCurrentCurrency(newCurrency), @@ -95,6 +105,31 @@ class Settings extends Component { ]) } + renderCurrentLocale () { + const { updateCurrentLocale, currentLocale } = this.props + const currentLocaleMeta = locales.find(locale => locale.code === currentLocale) + const currentLocaleName = currentLocaleMeta ? currentLocaleMeta.name : '' + + return h('div.settings__content-row', [ + h('div.settings__content-item', [ + h('span', 'Current Language'), + h('span.settings__content-description', `${currentLocaleName}`), + ]), + h('div.settings__content-item', [ + h('div.settings__content-item-col', [ + h(SimpleDropdown, { + placeholder: 'Select Locale', + options: getLocaleOptions(), + selectedOption: currentLocale, + onSelect: async (newLocale) => { + updateCurrentLocale(newLocale) + }, + }), + ]), + ]), + ]) + } + renderCurrentProvider () { const { metamask: { provider = {} } } = this.props let title, value, color @@ -102,31 +137,31 @@ class Settings extends Component { switch (provider.type) { case 'mainnet': - title = t('currentNetwork') - value = t('mainnet') + title = this.context.t('currentNetwork') + value = this.context.t('mainnet') color = '#038789' break case 'ropsten': - title = t('currentNetwork') - value = t('ropsten') + title = this.context.t('currentNetwork') + value = this.context.t('ropsten') color = '#e91550' break case 'kovan': - title = t('currentNetwork') - value = t('kovan') + title = this.context.t('currentNetwork') + value = this.context.t('kovan') color = '#690496' break case 'rinkeby': - title = t('currentNetwork') - value = t('rinkeby') + title = this.context.t('currentNetwork') + value = this.context.t('rinkeby') color = '#ebb33f' break default: - title = t('currentRpc') + title = this.context.t('currentRpc') value = provider.rpcTarget } @@ -147,12 +182,12 @@ class Settings extends Component { return ( h('div.settings__content-row', [ h('div.settings__content-item', [ - h('span', t('newRPC')), + h('span', this.context.t('newRPC')), ]), h('div.settings__content-item', [ h('div.settings__content-item-col', [ h('input.settings__input', { - placeholder: t('newRPC'), + placeholder: this.context.t('newRPC'), onChange: event => this.setState({ newRpc: event.target.value }), onKeyPress: event => { if (event.key === 'Enter') { @@ -165,7 +200,7 @@ class Settings extends Component { event.preventDefault() this.validateRpc(this.state.newRpc) }, - }, t('save')), + }, this.context.t('save')), ]), ]), ]) @@ -181,9 +216,9 @@ class Settings extends Component { const appendedRpc = `http://${newRpc}` if (validUrl.isWebUri(appendedRpc)) { - displayWarning(t('uriErrorMsg')) + displayWarning(this.context.t('uriErrorMsg')) } else { - displayWarning(t('invalidRPC')) + displayWarning(this.context.t('invalidRPC')) } } } @@ -192,10 +227,10 @@ class Settings extends Component { return ( h('div.settings__content-row', [ h('div.settings__content-item', [ - h('div', t('stateLogs')), + h('div', this.context.t('stateLogs')), h( 'div.settings__content-description', - t('stateLogsDescription') + this.context.t('stateLogsDescription') ), ]), h('div.settings__content-item', [ @@ -204,13 +239,13 @@ class Settings extends Component { onClick (event) { window.logStateString((err, result) => { if (err) { - this.state.dispatch(actions.displayWarning(t('stateLogError'))) + this.state.dispatch(actions.displayWarning(this.context.t('stateLogError'))) } else { exportAsFile('MetaMask State Logs.json', result) } }) }, - }, t('downloadStateLogs')), + }, this.context.t('downloadStateLogs')), ]), ]), ]) @@ -222,7 +257,7 @@ class Settings extends Component { return ( h('div.settings__content-row', [ - h('div.settings__content-item', t('revealSeedWords')), + h('div.settings__content-item', this.context.t('revealSeedWords')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ h('button.btn-primary--lg.settings__button--red', { @@ -230,7 +265,7 @@ class Settings extends Component { event.preventDefault() revealSeedConfirmation() }, - }, t('revealSeedWords')), + }, this.context.t('revealSeedWords')), ]), ]), ]) @@ -242,7 +277,7 @@ class Settings extends Component { return ( h('div.settings__content-row', [ - h('div.settings__content-item', t('useOldUI')), + h('div.settings__content-item', this.context.t('useOldUI')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ h('button.btn-primary--lg.settings__button--orange', { @@ -250,7 +285,7 @@ class Settings extends Component { event.preventDefault() setFeatureFlagToBeta() }, - }, t('useOldUI')), + }, this.context.t('useOldUI')), ]), ]), ]) @@ -261,7 +296,7 @@ class Settings extends Component { const { showResetAccountConfirmationModal } = this.props return h('div.settings__content-row', [ - h('div.settings__content-item', t('resetAccount')), + h('div.settings__content-item', this.context.t('resetAccount')), h('div.settings__content-item', [ h('div.settings__content-item-col', [ h('button.btn-primary--lg.settings__button--orange', { @@ -269,7 +304,7 @@ class Settings extends Component { event.preventDefault() showResetAccountConfirmationModal() }, - }, t('resetAccount')), + }, this.context.t('resetAccount')), ]), ]), ]) @@ -282,6 +317,7 @@ class Settings extends Component { h('div.settings__content', [ warning && h('div.settings__error', warning), this.renderCurrentConversion(), + this.renderCurrentLocale(), // this.renderCurrentProvider(), this.renderNewRpcUrl(), this.renderStateLogs(), @@ -304,13 +340,13 @@ class Settings extends Component { renderInfoLinks () { return ( h('div.settings__content-item.settings__content-item--without-height', [ - h('div.settings__info-link-header', t('links')), + 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', t('privacyMsg')), + h('span.settings__info-link', this.context.t('privacyMsg')), ]), ]), h('div.settings__info-link-item', [ @@ -318,7 +354,7 @@ class Settings extends Component { href: 'https://metamask.io/terms.html', target: '_blank', }, [ - h('span.settings__info-link', t('terms')), + h('span.settings__info-link', this.context.t('terms')), ]), ]), h('div.settings__info-link-item', [ @@ -326,7 +362,7 @@ class Settings extends Component { href: 'https://metamask.io/attributions.html', target: '_blank', }, [ - h('span.settings__info-link', t('attributions')), + h('span.settings__info-link', this.context.t('attributions')), ]), ]), h('hr.settings__info-separator'), @@ -335,7 +371,7 @@ class Settings extends Component { href: 'https://support.metamask.io', target: '_blank', }, [ - h('span.settings__info-link', t('supportCenter')), + h('span.settings__info-link', this.context.t('supportCenter')), ]), ]), h('div.settings__info-link-item', [ @@ -343,7 +379,7 @@ class Settings extends Component { href: 'https://metamask.io/', target: '_blank', }, [ - h('span.settings__info-link', t('visitWebSite')), + h('span.settings__info-link', this.context.t('visitWebSite')), ]), ]), h('div.settings__info-link-item', [ @@ -351,7 +387,7 @@ class Settings extends Component { target: '_blank', href: 'mailto:help@metamask.io?subject=Feedback', }, [ - h('span.settings__info-link', t('emailUs')), + h('span.settings__info-link', this.context.t('emailUs')), ]), ]), ]) @@ -373,7 +409,7 @@ class Settings extends Component { h('div.settings__info-item', [ h( 'div.settings__info-about', - t('builtInCalifornia') + this.context.t('builtInCalifornia') ), ]), ]), @@ -417,6 +453,9 @@ Settings.propTypes = { warning: PropTypes.string, goHome: PropTypes.func, isMascara: PropTypes.bool, + updateCurrentLocale: PropTypes.func, + currentLocale: PropTypes.string, + t: PropTypes.func, } const mapStateToProps = state => { @@ -424,6 +463,7 @@ const mapStateToProps = state => { metamask: state.metamask, warning: state.appState.warning, isMascara: state.metamask.isMascara, + currentLocale: state.metamask.currentLocale, } } @@ -435,6 +475,7 @@ const mapDispatchToProps = dispatch => { displayWarning: warning => dispatch(actions.displayWarning(warning)), revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()), setUseBlockie: value => dispatch(actions.setUseBlockie(value)), + updateCurrentLocale: key => dispatch(actions.updateCurrentLocale(key)), setFeatureFlagToBeta: () => { return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) .then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))) @@ -445,5 +486,9 @@ const mapDispatchToProps = dispatch => { } } +Settings.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings) diff --git a/ui/app/store.js b/ui/app/store.js index 3bafdee11..feebbabc0 100644 --- a/ui/app/store.js +++ b/ui/app/store.js @@ -4,7 +4,7 @@ const thunkMiddleware = require('redux-thunk').default const rootReducer = require('./reducers') const createLogger = require('redux-logger').createLogger -global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' +global.METAMASK_DEBUG = process.env.METAMASK_DEBUG module.exports = configureStore diff --git a/ui/app/unlock.js b/ui/app/unlock.js index 322808619..84d8b7e7c 100644 --- a/ui/app/unlock.js +++ b/ui/app/unlock.js @@ -1,18 +1,23 @@ const inherits = require('util').inherits const Component = require('react').Component +const PropTypes = require('prop-types') const h = require('react-hyperscript') const connect = require('react-redux').connect const actions = require('./actions') const getCaretCoordinates = require('textarea-caret') const EventEmitter = require('events').EventEmitter -const t = require('../i18n') const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums const environmentType = require('../../app/scripts/lib/environment-type') const Mascot = require('./components/mascot') +UnlockScreen.contextTypes = { + t: PropTypes.func, +} + module.exports = connect(mapStateToProps)(UnlockScreen) + inherits(UnlockScreen, Component) function UnlockScreen () { Component.call(this) @@ -41,7 +46,7 @@ UnlockScreen.prototype.render = function () { textTransform: 'uppercase', color: '#7F8082', }, - }, t('appName')), + }, this.context.t('appName')), h('input.large-input', { type: 'password', @@ -67,7 +72,7 @@ UnlockScreen.prototype.render = function () { style: { margin: 10, }, - }, t('login')), + }, this.context.t('login')), h('p.pointer', { onClick: () => { @@ -81,7 +86,7 @@ UnlockScreen.prototype.render = function () { color: 'rgb(247, 134, 28)', textDecoration: 'underline', }, - }, t('restoreFromSeed')), + }, this.context.t('restoreFromSeed')), h('p.pointer', { onClick: () => { @@ -94,7 +99,7 @@ UnlockScreen.prototype.render = function () { textDecoration: 'underline', marginTop: '32px', }, - }, t('classicInterface')), + }, this.context.t('classicInterface')), ]) ) } diff --git a/ui/app/util.js b/ui/app/util.js index 800ccb218..bbe2bb09e 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -271,6 +271,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/ui/i18n-helper.js b/ui/i18n-helper.js new file mode 100644 index 000000000..3eee55ae9 --- /dev/null +++ b/ui/i18n-helper.js @@ -0,0 +1,42 @@ +// cross-browser connection to extension i18n API +const log = require('loglevel') + +const getMessage = (locale, key, substitutions) => { + // check locale is loaded + if (!locale) { + // throw new Error('Translator - has not loaded a locale yet.') + return '' + } + // check entry is present + 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}"`) + } + let phrase = entry.message + // perform substitutions + if (substitutions && substitutions.length) { + phrase = phrase.replace(/\$1/g, substitutions[0]) + if (substitutions.length > 1) { + phrase = phrase.replace(/\$2/g, substitutions[1]) + } + } + return phrase +} + +async function fetchLocale (localeName) { + try { + const response = await fetch(`./_locales/${localeName}/messages.json`) + const locale = await response.json() + return locale + } catch (error) { + log.error(`failed to fetch ${localeName} locale because of ${error}`) + return {} + } +} + +module.exports = { + getMessage, + fetchLocale, +} diff --git a/ui/i18n.js b/ui/i18n.js deleted file mode 100644 index abfece426..000000000 --- a/ui/i18n.js +++ /dev/null @@ -1,33 +0,0 @@ - -// cross-browser connection to extension i18n API - -const chrome = chrome || null -const browser = browser || null -const extension = require('extensionizer') -var log = require('loglevel') -window.log = log -let getMessage - -if (extension.i18n && extension.i18n.getMessage) { - getMessage = extension.i18n.getMessage -} else { - // fallback function - log.warn('browser.i18n API not available, calling back to english.') - const msg = require('../app/_locales/en/messages.json') - getMessage = function (key, substitutions) { - if (!msg[key]) { - log.error(key) - throw new Error(key) - } - let phrase = msg[key].message - if (substitutions && substitutions.length) { - phrase = phrase.replace(/\$1/g, substitutions[0]) - if (substitutions.length > 1) { - phrase = phrase.replace(/\$2/g, substitutions[1]) - } - } - return phrase - } -} - -module.exports = getMessage diff --git a/ui/index.js b/ui/index.js index fdb2f23e0..746e28eab 100644 --- a/ui/index.js +++ b/ui/index.js @@ -4,6 +4,7 @@ const Root = require('./app/root') 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 global.log = require('loglevel') @@ -18,14 +19,22 @@ function launchMetamaskUi (opts, cb) { // check if we are unlocked first accountManager.getState(function (err, metamaskState) { if (err) return cb(err) - const store = startApp(metamaskState, accountManager, opts) - cb(null, store) + startApp(metamaskState, accountManager, opts) + .then((store) => { + cb(null, store) + }) }) } -function startApp (metamaskState, accountManager, opts) { +async function startApp (metamaskState, accountManager, opts) { // parse opts if (!metamaskState.featureFlags) metamaskState.featureFlags = {} + + const currentLocaleMessages = metamaskState.currentLocale + ? await fetchLocale(metamaskState.currentLocale) + : {} + const enLocaleMessages = await fetchLocale('en') + const store = configureStore({ // metamaskState represents the cross-tab state @@ -34,6 +43,11 @@ function startApp (metamaskState, accountManager, opts) { // appState represents the current tab's popup state appState: {}, + localeMessages: { + current: currentLocaleMessages, + en: enLocaleMessages, + }, + // Which blockchain we are using: networkVersion: opts.networkVersion, }) @@ -55,6 +69,16 @@ function startApp (metamaskState, accountManager, opts) { store.dispatch(actions.updateMetamaskState(metamaskState)) }) + // global metamask api - used by tooling + global.metamask = { + updateCurrentLocale: (code) => { + store.dispatch(actions.updateCurrentLocale(code)) + }, + setProviderType: (type) => { + store.dispatch(actions.setProviderType(type)) + }, + } + // start app render( h(Root, { diff --git a/yarn.lock b/yarn.lock index 8ccdc7efd..cda23f3c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,7 +99,7 @@ JSONStream@^1.0.3: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^1.0.3: +abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -152,7 +152,7 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" -acorn-globals@^4.0.0: +acorn-globals@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" dependencies: @@ -171,7 +171,7 @@ acorn-node@^1.3.0: acorn "^5.4.1" xtend "^4.0.1" -acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.2, acorn@^5.2.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" @@ -183,7 +183,7 @@ acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -acorn@^5.4.1: +acorn@^5.3.0, acorn@^5.4.1: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" @@ -2339,6 +2339,16 @@ chokidar@^2.0.0: optionalDependencies: fsevents "^1.0.0" +chromedriver@^2.34.1: + version "2.37.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.37.0.tgz#e7867c8236f6bb89024737bbffc9a4b33ded658b" + dependencies: + del "^3.0.0" + extract-zip "^1.6.5" + kew "^0.7.0" + mkdirp "^0.5.1" + request "^2.83.0" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -2378,10 +2388,6 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" -client-sw-ready-event@^3.3.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/client-sw-ready-event/-/client-sw-ready-event-3.4.0.tgz#ff486461769055e7748570f1aef102b8675b66d0" - cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -2642,7 +2648,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.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, 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: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -2698,7 +2704,7 @@ 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.1: +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" @@ -2747,6 +2753,10 @@ 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.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3437,7 +3447,7 @@ 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, duplexify@^3.5.0: +duplexify@^3.1.2, duplexify@^3.4.2: version "3.5.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" dependencies: @@ -3730,6 +3740,10 @@ es6-promise@^4.0.3: version "4.2.4" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" +es6-promise@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" + es6-promisify@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" @@ -3824,11 +3838,11 @@ 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-mocha@^4.9.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-4.11.0.tgz#91193a2f55e20a5e35974054a0089d30198ee578" +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" dependencies: - ramda "^0.24.1" + ramda "^0.25.0" eslint-plugin-react@^7.4.0: version "7.5.1" @@ -4317,12 +4331,12 @@ ethjs-format@0.2.3: number-to-bn "1.7.0" strip-hex-prefix "1.0.0" -ethjs-format@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.4.tgz#5bbbc44a5ad24e68ab393312ff9039a73b65bf81" +ethjs-format@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.5.tgz#44f30abee17b074d7162d2c886abffd065828925" dependencies: bn.js "4.11.6" - ethjs-schema "^0.1.9" + ethjs-schema "0.2.0" ethjs-util "0.1.3" is-hex-prefixed "1.0.0" number-to-bn "1.7.0" @@ -4348,26 +4362,30 @@ ethjs-query@^0.2.4, ethjs-query@^0.2.6, ethjs-query@^0.2.9: ethjs-format "0.2.2" ethjs-rpc "0.1.5" -ethjs-query@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.2.tgz#f488a48ce1994cd4c77eccb7b52902c6f29cfd85" +ethjs-query@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.4.tgz#068a8b268fe045acd2dfdf167bb740b12e596bc3" dependencies: - ethjs-format "0.2.4" - ethjs-rpc "0.1.8" + ethjs-format "0.2.5" + ethjs-rpc "0.1.9" ethjs-rpc@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.5.tgz#099e22f27dc4c18b6978a485fc36b1b0f7969080" -ethjs-rpc@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.8.tgz#1676740e41c7228196a71189d33f15c9c85b599d" +ethjs-rpc@0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.9.tgz#389dcd61be52e72bc47111a75805f8e45882faea" ethjs-schema@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.5.tgz#59740e3b3977bcdbb9b11bc3068201e8aceabb0d" -ethjs-schema@^0.1.6, ethjs-schema@^0.1.9: +ethjs-schema@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.2.0.tgz#07b46d4f55b792a846c90a79f330d31d112cca38" + +ethjs-schema@^0.1.6: version "0.1.9" resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.9.tgz#858c2a5da706ae04812b4ce8b1eb4b4921e33092" @@ -4644,6 +4662,15 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-zip@^1.6.5: + version "1.6.6" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" + dependencies: + concat-stream "1.6.0" + debug "2.6.9" + mkdirp "0.5.0" + yauzl "2.4.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -4715,6 +4742,12 @@ fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.9: setimmediate "^1.0.5" ua-parser-js "^0.7.9" +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + dependencies: + pend "~1.2.0" + fetch-ponyfill@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" @@ -4939,10 +4972,6 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -fork-stream@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/fork-stream/-/fork-stream-0.0.4.tgz#db849fce77f6708a5f8f386ae533a0907b54ae70" - form-data@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" @@ -5130,6 +5159,10 @@ get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" +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" @@ -5408,6 +5441,17 @@ gulp-cli@^2.0.0: v8flags "^3.0.1" yargs "^7.1.0" +gulp-debug@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/gulp-debug/-/gulp-debug-3.2.0.tgz#45aba4439fa79fe0788f6a411ee0778f4492dfa5" + dependencies: + chalk "^2.3.0" + fancy-log "^1.3.2" + plur "^2.0.0" + stringify-object "^3.0.0" + through2 "^2.0.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" @@ -5415,14 +5459,6 @@ gulp-eslint@^4.0.0: eslint "^4.0.0" gulp-util "^3.0.8" -gulp-if@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/gulp-if/-/gulp-if-2.0.2.tgz#a497b7e7573005041caa2bc8b7dda3c80444d629" - dependencies: - gulp-match "^1.0.3" - ternary-stream "^2.0.1" - through2 "^2.0.1" - 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" @@ -5444,12 +5480,6 @@ gulp-livereload@^3.8.1: lodash.assign "^3.0.0" mini-lr "^0.1.8" -gulp-match@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/gulp-match/-/gulp-match-1.0.3.tgz#91c7c0d7f29becd6606d57d80a7f8776a87aba8e" - dependencies: - minimatch "^3.0.3" - gulp-replace@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-0.6.1.tgz#11bf8c8fce533e33e2f6a8f2f430b955ba0be066" @@ -5823,7 +5853,7 @@ 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" -html-encoding-sniffer@^1.0.1: +html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" dependencies: @@ -6013,6 +6043,10 @@ immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -6353,6 +6387,10 @@ is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" +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" @@ -6641,34 +6679,36 @@ 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.1.0: - version "11.5.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.5.1.tgz#5df753b8d0bca20142ce21f4f6c039f99a992929" +jsdom@^11.2.0: + version "11.6.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb" dependencies: - abab "^1.0.3" - acorn "^5.1.2" - acorn-globals "^4.0.0" + 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.1" + content-type-parser "^1.0.2" cssom ">= 0.3.2 < 0.4.0" cssstyle ">= 0.2.37 < 0.3.0" domexception "^1.0.0" escodegen "^1.9.0" - html-encoding-sniffer "^1.0.1" + html-encoding-sniffer "^1.0.2" left-pad "^1.2.0" nwmatcher "^1.4.3" - parse5 "^3.0.2" - pn "^1.0.0" + parse5 "4.0.0" + pn "^1.1.0" request "^2.83.0" - request-promise-native "^1.0.3" - sax "^1.2.1" - symbol-tree "^3.2.1" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.1" - whatwg-url "^6.3.0" - xml-name-validator "^2.0.1" + whatwg-encoding "^1.0.3" + whatwg-url "^6.4.0" + ws "^4.0.0" + xml-name-validator "^3.0.0" jsesc@^1.3.0: version "1.3.0" @@ -6833,6 +6873,16 @@ jsx-ast-utils@^2.0.0: dependencies: array-includes "^3.0.3" +jszip@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" + dependencies: + core-js "~2.3.0" + es6-promise "~3.0.2" + lie "~3.1.0" + pako "~1.0.2" + readable-stream "~2.0.6" + just-debounce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" @@ -6911,6 +6961,10 @@ keccakjs@^0.2.0: browserify-sha3 "^0.0.1" sha3 "^1.1.0" +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: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -7076,6 +7130,12 @@ libqp@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/libqp/-/libqp-1.1.0.tgz#f5e6e06ad74b794fb5b5b66988bf728ef1dedbe8" +lie@~3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + dependencies: + immediate "~3.0.5" + liftoff@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" @@ -7587,12 +7647,6 @@ merge-source-map@^1.0.2: dependencies: source-map "^0.6.1" -merge-stream@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - dependencies: - readable-stream "^2.0.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" @@ -7759,7 +7813,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -7792,6 +7846,12 @@ mkdirp@0.0.x: version "0.0.7" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.0.7.tgz#d89b4f0e4c3e5e5ca54235931675e094fe1a5072" +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + dependencies: + minimist "0.0.8" + mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -8537,7 +8597,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -8596,7 +8656,7 @@ pac-resolver@~2.0.0: netmask "~1.0.4" thunkify "~2.1.1" -pako@~1.0.5: +pako@~1.0.2, pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -8661,7 +8721,11 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" -parse5@^3.0.1, parse5@^3.0.2: +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" dependencies: @@ -8785,6 +8849,10 @@ pbkdf2@^3.0.3, pbkdf2@^3.0.9: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + percentile@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/percentile/-/percentile-1.2.0.tgz#fa3b05c1ffd355b35228529834e5fa37f0bd465d" @@ -8867,9 +8935,9 @@ pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" -pn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.0.0.tgz#1cf5a30b0d806cd18f88fc41a6b5d4ad615b3ba9" +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" pojo-migrator@^2.1.0: version "2.1.0" @@ -9244,6 +9312,10 @@ ramda@^0.24.1: version "0.24.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" +ramda@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9" + randexp@^0.4.2: version "0.4.6" resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" @@ -9544,7 +9616,7 @@ readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-str string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@~2.0.0, readable-stream@~2.0.5: +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" dependencies: @@ -9787,7 +9859,7 @@ request-promise-core@1.1.1: dependencies: lodash "^4.13.1" -request-promise-native@^1.0.3: +request-promise-native@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" dependencies: @@ -10105,7 +10177,7 @@ sass-graph@^2.2.4: scss-tokenizer "^0.2.3" yargs "^7.0.0" -sax@^1.2.1: +sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -10156,6 +10228,15 @@ secp256k1@^3.0.1: nan "^2.2.1" safe-buffer "^5.1.0" +selenium-webdriver@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" + dependencies: + jszip "^3.1.3" + rimraf "^2.5.4" + tmp "0.0.30" + xml2js "^0.4.17" + 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" @@ -10304,9 +10385,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@^4.0.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.3.tgz#fc599eda47ed9f1a694ce774b94ab44260bd7ac5" +sinon@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-5.0.0.tgz#e6de3b3f7fed338b470f8779dc4bab9fca058894" dependencies: diff "^3.1.0" formatio "1.2.0" @@ -10813,6 +10894,14 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +stringify-object@^3.0.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" + dependencies: + get-own-enumerable-property-symbols "^2.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -11031,7 +11120,15 @@ svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" -sw-stream@^2.0.0: +sw-controller@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sw-controller/-/sw-controller-1.0.3.tgz#794b5e3e324cf2c515d12b3df57a56128e67dd1e" + dependencies: + babel-preset-es2015 "^6.22.0" + babel-runtime "^6.23.0" + babelify "^7.3.0" + +sw-stream@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/sw-stream/-/sw-stream-2.0.2.tgz#68cd1ce959f3fe79b76f583f98c9172543880a0f" dependencies: @@ -11047,7 +11144,7 @@ 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" -symbol-tree@^3.2.1: +symbol-tree@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" @@ -11126,15 +11223,6 @@ tar@^2.0.0, tar@^2.2.1: fstream "^1.0.2" inherits "2" -ternary-stream@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ternary-stream/-/ternary-stream-2.0.1.tgz#064e489b4b5bf60ba6a6b7bc7f2f5c274ecf8269" - dependencies: - duplexify "^3.5.0" - fork-stream "^0.0.4" - merge-stream "^1.0.0" - through2 "^2.0.1" - test-exclude@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" @@ -11259,6 +11347,12 @@ thunkify@~2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" +tildify@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + dependencies: + os-homedir "^1.0.0" + time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" @@ -11286,6 +11380,12 @@ timespan@2.3.x: version "2.3.0" resolved "https://registry.yarnpkg.com/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929" +tmp@0.0.30: + version "0.0.30" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" + dependencies: + os-tmpdir "~1.0.1" + tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -11863,6 +11963,12 @@ vreme@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/vreme/-/vreme-3.0.2.tgz#4721376b449457fefde8a849d3340933b90b5686" +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + walk-sync@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465" @@ -11927,14 +12033,14 @@ web3-provider-engine@^13.3.2: xhr "^2.2.0" xtend "^4.0.1" -web3-provider-engine@^13.5.6: - version "13.6.0" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.6.0.tgz#836f51c4ee48bd7583acf3696033779c704c2214" +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: async "^2.5.0" clone "^2.0.0" eth-block-tracker "^2.2.2" - eth-sig-util "^1.3.0" + eth-sig-util "^1.4.2" ethereumjs-block "^1.2.2" ethereumjs-tx "^1.2.0" ethereumjs-util "^5.1.1" @@ -12025,7 +12131,7 @@ websocket-extensions@>=0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" -whatwg-encoding@^1.0.1: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" dependencies: @@ -12035,7 +12141,7 @@ whatwg-fetch@>=0.10.0: version "2.0.3" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" -whatwg-url@^6.3.0: +whatwg-url@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" dependencies: @@ -12143,6 +12249,13 @@ ws@1.1.1: 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" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -12180,9 +12293,20 @@ xhr@^2.2.0: parse-headers "^2.0.0" xtend "^4.0.0" -xml-name-validator@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +xml2js@^0.4.17: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" xmldom@^0.1.19: version "0.1.27" @@ -12354,6 +12478,12 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + dependencies: + fd-slicer "~1.0.1" + yazl@^2.1.0: version "2.4.3" resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071"