diff --git a/.circleci/config.yml b/.circleci/config.yml index 530f5bd62..240b4aa02 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,9 +19,6 @@ workflows: - prep-build-storybook: requires: - prep-deps - - prep-scss: - requires: - - prep-deps - test-lint: requires: - prep-deps @@ -45,14 +42,6 @@ workflows: requires: - prep-deps - prep-build - - test-integration-flat-chrome: - requires: - - prep-deps - - prep-scss - - test-integration-flat-firefox: - requires: - - prep-deps - - prep-scss - all-tests-pass: requires: - test-lint @@ -63,8 +52,6 @@ workflows: - test-mozilla-lint - test-e2e-chrome - test-e2e-firefox - - test-integration-flat-chrome - - test-integration-flat-firefox - benchmark: requires: - prep-build-test @@ -176,25 +163,6 @@ jobs: paths: - .out - prep-scss: - docker: - - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 - steps: - - checkout - - attach_workspace: - at: . - - run: - name: Get Scss Cache key - # this allows us to checksum against a whole directory - command: find ui/app/css -type f -exec md5sum {} \; | sort -k 2 > scss_checksum - - run: - name: Build for integration tests - command: yarn test:integration:build - - persist_to_workspace: - root: . - paths: - - ui/app/css/output - test-lint: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 @@ -401,33 +369,6 @@ jobs: name: test:mozilla-lint command: NODE_OPTIONS=--max_old_space_size=3072 yarn mozilla-lint - test-integration-flat-firefox: - docker: - - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 - steps: - - checkout - - attach_workspace: - at: . - - run: - name: Install Firefox - command: ./.circleci/scripts/firefox-install - - run: - name: test:integration:flat - command: yarn test:flat - - test-integration-flat-chrome: - environment: - browsers: '["Chrome"]' - docker: - - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 - steps: - - checkout - - attach_workspace: - at: . - - run: - name: test:integration:flat - command: yarn test:flat - all-tests-pass: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 diff --git a/.eslintignore b/.eslintignore index d791f6a12..a07416923 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,17 +7,10 @@ test-builds/** docs/** coverage/ -development/bundle.js -development/states.js - app/scripts/lib/extension-instance.js app/scripts/chromereload.js app/vendor/** ui/lib/blockies.js -test/integration/bundle.js -test/integration/jquery-3.1.0.min.js -test/integration/helpers.js - package-lock.json diff --git a/.gitignore b/.gitignore index c56fec25c..41575124b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,13 +32,6 @@ dist builds/ builds.zip -development/bundle.js -development/states.js -test/integration/bundle.js -test/background.js -test/bundle.js -test/test-bundle.js - test-artifacts test-builds diff --git a/.stylelintignore b/.stylelintignore index a42709a90..a2aefc538 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,9 +1,9 @@ -app/ -development/ -dist/ -docs/ -fonts/ -images/ -node_modules/ -notices/ -test/ +/app +/development +/dist +/docs +/fonts +/images +/node_modules +/notices +/test diff --git a/.stylelintrc b/.stylelintrc deleted file mode 100644 index 3615abd98..000000000 --- a/.stylelintrc +++ /dev/null @@ -1,50 +0,0 @@ -{ - "extends": "stylelint-config-standard", - "rules": { - "color-named": "never", - "font-family-name-quotes": "always-where-recommended", - "font-weight-notation": "numeric", - "function-url-quotes": "always", - "number-leading-zero": "never", - "value-no-vendor-prefix": true, - "value-list-comma-newline-before": "never-multi-line", - "custom-property-empty-line-before": "never", - "property-no-unknown": [ - true, - { - "ignoreProperties": [ - "composes", - "all", - "-webkit-appearance" - ] - } - ], - "declaration-block-semicolon-newline-after": "always", - "block-opening-brace-newline-after": "always", - "selector-attribute-quotes": "always", - "selector-max-specificity": "0,5,2", - "selector-pseudo-class-no-unknown": [ - true, - { - "ignorePseudoClasses": ["local", "global"] - } - ], - "at-rule-empty-line-before": [ - "always", - { - "ignore": [ - "after-comment" - ] - } - ], - "indentation": [ - 2, - { - "indentInsideParens": "once-at-root-twice-in-block" - } - ], - "max-nesting-depth": 3, - "no-duplicate-selectors": true, - "no-unknown-animations": true - } -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f5c24cd..17db87987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## Current Develop Branch +## 8.0.5 Thu Jul 16 2020 +- [#8942](https://github.com/MetaMask/metamask-extension/pull/8942): Fix display of incoming transactions (#8942) +- [#8998](https://github.com/MetaMask/metamask-extension/pull/8998): Fix `web3_clientVersion` method (#8998) +- [#9003](https://github.com/MetaMask/metamask-extension/pull/9003): @metamask/inpage-provider@6.0.1 (#9003) +- [#9006](https://github.com/MetaMask/metamask-extension/pull/9006): Hide loading indication after `personal_sign` (#9006) +- [#9011](https://github.com/MetaMask/metamask-extension/pull/9011): Display pending notifications after connect flow (#9011) +- [#9012](https://github.com/MetaMask/metamask-extension/pull/9012): Skip render when home page is closing or redirecting (#9012) +- [#9010](https://github.com/MetaMask/metamask-extension/pull/9010): Limit number of transactions passed outside of TransactionController (#9010) +- [#9023](https://github.com/MetaMask/metamask-extension/pull/9023): Clear AccountTracker accounts and CachedBalances on createNewVaultAndRestore (#9023) +- [#9025](https://github.com/MetaMask/metamask-extension/pull/9025): Catch gas estimate errors (#9025) +- [#9026](https://github.com/MetaMask/metamask-extension/pull/9026): Clear transactions on createNewVaultAndRestore (#9026) + ## 8.0.4 Tue Jul 07 2020 - [#8934](https://github.com/MetaMask/metamask-extension/pull/8934): Fix transaction activity on custom networks - [#8936](https://github.com/MetaMask/metamask-extension/pull/8936): Fix account tracker optimization diff --git a/README.md b/README.md index 0227a668f..09f8d2857 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # MetaMask Browser Extension -[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) - You can find the latest version of MetaMask on [our official website](https://metamask.io/). For help using MetaMask, visit our [User Support Site](https://metamask.zendesk.com/hc/en-us). MetaMask supports Firefox, Google Chrome, and Chromium-based browsers. We recommend using the latest available browser version. diff --git a/app/fonts/DIN Next/DIN Next W01 Bold.otf b/app/fonts/DIN Next/DIN Next W01 Bold.otf deleted file mode 100644 index 2b78d1ff4..000000000 Binary files a/app/fonts/DIN Next/DIN Next W01 Bold.otf and /dev/null differ diff --git a/app/fonts/DIN Next/DIN Next W01 Regular.otf b/app/fonts/DIN Next/DIN Next W01 Regular.otf deleted file mode 100644 index 09f6ee297..000000000 Binary files a/app/fonts/DIN Next/DIN Next W01 Regular.otf and /dev/null differ diff --git a/app/fonts/DIN Next/DIN Next W10 Black.otf b/app/fonts/DIN Next/DIN Next W10 Black.otf deleted file mode 100644 index 08eb73373..000000000 Binary files a/app/fonts/DIN Next/DIN Next W10 Black.otf and /dev/null differ diff --git a/app/fonts/DIN Next/DIN Next W10 Italic.otf b/app/fonts/DIN Next/DIN Next W10 Italic.otf deleted file mode 100644 index 73f2b9e8c..000000000 Binary files a/app/fonts/DIN Next/DIN Next W10 Italic.otf and /dev/null differ diff --git a/app/fonts/DIN Next/DIN Next W10 Light.otf b/app/fonts/DIN Next/DIN Next W10 Light.otf deleted file mode 100644 index 700450e49..000000000 Binary files a/app/fonts/DIN Next/DIN Next W10 Light.otf and /dev/null differ diff --git a/app/fonts/DIN Next/DIN Next W10 Medium.otf b/app/fonts/DIN Next/DIN Next W10 Medium.otf deleted file mode 100644 index b73f2e43f..000000000 Binary files a/app/fonts/DIN Next/DIN Next W10 Medium.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-2.otf b/app/fonts/DIN_OT/DINOT-2.otf deleted file mode 100644 index 4a5e13127..000000000 Binary files a/app/fonts/DIN_OT/DINOT-2.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-Bold 2.otf b/app/fonts/DIN_OT/DINOT-Bold 2.otf deleted file mode 100644 index 6ed5b6c3d..000000000 Binary files a/app/fonts/DIN_OT/DINOT-Bold 2.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-BoldItalic.otf b/app/fonts/DIN_OT/DINOT-BoldItalic.otf deleted file mode 100644 index 148c90588..000000000 Binary files a/app/fonts/DIN_OT/DINOT-BoldItalic.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-Italic 2.otf b/app/fonts/DIN_OT/DINOT-Italic 2.otf deleted file mode 100644 index e365e77ab..000000000 Binary files a/app/fonts/DIN_OT/DINOT-Italic 2.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-Medium 2.otf b/app/fonts/DIN_OT/DINOT-Medium 2.otf deleted file mode 100644 index a87a2df37..000000000 Binary files a/app/fonts/DIN_OT/DINOT-Medium 2.otf and /dev/null differ diff --git a/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf b/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf deleted file mode 100644 index 14eddfc76..000000000 Binary files a/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Black.ttf b/app/fonts/Lato/Lato-Black.ttf deleted file mode 100755 index 6848db0d1..000000000 Binary files a/app/fonts/Lato/Lato-Black.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-BlackItalic.ttf b/app/fonts/Lato/Lato-BlackItalic.ttf deleted file mode 100755 index 5decf1297..000000000 Binary files a/app/fonts/Lato/Lato-BlackItalic.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Bold.ttf b/app/fonts/Lato/Lato-Bold.ttf deleted file mode 100755 index 74343694e..000000000 Binary files a/app/fonts/Lato/Lato-Bold.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-BoldItalic.ttf b/app/fonts/Lato/Lato-BoldItalic.ttf deleted file mode 100755 index 684aacf5b..000000000 Binary files a/app/fonts/Lato/Lato-BoldItalic.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Hairline.ttf b/app/fonts/Lato/Lato-Hairline.ttf deleted file mode 100755 index 288be2955..000000000 Binary files a/app/fonts/Lato/Lato-Hairline.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-HairlineItalic.ttf b/app/fonts/Lato/Lato-HairlineItalic.ttf deleted file mode 100755 index c2bfd3353..000000000 Binary files a/app/fonts/Lato/Lato-HairlineItalic.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Italic.ttf b/app/fonts/Lato/Lato-Italic.ttf deleted file mode 100755 index 3d3b7a298..000000000 Binary files a/app/fonts/Lato/Lato-Italic.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Light.ttf b/app/fonts/Lato/Lato-Light.ttf deleted file mode 100755 index a958067a8..000000000 Binary files a/app/fonts/Lato/Lato-Light.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-LightItalic.ttf b/app/fonts/Lato/Lato-LightItalic.ttf deleted file mode 100755 index 5e45ad9a6..000000000 Binary files a/app/fonts/Lato/Lato-LightItalic.ttf and /dev/null differ diff --git a/app/fonts/Lato/Lato-Regular.ttf b/app/fonts/Lato/Lato-Regular.ttf deleted file mode 100755 index 04ea8efb1..000000000 Binary files a/app/fonts/Lato/Lato-Regular.ttf and /dev/null differ diff --git a/app/fonts/Lato/OFL.txt b/app/fonts/Lato/OFL.txt deleted file mode 100755 index dfca0da4b..000000000 --- a/app/fonts/Lato/OFL.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato" - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/fonts/Montserrat/Montserrat-Bold.ttf b/app/fonts/Montserrat/Montserrat-Bold.ttf deleted file mode 100755 index ae33a4538..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Bold.ttf and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-Bold.woff b/app/fonts/Montserrat/Montserrat-Bold.woff deleted file mode 100644 index 29644358c..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Bold.woff and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-Light.ttf b/app/fonts/Montserrat/Montserrat-Light.ttf deleted file mode 100644 index cd8f62d7e..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Light.ttf and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-Light.woff b/app/fonts/Montserrat/Montserrat-Light.woff deleted file mode 100644 index d8aa6e103..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Light.woff and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-Regular.ttf b/app/fonts/Montserrat/Montserrat-Regular.ttf deleted file mode 100755 index 5b4b5afe6..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Regular.ttf and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-Regular.woff b/app/fonts/Montserrat/Montserrat-Regular.woff deleted file mode 100644 index fcbed1602..000000000 Binary files a/app/fonts/Montserrat/Montserrat-Regular.woff and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-UltraLight.ttf b/app/fonts/Montserrat/Montserrat-UltraLight.ttf deleted file mode 100644 index 16d2dbf15..000000000 Binary files a/app/fonts/Montserrat/Montserrat-UltraLight.ttf and /dev/null differ diff --git a/app/fonts/Montserrat/Montserrat-UltraLight.woff b/app/fonts/Montserrat/Montserrat-UltraLight.woff deleted file mode 100644 index 156ff32c8..000000000 Binary files a/app/fonts/Montserrat/Montserrat-UltraLight.woff and /dev/null differ diff --git a/app/fonts/Montserrat/OFL.txt b/app/fonts/Montserrat/OFL.txt deleted file mode 100755 index 3968b2265..000000000 --- a/app/fonts/Montserrat/OFL.txt +++ /dev/null @@ -1,92 +0,0 @@ -Copyright (c) 2011-2012, Julieta Ulanovsky (julieta.ulanovsky@gmail.com), with Reserved Font Names 'Montserrat' -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/images/404.png b/app/images/404.png deleted file mode 100644 index 00a3fa14a..000000000 Binary files a/app/images/404.png and /dev/null differ diff --git a/app/images/cancel.png b/app/images/cancel.png deleted file mode 100644 index e61287cd0..000000000 Binary files a/app/images/cancel.png and /dev/null differ diff --git a/app/images/coinbase logo.png b/app/images/coinbase logo.png deleted file mode 100644 index cd4f75bad..000000000 Binary files a/app/images/coinbase logo.png and /dev/null differ diff --git a/app/images/deadface.png b/app/images/deadface.png deleted file mode 100644 index 58e075945..000000000 Binary files a/app/images/deadface.png and /dev/null differ diff --git a/app/images/ethereum-metamask-chrome.png b/app/images/ethereum-metamask-chrome.png deleted file mode 100644 index d77be57ed..000000000 Binary files a/app/images/ethereum-metamask-chrome.png and /dev/null differ diff --git a/app/images/key-32.png b/app/images/key-32.png deleted file mode 100644 index 096700f03..000000000 Binary files a/app/images/key-32.png and /dev/null differ diff --git a/app/images/logo.png b/app/images/logo.png deleted file mode 100644 index 05b4e62e6..000000000 Binary files a/app/images/logo.png and /dev/null differ diff --git a/app/images/pw-128x128.png b/app/images/pw-128x128.png deleted file mode 100644 index 9d61124f3..000000000 Binary files a/app/images/pw-128x128.png and /dev/null differ diff --git a/app/images/pw-48x48.png b/app/images/pw-48x48.png deleted file mode 100644 index fe39bc267..000000000 Binary files a/app/images/pw-48x48.png and /dev/null differ diff --git a/app/images/pw128x128.png b/app/images/pw128x128.png deleted file mode 100644 index 9d61124f3..000000000 Binary files a/app/images/pw128x128.png and /dev/null differ diff --git a/app/images/shapeshift logo.png b/app/images/shapeshift logo.png deleted file mode 100644 index 0cb74d5f0..000000000 Binary files a/app/images/shapeshift logo.png and /dev/null differ diff --git a/app/manifest/_base.json b/app/manifest/_base.json index 75c0a2c40..fb12daf81 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "__MSG_appName__", - "version": "8.0.4", + "version": "8.0.5", "manifest_version": 2, "author": "https://metamask.io", "description": "__MSG_appDescription__", diff --git a/app/scripts/background.js b/app/scripts/background.js index beaeb78c3..adbd1e40e 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -260,7 +260,7 @@ function setupController (initState, initLangCode) { createStreamSink(persistData), (error) => { log.error('MetaMask - Persistence pipeline failed', error) - } + }, ) /** @@ -454,7 +454,7 @@ async function openPopup () { resolve() } }, 1000) - } + }, ) } diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 17eeabf89..de3066ca8 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -77,13 +77,13 @@ async function setupStreams () { pageMux, pageStream, pageMux, - (err) => logStreamDisconnectWarning('MetaMask Inpage Multiplex', err) + (err) => logStreamDisconnectWarning('MetaMask Inpage Multiplex', err), ) pump( extensionMux, extensionStream, extensionMux, - (err) => logStreamDisconnectWarning('MetaMask Background Multiplex', err) + (err) => logStreamDisconnectWarning('MetaMask Background Multiplex', err), ) // forward communication across inpage-background for these channels only @@ -102,7 +102,7 @@ function forwardTrafficBetweenMuxers (channelName, muxA, muxB) { channelA, channelB, channelA, - (err) => logStreamDisconnectWarning(`MetaMask muxed traffic for channel "${channelName}" failed.`, err) + (err) => logStreamDisconnectWarning(`MetaMask muxed traffic for channel "${channelName}" failed.`, err), ) } diff --git a/app/scripts/controllers/alert.js b/app/scripts/controllers/alert.js index ff0d7fb89..7fdddcdb1 100644 --- a/app/scripts/controllers/alert.js +++ b/app/scripts/controllers/alert.js @@ -22,7 +22,7 @@ const defaultState = { alertEnabledness[alertType] = true return alertEnabledness }, - {} + {}, ), unconnectedAccountAlertShownOrigins: {}, } @@ -44,7 +44,7 @@ export default class AlertController { initState, { unconnectedAccountAlertShownOrigins: {}, - } + }, ) this.store = new ObservableStore(state) diff --git a/app/scripts/controllers/cached-balances.js b/app/scripts/controllers/cached-balances.js index d978c8927..3cee10df0 100644 --- a/app/scripts/controllers/cached-balances.js +++ b/app/scripts/controllers/cached-balances.js @@ -65,6 +65,14 @@ export default class CachedBalancesController { return balancesToCache } + /** + * Removes cachedBalances + */ + + clearCachedBalances () { + this.store.updateState({ cachedBalances: {} }) + } + /** * Sets up listeners and subscriptions which should trigger an update of cached balances. These updates will * happen when the current account changes. Which happens on block updates, as well as on network and account diff --git a/app/scripts/controllers/network/createInfuraClient.js b/app/scripts/controllers/network/createInfuraClient.js index a03dce7e6..c961aeca1 100644 --- a/app/scripts/controllers/network/createInfuraClient.js +++ b/app/scripts/controllers/network/createInfuraClient.js @@ -33,23 +33,23 @@ function createNetworkAndChainIdMiddleware ({ network }) { switch (network) { case 'mainnet': - netId = networkEnums.MAINNET_NETWORK_ID.toString() + netId = networkEnums.MAINNET_NETWORK_ID chainId = '0x01' break case 'ropsten': - netId = networkEnums.ROPSTEN_NETWORK_ID.toString() + netId = networkEnums.ROPSTEN_NETWORK_ID chainId = '0x03' break case 'rinkeby': - netId = networkEnums.RINKEBY_NETWORK_ID.toString() + netId = networkEnums.RINKEBY_NETWORK_ID chainId = '0x04' break case 'kovan': - netId = networkEnums.KOVAN_NETWORK_ID.toString() + netId = networkEnums.KOVAN_NETWORK_ID chainId = networkEnums.KOVAN_CHAIN_ID break case 'goerli': - netId = networkEnums.GOERLI_NETWORK_ID.toString() + netId = networkEnums.GOERLI_NETWORK_ID chainId = '0x05' break default: diff --git a/app/scripts/controllers/network/enums.js b/app/scripts/controllers/network/enums.js index 13bdbbe1a..b9b2f2224 100644 --- a/app/scripts/controllers/network/enums.js +++ b/app/scripts/controllers/network/enums.js @@ -5,11 +5,11 @@ export const MAINNET = 'mainnet' export const GOERLI = 'goerli' export const LOCALHOST = 'localhost' -export const MAINNET_NETWORK_ID = 1 -export const ROPSTEN_NETWORK_ID = 3 -export const RINKEBY_NETWORK_ID = 4 -export const GOERLI_NETWORK_ID = 5 -export const KOVAN_NETWORK_ID = 42 +export const MAINNET_NETWORK_ID = '1' +export const ROPSTEN_NETWORK_ID = '3' +export const RINKEBY_NETWORK_ID = '4' +export const GOERLI_NETWORK_ID = '5' +export const KOVAN_NETWORK_ID = '42' export const MAINNET_CHAIN_ID = '0x1' export const ROPSTEN_CHAIN_ID = '0x3' diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 6d12e4268..f5efc58bd 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -100,7 +100,7 @@ export default class NetworkController extends EventEmitter { if (!type) { return } - network = networks.networkList[type] && networks.networkList[type].chainId ? networks.networkList[type].chainId : network + network = networks.networkList[type]?.chainId || network return this.networkStore.putState(network) } @@ -211,7 +211,7 @@ export default class NetworkController extends EventEmitter { const networkClient = createJsonRpcClient({ rpcUrl }) // hack to add a 'rpc' network with chainId networks.networkList['rpc'] = { - chainId: chainId, + chainId, rpcUrl, ticker: ticker || 'ETH', nickname, diff --git a/app/scripts/controllers/permissions/enums.js b/app/scripts/controllers/permissions/enums.js index efd994c10..a4d3afd5b 100644 --- a/app/scripts/controllers/permissions/enums.js +++ b/app/scripts/controllers/permissions/enums.js @@ -36,6 +36,7 @@ export const LOG_LIMIT = 100 export const SAFE_METHODS = [ 'web3_sha3', + 'web3_clientVersion', 'net_listening', 'net_peerCount', 'net_version', diff --git a/app/scripts/controllers/permissions/index.js b/app/scripts/controllers/permissions/index.js index b0aa79c46..311a0d1ca 100644 --- a/app/scripts/controllers/permissions/index.js +++ b/app/scripts/controllers/permissions/index.js @@ -102,7 +102,7 @@ export class PermissionsController { })) engine.push(this.permissions.providerMiddlewareFunction.bind( - this.permissions, { origin } + this.permissions, { origin }, )) return asMiddleware(engine) @@ -132,7 +132,7 @@ export class PermissionsController { const req = { method: 'eth_accounts' } const res = {} this.permissions.providerMiddlewareFunction( - { origin }, req, res, () => {}, _end + { origin }, req, res, () => {}, _end, ) function _end () { @@ -187,7 +187,7 @@ export class PermissionsController { const res = {} this.permissions.providerMiddlewareFunction( - domain, req, res, () => {}, _end + domain, req, res, () => {}, _end, ) function _end (_err) { @@ -233,7 +233,7 @@ export class PermissionsController { // attempt to finalize the request and resolve it, // settings caveats as necessary approved.permissions = await this.finalizePermissionsRequest( - approved.permissions, accounts + approved.permissions, accounts, ) approval.resolve(approved.permissions) } @@ -295,7 +295,7 @@ export class PermissionsController { this.permissions.updateCaveatFor( origin, 'eth_accounts', CAVEAT_NAMES.exposedAccounts, - [...oldPermittedAccounts, account] + [...oldPermittedAccounts, account], ) const permittedAccounts = await this.getAccounts(origin) @@ -459,7 +459,7 @@ export class PermissionsController { // update "last seen" time for the origin and account(s) // exception: no accounts -> no times to update this.permissionsLog.updateAccountsHistory( - origin, newAccounts + origin, newAccounts, ) // NOTE: @@ -490,7 +490,7 @@ export class PermissionsController { } return { parentCapability: methodName } - }) + }), ) }) } @@ -642,8 +642,8 @@ export class PermissionsController { await Promise.all( connectedDomains .map( - (origin) => this._handleConnectedAccountSelected(origin) - ) + (origin) => this._handleConnectedAccountSelected(origin), + ), ) } @@ -675,7 +675,7 @@ export class PermissionsController { this.pendingApprovals.has(id) ) { throw new Error( - `Pending approval with id '${id}' or origin '${origin}' already exists.` + `Pending approval with id '${id}' or origin '${origin}' already exists.`, ) } @@ -728,7 +728,7 @@ export class PermissionsController { if (this.pendingApprovalOrigins.has(origin)) { throw ethErrors.rpc.resourceUnavailable( - 'Permissions request already pending; please wait.' + 'Permissions request already pending; please wait.', ) } diff --git a/app/scripts/controllers/permissions/methodMiddleware.js b/app/scripts/controllers/permissions/methodMiddleware.js index 76dc363bb..b57585acd 100644 --- a/app/scripts/controllers/permissions/methodMiddleware.js +++ b/app/scripts/controllers/permissions/methodMiddleware.js @@ -33,7 +33,7 @@ export default function createMethodMiddleware ({ if (isProcessingRequestAccounts) { res.error = ethErrors.rpc.resourceUnavailable( - 'Already processing eth_requestAccounts. Please wait.' + 'Already processing eth_requestAccounts. Please wait.', ) return } @@ -68,7 +68,7 @@ export default function createMethodMiddleware ({ // this should never happen, because it should be caught in the // above catch clause res.error = ethErrors.rpc.internal( - 'Accounts unexpectedly unavailable. Please report this bug.' + 'Accounts unexpectedly unavailable. Please report this bug.', ) } diff --git a/app/scripts/controllers/permissions/permissionsLog.js b/app/scripts/controllers/permissions/permissionsLog.js index 927dbf018..f7997f085 100644 --- a/app/scripts/controllers/permissions/permissionsLog.js +++ b/app/scripts/controllers/permissions/permissionsLog.js @@ -213,7 +213,7 @@ export default class PermissionsLogController { */ logPermissionsHistory ( requestedMethods, origin, result, - time, isEthRequestAccounts + time, isEthRequestAccounts, ) { let accounts, newEntries @@ -378,6 +378,6 @@ export default class PermissionsLogController { */ function getAccountToTimeMap (accounts, time) { return accounts.reduce( - (acc, account) => ({ ...acc, [account]: time }), {} + (acc, account) => ({ ...acc, [account]: time }), {}, ) } diff --git a/app/scripts/controllers/permissions/restrictedMethods.js b/app/scripts/controllers/permissions/restrictedMethods.js index 6fc6122e7..074cbb5a5 100644 --- a/app/scripts/controllers/permissions/restrictedMethods.js +++ b/app/scripts/controllers/permissions/restrictedMethods.js @@ -27,7 +27,7 @@ export default function getRestrictedMethods ({ getIdentities, getKeyringAccount (err) => { res.error = err end(err) - } + }, ) }, }, diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index ccbeab0d7..0a2c0bbe3 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -482,7 +482,7 @@ export default class PreferencesController { * updates custom RPC details * * @param {string} url - The RPC url to add to frequentRpcList. - * @param {number} chainId - Optional chainId of the selected network. + * @param {string} chainId - Optional chainId of the selected network. * @param {string} ticker - Optional ticker symbol of the selected network. * @param {string} nickname - Optional nickname of the selected network. * @returns {Promise} - Promise resolving to updated frequentRpcList. @@ -510,7 +510,7 @@ export default class PreferencesController { * Adds custom RPC url to state. * * @param {string} url - The RPC url to add to frequentRpcList. - * @param {number} chainId - Optional chainId of the selected network. + * @param {string} chainId - Optional chainId of the selected network. * @param {string} ticker - Optional ticker symbol of the selected network. * @param {string} nickname - Optional nickname of the selected network. * @returns {Promise} - Promise resolving to updated frequentRpcList. diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 344f9a972..41ddc70ad 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -25,7 +25,6 @@ import NonceTracker from 'nonce-tracker' import * as txUtils from './lib/util' import cleanErrorStack from '../../lib/cleanErrorStack' import log from 'loglevel' -import { throwIfAccountIsBlocked } from './lib/recipient-blocklist-checker' import { TRANSACTION_TYPE_CANCEL, @@ -38,6 +37,7 @@ import { hexToBn, bnToHex, BnMultiplyByFraction } from '../../lib/util' import { TRANSACTION_NO_CONTRACT_ERROR_KEY } from '../../../../ui/app/helpers/constants/error-keys' const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send. +const MAX_MEMSTORE_TX_LIST_SIZE = 100 // Number of transactions (by unique nonces) to keep in memory /** Transaction Controller is an aggregate of sub-controllers and trackers @@ -125,14 +125,19 @@ export default class TransactionController extends EventEmitter { this._updatePendingTxsAfterFirstBlock() } - /** @returns {number} - the chainId*/ + /** + * Gets the current chainId in the network store as a number, returning 0 if + * the chainId parses to NaN. + * + * @returns {number} The numerical chainId. + */ getChainId () { const networkState = this.networkStore.getState() - const getChainId = parseInt(networkState) - if (Number.isNaN(getChainId)) { + const integerChainId = parseInt(networkState) + if (Number.isNaN(integerChainId)) { return 0 } else { - return getChainId + return integerChainId } } @@ -241,7 +246,6 @@ export default class TransactionController extends EventEmitter { this.emit('newUnapprovedTx', txMeta) try { - throwIfAccountIsBlocked(txMeta.metamaskNetworkId, normalizedTxParams.to) txMeta = await this.addTxGasDefaults(txMeta, getCodeResponse) } catch (error) { log.warn(error) @@ -786,9 +790,8 @@ export default class TransactionController extends EventEmitter { */ _updateMemstore () { const unapprovedTxs = this.txStateManager.getUnapprovedTxList() - const currentNetworkTxList = this.txStateManager.getFilteredTxList({ - metamaskNetworkId: this.getNetwork(), - }) + const currentNetworkTxList = this.txStateManager.getTxList(MAX_MEMSTORE_TX_LIST_SIZE) this.memStore.updateState({ unapprovedTxs, currentNetworkTxList }) } + } diff --git a/app/scripts/controllers/transactions/lib/recipient-blocklist-checker.js b/app/scripts/controllers/transactions/lib/recipient-blocklist-checker.js deleted file mode 100644 index 15a1e777c..000000000 --- a/app/scripts/controllers/transactions/lib/recipient-blocklist-checker.js +++ /dev/null @@ -1,19 +0,0 @@ -import blocklist from './recipient-blocklist' - -/** - * Checks if a specified account on a specified network is blocked - * @param {number} networkId - * @param {string} account - * @throws {Error} if the account is blocked on mainnet - */ -export function throwIfAccountIsBlocked (networkId, account) { - const mainnetId = 1 - if (networkId !== mainnetId) { - return - } - - const accountToCheck = account.toLowerCase() - if (blocklist.includes(accountToCheck)) { - throw new Error('Recipient is a public account') - } -} diff --git a/app/scripts/controllers/transactions/lib/recipient-blocklist.js b/app/scripts/controllers/transactions/lib/recipient-blocklist.js deleted file mode 100644 index fc7e49126..000000000 --- a/app/scripts/controllers/transactions/lib/recipient-blocklist.js +++ /dev/null @@ -1,17 +0,0 @@ -const blocklist = [ - // IDEX phisher - '0x9bcb0A9d99d815Bb87ee3191b1399b1Bcc46dc77', - // Ganache default seed phrases - '0x627306090abab3a6e1400e9345bc60c78a8bef57', - '0xf17f52151ebef6c7334fad080c5704d77216b732', - '0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef', - '0x821aea9a577a9b44299b9c15c88cf3087f3b5544', - '0x0d1d4e623d10f9fba5db95830f7d3839406c6af2', - '0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e', - '0x2191ef87e392377ec08e7c08eb105ef5448eced5', - '0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5', - '0x6330a553fc93768f612722bb8c2ec78ac90b3bbc', - '0x5aeda56215b167893e80b4fe645ba6d5bab767de', -] - -export default blocklist diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js index 304246565..a901707a8 100644 --- a/app/scripts/controllers/transactions/pending-tx-tracker.js +++ b/app/scripts/controllers/transactions/pending-tx-tracker.js @@ -243,7 +243,7 @@ export default class PendingTransactionTracker extends EventEmitter { // This is called while the transaction is in-flight, so it is possible that the // list of completed transactions now includes the transaction we were looking at // and if that is the case, don't consider the transaction to have taken its own nonce - !(other.id === txMeta.id) && other.txParams.nonce === txMeta.txParams.nonce + !(other.id === txMeta.id) && other.txParams.nonce === txMeta.txParams.nonce, ) } } diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js index 1489a3bb1..7992a1d02 100644 --- a/app/scripts/controllers/transactions/tx-state-manager.js +++ b/app/scripts/controllers/transactions/tx-state-manager.js @@ -57,12 +57,39 @@ export default class TransactionStateManager extends EventEmitter { } /** - @returns {array} - of txMetas that have been filtered for only the current network - */ - getTxList () { + * Returns the full tx list for the current network + * + * The list is iterated backwards as new transactions are pushed onto it. + * + * @param {number} [limit] a limit for the number of transactions to return + * @returns {Object[]} The {@code txMeta}s, filtered to the current network + */ + getTxList (limit) { const network = this.getNetwork() const fullTxList = this.getFullTxList() - return fullTxList.filter((txMeta) => txMeta.metamaskNetworkId === network) + + const nonces = new Set() + const txs = [] + for (let i = fullTxList.length - 1; i > -1; i--) { + const txMeta = fullTxList[i] + if (txMeta.metamaskNetworkId !== network) { + continue + } + + if (limit !== undefined) { + const { nonce } = txMeta.txParams + if (!nonces.has(nonce)) { + if (nonces.size < limit) { + nonces.add(nonce) + } else { + continue + } + } + } + + txs.unshift(txMeta) + } + return txs } /** @@ -481,4 +508,14 @@ export default class TransactionStateManager extends EventEmitter { const transactionList = this.getFullTxList() this._saveTxList(transactionList.filter((txMeta) => txMeta.id !== txId)) } + + /** + * Filters out the unapproved transactions + */ + + clearUnapprovedTxs () { + const transactions = this.getFullTxList() + const nonUnapprovedTxs = transactions.filter((tx) => tx.status !== 'unapproved') + this._saveTxList(nonUnapprovedTxs) + } } diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index dd8a2a479..974920ee4 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -151,6 +151,14 @@ export default class AccountTracker { this.store.updateState({ accounts }) } + /** + * Removes all addresses and associated balances + */ + + clearAccounts () { + this.store.updateState({ accounts: {} }) + } + /** * Given a block, updates this AccountTracker's currentBlockGasLimit, and then updates each local account's balance * via EthQuery diff --git a/app/scripts/lib/ens-ipfs/resolver.js b/app/scripts/lib/ens-ipfs/resolver.js index 14cc045a6..475432ba1 100644 --- a/app/scripts/lib/ens-ipfs/resolver.js +++ b/app/scripts/lib/ens-ipfs/resolver.js @@ -62,11 +62,8 @@ function hexValueIsEmpty (value) { function getRegistryForChainId (chainId) { switch (chainId) { case 1: - // falls through case 3: - // falls through case 4: - // falls through case 5: // Mainnet, Ropsten, Rinkeby, and Goerli, respectively, use the same address return '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e' diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js index 9194b86d4..00e50d7f4 100644 --- a/app/scripts/lib/get-first-preferred-lang-code.js +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -4,7 +4,7 @@ import allLocales from '../../_locales/index.json' const getPreferredLocales = extension.i18n ? promisify( extension.i18n.getAcceptLanguages, - { errorFirst: false } + { errorFirst: false }, ) : async () => [] // mapping some browsers return hyphen instead underscore in locale codes (e.g. zh_TW -> zh-tw) diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index c41a4a5dc..8ec1402c4 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -8,10 +8,69 @@ const METAMASK_ENVIRONMENT = process.env.METAMASK_ENVIRONMENT const SENTRY_DSN_PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' const SENTRY_DSN_DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' -export default function setupSentry ({ release }) { +// This describes the subset of Redux state attached to errors sent to Sentry +// These properties have some potential to be useful for debugging, and they do +// not contain any identifiable information. +export const SENTRY_STATE = { + gas: true, + history: true, + metamask: { + alertEnabledness: true, + completedOnboarding: true, + connectedStatusPopoverHasBeenShown: true, + conversionDate: true, + conversionRate: true, + currentBlockGasLimit: true, + currentCurrency: true, + currentLocale: true, + customNonceValue: true, + defaultHomeActiveTabName: true, + featureFlags: true, + firstTimeFlowType: true, + forgottenPassword: true, + incomingTxLastFetchedBlocksByNetwork: true, + ipfsGateway: true, + isAccountMenuOpen: true, + isInitialized: true, + isUnlocked: true, + metaMetricsId: true, + metaMetricsSendCount: true, + nativeCurrency: true, + network: true, + nextNonce: true, + participateInMetaMetrics: true, + preferences: true, + provider: { + nickname: true, + ticker: true, + type: true, + }, + seedPhraseBackedUp: true, + settings: { + chainId: true, + ticker: true, + nickname: true, + }, + showRestorePrompt: true, + threeBoxDisabled: true, + threeBoxLastUpdated: true, + threeBoxSynced: true, + threeBoxSyncingAllowed: true, + unapprovedDecryptMsgCount: true, + unapprovedEncryptionPublicKeyMsgCount: true, + unapprovedMsgCount: true, + unapprovedPersonalMsgCount: true, + unapprovedTypedMessagesCount: true, + useBlockie: true, + useNonceField: true, + usePhishDetect: true, + welcomeScreenSeen: true, + }, + unconnectedAccount: true, +} + +export default function setupSentry ({ release, getState }) { let sentryTarget - // detect brave - const isBrave = Boolean(window.chrome.ipcRenderer) if (METAMASK_DEBUG || process.env.IN_TEST) { console.log(`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_DEV`) @@ -33,16 +92,17 @@ export default function setupSentry ({ release }) { beforeSend: (report) => rewriteReport(report), }) - Sentry.configureScope((scope) => { - scope.setExtra('isBrave', isBrave) - }) - function rewriteReport (report) { try { // simplify certain complex error messages (e.g. Ethjs) simplifyErrorMessages(report) // modify report urls rewriteReportUrls(report) + // append app state + if (getState) { + const appState = getState() + report.extra.appState = appState + } } catch (err) { console.warn(err) } diff --git a/app/scripts/lib/stream-utils.js b/app/scripts/lib/stream-utils.js index 55e2c419c..b1b4aeec3 100644 --- a/app/scripts/lib/stream-utils.js +++ b/app/scripts/lib/stream-utils.js @@ -16,7 +16,7 @@ export function setupMultiplex (connectionStream) { if (err) { console.error(err) } - } + }, ) return mux } diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index 49e71e59f..3f5da3db1 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -143,7 +143,7 @@ export default class TypedMessageManager extends EventEmitter { assert.ok('from' in params, 'Params must include a "from" field.') assert.ok( typeof params.from === 'string' && isValidAddress(params.from), - '"from" field must be a valid, lowercase, hexadecimal Ethereum address string.' + '"from" field must be a valid, lowercase, hexadecimal Ethereum address string.', ) switch (params.version) { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index a2cff4655..396873d36 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -267,7 +267,14 @@ export default class MetamaskController extends EventEmitter { }) this.networkController.on('networkDidChange', () => { - this.setCurrentCurrency(this.currencyRateController.state.currentCurrency, function () {}) + this.setCurrentCurrency( + this.currencyRateController.state.currentCurrency, + (error) => { + if (error) { + throw error + } + }, + ) }) this.networkController.lookupNetwork() @@ -624,6 +631,15 @@ export default class MetamaskController extends EventEmitter { // clear permissions this.permissionsController.clearPermissions() + // clear accounts in accountTracker + this.accountTracker.clearAccounts() + + // clear cachedBalances + this.cachedBalancesController.clearCachedBalances() + + // clear unapproved transactions + this.txController.txStateManager.clearUnapprovedTxs() + // create new vault const vault = await keyringController.createNewVaultAndRestore(password, seed) @@ -710,7 +726,7 @@ export default class MetamaskController extends EventEmitter { const tokenAddress = ethUtil.toChecksumAddress(address) return contractMap[tokenAddress] ? contractMap[tokenAddress].erc20 : true }) - ) + ), ) }) @@ -728,7 +744,7 @@ export default class MetamaskController extends EventEmitter { const simpleKeyPairKeyrings = this.keyringController.getKeyringsByType('Simple Key Pair') const hdAccounts = await hdKeyring.getAccounts() const simpleKeyPairKeyringAccounts = await Promise.all( - simpleKeyPairKeyrings.map((keyring) => keyring.getAccounts()) + simpleKeyPairKeyrings.map((keyring) => keyring.getAccounts()), ) const simpleKeyPairAccounts = simpleKeyPairKeyringAccounts.reduce((acc, accounts) => [...acc, ...accounts], []) const accounts = { @@ -1516,7 +1532,7 @@ export default class MetamaskController extends EventEmitter { if (err) { log.error(err) } - } + }, ) dnode.on('remote', (remote) => { // push updates to popup @@ -1568,7 +1584,7 @@ export default class MetamaskController extends EventEmitter { if (err) { log.error(err) } - } + }, ) } @@ -1643,7 +1659,7 @@ export default class MetamaskController extends EventEmitter { if (err) { log.error(err) } - } + }, ) } @@ -1854,7 +1870,7 @@ export default class MetamaskController extends EventEmitter { /** * A method for selecting a custom URL for an ethereum RPC provider and updating it * @param {string} rpcUrl - A URL for a valid Ethereum RPC API. - * @param {number} chainId - The chainId of the selected network. + * @param {string} chainId - The chainId of the selected network. * @param {string} ticker - The ticker symbol of the selected network. * @param {string} nickname - Optional nickname of the selected network. * @returns {Promise} - The RPC Target URL confirmed. @@ -1870,7 +1886,7 @@ export default class MetamaskController extends EventEmitter { /** * A method for selecting a custom URL for an ethereum RPC provider. * @param {string} rpcTarget - A URL for a valid Ethereum RPC API. - * @param {number} chainId - The chainId of the selected network. + * @param {string} chainId - The chainId of the selected network. * @param {string} ticker - The ticker symbol of the selected network. * @param {string} nickname - Optional nickname of the selected network. * @returns {Promise} - The RPC Target URL confirmed. diff --git a/app/scripts/migrations/047.js b/app/scripts/migrations/047.js new file mode 100644 index 000000000..255971ec3 --- /dev/null +++ b/app/scripts/migrations/047.js @@ -0,0 +1,28 @@ +const version = 47 +import { cloneDeep } from 'lodash' + +/** + * Stringify the `metamaskNetworkId` property of all transactions + */ +export default { + version, + migrate: async function (originalVersionedData) { + const versionedData = cloneDeep(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + versionedData.data = transformState(state) + return versionedData + }, +} + +function transformState (state) { + const transactions = state?.TransactionController?.transactions + if (Array.isArray(transactions)) { + transactions.forEach((transaction) => { + if (typeof transaction.metamaskNetworkId === 'number') { + transaction.metamaskNetworkId = transaction.metamaskNetworkId.toString() + } + }) + } + return state +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index a5bf0206b..d90c5dc86 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -57,6 +57,7 @@ const migrations = [ require('./044').default, require('./045').default, require('./046').default, + require('./047').default, ] export default migrations diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 822ea73a4..3a76a5f4e 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -36,7 +36,10 @@ async function start () { // setup sentry error reporting const release = global.platform.getVersion() - setupSentry({ release }) + setupSentry({ + release, + getState: () => window.getSentryState?.() || {}, + }) // identify window type (popup, notification) const windowType = getEnvironmentType() diff --git a/app/unsupport.html b/app/unsupport.html deleted file mode 100644 index 6f514eb17..000000000 --- a/app/unsupport.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - MetaMask - - - -
- -

ENS resolver only support on Ethereum mainnet

-
- - \ No newline at end of file diff --git a/development/backGroundConnectionModifiers.js b/development/backGroundConnectionModifiers.js deleted file mode 100644 index cf1a723d0..000000000 --- a/development/backGroundConnectionModifiers.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - 'confirm sig requests': { - signMessage: (_, cb) => { - const stateUpdate = { - unapprovedMsgs: {}, - unapprovedMsgCount: 0, - } - return cb(null, stateUpdate) - }, - signPersonalMessage: (_, cb) => { - const stateUpdate = { - unapprovedPersonalMsgs: {}, - unapprovedPersonalMsgCount: 0, - } - return cb(null, stateUpdate) - }, - signTypedMessage: (_, cb) => { - const stateUpdate = { - unapprovedTypedMessages: {}, - unapprovedTypedMessagesCount: 0, - } - return cb(null, stateUpdate) - }, - }, -} - diff --git a/development/build/display.js b/development/build/display.js index 008b19d0c..e9c255af5 100644 --- a/development/build/display.js +++ b/development/build/display.js @@ -34,7 +34,7 @@ function setupTaskDisplay (taskEvents) { function displayChart (data) { // sort tasks by start time - data.sort((a, b,) => a[1] - b[1]) + data.sort((a, b) => a[1] - b[1]) // get bounds const first = Math.min(...data.map((entry) => entry[1])) diff --git a/development/build/etc.js b/development/build/etc.js index ab0c2afb8..0dbce1255 100644 --- a/development/build/etc.js +++ b/development/build/etc.js @@ -25,7 +25,7 @@ function createEtcTasks ({ browserPlatforms, livereload }) { // zip tasks for distribution const zip = createTask('zip', composeParallel( - ...browserPlatforms.map((platform) => createZipTask(platform)) + ...browserPlatforms.map((platform) => createZipTask(platform)), )) return { clean, reload, zip } diff --git a/development/build/index.js b/development/build/index.js index 5b073de55..a665410b2 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -39,9 +39,9 @@ function defineAllTasks () { scriptTasks.dev, staticTasks.dev, manifestTasks.dev, - reload - ) - ) + reload, + ), + ), ) // build for test development (livereload) @@ -53,9 +53,9 @@ function defineAllTasks () { scriptTasks.testDev, staticTasks.dev, manifestTasks.testDev, - reload - ) - ) + reload, + ), + ), ) // build for prod release @@ -69,7 +69,7 @@ function defineAllTasks () { manifestTasks.prod, ), zip, - ) + ), ) // build for CI testing @@ -82,7 +82,7 @@ function defineAllTasks () { staticTasks.prod, manifestTasks.test, ), - ) + ), ) // special build for minimal CI testing diff --git a/development/build/scripts.js b/development/build/scripts.js index 86a082bd6..0cb3e85ea 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -94,13 +94,13 @@ function createScriptTasks ({ browserPlatforms, livereload }) { const standardSubtasks = standardBundles.map((filename) => { return createTask(`${taskPrefix}:${filename}`, - createBundleTaskForBuildJsExtensionNormal({ filename, devMode, testing }) + createBundleTaskForBuildJsExtensionNormal({ filename, devMode, testing }), ) }) // inpage must be built before contentscript // because inpage bundle result is included inside contentscript const contentscriptSubtask = createTask(`${taskPrefix}:contentscript`, - createTaskForBuildJsExtensionContentscript({ devMode, testing }) + createTaskForBuildJsExtensionContentscript({ devMode, testing }), ) // task for initiating livereload @@ -156,7 +156,7 @@ function createScriptTasks ({ browserPlatforms, livereload }) { externalDependencies: devMode ? undefined : externalDependenciesMap[contentscript], devMode, testing, - }) + }), ) } diff --git a/development/create-static-server.js b/development/create-static-server.js new file mode 100644 index 000000000..3312c43e7 --- /dev/null +++ b/development/create-static-server.js @@ -0,0 +1,22 @@ +const http = require('http') +const path = require('path') + +const serveHandler = require('serve-handler') + +const createStaticServer = (rootDirectory) => { + return http.createServer((request, response) => { + if (request.url.startsWith('/node_modules/')) { + request.url = request.url.substr(14) + return serveHandler(request, response, { + directoryListing: false, + public: path.resolve('./node_modules'), + }) + } + return serveHandler(request, response, { + directoryListing: false, + public: rootDirectory, + }) + }) +} + +module.exports = createStaticServer diff --git a/development/genStates.js b/development/genStates.js deleted file mode 100644 index 7a6945c81..000000000 --- a/development/genStates.js +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint-disable import/no-dynamic-require */ -const fs = require('fs') -const path = require('path') -const promisify = require('pify') -const enLocaleMessages = require('../app/_locales/en/messages.json') - -const writeFile = promisify(fs.writeFile) - -start().catch(console.error) - -async function start () { - const statesPath = path.join(__dirname, 'states') - const stateFilesNames = await promisify(fs.readdir)(statesPath) - const states = {} - await Promise.all(stateFilesNames.map(async (stateFileName) => { - const stateFilePath = path.join(__dirname, 'states', stateFileName) - const state = require(stateFilePath) - - state.localeMessages = { en: enLocaleMessages, current: {} } - - const stateName = stateFileName.split('.')[0].replace(/-/g, ' ', 'g') - states[stateName] = state - })) - const generatedFileContent = `module.exports = ${JSON.stringify(states)}` - const generatedFilePath = path.join(__dirname, 'states.js') - await writeFile(generatedFilePath, generatedFileContent) -} diff --git a/development/index.html b/development/index.html deleted file mode 100644 index e5a027447..000000000 --- a/development/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - MetaMask - - - - - - - - - - diff --git a/development/mock-dev.js b/development/mock-dev.js deleted file mode 100644 index 6e3da391f..000000000 --- a/development/mock-dev.js +++ /dev/null @@ -1,156 +0,0 @@ -/* MOCK DEV - * - * This is a utility module. - * It initializes a minimalist browserifiable project - * that contains the Metamask UI, with a local background process. - * - * Includes a state reset button for restoring to initial state. - * - * This is a convenient way to develop and test the plugin - * without having to re-open the plugin or even re-build it. - */ - -import log from 'loglevel' -import React from 'react' -import { render } from 'react-dom' -import { createStore, applyMiddleware } from 'redux' -import thunkMiddleware from 'redux-thunk' -import * as qs from 'qs' -import Selector from './selector' -import * as actions from '../ui/app/store/actions' -import Root from '../ui/app/pages' -import rootReducer from '../ui/app/ducks' -import MetamaskController from '../app/scripts/metamask-controller' -import firstTimeState from '../app/scripts/first-time-state' -import ExtensionPlatform from '../app/scripts/platforms/extension' - -const backGroundConnectionModifiers = require('./backGroundConnectionModifiers') - -const noop = function () {} - -// the states file is generated before this file is run, but after `lint` is run -const states = require('./states') /* eslint-disable-line import/no-unresolved */ - -window.log = log -log.setLevel('debug') - -const routerPath = window.location.href.split('#')[1] -let queryString = {} -let selectedView - -if (routerPath) { - queryString = qs.parse(routerPath.split('?')[1]) -} - -selectedView = queryString.view || 'confirm sig requests' -const firstState = states[selectedView] -updateQueryParams(selectedView) - -function updateQueryParams (newView) { - queryString.view = newView - const params = qs.stringify(queryString) - const locationPaths = window.location.href.split('#') - const routerPath = locationPaths[1] || '' - const newPath = locationPaths[0] + '#' + routerPath.split('?')[0] + `?${params}` - - if (window.location.href !== newPath) { - window.location.href = newPath - } -} - -// -// MetaMask Controller -// - -// some extension platform APIs must be mocked -function mockPlatformApis () { - global.platform.getVersion = () => '0.0.0' -} - -const controller = new MetamaskController({ - // User confirmation callbacks: - showUnconfirmedMessage: noop, - showUnapprovedTx: noop, - platform: {}, - // initial state - initState: firstTimeState, -}) -global.metamaskController = controller -global.platform = new ExtensionPlatform() -mockPlatformApis() - -// -// User Interface -// - -actions._setBackgroundConnection(controller.getApi()) -function updateState (stateName) { - selectedView = stateName - updateQueryParams(stateName) - const newState = states[selectedView] - return { - type: 'GLOBAL_FORCE_UPDATE', - value: newState, - } -} - -function modifyBackgroundConnection (backgroundConnectionModifier) { - const modifiedBackgroundConnection = Object.assign({}, controller.getApi(), backgroundConnectionModifier) - actions._setBackgroundConnection(modifiedBackgroundConnection) -} - -// parse opts -const store = createStore( - (state, action) => - (action.type === 'GLOBAL_FORCE_UPDATE' - ? action.value - : rootReducer(state, action)), - firstState, - applyMiddleware(thunkMiddleware), -) - -// start app -startApp() - -function startApp () { - const body = document.body - const container = document.createElement('div') - container.id = 'test-container' - body.appendChild(container) - - render( -
- - -
- -
-
, - container, - ) -} diff --git a/development/selector.js b/development/selector.js deleted file mode 100644 index d3ef65bcc..000000000 --- a/development/selector.js +++ /dev/null @@ -1,49 +0,0 @@ -import PropTypes from 'prop-types' -import React, { Component } from 'react' - -export default class Selector extends Component { - state = {} - - render () { - const { - states, - selectedKey, - updateState, - store, - modifyBackgroundConnection, - backGroundConnectionModifiers, - } = this.props - const selected = this.state.selected || selectedKey - - return ( - - ) - } -} - -Selector.propTypes = { - states: PropTypes.object.isRequired, - selectedKey: PropTypes.string.isRequired, - updateState: PropTypes.func.isRequired, - store: PropTypes.object.isRequired, - modifyBackgroundConnection: PropTypes.func.isRequired, - backGroundConnectionModifiers: PropTypes.object.isRequired, -} diff --git a/development/states/confirm-sig-requests.json b/development/states/confirm-sig-requests.json deleted file mode 100644 index 18a31a93f..000000000 --- a/development/states/confirm-sig-requests.json +++ /dev/null @@ -1,531 +0,0 @@ -{ - "metamask": { - "completedOnboarding": true, - "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" - } - }, - "abTests": { - "fullScreenVsPopup": "control" - }, - "cachedBalances": {}, - "conversionRate": 1200.88200327, - "conversionDate": 1489013762, - "noActiveNotices": true, - "frequentRpcList": [], - "network": "3", - "accounts": { - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { - "code": "0x", - "balance": "0x47c9d71831c76efe", - "nonce": "0x1b", - "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" - }, - "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { - "code": "0x", - "balance": "0x37452b1315889f80", - "nonce": "0xa", - "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb" - }, - "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { - "code": "0x", - "balance": "0x30c9d71831c76efe", - "nonce": "0x1c", - "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" - }, - "0xd85a4b6a394794842887b8284293d69163007bbb": { - "code": "0x", - "balance": "0x0", - "nonce": "0x0", - "address": "0xd85a4b6a394794842887b8284293d69163007bbb" - } - }, - "addressBook": [ - { - "address": "0x06195827297c7a80a443b6894d3bdb8824b43896", - "name": "Address Book Account 1" - } - ], - "tokens": [], - "transactions": {}, - "incomingTransactions": {}, - "currentNetworkTxList": [], - "unapprovedTxs": {}, - "unapprovedMsgs": { - "8927167822566864": { - "id": 8927167822566864, - "msgParams": { - "data": "0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0", - "from": "0xd85a4b6a394794842887b8284293d69163007bbb" - }, - "status": "unapproved", - "time": 1537889070000, - "type": "eth_sign" - } - }, - "unapprovedMsgCount": 1, - "unapprovedPersonalMsgs": { - "8907167822566865": { - "id": 8907167822566865, - "msgParams": { - "data": "0x23205465726d73206f662055736520230a0a2a2a544849532041475245454d454e54204953205355424a45435420544f2042494e44494e47204152424954524154494f4e20414e44204120574149564552204f4620434c41535320414354494f4e205249474854532041532044455441494c454420494e2053454354494f4e2031332e20504c454153452052454144205448452041475245454d454e54204341524546554c4c592e2a2a0a0a5f4f7572205465726d73206f66205573652068617665206265656e2075706461746564206173206f662053657074656d62657220352c20323031365f0a0a232320312e20416363657074616e6365206f66205465726d732023230a0a4d6574614d61736b2070726f7669646573206120706c6174666f726d20666f72206d616e6167696e6720457468657265756d20286f7220224554482229206163636f756e74732c20616e6420616c6c6f77696e67206f7264696e61727920776562736974657320746f20696e74657261637420776974682074686520457468657265756d20626c6f636b636861696e2c207768696c65206b656570696e6720746865207573657220696e20636f6e74726f6c206f7665722077686174207472616e73616374696f6e73207468657920617070726f76652c207468726f756768206f75722077656273697465206c6f63617465642061745b205d28687474703a2f2f6d6574616d61736b2e696f295b68747470733a2f2f6d6574616d61736b2e696f2f5d2868747470733a2f2f6d6574616d61736b2e696f2f2920616e642062726f7773657220706c7567696e2028746865202253697465222920e2809420776869636820696e636c7564657320746578742c20696d616765732c20617564696f2c20636f646520616e64206f74686572206d6174657269616c73202028636f6c6c6563746976656c792c2074686520e2809c436f6e74656e74e2809d2920616e6420616c6c206f66207468652066656174757265732c20616e642073657276696365732070726f76696465642e2054686520536974652c20616e6420616e79206f746865722066656174757265732c20746f6f6c732c206d6174657269616c732c206f72206f74686572207365727669636573206f6666657265642066726f6d2074696d6520746f2074696d65206279204d6574614d61736b2061726520726566657272656420746f20686572652061732074686520e2809c536572766963652ee2809d20506c656173652072656164207468657365205465726d73206f6620557365202874686520e2809c5465726d73e2809d206f7220e2809c5465726d73206f6620557365e2809d29206361726566756c6c79206265666f7265207573696e672074686520536572766963652e204279207573696e67206f72206f746865727769736520616363657373696e67207468652053657276696365732c206f7220636c69636b696e6720746f20616363657074206f7220616772656520746f207468657365205465726d732077686572652074686174206f7074696f6e206973206d61646520617661696c61626c652c20796f75202831292061636365707420616e6420616772656520746f207468657365205465726d732028322920636f6e73656e7420746f2074686520636f6c6c656374696f6e2c207573652c20646973636c6f7375726520616e64206f746865722068616e646c696e67206f6620696e666f726d6174696f6e2061732064657363726962656420696e206f7572205072697661637920506f6c6963792020616e642028332920616e79206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e20697373756564206279204d6574614d61736b2066726f6d2074696d6520746f2074696d652e20496620796f7520646f206e6f7420616772656520746f20746865205465726d732c207468656e20796f75206d6179206e6f7420616363657373206f72207573652074686520436f6e74656e74206f722053657276696365732e0a0a232320322e204d6f64696669636174696f6e206f66205465726d73206f66205573652023230a0a45786365707420666f722053656374696f6e2031332c2070726f766964696e6720666f722062696e64696e67206172626974726174696f6e20616e6420776169766572206f6620636c61737320616374696f6e207269676874732c204d6574614d61736b207265736572766573207468652072696768742c2061742069747320736f6c652064697363726574696f6e2c20746f206d6f64696679206f72207265706c61636520746865205465726d73206f662055736520617420616e792074696d652e20546865206d6f73742063757272656e742076657273696f6e206f66207468657365205465726d732077696c6c20626520706f73746564206f6e206f757220536974652e20596f75207368616c6c20626520726573706f6e7369626c6520666f7220726576696577696e6720616e64206265636f6d696e672066616d696c696172207769746820616e792073756368206d6f64696669636174696f6e732e20557365206f662074686520536572766963657320627920796f7520616674657220616e79206d6f64696669636174696f6e20746f20746865205465726d7320636f6e737469747574657320796f757220616363657074616e6365206f6620746865205465726d73206f6620557365206173206d6f6469666965642e0a0a0a0a232320332e20456c69676962696c6974792023230a0a596f752068657265627920726570726573656e7420616e642077617272616e74207468617420796f75206172652066756c6c792061626c6520616e6420636f6d706574656e7420746f20656e74657220696e746f20746865207465726d732c20636f6e646974696f6e732c206f626c69676174696f6e732c2061666669726d6174696f6e732c20726570726573656e746174696f6e7320616e642077617272616e746965732073657420666f72746820696e207468657365205465726d7320616e6420746f20616269646520627920616e6420636f6d706c792077697468207468657365205465726d732e0a0a4d6574614d61736b206973206120676c6f62616c20706c6174666f726d20616e6420627920616363657373696e672074686520436f6e74656e74206f722053657276696365732c20796f752061726520726570726573656e74696e6720616e642077617272616e74696e6720746861742c20796f7520617265206f6620746865206c6567616c20616765206f66206d616a6f7269747920696e20796f7572206a7572697364696374696f6e20617320697320726571756972656420746f20616363657373207375636820536572766963657320616e6420436f6e74656e…16e79206368616e67657320746f20746869732073656374696f6e2e204368616e6765732077696c6c206265636f6d6520656666656374697665206f6e207468652036307468206461792c20616e642077696c6c206170706c792070726f73706563746976656c79206f6e6c7920746f20616e7920636c61696d732061726973696e67206166746572207468652036307468206461792e0a0a466f7220616e792064697370757465206e6f74207375626a65637420746f206172626974726174696f6e20796f7520616e64204d6574614d61736b20616772656520746f207375626d697420746f2074686520706572736f6e616c20616e64206578636c7573697665206a7572697364696374696f6e206f6620616e642076656e756520696e20746865206665646572616c20616e6420737461746520636f75727473206c6f636174656420696e204e657720596f726b2c204e657720596f726b2e20596f75206675727468657220616772656520746f206163636570742073657276696365206f662070726f63657373206279206d61696c2c20616e642068657265627920776169766520616e7920616e6420616c6c206a7572697364696374696f6e616c20616e642076656e756520646566656e736573206f746865727769736520617661696c61626c652e0a0a546865205465726d7320616e64207468652072656c6174696f6e73686970206265747765656e20796f7520616e64204d6574614d61736b207368616c6c20626520676f7665726e656420627920746865206c617773206f6620746865205374617465206f66204e657720596f726b20776974686f75742072656761726420746f20636f6e666c696374206f66206c61772070726f766973696f6e732e0a0a23232031342e2047656e6572616c20496e666f726d6174696f6e2023230a0a2323232031342e3120456e746972652041677265656d656e74202323230a0a5468657365205465726d732028616e6420616e79206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e2074686174204d6574614d61736b206d617920706f7374206f6e2074686520536572766963652920636f6e737469747574652074686520656e746972652061677265656d656e74206265747765656e20796f7520616e64204d6574614d61736b2077697468207265737065637420746f20746865205365727669636520616e64207375706572736564657320616e79207072696f722061677265656d656e74732c206f72616c206f72207772697474656e2c206265747765656e20796f7520616e64204d6574614d61736b2e20496e20746865206576656e74206f66206120636f6e666c696374206265747765656e207468657365205465726d7320616e6420746865206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e2c20746865206c61747465722077696c6c207072657661696c206f76657220746865205465726d7320746f2074686520657874656e74206f662074686520636f6e666c6963742e0a0a2323232031342e322057616976657220616e642053657665726162696c697479206f66205465726d73202323230a0a546865206661696c757265206f66204d6574614d61736b20746f206578657263697365206f7220656e666f72636520616e79207269676874206f722070726f766973696f6e206f6620746865205465726d73207368616c6c206e6f7420636f6e73746974757465206120776169766572206f662073756368207269676874206f722070726f766973696f6e2e20496620616e792070726f766973696f6e206f6620746865205465726d7320697320666f756e6420627920616e2061726269747261746f72206f7220636f757274206f6620636f6d706574656e74206a7572697364696374696f6e20746f20626520696e76616c69642c207468652070617274696573206e657665727468656c6573732061677265652074686174207468652061726269747261746f72206f7220636f7572742073686f756c6420656e646561766f7220746f20676976652065666665637420746f2074686520706172746965732720696e74656e74696f6e73206173207265666c656374656420696e207468652070726f766973696f6e2c20616e6420746865206f746865722070726f766973696f6e73206f6620746865205465726d732072656d61696e20696e2066756c6c20666f72636520616e64206566666563742e0a0a2323232031342e332053746174757465206f66204c696d69746174696f6e73202323230a0a596f752061677265652074686174207265676172646c657373206f6620616e792073746174757465206f72206c617720746f2074686520636f6e74726172792c20616e7920636c61696d206f72206361757365206f6620616374696f6e2061726973696e67206f7574206f66206f722072656c6174656420746f2074686520757365206f66207468652053657276696365206f7220746865205465726d73206d7573742062652066696c65642077697468696e206f6e65202831292079656172206166746572207375636820636c61696d206f72206361757365206f6620616374696f6e2061726f7365206f7220626520666f7265766572206261727265642e0a0a2323232031342e342053656374696f6e205469746c6573202323230a0a5468652073656374696f6e207469746c657320696e20746865205465726d732061726520666f7220636f6e76656e69656e6365206f6e6c7920616e642068617665206e6f206c6567616c206f7220636f6e747261637475616c206566666563742e0a0a2323232031342e3520436f6d6d756e69636174696f6e73202323230a0a55736572732077697468207175657374696f6e732c20636f6d706c61696e7473206f7220636c61696d732077697468207265737065637420746f207468652053657276696365206d617920636f6e74616374207573207573696e67207468652072656c6576616e7420636f6e7461637420696e666f726d6174696f6e2073657420666f7274682061626f766520616e6420617420636f6d6d756e69636174696f6e73406d6574616d61736b2e696f2e0a0a23232031352052656c61746564204c696e6b732023230a0a2a2a5b5465726d73206f66205573655d2868747470733a2f2f6d6574616d61736b2e696f2f7465726d732e68746d6c292a2a0a0a2a2a5b507269766163795d2868747470733a2f2f6d6574616d61736b2e696f2f707269766163792e68746d6c292a2a0a0a2a2a5b4174747269627574696f6e735d2868747470733a2f2f6d6574616d61736b2e696f2f6174747269627574696f6e732e68746d6c292a2a0a", - "from": "0xd85a4b6a394794842887b8284293d69163007bbb" - }, - "status": "unapproved", - "time": 1537889065000, - "type": "personal_sign" - } - }, - "unapprovedPersonalMsgCount": 1 , - "unapprovedTypedMessages": { - "8997167822566869": { - "id": 8997167822566869, - "msgParams": { - "data": [ - {"type": "string", "name": "Message", "value": "Hi, Alice!"}, - {"type": "uint32", "name": "A number", "value": "1337"} - ], - "from": "0xd85a4b6a394794842887b8284293d69163007bbb" - }, - "status": "unapproved", - "time": 1537889060000, - "type": "eth_signTypedData" - } - }, - "unapprovedTypedMessagesCount": 1, - "keyringTypes": [ - "Simple Key Pair", - "HD Key Tree" - ], - "keyrings": [ - { - "type": "HD Key Tree", - "accounts": [ - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", - "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", - "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" - ] - }, - { - "type": "Simple Key Pair", - "accounts": [ - "0xd85a4b6a394794842887b8284293d69163007bbb" - ] - } - ], - "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb", - "currentCurrency": "USD", - "provider": { - "type": "testnet" - }, - "send": { - "gasLimit": "0xea60", - "gasPrice": "0xba43b7400", - "gasTotal": "0xb451dc41b578", - "tokenBalance": null, - "from": { - "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", - "balance": "0x37452b1315889f80" - }, - "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d", - "amount": "0x1bc16d674ec80000", - "memo": "", - "errors": {}, - "warnings": {}, - "maxModeOn": false, - "editingTransactionId": null - }, - "currentLocale": "en", - "preferences": { - "useNativeCurrencyAsPrimaryCurrency": true - }, - "frequentRpcListDetail": [] - }, - "appState": { - "menuOpen": false, - "currentView": { - "name": "confTx", - "detailView": null, - "context": 0 - }, - "accountDetail": { - "subview": "transactions" - }, - "sidebar": {}, - "modal": { - "modalState": {}, - "previousModalState": {} - }, - "isLoading": false, - "warning": null, - "scrollToBottom": false, - "forgottenPassword": null - }, - "identities": {}, - "confirmTransaction": { - "txData": { - "id": 8927167822566864, - "msgParams": { - "data": "0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0", - "from": "0x0d0c7188d9c72b019a5da9bca0d127680c22e658" - }, - "status": "unapproved", - "time": 1537889069339, - "type": "eth_sign" - }, - "tokenData": {}, - "methodData": {}, - "tokenProps": { - "tokenDecimals": "", - "tokenSymbol": "" - }, - "fiatTransactionAmount": "", - "fiatTransactionFee": "", - "fiatTransactionTotal": "", - "ethTransactionAmount": "", - "ethTransactionFee": "", - "ethTransactionTotal": "", - "hexGasTotal": "", - "nonce": "", - "fetchingMethodData": false - }, - "gas": { - "customData": { - "price": null, - "limit": "0x186a0" - }, - "basicEstimates": { - "average": 73, - "avgWait": 10.6, - "blockTime": 13.871657754010695, - "blockNum": 6655504, - "fast": 160, - "fastest": 290, - "fastestWait": 0.5, - "fastWait": 0.6, - "safeLow": 50, - "safeLowWait": 16.1, - "speed": 0.6702462692280712 - }, - "basicEstimateIsLoading": false, - "gasEstimatesLoading": false, - "priceAndTimeEstimates": [ - { - "expectedTime": "1374.1168296452973076627", - "expectedWait": 99.0593088449, - "gasprice": 4.1 - }, - { - "expectedTime": "1280.88976972896682763716", - "expectedWait": 92.3386225672, - "gasprice": 4.4 - }, - { - "expectedTime": "1245.13314632680319175597", - "expectedWait": 89.7609477113, - "gasprice": 4.8 - }, - { - "expectedTime": "1227.99925007911014385881", - "expectedWait": 88.5257747744, - "gasprice": 4.9 - }, - { - "expectedTime": "965.52572720362993349654", - "expectedWait": 69.6042062402, - "gasprice": 5 - }, - { - "expectedTime": "917.466895447437420776", - "expectedWait": 66.1396721082, - "gasprice": 5.1 - }, - { - "expectedTime": "915.81694044041496090521", - "expectedWait": 66.0207277804, - "gasprice": 5.2 - }, - { - "expectedTime": "902.13145619709089691874", - "expectedWait": 65.034148924, - "gasprice": 5.3 - }, - { - "expectedTime": "890.83591122200105749896", - "expectedWait": 64.2198594443, - "gasprice": 5.4 - }, - { - "expectedTime": "879.10469542971335712248", - "expectedWait": 63.3741627006, - "gasprice": 5.5 - }, - { - "expectedTime": "876.99737395823100420974", - "expectedWait": 63.2222470818, - "gasprice": 5.6 - }, - { - "expectedTime": "865.96781957003849098957", - "expectedWait": 62.4271327138, - "gasprice": 5.7 - }, - { - "expectedTime": "865.44839472121496158482", - "expectedWait": 62.3896876688, - "gasprice": 5.8 - }, - { - "expectedTime": "802.16173170976255602161", - "expectedWait": 57.8273877524, - "gasprice": 6 - }, - { - "expectedTime": "780.79313908053047074843", - "expectedWait": 56.2869379368, - "gasprice": 6.1 - }, - { - "expectedTime": "770.04888359616469549233", - "expectedWait": 55.5123906062, - "gasprice": 6.2 - }, - { - "expectedTime": "745.01007965146736962697", - "expectedWait": 53.7073573226, - "gasprice": 6.3 - }, - { - "expectedTime": "735.19921111598501681816", - "expectedWait": 53.0000973318, - "gasprice": 6.6 - }, - { - "expectedTime": "705.68767153912619368694", - "expectedWait": 50.8726270539, - "gasprice": 6.7 - }, - { - "expectedTime": "705.26438593445239690121", - "expectedWait": 50.8421126329, - "gasprice": 6.9 - }, - { - "expectedTime": "652.51573119854865429742", - "expectedWait": 47.0394918019, - "gasprice": 7 - }, - { - "expectedTime": "635.51471669299464383162", - "expectedWait": 45.813898235, - "gasprice": 7.1 - }, - { - "expectedTime": "634.37181911960854759036", - "expectedWait": 45.7315073922, - "gasprice": 7.2 - }, - { - "expectedTime": "633.23097691113902888918", - "expectedWait": 45.6492647195, - "gasprice": 7.3 - }, - { - "expectedTime": "112.7753456245379663928", - "expectedWait": 8.1299111919, - "gasprice": 7.6 - }, - { - "expectedTime": "102.9665314468898381829", - "expectedWait": 7.4227992986, - "gasprice": 8 - }, - { - "expectedTime": "100.94784507024919649891", - "expectedWait": 7.2772733339, - "gasprice": 8.1 - }, - { - "expectedTime": "100.46445647447807351078", - "expectedWait": 7.2424261221, - "gasprice": 8.8 - }, - { - "expectedTime": "84.91686745986737853339", - "expectedWait": 6.1216091808, - "gasprice": 9 - }, - { - "expectedTime": "80.39566429296684383503", - "expectedWait": 5.7956781892, - "gasprice": 9.1 - }, - { - "expectedTime": "78.24522052614759252715", - "expectedWait": 5.6406539084, - "gasprice": 9.2 - }, - { - "expectedTime": "77.1685119880459882636", - "expectedWait": 5.5630345959, - "gasprice": 9.5 - }, - { - "expectedTime": "72.43649507646737870178", - "expectedWait": 5.2219061601, - "gasprice": 9.8 - }, - { - "expectedTime": "71.48259532351443753818", - "expectedWait": 5.1531400638, - "gasprice": 9.9 - }, - { - "expectedTime": "58.23892805162994573827", - "expectedWait": 4.1984115442, - "gasprice": 10 - }, - { - "expectedTime": "53.13065124862245917617", - "expectedWait": 3.8301587446, - "gasprice": 10.1 - }, - { - "expectedTime": "53.03510209647058751971", - "expectedWait": 3.82327066, - "gasprice": 10.3 - }, - { - "expectedTime": "49.06846157804491912403", - "expectedWait": 3.5373177776, - "gasprice": 11 - }, - { - "expectedTime": "48.30893330101818116637", - "expectedWait": 3.4825638116, - "gasprice": 11.1 - }, - { - "expectedTime": "48.25099734861818116715", - "expectedWait": 3.4783872414, - "gasprice": 11.3 - }, - { - "expectedTime": "47.64416885027272662988", - "expectedWait": 3.4346413165, - "gasprice": 11.9 - }, - { - "expectedTime": "46.76354741392085498401", - "expectedWait": 3.3711578128, - "gasprice": 12.6 - }, - { - "expectedTime": "44.99427448545882292232", - "expectedWait": 3.2436119232, - "gasprice": 13 - }, - { - "expectedTime": "44.61790554199251276697", - "expectedWait": 3.2164796979, - "gasprice": 13.1 - }, - { - "expectedTime": "42.87832690973048070488", - "expectedWait": 3.0910744534, - "gasprice": 14 - }, - { - "expectedTime": "42.21224091308663044649", - "expectedWait": 3.0430566888, - "gasprice": 14.9 - }, - { - "expectedTime": "41.15715335111336842864", - "expectedWait": 2.9669960203, - "gasprice": 15 - }, - { - "expectedTime": "40.9600723880876999821", - "expectedWait": 2.9527885646, - "gasprice": 15.1 - }, - { - "expectedTime": "38.89138450301711177472", - "expectedWait": 2.8036580193, - "gasprice": 15.8 - }, - { - "expectedTime": "37.89655640860213852611", - "expectedWait": 2.7319414219, - "gasprice": 16 - }, - { - "expectedTime": "37.35265517364705831954", - "expectedWait": 2.692731888, - "gasprice": 17.4 - }, - { - "expectedTime": "36.79447683873796741798", - "expectedWait": 2.652493126, - "gasprice": 17.8 - }, - { - "expectedTime": "36.11439350850802090309", - "expectedWait": 2.6034663015, - "gasprice": 19 - }, - { - "expectedTime": "31.32676199432192471101", - "expectedWait": 2.2583286403, - "gasprice": 20 - }, - { - "expectedTime": "30.76792490132192471855", - "expectedWait": 2.2180423888, - "gasprice": 20.1 - }, - { - "expectedTime": "29.94493658520962526441", - "expectedWait": 2.1587136243, - "gasprice": 25 - }, - { - "expectedTime": "29.53287347625561457478", - "expectedWait": 2.1290082267, - "gasprice": 29 - }, - { - "expectedTime": "29.09318627175614934008", - "expectedWait": 2.0973114236, - "gasprice": 47 - } - ], - "priceAndTimeEstimatesLastRetrieved": 1541527901281, - "errors": {} - }, - "unconnectedAccount": { - "state": "CLOSED" - }, - "history": { - "mostRecentOverviewPage": "/" - } -} diff --git a/development/states/currency-localization.json b/development/states/currency-localization.json deleted file mode 100644 index ca8ee7c42..000000000 --- a/development/states/currency-localization.json +++ /dev/null @@ -1,482 +0,0 @@ -{ - "metamask": { - "completedOnboarding": true, - "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" - } - }, - "abTests": { - "fullScreenVsPopup": "control" - }, - "cachedBalances": {}, - "unapprovedTxs": {}, - "conversionRate": 19855, - "conversionDate": 1489013762, - "noActiveNotices": true, - "frequentRpcList": [], - "network": "3", - "accounts": { - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { - "code": "0x", - "balance": "0x47c9d71831c76efe", - "nonce": "0x1b", - "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" - }, - "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { - "code": "0x", - "balance": "0x37452b1315889f80", - "nonce": "0xa", - "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb" - }, - "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { - "code": "0x", - "balance": "0x30c9d71831c76efe", - "nonce": "0x1c", - "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" - }, - "0xd85a4b6a394794842887b8284293d69163007bbb": { - "code": "0x", - "balance": "0x0", - "nonce": "0x0", - "address": "0xd85a4b6a394794842887b8284293d69163007bbb" - } - }, - "addressBook": [ - { - "address": "0x06195827297c7a80a443b6894d3bdb8824b43896", - "name": "Address Book Account 1" - } - ], - "tokens": [], - "transactions": {}, - "incomingTransactions": {}, - "currentNetworkTxList": [], - "unapprovedMsgs": {}, - "unapprovedMsgCount": 0, - "unapprovedPersonalMsgs": {}, - "unapprovedPersonalMsgCount": 0, - "keyringTypes": [ - "Simple Key Pair", - "HD Key Tree" - ], - "keyrings": [ - { - "type": "HD Key Tree", - "accounts": [ - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", - "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", - "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" - ] - }, - { - "type": "Simple Key Pair", - "accounts": [ - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" - ] - } - ], - "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", - "currentCurrency": "PHP", - "provider": { - "type": "testnet" - }, - "send": { - "gasLimit": null, - "gasPrice": null, - "gasTotal": "0xb451dc41b578", - "tokenBalance": null, - "from": "", - "to": "", - "amount": "0x0", - "memo": "", - "errors": {}, - "warnings": {}, - "maxModeOn": false, - "editingTransactionId": null - }, - "currentLocale": "en", - "preferences": { - "useNativeCurrencyAsPrimaryCurrency": true, - "showFiatInTestnets": true - }, - "frequentRpcListDetail": [] - }, - "appState": { - "menuOpen": false, - "currentView": { - "name": "accountDetail", - "detailView": null, - "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" - }, - "accountDetail": { - "subview": "transactions" - }, - "sidebar": {}, - "modal": { - "modalState": {}, - "previousModalState": {} - }, - "isLoading": false, - "warning": null, - "scrollToBottom": false, - "forgottenPassword": null - }, - "identities": {}, - "confirmTransaction": { - "txData": {}, - "tokenData": {}, - "methodData": {}, - "tokenProps": { - "tokenDecimals": "", - "tokenSymbol": "" - }, - "fiatTransactionAmount": "", - "fiatTransactionFee": "", - "fiatTransactionTotal": "", - "ethTransactionAmount": "", - "ethTransactionFee": "", - "ethTransactionTotal": "", - "hexGasTotal": "", - "nonce": "", - "fetchingMethodData": false - }, - "gas": { - "customData": { - "price": null, - "limit": "0x186a0" - }, - "basicEstimates": { - "average": 73, - "avgWait": 10.6, - "blockTime": 13.871657754010695, - "blockNum": 6655504, - "fast": 160, - "fastest": 290, - "fastestWait": 0.5, - "fastWait": 0.6, - "safeLow": 50, - "safeLowWait": 16.1, - "speed": 0.6702462692280712 - }, - "basicEstimateIsLoading": false, - "gasEstimatesLoading": false, - "priceAndTimeEstimates": [ - { - "expectedTime": "1374.1168296452973076627", - "expectedWait": 99.0593088449, - "gasprice": 4.1 - }, - { - "expectedTime": "1280.88976972896682763716", - "expectedWait": 92.3386225672, - "gasprice": 4.4 - }, - { - "expectedTime": "1245.13314632680319175597", - "expectedWait": 89.7609477113, - "gasprice": 4.8 - }, - { - "expectedTime": "1227.99925007911014385881", - "expectedWait": 88.5257747744, - "gasprice": 4.9 - }, - { - "expectedTime": "965.52572720362993349654", - "expectedWait": 69.6042062402, - "gasprice": 5 - }, - { - "expectedTime": "917.466895447437420776", - "expectedWait": 66.1396721082, - "gasprice": 5.1 - }, - { - "expectedTime": "915.81694044041496090521", - "expectedWait": 66.0207277804, - "gasprice": 5.2 - }, - { - "expectedTime": "902.13145619709089691874", - "expectedWait": 65.034148924, - "gasprice": 5.3 - }, - { - "expectedTime": "890.83591122200105749896", - "expectedWait": 64.2198594443, - "gasprice": 5.4 - }, - { - "expectedTime": "879.10469542971335712248", - "expectedWait": 63.3741627006, - "gasprice": 5.5 - }, - { - "expectedTime": "876.99737395823100420974", - "expectedWait": 63.2222470818, - "gasprice": 5.6 - }, - { - "expectedTime": "865.96781957003849098957", - "expectedWait": 62.4271327138, - "gasprice": 5.7 - }, - { - "expectedTime": "865.44839472121496158482", - "expectedWait": 62.3896876688, - "gasprice": 5.8 - }, - { - "expectedTime": "802.16173170976255602161", - "expectedWait": 57.8273877524, - "gasprice": 6 - }, - { - "expectedTime": "780.79313908053047074843", - "expectedWait": 56.2869379368, - "gasprice": 6.1 - }, - { - "expectedTime": "770.04888359616469549233", - "expectedWait": 55.5123906062, - "gasprice": 6.2 - }, - { - "expectedTime": "745.01007965146736962697", - "expectedWait": 53.7073573226, - "gasprice": 6.3 - }, - { - "expectedTime": "735.19921111598501681816", - "expectedWait": 53.0000973318, - "gasprice": 6.6 - }, - { - "expectedTime": "705.68767153912619368694", - "expectedWait": 50.8726270539, - "gasprice": 6.7 - }, - { - "expectedTime": "705.26438593445239690121", - "expectedWait": 50.8421126329, - "gasprice": 6.9 - }, - { - "expectedTime": "652.51573119854865429742", - "expectedWait": 47.0394918019, - "gasprice": 7 - }, - { - "expectedTime": "635.51471669299464383162", - "expectedWait": 45.813898235, - "gasprice": 7.1 - }, - { - "expectedTime": "634.37181911960854759036", - "expectedWait": 45.7315073922, - "gasprice": 7.2 - }, - { - "expectedTime": "633.23097691113902888918", - "expectedWait": 45.6492647195, - "gasprice": 7.3 - }, - { - "expectedTime": "112.7753456245379663928", - "expectedWait": 8.1299111919, - "gasprice": 7.6 - }, - { - "expectedTime": "102.9665314468898381829", - "expectedWait": 7.4227992986, - "gasprice": 8 - }, - { - "expectedTime": "100.94784507024919649891", - "expectedWait": 7.2772733339, - "gasprice": 8.1 - }, - { - "expectedTime": "100.46445647447807351078", - "expectedWait": 7.2424261221, - "gasprice": 8.8 - }, - { - "expectedTime": "84.91686745986737853339", - "expectedWait": 6.1216091808, - "gasprice": 9 - }, - { - "expectedTime": "80.39566429296684383503", - "expectedWait": 5.7956781892, - "gasprice": 9.1 - }, - { - "expectedTime": "78.24522052614759252715", - "expectedWait": 5.6406539084, - "gasprice": 9.2 - }, - { - "expectedTime": "77.1685119880459882636", - "expectedWait": 5.5630345959, - "gasprice": 9.5 - }, - { - "expectedTime": "72.43649507646737870178", - "expectedWait": 5.2219061601, - "gasprice": 9.8 - }, - { - "expectedTime": "71.48259532351443753818", - "expectedWait": 5.1531400638, - "gasprice": 9.9 - }, - { - "expectedTime": "58.23892805162994573827", - "expectedWait": 4.1984115442, - "gasprice": 10 - }, - { - "expectedTime": "53.13065124862245917617", - "expectedWait": 3.8301587446, - "gasprice": 10.1 - }, - { - "expectedTime": "53.03510209647058751971", - "expectedWait": 3.82327066, - "gasprice": 10.3 - }, - { - "expectedTime": "49.06846157804491912403", - "expectedWait": 3.5373177776, - "gasprice": 11 - }, - { - "expectedTime": "48.30893330101818116637", - "expectedWait": 3.4825638116, - "gasprice": 11.1 - }, - { - "expectedTime": "48.25099734861818116715", - "expectedWait": 3.4783872414, - "gasprice": 11.3 - }, - { - "expectedTime": "47.64416885027272662988", - "expectedWait": 3.4346413165, - "gasprice": 11.9 - }, - { - "expectedTime": "46.76354741392085498401", - "expectedWait": 3.3711578128, - "gasprice": 12.6 - }, - { - "expectedTime": "44.99427448545882292232", - "expectedWait": 3.2436119232, - "gasprice": 13 - }, - { - "expectedTime": "44.61790554199251276697", - "expectedWait": 3.2164796979, - "gasprice": 13.1 - }, - { - "expectedTime": "42.87832690973048070488", - "expectedWait": 3.0910744534, - "gasprice": 14 - }, - { - "expectedTime": "42.21224091308663044649", - "expectedWait": 3.0430566888, - "gasprice": 14.9 - }, - { - "expectedTime": "41.15715335111336842864", - "expectedWait": 2.9669960203, - "gasprice": 15 - }, - { - "expectedTime": "40.9600723880876999821", - "expectedWait": 2.9527885646, - "gasprice": 15.1 - }, - { - "expectedTime": "38.89138450301711177472", - "expectedWait": 2.8036580193, - "gasprice": 15.8 - }, - { - "expectedTime": "37.89655640860213852611", - "expectedWait": 2.7319414219, - "gasprice": 16 - }, - { - "expectedTime": "37.35265517364705831954", - "expectedWait": 2.692731888, - "gasprice": 17.4 - }, - { - "expectedTime": "36.79447683873796741798", - "expectedWait": 2.652493126, - "gasprice": 17.8 - }, - { - "expectedTime": "36.11439350850802090309", - "expectedWait": 2.6034663015, - "gasprice": 19 - }, - { - "expectedTime": "31.32676199432192471101", - "expectedWait": 2.2583286403, - "gasprice": 20 - }, - { - "expectedTime": "30.76792490132192471855", - "expectedWait": 2.2180423888, - "gasprice": 20.1 - }, - { - "expectedTime": "29.94493658520962526441", - "expectedWait": 2.1587136243, - "gasprice": 25 - }, - { - "expectedTime": "29.53287347625561457478", - "expectedWait": 2.1290082267, - "gasprice": 29 - }, - { - "expectedTime": "29.09318627175614934008", - "expectedWait": 2.0973114236, - "gasprice": 47 - } - ], - "priceAndTimeEstimatesLastRetrieved": 1541527901281, - "errors": {} - }, - "unconnectedAccount": { - "state": "CLOSED" - }, - "history": { - "mostRecentOverviewPage": "/" - } -} diff --git a/development/states/tx-list-items.json b/development/states/tx-list-items.json deleted file mode 100644 index 17a2435d5..000000000 --- a/development/states/tx-list-items.json +++ /dev/null @@ -1,1301 +0,0 @@ -{ - "metamask": { - "completedOnboarding": true, - "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" - } - }, - "abTests": { - "fullScreenVsPopup": "control" - }, - "cachedBalances": {}, - "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": [{ - "name": "FakeTokenOne", - "address": "0x66f30b996a7d345cd00badcfe75e81e25dc5e1ec", - "symbol": "FTO", - "decimals": 2 - }, { - "name": "FakeTokenTwo", - "address": "0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb", - "symbol": "FTT", - "decimals": 2 - }], - "transactions": {}, - "incomingTransactions": {}, - "currentNetworkTxList": [ - { - "err": { - "message": "Error: intrinsic gas too low", - "stack": "Error: some error" - }, - "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 - } - ], - [ - { - "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: intrinsic gas too low", - "stack":"Error: some error" - } - } - ] - ], - "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, - "transactionCategory": "sentEther", - "txParams": { - "chainId": "0x3", - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "gas": "0x0", - "gasPrice": "0x77359400", - "nonce": "0x3", - "to": "0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3", - "value": "0x0" - } - }, - { - "id": 2315363930841933, - "time": 1522378572149, - "status": "approved", - "metamaskNetworkId": "1", - "loadingDefaults": false, - "transactionCategory": "sentEther", - "txParams": { - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "to": "0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3", - "value": "0x0", - "gas": "0x0", - "gasPrice": "0x5f5e100", - "nonce": "0x4" - }, - "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": "replace", - "path": "/txParams/gas", - "value": "0x0", - "note": "confTx: user approved transaction" - } - ], - [ - { - "op": "replace", - "path": "/status", - "value": "approved", - "note": "txStateManager: setting status to approved" - } - ] - ] - }, - { - "firstRetryBlockNumber": "0x2cbc70", - "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 - } - ], - [ - { - "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": 1522348270251, - "transactionCategory": "transfer", - "txParams": { - "chainId": "0x3", - "data": "0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b", - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "gas": "0xd3e1", - "gasPrice": "0x5f5e100", - "nonce": "0x6", - "to": "0x66f30b996a7d345cd00badcfe75e81e25dc5e1ec", - "value": "0x0" - } - }, - { - "firstRetryBlockNumber": "0x2cbc70", - "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 - } - ], - [ - { - "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, - "transactionCategory": "transfer", - "txParams": { - "chainId": "0x3", - "data": "0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b", - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "gas": "0xd3e1", - "gasPrice": "0x5f5e100", - "nonce": "0x2", - "to": "0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb", - "value": "0x0" - } - }, - { - "id": 4087002078467524, - "time": 1522379587999, - "status": "submitted", - "metamaskNetworkId": "1", - "loadingDefaults": false, - "transactionCategory": "sentEther", - "txParams": { - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "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": "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" - } - ] - ], - "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" - }, - { - "id": 2699829174766090, - "time": 1522381785750, - "status": "unapproved", - "metamaskNetworkId": "1", - "loadingDefaults": false, - "transactionCategory": "sentEther", - "txParams": { - "from": "0xd85a4b6a394794842887b8284293d69163007bbb", - "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 - } - ] - ] - } - ], - "unapprovedTxs": { - "2699829174766090": { - "id": 2699829174766090, - "time": 1522381785750, - "status": "unapproved", - "metamaskNetworkId": "1", - "loadingDefaults": false, - "transactionCategory": "sentEther", - "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 - } - ] - ] - } - }, - "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": [ - "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", - "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", - "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" - ] - }, - { - "type": "Simple Key Pair", - "accounts": [ - "0xd85a4b6a394794842887b8284293d69163007bbb" - ] - } - ], - "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb", - "provider": { - "type": "testnet" - }, - "send": {}, - "currentLocale": "en", - "preferences": { - "useNativeCurrencyAsPrimaryCurrency": true - }, - "frequentRpcListDetail": [] - }, - "appState": { - "menuOpen": false, - "currentView": { - "name": "confTx", - "detailView": null, - "context": 0 - }, - "accountDetail": { - "subview": "transactions" - }, - "modal": { - "modalState": {}, - "previousModalState": {} - }, - "sidebar": {}, - "isLoading": false, - "warning": null, - "scrollToBottom": false, - "forgottenPassword": null - }, - "identities": {}, - "send": { - "toDropdownOpen": false, - "errors": {}, - "warnings": {} - }, - "gas": { - "customData": { - "price": null, - "limit": "0x186a0" - }, - "basicEstimates": { - "average": 73, - "avgWait": 10.6, - "blockTime": 13.871657754010695, - "blockNum": 6655504, - "fast": 160, - "fastest": 290, - "fastestWait": 0.5, - "fastWait": 0.6, - "safeLow": 50, - "safeLowWait": 16.1, - "speed": 0.6702462692280712 - }, - "basicEstimateIsLoading": false, - "gasEstimatesLoading": false, - "priceAndTimeEstimates": [ - { - "expectedTime": "1374.1168296452973076627", - "expectedWait": 99.0593088449, - "gasprice": 4.1 - }, - { - "expectedTime": "1280.88976972896682763716", - "expectedWait": 92.3386225672, - "gasprice": 4.4 - }, - { - "expectedTime": "1245.13314632680319175597", - "expectedWait": 89.7609477113, - "gasprice": 4.8 - }, - { - "expectedTime": "1227.99925007911014385881", - "expectedWait": 88.5257747744, - "gasprice": 4.9 - }, - { - "expectedTime": "965.52572720362993349654", - "expectedWait": 69.6042062402, - "gasprice": 5 - }, - { - "expectedTime": "917.466895447437420776", - "expectedWait": 66.1396721082, - "gasprice": 5.1 - }, - { - "expectedTime": "915.81694044041496090521", - "expectedWait": 66.0207277804, - "gasprice": 5.2 - }, - { - "expectedTime": "902.13145619709089691874", - "expectedWait": 65.034148924, - "gasprice": 5.3 - }, - { - "expectedTime": "890.83591122200105749896", - "expectedWait": 64.2198594443, - "gasprice": 5.4 - }, - { - "expectedTime": "879.10469542971335712248", - "expectedWait": 63.3741627006, - "gasprice": 5.5 - }, - { - "expectedTime": "876.99737395823100420974", - "expectedWait": 63.2222470818, - "gasprice": 5.6 - }, - { - "expectedTime": "865.96781957003849098957", - "expectedWait": 62.4271327138, - "gasprice": 5.7 - }, - { - "expectedTime": "865.44839472121496158482", - "expectedWait": 62.3896876688, - "gasprice": 5.8 - }, - { - "expectedTime": "802.16173170976255602161", - "expectedWait": 57.8273877524, - "gasprice": 6 - }, - { - "expectedTime": "780.79313908053047074843", - "expectedWait": 56.2869379368, - "gasprice": 6.1 - }, - { - "expectedTime": "770.04888359616469549233", - "expectedWait": 55.5123906062, - "gasprice": 6.2 - }, - { - "expectedTime": "745.01007965146736962697", - "expectedWait": 53.7073573226, - "gasprice": 6.3 - }, - { - "expectedTime": "735.19921111598501681816", - "expectedWait": 53.0000973318, - "gasprice": 6.6 - }, - { - "expectedTime": "705.68767153912619368694", - "expectedWait": 50.8726270539, - "gasprice": 6.7 - }, - { - "expectedTime": "705.26438593445239690121", - "expectedWait": 50.8421126329, - "gasprice": 6.9 - }, - { - "expectedTime": "652.51573119854865429742", - "expectedWait": 47.0394918019, - "gasprice": 7 - }, - { - "expectedTime": "635.51471669299464383162", - "expectedWait": 45.813898235, - "gasprice": 7.1 - }, - { - "expectedTime": "634.37181911960854759036", - "expectedWait": 45.7315073922, - "gasprice": 7.2 - }, - { - "expectedTime": "633.23097691113902888918", - "expectedWait": 45.6492647195, - "gasprice": 7.3 - }, - { - "expectedTime": "112.7753456245379663928", - "expectedWait": 8.1299111919, - "gasprice": 7.6 - }, - { - "expectedTime": "102.9665314468898381829", - "expectedWait": 7.4227992986, - "gasprice": 8 - }, - { - "expectedTime": "100.94784507024919649891", - "expectedWait": 7.2772733339, - "gasprice": 8.1 - }, - { - "expectedTime": "100.46445647447807351078", - "expectedWait": 7.2424261221, - "gasprice": 8.8 - }, - { - "expectedTime": "84.91686745986737853339", - "expectedWait": 6.1216091808, - "gasprice": 9 - }, - { - "expectedTime": "80.39566429296684383503", - "expectedWait": 5.7956781892, - "gasprice": 9.1 - }, - { - "expectedTime": "78.24522052614759252715", - "expectedWait": 5.6406539084, - "gasprice": 9.2 - }, - { - "expectedTime": "77.1685119880459882636", - "expectedWait": 5.5630345959, - "gasprice": 9.5 - }, - { - "expectedTime": "72.43649507646737870178", - "expectedWait": 5.2219061601, - "gasprice": 9.8 - }, - { - "expectedTime": "71.48259532351443753818", - "expectedWait": 5.1531400638, - "gasprice": 9.9 - }, - { - "expectedTime": "58.23892805162994573827", - "expectedWait": 4.1984115442, - "gasprice": 10 - }, - { - "expectedTime": "53.13065124862245917617", - "expectedWait": 3.8301587446, - "gasprice": 10.1 - }, - { - "expectedTime": "53.03510209647058751971", - "expectedWait": 3.82327066, - "gasprice": 10.3 - }, - { - "expectedTime": "49.06846157804491912403", - "expectedWait": 3.5373177776, - "gasprice": 11 - }, - { - "expectedTime": "48.30893330101818116637", - "expectedWait": 3.4825638116, - "gasprice": 11.1 - }, - { - "expectedTime": "48.25099734861818116715", - "expectedWait": 3.4783872414, - "gasprice": 11.3 - }, - { - "expectedTime": "47.64416885027272662988", - "expectedWait": 3.4346413165, - "gasprice": 11.9 - }, - { - "expectedTime": "46.76354741392085498401", - "expectedWait": 3.3711578128, - "gasprice": 12.6 - }, - { - "expectedTime": "44.99427448545882292232", - "expectedWait": 3.2436119232, - "gasprice": 13 - }, - { - "expectedTime": "44.61790554199251276697", - "expectedWait": 3.2164796979, - "gasprice": 13.1 - }, - { - "expectedTime": "42.87832690973048070488", - "expectedWait": 3.0910744534, - "gasprice": 14 - }, - { - "expectedTime": "42.21224091308663044649", - "expectedWait": 3.0430566888, - "gasprice": 14.9 - }, - { - "expectedTime": "41.15715335111336842864", - "expectedWait": 2.9669960203, - "gasprice": 15 - }, - { - "expectedTime": "40.9600723880876999821", - "expectedWait": 2.9527885646, - "gasprice": 15.1 - }, - { - "expectedTime": "38.89138450301711177472", - "expectedWait": 2.8036580193, - "gasprice": 15.8 - }, - { - "expectedTime": "37.89655640860213852611", - "expectedWait": 2.7319414219, - "gasprice": 16 - }, - { - "expectedTime": "37.35265517364705831954", - "expectedWait": 2.692731888, - "gasprice": 17.4 - }, - { - "expectedTime": "36.79447683873796741798", - "expectedWait": 2.652493126, - "gasprice": 17.8 - }, - { - "expectedTime": "36.11439350850802090309", - "expectedWait": 2.6034663015, - "gasprice": 19 - }, - { - "expectedTime": "31.32676199432192471101", - "expectedWait": 2.2583286403, - "gasprice": 20 - }, - { - "expectedTime": "30.76792490132192471855", - "expectedWait": 2.2180423888, - "gasprice": 20.1 - }, - { - "expectedTime": "29.94493658520962526441", - "expectedWait": 2.1587136243, - "gasprice": 25 - }, - { - "expectedTime": "29.53287347625561457478", - "expectedWait": 2.1290082267, - "gasprice": 29 - }, - { - "expectedTime": "29.09318627175614934008", - "expectedWait": 2.0973114236, - "gasprice": 47 - } - ], - "priceAndTimeEstimatesLastRetrieved": 1541527901281, - "errors": {} - }, - "confirmTransaction": {}, - "unconnectedAccount": { - "state": "CLOSED" - } -} diff --git a/development/static-server.js b/development/static-server.js index e07c2e33f..fff4103c4 100644 --- a/development/static-server.js +++ b/development/static-server.js @@ -1,10 +1,10 @@ const fs = require('fs') -const http = require('http') const path = require('path') const chalk = require('chalk') const pify = require('pify') -const serveHandler = require('serve-handler') + +const createStaticServer = require('./create-static-server') const fsStat = pify(fs.stat) const DEFAULT_PORT = 9080 @@ -24,19 +24,7 @@ const onRequest = (request, response) => { } const startServer = ({ port, rootDirectory }) => { - const server = http.createServer((request, response) => { - if (request.url.startsWith('/node_modules/')) { - request.url = request.url.substr(14) - return serveHandler(request, response, { - directoryListing: false, - public: path.resolve('./node_modules'), - }) - } - return serveHandler(request, response, { - directoryListing: false, - public: rootDirectory, - }) - }) + const server = createStaticServer(rootDirectory) server.on('request', onRequest) diff --git a/development/test.html b/development/test.html deleted file mode 100644 index 49084c0a4..000000000 --- a/development/test.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - MetaMask - - - - - - -
- - - - - - diff --git a/package.json b/package.json index 6a8b3e466..d1fe481d6 100644 --- a/package.json +++ b/package.json @@ -15,15 +15,12 @@ "dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'", "forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010", "dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'", - "watch:test:unit": "nodemon --exec \"yarn test:unit\" ./test ./app ./ui", "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"", "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive mocha test/unit-global/*", "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.js\" \"ui/app/**/*.test.js\"", "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.js\"", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", - "test:integration": "yarn test:integration:build && yarn test:flat", - "test:integration:build": "yarn build styles", "test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh", "test:web3:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-web3.sh", "test:web3:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-web3.sh", @@ -31,19 +28,14 @@ "test:coverage": "nyc --silent --check-coverage yarn test:unit:strict && nyc --silent --no-clean yarn test:unit:lax && nyc report --reporter=text --reporter=html", "test:coverage:strict": "nyc --check-coverage yarn test:unit:strict", "test:coveralls-upload": "if [ \"$COVERALLS_REPO_TOKEN\" ]; then nyc report --reporter=text-lcov | coveralls; fi", - "test:flat": "yarn test:flat:build && karma start test/flat.conf.js", - "test:flat:build": "yarn test:flat:build:ui && yarn test:flat:build:tests && yarn 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": "mkdir -p dist/chrome && cp -R app/_locales dist/chrome/_locales", - "test:flat:build:ui": "yarn test:flat:build:states && browserify --transform babelify --transform brfs ./development/mock-dev.js -o ./development/bundle.js", "ganache:start": "./development/run-ganache", "sentry:publish": "node ./development/sentry-publish.js", - "lint": "eslint . --ext js,json", + "lint": "eslint . --ext js,json && yarn lint:styles", "lint:fix": "eslint . --ext js,json --fix", "lint:changed": "{ git ls-files --others --exclude-standard ; git diff-index --name-only --diff-filter=d HEAD ; } | grep --regexp='[.]js$' --regexp='[.]json$' | tr '\\n' '\\0' | xargs -0 eslint", "lint:changed:fix": "{ git ls-files --others --exclude-standard ; git diff-index --name-only --diff-filter=d HEAD ; } | grep --regexp='[.]js$' --regexp='[.]json$' | tr '\\n' '\\0' | xargs -0 eslint --fix", "lint:shellcheck": "./development/shellcheck.sh", + "lint:styles": "stylelint '*/**/*.scss'", "lint:lockfile": "lockfile-lint --path yarn.lock --allowed-hosts npm yarn github.com codeload.github.com --empty-hostname false --allowed-schemes \"https:\" \"git+https:\"", "verify-locales": "node ./development/verify-locale-strings.js", "verify-locales:fix": "node ./development/verify-locale-strings.js --fix", @@ -60,12 +52,11 @@ "generate:migration": "./development/generate-migration.sh" }, "resolutions": { - "**/gonzales-pe/minimist": "^1.2.5", "**/knex/minimist": "^1.2.5", - "**/mkdirp/minimist": "^1.2.5", "**/optimist/minimist": "^1.2.5", "**/socketcluster/minimist": "^1.2.5", - "3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.15" + "3box/ipfs/ipld-zcash/zcash-bitcore-lib/lodash": "^4.17.19", + "ganache-core/lodash": "^4.17.19" }, "dependencies": { "3box": "^1.10.2", @@ -73,19 +64,19 @@ "@download/blockies": "^1.0.3", "@formatjs/intl-relativetimeformat": "^5.2.6", "@fortawesome/fontawesome-free": "^5.13.0", - "@material-ui/core": "1.0.0", + "@material-ui/core": "^4.11.0", "@metamask/controllers": "^2.0.1", "@metamask/eth-ledger-bridge-keyring": "^0.2.6", "@metamask/eth-token-tracker": "^2.0.0", "@metamask/etherscan-link": "^1.1.0", - "@metamask/inpage-provider": "^6.0.0", + "@metamask/inpage-provider": "^6.0.1", "@popperjs/core": "^2.4.0", "@reduxjs/toolkit": "^1.3.2", "@sentry/browser": "^5.11.1", "@sentry/integrations": "^5.11.1", "@zxing/library": "^0.8.0", "abi-decoder": "^1.2.0", - "abortcontroller-polyfill": "^1.3.0", + "abortcontroller-polyfill": "^1.4.0", "await-semaphore": "^0.1.1", "bignumber.js": "^4.1.0", "bip39": "^2.2.0", @@ -131,7 +122,7 @@ "json-rpc-engine": "^5.1.8", "json-rpc-middleware-stream": "^2.1.1", "jsonschema": "^1.2.4", - "lodash": "^4.17.15", + "lodash": "^4.17.19", "loglevel": "^1.4.1", "luxon": "^1.23.0", "metamask-logo": "^2.1.4", @@ -148,7 +139,6 @@ "pump": "^3.0.0", "punycode": "^2.1.1", "qrcode-generator": "1.4.1", - "ramda": "^0.24.1", "react": "^16.12.0", "react-dnd": "^3.0.2", "react-dnd-html5-backend": "^7.4.4", @@ -163,7 +153,6 @@ "react-tippy": "^1.2.2", "react-toggle-button": "^2.2.0", "react-transition-group": "^1.2.1", - "react-trigger-change": "^1.0.2", "readable-stream": "^2.3.3", "redux": "^4.0.5", "redux-thunk": "^2.3.0", @@ -190,7 +179,7 @@ "@babel/register": "^7.5.5", "@metamask/eslint-config": "^1.1.0", "@metamask/forwarder": "^1.1.0", - "@metamask/test-dapp": "3.0.0", + "@metamask/test-dapp": "^3.1.0", "@sentry/cli": "^1.49.0", "@storybook/addon-actions": "^5.3.14", "@storybook/addon-backgrounds": "^5.3.14", @@ -200,7 +189,7 @@ "@storybook/storybook-deployer": "^2.8.6", "@testing-library/react-hooks": "^3.2.1", "addons-linter": "1.14.0", - "babel-eslint": "^10.0.2", + "babel-eslint": "^10.1.0", "babel-loader": "^8.0.6", "babelify": "^10.0.0", "brfs": "^1.6.1", @@ -219,11 +208,11 @@ "envify": "^4.1.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", - "eslint": "^6.0.1", + "eslint": "^6.8.0", "eslint-plugin-babel": "^5.3.0", - "eslint-plugin-import": "^2.19.1", + "eslint-plugin-import": "^2.22.0", "eslint-plugin-json": "^1.2.0", - "eslint-plugin-mocha": "^6.2.2", + "eslint-plugin-mocha": "^6.3.0", "eslint-plugin-react": "^7.18.3", "eslint-plugin-react-hooks": "^4.0.4", "fancy-log": "^1.3.3", @@ -246,16 +235,11 @@ "gulp-rtlcss": "^1.4.0", "gulp-sass": "^4.0.0", "gulp-sourcemaps": "^2.6.0", - "gulp-stylelint": "^7.0.0", + "gulp-stylelint": "^13.0.0", "gulp-terser-js": "^5.0.0", "gulp-watch": "^5.0.1", "gulp-zip": "^4.0.0", "jsdom": "^11.2.0", - "karma": "^4.1.0", - "karma-chrome-launcher": "^2.2.0", - "karma-cli": "^1.0.1", - "karma-firefox-launcher": "^1.0.1", - "karma-qunit": "^1.2.1", "koa": "^2.7.0", "lockfile-lint": "^4.0.0", "mocha": "^7.2.0", @@ -265,8 +249,6 @@ "nyc": "^15.0.0", "polyfill-crypto.getrandomvalues": "^1.0.0", "proxyquire": "^2.1.3", - "qs": "^6.2.0", - "qunitjs": "^2.4.1", "randomcolor": "^0.5.4", "rc": "^1.2.8", "react-devtools": "^4.4.0", @@ -287,9 +269,7 @@ "source-map-explorer": "^2.0.1", "string.prototype.matchall": "^4.0.2", "style-loader": "^0.21.0", - "stylelint": "^9.10.1", - "stylelint-config-standard": "^18.2.0", - "testem": "^2.16.0", + "stylelint": "^13.6.1", "through2": "^2.0.3", "ttest": "^2.1.1", "vinyl-buffer": "^1.0.1", diff --git a/stylelint.config.js b/stylelint.config.js new file mode 100644 index 000000000..3582b90ef --- /dev/null +++ b/stylelint.config.js @@ -0,0 +1,122 @@ +module.exports = { + rules: { + // stylelint-config-standard + + 'at-rule-empty-line-before': [ + 'always', + { + except: ['blockless-after-same-name-blockless', 'first-nested'], + ignore: ['after-comment'], + }, + ], + 'at-rule-name-case': 'lower', + 'at-rule-name-space-after': 'always-single-line', + 'at-rule-semicolon-newline-after': 'always', + 'block-closing-brace-empty-line-before': 'never', + 'block-closing-brace-newline-after': 'always', + 'block-closing-brace-newline-before': 'always-multi-line', + 'block-closing-brace-space-before': 'always-single-line', + 'block-opening-brace-newline-after': 'always-multi-line', + 'block-opening-brace-space-after': 'always-single-line', + 'block-opening-brace-space-before': 'always', + 'color-hex-case': 'lower', + 'color-hex-length': 'short', + 'comment-empty-line-before': [ + 'always', + { + except: ['first-nested'], + ignore: ['stylelint-commands'], + }, + ], + // 'comment-whitespace-inside': 'always', + 'custom-property-empty-line-before': [ + 'always', + { + except: ['after-custom-property', 'first-nested'], + ignore: ['after-comment', 'inside-single-line-block'], + }, + ], + 'declaration-bang-space-after': 'never', + 'declaration-bang-space-before': 'always', + 'declaration-block-semicolon-newline-after': 'always-multi-line', + 'declaration-block-semicolon-space-after': 'always-single-line', + 'declaration-block-semicolon-space-before': 'never', + 'declaration-block-single-line-max-declarations': 1, + 'declaration-block-trailing-semicolon': 'always', + 'declaration-colon-newline-after': 'always-multi-line', + 'declaration-colon-space-after': 'always-single-line', + 'declaration-colon-space-before': 'never', + 'declaration-empty-line-before': [ + 'always', + { + except: ['after-declaration', 'first-nested'], + ignore: ['after-comment', 'inside-single-line-block'], + }, + ], + 'function-comma-newline-after': 'always-multi-line', + 'function-comma-space-after': 'always-single-line', + 'function-comma-space-before': 'never', + 'function-max-empty-lines': 0, + 'function-name-case': 'lower', + 'function-parentheses-newline-inside': 'always-multi-line', + 'function-parentheses-space-inside': 'never-single-line', + 'function-whitespace-after': 'always', + indentation: 2, + 'length-zero-no-unit': true, + // 'max-empty-lines': 1, + 'media-feature-colon-space-after': 'always', + 'media-feature-colon-space-before': 'never', + 'media-feature-name-case': 'lower', + 'media-feature-parentheses-space-inside': 'never', + 'media-feature-range-operator-space-after': 'always', + 'media-feature-range-operator-space-before': 'always', + 'media-query-list-comma-newline-after': 'always-multi-line', + 'media-query-list-comma-space-after': 'always-single-line', + 'media-query-list-comma-space-before': 'never', + 'no-eol-whitespace': true, + 'no-missing-end-of-source-newline': true, + 'number-leading-zero': 'always', + 'number-no-trailing-zeros': true, + 'property-case': 'lower', + 'rule-empty-line-before': [ + 'always-multi-line', + { + except: ['first-nested'], + ignore: ['after-comment'], + }, + ], + 'selector-attribute-brackets-space-inside': 'never', + 'selector-attribute-operator-space-after': 'never', + 'selector-attribute-operator-space-before': 'never', + 'selector-combinator-space-after': 'always', + 'selector-combinator-space-before': 'always', + 'selector-descendant-combinator-no-non-space': true, + 'selector-list-comma-newline-after': 'always', + 'selector-list-comma-space-before': 'never', + 'selector-max-empty-lines': 0, + 'selector-pseudo-class-case': 'lower', + 'selector-pseudo-class-parentheses-space-inside': 'never', + 'selector-pseudo-element-case': 'lower', + 'selector-pseudo-element-colon-notation': 'double', + 'selector-type-case': 'lower', + 'unit-case': 'lower', + // 'value-keyword-case': 'lower', + 'value-list-comma-newline-after': 'always-multi-line', + 'value-list-comma-space-after': 'always-single-line', + 'value-list-comma-space-before': 'never', + 'value-list-max-empty-lines': 0, + + // custom rules + + // 'color-named': 'never', + // 'font-family-name-quotes': 'always-where-recommended', + // 'font-weight-notation': 'numeric', + // 'function-url-quotes': 'always', + 'value-no-vendor-prefix': true, + 'value-list-comma-newline-before': 'never-multi-line', + // 'selector-attribute-quotes': 'always', + // 'selector-max-specificity': '0,5,2', + // 'max-nesting-depth': 3, + 'no-unknown-animations': true, + }, +} diff --git a/test/base.conf.js b/test/base.conf.js deleted file mode 100644 index ccb91cc65..000000000 --- a/test/base.conf.js +++ /dev/null @@ -1,68 +0,0 @@ -// Karma configuration -// Generated on Mon Sep 11 2017 18:45:48 GMT-0700 (PDT) - -module.exports = function (config) { - return { - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: process.cwd(), - - // Uncomment to allow for longer timeouts - // browserNoActivityTimeout: 100000000, - - browserConsoleLogOptions: { - terminal: false, - }, - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['qunit'], - - // list of files / patterns to load in the browser - files: [ - '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 - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress'], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: process.env.browsers ? - JSON.parse(process.env.browsers) - : ['Chrome', 'Firefox'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - nocache: true, - } -} diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index 04ea4a14c..f9fc7d5be 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -43,7 +43,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index 19bcb9e5d..e7412ac68 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -42,7 +42,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/fixtures/localization/state.json b/test/e2e/fixtures/localization/state.json new file mode 100644 index 000000000..74325c8c4 --- /dev/null +++ b/test/e2e/fixtures/localization/state.json @@ -0,0 +1,125 @@ +{ + "data": { + "AppStateController": { + "mkrMigrationReminderTimestamp": null + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {} + } + }, + "CurrencyController": { + "conversionDate": 1594323667.203, + "conversionRate": 14205.88, + "currentCurrency": "php", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "network": "5777", + "provider": { + "nickname": "", + "rpcTarget": "", + "ticker": "ETH", + "type": "localhost" + }, + "settings": { + "ticker": "ETH" + } + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "domainMetadata": { + "metamask.github.io": { + "icon": null, + "name": "M E T A M A S K M E S H T E S T" + } + }, + "permissionsHistory": {}, + "permissionsLog": [ + { + "id": 746677923, + "method": "eth_accounts", + "methodType": "restricted", + "origin": "metamask.github.io", + "request": { + "id": 746677923, + "jsonrpc": "2.0", + "method": "eth_accounts", + "origin": "metamask.github.io", + "params": [] + }, + "requestTime": 1575697241368, + "response": { + "id": 746677923, + "jsonrpc": "2.0", + "result": [] + }, + "responseTime": 1575697241370, + "success": true + } + ] + }, + "PreferencesController": { + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "completedOnboarding": true, + "currentLocale": "en", + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "firstTimeFlowType": "create", + "forgottenPassword": false, + "frequentRpcListDetail": [], + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "knownMethodData": {}, + "lostIdentities": {}, + "metaMetricsId": null, + "metaMetricsSendCount": 0, + "participateInMetaMetrics": false, + "preferences": { + "showFiatInTestnets": true, + "useNativeCurrencyAsPrimaryCurrency": true + }, + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "suggestedTokens": {}, + "tokens": [], + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + } + }, + "meta": { + "version": 40 + } +} diff --git a/test/e2e/fixtures/personal-sign/state.json b/test/e2e/fixtures/personal-sign/state.json new file mode 100644 index 000000000..b3dbe5ed6 --- /dev/null +++ b/test/e2e/fixtures/personal-sign/state.json @@ -0,0 +1,175 @@ +{ + "data": { + "AppStateController": { + "connectedStatusPopoverHasBeenShown": false + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {}, + "5777": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": "0x15af1d78b58c40000" + } + } + }, + "CurrencyController": { + "conversionDate": 1594348502.519, + "conversionRate": 240.09, + "currentCurrency": "usd", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536, + "localhost": 98 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "provider": { + "nickname": "", + "rpcTarget": "", + "ticker": "ETH", + "type": "localhost" + }, + "network": "5777", + "settings": { + "ticker": "ETH" + } + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "permissionsLog": [ + { + "id": 1764280960, + "method": "eth_requestAccounts", + "methodType": "restricted", + "origin": "http://127.0.0.1:8080", + "request": { + "method": "eth_requestAccounts", + "jsonrpc": "2.0", + "id": 1764280960, + "origin": "http://127.0.0.1:8080", + "tabId": 2 + }, + "requestTime": 1594348329232, + "response": { + "id": 1764280960, + "jsonrpc": "2.0", + "result": [ + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1" + ] + }, + "responseTime": 1594348332276, + "success": true + } + ], + "permissionsHistory": { + "http://127.0.0.1:8080": { + "eth_accounts": { + "accounts": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": 1594348332276 + }, + "lastApproved": 1594348332276 + } + } + }, + "domainMetadata": { + "http://127.0.0.1:8080": { + "name": "E2E Test Dapp", + "icon": "http://127.0.0.1:8080/metamask-fox.svg", + "lastUpdated": 1594348323811, + "host": "127.0.0.1:8080" + } + } + }, + "PreferencesController": { + "frequentRpcListDetail": [], + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "tokens": [], + "suggestedTokens": {}, + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true, + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "knownMethodData": {}, + "participateInMetaMetrics": false, + "firstTimeFlowType": "create", + "currentLocale": "en", + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "lostIdentities": {}, + "forgottenPassword": false, + "preferences": { + "useNativeCurrencyAsPrimaryCurrency": true + }, + "completedOnboarding": true, + "metaMetricsId": null, + "metaMetricsSendCount": 0, + "ipfsGateway": "dweb.link", + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1" + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + }, + "PermissionsController": { + "permissionsRequests": [], + "permissionsDescriptions": {}, + "domains": { + "http://127.0.0.1:8080": { + "permissions": [ + { + "@context": [ + "https://github.com/MetaMask/rpc-cap" + ], + "parentCapability": "eth_accounts", + "id": "f55a1c15-ea48-4088-968e-63be474d42fa", + "date": 1594348332268, + "invoker": "http://127.0.0.1:8080", + "caveats": [ + { + "type": "limitResponseLength", + "value": 1, + "name": "primaryAccountOnly" + }, + { + "type": "filterResponse", + "value": [ + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1" + ], + "name": "exposedAccounts" + } + ] + } + ] + } + } + } + }, + "meta": { + "version": 47 + } +} diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js index cb8da4a45..7a112c722 100644 --- a/test/e2e/from-import-ui.spec.js +++ b/test/e2e/from-import-ui.spec.js @@ -46,7 +46,7 @@ describe('Using MetaMask with an existing account', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 2d4e030ca..f7954ffd7 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -2,33 +2,68 @@ const path = require('path') const Ganache = require('./ganache') const FixtureServer = require('./fixture-server') const { buildWebDriver } = require('./webdriver') +const createStaticServer = require('../../development/create-static-server') const tinyDelayMs = 200 const regularDelayMs = tinyDelayMs * 2 const largeDelayMs = regularDelayMs * 2 +const dappPort = 8080 + async function withFixtures (options, callback) { - const { fixtures, ganacheOptions, driverOptions } = options + const { dapp, fixtures, ganacheOptions, driverOptions, title } = options const fixtureServer = new FixtureServer() const ganacheServer = new Ganache() + let dappServer let webDriver try { await ganacheServer.start(ganacheOptions) await fixtureServer.start() await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures)) + if (dapp) { + const dappDirectory = path.resolve(__dirname, '..', '..', 'node_modules', '@metamask', 'test-dapp', 'dist') + dappServer = createStaticServer(dappDirectory) + dappServer.listen(dappPort) + await new Promise((resolve, reject) => { + dappServer.on('listening', resolve) + dappServer.on('error', reject) + }) + } const { driver } = await buildWebDriver(driverOptions) webDriver = driver await callback({ driver, }) + + if (process.env.SELENIUM_BROWSER === 'chrome') { + const errors = await driver.checkBrowserForConsoleErrors(driver) + if (errors.length) { + const errorReports = errors.map((err) => err.message) + const errorMessage = `Errors found in browser console:\n${errorReports.join('\n')}` + throw new Error(errorMessage) + } + } + } catch (error) { + await webDriver.verboseReportOnFailure(title) + throw error } finally { await fixtureServer.stop() await ganacheServer.quit() if (webDriver) { await webDriver.quit() } + if (dappServer) { + await new Promise((resolve, reject) => { + dappServer.close((error) => { + if (error) { + return reject(error) + } + return resolve() + }) + }) + } } } diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js index 7a3848925..82e3fc0e0 100644 --- a/test/e2e/incremental-security.spec.js +++ b/test/e2e/incremental-security.spec.js @@ -47,7 +47,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/metamask-responsive-ui.spec.js b/test/e2e/metamask-responsive-ui.spec.js index 7e98e4227..0b7e8b4d4 100644 --- a/test/e2e/metamask-responsive-ui.spec.js +++ b/test/e2e/metamask-responsive-ui.spec.js @@ -37,7 +37,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) @@ -166,7 +166,7 @@ describe('MetaMask', function () { }) it('balance renders', async function () { - const balance = await driver.findElement(By.css('.eth-overview__primary-balance')) + const balance = await driver.findElement(By.css('[data-testid="eth-overview__primary-currency"]')) await driver.wait(until.elementTextMatches(balance, /100\s*ETH/)) await driver.delay(regularDelayMs) }) diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 2e230e731..9e8b90cb2 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -38,7 +38,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) @@ -750,7 +750,7 @@ describe('MetaMask', function () { }) it('renders the correct ETH balance', async function () { - const balance = await driver.findElement(By.css('.eth-overview__primary-balance')) + const balance = await driver.findElement(By.css('[data-testid="eth-overview__primary-currency"]')) await driver.delay(regularDelayMs) await driver.wait(until.elementTextMatches(balance, /^87.*\s*ETH.*$/), 10000) const tokenAmount = await balance.getText() diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 4785b4fe8..8ec86b3cb 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -42,7 +42,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index 48ee97cb0..c3e60f1c2 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -44,7 +44,7 @@ describe('Using MetaMask with an existing account', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index 76c0ec6a4..8c80116ec 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -41,7 +41,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) @@ -92,7 +92,7 @@ describe('MetaMask', function () { }) it('creates a sign typed data signature request', async function () { - await driver.clickElement(By.xpath(`//button[contains(text(), 'Sign')]`), 10000) + await driver.clickElement(By.id('signTypedData'), 10000) await driver.delay(largeDelayMs) await driver.delay(regularDelayMs) diff --git a/test/e2e/tests/localization.spec.js b/test/e2e/tests/localization.spec.js new file mode 100644 index 000000000..e3d4520ca --- /dev/null +++ b/test/e2e/tests/localization.spec.js @@ -0,0 +1,29 @@ +const { strict: assert } = require('assert') +const { By, Key } = require('selenium-webdriver') +const { withFixtures } = require('../helpers') + +describe('Localization', function () { + it('can correctly display Philippine peso symbol and code', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: 25000000000000000000, + }, + ], + } + await withFixtures( + { fixtures: 'localization', ganacheOptions, title: this.test.title }, + async ({ driver }) => { + const passwordField = await driver.findElement(By.css('#password')) + await passwordField.sendKeys('correct horse battery staple') + await passwordField.sendKeys(Key.ENTER) + const secondaryBalance = await driver.findElement(By.css('[data-testid="eth-overview__secondary-currency"]')) + const secondaryBalanceText = await secondaryBalance.getText() + const [fiatAmount, fiatUnit] = secondaryBalanceText.trim().split(/\s+/) + assert.ok(fiatAmount.startsWith('₱')) + assert.equal(fiatUnit, 'PHP') + }, + ) + }) +}) diff --git a/test/e2e/tests/personal-sign.spec.js b/test/e2e/tests/personal-sign.spec.js new file mode 100644 index 000000000..9cc2d4fc3 --- /dev/null +++ b/test/e2e/tests/personal-sign.spec.js @@ -0,0 +1,40 @@ +const { strict: assert } = require('assert') +const { By, Key } = require('selenium-webdriver') +const { withFixtures } = require('../helpers') + +describe('Personal sign', function () { + it('can initiate and confirm a personal sign', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: 25000000000000000000, + }, + ], + } + await withFixtures( + { dapp: true, fixtures: 'personal-sign', ganacheOptions, title: this.test.title }, + async ({ driver }) => { + const passwordField = await driver.findElement(By.css('#password')) + await passwordField.sendKeys('correct horse battery staple') + await passwordField.sendKeys(Key.ENTER) + + await driver.openNewPage('http://127.0.0.1:8080/') + await driver.clickElement(By.id('personalSign')) + + await driver.waitUntilXWindowHandles(3) + + const windowHandles = await driver.getAllWindowHandles() + await driver.switchToWindowWithTitle('MetaMask Notification', windowHandles) + + const personalMessageRow = await driver.findElement(By.css('.request-signature__row-value')) + const personalMessage = await personalMessageRow.getText() + assert.equal(personalMessage, 'Example `personal_sign` message') + + await driver.clickElement(By.css('[data-testid="request-signature__sign"]')) + + await driver.waitUntilXWindowHandles(2) + }, + ) + }) +}) diff --git a/test/e2e/tests/simple-send.spec.js b/test/e2e/tests/simple-send.spec.js index 0b48916a7..3328b110c 100644 --- a/test/e2e/tests/simple-send.spec.js +++ b/test/e2e/tests/simple-send.spec.js @@ -1,7 +1,7 @@ const { By, Key } = require('selenium-webdriver') const { withFixtures } = require('../helpers') -describe('MetaMask Browser Extension', function () { +describe('Simple send', function () { it('can send a simple transaction from one account to another', async function () { const ganacheOptions = { accounts: [ @@ -11,19 +11,22 @@ describe('MetaMask Browser Extension', function () { }, ], } - await withFixtures({ fixtures: 'imported-account', ganacheOptions }, async ({ driver }) => { - const passwordField = await driver.findElement(By.css('#password')) - await passwordField.sendKeys('correct horse battery staple') - await passwordField.sendKeys(Key.ENTER) - await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) - const recipientAddressField = await driver.findElement(By.css('[data-testid="ens-input"]')) - await recipientAddressField.sendKeys('0x985c30949c92df7a0bd42e0f3e3d539ece98db24') - const amountField = await driver.findElement(By.css('.unit-input__input')) - await amountField.sendKeys('1') - await driver.clickElement(By.css('[data-testid="page-container-footer-next"]')) - await driver.clickElement(By.css('[data-testid="page-container-footer-next"]')) - await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) - await driver.findElement(By.css('.transaction-list-item')) - }) + await withFixtures( + { fixtures: 'imported-account', ganacheOptions, title: this.test.title }, + async ({ driver }) => { + const passwordField = await driver.findElement(By.css('#password')) + await passwordField.sendKeys('correct horse battery staple') + await passwordField.sendKeys(Key.ENTER) + await driver.clickElement(By.css('[data-testid="eth-overview-send"]')) + const recipientAddressField = await driver.findElement(By.css('[data-testid="ens-input"]')) + await recipientAddressField.sendKeys('0x985c30949c92df7a0bd42e0f3e3d539ece98db24') + const amountField = await driver.findElement(By.css('.unit-input__input')) + await amountField.sendKeys('1') + await driver.clickElement(By.css('[data-testid="page-container-footer-next"]')) + await driver.clickElement(By.css('[data-testid="page-container-footer-next"]')) + await driver.clickElement(By.css('[data-testid="home__activity-tab"]')) + await driver.findElement(By.css('.transaction-list-item')) + }, + ) }) }) diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 46669f1df..e7affbfeb 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -45,7 +45,7 @@ describe('MetaMask', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/web3.spec.js b/test/e2e/web3.spec.js index 7c2c4c5e5..4bcca74dd 100644 --- a/test/e2e/web3.spec.js +++ b/test/e2e/web3.spec.js @@ -44,7 +44,7 @@ describe('Using MetaMask with an existing account', function () { } } if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest) + await driver.verboseReportOnFailure(this.currentTest.title) } }) diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index c5cd917d4..daf3a1acc 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -61,7 +61,7 @@ class Driver { this.driver.wait(until.elementIsEnabled(element), this.timeout), ) return acc - }, []) + }, []), ) return elements } @@ -172,8 +172,8 @@ class Driver { // Error handling - async verboseReportOnFailure (test) { - const artifactDir = `./test-artifacts/${this.browser}/${test.title}` + async verboseReportOnFailure (title) { + const artifactDir = `./test-artifacts/${this.browser}/${title}` const filepathBase = `${artifactDir}/test-failure` await fs.mkdir(artifactDir, { recursive: true }) const screenshot = await this.driver.takeScreenshot() diff --git a/test/flat.conf.js b/test/flat.conf.js deleted file mode 100644 index 1c9ec3dcd..000000000 --- a/test/flat.conf.js +++ /dev/null @@ -1,8 +0,0 @@ -const getBaseConfig = require('./base.conf.js') - -module.exports = function (config) { - const settings = getBaseConfig(config) - settings.files.push('development/bundle.js') - settings.files.push('test/integration/bundle.js') - config.set(settings) -} diff --git a/test/integration/index.html b/test/integration/index.html deleted file mode 100644 index 430814a8a..000000000 --- a/test/integration/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - QUnit Example - - - -
-
- - - - - - - - - diff --git a/test/integration/index.js b/test/integration/index.js deleted file mode 100644 index d5dea6f9c..000000000 --- a/test/integration/index.js +++ /dev/null @@ -1,29 +0,0 @@ -const fs = require('fs') -const path = require('path') -const pump = require('pump') -const browserify = require('browserify') - -const tests = fs.readdirSync(path.join(__dirname, 'lib')) -const bundlePath = path.join(__dirname, 'bundle.js') - -const b = browserify() - -const writeStream = fs.createWriteStream(bundlePath) - -tests.forEach(function (fileName) { - const filePath = path.join(__dirname, 'lib', fileName) - console.log(`bundling test "${filePath}"`) - b.add(filePath) -}) - -pump( - b.bundle(), - writeStream, - (err) => { - if (err) { - throw err - } - console.log(`Integration test build completed: "${bundlePath}"`) - process.exit(0) - } -) diff --git a/test/integration/jquery-3.1.0.min.js b/test/integration/jquery-3.1.0.min.js deleted file mode 100644 index f6a6a99e6..000000000 --- a/test/integration/jquery-3.1.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0, -r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K); -if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("