From 7bbd48a2bde8fe93f01bb833bcd5fdec8bcb048c Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 13 Jun 2017 11:02:38 +0200 Subject: [PATCH] Merge branch 'master' into ui-2 # Conflicts: # js/package.json # js/src/api/local/ethkey/worker.js # js/src/modals/FirstRun/TnC/tnc.js # js/src/modals/FirstRun/Welcome/welcome.js # js/src/ui/Form/Input/input.js # js/src/ui/VaultCard/Accounts/accounts.spec.js # js/src/views/Accounts/accounts.js # js/src/views/Application/TabBar/tabBar.js # js/src/views/Settings/Views/defaults.js # js/src/views/Settings/Views/views.js # js/webpack/app.js # js/webpack/libraries.js --- .gitlab-ci.yml | 14 +- CHANGELOG.md | 38 +++ Cargo.lock | 80 +++-- Cargo.toml | 5 +- README.md | 2 +- ethcore/src/engines/authority_round.rs | 5 +- ethcore/src/engines/basic_authority.rs | 4 + ethcore/src/engines/mod.rs | 2 +- ethcore/src/ethereum/ethash.rs | 2 +- ethcore/src/evm/evm.rs | 2 +- ethcore/src/evm/ext.rs | 2 +- ethcore/src/evm/instructions.rs | 289 +++++++++--------- ethcore/src/evm/interpreter/memory.rs | 14 +- ethcore/src/evm/interpreter/mod.rs | 2 +- ethcore/src/evm/mod.rs | 1 + ethcore/src/executive.rs | 4 +- ethcore/src/externalities.rs | 4 +- ethcore/src/trace/executive_tracer.rs | 4 +- ethcore/src/trace/mod.rs | 4 +- ethcore/src/trace/noop_tracer.rs | 4 +- evmbin/src/display/json.rs | 46 ++- evmbin/src/display/mod.rs | 5 + evmbin/src/display/simple.rs | 2 +- evmbin/src/main.rs | 1 + evmbin/src/vm.rs | 6 + js/package.json | 10 +- js/src/api/api.js | 8 +- js/src/api/local/accounts/account.js | 17 +- js/src/api/local/accounts/accounts.js | 137 +++++++-- js/src/api/local/ethkey/ethkey.js | 147 +++++++++ js/src/api/local/ethkey/ethkey.wasm.js | 1 + js/src/api/local/ethkey/index.js | 7 +- js/src/api/local/ethkey/index.spec.js | 3 +- js/src/api/local/ethkey/worker.js | 58 ++-- js/src/api/local/ethkey/workerPool.js | 51 +++- js/src/api/local/localAccountsMiddleware.js | 73 ++++- .../api/local/localAccountsMiddleware.spec.js | 5 +- .../dapps/dappreg/Application/application.js | 2 +- .../dapps/dappreg/ModalDelete/modalDelete.js | 2 +- .../dappreg/ModalRegister/modalRegister.js | 2 +- js/src/i18n/_default/extension.js | 2 +- js/src/i18n/_default/settings.js | 4 +- js/src/i18n/_default/tabBar.js | 2 +- js/src/i18n/zh-Hant-TW/extension.js | 2 +- js/src/i18n/zh-Hant-TW/settings.js | 4 +- js/src/i18n/zh-Hant-TW/tabBar.js | 2 +- js/src/i18n/zh/extension.js | 2 +- js/src/i18n/zh/settings.js | 4 +- js/src/i18n/zh/tabBar.js | 2 +- js/src/lib.rs.in | 2 +- js/src/shared/config/dappsBuiltin.json | 6 +- js/src/shell/Dapps/dapps.js | 13 +- js/src/shell/Extension/extension.js | 2 +- js/src/shell/FirstRun/TnC/tnc.js | 132 ++++---- js/src/shell/FirstRun/Welcome/welcome.js | 2 +- js/src/shell/FirstRun/firstRun.js | 72 +++-- js/src/ui/Form/Input/input.js | 12 + js/src/ui/VaultCard/Accounts/accounts.spec.js | 27 ++ .../AccountDetails/accountDetails.js | 119 ++++++-- .../Accounts/CreateAccount/createAccount.css | 5 + .../Accounts/CreateAccount/createAccount.js | 78 ++++- js/src/views/Accounts/CreateAccount/errors.js | 15 + js/src/views/Accounts/CreateAccount/store.js | 49 ++- js/src/views/Accounts/accounts.js | 63 +++- js/src/views/Accounts/accounts.spec.js | 5 + js/src/views/Application/TabBar/tabBar.js | 133 ++++++++ js/src/views/Home/home.js | 32 +- js/src/views/Home/home.spec.js | 27 +- js/src/views/Settings/Views/defaults.js | 35 +++ js/src/views/Settings/Views/views.js | 59 +++- js/wasm/README.md | 3 + js/wasm/ethkey/.gitignore | 2 + js/wasm/ethkey/Cargo.toml | 17 ++ js/wasm/ethkey/base64ify.js | 5 + js/wasm/ethkey/build.sh | 16 + js/wasm/ethkey/ethkey.opt.wasm | Bin 0 -> 55961 bytes js/wasm/ethkey/ethkey.wasm | Bin 0 -> 67263 bytes js/wasm/ethkey/src/main.rs | 153 ++++++++++ js/webpack/app.js | 3 + js/webpack/libraries.js | 3 + json/src/spec/ethash.rs | 7 +- nsis/installer.nsi | 2 +- parity/configuration.rs | 4 +- parity/rpc.rs | 15 +- rpc/src/v1/extractors.rs | 10 +- rpc/src/v1/impls/eth_pubsub.rs | 4 +- rpc/src/v1/impls/parity.rs | 5 + rpc/src/v1/impls/pubsub.rs | 8 +- rpc/src/v1/impls/signer.rs | 2 +- rpc_cli/Cargo.toml | 2 +- rpc_client/Cargo.toml | 2 +- scripts/cov.sh | 11 +- util/rlp/src/compression.rs | 44 +-- 93 files changed, 1762 insertions(+), 533 deletions(-) create mode 100644 js/src/api/local/ethkey/ethkey.js create mode 100644 js/src/api/local/ethkey/ethkey.wasm.js create mode 100644 js/src/views/Application/TabBar/tabBar.js create mode 100644 js/wasm/README.md create mode 100644 js/wasm/ethkey/.gitignore create mode 100644 js/wasm/ethkey/Cargo.toml create mode 100644 js/wasm/ethkey/base64ify.js create mode 100755 js/wasm/ethkey/build.sh create mode 100644 js/wasm/ethkey/ethkey.opt.wasm create mode 100644 js/wasm/ethkey/ethkey.wasm create mode 100644 js/wasm/ethkey/src/main.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f88509475..cfed44415 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: RUST_BACKTRACE: "1" RUSTFLAGS: "" CARGOFLAGS: "" + CI_SERVER_NAME: "GitLab CI" cache: key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME" untracked: true @@ -607,19 +608,6 @@ js-test: tags: - rust - rust-stable -js-test-node_8: - stage: test - image: parity/rust-debian-node_8:gitlab-ci - before_script: - - git submodule update --init --recursive - - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) - - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi - script: - - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi - tags: - - rust - - rust-stable - allow_failure: true test-rust-beta: stage: test only: diff --git a/CHANGELOG.md b/CHANGELOG.md index d109cfdb0..29f84462d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ +## Parity [v1.6.8](https://github.com/paritytech/parity/releases/tag/v1.6.8) (2017-06-08) + +This release addresses: + +- a rare condition where quickly creating a new account was generating an account not matching the recovery phrase. +- compressed RLP strings caused wrong/empty transaction receipts on Classic network. +- blacklisting the _empty phrase_ account from UI and RPC on non-development chains. See also [this blog post](https://blog.parity.io/restoring-blank-seed-phrase/). +- canceling transactions that didn't have a condition. +- the updated Expanse fork block and chain ID. + +Full changelog: + +- Backporting to beta [#5791](https://github.com/paritytech/parity/pull/5791) + - Bump to v1.6.8 + - Update expanse json with fork at block 600000 [#5351](https://github.com/paritytech/parity/pull/5351) + - Update expanse json with fork at block 600000 + - Update exp chainID to 2 + - Bumped mio [#5763](https://github.com/paritytech/parity/pull/5763) + - Fixed default UI port for mac installer [#5782](https://github.com/paritytech/parity/pull/5782) + - Blacklist empty phrase account. [#5730](https://github.com/paritytech/parity/pull/5730) + - Update Cid/multihash/ring/tinykeccak [#5785](https://github.com/paritytech/parity/pull/5785) + - Updating ring,multihash,tiny-keccak + - Updating CID in ipfs. + - Disable compression for RLP strings [#5786](https://github.com/paritytech/parity/pull/5786) +- Beta Backports [#5789](https://github.com/paritytech/parity/pull/5789) + - Fix local transactions without condition. [#5716](https://github.com/paritytech/parity/pull/5716) + - Block invalid account name creation [#5784](https://github.com/paritytech/parity/pull/5784) + - Additional non-empty phrase check (fromNew) + - Explicit canCreate check in create (not only on UI) + - BN instance check (fixes Geth imports) + - Fixup tests after better checks + - Recover from empty phrase in dev mode [#5698](https://github.com/paritytech/parity/pull/5698) + - Add dev chain to isTest + - Fix signer + - Fix no condition transactions + - Fix case: old parity + - Fix propTypes. + ## Parity [v1.6.7](https://github.com/paritytech/parity/releases/tag/v1.6.7) (2017-05-18) This release addresses: diff --git a/Cargo.lock b/Cargo.lock index ff8b71780..6b1a66e8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,6 +120,11 @@ name = "bitflags" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "blastfig" version = "0.3.3" @@ -800,6 +805,11 @@ name = "fnv" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "foreign-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "futures" version = "0.1.11" @@ -942,7 +952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1017,7 +1027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonrpc-core" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1029,7 +1039,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1042,7 +1052,7 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1055,7 +1065,7 @@ dependencies = [ [[package]] name = "jsonrpc-macros" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-pubsub 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1065,7 +1075,7 @@ dependencies = [ [[package]] name = "jsonrpc-minihttp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1079,7 +1089,7 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1089,7 +1099,7 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1101,7 +1111,7 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "bytes 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1115,7 +1125,7 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" version = "7.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#900b528213ffd1aaaefd29e2b99dfab892b15ab4" +source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7#87db29043826f152cce171351fa34fada287764d" dependencies = [ "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-server-utils 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1366,13 +1376,13 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1499,23 +1509,25 @@ dependencies = [ [[package]] name = "openssl" -version = "0.9.3" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.3" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1791,7 +1803,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/paritytech/js-precompiled.git#52ba0075a974e89a723e04c55dd5d5b9941d9a11" +source = "git+https://github.com/paritytech/js-precompiled.git#0811e57083d75d8e93e03ccd9bba3432703236ce" dependencies = [ "parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1887,7 +1899,7 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2184,7 +2196,7 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2212,18 +2224,18 @@ dependencies = [ [[package]] name = "security-framework" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "security-framework-sys" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2857,6 +2869,7 @@ dependencies = [ "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum blastfig 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09640e0509d97d5cdff03a9f5daf087a8e04c735c3b113a75139634a19cfc7b2" "checksum bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f421095d2a76fc24cd3fb3f912b90df06be7689912b1bdb423caefae59c258d" "checksum bn 0.4.4 (git+https://github.com/paritytech/bn)" = "" @@ -2888,6 +2901,7 @@ dependencies = [ "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" +"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" "checksum futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8e51e7f9c150ba7fd4cee9df8bf6ea3dea5b63b68955ddad19ccd35b71dcfb4d" "checksum futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bb982bb25cd8fa5da6a8eb3a460354c984ff1113da82bcb4f0b0862b5795db82" "checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d" @@ -2945,7 +2959,7 @@ dependencies = [ "checksum multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d14363c7695e2e5adbbb8fe139d806a19b8b13f02b9b1fb770fab0c12edaff58" "checksum nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "" "checksum nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "" -"checksum native-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4e52995154bb6f0b41e4379a279482c9387c1632e3798ba4e511ef8c54ee09" +"checksum native-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e94a2fc65a44729fe969cc973da87c1052ae3f000b2cb33029f14aeb85550d5" "checksum net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bc01404e7568680f1259aa5729539f221cb1e6d047a0d9053cab4be8a73b5d67" "checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2" "checksum nom 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6caab12c5f97aa316cb249725aa32115118e1522b445e26c257dd77cad5ffd4e" @@ -2960,8 +2974,8 @@ dependencies = [ "checksum number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "084d05f4bf60621a9ac9bde941a410df548f4de9545f06e5ee9d3aef4b97cd77" "checksum odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b28c06e81b0f789122d415d6394b5fe849bde8067469f4c2980d3cdc10c78ec1" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" -"checksum openssl 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "12be61c7eaa23228316ff02c39807e4c1b1af84ba81420f19fd58dade304b25c" -"checksum openssl-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d2845e841700e7b04282ceaa115407ea84e0db918ae689ad9ceb6f06fa6046bd" +"checksum openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b34cd77cf91301fff3123fbd46b065c3b728b17a392835de34c397315dce5586" +"checksum openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e035022a50faa380bd7ccdbd184d946ce539ebdb0a358780de92a995882af97a" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1d06f6ee0fda786df3784a96ee3f0629f529b91cbfb7d142f6410e6bcd1ce2c" @@ -2974,7 +2988,7 @@ dependencies = [ "checksum phf_codegen 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8af7ae7c3f75a502292b491e5cc0a1f69e3407744abe6e57e2a3b712bb82f01d" "checksum phf_generator 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "db005608fd99800c8c74106a7c894cf582055b689aa14a79462cefdcb7dc1cc3" "checksum phf_shared 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fee4d039930e4f45123c9b15976cf93a499847b6483dc09c42ea0ec4940f2aa6" -"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0" "checksum pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2412f3332a07c7a2a50168988dcc184f32180a9758ad470390e5f55e089f6b6e" "checksum primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e31b86efadeaeb1235452171a66689682783149a6249ff334a2c5d8218d00a4" @@ -3006,11 +3020,11 @@ dependencies = [ "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e114e275f7c9b5d50bb52b28f9aac1921209f02aa6077c8b255e21eefaf8ffa" -"checksum schannel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "167852e03fcd0029c3ddebb5afb0715b2996f6e262b2c2aceaa7cd84edd4b158" +"checksum schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4e45ac5e9e4698c1c138d2972bedcd90b81fe1efeba805449d2bdd54512de5f9" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" -"checksum security-framework 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52186fcf3b391c9f0ccdce9a2ac708f7cc81b3f89e149b34bd9279fb1b23f9fa" -"checksum security-framework-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c84067e6297c1f09514a8666d8bbc1268817ec4a6c0f30f12f6201e1f34bd2a1" +"checksum security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "42ddf098d78d0b64564b23ee6345d07573e7d10e52ad86875d89ddf5f8378a02" +"checksum security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5bacdada57ea62022500c457c8571c17dfb5e6240b7c8eac5916ffa8c7138a55" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" diff --git a/Cargo.toml b/Cargo.toml index 597766a49..497078c62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,13 +72,14 @@ daemonize = "0.2" [features] default = ["ui-precompiled"] ui = [ - "dapps", + "ui-enabled", "parity-dapps/ui", ] ui-precompiled = [ - "dapps", + "ui-enabled", "parity-dapps/ui-precompiled", ] +ui-enabled = ["dapps"] dapps = ["parity-dapps"] ipc = ["ethcore/ipc", "ethsync/ipc"] jit = ["ethcore/jit"] diff --git a/README.md b/README.md index a21e6eeb9..b286055b2 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ below to build from source. ## Build dependencies -**Parity requires Rust version 1.16.0 to build** +**Parity requires Rust version 1.17.0 to build** We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this: diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index c6c41c5f8..84c1df8fc 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -168,7 +168,10 @@ fn verify_external(header: &Header, validators: &ValidatorSet, step: &Step) -> R } else { let proposer_signature = header_signature(header)?; let correct_proposer = validators.get(header.parent_hash(), header_step); - if !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())? { + let is_invalid_proposer = *header.author() != correct_proposer || + !verify_address(&correct_proposer, &proposer_signature, &header.bare_hash())?; + + if is_invalid_proposer { trace!(target: "engine", "verify_block_unordered: bad proposer for step: {}", header_step); Err(EngineError::NotProposer(Mismatch { expected: correct_proposer, found: header.author().clone() }))? } else { diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 008a63424..75a4806b8 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -69,6 +69,10 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err let sig = UntrustedRlp::new(&header.seal()[0]).as_val::()?; let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?); + if *header.author() != signer { + return Err(EngineError::NotAuthorized(*header.author()).into()) + } + match validators.contains(header.parent_hash(), &signer) { false => Err(BlockError::InvalidSeal.into()), true => Ok(()) diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index e0000f4cc..7d3963eac 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -60,7 +60,7 @@ pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73ffffffffffffffffffffffff /// Voting errors. #[derive(Debug)] pub enum EngineError { - /// Signature does not belong to an authority. + /// Signature or author field does not belong to an authority. NotAuthorized(Address), /// The same author issued different votes at the same step. DoubleVote(Address), diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 6e698150b..1013612e8 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -106,7 +106,7 @@ impl From for EthashParams { difficulty_bound_divisor: p.difficulty_bound_divisor.into(), difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into), metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into), - duration_limit: p.duration_limit.into(), + duration_limit: p.duration_limit.map_or(0, Into::into), block_reward: p.block_reward.into(), registrar: p.registrar.map_or_else(Address::new, Into::into), homestead_transition: p.homestead_transition.map_or(0, Into::into), diff --git a/ethcore/src/evm/evm.rs b/ethcore/src/evm/evm.rs index 46457c35f..a644fd255 100644 --- a/ethcore/src/evm/evm.rs +++ b/ethcore/src/evm/evm.rs @@ -76,7 +76,7 @@ impl From> for Error { impl From for Error { fn from(err: builtin::Error) -> Self { Error::BuiltIn(err.0) - } + } } impl fmt::Display for Error { diff --git a/ethcore/src/evm/ext.rs b/ethcore/src/evm/ext.rs index cc294dbd4..2eb99fe7c 100644 --- a/ethcore/src/evm/ext.rs +++ b/ethcore/src/evm/ext.rs @@ -131,7 +131,7 @@ pub trait Ext { fn inc_sstore_clears(&mut self); /// Prepare to trace an operation. Passthrough for the VM trace. - fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false } + fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false } /// Trace the finalised execution of a single instruction. fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} diff --git a/ethcore/src/evm/instructions.rs b/ethcore/src/evm/instructions.rs index f726c9166..26d9ca989 100644 --- a/ethcore/src/evm/instructions.rs +++ b/ethcore/src/evm/instructions.rs @@ -37,6 +37,15 @@ pub fn get_push_bytes(i: Instruction) -> usize { (i - PUSH1 + 1) as usize } +/// Returns number of bytes to read for `PUSHN` instruction or 0. +pub fn push_bytes(i: Instruction) -> usize { + if is_push(i) { + get_push_bytes(i) + } else { + 0 + } +} + #[test] fn test_get_push_bytes() { assert_eq!(get_push_bytes(PUSH1), 1); @@ -129,166 +138,172 @@ pub fn get_tier_idx (tier: GasPriceTier) -> usize { } } +/// EVM instruction information. #[derive(Copy, Clone, Default)] pub struct InstructionInfo { + /// Mnemonic name. pub name: &'static str, + /// Additional code bytes used. Used only for PUSHxx. pub additional: usize, + /// Number of stack arguments. pub args: usize, + /// Number of returned stack items. pub ret: usize, - pub side_effects: bool, + /// Gas price tier. pub tier: GasPriceTier } impl InstructionInfo { - pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, side_effects: bool, tier: GasPriceTier) -> Self { + /// Create new instruction info. + pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, tier: GasPriceTier) -> Self { InstructionInfo { name: name, additional: additional, args: args, ret: ret, - side_effects: side_effects, tier: tier } } } lazy_static! { + /// Static instruction table. pub static ref INSTRUCTIONS: [InstructionInfo; 0x100] = { let mut arr = [InstructionInfo::default(); 0x100]; - arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, true, GasPriceTier::Zero); - arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, false, GasPriceTier::Low); - arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, false, GasPriceTier::Low); - arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, false, GasPriceTier::Low); - arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, false, GasPriceTier::Low); - arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, false, GasPriceTier::Low); - arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, false, GasPriceTier::Special); - arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, false, GasPriceTier::Mid); - arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, false, GasPriceTier::Mid); - arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, false, GasPriceTier::Low); - arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, false, GasPriceTier::Special); - arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, false, GasPriceTier::Base); - arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, false, GasPriceTier::Special); - arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, false, GasPriceTier::Base); - arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, false, GasPriceTier::Special); - arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, true, GasPriceTier::Special); - arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, false, GasPriceTier::Ext); - arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, false, GasPriceTier::Base); - arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, false, GasPriceTier::Base); - arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, false, GasPriceTier::Base); - arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, false, GasPriceTier::Base); - arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, false, GasPriceTier::Base); - arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, false, GasPriceTier::Base); - arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, true, GasPriceTier::VeryLow); - arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, true, GasPriceTier::VeryLow); - arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, false, GasPriceTier::Special); - arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, true, GasPriceTier::Special); - arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, true, GasPriceTier::Mid); - arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, true, GasPriceTier::High); - arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, false, GasPriceTier::Base); - arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, false, GasPriceTier::Base); - arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, true, GasPriceTier::Special); - arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, false, GasPriceTier::VeryLow); - arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, false, GasPriceTier::VeryLow); - arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, false, GasPriceTier::VeryLow); - arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, false, GasPriceTier::VeryLow); - arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, false, GasPriceTier::VeryLow); - arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, false, GasPriceTier::VeryLow); - arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, false, GasPriceTier::VeryLow); - arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, false, GasPriceTier::VeryLow); - arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, false, GasPriceTier::VeryLow); - arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, false, GasPriceTier::VeryLow); - arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, false, GasPriceTier::VeryLow); - arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, false, GasPriceTier::VeryLow); - arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, false, GasPriceTier::VeryLow); - arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, false, GasPriceTier::VeryLow); - arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, false, GasPriceTier::VeryLow); - arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, false, GasPriceTier::VeryLow); - arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, false, GasPriceTier::VeryLow); - arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, false, GasPriceTier::VeryLow); - arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, false, GasPriceTier::VeryLow); - arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, false, GasPriceTier::VeryLow); - arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, false, GasPriceTier::VeryLow); - arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, false, GasPriceTier::VeryLow); - arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, false, GasPriceTier::VeryLow); - arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, false, GasPriceTier::VeryLow); - arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, false, GasPriceTier::VeryLow); - arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, false, GasPriceTier::VeryLow); - arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, false, GasPriceTier::VeryLow); - arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, false, GasPriceTier::VeryLow); - arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, false, GasPriceTier::VeryLow); - arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, false, GasPriceTier::VeryLow); - arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, false, GasPriceTier::VeryLow); - arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, false, GasPriceTier::VeryLow); - arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, false, GasPriceTier::VeryLow); - arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, true, GasPriceTier::Special); - arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, true, GasPriceTier::Special); - arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, true, GasPriceTier::Special); - arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, true, GasPriceTier::Special); - arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, true, GasPriceTier::Special); - arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, true, GasPriceTier::Special); - arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, true, GasPriceTier::Special); - arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, true, GasPriceTier::Special); - arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero); - arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special); - arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special); - arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, true, GasPriceTier::Special); - arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, true, GasPriceTier::Zero); + arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, GasPriceTier::Zero); + arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, GasPriceTier::VeryLow); + arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, GasPriceTier::VeryLow); + arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, GasPriceTier::Low); + arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, GasPriceTier::Low); + arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, GasPriceTier::Low); + arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, GasPriceTier::Low); + arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, GasPriceTier::Low); + arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, GasPriceTier::Special); + arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, GasPriceTier::VeryLow); + arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, GasPriceTier::VeryLow); + arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, GasPriceTier::VeryLow); + arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, GasPriceTier::VeryLow); + arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, GasPriceTier::VeryLow); + arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, GasPriceTier::VeryLow); + arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, GasPriceTier::VeryLow); + arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, GasPriceTier::VeryLow); + arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, GasPriceTier::VeryLow); + arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, GasPriceTier::VeryLow); + arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, GasPriceTier::VeryLow); + arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, GasPriceTier::Mid); + arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, GasPriceTier::Mid); + arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, GasPriceTier::Low); + arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, GasPriceTier::Base); + arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, GasPriceTier::Special); + arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, GasPriceTier::Base); + arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, GasPriceTier::Special); + arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, GasPriceTier::Base); + arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, GasPriceTier::Base); + arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, GasPriceTier::Base); + arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, GasPriceTier::VeryLow); + arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, GasPriceTier::Base); + arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, GasPriceTier::Base); + arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, GasPriceTier::Base); + arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, GasPriceTier::Special); + arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, GasPriceTier::Special); + arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, GasPriceTier::Ext); + arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, GasPriceTier::Base); + arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, GasPriceTier::Base); + arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, GasPriceTier::Base); + arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, GasPriceTier::Base); + arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, GasPriceTier::Base); + arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, GasPriceTier::Base); + arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, GasPriceTier::VeryLow); + arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, GasPriceTier::VeryLow); + arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, GasPriceTier::VeryLow); + arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, GasPriceTier::Special); + arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, GasPriceTier::Special); + arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, GasPriceTier::Mid); + arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, GasPriceTier::High); + arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, GasPriceTier::Base); + arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, GasPriceTier::Base); + arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, GasPriceTier::Base); + arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, GasPriceTier::Special); + arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, GasPriceTier::VeryLow); + arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, GasPriceTier::VeryLow); + arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, GasPriceTier::VeryLow); + arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, GasPriceTier::VeryLow); + arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, GasPriceTier::VeryLow); + arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, GasPriceTier::VeryLow); + arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, GasPriceTier::VeryLow); + arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, GasPriceTier::VeryLow); + arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, GasPriceTier::VeryLow); + arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, GasPriceTier::VeryLow); + arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, GasPriceTier::VeryLow); + arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, GasPriceTier::VeryLow); + arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, GasPriceTier::VeryLow); + arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, GasPriceTier::VeryLow); + arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, GasPriceTier::VeryLow); + arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, GasPriceTier::VeryLow); + arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, GasPriceTier::VeryLow); + arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, GasPriceTier::VeryLow); + arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, GasPriceTier::VeryLow); + arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, GasPriceTier::VeryLow); + arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, GasPriceTier::VeryLow); + arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, GasPriceTier::VeryLow); + arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, GasPriceTier::VeryLow); + arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, GasPriceTier::VeryLow); + arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, GasPriceTier::VeryLow); + arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, GasPriceTier::VeryLow); + arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, GasPriceTier::VeryLow); + arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, GasPriceTier::VeryLow); + arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, GasPriceTier::VeryLow); + arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, GasPriceTier::VeryLow); + arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, GasPriceTier::VeryLow); + arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, GasPriceTier::VeryLow); + arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, GasPriceTier::VeryLow); + arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, GasPriceTier::VeryLow); + arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, GasPriceTier::VeryLow); + arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, GasPriceTier::VeryLow); + arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, GasPriceTier::VeryLow); + arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, GasPriceTier::VeryLow); + arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, GasPriceTier::VeryLow); + arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, GasPriceTier::VeryLow); + arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, GasPriceTier::VeryLow); + arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, GasPriceTier::VeryLow); + arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, GasPriceTier::VeryLow); + arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, GasPriceTier::VeryLow); + arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, GasPriceTier::VeryLow); + arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, GasPriceTier::VeryLow); + arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, GasPriceTier::VeryLow); + arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, GasPriceTier::VeryLow); + arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, GasPriceTier::VeryLow); + arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, GasPriceTier::VeryLow); + arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, GasPriceTier::VeryLow); + arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, GasPriceTier::VeryLow); + arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, GasPriceTier::VeryLow); + arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, GasPriceTier::VeryLow); + arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, GasPriceTier::VeryLow); + arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, GasPriceTier::VeryLow); + arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, GasPriceTier::VeryLow); + arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, GasPriceTier::VeryLow); + arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, GasPriceTier::VeryLow); + arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, GasPriceTier::VeryLow); + arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, GasPriceTier::VeryLow); + arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, GasPriceTier::VeryLow); + arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, GasPriceTier::VeryLow); + arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, GasPriceTier::VeryLow); + arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, GasPriceTier::Special); + arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, GasPriceTier::Special); + arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, GasPriceTier::Special); + arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, GasPriceTier::Special); + arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, GasPriceTier::Special); + arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, GasPriceTier::Special); + arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, GasPriceTier::Special); + arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, GasPriceTier::Special); + arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, GasPriceTier::Zero); + arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, GasPriceTier::Special); + arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, GasPriceTier::Special); + arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, GasPriceTier::Special); + arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, GasPriceTier::Zero); arr }; } diff --git a/ethcore/src/evm/interpreter/memory.rs b/ethcore/src/evm/interpreter/memory.rs index 555e4bc30..00f7a7d79 100644 --- a/ethcore/src/evm/interpreter/memory.rs +++ b/ethcore/src/evm/interpreter/memory.rs @@ -89,9 +89,10 @@ impl Memory for Vec { } fn write_slice(&mut self, offset: U256, slice: &[u8]) { - let off = offset.low_u64() as usize; - - self[off..off+slice.len()].copy_from_slice(slice); + if !slice.is_empty() { + let off = offset.low_u64() as usize; + self[off..off+slice.len()].copy_from_slice(slice); + } } fn write(&mut self, offset: U256, value: U256) { @@ -183,5 +184,12 @@ mod tests { assert_eq!(mem.read_slice(U256::from(0), U256::from(7)), "a67890g".as_bytes()); } + + // write empty slice out of bounds + { + let slice = []; + mem.write_slice(U256::from(0x1000), &slice); + assert_eq!(mem.size(), 32); + } } } diff --git a/ethcore/src/evm/interpreter/mod.rs b/ethcore/src/evm/interpreter/mod.rs index 8b8b739e0..32d010daf 100644 --- a/ethcore/src/evm/interpreter/mod.rs +++ b/ethcore/src/evm/interpreter/mod.rs @@ -130,7 +130,7 @@ impl evm::Evm for Interpreter { // Calculate gas cost let requirements = gasometer.requirements(ext, instruction, info, &stack, self.mem.size())?; // TODO: make compile-time removable if too much of a performance hit. - let trace_executed = ext.trace_prepare_execute(reader.position - 1, instruction, info.args, &requirements.gas_cost.as_u256()); + let trace_executed = ext.trace_prepare_execute(reader.position - 1, instruction, &requirements.gas_cost.as_u256()); gasometer.verify_gas(&requirements.gas_cost)?; self.mem.expand(requirements.memory_required_size); diff --git a/ethcore/src/evm/mod.rs b/ethcore/src/evm/mod.rs index 1ac05ce61..91b44a543 100644 --- a/ethcore/src/evm/mod.rs +++ b/ethcore/src/evm/mod.rs @@ -35,6 +35,7 @@ mod benches; pub use self::evm::{Evm, Error, Finalize, FinalizationResult, GasLeft, Result, CostType, ReturnData}; pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, CreateContractAddress}; +pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; pub use self::vmtype::VMType; pub use self::factory::Factory; pub use self::schedule::Schedule; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index b5b5fb959..4dbee6bde 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -357,7 +357,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output, trace_output.as_mut()), &mut subtracer, &mut subvmtracer) }; - vm_tracer.done_subtrace(subvmtracer); + vm_tracer.done_subtrace(subvmtracer, res.is_ok()); trace!(target: "executive", "res={:?}", res); @@ -432,7 +432,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> { self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract(trace_output.as_mut()), &mut subtracer, &mut subvmtracer) }; - vm_tracer.done_subtrace(subvmtracer); + vm_tracer.done_subtrace(subvmtracer, res.is_ok()); match res { Ok(ref res) => tracer.trace_create( diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 22a80a3ba..d0895306e 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -361,8 +361,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E> self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one(); } - fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, stack_pop: usize, gas_cost: &U256) -> bool { - self.vm_tracer.trace_prepare_execute(pc, instruction, stack_pop, gas_cost) + fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool { + self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost) } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) { diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index 6cca0020c..fb2f91a2f 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -192,7 +192,7 @@ impl ExecutiveVMTracer { } impl VMTracer for ExecutiveVMTracer { - fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, _stack_pop: usize, gas_cost: &U256) -> bool { + fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool { self.data.operations.push(VMOperation { pc: pc, instruction: instruction, @@ -221,7 +221,7 @@ impl VMTracer for ExecutiveVMTracer { }} } - fn done_subtrace(&mut self, sub: Self) { + fn done_subtrace(&mut self, sub: Self, _is_successful: bool) { self.data.subs.push(sub.data); } diff --git a/ethcore/src/trace/mod.rs b/ethcore/src/trace/mod.rs index 6cb9e47e9..a7eea218b 100644 --- a/ethcore/src/trace/mod.rs +++ b/ethcore/src/trace/mod.rs @@ -89,7 +89,7 @@ pub trait Tracer: Send { pub trait VMTracer: Send { /// Trace the preparation to execute a single instruction. /// @returns true if `trace_executed` should be called. - fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false } + fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false } /// Trace the finalised execution of a single instruction. fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} @@ -98,7 +98,7 @@ pub trait VMTracer: Send { fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized; /// Finalize subtracer. - fn done_subtrace(&mut self, sub: Self) where Self: Sized; + fn done_subtrace(&mut self, sub: Self, is_successful: bool) where Self: Sized; /// Consumes self and returns the VM trace. fn drain(self) -> Option; diff --git a/ethcore/src/trace/noop_tracer.rs b/ethcore/src/trace/noop_tracer.rs index d69ed9a16..d8502a4a8 100644 --- a/ethcore/src/trace/noop_tracer.rs +++ b/ethcore/src/trace/noop_tracer.rs @@ -72,7 +72,7 @@ pub struct NoopVMTracer; impl VMTracer for NoopVMTracer { /// Trace the preparation to execute a single instruction. - fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false } + fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false } /// Trace the finalised execution of a single instruction. fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {} @@ -81,7 +81,7 @@ impl VMTracer for NoopVMTracer { fn prepare_subtrace(&self, _code: &[u8]) -> Self { NoopVMTracer } /// Spawn subtracer which will be used to trace deeper levels of execution. - fn done_subtrace(&mut self, _sub: Self) {} + fn done_subtrace(&mut self, _sub: Self, _is_successful: bool) {} /// Consumes self and returns all VM traces. fn drain(self) -> Option { None } diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index 604d3d3c3..1791640d6 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -16,7 +16,7 @@ //! JSON VM output. -use ethcore::trace; +use ethcore::{evm, trace}; use std::collections::HashMap; use util::{U256, H256, ToPretty}; @@ -26,11 +26,14 @@ use vm; /// JSON formatting informant. #[derive(Default)] pub struct Informant { + code: Vec, depth: usize, pc: usize, instruction: u8, + name: &'static str, gas_cost: U256, gas_used: U256, + stack_pop: usize, stack: Vec, memory: Vec, storage: HashMap, @@ -55,38 +58,44 @@ impl Informant { } impl vm::Informant for Informant { + fn set_gas(&mut self, gas: U256) { + self.gas_used = gas; + } + fn finish(&mut self, result: Result) { match result { Ok(success) => println!( - "{{\"output\":\"0x{output}\",\"gasUsed\":\"{gas:x}\",\"time\":\"{time}\"}}", + "{{\"output\":\"0x{output}\",\"gasUsed\":\"{gas:x}\",\"time\":{time}}}", output = success.output.to_hex(), gas = success.gas_used, - time = display::format_time(&success.time), + time = display::as_micros(&success.time), ), Err(failure) => println!( - "{{\"error\":\"{error}\",\"time\":\"{time}\"}}", + "{{\"error\":\"{error}\",\"gasUsed\":\"{gas:x}\",\"time\":{time}}}", error = failure.error, - time = display::format_time(&failure.time), + gas = failure.gas_used, + time = display::as_micros(&failure.time), ), } } } impl trace::VMTracer for Informant { - fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, stack_pop: usize, gas_cost: &U256) -> bool { + fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool { self.pc = pc; self.instruction = instruction; self.gas_cost = *gas_cost; - let len = self.stack.len(); - self.stack.truncate(len - stack_pop); true } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) { + let info = evm::INSTRUCTIONS[self.instruction as usize]; + println!( - "{{\"pc\":{pc},\"op\":{op},\"gas\":{gas},\"gasCost\":{gas_cost},\"memory\":{memory},\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}", + "{{\"pc\":{pc},\"op\":{op},\"opName\":\"{name}\",\"gas\":{gas},\"gasCost\":{gas_cost},\"memory\":{memory},\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}", pc = self.pc, op = self.instruction, + name = info.name, gas = display::u256_as_str(&(gas_used + self.gas_cost)), gas_cost = display::u256_as_str(&self.gas_cost), memory = self.memory(), @@ -96,6 +105,9 @@ impl trace::VMTracer for Informant { ); self.gas_used = gas_used; + + let len = self.stack.len(); + self.stack.truncate(len - info.args); self.stack.extend_from_slice(stack_push); if let Some((pos, data)) = mem_diff { @@ -107,17 +119,25 @@ impl trace::VMTracer for Informant { } } - fn prepare_subtrace(&self, _code: &[u8]) -> Self where Self: Sized { + fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized { let mut vm = Informant::default(); vm.depth = self.depth + 1; + vm.code = code.to_vec(); + vm.gas_used = self.gas_used; vm } - fn done_subtrace(&mut self, mut sub: Self) where Self: Sized { + fn done_subtrace(&mut self, mut sub: Self, is_successful: bool) where Self: Sized { if sub.depth == 1 { // print last line with final state: - sub.pc += 1; - sub.instruction = 0; + if is_successful { + sub.pc += 1; + sub.instruction = 0; + } else { + let push_bytes = evm::push_bytes(sub.instruction); + sub.pc += if push_bytes > 0 { push_bytes + 1 } else { 0 }; + sub.instruction = if sub.pc < sub.code.len() { sub.code[sub.pc] } else { 0 }; + } sub.gas_cost = 0.into(); let gas_used = sub.gas_used; trace::VMTracer::trace_executed(&mut sub, gas_used, &[], None, None); diff --git a/evmbin/src/display/mod.rs b/evmbin/src/display/mod.rs index 2d6179859..2c25fe721 100644 --- a/evmbin/src/display/mod.rs +++ b/evmbin/src/display/mod.rs @@ -27,6 +27,11 @@ pub fn format_time(time: &Duration) -> String { format!("{}.{:.9}s", time.as_secs(), time.subsec_nanos()) } +/// Formats the time as microseconds. +pub fn as_micros(time: &Duration) -> u64 { + time.as_secs() * 1_000_000 + time.subsec_nanos() as u64 / 1_000 +} + /// Converts U256 into string. /// TODO Overcomes: https://github.com/paritytech/bigint/issues/13 pub fn u256_as_str(v: &U256) -> String { diff --git a/evmbin/src/display/simple.rs b/evmbin/src/display/simple.rs index 5dcefd92c..46a57bab0 100644 --- a/evmbin/src/display/simple.rs +++ b/evmbin/src/display/simple.rs @@ -44,6 +44,6 @@ impl vm::Informant for Informant { impl trace::VMTracer for Informant { fn prepare_subtrace(&self, _code: &[u8]) -> Self where Self: Sized { Default::default() } - fn done_subtrace(&mut self, _sub: Self) where Self: Sized {} + fn done_subtrace(&mut self, _sub: Self, _is_successful: bool) where Self: Sized {} fn drain(self) -> Option { None } } diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 6f50249e0..a7d90b90b 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -81,6 +81,7 @@ fn run(args: Args, mut informant: T) { params.code = Some(Arc::new(code)); params.data = data; + informant.set_gas(gas); let result = vm::run(&mut informant, spec, params); informant.finish(result); } diff --git a/evmbin/src/vm.rs b/evmbin/src/vm.rs index 6e45c5dc8..51a8425a1 100644 --- a/evmbin/src/vm.rs +++ b/evmbin/src/vm.rs @@ -24,6 +24,8 @@ use ethcore::action_params::ActionParams; /// VM execution informant pub trait Informant: trace::VMTracer { + /// Set initial gas. + fn set_gas(&mut self, _gas: U256) {} /// Display final result. fn finish(&mut self, result: Result); } @@ -40,6 +42,8 @@ pub struct Success { /// Execution failed pub struct Failure { + /// Used gas + pub gas_used: U256, /// Internal error pub error: EvmTestError, /// Duration @@ -49,6 +53,7 @@ pub struct Failure { /// Execute VM with given `ActionParams` pub fn run(vm_tracer: &mut T, spec: spec::Spec, params: ActionParams) -> Result { let mut test_client = EvmTestClient::new(spec).map_err(|error| Failure { + gas_used: 0.into(), error, time: Duration::from_secs(0) })?; @@ -65,6 +70,7 @@ pub fn run(vm_tracer: &mut T, spec: spec::Spec, params: Acti time: duration, }), Err(e) => Err(Failure { + gas_used: initial_gas, error: e, time: duration, }), diff --git a/js/package.json b/js/package.json index 57f6793b5..bca02d6f2 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "1.7.87", + "version": "1.7.89", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", @@ -68,6 +68,7 @@ "qrcode-generator": "kazuhikoarase/qrcode-generator" }, "devDependencies": { + "arraybuffer-loader": "0.2.2", "babel-cli": "6.23.0", "babel-core": "6.23.1", "babel-eslint": "7.1.1", @@ -127,6 +128,7 @@ "mocha": "3.2.0", "mock-local-storage": "1.0.2", "mock-socket": "6.0.4", + "napa": "2.3.0", "nock": "9.0.7", "postcss-import": "9.1.0", "postcss-loader": "1.3.2", @@ -169,6 +171,7 @@ "@parity/ui": "file:src/ui", "@parity/views": "file:src/views", "@parity/wordlist": "1.0.1", + "es6-error": "4.0.0", "es6-promise": "4.0.5", "flat": "2.0.1", "flow": "^0.2.3", @@ -178,7 +181,6 @@ "lodash": "4.17.2", "loglevel": "1.4.1", "moment": "2.17.0", - "napa": "2.3.0", "promise-worker": "1.1.1", "react": "15.4.2", "react-dom": "15.4.2", @@ -188,6 +190,10 @@ "react-router-redux": "4.0.7", "react-tap-event-plugin": "2.0.1", "react-tooltip": "3.2.2", + "recharts": "0.15.2", + "redux": "3.6.0", + "redux-actions": "1.1.0", + "redux-thunk": "2.1.0", "store": "1.3.20", "sw-toolbox": "^3.6.0", "u2f-api": "0.0.9", diff --git a/js/src/api/api.js b/js/src/api/api.js index 5131d1a1a..dc8cd9da7 100644 --- a/js/src/api/api.js +++ b/js/src/api/api.js @@ -24,7 +24,7 @@ import { Db, Eth, Parity, Net, Personal, Shh, Signer, Trace, Web3 } from './rpc' import Subscriptions from './subscriptions'; import util from './util'; import { isFunction } from './util/types'; -// import { LocalAccountsMiddleware } from './local'; +import { LocalAccountsMiddleware } from './local'; export default class Api extends EventEmitter { constructor (provider, allowSubscriptions = true) { @@ -59,9 +59,9 @@ export default class Api extends EventEmitter { const middleware = this.parity .nodeKind() .then((nodeKind) => { - // if (nodeKind.availability === 'public') { - // return LocalAccountsMiddleware; - // } + if (nodeKind.availability === 'public') { + return LocalAccountsMiddleware; + } return null; }) diff --git a/js/src/api/local/accounts/account.js b/js/src/api/local/accounts/account.js index 94e923f45..0bb069c8b 100644 --- a/js/src/api/local/accounts/account.js +++ b/js/src/api/local/accounts/account.js @@ -17,9 +17,9 @@ import { createKeyObject, decryptPrivateKey } from '../ethkey'; export default class Account { - constructor (persist, data) { + constructor (persist, data = {}) { const { - keyObject, + keyObject = null, meta = {}, name = '' } = data; @@ -41,6 +41,15 @@ export default class Account { }); } + export () { + const exported = Object.assign({}, this._keyObject); + + exported.meta = JSON.stringify(this._meta); + exported.name = this._name; + + return exported; + } + get address () { return `0x${this._keyObject.address.toLowerCase()}`; } @@ -66,6 +75,10 @@ export default class Account { } get uuid () { + if (!this._keyObject) { + return null; + } + return this._keyObject.id; } diff --git a/js/src/api/local/accounts/accounts.js b/js/src/api/local/accounts/accounts.js index e7e5cc397..d0d100862 100644 --- a/js/src/api/local/accounts/accounts.js +++ b/js/src/api/local/accounts/accounts.js @@ -17,23 +17,74 @@ import Account from './account'; import localStore from 'store'; import { debounce } from 'lodash'; +import { decryptPrivateKey } from '../ethkey'; const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; const LS_STORE_KEY = '_parity::localAccounts'; export default class Accounts { + persist = debounce(() => { + this._lastState = JSON.stringify(this); + + localStore.set(LS_STORE_KEY, this); + }, 100); + constructor (data = localStore.get(LS_STORE_KEY) || {}) { + this._lastState = JSON.stringify(data); + + window.addEventListener('storage', ({ key, newValue }) => { + if (key !== LS_STORE_KEY) { + return; + } + + if (newValue !== this._lastState) { + console.log('Data changed in a second tab, syncing state'); + + this.restore(JSON.parse(newValue)); + } + }); + + this.restore(data); + } + + restore (data) { const { last = NULL_ADDRESS, - store = [] + dappsDefault = NULL_ADDRESS, + store = {} } = data; - this.persist = debounce(() => { - localStore.set(LS_STORE_KEY, this); - }, 100); - this._last = last; - this._store = store.map((data) => new Account(this.persist, data)); + this._dappsDefaultAddress = dappsDefault; + this._store = {}; + + if (Array.isArray(store)) { + // Recover older version that stored accounts as an array + store.forEach((data) => { + const account = new Account(this.persist, data); + + this._store[account.address] = account; + }); + } else { + Object.keys(store).forEach((key) => { + this._store[key] = new Account(this.persist, store[key]); + }); + } + } + + _addAccount = (account) => { + const { address } = account; + + if (address in this._store && this._store[address].uuid) { + throw new Error(`Account ${address} already exists!`); + } + + this._store[address] = account; + this.lastAddress = address; + + this.persist(); + + return account.address; } create (secret, password) { @@ -41,20 +92,19 @@ export default class Accounts { return Account .fromPrivateKey(this.persist, privateKey, password) - .then((account) => { - const { address } = account; + .then(this._addAccount); + } - if (this._store.find((account) => account.address === address)) { - throw new Error(`Account ${address} already exists!`); + restoreFromWallet (wallet, password) { + return decryptPrivateKey(wallet, password) + .then((privateKey) => { + if (!privateKey) { + throw new Error('Invalid password'); } - this._store.push(account); - this.lastAddress = address; - - this.persist(); - - return account.address; - }); + return Account.fromPrivateKey(this.persist, privateKey, password); + }) + .then(this._addAccount); } set lastAddress (value) { @@ -65,20 +115,48 @@ export default class Accounts { return this._last; } + get dappsDefaultAddress () { + if (this._dappsDefaultAddress === NULL_ADDRESS) { + return this._last; + } + + if (this._dappsDefaultAddress in this._store) { + return this._dappsDefaultAddress; + } + + return NULL_ADDRESS; + } + + set dappsDefaultAddress (value) { + this._dappsDefaultAddress = value.toLowerCase(); + } + get (address) { address = address.toLowerCase(); - this.lastAddress = address; - - const account = this._store.find((account) => account.address === address); + const account = this._store[address]; if (!account) { throw new Error(`Account not found: ${address}`); } + this.lastAddress = address; + return account; } + getLazyCreate (address) { + address = address.toLowerCase(); + + this.lastAddress = address; + + if (!(address in this._store)) { + this._store[address] = new Account(this.persist); + } + + return this._store[address]; + } + remove (address, password) { address = address.toLowerCase(); @@ -108,26 +186,20 @@ export default class Accounts { removeUnsafe (address) { address = address.toLowerCase(); - const index = this._store.findIndex((account) => account.address === address); - - if (index === -1) { - return; - } - - this._store.splice(index, 1); + delete this._store[address]; this.persist(); } - mapArray (mapper) { - return this._store.map(mapper); + addresses () { + return Object.keys(this._store); } - mapObject (mapper) { + map (mapper) { const result = {}; - this._store.forEach((account) => { - result[account.address] = mapper(account); + Object.keys(this._store).forEach((key) => { + result[key] = mapper(this._store[key]); }); return result; @@ -136,6 +208,7 @@ export default class Accounts { toJSON () { return { last: this._last, + dappsDefault: this._dappsDefaultAddress, store: this._store }; } diff --git a/js/src/api/local/ethkey/ethkey.js b/js/src/api/local/ethkey/ethkey.js new file mode 100644 index 000000000..f8395b007 --- /dev/null +++ b/js/src/api/local/ethkey/ethkey.js @@ -0,0 +1,147 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +/* global WebAssembly */ + +import wasmBuffer from './ethkey.wasm.js'; + +const NOOP = () => {}; + +// WASM memory setup +const WASM_PAGE_SIZE = 65536; +const STATIC_BASE = 1024; +const STATICTOP = STATIC_BASE + WASM_PAGE_SIZE * 2; +const STACK_BASE = align(STATICTOP + 16); +const STACKTOP = STACK_BASE; +const TOTAL_STACK = 5 * 1024 * 1024; +const TOTAL_MEMORY = 16777216; +const STACK_MAX = STACK_BASE + TOTAL_STACK; +const DYNAMIC_BASE = STACK_MAX + 64; +const DYNAMICTOP_PTR = STACK_MAX; + +function mockWebAssembly () { + function throwWasmError () { + throw new Error('Missing WebAssembly support'); + } + + // Simple mock replacement + return { + Memory: class { buffer = new ArrayBuffer(2048) }, + Table: class {}, + Module: class {}, + Instance: class { + exports = { + '_input_ptr': () => 0, + '_secret_ptr': () => 0, + '_public_ptr': () => 0, + '_address_ptr': () => 0, + '_ecpointg': NOOP, + '_brain': throwWasmError, + '_verify_secret': throwWasmError + } + } + }; +} + +const { Memory, Table, Module, Instance } = typeof WebAssembly !== 'undefined' ? WebAssembly : mockWebAssembly(); + +const wasmMemory = new Memory({ + initial: TOTAL_MEMORY / WASM_PAGE_SIZE, + maximum: TOTAL_MEMORY / WASM_PAGE_SIZE +}); + +const wasmTable = new Table({ + initial: 8, + maximum: 8, + element: 'anyfunc' +}); + +// TypedArray views into the memory +const wasmMemoryU8 = new Uint8Array(wasmMemory.buffer); +const wasmMemoryU32 = new Uint32Array(wasmMemory.buffer); + +// Keep DYNAMIC_BASE in memory +wasmMemoryU32[DYNAMICTOP_PTR >> 2] = align(DYNAMIC_BASE); + +function align (mem) { + const ALIGN_SIZE = 16; + + return (Math.ceil(mem / ALIGN_SIZE) * ALIGN_SIZE) | 0; +} + +export function slice (ptr, len) { + return wasmMemoryU8.subarray(ptr, ptr + len); +} + +// Required by emscripten +function abort (what) { + throw new Error(what || 'WASM abort'); +} + +// Required by emscripten +function abortOnCannotGrowMemory () { + abort(`Cannot enlarge memory arrays.`); +} + +// Required by emscripten +function enlargeMemory () { + abortOnCannotGrowMemory(); +} + +// Required by emscripten +function getTotalMemory () { + return TOTAL_MEMORY; +} + +// Required by emscripten - used to perform memcpy on large data +function memcpy (dest, src, len) { + wasmMemoryU8.set(wasmMemoryU8.subarray(src, src + len), dest); + + return dest; +} + +// Synchronously compile WASM from the buffer +const module = new Module(wasmBuffer); + +// Instantiated WASM module +const instance = new Instance(module, { + global: {}, + env: { + DYNAMICTOP_PTR, + STACKTOP, + STACK_MAX, + abort, + enlargeMemory, + getTotalMemory, + abortOnCannotGrowMemory, + ___lock: NOOP, + ___syscall6: () => 0, + ___setErrNo: (no) => no, + _abort: abort, + ___syscall140: () => 0, + _emscripten_memcpy_big: memcpy, + ___syscall54: () => 0, + ___unlock: NOOP, + _llvm_trap: abort, + ___syscall146: () => 0, + 'memory': wasmMemory, + 'table': wasmTable, + tableBase: 0, + memoryBase: STATIC_BASE + } +}); + +export const extern = instance.exports; diff --git a/js/src/api/local/ethkey/ethkey.wasm.js b/js/src/api/local/ethkey/ethkey.wasm.js new file mode 100644 index 000000000..d426f0e0c --- /dev/null +++ b/js/src/api/local/ethkey/ethkey.wasm.js @@ -0,0 +1 @@ +module.exports = new Buffer('AGFzbQEAAAABOgpgA39/fwF/YAF/AX9gAn9/AX9gAX8AYAABf2AAAGACf38AYAR/f39/AGADf39/AGAGf39/f39/AX8CyQELA2VudghTVEFDS1RPUAN/AANlbnYFYWJvcnQAAwNlbnYLX19fc3lzY2FsbDYAAgNlbnYNX19fc3lzY2FsbDE0MAACA2VudhZfZW1zY3JpcHRlbl9tZW1jcHlfYmlnAAADZW52DF9fX3N5c2NhbGw1NAACA2VudgpfbGx2bV90cmFwAAUDZW52DV9fX3N5c2NhbGwxNDYAAgNlbnYGbWVtb3J5AgGAAoACA2VudgV0YWJsZQFwAQgIA2Vudgl0YWJsZUJhc2UDfwADOjkEBAQEBAQDBwMICAgIAwYGBgIIAwMDBgMDCAYGBgMCBwYIAgICBgkDBgEAAAEEBAQAAQAAAQABAAIGBgF/ASMACwdfBw5fdmVyaWZ5X3NlY3JldAAMC19wdWJsaWNfcHRyAAoLX3NlY3JldF9wdHIACQpfaW5wdXRfcHRyAAgJX2VjcG9pbnRnAAcGX2JyYWluAA0MX2FkZHJlc3NfcHRyAAsJDgEAIwELCD0wPjEyNz8rCpClAzlJAQJ/An8jAiEAIwJB0JgBaiQCQagZKAIAQQFGBEAgACQCQawZDwsgACIBEB9BqBlBATYCAEGsGSABQdCYARA8GiAAJAJBrBkLCwYAQbi2AQsGAEG4vgELBgBB2L4BCwYAQZi/AQsKAEG4vgFBIBAlC74HAQt/AkAjAiEIIwJBoJwBaiQCIABBgAhLBEAgAEGACBAnCyAIQaACaiEFQagZKAIAQQFHBEAgBRAfQagZQQE2AgBBrBkgBUHQmAEQPBoLIAghCSAIQcgAaiIEEBQgCEH4mwFqIgFCADcAACABQgA3AAggAUIANwAQIAFCADcAGCAEQbi2ASAAEBAgBSAEQdgBEDwaIAUgAUEgEBIgCEHwmgFqIgMgASkAADcAACADIAEpAAg3AAggAyABKQAQNwAQIAMgASkAGDcAGCAIQZCbAWoiBkEBaiEHIAhB2JsBaiICQQxqIQpBACEAA0AgBBAUIAFCADcAACABQgA3AAggAUIANwAQIAFCADcAGCAEIANBIBAQIAUgBEHYARA8GiAFIAFBIBASIAIgASkAADcAACACIAEpAAg3AAggAiABKQAQNwAQIAIgASkAGDcAGCADIAIpAAA3AAAgAyACKQAINwAIIAMgAikAEDcAECADIAIpABg3ABggAEEBaiELIABBgYABRwRAIAshAAwBCwsgCUEBaiEAA0ACQCAJQawZIANBIBAmIAksAABBAUYEQCAGIAApAAA3AAAgBiAAKQAINwAIIAYgACkAEDcAECAGIAApABg3ABggBiAAKQAgNwAgIAYgACkAKDcAKCAGIAApADA3ADAgBiAAKQA4NwA4IAYgACwAQDoAQCAEEBQgAUIANwAAIAFCADcACCABQgA3ABAgAUIANwAYIAQgB0HAABAQIAUgBEHYARA8GiAFIAFBIBASIAIgASkAADcAACACIAEpAAg3AAggAiABKQAQNwAQIAIgASkAGDcAGEGYvwEgCikAADcAAEGgvwEgCikACDcAAEGovwEgCigAEDYAAEGYvwEsAABFDQELIAQQFCABQgA3AAAgAUIANwAIIAFCADcAECABQgA3ABggBCADQSAQECAFIARB2AEQPBogBSABQSAQEiACIAEpAAA3AAAgAiABKQAINwAIIAIgASkAEDcAECACIAEpABg3ABggAyACKQAANwAAIAMgAikACDcACCADIAIpABA3ABAgAyACKQAYNwAYDAELC0HYvgEgBykAADcAAEHgvgEgBykACDcAAEHovgEgBykAEDcAAEHwvgEgBykAGDcAAEH4vgEgBykAIDcAAEGAvwEgBykAKDcAAEGIvwEgBykAMDcAAEGQvwEgBykAODcAAEG4vgEgAykAADcAAEHAvgEgAykACDcAAEHIvgEgAykAEDcAAEHQvgEgAykAGDcAACAIJAILCwQAEAUL1wsCGX8tfgJAIAApAwAhJCAAQShqIgIpAwAhJSAAQdAAaiIDKQMAITAgAEH4AGoiBCkDACE+IABBoAFqIgUpAwAhJiAAQQhqIgYpAwAhMSAAQTBqIgcpAwAhMiAAQdgAaiIIKQMAIScgAEGAAWoiCSkDACEgIABBqAFqIgopAwAhPyAAQRBqIgspAwAhMyAAQThqIgwpAwAhHSAAQeAAaiINKQMAISEgAEGIAWoiDikDACE0IABBsAFqIg8pAwAhHiAAQRhqIhApAwAhNSAAQcAAaiIRKQMAISggAEHoAGoiEikDACE2IABBkAFqIhMpAwAhGyAAQbgBaiIUKQMAISIgAEEgaiIV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0AkpAwA3AxAgAUHYCSkDADcDGCABQeAJKQMANwMgIAFB6AkpAwA3AyggAUHwCSkDADcDMCABQfgJKQMANwM4IAFBgAopAwA3A0AgASADEBYgACABKQIANwIAIAAgASkCCDcCCCAAIAEpAhA3AhAgACABKQIYNwIYIAAgASkCIDcCICAAIAEpAig3AiggACABKQIwNwIwIAAgASkCODcCOCAAIAEpAkA3AkAgByQCDwsACwsgAxAbIAAgAykCADcCACAAIAMpAgg3AgggACADKQIQNwIQIAAgAykCGDcCGCAAIAMpAiA3AiAgACADKQIoNwIoIAAgAykCMDcCMCAAIAMpAjg3AjggACADKQJANwJAIAckAgsLzx8BD38CQCMCIQwjAkGABWokAiAAQZABaiIELAAABEAgDCQCDwsgDCELIAxBuARqIgIgAEHIAGoiCikCADcCACACIAopAgg3AgggAiAKKQIQNwIQIAIgCikCGDcCGCACIAopAiA3AiAgAiAKKQIoNwIoIAIgCikCMDcCMCACIAopAjg3AjggAiAKKQJANwJAIAIgChAVIAxB8ANqIgEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgNBCEYEQEEIIQcCQAJAAkADQCAHQX9qIQMgB0UNBSADQRBPDQEgAUEEaiADQQJ0aigCACIHIANBAnRBxAlqKAIAIgVHDQIgAyEHDAALAAtBvAsgA0EQECgMAQsgByAFTw0CQQghDQsFIANBCE8NASADIQ0LDAELIAFBwAkQFiABKAIAIQ0LIAEoAgQhDiALIAFBCGoiAykCADcCACALIAMpAgg3AgggCyADKQIQNwIQIAsgAykCGDcCGCALIAMpAiA3AiAgCyADKQIoNwIoIAsgAykCMDcCMCALIAMpAjg3AjggDUEBRiAORXEEQCAEQQE6AAAgDCQCDwsgDEGoA2ohCCAMQeACaiEEIAxBmAJqIQUgDEGIAWohBiACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAAQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgDEHAAGoiCSABKQMANwMAIAkgASkDCDcDCCAJIAEpAxA3AxAgCSABKQMYNwMYIAkgASkDIDcDICAJIAEpAyg3AyggCSABKQMwNwMwIAkgASkDODcDOCAJIAEpA0A3A0AgAiAJKQMANwMAIAIgCSkDCDcDCCACIAkpAxA3AxAgAiAJKQMYNwMYIAIgCSkDIDcDICACIAkpAyg3AyggAiAJKQMwNwMwIAIgCSkDODcDOCACIAkpA0A3A0AgAiAJEBUgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0ACQAJAIAEoAgAiA0EIRgRAQQghBwJAAkACQANAIAdBf2ohAyAHRQ0FIANBEE8NASABQQRqIANBAnRqKAIAIgcgA0ECdEHECWooAgAiD0cNAiADIQcMAAsAC0G8CyADQRAQKAwBCyAHIA9PDQILBSADQQhPDQELDAELIAFBwAkQFgsgBCABKQMANwMAIAQgASkDCDcDCCAEIAEpAxA3AxAgBCABKQMYNwMYIAQgASkDIDcDICAEIAEpAyg3AyggBCABKQMwNwMwIAQgASkDODcDOCAEIAEpA0A3A0AgAiAEKQMANwMAIAIgBCkDCDcDCCACIAQpAxA3AxAgAiAEKQMYNwMYIAIgBCkDIDcDICACIAQpAyg3AyggAiAEKQMwNwMwIAIgBCkDODcDOCACIAQpA0A3A0AgAiAJEBUgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0ACQAJAIAEoAgAiA0EIRgRAQQghBwJAAkACQANAIAdBf2ohAyAHRQ0FIANBEE8NASABQQRqIANBAnRqKAIAIgcgA0ECdEHECWooAgAiCUcNAiADIQcMAAsAC0G8CyADQRAQKAwBCyAHIAlPDQILBSADQQhPDQELDAELIAFBwAkQFgsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgAiANNgIAIAIgDjYCBCACQQhqIgMgCykDADcDACADIAspAwg3AwggAyALKQMQNwMQIAMgCykDGDcDGCADIAspAyA3AyAgAyALKQMoNwMoIAMgCykDMDcDMCADIAspAzg3AzggCCACEB0gAiAFKQMANwMAIAIgBSkDCDcDCCACIAUpAxA3AxAgAiAFKQMYNwMYIAIgBSkDIDcDICACIAUpAyg3AyggAiAFKQMwNwMwIAIgBSkDODcDOCACIAUpA0A3A0AgAiAIEBcgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgARAbIAYgASkDADcDACAGIAEpAwg3AwggBiABKQMQNwMQIAYgASkDGDcDGCAGIAEpAyA3AyAgBiABKQMoNwMoIAYgASkDMDcDMCAGIAEpAzg3AzggBiABKQNANwNAIAIgBikDADcDACACIAYpAwg3AwggAiAGKQMQNwMQIAIgBikDGDcDGCACIAYpAyA3AyAgAiAGKQMoNwMoIAIgBikDMDcDMCACIAYpAzg3AzggAiAGKQNANwNAIAIgBhAXIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAEQGyAEIAEpAwA3AwAgBCABKQMINwMIIAQgASkDEDcDECAEIAEpAxg3AxggBCABKQMgNwMgIAQgASkDKDcDKCAEIAEpAzA3AzAgBCABKQM4NwM4IAQgASkDQDcDQCACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAAQFSABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQAJAAkAgASgCACIDQQhGBEBBCCEHAkACQAJAA0AgB0F/aiEDIAdFDQUgA0EQTw0BIAFBBGogA0ECdGooAgAiByADQQJ0QcQJaigCACILRw0CIAMhBwwACwALQbwLIANBEBAoDAELIAcgC08NAgsFIANBCE8NAQsMAQsgAUHACRAWCyAIIAEpAwA3AwAgCCABKQMINwMIIAggASkDEDcDECAIIAEpAxg3AxggCCABKQMgNwMgIAggASkDKDcDKCAIIAEpAzA3AzAgCCABKQM4NwM4IAggASkDQDcDQCACIAQpAwA3AwAgAiAEKQMINwMIIAIgBCkDEDcDECACIAQpAxg3AxggAiAEKQMgNwMgIAIgBCkDKDcDKCACIAQpAzA3AzAgAiAEKQM4NwM4IAIgBCkDQDcDQCACIAgQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyAMQdABaiIDIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAMQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyAIIAEpAwA3AwAgCCABKQMINwMIIAggASkDEDcDECAIIAEpAxg3AxggCCABKQMgNwMgIAggASkDKDcDKCAIIAEpAzA3AzAgCCABKQM4NwM4IAggASkDQDcDQCACIAYpAwA3AwAgAiAGKQMINwMIIAIgBikDEDcDECACIAYpAxg3AxggAiAGKQMgNwMgIAIgBikDKDcDKCACIAYpAzA3AzAgAiAGKQM4NwM4IAIgBikDQDcDQCACIAgQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgBCABKQMANwMAIAQgASkDCDcDCCAEIAEpAxA3AxAgBCABKQMYNwMYIAQgASkDIDcDICAEIAEpAyg3AyggBCABKQMwNwMwIAQgASkDODcDOCAEIAEpA0A3A0AgAiAEKQMANwMAIAIgBCkDCDcDCCACIAQpAxA3AxAgAiAEKQMYNwMYIAIgBCkDIDcDICACIAQpAyg3AyggAiAEKQMwNwMwIAIgBCkDODcDOCACIAQpA0A3A0AgAiAKEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgCiAFKQIANwIAIAogBSkCCDcCCCAKIAUpAhA3AhAgCiAFKQIYNwIYIAogBSkCIDcCICAKIAUpAig3AiggCiAFKQIwNwIwIAogBSkCODcCOCAKIAUpAkA3AkAgACADKQIANwIAIAAgAykCCDcCCCAAIAMpAhA3AhAgACADKQIYNwIYIAAgAykCIDcCICAAIAMpAig3AiggACADKQIwNwIwIAAgAykCODcCOCAAIAMpAkA3AkAgDCQCCwvCFgETfwJAIwIhCSMCQfC1AmokAiAJQZC0AmohAyAJQcizAmohBSAJQbiyAmohByAJQey1AmohCyAJIgRBCDYCACAEQZiv4LcBNgIEIARB24LKzwU2AgggBEHZ0bjuAjYCDCAEQdv57xQ2AhAgBEGHlpz0fDYCFCAEQZXFga0FNgIYIARBrPfyTjYCHCAEQf7M+c0HNgIgIARBJGoiBkIANwIAIAZCADcCCCAGQgA3AhAgBkIANwIYIAZBADoAICAEQQg2AkggBEHMAGoiD0G4qcNYNgIAIARBj6Gf4nk2AlAgBEGZqJW0ejYCVCAEQcjo3mg2AlggBEGokcTwADYCXCAEQfz3k+0FNgJgIARB5YiPtQI2AmQgBEH3tOvBBDYCaCAEQewAaiIGQgA3AgAgBkIANwIIIAZCADcCECAGQgA3AhggBkEAOgAgIARBkAFqIhBBADoAACAJQdi0AmoiASAEQZQBEDwaIAlB6JkBaiICIARBlAEQPBogAkGUAWogAUGUARA8GiACQagCaiABQZQBEDwaIAJBvANqIAFBlAEQPBogAkHQBGogAUGUARA8GiACQeQFaiABQZQBEDwaIAJB+AZqIAFBlAEQPBogAkGMCGogAUGUARA8GiACQaAJaiABQZQBEDwaIAJBtApqIAFBlAEQPBogAkHIC2ogAUGUARA8GiACQdwMaiABQZQBEDwaIAJB8A1qIAFBlAEQPBogAkGED2ogAUGUARA8GiACQZgQaiABQZQBEDwaIAJBrBFqIAFBlAEQPBogAkHAEmogAUGUARA8GiACQdQTaiABQZQBEDwaIAJB6BRqIAFBlAEQPBogAkH8FWogAUGUARA8GiACQZAXaiABQZQBEDwaIAJBpBhqIAFBlAEQPBogAkG4GWogAUGUARA8GiACQcwaaiABQZQBEDwaIAJB4BtqIAFBlAEQPBogAkH0HGogAUGUARA8GiACQYgeaiABQZQBEDwaIAJBnB9qIAFBlAEQPBogAkGwIGogAUGUARA8GiACQcQhaiABQZQBEDwaIAJB2CJqIAFBlAEQPBogAkHsI2ogAUGUARA8GiACQYAlaiABQZQBEDwaIAJBlCZqIAFBlAEQPBogAkGoJ2ogAUGUARA8GiACQbwoaiABQZQBEDwaIAJB0ClqIAFBlAEQPBogAkHkKmogAUGUARA8GiACQfgraiABQZQBEDwaIAJBjC1qIAFBlAEQPBogAkGgLmogAUGUARA8GiACQbQvaiABQZQBEDwaIAJByDBqIAFBlAEQPBogAkHcMWogAUGUARA8GiACQfAyaiABQZQBEDwaIAJBhDRqIAFBlAEQPBogAkGYNWogAUGUARA8GiACQaw2aiABQZQBEDwaIAJBwDdqIAFBlAEQPBogAkHUOGogAUGUARA8GiACQeg5aiABQZQBEDwaIAJB/DpqIAFBlAEQPBogAkGQPGogAUGUARA8GiACQaQ9aiABQZQBEDwaIAJBuD5qIAFBlAEQPBogAkHMP2ogAUGUARA8GiACQeDAAGogAUGUARA8GiACQfTBAGogAUGUARA8GiACQYjDAGogAUGUARA8GiACQZzEAGogAUGUARA8GiACQbDFAGogAUGUARA8GiACQcTGAGogAUGUARA8GiACQdjHAGogAUGUARA8GiACQezIAGogAUGUARA8GiACQYDKAGogAUGUARA8GiACQZTLAGogAUGUARA8GiAQLAAABH8gByAEQZABEDwaIAsgBEGRAWoiBi4AADsAACALIAYsAAI6AAJBAQUgBSAEKQMANwMAIAUgBCkDCDcDCCAFIAQpAxA3AxAgBSAEKQMYNwMYIAUgBCkDIDcDICAFIAQpAyg3AyggBSAEKQMwNwMwIAUgBCkDODcDOCAFIAQpA0A3A0AgBEHIAGoiBigCAEEBRiAPKAIARXEEQCADQdgMKQIANwIAIANB4AwpAgA3AgggA0HoDCkCADcCECADQfAMKQIANwIYIANB+AwpAgA3AiAgA0GADSkCADcCKCADQYgNKQIANwIwIANBkA0pAgA3AjggA0GYDSkCADcCQAUgAUHACSkDADcDACABQcgJKQMANwMIIAFB0AkpAwA3AxAgAUHYCSkDADcDGCABQeAJKQMANwMgIAFB6AkpAwA3AyggAUHwCSkDADcDMCABQfgJKQMANwM4IAFBgAopAwA3A0AgASAGEBYgAyABKQMANwMAIAMgASkDCDcDCCADIAEpAxA3AxAgAyABKQMYNwMYIAMgASkDIDcDICADIAEpAyg3AyggAyABKQMwNwMwIAMgASkDODcDOCADIAEpA0A3A0ALIAcgBSkDADcDACAHIAUpAwg3AwggByAFKQMQNwMQIAcgBSkDGDcDGCAHIAUpAyA3AyAgByAFKQMoNwMoIAcgBSkDMDcDMCAHIAUpAzg3AzggByAFKQNANwNAIAdByABqIgYgAykDADcDACAGIAMpAwg3AwggBiADKQMQNwMQIAYgAykDGDcDGCAGIAMpAyA3AyAgBiADKQMoNwMoIAYgAykDMDcDMCAGIAMpAzg3AzggBiADKQNANwNAQQALIQwgCUGYAWohDSAJQZDmAWoiCkGozABqIQggCiEG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QCACIA4QFyAMQbgIaiIDIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgDCIGIAMpAwA3AwAgBiADKQMINwMIIAYgAykDEDcDECAGIAMpAxg3AxggBiADKQMgNwMgIAYgAykDKDcDKCAGIAMpAzA3AzAgBiADKQM4NwM4IAYgAykDQDcDQCACIABBkAFqIgkpAgA3AgAgAiAJKQIINwIIIAIgCSkCEDcCECACIAkpAhg3AhggAiAJKQIgNwIgIAIgCSkCKDcCKCACIAkpAjA3AjAgAiAJKQI4NwI4IAIgCSkCQDcCQCACIAkQFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgDEHIAGoiBSADKQMANwMAIAUgAykDCDcDCCAFIAMpAxA3AxAgBSADKQMYNwMYIAUgAykDIDcDICAFIAMpAyg3AyggBSADKQMwNwMwIAUgAykDODcDOCAFIAMpA0A3A0AgAiAAKQIANwIAIAIgACkCCDcCCCACIAApAhA3AhAgAiAAKQIYNwIYIAIgACkCIDcCICACIAApAig3AiggAiAAKQIwNwIwIAIgACkCODcCOCACIAApAkA3AkAgAiAGEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAxBkAFqIgcgAykDADcDACAHIAMpAwg3AwggByADKQMQNwMQIAcgAykDGDcDGCAHIAMpAyA3AyAgByADKQMoNwMoIAcgAykDMDcDMCAHIAMpAzg3AzggByADKQNANwNAIAIgASkCADcCACACIAEpAgg3AgggAiABKQIQNwIQIAIgASkCGDcCGCACIAEpAiA3AiAgAiABKQIoNwIoIAIgASkCMDcCMCACIAEpAjg3AjggAiABKQJANwJAIAIgBRAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyAMQdgBaiIIIAMpAwA3AwAgCCADKQMINwMIIAggAykDEDcDECAIIAMpAxg3AxggCCADKQMgNwMgIAggAykDKDcDKCAIIAMpAzA3AzAgCCADKQM4NwM4IAggAykDQDcDQCACIABByABqIg0pAgA3AgAgAiANKQIINwIIIAIgDSkCEDcCECACIA0pAhg3AhggAiANKQIgNwIgIAIgDSkCKDcCKCACIA0pAjA3AjAgAiANKQI4NwI4IAIgDSkCQDcCQCACIAYQFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgDEHwB2oiBCADKQMANwMAIAQgAykDCDcDCCAEIAMpAxA3AxAgBCADKQMYNwMYIAQgAykDIDcDICAEIAMpAyg3AyggBCADKQMwNwMwIAQgAykDODcDOCAEIAMpA0A3A0AgAiAEKQMANwMAIAIgBCkDCDcDCCACIAQpAxA3AxAgAiAEKQMYNwMYIAIgBCkDIDcDICACIAQpAyg3AyggAiAEKQMwNwMwIAIgBCkDODcDOCACIAQpA0A3A0AgAiAOEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAxBoAJqIgogAykDADcDACAKIAMpAwg3AwggCiADKQMQNwMQIAogAykDGDcDGCAKIAMpAyA3AyAgCiADKQMoNwMoIAogAykDMDcDMCAKIAMpAzg3AzggCiADKQNANwNAIAIgAUHIAGoiASkCADcCACACIAEpAgg3AgggAiABKQIQNwIQIAIgASkCGDcCGCACIAEpAiA3AiAgAiABKQIoNwIoIAIgASkCMDcCMCACIAEpAjg3AjggAiABKQJANwJAIAIgBRAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyAEIAMpAwA3AwAgBCADKQMINwMIIAQgAykDEDcDECAEIAMpAxg3AxggBCADKQMgNwMgIAQgAykDKDcDKCAEIAMpAzA3AzAgBCADKQM4NwM4IAQgAykDQDcDQCACIAQpAwA3AwAgAiAEKQMINwMIIAIgBCkDEDcDECACIAQpAxg3AxggAiAEKQMgNwMgIAIgBCkDKDcDKCACIAQpAzA3AzAgAiAEKQM4NwM4IAIgBCkDQDcDQCACIAkQFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgDEHoAmoiASADKQMANwMAIAEgAykDCDcDCCABIAMpAxA3AxAgASADKQMYNwMYIAEgAykDIDcDICABIAMpAyg3AyggASADKQMwNwMwIAEgAykDODcDOCABIAMpA0A3A0AgAiAHKQMANwMAIAIgBykDCDcDCCACIAcpAxA3AxAgAiAHKQMYNwMYIAIgBykDIDcDICACIAcpAyg3AyggAiAHKQMwNwMwIAIgBykDODcDOCACIAcpA0A3A0AgAiAIEBYgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAywARARAIANBwAkQFQsgDEGwA2oiCyADKQMANwMAIAsgAykDCDcDCCALIAMpAxA3AxAgCyADKQMYNwMYIAsgAykDIDcDICALIAMpAyg3AyggCyADKQMwNwMwIAsgAykDODcDOCALIAMpA0A3A0AgAiAKKQMANwMAIAIgCikDCDcDCCACIAopAxA3AxAgAiAKKQMYNwMYIAIgCikDIDcDICACIAopAyg3AyggAiAKKQMwNwMwIAIgCikDODcDOCACIAopA0A3A0AgAiABEBYgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAywARARAIANBwAkQFQsgDEH4A2oiCCADKQMANwMAIAggAykDCDcDCCAIIAMpAxA3AxAgCCADKQMYNwMYIAggAykDIDcDICAIIAMpAyg3AyggCCADKQMwNwMwIAggAykDODcDOCAIIAMpA0A3A0AgCygCAEEBRgRAIAsoAgRFBEACQAJAIAgoAgBBAUcNACAIKAIEDQAgABAkDAELIAJBiAopAwA3AwAgAkGQCikDADcDCCACQZgKKQMANwMQIAJBoAopAwA3AxggAkGoCikDADcDICACQbAKKQMANwMoIAJBuAopAwA3AzAgAkHACikDADcDOCACQcgKKQMANwNAIAJByABqIgFBiAopAwA3AwAgAUGQCikDADcDCCABQZgKKQMANwMQIAFBoAopAwA3AxggAUGoCikDADcDICABQbAKKQMANwMoIAFBuAopAwA3AzAgAUHACikDADcDOCABQcgKKQMANwNAIAJBkAFqIgFB2AwpAgA3AgAgAUHgDCkCADcCCCABQegMKQIANwIQIAFB8AwpAgA3AhggAUH4DCkCADcCICABQYANKQIANwIoIAFBiA0pAgA3AjAgAUGQDSkCADcCOCABQZgNKQIANwJAIAAgAkHYARA8GgsgDCQCDwsLIAxBqAdqIQUgAiALKQMANwMAIAIgCykDCDcDCCACIAspAxA3AxAgAiALKQMYNwMYIAIgCykDIDcDICACIAspAyg3AyggAiALKQMwNwMwIAIgCykDODcDOCACIAspA0A3A0AgAiALEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAxBwARqIgEgAykDADcDACABIAMpAwg3AwggASADKQMQNwMQIAEgAykDGDcDGCABIAMpAyA3AyAgASADKQMoNwMoIAEgAykDMDcDMCABIAMpAzg3AzggASADKQNANwNAIAIgBykDADcDACACIAcpAwg3AwggAiAHKQMQNwMQIAIgBykDGDcDGCACIAcpAyA3AyAgAiAHKQMoNwMoIAIgBykDMDcDMCACIAcpAzg3AzggAiAHKQNANwNAIAIgARAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyAMQYgFaiIHIAMpAwA3AwAgByADKQMINwMIIAcgAykDEDcDECAHIAMpAxg3AxggByADKQMgNwMgIAcgAykDKDcDKCAHIAMpAzA3AzAgByADKQM4NwM4IAcgAykDQDcDQCACIAEpAwA3AwAgAiABKQMINwMIIAIgASkDEDcDECACIAEpAxg3AxggAiABKQMgNwMgIAIgASkDKDcDKCACIAEpAzA3AzAgAiABKQM4NwM4IAIgASkDQDcDQCACIAsQFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgDEHQBWoiDyADKQMANwMAIA8gAykDCDcDCCAPIAMpAxA3AxAgDyADKQMYNwMYIA8gAykDIDcDICAPIAMpAyg3AyggDyADKQMwNwMwIA8gAykDODcDOCAPIAMpA0A3A0AgAiAIKQMANwMAIAIgCCkDCDcDCCACIAgpAxA3AxAgAiAIKQMYNwMYIAIgCCkDIDcDICACIAgpAyg3AyggAiAIKQMwNwMwIAIgCCkDODcDOCACIAgpA0A3A0AgAiAIEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAQgAykDADcDACAEIAMpAwg3AwggBCADKQMQNwMQIAQgAykDGDcDGCAEIAMpAyA3AyAgBCADKQMoNwMoIAQgAykDMDcDMCAEIAMpAzg3AzggBCADKQNANwNAIAIgBCkDADcDACACIAQpAwg3AwggAiAEKQMQNwMQIAIgBCkDGDcDGCACIAQpAyA3AyAgAiAEKQMoNwMoIAIgBCkDMDcDMCACIAQpAzg3AzggAiAEKQNANwNAIAIgDxAVIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAAkACQCADKAIAIgFBCEYEQEEIIQYCQAJAAkADQCAGQX9qIQEgBkUNBSABQRBPDQEgA0EEaiABQQJ0aigCACIGIAFBAnRBxAlqKAIAIhBHDQIgASEGDAALAAtBvAsgAUEQECgMAQsgBiAQTw0CCwUgAUEITw0BCwwBCyADQcAJEBYLIAUgAykDADcDACAFIAMpAwg3AwggBSADKQMQNwMQIAUgAykDGDcDGCAFIAMpAyA3AyAgBSADKQMoNwMoIAUgAykDMDcDMCAFIAMpAzg3AzggBSADKQNANwNAIAIgBSkDADcDACACIAUpAwg3AwggAiAFKQMQNwMQIAIgBSkDGDcDGCACIAUpAyA3AyAgAiAFKQMoNwMoIAIgBSkDMDcDMCACIAUpAzg3AzggAiAFKQNANwNAIAIgBxAWIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMsAEQEQCADQcAJEBULIAxB4AZqIgEgAykDADcDACABIAMpAwg3AwggASADKQMQNwMQIAEgAykDGDcDGCABIAMpAyA3AyAgASADKQMoNwMoIAEgAykDMDcDMCABIAMpAzg3AzggASADKQNANwNAIAIgASkDADcDACACIAEpAwg3AwggAiABKQMQNwMQIAIgASkDGDcDGCACIAEpAyA3AyAgAiABKQMoNwMoIAIgASkDMDcDMCACIAEpAzg3AzggAiABKQNANwNAIAIgBxAWIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMsAEQEQCADQcAJEBULIAxBmAZqIgYgAykDADcDACAGIAMpAwg3AwggBiADKQMQNwMQIAYgAykDGDcDGCAGIAMpAyA3AyAgBiADKQMoNwMoIAYgAykDMDcDMCAGIAMpAzg3AzggBiADKQNANwNAIAAgBikCADcCACAAIAYpAgg3AgggACAGKQIQNwIQIAAgBikCGDcCGCAAIAYpAiA3AiAgACAGKQIoNwIoIAAgBikCMDcCMCAAIAYpAjg3AjggACAGKQJANwJAIAIgBykDADcDACACIAcpAwg3AwggAiAHKQMQNwMQIAIgBykDGDcDGCACIAcpAyA3AyAgAiAHKQMoNwMoIAIgBykDMDcDMCACIAcpAzg3AzggAiAHKQNANwNAIAIgABAWIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMsAEQEQCADQcAJEBULIAUgAykDADcDACAFIAMpAwg3AwggBSADKQMQNwMQIAUgAykDGDcDGCAFIAMpAyA3AyAgBSADKQMoNwMoIAUgAykDMDcDMCAFIAMpAzg3AzggBSADKQNANwNAIAIgCCkDADcDACACIAgpAwg3AwggAiAIKQMQNwMQIAIgCCkDGDcDGCACIAgpAyA3AyAgAiAIKQMoNwMoIAIgCCkDMDcDMCACIAgpAzg3AzggAiAIKQNANwNAIAIgBRAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyABIAMpAwA3AwAgASADKQMINwMIIAEgAykDEDcDECABIAMpAxg3AxggASADKQMgNwMgIAEgAykDKDcDKCABIAMpAzA3AzAgASADKQM4NwM4IAEgAykDQDcDQCACIAopAwA3AwAgAiAKKQMINwMIIAIgCikDEDcDECACIAopAxg3AxggAiAKKQMgNwMgIAIgCikDKDcDKCACIAopAzA3AzAgAiAKKQM4NwM4IAIgCikDQDcDQCACIA8QFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgBCADKQMANwMAIAQgAykDCDcDCCAEIAMpAxA3AxAgBCADKQMYNwMYIAQgAykDIDcDICAEIAMpAyg3AyggBCADKQMwNwMwIAQgAykDODcDOCAEIAMpA0A3A0AgAiABKQMANwMAIAIgASkDCDcDCCACIAEpAxA3AxAgAiABKQMYNwMYIAIgASkDIDcDICACIAEpAyg3AyggAiABKQMwNwMwIAIgASkDODcDOCACIAEpA0A3A0AgAiAEEBYgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAywARARAIANBwAkQFQsgBiADKQMANwMAIAYgAykDCDcDCCAGIAMpAxA3AxAgBiADKQMYNwMYIAYgAykDIDcDICAGIAMpAyg3AyggBiADKQMwNwMwIAYgAykDODcDOCAGIAMpA0A3A0AgDSAGKQIANwIAIA0gBikCCDcCCCANIAYpAhA3AhAgDSAGKQIYNwIYIA0gBikCIDcCICANIAYpAig3AiggDSAGKQIwNwIwIA0gBikCODcCOCANIAYpAkA3AkAgAiAJKQIANwIAIAIgCSkCCDcCCCACIAkpAhA3AhAgAiAJKQIYNwIYIAIgCSkCIDcCICACIAkpAig3AiggAiAJKQIwNwIwIAIgCSkCODcCOCACIAkpAkA3AkAgAiAOEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAQgAykDADcDACAEIAMpAwg3AwggBCADKQMQNwMQIAQgAykDGDcDGCAEIAMpAyA3AyAgBCADKQMoNwMoIAQgAykDMDcDMCAEIAMpAzg3AzggBCADKQNANwNAIAIgBCkDADcDACACIAQpAwg3AwggAiAEKQMQNwMQIAIgBCkDGDcDGCACIAQpAyA3AyAgAiAEKQMoNwMoIAIgBCkDMDcDMCACIAQpAzg3AzggAiAEKQNANwNAIAIgCxAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyAFIAMpAwA3AwAgBSADKQMINwMIIAUgAykDEDcDECAFIAMpAxg3AxggBSADKQMgNwMgIAUgAykDKDcDKCAFIAMpAzA3AzAgBSADKQM4NwM4IAUgAykDQDcDQCAJIAUpAgA3AgAgCSAFKQIINwIIIAkgBSkCEDcCECAJIAUpAhg3AhggCSAFKQIgNwIgIAkgBSkCKDcCKCAJIAUpAjA3AjAgCSAFKQI4NwI4IAkgBSkCQDcCQCAMJAILC94KAQt/AkAjAiEJIwJBgAVqJAIgCUG4BGohAiAJQfADaiEDIAlBqANqIQQgCUHgAmohBSAJQZgCaiEIIAlB0AFqIQcgCUHAAGoiCiABQZABEDwaIAEoApABIQsgASgClAEhDCAJIgYgAUGYAWoiASkCADcCACAGIAEpAgg3AgggBiABKQIQNwIQIAYgASkCGDcCGCAGIAEpAiA3AiAgBiABKQIoNwIoIAYgASkCMDcCMCAGIAEpAjg3AjggC0EBRiAMRXEEQCAAQYgOQZQBEDwaIAkkAgUgAiALNgIAIAIgDDYCBCACQQhqIgEgBikDADcDACABIAYpAwg3AwggASAGKQMQNwMQIAEgBikDGDcDGCABIAYpAyA3AyAgASAGKQMoNwMoIAEgBikDMDcDMCABIAYpAzg3AzggByACEB0gAiAHKQMANwMAIAIgBykDCDcDCCACIAcpAxA3AxAgAiAHKQMYNwMYIAIgBykDIDcDICACIAcpAyg3AyggAiAHKQMwNwMwIAIgBykDODcDOCACIAcpA0A3A0AgAiAHEBcgAyACKQMANwMAIAMgAikDCDcDCCADIAIpAxA3AxAgAyACKQMYNwMYIAMgAikDIDcDICADIAIpAyg3AyggAyACKQMwNwMwIAMgAikDODcDOCADIAIpA0A3A0AgAxAbIAggAykDADcDACAIIAMpAwg3AwggCCADKQMQNwMQIAggAykDGDcDGCAIIAMpAyA3AyAgCCADKQMoNwMoIAggAykDMDcDMCAIIAMpAzg3AzggCCADKQNANwNAIAIgCikDADcDACACIAopAwg3AwggAiAKKQMQNwMQIAIgCikDGDcDGCACIAopAyA3AyAgAiAKKQMoNwMoIAIgCikDMDcDMCACIAopAzg3AzggAiAKKQNANwNAIAIgCBAXIAMgAikDADcDACADIAIpAwg3AwggAyACKQMQNwMQIAMgAikDGDcDGCADIAIpAyA3AyAgAyACKQMoNwMoIAMgAikDMDcDMCADIAIpAzg3AzggAyACKQNANwNAIAMQGyAFIAMpAwA3AwAgBSADKQMINwMIIAUgAykDEDcDECAFIAMpAxg3AxggBSADKQMgNwMgIAUgAykDKDcDKCAFIAMpAzA3AzAgBSADKQM4NwM4IAUgAykDQDcDQCACIApByABqIgEpAwA3AwAgAiABKQMINwMIIAIgASkDEDcDECACIAEpAxg3AxggAiABKQMgNwMgIAIgASkDKDcDKCACIAEpAzA3AzAgAiABKQM4NwM4IAIgASkDQDcDQCACIAgQFyADIAIpAwA3AwAgAyACKQMINwMIIAMgAikDEDcDECADIAIpAxg3AxggAyACKQMgNwMgIAMgAikDKDcDKCADIAIpAzA3AzAgAyACKQM4NwM4IAMgAikDQDcDQCADEBsgBCADKQMANwMAIAQgAykDCDcDCCAEIAMpAxA3AxAgBCADKQMYNwMYIAQgAykDIDcDICAEIAMpAyg3AyggBCADKQMwNwMwIAQgAykDODcDOCAEIAMpA0A3A0AgBCAHEBcgBBAbIAAgBSkCADcCACAAIAUpAgg3AgggACAFKQIQNwIQIAAgBSkCGDcCGCAAIAUpAiA3AiAgACAFKQIoNwIoIAAgBSkCMDcCMCAAIAUpAjg3AjggACAFKQJANwJAIABByABqIgEgBCkCADcCACABIAQpAgg3AgggASAEKQIQNwIQIAEgBCkCGDcCGCABIAQpAiA3AiAgASAEKQIoNwIoIAEgBCkCMDcCMCABIAQpAjg3AjggASAEKQJANwJAIABBADoAkAEgCSQCCwsLhC0BDX8CQCMCIQwjAkHQCWokAiAMQbgIaiEDIAxB4AZqIQIgACgCkAFBAUYEQCAAKAKUAUUEQCABLACQASEHIAMgAUGQARA8GiAHQQFxBEAgAkGICikDADcDACACQZAKKQMANwMIIAJBmAopAwA3AxAgAkGgCikDADcDGCACQagKKQMANwMgIAJBsAopAwA3AyggAkG4CikDADcDMCACQcAKKQMANwM4IAJByAopAwA3A0AgAkHIAGoiAUGICikDADcDACABQZAKKQMANwMIIAFBmAopAwA3AxAgAUGgCikDADcDGCABQagKKQMANwMgIAFBsAopAwA3AyggAUG4CikDADcDMCABQcAKKQMANwM4IAFByAopAwA3A0AgAkGQAWoiAUHYDCkCADcCACABQeAMKQIANwIIIAFB6AwpAgA3AhAgAUHwDCkCADcCGCABQfgMKQIANwIgIAFBgA0pAgA3AiggAUGIDSkCADcCMCABQZANKQIANwI4IAFBmA0pAgA3AkAFIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAJByABqIgEgA0HIAGoiBykDADcDACABIAcpAwg3AwggASAHKQMQNwMQIAEgBykDGDcDGCABIAcpAyA3AyAgASAHKQMoNwMoIAEgBykDMDcDMCABIAcpAzg3AzggASAHKQNANwNAIAJBkAFqIgFBiAopAwA3AwAgAUGQCikDADcDCCABQZgKKQMANwMQIAFBoAopAwA3AxggAUGoCikDADcDICABQbAKKQMANwMoIAFBuAopAwA3AzAgAUHACikDADcDOCABQcgKKQMANwNACyAAIAJB2AEQPBogDCQCDwsLIAEsAJABBEAgDCQCDwsgAyAAQZABaiIKKQIANwIAIAMgCikCCDcCCCADIAopAhA3AhAgAyAKKQIYNwIYIAMgCikCIDcCICADIAopAig3AiggAyAKKQIwNwIwIAMgCikCODcCOCADIAopAkA3AkAgAyAKEBcgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAhAbIAwiByACKQMANwMAIAcgAikDCDcDCCAHIAIpAxA3AxAgByACKQMYNwMYIAcgAikDIDcDICAHIAIpAyg3AyggByACKQMwNwMwIAcgAikDODcDOCAHIAIpA0A3A0AgAyABKQIANwIAIAMgASkCCDcCCCADIAEpAhA3AhAgAyABKQIYNwIYIAMgASkCIDcCICADIAEpAig3AiggAyABKQIwNwIwIAMgASkCODcCOCADIAEpAkA3AkAgAyAHEBcgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAhAbIAxByABqIgQgAikDADcDACAEIAIpAwg3AwggBCACKQMQNwMQIAQgAikDGDcDGCAEIAIpAyA3AyAgBCACKQMoNwMoIAQgAikDMDcDMCAEIAIpAzg3AzggBCACKQNANwNAIAMgAUHIAGoiASkCADcCACADIAEpAgg3AgggAyABKQIQNwIQIAMgASkCGDcCGCADIAEpAiA3AiAgAyABKQIoNwIoIAMgASkCMDcCMCADIAEpAjg3AjggAyABKQJANwJAIAMgBxAXIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIQGyAMQZABaiIBIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABIAoQFyABEBsgAyAAKQIANwIAIAMgACkCCDcCCCADIAApAhA3AhAgAyAAKQIYNwIYIAMgACkCIDcCICADIAApAig3AiggAyAAKQIwNwIwIAMgACkCODcCOCADIAApAkA3AkAgAyAEEBYgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAiwARARAIAJBwAkQFQsgDEHYAWoiCSACKQMANwMAIAkgAikDCDcDCCAJIAIpAxA3AxAgCSACKQMYNwMYIAkgAikDIDcDICAJIAIpAyg3AyggCSACKQMwNwMwIAkgAikDODcDOCAJIAIpA0A3A0AgAyAAQcgAaiIEKQIANwIAIAMgBCkCCDcCCCADIAQpAhA3AhAgAyAEKQIYNwIYIAMgBCkCIDcCICADIAQpAig3AiggAyAEKQIwNwIwIAMgBCkCODcCOCADIAQpAkA3AkAgAyABEBYgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAiwARARAIAJBwAkQFQsgDEGgAmoiBSACKQMANwMAIAUgAikDCDcDCCAFIAIpAxA3AxAgBSACKQMYNwMYIAUgAikDIDcDICAFIAIpAyg3AyggBSACKQMwNwMwIAUgAikDODcDOCAFIAIpA0A3A0AgCSgCAEEBRgRAIAkoAgRFBEACQAJAIAUoAgBBAUcNACAFKAIEDQAgABAkDAELIABBiAopAgA3AgAgAEGQCikCADcCCCAAQZgKKQIANwIQIABBoAopAgA3AhggAEGoCikCADcCICAAQbAKKQIANwIoIABBuAopAgA3AjAgAEHACikCADcCOCAAQcgKKQIANwJAIARBiAopAgA3AgAgBEGQCikCADcCCCAEQZgKKQIANwIQIARBoAopAgA3AhggBEGoCikCADcCICAEQbAKKQIANwIoIARBuAopAgA3AjAgBEHACikCADcCOCAEQcgKKQIANwJAIApB2AwpAgA3AgAgCkHgDCkCADcCCCAKQegMKQIANwIQIApB8AwpAgA3AhggCkH4DCkCADcCICAKQYANKQIANwIoIApBiA0pAgA3AjAgCkGQDSkCADcCOCAKQZgNKQIANwJACyAMJAIPCwsgDEHQBWohBiADIAkpAwA3AwAgAyAJKQMINwMIIAMgCSkDEDcDECADIAkpAxg3AxggAyAJKQMgNwMgIAMgCSkDKDcDKCADIAkpAzA3AzAgAyAJKQM4NwM4IAMgCSkDQDcDQCADIAkQFyACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACEBsgDEHoAmoiASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgAyAAKQIANwIAIAMgACkCCDcCCCADIAApAhA3AhAgAyAAKQIYNwIYIAMgACkCIDcCICADIAApAig3AiggAyAAKQIwNwIwIAMgACkCODcCOCADIAApAkA3AkAgAyABEBcgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAhAbIAxBsANqIgsgAikDADcDACALIAIpAwg3AwggCyACKQMQNwMQIAsgAikDGDcDGCALIAIpAyA3AyAgCyACKQMoNwMoIAsgAikDMDcDMCALIAIpAzg3AzggCyACKQNANwNAIAMgASkDADcDACADIAEpAwg3AwggAyABKQMQNwMQIAMgASkDGDcDGCADIAEpAyA3AyAgAyABKQMoNwMoIAMgASkDMDcDMCADIAEpAzg3AzggAyABKQNANwNAIAMgCRAXIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIQGyAMQfgDaiINIAIpAwA3AwAgDSACKQMINwMIIA0gAikDEDcDECANIAIpAxg3AxggDSACKQMgNwMgIA0gAikDKDcDKCANIAIpAzA3AzAgDSACKQM4NwM4IA0gAikDQDcDQCADIAUpAwA3AwAgAyAFKQMINwMIIAMgBSkDEDcDECADIAUpAxg3AxggAyAFKQMgNwMgIAMgBSkDKDcDKCADIAUpAzA3AzAgAyAFKQM4NwM4IAMgBSkDQDcDQCADIAUQFyACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACEBsgDEGYBmoiCCACKQMANwMAIAggAikDCDcDCCAIIAIpAxA3AxAgCCACKQMYNwMYIAggAikDIDcDICAIIAIpAyg3AyggCCACKQMwNwMwIAggAikDODcDOCAIIAIpA0A3A0AgAyAIKQMANwMAIAMgCCkDCDcDCCADIAgpAxA3AxAgAyAIKQMYNwMYIAMgCCkDIDcDICADIAgpAyg3AyggAyAIKQMwNwMwIAMgCCkDODcDOCADIAgpA0A3A0AgAyANEBUgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0ACQAJAIAIoAgAiAUEIRgRAQQghBwJAAkACQANAIAdBf2ohASAHRQ0FIAFBEE8NASACQQRqIAFBAnRqKAIAIgcgAUECdEHECWooAgAiDkcNAiABIQcMAAsAC0G8CyABQRAQKAwBCyAHIA5PDQILBSABQQhPDQELDAELIAJBwAkQFgsgBiACKQMANwMAIAYgAikDCDcDCCAGIAIpAxA3AxAgBiACKQMYNwMYIAYgAikDIDcDICAGIAIpAyg3AyggBiACKQMwNwMwIAYgAikDODcDOCAGIAIpA0A3A0AgAyAGKQMANwMAIAMgBikDCDcDCCADIAYpAxA3AxAgAyAGKQMYNwMYIAMgBikDIDcDICADIAYpAyg3AyggAyAGKQMwNwMwIAMgBikDODcDOCADIAYpA0A3A0AgAyALEBYgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAiALEBYgAkHEAGoiASwAAARAA0AgAkHACRAVIAEsAAANAAsLIAxBiAVqIgEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAAgASkCADcCACAAIAEpAgg3AgggACABKQIQNwIQIAAgASkCGDcCGCAAIAEpAiA3AiAgACABKQIoNwIoIAAgASkCMDcCMCAAIAEpAjg3AjggACABKQJANwJAIAMgCykDADcDACADIAspAwg3AwggAyALKQMQNwMQIAMgCykDGDcDGCADIAspAyA3AyAgAyALKQMoNwMoIAMgCykDMDcDMCADIAspAzg3AzggAyALKQNANwNAIAMgABAWIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIsAEQEQCACQcAJEBULIAYgAikDADcDACAGIAIpAwg3AwggBiACKQMQNwMQIAYgAikDGDcDGCAGIAIpAyA3AyAgBiACKQMoNwMoIAYgAikDMDcDMCAGIAIpAzg3AzggBiACKQNANwNAIAMgBSkDADcDACADIAUpAwg3AwggAyAFKQMQNwMQIAMgBSkDGDcDGCADIAUpAyA3AyAgAyAFKQMoNwMoIAMgBSkDMDcDMCADIAUpAzg3AzggAyAFKQNANwNAIAMgBhAXIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIQGyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCADIAQpAgA3AgAgAyAEKQIINwIIIAMgBCkCEDcCECADIAQpAhg3AhggAyAEKQIgNwIgIAMgBCkCKDcCKCADIAQpAjA3AjAgAyAEKQI4NwI4IAMgBCkCQDcCQCADIA0QFyACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACEBsgCCACKQMANwMAIAggAikDCDcDCCAIIAIpAxA3AxAgCCACKQMYNwMYIAggAikDIDcDICAIIAIpAyg3AyggCCACKQMwNwMwIAggAikDODcDOCAIIAIpA0A3A0AgAyABKQMANwMAIAMgASkDCDcDCCADIAEpAxA3AxAgAyABKQMYNwMYIAMgASkDIDcDICADIAEpAyg3AyggAyABKQMwNwMwIAMgASkDODcDOCADIAEpA0A3A0AgAyAIEBYgAiADKQMANwMAIAIgAykDCDcDCCACIAMpAxA3AxAgAiADKQMYNwMYIAIgAykDIDcDICACIAMpAyg3AyggAiADKQMwNwMwIAIgAykDODcDOCACIAMpA0A3A0AgAiwARARAIAJBwAkQFQsgDEHABGoiACACKQMANwMAIAAgAikDCDcDCCAAIAIpAxA3AxAgACACKQMYNwMYIAAgAikDIDcDICAAIAIpAyg3AyggACACKQMwNwMwIAAgAikDODcDOCAAIAIpA0A3A0AgBCAAKQIANwIAIAQgACkCCDcCCCAEIAApAhA3AhAgBCAAKQIYNwIYIAQgACkCIDcCICAEIAApAig3AiggBCAAKQIwNwIwIAQgACkCODcCOCAEIAApAkA3AkAgCiAJEBcgChAbIAwkAgsLklcBE38CQCMCIREjAkHwB2okAiAAKAKQAUEBRiIIBEAgACgClAFFBEAgESQCDwsLIBFBqAdqIQIgEUHgBmohASARQZgGaiEDIBFB0AVqIQUgEUGIBWohBiARQcAEaiEOIBFB+ANqIQcgEUGwA2ohCyARQegCaiENIBFBoAJqIQQgEUHYAWohCSARQZABaiEKIBFByABqIRAgESEPIABBkAFqIRICfwJAIAhFDQAgACgClAFBAUcNACACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAAQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgCSABKQMANwMAIAkgASkDCDcDCCAJIAEpAxA3AxAgCSABKQMYNwMYIAkgASkDIDcDICAJIAEpAyg3AyggCSABKQMwNwMwIAkgASkDODcDOCAJIAEpA0A3A0AgAiAAQcgAaiIMKQIANwIAIAIgDCkCCDcCCCACIAwpAhA3AhAgAiAMKQIYNwIYIAIgDCkCIDcCICACIAwpAig3AiggAiAMKQIwNwIwIAIgDCkCODcCOCACIAwpAkA3AkAgAiAMEBcgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgARAbIAQgASkDADcDACAEIAEpAwg3AwggBCABKQMQNwMQIAQgASkDGDcDGCAEIAEpAyA3AyAgBCABKQMoNwMoIAQgASkDMDcDMCAEIAEpAzg3AzggBCABKQNANwNAIAIgBCkDADcDACACIAQpAwg3AwggAiAEKQMQNwMQIAIgBCkDGDcDGCACIAQpAyA3AyAgAiAEKQMoNwMoIAIgBCkDMDcDMCACIAQpAzg3AzggAiAEKQNANwNAIAIgBBAXIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAEQGyANIAEpAwA3AwAgDSABKQMINwMIIA0gASkDEDcDECANIAEpAxg3AxggDSABKQMgNwMgIA0gASkDKDcDKCANIAEpAzA3AzAgDSABKQM4NwM4IA0gASkDQDcDQCACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAQQFSABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQAJAAkAgASgCACIEQQhGBEBBCCEIAkACQAJAA0AgCEF/aiEEIAhFDQUgBEEQTw0BIAFBBGogBEECdGooAgAiCCAEQQJ0QcQJaigCACITRw0CIAQhCAwACwALQbwLIARBEBAoDAELIAggE08NAgsFIARBCE8NAQsMAQsgAUHACRAWCyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACIAMQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgAiAFKQMANwMAIAIgBSkDCDcDCCACIAUpAxA3AxAgAiAFKQMYNwMYIAIgBSkDIDcDICACIAUpAyg3AyggAiAFKQMwNwMwIAIgBSkDODcDOCACIAUpA0A3A0AgAiAJEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgBiABKQMANwMAIAYgASkDCDcDCCAGIAEpAxA3AxAgBiABKQMYNwMYIAYgASkDIDcDICAGIAEpAyg3AyggBiABKQMwNwMwIAYgASkDODcDOCAGIAEpA0A3A0AgAiAGKQMANwMAIAIgBikDCDcDCCACIAYpAxA3AxAgAiAGKQMYNwMYIAIgBikDIDcDICACIAYpAyg3AyggAiAGKQMwNwMwIAIgBikDODcDOCACIAYpA0A3A0AgAiANEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgCyABKQMANwMAIAsgASkDCDcDCCALIAEpAxA3AxAgCyABKQMYNwMYIAsgASkDIDcDICALIAEpAyg3AyggCyABKQMwNwMwIAsgASkDODcDOCALIAEpA0A3A0AgCxAaIAIgCSkDADcDACACIAkpAwg3AwggAiAJKQMQNwMQIAIgCSkDGDcDGCACIAkpAyA3AyAgAiAJKQMoNwMoIAIgCSkDMDcDMCACIAkpAzg3AzggAiAJKQNANwNAIAIgCRAVIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgRBCEYEQEEIIQgCQAJAAkADQCAIQX9qIQQgCEUNBSAEQRBPDQEgAUEEaiAEQQJ0aigCACIIIARBAnRBxAlqKAIAIhNHDQIgBCEIDAALAAtBvAsgBEEQECgMAQsgCCATTw0CCwUgBEEITw0BCwwBCyABQcAJEBYLIAMgASkDADcDACADIAEpAwg3AwggAyABKQMQNwMQIAMgASkDGDcDGCADIAEpAyA3AyAgAyABKQMoNwMoIAMgASkDMDcDMCADIAEpAzg3AzggAyABKQNANwNAIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIgCRAVIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgRBCEYEQEEIIQgCQAJAAkADQCAIQX9qIQQgCEUNBSAEQRBPDQEgAUEEaiAEQQJ0aigCACIIIARBAnRBxAlqKAIAIglHDQIgBCEIDAALAAtBvAsgBEEQECgMAQsgCCAJTw0CCwUgBEEITw0BCwwBCyABQcAJEBYLIAcgASkDADcDACAHIAEpAwg3AwggByABKQMQNwMQIAcgASkDGDcDGCAHIAEpAyA3AyAgByABKQMoNwMoIAcgASkDMDcDMCAHIAEpAzg3AzggByABKQNANwNAIAIgBykDADcDACACIAcpAwg3AwggAiAHKQMQNwMQIAIgBykDGDcDGCACIAcpAyA3AyAgAiAHKQMoNwMoIAIgBykDMDcDMCACIAcpAzg3AzggAiAHKQNANwNAIAIgBxAXIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAEQGyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACIAsQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyAFIAEpAwA3AwAgBSABKQMINwMIIAUgASkDEDcDECAFIAEpAxg3AxggBSABKQMgNwMgIAUgASkDKDcDKCAFIAEpAzA3AzAgBSABKQM4NwM4IAUgASkDQDcDQCACIAUpAwA3AwAgAiAFKQMINwMIIAIgBSkDEDcDECACIAUpAxg3AxggAiAFKQMgNwMgIAIgBSkDKDcDKCACIAUpAzA3AzAgAiAFKQM4NwM4IAIgBSkDQDcDQCACIAsQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyAOIAEpAwA3AwAgDiABKQMINwMIIA4gASkDEDcDECAOIAEpAxg3AxggDiABKQMgNwMgIA4gASkDKDcDKCAOIAEpAzA3AzAgDiABKQM4NwM4IA4gASkDQDcDQCAGIA0pAwA3AwAgBiANKQMINwMIIAYgDSkDEDcDECAGIA0pAxg3AxggBiANKQMgNwMgIAYgDSkDKDcDKCAGIA0pAzA3AzAgBiANKQM4NwM4IAYgDSkDQDcDQCAGEBogBhAaIAYQGiAPIA4pAwA3AwAgDyAOKQMINwMIIA8gDikDEDcDECAPIA4pAxg3AxggDyAOKQMgNwMgIA8gDikDKDcDKCAPIA4pAzA3AzAgDyAOKQM4NwM4IA8gDikDQDcDQCACIAspAwA3AwAgAiALKQMINwMIIAIgCykDEDcDECACIAspAxg3AxggAiALKQMgNwMgIAIgCykDKDcDKCACIAspAzA3AzAgAiALKQM4NwM4IAIgCykDQDcDQCACIA4QFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAcpAwA3AwAgAiAHKQMINwMIIAIgBykDEDcDECACIAcpAxg3AxggAiAHKQMgNwMgIAIgBykDKDcDKCACIAcpAzA3AzAgAiAHKQM4NwM4IAIgBykDQDcDQCACIAMQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgAiAFKQMANwMAIAIgBSkDCDcDCCACIAUpAxA3AxAgAiAFKQMYNwMYIAIgBSkDIDcDICACIAUpAyg3AyggAiAFKQMwNwMwIAIgBSkDODcDOCACIAUpA0A3A0AgAiAGEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgECABKQMANwMAIBAgASkDCDcDCCAQIAEpAxA3AxAgECABKQMYNwMYIBAgASkDIDcDICAQIAEpAyg3AyggECABKQMwNwMwIBAgASkDODcDOCAQIAEpA0A3A0AgAiAMKQIANwIAIAIgDCkCCDcCCCACIAwpAhA3AhAgAiAMKQIYNwIYIAIgDCkCIDcCICACIAwpAig3AiggAiAMKQIwNwIwIAIgDCkCODcCOCACIAwpAkA3AkAgAiAMEBUgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0ACQAJAIAEoAgAiBEEIRgRAQQghCAJAAkACQANAIAhBf2ohBCAIRQ0FIARBEE8NASABQQRqIARBAnRqKAIAIgggBEECdEHECWooAgAiAkcNAiAEIQgMAAsAC0G8CyAEQRAQKAwBCyAIIAJPDQILBSAEQQhPDQELDAELIAFBwAkQFgsgCiABKQMANwMAIAogASkDCDcDCCAKIAEpAxA3AxAgCiABKQMYNwMYIAogASkDIDcDICAKIAEpAyg3AyggCiABKQMwNwMwIAogASkDODcDOCAKIAEpA0A3A0AgDAwBCyACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAAQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgCSABKQMANwMAIAkgASkDCDcDCCAJIAEpAxA3AxAgCSABKQMYNwMYIAkgASkDIDcDICAJIAEpAyg3AyggCSABKQMwNwMwIAkgASkDODcDOCAJIAEpA0A3A0AgAiAAQcgAaiIMKQIANwIAIAIgDCkCCDcCCCACIAwpAhA3AhAgAiAMKQIYNwIYIAIgDCkCIDcCICACIAwpAig3AiggAiAMKQIwNwIwIAIgDCkCODcCOCACIAwpAkA3AkAgAiAMEBcgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgARAbIAQgASkDADcDACAEIAEpAwg3AwggBCABKQMQNwMQIAQgASkDGDcDGCAEIAEpAyA3AyAgBCABKQMoNwMoIAQgASkDMDcDMCAEIAEpAzg3AzggBCABKQNANwNAIAIgBCkDADcDACACIAQpAwg3AwggAiAEKQMQNwMQIAIgBCkDGDcDGCACIAQpAyA3AyAgAiAEKQMoNwMoIAIgBCkDMDcDMCACIAQpAzg3AzggAiAEKQNANwNAIAIgBBAXIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAEQGyANIAEpAwA3AwAgDSABKQMINwMIIA0gASkDEDcDECANIAEpAxg3AxggDSABKQMgNwMgIA0gASkDKDcDKCANIAEpAzA3AzAgDSABKQM4NwM4IA0gASkDQDcDQCACIAApAgA3AgAgAiAAKQIINwIIIAIgACkCEDcCECACIAApAhg3AhggAiAAKQIgNwIgIAIgACkCKDcCKCACIAApAjA3AjAgAiAAKQI4NwI4IAIgACkCQDcCQCACIAQQFSABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQAJAAkAgASgCACIEQQhGBEBBCCEIAkACQAJAA0AgCEF/aiEEIAhFDQUgBEEQTw0BIAFBBGogBEECdGooAgAiCCAEQQJ0QcQJaigCACITRw0CIAQhCAwACwALQbwLIARBEBAoDAELIAggE08NAgsFIARBCE8NAQsMAQsgAUHACRAWCyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACIAMQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgAiAFKQMANwMAIAIgBSkDCDcDCCACIAUpAxA3AxAgAiAFKQMYNwMYIAIgBSkDIDcDICACIAUpAyg3AyggAiAFKQMwNwMwIAIgBSkDODcDOCACIAUpA0A3A0AgAiAJEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgBiABKQMANwMAIAYgASkDCDcDCCAGIAEpAxA3AxAgBiABKQMYNwMYIAYgASkDIDcDICAGIAEpAyg3AyggBiABKQMwNwMwIAYgASkDODcDOCAGIAEpA0A3A0AgAiAGKQMANwMAIAIgBikDCDcDCCACIAYpAxA3AxAgAiAGKQMYNwMYIAIgBikDIDcDICACIAYpAyg3AyggAiAGKQMwNwMwIAIgBikDODcDOCACIAYpA0A3A0AgAiANEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgCyABKQMANwMAIAsgASkDCDcDCCALIAEpAxA3AxAgCyABKQMYNwMYIAsgASkDIDcDICALIAEpAyg3AyggCyABKQMwNwMwIAsgASkDODcDOCALIAEpA0A3A0AgCxAaIAIgCSkDADcDACACIAkpAwg3AwggAiAJKQMQNwMQIAIgCSkDGDcDGCACIAkpAyA3AyAgAiAJKQMoNwMoIAIgCSkDMDcDMCACIAkpAzg3AzggAiAJKQNANwNAIAIgCRAVIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgRBCEYEQEEIIQgCQAJAAkADQCAIQX9qIQQgCEUNBSAEQRBPDQEgAUEEaiAEQQJ0aigCACIIIARBAnRBxAlqKAIAIhNHDQIgBCEIDAALAAtBvAsgBEEQECgMAQsgCCATTw0CCwUgBEEITw0BCwwBCyABQcAJEBYLIAMgASkDADcDACADIAEpAwg3AwggAyABKQMQNwMQIAMgASkDGDcDGCADIAEpAyA3AyAgAyABKQMoNwMoIAMgASkDMDcDMCADIAEpAzg3AzggAyABKQNANwNAIAIgAykDADcDACACIAMpAwg3AwggAiADKQMQNwMQIAIgAykDGDcDGCACIAMpAyA3AyAgAiADKQMoNwMoIAIgAykDMDcDMCACIAMpAzg3AzggAiADKQNANwNAIAIgCRAVIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgRBCEYEQEEIIQgCQAJAAkADQCAIQX9qIQQgCEUNBSAEQRBPDQEgAUEEaiAEQQJ0aigCACIIIARBAnRBxAlqKAIAIglHDQIgBCEIDAALAAtBvAsgBEEQECgMAQsgCCAJTw0CCwUgBEEITw0BCwwBCyABQcAJEBYLIAcgASkDADcDACAHIAEpAwg3AwggByABKQMQNwMQIAcgASkDGDcDGCAHIAEpAyA3AyAgByABKQMoNwMoIAcgASkDMDcDMCAHIAEpAzg3AzggByABKQNANwNAIAIgBykDADcDACACIAcpAwg3AwggAiAHKQMQNwMQIAIgBykDGDcDGCACIAcpAyA3AyAgAiAHKQMoNwMoIAIgBykDMDcDMCACIAcpAzg3AzggAiAHKQNANwNAIAIgBxAXIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAIAEQGyAOIAEpAwA3AwAgDiABKQMINwMIIA4gASkDEDcDECAOIAEpAxg3AxggDiABKQMgNwMgIA4gASkDKDcDKCAOIAEpAzA3AzAgDiABKQM4NwM4IA4gASkDQDcDQCAGIA0pAwA3AwAgBiANKQMINwMIIAYgDSkDEDcDECAGIA0pAxg3AxggBiANKQMgNwMgIAYgDSkDKDcDKCAGIA0pAzA3AzAgBiANKQM4NwM4IAYgDSkDQDcDQCAGEBogBhAaIAYQGiACIA4pAwA3AwAgAiAOKQMINwMIIAIgDikDEDcDECACIA4pAxg3AxggAiAOKQMgNwMgIAIgDikDKDcDKCACIA4pAzA3AzAgAiAOKQM4NwM4IAIgDikDQDcDQCACIAsQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAMpAwA3AwAgAiADKQMINwMIIAIgAykDEDcDECACIAMpAxg3AxggAiADKQMgNwMgIAIgAykDKDcDKCACIAMpAzA3AzAgAiADKQM4NwM4IAIgAykDQDcDQCACIAsQFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyAPIAEpAwA3AwAgDyABKQMINwMIIA8gASkDEDcDECAPIAEpAxg3AxggDyABKQMgNwMgIA8gASkDKDcDKCAPIAEpAzA3AzAgDyABKQM4NwM4IA8gASkDQDcDQCACIAspAwA3AwAgAiALKQMINwMIIAIgCykDEDcDECACIAspAxg3AxggAiALKQMgNwMgIAIgCykDKDcDKCACIAspAzA3AzAgAiALKQM4NwM4IAIgCykDQDcDQCACIA8QFiABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABLABEBEAgAUHACRAVCyADIAEpAwA3AwAgAyABKQMINwMIIAMgASkDEDcDECADIAEpAxg3AxggAyABKQMgNwMgIAMgASkDKDcDKCADIAEpAzA3AzAgAyABKQM4NwM4IAMgASkDQDcDQCACIAcpAwA3AwAgAiAHKQMINwMIIAIgBykDEDcDECACIAcpAxg3AxggAiAHKQMgNwMgIAIgBykDKDcDKCACIAcpAzA3AzAgAiAHKQM4NwM4IAIgBykDQDcDQCACIAMQFyABIAIpAwA3AwAgASACKQMINwMIIAEgAikDEDcDECABIAIpAxg3AxggASACKQMgNwMgIAEgAikDKDcDKCABIAIpAzA3AzAgASACKQM4NwM4IAEgAikDQDcDQCABEBsgBSABKQMANwMAIAUgASkDCDcDCCAFIAEpAxA3AxAgBSABKQMYNwMYIAUgASkDIDcDICAFIAEpAyg3AyggBSABKQMwNwMwIAUgASkDODcDOCAFIAEpA0A3A0AgAiAFKQMANwMAIAIgBSkDCDcDCCACIAUpAxA3AxAgAiAFKQMYNwMYIAIgBSkDIDcDICACIAUpAyg3AyggAiAFKQMwNwMwIAIgBSkDODcDOCACIAUpA0A3A0AgAiAGEBYgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgASwARARAIAFBwAkQFQsgECABKQMANwMAIBAgASkDCDcDCCAQIAEpAxA3AxAgECABKQMYNwMYIBAgASkDIDcDICAQIAEpAyg3AyggECABKQMwNwMwIBAgASkDODcDOCAQIAEpA0A3A0AgAiAMKQIANwIAIAIgDCkCCDcCCCACIAwpAhA3AhAgAiAMKQIYNwIYIAIgDCkCIDcCICACIAwpAig3AiggAiAMKQIwNwIwIAIgDCkCODcCOCACIAwpAkA3AkAgAiASEBcgASACKQMANwMAIAEgAikDCDcDCCABIAIpAxA3AxAgASACKQMYNwMYIAEgAikDIDcDICABIAIpAyg3AyggASACKQMwNwMwIAEgAikDODcDOCABIAIpA0A3A0AgARAbIAogASkDADcDACAKIAEpAwg3AwggCiABKQMQNwMQIAogASkDGDcDGCAKIAEpAyA3AyAgCiABKQMoNwMoIAogASkDMDcDMCAKIAEpAzg3AzggCiABKQNANwNAIAIgCikDADcDACACIAopAwg3AwggAiAKKQMQNwMQIAIgCikDGDcDGCACIAopAyA3AyAgAiAKKQMoNwMoIAIgCikDMDcDMCACIAopAzg3AzggAiAKKQNANwNAIAIgChAVIAEgAikDADcDACABIAIpAwg3AwggASACKQMQNwMQIAEgAikDGDcDGCABIAIpAyA3AyAgASACKQMoNwMoIAEgAikDMDcDMCABIAIpAzg3AzggASACKQNANwNAAkACQCABKAIAIgRBCEYEQEEIIQgCQAJAAkADQCAIQX9qIQQgCEUNBSAEQRBPDQEgAUEEaiAEQQJ0aigCACIIIARBAnRBxAlqKAIAIgJHDQIgBCEIDAALAAtBvAsgBEEQECgM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ACAAIAEoAgQ2AgQgACABKAIINgIIIAAgASgCDDYCDCAAIAEoAhA2AhAgACABKAIUNgIUIAAgASgCGDYCGCAAIAEoAhw2AhwgACABKAIgNgIgIAAgASgCJDYCJCAAIAEoAig2AiggACABKAIsNgIsIAAgASgCMDYCMCAAIAEoAjQ2AjQgACABKAI4NgI4IAAgASgCPDYCPCAAQcAAaiEAIAFBwABqIQEMAQsLA0AgACACSARAIAAgASgCADYCACAAQQRqIQAgAUEEaiEBDAELCwUgA0EEayECA0AgACACSARAIAAgASwAADoAACAAIAEsAAE6AAEgACABLAACOgACIAAgASwAAzoAAyAAQQRqIQAgAUEEaiEBDAELCwsDQCAAIANIBEAgACABLAAAOgAAIABBAWohACABQQFqIQEMAQsLIAQLCwsAAn9BABAAQQALCwsAAn9BARAAQQALCwsAAn9BAhAAQQALCwu9DA0AQYAIC+QBAQAAAAAAAACCgAAAAAAAAIqAAAAAAACAAIAAgAAAAICLgAAAAAAAAAEAAIAAAAAAgYAAgAAAAIAJgAAAAAAAgIoAAAAAAAAAiAAAAAAAAAAJgACAAAAAAAoAAIAAAAAAi4AAgAAAAACLAAAAAAAAgImAAAAAAACAA4AAAAAAAIACgAAAAAAAgIAAAAAAAACACoAAAAAAAAAKAACAAAAAgIGAAIAAAACAgIAAAAAAAIABAACAAAAAAAiAAIAAAACACAAAAC/8///+////////////////////////////////////AEGICgsFAQAAAAEAQdAKCzyxCQAAIgAAAPYCAABYCQAAWQAAADwBAAAIAAAAQUE20Ixe0r87oEiv5tyuuv7///////////////////8AQbALC6kBMwoAACIAAADwAgAA0wkAAGAAAAA9AAAA0wkAAGAAAACBAAAA0wkAAGAAAACLAAAA0wkAAGAAAACTAAAA0wkAAGAAAACbAAAA0wkAAGAAAADvAAAA0wkAAGAAAAD3AAAA0wkAAGAAAAC6AAAA0wkAAGAAAABeAQAA0wkAAGAAAAAxAQAA0wkAAGAAAAAyAQAA0wkAAGAAAAA4AQAA0wkAAGAAAAA9AQAAAQBBoA0LadMJAABgAAAAbgMAAFUKAABcAAAAEAAAADMKAAAiAAAA9gIAANMJAABgAAAAHgQAABQLAAAoAAAAsQoAAGMAAABCAAAAsQoAAGMAAAA9AAAAsQoAAGMAAABQAAAAsQoAAGMAAABSAAAAAQBB0A4LAQEAQZgPC00BAAAAXgsAACAAAAB+CwAAEgAAAFgMAAAGAAAAXgwAACIAAAA8CwAAIgAAAKACAACADAAAFgAAAJYMAAANAAAAPAsAACIAAACmAgAABQBB8A8LAQEAQYgQCw4BAAAAAgAAALRfAAAABABBoBALAQEAQa8QCwUK/////wBBnBILAiRZAEHUEgvPBuQHAAAvaG9tZS9tYWNpZWovLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvdGlueS1rZWNjYWstMS4yLjEvc3JjL2xpYi5ycy9jaGVja291dC9zcmMvbGliY29yZS9zbGljZS9tb2QucnMvaG9tZS9tYWNpZWovLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvdGlueS1zZWNwMjU2azEtMC4xLjAvc3JjL2JpZ19udW0ucnMvY2hlY2tvdXQvc3JjL2xpYmNvcmUvc2xpY2UvbW9kLnJzL2hvbWUvbWFjaWVqLy5jYXJnby9yZWdpc3RyeS9zcmMvZ2l0aHViLmNvbS0xZWNjNjI5OWRiOWVjODIzL3Rpbnktc2VjcDI1NmsxLTAuMS4wL3NyYy9uYWYucnMvaG9tZS9tYWNpZWovLmNhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvdGlueS1zZWNwMjU2azEtMC4xLjAvc3JjL2VjX3BvaW50X2cucnNpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlL2NoZWNrb3V0L3NyYy9saWJjb3JlL3NsaWNlL21vZC5yc2luZGV4IG91dCBvZiBib3VuZHM6IHRoZSBsZW4gaXMgIGJ1dCB0aGUgaW5kZXggaXMgMDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggc2xpY2UgaW5kZXggc3RhcnRzIGF0ICBidXQgZW5kcyBhdCA=', 'base64'); diff --git a/js/src/api/local/ethkey/index.js b/js/src/api/local/ethkey/index.js index a6967da25..07ca34ba1 100644 --- a/js/src/api/local/ethkey/index.js +++ b/js/src/api/local/ethkey/index.js @@ -17,13 +17,12 @@ import workerPool from './workerPool'; export function createKeyObject (key, password) { - return workerPool.getWorker().action('createKeyObject', { key, password }) + return workerPool.action('createKeyObject', { key, password }) .then((obj) => JSON.parse(obj)); } export function decryptPrivateKey (keyObject, password) { return workerPool - .getWorker() .action('decryptPrivateKey', { keyObject, password }) .then((privateKey) => { if (privateKey) { @@ -40,9 +39,9 @@ export function phraseToAddress (phrase) { } export function phraseToWallet (phrase) { - return workerPool.getWorker().action('phraseToWallet', phrase); + return workerPool.action('phraseToWallet', phrase); } export function verifySecret (secret) { - return workerPool.getWorker().action('verifySecret', secret); + return workerPool.action('verifySecret', secret); } diff --git a/js/src/api/local/ethkey/index.spec.js b/js/src/api/local/ethkey/index.spec.js index 781c49b5c..ce4cc29df 100644 --- a/js/src/api/local/ethkey/index.spec.js +++ b/js/src/api/local/ethkey/index.spec.js @@ -17,7 +17,8 @@ import { randomPhrase } from '@parity/wordlist'; import { phraseToAddress, phraseToWallet } from './'; -describe('api/local/ethkey', () => { +// TODO: Skipping until Node.js 8.0 comes out and we can test WebAssembly +describe.skip('api/local/ethkey', () => { describe('phraseToAddress', function () { this.timeout(30000); diff --git a/js/src/api/local/ethkey/worker.js b/js/src/api/local/ethkey/worker.js index d5fce2a71..76ccf06b2 100644 --- a/js/src/api/local/ethkey/worker.js +++ b/js/src/api/local/ethkey/worker.js @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import secp256k1 from 'secp256k1'; -import { keccak_256 as keccak256 } from 'js-sha3'; - -import { bytesToHex } from '../../util/format'; +import { bytesToHex } from '~/api/util/format'; +import { extern, slice } from './ethkey.js'; const isWorker = typeof self !== 'undefined'; @@ -43,43 +41,40 @@ function route ({ action, payload }) { return null; } +const input = slice(extern._input_ptr(), 1024); +const secret = slice(extern._secret_ptr(), 32); +const publicKey = slice(extern._public_ptr(), 64); +const address = slice(extern._address_ptr(), 20); + +extern._ecpointg(); + const actions = { phraseToWallet (phrase) { - let secret = keccak256.array(phrase); + const phraseUtf8 = Buffer.from(phrase, 'utf8'); - for (let i = 0; i < 16384; i++) { - secret = keccak256.array(secret); + if (phraseUtf8.length > input.length) { + throw new Error('Phrase is too long!'); } - while (true) { - secret = keccak256.array(secret); + input.set(phraseUtf8); - const secretBuf = Buffer.from(secret); + extern._brain(phraseUtf8.length); - if (secp256k1.privateKeyVerify(secretBuf)) { - // No compression, slice out last 64 bytes - const publicBuf = secp256k1.publicKeyCreate(secretBuf, false).slice(-64); - const address = keccak256.array(publicBuf).slice(12); + const wallet = { + secret: bytesToHex(secret), + public: bytesToHex(publicKey), + address: bytesToHex(address) + }; - if (address[0] !== 0) { - continue; - } - - const wallet = { - secret: bytesToHex(secretBuf), - public: bytesToHex(publicBuf), - address: bytesToHex(address) - }; - - return wallet; - } - } + return wallet; }, - verifySecret (secret) { - const key = Buffer.from(secret.slice(2), 'hex'); + verifySecret (key) { + const keyBuf = Buffer.from(key.slice(2), 'hex'); - return secp256k1.privateKeyVerify(key); + secret.set(keyBuf); + + return extern._verify_secret(); }, createKeyObject ({ key, password }) { @@ -113,7 +108,8 @@ self.onmessage = function ({ data }) { postMessage([null, result]); } catch (err) { - postMessage([err, null]); + console.error(err); + postMessage([err.toString(), null]); } }; diff --git a/js/src/api/local/ethkey/workerPool.js b/js/src/api/local/ethkey/workerPool.js index e4e4a5134..d7db73b41 100644 --- a/js/src/api/local/ethkey/workerPool.js +++ b/js/src/api/local/ethkey/workerPool.js @@ -38,7 +38,8 @@ class WorkerContainer { this.busy = false; if (err) { - reject(err); + // `err` ought to be a String + reject(new Error(err)); } else { resolve(result); } @@ -48,20 +49,56 @@ class WorkerContainer { } class WorkerPool { - pool = []; + pool = [ + new WorkerContainer(), + new WorkerContainer() + ]; - getWorker () { + queue = []; + + _getContainer () { + return this.pool.find((container) => !container.busy); + } + + action (action, payload) { let container = this.pool.find((container) => !container.busy); + let promise; + + // const start = Date.now(); + if (container) { - return container; + promise = container.action(action, payload); + } else { + promise = new Promise((resolve, reject) => { + this.queue.push([action, payload, resolve]); + }); } - container = new WorkerContainer(); + return promise + .catch((err) => { + this.processQueue(); - this.pool.push(container); + throw err; + }) + .then((result) => { + this.processQueue(); - return container; + // console.log('Work done in ', Date.now() - start); + + return result; + }); + } + + processQueue () { + let container = this._getContainer(); + + while (container && this.queue.length > 0) { + const [action, payload, resolve] = this.queue.shift(); + + resolve(container.action(action, payload)); + container = this._getContainer(); + } } } diff --git a/js/src/api/local/localAccountsMiddleware.js b/js/src/api/local/localAccountsMiddleware.js index 753de8a4c..457574715 100644 --- a/js/src/api/local/localAccountsMiddleware.js +++ b/js/src/api/local/localAccountsMiddleware.js @@ -29,7 +29,7 @@ export default class LocalAccountsMiddleware extends Middleware { const register = this.register.bind(this); register('eth_accounts', () => { - return accounts.mapArray((account) => account.address); + return accounts.addresses(); }); register('eth_coinbase', () => { @@ -37,13 +37,13 @@ export default class LocalAccountsMiddleware extends Middleware { }); register('parity_accountsInfo', () => { - return accounts.mapObject(({ name }) => { + return accounts.map(({ name }) => { return { name }; }); }); register('parity_allAccountsInfo', () => { - return accounts.mapObject(({ name, meta, uuid }) => { + return accounts.map(({ name, meta, uuid }) => { return { name, meta, uuid }; }); }); @@ -68,10 +68,31 @@ export default class LocalAccountsMiddleware extends Middleware { return transactions.hash(id) || Promise.resolve(null); }); + register('parity_dappsList', () => { + return []; + }); + register('parity_defaultAccount', () => { return accounts.lastAddress; }); + register('parity_exportAccount', ([address, password]) => { + const account = accounts.get(address); + + if (!password) { + password = ''; + } + + return account.isValidPassword(password) + .then((isValid) => { + if (!isValid) { + throw new Error('Invalid password'); + } + + return account.export(); + }); + }); + register('parity_generateSecretPhrase', () => { return randomPhrase(12); }); @@ -80,6 +101,10 @@ export default class LocalAccountsMiddleware extends Middleware { return []; }); + register('parity_getNewDappsDefaultAddress', () => { + return accounts.lastAddress; + }); + register('parity_hardwareAccountsInfo', () => { return {}; }); @@ -102,18 +127,30 @@ export default class LocalAccountsMiddleware extends Middleware { }); }); + register('parity_newAccountFromWallet', ([json, password]) => { + if (!password) { + password = ''; + } + + return accounts.restoreFromWallet(JSON.parse(json), password); + }); + register('parity_setAccountMeta', ([address, meta]) => { - accounts.get(address).meta = meta; + accounts.getLazyCreate(address).meta = meta; return true; }); register('parity_setAccountName', ([address, name]) => { - accounts.get(address).name = name; + accounts.getLazyCreate(address).name = name; return true; }); + register('parity_setNewDappsDefaultAddress', ([address]) => { + accounts.dappsDefaultAddress = address; + }); + register('parity_postTransaction', ([tx]) => { if (!tx.from) { tx.from = accounts.lastAddress; @@ -137,10 +174,32 @@ export default class LocalAccountsMiddleware extends Middleware { return []; }); + register('parity_listOpenedVaults', () => { + return []; + }); + register('parity_listRecentDapps', () => { return {}; }); + register('parity_listVaults', () => { + return []; + }); + + register('parity_wsUrl', () => { + // This is a hack, will be replaced by a `hostname` setting on the node itself + return `${window.location.hostname}:8546`; + }); + + register('parity_dappsUrl', () => { + // This is a hack, will be replaced by a `hostname` setting on the node itself + return `${window.location.hostname}:8545`; + }); + + register('parity_hashContent', () => { + throw new Error('Functionality unavailable on a public wallet.'); + }); + register('parity_killAccount', ([address, password]) => { return accounts.remove(address, password); }); @@ -204,6 +263,10 @@ export default class LocalAccountsMiddleware extends Middleware { }); }); + register('signer_generateAuthorizationToken', () => { + return ''; + }); + register('signer_rejectRequest', ([id]) => { return transactions.reject(id); }); diff --git a/js/src/api/local/localAccountsMiddleware.spec.js b/js/src/api/local/localAccountsMiddleware.spec.js index 00f5f4dca..9b065bf22 100644 --- a/js/src/api/local/localAccountsMiddleware.spec.js +++ b/js/src/api/local/localAccountsMiddleware.spec.js @@ -32,7 +32,8 @@ class MockedTransport extends JsonRpcBase { } } -describe('api/local/LocalAccountsMiddleware', function () { +// Skip till all CI runs on Node 8+ +describe.skip('api/local/LocalAccountsMiddleware', function () { this.timeout(30000); let transport; @@ -71,7 +72,9 @@ describe('api/local/LocalAccountsMiddleware', function () { 'parity_phraseToAddress', 'parity_useLocalAccounts', 'parity_listGethAccounts', + 'parity_listOpenedVaults', 'parity_listRecentDapps', + 'parity_listVaults', 'parity_killAccount', 'parity_testPassword', 'signer_confirmRequest', diff --git a/js/src/dapps/dappreg/Application/application.js b/js/src/dapps/dappreg/Application/application.js index 4c3a567c2..b33aa0b96 100644 --- a/js/src/dapps/dappreg/Application/application.js +++ b/js/src/dapps/dappreg/Application/application.js @@ -42,7 +42,7 @@ export default class Application extends Component { return (
- DAPP REGISTRY, a global view of distributed applications available on the network. Putting the puzzle together. + DAPP REGISTRY, a global view of decentralized applications available on the network. Putting the puzzle together.
diff --git a/js/src/dapps/dappreg/ModalDelete/modalDelete.js b/js/src/dapps/dappreg/ModalDelete/modalDelete.js index e64c315fa..20ca64067 100644 --- a/js/src/dapps/dappreg/ModalDelete/modalDelete.js +++ b/js/src/dapps/dappreg/ModalDelete/modalDelete.js @@ -43,7 +43,7 @@ export default class ModalDelete extends Component { secondary >
- You are about to remove a distributed application from the registry, + You are about to remove a decentralized application from the registry, the details of this application is given below. Removal does not return any fees, however the application will not be available to users anymore.
diff --git a/js/src/dapps/dappreg/ModalRegister/modalRegister.js b/js/src/dapps/dappreg/ModalRegister/modalRegister.js index 0c8bd0b9a..ee4d2a374 100644 --- a/js/src/dapps/dappreg/ModalRegister/modalRegister.js +++ b/js/src/dapps/dappreg/ModalRegister/modalRegister.js @@ -50,7 +50,7 @@ export default class ModalRegister extends Component { secondary >
- You are about to register a new distributed application on the network, the details of + You are about to register a new decentralized application on the network, the details of this application is given below. This will require a non-refundable fee of { api.util.fromWei(this.dappsStore.fee).toFormat(3) } ETH
diff --git a/js/src/i18n/_default/extension.js b/js/src/i18n/_default/extension.js index 88ba33674..baa2efd4e 100644 --- a/js/src/i18n/_default/extension.js +++ b/js/src/i18n/_default/extension.js @@ -16,5 +16,5 @@ export default { install: `Install the extension now`, - intro: `Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. It is highly recommended that you install this extension to further enhance your Parity experience.` + intro: `Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled decentralized applications. It is highly recommended that you install this extension to further enhance your Parity experience.` }; diff --git a/js/src/i18n/_default/settings.js b/js/src/i18n/_default/settings.js index 3e475e087..ea447e4a9 100644 --- a/js/src/i18n/_default/settings.js +++ b/js/src/i18n/_default/settings.js @@ -69,7 +69,7 @@ export default { label: `Addressbook` }, apps: { - description: `Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and interact with application from around the network.`, + description: `Decentralized applications that interact with the underlying network. Add applications, manage you application portfolio and interact with application from around the network.`, label: `Applications` }, contracts: { @@ -85,7 +85,7 @@ export default { label: `Settings` }, signer: { - description: `The secure transaction management area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by distributed applications.`, + description: `The secure transaction management area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by decentralized applications.`, label: `Signer` }, status: { diff --git a/js/src/i18n/_default/tabBar.js b/js/src/i18n/_default/tabBar.js index 1692a1997..b704879e0 100644 --- a/js/src/i18n/_default/tabBar.js +++ b/js/src/i18n/_default/tabBar.js @@ -16,6 +16,6 @@ export default { tooltip: { - overview: `navigate between the different parts and views of the application, switching between an account view, token view and distributed application view` + overview: `navigate between the different parts and views of the application, switching between an account view, token view and decentralized application view` } }; diff --git a/js/src/i18n/zh-Hant-TW/extension.js b/js/src/i18n/zh-Hant-TW/extension.js index 5c0987038..0f017aa0f 100644 --- a/js/src/i18n/zh-Hant-TW/extension.js +++ b/js/src/i18n/zh-Hant-TW/extension.js @@ -17,6 +17,6 @@ export default { install: `現在就安裝這個擴充套件`, // Install the extension now intro: `Parity現在有一個Chrome的擴充套件,可以安全的瀏覽以太坊所支援的分散式應用。我們強烈推薦你安裝這個擴充套件來進一步提升你的Parity使用體驗。` - // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. + // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled decentralized applications. // It is highly recommended that you install this extension to further enhance your Parity experience. }; diff --git a/js/src/i18n/zh-Hant-TW/settings.js b/js/src/i18n/zh-Hant-TW/settings.js index bf026c384..8841279dc 100644 --- a/js/src/i18n/zh-Hant-TW/settings.js +++ b/js/src/i18n/zh-Hant-TW/settings.js @@ -82,7 +82,7 @@ export default { }, apps: { description: `與整個底層網路交流的分散式應用。新增應用,管理你的應用庫和與網路上的其他應用進行互動。`, - // Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and + // Decentralized applications that interact with the underlying network. Add applications, manage you application portfolio and // interact with application from around the network. label: `應用` // Applications }, @@ -108,7 +108,7 @@ export default { signer: { description: `這個應用安全交易管理區域,你可以通過任何從本應用和其他分散式應用發起的即將傳送的交易`, // The secure transaction management area of the application where you can approve any outgoing transactions made - // from the application as well as those placed into the queue by distributed applications. + // from the application as well as those placed into the queue by decentralized applications. label: `Signer` // Signer }, status: { diff --git a/js/src/i18n/zh-Hant-TW/tabBar.js b/js/src/i18n/zh-Hant-TW/tabBar.js index 73ccabf96..482c230fb 100644 --- a/js/src/i18n/zh-Hant-TW/tabBar.js +++ b/js/src/i18n/zh-Hant-TW/tabBar.js @@ -17,6 +17,6 @@ export default { tooltip: { overview: `在應用的不同部分和不同介面進行導航,在帳戶介面、代幣介面和分散式應用介面之間切換。` - // navigate between the different parts and views of the application, switching between an account view, token view and distributed application view + // navigate between the different parts and views of the application, switching between an account view, token view and decentralized application view } }; diff --git a/js/src/i18n/zh/extension.js b/js/src/i18n/zh/extension.js index e79c03667..609b76bcf 100644 --- a/js/src/i18n/zh/extension.js +++ b/js/src/i18n/zh/extension.js @@ -17,6 +17,6 @@ export default { install: `现在就安装这个扩展`, // Install the extension now intro: `Parity现在有一个Chrome的扩展,可以安全的浏览以太坊所支持的分布式应用。我们强烈推荐你安装这个扩展来进一步提升你的Parity使用体验。` - // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. + // Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled decentralized applications. // It is highly recommended that you install this extension to further enhance your Parity experience. }; diff --git a/js/src/i18n/zh/settings.js b/js/src/i18n/zh/settings.js index 3630caa45..4081a06d6 100644 --- a/js/src/i18n/zh/settings.js +++ b/js/src/i18n/zh/settings.js @@ -82,7 +82,7 @@ export default { }, apps: { description: `与整个底层网络交流的分布式应用。添加应用,管理你的应用库和与网络上的其他应用进行交互。`, - // Distributed applications that interact with the underlying network. Add applications, manage you application portfolio and + // Decentralized applications that interact with the underlying network. Add applications, manage you application portfolio and // interact with application from around the network. label: `应用` // Applications }, @@ -108,7 +108,7 @@ export default { signer: { description: `这个应用安全交易管理区域,你可以通过任何从本应用和其他分布式应用发起的即将发送的交易`, // The secure transaction management area of the application where you can approve any outgoing transactions made - // from the application as well as those placed into the queue by distributed applications. + // from the application as well as those placed into the queue by decentralized applications. label: `Signer` // Signer }, status: { diff --git a/js/src/i18n/zh/tabBar.js b/js/src/i18n/zh/tabBar.js index 7521c1b33..08a0a816f 100644 --- a/js/src/i18n/zh/tabBar.js +++ b/js/src/i18n/zh/tabBar.js @@ -17,6 +17,6 @@ export default { tooltip: { overview: `在应用的不同部分和不同界面进行导航,在账户界面、代币界面和分布式应用界面之间切换。` - // navigate between the different parts and views of the application, switching between an account view, token view and distributed application view + // navigate between the different parts and views of the application, switching between an account view, token view and decentralized application view } }; diff --git a/js/src/lib.rs.in b/js/src/lib.rs.in index 2dabd46c5..220811656 100644 --- a/js/src/lib.rs.in +++ b/js/src/lib.rs.in @@ -42,7 +42,7 @@ impl WebApp for App { Info { name: "Parity UI", version: env!("CARGO_PKG_VERSION"), - author: "Ethcore ", + author: "Parity ", description: "New UI for Parity.", icon_url: "icon.png", } diff --git a/js/src/shared/config/dappsBuiltin.json b/js/src/shared/config/dappsBuiltin.json index 5cc789622..55096a26e 100644 --- a/js/src/shared/config/dappsBuiltin.json +++ b/js/src/shared/config/dappsBuiltin.json @@ -64,7 +64,8 @@ "author": "Parity Team ", "version": "1.0.0", "visible": false, - "secure": true + "secure": true, + "onlyPersonal": true }, { "id": "0xae74ad174b95cdbd01c88ac5b73a296d33e9088fc2a200e76bcedf3a94a7815d", @@ -95,6 +96,7 @@ "version": "1.0.0", "visible": true, "skipBuild": true, - "skipHistory": true + "skipHistory": true, + "onlyPersonal": true } ] diff --git a/js/src/shell/Dapps/dapps.js b/js/src/shell/Dapps/dapps.js index e1b67db66..786c49939 100644 --- a/js/src/shell/Dapps/dapps.js +++ b/js/src/shell/Dapps/dapps.js @@ -35,10 +35,11 @@ import styles from './dapps.css'; class Dapps extends Component { static contextTypes = { api: PropTypes.object.isRequired - } + }; static propTypes = { - accounts: PropTypes.object.isRequired + accounts: PropTypes.object.isRequired, + availability: PropTypes.string.isRequired }; store = DappsStore.get(this.context.api); @@ -135,6 +136,10 @@ class Dapps extends Component { } renderApp = (app) => { + if (app.onlyPersonal && this.props.availability !== 'personal') { + return null; + } + return ( account.wallet); return { - accounts: _accounts + accounts: _accounts, + availability }; } diff --git a/js/src/shell/Extension/extension.js b/js/src/shell/Extension/extension.js index f96dc3bb9..1e0a4b71e 100644 --- a/js/src/shell/Extension/extension.js +++ b/js/src/shell/Extension/extension.js @@ -46,7 +46,7 @@ export default class Extension extends Component {

diff --git a/js/src/shell/FirstRun/TnC/tnc.js b/js/src/shell/FirstRun/TnC/tnc.js index d19be463a..38779a6ee 100644 --- a/js/src/shell/FirstRun/TnC/tnc.js +++ b/js/src/shell/FirstRun/TnC/tnc.js @@ -38,124 +38,124 @@ export default function TnC ({ hasAccepted, onAccept }) {

  • The user represents that the user has an adequate understanding of the risks, usage and intricacies of cryptographic tokens and blockchain-based open source software, eth platform and eth.
  • The user acknowledges and agrees that, to the fullest extent permitted by any applicable law, the disclaimers of liability contained herein apply to any and all damages or injury whatsoever caused by or related to risks of, use of, or inability to use, Parity under any cause or action whatsoever of any kind in any jurisdiction, including, without limitation, actions for breach of warranty, breach of contract or tort (including negligence) and that Eth Core Limited shall be not liable for any indirect, incidental, special, exemplary or consequential damages, including for loss of profits, goodwill or data.
  • Some jurisdictions do not allow the exclusion of certain warranties or the limitation or exclusion of liability for certain types of damages. Therefore, some of the above limitations in this section may not apply to a user. In particular, nothing in these terms shall affect the statutory rights of any user or exclude injury arising from any wilful misconduct or fraud of Eth Core Limited.
  • -
  • All rights reserved by Ethcore. Licensed to the public under the GPL v3 https://www.gnu.org/licenses/gpl-3.0.txt
  • +
  • All rights reserved by Parity. Licensed to the public under the GPL v3 https://www.gnu.org/licenses/gpl-3.0.txt
  • LONG VERSION

    -

    The following Terms and Conditions (“Terms”) govern the use of Parity Technologies Limited’s open source software product (“Parity”). Prior to any use of the Parity or any of Parity Technologies Limited’s products (“EthCore’s Products”), the user or anyone on whose behalf the software is used for directly or indirectly (“User”) confirms that they understand and expressly agree to all of the Terms. All capitalized terms in this agreement will be given the same effect and meaning as in the Terms. The group of developers and other personnel that is now, or will be, employed by, or contracted with, or affiliated with, Parity Technologies Limited (“EthCore”) is termed the “EthCore Team”.

    +

    The following Terms and Conditions (“Terms”) govern the use of Parity Technologies Limited’s open source software product (“Parity”). Prior to any use of the Parity or any of Parity Technologies Limited’s products (“Parity’s Products”), the user or anyone on whose behalf the software is used for directly or indirectly (“User”) confirms that they understand and expressly agree to all of the Terms. All capitalized terms in this agreement will be given the same effect and meaning as in the Terms. The group of developers and other personnel that is now, or will be, employed by, or contracted with, or affiliated with, Parity Technologies Limited (“Parity”) is termed the “Parity Team”.

    Acknowledgement of Risks

    -

    The user acknowledges the following serious risks to any use Parity and expressly agrees not to hold liable EthCore or the EthCore Team should any of these risks occur:

    +

    The user acknowledges the following serious risks to any use Parity and expressly agrees not to hold liable Parity or the Parity Team should any of these risks occur:

    Risk of Security Weaknesses in the Parity Core Infrastructure Software

    -

    Parity rests on open-source software, and although it is professionally developed in line with industry standards (which include external audits of the code base), there is a risk that Ethcore or the Ethcore Team, may have introduce unintentional weaknesses or bugs into the core infrastructural elements of Parity causing the system to lose ETH stored in one or more User accounts or other accounts or lose sums of other valued tokens.

    +

    Parity rests on open-source software, and although it is professionally developed in line with industry standards (which include external audits of the code base), there is a risk that Parity or the Parity Team, may have introduce unintentional weaknesses or bugs into the core infrastructural elements of Parity causing the system to lose ETH stored in one or more User accounts or other accounts or lose sums of other valued tokens.

    Risk of Weaknesses or Exploitable Breakthroughs in the Field of Cryptography

    -

    Cryptography is an art, not a science. And the state of the art can advance over time Advances in code cracking, or technical advances such as the development of quantum computers, could present risks to cryptocurrencies and Parity, which could result in the theft or loss of ETH. To the extent possible, EthCore intends to update the protocol underlying Parity to account for any advances in cryptography and to incorporate additional security measures, but it cannot predict the future of cryptography or guaranty that any security updates will be made, timely or successful.

    +

    Cryptography is an art, not a science. And the state of the art can advance over time Advances in code cracking, or technical advances such as the development of quantum computers, could present risks to cryptocurrencies and Parity, which could result in the theft or loss of ETH. To the extent possible, Parity intends to update the protocol underlying Parity to account for any advances in cryptography and to incorporate additional security measures, but it cannot predict the future of cryptography or guaranty that any security updates will be made, timely or successful.

    Risk of Ether Mining Attacks

    -

    As with other cryptocurrencies, the blockchain used by Parity is susceptible to mining attacks, including but not limited to double-spend attacks, majority mining power attacks, “selfish-mining” attacks, and race condition attacks. Any successful attacks present a risk to the Ethereum ecosystem, expected proper execution and sequencing of ETH transactions, and expected proper execution and sequencing of contract computations. Despite the efforts of the EthCore and the EthCore Team, known or novel mining attacks may be successful.

    +

    As with other cryptocurrencies, the blockchain used by Parity is susceptible to mining attacks, including but not limited to double-spend attacks, majority mining power attacks, “selfish-mining” attacks, and race condition attacks. Any successful attacks present a risk to the Ethereum ecosystem, expected proper execution and sequencing of ETH transactions, and expected proper execution and sequencing of contract computations. Despite the efforts of the Parity and the Parity Team, known or novel mining attacks may be successful.

    Risk of Rapid Adoption and Insufficiency of Computational Application Processing Power on the Ethereum Network

    -

    If Parity is rapidly adopted, the demand for transaction processing and distributed application computations could rise dramatically and at a pace that exceeds the rate with which ETH miners can bring online additional mining power. Under such a scenario, the entire Ethereum ecosystem could become destabilized, due to the increased cost of running distributed applications. In turn, this could dampen interest in the Ethereum ecosystem and ETH. Insufficiency of computational resources and an associated rise in the price of ETH could result in businesses being unable to acquire scarce computational resources to run their distributed applications. This would represent revenue losses to businesses or worst case, cause businesses to cease operations because such operations have become uneconomical due to distortions in the crypto-economy.

    +

    If Parity is rapidly adopted, the demand for transaction processing and decentralized application computations could rise dramatically and at a pace that exceeds the rate with which ETH miners can bring online additional mining power. Under such a scenario, the entire Ethereum ecosystem could become destabilized, due to the increased cost of running decentralized applications. In turn, this could dampen interest in the Ethereum ecosystem and ETH. Insufficiency of computational resources and an associated rise in the price of ETH could result in businesses being unable to acquire scarce computational resources to run their decentralized applications. This would represent revenue losses to businesses or worst case, cause businesses to cease operations because such operations have become uneconomical due to distortions in the crypto-economy.

    Risk of temporary network incoherence

    We recommend any groups handling large or important transactions to maintain a voluntary 24 hour waiting period on any ether deposited. In case the integrity of the network is at risk due to issues in the clients, we will endeavour to publish patches in a timely fashion to address the issues. We will endeavour to provide solutions within the voluntary 24 hour waiting period.

    Use of Parity by you

    -

    You agree to use Party only for purposes that are permitted by (a) these Terms and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United Kingdom or other relevant countries).

    -

    You agree that you will not engage in any activity that interferes with or disrupts Parity’s or EthCore’s Products’ functioning (or the networks which are connected to Parity).

    -

    Unless you have been specifically permitted to do so in a separate agreement with EthCore, you agree that you will not reproduce, duplicate, copy, sell, trade or resell the EthCore’s Products for any purpose unless than in accordance to the terms of the software licence terms available here: https://www.gnu.org/licenses/gpl-3.0.txt (“Software Licence Terms”).

    -

    You agree that you are solely responsible for (and that EthCore has no responsibility to you or to any third party for) any breach of your obligations under these terms and for the consequences (including any loss or damage which EthCore may suffer) of any such breach.

    +

    You agree to use Parity only for purposes that are permitted by (a) these Terms and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United Kingdom or other relevant countries).

    +

    You agree that you will not engage in any activity that interferes with or disrupts Parity’s or Parity’s Products’ functioning (or the networks which are connected to Parity).

    +

    Unless you have been specifically permitted to do so in a separate agreement with Parity, you agree that you will not reproduce, duplicate, copy, sell, trade or resell the Parity’s Products for any purpose unless than in accordance to the terms of the software licence terms available here: https://www.gnu.org/licenses/gpl-3.0.txt (“Software Licence Terms”).

    +

    You agree that you are solely responsible for (and that Parity has no responsibility to you or to any third party for) any breach of your obligations under these terms and for the consequences (including any loss or damage which Parity may suffer) of any such breach.

    Privacy and your personal information

    -

    You agree to the use of your data (if any is gathered) in accordance with EthCore’s privacy policies: https://ethcore.io/legal.html. This policy explains how EthCore treats your personal information (if any is gathered), and protects your privacy, when you use EthCore’s Products.

    +

    You agree to the use of your data (if any is gathered) in accordance with Parity’s privacy policies: https://parity.io/legal.html. This policy explains how Parity treats your personal information (if any is gathered), and protects your privacy, when you use Parity’s Products.

    Content in Parity

    -

    You understand that all information and data (such as smart contracts, data files, written text, computer software, music, audio files or other sounds, photographs, videos or other images) which you may have access to as part of, or through your use of, EthCore’s Product are the sole responsibility of the person from which such content originated. All such information is referred to below as the “Content”.

    -

    You should be aware that Content presented to you through Parity or EthCore’s Product may be protected by intellectual property rights which are owned by thisrd parties who may provide that Content to EthCore (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this Content (either in whole or in part) unless you have been specifically told that you may do so by Ethcore or by the owners of that Content, in a separate agreement.

    -

    You understand that by using Parity or EthCore’s Products you may be exposed to Content that you may find offensive, indecent or objectionable and that, in this respect, you use Parity or EthCore’s Products at your own risk.

    -

    You agree that you are solely responsible for (and that EthCore has no responsibility to you or to any third party for) any Content that you create, transmit or display while using Parity or EthCore’s Products and for the consequences of your actions (including any loss or damage which EthCore may suffer) by doing so.

    +

    You understand that all information and data (such as smart contracts, data files, written text, computer software, music, audio files or other sounds, photographs, videos or other images) which you may have access to as part of, or through your use of, Parity’s Product are the sole responsibility of the person from which such content originated. All such information is referred to below as the “Content”.

    +

    You should be aware that Content presented to you through Parity or Parity’s Product may be protected by intellectual property rights which are owned by thisrd parties who may provide that Content to Parity (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this Content (either in whole or in part) unless you have been specifically told that you may do so by Parity or by the owners of that Content, in a separate agreement.

    +

    You understand that by using Parity or Parity’s Products you may be exposed to Content that you may find offensive, indecent or objectionable and that, in this respect, you use Parity or Parity’s Products at your own risk.

    +

    You agree that you are solely responsible for (and that Parity has no responsibility to you or to any third party for) any Content that you create, transmit or display while using Parity or Parity’s Products and for the consequences of your actions (including any loss or damage which Parity may suffer) by doing so.

    Proprietary rights

    -

    You acknowledge and agree that EthCore own all legal right, title and interest in and to the Parity and EthCore’s Products, including any intellectual property rights which subsist in Parity and EthCore’s Products (whether those rights happen to be registered or not, and wherever in the world those rights may exist).

    -

    Unless you have agreed otherwise in writing with EthCore, nothing in the Terms gives you a right to use any of EthCore’s trade names, trade marks, service marks, logos, domain names, and other distinctive brand features.

    -

    If you have been given an explicit right to use any of these brand features in a separate written agreement with EthCore, then you agree that your use of such features shall be in compliance with that agreement, any applicable provisions of these terms, and EthCore’s brand feature use guidelines as updated from time to time. These guidelines can be viewed online at https://ethcore.io/press.html.

    -

    EthCore acknowledges and agrees that it obtains no right, title or interest from you (or your licensors) under these terms in or to any content that you submit, post, transmit or display on, or through, Parity, including any intellectual property rights which subsist in that content (whether those rights happen to be registered or not, and wherever in the world those rights may exist). Unless you have agreed otherwise in writing with EthCore, you agree that you are responsible for protecting and enforcing those rights and that EthCore has no obligation to do so on your behalf.

    -

    You agree that you shall not remove, obscure, or alter any proprietary rights notices (including copyright and trade mark notices) which may be affixed to or contained within Parity or EthCore’s Products.

    -

    Unless you have been expressly authorized to do so in writing by EthCore, you agree that in using Parity, you will not use any trade mark, service mark, trade name, logo of any company or organization in a way that is likely or intended to cause confusion about the owner or authorized user of such marks, names or logos.

    +

    You acknowledge and agree that Parity own all legal right, title and interest in and to the Parity and Parity’s Products, including any intellectual property rights which subsist in Parity and Parity’s Products (whether those rights happen to be registered or not, and wherever in the world those rights may exist).

    +

    Unless you have agreed otherwise in writing with Parity, nothing in the Terms gives you a right to use any of Parity’s trade names, trade marks, service marks, logos, domain names, and other distinctive brand features.

    +

    If you have been given an explicit right to use any of these brand features in a separate written agreement with Parity, then you agree that your use of such features shall be in compliance with that agreement, any applicable provisions of these terms, and Parity’s brand feature use guidelines as updated from time to time. These guidelines can be viewed online at https://parity.io/press.html.

    +

    Parity acknowledges and agrees that it obtains no right, title or interest from you (or your licensors) under these terms in or to any content that you submit, post, transmit or display on, or through, Parity, including any intellectual property rights which subsist in that content (whether those rights happen to be registered or not, and wherever in the world those rights may exist). Unless you have agreed otherwise in writing with Parity, you agree that you are responsible for protecting and enforcing those rights and that Parity has no obligation to do so on your behalf.

    +

    You agree that you shall not remove, obscure, or alter any proprietary rights notices (including copyright and trade mark notices) which may be affixed to or contained within Parity or Parity’s Products.

    +

    Unless you have been expressly authorized to do so in writing by Parity, you agree that in using Parity, you will not use any trade mark, service mark, trade name, logo of any company or organization in a way that is likely or intended to cause confusion about the owner or authorized user of such marks, names or logos.

    -

    License Restrictions from EthCore

    -

    You may not (and you may not permit anyone else to) copy, modify, create a derivative work of, reverse engineer, decompile or otherwise attempt to extract the source code of the Parity, EthCore’s Products or any part thereof, unless this is expressly permitted by our Software Licence Terms or required by law, or unless you have been specifically told that you may do so by EthCore, in writing.

    -

    Unless EthCore has given you specific written permission to do so, you may not assign (or grant a sub-licence of) your rights to use EthCore’s Products, grant a security interest in or over your rights to use the EthCore’s Products, or otherwise transfer any part of your rights to use the EthCore’s Products.

    +

    License Restrictions from Parity

    +

    You may not (and you may not permit anyone else to) copy, modify, create a derivative work of, reverse engineer, decompile or otherwise attempt to extract the source code of the Parity, Parity’s Products or any part thereof, unless this is expressly permitted by our Software Licence Terms or required by law, or unless you have been specifically told that you may do so by Parity, in writing.

    +

    Unless Parity has given you specific written permission to do so, you may not assign (or grant a sub-licence of) your rights to use Parity’s Products, grant a security interest in or over your rights to use the Parity’s Products, or otherwise transfer any part of your rights to use the Parity’s Products.

    Content licence from you

    You retain copyright and any other rights you already hold in content which you submit, post or display on or through, Parity.

    -

    Ending your relationship with EthCore

    -

    The Terms will continue to apply until terminated by either you or EthCore as set out below.

    -

    EthCore may at any time, terminate its legal agreement with you if:

    +

    Ending your relationship with Parity

    +

    The Terms will continue to apply until terminated by either you or Parity as set out below.

    +

    Parity may at any time, terminate its legal agreement with you if:

    1. you have breached any provision of these Terms (or have acted in manner which clearly shows that you do not intend to, or are unable to comply with the provisions of these terms); or
    2. -
    3. EthCore is required to do so by law (for example, where the provision of EthCore’s Product to you is, or becomes, unlawful); or
    4. -
    5. the partner with whom EthCore offered products or services to you has terminated its relationship with EthCore or ceased to offer products or services to you; or
    6. -
    7. EthCore is transitioning to no longer providing products or services to users in the country in which you are resident or from which you use the service; or
    8. -
    9. the provision of products or services to you by EthCore is, in EthCore’s opinion, no longer commercially viable.
    10. -
    11. When these Terms come to an end, all of the legal rights, obligations and liabilities that you and EthCore have benefited from, been subject to (or which have accrued over time whilst the Terms have been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the England and Wales jurisdiction choice shall continue to apply to such rights, obligations and liabilities indefinitely.
    12. +
    13. Parity is required to do so by law (for example, where the provision of Parity’s Product to you is, or becomes, unlawful); or
    14. +
    15. the partner with whom Parity offered products or services to you has terminated its relationship with Parity or ceased to offer products or services to you; or
    16. +
    17. Parity is transitioning to no longer providing products or services to users in the country in which you are resident or from which you use the service; or
    18. +
    19. the provision of products or services to you by Parity is, in Parity’s opinion, no longer commercially viable.
    20. +
    21. When these Terms come to an end, all of the legal rights, obligations and liabilities that you and Parity have benefited from, been subject to (or which have accrued over time whilst the Terms have been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the England and Wales jurisdiction choice shall continue to apply to such rights, obligations and liabilities indefinitely.

    ACKNOWLEDGEMENT AND ACCEPTANCE OF ALL RISKS, EXCLUSION OF WARRANTIES

    -

    THE USER EXPRESSLY KNOWS AND AGREES THAT THE USER IS USING PARITY OR ETHCORE’S PRODUCTS AT THE USER’S SOLE RISK. THE USER REPRESENTS THAT THE USER HAS AN ADEQUATE UNDERSTANDING OF THE RISKS, USAGE AND INTRICACIES OF CRYPTOGRAPHIC TOKENS AND BLOCKCHAIN-BASED OPEN SOURCE SOFTWARE, PARITY.

    -

    YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF ETHCORE’S PRODUCTS IS AT YOUR SOLE RISK AND THAT ETHCORE’S PRODUCTS ARE PROVIDED "AS IS" AND “AS AVAILABLE.”

    -

    IN PARTICULAR, ETHCORE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS DO NOT REPRESENT OR WARRANT TO YOU THAT:

    -

    (A) YOUR USE OF PARITY OR ETHCORE’S PRODUCTS WILL MEET YOUR REQUIREMENTS,

    -

    (B) YOUR USE OF PARITY OR ETHCORE’S PRODUCTS WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR,

    -

    (C) ANY INFORMATION OBTAINED BY YOU AS A RESULT OF YOUR USE OF PARITY OR ETHCORE’S PRODUCTS WILL BE ACCURATE OR RELIABLE, AND

    -

    (D) THAT DEFECTS IN THE OPERATION OR FUNCTIONALITY OF ANY SOFTWARE PROVIDED TO YOU AS PART OF ETHCORE’S PRODUCTS WILL BE CORRECTED.

    -

    ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF PARITY OR ETHCORE’S PRODUCTS IS DONE AT YOUR OWN DISCRETION AND RISK AND THAT YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA OR ECONOMIC LOSS THAT RESULTS FROM THE DOWNLOAD OF ANY SUCH MATERIAL.

    -

    NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM ETHCORE OR THROUGH OR FROM ETHCORE’S PRODUCTS SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN THE TERMS.

    -

    ETHCORE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.

    +

    THE USER EXPRESSLY KNOWS AND AGREES THAT THE USER IS USING PARITY OR PARITY’S PRODUCTS AT THE USER’S SOLE RISK. THE USER REPRESENTS THAT THE USER HAS AN ADEQUATE UNDERSTANDING OF THE RISKS, USAGE AND INTRICACIES OF CRYPTOGRAPHIC TOKENS AND BLOCKCHAIN-BASED OPEN SOURCE SOFTWARE, PARITY.

    +

    YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF PARITY’S PRODUCTS IS AT YOUR SOLE RISK AND THAT PARITY’S PRODUCTS ARE PROVIDED "AS IS" AND “AS AVAILABLE.”

    +

    IN PARTICULAR, PARITY, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS DO NOT REPRESENT OR WARRANT TO YOU THAT:

    +

    (A) YOUR USE OF PARITY OR PARITY’S PRODUCTS WILL MEET YOUR REQUIREMENTS,

    +

    (B) YOUR USE OF PARITY OR PARITY’S PRODUCTS WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR,

    +

    (C) ANY INFORMATION OBTAINED BY YOU AS A RESULT OF YOUR USE OF PARITY OR PARITY’S PRODUCTS WILL BE ACCURATE OR RELIABLE, AND

    +

    (D) THAT DEFECTS IN THE OPERATION OR FUNCTIONALITY OF ANY SOFTWARE PROVIDED TO YOU AS PART OF PARITY’S PRODUCTS WILL BE CORRECTED.

    +

    ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF PARITY OR PARITY’S PRODUCTS IS DONE AT YOUR OWN DISCRETION AND RISK AND THAT YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA OR ECONOMIC LOSS THAT RESULTS FROM THE DOWNLOAD OF ANY SUCH MATERIAL.

    +

    NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM PARITY OR THROUGH OR FROM PARITY’S PRODUCTS SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN THE TERMS.

    +

    PARITY FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.

    EXCLUSION AND LIMITATION OF LIABILITY

    -

    THE USER ACKNOWLEDGES AND AGREES THAT, TO THE FULLEST EXTENT PERMITTED BY ANY APPLICABLE LAW, THE DISCLAIMERS AND EXCLUSION OF LIABILITY CONTAINED HEREIN APPLY TO ANY AND ALL DAMAGES OR INJURY WHATSOEVER CAUSED BY OR RELATED TO RISKS OF, USE OF, OR INABILITY TO USE, PARITY UNDER ANY CAUSE OF ACTION WHATSOEVER OF ANY KIND IN ANY JURISDICTION, INCLUDING, WITHOUT LIMITATION, ACTIONS FOR BREACH OF WARRANTY, BREACH OF CONTRACT OR TORT (INCLUDING NEGLIGENCE) AND THAT NEITHER ETHCORE NOR THE ETHCORE TEAM SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, INCLUDING FOR LOSS OF PROFITS, GOODWILL OR DATA.

    -

    SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF DAMAGES. THEREFORE, SOME OF THE ABOVE LIMITATIONS IN THIS SECTION MAY NOT APPLY TO A USER. IN PARTICULAR, NOTHING IN THESE TERMS SHALL AFFECT THE STATUTORY RIGHTS OF ANY USER OR EXCLUDE INJURY ARISING FROM ANY WILLFUL MISCONDUCT OR FRAUD OF ETHCORE.

    -

    SUBJECT TO ANY LIABILITY WHICH MAY NOT BE EXCLUDED, YOU EXPRESSLY UNDERSTAND AND AGREE THAT ETHCORE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU FOR:

    +

    THE USER ACKNOWLEDGES AND AGREES THAT, TO THE FULLEST EXTENT PERMITTED BY ANY APPLICABLE LAW, THE DISCLAIMERS AND EXCLUSION OF LIABILITY CONTAINED HEREIN APPLY TO ANY AND ALL DAMAGES OR INJURY WHATSOEVER CAUSED BY OR RELATED TO RISKS OF, USE OF, OR INABILITY TO USE, PARITY UNDER ANY CAUSE OF ACTION WHATSOEVER OF ANY KIND IN ANY JURISDICTION, INCLUDING, WITHOUT LIMITATION, ACTIONS FOR BREACH OF WARRANTY, BREACH OF CONTRACT OR TORT (INCLUDING NEGLIGENCE) AND THAT NEITHER PARITY NOR THE PARITY TEAM SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, INCLUDING FOR LOSS OF PROFITS, GOODWILL OR DATA.

    +

    SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF DAMAGES. THEREFORE, SOME OF THE ABOVE LIMITATIONS IN THIS SECTION MAY NOT APPLY TO A USER. IN PARTICULAR, NOTHING IN THESE TERMS SHALL AFFECT THE STATUTORY RIGHTS OF ANY USER OR EXCLUDE INJURY ARISING FROM ANY WILLFUL MISCONDUCT OR FRAUD OF PARITY.

    +

    SUBJECT TO ANY LIABILITY WHICH MAY NOT BE EXCLUDED, YOU EXPRESSLY UNDERSTAND AND AGREE THAT PARITY, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU FOR:

    (A) ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL CONSEQUENTIAL OR EXEMPLARY DAMAGES WHICH MAY BE INCURRED BY YOU, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY. THIS SHALL INCLUDE, BUT NOT BE LIMITED TO, ANY LOSS OF PROFIT (WHETHER INCURRED DIRECTLY OR INDIRECTLY), ANY LOSS OF GOODWILL OR BUSINESS REPUTATION, ANY LOSS OF DATA SUFFERED, COST OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR OTHER INTANGIBLE LOSS;

    (B) ANY LOSS OR DAMAGE WHICH MAY BE INCURRED BY YOU, INCLUDING BUT NOT LIMITED TO LOSS OR DAMAGE AS A RESULT OF:

    -

    (I) ANY RELIANCE PLACED BY YOU ON THE COMPLETENESS, ACCURACY OR EXISTENCE OF ANY ADVERTISING, OR AS A RESULT OF ANY RELATIONSHIP OR TRANSACTION BETWEEN YOU AND ANY ADVERTISER OR SPONSOR WHOSE ADVERTISING APPEARS ON ETHCORE’S PRODUCTS;

    -

    (II) ANY CHANGES WHICH ETHCORE MAY MAKE TO ETHCORE’S PRODUCTS, OR FOR ANY PERMANENT OR TEMPORARY CESSATION IN THE PROVISION OF ETHCORE’S PRODUCTS (OR ANY FEATURES WITHIN ETHCORE’S PRODUCTS);

    -

    (III) THE DELETION OF, CORRUPTION OF, OR FAILURE TO STORE, ANY CONTENT AND OTHER COMMUNICATIONS DATA MAINTAINED OR TRANSMITTED BY OR THROUGH YOUR USE OF ETHCORE’S PRODUCTS;

    -

    (IV) YOUR FAILURE TO PROVIDE ETHCORE WITH ACCURATE ACCOUNT INFORMATION (IF THIS IS REQUIRED);

    +

    (I) ANY RELIANCE PLACED BY YOU ON THE COMPLETENESS, ACCURACY OR EXISTENCE OF ANY ADVERTISING, OR AS A RESULT OF ANY RELATIONSHIP OR TRANSACTION BETWEEN YOU AND ANY ADVERTISER OR SPONSOR WHOSE ADVERTISING APPEARS ON PARITY’S PRODUCTS;

    +

    (II) ANY CHANGES WHICH PARITY MAY MAKE TO PARITY’S PRODUCTS, OR FOR ANY PERMANENT OR TEMPORARY CESSATION IN THE PROVISION OF PARITY’S PRODUCTS (OR ANY FEATURES WITHIN PARITY’S PRODUCTS);

    +

    (III) THE DELETION OF, CORRUPTION OF, OR FAILURE TO STORE, ANY CONTENT AND OTHER COMMUNICATIONS DATA MAINTAINED OR TRANSMITTED BY OR THROUGH YOUR USE OF PARITY’S PRODUCTS;

    +

    (IV) YOUR FAILURE TO PROVIDE PARITY WITH ACCURATE ACCOUNT INFORMATION (IF THIS IS REQUIRED);

    (V) YOUR FAILURE TO KEEP YOUR PASSWORD OR ACCOUNT DETAILS SECURE AND CONFIDENTIAL;

    -

    THE LIMITATIONS ON ETHCORE’S LIABILITY TO YOU SHALL APPLY WHETHER OR NOT ETHCORE HAS BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.

    +

    THE LIMITATIONS ON PARITY’S LIABILITY TO YOU SHALL APPLY WHETHER OR NOT PARITY HAS BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.

    Copyright and trade mark policies

    -

    It is EthCore’s policy to respond to notices of alleged copyright infringement that comply with applicable international intellectual property law (including, in the United States, the Digital Millennium Copyright Act) and if EthCore is put on notice and it is under EthCore’s control and terminating the accounts of repeat infringers.

    +

    It is Parity’s policy to respond to notices of alleged copyright infringement that comply with applicable international intellectual property law (including, in the United States, the Digital Millennium Copyright Act) and if Parity is put on notice and it is under Parity’s control and terminating the accounts of repeat infringers.

    Other content

    -

    Services provided may include hyperlinks to other web sites, smart contracts or content or resources. EthCore may have no control over any web sites or resources which are provided by companies or persons other than EthCore.

    -

    You acknowledge and agree that EthCore is not responsible for the availability of any such external sites or resources, and does not endorse any advertising, products or other materials on or available from such web sites or resources.

    -

    You acknowledge and agree that EthCore is not liable for any loss or damage which may be incurred by you as a result of the availability of those external sites or resources, or as a result of any reliance placed by you on the completeness, accuracy or existence of any advertising, products or other materials on, or available from, such web sites or resources.

    +

    Services provided may include hyperlinks to other web sites, smart contracts or content or resources. Parity may have no control over any web sites or resources which are provided by companies or persons other than Parity.

    +

    You acknowledge and agree that Parity is not responsible for the availability of any such external sites or resources, and does not endorse any advertising, products or other materials on or available from such web sites or resources.

    +

    You acknowledge and agree that Parity is not liable for any loss or damage which may be incurred by you as a result of the availability of those external sites or resources, or as a result of any reliance placed by you on the completeness, accuracy or existence of any advertising, products or other materials on, or available from, such web sites or resources.

    Changes to the Terms

    -

    EthCore may make changes to these from time to time. When these changes are made, EthCore will make a new copy of these terms available at https://ethcore.io/legal.html and any new terms will be made available to you from within, or through, the affected EthCore’s Product.

    -

    You understand and agree that if you use Parity or EthCore’s Products after the date on which the Terms have changed, EthCore will treat your use as acceptance of the updated terms.

    +

    Parity may make changes to these from time to time. When these changes are made, Parity will make a new copy of these terms available at https://parity.io/legal.html and any new terms will be made available to you from within, or through, the affected Parity’s Product.

    +

    You understand and agree that if you use Parity or Parity’s Products after the date on which the Terms have changed, Parity will treat your use as acceptance of the updated terms.

    General legal terms

    -

    Sometimes when you use Parity or EthCore’s Products, you may (as a result of, or in connection with your use of these products) use a service or download a piece of software, or smart contract, or purchase goods, which are provided by another person or company. Your use of these other services, software, smart contract or goods may be subject to separate terms between you and the company or person concerned. If so, these Terms do not affect your legal relationship with these other companies or individuals.

    -

    These Terms constitute the whole legal agreement between you and EthCore and govern your use of Parity and EthCore’s Products (but excluding any products or services which EthCore may provide to you under a separate written agreement), and completely replace any prior agreements between you and EthCore in relation to Parity and EthCore’s Products.

    -

    You agree that EthCore may provide you with notices, including those regarding changes to the Terms, by postings on the affected EthCore’s Product.

    -

    You agree that if EthCore does not exercise or enforce any legal right or remedy which is contained in these Terms (or which EthCore has the benefit of under any applicable law), this will not be taken to be a formal waiver of EthCore’s rights and that those rights or remedies will still be available to EthCore.

    +

    Sometimes when you use Parity or Parity’s Products, you may (as a result of, or in connection with your use of these products) use a service or download a piece of software, or smart contract, or purchase goods, which are provided by another person or company. Your use of these other services, software, smart contract or goods may be subject to separate terms between you and the company or person concerned. If so, these Terms do not affect your legal relationship with these other companies or individuals.

    +

    These Terms constitute the whole legal agreement between you and Parity and govern your use of Parity and Parity’s Products (but excluding any products or services which Parity may provide to you under a separate written agreement), and completely replace any prior agreements between you and Parity in relation to Parity and Parity’s Products.

    +

    You agree that Parity may provide you with notices, including those regarding changes to the Terms, by postings on the affected Parity’s Product.

    +

    You agree that if Parity does not exercise or enforce any legal right or remedy which is contained in these Terms (or which Parity has the benefit of under any applicable law), this will not be taken to be a formal waiver of Parity’s rights and that those rights or remedies will still be available to Parity.

    If any court of law, having the jurisdiction to decide on this matter, rules that any provision of these Terms is invalid, then that provision will be removed from the Terms without affecting the rest of the Terms. The remaining provisions of the Terms will continue to be valid and enforceable.

    -

    You acknowledge and agree that each member of the group of companies of which EthCore is the parent shall be third party beneficiaries to these Terms and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the Terms which confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to these Terms.

    -

    These Terms, and your relationship with EthCore under these Terms, shall be governed by the laws of England and Wales, United Kingdom without regard to its conflict of laws provisions. You and EthCore agree to submit to the exclusive jurisdiction of the courts located within England, United Kingdom to resolve any legal matter arising from these Terms (subject to the Dispute Resolution clause below). Notwithstanding this, you agree that EthCore shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.

    +

    You acknowledge and agree that each member of the group of companies of which Parity is the parent shall be third party beneficiaries to these Terms and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the Terms which confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to these Terms.

    +

    These Terms, and your relationship with Parity under these Terms, shall be governed by the laws of England and Wales, United Kingdom without regard to its conflict of laws provisions. You and Parity agree to submit to the exclusive jurisdiction of the courts located within England, United Kingdom to resolve any legal matter arising from these Terms (subject to the Dispute Resolution clause below). Notwithstanding this, you agree that Parity shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.

    Dispute Resolution

    All disputes or claims arising out of, relating to, or in connection with the Terms, the breach thereof, or use of Parity shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with said Rules. All claims between the parties relating to these Terms that are capable of being resolved by arbitration, whether sounding in contract, tort, or otherwise, shall be submitted to ICC arbitration. Prior to commencing arbitration, the parties have a duty to negotiate in good faith and attempt to resolve their dispute in a manner other than by submission to ICC arbitration. The arbitration panel shall consist of one arbitrator only, unless the ICC Court of Arbitration determines that the dispute is such as to warrant three arbitrators. If the Court determines that one arbitrator is sufficient, then such arbitrator shall be a UK resident. If the Court determines that three arbitrators are necessary, then each party shall have 30 days to nominate an arbitrator of its choice - in the case of the Claimant, measured from receipt of notification of the ICC Court’s decision to have three arbitrators; in the case of Respondent, measured from receipt of notification of Claimant’s nomination. All nominations must be UK residents. If a party fails to nominate an arbitrator, the Court will do so. The Court shall also appoint the chairman. All arbitrators shall be and remain “independent” of the parties involved in the arbitration. The place of arbitration shall be England, United Kingdom. The language of the arbitration shall be English. In deciding the merits of the dispute, the tribunal shall apply the laws of England and Wales and any discovery shall be limited and shall not involve any depositions or any other examinations outside of a formal hearing. The tribunal shall not assume the powers of amiable compositeur or decide the case ex aequo et bono. In the final award, the tribunal shall fix the costs of the arbitration and decide which of the parties shall bear such costs in what proportion. Every award shall be binding on the parties. The parties undertake to carry out the award without delay and waive their right to any form of recourse against the award in so far as such waiver can validly be made.

    Additional Terms for Enterprise Use

    -

    If you are a business entity, then the individual accepting on behalf of the entity (for the avoidance of doubt, for business entities, in these Terms, "you" means the entity) represents and warrants that he or she has the authority to act on your behalf, that you represent that you are duly authorized to do business in the country or countries where you operate, and that your employees, officers, representatives, and other agents accessing EthCore’s Products are duly authorized to access Parity and to legally bind you to these Terms.

    -

    Subject to these Terms and subject to the Software Licence Terms, EthCore grants you a non-exclusive, non-transferable licence to install and use Parity solely on machines intended for use by your employees, officers, representatives, and agents in connection with your business entity, and provided that their use of EthCore will be subject to these Terms and EthCore’s Products software licence terms.

    +

    If you are a business entity, then the individual accepting on behalf of the entity (for the avoidance of doubt, for business entities, in these Terms, "you" means the entity) represents and warrants that he or she has the authority to act on your behalf, that you represent that you are duly authorized to do business in the country or countries where you operate, and that your employees, officers, representatives, and other agents accessing Parity’s Products are duly authorized to access Parity and to legally bind you to these Terms.

    +

    Subject to these Terms and subject to the Software Licence Terms, Parity grants you a non-exclusive, non-transferable licence to install and use Parity solely on machines intended for use by your employees, officers, representatives, and agents in connection with your business entity, and provided that their use of Parity will be subject to these Terms and Parity’s Products software licence terms.

    } checked={ hasAccepted } - onClick={ onAccept } + onClict={ onAccept } />
    ); diff --git a/js/src/shell/FirstRun/Welcome/welcome.js b/js/src/shell/FirstRun/Welcome/welcome.js index 95284095b..7557da133 100644 --- a/js/src/shell/FirstRun/Welcome/welcome.js +++ b/js/src/shell/FirstRun/Welcome/welcome.js @@ -33,7 +33,7 @@ export default function FirstRun () {
    Ethcore Ltd.

    diff --git a/js/src/shell/FirstRun/firstRun.js b/js/src/shell/FirstRun/firstRun.js index 1a3fea866..fff377e9b 100644 --- a/js/src/shell/FirstRun/firstRun.js +++ b/js/src/shell/FirstRun/firstRun.js @@ -54,6 +54,10 @@ const STAGE_NAMES = [ id='firstRun.title.recovery' defaultMessage='recovery' />, + , + ); case 4: + return ( + + ); + case 5: return ( ); @@ -143,7 +157,7 @@ class FirstRun extends Component { renderDialogActions () { const { hasAccounts } = this.props; const { stage, hasAcceptedTnc } = this.state; - const { canCreate } = this.createStore; + const { canCreate, phraseBackedUpError } = this.createStore; switch (stage) { case 0: @@ -171,15 +185,10 @@ class FirstRun extends Component { const buttons = [