aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba S <csaba.solya@gmail.com>2018-02-22 21:55:46 +0800
committerGitHub <noreply@github.com>2018-02-22 21:55:46 +0800
commit2f3463048685759319eb320c916cc7bc23a41649 (patch)
treee53ac24a1a127f1c684327bca00d23f51b56c542
parent5ec311ba3e01bd9b0a9ff447fd7639d22a7b3d9c (diff)
parenteed75735b8e90d121537249cf147c1ece60f1e47 (diff)
downloadtangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar.gz
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar.bz2
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar.lz
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar.xz
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.tar.zst
tangerine-wallet-browser-2f3463048685759319eb320c916cc7bc23a41649.zip
Merge branch 'master' into edge-support
-rw-r--r--.eslintignore3
-rw-r--r--.gitignore5
-rw-r--r--.stylelintignore10
-rw-r--r--.stylelintrc50
-rw-r--r--app/fonts/DIN Next/DIN Next W01 Bold.otfbin0 -> 106032 bytes
-rw-r--r--app/fonts/DIN Next/DIN Next W01 Regular.otfbin0 -> 106580 bytes
-rw-r--r--app/fonts/DIN Next/DIN Next W10 Black.otfbin0 -> 105972 bytes
-rw-r--r--app/fonts/DIN Next/DIN Next W10 Italic.otfbin0 -> 115984 bytes
-rw-r--r--app/fonts/DIN Next/DIN Next W10 Light.otfbin0 -> 108672 bytes
-rw-r--r--app/fonts/DIN Next/DIN Next W10 Medium.otfbin0 -> 105684 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-2.otfbin0 -> 44144 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-Bold 2.otfbin0 -> 45564 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-BoldItalic.otfbin0 -> 49684 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-Italic 2.otfbin0 -> 47956 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-Medium 2.otfbin0 -> 44652 bytes
-rw-r--r--app/fonts/DIN_OT/DINOT-MediumItalic 2.otfbin0 -> 47732 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Black.ttfbin0 -> 114588 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-BlackItalic.ttfbin0 -> 111616 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Bold.ttfbin0 -> 121788 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-BoldItalic.ttfbin0 -> 120312 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Hairline.ttfbin0 -> 115316 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-HairlineItalic.ttfbin0 -> 91460 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Italic.ttfbin0 -> 118352 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Light.ttfbin0 -> 122524 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-LightItalic.ttfbin0 -> 91600 bytes
-rwxr-xr-xapp/fonts/Lato/Lato-Regular.ttfbin0 -> 120196 bytes
-rwxr-xr-xapp/fonts/Lato/OFL.txt93
-rw-r--r--app/fonts/Roboto/Roboto-Black.ttfbin0 -> 142472 bytes
-rw-r--r--app/fonts/Roboto/Roboto-BlackItalic.ttfbin0 -> 149644 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Bold.ttfbin0 -> 135820 bytes
-rw-r--r--app/fonts/Roboto/Roboto-BoldItalic.ttfbin0 -> 144700 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Italic.ttfbin0 -> 148540 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Light.ttfbin0 -> 140276 bytes
-rw-r--r--app/fonts/Roboto/Roboto-LightItalic.ttfbin0 -> 145932 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Medium.ttfbin0 -> 137308 bytes
-rw-r--r--app/fonts/Roboto/Roboto-MediumItalic.ttfbin0 -> 147876 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Regular.ttfbin0 -> 145348 bytes
-rw-r--r--app/fonts/Roboto/Roboto-Thin.ttfbin0 -> 130044 bytes
-rw-r--r--app/fonts/Roboto/Roboto-ThinItalic.ttfbin0 -> 132376 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-Bold.ttfbin0 -> 141796 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-BoldItalic.ttfbin0 -> 145256 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-Italic.ttfbin0 -> 144404 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-Light.ttfbin0 -> 141384 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-LightItalic.ttfbin0 -> 145104 bytes
-rw-r--r--app/fonts/Roboto/RobotoCondensed-Regular.ttfbin0 -> 140396 bytes
-rw-r--r--app/images/.DS_Storebin6148 -> 0 bytes
-rw-r--r--app/images/check-white.svg14
-rw-r--r--app/images/coinbase logo.pngbin0 -> 9775 bytes
-rw-r--r--app/images/eth_logo.svg11
-rw-r--r--app/images/import-account.svg18
-rw-r--r--app/images/info-logo.pngbin0 -> 32567 bytes
-rw-r--r--app/images/metamask-fox.svg128
-rw-r--r--app/images/mm-bolt.svg11
-rw-r--r--app/images/mm-info-icon.svg11
-rw-r--r--app/images/open.svg15
-rw-r--r--app/images/plus-btn-white.svg17
-rw-r--r--app/images/popout.svg21
-rw-r--r--app/images/settings.svg46
-rw-r--r--app/images/shapeshift logo.pngbin0 -> 17537 bytes
-rw-r--r--app/manifest.json2
-rw-r--r--app/notification.html4
-rw-r--r--app/popup.html4
-rw-r--r--app/scripts/background.js12
-rw-r--r--app/scripts/config.js22
-rw-r--r--app/scripts/controllers/network.js40
-rw-r--r--app/scripts/controllers/preferences.js37
-rw-r--r--app/scripts/controllers/transactions.js4
-rw-r--r--app/scripts/lib/config-manager.js11
-rw-r--r--app/scripts/lib/environment-type.js10
-rw-r--r--app/scripts/lib/is-popup-or-notification.js5
-rw-r--r--app/scripts/lib/notification-manager.js2
-rw-r--r--app/scripts/metamask-controller.js29
-rw-r--r--app/scripts/platforms/extension.js5
-rw-r--r--app/scripts/popup-core.js2
-rw-r--r--app/scripts/popup.js29
-rw-r--r--development/backGroundConnectionModifiers.js26
-rw-r--r--development/mockExtension.js5
-rw-r--r--development/selector.js11
-rw-r--r--development/states/add-token.json132
-rw-r--r--development/states/confirm-new-ui.json154
-rw-r--r--development/states/confirm-sig-requests.json175
-rw-r--r--development/states/first-time.json11
-rw-r--r--development/states/send-edit.json154
-rw-r--r--development/states/send-new-ui.json133
-rw-r--r--docker-compose.yml6
-rw-r--r--gulpfile.js70
-rw-r--r--mascara/server/index.js3
-rw-r--r--mascara/server/util.js4
-rw-r--r--mascara/src/app/buy-ether-widget/index.js198
-rw-r--r--mascara/src/app/first-time/backup-phrase-screen.js7
-rw-r--r--mascara/src/app/first-time/breadcrumbs.js5
-rw-r--r--mascara/src/app/first-time/buy-ether-screen.js3
-rw-r--r--mascara/src/app/first-time/create-password-screen.js146
-rw-r--r--mascara/src/app/first-time/import-account-screen.js3
-rw-r--r--mascara/src/app/first-time/import-seed-phrase-screen.js59
-rw-r--r--mascara/src/app/first-time/index.css66
-rw-r--r--mascara/src/app/first-time/index.js43
-rw-r--r--mascara/src/app/first-time/loading-screen.js10
-rw-r--r--mascara/src/app/first-time/notice-screen.js72
-rw-r--r--mascara/src/app/first-time/unique-image-screen.js3
-rw-r--r--mascara/src/app/shapeshift-form/index.js3
-rw-r--r--mock-dev.js17
-rw-r--r--old-ui/.gitignore66
-rw-r--r--old-ui/app/account-detail.js292
-rw-r--r--old-ui/app/accounts/import/index.js101
-rw-r--r--old-ui/app/accounts/import/json.js100
-rw-r--r--old-ui/app/accounts/import/private-key.js67
-rw-r--r--old-ui/app/accounts/import/seed.js30
-rw-r--r--old-ui/app/add-token.js238
-rw-r--r--old-ui/app/app.js707
-rw-r--r--old-ui/app/components/account-dropdowns.js320
-rw-r--r--old-ui/app/components/account-export.js132
-rw-r--r--old-ui/app/components/account-panel.js86
-rw-r--r--old-ui/app/components/balance.js89
-rw-r--r--old-ui/app/components/binary-renderer.js46
-rw-r--r--old-ui/app/components/bn-as-decimal-input.js181
-rw-r--r--old-ui/app/components/buy-button-subview.js262
-rw-r--r--old-ui/app/components/coinbase-form.js63
-rw-r--r--old-ui/app/components/copyButton.js59
-rw-r--r--old-ui/app/components/copyable.js46
-rw-r--r--old-ui/app/components/custom-radio-list.js60
-rw-r--r--old-ui/app/components/dropdown.js (renamed from ui/app/components/dropdown.js)2
-rw-r--r--old-ui/app/components/editable-label.js57
-rw-r--r--old-ui/app/components/ens-input.js170
-rw-r--r--old-ui/app/components/eth-balance.js89
-rw-r--r--old-ui/app/components/fiat-value.js64
-rw-r--r--old-ui/app/components/hex-as-decimal-input.js154
-rw-r--r--old-ui/app/components/identicon.js74
-rw-r--r--old-ui/app/components/loading.js55
-rw-r--r--old-ui/app/components/mascot.js59
-rw-r--r--old-ui/app/components/menu-droppo.js132
-rw-r--r--old-ui/app/components/mini-account-panel.js74
-rw-r--r--old-ui/app/components/network.js129
-rw-r--r--old-ui/app/components/notice.js132
-rw-r--r--old-ui/app/components/pending-msg-details.js50
-rw-r--r--old-ui/app/components/pending-msg.js70
-rw-r--r--old-ui/app/components/pending-personal-msg-details.js60
-rw-r--r--old-ui/app/components/pending-personal-msg.js (renamed from ui/app/components/pending-personal-msg.js)0
-rw-r--r--old-ui/app/components/pending-tx.js (renamed from ui/app/components/pending-tx.js)2
-rw-r--r--old-ui/app/components/pending-typed-msg-details.js59
-rw-r--r--old-ui/app/components/pending-typed-msg.js46
-rw-r--r--old-ui/app/components/qr-code.js80
-rw-r--r--old-ui/app/components/range-slider.js58
-rw-r--r--old-ui/app/components/shapeshift-form.js308
-rw-r--r--old-ui/app/components/shift-list-item.js204
-rw-r--r--old-ui/app/components/tab-bar.js37
-rw-r--r--old-ui/app/components/template.js18
-rw-r--r--old-ui/app/components/token-cell.js72
-rw-r--r--old-ui/app/components/token-list.js207
-rw-r--r--old-ui/app/components/tooltip.js22
-rw-r--r--old-ui/app/components/transaction-list-item-icon.js68
-rw-r--r--old-ui/app/components/transaction-list-item.js175
-rw-r--r--old-ui/app/components/transaction-list.js87
-rw-r--r--old-ui/app/components/typed-message-renderer.js42
-rw-r--r--old-ui/app/conf-tx.js245
-rw-r--r--old-ui/app/config.js (renamed from ui/app/config.js)8
-rw-r--r--old-ui/app/css/debug.css (renamed from ui/app/css/debug.css)0
-rw-r--r--old-ui/app/css/fonts.css (renamed from ui/app/css/fonts.css)0
-rw-r--r--old-ui/app/css/index.css (renamed from ui/app/css/index.css)104
-rw-r--r--old-ui/app/css/lib.css (renamed from ui/app/css/lib.css)0
-rw-r--r--old-ui/app/css/output/index.css5385
-rw-r--r--old-ui/app/css/reset.css (renamed from ui/app/css/reset.css)0
-rw-r--r--old-ui/app/css/transitions.css (renamed from ui/app/css/transitions.css)0
-rw-r--r--old-ui/app/first-time/init-menu.js179
-rw-r--r--old-ui/app/img/identicon-tardigrade.pngbin0 -> 141119 bytes
-rw-r--r--old-ui/app/img/identicon-walrus.pngbin0 -> 388973 bytes
-rw-r--r--old-ui/app/info.js155
-rw-r--r--old-ui/app/infura-conversion.json653
-rw-r--r--old-ui/app/keychains/hd/create-vault-complete.js91
-rw-r--r--old-ui/app/keychains/hd/recover-seed/confirmation.js121
-rw-r--r--old-ui/app/keychains/hd/restore-vault.js152
-rw-r--r--old-ui/app/new-keychain.js29
-rw-r--r--old-ui/app/send.js309
-rw-r--r--old-ui/app/settings.js59
-rw-r--r--old-ui/app/template.js30
-rw-r--r--old-ui/app/unlock.js122
-rw-r--r--old-ui/app/util.js240
-rw-r--r--old-ui/css.js30
-rw-r--r--old-ui/design/00-metamask-SignIn.jpgbin0 -> 57848 bytes
-rw-r--r--old-ui/design/01-metamask-SelectAcc.jpgbin0 -> 76063 bytes
-rw-r--r--old-ui/design/02-metamask-AccDetails.jpgbin0 -> 75780 bytes
-rw-r--r--old-ui/design/02a-metamask-AccDetails-OverToken.jpgbin0 -> 121847 bytes
-rw-r--r--old-ui/design/02a-metamask-AccDetails-OverTransaction.jpgbin0 -> 122075 bytes
-rw-r--r--old-ui/design/02a-metamask-AccDetails.jpgbin0 -> 117570 bytes
-rw-r--r--old-ui/design/02b-metamask-AccDetails-Send.jpgbin0 -> 110143 bytes
-rw-r--r--old-ui/design/03-metamask-Qr.jpgbin0 -> 66052 bytes
-rw-r--r--old-ui/design/05-metamask-Menu.jpgbin0 -> 130264 bytes
-rw-r--r--old-ui/design/chromeStorePics/final_screen_dao_accounts.pngbin0 -> 249708 bytes
-rw-r--r--old-ui/design/chromeStorePics/final_screen_dao_locked.pngbin0 -> 220295 bytes
-rw-r--r--old-ui/design/chromeStorePics/final_screen_dao_notification.pngbin0 -> 214405 bytes
-rw-r--r--old-ui/design/chromeStorePics/final_screen_wei_account.pngbin0 -> 253382 bytes
-rw-r--r--old-ui/design/chromeStorePics/final_screen_wei_notification.pngbin0 -> 193865 bytes
-rw-r--r--old-ui/design/chromeStorePics/icon-128.pngbin0 -> 5770 bytes
-rw-r--r--old-ui/design/chromeStorePics/icon-64.pngbin0 -> 3573 bytes
-rw-r--r--old-ui/design/chromeStorePics/metamask_icon.ai2383
-rw-r--r--old-ui/design/chromeStorePics/promo1400560.pngbin0 -> 261644 bytes
-rw-r--r--old-ui/design/chromeStorePics/promo440280.pngbin0 -> 57471 bytes
-rw-r--r--old-ui/design/chromeStorePics/promo920680.pngbin0 -> 206713 bytes
-rw-r--r--old-ui/design/chromeStorePics/screen_dao_accounts.pngbin0 -> 517598 bytes
-rw-r--r--old-ui/design/chromeStorePics/screen_dao_locked.pngbin0 -> 287108 bytes
-rw-r--r--old-ui/design/chromeStorePics/screen_dao_notification.pngbin0 -> 296498 bytes
-rw-r--r--old-ui/design/chromeStorePics/screen_wei_account.pngbin0 -> 653633 bytes
-rw-r--r--old-ui/design/chromeStorePics/screen_wei_notification.pngbin0 -> 402486 bytes
-rw-r--r--old-ui/design/metamask-logo-eyes.pngbin0 -> 146076 bytes
-rw-r--r--old-ui/design/wireframes/1st_time_use.pngbin0 -> 937556 bytes
-rw-r--r--old-ui/design/wireframes/metamask_wfs_jan_13.pdfbin0 -> 452413 bytes
-rw-r--r--old-ui/design/wireframes/metamask_wfs_jan_13.pngbin0 -> 419066 bytes
-rw-r--r--old-ui/design/wireframes/metamask_wfs_jan_18.pdfbin0 -> 612778 bytes
-rw-r--r--old-ui/example.js123
-rw-r--r--old-ui/lib/contract-namer.js33
-rw-r--r--old-ui/lib/etherscan-prefix-for-network.js21
-rw-r--r--old-ui/lib/icon-factory.js65
-rw-r--r--old-ui/lib/lost-accounts-notice.js23
-rw-r--r--old-ui/lib/persistent-form.js61
-rw-r--r--old-ui/lib/tx-helper.js27
-rw-r--r--package.json39
-rw-r--r--test/base.conf.js4
-rw-r--r--test/integration/lib/add-token.js153
-rw-r--r--test/integration/lib/confirm-sig-requests.js67
-rw-r--r--test/integration/lib/first-time.js16
-rw-r--r--test/integration/lib/mascara-first-time.js24
-rw-r--r--test/integration/lib/send-new-ui.js225
-rw-r--r--test/lib/shallow-with-store.js2
-rw-r--r--test/unit/actions/tx_test.js3
-rw-r--r--test/unit/components/balance-component-test.js45
-rw-r--r--test/unit/components/pending-tx-test.js92
-rw-r--r--test/unit/pending-tx-test.js1
-rw-r--r--test/unit/responsive/components/dropdown-test.js116
-rw-r--r--test/unit/ui/add-token.spec.js2
-rw-r--r--ui/app/account-and-transaction-details.js33
-rw-r--r--ui/app/account-detail.js185
-rw-r--r--ui/app/accounts/import/index.js31
-rw-r--r--ui/app/accounts/import/json.js42
-rw-r--r--ui/app/accounts/import/private-key.js72
-rw-r--r--ui/app/accounts/new-account/create-form.js99
-rw-r--r--ui/app/accounts/new-account/index.js81
-rw-r--r--ui/app/actions.js723
-rw-r--r--ui/app/add-token.js504
-rw-r--r--ui/app/app.js612
-rw-r--r--ui/app/components/account-dropdowns.js2
-rw-r--r--ui/app/components/account-menu/index.js160
-rw-r--r--ui/app/components/balance-component.js121
-rw-r--r--ui/app/components/buy-button-subview.js6
-rw-r--r--ui/app/components/currency-input.js103
-rw-r--r--ui/app/components/customize-gas-modal/gas-modal-card.js54
-rw-r--r--ui/app/components/customize-gas-modal/gas-slider.js50
-rw-r--r--ui/app/components/customize-gas-modal/index.js298
-rw-r--r--ui/app/components/dropdowns/account-dropdown-mini.js75
-rw-r--r--ui/app/components/dropdowns/account-options-dropdown.js29
-rw-r--r--ui/app/components/dropdowns/account-selection-dropdown.js29
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js482
-rw-r--r--ui/app/components/dropdowns/components/dropdown.js113
-rw-r--r--ui/app/components/dropdowns/components/menu.js51
-rw-r--r--ui/app/components/dropdowns/components/network-dropdown-icon.js28
-rw-r--r--ui/app/components/dropdowns/index.js17
-rw-r--r--ui/app/components/dropdowns/network-dropdown.js322
-rw-r--r--ui/app/components/dropdowns/simple-dropdown.js92
-rw-r--r--ui/app/components/dropdowns/token-menu-dropdown.js51
-rw-r--r--ui/app/components/editable-label.js115
-rw-r--r--ui/app/components/ens-input.js4
-rw-r--r--ui/app/components/eth-balance.js107
-rw-r--r--ui/app/components/fiat-value.js20
-rw-r--r--ui/app/components/identicon.js109
-rw-r--r--ui/app/components/input-number.js73
-rw-r--r--ui/app/components/loading.js75
-rw-r--r--ui/app/components/mascot.js6
-rw-r--r--ui/app/components/menu-droppo.js4
-rw-r--r--ui/app/components/modals/account-details-modal.js75
-rw-r--r--ui/app/components/modals/account-modal-container.js74
-rw-r--r--ui/app/components/modals/buy-options-modal.js95
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js184
-rw-r--r--ui/app/components/modals/edit-account-name-modal.js77
-rw-r--r--ui/app/components/modals/export-private-key-modal.js141
-rw-r--r--ui/app/components/modals/hide-token-confirmation-modal.js74
-rw-r--r--ui/app/components/modals/index.js5
-rw-r--r--ui/app/components/modals/modal.js344
-rw-r--r--ui/app/components/modals/new-account-modal.js106
-rw-r--r--ui/app/components/modals/notification-modal.js75
-rw-r--r--ui/app/components/modals/notification-modals/confirm-reset-account.js46
-rw-r--r--ui/app/components/modals/shapeshift-deposit-tx-modal.js40
-rw-r--r--ui/app/components/network.js78
-rw-r--r--ui/app/components/notice.js5
-rw-r--r--ui/app/components/pending-tx/confirm-deploy-contract.js348
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js469
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js462
-rw-r--r--ui/app/components/pending-tx/index.js145
-rw-r--r--ui/app/components/qr-code.js45
-rw-r--r--ui/app/components/readonly-input.js33
-rw-r--r--ui/app/components/send-token/index.js439
-rw-r--r--ui/app/components/send/account-list-item.js73
-rw-r--r--ui/app/components/send/currency-display.js116
-rw-r--r--ui/app/components/send/currency-toggle.js44
-rw-r--r--ui/app/components/send/eth-fee-display.js37
-rw-r--r--ui/app/components/send/from-dropdown.js72
-rw-r--r--ui/app/components/send/gas-fee-display-v2.js44
-rw-r--r--ui/app/components/send/gas-fee-display.js62
-rw-r--r--ui/app/components/send/gas-tooltip.js100
-rw-r--r--ui/app/components/send/memo-textarea.js33
-rw-r--r--ui/app/components/send/send-constants.js33
-rw-r--r--ui/app/components/send/send-utils.js68
-rw-r--r--ui/app/components/send/send-v2-container.js85
-rw-r--r--ui/app/components/send/to-autocomplete.js114
-rw-r--r--ui/app/components/send/usd-fee-display.js35
-rw-r--r--ui/app/components/shapeshift-form.js468
-rw-r--r--ui/app/components/shift-list-item.js49
-rw-r--r--ui/app/components/signature-request.js253
-rw-r--r--ui/app/components/tab-bar.js70
-rw-r--r--ui/app/components/token-balance.js113
-rw-r--r--ui/app/components/token-cell.js118
-rw-r--r--ui/app/components/token-list.js153
-rw-r--r--ui/app/components/tooltip-v2.js31
-rw-r--r--ui/app/components/transaction-list-item.js54
-rw-r--r--ui/app/components/tx-list-item.js245
-rw-r--r--ui/app/components/tx-list.js137
-rw-r--r--ui/app/components/tx-view.js148
-rw-r--r--ui/app/components/wallet-content-display.js56
-rw-r--r--ui/app/components/wallet-view.js187
-rw-r--r--ui/app/conf-tx.js198
-rw-r--r--ui/app/conversion-util.js221
-rw-r--r--ui/app/css/index.scss14
-rw-r--r--ui/app/css/itcss/base/index.scss7
-rw-r--r--ui/app/css/itcss/components/account-dropdown-mini.scss48
-rw-r--r--ui/app/css/itcss/components/account-dropdown.scss83
-rw-r--r--ui/app/css/itcss/components/account-menu.scss132
-rw-r--r--ui/app/css/itcss/components/add-token.scss343
-rw-r--r--ui/app/css/itcss/components/buttons.scss142
-rw-r--r--ui/app/css/itcss/components/confirm.scss324
-rw-r--r--ui/app/css/itcss/components/currency-display.scss57
-rw-r--r--ui/app/css/itcss/components/editable-label.scss35
-rw-r--r--ui/app/css/itcss/components/footer.scss4
-rw-r--r--ui/app/css/itcss/components/gas-slider.scss51
-rw-r--r--ui/app/css/itcss/components/header.scss107
-rw-r--r--ui/app/css/itcss/components/hero-balance.scss118
-rw-r--r--ui/app/css/itcss/components/index.scss57
-rw-r--r--ui/app/css/itcss/components/loading-overlay.scss21
-rw-r--r--ui/app/css/itcss/components/menu.scss59
-rw-r--r--ui/app/css/itcss/components/modal.scss851
-rw-r--r--ui/app/css/itcss/components/network.scss157
-rw-r--r--ui/app/css/itcss/components/new-account.scss211
-rw-r--r--ui/app/css/itcss/components/newui-sections.scss292
-rw-r--r--ui/app/css/itcss/components/request-signature.scss230
-rw-r--r--ui/app/css/itcss/components/sections.scss476
-rw-r--r--ui/app/css/itcss/components/send.scss887
-rw-r--r--ui/app/css/itcss/components/settings.scss206
-rw-r--r--ui/app/css/itcss/components/simple-dropdown.scss65
-rw-r--r--ui/app/css/itcss/components/tab-bar.scss23
-rw-r--r--ui/app/css/itcss/components/token-list.scss111
-rw-r--r--ui/app/css/itcss/components/tooltip.scss7
-rw-r--r--ui/app/css/itcss/components/transaction-list.scss264
-rw-r--r--ui/app/css/itcss/components/wallet-balance.scss74
-rw-r--r--ui/app/css/itcss/generic/index.scss204
-rw-r--r--ui/app/css/itcss/generic/reset.scss147
-rw-r--r--ui/app/css/itcss/objects/index.scss1
-rw-r--r--ui/app/css/itcss/settings/index.scss3
-rw-r--r--ui/app/css/itcss/settings/typography.scss71
-rw-r--r--ui/app/css/itcss/settings/variables.scss81
-rw-r--r--ui/app/css/itcss/tools/index.scss1
-rw-r--r--ui/app/css/itcss/tools/utilities.scss309
-rw-r--r--ui/app/css/itcss/trumps/index.scss72
-rw-r--r--ui/app/first-time/init-menu.js24
-rw-r--r--ui/app/keychains/hd/restore-vault.js4
-rw-r--r--ui/app/main-container.js59
-rw-r--r--ui/app/reducers/app.js111
-rw-r--r--ui/app/reducers/metamask.js199
-rw-r--r--ui/app/root.js4
-rw-r--r--ui/app/select-app.js68
-rw-r--r--ui/app/selectors.js189
-rw-r--r--ui/app/send-v2.js624
-rw-r--r--ui/app/send.js856
-rw-r--r--ui/app/settings.js447
-rw-r--r--ui/app/token-tracker.js0
-rw-r--r--ui/app/token-util.js45
-rw-r--r--ui/app/unlock.js27
-rw-r--r--ui/app/util.js45
-rw-r--r--ui/css.js6
-rw-r--r--ui/index.js14
-rw-r--r--ui/lib/account-link.js26
-rw-r--r--ui/lib/blockies.js364
-rw-r--r--ui/lib/feature-toggle-utils.js11
-rw-r--r--ui/lib/icon-factory.js2
-rw-r--r--ui/lib/is-mobile-view.js5
-rw-r--r--yarn.lock5160
382 files changed, 42016 insertions, 3802 deletions
diff --git a/.eslintignore b/.eslintignore
index b96f79011..e4cade21c 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,4 +2,5 @@ app/scripts/lib/extension-instance.js
test/integration/bundle.js
test/integration/jquery-3.1.0.min.js
test/integration/helpers.js
-test/integration/lib/first-time.js \ No newline at end of file
+test/integration/lib/first-time.js
+ui/lib/blockies.js \ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 1806b1932..92b3f2875 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@ app/bower_components
test/bower_components
package
+.idea
+
temp
.tmp
.sass-cache
@@ -24,6 +26,9 @@ test/background.js
test/bundle.js
test/test-bundle.js
+#ignore css output and sourcemaps
+ui/app/css/output/
+
notes.txt
.coveralls.yml
diff --git a/.stylelintignore b/.stylelintignore
new file mode 100644
index 000000000..854829a54
--- /dev/null
+++ b/.stylelintignore
@@ -0,0 +1,10 @@
+app/
+development/
+dist/
+docs/
+fonts/
+images/
+mascara/
+node_modules/
+notices/
+test/
diff --git a/.stylelintrc b/.stylelintrc
new file mode 100644
index 000000000..d080d68d9
--- /dev/null
+++ b/.stylelintrc
@@ -0,0 +1,50 @@
+{
+ "extends": "stylelint-config-standard",
+ "rules": {
+ "color-named": "never",
+ "font-family-name-quotes": "always-where-recommended",
+ "font-weight-notation": "numeric",
+ "function-url-quotes": "always",
+ "number-leading-zero": "never",
+ "value-no-vendor-prefix": true,
+ "value-list-comma-newline-before": "never-multi-line",
+ "custom-property-empty-line-before": "never",
+ "property-no-unknown": [
+ true,
+ {
+ "ignoreProperties": [
+ "composes",
+ "all",
+ "-webkit-appearance"
+ ]
+ }
+ ],
+ "declaration-block-semicolon-newline-after": "always",
+ "block-opening-brace-newline-after": "always",
+ "selector-attribute-quotes": "always",
+ "selector-max-specificity": "0,5,2",
+ "selector-pseudo-class-no-unknown": [
+ true,
+ {
+ "ignorePseudoClasses": ["local", "global"]
+ }
+ ],
+ "at-rule-empty-line-before": [
+ "always",
+ {
+ "ignore": [
+ "after-comment",
+ ]
+ }
+ ],
+ "indentation": [
+ 2,
+ {
+ "indentInsideParens": "once-at-root-twice-in-block"
+ }
+ ],
+ "max-nesting-depth": 3,
+ "no-duplicate-selectors": true,
+ "no-unknown-animations": true
+ }
+}
diff --git a/app/fonts/DIN Next/DIN Next W01 Bold.otf b/app/fonts/DIN Next/DIN Next W01 Bold.otf
new file mode 100644
index 000000000..2b78d1ff4
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W01 Bold.otf
Binary files differ
diff --git a/app/fonts/DIN Next/DIN Next W01 Regular.otf b/app/fonts/DIN Next/DIN Next W01 Regular.otf
new file mode 100644
index 000000000..09f6ee297
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W01 Regular.otf
Binary files differ
diff --git a/app/fonts/DIN Next/DIN Next W10 Black.otf b/app/fonts/DIN Next/DIN Next W10 Black.otf
new file mode 100644
index 000000000..08eb73373
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W10 Black.otf
Binary files differ
diff --git a/app/fonts/DIN Next/DIN Next W10 Italic.otf b/app/fonts/DIN Next/DIN Next W10 Italic.otf
new file mode 100644
index 000000000..73f2b9e8c
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W10 Italic.otf
Binary files differ
diff --git a/app/fonts/DIN Next/DIN Next W10 Light.otf b/app/fonts/DIN Next/DIN Next W10 Light.otf
new file mode 100644
index 000000000..700450e49
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W10 Light.otf
Binary files differ
diff --git a/app/fonts/DIN Next/DIN Next W10 Medium.otf b/app/fonts/DIN Next/DIN Next W10 Medium.otf
new file mode 100644
index 000000000..b73f2e43f
--- /dev/null
+++ b/app/fonts/DIN Next/DIN Next W10 Medium.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-2.otf b/app/fonts/DIN_OT/DINOT-2.otf
new file mode 100644
index 000000000..4a5e13127
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-2.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-Bold 2.otf b/app/fonts/DIN_OT/DINOT-Bold 2.otf
new file mode 100644
index 000000000..6ed5b6c3d
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-Bold 2.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-BoldItalic.otf b/app/fonts/DIN_OT/DINOT-BoldItalic.otf
new file mode 100644
index 000000000..148c90588
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-BoldItalic.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-Italic 2.otf b/app/fonts/DIN_OT/DINOT-Italic 2.otf
new file mode 100644
index 000000000..e365e77ab
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-Italic 2.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-Medium 2.otf b/app/fonts/DIN_OT/DINOT-Medium 2.otf
new file mode 100644
index 000000000..a87a2df37
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-Medium 2.otf
Binary files differ
diff --git a/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf b/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf
new file mode 100644
index 000000000..14eddfc76
--- /dev/null
+++ b/app/fonts/DIN_OT/DINOT-MediumItalic 2.otf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Black.ttf b/app/fonts/Lato/Lato-Black.ttf
new file mode 100755
index 000000000..6848db0d1
--- /dev/null
+++ b/app/fonts/Lato/Lato-Black.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-BlackItalic.ttf b/app/fonts/Lato/Lato-BlackItalic.ttf
new file mode 100755
index 000000000..5decf1297
--- /dev/null
+++ b/app/fonts/Lato/Lato-BlackItalic.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Bold.ttf b/app/fonts/Lato/Lato-Bold.ttf
new file mode 100755
index 000000000..74343694e
--- /dev/null
+++ b/app/fonts/Lato/Lato-Bold.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-BoldItalic.ttf b/app/fonts/Lato/Lato-BoldItalic.ttf
new file mode 100755
index 000000000..684aacf5b
--- /dev/null
+++ b/app/fonts/Lato/Lato-BoldItalic.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Hairline.ttf b/app/fonts/Lato/Lato-Hairline.ttf
new file mode 100755
index 000000000..288be2955
--- /dev/null
+++ b/app/fonts/Lato/Lato-Hairline.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-HairlineItalic.ttf b/app/fonts/Lato/Lato-HairlineItalic.ttf
new file mode 100755
index 000000000..c2bfd3353
--- /dev/null
+++ b/app/fonts/Lato/Lato-HairlineItalic.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Italic.ttf b/app/fonts/Lato/Lato-Italic.ttf
new file mode 100755
index 000000000..3d3b7a298
--- /dev/null
+++ b/app/fonts/Lato/Lato-Italic.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Light.ttf b/app/fonts/Lato/Lato-Light.ttf
new file mode 100755
index 000000000..a958067a8
--- /dev/null
+++ b/app/fonts/Lato/Lato-Light.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-LightItalic.ttf b/app/fonts/Lato/Lato-LightItalic.ttf
new file mode 100755
index 000000000..5e45ad9a6
--- /dev/null
+++ b/app/fonts/Lato/Lato-LightItalic.ttf
Binary files differ
diff --git a/app/fonts/Lato/Lato-Regular.ttf b/app/fonts/Lato/Lato-Regular.ttf
new file mode 100755
index 000000000..04ea8efb1
--- /dev/null
+++ b/app/fonts/Lato/Lato-Regular.ttf
Binary files differ
diff --git a/app/fonts/Lato/OFL.txt b/app/fonts/Lato/OFL.txt
new file mode 100755
index 000000000..dfca0da4b
--- /dev/null
+++ b/app/fonts/Lato/OFL.txt
@@ -0,0 +1,93 @@
+Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato"
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/app/fonts/Roboto/Roboto-Black.ttf b/app/fonts/Roboto/Roboto-Black.ttf
new file mode 100644
index 000000000..71f01ac2b
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Black.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-BlackItalic.ttf b/app/fonts/Roboto/Roboto-BlackItalic.ttf
new file mode 100644
index 000000000..ec309c785
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-BlackItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Bold.ttf b/app/fonts/Roboto/Roboto-Bold.ttf
new file mode 100644
index 000000000..aaf374d2c
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Bold.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-BoldItalic.ttf b/app/fonts/Roboto/Roboto-BoldItalic.ttf
new file mode 100644
index 000000000..dcd0f8007
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Italic.ttf b/app/fonts/Roboto/Roboto-Italic.ttf
new file mode 100644
index 000000000..f382c6874
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Italic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Light.ttf b/app/fonts/Roboto/Roboto-Light.ttf
new file mode 100644
index 000000000..664e1b2f9
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Light.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-LightItalic.ttf b/app/fonts/Roboto/Roboto-LightItalic.ttf
new file mode 100644
index 000000000..b8f529637
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-LightItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Medium.ttf b/app/fonts/Roboto/Roboto-Medium.ttf
new file mode 100644
index 000000000..aa00de0ef
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Medium.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-MediumItalic.ttf b/app/fonts/Roboto/Roboto-MediumItalic.ttf
new file mode 100644
index 000000000..67e25f019
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-MediumItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Regular.ttf b/app/fonts/Roboto/Roboto-Regular.ttf
new file mode 100644
index 000000000..3e6e2e761
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Regular.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-Thin.ttf b/app/fonts/Roboto/Roboto-Thin.ttf
new file mode 100644
index 000000000..d262d1446
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-Thin.ttf
Binary files differ
diff --git a/app/fonts/Roboto/Roboto-ThinItalic.ttf b/app/fonts/Roboto/Roboto-ThinItalic.ttf
new file mode 100644
index 000000000..63e9f9718
--- /dev/null
+++ b/app/fonts/Roboto/Roboto-ThinItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-Bold.ttf b/app/fonts/Roboto/RobotoCondensed-Bold.ttf
new file mode 100644
index 000000000..48dd63534
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-Bold.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-BoldItalic.ttf b/app/fonts/Roboto/RobotoCondensed-BoldItalic.ttf
new file mode 100644
index 000000000..ad728646a
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-BoldItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-Italic.ttf b/app/fonts/Roboto/RobotoCondensed-Italic.ttf
new file mode 100644
index 000000000..a232513d5
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-Italic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-Light.ttf b/app/fonts/Roboto/RobotoCondensed-Light.ttf
new file mode 100644
index 000000000..a6e368d40
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-Light.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-LightItalic.ttf b/app/fonts/Roboto/RobotoCondensed-LightItalic.ttf
new file mode 100644
index 000000000..5b2b6ae08
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-LightItalic.ttf
Binary files differ
diff --git a/app/fonts/Roboto/RobotoCondensed-Regular.ttf b/app/fonts/Roboto/RobotoCondensed-Regular.ttf
new file mode 100644
index 000000000..65bf32a19
--- /dev/null
+++ b/app/fonts/Roboto/RobotoCondensed-Regular.ttf
Binary files differ
diff --git a/app/images/.DS_Store b/app/images/.DS_Store
deleted file mode 100644
index d28ef2089..000000000
--- a/app/images/.DS_Store
+++ /dev/null
Binary files differ
diff --git a/app/images/check-white.svg b/app/images/check-white.svg
new file mode 100644
index 000000000..0f15667da
--- /dev/null
+++ b/app/images/check-white.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="13px" viewBox="0 0 16 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 47 (45396) - http://www.bohemiancoding.com/sketch -->
+ <title>check-white</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="MetaMascara-v2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="account-dropdown-top-bar-IXD" transform="translate(-17.000000, -80.000000)" fill-rule="nonzero" fill="#FFFFFF">
+ <g id="Group-11" transform="translate(18.000000, 74.000000)">
+ <polygon id="check-white" points="4.2 15.5712828 0.714212839 12.0143571 -0.714212839 13.4142143 4.2 18.4287172 14.7142128 7.69992858 13.2857872 6.30007142"></polygon>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/coinbase logo.png b/app/images/coinbase logo.png
new file mode 100644
index 000000000..a23d7926d
--- /dev/null
+++ b/app/images/coinbase logo.png
Binary files differ
diff --git a/app/images/eth_logo.svg b/app/images/eth_logo.svg
new file mode 100644
index 000000000..894bd70dd
--- /dev/null
+++ b/app/images/eth_logo.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="256px" height="417px" viewBox="0 0 256 417" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
+ <g>
+ <polygon fill="#343434" points="127.9611 0 125.1661 9.5 125.1661 285.168 127.9611 287.958 255.9231 212.32"/>
+ <polygon fill="#8C8C8C" points="127.962 0 0 212.32 127.962 287.959 127.962 154.158"/>
+ <polygon fill="#3C3C3B" points="127.9611 312.1866 126.3861 314.1066 126.3861 412.3056 127.9611 416.9066 255.9991 236.5866"/>
+ <polygon fill="#8C8C8C" points="127.962 416.9052 127.962 312.1852 0 236.5852"/>
+ <polygon fill="#141414" points="127.9611 287.9577 255.9211 212.3207 127.9611 154.1587"/>
+ <polygon fill="#393939" points="0.0009 212.3208 127.9609 287.9578 127.9609 154.1588"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/import-account.svg b/app/images/import-account.svg
new file mode 100644
index 000000000..d6a81b70c
--- /dev/null
+++ b/app/images/import-account.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 47 (45396) - http://www.bohemiancoding.com/sketch -->
+ <title>import-account</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="MetaMascara-v2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="account-dropdown-top-bar-IXD" transform="translate(-25.000000, -718.000000)">
+ <g id="Group-6" transform="translate(4.000000, 646.000000)">
+ <g id="import-account" transform="translate(21.000000, 72.000000)">
+ <rect id="Rectangle-49" fill="#FFFFFF" x="0" y="13.1721326" width="14.4893459" height="1.08397642"></rect>
+ <rect id="Rectangle" fill="#FFFFFF" x="6.5860663" y="0" width="1.08397642" height="10.5377061"></rect>
+ <polyline id="Path-12" stroke="#FFFFFF" points="2.63442652 6.5860663 7.24467293 10.5377061 11.8549193 6.5860663"></polyline>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/info-logo.png b/app/images/info-logo.png
new file mode 100644
index 000000000..f654ed5b1
--- /dev/null
+++ b/app/images/info-logo.png
Binary files differ
diff --git a/app/images/metamask-fox.svg b/app/images/metamask-fox.svg
new file mode 100644
index 000000000..f3c24f79e
--- /dev/null
+++ b/app/images/metamask-fox.svg
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns:ev="http://www.w3.org/2001/xml-events"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 318.6 318.6"
+ style="enable-background:new 0 0 318.6 318.6;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#161616;stroke:#161616;}
+ .st1{fill:#E4761B;stroke:#E4761B;stroke-linecap:round;stroke-linejoin:round;}
+ .st2{fill:#763D16;stroke:#763D16;stroke-linecap:round;stroke-linejoin:round;}
+ .st3{fill:#F6851B;stroke:#F6851B;stroke-linecap:round;stroke-linejoin:round;}
+ .st4{fill:#E2761B;stroke:#E2761B;stroke-linecap:round;stroke-linejoin:round;}
+ .st5{fill:#CD6116;stroke:#CD6116;stroke-linecap:round;stroke-linejoin:round;}
+ .st6{fill:#C0AD9E;stroke:#C0AD9E;stroke-linecap:round;stroke-linejoin:round;}
+ .st7{fill:#D7C1B3;stroke:#D7C1B3;stroke-linecap:round;stroke-linejoin:round;}
+ .st8{fill:#E4751F;stroke:#E4751F;stroke-linecap:round;stroke-linejoin:round;}
+ .st9{fill:#233447;stroke:#233447;stroke-linecap:round;stroke-linejoin:round;}
+ .st10{fill:#161616;stroke:#161616;stroke-linecap:round;stroke-linejoin:round;}
+</style>
+<polygon class="st0" points="277.3,145.6 272.3,142 280.3,134.7 274.2,129.9 282.2,123.8 276.9,119.8 285.3,79 272.7,41.1
+ 191.6,71.4 124.1,71.4 43,41.1 30.4,79 38.9,119.8 33.5,123.8 41.5,129.9 35.4,134.7 43.4,142 38.4,145.6 49.9,159.1 32.5,213.3
+ 48.6,268.6 105.3,253 116.3,262 138.7,277.5 177,277.5 199.4,262 210.4,253 267.1,268.6 283.3,213.3 265.8,159.1 "/>
+<g>
+ <polygon class="st1" points="105.3,253 48.6,268.6 32.5,213.3 "/>
+ <polygon class="st1" points="283.3,213.3 267.1,268.6 210.4,253 "/>
+ <polygon class="st2" points="265.8,159.1 213.5,143.8 231.8,139 "/>
+ <polygon class="st2" points="49.9,159.1 84,139 102.2,143.8 "/>
+ <polygon class="st2" points="43.4,142 41.5,129.9 84,139 "/>
+ <polygon class="st2" points="272.3,142 231.8,139 274.2,129.9 "/>
+ <polygon class="st2" points="272.3,142 265.8,159.1 231.8,139 "/>
+ <polygon class="st2" points="43.4,142 84,139 49.9,159.1 "/>
+ <polygon class="st2" points="231.8,139 276.9,119.8 274.2,129.9 "/>
+ <polygon class="st2" points="84,139 41.5,129.9 38.9,119.8 "/>
+ <polygon class="st3" points="124.1,71.4 191.6,71.4 176.5,112.5 "/>
+ <polygon class="st3" points="176.5,112.5 139.2,112.5 124.1,71.4 "/>
+ <polygon class="st2" points="276.9,119.8 231.8,139 231,87.4 "/>
+ <polygon class="st2" points="102.2,143.8 84,139 84.7,87.4 "/>
+ <polygon class="st2" points="84.7,87.4 84,139 38.9,119.8 "/>
+ <polygon class="st2" points="231,87.4 231.8,139 213.5,143.8 "/>
+ <polygon class="st1" points="139.2,112.5 43,41.1 124.1,71.4 "/>
+ <polygon class="st4" points="272.7,41.1 176.5,112.5 191.6,71.4 "/>
+ <polygon class="st1" points="210.4,253 236.9,213.3 283.3,213.3 "/>
+ <polygon class="st1" points="32.5,213.3 78.9,213.3 105.3,253 "/>
+ <polygon class="st3" points="229.3,167.7 283.3,213.3 236.9,213.3 "/>
+ <polygon class="st3" points="86.4,167.7 32.5,213.3 49.9,159.1 "/>
+ <polygon class="st3" points="78.9,213.3 32.5,213.3 86.4,167.7 "/>
+ <polygon class="st3" points="229.3,167.7 265.8,159.1 283.3,213.3 "/>
+ <polygon class="st2" points="84.7,87.4 139.2,112.5 102.2,143.8 "/>
+ <polygon class="st2" points="213.5,143.8 176.5,112.5 231,87.4 "/>
+ <polygon class="st2" points="265.8,159.1 272.3,142 277.3,145.6 "/>
+ <polygon class="st2" points="49.9,159.1 38.4,145.6 43.4,142 "/>
+ <polygon class="st2" points="272.3,142 274.2,129.9 280.3,134.7 "/>
+ <polygon class="st2" points="43.4,142 35.4,134.7 41.5,129.9 "/>
+ <polygon class="st2" points="33.5,123.8 38.9,119.8 41.5,129.9 "/>
+ <polygon class="st2" points="282.2,123.8 274.2,129.9 276.9,119.8 "/>
+ <polygon class="st3" points="49.9,159.1 102.2,143.8 86.4,167.7 "/>
+ <polygon class="st3" points="265.8,159.1 229.3,167.7 213.5,143.8 "/>
+ <polygon class="st2" points="38.9,119.8 30.4,79 84.7,87.4 "/>
+ <polygon class="st2" points="231,87.4 285.3,79 276.9,119.8 "/>
+ <polygon class="st1" points="102.2,143.8 139.2,112.5 142.6,170.2 "/>
+ <polygon class="st1" points="213.5,143.8 229.3,167.7 173.1,170.2 "/>
+ <polygon class="st1" points="173.1,170.2 176.5,112.5 213.5,143.8 "/>
+ <polygon class="st1" points="142.6,170.2 86.4,167.7 102.2,143.8 "/>
+ <polygon class="st2" points="272.7,41.1 285.3,79 231,87.4 "/>
+ <polygon class="st2" points="43,41.1 139.2,112.5 84.7,87.4 "/>
+ <polygon class="st2" points="231,87.4 176.5,112.5 272.7,41.1 "/>
+ <polygon class="st2" points="84.7,87.4 30.4,79 43,41.1 "/>
+ <polygon class="st5" points="105.3,253 78.9,213.3 110,213.7 "/>
+ <polygon class="st5" points="210.4,253 205.7,213.7 236.9,213.3 "/>
+ <polygon class="st3" points="173.1,170.2 142.6,170.2 139.2,112.5 "/>
+ <polygon class="st3" points="139.2,112.5 176.5,112.5 173.1,170.2 "/>
+ <polygon class="st6" points="116.3,262 105.3,253 136.8,267.9 "/>
+ <polygon class="st6" points="178.9,267.9 210.4,253 199.4,262 "/>
+ <polygon class="st7" points="136.6,258.6 136.8,267.9 105.3,253 "/>
+ <polygon class="st7" points="179.2,258.6 210.4,253 178.9,267.9 "/>
+ <polygon class="st3" points="86.4,167.7 110,213.7 78.9,213.3 "/>
+ <polygon class="st3" points="236.9,213.3 205.7,213.7 229.3,167.7 "/>
+ <polygon class="st8" points="86.4,167.7 109.2,190.8 110,213.7 "/>
+ <polygon class="st8" points="229.3,167.7 205.7,213.7 206.6,190.8 "/>
+ <polygon class="st7" points="105.3,253 139.2,236.5 136.6,258.6 "/>
+ <polygon class="st7" points="210.4,253 179.2,258.6 176.5,236.5 "/>
+ <polygon class="st1" points="139.2,236.5 105.3,253 110,213.7 "/>
+ <polygon class="st1" points="176.5,236.5 205.7,213.7 210.4,253 "/>
+ <polygon class="st5" points="173.1,170.2 229.3,167.7 206.6,190.8 "/>
+ <polygon class="st5" points="109.2,190.8 86.4,167.7 142.6,170.2 "/>
+ <polygon class="st5" points="142.6,170.2 129.1,181.7 109.2,190.8 "/>
+ <polygon class="st5" points="206.6,190.8 186.6,181.7 173.1,170.2 "/>
+ <polygon class="st3" points="205.7,213.7 178.3,199.1 206.6,190.8 "/>
+ <polygon class="st3" points="110,213.7 109.2,190.8 137.4,199.1 "/>
+ <polygon class="st9" points="137.4,199.1 109.2,190.8 129.1,181.7 "/>
+ <polygon class="st9" points="178.3,199.1 186.6,181.7 206.6,190.8 "/>
+ <polygon class="st5" points="186.6,181.7 178.3,199.1 173.1,170.2 "/>
+ <polygon class="st5" points="129.1,181.7 142.6,170.2 137.4,199.1 "/>
+ <polygon class="st6" points="199.4,262 177,277.5 178.9,267.9 "/>
+ <polygon class="st6" points="136.8,267.9 138.7,277.5 116.3,262 "/>
+ <polygon class="st4" points="178.3,199.1 171.8,188.4 173.1,170.2 "/>
+ <polygon class="st8" points="137.4,199.1 142.6,170.2 143.9,188.4 "/>
+ <polygon class="st3" points="173.1,170.2 171.8,188.4 143.9,188.4 "/>
+ <polygon class="st3" points="143.9,188.4 142.6,170.2 173.1,170.2 "/>
+ <polygon class="st3" points="178.3,199.1 205.7,213.7 176.5,236.5 "/>
+ <polygon class="st3" points="139.2,236.5 110,213.7 137.4,199.1 "/>
+ <polygon class="st3" points="137.4,199.1 144,233.2 139.2,236.5 "/>
+ <polygon class="st3" points="176.5,236.5 171.7,233.2 178.3,199.1 "/>
+ <polygon class="st8" points="171.8,188.4 178.3,199.1 171.7,233.2 "/>
+ <polygon class="st8" points="143.9,188.4 144,233.2 137.4,199.1 "/>
+ <polygon class="st3" points="143.9,188.4 171.8,188.4 171.7,233.2 "/>
+ <polygon class="st3" points="171.7,233.2 144,233.2 143.9,188.4 "/>
+ <polygon class="st6" points="179.2,258.6 178.9,267.9 177,277.5 "/>
+ <polygon class="st6" points="138.7,277.5 136.8,267.9 136.6,258.6 "/>
+ <polygon class="st6" points="136.6,258.6 139,256.4 138.7,277.5 "/>
+ <polygon class="st6" points="177,277.5 176.7,256.4 179.2,258.6 "/>
+ <polygon class="st6" points="138.7,277.5 139,256.4 176.7,256.4 "/>
+ <polygon class="st6" points="176.7,256.4 177,277.5 138.7,277.5 "/>
+ <polygon class="st10" points="176.5,236.5 179.2,258.6 176.7,256.4 "/>
+ <polygon class="st10" points="139,256.4 136.6,258.6 139.2,236.5 "/>
+ <polygon class="st10" points="139.2,236.5 140.7,241.2 139,256.4 "/>
+ <polygon class="st10" points="176.7,256.4 175,241.2 176.5,236.5 "/>
+ <polygon class="st10" points="143.7,237.7 140.7,241.2 139.2,236.5 "/>
+ <polygon class="st10" points="176.5,236.5 175,241.2 172,237.7 "/>
+ <polygon class="st10" points="172,237.7 171.7,233.2 176.5,236.5 "/>
+ <polygon class="st10" points="139.2,236.5 144,233.2 143.7,237.7 "/>
+ <polygon class="st10" points="171.7,233.2 172,237.7 143.7,237.7 "/>
+ <polygon class="st10" points="143.7,237.7 144,233.2 171.7,233.2 "/>
+ <polygon class="st10" points="140.7,241.2 175,241.2 176.7,256.4 "/>
+ <polygon class="st10" points="176.7,256.4 139,256.4 140.7,241.2 "/>
+ <polygon class="st10" points="140.7,241.2 143.7,237.7 172,237.7 "/>
+ <polygon class="st10" points="172,237.7 175,241.2 140.7,241.2 "/>
+</g>
+</svg>
diff --git a/app/images/mm-bolt.svg b/app/images/mm-bolt.svg
new file mode 100644
index 000000000..bbf0abcc7
--- /dev/null
+++ b/app/images/mm-bolt.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 252 251.7" style="enable-background:new 0 0 252 251.7;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#757575;}
+</style>
+<path class="st0" d="M211.3,103.9h-60.7c-2,0-3.6-1.6-3.6-3.6V3.6c0-3.5-4.5-5-6.6-2.2l-102.7,140c-1.8,2.4,0,5.8,2.9,5.8h60.7
+ c2,0,3.6,1.6,3.6,3.6v96.6c0,3.5,4.5,5,6.6,2.2l102.7-140C216,107.3,214.3,103.9,211.3,103.9z"/>
+</svg>
diff --git a/app/images/mm-info-icon.svg b/app/images/mm-info-icon.svg
new file mode 100644
index 000000000..825f0f200
--- /dev/null
+++ b/app/images/mm-info-icon.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 10 10" style="enable-background:new 0 0 10 10;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#B8B8B8;}
+</style>
+<path class="st0" d="M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0z M5,2c0.4,0,0.7,0.3,0.7,0.7c0,0.4-0.3,0.7-0.7,0.7
+ S4.3,3.2,4.3,2.8C4.3,2.4,4.6,2,5,2z M5.7,8H4.3V4.3h1.5V8z"/>
+</svg>
diff --git a/app/images/open.svg b/app/images/open.svg
new file mode 100644
index 000000000..2957ce43d
--- /dev/null
+++ b/app/images/open.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
+ <title>open</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="Mobile-screens" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="MetaMascara-Mobile---structured" transform="translate(-329.000000, -93.000000)">
+ <g id="open" transform="translate(330.000000, 94.000000)">
+ <path d="M26,13 C26,20.1799 20.1799,26 13,26 C5.8201,26 0,20.1799 0,13 C0,5.8201 5.8201,0 13,0 C20.1799,0 26,5.8201 26,13 Z" id="Stroke-3" stroke="#4A4A4A"></path>
+ <path d="M6,17 C6,17 7.78735344,10.8360387 13.7616996,10.8360387 L13.7616996,8 L19,12.3733433 L13.7616996,17 L13.7616996,14.1639613 C13.7616996,14.1639613 9.54083576,13.4629933 6,17" id="Fill-5" fill="#4A4A4A"></path>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/plus-btn-white.svg b/app/images/plus-btn-white.svg
new file mode 100644
index 000000000..2672d39dd
--- /dev/null
+++ b/app/images/plus-btn-white.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 47 (45396) - http://www.bohemiancoding.com/sketch -->
+ <title>plus-btn-white</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="MetaMascara-v2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="account-dropdown-top-bar-IXD" transform="translate(-24.000000, -669.000000)" fill="#FFFFFF">
+ <g id="Group-6" transform="translate(4.000000, 646.000000)">
+ <g id="plus-btn-white" transform="translate(20.000000, 23.000000)">
+ <rect id="Rectangle-48" x="7.38461538" y="0" width="1.23076923" height="16"></rect>
+ <rect id="Rectangle-48" transform="translate(8.000000, 8.000000) rotate(-90.000000) translate(-8.000000, -8.000000) " x="7.38461538" y="0" width="1.23076923" height="16"></rect>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/popout.svg b/app/images/popout.svg
new file mode 100644
index 000000000..760fe4379
--- /dev/null
+++ b/app/images/popout.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
+ <title>popout</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <polygon id="path-1" points="-0.00035 0 10.9999 0 10.9999 10.9997 -0.00035 10.9997"></polygon>
+ </defs>
+ <g id="MetaMascara-Mobile---structured-TOKEN" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(-327.000000, -96.000000)">
+ <g id="popout" transform="translate(327.000000, 96.000000)">
+ <g id="Group-3" transform="translate(11.000000, 0.000000)">
+ <mask id="mask-2" fill="white">
+ <use xlink:href="#path-1"></use>
+ </mask>
+ <g id="Clip-2"></g>
+ <path d="M10.9229,0.6177 C10.8209,0.3737 10.6269,0.1787 10.3819,0.0767 C10.2599,0.0267 10.1309,-0.0003 9.9999,-0.0003 L3.9999,-0.0003 C3.4479,-0.0003 2.9999,0.4477 2.9999,0.9997 C2.9999,1.5527 3.4479,1.9997 3.9999,1.9997 L7.5859,1.9997 L0.2929,9.2927 C-0.0981,9.6837 -0.0981,10.3167 0.2929,10.7067 C0.4879,10.9027 0.7439,10.9997 0.9999,10.9997 C1.2559,10.9997 1.5119,10.9027 1.7069,10.7067 L8.9999,3.4137 L8.9999,6.9997 C8.9999,7.5527 9.4479,7.9997 9.9999,7.9997 C10.5519,7.9997 10.9999,7.5527 10.9999,6.9997 L10.9999,0.9997 C10.9999,0.8697 10.9739,0.7407 10.9229,0.6177" id="Fill-1" fill="#4A4A4A" mask="url(#mask-2)"></path>
+ </g>
+ <path d="M19,10 C18.448,10 18,10.448 18,11 L18,19 C18,19.551 17.551,20 17,20 L3,20 C2.449,20 2,19.551 2,19 L2,5 C2,4.449 2.449,4 3,4 L11,4 C11.552,4 12,3.552 12,3 C12,2.448 11.552,2 11,2 L3,2 C1.346,2 0,3.346 0,5 L0,19 C0,20.654 1.346,22 3,22 L17,22 C18.654,22 20,20.654 20,19 L20,11 C20,10.448 19.552,10 19,10" id="Fill-4" fill="#4A4A4A"></path>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/settings.svg b/app/images/settings.svg
index fe61320a5..cf9b298dd 100644
--- a/app/images/settings.svg
+++ b/app/images/settings.svg
@@ -1,24 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="24.088px" height="24px" viewBox="0 0 24.088 24" enable-background="new 0 0 24.088 24" xml:space="preserve">
-<path d="M21.525,10.147c-0.41-0.059-0.847-0.428-0.974-0.82l-0.608-1.481c-0.191-0.365-0.146-0.935,0.1-1.264l0.99-1.318
- c0.246-0.33,0.227-0.854-0.047-1.162l-1.084-1.086c-0.31-0.272-0.832-0.293-1.164-0.045l-1.316,0.988
- c-0.33,0.248-0.898,0.293-1.264,0.101l-1.48-0.609c-0.395-0.126-0.764-0.562-0.82-0.971l-0.233-1.629
- c-0.058-0.409-0.44-0.778-0.851-0.822c0,0-0.254-0.026-0.77-0.026c-0.514,0-0.77,0.026-0.77,0.026
- c-0.41,0.044-0.793,0.413-0.852,0.822L10.15,2.48c-0.059,0.409-0.428,0.845-0.82,0.971L7.85,4.06
- C7.484,4.251,6.916,4.207,6.586,3.959L5.268,2.97c-0.33-0.248-0.854-0.228-1.162,0.045L3.021,4.101
- C2.749,4.41,2.727,4.933,2.975,5.263l0.988,1.318c0.249,0.33,0.293,0.899,0.102,1.264l-0.61,1.482
- c-0.125,0.393-0.562,0.762-0.972,0.82l-1.629,0.231c-0.408,0.059-0.776,0.442-0.82,0.853c0,0-0.026,0.255-0.026,0.77
- c0,0.516,0.026,0.77,0.026,0.77c0.044,0.412,0.412,0.793,0.82,0.853l1.629,0.231c0.408,0.06,0.847,0.429,0.972,0.82l0.61,1.48
- c0.191,0.365,0.146,0.936-0.102,1.264l-0.988,1.318c-0.248,0.33-0.308,0.779-0.132,0.994c0.175,0.217,0.677,0.752,0.679,0.754
- c0,0.002,0.17,0.156,0.375,0.344c0.203,0.188,1.041,0.449,1.371,0.203l1.317-0.99c0.33-0.246,0.897-0.293,1.265-0.1l1.479,0.608
- c0.394,0.125,0.763,0.562,0.819,0.972l0.233,1.629c0.058,0.408,0.44,0.779,0.853,0.822c0,0,0.254,0.026,0.769,0.026
- s0.771-0.026,0.771-0.026c0.408-0.043,0.793-0.414,0.85-0.822l0.234-1.629c0.057-0.408,0.426-0.847,0.819-0.972l1.479-0.61
- c0.365-0.191,0.935-0.146,1.265,0.102l1.317,0.99c0.332,0.246,0.854,0.227,1.164-0.047l1.082-1.084
- c0.273-0.312,0.293-0.834,0.047-1.164l-0.989-1.318c-0.246-0.328-0.291-0.898-0.101-1.264l0.609-1.48
- c0.127-0.393,0.562-0.762,0.973-0.82l1.627-0.231c0.41-0.06,0.779-0.44,0.822-0.853c0,0,0.027-0.254,0.027-0.77
- c0-0.515-0.027-0.77-0.027-0.77c-0.043-0.41-0.412-0.794-0.822-0.853L21.525,10.147z M12.004,15.001c-1.657,0-3-1.344-3-3
- c0-1.657,1.343-3,3-3s3,1.344,3,3S13.66,15.001,12.004,15.001z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 47 (45396) - http://www.bohemiancoding.com/sketch -->
+ <title>settings</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <polygon id="path-1" points="20 10 20 19.9998 0 19.9998 0 10 0 0.0002 20 0.0002"></polygon>
+ </defs>
+ <g id="MetaMascara-v2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="account-dropdown-top-bar-IXD" transform="translate(-25.000000, -826.000000)">
+ <g id="Group-6" transform="translate(4.000000, 646.000000)">
+ <g id="settings" transform="translate(21.000000, 180.000000)">
+ <mask id="mask-2" fill="white">
+ <use xlink:href="#path-1"></use>
+ </mask>
+ <g id="Clip-2"></g>
+ <path d="M10,13.6602 C7.979,13.6602 6.34,12.0212 6.34,10.0002 C6.34,7.9782 7.979,6.3402 10,6.3402 C12.021,6.3402 13.66,7.9782 13.66,10.0002 C13.66,12.0212 12.021,13.6602 10,13.6602 L10,13.6602 Z M19.157,11.8112 C19.53,11.8112 19.878,11.5092 19.929,11.1392 C19.929,11.1392 20,10.6182 20,10.0002 C20,9.3822 19.929,8.8622 19.929,8.8622 C19.878,8.4922 19.53,8.1892 19.157,8.1892 L17.228,8.1892 C16.854,8.1892 16.466,7.9512 16.365,7.6602 C16.265,7.3682 16.127,6.4352 16.391,6.1712 L17.755,4.8072 C18.019,4.5432 18.039,4.0922 17.8,3.8052 L16.195,2.2002 C15.908,1.9602 15.458,1.9812 15.193,2.2452 L13.829,3.6092 C13.565,3.8732 13.125,3.9802 12.852,3.8462 C12.578,3.7122 11.812,3.1462 11.812,2.7732 L11.812,0.8432 C11.812,0.4702 11.509,0.1222 11.139,0.0722 C11.139,0.0722 10.619,0.0002 10,0.0002 C9.382,0.0002 8.862,0.0722 8.862,0.0722 C8.492,0.1222 8.189,0.4702 8.189,0.8432 L8.189,2.7732 C8.189,3.1462 7.951,3.5352 7.66,3.6352 C7.369,3.7352 6.435,3.8732 6.171,3.6092 L4.807,2.2452 C4.542,1.9812 4.092,1.9612 3.805,2.2002 L2.2,3.8052 C1.96,4.0922 1.981,4.5432 2.245,4.8072 L3.609,6.1712 C3.873,6.4352 3.98,6.8752 3.846,7.1482 C3.711,7.4222 3.146,8.1892 2.773,8.1892 L0.843,8.1892 C0.47,8.1892 0.123,8.4922 0.072,8.8622 C0.072,8.8622 0,9.3822 0,10.0002 C0,10.6182 0.072,11.1392 0.072,11.1392 C0.123,11.5092 0.47,11.8112 0.843,11.8112 L2.773,11.8112 C3.146,11.8112 3.535,12.0502 3.635,12.3412 C3.735,12.6322 3.874,13.5642 3.609,13.8292 L2.246,15.1932 C1.981,15.4572 1.961,15.9082 2.2,16.1952 L3.805,17.8002 C4.092,18.0392 4.542,18.0192 4.807,17.7552 L6.171,16.3902 C6.435,16.1272 6.875,16.0202 7.148,16.1542 C7.422,16.2882 8.189,16.8532 8.189,17.2272 L8.189,19.1572 C8.189,19.5302 8.492,19.8782 8.862,19.9292 C8.862,19.9292 9.382,20.0002 10,20.0002 C10.619,20.0002 11.139,19.9292 11.139,19.9292 C11.509,19.8772 11.812,19.5302 11.812,19.1572 L11.812,17.2272 C11.812,16.8532 12.05,16.4662 12.341,16.3652 C12.632,16.2642 13.565,16.1272 13.829,16.3902 L15.193,17.7552 C15.458,18.0182 15.908,18.0392 16.195,17.8002 L17.8,16.1952 C18.039,15.9082 18.02,15.4582 17.755,15.1932 L16.391,13.8292 C16.127,13.5652 16.021,13.1252 16.154,12.8512 C16.288,12.5782 16.854,11.8112 17.228,11.8112 L19.157,11.8112 Z" id="Fill-1" fill="#B3B3B3" mask="url(#mask-2)"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/images/shapeshift logo.png b/app/images/shapeshift logo.png
new file mode 100644
index 000000000..ac8faba5b
--- /dev/null
+++ b/app/images/shapeshift logo.png
Binary files differ
diff --git a/app/manifest.json b/app/manifest.json
index 3a80cc4fc..c4e134053 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "3.14.2",
+ "version": "4.0.12",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/notification.html b/app/notification.html
index cc485da7f..f10cbbf41 100644
--- a/app/notification.html
+++ b/app/notification.html
@@ -1,5 +1,5 @@
<!doctype html>
-<html>
+<html style="height:600px;">
<head>
<meta charset="utf-8">
<title>MetaMask Notification</title>
@@ -9,7 +9,7 @@
}
</style>
</head>
- <body>
+ <body class="notification" style="height:600px;">
<div id="app-content"></div>
<script src="./scripts/popup.js" type="text/javascript" charset="utf-8"></script>
</body>
diff --git a/app/popup.html b/app/popup.html
index d09b09315..bf09b97ca 100644
--- a/app/popup.html
+++ b/app/popup.html
@@ -1,11 +1,11 @@
<!doctype html>
-<html>
+<html style="width:357px; height:600px;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1 user-scalable=no">
<title>MetaMask Plugin</title>
</head>
- <body style="width:357px; height:500px;">
+ <body style="width:357px; height:600px;">
<div id="app-content"></div>
<script src="./scripts/popup.js" type="text/javascript" charset="utf-8"></script>
</body>
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 7bececba1..9dd438dc9 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -38,6 +38,7 @@ const isIE = !!document.documentMode
const isEdge = !isIE && !!window.StyleMedia
let popupIsOpen = false
+let openMetamaskTabsIDs = {}
// state persistence
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
@@ -125,9 +126,15 @@ function setupController (initState) {
popupIsOpen = popupIsOpen || (remotePort.name === 'popup')
controller.setupTrustedCommunication(portStream, 'MetaMask')
// record popup as closed
+ if (remotePort.sender.url.match(/home.html$/)) {
+ openMetamaskTabsIDs[remotePort.sender.tab.id] = true
+ }
if (remotePort.name === 'popup') {
endOfStream(portStream, () => {
popupIsOpen = false
+ if (remotePort.sender.url.match(/home.html$/)) {
+ openMetamaskTabsIDs[remotePort.sender.tab.id] = false
+ }
})
}
} else {
@@ -170,7 +177,10 @@ function setupController (initState) {
// popup trigger
function triggerUi () {
- if (!popupIsOpen) notificationManager.showPopup()
+ extension.tabs.query({ active: true }, (tabs) => {
+ const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id])
+ if (!popupIsOpen && !currentlyActiveMetamaskTab) notificationManager.showPopup()
+ })
}
// On first install, open a window to MetaMask website to how-it-works.
diff --git a/app/scripts/config.js b/app/scripts/config.js
index 1d4ff7c0d..74c5b576e 100644
--- a/app/scripts/config.js
+++ b/app/scripts/config.js
@@ -4,6 +4,15 @@ const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask'
const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask'
const LOCALHOST_RPC_URL = 'http://localhost:8545'
+const MAINET_RPC_URL_BETA = 'https://mainnet.infura.io/metamask2'
+const ROPSTEN_RPC_URL_BETA = 'https://ropsten.infura.io/metamask2'
+const KOVAN_RPC_URL_BETA = 'https://kovan.infura.io/metamask2'
+const RINKEBY_RPC_URL_BETA = 'https://rinkeby.infura.io/metamask2'
+
+const DEFAULT_RPC = 'rinkeby'
+const OLD_UI_NETWORK_TYPE = 'network'
+const BETA_UI_NETWORK_TYPE = 'networkBeta'
+
global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
module.exports = {
@@ -14,9 +23,22 @@ module.exports = {
kovan: KOVAN_RPC_URL,
rinkeby: RINKEBY_RPC_URL,
},
+ // Used for beta UI
+ networkBeta: {
+ localhost: LOCALHOST_RPC_URL,
+ mainnet: MAINET_RPC_URL_BETA,
+ ropsten: ROPSTEN_RPC_URL_BETA,
+ kovan: KOVAN_RPC_URL_BETA,
+ rinkeby: RINKEBY_RPC_URL_BETA,
+ },
networkNames: {
3: 'Ropsten',
4: 'Rinkeby',
42: 'Kovan',
},
+ enums: {
+ DEFAULT_RPC,
+ OLD_UI_NETWORK_TYPE,
+ BETA_UI_NETWORK_TYPE,
+ },
}
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js
index a1db8946a..617456cd7 100644
--- a/app/scripts/controllers/network.js
+++ b/app/scripts/controllers/network.js
@@ -8,14 +8,19 @@ const ComposedStore = require('obs-store/lib/composed')
const extend = require('xtend')
const EthQuery = require('eth-query')
const createEventEmitterProxy = require('../lib/events-proxy.js')
-const RPC_ADDRESS_LIST = require('../config.js').network
-const DEFAULT_RPC = RPC_ADDRESS_LIST['rinkeby']
+const networkConfig = require('../config.js')
+const { OLD_UI_NETWORK_TYPE, DEFAULT_RPC } = networkConfig.enums
const INFURA_PROVIDER_TYPES = ['ropsten', 'rinkeby', 'kovan', 'mainnet']
module.exports = class NetworkController extends EventEmitter {
constructor (config) {
super()
+
+ this._networkEndpointVersion = OLD_UI_NETWORK_TYPE
+ this._networkEndpoints = this.getNetworkEndpoints(OLD_UI_NETWORK_TYPE)
+ this._defaultRpc = this._networkEndpoints[DEFAULT_RPC]
+
config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider)
this.networkStore = new ObservableStore('loading')
this.providerStore = new ObservableStore(config.provider)
@@ -25,6 +30,23 @@ module.exports = class NetworkController extends EventEmitter {
this.on('networkDidChange', this.lookupNetwork)
}
+ async setNetworkEndpoints (version) {
+ if (version === this._networkEndpointVersion) {
+ return
+ }
+
+ this._networkEndpointVersion = version
+ this._networkEndpoints = this.getNetworkEndpoints(version)
+ this._defaultRpc = this._networkEndpoints[DEFAULT_RPC]
+ const { type } = this.getProviderConfig()
+
+ return this.setProviderType(type, true)
+ }
+
+ getNetworkEndpoints (version = OLD_UI_NETWORK_TYPE) {
+ return networkConfig[version]
+ }
+
initializeProvider (_providerParams) {
this._baseProviderParams = _providerParams
const { type, rpcTarget } = this.providerStore.getState()
@@ -84,10 +106,13 @@ module.exports = class NetworkController extends EventEmitter {
return this.getRpcAddressForType(provider.type)
}
- async setProviderType (type) {
+ async setProviderType (type, forceUpdate = false) {
assert(type !== 'rpc', `NetworkController.setProviderType - cannot connect by type "rpc"`)
// skip if type already matches
- if (type === this.getProviderConfig().type) return
+ if (type === this.getProviderConfig().type && !forceUpdate) {
+ return
+ }
+
const rpcTarget = this.getRpcAddressForType(type)
assert(rpcTarget, `NetworkController - unknown rpc address for type "${type}"`)
this.providerStore.updateState({ type, rpcTarget })
@@ -99,8 +124,11 @@ module.exports = class NetworkController extends EventEmitter {
}
getRpcAddressForType (type, provider = this.getProviderConfig()) {
- if (RPC_ADDRESS_LIST[type]) return RPC_ADDRESS_LIST[type]
- return provider && provider.rpcTarget ? provider.rpcTarget : DEFAULT_RPC
+ if (this._networkEndpoints[type]) {
+ return this._networkEndpoints[type]
+ }
+
+ return provider && provider.rpcTarget ? provider.rpcTarget : this._defaultRpc
}
//
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index c42f47037..39d15fd83 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -9,11 +9,21 @@ class PreferencesController {
frequentRpcList: [],
currentAccountTab: 'history',
tokens: [],
+ useBlockie: false,
+ featureFlags: {},
}, opts.initState)
this.store = new ObservableStore(initState)
}
// PUBLIC METHODS
+ setUseBlockie (val) {
+ this.store.updateState({ useBlockie: val })
+ }
+
+ getUseBlockie () {
+ return this.store.getState().useBlockie
+ }
+
setSelectedAddress (_address) {
return new Promise((resolve, reject) => {
const address = normalizeAddress(_address)
@@ -43,6 +53,17 @@ class PreferencesController {
}
this.store.updateState({ tokens })
+
+ return Promise.resolve(tokens)
+ }
+
+ removeToken (rawAddress) {
+ const tokens = this.store.getState().tokens
+
+ const updatedTokens = tokens.filter(token => token.address !== rawAddress)
+
+ this.store.updateState({ tokens: updatedTokens })
+ return Promise.resolve(updatedTokens)
}
getTokens () {
@@ -82,6 +103,22 @@ class PreferencesController {
getFrequentRpcList () {
return this.store.getState().frequentRpcList
}
+
+ setFeatureFlag (feature, activated) {
+ const currentFeatureFlags = this.store.getState().featureFlags
+ const updatedFeatureFlags = {
+ ...currentFeatureFlags,
+ [feature]: activated,
+ }
+
+ this.store.updateState({ featureFlags: updatedFeatureFlags })
+
+ return Promise.resolve(updatedFeatureFlags)
+ }
+
+ getFeatureFlags () {
+ return this.store.getState().featureFlags
+ }
//
// PRIVATE METHODS
//
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index a3670155a..ef5578d5a 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -233,6 +233,10 @@ module.exports = class TransactionController extends EventEmitter {
this.txStateManager.updateTx(txMeta, 'retryTransaction: manual retry')
}
+ async updateTransaction (txMeta) {
+ this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction')
+ }
+
async updateAndApproveTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction')
await this.approveTransaction(txMeta.id)
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index 9c0dffe9c..34b603b96 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -42,6 +42,17 @@ ConfigManager.prototype.getData = function () {
return this.store.getState()
}
+ConfigManager.prototype.setPasswordForgotten = function (passwordForgottenState) {
+ const data = this.getData()
+ data.forgottenPassword = passwordForgottenState
+ this.setData(data)
+}
+
+ConfigManager.prototype.getPasswordForgotten = function (passwordForgottenState) {
+ const data = this.getData()
+ return data.forgottenPassword
+}
+
ConfigManager.prototype.setWallet = function (wallet) {
var data = this.getData()
data.wallet = wallet
diff --git a/app/scripts/lib/environment-type.js b/app/scripts/lib/environment-type.js
new file mode 100644
index 000000000..7966926eb
--- /dev/null
+++ b/app/scripts/lib/environment-type.js
@@ -0,0 +1,10 @@
+module.exports = function environmentType () {
+ const url = window.location.href
+ if (url.match(/popup.html$/)) {
+ return 'popup'
+ } else if (url.match(/home.html$/)) {
+ return 'responsive'
+ } else {
+ return 'notification'
+ }
+}
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
index 693fa8751..e2999411f 100644
--- a/app/scripts/lib/is-popup-or-notification.js
+++ b/app/scripts/lib/is-popup-or-notification.js
@@ -1,6 +1,9 @@
module.exports = function isPopupOrNotification () {
const url = window.location.href
- if (url.match(/popup.html$/)) {
+ // if (url.match(/popup.html$/) || url.match(/home.html$/)) {
+ // Below regexes needed for feature toggles (e.g. see line ~340 in ui/app/app.js)
+ // Revert below regexes to above commented out regexes before merge to master
+ if (url.match(/popup.html(?:\?.+)*$/) || url.match(/home.html(?:\?.+)*$/)) {
return 'popup'
} else {
return 'notification'
diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js
index 7846ef7f0..adaf60c65 100644
--- a/app/scripts/lib/notification-manager.js
+++ b/app/scripts/lib/notification-manager.js
@@ -1,5 +1,5 @@
const extension = require('extensionizer')
-const height = 520
+const height = 620
const width = 360
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 428c78e2c..ad4e71792 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -310,6 +310,7 @@ module.exports = class MetamaskController extends EventEmitter {
{
lostAccounts: this.configManager.getLostAccounts(),
seedWords: this.configManager.getSeedWords(),
+ forgottenPassword: this.configManager.getPasswordForgotten(),
}
)
}
@@ -330,7 +331,10 @@ module.exports = class MetamaskController extends EventEmitter {
// etc
getState: (cb) => cb(null, this.getState()),
setCurrentCurrency: this.setCurrentCurrency.bind(this),
+ setUseBlockie: this.setUseBlockie.bind(this),
markAccountsFound: this.markAccountsFound.bind(this),
+ markPasswordForgotten: this.markPasswordForgotten.bind(this),
+ unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this),
// coinbase
buyEth: this.buyEth.bind(this),
@@ -348,13 +352,16 @@ module.exports = class MetamaskController extends EventEmitter {
submitPassword: nodeify(keyringController.submitPassword, keyringController),
// network management
+ setNetworkEndpoints: nodeify(networkController.setNetworkEndpoints, networkController),
setProviderType: nodeify(networkController.setProviderType, networkController),
setCustomRpc: nodeify(this.setCustomRpc, this),
// PreferencesController
setSelectedAddress: nodeify(preferencesController.setSelectedAddress, preferencesController),
addToken: nodeify(preferencesController.addToken, preferencesController),
+ removeToken: nodeify(preferencesController.removeToken, preferencesController),
setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab, preferencesController),
+ setFeatureFlag: nodeify(preferencesController.setFeatureFlag, preferencesController),
// AddressController
setAddressBook: nodeify(addressBookController.setAddressBook, addressBookController),
@@ -369,6 +376,7 @@ module.exports = class MetamaskController extends EventEmitter {
// txController
cancelTransaction: nodeify(txController.cancelTransaction, txController),
+ updateTransaction: nodeify(txController.updateTransaction, txController),
updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController),
retryTransaction: nodeify(this.retryTransaction, this),
@@ -789,6 +797,18 @@ module.exports = class MetamaskController extends EventEmitter {
cb(null, this.getState())
}
+ markPasswordForgotten(cb) {
+ this.configManager.setPasswordForgotten(true)
+ this.sendUpdate()
+ cb()
+ }
+
+ unMarkPasswordForgotten(cb) {
+ this.configManager.setPasswordForgotten(false)
+ this.sendUpdate()
+ cb()
+ }
+
restoreOldVaultAccounts (migratorOutput) {
const { serialized } = migratorOutput
return this.keyringController.restoreKeyring(serialized)
@@ -856,6 +876,15 @@ module.exports = class MetamaskController extends EventEmitter {
return rpcTarget
}
+ setUseBlockie (val, cb) {
+ try {
+ this.preferencesController.setUseBlockie(val)
+ cb(null)
+ } catch (err) {
+ cb(err)
+ }
+ }
+
recordFirstTimeInfo (initState) {
if (!('firstTimeInfo' in initState)) {
initState.firstTimeInfo = {
diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js
index 2f47512eb..f5cc255d1 100644
--- a/app/scripts/platforms/extension.js
+++ b/app/scripts/platforms/extension.js
@@ -17,6 +17,11 @@ class ExtensionPlatform {
return extension.runtime.getManifest().version
}
+ openExtensionInBrowser () {
+ const extensionURL = extension.runtime.getURL('home.html')
+ this.openWindow({ url: extensionURL })
+ }
+
getPlatformInfo (cb) {
try {
extension.runtime.getPlatformInfo((platform) => {
diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js
index f1eb394d7..2e4334bb1 100644
--- a/app/scripts/popup-core.js
+++ b/app/scripts/popup-core.js
@@ -1,6 +1,7 @@
const EventEmitter = require('events').EventEmitter
const async = require('async')
const Dnode = require('dnode')
+const Eth = require('ethjs')
const EthQuery = require('eth-query')
const launchMetamaskUi = require('../../ui')
const StreamProvider = require('web3-stream-provider')
@@ -34,6 +35,7 @@ function setupWeb3Connection (connectionStream) {
providerStream.on('error', console.error.bind(console))
global.ethereumProvider = providerStream
global.ethQuery = new EthQuery(providerStream)
+ global.eth = new Eth(providerStream)
}
function setupControllerConnection (connectionStream, cb) {
diff --git a/app/scripts/popup.js b/app/scripts/popup.js
index 860cc567d..53ab00e00 100644
--- a/app/scripts/popup.js
+++ b/app/scripts/popup.js
@@ -1,5 +1,6 @@
const injectCss = require('inject-css')
-const MetaMaskUiCss = require('../../ui/css')
+const OldMetaMaskUiCss = require('../../old-ui/css')
+const NewMetaMaskUiCss = require('../../ui/css')
const startPopup = require('./popup-core')
const PortStream = require('./lib/port-stream.js')
const isPopupOrNotification = require('./lib/is-popup-or-notification')
@@ -17,8 +18,8 @@ const release = global.platform.getVersion()
setupRaven({ release })
// inject css
-const css = MetaMaskUiCss()
-injectCss(css)
+// const css = MetaMaskUiCss()
+// injectCss(css)
// identify window type (popup, notification)
const windowType = isPopupOrNotification()
@@ -33,8 +34,30 @@ const connectionStream = new PortStream(extensionPort)
const container = document.getElementById('app-content')
startPopup({ container, connectionStream }, (err, store) => {
if (err) return displayCriticalError(err)
+
+ // Code commented out until we begin auto adding users to NewUI
+ // const { isMascara, identities = {}, featureFlags = {} } = store.getState().metamask
+ // const firstTime = Object.keys(identities).length === 0
+ const { isMascara, featureFlags = {} } = store.getState().metamask
+ let betaUIState = featureFlags.betaUI
+
+ // Code commented out until we begin auto adding users to NewUI
+ // const useBetaCss = isMascara || firstTime || betaUIState
+ const useBetaCss = isMascara || betaUIState
+
+ let css = useBetaCss ? NewMetaMaskUiCss() : OldMetaMaskUiCss()
+ let deleteInjectedCss = injectCss(css)
+ let newBetaUIState
+
store.subscribe(() => {
const state = store.getState()
+ newBetaUIState = state.metamask.featureFlags.betaUI
+ if (newBetaUIState !== betaUIState) {
+ deleteInjectedCss()
+ betaUIState = newBetaUIState
+ css = betaUIState ? NewMetaMaskUiCss() : OldMetaMaskUiCss()
+ deleteInjectedCss = injectCss(css)
+ }
if (state.appState.shouldClose) notificationManager.closePopup()
})
})
diff --git a/development/backGroundConnectionModifiers.js b/development/backGroundConnectionModifiers.js
new file mode 100644
index 000000000..ffbe49d4d
--- /dev/null
+++ b/development/backGroundConnectionModifiers.js
@@ -0,0 +1,26 @@
+module.exports = {
+ "confirm sig requests": {
+ signMessage: (msgData, cb) => {
+ const stateUpdate = {
+ unapprovedMsgs: {},
+ unapprovedMsgCount: 0,
+ }
+ return cb(null, stateUpdate)
+ },
+ signPersonalMessage: (msgData, cb) => {
+ const stateUpdate = {
+ unapprovedPersonalMsgs: {},
+ unapprovedPersonalMsgsCount: 0,
+ }
+ return cb(null, stateUpdate)
+ },
+ signTypedMessage: (msgData, cb) => {
+ const stateUpdate = {
+ unapprovedTypedMessages: {},
+ unapprovedTypedMessagesCount: 0,
+ }
+ return cb(null, stateUpdate)
+ },
+ },
+}
+
diff --git a/development/mockExtension.js b/development/mockExtension.js
index 55799b2bf..ac03d965c 100644
--- a/development/mockExtension.js
+++ b/development/mockExtension.js
@@ -37,3 +37,8 @@ apis.forEach(function (api) {
extension.runtime.reload = noop
extension.tabs.create = noop
+extension.runtime.getManifest = function () {
+ return {
+ version: 'development'
+ }
+} \ No newline at end of file
diff --git a/development/selector.js b/development/selector.js
index c466905ca..fd387df15 100644
--- a/development/selector.js
+++ b/development/selector.js
@@ -11,7 +11,14 @@ function NewComponent () {
NewComponent.prototype.render = function () {
const props = this.props
- let { states, selectedKey, actions, store } = props
+ let {
+ states,
+ selectedKey,
+ actions,
+ store,
+ modifyBackgroundConnection,
+ backGroundConnectionModifiers,
+ } = props
const state = this.state || {}
const selected = state.selected || selectedKey
@@ -23,6 +30,8 @@ NewComponent.prototype.render = function () {
value: selected,
onChange:(event) => {
const selectedKey = event.target.value
+ const backgroundConnectionModifier = backGroundConnectionModifiers[selectedKey]
+ modifyBackgroundConnection(backgroundConnectionModifier || {})
store.dispatch(actions.update(selectedKey))
this.setState({ selected: selectedKey })
},
diff --git a/development/states/add-token.json b/development/states/add-token.json
new file mode 100644
index 000000000..e78393b7f
--- /dev/null
+++ b/development/states/add-token.json
@@ -0,0 +1,132 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedMsgs": {},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "currentCurrency": "USD",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": null,
+ "gasPrice": null,
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": "",
+ "to": "",
+ "amount": "0x0",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ }
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail",
+ "detailView": null,
+ "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/states/confirm-new-ui.json b/development/states/confirm-new-ui.json
new file mode 100644
index 000000000..6ea8e64cd
--- /dev/null
+++ b/development/states/confirm-new-ui.json
@@ -0,0 +1,154 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "currentCurrency": "USD",
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedTxs": {
+ "4768706228115573": {
+ "id": 4768706228115573,
+ "time": 1487363153561,
+ "status": "unapproved",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "value": "0x1bc16d674ec80000",
+ "metamaskId": 4768706228115573,
+ "metamaskNetworkId": "3",
+ "gas": "0xea60",
+ "gasPrice": "0xba43b7400"
+ }
+ }
+ },
+ "unapprovedMsgs": {},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "currentCurrency": "USD",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": "0xea60",
+ "gasPrice": "0xba43b7400",
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "balance": "0x37452b1315889f80"
+ },
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "amount": "0x1bc16d674ec80000",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ }
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "confTx",
+ "detailView": null,
+ "context": 0
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/states/confirm-sig-requests.json b/development/states/confirm-sig-requests.json
new file mode 100644
index 000000000..0a691e948
--- /dev/null
+++ b/development/states/confirm-sig-requests.json
@@ -0,0 +1,175 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "currentCurrency": "USD",
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedTxs": {},
+ "unapprovedMsgs": {
+ "8927167822566864": {
+ "id": 8927167822566864,
+ "msgParams": {
+ "data": "0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0",
+ "from": "0x0d0c7188d9c72b019a5da9bca0d127680c22e658"
+ },
+ "status": "unapproved",
+ "time": 1537889069339,
+ "type": "eth_sign"
+ }
+ },
+ "unapprovedMsgCount": 1,
+ "unapprovedPersonalMsgs": {
+ "8907167822566865": {
+ "id": 8907167822566865,
+ "msgParams": {
+ "data": "0x23205465726d73206f662055736520230a0a2a2a544849532041475245454d454e54204953205355424a45435420544f2042494e44494e47204152424954524154494f4e20414e44204120574149564552204f4620434c41535320414354494f4e205249474854532041532044455441494c454420494e2053454354494f4e2031332e20504c454153452052454144205448452041475245454d454e54204341524546554c4c592e2a2a0a0a5f4f7572205465726d73206f66205573652068617665206265656e2075706461746564206173206f662053657074656d62657220352c20323031365f0a0a232320312e20416363657074616e6365206f66205465726d732023230a0a4d6574614d61736b2070726f7669646573206120706c6174666f726d20666f72206d616e6167696e6720457468657265756d20286f7220224554482229206163636f756e74732c20616e6420616c6c6f77696e67206f7264696e61727920776562736974657320746f20696e74657261637420776974682074686520457468657265756d20626c6f636b636861696e2c207768696c65206b656570696e6720746865207573657220696e20636f6e74726f6c206f7665722077686174207472616e73616374696f6e73207468657920617070726f76652c207468726f756768206f75722077656273697465206c6f63617465642061745b205d28687474703a2f2f6d6574616d61736b2e696f295b68747470733a2f2f6d6574616d61736b2e696f2f5d2868747470733a2f2f6d6574616d61736b2e696f2f2920616e642062726f7773657220706c7567696e2028746865202253697465222920e2809420776869636820696e636c7564657320746578742c20696d616765732c20617564696f2c20636f646520616e64206f74686572206d6174657269616c73202028636f6c6c6563746976656c792c2074686520e2809c436f6e74656e74e2809d2920616e6420616c6c206f66207468652066656174757265732c20616e642073657276696365732070726f76696465642e2054686520536974652c20616e6420616e79206f746865722066656174757265732c20746f6f6c732c206d6174657269616c732c206f72206f74686572207365727669636573206f6666657265642066726f6d2074696d6520746f2074696d65206279204d6574614d61736b2061726520726566657272656420746f20686572652061732074686520e2809c536572766963652ee2809d20506c656173652072656164207468657365205465726d73206f6620557365202874686520e2809c5465726d73e2809d206f7220e2809c5465726d73206f6620557365e2809d29206361726566756c6c79206265666f7265207573696e672074686520536572766963652e204279207573696e67206f72206f746865727769736520616363657373696e67207468652053657276696365732c206f7220636c69636b696e6720746f20616363657074206f7220616772656520746f207468657365205465726d732077686572652074686174206f7074696f6e206973206d61646520617661696c61626c652c20796f75202831292061636365707420616e6420616772656520746f207468657365205465726d732028322920636f6e73656e7420746f2074686520636f6c6c656374696f6e2c207573652c20646973636c6f7375726520616e64206f746865722068616e646c696e67206f6620696e666f726d6174696f6e2061732064657363726962656420696e206f7572205072697661637920506f6c6963792020616e642028332920616e79206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e20697373756564206279204d6574614d61736b2066726f6d2074696d6520746f2074696d652e20496620796f7520646f206e6f7420616772656520746f20746865205465726d732c207468656e20796f75206d6179206e6f7420616363657373206f72207573652074686520436f6e74656e74206f722053657276696365732e0a0a232320322e204d6f64696669636174696f6e206f66205465726d73206f66205573652023230a0a45786365707420666f722053656374696f6e2031332c2070726f766964696e6720666f722062696e64696e67206172626974726174696f6e20616e6420776169766572206f6620636c61737320616374696f6e207269676874732c204d6574614d61736b207265736572766573207468652072696768742c2061742069747320736f6c652064697363726574696f6e2c20746f206d6f64696679206f72207265706c61636520746865205465726d73206f662055736520617420616e792074696d652e20546865206d6f73742063757272656e742076657273696f6e206f66207468657365205465726d732077696c6c20626520706f73746564206f6e206f757220536974652e20596f75207368616c6c20626520726573706f6e7369626c6520666f7220726576696577696e6720616e64206265636f6d696e672066616d696c696172207769746820616e792073756368206d6f64696669636174696f6e732e20557365206f662074686520536572766963657320627920796f7520616674657220616e79206d6f64696669636174696f6e20746f20746865205465726d7320636f6e737469747574657320796f757220616363657074616e6365206f6620746865205465726d73206f6620557365206173206d6f6469666965642e0a0a0a0a232320332e20456c69676962696c6974792023230a0a596f752068657265627920726570726573656e7420616e642077617272616e74207468617420796f75206172652066756c6c792061626c6520616e6420636f6d706574656e7420746f20656e74657220696e746f20746865207465726d732c20636f6e646974696f6e732c206f626c69676174696f6e732c2061666669726d6174696f6e732c20726570726573656e746174696f6e7320616e642077617272616e746965732073657420666f72746820696e207468657365205465726d7320616e6420746f20616269646520627920616e6420636f6d706c792077697468207468657365205465726d732e0a0a4d6574614d61736b206973206120676c6f62616c20706c6174666f726d20616e6420627920616363657373696e672074686520436f6e74656e74206f722053657276696365732c20796f752061726520726570726573656e74696e6720616e642077617272616e74696e6720746861742c20796f7520617265206f6620746865206c6567616c20616765206f66206d616a6f7269747920696e20796f7572206a7572697364696374696f6e20617320697320726571756972656420746f20616363657373207375636820536572766963657320616e6420436f6e74656e…16e79206368616e67657320746f20746869732073656374696f6e2e204368616e6765732077696c6c206265636f6d6520656666656374697665206f6e207468652036307468206461792c20616e642077696c6c206170706c792070726f73706563746976656c79206f6e6c7920746f20616e7920636c61696d732061726973696e67206166746572207468652036307468206461792e0a0a466f7220616e792064697370757465206e6f74207375626a65637420746f206172626974726174696f6e20796f7520616e64204d6574614d61736b20616772656520746f207375626d697420746f2074686520706572736f6e616c20616e64206578636c7573697665206a7572697364696374696f6e206f6620616e642076656e756520696e20746865206665646572616c20616e6420737461746520636f75727473206c6f636174656420696e204e657720596f726b2c204e657720596f726b2e20596f75206675727468657220616772656520746f206163636570742073657276696365206f662070726f63657373206279206d61696c2c20616e642068657265627920776169766520616e7920616e6420616c6c206a7572697364696374696f6e616c20616e642076656e756520646566656e736573206f746865727769736520617661696c61626c652e0a0a546865205465726d7320616e64207468652072656c6174696f6e73686970206265747765656e20796f7520616e64204d6574614d61736b207368616c6c20626520676f7665726e656420627920746865206c617773206f6620746865205374617465206f66204e657720596f726b20776974686f75742072656761726420746f20636f6e666c696374206f66206c61772070726f766973696f6e732e0a0a23232031342e2047656e6572616c20496e666f726d6174696f6e2023230a0a2323232031342e3120456e746972652041677265656d656e74202323230a0a5468657365205465726d732028616e6420616e79206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e2074686174204d6574614d61736b206d617920706f7374206f6e2074686520536572766963652920636f6e737469747574652074686520656e746972652061677265656d656e74206265747765656e20796f7520616e64204d6574614d61736b2077697468207265737065637420746f20746865205365727669636520616e64207375706572736564657320616e79207072696f722061677265656d656e74732c206f72616c206f72207772697474656e2c206265747765656e20796f7520616e64204d6574614d61736b2e20496e20746865206576656e74206f66206120636f6e666c696374206265747765656e207468657365205465726d7320616e6420746865206164646974696f6e616c207465726d732c2072756c657320616e6420636f6e646974696f6e73206f662070617274696369706174696f6e2c20746865206c61747465722077696c6c207072657661696c206f76657220746865205465726d7320746f2074686520657874656e74206f662074686520636f6e666c6963742e0a0a2323232031342e322057616976657220616e642053657665726162696c697479206f66205465726d73202323230a0a546865206661696c757265206f66204d6574614d61736b20746f206578657263697365206f7220656e666f72636520616e79207269676874206f722070726f766973696f6e206f6620746865205465726d73207368616c6c206e6f7420636f6e73746974757465206120776169766572206f662073756368207269676874206f722070726f766973696f6e2e20496620616e792070726f766973696f6e206f6620746865205465726d7320697320666f756e6420627920616e2061726269747261746f72206f7220636f757274206f6620636f6d706574656e74206a7572697364696374696f6e20746f20626520696e76616c69642c207468652070617274696573206e657665727468656c6573732061677265652074686174207468652061726269747261746f72206f7220636f7572742073686f756c6420656e646561766f7220746f20676976652065666665637420746f2074686520706172746965732720696e74656e74696f6e73206173207265666c656374656420696e207468652070726f766973696f6e2c20616e6420746865206f746865722070726f766973696f6e73206f6620746865205465726d732072656d61696e20696e2066756c6c20666f72636520616e64206566666563742e0a0a2323232031342e332053746174757465206f66204c696d69746174696f6e73202323230a0a596f752061677265652074686174207265676172646c657373206f6620616e792073746174757465206f72206c617720746f2074686520636f6e74726172792c20616e7920636c61696d206f72206361757365206f6620616374696f6e2061726973696e67206f7574206f66206f722072656c6174656420746f2074686520757365206f66207468652053657276696365206f7220746865205465726d73206d7573742062652066696c65642077697468696e206f6e65202831292079656172206166746572207375636820636c61696d206f72206361757365206f6620616374696f6e2061726f7365206f7220626520666f7265766572206261727265642e0a0a2323232031342e342053656374696f6e205469746c6573202323230a0a5468652073656374696f6e207469746c657320696e20746865205465726d732061726520666f7220636f6e76656e69656e6365206f6e6c7920616e642068617665206e6f206c6567616c206f7220636f6e747261637475616c206566666563742e0a0a2323232031342e3520436f6d6d756e69636174696f6e73202323230a0a55736572732077697468207175657374696f6e732c20636f6d706c61696e7473206f7220636c61696d732077697468207265737065637420746f207468652053657276696365206d617920636f6e74616374207573207573696e67207468652072656c6576616e7420636f6e7461637420696e666f726d6174696f6e2073657420666f7274682061626f766520616e6420617420636f6d6d756e69636174696f6e73406d6574616d61736b2e696f2e0a0a23232031352052656c61746564204c696e6b732023230a0a2a2a5b5465726d73206f66205573655d2868747470733a2f2f6d6574616d61736b2e696f2f7465726d732e68746d6c292a2a0a0a2a2a5b507269766163795d2868747470733a2f2f6d6574616d61736b2e696f2f707269766163792e68746d6c292a2a0a0a2a2a5b4174747269627574696f6e735d2868747470733a2f2f6d6574616d61736b2e696f2f6174747269627574696f6e732e68746d6c292a2a0a",
+ "from": "0x0d0c7188d9c72b019a5da9bca0d127680c22e659"
+ },
+ "status": "unapproved",
+ "time": 1517889069339,
+ "type": "personal_sign"
+ }
+ },
+ "unapprovedPersonalMsgCount": 0,
+ "unapprovedTypedMessages": {
+ "8997167822566869": {
+ "id": 8997167822566869,
+ "msgParams": {
+ "data": [
+ {"type": "string", "name": "Message", "value": "Hi, Alice!"},
+ {"type": "uint32", "name": "A number", "value": "1337"}
+ ],
+ "from": "0x0d0c7188d9c72b019a5da9bca0d127680c22e659"
+ },
+ "status": "unapproved",
+ "time": 1617889069339,
+ "type": "eth_signTypedData"
+ }
+ },
+ "unapprovedTypedMessagesCount": 1,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "currentCurrency": "USD",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": "0xea60",
+ "gasPrice": "0xba43b7400",
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "balance": "0x37452b1315889f80"
+ },
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "amount": "0x1bc16d674ec80000",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ }
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "confTx",
+ "detailView": null,
+ "context": 0
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/states/first-time.json b/development/states/first-time.json
index b2cc8ef8f..4f5352992 100644
--- a/development/states/first-time.json
+++ b/development/states/first-time.json
@@ -8,6 +8,7 @@
"frequentRpcList": [],
"unapprovedTxs": {},
"currentCurrency": "USD",
+ "featureFlags": {"betaUI": false},
"conversionRate": 12.7527416,
"conversionDate": 1487624341,
"noActiveNotices": false,
@@ -34,7 +35,8 @@
"type": "testnet"
},
"shapeShiftTxList": [],
- "lostAccounts": []
+ "lostAccounts": [],
+ "tokens": []
},
"appState": {
"menuOpen": false,
@@ -47,7 +49,12 @@
},
"transForward": true,
"isLoading": false,
- "warning": null
+ "warning": null,
+ "modal": {
+ "modalState": {"name": null},
+ "open": false,
+ "previousModalState": {"name": null}
+ }
},
"identities": {},
"computedBalances": {}
diff --git a/development/states/send-edit.json b/development/states/send-edit.json
new file mode 100644
index 000000000..6ea8e64cd
--- /dev/null
+++ b/development/states/send-edit.json
@@ -0,0 +1,154 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "currentCurrency": "USD",
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedTxs": {
+ "4768706228115573": {
+ "id": 4768706228115573,
+ "time": 1487363153561,
+ "status": "unapproved",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "value": "0x1bc16d674ec80000",
+ "metamaskId": 4768706228115573,
+ "metamaskNetworkId": "3",
+ "gas": "0xea60",
+ "gasPrice": "0xba43b7400"
+ }
+ }
+ },
+ "unapprovedMsgs": {},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "currentCurrency": "USD",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": "0xea60",
+ "gasPrice": "0xba43b7400",
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "balance": "0x37452b1315889f80"
+ },
+ "to": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "amount": "0x1bc16d674ec80000",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ }
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "confTx",
+ "detailView": null,
+ "context": 0
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json
new file mode 100644
index 000000000..a0a2c66e4
--- /dev/null
+++ b/development/states/send-new-ui.json
@@ -0,0 +1,133 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "unapprovedTxs": {},
+ "currentCurrency": "USD",
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "3",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [],
+ "unapprovedMsgs": {},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "currentCurrency": "USD",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [],
+ "lostAccounts": [],
+ "send": {
+ "gasLimit": null,
+ "gasPrice": null,
+ "gasTotal": "0xb451dc41b578",
+ "tokenBalance": null,
+ "from": "",
+ "to": "",
+ "amount": "0x0",
+ "memo": "",
+ "errors": {},
+ "maxModeOn": false,
+ "editingTransactionId": null
+ }
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail",
+ "detailView": null,
+ "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index 58c046c32..9a57617dd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,8 +4,8 @@ metamascara:
ports:
- "9001"
environment:
- MASCARA_ORIGIN: "https://zero.metamask.io"
+ MASCARA_ORIGIN: "https://wallet.metamask.io"
VIRTUAL_PORT: "9001"
- VIRTUAL_HOST: "zero.metamask.io"
- LETSENCRYPT_HOST: "zero.metamask.io"
+ VIRTUAL_HOST: "wallet.metamask.io"
+ LETSENCRYPT_HOST: "wallet.metamask.io"
LETSENCRYPT_EMAIL: "admin@metamask.io" \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index fed1bd67d..3ade82f87 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -21,10 +21,18 @@ var replace = require('gulp-replace')
var mkdirp = require('mkdirp')
var asyncEach = require('async/each')
var exec = require('child_process').exec
+var sass = require('gulp-sass')
+var autoprefixer = require('gulp-autoprefixer')
+var gulpStylelint = require('gulp-stylelint')
+var stylefmt = require('gulp-stylefmt')
+var uglify = require('gulp-uglify-es').default
+var babel = require('gulp-babel')
+
var disableDebugTools = gutil.env.disableDebugTools
var debug = gutil.env.debug
+
// browser reload
gulp.task('dev:reload', function() {
@@ -203,14 +211,55 @@ const jsFiles = [
'popup',
]
+// scss compilation and autoprefixing tasks
+
+gulp.task('build:scss', function () {
+ return gulp.src('ui/app/css/index.scss')
+ .pipe(sourcemaps.init())
+ .pipe(sass().on('error', sass.logError))
+ .pipe(sourcemaps.write())
+ .pipe(autoprefixer())
+ .pipe(gulp.dest('ui/app/css/output'))
+})
+gulp.task('watch:scss', function() {
+ gulp.watch(['ui/app/css/**/*.scss'], gulp.series(['build:scss']))
+})
+
+gulp.task('lint-scss', function() {
+ return gulp
+ .src('ui/app/css/itcss/**/*.scss')
+ .pipe(gulpStylelint({
+ reporters: [
+ {formatter: 'string', console: true}
+ ],
+ fix: true,
+ }));
+});
+
+gulp.task('fmt-scss', function () {
+ return gulp.src('ui/app/css/itcss/**/*.scss')
+ .pipe(stylefmt())
+ .pipe(gulp.dest('ui/app/css/itcss'));
+});
+
// bundle tasks
var jsDevStrings = jsFiles.map(jsFile => `dev:js:${jsFile}`)
var jsBuildStrings = jsFiles.map(jsFile => `build:js:${jsFile}`)
jsFiles.forEach((jsFile) => {
- gulp.task(`dev:js:${jsFile}`, bundleTask({ watch: true, label: jsFile, filename: `${jsFile}.js` }))
- gulp.task(`build:js:${jsFile}`, bundleTask({ watch: false, label: jsFile, filename: `${jsFile}.js` }))
+ gulp.task(`dev:js:${jsFile}`, bundleTask({
+ watch: true,
+ label: jsFile,
+ filename: `${jsFile}.js`,
+ isBuild: false
+ }))
+ gulp.task(`build:js:${jsFile}`, bundleTask({
+ watch: false,
+ label: jsFile,
+ filename: `${jsFile}.js`,
+ isBuild: true
+ }))
})
// inpage must be built before all other scripts:
@@ -244,12 +293,18 @@ gulp.task('zip:edge', zipTask('edge'))
gulp.task('zip:opera', zipTask('opera'))
gulp.task('zip', gulp.parallel('zip:chrome', 'zip:firefox', 'zip:edge', 'zip:opera'))
+// set env var for production
+gulp.task('apply-prod-environment', function(done) {
+ process.env.NODE_ENV = 'production'
+ done()
+});
+
// high level tasks
-gulp.task('dev', gulp.series('dev:js', 'copy', gulp.parallel('copy:watch', 'dev:reload')))
+gulp.task('dev', gulp.series('build:scss', 'dev:js', 'copy', gulp.parallel('watch:scss', 'copy:watch', 'dev:reload')))
-gulp.task('build', gulp.series('clean', gulp.parallel('build:js', 'copy')))
-gulp.task('dist', gulp.series('build', 'zip'))
+gulp.task('build', gulp.series('clean', 'build:scss', gulp.parallel('build:js', 'copy')))
+gulp.task('dist', gulp.series('apply-prod-environment', 'build', 'zip'))
// task generators
@@ -276,7 +331,7 @@ function zipTask(target) {
return () => {
return gulp.src(`dist/${target}/**`)
.pipe(zip(`metamask-${target}-${manifest.version}.zip`))
- .pipe(gulp.dest('builds'));
+ .pipe(gulp.dest('builds'))
}
}
@@ -342,7 +397,6 @@ function bundleTask(opts) {
throw err
}
})
-
// convert bundle stream to gulp vinyl stream
.pipe(source(opts.filename))
// inject variables into bundle
@@ -352,6 +406,8 @@ function bundleTask(opts) {
// sourcemaps
// loads map from browserify file
.pipe(gulpif(debug, sourcemaps.init({ loadMaps: true })))
+ // Minification
+ .pipe(gulpif(opts.isBuild, uglify()))
// writes .map file
.pipe(gulpif(debug, sourcemaps.write('./')))
// write completed bundles
diff --git a/mascara/server/index.js b/mascara/server/index.js
index 83f84f6d1..6fb1287cc 100644
--- a/mascara/server/index.js
+++ b/mascara/server/index.js
@@ -2,6 +2,7 @@ const path = require('path')
const express = require('express')
const createBundle = require('./util').createBundle
const serveBundle = require('./util').serveBundle
+const compression = require('compression')
module.exports = createMetamascaraServer
@@ -16,6 +17,8 @@ function createMetamascaraServer () {
// serve bundles
const server = express()
+ server.use(compression())
+
// ui window
serveBundle(server, '/ui.js', uiBundle)
server.use(express.static(path.join(__dirname, '/../ui/'), { setHeaders: (res) => res.set('X-Frame-Options', 'DENY') }))
diff --git a/mascara/server/util.js b/mascara/server/util.js
index af2daddb9..f9692afb6 100644
--- a/mascara/server/util.js
+++ b/mascara/server/util.js
@@ -23,7 +23,9 @@ function createBundle (entryPoint) {
cache: {},
packageCache: {},
plugin: [watchify],
- }).transform('babelify')
+ })
+ .transform('babelify')
+ .transform('uglifyify', { global: true })
bundler.on('update', bundle)
bundle()
diff --git a/mascara/src/app/buy-ether-widget/index.js b/mascara/src/app/buy-ether-widget/index.js
new file mode 100644
index 000000000..c60221a0a
--- /dev/null
+++ b/mascara/src/app/buy-ether-widget/index.js
@@ -0,0 +1,198 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import classnames from 'classnames'
+import {connect} from 'react-redux'
+import {qrcode} from 'qrcode-npm'
+import copyToClipboard from 'copy-to-clipboard'
+import ShapeShiftForm from '../shapeshift-form'
+import {buyEth, showAccountDetail} from '../../../../ui/app/actions'
+
+const OPTION_VALUES = {
+ COINBASE: 'coinbase',
+ SHAPESHIFT: 'shapeshift',
+ QR_CODE: 'qr_code',
+}
+
+const OPTIONS = [
+ {
+ name: 'Direct Deposit',
+ value: OPTION_VALUES.QR_CODE,
+ },
+ {
+ name: 'Buy with Dollars',
+ value: OPTION_VALUES.COINBASE,
+ },
+ {
+ name: 'Buy with Cryptos',
+ value: OPTION_VALUES.SHAPESHIFT,
+ },
+]
+
+class BuyEtherWidget extends Component {
+
+ static propTypes = {
+ address: PropTypes.string,
+ skipText: PropTypes.string,
+ className: PropTypes.string,
+ onSkip: PropTypes.func,
+ goToCoinbase: PropTypes.func,
+ showAccountDetail: PropTypes.func,
+ };
+
+ state = {
+ selectedOption: OPTION_VALUES.QR_CODE,
+ };
+
+
+ copyToClipboard = () => {
+ const { address } = this.props
+
+ this.setState({ justCopied: true }, () => copyToClipboard(address))
+
+ setTimeout(() => this.setState({ justCopied: false }), 1000)
+ }
+
+ renderSkip () {
+ const {showAccountDetail, address, skipText, onSkip} = this.props
+
+ return (
+ <div
+ className="buy-ether__do-it-later"
+ onClick={() => {
+ if (onSkip) return onSkip()
+ showAccountDetail(address)
+ }}
+ >
+ {skipText || 'Do it later'}
+ </div>
+ )
+ }
+
+ renderCoinbaseLogo () {
+ return (
+ <svg width="140px" height="49px" viewBox="0 0 579 126" version="1.1">
+ <g id="Page-1" stroke="none" strokeWidth={1} fill="none" fillRule="evenodd">
+ <g id="Imported-Layers" fill="#0081C9">
+ <path d="M37.752,125.873 C18.824,125.873 0.369,112.307 0.369,81.549 C0.369,50.79 18.824,37.382 37.752,37.382 C47.059,37.382 54.315,39.749 59.52,43.219 L53.841,55.68 C50.371,53.156 45.166,51.579 39.961,51.579 C28.604,51.579 18.193,60.57 18.193,81.391 C18.193,102.212 28.919,111.361 39.961,111.361 C45.166,111.361 50.371,109.783 53.841,107.26 L59.52,120.036 C54.157,123.664 47.059,125.873 37.752,125.873" id="Fill-1" />
+ <path d="M102.898,125.873 C78.765,125.873 65.515,106.786 65.515,81.549 C65.515,56.311 78.765,37.382 102.898,37.382 C127.032,37.382 140.282,56.311 140.282,81.549 C140.282,106.786 127.032,125.873 102.898,125.873 L102.898,125.873 Z M102.898,51.105 C89.491,51.105 82.866,63.093 82.866,81.391 C82.866,99.688 89.491,111.834 102.898,111.834 C116.306,111.834 122.931,99.688 122.931,81.391 C122.931,63.093 116.306,51.105 102.898,51.105 L102.898,51.105 Z" id="Fill-2" />
+ <path d="M163.468,23.659 C157.79,23.659 153.215,19.243 153.215,13.88 C153.215,8.517 157.79,4.1 163.468,4.1 C169.146,4.1 173.721,8.517 173.721,13.88 C173.721,19.243 169.146,23.659 163.468,23.659 L163.468,23.659 Z M154.793,39.118 L172.144,39.118 L172.144,124.138 L154.793,124.138 L154.793,39.118 Z" id="Fill-3" />
+ <path d="M240.443,124.137 L240.443,67.352 C240.443,57.415 234.449,51.263 222.619,51.263 C216.31,51.263 210.473,52.367 207.003,53.787 L207.003,124.137 L189.81,124.137 L189.81,43.376 C198.328,39.906 209.212,37.382 222.461,37.382 C246.28,37.382 257.794,47.793 257.794,65.775 L257.794,124.137 L240.443,124.137" id="Fill-4" />
+ <path d="M303.536,125.873 C292.494,125.873 281.611,123.191 274.986,119.879 L274.986,0.314 L292.179,0.314 L292.179,41.326 C296.28,39.433 302.905,37.856 308.741,37.856 C330.667,37.856 345.494,53.629 345.494,79.656 C345.494,111.676 328.931,125.873 303.536,125.873 L303.536,125.873 Z M305.744,51.263 C301.012,51.263 295.491,52.367 292.179,54.103 L292.179,109.941 C294.703,111.045 299.593,112.149 304.482,112.149 C318.205,112.149 328.301,102.685 328.301,80.918 C328.301,62.305 319.467,51.263 305.744,51.263 L305.744,51.263 Z" id="Fill-5" />
+ <path d="M392.341,125.873 C367.892,125.873 355.589,115.935 355.589,99.215 C355.589,75.555 380.826,71.296 406.537,69.876 L406.537,64.513 C406.537,53.787 399.439,50.001 388.555,50.001 C380.511,50.001 370.731,52.525 365.053,55.207 L360.636,43.376 C367.419,40.379 378.933,37.382 390.29,37.382 C410.638,37.382 422.942,45.269 422.942,66.248 L422.942,119.879 C416.79,123.191 404.329,125.873 392.341,125.873 L392.341,125.873 Z M406.537,81.391 C389.186,82.337 371.835,83.757 371.835,98.9 C371.835,107.89 378.776,113.411 391.868,113.411 C397.389,113.411 403.856,112.465 406.537,111.203 L406.537,81.391 L406.537,81.391 Z" id="Fill-6" />
+ <path d="M461.743,125.873 C451.806,125.873 441.395,123.191 435.244,119.879 L441.08,106.629 C445.496,109.31 454.803,112.149 461.27,112.149 C470.576,112.149 476.728,107.575 476.728,100.477 C476.728,92.748 470.261,89.751 461.586,86.596 C450.228,82.337 437.452,77.132 437.452,61.201 C437.452,47.162 448.336,37.382 467.264,37.382 C477.517,37.382 486.035,39.906 492.029,43.376 L486.665,55.364 C482.88,52.998 475.309,50.317 469.157,50.317 C460.166,50.317 455.118,55.049 455.118,61.201 C455.118,68.93 461.428,71.611 469.788,74.766 C481.618,79.183 494.71,84.072 494.71,100.635 C494.71,115.935 483.038,125.873 461.743,125.873" id="Fill-7" />
+ <path d="M578.625,81.233 L522.155,89.12 C523.89,104.42 533.828,112.149 548.182,112.149 C556.699,112.149 565.848,110.099 571.684,106.944 L576.732,119.879 C570.107,123.349 558.75,125.873 547.078,125.873 C520.262,125.873 505.277,108.679 505.277,81.549 C505.277,55.522 519.789,37.382 543.607,37.382 C565.69,37.382 578.782,51.894 578.782,74.766 C578.782,76.816 578.782,79.025 578.625,81.233 L578.625,81.233 Z M543.292,50.001 C530.042,50.001 521.367,60.097 521.051,77.763 L562.22,72.084 C562.062,57.257 554.649,50.001 543.292,50.001 L543.292,50.001 Z" id="Fill-8" />
+ </g>
+ </g>
+ </svg>
+ )
+ }
+
+ renderCoinbaseForm () {
+ const {goToCoinbase, address} = this.props
+
+ return (
+ <div className="buy-ether__action-content-wrapper">
+ <div>{this.renderCoinbaseLogo()}</div>
+ <div className="buy-ether__body-text">Coinbase is the world’s most popular way to buy and sell bitcoin, ethereum, and litecoin.</div>
+ <a className="first-time-flow__link buy-ether__faq-link">What is Ethereum?</a>
+ <div className="buy-ether__buttons">
+ <button
+ className="first-time-flow__button"
+ onClick={() => goToCoinbase(address)}
+ >
+ Buy
+ </button>
+ </div>
+ </div>
+ )
+ }
+
+ renderContent () {
+ const { address } = this.props
+ const { justCopied } = this.state
+ const qrImage = qrcode(4, 'M')
+ qrImage.addData(address)
+ qrImage.make()
+
+ switch (this.state.selectedOption) {
+ case OPTION_VALUES.COINBASE:
+ return this.renderCoinbaseForm()
+ case OPTION_VALUES.SHAPESHIFT:
+ return (
+ <div className="buy-ether__action-content-wrapper">
+ <div className="shapeshift-logo" />
+ <div className="buy-ether__body-text">
+ Trade any leading blockchain asset for any other. Protection by Design. No Account Needed.
+ </div>
+ <ShapeShiftForm btnClass="first-time-flow__button" />
+ </div>
+ )
+ case OPTION_VALUES.QR_CODE:
+ return (
+ <div className="buy-ether__action-content-wrapper">
+ <div dangerouslySetInnerHTML={{ __html: qrImage.createTableTag(4) }} />
+ <div className="buy-ether__body-text">Deposit Ether directly into your account.</div>
+ <div className="buy-ether__small-body-text">(This is the account address that MetaMask created for you to recieve funds.)</div>
+ <div className="buy-ether__buttons">
+ <button
+ className="first-time-flow__button"
+ onClick={this.copyToClipboard}
+ disabled={justCopied}
+ >
+ { justCopied ? 'Copied' : 'Copy' }
+ </button>
+ </div>
+ </div>
+ )
+ default:
+ return null
+ }
+ }
+
+ render () {
+ const { className = '' } = this.props
+ const { selectedOption } = this.state
+
+ return (
+ <div className={`${className} buy-ether__content-wrapper`}>
+ <div className="buy-ether__content-headline-wrapper">
+ <div className="buy-ether__content-headline">Deposit Options</div>
+ {this.renderSkip()}
+ </div>
+ <div className="buy-ether__content">
+ <div className="buy-ether__side-panel">
+ {OPTIONS.map(({ name, value }) => (
+ <div
+ key={value}
+ className={classnames('buy-ether__side-panel-item', {
+ 'buy-ether__side-panel-item--selected': value === selectedOption,
+ })}
+ onClick={() => this.setState({ selectedOption: value })}
+ >
+ <div className="buy-ether__side-panel-item-name">{name}</div>
+ {value === selectedOption && (
+ <svg viewBox="0 0 574 1024" id="si-ant-right" width="15px" height="15px">
+ <path d="M10 9Q0 19 0 32t10 23l482 457L10 969Q0 979 0 992t10 23q10 9 24 9t24-9l506-480q10-10 10-23t-10-23L58 9Q48 0 34 0T10 9z" />
+ </svg>
+ )}
+ </div>
+ ))}
+ </div>
+ <div className="buy-ether__action-content">
+ {this.renderContent()}
+ </div>
+ </div>
+ </div>
+ )
+ }
+}
+
+export default connect(
+ ({ metamask: { selectedAddress } }) => ({
+ address: selectedAddress,
+ }),
+ dispatch => ({
+ goToCoinbase: address => dispatch(buyEth({ network: '1', address, amount: 0 })),
+ showAccountDetail: address => dispatch(showAccountDetail(address)),
+ })
+)(BuyEtherWidget)
diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/backup-phrase-screen.js
index c68dacea2..9db61f3ab 100644
--- a/mascara/src/app/first-time/backup-phrase-screen.js
+++ b/mascara/src/app/first-time/backup-phrase-screen.js
@@ -1,5 +1,6 @@
-import React, {Component, PropTypes} from 'react'
-import {connect} from 'react-redux';
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
import classnames from 'classnames'
import shuffle from 'lodash.shuffle'
import {compose, onlyUpdateForPropTypes} from 'recompose'
@@ -194,7 +195,7 @@ class BackupPhraseScreen extends Component {
</button>
</div>
</div>
- )
+ )
}
renderBack () {
diff --git a/mascara/src/app/first-time/breadcrumbs.js b/mascara/src/app/first-time/breadcrumbs.js
index f8460d200..b81a9fb9b 100644
--- a/mascara/src/app/first-time/breadcrumbs.js
+++ b/mascara/src/app/first-time/breadcrumbs.js
@@ -1,10 +1,11 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
export default class Breadcrumbs extends Component {
static propTypes = {
total: PropTypes.number,
- currentIndex: PropTypes.number
+ currentIndex: PropTypes.number,
};
render() {
diff --git a/mascara/src/app/first-time/buy-ether-screen.js b/mascara/src/app/first-time/buy-ether-screen.js
index 45b2df1c8..c5a560638 100644
--- a/mascara/src/app/first-time/buy-ether-screen.js
+++ b/mascara/src/app/first-time/buy-ether-screen.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import classnames from 'classnames'
import {connect} from 'react-redux'
import {qrcode} from 'qrcode-npm'
diff --git a/mascara/src/app/first-time/create-password-screen.js b/mascara/src/app/first-time/create-password-screen.js
index 2f4b81e7c..d1a2ec70f 100644
--- a/mascara/src/app/first-time/create-password-screen.js
+++ b/mascara/src/app/first-time/create-password-screen.js
@@ -1,8 +1,11 @@
-import React, {Component, PropTypes} from 'react'
-import {connect} from 'react-redux';
+import EventEmitter from 'events'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
import {createNewVaultAndKeychain} from '../../../../ui/app/actions'
import LoadingScreen from './loading-screen'
import Breadcrumbs from './breadcrumbs'
+import Mascot from '../../../../ui/app/components/mascot'
class CreatePasswordScreen extends Component {
static propTypes = {
@@ -10,92 +13,115 @@ class CreatePasswordScreen extends Component {
createAccount: PropTypes.func.isRequired,
goToImportWithSeedPhrase: PropTypes.func.isRequired,
goToImportAccount: PropTypes.func.isRequired,
- next: PropTypes.func.isRequired
+ next: PropTypes.func.isRequired,
}
state = {
password: '',
- confirmPassword: ''
+ confirmPassword: '',
}
- isValid() {
- const {password, confirmPassword} = this.state;
+ constructor () {
+ super()
+ this.animationEventEmitter = new EventEmitter()
+ }
+
+ isValid () {
+ const {password, confirmPassword} = this.state
if (!password || !confirmPassword) {
- return false;
+ return false
}
if (password.length < 8) {
- return false;
+ return false
}
- return password === confirmPassword;
+ return password === confirmPassword
}
createAccount = () => {
if (!this.isValid()) {
- return;
+ return
}
- const {password} = this.state;
- const {createAccount, next} = this.props;
+ const {password} = this.state
+ const {createAccount, next} = this.props
createAccount(password)
- .then(next);
+ .then(next)
}
- render() {
- const { isLoading, goToImportAccount, goToImportWithSeedPhrase } = this.props
+ render () {
+ const { isLoading, goToImportWithSeedPhrase } = this.props
return isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
: (
- <div className="create-password">
- <div className="create-password__title">
- Create Password
+ <div>
+ <h2 className="alpha-warning">Warning: This is Experimental software and is a Developer BETA</h2>
+ <div className="first-view-main">
+ <div className="mascara-info">
+ <Mascot
+ animationEventEmitter={this.animationEventEmitter}
+ width="225"
+ height="225"
+ />
+ <div className="info">
+ MetaMask is a secure identity vault for Ethereum.
+ </div>
+ <div className="info">
+ It allows you to hold ether & tokens, and interact with decentralized applications.
+ </div>
+ </div>
+ <div className="create-password">
+ <div className="create-password__title">
+ Create Password
+ </div>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ <input
+ className="first-time-flow__input create-password__confirm-input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ <button
+ className="first-time-flow__button"
+ disabled={!this.isValid()}
+ onClick={this.createAccount}
+ >
+ Create
+ </button>
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ goToImportWithSeedPhrase()
+ }}
+ >
+ Import with seed phrase
+ </a>
+ { /* }
+ <a
+ href=""
+ className="first-time-flow__link create-password__import-link"
+ onClick={e => {
+ e.preventDefault()
+ goToImportAccount()
+ }}
+ >
+ Import an account
+ </a>
+ { */ }
+ <Breadcrumbs total={3} currentIndex={0} />
+ </div>
</div>
- <input
- className="first-time-flow__input"
- type="password"
- placeholder="New Password (min 8 characters)"
- onChange={e => this.setState({password: e.target.value})}
- />
- <input
- className="first-time-flow__input create-password__confirm-input"
- type="password"
- placeholder="Confirm Password"
- onChange={e => this.setState({confirmPassword: e.target.value})}
- />
- <button
- className="first-time-flow__button"
- disabled={!this.isValid()}
- onClick={this.createAccount}
- >
- Create
- </button>
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportWithSeedPhrase()
- }}
- >
- Import with seed phrase
- </a>
- { /* }
- <a
- href=""
- className="first-time-flow__link create-password__import-link"
- onClick={e => {
- e.preventDefault()
- goToImportAccount()
- }}
- >
- Import an account
- </a>
- { */ }
- <Breadcrumbs total={3} currentIndex={0} />
</div>
)
}
diff --git a/mascara/src/app/first-time/import-account-screen.js b/mascara/src/app/first-time/import-account-screen.js
index bf8e209e4..ab0aca0f0 100644
--- a/mascara/src/app/first-time/import-account-screen.js
+++ b/mascara/src/app/first-time/import-account-screen.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import classnames from 'classnames'
import LoadingScreen from './loading-screen'
diff --git a/mascara/src/app/first-time/import-seed-phrase-screen.js b/mascara/src/app/first-time/import-seed-phrase-screen.js
index d9a9dc835..93c3f9203 100644
--- a/mascara/src/app/first-time/import-seed-phrase-screen.js
+++ b/mascara/src/app/first-time/import-seed-phrase-screen.js
@@ -1,7 +1,14 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import LoadingScreen from './loading-screen'
-import {createNewVaultAndRestore, hideWarning, displayWarning} from '../../../../ui/app/actions'
+import {
+ createNewVaultAndRestore,
+ hideWarning,
+ displayWarning,
+ unMarkPasswordForgotten,
+ clearNotices,
+} from '../../../../ui/app/actions'
class ImportSeedPhraseScreen extends Component {
static propTypes = {
@@ -22,7 +29,7 @@ class ImportSeedPhraseScreen extends Component {
onClick = () => {
const { password, seedPhrase, confirmPassword } = this.state
- const { createNewVaultAndRestore, next, displayWarning } = this.props
+ const { createNewVaultAndRestore, next, displayWarning, leaveImportSeedScreenState } = this.props
if (seedPhrase.split(' ').length !== 12) {
this.warning = 'Seed Phrases are 12 words long'
@@ -42,6 +49,7 @@ class ImportSeedPhraseScreen extends Component {
return
}
this.warning = null
+ leaveImportSeedScreenState()
createNewVaultAndRestore(password, seedPhrase)
.then(next)
}
@@ -67,27 +75,37 @@ class ImportSeedPhraseScreen extends Component {
<div className="import-account__selector-label">
Enter your secret twelve word phrase here to restore your vault.
</div>
- <textarea
- className="import-account__secret-phrase"
- onChange={e => this.setState({seedPhrase: e.target.value})}
- />
+ <div className="import-account__input-wrapper">
+ <label className="import-account__input-label">Wallet Seed</label>
+ <textarea
+ className="import-account__secret-phrase"
+ onChange={e => this.setState({seedPhrase: e.target.value})}
+ placeholder="Separate each word with a single space"
+ />
+ </div>
<span
className="error"
>
{this.props.warning}
</span>
- <input
- className="first-time-flow__input"
- type="password"
- placeholder="New Password (min 8 characters)"
- onChange={e => this.setState({password: e.target.value})}
- />
- <input
- className="first-time-flow__input create-password__confirm-input"
- type="password"
- placeholder="Confirm Password"
- onChange={e => this.setState({confirmPassword: e.target.value})}
- />
+ <div className="import-account__input-wrapper">
+ <label className="import-account__input-label">New Password</label>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.setState({password: e.target.value})}
+ />
+ </div>
+ <div className="import-account__input-wrapper">
+ <label className="import-account__input-label">Confirm Password</label>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.setState({confirmPassword: e.target.value})}
+ />
+ </div>
<button
className="first-time-flow__button"
onClick={this.onClick}
@@ -102,6 +120,9 @@ class ImportSeedPhraseScreen extends Component {
export default connect(
({ appState: { isLoading, warning } }) => ({ isLoading, warning }),
dispatch => ({
+ leaveImportSeedScreenState: () => {
+ dispatch(unMarkPasswordForgotten())
+ },
createNewVaultAndRestore: (pw, seed) => dispatch(createNewVaultAndRestore(pw, seed)),
displayWarning: (warning) => dispatch(displayWarning(warning)),
hideWarning: () => dispatch(hideWarning()),
diff --git a/mascara/src/app/first-time/index.css b/mascara/src/app/first-time/index.css
index 28aa3060a..4314efbe6 100644
--- a/mascara/src/app/first-time/index.css
+++ b/mascara/src/app/first-time/index.css
@@ -1,3 +1,4 @@
+
.first-time-flow {
height: 100vh;
width: 100vw;
@@ -5,6 +6,36 @@
overflow: auto;
}
+.alpha-warning {
+ background: #f7861c;
+ color: #fff;
+ line-height: 2em;
+ padding-left: 2em;
+}
+
+.first-view-main {
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: space-between;
+}
+
+.mascara-info {
+ display: flex;
+ flex-flow: column;
+ margin-top: 70px;
+ margin-right: 10vw;
+ width: 35vw;
+ max-width: 550px;
+}
+
+.mascara-info :first-child {
+ align-self: flex-end;
+}
+
+.info {
+ font-size: 19px;
+}
+
.create-password,
.unique-image,
.tou,
@@ -13,10 +44,14 @@
.buy-ether {
display: flex;
flex-flow: column nowrap;
- margin: 67px 0 0 146px;
+ margin: 67px 0 50px 146px;
max-width: 35rem;
}
+.import-account {
+ max-width: initial;
+}
+
@media only screen and (max-width: 575px) {
.create-password,
.unique-image,
@@ -75,7 +110,7 @@
.backup-phrase__tips {
margin: 40px 0 !important;
- width: initial !important;
+ width: initial !important;
}
.backup-phrase__confirm-secret,
@@ -104,14 +139,16 @@
.backup-phrase__title,
.import-account__title,
.buy-ether__title {
- width: 280px;
color: #1B344D;
font-size: 40px;
- font-weight: 500;
line-height: 51px;
margin-bottom: 24px;
}
+.import-account__title {
+ margin-bottom: 10px;
+}
+
.tou__title,
.backup-phrase__title {
width: 480px;
@@ -257,9 +294,7 @@
.import-account__back-button:hover {
margin-bottom: 18px;
color: #22232C;
- font-family: Montserrat Regular;
font-size: 16px;
- font-weight: 500;
line-height: 21px;
}
@@ -280,6 +315,12 @@ button.backup-phrase__reveal-button:hover {
.import-account__secret-phrase {
font-size: 16px;
+ margin: initial;
+}
+
+.import-account__secret-phrase::placeholder {
+ color: #9B9B9B;
+ font-weight: 200;
}
.backup-phrase__confirm-seed-options {
@@ -319,9 +360,7 @@ button.backup-phrase__confirm-seed-option:hover {
.import-account__selector-label {
color: #1B344D;
- font-family: Montserrat Light;
- font-size: 18px;
- line-height: 23px;
+ font-size: 16px;
}
.import-account__dropdown {
@@ -337,7 +376,7 @@ button.backup-phrase__confirm-seed-option:hover {
padding: 14px 21px;
appearance: none;
-webkit-appearance: none;
- -moz-appearance: none;
+ -moz-appearance: none;
cursor: pointer;
}
@@ -363,7 +402,6 @@ button.backup-phrase__confirm-seed-option:hover {
margin-top: 10px;
width: 422px;
color: #FF001F;
- font-family: Montserrat Light;
font-size: 16px;
line-height: 21px;
}
@@ -371,10 +409,8 @@ button.backup-phrase__confirm-seed-option:hover {
.import-account__input-label {
margin-bottom: 9px;
color: #1B344D;
- font-family: Montserrat Light;
font-size: 18px;
line-height: 23px;
- text-transform: uppercase;
}
.import-account__input {
@@ -518,7 +554,7 @@ button.backup-phrase__confirm-seed-option:hover {
width: 350px;
font-size: 18px;
line-height: 24px;
- padding: 15px 28px;
+ padding: 15px;
border: 1px solid #CDCDCD;
background-color: #FFFFFF;
}
@@ -540,10 +576,10 @@ button.backup-phrase__confirm-seed-option:hover {
text-transform: uppercase;
margin: 35px 0 14px;
transition: 200ms ease-in-out;
+ background-color: rgba(247, 134, 28, 0.9);
}
button.first-time-flow__button[disabled] {
- background-color: rgba(247, 134, 28, 0.9);
opacity: .6;
}
diff --git a/mascara/src/app/first-time/index.js b/mascara/src/app/first-time/index.js
index 66b591bd8..da2f6bab9 100644
--- a/mascara/src/app/first-time/index.js
+++ b/mascara/src/app/first-time/index.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import CreatePasswordScreen from './create-password-screen'
import UniqueImageScreen from './unique-image-screen'
@@ -6,7 +7,10 @@ import NoticeScreen from './notice-screen'
import BackupPhraseScreen from './backup-phrase-screen'
import ImportAccountScreen from './import-account-screen'
import ImportSeedPhraseScreen from './import-seed-phrase-screen'
-import {onboardingBuyEthView} from '../../../../ui/app/actions'
+import {
+ onboardingBuyEthView,
+ unMarkPasswordForgotten,
+} from '../../../../ui/app/actions'
class FirstTimeFlow extends Component {
@@ -32,6 +36,7 @@ class FirstTimeFlow extends Component {
NOTICE: 'notice',
BACK_UP_PHRASE: 'back_up_phrase',
CONFIRM_BACK_UP_PHRASE: 'confirm_back_up_phrase',
+ LOADING: 'loading',
};
constructor (props) {
@@ -50,11 +55,15 @@ class FirstTimeFlow extends Component {
isInitialized,
seedWords,
noActiveNotices,
+ forgottenPassword,
} = this.props
const {SCREEN_TYPE} = FirstTimeFlow
// return SCREEN_TYPE.NOTICE
+ if (forgottenPassword) {
+ return SCREEN_TYPE.IMPORT_SEED_PHRASE
+ }
if (!isInitialized) {
return SCREEN_TYPE.CREATE_PASSWORD
}
@@ -70,7 +79,13 @@ class FirstTimeFlow extends Component {
renderScreen () {
const {SCREEN_TYPE} = FirstTimeFlow
- const {goToBuyEtherView, address} = this.props
+ const {
+ goToBuyEtherView,
+ address,
+ restoreCreatePasswordScreen,
+ forgottenPassword,
+ leaveImportSeedScreenState,
+ } = this.props
switch (this.state.screenType) {
case SCREEN_TYPE.CREATE_PASSWORD:
@@ -91,8 +106,14 @@ class FirstTimeFlow extends Component {
case SCREEN_TYPE.IMPORT_SEED_PHRASE:
return (
<ImportSeedPhraseScreen
- back={() => this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)}
- next={() => this.setScreenType(SCREEN_TYPE.NOTICE)}
+ back={() => {
+ leaveImportSeedScreenState()
+ this.setScreenType(SCREEN_TYPE.CREATE_PASSWORD)
+ }}
+ next={() => {
+ const newScreenType = forgottenPassword ? null : SCREEN_TYPE.NOTICE
+ this.setScreenType(newScreenType)
+ }}
/>
)
case SCREEN_TYPE.UNIQUE_IMAGE:
@@ -129,13 +150,23 @@ class FirstTimeFlow extends Component {
}
export default connect(
- ({ metamask: { isInitialized, seedWords, noActiveNotices, selectedAddress } }) => ({
+ ({
+ metamask: {
+ isInitialized,
+ seedWords,
+ noActiveNotices,
+ selectedAddress,
+ forgottenPassword,
+ }
+ }) => ({
isInitialized,
seedWords,
noActiveNotices,
address: selectedAddress,
+ forgottenPassword,
}),
dispatch => ({
+ leaveImportSeedScreenState: () => dispatch(unMarkPasswordForgotten()),
goToBuyEtherView: address => dispatch(onboardingBuyEthView(address)),
})
)(FirstTimeFlow)
diff --git a/mascara/src/app/first-time/loading-screen.js b/mascara/src/app/first-time/loading-screen.js
index 732b7f2d7..01e1c1998 100644
--- a/mascara/src/app/first-time/loading-screen.js
+++ b/mascara/src/app/first-time/loading-screen.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React from 'react'
+import PropTypes from 'prop-types'
import Spinner from './spinner'
export default function LoadingScreen({ className = '', loadingMessage }) {
@@ -7,5 +8,10 @@ export default function LoadingScreen({ className = '', loadingMessage }) {
<Spinner color="#1B344D" />
<div className="loading-screen__message">{loadingMessage}</div>
</div>
- );
+ )
+}
+
+LoadingScreen.propTypes = {
+ className: PropTypes.string,
+ loadingMessage: PropTypes.string,
}
diff --git a/mascara/src/app/first-time/notice-screen.js b/mascara/src/app/first-time/notice-screen.js
index d09070a95..0f0a7e95d 100644
--- a/mascara/src/app/first-time/notice-screen.js
+++ b/mascara/src/app/first-time/notice-screen.js
@@ -1,10 +1,12 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import Markdown from 'react-markdown'
import {connect} from 'react-redux'
import debounce from 'lodash.debounce'
import {markNoticeRead} from '../../../../ui/app/actions'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
+import LoadingScreen from './loading-screen'
class NoticeScreen extends Component {
static propTypes = {
@@ -12,25 +14,26 @@ class NoticeScreen extends Component {
lastUnreadNotice: PropTypes.shape({
title: PropTypes.string,
date: PropTypes.string,
- body: PropTypes.string
+ body: PropTypes.string,
}),
- next: PropTypes.func.isRequired
+ next: PropTypes.func.isRequired,
+ markNoticeRead: PropTypes.func,
};
static defaultProps = {
- lastUnreadNotice: {}
+ lastUnreadNotice: {},
};
state = {
atBottom: false,
}
- componentDidMount() {
+ componentDidMount () {
this.onScroll()
}
acceptTerms = () => {
- const { markNoticeRead, lastUnreadNotice, next } = this.props;
+ const { markNoticeRead, lastUnreadNotice, next } = this.props
const defer = markNoticeRead(lastUnreadNotice)
.then(() => this.setState({ atBottom: false }))
@@ -43,50 +46,53 @@ class NoticeScreen extends Component {
if (this.state.atBottom) return
const target = document.querySelector('.tou__body')
- const {scrollTop, offsetHeight, scrollHeight} = target;
- const atBottom = scrollTop + offsetHeight >= scrollHeight;
+ const {scrollTop, offsetHeight, scrollHeight} = target
+ const atBottom = scrollTop + offsetHeight >= scrollHeight
this.setState({atBottom: atBottom})
}, 25)
- render() {
+ render () {
const {
address,
- lastUnreadNotice: { title, body }
- } = this.props;
+ lastUnreadNotice: { title, body },
+ isLoading,
+ } = this.props
const { atBottom } = this.state
return (
- <div
- className="tou"
- onScroll={this.onScroll}
- >
- <Identicon address={address} diameter={70} />
- <div className="tou__title">{title}</div>
- <Markdown
- className="tou__body markdown"
- source={body}
- skipHtml
- />
- <button
- className="first-time-flow__button"
- onClick={atBottom && this.acceptTerms}
- disabled={!atBottom}
+ isLoading
+ ? <LoadingScreen />
+ : <div
+ className="tou"
+ onScroll={this.onScroll}
>
- Accept
- </button>
- <Breadcrumbs total={3} currentIndex={2} />
- </div>
+ <Identicon address={address} diameter={70} />
+ <div className="tou__title">{title}</div>
+ <Markdown
+ className="tou__body markdown"
+ source={body}
+ skipHtml
+ />
+ <button
+ className="first-time-flow__button"
+ onClick={atBottom && this.acceptTerms}
+ disabled={!atBottom}
+ >
+ Accept
+ </button>
+ <Breadcrumbs total={3} currentIndex={2} />
+ </div>
)
}
}
export default connect(
- ({ metamask: { selectedAddress, lastUnreadNotice } }) => ({
+ ({ metamask: { selectedAddress, lastUnreadNotice }, appState: { isLoading } }) => ({
lastUnreadNotice,
- address: selectedAddress
+ address: selectedAddress,
}),
dispatch => ({
- markNoticeRead: notice => dispatch(markNoticeRead(notice))
+ markNoticeRead: notice => dispatch(markNoticeRead(notice)),
})
)(NoticeScreen)
diff --git a/mascara/src/app/first-time/unique-image-screen.js b/mascara/src/app/first-time/unique-image-screen.js
index ef6bd28ab..46448aacf 100644
--- a/mascara/src/app/first-time/unique-image-screen.js
+++ b/mascara/src/app/first-time/unique-image-screen.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import Identicon from '../../../../ui/app/components/identicon'
import Breadcrumbs from './breadcrumbs'
diff --git a/mascara/src/app/shapeshift-form/index.js b/mascara/src/app/shapeshift-form/index.js
index 15c7e95e1..53a63403a 100644
--- a/mascara/src/app/shapeshift-form/index.js
+++ b/mascara/src/app/shapeshift-form/index.js
@@ -1,4 +1,5 @@
-import React, {Component, PropTypes} from 'react'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
import classnames from 'classnames'
import {qrcode} from 'qrcode-npm'
import {connect} from 'react-redux'
diff --git a/mock-dev.js b/mock-dev.js
index 0a3eb12ce..8b04352cf 100644
--- a/mock-dev.js
+++ b/mock-dev.js
@@ -20,9 +20,11 @@ const Root = require('./ui/app/root')
const configureStore = require('./ui/app/store')
const actions = require('./ui/app/actions')
const states = require('./development/states')
+const backGroundConnectionModifiers = require('./development/backGroundConnectionModifiers')
const Selector = require('./development/selector')
const MetamaskController = require('./app/scripts/metamask-controller')
const firstTimeState = require('./app/scripts/first-time-state')
+const ExtensionPlatform = require('./app/scripts/platforms/extension')
const extension = require('./development/mockExtension')
const noop = function () {}
@@ -67,6 +69,7 @@ const controller = new MetamaskController({
initState: firstTimeState,
})
global.metamaskController = controller
+global.platform = new ExtensionPlatform
//
// User Interface
@@ -83,6 +86,11 @@ actions.update = function(stateName) {
}
}
+function modifyBackgroundConnection(backgroundConnectionModifier) {
+ const modifiedBackgroundConnection = Object.assign({}, controller.getApi(), backgroundConnectionModifier)
+ actions._setBackgroundConnection(modifiedBackgroundConnection)
+}
+
var css = MetaMaskUiCss()
injectCss(css)
@@ -111,7 +119,14 @@ function startApp(){
},
}, 'Reset State'),
- h(Selector, { actions, selectedKey: selectedView, states, store }),
+ h(Selector, {
+ actions,
+ selectedKey: selectedView,
+ states,
+ store,
+ modifyBackgroundConnection,
+ backGroundConnectionModifiers,
+ }),
h('#app-content', {
style: {
diff --git a/old-ui/.gitignore b/old-ui/.gitignore
new file mode 100644
index 000000000..c6b1254b5
--- /dev/null
+++ b/old-ui/.gitignore
@@ -0,0 +1,66 @@
+
+# Created by https://www.gitignore.io/api/osx,node
+
+### OSX ###
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directory
+# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
+node_modules
+
+# Optional npm cache directory
+.npm
+
+# Optional REPL history
+.node_repl_history
+
diff --git a/old-ui/app/account-detail.js b/old-ui/app/account-detail.js
new file mode 100644
index 000000000..692d50491
--- /dev/null
+++ b/old-ui/app/account-detail.js
@@ -0,0 +1,292 @@
+const inherits = require('util').inherits
+const extend = require('xtend')
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+const valuesFor = require('./util').valuesFor
+const Identicon = require('./components/identicon')
+const EthBalance = require('./components/eth-balance')
+const TransactionList = require('./components/transaction-list')
+const ExportAccountView = require('./components/account-export')
+const ethUtil = require('ethereumjs-util')
+const EditableLabel = require('./components/editable-label')
+const TabBar = require('./components/tab-bar')
+const TokenList = require('./components/token-list')
+const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
+
+module.exports = connect(mapStateToProps)(AccountDetailScreen)
+
+function mapStateToProps (state) {
+ return {
+ metamask: state.metamask,
+ identities: state.metamask.identities,
+ accounts: state.metamask.accounts,
+ address: state.metamask.selectedAddress,
+ accountDetail: state.appState.accountDetail,
+ network: state.metamask.network,
+ unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
+ shapeShiftTxList: state.metamask.shapeShiftTxList,
+ transactions: state.metamask.selectedAddressTxList || [],
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ currentAccountTab: state.metamask.currentAccountTab,
+ tokens: state.metamask.tokens,
+ computedBalances: state.metamask.computedBalances,
+ }
+}
+
+inherits(AccountDetailScreen, Component)
+function AccountDetailScreen () {
+ Component.call(this)
+}
+
+AccountDetailScreen.prototype.render = function () {
+ var props = this.props
+ var selected = props.address || Object.keys(props.accounts)[0]
+ var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
+ var identity = props.identities[selected]
+ var account = props.accounts[selected]
+ const { network, conversionRate, currentCurrency } = props
+
+ return (
+
+ h('.account-detail-section.full-flex-height', [
+
+ // identicon, label, balance, etc
+ h('.account-data-subsection', {
+ style: {
+ margin: '0 20px',
+ flex: '1 0 auto',
+ },
+ }, [
+
+ // header - identicon + nav
+ h('div', {
+ style: {
+ paddingTop: '20px',
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'flex-start',
+ },
+ }, [
+
+ // large identicon and addresses
+ h('.identicon-wrapper.select-none', [
+ h(Identicon, {
+ diameter: 62,
+ address: selected,
+ }),
+ ]),
+ h('flex-column', {
+ style: {
+ lineHeight: '10px',
+ marginLeft: '15px',
+ width: '100%',
+ },
+ }, [
+ h(EditableLabel, {
+ textValue: identity ? identity.name : '',
+ state: {
+ isEditingLabel: false,
+ },
+ saveText: (text) => {
+ props.dispatch(actions.saveAccountLabel(selected, text))
+ },
+ }, [
+
+ // What is shown when not editing + edit text:
+ h('label.editing-label', [h('.edit-text', 'edit')]),
+ h(
+ 'div',
+ {
+ style: {
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ },
+ },
+ [
+ h(
+ 'div.font-medium.color-forest',
+ {
+ name: 'edit',
+ style: {
+ },
+ },
+ [
+ h('h2', {
+ style: {
+ maxWidth: '180px',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ padding: '5px 0px',
+ lineHeight: '25px',
+ },
+ }, [
+ identity && identity.name,
+ ]),
+ ]
+ ),
+ h(
+ AccountDropdowns,
+ {
+ style: {
+ marginRight: '8px',
+ marginLeft: 'auto',
+ cursor: 'pointer',
+ },
+ selected,
+ network,
+ identities: props.identities,
+ enableAccountOptions: true,
+ },
+ ),
+ ]
+ ),
+ ]),
+ h('.flex-row', {
+ style: {
+ width: '15em',
+ justifyContent: 'space-between',
+ alignItems: 'baseline',
+ },
+ }, [
+
+ // address
+
+ h('div', {
+ style: {
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ paddingTop: '3px',
+ width: '5em',
+ height: '15px',
+ fontSize: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ marginBottom: '15px',
+ color: '#AEAEAE',
+ },
+ }, checksumAddress),
+ ]),
+
+ // account ballence
+
+ ]),
+ ]),
+ h('.flex-row', {
+ style: {
+ justifyContent: 'space-between',
+ alignItems: 'flex-start',
+ },
+ }, [
+
+ h(EthBalance, {
+ value: account && account.balance,
+ conversionRate,
+ currentCurrency,
+ style: {
+ lineHeight: '7px',
+ marginTop: '10px',
+ },
+ }),
+
+ h('.flex-grow'),
+
+ h('button', {
+ onClick: () => props.dispatch(actions.buyEthView(selected)),
+ style: { marginRight: '10px' },
+ }, 'BUY'),
+
+ h('button', {
+ onClick: () => props.dispatch(actions.showSendPage()),
+ style: {
+ marginBottom: '20px',
+ marginRight: '8px',
+ },
+ }, 'SEND'),
+
+ ]),
+ ]),
+
+ // subview (tx history, pk export confirm, buy eth warning)
+ this.subview(),
+
+ ])
+ )
+}
+
+AccountDetailScreen.prototype.subview = function () {
+ var subview
+ try {
+ subview = this.props.accountDetail.subview
+ } catch (e) {
+ subview = null
+ }
+
+ switch (subview) {
+ case 'transactions':
+ return this.tabSections()
+ case 'export':
+ var state = extend({key: 'export'}, this.props)
+ return h(ExportAccountView, state)
+ default:
+ return this.tabSections()
+ }
+}
+
+AccountDetailScreen.prototype.tabSections = function () {
+ const { currentAccountTab } = this.props
+
+ return h('section.tabSection.full-flex-height.grow-tenx', [
+
+ h(TabBar, {
+ tabs: [
+ { content: 'Sent', key: 'history' },
+ { content: 'Tokens', key: 'tokens' },
+ ],
+ defaultTab: currentAccountTab || 'history',
+ tabSelected: (key) => {
+ this.props.dispatch(actions.setCurrentAccountTab(key))
+ },
+ }),
+
+ this.tabSwitchView(),
+ ])
+}
+
+AccountDetailScreen.prototype.tabSwitchView = function () {
+ const props = this.props
+ const { address, network } = props
+ const { currentAccountTab, tokens } = this.props
+
+ switch (currentAccountTab) {
+ case 'tokens':
+ return h(TokenList, {
+ userAddress: address,
+ network,
+ tokens,
+ addToken: () => this.props.dispatch(actions.showAddTokenPage()),
+ })
+ default:
+ return this.transactionList()
+ }
+}
+
+AccountDetailScreen.prototype.transactionList = function () {
+ const {transactions, unapprovedMsgs, address,
+ network, shapeShiftTxList, conversionRate } = this.props
+
+ return h(TransactionList, {
+ transactions: transactions.sort((a, b) => b.time - a.time),
+ network,
+ unapprovedMsgs,
+ conversionRate,
+ address,
+ shapeShiftTxList,
+ viewPendingTx: (txId) => {
+ this.props.dispatch(actions.viewPendingTx(txId))
+ },
+ })
+}
diff --git a/old-ui/app/accounts/import/index.js b/old-ui/app/accounts/import/index.js
new file mode 100644
index 000000000..3502efe93
--- /dev/null
+++ b/old-ui/app/accounts/import/index.js
@@ -0,0 +1,101 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../../ui/app/actions')
+import Select from 'react-select'
+
+// Subviews
+const JsonImportView = require('./json.js')
+const PrivateKeyImportView = require('./private-key.js')
+
+const menuItems = [
+ 'Private Key',
+ 'JSON File',
+]
+
+module.exports = connect(mapStateToProps)(AccountImportSubview)
+
+function mapStateToProps (state) {
+ return {
+ menuItems,
+ }
+}
+
+inherits(AccountImportSubview, Component)
+function AccountImportSubview () {
+ Component.call(this)
+}
+
+AccountImportSubview.prototype.render = function () {
+ const props = this.props
+ const state = this.state || {}
+ const { menuItems } = props
+ const { type } = state
+
+ return (
+ h('div', {
+ style: {
+ },
+ }, [
+ h('.section-title.flex-row.flex-center', [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: (event) => {
+ props.dispatch(actions.goHome())
+ },
+ }),
+ h('h2.page-subtitle', 'Import Accounts'),
+ ]),
+ h('div', {
+ style: {
+ padding: '10px',
+ color: 'rgb(174, 174, 174)',
+ },
+ }, [
+
+ h('h3', { style: { padding: '3px' } }, 'SELECT TYPE'),
+
+ h('style', `
+ .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label {
+ color: rgb(174,174,174);
+ }
+ `),
+
+ h(Select, {
+ name: 'import-type-select',
+ clearable: false,
+ value: type || menuItems[0],
+ options: menuItems.map((type) => {
+ return {
+ value: type,
+ label: type,
+ }
+ }),
+ onChange: (opt) => {
+ props.dispatch(actions.showImportPage())
+ this.setState({ type: opt.value })
+ },
+ }),
+ ]),
+
+ this.renderImportView(),
+ ])
+ )
+}
+
+AccountImportSubview.prototype.renderImportView = function () {
+ const props = this.props
+ const state = this.state || {}
+ const { type } = state
+ const { menuItems } = props
+ const current = type || menuItems[0]
+
+ switch (current) {
+ case 'Private Key':
+ return h(PrivateKeyImportView)
+ case 'JSON File':
+ return h(JsonImportView)
+ default:
+ return h(JsonImportView)
+ }
+}
diff --git a/old-ui/app/accounts/import/json.js b/old-ui/app/accounts/import/json.js
new file mode 100644
index 000000000..8d6bd7f7b
--- /dev/null
+++ b/old-ui/app/accounts/import/json.js
@@ -0,0 +1,100 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../../ui/app/actions')
+const FileInput = require('react-simple-file-input').default
+
+const HELP_LINK = 'https://github.com/MetaMask/faq/blob/master/README.md#q-i-cant-use-the-import-feature-for-uploading-a-json-file-the-window-keeps-closing-when-i-try-to-select-a-file'
+
+module.exports = connect(mapStateToProps)(JsonImportSubview)
+
+function mapStateToProps (state) {
+ return {
+ error: state.appState.warning,
+ }
+}
+
+inherits(JsonImportSubview, Component)
+function JsonImportSubview () {
+ Component.call(this)
+}
+
+JsonImportSubview.prototype.render = function () {
+ const { error } = this.props
+
+ return (
+ h('div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ padding: '5px 15px 0px 15px',
+ },
+ }, [
+
+ h('p', 'Used by a variety of different clients'),
+ h('a.warning', { href: HELP_LINK, target: '_blank' }, 'File import not working? Click here!'),
+
+ h(FileInput, {
+ readAs: 'text',
+ onLoad: this.onLoad.bind(this),
+ style: {
+ margin: '20px 0px 12px 20px',
+ fontSize: '15px',
+ },
+ }),
+
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ placeholder: 'Enter password',
+ id: 'json-password-box',
+ onKeyPress: this.createKeyringOnEnter.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ h('button.primary', {
+ onClick: this.createNewKeychain.bind(this),
+ style: {
+ margin: 12,
+ },
+ }, 'Import'),
+
+ error ? h('span.error', error) : null,
+ ])
+ )
+}
+
+JsonImportSubview.prototype.onLoad = function (event, file) {
+ this.setState({file: file, fileContents: event.target.result})
+}
+
+JsonImportSubview.prototype.createKeyringOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+}
+
+JsonImportSubview.prototype.createNewKeychain = function () {
+ const state = this.state
+ const { fileContents } = state
+
+ if (!fileContents) {
+ const message = 'You must select a file to import.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ const passwordInput = document.getElementById('json-password-box')
+ const password = passwordInput.value
+
+ if (!password) {
+ const message = 'You must enter a password for the selected file.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ this.props.dispatch(actions.importNewAccount('JSON File', [ fileContents, password ]))
+}
diff --git a/old-ui/app/accounts/import/private-key.js b/old-ui/app/accounts/import/private-key.js
new file mode 100644
index 000000000..105191105
--- /dev/null
+++ b/old-ui/app/accounts/import/private-key.js
@@ -0,0 +1,67 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(PrivateKeyImportView)
+
+function mapStateToProps (state) {
+ return {
+ error: state.appState.warning,
+ }
+}
+
+inherits(PrivateKeyImportView, Component)
+function PrivateKeyImportView () {
+ Component.call(this)
+}
+
+PrivateKeyImportView.prototype.render = function () {
+ const { error } = this.props
+
+ return (
+ h('div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ padding: '5px 15px 0px 15px',
+ },
+ }, [
+ h('span', 'Paste your private key string here'),
+
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'private-key-box',
+ onKeyPress: this.createKeyringOnEnter.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ h('button.primary', {
+ onClick: this.createNewKeychain.bind(this),
+ style: {
+ margin: 12,
+ },
+ }, 'Import'),
+
+ error ? h('span.error', error) : null,
+ ])
+ )
+}
+
+PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewKeychain()
+ }
+}
+
+PrivateKeyImportView.prototype.createNewKeychain = function () {
+ const input = document.getElementById('private-key-box')
+ const privateKey = input.value
+ this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ]))
+}
diff --git a/old-ui/app/accounts/import/seed.js b/old-ui/app/accounts/import/seed.js
new file mode 100644
index 000000000..b4a7c0afa
--- /dev/null
+++ b/old-ui/app/accounts/import/seed.js
@@ -0,0 +1,30 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+
+module.exports = connect(mapStateToProps)(SeedImportSubview)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(SeedImportSubview, Component)
+function SeedImportSubview () {
+ Component.call(this)
+}
+
+SeedImportSubview.prototype.render = function () {
+ return (
+ h('div', {
+ style: {
+ },
+ }, [
+ `Paste your seed phrase here!`,
+ h('textarea'),
+ h('br'),
+ h('button', 'Submit'),
+ ])
+ )
+}
+
diff --git a/old-ui/app/add-token.js b/old-ui/app/add-token.js
new file mode 100644
index 000000000..8a3e66978
--- /dev/null
+++ b/old-ui/app/add-token.js
@@ -0,0 +1,238 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+const Tooltip = require('./components/tooltip.js')
+
+
+const ethUtil = require('ethereumjs-util')
+const abi = require('human-standard-token-abi')
+const Eth = require('ethjs-query')
+const EthContract = require('ethjs-contract')
+
+const emptyAddr = '0x0000000000000000000000000000000000000000'
+
+module.exports = connect(mapStateToProps)(AddTokenScreen)
+
+function mapStateToProps (state) {
+ return {
+ identities: state.metamask.identities,
+ }
+}
+
+inherits(AddTokenScreen, Component)
+function AddTokenScreen () {
+ this.state = {
+ warning: null,
+ address: '',
+ symbol: 'TOKEN',
+ decimals: 18,
+ }
+ Component.call(this)
+}
+
+AddTokenScreen.prototype.render = function () {
+ const state = this.state
+ const props = this.props
+ const { warning, symbol, decimals } = state
+
+ return (
+ h('.flex-column.flex-grow', [
+
+ // subtitle and nav
+ h('.section-title.flex-row.flex-center', [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: (event) => {
+ props.dispatch(actions.goHome())
+ },
+ }),
+ h('h2.page-subtitle', 'Add Token'),
+ ]),
+
+ h('.error', {
+ style: {
+ display: warning ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, warning),
+
+ // conf view
+ h('.flex-column.flex-justify-center.flex-grow.select-none', [
+ h('.flex-space-around', {
+ style: {
+ padding: '20px',
+ },
+ }, [
+
+ h('div', [
+ h(Tooltip, {
+ position: 'top',
+ title: 'The contract of the actual token contract. Click for more info.',
+ }, [
+ h('a', {
+ style: { fontWeight: 'bold', paddingRight: '10px'},
+ href: 'https://support.metamask.io/kb/article/24-what-is-a-token-contract-address',
+ target: '_blank',
+ }, [
+ h('span', 'Token Contract Address '),
+ h('i.fa.fa-question-circle'),
+ ]),
+ ]),
+ ]),
+
+ h('section.flex-row.flex-center', [
+ h('input#token-address', {
+ name: 'address',
+ placeholder: 'Token Contract Address',
+ onChange: this.tokenAddressDidChange.bind(this),
+ style: {
+ width: 'inherit',
+ flex: '1 0 auto',
+ height: '30px',
+ margin: '8px',
+ },
+ }),
+ ]),
+
+ h('div', [
+ h('span', {
+ style: { fontWeight: 'bold', paddingRight: '10px'},
+ }, 'Token Symbol'),
+ ]),
+
+ h('div', { style: {display: 'flex'} }, [
+ h('input#token_symbol', {
+ placeholder: `Like "ETH"`,
+ value: symbol,
+ style: {
+ width: 'inherit',
+ flex: '1 0 auto',
+ height: '30px',
+ margin: '8px',
+ },
+ onChange: (event) => {
+ var element = event.target
+ var symbol = element.value
+ this.setState({ symbol })
+ },
+ }),
+ ]),
+
+ h('div', [
+ h('span', {
+ style: { fontWeight: 'bold', paddingRight: '10px'},
+ }, 'Decimals of Precision'),
+ ]),
+
+ h('div', { style: {display: 'flex'} }, [
+ h('input#token_decimals', {
+ value: decimals,
+ type: 'number',
+ min: 0,
+ max: 36,
+ style: {
+ width: 'inherit',
+ flex: '1 0 auto',
+ height: '30px',
+ margin: '8px',
+ },
+ onChange: (event) => {
+ var element = event.target
+ var decimals = element.value.trim()
+ this.setState({ decimals })
+ },
+ }),
+ ]),
+
+ h('button', {
+ style: {
+ alignSelf: 'center',
+ },
+ onClick: (event) => {
+ const valid = this.validateInputs()
+ if (!valid) return
+
+ const { address, symbol, decimals } = this.state
+ this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
+ },
+ }, 'Add'),
+ ]),
+ ]),
+ ])
+ )
+}
+
+AddTokenScreen.prototype.componentWillMount = function () {
+ if (typeof global.ethereumProvider === 'undefined') return
+
+ this.eth = new Eth(global.ethereumProvider)
+ this.contract = new EthContract(this.eth)
+ this.TokenContract = this.contract(abi)
+}
+
+AddTokenScreen.prototype.tokenAddressDidChange = function (event) {
+ const el = event.target
+ const address = el.value.trim()
+ if (ethUtil.isValidAddress(address) && address !== emptyAddr) {
+ this.setState({ address })
+ this.attemptToAutoFillTokenParams(address)
+ }
+}
+
+AddTokenScreen.prototype.validateInputs = function () {
+ let msg = ''
+ const state = this.state
+ const identitiesList = Object.keys(this.props.identities)
+ const { address, symbol, decimals } = state
+ const standardAddress = ethUtil.addHexPrefix(address).toLowerCase()
+
+ const validAddress = ethUtil.isValidAddress(address)
+ if (!validAddress) {
+ msg += 'Address is invalid.'
+ }
+
+ const validDecimals = decimals >= 0 && decimals < 36
+ if (!validDecimals) {
+ msg += 'Decimals must be at least 0, and not over 36. '
+ }
+
+ const symbolLen = symbol.trim().length
+ const validSymbol = symbolLen > 0 && symbolLen < 10
+ if (!validSymbol) {
+ msg += 'Symbol must be between 0 and 10 characters.'
+ }
+
+ const ownAddress = identitiesList.includes(standardAddress)
+ if (ownAddress) {
+ msg = 'Personal address detected. Input the token contract address.'
+ }
+
+ const isValid = validAddress && validDecimals && !ownAddress
+
+ if (!isValid) {
+ this.setState({
+ warning: msg,
+ })
+ } else {
+ this.setState({ warning: null })
+ }
+
+ return isValid
+}
+
+AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) {
+ const contract = this.TokenContract.at(address)
+
+ const results = await Promise.all([
+ contract.symbol(),
+ contract.decimals(),
+ ])
+
+ const [ symbol, decimals ] = results
+ if (symbol && decimals) {
+ console.log('SETTING SYMBOL AND DECIMALS', { symbol, decimals })
+ this.setState({ symbol: symbol[0], decimals: decimals[0].toString() })
+ }
+}
diff --git a/old-ui/app/app.js b/old-ui/app/app.js
new file mode 100644
index 000000000..c79ac633a
--- /dev/null
+++ b/old-ui/app/app.js
@@ -0,0 +1,707 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const actions = require('../../ui/app/actions')
+// mascara
+const MascaraFirstTime = require('../../mascara/src/app/first-time').default
+const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
+// init
+const InitializeMenuScreen = require('./first-time/init-menu')
+const NewKeyChainScreen = require('./new-keychain')
+// unlock
+const UnlockScreen = require('./unlock')
+// accounts
+const AccountDetailScreen = require('./account-detail')
+const SendTransactionScreen = require('./send')
+const ConfirmTxScreen = require('./conf-tx')
+// notice
+const NoticeScreen = require('./components/notice')
+const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
+// other views
+const ConfigScreen = require('./config')
+const AddTokenScreen = require('./add-token')
+const Import = require('./accounts/import')
+const InfoScreen = require('./info')
+const Loading = require('./components/loading')
+const SandwichExpando = require('sandwich-expando')
+const Dropdown = require('./components/dropdown').Dropdown
+const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
+const NetworkIndicator = require('./components/network')
+const BuyView = require('./components/buy-button-subview')
+const QrView = require('./components/qr-code')
+const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
+const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
+const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
+const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
+const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+
+module.exports = connect(mapStateToProps)(App)
+
+inherits(App, Component)
+function App () { Component.call(this) }
+
+function mapStateToProps (state) {
+ const {
+ identities,
+ accounts,
+ address,
+ keyrings,
+ isInitialized,
+ noActiveNotices,
+ seedWords,
+ featureFlags,
+ } = state.metamask
+ const selected = address || Object.keys(accounts)[0]
+
+ return {
+ // state from plugin
+ isLoading: state.appState.isLoading,
+ loadingMessage: state.appState.loadingMessage,
+ noActiveNotices: state.metamask.noActiveNotices,
+ isInitialized: state.metamask.isInitialized,
+ isUnlocked: state.metamask.isUnlocked,
+ currentView: state.appState.currentView,
+ activeAddress: state.appState.activeAddress,
+ transForward: state.appState.transForward,
+ isMascara: state.metamask.isMascara,
+ isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ seedWords: state.metamask.seedWords,
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
+ menuOpen: state.appState.menuOpen,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice: state.metamask.lastUnreadNotice,
+ lostAccounts: state.metamask.lostAccounts,
+ frequentRpcList: state.metamask.frequentRpcList || [],
+ featureFlags,
+
+ // state needed to get account dropdown temporarily rendering from app bar
+ identities,
+ selected,
+ keyrings,
+ }
+}
+
+App.prototype.render = function () {
+ var props = this.props
+ const { isLoading, loadingMessage, transForward, network } = props
+ const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
+ const loadMessage = loadingMessage || isLoadingNetwork ?
+ `Connecting to ${this.getNetworkName()}` : null
+ log.debug('Main ui render function')
+
+ return (
+ h('.flex-column.full-height', {
+ style: {
+ // Windows was showing a vertical scroll bar:
+ overflow: 'hidden',
+ position: 'relative',
+ alignItems: 'center',
+ },
+ }, [
+
+ // app bar
+ this.renderAppBar(),
+ this.renderNetworkDropdown(),
+ this.renderDropdown(),
+
+ this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
+
+ // panel content
+ h('.app-primary' + (transForward ? '.from-right' : '.from-left'), {
+ style: {
+ width: '100%',
+ },
+ }, [
+ this.renderPrimary(),
+ ]),
+ ])
+ )
+}
+
+App.prototype.renderAppBar = function () {
+ if (window.METAMASK_UI_TYPE === 'notification') {
+ return null
+ }
+
+ const props = this.props
+ const state = this.state || {}
+ const isNetworkMenuOpen = state.isNetworkMenuOpen || false
+ const {isMascara, isOnboarding} = props
+
+ // Do not render header if user is in mascara onboarding
+ if (isMascara && isOnboarding) {
+ return null
+ }
+
+ // Do not render header if user is in mascara buy ether
+ if (isMascara && props.currentView.name === 'buyEth') {
+ return null
+ }
+
+ return (
+
+ h('.full-width', {
+ height: '38px',
+ }, [
+
+ h('.app-header.flex-row.flex-space-between', {
+ style: {
+ alignItems: 'center',
+ visibility: props.isUnlocked ? 'visible' : 'none',
+ background: props.isUnlocked ? 'white' : 'none',
+ height: '38px',
+ position: 'relative',
+ zIndex: 12,
+ },
+ }, [
+
+ h('div.left-menu-section', {
+ style: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ }, [
+
+ // mini logo
+ h('img', {
+ height: 24,
+ width: 24,
+ src: '/images/icon-128.png',
+ }),
+
+ h(NetworkIndicator, {
+ network: this.props.network,
+ provider: this.props.provider,
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
+ },
+ }),
+ ]),
+
+ props.isUnlocked && h('div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ }, [
+
+ props.isUnlocked && h(AccountDropdowns, {
+ style: {},
+ enableAccountsSelector: true,
+ identities: this.props.identities,
+ selected: this.props.currentView.context,
+ network: this.props.network,
+ keyrings: this.props.keyrings,
+ }, []),
+
+ // hamburger
+ props.isUnlocked && h(SandwichExpando, {
+ className: 'sandwich-expando',
+ width: 16,
+ barHeight: 2,
+ padding: 0,
+ isOpen: state.isMainMenuOpen,
+ color: 'rgb(247,146,30)',
+ onClick: () => {
+ this.setState({
+ isMainMenuOpen: !state.isMainMenuOpen,
+ })
+ },
+ }),
+ ]),
+ ]),
+ ])
+ )
+}
+
+App.prototype.renderNetworkDropdown = function () {
+ const props = this.props
+ const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
+ const rpcList = props.frequentRpcList
+ const state = this.state || {}
+ const isOpen = state.isNetworkMenuOpen
+
+ return h(Dropdown, {
+ useCssTransition: true,
+ isOpen,
+ onClickOutside: (event) => {
+ const { classList } = event.target
+ const isNotToggleElement = [
+ classList.contains('menu-icon'),
+ classList.contains('network-name'),
+ classList.contains('network-indicator'),
+ ].filter(bool => bool).length === 0
+ // classes from three constituent nodes of the toggle element
+
+ if (isNotToggleElement) {
+ this.setState({ isNetworkMenuOpen: false })
+ }
+ },
+ zIndex: 11,
+ style: {
+ position: 'absolute',
+ left: '2px',
+ top: '36px',
+ },
+ innerStyle: {
+ padding: '2px 16px 2px 0px',
+ },
+ }, [
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'main',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('mainnet')),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('.menu-icon.diamond'),
+ 'Main Ethereum Network',
+ providerType === 'mainnet' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'ropsten',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('ropsten')),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('.menu-icon.red-dot'),
+ 'Ropsten Test Network',
+ providerType === 'ropsten' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'kovan',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('kovan')),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('.menu-icon.hollow-diamond'),
+ 'Kovan Test Network',
+ providerType === 'kovan' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'rinkeby',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('rinkeby')),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('.menu-icon.golden-square'),
+ 'Rinkeby Test Network',
+ providerType === 'rinkeby' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'default',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('localhost')),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Localhost 8545',
+ activeNetwork === 'http://localhost:8545' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ this.renderCustomOption(props.provider),
+ this.renderCommonRpc(rpcList, props.provider),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => this.props.dispatch(actions.showConfigPage()),
+ style: {
+ fontSize: '18px',
+ },
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Custom RPC',
+ activeNetwork === 'custom' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ ])
+}
+
+App.prototype.renderDropdown = function () {
+ const state = this.state || {}
+ const isOpen = state.isMainMenuOpen
+
+ return h(Dropdown, {
+ useCssTransition: true,
+ isOpen: isOpen,
+ zIndex: 11,
+ onClickOutside: (event) => {
+ const classList = event.target.classList
+ const parentClassList = event.target.parentElement.classList
+
+ const isToggleElement = classList.contains('sandwich-expando') ||
+ parentClassList.contains('sandwich-expando')
+
+ if (isOpen && !isToggleElement) {
+ this.setState({ isMainMenuOpen: false })
+ }
+ },
+ style: {
+ position: 'absolute',
+ right: '2px',
+ top: '38px',
+ },
+ innerStyle: {},
+ }, [
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { this.props.dispatch(actions.showConfigPage()) },
+ }, 'Settings'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { this.props.dispatch(actions.lockMetamask()) },
+ }, 'Log Out'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => { this.props.dispatch(actions.showInfoPage()) },
+ }, 'Info/Help'),
+
+ h(DropdownMenuItem, {
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ onClick: () => {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
+ },
+ }, 'Try Beta!'),
+ ])
+}
+
+App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
+ const { isMascara } = this.props
+
+ return isMascara
+ ? null
+ : h(Loading, {
+ isLoading: isLoading || isLoadingNetwork,
+ loadingMessage: loadMessage,
+ })
+}
+
+App.prototype.renderBackButton = function (style, justArrow = false) {
+ var props = this.props
+ return (
+ h('.flex-row', {
+ key: 'leftArrow',
+ style: style,
+ onClick: () => props.dispatch(actions.goBackToInitView()),
+ }, [
+ h('i.fa.fa-arrow-left.cursor-pointer'),
+ justArrow ? null : h('div.cursor-pointer', {
+ style: {
+ marginLeft: '3px',
+ },
+ onClick: () => props.dispatch(actions.goBackToInitView()),
+ }, 'BACK'),
+ ])
+ )
+}
+
+App.prototype.renderPrimary = function () {
+ log.debug('rendering primary')
+ var props = this.props
+ const {isMascara, isOnboarding} = props
+
+ if (isMascara && isOnboarding) {
+ return h(MascaraFirstTime)
+ }
+
+ // notices
+ if (!props.noActiveNotices) {
+ log.debug('rendering notice screen for unread notices.')
+ return h('div', {
+ style: { width: '100%' },
+ }, [
+
+ h(NoticeScreen, {
+ notice: props.lastUnreadNotice,
+ key: 'NoticeScreen',
+ onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ }),
+
+ !props.isInitialized && h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => {
+ global.platform.openExtensionInBrowser()
+ props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
+ .then(() => props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
+ },
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Try Beta Version'),
+ ]),
+
+ ])
+ } else if (props.lostAccounts && props.lostAccounts.length > 0) {
+ log.debug('rendering notice screen for lost accounts view.')
+ return h(NoticeScreen, {
+ notice: generateLostAccountsNotice(props.lostAccounts),
+ key: 'LostAccountsNotice',
+ onConfirm: () => props.dispatch(actions.markAccountsFound()),
+ })
+ }
+
+ // show initialize screen
+ if (!props.isInitialized || props.forgottenPassword) {
+ // show current view
+ log.debug('rendering an initialize screen')
+ switch (props.currentView.name) {
+
+ case 'restoreVault':
+ log.debug('rendering restore vault screen')
+ return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ default:
+ log.debug('rendering menu screen')
+ return h(InitializeMenuScreen, {key: 'menuScreenInit'})
+ }
+ }
+
+ // show unlock screen
+ if (!props.isUnlocked) {
+ switch (props.currentView.name) {
+
+ case 'restoreVault':
+ log.debug('rendering restore vault screen')
+ return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ case 'config':
+ log.debug('rendering config screen from unlock screen.')
+ return h(ConfigScreen, {key: 'config'})
+
+ default:
+ log.debug('rendering locked screen')
+ return h(UnlockScreen, {key: 'locked'})
+ }
+ }
+
+ // show seed words screen
+ if (props.seedWords) {
+ log.debug('rendering seed words')
+ return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
+ }
+
+ // show current view
+ switch (props.currentView.name) {
+
+ case 'accountDetail':
+ log.debug('rendering account detail screen')
+ return h(AccountDetailScreen, {key: 'account-detail'})
+
+ case 'sendTransaction':
+ log.debug('rendering send tx screen')
+ return h(SendTransactionScreen, {key: 'send-transaction'})
+
+ case 'newKeychain':
+ log.debug('rendering new keychain screen')
+ return h(NewKeyChainScreen, {key: 'new-keychain'})
+
+ case 'confTx':
+ log.debug('rendering confirm tx screen')
+ return h(ConfirmTxScreen, {key: 'confirm-tx'})
+
+ case 'add-token':
+ log.debug('rendering add-token screen from unlock screen.')
+ return h(AddTokenScreen, {key: 'add-token'})
+
+ case 'config':
+ log.debug('rendering config screen')
+ return h(ConfigScreen, {key: 'config'})
+
+ case 'import-menu':
+ log.debug('rendering import screen')
+ return h(Import, {key: 'import-menu'})
+
+ case 'reveal-seed-conf':
+ log.debug('rendering reveal seed confirmation screen')
+ return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
+
+ case 'info':
+ log.debug('rendering info screen')
+ return h(InfoScreen, {key: 'info'})
+
+ case 'buyEth':
+ log.debug('rendering buy ether screen')
+ return h(BuyView, {key: 'buyEthView'})
+
+ case 'onboardingBuyEth':
+ log.debug('rendering onboarding buy ether screen')
+ return h(MascaraBuyEtherScreen, {key: 'buyEthView'})
+
+ case 'qr':
+ log.debug('rendering show qr screen')
+ console.log(`QrView`, QrView);
+ return h('div', {
+ style: {
+ position: 'absolute',
+ height: '100%',
+ top: '0px',
+ left: '0px',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
+ style: {
+ marginLeft: '10px',
+ marginTop: '50px',
+ },
+ }),
+ h('div', {
+ style: {
+ position: 'absolute',
+ left: '44px',
+ width: '285px',
+ },
+ }, [
+ h(QrView, {key: 'qr'}),
+ ]),
+ ])
+
+ default:
+ log.debug('rendering default, account detail screen')
+ return h(AccountDetailScreen, {key: 'account-detail'})
+ }
+}
+
+App.prototype.toggleMetamaskActive = function () {
+ if (!this.props.isUnlocked) {
+ // currently inactive: redirect to password box
+ var passwordBox = document.querySelector('input[type=password]')
+ if (!passwordBox) return
+ passwordBox.focus()
+ } else {
+ // currently active: deactivate
+ this.props.dispatch(actions.lockMetamask(false))
+ }
+}
+
+App.prototype.renderCustomOption = function (provider) {
+ const { rpcTarget, type } = provider
+ const props = this.props
+
+ if (type !== 'rpc') return null
+
+ // Concatenate long URLs
+ let label = rpcTarget
+ if (rpcTarget.length > 31) {
+ label = label.substr(0, 34) + '...'
+ }
+
+ switch (rpcTarget) {
+
+ case 'http://localhost:8545':
+ return null
+
+ default:
+ return h(
+ DropdownMenuItem,
+ {
+ key: rpcTarget,
+ onClick: () => props.dispatch(actions.setRpcTarget(rpcTarget)),
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ label,
+ h('.check', '✓'),
+ ]
+ )
+ }
+}
+
+App.prototype.getNetworkName = function () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = 'Main Ethereum Network'
+ } else if (providerName === 'ropsten') {
+ name = 'Ropsten Test Network'
+ } else if (providerName === 'kovan') {
+ name = 'Kovan Test Network'
+ } else if (providerName === 'rinkeby') {
+ name = 'Rinkeby Test Network'
+ } else {
+ name = 'Unknown Private Network'
+ }
+
+ return name
+}
+
+App.prototype.renderCommonRpc = function (rpcList, provider) {
+ const props = this.props
+ const rpcTarget = provider.rpcTarget
+
+ return rpcList.map((rpc) => {
+ if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
+ return null
+ } else {
+ return h(
+ DropdownMenuItem,
+ {
+ key: `common${rpc}`,
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ onClick: () => props.dispatch(actions.setRpcTarget(rpc)),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ rpc,
+ rpcTarget === rpc ? h('.check', '✓') : null,
+ ]
+ )
+ }
+ })
+}
diff --git a/old-ui/app/components/account-dropdowns.js b/old-ui/app/components/account-dropdowns.js
new file mode 100644
index 000000000..aa7a3ad67
--- /dev/null
+++ b/old-ui/app/components/account-dropdowns.js
@@ -0,0 +1,320 @@
+const Component = require('react').Component
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const actions = require('../../../ui/app/actions')
+const genAccountLink = require('etherscan-link').createAccountLink
+const connect = require('react-redux').connect
+const Dropdown = require('./dropdown').Dropdown
+const DropdownMenuItem = require('./dropdown').DropdownMenuItem
+const Identicon = require('./identicon')
+const ethUtil = require('ethereumjs-util')
+const copyToClipboard = require('copy-to-clipboard')
+
+class AccountDropdowns extends Component {
+ constructor (props) {
+ super(props)
+ this.state = {
+ accountSelectorActive: false,
+ optionsMenuActive: false,
+ }
+ this.accountSelectorToggleClassName = 'accounts-selector'
+ this.optionsMenuToggleClassName = 'fa-ellipsis-h'
+ }
+
+ renderAccounts () {
+ const { identities, selected, keyrings } = this.props
+
+ return Object.keys(identities).map((key, index) => {
+ const identity = identities[key]
+ const isSelected = identity.address === selected
+
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress) ||
+ kr.accounts.includes(identity.address)
+ })
+
+ return h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ this.props.actions.showAccountDetail(identity.address)
+ },
+ style: {
+ marginTop: index === 0 ? '5px' : '',
+ fontSize: '24px',
+ },
+ },
+ [
+ h(
+ Identicon,
+ {
+ address: identity.address,
+ diameter: 32,
+ style: {
+ marginLeft: '10px',
+ },
+ },
+ ),
+ this.indicateIfLoose(keyring),
+ h('span', {
+ style: {
+ marginLeft: '20px',
+ fontSize: '24px',
+ maxWidth: '145px',
+ whiteSpace: 'nowrap',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ },
+ }, identity.name || ''),
+ h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
+ ]
+ )
+ })
+ }
+
+ indicateIfLoose (keyring) {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'LOOSE') : null
+ } catch (e) { return }
+ }
+
+ renderAccountSelector () {
+ const { actions } = this.props
+ const { accountSelectorActive } = this.state
+
+ return h(
+ Dropdown,
+ {
+ useCssTransition: true, // Hardcoded because account selector is temporarily in app-header
+ style: {
+ marginLeft: '-238px',
+ marginTop: '38px',
+ minWidth: '180px',
+ overflowY: 'auto',
+ maxHeight: '300px',
+ width: '300px',
+ },
+ innerStyle: {
+ padding: '8px 25px',
+ },
+ isOpen: accountSelectorActive,
+ onClickOutside: (event) => {
+ const { classList } = event.target
+ const isNotToggleElement = !classList.contains(this.accountSelectorToggleClassName)
+ if (accountSelectorActive && isNotToggleElement) {
+ this.setState({ accountSelectorActive: false })
+ }
+ },
+ },
+ [
+ ...this.renderAccounts(),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => actions.addNewAccount(),
+ },
+ [
+ h(
+ Identicon,
+ {
+ style: {
+ marginLeft: '10px',
+ },
+ diameter: 32,
+ },
+ ),
+ h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, 'Create Account'),
+ ],
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => actions.showImportPage(),
+ },
+ [
+ h(
+ Identicon,
+ {
+ style: {
+ marginLeft: '10px',
+ },
+ diameter: 32,
+ },
+ ),
+ h('span', {
+ style: {
+ marginLeft: '20px',
+ fontSize: '24px',
+ marginBottom: '5px',
+ },
+ }, 'Import Account'),
+ ]
+ ),
+ ]
+ )
+ }
+
+ renderAccountOptions () {
+ const { actions } = this.props
+ const { optionsMenuActive } = this.state
+
+ return h(
+ Dropdown,
+ {
+ style: {
+ marginLeft: '-215px',
+ minWidth: '180px',
+ },
+ isOpen: optionsMenuActive,
+ onClickOutside: () => {
+ const { classList } = event.target
+ const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
+ if (optionsMenuActive && isNotToggleElement) {
+ this.setState({ optionsMenuActive: false })
+ }
+ },
+ },
+ [
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ const { selected, network } = this.props
+ const url = genAccountLink(selected, network)
+ global.platform.openWindow({ url })
+ },
+ },
+ 'View account on Etherscan',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ const { selected, identities } = this.props
+ var identity = identities[selected]
+ actions.showQrView(selected, identity ? identity.name : '')
+ },
+ },
+ 'Show QR Code',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ const { selected } = this.props
+ const checkSumAddress = selected && ethUtil.toChecksumAddress(selected)
+ copyToClipboard(checkSumAddress)
+ },
+ },
+ 'Copy Address to clipboard',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ actions.requestAccountExport()
+ },
+ },
+ 'Export Private Key',
+ ),
+ ]
+ )
+ }
+
+ render () {
+ const { style, enableAccountsSelector, enableAccountOptions } = this.props
+ const { optionsMenuActive, accountSelectorActive } = this.state
+
+ return h(
+ 'span',
+ {
+ style: style,
+ },
+ [
+ enableAccountsSelector && h(
+ // 'i.fa.fa-angle-down',
+ 'div.cursor-pointer.color-orange.accounts-selector',
+ {
+ style: {
+ // fontSize: '1.8em',
+ background: 'url(images/switch_acc.svg) white center center no-repeat',
+ height: '25px',
+ width: '25px',
+ transform: 'scale(0.75)',
+ marginRight: '3px',
+ },
+ onClick: (event) => {
+ event.stopPropagation()
+ this.setState({
+ accountSelectorActive: !accountSelectorActive,
+ optionsMenuActive: false,
+ })
+ },
+ },
+ this.renderAccountSelector(),
+ ),
+ enableAccountOptions && h(
+ 'i.fa.fa-ellipsis-h',
+ {
+ style: {
+ margin: '0.5em',
+ fontSize: '1.8em',
+ },
+ onClick: (event) => {
+ event.stopPropagation()
+ this.setState({
+ accountSelectorActive: false,
+ optionsMenuActive: !optionsMenuActive,
+ })
+ },
+ },
+ this.renderAccountOptions()
+ ),
+ ]
+ )
+ }
+}
+
+AccountDropdowns.defaultProps = {
+ enableAccountsSelector: false,
+ enableAccountOptions: false,
+}
+
+AccountDropdowns.propTypes = {
+ identities: PropTypes.objectOf(PropTypes.object),
+ selected: PropTypes.string,
+ keyrings: PropTypes.array,
+ actions: PropTypes.objectOf(PropTypes.func),
+ network: PropTypes.string,
+ style: PropTypes.object,
+ enableAccountOptions: PropTypes.bool,
+ enableAccountsSelector: PropTypes.bool,
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ actions: {
+ showConfigPage: () => dispatch(actions.showConfigPage()),
+ requestAccountExport: () => dispatch(actions.requestExportAccount()),
+ showAccountDetail: (address) => dispatch(actions.showAccountDetail(address)),
+ addNewAccount: () => dispatch(actions.addNewAccount()),
+ showImportPage: () => dispatch(actions.showImportPage()),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ },
+ }
+}
+
+module.exports = {
+ AccountDropdowns: connect(null, mapDispatchToProps)(AccountDropdowns),
+}
diff --git a/old-ui/app/components/account-export.js b/old-ui/app/components/account-export.js
new file mode 100644
index 000000000..51b85b786
--- /dev/null
+++ b/old-ui/app/components/account-export.js
@@ -0,0 +1,132 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const exportAsFile = require('../util').exportAsFile
+const copyToClipboard = require('copy-to-clipboard')
+const actions = require('../../../ui/app/actions')
+const ethUtil = require('ethereumjs-util')
+const connect = require('react-redux').connect
+
+module.exports = connect(mapStateToProps)(ExportAccountView)
+
+inherits(ExportAccountView, Component)
+function ExportAccountView () {
+ Component.call(this)
+}
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ }
+}
+
+ExportAccountView.prototype.render = function () {
+ const state = this.props
+ const accountDetail = state.accountDetail
+ const nickname = state.identities[state.address].name
+
+ if (!accountDetail) return h('div')
+ const accountExport = accountDetail.accountExport
+
+ const notExporting = accountExport === 'none'
+ const exportRequested = accountExport === 'requested'
+ const accountExported = accountExport === 'completed'
+
+ if (notExporting) return h('div')
+
+ if (exportRequested) {
+ const warning = `Export private keys at your own risk.`
+ return (
+ h('div', {
+ style: {
+ display: 'inline-block',
+ textAlign: 'center',
+ },
+ },
+ [
+ h('div', {
+ key: 'exporting',
+ style: {
+ margin: '0 20px',
+ },
+ }, [
+ h('p.error', warning),
+ h('input#exportAccount.sizing-input', {
+ type: 'password',
+ placeholder: 'confirm password',
+ onKeyPress: this.onExportKeyPress.bind(this),
+ style: {
+ position: 'relative',
+ top: '1.5px',
+ marginBottom: '7px',
+ },
+ }),
+ ]),
+ h('div', {
+ key: 'buttons',
+ style: {
+ margin: '0 20px',
+ },
+ },
+ [
+ h('button', {
+ onClick: () => this.onExportKeyPress({ key: 'Enter', preventDefault: () => {} }),
+ style: {
+ marginRight: '10px',
+ },
+ }, 'Submit'),
+ h('button', {
+ onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
+ }, 'Cancel'),
+ ]),
+ (this.props.warning) && (
+ h('span.error', {
+ style: {
+ margin: '20px',
+ },
+ }, this.props.warning.split('-'))
+ ),
+ ])
+ )
+ }
+
+ if (accountExported) {
+ const plainKey = ethUtil.stripHexPrefix(accountDetail.privateKey)
+
+ return h('div.privateKey', {
+ style: {
+ margin: '0 20px',
+ },
+ }, [
+ h('label', 'Your private key (click to copy):'),
+ h('p.error.cursor-pointer', {
+ style: {
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ webkitUserSelect: 'text',
+ maxWidth: '275px',
+ },
+ onClick: function (event) {
+ copyToClipboard(ethUtil.stripHexPrefix(accountDetail.privateKey))
+ },
+ }, plainKey),
+ h('button', {
+ onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
+ }, 'Done'),
+ h('button', {
+ style: {
+ marginLeft: '10px',
+ },
+ onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey),
+ }, 'Save as File'),
+ ])
+ }
+}
+
+ExportAccountView.prototype.onExportKeyPress = function (event) {
+ if (event.key !== 'Enter') return
+ event.preventDefault()
+
+ const input = document.getElementById('exportAccount').value
+ this.props.dispatch(actions.exportAccount(input, this.props.address))
+}
diff --git a/old-ui/app/components/account-panel.js b/old-ui/app/components/account-panel.js
new file mode 100644
index 000000000..abaaf8163
--- /dev/null
+++ b/old-ui/app/components/account-panel.js
@@ -0,0 +1,86 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const Identicon = require('./identicon')
+const formatBalance = require('../util').formatBalance
+const addressSummary = require('../util').addressSummary
+
+module.exports = AccountPanel
+
+
+inherits(AccountPanel, Component)
+function AccountPanel () {
+ Component.call(this)
+}
+
+AccountPanel.prototype.render = function () {
+ var state = this.props
+ var identity = state.identity || {}
+ var account = state.account || {}
+ var isFauceting = state.isFauceting
+
+ var panelState = {
+ key: `accountPanel${identity.address}`,
+ identiconKey: identity.address,
+ identiconLabel: identity.name || '',
+ attributes: [
+ {
+ key: 'ADDRESS',
+ value: addressSummary(identity.address),
+ },
+ balanceOrFaucetingIndication(account, isFauceting),
+ ],
+ }
+
+ return (
+
+ h('.identity-panel.flex-row.flex-space-between', {
+ style: {
+ flex: '1 0 auto',
+ cursor: panelState.onClick ? 'pointer' : undefined,
+ },
+ onClick: panelState.onClick,
+ }, [
+
+ // account identicon
+ h('.identicon-wrapper.flex-column.select-none', [
+ h(Identicon, {
+ address: panelState.identiconKey,
+ imageify: state.imageifyIdenticons,
+ }),
+ h('span.font-small', panelState.identiconLabel.substring(0, 7) + '...'),
+ ]),
+
+ // account address, balance
+ h('.identity-data.flex-column.flex-justify-center.flex-grow.select-none', [
+
+ panelState.attributes.map((attr) => {
+ return h('.flex-row.flex-space-between', {
+ key: '' + Math.round(Math.random() * 1000000),
+ }, [
+ h('label.font-small.no-select', attr.key),
+ h('span.font-small', attr.value),
+ ])
+ }),
+ ]),
+
+ ])
+
+ )
+}
+
+function balanceOrFaucetingIndication (account, isFauceting) {
+ // Temporarily deactivating isFauceting indication
+ // because it shows fauceting for empty restored accounts.
+ if (/* isFauceting*/ false) {
+ return {
+ key: 'Account is auto-funding.',
+ value: 'Please wait.',
+ }
+ } else {
+ return {
+ key: 'BALANCE',
+ value: formatBalance(account.balance),
+ }
+ }
+}
diff --git a/old-ui/app/components/balance.js b/old-ui/app/components/balance.js
new file mode 100644
index 000000000..57ca84564
--- /dev/null
+++ b/old-ui/app/components/balance.js
@@ -0,0 +1,89 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const formatBalance = require('../util').formatBalance
+const generateBalanceObject = require('../util').generateBalanceObject
+const Tooltip = require('./tooltip.js')
+const FiatValue = require('./fiat-value.js')
+
+module.exports = EthBalanceComponent
+
+inherits(EthBalanceComponent, Component)
+function EthBalanceComponent () {
+ Component.call(this)
+}
+
+EthBalanceComponent.prototype.render = function () {
+ var props = this.props
+ let { value } = props
+ var style = props.style
+ var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
+ value = value ? formatBalance(value, 6, needsParse) : '...'
+ var width = props.width
+
+ return (
+
+ h('.ether-balance.ether-balance-amount', {
+ style: style,
+ }, [
+ h('div', {
+ style: {
+ display: 'inline',
+ width: width,
+ },
+ }, this.renderBalance(value)),
+ ])
+
+ )
+}
+EthBalanceComponent.prototype.renderBalance = function (value) {
+ var props = this.props
+ if (value === 'None') return value
+ if (value === '...') return value
+ var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
+ var balance
+ var splitBalance = value.split(' ')
+ var ethNumber = splitBalance[0]
+ var ethSuffix = splitBalance[1]
+ const showFiat = 'showFiat' in props ? props.showFiat : true
+
+ if (props.shorten) {
+ balance = balanceObj.shortBalance
+ } else {
+ balance = balanceObj.balance
+ }
+
+ var label = balanceObj.label
+
+ return (
+ h(Tooltip, {
+ position: 'bottom',
+ title: `${ethNumber} ${ethSuffix}`,
+ }, h('div.flex-column', [
+ h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('div', {
+ style: {
+ width: '100%',
+ textAlign: 'right',
+ },
+ }, this.props.incoming ? `+${balance}` : balance),
+ h('div', {
+ style: {
+ color: ' #AEAEAE',
+ fontSize: '12px',
+ marginLeft: '5px',
+ },
+ }, label),
+ ]),
+
+ showFiat ? h(FiatValue, { value: props.value }) : null,
+ ]))
+ )
+}
diff --git a/old-ui/app/components/binary-renderer.js b/old-ui/app/components/binary-renderer.js
new file mode 100644
index 000000000..0b6a1f5c2
--- /dev/null
+++ b/old-ui/app/components/binary-renderer.js
@@ -0,0 +1,46 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ethUtil = require('ethereumjs-util')
+const extend = require('xtend')
+
+module.exports = BinaryRenderer
+
+inherits(BinaryRenderer, Component)
+function BinaryRenderer () {
+ Component.call(this)
+}
+
+BinaryRenderer.prototype.render = function () {
+ const props = this.props
+ const { value, style } = props
+ const text = this.hexToText(value)
+
+ const defaultStyle = extend({
+ width: '315px',
+ maxHeight: '210px',
+ resize: 'none',
+ border: 'none',
+ background: 'white',
+ padding: '3px',
+ }, style)
+
+ return (
+ h('textarea.font-small', {
+ readOnly: true,
+ style: defaultStyle,
+ defaultValue: text,
+ })
+ )
+}
+
+BinaryRenderer.prototype.hexToText = function (hex) {
+ try {
+ const stripped = ethUtil.stripHexPrefix(hex)
+ const buff = Buffer.from(stripped, 'hex')
+ return buff.toString('utf8')
+ } catch (e) {
+ return hex
+ }
+}
+
diff --git a/old-ui/app/components/bn-as-decimal-input.js b/old-ui/app/components/bn-as-decimal-input.js
new file mode 100644
index 000000000..22e37602e
--- /dev/null
+++ b/old-ui/app/components/bn-as-decimal-input.js
@@ -0,0 +1,181 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const extend = require('xtend')
+
+module.exports = BnAsDecimalInput
+
+inherits(BnAsDecimalInput, Component)
+function BnAsDecimalInput () {
+ this.state = { invalid: null }
+ Component.call(this)
+}
+
+/* Bn as Decimal Input
+ *
+ * A component for allowing easy, decimal editing
+ * of a passed in bn string value.
+ *
+ * On change, calls back its `onChange` function parameter
+ * and passes it an updated bn string.
+ */
+
+BnAsDecimalInput.prototype.render = function () {
+ const props = this.props
+ const state = this.state
+
+ const { value, scale, precision, onChange, min, max } = props
+
+ const suffix = props.suffix
+ const style = props.style
+ const valueString = value.toString(10)
+ const newMin = min && this.downsize(min.toString(10), scale)
+ const newMax = max && this.downsize(max.toString(10), scale)
+ const newValue = this.downsize(valueString, scale)
+
+ return (
+ h('.flex-column', [
+ h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('input.hex-input', {
+ type: 'number',
+ step: 'any',
+ required: true,
+ min: newMin,
+ max: newMax,
+ style: extend({
+ display: 'block',
+ textAlign: 'right',
+ backgroundColor: 'transparent',
+ border: '1px solid #bdbdbd',
+
+ }, style),
+ value: newValue,
+ onBlur: (event) => {
+ this.updateValidity(event)
+ },
+ onChange: (event) => {
+ this.updateValidity(event)
+ const value = (event.target.value === '') ? '' : event.target.value
+
+
+ const scaledNumber = this.upsize(value, scale, precision)
+ const precisionBN = new BN(scaledNumber, 10)
+ onChange(precisionBN, event.target.checkValidity())
+ },
+ onInvalid: (event) => {
+ const msg = this.constructWarning()
+ if (msg === state.invalid) {
+ return
+ }
+ this.setState({ invalid: msg })
+ event.preventDefault()
+ return false
+ },
+ }),
+ h('div', {
+ style: {
+ color: ' #AEAEAE',
+ fontSize: '12px',
+ marginLeft: '5px',
+ marginRight: '6px',
+ width: '20px',
+ },
+ }, suffix),
+ ]),
+
+ state.invalid ? h('span.error', {
+ style: {
+ position: 'absolute',
+ right: '0px',
+ textAlign: 'right',
+ transform: 'translateY(26px)',
+ padding: '3px',
+ background: 'rgba(255,255,255,0.85)',
+ zIndex: '1',
+ textTransform: 'capitalize',
+ border: '2px solid #E20202',
+ },
+ }, state.invalid) : null,
+ ])
+ )
+}
+
+BnAsDecimalInput.prototype.setValid = function (message) {
+ this.setState({ invalid: null })
+}
+
+BnAsDecimalInput.prototype.updateValidity = function (event) {
+ const target = event.target
+ const value = this.props.value
+ const newValue = target.value
+
+ if (value === newValue) {
+ return
+ }
+
+ const valid = target.checkValidity()
+
+ if (valid) {
+ this.setState({ invalid: null })
+ }
+}
+
+BnAsDecimalInput.prototype.constructWarning = function () {
+ const { name, min, max, scale, suffix } = this.props
+ const newMin = min && this.downsize(min.toString(10), scale)
+ const newMax = max && this.downsize(max.toString(10), scale)
+ let message = name ? name + ' ' : ''
+
+ if (min && max) {
+ message += `must be greater than or equal to ${newMin} ${suffix} and less than or equal to ${newMax} ${suffix}.`
+ } else if (min) {
+ message += `must be greater than or equal to ${newMin} ${suffix}.`
+ } else if (max) {
+ message += `must be less than or equal to ${newMax} ${suffix}.`
+ } else {
+ message += 'Invalid input.'
+ }
+
+ return message
+}
+
+
+BnAsDecimalInput.prototype.downsize = function (number, scale) {
+ // if there is no scaling, simply return the number
+ if (scale === 0) {
+ return Number(number)
+ } else {
+ // if the scale is the same as the precision, account for this edge case.
+ var adjustedNumber = number
+ while (adjustedNumber.length < scale) {
+ adjustedNumber = '0' + adjustedNumber
+ }
+ return Number(adjustedNumber.slice(0, -scale) + '.' + adjustedNumber.slice(-scale))
+ }
+}
+
+BnAsDecimalInput.prototype.upsize = function (number, scale, precision) {
+ var stringArray = number.toString().split('.')
+ var decimalLength = stringArray[1] ? stringArray[1].length : 0
+ var newString = stringArray[0]
+
+ // If there is scaling and decimal parts exist, integrate them in.
+ if ((scale !== 0) && (decimalLength !== 0)) {
+ newString += stringArray[1].slice(0, precision)
+ }
+
+ // Add 0s to account for the upscaling.
+ for (var i = decimalLength; i < scale; i++) {
+ newString += '0'
+ }
+ return newString
+}
diff --git a/old-ui/app/components/buy-button-subview.js b/old-ui/app/components/buy-button-subview.js
new file mode 100644
index 000000000..843627c33
--- /dev/null
+++ b/old-ui/app/components/buy-button-subview.js
@@ -0,0 +1,262 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../../ui/app/actions')
+const CoinbaseForm = require('./coinbase-form')
+const ShapeshiftForm = require('./shapeshift-form')
+const Loading = require('./loading')
+const AccountPanel = require('./account-panel')
+const RadioList = require('./custom-radio-list')
+const networkNames = require('../../../app/scripts/config.js').networkNames
+
+module.exports = connect(mapStateToProps)(BuyButtonSubview)
+
+function mapStateToProps (state) {
+ return {
+ identity: state.appState.identity,
+ account: state.metamask.accounts[state.appState.buyView.buyAddress],
+ warning: state.appState.warning,
+ buyView: state.appState.buyView,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ context: state.appState.currentView.context,
+ isSubLoading: state.appState.isSubLoading,
+ }
+}
+
+inherits(BuyButtonSubview, Component)
+function BuyButtonSubview () {
+ Component.call(this)
+}
+
+BuyButtonSubview.prototype.render = function () {
+ return (
+ h('div', {
+ style: {
+ width: '100%',
+ },
+ }, [
+ this.headerSubview(),
+ this.primarySubview(),
+ ])
+ )
+}
+
+BuyButtonSubview.prototype.headerSubview = function () {
+ const props = this.props
+ const isLoading = props.isSubLoading
+ return (
+
+ h('.flex-column', {
+ style: {
+ alignItems: 'center',
+ },
+ }, [
+
+ // header bar (back button, label)
+ h('.flex-row', {
+ style: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: this.backButtonContext.bind(this),
+ style: {
+ position: 'absolute',
+ left: '10px',
+ },
+ }),
+ h('h2.text-transform-uppercase.flex-center', {
+ style: {
+ width: '100vw',
+ background: 'rgb(235, 235, 235)',
+ color: 'rgb(174, 174, 174)',
+ paddingTop: '4px',
+ paddingBottom: '4px',
+ },
+ }, 'Buy Eth'),
+ ]),
+
+ // loading indication
+ h('div', {
+ style: {
+ position: 'absolute',
+ top: '57vh',
+ left: '49vw',
+ },
+ }, [
+ h(Loading, { isLoading }),
+ ]),
+
+ // account panel
+ h('div', {
+ style: {
+ width: '80%',
+ },
+ }, [
+ h(AccountPanel, {
+ showFullAddress: true,
+ identity: props.identity,
+ account: props.account,
+ }),
+ ]),
+
+ h('.flex-row', {
+ style: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ }, [
+ h('h3.text-transform-uppercase.flex-center', {
+ style: {
+ paddingLeft: '15px',
+ width: '100vw',
+ background: 'rgb(235, 235, 235)',
+ color: 'rgb(174, 174, 174)',
+ paddingTop: '4px',
+ paddingBottom: '4px',
+ },
+ }, 'Select Service'),
+ ]),
+
+ ])
+
+ )
+}
+
+
+BuyButtonSubview.prototype.primarySubview = function () {
+ const props = this.props
+ const network = props.network
+
+ switch (network) {
+ case 'loading':
+ return
+
+ case '1':
+ return this.mainnetSubview()
+
+ // Ropsten, Rinkeby, Kovan
+ case '3':
+ case '4':
+ case '42':
+ const networkName = networkNames[network]
+ const label = `${networkName} Test Faucet`
+ return (
+ h('div.flex-column', {
+ style: {
+ alignItems: 'center',
+ margin: '20px 50px',
+ },
+ }, [
+ h('button.text-transform-uppercase', {
+ onClick: () => this.props.dispatch(actions.buyEth({ network })),
+ style: {
+ marginTop: '15px',
+ },
+ }, label),
+ // Kovan only: Dharma loans beta
+ network === '42' ? (
+ h('button.text-transform-uppercase', {
+ onClick: () => this.navigateTo('https://borrow.dharma.io/'),
+ style: {
+ marginTop: '15px',
+ },
+ }, 'Borrow With Dharma (Beta)')
+ ) : null,
+ ])
+ )
+
+ default:
+ return (
+ h('h2.error', 'Unknown network ID')
+ )
+
+ }
+}
+
+BuyButtonSubview.prototype.mainnetSubview = function () {
+ const props = this.props
+
+ return (
+
+ h('.flex-column', {
+ style: {
+ alignItems: 'center',
+ },
+ }, [
+
+ h('.flex-row.selected-exchange', {
+ style: {
+ position: 'relative',
+ right: '35px',
+ marginTop: '20px',
+ marginBottom: '20px',
+ },
+ }, [
+ h(RadioList, {
+ defaultFocus: props.buyView.subview,
+ labels: [
+ 'Coinbase',
+ 'ShapeShift',
+ ],
+ subtext: {
+ 'Coinbase': 'Crypto/FIAT (USA only)',
+ 'ShapeShift': 'Crypto',
+ },
+ onClick: this.radioHandler.bind(this),
+ }),
+ ]),
+
+ h('h3.text-transform-uppercase', {
+ style: {
+ paddingLeft: '15px',
+ fontFamily: 'Montserrat Light',
+ width: '100vw',
+ background: 'rgb(235, 235, 235)',
+ color: 'rgb(174, 174, 174)',
+ paddingTop: '4px',
+ paddingBottom: '4px',
+ },
+ }, props.buyView.subview),
+
+ this.formVersionSubview(),
+ ])
+
+ )
+}
+
+BuyButtonSubview.prototype.formVersionSubview = function () {
+ const network = this.props.network
+ if (network === '1') {
+ if (this.props.buyView.formView.coinbase) {
+ return h(CoinbaseForm, this.props)
+ } else if (this.props.buyView.formView.shapeshift) {
+ return h(ShapeshiftForm, this.props)
+ }
+ }
+}
+
+BuyButtonSubview.prototype.navigateTo = function (url) {
+ global.platform.openWindow({ url })
+}
+
+BuyButtonSubview.prototype.backButtonContext = function () {
+ if (this.props.context === 'confTx') {
+ this.props.dispatch(actions.showConfTxPage(false))
+ } else {
+ console.log(`actions.goHome`, actions.goHome);
+ this.props.dispatch(actions.goHome())
+ }
+}
+
+BuyButtonSubview.prototype.radioHandler = function (event) {
+ switch (event.target.title) {
+ case 'Coinbase':
+ return this.props.dispatch(actions.coinBaseSubview())
+ case 'ShapeShift':
+ return this.props.dispatch(actions.shapeShiftSubview(this.props.provider.type))
+ }
+}
diff --git a/old-ui/app/components/coinbase-form.js b/old-ui/app/components/coinbase-form.js
new file mode 100644
index 000000000..35b2111ff
--- /dev/null
+++ b/old-ui/app/components/coinbase-form.js
@@ -0,0 +1,63 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(CoinbaseForm)
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ }
+}
+
+inherits(CoinbaseForm, Component)
+
+function CoinbaseForm () {
+ Component.call(this)
+}
+
+CoinbaseForm.prototype.render = function () {
+ var props = this.props
+
+ return h('.flex-column', {
+ style: {
+ marginTop: '35px',
+ padding: '25px',
+ width: '100%',
+ },
+ }, [
+ h('.flex-row', {
+ style: {
+ justifyContent: 'space-around',
+ margin: '33px',
+ marginTop: '0px',
+ },
+ }, [
+ h('button.btn-green', {
+ onClick: this.toCoinbase.bind(this),
+ }, 'Continue to Coinbase'),
+
+ h('button.btn-red', {
+ onClick: () => props.dispatch(actions.backTobuyView(props.accounts.address)),
+ }, 'Cancel'),
+ ]),
+ ])
+}
+
+CoinbaseForm.prototype.toCoinbase = function () {
+ const props = this.props
+ const address = props.buyView.buyAddress
+ props.dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+}
+
+CoinbaseForm.prototype.renderLoading = function () {
+ return h('img', {
+ style: {
+ width: '27px',
+ marginRight: '-27px',
+ },
+ src: 'images/loading.svg',
+ })
+}
diff --git a/old-ui/app/components/copyButton.js b/old-ui/app/components/copyButton.js
new file mode 100644
index 000000000..a25d0719c
--- /dev/null
+++ b/old-ui/app/components/copyButton.js
@@ -0,0 +1,59 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const copyToClipboard = require('copy-to-clipboard')
+
+const Tooltip = require('./tooltip')
+
+module.exports = CopyButton
+
+inherits(CopyButton, Component)
+function CopyButton () {
+ Component.call(this)
+}
+
+// As parameters, accepts:
+// "value", which is the value to copy (mandatory)
+// "title", which is the text to show on hover (optional, defaults to 'Copy')
+CopyButton.prototype.render = function () {
+ const props = this.props
+ const state = this.state || {}
+
+ const value = props.value
+ const copied = state.copied
+
+ const message = copied ? 'Copied' : props.title || ' Copy '
+
+ return h('.copy-button', {
+ style: {
+ display: 'flex',
+ alignItems: 'center',
+ },
+ }, [
+
+ h(Tooltip, {
+ title: message,
+ }, [
+ h('i.fa.fa-clipboard.cursor-pointer.color-orange', {
+ style: {
+ margin: '5px',
+ },
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ copyToClipboard(value)
+ this.debounceRestore()
+ },
+ }),
+ ]),
+
+ ])
+}
+
+CopyButton.prototype.debounceRestore = function () {
+ this.setState({ copied: true })
+ clearTimeout(this.timeout)
+ this.timeout = setTimeout(() => {
+ this.setState({ copied: false })
+ }, 850)
+}
diff --git a/old-ui/app/components/copyable.js b/old-ui/app/components/copyable.js
new file mode 100644
index 000000000..a4f6f4bc6
--- /dev/null
+++ b/old-ui/app/components/copyable.js
@@ -0,0 +1,46 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const Tooltip = require('./tooltip')
+const copyToClipboard = require('copy-to-clipboard')
+
+module.exports = Copyable
+
+inherits(Copyable, Component)
+function Copyable () {
+ Component.call(this)
+ this.state = {
+ copied: false,
+ }
+}
+
+Copyable.prototype.render = function () {
+ const props = this.props
+ const state = this.state
+ const { value, children } = props
+ const { copied } = state
+
+ return h(Tooltip, {
+ title: copied ? 'Copied!' : 'Copy',
+ position: 'bottom',
+ }, h('span', {
+ style: {
+ cursor: 'pointer',
+ },
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ copyToClipboard(value)
+ this.debounceRestore()
+ },
+ }, children))
+}
+
+Copyable.prototype.debounceRestore = function () {
+ this.setState({ copied: true })
+ clearTimeout(this.timeout)
+ this.timeout = setTimeout(() => {
+ this.setState({ copied: false })
+ }, 850)
+}
diff --git a/old-ui/app/components/custom-radio-list.js b/old-ui/app/components/custom-radio-list.js
new file mode 100644
index 000000000..a4c525396
--- /dev/null
+++ b/old-ui/app/components/custom-radio-list.js
@@ -0,0 +1,60 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = RadioList
+
+inherits(RadioList, Component)
+function RadioList () {
+ Component.call(this)
+}
+
+RadioList.prototype.render = function () {
+ const props = this.props
+ const activeClass = '.custom-radio-selected'
+ const inactiveClass = '.custom-radio-inactive'
+ const {
+ labels,
+ defaultFocus,
+ } = props
+
+
+ return (
+ h('.flex-row', {
+ style: {
+ fontSize: '12px',
+ },
+ }, [
+ h('.flex-column.custom-radios', {
+ style: {
+ marginRight: '5px',
+ },
+ },
+ labels.map((lable, i) => {
+ let isSelcted = (this.state !== null)
+ isSelcted = isSelcted ? (this.state.selected === lable) : (defaultFocus === lable)
+ return h(isSelcted ? activeClass : inactiveClass, {
+ title: lable,
+ onClick: (event) => {
+ this.setState({selected: event.target.title})
+ props.onClick(event)
+ },
+ })
+ })
+ ),
+ h('.text', {},
+ labels.map((lable) => {
+ if (props.subtext) {
+ return h('.flex-row', {}, [
+ h('.radio-titles', lable),
+ h('.radio-titles-subtext', `- ${props.subtext[lable]}`),
+ ])
+ } else {
+ return h('.radio-titles', lable)
+ }
+ })
+ ),
+ ])
+ )
+}
+
diff --git a/ui/app/components/dropdown.js b/old-ui/app/components/dropdown.js
index cdd864cc3..fb606d2c5 100644
--- a/ui/app/components/dropdown.js
+++ b/old-ui/app/components/dropdown.js
@@ -1,5 +1,5 @@
const Component = require('react').Component
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const MenuDroppo = require('./menu-droppo')
const extend = require('xtend')
diff --git a/old-ui/app/components/editable-label.js b/old-ui/app/components/editable-label.js
new file mode 100644
index 000000000..8a5c8954f
--- /dev/null
+++ b/old-ui/app/components/editable-label.js
@@ -0,0 +1,57 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const findDOMNode = require('react-dom').findDOMNode
+
+module.exports = EditableLabel
+
+inherits(EditableLabel, Component)
+function EditableLabel () {
+ Component.call(this)
+}
+
+EditableLabel.prototype.render = function () {
+ const props = this.props
+ const state = this.state
+
+ if (state && state.isEditingLabel) {
+ return h('div.editable-label', [
+ h('input.sizing-input', {
+ defaultValue: props.textValue,
+ maxLength: '20',
+ onKeyPress: (event) => {
+ this.saveIfEnter(event)
+ },
+ }),
+ h('button.editable-button', {
+ onClick: () => this.saveText(),
+ }, 'Save'),
+ ])
+ } else {
+ return h('div.name-label', {
+ onClick: (event) => {
+ const nameAttribute = event.target.getAttribute('name')
+ // checks for class to handle smaller CTA above the account name
+ const classAttribute = event.target.getAttribute('class')
+ if (nameAttribute === 'edit' || classAttribute === 'edit-text') {
+ this.setState({ isEditingLabel: true })
+ }
+ },
+ }, this.props.children)
+ }
+}
+
+EditableLabel.prototype.saveIfEnter = function (event) {
+ if (event.key === 'Enter') {
+ this.saveText()
+ }
+}
+
+EditableLabel.prototype.saveText = function () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
+ var text = container.querySelector('.editable-label input').value
+ var truncatedText = text.substring(0, 20)
+ this.props.saveText(truncatedText)
+ this.setState({ isEditingLabel: false, textLabel: truncatedText })
+}
diff --git a/old-ui/app/components/ens-input.js b/old-ui/app/components/ens-input.js
new file mode 100644
index 000000000..c85a23514
--- /dev/null
+++ b/old-ui/app/components/ens-input.js
@@ -0,0 +1,170 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const extend = require('xtend')
+const debounce = require('debounce')
+const copyToClipboard = require('copy-to-clipboard')
+const ENS = require('ethjs-ens')
+const networkMap = require('ethjs-ens/lib/network-map.json')
+const ensRE = /.+\..+$/
+const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
+
+
+module.exports = EnsInput
+
+inherits(EnsInput, Component)
+function EnsInput () {
+ Component.call(this)
+}
+
+EnsInput.prototype.render = function () {
+ const props = this.props
+ const opts = extend(props, {
+ list: 'addresses',
+ onChange: () => {
+ const network = this.props.network
+ const networkHasEnsSupport = getNetworkEnsSupport(network)
+ if (!networkHasEnsSupport) return
+
+ const recipient = document.querySelector('input[name="address"]').value
+ if (recipient.match(ensRE) === null) {
+ return this.setState({
+ loadingEns: false,
+ ensResolution: null,
+ ensFailure: null,
+ })
+ }
+
+ this.setState({
+ loadingEns: true,
+ })
+ this.checkName()
+ },
+ })
+ return h('div', {
+ style: { width: '100%' },
+ }, [
+ h('input.large-input', opts),
+ // The address book functionality.
+ h('datalist#addresses',
+ [
+ // Corresponds to the addresses owned.
+ Object.keys(props.identities).map((key) => {
+ const identity = props.identities[key]
+ return h('option', {
+ value: identity.address,
+ label: identity.name,
+ key: identity.address,
+ })
+ }),
+ // Corresponds to previously sent-to addresses.
+ props.addressBook.map((identity) => {
+ return h('option', {
+ value: identity.address,
+ label: identity.name,
+ key: identity.address,
+ })
+ }),
+ ]),
+ this.ensIcon(),
+ ])
+}
+
+EnsInput.prototype.componentDidMount = function () {
+ const network = this.props.network
+ const networkHasEnsSupport = getNetworkEnsSupport(network)
+ this.setState({ ensResolution: ZERO_ADDRESS })
+
+ if (networkHasEnsSupport) {
+ const provider = global.ethereumProvider
+ this.ens = new ENS({ provider, network })
+ this.checkName = debounce(this.lookupEnsName.bind(this), 200)
+ }
+}
+
+EnsInput.prototype.lookupEnsName = function () {
+ const recipient = document.querySelector('input[name="address"]').value
+ const { ensResolution } = this.state
+
+ log.info(`ENS attempting to resolve name: ${recipient}`)
+ this.ens.lookup(recipient.trim())
+ .then((address) => {
+ if (address === ZERO_ADDRESS) throw new Error('No address has been set for this name.')
+ if (address !== ensResolution) {
+ this.setState({
+ loadingEns: false,
+ ensResolution: address,
+ nickname: recipient.trim(),
+ hoverText: address + '\nClick to Copy',
+ ensFailure: false,
+ })
+ }
+ })
+ .catch((reason) => {
+ log.error(reason)
+ return this.setState({
+ loadingEns: false,
+ ensResolution: ZERO_ADDRESS,
+ ensFailure: true,
+ hoverText: reason.message,
+ })
+ })
+}
+
+EnsInput.prototype.componentDidUpdate = function (prevProps, prevState) {
+ const state = this.state || {}
+ const ensResolution = state.ensResolution
+ // If an address is sent without a nickname, meaning not from ENS or from
+ // the user's own accounts, a default of a one-space string is used.
+ const nickname = state.nickname || ' '
+ if (prevState && ensResolution && this.props.onChange &&
+ ensResolution !== prevState.ensResolution) {
+ this.props.onChange(ensResolution, nickname)
+ }
+}
+
+EnsInput.prototype.ensIcon = function (recipient) {
+ const { hoverText } = this.state || {}
+ return h('span', {
+ title: hoverText,
+ style: {
+ position: 'absolute',
+ padding: '9px',
+ transform: 'translatex(-40px)',
+ },
+ }, this.ensIconContents(recipient))
+}
+
+EnsInput.prototype.ensIconContents = function (recipient) {
+ const { loadingEns, ensFailure, ensResolution } = this.state || { ensResolution: ZERO_ADDRESS}
+
+ if (loadingEns) {
+ return h('img', {
+ src: 'images/loading.svg',
+ style: {
+ width: '30px',
+ height: '30px',
+ transform: 'translateY(-6px)',
+ },
+ })
+ }
+
+ if (ensFailure) {
+ return h('i.fa.fa-warning.fa-lg.warning')
+ }
+
+ if (ensResolution && (ensResolution !== ZERO_ADDRESS)) {
+ return h('i.fa.fa-check-circle.fa-lg.cursor-pointer', {
+ style: { color: 'green' },
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ copyToClipboard(ensResolution)
+ },
+ })
+ }
+}
+
+function getNetworkEnsSupport (network) {
+ return Boolean(networkMap[network])
+}
diff --git a/old-ui/app/components/eth-balance.js b/old-ui/app/components/eth-balance.js
new file mode 100644
index 000000000..4f538fd31
--- /dev/null
+++ b/old-ui/app/components/eth-balance.js
@@ -0,0 +1,89 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const formatBalance = require('../util').formatBalance
+const generateBalanceObject = require('../util').generateBalanceObject
+const Tooltip = require('./tooltip.js')
+const FiatValue = require('./fiat-value.js')
+
+module.exports = EthBalanceComponent
+
+inherits(EthBalanceComponent, Component)
+function EthBalanceComponent () {
+ Component.call(this)
+}
+
+EthBalanceComponent.prototype.render = function () {
+ var props = this.props
+ let { value } = props
+ const { style, width } = props
+ var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
+ value = value ? formatBalance(value, 6, needsParse) : '...'
+
+ return (
+
+ h('.ether-balance.ether-balance-amount', {
+ style,
+ }, [
+ h('div', {
+ style: {
+ display: 'inline',
+ width,
+ },
+ }, this.renderBalance(value)),
+ ])
+
+ )
+}
+EthBalanceComponent.prototype.renderBalance = function (value) {
+ var props = this.props
+ const { conversionRate, shorten, incoming, currentCurrency } = props
+ if (value === 'None') return value
+ if (value === '...') return value
+ var balanceObj = generateBalanceObject(value, shorten ? 1 : 3)
+ var balance
+ var splitBalance = value.split(' ')
+ var ethNumber = splitBalance[0]
+ var ethSuffix = splitBalance[1]
+ const showFiat = 'showFiat' in props ? props.showFiat : true
+
+ if (shorten) {
+ balance = balanceObj.shortBalance
+ } else {
+ balance = balanceObj.balance
+ }
+
+ var label = balanceObj.label
+
+ return (
+ h(Tooltip, {
+ position: 'bottom',
+ title: `${ethNumber} ${ethSuffix}`,
+ }, h('div.flex-column', [
+ h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('div', {
+ style: {
+ width: '100%',
+ textAlign: 'right',
+ },
+ }, incoming ? `+${balance}` : balance),
+ h('div', {
+ style: {
+ color: ' #AEAEAE',
+ fontSize: '12px',
+ marginLeft: '5px',
+ },
+ }, label),
+ ]),
+
+ showFiat ? h(FiatValue, { value: props.value, conversionRate, currentCurrency }) : null,
+ ]))
+ )
+}
diff --git a/old-ui/app/components/fiat-value.js b/old-ui/app/components/fiat-value.js
new file mode 100644
index 000000000..d69f41d11
--- /dev/null
+++ b/old-ui/app/components/fiat-value.js
@@ -0,0 +1,64 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const formatBalance = require('../util').formatBalance
+
+module.exports = FiatValue
+
+inherits(FiatValue, Component)
+function FiatValue () {
+ Component.call(this)
+}
+
+FiatValue.prototype.render = function () {
+ const props = this.props
+ const { conversionRate, currentCurrency } = props
+ const renderedCurrency = currentCurrency || ''
+
+ const value = formatBalance(props.value, 6)
+
+ if (value === 'None') return value
+ var fiatDisplayNumber, fiatTooltipNumber
+ var splitBalance = value.split(' ')
+
+ if (conversionRate !== 0) {
+ fiatTooltipNumber = Number(splitBalance[0]) * conversionRate
+ fiatDisplayNumber = fiatTooltipNumber.toFixed(2)
+ } else {
+ fiatDisplayNumber = 'N/A'
+ fiatTooltipNumber = 'Unknown'
+ }
+
+ return fiatDisplay(fiatDisplayNumber, renderedCurrency.toUpperCase())
+}
+
+function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
+ if (fiatDisplayNumber !== 'N/A') {
+ return h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('div', {
+ style: {
+ width: '100%',
+ textAlign: 'right',
+ fontSize: '12px',
+ color: '#333333',
+ },
+ }, fiatDisplayNumber),
+ h('div', {
+ style: {
+ color: '#AEAEAE',
+ marginLeft: '5px',
+ fontSize: '12px',
+ },
+ }, fiatSuffix),
+ ])
+ } else {
+ return h('div')
+ }
+}
diff --git a/old-ui/app/components/hex-as-decimal-input.js b/old-ui/app/components/hex-as-decimal-input.js
new file mode 100644
index 000000000..4a71e9585
--- /dev/null
+++ b/old-ui/app/components/hex-as-decimal-input.js
@@ -0,0 +1,154 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const extend = require('xtend')
+
+module.exports = HexAsDecimalInput
+
+inherits(HexAsDecimalInput, Component)
+function HexAsDecimalInput () {
+ this.state = { invalid: null }
+ Component.call(this)
+}
+
+/* Hex as Decimal Input
+ *
+ * A component for allowing easy, decimal editing
+ * of a passed in hex string value.
+ *
+ * On change, calls back its `onChange` function parameter
+ * and passes it an updated hex string.
+ */
+
+HexAsDecimalInput.prototype.render = function () {
+ const props = this.props
+ const state = this.state
+
+ const { value, onChange, min, max } = props
+
+ const toEth = props.toEth
+ const suffix = props.suffix
+ const decimalValue = decimalize(value, toEth)
+ const style = props.style
+
+ return (
+ h('.flex-column', [
+ h('.flex-row', {
+ style: {
+ alignItems: 'flex-end',
+ lineHeight: '13px',
+ fontFamily: 'Montserrat Light',
+ textRendering: 'geometricPrecision',
+ },
+ }, [
+ h('input.hex-input', {
+ type: 'number',
+ required: true,
+ min: min,
+ max: max,
+ style: extend({
+ display: 'block',
+ textAlign: 'right',
+ backgroundColor: 'transparent',
+ border: '1px solid #bdbdbd',
+
+ }, style),
+ value: parseInt(decimalValue),
+ onBlur: (event) => {
+ this.updateValidity(event)
+ },
+ onChange: (event) => {
+ this.updateValidity(event)
+ const hexString = (event.target.value === '') ? '' : hexify(event.target.value)
+ onChange(hexString)
+ },
+ onInvalid: (event) => {
+ const msg = this.constructWarning()
+ if (msg === state.invalid) {
+ return
+ }
+ this.setState({ invalid: msg })
+ event.preventDefault()
+ return false
+ },
+ }),
+ h('div', {
+ style: {
+ color: ' #AEAEAE',
+ fontSize: '12px',
+ marginLeft: '5px',
+ marginRight: '6px',
+ width: '20px',
+ },
+ }, suffix),
+ ]),
+
+ state.invalid ? h('span.error', {
+ style: {
+ position: 'absolute',
+ right: '0px',
+ textAlign: 'right',
+ transform: 'translateY(26px)',
+ padding: '3px',
+ background: 'rgba(255,255,255,0.85)',
+ zIndex: '1',
+ textTransform: 'capitalize',
+ border: '2px solid #E20202',
+ },
+ }, state.invalid) : null,
+ ])
+ )
+}
+
+HexAsDecimalInput.prototype.setValid = function (message) {
+ this.setState({ invalid: null })
+}
+
+HexAsDecimalInput.prototype.updateValidity = function (event) {
+ const target = event.target
+ const value = this.props.value
+ const newValue = target.value
+
+ if (value === newValue) {
+ return
+ }
+
+ const valid = target.checkValidity()
+ if (valid) {
+ this.setState({ invalid: null })
+ }
+}
+
+HexAsDecimalInput.prototype.constructWarning = function () {
+ const { name, min, max } = this.props
+ let message = name ? name + ' ' : ''
+
+ if (min && max) {
+ message += `must be greater than or equal to ${min} and less than or equal to ${max}.`
+ } else if (min) {
+ message += `must be greater than or equal to ${min}.`
+ } else if (max) {
+ message += `must be less than or equal to ${max}.`
+ } else {
+ message += 'Invalid input.'
+ }
+
+ return message
+}
+
+function hexify (decimalString) {
+ const hexBN = new BN(parseInt(decimalString), 10)
+ return '0x' + hexBN.toString('hex')
+}
+
+function decimalize (input, toEth) {
+ if (input === '') {
+ return ''
+ } else {
+ const strippedInput = ethUtil.stripHexPrefix(input)
+ const inputBN = new BN(strippedInput, 'hex')
+ return inputBN.toString(10)
+ }
+}
diff --git a/old-ui/app/components/identicon.js b/old-ui/app/components/identicon.js
new file mode 100644
index 000000000..bb476ca7b
--- /dev/null
+++ b/old-ui/app/components/identicon.js
@@ -0,0 +1,74 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const isNode = require('detect-node')
+const findDOMNode = require('react-dom').findDOMNode
+const jazzicon = require('jazzicon')
+const iconFactoryGen = require('../../lib/icon-factory')
+const iconFactory = iconFactoryGen(jazzicon)
+
+module.exports = IdenticonComponent
+
+inherits(IdenticonComponent, Component)
+function IdenticonComponent () {
+ Component.call(this)
+
+ this.defaultDiameter = 46
+}
+
+IdenticonComponent.prototype.render = function () {
+ var props = this.props
+ var diameter = props.diameter || this.defaultDiameter
+ return (
+ h('div', {
+ key: 'identicon-' + this.props.address,
+ style: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: diameter,
+ width: diameter,
+ borderRadius: diameter / 2,
+ overflow: 'hidden',
+ },
+ })
+ )
+}
+
+IdenticonComponent.prototype.componentDidMount = function () {
+ var props = this.props
+ const { address } = props
+
+ if (!address) return
+
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
+
+ var diameter = props.diameter || this.defaultDiameter
+ if (!isNode) {
+ var img = iconFactory.iconForAddress(address, diameter)
+ container.appendChild(img)
+ }
+}
+
+IdenticonComponent.prototype.componentDidUpdate = function () {
+ var props = this.props
+ const { address } = props
+
+ if (!address) return
+
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
+
+ var children = container.children
+ for (var i = 0; i < children.length; i++) {
+ container.removeChild(children[i])
+ }
+
+ var diameter = props.diameter || this.defaultDiameter
+ if (!isNode) {
+ var img = iconFactory.iconForAddress(address, diameter)
+ container.appendChild(img)
+ }
+}
+
diff --git a/old-ui/app/components/loading.js b/old-ui/app/components/loading.js
new file mode 100644
index 000000000..b8e2eb599
--- /dev/null
+++ b/old-ui/app/components/loading.js
@@ -0,0 +1,55 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+
+
+inherits(LoadingIndicator, Component)
+module.exports = LoadingIndicator
+
+function LoadingIndicator () {
+ Component.call(this)
+}
+
+LoadingIndicator.prototype.render = function () {
+ const { isLoading, loadingMessage, canBypass, bypass } = this.props
+
+ return (
+ isLoading ? h('.full-flex-height', {
+ style: {
+ left: '0px',
+ zIndex: 10,
+ position: 'absolute',
+ flexDirection: 'column',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+ width: '100%',
+ background: 'rgba(255, 255, 255, 0.8)',
+ },
+ }, [
+ canBypass ? h( 'i.fa.fa-close.cursor-pointer.close-loading', {
+ style: {
+ position: 'absolute',
+ top: '1px',
+ right: '15px',
+ color: '#AEAEAE',
+ },
+ onClick: bypass,
+ }) : null,
+
+ h('img', {
+ src: 'images/loading.svg',
+ }),
+
+ h('br'),
+
+ showMessageIfAny(loadingMessage),
+ ]) : null
+ )
+}
+
+function showMessageIfAny (loadingMessage) {
+ if (!loadingMessage) return null
+ return h('span', loadingMessage)
+}
diff --git a/old-ui/app/components/mascot.js b/old-ui/app/components/mascot.js
new file mode 100644
index 000000000..973ec2cad
--- /dev/null
+++ b/old-ui/app/components/mascot.js
@@ -0,0 +1,59 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const metamaskLogo = require('metamask-logo')
+const debounce = require('debounce')
+
+module.exports = Mascot
+
+inherits(Mascot, Component)
+function Mascot () {
+ Component.call(this)
+ this.logo = metamaskLogo({
+ followMouse: true,
+ pxNotRatio: true,
+ width: 200,
+ height: 200,
+ })
+
+ this.refollowMouse = debounce(this.logo.setFollowMouse.bind(this.logo, true), 1000)
+ this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false)
+}
+
+Mascot.prototype.render = function () {
+ // this is a bit hacky
+ // the event emitter is on `this.props`
+ // and we dont get that until render
+ this.handleAnimationEvents()
+
+ return h('#metamask-mascot-container', {
+ style: { zIndex: 0 },
+ })
+}
+
+Mascot.prototype.componentDidMount = function () {
+ var targetDivId = 'metamask-mascot-container'
+ var container = document.getElementById(targetDivId)
+ container.appendChild(this.logo.container)
+}
+
+Mascot.prototype.componentWillUnmount = function () {
+ this.animations = this.props.animationEventEmitter
+ this.animations.removeAllListeners()
+ this.logo.container.remove()
+ this.logo.stopAnimation()
+}
+
+Mascot.prototype.handleAnimationEvents = function () {
+ // only setup listeners once
+ if (this.animations) return
+ this.animations = this.props.animationEventEmitter
+ this.animations.on('point', this.lookAt.bind(this))
+ this.animations.on('setFollowMouse', this.logo.setFollowMouse.bind(this.logo))
+}
+
+Mascot.prototype.lookAt = function (target) {
+ this.unfollowMouse()
+ this.logo.lookAt(target)
+ this.refollowMouse()
+}
diff --git a/old-ui/app/components/menu-droppo.js b/old-ui/app/components/menu-droppo.js
new file mode 100644
index 000000000..e6276f3b1
--- /dev/null
+++ b/old-ui/app/components/menu-droppo.js
@@ -0,0 +1,132 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const findDOMNode = require('react-dom').findDOMNode
+const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
+
+module.exports = MenuDroppoComponent
+
+
+inherits(MenuDroppoComponent, Component)
+function MenuDroppoComponent () {
+ Component.call(this)
+}
+
+MenuDroppoComponent.prototype.render = function () {
+ const speed = this.props.speed || '300ms'
+ const useCssTransition = this.props.useCssTransition
+ const zIndex = ('zIndex' in this.props) ? this.props.zIndex : 0
+
+ this.manageListeners()
+
+ const style = this.props.style || {}
+ if (!('position' in style)) {
+ style.position = 'fixed'
+ }
+ style.zIndex = zIndex
+
+ return (
+ h('.menu-droppo-container', {
+ style,
+ }, [
+ h('style', `
+ .menu-droppo-enter {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(-200%);
+ }
+
+ .menu-droppo-enter.menu-droppo-enter-active {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(0%);
+ }
+
+ .menu-droppo-leave {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(0%);
+ }
+
+ .menu-droppo-leave.menu-droppo-leave-active {
+ transition: transform ${speed} ease-in-out;
+ transform: translateY(-200%);
+ }
+ `),
+
+ useCssTransition
+ ? h(ReactCSSTransitionGroup, {
+ className: 'css-transition-group',
+ transitionName: 'menu-droppo',
+ transitionEnterTimeout: parseInt(speed),
+ transitionLeaveTimeout: parseInt(speed),
+ }, this.renderPrimary())
+ : this.renderPrimary(),
+ ])
+ )
+}
+
+MenuDroppoComponent.prototype.renderPrimary = function () {
+ const isOpen = this.props.isOpen
+ if (!isOpen) {
+ return null
+ }
+
+ const innerStyle = this.props.innerStyle || {}
+
+ return (
+ h('.menu-droppo', {
+ key: 'menu-droppo-drawer',
+ style: innerStyle,
+ },
+ [ this.props.children ])
+ )
+}
+
+MenuDroppoComponent.prototype.manageListeners = function () {
+ const isOpen = this.props.isOpen
+ const onClickOutside = this.props.onClickOutside
+
+ if (isOpen) {
+ this.outsideClickHandler = onClickOutside
+ } else if (isOpen) {
+ this.outsideClickHandler = null
+ }
+}
+
+MenuDroppoComponent.prototype.componentDidMount = function () {
+ if (this && document.body) {
+ this.globalClickHandler = this.globalClickOccurred.bind(this)
+ document.body.addEventListener('click', this.globalClickHandler)
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
+ this.container = container
+ }
+}
+
+MenuDroppoComponent.prototype.componentWillUnmount = function () {
+ if (this && document.body) {
+ document.body.removeEventListener('click', this.globalClickHandler)
+ }
+}
+
+MenuDroppoComponent.prototype.globalClickOccurred = function (event) {
+ const target = event.target
+ // eslint-disable-next-line react/no-find-dom-node
+ const container = findDOMNode(this)
+
+ if (target !== container &&
+ !isDescendant(this.container, event.target) &&
+ this.outsideClickHandler) {
+ this.outsideClickHandler(event)
+ }
+}
+
+function isDescendant (parent, child) {
+ var node = child.parentNode
+ while (node !== null) {
+ if (node === parent) {
+ return true
+ }
+ node = node.parentNode
+ }
+
+ return false
+}
diff --git a/old-ui/app/components/mini-account-panel.js b/old-ui/app/components/mini-account-panel.js
new file mode 100644
index 000000000..c09cf5b7a
--- /dev/null
+++ b/old-ui/app/components/mini-account-panel.js
@@ -0,0 +1,74 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const Identicon = require('./identicon')
+
+module.exports = AccountPanel
+
+
+inherits(AccountPanel, Component)
+function AccountPanel () {
+ Component.call(this)
+}
+
+AccountPanel.prototype.render = function () {
+ var props = this.props
+ var picOrder = props.picOrder || 'left'
+ const { imageSeed } = props
+
+ return (
+
+ h('.identity-panel.flex-row.flex-left', {
+ style: {
+ cursor: props.onClick ? 'pointer' : undefined,
+ },
+ onClick: props.onClick,
+ }, [
+
+ this.genIcon(imageSeed, picOrder),
+
+ h('div.flex-column.flex-justify-center', {
+ style: {
+ lineHeight: '15px',
+ order: 2,
+ display: 'flex',
+ alignItems: picOrder === 'left' ? 'flex-begin' : 'flex-end',
+ },
+ }, this.props.children),
+ ])
+ )
+}
+
+AccountPanel.prototype.genIcon = function (seed, picOrder) {
+ const props = this.props
+
+ // When there is no seed value, this is a contract creation.
+ // We then show the contract icon.
+ if (!seed) {
+ return h('.identicon-wrapper.flex-column.select-none', {
+ style: {
+ order: picOrder === 'left' ? 1 : 3,
+ },
+ }, [
+ h('i.fa.fa-file-text-o.fa-lg', {
+ style: {
+ fontSize: '42px',
+ transform: 'translate(0px, -16px)',
+ },
+ }),
+ ])
+ }
+
+ // If there was a seed, we return an identicon for that address.
+ return h('.identicon-wrapper.flex-column.select-none', {
+ style: {
+ order: picOrder === 'left' ? 1 : 3,
+ },
+ }, [
+ h(Identicon, {
+ address: seed,
+ imageify: props.imageifyIdenticons,
+ }),
+ ])
+}
+
diff --git a/old-ui/app/components/network.js b/old-ui/app/components/network.js
new file mode 100644
index 000000000..0dbe37cdd
--- /dev/null
+++ b/old-ui/app/components/network.js
@@ -0,0 +1,129 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = Network
+
+inherits(Network, Component)
+
+function Network () {
+ Component.call(this)
+}
+
+Network.prototype.render = function () {
+ const props = this.props
+ const networkNumber = props.network
+ let providerName
+ try {
+ providerName = props.provider.type
+ } catch (e) {
+ providerName = null
+ }
+ let iconName, hoverText
+
+ if (networkNumber === 'loading') {
+ return h('span.pointer', {
+ style: {
+ display: 'flex',
+ alignItems: 'center',
+ flexDirection: 'row',
+ },
+ onClick: (event) => this.props.onClick(event),
+ }, [
+ h('img', {
+ title: 'Attempting to connect to blockchain.',
+ style: {
+ width: '27px',
+ },
+ src: 'images/loading.svg',
+ }),
+ h('i.fa.fa-caret-down'),
+ ])
+ } else if (providerName === 'mainnet') {
+ hoverText = 'Main Ethereum Network'
+ iconName = 'ethereum-network'
+ } else if (providerName === 'ropsten') {
+ hoverText = 'Ropsten Test Network'
+ iconName = 'ropsten-test-network'
+ } else if (parseInt(networkNumber) === 3) {
+ hoverText = 'Ropsten Test Network'
+ iconName = 'ropsten-test-network'
+ } else if (providerName === 'kovan') {
+ hoverText = 'Kovan Test Network'
+ iconName = 'kovan-test-network'
+ } else if (providerName === 'rinkeby') {
+ hoverText = 'Rinkeby Test Network'
+ iconName = 'rinkeby-test-network'
+ } else {
+ hoverText = 'Unknown Private Network'
+ iconName = 'unknown-private-network'
+ }
+
+ return (
+ h('#network_component.pointer', {
+ title: hoverText,
+ onClick: (event) => this.props.onClick(event),
+ }, [
+ (function () {
+ switch (iconName) {
+ case 'ethereum-network':
+ return h('.network-indicator', [
+ h('.menu-icon.diamond'),
+ h('.network-name', {
+ style: {
+ color: '#039396',
+ }},
+ 'Main Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
+ ])
+ case 'ropsten-test-network':
+ return h('.network-indicator', [
+ h('.menu-icon.red-dot'),
+ h('.network-name', {
+ style: {
+ color: '#ff6666',
+ }},
+ 'Ropsten Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
+ ])
+ case 'kovan-test-network':
+ return h('.network-indicator', [
+ h('.menu-icon.hollow-diamond'),
+ h('.network-name', {
+ style: {
+ color: '#690496',
+ }},
+ 'Kovan Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
+ ])
+ case 'rinkeby-test-network':
+ return h('.network-indicator', [
+ h('.menu-icon.golden-square'),
+ h('.network-name', {
+ style: {
+ color: '#e7a218',
+ }},
+ 'Rinkeby Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
+ ])
+ default:
+ return h('.network-indicator', [
+ h('i.fa.fa-question-circle.fa-lg', {
+ style: {
+ margin: '10px',
+ color: 'rgb(125, 128, 130)',
+ },
+ }),
+
+ h('.network-name', {
+ style: {
+ color: '#AEAEAE',
+ }},
+ 'Private Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
+ ])
+ }
+ })(),
+ ])
+ )
+}
diff --git a/old-ui/app/components/notice.js b/old-ui/app/components/notice.js
new file mode 100644
index 000000000..09d461c7b
--- /dev/null
+++ b/old-ui/app/components/notice.js
@@ -0,0 +1,132 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const ReactMarkdown = require('react-markdown')
+const linker = require('extension-link-enabler')
+const findDOMNode = require('react-dom').findDOMNode
+
+module.exports = Notice
+
+inherits(Notice, Component)
+function Notice () {
+ Component.call(this)
+}
+
+Notice.prototype.render = function () {
+ const { notice, onConfirm } = this.props
+ const { title, date, body } = notice
+ const state = this.state || { disclaimerDisabled: true }
+ const disabled = state.disclaimerDisabled
+
+ return (
+ h('.flex-column.flex-center.flex-grow', {
+ style: {
+ width: '100%',
+ },
+ }, [
+ h('h3.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ title,
+ ]),
+
+ h('h5.flex-center.text-transform-uppercase.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ date,
+ ]),
+
+ h('style', `
+
+ .markdown {
+ overflow-x: hidden;
+ }
+
+ .markdown h1, .markdown h2, .markdown h3 {
+ margin: 10px 0;
+ font-weight: bold;
+ }
+
+ .markdown strong {
+ font-weight: bold;
+ }
+ .markdown em {
+ font-style: italic;
+ }
+
+ .markdown p {
+ margin: 10px 0;
+ }
+
+ .markdown a {
+ color: #df6b0e;
+ }
+
+ `),
+
+ h('div.markdown', {
+ onScroll: (e) => {
+ var object = e.currentTarget
+ if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
+ this.setState({disclaimerDisabled: false})
+ }
+ },
+ style: {
+ background: 'rgb(235, 235, 235)',
+ height: '310px',
+ padding: '6px',
+ width: '90%',
+ overflowY: 'scroll',
+ scroll: 'auto',
+ },
+ }, [
+ h(ReactMarkdown, {
+ className: 'notice-box',
+ source: body,
+ skipHtml: true,
+ }),
+ ]),
+
+ h('button', {
+ disabled,
+ onClick: () => {
+ this.setState({disclaimerDisabled: true})
+ onConfirm()
+ },
+ style: {
+ marginTop: '18px',
+ },
+ }, 'Accept'),
+ ])
+ )
+}
+
+Notice.prototype.componentDidMount = function () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+ if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
+ this.setState({disclaimerDisabled: false})
+ }
+}
+
+Notice.prototype.componentWillUnmount = function () {
+ // eslint-disable-next-line react/no-find-dom-node
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+}
diff --git a/old-ui/app/components/pending-msg-details.js b/old-ui/app/components/pending-msg-details.js
new file mode 100644
index 000000000..718a22de0
--- /dev/null
+++ b/old-ui/app/components/pending-msg-details.js
@@ -0,0 +1,50 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const AccountPanel = require('./account-panel')
+
+module.exports = PendingMsgDetails
+
+inherits(PendingMsgDetails, Component)
+function PendingMsgDetails () {
+ Component.call(this)
+}
+
+PendingMsgDetails.prototype.render = function () {
+ var state = this.props
+ var msgData = state.txData
+
+ var msgParams = msgData.msgParams || {}
+ var address = msgParams.from || state.selectedAddress
+ var identity = state.identities[address] || { address: address }
+ var account = state.accounts[address] || { address: address }
+
+ return (
+ h('div', {
+ key: msgData.id,
+ style: {
+ margin: '10px 20px',
+ },
+ }, [
+
+ // account that will sign
+ h(AccountPanel, {
+ showFullAddress: true,
+ identity: identity,
+ account: account,
+ imageifyIdenticons: state.imageifyIdenticons,
+ }),
+
+ // message data
+ h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
+ h('.flex-column.flex-space-between', [
+ h('label.font-small', 'MESSAGE'),
+ h('span.font-small', msgParams.data),
+ ]),
+ ]),
+
+ ])
+ )
+}
+
diff --git a/old-ui/app/components/pending-msg.js b/old-ui/app/components/pending-msg.js
new file mode 100644
index 000000000..834719c53
--- /dev/null
+++ b/old-ui/app/components/pending-msg.js
@@ -0,0 +1,70 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const PendingTxDetails = require('./pending-msg-details')
+
+module.exports = PendingMsg
+
+inherits(PendingMsg, Component)
+function PendingMsg () {
+ Component.call(this)
+}
+
+PendingMsg.prototype.render = function () {
+ var state = this.props
+ var msgData = state.txData
+
+ return (
+
+ h('div', {
+ key: msgData.id,
+ style: {
+ maxWidth: '350px',
+ },
+ }, [
+
+ // header
+ h('h3', {
+ style: {
+ fontWeight: 'bold',
+ textAlign: 'center',
+ },
+ }, 'Sign Message'),
+
+ h('.error', {
+ style: {
+ margin: '10px',
+ },
+ }, [
+ `Signing this message can have
+ dangerous side effects. Only sign messages from
+ sites you fully trust with your entire account.
+ This dangerous method will be removed in a future version. `,
+ h('a', {
+ href: 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527',
+ style: { color: 'rgb(247, 134, 28)' },
+ onClick: (event) => {
+ event.preventDefault()
+ const url = 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527'
+ global.platform.openWindow({ url })
+ },
+ }, 'Read more here.'),
+ ]),
+
+ // message details
+ h(PendingTxDetails, state),
+
+ // sign + cancel
+ h('.flex-row.flex-space-around', [
+ h('button', {
+ onClick: state.cancelMessage,
+ }, 'Cancel'),
+ h('button', {
+ onClick: state.signMessage,
+ }, 'Sign'),
+ ]),
+ ])
+
+ )
+}
+
diff --git a/old-ui/app/components/pending-personal-msg-details.js b/old-ui/app/components/pending-personal-msg-details.js
new file mode 100644
index 000000000..1050513f2
--- /dev/null
+++ b/old-ui/app/components/pending-personal-msg-details.js
@@ -0,0 +1,60 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const AccountPanel = require('./account-panel')
+const BinaryRenderer = require('./binary-renderer')
+
+module.exports = PendingMsgDetails
+
+inherits(PendingMsgDetails, Component)
+function PendingMsgDetails () {
+ Component.call(this)
+}
+
+PendingMsgDetails.prototype.render = function () {
+ var state = this.props
+ var msgData = state.txData
+
+ var msgParams = msgData.msgParams || {}
+ var address = msgParams.from || state.selectedAddress
+ var identity = state.identities[address] || { address: address }
+ var account = state.accounts[address] || { address: address }
+
+ var { data } = msgParams
+
+ return (
+ h('div', {
+ key: msgData.id,
+ style: {
+ margin: '10px 20px',
+ },
+ }, [
+
+ // account that will sign
+ h(AccountPanel, {
+ showFullAddress: true,
+ identity: identity,
+ account: account,
+ imageifyIdenticons: state.imageifyIdenticons,
+ }),
+
+ // message data
+ h('div', {
+ style: {
+ height: '260px',
+ },
+ }, [
+ h('label.font-small', { style: { display: 'block' } }, 'MESSAGE'),
+ h(BinaryRenderer, {
+ value: data,
+ style: {
+ height: '215px',
+ },
+ }),
+ ]),
+
+ ])
+ )
+}
+
diff --git a/ui/app/components/pending-personal-msg.js b/old-ui/app/components/pending-personal-msg.js
index 4542adb28..4542adb28 100644
--- a/ui/app/components/pending-personal-msg.js
+++ b/old-ui/app/components/pending-personal-msg.js
diff --git a/ui/app/components/pending-tx.js b/old-ui/app/components/pending-tx.js
index 98193ea6f..720df2243 100644
--- a/ui/app/components/pending-tx.js
+++ b/old-ui/app/components/pending-tx.js
@@ -1,7 +1,7 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
-const actions = require('../actions')
+const actions = require('../../../ui/app/actions')
const clone = require('clone')
const ethUtil = require('ethereumjs-util')
diff --git a/old-ui/app/components/pending-typed-msg-details.js b/old-ui/app/components/pending-typed-msg-details.js
new file mode 100644
index 000000000..b5fd29f71
--- /dev/null
+++ b/old-ui/app/components/pending-typed-msg-details.js
@@ -0,0 +1,59 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const AccountPanel = require('./account-panel')
+const TypedMessageRenderer = require('./typed-message-renderer')
+
+module.exports = PendingMsgDetails
+
+inherits(PendingMsgDetails, Component)
+function PendingMsgDetails () {
+ Component.call(this)
+}
+
+PendingMsgDetails.prototype.render = function () {
+ var state = this.props
+ var msgData = state.txData
+
+ var msgParams = msgData.msgParams || {}
+ var address = msgParams.from || state.selectedAddress
+ var identity = state.identities[address] || { address: address }
+ var account = state.accounts[address] || { address: address }
+
+ var { data } = msgParams
+
+ return (
+ h('div', {
+ key: msgData.id,
+ style: {
+ margin: '10px 20px',
+ },
+ }, [
+
+ // account that will sign
+ h(AccountPanel, {
+ showFullAddress: true,
+ identity: identity,
+ account: account,
+ imageifyIdenticons: state.imageifyIdenticons,
+ }),
+
+ // message data
+ h('div', {
+ style: {
+ height: '260px',
+ },
+ }, [
+ h('label.font-small', { style: { display: 'block' } }, 'YOU ARE SIGNING'),
+ h(TypedMessageRenderer, {
+ value: data,
+ style: {
+ height: '215px',
+ },
+ }),
+ ]),
+
+ ])
+ )
+}
diff --git a/old-ui/app/components/pending-typed-msg.js b/old-ui/app/components/pending-typed-msg.js
new file mode 100644
index 000000000..f8926d0a3
--- /dev/null
+++ b/old-ui/app/components/pending-typed-msg.js
@@ -0,0 +1,46 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const PendingTxDetails = require('./pending-typed-msg-details')
+
+module.exports = PendingMsg
+
+inherits(PendingMsg, Component)
+function PendingMsg () {
+ Component.call(this)
+}
+
+PendingMsg.prototype.render = function () {
+ var state = this.props
+ var msgData = state.txData
+
+ return (
+
+ h('div', {
+ key: msgData.id,
+ }, [
+
+ // header
+ h('h3', {
+ style: {
+ fontWeight: 'bold',
+ textAlign: 'center',
+ },
+ }, 'Sign Message'),
+
+ // message details
+ h(PendingTxDetails, state),
+
+ // sign + cancel
+ h('.flex-row.flex-space-around', [
+ h('button', {
+ onClick: state.cancelTypedMessage,
+ }, 'Cancel'),
+ h('button', {
+ onClick: state.signTypedMessage,
+ }, 'Sign'),
+ ]),
+ ])
+
+ )
+}
diff --git a/old-ui/app/components/qr-code.js b/old-ui/app/components/qr-code.js
new file mode 100644
index 000000000..fa38dcd92
--- /dev/null
+++ b/old-ui/app/components/qr-code.js
@@ -0,0 +1,80 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const qrCode = require('qrcode-npm').qrcode
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const isHexPrefixed = require('ethereumjs-util').isHexPrefixed
+const CopyButton = require('./copyButton')
+
+module.exports = connect(mapStateToProps)(QrCodeView)
+
+function mapStateToProps (state) {
+ return {
+ Qr: state.appState.Qr,
+ buyView: state.appState.buyView,
+ warning: state.appState.warning,
+ }
+}
+
+inherits(QrCodeView, Component)
+
+function QrCodeView () {
+ Component.call(this)
+}
+
+QrCodeView.prototype.render = function () {
+ const props = this.props
+ const Qr = props.Qr
+ console.log(`QrCodeView Qr`, Qr);
+ const address = `${isHexPrefixed(Qr.data) ? 'ethereum:' : ''}${Qr.data}`
+ const qrImage = qrCode(4, 'M')
+ qrImage.addData(address)
+ qrImage.make()
+ return h('.main-container.flex-column', {
+ key: 'qr',
+ style: {
+ justifyContent: 'center',
+ paddingBottom: '45px',
+ paddingLeft: '45px',
+ paddingRight: '45px',
+ alignItems: 'center',
+ },
+ }, [
+ Array.isArray(Qr.message) ? h('.message-container', this.renderMultiMessage()) : h('.qr-header', Qr.message),
+
+ this.props.warning ? this.props.warning && h('span.error.flex-center', {
+ style: {
+ textAlign: 'center',
+ width: '229px',
+ height: '82px',
+ },
+ },
+ this.props.warning) : null,
+
+ h('#qr-container.flex-column', {
+ style: {
+ marginTop: '25px',
+ marginBottom: '15px',
+ },
+ dangerouslySetInnerHTML: {
+ __html: qrImage.createTableTag(4),
+ },
+ }),
+ h('.flex-row', [
+ h('h3.ellip-address', {
+ style: {
+ width: '247px',
+ },
+ }, Qr.data),
+ h(CopyButton, {
+ value: Qr.data,
+ }),
+ ]),
+ ])
+}
+
+QrCodeView.prototype.renderMultiMessage = function () {
+ var Qr = this.props.Qr
+ var multiMessage = Qr.message.map((message) => h('.qr-message', message))
+ return multiMessage
+}
diff --git a/old-ui/app/components/range-slider.js b/old-ui/app/components/range-slider.js
new file mode 100644
index 000000000..823f5eb01
--- /dev/null
+++ b/old-ui/app/components/range-slider.js
@@ -0,0 +1,58 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = RangeSlider
+
+inherits(RangeSlider, Component)
+function RangeSlider () {
+ Component.call(this)
+}
+
+RangeSlider.prototype.render = function () {
+ const state = this.state || {}
+ const props = this.props
+ const onInput = props.onInput || function () {}
+ const name = props.name
+ const {
+ min = 0,
+ max = 100,
+ increment = 1,
+ defaultValue = 50,
+ mirrorInput = false,
+ } = this.props.options
+ const {container, input, range} = props.style
+
+ return (
+ h('.flex-row', {
+ style: container,
+ }, [
+ h('input', {
+ type: 'range',
+ name: name,
+ min: min,
+ max: max,
+ step: increment,
+ style: range,
+ value: state.value || defaultValue,
+ onChange: mirrorInput ? this.mirrorInputs.bind(this, event) : onInput,
+ }),
+
+ // Mirrored input for range
+ mirrorInput ? h('input.large-input', {
+ type: 'number',
+ name: `${name}Mirror`,
+ min: min,
+ max: max,
+ value: state.value || defaultValue,
+ step: increment,
+ style: input,
+ onChange: this.mirrorInputs.bind(this, event),
+ }) : null,
+ ])
+ )
+}
+
+RangeSlider.prototype.mirrorInputs = function (event) {
+ this.setState({value: event.target.value})
+}
diff --git a/old-ui/app/components/shapeshift-form.js b/old-ui/app/components/shapeshift-form.js
new file mode 100644
index 000000000..a54987c04
--- /dev/null
+++ b/old-ui/app/components/shapeshift-form.js
@@ -0,0 +1,308 @@
+const PersistentForm = require('../../lib/persistent-form')
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../../ui/app/actions')
+const Qr = require('./qr-code')
+const isValidAddress = require('../util').isValidAddress
+module.exports = connect(mapStateToProps)(ShapeshiftForm)
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ isSubLoading: state.appState.isSubLoading,
+ qrRequested: state.appState.qrRequested,
+ }
+}
+
+inherits(ShapeshiftForm, PersistentForm)
+
+function ShapeshiftForm () {
+ PersistentForm.call(this)
+ this.persistentFormParentId = 'shapeshift-buy-form'
+}
+
+ShapeshiftForm.prototype.render = function () {
+ return this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain()
+}
+
+ShapeshiftForm.prototype.renderMain = function () {
+ const marketinfo = this.props.buyView.formView.marketinfo
+ const coinOptions = this.props.buyView.formView.coinOptions
+ var coin = marketinfo.pair.split('_')[0].toUpperCase()
+
+ return h('.flex-column', {
+ style: {
+ position: 'relative',
+ padding: '25px',
+ paddingTop: '5px',
+ width: '90%',
+ minHeight: '215px',
+ alignItems: 'center',
+ overflowY: 'auto',
+ },
+ }, [
+ h('.flex-row', {
+ style: {
+ justifyContent: 'center',
+ alignItems: 'baseline',
+ height: '42px',
+ },
+ }, [
+ h('img', {
+ src: coinOptions[coin].image,
+ width: '25px',
+ height: '25px',
+ style: {
+ marginRight: '5px',
+ },
+ }),
+
+ h('.input-container', {
+ position: 'relative',
+ }, [
+ h('input#fromCoin.buy-inputs.ex-coins', {
+ type: 'text',
+ list: 'coinList',
+ autoFocus: true,
+ dataset: {
+ persistentFormId: 'input-coin',
+ },
+ style: {
+ boxSizing: 'border-box',
+ },
+ onChange: this.handleLiveInput.bind(this),
+ defaultValue: 'BTC',
+ }),
+
+ this.renderCoinList(),
+
+ h('i.fa.fa-pencil-square-o.edit-text', {
+ style: {
+ fontSize: '12px',
+ color: '#F7861C',
+ position: 'absolute',
+ },
+ }),
+ ]),
+
+ h('.icon-control', {
+ style: {
+ position: 'relative',
+ },
+ }, [
+ // Not visible on the screen, can't see it on master.
+
+ // h('i.fa.fa-refresh.fa-4.orange', {
+ // style: {
+ // bottom: '5px',
+ // left: '5px',
+ // color: '#F7861C',
+ // },
+ // onClick: this.updateCoin.bind(this),
+ // }),
+ h('i.fa.fa-chevron-right.fa-4.orange', {
+ style: {
+ position: 'absolute',
+ bottom: '35%',
+ left: '0%',
+ color: '#F7861C',
+ },
+ onClick: this.updateCoin.bind(this),
+ }),
+ ]),
+
+ h('#toCoin.ex-coins', marketinfo.pair.split('_')[1].toUpperCase()),
+
+ h('img', {
+ src: coinOptions[marketinfo.pair.split('_')[1].toUpperCase()].image,
+ width: '25px',
+ height: '25px',
+ style: {
+ marginLeft: '5px',
+ },
+ }),
+ ]),
+
+ h('.flex-column', {
+ style: {
+ marginTop: '1%',
+ alignItems: 'flex-start',
+ },
+ }, [
+ this.props.warning ?
+ this.props.warning &&
+ h('span.error.flex-center', {
+ style: {
+ textAlign: 'center',
+ width: '229px',
+ height: '82px',
+ },
+ }, this.props.warning)
+ : this.renderInfo(),
+
+ this.renderRefundAddressForCoin(coin),
+ ]),
+
+ ])
+}
+
+ShapeshiftForm.prototype.renderRefundAddressForCoin = function (coin) {
+ return h(this.activeToggle('.input-container'), {
+ style: {
+ marginTop: '1%',
+ },
+ }, [
+
+ h('div', `${coin} Address:`),
+
+ h('input#fromCoinAddress.buy-inputs', {
+ type: 'text',
+ placeholder: `Your ${coin} Refund Address`,
+ dataset: {
+ persistentFormId: 'refund-address',
+
+ },
+ style: {
+ boxSizing: 'border-box',
+ width: '227px',
+ height: '30px',
+ padding: ' 5px ',
+ },
+ }),
+
+ h('i.fa.fa-pencil-square-o.edit-text', {
+ style: {
+ fontSize: '12px',
+ color: '#F7861C',
+ position: 'absolute',
+ },
+ }),
+ h('div.flex-row', {
+ style: {
+ justifyContent: 'flex-start',
+ },
+ }, [
+ h('button', {
+ onClick: this.shift.bind(this),
+ style: {
+ marginTop: '1%',
+ },
+ },
+ 'Submit'),
+ ]),
+ ])
+}
+
+ShapeshiftForm.prototype.shift = function () {
+ var props = this.props
+ var withdrawal = this.props.buyView.buyAddress
+ var returnAddress = document.getElementById('fromCoinAddress').value
+ var pair = this.props.buyView.formView.marketinfo.pair
+ var data = {
+ 'withdrawal': withdrawal,
+ 'pair': pair,
+ 'returnAddress': returnAddress,
+ // Public api key
+ 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
+ }
+ var message = [
+ `Deposit Limit: ${props.buyView.formView.marketinfo.limit}`,
+ `Deposit Minimum:${props.buyView.formView.marketinfo.minimum}`,
+ ]
+ if (isValidAddress(withdrawal)) {
+ this.props.dispatch(actions.coinShiftRquest(data, message))
+ }
+}
+
+ShapeshiftForm.prototype.renderCoinList = function () {
+ var list = Object.keys(this.props.buyView.formView.coinOptions).map((item) => {
+ return h('option', {
+ value: item,
+ }, item)
+ })
+
+ return h('datalist#coinList', {
+ onClick: (event) => {
+ event.preventDefault()
+ },
+ }, list)
+}
+
+ShapeshiftForm.prototype.updateCoin = function (event) {
+ event.preventDefault()
+ const props = this.props
+ var coinOptions = this.props.buyView.formView.coinOptions
+ var coin = document.getElementById('fromCoin').value
+
+ if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
+ var message = 'Not a valid coin'
+ return props.dispatch(actions.displayWarning(message))
+ } else {
+ return props.dispatch(actions.pairUpdate(coin))
+ }
+}
+
+ShapeshiftForm.prototype.handleLiveInput = function () {
+ const props = this.props
+ var coinOptions = this.props.buyView.formView.coinOptions
+ var coin = document.getElementById('fromCoin').value
+
+ if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
+ return null
+ } else {
+ return props.dispatch(actions.pairUpdate(coin))
+ }
+}
+
+ShapeshiftForm.prototype.renderInfo = function () {
+ const marketinfo = this.props.buyView.formView.marketinfo
+ const coinOptions = this.props.buyView.formView.coinOptions
+ var coin = marketinfo.pair.split('_')[0].toUpperCase()
+
+ return h('span', {
+ style: {
+ },
+ }, [
+ h('h3.flex-row.text-transform-uppercase', {
+ style: {
+ color: '#868686',
+ paddingTop: '4px',
+ justifyContent: 'space-around',
+ textAlign: 'center',
+ fontSize: '17px',
+ },
+ }, `Market Info for ${marketinfo.pair.replace('_', ' to ').toUpperCase()}:`),
+ h('.marketinfo', ['Status : ', `${coinOptions[coin].status}`]),
+ h('.marketinfo', ['Exchange Rate: ', `${marketinfo.rate}`]),
+ h('.marketinfo', ['Limit: ', `${marketinfo.limit}`]),
+ h('.marketinfo', ['Minimum : ', `${marketinfo.minimum}`]),
+ ])
+}
+
+ShapeshiftForm.prototype.activeToggle = function (elementType) {
+ if (!this.props.buyView.formView.response || this.props.warning) return elementType
+ return `${elementType}.inactive`
+}
+
+ShapeshiftForm.prototype.renderLoading = function () {
+ return h('span', {
+ style: {
+ position: 'absolute',
+ left: '70px',
+ bottom: '194px',
+ background: 'transparent',
+ width: '229px',
+ height: '82px',
+ display: 'flex',
+ justifyContent: 'center',
+ },
+ }, [
+ h('img', {
+ style: {
+ width: '60px',
+ },
+ src: 'images/loading.svg',
+ }),
+ ])
+}
diff --git a/old-ui/app/components/shift-list-item.js b/old-ui/app/components/shift-list-item.js
new file mode 100644
index 000000000..5454a90bc
--- /dev/null
+++ b/old-ui/app/components/shift-list-item.js
@@ -0,0 +1,204 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const vreme = new (require('vreme'))()
+const explorerLink = require('etherscan-link').createExplorerLink
+const actions = require('../../../ui/app/actions')
+const addressSummary = require('../util').addressSummary
+
+const CopyButton = require('./copyButton')
+const EthBalance = require('./eth-balance')
+const Tooltip = require('./tooltip')
+
+
+module.exports = connect(mapStateToProps)(ShiftListItem)
+
+function mapStateToProps (state) {
+ return {
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ }
+}
+
+inherits(ShiftListItem, Component)
+
+function ShiftListItem () {
+ Component.call(this)
+}
+
+ShiftListItem.prototype.render = function () {
+ return (
+ h('.transaction-list-item.flex-row', {
+ style: {
+ paddingTop: '20px',
+ paddingBottom: '20px',
+ justifyContent: 'space-around',
+ alignItems: 'center',
+ },
+ }, [
+ h('div', {
+ style: {
+ width: '0px',
+ position: 'relative',
+ bottom: '19px',
+ },
+ }, [
+ h('img', {
+ src: 'https://info.shapeshift.io/sites/default/files/logo.png',
+ style: {
+ height: '35px',
+ width: '132px',
+ position: 'absolute',
+ clip: 'rect(0px,23px,34px,0px)',
+ },
+ }),
+ ]),
+
+ this.renderInfo(),
+ this.renderUtilComponents(),
+ ])
+ )
+}
+
+function formatDate (date) {
+ return vreme.format(new Date(date), 'March 16 2014 14:30')
+}
+
+ShiftListItem.prototype.renderUtilComponents = function () {
+ var props = this.props
+ const { conversionRate, currentCurrency } = props
+
+ switch (props.response.status) {
+ case 'no_deposits':
+ return h('.flex-row', [
+ h(CopyButton, {
+ value: this.props.depositAddress,
+ }),
+ h(Tooltip, {
+ title: 'QR Code',
+ }, [
+ h('i.fa.fa-qrcode.pointer.pop-hover', {
+ onClick: () => props.dispatch(actions.reshowQrCode(props.depositAddress, props.depositType)),
+ style: {
+ margin: '5px',
+ marginLeft: '23px',
+ marginRight: '12px',
+ fontSize: '20px',
+ color: '#F7861C',
+ },
+ }),
+ ]),
+ ])
+ case 'received':
+ return h('.flex-row')
+
+ case 'complete':
+ return h('.flex-row', [
+ h(CopyButton, {
+ value: this.props.response.transaction,
+ }),
+ h(EthBalance, {
+ value: `${props.response.outgoingCoin}`,
+ conversionRate,
+ currentCurrency,
+ width: '55px',
+ shorten: true,
+ needsParse: false,
+ incoming: true,
+ style: {
+ fontSize: '15px',
+ color: '#01888C',
+ },
+ }),
+ ])
+
+ case 'failed':
+ return ''
+ default:
+ return ''
+ }
+}
+
+ShiftListItem.prototype.renderInfo = function () {
+ var props = this.props
+ switch (props.response.status) {
+ case 'no_deposits':
+ return h('.flex-column', {
+ style: {
+ width: '200px',
+ overflow: 'hidden',
+ },
+ }, [
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, `${props.depositType} to ETH via ShapeShift`),
+ h('div', 'No deposits received'),
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, formatDate(props.time)),
+ ])
+ case 'received':
+ return h('.flex-column', {
+ style: {
+ width: '200px',
+ overflow: 'hidden',
+ },
+ }, [
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, `${props.depositType} to ETH via ShapeShift`),
+ h('div', 'Conversion in progress'),
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, formatDate(props.time)),
+ ])
+ case 'complete':
+ var url = explorerLink(props.response.transaction, parseInt('1'))
+
+ return h('.flex-column.pointer', {
+ style: {
+ width: '200px',
+ overflow: 'hidden',
+ },
+ onClick: () => global.platform.openWindow({ url }),
+ }, [
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, 'From ShapeShift'),
+ h('div', formatDate(props.time)),
+ h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ width: '100%',
+ },
+ }, addressSummary(props.response.transaction)),
+ ])
+
+ case 'failed':
+ return h('span.error', '(Failed)')
+ default:
+ return ''
+ }
+}
diff --git a/old-ui/app/components/tab-bar.js b/old-ui/app/components/tab-bar.js
new file mode 100644
index 000000000..bef444a48
--- /dev/null
+++ b/old-ui/app/components/tab-bar.js
@@ -0,0 +1,37 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = TabBar
+
+inherits(TabBar, Component)
+function TabBar () {
+ Component.call(this)
+}
+
+TabBar.prototype.render = function () {
+ const props = this.props
+ const state = this.state || {}
+ const { tabs = [], defaultTab, tabSelected } = props
+ const { subview = defaultTab } = state
+
+ return (
+ h('.flex-row.space-around.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ paddingTop: '4px',
+ minHeight: '30px',
+ },
+ }, tabs.map((tab) => {
+ const { key, content } = tab
+ return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', {
+ onClick: () => {
+ this.setState({ subview: key })
+ tabSelected(key)
+ },
+ }, content)
+ }))
+ )
+}
+
diff --git a/old-ui/app/components/template.js b/old-ui/app/components/template.js
new file mode 100644
index 000000000..b6ed8eaa0
--- /dev/null
+++ b/old-ui/app/components/template.js
@@ -0,0 +1,18 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = NewComponent
+
+inherits(NewComponent, Component)
+function NewComponent () {
+ Component.call(this)
+}
+
+NewComponent.prototype.render = function () {
+ const props = this.props
+
+ return (
+ h('span', props.message)
+ )
+}
diff --git a/old-ui/app/components/token-cell.js b/old-ui/app/components/token-cell.js
new file mode 100644
index 000000000..19d7139bb
--- /dev/null
+++ b/old-ui/app/components/token-cell.js
@@ -0,0 +1,72 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const Identicon = require('./identicon')
+const prefixForNetwork = require('../../lib/etherscan-prefix-for-network')
+
+module.exports = TokenCell
+
+inherits(TokenCell, Component)
+function TokenCell () {
+ Component.call(this)
+}
+
+TokenCell.prototype.render = function () {
+ const props = this.props
+ const { address, symbol, string, network, userAddress } = props
+
+ return (
+ h('li.token-cell', {
+ style: { cursor: network === '1' ? 'pointer' : 'default' },
+ onClick: this.view.bind(this, address, userAddress, network),
+ }, [
+
+ h(Identicon, {
+ diameter: 50,
+ address,
+ network,
+ }),
+
+ h('h3', `${string || 0} ${symbol}`),
+
+ h('span', { style: { flex: '1 0 auto' } }),
+
+ /*
+ h('button', {
+ onClick: this.send.bind(this, address),
+ }, 'SEND'),
+ */
+
+ ])
+ )
+}
+
+TokenCell.prototype.send = function (address, event) {
+ event.preventDefault()
+ event.stopPropagation()
+ const url = tokenFactoryFor(address)
+ if (url) {
+ navigateTo(url)
+ }
+}
+
+TokenCell.prototype.view = function (address, userAddress, network, event) {
+ const url = etherscanLinkFor(address, userAddress, network)
+ if (url) {
+ navigateTo(url)
+ }
+}
+
+function navigateTo (url) {
+ global.platform.openWindow({ url })
+}
+
+function etherscanLinkFor (tokenAddress, address, network) {
+ const prefix = prefixForNetwork(network)
+ return `https://${prefix}etherscan.io/token/${tokenAddress}?a=${address}`
+}
+
+function tokenFactoryFor (tokenAddress) {
+ return `https://tokenfactory.surge.sh/#/token/${tokenAddress}`
+}
+
diff --git a/old-ui/app/components/token-list.js b/old-ui/app/components/token-list.js
new file mode 100644
index 000000000..998ec901d
--- /dev/null
+++ b/old-ui/app/components/token-list.js
@@ -0,0 +1,207 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const TokenTracker = require('eth-token-tracker')
+const TokenCell = require('./token-cell.js')
+
+module.exports = TokenList
+
+inherits(TokenList, Component)
+function TokenList () {
+ this.state = {
+ tokens: [],
+ isLoading: true,
+ network: null,
+ }
+ Component.call(this)
+}
+
+TokenList.prototype.render = function () {
+ const state = this.state
+ const { tokens, isLoading, error } = state
+ const { userAddress, network } = this.props
+
+ if (isLoading) {
+ return this.message('Loading')
+ }
+
+ if (error) {
+ log.error(error)
+ return h('.hotFix', {
+ style: {
+ padding: '80px',
+ },
+ }, [
+ 'We had trouble loading your token balances. You can view them ',
+ h('span.hotFix', {
+ style: {
+ color: 'rgba(247, 134, 28, 1)',
+ cursor: 'pointer',
+ },
+ onClick: () => {
+ global.platform.openWindow({
+ url: `https://ethplorer.io/address/${userAddress}`,
+ })
+ },
+ }, 'here'),
+ ])
+ }
+
+ const tokenViews = tokens.map((tokenData) => {
+ tokenData.network = network
+ tokenData.userAddress = userAddress
+ return h(TokenCell, tokenData)
+ })
+
+ return h('.full-flex-height', [
+ this.renderTokenStatusBar(),
+
+ h('ol.full-flex-height.flex-column', {
+ style: {
+ overflowY: 'auto',
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ }, [
+ h('style', `
+
+ li.token-cell {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ padding: 10px;
+ min-height: 50px;
+ }
+
+ li.token-cell > h3 {
+ margin-left: 12px;
+ }
+
+ li.token-cell:hover {
+ background: white;
+ cursor: pointer;
+ }
+
+ `),
+ ...tokenViews,
+ h('.flex-grow'),
+ ]),
+ ])
+}
+
+TokenList.prototype.renderTokenStatusBar = function () {
+ const { tokens } = this.state
+
+ let msg
+ if (tokens.length === 1) {
+ msg = `You own 1 token`
+ } else if (tokens.length > 1) {
+ msg = `You own ${tokens.length} tokens`
+ } else {
+ msg = `No tokens found`
+ }
+
+ return h('div', {
+ style: {
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ minHeight: '70px',
+ padding: '10px',
+ },
+ }, [
+ h('span', msg),
+ h('button', {
+ key: 'reveal-account-bar',
+ onClick: (event) => {
+ event.preventDefault()
+ this.props.addToken()
+ },
+ style: {
+ display: 'flex',
+ height: '40px',
+ padding: '10px',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ }, [
+ 'ADD TOKEN',
+ ]),
+ ])
+}
+
+TokenList.prototype.message = function (body) {
+ return h('div', {
+ style: {
+ display: 'flex',
+ height: '250px',
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: '30px',
+ },
+ }, body)
+}
+
+TokenList.prototype.componentDidMount = function () {
+ this.createFreshTokenTracker()
+}
+
+TokenList.prototype.createFreshTokenTracker = function () {
+ if (this.tracker) {
+ // Clean up old trackers when refreshing:
+ this.tracker.stop()
+ this.tracker.removeListener('update', this.balanceUpdater)
+ this.tracker.removeListener('error', this.showError)
+ }
+
+ if (!global.ethereumProvider) return
+ const { userAddress } = this.props
+ this.tracker = new TokenTracker({
+ userAddress,
+ provider: global.ethereumProvider,
+ tokens: this.props.tokens,
+ pollingInterval: 8000,
+ })
+
+
+ // Set up listener instances for cleaning up
+ this.balanceUpdater = this.updateBalances.bind(this)
+ this.showError = (error) => {
+ this.setState({ error, isLoading: false })
+ }
+ this.tracker.on('update', this.balanceUpdater)
+ this.tracker.on('error', this.showError)
+
+ this.tracker.updateBalances()
+ .then(() => {
+ this.updateBalances(this.tracker.serialize())
+ })
+ .catch((reason) => {
+ log.error(`Problem updating balances`, reason)
+ this.setState({ isLoading: false })
+ })
+}
+
+TokenList.prototype.componentWillUpdate = function (nextProps) {
+ if (nextProps.network === 'loading') return
+ const oldNet = this.props.network
+ const newNet = nextProps.network
+
+ if (oldNet && newNet && newNet !== oldNet) {
+ this.setState({ isLoading: true })
+ this.createFreshTokenTracker()
+ }
+}
+
+TokenList.prototype.updateBalances = function (tokens) {
+ const heldTokens = tokens.filter(token => {
+ return token.balance !== '0' && token.string !== '0.000'
+ })
+ this.setState({ tokens: heldTokens, isLoading: false })
+}
+
+TokenList.prototype.componentWillUnmount = function () {
+ if (!this.tracker) return
+ this.tracker.stop()
+}
+
diff --git a/old-ui/app/components/tooltip.js b/old-ui/app/components/tooltip.js
new file mode 100644
index 000000000..efab2c497
--- /dev/null
+++ b/old-ui/app/components/tooltip.js
@@ -0,0 +1,22 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ReactTooltip = require('react-tooltip-component')
+
+module.exports = Tooltip
+
+inherits(Tooltip, Component)
+function Tooltip () {
+ Component.call(this)
+}
+
+Tooltip.prototype.render = function () {
+ const props = this.props
+ const { position, title, children } = props
+
+ return h(ReactTooltip, {
+ position: position || 'left',
+ title,
+ fixed: true,
+ }, children)
+}
diff --git a/old-ui/app/components/transaction-list-item-icon.js b/old-ui/app/components/transaction-list-item-icon.js
new file mode 100644
index 000000000..f442b05af
--- /dev/null
+++ b/old-ui/app/components/transaction-list-item-icon.js
@@ -0,0 +1,68 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const Tooltip = require('./tooltip')
+
+const Identicon = require('./identicon')
+
+module.exports = TransactionIcon
+
+inherits(TransactionIcon, Component)
+function TransactionIcon () {
+ Component.call(this)
+}
+
+TransactionIcon.prototype.render = function () {
+ const { transaction, txParams, isMsg } = this.props
+ switch (transaction.status) {
+ case 'unapproved':
+ return h(!isMsg ? '.unapproved-tx-icon' : 'i.fa.fa-certificate.fa-lg')
+
+ case 'rejected':
+ return h('i.fa.fa-exclamation-triangle.fa-lg.warning', {
+ style: {
+ width: '24px',
+ },
+ })
+
+ case 'failed':
+ return h('i.fa.fa-exclamation-triangle.fa-lg.error', {
+ style: {
+ width: '24px',
+ },
+ })
+
+ case 'submitted':
+ return h(Tooltip, {
+ title: 'Pending',
+ position: 'right',
+ }, [
+ h('i.fa.fa-ellipsis-h', {
+ style: {
+ fontSize: '27px',
+ },
+ }),
+ ])
+ }
+
+ if (isMsg) {
+ return h('i.fa.fa-certificate.fa-lg', {
+ style: {
+ width: '24px',
+ },
+ })
+ }
+
+ if (txParams.to) {
+ return h(Identicon, {
+ diameter: 24,
+ address: txParams.to || transaction.hash,
+ })
+ } else {
+ return h('i.fa.fa-file-text-o.fa-lg', {
+ style: {
+ width: '24px',
+ },
+ })
+ }
+}
diff --git a/old-ui/app/components/transaction-list-item.js b/old-ui/app/components/transaction-list-item.js
new file mode 100644
index 000000000..76a456d3f
--- /dev/null
+++ b/old-ui/app/components/transaction-list-item.js
@@ -0,0 +1,175 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const EthBalance = require('./eth-balance')
+const addressSummary = require('../util').addressSummary
+const explorerLink = require('etherscan-link').createExplorerLink
+const CopyButton = require('./copyButton')
+const vreme = new (require('vreme'))()
+const Tooltip = require('./tooltip')
+const numberToBN = require('number-to-bn')
+
+const TransactionIcon = require('./transaction-list-item-icon')
+const ShiftListItem = require('./shift-list-item')
+module.exports = TransactionListItem
+
+inherits(TransactionListItem, Component)
+function TransactionListItem () {
+ Component.call(this)
+}
+
+TransactionListItem.prototype.render = function () {
+ const { transaction, network, conversionRate, currentCurrency } = this.props
+ if (transaction.key === 'shapeshift') {
+ if (network === '1') return h(ShiftListItem, transaction)
+ }
+ var date = formatDate(transaction.time)
+
+ let isLinkable = false
+ const numericNet = parseInt(network)
+ isLinkable = numericNet === 1 || numericNet === 3 || numericNet === 4 || numericNet === 42
+
+ var isMsg = ('msgParams' in transaction)
+ var isTx = ('txParams' in transaction)
+ var isPending = transaction.status === 'unapproved'
+ let txParams
+ if (isTx) {
+ txParams = transaction.txParams
+ } else if (isMsg) {
+ txParams = transaction.msgParams
+ }
+
+ const nonce = txParams.nonce ? numberToBN(txParams.nonce).toString(10) : ''
+
+ const isClickable = ('hash' in transaction && isLinkable) || isPending
+ return (
+ h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, {
+ onClick: (event) => {
+ if (isPending) {
+ this.props.showTx(transaction.id)
+ }
+ event.stopPropagation()
+ if (!transaction.hash || !isLinkable) return
+ var url = explorerLink(transaction.hash, parseInt(network))
+ global.platform.openWindow({ url })
+ },
+ style: {
+ padding: '20px 0',
+ display: 'flex',
+ justifyContent: 'space-between',
+ },
+ }, [
+
+ h('.identicon-wrapper.flex-column.flex-center.select-none', [
+ h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
+ ]),
+
+ h(Tooltip, {
+ title: 'Transaction Number',
+ position: 'right',
+ }, [
+ h('span', {
+ style: {
+ display: 'flex',
+ cursor: 'normal',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ }, nonce),
+ ]),
+
+ h('.flex-column', {style: {width: '150px', overflow: 'hidden'}}, [
+ domainField(txParams),
+ h('div', date),
+ recipientField(txParams, transaction, isTx, isMsg),
+ ]),
+
+ // Places a copy button if tx is successful, else places a placeholder empty div.
+ transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}),
+
+ isTx ? h(EthBalance, {
+ value: txParams.value,
+ conversionRate,
+ currentCurrency,
+ shorten: true,
+ showFiat: false,
+ style: {fontSize: '15px'},
+ }) : h('.flex-column'),
+ ])
+ )
+}
+
+function domainField (txParams) {
+ return h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ width: '100%',
+ },
+ }, [
+ txParams.origin,
+ ])
+}
+
+function recipientField (txParams, transaction, isTx, isMsg) {
+ let message
+
+ if (isMsg) {
+ message = 'Signature Requested'
+ } else if (txParams.to) {
+ message = addressSummary(txParams.to)
+ } else {
+ message = 'Contract Published'
+ }
+
+ return h('div', {
+ style: {
+ fontSize: 'x-small',
+ color: '#ABA9AA',
+ },
+ }, [
+ message,
+ renderErrorOrWarning(transaction),
+ ])
+}
+
+function formatDate (date) {
+ return vreme.format(new Date(date), 'March 16 2014 14:30')
+}
+
+function renderErrorOrWarning (transaction) {
+ const { status, err, warning } = transaction
+
+ // show rejected
+ if (status === 'rejected') {
+ return h('span.error', ' (Rejected)')
+ }
+
+ // show error
+ if (err) {
+ const message = err.message || ''
+ return (
+ h(Tooltip, {
+ title: message,
+ position: 'bottom',
+ }, [
+ h(`span.error`, ` (Failed)`),
+ ])
+ )
+ }
+
+ // show warning
+ if (warning) {
+ const message = warning.message
+ return h(Tooltip, {
+ title: message,
+ position: 'bottom',
+ }, [
+ h(`span.warning`, ` (Warning)`),
+ ])
+ }
+}
diff --git a/old-ui/app/components/transaction-list.js b/old-ui/app/components/transaction-list.js
new file mode 100644
index 000000000..345e3ca16
--- /dev/null
+++ b/old-ui/app/components/transaction-list.js
@@ -0,0 +1,87 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+const TransactionListItem = require('./transaction-list-item')
+
+module.exports = TransactionList
+
+
+inherits(TransactionList, Component)
+function TransactionList () {
+ Component.call(this)
+}
+
+TransactionList.prototype.render = function () {
+ const { transactions, network, unapprovedMsgs, conversionRate } = this.props
+
+ var shapeShiftTxList
+ if (network === '1') {
+ shapeShiftTxList = this.props.shapeShiftTxList
+ }
+ const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
+ .sort((a, b) => b.time - a.time)
+
+ return (
+
+ h('section.transaction-list.full-flex-height', {
+ style: {
+ justifyContent: 'center',
+ },
+ }, [
+
+ h('style', `
+ .transaction-list .transaction-list-item:not(:last-of-type) {
+ border-bottom: 1px solid #D4D4D4;
+ }
+ .transaction-list .transaction-list-item .ether-balance-label {
+ display: block !important;
+ font-size: small;
+ }
+ `),
+
+ h('.tx-list', {
+ style: {
+ overflowY: 'auto',
+ height: '100%',
+ padding: '0 25px 0 15px',
+ textAlign: 'center',
+ },
+ }, [
+
+ txsToRender.length
+ ? txsToRender.map((transaction, i) => {
+ let key
+ switch (transaction.key) {
+ case 'shapeshift':
+ const { depositAddress, time } = transaction
+ key = `shift-tx-${depositAddress}-${time}-${i}`
+ break
+ default:
+ key = `tx-${transaction.id}-${i}`
+ }
+ return h(TransactionListItem, {
+ transaction, i, network, key,
+ conversionRate,
+ showTx: (txId) => {
+ this.props.viewPendingTx(txId)
+ },
+ })
+ })
+ : h('.flex-center.full-flex-height', {
+ style: {
+ flexDirection: 'column',
+ justifyContent: 'center',
+ },
+ }, [
+ h('p', {
+ style: {
+ marginTop: '50px',
+ },
+ }, 'No transaction history.'),
+ ]),
+ ]),
+ ])
+ )
+}
+
diff --git a/old-ui/app/components/typed-message-renderer.js b/old-ui/app/components/typed-message-renderer.js
new file mode 100644
index 000000000..d170d63b7
--- /dev/null
+++ b/old-ui/app/components/typed-message-renderer.js
@@ -0,0 +1,42 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const extend = require('xtend')
+
+module.exports = TypedMessageRenderer
+
+inherits(TypedMessageRenderer, Component)
+function TypedMessageRenderer () {
+ Component.call(this)
+}
+
+TypedMessageRenderer.prototype.render = function () {
+ const props = this.props
+ const { value, style } = props
+ const text = renderTypedData(value)
+
+ const defaultStyle = extend({
+ width: '315px',
+ maxHeight: '210px',
+ resize: 'none',
+ border: 'none',
+ background: 'white',
+ padding: '3px',
+ overflow: 'scroll',
+ }, style)
+
+ return (
+ h('div.font-small', {
+ style: defaultStyle,
+ }, text)
+ )
+}
+
+function renderTypedData (values) {
+ return values.map(function (value) {
+ return h('div', {}, [
+ h('strong', {style: {display: 'block', fontWeight: 'bold'}}, String(value.name) + ':'),
+ h('div', {}, value.value),
+ ])
+ })
+}
diff --git a/old-ui/app/conf-tx.js b/old-ui/app/conf-tx.js
new file mode 100644
index 000000000..1bb8eb97c
--- /dev/null
+++ b/old-ui/app/conf-tx.js
@@ -0,0 +1,245 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+const NetworkIndicator = require('./components/network')
+const LoadingIndicator = require('./components/loading')
+const txHelper = require('../lib/tx-helper')
+const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
+
+const PendingTx = require('./components/pending-tx')
+const PendingMsg = require('./components/pending-msg')
+const PendingPersonalMsg = require('./components/pending-personal-msg')
+const PendingTypedMsg = require('./components/pending-typed-msg')
+const Loading = require('./components/loading')
+
+module.exports = connect(mapStateToProps)(ConfirmTxScreen)
+
+function mapStateToProps (state) {
+ return {
+ identities: state.metamask.identities,
+ accounts: state.metamask.accounts,
+ selectedAddress: state.metamask.selectedAddress,
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ unapprovedMsgs: state.metamask.unapprovedMsgs,
+ unapprovedPersonalMsgs: state.metamask.unapprovedPersonalMsgs,
+ unapprovedTypedMessages: state.metamask.unapprovedTypedMessages,
+ index: state.appState.currentView.context,
+ warning: state.appState.warning,
+ network: state.metamask.network,
+ provider: state.metamask.provider,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ blockGasLimit: state.metamask.currentBlockGasLimit,
+ computedBalances: state.metamask.computedBalances,
+ }
+}
+
+inherits(ConfirmTxScreen, Component)
+function ConfirmTxScreen () {
+ Component.call(this)
+}
+
+ConfirmTxScreen.prototype.render = function () {
+ const props = this.props
+ const { network, provider, unapprovedTxs, currentCurrency, computedBalances,
+ unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, conversionRate, blockGasLimit } = props
+
+ var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network)
+
+ var txData = unconfTxList[props.index] || {}
+ var txParams = txData.params || {}
+ var isNotification = isPopupOrNotification() === 'notification'
+
+ log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
+ if (unconfTxList.length === 0) return h(Loading, { isLoading: true })
+
+ const unconfTxListLength = unconfTxList.length
+
+ return (
+
+ h('.flex-column.flex-grow', [
+
+ h(LoadingIndicator, {
+ isLoading: this.state ? !this.state.bypassLoadingScreen : txData.loadingDefaults,
+ loadingMessage: 'Estimating transaction cost…',
+ canBypass: true,
+ bypass: () => {
+ this.setState({bypassLoadingScreen: true})
+ },
+ }),
+
+ // subtitle and nav
+ h('.section-title.flex-row.flex-center', [
+ !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: this.goHome.bind(this),
+ }) : null,
+ h('h2.page-subtitle', 'Confirm Transaction'),
+ isNotification ? h(NetworkIndicator, {
+ network: network,
+ provider: provider,
+ }) : null,
+ ]),
+
+ h('h3', {
+ style: {
+ alignSelf: 'center',
+ display: unconfTxList.length > 1 ? 'block' : 'none',
+ },
+ }, [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ style: {
+ display: props.index === 0 ? 'none' : 'inline-block',
+ },
+ onClick: () => props.dispatch(actions.previousTx()),
+ }),
+ ` ${props.index + 1} of ${unconfTxList.length} `,
+ h('i.fa.fa-arrow-right.fa-lg.cursor-pointer', {
+ style: {
+ display: props.index + 1 === unconfTxList.length ? 'none' : 'inline-block',
+ },
+ onClick: () => props.dispatch(actions.nextTx()),
+ }),
+ ]),
+
+ warningIfExists(props.warning),
+
+ currentTxView({
+ // Properties
+ txData: txData,
+ key: txData.id,
+ selectedAddress: props.selectedAddress,
+ accounts: props.accounts,
+ identities: props.identities,
+ conversionRate,
+ currentCurrency,
+ blockGasLimit,
+ unconfTxListLength,
+ computedBalances,
+ // Actions
+ buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress),
+ sendTransaction: this.sendTransaction.bind(this),
+ cancelTransaction: this.cancelTransaction.bind(this, txData),
+ cancelAllTransactions: this.cancelAllTransactions.bind(this, unconfTxList),
+ signMessage: this.signMessage.bind(this, txData),
+ signPersonalMessage: this.signPersonalMessage.bind(this, txData),
+ signTypedMessage: this.signTypedMessage.bind(this, txData),
+ cancelMessage: this.cancelMessage.bind(this, txData),
+ cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
+ cancelTypedMessage: this.cancelTypedMessage.bind(this, txData),
+ }),
+ ])
+ )
+}
+
+function currentTxView (opts) {
+ log.info('rendering current tx view')
+ const { txData } = opts
+ const { txParams, msgParams, type } = txData
+
+ if (txParams) {
+ log.debug('txParams detected, rendering pending tx')
+ return h(PendingTx, opts)
+ } else if (msgParams) {
+ log.debug('msgParams detected, rendering pending msg')
+
+ if (type === 'eth_sign') {
+ log.debug('rendering eth_sign message')
+ return h(PendingMsg, opts)
+ } else if (type === 'personal_sign') {
+ log.debug('rendering personal_sign message')
+ return h(PendingPersonalMsg, opts)
+ } else if (type === 'eth_signTypedData') {
+ log.debug('rendering eth_signTypedData message')
+ return h(PendingTypedMsg, opts)
+ }
+ }
+}
+
+ConfirmTxScreen.prototype.buyEth = function (address, event) {
+ event.preventDefault()
+ this.props.dispatch(actions.buyEthView(address))
+}
+
+ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
+ this.stopPropagation(event)
+ this.props.dispatch(actions.updateAndApproveTx(txData))
+}
+
+ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
+ this.stopPropagation(event)
+ event.preventDefault()
+ this.props.dispatch(actions.cancelTx(txData))
+}
+
+ConfirmTxScreen.prototype.cancelAllTransactions = function (unconfTxList, event) {
+ this.stopPropagation(event)
+ event.preventDefault()
+ this.props.dispatch(actions.cancelAllTx(unconfTxList))
+}
+
+ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
+ log.info('conf-tx.js: signing message')
+ var params = msgData.msgParams
+ params.metamaskId = msgData.id
+ this.stopPropagation(event)
+ this.props.dispatch(actions.signMsg(params))
+}
+
+ConfirmTxScreen.prototype.stopPropagation = function (event) {
+ if (event.stopPropagation) {
+ event.stopPropagation()
+ }
+}
+
+ConfirmTxScreen.prototype.signPersonalMessage = function (msgData, event) {
+ log.info('conf-tx.js: signing personal message')
+ var params = msgData.msgParams
+ params.metamaskId = msgData.id
+ this.stopPropagation(event)
+ this.props.dispatch(actions.signPersonalMsg(params))
+}
+
+ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
+ log.info('conf-tx.js: signing typed message')
+ var params = msgData.msgParams
+ params.metamaskId = msgData.id
+ this.stopPropagation(event)
+ this.props.dispatch(actions.signTypedMsg(params))
+}
+
+ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
+ log.info('canceling message')
+ this.stopPropagation(event)
+ this.props.dispatch(actions.cancelMsg(msgData))
+}
+
+ConfirmTxScreen.prototype.cancelPersonalMessage = function (msgData, event) {
+ log.info('canceling personal message')
+ this.stopPropagation(event)
+ this.props.dispatch(actions.cancelPersonalMsg(msgData))
+}
+
+ConfirmTxScreen.prototype.cancelTypedMessage = function (msgData, event) {
+ log.info('canceling typed message')
+ this.stopPropagation(event)
+ this.props.dispatch(actions.cancelTypedMsg(msgData))
+}
+
+ConfirmTxScreen.prototype.goHome = function (event) {
+ this.stopPropagation(event)
+ this.props.dispatch(actions.goHome())
+}
+
+function warningIfExists (warning) {
+ if (warning &&
+ // Do not display user rejections on this screen:
+ warning.indexOf('User denied transaction signature') === -1) {
+ return h('.error', {
+ style: {
+ margin: 'auto',
+ },
+ }, warning)
+ }
+}
diff --git a/ui/app/config.js b/old-ui/app/config.js
index 06568f669..9e07cf348 100644
--- a/ui/app/config.js
+++ b/old-ui/app/config.js
@@ -2,13 +2,13 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('./actions')
+const actions = require('../../ui/app/actions')
const infuraCurrencies = require('./infura-conversion.json').objects.sort((a, b) => {
return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
})
const validUrl = require('valid-url')
const exportAsFile = require('./util').exportAsFile
-
+const Modal = require('../../ui/app/components/modals/index').Modal
module.exports = connect(mapStateToProps)(ConfigScreen)
@@ -32,11 +32,13 @@ ConfigScreen.prototype.render = function () {
return (
h('.flex-column.flex-grow', {
style:{
- maxHeight: '465px',
+ maxHeight: '585px',
overflowY: 'auto',
},
}, [
+ h(Modal, {}, []),
+
// subtitle and nav
h('.section-title.flex-row.flex-center', [
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
diff --git a/ui/app/css/debug.css b/old-ui/app/css/debug.css
index 3e125bcd4..3e125bcd4 100644
--- a/ui/app/css/debug.css
+++ b/old-ui/app/css/debug.css
diff --git a/ui/app/css/fonts.css b/old-ui/app/css/fonts.css
index 3b9f581b9..3b9f581b9 100644
--- a/ui/app/css/fonts.css
+++ b/old-ui/app/css/fonts.css
diff --git a/ui/app/css/index.css b/old-ui/app/css/index.css
index b40d48b5d..67c327f62 100644
--- a/ui/app/css/index.css
+++ b/old-ui/app/css/index.css
@@ -21,6 +21,7 @@ html, body {
background: #F7F7F7;
margin: 0;
padding: 0;
+ height: 100%;
}
html {
@@ -61,7 +62,6 @@ input:focus, textarea:focus {
#app-content {
overflow-x: hidden;
- min-width: 357px;
height: 100%;
display: flex;
flex-direction: column;
@@ -285,7 +285,7 @@ app sections
}
.unlock-screen #metamask-mascot-container {
- margin-top: 24px;
+ margin-top: 80px;
}
.unlock-screen h1 {
@@ -443,10 +443,14 @@ input.large-input {
flex-wrap: wrap;
overflow-x: hidden;
overflow-y: auto;
- max-height: 465px;
+ max-height: 585px;
flex-direction: inherit;
}
+.account-detail-section .name-label {
+ margin-left: 15px;
+}
+
.grow-tenx {
flex-grow: 10;
}
@@ -711,3 +715,97 @@ div.message-container > div:first-child {
.pop-hover:hover {
transform: scale(1.1);
}
+
+//Notification Modal
+
+.notification-modal-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ border: 1px solid #dedede;
+ box-shadow: 0 0 2px 2px #dedede;
+ font-family: Roboto;
+}
+
+.notification-modal-header {
+ background: #f6f6f6;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 30px;
+ font-size: 22px;
+ color: #1b344d;
+ height: 79px;
+}
+
+.notification-modal-message {
+ padding: 20px;
+}
+
+.notification-modal-message {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ font-size: 17px;
+ color: #1b344d;
+}
+
+.modal-close-x::after {
+ content: '\00D7';
+ font-size: 2em;
+ color: #9b9b9b;
+ position: absolute;
+ top: 25px;
+ right: 17.5px;
+ font-family: sans-serif;
+ cursor: pointer;
+}
+
+.notification-modal__wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ border: 1px solid #dedede;
+ box-shadow: 0 0 2px 2px #dedede;
+ font-family: Roboto;
+}
+
+.notification-modal__header {
+ background: #f6f6f6;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 30px;
+ font-size: 22px;
+ color: #1b344d;
+ height: 79px;
+}
+
+.notification-modal__message {
+ padding: 20px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ font-size: 17px;
+ color: #1b344d;
+}
+
+.notification-modal__buttons {
+ display: flex;
+ justify-content: space-evenly;
+ width: 100%;
+ margin-bottom: 24px;
+ padding: 0px 42px;
+}
+
+.notification-modal__buttons__btn {
+ cursor: pointer;
+}
+
+.notification-modal__link {
+ color: #2f9ae0;
+} \ No newline at end of file
diff --git a/ui/app/css/lib.css b/old-ui/app/css/lib.css
index f3acbee76..f3acbee76 100644
--- a/ui/app/css/lib.css
+++ b/old-ui/app/css/lib.css
diff --git a/old-ui/app/css/output/index.css b/old-ui/app/css/output/index.css
new file mode 100644
index 000000000..84ceb3bd7
--- /dev/null
+++ b/old-ui/app/css/output/index.css
@@ -0,0 +1,5385 @@
+@charset "UTF-8";
+/*
+ ITCSS
+
+ http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
+ https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
+ */
+/*
+ Variables
+ */
+/*
+ Colors
+ http://chir.ag/projects/name-that-color
+ */
+/*
+ Z-Indicies
+ */
+/*
+ Z Indicies - Current
+ app - 11
+ hex/bn as decimal input - 1 - remove?
+ dropdown - 11
+ loading - 10 - higher?
+ mascot - 0 - remove?
+ */
+/*
+ Responsive Breakpoints
+ */
+@import url("https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900");
+@import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css");
+@font-face {
+ font-family: 'Montserrat Regular';
+ src: url("/fonts/Montserrat/Montserrat-Regular.woff") format("woff");
+ src: url("/fonts/Montserrat/Montserrat-Regular.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal;
+ font-size: 'small'; }
+
+@font-face {
+ font-family: 'Montserrat Bold';
+ src: url("/fonts/Montserrat/Montserrat-Bold.woff") format("woff");
+ src: url("/fonts/Montserrat/Montserrat-Bold.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'Montserrat Light';
+ src: url("/fonts/Montserrat/Montserrat-Light.woff") format("woff");
+ src: url("/fonts/Montserrat/Montserrat-Light.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'Montserrat UltraLight';
+ src: url("/fonts/Montserrat/Montserrat-UltraLight.woff") format("woff");
+ src: url("/fonts/Montserrat/Montserrat-UltraLight.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'DIN OT';
+ src: url("/fonts/DIN_OT/DINOT-2.otf") format("opentype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'DIN OT Light';
+ src: url("/fonts/DIN_OT/DINOT-2.otf") format("opentype");
+ font-weight: 200;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'DIN NEXT';
+ src: url("/fonts/DIN NEXT/DIN NEXT W01 Regular.otf") format("opentype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'DIN NEXT Light';
+ src: url("/fonts/DIN NEXT/DIN NEXT W10 Light.otf") format("opentype");
+ font-weight: 400;
+ font-style: normal; }
+
+@font-face {
+ font-family: 'Lato';
+ src: url("/fonts/Lato/Lato-Regular.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal; }
+
+/*
+ Utility Classes
+ */
+/* color */
+.color-orange {
+ color: #f7861c; }
+
+.color-forest {
+ color: #0a5448; }
+
+/* lib */
+.full-size {
+ height: 100%;
+ width: 100%; }
+
+.full-width {
+ width: 100%; }
+
+.full-flex-height {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+
+.full-height {
+ height: 100%; }
+
+.flex-column {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+
+.space-between {
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between; }
+
+.space-around {
+ -ms-flex-pack: distribute;
+ justify-content: space-around; }
+
+.flex-column-bottom {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: reverse;
+ -ms-flex-direction: column-reverse;
+ flex-direction: column-reverse; }
+
+.flex-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row; }
+
+.flex-space-between {
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between; }
+
+.flex-space-around {
+ -ms-flex-pack: distribute;
+ justify-content: space-around; }
+
+.flex-right {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end; }
+
+.flex-left {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start; }
+
+.flex-fixed {
+ -webkit-box-flex: 0;
+ -ms-flex: none;
+ flex: none; }
+
+.flex-basis-auto {
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto; }
+
+.flex-grow {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; }
+
+.flex-wrap {
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap; }
+
+.flex-center {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.flex-justify-center {
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+
+.flex-align-center {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.flex-self-end {
+ -ms-flex-item-align: end;
+ align-self: flex-end; }
+
+.flex-self-stretch {
+ -ms-flex-item-align: stretch;
+ align-self: stretch; }
+
+.flex-vertical {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+
+.z-bump {
+ z-index: 1; }
+
+.select-none {
+ cursor: inherit;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+
+.pointer {
+ cursor: pointer; }
+
+.cursor-pointer {
+ cursor: pointer;
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ -webkit-transition: -webkit-transform 50ms ease-in-out;
+ transition: -webkit-transform 50ms ease-in-out;
+ transition: transform 50ms ease-in-out;
+ transition: transform 50ms ease-in-out, -webkit-transform 50ms ease-in-out; }
+
+.cursor-pointer:hover {
+ -webkit-transform: scale(1.1);
+ transform: scale(1.1); }
+
+.cursor-pointer:active {
+ -webkit-transform: scale(0.95);
+ transform: scale(0.95); }
+
+.cursor-disabled {
+ cursor: not-allowed; }
+
+.margin-bottom-sml {
+ margin-bottom: 20px; }
+
+.margin-bottom-med {
+ margin-bottom: 40px; }
+
+.margin-right-left {
+ margin: 0 20px; }
+
+.bold {
+ font-weight: 700; }
+
+.text-transform-uppercase {
+ text-transform: uppercase; }
+
+.font-small {
+ font-size: 12px; }
+
+.font-medium {
+ font-size: 1.2em; }
+
+hr.horizontal-line {
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #ccc;
+ margin: 1em 0;
+ padding: 0; }
+
+.hover-white:hover {
+ background: #fff; }
+
+.red-dot {
+ background: #e91550;
+ color: #fff;
+ border-radius: 10px; }
+
+.diamond {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ background: #038789; }
+
+.hollow-diamond {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ border: 3px solid #690496; }
+
+.golden-square {
+ background: #ebb33f; }
+
+.pending-dot {
+ background: #f00;
+ left: 14px;
+ top: 14px;
+ color: #fff;
+ border-radius: 10px;
+ height: 20px;
+ min-width: 20px;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding: 4px;
+ z-index: 1; }
+
+.keyring-label {
+ z-index: 1;
+ font-size: 8px;
+ line-height: 8px;
+ background: rgba(255, 255, 255, 0.4);
+ color: #fff;
+ border-radius: 10px;
+ padding: 4px;
+ text-align: center;
+ height: 15px; }
+
+.ether-balance {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.tabSection {
+ min-width: 350px; }
+
+.menu-icon {
+ display: inline-block;
+ height: 12px;
+ min-width: 12px;
+ margin: 13px; }
+
+.ether-icon {
+ background: #00a344;
+ border-radius: 20px; }
+
+.testnet-icon {
+ background: #2465e1; }
+
+.drop-menu-item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.invisible {
+ visibility: hidden; }
+
+.one-line-concat {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap; }
+
+.critical-error {
+ text-align: center;
+ margin-top: 20px;
+ color: #f00; }
+
+/*
+ Misc
+ */
+.letter-spacey {
+ letter-spacing: .1em; }
+
+.active {
+ color: #909090; }
+
+.check {
+ margin-left: 7px;
+ color: #f7861c;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end; }
+
+/*
+ Generic
+ */
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ /* stylelint-disable */
+ font: inherit;
+ /* stylelint-enable */
+ vertical-align: baseline; }
+
+/* HTML5 display-role reset for older browsers */
+/* stylelint-disable */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block; }
+
+body {
+ line-height: 1; }
+
+ol,
+ul {
+ list-style: none; }
+
+blockquote,
+q {
+ quotes: none; }
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none; }
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0; }
+
+button {
+ border-style: none;
+ cursor: pointer; }
+
+/* stylelint-enable */
+* {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box; }
+
+html,
+body {
+ font-family: Roboto, Arial;
+ color: #4d4d4d;
+ font-weight: 300;
+ line-height: 1.4em;
+ background: #f7f7f7;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0; }
+
+html {
+ min-height: 500px; }
+
+.app-root {
+ overflow: hidden;
+ position: relative; }
+
+.app-primary {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+
+input:focus,
+textarea:focus {
+ outline: none; }
+
+/* stylelint-disable */
+#app-content {
+ overflow-x: hidden;
+ height: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+ @media screen and (max-width: 575px) {
+ #app-content {
+ background-color: #fff; } }
+
+/* stylelint-enable */
+a {
+ text-decoration: none;
+ color: inherit; }
+
+a:hover {
+ color: #df6b0e; }
+
+input.large-input,
+textarea.large-input {
+ padding: 8px; }
+
+input.large-input {
+ height: 36px; }
+
+/*
+ Buttons
+ */
+.btn-green {
+ background-color: #02c9b1; }
+
+button.btn-clear {
+ background: #fff;
+ border: 1px solid; }
+
+button[disabled],
+input[type="submit"][disabled] {
+ cursor: not-allowed;
+ opacity: .5; }
+
+button.primary {
+ padding: 8px 12px;
+ background: #f7861c;
+ -webkit-box-shadow: 0 3px 6px rgba(247, 134, 28, 0.36);
+ box-shadow: 0 3px 6px rgba(247, 134, 28, 0.36);
+ color: #fff;
+ font-size: 1.1em;
+ font-family: Roboto;
+ text-transform: uppercase; }
+
+.btn-light {
+ padding: 8px 12px;
+ -webkit-box-shadow: 0 3px 6px rgba(247, 134, 28, 0.36);
+ box-shadow: 0 3px 6px rgba(247, 134, 28, 0.36);
+ color: #585d67;
+ font-size: 1.1em;
+ font-family: Roboto;
+ text-transform: uppercase;
+ text-align: center;
+ line-height: 20px;
+ border-radius: 2px;
+ border: 1px solid #979797;
+ opacity: .5; }
+
+button.btn-thin {
+ border: 1px solid;
+ border-color: #4d4d4d;
+ color: #4d4d4d;
+ background: #ffae29;
+ border-radius: 4px;
+ min-width: 200px;
+ margin: 12px 0;
+ padding: 6px;
+ font-size: 13px; }
+
+.btn-secondary {
+ border: 1px solid #979797;
+ border-radius: 2px;
+ background-color: #fff;
+ font-size: 16px;
+ line-height: 24px;
+ padding: 16px 42px; }
+ .btn-secondary[disabled] {
+ background-color: #fff !important;
+ opacity: .5; }
+
+.btn-tertiary {
+ border: 1px solid transparent;
+ border-radius: 2px;
+ background-color: transparent;
+ font-size: 16px;
+ line-height: 24px;
+ padding: 16px 42px; }
+
+.app-header {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ visibility: visible;
+ background: #efefef;
+ position: relative;
+ z-index: 12;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap; }
+ @media screen and (max-width: 575px) {
+ .app-header {
+ padding: 12px;
+ width: 100%;
+ -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
+ z-index: 26; } }
+ @media screen and (min-width: 576px) {
+ .app-header {
+ height: 75px;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+ .app-header::after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ height: 32px;
+ background: #efefef;
+ bottom: -32px; } }
+ .app-header .metafox-icon {
+ cursor: pointer; }
+
+.app-header-contents {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ width: 100%;
+ height: 6.9vh; }
+ @media screen and (max-width: 575px) {
+ .app-header-contents {
+ height: 100%; } }
+ @media screen and (min-width: 576px) {
+ .app-header-contents {
+ width: 85vw; } }
+ @media screen and (min-width: 769px) {
+ .app-header-contents {
+ width: 80vw; } }
+ @media screen and (min-width: 1281px) {
+ .app-header-contents {
+ width: 65vw; } }
+
+.app-header h1 {
+ font-family: Roboto;
+ text-transform: uppercase;
+ font-weight: 400;
+ color: #22232c;
+ line-height: 29px; }
+ @media screen and (max-width: 575px) {
+ .app-header h1 {
+ display: none; } }
+
+h2.page-subtitle {
+ text-transform: uppercase;
+ color: #aeaeae;
+ font-size: 1em;
+ margin: 12px; }
+
+.network-component-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.left-menu-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ cursor: pointer; }
+
+.header__right-actions {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .header__right-actions .identicon {
+ cursor: pointer; }
+
+.app-footer {
+ padding-bottom: 10px;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.network-component--disabled {
+ cursor: default; }
+ .network-component--disabled .fa-caret-down {
+ opacity: 0; }
+
+.network-component.pointer {
+ border: 1px solid #22232c;
+ border-radius: 82px;
+ padding: 6px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .network-component.pointer.ethereum-network {
+ border-color: #038789; }
+ .network-component.pointer.ethereum-network .menu-icon-circle div {
+ background-color: rgba(3, 135, 137, 0.7) !important; }
+ .network-component.pointer.ropsten-test-network {
+ border-color: #e91550; }
+ .network-component.pointer.ropsten-test-network .menu-icon-circle div {
+ background-color: rgba(233, 21, 80, 0.7) !important; }
+ .network-component.pointer.kovan-test-network {
+ border-color: #690496; }
+ .network-component.pointer.kovan-test-network .menu-icon-circle div {
+ background-color: rgba(105, 4, 150, 0.7) !important; }
+ .network-component.pointer.rinkeby-test-network {
+ border-color: #ebb33f; }
+ .network-component.pointer.rinkeby-test-network .menu-icon-circle div {
+ background-color: rgba(235, 179, 63, 0.7) !important; }
+
+.dropdown-menu-item .menu-icon-circle,
+.dropdown-menu-item .menu-icon-circle--active {
+ margin: 0 14px; }
+
+.network-indicator {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-size: .6em; }
+ .network-indicator .fa-caret-down {
+ line-height: 15px;
+ font-size: 12px;
+ padding: 0 4px; }
+
+.network-name {
+ line-height: 15px;
+ padding: 0 4px;
+ font-family: Roboto;
+ font-size: 12px;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto; }
+
+.network-droppo {
+ right: 2px; }
+ @media screen and (min-width: 576px) {
+ .network-droppo {
+ right: calc(((100% - 85vw) / 2) + 2px); } }
+ @media screen and (min-width: 769px) {
+ .network-droppo {
+ right: calc(((100% - 80vw) / 2) + 2px); } }
+ @media screen and (min-width: 1281px) {
+ .network-droppo {
+ right: calc(((100% - 65vw) / 2) + 2px); } }
+
+.network-name-item {
+ font-weight: 100;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ color: #9b9b9b; }
+
+.network-check,
+.network-check__transparent {
+ color: #fff;
+ margin-left: 7px; }
+
+.network-check__transparent {
+ opacity: 0;
+ width: 16px;
+ margin: 0; }
+
+.menu-icon-circle,
+.menu-icon-circle--active {
+ background: none;
+ border-radius: 22px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border: 1px solid transparent;
+ margin: 0 4px; }
+
+.menu-icon-circle--active {
+ border: 1px solid #fff;
+ background: rgba(100, 100, 100, 0.4); }
+
+.menu-icon-circle div,
+.menu-icon-circle--active div {
+ height: 12px;
+ width: 12px;
+ border-radius: 17px; }
+
+.menu-icon-circle--active div {
+ opacity: 1; }
+
+.network-dropdown-header {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ width: 100%; }
+
+.network-dropdown-divider {
+ width: 100%;
+ height: 1px;
+ margin: 10px 0;
+ background-color: #5d5d5d; }
+
+.network-dropdown-title {
+ height: 25px;
+ width: 75px;
+ color: #fff;
+ font-family: Roboto;
+ font-size: 18px;
+ line-height: 25px;
+ text-align: center; }
+
+.network-dropdown-content {
+ height: 36px;
+ width: 265px;
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px; }
+
+.modal > div:focus {
+ outline: none !important; }
+
+.buy-modal-content {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ text-align: center;
+ font-family: Roboto;
+ padding: 0 16px; }
+
+.buy-modal-content-option {
+ cursor: pointer;
+ color: #5B5D67; }
+
+.qr-ellip-address, .ellip-address {
+ width: 247px;
+ border: none;
+ font-family: Roboto;
+ font-size: 14px; }
+
+@media screen and (max-width: 575px) {
+ .buy-modal-content-title-wrapper {
+ -ms-flex-pack: distribute;
+ justify-content: space-around;
+ width: 100%;
+ height: 100px; }
+ .buy-modal-content-title {
+ font-size: 26px;
+ margin-top: 15px; }
+ .buy-modal-content-options {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding: 5% 33%; }
+ .buy-modal-content-footer {
+ text-transform: uppercase;
+ width: 100%;
+ height: 50px; }
+ div.buy-modal-content-option {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 80vw;
+ height: 15vh;
+ margin: 10px;
+ text-align: center;
+ border-radius: 6px;
+ border: 1px solid #000;
+ padding: 0% 7%;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+ div.buy-modal-content-option div.buy-modal-content-option-title {
+ font-size: 20px; }
+ div.buy-modal-content-option div.buy-modal-content-option-subtitle {
+ font-size: 16px; } }
+
+@media screen and (min-width: 576px) {
+ .buy-modal-content-title-wrapper {
+ -ms-flex-pack: distribute;
+ justify-content: space-around;
+ width: 100%;
+ height: 110px; }
+ .buy-modal-content-title {
+ font-size: 26px;
+ margin-top: 15px; }
+ .buy-modal-content-footer {
+ text-transform: uppercase;
+ width: 100%;
+ height: 50px; }
+ .buy-modal-content-options {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ margin: 20px 0 60px; }
+ div.buy-modal-content-option {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 20vw;
+ height: 120px;
+ text-align: center;
+ border-radius: 6px;
+ border: 1px solid #000;
+ margin: 0 8px;
+ padding: 18px 0; }
+ div.buy-modal-content-option div.buy-modal-content-option-title {
+ font-size: 20px;
+ margin-bottom: 12px; } }
+ @media screen and (min-width: 576px) and (max-width: 679px) {
+ div.buy-modal-content-option div.buy-modal-content-option-title {
+ font-size: 14px; } }
+ @media screen and (min-width: 576px) and (min-width: 1281px) {
+ div.buy-modal-content-option div.buy-modal-content-option-title {
+ font-size: 20px; } }
+
+@media screen and (min-width: 576px) {
+ div.buy-modal-content-option div.buy-modal-content-option-subtitle {
+ font-size: 16px;
+ padding: 0 10px;
+ height: 25%; } }
+ @media screen and (min-width: 576px) and (max-width: 679px) {
+ div.buy-modal-content-option div.buy-modal-content-option-subtitle {
+ font-size: 10px;
+ padding: 0 10px;
+ margin-bottom: 5px;
+ line-height: 15px; } }
+ @media screen and (min-width: 576px) and (min-width: 680px) {
+ div.buy-modal-content-option div.buy-modal-content-option-subtitle {
+ font-size: 14px;
+ padding: 0 4px;
+ margin-bottom: 2px; } }
+ @media screen and (min-width: 576px) and (min-width: 1281px) {
+ div.buy-modal-content-option div.buy-modal-content-option-subtitle {
+ font-size: 16px;
+ padding: 0; } }
+
+@media screen and (min-width: 576px) {
+ div.buy-modal-content-option div.buy-modal-content-footer {
+ margin-top: 8vh; } }
+
+.edit-account-name-modal-content {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative; }
+
+.edit-account-name-modal-cancel {
+ position: absolute;
+ top: 12px;
+ right: 20px;
+ font-size: 25px; }
+
+.edit-account-name-modal-title {
+ margin: 15px; }
+
+.edit-account-name-modal-save-button {
+ width: 33%;
+ height: 45px;
+ margin: 15px;
+ font-weight: 700;
+ margin-top: 25px; }
+
+.edit-account-name-modal-input {
+ width: 90%;
+ height: 50px;
+ text-align: left;
+ margin: 10px;
+ padding: 10px;
+ font-size: 18px; }
+
+.account-modal-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative;
+ padding: 5px 0 31px 0;
+ border: 1px solid #cdcdcd;
+ border-radius: 4px;
+ font-family: Roboto; }
+ .account-modal-container button {
+ cursor: pointer; }
+
+.account-modal-back {
+ color: #9b9b9b;
+ position: absolute;
+ top: 13px;
+ left: 17px;
+ cursor: pointer; }
+ .account-modal-back__text {
+ margin-top: 2px;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px; }
+
+.account-modal-close::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: #9b9b9b;
+ position: absolute;
+ top: 10px;
+ right: 12px;
+ cursor: pointer; }
+
+.account-modal-container .identicon {
+ position: relative;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ top: -32px;
+ margin-bottom: -32px; }
+
+.account-modal-container .qr-header {
+ margin-top: 9px;
+ font-size: 20px; }
+
+.account-modal-container .qr-wrapper {
+ margin-top: 5px; }
+
+.account-modal-container .ellip-address-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ border: 1px solid #dedede;
+ padding: 5px 10px;
+ font-family: Roboto;
+ margin-top: 7px;
+ width: 286px; }
+
+.account-modal-container .btn-clear {
+ min-height: 28px;
+ font-size: 14px;
+ border-color: #2f9ae0;
+ color: #2f9ae0;
+ border-radius: 2px;
+ -ms-flex-preferred-size: 100%;
+ flex-basis: 100%;
+ width: 75%;
+ margin-top: 17px;
+ padding: 10px 22px;
+ height: 44px;
+ width: 235px;
+ font-family: Roboto; }
+
+.account-modal-divider {
+ width: 100%;
+ height: 1px;
+ margin: 19px 0 8px 0;
+ background-color: #dedede; }
+
+.account-modal-container .account-name {
+ margin-top: 9px;
+ font-size: 20px; }
+
+.account-modal-container .modal-body-title {
+ margin-top: 16px;
+ margin-bottom: 16px;
+ font-size: 18px; }
+
+.account-modal__name {
+ margin-top: 9px;
+ font-size: 20px; }
+
+.private-key-password {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+
+.private-key-password-label, .private-key-password-error {
+ color: #5d5d5d;
+ font-size: 14px;
+ line-height: 18px;
+ margin-bottom: 10px; }
+
+.private-key-password-error {
+ color: #e91550;
+ margin-bottom: 0; }
+
+.private-key-password-input {
+ padding: 10px 0 13px 17px;
+ font-size: 16px;
+ line-height: 21px;
+ width: 291px;
+ height: 44px; }
+
+.private-key-password::-webkit-input-placeholder {
+ color: #9b9b9b;
+ font-family: Roboto; }
+
+.private-key-password-warning {
+ border-radius: 8px;
+ background-color: #FFF6F6;
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 15px;
+ color: #e91550;
+ width: 292px;
+ padding: 9px 15px;
+ margin-top: 18px;
+ font-family: Roboto; }
+
+.export-private-key-buttons {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+ .export-private-key-buttons .btn-clear {
+ width: 141px;
+ height: 54px; }
+ .export-private-key-buttons .btn-cancel {
+ margin-right: 15px;
+ border-color: #9b9b9b;
+ color: #5d5d5d; }
+
+.private-key-password-display-wrapper {
+ height: 80px;
+ width: 291px;
+ border: 1px solid #cdcdcd;
+ border-radius: 2px; }
+
+.private-key-password-display-textarea {
+ color: #e91550;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ border: none;
+ height: 75px;
+ width: 100%;
+ overflow: hidden;
+ resize: none;
+ padding: 9px 13px 8px;
+ text-transform: uppercase;
+ font-weight: 300; }
+
+.new-account-modal-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative;
+ border: 1px solid #dedede;
+ -webkit-box-shadow: 0 0 2px 2px #dedede;
+ box-shadow: 0 0 2px 2px #dedede;
+ font-family: Roboto; }
+
+.new-account-modal-header {
+ background: #f6f6f6;
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding: 30px;
+ font-size: 22px;
+ color: #1b344d;
+ height: 79px; }
+
+.modal-close-x::after {
+ content: '\00D7';
+ font-size: 2em;
+ color: #9b9b9b;
+ position: absolute;
+ top: 25px;
+ right: 17.5px;
+ font-family: sans-serif;
+ cursor: pointer; }
+
+.new-account-modal-content {
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ margin-top: 15px;
+ font-size: 17px;
+ color: #1b344d; }
+
+.new-account-modal-content.after-input {
+ margin-top: 15px;
+ line-height: 25px; }
+
+.new-account-input-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ width: 100%;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding-bottom: 2px;
+ margin-top: 13px; }
+
+.new-account-input {
+ padding: 15px;
+ padding-bottom: 20px;
+ border-radius: 8px;
+ border: 1px solid #dedede;
+ width: 100%;
+ font-size: 1em;
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 17px;
+ margin: 0 60px; }
+
+.new-account-input::-webkit-input-placeholder {
+ color: #9b9b9b; }
+
+.new-account-input:-moz-placeholder {
+ color: #9b9b9b;
+ opacity: 1; }
+
+.new-account-input::-moz-placeholder {
+ color: #9b9b9b;
+ opacity: 1; }
+
+.new-account-input:-ms-input-placeholder {
+ color: #9b9b9b; }
+
+.new-account-input::-ms-input-placeholder {
+ color: #9b9b9b; }
+
+.new-account-modal-content.button {
+ margin-top: 22px;
+ margin-bottom: 30px;
+ width: 113px;
+ height: 44px; }
+
+.new-account-modal-wrapper .btn-clear {
+ font-size: 14px;
+ font-weight: 700;
+ background: #fff;
+ border: 1px solid;
+ border-radius: 2px;
+ color: #4d4d4d;
+ -webkit-box-flex: 1;
+ -ms-flex: 1;
+ flex: 1; }
+
+.hide-token-confirmation {
+ min-height: 250.72px;
+ width: 374.49px;
+ border-radius: 4px;
+ background-color: #FFFFFF;
+ -webkit-box-shadow: 0 1px 7px 0 rgba(0, 0, 0, 0.5);
+ box-shadow: 0 1px 7px 0 rgba(0, 0, 0, 0.5); }
+ .hide-token-confirmation__container {
+ padding: 24px 27px 21px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .hide-token-confirmation__identicon {
+ margin-bottom: 10px; }
+ .hide-token-confirmation__symbol {
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 24px;
+ text-align: center;
+ margin-bottom: 7.5px; }
+ .hide-token-confirmation__title {
+ height: 30px;
+ width: 271.28px;
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 22px;
+ line-height: 30px;
+ text-align: center;
+ margin-bottom: 10.5px; }
+ .hide-token-confirmation__copy {
+ height: 41px;
+ width: 318px;
+ color: #5d5d5d;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px;
+ text-align: center; }
+ .hide-token-confirmation__buttons {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ margin-top: 15px;
+ width: 100%; }
+ .hide-token-confirmation__buttons button {
+ height: 44px;
+ width: 113px;
+ border: 1px solid #5d5d5d;
+ border-radius: 2px;
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 20px;
+ text-align: center;
+ margin-left: 4px;
+ margin-right: 4px; }
+
+/*
+ NewUI Container Elements
+ */
+.main-container {
+ z-index: 18;
+ font-family: Roboto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch; }
+
+.main-container::-webkit-scrollbar {
+ display: none; }
+
+.tx-view {
+ -webkit-box-flex: 63.5;
+ -ms-flex: 63.5 0 66.5%;
+ flex: 63.5 0 66.5%;
+ background: #fff; }
+ @media screen and (max-width: 575px) {
+ .tx-view .identicon-wrapper {
+ display: none; }
+ .tx-view .account-name {
+ display: none; } }
+
+.wallet-view {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-flex: 33.5;
+ -ms-flex: 33.5 1 33.5%;
+ flex: 33.5 1 33.5%;
+ width: 0;
+ background: #f6f6f6;
+ z-index: 200;
+ position: relative; }
+ @media screen and (min-width: 576px) {
+ .wallet-view {
+ overflow-y: scroll;
+ overflow-x: hidden; } }
+ .wallet-view .wallet-view-account-details {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .wallet-view__name-container {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ cursor: pointer;
+ width: 100%; }
+ .wallet-view__keyring-label {
+ height: 40px;
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 10px;
+ line-height: 40px;
+ text-align: right;
+ padding: 0 20px; }
+ .wallet-view__details-button {
+ color: #2f9ae0;
+ font-size: 10px;
+ line-height: 13px;
+ text-align: center;
+ border: 1px solid #2f9ae0;
+ border-radius: 10.5px;
+ background-color: transparent;
+ margin: 0 auto;
+ padding: 4px 12px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .wallet-view__address {
+ border-radius: 3px;
+ background-color: #dedede;
+ color: #5d5d5d;
+ font-size: 14px;
+ line-height: 12px;
+ padding: 4px 12px;
+ margin: 24px auto;
+ font-weight: 300;
+ cursor: pointer;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ @media screen and (max-width: 575px) {
+ .wallet-view__sidebar-close::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: #4d4d4d;
+ position: absolute;
+ top: 12px;
+ left: 12px;
+ cursor: pointer; } }
+ .wallet-view__add-token-button {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ color: #9b9b9b;
+ font-size: 14px;
+ line-height: 19px;
+ text-align: center;
+ margin: 36px auto;
+ border: 1px solid #9b9b9b;
+ border-radius: 2px;
+ font-weight: 300;
+ background: none;
+ padding: 9px 30px; }
+
+@media screen and (min-width: 576px) {
+ .wallet-view::-webkit-scrollbar {
+ display: none; } }
+
+.wallet-view-title-wrapper {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 25px;
+ flex: 0 0 25px; }
+
+.wallet-view-title {
+ margin-left: 15px;
+ font-size: 16px; }
+ @media screen and (max-width: 575px) {
+ .wallet-view-title {
+ display: none; } }
+
+.wallet-view.sidebar {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 230px;
+ flex: 1 0 230px;
+ background: #fafafa;
+ z-index: 26;
+ position: fixed;
+ top: 56px;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ will-change: transform;
+ overflow-y: auto;
+ -webkit-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 4px;
+ box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 4px;
+ width: 85%;
+ height: calc(100% - 56px); }
+
+.sidebar-overlay {
+ z-index: 25;
+ position: fixed;
+ height: 100%;
+ width: 100%;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ background-color: rgba(0, 0, 0, 0.3); }
+
+@media screen and (min-width: 576px) {
+ .lap-visible {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+ .phone-visible {
+ display: none; }
+ .main-container {
+ width: 85%;
+ height: 90vh;
+ -webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); } }
+
+@media screen and (min-width: 769px) {
+ .main-container {
+ width: 80%;
+ height: 82vh;
+ -webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); } }
+
+@media screen and (min-width: 1281px) {
+ .main-container {
+ width: 65%;
+ height: 82vh;
+ -webkit-box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); } }
+
+@media screen and (max-width: 575px) {
+ .lap-visible {
+ display: none; }
+ .phone-visible {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+ .main-container {
+ height: 100%;
+ width: 100%;
+ overflow-y: auto;
+ background-color: #fff; }
+ button.btn-clear {
+ width: 93px;
+ height: 50px;
+ font-size: .7em;
+ background: #fff;
+ border: 1px solid; } }
+
+.account-name {
+ font-size: 24px;
+ font-weight: 200;
+ line-height: 20px;
+ color: #5d5d5d;
+ margin-top: 8px;
+ margin-bottom: 24px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ width: 100%;
+ padding: 0 8px;
+ text-align: center; }
+
+.account-options-menu {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ margin: 5% 7% 0%; }
+
+.fiat-amount {
+ text-transform: uppercase; }
+
+.token-balance__amount {
+ padding-right: 6px; }
+
+.account-dropdown-name {
+ font-family: Roboto; }
+
+.account-dropdown-balance {
+ color: #9b9b9b;
+ line-height: 19px; }
+
+.account-dropdown-edit-button {
+ color: #9b9b9b;
+ font-family: Roboto; }
+ .account-dropdown-edit-button:hover {
+ color: #fff; }
+
+.account-list-item__top-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin-top: 10px;
+ margin-left: 8px;
+ position: relative; }
+
+.account-list-item__account-balances {
+ height: auto;
+ border: none;
+ background-color: transparent;
+ color: #9b9b9b;
+ margin-left: 34px;
+ margin-top: 4px;
+ position: relative; }
+
+.account-list-item__account-name {
+ font-size: 16px;
+ margin-left: 8px; }
+
+.account-list-item__icon {
+ position: absolute;
+ right: 12px;
+ top: 1px; }
+
+.account-list-item__account-primary-balance, .account-list-item__account-secondary-balance {
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ font-weight: 300; }
+
+.account-list-item__account-primary-balance {
+ color: #5d5d5d;
+ border: none;
+ outline: 0 !important; }
+
+.account-list-item__account-secondary-balance {
+ color: #9b9b9b; }
+
+.account-list-item__account-address {
+ margin-left: 35px;
+ width: 80%;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+
+.account-list-item__dropdown:hover {
+ background: rgba(222, 222, 222, 0.2);
+ cursor: pointer; }
+ .account-list-item__dropdown:hover input {
+ background: rgba(222, 222, 222, 0.1); }
+
+.send-screen-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ z-index: 25;
+ font-family: Roboto; }
+ @media screen and (max-width: 575px) {
+ .send-screen-wrapper {
+ width: 100%;
+ overflow-y: auto; } }
+ .send-screen-wrapper section {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.send-screen-card {
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ padding: 46px 40.5px 26px;
+ position: relative;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ width: 498px;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto; }
+ @media screen and (max-width: 575px) {
+ .send-screen-card {
+ top: 0;
+ width: 100%;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ padding: 12px; } }
+
+/* Send Screen */
+.send-screen section {
+ margin: 4px 16px; }
+
+.send-screen input {
+ width: 100%;
+ font-size: 12px; }
+
+.send-eth-icon {
+ border-radius: 50%;
+ width: 70px;
+ height: 70px;
+ border: 1px solid #dedede;
+ -webkit-box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2);
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2);
+ position: absolute;
+ top: -35px;
+ z-index: 25;
+ padding: 4px;
+ background-color: #fff; }
+ @media screen and (max-width: 575px) {
+ .send-eth-icon {
+ position: relative;
+ top: 0; } }
+
+.send-screen-input-wrapper {
+ width: 95%;
+ position: relative; }
+ .send-screen-input-wrapper .fa-bolt {
+ padding-right: 4px; }
+ .send-screen-input-wrapper .large-input {
+ border: 1px solid #9b9b9b;
+ border-radius: 4px;
+ margin: 4px 0 20px;
+ font-size: 16px;
+ line-height: 22.4px;
+ font-family: Roboto; }
+ .send-screen-input-wrapper .send-screen-gas-input {
+ border: 1px solid transparent; }
+ .send-screen-input-wrapper__error-message {
+ display: none; }
+ .send-screen-input-wrapper--error input,
+ .send-screen-input-wrapper--error .send-screen-gas-input {
+ border-color: #f00 !important; }
+ .send-screen-input-wrapper--error .send-screen-input-wrapper__error-message {
+ display: block;
+ position: absolute;
+ bottom: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: #f00; }
+ .send-screen-input-wrapper .send-screen-input-wrapper__error-message {
+ display: block;
+ position: absolute;
+ bottom: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: #f00; }
+
+.send-screen-input {
+ width: 100%; }
+
+.send-screen-gas-input {
+ width: 100%;
+ height: 41px;
+ border-radius: 3px;
+ background-color: #f3f3f3;
+ border-width: 0;
+ border-style: none;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding-left: 10px;
+ padding-right: 12px;
+ font-size: 16px;
+ color: #5d5d5d; }
+
+.send-screen-amount-labels {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between; }
+
+.send-screen-gas-labels {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between; }
+
+.currency-toggle__item {
+ color: #2f9ae0;
+ cursor: pointer; }
+ .currency-toggle__item--selected {
+ color: #000;
+ cursor: default; }
+
+.send-screen-gas-input-customize {
+ color: #2f9ae0;
+ font-size: 12px;
+ cursor: pointer; }
+
+.gas-tooltip-close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%; }
+
+.customize-gas-tooltip-container {
+ position: absolute;
+ bottom: 50px;
+ width: 237px;
+ height: 307px;
+ background-color: #fff;
+ opacity: 1;
+ -webkit-box-shadow: #dedede 0 0 5px;
+ box-shadow: #dedede 0 0 5px;
+ z-index: 1050;
+ padding: 13px 19px;
+ font-size: 16px;
+ border-radius: 4px;
+ font-family: "Lato";
+ font-weight: 500; }
+
+.gas-tooltip-arrow {
+ height: 25px;
+ width: 25px;
+ z-index: 1200;
+ background: #fff;
+ position: absolute;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ left: 107px;
+ top: 294px;
+ -webkit-box-shadow: 2px 2px 2px #dedede;
+ box-shadow: 2px 2px 2px #dedede; }
+
+.customize-gas-tooltip-container input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none; }
+
+.customize-gas-tooltip-container input[type="number"]:hover::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none; }
+
+.customize-gas-tooltip {
+ position: relative; }
+
+.gas-tooltip {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+
+.gas-tooltip-label {
+ font-size: 16px;
+ color: #4d4d4d; }
+
+.gas-tooltip-header {
+ padding-bottom: 12px; }
+
+.gas-tooltip-input-label {
+ margin-bottom: 5px; }
+
+.gas-tooltip-input-label i {
+ color: #aeaeae;
+ margin-left: 6px; }
+
+.customize-gas-input {
+ width: 178px;
+ height: 28px;
+ border: 1px solid #dedede;
+ font-size: 16px;
+ color: #1b344d;
+ padding-left: 8px; }
+
+.customize-gas-input-wrapper {
+ position: relative; }
+
+.gas-tooltip-input-detail {
+ position: absolute;
+ top: 4px;
+ right: 26px;
+ font-size: 12px;
+ color: #aeaeae; }
+
+.gas-tooltip-input-arrows {
+ position: absolute;
+ top: 0;
+ right: 4px;
+ width: 17px;
+ height: 28px;
+ border: 1px solid #dadada;
+ border-left: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ color: #9b9b9b;
+ font-size: .8em;
+ padding: 1px 4px;
+ cursor: pointer; }
+
+.token-gas__amount {
+ display: inline-block;
+ margin-right: 4px; }
+
+.token-gas__symbol {
+ display: inline-block; }
+
+.send-screen__title {
+ color: #5d5d5d;
+ font-size: 18px;
+ line-height: 29px; }
+
+.send-screen__subtitle {
+ margin: 10px 0 20px;
+ font-size: 14px;
+ line-height: 24px; }
+
+.send-screen__send-button, .send-screen__cancel-button {
+ width: 163px;
+ text-align: center; }
+
+.send-screen__send-button__disabled {
+ opacity: .5;
+ cursor: auto; }
+
+.send-token {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ z-index: 25;
+ font-family: Roboto; }
+ .send-token__content {
+ width: 498px;
+ height: 605px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ padding: 46px 40.5px 26px;
+ position: relative;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto; }
+ @media screen and (max-width: 575px) {
+ .send-token__content {
+ top: 0;
+ width: 100%;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ padding: 12px; } }
+ .send-token .identicon {
+ position: absolute;
+ top: -35px;
+ z-index: 25; }
+ @media screen and (max-width: 575px) {
+ .send-token .identicon {
+ position: relative;
+ top: 0;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; } }
+ .send-token__title {
+ color: #5d5d5d;
+ font-size: 18px;
+ line-height: 29px; }
+ .send-token__description, .send-token__balance-text, .send-token__token-symbol {
+ margin-top: 10px;
+ font-size: 14px;
+ line-height: 24px;
+ text-align: center; }
+ .send-token__token-balance {
+ font-size: 40px;
+ line-height: 40px;
+ margin-top: 13px; }
+ .send-token__token-balance .token-balance__amount {
+ padding-right: 12px; }
+ .send-token__button-group {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ @media screen and (max-width: 575px) {
+ .send-token__button-group {
+ margin-top: 24px; } }
+ .send-token__button-group button {
+ width: 163px; }
+
+.confirm-send-token__hero-amount-wrapper {
+ width: 100%; }
+
+.send-v2__container {
+ width: 380px;
+ border-radius: 8px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ z-index: 25;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-family: Roboto;
+ position: relative; }
+ @media screen and (max-width: 575px) {
+ .send-v2__container {
+ width: 100%;
+ top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; } }
+
+.send-v2__send-header-icon-container {
+ z-index: 25; }
+ @media screen and (max-width: 575px) {
+ .send-v2__send-header-icon-container {
+ position: relative;
+ top: 0; } }
+
+.send-v2__send-header-icon {
+ border-radius: 50%;
+ width: 48px;
+ height: 48px;
+ border: 1px solid #dedede;
+ z-index: 25;
+ padding: 4px;
+ background-color: #fff; }
+
+.send-v2__send-arrow-icon {
+ color: #f28930;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ position: absolute;
+ top: -2px;
+ left: 0;
+ font-size: 1.12em; }
+
+.send-v2__arrow-background {
+ background-color: #fff;
+ height: 14px;
+ width: 14px;
+ position: absolute;
+ top: 52px;
+ left: 199px;
+ border-radius: 50%;
+ z-index: 100; }
+ @media screen and (max-width: 575px) {
+ .send-v2__arrow-background {
+ top: 36px; } }
+
+.send-v2__header {
+ height: 88px;
+ width: 380px;
+ background-color: #e9edf0;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ @media screen and (max-width: 575px) {
+ .send-v2__header {
+ height: 59px;
+ width: 100vw; } }
+
+.send-v2__header-tip {
+ height: 25px;
+ width: 25px;
+ background: #e9edf0;
+ position: absolute;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ left: 178px;
+ top: 75px; }
+ @media screen and (max-width: 575px) {
+ .send-v2__header-tip {
+ top: 46px;
+ left: 0;
+ right: 0;
+ margin: 0 auto; } }
+
+.send-v2__title {
+ color: #5d5d5d;
+ font-size: 22px;
+ line-height: 29px;
+ text-align: center;
+ margin-top: 25px; }
+
+.send-v2__copy {
+ color: #808080;
+ font-size: 14px;
+ font-weight: 300;
+ line-height: 19px;
+ text-align: center;
+ margin-top: 10px;
+ width: 287px; }
+
+.send-v2__error {
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: #f00; }
+
+.send-v2__error-border {
+ color: #f00; }
+
+.send-v2__form {
+ margin: 13px 0;
+ width: 100%; }
+ @media screen and (max-width: 575px) {
+ .send-v2__form {
+ padding: 13px 0;
+ margin: 0;
+ height: 0;
+ overflow-y: auto;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; } }
+
+.send-v2__form-header, .send-v2__form-header-copy {
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.send-v2__form-row {
+ margin: 14.5px 18px 0px;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row;
+ flex-flow: row;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between; }
+
+.send-v2__form-field {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; }
+
+.send-v2__form-label {
+ color: #5d5d5d;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ width: 88px; }
+
+.send-v2__from-dropdown {
+ height: 73px;
+ width: 100%;
+ border: 1px solid #dedede;
+ border-radius: 4px;
+ background-color: #fff;
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ color: #4d4d4d;
+ position: relative; }
+ .send-v2__from-dropdown__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%; }
+ .send-v2__from-dropdown__list {
+ z-index: 1050;
+ position: absolute;
+ height: 220px;
+ width: 100%;
+ border: 1px solid #d2d8dd;
+ border-radius: 4px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ margin-top: 11px;
+ margin-left: -1px;
+ overflow-y: scroll; }
+
+.send-v2__to-autocomplete {
+ position: relative; }
+ .send-v2__to-autocomplete__down-caret {
+ position: absolute;
+ top: 18px;
+ right: 12px; }
+
+.send-v2__to-autocomplete__input, .send-v2__memo-text-area__input {
+ height: 54px;
+ width: 100%;
+ border: 1px solid #dedede;
+ border-radius: 4px;
+ background-color: #fff;
+ color: #9b9b9b;
+ padding: 10px;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ font-weight: 300; }
+
+.send-v2__amount-max {
+ color: #2f9ae0;
+ font-family: Roboto;
+ font-size: 12px;
+ left: 8px;
+ border: none;
+ cursor: pointer; }
+
+.send-v2__gas-fee-display {
+ width: 100%; }
+
+.send-v2__sliders-icon-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ height: 24px;
+ width: 24px;
+ border: 1px solid #2f9ae0;
+ border-radius: 4px;
+ background-color: #fff;
+ padding: 5px;
+ position: absolute;
+ right: 15px;
+ top: 14px;
+ cursor: pointer; }
+
+.send-v2__sliders-icon {
+ color: #2f9ae0; }
+
+.send-v2__memo-text-area__input {
+ padding: 6px 10px; }
+
+.send-v2__footer {
+ height: 92px;
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: space-evenly;
+ -ms-flex-pack: space-evenly;
+ justify-content: space-evenly;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border-top: 1px solid #dedede;
+ background: #fff;
+ padding: 0 12px; }
+
+.send-v2__next-btn, .send-v2__cancel-btn, .send-v2__next-btn__disabled {
+ width: 163px;
+ text-align: center;
+ height: 55px;
+ border-radius: 2px;
+ background-color: #fff;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 21px;
+ border: 1px solid;
+ margin: 0 4px; }
+
+.send-v2__next-btn, .send-v2__next-btn__disabled {
+ color: #2f9ae0;
+ border-color: #2f9ae0; }
+
+.send-v2__next-btn__disabled {
+ opacity: .5;
+ cursor: auto; }
+
+.send-v2__cancel-btn {
+ color: #9b9b9b;
+ border-color: #9b9b9b; }
+
+.send-v2__customize-gas {
+ border: 1px solid #D8D8D8;
+ border-radius: 4px;
+ background-color: #FFFFFF;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.14);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.14);
+ font-family: Roboto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column; }
+ @media screen and (max-width: 575px) {
+ .send-v2__customize-gas {
+ width: 100vw;
+ height: 100vh; } }
+ .send-v2__customize-gas__header {
+ height: 52px;
+ border-bottom: 1px solid #dedede;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-size: 22px; }
+ @media screen and (max-width: 575px) {
+ .send-v2__customize-gas__header {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; } }
+ .send-v2__customize-gas__title {
+ margin-left: 19.25px; }
+ .send-v2__customize-gas__close::after {
+ content: '\00D7';
+ font-size: 1.8em;
+ color: #9b9b9b;
+ font-family: sans-serif;
+ cursor: pointer;
+ margin-right: 19.25px; }
+ .send-v2__customize-gas__content {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ height: 100%; }
+ .send-v2__customize-gas__body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin-bottom: 24px; }
+ @media screen and (max-width: 575px) {
+ .send-v2__customize-gas__body {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; } }
+ .send-v2__customize-gas__footer {
+ height: 75px;
+ border-top: 1px solid #dedede;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-size: 22px;
+ position: relative; }
+ @media screen and (max-width: 575px) {
+ .send-v2__customize-gas__footer {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; } }
+ .send-v2__customize-gas__buttons {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ width: 181.75px;
+ margin-right: 21.25px; }
+ .send-v2__customize-gas__revert, .send-v2__customize-gas__cancel, .send-v2__customize-gas__save, .send-v2__customize-gas__save__error {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ cursor: pointer; }
+ .send-v2__customize-gas__revert {
+ color: #aeaeae;
+ font-size: 16px;
+ margin-left: 21.25px; }
+ .send-v2__customize-gas__cancel, .send-v2__customize-gas__save, .send-v2__customize-gas__save__error {
+ height: 34.64px;
+ width: 85.74px;
+ border: 1px solid #9b9b9b;
+ border-radius: 2px;
+ font-family: 'DIN OT';
+ font-size: 12px;
+ color: #9b9b9b; }
+ .send-v2__customize-gas__save__error {
+ opacity: 0.5;
+ cursor: auto; }
+ .send-v2__customize-gas__error-message {
+ display: block;
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ color: #f00; }
+
+.send-v2__gas-modal-card {
+ width: 360px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ padding-left: 20px; }
+ .send-v2__gas-modal-card__title {
+ height: 26px;
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 20px;
+ font-weight: 300;
+ line-height: 26px;
+ margin-top: 17px; }
+ .send-v2__gas-modal-card__copy {
+ height: 38px;
+ width: 314px;
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 19px;
+ margin-top: 17px; }
+ .send-v2__gas-modal-card .customize-gas-input-wrapper {
+ margin-top: 17px; }
+ .send-v2__gas-modal-card .customize-gas-input {
+ height: 54px;
+ width: 315px;
+ border: 1px solid #d2d8dd;
+ background-color: #fff;
+ padding-left: 15px; }
+ .send-v2__gas-modal-card .gas-tooltip-input-arrows {
+ width: 32px;
+ height: 54px;
+ border-left: 1px solid #dadada;
+ font-size: 18px;
+ color: #4d4d4d;
+ right: 0px;
+ padding: 1px 4px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-pack: distribute;
+ justify-content: space-around;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .send-v2__gas-modal-card input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none; }
+ .send-v2__gas-modal-card input[type="number"]:hover::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none; }
+
+.confirm-screen-container {
+ position: relative;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-family: Roboto;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ border-radius: 8px; }
+ @media screen and (max-width: 575px) {
+ .confirm-screen-container {
+ width: 100%; } }
+
+@media screen and (max-width: 575px) {
+ .notification .confirm-screen-wrapper {
+ height: calc(100vh - 85px); } }
+
+.confirm-screen-wrapper {
+ height: 100%;
+ width: 380px;
+ background-color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ z-index: 25;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-family: Roboto;
+ position: relative;
+ overflow-y: auto;
+ overflow-x: hidden;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px; }
+ @media screen and (max-width: 575px) {
+ .confirm-screen-wrapper {
+ width: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ height: calc(100vh - 58px - 85px);
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; } }
+
+.confirm-screen-wrapper > .confirm-screen-total-box {
+ margin-left: 10px;
+ margin-right: 10px; }
+
+.confirm-screen-wrapper > .confirm-memo-wrapper {
+ margin: 0; }
+
+.confirm-screen-header {
+ height: 88px;
+ background-color: #e9edf0;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-size: 22px;
+ line-height: 29px;
+ width: 100%;
+ padding: 25px 0;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ @media screen and (max-width: 575px) {
+ .confirm-screen-header {
+ font-size: 20px; } }
+
+.confirm-screen-header-tip {
+ height: 25px;
+ width: 25px;
+ background: #e9edf0;
+ position: absolute;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ top: 71px;
+ left: 0;
+ right: 0;
+ margin: 0 auto; }
+
+.confirm-screen-title {
+ line-height: 27px; }
+ @media screen and (max-width: 575px) {
+ .confirm-screen-title {
+ margin-left: 22px;
+ margin-right: 8px; } }
+
+.confirm-screen-back-button {
+ background: transparent;
+ border: 1px solid #2f9ae0;
+ left: 24px;
+ position: absolute;
+ text-align: center;
+ color: #2f9ae0;
+ padding: 6px 13px 7px 12px;
+ border-radius: 2px;
+ height: 30px;
+ width: 54px; }
+ @media screen and (max-width: 575px) {
+ .confirm-screen-back-button {
+ margin-right: 12px; } }
+
+.confirm-screen-account-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.confirm-screen-account-name {
+ margin-top: 12px;
+ font-size: 14px;
+ line-height: 19px;
+ color: #5d5d5d;
+ text-align: center; }
+
+.confirm-screen-row-info {
+ font-size: 16px;
+ line-height: 21px; }
+
+.confirm-screen-account-number {
+ font-size: 10px;
+ line-height: 16px;
+ color: #9b9b9b;
+ text-align: center;
+ height: 16px; }
+
+.confirm-send-ether i.fa-arrow-right,
+.confirm-send-token i.fa-arrow-right {
+ -ms-flex-item-align: start;
+ align-self: start;
+ margin: 24px 14px 0 !important; }
+
+.confirm-screen-identicons {
+ margin-top: 24px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .confirm-screen-identicons i.fa-arrow-right {
+ -ms-flex-item-align: start;
+ align-self: start;
+ margin: 42px 14px 0; }
+ .confirm-screen-identicons i.fa-file-text-o {
+ font-size: 60px;
+ margin: 16px 8px 0 8px;
+ text-align: center; }
+
+.confirm-screen-sending-to-message {
+ text-align: center;
+ font-size: 16px;
+ margin-top: 30px;
+ font-family: 'DIN NEXT Light'; }
+
+.confirm-screen-send-amount {
+ color: #5d5d5d;
+ margin-top: 12px;
+ text-align: center;
+ font-size: 40px;
+ font-weight: 300;
+ line-height: 53px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.confirm-screen-send-amount-currency {
+ font-size: 20px;
+ line-height: 20px;
+ text-align: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.confirm-memo-wrapper {
+ min-height: 24px;
+ width: 100%;
+ border-bottom: 1px solid #dedede;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.confirm-screen-send-memo {
+ color: #5d5d5d;
+ font-size: 16px;
+ line-height: 19px;
+ font-weight: 400; }
+
+.confirm-screen-label {
+ font-size: 18px;
+ line-height: 40px;
+ color: #5d5d5d;
+ text-align: left; }
+
+section .confirm-screen-account-name,
+section .confirm-screen-account-number,
+.confirm-screen-row-info,
+.confirm-screen-row-detail {
+ text-align: left; }
+
+.confirm-screen-rows {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ width: 100%;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.confirm-screen-section-column {
+ -webkit-box-flex: .5;
+ -ms-flex: .5;
+ flex: .5; }
+
+.confirm-screen-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ border-bottom: 1px solid #dedede;
+ width: 100%;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 12px;
+ padding-left: 35px;
+ font-size: 16px;
+ line-height: 22px;
+ font-weight: 300; }
+
+.confirm-screen-row-detail {
+ font-size: 12px;
+ line-height: 16px;
+ color: #9b9b9b; }
+
+.confirm-screen-total-box {
+ background-color: #f6f6f6;
+ padding: 20px;
+ padding-left: 35px;
+ border-bottom: 1px solid #dedede; }
+ .confirm-screen-total-box .confirm-screen-label {
+ line-height: 18px; }
+ .confirm-screen-total-box .confirm-screen-row-detail {
+ color: #5d5d5d; }
+ .confirm-screen-total-box__subtitle {
+ font-size: 12px;
+ line-height: 22px; }
+ .confirm-screen-total-box .confirm-screen-row-info {
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 21px; }
+
+.confirm-screen-confirm-button {
+ height: 62px;
+ border-radius: 2px;
+ background-color: #02c9b1;
+ font-size: 16px;
+ color: #fff;
+ text-align: center;
+ font-family: Roboto;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ border-width: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ font-weight: 300;
+ margin: 0 8px; }
+
+.btn-light.confirm-screen-cancel-button {
+ height: 62px;
+ background: none;
+ border: none;
+ opacity: 1;
+ font-family: Roboto;
+ border-width: 0;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ font-size: 16px;
+ line-height: 32px;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ cursor: pointer;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ font-weight: 300;
+ margin: 0 8px; }
+
+#pending-tx-form {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ background-color: #fff;
+ padding: 12px 18px;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ width: 100%; }
+ @media screen and (max-width: 575px) {
+ #pending-tx-form {
+ border-top: 1px solid #dedede;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; } }
+
+.loading-overlay {
+ left: 0px;
+ z-index: 50;
+ position: absolute;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ width: 100%;
+ background: rgba(255, 255, 255, 0.8); }
+ @media screen and (max-width: 575px) {
+ .loading-overlay {
+ margin-top: 56px;
+ height: calc(100% - 56px); } }
+ @media screen and (min-width: 576px) {
+ .loading-overlay {
+ margin-top: 75px;
+ height: calc(100% - 75px); } }
+
+@media screen and (max-width: 575px) {
+ .hero-balance {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin: .3em .9em 0;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; } }
+
+@media screen and (min-width: 576px) {
+ .hero-balance {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin: 2.8em 2.37em .8em; } }
+
+.hero-balance .balance-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin: 0;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ @media screen and (max-width: 575px) {
+ .hero-balance .balance-container {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; } }
+ @media screen and (min-width: 576px) {
+ .hero-balance .balance-container {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-flex: 3;
+ -ms-flex-positive: 3;
+ flex-grow: 3; } }
+
+@media screen and (max-width: 575px) {
+ .hero-balance .balance-display {
+ text-align: center; }
+ .hero-balance .balance-display .token-amount {
+ font-size: 175%;
+ margin-top: 12.5%; }
+ .hero-balance .balance-display .fiat-amount {
+ font-size: 115%;
+ margin-top: 8.5%;
+ color: #a0a0a0; } }
+
+@media screen and (min-width: 576px) {
+ .hero-balance .balance-display {
+ margin-left: 3%;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start; }
+ .hero-balance .balance-display .token-amount {
+ font-size: 135%; }
+ .hero-balance .balance-display .fiat-amount {
+ margin-top: .25%;
+ font-size: 105%; } }
+
+.hero-balance .balance-icon {
+ border-radius: 25px;
+ width: 45px;
+ height: 45px;
+ border: 1px solid #dedede; }
+
+@media screen and (max-width: 575px) {
+ .hero-balance .hero-balance-buttons {
+ width: 100%;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ padding: 16px 0; } }
+
+@media screen and (min-width: 576px) {
+ .hero-balance .hero-balance-buttons {
+ -webkit-box-flex: 2;
+ -ms-flex-positive: 2;
+ flex-grow: 2;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end; } }
+
+.hero-balance .hero-balance-buttons button.btn-clear {
+ background: #fff;
+ border: 1px solid;
+ border-radius: 2px;
+ font-size: 12px; }
+ @media screen and (max-width: 575px) {
+ .hero-balance .hero-balance-buttons button.btn-clear {
+ border-color: #2f9ae0;
+ color: #2f9ae0;
+ height: 36px; } }
+ @media screen and (min-width: 576px) {
+ .hero-balance .hero-balance-buttons button.btn-clear {
+ border-color: #2f9ae0;
+ color: #2f9ae0;
+ padding: 0;
+ width: 85px;
+ height: 34px; } }
+
+.wallet-balance-wrapper {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ -webkit-transition: linear 200ms;
+ transition: linear 200ms;
+ background: rgba(231, 231, 231, 0); }
+ .wallet-balance-wrapper--active {
+ background: #e7e7e7; }
+
+.wallet-balance {
+ background: inherit;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ cursor: pointer;
+ border-top: 1px solid #e7e7e7; }
+ .wallet-balance .balance-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin: 20px 24px;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-flex: 3;
+ -ms-flex-positive: 3;
+ flex-grow: 3; }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .wallet-balance .balance-container {
+ margin: 10% 4%; } }
+ .wallet-balance .balance-display {
+ margin-left: 15px;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start; }
+ .wallet-balance .balance-display .token-amount {
+ font-size: 135%; }
+ .wallet-balance .balance-display .fiat-amount {
+ margin-top: .25%;
+ font-size: 105%; }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .wallet-balance .balance-display {
+ margin-left: 4%; }
+ .wallet-balance .balance-display .token-amount {
+ font-size: 105%; }
+ .wallet-balance .balance-display .fiat-amount {
+ font-size: 95%; } }
+ .wallet-balance .balance-icon {
+ border-radius: 25px;
+ width: 45px;
+ height: 45px;
+ border: 1px solid #dedede; }
+
+.tx-list-container {
+ height: 87.5%; }
+ @media screen and (min-width: 576px) {
+ .tx-list-container {
+ overflow-y: scroll; } }
+
+.tx-list-header {
+ text-transform: capitalize; }
+
+@media screen and (max-width: 575px) {
+ .tx-list-header-wrapper {
+ margin-top: .2em;
+ margin-bottom: .6em;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .tx-list-header {
+ -ms-flex-item-align: center;
+ align-self: center;
+ font-size: 12px;
+ color: #9b9b9b;
+ font-family: Roboto;
+ text-transform: uppercase; } }
+
+@media screen and (min-width: 576px) {
+ .tx-list-header-wrapper {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 55px;
+ flex: 0 0 55px; }
+ .tx-list-header {
+ font-size: 16px;
+ margin: 1.5em 2.37em; }
+ .tx-list-container::-webkit-scrollbar {
+ display: none; } }
+
+.tx-list-content-divider {
+ height: 1px;
+ background: #e7e7e7;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 1px;
+ flex: 0 0 1px; }
+ @media screen and (max-width: 575px) {
+ .tx-list-content-divider {
+ margin: .1em 0; } }
+ @media screen and (min-width: 576px) {
+ .tx-list-content-divider {
+ margin: .1em 2.37em; } }
+
+.tx-list-item-wrapper {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ width: 0;
+ -webkit-box-align: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap; }
+ @media screen and (max-width: 575px) {
+ .tx-list-item-wrapper {
+ padding: 0 1.3em .8em; } }
+ @media screen and (min-width: 576px) {
+ .tx-list-item-wrapper {
+ padding-bottom: 12px; } }
+
+.tx-list-clickable {
+ cursor: pointer; }
+ .tx-list-clickable:hover {
+ background: rgba(222, 222, 222, 0.2); }
+
+.tx-list-pending-item-container {
+ cursor: pointer;
+ opacity: .5; }
+
+.tx-list-date-wrapper {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; }
+ @media screen and (max-width: 575px) {
+ .tx-list-date-wrapper {
+ margin-top: 6px; } }
+ @media screen and (min-width: 576px) {
+ .tx-list-date-wrapper {
+ margin-top: 12px; } }
+
+.tx-list-content-wrapper {
+ -webkit-box-align: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch;
+ margin-bottom: 4px;
+ margin-top: 2px;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap; }
+ @media screen and (max-width: 575px) {
+ .tx-list-content-wrapper {
+ font-size: 12px; }
+ .tx-list-content-wrapper .tx-list-status {
+ font-size: 14px !important; }
+ .tx-list-content-wrapper .tx-list-account {
+ font-size: 14px !important; }
+ .tx-list-content-wrapper .tx-list-value {
+ font-size: 14px;
+ line-height: 18px; }
+ .tx-list-content-wrapper .tx-list-fiat-value {
+ font-size: 12px;
+ line-height: 16px; } }
+
+.tx-list-date {
+ color: #9b9b9b;
+ font-size: 12px;
+ font-family: Roboto; }
+
+.tx-list-identicon-wrapper {
+ -ms-flex-item-align: center;
+ align-self: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ margin-right: 16px; }
+
+.tx-list-account-and-status-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ width: 0; }
+ @media screen and (max-width: 575px) {
+ .tx-list-account-and-status-wrapper {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ -ms-flex-item-align: center;
+ align-self: center; }
+ .tx-list-account-and-status-wrapper .tx-list-account-wrapper {
+ height: 18px; }
+ .tx-list-account-and-status-wrapper .tx-list-account-wrapper .tx-list-account {
+ line-height: 14px; } }
+ @media screen and (min-width: 576px) {
+ .tx-list-account-and-status-wrapper {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .tx-list-account-and-status-wrapper .tx-list-account-wrapper {
+ -webkit-box-flex: 1.3;
+ -ms-flex: 1.3 2 auto;
+ flex: 1.3 2 auto;
+ min-width: 153px; }
+ .tx-list-account-and-status-wrapper .tx-list-status-wrapper {
+ -webkit-box-flex: 6;
+ -ms-flex: 6 6 auto;
+ flex: 6 6 auto; } }
+ .tx-list-account-and-status-wrapper .tx-list-account {
+ font-size: 16px;
+ color: #5d5d5d; }
+ .tx-list-account-and-status-wrapper .tx-list-status {
+ color: #9b9b9b;
+ font-size: 16px;
+ text-transform: capitalize; }
+ .tx-list-account-and-status-wrapper .tx-list-status--rejected,
+ .tx-list-account-and-status-wrapper .tx-list-status--failed {
+ color: #d0021b; }
+
+.tx-list-item {
+ border-top: 1px solid #e7e7e7;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap; }
+ @media screen and (min-width: 576px) {
+ .tx-list-item {
+ margin: 0 2.37em; } }
+ .tx-list-item:last-of-type {
+ border-bottom: 1px solid #e7e7e7;
+ margin-bottom: 32px; }
+ .tx-list-item__wrapper {
+ -ms-flex-item-align: center;
+ align-self: center;
+ -webkit-box-flex: 2;
+ -ms-flex: 2 2 auto;
+ flex: 2 2 auto;
+ color: #9b9b9b; }
+ .tx-list-item__wrapper .tx-list-value {
+ font-size: 16px;
+ text-align: right; }
+ .tx-list-item__wrapper .tx-list-value--confirmed {
+ color: #02c9b1; }
+ .tx-list-item__wrapper .tx-list-fiat-value {
+ font-size: 12px;
+ text-align: right; }
+ .tx-list-item--empty {
+ text-align: center;
+ border-bottom: none !important;
+ padding: 16px; }
+
+.tx-list-details-wrapper {
+ overflow: hidden;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 35%;
+ flex: 0 0 35%; }
+
+.tx-list-value {
+ font-size: 16px;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden; }
+
+.tx-list-fiat-value {
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden; }
+
+.tx-list-value--confirmed {
+ color: #02c9b1; }
+
+/* stylelint-disable */
+/*
+App Sections
+ TODO: Move into separate files.
+*/
+/* initialize */
+textarea.twelve-word-phrase {
+ padding: 12px;
+ width: 300px;
+ height: 140px;
+ font-size: 16px;
+ background: #fff;
+ resize: none; }
+
+.initialize-screen hr {
+ width: 60px;
+ margin: 12px;
+ border-color: #f7861c;
+ border-style: solid; }
+
+.initialize-screen label {
+ margin-top: 20px; }
+
+.initialize-screen button.create-vault {
+ margin-top: 40px; }
+
+.initialize-screen .warning {
+ font-size: 14px;
+ margin: 0 16px; }
+
+/* unlock */
+.error {
+ color: #f7861c;
+ margin-bottom: 9px; }
+
+.warning {
+ color: #ffae00; }
+
+.lock {
+ width: 50px;
+ height: 50px; }
+
+.lock.locked {
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5);
+ opacity: 0;
+ -webkit-transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in, -webkit-transform 400ms ease-in; }
+
+.lock.unlocked {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ -webkit-transition: opacity 500ms ease-out, background 200ms ease-in, -webkit-transform 500ms ease-out;
+ transition: opacity 500ms ease-out, background 200ms ease-in, -webkit-transform 500ms ease-out;
+ transition: opacity 500ms ease-out, transform 500ms ease-out, background 200ms ease-in;
+ transition: opacity 500ms ease-out, transform 500ms ease-out, background 200ms ease-in, -webkit-transform 500ms ease-out; }
+
+.lock.locked .lock-top {
+ -webkit-transform: scaleX(1) translateX(0);
+ transform: scaleX(1) translateX(0);
+ -webkit-transition: -webkit-transform 250ms ease-in;
+ transition: -webkit-transform 250ms ease-in;
+ transition: transform 250ms ease-in;
+ transition: transform 250ms ease-in, -webkit-transform 250ms ease-in; }
+
+.lock.unlocked .lock-top {
+ -webkit-transform: scaleX(-1) translateX(-12px);
+ transform: scaleX(-1) translateX(-12px);
+ -webkit-transition: -webkit-transform 250ms ease-in;
+ transition: -webkit-transform 250ms ease-in;
+ transition: transform 250ms ease-in;
+ transition: transform 250ms ease-in, -webkit-transform 250ms ease-in; }
+
+.lock.unlocked:hover {
+ border-radius: 4px;
+ background: #e5e5e5;
+ border: 1px solid #b1b1b1; }
+
+.lock.unlocked:active {
+ background: #c3c3c3; }
+
+.section-title .fa-arrow-left {
+ margin: -2px 8px 0px -8px; }
+
+.unlock-screen #metamask-mascot-container {
+ margin-top: 24px; }
+
+.unlock-screen h1 {
+ margin-top: -28px;
+ margin-bottom: 42px; }
+
+.unlock-screen input[type=password] {
+ width: 260px; }
+
+.sizing-input {
+ font-size: 14px;
+ height: 30px;
+ padding-left: 5px; }
+
+.editable-label {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+
+/* Webkit */
+.unlock-screen input::-webkit-input-placeholder {
+ text-align: center;
+ font-size: 1.2em; }
+
+/* Firefox 18- */
+.unlock-screen input:-moz-placeholder {
+ text-align: center;
+ font-size: 1.2em; }
+
+/* Firefox 19+ */
+.unlock-screen input::-moz-placeholder {
+ text-align: center;
+ font-size: 1.2em; }
+
+/* IE */
+.unlock-screen input:-ms-input-placeholder {
+ text-align: center;
+ font-size: 1.2em; }
+
+/* accounts */
+.accounts-section {
+ margin: 0 0px; }
+
+.accounts-section .horizontal-line {
+ margin: 0 18px; }
+
+.accounts-list-option {
+ height: 120px; }
+
+.accounts-list-option .identicon-wrapper {
+ width: 100px; }
+
+.unconftx-link {
+ margin-top: 24px;
+ cursor: pointer; }
+
+.unconftx-link .fa-arrow-right {
+ margin: 0 -8px 0px 8px; }
+
+/* identity panel */
+.identity-panel {
+ font-weight: 500; }
+
+.identity-panel .identicon-wrapper {
+ margin: 4px;
+ margin-top: 8px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.identity-panel .identicon-wrapper span {
+ margin: 0 auto; }
+
+.identity-panel .identity-data {
+ margin: 8px 8px 8px 18px; }
+
+.identity-panel i {
+ margin-top: 32px;
+ margin-right: 6px;
+ color: #b9b9b9; }
+
+.identity-panel .arrow-right {
+ padding-left: 18px;
+ width: 42px;
+ min-width: 18px;
+ height: 100%; }
+
+.identity-copy.flex-column {
+ -webkit-box-flex: .25;
+ -ms-flex: .25 0 auto;
+ flex: .25 0 auto;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+
+/* accounts screen */
+.identity-section .identity-panel {
+ background: #e9e9e9;
+ border-bottom: 1px solid #b1b1b1;
+ cursor: pointer; }
+
+.identity-section .identity-panel.selected {
+ background: #fff;
+ color: #f3c83e; }
+
+.identity-section .identity-panel.selected .identicon {
+ border-color: #ffa500; }
+
+.identity-section .accounts-list-option:hover,
+.identity-section .accounts-list-option.selected {
+ background: #fff; }
+
+/* account detail screen */
+.account-detail-section {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ overflow-y: auto;
+ -webkit-box-orient: inherit;
+ -webkit-box-direction: inherit;
+ -ms-flex-direction: inherit;
+ flex-direction: inherit; }
+
+.grow-tenx {
+ -webkit-box-flex: 10;
+ -ms-flex-positive: 10;
+ flex-grow: 10; }
+
+.unapproved-tx-icon {
+ height: 16px;
+ width: 16px;
+ background: #2faef4;
+ border-color: #aeaeae;
+ border-radius: 13px; }
+
+.edit-text {
+ height: 100%;
+ visibility: hidden; }
+
+.editing-label {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ margin-left: 50px;
+ margin-bottom: 2px;
+ font-size: 11px;
+ text-rendering: geometricPrecision;
+ color: #f7861c; }
+
+.name-label:hover .edit-text {
+ visibility: visible; }
+
+/* tx confirm */
+.unconftx-section input[type=password] {
+ height: 22px;
+ padding: 2px;
+ margin: 12px;
+ margin-bottom: 24px;
+ border-radius: 4px;
+ border: 2px solid #f3c83e;
+ background: #faf6f0; }
+
+/* Ether Balance Widget */
+.ether-balance-amount {
+ color: #f7861c; }
+
+.ether-balance-label {
+ color: #aba9aa; }
+
+/* Info screen */
+.info-gray {
+ font-family: Roboto;
+ text-transform: uppercase;
+ color: #aeaeae; }
+
+.icon-size {
+ width: 20px; }
+
+.info {
+ font-family: Roboto, Arial;
+ padding-bottom: 10px;
+ display: inline-block;
+ padding-left: 5px; }
+
+/* buy eth warning screen */
+.custom-radios {
+ -ms-flex-pack: distribute;
+ justify-content: space-around;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+
+.custom-radio-selected {
+ width: 17px;
+ height: 17px;
+ border: solid;
+ border-style: double;
+ border-radius: 15px;
+ border-width: 5px;
+ background: #f7861c;
+ border-color: #f7f7f7; }
+
+.custom-radio-inactive {
+ width: 14px;
+ height: 14px;
+ border: solid;
+ border-width: 1px;
+ border-radius: 24px;
+ border-color: #aeaeae; }
+
+.radio-titles {
+ color: #f7861c; }
+
+.eth-warning {
+ -webkit-transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in, -webkit-transform 400ms ease-in; }
+
+.buy-subview {
+ -webkit-transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, -webkit-transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+ transition: opacity 400ms ease-in, transform 400ms ease-in, -webkit-transform 400ms ease-in; }
+
+.input-container:hover .edit-text {
+ visibility: visible; }
+
+.buy-inputs {
+ font-family: Roboto;
+ font-size: 13px;
+ height: 20px;
+ background: transparent;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border: solid;
+ border-color: transparent;
+ border-width: .5px;
+ border-radius: 2px; }
+
+.input-container:hover .buy-inputs {
+ -webkit-box-sizing: inherit;
+ box-sizing: inherit;
+ border: solid;
+ border-color: #f7861c;
+ border-width: .5px;
+ border-radius: 2px; }
+
+.buy-inputs:focus {
+ border: solid;
+ border-color: #f7861c;
+ border-width: .5px;
+ border-radius: 2px; }
+
+.activeForm {
+ background: #f7f7f7;
+ border: none;
+ border-radius: 8px 8px 0px 0px;
+ width: 50%;
+ text-align: center;
+ padding-bottom: 4px; }
+
+.inactiveForm {
+ border: none;
+ border-radius: 8px 8px 0px 0px;
+ width: 50%;
+ text-align: center;
+ padding-bottom: 4px; }
+
+.ex-coins {
+ font-family: Roboto;
+ text-transform: uppercase;
+ text-align: center;
+ font-size: 33px;
+ width: 118px;
+ height: 42px;
+ padding: 1px;
+ color: #4d4d4d; }
+
+.marketinfo {
+ font-family: Roboto;
+ color: #aeaeae;
+ font-size: 15px;
+ line-height: 17px; }
+
+#fromCoin::-webkit-calendar-picker-indicator {
+ display: none; }
+
+#coinList {
+ width: 400px;
+ height: 500px;
+ overflow: scroll; }
+
+.icon-control .fa-refresh {
+ visibility: hidden; }
+
+.icon-control:hover .fa-refresh {
+ visibility: visible; }
+
+.icon-control:hover .fa-chevron-right {
+ visibility: hidden; }
+
+.inactive {
+ color: #aeaeae; }
+
+.inactive button {
+ background: #aeaeae;
+ color: #fff; }
+
+.qr-ellip-address, .ellip-address {
+ overflow: hidden;
+ text-overflow: ellipsis; }
+
+.qr-header {
+ font-size: 25px;
+ margin-top: 40px; }
+
+.qr-message {
+ font-size: 12px;
+ color: #f7861c; }
+
+div.message-container > div:first-child {
+ margin-top: 18px;
+ font-size: 15px;
+ color: #4d4d4d; }
+
+.pop-hover:hover {
+ -webkit-transform: scale(1.1);
+ transform: scale(1.1); }
+
+/* stylelint-enable */
+.token-list-item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 20px 24px;
+ cursor: pointer;
+ -webkit-transition: linear 200ms;
+ transition: linear 200ms;
+ background-color: rgba(231, 231, 231, 0);
+ position: relative; }
+ .token-list-item__token-balance {
+ font-size: 130%; }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .token-list-item__token-balance {
+ font-size: 105%; } }
+ .token-list-item__fiat-amount {
+ margin-top: .25%;
+ font-size: 105%;
+ text-transform: uppercase; }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .token-list-item__fiat-amount {
+ font-size: 95%; } }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .token-list-item {
+ padding: 10% 4%; } }
+ .token-list-item--active {
+ background-color: #e7e7e7; }
+ .token-list-item__identicon {
+ margin-right: 15px;
+ border: '1px solid #dedede'; }
+ @media screen and (min-width: 576px) and (max-width: 890px) {
+ .token-list-item__identicon {
+ margin-right: 4%; } }
+ .token-list-item__ellipsis {
+ line-height: 45px; }
+ .token-list-item__balance-wrapper {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; }
+
+.token-menu-dropdown {
+ height: 55px;
+ width: 191px;
+ border-radius: 4px;
+ background-color: rgba(0, 0, 0, 0.82);
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
+ position: fixed;
+ margin-top: 20px;
+ margin-left: 105px;
+ z-index: 2000; }
+ .token-menu-dropdown__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 2100;
+ width: 100%;
+ height: 100%;
+ cursor: default; }
+ .token-menu-dropdown__container {
+ padding: 16px 34px 32px;
+ z-index: 2200;
+ position: relative; }
+ .token-menu-dropdown__options {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+ .token-menu-dropdown__option {
+ color: #fff;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ text-align: center; }
+
+.add-token {
+ width: 498px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative;
+ z-index: 12;
+ font-family: 'DIN Next Light'; }
+ .add-token__wrapper {
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .add-token__title-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 30px 60px 12px;
+ border-bottom: 1px solid #efefef;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .add-token__title {
+ color: #5d5d5d;
+ font-size: 20px;
+ line-height: 26px;
+ text-align: center;
+ font-weight: 600;
+ margin-bottom: 12px; }
+ .add-token__description {
+ text-align: center; }
+ .add-token__description + .add-token__description {
+ margin-top: 24px; }
+ .add-token__confirmation-description {
+ margin: 12px 0; }
+ .add-token__content-container {
+ width: 100%;
+ border-bottom: 1px solid #efefef; }
+ .add-token__input-container {
+ padding: 11px 0;
+ width: 263px;
+ margin: 0 auto;
+ position: relative; }
+ .add-token__search-input-error-message {
+ position: absolute;
+ bottom: -10px;
+ font-size: 12px;
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ color: #f00; }
+ .add-token__input {
+ width: 100%;
+ border: 2px solid #efefef;
+ border-radius: 4px;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px; }
+ .add-token__input::-webkit-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__input:-ms-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__input::-ms-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__input::placeholder {
+ color: #cdcdcd; }
+ .add-token__footers {
+ width: 100%; }
+ .add-token__add-custom {
+ color: #5d5d5d;
+ font-size: 18px;
+ line-height: 24px;
+ text-align: center;
+ padding: 12px 0;
+ font-weight: 600;
+ cursor: pointer; }
+ .add-token__add-custom:hover {
+ background-color: rgba(0, 0, 0, 0.05); }
+ .add-token__add-custom:active {
+ background-color: rgba(0, 0, 0, 0.1); }
+ .add-token__add-custom .fa {
+ position: absolute;
+ right: 24px;
+ font-size: 24px;
+ line-height: 24px; }
+ .add-token__add-custom-form {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ margin: 8px 0 51px; }
+ .add-token__add-custom-field {
+ width: 290px;
+ margin: 0 auto;
+ position: relative; }
+ .add-token__add-custom-field--error .add-token__add-custom-input {
+ border-color: #f00; }
+ .add-token__add-custom-error-message {
+ position: absolute;
+ bottom: -21px;
+ font-size: 12px;
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ color: #f00; }
+ .add-token__add-custom-label {
+ font-size: 16px;
+ line-height: 21px;
+ margin-bottom: 8px; }
+ .add-token__add-custom-input {
+ width: 100%;
+ border: 1px solid #cdcdcd;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px; }
+ .add-token__add-custom-input::-webkit-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__add-custom-input:-ms-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__add-custom-input::-ms-input-placeholder {
+ color: #cdcdcd; }
+ .add-token__add-custom-input::placeholder {
+ color: #cdcdcd; }
+ .add-token__add-custom-field + .add-token__add-custom-field {
+ margin-top: 21px; }
+ .add-token__buttons {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ margin: 30px 0 51px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .add-token__token-icons-container {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap; }
+ .add-token__token-wrapper {
+ -webkit-transition: 200ms ease-in-out;
+ transition: 200ms ease-in-out;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 42.5%;
+ flex: 0 0 42.5%;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 12px;
+ margin: 2.5%;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border-radius: 10px;
+ cursor: pointer;
+ border: 2px solid transparent;
+ position: relative; }
+ .add-token__token-wrapper:hover {
+ border: 2px solid rgba(122, 201, 253, 0.5); }
+ .add-token__token-wrapper--selected {
+ border: 2px solid #7ac9fd !important; }
+ .add-token__token-wrapper--disabled {
+ opacity: .4;
+ pointer-events: none; }
+ .add-token__token-data {
+ -ms-flex-item-align: start;
+ align-self: flex-start; }
+ .add-token__token-name {
+ font-size: 14px;
+ line-height: 19px; }
+ .add-token__token-symbol {
+ font-size: 22px;
+ line-height: 29px;
+ font-weight: 600; }
+ .add-token__token-icon {
+ width: 60px;
+ height: 60px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+ border-radius: 50%;
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.24);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.24);
+ margin-right: 12px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .add-token__token-message {
+ position: absolute;
+ color: #02c9b1;
+ font-size: 11px;
+ bottom: 0;
+ left: 85px; }
+ .add-token__confirmation-token-list {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap; }
+ .add-token__confirmation-token-list .token-balance {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start; }
+ .add-token__confirmation-token-list .token-balance__amount {
+ color: #5d5d5d;
+ font-size: 43px;
+ font-weight: 300;
+ line-height: 43px;
+ margin-right: 8px; }
+ .add-token__confirmation-token-list .token-balance__symbol {
+ color: #5d5d5d;
+ font-size: 16px;
+ line-height: 24px; }
+ .add-token__confirmation-title {
+ padding: 30px 120px 12px; }
+ @media screen and (max-width: 575px) {
+ .add-token__confirmation-title {
+ padding: 20px 0;
+ width: 100%; } }
+ .add-token__confirmation-content {
+ padding-bottom: 60px; }
+ .add-token__confirmation-token-list-item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ margin: 0 auto;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .add-token__confirmation-token-list-item + .add-token__confirmation-token-list-item {
+ margin-top: 30px; }
+ .add-token__confirmation-token-icon {
+ margin-right: 18px; }
+ @media screen and (max-width: 575px) {
+ .add-token {
+ top: 0;
+ width: 100%;
+ overflow: hidden;
+ height: 100%; }
+ .add-token__wrapper {
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ width: 100%;
+ overflow-y: auto; }
+ .add-token__footers {
+ border-bottom: 1px solid #efefef; }
+ .add-token__token-icon {
+ width: 50px;
+ height: 50px; }
+ .add-token__token-symbol {
+ font-size: 18px;
+ line-height: 24px; }
+ .add-token__token-name {
+ font-size: 12px;
+ line-height: 16px; }
+ .add-token__buttons {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ width: 100%;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding: 12px 0;
+ margin: 0;
+ border-top: 1px solid #efefef; }
+ .add-token__buttons button {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ margin: 0 12px; } }
+
+.currency-display {
+ height: 54px;
+ width: 100%ß;
+ border: 1px solid #dedede;
+ border-radius: 4px;
+ background-color: #fff;
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: 300;
+ padding: 8px 10px;
+ position: relative; }
+ .currency-display__primary-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+ .currency-display__input {
+ color: #5d5d5d;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ border: none;
+ outline: 0 !important;
+ max-width: 100%; }
+ .currency-display__primary-currency {
+ color: #5d5d5d;
+ font-weight: 400;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px; }
+ .currency-display__converted-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+ .currency-display__converted-value, .currency-display__converted-currency {
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 12px;
+ line-height: 12px; }
+ .currency-display__input-wrapper {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex; }
+ .currency-display__currency-symbol {
+ margin-top: 1px; }
+
+.account-menu {
+ position: fixed;
+ z-index: 100;
+ top: 58px;
+ width: 310px; }
+ @media screen and (max-width: 575px) {
+ .account-menu {
+ right: calc(((100vw - 100%) / 2) + 8px); } }
+ @media screen and (min-width: 576px) {
+ .account-menu {
+ right: calc((100vw - 85vw) / 2); } }
+ @media screen and (min-width: 769px) {
+ .account-menu {
+ right: calc((100vw - 80vw) / 2); } }
+ @media screen and (min-width: 1281px) {
+ .account-menu {
+ right: calc((100vw - 65vw) / 2); } }
+ .account-menu__icon {
+ margin-left: 20px;
+ cursor: pointer; }
+ .account-menu__header {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center; }
+ .account-menu__logout-button {
+ border: 1px solid #9b9b9b;
+ background-color: transparent;
+ color: #fff;
+ border-radius: 4px;
+ font-size: 12px;
+ line-height: 23px;
+ padding: 0 24px;
+ font-weight: 200; }
+ .account-menu img {
+ width: 16px;
+ height: 16px; }
+ .account-menu__accounts {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ overflow-y: auto;
+ max-height: 240px;
+ position: relative;
+ z-index: 200; }
+ .account-menu__accounts::-webkit-scrollbar {
+ display: none; }
+ @media screen and (max-width: 575px) {
+ .account-menu__accounts {
+ max-height: 215px; } }
+ .account-menu__accounts .keyring-label {
+ margin-top: 5px;
+ background-color: #000;
+ color: #9b9b9b; }
+ .account-menu__account {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ padding: 16px 14px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ @media screen and (max-width: 575px) {
+ .account-menu__account {
+ padding: 12px 14px; } }
+ .account-menu__account-info {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ padding-top: 4px; }
+ .account-menu__check-mark {
+ width: 14px;
+ margin-right: 12px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .account-menu__check-mark-icon {
+ background-image: url("images/check-white.svg");
+ height: 18px;
+ width: 18px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ margin: 3px 0; }
+ .account-menu .identicon {
+ margin: 0 12px 0 0;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+ .account-menu__name {
+ color: #fff;
+ font-size: 18px;
+ font-weight: 200;
+ line-height: 16px; }
+ .account-menu__balance {
+ color: #9b9b9b;
+ font-size: 14px;
+ line-height: 19px; }
+ .account-menu__action {
+ font-size: 16px;
+ line-height: 18px;
+ font-weight: 200;
+ cursor: pointer; }
+
+.menu {
+ border-radius: 4px;
+ background: rgba(0, 0, 0, 0.8);
+ -webkit-box-shadow: rgba(0, 0, 0, 0.15) 0 2px 2px 2px;
+ box-shadow: rgba(0, 0, 0, 0.15) 0 2px 2px 2px;
+ min-width: 150px;
+ color: #fff; }
+ .menu__item {
+ padding: 18px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative;
+ z-index: 200;
+ font-weight: 200; }
+ @media screen and (max-width: 575px) {
+ .menu__item {
+ padding: 14px; } }
+ .menu__item--clickable {
+ cursor: pointer; }
+ .menu__item--clickable:hover {
+ background-color: rgba(255, 255, 255, 0.05); }
+ .menu__item--clickable:active {
+ background-color: rgba(255, 255, 255, 0.1); }
+ .menu__item__icon {
+ height: 16px;
+ width: 16px;
+ margin-right: 14px; }
+ .menu__item__text {
+ font-size: 16px;
+ line-height: 21px; }
+ .menu__divider {
+ background-color: #5d5d5d;
+ width: 100%;
+ height: 1px; }
+ .menu__close-area {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ z-index: 100; }
+
+.gas-slider {
+ position: relative;
+ width: 313px; }
+ .gas-slider__input {
+ width: 317px;
+ margin-left: -2px;
+ z-index: 2; }
+ .gas-slider input[type=range] {
+ -webkit-appearance: none !important; }
+ .gas-slider input[type=range]::-webkit-slider-thumb {
+ -webkit-appearance: none !important;
+ height: 26px;
+ width: 26px;
+ border: 2px solid #B8B8B8;
+ background-color: #FFFFFF;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ border-radius: 50%;
+ position: relative;
+ z-index: 10; }
+ .gas-slider__bar {
+ height: 6px;
+ width: 313px;
+ background: #dedede;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ position: absolute;
+ top: 11px;
+ z-index: 0; }
+ .gas-slider__low, .gas-slider__high {
+ height: 6px;
+ width: 49px;
+ z-index: 1; }
+ .gas-slider__low {
+ background-color: #e91550; }
+ .gas-slider__high {
+ background-color: #02c9b1; }
+
+.settings {
+ position: relative;
+ background: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ height: auto;
+ overflow: auto; }
+
+.settings__header {
+ padding: 25px; }
+
+.settings__close-button::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: #9b9b9b;
+ position: absolute;
+ top: 25px;
+ right: 30px;
+ cursor: pointer; }
+
+.settings__error {
+ padding-bottom: 20px;
+ text-align: center;
+ color: #e91550; }
+
+.settings__content {
+ padding: 0 25px; }
+
+.settings__content-row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ padding: 10px 0 20px; }
+ @media screen and (max-width: 575px) {
+ .settings__content-row {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding: 10px 0; } }
+
+.settings__content-item {
+ -webkit-box-flex: 1;
+ -ms-flex: 1;
+ flex: 1;
+ min-width: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding: 0 5px;
+ height: 71px; }
+ @media screen and (max-width: 575px) {
+ .settings__content-item {
+ height: initial;
+ padding: 5px 0; } }
+ .settings__content-item--without-height {
+ height: initial; }
+
+.settings__content-item-col {
+ max-width: 300px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column; }
+ @media screen and (max-width: 575px) {
+ .settings__content-item-col {
+ max-width: 100%;
+ width: 100%; } }
+
+.settings__content-description {
+ font-size: 14px;
+ color: #9b9b9b;
+ padding-top: 5px; }
+
+.settings__input {
+ padding-left: 10px;
+ font-size: 14px;
+ height: 40px;
+ border: 1px solid #dedede; }
+
+.settings__input::-webkit-input-placeholder {
+ font-weight: 100;
+ color: #9b9b9b; }
+
+.settings__input::-moz-placeholder {
+ font-weight: 100;
+ color: #9b9b9b; }
+
+.settings__input:-ms-input-placeholder {
+ font-weight: 100;
+ color: #9b9b9b; }
+
+.settings__input:-moz-placeholder {
+ font-weight: 100;
+ color: #9b9b9b; }
+
+.settings__provider-wrapper {
+ font-size: 16px;
+ border: 1px solid #dedede;
+ border-radius: 2px;
+ padding: 15px;
+ background-color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start; }
+
+.settings__provider-icon {
+ height: 10px;
+ width: 10px;
+ margin-right: 10px;
+ border-radius: 10px; }
+
+.settings__rpc-save-button {
+ -ms-flex-item-align: end;
+ align-self: flex-end;
+ padding: 5px;
+ text-transform: uppercase;
+ color: #9b9b9b;
+ cursor: pointer; }
+
+.settings__clear-button {
+ font-size: 16px;
+ border: 1px solid #2f9ae0;
+ color: #2f9ae0;
+ border-radius: 2px;
+ padding: 18px;
+ background-color: #fff;
+ text-transform: uppercase; }
+
+.settings__clear-button--red {
+ border: 1px solid #d0021b;
+ color: #d0021b; }
+
+.settings__info-logo-wrapper {
+ height: 80px;
+ margin-bottom: 20px; }
+
+.settings__info-logo {
+ max-height: 100%;
+ max-width: 100%; }
+
+.settings__info-item {
+ padding: 10px 0; }
+
+.settings__info-link-header {
+ padding-bottom: 15px; }
+ @media screen and (max-width: 575px) {
+ .settings__info-link-header {
+ padding-bottom: 5px; } }
+
+.settings__info-link-item {
+ padding: 15px 0; }
+ @media screen and (max-width: 575px) {
+ .settings__info-link-item {
+ padding: 5px 0; } }
+
+.settings__info-version-number {
+ padding-top: 5px;
+ font-size: 13px;
+ color: #9b9b9b; }
+
+.settings__info-about {
+ color: #9b9b9b;
+ margin-bottom: 15px; }
+
+.settings__info-link {
+ color: #2f9ae0; }
+
+.settings__info-separator {
+ margin: 15px 0;
+ width: 80px;
+ border-color: #dedede;
+ border: none;
+ height: 1px;
+ background-color: #dedede;
+ color: #dedede; }
+
+.tab-bar {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: end;
+ -ms-flex-align: end;
+ align-items: flex-end; }
+
+.tab-bar__tab {
+ min-width: 0;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ padding: 15px 25px;
+ border-bottom: 1px solid #dedede;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ font-size: 18px; }
+
+.tab-bar__tab--active {
+ border-color: #000; }
+
+.tab-bar__grow-tab {
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1; }
+
+.simple-dropdown {
+ height: 56px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border: 1px solid #dedede;
+ border-radius: 4px;
+ background-color: #fff;
+ font-size: 16px;
+ color: #4d4d4d;
+ cursor: pointer;
+ position: relative; }
+
+.simple-dropdown__caret {
+ color: #cdcdcd;
+ padding: 0 10px; }
+
+.simple-dropdown__selected {
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ padding: 0 15px; }
+
+.simple-dropdown__options {
+ z-index: 1050;
+ position: absolute;
+ height: 220px;
+ width: 100%;
+ border: 1px solid #d2d8dd;
+ border-radius: 4px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ margin-top: 10px;
+ overflow-y: scroll;
+ left: 0;
+ top: 100%; }
+
+.simple-dropdown__option {
+ padding: 10px; }
+ .simple-dropdown__option:hover {
+ background-color: #efefef; }
+
+.simple-dropdown__option--selected {
+ background-color: #dedede; }
+ .simple-dropdown__option--selected:hover {
+ background-color: #dedede;
+ cursor: default; }
+
+.simple-dropdown__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%; }
+
+.request-signature__container {
+ width: 380px;
+ border-radius: 8px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column nowrap;
+ flex-flow: column nowrap;
+ z-index: 25;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-family: Roboto;
+ position: relative;
+ height: 100%; }
+ @media screen and (max-width: 575px) {
+ .request-signature__container {
+ width: 100%;
+ top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none; } }
+ @media screen and (min-width: 576px) {
+ .request-signature__container {
+ max-height: 620px; } }
+
+.request-signature__header {
+ height: 64px;
+ width: 100%;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto; }
+
+.request-signature__header-background {
+ position: absolute;
+ background-color: #e9edf0;
+ z-index: 2;
+ width: 100%;
+ height: 100%; }
+
+.request-signature__header__text {
+ height: 29px;
+ width: 179px;
+ color: #5B5D67;
+ font-family: Roboto;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 29px;
+ z-index: 3; }
+
+.request-signature__header__tip-container {
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+
+.request-signature__header__tip {
+ height: 25px;
+ width: 25px;
+ background: #e9edf0;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ position: absolute;
+ bottom: -8px;
+ z-index: 1; }
+
+.request-signature__account-info {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin-top: 18px;
+ margin-bottom: 20px; }
+
+.request-signature__account {
+ color: #9b9b9b;
+ margin-left: 17px; }
+
+.request-signature__account-text {
+ font-size: 14px; }
+
+.request-signature__balance {
+ color: #9b9b9b;
+ margin-right: 17px;
+ width: 124px; }
+
+.request-signature__balance-text {
+ text-align: right;
+ font-size: 14px; }
+
+.request-signature__balance-value {
+ text-align: right;
+ margin-top: 2.5px; }
+
+.request-signature__request-icon {
+ margin-top: 25px; }
+
+.request-signature__body {
+ width: 100%;
+ height: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ height: 0; }
+
+.request-signature__request-info {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center; }
+
+.request-signature__headline {
+ height: 48px;
+ width: 240px;
+ color: #4d4d4d;
+ font-family: Roboto;
+ font-size: 18px;
+ font-weight: 300;
+ line-height: 24px;
+ text-align: center;
+ margin-top: 20px; }
+
+.request-signature__notice, .request-signature__warning {
+ font-family: "Avenir Next";
+ font-size: 14px;
+ line-height: 19px;
+ text-align: center;
+ margin-top: 41px;
+ margin-bottom: 11px;
+ width: 100%; }
+
+.request-signature__notice {
+ color: #9b9b9b; }
+
+.request-signature__warning {
+ color: #e91550; }
+
+.request-signature__rows {
+ height: 100%;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ border-top: 1px solid #d2d8dd;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column; }
+
+.request-signature__row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: column;
+ flex-flow: column; }
+
+.request-signature__row-title {
+ width: 80px;
+ color: #9b9b9b;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ margin-top: 12px;
+ margin-left: 18px;
+ width: 100%; }
+
+.request-signature__row-value {
+ color: #5d5d5d;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 19px;
+ width: 100%;
+ overflow-wrap: break-word;
+ border-bottom: 1px solid #d2d8dd;
+ padding: 6px 18px 15px; }
+
+.request-signature__footer {
+ width: 100%;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: space-evenly;
+ -ms-flex-pack: space-evenly;
+ justify-content: space-evenly;
+ font-size: 22px;
+ position: relative;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ border-top: 1px solid #d2d8dd; }
+ .request-signature__footer__cancel-button, .request-signature__footer__sign-button {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 auto;
+ flex: 1 0 auto;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: 300;
+ height: 55px;
+ line-height: 32px;
+ cursor: pointer;
+ border-radius: 2px;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ max-width: 162px;
+ margin: 12px; }
+ .request-signature__footer__cancel-button {
+ background: none;
+ border: 1px solid #9b9b9b;
+ margin-right: 6px; }
+ .request-signature__footer__sign-button {
+ background-color: #02c9b1;
+ border-width: 0;
+ color: #fff;
+ margin-left: 6px; }
+
+.account-dropdown-mini {
+ height: 22px;
+ background-color: #fff;
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ width: 124px; }
+ .account-dropdown-mini__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%; }
+ .account-dropdown-mini__list {
+ z-index: 1050;
+ position: absolute;
+ height: 180px;
+ width: 96pxpx;
+ border: 1px solid #d2d8dd;
+ border-radius: 4px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.11);
+ overflow-y: scroll; }
+ .account-dropdown-mini .account-list-item {
+ margin-top: 6px; }
+ .account-dropdown-mini .account-list-item__account-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ width: 80px; }
+ .account-dropdown-mini .account-list-item__top-row {
+ margin: 0; }
+ .account-dropdown-mini .account-list-item__icon {
+ position: initial; }
+
+.editable-label {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ position: relative; }
+ .editable-label__value {
+ max-width: 250px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis; }
+ .editable-label__input {
+ width: 250px;
+ font-size: 14px;
+ text-align: center;
+ border: 1px solid #dedede; }
+ .editable-label__input--error {
+ border: 1px solid #d0021b; }
+ .editable-label__icon-wrapper {
+ position: absolute;
+ margin-left: 10px;
+ left: 100%; }
+ .editable-label__icon {
+ cursor: pointer;
+ color: #9b9b9b; }
+
+/*
+ Trumps
+ */
+/* universal */
+.app-primary .main-enter {
+ position: absolute;
+ width: 100%; }
+
+/* center position */
+.app-primary.from-right .main-enter-active,
+.app-primary.from-left .main-enter-active {
+ overflow-x: hidden;
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ -webkit-transition: -webkit-transform 300ms ease-in;
+ transition: -webkit-transform 300ms ease-in;
+ transition: transform 300ms ease-in;
+ transition: transform 300ms ease-in, -webkit-transform 300ms ease-in; }
+
+/* exited positions */
+.app-primary.from-left .main-leave-active {
+ -webkit-transform: translateX(360px);
+ transform: translateX(360px);
+ -webkit-transition: -webkit-transform 300ms ease-in;
+ transition: -webkit-transform 300ms ease-in;
+ transition: transform 300ms ease-in;
+ transition: transform 300ms ease-in, -webkit-transform 300ms ease-in; }
+
+.app-primary.from-right .main-leave-active {
+ -webkit-transform: translateX(-360px);
+ transform: translateX(-360px);
+ -webkit-transition: -webkit-transform 300ms ease-in;
+ transition: -webkit-transform 300ms ease-in;
+ transition: transform 300ms ease-in;
+ transition: transform 300ms ease-in, -webkit-transform 300ms ease-in; }
+
+.sidebar.from-left {
+ -webkit-transform: translateX(-320px);
+ transform: translateX(-320px);
+ -webkit-transition: -webkit-transform 300ms ease-in;
+ transition: -webkit-transform 300ms ease-in;
+ transition: transform 300ms ease-in;
+ transition: transform 300ms ease-in, -webkit-transform 300ms ease-in; }
+
+/* loader transitions */
+.loader-enter,
+.loader-leave-active {
+ opacity: 0;
+ -webkit-transition: opacity 150 ease-in;
+ transition: opacity 150 ease-in; }
+
+.loader-enter-active,
+.loader-leave {
+ opacity: 1;
+ -webkit-transition: opacity 150 ease-in;
+ transition: opacity 150 ease-in; }
+
+/* entering positions */
+.app-primary.from-right .main-enter:not(.main-enter-active) {
+ -webkit-transform: translateX(360px);
+ transform: translateX(360px); }
+
+.app-primary.from-left .main-enter:not(.main-enter-active) {
+ -webkit-transform: translateX(-360px);
+ transform: translateX(-360px); }
+
+i.fa.fa-question-circle.fa-lg.menu-icon {
+ font-size: 18px; }
+
+/* stylelint-disable */
+#buy-modal-content-footer-text {
+ font-family: 'DIN OT';
+ font-size: 16px; }
+
+/* stylelint-enable */
+
+/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY3NzIiwic291cmNlcyI6WyJpbmRleC5zY3NzIiwiaXRjc3Mvc2V0dGluZ3MvaW5kZXguc2NzcyIsIml0Y3NzL3NldHRpbmdzL3ZhcmlhYmxlcy5zY3NzIiwiaXRjc3Mvc2V0dGluZ3MvdHlwb2dyYXBoeS5zY3NzIiwiaXRjc3MvdG9vbHMvaW5kZXguc2NzcyIsIml0Y3NzL3Rvb2xzL3V0aWxpdGllcy5zY3NzIiwiaXRjc3MvZ2VuZXJpYy9pbmRleC5zY3NzIiwiaXRjc3MvZ2VuZXJpYy9yZXNldC5zY3NzIiwiaXRjc3MvYmFzZS9pbmRleC5zY3NzIiwiaXRjc3Mvb2JqZWN0cy9pbmRleC5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9pbmRleC5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9idXR0b25zLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL2hlYWRlci5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9mb290ZXIuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvbmV0d29yay5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9tb2RhbC5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9uZXd1aS1zZWN0aW9ucy5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9hY2NvdW50LWRyb3Bkb3duLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3NlbmQuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvY29uZmlybS5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9sb2FkaW5nLW92ZXJsYXkuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvaGVyby1iYWxhbmNlLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3dhbGxldC1iYWxhbmNlLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3RyYW5zYWN0aW9uLWxpc3Quc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvc2VjdGlvbnMuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvdG9rZW4tbGlzdC5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9hZGQtdG9rZW4uc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvY3VycmVuY3ktZGlzcGxheS5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9hY2NvdW50LW1lbnUuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvbWVudS5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9nYXMtc2xpZGVyLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3NldHRpbmdzLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3RhYi1iYXIuc2NzcyIsIml0Y3NzL2NvbXBvbmVudHMvc2ltcGxlLWRyb3Bkb3duLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL3JlcXVlc3Qtc2lnbmF0dXJlLnNjc3MiLCJpdGNzcy9jb21wb25lbnRzL2FjY291bnQtZHJvcGRvd24tbWluaS5zY3NzIiwiaXRjc3MvY29tcG9uZW50cy9lZGl0YWJsZS1sYWJlbC5zY3NzIiwiaXRjc3MvdHJ1bXBzL2luZGV4LnNjc3MiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgSVRDU1NcblxuICBodHRwOi8vd3d3LmNyZWF0aXZlYmxvcS5jb20vd2ViLWRlc2lnbi9tYW5hZ2UtbGFyZ2UtY3NzLXByb2plY3RzLWl0Y3NzLTEwMTUxNzUyOFxuICBodHRwczovL3d3dy54Zml2ZS5jby9ibG9nL2l0Y3NzLXNjYWxhYmxlLW1haW50YWluYWJsZS1jc3MtYXJjaGl0ZWN0dXJlL1xuICovXG5AaW1wb3J0ICcuL2l0Y3NzL3NldHRpbmdzL2luZGV4LnNjc3MnO1xuQGltcG9ydCAnLi9pdGNzcy90b29scy9pbmRleC5zY3NzJztcbkBpbXBvcnQgJy4vaXRjc3MvZ2VuZXJpYy9pbmRleC5zY3NzJztcbkBpbXBvcnQgJy4vaXRjc3MvYmFzZS9pbmRleC5zY3NzJztcbkBpbXBvcnQgJy4vaXRjc3Mvb2JqZWN0cy9pbmRleC5zY3NzJztcbkBpbXBvcnQgJy4vaXRjc3MvY29tcG9uZW50cy9pbmRleC5zY3NzJztcbkBpbXBvcnQgJy4vaXRjc3MvdHJ1bXBzL2luZGV4LnNjc3MnO1xuIiwiQGltcG9ydCAnLi92YXJpYWJsZXMuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vdHlwb2dyYXBoeS5zY3NzJztcbiIsIi8qXG4gIFZhcmlhYmxlc1xuICovXG5cbi8vIEJhc2UgQ29sb3JzXG4kd2hpdGU6ICNmZmY7XG4kYmxhY2s6ICMwMDA7XG4kb3JhbmdlOiAjZmZhNTAwO1xuJHJlZDogI2YwMDtcbiRncmF5OiAjODA4MDgwO1xuXG4vKlxuICBDb2xvcnNcbiAgaHR0cDovL2NoaXIuYWcvcHJvamVjdHMvbmFtZS10aGF0LWNvbG9yXG4gKi9cbiR3aGl0ZS1saW5lbjogI2ZhZjZmMDsgLy8gZm9ybWVybHkgJ2ZhaW50IG9yYW5nZSAodGV4dGZpZWxkIHNoYWRlcyknXG4kcmFqYWg6ICNmNWMyNmQ7IC8vIGZvcm1lcmx5ICdsaWdodCBvcmFuZ2UgKGJ1dHRvbiBzaGFkZXMpJ1xuJGJ1dHRlcmN1cDogI2Y1YTYyMzsgLy8gZm9ybWVybHkgJ2Rhcmsgb3JhbmdlICh0ZXh0KSdcbiR0dW5kb3JhOiAjNGE0YTRhOyAvLyBmb3JtZXJseSAnYm9yZGVycy9mb250L2FueSBncmF5J1xuJGdhbGxlcnk6ICNlZmVmZWY7XG4kYWxhYmFzdGVyOiAjZjdmN2Y3O1xuJHNoYXJrOiAjMjIyMzJjO1xuJHdpbGQtc2FuZDogI2Y2ZjZmNjtcbiR3aGl0ZTogI2ZmZjtcbiRkdXN0eS1ncmF5OiAjOWI5YjliO1xuJGFsdG86ICNkZWRlZGU7XG4kYWxhYmFzdGVyOiAjZmFmYWZhO1xuJHNpbHZlci1jaGFsaWNlOiAjYWVhZWFlO1xuJGN1cmlvdXMtYmx1ZTogIzJmOWFlMDtcbiRjb25jcmV0ZTogI2YzZjNmMztcbiR0dW5kb3JhOiAjNGQ0ZDRkO1xuJG5pbGUtYmx1ZTogIzFiMzQ0ZDtcbiRzY29ycGlvbjogIzVkNWQ1ZDtcbiRzaWx2ZXI6ICNjZGNkY2Q7XG4kY2FyaWJiZWFuLWdyZWVuOiAjMDJjOWIxO1xuJG1vbnpvOiAjZDAwMjFiO1xuJGNyaW1zb246ICNlOTE1NTA7XG4kYmx1ZS1sYWdvb246ICMwMzg3ODk7XG4kcHVycGxlOiAjNjkwNDk2O1xuJHR1bGlwLXRyZWU6ICNlYmIzM2Y7XG4kbWFsaWJ1LWJsdWU6ICM3YWM5ZmQ7XG4kYXRoZW5zLWdyZXk6ICNlOWVkZjA7XG4kamFmZmE6ICNmMjg5MzA7XG4kZ2V5c2VyOiAjZDJkOGRkO1xuXG4vKlxuICBaLUluZGljaWVzXG4gKi9cbiRkcm9wZG93bi16LWluZGV4OiAzMDtcbiR0b2tlbi1pY29uLXotaW5kZXg6IDE1O1xuJGNvbnRhaW5lci16LWluZGV4OiAxNTtcbiRoZWFkZXItei1pbmRleDogMTI7XG4kbW9iaWxlLWhlYWRlci16LWluZGV4OiAyNjtcbiRtYWluLWNvbnRhaW5lci16LWluZGV4OiAxODtcbiRzZW5kLWNhcmQtei1pbmRleDogMjA7XG4kc2lkZWJhci16LWluZGV4OiAyNjtcbiRzaWRlYmFyLW92ZXJsYXktei1pbmRleDogMjU7XG5cbi8qXG4gIFogSW5kaWNpZXMgLSBDdXJyZW50XG4gIGFwcCAtIDExXG4gIGhleC9ibiBhcyBkZWNpbWFsIGlucHV0IC0gMSAtIHJlbW92ZT9cbiAgZHJvcGRvd24gLSAxMVxuICBsb2FkaW5nIC0gMTAgLSBoaWdoZXI/XG4gIG1hc2NvdCAtIDAgLSByZW1vdmU/XG4gKi9cblxuLypcbiAgUmVzcG9uc2l2ZSBCcmVha3BvaW50c1xuICovXG4kYnJlYWstc21hbGw6IDU3NXB4O1xuJGJyZWFrLW1pZHBvaW50OiA3ODBweDtcbiRicmVhay1sYXJnZTogNTc2cHg7XG5cblxuJHByaW1hcnktZm9udC10eXBlOiBSb2JvdG87XG5cbiIsIkBpbXBvcnQgdXJsKCdodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9Um9ib3RvOjEwMCwzMDAsNDAwLDUwMCw3MDAsOTAwJyk7XG5cbkBpbXBvcnQgdXJsKCdodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2ZvbnQtYXdlc29tZS80LjQuMC9jc3MvZm9udC1hd2Vzb21lLm1pbi5jc3MnKTtcblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnTW9udHNlcnJhdCBSZWd1bGFyJztcbiAgc3JjOiB1cmwoJy9mb250cy9Nb250c2VycmF0L01vbnRzZXJyYXQtUmVndWxhci53b2ZmJykgZm9ybWF0KCd3b2ZmJyk7XG4gIHNyYzogdXJsKCcvZm9udHMvTW9udHNlcnJhdC9Nb250c2VycmF0LVJlZ3VsYXIudHRmJykgZm9ybWF0KCd0cnVldHlwZScpO1xuICBmb250LXdlaWdodDogNDAwO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtc2l6ZTogJ3NtYWxsJztcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnTW9udHNlcnJhdCBCb2xkJztcbiAgc3JjOiB1cmwoJy9mb250cy9Nb250c2VycmF0L01vbnRzZXJyYXQtQm9sZC53b2ZmJykgZm9ybWF0KCd3b2ZmJyk7XG4gIHNyYzogdXJsKCcvZm9udHMvTW9udHNlcnJhdC9Nb250c2VycmF0LUJvbGQudHRmJykgZm9ybWF0KCd0cnVldHlwZScpO1xuICBmb250LXdlaWdodDogNDAwO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG59XG5cbkBmb250LWZhY2Uge1xuICBmb250LWZhbWlseTogJ01vbnRzZXJyYXQgTGlnaHQnO1xuICBzcmM6IHVybCgnL2ZvbnRzL01vbnRzZXJyYXQvTW9udHNlcnJhdC1MaWdodC53b2ZmJykgZm9ybWF0KCd3b2ZmJyk7XG4gIHNyYzogdXJsKCcvZm9udHMvTW9udHNlcnJhdC9Nb250c2VycmF0LUxpZ2h0LnR0ZicpIGZvcm1hdCgndHJ1ZXR5cGUnKTtcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xufVxuXG5AZm9udC1mYWNlIHtcbiAgZm9udC1mYW1pbHk6ICdNb250c2VycmF0IFVsdHJhTGlnaHQnO1xuICBzcmM6IHVybCgnL2ZvbnRzL01vbnRzZXJyYXQvTW9udHNlcnJhdC1VbHRyYUxpZ2h0LndvZmYnKSBmb3JtYXQoJ3dvZmYnKTtcbiAgc3JjOiB1cmwoJy9mb250cy9Nb250c2VycmF0L01vbnRzZXJyYXQtVWx0cmFMaWdodC50dGYnKSBmb3JtYXQoJ3RydWV0eXBlJyk7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnRElOIE9UJztcbiAgc3JjOiB1cmwoJy9mb250cy9ESU5fT1QvRElOT1QtMi5vdGYnKSBmb3JtYXQoJ29wZW50eXBlJyk7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnRElOIE9UIExpZ2h0JztcbiAgc3JjOiB1cmwoJy9mb250cy9ESU5fT1QvRElOT1QtMi5vdGYnKSBmb3JtYXQoJ29wZW50eXBlJyk7XG4gIGZvbnQtd2VpZ2h0OiAyMDA7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnRElOIE5FWFQnO1xuICBzcmM6IHVybCgnL2ZvbnRzL0RJTiBORVhUL0RJTiBORVhUIFcwMSBSZWd1bGFyLm90ZicpIGZvcm1hdCgnb3BlbnR5cGUnKTtcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xufVxuXG5AZm9udC1mYWNlIHtcbiAgZm9udC1mYW1pbHk6ICdESU4gTkVYVCBMaWdodCc7XG4gIHNyYzogdXJsKCcvZm9udHMvRElOIE5FWFQvRElOIE5FWFQgVzEwIExpZ2h0Lm90ZicpIGZvcm1hdCgnb3BlbnR5cGUnKTtcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xufVxuXG5AZm9udC1mYWNlIHtcbiAgZm9udC1mYW1pbHk6ICdMYXRvJztcbiAgc3JjOiB1cmwoJy9mb250cy9MYXRvL0xhdG8tUmVndWxhci50dGYnKSBmb3JtYXQoJ3RydWV0eXBlJyk7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbn1cbiIsIkBpbXBvcnQgJy4vdXRpbGl0aWVzLnNjc3MnO1xuIiwiLypcbiAgVXRpbGl0eSBDbGFzc2VzXG4gKi9cblxuLyogY29sb3IgKi9cblxuLmNvbG9yLW9yYW5nZSB7XG4gIGNvbG9yOiAjZjc4NjFjOyAvLyBUT0RPOiBtb3ZlIHRvIHNldHRpbmdzL3ZhcmlhYmxlc1xufVxuXG4uY29sb3ItZm9yZXN0IHtcbiAgY29sb3I6ICMwYTU0NDg7IC8vIFRPRE86IG1vdmUgdG8gc2V0dGluZ3MvdmFyaWFibGVzXG59XG5cbi8qIGxpYiAqL1xuXG4uZnVsbC1zaXplIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICB3aWR0aDogMTAwJTtcbn1cblxuLmZ1bGwtd2lkdGgge1xuICB3aWR0aDogMTAwJTtcbn1cblxuLmZ1bGwtZmxleC1oZWlnaHQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4OiAxIDEgYXV0bztcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbn1cblxuLmZ1bGwtaGVpZ2h0IHtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4uZmxleC1jb2x1bW4ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xufVxuXG4uc3BhY2UtYmV0d2VlbiB7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2Vlbjtcbn1cblxuLnNwYWNlLWFyb3VuZCB7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYXJvdW5kO1xufVxuXG4uZmxleC1jb2x1bW4tYm90dG9tIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbi1yZXZlcnNlO1xufVxuXG4uZmxleC1yb3cge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xufVxuXG4uZmxleC1zcGFjZS1iZXR3ZWVuIHtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xufVxuXG4uZmxleC1zcGFjZS1hcm91bmQge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbn1cblxuLmZsZXgtcmlnaHQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuXG4uZmxleC1sZWZ0IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xufVxuXG4uZmxleC1maXhlZCB7XG4gIGZsZXg6IG5vbmU7XG59XG5cbi5mbGV4LWJhc2lzLWF1dG8ge1xuICBmbGV4LWJhc2lzOiBhdXRvO1xufVxuXG4uZmxleC1ncm93IHtcbiAgZmxleDogMSAxIGF1dG87XG59XG5cbi5mbGV4LXdyYXAge1xuICBmbGV4LXdyYXA6IHdyYXA7XG59XG5cbi5mbGV4LWNlbnRlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uZmxleC1qdXN0aWZ5LWNlbnRlciB7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xufVxuXG4uZmxleC1hbGlnbi1jZW50ZXIge1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uZmxleC1zZWxmLWVuZCB7XG4gIGFsaWduLXNlbGY6IGZsZXgtZW5kO1xufVxuXG4uZmxleC1zZWxmLXN0cmV0Y2gge1xuICBhbGlnbi1zZWxmOiBzdHJldGNoO1xufVxuXG4uZmxleC12ZXJ0aWNhbCB7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG59XG5cbi56LWJ1bXAge1xuICB6LWluZGV4OiAxO1xufVxuXG4uc2VsZWN0LW5vbmUge1xuICBjdXJzb3I6IGluaGVyaXQ7XG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5wb2ludGVyIHtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uY3Vyc29yLXBvaW50ZXIge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHRyYW5zZm9ybS1vcmlnaW46IGNlbnRlciBjZW50ZXI7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSA1MG1zIGVhc2UtaW4tb3V0O1xufVxuXG4uY3Vyc29yLXBvaW50ZXI6aG92ZXIge1xuICB0cmFuc2Zvcm06IHNjYWxlKDEuMSk7XG59XG5cbi5jdXJzb3ItcG9pbnRlcjphY3RpdmUge1xuICB0cmFuc2Zvcm06IHNjYWxlKC45NSk7XG59XG5cbi5jdXJzb3ItZGlzYWJsZWQge1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4ubWFyZ2luLWJvdHRvbS1zbWwge1xuICBtYXJnaW4tYm90dG9tOiAyMHB4O1xufVxuXG4ubWFyZ2luLWJvdHRvbS1tZWQge1xuICBtYXJnaW4tYm90dG9tOiA0MHB4O1xufVxuXG4ubWFyZ2luLXJpZ2h0LWxlZnQge1xuICBtYXJnaW46IDAgMjBweDtcbn1cblxuLmJvbGQge1xuICBmb250LXdlaWdodDogNzAwO1xufVxuXG4udGV4dC10cmFuc2Zvcm0tdXBwZXJjYXNlIHtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbn1cblxuLmZvbnQtc21hbGwge1xuICBmb250LXNpemU6IDEycHg7XG59XG5cbi5mb250LW1lZGl1bSB7XG4gIGZvbnQtc2l6ZTogMS4yZW07XG59XG5cbmhyLmhvcml6b250YWwtbGluZSB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBoZWlnaHQ6IDFweDtcbiAgYm9yZGVyOiAwO1xuICBib3JkZXItdG9wOiAxcHggc29saWQgI2NjYztcbiAgbWFyZ2luOiAxZW0gMDtcbiAgcGFkZGluZzogMDtcbn1cblxuLmhvdmVyLXdoaXRlOmhvdmVyIHtcbiAgYmFja2dyb3VuZDogJHdoaXRlO1xufVxuXG4ucmVkLWRvdCB7XG4gIGJhY2tncm91bmQ6ICNlOTE1NTA7XG4gIGNvbG9yOiAkd2hpdGU7XG4gIGJvcmRlci1yYWRpdXM6IDEwcHg7XG59XG5cbi5kaWFtb25kIHtcbiAgdHJhbnNmb3JtOiByb3RhdGUoNDVkZWcpO1xuICBiYWNrZ3JvdW5kOiAjMDM4Nzg5O1xufVxuXG4uaG9sbG93LWRpYW1vbmQge1xuICB0cmFuc2Zvcm06IHJvdGF0ZSg0NWRlZyk7XG4gIGJvcmRlcjogM3B4IHNvbGlkICM2OTA0OTY7XG59XG5cbi5nb2xkZW4tc3F1YXJlIHtcbiAgYmFja2dyb3VuZDogI2ViYjMzZjtcbn1cblxuLnBlbmRpbmctZG90IHtcbiAgYmFja2dyb3VuZDogJHJlZDtcbiAgbGVmdDogMTRweDtcbiAgdG9wOiAxNHB4O1xuICBjb2xvcjogJHdoaXRlO1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBoZWlnaHQ6IDIwcHg7XG4gIG1pbi13aWR0aDogMjBweDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgcGFkZGluZzogNHB4O1xuICB6LWluZGV4OiAxO1xufVxuXG4ua2V5cmluZy1sYWJlbCB7XG4gIHotaW5kZXg6IDE7XG4gIGZvbnQtc2l6ZTogOHB4O1xuICBsaW5lLWhlaWdodDogOHB4O1xuICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNCk7XG4gIGNvbG9yOiAjZmZmO1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBwYWRkaW5nOiA0cHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgaGVpZ2h0OiAxNXB4O1xufVxuXG4uZXRoZXItYmFsYW5jZSB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi50YWJTZWN0aW9uIHtcbiAgbWluLXdpZHRoOiAzNTBweDtcbn1cblxuLm1lbnUtaWNvbiB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgaGVpZ2h0OiAxMnB4O1xuICBtaW4td2lkdGg6IDEycHg7XG4gIG1hcmdpbjogMTNweDtcbn1cblxuLmV0aGVyLWljb24ge1xuICBiYWNrZ3JvdW5kOiByZ2IoMCwgMTYzLCA2OCk7XG4gIGJvcmRlci1yYWRpdXM6IDIwcHg7XG59XG5cbi50ZXN0bmV0LWljb24ge1xuICBiYWNrZ3JvdW5kOiAjMjQ2NWUxO1xufVxuXG4uZHJvcC1tZW51LWl0ZW0ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uaW52aXNpYmxlIHtcbiAgdmlzaWJpbGl0eTogaGlkZGVuO1xufVxuXG4ub25lLWxpbmUtY29uY2F0IHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbi5jcml0aWNhbC1lcnJvciB7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgbWFyZ2luLXRvcDogMjBweDtcbiAgY29sb3I6ICRyZWQ7XG59XG5cbi8qXG4gIE1pc2NcbiAqL1xuXG4vLyBUT0RPOiBtb3ZlIGludG8gY29tcG9uZW50LWxldmVsIGNvbnRleHR1YWwgJ2FjdGl2ZScgc3RhdGVcbi5sZXR0ZXItc3BhY2V5IHtcbiAgbGV0dGVyLXNwYWNpbmc6IC4xZW07XG59XG5cbi5hY3RpdmUge1xuICBjb2xvcjogIzkwOTA5MDtcbn1cblxuLmNoZWNrIHtcbiAgbWFyZ2luLWxlZnQ6IDdweDtcbiAgY29sb3I6ICNmNzg2MWM7XG4gIGZsZXg6IDEgMCBhdXRvO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuIiwiLypcbiAgR2VuZXJpY1xuICovXG5cbkBpbXBvcnQgJy4vcmVzZXQuc2Nzcyc7XG5cbioge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuXG5odG1sLFxuYm9keSB7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG8sIEFyaWFsO1xuICBjb2xvcjogIzRkNGQ0ZDtcbiAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgbGluZS1oZWlnaHQ6IDEuNGVtO1xuICBiYWNrZ3JvdW5kOiAjZjdmN2Y3O1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBtYXJnaW46IDA7XG4gIHBhZGRpbmc6IDA7XG59XG5cbmh0bWwge1xuICBtaW4taGVpZ2h0OiA1MDBweDtcbn1cblxuLmFwcC1yb290IHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4uYXBwLXByaW1hcnkge1xuICBkaXNwbGF5OiBmbGV4O1xufVxuXG5pbnB1dDpmb2N1cyxcbnRleHRhcmVhOmZvY3VzIHtcbiAgb3V0bGluZTogbm9uZTtcbn1cblxuLyogc3R5bGVsaW50LWRpc2FibGUgKi9cbiNhcHAtY29udGVudCB7XG4gIG92ZXJmbG93LXg6IGhpZGRlbjtcbiAgaGVpZ2h0OiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgfVxufVxuLyogc3R5bGVsaW50LWVuYWJsZSAqL1xuXG5hIHtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBjb2xvcjogaW5oZXJpdDtcbn1cblxuYTpob3ZlciB7XG4gIGNvbG9yOiAjZGY2YjBlO1xufVxuXG5pbnB1dC5sYXJnZS1pbnB1dCxcbnRleHRhcmVhLmxhcmdlLWlucHV0IHtcbiAgcGFkZGluZzogOHB4O1xufVxuXG5pbnB1dC5sYXJnZS1pbnB1dCB7XG4gIGhlaWdodDogMzZweDtcbn1cbiIsIi8qIGh0dHA6Ly9tZXllcndlYi5jb20vZXJpYy90b29scy9jc3MvcmVzZXQvXG4gICB2Mi4wIHwgMjAxMTAxMjZcbiAgIExpY2Vuc2U6IG5vbmUgKHB1YmxpYyBkb21haW4pXG4qL1xuXG5odG1sLFxuYm9keSxcbmRpdixcbnNwYW4sXG5hcHBsZXQsXG5vYmplY3QsXG5pZnJhbWUsXG5oMSxcbmgyLFxuaDMsXG5oNCxcbmg1LFxuaDYsXG5wLFxuYmxvY2txdW90ZSxcbnByZSxcbmEsXG5hYmJyLFxuYWNyb255bSxcbmFkZHJlc3MsXG5iaWcsXG5jaXRlLFxuY29kZSxcbmRlbCxcbmRmbixcbmVtLFxuaW1nLFxuaW5zLFxua2JkLFxucSxcbnMsXG5zYW1wLFxuc21hbGwsXG5zdHJpa2UsXG5zdHJvbmcsXG5zdWIsXG5zdXAsXG50dCxcbnZhcixcbmIsXG51LFxuaSxcbmNlbnRlcixcbmRsLFxuZHQsXG5kZCxcbm9sLFxudWwsXG5saSxcbmZpZWxkc2V0LFxuZm9ybSxcbmxhYmVsLFxubGVnZW5kLFxudGFibGUsXG5jYXB0aW9uLFxudGJvZHksXG50Zm9vdCxcbnRoZWFkLFxudHIsXG50aCxcbnRkLFxuYXJ0aWNsZSxcbmFzaWRlLFxuY2FudmFzLFxuZGV0YWlscyxcbmVtYmVkLFxuZmlndXJlLFxuZmlnY2FwdGlvbixcbmZvb3RlcixcbmhlYWRlcixcbmhncm91cCxcbm1lbnUsXG5uYXYsXG5vdXRwdXQsXG5ydWJ5LFxuc2VjdGlvbixcbnN1bW1hcnksXG50aW1lLFxubWFyayxcbmF1ZGlvLFxudmlkZW8ge1xuICBtYXJnaW46IDA7XG4gIHBhZGRpbmc6IDA7XG4gIGJvcmRlcjogMDtcbiAgZm9udC1zaXplOiAxMDAlO1xuICAvKiBzdHlsZWxpbnQtZGlzYWJsZSAqL1xuICBmb250OiBpbmhlcml0O1xuICAvKiBzdHlsZWxpbnQtZW5hYmxlICovXG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTtcbn1cblxuLyogSFRNTDUgZGlzcGxheS1yb2xlIHJlc2V0IGZvciBvbGRlciBicm93c2VycyAqL1xuXG4vKiBzdHlsZWxpbnQtZGlzYWJsZSAqL1xuXG5hcnRpY2xlLFxuYXNpZGUsXG5kZXRhaWxzLFxuZmlnY2FwdGlvbixcbmZpZ3VyZSxcbmZvb3RlcixcbmhlYWRlcixcbmhncm91cCxcbm1lbnUsXG5uYXYsXG5zZWN0aW9uIHtcbiAgZGlzcGxheTogYmxvY2s7XG59XG5cbmJvZHkge1xuICBsaW5lLWhlaWdodDogMTtcbn1cblxub2wsXG51bCB7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG59XG5cbmJsb2NrcXVvdGUsXG5xIHtcbiAgcXVvdGVzOiBub25lO1xufVxuXG5ibG9ja3F1b3RlOmJlZm9yZSxcbmJsb2NrcXVvdGU6YWZ0ZXIsXG5xOmJlZm9yZSxcbnE6YWZ0ZXIge1xuICBjb250ZW50OiAnJztcbiAgY29udGVudDogbm9uZTtcbn1cblxudGFibGUge1xuICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICBib3JkZXItc3BhY2luZzogMDtcbn1cblxuYnV0dG9uIHtcbiAgYm9yZGVyLXN0eWxlOiBub25lO1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi8qIHN0eWxlbGludC1lbmFibGUgKi9cbiIsIi8vIEJhc2VcbiIsIi8vIE9iamVjdHNcbiIsIkBpbXBvcnQgJy4vYnV0dG9ucy5zY3NzJztcblxuQGltcG9ydCAnLi9oZWFkZXIuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vZm9vdGVyLnNjc3MnO1xuXG5AaW1wb3J0ICcuL25ldHdvcmsuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vbW9kYWwuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vbmV3dWktc2VjdGlvbnMuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vYWNjb3VudC1kcm9wZG93bi5zY3NzJztcblxuQGltcG9ydCAnLi9zZW5kLnNjc3MnO1xuXG5AaW1wb3J0ICcuL2NvbmZpcm0uc2Nzcyc7XG5cbkBpbXBvcnQgJy4vbG9hZGluZy1vdmVybGF5LnNjc3MnO1xuXG4vLyBCYWxhbmNlc1xuQGltcG9ydCAnLi9oZXJvLWJhbGFuY2Uuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vd2FsbGV0LWJhbGFuY2Uuc2Nzcyc7XG5cbi8vIFR4IExpc3QgYW5kIFNlY3Rpb25zXG5AaW1wb3J0ICcuL3RyYW5zYWN0aW9uLWxpc3Quc2Nzcyc7XG5cbkBpbXBvcnQgJy4vc2VjdGlvbnMuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vdG9rZW4tbGlzdC5zY3NzJztcblxuQGltcG9ydCAnLi9hZGQtdG9rZW4uc2Nzcyc7XG5cbkBpbXBvcnQgJy4vY3VycmVuY3ktZGlzcGxheS5zY3NzJztcblxuQGltcG9ydCAnLi9hY2NvdW50LW1lbnUuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vbWVudS5zY3NzJztcblxuQGltcG9ydCAnLi9nYXMtc2xpZGVyLnNjc3MnO1xuXG5AaW1wb3J0ICcuL3NldHRpbmdzLnNjc3MnO1xuXG5AaW1wb3J0ICcuL3RhYi1iYXIuc2Nzcyc7XG5cbkBpbXBvcnQgJy4vc2ltcGxlLWRyb3Bkb3duLnNjc3MnO1xuXG5AaW1wb3J0ICcuL3JlcXVlc3Qtc2lnbmF0dXJlLnNjc3MnO1xuXG5AaW1wb3J0ICcuL2FjY291bnQtZHJvcGRvd24tbWluaS5zY3NzJztcblxuQGltcG9ydCAnLi9lZGl0YWJsZS1sYWJlbC5zY3NzJztcbiIsIi8qXG4gIEJ1dHRvbnNcbiAqL1xuXG4uYnRuLWdyZWVuIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAyYzliMTsgLy8gVE9ETzogcmV1c2FibGUgY29sb3IgaW4gY29sb3JzLmNzc1xufVxuXG5idXR0b24uYnRuLWNsZWFyIHtcbiAgYmFja2dyb3VuZDogJHdoaXRlO1xuICBib3JkZXI6IDFweCBzb2xpZDtcbn1cblxuLy8gTm8gbG9uZ2VyIHVzZWQgaW4gZmxhdCBkZXNpZ24sIHJlbW92ZSB3aGVuIG1vZGFsIGJ1dHRvbnMgZG9uZVxuLy8gZGl2LndhbGxldC1idG4ge1xuLy8gICBib3JkZXI6IDFweCBzb2xpZCByZ2IoOTEsIDkzLCAxMDMpO1xuLy8gICBib3JkZXItcmFkaXVzOiAycHg7XG4vLyAgIGhlaWdodDogMzBweDtcbi8vICAgd2lkdGg6IDc1cHg7XG4vLyAgIGZvbnQtc2l6ZTogMC44ZW07XG4vLyAgIHRleHQtYWxpZ246IGNlbnRlcjtcbi8vICAgbGluZS1oZWlnaHQ6IDI1cHg7XG4vLyB9XG5cbi8vIC5idG4tcmVkIHtcbi8vICAgYmFja2dyb3VuZDogcmdiYSgyNTQsIDM1LCAxNywgMSk7XG4vLyAgIGJveC1zaGFkb3c6IDBweCAzcHggNnB4IHJnYmEoMjU0LCAzNSwgMTcsIDAuMzYpO1xuLy8gfVxuXG5idXR0b25bZGlzYWJsZWRdLFxuaW5wdXRbdHlwZT1cInN1Ym1pdFwiXVtkaXNhYmxlZF0ge1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xuICBvcGFjaXR5OiAuNTtcbiAgLy8gYmFja2dyb3VuZDogcmdiYSgxOTcsIDE5NywgMTk3LCAxKTtcbiAgLy8gYm94LXNoYWRvdzogMCAzcHggNnB4IHJnYmEoMTk3LCAxOTcsIDE5NywgLjM2KTtcbn1cblxuLy8gYnV0dG9uLnNwYWNlZCB7XG4vLyAgIG1hcmdpbjogMnB4O1xuLy8gfVxuXG4vLyBidXR0b246bm90KFtkaXNhYmxlZF0pOmhvdmVyLCBpbnB1dFt0eXBlPVwic3VibWl0XCJdOm5vdChbZGlzYWJsZWRdKTpob3ZlciB7XG4vLyAgIHRyYW5zZm9ybTogc2NhbGUoMS4xKTtcbi8vIH1cbi8vIGJ1dHRvbjpub3QoW2Rpc2FibGVkXSk6YWN0aXZlLCBpbnB1dFt0eXBlPVwic3VibWl0XCJdOm5vdChbZGlzYWJsZWRdKTphY3RpdmUge1xuLy8gICB0cmFuc2Zvcm06IHNjYWxlKDAuOTUpO1xuLy8gfVxuXG5idXR0b24ucHJpbWFyeSB7XG4gIHBhZGRpbmc6IDhweCAxMnB4O1xuICBiYWNrZ3JvdW5kOiAjZjc4NjFjO1xuICBib3gtc2hhZG93OiAwIDNweCA2cHggcmdiYSgyNDcsIDEzNCwgMjgsIC4zNik7XG4gIGNvbG9yOiAkd2hpdGU7XG4gIGZvbnQtc2l6ZTogMS4xZW07XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG59XG5cbi5idG4tbGlnaHQge1xuICBwYWRkaW5nOiA4cHggMTJweDtcbiAgLy8gYmFja2dyb3VuZDogI0ZGRkZGRjsgLy8gJGJnLXdoaXRlXG4gIGJveC1zaGFkb3c6IDAgM3B4IDZweCByZ2JhKDI0NywgMTM0LCAyOCwgLjM2KTtcbiAgY29sb3I6ICM1ODVkNjc7IC8vIFRPRE86IG1ha2UgcmV1c2FibGUgbGlnaHQgYnV0dG9uIGNvbG9yXG4gIGZvbnQtc2l6ZTogMS4xZW07XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgbGluZS1oZWlnaHQ6IDIwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYm9yZGVyOiAxcHggc29saWQgIzk3OTc5NzsgLy8gI1RPRE86IG1ha2UgcmV1c2FibGUgbGlnaHQgYm9yZGVyIGNvbG9yXG4gIG9wYWNpdHk6IC41O1xufVxuXG4vLyBUT0RPOiBjbGVhbnVwOiBub3QgdXNlZCBhbnl3aGVyZVxuYnV0dG9uLmJ0bi10aGluIHtcbiAgYm9yZGVyOiAxcHggc29saWQ7XG4gIGJvcmRlci1jb2xvcjogIzRkNGQ0ZDtcbiAgY29sb3I6ICM0ZDRkNGQ7XG4gIGJhY2tncm91bmQ6IHJnYigyNTUsIDE3NCwgNDEpO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIG1pbi13aWR0aDogMjAwcHg7XG4gIG1hcmdpbjogMTJweCAwO1xuICBwYWRkaW5nOiA2cHg7XG4gIGZvbnQtc2l6ZTogMTNweDtcbn1cblxuLmJ0bi1zZWNvbmRhcnkge1xuICBib3JkZXI6IDFweCBzb2xpZCAjOTc5Nzk3O1xuICBib3JkZXItcmFkaXVzOiAycHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgZm9udC1zaXplOiAxNnB4O1xuICBsaW5lLWhlaWdodDogMjRweDtcbiAgcGFkZGluZzogMTZweCA0MnB4O1xuXG4gICZbZGlzYWJsZWRdIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGUgIWltcG9ydGFudDtcbiAgICBvcGFjaXR5OiAuNTtcbiAgfVxufVxuXG4uYnRuLXRlcnRpYXJ5IHtcbiAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDI0cHg7XG4gIHBhZGRpbmc6IDE2cHggNDJweDtcbn1cbiIsIi5hcHAtaGVhZGVyIHtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgYmFja2dyb3VuZDogJGdhbGxlcnk7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgei1pbmRleDogJGhlYWRlci16LWluZGV4O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICBwYWRkaW5nOiAxMnB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDFweCByZ2JhKDAsIDAsIDAsIC4wOCk7XG4gICAgei1pbmRleDogJG1vYmlsZS1oZWFkZXItei1pbmRleDtcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDU3NnB4KSB7XG4gICAgaGVpZ2h0OiA3NXB4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgJjo6YWZ0ZXIge1xuICAgICAgY29udGVudDogJyc7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogMzJweDtcbiAgICAgIGJhY2tncm91bmQ6ICRnYWxsZXJ5O1xuICAgICAgYm90dG9tOiAtMzJweDtcbiAgICB9XG4gIH1cblxuICAubWV0YWZveC1pY29uIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cbn1cblxuLmFwcC1oZWFkZXItY29udGVudHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNi45dmg7XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gIH1cblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA1NzZweCkge1xuICAgIHdpZHRoOiA4NXZ3O1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzY5cHgpIHtcbiAgICB3aWR0aDogODB2dztcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDEyODFweCkge1xuICAgIHdpZHRoOiA2NXZ3O1xuICB9XG59XG5cbi5hcHAtaGVhZGVyIGgxIHtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgY29sb3I6ICMyMjIzMmM7IC8vICRzaGFya1xuICBsaW5lLWhlaWdodDogMjlweDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1NzVweCkge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cblxuaDIucGFnZS1zdWJ0aXRsZSB7XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIGNvbG9yOiAjYWVhZWFlO1xuICBmb250LXNpemU6IDFlbTtcbiAgbWFyZ2luOiAxMnB4O1xufVxuXG4ubmV0d29yay1jb21wb25lbnQtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5sZWZ0LW1lbnUtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLmhlYWRlcl9fcmlnaHQtYWN0aW9ucyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcblxuICAuaWRlbnRpY29uIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cbn1cbiIsIi5hcHAtZm9vdGVyIHtcbiAgcGFkZGluZy1ib3R0b206IDEwcHg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG4iLCIubmV0d29yay1jb21wb25lbnQtLWRpc2FibGVkIHtcbiAgLy8gYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudCAhaW1wb3J0YW50O1xuICBjdXJzb3I6IGRlZmF1bHQ7XG5cbiAgLmZhLWNhcmV0LWRvd24ge1xuICAgIG9wYWNpdHk6IDA7XG4gIH1cbn1cblxuLm5ldHdvcmstY29tcG9uZW50LnBvaW50ZXIge1xuICBib3JkZXI6IDFweCBzb2xpZCAkc2hhcms7XG4gIGJvcmRlci1yYWRpdXM6IDgycHg7XG4gIHBhZGRpbmc6IDZweDtcbiAgZmxleDogMCAwIGF1dG87XG5cbiAgJi5ldGhlcmV1bS1uZXR3b3JrIHtcbiAgICBib3JkZXItY29sb3I6IHJnYigzLCAxMzUsIDEzNyk7XG5cbiAgICAubWVudS1pY29uLWNpcmNsZSBkaXYge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgzLCAxMzUsIDEzNywgLjcpICFpbXBvcnRhbnQ7XG4gICAgfVxuICB9XG5cbiAgJi5yb3BzdGVuLXRlc3QtbmV0d29yayB7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2IoMjMzLCAyMSwgODApO1xuXG4gICAgLm1lbnUtaWNvbi1jaXJjbGUgZGl2IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjMzLCAyMSwgODAsIC43KSAhaW1wb3J0YW50O1xuICAgIH1cbiAgfVxuXG4gICYua292YW4tdGVzdC1uZXR3b3JrIHtcbiAgICBib3JkZXItY29sb3I6IHJnYigxMDUsIDQsIDE1MCk7XG5cbiAgICAubWVudS1pY29uLWNpcmNsZSBkaXYge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxMDUsIDQsIDE1MCwgLjcpICFpbXBvcnRhbnQ7XG4gICAgfVxuICB9XG5cbiAgJi5yaW5rZWJ5LXRlc3QtbmV0d29yayB7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2IoMjM1LCAxNzksIDYzKTtcblxuICAgIC5tZW51LWljb24tY2lyY2xlIGRpdiB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIzNSwgMTc5LCA2MywgLjcpICFpbXBvcnRhbnQ7XG4gICAgfVxuICB9XG59XG5cbi5kcm9wZG93bi1tZW51LWl0ZW0ge1xuICAubWVudS1pY29uLWNpcmNsZSxcbiAgLm1lbnUtaWNvbi1jaXJjbGUtLWFjdGl2ZSB7XG4gICAgbWFyZ2luOiAwIDE0cHg7XG4gIH1cbn1cblxuLm5ldHdvcmstaW5kaWNhdG9yIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1zaXplOiAuNmVtO1xuXG4gIC5mYS1jYXJldC1kb3duIHtcbiAgICBsaW5lLWhlaWdodDogMTVweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgcGFkZGluZzogMCA0cHg7XG4gIH1cbn1cblxuLm5ldHdvcmstbmFtZSB7XG4gIGxpbmUtaGVpZ2h0OiAxNXB4O1xuICBwYWRkaW5nOiAwIDRweDtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgZm9udC1zaXplOiAxMnB4O1xuICBmbGV4OiAxIDAgYXV0bztcbn1cblxuLm5ldHdvcmstZHJvcHBvIHtcbiAgcmlnaHQ6IDJweDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA1NzZweCkge1xuICAgIHJpZ2h0OiBjYWxjKCgoMTAwJSAtIDg1dncpIC8gMikgKyAycHgpO1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzY5cHgpIHtcbiAgICByaWdodDogY2FsYygoKDEwMCUgLSA4MHZ3KSAvIDIpICsgMnB4KTtcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDEyODFweCkge1xuICAgIHJpZ2h0OiBjYWxjKCgoMTAwJSAtIDY1dncpIC8gMikgKyAycHgpO1xuICB9XG59XG5cbi5uZXR3b3JrLW5hbWUtaXRlbSB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7XG4gIGZsZXg6IDEgMCBhdXRvO1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG59XG5cbi5uZXR3b3JrLWNoZWNrLFxuLm5ldHdvcmstY2hlY2tfX3RyYW5zcGFyZW50IHtcbiAgY29sb3I6ICR3aGl0ZTtcbiAgbWFyZ2luLWxlZnQ6IDdweDtcbn1cblxuLm5ldHdvcmstY2hlY2tfX3RyYW5zcGFyZW50IHtcbiAgb3BhY2l0eTogMDtcbiAgd2lkdGg6IDE2cHg7XG4gIG1hcmdpbjogMDtcbn1cblxuLm1lbnUtaWNvbi1jaXJjbGUsXG4ubWVudS1pY29uLWNpcmNsZS0tYWN0aXZlIHtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogMjJweDtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICBtYXJnaW46IDAgNHB4O1xufVxuXG4ubWVudS1pY29uLWNpcmNsZS0tYWN0aXZlIHtcbiAgYm9yZGVyOiAxcHggc29saWQgJHdoaXRlO1xuICBiYWNrZ3JvdW5kOiByZ2JhKDEwMCwgMTAwLCAxMDAsIC40KTtcbn1cblxuLm1lbnUtaWNvbi1jaXJjbGUgZGl2LFxuLm1lbnUtaWNvbi1jaXJjbGUtLWFjdGl2ZSBkaXYge1xuICBoZWlnaHQ6IDEycHg7XG4gIHdpZHRoOiAxMnB4O1xuICBib3JkZXItcmFkaXVzOiAxN3B4O1xufVxuXG4ubWVudS1pY29uLWNpcmNsZS0tYWN0aXZlIGRpdiB7XG4gIG9wYWNpdHk6IDE7XG59XG5cbi5uZXR3b3JrLWRyb3Bkb3duLWhlYWRlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIHdpZHRoOiAxMDAlO1xufVxuXG4ubmV0d29yay1kcm9wZG93bi1kaXZpZGVyIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMXB4O1xuICBtYXJnaW46IDEwcHggMDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJHNjb3JwaW9uO1xufVxuXG4ubmV0d29yay1kcm9wZG93bi10aXRsZSB7XG4gIGhlaWdodDogMjVweDtcbiAgd2lkdGg6IDc1cHg7XG4gIGNvbG9yOiAkd2hpdGU7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIGZvbnQtc2l6ZTogMThweDtcbiAgbGluZS1oZWlnaHQ6IDI1cHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbn1cblxuLm5ldHdvcmstZHJvcGRvd24tY29udGVudCB7XG4gIGhlaWdodDogMzZweDtcbiAgd2lkdGg6IDI2NXB4O1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgbGluZS1oZWlnaHQ6IDE4cHg7XG59XG5cbiIsIi5tb2RhbCA+IGRpdjpmb2N1cyB7XG4gIG91dGxpbmU6IG5vbmUgIWltcG9ydGFudDtcbn1cblxuLy8gQnV5IE1vZGFsXG4uYnV5LW1vZGFsLWNvbnRlbnQge1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuICBwYWRkaW5nOiAwIDE2cHg7XG59XG5cbi5idXktbW9kYWwtY29udGVudC1vcHRpb24ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGNvbG9yOiAjNUI1RDY3O1xufVxuXG4ucXItZWxsaXAtYWRkcmVzcywgLmVsbGlwLWFkZHJlc3Mge1xuICB3aWR0aDogMjQ3cHg7XG4gIGJvcmRlcjogbm9uZTtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgZm9udC1zaXplOiAxNHB4O1xufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1NzVweCkge1xuICAuYnV5LW1vZGFsLWNvbnRlbnQtdGl0bGUtd3JhcHBlciB7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1hcm91bmQ7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDBweDtcbiAgfVxuXG4gIC5idXktbW9kYWwtY29udGVudC10aXRsZSB7XG4gICAgZm9udC1zaXplOiAyNnB4O1xuICAgIG1hcmdpbi10b3A6IDE1cHg7XG4gIH1cblxuICAuYnV5LW1vZGFsLWNvbnRlbnQtb3B0aW9ucyB7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBwYWRkaW5nOiA1JSAzMyU7XG4gIH1cblxuICAuYnV5LW1vZGFsLWNvbnRlbnQtZm9vdGVyIHtcbiAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogNTBweDtcbiAgfVxuXG4gIGRpdi5idXktbW9kYWwtY29udGVudC1vcHRpb24ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICB3aWR0aDogODB2dztcbiAgICBoZWlnaHQ6IDE1dmg7XG4gICAgbWFyZ2luOiAxMHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgJGJsYWNrO1xuICAgIHBhZGRpbmc6IDAlIDclO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgZGl2LmJ1eS1tb2RhbC1jb250ZW50LW9wdGlvbi10aXRsZSB7XG4gICAgICBmb250LXNpemU6IDIwcHg7XG4gICAgfVxuXG4gICAgZGl2LmJ1eS1tb2RhbC1jb250ZW50LW9wdGlvbi1zdWJ0aXRsZSB7XG4gICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgfVxuICB9XG59XG5cbkBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDU3NnB4KSB7XG4gIC5idXktbW9kYWwtY29udGVudC10aXRsZS13cmFwcGVyIHtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDExMHB4O1xuICB9XG5cbiAgLmJ1eS1tb2RhbC1jb250ZW50LXRpdGxlIHtcbiAgICBmb250LXNpemU6IDI2cHg7XG4gICAgbWFyZ2luLXRvcDogMTVweDtcbiAgfVxuXG4gIC5idXktbW9kYWwtY29udGVudC1mb290ZXIge1xuICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiA1MHB4O1xuICB9XG5cbiAgLmJ1eS1tb2RhbC1jb250ZW50LW9wdGlvbnMge1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgbWFyZ2luOiAyMHB4IDAgNjBweDtcbiAgfVxuXG4gIGRpdi5idXktbW9kYWwtY29udGVudC1vcHRpb24ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICB3aWR0aDogMjB2dztcbiAgICBoZWlnaHQ6IDEyMHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgJGJsYWNrO1xuICAgIG1hcmdpbjogMCA4cHg7XG4gICAgcGFkZGluZzogMThweCAwO1xuXG4gICAgZGl2LmJ1eS1tb2RhbC1jb250ZW50LW9wdGlvbi10aXRsZSB7XG4gICAgICBmb250LXNpemU6IDIwcHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuXG4gICAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA2NzlweCkge1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICB9XG5cbiAgICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDEyODFweCkge1xuICAgICAgICBmb250LXNpemU6IDIwcHg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZGl2LmJ1eS1tb2RhbC1jb250ZW50LW9wdGlvbi1zdWJ0aXRsZSB7XG4gICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICBwYWRkaW5nOiAwIDEwcHg7XG4gICAgICBoZWlnaHQ6IDI1JTtcblxuICAgICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNjc5cHgpIHtcbiAgICAgICAgZm9udC1zaXplOiAxMHB4O1xuICAgICAgICBwYWRkaW5nOiAwIDEwcHg7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDVweDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDE1cHg7XG4gICAgICB9XG5cbiAgICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDY4MHB4KSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgcGFkZGluZzogMCA0cHg7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDJweDtcbiAgICAgIH1cblxuICAgICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTI4MXB4KSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBkaXYuYnV5LW1vZGFsLWNvbnRlbnQtZm9vdGVyIHtcbiAgICAgIG1hcmdpbi10b3A6IDh2aDtcbiAgICB9XG4gIH1cbn1cblxuLy8gRWRpdCBBY2NvdW50IE5hbWUgTW9kYWxcbi5lZGl0LWFjY291bnQtbmFtZS1tb2RhbC1jb250ZW50IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5lZGl0LWFjY291bnQtbmFtZS1tb2RhbC1jYW5jZWwge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMTJweDtcbiAgcmlnaHQ6IDIwcHg7XG4gIGZvbnQtc2l6ZTogMjVweDtcbn1cblxuLmVkaXQtYWNjb3VudC1uYW1lLW1vZGFsLXRpdGxlIHtcbiAgbWFyZ2luOiAxNXB4O1xufVxuXG4uZWRpdC1hY2NvdW50LW5hbWUtbW9kYWwtc2F2ZS1idXR0b24ge1xuICB3aWR0aDogMzMlO1xuICBoZWlnaHQ6IDQ1cHg7XG4gIG1hcmdpbjogMTVweDtcbiAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgbWFyZ2luLXRvcDogMjVweDtcbn1cblxuLmVkaXQtYWNjb3VudC1uYW1lLW1vZGFsLWlucHV0IHtcbiAgd2lkdGg6IDkwJTtcbiAgaGVpZ2h0OiA1MHB4O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBtYXJnaW46IDEwcHg7XG4gIHBhZGRpbmc6IDEwcHg7XG4gIGZvbnQtc2l6ZTogMThweDtcbn1cblxuLy8gQWNjb3VudCBNb2RhbCBDb250YWluZXJcbi5hY2NvdW50LW1vZGFsLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBwYWRkaW5nOiA1cHggMCAzMXB4IDA7XG4gIGJvcmRlcjogMXB4IHNvbGlkICRzaWx2ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcblxuICBidXR0b24ge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgfVxufVxuXG4uYWNjb3VudC1tb2RhbC1iYWNrIHtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMTNweDtcbiAgbGVmdDogMTdweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuXG4gICZfX3RleHQge1xuICAgIG1hcmdpbi10b3A6IDJweDtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMThweDtcbiAgfVxufVxuXG4uYWNjb3VudC1tb2RhbC1jbG9zZTo6YWZ0ZXIge1xuICBjb250ZW50OiAnXFwwMEQ3JztcbiAgZm9udC1zaXplOiA0MHB4O1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAxMHB4O1xuICByaWdodDogMTJweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uYWNjb3VudC1tb2RhbC1jb250YWluZXIgLmlkZW50aWNvbiB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgbGVmdDogMDtcbiAgcmlnaHQ6IDA7XG4gIG1hcmdpbjogMCBhdXRvO1xuICB0b3A6IC0zMnB4O1xuICBtYXJnaW4tYm90dG9tOiAtMzJweDtcbn1cblxuXG4vLyBBY2NvdW50IERldGFpbHMgTW9kYWxcblxuLmFjY291bnQtbW9kYWwtY29udGFpbmVyIHtcblxuICAucXItaGVhZGVyIHtcbiAgICBtYXJnaW4tdG9wOiA5cHg7XG4gICAgZm9udC1zaXplOiAyMHB4O1xuICB9XG5cbiAgLnFyLXdyYXBwZXIge1xuICAgIG1hcmdpbi10b3A6IDVweDtcbiAgfVxuXG4gIC5lbGxpcC1hZGRyZXNzLXdyYXBwZXIge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgYm9yZGVyOiAxcHggc29saWQgJGFsdG87XG4gICAgcGFkZGluZzogNXB4IDEwcHg7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBtYXJnaW4tdG9wOiA3cHg7XG4gICAgd2lkdGg6IDI4NnB4O1xuICB9XG5cbiAgLmJ0bi1jbGVhciB7XG4gICAgbWluLWhlaWdodDogMjhweDtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgYm9yZGVyLWNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICAgIGNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICBmbGV4LWJhc2lzOiAxMDAlO1xuICAgIHdpZHRoOiA3NSU7XG4gICAgbWFyZ2luLXRvcDogMTdweDtcbiAgICBwYWRkaW5nOiAxMHB4IDIycHg7XG4gICAgaGVpZ2h0OiA0NHB4O1xuICAgIHdpZHRoOiAyMzVweDtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICB9XG59XG5cbi5hY2NvdW50LW1vZGFsLWRpdmlkZXIge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxcHg7XG4gIG1hcmdpbjogMTlweCAwIDhweCAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkYWx0bztcbn1cblxuLy8gRXhwb3J0IFByaXZhdGUgS2V5IE1vZGFsXG5cbi5hY2NvdW50LW1vZGFsLWNvbnRhaW5lciAuYWNjb3VudC1uYW1lIHtcbiAgbWFyZ2luLXRvcDogOXB4O1xuICBmb250LXNpemU6IDIwcHg7XG59XG5cbi5hY2NvdW50LW1vZGFsLWNvbnRhaW5lciAubW9kYWwtYm9keS10aXRsZSB7XG4gIG1hcmdpbi10b3A6IDE2cHg7XG4gIG1hcmdpbi1ib3R0b206IDE2cHg7XG4gIGZvbnQtc2l6ZTogMThweDtcbn1cblxuLmFjY291bnQtbW9kYWxfX25hbWUge1xuICBtYXJnaW4tdG9wOiA5cHg7XG4gIGZvbnQtc2l6ZTogMjBweDtcbn1cblxuLnByaXZhdGUta2V5LXBhc3N3b3JkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbn1cblxuLnByaXZhdGUta2V5LXBhc3N3b3JkLWxhYmVsLCAucHJpdmF0ZS1rZXktcGFzc3dvcmQtZXJyb3Ige1xuICBjb2xvcjogJHNjb3JwaW9uO1xuICBmb250LXNpemU6IDE0cHg7XG4gIGxpbmUtaGVpZ2h0OiAxOHB4O1xuICBtYXJnaW4tYm90dG9tOiAxMHB4O1xufVxuXG4ucHJpdmF0ZS1rZXktcGFzc3dvcmQtZXJyb3Ige1xuICBjb2xvcjogJGNyaW1zb247XG4gIG1hcmdpbi1ib3R0b206IDA7XG59XG5cbi5wcml2YXRlLWtleS1wYXNzd29yZC1pbnB1dCB7XG4gIHBhZGRpbmc6IDEwcHggMCAxM3B4IDE3cHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDIxcHg7XG4gIHdpZHRoOiAyOTFweDtcbiAgaGVpZ2h0OiA0NHB4O1xufVxuXG4ucHJpdmF0ZS1rZXktcGFzc3dvcmQ6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXIge1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG59XG5cbi5wcml2YXRlLWtleS1wYXNzd29yZC13YXJuaW5nIHtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkZGNkY2O1xuICBmb250LXNpemU6IDEycHg7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7XG4gIGxpbmUtaGVpZ2h0OiAxNXB4O1xuICBjb2xvcjogJGNyaW1zb247XG4gIHdpZHRoOiAyOTJweDtcbiAgcGFkZGluZzogOXB4IDE1cHg7XG4gIG1hcmdpbi10b3A6IDE4cHg7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG59XG5cbi5leHBvcnQtcHJpdmF0ZS1rZXktYnV0dG9ucyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gIC5idG4tY2xlYXIge1xuICAgIHdpZHRoOiAxNDFweDtcbiAgICBoZWlnaHQ6IDU0cHg7XG4gIH1cblxuICAuYnRuLWNhbmNlbCB7XG4gICAgbWFyZ2luLXJpZ2h0OiAxNXB4O1xuICAgIGJvcmRlci1jb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgfVxufVxuXG4ucHJpdmF0ZS1rZXktcGFzc3dvcmQtZGlzcGxheS13cmFwcGVyIHtcbiAgaGVpZ2h0OiA4MHB4O1xuICB3aWR0aDogMjkxcHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkICRzaWx2ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cblxuLnByaXZhdGUta2V5LXBhc3N3b3JkLWRpc3BsYXktdGV4dGFyZWEge1xuICBjb2xvcjogJGNyaW1zb247XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDIxcHg7XG4gIGJvcmRlcjogbm9uZTtcbiAgaGVpZ2h0OiA3NXB4O1xuICB3aWR0aDogMTAwJTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgcmVzaXplOiBub25lO1xuICBwYWRkaW5nOiA5cHggMTNweCA4cHg7XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIGZvbnQtd2VpZ2h0OiAzMDA7XG59XG5cblxuLy8gTmV3IEFjY291bnQgTW9kYWxcbi5uZXctYWNjb3VudC1tb2RhbC13cmFwcGVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGJvcmRlcjogMXB4IHNvbGlkICRhbHRvO1xuICBib3gtc2hhZG93OiAwIDAgMnB4IDJweCAkYWx0bztcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbn1cblxuLm5ldy1hY2NvdW50LW1vZGFsLWhlYWRlciB7XG4gIGJhY2tncm91bmQ6ICR3aWxkLXNhbmQ7XG4gIHdpZHRoOiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgcGFkZGluZzogMzBweDtcbiAgZm9udC1zaXplOiAyMnB4O1xuICBjb2xvcjogJG5pbGUtYmx1ZTtcbiAgaGVpZ2h0OiA3OXB4O1xufVxuXG4ubW9kYWwtY2xvc2UteDo6YWZ0ZXIge1xuICBjb250ZW50OiAnXFwwMEQ3JztcbiAgZm9udC1zaXplOiAyZW07XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDI1cHg7XG4gIHJpZ2h0OiAxNy41cHg7XG4gIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmO1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5uZXctYWNjb3VudC1tb2RhbC1jb250ZW50IHtcbiAgd2lkdGg6IDEwMCU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBtYXJnaW4tdG9wOiAxNXB4O1xuICBmb250LXNpemU6IDE3cHg7XG4gIGNvbG9yOiAkbmlsZS1ibHVlO1xufVxuXG4ubmV3LWFjY291bnQtbW9kYWwtY29udGVudC5hZnRlci1pbnB1dCB7XG4gIG1hcmdpbi10b3A6IDE1cHg7XG4gIGxpbmUtaGVpZ2h0OiAyNXB4O1xufVxuXG4ubmV3LWFjY291bnQtaW5wdXQtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIHdpZHRoOiAxMDAlO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgcGFkZGluZy1ib3R0b206IDJweDtcbiAgbWFyZ2luLXRvcDogMTNweDtcbn1cblxuLm5ldy1hY2NvdW50LWlucHV0IHtcbiAgcGFkZGluZzogMTVweDtcbiAgcGFkZGluZy1ib3R0b206IDIwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgYm9yZGVyOiAxcHggc29saWQgJGFsdG87XG4gIHdpZHRoOiAxMDAlO1xuICBmb250LXNpemU6IDFlbTtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuICBmb250LXNpemU6IDE3cHg7XG4gIG1hcmdpbjogMCA2MHB4O1xufVxuXG4vLyBGb3IgcmVmZXJlbmNlIG9uIGJlbG93IHBsYWNlaG9sZGVyIHNlbGVjdG9yczogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjYxMDQ5Ny9jaGFuZ2UtYW4taHRtbDUtaW5wdXRzLXBsYWNlaG9sZGVyLWNvbG9yLXdpdGgtY3NzXG4ubmV3LWFjY291bnQtaW5wdXQ6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXIge1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG59XG5cbi5uZXctYWNjb3VudC1pbnB1dDotbW96LXBsYWNlaG9sZGVyIHtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICBvcGFjaXR5OiAxO1xufVxuXG4ubmV3LWFjY291bnQtaW5wdXQ6Oi1tb3otcGxhY2Vob2xkZXIge1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIG9wYWNpdHk6IDE7XG59XG5cbi5uZXctYWNjb3VudC1pbnB1dDotbXMtaW5wdXQtcGxhY2Vob2xkZXIge1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG59XG5cbi5uZXctYWNjb3VudC1pbnB1dDo6LW1zLWlucHV0LXBsYWNlaG9sZGVyIHtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xufVxuXG4ubmV3LWFjY291bnQtbW9kYWwtY29udGVudC5idXR0b24ge1xuICBtYXJnaW4tdG9wOiAyMnB4O1xuICBtYXJnaW4tYm90dG9tOiAzMHB4O1xuICB3aWR0aDogMTEzcHg7XG4gIGhlaWdodDogNDRweDtcbn1cblxuLm5ldy1hY2NvdW50LW1vZGFsLXdyYXBwZXIgLmJ0bi1jbGVhciB7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgYmFja2dyb3VuZDogJHdoaXRlO1xuICBib3JkZXI6IDFweCBzb2xpZDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBjb2xvcjogJHR1bmRvcmE7XG4gIGZsZXg6IDE7XG59XG5cbi8vIEhpZGUgdG9rZW4gY29uZmlybWF0aW9uXG5cbi5oaWRlLXRva2VuLWNvbmZpcm1hdGlvbiB7XG4gIG1pbi1oZWlnaHQ6IDI1MC43MnB4O1xuICB3aWR0aDogMzc0LjQ5cHg7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI0ZGRkZGRjtcbiAgYm94LXNoYWRvdzogMCAxcHggN3B4IDAgcmdiYSgwLDAsMCwwLjUpO1xuXG4gICZfX2NvbnRhaW5lciB7XG4gICAgcGFkZGluZzogMjRweCAyN3B4IDIxcHg7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIH1cblxuICAmX19pZGVudGljb24ge1xuICAgIG1hcmdpbi1ib3R0b206IDEwcHhcbiAgfVxuXG4gICZfX3N5bWJvbCB7XG4gICAgY29sb3I6ICR0dW5kb3JhO1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAyNHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBtYXJnaW4tYm90dG9tOiA3LjVweDtcbiAgfVxuXG4gICZfX3RpdGxlIHtcbiAgICBoZWlnaHQ6IDMwcHg7XG4gICAgd2lkdGg6IDI3MS4yOHB4O1xuICAgIGNvbG9yOiAkdHVuZG9yYTtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGZvbnQtc2l6ZTogMjJweDtcbiAgICBsaW5lLWhlaWdodDogMzBweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgbWFyZ2luLWJvdHRvbTogMTAuNXB4O1xuICB9XG5cbiAgJl9fY29weSB7XG4gICAgaGVpZ2h0OiA0MXB4O1xuICAgIHdpZHRoOiAzMThweDtcbiAgICBjb2xvcjogJHNjb3JwaW9uO1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxOHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgfVxuXG4gICZfX2J1dHRvbnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBtYXJnaW4tdG9wOiAxNXB4O1xuICAgIHdpZHRoOiAxMDAlO1xuXG4gICAgYnV0dG9uIHtcbiAgICAgIGhlaWdodDogNDRweDtcbiAgICAgIHdpZHRoOiAxMTNweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICRzY29ycGlvbjtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgIGNvbG9yOiAkdHVuZG9yYTtcbiAgICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICBsaW5lLWhlaWdodDogMjBweDtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIG1hcmdpbi1sZWZ0OiA0cHg7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDRweDtcbiAgICB9XG4gIH1cbn1cbiIsIi8qXG4gIE5ld1VJIENvbnRhaW5lciBFbGVtZW50c1xuICovXG5cbi8vIENvbXBvbmVudCBDb2xvcnNcbiR0eC12aWV3LWJnOiAkd2hpdGU7XG4kd2FsbGV0LXZpZXctYmc6ICR3aWxkLXNhbmQ7XG5cbi8vIE1haW4gY29udGFpbmVyXG4ubWFpbi1jb250YWluZXIge1xuICAvLyBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHotaW5kZXg6ICRtYWluLWNvbnRhaW5lci16LWluZGV4O1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LXdyYXA6IHdyYXA7XG4gIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xufVxuXG4ubWFpbi1jb250YWluZXI6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLy8gdHggdmlld1xuXG4udHgtdmlldyB7XG4gIGZsZXg6IDYzLjUgMCA2Ni41JTtcbiAgYmFja2dyb3VuZDogJHR4LXZpZXctYmc7XG5cbiAgLy8gTm8gdGl0bGUgb24gbW9iaWxlXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgLmlkZW50aWNvbi13cmFwcGVyIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxuXG4gICAgLmFjY291bnQtbmFtZSB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbiAgfVxufVxuXG4vLyB3YWxsZXQgdmlldyBhbmQgc2lkZWJhclxuXG4ud2FsbGV0LXZpZXcge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBmbGV4OiAzMy41IDEgMzMuNSU7XG4gIHdpZHRoOiAwO1xuICBiYWNrZ3JvdW5kOiAkd2FsbGV0LXZpZXctYmc7XG4gIHotaW5kZXg6IDIwMDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDU3NnB4KSB7XG4gICAgb3ZlcmZsb3cteTogc2Nyb2xsO1xuICAgIG92ZXJmbG93LXg6IGhpZGRlbjtcbiAgfVxuXG4gIC53YWxsZXQtdmlldy1hY2NvdW50LWRldGFpbHMge1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICB9XG5cbiAgJl9fbmFtZS1jb250YWluZXIge1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB3aWR0aDogMTAwJTtcbiAgfVxuXG4gICZfX2tleXJpbmctbGFiZWwge1xuICAgIGhlaWdodDogNDBweDtcbiAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDEwcHg7XG4gICAgbGluZS1oZWlnaHQ6IDQwcHg7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgcGFkZGluZzogMCAyMHB4O1xuICB9XG5cbiAgJl9fZGV0YWlscy1idXR0b24ge1xuICAgIGNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICBsaW5lLWhlaWdodDogMTNweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgYm9yZGVyOiAxcHggc29saWQgJGN1cmlvdXMtYmx1ZTtcbiAgICBib3JkZXItcmFkaXVzOiAxMC41cHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgbWFyZ2luOiAwIGF1dG87XG4gICAgcGFkZGluZzogNHB4IDEycHg7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICAmX19hZGRyZXNzIHtcbiAgICBib3JkZXItcmFkaXVzOiAzcHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGFsdG87XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEycHg7XG4gICAgcGFkZGluZzogNHB4IDEycHg7XG4gICAgbWFyZ2luOiAyNHB4IGF1dG87XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICAmX19zaWRlYmFyLWNsb3NlIHtcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgICAmOjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6ICdcXDAwRDcnO1xuICAgICAgICBmb250LXNpemU6IDQwcHg7XG4gICAgICAgIGNvbG9yOiAkdHVuZG9yYTtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB0b3A6IDEycHg7XG4gICAgICAgIGxlZnQ6IDEycHg7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAmX19hZGQtdG9rZW4tYnV0dG9uIHtcbiAgICBmbGV4OiAwIDAgYXV0bztcbiAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxOXB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBtYXJnaW46IDM2cHggYXV0bztcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkZHVzdHktZ3JheTtcbiAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgIHBhZGRpbmc6IDlweCAzMHB4O1xuICB9XG59XG5cbkBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDU3NnB4KSB7XG4gIC53YWxsZXQtdmlldzo6LXdlYmtpdC1zY3JvbGxiYXIge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cblxuLndhbGxldC12aWV3LXRpdGxlLXdyYXBwZXIge1xuICBmbGV4OiAwIDAgMjVweDtcbn1cblxuLndhbGxldC12aWV3LXRpdGxlIHtcbiAgbWFyZ2luLWxlZnQ6IDE1cHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcblxuICAvLyBObyB0aXRsZSBvbiBtb2JpbGVcbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG59XG5cbi53YWxsZXQtdmlldy5zaWRlYmFyIHtcbiAgZmxleDogMSAwIDIzMHB4O1xuICBiYWNrZ3JvdW5kOiByZ2IoMjUwLCAyNTAsIDI1MCk7XG4gIHotaW5kZXg6ICRzaWRlYmFyLXotaW5kZXg7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiA1NnB4O1xuICBsZWZ0OiAwO1xuICByaWdodDogMDtcbiAgYm90dG9tOiAwO1xuICBvcGFjaXR5OiAxO1xuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xuICB3aWxsLWNoYW5nZTogdHJhbnNmb3JtO1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICBib3gtc2hhZG93OiByZ2JhKDAsIDAsIDAsIC4xNSkgMnB4IDJweCA0cHg7XG4gIHdpZHRoOiA4NSU7XG4gIGhlaWdodDogY2FsYygxMDAlIC0gNTZweCk7XG59XG5cbi5zaWRlYmFyLW92ZXJsYXkge1xuICB6LWluZGV4OiAkc2lkZWJhci1vdmVybGF5LXotaW5kZXg7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgLy8gdG9wOiA0MXB4O1xuICBoZWlnaHQ6IDEwMCU7XG4gIHdpZHRoOiAxMDAlO1xuICBsZWZ0OiAwO1xuICByaWdodDogMDtcbiAgYm90dG9tOiAwO1xuICBvcGFjaXR5OiAxO1xuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIC4zKTtcbn1cblxuLy8gbWFpbi1jb250YWluZXIgbWVkaWEgcXVlcmllc1xuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA1NzZweCkge1xuICAubGFwLXZpc2libGUge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gIH1cblxuICAucGhvbmUtdmlzaWJsZSB7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgfVxuXG4gIC5tYWluLWNvbnRhaW5lciB7XG4gICAgLy8gbWFyZ2luLXRvcDogNi45dmg7XG4gICAgd2lkdGg6IDg1JTtcbiAgICBoZWlnaHQ6IDkwdmg7XG4gICAgYm94LXNoYWRvdzogMCAwIDdweCAwIHJnYmEoMCwgMCwgMCwgLjA4KTtcbiAgfVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3NjlweCkge1xuICAubWFpbi1jb250YWluZXIge1xuICAgIC8vIG1hcmdpbi10b3A6IDYuOXZoO1xuICAgIHdpZHRoOiA4MCU7XG4gICAgaGVpZ2h0OiA4MnZoO1xuICAgIGJveC1zaGFkb3c6IDAgMCA3cHggMCByZ2JhKDAsIDAsIDAsIC4wOCk7XG4gIH1cbn1cblxuQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTI4MXB4KSB7XG4gIC5tYWluLWNvbnRhaW5lciB7XG4gICAgLy8gbWFyZ2luLXRvcDogNi45dmg7XG4gICAgd2lkdGg6IDY1JTtcbiAgICBoZWlnaHQ6IDgydmg7XG4gICAgYm94LXNoYWRvdzogMCAwIDdweCAwIHJnYmEoMCwgMCwgMCwgLjA4KTtcbiAgfVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1NzVweCkge1xuICAubGFwLXZpc2libGUge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAucGhvbmUtdmlzaWJsZSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgfVxuXG4gIC5tYWluLWNvbnRhaW5lciB7XG4gICAgLy8gbWFyZ2luLXRvcDogNDFweDtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gIH1cblxuICBidXR0b24uYnRuLWNsZWFyIHtcbiAgICB3aWR0aDogOTNweDtcbiAgICBoZWlnaHQ6IDUwcHg7XG4gICAgZm9udC1zaXplOiAuN2VtO1xuICAgIGJhY2tncm91bmQ6ICR3aGl0ZTtcbiAgICBib3JkZXI6IDFweCBzb2xpZDtcbiAgfVxufVxuXG4vLyB3YWxsZXQgdmlld1xuLmFjY291bnQtbmFtZSB7XG4gIGZvbnQtc2l6ZTogMjRweDtcbiAgZm9udC13ZWlnaHQ6IDIwMDtcbiAgbGluZS1oZWlnaHQ6IDIwcHg7XG4gIGNvbG9yOiAkc2NvcnBpb247XG4gIG1hcmdpbi10b3A6IDhweDtcbiAgbWFyZ2luLWJvdHRvbTogMjRweDtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHdpZHRoOiAxMDAlO1xuICBwYWRkaW5nOiAwIDhweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG4vLyBhY2NvdW50IG9wdGlvbnMgZHJvcGRvd25cbi5hY2NvdW50LW9wdGlvbnMtbWVudSB7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbiAgbWFyZ2luOiA1JSA3JSAwJTtcbn1cblxuLmZpYXQtYW1vdW50IHtcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbn1cblxuLnRva2VuLWJhbGFuY2VfX2Ftb3VudCB7XG4gIHBhZGRpbmctcmlnaHQ6IDZweDtcbn1cbiIsIi5hY2NvdW50LWRyb3Bkb3duLW5hbWUge1xuICBmb250LWZhbWlseTogUm9ib3RvO1xufVxuXG4uYWNjb3VudC1kcm9wZG93bi1iYWxhbmNlIHtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICBsaW5lLWhlaWdodDogMTlweDtcbn1cblxuLmFjY291bnQtZHJvcGRvd24tZWRpdC1idXR0b24ge1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG5cbiAgJjpob3ZlciB7XG4gICAgY29sb3I6ICR3aGl0ZTtcbiAgfVxufVxuXG4uYWNjb3VudC1saXN0LWl0ZW0ge1xuICAmX190b3Atcm93IHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIH1cblxuICAmX19hY2NvdW50LWJhbGFuY2VzIHtcbiAgICBoZWlnaHQ6IGF1dG87XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIGNvbG9yOiAjOWI5YjliO1xuICAgIG1hcmdpbi1sZWZ0OiAzNHB4O1xuICAgIG1hcmdpbi10b3A6IDRweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIH1cbiAgXG4gICZfX2FjY291bnQtbmFtZSB7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIG1hcmdpbi1sZWZ0OiA4cHg7XG4gIH1cblxuICAmX19pY29uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDEycHg7XG4gICAgdG9wOiAxcHg7XG4gIH1cblxuICAmX19hY2NvdW50LXByaW1hcnktYmFsYW5jZSxcbiAgJl9fYWNjb3VudC1zZWNvbmRhcnktYmFsYW5jZSB7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBsaW5lLWhlaWdodDogMTZweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgfVxuXG4gICZfX2FjY291bnQtcHJpbWFyeS1iYWxhbmNlIHtcbiAgICBjb2xvcjogJHNjb3JwaW9uO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBvdXRsaW5lOiAwICFpbXBvcnRhbnQ7XG4gIH1cblxuICAmX19hY2NvdW50LXNlY29uZGFyeS1iYWxhbmNlIHtcbiAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIH1cblxuICAmX19hY2NvdW50LWFkZHJlc3Mge1xuICAgIG1hcmdpbi1sZWZ0OiAzNXB4O1xuICAgIHdpZHRoOiA4MCU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgfVxuXG4gICZfX2Ryb3Bkb3duIHtcbiAgICAmOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQ6IHJnYmEoJGFsdG8sIC4yKTtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcblxuICAgICAgaW5wdXQge1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKCRhbHRvLCAuMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIuc2VuZC1zY3JlZW4td3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgei1pbmRleDogMjU7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgfVxuXG4gIHNlY3Rpb24ge1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICB9XG59XG5cbi5zZW5kLXNjcmVlbi1jYXJkIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgYm94LXNoYWRvdzogMCAycHggNHB4IDAgcmdiYSgwLCAwLCAwLCAuMDgpO1xuICBwYWRkaW5nOiA0NnB4IDQwLjVweCAyNnB4O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIC8vIHRvcDogLTI2cHg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgd2lkdGg6IDQ5OHB4O1xuICBmbGV4OiAxIDAgYXV0bztcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBwYWRkaW5nOiAxMnB4O1xuICB9XG59XG5cbi8qIFNlbmQgU2NyZWVuICovXG5cbi5zZW5kLXNjcmVlbiBzZWN0aW9uIHtcbiAgbWFyZ2luOiA0cHggMTZweDtcbn1cblxuLnNlbmQtc2NyZWVuIGlucHV0IHtcbiAgd2lkdGg6IDEwMCU7XG4gIGZvbnQtc2l6ZTogMTJweDtcbn1cblxuLnNlbmQtZXRoLWljb24ge1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG4gIHdpZHRoOiA3MHB4O1xuICBoZWlnaHQ6IDcwcHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkICRhbHRvO1xuICBib3gtc2hhZG93OiAwIDAgNHB4IDAgcmdiYSgwLCAwLCAwLCAuMik7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAtMzVweDtcbiAgei1pbmRleDogMjU7XG4gIHBhZGRpbmc6IDRweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB0b3A6IDA7XG4gIH1cbn1cblxuLnNlbmQtc2NyZWVuLWlucHV0LXdyYXBwZXIge1xuICB3aWR0aDogOTUlO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgLmZhLWJvbHQge1xuICAgIHBhZGRpbmctcmlnaHQ6IDRweDtcbiAgfVxuXG4gIC5sYXJnZS1pbnB1dCB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgJGR1c3R5LWdyYXk7XG4gICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgIG1hcmdpbjogNHB4IDAgMjBweDtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbGluZS1oZWlnaHQ6IDIyLjRweDtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICB9XG5cbiAgLnNlbmQtc2NyZWVuLWdhcy1pbnB1dCB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gIH1cblxuICAmX19lcnJvci1tZXNzYWdlIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG5cbiAgJi0tZXJyb3Ige1xuICAgIGlucHV0LFxuICAgIC5zZW5kLXNjcmVlbi1nYXMtaW5wdXQge1xuICAgICAgYm9yZGVyLWNvbG9yOiAkcmVkICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnNlbmQtc2NyZWVuLWlucHV0LXdyYXBwZXJfX2Vycm9yLW1lc3NhZ2Uge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICBib3R0b206IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxMnB4O1xuICAgICAgbGVmdDogOHB4O1xuICAgICAgY29sb3I6ICRyZWQ7XG4gICAgfVxuICB9XG5cbiAgLnNlbmQtc2NyZWVuLWlucHV0LXdyYXBwZXJfX2Vycm9yLW1lc3NhZ2Uge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBib3R0b206IDRweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbGluZS1oZWlnaHQ6IDEycHg7XG4gICAgbGVmdDogOHB4O1xuICAgIGNvbG9yOiAkcmVkO1xuICB9XG59XG5cbi5zZW5kLXNjcmVlbi1pbnB1dCB7XG4gIHdpZHRoOiAxMDAlO1xufVxuXG4uc2VuZC1zY3JlZW4tZ2FzLWlucHV0IHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNDFweDtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjNmM2YzO1xuICBib3JkZXItd2lkdGg6IDA7XG4gIGJvcmRlci1zdHlsZTogbm9uZTtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBwYWRkaW5nLWxlZnQ6IDEwcHg7XG4gIHBhZGRpbmctcmlnaHQ6IDEycHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgY29sb3I6ICRzY29ycGlvbjtcbn1cblxuLnNlbmQtc2NyZWVuLWFtb3VudC1sYWJlbHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG59XG5cbi5zZW5kLXNjcmVlbi1nYXMtbGFiZWxzIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xufVxuXG4uY3VycmVuY3ktdG9nZ2xlIHtcbiAgJl9faXRlbSB7XG4gICAgY29sb3I6ICRjdXJpb3VzLWJsdWU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuXG4gICAgJi0tc2VsZWN0ZWQge1xuICAgICAgY29sb3I6ICRibGFjaztcbiAgICAgIGN1cnNvcjogZGVmYXVsdDtcbiAgICB9XG4gIH1cbn1cblxuLnNlbmQtc2NyZWVuLWdhcy1pbnB1dC1jdXN0b21pemUge1xuICBjb2xvcjogJGN1cmlvdXMtYmx1ZTtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5nYXMtdG9vbHRpcC1jbG9zZS1hcmVhIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIGxlZnQ6IDA7XG4gIHotaW5kZXg6IDEwMDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5jdXN0b21pemUtZ2FzLXRvb2x0aXAtY29udGFpbmVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBib3R0b206IDUwcHg7XG4gIHdpZHRoOiAyMzdweDtcbiAgaGVpZ2h0OiAzMDdweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICBvcGFjaXR5OiAxO1xuICBib3gtc2hhZG93OiAkYWx0byAwIDAgNXB4O1xuICB6LWluZGV4OiAxMDUwO1xuICBwYWRkaW5nOiAxM3B4IDE5cHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBmb250LWZhbWlseTogXCJMYXRvXCI7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7XG59XG5cbi5nYXMtdG9vbHRpcC1hcnJvdyB7XG4gIGhlaWdodDogMjVweDtcbiAgd2lkdGg6IDI1cHg7XG4gIHotaW5kZXg6IDEyMDA7XG4gIGJhY2tncm91bmQ6ICR3aGl0ZTtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0cmFuc2Zvcm06IHJvdGF0ZSg0NWRlZyk7XG4gIGxlZnQ6IDEwN3B4O1xuICB0b3A6IDI5NHB4O1xuICBib3gtc2hhZG93OiAycHggMnB4IDJweCAkYWx0bztcbn1cblxuLmN1c3RvbWl6ZS1nYXMtdG9vbHRpcC1jb250YWluZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTo6LXdlYmtpdC1pbm5lci1zcGluLWJ1dHRvbiB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLmN1c3RvbWl6ZS1nYXMtdG9vbHRpcC1jb250YWluZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTpob3Zlcjo6LXdlYmtpdC1pbm5lci1zcGluLWJ1dHRvbiB7XG4gIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLmN1c3RvbWl6ZS1nYXMtdG9vbHRpcCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cblxuLmdhcy10b29sdGlwIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG59XG5cbi5nYXMtdG9vbHRpcC1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgY29sb3I6ICR0dW5kb3JhO1xufVxuXG4uZ2FzLXRvb2x0aXAtaGVhZGVyIHtcbiAgcGFkZGluZy1ib3R0b206IDEycHg7XG59XG5cbi5nYXMtdG9vbHRpcC1pbnB1dC1sYWJlbCB7XG4gIG1hcmdpbi1ib3R0b206IDVweDtcbn1cblxuLmdhcy10b29sdGlwLWlucHV0LWxhYmVsIGkge1xuICBjb2xvcjogJHNpbHZlci1jaGFsaWNlO1xuICBtYXJnaW4tbGVmdDogNnB4O1xufVxuXG4uY3VzdG9taXplLWdhcy1pbnB1dCB7XG4gIHdpZHRoOiAxNzhweDtcbiAgaGVpZ2h0OiAyOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgZm9udC1zaXplOiAxNnB4O1xuICBjb2xvcjogJG5pbGUtYmx1ZTtcbiAgcGFkZGluZy1sZWZ0OiA4cHg7XG59XG5cbi5jdXN0b21pemUtZ2FzLWlucHV0LXdyYXBwZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5nYXMtdG9vbHRpcC1pbnB1dC1kZXRhaWwge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogNHB4O1xuICByaWdodDogMjZweDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogJHNpbHZlci1jaGFsaWNlO1xufVxuXG4uZ2FzLXRvb2x0aXAtaW5wdXQtYXJyb3dzIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIHJpZ2h0OiA0cHg7XG4gIHdpZHRoOiAxN3B4O1xuICBoZWlnaHQ6IDI4cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkICNkYWRhZGE7XG4gIGJvcmRlci1sZWZ0OiAwO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBjb2xvcjogIzliOWI5YjtcbiAgZm9udC1zaXplOiAuOGVtO1xuICBwYWRkaW5nOiAxcHggNHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi50b2tlbi1nYXMge1xuICAmX19hbW91bnQge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBtYXJnaW4tcmlnaHQ6IDRweDtcbiAgfVxuXG4gICZfX3N5bWJvbCB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB9XG59XG5cbi5zZW5kLXNjcmVlbiB7XG4gICZfX3RpdGxlIHtcbiAgICBjb2xvcjogJHNjb3JwaW9uO1xuICAgIGZvbnQtc2l6ZTogMThweDtcbiAgICBsaW5lLWhlaWdodDogMjlweDtcbiAgfVxuXG4gICZfX3N1YnRpdGxlIHtcbiAgICBtYXJnaW46IDEwcHggMCAyMHB4O1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMjRweDtcbiAgfVxuXG4gICZfX3NlbmQtYnV0dG9uLFxuICAmX19jYW5jZWwtYnV0dG9uIHtcbiAgICB3aWR0aDogMTYzcHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICB9XG5cbiAgJl9fc2VuZC1idXR0b25fX2Rpc2FibGVkIHtcbiAgICBvcGFjaXR5OiAuNTtcbiAgICBjdXJzb3I6IGF1dG87XG4gIH1cbn1cblxuLnNlbmQtdG9rZW4ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG4gIHotaW5kZXg6IDI1O1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuXG4gICZfX2NvbnRlbnQge1xuICAgIHdpZHRoOiA0OThweDtcbiAgICBoZWlnaHQ6IDYwNXB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gICAgYm94LXNoYWRvdzogMCAycHggNHB4IDAgcmdiYSgwLCAwLCAwLCAuMDgpO1xuICAgIHBhZGRpbmc6IDQ2cHggNDAuNXB4IDI2cHg7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC8vIHRvcDogLTI2cHg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgICBmbGV4OiAxIDAgYXV0bztcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgICAgdG9wOiAwO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBib3gtc2hhZG93OiBub25lO1xuICAgICAgcGFkZGluZzogMTJweDtcbiAgICB9XG4gIH1cblxuICAuaWRlbnRpY29uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAtMzVweDtcbiAgICB6LWluZGV4OiAyNTtcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgdG9wOiAwO1xuICAgICAgZmxleDogMCAwIGF1dG87XG4gICAgfVxuICB9XG5cbiAgJl9fdGl0bGUge1xuICAgIGNvbG9yOiAkc2NvcnBpb247XG4gICAgZm9udC1zaXplOiAxOHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAyOXB4O1xuICB9XG5cbiAgJl9fZGVzY3JpcHRpb24sXG4gICZfX2JhbGFuY2UtdGV4dCxcbiAgJl9fdG9rZW4tc3ltYm9sIHtcbiAgICBtYXJnaW4tdG9wOiAxMHB4O1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMjRweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIH1cblxuICAmX190b2tlbi1iYWxhbmNlIHtcbiAgICBmb250LXNpemU6IDQwcHg7XG4gICAgbGluZS1oZWlnaHQ6IDQwcHg7XG4gICAgbWFyZ2luLXRvcDogMTNweDtcblxuICAgIC50b2tlbi1iYWxhbmNlX19hbW91bnQge1xuICAgICAgcGFkZGluZy1yaWdodDogMTJweDtcbiAgICB9XG4gIH1cblxuICAmX19idXR0b24tZ3JvdXAge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZmxleDogMCAwIGF1dG87XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIG1hcmdpbi10b3A6IDI0cHg7XG4gICAgfVxuXG4gICAgYnV0dG9uIHtcbiAgICAgIHdpZHRoOiAxNjNweDtcbiAgICB9XG4gIH1cbn1cblxuLmNvbmZpcm0tc2VuZC10b2tlbiB7XG4gICZfX2hlcm8tYW1vdW50LXdyYXBwZXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICB9XG59XG5cbi5zZW5kLXYyIHtcbiAgJl9fY29udGFpbmVyIHtcbiAgICAvLyBoZWlnaHQ6IDcwMXB4O1xuICAgIHdpZHRoOiAzODBweDtcbiAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDRweCAwIHJnYmEoMCwgMCwgMCwgLjA4KTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgICB6LWluZGV4OiAyNTtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIHRvcDogMDtcbiAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICBmbGV4OiAxIDEgYXV0bztcbiAgICB9XG4gIH1cblxuICAmX19zZW5kLWhlYWRlci1pY29uLWNvbnRhaW5lciB7XG4gICAgei1pbmRleDogMjU7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIHRvcDogMDtcbiAgICB9XG4gIH1cblxuICAmX19zZW5kLWhlYWRlci1pY29uIHtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgd2lkdGg6IDQ4cHg7XG4gICAgaGVpZ2h0OiA0OHB4O1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRhbHRvO1xuICAgIHotaW5kZXg6IDI1O1xuICAgIHBhZGRpbmc6IDRweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gIH1cblxuICAmX19zZW5kLWFycm93LWljb24ge1xuICAgIGNvbG9yOiAjZjI4OTMwO1xuICAgIHRyYW5zZm9ybTogcm90YXRlKC00NWRlZyk7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogLTJweDtcbiAgICBsZWZ0OiAwO1xuICAgIGZvbnQtc2l6ZTogMS4xMmVtO1xuICB9XG5cbiAgJl9fYXJyb3ctYmFja2dyb3VuZCB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICAgIGhlaWdodDogMTRweDtcbiAgICB3aWR0aDogMTRweDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiA1MnB4O1xuICAgIGxlZnQ6IDE5OXB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICB6LWluZGV4OiAxMDA7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIHRvcDogMzZweDtcbiAgICB9XG4gIH1cblxuICAmX19oZWFkZXIge1xuICAgIGhlaWdodDogODhweDtcbiAgICB3aWR0aDogMzgwcHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGF0aGVucy1ncmV5O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIGhlaWdodDogNTlweDtcbiAgICAgIHdpZHRoOiAxMDB2dztcbiAgICB9XG4gIH1cblxuICAmX19oZWFkZXItdGlwIHtcbiAgICBoZWlnaHQ6IDI1cHg7XG4gICAgd2lkdGg6IDI1cHg7XG4gICAgYmFja2dyb3VuZDogJGF0aGVucy1ncmV5O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSg0NWRlZyk7XG4gICAgbGVmdDogMTc4cHg7XG4gICAgdG9wOiA3NXB4O1xuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgICB0b3A6IDQ2cHg7XG4gICAgICBsZWZ0OiAwO1xuICAgICAgcmlnaHQ6IDA7XG4gICAgICBtYXJnaW46IDAgYXV0bztcbiAgICB9XG4gIH1cblxuICAmX190aXRsZSB7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgICBmb250LXNpemU6IDIycHg7XG4gICAgbGluZS1oZWlnaHQ6IDI5cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIG1hcmdpbi10b3A6IDI1cHg7XG4gIH1cblxuICAmX19jb3B5IHtcbiAgICBjb2xvcjogJGdyYXk7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgd2lkdGg6IDI4N3B4O1xuICB9XG5cbiAgJl9fZXJyb3Ige1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBsaW5lLWhlaWdodDogMTJweDtcbiAgICBsZWZ0OiA4cHg7XG4gICAgY29sb3I6ICRyZWQ7XG4gIH1cblxuICAmX19lcnJvci1ib3JkZXIge1xuICAgIGNvbG9yOiAkcmVkO1xuICB9XG5cbiAgJl9fZm9ybSB7XG4gICAgbWFyZ2luOiAxM3B4IDA7XG4gICAgd2lkdGg6IDEwMCU7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIHBhZGRpbmc6IDEzcHggMDtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIGhlaWdodDogMDtcbiAgICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgICBmbGV4OiAxIDEgYXV0bztcbiAgICB9XG4gIH1cblxuICAmX19mb3JtLWhlYWRlcixcbiAgJl9fZm9ybS1oZWFkZXItY29weSB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICB9XG5cbiAgJl9fZm9ybS1yb3cge1xuICAgIG1hcmdpbjogMTQuNXB4IDE4cHggMHB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogcm93O1xuICAgIGZsZXg6IDEgMCBhdXRvO1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgfVxuXG4gICZfX2Zvcm0tZmllbGQge1xuICAgIGZsZXg6IDEgMSBhdXRvO1xuICB9XG5cbiAgJl9fZm9ybS1sYWJlbCB7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBsaW5lLWhlaWdodDogMjJweDtcbiAgICB3aWR0aDogODhweDtcbiAgfVxuXG4gICZfX2Zyb20tZHJvcGRvd24ge1xuICAgIGhlaWdodDogNzNweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgbGluZS1oZWlnaHQ6IDE2cHg7XG4gICAgZm9udC1zaXplOiAxMnB4O1xuICAgIGNvbG9yOiAkdHVuZG9yYTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgICAmX19jbG9zZS1hcmVhIHtcbiAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgIHRvcDogMDtcbiAgICAgIGxlZnQ6IDA7XG4gICAgICB6LWluZGV4OiAxMDAwO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgfVxuICAgIFxuICAgICZfX2xpc3Qge1xuICAgICAgei1pbmRleDogMTA1MDtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGhlaWdodDogMjIwcHg7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICRnZXlzZXI7XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gICAgICBib3gtc2hhZG93OiAwIDNweCA2cHggMCByZ2JhKDAgLDAgLDAgLC4xMSk7XG4gICAgICBtYXJnaW4tdG9wOiAxMXB4O1xuICAgICAgbWFyZ2luLWxlZnQ6IC0xcHg7XG4gICAgICBvdmVyZmxvdy15OiBzY3JvbGw7XG4gICAgfVxuICB9XG5cbiAgJl9fdG8tYXV0b2NvbXBsZXRlIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgICAmX19kb3duLWNhcmV0IHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIHRvcDogMThweDtcbiAgICAgIHJpZ2h0OiAxMnB4O1xuICAgIH1cbiAgfVxuXG4gICZfX3RvLWF1dG9jb21wbGV0ZSwgJl9fbWVtby10ZXh0LWFyZWEge1xuICAgICZfX2lucHV0IHtcbiAgICAgIGhlaWdodDogNTRweDtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgJGFsdG87XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gICAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgICBwYWRkaW5nOiAxMHB4O1xuICAgICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAyMXB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICB9XG4gIH1cblxuICAmX19hbW91bnQtbWF4IHtcbiAgICBjb2xvcjogJGN1cmlvdXMtYmx1ZTtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBsZWZ0OiA4cHg7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgfVxuXG4gICZfX2dhcy1mZWUtZGlzcGxheSB7XG4gICAgd2lkdGg6IDEwMCU7XG4gIH1cblxuICAmX19zbGlkZXJzLWljb24tY29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgaGVpZ2h0OiAyNHB4O1xuICAgIHdpZHRoOiAyNHB4O1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRjdXJpb3VzLWJsdWU7XG4gICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgICBwYWRkaW5nOiA1cHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHJpZ2h0OiAxNXB4O1xuICAgIHRvcDogMTRweDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gIH1cblxuICAmX19zbGlkZXJzLWljb24ge1xuICAgIGNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICB9XG5cbiAgJl9fbWVtby10ZXh0LWFyZWEge1xuICAgICZfX2lucHV0IHtcbiAgICAgIHBhZGRpbmc6IDZweCAxMHB4O1xuICAgIH1cbiAgfVxuXG4gICZfX2Zvb3RlciB7XG4gICAgaGVpZ2h0OiA5MnB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1ldmVubHk7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBib3JkZXItdG9wOiAxcHggc29saWQgJGFsdG87XG4gICAgYmFja2dyb3VuZDogJHdoaXRlO1xuICAgIHBhZGRpbmc6IDAgMTJweDtcbiAgfVxuXG4gICZfX25leHQtYnRuLFxuICAmX19jYW5jZWwtYnRuLFxuICAmX19uZXh0LWJ0bl9fZGlzYWJsZWQge1xuICAgIHdpZHRoOiAxNjNweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgaGVpZ2h0OiA1NXB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsaW5lLWhlaWdodDogMjFweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZDtcbiAgICBtYXJnaW46IDAgNHB4O1xuICB9XG5cbiAgJl9fbmV4dC1idG4sXG4gICZfX25leHQtYnRuX19kaXNhYmxlZCB7XG4gICAgY29sb3I6ICRjdXJpb3VzLWJsdWU7XG4gICAgYm9yZGVyLWNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICB9XG5cbiAgJl9fbmV4dC1idG5fX2Rpc2FibGVkIHtcbiAgICBvcGFjaXR5OiAuNTtcbiAgICBjdXJzb3I6IGF1dG87XG4gIH1cblxuICAmX19jYW5jZWwtYnRuIHtcbiAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgYm9yZGVyLWNvbG9yOiAkZHVzdHktZ3JheTtcbiAgfVxuXG4gICZfX2N1c3RvbWl6ZS1nYXMge1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNEOEQ4RDg7XG4gICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNGRkZGRkY7XG4gICAgYm94LXNoYWRvdzogMCAycHggNHB4IDAgcmdiYSgwLDAsMCwwLjE0KTtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1mbG93OiBjb2x1bW47XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIHdpZHRoOiAxMDB2dztcbiAgICAgIGhlaWdodDogMTAwdmg7XG4gICAgfVxuXG4gICAgJl9faGVhZGVyIHtcbiAgICAgIGhlaWdodDogNTJweDtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkYWx0bztcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgZm9udC1zaXplOiAyMnB4O1xuXG4gICAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgICAgZmxleDogMCAwIGF1dG87XG4gICAgICB9XG4gICAgfVxuXG4gICAgJl9fdGl0bGUge1xuICAgICAgbWFyZ2luLWxlZnQ6IDE5LjI1cHg7XG4gICAgfVxuXG4gICAgJl9fY2xvc2U6OmFmdGVyIHtcbiAgICAgIGNvbnRlbnQ6ICdcXDAwRDcnO1xuICAgICAgZm9udC1zaXplOiAxLjhlbTtcbiAgICAgIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgICAgIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgbWFyZ2luLXJpZ2h0OiAxOS4yNXB4O1xuICAgIH1cblxuICAgICZfX2NvbnRlbnQge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgICAgIGhlaWdodDogMTAwJTtcbiAgICB9XG5cbiAgICAmX19ib2R5IHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBtYXJnaW4tYm90dG9tOiAyNHB4O1xuXG4gICAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgICAgZmxleC1mbG93OiBjb2x1bW47XG4gICAgICAgIGZsZXg6IDEgMSBhdXRvO1xuICAgICAgfVxuICAgIH1cblxuICAgICZfX2Zvb3RlciB7XG4gICAgICBoZWlnaHQ6IDc1cHg7XG4gICAgICBib3JkZXItdG9wOiAxcHggc29saWQgJGFsdG87XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIGZvbnQtc2l6ZTogMjJweDtcbiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgICAgIGZsZXg6IDAgMCBhdXRvO1xuICAgICAgfVxuICAgIH1cblxuICAgICZfX2J1dHRvbnMge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIHdpZHRoOiAxODEuNzVweDtcbiAgICAgIG1hcmdpbi1yaWdodDogMjEuMjVweDtcbiAgICB9XG5cbiAgICAmX19yZXZlcnQsICZfX2NhbmNlbCwgJl9fc2F2ZSwgJl9fc2F2ZV9fZXJyb3Ige1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB9XG5cbiAgICAmX19yZXZlcnQge1xuICAgICAgY29sb3I6ICRzaWx2ZXItY2hhbGljZTtcbiAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIG1hcmdpbi1sZWZ0OiAyMS4yNXB4O1xuICAgIH1cblxuICAgICZfX2NhbmNlbCwgJl9fc2F2ZSwgJl9fc2F2ZV9fZXJyb3Ige1xuICAgICAgaGVpZ2h0OiAzNC42NHB4O1xuICAgICAgd2lkdGg6IDg1Ljc0cHg7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAkZHVzdHktZ3JheTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgIGZvbnQtZmFtaWx5OiAnRElOIE9UJztcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgICB9XG5cbiAgICAmX19zYXZlX19lcnJvciB7XG4gICAgICBvcGFjaXR5OiAwLjU7XG4gICAgICBjdXJzb3I6IGF1dG87XG4gICAgfVxuXG4gICAgJl9fZXJyb3ItbWVzc2FnZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIHRvcDogNHB4O1xuICAgICAgcmlnaHQ6IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxMnB4O1xuICAgICAgY29sb3I6ICRyZWQ7XG4gICAgfVxuICB9XG5cbiAgJl9fZ2FzLW1vZGFsLWNhcmQge1xuICAgIHdpZHRoOiAzNjBweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogY29sdW1uO1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuICAgIHBhZGRpbmctbGVmdDogMjBweDtcblxuICAgICZfX3RpdGxlIHtcbiAgICAgIGhlaWdodDogMjZweDtcbiAgICAgIGNvbG9yOiAkdHVuZG9yYTtcbiAgICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgICBmb250LXNpemU6IDIwcHg7XG4gICAgICBmb250LXdlaWdodDogMzAwO1xuICAgICAgbGluZS1oZWlnaHQ6IDI2cHg7XG4gICAgICBtYXJnaW4tdG9wOiAxN3B4O1xuICAgIH1cblxuICAgICZfX2NvcHkge1xuICAgICAgaGVpZ2h0OiAzOHB4O1xuICAgICAgd2lkdGg6IDMxNHB4O1xuICAgICAgY29sb3I6ICR0dW5kb3JhO1xuICAgICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxOXB4O1xuICAgICAgbWFyZ2luLXRvcDogMTdweDtcbiAgICB9XG5cbiAgICAuY3VzdG9taXplLWdhcy1pbnB1dC13cmFwcGVyIHtcbiAgICAgIG1hcmdpbi10b3A6IDE3cHg7XG4gICAgfVxuXG4gICAgLmN1c3RvbWl6ZS1nYXMtaW5wdXQge1xuICAgICAgaGVpZ2h0OiA1NHB4O1xuICAgICAgd2lkdGg6IDMxNXB4O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgJGdleXNlcjtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgICAgIHBhZGRpbmctbGVmdDogMTVweDtcbiAgICB9XG5cbiAgICAuZ2FzLXRvb2x0aXAtaW5wdXQtYXJyb3dzIHtcbiAgICAgIHdpZHRoOiAzMnB4O1xuICAgICAgaGVpZ2h0OiA1NHB4O1xuICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjZGFkYWRhO1xuICAgICAgZm9udC1zaXplOiAxOHB4O1xuICAgICAgY29sb3I6ICR0dW5kb3JhO1xuICAgICAgcmlnaHQ6IDBweDtcbiAgICAgIHBhZGRpbmc6IDFweCA0cHg7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1hcm91bmQ7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIH1cblxuICAgIGlucHV0W3R5cGU9XCJudW1iZXJcIl06Oi13ZWJraXQtaW5uZXItc3Bpbi1idXR0b24ge1xuICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG5cbiAgICBpbnB1dFt0eXBlPVwibnVtYmVyXCJdOmhvdmVyOjotd2Via2l0LWlubmVyLXNwaW4tYnV0dG9uIHtcbiAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxuICB9XG59XG4iLCIuY29uZmlybS1zY3JlZW4tY29udGFpbmVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuICBmbGV4OiAwIDAgYXV0bztcbiAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICBib3gtc2hhZG93OiAwIDJweCA0cHggMCByZ2JhKCRibGFjaywgLjA4KTtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgd2lkdGg6IDEwMCU7XG4gIH1cblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA1NzZweCkge1xuICAgIC8vIHRvcDogLTI2cHg7XG4gIH1cbn1cblxuLm5vdGlmaWNhdGlvbiB7XG4gIC5jb25maXJtLXNjcmVlbi13cmFwcGVyIHtcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgICAgaGVpZ2h0OiBjYWxjKDEwMHZoIC0gODVweCk7XG4gICAgfVxuICB9XG59XG5cbi5jb25maXJtLXNjcmVlbi13cmFwcGVyIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICB3aWR0aDogMzgwcHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICB6LWluZGV4OiAyNTtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICBvdmVyZmxvdy14OiBoaWRkZW47XG4gIGJvcmRlci10b3AtbGVmdC1yYWRpdXM6IDhweDtcbiAgYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6IDhweDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47XG4gICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICB0b3A6IDA7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBoZWlnaHQ6IGNhbGMoMTAwdmggLSA1OHB4IC0gODVweCk7XG4gICAgYm9yZGVyLXRvcC1sZWZ0LXJhZGl1czogMDtcbiAgICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogMDtcbiAgfVxufVxuXG4uY29uZmlybS1zY3JlZW4td3JhcHBlciA+IC5jb25maXJtLXNjcmVlbi10b3RhbC1ib3gge1xuICBtYXJnaW4tbGVmdDogMTBweDtcbiAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xufVxuXG4uY29uZmlybS1zY3JlZW4td3JhcHBlciA+IC5jb25maXJtLW1lbW8td3JhcHBlciB7XG4gIG1hcmdpbjogMDtcbn1cblxuLmNvbmZpcm0tc2NyZWVuLWhlYWRlciB7XG4gIGhlaWdodDogODhweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGF0aGVucy1ncmV5O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmb250LXNpemU6IDIycHg7XG4gIGxpbmUtaGVpZ2h0OiAyOXB4O1xuICB3aWR0aDogMTAwJTtcbiAgcGFkZGluZzogMjVweCAwO1xuICBmbGV4OiAwIDAgYXV0bztcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICBmb250LXNpemU6IDIwcHg7XG4gIH1cbn1cblxuLmNvbmZpcm0tc2NyZWVuLWhlYWRlci10aXAge1xuICBoZWlnaHQ6IDI1cHg7XG4gIHdpZHRoOiAyNXB4O1xuICBiYWNrZ3JvdW5kOiAkYXRoZW5zLWdyZXk7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdHJhbnNmb3JtOiByb3RhdGUoNDVkZWcpO1xuICB0b3A6IDcxcHg7XG4gIGxlZnQ6IDA7XG4gIHJpZ2h0OiAwO1xuICBtYXJnaW46IDAgYXV0bztcbn1cblxuLmNvbmZpcm0tc2NyZWVuLXRpdGxlIHtcbiAgbGluZS1oZWlnaHQ6IDI3cHg7XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgbWFyZ2luLWxlZnQ6IDIycHg7XG4gICAgbWFyZ2luLXJpZ2h0OiA4cHg7XG4gIH1cbn1cblxuLmNvbmZpcm0tc2NyZWVuLWJhY2stYnV0dG9uIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIGJvcmRlcjogMXB4IHNvbGlkICRjdXJpb3VzLWJsdWU7XG4gIGxlZnQ6IDI0cHg7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBjb2xvcjogJGN1cmlvdXMtYmx1ZTtcbiAgcGFkZGluZzogNnB4IDEzcHggN3B4IDEycHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgaGVpZ2h0OiAzMHB4O1xuICB3aWR0aDogNTRweDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICBtYXJnaW4tcmlnaHQ6IDEycHg7XG4gIH1cbn1cblxuLmNvbmZpcm0tc2NyZWVuLWFjY291bnQtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5jb25maXJtLXNjcmVlbi1hY2NvdW50LW5hbWUge1xuICBtYXJnaW4tdG9wOiAxMnB4O1xuICBmb250LXNpemU6IDE0cHg7XG4gIGxpbmUtaGVpZ2h0OiAxOXB4O1xuICBjb2xvcjogJHNjb3JwaW9uO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG5cbi5jb25maXJtLXNjcmVlbi1yb3ctaW5mbyB7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDIxcHg7XG59XG5cbi5jb25maXJtLXNjcmVlbi1hY2NvdW50LW51bWJlciB7XG4gIGZvbnQtc2l6ZTogMTBweDtcbiAgbGluZS1oZWlnaHQ6IDE2cHg7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBoZWlnaHQ6IDE2cHg7XG59XG5cbi5jb25maXJtLXNlbmQtZXRoZXIsXG4uY29uZmlybS1zZW5kLXRva2VuIHtcbiAgaS5mYS1hcnJvdy1yaWdodCB7XG4gICAgYWxpZ24tc2VsZjogc3RhcnQ7XG4gICAgbWFyZ2luOiAyNHB4IDE0cHggMCAhaW1wb3J0YW50O1xuICB9XG59XG5cbi5jb25maXJtLXNjcmVlbi1pZGVudGljb25zIHtcbiAgbWFyZ2luLXRvcDogMjRweDtcbiAgZmxleDogMCAwIGF1dG87XG5cbiAgaS5mYS1hcnJvdy1yaWdodCB7XG4gICAgYWxpZ24tc2VsZjogc3RhcnQ7XG4gICAgbWFyZ2luOiA0MnB4IDE0cHggMDtcbiAgfVxuXG4gIGkuZmEtZmlsZS10ZXh0LW8ge1xuICAgIGZvbnQtc2l6ZTogNjBweDtcbiAgICBtYXJnaW46IDE2cHggOHB4IDAgOHB4O1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgfVxufVxuXG4uY29uZmlybS1zY3JlZW4tc2VuZGluZy10by1tZXNzYWdlIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LXNpemU6IDE2cHg7XG4gIG1hcmdpbi10b3A6IDMwcHg7XG4gIGZvbnQtZmFtaWx5OiAnRElOIE5FWFQgTGlnaHQnO1xufVxuXG4uY29uZmlybS1zY3JlZW4tc2VuZC1hbW91bnQge1xuICBjb2xvcjogJHNjb3JwaW9uO1xuICBtYXJnaW4tdG9wOiAxMnB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogNDBweDtcbiAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgbGluZS1oZWlnaHQ6IDUzcHg7XG4gIGZsZXg6IDAgMCBhdXRvO1xufVxuXG4uY29uZmlybS1zY3JlZW4tc2VuZC1hbW91bnQtY3VycmVuY3kge1xuICBmb250LXNpemU6IDIwcHg7XG4gIGxpbmUtaGVpZ2h0OiAyMHB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZsZXg6IDAgMCBhdXRvO1xufVxuXG4uY29uZmlybS1tZW1vLXdyYXBwZXIge1xuICBtaW4taGVpZ2h0OiAyNHB4O1xuICB3aWR0aDogMTAwJTtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICRhbHRvO1xuICBmbGV4OiAwIDAgYXV0bztcbn1cblxuLmNvbmZpcm0tc2NyZWVuLXNlbmQtbWVtbyB7XG4gIGNvbG9yOiAkc2NvcnBpb247XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG59XG5cbi5jb25maXJtLXNjcmVlbi1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMThweDtcbiAgbGluZS1oZWlnaHQ6IDQwcHg7XG4gIGNvbG9yOiAkc2NvcnBpb247XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbnNlY3Rpb24gLmNvbmZpcm0tc2NyZWVuLWFjY291bnQtbmFtZSxcbnNlY3Rpb24gLmNvbmZpcm0tc2NyZWVuLWFjY291bnQtbnVtYmVyLFxuLmNvbmZpcm0tc2NyZWVuLXJvdy1pbmZvLFxuLmNvbmZpcm0tc2NyZWVuLXJvdy1kZXRhaWwge1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xufVxuXG4uY29uZmlybS1zY3JlZW4tcm93cyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgd2lkdGg6IDEwMCU7XG4gIGZsZXg6IDAgMCBhdXRvO1xufVxuXG4uY29uZmlybS1zY3JlZW4tc2VjdGlvbi1jb2x1bW4ge1xuICBmbGV4OiAuNTtcbn1cblxuLmNvbmZpcm0tc2NyZWVuLXJvdyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICRhbHRvO1xuICB3aWR0aDogMTAwJTtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgcGFkZGluZzogMTJweDtcbiAgcGFkZGluZy1sZWZ0OiAzNXB4O1xuICBmb250LXNpemU6IDE2cHg7XG4gIGxpbmUtaGVpZ2h0OiAyMnB4O1xuICBmb250LXdlaWdodDogMzAwO1xufVxuXG4uY29uZmlybS1zY3JlZW4tcm93LWRldGFpbCB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbGluZS1oZWlnaHQ6IDE2cHg7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbn1cblxuLmNvbmZpcm0tc2NyZWVuLXRvdGFsLWJveCB7XG4gIGJhY2tncm91bmQtY29sb3I6ICR3aWxkLXNhbmQ7XG4gIHBhZGRpbmc6IDIwcHg7XG4gIHBhZGRpbmctbGVmdDogMzVweDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICRhbHRvO1xuXG4gIC5jb25maXJtLXNjcmVlbi1sYWJlbCB7XG4gICAgbGluZS1oZWlnaHQ6IDE4cHg7XG4gIH1cblxuICAuY29uZmlybS1zY3JlZW4tcm93LWRldGFpbCB7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgfVxuXG4gICZfX3N1YnRpdGxlIHtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbGluZS1oZWlnaHQ6IDIycHg7XG4gIH1cblxuICAuY29uZmlybS1zY3JlZW4tcm93LWluZm8ge1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIGxpbmUtaGVpZ2h0OiAyMXB4O1xuICB9XG59XG5cbi5jb25maXJtLXNjcmVlbi1jb25maXJtLWJ1dHRvbiB7XG4gIGhlaWdodDogNjJweDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDJjOWIxO1xuICBmb250LXNpemU6IDE2cHg7XG4gIGNvbG9yOiAkd2hpdGU7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgcGFkZGluZy10b3A6IDE1cHg7XG4gIHBhZGRpbmctYm90dG9tOiAxNXB4O1xuICBib3JkZXItd2lkdGg6IDA7XG4gIGJveC1zaGFkb3c6IG5vbmU7XG4gIGZsZXg6IDEgMCBhdXRvO1xuICBmb250LXdlaWdodDogMzAwO1xuICBtYXJnaW46IDAgOHB4O1xufVxuXG4uYnRuLWxpZ2h0LmNvbmZpcm0tc2NyZWVuLWNhbmNlbC1idXR0b24ge1xuICBoZWlnaHQ6IDYycHg7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGJvcmRlcjogbm9uZTtcbiAgb3BhY2l0eTogMTtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgYm9yZGVyLXdpZHRoOiAwO1xuICBwYWRkaW5nLXRvcDogMTVweDtcbiAgcGFkZGluZy1ib3R0b206IDE1cHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgbGluZS1oZWlnaHQ6IDMycHg7XG4gIGJveC1zaGFkb3c6IG5vbmU7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgZmxleDogMSAwIGF1dG87XG4gIGZvbnQtd2VpZ2h0OiAzMDA7XG4gIG1hcmdpbjogMCA4cHg7XG59XG5cbiNwZW5kaW5nLXR4LWZvcm0ge1xuICBmbGV4OiAxIDAgYXV0bztcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWZsb3c6IHJvdyBub3dyYXA7XG4gIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgcGFkZGluZzogMTJweCAxOHB4O1xuICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiA4cHg7XG4gIGJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOiA4cHg7XG4gIHdpZHRoOiAxMDAlO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCAkYWx0bztcbiAgICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiAwO1xuICAgIGJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOiAwO1xuICB9XG59XG4iLCIubG9hZGluZy1vdmVybGF5IHtcbiAgbGVmdDogMHB4O1xuICB6LWluZGV4OiA1MDtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgd2lkdGg6IDEwMCU7XG4gIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC44KTtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1NzVweCkge1xuICAgIG1hcmdpbi10b3A6IDU2cHg7XG4gICAgaGVpZ2h0OiBjYWxjKDEwMCUgLSA1NnB4KTtcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDU3NnB4KSB7XG4gICAgbWFyZ2luLXRvcDogNzVweDtcbiAgICBoZWlnaHQ6IGNhbGMoMTAwJSAtIDc1cHgpO1xuICB9XG59XG4iLCIuaGVyby1iYWxhbmNlIHtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgbWFyZ2luOiAuM2VtIC45ZW0gMDtcbiAgICAvLyBoZWlnaHQ6IDgwdmg7XG4gICAgLy8gbWF4LWhlaWdodDogMjI1cHg7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWstbGFyZ2UpIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgbWFyZ2luOiAyLjhlbSAyLjM3ZW0gLjhlbTtcbiAgfVxuXG4gIC5iYWxhbmNlLWNvbnRhaW5lciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBtYXJnaW46IDA7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBmbGV4OiAwIDAgYXV0bztcbiAgICB9XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWstbGFyZ2UpIHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICBmbGV4LWdyb3c6IDM7XG4gICAgfVxuICB9XG5cbiAgLmJhbGFuY2UtZGlzcGxheSB7XG5cbiAgICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcblxuICAgICAgLnRva2VuLWFtb3VudCB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTc1JTtcbiAgICAgICAgbWFyZ2luLXRvcDogMTIuNSU7XG4gICAgICB9XG5cbiAgICAgIC5maWF0LWFtb3VudCB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTE1JTtcbiAgICAgICAgbWFyZ2luLXRvcDogOC41JTtcbiAgICAgICAgY29sb3I6ICNhMGEwYTA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJGJyZWFrLWxhcmdlKSB7XG4gICAgICBtYXJnaW4tbGVmdDogMyU7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gICAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcblxuICAgICAgLnRva2VuLWFtb3VudCB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTM1JTtcbiAgICAgIH1cblxuICAgICAgLmZpYXQtYW1vdW50IHtcbiAgICAgICAgbWFyZ2luLXRvcDogLjI1JTtcbiAgICAgICAgZm9udC1zaXplOiAxMDUlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC5iYWxhbmNlLWljb24ge1xuICAgIGJvcmRlci1yYWRpdXM6IDI1cHg7XG4gICAgd2lkdGg6IDQ1cHg7XG4gICAgaGVpZ2h0OiA0NXB4O1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRhbHRvO1xuICB9XG5cbiAgLmhlcm8tYmFsYW5jZS1idXR0b25zIHtcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAvLyBoZWlnaHQ6IDEwMHB4OyAvLyBuZWVkZWQgYSByb3VuZCBudW1iZXIgdG8gc2V0IHRoZSBoZWlnaHRzIG9mIHRoZSBidXR0b25zIGluc2lkZVxuICAgICAgZmxleDogMCAwIGF1dG87XG4gICAgICBwYWRkaW5nOiAxNnB4IDA7XG4gICAgfVxuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJGJyZWFrLWxhcmdlKSB7XG4gICAgICBmbGV4LWdyb3c6IDI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICAgIH1cblxuICAgIGJ1dHRvbi5idG4tY2xlYXIge1xuICAgICAgYmFja2dyb3VuZDogJHdoaXRlO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQ7XG4gICAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgICBmb250LXNpemU6IDEycHg7XG5cbiAgICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgICAgICBib3JkZXItY29sb3I6ICRjdXJpb3VzLWJsdWU7XG4gICAgICAgIGNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICAgICAgICBoZWlnaHQ6IDM2cHg7XG4gICAgICB9XG5cbiAgICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6ICRicmVhay1sYXJnZSkge1xuICAgICAgICBib3JkZXItY29sb3I6ICRjdXJpb3VzLWJsdWU7XG4gICAgICAgIGNvbG9yOiAkY3VyaW91cy1ibHVlO1xuICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICB3aWR0aDogODVweDtcbiAgICAgICAgaGVpZ2h0OiAzNHB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiJHdhbGxldC1iYWxhbmNlLWJnOiAjZTdlN2U3O1xuJHdhbGxldC1iYWxhbmNlLWJyZWFrcG9pbnQ6IDg5MHB4O1xuJHdhbGxldC1iYWxhbmNlLWJyZWFrcG9pbnQtcmFuZ2U6IFwic2NyZWVuIGFuZCAobWluLXdpZHRoOiAjeyRicmVhay1sYXJnZX0pIGFuZCAobWF4LXdpZHRoOiAjeyR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50fSlcIjtcblxuLndhbGxldC1iYWxhbmNlLXdyYXBwZXIge1xuICBmbGV4OiAwIDAgYXV0bztcbiAgdHJhbnNpdGlvbjogbGluZWFyIDIwMG1zO1xuICBiYWNrZ3JvdW5kOiByZ2JhKCR3YWxsZXQtYmFsYW5jZS1iZywgMCk7XG5cbiAgJi0tYWN0aXZlIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKCR3YWxsZXQtYmFsYW5jZS1iZywgMSk7XG4gIH1cbn1cblxuLndhbGxldC1iYWxhbmNlIHtcbiAgYmFja2dyb3VuZDogaW5oZXJpdDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBmbGV4OiAwIDAgYXV0bztcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBib3JkZXItdG9wOiAxcHggc29saWQgJHdhbGxldC1iYWxhbmNlLWJnO1xuXG4gIC5iYWxhbmNlLWNvbnRhaW5lciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBtYXJnaW46IDIwcHggMjRweDtcbiAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICAgIGZsZXgtZ3JvdzogMztcblxuICAgIEBtZWRpYSAjeyR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50LXJhbmdlfSB7XG4gICAgICBtYXJnaW46IDEwJSA0JTtcbiAgICB9XG4gIH1cblxuICAuYmFsYW5jZS1kaXNwbGF5IHtcbiAgICBtYXJnaW4tbGVmdDogMTVweDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtc3RhcnQ7XG5cbiAgICAudG9rZW4tYW1vdW50IHtcbiAgICAgIGZvbnQtc2l6ZTogMTM1JTtcbiAgICB9XG5cbiAgICAuZmlhdC1hbW91bnQge1xuICAgICAgbWFyZ2luLXRvcDogLjI1JTtcbiAgICAgIGZvbnQtc2l6ZTogMTA1JTtcbiAgICB9XG5cbiAgICBAbWVkaWEgI3skd2FsbGV0LWJhbGFuY2UtYnJlYWtwb2ludC1yYW5nZX0ge1xuICAgICAgbWFyZ2luLWxlZnQ6IDQlO1xuXG4gICAgICAudG9rZW4tYW1vdW50IHtcbiAgICAgICAgZm9udC1zaXplOiAxMDUlO1xuICAgICAgfVxuXG4gICAgICAuZmlhdC1hbW91bnQge1xuICAgICAgICBmb250LXNpemU6IDk1JTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAuYmFsYW5jZS1pY29uIHtcbiAgICBib3JkZXItcmFkaXVzOiAyNXB4O1xuICAgIHdpZHRoOiA0NXB4O1xuICAgIGhlaWdodDogNDVweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgfVxufVxuIiwiLnR4LWxpc3QtY29udGFpbmVyIHtcbiAgaGVpZ2h0OiA4Ny41JTtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWstbGFyZ2UpIHtcbiAgICBvdmVyZmxvdy15OiBzY3JvbGw7XG4gIH1cbn1cblxuLnR4LWxpc3QtaGVhZGVyIHtcbiAgdGV4dC10cmFuc2Zvcm06IGNhcGl0YWxpemU7XG59XG5cbkBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAudHgtbGlzdC1oZWFkZXItd3JhcHBlciB7XG4gICAgbWFyZ2luLXRvcDogLjJlbTtcbiAgICBtYXJnaW4tYm90dG9tOiAuNmVtO1xuICAgIC8vIFRPRE86IFJlc29sdmUgTGF5b3V0IENvbmZsaWNzdCBpbiBXYWxsZXQgVmlld1xuICAgIC8vICAtIFRoaXMgZml4ZXMgdHhsaXN0IFwidHJhbnNhY3Rpb25zXCIgdGl0bGUgZGlzcGF5XG4gICAgLy8gbWFyZ2luLXRvcDogMC4yZW07XG4gICAgLy8gbWFyZ2luLWJvdHRvbTogMC42ZW07XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICAudHgtbGlzdC1oZWFkZXIge1xuICAgIGFsaWduLXNlbGY6IGNlbnRlcjtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgfVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWstbGFyZ2UpIHtcbiAgLnR4LWxpc3QtaGVhZGVyLXdyYXBwZXIge1xuICAgIGZsZXg6IDAgMCA1NXB4O1xuICB9XG5cbiAgLnR4LWxpc3QtaGVhZGVyIHtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbWFyZ2luOiAxLjVlbSAyLjM3ZW07XG4gIH1cblxuICAudHgtbGlzdC1jb250YWluZXI6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG59XG5cbi50eC1saXN0LWNvbnRlbnQtZGl2aWRlciB7XG4gIGhlaWdodDogMXB4O1xuICBiYWNrZ3JvdW5kOiByZ2IoMjMxLCAyMzEsIDIzMSk7XG4gIGZsZXg6IDAgMCAxcHg7XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgbWFyZ2luOiAuMWVtIDA7XG4gIH1cblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWstbGFyZ2UpIHtcbiAgICBtYXJnaW46IC4xZW0gMi4zN2VtO1xuICB9XG59XG5cbi50eC1saXN0LWl0ZW0td3JhcHBlciB7XG4gIGZsZXg6IDEgMSBhdXRvO1xuICB3aWR0aDogMDtcbiAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIHBhZGRpbmc6IDAgMS4zZW0gLjhlbTtcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6ICRicmVhay1sYXJnZSkge1xuICAgIHBhZGRpbmctYm90dG9tOiAxMnB4O1xuICB9XG59XG5cbi50eC1saXN0LWNsaWNrYWJsZSB7XG4gIGN1cnNvcjogcG9pbnRlcjtcblxuICAmOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKCRhbHRvLCAuMik7XG4gIH1cbn1cblxuLnR4LWxpc3QtcGVuZGluZy1pdGVtLWNvbnRhaW5lciB7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgb3BhY2l0eTogLjU7XG59XG5cbi50eC1saXN0LWRhdGUtd3JhcHBlciB7XG4gIGZsZXg6IDEgMSBhdXRvO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIG1hcmdpbi10b3A6IDZweDtcbiAgfVxuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6ICRicmVhay1sYXJnZSkge1xuICAgIG1hcmdpbi10b3A6IDEycHg7XG4gIH1cbn1cblxuLnR4LWxpc3QtY29udGVudC13cmFwcGVyIHtcbiAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gIG1hcmdpbi1ib3R0b206IDRweDtcbiAgbWFyZ2luLXRvcDogMnB4O1xuICBmbGV4OiAxIDAgYXV0bztcbiAgd2lkdGg6IDEwMCU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICBmb250LXNpemU6IDEycHg7XG5cbiAgICAudHgtbGlzdC1zdGF0dXMge1xuICAgICAgZm9udC1zaXplOiAxNHB4ICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLnR4LWxpc3QtYWNjb3VudCB7XG4gICAgICBmb250LXNpemU6IDE0cHggIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAudHgtbGlzdC12YWx1ZSB7XG4gICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICBsaW5lLWhlaWdodDogMThweDtcbiAgICB9XG5cbiAgICAudHgtbGlzdC1maWF0LXZhbHVlIHtcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxNnB4O1xuICAgIH1cbiAgfVxufVxuXG4udHgtbGlzdC1kYXRlIHtcbiAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICBmb250LXNpemU6IDEycHg7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG59XG5cbi50eC1saXN0LWlkZW50aWNvbi13cmFwcGVyIHtcbiAgYWxpZ24tc2VsZjogY2VudGVyO1xuICBmbGV4OiAwIDAgYXV0bztcbiAgbWFyZ2luLXJpZ2h0OiAxNnB4O1xufVxuXG4udHgtbGlzdC1hY2NvdW50LWFuZC1zdGF0dXMtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXg6IDEgMSBhdXRvO1xuICBmbGV4LWZsb3c6IHJvdyB3cmFwO1xuICB3aWR0aDogMDtcblxuICBAbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkYnJlYWstc21hbGwpIHtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbiAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcbiAgICBhbGlnbi1zZWxmOiBjZW50ZXI7XG5cbiAgICAudHgtbGlzdC1hY2NvdW50LXdyYXBwZXIge1xuICAgICAgaGVpZ2h0OiAxOHB4O1xuXG4gICAgICAudHgtbGlzdC1hY2NvdW50IHtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDE0cHg7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJGJyZWFrLWxhcmdlKSB7XG4gICAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcblxuICAgIC50eC1saXN0LWFjY291bnQtd3JhcHBlciB7XG4gICAgICBmbGV4OiAxLjMgMiBhdXRvO1xuICAgICAgbWluLXdpZHRoOiAxNTNweDtcbiAgICB9XG5cbiAgICAudHgtbGlzdC1zdGF0dXMtd3JhcHBlciB7XG4gICAgICBmbGV4OiA2IDYgYXV0bztcbiAgICB9XG4gIH1cblxuICAudHgtbGlzdC1hY2NvdW50IHtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgfVxuXG4gIC50eC1saXN0LXN0YXR1cyB7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICB0ZXh0LXRyYW5zZm9ybTogY2FwaXRhbGl6ZTtcbiAgfVxuXG4gIC50eC1saXN0LXN0YXR1cy0tcmVqZWN0ZWQsXG4gIC50eC1saXN0LXN0YXR1cy0tZmFpbGVkIHtcbiAgICBjb2xvcjogJG1vbnpvO1xuICB9XG59XG5cbi50eC1saXN0LWl0ZW0ge1xuICBib3JkZXItdG9wOiAxcHggc29saWQgcmdiKDIzMSwgMjMxLCAyMzEpO1xuICBmbGV4OiAwIDAgYXV0bztcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1mbG93OiByb3cgbm93cmFwO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6ICRicmVhay1zbWFsbCkge1xuICAgIC8vIG1hcmdpbjogMCAxLjNlbSAuOTVlbTsgIWltcG9ydGFudFxuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJGJyZWFrLWxhcmdlKSB7XG4gICAgbWFyZ2luOiAwIDIuMzdlbTtcbiAgfVxuXG4gICY6bGFzdC1vZi10eXBlIHtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgcmdiKDIzMSwgMjMxLCAyMzEpO1xuICAgIG1hcmdpbi1ib3R0b206IDMycHg7XG4gIH1cblxuICAmX193cmFwcGVyIHtcbiAgICBhbGlnbi1zZWxmOiBjZW50ZXI7XG4gICAgZmxleDogMiAyIGF1dG87XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuXG4gICAgLnR4LWxpc3QtdmFsdWUge1xuICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgfVxuXG4gICAgLnR4LWxpc3QtdmFsdWUtLWNvbmZpcm1lZCB7XG4gICAgICBjb2xvcjogJGNhcmliYmVhbi1ncmVlbjtcbiAgICB9XG5cbiAgICAudHgtbGlzdC1maWF0LXZhbHVlIHtcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIHRleHQtYWxpZ246IHJpZ2h0O1xuICAgIH1cbiAgfVxuXG4gICYtLWVtcHR5IHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgYm9yZGVyLWJvdHRvbTogbm9uZSAhaW1wb3J0YW50O1xuICAgIHBhZGRpbmc6IDE2cHg7XG4gIH1cbn1cblxuLnR4LWxpc3QtZGV0YWlscy13cmFwcGVyIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgZmxleDogMCAwIDM1JTtcbn1cblxuLnR4LWxpc3QtdmFsdWUge1xuICBmb250LXNpemU6IDE2cHg7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnR4LWxpc3QtZmlhdC12YWx1ZSB7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnR4LWxpc3QtdmFsdWUtLWNvbmZpcm1lZCB7XG4gIGNvbG9yOiAkY2FyaWJiZWFuLWdyZWVuO1xufVxuIiwiLy8gT2xkIHNjc3MsIGRvIG5vdCBsaW50IC0gY2xlYW4gdXAgbGF0ZXJcbi8qIHN0eWxlbGludC1kaXNhYmxlICovXG5cblxuLypcbkFwcCBTZWN0aW9uc1xuICBUT0RPOiBNb3ZlIGludG8gc2VwYXJhdGUgZmlsZXMuXG4qL1xuXG4vKiBpbml0aWFsaXplICovXG50ZXh0YXJlYS50d2VsdmUtd29yZC1waHJhc2Uge1xuICBwYWRkaW5nOiAxMnB4O1xuICB3aWR0aDogMzAwcHg7XG4gIGhlaWdodDogMTQwcHg7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgYmFja2dyb3VuZDogJHdoaXRlO1xuICByZXNpemU6IG5vbmU7XG59XG5cbi5pbml0aWFsaXplLXNjcmVlbiBociB7XG4gIHdpZHRoOiA2MHB4O1xuICBtYXJnaW46IDEycHg7XG4gIGJvcmRlci1jb2xvcjogI2Y3ODYxYztcbiAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcbn1cblxuLmluaXRpYWxpemUtc2NyZWVuIGxhYmVsIHtcbiAgbWFyZ2luLXRvcDogMjBweDtcbn1cblxuLmluaXRpYWxpemUtc2NyZWVuIGJ1dHRvbi5jcmVhdGUtdmF1bHQge1xuICBtYXJnaW4tdG9wOiA0MHB4O1xufVxuXG4uaW5pdGlhbGl6ZS1zY3JlZW4gLndhcm5pbmcge1xuICBmb250LXNpemU6IDE0cHg7XG4gIG1hcmdpbjogMCAxNnB4O1xufVxuXG4vKiB1bmxvY2sgKi9cbi5lcnJvciB7XG4gIC8vIGNvbG9yOiAjZTIwMjAyO1xuICBjb2xvcjogI2Y3ODYxYztcbiAgbWFyZ2luLWJvdHRvbTogOXB4O1xufVxuXG4ud2FybmluZyB7XG4gIGNvbG9yOiAjZmZhZTAwO1xufVxuXG4ubG9jayB7XG4gIHdpZHRoOiA1MHB4O1xuICBoZWlnaHQ6IDUwcHg7XG59XG5cbi5sb2NrLmxvY2tlZCB7XG4gIHRyYW5zZm9ybTogc2NhbGUoMS41KTtcbiAgb3BhY2l0eTogMDtcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSA0MDBtcyBlYXNlLWluLCB0cmFuc2Zvcm0gNDAwbXMgZWFzZS1pbjtcbn1cblxuLmxvY2sudW5sb2NrZWQge1xuICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xuICBvcGFjaXR5OiAxO1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IDUwMG1zIGVhc2Utb3V0LCB0cmFuc2Zvcm0gNTAwbXMgZWFzZS1vdXQsIGJhY2tncm91bmQgMjAwbXMgZWFzZS1pbjtcbn1cblxuLmxvY2subG9ja2VkIC5sb2NrLXRvcCB7XG4gIHRyYW5zZm9ybTogc2NhbGVYKDEpIHRyYW5zbGF0ZVgoMCk7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAyNTBtcyBlYXNlLWluO1xufVxuXG4ubG9jay51bmxvY2tlZCAubG9jay10b3Age1xuICB0cmFuc2Zvcm06IHNjYWxlWCgtMSkgdHJhbnNsYXRlWCgtMTJweCk7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAyNTBtcyBlYXNlLWluO1xufVxuXG4ubG9jay51bmxvY2tlZDpob3ZlciB7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgYmFja2dyb3VuZDogI2U1ZTVlNTtcbiAgYm9yZGVyOiAxcHggc29saWQgI2IxYjFiMTtcbn1cblxuLmxvY2sudW5sb2NrZWQ6YWN0aXZlIHtcbiAgYmFja2dyb3VuZDogI2MzYzNjMztcbn1cblxuLnNlY3Rpb24tdGl0bGUgLmZhLWFycm93LWxlZnQge1xuICBtYXJnaW46IC0ycHggOHB4IDBweCAtOHB4O1xufVxuXG4udW5sb2NrLXNjcmVlbiAjbWV0YW1hc2stbWFzY290LWNvbnRhaW5lciB7XG4gIG1hcmdpbi10b3A6IDI0cHg7XG59XG5cbi51bmxvY2stc2NyZWVuIGgxIHtcbiAgbWFyZ2luLXRvcDogLTI4cHg7XG4gIG1hcmdpbi1ib3R0b206IDQycHg7XG59XG5cbi51bmxvY2stc2NyZWVuIGlucHV0W3R5cGU9cGFzc3dvcmRdIHtcbiAgd2lkdGg6IDI2MHB4O1xufVxuXG4uc2l6aW5nLWlucHV0IHtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBoZWlnaHQ6IDMwcHg7XG4gIHBhZGRpbmctbGVmdDogNXB4O1xufVxuXG4uZWRpdGFibGUtbGFiZWwge1xuICBkaXNwbGF5OiBmbGV4O1xufVxuXG4vKiBXZWJraXQgKi9cblxuLnVubG9jay1zY3JlZW4gaW5wdXQ6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXIge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMS4yZW07XG59XG5cbi8qIEZpcmVmb3ggMTgtICovXG5cbi51bmxvY2stc2NyZWVuIGlucHV0Oi1tb3otcGxhY2Vob2xkZXIge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMS4yZW07XG59XG5cbi8qIEZpcmVmb3ggMTkrICovXG5cbi51bmxvY2stc2NyZWVuIGlucHV0OjotbW96LXBsYWNlaG9sZGVyIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LXNpemU6IDEuMmVtO1xufVxuXG4vKiBJRSAqL1xuXG4udW5sb2NrLXNjcmVlbiBpbnB1dDotbXMtaW5wdXQtcGxhY2Vob2xkZXIge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMS4yZW07XG59XG5cbi8qIGFjY291bnRzICovXG5cbi5hY2NvdW50cy1zZWN0aW9uIHtcbiAgbWFyZ2luOiAwIDBweDtcbn1cblxuLmFjY291bnRzLXNlY3Rpb24gLmhvcml6b250YWwtbGluZSB7XG4gIG1hcmdpbjogMCAxOHB4O1xufVxuXG4uYWNjb3VudHMtbGlzdC1vcHRpb24ge1xuICBoZWlnaHQ6IDEyMHB4O1xufVxuXG4uYWNjb3VudHMtbGlzdC1vcHRpb24gLmlkZW50aWNvbi13cmFwcGVyIHtcbiAgd2lkdGg6IDEwMHB4O1xufVxuXG4udW5jb25mdHgtbGluayB7XG4gIG1hcmdpbi10b3A6IDI0cHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLnVuY29uZnR4LWxpbmsgLmZhLWFycm93LXJpZ2h0IHtcbiAgbWFyZ2luOiAwIC04cHggMHB4IDhweDtcbn1cblxuLyogaWRlbnRpdHkgcGFuZWwgKi9cblxuLmlkZW50aXR5LXBhbmVsIHtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbn1cblxuLmlkZW50aXR5LXBhbmVsIC5pZGVudGljb24td3JhcHBlciB7XG4gIG1hcmdpbjogNHB4O1xuICBtYXJnaW4tdG9wOiA4cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5pZGVudGl0eS1wYW5lbCAuaWRlbnRpY29uLXdyYXBwZXIgc3BhbiB7XG4gIG1hcmdpbjogMCBhdXRvO1xufVxuXG4uaWRlbnRpdHktcGFuZWwgLmlkZW50aXR5LWRhdGEge1xuICBtYXJnaW46IDhweCA4cHggOHB4IDE4cHg7XG59XG5cbi5pZGVudGl0eS1wYW5lbCBpIHtcbiAgbWFyZ2luLXRvcDogMzJweDtcbiAgbWFyZ2luLXJpZ2h0OiA2cHg7XG4gIGNvbG9yOiAjYjliOWI5O1xufVxuXG4uaWRlbnRpdHktcGFuZWwgLmFycm93LXJpZ2h0IHtcbiAgcGFkZGluZy1sZWZ0OiAxOHB4O1xuICB3aWR0aDogNDJweDtcbiAgbWluLXdpZHRoOiAxOHB4O1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5pZGVudGl0eS1jb3B5LmZsZXgtY29sdW1uIHtcbiAgZmxleDogLjI1IDAgYXV0bztcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG59XG5cbi8qIGFjY291bnRzIHNjcmVlbiAqL1xuXG4uaWRlbnRpdHktc2VjdGlvbiB7XG59XG5cbi5pZGVudGl0eS1zZWN0aW9uIC5pZGVudGl0eS1wYW5lbCB7XG4gIGJhY2tncm91bmQ6ICNlOWU5ZTk7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjYjFiMWIxO1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5pZGVudGl0eS1zZWN0aW9uIC5pZGVudGl0eS1wYW5lbC5zZWxlY3RlZCB7XG4gIGJhY2tncm91bmQ6ICR3aGl0ZTtcbiAgY29sb3I6ICNmM2M4M2U7XG59XG5cbi5pZGVudGl0eS1zZWN0aW9uIC5pZGVudGl0eS1wYW5lbC5zZWxlY3RlZCAuaWRlbnRpY29uIHtcbiAgYm9yZGVyLWNvbG9yOiAkb3JhbmdlO1xufVxuXG4uaWRlbnRpdHktc2VjdGlvbiAuYWNjb3VudHMtbGlzdC1vcHRpb246aG92ZXIsXG4uaWRlbnRpdHktc2VjdGlvbiAuYWNjb3VudHMtbGlzdC1vcHRpb24uc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAkd2hpdGU7XG59XG5cbi8qIGFjY291bnQgZGV0YWlsIHNjcmVlbiAqL1xuXG4uYWNjb3VudC1kZXRhaWwtc2VjdGlvbiB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtd3JhcDogd3JhcDtcbiAgb3ZlcmZsb3cteTogYXV0bztcbiAgZmxleC1kaXJlY3Rpb246IGluaGVyaXQ7XG59XG5cbi5ncm93LXRlbngge1xuICBmbGV4LWdyb3c6IDEwO1xufVxuXG4ubmFtZS1sYWJlbCB7XG59XG5cbi51bmFwcHJvdmVkLXR4LWljb24ge1xuICBoZWlnaHQ6IDE2cHg7XG4gIHdpZHRoOiAxNnB4O1xuICBiYWNrZ3JvdW5kOiByZ2IoNDcsIDE3NCwgMjQ0KTtcbiAgYm9yZGVyLWNvbG9yOiAkc2lsdmVyLWNoYWxpY2U7XG4gIGJvcmRlci1yYWRpdXM6IDEzcHg7XG59XG5cbi5lZGl0LXRleHQge1xuICBoZWlnaHQ6IDEwMCU7XG4gIHZpc2liaWxpdHk6IGhpZGRlbjtcbn1cblxuLmVkaXRpbmctbGFiZWwge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gIG1hcmdpbi1sZWZ0OiA1MHB4O1xuICBtYXJnaW4tYm90dG9tOiAycHg7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgdGV4dC1yZW5kZXJpbmc6IGdlb21ldHJpY1ByZWNpc2lvbjtcbiAgY29sb3I6ICNmNzg2MWM7XG59XG5cbi5uYW1lLWxhYmVsOmhvdmVyIC5lZGl0LXRleHQge1xuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xufVxuLyogdHggY29uZmlybSAqL1xuXG4udW5jb25mdHgtc2VjdGlvbiBpbnB1dFt0eXBlPXBhc3N3b3JkXSB7XG4gIGhlaWdodDogMjJweDtcbiAgcGFkZGluZzogMnB4O1xuICBtYXJnaW46IDEycHg7XG4gIG1hcmdpbi1ib3R0b206IDI0cHg7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgYm9yZGVyOiAycHggc29saWQgI2YzYzgzZTtcbiAgYmFja2dyb3VuZDogI2ZhZjZmMDtcbn1cblxuLyogRXRoZXIgQmFsYW5jZSBXaWRnZXQgKi9cblxuLmV0aGVyLWJhbGFuY2UtYW1vdW50IHtcbiAgY29sb3I6ICNmNzg2MWM7XG59XG5cbi5ldGhlci1iYWxhbmNlLWxhYmVsIHtcbiAgY29sb3I6ICNhYmE5YWE7XG59XG5cbi8qIEluZm8gc2NyZWVuICovXG4uaW5mby1ncmF5IHtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgY29sb3I6ICRzaWx2ZXItY2hhbGljZTtcbn1cblxuLmljb24tc2l6ZSB7XG4gIHdpZHRoOiAyMHB4O1xufVxuXG4uaW5mbyB7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG8sIEFyaWFsO1xuICBwYWRkaW5nLWJvdHRvbTogMTBweDtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBwYWRkaW5nLWxlZnQ6IDVweDtcbn1cblxuLyogYnV5IGV0aCB3YXJuaW5nIHNjcmVlbiAqL1xuLmN1c3RvbS1yYWRpb3Mge1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cblxuLmN1c3RvbS1yYWRpby1zZWxlY3RlZCB7XG4gIHdpZHRoOiAxN3B4O1xuICBoZWlnaHQ6IDE3cHg7XG4gIGJvcmRlcjogc29saWQ7XG4gIGJvcmRlci1zdHlsZTogZG91YmxlO1xuICBib3JkZXItcmFkaXVzOiAxNXB4O1xuICBib3JkZXItd2lkdGg6IDVweDtcbiAgYmFja2dyb3VuZDogcmdiYSgyNDcsIDEzNCwgMjgsIDEpO1xuICBib3JkZXItY29sb3I6ICNmN2Y3Zjc7XG59XG5cbi5jdXN0b20tcmFkaW8taW5hY3RpdmUge1xuICB3aWR0aDogMTRweDtcbiAgaGVpZ2h0OiAxNHB4O1xuICBib3JkZXI6IHNvbGlkO1xuICBib3JkZXItd2lkdGg6IDFweDtcbiAgYm9yZGVyLXJhZGl1czogMjRweDtcbiAgYm9yZGVyLWNvbG9yOiAkc2lsdmVyLWNoYWxpY2U7XG59XG5cbi5yYWRpby10aXRsZXMge1xuICBjb2xvcjogcmdiYSgyNDcsIDEzNCwgMjgsIDEpO1xufVxuXG4uZXRoLXdhcm5pbmcge1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IDQwMG1zIGVhc2UtaW4sIHRyYW5zZm9ybSA0MDBtcyBlYXNlLWluO1xufVxuXG4uYnV5LXN1YnZpZXcge1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IDQwMG1zIGVhc2UtaW4sIHRyYW5zZm9ybSA0MDBtcyBlYXNlLWluO1xufVxuXG4uaW5wdXQtY29udGFpbmVyOmhvdmVyIC5lZGl0LXRleHQge1xuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xufVxuXG4uYnV5LWlucHV0cyB7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgaGVpZ2h0OiAyMHB4O1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgYm9yZGVyOiBzb2xpZDtcbiAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgYm9yZGVyLXdpZHRoOiAuNXB4O1xuICBib3JkZXItcmFkaXVzOiAycHg7XG59XG5cbi5pbnB1dC1jb250YWluZXI6aG92ZXIgLmJ1eS1pbnB1dHMge1xuICBib3gtc2l6aW5nOiBpbmhlcml0O1xuICBib3JkZXI6IHNvbGlkO1xuICBib3JkZXItY29sb3I6ICNmNzg2MWM7XG4gIGJvcmRlci13aWR0aDogLjVweDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xufVxuXG4uYnV5LWlucHV0czpmb2N1cyB7XG4gIGJvcmRlcjogc29saWQ7XG4gIGJvcmRlci1jb2xvcjogI2Y3ODYxYztcbiAgYm9yZGVyLXdpZHRoOiAuNXB4O1xuICBib3JkZXItcmFkaXVzOiAycHg7XG59XG5cbi5hY3RpdmVGb3JtIHtcbiAgYmFja2dyb3VuZDogI2Y3ZjdmNztcbiAgYm9yZGVyOiBub25lO1xuICBib3JkZXItcmFkaXVzOiA4cHggOHB4IDBweCAwcHg7XG4gIHdpZHRoOiA1MCU7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgcGFkZGluZy1ib3R0b206IDRweDtcbn1cblxuLmluYWN0aXZlRm9ybSB7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogOHB4IDhweCAwcHggMHB4O1xuICB3aWR0aDogNTAlO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHBhZGRpbmctYm90dG9tOiA0cHg7XG59XG5cbi5leC1jb2lucyB7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1zaXplOiAzM3B4O1xuICB3aWR0aDogMTE4cHg7XG4gIGhlaWdodDogNDJweDtcbiAgcGFkZGluZzogMXB4O1xuICBjb2xvcjogIzRkNGQ0ZDtcbn1cblxuLm1hcmtldGluZm8ge1xuICBmb250LWZhbWlseTogUm9ib3RvO1xuICBjb2xvcjogJHNpbHZlci1jaGFsaWNlO1xuICBmb250LXNpemU6IDE1cHg7XG4gIGxpbmUtaGVpZ2h0OiAxN3B4O1xufVxuXG4jZnJvbUNvaW46Oi13ZWJraXQtY2FsZW5kYXItcGlja2VyLWluZGljYXRvciB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbiNjb2luTGlzdCB7XG4gIHdpZHRoOiA0MDBweDtcbiAgaGVpZ2h0OiA1MDBweDtcbiAgb3ZlcmZsb3c6IHNjcm9sbDtcbn1cblxuLmljb24tY29udHJvbCAuZmEtcmVmcmVzaCB7XG4gIHZpc2liaWxpdHk6IGhpZGRlbjtcbn1cblxuLmljb24tY29udHJvbDpob3ZlciAuZmEtcmVmcmVzaCB7XG4gIHZpc2liaWxpdHk6IHZpc2libGU7XG59XG5cbi5pY29uLWNvbnRyb2w6aG92ZXIgLmZhLWNoZXZyb24tcmlnaHQge1xuICB2aXNpYmlsaXR5OiBoaWRkZW47XG59XG5cbi5pbmFjdGl2ZSB7XG4gIGNvbG9yOiAkc2lsdmVyLWNoYWxpY2U7XG59XG5cbi5pbmFjdGl2ZSBidXR0b24ge1xuICBiYWNrZ3JvdW5kOiAkc2lsdmVyLWNoYWxpY2U7XG4gIGNvbG9yOiAkd2hpdGU7XG59XG5cbi5xci1lbGxpcC1hZGRyZXNzLCAuZWxsaXAtYWRkcmVzcyB7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xufVxuXG4ucXItaGVhZGVyIHtcbiAgZm9udC1zaXplOiAyNXB4O1xuICBtYXJnaW4tdG9wOiA0MHB4O1xufVxuXG4ucXItbWVzc2FnZSB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6ICNmNzg2MWM7XG59XG5cbmRpdi5tZXNzYWdlLWNvbnRhaW5lciA+IGRpdjpmaXJzdC1jaGlsZCB7XG4gIG1hcmdpbi10b3A6IDE4cHg7XG4gIGZvbnQtc2l6ZTogMTVweDtcbiAgY29sb3I6ICM0ZDRkNGQ7XG59XG5cbi5wb3AtaG92ZXI6aG92ZXIge1xuICB0cmFuc2Zvcm06IHNjYWxlKDEuMSk7XG59XG5cbi8qIHN0eWxlbGludC1lbmFibGUgKi9cbiIsIiR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50OiA4OTBweDtcbiR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50LXJhbmdlOiBcInNjcmVlbiBhbmQgKG1pbi13aWR0aDogI3skYnJlYWstbGFyZ2V9KSBhbmQgKG1heC13aWR0aDogI3skd2FsbGV0LWJhbGFuY2UtYnJlYWtwb2ludH0pXCI7XG5cbi50b2tlbi1saXN0LWl0ZW0ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWZsb3c6IHJvdyBub3dyYXA7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIHBhZGRpbmc6IDIwcHggMjRweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB0cmFuc2l0aW9uOiBsaW5lYXIgMjAwbXM7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHdhbGxldC1iYWxhbmNlLWJnLCAwKTtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gICZfX3Rva2VuLWJhbGFuY2Uge1xuICAgIGZvbnQtc2l6ZTogMTMwJTtcblxuICAgIEBtZWRpYSAjeyR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50LXJhbmdlfSB7XG4gICAgICBmb250LXNpemU6IDEwNSU7XG4gICAgfVxuICB9XG5cbiAgJl9fZmlhdC1hbW91bnQge1xuICAgIG1hcmdpbi10b3A6IC4yNSU7XG4gICAgZm9udC1zaXplOiAxMDUlO1xuICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG5cbiAgICBAbWVkaWEgI3skd2FsbGV0LWJhbGFuY2UtYnJlYWtwb2ludC1yYW5nZX0ge1xuICAgICAgZm9udC1zaXplOiA5NSU7XG4gICAgfVxuICB9XG5cbiAgQG1lZGlhICN7JHdhbGxldC1iYWxhbmNlLWJyZWFrcG9pbnQtcmFuZ2V9IHtcbiAgICBwYWRkaW5nOiAxMCUgNCU7XG4gIH1cblxuICAmLS1hY3RpdmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoJHdhbGxldC1iYWxhbmNlLWJnLCAxKTtcbiAgfVxuXG4gICZfX2lkZW50aWNvbiB7XG4gICAgbWFyZ2luLXJpZ2h0OiAxNXB4O1xuICAgIGJvcmRlcjogJzFweCBzb2xpZCAjZGVkZWRlJztcblxuICAgIEBtZWRpYSAjeyR3YWxsZXQtYmFsYW5jZS1icmVha3BvaW50LXJhbmdlfSB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDQlO1xuICAgIH1cbiAgfVxuXG4gICZfX2VsbGlwc2lzIHtcbiAgICAvLyBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgLy8gdG9wOiAyMHB4O1xuICAgIC8vIHJpZ2h0OiAyNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiA0NXB4O1xuICB9XG5cbiAgJl9fYmFsYW5jZS13cmFwcGVyIHtcbiAgICBmbGV4OiAxIDEgYXV0bztcbiAgfVxufVxuXG4udG9rZW4tbWVudS1kcm9wZG93biB7XG4gIGhlaWdodDogNTVweDtcbiAgd2lkdGg6IDE5MXB4O1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwwLDAsMC44Mik7XG4gIGJveC1zaGFkb3c6IDAgMnB4IDRweCAwIHJnYmEoMCwwLDAsMC41KTtcbiAgcG9zaXRpb246IGZpeGVkO1xuICBtYXJnaW4tdG9wOiAyMHB4O1xuICBtYXJnaW4tbGVmdDogMTA1cHg7XG4gIHotaW5kZXg6IDIwMDA7XG5cbiAgJl9fY2xvc2UtYXJlYSB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHotaW5kZXg6IDIxMDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGN1cnNvcjogZGVmYXVsdDtcbiAgfVxuXG4gICZfX2NvbnRhaW5lciB7XG4gICAgcGFkZGluZzogMTZweCAzNHB4IDMycHg7XG4gICAgei1pbmRleDogMjIwMDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIH1cblxuICAmX19vcHRpb25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIH1cblxuICAmX19vcHRpb24ge1xuICAgIGNvbG9yOiAkd2hpdGU7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbGluZS1oZWlnaHQ6IDIxcHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICB9XG59IiwiLmFkZC10b2tlbiB7XG4gIHdpZHRoOiA0OThweDtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHotaW5kZXg6IDEyO1xuICBmb250LWZhbWlseTogJ0RJTiBOZXh0IExpZ2h0JztcblxuICAmX193cmFwcGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gICAgYm94LXNoYWRvdzogMCAycHggNHB4IDAgcmdiYSgkYmxhY2ssIC4wOCk7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBmbGV4OiAwIDAgYXV0bztcbiAgfVxuXG4gICZfX3RpdGxlLWNvbnRhaW5lciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBwYWRkaW5nOiAzMHB4IDYwcHggMTJweDtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgJGdhbGxlcnk7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICAmX190aXRsZSB7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgICBmb250LXNpemU6IDIwcHg7XG4gICAgbGluZS1oZWlnaHQ6IDI2cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgbWFyZ2luLWJvdHRvbTogMTJweDtcbiAgfVxuXG4gICZfX2Rlc2NyaXB0aW9uIHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIH1cblxuICAmX19kZXNjcmlwdGlvbiArICZfX2Rlc2NyaXB0aW9uIHtcbiAgICBtYXJnaW4tdG9wOiAyNHB4O1xuICB9XG5cbiAgJl9fY29uZmlybWF0aW9uLWRlc2NyaXB0aW9uIHtcbiAgICBtYXJnaW46IDEycHggMDtcbiAgfVxuXG4gICZfX2NvbnRlbnQtY29udGFpbmVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgJGdhbGxlcnk7XG4gIH1cblxuICAmX19pbnB1dC1jb250YWluZXIge1xuICAgIHBhZGRpbmc6IDExcHggMDtcbiAgICB3aWR0aDogMjYzcHg7XG4gICAgbWFyZ2luOiAwIGF1dG87XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB9XG5cbiAgJl9fc2VhcmNoLWlucHV0LWVycm9yLW1lc3NhZ2Uge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBib3R0b206IC0xMHB4O1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgY29sb3I6ICRyZWQ7XG4gIH1cblxuICAmX19pbnB1dCB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgYm9yZGVyOiAycHggc29saWQgJGdhbGxlcnk7XG4gICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgIHBhZGRpbmc6IDVweCAxNXB4O1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMTlweDtcblxuICAgICY6OnBsYWNlaG9sZGVyIHtcbiAgICAgIGNvbG9yOiAkc2lsdmVyO1xuICAgIH1cbiAgfVxuXG4gICZfX2Zvb3RlcnMge1xuICAgIHdpZHRoOiAxMDAlO1xuICB9XG5cbiAgJl9fYWRkLWN1c3RvbSB7XG4gICAgY29sb3I6ICRzY29ycGlvbjtcbiAgICBmb250LXNpemU6IDE4cHg7XG4gICAgbGluZS1oZWlnaHQ6IDI0cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIHBhZGRpbmc6IDEycHggMDtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcblxuICAgICY6aG92ZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAuMDUpO1xuICAgIH1cblxuICAgICY6YWN0aXZlIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgLjEpO1xuICAgIH1cblxuICAgIC5mYSB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICByaWdodDogMjRweDtcbiAgICAgIGZvbnQtc2l6ZTogMjRweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAyNHB4O1xuICAgIH1cbiAgfVxuXG4gICZfX2FkZC1jdXN0b20tZm9ybSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG4gICAgbWFyZ2luOiA4cHggMCA1MXB4O1xuICB9XG5cbiAgJl9fYWRkLWN1c3RvbS1maWVsZCB7XG4gICAgd2lkdGg6IDI5MHB4O1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgICYtLWVycm9yIHtcbiAgICAgIC5hZGQtdG9rZW5fX2FkZC1jdXN0b20taW5wdXQge1xuICAgICAgICBib3JkZXItY29sb3I6ICRyZWQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgJl9fYWRkLWN1c3RvbS1lcnJvci1tZXNzYWdlIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgYm90dG9tOiAtMjFweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIGNvbG9yOiAkcmVkO1xuICB9XG5cbiAgJl9fYWRkLWN1c3RvbS1sYWJlbCB7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAyMXB4O1xuICAgIG1hcmdpbi1ib3R0b206IDhweDtcbiAgfVxuXG4gICZfX2FkZC1jdXN0b20taW5wdXQge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRzaWx2ZXI7XG4gICAgcGFkZGluZzogNXB4IDE1cHg7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxOXB4O1xuXG4gICAgJjo6cGxhY2Vob2xkZXIge1xuICAgICAgY29sb3I6ICRzaWx2ZXI7XG4gICAgfVxuICB9XG5cbiAgJl9fYWRkLWN1c3RvbS1maWVsZCArICZfX2FkZC1jdXN0b20tZmllbGQge1xuICAgIG1hcmdpbi10b3A6IDIxcHg7XG4gIH1cblxuICAmX19idXR0b25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgICBtYXJnaW46IDMwcHggMCA1MXB4O1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICB9XG5cbiAgJl9fdG9rZW4taWNvbnMtY29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogcm93IHdyYXA7XG4gIH1cblxuICAmX190b2tlbi13cmFwcGVyIHtcbiAgICB0cmFuc2l0aW9uOiAyMDBtcyBlYXNlLWluLW91dDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgICBmbGV4OiAwIDAgNDIuNSU7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBwYWRkaW5nOiAxMnB4O1xuICAgIG1hcmdpbjogMi41JTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgICY6aG92ZXIge1xuICAgICAgYm9yZGVyOiAycHggc29saWQgcmdiYSgkbWFsaWJ1LWJsdWUsIC41KTtcbiAgICB9XG5cbiAgICAmLS1zZWxlY3RlZCB7XG4gICAgICBib3JkZXI6IDJweCBzb2xpZCAkbWFsaWJ1LWJsdWUgIWltcG9ydGFudDtcbiAgICB9XG5cbiAgICAmLS1kaXNhYmxlZCB7XG4gICAgICBvcGFjaXR5OiAuNDtcbiAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIH1cbiAgfVxuXG4gICZfX3Rva2VuLWRhdGEge1xuICAgIGFsaWduLXNlbGY6IGZsZXgtc3RhcnQ7XG4gIH1cblxuICAmX190b2tlbi1uYW1lIHtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gIH1cblxuICAmX190b2tlbi1zeW1ib2wge1xuICAgIGZvbnQtc2l6ZTogMjJweDtcbiAgICBsaW5lLWhlaWdodDogMjlweDtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICB9XG5cbiAgJl9fdG9rZW4taWNvbiB7XG4gICAgd2lkdGg6IDYwcHg7XG4gICAgaGVpZ2h0OiA2MHB4O1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgYmFja2dyb3VuZC1zaXplOiBjb250YWluO1xuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICAgIGJveC1zaGFkb3c6IDAgMnB4IDRweCAwIHJnYmEoJGJsYWNrLCAuMjQpO1xuICAgIG1hcmdpbi1yaWdodDogMTJweDtcbiAgICBmbGV4OiAwIDAgYXV0bztcbiAgfVxuXG4gICZfX3Rva2VuLW1lc3NhZ2Uge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBjb2xvcjogJGNhcmliYmVhbi1ncmVlbjtcbiAgICBmb250LXNpemU6IDExcHg7XG4gICAgYm90dG9tOiAwO1xuICAgIGxlZnQ6IDg1cHg7XG4gIH1cblxuICAmX19jb25maXJtYXRpb24tdG9rZW4tbGlzdCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbiBub3dyYXA7XG5cbiAgICAudG9rZW4tYmFsYW5jZSB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1mbG93OiByb3cgbm93cmFwO1xuICAgICAgYWxpZ24taXRlbXM6IGZsZXgtc3RhcnQ7XG5cbiAgICAgICZfX2Ftb3VudCB7XG4gICAgICAgIGNvbG9yOiAkc2NvcnBpb247XG4gICAgICAgIGZvbnQtc2l6ZTogNDNweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDQzcHg7XG4gICAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgICAgfVxuXG4gICAgICAmX19zeW1ib2wge1xuICAgICAgICBjb2xvcjogJHNjb3JwaW9uO1xuICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAyNHB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gICZfX2NvbmZpcm1hdGlvbi10aXRsZSB7XG4gICAgcGFkZGluZzogMzBweCAxMjBweCAxMnB4O1xuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgICBwYWRkaW5nOiAyMHB4IDA7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG4gIH1cblxuICAmX19jb25maXJtYXRpb24tY29udGVudCB7XG4gICAgcGFkZGluZy1ib3R0b206IDYwcHg7XG4gIH1cblxuICAmX19jb25maXJtYXRpb24tdG9rZW4tbGlzdC1pdGVtIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgICBtYXJnaW46IDAgYXV0bztcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICB9XG5cbiAgJl9fY29uZmlybWF0aW9uLXRva2VuLWxpc3QtaXRlbSArICZfX2NvbmZpcm1hdGlvbi10b2tlbi1saXN0LWl0ZW0ge1xuICAgIG1hcmdpbi10b3A6IDMwcHg7XG4gIH1cblxuICAmX19jb25maXJtYXRpb24tdG9rZW4taWNvbiB7XG4gICAgbWFyZ2luLXJpZ2h0OiAxOHB4O1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgaGVpZ2h0OiAxMDAlO1xuXG4gICAgJl9fd3JhcHBlciB7XG4gICAgICBib3gtc2hhZG93OiBub25lICFpbXBvcnRhbnQ7XG4gICAgICBmbGV4OiAxIDEgYXV0bztcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICB9XG5cbiAgICAmX19mb290ZXJzIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkZ2FsbGVyeTtcbiAgICB9XG5cbiAgICAmX190b2tlbi1pY29uIHtcbiAgICAgIHdpZHRoOiA1MHB4O1xuICAgICAgaGVpZ2h0OiA1MHB4O1xuICAgIH1cblxuICAgICZfX3Rva2VuLXN5bWJvbCB7XG4gICAgICBmb250LXNpemU6IDE4cHg7XG4gICAgICBsaW5lLWhlaWdodDogMjRweDtcbiAgICB9XG5cbiAgICAmX190b2tlbi1uYW1lIHtcbiAgICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxNnB4O1xuICAgIH1cblxuICAgICZfX2J1dHRvbnMge1xuICAgICAgZmxleC1mbG93OiByb3cgbm93cmFwO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBwYWRkaW5nOiAxMnB4IDA7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBib3JkZXItdG9wOiAxcHggc29saWQgJGdhbGxlcnk7XG5cbiAgICAgIGJ1dHRvbiB7XG4gICAgICAgIGZsZXg6IDEgMCBhdXRvO1xuICAgICAgICBtYXJnaW46IDAgMTJweDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsIi5jdXJyZW5jeS1kaXNwbGF5IHtcbiAgaGVpZ2h0OiA1NHB4O1xuICB3aWR0aDogMTAwJcOfO1xuICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgZm9udC1zaXplOiAxNnB4O1xuICBmb250LXdlaWdodDogMzAwO1xuICBwYWRkaW5nOiA4cHggMTBweDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gICZfX3ByaW1hcnktcm93IHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICB9XG5cbiAgJl9faW5wdXQge1xuICAgIGNvbG9yOiAkc2NvcnBpb247XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbGluZS1oZWlnaHQ6IDIycHg7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIG91dGxpbmU6IDAgIWltcG9ydGFudDtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gIH1cblxuICAmX19wcmltYXJ5LWN1cnJlbmN5IHtcbiAgICBjb2xvcjogJHNjb3JwaW9uO1xuICAgIGZvbnQtd2VpZ2h0OiA0MDA7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbGluZS1oZWlnaHQ6IDIycHg7XG4gIH1cblxuICAmX19jb252ZXJ0ZWQtcm93IHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICB9XG5cbiAgJl9fY29udmVydGVkLXZhbHVlLFxuICAmX19jb252ZXJ0ZWQtY3VycmVuY3kge1xuICAgIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgICBmb250LWZhbWlseTogUm9ib3RvO1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBsaW5lLWhlaWdodDogMTJweDtcbiAgfVxuXG4gICZfX2lucHV0LXdyYXBwZXIge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICB9XG5cbiAgJl9fY3VycmVuY3ktc3ltYm9sIHtcbiAgICBtYXJnaW4tdG9wOiAxcHg7XG4gIH1cbn0iLCIuYWNjb3VudC1tZW51IHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB6LWluZGV4OiAxMDA7XG4gIHRvcDogNThweDtcbiAgd2lkdGg6IDMxMHB4O1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgcmlnaHQ6IGNhbGMoKCgxMDB2dyAtIDEwMCUpIC8gMikgKyA4cHgpO1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNTc2cHgpIHtcbiAgICByaWdodDogY2FsYygoMTAwdncgLSA4NXZ3KSAvIDIpO1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzY5cHgpIHtcbiAgICByaWdodDogY2FsYygoMTAwdncgLSA4MHZ3KSAvIDIpO1xuICB9XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTI4MXB4KSB7XG4gICAgcmlnaHQ6IGNhbGMoKDEwMHZ3IC0gNjV2dykgLyAyKTtcbiAgfVxuXG4gICZfX2ljb24ge1xuICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgfVxuXG4gICZfX2hlYWRlciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IHJvdyBub3dyYXA7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIH1cblxuICAmX19sb2dvdXQtYnV0dG9uIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkZHVzdHktZ3JheTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICBjb2xvcjogJHdoaXRlO1xuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbGluZS1oZWlnaHQ6IDIzcHg7XG4gICAgcGFkZGluZzogMCAyNHB4O1xuICAgIGZvbnQtd2VpZ2h0OiAyMDA7XG4gIH1cblxuICBpbWcge1xuICAgIHdpZHRoOiAxNnB4O1xuICAgIGhlaWdodDogMTZweDtcbiAgfVxuXG4gICZfX2FjY291bnRzIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogY29sdW1uIG5vd3JhcDtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIG1heC1oZWlnaHQ6IDI0MHB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB6LWluZGV4OiAyMDA7XG5cbiAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgICBtYXgtaGVpZ2h0OiAyMTVweDtcbiAgICB9XG5cbiAgICAua2V5cmluZy1sYWJlbCB7XG4gICAgICBtYXJnaW4tdG9wOiA1cHg7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkYmxhY2s7XG4gICAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgfVxuICB9XG5cbiAgJl9fYWNjb3VudCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IHJvdyBub3dyYXA7XG4gICAgcGFkZGluZzogMTZweCAxNHB4O1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICAgIHBhZGRpbmc6IDEycHggMTRweDtcbiAgICB9XG4gIH1cblxuICAmX19hY2NvdW50LWluZm8ge1xuICAgIGZsZXg6IDEgMCBhdXRvO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICAgIHBhZGRpbmctdG9wOiA0cHg7XG4gIH1cblxuICAmX19jaGVjay1tYXJrIHtcbiAgICB3aWR0aDogMTRweDtcbiAgICBtYXJnaW4tcmlnaHQ6IDEycHg7XG4gICAgZmxleDogMCAwIGF1dG87XG4gIH1cblxuICAmX19jaGVjay1tYXJrLWljb24ge1xuICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybChcImltYWdlcy9jaGVjay13aGl0ZS5zdmdcIik7XG4gICAgaGVpZ2h0OiAxOHB4O1xuICAgIHdpZHRoOiAxOHB4O1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyO1xuICAgIGJhY2tncm91bmQtc2l6ZTogY29udGFpbjtcbiAgICBtYXJnaW46IDNweCAwO1xuICB9XG5cbiAgLmlkZW50aWNvbiB7XG4gICAgbWFyZ2luOiAwIDEycHggMCAwO1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICB9XG5cbiAgJl9fbmFtZSB7XG4gICAgY29sb3I6ICR3aGl0ZTtcbiAgICBmb250LXNpemU6IDE4cHg7XG4gICAgZm9udC13ZWlnaHQ6IDIwMDtcbiAgICBsaW5lLWhlaWdodDogMTZweDtcbiAgfVxuXG4gICZfX2JhbGFuY2Uge1xuICAgIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gIH1cblxuICAmX19hY3Rpb24ge1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBsaW5lLWhlaWdodDogMThweDtcbiAgICBmb250LXdlaWdodDogMjAwO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgfVxufVxuIiwiLm1lbnUge1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGJhY2tncm91bmQ6IHJnYmEoJGJsYWNrLCAuOCk7XG4gIGJveC1zaGFkb3c6IHJnYmEoJGJsYWNrLCAuMTUpIDAgMnB4IDJweCAycHg7XG4gIG1pbi13aWR0aDogMTUwcHg7XG4gIGNvbG9yOiAkd2hpdGU7XG5cbiAgJl9faXRlbSB7XG4gICAgcGFkZGluZzogMThweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZmxvdzogcm93IG5vd3JhcDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB6LWluZGV4OiAyMDA7XG4gICAgZm9udC13ZWlnaHQ6IDIwMDtcblxuICAgIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgICBwYWRkaW5nOiAxNHB4O1xuICAgIH1cblxuICAgICYtLWNsaWNrYWJsZSB7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG5cbiAgICAgICY6aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCR3aGl0ZSwgLjA1KTtcbiAgICAgIH1cblxuICAgICAgJjphY3RpdmUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCR3aGl0ZSwgLjEpO1xuICAgICAgfVxuICAgIH1cblxuICAgICZfX2ljb24ge1xuICAgICAgaGVpZ2h0OiAxNnB4O1xuICAgICAgd2lkdGg6IDE2cHg7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDE0cHg7XG4gICAgfVxuXG4gICAgJl9fdGV4dCB7XG4gICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICBsaW5lLWhlaWdodDogMjFweDtcbiAgICB9XG4gIH1cblxuICAmX19kaXZpZGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkc2NvcnBpb247XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxcHg7XG4gIH1cblxuICAmX19jbG9zZS1hcmVhIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgfVxufVxuIiwiLmdhcy1zbGlkZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHdpZHRoOiAzMTNweDtcblxuICAmX19pbnB1dCB7XG4gICAgd2lkdGg6IDMxN3B4O1xuICAgIG1hcmdpbi1sZWZ0OiAtMnB4O1xuICAgIHotaW5kZXg6IDI7XG4gIH1cblxuICBpbnB1dFt0eXBlPXJhbmdlXSB7XG4gICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lICFpbXBvcnRhbnQ7XG4gIH1cblxuICBpbnB1dFt0eXBlPXJhbmdlXTo6LXdlYmtpdC1zbGlkZXItdGh1bWIge1xuICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZSAhaW1wb3J0YW50O1xuICAgIGhlaWdodDogMjZweDtcbiAgICB3aWR0aDogMjZweDtcbiAgICBib3JkZXI6IDJweCBzb2xpZCAjQjhCOEI4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNGRkZGRkY7XG4gICAgYm94LXNoYWRvdzogMCAycHggNHB4IDAgcmdiYSgwLDAsMCwwLjA4KTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHotaW5kZXg6IDEwO1xuICB9XG5cbiAgJl9fYmFyIHtcbiAgICBoZWlnaHQ6IDZweDtcbiAgICB3aWR0aDogMzEzcHg7XG4gICAgYmFja2dyb3VuZDogJGFsdG87XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMTFweDtcbiAgICB6LWluZGV4OiAwO1xuICB9XG5cbiAgJl9fbG93LCAmX19oaWdoIHtcbiAgICBoZWlnaHQ6IDZweDtcbiAgICB3aWR0aDogNDlweDtcbiAgICB6LWluZGV4OiAxO1xuICB9XG5cbiAgJl9fbG93IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY3JpbXNvbjtcbiAgfVxuXG4gICZfX2hpZ2gge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjYXJpYmJlYW4tZ3JlZW47XG4gIH1cbn0iLCIuc2V0dGluZ3Mge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGJhY2tncm91bmQ6ICR3aGl0ZTtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICBoZWlnaHQ6IGF1dG87XG4gIG92ZXJmbG93OiBhdXRvO1xufVxuXG4uc2V0dGluZ3NfX2hlYWRlciB7XG4gIHBhZGRpbmc6IDI1cHg7XG59XG5cbi5zZXR0aW5nc19fY2xvc2UtYnV0dG9uOjphZnRlciB7XG4gIGNvbnRlbnQ6ICdcXDAwRDcnO1xuICBmb250LXNpemU6IDQwcHg7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDI1cHg7XG4gIHJpZ2h0OiAzMHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5zZXR0aW5nc19fZXJyb3Ige1xuICBwYWRkaW5nLWJvdHRvbTogMjBweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBjb2xvcjogJGNyaW1zb247XG59XG5cbi5zZXR0aW5nc19fY29udGVudCB7XG4gIHBhZGRpbmc6IDAgMjVweDtcbn1cblxuLnNldHRpbmdzX19jb250ZW50LXJvdyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIHBhZGRpbmc6IDEwcHggMCAyMHB4O1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBwYWRkaW5nOiAxMHB4IDA7XG4gIH1cbn1cblxuLnNldHRpbmdzX19jb250ZW50LWl0ZW0ge1xuICBmbGV4OiAxO1xuICBtaW4td2lkdGg6IDA7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIHBhZGRpbmc6IDAgNXB4O1xuICBoZWlnaHQ6IDcxcHg7XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICBoZWlnaHQ6IGluaXRpYWw7XG4gICAgcGFkZGluZzogNXB4IDA7XG4gIH1cblxuICAmLS13aXRob3V0LWhlaWdodCB7XG4gICAgaGVpZ2h0OiBpbml0aWFsO1xuICB9XG59XG5cbi5zZXR0aW5nc19fY29udGVudC1pdGVtLWNvbCB7XG4gIG1heC13aWR0aDogMzAwcHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG5cbiAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTc1cHgpIHtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgd2lkdGg6IDEwMCU7XG4gIH1cbn1cblxuLnNldHRpbmdzX19jb250ZW50LWRlc2NyaXB0aW9uIHtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gIHBhZGRpbmctdG9wOiA1cHg7XG59XG5cbi5zZXR0aW5nc19faW5wdXQge1xuICBwYWRkaW5nLWxlZnQ6IDEwcHg7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgaGVpZ2h0OiA0MHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbn1cblxuLnNldHRpbmdzX19pbnB1dDo6LXdlYmtpdC1pbnB1dC1wbGFjZWhvbGRlciB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbn1cblxuLnNldHRpbmdzX19pbnB1dDo6LW1vei1wbGFjZWhvbGRlciB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbn1cblxuLnNldHRpbmdzX19pbnB1dDotbXMtaW5wdXQtcGxhY2Vob2xkZXIge1xuICBmb250LXdlaWdodDogMTAwO1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG59XG5cbi5zZXR0aW5nc19faW5wdXQ6LW1vei1wbGFjZWhvbGRlciB7XG4gIGZvbnQtd2VpZ2h0OiAxMDA7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbn1cblxuLnNldHRpbmdzX19wcm92aWRlci13cmFwcGVyIHtcbiAgZm9udC1zaXplOiAxNnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBwYWRkaW5nOiAxNXB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cblxuLnNldHRpbmdzX19wcm92aWRlci1pY29uIHtcbiAgaGVpZ2h0OiAxMHB4O1xuICB3aWR0aDogMTBweDtcbiAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xufVxuXG4uc2V0dGluZ3NfX3JwYy1zYXZlLWJ1dHRvbiB7XG4gIGFsaWduLXNlbGY6IGZsZXgtZW5kO1xuICBwYWRkaW5nOiA1cHg7XG4gIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uc2V0dGluZ3NfX2NsZWFyLWJ1dHRvbiB7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgYm9yZGVyOiAxcHggc29saWQgJGN1cmlvdXMtYmx1ZTtcbiAgY29sb3I6ICRjdXJpb3VzLWJsdWU7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgcGFkZGluZzogMThweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJHdoaXRlO1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xufVxuXG4uc2V0dGluZ3NfX2NsZWFyLWJ1dHRvbi0tcmVkIHtcbiAgYm9yZGVyOiAxcHggc29saWQgJG1vbnpvO1xuICBjb2xvcjogJG1vbnpvO1xufVxuXG4uc2V0dGluZ3NfX2luZm8tbG9nby13cmFwcGVyIHtcbiAgaGVpZ2h0OiA4MHB4O1xuICBtYXJnaW4tYm90dG9tOiAyMHB4O1xufVxuXG4uc2V0dGluZ3NfX2luZm8tbG9nbyB7XG4gIG1heC1oZWlnaHQ6IDEwMCU7XG4gIG1heC13aWR0aDogMTAwJTtcbn1cblxuLnNldHRpbmdzX19pbmZvLWl0ZW0ge1xuICBwYWRkaW5nOiAxMHB4IDA7XG59XG5cbi5zZXR0aW5nc19faW5mby1saW5rLWhlYWRlciB7XG4gIHBhZGRpbmctYm90dG9tOiAxNXB4O1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgcGFkZGluZy1ib3R0b206IDVweDtcbiAgfVxufVxuXG4uc2V0dGluZ3NfX2luZm8tbGluay1pdGVtIHtcbiAgcGFkZGluZzogMTVweCAwO1xuXG4gIEBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU3NXB4KSB7XG4gICAgcGFkZGluZzogNXB4IDA7XG4gIH1cbn1cblxuLnNldHRpbmdzX19pbmZvLXZlcnNpb24tbnVtYmVyIHtcbiAgcGFkZGluZy10b3A6IDVweDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBjb2xvcjogJGR1c3R5LWdyYXk7XG59XG5cbi5zZXR0aW5nc19faW5mby1hYm91dCB7XG4gIGNvbG9yOiAkZHVzdHktZ3JheTtcbiAgbWFyZ2luLWJvdHRvbTogMTVweDtcbn1cblxuLnNldHRpbmdzX19pbmZvLWxpbmsge1xuICBjb2xvcjogJGN1cmlvdXMtYmx1ZTtcbn1cblxuLnNldHRpbmdzX19pbmZvLXNlcGFyYXRvciB7XG4gIG1hcmdpbjogMTVweCAwO1xuICB3aWR0aDogODBweDtcbiAgYm9yZGVyLWNvbG9yOiAkYWx0bztcbiAgYm9yZGVyOiBub25lO1xuICBoZWlnaHQ6IDFweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogJGFsdG87XG4gIGNvbG9yOiAkYWx0bztcbn1cbiIsIi50YWItYmFyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IHJvdztcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG59XG5cbi50YWItYmFyX190YWIge1xuICBtaW4td2lkdGg6IDA7XG4gIGZsZXg6IDAgMCBhdXRvO1xuICBwYWRkaW5nOiAxNXB4IDI1cHg7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAkYWx0bztcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgZm9udC1zaXplOiAxOHB4O1xufVxuXG4udGFiLWJhcl9fdGFiLS1hY3RpdmUge1xuICBib3JkZXItY29sb3I6ICRibGFjaztcbn1cblxuLnRhYi1iYXJfX2dyb3ctdGFiIHtcbiAgZmxleC1ncm93OiAxO1xufVxuIiwiLnNpbXBsZS1kcm9wZG93biB7XG4gIGhlaWdodDogNTZweDtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBib3JkZXI6IDFweCBzb2xpZCAkYWx0bztcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gIGZvbnQtc2l6ZTogMTZweDtcbiAgY29sb3I6ICM0ZDRkNGQ7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4uc2ltcGxlLWRyb3Bkb3duX19jYXJldCB7XG4gIGNvbG9yOiAkc2lsdmVyO1xuICBwYWRkaW5nOiAwIDEwcHg7XG59XG5cbi5zaW1wbGUtZHJvcGRvd25fX3NlbGVjdGVkIHtcbiAgZmxleC1ncm93OiAxO1xuICBwYWRkaW5nOiAwIDE1cHg7XG59XG5cbi5zaW1wbGUtZHJvcGRvd25fX29wdGlvbnMge1xuICB6LWluZGV4OiAxMDUwO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGhlaWdodDogMjIwcHg7XG4gIHdpZHRoOiAxMDAlO1xuICBib3JkZXI6IDFweCBzb2xpZCAjZDJkOGRkO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogMCAzcHggNnB4IDAgcmdiYSgwLCAwLCAwLCAuMTEpO1xuICBib3gtc2hhZG93OiAwIDNweCA2cHggMCByZ2JhKDAsIDAsIDAsIC4xMSk7XG4gIG1hcmdpbi10b3A6IDEwcHg7XG4gIG92ZXJmbG93LXk6IHNjcm9sbDtcbiAgbGVmdDogMDtcbiAgdG9wOiAxMDAlO1xufVxuXG4uc2ltcGxlLWRyb3Bkb3duX19vcHRpb24ge1xuICBwYWRkaW5nOiAxMHB4O1xuXG4gICY6aG92ZXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRnYWxsZXJ5O1xuICB9XG59XG5cbi5zaW1wbGUtZHJvcGRvd25fX29wdGlvbi0tc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkYWx0bztcblxuICAmOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkYWx0bztcbiAgICBjdXJzb3I6IGRlZmF1bHQ7XG4gIH1cbn1cblxuLnNpbXBsZS1kcm9wZG93bl9fY2xvc2UtYXJlYSB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICB6LWluZGV4OiAxMDAwO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuIiwiLnJlcXVlc3Qtc2lnbmF0dXJlIHtcbiAgJl9fY29udGFpbmVyIHtcbiAgICB3aWR0aDogMzgwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgICBib3gtc2hhZG93OiAwIDJweCA0cHggMCByZ2JhKDAsMCwwLDAuMDgpO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1mbG93OiBjb2x1bW4gbm93cmFwO1xuICAgIHotaW5kZXg6IDI1O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJGJyZWFrLXNtYWxsKSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIHRvcDogMDtcbiAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgfVxuXG4gICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJGJyZWFrLWxhcmdlKSB7XG4gICAgICBtYXgtaGVpZ2h0OiA2MjBweDtcbiAgICB9XG4gIH1cblxuICAmX19oZWFkZXIge1xuICAgIGhlaWdodDogNjRweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGZsZXg6IDAgMCBhdXRvO1xuICB9XG5cbiAgJl9faGVhZGVyLWJhY2tncm91bmQge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkYXRoZW5zLWdyZXk7XG4gICAgei1pbmRleDogMjtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gIH1cblxuICAmX19oZWFkZXJfX3RleHQge1xuICAgIGhlaWdodDogMjlweDtcbiAgICB3aWR0aDogMTc5cHg7XG4gICAgY29sb3I6ICM1QjVENjc7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDIycHg7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsaW5lLWhlaWdodDogMjlweDtcbiAgICB6LWluZGV4OiAzO1xuICB9XG5cbiAgJl9faGVhZGVyX190aXAtY29udGFpbmVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICB9XG5cbiAgJl9faGVhZGVyX190aXAge1xuICAgIGhlaWdodDogMjVweDtcbiAgICB3aWR0aDogMjVweDtcbiAgICBiYWNrZ3JvdW5kOiAkYXRoZW5zLWdyZXk7XG4gICAgdHJhbnNmb3JtOiByb3RhdGUoNDVkZWcpO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBib3R0b206IC04cHg7XG4gICAgei1pbmRleDogMTtcbiAgfVxuXG4gICZfX2FjY291bnQtaW5mbyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgbWFyZ2luLXRvcDogMThweDtcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xuICB9XG5cbiAgJl9fYWNjb3VudCB7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICAgIG1hcmdpbi1sZWZ0OiAxN3B4O1xuICB9XG5cbiAgJl9fYWNjb3VudC10ZXh0IHtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gIH1cblxuICAmX19iYWxhbmNlIHtcbiAgICBjb2xvcjogJGR1c3R5LWdyYXk7XG4gICAgbWFyZ2luLXJpZ2h0OiAxN3B4O1xuICAgIHdpZHRoOiAxMjRweDtcbiAgfVxuXG4gICZfX2JhbGFuY2UtdGV4dCB7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICB9XG5cbiAgJl9fYmFsYW5jZS12YWx1ZSB7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgbWFyZ2luLXRvcDogMi41cHg7XG4gIH1cblxuICAmX19yZXF1ZXN0LWljb24ge1xuICAgIG1hcmdpbi10b3A6IDI1cHg7XG4gIH1cblxuICAmX19ib2R5IHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbjtcbiAgICBmbGV4OiAxIDEgYXV0bztcbiAgICBoZWlnaHQ6IDA7XG4gIH1cblxuICAmX19yZXF1ZXN0LWluZm8ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIH1cblxuICAmX19oZWFkbGluZSB7XG4gICAgaGVpZ2h0OiA0OHB4O1xuICAgIHdpZHRoOiAyNDBweDtcbiAgICBjb2xvcjogJHR1bmRvcmE7XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE4cHg7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsaW5lLWhlaWdodDogMjRweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgbWFyZ2luLXRvcDogMjBweDtcbiAgfVxuXG4gICZfX25vdGljZSxcbiAgJl9fd2FybmluZyB7XG4gICAgZm9udC1mYW1pbHk6IFwiQXZlbmlyIE5leHRcIjtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIG1hcmdpbi10b3A6IDQxcHg7XG4gICAgbWFyZ2luLWJvdHRvbTogMTFweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgfVxuXG4gICZfX25vdGljZSB7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICB9XG5cbiAgJl9fd2FybmluZyB7XG4gICAgY29sb3I6ICRjcmltc29uO1xuICB9XG5cbiAgJl9fcm93cyB7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG92ZXJmbG93LXk6IHNjcm9sbDtcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47XG4gICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICRnZXlzZXI7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbjtcbiAgfVxuXG4gICZfX3JvdyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWZsb3c6IGNvbHVtbjtcbiAgfVxuXG4gICZfX3Jvdy10aXRsZSB7XG4gICAgd2lkdGg6IDgwcHg7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAyMnB4O1xuICAgIG1hcmdpbi10b3A6IDEycHg7XG4gICAgbWFyZ2luLWxlZnQ6IDE4cHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gIH1cblxuICAmX19yb3ctdmFsdWUge1xuICAgIGNvbG9yOiAkc2NvcnBpb247XG4gICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDE5cHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgb3ZlcmZsb3ctd3JhcDogYnJlYWstd29yZDtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2QyZDhkZDtcbiAgICBwYWRkaW5nOiA2cHggMThweCAxNXB4O1xuICB9XG5cbiAgJl9fZm9vdGVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1ldmVubHk7XG4gICAgZm9udC1zaXplOiAyMnB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBmbGV4OiAwIDAgYXV0bztcbiAgICBib3JkZXItdG9wOiAxcHggc29saWQgJGdleXNlcjtcblxuICAgICZfX2NhbmNlbC1idXR0b24sXG4gICAgJl9fc2lnbi1idXR0b24ge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGZsZXg6IDEgMCBhdXRvO1xuICAgICAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgICBoZWlnaHQ6IDU1cHg7XG4gICAgICBsaW5lLWhlaWdodDogMzJweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICBtYXgtd2lkdGg6IDE2MnB4O1xuICAgICAgbWFyZ2luOiAxMnB4O1xuICAgIH1cblxuICAgICZfX2NhbmNlbC1idXR0b24ge1xuICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICRkdXN0eS1ncmF5O1xuICAgICAgbWFyZ2luLXJpZ2h0OiA2cHg7XG4gICAgfVxuXG4gICAgJl9fc2lnbi1idXR0b24ge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNhcmliYmVhbi1ncmVlbjtcbiAgICAgIGJvcmRlci13aWR0aDogMDtcbiAgICAgIGNvbG9yOiAkd2hpdGU7XG4gICAgICBtYXJnaW4tbGVmdDogNnB4O1xuICAgIH1cbiAgfVxufSIsIi5hY2NvdW50LWRyb3Bkb3duLW1pbmkge1xuICBoZWlnaHQ6IDIycHg7XG4gIGJhY2tncm91bmQtY29sb3I6ICR3aGl0ZTtcbiAgZm9udC1mYW1pbHk6IFJvYm90bztcbiAgbGluZS1oZWlnaHQ6IDE2cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgd2lkdGg6IDEyNHB4O1xuXG4gICZfX2Nsb3NlLWFyZWEge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDA7XG4gICAgbGVmdDogMDtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgfVxuXG4gICZfX2xpc3Qge1xuICAgIHotaW5kZXg6IDEwNTA7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGhlaWdodDogMTgwcHg7XG4gICAgd2lkdGg6IDk2cHhweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAkZ2V5c2VyO1xuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkd2hpdGU7XG4gICAgYm94LXNoYWRvdzogMCAzcHggNnB4IDAgcmdiYSgwICwwICwwICwuMTEpO1xuICAgIG92ZXJmbG93LXk6IHNjcm9sbDtcbiAgfVxuXG4gIC5hY2NvdW50LWxpc3QtaXRlbSB7XG4gICAgbWFyZ2luLXRvcDogNnB4O1xuICB9XG5cbiAgLmFjY291bnQtbGlzdC1pdGVtX19hY2NvdW50LW5hbWUge1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB3aWR0aDogODBweDtcbiAgfVxuXG4gIC5hY2NvdW50LWxpc3QtaXRlbV9fdG9wLXJvdyB7XG4gICAgbWFyZ2luOiAwO1xuICB9XG5cbiAgLmFjY291bnQtbGlzdC1pdGVtX19pY29uIHtcbiAgICBwb3NpdGlvbjogaW5pdGlhbDtcbiAgfVxufSIsIi5lZGl0YWJsZS1sYWJlbCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG5cbiAgJl9fdmFsdWUge1xuICAgIG1heC13aWR0aDogMjUwcHg7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB9XG5cbiAgJl9faW5wdXQge1xuICAgIHdpZHRoOiAyNTBweDtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICRhbHRvO1xuXG4gICAgJi0tZXJyb3Ige1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgJG1vbnpvO1xuICAgIH1cbiAgfVxuXG4gICZfX2ljb24td3JhcHBlciB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIG1hcmdpbi1sZWZ0OiAxMHB4O1xuICAgIGxlZnQ6IDEwMCU7XG4gIH1cblxuICAmX19pY29uIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgY29sb3I6ICRkdXN0eS1ncmF5O1xuICB9XG59XG4iLCIvKlxuICBUcnVtcHNcbiAqL1xuXG4vLyBUcmFuc2l0aW9uc1xuXG4vKiB1bml2ZXJzYWwgKi9cbi5hcHAtcHJpbWFyeSAubWFpbi1lbnRlciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgd2lkdGg6IDEwMCU7XG59XG5cbi8qIGNlbnRlciBwb3NpdGlvbiAqL1xuLmFwcC1wcmltYXJ5LmZyb20tcmlnaHQgLm1haW4tZW50ZXItYWN0aXZlLFxuLmFwcC1wcmltYXJ5LmZyb20tbGVmdCAubWFpbi1lbnRlci1hY3RpdmUge1xuICBvdmVyZmxvdy14OiBoaWRkZW47XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDMwMG1zIGVhc2UtaW47XG59XG5cbi8qIGV4aXRlZCBwb3NpdGlvbnMgKi9cbi5hcHAtcHJpbWFyeS5mcm9tLWxlZnQgLm1haW4tbGVhdmUtYWN0aXZlIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDM2MHB4KTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDMwMG1zIGVhc2UtaW47XG59XG5cbi5hcHAtcHJpbWFyeS5mcm9tLXJpZ2h0IC5tYWluLWxlYXZlLWFjdGl2ZSB7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMzYwcHgpO1xuICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMzAwbXMgZWFzZS1pbjtcbn1cblxuLnNpZGViYXIuZnJvbS1sZWZ0IHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0zMjBweCk7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAzMDBtcyBlYXNlLWluO1xufVxuXG4vKiBsb2FkZXIgdHJhbnNpdGlvbnMgKi9cbi5sb2FkZXItZW50ZXIsXG4ubG9hZGVyLWxlYXZlLWFjdGl2ZSB7XG4gIG9wYWNpdHk6IDA7XG4gIHRyYW5zaXRpb246IG9wYWNpdHkgMTUwIGVhc2UtaW47XG59XG5cbi5sb2FkZXItZW50ZXItYWN0aXZlLFxuLmxvYWRlci1sZWF2ZSB7XG4gIG9wYWNpdHk6IDE7XG4gIHRyYW5zaXRpb246IG9wYWNpdHkgMTUwIGVhc2UtaW47XG59XG5cbi8qIGVudGVyaW5nIHBvc2l0aW9ucyAqL1xuLmFwcC1wcmltYXJ5LmZyb20tcmlnaHQgLm1haW4tZW50ZXI6bm90KC5tYWluLWVudGVyLWFjdGl2ZSkge1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMzYwcHgpO1xufVxuXG4uYXBwLXByaW1hcnkuZnJvbS1sZWZ0IC5tYWluLWVudGVyOm5vdCgubWFpbi1lbnRlci1hY3RpdmUpIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0zNjBweCk7XG59XG5cbmkuZmEuZmEtcXVlc3Rpb24tY2lyY2xlLmZhLWxnLm1lbnUtaWNvbiB7XG4gIGZvbnQtc2l6ZTogMThweDtcbn1cblxuLy8gVGhpcyB0ZXh0IGlzIGNvbnRhaW5lZCBpbnNpZGUgYSBkaXYuXG4vLyBJRCBuZWVkZWQgdG8gb3ZlcnJpZGUgdXNlciBhZ2VudCBzdHlsZXNoZWV0LlxuLy8gU2VlIGNvbXBvbmVudHMvbW9kYWwuc2Nzc1xuXG4vKiBzdHlsZWxpbnQtZGlzYWJsZSAqL1xuI2J1eS1tb2RhbC1jb250ZW50LWZvb3Rlci10ZXh0IHtcbiAgZm9udC1mYW1pbHk6ICdESU4gT1QnO1xuICBmb250LXNpemU6IDE2cHg7XG59XG4vKiBzdHlsZWxpbnQtZW5hYmxlICovXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7OztHQUtHO0FFTEg7O0dBRUc7QUFTSDs7O0dBR0c7QUErQkg7O0dBRUc7QUFXSDs7Ozs7OztHQU9HO0FBRUg7O0dBRUc7QUNyRUgs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QUc7QUFDSCxBQUFBLElBQUk7QUFDSixBQUFBLE1BQU07QUFDTixBQUFBLE1BQU07QUFDTixBQUFBLE1BQU07QUFDTixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLENBQUM7QUFDRCxBQUFBLFVBQVU7QUFDVixBQUFBLEdBQUc7QUFDSCxBQUFBLENBQUM7QUFDRCxBQUFBLElBQUk7QUFDSixBQUFBLE9BQU87QUFDUCxBQUFBLE9BQU87QUFDUCxBQUFBLEdBQUc7QUFDSCxBQUFBLElBQUk7QUFDSixBQUFBLElBQUk7QUFDSixBQUFBLEdBQUc7QUFDSCxBQUFBLEdBQUc7QUFDSCxBQUFBLEVBQUU7QUFDRixBQUFBLEdBQUc7QUFDSCxBQUFBLEdBQUc7QUFDSCxBQUFBLEdBQUc7QUFDSCxBQUFBLENBQUM7QUFDRCxBQUFBLENBQUM7QUFDRCxBQUFBLElBQUk7QUFDSixBQUFBLEtBQUs7QUFDTCxBQUFBLE1BQU07QUFDTixBQUFBLE1BQU07QUFDTixBQUFBLEdBQUc7QUFDSCxBQUFBLEdBQUc7QUFDSCxBQUFBLEVBQUU7QUFDRixBQUFBLEdBQUc7QUFDSCxBQUFBLENBQUM7QUFDRCxBQUFBLENBQUM7QUFDRCxBQUFBLENBQUM7QUFDRCxBQUFBLE1BQU07QUFDTixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLFFBQVE7QUFDUixBQUFBLElBQUk7QUFDSixBQUFBLEtBQUs7QUFDTCxBQUFBLE1BQU07QUFDTixBQUFBLEtBQUs7QUFDTCxBQUFBLE9BQU87QUFDUCxBQUFBLEtBQUs7QUFDTCxBQUFBLEtBQUs7QUFDTCxBQUFBLEtBQUs7QUFDTCxBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLEVBQUU7QUFDRixBQUFBLE9BQU87QUFDUCxBQUFBLEtB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 */
diff --git a/ui/app/css/reset.css b/old-ui/app/css/reset.css
index 9ce89e8bc..9ce89e8bc 100644
--- a/ui/app/css/reset.css
+++ b/old-ui/app/css/reset.css
diff --git a/ui/app/css/transitions.css b/old-ui/app/css/transitions.css
index 393a944f9..393a944f9 100644
--- a/ui/app/css/transitions.css
+++ b/old-ui/app/css/transitions.css
diff --git a/old-ui/app/first-time/init-menu.js b/old-ui/app/first-time/init-menu.js
new file mode 100644
index 000000000..4f1d5d186
--- /dev/null
+++ b/old-ui/app/first-time/init-menu.js
@@ -0,0 +1,179 @@
+const inherits = require('util').inherits
+const EventEmitter = require('events').EventEmitter
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const Mascot = require('../components/mascot')
+const actions = require('../../../ui/app/actions')
+const Tooltip = require('../components/tooltip')
+const getCaretCoordinates = require('textarea-caret')
+
+module.exports = connect(mapStateToProps)(InitializeMenuScreen)
+
+inherits(InitializeMenuScreen, Component)
+function InitializeMenuScreen () {
+ Component.call(this)
+ this.animationEventEmitter = new EventEmitter()
+}
+
+function mapStateToProps (state) {
+ return {
+ // state from plugin
+ currentView: state.appState.currentView,
+ warning: state.appState.warning,
+ }
+}
+
+InitializeMenuScreen.prototype.render = function () {
+ var state = this.props
+
+ switch (state.currentView.name) {
+
+ default:
+ return this.renderMenu(state)
+
+ }
+}
+
+// InitializeMenuScreen.prototype.componentDidMount = function(){
+// document.getElementById('password-box').focus()
+// }
+
+InitializeMenuScreen.prototype.renderMenu = function (state) {
+ return (
+
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
+
+ h('h1', {
+ style: {
+ fontSize: '1.3em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ marginBottom: 10,
+ },
+ }, 'MetaMask'),
+
+
+ h('div', [
+ h('h3', {
+ style: {
+ fontSize: '0.8em',
+ color: '#7F8082',
+ display: 'inline',
+ },
+ }, 'Encrypt your new DEN'),
+
+ h(Tooltip, {
+ title: 'Your DEN is your password-encrypted storage within MetaMask.',
+ }, [
+ h('i.fa.fa-question-circle.pointer', {
+ style: {
+ fontSize: '18px',
+ position: 'relative',
+ color: 'rgb(247, 134, 28)',
+ top: '2px',
+ marginLeft: '4px',
+ },
+ }),
+ ]),
+ ]),
+
+ h('span.in-progress-notification', state.warning),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'New Password (min 8 chars)',
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: 'Confirm Password',
+ onKeyPress: this.createVaultOnEnter.bind(this),
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
+
+
+ h('button.primary', {
+ onClick: this.createNewVaultAndKeychain.bind(this),
+ style: {
+ margin: 12,
+ },
+ }, 'Create'),
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showRestoreVault.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'Import Existing DEN'),
+ ]),
+
+ ])
+ )
+}
+
+InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewVaultAndKeychain()
+ }
+}
+
+InitializeMenuScreen.prototype.componentDidMount = function () {
+ document.getElementById('password-box').focus()
+}
+
+InitializeMenuScreen.prototype.showRestoreVault = function () {
+ this.props.dispatch(actions.showRestoreVault())
+}
+
+InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+
+ if (password.length < 8) {
+ this.warning = 'password not long enough'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+ if (password !== passwordConfirm) {
+ this.warning = 'passwords don\'t match'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+
+ this.props.dispatch(actions.createNewVaultAndKeychain(password))
+}
+
+InitializeMenuScreen.prototype.inputChanged = function (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+}
diff --git a/old-ui/app/img/identicon-tardigrade.png b/old-ui/app/img/identicon-tardigrade.png
new file mode 100644
index 000000000..1742a32b8
--- /dev/null
+++ b/old-ui/app/img/identicon-tardigrade.png
Binary files differ
diff --git a/old-ui/app/img/identicon-walrus.png b/old-ui/app/img/identicon-walrus.png
new file mode 100644
index 000000000..d58fae912
--- /dev/null
+++ b/old-ui/app/img/identicon-walrus.png
Binary files differ
diff --git a/old-ui/app/info.js b/old-ui/app/info.js
new file mode 100644
index 000000000..db9f30f23
--- /dev/null
+++ b/old-ui/app/info.js
@@ -0,0 +1,155 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(InfoScreen)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(InfoScreen, Component)
+function InfoScreen () {
+ Component.call(this)
+}
+
+InfoScreen.prototype.render = function () {
+ const state = this.props
+ const version = global.platform.getVersion()
+
+ return (
+ h('.flex-column.flex-grow', {
+ style: {
+ maxWidth: '400px',
+ },
+ }, [
+
+ // subtitle and nav
+ h('.section-title.flex-row.flex-center', [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: (event) => {
+ state.dispatch(actions.goHome())
+ },
+ }),
+ h('h2.page-subtitle', 'Info'),
+ ]),
+
+ // main view
+ h('.flex-column.flex-justify-center.flex-grow.select-none', [
+ h('.flex-space-around', {
+ style: {
+ padding: '20px',
+ },
+ }, [
+ // current version number
+
+ h('.info.info-gray', [
+ h('div', 'Metamask'),
+ h('div', {
+ style: {
+ marginBottom: '10px',
+ },
+ }, `Version: ${version}`),
+ ]),
+
+ h('div', {
+ style: {
+ marginBottom: '5px',
+ }},
+ [
+ h('div', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ onClick (event) { this.navigateTo(event.target.href) },
+ }, [
+ h('div.info', 'Privacy Policy'),
+ ]),
+ ]),
+ h('div', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
+ onClick (event) { this.navigateTo(event.target.href) },
+ }, [
+ h('div.info', 'Terms of Use'),
+ ]),
+ ]),
+ h('div', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ onClick (event) { this.navigateTo(event.target.href) },
+ }, [
+ h('div.info', 'Attributions'),
+ ]),
+ ]),
+ ]
+ ),
+
+ h('hr', {
+ style: {
+ margin: '10px 0 ',
+ width: '7em',
+ },
+ }),
+
+ h('div', {
+ style: {
+ paddingLeft: '30px',
+ }},
+ [
+ h('div.fa.fa-support', [
+ h('a.info', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, 'Visit our Support Center'),
+ ]),
+
+ h('div', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('img.icon-size', {
+ src: 'images/icon-128.png',
+ style: {
+ // IE6-9
+ filter: 'grayscale(100%)',
+ // Microsoft Edge and Firefox 35+
+ WebkitFilter: 'grayscale(100%)',
+ },
+ }),
+ h('div.info', 'Visit our web site'),
+ ]),
+ ]),
+
+ h('div', [
+ h('.fa.fa-twitter', [
+ h('a.info', {
+ href: 'https://twitter.com/metamask_io',
+ target: '_blank',
+ }, 'Follow us on Twitter'),
+ ]),
+ ]),
+
+ h('div.fa.fa-envelope', [
+ h('a.info', {
+ target: '_blank',
+ style: { width: '85vw' },
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, 'Email us!'),
+ ]),
+ ]),
+ ]),
+ ]),
+ ])
+ )
+}
+
+InfoScreen.prototype.navigateTo = function (url) {
+ global.platform.openWindow({ url })
+}
+
diff --git a/old-ui/app/infura-conversion.json b/old-ui/app/infura-conversion.json
new file mode 100644
index 000000000..9a96fe069
--- /dev/null
+++ b/old-ui/app/infura-conversion.json
@@ -0,0 +1,653 @@
+{
+ "objects": [
+ {
+ "symbol": "ethaud",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "aud",
+ "name": "Australian Dollar"
+ }
+ },
+ {
+ "symbol": "ethhkd",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "hkd",
+ "name": "Hong Kong Dollar"
+ }
+ },
+ {
+ "symbol": "ethsgd",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "sgd",
+ "name": "Singapore Dollar"
+ }
+ },
+ {
+ "symbol": "ethidr",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "idr",
+ "name": "Indonesian Rupiah"
+ }
+ },
+ {
+ "symbol": "ethphp",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "php",
+ "name": "Philippine Peso"
+ }
+ },
+ {
+ "symbol": "eth1st",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "1st",
+ "name": "FirstBlood"
+ }
+ },
+ {
+ "symbol": "ethadt",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "adt",
+ "name": "adToken"
+ }
+ },
+ {
+ "symbol": "ethadx",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "adx",
+ "name": "AdEx"
+ }
+ },
+ {
+ "symbol": "ethant",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "ant",
+ "name": "Aragon"
+ }
+ },
+ {
+ "symbol": "ethbat",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "bat",
+ "name": "Basic Attention Token"
+ }
+ },
+ {
+ "symbol": "ethbnt",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "bnt",
+ "name": "Bancor"
+ }
+ },
+ {
+ "symbol": "ethbtc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "btc",
+ "name": "Bitcoin"
+ }
+ },
+ {
+ "symbol": "ethcad",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "cad",
+ "name": "Canadian Dollar"
+ }
+ },
+ {
+ "symbol": "ethcfi",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "cfi",
+ "name": "Cofound.it"
+ }
+ },
+ {
+ "symbol": "ethcrb",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "crb",
+ "name": "CreditBit"
+ }
+ },
+ {
+ "symbol": "ethcvc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "cvc",
+ "name": "Civic"
+ }
+ },
+ {
+ "symbol": "ethdash",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "dash",
+ "name": "Dash"
+ }
+ },
+ {
+ "symbol": "ethdgd",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "dgd",
+ "name": "DigixDAO"
+ }
+ },
+ {
+ "symbol": "ethetc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "etc",
+ "name": "Ethereum Classic"
+ }
+ },
+ {
+ "symbol": "etheur",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "eur",
+ "name": "Euro"
+ }
+ },
+ {
+ "symbol": "ethfun",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "fun",
+ "name": "FunFair"
+ }
+ },
+ {
+ "symbol": "ethgbp",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "gbp",
+ "name": "Pound Sterling"
+ }
+ },
+ {
+ "symbol": "ethgno",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "gno",
+ "name": "Gnosis"
+ }
+ },
+ {
+ "symbol": "ethgnt",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "gnt",
+ "name": "Golem"
+ }
+ },
+ {
+ "symbol": "ethgup",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "gup",
+ "name": "Matchpool"
+ }
+ },
+ {
+ "symbol": "ethhmq",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "hmq",
+ "name": "Humaniq"
+ }
+ },
+ {
+ "symbol": "ethjpy",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "jpy",
+ "name": "Japanese Yen"
+ }
+ },
+ {
+ "symbol": "ethlgd",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "lgd",
+ "name": "Legends Room"
+ }
+ },
+ {
+ "symbol": "ethlsk",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "lsk",
+ "name": "Lisk"
+ }
+ },
+ {
+ "symbol": "ethltc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "ltc",
+ "name": "Litecoin"
+ }
+ },
+ {
+ "symbol": "ethlun",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "lun",
+ "name": "Lunyr"
+ }
+ },
+ {
+ "symbol": "ethmco",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "mco",
+ "name": "Monaco"
+ }
+ },
+ {
+ "symbol": "ethmtl",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "mtl",
+ "name": "Metal"
+ }
+ },
+ {
+ "symbol": "ethmyst",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "myst",
+ "name": "Mysterium"
+ }
+ },
+ {
+ "symbol": "ethnmr",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "nmr",
+ "name": "Numeraire"
+ }
+ },
+ {
+ "symbol": "ethomg",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "omg",
+ "name": "OmiseGO"
+ }
+ },
+ {
+ "symbol": "ethpay",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "pay",
+ "name": "TenX"
+ }
+ },
+ {
+ "symbol": "ethptoy",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "ptoy",
+ "name": "Patientory"
+ }
+ },
+ {
+ "symbol": "ethqrl",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "qrl",
+ "name": "Quantum-Resistant Ledger"
+ }
+ },
+ {
+ "symbol": "ethqtum",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "qtum",
+ "name": "Qtum"
+ }
+ },
+ {
+ "symbol": "ethrep",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "rep",
+ "name": "Augur"
+ }
+ },
+ {
+ "symbol": "ethrlc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "rlc",
+ "name": "iEx.ec"
+ }
+ },
+ {
+ "symbol": "ethrub",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "rub",
+ "name": "Russian Ruble"
+ }
+ },
+ {
+ "symbol": "ethsc",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "sc",
+ "name": "Siacoin"
+ }
+ },
+ {
+ "symbol": "ethsngls",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "sngls",
+ "name": "SingularDTV"
+ }
+ },
+ {
+ "symbol": "ethsnt",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "snt",
+ "name": "Status"
+ }
+ },
+ {
+ "symbol": "ethsteem",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "steem",
+ "name": "Steem"
+ }
+ },
+ {
+ "symbol": "ethstorj",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "storj",
+ "name": "Storj"
+ }
+ },
+ {
+ "symbol": "ethtime",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "time",
+ "name": "ChronoBank"
+ }
+ },
+ {
+ "symbol": "ethtkn",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "tkn",
+ "name": "TokenCard"
+ }
+ },
+ {
+ "symbol": "ethtrst",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "trst",
+ "name": "WeTrust"
+ }
+ },
+ {
+ "symbol": "ethuah",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "uah",
+ "name": "Ukrainian Hryvnia"
+ }
+ },
+ {
+ "symbol": "ethusd",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "usd",
+ "name": "United States Dollar"
+ }
+ },
+ {
+ "symbol": "ethwings",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "wings",
+ "name": "Wings"
+ }
+ },
+ {
+ "symbol": "ethxem",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "xem",
+ "name": "NEM"
+ }
+ },
+ {
+ "symbol": "ethxlm",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "xlm",
+ "name": "Stellar Lumen"
+ }
+ },
+ {
+ "symbol": "ethxmr",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "xmr",
+ "name": "Monero"
+ }
+ },
+ {
+ "symbol": "ethxrp",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "xrp",
+ "name": "Ripple"
+ }
+ },
+ {
+ "symbol": "ethzec",
+ "base": {
+ "code": "eth",
+ "name": "Ethereum"
+ },
+ "quote": {
+ "code": "zec",
+ "name": "Zcash"
+ }
+ }
+ ]
+}
diff --git a/old-ui/app/keychains/hd/create-vault-complete.js b/old-ui/app/keychains/hd/create-vault-complete.js
new file mode 100644
index 000000000..736e922b7
--- /dev/null
+++ b/old-ui/app/keychains/hd/create-vault-complete.js
@@ -0,0 +1,91 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const actions = require('../../../../ui/app/actions')
+const exportAsFile = require('../../util').exportAsFile
+
+module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
+
+inherits(CreateVaultCompleteScreen, Component)
+function CreateVaultCompleteScreen () {
+ Component.call(this)
+}
+
+function mapStateToProps (state) {
+ return {
+ seed: state.appState.currentView.seedWords,
+ cachedSeed: state.metamask.seedWords,
+ }
+}
+
+CreateVaultCompleteScreen.prototype.render = function () {
+ var state = this.props
+ var seed = state.seed || state.cachedSeed || ''
+
+ return (
+
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ // // subtitle and nav
+ // h('.section-title.flex-row.flex-center', [
+ // h('h2.page-subtitle', 'Vault Created'),
+ // ]),
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginTop: 36,
+ marginBottom: 8,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Vault Created',
+ ]),
+
+ h('div', {
+ style: {
+ fontSize: '1em',
+ marginTop: '10px',
+ textAlign: 'center',
+ },
+ }, [
+ h('span.error', 'These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret.'),
+ ]),
+
+ h('textarea.twelve-word-phrase', {
+ readOnly: true,
+ value: seed,
+ }),
+
+ h('button.primary', {
+ onClick: () => this.confirmSeedWords()
+ .then(account => this.showAccountDetail(account)),
+ style: {
+ margin: '24px',
+ fontSize: '0.9em',
+ marginBottom: '10px',
+ },
+ }, 'I\'ve copied it somewhere safe'),
+
+ h('button.primary', {
+ onClick: () => exportAsFile(`MetaMask Seed Words`, seed),
+ style: {
+ margin: '10px',
+ fontSize: '0.9em',
+ },
+ }, 'Save Seed Words As File'),
+ ])
+ )
+}
+
+CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
+ return this.props.dispatch(actions.confirmSeedWords())
+}
+
+CreateVaultCompleteScreen.prototype.showAccountDetail = function (account) {
+ return this.props.dispatch(actions.showAccountDetail(account))
+}
diff --git a/old-ui/app/keychains/hd/recover-seed/confirmation.js b/old-ui/app/keychains/hd/recover-seed/confirmation.js
new file mode 100644
index 000000000..eb0298a09
--- /dev/null
+++ b/old-ui/app/keychains/hd/recover-seed/confirmation.js
@@ -0,0 +1,121 @@
+const inherits = require('util').inherits
+
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const actions = require('../../../../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
+
+inherits(RevealSeedConfirmation, Component)
+function RevealSeedConfirmation () {
+ Component.call(this)
+}
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ }
+}
+
+RevealSeedConfirmation.prototype.render = function () {
+ const props = this.props
+
+ return (
+
+ h('.initialize-screen.flex-column.flex-center.flex-grow', {
+ style: { maxWidth: '420px' },
+ }, [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Reveal Seed Words',
+ ]),
+
+ h('.div', {
+ style: {
+ display: 'flex',
+ flexDirection: 'column',
+ padding: '20px',
+ justifyContent: 'center',
+ },
+ }, [
+
+ h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
+
+ // confirmation
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'Enter your password to confirm',
+ onKeyPress: this.checkConfirmation.bind(this),
+ style: {
+ width: 260,
+ marginTop: '12px',
+ },
+ }),
+
+ h('.flex-row.flex-start', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+ // cancel
+ h('button.primary', {
+ onClick: this.goHome.bind(this),
+ }, 'CANCEL'),
+
+ // submit
+ h('button.primary', {
+ style: { marginLeft: '10px' },
+ onClick: this.revealSeedWords.bind(this),
+ }, 'OK'),
+
+ ]),
+
+ (props.warning) && (
+ h('span.error', {
+ style: {
+ margin: '20px',
+ },
+ }, props.warning.split('-'))
+ ),
+
+ props.inProgress && (
+ h('span.in-progress-notification', 'Generating Seed...')
+ ),
+ ]),
+ ])
+ )
+}
+
+RevealSeedConfirmation.prototype.componentDidMount = function () {
+ document.getElementById('password-box').focus()
+}
+
+RevealSeedConfirmation.prototype.goHome = function () {
+ this.props.dispatch(actions.showConfigPage(false))
+}
+
+// create vault
+
+RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.revealSeedWords()
+ }
+}
+
+RevealSeedConfirmation.prototype.revealSeedWords = function () {
+ var password = document.getElementById('password-box').value
+ this.props.dispatch(actions.requestRevealSeed(password))
+}
diff --git a/old-ui/app/keychains/hd/restore-vault.js b/old-ui/app/keychains/hd/restore-vault.js
new file mode 100644
index 000000000..222172dfd
--- /dev/null
+++ b/old-ui/app/keychains/hd/restore-vault.js
@@ -0,0 +1,152 @@
+const inherits = require('util').inherits
+const PersistentForm = require('../../../lib/persistent-form')
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const actions = require('../../../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(RestoreVaultScreen)
+
+inherits(RestoreVaultScreen, PersistentForm)
+function RestoreVaultScreen () {
+ PersistentForm.call(this)
+}
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ forgottenPassword: state.appState.forgottenPassword,
+ }
+}
+
+RestoreVaultScreen.prototype.render = function () {
+ var state = this.props
+ this.persistentFormParentId = 'restore-vault-form'
+
+ return (
+
+ h('.initialize-screen.flex-column.flex-center.flex-grow', [
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ padding: 6,
+ },
+ }, [
+ 'Restore Vault',
+ ]),
+
+ // wallet seed entry
+ h('h3', 'Wallet Seed'),
+ h('textarea.twelve-word-phrase.letter-spacey', {
+ dataset: {
+ persistentFormId: 'wallet-seed',
+ },
+ placeholder: 'Enter your secret twelve word phrase here to restore your vault.',
+ }),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'New Password (min 8 chars)',
+ dataset: {
+ persistentFormId: 'password',
+ },
+ style: {
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: 'Confirm Password',
+ onKeyPress: this.createOnEnter.bind(this),
+ dataset: {
+ persistentFormId: 'password-confirmation',
+ },
+ style: {
+ width: 260,
+ marginTop: 16,
+ },
+ }),
+
+ (state.warning) && (
+ h('span.error.in-progress-notification', state.warning)
+ ),
+
+ // submit
+
+ h('.flex-row.flex-space-between', {
+ style: {
+ marginTop: 30,
+ width: '50%',
+ },
+ }, [
+
+ // cancel
+ h('button.primary', {
+ onClick: this.showInitializeMenu.bind(this),
+ }, 'CANCEL'),
+
+ // submit
+ h('button.primary', {
+ onClick: this.createNewVaultAndRestore.bind(this),
+ }, 'OK'),
+
+ ]),
+ ])
+
+ )
+}
+
+RestoreVaultScreen.prototype.showInitializeMenu = function () {
+ if (this.props.forgottenPassword) {
+ this.props.dispatch(actions.backToUnlockView())
+ } else {
+ this.props.dispatch(actions.showInitializeMenu())
+ }
+}
+
+RestoreVaultScreen.prototype.createOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ this.createNewVaultAndRestore()
+ }
+}
+
+RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
+ // check password
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+ if (password.length < 8) {
+ this.warning = 'Password not long enough'
+
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+ if (password !== passwordConfirm) {
+ this.warning = 'Passwords don\'t match'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+ // check seed
+ var seedBox = document.querySelector('textarea.twelve-word-phrase')
+ var seed = seedBox.value.trim()
+ if (seed.split(' ').length !== 12) {
+ this.warning = 'seed phrases are 12 words long'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+ // submit
+ this.warning = null
+ this.props.dispatch(actions.displayWarning(this.warning))
+ this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
+}
diff --git a/old-ui/app/new-keychain.js b/old-ui/app/new-keychain.js
new file mode 100644
index 000000000..cc9633166
--- /dev/null
+++ b/old-ui/app/new-keychain.js
@@ -0,0 +1,29 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+
+module.exports = connect(mapStateToProps)(NewKeychain)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(NewKeychain, Component)
+function NewKeychain () {
+ Component.call(this)
+}
+
+NewKeychain.prototype.render = function () {
+ // const props = this.props
+
+ return (
+ h('div', {
+ style: {
+ background: 'blue',
+ },
+ }, [
+ h('h1', `Here's a list!!!!`),
+ ])
+ )
+}
diff --git a/old-ui/app/send.js b/old-ui/app/send.js
new file mode 100644
index 000000000..b40910236
--- /dev/null
+++ b/old-ui/app/send.js
@@ -0,0 +1,309 @@
+const inherits = require('util').inherits
+const PersistentForm = require('../lib/persistent-form')
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const Identicon = require('./components/identicon')
+const actions = require('../../ui/app/actions')
+const util = require('./util')
+const numericBalance = require('./util').numericBalance
+const addressSummary = require('./util').addressSummary
+const isHex = require('./util').isHex
+const EthBalance = require('./components/eth-balance')
+const EnsInput = require('./components/ens-input')
+const ethUtil = require('ethereumjs-util')
+module.exports = connect(mapStateToProps)(SendTransactionScreen)
+
+function mapStateToProps (state) {
+ var result = {
+ address: state.metamask.selectedAddress,
+ accounts: state.metamask.accounts,
+ identities: state.metamask.identities,
+ warning: state.appState.warning,
+ network: state.metamask.network,
+ addressBook: state.metamask.addressBook,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ }
+
+ result.error = result.warning && result.warning.split('.')[0]
+
+ result.account = result.accounts[result.address]
+ result.identity = result.identities[result.address]
+ result.balance = result.account ? numericBalance(result.account.balance) : null
+
+ return result
+}
+
+inherits(SendTransactionScreen, PersistentForm)
+function SendTransactionScreen () {
+ PersistentForm.call(this)
+}
+
+SendTransactionScreen.prototype.render = function () {
+ this.persistentFormParentId = 'send-tx-form'
+
+ const props = this.props
+ const {
+ address,
+ account,
+ identity,
+ network,
+ identities,
+ addressBook,
+ conversionRate,
+ currentCurrency,
+ } = props
+
+ return (
+
+ h('.send-screen.flex-column.flex-grow', [
+
+ //
+ // Sender Profile
+ //
+
+ h('.account-data-subsection.flex-row.flex-grow', {
+ style: {
+ margin: '0 20px',
+ },
+ }, [
+
+ // header - identicon + nav
+ h('.flex-row.flex-space-between', {
+ style: {
+ marginTop: '15px',
+ },
+ }, [
+ // back button
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
+ onClick: this.back.bind(this),
+ }),
+
+ // large identicon
+ h('.identicon-wrapper.flex-column.flex-center.select-none', [
+ h(Identicon, {
+ diameter: 62,
+ address: address,
+ }),
+ ]),
+
+ // invisible place holder
+ h('i.fa.fa-users.fa-lg.invisible', {
+ style: {
+ marginTop: '28px',
+ },
+ }),
+
+ ]),
+
+ // account label
+
+ h('.flex-column', {
+ style: {
+ marginTop: '10px',
+ alignItems: 'flex-start',
+ },
+ }, [
+ h('h2.font-medium.color-forest.flex-center', {
+ style: {
+ paddingTop: '8px',
+ marginBottom: '8px',
+ },
+ }, identity && identity.name),
+
+ // address and getter actions
+ h('.flex-row.flex-center', {
+ style: {
+ marginBottom: '8px',
+ },
+ }, [
+
+ h('div', {
+ style: {
+ lineHeight: '16px',
+ },
+ }, addressSummary(address)),
+
+ ]),
+
+ // balance
+ h('.flex-row.flex-center', [
+
+ h(EthBalance, {
+ value: account && account.balance,
+ conversionRate,
+ currentCurrency,
+ }),
+
+ ]),
+ ]),
+ ]),
+
+ //
+ // Required Fields
+ //
+
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginTop: '15px',
+ marginBottom: '16px',
+ },
+ }, [
+ 'Send Transaction',
+ ]),
+
+ // error message
+ props.error && h('span.error.flex-center', props.error),
+
+ // 'to' field
+ h('section.flex-row.flex-center', [
+ h(EnsInput, {
+ name: 'address',
+ placeholder: 'Recipient Address',
+ onChange: this.recipientDidChange.bind(this),
+ network,
+ identities,
+ addressBook,
+ }),
+ ]),
+
+ // 'amount' and send button
+ h('section.flex-row.flex-center', [
+
+ h('input.large-input', {
+ name: 'amount',
+ placeholder: 'Amount',
+ type: 'number',
+ style: {
+ marginRight: '6px',
+ },
+ dataset: {
+ persistentFormId: 'tx-amount',
+ },
+ }),
+
+ h('button.primary', {
+ onClick: this.onSubmit.bind(this),
+ style: {
+ textTransform: 'uppercase',
+ },
+ }, 'Next'),
+
+ ]),
+
+ //
+ // Optional Fields
+ //
+ h('h3.flex-center.text-transform-uppercase', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginTop: '16px',
+ marginBottom: '16px',
+ },
+ }, [
+ 'Transaction Data (optional)',
+ ]),
+
+ // 'data' field
+ h('section.flex-column.flex-center', [
+ h('input.large-input', {
+ name: 'txData',
+ placeholder: '0x01234',
+ style: {
+ width: '100%',
+ resize: 'none',
+ },
+ dataset: {
+ persistentFormId: 'tx-data',
+ },
+ }),
+ ]),
+ ])
+ )
+}
+
+SendTransactionScreen.prototype.navigateToAccounts = function (event) {
+ event.stopPropagation()
+ this.props.dispatch(actions.showAccountsPage())
+}
+
+SendTransactionScreen.prototype.back = function () {
+ var address = this.props.address
+ this.props.dispatch(actions.backToAccountDetail(address))
+}
+
+SendTransactionScreen.prototype.recipientDidChange = function (recipient, nickname) {
+ this.setState({
+ recipient: recipient,
+ nickname: nickname,
+ })
+}
+
+SendTransactionScreen.prototype.onSubmit = function () {
+ const state = this.state || {}
+ const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '')
+ const nickname = state.nickname || ' '
+ const input = document.querySelector('input[name="amount"]').value
+ const parts = input.split('')
+
+ let message
+
+ if (isNaN(input) || input === '') {
+ message = 'Invalid ether value.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ if (parts[1]) {
+ var decimal = parts[1]
+ if (decimal.length > 18) {
+ message = 'Ether amount is too precise.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+ }
+
+ const value = util.normalizeEthStringToWei(input)
+ const txData = document.querySelector('input[name="txData"]').value
+ const balance = this.props.balance
+
+ if (value.gt(balance)) {
+ message = 'Insufficient funds.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ if (input < 0) {
+ message = 'Can not send negative amounts of ETH.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ if ((util.isInvalidChecksumAddress(recipient))) {
+ message = 'Recipient address checksum is invalid.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) {
+ message = 'Recipient address is invalid.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ if (!isHex(ethUtil.stripHexPrefix(txData)) && txData) {
+ message = 'Transaction data must be hex string.'
+ return this.props.dispatch(actions.displayWarning(message))
+ }
+
+ this.props.dispatch(actions.hideWarning())
+
+ this.props.dispatch(actions.addToAddressBook(recipient, nickname))
+
+ var txParams = {
+ from: this.props.address,
+ value: '0x' + value.toString(16),
+ }
+
+ if (recipient) txParams.to = ethUtil.addHexPrefix(recipient)
+ if (txData) txParams.data = txData
+
+ this.props.dispatch(actions.signTx(txParams))
+}
diff --git a/old-ui/app/settings.js b/old-ui/app/settings.js
new file mode 100644
index 000000000..8df37c555
--- /dev/null
+++ b/old-ui/app/settings.js
@@ -0,0 +1,59 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+
+module.exports = connect(mapStateToProps)(AppSettingsPage)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(AppSettingsPage, Component)
+function AppSettingsPage () {
+ Component.call(this)
+}
+
+AppSettingsPage.prototype.render = function () {
+ return (
+
+ h('.account-detail-section.flex-column.flex-grow', [
+
+ // subtitle and nav
+ h('.flex-row.flex-center', [
+ h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: this.navigateToAccounts.bind(this),
+ }),
+ h('h2.page-subtitle', 'Settings'),
+ ]),
+
+ h('label', {
+ htmlFor: 'settings-rpc-endpoint',
+ }, 'RPC Endpoint:'),
+ h('input', {
+ type: 'url',
+ id: 'settings-rpc-endpoint',
+ onKeyPress: this.onKeyPress.bind(this),
+ }),
+
+ ])
+
+ )
+}
+
+AppSettingsPage.prototype.componentDidMount = function () {
+ document.querySelector('input').focus()
+}
+
+AppSettingsPage.prototype.onKeyPress = function (event) {
+ // get submit event
+ if (event.key === 'Enter') {
+ // this.submitPassword(event)
+ }
+}
+
+AppSettingsPage.prototype.navigateToAccounts = function (event) {
+ event.stopPropagation()
+ this.props.dispatch(actions.showAccountsPage())
+}
diff --git a/old-ui/app/template.js b/old-ui/app/template.js
new file mode 100644
index 000000000..d15b30fd2
--- /dev/null
+++ b/old-ui/app/template.js
@@ -0,0 +1,30 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+
+module.exports = connect(mapStateToProps)(COMPONENTNAME)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(COMPONENTNAME, Component)
+function COMPONENTNAME () {
+ Component.call(this)
+}
+
+COMPONENTNAME.prototype.render = function () {
+ const props = this.props
+
+ return (
+ h('div', {
+ style: {
+ background: 'blue',
+ },
+ }, [
+ `Hello, ${props.sender}`,
+ ])
+ )
+}
+
diff --git a/old-ui/app/unlock.js b/old-ui/app/unlock.js
new file mode 100644
index 000000000..a1f791552
--- /dev/null
+++ b/old-ui/app/unlock.js
@@ -0,0 +1,122 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const actions = require('../../ui/app/actions')
+const getCaretCoordinates = require('textarea-caret')
+const EventEmitter = require('events').EventEmitter
+
+const Mascot = require('./components/mascot')
+
+module.exports = connect(mapStateToProps)(UnlockScreen)
+
+inherits(UnlockScreen, Component)
+function UnlockScreen () {
+ Component.call(this)
+ this.animationEventEmitter = new EventEmitter()
+}
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ }
+}
+
+UnlockScreen.prototype.render = function () {
+ const state = this.props
+ const warning = state.warning
+ return (
+ h('.flex-column', {
+ style: {
+ width: 'inherit',
+ },
+ }, [
+ h('.unlock-screen.flex-column.flex-center.flex-grow', [
+
+ h(Mascot, {
+ animationEventEmitter: this.animationEventEmitter,
+ }),
+
+ h('h1', {
+ style: {
+ fontSize: '1.4em',
+ textTransform: 'uppercase',
+ color: '#7F8082',
+ },
+ }, 'MetaMask'),
+
+ h('input.large-input', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'enter password',
+ style: {
+
+ },
+ onKeyPress: this.onKeyPress.bind(this),
+ onInput: this.inputChanged.bind(this),
+ }),
+
+ h('.error', {
+ style: {
+ display: warning ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, warning),
+
+ h('button.primary.cursor-pointer', {
+ onClick: this.onSubmit.bind(this),
+ style: {
+ margin: 10,
+ },
+ }, 'Unlock'),
+ ]),
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => this.props.dispatch(actions.forgotPassword()),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'Restore from seed phrase'),
+ ]),
+ ])
+ )
+}
+
+UnlockScreen.prototype.componentDidMount = function () {
+ document.getElementById('password-box').focus()
+}
+
+UnlockScreen.prototype.onSubmit = function (event) {
+ const input = document.getElementById('password-box')
+ const password = input.value
+ this.props.dispatch(actions.tryUnlockMetamask(password))
+}
+
+UnlockScreen.prototype.onKeyPress = function (event) {
+ if (event.key === 'Enter') {
+ this.submitPassword(event)
+ }
+}
+
+UnlockScreen.prototype.submitPassword = function (event) {
+ var element = event.target
+ var password = element.value
+ // reset input
+ element.value = ''
+ this.props.dispatch(actions.tryUnlockMetamask(password))
+}
+
+UnlockScreen.prototype.inputChanged = function (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+}
diff --git a/old-ui/app/util.js b/old-ui/app/util.js
new file mode 100644
index 000000000..3f8b4dcc3
--- /dev/null
+++ b/old-ui/app/util.js
@@ -0,0 +1,240 @@
+const ethUtil = require('ethereumjs-util')
+
+var valueTable = {
+ wei: '1000000000000000000',
+ kwei: '1000000000000000',
+ mwei: '1000000000000',
+ gwei: '1000000000',
+ szabo: '1000000',
+ finney: '1000',
+ ether: '1',
+ kether: '0.001',
+ mether: '0.000001',
+ gether: '0.000000001',
+ tether: '0.000000000001',
+}
+var bnTable = {}
+for (var currency in valueTable) {
+ bnTable[currency] = new ethUtil.BN(valueTable[currency], 10)
+}
+
+module.exports = {
+ valuesFor: valuesFor,
+ addressSummary: addressSummary,
+ miniAddressSummary: miniAddressSummary,
+ isAllOneCase: isAllOneCase,
+ isValidAddress: isValidAddress,
+ numericBalance: numericBalance,
+ parseBalance: parseBalance,
+ formatBalance: formatBalance,
+ generateBalanceObject: generateBalanceObject,
+ dataSize: dataSize,
+ readableDate: readableDate,
+ normalizeToWei: normalizeToWei,
+ normalizeEthStringToWei: normalizeEthStringToWei,
+ normalizeNumberToWei: normalizeNumberToWei,
+ valueTable: valueTable,
+ bnTable: bnTable,
+ isHex: isHex,
+ exportAsFile: exportAsFile,
+ isInvalidChecksumAddress,
+}
+
+function valuesFor (obj) {
+ if (!obj) return []
+ return Object.keys(obj)
+ .map(function (key) { return obj[key] })
+}
+
+function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includeHex = true) {
+ if (!address) return ''
+ let checked = ethUtil.toChecksumAddress(address)
+ if (!includeHex) {
+ checked = ethUtil.stripHexPrefix(checked)
+ }
+ return checked ? checked.slice(0, firstSegLength) + '...' + checked.slice(checked.length - lastSegLength) : '...'
+}
+
+function miniAddressSummary (address) {
+ if (!address) return ''
+ var checked = ethUtil.toChecksumAddress(address)
+ return checked ? checked.slice(0, 4) + '...' + checked.slice(-4) : '...'
+}
+
+function isValidAddress (address) {
+ var prefixed = ethUtil.addHexPrefix(address)
+ if (address === '0x0000000000000000000000000000000000000000') return false
+ return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
+}
+
+function isInvalidChecksumAddress (address) {
+ var prefixed = ethUtil.addHexPrefix(address)
+ if (address === '0x0000000000000000000000000000000000000000') return false
+ return !isAllOneCase(prefixed) && !ethUtil.isValidChecksumAddress(prefixed) && ethUtil.isValidAddress(prefixed)
+}
+
+function isAllOneCase (address) {
+ if (!address) return true
+ var lower = address.toLowerCase()
+ var upper = address.toUpperCase()
+ return address === lower || address === upper
+}
+
+// Takes wei Hex, returns wei BN, even if input is null
+function numericBalance (balance) {
+ if (!balance) return new ethUtil.BN(0, 16)
+ var stripped = ethUtil.stripHexPrefix(balance)
+ return new ethUtil.BN(stripped, 16)
+}
+
+// Takes hex, returns [beforeDecimal, afterDecimal]
+function parseBalance (balance) {
+ var beforeDecimal, afterDecimal
+ const wei = numericBalance(balance)
+ var weiString = wei.toString()
+ const trailingZeros = /0+$/
+
+ beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0'
+ afterDecimal = ('000000000000000000' + wei).slice(-18).replace(trailingZeros, '')
+ if (afterDecimal === '') { afterDecimal = '0' }
+ return [beforeDecimal, afterDecimal]
+}
+
+// Takes wei hex, returns an object with three properties.
+// Its "formatted" property is what we generally use to render values.
+function formatBalance (balance, decimalsToKeep, needsParse = true) {
+ var parsed = needsParse ? parseBalance(balance) : balance.split('.')
+ var beforeDecimal = parsed[0]
+ var afterDecimal = parsed[1]
+ var formatted = 'None'
+ if (decimalsToKeep === undefined) {
+ if (beforeDecimal === '0') {
+ if (afterDecimal !== '0') {
+ var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
+ if (sigFigs) { afterDecimal = sigFigs[0] }
+ formatted = '0.' + afterDecimal + ' ETH'
+ }
+ } else {
+ formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
+ }
+ } else {
+ afterDecimal += Array(decimalsToKeep).join('0')
+ formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
+ }
+ return formatted
+}
+
+
+function generateBalanceObject (formattedBalance, decimalsToKeep = 1) {
+ var balance = formattedBalance.split(' ')[0]
+ var label = formattedBalance.split(' ')[1]
+ var beforeDecimal = balance.split('.')[0]
+ var afterDecimal = balance.split('.')[1]
+ var shortBalance = shortenBalance(balance, decimalsToKeep)
+
+ if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') {
+ // eslint-disable-next-line eqeqeq
+ if (afterDecimal == 0) {
+ balance = '0'
+ } else {
+ balance = '<1.0e-5'
+ }
+ } else if (beforeDecimal !== '0') {
+ balance = `${beforeDecimal}.${afterDecimal.slice(0, decimalsToKeep)}`
+ }
+
+ return { balance, label, shortBalance }
+}
+
+function shortenBalance (balance, decimalsToKeep = 1) {
+ var truncatedValue
+ var convertedBalance = parseFloat(balance)
+ if (convertedBalance > 1000000) {
+ truncatedValue = (balance / 1000000).toFixed(decimalsToKeep)
+ return `${truncatedValue}m`
+ } else if (convertedBalance > 1000) {
+ truncatedValue = (balance / 1000).toFixed(decimalsToKeep)
+ return `${truncatedValue}k`
+ } else if (convertedBalance === 0) {
+ return '0'
+ } else if (convertedBalance < 0.001) {
+ return '<0.001'
+ } else if (convertedBalance < 1) {
+ var stringBalance = convertedBalance.toString()
+ if (stringBalance.split('.')[1].length > 3) {
+ return convertedBalance.toFixed(3)
+ } else {
+ return stringBalance
+ }
+ } else {
+ return convertedBalance.toFixed(decimalsToKeep)
+ }
+}
+
+function dataSize (data) {
+ var size = data ? ethUtil.stripHexPrefix(data).length : 0
+ return size + ' bytes'
+}
+
+// Takes a BN and an ethereum currency name,
+// returns a BN in wei
+function normalizeToWei (amount, currency) {
+ try {
+ return amount.mul(bnTable.wei).div(bnTable[currency])
+ } catch (e) {}
+ return amount
+}
+
+function normalizeEthStringToWei (str) {
+ const parts = str.split('.')
+ let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei)
+ if (parts[1]) {
+ var decimal = parts[1]
+ while (decimal.length < 18) {
+ decimal += '0'
+ }
+ const decimalBN = new ethUtil.BN(decimal, 10)
+ eth = eth.add(decimalBN)
+ }
+ return eth
+}
+
+var multiple = new ethUtil.BN('10000', 10)
+function normalizeNumberToWei (n, currency) {
+ var enlarged = n * 10000
+ var amount = new ethUtil.BN(String(enlarged), 10)
+ return normalizeToWei(amount, currency).div(multiple)
+}
+
+function readableDate (ms) {
+ var date = new Date(ms)
+ var month = date.getMonth()
+ var day = date.getDate()
+ var year = date.getFullYear()
+ var hours = date.getHours()
+ var minutes = '0' + date.getMinutes()
+ var seconds = '0' + date.getSeconds()
+
+ var dateStr = `${month}/${day}/${year}`
+ var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`
+ return `${dateStr} ${time}`
+}
+
+function isHex (str) {
+ return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/))
+}
+
+function exportAsFile (filename, data) {
+ // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz
+ const blob = new Blob([data], {type: 'text/csv'})
+ if (window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveBlob(blob, filename)
+ } else {
+ const elem = window.document.createElement('a')
+ elem.href = window.URL.createObjectURL(blob)
+ elem.download = filename
+ document.body.appendChild(elem)
+ elem.click()
+ document.body.removeChild(elem)
+ }
+}
diff --git a/old-ui/css.js b/old-ui/css.js
new file mode 100644
index 000000000..21b311c28
--- /dev/null
+++ b/old-ui/css.js
@@ -0,0 +1,30 @@
+const fs = require('fs')
+const path = require('path')
+
+module.exports = bundleCss
+
+var cssFiles = {
+ 'fonts.css': fs.readFileSync(path.join(__dirname, '/app/css/fonts.css'), 'utf8'),
+ 'reset.css': fs.readFileSync(path.join(__dirname, '/app/css/reset.css'), 'utf8'),
+ 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'),
+ 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'),
+ 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'),
+ 'first-time.css': fs.readFileSync(path.join(__dirname, '../mascara/src/app/first-time/index.css'), 'utf8'),
+ 'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
+ 'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
+}
+
+function bundleCss () {
+ var cssBundle = Object.keys(cssFiles).reduce(function (bundle, fileName) {
+ var fileContent = cssFiles[fileName]
+ var output = String()
+
+ output += '/*========== ' + fileName + ' ==========*/\n\n'
+ output += fileContent
+ output += '\n\n'
+
+ return bundle + output
+ }, String())
+
+ return cssBundle
+}
diff --git a/old-ui/design/00-metamask-SignIn.jpg b/old-ui/design/00-metamask-SignIn.jpg
new file mode 100644
index 000000000..2becdb032
--- /dev/null
+++ b/old-ui/design/00-metamask-SignIn.jpg
Binary files differ
diff --git a/old-ui/design/01-metamask-SelectAcc.jpg b/old-ui/design/01-metamask-SelectAcc.jpg
new file mode 100644
index 000000000..239091a98
--- /dev/null
+++ b/old-ui/design/01-metamask-SelectAcc.jpg
Binary files differ
diff --git a/old-ui/design/02-metamask-AccDetails.jpg b/old-ui/design/02-metamask-AccDetails.jpg
new file mode 100644
index 000000000..d7d408ffc
--- /dev/null
+++ b/old-ui/design/02-metamask-AccDetails.jpg
Binary files differ
diff --git a/old-ui/design/02a-metamask-AccDetails-OverToken.jpg b/old-ui/design/02a-metamask-AccDetails-OverToken.jpg
new file mode 100644
index 000000000..f26ff31e8
--- /dev/null
+++ b/old-ui/design/02a-metamask-AccDetails-OverToken.jpg
Binary files differ
diff --git a/old-ui/design/02a-metamask-AccDetails-OverTransaction.jpg b/old-ui/design/02a-metamask-AccDetails-OverTransaction.jpg
new file mode 100644
index 000000000..8a06be6b9
--- /dev/null
+++ b/old-ui/design/02a-metamask-AccDetails-OverTransaction.jpg
Binary files differ
diff --git a/old-ui/design/02a-metamask-AccDetails.jpg b/old-ui/design/02a-metamask-AccDetails.jpg
new file mode 100644
index 000000000..c37e0f539
--- /dev/null
+++ b/old-ui/design/02a-metamask-AccDetails.jpg
Binary files differ
diff --git a/old-ui/design/02b-metamask-AccDetails-Send.jpg b/old-ui/design/02b-metamask-AccDetails-Send.jpg
new file mode 100644
index 000000000..10f2d27fd
--- /dev/null
+++ b/old-ui/design/02b-metamask-AccDetails-Send.jpg
Binary files differ
diff --git a/old-ui/design/03-metamask-Qr.jpg b/old-ui/design/03-metamask-Qr.jpg
new file mode 100644
index 000000000..9c09de42f
--- /dev/null
+++ b/old-ui/design/03-metamask-Qr.jpg
Binary files differ
diff --git a/old-ui/design/05-metamask-Menu.jpg b/old-ui/design/05-metamask-Menu.jpg
new file mode 100644
index 000000000..0a43d7b2a
--- /dev/null
+++ b/old-ui/design/05-metamask-Menu.jpg
Binary files differ
diff --git a/old-ui/design/chromeStorePics/final_screen_dao_accounts.png b/old-ui/design/chromeStorePics/final_screen_dao_accounts.png
new file mode 100644
index 000000000..805cc96b6
--- /dev/null
+++ b/old-ui/design/chromeStorePics/final_screen_dao_accounts.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/final_screen_dao_locked.png b/old-ui/design/chromeStorePics/final_screen_dao_locked.png
new file mode 100644
index 000000000..9d9e33930
--- /dev/null
+++ b/old-ui/design/chromeStorePics/final_screen_dao_locked.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/final_screen_dao_notification.png b/old-ui/design/chromeStorePics/final_screen_dao_notification.png
new file mode 100644
index 000000000..d56a5ce62
--- /dev/null
+++ b/old-ui/design/chromeStorePics/final_screen_dao_notification.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/final_screen_wei_account.png b/old-ui/design/chromeStorePics/final_screen_wei_account.png
new file mode 100644
index 000000000..d503ff301
--- /dev/null
+++ b/old-ui/design/chromeStorePics/final_screen_wei_account.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/final_screen_wei_notification.png b/old-ui/design/chromeStorePics/final_screen_wei_notification.png
new file mode 100644
index 000000000..3560c51ff
--- /dev/null
+++ b/old-ui/design/chromeStorePics/final_screen_wei_notification.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/icon-128.png b/old-ui/design/chromeStorePics/icon-128.png
new file mode 100644
index 000000000..ae687147d
--- /dev/null
+++ b/old-ui/design/chromeStorePics/icon-128.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/icon-64.png b/old-ui/design/chromeStorePics/icon-64.png
new file mode 100644
index 000000000..7062cf4f1
--- /dev/null
+++ b/old-ui/design/chromeStorePics/icon-64.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/metamask_icon.ai b/old-ui/design/chromeStorePics/metamask_icon.ai
new file mode 100644
index 000000000..27400c5a4
--- /dev/null
+++ b/old-ui/design/chromeStorePics/metamask_icon.ai
@@ -0,0 +1,2383 @@
+%PDF-1.5 %âãÏÓ
+1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R]/Order 6 0 R/RBGroups[]>>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 47428/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c111 79.158366, 2015/09/25-01:12:00 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
+ xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
+ xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">metamask_icon</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ <xmp:CreatorTool>Adobe Illustrator CC 2015 (Macintosh)</xmp:CreatorTool>
+ <xmp:CreateDate>2016-06-15T14:23:12-04:00</xmp:CreateDate>
+ <xmp:ModifyDate>2016-06-15T14:23:12-04:00</xmp:ModifyDate>
+ <xmp:MetadataDate>2016-06-15T14:23:12-04:00</xmp:MetadataDate>
+ <xmp:Thumbnails>
+ <rdf:Alt>
+ <rdf:li rdf:parseType="Resource">
+ <xmpGImg:width>240</xmpGImg:width>
+ <xmpGImg:height>256</xmpGImg:height>
+ <xmpGImg:format>JPEG</xmpGImg:format>
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADwAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXnP5r/mvB5Tg/RmnAT6/cJyUMKx28bVAkf+ZjT4U+k7UDYuo1HBsObl6bTce5+l5X+Wf5t6jonm&#xA;KZtfu5rzTNVcG+lkZpHilACLOAamgUBWC/sgUrxAzEwakxl6uRczUaYSj6eYfS9vcQXEEdxA6ywT&#xA;KskUimqsjCqsCOoIObUG3UkUvxQ7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY&#xA;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</xmpGImg:image>
+ </rdf:li>
+ </rdf:Alt>
+ </xmp:Thumbnails>
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+ <xmpMM:OriginalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</xmpMM:OriginalDocumentID>
+ <xmpMM:DocumentID>xmp.did:d4d07395-aa96-47c2-a9e5-d0351947bb0c</xmpMM:DocumentID>
+ <xmpMM:InstanceID>uuid:c63c1031-e157-9748-9c58-86481308e954</xmpMM:InstanceID>
+ <xmpMM:DerivedFrom rdf:parseType="Resource">
+ <stRef:instanceID>uuid:1abccb90-0c26-4942-b156-fd2eb962e3e1</stRef:instanceID>
+ <stRef:documentID>xmp.did:58fdc1b8-1448-3a44-9e20-282d8ec1cf95</stRef:documentID>
+ <stRef:originalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</stRef:originalDocumentID>
+ <stRef:renditionClass>proof:pdf</stRef:renditionClass>
+ </xmpMM:DerivedFrom>
+ <xmpMM:History>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <stEvt:action>saved</stEvt:action>
+ <stEvt:instanceID>xmp.iid:d4d07395-aa96-47c2-a9e5-d0351947bb0c</stEvt:instanceID>
+ <stEvt:when>2016-06-15T14:23:10-04:00</stEvt:when>
+ <stEvt:softwareAgent>Adobe Illustrator CC 2015 (Macintosh)</stEvt:softwareAgent>
+ <stEvt:changed>/</stEvt:changed>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpMM:History>
+ <illustrator:StartupProfile>Web</illustrator:StartupProfile>
+ <illustrator:Type>Document</illustrator:Type>
+ <xmpTPg:NPages>1</xmpTPg:NPages>
+ <xmpTPg:HasVisibleTransparency>True</xmpTPg:HasVisibleTransparency>
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
+ <stDim:w>128.000000</stDim:w>
+ <stDim:h>128.000000</stDim:h>
+ <stDim:unit>Pixels</stDim:unit>
+ </xmpTPg:MaxPageSize>
+ <xmpTPg:PlateNames>
+ <rdf:Seq>
+ <rdf:li>Cyan</rdf:li>
+ <rdf:li>Magenta</rdf:li>
+ <rdf:li>Yellow</rdf:li>
+ <rdf:li>Black</rdf:li>
+ </rdf:Seq>
+ </xmpTPg:PlateNames>
+ <xmpTPg:SwatchGroups>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+ <xmpG:groupType>0</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>White</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>255</xmpG:green>
+ <xmpG:blue>255</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>Black</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Red</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>255</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Green</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>255</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>255</xmpG:green>
+ <xmpG:blue>255</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Blue</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>255</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>255</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>193</xmpG:red>
+ <xmpG:green>39</xmpG:green>
+ <xmpG:blue>45</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>237</xmpG:red>
+ <xmpG:green>28</xmpG:green>
+ <xmpG:blue>36</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>241</xmpG:red>
+ <xmpG:green>90</xmpG:green>
+ <xmpG:blue>36</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>247</xmpG:red>
+ <xmpG:green>147</xmpG:green>
+ <xmpG:blue>30</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>251</xmpG:red>
+ <xmpG:green>176</xmpG:green>
+ <xmpG:blue>59</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>252</xmpG:red>
+ <xmpG:green>238</xmpG:green>
+ <xmpG:blue>33</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>217</xmpG:red>
+ <xmpG:green>224</xmpG:green>
+ <xmpG:blue>33</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>140</xmpG:red>
+ <xmpG:green>198</xmpG:green>
+ <xmpG:blue>63</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>57</xmpG:red>
+ <xmpG:green>181</xmpG:green>
+ <xmpG:blue>74</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>146</xmpG:green>
+ <xmpG:blue>69</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>104</xmpG:green>
+ <xmpG:blue>55</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>34</xmpG:red>
+ <xmpG:green>181</xmpG:green>
+ <xmpG:blue>115</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>169</xmpG:green>
+ <xmpG:blue>157</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>41</xmpG:red>
+ <xmpG:green>171</xmpG:green>
+ <xmpG:blue>226</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>113</xmpG:green>
+ <xmpG:blue>188</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>46</xmpG:red>
+ <xmpG:green>49</xmpG:green>
+ <xmpG:blue>146</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>27</xmpG:red>
+ <xmpG:green>20</xmpG:green>
+ <xmpG:blue>100</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>102</xmpG:red>
+ <xmpG:green>45</xmpG:green>
+ <xmpG:blue>145</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>147</xmpG:red>
+ <xmpG:green>39</xmpG:green>
+ <xmpG:blue>143</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>158</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>93</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>212</xmpG:red>
+ <xmpG:green>20</xmpG:green>
+ <xmpG:blue>90</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>237</xmpG:red>
+ <xmpG:green>30</xmpG:green>
+ <xmpG:blue>121</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>199</xmpG:red>
+ <xmpG:green>178</xmpG:green>
+ <xmpG:blue>153</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>153</xmpG:red>
+ <xmpG:green>134</xmpG:green>
+ <xmpG:blue>117</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>115</xmpG:red>
+ <xmpG:green>99</xmpG:green>
+ <xmpG:blue>87</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>83</xmpG:red>
+ <xmpG:green>71</xmpG:green>
+ <xmpG:blue>65</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>198</xmpG:red>
+ <xmpG:green>156</xmpG:green>
+ <xmpG:blue>109</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>166</xmpG:red>
+ <xmpG:green>124</xmpG:green>
+ <xmpG:blue>82</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>140</xmpG:red>
+ <xmpG:green>98</xmpG:green>
+ <xmpG:blue>57</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>117</xmpG:red>
+ <xmpG:green>76</xmpG:green>
+ <xmpG:blue>36</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>96</xmpG:red>
+ <xmpG:green>56</xmpG:green>
+ <xmpG:blue>19</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>66</xmpG:red>
+ <xmpG:green>33</xmpG:green>
+ <xmpG:blue>11</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Grays</xmpG:groupName>
+ <xmpG:groupType>1</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>26</xmpG:red>
+ <xmpG:green>26</xmpG:green>
+ <xmpG:blue>26</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>51</xmpG:red>
+ <xmpG:green>51</xmpG:green>
+ <xmpG:blue>51</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>77</xmpG:red>
+ <xmpG:green>77</xmpG:green>
+ <xmpG:blue>77</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>102</xmpG:red>
+ <xmpG:green>102</xmpG:green>
+ <xmpG:blue>102</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>128</xmpG:red>
+ <xmpG:green>128</xmpG:green>
+ <xmpG:blue>128</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>153</xmpG:red>
+ <xmpG:green>153</xmpG:green>
+ <xmpG:blue>153</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>179</xmpG:red>
+ <xmpG:green>179</xmpG:green>
+ <xmpG:blue>179</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>204</xmpG:red>
+ <xmpG:green>204</xmpG:green>
+ <xmpG:blue>204</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>230</xmpG:red>
+ <xmpG:green>230</xmpG:green>
+ <xmpG:blue>230</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>242</xmpG:red>
+ <xmpG:green>242</xmpG:green>
+ <xmpG:blue>242</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Web Color Group</xmpG:groupName>
+ <xmpG:groupType>1</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=63 G=169 B=245</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>63</xmpG:red>
+ <xmpG:green>169</xmpG:green>
+ <xmpG:blue>245</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=122 G=201 B=67</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>122</xmpG:red>
+ <xmpG:green>201</xmpG:green>
+ <xmpG:blue>67</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=255 G=147 B=30</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>147</xmpG:green>
+ <xmpG:blue>30</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=255 G=29 B=37</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>29</xmpG:green>
+ <xmpG:blue>37</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=255 G=123 B=172</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>123</xmpG:green>
+ <xmpG:blue>172</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>R=189 G=204 B=212</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>189</xmpG:red>
+ <xmpG:green>204</xmpG:green>
+ <xmpG:blue>212</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpTPg:SwatchGroups>
+ <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?> endstream endobj 3 0 obj <</Count 1/Kids[7 0 R]/Type/Pages>> endobj 7 0 obj <</ArtBox[19.792 16.0 109.0 112.0]/BleedBox[0.0 0.0 128.0 128.0]/Contents 8 0 R/Group 9 0 R/LastModified(D:20160615142312-04'00')/MediaBox[0.0 0.0 128.0 128.0]/Parent 3 0 R/PieceInfo<</Illustrator 10 0 R>>/Resources<</ColorSpace<</CS0 11 0 R>>/ExtGState<</GS0 12 0 R>>/ProcSet[/PDF/ImageC]/Properties<</MC0 5 0 R>>/XObject<</Im0 13 0 R>>>>/Thumb 14 0 R/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 8 0 obj <</Filter/FlateDecode/Length 106>>stream
+H‰Ò÷wVÐ÷u6PprqVà*ä2´Ô3·4R04S°°Ô32°P°4Õ³´´T(Jå
+WÈ*Ðw6PH/æ‚H™+
+8;W:dYmnJk$j=`^PKX*GV"-/6MPPhMW4o*<SJ[.r.2B:%l2U+:>jFegTA5n:ROqi.
+8M?-(/t#IN>re.=TbIMqYWQK1D%b&pOLGa]H?hKs'8Gqa4A/k;[i&\e-=4:h!/H6BW;~> endstream endobj 16 0 obj [/Indexed/DeviceRGB 255 17 0 R] endobj 17 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 13 0 obj <</BitsPerComponent 8/ColorSpace 11 0 R/DecodeParms<</BitsPerComponent 4/Colors 3/Columns 880>>/Filter/FlateDecode/Height 947/Intent/RelativeColorimetric/Length 90241/Name/X/SMask 18 0 R/Subtype/Image/Type/XObject/Width 880>>stream
+H‰ì×ÏoiÀñù@H•–•²™y&¶á‰Ã8´™_Én²á¶„Äâ—ØÖyŸÛA¢'¸íŠ?
+I
+
+Wú <Ó* ²º'’œ°%ÌŸ­YLj%éâV‡ì§æšmaþo!û‹—Ç©k¸vÜ>¢Ñw áŒu{=€Q†®<\ȃ*fƸmqÈäþY%Å”RÓp»
+
+i¤HòF·'î>hd,“®I#Éä_¿™ýÑ‹ÆâTj›~Qš5¸c§Rñ`ôˆn:Ës· e8ÉÃ ù¤P·ÑîÕ
+WW®zÙ¶°:‚­lÕgÒëÜlØ7ɃÔHi’J&ÛÂüï¢ù³/¤ ÓºgË.°}› ÍCœ§¯ãÃ'ÁˆËdîD|V“Öª'9TL*ù4ŸI]˜Š6… ”
+››>•#g‰ÛãV™¤±-Ì?}=óÆ ÆÂTj¡šOK¥<ý>µNh aÔuOB×në¥Y#qkBÞ)‘çÓÑfiQõ@ 
+¥
+zÁŸÍtuõÏt&“ì¼k¿sª»§çg1›twuO/‡JÍÀ„>_¿ç9Eªzb‚(Jr2éh›+’É“¼)€£ó⇻¤”AŒ!·àÜð«·_:Ûª.Æ%£îÙ±4¨EÑ3wËì~ÅÞ ÄsO®¼q9ÛÔFÈ$·þ½Æ~þÕEßÑ<GãîÈJÏîä?
+7"P¨ç‰ 16?wŠ'¾‘¶óPÆ”äšPÎ ¥ìm?U AÑJ¢‘‡®¥»åO¡C¢/%öˆ-n·Ö :d¬}Ä_HÛëR0I™·þþºyc5SÊj¾¬åÑV}¥ ¹ nÇ¡Ý!ˆñ1Iî,òœŽC8òÁ¦LaP)GíŠcAê 1 (ÂEŽ4F|õì°Q#0#0PïWí{² V<¬Ž^úF—¦LzâÓ@™üÓ%óûÏékËê˜êÏñ0«uÉ'‰I1ÉÀÕqÃ<Éä¼$p5žSyV(%AÇ“8äM¹ùY½Ä¶QE¾ÑðY'd7íÝ2k€µ/QÞ¼;ä°L&ŸÌï^1* e’»£ïv<Ä7V2Sy¾+GäŸ FÎÀ"wA
+†žºäP&ìœrA\Ê9g ¸JCÄ
+¤´Çc¾°Øè‡1Bu€íUìU!h’B
+ä¡m²‘›Õ?IÔòXü¦qýBf=«Oò¨-çuÑäÎS]*pb  L¢pº¡³
+½+Qf1XGbuô.•ALø}åœÃõÀ{øì;×jÞé:˜1°XºM;`ïmœ¾öþ)Ý’r¼2ÙâÖ?¯™?ûÊbÉÑ<gÒ2¸â|çÎNDq•ª›)}™ôs*Î[˜×SwÊLGEôR>Ó¥^"ˆT‘.4²{óÀ7±Ïî„VÌ:7ÐcO¬ °î–Ùn™µ¸]‡ƒ&IŸIÊ´¹õ·×­]Ô׳ºŸ›¨L&Ù¼á®~ãe¥?61‚þ8qW 6É$åуS-èÜÑJ+j—”’ &‰HàR#Y(Íu3C¸"š¤ÇvaµÖäVO í¯”qˤgáŠþŸ/™ß{NÈd* ð¬w4~ž›²‹8`ਡ«Oþ®D™éàÀT
+¢¯žž(‚ ƃ‚º(r„Vu¥¥6z‹0FÏ|¸iïUì6—ÆèÉô”º_ÍUp_š |ò7//…y e2•£6©ka•…E9JT×Ähý<'|€»éË eæ’\xËyì(µ7QÔQ1Z)7•#÷5eoÓˆÀ¨ƒ0Æ‹gÞ+Û¨‘wC–xc òX”¶SÍg")“-nýkýâÅEßÑJÙÔN[ìê*ú¤«õ†Š FAÒK¸¢L®LR7‰R.’šL—BME#@Ù*
+~U¿üÌÝŠÙtEEVOtÑ7ïU콊ÝؾÌxéÛÔœ'’isëöóÆjf=«£Oòôº[Z¬¹Oà ÔÒÄ((®ŠAúî>®Š&™Ö]‰r’"šÊÑ‚|f0`A|0Ä/2}€+58{™:ØÂ!ELTÇ€uB†1Hôz“ºGQ0‘gáÚâÖ[—|Q_[VSoér^G›½þyµ?lñD$g=?ÿÈ©Õ•LêN9Áš
+±¬•K¥Ü*RYÄ£pØÔáÓu0ë%Kˆ¢'üäÝ*Û- l€p•D <P¦#¸Y¸Gèù¿}Ũ4”Iî¦Üϸ.V´Ö;òIâÉèÉäòÇQ&+=u ¡œ°àPaqU²¢²€S_Äq(R o*B&ñ†Ò³Bcß@-Ù«Øïmœî„ 大+R/ëÀ¢´­‰rlpך`m{Öͯ-úŽVr´te¤O&ÿ^åLOF"“¥e59÷Åh9éåĄ˵ŠJéhoº¤”q¥{5²0üêí—ÎÞ¥:˜¨‹5ß8Ƀ*ô¸x'/>I™ÖD2Mnݾbþä…L)«¡Oò´›äYæñÐׯžîR3OF"“R õj"“iO8åä%ªÀÕÁÑ{“§Pqs Î?Heøe}-°ÄXJÚÈNÀî•m\Ñ-ëžÔH/}G¢<b"ϵŭ¿|Ëxãy}}YM½‡ƒç>Ï©ý¤Z&œœžLæð¸/çu>7&ÊI wQ)µ /º+Pê.bŽPà"Â$Nþö5ûØ5ÏB]Œ=á{»2È·`¡[Šø¤‘³—Hnk¬?¼¶´±¢®-«ÓsÈò\ïÄ粓ùy*dâqPúºŸäò†9’IÊغº,1ýì—ík[×ÇõìÅØ`Ä÷^Ù÷A¦/önƒ¾3¬ÖÕ•ìŒËcËèVÚn´ì©a­-_s%YñS’µ…²îM{b ¶FÇ £oZÆ”±Žnk›E–%ÇytÜ$mAûs%E±Äv]ùûåÃáúJWÈøëßùê^xœAž ÍXkŒ­È0v_•ÝKÓ‰Õò i$é‡ðFߪ†/Ñu(“ jL’Ižž²÷íþ‚§O%»k“¥/S‰‹<z YWÙnZµ <QªbÚ誒ƒÞ&ì[q¤¯¥Dz1ŒÇ'‰ÌMwc±×ÙýU¯0s)/ýPzãÚÑÄÅR¢Î¤‘m¬äÊuì˜ð/Xçö»ÏÚ?¸ßOêy·ëd’ÖRÆ<êɇ0Š‘m'hˤ¬S!m(/6Øo”Gâ´ò¡ÁF¸ù"HÔCs• c¤µófÙä§YBh†ß”•‚syÚ¡•²yß¿‡nö˜ð,@2ùöûÅ1crXS>r7B>YÌœ,7©70‡‘í§Ý™Às)“]ubûQ9OŸÎˆƒL³1Œ2$j¥ˆ¡Ên*ð2Ó*쾊O&iVóÎ"sÎÎràœ+ˆ 2L²ÇjèÐÈžCüÝóÖ³ßxÒœÿŠ‘ëJ™ 9:J µÊŒ ÛH(“´žhxàA&xk Âi&æÒõ‰Iu$6Ô•æj•õ“:.æÍE– Q\-^*%V¤@V;•ƒR¼M½ù€]‡d’L’ÖWí<}*©wç&Kߊ{òÂÕ-7@-&;.
+C»6õ§˜6 “@9TB–U¤fðI¤[#vÛ1©‘r¶`·’,¢Î×f/5nßÐ ÙûT¤LÖ¹ýÞ¤õëoÄsIÃw»T&™ôÉ錿\Žßç#¹UB™ä£XJ&éuoÏÁ¾‚Ž6TEžÖÚ-E®HLäëìþu[íòÓFÙä‡Uf
+‘–x¾è¬–ÏšÆX¥›¾zÃ{FEr6°ÿqÄúiVÈd>Õ½›løÅ
+žÁ\½UvÌ^dKáCR&‡òpûöÔ÷€6ÓkÚ„o@)µ»ªÐÈÆÉ›zx¹üùZÎZfBÏøv¨5n“F’CÒÅ µ`Žr·{LÅ·«y«Îí7¿gÎ2H&•Õ;xù@ÁíkÕAîœSYQ•ÙC,¥•2è9ØWp¹
+¥ôô°±Œc¸!{)²r±õ»*ûâR¨²ÁjÞ!¬ú&Ù#±8ËScM‡¤—}«¢Zi€*H&—˜MøÓfàé$“\õPÝ
+Å´Á\¤¦ðId e²žDÒIЄã—F1÷úšÅÅ|CîeH Åld›Ô¬6i.2K8¤tŷ׎&Ît±(ÕQ—+ý¨Zf€B*R&ëÜ~?gÿö›ý4Ä|Wï~™ ¿!ù$÷ô°ó1Ì[äN¡™Ikq¤úS‰ó(Tì[È'iͧ4*m€ù†ì~¤@žŒ­?­ŒÅ>˜èûKT™ô)ŠÎ•òàJà3t
+dEµÃ€.¡"!™|çëg_ç’F>";,o)%OõQý³ã¶ÈîÈ~Z£æ”2F»B
+3›†Àœ%f_,%.už ;ÕÖ}å꺊oÓZãö_`>÷19¬)žÛ‚”€Ö™Ĥ b˜´È-‹Å 2z[&•€;BE¦ººz1i6 ”ÈöCÓ¯!öG9™¸h¿tšÅj9«î'I#…8ä˳BœÐ!…=úÂ*ªt-T:zT™óçï”G´\2z;¬³F3¹}ZgÀµL‚hž€èâHòÓÖ¸‹!Èfi´VáL:ä†,NÆÏ0E«šwHÈV§sR I „!ø-UàÖLÒ1äô”ýÊ#4¦¦’zävØBÚ`®VðŒ|¹uÚã” ™4ŠiÈ$ˆ\"&^ÊX×jÙbÞŸ±—Ø mýRòÆÕò q6ÆØÖH ¶JERçö»ÏÚ/-N&™w£'“,¥ÍŒÆ¹§Ó¿‰8‹!ÈféIƒ|²”1T÷€BãŽÖÀíSû?…D%ÿ}ê35fW§ÌŠôCÈŠ\É!/–5n“:VC1€@‚í#Î&R&ÿþ£ç2rÚò!¹“¹Ú"H Ÿ<•…O"›$;Þ,Æ”ÛGµ)¤!“ ÚP‡iîýáq£ñ‚¹6k^›³6åž¾´éÛnóìmØÙG©úÅ£òÒÚüÀÕóÜt‚,Qè¢\W
+Îù¢³Hoô[¨]H&élB§’¿<iÎŒÆ'£)“LšätÆ`®Î=CèB >‰¬OS&c1–[pà‰Uyu¸¸§û®þ«Ãý×ìÆóNã'vã9
+ˆ•–Lþëëå‡\ÒÈ÷œL2é“¥ŒAkq¤‚qø$ÒàC¢Üëk—DyQØc¸§OþŸýzýqã*ã8î
+U_”›D"QA‹PA‰@¥I¬µw“涱ÜÝDZž™IœPP²i¯ÏïÑG~¿;Ï9ó¤ö½]Æùºµ6ov”p“3Uô$lJ´'“o0Ÿ bRúåv¯îL‡Õž¤~ðcˆIÌÆF¸ôeA[QψIPY1©ßo®7xGvÀÀàèΛçjÖiô$Ü-IË ßgÖ2lˆc’ø.Ťæ‡=I !;e0ò'ZƒJZóÝwzT6‘b3;—­ )gå— êÉ S¦ôVG1¹,ø© þòžxt™ ñû”þ´É õ$¹û(!b1ô¤êÓÛßÑ®í†ì-ˆö¿Ô~ô¨Å$’"«3V[ðf‰K@MRâ+‚ÿ3ÏŸÛePI–ìa~™Fšp™ç2¹ ƒœñÞ£qZJZ—¾¥
+0 è¶Ì'ÙÏöÝ0$:HJåÑ\¨‡ý ;``pPL¶=N¿¯ìMø.›H1Eb’~«Ô“ŽvsK`TO„=éhÄwÑ“
+émýÔ crEð¿?m}÷ÓF!©•e_JRPF
+7øõb1‡žT}<ì€xà´•4zàVèþ,&µ™ì²yeÁºŒ¤TõäJ=©–èqŸñùÌ#cz>)ÿR’v:¬ž5Â[Q§ŠˆÅГÊO¸"¥õ¾5¤o)À £c’ßÁ^Øm¬ÎXÝy³ƒ¤Tعš…žT=ë%o¤-øoKÔ2¬˜ÒU~cÒßîÍ õB£òô>(h1*éàh¨|:
+§ØÞ<pD “úšõŤô›Gº¨|—ùi-j‰zRíñÃŽE»QË 'î
+còõ'ÌÆz>‰wâ­TÒºçè¾£QEx=©ôD19—ú-Ædø•!}?†Åd!©}3§·«æZƒ#)•ònmDzÁ¢˜ly_|1^Ëç—N±ô›d`Q0ÔÂl¸9'0ÊNn<X
+†(iCÚ4P+¾ $ Š
+c€T6•©^b§íú-–Û4¨¼ïœ†jeË·O|÷zë©S~?_îq¤ŒC—jžÜRÑrÌ–EË“¿>˜jìâE›k¿ú.C-ün#¶Eð<ãI«O{€vE5‹Ó„Ð&E¤N³& “݆
+ßåÚw&BÈ ¯è¢ÍgöðwüÔâ´)#Ù„˜S’´£]\Q­ÖVòìQùâ>“$I_jJ÷éŽXÕ,÷\^³YÂSðd|'z’¶D%Ë{o1í›!ä…‡qx';qÀì†öèèÆÚˆÚ><¹a˜ XÂä™/§¾ö/¤ í‡:zÑ556hzÞó„^Ï`tN¸úʦ]aÔr˜DhKUvXÅeg§–fĤ~ü uïbU4u»+’&gËbÖ8õ”5ñ€I˜Ä nÝ£ŸT¹Á¾c’%NæáÉøN~(ôdÆXÙÚ÷'Bh%º«é=øõ½f»j-NK2z]©ë§Wô"LÎy't é»lÄ^fZ÷êƒ&Éa,·- EžŒë„K¯v|deKhß™¡÷Ds8Í^{2ycÊ"~ttû­o×DZ§©`‘©ÖVò­‚xé³hó²ÃðvÛ «‰ªd¹—ÙN–È“ñ“ù`õ}‡»ÂʼnCh‹VrèÒfg‹Ö­iÑ™ÔO ´ŽÑ‚¶|Ù,Ií‹@ô3&ç•üó³Ö7örúÓ~x£]5K~àÊ <é'àɸN¸ôjÇG=‡=`jß–¡ÿ}ëÓÆ‹ŸäWÇ­n¤ŒZ«ž\LÒ³­äo¿`Mì2 iCûÉ|µa’'BN$àɸN~(ô¤Í<'x[)ÝÛ!tÊDJ›ÿò`òßÇàɨu¹O®&ç¼à7üéçR•,±ñRÛØ6¸=<·ÉÏÊÒ{.Íqí;!tïèê&O6vóse±8-@ʨÔmˆkãÀä$b²­ä›Ãâ•ýfÙa%˜ÜŒ*Ù
+ÓsÿÔMzìC*ðd\'\z•1zûAûÎD­®›½ödò&<Ùÿu¢;e]ª xò^˜,ÉYo`Γ§ZõAƒ>©ð
+Óýì£9®œ$Y"?LÆtzK_ÉÒ14*Y|Ù!Ô¯)7ð$½UÏ­¥±
+Lì&\÷üPby?èÞ“¡u‰Îr!m¼¼ßì† éèFZK—GÉÿbrΓͲøñc)ßeE›+Wÿq‹ytÛT?˜w»» ×]ÙÁ–ð]®}["„Ö«²<O?“ZšIý(B«îÚ¸œõˆRÚ9§S’!&[J¾9,^ÙŸ,9Œ&µG˜¤U
+=™
+ã“
+7]&!êI
+¸AQóש'=FE¡4b2¾‹&alÈ6>“
+¥ŒõôÝüôhêBÛé")ûÇ;õ¾ïIúþs*ÝQò•‡ÅäçY9c"à¦1é²’»ãz2–k¦lºvy0 7>
+ÄdìÖ•MW.oä¹ñ€žBgDtÊ¿v(uñ˜Xš4ßKp}´G½ß“³¡-ß8,žý‚]ÎâôéoôŠÐ^ð×÷‚žôÑ“ñ[J›^Í󀞀£c¢œ±ž(òNÃY™’]$eo£ êh9[•Æ£ñ:1ùv“¯tŽí᥌e|ÈáÖ áq½'èÉKèÉø­âp°é4 ­b
+4 Úô4@ß©¹Áß¿N­N ôdÏ ;ÿtSl}OžªJ*Iúpü”ï±r–G l?ú
+×¢¨(£'㵢đÂgi
+Ù뛌&ÞÌÂÑý¼ˆ!&;ÁÄ=Û¡ @OÀ¢çK1ÅŽ=Îú5ó:’2J.778&©$éÃkûâ4ôRJGL*ÈsͽšÖ¨+òãèI…N,ˆIñèçij&}`K¢¤üé—ësEvDÁÐRÛÏ¿îý—d“}ÁϬ“O“I­bË_9¢•3„ÍDþ‘a`à(r\áÛË|Ρ@OÀ@·—²Mo¬úߎ$Ög­åiù)„ÑœRð~c²b]ôø_žµ¾û+$åïH!n~ðF]1—GL*v‚×ZƒFŽ‰¹i
+üåÝ• &•æèôNA„Íü®@Oªt\á»No”¶VË0ùÛ
+'?îÏZØt‹Ðüw
+Ù«
+
+Ûõ—w~Lº£wŒÉ°dú_ž–ŸXª¡†¿Ò2çoÄ‚ËϼÈ0aL&5éËQPÏRK0¿0“*¹¼?‡%‰ž
+G»C‘;ô­0œSOõ!ä’¢ì(m© ˆ“ @bcµÓÄ_v–¤(J–k EÛ@m·…‘KÛ8§š¸h/M Hhb IY–eIàQ}v‡¦ÛÀ¶Þ¸rç7øb¡ŽðyH~¤Ô¼ò0¶qòi_’ð¤VÇ·°ÙäS¾‡!=“˜üÅ#_¼m‘L¶Ä¤g˜¢ÇÎõiõ¾Ò°»“à= îæÙØÅçX.‰o“÷7Í›=ð<©ËéÌZ¤Ød†áR‰Úÿè“'Ÿ4É!¤‘¦àsÛÀd‡”÷ªêq¥ak5kÁ‰ƒýôM·MJ(¾PtKx˜ôžÂ÷¤#€IŽïÉìØ
+d˜”ÿ!ý†Õ©XKµ¯tkcÆZ*yÇÍ…ª þÁÉ( ¤ w¯<Ì\›*Dö bÜàìû‘ž,“$=OšÂV¿–¡p'1™K.:|/˜lÓ¥À—+<¹ÿ­LZódg¬4bº5ÈëHâ<R¦ý†+1 88û{¼‰ »½ x³#„‚®˜2sIöû—†æ
+|Á‰?$Û÷dÃåëÓê}¥Q3àï׶˜]‡”×AÊ°''[É0'Å&lR»3 =™brðNG]>i&o练Ɏ[îU­ÖlL=´tŠ _wù“‡H£Y œø{¯D'†òõCÁ%A¤)CyŠt‘)µ8“tDzP¤ÛË |!B!ŽDñëŸD¾ÊóEg ‡ìÌ“~§¬ÞWF/ûÜVs¤é'éA÷ˆ\’U/!
+.a{ÏÒ0£ç•Ã‡Ž
+.²Ä•ç#_žãuÑMLzb)Z‹‚¯O«÷•Vµfc+UïÅßøéA¤üãË)•¯"
+4²DÙ'¥ÈÜ)58=™2è6L"„Š>^&Ư~Ì“Ínc²#–{UõÄÒ­µš'ùí T’ò«ÿÍ Zå;‰ ¤Ôëøž$U:rîiõˆ
+_ôÍ’K² £ì³·x#LJ®4K\¹¯4Œ^ömΔþX]ð[ãüòX„VBùf¢@)5:¾'7}OV2L¨Þ=„Pøi“³Ï²›gcÍÀ0éY¥h-8ñµiõ¾Ò§óVk6¶\‰o¬ô'éNqë¿ü|$ŸT¿Ÿ(Ð$)éyùÄ÷6AÊß“µg O"„Hb²’1ÿñflÉåsa²ÓrE½²tku*F’ŸßöŒæò—?ŠL$ |õ„»)¯>´ R†õøžÞ ‘Ѹ•oB(LÑ7H>IwUóÆéhÝáóÁc’þŠºàÊ}¥[3½ì;š/‘²)øgoñŸ2ºq€”á®CJ‘=¸ R†òHO¦½Y—Òð$B¨kѧJÁ6‹)ó¯§b ÂFÀ’l{²h-8ñÕ©˜rbéV³´ãûýyZŒ›gcFÝ;è›HùÒ¢à’¤t@Ê°ߓŤA#v齌·3B¨ILÒ×ODxRzûàI©”;e«5 Rîkw'w9¬¦OÊóÇØDÂ
+¶yõÅ¡¯ó|ÑÙ%0öý¥Ke®œXºµ\±véIÿÙ¤)ÃHÂã{’fZ;qR†òCõ{ ã·/Dnçy]&¥Oˆ²kÓꉥU«S±ù=ŒlÞ'凯G‹¶w%)ÃH¦3àcòt:B­ŽxOå †êßè3$—0.e#·ÎñºP†É¶O
+|¥ªžXZE€_¤¹ï”ô\(Z×ODh<Rª^ihIyä)Òˆ;
+èÎrkÜ'e’‰´úýGÁÕ!%ýð ®àôèñôö±¬:ªW!ÔGåÆ{¯DNžì¢‚h®À—J\9±ô‰è¾\‰w÷ŠACl
+þ¯w¬‹Ï±‰„R†>"¥°éÒj¨¦ÎÖÇž'Å3†°J†)_„P¿”K²wG¾Î÷&)‚ ¹w­¦Zút¿ÖýÝ ßVwø§gcž)ßH™åaO&nr°#œÞ<r:%›æÅäÔBhË“¿;¹]à„´ÞÇd‡"+“VKµ²ôicÆZÝ_ú… Áoú¤¤=)Cœ›6Ki&RLùYe`
+UöB.•€Ét/MëO0ôtx!Dùœþn‰}~ÆyLÒ¿îV]=´2ÒfÛ^åCÝQ’”_œuÞy™ÍæpÀ%(I—͹À䈬€‹!òI-ðy÷Bs9ýçß5“k£ŽI᛼AÎQn­ŒÔ©{Sѯëp篧íóGímî«¿Ë2=d¤7¸»Rš&Óº4M 5þ³ó‡4Ù<‰P¶£'À|ž-¿È>;=NGðÈc2ncÑR­Œt»¡`¾’”´«AJåÅØxÿÐwÈ&Ó·ˆ‘4¸p#§ÇB×äžÎ£)Óe6ºýËyƒ0ùÉ)«›%L^_°×«Žrhe¤{-G^óáO9&%½4”j2¾Q/
+LòÒAHi˜LÙ"Còɇ¦v¶øMîÃ¥ÏÅ)3ô0‰Pf£Û¿âÕ‚ñçŸXëa†0)¤QqVgsI½µ²ÐVÛ^Uô¶B¿”ööŸ~l׋âÕ GÞÌpé‹þ3ß ‡˜LÍÒ4íRIÛ9²&MÓ?¸ýáV ¬!$)n+ÜYe6ºý\£V0®œïÐYO'¯jã •Ñçí¦ÓSm­,´uÎ^¯)òdÔw>ú‘Rù CÒ /eO— 5`2é‹ ù j'#®Ã=%ÆJŒ¬XÌHÜPe9zT¢wÌ?üp¼f“}iTœnÕQn­ŒtwÑRµÇäïí)OX"£pOù%tû˜¼T&“»´»ÀÏî]3ˆîîÍ)“$É7e„Pf[prÞ¸||l5pnd“Ò“+ÁĽH9ðzçìûK6]mŤ z¢Í¿
+¥'Ý}§ÓnM›ty!´×¸/0yþ(ûÛ[v7t®%ãOZ×ì•`bsI=·²P'LŠ'ol“òó3ö{%RÅJæµ }&¾»ûß|áDQÀ5M,÷º$)KßàB’cuq…û×\ùÜB銞„Éöö—SV‡'èOfwê­5òõÎÙ7ëðÊÇ'HÉ#RΘs9§­‚'•ÛÿR/)ÅÈ–1‹BrT¹§kœû,pYÿ
+û}Æ+Ÿ;B(Řüä”Õ É¯GE't”s+ ÝmF\õÄwOŸ;ËþéKl¤T÷È’_šS¦OÅÓc•f@Ê=-M‹//èò:GnW?q„Pò£gE9o
+óãÜ—Wª!DÏÂdUb’;É<¯ÞµŠs³®ž[#ßVÛ¦-šÌ÷ëQî|ô_öËç·ãŠãûäT èhw–äŽr+ŠþP‹»KR*„B›¤@êE` ¨kRäÎ.Iñ‡tiaýi‘^ª¢ArÈ¥¨ÛkP_Úƒb£¢DJ²lÙ2Ë£úfgI»rlX?gwø>Xðàƒ<ß÷æ}æ"WÊ
+*eœ¨ç ˜Oh•)–5Àˆ´Ð‹°ŽPÅ…èèšù¯øŽÎÂãõ]lx™hà¨ð7&Êäñ\¢B{Œîµå—òìÔ­xúäúhv„RÂzE¥Œ,¤Y0™C˜>yÜòáôFÈòÑ ƒUJA)™¬ÚÆ_~œÞD™<¦KTèn33”­[jÇ»»_Ÿ\'Øö§?½^ÌòáB¥Œ‚ï’ðkBŸ<~UŠc„>ˆº«7òDœ³çÊA³AÈ$ðñ;)± Q&%ºÐAG¾t)K‡ûä^Ûêy4ν*þ¶ oú“¥Ä{Mú°O8p×Õr\r@x"B™<¹òXt˜¥ù)ÆP¤ž·äÇŽ)Qž'eRì>¡”ÈqبrÛ‘ï]JƾИ·k7l†ÇJ){Þ'¸ë@o<‡ø®qÀ°Nª4M[-F§Êl"N¾Á•A§Š2y:q¿!߸f°l W2÷ÖZì;fj#üñ§·SWfåüd2SËøúÎׄíøÊäiÕ“¢Îœ)~ì.—y†V‰ ê²hG™<y…è3úߎ|ïR˜á²õ ™¾•÷‹ôCÏ£wÊô÷ÌÒ¬.}ê'!3Õ‘Lî£Lžriš66v6ó³y
+0­A”£œ%øAj-\v(“'ëà9{-ùÒ¥6Úx{"Zw¤”(%ÌôÙŸ(j9®1Ì5Æ®#M³&¬À*=6²Ê¹X%
+•òêë&(%“}-( È$ã7Þ×Ç&#M¢°d1ŠƒÙ:„UË‘ ‡ƒ€ ‰¦µ4«_}͸ùS d2Y+8‰À ÷ÝkË7.µÙ©OKÏú°ÀSn˧ÿzßZù.A¥<ñ‹®ÊdPH {ÑP&ãW‹ra3/±œÎB«ô]ñ
+ßE‚<X[ “·.[›(“gœóî’5\É dK—Â<lñfîÊÎú½“xãR¦3JybŒe²b§ÁUŠ h’±®ÕbPÍF ž'*%‚Ć2)϶:èÈ—.…ãíy‰ìjø›·üH)³så߉FȤç–3AQ<†2™€â1iQR0"|Ñ*$†Àl–fõ_¼JP&¥°QµöZò¥KaËÖv-‘Ý/Ÿ~ö^¦ž3P) È$HPHí£L&­ü±Rþð«~h’ ”bÐ*$À<–³¤=güó}¾¶Ö¸s“Ãý†|éR8á$úäºPʪÕ÷èß.¦7TJÙ—Fa#™¬Øé}”Éd–¦iãàع´gC¬¬r±ô6C‰…Ëä¬2yãR¦ÏhBnÒcïûtБ/]ª2\¶¶ÜÛ‘R²H)+6®ÎÃÜrB& &|”IJÓV‹Q‚Ãß°Èj9‚C ²€éã29ÏereRª-À„Gºw)Ì£ŽÒžÜ&Mszýbºj£Râ–@6<”Iµª¸ 0›ç )aÐ8r–Àƒn1ktæÉ?P&c
+Ýdôó’õ˳4«ã¢<@{ÎdŽÎb}râJÓ4E¹7lê;|@Ü*åw&‚$!“ÀŸÏ§»Uke2®ðt¼é‡-:”í]
+³¨ã“ëá,ƒ!ß¼l]}Í
+³»ž³ì O¶g6½*åbeœC³
+$ÀÍ_û¿°XñÆ;™T—™Ëí1”ÃHƒ‡¬åIà>~@¡C"Èña(“ÉRÛ
+¨tïR•Á²u·f©:ÝæëïNºRÂeØš3CŸQ‘äJXkl¾Æë ÿ ØcàfS,ŒhäIC¨cŽø¡=²§—Þu¢0_WfkÅÔç¥é>£kŠnLåÕé1º×–¯^ª²»¤¬O®‡> ß~¨”µœQ±'tÏÂÿz©`²Ð'#Á’WÅ xV
+íùt`Oùš=Æ÷?öËï7Ž«ŠãóðFÔ{æNvfüÀo–ˆwvv—*µQ«J¨•*0•
+‰DÓÄ?öÞ™ýaïÚå úОúB¼ „J_$<©Îz½;¶ÙÇð¹ëõ¶‰iÛ{wF#ùe=ç{Ïù\&C[›²ÑÄr!ȱìö7Á&ˆÓ'kn¼~Ѻ{Å]çžÆë2 @ ¶*n{ÕQ®^ºQwÛ+î£e¯ÁÇ”wùTóƒç†ð>~'Ÿ,¦U)+…DBÆGbe!Ÿ˜z/°EÀ"Ÿ…¾-|tÊŒWXüb•ó¬vÁFã¢<ë®6NêHýâP&?p›‚drèA[‘³_Wm_š‚Û
+5?&PÊFòüÝÛçà“‹¾ú1ÕJÒ'ý3p˜|R]]ž9åM‘µŠã]9LL2 ìQ
+¤äŸLrH‚PÎà<ɤv4øØÎ’ÓV­^Z‚¯ºYv?Óý¤`¬óø¼ùvFù˜RB¬(˜çM( ä“
+ÊH4J»¢oÕ§X)Ï¢ ¶G)<ñÆ®@’C„*pç&ÌŸ½Êî\q7H&5¶³UQ¯^ZÒ^u¶—å-îR)E÷7ß?‡A¡|^õu6æ¬0H%›ÒLÏOª©ŽRŽ„è…ÏКrñ{$$ˆA@Ê$n|Ÿ^vš$“znâ‚°WSo_Z²[sSrd¤RÞ›÷>|ãÜ|š”RŠ
+Ô%
+Xâ3ä“ÊJ*%ê0|ÿ,Ï™"g–ò,Ê3å9!¢+“Ÿ\JdRõÚ"NôtgÉQ®^ºÒŠ¼ÏRà“÷¥lrï?R)³iÙàÒ'a,P˜ ä“* JycºÓ¼Ÿq?î„¿DVIêÀ1œ?É ’IM<(«÷.-i¯¸[õ-îg–b¥\ð~ýº{¨ò ÖŸ!É¥O–Z•¢:,Øž9{áòœÙµJ¡:3‘6pè²Ví‚Ý•IòI-¬ o¿®Þ¾´äѲ×àcøÈÊÝ·85…÷ïkÞõ×ìk,Kù(;í9‰g©Ç' Ã8Âr¨ú[†ÁÅa/³#<™4+“,
+:VInI§”É(oýù½ ÉdØ^r”«—–@Ô›¡—Ÿ¼/•’{w?p¯_´æ&Ì4(e”ýDŒRc”սёƒ¦D>Ì]+X§kd•qjÄ2éÇ2y{6ƒ½pŸdRw
+V‰Nͪø^è3´2 X)¯mP ¢?sÖbÖºùVf{D0”/#¢o`ï7øØÎ’ÓVm_Zò°’Òµ–ÐÞ_~ì” ÖBÖÒpSøE£ÒTTzÕó–aLÏtZvµð2Z)ü8¥°J¸¥†q%ˆS&–I?–IHÉd:AÓ7Ë.ùäɲ¿ÒGËé=Pkɳ)¼?ü(å­_ý¸;YDl’ÉÓg‰žO_…†!Æ;‰FJ*…Ø*e—•' )“¿•2ÉÇH&Ó úÞ ½½šzÓ½z,T©=Y]¥¼=+eQ/¥Ï0gª•"ªcïb|¤è›²¹ÕI»k˜ÊóFƒ É$!ÁÞßYrÚªíKK”Ü4.©”»5›ÁJ©Íj–šå÷;>i†:'¢:nA){;,n±ŸXepx}P<‚4®MX½y£žd’@
+ÆAòâ³Çä“)(#±Ên£a•¡oó$¥<2ªcI§GG&/Zw®¸$“ÄQ ¡·¯Ú¾ôŠÞŠèÜ}!iD÷æÜ_~Ͼz¾£dÈ4‡0
+ûÉ$ñlÈ¿WS/`š±_w›tŸ–7Œ¦¾ïþüU6?„J)p°0gÂ%z½‚*uÕ#–"À#¾eDy”• Žƒ”ÉÚ”ýן8´Èˆgg­ènWÝöª£ÜÁ4c³[åý4¤R~zÙÅ°ÂÈ:¥,âß,ÆG¡ ŸL}†ïµÊ³âàÞAÃH¯L¶Bo­H‹ŒxV°ß”ÔÛ—~ì,9Ê›;˜`:A)1¬0²²C³|E"“<gŠ‰— !É$•,ÃøÁ·¾)_Eþ,¬²å¡%ˆç¡ÅL>”ÉEd’xv–Û­Å
+´¯ÚÁtb¯X:ŒOÀ°ÂÈZº` …RâFyxÙQh$“TIcz¦“‘7ü8'a0y&ˆ'‘2Y™d˜ÌŸ“L/b³]U/`š±_w[Q|$•÷w
+‚H\A¼Ä=xraOjVDÄÍEI`NÿšI&ó£éãø­ªžÎŒÄ8™éš§ë™Ï—7E69t}ûy^&™§+¸t€©×z™­Â“/Þ½%ÖvÿpçÒ\ÞÔ§Š”"é>ãA“§nB¡Ðþ÷.ÌŽ÷W†ˆC’(Ày˜¤S÷÷ß&ÑÄrît+ºY‹H˜J W"U|C±~î‘ò®KJéǬwÒRÅ”!’3c[È1 FÒd÷I2qÇõ…ðxC¤o)BÇi)¡çLƒNÝÕ0‰&Ýéë%6$5åKL™¶ë¬#xËý¶¢¯ŸGÊ;—ænÄ䟴T%m8ª<û9â„%€ÉS4ôºÇo¼¼÷§œ6è÷…•Ð I¤@Kq=oêw¿;G§nÛŠ“h‚Ñ…Þ|§!ß`JÕd}ž<ìv,þYžøÎl6¦I<i…‹“éÙ]`ò4M(Ê,Ž^·H:;`%5bdÉ‘¤| 4©L^r1éž½ÒϤ^U6\‰Èg˜* —ÙãrßÖCæ‘òa–É%¥íBBÄõ]`òÔ Irü®³oÎØIÚƒ~V!I¤\¹˜ö›ïÌ>&‘o­øzI¾Ák³i[Ñ–ì—”èp뺤¼u1œ3Oú*î“QLê#d„àIÕ'²÷ÞòíLH˜†ˆ;Œ,¥ ±o+R£1ý—ß ÿ;Ï‹ ˜DþDæéX|»Á†² ¦Rƒ&뎯íKì!‘Rð]ç?y;œi'|›WçÃôKCr0þýXÈ,>“¤{;P™7`H¤dt¢~øÎììs×ãVB¾F ö´*ß`ŠµVÄ7÷¥÷°'ø§×ØûÂ9Ó8™“–QN;±×–
+\CèD£}£­#Ig˜JÑñE>òBöm‡”õÝ'R–Ó†ˆ"ixØŒŒÿcÓχ¸n' é×=B¾–3÷]LöItâµÜçf-"Ý`*EŸ'¾ËGßI—”¾)¥\R&'vØ’NK)¤VŒÏ3,L*>¡½ß ôÒEÜ}û²o|„|
+˜DÒ£Å[+ò¡lƒ©Ôvƒu,Þ’ýfZË­+øGïÍÑí_ˆë“2€íÒT$fvÉS3DJÛU¥z¤DJF+7õ›çûÀ$’íÝÝ; ù S¦Á2[+áK}ŒtŸ]‹ÿaB¤ôþz1eØ mÌ ©ÌÁœÜлö~>ˆä ‘²R"…¢eΙFc!ü·έÙ|÷’ÝF• W"Ò%¦FôIÒç O§)…KÊä±HéýÅrÚ°š8û:¹ÂÓæôÌ3RÆ¿$ %R$Z㼩×ô{W"=Áqé éÑ®•¸t†)Óp™mÕyÛŠ¶d¿Ù@ç}z‹ÿöÝY:3—ŽJJú[“ºˆ½F¢È,“§qBîЖ&í$H‰‚Ý“óa²os\7h¢=$ü†²%¦Lƒ&ëÙøµ8ͤçjß¹4ç‘ò§n1åÈ¡˜ÔÉ·3Àä)žÐè틤³ %
+n´º…¸^_ÐG˜,À“hZ¢m|R‘Ï0e"™¯—<9‘ÍìXÎiI¤$O.½ä‘ë<“z>>ãj˜<í3ÞÛ!¥R¢ æœi¦^Léº L¢©‹’ÖrД/15®D6ªÀäÄ–³mEé¿úÖl6¦öÈuŸ¥”AÏ]W6<‰ÙÝÝ=HÊ"H‰­k!î<?zo®+€I4¥mÕ¹t‰)ÓvƒuÜ/»ôת@ô1v,þà»u1œ3Cžºå4ýŸ3Õ·^!<X˜ÄìÍARÚ %
+H0i9— 0‰¦0º²—å3L¥z6<9Éýì þ ë2oþÿƒ·”rPLhĆÌ"0‰98H©ƒ”hú;€IL¢é6“VtДÏ05.3ò¹ôתR«#RFöõp6¦ý/
+QÁÀ$æEãmHf¤DSš‡É¼©ß½4·Z
+&Hã‘’ž#RʆBl¿þö,Ý m+
+L¢`åýÚªó¡l‰©Ñ Éú6~Tú¶®K¬'ø'W"õyƒ0i%Ã#
+¤D'aòçß?t1¹Š‹<ÂÏã²|‰)Óz‰áXð«ëZÎg»z9x;$Ù"%ævæ)ËiÃ)‘ÿÑŽecÚô^çÀ$R£Öë¾Ó”/± 7h²áJd£â]úkUµ¾ˆÒ³g}Åq€Ob&3ûIYJ¤D~FÛ•3›çû×0‰k³‘î1.³Íz¤mE[²_¨ª=.FéãíZÜA
+VâðÉ°•ô$Ñ*#À%RJsc™¥þiø$—ÐÎñ»0†R‚.±ÙðÉdL@&è@ƒ@»»ž†RŽ€š+–Q,£8“+δ¹q¦h_=ŸDX³«”q(%ð8wr⧟Ÿ¤¶‡LÐ ÃÚ¼jå­í,¿’z€ëIQàþ6ǃj\ÑkNA[f‹kø$Â^¥œñ”rθ%ÄòrþäÄ?;ù¯s
+2 Àh"Vâ² ™<4õ4^WGú«ŠZU‚6¸và“â=J©IF.œ
+wˆÍ„c³=×ÎMïý~Ñ_Ÿghf‡]áüÃùS’É·Ï©Šƒª`6SV‹ÛÇOV™£d‹-6秋1õ}·Àᓈ/ÒUÊÔ#÷å ç?É?I}¼G½ö¶¹ý>š Ÿ;9ñôG'žú#Ï~,üüCáçÚ¹ð†øÎIó9³=3 zöêÛ+À{žaŸ†¥kŒ½?qz8gdò%È$
+g8ÖŠ®»& ŸD¸Óyµù®Õ̉öÅ^/€ZŽõ´,iUà®J
+ø$
+ô<
+ˆJ¸¢)H ®º¤‹A]Têª*CpŽ&ö½NÐÍl»LÿƒnfÓU¥YTª*¡V‚‰%±ûú6aÀýî50C00D‰?ŸÜ÷Õ“+osï÷½ç9ôöØ¿£Atò±jJ|÷LGq'¸Îl/£-~zG²7 0‚œ„OðhA„W¶\îm5”ž-Ö2è™ïVôÜÌÇ*Z¼<Ó„!ÁìQã=Êd™¿FÀäÓ-ŠšVö"`R!ZÏZ®Í¿­æÒÊ øä» |²;?Eï*8ÓÏ0KÎ2ùHGܲ,Köö
+w—0™ WƒÖ„aÍÄ+[í<.­ï¦SU­ZyáìðIdü ¦®häÎ"ì…fmÀ!¥¤aßSsÙ,Z¸´¾­:ù˜ï“Å‚£>‰ðĵÅà.dì‘­¢ôÛJ À(h5êiI5˾ª†â:b-#Ñ0o#%ºE?+IFà“Èx£ý‘û¦lõÉ'—Qw`ï4smÀH*Á³3Ï¿§†â9b#Ÿ|µ9á.Ī:æŸìIdü .2}'úlYöƒ; {o
+{Ó0yÐ=k=+Ù7Ô8\òɲE*Îþ'‹”¨k_°k>‰Œ1+þ¤m;Q×O–à“à
+=Sb#£VS2‘HÀ'‘ƒ?]/¢®}¶,û6€PÑ.È
+wñ0iO6süëi"=[Ô´Â-µª=×Ò±‡·äé“7È'#‘_G‚p[rH£ýÑòÊÊsÄ“%Å^ lôJ¢ž†Rð
+´$E¤Fìj®-Ö3>YMù#D?ÝVä“ñx<PÊ |9°ø£Õw¢ƒ»²î´ (
+­C#-»%þõ4 ¯lù÷Ó0—‰Vä“ÿ¹‹ÇE>ù“™™óç’Ñ™™xH$ŸDö#þ=Òºó>½ŸD» +ì= À$AÑY°H\îõ4:Ý襑S…´O‚|#£ÜŠÉøå⟞={éô©ËG.\?}ò|Ù¿øSÔ+KÚ¸'‹ü‹ÀKz%QOC)ø–JJ6sµù×Ó,¨LT&)ÉþЪøä?nž8ù³dìâUëì%õñ•óç’¤”䓉D‚”’[E³óòJâËä’b_y
+Ês¢ƒ»’}åØ›tHO
+ë›8†åT›ÃìÇSsmÜåßÖ•$+F½".÷ÑâPì(’….
+ŹÚ¬›6ã:T†¯“‰˜Q•‡ßµÖO"ùŸ4TJÍ•WìÆr'xÒ(9“ž”$ I‰ë”ËO= ÷ëýÏ“XN·=Æ?
+Ð+3ó›8†åB0 ë®ÞÌgS[=%ôÕ;Ë‹/£qUæbÔ'D}$âC‘*±‡,
+Û@†S™¸8½e1üô‹[õ °gþÝYž4šíùUÍÆrgI­Ó(9+ÊŠ'%IÒét¬u‚KkKöäö8÷Ó¤<hì'ÃŽˆÞHJL %Õ'3–þ]jÉÄó Q‰Òcò„D½$âåáÎù~HØ ;Aöã©•bAþñ U"})i‹`Å.Ú|'V(*>¤DtåÑT0Ë|‰‘éÉùvÔÆ8Õ{¾ÐbR–I6ÓeGùºXé(´Z9›-áÉAÖ:Á¥­E1þÓ/'Èþ|ÂÅ´Ñֽɲ×ön”‚ºÃíw4eé©’¡¢à·ÜÇ/©Ãt“…DÊyØC=£n®„Üzu °‚„ïÚô‘^<CO³ /×Æ Qˆ÷¡LÁ# 8£üKÖ&<£'A˰ß¼†‹æëàÉ‹–£ä$;)«ƒ“Šr§ÉèO¶¶¶êt:ÖDÁ¥å§»eï3}lœß›DObÚh{Œ@RbªÀxi¥"Ð/žI)ƒú(óˆ*~±‡À]xA¿p×ò…=qõ© µSõ͸òÔÇC¹ò¦fTª™>¨ø|¤{1Æ~05“ìÉç£$ÜùšåïI°Ÿa6‡ÄeŸøÅï?*´Ø/ÔÔåW5›æëàÉÒ;g³•ßl•k£àÒÈJ<zìŒs{÷ù]æ3ŽaÇnk„GOþß[aý dþ­dõ©‹x|ü²*øJï úÔäSšëHSŸ›ªoÖ­
+àwð ä˜jKЮMî˜|û<
+± ûÁÔJðZ½œ$O|vØŸ Á_
+Pôš 3>Ào ‰ßt™Œ’C’®š, ùUÍ‚d7–; ­V %g³I’${r5Tpi`ùÔ“ÛüNß›DObZjwœßW˜ó,[\{SÌó¥D¼|²¨—~HÕ—(ÒÏ/)êK´$ 0ìáÂ"'
+sS…ä0HàÉb³<)V:€”çªo(ž”I©c­\¹¿è&™zõ€b2Æ|À1ì$mñëÊ$öä;Äko¢`\}ê|0O%_ßRȧ´ÐEÂr ‰ã|'ÒPê›uq³n9ùdæÔœ;xê˜ß@߇àu†÷ZÙH?Œ°ŸJm òK]ÜTÛ{áI.ñ‡Í;üÓaCØkðýºÆ(9
+ji²4˜.;ÉNÊꌒ³¢Üi2:ždm\¹½ü“ÛxžÝÿLd>×vÒ`ën‹+ÙÂáªÌ¿Õ£>¢.ÒŸ¦¾ÞTõQéy¸°‡$K!ß¼¢>·^UŸ+qGpå)çgQŸ‚ä9¦Ý”w6›²'Ÿ
+-v“¥Y`¾ž+àI“Ñ©"¥Žµ[påâú§¿ŽÏåi‚4æagiã.¿ÔËÏuR1Nµý<N»#Ô§:ŸAûaš ö0<I­¨„°bAö#©¡à¸Ô=OÂÕ&äâþÛF&uñ«›ùËÜôm.;?z±‡¨= ýp×0Ó—ÿ‡Æš|KK‰ä0HùUÍÅf'xOž«¾žÄuÔJìŠ ·ÿ…¸3Î1Ÿh ;c›Ã"\#ý<Ü^A•ÓÙº;`Ã`Ÿ«‘
+Áƾ`bâø‚±½h[•4Aix°ÍCxˆ!)ICKÚ7Û‹©ÕTeRÖ½ë¶JU¥M{ÑfmÕM—'ìÚDiE”ec¿s¯íÑð䛋Ãù飫+„ñ½œïïü>gHñ—vÚäPšœJÓQðIçŸÔm¸¸¶Ho¥T«ÜÔ'i­WB‚?ZFÿ|2.u/S(”rõ¶ëcÀ*'}²°©Jî
+^’ºs‹»=hgö‡±6t7€ß;¥=X~|èrÂ>øvÊfT"x­LÎ_?¸Èþ³;ÿHÝðÉ‚Ã6eEkà nU‰[_éNùdQaUJZkŠ„áшv›²’w1…’qˆR
+ƒ5±mY˜¹°«l•Q«¤lDnež6¼ž$@Ú¡¨O¦ÏÒ¾?ˆÇwdõá[:åïœ(
+…Ññ²¥Vk²k¹µ…WX£ Ü2å“.—‹ú$­µµ<Â<¾ÎHÞÅJf‰'oD¥\½mÎÙXé"V™sæ@É6˜æ“2ÐCR?LúÏ<ÛM‚½Ö'¿d^•¾s‚ø0ñÉÅËV¶…±Vt¯‹ùå+zâ“&€¾Úúñ9&ìC¡¶Ì+%¼Ô¤WëÅëød¿üë®o*ÓxÑ'áyÀ' nðI\\{¨Ä-*%ÇqÔ'i­*’„‡CÊø5´r“ú$åEf­R‚,L[˜ÂSíHÜi©XîqÀE“œmG¹b’"푯# ‹W0h’äm¸û¡ ß³Yß Bà—~RÚ¦dR¼ö8K§½øË,uáNûì{ëä¤_¾dàHòA›Nmr(ŒÑ©¬hP–5èJª7ød‘ÞžòI—ËE•’V¢n >y =º†–éVCyÑY_)«ÄÄ*=™ßÀ)¹˜$Ì÷¨ƒO¾wJÓRozÿ´jÎ?D’?Ûæ@h§|8Ö‡7Š7„_òÌ!À½úñxKÖ}rB¸v6Á!µfÁ'Íup-0ó¿mÔAö “J¸¯î~øÍ€âó®|%G|²¨´|RWqTmáή¯tk­ÖC%nÑ'¡¨OÒJ”É•·XÉû—BÉ"É›M”Rdî¼|ÚO­rÏË Òñ¡i/þã™ü@ƒ±€#Ãý5Þ<ÖŠ@/wyàñ ·¥|ra€yxUê6ÌâÃòåëøÁEÊúª¡)¯ì‹|š/OùdêÆ^m½sN̸RÎvËç×õIÙ™^…ºŒ×pN}ñI-× âÜà“£ nŠôvTSSTØ>ér¹¨OÒZq’ ,“|2J}’²WØB)…mV°Jù„`Ùž)ia K c=À>«èr 6q¬ÿöñý‘vHB†gzf †;ñ&’
+±dKßz9A|X¾|/ô㬶<X"¸â‡MùËí«ó–:ÔÀµ®Æzçöe&~ð:°›Ío|î
+×ï.Kßw¹ÂÒþöžôf±ßÇZÑÝ
+B¸/êG“ôn£î›eõà^;Í“SžÌô³uføø„íÂu‡Gšö£Í%Aô¼ä}—C<¼*ûÑxK¶V‡”ßœ(ØÈ'5frÝoæoÜ?çÞã äíÙb£ƒœ,¾®÷*^uZò vÅ¡àêµ\ø¤®Ô>‰‹kÁ'_27®öɼ¼<©Å†–$ëþx„˜äãët{¡ì]žY)“Vé“>µÊœ D ƒ8ÒŽ¦<²Û'µgy³ž³'Gö†&¹zʃp¾}¼0ÀcÏ7Ó³D¤o]ÈùBG’¼ïr…¥ëÎÖ "$\§½xô§7‰®öªª¿533>
+ºýol•Mze[nwð ÷Ùhûë¦à“Êy­ÉžòIÑ>©âÜà“j•[ôI—ËJ)µÙÐÚéJ"`’>e—¤nX
+EZ¶£”¢Uö%¬RܨCRe]`þÂêˆ&ùQ“Òë0,O˜¤ÖÄo2Ǩ”ÂL¯¶~rŽ ?ßLÏ8Äv<ûæzÒîwCrºí§ øä½9ü{³¡”ð7'<$H}îÒ­âG®]NÃŒ™Ñí}ã´m’~r²¶ªËø2KÆè„
+‹Wð¤W–%Ÿœô ±6Ôê0¥¤q“ìé9û­“û£~ Ùö—Fºpš9Y~Cùi@£2:UÖ‚O*+À'Õ^aqpõà“Ez;ª©)*l}ÒårIí6´v¾ˆOƇepD}2ÊJÞ­Ên€(åà6•’l¿äÔ*w°¡64å•Íw“¼r¬ØRY›šÎZa:?+¢–VØþt&u¼uû3=ã/;åKKÄ .™ïß`–¤î¸"Ò²ã“hÚ‹ÿÑ‚©LlÃø™HhíÕÖ;ç8Ñl#~â+D{ÓËI?³8¤ëQã+”œ£à°MÁÕ§|Rc´áâZ­Õ
+>©V¹S>™——'µÞÐÚá"+=²rƒ!cTêV¥Pv D)/n_)¿
+²ðY°Ê™
+V½ÜrB+>üè<ö§¡}
+Ó,gØGCOÊôÖ—ò$‡”ÛĦ223ؾ{UñQ«ïÒä0!"z^"eTõ„*Ó'ˆTмM9%·ßTkÕª¢¹ á«Ž$×e:;_Þ_r'èé8jÒ)IÔ«ðÿ.Š]k¹#8æO
+Ï“pC`Â:TjÏ“ñu4œ½»-Z¸C€»I¼O´K Ã…V7~“üç‚ìËþ‚úúfyu«JoåyR]ež”—ÙèJs‰ÆDx2OÇ-v£—Gضô‰‹^¤DDY¨? Š”p†UΞÀý„*…Éb6IYœ›qâ  ýõ°¼oe Ó²†|ºxÓ9 ñ®Õ7}t¸pÎ…Æ»ÅDJðÒ´%Á“†¤‘ñË-4B­øð¿½ÔD—eëç<ù»7J”Zs¬OټጭҵÞ8¨»qœ ø$àDáAiB<¹8DÏœ’9lºÂJÓ.½± fOŒ'A<On×uÉm€”„'óhDwârõ]zy‰_§DDÙ).gFJŽ*Ãx¶ÃÁN¨2A†BO9%á^üÏ·d'÷VVë›b°g.§Ž”v‹6qÒDÜJxt°'jÅn~|YìBËÁ9ðd /]DŽ
+foq]³¼Ê <)Ó[‹ ]iæy²Hnc†ðd~ vòá•QêWiÑË“ˆ(g”~¤„Cî<w’š&TùBòœ6çB3N|³½¸½¥F¡[K^…îÔ‰"%÷&»k.œûÅ@OßúÌœÀ©ô2ÏS+¢—X.hŇ—.¢i—D¨òd{‡ä‹ãT½¡!鶈w ÓZp IÚèÝàïÓn”Äñ?Y¢ç=´ýµÝòêÖrÆ < ©®²OjjmðäØÀCFÚDz=õ‘n”ˆ(1Eø9­H¥ÊÐ)jÚMñàçD”Ÿ‚” ö )§äÃCÊN3S´¬Ñlv‹Ò<ñ^
+º@Úß;eNkõ«»MQ’\ËÐ,‘B·èn/÷âñn”ѵrì€$yžäæ¥KÔŠØõ•ý‚Ú_ñá{ƒX¨zdÞƒ><TT^ÓœJ‹Äÿ°¡¾áGi¸!Üö¥K²ïð¬¹ëS—êNΘ'U5-1žÄ¥F¥Á@x2Æ^vgù¢x:Fx’ˆ(ye)£
+UöRʪ„Ï$›íA!7ºsT6°¯²lws,7Éfnz‘R˾ÕcÝgÇ¥3z:ÖjÒ) àT<öHÏ“PˆKÀ“Ïa¾Sß>ð ˜üÆAµ†1Ç“dÈÎ]-¼kŒ|p"hQ“6É£ó´ÿTaQµYVeUj¹ÎNo–2&àIºÒ <¹]×HIx2Æò¨dõZô’$"Ê]Eø9ƒH š fNà-O•ði°“îÅŸ¥‡÷—Öb‰©ÌJ’|NWì~1ÐÓ·bS.”¢»ÀÆÎJ_¿¸rB°PÓ.ÉD—
+õcA
+¨ïî 4¸¯"E˜Œâ(ë@cCã£2¨£õHÉú¤¥â“Å!:ì¡ovj€'+j' ª÷¨*¬„'ónÜb·`rõZôb$"Ú2Ê4Rrq”ûpÀ‰¶Uú»wLØ%@’À`_ÛÑÍöÖFŸJYÉAZ®ˆG‚·Ìº™äç>- ì§àIôáyñ *Wôíaš…q;zÐG·h9· â@¶^ì–ê ®;[ßÔûqòñP÷½ìA÷‰C¡`ö–Ö5OªjZÔU6EU3]i&<™/ÃËîiäâŽåŠð$‘PŠðs‘raÝ5Pålžìay2w©ÒßÍr×B/†‹~£z½©¦8
+Jm.‘äZšs/¿Sg~¯}g¸w C®ž]p Ðia¬ÀðøŠøe•ýZñá¥K¬|Šuççvp¶j©Ž'¹ÚÑ™ÿضsÞ½ö†¼OæSöÉÒÙý…EZkŒ'UVž'åŒ xr»®ƒðä·Ø=ýñ
+úqLÊ–ƒOüz$"ÚJ¤üv(CHù<x¤Á~<Õƒs‹*!I'ì4çBÓN|ûME—E«aLEÑ4T‘­¢ˆÇàMú¯ºð”CߘVžœtJ„2Ü0IôjÊ ýw„ú?ûõþÓÖyÆ<È´â÷=çð1I Hˆmˆc° v –¥JKÚrÁW Ià`ÈÍ\BºV[Öh?L‹4E›Ú©Ú«ºI™6m•²[Ì\ Ž¹äF³\H“†=ç°<–R°{ló¾úÊrHìÎû<çù¼c²X=i‘A…Ü>IW´
+ñPJþP£ÓéÿpL>æàºL”:Ï_H÷IWiÍŠâ
+¥Êž¤5¦ÌüêUž¬ªª
+{’2µ¿›î-¡n´t•‘¼ IHR2ó—©{‘rÊÍ,«Ò‰’B•Ü€³¦Ù1`ò·uÍ s‹–% ŒL^I®JwM.ü‚Â/?O¦‹x6yàÁp8’¼›’"SgQŒ½µáw ß×Ëõ%¥aŠ–µTªÀ«BŒ6ŠP!³ÆßJ÷.ÈÔ˜sµFð¤b¯<‰wÀ“9Ù¦ÿódñdJ-7·›Ïú¾÷e7úª—I݃$$©š9 I¹¢ÊÀ*¬Êø1&–
+IŽ;ÑŸOЧîVkÂTªÌ¬Ô+ Š´ rÀŠâwKýÍX4O¶SÓnNF’·Râg¡?êÀ±{Êã7GEû "{’ÿª­j󇇷]xÀ"?s…´Q3n:ØJÔ žÜ¥×+5VyéõÄ“)¿BÝòg½4´€ämHB’™—–”«TiãUÛÈ+pÀ*¿Ñç'èË5y{ù*ŒQV-=ãAJGåŸ5ÍgCñÛØkqKèñyZò>Jð„¼œ'Ÿ\ÀÃö˜ú :bÒ…þöÖE&¢V Š«ÀR]é­z94Ýx ‡ØIº(ÿ“3 <©)1 ž”ï­<©ÔéÀ“ŠÌjâÉ]üV^{-ÔM½¼Bž$$qô¤\ÉÝj´ ˜‘P•C07-ÜeÜmÄ ÉŸÎ./- O=–Ÿz©–ݦ6ÿòå„ ZP<ˆG†`«˜•u{¿ƒLŠoIh¥Ó§p,5h‘M7!è6¢fD¬@áPÓ`ÞsÇŠ¦asÅ(¹ é§3òµF¥Ê”«ÚŒd ˈ'7Çâ¶ò‰—+þ}ŒämHB’Ú š!%$ÐB¹ÏΫò;–¤EŽ‚ÿ4èÂCVtýðö*£6<ï`؉;@-,?Í« Ú¿ÄüêE¿½Ã™¸eß6ífž^"¤ü¶N÷R =ø^;8ý¶Â9ëáiª÷y\;ˆw°bWjOˆÞ`ø‹3sÖÃÛ™Ø+䑇;+o«Qƒ'U:0R¾·2[[M<™úËÍmåBý²Ÿ;’ø%áHéæ†Èݳ”¿ ûlß‘*‡¸ Ÿ5m܉FíøFmÖÛåÅ[5æð°KmI†Çºð¦»&wÒ…¬HtOÂIAô‚™l§fÏ3€¥/½ÒwSÂ<¹Ø‹g;±PíÑí œ¶¨µz—‚?^‰Rr‘ߣ×zßÝu§]ñ¨‹‚c‚£6jÆMO¶3?«ËOj˵ÀHZcO2»Í‚'s¶×O¦ââöñY_ÿÒUFò$!ÙTI R®R¥ ‰&aJÂë„ ÛЯßU7«³5¦•y'ÂÐL¢Ã}¯ÖðY}ÐzHTRÂNœÂâ{²~à¡%oŸ¤ÈÓ‹ØïBƒQµ(ÔÇ7‹µBÅ•JÌ­)I£QýxÞXgæW½ôÒ™¹KÔ4Rˆý¬¤|Ü)ÿÔº•-<¨ÒéÀ“Û «Oæd›ˆ'SvÝäö1ÔC-ÂISê¾#!Ù„™KRFŽ’`+=ÞŒ‡í2ÑU ÃqÀŠ
+4¢OëÒ‹´†ð¹cý‡”HšÊJ¯Õç{2–Þcž÷r†œ÷2«†þl'5)Ry<8ÇÛÏ¡"ðdAqx’-,ûOn!žLúµ²ƒPíP`’÷ ɦðTO\RF¨rØ! ²~Ò
+YO!EJÒhÐ_?žçïÈXºÊ|}…žã$I…^uÿ¹ Ra´Q3nò‰UžÜ¶Ï,xR©Ó'‘^O<™jËÍíàb uõâ
+ñ$ ‰ôIhRòk œ¡FœHàÊÚ°° Ÿ $ÿeA7j³*ôûØ•yǪÌë‡Ö& Ë@£5Þ:&R‚Ãc÷äÄi<ífâW ³]ÒwMâg¡OžAë?…Etl¦™ºy„]?&#%i0è¯Ët¦#—úix¼Ì{ךõs—Eª 73ÝΑòvSFVqy¦¦zûCf~5ñdê.nC=ÔË+´äíFBB"$ñI)T9ÚÈq‘Så*ÆXÓÀBðó`#¶¡_ɪ-/
+9"ɵHÉ¿Ú*T#6î®m«vv'Р÷xyÌpŽž÷Jß5 ðäÃsXh–yÒŠ&]ø§‡·…kK2Üe&céu“]œ$_\aB`Åull%lhì(Œ©6êa3ÜB3»ÍàÉ <ɽy•'¥¶Y1.~Ý[ºé¯yO†¤î8!ÉBJN•-Ô¨‹ú·--R•>kÚ¸9ÐGï(¬•ªíjÓ2–ÔfV-½Ù9‚¶iL7j³‚. œˆÞ“Ùˆ[ã[E ‡'±ä-“ø™»D Ûeƒñ¤ÐP£v|¹&oŸo8ƒ¨ÿç¯ö——þ¨>¢3}é=æy/ÿ<ñ2ëœï!/õÀ#Ú“gÖÃÜmeÞÚ_
+ŒÌ./g ËàMA~5xRÃ/âÉYnnŸ÷e@™=ïc$ï5!“?iHéfUŽ¹°Ï†8Ucl²Ïê3šìÞ]\¶<òTfVjª%K”*Ž”o‹ÿÙ€‡ù[µ'Gã^
+½ÔB~r‹óÌi£î¹ÿË~™?5‘圿c˜2Ýýš •¨Â$H¸CDaAÅ™µ$""WW$uwjªö—ÝfvvÜÒÚÚ­Ú£f·v§¦œ­©-‡P rÂpˆr„kÐì·»!‹NÐBwß«O½êP ýº¿Çû<¦}Ý- OÈôøä[Ê|Î'³³³±OîŠÁ†¯#Äe#Üþgƒá…`RJ–13­C_^Ýÿñ…èêSŠl­F¥I?¯}I™8±Än¹ðf`NÒ$ÿã|Ø@ ±e¥,ßyŸdç§M‹ÈU›n$9Kô1|N=ñÀ@~{ 太7ú$—ÜÅ»™I_œ²2ù¬FBÓØú"íÔl3‚œÙ~n@♨©zº·2|R¥Êا:¡ÑÄDçx|r])±Oó03á[´<+$x¡a0˜Í.¥„uNÔ3ûšûzÞŽ–ZÉïkÂÿ`ŒºQSúê}£—žm‘>Ê@,•º5:,™ÌkQ0ÎP~"¶Ï@öø#!ðýñ°Š¿  ^)¢ÆÆøä\3Õg”øå“ý%ÄÝ‹Náë§0OùäÓ|¦?ø¤™†Zƒ}œ1Ií
+DÃPÃ2ß$í¯B‘G²öFçÄÅ¥s>¾7gƒO†`Ÿ îÁúä¼r_§ì„ðµ†Á`¼bcæ RJX䨙žm^³ ØCWÛ˜ýZû=Öúuù¾[ùÍ‚˜ò\å mR”JëݦֶÎÌ—äóÍ{ðCGµ·>Š0 þúäý’Ÿœ»üP‹ K…¯qã²QÄï>ÙUD ‰¯.Òsãt–úÓ¢ƒSVäî¤áÈÿ6 &éa²!0ÝZÁtýЄ~wQ>“”$ÒbŸÜUƒ•Ièó`’ÏÛñ¡ƒ5®`SJ`ºqmåÜNÌÙ(`ÙÜŒXðÇõ{ïVFÞ)‰êüyŒá}U|RšW³±ŒTê"Þ<·†ù½´Äï ‰Þb?<„óɾRê‘™æ-èO,»­_2"ÅƼŸÉZÒYèká>ù§saž”8©ÓüÞ o
+…Úr+9g[ë9m¡Òj¸ƒÌÿ6F€O&­û¤ü@ÁFŸZ‰ðØúø{->—9Ú_b æu—RÂ
+'ê¼TçY«äX´Spž…mxæ´5t¸1ìÛªÈOõ›òãÎd%¾£N?¯`j£b½9néyÆŽ“ò¡ËDwá»Oe$o>9lB“õÞƒŽñT1¨ÚS ÑGŸý%įN€LÈÖ&Ý6È'À$;èÛ˜ãXÀM’ƒY¤• L+`ç麻" |2;[2‰}r÷ 3»y‹Ôe§ -/1 ãìÞ1JY+v¥„åÕ"Xê«ŸvC0dÎ-á㊹¯1¬¶ÑK­$0Ò(ýó•Ÿ\Œ.ÏUžÔiÔÉiò£Ú—t Ä’®eBëߎ(¥‚Ñiµ&åŸè©÷Y)‹÷ UðôjÔLÏ6£EÁ+E´p%ÜL \!@}Œco1qëœì³¢ƒÓVôüâLØÑ¥¶Ï¸¬¡ª¤²¸ô¨Äy”ö-e>øäºLÖaŸ âñ9;î\ƒ ƒ :f­ä˜YôJYC=i¢[IŠqK=Ç&\CkZn%aë|ÞÎJæu>~W-»mß(ˆ©ÌSžÉJTªÓ¼ غdîĹüDlŸì.ÚÓ탄€®ô<' Üί ¿¸ìÌû­"º.ùê“Êá2rÕA­´­• ë´Qãuj2&jÖB÷W£²÷bèØÌŒŒŒ}2ûdÐ.p! vÂÝÉGZb0˜€#~¥6¡Éz´`ÛÊÓÁ^Æ[ç<3¯í¡ÏÀ-;i÷ÍP0ÌGúneä’¨_D—ç*³µš(•Ö»Œ)2×ôRh-܆Of ø۳ådWá‹„Ü7<r¢¹¶ô7x9Kr²ŽôåPàÁ©—ŒT’ÜÏùY'è ~Õa\ÖÐÞªPY\zllfLt‘’²Ñ'v"<¶<ÌLì–š¥ v´â@‚ƒÙ"WÊ‘
+–7ט‡u±€UÎÙ¨9V/¡}yÜr¦ 5HïÕ„ß.‘;>:Røn|BrؘäKbÆŠ%3Ë”Â[¢_D°Ïr*#þ»BÉ}ƒÄ©R‚®ô_!ùú¨™† /
+]bf±•œi"ûŒp~}¾ÙSL<®'á·ü(%DpÚ˜Þ)±Ü"í©Ÿ<£ÓaŸÜecÁ†–2SðÊÂ`0[FüJ9c%wB-^rË¥VòY;«—×Ün¦MZÑL²ß\:\{Z‘wL­II=’˜áÍ-3ƒÎ-¯çÊD7kŒ¯–Ár!‚nBÓáKCä@^•8 }õI
+š|;õdî!Iì“»b0[¶K¡å®¶Ñ‚—ƒÙ>¢UÊ‘j¬Á®Äçۀ͚ÓK€³hw+Vé¾N³-Ô=“ìƨ_ž®ÎSäg©êôMü ¬23‚õLÁeÒã½0³Þé/!º×½Ñ«xô$#Õ¤}´†šk¾.ÄÌb+9Ý@BŒüRJ.¬O-üœc‡£Áv‹‰Ÿ„‹{e‘à“Æ™ ß›ãñI¡¥­3㓇ÏÚ“-­Â—ƒÙ>¢UJ`ÆJ
+õZ\ëzÉæœ`/~ÞκåMTóQ£ô¿Õá)=p£ ¦ôÕñŒ¤HoöJ bÉ! Orw?tTûŇC—‰®"b3ñè»L˜-´àE!ræ[¨F‰³ÐŸàûCWI_g´É4²Íd`}Ž]åáà“yyjðII
+t¯C¼9O皇WI§·ð½šî¢=ãf~ÎÃ"ŸXuôˆ‰þúò>:63;;ûänŸ3>¹ÐŠì<¥"ƒá*%,æ‡Zñª…Ç-çÙ.;гväî`æ¥VröÓú›Êˆ__:\§Ì?®ÎHO9’ñSÁ[sK¥Ž½ôÜâf^Ôp)ÙUDxõÉ¡
+ê‘™&è5Ô¨™ž±â]æUÀ.ü¸žìÙäDð*ŸÔKúŒ’™&þÃNWÖl3âº|˜¬£‡Mô7å‘œO†ïÍ™T©T¬O†-Fxø?Ö¢²hG bmï f;ˆM)a%£5Ì®$ø›y-°5{ô.@&A)W8ü†Üôj=Pö×+û?¹ðvužâ܉„´ÔpH¯Ê·£†)SdÂœ–œô¯ t áÔ¿ ”ÝE{ÀRV æ“\ܧ™w(xXEÎX5 ~ØíOÎBÉHÁÃò ¶ßO¦êé‘šÐ/òÍÿدۧ¦²;à¼éЙ¾Û1÷ÜsÃÊZiWË*AY+,âÝiÝ)«ÖÖjʃ"
+†›„<’
+vèÉe§“¡ªêGï”ÔT
+ô¤¾›âÉ¿^txZÄ`vIrˆ”@ ‡ó“ï1ÉP^ÚÒËþ»ÖA—ë]t3snúïÛû¿ºZä¨9zéì‰O*O>qú*°üøeÞìÉOõýìÀ“ëBÀ,0LþfÏÃZáÉmqœ·'¡èSVªæu“ÇÇ–¬Ö¡‚&RÂÁj=ï ðñ =€aÙ³Ó™qGîÐ}'O>w¸`ï¹&mèI6¥d÷ò`n¼è¢ÑăÁ¼õÉRÂÌÚi´ÿ€d!`K•—ˆò•aS^óxýÆ{¤x/c瀵à…_]=ä¬ùàÂÙ²òòòíŨpqÙÛ_púNýøþ:XG€”`ŒþzÃè·â›u»IŒwEr?0OÀ„adçm¤jV2¹²àD
+s_I‚—ǘ'‹JOÿù⾑ëä[³áq#—%î˜Oœ#V¼üÇ\/†ÚHR²D½aÑ)dˆ”°fçâhjoeN[CÍùBy9zRßM)Ù`Ïw¢>ï–¸/ Ã%ÜI ·žµÓLìwºèzÖ ™âªŸ<ïd°|ÑEŸvPBØKrÁ×µ½ŠY}âãÊS¦“•¯Ø²ÐÄHyéLéÍäQyÜ$Nä†'UR.º ÷qÖQ è3²ø ˜œ'!³a¤)#˜Œ(ÏKmXX?%Ó¡#xZ“6Þ6¦½ÉÌ“ì5å#Ï:ø¯ Ã+|I ûÜ}ÅËr9‘ö ^Bÿ^‚*UaÆ{¤õ.:æÈ¿{ÿWW‹\__ùôø™ÊSEÇ«6aÙûÓÃ×…'Íü¹µî3vÊ}`õ Üt«4’'%\<ceÌ„*—<”½:Ròä”òÁþfæÉ_\.DOê¸)žŒ´ ñn)ši†Á`tî¤\tñ½$²ÁKfKµ‡ß
+ÊßÜÚÿGs‘ç‹â‹Õeç«Êî_5N[©lý*º…Qdw홸ÃH™¼'5`3R¦}*¶‹Ó¶”ÞŠ'¡lÉ/Ø{<Y]]žÔeS0¹â¢Ì“xBÄ`0<I 7µÓ´ov»'°­+”–g®úÉ‹.¿+Åû$øyÆe| ï·QŽG†mŠ®ô .1¦™ûê"›5Þ"®%KJ¸r¬YÈÐ#ÁÊMmR©§›·˜'eë*&óòòxó›Æv•,â×»“ f#@Ê YÊ>9àŽp_÷x;²iËeeHŸuJñnéi]t‰¹EJ ¶á¤¹¸Ð¯xÅ‘&4'EÊ ôµ{Bvó“hZWüÁy§˜ÚŒšµ±WM ©àÀ.oz’·°il2Ãärçw#>¯ “;YpQu£Ïª+”>ì&Ü¿þÛ—M[Â1Ÿ¸ìgìt,1æ¹·¡T¤j×’"eÀl¼a€¤÷`F-ºéxJÓIñ$ùÏ-Éd2¡'õÚî1O®uHêdà¾(0LNeƒ”ÙEÜn¶rÿîow"jß„SÆ<»§$e:K §? »(1hNŠ”pÙx‹õ§ùIà„2i¥)Ì¥]µÐoê÷U+MñdoaÓÒõŠ¶ ñ»¸„1Ì6É>)a?š²RØ%¹÷]’E—8)§Â€ŒTI©=°XVýdÑ) Ô%EJ¸¦¿VXp
+)çìäAíždH ×Lµ’XZwÿy§æ³Ã¸Eœ³KЛL¦„'“újj½òà½ÞE¹/ “ãÉ&)Ó6ä—*‹²”s¤Ä™|üâ´,$CJ¸` Þv1R¦k­…Ý„Ížœµ'%À$zRŸÕK=˜ '1L2É)á°+ÁÞãý•wO"J¾ä¡SVšs¤Ä$ØÙ'ïÞèI•”OšÒ†I6‹Ú5žGd 2c‚nxþ¡'uÖdV/8È<ï”Ø4ðó_ &÷“5RŽZè¼CDOrÉJ»8k§cY)tò¤ŒðFl¼E¼‰”A¥Ÿµ hºT9mÓr±°^9¿MOòæ6MMÁ¤ã{ŸïO
+Ü'?ƒÑK6H™ü–‘2$liÛã0Ég“móN:‘ùBk"%&©
+ÂXùů8rK¾‘”fãÃ’›‘2-wŸsh9†È’êÉ U<™‡žÔY“‹ ‹¶S(}Œ÷ÌÇ`0ºKvH YòP|GqLØM&­I©»ÀX”Ã7 o$eàša¬YH×­]ZŠk'diR¦£–wUOæ¡'uÔÅZõ“x¯Ä}Úc0=fƒ”VÄ‚“ÿ7ÝÍ̃IÀrP‹ŒÖZ)#¼‡EQI¹ä&¯ Æ×x2¨ô!;ëwŽöe6O&Y}[òA’²1©«vÕkµƒÀ’|ÚA¹Ïy £Ódš”[ ᕘ"“C—%¨HŽ“LTR†]dHi~)œÿg¿Ü–ÚFÒ8îWØû­šHÝÌÔj/r1Ï°·3¯°w°9gCÓ>É6¶!KRµÁ<Ä<Á^Bå>aŒBI–Š÷k  >ÈƦ%òÿêW*aK²Äÿkõ¯ßÞÕ»Ù)üh7'ÑïkáÄ'ßG òÉx>ª2¯Ã‚Ñ{f*ïv
+ÅoHŸ\6_?৖‚
+AEdRÝö±Àå½
+Ÿ-QO˜»‚½^øƒg*J= å¯\íÿ”g‡yãhÍTÞÕ
+Õ¸ÑÍ©.à;'s÷‚ƒRŸÊr¥¤O^ÜÔ)”Òsôµ2¬t"Cè¤çw¢óÒUÄuŲ„^‘cá§Nè­›‡g^ò
+¯%¤RqŒY(%m¡”~ apò¼ié¯nk›‹_)%ýIžI¶é_)»9N2?Ü'KËl[üè* |2°%£iÿç/‡y£÷ÔtTw)
+Ly
+ßK@)ƒ IcUèR#O|’Ø\ÐÞÞÓ);Ÿi¦ù(Ÿd=Ÿ pmÈ\ ?ô£5Sy[
+ŠÆÛ©DÙÖ¢vV)éÏr”‘mŽ¸‚»jhg‡%ëdçK‚ŸJ *ˆåÚ¾×{Ï “
+¯% oápV ¥ô§””þòæ±Rn¹ìÇ™3T6(Íj¼Ïa?!%³ÿQª‹€O¬\™ìmüÂí­ÊÛ
+¼ôXß\ÐH)iûöžNæ/Ãêwp'ËËÂø*>×'É0+ÂO©6dÝ‚ñ¿5sP¦
+
+(¥R‚¶¤IQ§!y¤|r¢ã3ðI›ÑI~3ÍÚOdo×
+ÔZãÖ›
+”òÓlÓõÆÛHËFôO=·Ac„7RNû©k½%
+ÛÈÞÜg/oÿ:élß! ôWvî)» R&/‚‘„Š<‰ºd ÖËux}UE¤9D ªaèJgëßnÔh?‘t,íh”2ˆè$™úÜø¼?ü*
+hTç`HNÀ9•0/,°½9ckõøa´‡ ÙŽÉõqv¸Ð…úÃòÐEÈqH–#²çuÝÛ€ê,X;ø: R>Rðµå¬¢pš©?¡|,òäc ד0Ãÿ2é󖢨û†TŒô ?Ïã¼â/ÙÖ: ´–ëIF¶{rgŽk÷aç„zXž,‰‹„ôE÷ö î^-)Ja"åãÅœ·HÊF’¡}ž)»:Üù¼^ÁWÀש{­)Šê›ÚÙÌòzZ\Äùi„ƒ|w–mL
+i¹±žf¤ÉIãp¡ ïqí!,Ý€åiT*X6–},ÖIÄ[G"åcä¼5áø9ýàçGëïº6@ÃBOÂvV “EÝ#‘)qe¥È¿b;ÓÌ$¦[‰÷òäî<?²Líìš*,]“”ùé’8s;…«¦}çP¿ÛYL-Ù-RV–ô_QTw@J¼V”λÍ ŒábÒYþL,y’¢¨_/u{Ï
+U-!*a^xÍöæŒÍIÔcnÚeØ&7'y~á¡ïîž Xr”ËDXF%¬þME}³FZÀ2}Zì)á9!Rúeðæi¦¥4QADʇç8‡Ík¤é£•¢¨ÛêP
+v˶û—óÿd±ƒ—l{ÚØg`Èþed{{/pK;üW•®+àX´$@å4*.“?_tíj¨‘ê‹àáßDÊÛ)×Lx²9ÿù«Ï!oölêþ S5Ìíž(FÂÏZBœ.ñbïΰõqúÊ #!¸ŠÍ)–×½'…%¨Òõ º–Õºº¡{ïQ¿ÚY Wª ¤|#ˆ”?ëó²YOË}ËåE¤ìt¸Sg'M˜Ò›eSû²R¥·ºËȦËH
+.mkšiwö|XZÀÕ˜¸L‘*{(`|â•ÃR-‘²‹]©}žbJFVˆHyÏ1âÍØeŠ;«Rû‚Rõ4ÕSÞ hÁÃyŒ—,q`;ÓÆú8CFŽ"#µ{ï :x¥Ÿs½r%(,#â"Îý CiÖâ4ê-‘²k¥ÄuV‚Øí 󅤋f}9,œ®F%ùuEÚôÄ ¨ÞD
+Š‘p~™gK¬仳lsÒøßø³»3òcGÿ©×‚+ÝžáÚ ×›)X,`Y‰ˆZ¢µtïdê<΋!ùPR¾DÊö>/›p¬'¹g¤"å]Çû8WvJ:«HJ;£5)ŠêzõÖ§b3‹ŒCžÇøÉ"Ï¿b[S†â°
+Ó­»§Æä?ž­³ƒ×âÈ2µã­gË+XºçŸåiT\$$lªÁR_0óµ¤(…LÊ RÖu_Nït³¤”—)H²È“w8QÍÄw0uÎL Ó¾ŽEu=xï43ÈÈ‹8¯DøqïÏó #§
+JûEõFÌY•õ´¼ÁxG¤¼Ã°þ‡ZÚ¼Êpú6¡¨¾/…/ÿgÃ}ËCÕ˜(Yì0ÀvfØú8ûð½'Ií–ÓL¸úp<ÙB‚*Z²æ§QYKèÞÿ×ÿâ†{âA¤ ÊÒ"÷HI°L‹›eO–‰”w8?ÿý^:Òù'ÌÓ¾|EuP½‘ G;ƒ'—Iqá…¾;Ë6'‘Ž¹Qd¤vÂõTàÉ9~d™ÚmÖ¿å,ß–ò,&.I#:ÏóYÊvRRiá¬J¤QÊ@1)¿1ÜɹYÆI»ÊJí GQÔ}SŒC6³Ž`È‹8//òÃ
+–î À²Õ˜ X>egQQ°LeûNVHé—Áã× Po$þdzÿ‚Hù‹aáœÀ÷#Àûf…<IQ}22w®¨FE)$ò¶3ƒ:Ê’!ïƒÉ1ccÒèøKÝI&Ê–Ay’'qçø^Ö} |ø™Ç‹²+¤¬ë¾œ^ÈY3áÁëüøgŸO4ÚNÈußJêÝDQTOñzÊ;‡G™z Ã_*^X`{sÆÖêñÃ÷dÈÛ èפTY°ÌvXj¿Å5%@Ð`9,ó®ê;[2Ÿ”CžšÏëe|;o]L)o‡709_V¤M Õ3Á{V½jÑî·ü¼ˆórˆrc™%FvLÝÖƒ7¦vh UùvX.ÊÊ’¨%Z»]m~ÝwßÀäÏäYg»³­î‘2IKƒ5“«ÒÎH“DJoà<\gŸÁQž¤(J{>#›YdäEBž-±ã ß›CC*åƈ‘Ýi/ Ž,S;±†3KuþiQžFq·ÃþÇo(u/è¾ Ïã¼’'%¤„ì”h§Ô°×Õ—éÛ›—¢(½)FÂ+µe¥È¿b;3 9Š€Ätl`‚ÉÜšÑo*ê¨KERXžÅ–êvÐ~KR
+F|êîOço6rèªêêþiwÑ÷ïêÈh˜üsv{ÁÈùÉ“N-ß³e9,ª1 Kpì5ôýîÐμ $Léh«@¤ì—Ö¤lÁ ?ehZÝ÷)«É_ô$¼°ñ—ƒºÃZØ'àâà¡Ö®Õ¬¢øÑŠ±ÿÈ€é3T–à`‰0醴*,°<‰q° úÀ‰aê`‰”ãe?R»[桵õƒ–ò)߮뱿…g_vðÅvÝÏ;W_ùׯütàGíÿ‹Ë¿½ü·†ÿ¨ÓÀGBßƒî ¾š5Sü,nìà‰±»èûïü,1rª‚…ØYôåü£=7©)¯ËRXT㲑қñòÝžºùöuåù n¤™¿ %=S2üÓ&|£Ý ©å%R¶ÒâÝšÐOÀ´¾.?‡]ÙHZï^(ÉÏWì t–àµ8¯Ùïcô_\ùÑuÿ]|Äã|t×·ÊÉã•0Ûlh´XnÑaó‰ºÜÁ23•D'uëÙª´Ëaîêð,#UÜ*åýirÚmR¢Ÿü4ÔÝ’-xOÿ¦™åR–#‚•ˆ€}ï—ƒŸ•þÆg¿÷ëÿ¾<þæà›?ùçÃ|tÝÿ>Þ¿6à£Þ툢Æ,È÷—1rjƒ¥Ù]dùQž•”Ë÷næpW?ŽøR °„g=Ár`0Eõ$+…ÄHÛÄžê³Í0ogù§ ÑN‹îËßµ´¼AÊC¿¨FäÀçãØ™c}4‰sÈÐï”;Ú{l€[ÐíD]Ùá
+7•D¿H¨;Ë~–•Ð°Lðf
+ÛS˜f ¦Ë6À°óäDÊ~^#eAý
+Ë}!ORÔ¤Ú{ÂÀ6X¬òrûK H~P.è–A^
+‰ã¨¨%Dx€­”`ÔõUó@¤¡4ïnŠÀríï½ÜEÊ™‹áÀrh®
+¶sÎr” KU+mŒš)Ã7{b¼iƬw"¥Æä–XÖÕ,ÐëÕw‘ÒrI 3 ak')jB=çÛ DÊ;í`Ý)°´¥T ‰“(?ïÁ²“eèt¹³@‰öT ˜+ëHÙÎòî¦heŒ/ æ–—5–¿~,(Y‹Î¡oOŠrk°ÅW8:±<¸}gÑ7ðGQß_Þ†¥u±•Câ4Æë,A•t½ÜI0ÞRH)‡ïúlgÅ…Â\DÊWôXŽ²¤¬‹AIôíIQîLÉý%ÔAç–½ã¯8å±>Ã2Ì–çIÑXbëeÒÁ
+¹…”–óŠ”<&)j‚Áýöõ#ƒH9Ñ`za’>Ú(jrÙ°,*Q‹jL6’ø†™t­4¯Æ.Æ~ÓÌXïDÊ·YÖÑ“fô(æ*RšJ6÷Ì
+x¯oüM‹ÌɤT!ëäկŠ? K3€¿³(Ê í/1t9=ðäÁ2a’rU6,a•ˆ8kX6:Øæ;8ÿbH)o¨Õ#e7ý›ö˜“Ii¿
+ŠW#R¯¯’芢\_>È_?â "t•94˜º_ÎísŠ¢]–å0ÀR4Rß"BÃn¦øqD%ýH=NJ¨»%;ãdÊ©¤|õ@ŸyUý¤¯ÛÐœÀßGå…r~¶³è#RŽÝÁ23•D_GŠš\¶*á ¨D9"j Í3Ûiè>Ðïiüb8× ÌéqR¾Í²&À²kaÒ¡¤œ¹8m3ÈÎã’îÏug=ãÛó‘rÔ`ÆvÙuÏ&Šr_}X”<‰ò³o8 –pΠâHY [Ë-ìSEé]–½[5ÑÇ–
+¿ëõRŸv! 6&‰”uW,3tž9±ÃFw*ʃå{¶›Ù°ƒuœ
+és.Ç}Åë±93€¿e(Ê;í=aÿùÇ.4§sµûÐ@_5ŠÂ `™³`V
+Y°\eŽ0œäIÌ:ÿ«TÙ'%úybõH™á͌њóHÙ½¯ÏÙT¼•èÛ„¢<ÜBHDÊá{óÕ(jJ‚TPRÃ2Æϓ†e›F7TKp8á›I9Íç?ÉŒO¢•áï3LÛL9ГÖ9ÿŸýzûi#»8οÐvwI¸xÎœËËV6j»+5UWiz‘¶jWEjÕ6UwÛ•¶Y !!`¶Ç\’¨ªö±ÍCU©O•"íc»}¬Z. !€mÀ`nÆ1$Üß™±½, iÀg`~ÖW£‘•Œ3g,Õj.„,Xhí#æ&ÛøH’òÿ—èîE×½^æÂ,í€eÚõ°ÌD8¸ñÙ¤Ô>¤®Øf£uŠgõû”y5sRò宺„_ÿŸ†y(iM´òáF2¤ln¯‘L^U—Kÿ’a˜+‹;°´*[ì.À2cÚ™´%˜j>T˜yëYI ÎêžSKùëœû£¾cJg·ö)e§xJª•…_7HJ +s÷ZØÐG¦~³¹5¸8cÍLû2aØ~ÉeRZ© X°a PÉé–Ò–»Õ„€· _"¥ö!µ´1 ÖëaÌRDÛg¤TÓ.Êc ¿5´´ÿ!`˜çòó±fŠ¤Ü“#Mt²'$>0ìÅr`9-E* »9 M;–6ÐéHÊ'Ë)éZL
+úMȺ¹€ýÄÆç6†•·©v1zÞDR>Õ“÷.1|(aØKç¨v’ÒX.õ(Xf£®ÐÚj”§‚"C>1óL@d"ú'ÔFÊÖƒ(Ï÷W+ŸÉ
+J|¡—=jRš ?‡ °Õ~ÿc˜·’ÖäU>ÒH‘”[09ÒD§Ú„þ°ýßfX·8À2Ó«è’‹1½vJw[I{¼-ÓNK±np¯–6D`6KNsÿKvª9g¤€{,´´ßóæŤuÿ
+ÓN8W5Ô@Æ/3¸2úWÃPñ¢-§;Eº‹/…Ùj¯R¥F¹-‡ ó,RFõ¯üåŃ/ZmÒ™žÛ ¡º„_ÝlÚox ó`c—ØÐG¦vȹ!¸#M4Þ.öúšc˜gƒïú)›p31R°Ô'c&ÂSA±…_ ¥÷Z‹±õ>‘‹Ñ&÷)ëOò¤´æ–ö›ü<<ï^ HJÇ“÷/3í+‚a^ž<
+–™ˆâMnï•òù-ÛM“”H©xå .´ªbŸõ[¹k`©À&]OÊz5^BÖÁ’©åóë¿“1̳©<HÊ!{;ÑÊÒÒ¾†•R°ìàÀƒTP
+·¨²^‘j·€”ÓRÀVû͉aoª6™˜”pj#MNÀbØÁ(îÀÒÞŸ ˆÅî,s×T;T\ºK=(œã'ËHJŽ!!8‘ÇýJù›¶ ÇéngÿºDoýÖìø±ùÁióô rœǘ²_uµÒãá*£¶Æ >æ r;U:;–ÏçPΤ´g¸^’\îªKâãô'­‰V>ܨ~{çÉ{-LÿuÆ0l·‹m û© ‚åJD€Ír±!p©‡Ow
+çÈ{DJУÓj1
+ 娟ý³™ýíCöÇ_Ñ+ï˜gO™'¾Z%Æ;0$lá
+Î…„s„—#%a-Ʋ×øÅš‡ªÃJ€dºe¸“¸­JêóY>ŸUJõYIÉ”IiÁVû†a˜Ó½K 0¦„;o¢UÿÅÄ0Ìm)UúØc6
+”ôDÁ|S¤P¼S"2Ÿ]†%‚OKÏzÛ”&%\¼wýG˜&†a“3-–ýeö¯+ɠοI†!Ã{B_}Vÿæ'À$4TK¯²ºÀ“dzaÒHงI9ªŒŸ^Ð[ÅbD5ÖS ðX’¨ºyíT&e6rÒ„ý`b6¹3` +qX
+Ë*ò F0`9˜êÃJr«äqI Ï
+`©é°¼!Ùo—’ûÂ@UŒ”°„-@ʪLþ»FøïV{Ù[¼ÉDe%°¦«Žƒè:ÇBªgO<><9P>=‰a“°°“
+¸+¤Ô—ßÖ’½oÛx«•·€©Ø»Ž¹*éÒb±™Í RŽ³*¥Å°ˆJñ¯
+bÜþF¸¸oUàpvàhŽÿ³RßÉJ_ß½Í<íÇ•‹§ä«mòµN¹çíêyjȸå+M©5*—â+rgC §<¹
+Å+±e¼¦´]¿ÜèiEOŽáyXf“úA¿0…úKéoýôÆ0,}jݳnÒ2› 9Ù †aceˆÑ(ÕÉbtš#ù¦h¾)ÆEú˜ÙZÉ|­tˆQ-_ÞözhçŠÀþÕÁ¿|àÿ´ÐwªÚÛ°ÛÓzÄs¾ŽrñâIåÒj¿®¹»•ºñZ‡|µ]Gc«“Wš(;ëGÐq(>fèÉ13Æ„dΓp“èa5IˆJ$*‰ú/ Ã&ia'‘³mÌI à˘†añÄá’éXG£‹Kˆ1ºéùh^Ýb,] «~¨Ö¼®ýYxûýï½8æôŸ(öÕïô6T.üÍàŸŽ·f¥ë\ Ým:ÛX‡-°=†FPbZ4>«Ñ“ÏâI(ƒ˜Œ{ònõd©ÈúaبIb0°Å$-› »èÅ° ›æ‰ézèa 4º¬ÔN¥cÞ̈ۦÏSË—¨ÕKõ? }ô«Ð®•ý«ƒ¿ç¯sQ1ž©4zÎ4Ê]­rO%¢p‘¢‘Z ©Ä¸ØlÎPb²“И)7¢'Ÿ“°$Vkf=94tb=xÔ-Þ/#næï ÃÆÈŸ#ô®áYaNíϘ†M—âJ”Œ4n#ÝŠÃq±\ÃK­ôûjÅË ÆðŽ7C{üø£9”‹'·øÎn÷6îñ´ö´ª\:KÕwí¢üe'¥cÏ…˜u1&)ñ‘±#zòÙ=i/£žZN)£…â­ât?|0 ›Lin»wƒ )á¤ÊZ^u ô‹õ8`Ø”*FG¼8 (‚ ]ÖˆÓqšu%ÚŒgiÒ ZÑ­x 1\ójxÛÏC{Þ|7ðI®ÿDåbÓ^ϹCžÖ#žöJÇI¥ó ùJ³|µ¢蘄Fº¢±A¹\¯/%¬È‡èÉL`’çùŒcR¿IEôZ¡8P>;ÊþM‡aØ©.;¸nâI gôç"&1,mb:4:è.11š£ù¦hÞLêFØ(9´°â‹jùuËÔêWÃ. íZØ·*pd} Îé;]ã­ßé9_§t|®\<­\:`×9¥»•º‘Š±]¾Ú&ÃÝa46¦¢±qª£=ùÔž¬V{àÉ¡åô‘":çûŠìHJ ›ìIb0Ÿ\Ïæ&’”p.e¯ìÿ} ›èıs ÷H4R7Ø4émóÂkÚñËÐî_¬Îö×¹|§ª½_|ä9wÈÓ~\îÖY˜.УÒÕ¢×l p˜$ÆiŽFôäÓaòÿì×ýSùÀñþÕ\€%¦2m¯g;wµ×ª¹këÝدíÔÞõ¦ã8wkQ„
+>
+­À¼8)Wµ`žþ㥨¥b@#ºQC£&Æ´éü”i»1b7à:l½\†âÊTŽ|W)y#|ìûá“Û峿’Ïï^Û¸‘ãk.õµVˆ½u¢÷¦8Ð(4¡GÚùûnã\D4hhäÇ{U4ºÑŠ#‹¸Q†½4‘'ó¤ILF= ¯H‘å+ ×¢ÿ´@QÔRql¨ÀÂg™V•”ðãâ!“â°ê?^ŠŠÆ.DG¸y™±Bfy"¹U4²Jq&rñø–pùÖÐéwC•ï¡köêù¾{§¤îK¢·^㟦>!Šq¼¡8чá-nwkžQ?ß‘ˆFõ»„Fò¤®˜LK³¤¤èáI<$,¦–/¶rV|”ÓÆ (j©86˜gAõ­š'!Ù®÷0©W%ö©žú ÜžÀ‡ ÝhÔÜKÅ•©Åxr»|f§\ýAàÒÇÁšOõ‡ý·¾»å¾ö*Ñs]ìo
+#í*ÿT4Ž{U1öó^\óðˆF@E—jÅݨ?x¨U<™˜6|£Ñ¨³'gðÐ8+Ìÿ=Jž¤¨u–l·ðY¦‡+‡IøµPþã¢ôˆ]* ¦Y4B¹a]ál FäbÙC§ß U¾/Ÿû}ðâGÚýþ9¾æRK™Ô}YôÞ†Û…Å 1€bt«rЈØ9°]MØPºDžœïÉÔT½1©¾ðàó‘Óª>r²zÏiE-£@®¸Ržôå˜tµ:%ȳ©S}ÂlïÐ2GňhdÐU=ÂÇ”’×Ãe[BŸÿ,tö—ò…ƒ5{uŸùoÚ}wŽùî’º.J=WÅ&a¤Ÿä ñ“ØDbD+ºçÚ@cܳoIŒÔb‘'ãYÒÓÓÓÒ†I
+OrxŽ¹â_GÈ“µÎRŠ,¾ì %üÀ.4ë>"êJc,mZѳ¢
+E£öwÍ~=|ts¨|›|f§|~7Š±>Ûßèòµž–Ú«¤îË¢çºØ[lFþ§F0УæÆq¯0ÖÃßw«8Œ7O‰‰éjÝEžL <™˜Ô^*)a2ùºÄFž¤¨u—â°Š_””ðuÿaÂäº(ŽÆ¸3Ô-*‘‹ r1?%b7Lç£bä2ç&¥ø;Ê‘ï…ý \ö£Påûrõ®àÕ¿þ~ÐßXìk)“º/ŠÞz±ï–0Ð$ ÝFÚc„âƒ!DãD¿ŠÆ^6Þw…ѵ9t$(R«yRK¸Á`˜I6OrŽ}ì"ORÔú+T`ᘞ›”ðEá`z¸Ðªû@¨Xì\7ÆèXG#Š¸±#¹ßÄu‡Eqf(%o Oü$|ò§Q1^Ù¸¶ÏßÀù›K¥Îs’»FiÁ¯[눘Wå¢Ö‘¸ÑØ­~xA4’)"OÎÆ03ɃÉ<X<ä^‹8,ÿ>bUê=‘RµÌ86˜gy>Ljž 暧éÚ_‹Ø…šûdRÑÈÄܘ‚nÌÛ€hte¢On}þs¹ê×òùÝÁšOµYþ[þ¦_{•ÔuIì»)¶ð“ƒüä
+^Ù¼úiàFr±¥Lj«”º.Š½ubƒ0Ü
+2ä§FùC1=ªtó G»–ŒÄH­»È“š'ÓSSg’ “33œÏGæL0>v±«9ÓRµZ)«ô™é9H̳̚‡z¦âh´ÅÊP·¨hÔ”X†å§óS¢[`/gSœŠk“âÊ4†N¿:³S¾ô1ˆÑ«ÀßT,uTKÝ—EO­è­š„¡»ªúÜüDÌ{¸ý~·0Ò!ŒvÆšgEýïþµ²‘'µ!3 3“|ž„3Â÷ ¥ˆ}RÌÂ|¨è?]SµìÂ…fá@ú³“>)2Ñõ¾HìBn´á.‡Y%"VŒä¿±"yаÄXœ©”¼.}3\¶%\¾5T±#xáÁ+{õ‡ý œ¯­Bê:µâp«0ÒÄ%ø”nÔÄ8áåÇ=üXO@Ä…ÜHh¤^µÈ“X’bR}qxVaÎò¥S-9V¢¨åDZ²Ýò¬g亄ÏëÚ:Ä.U ÌtAÚt¾1b7#¹a—âܤݬ+têPå{rõ.ùÜ‚5{u‡· ý-eRGµè©‘ˆ‹'Œy„¨chœcg\ŒêRÿû8E%C¯¸'- “+&ÓLr{ò1—Så“bÂ$E­Û8öì×ûoSçÀñüë¦\ìØ>N)BìBU~èÊP…ÚJÓ4­h[WuhÒ¤ªë½pÉÍ~i¡…¤í€RPB;ÄqÇqbÇqǹlÐvÉ9¶ãØ>vHÁÐøùìyßã$& ´åÒç<G_tÎïû|= ›Ú­ýfOîÖ†ß-TþK2$qI‰r`Åt…KnÌ£•äÂY¬Úœ8øtâÃçãu/ÅN¼=õ§èç{¢öG.VGÚ‡»Ž…{> y­‚ßÎÜüÄ?îãÇø —zøÑ~>mÅeÓÐ)+qeð•â“ÃÖ~jö$¼¬Ž‘RZ³˜”FJѤ»SkLš†=x‘½ß@Ê)vŽ—*ÿ¨ÑÝb”“ÑhbbLC±€¥I@ÂWé®+6Æÿ"~ô…رßÇNîŠ6¼;Ó\
+\Œ8ê‹áÞ3!OSÈk†ºø?æã'†é™º‘¢Q
+ üD¹!ôöýH _Eö*þœß®h$lƒ4.Š±4/Y’›*É¥×p‡EK‘X¹Q¬ú‰X³%QûLüÈŽØ'/Ï~úÚìÙ7£û"mú(.
+¾VÁï
+^~´Šq|zûh=ÔŠð›tT|Âb˜zR­'å7RJk“}>z&[`ß¾]ÃѽZù9‚aØE¸x©žßS¸*)á&|/£?SþQiÜ]‘=µI—45 ¹ÅO$‹÷E@cÕf±æg‰÷žø`{¼î¥ØG¿š=ùÇè™7fšJf.VFõa×iÊÅ%õ¹@ŒBÀÍ”ØO¹(‹1àf÷]ì7NÅ®»ÅˆnÄ°5‘ª=É0)­}OJ’—l…3ÝÀ —‚MI‰aÙáf‹õ+1){rfŸî{y nµVü öœòB ‘º1/íÆÒ<Ñò”XýãÄ¡ç>ûøױ㿛=ýçèÙ¿P1¶X"G#]ÇB}  Ä1ô²<”‹‹VìL²ä©ädP\ã¢YÊM ÃVMµž„ôÌ“k“ì )hÖߪ6ªÊ“¢Ò€a#pãôní2L
+oiåГL‰„&c’ÑhbP\´b¹f¡Â»Óˆ•›µÏÄ?اb|eöÌëÑóoÏ´TDZFõáîãa÷¹P£0h§ää'†è™ê‘¹$I¹Ø“)Ãû„bÄ°ìMž”_sÛ¶mRÖxR"úœ0 ®Up0PY–Õ‰&Cè© RÂõÌ~åßwû¯Ñh\JþJfa™&YV,Í£•14²%’'E˱r£Xµ9qx[ü英˜ýÇëÑ {glæˆýHØu:Ü{6Ô×ò4‡|m‚¿ƒNÑ>*FŠÆ>è¥híÒh솻ØY•ˆa*J¥žÌÏ×æåIÙƒIvÐG« “‚’RéiˆaØC–(7oieR®áÎ=~Ì­âF3ýÓ2iÊcInªø‰TI®ŒF±‚YñàÓ‰Ú­TŒGvÄŽývöäkцw¢Íe‘öÑÎCž&aÐNó;
+=©×jáœ&Z¶y˜ 7*Ñ“–ý.VªŸÞ£™f¤Œ3.šW$£ˆ¸€ÆdÉR~,׈–"*Æ÷¶&=?úB¼þ—±¯D?ÛýüoÑ ûgÚÞ‹tÔ…]gBýø?Úσ YÂÂEº€[ õÒŸÑÑàdJ¼KŒ hD7b¶Jjó¤ü‚FÊ2L.)“~ÞbL6eˆ†=pl ÏÐ'C{ò“¥šT¹&Y¦¡n”éÈô(Z6ˆ5?Mz.~ôÅØßwΞÜ=ûå¢Í1:êÂ=§Bîs¡K‚¿ƒ¤ Ђž´!î(.æ\Tbf(F Ã,zR›½˜$ô™£ IÂ)Ñ“–•™hð'á1\¯ä Ùýº$yêzýöTÝŽø'¿‰újôÜ_£û"—j"Žúp÷ñ°ët¨¯!äµ ~;U(qb˜¹Ñǽ2…@/ QîÎh%QŒ†=–TåÉôÛååIYêI‰=3ɉî¿ÕFåÇ"†aß>`$áRf*É›UÆ[ÕF¸†;sf]¬zë´½nºß*x[âc=âd8è‚}ÂØ€0áçÇø '=Œˆ]«ÒQñ™‚a˜:S›'µ
+“ð!%åUb˜#†$FÊOI Ãî¬P»0¥ù¿ƒE)yÙšô¢É0O
+wçäÕ€»ûŸÇ•Î/}Žäe_tÌî8C¬é7ò#èF ÃÖVêñ¤üjö휜Å@ø¡Ož$›`$ݪ6¦Ð“¶ÆÍúECÂþô»^ÉÝ©5‚-Src‚<yŸUÞÓxÊ×Þ0Òiw]úb ¶è©!çÔP·p…F]ŠO ð•©Ç“zF[P o×YìI8^f¤4éÁ“Iô$†­™Ræ%C^«à •œh2¤Lœhæ®Ã\i#srˆÖ2kaG"„d®õáÖFoûy‡5Ðe»ì±_ñv|5Ø9íï[†”ž†a™©Ä“ò{åççKÙŽIIjÙIŸ_$’fîz%zÔΔnÞb¼Ye¼!¯Jö·žH¸ë¤(I6e¬àÉ&3ò~‡Õj]ú`.÷w4ûìƒöơΦ‘.뤻õ‹‡,Ìi7lãò~.\™{»âóÃ0õ¤OêµZmA”ý˜Lì-RfýíŽ2Åç)†©,ÑL™"tάD(EÒ’Lý5R$‘-w-[`$ù®ûÏ~ÉÚœùÙ×Õ<doîlrÀ¹ùŠ×ñ¯þöQ§mÒÝvÅkÿ·¿kjˆò2ÄlJoò4Åg †aë;5x’¾T~>ˆRZ7ždSI4`x]µ”ö}ÄôHi¦#oVïÔ)#‰1IôI‹1^mX¶X[vRF>üÎCÉü8ÚÞžvX‡Ípñ¥¯3ØÓA§m¢÷ÒeO;Üùj° vx€%¤ø¬Á0l}§Oj
+¤uƒI‰¾ œ¾>ô¬hÖߪ6¢'1ìñ%ÊrÞb¼QÉÑuwÒ÷‹æk´ËV(±À"Í‘õž³L•píàɦ‡ 09ánt·:),G:­£Ý¶q×Åɾ¶+^;ðR¶¥âCðuÙº÷¤ž½Q~~¾´ž<¹p$‰¦[z¨)=v1lý•bgXeÿ©â¾® ž¤7‰^4qÉr.U¼ai5’Úc0äÊcq+Ëäå ãü`ØÒ
+˜uÚ‚=-½­n›¿£qÈÑè¶pçÒeO»lË{L姆aÙغ÷$¤+(Ö&‰…¾Î<)„écNñ±‹aë'‹pÀÈÛ5H’Ýçàfœp)²A"[2–bŽdcŒTj+ ÄKÌ‹­VëXçÿÙ/ûߦ®3ŽûoäʼníØؾβP4
+]é`/ݺn¬“ÚªnSÑ´vlëTUh´ˆ‰ØÇNÒº•N]×®h«R¶Ä÷ú-±¯ßóŠßWBÒ MjqL€ØÊ~¾{ιŽc‡Ð&ƒæ&ÎyôÑÕ½'`ÅÑ=ßïç°1°Jž·éîíéLøàÑ
+ÀJ‡õr0ä€õñ~~*êõr:ª!8MÝ’B¡¬˜ÒöIñë¨T*¡ä|Rì¯IT}éç,¸é¤oa
+ec’1a{Ìm"£néA#ñ§YüSÝ¿PMñþ#‰ÖMª|™,\ëõx@ã^[‹ÅòÂ9ï@È'V)Š%¾ò —Ü@ÐÚ9Þø&cþŠÝ’B¡P>—Ò÷IµZ¢|_ƒÁ ’1j¯[Hñ!Fò^¦P6ˆÉ.ÜÀuÖ¬¿Ùl¸ÝRKÖµ°³>12£mÅ{NtÈu£‘Ëϱ%Ïq›ÂÙ÷r#Ý£=îTÀ'’‰õ’ˆ%õXÁ-ÓAûp—ë|¯{¼ŸŸŠú>"nyIꪢP(ëœöIQ&u:€K`çÿÿ5¸×„«¨ªðšy¡)Êg’oŒX#Á!ç, œÈn4ÈOµ3FæJƒaþäŽâFØ€1‚*|L`lq7v „œ!GÒo‹ólN/‰[‚Xƈ[‚v†#Ýc}Ñ-)
+eYJÛ'µPª2)ùvƒ~ü´¥÷£ÔMM¡¬sÄc×5 s«Ù
+%쓂ЇöÀ5cÔçê’*%…R œ¶ð¾ €FÂÉëF3ƒˆI"ÝLjɯC悈@2Á%„™Å%ŽzZSØ-YÑ$Çûù¡°+žÉã•œaŠzÉ[EÄÇ”ß6vŽöº'"Þ©¨¿À-C’÷…BY{JØ'5*•PÒ2I»Y¤Ïš´·[j³Rw7…².
+Ò_33óÌ­f"&ì‘lƒ_ÅH& M¤‘wBhÉJŒo{Û^+˜äHOçPØ•Ø>îN«\¢—Qè–¶ c¸Ëu¾×}á? P±¤P6Ô'Eut ©Q©Ô*UBY£PÔ(•°"l™ÄƒÛ|R•1én41Ô')›Ž‚wþº…™ob®š±CÂñ*ƒ
+‡ü)8Ž[\áبûŸ¢+&|lÒÏ „œà– ‹±»‹å· Mì!ÇhO'qKÿ]jHú*¤P(÷Èú÷I­:g:F¯ÑÀ¦¦F­TªªŠªªj¹~mpHµR%z掯Ôí}h·Ø›¦/ð×Ìšì“’—;…²†dÉuÎÂ|ÚR;kÖgŒz¬—+ei…÷kwÉ™ý LØ,™p/s d2ÿp‘cÓn6ákñlœÇÆx¾×=ÜÝñJ¹Ä-¸·Lú¸ c¤»c¼ß3õMÆP@ÓÉàt2$yR(”{dúä‚=ªÁÁ!5*è¢B^UUQY¾µ¬ª²R­R1Úmõµ†ÛëÙ½ë©ý~îÙG^<Ýø{îÌŸ|mgìüYÂ,^ûAfâ“fýŒQ5*yÅS(_àŠFEøètÍÂÜn©%Ç(&ƒ
+° áÀêr †ADPÒoKø8 I¤(φ­Re®d³õЭ×̤yR
+…’ç¾û¤( …:Fü4ðÆ…BU] Ÿ©Æ€F*«ªê ÌÞ¯íþñ?xþgÏùקŒ¯¼÷†åì;pŸ}¯ÛÑ
+Æ8Öǃ@B°À=d”˜9±åa‡Â®¸½3ñ6Åà&²¨šwÖ¬§>IÙ¸dÈ5K®sÌ­fä·Ìu—Mú¬‘™mÚ!X4Æ>´¿ÿÔ!×ppÆrlþñ"Ç&C6l•|Î!´‡»:>?‚[ò«tKNu¸Oú¸TÀ6Ôå:ß랈x¡°
+­Rœ„¿-áiKøl΃açXŸ"A] ‹+Mx‚5ß "Ð!ÇHwÇx¿g"âŒù/·”¼U)”ÍÉŸQÔªsÞ¸pż=‚:nùÒðIPÇo<üÐþï~ûÙ§~ô«C?=qä·DÇ[ß>Õùá»I¿m(ì„ýŽ bÀ!S[Òωöõ
+¥$ö$.V»H+µjÉøsÝ´å$!Á^ ,4ñøØcO‰í$>åàœÓº)HÛã$mzbµ+îÂï›Ï™uÜvÛ$c;ï«G£ñ—ªqÕ÷{Ïk_w9 ‘{å—¤*ã‡Ö¹Ús¢¾µm6.ÌeÛ²‘F6{1ÆN&CÿÀxLjƬž–’1Ràã+åDp GðD¬ _¦‡fSÁÅÑ0Üò¹%A,¦O á“ÉŽ';Nœ8uüøÉcÇŽ=zìÈ‘cŸ>„j~é ŸÿÆ׿úƒï~ûõ¿zág¯ýÆuþ/¿½âûóïê5HãÂH«bih
+½,êêd"0• ðŒ0&yî9‚`Û-ûð„©ŽÇ¼ˆ!äш&ÜRp{GöYŸ¿ÑNŸÔ¯ÿñ3²|ä“ŸzñÔ)ÐÙÑñ’Ãñµ¯|ù{ßùæë?zÕùæo]uþí÷¿„:âO¦Þ†.ÂçÒ!샓q1êÅ-Óú²œFuÜo|:q>ÒoÝÜl¦êæ3¼ªt  7\¤”DsÀ$óýÁ%ù½+]UX%“*̾ªØ×zä•s'ë»8ÃN“F¶WÝR=懪§½npèß\Z›J
+ü£úü‰PsËmAÅß?ó!ªæ3ÚÒ˜~3Cê!û–‹‰Ûµ$·$ˆçŸGÜ'êµï¿ò­v¿rþ§¯ýŠ{û­_kÿ¡Ž¸˜¸Œ³© (%& {Äv9ê« äHãî„ûñ•0…rÁ?aL1Ƭ˜ÍQ"‚½6„5OmËE‚8´À!ãEáï›né?¿0çÐH&ßwKÆ赑F¶w©ªºåì©?Õá{ý†FªæP¾ñò¥?¿G™"ÜÒ'ˆ3ü¢¹thq4RÎêH@ˆ%°<Ž ¢¥Á%ÂmZÑpÅć»<÷aUPÇñ¨‡øQV¨£Ö·}1­°Ç'àf‹§®òÁ´sLÞêæq\Qˆòª™éq0ÔõÛsÜ»È÷š —¼ê44Ré\û¹ÜرŒ4òÖYÛÎÿñ±Èu8dÎ쳩ÐôР‹›\½aFú‘wSÉÀl*]#·$ˆggq4<™ð ?„7
+uwÛcݽ³\wÒ›x­ˆÍZ|J¯^è¨:í/Éä“ÄA 0I8¤
+#a’ÏÌð`)9°™b& Þ¡¯ÐË©„6\‹ÜÌE…^.9"CI, ¢œbÃ}1ïNË‘‹xpͱ½˜<ªªZ7›³xdßaòªbßpÉÖ[ÑfJÕxØ+¿U6?®*«îþõÆ'êÛ‘k$#¤úHÕ0ÏÓéôX¤Oþ0þã1ß|&<÷ç÷3¼êÝun97<¸0.guèå-î– Ru™Ü’8ˆ5
+[n4¬ØÊ&iÜt,ªAþ®yŸ>T¼˜ðI[Åi¿wQ²^?ˆ6@±Wž§ý¾[âɤª"U™¼¢8îº_jhCßoE™$ÕÇ.ÆØ“³=ÇǾʇ¿îA–ͦBŨWäBaÿÝRPÐÕ‰¸zxp>Z<é–ÑÆ ÏËùš"îki“2YÀKQëÛ"™|JÙ¶|9\2|’‘Uτ›§ê´W™´á’±ž<î•ñ‘2i…Ùß¹`oh>æâFR=‰Q·Ä«yˆ9 YÐWÐ
+êÌpp*ù`z<&ö9àL±ÌjÂ-}¥d
+˜PøíÜ-Ãü‰øã1/Ür!ZÓoæ¢å|Œt1!ô’Ä’hrÌþ,gut2Z:·ÝÞ­Nדû¤ú?æ ÕŽòò ¯²N¸A¥fVë
+Ñ„ 1ãE±cïxÔ+p•k¤è™w™t‡Ý¥µi$•õUo•¢Šá>XeŽ[¥§”˜Ïhðº<Bð
+M £ÞZ x2Öë%¾ÆdÂ?3<×]‹ÜÚvKËý èÆr>¶ak3“Xë°rf”Œ%ê…«›G?$áÁ%Ér!šª³Î!/J÷ V™´ÆEÚèé¼ËN˜íÃ\6c+PQµHÕ¹å?õH^ƒ@Â-y”L%`2î/ži " ³ZŸá–êDÜWJfSÁÅÑÈÍ\Ôr— 9Ëù6Ü‘ö3IÌ™á`!ìÉþÚ0(¨þqت2î›nRÊCŒRcÃ%?ê•ï»¥ŠâÀùŠ³³Âìënûʹ“f×øÎض¼äT­^g3Ìi~È‘#þl¤™"ÂÉRJˆ÷‚ÅnÉSŠ[Œz'þ™Tpa$ ·,çcÈ÷Ûˆøb¢.î­W¢uÛxÇR“i½þí5¥!~ßÇ5/‚ªª–M¦Ö-·‚
+“÷ÊÜ(,â ¨8 ‡džkÌñïËÒ{Wºp^UøЛ¬k‹}Ñìæ²eØiÒHª6«†àH§Ó”,“GŒ:óÍgÂ"CkŽg©[š9½än9<·\Ó…^B,M·$±$öY}ÚЭú&l'¦‡ñÓú¬DmP„-î“öŠâXgRÊ6ǰǪÓ0IC#õÊï_•k?rv¾ËwØ‹;ZG·m‹‘FRµs1ÆÄUSG]…XΦ‚³©P1êå.guöåÂê%À÷™ˆûJCséÐâh¸œÕ!
+óäsò' …w a/Þf²¿8
+ùÞ?š|óÀ×"tABÿ©óäö©eQFÒ#ƒùm¡°<‚ú´hDÜÙ´‘Mm,¥Ê†<0°äKŸ€ŸkK©xÂKJͲ)×­ÄÆÒ\cYÛÉÀK&
+kŸ·m°W_wÑa—±ºIBacUÒ#Ùl–¾ÉAÿÕÿžŒh(*Z!ÏÛ‡>î4Â^ DìŸ8Œ‘oúÞMÓ‹‡Ä ÿÿáÏ8½ÔÛA #1˜Ï a¼b˜/™3¶.é,–¶rj}>Q6˜Y6³÷Ñùqxµ ¹fÅ×gaÂn¯è`˽2µ%wç`¯ °Ð»c}qú<è#IºË[[HÚšT˜›qßhN¿%£…yòþ-'(vÂâ°ðƒ½¬ºŒ Ðs0äË)ñEX„“VP<úšoÛï9ÅH"3¤€ŒÄ`.'ÂyoS)-­lkT’5+Q·ÕL¼;È(Þ¸ÓOÚ² FàX6äj&ÞXšk,k`KîàÁ© IXßõ¥¹Š©Ø3ÀýQ¼š®Î'‹†d›“²,_ùÇH§÷ÃØ ŠM:ܽ„=¯ÍþyÀ€|ûІ„‹€§M¼‡û¦õ÷'˪±»hH æ
+"Щ$KýÏyíÇ’¡P=Ô–eSžÕ¬¸Í{’þj{¶ŒR2üåµL|}q¶±¬îŒÝRºOîÂ~Vé
+îÛXÊF6UMÇŠã$IØÓ­-Ì‹Yθoë=^?£…ª =$^z›OØn‰H—ŽAO',þüؘì™Ùyr{Ôwà#2ƒálîþ™E3R2dwœ­Î'YµCœ6þãõëJcÐÕL ÆñVNÝÉë»L°D[Þ ÂbQI.kµL ¶ c$I¾qSÛìnýå0BïêÞ_¾¥¼›Ñ“œKºKàºñ(äƒEyý@„ë¡ÇvØsLþxf©$‘‘ÌuHÐ/Ëò™k¶)Ûzw|É
+Û/`ÖÅÝÂnÎ3vY…ýZÙTàu+jgwy˜a„±ä¸ö6ƒžWS¢ƒž¼bFèù fHJú
+S…%̻ՅdÍŠ3ªñÁ*…eÏ–eS®¦c«óÉÍlj'¯ƒ-UÃ]VcØçEscqÖÅÝpZx<Ÿ<%]9y1CMÏ'Àð$ez›ìè0O¾œßO‹mâmÊÈàçÈ?áL“#ß÷×Îcw‘‘ÌÍÏ€*!«ªZ2”¢.ƒ*aöUÒ±FV­f,yâ W“\´¸n±™“ëVbcin{Eظ¼Ü+[PW;»%þâÉîÓ{›ÞÊ¥*¦2¶’t»‘M•49›ûç1bòêB­Ò$àœvÈ °áŽ®+5d€Ö!"0òEXüðhò(äkÅf€ÞðCòõ±rZŒD8¾#¸KƒÁ`F&t®†%Ä6¢E}Æ6d:—RÐ2;ïUÆ´RÃ}[º…ïU³â닳em'¯/ÏØ{)Ý+SI6–aWgIÂhëR ¶fš´’ŽqyÍÇ7„¢å'ò-ȨÃ]_£Ó™ƒ$;añÝ´Ø Ñ;ì
+¨¶õH1WI–å+§Ç=±»ô7íÐï ¯+"ì…ÚdG‡åoúèìþ«ØòO¼ú«8(Æù$yî4Á`0cŽ?Yê^Ï&jºdÑ’FgeÙT6–æjVÜ…ÿÙýeíÙ2Êl ßN®fbk É­œú¬`ì–ÒPæ%k¿g§Ý¿]«>/š qW’ˆIØÕض«h<e/Ð=^oò8‡„¨j:On·âÛ‡>î6»)¥† t 篈MRR‘^'¾#ÿ$uã`ê‰Á`>lîþàGpf1)h2¸ Æåê|r3›*2£#¡—Cƒ(ª¤øš[¹ÔN^ß-˜`˽ò‰-÷Æ–p@’›Ù9Øb $ûL)KZ^Bˆ€s–Wzç€ïՔؕöS ôŽìäEXüù±¯M¼‡Ä ’<ð{ð­³·—´øxc0˜ß˜‰ ÉÁ+0"óꌭSIÚº´½¢ºÜs·Ügú¥t—Њ ¶Ll,Í5–µ¼ÁliA¹»Ž‹$áëoåÔZ&†’<©ZÃIY—x½­˜“æIòûV@tI‰=Ÿ‘Aô…|ÀÈ×|½"¶ˆ§˜8œòº¥T !#1ÌD
+&\”e²ÎÅbÏ×€®Í&`Í¿Xà_Ƙ¤o#æb\‚CôÞŽJN'T·§ 8RÒ¹j ãq€üï‘â0R¼ªØônï¤E\œ‘.”$ƒ‘ÍÛ³‡ZŒ•ùV.Ûx¢¯Î%×’½ûß +ڶ젫šå¶To.ÀË[~áT·Šég I+’|k×æ§Kp•BL^(wÑ®:ÂA‚º%¤TÏ{ÔózœœM.LÕ´Ur4î¹d¢‘ f`B)í©1pH¸ Ë0Àˆe™ [0®ËÇÀ͵ËB*Š^ÊDWfkóI˜„zÁt´&]Œo—d¶^ʬç§á´Q’oýáÚL0YÉ›ˆÉA Òýh
+X%_z7ÍHJCù ôµŸÀ ­ØÔ}HÝ{_|raf8¶…!‘‘ f0#~¸-5og¬j„Ë°ëÌ2X9©æâ˹øR6*Ü%ý°‡€%´d†+˜ØÊÜÔz>µõÔ¼TtõR¿ Ùý‰ŽüQ’ß÷5ÂË3 ¸9²Òœ‘ˆÉAL[J¶æ_·ÒÕwŒݧž“€r ÎÓUvU²çUv鯺g$Oï;ÌÆ`0˜áŠØgvž.š°‡,=ZÒùŽ ²Z›Ÿv`Y2˜t$ô‰"–p´€Ù&[ÊDWf ÓÏŸšõR
+¢Û.ç¶Ë-Ým‹‘þôùSc9sNRúD nõx[<@Fx¸^ª£@¬=êáÖ’.Àk·á0Rá¢N'”7“„?¥ÜÌü%ênÒ‹hŒ¸zG0 fC)m²p÷H6ûe‹…u¾A¯Í'Ÿ-L®œÍZ>úR0[§ÎH9©ÍÄŸ-$7zÁÜ*vl™s¼W¿1[¾(˜ÀZË wŸöÒZ°PaŠô¬/檈Úyô@ëÈOªGº¯oH8#OÊ·F#
+n<á¶ü—•éµb lÙ;茷å™Yϧ–²(É«—0ÌyÉ çÅrELGÄMkžÞohäìÑè {Rmy:©œ`dCHò%ôÓÿî'Ý×ÖŒ #1 æ;aáîg ‰¿e´´‚U2QØÙeÓBf:´ÀÛ&«f£«sS09/
+&ð¬¸]ÎA;Œ„‘ºäv™7õå\Ìy+é—3DL‚\0ÿÑDLWè=8ì¨0ã•îÆïR<Þ§`äÙ$œáˆ­Â©ºªç?ôãÞ+s5)2ƒÁ`¾7š·g³¶+Æn~XQo<1Vç“Îoµöú[*ÌŽ-;Âo¯Ì&À–›‹F½ÞnÛÒáåó§¼Úú²O~¸ÊçM¤ÉúZ`®N¯WŸ+6uŸN(¼ÉlÇ´ªÛÖÜ
+Lê¼·ÜHXR|Š–2ÑÚL|m> ¼\›‚¹r^¾S«¹xÉdVZÜæh^ _Ìõ}ÀHû<)“*÷$òõ89ò“C?á#¼# ï'ögwÏÏ›ºxÁÃ.d$ƒÁ\/⇔۲k¯$“…$
+#mq<ô‘Ó  Ùp`©€-$[ô7ÎvL0ƒÁ`07ÆX³ù°ó´–úgAg–Éa ’U®Í'ËéHQ—íA*ÌJòGÔGð$¨RâšÇ¼‡´o@tÇ>y²%FÊ?îÀ§¼™$Ç
+rÞÞüû;ÅHœžØe“{ì³·ì«‘;ÜÔ2·pb$EQu )Îùðþ–˜mX %¹YëKE¥ŽC4?|°÷\„9°bäÉxŽ¡Ã.&Ÿ Ýj¾»˜æ-`ðp·ënCè‘&…ÀÓ—ºœäS~Ï>ÝK%þ¸ŸØU˜|óíäŸn
+Õ!ŽÃœ.”ˆŒ’óõ…¹Vi®m›‡—ñt«ÝÆð~P"SÅgñ]¨«»CŒ¤(Š¢Æ]*yà€g?
+EQEQuÂÉFòíL
+H‰ì— pTÕ€ï½/!&„ò›È_aB«A+ˆÊ„b‚J±”±ZDhÅjh¶bÑ"SlɨSF[ •q¨€vB‹P¤
+´Pù)- ü7Bd I€&ûî;=÷î&_²»ïí{{÷|“!;LöíÞsÎwÏ9ŒWàœ=øñ¥û™å÷!óጽPÚ‡„#¯Œ=^vÞï®^áØÓfØêçõV$Ax ê6GëÀ<=\á kóË°n
+]¡ï¥J{³Xú/ÀÃÝ-‚0G¿OKøK;ֺWáÌ·ÊBaפ ¥=Rä2¶˜Xœ
+ 0M5bÂcдp”;NYºý‚¾#ýpMg½äÃ|ÃÓŒÿ4ðº©ÐWŽ4,ô£v_ã}&½ú÷Ó:ì2¡ûZ=lXËÍšj0¾³«T÷<6Êg–ßñ2né}Md~Â’=§«À—}­.Øß5+å¨Û³º)áÞíHÎ8·tYçöyháÎJ-îk~'3~,Ϩö&XÆ‚dÑ ·Xn‘p.ù຤ÛøFÑ–óáPÛ>7¶¬`&ù&X护ÑM…ž5*þ~ƒûZ$š½{ùS:ÆŽãçÂVB£LJ·`Y+T×H$\gR|%²¯1Ñí닶¯†ð¾Õ4´3hž±XÞzÝ4’J ˜åwà @¤é(¶ëùÕ¶•_R¡ `_«‡ó g,Öó]ÆœÞrlØýY.8.lºg´í;jî†È¾²X8wÓÞ¸`·oO:Ý”pëZ“„DƒªEÚÅ-ãç—„#*ƒ5D^AÂ;LI5ê6è(ñV»X‹ 2·"sA—Ñó×VãTª·lø‘1ºqVx”„`¡L2% ƒ‹4²ë®ö“MÿþTÅ÷µàª¦p ¬ÀÕuwVUn2"áü`CòpˆÔÑÊþÜÿÙ¯÷«ª+ àëìs‘AGETdTðQÑXšRP#é¬m5)hÕ–g}Ôˆ $¥!)Øf,QÒÆ*>ZƒE¤B Ö·ÅG0uÄ™jEq@ïÙ{usÇIg0uf€¿s¿ß_7œýøöZëÜY«Êé†ò—<k©²þ¥K1{ê&íF[Úg¼VËÀµG:¯e7Ö ùÎË·T¶ÏÙ […5º3¤”÷·«1›ÉŠDëÖò‹D®y‹Ž3wå+Ùq‡à!²–JôÕA…(ov
+s·ºiöô-q…8‹ƒÅZÈ,lQ¯‘7®¬ÿOºi FYk‘è}…8b'<n8ÕYRˆÓ8¢8k¶»}ÎÕ÷oiL÷Ë#Ìk­yÝ3¡=L,‡Ý†·ì4.â·¯(ªt‘nÐèË67ïU‚xÚ^_íU€5–wãÇ-í6¶œÎÀµÒ2¯}å[7ܵáÓl›€æµÖì« ƒ‰¥ÿŠ"Ä-]óŠÐo6¯Uîf×s®¹ç…Ùù0³–²/¼±Ô>“­_ðz_Wü9šçµ.½Or÷?ßKSÀy­ /ô?ÝX?§è'ñ[Ư
+Ðqì'+lé­ŒŽ~Ùï_ù$Û˜¤\€özúáF±ŒÜ À=Fö_.ûLö‡ÍkQ¶ú£GýìÖç+Y I1žÓ MÃ¥”÷ï;›o¾]˜ê–òºs”Äyïk.Zæ5þÓÛ×½—îFéÄ–÷™ ‰.?»¼ÙÇ}ËÖQ$^ëk«0p®2¯E¥“~ò‡ßL4Ÿ×Z ^§b—7kò'7¥-X¡x]Ó#]Zõˆ\)›×úžô£ß½¼+k"ËI¡²–Jôµ¡Ðçjß~ùÞ‚U7ÍÞÁ:>˜ˆ"›ØÒý†ÿpñ3{+P°ÂÖ¬¬‚î&¸YåâÅÍî›êµ}4ícI«,Ò~eÝ£ïV_ y­µ {&!¿¢±DóµˆqK;Ê]ßF>šöpqóO¼´îÑ׳U§Q+fÖR‰nê üˆÆrèÍ[¸­Ãm…EeóZvñº7añº·›Òp^kÍ–wpÓR’ÞËÓ{YP^Ÿ:¢˜³y-[WŸ!ãç=þAv€¾˜óZk^w7n±¶¢ÀqÓàu™­¥´¨EÙ+ñƒy«*+õE/lͼn¬=ÐXN|´ÈqËÚ›€Û}µÌkÇOœ·*›×lXóž×Z³u^{žNj7hÁÊkùØ÷° k!³›9nþÚ×>J——TOÔ2A÷œŠ: 8¶A ߆xm8 õ„þWg‹èqüysÞ¾;[Y5Ìkmx]Ó óùŒœŒ~G“¼7ðàK´~ tà"Ø\ZØj†Œµâ­æUþ¡ü\^¯Ä<K;¿Ñ;ª!niàVu·CŠ0¹æ×ü˜ñsïßTYPðÕWØ*¼n;2ovˆ“Þ¯Ž¸¥êBÁlBšõ:ö?L×’ÎkUšµTYï”(ïÓè»|W~j__¼êô¼w¼³ºöýÚõ+_ÿ ]FR…óZkA“ɈåÍ>yúžª‰[¸s¦ÎœÑì ~Ìló·mþ×Ì}þrÐ~Ìœ~ý=oTš*×ZKô•cë›Í2 µJšÉ
+Ÿ÷ì—T{akæu)à\`Õífô+ØQ–gÖ>ãµq,^y‹¥×²j‹›¦½v}5„–ð}þ_´òCCëý¿9ˆ?¨…×5py³¸­ªÂ¸<{{n´¼9é¿ZãFp‚îŠ6¾99å%åD@€¼®í–7‹ÛËšä½qDàuX7éäüMŒA
+úæ0‰óŽPGDrøz-ç½oD‘è]]°ê[,SÒg‚ÝÛÉhå­Ûƒ,o„)ÑúZˆ€”ä‚OXÞS¢K±â‰[j_MÈëÇ°òædØû,o„)Ñ =¬dà°oý¥æÙ½]w‚:ÆIß­V•‰
+Ú0Dâ¼3Ô‘Ü©IÞÛFÔ)‰ÞÛ ª¼Åröv–7åu2Vysr“–óÞ5¢NñZ_kWG,7³¼¨².…Š›µ¾W1n*èî‹¡ÚI'½ŸcÞT¢/ö´’#’ñÁ^ "DA7Y®y#H^G€åíÌÙN(¯ëJPysRÇn’@ÙͽZòæä„Wmæ$B´ñd»Ã8b™Ín’Pyýó!Xå­ï“,o„*è%`åíb ß“×͵v‡aDÒm9Ë¡*k`µ“çìU–7Â4\ŠUÞä·Œ¡*ëóG`•·ÿ¶˜R¢· •7{~¡¬oÊëûçYÍ€I÷õöFAJôYAj'c¹*ay#Pvsçä¡Žˆ$^e#'$¯;#µ“%¹à#–7Btu ¨´/]ÂéPY¥¸(n6½ }Çj2¤ ÛÛ%†É5ŒÁJôªoNúÖ3o„*(¥¼SÔ“²˜Q¢ëZÑ@‰{’å`%º(nö©~̼*¯Ž“8ïµ_$Ë7‚•èÓ5v‰Q89m›}3¤ º
+Ny“¹Ê¼0¯ NÞzÿ‹í$ êŒ7k'§{–7æuû‘v!DÒõ ë‰P… ·Â´“±ŒßÅv’€Ysv.Jy3wh9ï#ê<¯/’·X¾ºƒå%:¥›´ïœÍém%¥¼ƒÔ>±œ°5í‰P%ú×î(õ-’+”y#d^o°ºÁÉ¡ë7BæõÓì"Cˆd\¼2k'qºIYiﬠÉT”òæäÌÌ!óº­J}‹¥Žq#d!è’7'ÿaí/¬ :$nVÞ¦³¼4¯õ½AÆ7'ýþÎòFÐüÙ¯ÿX­Ë2Žã×ýý>çðcü:$OkØ
+ÁÑa Ä"TZ˜K¡âšX˜3@‘-ÜDLÑ~àsC˜¨ÍBØšJR¸a#jdSaSB‘¿=ˆ‚œç¾ï«ëûP×jÅá¹ïë~>¯?€ÿ¾7ß}ßÏuݼHË:™Ó•Å8PËsÛ%ò!kQý¬“ šå}Õ¬“Í'0ß@5Ës•Œ7Ùy—1zÍïû’šÞšÞÂ: ª•ym184ÈhƨæÙÎR3Þ¶Éö  —å݃•Ì·]ç0Þ@5ÏOŽÞ uû ƨæ¹|ŽÜdéã TsüZÊB§Ôò£°ã tóüS%ëdNŸ=€ñªy¶cÕŒ·yìÑhæø÷ :z˨×Ëo ›åy:¶I9åµ½jŽ÷’‹‘†Jä¸
+ã ´³<SÉxûÊ!ùq
+ œŠà¤·=lC¿*€³'Á-ýg¨÷^ôIPœ¡‹`Ÿ„4ÁŽRßŠÞ Ñßá M;‰Þ ±O8Có<ûÐo  “D~‡3´„=zƒdÄ=á =ŠuRup†6p9ôèDg¨ËV¶¡_@g*‚ëep†šZÐ$F‚»£ø¸£“Q󛸿AjÛÙ1—Ñ¥Ð$DZÿa„Áå4å}ö¡_@g“KR„Áåt#£7Hlmñ­”%º«ø%
+pNŽßUoò1c÷pÕ÷¾œ‹å×ÚãêM¾æÆC˜p ’å?Œ!ã;‘Ú24 ÁJ9o[o” 8Ð)çµur>ã’ 8ЩÊG7Þ$8\)A¥n^F™ï<jO‚›|Á2Îñ}”ú®ã"+åíÝtqlgGÙ[ñ&½Á.Žßº-ÎÞècùÀ2¾Ó¸8hcù¯Œµ·â»îì’OP"çíËA' î®rgÐ!ç-uñöFzÔ¨ò/¢½NR1àîÀx=,¯‰x¼ê÷sŒ7PC~û—EÝ[ûIÌ7PÃq~O¼½É‡-eôj8>=3æÞíÂuô°|lR¼½úbz=,þp¼½%´Žsß[ p–å}•h{3tÝ~Œ7P$ç¿›h{Ki1rM,oMbíÍÐðqEœãµkoM—/ô½Å
+ ã#S¢ë-¥Ëö3Æècyw;ßÔÜ\Fo PÎ/][o†-?$
+5à|ÏÜçÒèkŒñšüÒ†æð@1—JÏØ NýPlgôºüƶÑfµÒŸMÄTo¦8‡¢‡±N‚öÔ÷ÍV«>PÈ'ï™zÁ¹´ñ ôú y»Õ(æÓɘoì€sèä|l]k¤^.dRñ¨gè€s©ý¼úå
+¹L"5¯7‡¢û‘˜Bðï,泪·ˆqÁ9tÕ«êK
+ý³½™0àŠïãN¯ÀÛ-8$ï_½¼]¯ûóé„)½ytí¿s\Y‹èíOšl«ÞúÓ‰X4bBoêÞ…ë t´Pp’Å “Ë›ƒ¥Â…Þ\íƒs©úŒZ„´#Nýó“Ëš5Õ[6iHom^Ää¸òäÂÁ=võøh­\ÈgSñÀ„Þr÷#7Г\`ñ’|tõÄØP¥Ðß—ŽQß„ÞVMc=-4à$¿¶aykh°ØŸíÍíuP Ú…u4%¥˜÷Ý”|þ–ÉÑÆ`YÍ·Ä›½é=àÊáðJ=>€K¢z›w÷R1î™j5ªª·LÒ„Þ<úøY¬“ ©noó8ÁO®l7ëåB_: ôïèo «noó'øø»Ç›Ã墚oñ âkÞ›K«N`¼®fz›ïý|úÓã£Ã%3zóh;ÆhK.4à$‹cÃÕb.m@o.ŸDo +) NðÃËTo¥\:éÞ›GÔwºrÏàR\è-œû ùWS£Íj!?Ó›§zÓ78‡Ü{q½¶älp¹w0ÁǯkTËùL*1Ó›ÆÎ¥ÆKŒñººÐ[x~Ω ùÌçZ£µ™ÞÍ{#º‰Ñhë­ÞÎÍùš†|w«U+÷gRÉ ªuoEb}ÍöªÞÎÍõ7‚¼¬Y¯äLèmÝëè ôõVogÏÌõ¢
+>ò~Õ[VûÞ\úrýgŸ ;ópÓmU
+ÙtRïû͡ƳjûÐÖlorÎë­û7|ÛH½R̦z÷æÑÍÝ  ­7Üü#øÛê@1“JÄ"¾¾½9ù!w®Ìcø¿,w{{j²6PÌjÞ›GkNc¼ÎQ[··S×ÔªÅÜloŽž½©Ou'®70ŸjòµÁb.©î7}{s©~Lý4
+à2’ï/ú’j¾yžž½¹´ië$Ø!äC¥|.ªÞM{{ã ,òñ÷äó }{siÕ Œ7°„äé-ÝÞ"ÝÞzÝÖÅøt+ÆXCðÎ|>®mo.õÿ½5:üh.›ˆE<ÏÕ±7Ö…jØ!ä'Ó3½éx¾9ä܃ë ìÑáGréxÑu¬½Œñö8Ï{r}ÚöFt#£7°G‡ïíë‹©Þt<ßòŽuì!%ß‘ÉÚööÞiôö,¶eÒATõÖë¸.Â¥=Ý_
+¡X½Å2þqæ etÓ´"Ý“‘§ô†²
+º±H½Ù9ù{ÎI”–×5“íˆ+ŠH¤7”–×û÷*Po±|—sååõÞ Åé-’=ÕzÞß Ð+N—ìš¾šŠ!‘yÛ™7”—ÓG…éÍ~ŽŸ2o(1§×Å…é-‘ƒ×Û… ”U]Ï·_ó‚ˆåtû
+qOƲ×ãÌJÎ~Ã/(ȾÍUzCÉÝ~RöÍÎÉ_‘ÊÎë–9Åèí€Í<ßPvÖÛ§ŠÐ[,ßáœDéy}vjzÌå,’]ÑzÞ_ÐcN×M*@o‰û*ó†ÒsúÔ„ôÉõÌÊÏéŸ%ÿÞùÀ3vÚ%W×Uè-–V>PvNïÉ¿·XöXμ¡üBÐk‹ÐÛG½†¼¿  ×¬·rïÍþúÅä†
+°ßò‹òMÒyØÀ9‰
+ä›íÛWû†
+ê¿–ÿ9-gÞPA·™wo±Ì¤7T××gæÝ["W‘*Áëk3rî-’‰¨Ëû‹
+½ˇ6Ъͩߟà¹B=ç$ªÍéà1ý¸(#ÙûÑ´n Òœ¾t˜O¯ÕäóªÌ*Ïéši=.’71o€ª×'êup‰L{y4]¸»'ô|áβ®hðzçÄžËØGé ‚.­Y=Éì:ç$ð&KaÑÈÞ‰ÜLnÀ¿Ù­·0îYp‘LÚÈ9 ü‡ÕpæÐõB,ç+û¼ÍkèUp‘Œ¸W]Þ(§õyõ"¸DŽäœþ‹×?-q‚‹e±Öóþt@Áx<ÂÆ({û¯aÞ€ÿåtõ´^÷erþŸ×ÕÓ³nÌ2zÞÓÇÛ{+[3ÞÐ÷
+(xýÍ@ÖÁ-ÌûS‚þz·Œƒ»5ï•·0É6¸”{xg–FÆÁíý˜ú¼?PPÖÆ9"Q†Á]¬.ï•×ú‚LƒûÄË”Àp¼†ùeÜÈÛµž÷g
+ËéÆ£³ .‘3”†åuóÑgÔ[,û<Á žÓ§Ìì Ë-V0€á8]55«…‹åˆ­4àôOíé•…Hj+è h x½ý]Ù,œÝ¥gÙ0ïOXºl\6 Ë”Az±àK& Ɉ›8(†l‘f\"s8(Ƭs3 .–‰3p@c^·‘žƒw¡º¼? PpÜ|‰º.‘<ÏÀM8Ý|DÁE’ÜÆÀÍ8Ý8+ƒ'\"'»ô= ‘º>}`÷ÁE2ð4åtÕÛ§n{“…ÊÀM9}dBÁ}|›ú¼?
+PxÁë²qÝKí~ö h.]¶[× '_å Z` ·8¨n$2ùyzZ`\u\$²Ðž‚
+ #Áæê•ïíÛâQË™ACÞ?3°ó
+ö"{ì”QiL- ÜÀs”@7ÒâþðáV&Îþ…Ù7 ;ÜËW¾Çžq̓;¼Np@wÒgÜškM'.–1䠺孢¥³k\\$§ÑÐ=Ëè…Kì¨lT\"Ó6qPÝ uÕÕóF¦Wcƒ}KnLŸ{
+$A¢ŒQÐÀ€#§Á+ X Ø
+>x4  ´Ð"2øèh;N¡´AÅ*
+% åa)Paª´ HA ) ‚’°çÑó;gƒY²÷îÝÝ{wŸ?²;“Ý»ç÷;ç{¾¿o4HÃz%"¹AÂûú‚DÇo)E$¸á8P"HHùÌ êÍ$í÷£ÞÄ9LìoÙ8©T9‚8‡‰Iº›Ä"ý/ Á!ˆS¨ØÝ9R{ƒK[#¿‚ ˆ#˜xVºVÄXä)ÁÑàÄAñÏÌÈíÈæ|Œ‡ ŽNUlÇÞ@p Poâ&v¤ÉPfKo|&¿† ˆ]¸`£íÉM~ºù.48q
+8'%&™‹þ† ÃÅù{‰åPnÒàœ•ŠE$"¨˜ç4½)½‘m¨77à8&¤LœÊwnoÀe´pƧxo%?L,pîn\×㨷¨à”†Þ1ŠLn˜¨ê+5ヘóq t§Aù7X]6»äØ%xÇPrÉ‹ £`‘(Á9g»üïw‹re';ŒZv ˆQ.Yáât^Tã$ ”m7
+ÚôO!_†k#«Û5ÿûݯ4³Ëc¿ÙÓèŸH’ÁÅ $J½Iƒ›†z³ £j¯{ï…‚.²…†i
+˜LoW_¯0Hú>4¸¦`z8¼ð—YtЪ2Â:Ê‘n£çïƒ/qŠóºÿ¡âHw7ô&yU Á]T‚©]5)¿l—y=­5HNÛ\÷áo–«'`–ó9rÿžsGn&É=/ð‡Žl+—æ´„nYMjíJc!âY™C{ì’€,—èJ(`b_ñÖ_ƒ4߀þvMdd±ý`ÁÃU«,{7œaZðÒ~äÒëä–1Œr~EnÜ$7Ħ7ʯÀ¥<൦ôå!­µxœ\o¡ou~léQýTl´abo—Ò›|LÖa(¿L(pþݳ2 EFÓ‘-¼ä´æz]\ÕèшŸ`b¼;Ó$œB^4Ñy¦²V}å[…·¶’ý±"lá{ ƒe‹œÑ+Oã1Ëù *þÑÉ-{#$@×ã@‚S¸zjö.Ölº 6…a䬮ãþTΔÉaÃ}ƒÜ«)ÄrçÀQ i¥"˜è¢e¶ÊÍ¿¸?CkÄ­‚4z\·Éï*Ê¡äüÛÛ»go`pSEªo>gz¤>ñöÔþiJ¦«bÓ„zû„’Jõ£˜å|
+ŽsN¡îÊ/ß—¡•s±) Kå.×|"žÑTç= K‰Ëz3H«=©§7ÎtÉÿ}wjÿ€jC,"[ø¦ë_Ë)ZzD¯%çE˜ø_/bº¼õ„ÌãL!8Óõè¼Çï€)R&¶xŠ-Ôw­¹Þ/®‚µ0ÌrÞƒ‹ÉnË ÊœÚTÒƒÜ$ê¼2äfˆR¸ÛU­WY.{ÔÊj¸
+‘­¾¢¬¨Gº¬Åômd ‹aäÒ²ŸÙrJVÊ‚>¾½ŽlíÌ˜Ë n„/Jjàš¸´{ÅS™º¤›Æ°Ôè5£´B¨¹Ò‡›åd[ç$ögÈ$™;|gp\§™º-¿ÙAW‘‘-<¦>÷¯¬nT=â"œŠ8È îyá«dÀtù|Cñ}ÕaL¢ÈÀ³ÐâžñkÏAñ”¢äÜ„3QÚ1.r“?Òï¤Ç)xñåªÒ±½ÚÈÅ[V
+h­3 ÿdôš¸ù t"è›=óTìÍ–Î ²Î'¥[íwFeÔùK!±) RÙÓ6V
+49÷ ¢üŽø¸ƒ{Yx}ç¸ -°ÆÚm¯?Üú‹£—z˜úΛ¾ú¸PQÎë;瘨Fâvwä¦ÃÞ(9Ó7ù…uÓ·UK6SÍÙ£«7úM^uºÂJ.*˜àc‰G½‘ׄ‡ .$¶SËÐçF¹\ËŒ_k<‹¡l.=ï™íuÐêéëÒãÈÞ“øÙ ”ùu^ÕÂQºp`ñˆN-äR- µ°”äîš½óSYÎ9r ƒÄ-¼&¹aƒJ™Ù`U5{mxºZgŠF¶°:Ë |qkµ
+Ü=gG(Ë%z+ý
+“%¬QSEÑ@©EÑXݒŬ?ƒ¿ÀlVC]¬A EØ¥¥
+*hE©`¡/¶Ìý±÷ÜymiiÝ–¾¾¹ï½óùã½Ð7ÌÜ™s?sÎW‰÷¤O•á.¼„ÏX}[2t6§ÈÞBmØEñ™Ë÷À`É6¹NBnìï“n ÜlîÃ@)„Þ '?X>Y‡ e ^–#SŠ?þYB“è\¸Ü‘î›nꃾsƒk‰l_m¾’^F¶PB-½™â¦/+?§÷f¹‹aòP±ý«!E2Œ .ÙduéÜñp}‹R”-Ô¨g
+Î ¼¤¢Yï1T®.k'ú¨Q×Îl ›o܅φª§oKËll}µaW%Ýøøèr³œ†É³Óý&‹$¼–Rx²Ø¾b¢¶1²õ1Ô'lO\ù)d9›œÒ­)Ÿøü’·ÉÂ>÷Mp¡‹]óÚÃ7è‹ZØÙ‚¥G':uù΀„(ÛÎq)
+u„òµ$dlMŸ
+'¸wöƒk ÆéêS”-|¨‡ O;yæª]º
+1œåÔ¯ö]7®T5Ú¾ºG¦Oݸ·$kTßF×µ`‚O›V|P—ÄMãÔ]¿t…¿áMc“Y }Óà¼ÈÆêv,»n \ÉñÿfcjÃ{.)ûÙšU—Å rLV$ÛïB@ƒu*Bßà„7F6y÷Á±ú2ØÙ|ÆËrrÖî;+õ\[ιrßptƒr©î¶¡Cx!¡¹r]þï(›P¯
+ƒg=»Éc(Ë1ùõ fè¦ÜèŸB8P
+¦ÏÕôñãÓG]dŠ²™¥ õi9++½mØ'AÂ<˜¬ŸjˆnÊ7²9TýM0˜LÙ™f…S;¨šqP”»2»¤º jåÆ@“ã2OŒÙŠ”äˆP'8Ȩ}cÑÕPQ¢ëŠˆ—妕þ猪˜ís¥üQbŽor ·¾©È£I`Ïß
+2¼“bd3o®$ñy¥»UݸÑ뜺µU°ËMA‰±´WŽ3]¬sÛWÌL#:$`d3Ÿ`•RòJ>ÕUdQÚæ”n¯ô3%¼ilrÓO—Ýà8ÓªÖo+¼9™À¨‚ªETO–iSW€ò‹hÌr‚Éí‰F馜ó²d—w3:²{ãÏ£¯€¡l‡W³¤ìÕÕ ª”.‹6å˜ül„Yºâ{ex!8t¶_ö¿xWª>‹mΈŒôÝäÈ€œ5{ÏJ=WF‘sLÖÞhPvó $}_œRMפþÃâÜ}
+Ë´{Bz€Êrð5xæê.ÔU¿I£&맧$¸µ²û˜{CÇÏ[š¨#›EqŒŒx(Õ¯Ìa9E•P\ƒ%—ççw§E²OwS8îÂqÍ'^ÿÓ˜DøŸÙ¢ª#AJÖS‡šTYÄ+§vê£0½‡ZÒGÝñM0ÙªËæ¦Â] lQ‡—åâ§m>P•vy$+§Ö^D œ& ·HÈß}¶Bpœú¨8o°þ/¶‘w‚ôo®$Éó_¬Òu÷Ê.7ª›ZÕ°§Á Îô÷©7š’Dô°-z VwÔ¼ç«uõY÷¢†a0ùN¢¡ºÁ@YÖeã®þå› Æ'¨cmt-ðÆ—ŒYkCñ#0Ë1¹ë*SuS‘,Ù©pÜ…—[Cõ_ïæÀqÙbåhjîÆÚF Y.ÌÂô&L0W7µ²”O.(Ufƒ?ÕU¬Êסl±E0Ë%ݹù@³å"¥Íqy*Û`Ý@¸Âv¾yªIyì%Yqp
+Ò~&enàä‰cû*wnÝöjIñcwÞ5küø´Î—@,'k;Ò}‚Y.­à…ýZ¤.º\«\Œ)+;=¦ñôéÿVî~ëµMÅ+ž\¸`îäI™©)ñ^’*Ï-O0 ! ABõÚ\Æìu߃7¼%˵ ˆ.ë¢ó}wèð‡[¶<óÄŠ…sædÝrËÕ#Gôo?"Z-Ð6ü¹K1
+ÄÊÈó$d/Á:†0×ý­á\}]Ýþ÷Ë7>ýÌó
+²¯¹vTúUCâ:œË‰ðA€eÃç°ûÞ>ÚÅšëë<òåÁOvÿ«¬¬xÑ_ò'Mç8—jd£cÒ3t“Sƒåâ—Ë·•ý}ÍÃ…÷ý17{ĨAL--˜…3"‚\&ÔÒê ì×ñïAÚ’˜‹C(D·9=Ú­zù½&‰b¢]°ÿ 0
+H‰œ–yTSwÇoÉž•°Ãc [€°5la‘QIBHØADED„ª•2ÖmtFOE.®c­Ö}êÒõ0êè8´׎8GNg¦Óïï÷9÷wïïÝß½÷ó
+ 
+V³)gB£0ñiœWו8#©8wÕ©•õ8_Å٥ʨQãüÜ«QÊj@é&»A)/ÇÙgº>'K‚ó
+€x¯Íú·¶Ò-
+¨ꇆ¡Ðnè÷ÐQètº}MA ï —0Óal»Á¾°ŽSàx ¬‚kà&¸^Á£ð>ø0|>_ƒ'á‡ð,ÂG!"F$H:Rˆ”!z¤éF‘Qd?r 9‹\A&‘GÈ ”ˆrQ ¢áhš‹ÊÑ´íE‡Ñ]èaô4zBgÐ×Á–àE#H ‹*B=¡‹0HØIøˆp†p0MxJ$ùD1„˜D, V›‰½Ä­ÄÄãÄKÄ»ÄY‰dEò"EÒI2’ÔEÚBÚGúŒt™4MzN¦‘Èþär!YKî ’÷?%_&ß#¿¢°(®”0J:EAi¤ôQÆ(Ç()Ó”WT6U@ æP+¨íÔ!ê~êêmêæD ¥eÒÔ´å´!ÚïhŸÓ¦h/èº']B/¢éëèÒÓ¿¢?a0nŒhF!ÃÀXÇØÍ8ÅøšñÜŒkæc&5S˜µ™˜6»lö˜Iaº2c˜K™MÌAæ!æEæ#…åÆ’°d¬VÖë(ëk–Íe‹Øél »—½‡}Ž}ŸCâ¸qâ9
+N'çÎ)Î].ÂuæJ¸rî
+î÷ wšGä xR^¯‡÷[ÞoÆœchžgÞ`>bþ‰ù$á»ñ¥ü*~ÿ ÿ:ÿ¥…EŒ…ÒbÅ~‹ËÏ,m,£-•–Ý–,¯Y¾´Â¬â­*­6X[ݱF­=­3­ë­·YŸ±~dó ·‘ÛtÛ´¹i ÛzÚfÙ6Û~`{ÁvÖÎÞ.ÑNg·Åî”Ý#{¾}´}…ý€ý§ö¸‘j‡‡ÏþŠ™c1X6„Æfm“Ž;'_9 œr:œ8Ýq¦:‹ËœœO:ϸ8¸¤¹´¸ìu¹éJq»–»nv=ëúÌMà–ï¶ÊmÜí¾ÀR 4 ö
+n»3Ü£ÜkÜGݯz=Ä•[=¾ô„=ƒ<Ë=G</zÁ^Á^j¯­^—¼ Þ¡ÞZïQïBº0FX'Ü+œòáû¤útøŒû<öuñ-ôÝà{Ö÷µ__•ß˜ß-G”,ê}çïé/÷ñ¿ÀHh 8ðm W 2p[àŸƒ¸AiA«‚Ný#8$X¼?øAˆKHIÈ{!7Ä<q†¸Wüy(!46´-ôãÐaÁa†°ƒa†W†ï ¿¿@°@¹`lÁݧYÄŽˆÉH,²$òýÈÉ(Ç(YÔhÔ7ÑÎÑŠèÑ÷b<b*böÅ<Žõ‹ÕÇ~ûL&Y&9‡Ä%ÆuÇMÄsâsã‡ã¿NpJP%ìM˜I JlN<žDHJIÚtCj'•KwKg’C’—%ŸN¡§d§ §|“ꙪO=–§%§mL»½Ðu¡váx:H—¦oL¿“!ȨÉøC&13#s$ó/Y¢¬–¬³ÙÜìâì=ÙOsbsúrnåºçsOæ1óŠòvç=ËËïÏŸ\ä»hÙ¢óÖê‚#…¤Â¼Â…³‹ãoZ<]TÔUt}‰`IÃ’sK­—V-ý¤˜Y,+>TB(É/ÙSòƒ,]6*›-•–¾W:#—È7Ë*¢ŠÊe¿ò^YDYÙ}U„j£êAyTù`ù#µD=¬þ¶"©b{ųÊôÊ+¬Ê¯: !kJ4Gµm¥ötµ}uCõ%—®K7YV³©fFŸ¢ßY Õ.©=bàá?SŒîÆ•Æ©ºÈº‘ºçõyõ‡Ø Ú† žkï5%4ý¦m–7Ÿlqlio™Z³lG+ÔZÚz²Í¹­³mzyâò]íÔöÊö?uøuôw|¿"űN»ÎåwW&®ÜÛe֥ﺱ*|ÕöÕèjõê‰5k¶¬yÝ­èþ¢Ç¯g°ç‡^yïkEk‡Öþ¸®lÝD_p߶õÄõÚõ×7DmØÕÏîoê¿»1mãál {àûMśΠnßLÝlÜ<9”úO
+¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäüå„æ æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿ
+%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 19.2.1 %%For: (Zachary Mitton) () %%Title: (metamask_icon) %%CreationDate: 6/15/16 2:23 PM %%Canvassize: 16383 %%BoundingBox: 98 -140 188 -44 %%HiResBoundingBox: 98.7919746568114 -140 188 -44 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 147 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 79 -156 207 -28 %AI3_TemplateBox: 180.5 -120.5 180.5 -120.5 %AI3_TileBox: -163 -488 449 304 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: -39.6666666666679 23.666666666667 3 1419 866 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -39.6666666666679 23.666666666667 3 1419 866 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:-220 -420 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 24 0 obj <</Length 22700>>stream
+%%BoundingBox: 98 -140 188 -44 %%HiResBoundingBox: 98.7919746568114 -140 188 -44 %AI7_Thumbnail: 120 128 8 %%BeginData: 22554 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD24FFA776FD75FFA04A4AA1FD73FFA04A754A75A8FD71FF7C4475 %4A6F4A6FA8FD6FFFA04A754B754B754A75FD6EFF764A6F4A754A6F4A754A %76FD6CFF764A754B754A754B754A754AA1FD69FFA8754A6F4A754A6F4A75 %4A6F4A6F4AA1FD44FFA7C9A075A8FD1EFFA8754A754B754B754B754B754B %754B754ACAFD3FFFCFC9C299C1997476FD1EFFA76F4A754A6F4A754A6F4A %754A6F4A754A4B4AFD3BFFA7C99FC198BB98C198754AA8FD1DFFA8754A75 %4A754B754A754B754A754B754A754B6F76FD37FFC9C99FC198C199C199C1 %99754A75FD1DFFA74B4A754A6F4A754A6F4A754A6F4A754A6F4A754A4A76 %FD31FFA8C9A0C1999998C1999F99C199C1746F4A4A76FD1CFFA1754A754B %754B754B754B754B754B754B754B754B754B6F7CFD2CFFCAC9C89FC198C1 %99C199C199C199C1C1C175754B754ACAFD1BFF7D4A4A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A6FA8FD27FFCAC9A1C2989998C199C199 %C199C199C199C199C16E4B4A754A75A8FD1AFF7C6F4A754B754A754B754A %754B754A754B754A754B754A754B754A75FD24FFC9C99FC199C199C199C1 %99C199C199C199C199C1C1994A754B754A6F76FD1AFF764A4A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A76A8FD1DFFA7C9A0C1 %99BB989998C1999F99C1999F99C1999F99C199C199994A4B4A754A6F4AA8 %FD19FF756F4B754B754B754B754B754B754B754B754B754B754B754B754B %754B754A76FD1AFFCAC299C198C199C199C199C199C199C199C199C199C1 %99C199C199994B754B754B754A7CFD19FF764A4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A99FD04C199C1C1C199C1 %C1C199C1C1C199C1C1C199C1C1C199C198C199C199C199C199C199C199C1 %99C199C199C199C199C199754A754A6F4A754A4A7DFD18FF7C6E4B754A75 %4B754A754B754A754B754A754B754A754B754A754B754A754B754A754BFD %05C1BBC1C1C1BBC1C1C1BBC1C1C1BBC1C1C1BBC1C1C199C199C199C199C1 %99C199C199C199C199C199C199C199C199754B754A754B754A754BFD19FF %754A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A4B74C199C199C199C199C199C199C199C199C199C199C199C199 %9F99C1999F99C1999F99C1999F99C1999F99C1999F99C1994B4A754A6F4A %754A6F4A76FD18FFA14A754B754B754B754B754B754B754B754B754B754B %754B754B754B754B754B754B754B7599C2FD16C199C199C199C199C199C1 %99C199C199C199C199C199C175754B754B754B754B754B75A1FD18FF4A4B %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1 %99C199C199C199C199C199C199C199C199C199C16E4B4A6F4A754A6F4A75 %4A6F4AFD18FFA16F4B754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B75FD16C199C199C199C199C199C199 %C199C199C199C1999F6F754A754B754A754B754A754A7CFD18FF764A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A9999C199C199C199C199C199C199C199C199C199C199C199 %9F99C1999F99C1999F99C1999F99C199994A6F4A6F4A754A6F4A754A6F4A %4A7DFD17FFCA4A754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B7575FD17C199C199C199C199C199C1 %99C199C1C1994B754B754B754B754B754B754B754BFD18FF764A4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A4B74C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1 %99C199C199C199C199C199C199754A6F4A754A6F4A754A6F4A754A6F4A7C %FD18FF754B754A754B754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B7599FD13C1BBC199C199C199C199C1 %99C199C199754A754B754A754B754A754B754A754B75A8FD17FFA04A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A7599C199C199C199C199C199C199C199C199C199 %C199C1999F99C1999F99C199C174754A6F4A754A6F4A754A6F4A754A6F4A %6F75FD18FF4A754B754B754B754B754B754B754B754B754B754B754B754B %754B754B754B754B754B754B754B754B754B754A9FFD14C199C199C199C1 %99C199C175754B754B754B754B754B754B754B754B754AA7FD17FF7D4A4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A4B4AC1C1C199C1BBC199C1BBC199C1BBC199 %C1BBC199C199C199C199C199C16F4B4A754A6F4A754A6F4A754A6F4A754A %6F4A75A8FD17FF764A754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B7575FD13C199C1 %99C199C1BBC16F754B754A754B754A754B754A754B754A754B6F75FD17FF %A84A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A4B74C199C199C199C199C199 %C199C199C199C199C199C199C199994A4B4A754A6F4A754A6F4A754A6F4A %754A6F4A754AA1FD17FF76754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %9FFD11C199C199C199994B754B754B754B754B754B754B754B754B754B75 %4B75A8FD16FFA86F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A99C1C1 %99C1BBC199C1BBC199C1BBC199C1BBC199C199994A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A6F4A6F75FD17FFA74A754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A754B754A754B754A754B754A %754B754A754B754AFD13C199754B754A754B754A754B754A754B754A754B %754A754B754ACAFD16FFCA4A6F4A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A4B4AC1BBC199C199C199C199C199C199C199C1996F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A75FD17FF7D6F4B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B7599FD10C19F4A754B754B754B754B754B %754B754B754B754B754B754B6F7CFD17FF764A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A7599C1BBC199C1BBC199C1BBC199C1BBC199C1C199 %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754AA8FD17FF75754A %754B754A754B754A754B754A754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A7599C199FD12C1994A754B75 %4A754B754A754B754A754B754A754B754A75FD17FFA8754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A7599C1999999C199C199C199C199C199C199 %C199C199C199994A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A7CFD %17FF75754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B7599C199C199FD13C1 %99994B754B754B754B754B754B754B754B754B754B754A7CFD15FFA8754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A7599C199C199C199C1BBC199C1BB %C199C1BBC199C1BBC199C199C199994A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A76A8FD13FFA84A754B754A754B754A754B754A754B754A75 %4B754A754B754A754B754A754B754A754B754A754B754A754B754A754B75 %99C199C199C199C199FD0FC1BBC199C199994B754A754B754A754B754A75 %4B754A754B754A754AFD14FFA14A4A754A6F4A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %75C199C1999F99C199C199C199C199C199C199C199C199C199C199C199C1 %99754A6F4A754A6F4A754A6F4A754A6F4A754A4B4AA8FD14FF7C4A754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B7599C199C199C199C199C199FD11C199C199C1 %C1754A754B754B754B754B754B754B754B7576FD12FFA8A151754A6F4A75 %4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A4B74C199C199C199C199C199C199C1BBC199C1 %BBC199C1BBC199C1BBC199C199C199C199754A754A6F4A754A6F4A754A6F %4A754A757DFD11FFA14A4A4A754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A754B754A754B754A7575C199 %C199C199C199C199C199C1BBFD0FC199C199C199C199754A754B754A754B %754A754B754A754A4A75CFFD10FFA8754A4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %4B6EC1999F99C1999F99C1999F99C199C199C199C199C199C199C199C199 %C199C199C1999F99C199754A754A6F4A754A6F4A754A6F4A754A4A4ACAFD %11FFA8754A754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B7575C199C199C199C199C199C199C1 %99C199FD11C199C199C199C199754B754B754B754B754B754B754B754ACA %FD13FFA87C4A4B4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A756EC199C199C199C199C199C199C199 %C199C199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C199754A %6F4A754A6F4A754A6F4A754AA7FD17FF75754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B756FC199C199C1 %99C199C199C199C199C199C199FD11C199C199C199C199C199754B754A75 %4B754A754B754A76FD13FFA8CA7DA176754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A4B6EC199C1999F99 %C1999F99C1999F99C1999F99C199C199C199C199C199C199C199C199C199 %9F99C1999F99C199C198754A6F4A754A6F4A754A4B4AFD12FFA87C4A4A4A %754B754B754B754B754B754B754B754B754B754B754B754B754B754B754B %754B754B754B7575C199C199C199C199C199C199C199C199C199C199FD11 %C199C199C199C199C199C199754B754B754B754B754A75FD14FFA8754A4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A4B4A9F99C199C199C199C199C199C199C199C199C199C199C199 %C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C199C1994B4A754A %6F4A754A6F4AFD16FFA8A14B754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A7575C199C199C199C199C199C199C199 %C199C199C199C199C199FD11C199C199C199C199C199C199754A754B754A %754B6FA7FD18FF516F4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A4B4AC1999F99C1999F99C1999F99C1999F99C1999F99 %C1999F99C199C199C199C199C199C199C199C199C1999F99C1999F99C199 %9F99C1754B4A754A6F4A6F4AA8FD17FFA1754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754BC1C1C199C199C199C199C1 %99C199C199C199C199C199C199C199FD11C199C199C199C199C199C199C1 %75754B754B754AA7FD15FFA8A14B4A4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A756E9999C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C1BBC199C1BBC199C1BBC199C199 %C199C199C199C199C199C199C174754A6F4AA1FD17FF4B6F4B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B754AC1C1C199C1 %99C199C199C199C199C199C199C199C199C199C199C199FD11C199C199C1 %99C199C199C199C199C175754A76FD18FFCA4B4B4A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A6F4A9999C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C199C199C199C199C199C1 %99C199C199C1999F99C1999F99C1999F99C199C16E4BA8FD1AFF756F4B75 %4B754B754B754B754B754B754B754B754B754B754B754B756F9F99C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199FD0FC1 %99C199C199C199C199C199C199C199C1A1FD1CFF4B4B4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A4B4A9F99C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C1BBC199C1BBC1 %99C1BBC199C199C199C199C199C199C199C199C198CAFD1CFFCF4A754A75 %4B754A754B754A754B754A754B754A754B754A754B9999C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199FD0FC199C1 %99C199C199C199C199C199C199C1CAFD1DFFA84A6F4A754A6F4A754A6F4A %754A754A754A754A754A6F4A99999F99C1999F99C1999F99C1999F99C199 %9F99C1999F99C1999F99C1999F99C1999F99C199C199C199C199C199C199 %C199C199C1999F99C1999F99C1999F99C199FD1FFFC299C1C1C19FFD0FC1 %99C1C1C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199FD11C199C199C199C199C199C199C199C2FD1EFFCABBC1 %99C1C1C199C1C1C199C1C1C199C1C1C199C1C1C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1BBC199C1BBC199C1BBC199C199C199C199C199C199C199C1A0FD1EFF %FD18C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199FD0FC199C199C199C199C199C199C198C9FD1DFF %C9C199C199C199C199C199C199C199C199C199C199C199C199C199C1999F %99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1 %999F99C199C199C199C199C199C199C199C199C1999F99C1999F99C19999 %A1FD1DFFC9BBFD19C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199FD0FC199C199C199C199C199C199C198 %C9FD1DFFC1C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C1 %99C199BBA7FD1CFFC9FD1BC199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199FD0FC199C199C199C199C1 %99C199CFFD1CFFC298C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C1999F99C1999F99C1999F99C1999F99C1999F99C1999F %99C1999F99C1999F99C1999F99C199C199C199C199C199C199C1999F99C1 %999F99C1999F98C1A8FD1CFFFD1EC199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199FD0FC199C199C199C199 %C199C199FD1CFFC9C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C199C199C199C199C199C199C199C199C199C199C199 %C199C1999999C1999999C1999999C1BBC199C1BBC199C1BBC199C1999999 %C19999989999999899A8FD1BFFC2FD1EC1BBC199C199C199C199C199C199 %C1999999C1999999C1999999C199BB99C1999999C1999999FD0DC1999999 %C1999999C1999998C9FD1AFFC998C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199999899999998999999989999 %99989999999899999998BB999998999999989999C199C199C199C199C199 %C199C199C199999899279998999999A0FD1AFFC2FD23C199C199C199C199 %C199C199C199C199C199C199C1999F515299C199C199C199C199FD0DC199 %9999C1992E4BC199C199C2A8FD18FFCAC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C19999989999 %99989999999899999998C175510528057598999999989999C199C1BBC199 %C1BBC199C1BBC199C19999989927286FBB99C198C9FD18FFC9BBFD25C199 %C199C199C1999999C1999999C1BB994B2E0628272E279999C1999999C199 %FD0DC1BBC199BB992E282E99C199C1A0FD18FF9FC199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C1999F99 %C1999998999999989999BB98752706052827280528279998FD0499C199C1 %99C199C199C199C199C199C1989998990528054B98C198A0A9FD16FFCAFD %29C199C199C199C199C1999F7552282E272E272E272E272875C199C199C1 %99FD0FC199C1752E062E51C1BBC199FD17FFC998C1BBC199C1BBC199C1BB %C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C199C199C199C199992706052805280528272805280528989999C199C199 %C199C1BBC199C1BBC199C1BBC199999951057699C199C1999FA8FD16FFFD %2AC199C199C199C199C199A07576272E2728052E2728272E277599C199C1 %99C199FD0DC199C1759FFD04C199C199CAFD15FFA7C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C1999F99C199C1BBC1C1C1999F7575272827280528057598C1 %999F99C199C199C199C199C199C199C199C198BBC1C199C1999F98BBA7FD %15FFC2FD2EC199C199C199FD0BC17576512E27C19FC199C199FD0FC199FD %05C199C199CFFD14FFCA98C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1999F99C1 %999F99C1BBC199C1BBC199FD05C1999F99C199C199C199C199C1BBC199C1 %BBC199C1BBC1999999C199C1BBC198C1CAFD14FFC2FD31C199C199FD11C1 %99C199C199C199FD0DC199C199FD05C199FD14FFA8C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C1999F99C199C199C199C199C199C199C199C199C1 %99C199C1999F99C199C199C199C199C199C199C199C1999999C199C199C1 %CAFD13FFCFFD32C199C199FD15C199C199C199FD0FC1BBC1C1C199FD14FF %A0C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1 %BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C199C199C1BBC199C1BBC199C1 %BBC199C1999999C199C1CAFD13FFC1BBFD33C199C199FD15C199C199C199 %FD0DC199C1C1C1C2FD13FFC998C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1999F99C199C199C199C199C199C199C199C198C2FD13FFFD52C199C1 %99FD0DC199C1A1FD12FFA7C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1 %BBC199C1BBC199C199C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C199C199C199C199C1BBC199C1BBC199C1BBC198C9FD12FFC2BBFD35C1 %99C199C199C199FD17C199C199FD0DC1C9FD12FF99C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199999899999998C1999999C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %98C2FD11FFC9FD31C199C199BB99C199BB99C199C199C199C199FD15C199 %C199FD0BC1BAC9FD10FFC2BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1FD0499 %98999999989999C199C199C199C199C199C199C199C1BBC199C1BBC199C1 %BBC199C1BBC199C1999F99C1BBC199C1BBC199C1BBC198C9FD0EFFCFBBFD %2BC199C1999999C1999999C1999999C199C199C199C199C199C199C199C1 %99FD11C199C199FD0BC1BAC9FD0DFFA0C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C19999989999 %99989999999899999998FD0499C1999F99C1999F99C1999F99C1999F99C1 %99C199C199C199C199C199C199C199C1999F99C199C199C199C199C199C1 %98C9FD0CFFC299C19FC199C19FC199C19FC199C199C199C199C199C199C1 %99C199C199C199C199C199C199C1999999C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C19FFD0FC199FD %0CC1CFFD0BFFA79999C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C19999989999999899999998999999 %989999C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %BBC199C1BBC199C1BBC199C199C199C1BBC199C1BBC199C199CFFD0BFF99 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C1999999C1999999C1999999C1999999C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C19FC1BBFD09C199 %FD0CC1CFFD0AFFC2989F99C1999F99C1999F99C1999F99C1999F99C1999F %99C1999F99C1999F99C1999F99C199C1FD0499989999999899999998FD04 %99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1 %999F99C199C199C199C199C199C199C199C199C199C199C199CFFD09FFCA %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %FD07C199FD0CC1FD0AFF99C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199999899999998999999 %989999C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C1C1C199C1BBC199C1BBC199FD04C1 %FD09FFC999C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C1999999C1999999C1999999C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C1C1C199FD07C19975754B27A8FD07FFA8C1999F99 %C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C199 %9F99C1999F99C199999899999998FD0499C1999F99C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F %99C199C199C199C14A27F827F805F8F8F852A8FD06FF9FC199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1BBC175270027F82727272027F82752FD05FFCA98C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C1999998999999989999C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C198BB98C198C199C199C199C2A0A0A0 %C9A127F827F827F827F827F827F8F87DFD05FFC299C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C1999999C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C299C199C2A0C3A0C9A1CAA7CAA7CAA8CAA8CAA8A8 %2727F8272727F8272727F8274BFD06FFA0BB999F99C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C19999 %98FD0499C1999F99C1999F99C1999F98C1999998C198BB98C1999F99C199 %A09FA1A1A7A1A8A1A8A1A8A8A8A7A8A7A8A1A8A7A8A1A8A7A8A127F827F8 %27F827F827F827F8A8FD06FFCF99C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C29FC199C2A0C9A0C9A0C9A7CAA7CAA7CAA8 %CAA8CAA8CAA8CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA8CA27272027272720 %272727F852FD08FFC299C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C1989998BB99C199C199 %C2A0A0A0C3A0A7A1A8A7A8A1FD07A8A7A8A7A8A1A8A7A8A1A8A7A8A1A8A7 %A8A1A8A7A8A1A8A7A8A1A8A7A8A127F827F827F827F827F827A8FD08FFA1 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C198C2A1C9A0C9A1CAA7CAA7CAA8CAA8CAA8CAA7 %CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8 %CAA7CAA8CAA7CAA8A8FD0427F8272727F82752FD09FFCF98C1999F99C199 %9F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999998 %BB98C1A0C9CAFFAFFFA8A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7 %A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1 %CAA127F827F827F827F827F8A8FD0AFFC299C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C2C9CFFD0AFFA8A8 %A7A8A7CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CA %A8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8A8FD0427F827F827F87DFD0BFF %A8C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %989999C9A7CFFD10FFA8A87DA7A1A8A7A8A7CAA7A8A1A8A7A8A1A8A7A8A1 %A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1CAA127F82727 %5252767CA1A8FD0CFF9FC199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C2C9CFFD16FFA8A8A1A8A7A8A7CAA8CAA7CAA8CAA7CA %A8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7A8527D %7DA8A7CAA7A8A8FD0DFFC998C1999F99C1999F99C1999F99C1999F99C199 %9F98BB989999C9A7FD1CFFCFA7A87DA17DA8A1A8A1A8A7A8A1A8A7A8A1A8 %A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A1A77DA8A1A77DA7A1A1 %A7FD0EFFCAC199C199C199C199C199C199C199C199C199C199C2A0C9CAFD %23FFA8CAA1A8A1A8A7A8A7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CA %A7CAA8CAA7CAA7A8A1A8A1A8A1A8A1A8A8FD10FFA0C199C199C199C199C1 %99C199C199BB98C199C9CAFD29FFA8A77DA7A1A77DA8A1A8A1A8A7A8A7CA %A7A8A1A8A7A8A1A8A7A8A1CAA7A87DA8A1A77DA8A1A77DA7A1FD11FFCA98 %C199C199C199C199C199C198C2A0C9CAFD2FFFA8A8A1A7A1A8A1A8A1A8A7 %A8A7CAA8CAA7CAA8CAA7CAA8CAA7A8A1A8A1A8A1A8A1A8A1A8A1FD12FFCA %C198C1999F99C1999998C2A0CAA8FD33FFA8FFA8A87DA77DA77DA77DA77D %A8A1A8A1A8A7A8A1A8A1A77DA7A1A77DA7A1A77DA7A1FD14FFA0C199C199 %C199C1A0FD3DFFA8A8A1A8A1A8A1A8A1A8A1A8A7A8A7A8A1A8A1A8A1A8A1 %A8A1A8A1A8A1FD15FFCA98BB99C2A0CFFD41FFCFA7A8A1A17DA8A1A77DA8 %A1A77DA8A1A77DA8A1A77DA77DA17DCAFD16FFC9A7FD49FFA8A8A1A8A1A7 %A1A8A1A8A1A8A7A8A1FD04A8FFA8FD66FFA8CAA8A8A8FFA8FFA8FFFFFFA8 %FD12FFFF %%EndData endstream endobj 25 0 obj <</Length 65536>>stream
+%AI12_CompressedDataxœì½ë’$·•&øþ±?d& CŽ;\;¶f‘™õJ-©îÖn[[Y©˜¢²UZ±(­öé÷ûÎüxd&‹,²f› #+3€€Ãq98×ïüìûôóO®¾xó§»OÜq< ?ûÙùíÝówoÞþê Ÿ~óòå7_¿{Ë~þÙ/&G4ºúM~VþëÝÛ¯ïß¼þÕÁLG{4¨¼å·þ?ñ—çoÿqøÝý»wo^ÿâðó_ ê÷ï^Þ¡òÕݻ篞ý×g÷/PWŸŠn®Ÿ¿C}ü¥ ¿4ñ`eÝáÓß±þùë¿=ÿúëûÿµ&ºìðÙéÍ7¯¿¸ýåéÍÿó«Ã”Ÿ?LÆ/Þ£úÞv÷uÓæ˜&3%CÌÆøö×o^|óêîõ»Oß¾yq÷õ×ç7/ß¼ýúW‡ó?ž¿>üîù—¨y~ø¿î^¾|ó÷Ãéåó0áÙíýË;¼ò«çïÆqv®~cì³Ó7÷/¿øço^ýé“a|âÇî™tù/_£/tËßùqzö›Wøäó»wï0R<3üÙ¯OëaàC)?ÿ÷Ïî¾¼—ÁlýÇ/J·oß|õêùÛ¿â»iÂ[LݘŸØ¬õ¸{õÕK̬̂Éã1 ‘å?ë?J[¼Ž´ûóŒ‰Áìx?Üèµ~™¤»¿ÝßýýW‡~óúNgâêí»Ïu…¼Gý¿Ö|öÍË»·ÿòúþFùѤSñ»7_ܽDûùû·/ŸË H1ËÿµÁž¿ýòî–õÍËoÞɦËõ ˜êß>ÿÇ×Kz3éÙ 3õÏyýÃ}vÿçgÓ­úìËw¿2I›MÏ~ÿÕÝë?¼ùWy•OÜtŒËæҺ͇·2Ó!Lj©“á}.Ï6ËÿË(®^¾»{û“_GòÃ<öæõÏÊѼûbýè æƒë|aoþìSlÀß¿½Ç„ýêkѽ·£îÍ_¿½ÿbٚɲþO–åˆùç1“';=õ“I~R4!oŸò‰Î¶Ç;¼H]cûìü»Õ±¿ûï‚W?¿yÅ=ú5©wŽÒË7_jÝü»Ôàëß|¥ó¢ûÛùÓ·÷¯ÙçðÏR“Ÿ}úòTýúí›o¾úÍë?¿~®´ñ_ï^€
+Ó!}H“¦÷¬ªÐoï_wÈgÏß¾ûû›·¸ºÜŽÏ¿z¤×Ïÿz÷îÅ_Ú~˧ߩçOŸ¿û n”»×_|=w .³Ì™×Ïÿóó—/ï¿|ûü«¿Ü¿8œÞ~óõ_xóæåÜ÷NýüœuTñ›OX[žË·¯ÿZߥfiÐ>$_¿ó‘>kþÎÞsPù¿Ê3ê”Ü|q-yáø=Øæó¿?ÇFÿíýŸž°?!]í½Ï¶j~§òñ·x£äÿxõ§7/ï¿~µt½úäSúû/ï>ÿÇ×ï\¬?ß¿þcúü›ûwwËI|óê+r¨‡Ïÿòü«;鳶ü|î0Èe¾º—>ùä lóéõªþ×oŸq»\÷¯ß¼üâîõá3ÞLÃæ/Üæépúbø÷a,ÅHñ‡Ÿ=;½þÇ0¶?¦)vU\)¾” ÿÕù߀Ö%Í%Ó¦\­Ê å\ÊõªÜŒ·Ãx[Ëf`ë»*nUü¦-ƒü“LDIòo^•iS®Ìi.繜Ì5JýëzÀ7òѵ¹]—õÔÉàê[¿*ÁF–Aÿ±iU²‡Uþµ*'-Ãÿ±·–—VÓmÖÓ¯VuY[”a^^¿Zd]ÕõêfþËUÍ›õV+Œÿe©ëbŸæeÖ¹Ê7ëÕÆÿõgÜ]k;lÚa]ù/W–k¥dYåÔ¬ðU)ÛµÅZòŸ)×Í*Ö‡:YÃeÍXt‘ê’Me±°@CY#®Õ¹”k)7¥Ü²Ô“Å—Y¯¥‘Uòeâ³LèIÉ­Ì•—òz“¼ÊµŒØ”FÙ2 Ïås¬sλè„íÉP®Ý-VÛxç½>ùì'åOþÚßø[L¤ .øC
+S¸
+§p7ávÀ€ v)eîsœâU<Ås¼Ž·Ø ÓàSH1å4¥S:§ët‹}b²Í>‡sÊS¾Ê§|oò-ö‹&7ù ýL”NÓyº™n±iÌ•»òWá*^å«éêêê„r¾º¾º‘dñþNé”OªN§óéæt‹Ýe™mwöçpÆ
+DÆ5CÀ…ápqð·Øn×X‹.• —Kò׌ÇucqéŒØ÷7Øg\DW¸ò€›)º€;Êá®2àUn±C¯±|¼Ey­ò¢ ¸Üx;RÙ™¡-­Ø®¶’v8Pz©“ãÍ? g œxÙ'ÝHõëË—ÉvØ…0Ü®H½’„ ›*`Cl¦½­dË!·ô2r.y 9½õ&*w¯"Ü6`äÙ¼ïæË.b—åëÎÍ×/»+>P¾<s ®ð ©r Â4ÜÛ`
+ãfÖáj=íœòiã­v‰?„™»–?yZô¬Ô q¾E¥^Þ\ÞZ—áJ¸’·YYa ÍÌô(‡§ŒrrgaÄoе)L¶¾Nåš —,b…tU;Zº‘Nd6ôË»3¡C^/”.Ò†YNÁaåvÀIöBÃÔ©å¨gMs–­²Ð5åÚ£S¼CŽ¶Ôè1Z¤SßœÆï|O3û[Ë"È䈓ŠØ£%l$£"- å—ú£ ùFFÝò/õŽ™´™Ó—r6‚ÝY8è*ðß©)¹)‹©¿Å¡Š™sñ]q]±;¥ü I·èxâÖLÚüïõnfIû\„±“Jg»eºXr•û†•¯%>±,"eX—aûç¬lX~ï‹»PdS £}bÙ›à2<±á“öd÷ïôó½uXïE3Ϩr©•Í¾.E9¬ª”¨JŠ\dáªÄ('}(bs=ÞU-²lÿö4WµžÞõ=é9®"}ZÓ¬ˆ¥„YA°è†Üú€ŸLü6«%õTsë¼VJ­µ’ë´{OÕX ‹2¥=Ÿy£e[´3UC³wD翇îd¶‡°?”–¡SîÔ‡Îos<‡•ò;Ÿá‡Îñì¾÷÷XÔµôÓË?ÊôòOåBFÊÐ7ÂmLEò‹…ß°³ôs»â8Ò†ã°+ è H$ "… ("© tåÊAy–ƒ\‘ƒ( !DÊ¢JòƒˆBFÇ­HÅ×|¾Ÿ! ©,DiȪ4$òÐu‘‡N"e‘‡(‘r™¡E·"áR,RÁˆ¢Qш‘áÈÈQº é,e$JI OeSB%'äЈjæFÄ¥kˆK˜(2Qh¢Ø”|Á‰¢“J5Šøt[ë“–|97ònIø·ÈöŽ?Fø§…Š“§ÕµX¸4å̲P,~˜)uÇu­x¬ªIÕ×xÍ" ?4¬˜  Qíç†sÙÐÈ E6< KCÛvÉÚDÏ1<L\$ßç9.Ò¢–µšjý³UË­Tk]˜ˆ/R†ò‹Ý·)[µ[hJÜ”4lTy©Qóå
+p*’íºœÚ2Ì:¯Z®»ÒÿÜö¥î±a}S7zÏ¢úß-n·M^_Â…/–Y—;l»IÔÍ•é‘r54
+å½rzbâ>l4ו맕açýE|r.V½çO‰¾oGEq3Îâ§- -U…©
+ͪÞL¥TíçTJÑEUZ*mXŽM]JY«ˆ\9ùª¥U­Di¤%Î%•’ç2•r5—ÓÂÏШ=Ò´¨î÷©ÑŠ ˆÐ%ês‰ê¬(ÍIt8—iÍ4fCT
+a¤);”ä12<L7ž@2Ò0¬©Ä{“†Õy¿DžHú“ù?\~ sü­t¨-*X¶³*;ÅK>Ëy?€Ó‹+[ì ”@í±c±ÈÒ&Ä*›ÁPVËì5m³¸\Ô8ë„¥6 ŸV+-í´7b©U[­#w)öZþÐf{% 0í¶<@j»¥õ–Œ¥Xp1âfrÚbÈ=]ÏæÜì9IÚt=†G9 [>E¿ûîôâ¦XyÇ+3€·ÂÏÓÜKƒo¼JÂéO+ï˜~Q¸ÉQ0:1ÓL†<‰98§IlÂj> -âѾûð8“ÜJl+™­äu!«…¢3)]Hh% Ñ\håB#Ú¸¦ˆ×ÃL×ôo¡{[Z·&qk²¶"fÊŽmIWC¬v8Ÿž­xš}¾å•iØŽu¢’‰'^ðï{Ž‹âú߇qåm¿ÅCÇåÜIJéçÃÏž=¥ééë¾Çc@Ã0²9BŒ»kÛ±¯£‰iòcÊc°£wt½6sMô&;ýXݸCÎÒåäI1à“TÿÀ
++á¦àt€³Çµ“lð⟿ZŸ  +R>¶›„qœVÓð#â‡Ùó6³CÇxjiú7~ûäzQfdšŽ µ¸@,¶ÐËézv4­þ¢û.¤¿ûâ/÷_üb¨¿ S;;Žc4`&¬# 4Øœ6%ð0yœèSI¿RмíÊò‹ëí§ m{=´½jŒPÛë¡ëµ]¼¸ÇÕÔ| èâ|ŸsÙ|<:@>Ð lŸñm¶Æçýöÿ/zÝÿ£r.·…_±…S Åž
+_rUX‘ëµËBa3|ñ¢!<4¸S<½0—ô< Sy+úDe&£°‘WÂ@ÞAArŒÊ-^‰žøºu‰U÷×jKTˈXÈÅÅuXªï¯øÌî”á’—íÞÏe?êµÙ#užè—ÕçF¼nf¿›VÅœŠÿzàQ2ß7œsP‡€‡‹f¿¢'z­­ú3 mŠÓÉÚídq<9+Ÿ¼r>ñ3_<U”k]'
+@Å•rO®þ§"í¨÷i ‡’ 嚀y 0sÆfE€ ÅÕô:©g§µxì,>;—Ÿ¢ug{ùYôʪHNEaì‹­ÉÊ]­òÓü¬Ô•d1œ¨«†U¯¸â w]<àªç[ž )¡8¸©cÛ(ìôÍÆÿbåb<;«â]=)Ü,‘I£È¥IdÓ,v„+‘PO¢’ºD ¹QuVÕo˜ë¦«Ê¬‹Ô*rkñ$V_ba¨¸‰_³ˆ¯U€½Þ±[¤X.}õ7I¶Ê²C#ÌrOLÅù,òØÍìˆlE”­îÈkYö,²ì E™¡ˆ²n%ʦ"ÆžDŒ½1V]• Ö¯$XJ¯³ü:ˆvl`{6V„ØY‚=‰+2¬Ò¡â¬Y<çW®bcî¿™ß~Zì-CqÀÇÅŠ}³Ø³ëoëg÷üu8†šrŠs¾™m;nŽÍXþu›}!¿Õ‘?Ìj6U615r#•ÿ«½Iÿ¯n
+¿£™õwÏz·Ñ2üËë×Ï_Ý}qø²|t0¿ö>\¼©v½Â,³¬Ð½Ìe|
+…¹¸­(Cq7o]Í·`['sµØ«µþjã[ñd˜˧­1rQ•øNت¯àËðÛ8 úEùñTÔ‘<æ‡å}ž>àSð‚²žíÍ|eÂÍf¸k ñHʾƒ¿–é_
+±M¢á¼^A*Vﶦ³
+o‹DTŠÐ7 ‘Fð\'¨uYÂÌ6@ ë¶ ³,º·[ü…¶eh>ˆO*ér.Vå÷+÷h¼#²öexZ³§—Ÿ:Üi0ó$•ç‹3QNÏ
+ß‘6®V<Ï’°ª‚^Xºì®EH›¹92kÌV'jæX\+KdàìP¹8SÎÃìGYã·Ñ€3É¡e¨N”qV1ƒþ e'ž‹±ý¦„†%:СªºU†9J°–ª1ÑŸ«¡P–:¯‹v¦êluÎ{¶¨L[†5*ÙF—ä6Ô®/¡+B ‡•Æª-;–™ eÑ„åaýÇ“J§—Ú–á±߶<µÃ'ÿ Ooú_¦ÃK„ÌM ]"³\©EkF0ŒED©ÐϤE È”ˆ×θϔogŸû°Á|VUuÇ^§v)H¥!Õ {'¦x—ŠT:’ˆUªÄäjCITßÒ’…žØ¢(Z¨J(ZÔ4¬KýYöè–®l¼†Zç¨Ja†ŽÈ\"6öBi(ÎðDô9šËðPå{”iÜ{•Ÿ:ü:ü6‘KOþy¨Ã­O¹ë”0i£5*£aÖÁlðX×!X¢%R¥K努Q>E—¸±(c4”¸”,ç„Z®Û™;ò¢á^ào…;r%º( Ñ />êÁ1ˆÉ]ý3HJ¨­WÃ.=œÛCqÑ ™Q; ¾JªÜliJ‹†B†Î%œá±ÛµÔC^ײҫjL[ExD‚Z䤵 ´–n¶IË´®~Ô»üz§ôMj¿,v8Û'ÿ”2<­Ù9>µ Ooú_¦ÃªD»î ­Oسé&àÐãùºÀF
+0j¿h‚£ùMMo€p- ~v*šŸØ×fPóœj¤Ý0<м…4ŸAÍ—¸‚¡Øƪ]¬ÚÄ\ /0³)ìzdpµÂì[Œ_bøŠÝ«½¶¯jîZL]‹¡kmær‹kX›¸6æ­Ö¸Õš¶.Xµ†Æ¬uɨµ1i=dÏ.™³öLYO°^IÜÖSËù)exZ³ š¨2<½é‘ NÒOä'
+òùÏçÇßáOä'
+òùxÏçÇßáãm7æÓ?¤a>Y£Žƒkp¤iò>Æè§d§Ñ8ïí$á\Á09¶ f‡¶–Bà'ÙzgFx™qÛö¤O/e⎭þcT1ß;ɸC0ÇtmÄojj{ щ(qpþÍ‚C÷@‹í÷z £ÎNiçûm‹ùû)íx¬?þŽNvßéÀÒéÀU§ƒ!ñ¦qç¾nܺ/¹/¯®»rþvE»i]·ùóŧ³Mi|üâT3ûëÙ·¾O'—ûؤªÊ\§ÆL+ºu6Ùu&Ù¦|tÝ,ðJç­tѲ•½ K±]ŸÍÚjƒ=?Œâ‰Q‡æ`%óÖœk¬‚Ë,pHy„Ta¾kƒ5u1'ç@I¦QAÎûlÒÄ P¬8ú­MJ&â¢7nJi´Qø‰<ÕY…ôOúdßß飑F0ÌÚDõ²G3yvÇhC°Ùx/±àe¸±w9‚Ë£/ìh¢-ØUPèhŠ·nñÓu¸&ræS–wþOÑ÷øfõc[åïx•ì^$öÛûßØlx³¯qq}ª«îc¾¶©óµÝsn<œ•ƒc&æzß‹}ÇãÍû õ•ÞÇíöQ—PÜM5VåûŽ‡‘' 5æ¡Þ¿…Kë¶ÿ9ÚfKóÊÙrC$ÛŠî«éööºÛìõâ-h4ð5Œš^­73ø
+^.E/Íy“jðR®ÁKß— öþi{º v³·?úÈö|¨'ÈʾG¬¿ÉK¥6üæ𴜠ÖÊ…¹÷¸F|ý,x5Úï©¿ïvÊóî1ÏðÙa±b,®óT—ãÂËÖërTèÅhvƒÖ/ÜÌžÓãʽhùjý2~ä œÒsñ&pr|OÅÀ•sªO¸!yì‡øÂ"€pÖQÁ-×—ÙÁã*X\ÃZYåÂÜ[zõ¾Ü4ù€]%”÷zCç@醒®Æ×Ö(M»Diês—g„Ý'Ù Áæ§-tuh"BmÙ@ãL^u}DmA˜n$ýÝ$yïÜÉ`©†ž0&g’×nÕ³C7x'ƒ᥎Ü(6–Kf¤t'ì8ì=n€ñW’lŽ›ASïóuOÈûüx8SÉVÒæ*ñÿŸ;§TìœñdŽ­¨>€—ÈÙ– IÐÄ°ØXâ#Ö!ë
+®¯¼ÑMa†\QýÝ™†¢õ¹žµ>æ¬Y+|ÉZ±Î[1§z[gz[¥É¶ù1›Ô˜Û´˜ë’mJÌUrÌ5„íÃY|ŸVn‡o—dññòãw¨Ú`…xßÆNRÓKý®ðø…»¯œýi†îs‚ƒ™lÿ\7ÁPÎ||é›óTø‚GYÕugánK”€EŸ$%V`˜•t
+ú6 >+j::ÑT¨É\P—hÇÅeìlà³éŠ»PÂnñCö»%¾oÞÿ«ßS‡º5œÉ
+¾YS¸hð
+åšÊÓêóš€fW³X1V®Áþ×ÿç¿ëä ã*Â:æI±2ïõóS‡OøBI®4â4ž!ÀeVÉkÝ›?áx“Á·ÂÜ“µ'cO¶žL½jÆ4-ÀšŸo·KìüŠ¡ŸYúëâµuU²“h“% ‘J–”’L¥fd™³-yïçŒ÷›t÷uËϸÃÅ<÷®+q¦ÖeèòYmˇ_Ëï½CUÁÅVÄN`7Ž¡¹
+ ·6­˜<žr[D¯‹•å\,-§9n¼^$ Dðò³Â8¤aßw¡Øý2\¨0ï[†÷ÿê÷Ô¡z*-–¨µ-ªZ£Lç¿T½—òŒºFßh7@ Kò§`€nQ@ë°†½¹¹¬#ç¶^£MÞnúî›áRD_çyö´rwQûvåÇïp­ØýѹâÑჲÅp¡b?™MŸ•cC¤¢a7µMìðt·˜º¦;Hõ†sM”—‹8Î)”–4y%qÒ—i¨½$!¹wb‰¹-
+KúÔ «g…Ñ¢_Ìõ \ß¹Àœ¦D! ¦Ë”ª] š b—jÝQ"#ΕÿSm®2§aæû„ã+|ù;rudãȼ]‰¬A>ÌýàQø?uØýlå³R0ÌÔœn¶ø¶‚`uEssŠ¸­¤9 +Q37¢fÚ©¥Qå;NL÷óƒtø°hp) n)ÃnªÁ6WàZœ™¥œnE*Šßõ:]Ëyåu};» šöÓ•d“qþYÐJþ³Z×öã‡,È=ôê¼*©S¦ÙZ¸Å
+µ`E×;p8OÚ
+ï‘nü¾2 ;aN(¶êõFXg ¯Û`•”á¡­ðXb†mZ†bòòw Âk7Åõðþax«-²Ú(Ã…ôS[à£ïã/|ÿ×ážum*][¡WÔmØ!n;2Ñ.Âþ_¿=ß1ê1iÜãö8¼Üc±‚T]#Šwíœ-ÀÕÍÄÕ‡Iø~êÖÝ”€Ã·Q¸Î~§Õë´”^/¥CQäJé Rzý$˜Ò-Hi‰˜¾[Ȥ"k‰™Þ?hR¼«é{‹W5ªqœn ²´ƒUöÓVøi+ü´~Ú
+—
+¿wh¼pðC=áC©ÊðÁ³~óúÓ·÷¯ßÝ¿þò“OVrûºbøç¯Xã´æÓçïÞݽ} þêå?¾þú9DùòËašŽStž–~£;Xï4²3ðÆa{¬‰GìOlä
+Ç…I3Ô^³+ô0pl)=ñ4/è$«§MúÂŽŒº'0Y :DÑH˜kÇuˉÄf$©¼HºØËŸ…Æ^Ëf͵<‹$‘ßòòj¯'‡¨É²ý'peÜâ8l„¨à,X™Zæd§.¯T>×S·
+í­}¡ù[íÌϹ0qufÿÛ¿àÿòdfä7_ƒ÷øêîù»»/žá ʃì·ûÝs°‰ç7_ýãÙ›? óë·o¾ùjõL‡ŸÿâðÇ{”Á‘—Ø¢àþÅ!TfEbÀÑ(ØÀxÕL(2Ïf㴸˸$³án
+ãâó,L"ˆC"™ñzŽûJÂòЄ¶ \ˆä7TÌôóÂ[¾æ‹Ê¤£d ®+•¸¥ ¶6¿vB‡oeªW]Í!DW1•oHwm%H2kÇÁ¤ƒ±dRq'CâÃÕŽá™XZŒ‘[õ€i;Fªx#îBÞµ] y’—oeèá´Ó¸öN‡l3_œcD9æ¾ÅD/àú*m%®¡Ý
+dÞ„Sÿy]¶-•Æ ‰u•€µH¸JÙbcà®xµ[ ¶Ÿw?*ðÇ ŒrYrBàÊŸ:3Ì‘Ù§nŠsS.µ£ØçÁe·ôÝU”ÍdSi°k3GÔ>fT²9i\Èh?ü¹qûÂs÷¦iC;öŽ+xƒì#ÕÑà@EÔÅ:ª®P¯Ÿ€›‹lƒ‡XJÂŽµKun|‘ðÉÆ›Úëyµà$±ÐèÛá 8CžŽ(Aï]ÒZ0O¨ׄm x{\ê ÉF0TOÈE‡È“HfwÏãèÁaaJ@CôrÁ`%@|èR%›R˜Uø#>LØoè;yp "MfP"0Ð=âõXp©ÚÙÌé²nä |œÁ9€Àâ™APrƒ-àÉ
+á2Ã3AÞ(LŸOšÅ™\ªŒ'¬"‘D‘Ó‚ÓÇÈ3ÙÏÀ
+|=gÁ¿Á
+gÛZ½ÖÏh+ÊÀ´³¶›6,Qó”Äåõ±Y­ÐÞš×Y¾Õ¼ÿü”ý9Û>s¸úêǹ %Ò‘Æ?l„ âØm¥ m]À㽃)€L„·œŠÁpï¼è½‘Ch±Mç
+½Ï ÊS’I£8\®¾…Õ…<%4™À4.Ïi+Êà´»¶2©>=ôÏÐðo?ºR¡Ýµï4«™„ù1û·˜…œŽºº?U58?!YÞ¨Ø&Ø2<OYuf†\1?d1À¼ ‚J…Y®^U¤¥¸wRÂ1â4Qê×@R¤§'qâèA¤ ÁS"¤ÝV(Ûd@ÈDU€wÆüeº%EêAÀ[“Ô•
+Y ªBƸ4* „‡hÁÒUN­©vÍv4•N Žã[”iÉ^:ÌN"hw†@SQ‘AK'!ýSå; õ- '?d¬ ¶ˆ‘Û…ldÓ
+ƒÀeLQØ-2ux5nþ w¼¨S( 1˜£¥&y KÙµ'å…ØŽÉÀµ€µì»ÁÔ€»$FaÆîqÂRÒ'OÇ>q¯ÅˆÛLeL¤få9m#¹p\”ð ¡ŒKîdv“eŒ–œ~ÐeÜãØ ŒK¶¦“ûà¹#}0ºU±OÁˆêe¹ý€$ŠÀ|°ªxAÞ*
+ LæTøUÎþ$</k> ÖŽå&±ƒ±&ª4yrŒ(óö$bxò(¨5ÒMâ0êòúˆÉˆ“pörû‚³wÝ—#…-F6<_¤‰
+¼4Ö£VÔ»Úˉù˜¿s9)ß²zNWQF÷¢ˆm¥;’-:ôϱœ?»3ºR¡OûNó·ÚY¨Ï¹4wJË?¼YŽúÙ1’F 7lÖµŽ,í ÕþFÝç“8ÁªJ\ìoà¾À¢Yë}¼68j @)À€…7àTÛ•TÛE‰±ਟ °
+Þãicã³ c&ª›¨N-pd<ttd—pW œ#
+®«¡Ÿ*åµNX åžF^‹³ÓŽ£âÉ^ˆp¶À±‚rÕÚðf¬WY§Ë•ªå<
+ä
+`Ùó^­–7¹é1¼éq9§åM¸‰è(IDúRΖ72ƒøˆÌ z\-oÝ7Ë9 Fí4ÓüöÆBŒã‡!X°9f6Á :3m,oü(a¶)HÒS o­S-p¤¯Cˆ}78r!f.Ì. ‹ôk"'W o¤g.mím ‚½¦ÙÌBŸ#Y%µ®áOçň»X×HéóÆ«ºpdšŠ1 L
+/÷ -ƒÍ"¿UMg“h=Òl1{„uÞØÉäîäÊ`3’MœídœhŠëÕ<†1i*œ"h_wmÃw•Ú`{{*šª} '£å㜥4+qËËÙÃ-ÏðõÌPO ’UMcdm)GÐt8³Õ41MÏb /˜7–1ru¸/¨˜ŽT•TØ\Bb
+cÕ}[±2>õ•ÅdÕ?§¹úÑ­Lcó«ÌÛwž»¿0SÿkYÄ~x;(&68`d]@Ÿ‹i“ U}µq·­@3Å­¢õ¯Oʨ4|nÔÞ‚,¹ ¸xÊ€õóÌ1M”÷…ˆO#Ýi°Ú¸Ý&H-nqdq]±$«£äàŒ«ßé¡véÆó…ö¤0Ò§qTÉ£R;{Ìà¢#OR?WŸjJ–ÏÄ'$qÛ
+4Ã"ÙFjµ0ZÌ­‡eë¹HžÓ‚KÅÖßñaDcœJj{Å ·÷e¤Y³Î[¼Eõßl]©™¤Á­lëBëÝŽ
+‰²áÔyiÒê/š3ÏDo¸Â:MpÚq…yÇ‹ z¯­7­¥*Ü<7­§%'D•fW¾Ò¹rÒ""”‰èu¹ØÛ:ŸNÚ#=ÍÝØòÕ¹“Ú`o6ÐH½ÒÔ{yvwË#îžl¯´}¤úÅìû}ò2òóî9©Æt 4éãÑ8½»e×b×)t§ŸÆÑsg(]‹æ•vFy9Q”
+wœx™7c¡"—§"›ç±§®Åž/éN7ÝìvCyl•.º™‚Dá=yÈ#ȼ¹àoJ“›W+¶£3@ïxŠsvÄôÞµb×ñtùÖÖ‰tçymƒfØ{®¨<<AìØtíñ½Kª¥>ºÖnÐ¥b×%uùV7Kíó›ìŸ$ò‡Ý3œ)ÞŽ‘êI^ú´Âc_S¾ÀroœT´²#ãêx·C²AÞÁºaÔ#4[So+8Õ¸¹±à–Ê{|*&D
+ël
+Õ1 fE»hÄ5¤ÜéX1æFÃä˜HXª·PÈåI¸X ùX|Íñð5‚^É“ÀÑòIr=«Ït]F3ê¨}¥ª7Úåð¨Qï0YàÁŠu¦oe”•%D™>—Ž9tÁˆÉ†Ð/žGŽže#¾*¹ BßBu“ –ŽÊýÄØÿV æà¹É×Ñ«Çú!ô-šWÑ'µ­0•r½ƒÅǺ~,·•¥Ôñ!é^©ið¢™îËíTvÏtItÇu:+Ê!ä âHì{°ÓåDÝ>GY±Æ•n\£ø/Ê ÙñiÇ©¢'+z&;çvñ‘™äî¥×öÎì¼õʈ!ì5p¥ O´ø®ö­|¡ ß©w{Ç—$Ð$­Û{×b×í½ï§õ[·BP‰›è°ãOéÉè;y,êϾ Y¯ç¬[FK‡faÌ5¦;-Úíðˆg¼¥LÔPø>¥¥]ylí£‰Ü?ÖûÊw"CuQï*výçû¯·>ñýúÍ«ìú֋БGq»ÅE{'{:æ
+÷è±›’øÉ—Wi+vÝîw¾ÞÍf7„ÇVåãóÈ'Ë’ûQÜÅvÍ]«j.輪½€gTì’‘hL~×ö^±˜eYÝ„6³½€:oCت(‰”§Ù^@Úúdœ7ö‚Î^_íy½Ú
+Ïà DñLsL‰^¸:É®Ž~ã"Âñr™¨¯‰|’£ëªws5²mn%n!#\ˆ¢à
+¨ì–—yš£ˆ0¡9Ä¡øxJ¯xI&0!±¡¸ÂS½lÅ <ཽˆAz#௑’È(k$2JÜS¨éæ` —L%ìNO;…/Ú< &¾˜*Šãï0Æßyµf0÷
+•ÔXOñŸV:GK‡¡oe’'ñžá“o/^ùêwDFÐÝ掇ÝFãWñf¢”nØ
+¼8ݱ ɉé)Z\ɹxãf#~¶–þ£”€2Í`gWýuSq!¼nH¢ Àî¥é"ûÎ7‚±4w`>è¬Ç`±¦Å‘<`íz°*P¥ÌoƒÓ1¢Õ£gu¦Î!?„óç©‹§HÎ#o1)gœéÙ »5Šk7¶8€'*“ÅÆ%ŽôPb­ãNH¤ÌÕ„áŒjÖ2ÔÜpWôƒ°Ìàú×FpJø·O×^6‚…G¥ A„0SX´b»·;‡V“¼F ˆ
+/ƺ¸7–®EóNú¤®)(ꦑ6©~,VE ìVâ“î½SÓ¢R£fnº~ºùíÆòØ:}tê0%âGQØð¤Û ÀDèÖj[1"F°Œ¼QÞQ‰b3QÉËé ]‹›‡?‡ãh‹+&‰@z‡ñLYB€­ñ
+,%Ê¢®MÂw—Ë'I’£¤–‚Èèaì¢$ §Q=ïæ±âuŒù¨Y’åsTåB“ -Ý“Uƒ¢ Üg&Œ˜TQ«ÊL«QL¤ŸgŠy¹iPƒ¬”6ÆŽÜ}]7iR^!FKBᦢ5ˆJ«ád…2ƪ:©ªœ‘¹q§ïuÊ#U
+GbgÒy‰šöÃÎ@h <):oö^¨i¡ê&¦ë§Ûn(¬Ð쉢¦îÛ
+¡‚"deÙA53cK^í·šŠ3C†œ"«xfÊB+æDˆ ¤¾žÉuÅ…*á„MÌfHýVÛ@ã cXé=dÔ¥£ï—’ b¦”kug(]‹æ•ê“šVIµ`4f !mÇÂè :Ezé8Ó¿RÛ@ÔÎLßM7»ÝP[¥y=±µA
+é á¡ØÑÆD ”T æC׊Vc}j²x‘É Ôj˜)™BÜÐ+e <ë*ê%2.AÜ–nb;_÷ÌÌG韬ÁÞºí›è“ºVñÉ•âÎVÏËv,Œ„£¼]ß ü­wjóÚµm?­ícøºDtpÊ4£…Gb@ +(…Ú•ö­<j"°y/R;θ§ð:Q4ÎrS‰ÆÄ%f6Žtw"zSvé[èõNC*ýºÄF¶ÓJ"Í"ç™9 îØõXvZ4ï¤OêZYե洣ԅŽ—®8^Š/\÷NM‹eöš¹éúéæ·Ëãë4¯¨c ݲÀ
+X däp> ‰.hÛˆ~Ôõ$°ëtí$k£²UeG¢Ê€<å˜ÎÁK^‹Ô·xQ$d õB‹(Ü^߃먭Ş£ßB×¢}“*M6­Š94‰Oá¡
+X¦”ÌΛ”
+uÑ,ï_w³Ú<å±YÿøÌl
+rúé¡°È^SÂS‹Ž©…i1±hȤš3èä[ŽIƒŽEå¦8}Râ3f&‹ VN¸ŸˆHÑãeAÌaÐ*iq9™8ïNq†¥Ø6…8‹‹.Æp¢ÌºÚhñ‹3Öh‰íÕÓI¦ÕØi‰0îTfÄ¡»EÔ"§ä¦ ˆZœgüÍy¦/½ë¡µè !ã Ø:¡xÛ>¼Ä-/½Žâߢ§Z† {¨[Ô;ªŠ=æØqUZ¼*‘¤¢œQuºê஺/êÖ[eítÓÀlí ¥mѾQÕZ7­²nv·„†`܆êÏþEÚU ³¾Ÿvâë
+Ñùè¾ÝÍd7€GWäc4zvM$×A=ÊNe6Øo¢|À5%ʹ˜ 8’Þ@%&73Â7`pT= Ò™OÊ6«+6¨pâÒ¯7Þhû¿…‡£h 6M\ɳlƒ'®k¡¢´Æõ_o1à¨ÍS¥]¤ÝÊí´˜LÕt&: =tÓJ$+ [™TN”5¢ G¢t9òCªéäåPMœ-̃ºd<.3%ÊÔƒÈqŠ‡ÖƒqL;-"m‘‘ѳնo‰™Xlo#z9ÆxKñc ™ëZ¨$¾™ë»iÑá@5úÏØ®Îì´¨fL*J¬«ö®•9JHm .gÅš/ºSCÞ‚Ë1Z;ÊŒEúUós.GçTñ½ ë™`¶àrt*e°Ö&9ÁáiÁå¨c•]àÂ’¾¡Á–c蘄]:º7J€Yƒ-'šZ¬®hjCð=ÊÇ*ª[æ6$fó|D×(s ¤WB.ÇͪܕaZӣ̑6 Å£îØUØÏnŽ&2 ÚjáæÈ¢Ë;zþr;ױƭÅ;ã¹À/\C¼á÷è¸B Nœ¹‰(ôPt²BSê€ÛêçõØn`ß–/5€q;ÏëZ4ãÖt­Š€†ûD=e7"ˆ 2äÎ ´ ôAíë÷ÝtSØ å±¥˜Õ’-¨á<­É`+¶p÷Ö6êãH4Å]×aä^ìš]‹ È›ŽàÅb°ÓŠ.
+8ˆ<àîÙ
+µy–-œ3Á÷0m] }R÷¶ÓOƒ·3–®Åî;u­º¹éÆÒNï#‹4¯f žÆSžäáŠÓ>X)èƒpÉꮅm3™×­8‚¹ô­mP¹‚ d\×K 6פoѼЋa´Nt¾43¸ÒŒ©G¯S!xzFï½Ð¶^pÝ´´½t3ÛäÑzT9öããÜíBETÀ»"¢C¾ë ":¼]Œˆ ¯Ãˆè@ñ:ŒˆÎ~$¢ƒÉë@":¼¼$¢ÎÛ‰èô:ˆJ¯‰¨˜z»Ø¸^ÑÁìµàûþ.8D‡¢×Ct
+6…¾í~ä)°ÅÕ/v:RÉ)hÉËMÔ'†èo Ê
+ýžÞ|\oˆÌa\=yÆ)tõ3!÷š-m߈7p¢˜ç™Þ@Žy7Ž®Eó:ÕBÞµÒ”Ûݼ€÷Ã×Ïë=×¼{ýR?µú”G¦|Ù?¸V°a$T1Oب*ñEd\5!Ås¢oDÔ †4‹÷@õ€£®.ˆ3bã$n²§J{UsÁ8^}]U¹Ú~9)†¯˜Úç÷-š×¨>M«!:4ñiRê¯# ·e6ÜàâÝ¿iñ¢Xešièúig²Á#ëññÐ[%.hb7Ï =[/Ÿ¾’ab‚rQkGâ0’¥¦^3«úYÙ'î{çëç:­ Ä–: °virËwbñ™Š+®ÒV”¡UcÕ¶÷†$”ê“4…M?¶´Ê¼Ó½P©ì§ <çâÄ-1$¶Ø[&ªÖ•mI1_íVb¹F‰VcF2§†ž“i‰ó¢@Tk¹îÑÍʸLÅ°AÝä¦ù[Œö#£ý4ˆSÓ~^Ʀ5u<4¼O»‡>NÓÎÐJE(Ù¾Ðü­v
+ês.MÜÇCoEL“¼I¶«ÎÉ™Ènܶ­¨xˆ‚`;—(½VÃÚñ“ªLG+qv¦^BŠ£dI¸kQ¯dæXä½—Åa¸ï‡k4‰·Y–|²ýXºÍ;Õ;¹i•¾ÎÓ4h|^3–\ĺä&qeèß©iQ¥¸fnº~ºùíÆòØ:ý˜â\³§l(nešGQ•jâÑÃ~‹ÛZߊÆU‰°!<»j¼± Žði£ _0ÕϤ.Ø¢_÷Ž·­›+TñBÇsG±ß­¿5çr…MqçymƒvØÚ׊x¢¬-&Ìo7±÷ò²_Ÿ¨kï^ m¡Oj߿率èn,-ÅG£B"ëKöV#¡Œ9+¥(ük¥-6¦œs
+ª"à'ûstÕ'˜ï2–ør16îT¨2Ü!"óë´}ؽ¯“˜‹üHØ¿°7„®EóUíÞ´¢k’¸ã é†º±Äc&¤ C’]¿JS¡èf¢ûzÄîɦþã¡)bM7ñ6P ;T†Ä Ø²MºV´rµrû"„‚dãï ð+L€L$~I¢Xb4ÅO’ÅÀwõ:Õ´• zA0’öëd»áÎãkE3úÚ­VZ½ò0µ>ínû<´ Vª—ûQ· êܾ{ßM7ÝP[‡Q `5uf4¬ þÑ„ƒæËÖ˜+3ó°ÑŠ6F_B´ÅDœbÉïKâ-ÈÉ¢UdVÒ]|gRßB¥9¯AmA“kú8ΔÊÙh\ÜK×¢y•j•Ý¶ÂþÀ<PmÈês¹ Zœ²À–¤¸óNm‹eÒ¶sÓ÷S¦µ…Ũûã[!ˆÈà?¶7?Ad${ør $ж,Ã4ŽâàÞâ”1â?P܃'ËD$-¨zT²$æx׃‘%î)·A*&hô*œ·ˆc‘™ò@²4Fhïh§_Œ2¢ÏjaÅè™Ò41zYÖõ b^ÐQ\jo1 c§q°
+“
+6ö@a‘ae4έ€Â’„óû,MGŠq=,˜(zŠý¹C£¯ݺ&ÈÐu¨…3‚FB—w°Š£$€l
+E‡{,¨œÊ6ÜA€2’ð ó™ˆxAÒÝ @ɹkAŸvã–*óò«íà;-• ˜’dCžBÃDnÀù}'ždÑ…t_"”1ýc–Šh£¥²FZžÓ@*̓ÛdZÞ¨©\æ yÌÅ™«L£²b
+íÀ--•-´‘8 í€"d/]€T‚ìžÌ´‡¤tä>ÚPª»¸Iµ²Å(ªÏéàÊàvÁ‘Ê µuË 4O¹8oub¤)¹€{4W¶`C¤hr)´8E ¿£hñö`ŽhƒÄÀöKäÑÄï»}L­ØÃZ*h¡ú˜‚E4i…[4¿¶™g¡íëÒôÔùcªj#Þî; DKeƒÿÃõ£›ukÞí#éùiç[ôÞNiç9sÅÏRÙ ù,Ïi@€–Ñí`-ïÔ~kž…ö9—æ®N.mmÁ]
+ ,0Éö•¸+˜£¢à\±10W¶ósZpƒyt{ˆý˵­ú jŸüøD¿—Êæƒ$}»4E} õõðËÏîžožÃ~ß¼}ö‡û—wÏþíþ‹wÑþÃá—¿yýn§á§oïþv÷wŒëå×_Ú^ß¿âøïï¾~öÞýã±Ö¿½ûó»gxãÛ·o^_ž—:Þ7_µm]iF£÷÷ð«þÏ»û/ÿòî‰ïúÙ›¿—w ãÅnù²ŸÞ½}q÷úÝò¶þR×üçùŸ0Yßß¾y±|§YÚ›ágW¿qÏn^QºÐ¿Ow_Þ¿.ŸüêðóºÿÛÝ/ýG´EQ·¯ð ɺQœü©» €ñ<µf²
+ɵ©´,ÿÿãß;}áWCgšÿ„_ÿþ;üîðïÿ1¾Ð>1FFÒ>gŽg|p4‡ßîµêÞê·ËsªÛíýõ“ÏmY·Óó½ý¥n¢Ïî^¼Û¬ÙÙ¿—߉|@c5eÁD!š¾„'”1Õ®â뀑Ž™V+FkyÑ>ØÙ©*Ô ~ »é©y¢Ç#ogªclJ)+ÜÈJ&½H4œÑè†
+fé`E
+£ZT:½Ð£RÁSäó9…ˆ@ñ3›%O÷¨,ú#/h¯Š­FÀ1CvâU@uÉyPïk%d
+y –Ê }è@ƒZ™7ðp 1âW$£ãD¨‹I!GÅa×æÄTI„»‘@SVPKŠœ¨„¦úLŒ¨âXsIî´òш’‰ŽÝÒgPl>UB‹òÂn£>GRW£ž9´E&ô¥?Y#ÈЊ
+¶®­ø–l•äÁ¡JóF•çÒÂñIV’èžEÒ [ªV†Ê
+81ÕøªÉd:( iâªñDdÂ;YAÌ'ž1æ›-\¬ØÃP¢ €2mE«Ây…"ö“V$Q•Ò“Ld²QW«ËnÏø9"Í(sË8¶0ê«0Y<'ßÈ)HQ5Y˜Û‘ù¹ÊLK
+Bn
+TšÖÙ‰´ÅV’l¯ÔÂç ŠK®™£+ù¡<½b¬TŽã¤™®ÄÛÀSQƒ-B3Å”5Iºp ^l·F*bö‘ù^Ö^‡—+]én%BÞ2Œoé-kÚ5|nh°ªÏQö„!s陣¯KP2î>nKÐvÒ Šßb@LjHE°#‰
+’&Õáé4™240=#õåõ³%s†ÚMÐ9®IúáÐ $Q,™*WNüX¡YI*ÈJú GFO%]¹POH®(ߢëƒTèsÀeѲÏWT<0¡‡‘¾Æ¬FÑîðŠ&v¿â
+FB&?îi¸²Ra}4ºJ[1Ez.¦±
+WÅ Ña£Ò‚e
+–
+ï/A™¹’xC!A]U­Â8óV¯ØwÔC „ž!oO•sÂá“—¡CÑj%ÜîèÄ\B[.|&Hp©xQ”3Žt+Žd¥üò­`õX‚)dVÔÇ©ä˜
+4+GN»£I‡eÎ¥3I´ bD„ôI ­`Âëœx¡ôµ¡‡V4šHE‚=‰sé·Jeg… ‰%h˜ä>g¥8êÐóH\;¹ânZn¨ýeÂ3ê›Ù™©YL©£Â4‘ótR9%ý–€€³Â\£”Uô’صÀØ¡IÆæ«T|¨˜å–>T–~œ• >T*YIxYq³;Ÿgn¼0+Šá)†[µõ­"|»=8:WˆÛ4n†D·LÏËÈÙ_B½QI›>lÁCÓ$;w¦•¥$‘ t«Ð´§½Œ;Šˆ©#/%²~“Ô¥b¶ÂœóoG_0é„;‡íhAr^ù9ž\¼o'“
+QWƒT „&?šH†Œ8 è5`ÕûR²oFñƒ‰9…åÈüH½…ø§l ´ÅIe…v#õY® ¢³B¼\j'å­AÌDâU¦Ã’“¿CTG|z¬ !—VX£™âV."=ƒXˆ>w µô8ÒôFÀi$“RJ±[JW|_±îŸ‹þÄp¢¡oe-š†Áv°8™GŽúO¹Ž|Á’€ ¼!
+IBæè’Hd(ºŠzáéS0w'§<ziGaÄ\ÆŠ,ÞAÑg&íŽB3»1eEœ)ƒ7åê…\@5’0jVfX\5^À¸éŽ)t=•å”nKOBÕ– ª@
+IEm©lÌëaË´²Rvg¢ *ÏÖt¸ò-#dçñ¹•D| nþëš1wˆ81g¢°e¹/$RŠ`i¥ ±ýqÐE8è+e^ùÁ®2e·€‘Å[5‚ÿ§ê”×¢‹ê>Ñ)¹~¬‡¹ˆ-äÎĸ~¥(i"^›êYш“Óé*èW#CÚJÚ ¨ƒ¡'˜Ž€~”L¨¯#§Ó?ϸ¯š¾KOó€€Õ€hÀJuÞ3æ˜8™IL/ž‚EQYÉ­@E'†‹ÀR]†ÉÙã3¼¯êÄD"
+ê!Ì#.œÀZU•Î÷z᱂Zi)V‘yÔ ~TDÜ„ÂtY±x© ¯wþ¨§ &¿:ŠGX~i+;$2ùˆd‹9&ÏEe'¦iØ!¥¥ VAýY)ÞVQAE¸á¹‘”H“TjÅ­Q…š±ŸaWÚ]¨ ­ÂõÒ2Ĭ Ž ÂHº‹ƒ˜
+j/ÄËPÿª‘ªÝ‰2‚¨»’L²ü8ù–äzÄt?¨P“ŒsiFOI¤Ùqœ“‰ÊK&W±'ïä5!–4§¼Ä¥²j(YQ(³
+XÕ¾U¾PàœÀd‚ðñlÝVÃ@DóƒËw<è¨%ßœá¤bF=ÕEåóªßQ30ˆ¦YUJµ™YÁ÷¡9A}7›
+†jOè*i‡j‚I[‹•¶9pÀ>;¥2U%ÑDcþ¾&ÍÆ´Õ0'N‰ËŽcÐyB *Â¥$ ”à³ä@ȼk„ [ _KÔüÉ@™†¹(wËš©fIP},PǼ»(ägn$:‰PIc€á×㘊O³€ì0þgT@t;)‚-",$U Ò1=È—™·N/mÔ3ô‰‰¢ôx6i€À^”¥dñMf.,ç´ &b ÌHœdI•ÐŠQHû²<ôhæ¾À®De‘(®h ;i!XÈäz<¹‘Tóü$ÅãJ%÷¥¸nÑR Ö’|™% ¡Á4’Já Áâ _œ$'1â’'—“;qß¼Ë
+ùê$uRÆ™ºv+žƒôqô‚&En†‘P™>èÄŸ5\j´"Gsø`¼€±cÊÃ~ \çéã|™P«š$=œDz8¶àN•4jsM$¯´¾Pû§<¿™s…pˆÀE‘
+´­2Ñ8z‹ÒiØÂ ì5—ÂQ3CL*-°ºÒB1e[— c_€aZF³Õq"°‘&+_w<ƒ’H2Æ2U
+z$9”¼FF
+רû^ `qÒìú$£ÂsA›"'P´'d¥#z3&i”íprêÄ“šw³• nTh”HÌ0I$¦™jNy¹[8ϺÑ8^+QÞ“‚¹m@R}Û(`|®ÚÖˆOEö |Ž id]’RBR˜¨¶Ç+:Q)2PŒL@¢(o$T³p—0‡ž´
+}÷
+»%EEWgø8ÑÕ¹«‹ùÆ©ùžAâ‚]£x¨n£Y‰!gäçÅIYW)Ò¨{ëD*$èq¬ ¿F'øw´c2xL=hä+’´)‹öWêáXQ/Œ¬ G¬f[4%áX…CJ±æåäPaÆË^04éyB
+Æ3ÁٙĊL‘$-8ÅháRÖdwÂrzjsÅKÃóÁl
+`NË_–7y‘:x5±…´uðÖë½À
+YO…ÉlÈÒOEa)’ÂJ2òój²BÖÑ
+æPHEw21h¢…Hð#u;žÉ(DM­üv,ôÙ“§°Œ- Á“î ;I´ÜÿÇÞÛìÊÎdgzW {8Cõ@_“ñÏa«l=0`´ö¬ ¨eC€¥äêïÞñ<+‚ÉÌÜŸkR<0pg3"™L2±b­÷gCêh4Ï9Šr0GGˆu¡'ÿÏxãà,µ
+Oͪ‘q.óÑHš(Er†m
+éð%ŽàáNX=ãÉfÿ”_'s36O4h Ûïþ<n4
+ëùum×Éžá’üKã¾¾CÛ+R°Ù‚i‘«EE ãµKY´¹)£DÆ_ãXB@j!O7ç·j­2•Zí?£‰ãx}pqš‹Ò×–¹²CÎÙÈZxA\Mñ)ÒÂ4Tœ/®²¸·\ Êé³Èä¯Àík¢WÂÚ‚ýucôϹ´†+ËMÆ2NQ‡‚½ .t€Û«WŽÄVr¼cîbÉu€ºJz’4=œÕ¥H2ý™ŒçS›ãˆë®ÞÐ6Àí²2ÎÀÉF´ti˜Ñ>Œê ¢ÊÄè0ng =Üž¾«qÔ)¾ Íl¢ … ™Ë{¦’F†n^
+4
+Æ2A‡»r+PjÇÓ#­ñŽëØ‚„”\¼ÍiäÈÁ&YS~IYû6áe m¤CÒÛ¨¡j¯kçÜ
+°'Ã-L#‹áû‘ã´!§Í<ßÒغIMM ôΪïÝn0ôÇŸˆ`…ë cu
+ n-…îK#ߦ!!Ú?¿F¥T…‡ 4ISÙâÌi´AKª¦·XÃû½Z^­!£TztÀAwJˆ6ƒÎ:7Ôó~Ðåàž¢š:*ÖGëCbÎ!1;òå  8[]>mÁÿS*³ˆ|)ê²@ è.(øÀWÍ <æ:»¥; :íÕ¦†3
+÷h8‹¡¡õqœìí¾ûŸML(=\Œ…ç2Ú)Ëæ»@ì‘ŸËüŒÆï†x–YðÈ«3{!n Ø¿ìè–?
+øˆëïmDÞ=ˆÁßž+#›QèZ)äN,…czA-¯\7t•6çløN ÚêB{7qesÚ— ²Pé)|î³ÁïÂMÂCÑcK-8„´>ƒý4 3ì Ú4Lhó‡=åéé^ÀQàœÂ H„‹W,7ˆ)Ó£ÿ3·Íó?P8
+!FRƒ…d¬% Hi¤&òášv ‰ã* rœŠ*Yð6zELS Ë"XG}ûœv ª`Í¿ƒMA°7ÏRÓ-ÔÌ«{†f4ì½¾-ì?BëEüf¿£Ž¬/â¸3~bpGŠÐhÎvìÑc‡PàS±†|ùç´Ø]rߘÙd¡ ò‡õâ2 ’J9ê|J6
+ém!šDrŽ<‚ ÒæK¦»½9
+U!ò|j‰ø¾ lòê_×øpˆ$¹7G:j'×RödïÌq ³! U~ú~Ö¾¶ Em‡;np” ¹A‚Ô*&<óý8¾'ãcQiŽ¨ÛT®çró[Lmñç¥G@ƒŽ^¡ÆJÔ)Ô.bfí_yÌX÷z|êê+‘Çža®¼ØVž'%Sf'\†<Ÿµú‡]1•)fËvà=Ž%âLVñÏe%¼w´bÒû$¦T*¦ó§”®ÎëCʉ³ç
+5\¡®¤+Tø-¯=º©VÌ &ü›ééðî{6ßõ±Ï² øs£?Xµ(露«>¬4µé}¥ß<ÿ¹àâÏZ¹ïØèM7JhÀ™Õ]½5yÎ曲7Ž1¨Rºd’dYl=yÙ›E‰pŽ†à•«Þw_®L!Î;!¾œÝÍN?P G…k6¶ÌH¼~ª„š)H$Š(’´Ò¢ö²Ëa~=ÍЋ“¡£Ç™oÙÜârUO _7·t¢Ð~oçð‡¿ù º}•Ù\v¼ÚS€)uÌÍI¯¡M
+1Í"z»‚{`ƒ3:Ùiæ‰+À|ÿ¸çR Œ”SœC$2Z ®‘Ö¨îyFZ ‡åy·™ÔÎ ¡§Ru×NYU@\äÙÂú©ùda{@b4a°Î$ 4øÎ}2*/I¨˜¤^¹2iN{Ú8ÂW SO…e•Wi¦³2S®°´ÉüWÂÛPL&%fZ“°Ÿp-*áÞY ½Ngº]°JQ4²¬´@”×ç÷D¹+è¿^]¤ Òòö'´@*«rÆÒÅï2Nà7jä¤tÅßHyq‡SÜá†QœmÿV˨•Í¥ƒ{* ˆ”ݨIιEVRáJé'¤+ÌÖŽ «†ahêRqC
+€ˆ‹#¸ çMŠÓÜËr/¡çå5.©ižÝâw~ðhtaÃÂCÇÆŒ¹KöSAŸS¸Ï”~»DKŽ˜Vø{ÜÚÝ%@Håƒ"…`7¦Á5K‹æ°K-Ça3ðÒÆé]ƒÊ
+ïN– ›‰oU3é«œ (<s¬ñ—ó5$æ{œÎ½Å}º¤ºü ÑI+Ô¸_\ƒ„k Àœ×ê@C’ G߸¼Þ÷û׋Æ
+nSû»Vfœë×NMÔ´è½G<qÒ˜æ<·35纄’æœ\ËÒŽ…]¬ 5Û–Èt†0É°Bç¯;/É1§'“YVóº4¡%A•N¿$EržÊrR:àuæ`˜µè+²³R¤‹³_—†.5lÂuGÊ&ÌáBvá.̯—i·Ush_¤j¬Ó™ª!f?÷“P¨zE2<vŠ‘„j«Øɪ,­ujà-H¿RãS
+`t\˜ ó_Ñ(vkœjÊ3­WêfÌ~Š•È1³Åã»8~Àõ£q€² ©”mœÄ@?]'8910xiJX^ZÛ°8Â%»q•œ:ñŸ¨J9;Źk)Ÿw¢Bop¬¼{ä€þiR$.Å$DÃÕE‰‰l›Àc—ôydЮFšý›/@A¥)ÒîW„g:"ày7ztKˆ(–§*»uoÒÂef¨6úb÷ðV
+KuŒ§µ¿cbbëŒü]‹†Íê¤Qõ®’ÅùØh04B-z
+TKh<—½˜,å¹Å•0Ïݶd“1ÿuzž$êëùî¦KüÊ„ñ´1ò;´:‚MQWÆ÷w7w»Âõƒ4ÜßþŽ¡s ÿ‡_ÿñþó¿ÿó¿þï¿þöïÿþ?ýã?þ·ù/úó?Ð÷Cî¿Û4Œ~èQC«i^ƒrA…â忬^2Å[5Aë¡Â+®îè‘îcK«|ÌfÂ58 }9j‰%¡™ŽõBà0Ì^óUY½FHGîéQ½`žBYÒQpbfÓ¹"ÙØävö”ÑcÁǹ/,!ýçtŽàÉ°nE\Lü¤ÃÝ"Ià1÷»=ÌÐÍŠRß‹’çGˆàÑ„P"fþÒÜ:ϵæÀ¡m™C´CV ¾ð] 1·½yläeÈEY9²ë\²f+“£ ‘*n”˜ Ï/¨fr,i^–/ñ±@î„Ê%V§þ*|:¡4–Õf¯~ÄǵØàF*>ÞUÆ|\W”FU:  ùìw¾àXºÖ#¢=¤
+ÁµšÏˆ©5vWÁÜ=ú¯J£¥E×ò©àdØ;3]助ï«QÀŒ2z tN+•_ÇÑã`}Ú{÷"}±¨†4°*ÖT*Q¡ÒГ¨¶šB~§_dÜ)ë´³«4FÚ“{‡fº) áùÛý$y„ŸÔäíضi…Û9Ø¿`W@³hMZâ,Ÿ[P¶ ¤¥¡BÛà0Ÿ@‚íZ,¡¸a$í|À3°<ôCíqÇrT J;©ÓvËúKÖ‡°`NÙéŒàØZuJû8ùÏSž„l)í~Ê6?ž
+ô8ÙO^AV™ô
+ M{Æû
+1A-wÝ„ƒ)IšXeâªYeô`ÏÄÉä(þaçE[
+‹^Å´Ýr¸!lyæ@jž ©94pÉ >öY4‡™sçÁtª(?›~³N¬!Ì$s”
+ìku…{aòR9˜'t‘v¬5›íe
+äK'ÌãS>!1þ=@tîü™•©Ù¤ŒÁ¢PÕWfl;MuÎ8»ˆZÜ]ª›oTœíXÏó.£?@i dò30ÆéP^™6Éø@(A¦Gê`Se
+?áËÅ:2âË´elX,&6ÌIóåGt€&ÇŽsÔÛ ÐqÄ×øJr6:Z$Q6ñºD0ÖN{+Ó÷Xˆ ûPOÁM°Âß#Šƒ;
+
+@0‚•*„'«7v” žÐ?ÒübŽÕ˜°á’Z…Ÿ
+^¤q¿J„Î À’P¡{Öl¥nDæÞX¸ë®'åàìaõ-‹¨ ”oz‘.£à
+í‹y䲕¥[$,@ Ôé豨5êÙd*ª¢ A9—.i!3Í~ë:Eª¯†»¸guš°¬õקŽ´+…T¬ºB,ªU·¤ïùîAöè‚2;è´qóß½(˜ gó±j’úE>ÇRZÅLš¿œŒùk&€”}9Eé“ÅoÚB1ý„ÿߢwsû44¿&ä©¡4"t}n üU± ù(aÊsžÎ!ŠöSf6Ce—¹áU3<„œ  ’Ú°3‚Þ–,þ8ð¢ùaÐöE¨Àv~@3üÚ‘á‘*€ŠBDzL%gˆù¡ÆŸïS mA©¶Ç9ú2@E ìúâh ŒÓ1çtùÞÒzE-hæ Ó6=ƒØ˜Œ |^ñqÊD*åÁb˜T·`[ïíBDéÿ†¦ŽðŸ²ÔúÉëË‹íM9
+¤…]lžë«œö%[ˆ²U>Cü —Û8LÞ·„âìŒ8–d”
+üG8x^á+g
+ X{Â3Yª=¡aY’²äL·Rµ­IŸâ„Æ€N+v\†‚)3
+M¼HÖ^¹ÜƒÔ³€d€¯_w
+äÐœ8b¦ÙÊ‹–Ò£9àérKÖšˆFñËàÖÙHUŒ’[ŽO]«A•d˜ªÃ xÉÞ€Ú¾?7šLò‰|'¯
+¦ÛJytwáFÊW˜ër°ÿ-Ô¼gT9ÕÄÇ•Œ77÷ ÕÍàMÌVDF†O%ãªßóaÆ=§WŽV8´Þsœ{9DUpfÀÍãB)ÞR|N€9Eþþ.º6”ÝŠ'5&¿ô ó®²÷%äÜ5*Gù*عJð× æpÍmÀ}jÜæH—…
+çŠ::áS.1Y6C-.ncE€0éÚŒ{òÊÍÚÒ`Ž}6\°hpY¡e›
+ó¢¬÷o‹¥™†}uÒ×nì‡õ`×µ\ÁÉÉùÃØàªYZHi½Qסo›éÅstqêŠRjã{6¶aÊΟÅÈ¡1K¯ ™mŸ®±þFðãÌvüÊ«Ž´ÏRÙìÑØBP%D¨-Ά9 xú¥g
+¾›­Û &Ùðº¨Êéø\
+¸OX@(X•8úî…ÂbšZgw‘@C!'õäìAQ{ÃàöÖÊûÜ`wã+¦9qVŠrà6%}LñÒŸú
+u IŒ)#ªE‘Ìq&GUÓ’ÆîJC¡°xËzª›C°>s4fYHäxß{Dž‚dÇ’‘Ô± °p°ï\lwæÚMgn¦À0Å.ËPºQÐVÔ<SÊ7ç®Þ2¹Þ=r—±Ëj륯ŠôpçTªÕ­›¹Qd™Çì°†:35k3;®ØÜÇ¥éw±P†gŽRlÇxä _æ´l³BG´Ròâ×¼¶:T‡ò<sÅO=4³
+\üÛi•¿Õž7RNüˆ)mŸ¥“ =ÿ.Â6Ú¡ðòX#ì÷rÕ„«2óh…§‡ƒj‰*z¸.ÎWÆ·bαsEÝ#.íÓN®×HVe_2òEÝÚ:­ò¢±ëª²ç«ÕDõ„)Rʦd˜UõªCŠ±-•LÒ‹ú¿õ!ŽZ³‘þ•°k·q‰ó爵˜S/¯¡îò‹B¶g“•º/nY…÷ˆàvÄ#AÊ*BïIgZëVÂõ±š
+ õð‰ÎWPæšÉ<ÕCpŸùsðj
+.ÖZ8zº¹Öb gáîmûš—ÇNn1-§§õ)©8H¼¤âw‡h4Õ=] ¯Íô ðS€¯¨§ø@ 6(Öó‹•ï
+ð¿fð8Gq*ìŠÏܵ 1Ž¥ …q澶±”,â*ôƒ‰l•ÞÚ|X¸Vºª
+¸Ž7\¤·%`7Ľ?#ûO  MMV>ży„Hç|+éD3Sry,èÄÃ퇱ô°¼­$GþÃyÀåЀšË@¨Ù¹@ceÏJð%¸ Š=5t§n„+Š³ñC'„Pó|oÈUa$4{,g0 t _²}8ó§ñPHG P­¦˜„báΛÕS–œ™¾ì$@Ç¢œ*š_A£%$I×)À®rŠmàŠD›1’׎ʶFeß^ˆ;Ó^F
+âAQò±Íe|þà(U‡Xj no*I˜åö!CuÔ…E–V¯Ad±\dˆÎñ‹î¥[´¡ŠŠþV%$M-˜Š•<wŠ½¯ÔÔÙiy/uO³â ¤Á,ˆÍ(ˆ9
+Å—ç¤w*8eæßâ¡©5£D:O1ò+›¦”úì¤ãÛôz+ÛU¯ 4x.³GþOmXHa#¬‚þgŽsõ/êmž·óÑâ1@ei)„¸”ø™ÓQÀ¨ÛZÇ bQð4:—>VÍ;·C Üí<ã36ìûÙ„dÊÜ–¦õiø$s«Ì³8È…®(ߧÁ5€ìô‹y¢-’ Ìd¸n¨»ÜѽW¹þ "^Ãm­„µÎ1Ü$«d,_í²ŠzÅDDø9Ƕ>¬¹«Œ4ë#¥¥ÈèXhÈáDÔÅ;ÔÖõïuŸÜ¦$‹ùÚ×KÓÛs«©’±9MÀG†ï€ú¥µjToã÷‡¿âîRnþ_ãD¿sžó×üû?ýéÿøõ·ÿé?ÿOÿðç?ÿÓ¿ÿëÿóÿùÇÿòOÿöOÿðçú¯œˆ³üÜïü‡þ×?þáOÿöýñOÿÛÿûÿúÏþþýOÿíßÞ¾÷úõ·ÿá×ÿú¿üÍ­0ðßþæ'±ó—Ï·`<១6€`ŽV1g²†‡‘Þ „Úó½Üª§n1‚âøï¸ÅÎ7©ÔÍZ¾­Ãrà7€ìÅ­a±~‹|fû{„ÿŠ»þ½³¬ ñÉ1S=¡íùV!o„ÞsT¢†ÕÇÙ^”!Ø<Ç!·Ù#¸ Á‘+ÒI#*û6(g¤½}È|Àщ|BȺb+[Ã)ò¾>³$;©fqÞZñ·vBIUéøs©‡B0íW0HQL†ƒ¥sÇl¢Tí³ Ràg/½?/­zŽKÔ¾ÜÕ{¸Ú#'A¤ ª=¾íÑøfy_¬Ý§o¯û‚ëë(?[Ü.&ʧ³}!“¾ í‹âö³½09ˆ
+a__$èôíZ_ )û›Y=LÙžó·G}øèõokzJWùGzÒî)÷o#z´>·½ü›½Hèœö¯Bdó·Ý|垦öí2oC«?›ËW-OË·§<ß#ñèÃI¾Ê€»~6¯àÄ´òßx¬¹mù‡]<ù4ïñO.ñâ)sû6‡Wlª[ÂËöKíG'xò¹–oøξH‹£ð}'”Wý£Ý»‘èöpº¼+Av¶os÷.»~ötq¬s›º£†6¾Ü=|õŸ ÜÙs»ì~ú¶wèB³Ÿ~í½Xryº´w³íã6g•jÂË“ˆrÎmÅŽÊ"ò0Û‚}þ xf;¯ó'BOÃu>¶é=hKPE¶»:»t¶ž¦ê{ã‘o/uæ1ø#ÛDë.íÝ;šÔqôÛ2]N Âj÷e™nd¦€ªü¿Y¦GØ!,a—q[¦m°ƒ L­Û1}QÅRPÅúõæ˜.C̲Ö|ã>-ÇtyaÄhðÂJ£GŽ8¡4ô02~˜~µÈ'Âw‡o¶Óy| D·Qú¸
++të®/ks¾G55„„x/žFéQ´¤ÀŸã6J7â¥èÏØÕlòqº((Π4‘œ~8¥“´˜/ÿmŽ°úo¶´ct: .? Ñ/d`‘!_>è+¿³ÝÏ/BØönzÎ1æ‚íuNšåi[œs!Ë°å!Aõ¢f¿Íy創ö[ —éí_~¡¤VÏ۶ܱ[¶Y9ËñnQŽ2ÜÉíL^ùÔÑ—!¹“#¿ùW‰~ý¶GŠ›/Ý®ã5(}O¯ñ%›í0Ž"(ß²ÅùÛoyX3‚į½|ÄC7!ßöáDnùÍ4\ªùm¯ð&¤¬Ýᔿ NžÎàJa¶¾ Á!±X?YºEÅ’ôfÿ]"j·ë7Fp¬Ûì;,ß=¾‹/Íu[{ó7.œOGïû<ËÈ[Ø|¿0ò.ìS™žþÝyÍÑÛ¶›jpaE·nZÒÙO·nS
+×mÒZ<÷íÍý'ïÒY­ yF~·äFID½ŸpâFż–vp½°þ<}·)?Æm·-æ)§Ûe›Ï ’ô4×f·Z”jOm¾IÆmŠ]SlÚêScâ´Ž•£nÛeƒ„$ýü°ÉF‹V‘îåŽ +¤ÀmŠ 4uΧ6~µg
+(å¶=NÇZK*#žå69¶ON/scŠuñ­/scÀdõáiŒìS½^VÆû遼ñ>¶‹¯H¬,óa Q{H·lÍp”ÔÈòîîEÊíJ|ÿý0#ÞǶ1R.œõ¶^Ãìé8|)õYn£áIùÛak‘4Ogኾ­…AÃ*&½-…Ùy¼Y óvŠ­ÝÂ'ôÇv>Tâ 7é{ÂAέ.,Ì‚‰ªr¿=‚­*Õúf Œ×*QËxçÀÛ˜Édäw'`Vé@ÖÉ GŽ€ûßÆ¿Ì棞†¿ÜKƒ‘mô{àV.Ód9ý’+`b|:ü†gÌù2ö=–·Ôöó%ã•Ç›/…BÒm¹÷VC.L{™wØÒ>½zYQ0wÛ½Ųšlg^\—kÎo†¼¬ý¶‹>ù›"ÖÛ‡—¿‡Vx¯:?§QÇo¹î‚Ÿ
+c„Ø‹1–»·Ç.qÞÉÛZ—{¼ÑÐÆ6C&ìi¤»mÿ\¥#Ðf>oˆ2Ò/r/
+ø–Ç1Ùm‹ý³u›Š0Ð~[Ú2³¹‰X¦´•t¸Ñ‡ƒ-»ûëÉTbþíW»ÿ~ÚÔÞÇ–;meqðãè3dÝ-yþ˜æÉŸ?šÒR.TñIb%ݦ´gYÚ+ Dãu}›ÒÚ»–ÞÎö¢=óú´Ò5„øò¢åS$V¶íÉk&zÊ´=]ß=hít–oGX,µ2Ò_Þ³§šO•óω»÷Ÿ½gÁ*ÉØðQY¶ßÄÎ<yå‹ÎoïY{ K@£¥Ÿ½g¹ž ØÔœ"éùá=®•¨dˆ_×·÷l
+:¦Q©ßF´ô-,=-ÔÇ›­=œó0SY³_F´ooßþ³6
+”gùÙ7–lýQÚ·]ì\¾]biس_î°ƒ4ÊQ¾Mai ñúå×ü³ ,—º‘}z¿š&âƒGáçËûUÔ‚žðí?{¿zÇ“ƒ3žÈ§õ«cs¨R3|ëßÖ¯x-‚ |:¾^jiÕmôJ†ØBæòwåïÒž®®AÔb›¹r‚#rÚz¸jèxœoÖ­§ð9³ÿsŽ<^®Q‹sdÄ´º=\™¥U¸íV×Ï®.ÃM}ˆÐSüòpuLè!””·¸Í\}NV=Šeö§—«E=¸õH]o/W uI¹½\mÀ×öÎO3רn;iÌk*ù6sÊr ¼n3רl¯öh×›™+w"x Ù:õörU¦õ
++³8FN*]·©+ J>ã›ôéêJ£±ÔT=oWWŒGŒ¼ÒíêjCUåw.i­¾¹ºÊWb NÁÞeÛ»²f£Â4>ê¶we•‹8—­&]þá󜦴8MHÙ,ŸW?eÌ9?e5iù¼žæ‰Qò쀄˛Ï+ TtžªUú¼~1¡ÂçõÔþ {ø`_ûôy¥1h>”Ïqû¼Ú žË¿m^="—ãµ”7›WbáìËÝ’¼/UCl4Ûæ,U¬ç39×\°ÍUiTë 9\}¶óë©w%Ai:Ž y„ȵÖtÜ­y{·§ók4¬ÌFr‚ÛùÕ¯É*`r0nçW¼,°õ
+»ýv|õï pŒÛú5ÄÇ!)šÞ¬_¹(ðcÛñÕ©m®°Ûè•8iÆ‘O£W!)ˆZ€·cÛŽ¯"ƒÎ—e+«ÛˆâþíïʲI¾nÃ¥ i»¹6V$JyWŽ‘Q\î­ü©aT˜¶Bv|¹®®þù·W‹LÍ2î¹»ð'(…§k#_{•Û†Ó’£ÞNª½EMýaºªùèUö!È<`¶Çêþûá­zZžªÃˆtÜz’}:¨öÓ»{‹þ2NÝ?üRïCË&u^;àœíŽ:ÐÛ #Óz ËÙ~{¡Ö™sܨãˆûùô>å3f“—åéX@Öít:TùIo§óÇÛ¾¦ÂB¢:£¯)"®èM<íLuŒ¤Ð³÷á yÝî¥Ô^[yó,åÐu·g)ÚV¥=\AŸ¥ýX œåKJ=– ض#µ>›Ú› i3=oR^á˜dl‡zŠ2üÓ}4Œ=Æm:ÚÈÖÔóöm)às‹Qåt;‹òÝ.—¡(^‚^†¢xšä~Ûˆ‚ã9ú9)–ŒÜ›k¨ÔÜn³P0IâZ—G¨næÈ'6ÈÛ´E²dû€6NÒ›ý§RnÓÏfò¶úlV|Þ->Ufa$.kOe\@ -GÏû/϶ -Û¾³/¼Àq¿ÄaÖ‰ø/`<:™“N…BdŠ,î§#'xrõøvŸ+R$ÛSwÀÛM•‘f†â[˜lŽõ{šlŽX§í­ ;”ŶÔÄyM‡‘æeU3ßþ™¤­€2lÛÌý÷Ã-ó>´L2 @±½1I)¤ô°Ä¼T¿n'L’#ÚØõ’-@n'LP`æ•y8aÒ›cÔùÚN˜B&©pÌãGS‹j+´L˜ô€o¹|`ŠëNŠ¦Î8»§Û ÓOÿðˆ4ãà “%ðˉ d¨:éÔÁÎäe9rŒ˜§ë%I ÄW¶Ù¥Wëæ{¾Þs1¿Í. wTbPÀ4¿¹^éxÇØ°Ÿ·ée9
+GÍ7ä8oÓKBåÄt¼™^®
+„„=U ‰þ—¶YúD[óí…¡•".s^ZÈ)™æ&ôÖà Ó4r»¤–âSŠ0(Ë50üx—æ¥òå»&·6T0)oé6ÀüJìlLª('FŽ¾šß 0­%×· ïº0mð·cu\·¦ –íæ}Z¦ë¯RU¨çnÌ(àPbï!ˆ ez‚Ò¯ úÃÓ€oãÜÚ‘NÞ˜æ+Eyç (ã¶Â4+ïÜ΀2yxb~EêËÓ2¤Iá÷çÛ3¶.äŽÙº¤þfŠùS£õýs‰.õ3¸ÛSuV„ØgÖgOOLÉŸˆ!cïq¤ÛóÔÕÝeCæì¶Ä\R¸)¤pÃaó¶Ä”¡¡¤ªVMõöÄ oé
+$Ϯۓgš€HŠ(êé‰ ?®Î¶ÂDìâ:oLøFÔ@žÎ— §›¢Ã±Ib+dô6¼4M¯Ž¢è¸ /Mé¶Eû+ÏP2 ²RÊAVÒ49æ_\2¸Pý¿Ò6Χàexé÷T7CgÑéåØÚDÉ¥õésiѦ
+Š‡¡zÞ>—&j¤k¾Ò·Ï¥Y}µ^ö–ä¦A
+lWKŒàl3K)᩼yX¢AA a[Wv€½ÝŽ•]é‘úfTɱŽÔúSª
+ÈÄÖìÍ6ðºSöÓå/R¿cT¯¸Žø Ÿ?Ï0hš¿pˆjû4 ü<LÝóÇ´¦™ãrÞLÝàƒ«›&’¿>MÍ‚/©“/ë>3áñ’Ïı,
+9¨<
+v3ïÌÆÁ ÙΡä}hw!\y;ÿy:Ræ×ÌpíiüwÊGÀ‚-㜶ñêFQ$>Ai—ÛøO; ¿f¾™å|úþ‰²8¯…²×íûç@iœy
+Û6ÿðQdñá÷DZ¸$]ìûí÷wª']´ÂZ…€
+ ¶ÝŸŸò&×îxÛv~¿ qì(â·ÝØ/jE·Ý£SS€†‰y¼ìQrþlxÚý}7.»?."R¢¸7‚ZÆ}§¬Es©D}äi÷ØI³Ò†ðÖñòÿ@ò`»üÝ?Ìýö±íéwê à7µà¶§ß׋øôô­å93–t{ú©G¼Mº¹žmO?qÊJëÎ=<ýl¼âõ½J<Û˜*9$í :fŽ·§Ÿ0„°u¼YØNâê2²ËËOý+ªõH°u\^~öƦ€ãÊ
+=¼ü´  $ …ëmê'<¢
+} Œ×›Ñ=¢Ê0·}}ÓÖ?·€)f† ùú¥Ò«äýzsü“®b¦ÿ˜SWOOÇ¿¯¶/Ç?Ã/l(æ¯ocùË¿9þùä$©ùäûB^}YÿÑ+^_„:¯ök[ÿÑVó©Ô•#x³þó£²ȶñëGë?{9~ÑûZ¤ƒ§ó_ØI0í u«då‡óŸ¤—ÞKÔìÆrˆ\ Q†M°¾ÿ%vÑ™[”»Úñ2þS¿1©
+1xeŸÆV?à‚4Eÿ6þS9 pM©gËÃÏi·VPz™û­ ™Õ¸}ì*Qùòù»~²÷{5~¸ú]äó®¨>½¹ùýnj㯚E™7ZŸŒ§y_(Û·gYójÛªâf+ï}T $J,c¾¤âÛo„ŒÞ› ß<fan[çj¥ò´ý÷H¡ê ÷ðÝ#[מé(m“=É~ç»·8JÏFž2©P\7¬ô(~!sútЃi¬®oçQA±jÛÌa.ˆœðÓ/c˜·M›cÜæxÉuMzxâAJì¹=ñøû´¬ðøq­§žÖ…(Ú-+<(×j‡ïKƒµéÔýrƒÈn¿;HÅZ°.E¼RБzºÛ»¦–¸Lí2™i
+TR”ÍŽ%^ø°«=°ŒÛýM]¿œoÓ·êjŸž¦o U­Ê.Ó7àŒÓeõÆ樟ooTÅ€Yl_·®”p½íܺú6o&n€ß@nﶞB¶r[¶ñÛO§6аs¶CñZéi³¦—žÿðcãçWm6~¾è©U«¢–DÝíéºFÊà6[©Æ=BhZÈä=­Õš^æývTÛÊXÛH­-õ½§šžòœgÙ¦ÝZGË.-«Èu¾¹¤•3€—Û ë,ˆYË­æ¨î=½ÐT™Dh‰tñ7ð·í|V%Îä7Ã3Žåëås¦´dK·½YÕ[à|³7+W€n·«qq
+û-«jˆ~0àŸ>f{¾íËÿäÅY®eÜÈ=O³2ŽËUŒ5ãÀ[½É²uðóÍ’l˹n'²¬êXÚdü™øUß1îÆ aíÆ2C/ÔT÷eéò›¹bÊ„0@N±|l+1¤4(ª=Ädj§z‡…œûuû…ÍiýÍ%,µÐÚæ`ü}Žv{‚ñ÷ ߬ÀEñ£¾ÀÐE®eU'Áôæ÷¥]î:†ÍàÍ#ܼBbÞþ4ê›»WE¸ù(·¨ k#ñöò"#M¢ïiáu)•v¾œ»ŠBC/Ã.æ­F/Ÿ®’»·O×¹–ÌeÏÅP(ç›)#ˆpc›qAW¡–½Í¸Xý¹.ÄÏ@è)%C!&ð.,4@ÛXÙß·@ÎÖ—Ñ®ø-†’B¶Zs`¡Éx»iÉïé/-¨c%¿»g‘ãËåešõ›óm•LælïYÔ¯ñ2Æú-€i·Ö\øK½l°r/Ûý*­•y›^©fÅ(zx]Œlýv¸bwUÃ,œ­Ð 8ÎC+œxËícj∊©ÓýŸJÛª
+¨uÍí¥h&5Ÿ‡ET­!²¹KTè,›~_Oè\.°Âm5Îã1òÞëAhùÓõ‰cÜÈmötiHœ¶Çþ/Ñz;;QKcÕÛ†N°á•Ú^}@Q€/xÚ7 ævX˵)Ì„Òí»ÔGT‡Ÿ&Md›‰/ö±6‚²-™ößO'¦}l0õµºn+¥®jç»ïìŠÐímT5(Õl—¥ûÒ>¶=•ô“ºÊm¥Ô—ràÓA z‰žË8 Quð5Û8I‘uP]Ïh°†ˆã¶IêÂ5_&H ퟹk28¡t¸½FŽõw[ ro»Hø*„»„1ý;¿œLŒŸo~Gci«n›#S¶£ÝöFdRK{352)_Ëö2ðºÅ®uˆys.ÚbµÛ±hŒ@þ2*ë%üÑŸhˆE õR ÐãyÛñ·ñ‡‘ÇÂTÈߨãá>•š˜ìi:¤Ú@¿n³!í¤ú¹Í†d §7‹!Tr+ng!Æ œ×/C!ïî1~öê&×oû kïj>]ƒÔI¨ãg· åzõåÄõ«8ôá ãYÑŸ,H0Ÿb™½Ï—›¹O ûÌ?ØþŒYv?Âm½Í|öÔñ4÷R‘z»=}ÆâË‹§—¥Gþ“•OKÁÿ³‘Zí%6=Œ{d,ò³_ê“‘~Ùô(K õÓž§/àÓ•§Cǻʷ³$H¾/žÙ’ô?xï4«íÛr§Ë4àÓiçnx켎…¯N[rª_î%Ý,OÈØ|ÙéÃ,¿¾Lt o ù§wNQN 4¬¾,sÊ» /«x퇜¢¼Ñ¯q((ŸÛçé‡SÆ6)ø°Á)#¦´Ýoê‹Þ—é ÅùZo«±ýwn€b@°ÛÆ6îWgDyô¨XÊìp§=/ÿ7ÿš’øûe[S¤á`æÓ­¦‘8û÷c¦!çLjJ
+‰ñ§7MAîá'Kš( Û‰æ3ÒûÃ_1Šüÿ hþ_2 ¡ª) Ù:…YÀŒòÜ%,iì¥ÔCî:Oµúq7D¶/G]_NÀì¡b=®@ $k5s§§×›ÂžŽ¢"D"‹„ߌ‘\EÛÂKÁÚ ç/&çÆÖ4Ç6›ºv…'ÖÜ[°Åxf‚ó©c„Úä‘Šcš¾hˆ†­û›sûiä2—ÍJL¬ìI:5™e9ã9´±K)ïê`Ï9°˲S¢¨§ vOj3à÷½×yÐÓ°1îÑCx\å—D‹B¾“×Ï(Ú <÷ÑÞ—¨­Ñë´Ê`z‚µb^°À‹<±‡øÊ„
+ LHè
+“Õ”ï¹V4Cî}H~žs‘òÎ
+TÆÉbƒ¨Odý´[3€FÕŠê˜+=DŠR×™+‡u3¡Ïœ[)w”œ±ö¼@Ê3×x8ýJhLƒß-…­ïËhZØ™°GöâÅ(uA)·…—ª ÍÉé Ùx­ã%Žfè ©Æ}ZQKÃ槭îѹaï7 «çÜCjb.˜åuùÓçv­ž´Ä4v¤ô¨[Œ¨¥ XVb—½:‹Rƒ÷ Xç|ßÀ ¬8E€uÜË…W›SÍœ¯ö7ñMmë:™ˆà‘B(:â7çÏRfÌYôYžWŠôÜïÍG:Ãgxîsc”¢YŒ¦@ÍÇv’ýçM©}Õ*0^Fo
+û¤# ¨À¨Ü„zMÑŠY„ýÜV!:{
+yŽ½\NæzÆ{qQ7®*=j7Œ*]´p?}èÄ‚ã>¿Â”KÜ\jåç*’¥hÌ@­ô>ýÒ7,ÀÐ-ökô
+.Eë[áAfx^¥ŠnòÃÛãFVQ<–áC"Ö¼uHí3¡ž„³ë®Ÿëê/œV/'ÃAպ‰ñêk o ëóP+E( ®÷©´xŸx@ä§YþjcIÏ÷qE¡j
+sÙ›Û—ƒ^ù$clvN#\ ̃x¸eîeÌ^KGfÙsËVéP·ô1ÄžÏN‚«é—vj„œü"&X: 8=&óó4Tžé!대‰äµWBDš_V
+Œ¸û N(ö¸3…\C…ê@àÊËSy.×JµãÒ6æ\Z™à\{Ž «I=DÆ+áã¹Vc¾#7ù`æ 6g—æÆ\–Õˆ*+ô~#—Œà}E&tDÜIÐKÜRµE(Óðú½ã×åÙkœ¢M´帿•Ü”šqÄÉŠ9c<ÉéZ ªàì‘CÚî„ù£Œ­ÃE¯ÎÚ4{ÍÕõ\½ˆìáÂó…šÖøK=¬q‘CùøØ_2'˜=¤ÌâêwøwéŸÎâôfØÔæ’¾äÇÚå¶yÙ)^œê®9‡\*zóh5ô£{v¾:¯UË'`c{EHGšÓ‡mÖlN\‰bÛ©Ã@kèî8ß=ÞÀtÈì„É SòÔ¨n€¬žŸBóomøúB%•eèuZ¦œS e¼-ˆ¤Ä³½1ï< ò‹@ aºK`H±%dD·ó›…$Õ–ev·`]|3â,``ᢘ;ÙÀ˜w+‚(·*sÌ{Ôâ÷Ô- §eœëŇê¡Óp€„„ðVâ Ÿ£*{™Dö`¥£‡KL634`²¹Î­ü}@ñù¹0,¿ei½cÏY½—mmY—.ÎÜ":œÖ —Ü3¬w97ù<­½ ˆL†8°r}2°‡2£¾x¤ƒ9jN5-H±ŠòNgvŠÌ o†ÝçÜè´©£ÌVó‡È{°# `ý%û@Ǽ^V{ 9Iµ+ÖA|uËšBG šNXô/«Qôó¼iM}Lz ²sЀ"9µ{bˆ ÇMô`­¥‡
+B&Îæ{á‹ ²‰o"ü9zèÉ’» }Õ!òH1¯óoq1…OˆcØF]¶ D_˜†K¢}6\$RgCÖC¹-a*>IŠáë–hö86|ÆŸc†y˜êϲR›Ô6ëÂiÀcTPqtaijÞI¾’ÙíÂ#‰¤®zËðÒkØVR¬úsØa=?¬C”Èʤ%À°‡æ8³L\{47T”ž6‡Š^q‡jöŠ}âhŠÎÂ÷«
+BZBäá6 3¶™6tB(Äqj_J’œºÏ‘GŸ/ßB÷À'eª‘²ª~5~ç+æÕ¥¿Îø°ÅïáèL%N§Ög¬™lˆˆÌfHtng¡¢¬[äÌ™Ý6h>™ù8×”)3»±aâ'Ñ‘0£¸#zÈÙ!'îLušÌîìÑ·ŸÈ)À”';ØØ°f[ã4µì ¥ uTʪL
+&óEäùø"õ1@ó´ØY´s'8˹âBä®´ûjk_]É%W_6J¢¬ðÐ I¡°RZŒ,u —B&9 óVÿà5Wp9Kã[[©[©öZ­F¬V
+3— zàOì”PBÂ<ªkš2]öˆÝ˜ÞöÉŒº\ È 3f¸"»ÀÓÝ°y>äpc'Oùj¹Å%ê`ôE6éí–!hÄ2&Q§&Ùužäfv"“ëbÀ;· ¯ç¤×—]•*”øä\»H㪋åÍh ÑEi6ªŽ
+%ûMGZÄØ`³vÙÈ
+¤bF¾y~ç™ í{p:­И7tÆC¥•#Õ¿Ä+˜¿ä,Û<hò2³W! ÷é5–*,÷0K›=Ð1±qQFÌ$ «õK°ãŸÇ> o^²ëLjÇQló¤"¶ çå Z¶+ôP‚€GÁ;6{
+ù^C†1¹9Œ+†lIoy
+4FèÉùDê‘b ¹Ãe ÖÖ÷=;~[¥pôp®è5¢WaëBqrÌdņÂË â(ç0Ž]e/~Ê1vmÚ^Äì …@º'×ô‘èU‡Ž GÔ8f
+bP~ìÁlöhÒ‘ ŽZ#;[ø ÍŠèpm/,:%¤–f'4hí5HÀÍ‹G,NC:‚l”؇(5Û™Æø€FôhäÈ
+¬Bj  À¥“hP¾È3ÁN
+³d‘M#/Pé\³p7ÃD„HËq ‡F +4£| ”ÖgôJyk«™»È52ËÝ=‹©cÊ
+ð”{ûn»–=ÀqXFÿ$ê¨ã¦_Š©ÁÞq[V¯(©Æ¦ÄÒ@»¨e}ÚCUz ¦=Pi´tSAfÉ´†ï—ñ ]MzõßT4ŽÀ=Û»¸vøMM|)i`ùÄÐÀòXŽXIc9£!rŠ;IÜÙ±¦Óêè\§§©RfW˜Ô
+Š"+»M™M
+Hƒm¶'Œ)Ù5“mZ›Í‡9LÛMª£»Ç–"8t8Ϥ ]V+‰ÍNW FÊ.á-…àŒeøs”ˆÔ"¹°“Õ
+‘»=ÏR†V% 5#uAj|@%Rk.ãó#:¨ÆÇ£GöÞ5ár‰–ïé1RRãØÛ6¹¤ÉÓTß>tôœ6æøqLé™5¢®ž–ì?P¹`[ö—S¡wÒ”ÀÒÄÎÜ~PÍ°¦•-]%xÆæLQ.äÅ-˜]‰UBÒ˜¬æq*SE½ IŸ&ˆÝì
+q
+"p †Sh±ó[º9 @l45þ/¥d 1i7¬öâBõùj ”x(±ž±X©i^ÈÏQ7ëJ¶@=PGw+Ôƒù•²S?{¸EÉ' Bæ‘ÿÐ ˆ–¶¾ä ã¡•Í‰sœ‹c¡{G-h¶E2;9ôÍ´L‘@į䊖FÁ°Î€”;Uô;[ Ê!'F.@Ls%­RζÀm&3y¡oÍxä&ÙâT5-V/‡p#òµ±ñl—çôyÁë
+m¼±
+B n/Ú\°qgXSÄàp“Ò ÎåàÜ„è[Õçý‡ ¤4{ÌÉ|?øM0"íq…™^‡çF± 抌¯8¢ë„ÆõñÅÞç{ýèàƒ^Ï
+l¿d#Óç ´p¤'>½ܶÙC-ºµSà ¾¿"=ܨ5ÿÁyáhaJ/Ò•˜Ebdº>–A5{´tÅùC.„ñr–uŽdp 뛨¥“ú¼„:¬QÜÏÅç.­¡Æ
+„ô•3 @¡˜à pa‘ Üù3Šaé.@$ÓÜì{í.0N Ò{W6ßQ‚:4{œBµ8GyéèdÊû&.­´
+ -g{B³–ÒHkKËi&-Ez\ %@æO9âÊGäÓ¤°}ß5•Ð>
+£{àIñ›ÙPoXC_¥©`¡Î†í²¼µ\k©+5-¥­²Pœ„ZgñªK
+ ªó\ŠñÌPƒV9(æ‡û²r¨Žt
+†“%¿X*œþŒÄGp£(,%òUe?†Ž„™¥H[…¨‚á¦âz㛓٫¾R߇ðµfù4zQ«Bš¥KÍ[¸'Èb9EØ``H¸ô’T¢Â1¤¯oA‡˜ÄµU+èŃ^çˆ#E¯k]1£š+V¼ì;+ͤ±§²„¬r @4÷më;•Øãa ")ùò+2ßM±K˜ÜòÁ0Áp¾ %
+¡•”–€©#D¶Ó 5%)„¥ Qd«†¶TÝödg³DÖ””ÉA É W(¤Î-âfF൧S~U/A²­B!‚P+ç!b{=¤ t‘Ï®”2I“C¹"Î3Ÿ»î‰MyoŠcC!Ͳ¹) _„HMÔY©:©vÆbQñ e¦áŠ†¨¹5e`â'Ÿ¡z®æñ*XÐþRÆî]ÅŸÑ«zþ9rsœFÕÅÙ£â%þã¡åF¢B¾×È,Ã5Ž—rÖi -|Ù0£ÿëÎôJÖ‘§}h©Ãëåî “Èj÷RÎAÌç+Q¿
+Óµfsii®Øà1v)\üã‚ Ë'ÿŽ^KSD'g‘,øòp½D%äCP¬ AìÄÚ:"DR´o`g{Q‚u½ÎJzj*¦9]05«ùÄÔƒË i® ›¾.Ä2³ ýô"é|\
+Éx®=¼1FÃ_âÂûCƒvóù<OL@ ‡EÆoÒþ„»(Á|…‚0¾ˆP£Ë_‘Õ†u âTð/Dûïí¿#í/""jŠz ÍõòÆ]Þ Å%ÄâcZ‰è $eÉI/Í}ƒh`¨—Äù¿+òo»õhÄ“S¾
+îæÔ1Ôm¸
+2ÓOzÈ@b¶“ä“É}K© ñâG>äcš€Rhd-gT„ô'íÝjðm$Ó+9§/ˆSH_ÜW9ŸŽ«T
+2𙼠¹/`î0¥ô@xæ¿TJx÷gžT¾H/Ï ˆLãÝÕC4Ò}V¶éô0 $$¼øÓkX0\û,Œ§ZXW™ÂkÈì½ Ñ%I!@ö²ïLÕíºwE²ÈHP\η>˜õLŸËÁ×KïÙ«uvÅó5„àx|ö°ÞÞBæ´0û¶’5æNÞ[†Ž4`BDILù9^Ëù0ÄÚt
+?ddõ4²ºËd…|¿Àâîn:–DtNß±q-óG–ßZN)H¶Tk«)ø ÷Wò¸0ô4‰âÌ÷J¢U*Õ fùZ ½ï«»ööMÖ±8ýsÉVu5O–5ôœÁØ-—“—Dzᣌ”¨”(v¸P‚©9‹)ëüÀþT…6¾T³x.'°÷/-/
+z†»Wi+°&Š‘öö#Š# m†ËQ2”ó ¨³  ÏæðS8=ÁˆØbˆ’‚Ï8 ùmØ…à3@rÈ^è—Å»×ñŸú]ì=ÎÉä’£Ôè$õ:½Q×¾¼÷@^×0ßá14ê~ˆ±]ÔƒD¤i l]›%Ù'U`0ÈIú­,#­;uG<Y´§êò’µb¬“ç1rGV–ª¥‹ôЦKâ`g°œüÔðmIõ|åÏÁ8ã‚Ê@y—i¦Ù^釸Fì½+ô[ûY‹åj—¯I¬½4uîCM êÀVÍ9ˆ%SVIF{ƒ5da U@ˆŽ=åW¹–=Ó4ŽÒRrŒ¹]ÑjgÝX…`x‹Q„)8ËÄ Âoåy´ƒÜ[=$Ezy#Ô|†‘X»GOÛÎ*—ïb°’:y×&.X,V:”°ŠÚ&—²Ÿ54H~ˆéŒºôT†“½³èžÄ2<búô)ÝwПäñû0v4.ãÎœØCJÕ¢öà‹É%hjÓGk<8¸Ë,ÂK+T¼•F¥áúPÞÛ½&ƒ©©'…éYfLé¾\Äàû‡šÕ|ÔP›méÔÓ J“R·sUd©5CЋ… D=ˆ}ïWnŽ…†S+öÁm
+®ŸÎsG2¿©Fì/»N}Ù{R[ók=0rÆ•,'佞Ûf‘ʆrâ+†Õ5“ʬ®´ÁýyZÿV=”dP5¬†¿M™ÜÃVµ+ ãtȧ®£:óhY–½&°ðÀ}WäòŽO`¼jh¬3ﭜϘfDûA¦âQ/¯†ˆÍ5Ÿ%ªGŽuÕö
+î‰4`Óq^ør"ípOš)w عˆ&§3`§f–uÐCìZt…7¨kñÈè>=„r%Ÿ¥†w|
+>ßûŽ ½ ™Ô¡ã‰3Ë­„l7Iõ|Ùm
+•©ŒJT´ )ö )Fê^dÒèEIÂRUÙó=b»9_‰EJ#©C1#òÖÇEÆzŠóÓ©¯‡…òq¸B¼(Hû‘s9Ô¢MΔ(%7Žnz F+°qbr ™6b–Ø‚M´Î»0ýþ ù!ÌÜŠ§ßžõîÖ@–ÉÔT:ô/M
+rèa5qQ½9ÜÛôó!Jç¨)±7Ô«Hˆ‚ŒwµŽSe{à\ÅéÆg* gIïá ºúKõ™`¹ßˆ¥üŽfˆ·(¦ŠMHÁ–ƒ± ~ ·KTþ½*“ e~šÃ Œæôı ãØÖFîÓ”@ ô!ÑÛB×gå†^ôæ‰ÝÂ&¨
+àux5x EZ‚ ‚x˜YÍ#ôŒš4ŒÓËçñ!A²,ð#ÌË —|ø"ýuˆêžùª5nàš#7 JA°U}Ä¿‹‡r)ض^[xbU=1í3eÓÄ
+ûÞO½Jð°Ñ¹C²D¦ûA ù‘è«àB»Gò8õöZ„ˆÜ¯;0±J(þòN5ä–•9böø-õ'n;õJjé׫‡ê# ‚^Fw"¦Ê¾^%S›s§¨ X)HW=lTS[Dì9Pt2 D2ãC¬a"јiK&Fg`])qLKVÉú¤aÁ!%˜æuÖ ¦ól ){$Æ9Íôñ.`‰1¤êbö” sߥPx!(‰º=ˆšÙ—#*`×–ej‘Ç1ê¤èý¡ô&0Õ‡Ö"PA:ɘOç¹jâgÀTÌØϱ%¿BØìSºŒóEÛ’Šû¹×°c#ÜPÎŒªúÔþS¶dlb­‡³|û£ÉÐ?eV±&¹ÉŠÂÂúNÙÊÆ£ûC̽SŠ#(ÙÚÁF7ÚYüØyðQà3«b‰Èe±=¸Œ{í°çç(·Îñ0JmQ9Þ+‰ªîª_\‚µ,UökÙÐZ¥»ptûwÛý•2‡l¬#N¨NçXPcÕ„ú7ê¤Ê2ÞÕ.NöÔ
+‰‰˜>Ú@æ1UîX£Ïféa9a(Ú@>Üp Ûõ’w^o ÀäD¯&b¼p£2åÉ‹.âÔqc&û´Ë¢¬öÈÁkZ)ùINŸô‡áVÌ°#ÀMí¿uú¯U7Á(XÃ…Ø#ÙÐËËNÖÜÑ‚H~•D{Rùrß2Ö ¨gÁhj“Õ¯dÁ¥(qíþ<!P„®]
+8‰!7‹{ 4|Ã>P Ä1Í@¨N1:´m6Š¹¤Uí[2=ë‹¿³–ô¾ŒcÃ)s!È™í(rèwŠë
+4ÏyeÑ«ÜæMr¾j5ñ@ŒÇé¡ÂýîqËhïcP¸Ð/ÉPÁj(§¨!C.SIñæ*\’±d ³4oÊØe.©PسŽ»W,É݆’ɘüÂÎ%´±§V¾=õ£ôeÙp‘©Žn£ŒW¤×Äg"þÙ2+¼p 9jÛë\†öõ©eÅD!ÑiÑ5¹Óžñ²V˜ðP#z JÜT ªå-¯Á5ÃvE4L¿ft{Vªæ¼êÊ,cnŒwÜÕE´Å*© ®6 l9#åÿSSÃh9§ž$±V“X¶ÐC¾\¡ã—b)Ó –ÛªáªÌ`ÖY[ûŠ/Yu À9ÇðÿYAò\ïšân’Äbù'ðj÷I —h/¼iŸ/6D—@iJC@%Z€ß=ÌÄVĉæ±õëK?ß{±­CWCÚ`ˆ ú
+Âx’ÕØ·Ò¶h^wÚC‹›ež [=’ Œ
+ÉW)”Y±›MDŸRÕyD$Ujs–ôn²$y–.fß±Y©š/fˆ&`xöq-ÌdàêÅÓ«ËÁý¥®óÈ|s÷èM `\ õu û+¨P¼{´'<T])&£šªäm¿¡ñg?ŸÒ­8rã
+ÈLèí†þ"çÑœ ìmا‰Em‘=âNFÜI
+wÀ(!ÕMjÓì±™õ´}ÖÇœ•c-¦ž™~“S·XÕÄ@ܯârƒN÷9fƒ;öЃP£F/ù­íë[v÷Hlzmj܉`vû°<´B•ð'Tdz s‡{Šb/ÕKÓ~'Õq¹¦•ç’w¸„sT!ª]ÒOðˆ·L¨ÓÍ~2Ýà#ÌýeÈ“ ÎËv"ÙÓK¬òbÍ^¹LO¹F(w•ËF H-TÔ‹<$½FØ‚üĽĴþ®—ÃÕé\Pn·)Ñeã}‘S jX¾ò‰éß2í|Šÿ¸ø(×)è«FóŒ'œÑøŠå¿`‹2…Bì{ /›&O¦¡*k\6cü’Í»-æRØp£a“°+6‚“KÐ*lŽIQî\Ã"™àÄ2‰BÂÞÐïSV›^ÂbŠ¯iÓ»(ŠÈaϳ%Ø
+M\Vâ)!dãˆ!‹çŒB'h¡à|žÛÅÔøÓç(B
+,ÀM¼QÖ´À*R4ç–æ!M,ŠÈ«K ³Þâüx !Ÿ‰ÛrH<$@· H¨º¤ ÈLËiò£"S4zÇc9Å)ç;…ì{Ú“˜ª¨]\®0?É]ì—)É%{¨ƒ}ZIça÷„½Á¾Ò9w@îéõ„j‚ö 잤Ú"«”vÛ*åÎ Xól…[ƒB}ò©!Ö¦^ ÐèuG¯ËT7ë7hÂœÞÞ™ƒ%Çœá2“n æÐîQW7¯í)¯7âÈŽ,¤ä°¯´£5¥©mpa\žþ•ÛÓÓ~EOxÞz¶²OM1gäfFL–]ŠÕb$ÙŒ•dúÉ`¦ÀØ«åNÓ[Ž|µ[³œýØ3LA³5£œ£PÒækßcdhò›Á„ÙóŒ† ºâSàDÏÊ‚«÷6L]PÓæGp‰ì æÀrZuý"9@¯ì^M ½ ý²ûAð±¦!€ªðò¹ÊíWu…u‡––1¡EÍóâPIùŸµ7"Ê H½¹ÊÃêû<¨¾ÙI¯½ýñLéŸ4/kU!Dyк³æ
+„eá€_žøiôZ“‰«0×{
+–;kÂAé Øj÷ÐeÉâ_²Ü)¾ùò Ô'E\3ì—ÕPñË3Æq7ªB€ãzJŽo4K[k)hkîÀ«‰3$':oíçŠI¬Q•˜(‹§!²Ÿ÷ëßær\æŽ!:!¹µìüL¿[àîõ1¾Ê^”섺x\1@ çÑç
+ìM!Ãü"‹(cÙT¾|Ô˱´––áóHÿúé {#€ŠKË=ìÞÀ?ÑCòÕÈz~I›%Yï°Éy„f÷’§ˆ+K°<líóyÔC< õ‚¹Zª’ìŽM+oLÂj€FSWU~!+]Àý.TäÅr¨ZåÚÀˆžÅa±¡½¡¶žÕ‡ÞJ¯Øú7ˆ9ã+çA-RryÊf4“?!R)ÖîûSÐ:Çõœ˜äc'°•ì"fllxýmB±©Õ›b¹!ÕÆبÜÿÔÉ›e4("rRúütá.D1r‡G} $?´_¦¿ÃuïYgùØKïH±:sSˆõIÁpßf¿Bˆôó¶V±•æÒ„ô5è[ˆe!dÝ^L1`6ˆ^JÖÌ›,n-ªÛ>€·.¤=§Xî=e10&RgŒ’•>bôº-Ï-Š·`|Ú;¨Þ`>©4Ð0V–IA(K½½ÛHïÝ£+1ò±‡iÚ¥µãWWã<!§Ùš gÈâNcÑäÈ‹h\ Å£GÎ~z¢
+ðÒ;Ølb™ò×Z’òº[x^<ö¼r—&;ó%?Q™iQ ·+ &‹¢Ã4»cCdÔQì…sÍD ôúe%ÆÚ î”ÑFžæáŒxB‡"z‰óg,±¼2.<˜›<¥Ÿ,êßÍŒ*Äl%"±xJM¤¤ÄÒý@0A„Ž½ÁxÍUmUŠ³…-Fˆ¢_uÊ'‡¶’ó­zhæÙ=ÈÙœßÑV«+_¾IʵKyUu¨ò;YäÃÕÁÎ*ˆÍñõKûŒ
+ãÈ‚á“œ¨çÐ¥]6 GHAÙñ' üì³.á‹3"€Zµþ¸²~êá7S\ÏfKABY¢º\ÀD¬ÿZ.£WìëpcÌÖuxv/ ‡?÷ðŠJ&(á~B²dûxBa•Bv,Qoƒû‹ÍK¬ÐДS§yÛrj aÞ«Rñ¸Äß±ÕêáÖpY)˜þkIšÌ¤³³ÛY6€œôË}TF—©˜xb!Ã*2ÂØ©-©%/#%0í"¦\
+ëÂàNo¼½lIêáS’¿ÿ^Ç™ñS¯bU)‰ÄKäâ6m¨Äs†¢Þõ­ÙÁÏ$†Lzþàˆ3u4‹-¤;Àe`Y%òØ Ú´A5ÖM‚Ùb²›Ykࢇ¥Œº»€¾†•ÐJ÷ Qó$Ü gHC¬ -
+FcÃùÄsâ‘)eU¡ÉÉËÈøŒ*U±íoU®Fñ+z9ÃäI?tªz0dlë&àÎîti½;H#Ö¼Ü9JÔ öXÚ õ”äÇ#xRQçsLAŠ/Ù×ù‡¤XÝ­X]ÛWFm¿Â2rÆêEGš°¡pµ?^¨f,°4´s K@˜Ÿ‚Oª§'uÕ2\¸Ð´pT/]©†Þ[}ûÙÃ7Â,†ôõþ'ú™ó”·?ÿËü§·?û‹¿þ›_ýþ÷ßÿî·ßýõ¿|÷·ßÿó÷¿úý÷¿þnÿÏòõ~ÿáW¿ùíwßüøÏÿý»ÿñ»¿úõo~ÿï÷ã¿þóO~÷yû³÷öwÿåG%ð_ñ5ÁÀò¦Ž‰c‘ŠhH¢Ü1vœ‰
+Ï…Àþ2¨¡)ý?(Á¡ (ã7!ôùÏ <‚å'r’É´r‘+,·Pœa.ûeª.ˆš;Å.>°y
+þ+I“bË© ¸ç½;B—Õ»³}Jh;O¡/½ç„ý‘ i~®e…RBd‚¤rþÀ–¶ƒå”R8cHA»¦=ÜXØ$ü·–á4èY\L€>¼åÐ×É(Í"ªD²½œíÒþò7y+.mT •>,HÞ‚<$#Ùj<IÎàtéVDR·‡B2!HÈsÛÒ}Zaª ¸«½)0Ä
+i5ó·Kð·Wœîf€ÛÔFqü>ˆÄu{•ˆ"eÉ·p`ìa›Á%׌ƜèÓáËAOÜØåîÛD´7=Xñ&´Þ¹£¶®àÛ‘nÄè$ÉO.qb{؃¤¾‰D¦«½ ×iR£oR…l6”¹CÕ¯ ®ï@YUÀñˆ.`Qd6úØ`ð¬{‘eî¶""×R¨>îAŽƒ¶ÆÊiñW…ª‡”ÿsXœ°…Am2^DŽì!9jr•œ´Z˜@&¤QHéÒÆx|`È7Ž%Ô_îµûJæãŽx<X4äGIæqßñø"=[Ÿ®øtID$¬pÄhüÃŒÊ-ËxˆŸíC7 ÅeI
+hFŸðuÐx(c“ð¯Å»,½ÜýóëˆÒÑ‹äÿÎqy«h
+.™ŽG§QæößSCôê
+Ñ«å‚!Îd«ÈP…¦ÇñþPfD¥²Õä2Ó…WUЈšw[âH8Kì{hîÑ…zH¿Æ#0„³Ò'V%Ôõ÷s_² Dà–Œnݯ«¾Q¸ªÙ|པÏé?¡Ñ$D Êé*#éU€Ÿ.¡ð.yr²(”³mžÈºÜÖ¼²Êqmvû¸ŠÅUæ~WÂÕMfd)~õuÀ[ê%•·ggK
+âöTðÒct9û¢‚¾å\\ä"º$Ýî×ØœúH‘ÁÛ"ƒ=½l¢RWÄ|ƒ¢Ô 9 iŃS¥ªÄ]„‚„ lÆÝÓÊõêBâ*.=RÖ|>‹U=h \¡¤¨<îÀéÛë¹pᤗLÜäxt!\°à>G°F$Ð H/“Ë$b5Ûõ¤1ùh 3–¾OÁvú~?`¡ûC¬oÙ9K7-,K"¥¬š¶Éj5wÑ]ê)ÖrÜ#
+d±è] »øÀn*T_Æ:JÕÃÄe)C£Ið„[…ÐuÅ…Œe´ÀZ5„¹ÎÄKZ­"ãÝß@R]ªZV»Áw©º{N
+Þv„9ˆôË•½Ù›+Ë?M¦Å) ¶díÅDÊ_uÕO¹„ç‘’‹”À90{¨qª®‡8v_¿Õm¿Œ¡#Dd„˜Ó¤f„"„âqdTüPà‘v\Íüuådö» ‚¾¶4ïþ•Ñ÷|*bôþ/KöŠú=‡„O7ˆÔ69X7+ô–Òõ¢!m)¿¾M0„¾Ì%â)¾$Ô¬±ðîÒ~ýÓxuÙ®P“ÛO‹°ôz”Ö ÞñÐ~âcÞ"ú8h”;˜’² ½ ®‘Y%l&¾¡¾ï¦f;GïÑ6lI{~¤hb½ÔÜ ð€iy„¿Cu“ðKð¶Û–"`‹øÜ{u íc»Þ:6’|‘¶Ÿ*PK!€¤—»tʧá !ñùÝÊ2ùOõ&tÐU¶‡þ¿waÚõ7C„€Ã ß£ ¨n &Q¼‡ÌU¯ñõaÃÀ˜ÙÇ*3w$W߯XªÎël—ÏöâmA
+Íi«;ßÊ=&ÜÜÇGaÏḦ¡ÞRµ%žÜŠ½%áéÞƒfŸŽGjǯË5§} åÞXaÿ@vœÝuS ƒ+á°úÙ1PWy½®-ð_ÝC}7t‰`úTdÒ˜¡nï¦6#-ùŒ#*2é^Zé=qlœÈ¿±õ×èi÷ñ3‘‚¤›„ÄÙç ºLß!©OfA
+®ûÀÍðM-8Å­’KÆè¥)‰âI…;J«ÂΑÌ€Ò}þÞ\ŸË.=]Õ¿•«EÌ~+4§Pú”KUÕWmpq KA‚Jƒ¢ÎD¦ø¢ì'C‡u8„6· ‹^JÔ'Vq}bïH0RVXÎGJûËÉyþ‰¯
+{L-,Ö;ÞB±„‰ŠŽœ/;@¦=W3É^R«MK’èÁy1MØãËòüצ*‚ Œ’ÛgGªo·Tß/9ölÞFžNñ”RÄ Ïî»™òE’«ß]„RºàéßWÎÝW
+yáu»^඗£è¦™ëô .‘pû0ir›0ì…d•¯ÀUzQŽµÍ`º(lÿÕíÂ÷ìY; ®í1x¥#p63Y–¥î¸ì4£ÙÃ÷Þ]0ʤ£nºÌId̃+2Ï3ÒŸÈêÃ)³ëê…µ*¥e~jײï¹Çç¿Ñ6ß꯳k€¯)?ìs è3×I²­k2åih{«5~¹'ºZÉíöú;FŠÜý#û…Äš:‰ºµç†/¬–É­ò¦„õ¡2ЇókðA
+~)¦>ãCt<8­É jªŠÎ°²åì(œH*Ö¶vŒÁ—âÍŽåv×P©Ž$‘ôGÌÛÐ.d~UWåKøÆc´
+÷|?á¡Ðð
+oHDiºQ`)Y_awxÊÚñupKT‹ffŽ»´¸­>"Òø>B5 ¹8ŽÔœ.©Ý—öFñc’ãŠQ>`EjR; ö«Bê
+)Ã׋ýÉÉͬ`MA5·}8=¹î ªÜ [/4´`‡íCÞ*² )„–_ÐK)ч
+¦EøÌ1š_ Ÿ:âPÊv¤:k;Wç/§$MÊ;½¥î~ZF§Ñ"üE ÛK嶄˜Œ5„ƒ;ìvaôÁÅCTnÄ5W˜ÊXèA⌅ä] Ím²$™åÁh…©Óv½È³úÝ ‡95B‰@ñ \"’pÈm¤Œ{›lŠÉdEAà{§0-%C6÷áG…w¬èŒÄžÕ•ØÇå:\-‰Qï! Pð¨Éí~`x½6Ë<íQRaàçD…ð—6AÚηŸÝïgZ€Å$x©˜0Ym]ßÞ>på :ÔàX2X˜+y5*U’ÃÕ¼b¨9Ic¬Â›R ÂBŠ&Ì'šQtbòTj{PQi¡Å0 CšH]I²+¨’Psé=Íù Ë«!VY‡ÔÁb¡¬›×yË“{Ä\¡í¸Í7ÕCe )!9–þP˜Ùí?¥˜ç¶ÚŸáÅÜó• &¬™²…¹Ü¾¬âv4&i¿†º.&'aY5ã*,Ño‘»Ñ2»ñcæüB«šC²,Þ›_”ŸˆÄÒ“<Ã’k¤Ÿ\÷àüàÑ…Ô€Ù‘V
+5ÂáµW¹‡¡Ðâ’¢£ï}åEÞ;S÷rÐ,1 e«fY^®P¼Õ-åÈcO
+‚=©ôS9SûTµó£=î"Šä~îK=¬ÁÉùö‹Ä¢H稙°­OH0וø¥ÇnÕ¾‰¸ž¯Sw²wÏ*)ÒA›šÝ¡7߉T A¥Û‰j¹Å @)xÔÁ\ mYê7µzžPmÏ—ÍÔ #íéG8W¸æ!Ö“QÜÃïb÷”è^]³î>L]ÉrŠ~Û‘ʕ¤Pé ßMüÜ„eSU=•Î‰C¯kù¾Cæ{ÙoTï\Jéþ%U·(õ¡d!õ²aIn;W/9û(†‰»°W—{˜K‡ä¼<£CnÑÒI¤ßîªÕ®lÏ1"—ÂSªÚ¥î±ï©1ΰ/+g銒 AvÚ¼dyUÃVRòŽ’§¾"ŸeºˆwÝ“y5Ò‘h¥@H–AtH*a rÕ“74C×±R ð: #•^AÓaF¨Q RyëzX Ã»‡´bÉ
+ŸÃ<¼‰Rú8¿$ùz EL¹ÛBÇF„Rq’ìÔžrBÆ|ÍÅB牔¨¢¤Xï€l²Wã‘,¦ªƒf1A+V¹Ó¦u?¸[<>¢Šh;Šx®°þ‰¸’!“# “#õ\W(C0Kþ#£µsYÖS„p@ˆhcˆ½"ð/P®¥Ûª8Ã.;†¥¥)ª&W\ÉC†œE‹(l¸%‘9¾º«†
+ù*äsEKúV¬«‡3”Q¯).I/i—°
+ô²
+—Ì»t}¸½7›¾ªÇ
+š“øŠ8A`žb0ð–G`K›/R1ä)†w™Àù“\æÄSây>ÄK•
+ÖbwdÅ÷~kàÓ [‚‚È„ ¯PÃq¸ VyÏAÒÕtëÊ1Œ$D®ìÒìHÕåÙö×R}P
+X°Í£‹JFè²ø „Õ“èªÚeó®«Ð<w ˆY< Šk‚gªÜT_ÿÆÀG– ¦b{|LŠ”´ìø_Ê"ÖºTFJ‰ykœßLU’Œ¤Ì”ç—±é#à
+²ʉ.1Öð’&ût Ž'L°§É´Ì-üEtÖy/$õY@»`k?šR=ù´»T~Ù( ,àµû•‰TmѪ±ÕʯôÂF‚•{Ô¬Æk&ºâ5—T~­Áø+±—*$uÚpqX+|GŒ-¸CÆÀãY‰ñ"G3wþ»ªž/¥_Éd±!”Ìýí/Pßð—É„r÷ØØ9ô®Ëm'¾2G€ò
+‹†™B†ö»®) 1ãaj–ƒ^($ »Û!@˜*Î%(OùG·WßÄFL’Ÿì[ðŠžRŒ¯àM-;‘=÷Já T‚…D2zh,|yý
+/P´ç¨+Hx!v`ó^cAЀ%PÓ[#Ä¢ý‡g 36:‰S9Fpa†ó„¸‹ñŠ7ØXoÀ „'
+‹— l´OÍŒ(e
+Ri§/öœæ}¢Rƒ Þ ¨ïfA噀.ËsD„ÂX0²á(û&uØðÒ‘wö¾Mh„bà,ãõFÌ»¤ë„y»£F s±¦â—4A®:É¥Ý 1¦GJCÝ6{ ƒú2ÈÊœ!’Ez
+‹ô^Ât|v%uÔí¹²gK*kß8Éä«#s t•t]Ý
+R¤l¬ä°Šíà Ó_ÒCV8¹Cᤴ¼:Ïh%qÎu?÷Á__0CQZ$MâwVˆ?³‚‡љւE¸«{Ñ—ÜÀüŠn@—Þ¥y«b݈Ø.rD®Pc3ÜmÇwÜ¢f´T>A€¡)ùÚdk0ž/™G{29WÐÑÜ·&íÙn=
+ëì¹ZÈÂh„T"ÛL‡ˆáOsâzãÒÕqe_Y¨/  *ÖóÉ°-™GPQÂwݾ;9‡©HĪ7Í ºŽ€ÛX9—Dj†ëð‹ÁՔ훹¹2Ì“¤îõ¨I\³ë«âsl<.YæŠ,É‘˜w"{ÁΗS½ï
+¹™Ø¿\ÖÑ/®rÊ] šŸÕX‡RÌOj³údŒ:Ò4ÁÂÜ*Ápxu¢õ}TQÎÏ¢@×á\ª-G­›^ b™‘C×äXBô8˜L‹Úà) Æ;»(ƒ,€\5вw!ì`‘ ”‘Àºäoå^ÒÎi’Á‘,u(¡ÆeŠBÇ å+ ZŒÔ‚’'öù"ºÝÔ˜Žd¤¦žàŸÚå nà ºg$Ì‚”ÃÈ„DšP;ã1¹²ó7-˜RJ
+xm“sG" IC%¸„‚ºÚéâ¬v7-EÜê¸ö¹dÅþဧd$§ æþÊŸ”Oš|e—Hù‘%(’üÊgŒë°9"’;¸A}¿$®‘àf÷ÙÃ;dogDo¸"{”±ß$
+T àLq?DŠåG६׶(æ#ÈÖî%}¦î°“¤‚_ä¡UF=øŒ¯joð‰ƒàœ?ÿK#ÔkELl L‹@>TðÙ@Ó#ú
+1¿{àÅ°{IÓÃ|Ò«É1͆U†ÐÒ£ J0jáΣÔ
+)AÒøñ&Uv4Ã; +µIë2Œ \aûÉ9¦Šã±N|‹ä²q‘©»Š¢ÍÕ ÈI@¾de]óš®y]VnWI§ ˆ½'ë®È ž^Žì¾‰ïíÆægtª¾fDZž¢áã)VÄ‹!L¸•·Øwz»ln
+[þ»ë¤ëäîgѹæ˜ÚT ¶’èQàAfÓ@ñîÛI(·E¸_ï×÷²+,9=q»°3ùK¶Î€87ãz„U_ C1×ù%9çi² ÷ÊËXõýˆ†è+†û/À2ë¼” 'àc†•à›O²]üðÛêèxŘ¡Žá­ÊM½ä²Ú÷ø,Ú*Á)tÆqVŽ
+–ÈýYRl¦4w»4×%û¶¥æ ÁÑy§SG%¸“©¹uzˆâ+ßÒ†W'1 q>n¦\Q£ëÖaر”ö¶õ'Eú8â—™•¤±“ç,“G2=xýÉï·5ƒÄì—CÚ"Š–®íÃ`ˆ_ò§³ÏqeD~IKö²š"°Ýfm)áÁ'«ã —ö©5›}›n¼'™5kl#e^Àt”ä˽J0òe³bŧG< æü¿.F²8ÀŒ(]í!3ƒ¨¡u©Ý<¯¼§³ÉÞÙyµªF Uå¡gø.ÄFN
+Î@¢V„빃«.Ã<yõ°Gg‚D@†N-hÅ;pv¢‡"¢GìAucf‡6£¼œ‡/…ø¬IQâ¶VqC——$7Zc¬Øð°ÀÃÍYEw$­,c4á]±Ð>+ôH({ ÊT•;­Ëfê$[P¸ÂÜi/ÀŠ·ùº]€&Í$U¬ê¶×®eUò©÷ˆ-#ïcÈÀ „óé ÒõÅJ'v—@T¥”×2• XPviQ4z £Ó&=óB}€¡ Ê‹ç Qï·ŸM-þI³˜Œl?™$“ÀÄêAÞ¹ .«Cê{T>ð85^™
+!°Ò]Ô€Ê!Kñn1%âÇÉ>?é^”—.ãOô²·—œ¼†4ChcÆ™tOaYÚɦ¥ü×Î6eüñt ú€À,S.¥çâö÷ã%B¥d剅ôaôpÌ~$ÿ,Ý»défº"a¢GIPëêÔ"‹w§›‚-<
+øVéŠú“Ú´­ Žk/ÅMKBËãN@"s:T}éÜ•ÄLÊS®©-ÏfaG~¡IG l€8€Ð´Ó$yi~Ý~°r
+æËÝ“VžN6cª{ìom~‘þاûz¨XÚÆfäÌø¾?äÝd¦ÌT&¸/RÿõÍ.Œæb_…±â´·ˆ%~5EZ“`FSUóúbì“p;'q(uš‹É²,œ~‡À”TTo´»2ÞÕMAÇÛ-$ý­D·rX{Åì,Žš²\Òœ8-9Ü}%l‚Cf“Ú™Ìý¤¾ýÅ%}´¢zÉ8:OboG$2
+ôËãET^üW?à©äÌÄéÑŽs]Ôgÿ»¿„'P~ó†0qÙo§øa¡¼Gꦀ‡l‘’RAƒì3`„IV|öF¹pˆî†ž,äNž<ÈJ¾‰!HshN÷DjÍ°˜R±Ëà×õøøWjö°:cJEêyH†Ùtä¡$ì¶ãÔŠº"?ïMeš ~ûûÀÐ3Õ×L¢b¢Ù ®±PM{Ø
+ŽEÓÒ]<5´—Rˆüì幈Z‚SÆÆQ˜Õ–wJÏÉXsæß«˜Ð˜e|·[À¹cI(¬X Ýtí†J5’'CÒçAÜÀ¾fPP Ž[l, ÷3¢Øý‚º„”a,ÊCû
+Ë]+nÈahžª›ñ±2æA8t$[ÒenÒ2¾ Ò BK%.kg¨(ºPIÓÖnŸ…ˆ»€*Ó̶_ŒàxóEÒ±Ö öÕíWð” ¸)ÄÞó?uɶëßCZ°d›¥JŽ’u|^(8 fQÒþwGOæϪ’%bR™ 2Qïíe'©4˜‡)‰Chv©,ˆÄ›¶/”C„( ¢CÃË mbØp ú —@Ê"©ß~J%¨EM¡Hc±çt»ÉKˆÀTxó‚ÍhxâNæœ`dú’ÀC¯
+½HpÙ½‚ Q¸WŠŠ`Kع~¥ƾjÜ!=â°fÃZ‡DK·OðéL«Yð88nëªÉö Üt§®qZý’9Ömé-kÜnËßj^%L_ývH) ÄRŸðvñ¢$~_Ê— ×€Þ–¾ôˆTíé©ù@¦æîØÎÿKL_ho¢/ßá¥<È%’XE”>–æœ „f‡åŸ­À§”[¿M)bŸ]LnC‘@ ¸º¢7áÅ"ÑAÍúdžôbqXøjv|[µ€°ÆË'6¤»Ùðiß1"Îq‘vûŠQ¥ÑK‚À+2˦󡜡
+BV‘
+4»
+À+€f]Òuײ”c ˜,Å"tP¢YMž“]ÅYʬ‚n@y_:pÇhç¿Û{]ž1àJÎû`cC!ÓÖ½þŠŽ+J…Ê5ã¥ÛÊ’¦ð{ž½™6»´2‡@ë+½½`Fñ;Ìÿx@Û™+6"¦!Uõ˜@š¯e¯Ô²ô¬dw’
+.;m^áÜKü:ÄõV€JeçvÌú®ß|8 {½˜ôžÏ“iAÆ=è_ÿ¼Ì£jxêDö,jô)ÄÙ[•KeI…·G67L-L—3ž°n˜Þ‘îBÎÃör`ñÀ”& ÙÃSRW>`èÀbnb'ŠThZ¸q:c©‹‹J])(Ñ-š¤PìŽÊïtIqÌn_âOt:ð–D´âŒXªò²¹)päML—FÍ83ŠiÀùòVø“Þjˆ(ßoj¿}‹"¦ïqBŠL¨Ž¢‘"î6(+Ô)Vš.aDÕW(ûõh¥^ÍTþ©I®B ¯ù·J¢Ú‰Où~•ôbàÀcn¾Þg‘#Ü”rhT–µ~–]²öj…Õï›|¾…Aíµ(–‰ê“™{±ÍÚ­ì ‹ #™øNbª
+´¸=®Gº}ä:…bEWaŽ÷¿"Ì÷n#2©+áÊí²ÉŒ5x!Kx½Ãfûs?—r“9#: Çň˜Ã*ãBªÊ´~0ËYš»¶ó¼ÑwlØazýx ¦d»¬<fœ¤Õ[½k9YV›!ÜÂÆåFÇ â8Ðn˜Ñq¤:ÿ–@BŒ·„oÄgªwT/oªv©£sAK° òÊ£ÙÏ*mHØ& æTà>¹‡ë/¤F¹Rî|ò0bHÌ{:Wøºßé°ßµ˜ry †î9×ËS"sÔ%¸Ç/œô¤:()¾ýuµK‰½*d¹–¦tÊgìðÆ-‡W&‹=ßWŽ`Ú}Ì­òrÁ ñ†Ü¦Ò¥ê|÷ µ “8J»¨( Ì¢$R
+$u,u‡£–^ï]yB¤}j‰B(Ã÷¿bÒ!¯Tn[} û§€x’²ËB˜z5€zX€.ϸ*à
+C—N²Å‘udY~"’AÜŽ[]Ýi‚Gد·s³âå:DwØ£ &[eƒÍ¶@÷¡·|=¡¨>ìàÚhœ<;8^ËÖWÚ‰‘0]
+ÑÈÅwGœêÆÑJ?õ”çuBqëÊ›~pRò“
+º2ìÝÊ–?Oº²+€‘h\ùI¿ûÒiΩ…|D¶å4Öq€úê ÄÉz³ä éE³Šªn.¥´ F¼»§øË¢q¬8…Ô£X7y_ý¹˜ Q<¿s°<ÐɈæråÐK÷
+«9xº‘nÝ‹]¬snO¾~ÕlܘòÇÓæ+]dŸã:ÀÅ£  77O4’’ˆ×tg[¯ñŽæSb:ùIóB *ÿ¾¶h쯓þô|er>x©Ý^xÝÜbÄ+U•9´+=#¾-˜uij^¾
+NPOß5ÏÕw'xyi¯°žbYqiTæ®U‡NSW÷ ø[6^ñ> k|n¼c…ýÊÏÅwÀ^ãA=;í~ÈfÑ<õðÕ8ËWkÏÆ'†1›{`j®û¢qæé›ùêĸ‚¦¶rN %éK“Øgžh»1C
+òÒà­Œœ©Ö6òW˵
+HÙ¯ˆUOüÍå*±ÙP\÷ô¼A©1&øŒ12Õ\3ÂH=ú¶X€8i³õ•+xæÏ)¸Î‰F»ÀÝE[ï#¶Ÿ™*¢ùÎM&ºì‘ '8sÍÏÅ3ï¸ÁhÉÆ ( _½ƒ×7 `Ó+ã3Ûù‰L7³û6šsÝçÓ>s\™?Ð)¾zÞXqaâõ ~W]˜Â^Ÿ}êbóøm6_m¾{%qŠ8·ÄCÇÛWÏ›w(Àæç;¬_¤wëà!¶T4žÀúkâF¹Ø¹ñz7ÐtsíyiÆ Î÷U¯|ýº¨ß|ýÂ^_‚â1cù8¾µ€|eÐÿýîû“óþçýƒÊÑüÿªð„7é©9â—¢y¯L%›×zs#ö'qSž4Ä"óÉï2væà(Ä_
+¼ÅÔõ<•'Ú®ºâ—°Ì;F8ž”"•xþHÇD#Øñhlñ¨ÕÜ2c±®Ñ²oÉhÄDcÏoò¹bËfSäü¨õçÙkîщÆz•Œ­Ä³Ÿ'´#‡P_½~ý-å j)ùY{ŽUcô¬¯_Ï?.×»9ð5³]Ïã9pz/§aM4fј–¿>½l'õ™YºZNÌWl n9¼Tp«Ç· &kåµjmŒŒ—Bú§ÆÞë9mnb¦cl7ÞãŽ;UääFœâ¤ýü9°»|ø±°PhÉuA#)Ï™ƒJ©‹×ï?gs=ƹ­v¾ÅDñ¨Ö}¦ú'%©üê™ç­WnVÊÔ$¤[h9.×7KÝ73iO®+4¿—WÜò+—ÌrNÐGN¯âºøýÌþHŧ%‚z\Ö½âѨ–ü\Øgæ ö>ç¬Ï}DßJ!ÙoaÆBܾÈe¥Eh^Ï ®ûÎyŸ)Ù϶±íÊŸóœKãìÙ÷¾cÈ dg}î|å%Ï”ÑZ‹ž£æ(4‰ê§ç휠?D†d<YŠ™=3/meã5®ò®1Op]çÕP±ó};oqŠ•· ²Þü0@ë»[è”ß|ÞúnØ£}•]Š²—<Ákp8íG3€Î9sŒÇð °—×êeVB-'0X9f‹hJ'J[+–ïW‚p~qöš¶LjB#:žo dË9m›ç[ŠGðs'½ÎýÏH:êïÛÌ殤#¯Ä¼6Ñó¹!w’'x¥êbCŠqEn–Ä
+ò XÙÎÒWòK(±ÆÅîÇým4ß%'ä§x6—tQ>„’ç¥PN^°Äs¼–™;>2NâŒö’$Ë’¼´Û[è»íÉ"ª²
+pó=òkˆèï¸}Ã+÷êö†É¸|\œ@z²yÃÈظ±ÞågÅïAö™”)9”aæõ;›)Û»±žÉ:Å2×=“zyçDLá]2’œå,À¬vÙÜOØ(Rø‰;¿Ž¶šAó:CÉ·6«ÓX4^¹ŽH_ë›øû2ÏË|</Â.<ë`dèÜxåÚpÍÐÀÖe¤%¿æ×,›aó ×cwþXiù¡<¦cøùEìU¢æŸŸ/=ÒL*àÎ3Öœ=øóS‘z<³Ë†372ù™¹
+"¡wÉ*ç¡Ñýiöi½»Vþk.0ÇÅÀ¬…»x‚^iéyŠÈ­<±J€!=)|J6uÌySWɇ"c^7>-?+<ÎIW ‡ Ö¿ü Üude™Æw“ó]êëq[/йúæý—«fc;1o}‚v6¿%¿>¬6óÍ9ÁýdN(î<ºÂïVõè{'n¾7£ö{?Ûg”Üs—Ô…ÊGƒEË·Ñ<ïœÊ°$æŒãfG³g‘˜3¹Ÿç}ÕÅ´gμ@ú×9ë·¼Ãàöw¥ªËåq¯s2 û¥0¸«%‚{w Þ¬ZÃb0Àùë
+E“!jYESóÌ©2˜ý}Íó |ÔéÎF<kõ—Ô©>v¡ôõLÔã4ž²Å=Ûë¯bŠ– Ñ:©„Hrõ‹Ân®©õ<Äë]½ÜÞ+u¬ »©ÔÍ/…ÕZ±¬ª¾S•âë0YF‚½ä îÁÌZó÷Ù÷DQ™$i’À8ëMM¼jq_ïQ°Ï}âQO×3Sõõ‚¶­÷ ˆO ß³ØÔì›Qœ¨B†³¯×üÝ30ž\Rª• önî(2ëð3 ‹W9ˆ\³!œ¨Ù•-Í‘'•'FÜéz]€üª}ýý°9^Õ¿»ÅSA¤6'©ö"#Á‹Îóèþ|·2EĉMèÉ êOj'g´çE*S†/A‚ÎÚûK‡$ö s-ëu]¥gÚA3O\ìI‘§ch¯Hz–ó÷W¤c¨@·X,, ×u?_µ1\jL­ ¯á’+“À„IŠ¸ë™ª{}q%Ú•t¦u˜2™å d}ŒØ•ó¡Š29ºûÛ™ûüý E=\{Õ¢Üñûm¼Ãmf‰ŠÊX=´ŒšACó_ájÄGÛòúûë^W ~rÒ'€À/F=MO÷—Ly³b¡»1¡È¬–+Çs˜kM*–C¥aOê姜ìðp9Ç}º„(gÃÌ5׿‰¿WÝRÍš+ò´Y6Ç5în¯æq"¸Q»Q ßx61ý‹¯ŸŒ™Õˆ|JN“=ù*å
+}yÞÜ·öÃ8A Þ+ PÜ‹¥E‰ž’™Î o=Ú_ש-@
+ªîÙ¶àøgÏóÆÎË™× ©û©ISâ,9U‰çëž÷‘;(OÐÇkùYNÍ<ÍkNLÝa>)Ä2¯w,lA9ܘ;¶îå1NPj\«â–s‚'ßÊÄù‚fAc¿s̼äèHÔîuðÛhÎM:³Ç9oïõL)A=.Ì_§g}·­áò¼¹síIÄÜm3öKÝ$€lL®ÂÿSBŸùÀ’®“ži<Æ2=Ÿ|â¯ú&¥ù~>|6õTËÇI_˾9U3æÌD3ÿçxÎÓw¥ÊBë÷AŒ¤8·ƒT!c ¬8„Hƒõ³ÂrYgx‰½'È’Cw‡hl9¯fâökJnž+?²¬‚š8Tè!®dtó ÑGœ'xmÙLJß„æuÆn¬çÓ5+Ñ$IÖè.!Å JN÷|sŸØ¥;—š'×™<" ¦ñ,dÁ¼ú*§<úÆVƒc˜ŒÀŸ~üPÕsS‘5¢ÙÞmÂÑû´í,oì_óÏ[þy,£0åknN ä_g¦>ö?nÌÜw·î¡ו‡dWòø²æ”ø䥮š‘@IY=SW¤*Àª×~½ÐV3ŸU*ÛìVõ ^•~™î¯2ïÓ“ò”E. '*]ã#V+N0×û„F6gVÿ&ég ´È°–óŽdÏí¶Ì]\‘t£±æN%#2ΚñëûJ~ÿI¥¤•¯¦
+ì°À/b›HÔ렽ƻhH Òo£¹ßç» ˜ì'íÈ“‹ô¢Hè}ä}MۜąåF`¾‚ r›ØRùdJ4¾bÊCWTó8Ñ ¦Çn|Žä•¶Ÿ—ž×YpvE/¹ÔÈp,Ï ž³‘GC»åuÍš[¸ùY¨ÎÞÑü9UÜצâ¦yŸ]OÍQû¸Pߣ‹ëà,_29I±9=iïN°òk˜ÅÛ NpbÂe ïr"œ„Ÿ^'ÛõÒçZ/Žvئüò QÈàÍ,
+\âûgŠ¶¬ž'H(Êðt“'Èy’©o
+öÕþý/¾zŠ_
+A{õLÒÖXšQ'xr£ÚÎó^å
+ÕËÅ~šòW¦f*O´z@f¦ß§’œ
+OÁ ‚‹IªÖøH Á¹‚ƒ¸«Ô_7ƒpâ°úZ¡p„Z¥¨…h) ‹¸…G_åJW7«üNЫfdÕ~:8;ÃX˜;¸ÖL4d2Í+˜ +L½ÁKõ^„›‰ _±V¦PÑL³;ÕXU$FÕ¨)£ˆ›ª±ØbÕ½ Å4MÑ=8÷D|™©XþK*v fPµžá<xÑ6
+Á?`2áN2a',\+  ©PNK#´2ÕŽ>Ü(¡¸ J&Ò0cUQdkZD¥‘»êÛÆb™™*Ïf“ºÙÐPPGÅÆøG |Æjð¥QT²ši5U²L¬ç#`HÜh¨BBx*„2‹x_‰ø}‘›Ê„ïË ®#U×Ä23÷Ûoè Ñ/„w"/f&Ò%ŒsÕ‚YCxS5ƒ8‘F(Xg*KU6‘úÁ ÀÉ(l¦ÃµTTW ûæ .© ±Ân6|“@M‹Í2ávBÔßÌTLˆ‡Q4zv
+ÈTÊWÕÀ9a&ÕÞbØh(Ð
+3•„&S©´/„¯ã­Ž¢ÚÛó7©›5$Df ÞVi FJeBÐ …蘚èú5³jdš-ƪJnª›©œÍ¸Q´‹FFRM†¢§E]Z
+e¢x U9ô Ä™J
+hÖ'Ž˜«ÞÌPåõUÉLÜÅj,rtu5HØkh FŒ 5ûh5þD¡è‹¾TÜ%-SÕ3SïÎ5kê‹û`5›ve*m±IÝlªö¥‰R›†ñ9IêwÓv3hоf ºqî/Õ—©®…]µÂƒÉTõ®`W¹‘èyÄëMÕ¦p¯L—P_k*bµGïa]8±AèÀZ6i›z¼&¶¬â¸Q”©¾o&îÌ” Å%UÍFPGI Q¦o ʽp/!À/S•§ú5ÕL¯ÔT(‘ ß' e‚* 2ÂT—æ2ìSÕ§¶à~¡Ðƒè$Tc\B¦i
+EhJ˜ !
+Ü,ª[œ+¨z.©*k[õRuÍؾ-Ì­ªø>òÐT:aé¡+…äYŸýçp¤HÅ dê
+ F}K-«·?
+ÏjjbÒ—oá~¡øŽ‰è0R…\¡ÑH“
+)Óê@ß;Дǀfqqjîe :”T[Ì Q8}@]P[ø¾¡MÄkÿÖÆMRoi´ n€ XŒP*ÆÿØÔÁN¡¡„DŸk û
+êÌܦ¦ºN-y©Ù{+–5y÷¨bÛ¯n4ëE«É®¢
+<¤";UØ.Ž ©ü'Uç–ãï‹Eú6ŠU úvðÇçÚ¤9éµÜ„ó„ÆÐ,Z5xZLÑ„°šXPØÄØXµ¡RGÅ j§*¡U,U©o&$ßþ¥šœjÍý¥N”—ºÙD|CaCš±‰¸ãÃD•¶«n÷ò Ñ\øº‰PÈPal"f5˜¨ROþöþ}Ž³Q¯2SUV­æH'¡:¢ÚÛðÇkÕ‡büu…à‡©˜Ò Æ}®\ü÷ÇÞüícmÕÔ]5„
+%Â! úâ‘j»Š·˜ˆ%ˆ…mªÿi ÍŒ…ÂLjŽûá§Pä¯÷Ž<ÂPL,Kg œ­†u‘PêM¨¢®j¤Tï-Æ‚`Ë„z &}ªcˆçüÍí4‡åþézñ9Ä꼘܉Ï!VB0Rü„F&©÷SüÝs7ÔÔËƵªÿ?74I³x„“‰X¬J<lî/½jŽ–26ÒðXÍÑRÆ"ƒÂ¥µÄS"eBm(¬'….e®ÞKû×n-¨¯*‰¤úƒ±p†ª jÅ‹G’šŠ'䙊¤S]÷,¾‰¦Òé~`MÍ(á@?YßÂôêó„þæÁ„'6T­
+n±ÌŒLõþö½-U-r#Ñßè%4ˆÁ@1›ÔÍRM
+ :e_+Æ/Ôü×~…ÊT©¥*›g,ž% UæÌÄÕ'ÕìZ4+´
+§ˆüM'‚ö4î“X Ó¼Ž±X![¦*Ì-TëÓDë1 ßô÷lÐÓ N\UR88L³õMÜã„¥špµp.ž¾…Soþ¶[Áv™‰%¯ÕÞ/u³T&äú u R £«õŽ)¬A“?BdõµšX°p¡™ª„Z„^ÿôFÕï‡Á»‹¼ÔÍš£oñ–0!3Ds)N!Þô÷À@+†™éÍ›¯G‘ømöŠ ¦¶k¼Wú¸ZÚ:ù{«W:¹¸yÿ¡yžÂÛÛÞËÉQ·ê¡æùp¨{"œ@o ·Âýn §ÿ§ÂÐ?ÌÑ/î¨)DÏ@_o³Ëëë9—¬‡-613u„^ÈTßD^ÖTΨ
+ÌCí…cè°Â±¤KÜ@+Þ[ÛÚÞG›öJG”Žg¢+&q±¥_0aYcØ”QxLb
+'2q_PY#)Ç þœ_ÊÖ7n(Ìaë¡MÐvZ–¬³–%ï¢eA9!Yä$VÎý,­íûm´ä$ cƒæ]A{jY*œnb%›Í9ÉÆõr‰%íªeÃziËÑûhLÑ¿7YÒ’5«7I,m¶öS¸Å $ÝR+ÜÒË·†êZ3žZrç~ö¹Ò]ÛZé¡e¾ÅFbùkQy£¬ü´Í73’•ë,$›­Ñ8Ú‡õg¼sGÐù£(¯ä¡rÊGËŠõÔ²Rjo@×mXe!±TØ!9ŒìÏ¡`Ü´llƒuHÞW‡tíÏ¹Ç á½b‡²A©#mc
+A榳‘…ãiï„¡rô¾è´ØЂ±\tíd>¾Q‹)ŸÌ‡äŒEò<žªœÌ‡eŽù¡=Cn!ý¹ˆê/ÐøNf="ñ1S¸Òsflá #>&w\C#Ù¡½CÑžÁ9¿´Êĺ|Jã—ÊäÚpoyÛð¢IJ¿¨a¼è>4k,™=îÃ$ W8øèöº
+G_]…ÒU›°uÓ&¼u/$뱃)ÿ$3”ÑåSø¨âIL`âpÖ9­ƒÔá\\Ùd>¶~š;–ñŒLºô§Ý#2é#Aö oÊÉO—÷IΆ"ÙNŇNà3÷,ds.áCÊÆ3^1C(ŸèÁ ç\Bí4.®n›Þ2›KmŸÃ…•ŒgRG2žICA6¹¸ÆélJë—tÙS¦êæ7Töî¹tLéD6(g4é—8Ô†GsärFÏ€ä9¾a›Ò<“«œÊ'¤½£S^aƒØðäÑ||Ýt:(m$í2 ÉÃ"ù…y#í<uXgO]:ªa2í•8Ä’qÒZ»Üéȵk­7>XÇšñÕ–3h.uèc͸kmÞÂH¶l¤$Vrû~r¥·6å1ˆp
+AkÞ¡Ÿ¥B)±fá»nZò­þ:”cÌ
+ËÒË|pö.0më7 ôôÅçŽÁs™;dŽIo…Þw6Ÿ¼c6¬5.¥ý=kR›Ôö%|˜ä¦é\l ZÕS” ­_â{yG fýb‡2qÕSø$ÔÒ«ljóLôs›Ô<ƒ)™ÄDŽ£}S†‘~IC)ϘÁ”š‡Øª)l|ÍT6²h]8 Jë›Fã
+ÎE²’<¿Ÿ_êlŸ“w̤Ó}Gú€ôŒ¤p í¯pöËM¬ŸNç]ÄÆÔN¡üÑü¹Ä „9€ç£ýÓ†Ó>éȢq Z\rû—´oæpЩ¤;²¯è »LŒmñô&â
+­,Ÿ©Û¾´¢œûY#[nÁ¡Ÿˆ«ÀïV´—–5â_r}lÆÜꯋí)Øô£ ¨â+2²æúWLúyt@ú2ÖyÑX:ácü{þ&m÷l*÷øB:©}]9‘Š.›@E£ÂŠÇR±µ_À‡ˆ®ŸDød“;†èZR®zjîɃéÂ1”_Ú0…kXk¥`Rü!'S"ýí1
+°âX_¥Œd½c‡0ycµ·¿¢ê{V`þí>ÛD4¿ŠÚ{_)j{¾&
+N,bã맂|bܨ:p5Ë!€­'˜ºÙ­ Ÿ€ñü£÷Gxv`~À |LÕÍ•«²³È¾0Ⱦ€ƘÉ2<]48,ƒp ¶CC€ýg<oðˆŒ±²´ºa¤{]DëdôžCø¬XS Ÿ™”Æl’]ô7ül©-35÷Íäõ÷¿&r÷ÍûM9õ‡õ÷µÃ„Že’·Ï ¬a;g¨C:éÂ:ƒq{’þ)h®g¶õÔÎH!{G 9"÷WéÐêIÀe¶~˜ëÁÚ‚õ ãdž¥}J#K»!ÎléÖSXÙcÊá=$Ÿt@ÎHÒÍ'g6(k´¥q®ø’
+ˆk#ŒÔŸDØ”ñ‰ʇ lž3éE„1ÐïÁˆ÷„g#œ^<ëZd³}‹±È=ÒÙÈEkn]pt)ƒ¸5¬AÖ=裢sFTËËõôÎ'VÄöÇ«˜ÌýóßÔ€¯)7„!‡Q!y£ñØ#ٹܺì5á1¸鉮] ~!¿ôá„kÄ
+qK[‰ãÐOÁ#NÚA÷Q®Hv"û#yÓ¾nÍ#Ùcýµ,Z› ÎáýaÊítðC:ü– ;ßÓÁöÛùäa\`öhð
+òߨǃÙ[ð=)ãj¦ýM»b¾>€óCx yÆýH¦@‚-Ç:ÙXÐe,æë©£¹¸ÚilæÞùlæ®y˜ÿÆÖLåk§ŽŸ!‘7žGü­ .ºpÆËéÍ_õ·¿%ª¯™Ò!Y£ÀŸ ²Ì§VÍ`3[ç’¥—eĶ'«ˆ–ç+åÛ_® ª®šÒç ‘ÎœÉx¤[K¸E P¸E `ÃË'
+4öF °]‰¯ž¼”*=)EØj>¶K±Õ_0IÛô0>F6ëÈB:ïäªìŠ±ù¹| ›7ÊU|ɬ)àåâýðwðOÞ`s"þÄþ‚µ‰äü<àO }Ó‡3ˆ·`½ÂîUlEúÓ!¢?p:&a»°²ñtP1ÆÖŒoÎHÐË€wÀ',ߤ2I¹'fürG¢õ¡mC9hÑn1ƒÿŒ‘¬cÌ@MÂÖKp(‚}u|TÉàÛÅþΨ¢‰\æ¾lÆžyð@/„á‚“FÖccª'³‰#8ßè¡LrÝ4EÍÅîOæľ[ä­ï–“Q…ã@þ,9-ðËΑ
+ü«THÊHÚ ÒKtÖÁùtRãtÌŸÐwéücK¨Ä6=&¢ñ À‚0_`'èì£ É†çË©²»¦TbË4°‹LdÍ$ªä¸¾¢ñá2yõc:uÛ *8o4áŽl^Â9)Íz°Øê;+ÈÚÎoˆúÎoéÒ‹&ð>€“€s±±™ÂýK¨Â£K˜Ü ™„¦i€íi$·˜ÃåžZã-/¿a$oìþx5ë3˜Üê£ |¾vá&ðáw‚u±TXÑ8¼ÐÜ
+|z`l¸àŠñ º—|«øX/$ïHß‚LŽ8<¬Ö%bÄ„øômj¾5ü5ØWˆtÚö%öws ÀÆÙdÀ‡81[2‘(=©Oî~¶‰=üHI´½YGÇ×Nµ"wŽ@;Ç$íqÐNÇä»ÅG!‘?ø9Ħ8$‡\pÆh>ºä à+|bã Ùy> {4öÀx%ÔN®Œýå~‰ÃÙpÄëþ
+²èìïJAl¹Ö)? âO°~9¬‡Š'€=ÛJy„àÔk@ú¸…)Ñ|o9“Ù>ü p!ÂUËÂÒB²e“¥ñþ~Às >
+f«ãè«Ëy… æ\|ðîùèš©\ÁÞ%LÑ÷†\`ú(ð­Ù õD@î š|tådr¡
+›²wŽ¢öá×DÑE}*íÈ2ïÔ"¬£²ͧ
+ÏPY»æ
+]yóºöîrà<dDùxà ¯Þƒ×`yÈÛC2Á”Ÿ1e:×SíO7òïÙó{z2÷äB2¼vT8ZáŸ=b6¾:V”]?+$§ÀA(„Ðz™ zAë|Q/²0'$pèÀ…|æá%Ê”í³1ž Èùd-²åu·V1ç¥8ŸbvH¿
+±^&®f2¸Ì¢ò‚Œ*ùÞ€Kß; ¯À>ð@Α2¹rŸÖ<›Ï9²r:T˜¦a*ö½ƒ(8}ö±G—|û0‚2G¡5=ÇxÂÒGƒ|+|uǶòÚ·*ÎŽìwäwì_À§n› >{Æ/jˆ*=|
+:…jí^G–^1fZ¦3‘è}ÀçU: 0øÿq<Í)âTã!.ª¨DÜápn÷#B±ýé
+yã¯ÈüÝó¨äæéªøĶ©D@þH2´t,•yz“öý´ÖÇ`•Ó:|^\RÍt°™S€¶ü¸1U~Áløóø Äõ€ Oe
+Àß醻+è¦Î5˜Ÿ4v¯€˜ UxZŸJß?‡(>ºˆ¨î4£2O, c§€þVT\1¢š_®¼Ÿ-Ö¤l¥*Ï n: y pÿ¼#KتÛËÙ¦®udáErGœb©ÀÑÁ—öq$vo'aâþx‡£õÎ7+`-ùg—Paõ¨€¤aÀ5/á8p@îH¬‹ãê¦*jÏ›’MW¼›#<h¾z“ÄBÎK¬Ydß‘ç¼£‡(ÁŽ œNy
+Ø.;‚Ü2ÈùAv‘É9¼Í:ºo™1!À¿€iˆQB|Í%äŠÎ|  EöÑ/iöõ»Æ bƒJÞ5‹-8!ýÇE£y
+J ¸óל#À]¦€ìÒáYد~eíÃõš&¦v2pðEA¾mhÁ;¿ø\döx6£u²Ñú kanmÝ«•Çn8Ù]¸N|,‡8Õfs¹lækàÛInù’Ê=´
+`vÄ3pŽ.ä2æYLçì›óƒ Þ
+\RƒÎ+G<çÜfî…qš>%Ò+p
+|=ŠÚ[fLî9ì—Fkòõ€ocœ›³gÄŠ w¿&j¯šn
+þàu·øÁ‹~4¹­»*§ÞÁG|K6¶>Úà3VxÇ V¸„÷W@.OÂP:¾q*UxÞ¬¸ekAa¤ƒx½– Ò±€‹!7pŽ—Eå§cª&A^
+]pÖ@5e“À¦âg†¤œ“KÈÒÛ&Dõìæn¹†<QÛ¤†/1/üW‹}ŸlÆÑ…STù¶Ïb3wÌ㲎.¦K.cÌ
+8,¼xþà<¹Ã 1¿0²—X/Ä×Oy¡ ÏJɪKf؉äë<6çÐ"¤LÈÆû+ˆºë_“%' q Æ;gÛl섘ÄÁgœÒ8ã'dψÆ[ß‘•gd8nå“:œ+q~6ÿàRð§QEg¥DÕU°ýDÕEc²ò¢ UrDô2Qô4¶uÈf´!›½{>Æ´ÈfCÎ'“µ>¶ý­/ÖË[º–Qi­3àZðÊë{¾˜YpÑ
+o…Wõ•L­ÛZF}Ió§:=ø£÷
+N.¢êŸ,ç¶÷XÙm@°õOײÙ'—
+âÈ3ÅñWqö’<ÿ‹}õµ/}ëE
+yå[c›º_¿b>nP¶=VØìpW^ºn{óJÂÖë—’ìÎ߈äÎtzòûºY¶ý™Æ*Ûß®žF";Go{¿aBc.jûTyu§‰üèï–Šk¿:oŠã>_Ïå>ÞÈe>?Ï¢•É|~”Eÿò.úð.™ûp3ßýI{©OOsyêíÜêâ[i•®/ö–þϽëÎwy~¸ÊîõõRîÍã\þYw6yÿEO_êÇÎô¹Nò¶ßV*š?,çÏvùÚ]¼«üþ±;óÃòðG‚:ùŠã®w…Ù=¾–ÇÝì‰b~ìñb¯= à¯Ü çotÄØu\Hc¯÷ñçîû²—ïûrç»üés/œÉ_nåÎ>DòxÇ‹¿pûx×é<[«–W_Ùdžm]Õih½ÿ×XŸìµ"®¼saŸ>LU¾ºU |×QÀ¾êÊ`Þõdp¯»rÈ'Ï#mnü·½Íÿ²SÜøÝY~çg7òù§(æã£LþsG¡ó«c•Üçî<òÎsòÜk%µû­…¢è²>YðÃR¢ì¾1±ëÓFhcO?r¶=w;Xyö–¯òÈ'þÀ#[åáÛöÔñ§}â¹RqêMŸ{ìÌ^xäÃ}àÍxâÆ~ÿÌAqà·ÍŠc¬)désOœ¹;w¢Øû÷â•Ýw3ì_])q~ ÎëÉ®:×—‡«Þ«d?ÜËäßIeov†‘?¼³£¯?ñ£{îÅÛ½¾\âøöl…ÇÓ½µ¾=ÍÕA몃ïW—ûw5Ty<i/·ýp¾€úø&YÞù»§õ±mÿP8†kN4>_Fîø`Nooº l—<þôtËÆOÆÔÅ®vÏ.8<=_jÿb¶Ó‹SŽ/~¨`:º#åW~³ßr¸w…MÊé™ÖŽ‘ý7›ÛJHÒY‹Ý3ƒ;òÀÁáÅå^O÷ÕumÛæöøXíÃk™`×è}=»£ËŠ=‚ÆéÇëÁvÎg)¸@ïê¶ä÷=fAÏÐϺ=Ÿ¶W"™«¬½žRžu#»dÐéõÁ2ÛŠøÏ—
+Þ+zPŠe²ýF|ÙÁqeÛ®'•ûö4VðHn^)s{º·’7Ÿ{ß“ãøò\9õèC¸õÑÞMDûoëäu¯¾¦’OÌ!·ÿ¼Þîdg â…›¢õ¿V+ò¯/±.éX"?ý+¥|Ò‘åüâtµë³5¶o;Š™Ç¹—3¶¾¾ZÆ¿ìÈ¡®½ð’_ülkóý¿,å§^ÔÕ'žÔ'AòÎ_]©WâaN_ž(gïÝŒ²:òu-÷¤–m̶ú÷²-ç{7ZwÿËÝëqkUÓíÄÊÚ;IÕ9µIùu=uίWò?ß)â~z’Ç|~šÃþú$Çñõ±²€®Æ÷';Ëíß}_lsïß®–ûÿµŠÚý³wä ²óÖ1™ÇÒW¤€]©ö×±Í=ô˜gv#ü·ë±Â¶õœoxjN×ÞùŽ¨¸jLìø´Ž;÷ÄËöÎÍDþæXæÄ{yÛ?VÊK®-Uä_Zl]z}©âäGÿf’ëóSµ.¯N×(_ÜÌeŸw¦Ú~¼YÜUW—r?·>ù~n]CGBUêýÜ&þñµtòÁÓ@û÷WK6¦?̨(~”XÑÚWÚÞS¼çNl zß²ôÛYå9׳Êrîd”‡>¬¬ØúæX ýæM2yã½uúƒ=ê‘'î‘/é^wê‘}°‡¤w÷X±Ÿº²l>ö†Ó¿¼L÷êÙYãß³½Á·gG½WÏÞþŽ,òÚOÖ7þ›—wþÛMq÷Ü-.÷Zn>Û»Ö¢ù•Ìrû§¯Ø«O‚·¾¹Vîøúl9õøMuí¥7uã™ÂÏn\K·%µóù&öp§’¹zÛßîÑYnO÷W;>;Qæþôp]Pwó¶È®ÒªÔ{ÙeÑóKò´ÞŽ/Ý?ºäüý°Â›]!ùW:"Š.Þ‰,ºÑVp÷^XÁMôïÛwËn܈*>z3¦¤õfBYÞÍÌ*ßGÍ•¶ï(`?tf;¼:Qªxð_~6'z­‰ÃÿkCíÿÕ†:ö–e¿ØÊìødI5þ²†Ûñ’¤ýJ27_óo»ó˜—Sé—Ï“ù÷÷ ¹Ï· Éo™Ÿže)ßß(²{{·”zü2Úæô?m§ž+Ø žÊîëéüûŽ»÷—K;órf4ö´mw|yºœ{%ÓéõéJ×Wª]^í­\RYp/¹ü`Gté•ûáE…þÐVx ý<ÿ ¼ðüýðÂSQ%Gкkº›P¾íVByÃíÄòÔ»9•ÊÏò-nö2–E7æÛìè]ÁúÀrGßoå½rà.õøÛݸ–d÷èJ®ý³k%ìå.?yû‡UŠ–w«¸ön9wü©©+˜»ˆlò¹ŸøÎû)9w²›âî•6Ù?¹RÊœâ¡ØýOs›º‡&ò?¯¥N¼e™î®Ä ®†FÏ'{ëíÞ^Aºð|…Ý»k%Ü/ _)è.¯«½_Uy?©Î÷q[ÿþzýâA‚Û‹5IݹµÉ³«ªïÇ—îéˆ.†Ï»Ñ%ߣy:w+ªô쵸ªS×bË܈-­º™\æþlgûéqó¬;Uy¯#¹ðÔ‹»q?Œ½þ(Œ»}/
+ÖFéµ4$×ÙåY·³*’nVÅwVÕ_K®Ì¹]G¾|oõc¯uW¯»+ÒOy·2kª®¤Vl»’\ý  ÉW}}áŒzwôlćq›/÷n¶ø±w³¼ç7?èÛ«kSAGîÎÜ{y;}Ÿìmq~y¤‚~t;‚¹}+0é~a+Ì|ÎÝ,Ùs/¦dÛíø’ƒQ%W…5=Š©py} ’øýu‚å›^7«wÿëeý[oˆâ·ÏqvïOäÇt”TåÜͨ¬¹‘TÖz%¹,ênY…ßÆ2ÿ‡î=í¥Ê7—ò^Ÿ*åßtðÏ»rùž'YÌñ߉=ÿ³‘9ý»“C÷Í2ÿî¶&ŸžöZ—ç*·¾=SæøæTóéY†âÍ?©·¯Ù_;ò\^ì+wxw¼ÔêY¯‡UÏGòù½H—‡ª–ì°}p>Íâ‡Þ[Ú~•mÉ>1}Kxýh‹˜ú±[º ¬nÿ‹%Þ¾Œñx¹£ª°+©ªú^b¹ó«½¥Vÿè Üü²×vÓ›^nãû^~ã»^Æü}/µùc¯ƒÕ/½þVÿî ¢íH¡ëHQüüsìæǽܦ²î¹–‡{×—ÿíÈ]뉰»×‘éþø`]̽²Æ²Ûéu­·«"ºªšø×ws˜‡]ñôƒg‘샻 üÛGùþZêã:Jê"îVÕT~ür\IØÃj¤³OW)ßß.vx}±ÂùÕ‘Êàžú¦ìYMñÅužOÛ*©¾J#_¼ˆa^w!Ýy»ØùõÑJ¯§íÕÁ=UU•«Rd×2Ÿ{²ˆW?E/~´¾ßë°åJï–‡>šm*¬š¸1ç” ×zWX¿üÍ›ýýn^úìÊæk‰¥Èî•î¹’Xšz3§Ä«»¥ÄùÅîêý‡dúá›ê‡ÏNÈŽ»Ð]/bÝž¨I¾—WwðR|é¹ëÑ%G.%”ï¿œ€¾›Pzòr\鶫ÉN/‘}w¥ìkÖ쪓WcK/\‹.jG:ëÆÝð‚Ý!yŸÐç
+Òuɲ+åÿú·áq¯µÕo½A./÷–o[y¥;´ðÄ£ÈÒ#"Ëò»SØßn岿ÝÍ{hÿñR©Íûo<Ý»|Ktþˆu®¾Ú«íµ¾µá$¦+Í%F_}'16[)14^!Ñ7úV²Øx¹DßØB²LÓoMÔ‰QkÚþ{þÚ½k‰ŸŸÅÅÞ,*Ùv.½|ÏÉeųʫÎg–7_L.-¼S‘†°ƒOW[óöM¦í«;Å®OT!\TSx3³¶érjÕ¶ë‰å;n¨¸R8Ϧë<l?/Úv'¾üÒo§ºÂŠö? +Üÿ,¬˜þ÷£ŒÍ;?Ë,ÂJG®ÚÈJNÑ“ÌÔ/™./™"#ù}ôÐï ~!YúÅlÉÊ•¬d¥µN™¨ýÕ7¤dΨ)’É’IèªI’aÚã%#µ¾LÔÑ“L8G¢7f‰dæ#ÉüùË$2K_ÉÊŒ;ãÖŸéýzsG/#ù_AÄå^GæòO¾v/®–¶_N®¼x9¦øòµ˜â 7#‹N^)©¿XQq3µ*ýnN]âÝ‚ÚúË©•ûðœ&–V_M«,¾ž^±õíÉRÅ‹ßCÉwo¢ºŠ*;»C >ÉGk¨Fñïw‰æz-Öïü}Éú˜Ý£ÍÃ[FnŽ=8~cîU=ó?ëo8ò?2óc½_™W>˜³ÜÚM2Ko©dæÄ/%zãg¡w'&"*$Œ>#п&HÆJô´ÇIfÑ“,5±’|gW¤½<ôôÐ5§®íî]gùs¯·õï½á¶ïÏ°o_e3]“ØîשÜëg9nÏ÷V¦uäV×\N-k¾\ºëRR)Ò‹e­SÊ¿¿[úãõèâí×Ë>.=})®ôÇ‹qůÇ7ÝJ,/»“ZÝÓœÛûÊ·ðç§áõ¿¿ Èñ|ÑX¼åŸ½«/õÊV%ÿ8æ[.¼ŸÁW«$sçèI-ž'Yc淋!eÇxó¤Ö±kÜ"´gOדŒ” — ” èJtðÿºè½´Ñÿý$Zêë –¡è­£«ú£i㶡èÿiÃæKô YÉ×D¶Öêý½ ™wW’JÏæ”VÎ.+½YZq!³¬âjZYÕÅôòmSʶ_H.;x>±ìÌ…øÒ£âK¾ÿ!¡ä
++ºã*Ö¿êÝò­­»dÞ¤yHG£ç‡g€žJ ¿ÌÍô'í'ÑüÿóZømàJa’ýF¡ŸÃ%ýµ†£“LµH²Dæ(YÚ1Þú²{c‘ŽrâÞõäx<ÞUÕ~>¹ìâ…¸âÖËIeíWËŽ)>{%¦(ùN^•ý›…)·ò«A6_Š-9p5®´êZJ™ÇÓ¶2æ÷Ç9ô?»²b»ò«;žå÷Ä•Xü³×kuùS¤ßn’è ‡Þa ~þþè á÷aèÆ"‰~ƒßûýåmþü_?üv}ß»úæn0êoZ‹ ¿ó”,Ïz2nÍžÞ[>ôºÒ/Þ¤*ŸÝÍsx|ºÄíñÎòÐΪª°ÿÇÞ{†E•mûÞ“¨D%"¢( Q9CUµb2ˆDI’3JT$É&0Û†V»ÍYQÌÙn[ÛÔy‡î}κsLº÷ésïyÏÝçyîûÍåS«¨µæ˜#Ì5Çÿ÷ ©åÜ9œËb›„1l½¼± Æñè¹â¦³—òȸ/=q1¿ññõÜæW·²ëß]¯Ä¯é÷JàÄï„Xé/B†÷ ÁÃ1 áú}À9ªÿ~Eà­ß¯™Ùˆ©hòä
+²4wC¶ËbÐâ^uG‚õÃ79!o>¯¸ZP_s½¢)öùÎF¨‡÷4A^u%νËñÇ ÷›£_4À÷nä×ßÆ9û£ûé[‡sÝôÚŽ­aïŽ6àüBáœV;ÂÊbìÿçµ×Ä?Ÿë߃óÕøýgÃç­M®Œ.¾Bºøß(2{‡=ê°Òøý\uÈü3½
+‡jq|oh¾SÔþúÀŸAÁwÖôÿãóö†ä=küiLÕ~ÿ™.þ©þg¤6Ñ°B£ÔÌð8™`Ÿd‰cüDd¢5Òœ‚ 5l‘Îl4ÖÌ Í\•WŸ×r¾(ÌåÞ^ÌÅyKŽóo×6+¾¬
+úp¦&öéöìcOa_ÙÃøÈÉw`ßzézvó§iõûpÍ™þ¬¾Éÿ!£÷ëiË|”h¬†áÿelÐÿá+áë?âÌSì•àœÌGNEc ¢q¦ŽÈÂd 2ã€ÌŒ!SƒyÈtÄ\d¬7Ãçºó‘™>þ=3g4eA8rÚ­á6 ØŠ^ Ñ‘OTÇÝÝQ ¹ÙáÓ%Ûpì{q¹¨ïÙÅ’í_]+èy{­xÇ··
+¶¿¿“ß÷ö~n÷³;ÙÛs; îr¹-,¥ñÿÆ?þááü Oñ2ײFFšæø«Qx!òãø©n‰}ÉD4FÓ™Œ˜Ltì©þ4v¼šd‹s?<´€ëR[Ä÷¨/«zcäÿ£Æ¿9ŸÛz¶¢ñ³/ÊÚ®](h½u)¿õöå‚m·oæ¶^»”×zùr~ëákù±?={-· ¾ßt£¤Áõ¥à<s®óÿø\þð›à#t‰gñûç#‰ÑùýóÑx͵&£qxœ,MìÑx3{d1~%²œêŽ¬lÄÈÂFŠ,¦ˆ‘¹¥;3ÉŸÎ";ßZ´,ç¹Óa®âëÓ¹u§kIÞrySã‰Kù 87kj¹^Ü€óÌf¨=^Äù ÎÅnÜÈi|p9¯ñòÕÜF|Ž ~? ¡Kc6«Û,tıuô¿|^à'GÏ I>öÃsP—d#£Ðõ±ÈB×YÍE–cW¢©vJ4}I<šl‰1Èr¦YN¦ÑØi;Q„Ƙ»£qã¼ÈÏæJšÑòÜî_ ž°'‡Ëo÷Toû¢²ñæ—ÅmÎm»~±pŽñ­ç¯æ4|}3·åÃPvËûû™­dwÜ¿™» rRŸ_¥Í¢ÀÿјÁûEr´Q¿gÃ1æÞðÏ ðO™¶²Ô›Š,ôg"sã9Ø7Ï@fFvxþ-EÆË‘¹Érdj²’œÛxÛ`4ÞF&ÏC3|Ê‘}øa¥›_9l]® ‹¾¢¢ö—Cúå™âÖ{ Záqº7˜Ýør0·æÜWrz_ÞÍí~ù(«ëÊ`.®%Ê·º>VLåý?¶ÍásEdü ž«[ c \!áye‚眩ÆDü½‰Èá(ü0aƒÆèÏÆç¶
+¼ô£–z¯¥r8¯Ý8wλ³µEĈ‘·¿ = åÞ§<}ôG™¨øÀ¸U|ªšÍôÿ]ª“1¿>ÆçÃcÙDwdn+FÓ]Ö¢9T)šM•¡¹òZ´0f†CÍ}Ãåý‚Õª3x|î‹\îKÁÿ-«zh´8z—Æ\y%²W5ª-Û£µ"Ðpeùsç–ŸÆ»àüÄË÷/B°ä×)ÜW‹|ß¼WÕM+¿Æ§¶â-Wméÿ‰ù›o’å_þ¼š>ð[€¬ïÎÜÀ¿ÊÿÂú!„?úV©:q/Zqñyìw
+¸*:)ª4L5þû¸ë!0ÓŒGN¹þ4ÁZ‚&Í
+F6±hšG²“” Ù^ëÑœÑh–=¦ÏvG¶¶höb-¦ªÔ–$Ÿ±tÃU]—Þ›ìqWpõy(ú¿B¨ÉüjßVù×ʤ?ÿœ.ûá×Lßççµë¯³}º^ÏöÝ+Øû
+bÑM‘ !²Ç¸'²¹¯ï„¿ý¢9ìõÙ&ùw_U1>¤KnJÙ_×pß¼(.º»¥chpÖ⡚f×Γ&[/þìRª6œ{ày†ÏÓDo
+²´\Œ¦. D <ãUŒ–ÒÙhYl‡æÒºkF«. 3=~$báã:ù÷§ò©¿eþûOëd¿—!ùíizÀß…5¿"ωï/‚Òï'!œýþu±ÿk!Ø«úâx߸zÏÈm¿K‚ô–0ðÛqÞž±ÒãB óê}~Ì˽mQ¯¶&?éíŠùê`G€Ø±á1ZìÖÓóhöÔ[…¸÷ûEë;ô¦ÌXFê´ÿê0Äã6ÁÜM³“â<w#rˆ;§µ¤â+CÇnÁÛÞ¯Úï¯B¸ß¯B„Ï/‚Âå©àè|KXèþFp÷ÿ»°:ãA}ÃÀ­¼ú֡†ü{5õòg a ÅÛžÇYÁÁó¸`ïuKð=B$¯…µ²¿e)~¾WÃýøõFÿã‚S@PŒºóÂ%ÈÇÃA%ìc¤zŸ81uçæË3·WÄo5âóŽÙ0»ÿîËûDïúÁ“)Ú?Iš¹ËÜ7²zÄìbdi0åÿX úÛÔÀyαFÙ¢)‹xdÔ©¾¼æ¥ ø?·È| ÿ"ĉÿ"$|/Dø>ƾà@Ü(¿‚¿ø‘&û d~#ÄŠn \ÀiÁKÜðÒN\|ÈJÔóÆ^:ô÷æÝ·ùÒï„tÉK!Æoà·Åâò£Ö’mÑý?x1Ÿä¤-7çSµ§gSg3‡ïÊ]S(o]Í
+yt±Š?ùM×ùÑ­r`«/Ïe=eCžž­R¾¹U-ØùËèÿò¼t±_¥1i…Œ 'á:zš4ÓÍõÏ@±û56ÞÖ_¾ÿß&¸Þ–áù$ò:+¬ð*9mî×£ë—ÄÜïœàÁ>½óõÞvÕÇ‹›ÙOŠdïÞn¸$ˆD梄՚¢uëµEy%†~MÇlü®
+>üë'%Ü“çÙâ²C¼%rš®)Þó•Ôž_½e‰5†²ÐL-¶îáþð7rŹ§qÜ™—aÜÕg±Šƒ©»?¬”íùÙÚõÊ•Þñ;òëPú¡¾§'·u»õ&M_Iêì?Æ8fÌž+CK¹
+5çœ3£ÜîN¾ß ªÀ„$¿÷Bö×
+1Ž»ô?Ò?,òþÁ{C¿Ñ'O´xé|˜¬xä­—üɵ¼µÏwõ¤?mí
+{¬‰þîChHà}v~7Ç·ü¼•ÿç‚“èœÐój¸îÔ4ñç¿zÑ_|ÅRŸ½ ”ü›7•Úb" JÒð ”!J«At’@?¿ÛŠi¼ŒÝós€êü“TÕ¥û©ÒîËd õÓÛŒý’õ—û'¡Iö$FkõtµßíR ÖÀqmìB4ÝA†–¨ªÔœšÞŒs>-Ìv}$¬ôù« ’ýúuýÛË"îo*B>œ©‡{ÜûçÅ̃w©ô•Ÿ#¨sS°W?Æ+<)R>ËãŽ}PP:Í|}‘·ãRÄJYûß%íƒöâ“ÿî)n¿6W’Va}в– ¨Ýï=˜Ã爐–{‹d¹mc¹’® ŠŠÞi\ëàò ]Õå›ÁƒWKT§ÄóG¿Rð/$Ô®oܨ֛‹¤•û&û&7êÃý6SM²vðçÆÒlô 4a¦+ší›ˆ–'îáö™0Ëû[ÁõåjX£óù p~¯^|_ö?ðG¿ˆ-o¿`äå*E’`ÄQÁê¡1™úaÝÓøæ›+¸ªãv~ä0irœb‰–ÃcÆ8äáâ€¨Ö öòs×0§^qÒæ‹óéäÊQdÿùÀ;?²':&G‡ K×-Y¾ë•;ßýÚƒÝzfÓóÚU±ï)ÇÞ}½^~õiµóonÔÖsvÒÃ?ùЗ>F0Þ¦ˆ¾Â=†çU›n/êÓX²z·æòÕ»µœcFx¤å^pÒÄk÷OvÌÇ…°'ïÞÖmÔÛŸ²ü«Ä-¯ç‰û~\":"¸öÿº20µÍhùr'4×zZ`i‰d^ž(4~­n䆜1áÙeã O,ððîÌ•—ÑŠ¡¡léç‘HÿÅGºï¯î²ª#ÓdÙ•ÆTíÎiôÁ'"²Góô·as—VžFoè+ ËÑ–†¥hÉ¢“´HßËî×¢à“·×]x˜JþÀJšnÌ“T˜*êý¸8 ãÝ<Ÿücf.Š<õyN*4 Çæq³V¡ÉÎ!È>t«šóæûæ‡;ÏóÂJÏ øqûýžo§yí7ñLnÔ (Øa¸¥R`U•¸þÀQï{Qÿ·ŽÒš33¨Ìž±tJ‹ —Ñ9–ÉÙcÅdîÏÄWx¹z#÷å+‘ÄÇ+‰)”!ê2Uˆ:SØf)m¹4_ÚzqtÛE{ºåó…²mçQ;ߺ²G^rô—_ñd_å¦öIlA—ÝÿÁSyêÞš Á¡‚°Ûç«‚n^ÏS^¸·^ºç£;ôUPYõ¦¢”z>E»Æxl:c±2¬Tcö2
+1°F&#q=€ëPÛy"äœwi´ûSÁÍç[¥ü®~ÿ×<Éy Ü+8‹sÛLWãk™Rb Ûzj&]Üm…ý€&_¢š‚þNîÈc‘
+XåŽx6†ô
+í¸ÂÝ6Áéucy‘yáŸb¿Áµ§ZQ5Çl™ŠCÓÙ‡§Ëûžù„íº«äš¹¬Íc ƒ©Ú?î}å´ß_Nמš#Ûù«rà+Fñí½*ÕÓ[•ûþÍYVØm)m\HúÈ=½^üáJ÷Ëã
+é¯B†ä¯B
+ŽgñÞ¯Êû¨°Ä;m`´“(y*V«ù·?žÍ>y³¿õ*•9ù3'Kn6r[åÄ’Dz4Ê¿°¥*OÚúH•hÉÔYhåÌ…(ÀÅ+Â4ÂSr#“sMB×æVeÖŒ¥;//ƒ}¾ü‰GÁÔ±¯$ÔÀž’ݯWÊÊz­¨Êfÿ+ì«•íýÙCÒòr¡¬í;zï¿ùIš‡æÓ:Í©ø,&³~Œ´çñ2fï?jàƒ‡¤sh‘dëù¢Þ7‹ÅÇñaÁ-`à×¥~{ÿm±ßÁÞã¢àèù^ðù‹ ðü(øû<üü® ¾gßÀë':#øúm>eퟧ–¨š áã퉖Μˆ\(
+õÙôæ1²î˨®ç+˜ÒÖL^›“ßd!þPyævlèÍÓ¥ôéo²²ƒ“¥™[Œé’#S'Ÿ‡+ïÜ.„}ªk×2™ƒï¥ÒîgK™Ò½“™õuƲª/mÅ— õñÇÈ‹¼O Ë=²O¹'îÖõL=:Ê#y·¾÷a‘ä;! öòIîaù»Ì¼|ƒ»“?>'wäºtrYº É3uØ=/øÇbºï©“lmž®XªBГ.¡y¤JÈ6€^4vÇCï }פ·¨Ç40dÛŸ®‚9GUí™J'o2¤2635GgBÿ‰²çq
+P¦iHRG»ûÊÑ
+Wäë¥DžNÞÈi¶=ò\á6Ì¢áÔ=<órä퀤"ÉUa!I™†Á…=SBŠûg@o²pëxèqäú_ú…º³Z~øk…´ÿWYN³]¼c‚¬ï;'YÃõùTj³‰4¡J_¶ã7'å…gÉì¡· éuÙ°Íú™©M{'S…ÛÆÑÝãeå‡lÄÝíŇ~u ÜóÓªÀ¶Áy¢íôÿ´4à(Îe¯
+¢À¡(¯þƒõ;ò÷e¢’¢¼&ñöŸ—ÒÇÞÓ­/Š³ZLd¶‘¥Ö‰ù5§ÅK‘ÃT[´bÞbä‡ç;zÙ@KO™ZnZìTÝé¹ôÀkoùg÷åü‘<wèÃï"ev¿ó¦êŽÛ1ùí–\FÝ.§Û’ÉjÇþ¶Ý‚ÚØ7æ¡dÏ{Wêâ«`ùåû Ôñ$’=?»Jw}·JÚÿ£ sü[†»úb-áE¬tÏ/.²ä
+Cf}‰!•¿}¼¤ã‘sú[•òÙݲèoŽoã¾yX >#ˆ¾ÜšÞÍöÏ=fî|˜µêi£
+žÒêSÓkÕ%a™Z²à4M1½FÝÙÑÏ¿¹hÎG蔊Ѳ]ß8ü à‚Ô@3t‹ÙÐDMUJ•©¢æ‹…|ïÝ3è$ë½»’ÝþÜ 4 Tî*¥o\é²ÝÖLnóX¶¸o"ôzA<·i» èó„]>ÿ¸¿}í“¡×/Êw¾ `«¾œÍl:=ƒÚñÁ™9ñŠ—ö¼X.Û÷ƒ'uè?]}h:]kJ嵎•dwŽ—œ(Úzmº(}§‰·*M݃ŠWóUdjˆèu?q¸š,¥ÉX²®ÖÐyU
+ÛªüØËPÅ¡çJzÇ÷îp©º s™Â^+:c‹ »q`
+hRÇߊŽýÅ=ðÐOî‡q øq¥´òÀdIñ>+iVûYB©Œ‹/ðÇÄr½ùØÖÍèòcÓ¨õ•†`÷TéÁÉÐW*]½AÛça>"%’ÉS5˜üÞñtÛ#G¶ý™èfƒžÑ:ô”–í}ï½]LûÐ2jÇgj×3W觱Oaò;dzi[Lè´#zCƒ©¬ÇùÝœ¤÷–îyï$;ò^L{­b¾|­¤Ï¾ æ.|E{/•øÕƒ>õ^.ÙûW*®DÏŸ Q¯Õ€þ-z÷ÞÊS×ݾR º1˜Ãœy«ýwéçB€¨úÊOišm>Í2˜ˆ?ŽG~,’DoЖ®Ù ¶V“ŠHÓ–ªÖk:¹¸£•Ø®\ìHxlTr¥!“˜§' ‰T‡XÁ'¤ê*RÊŒ 3*:C‡ KÐäãRu@+ï,V|¬`}H•¶§Ó«¥}™¯=A×I«2â³·˜3}]•'¯E†]=U}÷³ºàÓƒÉÌŽ÷žÐƒÆ˜Ì4Üw`ªÌ`Ëz¬é­gç15gà<a†¤ÿG'IÓõ¹™Æ’‚ãÄUgl¤É­F®î¸^°_†–/vEÎŽ^È_®}–’ØRûivÈF×M10A³GG+pþùUP~×$ù–Ãs¡'O¹é¸×zgEPéÀ >8AS"ã«ŠÑ$Z„ÀÂH.-/¬³ä/dº¯¬”u-ù´Œ¿´íŽ½ôÐÞÜÁoiéŽç+€£À$UŒî½õÔjÛÃeTçÃeìö·^d®×´e6nŸD5.b÷¿d>{!ƒ±eν
+a/¾ˆ O¼fpLt¤Šv[Ic‹tDtŒº§ƒ<œDH:÷Ñù#é¤-£éì¾q EGæŽ1ÑØwÄ«Óëꌰ-L`Šð£æâè[aú?ø²å‡¦S±¹:TR±>“߃ãùAœ6™1 Ã>²æè,ªóÖ2¦û™ ³÷•/»ïk½û;ÑÛ>ð:€ùìú4dÝO—ËêOÛIÞ;AÔ²°ç›ùò½Jºýã
+Iý;IïOËàýÓé%£d Ù:Låáé²]œ©]@7“ª:8*ÿlª¬áÚ<IïGñÞ_VIS[=BÐÂéóédä0e.Z6orssCÞ~ÈÍ Ç6œûrÈ'€A^"äå#Fâ° Yz1h‚mÐZ­?–S§$Ø÷Pê„×|~1×óÔî}æ šÝTb¾S¹{
+»çi€rÿl—-ßeÃ嵎M,~ï™üØC%ô¹‚Ùÿ­ˆÚõ;µûGOè £Ûî-…kÈÔZЕ;l¤Û®Ù3Þò§^†K÷ÿÍSR}ÖVV=8[ÜóÖ!°ç£´tïDqx¶–˜_«î# W‡¦iR‰[ %k²´—Îw@s'LC˹ ÏU~ØoJ0"A^±q­²óš‡¼åÖJà®èJd*(báaæÕY@¯?è¾ðÛ§A)Ž˜œs¦¨ÃJÖùt½ï£/5ð]û…»¡ÍœÁЋgS«ŒIO^Në8’ßÔ_žOt+ΠOÏ£ëNÍaJ&Ñå¦Hw¼ZIú6€9ôFLmÿÑ•ÚxØô2$ª$ ³Z]œ¡IÅ”ë·Çþ9±H4õ¤ÁZ ³úôê‚‘lN—%[~Ô–j~°ì 4q^1IªE¯-7¤ãòt©Ø¬‘ Éï·‘m{¼”ô ×~n'뺹z+qü R»Î}¬TJàÏ?\Mú6PÖrc!‹c¿lóç3 7úטó_…I~r–ætšK“ëFË
+ûÆKwýì$íïù¶Méî]@ L•¤k"E¸:Ñii\(é~à@çöŽ N×tYî‹–Ï^ŠÜ–ya»” 
+°6èÌ­¦lf“9ÄI6¯Å‚hêlÀõ`ÎÅ‹vLds[,ˆ–dFý:!S‡N(Ò#z;ŸÛ’)[Œ¨¨¬ 5Ï>|Ш’®ÎÔ†>iÐÛã*ŽÍ૾˜C'éRájÒ öLÅêq¹–0_¤ß¹J÷¿÷¤v¾q¡v}p—u?[Ám<0 ´ÝA§€é{é
+k =D· kXSý¯<¹]/üÙCÏeì‰Jæóçœtç{gfóç³@w↬åòBêà;jÿ÷Þ²Æë ¨œ XW“¥7™ÐUØgö<[9Õ~o)ôƒž?hGJx®…ÆiP¶˜ÀÚ€¬÷å
+ºáêB*ªh¤'ë äçË#.¹b4·±o2hSrE}ñµ4ãÒêMáKc³GJƒÖkJÂâ5€ÙA·9«4äUý3¹Ú/€¶è}ëüÞ‰ =J´´q¬¶]Z(í}²ÏGG¦éÄ|¶õâºcp¿ýž²ÿ”ë»åÉl¿ãÎìþÖ‹>ðM
+¿t4h¢Ó{ÞùHw¾um3ªå¡Œ/hѳ€‰ÅuåÚ2C&¿Ë’)Äq×,öLVƒ—±Ù”Éj4£òq}”²ÙˆIÙb̬¯5âã õéµ%4ŽÁÀÅná€*âÕÙô­¦ÐßJõ½w¦ú^:ŽWØ5°ŠjpÓzÍøbÀÇ./°™@cˆM).̾¯üøãOŠÃ”ܾR¨@3ÖNˆ†På^[¶¬Ë´žè†s @{Ø 4®“èÞÔÀGOiÏóe0g@ÃŒþLRž>WØny µã[²ß¸»¸–š @lùÎÉ`£ ¡AÅçèH”àÔAó]¶&U[“;’.˜€ç¶·ñðô
+<ÖÜ‘§ŒâÒ£DåË›C^^¨…^9Ð*Q¸ÇB_>ðd _Ì‘áD¶í†ƒ´÷Û²ª/§KÖ”Œtu£å³– o\€¦‰›k‹õý€G¬LP‡&kúŠÂ°ß ClXº6hO…·ž÷ j»àF´ÓbŠô@+
+¸% ¡Ï¦×šÒkRF@ÜV~v[zäF ·õÄ<Ð¥M%ªõÜBæÐ søG©xÇŽLÉ!аgªpNY÷Å<6¥Ö$P¡¹[ºÏâ,ÔÕÒÐxMÐö§Öm4
+ÚÿtX²–”ŽR§C×iñé5¦LåþéàA·‰n¼¾H¹ï¯ÜóŒá«?›M´ ‹Û'Ò{^ùò'^ѧþÂ<èG¦’¸|²ÌÖ±Ôêd-?±wúê'‰ÊÔöô– ð‹„S†ó
+Ö9ëÍå{‡<;ï‹å]÷<؆S À.yü€{æÏ™– KØ®›ÎPÊw½ zŸ¬â²Ûðuª3¦Œ¬ãñRj÷ 9!í|¶”ÞØ?‰Ïm·„÷æíæ狘˜=jM¾N <^ŠLצbáZ¤jy‹8\ó¸"‡i‹ÐR»ÅÈÝt9CÕÄ!±têVcfÓ¾)LJµèă–*᧖+²kÝg<sQ€îá³>ö¯°bh qÝw]A‹™ø¦¤l}Yç-G¢ÿsúmsâ{9ÕþÒ˜cLb¥!ž꾸öò¤Ø Ý÷ÜUVvøIOOòò!à]‘1H­1îá8“Y¢zÇ”IùPuÐò&Ñ Yú\bš²^‹hÊcȵ_Z®ì8çÂoù|.Ø5™¬ú`lóÕ¥lçõU ûÅåÔ˜‘\«åÒºûÆrà0(ó·Z*Š»&@Yyh6hÒm—–*vߓл¾ñdÖ•ÊBc5 ç¼tÛdùæþYÀdw½õaúßú’Xß÷Ô™h1•î™ÂF—ê²1¹ºž< +ÍUŸ´£Û/ç·:€VpÔ`Ì`- ´‰Ø_{æ)ö7lvÇ86·Û’äë5_Îá¶=wâ»_z*»Ÿú)»ú1]·W Qž^mÊõL-CÐуý  oÌä÷Y‘œ£âØL¶ñúb¾ók7¾÷¥²÷ž(¸ïŽD¾ý®/è'â¹<G^Ø6A™W;N¾õè¶ûº ß1èŠmÓäd8·aJwL±nÑÓ‹/7&&Ýùx»ë½/×ÿÖÖ-`ô ™Òž‰$î'a?½qÏTXŸar&Èâ7êÑ)uÆTb•µ:C[ƨ9¯pCË—­BpO(€ŠR–;h1]Oœ@Ç—\#\׊%,¢#â´€Q¡ØzÆ0ÐÖW6-žçp-}C~lÓ•%|^Ó8Б璋 ÉzgÑ6œwåÊ2tñçˆ^ßÁw"æÈ[Z²çW&s‹)h2Šäkplæ2ë«FƒN:»ñÐtð ÀN]z.2^+(§q¼*¯ÓZ•×d5
+~<HÍ×Ïɸ`5Ðc„¸ z[ Å zÃtÄZ-¢?¹±ª¼ùü2®õúrಂæ(aÀƒö+ιònÐÒ”vœ[Ä|B)vÝó Å­ŠÑ L<.Áý7YyßìW™¾‡nÜÞbvó±YtJ‘hø³ÉE†À:†lB®äæ°öÀm·Ígˆ' 3ÆLb7ôŽ“EnÐÆŽ£A—îùÖ™mº¿Û5Ô~|f§%Ñ®ë{è*ëºã5/0³`]Œ¬Ã•ìš6¯ìxàZolÏ3¶ýöJ`ð«³F×X3L×­U²¾+@'ÖDˆÿ…ë\¶Ç†éx¶RÙõÈ›éùÚ ?ßtTªÍ¹°uZ0ïaÍI±åè|¦gÈY±ë®8h×=FÞyÇn»±˜­ÜÖÃv uÇïµ!Ü«²ÏfÈû¾ñåû¿3Û¿w§z^®äJN%ëÇeý6Dßnà…Huôv„â³'Aô– sÈ}Œ¤ÚÑTâF}¨uq Üu·Z t¹õ &<~}¢# Ìlw6JÝÏKJôŽ­ú…ʪ£óT%;¦që+䉣åY­lÇýUŠî»^ìÖ+öŠÌ-æD â+è]¯+0Æ÷;;‹jÆyÙ—bÅñ‡áDS­ ËêväQ´bö‡q\"hŠ¶™Ãù*s:'(Ó¶šƒª*§Ù
+ô`!Ö掷 ‹OXx¥F|ÝŶûAíw}ä­ƒN„彶ÔP•Ù8NYqt0¾‚’±‘¦C8Øø})Ó‡µ¸Ù-ý3¸ýÄòsCѪ3×@‹ÛÛÙøÑÃZܽƒÊ·å;îûS=W—-n¨)»Ÿ®Â5ôЄzD±.ß
+ŹÎ {×4Ž7 M¯,î±ô™M‡§ÑqúÒ°T-¨{€_"/˜$Ïß3‰0.ËöL‡\4‹H±ùðL¸†`[R.^¸|`ÿŠm÷ÜUO¼åÇfCþ+ã"Ôé5â0¯€Õ€ã2³õ(©{øäÍÆ q‰¯·6p øzm{â«(?9tÔáÄ1ŠVgCÖj)’‹F ΦS‹”÷½ƒº‡@stžwDõaÖxÝžp²;-A;˜îx±‚Þze>SzdSs×T‡lÙŠÃ3¨”'#ÃNŸNQž\-ÙûÑ•®==‡Ù|i.»¡ƒøX`ÎÁ}:¶ Ó
+Öõ€
+úÜÀ€H- ną̀ºøc…°K ·°hç” ”ª1Áñ¹†ÀT‘oêò‡·¼|ç4ªÿ…§êĵ¨àëçr¸#/°71æ4µŒ.Ñâ®Ø?ð°ÁlæÉ<íx$åz¾vgqŒ&ì,³ g(«u°³dÊpÂÎRü‰%øÎêC¸¿àG‘\i˜UBX„m“œk
+†'º´}@ÿlïv–¢ý‘ßõÌØ1žã6N]†m Xóð°6ÔŒ|Z^Ø=Þ•«ÃEd
+‰EÀ3Iœ.¸ï¼0ˆCŠ¸4ÝßÙYcEôJÿ`gEdTewMמ¶WLSàxFtø×ènWfÛ8ÂP̬0Ž¥2¿Á
+´ô•YØâq•Géû®=³žãá¨áçç??»Ç
+4«Á¾Ùl«ieFÊM}Ó‚:}B¶Ý uSïÝêÎÓèÎïy*ù?uç¹€î¼êì½x!‡˜ MEö¶ñòü¾‰²¨4mX“­Ù0‚[_c 1¸YT¨šˆV“G­h ¿õÖÈsùÌîqÿ€íG‡oЖ2Áj‰a;Ñ$ÖuÅ£‹=µÄH‘×b¥L­æµÁœßtx&ÓûÄ ¸D°¾(Åy°e€s.ò•!?w/ÂÎ’r
+5óOvÖ$X#‚˜(
+P¡
+ZÜ\J1ƒ_øf\Ç]gÈIa P§«ˆÍÕƒ}#„UÜ; Ö[û7·×ŠY¿i– IXN8f’ù;«ë® ß{Ï ÖRþ`gA¼•¯ßböÌgV™¯ ØYÀK†Úì?ØY…Ãì,®÷ƒc5!¾¨RjÆðá)Ú0wAÃ_±®Úr ð¹Ê– „g¶¡ÁB•½ÅûÀ±;ø°Œ„½…Ÿ”ºÙ žzë~>ÔñŠ’®É ¹M˜}k4œ_ªì<ïT¶g¦<«Ú tŸ÷LX°Lcv¼óàw}+Y`Ç<ÇNX`Z¿°—oÚ1m˜»ž¤ ¬DàÀz Üóò§x$â#Ôý¥r$æ"Õ v„õì
+GŦëG
+0¡FÖÎkÖ>´’k¿¾ø®ò´z3U^50*øî[îçÃ}È©@››ð 7uLfº‡œ!¶FBÎ;ò·çÒð9—£÷6η]T9 ã•1yzÁéõAY¸®¯Øe«Üu[¦Ús_.ßù\LƒvrÛÂÎ"üö=Ó¨¶‹„ŶÞt$쬜V`giøÂ\T$¨sy;¬@«›°©7í&ì,%ð“U8ÌÎRþ™•ð;+e­A±¸¶Tà¼r^`Ççm³}oào@N,0ejžŸõ–ÀV ÏÇu…Ÿ¼Fƒ¢ÃÕ€K9áþÀó«ŽÎ"`jà¼dXçxç¾–ò¸<=Â'‹^?˜ßò¬ ºñâBv൯¬ëÉ2àRÁQ°¿œÆ¨ÕH·~$¦áç-G×äÙ#àwÄ’ªBÕù Õ¦°Žñê7x]XÃ
+ÄA¶íÚr¾kÈ鸶’n=·ðd- öçZ¦Ë΋«ûbhÉþGEù‘ÙÀ%Uì¸À7|±((µÄ„ ‹ÕT­ÉÔÅõÚx®åúrÈÁ8\Ëó%‡ÙY agÝ_Éoå+ï{¡> ,ŒÄ|}:2g„$*M‹Š.ù; Ö—€9@øJ»§*ª÷Û)
+¶X’ø^ÐfÍmÙ;K^÷¥½²üÐl`WÊsôa¯ÌqX7QæwZ³Ç ó9¾´'ܘÒvkø]ˆràqU§Ütp¦"w‹øb9<?4Zø[À¹çZO9°œ`}Üs–`~-ö½ cɵ¦„á[@X÷ª‚k¾¼Çî_0P»xDÁ5eK{¬Ù˜L)¡.
+W‡ØIò_ÐôϨ6õõ`Q $T Û ­Œ+3„úV™¹e,0OÀ's›ÎRô>ð':Èp¯buöHðù\R™!ÄBJ™ !–†ª‰aÏŽ=KASætL 1Ç5ÂÙ…5O\·Áþ4X/æ—ì²a¶œ
+îéØ0 Ùºp_Š©ûr>Ýr}1°³”ÙöNÀÎb7ï›=\ÉîÉ\nÏxвfÈšó鄬XϪÄöYÖ‹Ï Ÿ/°³Š†ÙY|ãç‹ØÖóK FõVó•¹­V$×Ä~˜-3ͧìùZ|ÞeÝ“ø’žI„5_²kª¢þä"®ùܵ…{.É¥Fª\\
+õ»,2C[†s|6­Í Xiò²ßYœ¸îÃóx"÷;«¸s°8˜S-§ c]Q´Ãføu{&€=Z8ÔU»§sµ‡íØÖ³ØÆ–rõgHÎBÖ¬ªúgÀk6\)¶{ü÷  ¾ ¸SxŽ²Õ¸–ï¹»J¾ÿ.MïÿÚ—êt„=vpÏ]Qy|Ù7™ž7ŠßOrüêšÈc'Ã\‰Tí
+dún»àzÈÞ3ø"EN‡K|øÚoì
+{ݸ¨Ü‘òÒýÓHÍÜzÖQžQg&U­QgpNMÖ}ÖÀÝb±ý€ËØhu™,ç†R$•¨™1òc8/¦ùò"X—Àõä)¥T#,Oü·ä{m€oû—“¨êäºéÆ"`Ž
+Û&ÀÚ5ß{ßûï9\R¾©Ã†&iÉS·Ž}=ìÞ—ÊäòDlëÐ2Âì5Â>:í¸±‚k¿±R±q÷tÂ4æ-ÎùHÎZu`ì/ Ïo¶Ûxj!½ã©+ÕzeÜß…ûͤ×1¶XĤÊ}3ÁÏC.%O/6"yJvã8eQ‡5¹'„ý;ÝzvÕxb.\à¬C=/•Ç©¿‚0Up\!>¯´ö°L'Ü 8oœ?’ç=[½Ï–Åù9®[B>!á°Ây(•5Þ7ì=cw>ó ëÖÛn/gÎ-„¹
+Éø²]S¨°t-™rÔÀ­‚œ˜plægÌyœò°ßª|÷TEAƒ%¹WÖpl>Ûy}%×pÎîÓ3aÙÚ"nµDzâíÖTÛx}r¿&ÛC^‡%Ì1®¤ÏšÞ²Ï–ê¼æHµ^ZL5_°‡^T66Kø˜l\ºŽ|ãö©„{H
+vOæ×àW §Ho2V¡XÚ8媶cºØ$®¹ôáÞøàMÉ3ôØue†òÔ*¾°û¨Žñd×L¤ÞÀσk|i‘¯J)y4Ô&PïÂu‡< î·rØf¹ø bÛÀ˜Æ×L^Ø9öòðñYº
+ˆçõ'A¾<-¨aÏ–¢¤ÏönÀ¼‚÷÷‹åiÍfP;ƒÿ†<’pÓ×W“=GÀ‚OÛlŠã˜)‰óÀ{Å>…˨7¦3á Ã~Åœ6ÂìV@îœ[X£ÝPnBXMÄ>Ÿp^aÍç¡0ǹ-LJý°O±#œ+`ÅÂ:;žcòT|í
+±áúò"°A\-dê¿œã9!Óöåb¾¿>OÂ~(ð‡aÖÉÓʌȽRœŸM¾ý¡?ôÑ1i8߆½´¥øºm˜,:Â+ƒût™¦P'»æ6¹à6™EöWìû]› BØ/ó‹äøÚ‚¿RæuL q©êa‚ãsæ6uM&vZ¾Ó†Þ|r]u|›Vo
+ù97Ø÷Ò~ÃæalE%j'\ÒÿÕJÙg_pý_ûs»žûÒ5û¦3Q©ÚÐù»©ÀéÁq`™ÀL(3$ï›Ìëcs…OǧãÓñéøt|:>ŸŽOǧãÓñéøt|:>ŸŽOǧãÓñéøt|:>ŸŽOǧãÓñéøt|:>ŸŽOǧãÓñéøt|:>ŸŽÿŸ©SÝãÃÝB’C X/ƒ©ÎÞ‹‚ð×’uÉISƒæ:'%»E‡%G'ć$¥[;·X?ÊÛÍÚÑÚÖ/$=")h^}Ð ëeÖ¶ÎÞóçá'àŸÎ°žuÞœöÖs%!±Ö¶Ã/jl-JŠŽŠŽÇß”†…ÄF ÿê2ü0 à-,·à’´~ÝjqH2~Jüð7]"ðsþÓ·m©øø¸ˆpkò]kümëE3 æY;ã›
+ŸD¬Çæ[Ï#ÿØtü…þd þVªõüyÖþÖrå<ëpø}‰Ý’yóç[/™ç0ß:ÎÀÎa©Ã¼9‹— í÷篒~ÿüýÿýkòûñÿñçñ‡µÃ—Ö#:6ÂqøSr6¿_gÛøý°žsÝ"R¢Ã"\ý9_k6À@nmG®yóðÉŸÞâ%sÎsp°VZÏÇ_/^
+Z¿Áj }ï4Ž¤A)šŒ2Q“‰LÓV¬ÉÓSÆåêË×—ŽÊ©››(Ϭ5ƒýë2|¾ø=¨ËÓ¶˜*²·Y*ó»­AA™Ze
+zD+½Ü쇋MÕ¡£SµÚÆáëk)‹œæñŠ†³Kåµ'í•9Õð;¶.>MzˆÖIaé»Ö8h›6”±ÕBµ6Ë@™”¦§L«0 ¢ñ°®À4(˜uZ gº2tP´¯Et&cruÙ¤}èÏTe7‡¾a>¹ÐP™­C4‡ò-¡‡K‘VmÊÇfë2«×iƒÎéíÁ¶OGÅk²kµ@CBž†m#¥Ôzð•åûfÉ«ÏQ¦6šñq9zlB¶.Ø9ô‚¾ô–¾¿ôz3Ò7[¤¶©ÈëžHt´/.á[—C_$—3¬=Á¬-Ô—*ñX`{ ½ÌÉØž¡Ÿ·¤w2h3>\|–.é]É(6VæwLäÖ—æÖ¤Ž$½)ÐG‹Çô÷EÆjqY]–\\¡ž˜P÷pòÁ>ÒI<ß”)š>QCÆÇà±LÖ¤ðC¯Q÷àQ€/;ÌÄQÅk šˆT<çÃÔÄ”
+~+¼?ÐeÃsF@?Wªš~ð:b*\-‰R#ºÌø šK©3á¢
+t¤Ê$ ø s=Íò˜|=Й ã³zÿ†{µA¿øIlLúHùšb=™"QCªÀ~4(AS¾¦@O‘¶eŒ2©ÒX—¥§ˆI×ÞVUFµ½ÚÐ7Ëem&½g Á½÷x|t kÑûI«4U$—C/#ÑæK©CÆ)«a,_}b.ôNBo7ô¶ÊÓñuM ì{¡ÿDYºÇV¹ùøå¦=3Dbû4eôØçéˆýçp0öÉØgBï ØésÅcÅÆdŒ„>v°ej‘ôÂ’~fèU)Ü>z…H¿ëúR#boØ/+S*MÉeFò¤<ðsðZDg Æ<³šô¢’¾ñM;¦*‹û§Â\S”lŸšYÃý‚»lH¿YqÏDEnûxÐîQì´! tÖæêóymã¡wôO—öN–C ô™äÔ[ðjÇ=aÐÍÑ%¢]Ün½o|v­¹|}Á(˜ß  ~´Äà½Ò*<–`Ðÿƒ}Ø'è]°QqZÐ;:`W>"äã'A  %c±-zÑÈßO…d<~>öItX’–L©þ‡èD¥
+ñ{®ÅÂù%ëËSªL@¿tz@CCž\m :ÞnžˆRĪˡ'*_—
+^« zDWÇ^¢+}!øEL†.h.È“ŠFoíRvM–ô8*ʺl ü؃í'é£Êm±èÏå¢2G=²Ô-¤gPU²sé½Æã¦Èl²Î :'*Jû¦àüÀ
+4Šû¦**Íߤظ×|‘2u£1hk±‘‰Z¤ ÏÈ-øèu# ×U±¡bŒ|]…Ÿ^;tEˆ®h#@<Ìj€>¶iÐ ©,Ķ}¶Ð§ˆçÑ’#ºmø½€=dÔ™FœÌ%ès•WžMzxëÎ.„þ.èGƒ¾)ÈgˆöNî6+xmÐ#‡Vv-ôæéËs±ÝAÿØâÆíS@ëYYº{ª2«Ó
+ú÷ñß2‡¹=S|b‰!èÑ“zÐò]WbHbzzƒ9Ì&_û„ ºÐûG|*öµ A…$âñ[Mt†Áב÷ ãŸ}çp=@O]ʪԀÙÀF㸰&Gôj™ dM.4Ctš@cÆ~‘RD«Cþ½ ³ºN a z
+𠹎
+Ûob©>ÑÈn˦–A/5…s*"M‹‰/Ó-+nÓ¡éòÒöDG.,Y‹Ã¾”ôšâ9yh:‚ý®o6ƒ~x 誱êD«
+bØ¢ŠHw#ö÷9gþÇ;pŸ{¾{ïÿ~çþ~üæÖbËœs¼ã}Ÿçc>ûì±áumhºÀó•€- ï -]'ÀóŠ8΢˜½0k0ÂkçÝ&ÇFÓf(÷.<£ïŠæÊÇøÙ}Ð ;í>4õ(”ÿh‹s£àÞÀ¹ÝÓ)ÒS¨^ ú*]=‹Kc†ž)Eçøtž[ˆ@nÄó ½¹
+£`¼ÎúN†{)‚œ‡õË/O„yÄ^úYc÷Ãó¦3 µzN(NÿzÎÎ? 0$‹ê?Æ ×|¨ý—|§Ï­¬Gü`5èlãg`QŒŠ­Cp®ÄÇEÿ©¬ÿ4ðÈ€<
+*Ø;ÀïÎ2ðF`\“æb½³ñõñš„ë³Çµ… Wù
+øˆ‡¯hÀ3g.O
+W¡L†A/ p!œm ¼ý„=‚xÈq9ÐËß Ü'
+Ÿs-ªYày‚±Ä=ÊÙCú~™‹ÙÜuB¬íì1 k @>
+{¹™Éè<Àf·QWZ°Î(ÖŠ±ôšøëÒžs›
+´þ裣IÄ«§1äFB³aX§½¹9Šb÷°ÝHТ¾Úñ¤è¬<hý& en3æ¡ÀäÜp<ÇPŽ…¾%äNÄ÷†ãú‡ë¼Çðàƒ>
+ù´‡_%>ƒð
+Z1 ©‹ùº×TоÅÞ¾×—cþë?Oì–0p,ô ŶA
+›°!F‡ÐY/{§-¢’Ê÷`/¥‹~S Ÿ‰õ$¼bˆ|¯.£#ßn¡Ò[Õ¨Œû°_dì»ílÈË ‘(´ðµ<sÈcö£Àçð*ýnZ°™µ™ ø>f7tÌ阒TJã^¬Ñ
+ž]ŽIs‡Ä!Œàóp%#+ÝÁ&Ô©“jÔ„ 媠2¤ˆêŠKÜ\à¥X 40¡.§Š{ºÆÇèùå¬bƒž®e¢Š¶jë èe@\èé†ø:Š+˜SØ×ñ~¬IüâhÀ"àœˆ?–ž›(î¡ÏýÖÒ{¢ñÐ9‡¾à^ò ÊŸf¶#ÓFh±Vá[ -&C^¼=aЇ˜]xá™ÀÉà¥ÎgÌäØcŽc„g}&‹9Ž†Ø½HÀ¡’sž¸WÚÏÐÛÅýNû°™bßÛCú ÀO" wÁ}2`=¬…rÞmÖöHü…Œ/ÚFÞø¨MÝÔ\íS¡íCg@üŠ-ä / ߀ãà^aMx˜ç(O`|ºS.‘sqOzH>×Wà~îÿDÍQèË€v³z}VÐKAxñuÐ5‚Þ¸Ä
+ÕTÀ¶²™CúE¿¢<‰9”7èÞZþ=€÷±fðõÓNãD é~eÖ;ÃG© AÿôØA™± ™ÎZ#þrÑg
+ôW™‹ž“AWûåøÝ[þȘ?~uðõàá'´M™ XÆ ê럻ŠNþ ÂDUngÜ2~º(´‹ŸÅD<ZO¦Ô+ƒ땾€¹4•:ŽjžÂ9žiJ0DqªtBÍn*©fY¸ ë·œ‚øðœ r
+™) ½³ü3@§ë±èò‡ |¶î·@V²YÒ´ k”Y8Ž¥ž|¾uá&èáÿ¥—±”uØ <ÐØ
+Œù¥Qð>ö©@ç&µÒäE÷F|!Z´qÁóæ”<è Q¾…™
+Ì›Ñø iZMÃ=à|küo®N/ ÈY 9‘Š-ÚÆ„¼ZÇ
+úî¸_>G/71WƒÏ"øDcÞ†¸h‚·X·ñõ-ìéàI¸¿/:ýO¾Î†Ü_ žIÐœs0Ð_‡ùâ4ôîñúGˆc—ô…bç蹘¯›"¾>hlqßÙ+s1æËðÚy‡‰B¿k˱^ô™°ÇDÖaJ…º(«ÖPx»‰d®vj ßîÀÇÐ=?„°¸9Â9"KyJ|V~HKq”Ã`nÂ9€g
+¹Aÿá<Âá(w‰Qn‡¼ˆµÜPüaEè~Š)ðm[ì1á¤ôO ?ð˜Òû‡úùÅ.ó?ð˜`ln¤/Åê ÌG¨ âž ·
+±†óä…Àix¸ýq[<ŸpÝ9v.ëuc1ëÿ`åPþB´ù
+zX"à÷(ß@´÷€‡€ž­Ä'kè°âµò“C½.É匥XÿúRÈŒ!Ýâ £1@s <‡ ÿ):âÅ¥ä´×DÜ?ƒÚt{«à¾ýÙ¡½,ä)ðGAµúÎØGýRÀTòåpØ‚=(ιý‡ÇDJ•š(­Z‹¶‹QüËcB =/cúv3
+¹–=Þ8¤_<¯£ºÇ+Á:*Ö{ ÏÝÀ^­×]ÈÛ°†"µF¹Ü;e±(­â€äj_|¥Ý€ÎèÐ ã+·c 4OXßKɸ|ì1AÇ–ìÀˆ?Ã~ }cB_tZ|–ÀwúPØgÛ3~x·` ×! ñ¿zLXþå1a5’69&O‰ŽËa¼ k¨ÎÓ±¥»Øè¢,¸gàwc9äÌ9m£Åž·—1)íûÙ+ÝÚTê€*ô¥En× æЙà߆9/hi_‚ýaèÀÞ›g=&ã}6a3€—Cÿ¸:ð_ðü=4±ù¥Ñ’ÓÞ“À Ö>A¯–Žx¿…u¼2—<é5tá©ó!“!>yâcršê„ªš&¡¥iD°Çñz(àN:¹ZôkAzX|
+üŒÎŒÄ|"èáFØó1JµÉ". ×.N)Õd ¶ˆQmýw›Àéxýör8ƒlš™\µ‡Mo×Â!9«!fÈzLXÿô˜8?Z‚=&n­~ñyï)Ð[ã£ùDÁÞ„5%1s$°
+pã‘K£ ×Æ#%sðÄpñÅXÛö\xd,†\ñŠóè©Fçí†ço“º¤(ÁxBÿ¼( §ˆ½’‚F² æÉzæF³ðJ“Œ/xUá\Wª,É*ç “+ö³²¼­˜¬:mÐt†Þ%Þú¨~Ù+€
+56¥TN)Sñ…Þ3^°ÖnDà—íyk)™P¿‹
++\Ï\ÎYJ=[s”ÿýàaÉø]_
+˜csX‡
+>Xƒa‰â®)JØÏ ñT¬QŒÞg“+UÙÔuÌORšTaÍ|€À'
+ÿ?|òæþÓ'/­Söýèóè!-r¼Ï q¾ö5Àß­õØrQj£&Z¸îÄ^¯XKŽ½4¨‡ˆ#‰nÕP¦O^–<ª:ÄËîQ…¹@ç­e¬“AK¸&ð%¼|.p2ÎÅΉó@›NmQƒx×FxP{¿.ö+å‰P}Gu^|Êaœêx’ZX‚ü.9€÷‹ÜÃçb}eX;‚½e°çÕE!h3ûå®’¸d,€5!À¿Ø× Ö(a}%샜ø
+¶Š|î®yf.½°æo®=:æ´Ç¼û/â¯x]È#q>ø¡ŸÄ•lŸ:ê¤ûXòÄåq(Fæ2žw–€¿4öªwO@\%úá_P'`?^Èí5tô‹-P³%žYK
+’ç@\@>
+ÈÁ~XÀ}ØÕ9ðG¯dèg²{@?bÒjh¯hðÃ5¸Oòx¬
+Çö|
+7ÓYÝZ‚ÄšÂóS(³cx¯$ôaíæ»ÐûÎr‘}âìõb1zEh,Áë@aø¹¼ö)l:ö†FùMì{m®ý˜ÄÏÅï[¸c{âïQ?æ2ö¢@M`||hO½ÙéáÐ[⟖‡ž1yÊq,yÄf$ø’ƒï ë’2 ÍßHG—mƒ¹
+ã è £z‰ó‚KÒ//lhÞ&ðöÂýK÷è¾.¿Qðéð,£#žlÄk(p¿Ò—àž ¬ Áº#ôŒ=Sæcü„ê•R¶—Žy±¯[öšÞi°Î/
+¾·úiLXÞ&ðhÅ÷±…[±`DÎzÈËTÊÓ¸Ö¡蓉jöÓ‚oøùÝYkÿÕŽ‚ŒFeæòÕð»Ð?$5ï†5):¤pð2¾j‡ðj‹>}µû
+R†þ.`V›XÒ*l
+å4“vÍžOF–n"¯:@ßìÓç_ÿª.Èù¡O½úfLå<Hçö³ôµO:dæ§ýÔÕuöv_ü´éˆäUÝñëÆSÌ£1“Ñ­ÉƼÛe|9i‰ô¤Ý8èKཫ螇$š§Ë„AÏÖ³)jÒku”iV¹è`Z9išZÊÅ)c¿c«àéRÇ|WR‰Õ»¡?#
+~± öePIÕ»ÁKsN„íÙ̺LV“Ö§Î$·íƒu8Àÿç¹´fe<FS›ö’1¥¸/Í?^ù“ºÚ®¹…IjVßHðÝ8ûÞZ‰{©x¿èÝÇà+ëuc öt-{¿•Ìø°JkÚG_m: Êj2^mÐßH2¹~œ#ôoàÜÉ„Ê'×Tj»
+졯õh3·šyà=ÍÜû@òÓz÷
+â[w’Yß5˜gÝÆ¢¢çØ7'ÅÏš0Zá-t ß•Ü­1fï4 DwšÐÿ×JŠrMØ Z²
+}·žŒiØÎËú¬Lçv²’g5’Üj3À2’ì’¾Ú£%ÈlU®ÞJ°×€‘í'Tì>h²wºLlåÎ!ßÒÌ¥LrË>AäÛõÔŸ À»éäfeãû•‡ŒïV¦3¾jÐ!oÖƒ¯®ÈïùZìé–P§Œ×´|¯†zŒû‡mFdʶB Å8DV²]äûd 쑦ՊҺµ Å\¾¿ñ§™´Kæ<ÚíÚ|Ò3w¡a\ÝÃûœºàÙõò›„|ó»)]ðÍ\ðþoùåœÝúÅ^ØýÁ›iùäHWôœa ûNÀ½“–—º‰+j…/zÍé'"úY¿Xü¢þ„ôiíIã{ÕfÒŒž$¾J]’Tw€IiÚrÏ.W*äéj&©UE|¥ÙÈäJ%JjÓù?] \ÑÄ-a¡Ä!x–É9¯©ÆîW—Ãaí8û?/(¬ÓA}dn´07ûØœ6–Íi²ÏÚŠžÖæµ™‹®·ST怕X¿KÑ©ÂÞhç±÷Ú!yoÀ€¼ûUŸ¹ùшº;`ÄÞm§é{]|öQ‹Ht¿Y,É­9d’W|Nô°Ò„IoפÔî&Ó»TÑ¡1Ç„¼^q 1F_éÔf´jÃz­0«bS_z­†’Þ¬25Tj“
+ä>6 忤&eX³ Ó>(“W{öñ³÷Ó×ú´è›]zä]êÖG=êÎGæq¿”}Ö‹ò@7K½ø(a_õåvÝF×x·æÖKÅ›²[Äô½Nô˜ù¾ê r¾ê“O>ÓlþÇ#‚77!_|
+K[­Ä¥•ö&¯Þ]0yúî”än¥”¹Ö¬ÇdöhÁ¹±áù›¡ຂð•÷Q"Ìé–°©ý,ʯ›°Imj¼ƒ'å̬†ƒ§%¬…¼±–>/·Ýë6æôJÅ·ÚE’¬VJr­ž¦5k‹2»õÙ«ÝÚ¬ßãUà‘ÅúÜ[FGož¤áù[
+ß´æwgžõJéG}¬ðy»[ÐvœÉÿt˜~Ó„)é>üïµdÞ~>Fþq˜zýÍXðò‹*üdÊ”uYJÚJ}$íï}E•eöÌó¦ôÝ5¨E&·í!3>í‡ùÀÜï Ù‡íbqn“){¿e²ZuÈ«jÂÌV飊#ßÒ§eÂ;- }»Ëˆ¾Þ¡'¼ÓF‹4š
+Ÿµ™R7¿j“w?ê±·ÚH*§O>ꢨ¼>)ÿõ0û®Û’-ë8Ǽï:ÍT|8ÏTvœ¥^ ˆ™Ü.jõ¢WDÝÿ õ „÷›…tAÓ!¦¾ÅJØÙäeÜÿ>\<Ø$hæ,y5œ9ÕðùSßa˼î=LeÒ¢ÃP µ‹ž ¼ Ö4q.G¸êô«xaÕkx×ÿ®&ÌéHÞ”_4œwQ_«Á?ZÍ¿õ]“¼ýMGðò3C> ùY¿©
+bz·ò¿í%jI3[HÓ{UÇ¥oŠlŒK‹\¾ãn’_b'~QsBr»I$Êj7ÂXåJ¯&ð4Õ96½_ a­bû+óq5Û¹¿’ÅßÌèÞÏÎâOïŃ%ÂOüØ_»|…Ÿüد}ÞÌ@Ÿ‡x 4øxkVäéæ4™Wy`\xÙ嘣·dÔÀï.⾦à#Äšt¿÷´JÚ›üéÚŽ‹è~Z2¯ÍÙ—ƒ‡™ß÷‘i*’¼FK“Â2'éã–ãÂW=Gèƒó´K,~ßhmÒR$.m¶¾n>)*n=')ª´‘”T9šT\½o¶’¼¬µ½­µç7že_v˜Ó¯;ŠóêQ<Vœ””œVžA9ÏØ(£k'ßÿÁ^lÍFÞ¨óžrFTQßQ[½—´«,DÚW"êjôö5ûˆ»èÖvü’¿™òKþ4!K~5T|9Føh/lð•|ª
+5ïz#þÔDW|8K¿ì–27z È°·ëéW먨ڭÔõ:ðšèyƒ¹ñËò Ò¼2KiNÅaÉÝcéƒ*3ã»U¦Ì£61û䃔|ÖŲ/[ÌE §Åyu§ÄOZ‰·›‘w¿ë‘x ª¿ìËVsqE…½¨¶ÚEÚTécÚUqüÃÝÄ“­×v>ˆ;Ü÷2F4Pí+n©ð•ÖXÓ¯úLØ÷­gØæj“î·‡zó¢-Ún%X6§ÅYÕ'Æ]¨“mLŽµhÍ’ä‡0ƒ=‚š_Oðþ¡ýñ¹Ði"ç«ó©”ÊôµmöJ¿6ä6¨]—çó S>ne
+š´¿ 1kË4­-ô?Üñ,úPÇ«haU“ è»©þN•ïù|!ïÝH=mc‚¦ÍåDN7ˆsêÌÌ:^ÉN¶ÝN²jLO?Öò0Ѹ¾Øê{»™]k4å ûôúý“º|?é«Šsìõ&CÉí䶽ÑíD[V Š¹˜„÷ž2¿ÿhˆÁÃÝ÷¢Œ Â$ŸÞ„˜õ<Œ´¯‹Ä1™Uâu¯Ä9*ý½»Ì²9%Z‚âöpWNÔ±¶[1’þÊ`qsÀ¡Î—2¦aÀ†—ËéRYß5‰]»'Ké+_˜<­9/yÒqŒ¼úç~2øýZ^DÕZÁóoŒ´µÊϼãyÜÑö'ñƽUá–7qg½ÏÁîwQ’Ϊ
+ïˆÄ¹ý%÷»ÌÄošÏš”»›4š¶GˆÞ6žd ¨‘}jâ¬&øQÛaÉ›Æ âBT“_~1“ÔÔzTø§:WG¦š¶E
+ó[-È¿kóë· ®}Ñ`žôŠ„MnVÉ)'Zo%™ô¡\˜mÒW!þZr¨;GfÛ$KL¨u‰©uO´lÉL–ô¿a;ê\uÜwo
+Lð¨÷«u‰¼YåÇÝJ‡ˆÇhœ^–ÙGæ;Ç>+v’Ý-qŠŒ-õˆ:Þž%úØ loò’VW]´—ÔZ‹Þ7X‹Ë«íanD_Fqí/ó+÷‹v/u©
+M*öˆ (÷O¤;{\Œ^s|^#wü(ÊOAe¾ñ±E^ÑéE2‡º(_II¡>IÇѹQƒÎzo9=ƒ×œž ùûø·O6ÞI ©
+̬ʶl½•aÞ™Í6”Û
+ËËλ׆^…q‚ãe¥]ÄÍjLjôr—ˆ{5öE Öa© ŽÑGºïÆP¿v»öpÇŒúþq’÷»H~ÿälÒÿ$ر*"6 Ò'&¾Ä=êj‘G”}eTô™ú䨳õ)ÑÇ›³"¥=o‚ͺŸEJzC$%Í­~ÂG¿¢nþ]Gøü×ÃfM¥Qg›2SO7g%ùp7æ`C=Ï¢…Û}Èžßl˜Þn7Ñ·ª #·ef}"Ú9 £æÁ#ô‡j»#÷c]ë#®×å_6xÅéèg~Û¢ïÿd¾¾MÒTǤéúÉMŒÊÿQ½Ž×bCÝcãªÝdæ]·"~ãÎëurƺ=œX§Ÿ“èôqBí~ŽÑäÌŒ¾rg~pVì·*Oö{•'ùå‹“^ 'ÖjZfø€Ó¤Þþ8$.n¶5©®ò=Þr/ѱ:*%ªÜ;ñj™[¬mclª¤»2@XßèÂÖµÛ‰ê*]%½ Ág2’œ«"m+cnºË½uŽ°®C9ûy¬´¿<ܬ»0Ú¼+'æBsRª_ªKMx≶Ìæ÷®ËtG‡£°»åÎòpóîܘ“mYqšcccêÝb½êü„Ÿšý¨®ÏöTÇ7;^-g¦_ÄéëÜÜ¡;S'8{®V1§Êëü~Jôkew…LZ±[$ª{‘7‹Ü"½J"N6eD˜w܈`ú<Øú[æէèŽa;œŽµß÷¨J¼÷Æ%òå{‡ˆœ7®²;o]Ñÿëùô­sdú;èèÆö…C}õ«ð}úÎ)² Ø!, 嬒J›Á¦‹AÑQ„rGŒàÎZ-Ïè;gu¤ó–ìJƒSLQÓ¥Ð' v‘9 vQÁM^É¢ïe¢ï•PMßDòû» óœSÑwž¤yÔR~¿Éy¹=|1±}Ÿ6±yç^bëŽ}ÄÆ­ªÄúÍ{ˆ5[Uˆõ[ eÒq˜ºý“)ê™[¡QÇiP_ÚJÃ"Ò_zËn¾öˆ
+/ô“ÅæûÊÒ
+="C ¢/#ìpº13VØÛãkÜU~´ín,ÂEñ¡¥¾ ©o½bÓ߻ɲnˆ.÷ŒœÇoü»…ñÇü°ô
+ÙK”ßž5Z‡Ýiµ½ÓnÎþhðÑËþ´ÅÀ:r²šŽˆX5W‰X8\˜O(s‰iÄlt(¡ïWŽžM¬›½„Ø·ODh‰íå4¥nò;wÓÄÒ)s‰9Ä,ô[³ˆ ò
+Äd¹ÙÄÌáJÄÜÑK ¥ik‰…s7+V([ -‰}>3¼àvéUqBAçŸVÔ[îðígK“Žw‘Yo=b
+ß:†¿-v /(µ {úÎ1"©Ü-:ºÔ+Ö»2 Ñ­2$!é­WÌm<¦n‘qï.Ç„¿÷Ž>Øû4’ìøõÝ×ëjßSÓt)¤¾åb0šCñä>7íÎà@ö¯k8Þ˜ªm“1YÏéž‚Nà;%íì/ëµrþ¾Eû!·S;¦n©
+ï±Xi±pæ"BIa1º†Äb1žCŒEÇ$ô“"1P’ŸA,ž¦D¬ÛfDì5 “W¹ô|¼jüà<&NÓð wŠ÷+gcÜÿ"DÔÛå/lt5u{‰»ÛŽ}¸s¹*0.þ­WTZGäõ7î‘(/F]-ô”=.vŠ|ýÞ!üJ±[ÊÇ‘Ïß8G¾.t/|ïžZæ&‹ªðŠkn¾ÈuY†~i³Iúµï\À‰Ž”pýß9‹ýo¸-j¯§íÛ Û°SX¶T‰X½f9¡nzFNË󚂶ûÕéêÇlå—ÌW"&‰ÑÄ(b1Ž@×%>‡r?Ž^®z,ú­‘è'yüÚxôùË„Äú"bå/·ÿ·JØWä™ûÜ?*²À72ºÀ7*úÝå¨ØBoYz¡gÔ•¨{ùnQ/
+\"s \"¿r¸‹ææb—ÈEÎQoKíÃ}*âÙ¯¾ÂÏõ¾ä¯Ÿ\/¶DǼjF5¸õbht“sô.Nñqbù¬å(§¢ó‡s…ÎJ_ŒÍ8tÀ™#þãÞÿÏrøjà7áL F ›‚¾N$FÊMD?Í fNYM¬ÝrˆØïU¥À@ucsB9ê°¸¯9À¢åzlV¾GTasøÕ·îQYïÜ¢PŽ Ï+r ó¨Š5íyêY±ùèSÄÝwΑ±ÅžQm™QÂ_[Øßýœƒãª>X‡7;GüÎÜ/{=wÓ]Biü t £ñùDgßO@×4EÜTô|?ì¿\Íþ†¯î_¯{ú„±‹þ½h.®Ú{‚Pñk¡~“[©?Àe;z¼¤í•Af-Ï#ŽµdË.ÕÄÆZ×Êb^½BXÅ$ŒaìoŒcÎ+ÙËBg<nK¸D5;Ew”9Dˆ?û£Ï\·ƒc û¸üïœÖ{Nc§¾91Ðÿë¸F¹Ÿwþ;âç=Sµ„X¸PŸX«q‰ØëZ5I½‹;@}*³³*I
+Nxé'»óÚ#úi‹ìI¾[Ì“"ç¸ó
+\£ß¼t‹~•ïòÎ7Òµ"4&¸Ô7:¨Ü[vµñ®rÇÈ›¥ÎI¥2ÞWÎJã·UÝëötUs[¹uk·3å&áƒÏâÿŒ99|ÿåqœÂ×ÿ| C‘8½?
+Ͻ¡y8 ¯FŸãPV@Ì$¦ŒXLÌQÜO,ßeAl5M“Ó¨ç4ÈÏŽ¦Ý³‹\#‚Šýd'Z®F¶lH•.^‰°W”/új[}¬-;^Ï~ïQŽ0{}uØÖµM¬u5ëˉDøB¬z)tÔ¼Y3ÿïýptüëµþõ\¯üÏ÷†®{$¾3cÑ‹>'áÙ;”Q‡rüÏkƒçŸÂäÄÊÄÎã·GhÜäÖº9ëÃ-÷CÏV¦GG¾õÁqxº!5ª&ß-á}¡KtÃú"—„¦7nÉMïjÊ£_½u‰Fñ){Rè*K(ò’é r’ ÊbÆ„ixnýwyáûñ×uþwpMc~ŽéHô9_ÿ$ô‰jâÔÍÄ‚eb…ÊEb“8qØž«Ü<½Ïœùá†[ÞI/|e·ó<£ó^»Å¾-pM(+pK)-vNz^è›[è•RèéX‡[EPªï‘ѕºn‡h—r:«–mü__ÇP6”Çç,ÿ/c:ìç{cÑ»ãÐç”a3‰òóˆIÃÐ8MC9iªñó‰i#–“†/&&Ê/"¦ŒYMÌT8@¬Tv!v}=Bµ€[Çö8!܉êÔ„(—òÐhñÇÒ
+S·Ó'¬'¦ZGL·–˜
+ßÝ@(ŒG¿§ J,ÞxˆØfœ%¿?›[nÐÁ3o¼x²êJ(`³{/<£Pík}ãžÞ\à™ÑþÎ5µ÷Ç•ž2׌þJ—ôÞ§”æJ‡„ÒR§Dà]ûʹ­“äÿßäÇ¿ò \à/ÅJÄ”áŠè§Ih¡ò£ú)7å’ùÄŒáˉi£VÓƬ!¦ßHÌœ»ŸX°a? gb#›<l‹0UnW@÷½/œ™°ûµSìK¿¨ûÏ.ǽËw-+t‰-ãšP^âû®Ð9öÍ—Ø{ï\¢
+P>}ùÎI¯ËÞ{Fªµqª+שþ¯¯å¯¼ 9b,Îì£~~?ç‘1?¿ŸŒÆQqÄBb6§9Ó6s6³æî%æ,Q'æ-2$f-ⳊsÔ‰ ´ˆ¹ËbN(±Ë±e‚Ê[nøà §ðAQ·¼ñ‰z\艰™,¦Ø#áÌhàw
+~AXìý{ǨÚ7ÎQoŠœ¢Ð5Fê~ãî°–[´i'ª­“ÿíë‚<9g†áøû¡84Çb42‰˜!7“˜5v91kÊ:bÎ̽Ē5bÙöSÄÂÍæè° æ¬sRÄÌ¥$1s¾1CQ˜=û
+m_bó¡{ò;‚»¦¨äpË÷s[õ?rGŽÔ]ó ú<Ï#¶ºÀ5¦Su©CT[©S<̹öZÇ´¶*§”¶zûä·¥NˆKø†©Õr{–¬Òú_Çæеxü žM•›EL•G Í«ihÎM—Ÿ^›OLDc8 ÓF-"fŒ_®m#¡0k+ŠOU“úÄì&ļ­–Ä‚}ŽÄ}bO¬ ’ˆ fOåv‡ü6C¹”Û@÷_ºX˜âñ&<ÜïM`Ä{„½ªÐµ=|ï${Œj\i±£¬­Ô1¦«Ü1¶­Â!6ÿsôùêøõ·Ü®Y“fÿÛãö×|ƒ|•jº¼"¡8rº¦Ù(§£×' Š=qè=¹¹„â˜å(¢±·åÍÍÄ…½Äü…$±h“±t¯5±XÕX¢æBÌW¶!æ©Û¿¨ÛËyÄzã ¹¾­“Tžp+ ú¹£Â®7N犓Ýó#ž=ôI¬zî™\÷Ú3=?ßEœ!¸Ì7Öª1>¶ñ„ú2{܇}|yYå·dÖ¬uÿv-Ž±`DT½†£Z6N åþE„âð…(ÏÏG9Çæ4ô9]N]ßbæ¸EÄ´q PnDÇä•„Ât”ÿiJkL ¥µæÄ‚ 'ˆÅ{œ‰ÅúÄí
+Gè%Ejµp‹”¶ÿ[ã&ÿ/ùq(LDׂÐÇø„Ò/ªÄ%-t*Ĭùj(W(
+3Qþ˜¹ åL4ÏÐ\›;k71gö^bž¢
+1w¡1oM,ÜxŒX®îJ¬¤ëŽæÊmt+½!´yìÎÇÜ/»Ó~ÌÞWÈmÔìâ Ÿ›íŒÛzy¾Î Š,Ï÷L/*tŽ~òÚMÆ/ý~Ðà9§mô
+“VsP=^²ÁœX©aM,ÙfF,YÁ#ÎßCÌCùrÎÔ5耚·‰˜;{;”Ä‚Õ4±`½ˆXªz–X«H¬¥c‰ÍGŸÉo í¿ý7[µŸSVûÀíÓäÌ z9 ¶§ÏóHó­°“u™Ñ‡:DœlÌŠM}å›ôÚ'öTÓµÓžâ(—ÚˆÔ²2Û¾
+›Ðøb¨}µA÷Ìÿxm#ñõLÀµy2¡ˆóÇ8ŒùÇᯀA _N1a¹h>*SGÀ¡DLŸ¸†˜µ@‡X¤Œðñ™Ã÷„öÍØs›¯üŒ[xRù1·lwòßfíŒì¶=¤kÊ—²ñ;.=½Ç¯|Šj.·b-§jô‰;kø‰;-üRäeÚ÷(ølc|$ð9àä€5w-t‘=çQZbÞôÞ!j Â9©æ½Sù¥ÉAÍùý4ÈßÿØó³–C|2V5‡˜;e-±p•±Fó ±œ²!–™‡«r‡¯ñ};r£ßû1›<ÞŽ^wéÉðuŽy#¶x•Ýâß<~‹oýø-ŽïFoµÎµÓ£b¾ÇÜš}µÜnå›Ü"• fµln™f-§©SÏ tÛ8‘n'är—.VÇD
+·H—ê ÑàK7è¡h£ØÓxÉmÓ|Èm>PÆi4q¦¼.îŒ`àO{ñ·ê öËo½‡œŠ¾±…œê¦í„¶†:ÏQÂ>F2­Q…µAd—1W|*lŠÐ9wõ‡Ž0wÀ˜Êü¬I»ßZÀ·ËTÔ1µz£!1gÂâÿÒ úØ”G8 a¬IˉÅ[„Äfã$¹ÝAmÓ ÿíÿŒçËAÃïÜIÃ_9KýOÜa” j9R¿Œ#ußsz†õœ™`€³3êäN”q¬þ î€adÛC»ó R»7ó+þ8L÷õ¸ð?rÖ¼6ÎB7ûÏ­†¾9J¼„Ú-ÔµÏèGƒ,?¦dúb5™˜·•¾Wc$Ê}'–”Ù›ÖŸtš²Iƒû™ðŠmLà›uLncÚô2@Ò]hPÊ1vQÿíuEyq’ü\bòèyÄÔ‰ ÞB,X©C¬Ó³!¶¸5|›wùøÝ·þþ‹Z%· Í'ƒ/¹=<_(8™:V×å¢î+Nƒi*·³øp#^:XÌ 4º úzmõ 9¿(EƒÓG‡œ³iàì9QW–»H·ˆÓv5z²-†—ïþ¢Åú­‡^ÿÛ^òú-eÐDÁA»LxÝvá½N‘øUÓI6¯ÍŒ-j>!~_zÑ(k`¯àú7u2³CºòQ]øäÃA*ÿËAœÊþsYã,Û‹yö¿~LE5cõ:±ƒõ¦ê˜7i%§¢ó‘“}æÎêösÆ(_‹ QÝ¥¾|s£¾ ºë¢Ü e{mÊvMbëŽ „¾åùFzˆß9ŸiÉLµnŠM>Ô›+£>¸TpBí«×êø¾ž§÷ˆS1xÅéë§vl4 ºÔðÑÔ³v†¼ßg$¸ó»y1fßø¬¼Ž‘€ ¥'ä±Nèﻤ̣ãv1׿éK_7^”Ö\ä§ îœögd7U÷lÔøÝzg‰³6ã-ûéÃ~Æåb²<ªk37˶ ˆíÒ€a*²îÙª/¸ÕjõÜ^íß8©àÇ{êÏ6wö÷z?Ó¼Xûcû[<èÚ¾‹ÔÛo‡ÉW¿‹™¢ÁSâÚFwIi³3›; &m“tTu­;†Ï°ÿ_ºÙðÉ?4 ãß­ã]ò›ÏA bò7’Yýô½>¾ ¦z‹À)n&ë™ü‹Ø/m)[ºÛ8³Ž–¾)±1)-ò”¾¨=%Ìi ³[ydfç~2¶d ßÿæBóQãa½múð ¸wð¯0–
+“W¿¬T#VëX»-oÚŸ[¥ÕÃш_…ö
+¹¶À( užaÄíÅiµ› ®õìäå­ íRgRb¦±6I3iÇëóh»séSþ¨iê»÷<mT¯x†„Xb*'šÊÑnqsø1…ø±ù ›©˜G› ¯·W{Õ˜m,õ¼]ˆ÷UúÄ/`\“çQ×4%O«—V¸š•¿0.)v–äW[ñ¯ªÃs¤}Ätƒ Þã´Ý3ghøäÍÚkæ%¿zI̘ DLø
+ÿ$õ*¦jçêwp¦hÜô´ns›ô‚ëëš¹PV6 4 %„¾ä’<ïBÔdu±g›¡s@Bhªh*«7š{öyÑOËihꪻ÷Zêú߀"DR3yÓ³vMÜR›z\[ÏIÜÂæÂ3Žìµ6]Ó»•GE÷>ˆù×>« £(+¿Ò?ª"‹7£§ñOŒ\ùSE’ß|ž¹ÛKãg]láyfÒçÆBÒ-a6åš2Wà{w‘aJÝfû?ÔŒ®U6Š+]o1°UÿÚ×ú9ËqF“ýÑ}ðÇ.Ï+³ œeÓ 3¾í rû)£ØÖM†ö1Ó¶ 3C§
+SÙºƒØ¶d9±gýVBÍ;ê˜Óhx– ´ô$}§;þb•Ý¥%º_#>¨²w›iá­F>Õ§E†?\C»ÄÏamÂg°Ž)shûx”oãg‘Þéóaò®÷«‘&¢75§É‡Ÿy¼ëßÔø™•ù×¾ì£öÐlQëa~ë þõïûçý&ÒVžI—Œ¹¼Äúmô‹©¤¹êò±Î‡ lg«ag ÿŒS×—õ­ÖsÊUܧŒÐ¦ÏÈé_Jšl”ÃiòŸ.ÕŸ‘ã™Ù˜\nH—SÝ©Šæß:Báê‚ßdAf§*Ì}Öxhf€n1sÐr¸ôBÀtqгM´ŠTj©Š ­j/“Ñr
+þ‹1²Èº[†Ø\9&cf†¥ÁÇû Wø«ç_¹º÷—êÓ:Æq¯Ðþº/<7¬./5Üœc¶ª\ýæ zá•ïÿÛn\G®þƒeB^ÏT>¥fŒXrr6´¹k¿z{^ýÝÞþ¹Ûûâ¿ïò>ù­ºòs3µg¦êÒ[Ç꣊ìp_ÜÁóR4˜Íg¶>Ž/½:—‹/w€ÝsEçgb®Tw(ÕÚåanž^I´rz¦ð-_o[_n‡n6ôŒHOè ^ú×=˜íZlâúŸ»pƒ/wb^œg>EÈé˜"&ՌᓪFó©Nú£,Îý¶]×ñx½÷©_·ë/ÿêŽ÷g£ðîŸ üÝŸ}¥¾ æ®þªÓžûÏ=üÍ_íéÿ±ƒ‹(´; ù™yùÆX`~‹ú»«áæÓPŸûç?¿—)ÜùÙàuåÿÙ£{ç¿<<+?ž½W¬Y<~¶f‘ýtöyŠfÏ~Q£ IµÖ…¦Z{ûÇXrIÖ:c¼åö»5[™ÿܺv#ñظ¸r!:ÛNëdŽX!G%Úª ÅŽÄŒ
+I±‘ü£,åˆDh%È'žy©çŸ©Â…¼¹¢–)|r¥£®÷éF¡ÿÏ{¡k($UŒ–3jÆ ½Own|äÿÉÍÜG—ê}oß‹úÝ‹4)ïÜL¡ñÉ:¡òò±¸Û™¯»»\¨:¿€å ´'þ±]{ì³eÞiGµ¹“¼*îÌÒÅ5Þ¹›Õ «7i6¯Ý©qÙ¸Os@`†9Kmx‘Íê¹K4³l4³íÇhš¢ÙÂòäW>93”š‹Ë0“g8rm‰Ôüp‹OÑɲo”¥V/kDc˜%i‚…W8JÉ«Ÿ,½¶Jèúx«¾ëÁ&–K/Áý×µ<\­»ðwWéüO¼®ÿÕp„ز‘à.ðu7—rmO7qO7‰}?^u~¾PÒ7ƒ;~oxöµ·péµ÷Vxï{?ñÃ×üõ? ,&näò‡¦êÂóm<ù0ó½{ÍžížOè܇ä çckFñ½“ Åe óB˜ïˆ4ç×f¶0MÈgU.ÅÜŠpâ7w±ôÂ<.<ˆ‹-!ät³x~žåƒÇÆ )&Yue×ñå&¡ëåáô÷îâ™ï<ù¡w“Þö¹?{—~ÔaNCßõb³¾áöíÉ_·cµ,Î| ïþjÔõýe‹¶áã%ÚžnÂëç“ Gê£2l„ò‹óôƒ¿¹pýÙÝL®âü\®ôÒ}ã§Ëµ=?nô:ýïÛt‰ÍŽ{=ü4«æ-×,qš©Y7{™fÓò•š]»vi\÷{hvíc±åÇnÞ’ÆÍCÐìÛã©Ùçæ¥ñò²Ð'×;B{þ3ÚÐZ„ÖŸÈû›sZæ{¸@sâÇ­ÔýbßóÒšÝ\tŽP>4[<õÂÃpöÛKgIÙÍ“ ‰%ŸþJ¯\}j¯¼R…³?yrƒÝÍ ýc/fÂø–Çp åÜÚ‰|yÿ,]Û§«…s?{Ë7¿ ÐýŸ{µ•wçë+ï-öêþyw÷/uE§§{dXyÉ1ænú
+âaf×OĬ?t_ä²¾¹˜#eq`šÙ8^ÈoŸªïx±‰?ówîä_÷ðµ·–ˆ©-ãö½x1±Â‘fò2›'Q~Óð§¤+X~ewôör¾þæR¡èä ¾ôÜl]ÿ÷[¹ ?y~ôâúþ±“+¹8 zZc¬…§pÈ\ë›bÉ…•ÚyƒÛ 3ÿoM=oŠtö ÿÈÊ.fvNK¯Ì玵öÍ_–WLb+Fò1¥|D¶-ž>Ú‘bÁÙYú¶gh¹ö%úÎ/6`¶’Å?ÃÕ‡ò•gãQòûOñ~òÖ7}¾Jd±__ýÎÌ&b~Mxÿ[íɺè2;ÆëâêGéóz§èÿm»îį;ï0ÛÜ¡úÇhéƒc­ÐÓðTÌI§¥ùÞ*m×Wëø¬žI޾ɖ;6»k6/Þ Ùµi³K­ÆCÇktª¿¹>Ֆѹ#øè4[mp¬%”¤ñhÅ'78Iå7CÓº®ÆÄúqjpòpŸàE
+07'Ûs{fŠ-÷6Aë Ú|fÓx¾th&×ól«Ðõd»8ôÊ s®RÅ©ùÐä{ž»(§Ÿè„ó/´º¡Ÿ]´gþ¾ƒ¿þ‹ |ô<R¹ýâxúÏžº¡gÛÅ’ÁYbvîöâBýÙ¿¸ÒìòõUý…ÿ‹ÕOVêëGs‰ Ž\÷¯[õ½¿lã~ºZ_vqŸÕ>QW|y¦>©iŒ‹‹‡fÝÒÕš=[ökÀñëK§cŸYìÑÍIó£p€4:…ðÄaÐL%»d~S¬¿°Düv/×so‹œX0JŠN³“ š¦ò 7—‰57–òìïøënÝÀÛ¤œæÉBj­“Txn6X|Z“˜vl<⤘Ý4‘4uRY=˜ÄrñüþébVÓDÒ’LiËG¥ÙðQùv¤·SöÎ|úœP3š N­y<søШÒJ³Æœ4ôö¤²« äŠ[KùèüÞ\€™‡ÎG{æ"ó줬ŽÉX/º“Ý©;ûë^nàÇÜào»õ]/·H%çæBÛ:Bï7;¡±í!¾É¤aÍø~¯4øú€xá•^¼þÚ ¼óJÒ üê"T¿³ºsˆú¦?­âÎÿr€;û7WýÑÏVr™ÝÑWÓ'ÃW0ŸÙýr r®õñÌCÏÚ‘:•­µƒ\jÍôô=ßlá?YÅçwÛ+³:hf¿»¬‘âÊFI%½3¡M)å÷Ng×rœ”Ôà„k¬ Ï®ó‰·ÔúGZ€ÙÁ·>ØV4”Š ¥Ú[+¡­½OÒ¸Îé™íQÒÒf±B×òÑ*]ÏóÍl=nŽ]_!6¸žo¿·Iî{ìf8ñ•Nêýr¯Ð÷p·0ôÓ>þÜÒo}äGÓŒ¯>+7~õqæïý>¸“,]}¦Àç
+™Ç&°µ»Z8ýó~ÌâògþÓ]—ybâî½¼fëºm}Dù¡ë‡âà®Ðãrº'éK¯ÌÖ'wD.ºg˜­>èÛndÑÐ\â1f “c*Fë!µq4åÁU±ÎxõÓ`ùìta„ƒÁìëE£ ‰ÎŸúÅM7𳠴͸¦§ëp¡EfÎêʘb!§s²Çâ,«/Dæ+„ôÆqRJµ“~t—Ã꣄êÑBB£_;ZŽÌÁÇÚó,ƒ‹ nq@ÕHs1¹Î ó­\ï¯.\ï7Û¡ã!åuN#VQ«sš?]¾øxàò‚Í!1¡`$4\„3ßî—¯=WÕ‹_¤3_éP#@3½Ò*?=_,ît†ÖßøÞJhÏ€ ³:‰?ù›+wò/{uݯ6aÍ@ÃL&6{„”×:y ×ÿã.±ðì,pw½Y-ƒš ±t`&l\d¦‡Ö
+FìØeîu0ÎÒÝÓŸùMèŸl í©€æ÷Ý|Z>ØEÚiaùvЊ·úbr­š0 qÛpé¾ñàåÏäºëË¡KM%®ù½UÂ…ß´ÂÅè¼úÿ±Q(¼0 öBË)ëo-jÇx«fÈõÄ¢3³gQWëFZBÛŸ;\b@.¾j”.2‹ùÌ<;1‚ùºÄ2Gz“)ÍôÁ‰V°¨—4ÐI&Ƴ'p¬Ð{ä %Äâ‰qÚ2)1o¤œZ:ºŒx_à B‹[.==zu,†¹˜4²úgBëÜ"ÒŒJ¨t‚Ž!´>ô=_o_€X°à©6Ü]…¼KºøŠî›;BïbÁù†›¸ÐXf±Rßö`½˜xÜÉS‰0÷™oÍÄ ”aˆ!bfóD>¡t¤—O1¤utÀ<óö 5'¼î©ˆÈQ<¼d 0Æ
+ü"V§Œ“³ë&‚‰…x+‘nƒ>™—fÎr3}@šµ_9ZN¦“ÂH§H‚V~fýx©´6«Û·A7QìûjŸÐu»TmiÞU_Zf'Ø}ê©'úƒï¾xûV²Ï™FÒ†lxoÖ¨¾ùýÕˆåò»/ÊŸ¼ŠÂœjxè¸
+¾~Ì—…Z‰õ,>vNb+G¢Wŧ5C°_ïo¶}ó~͆yë5»·Ðh’¬t†h WV»îÜçÅri–C*!ÄßöÒû™A“úÓÐ/…ö?ïg¥ãƒÍùƒ‡­ää*'¡üì<ø@è6ñG?[c8ó•l8õR+/-&í‚Öéü©ïÝåë¯}ø›ÿ!yŸÿ¯=|Éå9wÀ'KkžÀŠ³Úï¥Õ€;‹¹z0à´ÁiÖ{]µøEâ”±<@L¯e1=ËlN>0ܺ˜Ä«döM(O¬†YʱÌÆ
+F‰±l-eµL
+)õNBD‘> Þ
+¬ )¡ž›°1¬K/é šlM,¡‚.gáp‘ƒÖ—å'ÌßAûW`µÅòÄÚ1ÐzWóNÌ"ÞL~ópŸˆéŠ÷Ïêh¥ƒÕ¥c1¼-áð‘‘BRýbätLU‹ÏÎ'=)ô9®.“{ìQžx)÷ˆ7WÂ.eö=sÄs¡éƒõbç.¨•Á×\ÏómRF »NõN`ÊèÛŸmà†þ¾šºŽ—ø’3ä¬ÖÉxm®»ö°õ$j„°B;.4ÇÆ[‰4ç‚’­¹p\‹D+WO‰Õ<;5ëæ®ÑlX²V³ÛºœͼüÂ-øÄ:GáÈ™ÙBBåhèÄCK•8‰¥ŽjF-Ø}£Á3÷ôP4Ð}">ô©˜ÅyÄ<h I]vB‹™|SlÆ}Ç—IÿçöÏ~Âõ¿)\ë7Á¢ËØÚ0wgµ×o^ä{_íÔ7Ü]
+?¹w¯^³oŸ§¼+º‰UNàNÇ Lf£Ÿ9ôŽ½9U£“šCË›4¢£ÒGHÑI6œ_¼iÊ3(µ~´ÙÐþÞ¹æe°k!(Î
+ú`âñO6ˆŸmƒî—”Y5Žr­¦Öó]Ÿo‡ÁS7Y-蜀¡üÂbhò-mP‡kùÁö
+‡‹ôÃ-‰s^Ô6S©>±ÜAqðg7áÄÏîë{_¸SÑ©ÙbH‘­–e˱õ§e÷ºÒRå%|ë³ÍrݽuЊG ÷ ½4h‰ßí%æ)ó7bFû$1«k2åëUï.•Ú^m—»¾Ùkèz±ßÐõt¿Ðy+XˆJr¥“”ß=Z†ÐÑÃyè 9½S)ç(»ºP<úÙZ¹ã»]rÏ7n†žÇž¾½µJß#wè'²µ¼TÉk™fÈ®¤Ô]Y)v}¶Cn¿·“Ùæ:ÊÉXn#õÏ`±nééE–:€‰Éw<Û"þê.øù
+µîÎ:b ÅW8›–­s\ µ÷Á~ñØÇëåìc“ #/Å8P¿3¿å]9JTŠ-û÷4Òë;ÿ‹§pùg^{êï;…´'h2z*¡,¶™8‡B|Å(褋%æÁ7€]z)(ÒÊ'óècv‡³1ûØTÔ`üAøq3÷ý4zÉ× zŒˆ›ÐÛ‚7ô†ùÀ+ÒŸ,91G9þþ&©ù³Íà²Bs”ðÐ~eù TÚ5 Zšºö÷ÖHçŸsêà/ZÜÆ0 bÚ°ûâ{â Qé}èÆüêF¡÷é.éôW^bõÕE|B¾=4üŸ|°ŽñYŒÊ²CnŽÞƒ”ßç ÍgÄèŒ 'gˆ©=“ôA©Ö`챘1
+º||÷O.â±'˜ 9£ö“Ó:&“v]ïÓú·Qó‚™…¾õá
+gÀæ í_íÖ›Øýr‡Øz+Øò¡ôáàú5#t~¹MßûÕè„¢'Bþ×¹øÔ,¡ýåVCç×®B÷w»ØówB÷Á˜Z9^ò?l…už“Zse…ÐýÀE|äå3øXP:îæ[>ß
+G.Îå#ÊFèü­P÷€_¢äœ¡äœšAŒËâSó+@³ˆòˆê‹ q a[:)Ò\>Ø¿Úöx·±ý¹«Zzu1ò_½hæÍû™ ˆ`^ÕÀâ²Pw…ê9®Ú—ìz[ƒk¨¶³ëÕöÜ]-½±:êØCBãäsÑ/ÆJËIœÇn®1t<qõézàÍ]è<ƒwÄõ2vô³ÕÄEÈè˜ í`¾ýõ¾îãBÑå¹BÕ]VS]˜/–]\Àõ?Ûn¸q/ÈÿöíÃÍ{‡´§ÿ²“¯½½T¨þh™˜ÚN>Ì9ìÓ‰¹SÑ×úw`wˆ=¯w{âºÛM³w7ó«Z‰å¡¾foxs†è<!(Ê
+q‘¸Y1£ÁJAÿ!é6Xwj\ÎH¹’ÅAh¬B—›ØYÌu?Ú«œx¢…Ÿ8ø›¾‹å1`gÊ·Õù'X‚-«—Â-ôb˜9ô¸ Q†;0NHSö`¢µDš¶9#HSùÈàlúÜ`@$‡œcçWÀX!¶qt‘q ófû$TŒõÌr
+¼:ŸôÚIê‘óå†ÖKÐâ.;1ü+uà±'rdìe é,gŠ,°“CLZÜÄjy°‘tfÁ|†Î5^wÕù%ЬÅy4â÷F¤Ú˜úÀ)Äø0†e
+ÍjØ·Ål5©x´áHï\ŸŽ{n~m<¨nêyô‡î<ÿFwþÔ íÿ®;ÿõèίãìÅk1 M5£mŠ’Ó;]œdž„>4u˜_åˆn–wÐÌ“÷5Óƒ£–j–\÷åzä¹rZ×$Ä?°ýø€Tkàk¦Õ*f'–Äa=\0’X쉅£Õ즩†ÄZ¯ kþÈÅ…BÏó]à¡¿¨cyØ2àœ{ºë5ûwï#v–NRÍôÂì¬è!&zz5»µ,¾™#>S†‚Ól !É6J`ü09(e8|4XÜħÎj˜¤æ4M…ÿ£Rlï‰wÁ®­tüî:0~HŸ>¾Ìy«Êr}æª7Ö)Õç–(åg³­°eºÐÿhÎÞ W
+-n)¡ÊQ`¿|3©ý‘ rRô
+'ðÊÀÎ/µÙ³³òLì,#«÷}Ã-_Œ Ucå€k¬]hø«‡+‘Áçòš¦Ï,µq¢1£f"ó;dÿ”aÄÞbÏ÷I¬‡çCoý_Ÿ:^-ìœ Ímbö!×h|ƒ¡ãý>ŧ*é•ã û Þ3±`KÎÍúÙ#þä Y°cÁÆ£ç³Ø‰€Ð|kµr¤®‰»k V"øèbÏë
+¼y°³<pVRò1;K/Hì,fãðOÄÎre}€ýnˆ/£&äò O¶ó É·£Qˆ¶¢¬”H?Áîb>Y.í "jÔ;׬õÁV©õ³-à»*I ãŒÙÝÎ`TÈ]_îFž}äTÐæ&>á‘ö™B×Äb$³¼#§mŠ”ÄÞ#¸=÷Y¾uo‡1³qŠ!,ÛÎ7¹a¢O:«ëËçï맞(ÊÀ+/ÚÉ-×;‹øí§ær-;Klþb#±³2›ÁβpÇZT£Ì¥ìþ©Ðê&6õ‘!bgÀO;+ÏÄÎ2ü+;+ê ;+a˜àbÁ‰¬¶TYÞŽœìø충Ð÷9 X`†Äb¶>&ƒ­@Ïgu‡ÌžïjÁñfàR!g îž_qe}€©Áò“ÎñÀl•]K%"ÛŽød!ñÃÀüVÒ›&òG?\%žü³»¾óù&ð9ß` œ/çÙj5ª"â‡ó~þû]–g5y`Æ0üŒ‡§ÑšË©•Nè#"þ ~ÃïEÜi.€å?Ç'J•—‚W6·û½ÆÝU¯A¾-†$2\7Q-š–/å•,nËð'%Ìç²ZFN®%æÎ[q}/\äþ—û‰ôðdÝ쬤ßÙYñ6FbgYªÔÞ\­ÆÒéýÌðÚÁÛÆ^©!­~‚Zuj±OA×lŸ¸<â[S=žvté±·|²‘x,KCZöà›¼a‚œZÃr¯“³Å–O7Ëv íŸnå›ß[ <õÂp>‡j™Ng¼/©þÖJhÉãÜ£Zzy1¸¤jÿ¹ñÖŸÄÂ1¢¸¥14Í–ÕkS¤¦Ï6#“X-kâKšØY±³žl•û¾wWN¼ôÆdÔĈÎÁeÓ'Yq!yÃß°³Ð_s€øJ%]sÔʳKÔÜšÉßs[œ¥šÓ‹”úwWJ/,»R‰Î³bXãè›r:œÅ£×Všøï®&nLQ«3~±C«òÊrÑó Õ¬š‰ðÅ
+ž0Äü-pî¥æ›ëÄŽ¯¶£¿F{î` æÔ2ßÛ8A«u"†sx.±î¹íÎri÷,ì_¨]Î}ÍᚊEÝÎbXšN 4×û˜#vRþ Mÿ”J'÷=¢Æ[{ÐLôOµ6D; ¾5¤ÕL
+8?bݵed›`ˤS,š+·~¹ö)õüyöëÔž'î~ƒe‰ùOpé<€ŸdNè‚Îéòáâ‘ØÓÇ=¢2l±/%Ô¿»‚oúl-ØY†“Ï}ßëí`g‰Õg`æC*š)euO–µ@=çÛ ˆVúYåÌ>‹{Ø{bïì¬|;K>úαùýõˆÔoe1ßÕ<•rMæ÷ÁlA>,¿¹Z®eﻸk†\Ø=ƒXó…ƒsÔ†k¤ãï­'®-ö\âŠF³X}
+Ø]¨ùä쎩`nÈ…31cB}¦¼³DØ+ú—Q™¶rLöäaÄ€a¶¤Tœ[„ý b¼GæÚ‹I”ï#SŠ.̺=¥°g&˜ßˆß"óq` Ả%¿˜w|
+˜Õ4çR÷Ñâ¥TÕ\>–ÌìÞ •ëXÜf5ò}âØ /*ìrÙµ§Ú<Üö>™þÎt·—ª/.FOC½ðµj¸ðÀ(v?Ü!ùDZêµ²ûWĨɮŸDŒ/pÞ‡Eä ~¿°³Ä†;«¨nËmž"×^[|\ßþhêw}PŠµžåøbRË8°Ò”âßYœ¬îcëxºô†UÐ1l# kªé61ÖÕüþY¦ßÛ= ö@µ 8ÔCó¤Ú‹KÄæ»ë˜mîPÎB=«Š ð;ˆ WÄìžý=ääÛÀbkT¬dµ|÷£mÊÙG<ö;w®ãÞFœ±Ãž»Z~m)›LÎ)Ÿ}¬ó»öIhÐÕÑþç>2<ðzïï`õ ^3|‘šÙ>•ÝKöص/陃³nRpÖp¥èì\ª™›ïnTRêÇ錡æË©‰aÛë î–Èì6®CÌõz–ê4:­Q#¥ C~Œ÷%ÿÓô%X=9LÇ̈åÉþ–RÒ3 |+œ_"&QÅ¥ü±Ï×€9¦Í9°Z½(18Ü
+¬-\O¥êebå¥Eèå#F‹!™6œ!Æeì¡+Eçæ…özÁ¤jÎzÛ˜%“kï¬Æž1ÑÄ]_[¨œšµ!§Óço¤Æ»¦Ü’ÖÑà\Cù¥%°{º×è7Ç•×2 ½k¹ç‰óßK¥Ø{9$ÍF<k¥$ÖŹñô7†s_+JÿמbóƒMÄìA¸ÓW–‹íŸo‘Z?ߪ– Í#¦9˜·,磜µâÜœ/„PrŽOK<zsßÿb'×üñìïb¿™fà ì(&•ŸY?\JI.MyJÆÑI†üvgÚbþo¾»†;z}®8ë¨çuJ„9øÄTaq…|^Q;ΰÌ#nÞ7Ë)F°u/Vž™/²üœÕ-«Oh%æŸX*§ÃëÆÙ3qàå>0
+XöQvè_Êõï®óˆøA`m —v|êlÚGÎd÷ 2ðòjÏ/A>BÜj0Û ûf±…øØ;‡/'OûgÁ.Âs¨ÞC­Êì9|Ç‹­|Û£MðyJ9Ë%ÀUB¬­¾°„ï~î¢=Òƒ½zb}%”:ÒÙôq¨ôÌ|©ˆåµàãÿáŸÀ]î~´Eßþùz¾ñîJÚÓIb±¶ÃÖ˜‰oÜ2™öÑÀÙáô£M9rË4œ#àÚ?¦ÜI.œÍù'[é ‡-PK€[…œL81­†Å™Æñ2Ë?eœ·*š£æ6N¦½²Æ«+Ď϶Jï­Ã>½àŸaí)…šq‡X,+èsæZ>^‡ßOû5̲Û'cI…½Î|Í™ù\ǧ¹æÖrÇ?XYT1<Ý|L1"ÙF)é›C|8œ!Éš)‡²‘k§&V¡–6ËG¥Š>æCÏ.‚M²šköÞà_À›R¢SìÄÃÅJbÅ9¯‡ù¨ö)Ôçc5Õìy¸FàK{ºk5Þ:Nƒ<µ ê]\wäIØo•˜ÍJ‘)6dÛ`L³k¦äuLÃY92ÝVE<o¸¾ù
+xZ¨qfK-ì…³XWxØ/V’ŽCí ÿ<’¸éñeŽtæ,ø¤j'Çœ(΃÷Ê|Š”Ò0Lgâ ã¼bf 1»Uä>àÜ¢G›Z:†XMäƒßYAœWôLXŠ5.Õ\3ù#°O™#ÎX±è³³5¦$²k—ÇìŒÕ'È‹`ƒ¬Z%4¼»÷9¡ÐòîZ¹Šýö>‰'~(øÃèó OžT<šöJYN>›Ò÷ô
+n"„8/ˆõE9»¶ðW†ìöi—*.,!&8{ÏґΙd§¥³øê‹øŠk Ĥ'äsôÞpî¥õóXOÄØ
+Ž¶'\{âÛ­úKßyH'¾; ¾rç«ÎÌ‚­1‚üÝ»9àô°8°€Ö#؃QÅôºi]_]ö_ooooooooooooooooooooooooooooooooooooooooÿ??æÌÙ°Ë/ÎÏ^Üg?ÇÅuû­ßá¸ÀX{û9>Ë\bãv…øÇ…DEúÅ&;oÄ—Äû9×]Îçï÷KŒõYî³b¹ÏçMÎó]\Ù¿Ø3Ø·8/f?»|éÊÕÎË´~áÎóM¿Õ™}ÛÙ36$8$’}QçïhúÑMìÃ~ɺ ëV,]¹bùçõËW¯ZºzåºuÎøò†õKW-_·ö_¾Ž/¯§ÿÁ—×Ðüþåÿþ%ÿ‡/ÿ÷/9d/ØGÚ{Ûopž¿ÀYì—;»Úǘ®ÅžðÀ¦îd¯ø÷ Ã~p…³¸×~Ù®À„ÿÀ$wgÑÃ^q^îLoØôç?^Þ:öW-_ºv½³ÁyûïÚ•ì»â¡ÿoO`?òæI¿Z:ýýëÙ–³â™ËíçÌ¡Wˆ[¹ÑyõŠµk×Ù‹®¶û\Íî4®Í]€™—lŽòAsOÎÏÌÃÛßì€gÙ>wY³g—Vãæ®h´úCfºÀ,kŒ9êƒ2¬õAéÖÚ€+/5Æ|·‹§fÛæ}×=’ƃ3ó0Ƙ{èÃÌ÷¸‰š].Þš}{¼4@ó22׶òö‹¶à"rmõ¡…¶ž)VîZÍσÈ>éüã,õùô¾I–îÞ>ô·Ý¼ ìwè4»·¹²ÏZ·lŽ±Qß¿ß—~Æ[
+1ヒ­!ebH© É"cvË4ŒÒcÔ•dzÃsì0òL£-‡ËGc¼ãÁ8zŒqLC~ótŒš`’?c©`<’'ái¶†¥˪‹Ë1–‰29"Ö$(Øg%4ÅF‰†DIÝxÈI‘4 ~#H‡’†ËA‡­‘†Xö÷ãË!I"DgØ‘4B`Šµ#żьSüÍ!Gi! Æ
+#…–c­!•­å$ çn!ÅVÆ8 oÍÇ’„ $¸¤°tŒKBBU§÷5ÓÉÍDŒã‡±÷•b«¦WWKO.0dwOÇ(²·b&øÇ[AZÞ{ñÀÆl±ßƒ±P\ÏØ#£IÂ(³}ª’70CÊl™$Ä9ˆqUìëµc¤äZ'!8{¸·!Ò²­RtÖ’ÌÈ8>‘Ž“dMáhº&È>> £L8>OÇÕ!ÕÀþïfÁK¾æGô2›CF2ÌžÞAf^Z?3w/UÉ%F¤p’s<°_Ñ
+ÒÝž/õôÓ衾tóÐi0>-®íícáv@ÖìØë©9€ñV¿dk9²r¤W=ZŒ(¡£Ìhð6ÆY¸²ŸsÝ i^_3Háu@’Hç“`)¢-… $k54ÛΑ5B‰/å“Y ››®¤ÕŽÃqs={¿ì5˜+I5NjFÛdCN—3¤ ‰Ng$9«äR'ØžhÇ$Z«©-“Øõ¬@–"óøµñî¥öÆjCfåDüŒÄlGŠL²ÁHI“äµÓ˜¼I’ e:lÞ'¥n¢1&ÝÞ›dgH*s‚dI2Îu€d„àwØ
+òƒá}B,ÿH+’… ˲c3G`œÒ˜ql
+Æ|å¸<%(Æ$‚²NÆÈ•šTé$‡gØ
+‡[C–‹Fq˜íóÁ‘–b`Œ$”$f E£12o(=³H©¼¸Ôxtœ‘i'FeØÂÎ1Æ9"Œ‚И^rÃ8sÏÛT³»¦“ìÕÑ×ËÍ÷6cŒQÊ4IE1y#tv/˜=Ðèq³gŒßöÌ„”áÜ"ÓmiÔ$¥ÀÑÓ>]Š/%…&§QŒ½²ûFãxAáVRzçd)"ÏÎK4ß³ÝùÈ=­ÀÖ›!ÁR+G[èå0v/ã,9ö¡•CÍxÈwÑ„°1FZdL`"[óþf^œQ¹U¼>ȵŠ™Ã0~#D€~`æ-›‘Œ2{Y–êÇHÁ¹6:C¬þd)0‚¬„åØA‚îO(FõL£Õ›îH K®„ØéÕh Êü¨O”¥šk§&ÕŒ5Ä–;ªévjX² FQ)•ã$Œ:¤XcÌUJ¯¦Q1Hf`TžÝ[Bc°û@ò<IåNj\©#FIJ/¡a,ݧôÆ råõeuÄ(6FQ•dv]!AÁ|/ÆE E§æª¯­49µ@%)‡¾¹†tŒÄg Èü§il—ùdæ31*»¢±Tv¯Ä°”á;‡ÍóGct•Æ1Z’×7£=4ž_4šìùeCBù5®x´›m?‡ßE²X¸çi•4:JcÞGúç
+NÌÁZS ûfCâÊ4Þ78‹ÆÃ
+º§«Y­S µc̘E ²1Y#äì–)5£q碞™
+Fú0’Ù0QN­Kò¿ïÏ´%l I ·NŨšœQ;^‰Ï‰õ YWøUHáµòFv/a×a>ö y
+18Â
+£n…€]¹íñÔ¸í×j ᤙ-îã5ö5z™=Ÿù$Þ?ÖJo2‡ÿ!Ùà¤a°øf½_¨a‰ÑgwO½Æ[ 0S­…,ÈÚâoC^6Æû&YaÔk #R4Ö•Ç^sùHï/ª`„’P1rCÕä…WéY?×]{5œn®`l&8Ç–ó±„<É ²ØK2ÌÂG¨a)¶HPbóGÂ7BjT M·ÁH¢ZÜ9 cËð°-9ŒÙ'»Ÿ4ö”Õ4²<§•‚Ó†“|Xb ø æÒ¨4»ojÚ±‰¦¼ cºZÔ;›åS!)¤–ôÎQË/,†oRKNχ/2$–8B
+K Š¶¢±-¶[È!‡‡a4UM-«.-'׎… ÉAÊ
+É9´NÃë$™
+Ë…äÈl;ŒŸ’|îWlé(\K>äÆ‹°Ž¤¤ßc,ò~Œ‡Âf ù%f§oÆòñZht™å‹ÿ»_óû“JQgAš€ä#«//†,6¬2U“kÈWÒGb¹£”V>H øQHžÔÙùy@ˆ¹SHž#¶ÀÞ_LÑHŠÏ'fB^þ
+ܤAÕ‚¡YRt©|*dðð7hä<׶~¼¿Éj
+¤’Øú…MÂÑÈðïÏÁzÁš‚– »f\û½¶¢¾™ÀP@Öœ¯<7ñdXïø;X;(€LŽÈlâä²â­°ÎHJýMÈòëXÍìnšQdñŽV£õäC[&¢–å|b¨Ö£t¶>qý”äG°+…°šƒÅ$!Œ­ƒÀdkžÅc`µ`ŸÒáŠQ@Gà:ctÝKÏjÞ× ½$ä…xm‚êöps­ÌêPsÈÛóC}äg¸ÏÌg!&³\ØF)½¸ë ±°RlÙH’'e¾ù¡àfÉE[êb,).É…$[Cò2†ZV—›dýâ-Ñ›"óíxßxK/ÔëJ¤…§`Žz õ®›Þ'ÚŽ$Ëêt)$}8$õ ˜Vãæ³{„<­èä ¸ög›i}ÁeVOà:mqÓŸü»uíßn€&ÉõÃSÆêc-½%Õ 7¡ñýÕRÍ+¥øJG. Ö
+=ÈR` È1™#à7©άC…ÕÒǧ@FИÈr‚èôjT’-òO5µd ê S oŽ5Eµ«µYŽd 9ÈNYn ) äšq‘–„ä*“êÇ’¯e1 ˆÊ `÷Ìg›äøgK5W—É$Å\0’¤àêî®û~Ø'|íÍ÷¿"YP’v‰.‰üšddçÙÑ@מÙìy|'â5Ш-„pöóð•è Å”8ð‡R‡Q‚œ ¾ÎxÊ 2Ú§’Ô4Ëq •B>?Çòj  HŽ5®p¤™c‹µÛ$ËÖ‚ŠzŸY\pÝã®Á}×û&[¡~VÖ´~¬€€¤´^
+2—²má·%æSÐÿ€äåŒÌÈq€ŒDò±ql- ƒ4Ÿp(c8ÇêjoVÓxé|4Þ²¿ÉJ²¯Ã÷‰‡˜í¦YC:õ:¤Þ9%ÖÒ|ðãƒR¬±õ¾‡-i1‹¾%|'«÷,)þQœ/°2}
+{ÌérzJeñ½'cvëtä¢ðß
+fõú05†å[AÞ‰iæËɇBÚ¸T¯9Bª–P¥§æSý›Õ:UÍk›Ž<=C5µjœ!¥Î$«˜Q;‘òå’žY|Çý-„>J,~&É?5ÏPJæ ¯á{_ïäû¾ÛAxÇæO×K5wWBÒP+X Ä ’> X"ä«ÂñO×Iµ®–Ò›& ?BÒ†Cv\húbßõ|+Iª±•Ù1YÌh7åG®-ÝÛ µ=Ý.w<Ù)·Ýw\‰I²Å•œ–)¨KIº’•ˆK@ ä÷:S~Ì>”²+‹¤ª›KÅ£Ÿ¬uóÐkÐË€]p×›êufWXS„á`u?Iȇ&G¾¡ ædõ¤Ïhm2»GŸý)ºÄAfu dÉÑ·CÞËdþÓ?Õ5$ A$Å×Sn-GWŒ‚_F¾ƒž0dÛa“q—c*G}®ýÍ¥L9öÈ(% s8lòŽÈC ‡ ©W©fôv©ß™^7A-=g’ó@Ár¸„üQÈõHº$.o$Éø´OãZ?YÇþ«î/ú_¶ éµca^j˜9ú²äF‡kEîXçÌOP~™¨œÆ)ÔÓGéÈ©ÔO¢þÏÑIE_RË2z}ñ襰|ƒÕë!BoÜÏb*òÇÔcLrC,e~’j¨ÈþÜò}’¸C½•e§@â1¿É“‘$Q÷LÈ5B>Æbj“”Ìê—Ä#£Ñ_ GAœð6e
+{œ±”–.BÛ“Í|Ç“-RãGëHn%öQh¯dÕLkÏ/î²B$Ÿé6È裆«¼µ×[ì‹Õú®›HR,,ÓV8e…z]D½Ž8Éò&ôðßÈÛS.•\7–Ö»7ȵàC#cÊF*©Í¦z=¡tõ™ÏE¼€”´\|~žPsk©\ze¡œxlœ”4 ß'¬{mÆÔf“„.»6jÂñq²Õ¢&Òò@2ó·è‘éY õ¢§Ú`OÈPÒû{½žn‡~ õ
+™/“ŠgQµ[pü0HqÃ6eôñ~GBð7— §¿Ý¯\~fäÚ ÉÛ7H)(k¸àÇrÿÖ¨éäÃÕŽˆ[†ôã¥ú{S*³C’°‚¬2üg^× H°’'z¸^¹m$¯ù»ôžƒ’Âê:–Àß’Œ•©^·G…×FŽ9-Så’¡9¬v^@us&»& ª1Ôc@Í_S~f!jz¹âÊbøD¾ù“ubÍ{ËÄ
+äþ°éüQ<«ÄC)ÃH¶± gò)8a˜O^ÇLþøŸÖ+#–^œ'DW: ¦¡w­D²Ú;÷ä 9û¤3â4Õ’,¦CÆ ¸3¡šÕ•,fC:M¯ÆX
+߉øÕåF–Û4?ûêsúyÚKl
+ÉT©êö2êGDdÙ!Ÿ'¬BLÉ(c8[‡"­¨n#$DÃTqèëý?’€„0h¼¼T Ùös ýfƒ<¸¥ß‘„À{3¾AB¥7ÉZ¾»ÚPpzžÂr)=RV¡ç™?8“p,'E&´}±I¬»º Èü,䥲k ¹¦Gë€2É]wLE¿Šöw³|{fðQ†B¶¾™ÏDo–¤è€AöK¦=7 @ä¾g®|÷w."«mI>–åCí„Og%Ð'BÍ/F±§þþÍêa}`’•§.ÈÌm·€ž§9Ø|HÚ0`!p@ÇÖ®ÀÖ<Ðè'áÌò( '@M„ûº5¤}QÑú—,§[lVÊo,%ü
+9p3|èI#êHPÂMÐìwç5Ò¡ôáF 7˜¿¦þ䡤á¸ß´¯áiEŸƒ¢­p­”p€±J·ãƒÈQnQ}ÒüÞfò‹È9Ñ뢫þæJñØݵÈ3!“ˆ{
+ß »¾Ò$7Z=öQó[±JòŒõWWH_»A†~{(ÆdæËKºf+=öžéÔþo=…¾ï÷p­×‚­©ôô\®åBBÍ_l $«ŸqÞÂÝÃGã¡D™‹L úP„Å.lÔ
+!!rMHõ_‘ÑoñÖ‚oˆ¯„šS¾‹=aç…æ{›¤ãŸlXÞI=ƒ²ÓóáG¨æL=:^-<7Oìúv—Ôÿ£ßý› úÒJÞ©YrFÛdaðû=À­QÍ ékÔK8Æ>•[0ŠÎE¤ÔE]ŽþjuÔ¿@x"ÿCM Jnˆ* dö>!/+4|¾FÊìŸÂEÙAÆ«ûÔª!æ{w{j\vîÕ¸îõÖxJ¡´Š¼Sè|¼ r³/GKÇ?cMõDÕµ•8óÅ[K¬–Æ{W»îíë?\£²ØF½÷”J'ÚÿÃYŽlȶö8s¶H½ßº¢æÊbØ ÷"ùw$DÜp!!Î.…¤¾W2½5[O<Ξ°\ÓÑ4Ù€³Pȃ“†¡×¦å ñ`¸¥šX3–¤èq梠o6|ì•üäOß٠װΘÓåŒû‰þ;Ðð)jQÇLHë›n,O¿ô”û_¸ãþ-E¾¶åÞ6ÃÐ}­Üù`—tìÎZøqè©$˜Ñ»¤ó 3-;¹
+³ïK]¤î'»©>ézá‚=`{€µãëÿ¬Ý”?°v=?ìƹ­`’§síÓœkÀ߇4zóýíJ÷ó½BíG+p`;´'´öRQ££—†xÈj$åìÞïÆ{Q†whOþ䂵 TßY*&wŒ‡ô=jMÔK´|¸rùâìö©Rº_턽»±|Ðm×~‹jßYœW#3쌈#@ˆ†Åƒ7ÄVйb%¿~
+É!cïgËpæ‡ÅERÊeWrúf`Où/aØ°G‰ýv/qV >ùðyjLþHêõÊ´QâX}j¶Rscü¡€$Ï
+ç}|’jÆûÆäŒTÓÊÇ‘þïGÜ[nðÅ.ãµ/}?üSŠxñ•ûTÜôÄ&ª×ÐÛ±òÒB`i…žov³)t>Û&5|¸V9raR88‹ºØóO­U`O{°ÿ‚„àYýJûBíÓ/G=¡oùb°r|D¾-^lÇldŠXx~pЄ–ÏocµÊñiò$âÎãÕœ["¿½1ÛP84¹ß›þ*Õ´¥sŶϷ©í÷(w ½_ýµÞ`íN¾ðþß±vO]€µÃ9LZcè1[$yøÊS ýÄâ?ÎAD˜¤ÂÓ³pF
+æ/€D•3ëMg>P§ gguÑÅYÆŠ+K€ óAØoÀ>ÊÁD+ìSa{CèQଂšßéLçÊoÀPa¥,Jª#DÄ £32,¢®!™røÔŒøÈh™ ôzµ†ÜÆ©jÙ©…8ß+ሜ¶ÚûÈ øS}ß·ÛèŒBdþœ1Äê;¶>؈ž $èÉ·£&Æú*>=ÎüÁ­º‚Õ8»’Ý4…Ö*°’µW—“¬äu›ÞSnï ±îâR®çÑV®õ‹u‘3s„”£cq&„#bÿO¸¦;« ”Q;Òùô»ÓA¦ì¾éîîØÔ7B*êˆúÈ„™,¿¼8pCéé…t¦çÀqvk§äܾ÷Ç]òÀ/äÂËóè| ðYÈËJ†æ°ša0.$—Ìê
+¶× ¡µ}TÔ”¨»ÓŽÇé¯cù r] p²Ú&cß{~bp*Å}Üc!<i8mÍ윂=ZÔ>|ÐÇÇÆ 1Åö@w£Nb” e¹tΠ³\ýÙjärFÏŠÍQyö´o· <,2ÍNeñäàé¼D>õ{éï nE/µäì<ª7*¯,"tI.γûg­XœE}”³µêê
+¥üÊÜ[ìYc¯žÐècbÿýBœñEŸ?`&õ…°gÊ|/í壇…ç±<CJ*M~ˆ$ì5ÃFk®-'\
+êK³µóz¨·)Ï­83{Å„goût|ló8/Â~Çb¹ä —ÅþöyÑÓÀyáèG«…¡]õíO6Èq•£yÿ:+‰ž"ö®±Þå’óó•ôöÉ„fIm˜€^[sh(£ŽæFhï?©Î‰PÎÌ¿©¥'Pì§ú£u
+}?,ßN
+-¤:£’c‹³(è£é}BMgêý£,Ñ[ÒùDY gÌEfÚrÁ)ÖÀˆS"åtMk?X)ÿrÖðc¬®7×1‹¼gs A‡ý²ôêq@;á\ŠTsg…鈘J¯g*n.ï¯:–êyæ[a×8'ê“ß9‹êRäÿÀ~°šX9ruöMý€þÙ@b©eW—H ­¥œyXJýxú sr—Q„¾0‹—är:¦Á^¤Ú;«€â¢þ%³{v]ç
+¬$@Œ 7VÒ
+®wEïê bOûŽèvM§ü‰Å3¾ëË­BÓí5´oUä
+ŎÿAÌQK/-’ê®-£(0Ó§žyñm÷7
+Gf꽪ÐH+Šw@¸ôü°ƒïþq»X÷Å\GøGœaë>^%$uÓÚ'HE§f ÝßìPú^
+y'¦s…Wgzµ<]áué¿vëoý§ž¿ûoîOÿÓOøðß‚ôŸÿßu÷ÿË_xýtùÇïJÄWËü#}ôK8®ñþ½<õÁ“LùöÏAÂßáÖ¯ªzûëpãͯ"|.>ö7ö=ÑZí6t<Ý'v½ØÅ|Ï&ÜW¾ææb±ãõvµÿ¥·oÿS^éøfR~s)jEß¼¶™†Œê‰¾‡‹}òæÈõØ;¾C¸&`<±O‡ø(žþÖS<ó«·tåIºòJ–n}{P¹ù4X¾óMrê[žümßþõ&}ßÛ¥Óßj¥‹ßˆ"»‡ÜÅß<¹ ÿôÏüÕ›¿ð›·tá[A¸øgôÎ+E¹ôR5\}à{ç³Ãʵ‡¾bï·{ôÿ/koÞT³î}O ×(îîîP£Þ&i’¥‘z¡@¡XKKݺ¦î-PA ÷R¨»+uÁáÙ{¯ofñ<çì÷œówïëz“k‘4iÊš™{n™¬ùý3÷cÙ}ðPG6GF¼ÙŒìÙqµW‡¾Òi€¾¯¥s»‘mr¤y ¸ôf M^iÐÁ3Ûԑ ÿKkSCßY`YÔ°kš‚üÑCDÞ>q³Ï»3b„ßúhŒßùÈ%K©gƒÐôSø‹êõÀу^ ÑmØÆ‚.œ~Ð,?l· vˆ‰»½|´Æ,¸ÿÕXXø•ƒ=ùLPE ßýÝ {ñ•¦+;ω+k]Í^—:˜=-=!)¨•’yíÆd΀>:7*ºh;Šl\ùþò£„.ì—P™Ã:ô×Ę̈´.-¾…‚‰å9E$A‰¾ 5}ûÎIú¼Ú^t·ß”.”Šou‹$¹¸$¯™ ³Ú D9ýêZ¿ôx’´¢.ß]EÈÊv²2¢ÑE;Pþ"ºçydÙQv·(ëƒ>‘Ù¯%Èý¢!LÞÃÏþv€ŸûC÷ŽÁømÌ1áÀçÅáôpïe¬áËI¼ý‹9ôÑ—úæ-- ·¸';Úu3A<Ò&êÿ,íi7ë­’éz™"iªõ‡ý(&Þ|µ ‹úŠËš/H_µœtH¤wÌÌTÙY¼*r2TvJ|¯^Šå|Ѧv÷
+¤ŽP·1<±~ZÿCkÆtNú!žôj½Ðüv­µéÍz)ª7‰¬nm
+Ù•]âN_\Øf&zÙxTò²ÅNXð»öè‹x:,¥ßu¢‹úŽ’ϥģ!Š~ÞmI½í:J}²&Þ &+úO‘åƒöäû϶xñïÖø›o¦ÂW_h¼ø“9YÕg/骼,é.ÕV¹’Ï?˜B"wTKï:€]ùtÍò^A=ì‹´™S÷Z(2·Ó»Ö£Eçtr¥j#û–>­:Fßé ‰Û}&ÄõcúN!¾ßjN?ë2Ço~5À
+>S·º0¼°[€=êÃñ—CR¢è«5UÚoOUõœ!ËûN’5Î’µ=§ñ#bòA‰bþbP„ßû Ä é{í4ñ¶ÍŠlî8G÷¶˜—G‹G[„íŒ=¿±Á[>;Í=È7ƒÖxþ'}"
+ÆP—øÙ¨.Cßi²¾æ¥(> õ*~Týþõ¿kÑ…=É»jG›Ç/%É:dø£õ‚[ßu±Ûß …¯>“Ø“Bû«†0ap§ õÛ^Qú¨¾4§3¿[wTú®ÄÙ´²ÄÛ¢ü¯YQ…‹øEÃqÉí6‘(·Û„ÍU®ê¢:€qŽÊÖ‡9áN±ëÕ¤†]¿ð°²o–ÄàgOñ§òPñhE(ýéCõK_ ý©%ˆú:t‰òT†íÌ•lÏŠ ¨MŠ®º˜p¤çV>ò›—x¨-üð‡û‰fýå2ñ@G¨¤»-˜hìq„ýiO¾µ¡^Z s¾kbY#ê’—­öfÅUÒÇGéׇ‰û£8ù´O,.ou2ë( W¶»ÒoÚíDeg$%µÎ’Š:w³º·Eåíç$¯íEïíÅE­§©W=6Ä›^ ñËfh5v’·§Äŵ§ Ï35¹Ò·W|?±a+ÿÎ?´ùO¼dè°¨«9@ÚW!ª‹õµ^¦‡Ú/‹û[CˆÎ.‚Š¿™ *þ0Ã*~±Ö|±%>|t¥G[%Ÿê"mú&ˆ?µ…5N¯ú¥äA.õ~3ñzÛ¸¿þѽ&zÞbcúªÚAú²Ê^ZXc-)h1•Þ¯³4-¨3'u‰©'¤Ø³>ŠzÕa#zÛrRü²é„øI§­èq·%VðÝ{8Â'aü¥^uÚˆkj\Eõ^Ò¶ÚËæ}%1G?¤Úu^O=Ò{?ÉzèU‚h¤>PÜQ ªlp"^™Q姨öz/³þ÷1Vƒ/ãuÝJ±oÏJ:לšäИwº5=ñXgnœéHQ9:à'løå8ÿáïÆhýG|&REäymžñAÈ1 ® ߆b—Ðëù"^ÆÇdñè³î÷–]E2óÆâ`ëžgñV=¯ãéº6aÉwsÎ}FCàÿ|)ßÊeŒ±) y‘ÇÍ%âÂ&KËž×qv]·ÓεfgÛv<L5m. DqºÝŽ‹òZMD…°ŸÞ”;˜5I_ל¡®·ñ$·;DÈÏPÝ­>Ç»r Í%¤”ûÇUÇ#´î¿k:ú6Jòé]„åÀC™k“ŒµÉÜ
+¯Ø»ž±Ùå¾qöíñh·Ö}…±¶]·$õáâáö«ÞWqdˈ3ÿc„ç~צöí#ýž¬$®~Ñ3{ÚpVò¤Ç»öÇ!,¼|#?¦n£ðù7RÚYdÓó<éH÷“dÓÁºhº£ÅGÜÛ|Ù¢¿4VÒ[B–õØ ‹?™
+ÿÎ>ëÇÉÒÎãdMç9a÷#d_“«Þ'q¢úJW“Â_u¹Wê·ñrFöpîýPã1†ü¶ßÚu\K̬öIH©ñM
+i¸œâÛžz¶=#Õ¦ï~‚äKM”øsgý©+Dô­3Īÿaì™ÖŒä£ùqæC£õ?Žðîü®EÞøÂvÂ8?¢K>\GE”lC¹+™ÛoÈÆÜ{úÌÿ®w`¦×š„’ô.*¥æ _ºÏû¨+~ÕigZSé#©¬ñ Ÿ ˜ s~ÕÆ”mÂÂßmàËÊ7aOG1Ic¥ï‘ÏR÷=O–öT†Š>4˜ŽVÆ8´¦¦ú7†¦ù5†¦¦×y'4†fJ:Ê.M]g͇KeÞ-‘—š/ÇG·øÄ_«ó”å6¸G߬ñˆí½TRRs9î|sB¼ÅÀÃj`À¨>I>1—<k9.yÕb/yWï(~ÖbKÝm'¨í&¢­A‚QÆ™úÚ{É®=?ùtûÕtûö¼4»ö[é’žú ¢ìó1~Åß$†¶Xíßrß3<ã—Œ7«oïêǽ¢ÒN‹²8«þ—qdÇ€+YÖ{‚¬è>óg[ñ•6™ÿÁHt¿AJ—VŸ6kydÛu'ɪûIìÑ®û©çÚ²²]Ze‰õÁ±nÍá1aµ1ת½dwÝbŠ"+[ÃKê.D׸DU48EÔÖ;ETŸ«k£**\£TºÇ\«ôŽ « L´oÉJ0~!i¶ì{"Úþ8%xÂðñûÿw¾ ȇƒ"Ñ£ :ï#Ìøª-Îë%È{ߺ²ÇA2ØF÷vP½ü$ÑâOÕ‘ÄÈ€ý¹;H:\e6X+#;zÝÏ`Ï>`¢· Ç¥må—$ÃufÃïe> áé!Í—3϶ç\µê}', ´îžp¤¯ épß­x玘„ˆz¿¸»un²’Fç¨â§È×­N‘ïàcQ“sdQ£sä³:טB8ï2k½ã²«¼ãÒ«}âjC¤ŸÞ†s+šU±FÇhÐ÷FDâÃ’{}–âwí§Í*Ê|ÍZJBÍ»ËbDï[O sG´°+CZâÜ6¡øQ—µä]«ƒ¸ÆäW_,% þ!5Á™žõ²LóÎ]Ôy »ñ› µy—0ï‹ùdPD·µúœkMÏ8Þy+Íl°ú¢x³¡²ñ×æ«þ¸ mq©)^‰ ¾©ö9é’áòª§ÉÛ¶§ Ù·-4ů981©ÑKv³Î-µn1á8½ªr•½,óL|VæWPá!K¬ô‹=Ú+úØBw·Hëë.Òo»ìÄN¢ò'qu½+š²²‹Ð®ƒã‚ªƒâ}«#½ê"ÓÊüBªƒS‰Þ/“7Œ€ßÊ=ýSXU`rbI@|v‰_œ[S,´¯´´ÈšËiGá¹á#£žÆïcîÆXØþýúÛv­w2#êBóCëÃòí;o]±é-Œ§Zª/ÐÕUg}#¯¡qBÇ«Z—˜›õî1ÙÕ^1w\cJZœ¢2[Üã÷$à¿ô{ó[“¡Øñ¿3ŽØ÷OžfÃOÂÝëbCj/'$WøÆ^+ñ‹u­?Õœ{º9#þh{®L:ð.ܲÿ™L2Ð!ùÐ*iï ¢ýb…ßü»!ýük˶ÊØÓm9™'ÛsS(H°|k5ð,žþØ}øÕ™ì÷}« ;Üs;Îrè‘̤›9fÒ>z˜øPïr¸ç^¢wsLžiSÑEîkÆ“óm'øÉ"Žsš2×=m'½m‹Iõï"|°×ýXo^bd«obR½OœMß-™É¯ÌYã^ÆÔh€3Ã!†6fHãQÆÒä+sÚäsŽúVçO}¯óǾ|ñ0î`ÄF±m«x÷]üý+qYû³úºÀ£wSÝëc3b«/¥^«òI¼Ðš˜)é¯ ¡›[½¨¦nQS­·d°%ütË•4Ϻ˜Ô µ‰)7‹}ã½÷ŒqjN‚>ûy¢t¸:Ú²¿8Þ¦¯0Á¡=-3¸)(Ó«!:õxWNù[ßE¢§Çîo…¾³:Ú¦ÿA‚]Wn’C{bbB³Ob@Sp
+ý©=ïûìŠ÷|sá72–œ†cxotQdâlÃðüùúeŒ¿÷û Ñ/µa—j‚²Ê|d0îÉn–øÈ*CbìÚ®ÄØô܈!‡Gü¨æ äëOÖ0Ž¦Z{<l» ’ýêÃRï¾ó’½*w‹)|çwç½7ü¬·ìé{OYv©_¼u/Œ±C%Ñ(¾Õ'>-õ½-s‹Ê…>«¢Ö9b´Í1ì#<J ¯ók
+NþþÑS¿ƒá›|gÎî½wµÅ#¡¤í|ä“Ya‹Klx[@ºè{U¨è{mŠ‡æ£ïd‚á_ Ÿ3ê·ð©ºG왕? ƒÝš`ûÞƒ`çM°u§ؼý
+a^”Y˜’ù> 1»Ü'.æ ñÕþ‰(Ï´þý˜éÇ¢¨ì¯¸Wп=kuŠºÓéy§Û)šúÑrÙ8ÿÓ®“lš–¡¬›¿,UœY`>Psá±>_;n.Ø4wÐÔ}±«¼®ÔGaï~¬œ>ÌsàoÍ“fiòsÁlÅÅ`þ¸•`±ÊF°tþv°fØÁ³š—kfê½`ö×1´°÷sø{ÆŠ~ÿÙÞ¬§T–ûÞ/¡ø½{ôû2÷è·•.QOKÝcÒª}âã+/Õ†¤úÔF¤¤½H¸ÍŽ©,©ôbBtù¥x‹Á§2¬ç—óÄР·kkTBCÛùˆæÇp8‡’±C>- W/ÿ—zî7” œ¯L3ö¸;Ë0´t±Aþ—Íú…ßaðÙkдRo –/Þ–Î^ÏZÛ0LÁ$0L€ÇTø“*˜+ÌËUƒM»LÀA³(õóÏ'i$.Ðicty_˜ü_gÓá¢Á¾`ºuÔWÔÖ îï±ýp+áb]hRòû€Ø¬·~²ëï|eÐ/Æ^+ö{\æ!{Sî}µÌ'úcÙówž²7ÅžÑÅåîÑ™U>q±5Iíí¡LŸ}ä—.ç´_†Î„ïɈæüÆ;ôŽÙ¡å÷Få€ØYnË^-°jåb°~Ãj m~J^ß?o–ïµÚ¶V,Z ¦)` ”€"{W‚íR€w9 ÿçÏŠð•I°Õào?)°¯M‚÷…“×€Í[E`,賎*ñ•½ ‘%>Ž•½ ”Å¿ Œ/½›X|).»Ø?öê[¿Ø»E>±/ÞzɼõŠyüÚ;¦
+Š»óÆ/þé[¯¸'E> OJ<“î—zÆ¿|ëÿî•Oüë"ï؈Ò@™wMdBxe`|Xõ¥¸k5°îªv—ݬôŒI«ô‹ãeÎé¼fvjÜž¡asA~ÓÆ`¶üTÖdzgñÚœ<Ûÿ
+¬¢ÇÿÚ†Ÿ–8¾?–{?ç¡û½6Þ'B¯:ÌÓ•–ƒyª‡Àê}ÇÀNó,yfFûÜënÞÿ(4¿Ä;&¬,(îxǵXTÛ·dÆ¡¼ Õ•0÷Š „bãm»òeèõür¯˜j˜³778EýÌu"S½-‡
+e0¿kœ»`Îìÿß¾W„Ç?·õ¯×P{þ|ïg»Ç°=3öÐxŸÊÎÞŸõ§Rø³­ãÙù7kÚV°vÏ1°÷èm%›Ìa?ãdÝq/òtmv¼ìýeÖO¶dÆ6ù¤”{Å7Á1l.ñJi{ç“ÞVî™ÒPåÿú½W<´Ï¸'ÅÞq)%q†£Œd‹šÌœ¬ÂέÿÉ/ü»·¿Úù?ÝP›Æÿ9¦cà}Ûþ©ðc¢òv°d•¬QwÛÄ©r®1 Œ?36Ö-·.¥½Œ»ýÒ?þåŸÄ÷o½SªÞúdT–y¦=/öN|Pì›Qì/s¯Ž‰E‡OMX,Œï²øZ_™UßíƒJÆpݪ­ÿv;~zCöœþiLåþ|o|w"¼O—› f*,
+0Uq9˜¢° L¿Ìž¥Öªy½GÞ(i¼e6Qƒo=`Þ"ƒñ
+}e #È× œü*ô­Åen²ö¶ó17aÍéÔgü±ÖÉú°rŸÌV˜òðß|%úù¯xæédè•P›TÇ­
+Œ}ï|³Ûßú_é.õÎ,õ»:På}e¸Ö+{°Á#£½Ö-¥²Ò#Õ]šÕÌΩ
+ÿoüã_~µå)h¼T•ƒéŠªð§©pQä‡ñS~ô%‹ÀLÅÕ@eìz 2~˜1i+˜=ÿX²æ~:ž`+•.·ƒÎ”ßÒ?Ýø cI÷¿ñH|{ïÙŤÒ"ïĪb¯ÄêwÞ)Õ‰¥Åž‰ïÞy%Þ-õŠ} ýé«R8ôz\¹¿L«‹ÑX»IãßnË_~ùˆ ¬gûçóq¬ÿçóipU•–‚¹pœæ©lógmsæóVhƒËx`Î2˜³œTçiƒ™KôÁüU$Ø` ö¹wLVÏlxáý",–Í[Þ]Ž}\ì%ƒ¹Y\B™Ÿ æ™ñ¨ö¸óæ/0+/wm|çû®Ä#¶Qfô±Øs,\~Ù¶½0¶Nû—Û…üä8Ö3(²ÏúÀŸsp›L3ågƒ9Vƒ9Ó7y³‚$`Õî`évxóÖŠÀ¼¥8˜½³qÁLUm0w®ûÞ&~<ØïÑ8Yû£Ëb¬-[ï^´¯Î My[ñÜ/©ùoJÙ[Ÿãß”¸Ë>Tx$ŒÔ¸% 7¸$Ž4º¥6Tx¤ œÔà#Y¶Ãäß3tþSÙmêŸÙãϘ‡æÞÏ÷&Ãw§ƒYcæ€yW€9“ÖUåÐ7¯³¦o€óo˜£¼¨ªì3T²m›¿Ú Ì_&K7Ù5`»Õ]…=á}ÓÕ ™ÕšeÌNÎGæðᦼ@”ƒ>é—XÿÖ;¡ŽS}¥[lW¥G2šsÝîY]u]Í®éï+=`-¥ÕÈX±Nÿ߶͟mìø¡x¦,?(+À
+ Î+8çf(,‚¯-SàN…‡ÊØe`æ¤õ°m[Á¬9;¡}j@›ä€¹[ÍÀ‚ö`‰¦;XÁ k¨d°O[,ŸÊïøu¦Z%³…,;ïXœá÷.::è]hL9̽ê`Û–{Ä=†1®²Ì=®«Ò=¡¯Ú=±«Æ-±ègüÙúäí÷̾9SçþËãö×|CþEª
+ª@uÌئ¹ÐgÀ×'È=åç{òóêøÕб›¸ úÍí`Þ¬ƒ`ÑR ,Ûv ¬<è–ëxƒZ^`‘š3X },Ôv«ù1`³éù=SÕŸ0k¸Ã̺ïÇ™²ôPߢ˜¨g/§Ö=÷OozãŸ]Tä‡j†ðªÀÄs­É‰Å°Nh®re×!E_]T¿Ã¬˜3gÓ¿ËÙ\ åˆ0z)ÂX6q1ôýË€ªâRèçA‹œÉÚ¦
+¼ÏŸÛ·Ìž¸ ¨L\}#<¦­³f@ÿ¿Ì
+ß“ýDNÿ×1û™ÿçÏù’Ÿ¹ðx8Zá\›Çp{ÌPXT§nbÇJu´AC0Úá­°p3 }
+Ì[n
+6‰`û‘g
+[#{&í~ÄÌÕfÔ´>0šœQƆ;È£†ü·ßŠ²kʉ·ê½cך›˜ùúRbڛˉ'ÚòRÌÊb½c2«ª.D Õ8G&—ùÅê 1ø£SÿkÛÆ°í™ÌÆæi@•õÙœ"ûˆrä/g(-€9È|8U²:ƒS6€9K Á25˜Ÿz¡x rhæëÌ"µgÌj”Oª=fVíOÿÛœ½²A•Ý}Ó÷xUMÚsþñ¸AÕÓ50k52&Ÿ˜Ó¼OÌIúKI€ùУðÓ­É2TÏ¡šåšQíZì÷¼Ô=¦²Â5º­Ü-v¤Æ3­¡Ü# ûÒæ¦åY®‚|òïÿŠmŽÿ3–#ûD™±êØy`þô`é:C°A÷X;ƒU6Q`½ÛÅ ïÇl *¿Íïý¸MçŸ(nr©´# jÂŽàöI;›'íp/·Ó©hì^¿šÉš™ šÌ~µ›Ì2õ°öYZùÌ*ÝFF×°™u1"£6†Œ2çëbP΂ڕ sgÏÚ¨.ÁúÆš
+lÄÀzì"Ø$ŠÛŽ]WØÖ0e³@í%ŸZf‡f-³ù¿}!MÓwÚæ(lƒíÒX¹=vוxUN9Ø¡¢‘ðuþ¡ÇÌV˜Ÿèþ˜ñŒ:P_J| ûZ/¤bQlÛj^DÉjüî<º¢ÿ¬èù·#øí?8Âì¿iPùÿ0=ünN=ýlNJ¤ëmÅo;N£ë8%Œ‰º8Da†Âÿ÷ÐzšiÊã–À\+X¸˜–¬3Ëv+uœÁ¾?X¯wl<` ÖmÇÁªõÚ`õj°~' vb!r»Ï>»çBÉͬ¿/Õ©c´ šãAÆûòÝæûf”èséEÁ·oNÂÏ?\ ;J/ç×õé}ë o0Û+·‚!ø5Œ¹°eä$ÕÚèF}¨÷¶|oÙ÷*Nô±;„hqâ—3aí£To§Ÿo]DjMå…¿š°x­´Ñ%KïüìRUm0÷€ó ¶Seâr0oÞN°b› تkva~`îöOUÜ]:]í³VçÃç1£gDŸžza¿Ö¸˜üãëáïõÎü?Úœ8¿3Gu¾3\ÝÏ ßð;#1úÊX‘ŸúüŒû3½Ð·ó íbÆëÚ„1*f UŒ'ÿÝ<Ïë³¢gØëXפÃ=w϶f¥뾓ÊáÒê˜õb‹8¿'ŸŠyYŸvèœK¸|Í>¶NûŸnSà¸-TÝVnÀ<÷Øe÷ZiwP÷”½Œ*´½ÝzŸÜèWÆÊècmðk¶1{5ª˜mÚýŒ¶ñïÌçÆY~•gLbÌ«>,F4úÊ­¡@ÛÓyÅìÒ}Èl׫bt¸mŒ9¿9%ùÃUü­>Œúòá’ñCFczL^cÛn` £ Ð>Jt#–ÕªND¿Þ"r¹2_|"j:íù`‘û»!ý`ÄÏù¬KøÞZ"pÉQ5´ »~+Ì›¼ü¿­ý§m*À< æXSWƒå;h°Ý4M~X—
+ò‡>³óÅ‚÷±ãýÂØs>1Ö†-Ð42§ŠÁŒÊc^3c)a\Lz™ãÜ*†â¼`ôx²® <¿‚ÜÌþí‚šß­‰¡/ÁGƉßÅ3Êÿc'/°p1?¥qž÷Yx4J *¶`‘/Öc©/wwLDJÅ’ªWóæ·!ô“^s*mô]³‹ }·‰|ÐFš·½
+‘ôW…r+rË>ül×è§*ÌÓÆ-
+0®ÍÞVí‚ÝÒ9õ¸þ¹/˜õZÍÌAƒ_©ðÇWü._ê·æ ó‘—1è»?j¸ÃhrÄß³Æ^ÿ&&KFOˆ[}%•ížÔƒ1v!m–¡†!Ðß» ëßùÉ•ÛyOþ¡ËK.ÝÄ?4íƒ&mÅr‡uˆ»CaBý¡GÒlÊ?}¡8(k%•X¹ß4§‰¾«p6«,ñ—¾h<Av‹éüN>–Ó{K¬Ø!¾¹Ôðlì$ô}Û ÅÉìÚÁ?ßÐXΚ¶,\«ÖÚƒýö·ÆºÇ¬Ó`X_Akt# eÔÇмÆÌøößöY»+é™=-0á›
+3“·8æ2ÉÒ;c%_q€
+y¸cÄ»–Ì{—Ïûѱf.ÐÑÜ°Ä¢í¢×MG‰§=” þíülðTöúóü!#öšècîã K§1ˆ%K§÷hÓ}:dÔË­DfŸ–øfEÖõ•´Æ®ýv‹z½Ap÷«^<jM4:p{+FCír…òžÃÙ
+»ä*î?’«¤q,¬Îù‡Sµ½Ÿ¨èå~Ý@ŒŽø kq<ë£R°Á¯®Æ÷5^Bßf^ö—ÝÜûŒ¶IÞƒ&ŽIÓ÷ïW›Ï[çÍB=]`qâÔ› î3­Ü.ÎEûÄLî~Ñ&ÞwÙŠkjÜ~á îþb ¸ù«¶0äþJ¡[°2ym%~§•Ë^£ùbÀÒäÎÚ‚àW+ñ Ù³…–îc–JBÛÓJì¾—Ü>®Ù“êS¦EMŽØ‹’W¾™òx7kt''uh³×ƒYšbOùÍêR°Ææ¹ëÔÀR s°Ý"JN#¼AU§€Ù û†9¨[ûÐïg¬Ôñ½¥¢{6vÇûê,“ˆ¼%&!™ x1·—s³·sóö
+Â^®Á\2gã *”sÚlÂýúÂåÆ|âDðd=-} ½ÿ àÀxÅç±Ä\^(5—'|’æ Š·ßn¤¼ÝŽ'<Ú&Ly³»6¨EÞï¢ðçÝ4{]ååä%¤wú<oDWò´þ¨ie·eõ›ÓŠ2OIQý9ÁõQm´¯s™Áu¸4ÑÀ7g¦Îå—sZ(¬ß‡™“•q°€uèêÍ\ áY<M»9d0Àø—>øð¯žü7 irƒÑày$Í09ûÒÁ²0êéZÜ/côŠÄ ÿIˆ)h¬® tvì5m@“ÇؽB,;Î'w™™Sôlš+
+VÊ6g=T,NyN“º„ÍÆÓÞíC×ùқͰÝ|,ÿ³.?·ï ðbÖ,8q«‡‹®«Þø¦ÃOèÚ&Lú¸ ¿ñw#~|ÍüBš*vÂu<á3SÙ²¸1b„åèðÓjvð£Þ¬áfõïä=`txw™Cœü{Œnü}§Ñuf»Î[f¯î0Ã1ø…ëŽ2ÆÍŒ‘Q)cÈyÅš”1÷%chþt±ñIÏ1K{‹“
+úº`ÏÚE@s×.`Àå
+æ§]¦˜ùd.7÷Ë[ƒöI|¢æ£=ŽT^—‘yAíÑÝbAÞg-¡{ü,ÜïêBaöGu¡¬l æ¯"82IxõuIQûY²``÷º\HQEû™±Ë7–b>)sqïŒùÂÀ‚e¼Œ¦í¼‚Z&׿ª™$Unæ^ÙÉÉûº‡SsÙ†kRó7‰IÉßH£û¿ïãú_ÃõŒSá]ù¶0Œ›$vnã¹&¨/¤Ì:FNçÑÖrê;÷€]+Vƒ›w#8ïp[qh/béIU‹‹~± ÏïÓÝkÑ÷iª  oµ
+ˆÜ!},úáÂ+yå=“rϘG¸&C›<»”½ÍCþõa-ìm™è]ÃIìág>ÿú7-AÎG5AÞMâá
+]AèÓ•ñ)y¾¥‹’Ðì¼"?*¯±WοM@ æ#¸CÐ4aN¯š7ÊT13·˜´°W”:„̇=ÛFgÕèᙕꬺƒä•=Ä€Þ®“òûµð‹¹‹ øÙ¤_ö"´× í§._Y†ø<–ï^¸hÉK>Õz-Í¢¬ÈGtmˆC†<_O\~±»:¢A<î¡™û…7?ëbýÆxhÁ*Ü-ræ™8›ï–6“xg7ªt×隊¾ô¼¼vBÎPì¢ÀÅäxVrB‡8eþ™È)j°t¬
+˜ ë¦MÊ Ö¾C@kï~`lÈe9Ä\¡™&9¦Àê✺4Md}\ ‡mEú/ÒSwKrÚ{
+}ÊmÚ3LåÔIÔXŠïtH±¨7….i³0Ùû-üœauÜÿöR¤ÕÅ—Ç ­ŠtYˆ :$øÕOÚ¨±è¢M„OÖÜ9B…¼”¿±±‡Ã&Ü¿h›|Õ6¹ûýIþ—ƒ‚àÛKù~7\“g
+OLDãbˆôÇx"€öæC[Ÿ…>X‰ ž‚ì ¸³í+¹0Ææa\ Š¯¬ùxRó^2¹]q³ψå ´áÂÃ:ho‘\³»Úªå´k¡ýâ8ô)„WÚ|ò|„
+~>l:~A6C ã| ­~·ÉõauáýaöºOJ<ï“à¯ͨ¢îÃ؃aÿöüé°ˆãWMÌ΢1e.Ç3;¥€öoṟõ%O›ŽšV¿÷––Wº/%¼Âè1nèû庂Ã`½êr°nò"ø8è‘€o{aŒàè…1&–§1ëócÒsŠêšÚà ôŸwîeõØ°³ÁS{ω|sy+è“ŽÄ•YÍ([çñ”åIEÚÎq<b%Ðy-<ñ1QÐk‚$ÍÇB•ÙM{‰«}ºˆkHœ™N»E¨ÙMZ’'¥6–%O½mëîE›½¨<K\ÖE{Ð(ŸÛK YÃ."ôþòbæb<êÕf"ìΘ'¬áç}QçÇ•m2q‰Uæ{_›Ë y¹Lp6qº–6¬¶ïûwj½zÀ˜o%‡öYòŒß¾rX6aX>Y¬Ÿ6€ùʯL½Ò—ˆ"înB{ò$—n k˜䯡ÍN*ò…4 ¥ÇY!ÒÂ8ë?Mä=Š}¸ÈxP˜Q³æÒÐø ’j·
+>ëSwpÁÕŽHG84é.àQO7b)Mû°´¦}ä•A=v®‡ÝYM\º²‹¯ÜAÞê4!îu
+Ñد{ÌÉ·Öøã>ÆĽ˜oîÁqßñ\ü˜¼®tÔ¹€‹8÷¶^ãðÓÓp·ì¹ˆ…ÛxŒå¶ÐwœÇÏDO‡¶°ð…GØÛhß
+‘7bH¬ÂŽ{ŒÇNûM"¼2a<¿óÁ¸Y„³ì§ +\‡¥Uí#2Ú5‰=†äÍ\<·_›åmßîã÷úhŸ†0£m¿0æÅ~þ°:Ú„jYtÍ7ñ|X*¸2z€ó~?ëë>tþ¸“ÿTáI·ñDðÝUÂœ ìê¨&âfb!wVb÷Ve¥›ùYý{y7¾« •u9æ`ÛªÍ`ÃŒ¥`×òM`ßæ­àСC@߈éÁØóc
+p §Ãz<À³<© tŠVFìAä_ÐmÄZD¬?·”ÇøÐ÷`Öò¬~\ü›TfÛ!<«]1»1{¯‰DpîròzGr«F„l— ÌYFy&ÎEL,úF£Pô IBvˆ‰[\,ç£6–ûEí Óê÷ >¤½#çàÁW— RJ··Mè§]V‚[¿éòC_­†V®çeî2ÉÚ+¸±ˆgå¦Ä£OÉ­äxç1ûˆ)ü£®cölÙ6-\ öíкjFÐo
+
+®Áb_lÆ£Ÿn$ò—à·— ®öÄ
+8DA?»òE »twâe𥧸Äy¾™³"v,p¢ Òm ¡¶÷ˆ˜z3g%ÄÙCüGüˆ÷8Ò=}X¸‹o܉ì 1a^±82?8·óœ€w‡Ø‘¤ß­e”–=ìäÈG„é{ÐÞJÿL%j­è‰ôeÍIúMÓ¼`ÀD˜P¾„±_þh Ú›ˆö¯oº-ùù_5îiª‚³ÑÓ„>Ùó9ßÔyÚ(߶©)Èý¢‰X`Âç•ÐšWl%ÏrZ+·ñ3wáYsMÌœ5÷‚ýë÷€Cûô ]òG€ØR^h kK{ïI¸½ËþáÓŠHƒ’e¼X9*áN13¨à'ëÓq]¥ŽÑ³Ä‡Æ™v/¢¬ä%‡ÆK½³–’I•ûë ±1p÷U<0w)–ÕrÈhP's; Ð>W*äújÄijZ5D7Ä6¾ wPƒó³&þxˆ·ž½h;BÞèã
+r[ÔÉK9ËHϘÙXäݵÂ[£úìÞåÇýbaÁ°îhØ*pŒžŽ9Æ(c™Ã…ÙCjxlévaÐݸGêÁÅûK…çT448`×Æí@ç€@:žHëK €0ö¤Öò,óÃÿËè$Ž;ŽEÌTÖ.¡ß$£ 69ݺXVåÚÑoeï2‘öKX€Ç<ÝDF<ÙˆËàÿ—÷Q[p­WòJœG\ˆœAùß^Ž´6p—¨¤Kœ*Š“¤g–©sÖƒça.î{ué‘0‡eI:ÇÌÄOºŒÇOúNdy;AV³ӱîck}íÃGŒ*Á—1hŸ4âíQAÖÐ!Ï6âö¾“L0+9ŽÀ {ÆNøL¤<Òæ¡ù"Èÿ¨%¸5¬‹]ë×ÄrF´…í¨K·W"¶;âÙ]Zˆ±†ØCxÂO†5–×£Kåt“Bòq§„xÔA ® káÖ!wÛ°;CÆØ­OúÂز­˜{æ´®&tŠSÁC ÏÌl?€r,¹~Ú?Žxþˆ)ùfa§€]ˆPAk¬®¸¬dvØwœ. ë `dHêlÐ4êRöRĦ¤|³Á¾œE™úXpÜmœÀôœ"ßò„ÒìÀ“kö"­Ä…ä­¥"ŸmElÄûd×^Y‹{”eiÃX!H*Þ&ÈjÝçã^"îñ2ñín<µr}¥Þ@’×( ²«t‰+µÚDî€~»—C=é6¥ëê]¤eÁÒÆ÷~hÿ½yÑK'êA‹ù\Â=n6œ»Û‰ƒFh/.~ó‡¡À=oŽ¶.îRB»àIDF¯&™Ó«øb˜Wæ\a`ár¡C¼2ÊEu4‘f«)@|–»’Õc´vKŸ
+™Æj=\ÍBLy¤«„ôðP¬“>(=Lßj . aq¾0 1ÑñëC‚kƒˆm†%4íBã‹XtH³€8ëÊS§^éóga}AB_A¸ÊfQÎá3×ØY˜¬§ÊĹÈéô ŸIø)ÿÉ8ŒÁH醰: âò¤SÔ ´¿ËÖÀ²»ÔǃòI_Èj…Á:'±tÒCúxH—i3!Æéà71\ˆ›ÝFôÃV±øn³„ºÙ(@5bF£µ–!|c5y1}1b=á²×[{iƒà°NÂóGô±üQ]AfÇ>4gÃŒBú3§='Q>É PÞ‚]í?DúßZ†twM`-ƒj2¤D^[Šl14°îã9| ò òˆù.<ê8FxÌcî¿ÎmuêÒÝUž%Ð>¨ ŒLh€Y:(Ѿ) Gq€ˆ^‘âö' l”t )`LÚÊÁ¾X€ØCˆéŠ›ŸVD,’åg_[ƲTÐ㥼•t`ö
+:äÎ:–•tgûr «)r¥GW|£³¼÷ÖÖæዳæwË­©ì}–GÇšºßFˆ‹›í%]—Ì»Š"Ñ^9Ä*ß®'Ѿ|¤Ç ”=Û(„5ˆ0¥|— kà€0äù*þQÿqZ<°Ýn kÄtbãæ)¿IFHXrRžgqVÑk ý¦% -Æ ö”UâÓ¤¢C,;í˜ïDÄŠBº%ˆ¡O:EÎÀ:ŒEq[r¯Zjq¿üõx3âÒ!¦–øzQ0Â'î~ð®~ÙKø,C {"æ”ÑÏ6“‘*&bk9”ë‘7—¡8‹êjÅ EÄöÇÎ\šŒع°i‚ÐgúL$í ¯s R¦oÒ9q¶ð°£’±1ŒB
+ N2«±í éX¡µG ±„`ú©qš4éPŽ>Sé *ˆËˆÚ…tP‹›¼±
+ñê` ÓøÉȺº±înËŒr8†ˆõ!Ìj>ˆôX-X¤§ójÊ»¨»ì8৽' Íl0³ã?ucÆJaJÍnÒ1~Wd'oBBßHXË‘6ÎcQ !ÝçàSy¦v¬†´ÀÊŽí¤yfbvTžålød.@1å( p‹SJH¿Ö)³hϨ9H Ås¤ÃŠÛ¹ŽGëd<ú˜<Ìä„V.cˆs¡Ó‰Ã.cÔ1–SD!V¾{´*xu9¬ÛÕ7‘¼Ò¨GdT«SÑ·°Ì»ð{f'Òî_oZ<sÎúÅ3'Ó›5R– ózš£ÂÄ7ÛQ,§Ÿ·[Ð%'Ñ>=TÃ#Ž+af}ÙQÂ1ÆÇôùÄéЩh­
+wI˜…j#¡¥œú~#°gÕn ­f øVç•{}X»jéñ`. sH‘-«¿ÍšË!&7âO#~)bÿã–g•øayÜâŒí6ƒ¾µ
+ù@ÄmÂcËvHn6Ò’ëízo=Ë.ôK^„_ï1¤wšâO¡Lî0:ø¥û+ظƒôÉ\gcGÎ*ñø
+­Î)!­ Ê!šÕØD6†æ%²ÃŽ:aµ„ü2g¦ðÍ`~ýbÿ°Öcc¹c¤
+b½‹}ò–±z3¾‰ó‘î«éŠÚëÄJGZ]#ÞqæòTâ|´
+«aà•¶@|ñÖj–'…Ö9cl¢³jtÄ×x¢ôzRöt+²Kè;sω„¢Ýdz…ªE9,«UrK‚ý=iÊS[ö`¹ŸusBÖ¾¿”·„öHž‡ÎMÿœO$ ŽùOÄŽz7ÇlœÆ`ÇQ_8*és)Xóh]+w€=vm Äå´ã™WÀ£”‰Ë7—¡Ó'±TYaÇ@e±[$Òô̹@Ü'VŸ ñ© E×£ ˜‡ØBTFb1³¾é´Û$aZÕ^–ÿóbÐœxüI„%wíEšc„}ð87ä aíel‚dƒxv‡–0æÕFä'uu…@O Þ;Ža3î«ã„4™¥æòˆwl‚‰€¶G,o–}Òue~<f~N‰eÊCH%ï—¤¾Ö¤#mBvMØœUB|02¾d™V¦†¸_”{Ø,6×J(Þg”ïG: ¯¨yb¿ô%H@\°±ñ¤â=âÜz>žÓ«Kœ¹8Ehq\‘Õ9HY*
+Ï[‡tÉœA"oÐõÙm,‹)àúrÒ6`yÌcçŽâJS¡O6àÉ-ûé¨Ê]ˆ‡tÔИ¡µ4Ä&"¯}Ðe5O¡¿!ÝRç’óØ|=ìùF*¥CÎèÒ•d´I2šŒˆôêƒH Qä:ƒòÍ\„X†ˆ£‡®g@|cÂ+{›s=XKÆ–í¤Ó>¢³º $Yõ\³ìZ¾èJ!â'¹¼Qä“´Pâ9WU¸•Ì(Ó¤S+µ mîbs2˜ÛW—ÀX·†å霂41ñ´–dΰ!•7hŒÖ-Ð:)âA™‹Ø¸úéK×W õÂ#¡ðÄ¥‰¸C´2f2;â<†KšËi8öïSè;!vXi¹#‘ÞªŽ8¾lÁº–Ç'nm§„4*ÄQ/w±hçB”YmZ8ÏQ_ˆ³kŒÈ¸÷»iϸ¹ˆ#Oõ›Â®wú¦À¼ËkŠè¤óø|!Ëë»3Ä%îâü럵—ˆˆÉÈ…±í§Î!q.d⤓—
+V!߀´—ž²9¡dê;_ꙶXê·
+ˆYÄæáw×¢>D¶% NÈ#]>dÿâ”zmij«¾8ðÁz”ÿ
+)k9Ü\Ž@qi^!­—‰¨B¶î¡Ï†+#Æ%ìï1H×Pœ
+û+¥ÕPød#⨣ïPÃh[yÒü”’ø¬ïT–Á÷t‡$­Aß4£†ƒ˜»ˆóŒôŽ°lèÏb˶³ºnió;Oí<€G½ßBÜ_I„½‚5UÁj2èîìj‹ºäI¥å‹’§•Gø7FµðȉðâMä…TÖÇ"Í9ô=é¶
+VžåÒf/Dügd{ig‰“›Ñéí‡X;†sœOÚÉ ¡m!­yô1Òj¸6åÓ"ŸŒE蜨Ãã)k×±H_^’ÔpˆÎèÔAºøaôùãòÒJŽÕoAšá¹+‘a9ˆ¡ù먘§ÛEiuÚˆ«Keuê"Æ#‘ÚªcËÇ¢þîü¼ÿàÎg÷êH
+Û--‹_yŠ¯5qÉÐ[kØuC¤óàwmî¥Ì®+†®'â^ï@ká|ësŠˆuLüÅuIV9ºÞ
+圬^1ÒÁEšˆbyØŠÍõX6÷‘Sc.«Wƒô ­ÎŽÙA»96±ÏE×ÚYí,Ø·ig#í,˜ßÙ{M{ÇÏGÌX‰ Œ{jg‘Çý'òal|HpÊJž”ÀÿËÔB²´SB¬eR
+mó(²×eVÆ1vMälÀTÌö¨"ÒgBLo–{÷rËâF:[0N£ÃôäÅiH¯ÎÔ5r®ørÞj:¦h7…XÜAy«þ•øZ=åÈè»,ÂæL'ü&Ò¶?YܬþPRÍ^–3‹4ŸçwØ ˆY‹®Gcõ{í.Œÿ¹ìÌj|HyNBÚQâ“®jgE/ s› Ñú 刴³¤€ÇEz&Žc‘NúÞ é…¡8$¶;?áOí¬ÙH;‹å•þ¥eí:Nê–¾Pùb»Ô'¥Æ3–ÃÔ{«Ûå’4—ÕPt št,%^²ˆ¥/q…¾Ž«ÈÖw"kß‘/w¢ÏÃx8õçç½~~Þ-sbV#û&OB[=qºäröJÓ´Jó”:[7eÕýwÿ‹;½ÿß¹óÍšˆ;/}Œ®½è¡˜†44Ån)óE^Ù‹„‡ÏAk£ÆRç”QŒGºYÌBŽ‹›É ‘ŽšïõetTÕn”çÒ.sQüCÚ~¸Õ…1ÂLŽÏh'Š¬ë¿©¬»£ÿt±g‰cäO½64ç/ß]KdµBºDh}Q
+8Ú|_läQ|’X;“v/±u/²>7–¶q‡|4Òâfõ©=b抽 ÿIžtâ=«wû–Šµ iü°|úsAÊ(oÃ\úµbÙ“]¢ðÛDÁ·Ö²šmþI‹ˆ«u:èÚ´VŠXÜ”C˜2ÿ&Ò7£Rë4PNŠÖ
+PÍŠÝЧ¢_mCzóH;‹ƒ®•¤Lå‘v– 
+ÜÜTŸ0¶h"[Z¿±…j$DÜR8Ž÷"×]Žò:‚·jרÕã”NÁ¬¼3ÇXú“¼>¾jš²ªN¦:Ø$Š•¦
+p'ç7,¥ÚYT¿ýàyþ-ªÅå=\Nµ³ó ¥eˆ¹(¹jòÁûƃ«›jSÇVSí,%ô“¡Ö£¥ügí,×?µ³v÷a-´äÉ-%‚Ûy¡\8üÞÐß
+ò@®FóϾ
+k­-›EÆ\ArrÛ€>x±©œ±PmÕ|“F Žˆøƒü ï‹t§åÛþ ÈÃ'œ½
+hsn1†›e ð6ç°‡øãô1R|õ4hùR\Iâ¶
+-ÒâÊ&aý‚Eîr´YŽ{ÊE•éqN~ý,8[M™å6MÄNŠÁéï“4Âpǘ™oÕàl|{+]¢!¿Uú¥Ž†æ |2Ÿrl¦TþĈò c­b{@_ø|Þ#zb¡\éªej±UÃ{~Hì–BS}Kc$‰kTg5O’·aê¥=ú%U“ØÔóàÖ_Šœ‹Í<?:JŸ¬ÑT,(<âŽeT>õR⩹"ÉU¡ƒúf¦pÒ°*CSÓ/,‚öp
+é$n“ xŸêØ
+ÕX—Â÷Mêyß²oa4„ubõT>íÄl.ïÚRbcËøÌ«³ÐšUâþéxª Eìž|°
+û—¨&Qâ…9Šì‹¡9M9Úç@rYÔ¢8{gmhmá~ŠÉçærI'g¢–Í9ö“+Ý{AGkèbÔÑ©T…®õB“ª`tÖPÛF/™vuÖ¬¨æ!j˜°‹è³3¤ˆƒúСV†”èaÿ ¯¾Öƒ-é<ªš¢L89vOÇõ&èq…å‹ÚµPÞd@ü÷Þ#DGpðëÇmõÐ÷¤Ä¾îÐscåÑfQÜ×lÂåÕÿ@5{PC ºÓ§çqE~ä ü$ÅTO¥šæм%˜bÖÄ£Ó±¿>@ É ,.ëâBž¶µò¼»‹±¾‹õfÚëè1€Æ¤„Ã3àç¥D§d}£ /Ò£kBÄ¿+ò®-–gŸ‹ûuäó¢‹&ô+¨¦
+‰+ÔçEaËTª„ë&ø‘Æ2﹤ÃÓ8‚ÏIÞ²xÂœ'þ‰àPÖÞ¿Î{ϸÊöMÐ
+Ž$†º„¼³GA«P„–6Á£|bñ¡GfÂ&IÎ5koð/ЛÝ|p;£‰{‡ aåÄG£u>’3Ñ|ƒüîô¥M Í3 9Üù.î;pÖ[yb³üŸ~Ô¶¡1Mî™Vü-öò;üûKˆç™ç¯@O ù ölI‘{'aïæÎëÅ¢WŽ.rgøoàHª›î?Œî9‚¼WÊÇFÐ8½WâSxŸL]h:S=aìW ̧šÝ°tnQ£õNµš¨>7Ÿê¼¢fBp(æ8Ÿz¶ÇAû”ø8ªs­XÔÙÉ÷{FìŒä'ÀE°A’-d3/ÏÇ8²ù——Éä=ÈuR=1è‡BuÔɽ¢‡ÒµR‚‰ Ï&V<5BëEð6öÒF‘û{`
+´è¨^ÖéüâG O‚væ6½ð)§fÒýÀñ‡&c¿+t¡Aˆý‚˜_#{ ¥ .ú–Æ¥Ä㳩&8¹f>¶d"µÓ¸ÊIŠ” 3‰g§s^™#€çèµaßKÁƒå˜OTcËÞM:áæû;’|aÌïaÄWu*’Oeí÷ôFð;}èô80ÎGhºF¢çMçõ™¹Ý_¯Ç×ãëñõøz|=¾_¯Ç×ãëñõøz|=¾_¯Ç×ãëñõøz|=¾_¯Ç×ãëñõøz|=¾_¯Ç×ãëñõøz|=¾ÿ?úúëwl[g½ËZ‡Û¤£¿zóbKò³¹õÎ]¶:Æ:ú–sW{ìZç`³ËÁu‡µ‡·Þr<Åm‘o^§·\oÚko[Ëy–Ë,§ëý 7mõæùó,ÉßN×›E^:o΂EzsÍm­õ¦õ¼©ùµž‰‡ƒ½Ãò¤…µ³mÏK ÙK—-û~ÎÂyK—è}?oé¼9‹,ZªçòŸŸ^´p΢K—ê9ãéïéxz1}Á{úÏ7qþŸßÛYg»«³CÇLg™Þ´éz«#ÿ§ïÈýø÷c‡çÎí¦Ö»Èùïèyr-¹€ÿôô4ùŽÖ.¶Ûôè³zäi½%Óuæé­&n¾±Õñ$_æëÍ£ÿ8oòƒùÆ‘<µGoþ<=#=Q9Oo^o®3ûûyóçãDç÷\?9á%ß÷ü¼åŸ^H¿nùÇëÿëÏôõ;þããÉ÷žqÞààl»¼ç[z5_\û|=n£ÎÜu¶»ll×ñ†zœ±ŽHÎt6ΞÿÉOô~.X¼`aÏÇ(õæ“O^²
+̆u挡Ș˶kXØõF§Ì. ·Ìο·ù¶ÝÚ¦’»æúÕ&ÌÊ›˜ÍxÆXá¤a¬r×4–9in0à˜u«Í˜ML»™*·kšÛîÔ6³vÓ’»„ö—9Fö7±õÑ64·dŒL¶2 ´²°ÙÕKfÞÇÜÊ«—¡™%ýl3%y fýÊÍä«9cÆÛk¢¡›ï·l±¢¯1ã4vÞ½AÒ¢ôI 2&Upþ· @/% v€fnÚ´³3a(gÑøŒMÕh4U†çM@ =[Ý{‰hü™‹³_ÞÒæÑäóÐpŠæ8Á% ?%× _EGŸ~¢ÈWÒG(‹’®àõh®ÚîÕW°ÛÙ[µ#bÒƒ|¾gü0­°n(郭Oo 4K+TrÑFDK M`·¹k£Y Ѽ­Go€›ËyFní¬Å{¤ E£ÂÁ³·ÂÞƒ’ã€\Œwòï‡FPÃZȬ4,„­ˆœÈõ»úô—ü“GIq¦+ƒË& ÉÚLrÐ`m<µAA¯=ºR_‰âíä}ÐðŠûé;”’3Ã*¿ãó¿a=£q»’ÉóiÃyï´¬}p_3å-ÒònA)H@κÁ’ñD¥÷MÁ9ß I t#>H(Èç(,´¼•&ˆM•öš Á´‰™†©¹µ†¡©Ä€LÊM¼3%ª4Ú"2FjØ$cÐk!ºhÉÈõ(lÈ=%?ƒäsýº- gAXË:Dö—;D÷—mõÒ)¹ ˆYM¬™ÊQ ¤žÆ ùÉCÍlܵ ŒfÍFÆ»ÖÞ½…Iƒù])C9—ˆ2ÎUâfª]Z›Éë6¯é°•H˜p [²°ÜÝ‹Uºõbí¼zKŽÁ”.AEϨ!–i°¹ ¢_š.6ÒËÈõ’sнRGH…c•!¥z iPîIâIJÔå7öÃ;ïé§pØÓ[òÍÿ†Üß±"7sÆIêkËÄ´ ‹”IcðžØ¿Ã«š%(éJX%
+.@ ½²n}/äÕ®@ƒ&ØC‚Áº‡ ´P’± ö@›ªw{FcqdùDDP¡ºþýiOÄ0eHÑÞ3z︧/m’AC/7Úhhç¬Íû—Œå]˜
+¶šV¹1gÉ|Sîîe.¸iÉ'2–»zÉÉÃ\pÔ42cC®GœGµC‹’áØî!sÞFÃT®b@$‹ó-·-°‹X—¨ Äû˜Ê·i˜±ö” š\š±ùÝÃyûÐ~J-|7Ð\-:…
+Çã½AŒŽfZÎMÁÅ bwhă-ÆTLé´2ªZ_é_<Dä³Fa.¡yKp‹b|ÚÌRᑃhL÷VÂ\aw{ïêÛMˆÔ§_ B
+¹µ¿í”𾎞7ƃü àq?@ìnÁ©4 Á9¸àØŬå®^üVŸÞ ŒÙŸ‚øE¹ä  ü‚¦L~€`
+dº vÀƒb±_·¨”à @=šÛ7MÝr‚ä¶^ÚìŽè ÕâcO£NL£„v6»´yâKiÓ+™“–Àu —„ýzæè¢1ßoœ­&%M ~’³r×V(m{Çɵ .£A’8{Q(¹   °ôº3t)„ô"±<`ÂàÜqÔžAzC~±‡¤¯Ý£ÖY
+õQ>9chs#‰ßÀvCJ@pœwš.%›òŒ"íŽN‰ˆmÀGÑøëAl ð±˜CYchs9ˆµ¼£‡)ÃJ¾“ŠõИL4É|ż&1o@,#R¢Š‚oqž”
+¾7ã]4ÍIþ%“zM(Ùß ¶1gf€t˜6îÆŸAÝÑ&í=ÓïS† чô¹¤s3AÆÍ䎆`v8ïŒ\Pá7x(ŠÇ@ä „íM° yÎ@FϹGë@ŒÄ\åª LJ
+’“©ˆÿ¶óí
+0Ë;œƒÄ$Ö‰Ì[ïÞ
+!ûäw&(î3šòMe$WQXi –\ˆsc-‘·;kšóö$qÔqŒh
+:¿àÇSFËKWpUï dþ²Þ¢¨sH>©lÐ's¤ÌÖ£—/i@œŽUßXħÞ\À{& “oóÐF „˜‚{à@øMš¦£†Bréœq HTí!˜ÀÍ äêÕøSòŽ|b0 nÇœ¢¹ɵ Fê ¢j+÷l ’#ïT]dAp…qzeŒ¤¾–Ä,ˆ¯Pl
+ê 3¤˜‘ø ÈðÎÖ%s©HÙí}å$¯6#9©…%c&ØhPÂLò<|·Ø®­_ob"_‰½\ôÐé È v>½1eV;{Ñ9F|,ê–ð$ßëEãó:D
+¡Ú±)çfq»¢#)¶‘Ïù p+ì1¤T¢Z‰·¨=©‚ &
+'
+NQk!Þ#wðïÁ%àU6çþR>íÖ"Þ?w4ð!ëàׄêlîÃeŠÒÖŸ(Y,ÄËÇrE=!öì .»v_øt•PÜ´V(¬[ "–2FWBòÇ!/¥¤D ãD\‚¸Kø^=ŠÉCŒ?=“O¾8‡Ëº·ÄÀXÆ –»02”õäëÄ®0§¨ÀÉû)9¾ãž¾À"rN’?ÔÎMb÷¨ó žÀ»Å HÞÂuÔí€{å[‰ÿ´ñíœdU Wâ=3(¶Ü‡À/ï & BzØ$ê÷¤!u·àl4y‡À~‚Gìq[`_Ø&ˆ+C•;#i­$Ô¨íÒz§úh)îhQ ò@‚áv‡Ö£¤,»ÂS‚∢oå÷–Ê}2Pýh,«|·ŠõO û3•œ4Q—Ù8pî%§Ç<'~‚âs`…¨ÇÑš>jH±§Óz­ÿd}²SÔe@"- Öç‰Z
+Á$_ÁjãJOS}³G÷)üJü$Í¡b@hxd*„„€÷)yòu× "È+Ã÷M¢Äk”l©l"ˆ(A rfÎ7uïMò—=±CQ_åöDÁ9î‰?1BÍ4‘vÊÙ9|K¿Äx!Nð gf²%/VqY ßsaß".
+~c¸Ìsóä¥Í+!LÆGíýŽÛ<LáHbž'Á9‘åz˜b~ýj¶°i…¢¸éG^}{)%’ÙûˆÔƒRG iÇæ@È„I”¤t@—tiî·,ûá"YiÛ”,Í)°?»ÕUù:‡|q’à&Ôðÿ$î§XÊ;}$dl€µàC€…9÷øÁ¢o^O¾¾;n­1Ÿ‹x’l!úØT6õÒ!îô aO¶.gçÕ¿§‚äÜT¾y=äÀäÞH»stAÒ+Û
+ñZ >ˆ¿ELFrxÌÑÞ·Ö„”1{¿äëþP¯¡µBâËø¨ªI´FˆÜÍÞ³HÆa›êx_Ä.ê‹óØC[ÄS-*EÕ› óýSì‚· êËZ b³³r:agÊ0Ä-¥wF!?ÇÚ”Dì’s0þ3¬ô;ËR’QÔ
+p¿B )qèRÁA¢Éëþ€¿¥]=ùºr,œ%§ É/ÄTë“Üy:Í›Éøõk §5ä|ð5 ‡g §OÏ‚OTäÝ[Ê¥^ŸË%ûæÇ(HþÀm÷éC )#Ê¿>áíw÷± +ž¨È¹³‚9\܉©¬[Ò Ä4Ô®Å$÷=ð|@qšæ’$¦ƒ  Bnl
+É+IÌ)œLrׂø²¤ü†5bÑÓµAÆ€HÛé¼&qË ±+÷Æ.ë&%1¤øÖ7oÆ 'Ù”íû´Æ¼¢sÅŸù:0ŠÜSäëT4ÉÌyßþ” ”ø[!íì<1¼XO
+-™@òàI Ñ<­×@p)óÚB.éü,>B°šæm$W #DŽØ¢§?‘|}1ïš2˜Ö÷E×äë|êÉ9oBý 8s¨'_Ç| 
+vb²w¢œ3ŽæëÖ$_‡à[ZwŽªšLóe<·+`¿%nB‰Š]Të ¥õëÅê'¦ÂÑ69Wùr³¬èî2*vá@îù6‚ÅíÎÝ´’‡V©+Éý‰ÃÜÄ9@¼
+×ÈfX•;h¿J¡åzGÄ$Ô5XGÿ¾ Ë•[ûhcm¡G€$M—®w'›OÏ õ‡]‡ß%ß¿HIåˆýQ1GÔ@äGl
+e Ù¥b1Åzÿ»ˆ‡ØERð
+Ä>°Wu"äüœk¬­?à{’Ël½´M,ì4 Ö³¨yjBì[áàׂØ`Aæ.Kæ<D)QOžà(ˆSBx9j äùÞ -FD×8P¿$˜ŠË¯_!&\˜C…È=c þ ¯h_-/x´Ì¢¼íGà4Ô.M Þ6Þ¸™Š]ÈH®n¡ø‡Ø…|Ö®ŒM”ŒÙ‘Ú'>‹ŠV¡.i·›Öf°vÛ¤y5ˆ>·ïˆüžøÔQ@ˆ<ĺÊØê© „¥kå.=µ.etÅJÄí•:²‡@yw_ŠÈƒø꟢+±_b—JרA´~†Øš|’Š¼Ðº½GÏÞ
+~
+B-$Ö£îLݽ‡É·¹õÂÞ*†±3ì?Ä.J׊å7³~¹£þ»©viQ›AÒ/i$ð=Ä.0Rð?‹]„÷ˆ]GÅ*ˆÝ¨¼IdïÛ—³õèMë !%;RA2P§ø7âðdjw®qƒàG +/}µŠ-íZͦ_ŸOëýžQƒû^®Ã<å=Ct°þ„ù+Q?”1Š
+ïØÊ9íî‹=<È©!2/Ÿ+ʯ¢äî kE.¤Ø®ibjÂo1eHÞ¯<ëȇ‘û)ÜÁ/BuÓF–Y·ÜYóã&â°¨µZ8@¤,W‚Ĩ›a ï LIs‘¿’˜‰z!ù¨¸jÈË!H
+± 3É7ó‚ˆ÷…–Vt¬•y·™Ì©Åû†Ø…Éf[jàaÁò Ä%‘ÿƒ\›Š]°ÌCÃo÷ï«‚¨ñ×´>¹Ý«/Æ›®kØìЦ_íÜ´q¯Dg Ðëê?@a¿›ú!Š-2Î/󮯠~˜µNˆe\\Àe_[œ HŒ)|›}~A‘jÊhºŽ^ ‡uTJ<™qf>_Ùl
+~G|*vÚ#v!ý³Ø…ÛŸbž½Y+-…è¨Iñ.Ö„Iœgójàsî-ã î¤5ƒøCÓàGhÎé›5JŠ<:•+í\Çï{m (û°ui1ìà$! p,[ÕµBr4ç©7ò%ì#*ê1„î‹ðI‰¼õ#äêÈ!N
+ü‡šdçÕWé3b\Xûq.›ù`1¸oœÜ%j
+Æ\¨Œ;5G¹OŸâ™ñC±_bÑ£µBêÍ…t?Öì  úe­¢¡‚ÅøÈso-æ2Ïχ؅ä“Ck¨`Ï‘*"÷;et¹¾2ñô\ìéèÁ4%ãiíu Ý1Ci= ûäã´†òß]‘ƒéwÌ0ÔÁQ[Qæ7®sk~ìÉÙIüöÅþŽc3”Q{õQ³§Â™t:aj
+/˜@Å."zÄ.ÄìsK hAÅ
+Ë‘<•’%“ßó% «ù²¦õ4?)m[5A°O‘ñŸûÆýC°¯üåzìû16g{HÑé>ƒ¢ "ö5àóAúžW·J,kÝȦݞû
+û},½RGY¹‡ –üt)¹ÿqJŒ­¼ªmêìC[«[w|¸2¬SÈÄ&š¯¡¶qʤ“3 ¸Ë–?_Q¶¤e%Ÿyk‰{|ºY5‰ŠcÍß7cjtœk„]ƒý'± É_éºPDѳ#Ÿå?\
+Á<…Kx¹sô
+öh3ûï‚}OWC°û0éCýˆØ"%¾O:8ŠZ‘ø}‡W¢P‘‡&a
+HQ
+B}&þøtEîµÅòì«óiÝâX®±ƒPG¦š §fAè\whÝÓ‡}àØ»ˆ¹sT_±÷õ:¡ò‘yj*Ý_a0ಘj}’3̇@ €&y™‹‹_èÜÀ:*rJäÝ~9£ð {úÓ ¾Ö…¸OPáX¬{bͳ÷¥qcÌ:{õ¥{[KÆa¹bD³uY÷hˆ’#O‚xªÜ‘`é*=!¥fp‡P>ŽÆf×0º¯tÖ¢8l‡ß
+âOå¥ +QW¡×LÎ Âö)Ä~2®,¢ßɧf‘ç¦#gÃþ0ï°ëäUkQ å"öMàÃ÷êaŸj=òÂGË„¤kói]šÌ ì×C¾MqnâáiX+¦Âó…÷—Á7À¶Ñïý"ä=f 1‡é~Y¬/`5 ìÇa³n/b«_o–5-v% UØ8н’¨)bíó]ˆ96Mô/KEg|3G£VDæ€>]
+H§}#tíß+}©&þMŠÛ?Æ~šŒ£¿w
+À;FÒÝ£îÒ{QPG“Y:öì©·qí…Ú’…¥«jÆòýåö>½!>¤t<—vs›óh)æ„ÕH^¯iA|,p1öæRq=¬—ù§èB´
+ûRøÔ«ó{îAÖÄTzÎ؃”xq«®[
+Q\šÏß
+»Æ>QËð’I4/þ‡  ɉÅØ33±¦ØSØ7b_Rü™Ù|æí%³‡ùdŒ¢ºOîÔLŠƒP&ñ’ú…âoa/|ÚÕ…£õKb÷ä¾Nƒð)ƒ ¶ñ46󺆂û¸WŸÖ±&„uGÔŒ#K'PüD♢ôÑOlî•ÅtÝÊ5jDÜ°Î/¦œ˜‹z—~u!Äbûy·—PaÂÌÓóà—ùÄOÓXGb`l‰Ù‡¦SL  !Å›Nce×&YEëJ.ºò;¼õCYqû
+¬I±©·ç#‘4.*;ŒÙÊ×›E-+¨Ý§œ…˜ÝEQÝ$f-Æ:*É¡æ-FîŸ ÿƒ˜#ŜɧŸKk Ð>Øbª(¬[ÎÆVN¤"¨U9îЦñâ4å/×(Ê^¯âÒ.Æ}„ÄV.ýîBÖ+kçW4š:8‰-{¾F¬h3‚ð;­7¢¯ 9Ö<‡Q/Û§‡u@n{xÚ«rh¢´wöQQ#ˆ`O2|pòi‚#.Í£˜#ì~x"—xzº<›|.0«Ož®Ü3}¨" x4z`‚\]»P~ðó&öð;c‹ƒ¿®—þ»±âúo–Š›Ÿ¶²gÞóìþφòªÏë•ÖóG_YHÛì•×ŸºK7Zwpçº$®âõF>÷þ–ÑÅú*¿¨Kн«äžAÌ’ÌÓ©Bò¥y|iëZÕþ§
+ëê:qkyܺ¬Ö\Ì»·’
+/{¦ŒPÒ{Œ¼RQôxê3bÊ•…Ø—¡(~¼¢F4ç$Øž¯z±…«~cÈ•¿[Ï•<_ƒu< ÄDý\yûJb§em?Éski]šO9?þSQÙ¹¾…+n_K
+WÒ±F¦¾;O᫃¼›-i_iy²a›åñǶlůØÔ;ó ð+Æ_žCÅå
+Ÿ®¤kZ±çg!Óz§­Ooäƒ|ú½%ˆ¡‡d?ü^Œ»0û_TåOMÅò×›Qƒâ¢ON!ùÓh6¤j<¶‚<òÌDÓü§óMOv¯—]ú»Lqí7¥üÎ_­Ù[¿ÙÉüëV‹ºnöÙ/þÂë1\Çç@¶þ;û36Lªo
+®¼µc/|ÙKï%éJ³³êâËmTMæÊ‚ÆõÊ⧛¸Ò¶uÄ÷ü€qU¤^œÅ?[%ík7³Ú÷T!?ß &\œƒ\Ñ*¬p¢2 eŒÕΨa–á•úBÖŽ¯R!*”bñ‘;ÔiÂ~oÆŸ~Îó§;þRçVñâS{áês;ñ`§BQõaƒ¢¨ùYÅËUü¡NsþÄsŽ#c(?ñÁD~üWcîð'3ÅñfüñN–=ñÊ‚?×!Š'Û%噦mVWkvŠg¬¸½d¥OVÈ÷¾ZM«`s\êy°KØ»ïå¡â™Ök…êNئ±j“Bu¸^à*š6(ÊÚVÁ÷ñåÄÿ·­Äš…¼üÅJyå›5>®c÷¿ÛÌ~e$?öa‹âÈ'#űO&Üù÷*þÒ[â^óŠ+Ÿ”üõ7ÛÅ3/·ŠGÉ5®Î4«¤³í[ù³{â¥9j̧~5’þÕX~ág–¿ùÉ^vç߬äW~„ÚgžRmƒ¿Õõû»­.Þß¡<Þ âö·qUo6ãÜøŒ›‹ h\!øHqõ“R8ýZÉ—½ßÀ_°õ`_ü|­ùV-3Ï^×ÄZ¨å­;ÞªËunâ‰×–Âé·*éH§¨¬~¦Pîof…òv±êµ1_ùÚ€??b]|쉩¬ºf H͸¹øEŒ!ó<­f±¸·Ó@,±™-{½Ö¢ú—Õ²‚÷ËÌ÷þö£yõßWšÞé–›·u;ÉÞü‹—ôþI’ðþe¬¼éWEû/ÞÜ»Oáì»ßB•kR¶½9©v|~8Wúð4Y|ý"AÕÕœbõò‘zûó«…ʧ ‘ä>Jì_·
+7_;J5;ªk-âñ¥êX“•õ™G.[¯Ýô¶>Wã.|¬’Wý²^Vôl¹pð¥…êLÓvþÈ[¹"ïñ2ÔÿP3ª:Œ‰2Uí{,³>Ú`kyø±
+ù&[Þ¹ž‡-Ttmdu˜K§Û¬Ä«O•W[\dÇÿ¶E~î{ñ½J¸óÜ]¸ùÊ‘»ôVÅž{Ç —;mø[Ϲ›ŸmÙ;ïí¹‡¯Ý¹oݸ»?;(nÿÍVqã7KÙµ_ÅíÏÖÜ£WnÊçµ±ÊÎqbÃ#îò köø[ýq³¼äùòŠÏë0¸“],¶S’δYó'[x®ú™¡¼²k­PõÌDu®Þö­ºøÈI8ÖÁ±G_™±»Œ„cÏYéT«µpé¹µâð¯ò㟌ø#ÏåŠÓòs¯Š«ïTìÍ_mùû¯ÝøG];¹¯\¹ú»¸†.Å•wæ‡Ø¤¸òVTœ|!“Ÿ{'N¶ ì­¶m\s‡§ð²-Êòýƒ écK²¬½Ûͼ©ÛNÑòón®¹Ë—»ñÖVqàóf6ÄP¿œÑÈË°¦I}9Á¥ˆ¨W™§?žm~ðßÖ
+§»”Ê;u{ìÎ_Ý£,x²K97ËâÈïåG3”]û™“_øÀZTÿeµ,÷틢ߖ‹%7«ª:äÖ'UwîùXÖÞ ÝúàN¸Õ͇~Ò•&gåÑ6Q¬î4£XeßÛÈÓXçø½ï7L¸Dòß7^–ß´TvæSyÍo6ìÛŸƒ¥Ï’¤“„Ï/âù?^Å Ÿ[âù_ßÅpÞEHjSŸU«]Û˳£ê’ò3Eçnï:’­øð×é][Šý‹SyV¯¨¥7IÊζöI×r?ݸíøkmeU¿¯‘—X¥¼ÚêfuûQê|‡£pý={ꣂ»øJ’´z[uÔ$KµíþÂv±æÙNå½åÃÆ@«Æ[ÑâƒvOåµ'nâÝ'nÒÍVþZ—{ãåVéj3±Çzå­‡îÒíwâó,Í*^-·H8¥ož×´ÀüØ¿¯7¿Øm¦¸÷Î^|Þ¥zõ(Uõ®1U|Õ+¼k•^·&²Ï^øY<üWk‹‡ÿb%ø‡¬þöÅ'ácKœòscšÝ«³¹Òç¶d¶þ…{íµŠ;ôÖDž~w›z}®"ëÉÅÁO†xN¼Übgy­n·êê#7Õéz[åñKÕ©FËãÖܹçá…J~éÏ_ë°oµ¸JWŸî.<sÏwÚÈÿn$?ûÁœ#ñ—¿öÌNª¯÷Ÿ<Qµ5ÄZ¿º—éøâx‘˳ƒEÛ_žÊ·}w-Wüð8Nê¨k›¼Ùëï¬øÏÜùöÇ!V¯ïfn{{5Çéù‘B·öò|Ïæ¢üÝOò³=ZKòœžUg[~¸™Ê}|!kúÃÙüìߌPÿ‘v¦ ƒ+'(J_¬d÷0à÷½7€oCì’…\ž`Zúi wûãv«Î»©6Ïoª­ŸÜN°íº”³­ëzŽÐØæ'»÷»µñ©îÕ‘—'šoóëmd`É°¬¦tø;éôS›®ëÙ.Ï{¶îÝëÐq¶È²¹&q?Ú®÷·š‰§É}ºñ`·ÕÓ›ñªëõ;ùƒm¦Ê£"ü ßÙæü¼:—Ø\náƒÈìø‡ 9°AÛ×'²,?ÞJW~¾“jóæ¬Úÿ©šÚdõ샳ö>Ïvk/ÍQ»µ}u:Ëáù‘\åû†é}{⶗ײ¹–>ægº·(ªß(+zõqa
+»ï—MV›v)/t9È+ÿe<åÁóÌÆ9²Ë¿qªgñv]—ó·w^(°|Û˜!t´„I/›c·¾¾Ÿ¥|Ù˜ÈÕt¹Èn¶´8ÿ7SÙ¥×
+îþ3g®þ™§¬é·íÜ«§!“m//d‹kýÍNÿe£IÅã…¦U–ŸüûJã›Ý†æmsté¨Ì+« Ë-¬ÏOlŠ- oJ)ÚÕ^Zd÷êT®ò—útéçgÉÂçç‰âoÏ·½>›µ³µ´ÀñÙlëwç3,ÿ}»é±¿­åýb"~Fâü‡BÜÙ™|ê½…À®\õkCsOv(…Cÿì[V>•)Kžð…õ?)rî/Qìÿ´QºöÌŲ¾6LY[$\xc-«úËYfÍ\yÊÙæêså?Ê•Oj÷¿¸Thÿêrª«6I|Ñeù±6swkQQ䓤âˆ'IE%¡yQO’Ê”51ìÓ绬ßßW‡¶¤•Æ4Çæd´„åT6««›3×e’ëÍŠ©‹ÏN|Ÿ•X›íÕœ›³õÍÙLþÍ›öá{Wîòkå¥gåµ7åÇ{¤K-ü‰v–?Ôn&~j·øØíÃÿú2Æ¥ý@Gû¾·öýÅ.íGJ”]ãÙšŸÌþ«RÖôwyÿ9šÜí65ºÚ½Á¤üÕbÓ}Ÿ–‹÷ŸíÞú¦&{Ûë«Ù\Ç®æåîa§;ÁÏRE›)wàÅñT“J¸_çaÕr#Þáù±üm²ŸŸ*òl+ßëת΋zœÐœ’™Ü•YY¢>ö$ óæï´ÚÖ=)÷}Óo×û¥?lòNmxìZK~®kðIøÐ?ãLm`femhVrm\ž[Ky®åûë©â‡¦›WÔò§ÿânq¡Û\qêß-¸c¿Ypgߊ⹮­ÂþO¦\é¯ë¥ý/Yîäo¬PÛµ[ù¶-YxÙÅ¿|¡|ÿ$Mú\—Æ~x&üܯzÿ0Ýêmƒšëx`qù¯òK/äâ­&gUÛƒåûÆT«÷wÕaM)%‰Í±e»Ú«öm{y9[ùö^œíë˹Û_Ï·u$ǧ#37õqDö‰Æ
+Í.© ËŽjHÌU}¾•bRÛ-˜¦?œn±¿{µpòƒ(y¿Uyò•t§ÝÃêaM¸U˽$ëΚLñn«»¬úÃZyÅ»µRu›L:÷ÜVy§u·t›Ääk¿Ø(›žD&Ö'”?V—Y?»§n>s’ú«EQóRÙþ_6pÞŠB[k˜gkI©ó³#ÅVoï_x3Çê]M¦ôksê¶×§³}Û²‹
+Ÿ„äå> /rë¨*Q¾Êw= uè:^Þ–TÑœ—ÿ$D}¸1 ã ™çÉ8]{䯾Zœw©&(ûøà u^mD–cç,ñSG¢ÐÙ¥zÜ-Üzî"=|â->hñ–êûcn¨k¢‰]'dÇ×Åç„×¥å…4¦å×Dä&Ö%±/ß„˜Ýè¶0oívÜNüSò£¸‚¼{Q9{ïEd<Í"öU\œV[ìHÎMñác°ÑÝn#“ÝF²ößÝñÞ.­ÇÊR“$=N>àöìH…ÝËÓ9|K¯P÷hWø“´JŒ×ü2?ÌÜ[’y¢É?ó^‹wzYK`Žýë㹊?^‡š¾év0{÷ï.æ¿wï‘ÿþ9Øêý…”ÀÆ̼ĆØÜ‚‡áY•÷"²ü²rÜ›K²<šKsÛ«Õª7wRl^_R+ß´¦*_´&)ÛŸÅ çþئ8üo†Âå?lmÚj³<ÚªÊ\Û« í_ÏÝúöJÖ¶7—r„O±ò7ñáÞ¾kL¶ï:šmóîœÚ¬³Ûɬý£=ûⱟ}×ɼÐæÌý–OoF›\ï64®úm±qÂ… Æ>ÅÃL‹G—´Í7«û›¨xû2Ðéåþ¼´Öð¼üÇaÙv¯Ž¨ÍþÒ½Ëèe·å–7Ý’áûn¥á»nÁà}7gô±ÛÆì×n³¿w{ò¿5Fò¿7FÊù%Ȩ£[Ú’Õ6ÕôT÷FÅÝ¿o“jÚ}­7Æ9vœ(
+|œUšUSTù(,Ï·5¯Lùº!Qhn áŸvú‰OB•o[R<Z*Šƒ3‹|ò
+ßÏ>w78Ó»9ŸøìËyª÷u6¯oçؽ:»»½¸,ái|YHSF‘óóª\¢Ù®®@áu+ñuv¯Ïäº<¯ÎßÝž——Û–õ4¡Pøܯxõ³¿¢ë7?ó'Ý6Æ÷º O~\¶%-o´aÊq›kºW›¿ü}‡øGCrL}BnyM˜šÄ=õá{aê¨ÚÄL—¶ŠL»®C™Üû|ó_îúg[ÇíùÖ® ‡Îã“‹NÜ Q_{yúNhö±»¡äoCÕï«÷Þȱ}Ibì»{ˆ¯ñõ yï©oÕ¤WŸõ°Á'õcÛžäOäqøºˆ§ ¹²¿}
+ÞÜÑmnö{·§ýË#ÙûZ‚rïµy¥]hñSŸnñËJi‹*”$þÞˆxhýñŽÚâý_v^î^e2xãv7­uV»4´˜ï×0‹–ÿÄ,Y¶†Y°d53oÑÌì%«˜yKL˜•ò@õþ†®¯ú×éžvoPüÒT›ž¹÷ZLöáY·ã³ónÆe—ߎP§ÝJ̉&ØÁµµ*Oxû&ÎòU}ÆöçÇó.*H«+,»•·÷AXö‚rê"ó€ó,ZÿÍÉòÓÍô½õ!Ù׈»Ôê~ì™wÚ±Nï þï-±F>/6ñVYk(23Çé1{é2]f3œù†<ôÈ÷3ú~ÃÌýFŸY³Fd6KþšUaZËW°Ì”¡ã˜±Ìòª1ŒŽ–.3Dóft/=f\ß)ŒÞð9ÌÄq‹˜éÓW2‹Mݘ5±õ#7]éþÁ¨±[½üOÅÝîmÂݟݬºî««ïFäÞ¾˜q·&0ãV­_úÅû™Åua99µQy1 ‰Ea ©…Åw£rÒ1 SçßÎÍx“³õíEµ¼ë/öÝÛPÿÖôܦ6¯ÔæŽ=)dÈÿþ.Ì ¥ÛdÓ?æl
+<4ÌÀ§bˆQÐ ]äûz~™·ùô¿-68Û½Ü ÷é”UæÌd½¹ÌÄÑ“=ÝÉäF2:Ì
+QŸ¹’yþzhæq27Õ„¨OÝ Îº[ëŸÛXÀÿÚ'üÜ'ÿãs螎œÜëí$?Û“–Óœ³éU·ñ–ŽÌ´1Óˆ#çsëCÎJ“^Æf
+Ûî„•´=.lz˜sýnH±Ïì ·C³ ïEe~ìVÎ_©dFê §sëò ÿÛãÏëüŸ\S¿/cÚ›üëK¯0ùGbâ°EÌwSeÌôU{˜…R‘Æ•Ýã~m9S|%.ûèÕÈœ«7ÂòîÞ
+-|t+¬´¶&¸øòíм3·C²JoGªë2³ð«OÎ"ñ]Ó®ÞöêhªAm·áÌ© þ××Ñã µè9kýÓ˜j|ù]òÛäßPÑÌH­ñÌ` ]2NÉOKbüf¸¶>3¸×dfÖ$fh¿YÌhÝMÌŒ•!Ìòí7´WßêžË¿½Dp‹šÄÄ„¬º´éSm¢å‡«ÉÎmjâc²._YJÂ| 0ù>â[oרÛÛ¼2“œÓ»=3Ûè÷nÛ å/¦ü` dFk úÿæ¿ùJüüg¼À<Õ!^ ×4ª¯>3zÐBæ›Ë™1ÿgF\Êè[̌Йnjè3—6`3 ß÷ŸÏè$¯Ó]ÍL^°YjY­µî@÷4“®n»Ö£I.ûÒ€ÍN\‰Ì*$±ïÙð½í·"+:½½±ïͣЊ÷ !{ß6•¶7ÖÖ!ïZS×½d°Öÿÿø§Äõ§`¼Fië1C{"? &£ˆÈOâ§æXâK&0#{Mc†÷™Å ï7›1p3zÜ:æ»iûmfð%‹…2Í_5ú¥ÛFx}#(ïZ|ÖÉKÑù÷o†æ=º’Ww'´°îaPÞýÛÁywî„丒u‹øÓk÷ƒ²ñ|öƒHõÚçÝ«gÌ]ý¿¾–?ý&|DêÙû|ù¾/õ#ý¾|?„Œã(í‰Ì7dœÆ_ÄŒÓ]ÄŒ÷3V=3~’)3f’3f²)3jìzfäw›™qS9f¶aóC`‡Îª»Ýs¥W‚2®$gQÜr'6ëüí5ÁfÙ¹5j‚3s{»Eð Ábf=¹œuç^P¹Fõ–ߺ·.sJÑœ´p9‰­Cþ¯ ~²/õ ½è÷=>°gö§hd03Rs43¦ÿ4fÌйÌØÑ?1ú³•ÌÔïw0Ù‘‡3v†ÈŒ¨`FO‘3£'˜0#G­g¾ùfýÝ\ófEÐõ/º7¿ë¶µi=íVW–Tx)!ëáåˆüæá…5·Â
+IŒÏ»q/PýâaPî‡ú€Ü÷M~yž5= *&5ø{·rÒb³ÿÕ˜áüSŒ6ø zì‰y˜{=¿Ó!¿ÊèöÃŒ ÏŒ8ƒ5lñÍÓÝ¡³Éü[ÆŒ¶‚5|3bøOôÚÆM³bÆM’˜‰s]˜éqÌ¢m'´–¥¼ºêt÷´55ÝKŒ?uÛÛ?Ý zùjDÞã[¡¹Ídœ×d=¯ *Àœë|Xþ¼1¨ôy³ÉÝÚ ’KÄ¥¯}Òý£þÌÍÿkÛì¹V†ŽâÙ0Í1Ì0-’!‘y5œÌ¹ZÈs˜Ad “Çð>“˜‘g‘k[ÀèŽYBìs5±Icæ›VÌø%nÌwk}ãf:_ÀLW3óm.j®HýËÈ•µÝóÙ·5^{n—¤FÜÉȈÿØ{Ï°ª®uï{R•ª"vQ{/(vA¤—µXköUè Ò‘ÞAª¢€Rl€ ņ]c‰šXc¢&{×[vÚ.É9g=ã?HöÙÏužë¼ûËûÍ™kÅÕæ÷¸Ë˜ãþý?­iüœä^wȹú¼pËiãn\/ØòâFÁ¶—_4½¸•ßtùÓ¢­©w[=>3,Ògè¿=nÎ7ø{D*{“AÌ óQ䜆{´'¿·!Û¶çߌ‡3ƒ,&HÆÎj:ñ›ÎÌ°K˜‘£9Æiv,3nI3Æs53Ö½˜¹4›qðÈaFxä2TÌŒàÆó«ž÷q=c˜¨xcX!¿ü´pÕõ5¥—ë?:µ¶õÎÇå;\*ïº|¹x j† 7«šÒ·4]!uÂÛytRóÃ…J×#†±C†Lÿ·c¹)͵#’èeJb™•#ñýNÌ ÓÑÄÏ$9€ÚfòŸ½ñ@r~£˜ÁVNL«QÄ7’GßIÌ@{âÿ|Ç©¡Œã´(fÔÌ8fÌâ"fL`#3Ê·š™uØØ¥â¾Õ’ÆÑî ®$Ž×}u®<ñn熺‹5›Ÿ+Ûtëâê-ɹ}q¹¨áìù_ßÉ®ûËýÜ–7Oswܼ›ßÚöEicÐoߥOÕdýŽYOüßÿÓ—ôäÂd´¬È\³'c8„>ìMF0ƒúL§c5ÈÁØ 3”ØáˆY:fÄ ‘ø”@fØ_fÐP7fÐ(OfÐŒfä2ç‚j˜Y±GMæl|d³ Û0dé-Ã,·[åÏ¿ÇE=î^[uu}CË'•[ˆïÜv‘äÒÄF·>½S°ýÛ{ùm¯äïøñA^Ûw·‹Ú¿¹U€µ¤M>Ï
+'ÇyÿÖ¸™ü‹ìñ¶ä\Höa=‘qáÆŒrô!çáÊ éN|ÅRfà`â?»ŸIæ™kÇ,b† ]Â8 re†V0ãfô¬f‚ÇjfÛÎL_qÒxVÉÍÞ3ëžZ.8m±¨ó·¡Ë®fy½4(ØŸæ¿8UQ~©¡aÃùÚM_^.ïºz¥hë™K%[Ô7~ S|lð :Nê‹+¿†I_=/ úÆïù…a‰ëš«ýÙŒþ_Ï«'¶YÐì^Ò’fYˆÐC™~dœö™Â #ñxìÌ(f’g3Ö%œ;QÅŒ¹˜q þr˜ÝTò@Ì›Í :ä”
+fÔ5CÃŒsKa¦Ö0Ó„&ÆyÅG&³ê¾±ž÷¡a¨ÛÃR÷¯ Ëߢ¯ ±Ò÷¯Ë£Ÿª°gkÄ·Çãïm길¦©íÒÚ¦„'ÝÛC¿¿¾¹ø~cÇÍ›9_ßÊ®k¹^¶ÙûµŸéŸü¿ž›9=›û2ƒ¨ÿ°¢9¿ý‰þÒÞÌä ÃÉ|ÄØ™ááÈØÛNe†Œòcœ–’ü8ùœéâº×ï7Œ\ú‘aòÉ¥§ ãíø! 6½ê?oãË~ó‹oZÏÏ<Ý{ñº/û¹4L\~ßàôCŠò/†Dù§«¡¯?Üò¸eê9ÔäÈ5O£v½R¼åãk7¾Èkxòyþæ··ŠÚî}^ØÌýô$ß½èóþððïÿŽmZüËaŸÈŒõÆ ï7=Ù™ê•ÌLà³™ñQõÌ”ü“¦S«>3Ÿµîs‹ÙeŸõžžyÆtzÁy³97-ç¬j=§ê¡õœ‚k½çf]îµ ì–Ͳӆ©Ëî-=hpr­}:Ð}Ÿa¼×}ƒ—ßCëÿ ñbÕï ™w·5"gÁyí%¹sÑíúm
+AÉø,cÀÓÐx"ó'~be‡‡.•3ŒœÆ/þ_ìÒ˜Žüú€A$ìÊ éÁ š dÆ/Kf¦qÌ®’™®©cfÇî7q©½g»¨Ûà°ô<ŸÛ†9ËnæÃÿ-¬~ÐonÌ“éšõŒ³~³Ñüøýf‹‹oØ.©zÖßmÛÏן6Ì"ù‰·ß_ !ªßÞ¥K?]-õûÎ {Wáà¿ùÉåÆ«øc¿+å/¾KÕ|üË
+þðïl׸Iûþ+Hsê×Péì¡ò‰W:ýé»1ÚOž¥`¿SàUC«¶ÚÄÞä{XÁL³ë=Šäú³˜Ž*fÔäÆÉ%Žç™ÍLU•3S¼Ó˜i‹c˜ÉÎ<3~Š3a‚'3e®ÌÌåªæ¥žî5?çªå²ÎÿíyÇàîûÀðÊÊýôkaÔWë5?^«TÿòKûão¹~Ï ’÷ž¿MñÝñrŠßƒsÀ ƒRñ…APÝ2„²Þ&JïçK_ß]ñ꣭á//lÑüðUµpÿm–êsƒŽ½ýÛJéÛçe¥w6¶Þº‘³±ìVíV÷¶w£F;Îý7ìÒUÉ=È<#çÙßj 3lØ\fìì f–W<ã•1óù|fa\«éü†ký–~j˜äù›A¥4¼[¥ùËÙbîo·rƒþëçUì?îf«~’øÃJÏ_
+¯ *¿_ :ÿŸ â_^–¼4„x×|2Ü/¾ÑÂ+ªÖÜÿŠÁW}Ó¸ï÷yÊ¢ýƒÕ§ AÂ7oŠc_hŽþæHSêãα_i T0bD¬™Xn¦vßC^<ûJ«ìüËÏ´V«1Ò:íÿuØ’q1È…7UMòÜ5ŒKüE³yë¾²]ÐnDlož÷Þÿo†ÿß ‘¾¿´Ëž¸Ý4ÌöøÎàðÊìû›öÝ,jlºU²©ønm£æÝ…¬¡øÛó¼`pñ:epö¾iðT<1„ª^’Ù·¿çi¹[+ýôõš€S×ÀàXc·Ùó_O}”ØÇÈu>v.ÎÔäî®M¨ï'töþÃO>ù6˜ßó£—Pzh”:wÏ ¿¨š^Sf)™a6cþÇZÐÛ¦ ɳHŽÕg3fŽÌ8·/ª}Ñþoùt¾„)5Ä+ÿjH
+ü‹!Òïñ÷ \àMçÿ¹!@ùÐξ5ä}kˆSÜ4Hç ÞÊM/¦*ËŽ:(:¾sVßúG¤ðúûbõ†,Õ C¬ÿ¾ßç*«N8ª¶ßŸÃwÿè-|øNRoûb&Wwn
+×z~®pì^æä5­îæռЇŸTËg¾ •ÚÞ-n¹ˆ5ŸNO>CŸ\¨Ö}w³Fqà Î\Èÿ?ÏË’øÅ>&Ù¾½;ÛQ¤ŽžÃŒšäÇLÈf\♺¬ùÒzÑ¡ÿá~Û°Ì'…÷Ãbïòsƒ¼ã;,ý‹ò¿hðŸ|™ûõý»O6ˆo—²¯_å^1(ë6R$®0U¬J3W•Ûúo9éäÕà+¿|\.=~–¯¬<:ÂG¥aòL•ûÿc ·ÿ76©Ö– Ë5Ì“}«Ñ^|/.]}§ýüFFÐÞ·KØý¿xp{¾qçwýà!Ÿù:Œ¿üS˜ß9ƒëòU{­F_Bëì=ìH̘2eæKëŒÜ
+Î÷Y~Ûàê÷ƒAô£!Åÿ!˜øk­’Ä]þ§_Jø_Þ•úßà“ÓÝož«3wþL&0)Õ,èø+oÍãkEÉÏötd=iÚñêäþ‡·«· ²ïî¦ùU]røÐસh ìøf–²áì8凿yó}%r¼bü݇ËØÖ_œbâÄ2œ>΄r’Àß/nwZ-÷ÿ¨¿ô8Cå^†ºýÝB6qUPV³ÊfëE)̨!Î4F›Ðõt£?ìÒŒékBâÚàÙÌx–™§¯6rÝòÝP·s†)î K|ÿfг¿}Çÿþ¢TúûÃu¡oÏ7âÞŸôæY™pÿuÿÙ/‘ÜÅ¿kÅ«ï´÷—ên<-’N¾Õr9mýÜüŸóQ-2Øÿ®j¹á¬<ó_^Ê–kÓU™ëlÑÍn»<‹ÛûÆS8öZÍn»;‡-l,•ï¡]×9Njº±(xÏAÿéÙ!7®–ëÏÝOO|¥•÷=Wq{¾]Î5}1G½þàh¿ÔÍÖ¸ßfojC×þõÀXì;‘1É™â—Ä,J:Ôkù†É>ßR_®Àï[ƒäÿÒ +ïBÿÇÿÈ3ÿÆÛ]Í©B‰ 1‹Íµ_Ý>NÞúÅb©úÔÔ@ã2j(³`Ì0f‡2žË\®é²³æ⃕ÂÙo$õÖOfò©ëûÐýçû^ûÓ=ѱBx–9X²òŽo<äö—žbýùYBÇKwíÁ'’xçešæê“n÷ß—sõ§ªýìË_y)<|•®øÖáyËà¶tívó£»Læ­ØkºhÅ^3·Ø}½<3OõñX}¦¿÷ÞŸ§
+ïÞ–`/NÑÝúíÜ«ŸóŽ–*·½œ¡ìúižâ¸Á#¨û·%AÍý-re¦;ef Æ°Þ^LXB²eTNÁ€ˆüÊ¡è :ö“‡ðÙ‹í­[ùêÿªRû«¯úàß<ØêããØüõv\Ýîqü‘Ç
+ºGóÜ÷áAG~÷P¯¿0ŽÏé̆˜«ÃÓÍؘ3Ú÷²÷¥"äÌ—ÉÁ—dpçÞŠª-ŸÏPUŸ«è|77°õõ ßâ“—i‹Œg¸ê™q$6¼”íÊ8‡Õ¹m¸7Èó¨aª×%ïËäqœøýŽïÇy–êÙ2põ®A»GUw8(QtÞwVt¿@]{~"—Û1˜OßÖ_Ên,ìwr ÖÛx»û0‹–0*_¯TJF« 5fõ¡ÆBIó0õ¶+3ÕMŸÌRoÿÄ™ßöálvû¥9ÜîWîâñÿñW2ÝW¹¶e”¸z‡ßýÖKwöîÊà·V‡y©:ø‹ëEºËwÓÔûßy ¯‚Ëk´W¤¯±ò-Ý3Àsíù!KÂ+L¦,ä˜6ŽLÿÞ¤ uè„
+Æ­èJ_'†å¾ßDþ§Jø7+R]2ˆA nÊÂfû äZ¦—Û°õg'ñeíĘ
+ åÖ`
+¸z0žs\˜À¥Œ,ÆÒ^!ÊŽ+Ùë’Õ0XV¨oòïAÄo¥-ù¦s¸Ú“„uGÇ‹kŽ×t=õ ßsG'm½±@ÊÛ0
+yûÙ&é×GëÔ¿²U3¤“x–àóó9a˜ç“¹¯¯«"ŒñÒ®0
+hy4E|ü]Ž|ó› áÌ/›ºµßò¥>ŒRÊЪ&pëÏLðUë˜yc'3K&Íf—¹1!Úp“ˆôB»¨ÔÂþaÉE}õ¹µƒù¶ObŸ¯|úawò+·ïG/ÕÞ—KØÊNný>'áÐ7
+ì«eüâ©Úöb6Ûüƒ à?ýU[oÍäsÚq yBnã
+Dï´ï±B÷ÑÍhÍÉÇ:݉aÒî7¾BË‹ÅlÛW‹ÄÎwØó©¹v?UuøÎ ¸g&± NVŸøÅ?èÊï\Àm’S}e üÆJÆ-Àç°avÀ†‡cüÃKÌ–.U0^J¨Ë4Q¥oîëá§a»¸3~Þ:ÆËÕ‡qâÌx-^Þ£E#'{z2n‹–1>ŒZÁ3}¸IhJ®mHIǘвî‰è Ò•ÔG£ÔýÂ?ôèíšc_kÕÝ?º³[òe»F°]?¸²›®Ïä2¶öW'V[³»~wÕ]~š*}%Ð^—œíƒÐÏÌ­=0š+Ù>”_Ý>œ­:ê¤là¬<ú›{ÐþŸ—5ߘ¡Øùvn`÷ÏóO\öªAtë?tAWÿCô?þ…Šò]CE[ú+wþ2Ÿ?ù†jz>[™·­?›³}
+ò¡Çjaïk®áÔT¡¸e˜”Ý0@*h&äµÛ2„[Ó5óPµÿ;÷É7!šOï%r§~T©öÿâ®ÞóÃRu÷OË„Sß ÒÕçÉòåçqêý¿.cS×Ù
+iå¶\ñÎáªÖ‡.¹ïõº§w*c¾=µ]úöÁjåyƒ"ð#ƒGà–×S
+OZÃø
+ÉÆ™m}ƒN¼Ô5gÇj“Uá¹flH¦©’_iì¶ÀÌ¿éÌR’ðéëú²{¾uü ”‚ÀÌ
+¿ ?yÉŸ~)˜¸€+Ýë Ž+µPð±Æ^žãéª`àÜÇ÷æS6öå󻆂ÅGöR1Äw$ó«ú[!”’Gí'Óз"t¿õ«ŽŽçâ
+-¸”2k¡¸ƒÄó#$Ü2PÈÞÔã#kOLæÚn.ÚŸ.|ã'üZÁïý΃ò¶¿ >øN> ¶ýÉ"¶ñÜTÕ¾7®èB-‹=ßÂÇoôêï«?›ªêüy!¾?ŸUÞ‡MÌ·ÖÏîyëÆíz· ÜL®úÈ8®êƒ±ì¦k3Tß-Pøu©:£ÉÎ+0”™=~3Õ~4ã2f:³pÆ,fùòåŒ ³Ü›Ä6’ûIŒo Àx{*o_%£ O4a³ìÀ„A6X‹`ý‰|¸1§"¾‡‹4¦úq[/Í•:ž,ç;ŸºÙÍ%[ ë÷Ž÷? Ôº¥íŠU{œ¤¢¦¡`bÉ“tò‰gZáÐ÷
+nÏÜÞŸ¼ÐÆ7ßk(¯®¯ßå¤Þ~ÍY8ü*H>û"B}èï^ªš ØšS”¯\‚:^/PW©ŒÈ7SÊÉƾl„‘2,Ó”KÚh«Z™g>¦ 3}Ä8fáœeŒ×Râ7Õ 4"Á†×®Ù?A×vÍS³íæè®C^¡ŠÕ3A
+¡z˜E CÐënç8ô‘’80B(Ø4H(mu`Ûž,ä¾óãöýàÉ×}4UÌi$xñbFµíÉ+hJó›ÆOgR®àú¹Íçfð g§ ûFñU‡Ç¨w}³„;ú} pô;%·ó'wnÍ1'ð2Tú…°ÂX’mÊÅVYA·A&þ9©Ô
+L=uH¶8{à?ò+V÷ v «NLà¶ÞŸ ûó—ä#„”ê>|r•-_dÉÅåõ;R,;äÄn4Ÿö ×}8•ÝñÅ|ôV’ø¬;y;B>ñH§?+Q¾ô`ôû vÛç³EûÙ NDo"úׄK_…«öýì¦.h¤NmèË–t WïùÅUÝýfòb›ËÔ{Zb†5 …6˜rZšnÌVµßwá ;‡…d™.[äÇ,š2ŸY¾Ð›Ø¥Š TóŒZnÌF’Ú2iµ5Ÿ”k©ŠN1…%e¼Dd˜ñYöÒú3SÀô×UŸÑ0PÕ;8:ÛB#E뢳,ô«;G‹Í7‚õ6_°m_µw4×ùh‰Ð~ÏUÜûÌ}®Rõþ à òÝ4î©…#OT꽯ÜT\ÆŸ~-h®<NÐœ{²B<ðR¡ÞûÈU\³ÇI,jÌÕ›ÄzçC{—O§eþNêŽ{³Ô ý¸ŒF;®ãͶëõR~ó5gvݱ±|aëuåñÑlæ¶þnnŒË4gÆs±?Oh}©Õä'‰=j}¤1e~”歷N!.£˜©Ô.‰ßŽNö|åÅuÞX,g”õ•’r­ä²m|ãÙéâÆ3ÓøMäóºðPïþv©TÜ4LÈ©³—ÊÖŸ[o/æn„8)mB™:9¤Ì$¹x鮑bá¶!”%™Ý8€O̵àK­(og݇èÏôý¸è¼^`Íã5èãJ½"×}ÒàíIëNN”«?šÆ'•ZqFê`öÌ%”XI…mÃ0_Ôû~pWzãÅíþn·ç­Ûþt±´æð8°ÝÁ)º^¸ƒ±ö¿­‡aÍuã%íy }ÆŠ§Ÿë„ŸIêÝoÜ„ NwqƒÝöélîÈë
+‰Ï,±㉯ËXg'ƒ7™Ý4˜Î0  1•p’©Æ±'èXaí‘KˆÄ¡ÓæáÐ12JúÈ9UýÁeÄyA,n¹êÀxðêH sëadí Öt‹(3*½ÆC°>Ø·K /@µ`¡§Úxa6ò.éØ3:|Êjk6$Æ„ ‰ëÑmc™ÄJvû­ybÆV{…&Þ8H$¾Qˆ4£²{!†ˆMCøôª>Êàxª!­Žˆ§×šgA!+)g£¤Ã19J Rfø°d3è‘:e \T?šXˆçÐaåãó,°N¦”cIŽ`ÄFäš i5ý„èÜ^j)–rŠ$°ò IU»Æº})¸‰âÎûÞBû—®Ré™”y·áƒ©Ðì„vŸvÿ=6ìãKi‘ç>Ê
+>xKOÙgcŽ²M—œË埆ÉWŸ%¢O5<8®BH(ñe+M„Œw Rjú`­ŠÏÝ65‚?näºÈŸ™?~ã±4€QEdš©uI&>¤vu÷V’\šäšª¿­dCÀäüR°ÿùðT35ṁ­2“³jí…õ‡ÆÂÛÄo¾>Gwð¾¬ÛÿTk>˜BÙ…e-#ùýßøɧŸógÿ*1xòkŽ¥qúd¹Mƒ¹©fþJÝYôÕCNkîå£bà©NÉļ:Ó -¡ÍÉGÆ™‚‹Iõ*‰} ¥PËŒk*§K/ë+¦¹TØ< z`i6J¹Ì$‡Ã’Ì(¯ªöÄtmÍá©àrA³JŒI4§Nlúl¾\sp2ø†=ú†…ÖÚ”5}¡× } ¾õú±ó¶;r30C©nvÑÖaà`jŽ<ÒèÏÜY©9ü@䛯ÍÆ6G®%tSÁL²ì…ø
++6"Í ZRzÕØ„a^*¥0#ne–9Õ*kwVUتBH~BüØ¿©õh,ϨëÖ»¶¤Û‰êÍ”6 ‡îÕtÅù“º¬thu©IŒ€Þ–°jm!³¡?Õ0(nsÐVš@yRXçl<9]î¼å©Ý}O©Ùq×SÜtvìR&Ü3G<¶]ž'îø õ fÏó@®óñR)¿™\§{hÊ°­æs{ôsBÝöt>¿¦{”\Ø2 ßÍg¹'™O"#Ä–[q+‹-‚4 Æ\T–9‡k‘aæ£HÍãθŒ›ÃÌŸ:—ñp—3ÌHgÂgÔÛ kŽÒkú–*ÕΨ²Óæ×A»¯ôÌÜ'ªÏ>ñ¯Ø‚˜¶Ô~Ç,fê›Rò­Ù¶› (ÿçÜ«Páô_4\Ë‹Ð’ÖÛ’¹aìGj¯€ ž ò]ÏÜÙÆ Óà'½¼XÆÛ[Á@AF­=t§¨Ž4™õ¡ÆàqZF-‡ƒåMщyÖRR¦šfF™òÄJ-WéZ/.“7~8v-D¥š&n½:_l»¾Ü/© v ͵¶]™Ç·¾: ºâúaÚ²£  [t
+X‡|ó•ùÚ½wUüžo½„U•¶lXœ)Õ9¯Ø>Z³¡{2tÅ=¯|…îW~4Öw=q£,¦ŠýcĘ
+K1¶Ð’#óOEÆ\i©æÌT¾åÑ"¹þ† XqÐQØa- l"q÷×^Tó”ø1¿u¨XØ>ŒæëµO“¶?s•Û_xéÚŸøëÚø ;¾\-DMV½TÚ1,Cpô°Ÿ|c¡¸ËæëNN7_Ÿ+·}½\î|á«ë¼«麭Òì¼ã~"™ËÓ4%Í#tEuC5õ'f‰í×—É­7܉mºÐœŒä6BÅ®Q$ÖM¤<½„*[hbòm‹{ÞøIݯ°nuRð …ŠŽ‘4î§?½fÿX¬Ï…ûF° k¬øô;.©Ú†[‘m®CÜ/g-\ÊàžP m-w°À„]Áñ¥×ˆÔµJ•Èð‘ñfШÐÖŸw¡hiÕvT›–Ìs\ m×-qËgóä¢-CÁ‘—RËlézgév’wÛj³-ÉŸGP^ß‘×
+áø+^µÿGw!w£=˜Œ
+ÍJÛzt…´ê¾à¤‹kŽŽ‡o€v"¸ôRT‚YpÁæáú¢6G}ÑÔ`|üx°‘Ÿ
+Õ6Nª°¥º…¥»Ç§WI(´…¦Šfmç˜?YÜšªÝã¸îç^úÓ×¢C®_,Ž?`3¾Ë•LNÓ¶ÁТ,îu‡ÆS=løO½ä}•Á»ª¥Ž¯=D£©v‰ÙTg(¯i(´³X]ÕÎÒþ‹v»ïwÔ‡¸¿èÏÑ\©G;«œjPm›ÔBhSPmxÊ¥íþ3lïOí,mËÃåòŽ§Ë©“9®ãYb[КÇk´ÐjÈ©€|ZSÒ>ßIŠ.´"ózA_^×|o¹Üþܺ|4^g¬#Œ¨~ 4ëöŽƒ¡Äš}“¥Æ³Îš¶;àêJϽÀxZ/%1rç¹úÿ‹;?ìŸÜù®o=u'ž†‡_¹P¤Ýý@!ÖšH× ¡óP¶{$Ÿ^oG×kNL¶\œƒµpUdš)XÇ2ÉË×usì·BÎIõŠ¡ƒ MDm”±ZAs=Êæ^‘l]$ªW=èˆTsM<±›ÌZ{°Ï5»ŸPí¬rrmÿÔÎZí,’ß%ÛhWof¬.—Ľ?´³Ä¸r+Ƀ–³ /E‹:òYÁa&Rx¼XË¢žØæJØkµÕÇ#qŒ®‰¤VôábVšBŸ LoʽÞr~eqCg‹Äi<‚+ûB¯.8¯n¨vm÷¹ñò< ,îuÝã¡¥Ý}W÷²„<’3%”YÉ1=,nª?Ô|kåÌBóœk|ïÚ#SÁ¬Å~4ªßŸcѳœM5>ô±EÖÐŽÒ&æYõhg58ˆ{øa}PÊ€v–žQ* g’Ñ :]¸ï½0Ä!m|¦åÚYƒ¡Ey¥jgEæõÖçï¡©;ç¬/Ù7NKâåð¯\mIu»r›‡R ÅÜuöбÔor
+kDˆ‰Š@=è¡"ñ%ÊñI™Ý[k¡‹É²ÐD¦õ’£²{ÃGC‹›êS6Õos€ÿ³-ï©Þ¹¶ÒÖ .Ðø¡|ú´uvÈ[µ$×'~`’vÓ͆ÃS5ëM¢šmåÍ#…]w<±÷k¥`qKéµvyOè›I­wÜ“b PSd©+´Â¾ªUÖ9
+ë-Tû·°ÓAH[Û‡ O4¥ZN$fÒù§vÖŽ;ËäλÞXKùS; ñV“¶±?ìYέ¶‡^´³ —ŒÚ쿵³Jz´³ô¤Þ‰3E|ѧ×#ÒÍ1wÁð×®ª±CŸ«+Ù6‚ê™ål¢Ïß8„øÀÁˆrxv/ª½E^œ±a ^Þú¿¾u¼¶|Çh0·©frM—æëÚ.¹Wɫî3ôž©ìšÃã„]¯=å=ß+À‘…v,´ñèëIìÄ€Ðô‘³fí®q=ºë)¦ÐJ„þ
+#@;‹Ø8üÕÎò!ŸGÐ~×¥­ï¯M/é—eSjF9"É\ŒH4Ó$ø í.â“媮1Ð@„†];‡®YË­%RËõÅÐwÕd6Ôu8B£Bn¿é<÷9SÍMõ ׶ŽÚo¹!¶P„J’wo.e’s„.Gç—$ߺ±L_°i¸.¶È*$«qHp©ë×í™ Ûó%«ßO£ÙýLɃÜ|Û…jgQýöýã¸æO¨v–ØôŪUÐí,?ÌEm¢±T´Ë¬nªM½v/ÕÎÒA?ÚY%=ÚYºÕÎJüS;+½—c‰¤¶Ô’¼9/´ã‹¶;€ï ý ä$ÐÓeT’ùÙ8 Ú
+ôõ¤î£ÉëCVšp|„t©3Pݼ¾úÄdú€¦ÉKz8Ç»ÇhɵÔÄYQ}²˜´^ÐüÖämÂoþd¶¸ï¥»ãñBèr!Ñ&Ø_Γj5Z'ħõæCÃMü}4ŒŠ'5yd~/<'PÉ1j}˜±œScuDÄÔox_¬a@wš‹ ùOþÖ!RÍ“ Wmn?O–ñóaäÛbLñÇõC´ëöN€–/Í+IÜ–áOÖŸKj9«Žjþa¿·ó‰›¼ë©?ÕÎ#=.ËBýOí¬Ì?´³Ò,ôT;ëà4MÝYgmje_5j„ï½mÜ+Õå6 ÖÖîŸ\Ö>&8µ„ê[Óz<wó`Êco¾º€ê8]ʲ‡^Õ&o,çl$¹×¾1ˆƒbóµEòŽ[Bëµ%|ÓŹЀ§kaØŸCk™Ž8/©á£Y`Écߣ¶êøè’jwÝ ”7}4'8£¼¿gª_™kIêµáҶ닃I¤–íÑ—ìÑΨvÖ½%òÎoü4ÝOƒ°õÕÂH*¶æ£
+z©¢3͸˜’Þjga} šT_iMûXmÍ¡©ÚÕ‡Ñø¾ºÙQÚx`²¦ácg]ÕÑ)ЮÔ$Xc¯æ8ÖMtÅmŽâæS³zô9>v¦º1-Žx.b‡z\5'fèÖ™¤-Ü8¾Xƒ×‡Å˜B :÷RÓY±í¾+Ö×è=wh ×ß»i°6µÎžj8Ç­¦Z÷úÕ­ŽrU‡î_¨]?äpMÅŠG16×B-F³Áƈ4ÿÓ?»ÆÞÏSd‚TaFbxŽ¹.¾Òõ­.wã`hžÀ'KŽLÖvÞ dÜ«X‘ß>_J©´E,ät‰&Ju˜‘{~HìA.…8¦+hAc$‰kTgkž¤nÃþ4¬—öè—ìq6ž[ß5—ÐxzttÙ›S}°ÂfÄàŠfê´ÕǧkH­
+ ¬oöh
+×ØõèP‘Š<µþŒ3´ßPMhð\þ¹&ö@ ö… hãzC£yˆ¸éÄ yó•ùÈq_ÚñÐEÎXj:µMhËäÑX4Nn¹é
+û”:_zã~¶óž_èžÛ²Dü'téÐOŒ2¦:Ðe;FÊ«*ûàž>ÆDHÌ·Ä})¡áã™ü¶ës¡¥Û÷H`w>w…v–¸áàDô|Hå{GK…ÃÁ²èšó¹‰T; Z!XÏZOì³²“œ9_hg•öhgÉ›?œ#6]š‡A×[IÌ×69Ð\“ø}h¶ ¶žu–ëÈyW¶’Ë;FQ­ùò=cµgæH[/Σº¶¸ç’ZÑO_HêhøUuOÚn¸Éí·=øö‹ùíä½jOL†žt> ÷¤]wjš.{Û!*ÞL®=8kÚwyäEtm£ë‰+×òÉ\ªïDj,Zk¬;>En¾¶DÞreò$…*”áõé¦Rh¦9Ö|´É«m¡ƒªÍ²Ôe¬³—v|áÜñ¥’jÉäÔ D.À“z(HIêu–ض c a„ucèÑ`]ƒæ`Tç4ÏRWÐ4Ú]¨ùä¢6hnÈå»G£Ç„®3•t;‰°W¬_&XÊÉEÖÈè ±%MõáɸŸA5ÞVÛˆ™4ßG¦©8:^ÜzmÖD4壡ùø-m!\WÔ£Ô/–lÍjÚçReÕ Ê®¦¨º¬õ¨3ä¡r=‰Û¤FC¾Oul•·;ŠäÚÓÚz¸Ùä<‰þ¡én#m86kÚ£µº£·ôbÇíeRp‚)«’Ü¿¢5E C©ÆtއŗZÓõ„ÑÎÏϦuÛê¦árÝ©™ÈÇÙÖ;óQ¿³QÙæ,ÉñÅÌæÐJÓTþ¡ÅIê>2GJjg•µ‚¶‘„9µíÕX×–îrêyߎ°Z B‡ºzïx©îØT±é‚ ±±ùRãyš³Ð5«êî‰xª WAìž|rêÛ ;Eæ¨XCjùŽ;K5‡îðü¡¯ý¸¶ °Ç÷ܵëOM£û&³ŠúȇîªCO]]uòLRøáÏ¢ô»o ]_.#õ¾3|‘¶ ÕŒ%9rí×tŽÅ^7)º°·¦âÐ8Z37]X Én¨Ö¯4HNM5¬Ww9BwK$ögÅc– &¹¡šQ«ôŒ•Ý ù1ÎKØúé¬Kz²—šÓQ-OòYš5NзÂþ%ªIT}f¿åó9Цís µ,Ö¢Äè83hmázjj?œ.Ö|0kùˆÑbL§K6…Ž2î¡k*§ú(ô^/4©ZFBg kÛè%“ëÎ;ãžÕ<Ä&ì¢òÔ$mÙþ±Ð¡ÖïpÄþiÓ…žÜ’Σ=ãtë?˜
+»§cõ&èq•4ÀÚµÜyÏ—øïiRJ±“k!†¥˜i2ê`_xàE îðCf×C…Øtk!ÕìÁÕ>1Clý|±Ôòù횽㩦94oIÎGsÖêñ¿>@S¼u4°ÄÍgg󻞸sMŸÍÁý]Üo¦½ŽqeV4&­?8 ~¹”&«¬ÍSò7Õ•¶:Ò{BÄ¿óMæp›OOÇõÎ:êyµ&ÞúTS…Äêó*Z±‡e<Õ Ây“ü‘Æ2ïÅšƒD’Ÿ“ºe6ò •DüÉC…è¼^øÞØ{&î~ê @ëÖÛ¿\$nº8sñK\×å$îx´ {=µ
+bý%gê«ó6DΊ÷¥>†Œ%ö^Bï ûhÜÃÚêþÖ«nð©ôÞth¤ ê^ÄX¼¿™h†=X ‡N‘²ÊL­
+îÑDÌÝ2š*8'Ü¢VšøúœVÃÈ«ˆ]àsæ†þ=zæNÓ¬?0k¨¸‰œQ“RbK5±HŒFŽ„嶺è¯i<7ë3š
+bäûi+M”²`O„_`©É‚Ž%yø¯ü–¡ˆ“hÙ'æ[aýRnøx4¨~´¶  —»u0êlz¹€Œ/4È —Wwd*òª[ ÍöòN¤F¡ú¸w_NµxZ¯/€v^Cë=ÔªÄn‘A‚o{²„ß~g!|žf=É% «„X»áèT¾ã±›vï5tbp¯žj}¥WÙѽ'XkÄ ªƒ¤
+’×B߇‚îrÇÅlëçóøMfÑ{:™$vÀvÈëÑ7nFïb={‡ó6éÉ‘›G`×úÍäÊ=c¸ð,3V·Êµt«s@NÌÝHâ̦A2É?eì·ªÚ;V»zÓ0z¯lÓÉ™bÛõ%Ò¦‹.¸O/„ç›+¤•FÜ
+ËÊv:rÍŸ¹àýéýš|bE­Ã0Ǥò.G~ãÁ \Ûµ\Ó•¹ÜÖËÎèEãò, )ÆgYhÖìKõá°‡dõÞÑòJCãW[i³¶ ‚V¡ZÚ$•ªwzh2l’Ô\Ö¸÷ÿ½)MR¶•¸ªÒV“QÝ_.é$>ªu8]ç#5­7Èëp /­ðS1AjŽAÚõ.®;ò$Üo•ˆÍJ ÙÔ¶¡1M®™¦¤möòÈ y–ZÄóÆÓs¯@O õ öliË»œ°wó
+ß÷‹5™[¢v†ÿFIuÓÓÖÙÑ=GЂÏÜ`Oâ˜=óÐ{%>EÊnMgª'ŒýŠÍT³[‹Ü:·X£Í©êOµš¨þp&ÕyÅš ÉC1Ç¥§zü´O‰£:WЊÅ:;™cš ríJˆ‘úylÔ@³…Ægb‘
+ÍÏ•kÉ{ó¤zbÐ…þ0Öy°NžYÙÞ+%9ôÙ4; NÈ$ù6öÒVë¶vß8hÑQ½2ܧË]g: Úu˜Ûô:À?l8>™î^w` ö»B7„Ø/ˆùEsrmá¯tE­#h\ª>:•j‚“s–ÖîMí´j·¿áÌd¾úÔD1³Ñù=7ì{iù|æÕØŠN2ƒN¸ªû«%ì_JÝ_H{žùñµÇ ÑæèAþGÆn,tzH˜Hç#´+mé÷¦óúätÃûãýñþx¼?Þï÷Çûãýñþx¼?Þï÷Çûãýñþx¼?Þï÷Çûãýñþx¼?Þï÷Çûãýñþx¼?Þï÷ÇÿÏÇر ËCSCmDo›±n>s‚ÉßU¡«R#SlmÆOwKI]ž“˜š’å¸
+Ýδ«eÕú~è,Eg0v£SWÚ4]&è„äÃ’M5èŒí$.×TXÚ]Y{l:2Ñ=&Çç[Rúù©Y™m¡I¤~HR”J‚ç£ûhEfo9j•¹>¡ÌV—B>?mh$BR¾¥"Df›«ÑMÌë8M¸1HD 
+Éfè&DÇ°™bJ¶Š“.4ÎDJÙÐ4|Lš9Bé1 oI±yè”=U͆©å0#ø±äü³-µyµƒ´Uû&êŠ:F¢ 9Hc$„§™ª@Ͻr÷X:lW÷AG(®gÊÚ~”^TÐê )Ù=J*h*¤UØŠ©µä÷uý¥¬:{!º¨w.ÁÄV)©ÐšÒ2ò·¡;À)­¦¼½&è(Ú:]LØ9OwªƒÒ@>‡Ž5á¥c•ºhc´A`VE)U¡F~J-Ú’] R%9øk˜
+K¡ «_iê¥o šAç´¸ª¶_Px²‰o€Ì,óR0èl Í2—júH©ú‰ñeÖ¬˜h u† }ª‰yž;¨¼!F á{€F¤N7tI¦BT¦¹ve‘•.¾ÐZ“VÑ7¸ 67R“[7;ÍYr¾ä;k27Úkó·Ó·;‚b Ë¨¶™‘’¬²ªìa?R\†“a®ÍiJ®ï0 ˆ[‡k7]˜¯©;ã¬+¨‚çHÄv¤„L tP*II+íï¡4„Íg×Ñ'çÙèR2­t™ëìA+ 4†U«mA‹BW™< c"„'˜Q"dl¡¥˜R`NJ}þ–áèð•SKl5Qù”T´yº­´™5ör\¾¥°b•9ˆ\´ ‡Ø>`*F&›ö É$¶‘^ÑÝòºªƒ“55Ǧé26”ã ¬ÄÄ|KØ9:ø@"BíÐËjH;âJ­a›Ú¢ö‘”xµù“yrÓEè`”
+z(Br‰µZGÆ‚Øí:N%öŒÎÛòÎÑ (P%·„<KÚe’]f§+n)¥Uö•Vfô¦]$èx%ãF;ñ¢â̤¼äø+¥iìéêK|¤'£È|Ó¥›ªä$VŽ%c™jÊ‘‡J^i(3~bz>Á„Òb"3Èœ7Rrz¤U|?Zň‚^è¼â+¬AßÃû(¹£ !Úˆ”É9 [YJoè/E¯¶PëRLð R ûX[l"Ÿ•èÒëéªiJGblVoÍÊ2+V›d¢Ö?œhªY¹ÚJ›¹q€.e½6>ÏJ›e.T}vÍ@)]Ùæèp•ò6Ð.1Ð2Ð%OÆÇ’ªbq džÌõöÚÔ*;tRŠ^zã
+úñ½èÑU쟠Ûpj–níþ‰ZJqØ9N—‡nø"kê‰ÿìéØ%>™øLtÉÀ®hG*+16»7:Îa3ºŒÒ~èZ¥Çè*)Ù9]=´35­¢µ7â—uéëûkS+ûiRŠlàçð^”ˆ…1Ï­¡]£´Ã{í®±º²î±˜kÚòc@·êéìÛãD;ÃÊ:Fj [†ƒ²£_½Û‰~ˆÉ…ÖrQópt™ÑNçŠÎÑtó¡#¤ qˆœS7€’AîŽ+°¤Š1”2Üâ€.59¿n&muÌo]áWAýÂwåõd,aèÔ!>ö 2…o†.7!`W¾ž
+Æ×_Å€ÞĊĽy&À_Ï°2y=ñI|xŠ«‹2†ÿ¡ÄèÌ^°øf6t¥ oŠ®g?ˉÆBdŽ¹Sh¢->dyØ’i†._Ì-tGÑŽ¦Äò×÷q~‰eÖšôêþ ¨Ú…&µÆD?Ÿå^ §3Ö c&ºØ’ I6™ƒPIì¥â á#´±Ù– #hRJûÀ7‚2*®Ì³@7¢¶r‡:–á`[r,±O2ž´ã©pÛ0yÐI+Eçö¦ä°Œ´»O_¾{í’&ã¦ÍÝ2¤'/h©­èCòЄ´kºÆj×ߤ]s`|‘.c(XbT’íØ"ó
+Éü¡Ô7JX#ßöÝ04'œæ:R5ëM¡Ý¶ f£ cèpB>C)9…ÛðÞ ‡£ÛTLF×_‘µ¦Ø:Õ`‹kvŽ•YW±w¬.¯Íöä³a.¡»IN*·9žv»ƒº»ªÜ–Æô¬Mƒ0W„rís,Ñ¥G}*ñµ 6p¡IdüVP"0|ýÞòtˆãz€|®õFPWcH\XY` ²¬œj*…e›ƒ¨Oü"§1Fþ‚®E1@`mä<h®£'ö›TaM
+?)†$›ñºÈ"79ÄetpÓ®ý¸Lšjã ­h‡(=ï†4„Ì$±¼€ä„EÛ†S{†ü;Æ~>7cÓ@äB ‰P•½uíþ#ñ¹ÆÒSòI—U7Ò˜ÒÊújÓ«úSò± ø(SˆÍ #>s(óÚ} òTV¥®dÇ(mI›#:wi#™¯˜— L¢cóä %9´ŒÀ÷¤„
+:!‘[ÀïÉI«mÐYHm …Ølzµ¥%âw©%6ÜÊüÞB8ñ} Õ¢›~5™cÄÓ.{ÐÂKm@¿ã‰ÿbWõµÁ¾„\Ó~ú/H|Õ€€›iÑÓýI¾CÍÙétn‘
+WŸœD;×ØJ9̓¥µN›,–ê®9Kñ5¶
+üt¬‰&»~ ¦öèT¹îÄtt…ÓkW¶s:ïA£”C(OÆ“ü2Œk‰_d>js·Õ—ì_¿#†¬0ýˆæK• <œŸ­!>¶©Ñ5smi×%GäA´û”Œ7lt ÚIŽY\2?(1…äBrB‘:O)>
+ã•RÕ×RŸGI㕶˜GRæ1y?:Ca3 "‚¼DìôÏŽ||ÚµLrH‰ÄŒùˆý™Uv¨³@% äÈ Ç§€ˆM»U‰j³6R_Iëí¤Üõý¡f?
+Ú ¥ü¯;2*âê¶á”Ì‘RfKÏ/¹¢ÏeÝ£A–?
+þY.oEIUäßèw«Ø9
+ šó5‡Ç#~ƒ>†ùŽÏÁÜ
+$ÆJ1¤æ 1Iˆ%ó 2Ëœ'ñŠZ°OiUu_¨Fà:£k]É’Z…1ÂZòB|7!u{œ±JŠ&uÈJcí ðC× Ÿaœ‰ÏBL&¹°…¦êØ$Ì/ÄfÐ_¥”u}(™”ø~ä‡Bh¬)•dÊF$›Òx°ªª“eÚ-†*R—÷ýÒL±6!$”Zñ!i¦JÔëš…aŒz õ®œdz#¥Å’:]ŠÉë šU¦˜Ô¸¥dŒ§Uì 5®õÑ":¿àÇ
+6 ævÜY$îyíËîû›‡ºõ«ù `RR?l0»q
+sYJ€?ª¿à,îüÖ[Ú÷<ˆßõŒA)Õ%©¢òkJ]Ubuzí‰íÁ®‘wÁw"^C•µ…Gž_‰u¡ä5¶üŠœ^4ANVoešä·:PÊ4Éq@I¡>Ï#y5T (‰5µ¼Pl‰¹Û¤>–Ì-ê}ü$qÁÇÓÁ¸³!Yf¨Ÿ¡(Û3ÒÍ 
+Eã…9”pºjFRゾ ì y£æýÕŸo¸é E ÌcÔq
+µž*˜B‰Ä7aÇSÄÔÊ>ˆE|ùlÐQ·Â‹Û¡:¥%ñkOú¢–‘ÈEá¿A &õz/m2É@ZAÞº4ñ‡ˆåÔ‡‚êú-­×+ì@©¥*Uû'Ðú·°ÅA[²}$òX¬jsjê²ë{ˆŠùuCh¾¼¦Ó‰oûr1U=ÊX×ë™”üPÑ4JSµ{¼°é³9|×sw~ç×˨²cÓµyÒÆ ³@3”c+¬k¡nÃÅäõ‚"òUaë5©îg)oÛ`ä‡BLnoÇ…m_ÌçÛ/¡4U¨k´ ó[{r„µ§&‰[nÌ—¶?p•Ûî¹ËÛ¿t©¤‡VHâJqópÔ¥”ÚZ%âÔOJ»i~Lšu'&Kµg§‰›¯Îõ d¬eÀ.üØžzØæUà u?¥Ç¯Ìè|Cƒš“ÔO žÑ¹Iìë<XO’ÖØʤn‘ëvÈ{¹0â?ÃsÌQÓæú”Ö@sk9©º/ü2ò¬ ƒØ›Á]N®é Õsµn,ÅXÈ)kûj"
+zÃ6AvDª[UN×ê@iÆÚ.]ïÌ«¬­:ÜCò@Or¸ôÒ¾Èõ(µ$µ¤%ø–µŽàZ®ºp~ðå¿ dw¿vòêÀþ”ÚXc¬Ë‚Æ<׊ÒÛÿkoWÕº­¿‚ݹÅîVl‘Žk­Y«
+Ƙ¯Ã"ÈK/à˜
+øÑ&lÖФ!Œ_±Ÿä8Ô5˜øwg9(í
+ó—Kק@~•¾ä>&€sÊ6^÷W‚’1ÇŸ`Ò´ÿ£u ¶'²I˜Xö â㳚Šÿ F‡Vn§]R~‚¸(²žM‡<Þ@$Ô«‚r㑼¾è7•<†cÞŒsÜ“”ሣ*Ô©˜šÝd\ÍF^°›´r
+ìÃ}‚Ø!`–(ðÞ:Pº€‰BÜä4˜ÚôÃù>_÷[V²E˜Ð´‹›&vÜ~,uàôàë4ðuˆ“7Aÿ¯Éö–²
+šÁ¼7€µÀ‡
+€©æܹÆqƱ+â
+šÇMùãð­M¤ì(€€
+¥0õã>~Jûî¿ø:`¾§À×9U‰ãøÌŸ´ËMÐÄþVøhƒØ5NYâ¿
+hˆ¯Ãyq“é¹úÞG°S§äEÇðy_7Ç|!ðÞrygô%_†ï·›(òº±‚›ly&N "c©(¡BSœQk,ºÛDÐiºÂØ·;85ˆ£øžÄXÜãñERrNqhê)æþ؇ÁÙ„×
+¯‘ãëC><|(öà€H…½ÚÊe[‡<%ÇÕ0.å¸:LÓƒ\ƒsÔ<ÔŽ°/$cËw‚ª߬Š1ÉÆdpN¹œí Çq„ì§!þ5PCgS2!0Wæˆ2?û§„Çñì‡m”@ B|ÆfœNiÄ1é'ÀĤøµ!5qtº(®IÖÓÁ!†Ò–øß¿à=&ŽÁô+ð« ,BFaŽíû˹rÓã®g.#b«vé}ûA¡¡%€‰àž¹ÝZ&s‰U–žq¶ ؆›NövW®JG½ÛÅM „uÂËÇ›N 2N™›â_»_’^o÷†
+{½…³OÏÛË¡FÃ\¿»œ›²æûr-㔡LžvoõQâ¨øW‰s’2ì#Ä$ÈkPÇ®Œ†i²„¹õ¨- )tÎäêݾ7r¯ òç1ǾK‚};øEnê¶?NíòF0éÛ(xÁZN âZœò?Õ ¼@ Âwh2?Äð/¶Ñÿ5sQÀæ&F2Aœó±ÆÜ&£‚­q~ò¢ï4®NÜþ˜ wž¸ºcä<ÆãÖÆûáª!ÿ…ÿ}˜¢˜ÑÖw&L5ƒúÇ¡17LÀ}ä&f­†3ËùRðÿ#`^.Ã؆›Êüœû}®–=¦¥2~/×sùˆ“ã
+g¯M–ÀgàÈ©oãÔ BæÓõ\ü¸ jRdl,AœMA=ç8Lý¶8”–þTƒ˜ j°6Ù_j–WFM´|±Eêvk¹cÆr¤˜AÎÓ5}§Ä⓹
+TȨ˜’]tPÎzP+ß…ÉnjףUDDÕ6PŒšt7òU\p7ÆëP3%uÇçûLÈÍrSè@ÙÜŠ«¹ú‡(¥A—Lü NcnËMŽÅx&v‚O5 è•€<p~úôõ \þ>Ç|XxèòžÀr˜ž&9OPÃ&ÚŽEèà³Ká3ªO‚žÀQ ÞÊÀ‰ Ç€¿?¦úâj¿Ä˜ŠŽªØ-ö~ºŽSÀ÷ŒŠ.ÙE¤4«Ñe;IM{
+rXbà÷Øß@¦äɳÒëËab*W+?9”ë’^MYÆMª¾0chÂðÅÑÀg Ô ÿ)>íÛ¥ô´ÇD.±Õ蓼ÂåíÏ õV0à§@ÉÇzÈ;sŠç—}¦Ï ‡ÞN-âg—ÿPƒH¨Ò'UëR¶J©Aeç9›<¤­ï À÷ { qüW5×!5ã85l72+ÌÛŒ¦Éåœâ
+„Æ8
+êE<=ÁïqŠ*J=®“¹§.åðÌÏ^S _$ıe¢€¼Í\?Ôì@aôÏZ/¨j‚R*ì‘¿•y²Ô $Öá\r
+ypÈ­H£ª4ÅÅ{†8;Žß6Ðßqo•Ô#y)äì9eI®í=r
+LŇ)Õ\=”¥0F€üÿ‚æl63¡.JD`nŠq¸äVI¤¶©ƒ(ÓnI †êÉóÉŸý'ƒJ:íùb§aí;ãQ>i+ ç%q^À©A¸ ©AˆÃ«€â7-céÌœ”9å5ÌS¹iÂøçL|¥:“X£Éñ“„&u¨™€b(Ú‘Áÿ‡¢Ý¼*Ú%ujBߟšÎõÄ.C_üû0=²\MœØ¨Ml„û
+`vÌ3¸]èeôÉ^ j\Ô ŽràÒ¨SA}jC£€^‰k¼2×WÊ Pƒ•0OŒ£.ûM£NžÅõÈàx¼†›P>8#\vQsAõ rµRgù|‰×ÍUÐßKƒz#`f°Õä*=P>¦´«r=
+§\ÇC!ô¨pyÇèŠ3éóœoN çëê­å\Ïø}à³¾ Z¹ô®8FÌãÎ*(J欅d±KâКœ“ÒA÷×IU{‰è’mÔõÛK)ëÐÐ1¤D„¿æ”šr·pªAvJ05ŸûÛ ¤ù¯¬•dÄ«­DXîF.oêQ§¯O„<2§0éýp (K=o­âzú záì\»»”LîÞ/Jë3¹?\Îõ×€rà²kK1gØ
+.ܤ|ðÁ˜W೸ð w6 Ž
+œx·m¸\\OÆ7€uAýÆ!f.Ô=¡æG¶áâ>ì1uâòh®·Õ>~ÔhûçAõ8l&uöêPížê¢Ä1Œ¥Ò•EþÅ[
+ꢋ~SéÓöãà5c³_EÓ.NçÖ
+ëÁÜ
+iq”ë•„œ"ԮἋ®Ý[!¾;—Se± ™¹"|–ru » î¹®ö9h:§âŒý›ÄóÆJ.ösü#z÷óã®ã˜cîÜÅõ¨u ½(Gšê©·8=rKÓÓŠ3&NÙ%[qP(aœæÓy›¨ð²mp@y ózö±€‹¡7—SŸƒzÙÿ™ ê})L@îÆ¡{:b*÷š¡ÉçÙ:J^¾ Tc9>}+Ø5ô‰šºÆ/æx)àPüÀœX|=g5Ô‡ò©K@ K╳– )Pá0+à0ë`%îâúä®æpä…q¼äü‚SÜO`/L`îfPáâò—Øîñ}]Ê  ¨j$ .F…<ÝÄÕPà~û$/år‚P‚º#äŒÝpø Ç32¡l/ñr+W·:í1TΠÎ/ö¿¿òitPîfPSåÔè# T8å¾ì à—É(짹X‡càõt³o­ä0-(L€R×½•\ìOëЦ4ªÒWÓÂïBþP×¼jRT@ÁFà/DtÕQZ‹•Ö­CÆ6ìæìÞÿ¨½©±å»pÌR? uTÌ·@Î[ì~c øˆ9Ï«™ Gë¹((Lßl0&cÊwR×Óq*«:vjï@½%©s™Ø­F•l…ûþzXé ·›©Ë¡ÓiÛØYŒÇÍÅTbÛ>qJ“!(£sùFx® 8Ô<C¾À%Uê€ôױܳ*N·I’@§úêГ >Ø/ãˆç8ÌárK™q½½ˆöÉ^I„á0«uäLâBÐÒ.n圹€—n&n~Ò¡n÷ n~Õfÿ0"_3%ó> rúêÆ'}"ýÓ~2m@“¹Û%<k:,}]wVò¦ñý¸CB§tk3ïv™^[*;i;ò\ï*¾g öˆÏér‘ßó LB£†ìFižQ.>TN˜'–òÅ‘Eªœ2ñÿé2ûî¯$c«wC~Fìÿr3ôeqÕ»Aõ‡ãœÛ3é èŒ}:©O“ŽoÛu¸@©ˆósIͪ¨&6í%"J¹¼4ãÿd=øO2­]| ׬
+ v&ñ¼³ŠË¥rý¢Y+ÁÁGÆãÖR*èÙz*ì½
+‘òa™Ô´JkÒg4ñDi  ðHÄ×ï×ùxíDLåN°°k2±] zG¨=zôf>¨DÓ÷?‚¤Þ½ÂèÖDÆw-úy·©¸èÃÏLaÇIÉóæÃôÃVZt_øw¥Y5¦Ì½&¡ø^þÿZ qv£ó°“&K6’ï6 ÛùŸU©œNFú¼æ¸4§Ú°Œ4³† Òzt…é­êÀ•@ z è°¢’˜Šý¢‡­"æ^·Ž¬Ü9¤0š¾ŒŽoÙ'”¿Ý@ž½>x7߬jú ò iVõ!*å«P¸pÅ^/Öqêk1uª\Mëú“5¹|ç!ë‘À™ "ˆ¡ +Ù.ö|ºú_dIuÆâ¤n]ÈAÑW,Ãüiå”>Ÿr¹±€pÏYdU·Ñø«)|þCH¾ú&%
+3§ò¿Y
+ßÿ퀠œµ Z¿\u¸F·|²§*zÎ2}'àÞÉÊK]$5ö¢—½–ÔÓ1õ¼_"yYBö¬ö¤éýj YJ _]¥)«Ó¡šöcß³ ö• x¶†ŽkU“¤6›˜¥Ö‘â¸6-±÷³uÀÍ\bIíüg›ýì1ÕÔ5m©(jǹœR(xBâ#}«Gßî7a²Û&»EÄ<o? ~VwX”Ûf)¾ÙN’éZdlý.aJ§s«ÏÜo£i¼‡Äý‘õÕˆ¾ýÑ„Ì0a²Ú)ê~—€yÜ"?h–Hsjšåÿ,~TiF'·k jwÉ]êøR›£Þl
+5 "éƒ*‘Ö³O9¸ŸºÑ§KÝî2$î w>’÷>òè'ý2æy/öÝ ùò£”yÝsDœÓy@|¯1«åÔË$š0Z$ÔýN>䘿
+³¿O?SLÞÇÿ›/¿ŠD¥­$¥•WÌ^¿»höìÝ)iV¥Œ¾ÑlH§÷èÂkc‚ó¶@,àâ
+ÆGdîG©(»[Ê$ök1ظYlÆĵiðœT4±¸0Ô'¡jš_h%{Q~F|¿ÛT”Ý+“ÜiK3ZIézJ”Ô¬'Nï6bÒºõ¯'«AÍŠ¹~9%/VáDƒó¶~_Ãç<°x«8¹]OœôA—JìÖd|QF÷ïà'ÛÃÏø¡j\Èü&ö¸°çË’þZ_Qçu¢æËi²ù‹Ý÷Ñ•êûæ,,ö?Øó@~¬ív„d ÎOÜýÁ[ÖQïoÖY&?Ò–#­«tÇ÷QB½ùz@”×}LR\o#{ÕpNœÕ"•Ý«13Ï);yàUž•ùãâ³’Õ2"ý‹¦0¶u§èf§@–Ss„¹ÓK‘Õ; ÿ9cQz‹öCƲÔj¡ùÝÊC¦·«eÀ7©¤vMl!¥C›º×—d7™‰skIsN
+³~7 RÏúe¢Â¶³¢¼®côó^õ¸½h·`òÛŽÑyŸQ…ý‡é’î³ôûÞ3ôÛÏGÉ‚ß‘o¾™
+_}‘ŸÌé²®3Ò¶ÒëÒö÷žâʲ+ô‹æTVÊÔ%âÛö)ŸöÃy tPÌ£v‰$§ÉœyÐÀЭúDZ‡†(½•'{\qì[ö¬ì¸è^ MÝí2¡nvŠîµQ’‡æ¢çmæäí¯zDÖGCæNAf· ˆÇ]$™Û'£ò¾bÞuŸaÊ:~¦ßw¦+>œ§+;Α/$tN ±‰|Ù+&|û„¢Í"*¿é ]ßrAÔÙäaÚÿ>X2Øà'lfÏðkXK²áóEº¾Ã†~Ó{ˆÌü¤Káj> xÔ49_Žq)ÄÈWñƒª×òoþ]C”Ý!•–_²|’{I]«Eû?^#¸ó]›¸ûM_øê3M< ¿ª #zU±ßvŠãueé-„ùýªc²Â"kÓÒ"çï ]ÍòJl%/kNHï6‰Åí&VIíÕžFá8Ç$÷ëbL¨"¹’:_U³M˜ó‹1QüÍ‚êýì(ùôÞW2Xâ+úôÁ‹ù¥ËSô©Á‹ùÚwès“ ”úkÍŸnN
+ó(÷
+.»q¤ãN9𛓤¯Éÿð‡‡‘fÝïå’ž_i{“7UÛq ßÏ3ô›AKæÕà!aú÷}DÒ€š4·ñŒYA™ƒìIË1ÑëžÃÔÃA’~Ö%‘¼o´2k)ö“”6_½i>).nýYZTi--©²7«Ê¿*~ß|AúªöŒømíI^ã9æU‡%õ¦ó€$·ÛcÅIi~ÉYIAåYìóLMRºv
+¼.åGÖlâßû‡&ÿkBõ·Õ{ȺÊd}Uâ®Æ뢾æë’îFªõƒ­ äoæ‚’?̈’_,…_ŽR>^ 6xJ?UZv=Š|jò£*>œ£^uËè[½<"èí*àõz2´V…¼ùQ¾'~Ñ`iúªü¢,·ìŒ,»â4«ÁTö°ÊÂ4«Êœ~Ü&až~Ï»æU‹¥8¿á´$·î”äiëQñ“v "ë»!ñh€Oãø˼jµ”TT\×V;Éš*¯›w…û{²õfì‘·Q‡ú^Eˆª=%-âÒ+êuŸó¾õ,Ó\ídÖý6ä`onøñ¶;1gš“¢.ÔÇF]¬
+;×y¼5#Ìt /€ìqÖür‚ÿèwCÈÿH~œ&vL[@&|P¥n è1©ýzàÛ v ^,0Nø¨B 1k`Ñ–'7¯-ð>Ôñ<ü`ÇëpQU“­°è»¹ÑCV]àþbÿ íHC=SDQ–
+b‡Û %Ùu¯ÃN¶Ý»Ð˜œ|´åQ¬i}±'Ä5æn3)¾Ñh"ÎÆ÷éÍû‹fuy^²×?37›Œ¥w[Äàg˜öF—mØæ"bÞ»‡y•x‡ƒ ê¾j:˜$ýT`ÑóH~¥NÎÙdF‰SèýÇÐä÷®agšÂ¥Ønue‡m»!í¯ô—ô7ûì|F7 XósX2㻶0¶kíöt•úEÇìYÍyéÓŽ£DÚû ÿ÷ëø!Uë„/¾Ñ²Ö*/ËŽQGÚŸF›öV‹Z\$õ×t¿ •vVùÐÅ'…ŸLO~7>ï&éw­'èŠÖ šoGè®:'Ø“ƒOÃÄÕ¥WL²Õæ¥To6NØaôà‡ªQ«ÏoúýØÉ–´ÈÄr—ˆ˜
+×(Ÿšë1®5þ±ç›b-»FH¿TI>·ú‰>µùˆ¿µúì~úscBô±ÖÌ0ó¾'Á‚êGŒïý®Aßú“d·â8? -ò|´š (Ú Ø•ÎèÖçbèÆ7[Ó´:¡4¾M‰©ØK†¿S!o|Ô–¼j=iZQê"-­p=í1¦ÿºOR¼žð/\Ë—¿_O<$¤µ¥®G><9Üõ"ZÖQê+þPãa:Xr±16Ö½Ö7έÖ76¾Ê9Ò£Ö7QÚR|ªk;oÞÿNîܘp­þzxpƒKxZ•£<£Æ>øv…C^oèµr¯0Ÿ÷^¡>×Ã.×G„èyÂôô¸Q%ý§éæÒç '¤¯ÎH «/Iž7eî7SÌ­fñÇF/Á kÍ|í¼v²93ú\sjü™æq'›ïÄK;ª½¨âÏÇù%“
+k~%*ÿ~Œ÷–56ÌeµxI][S?î¿k½x §8ì`wnÝÒs….î<E—´ŸÅøù¨$¥É˜Îü` ~X#½+?gÖðÆëhÛ½¨ƒíOCµ=Œ½Ð””lÛ(ô¨öµ«÷ñ«ôI+w’ß«µ É«µ
+,m¼ä_TeTPaTRcPYmPŠ¿.¯´*)¹œSj’VêêWêy¦!)´ÿu€x Æۢ멜¨ûã¬à)Ë'þC@ßû& õŠÅ;ˆn|4¦¾jJntRôƒo”¨´ã¢´·ÉOÔÙâÁt~p“ö×J>•R=.¢Ïí^²þ’ ³ÞJ9ÝÒi'xñ›€xþçל5½¿&í¯
+0ë+w©ñ÷©¿žx¾9=õ`ç‹0io‘ç¡îGº²¢wÝ ·n ‰¨v »_e'/ªµ*h°
+|ÝhXˆ?æÕYæÕZ>¯º’Ï]b¥sXr™sX|¹K˜G¥O„ìS¾?¯”•¬Ü`ÕEÄ’œþÒ]’Âæsf%Å®f E¾æíÅ!â·g…DJŸ†$£I(yÜvHZØxQR€cò«/ÒšZwŸ
+ïDÇjy¢yk‘\”×zœ¸õ›ž ¶~›ðÆ-úi¯XÔÔèr¡1>áDë8³Þ"ì óÂÍúŠC$_ëvg‡Ù4…ÅÆÔ:EFԺƞiI—ö¿`:êœvdE»6ùƸÕ{GFÕ:ÉoWÙÕUiòïÓ«²+òÜbÇÈçÅaY%òÈR·Ðc홡â->¢ö&YuÕUQ~ÛIII­•ø}ƒ•¤¼ú
+œ yñUl×Þa^å^á®å‘NU‘qÅn>åÞ±Tg“ÉVÀodÁþɯÌ3:²È#<¹È-Ì®.ÛW\\`Åõ¸cøµ‘ƒŽ†oYCÞÖPØüý,üí“÷ª|3}«ý2Ï´ÞI±ìÌgÊmDåeç]kÓ`ŸàzUir»Ú>$¹Ü)ä~Í•¢« ÄûðÃÝYä/ÝÎÆ=ìQ“¾œäg/ß?9šõ?õ·¯
+‰ô©¼]âšVäz¥24ül}|è¹ú„ðcÍrYO¡¿E÷s¹´§1@ú¡ÑWÚÜê%züËAòößõE/~9dÑTz®)=ñtsFÌáYz_†ìy.úØ~èùÕšîív«ò;Üq7Ì¢ï±Ü¤=nÒ<x˜úPm{¸ãA¤s}È Óº¼«¼×¬¾Qú·­FÞOYÇMåÙÇM7ŠoÚhRþ»˜ìí´?Þy#2°Ñ52ªÚ%̲ëŽÜäWö¼a'kjÐÃJôûY©~+ÒëgiÃAÖÂä+{Îä{ùVåÎ|¯r'¾|q0la%¡M˲ÚäÛ%ÅÍ6fÕUžÇZîÇÚW‡&„–_‹M+s‰´iŒL”vWúˆê˜ºv[q]¥³´·Áÿ\CJœcUH¬MedÌí×°ÇoC¬ê£°Ï~)ë/¶è.·ìÊŽ¸Ø—è]ç•èT{¢-=‚þ­ë*ÕÑa/ênľ³<ز;'âd[FÔÅæÈȈz—H:ïѧf/²ëó²ã›-¿–µ0*bô î0Œœ¥ïŸ9O·˜Uçw~?%þ¥ÒïZ…wDR±‹Ç=ùí"¹G©OÈɦ”ËŽ[!tÿ€SßcC¿þtÇñÃLc‡ÃÑö¬h·j¿Øû…NòWïíB² Ãî½uÆÿ¯³üÙ[Gyò;·ðC8ÆöC|õªðŽ|öÎAž_l”}VI¥uÀ`Ó%¿ø*¾έÎ;BøûGGÝ–oò½p¸óNXjƒCDQÓåÀ§ ¶òìÛPÿ&xñ÷2_ñ÷Jˆ‡æƒ…rAÿ¯õ_°jFvþ“´œQÜov^a@‚¶ïÓC[vîE*;ö¡M*êhÖ=h­ŠÚ ÂCª„ý0Í+O§h¦ÿm¥V«E~iwt(
+I~u-ìö·Ð௰È<Ï°¤7y`¾OøUŒN7¦GŠz{<M»*‚´eEb\Xê“øÖ#2ù½KX&Æ áåî‘€ó?nú1/(¹Â)ìöoÏ­‚îµZÞk·
+f~4\7Ìü´•g%Ÿ¬¡/F«ç)£EÃg¢h&š‡¦¡9øRÆŸ¯=­Ÿ³íÛ'Fº’+
+Ú2Å»)´lÊ<4ÍÆ¿5MPœ‰&+ÌA³†+£y£—!åiëТy[ÐÊ•ªh«ñ´ïzÅ —ì.Ã*V$ìüãù–=(zûùŒYÇ;yÆ[·ˆ‚·öÁo‹íƒóKmƒž½³‰+w /õˆ¼VéëR÷Ö#â.·§.ò¨wW#‚ß_ ?ÐûLNtür™êëu¾ÒQÓt9 ¾å’?>CÑÄ>½–§“ùË:û[Sõ¬S&:ÜŸ©ïûNY/óËÝì¿oÕ{ÄîÔ‹¨[¦Æ?Š–(¯G‹f-FÊ3—à5Ì@Ð84Acñ5 ¥„¦#eÅhÉ4e´~› Úk¤¨vùÅxõèÁùZM¬¶ñöÿÖÚ´ÿe€¸·Ë[Ô8è*nêöt·ûýp'âj•oTô[Ф|7ùÍBW9ö‹¡iîaOŠäoÞÛ§»„b,Qè(Sà\ðÞ>8±Ì%,´Â#ª¹ù¢/Ûu&ðK›uÜ/}?ûœèH6ú=¾¿ÝªáöfÚ‰õ°;5ÐòeÊhÍÚHÓü¬‚®û™z®iÓ5Ú(.] Œ&£‰h4…F áÜû¼.Eü> )üùõpüñxÕcñoÄ_)rßßš°mØ$F»Ho…ý÷ØÕ¢¾"Wy®<ò…w¨<ßSžïþîjhdÁµ°ä÷ÐÔ|·Ðûy.¡/óä9ùN!O^;‡dá³y¯ØIþ°È1ômé•àë•>ÑÌ×OÑçzOâ—OΗZÂ#^7ãÜz)0¼É1\§‹5Úcz ­˜½ÛáTüúáµÂ¯J[ìÍ8|Á+†þã ~þŸß¸ÕÀo˜€F ›‚?ND#&â¯f YSÖ u[¢ýU3ù8n ²ØG’ô5ûo¹™‘çZïœöÖ54ãK(ö1Á¹EöAn~‘æ=OÝËü£À6:„d½s”G»‡oKýÒâÃüÖèåÐèUõá‚p³cï7öäþ°7ó6ï1@Êãgà5Œæ^ÿHü
+áó xMÓ±ÅMÅŸÁçÃþËjþóÛ0nuÿºîaøön,þ{3ðY\½÷Rój¡y›]e4Àa:z<dí•~-/BŽ¶d†]®‰Œ´ª ‹xýcYl“°‡‘…×Â`³_»…½*päö |é“|§Ð†b‡ðŽ2»ÉÇboü÷, :XƸ=!øÎZë¾gµvY¢)x‡þ_¿Áþ¼#ðßÞ³™£–¢E‹ŒÐ:­Ëh¯sÕ$Í.V‡üTf{¡$Î?æ•Wؽ7náÏòžæ¹D<-rŒzøÎ1<7ß9¼ð•Køë<çЀwžrçŠÀÿRÏp¿òkai˜w•ÛËo—:†Ä•º…ñ¿²´^³*šw§«[Ú(¬_§‚f)Lâlp ÷*þO›Sàî¿"g§ðñ?¯aÈGâŸâÎÞÐ9Æ}ßßÇa¯:ÍBSF,As•ö£»Ž#ó$­zV‹øÜioÞýØ7³È9įØ+ìDKZ(ðá3 ‰a€Ë€Wbìê‰?ÚÔ„†mË”Ã÷3ß;…”cÌ^_c4„u­ck#-ú²å_HÔ/Žš?{Öÿn¯]ë_߃õ*þù³¡uäîÌX|‡Æâ÷IÜéò¨C>HñϵŽáÎßÌɛЪÇÑÎcwGhÝf×
+»Y«C-ÏU&‡Ëß^çìðtCbhMžKÌû§ð:¼‡õEN1M….ñMïcjÊìÃ_¿u
+Çöö´À9,¦È#L•nT•¢¦qgë¿ó ÿÛ·¿Öùß½ÁšÆü¹§#ñûhný“ð;Ž‰S· …Ë…h¥Ú%´Y;lO;ßð3ky¨áε¸—žawsÝÃs߸D¾ÍwŽ)ËwI(-vŒ{Qà™SàšPà.·/ …Ë¥Â/Çwyx¥«ü`×Ý
+}ðüjÔ»<çȲ§ÈòBç˜ò‡ÈwŽ‘……N‘÷ß9…æcúêC|?ì½»\£U_µ^ý½–¿ü&øˆ±œgõçç£9?2æÏÏ'ã}T±ÍÁû4wÚ4oæ4{Þ^4w©&š¿ØÍ^,@³—#¥¹šhÆB]4o9Öê¢]ö-ÔÞ²ë%^:¿ô åpKáõÐ'NrŒÍÂ"ŠÝäg†÷¸—ñ ÆbïßÛ‡Ö:†9„â5Ê ¾±v÷WX¼y'Ž­“ÿíuŸÍy†áÜçC>pè ŽåÐÈ$4Caš=vš=e=š;k/ZºVŠ–o?…m±Ä×q4w•Í]D¢YË4kÍPÒDsæèp?[ÏG»j'h~`µúØC÷¯ž)OôyîZòÂ-ªþkLq¾K Žñ‘oŠìåJ"*ì"úkl#jíbkJb
+)M]‡}óJ4sÊZ|þv ÙSw#¥i»Ñôi{¹µÍ[a†æ-– EëO¢•zžhËÁûŠ;ü»¦¨e³+ö³*FÙÇënx}‘ëYïQ÷©ºÔ.´­Ô!Î\{­}R[•CB[ý•ø·¥˜KxiÔ²{–®Öý_ÛæÐZ·Ϧ*ÌFS1CÂçj>sÓàï-@ñNÂ×´Q‹ÑŒñkðÚ6¡™³U°}ªc›4Bs6™¡ù*gÐÂ}öh©‘7ZÉD£•dÚhñLawÀ¯3TKÙToñåKñn…ÁÁ^…¾!ï1öªÂk{ôÞ!ì Žq¥Åöam¥ö]åö‘mv‘y…Žáç«£C4ß²»fOšóoïÛ_ç ü=DªéŠJHiäB¼¦9اãïOÀ{âÐÏæ!¥1+°?Ä{7n=ö›[ÐÜ™{Ñ‚EZ¼ù8Z¶×
+-ÑrFK5œÐUk4_Óý¤i‹VðCÐÓ…ž­“Ôž²+yýìQW¡ÃÏÅñ¾®y!AÏ]­zá_÷Æ=9/Ï) 8ƒ™gä…ÆèÈÌêË®pyHñÇWWÕî±KgÏ^ÿoÇòáÖŒˆ£×pËÆ)cß¿) _„ýül‘38Ûœ†ß§+ÌÄë[ˆf[Œ¦[ˆ}#¾&¯B3§cÿ¿X)¯5GÊë,ÑÂ'Ð’=Žh‰QZ¨çƒÖZÞUØæQ;nï]v‘F«†qðIiûK÷ÓÕIþ¯}Cï¾t“W¼v«Çk+És ~Vbò¡Ê:ðS­mt³m|Yµ]l\‰kˆÉî‹kÅVÿ×=ÂÀÿñõ_¾d Á»5Ÿµéxgs×tÅŸÒ¤õÜ^)Í×À6¨æ`;üi“ý´Æ>ÅÍ]¢‡”æ¨#¥…ZHiƒZ°Ÿ9_´éx–âÖ€† ;o°³U+ØMêì6㯜°l¼qݳÈ;8:ÿjö¯1–Æ6Þ\eÓYc×[gÿ¹îJ\w¥cBG…=ä’äº-,o±òökßÿÅ?ù‰x-}Œ_‰”RG •uñ:ÔÐìØW¨¢™³°ÿ˜µ ûL|ÎðY›7{7š;g/š¯¤†æ-â¡ùË)´hÓQ´BÓ­& õGr6¹”ÞØ<vçö§ÝI?æì+`7iw±<áçf[Ó¶Gîo‚ƒýsýäåyîÉEŽáO߸„ J¿à½`õLb~Qðý
+Üž_Ÿ¡„ñð,54s&RZaŒ–ï;‹Öh q­¢ÍÇo*n󫙸û;_5ïO%»u_%»üß.Ÿº)*GÓ׋½ÑYè°'oŽØãT:q¯gË4õˆ¯óö?a7a|¢£ÿ kÆÿ1x‘ùRäªßÍŠt|Jæ„6­0(ZAÞÿÃXTÒ}^üâÛòîFÂä¿©3™ÿ0?únÎ<ûl.Êî•ÊžT•ä·œƒ~'£"ÖDMâ£8]ñŽ{“6uôBŒõ7¡Ÿ”ùháj3´xÛ ´L˭廣5:к=GÑê-$Z¾F­X¡…Ö¨ˆ
+á3lûù'£vØÝ—ô÷EZU¬†^kbØËš_¾;X¶ß~wUð훕ðó[ý–ÑIÿu^|×ý[ìÃRÖ˜WÂRü
+Ö\Ø0pši¬µc>T;ì}nÑõ*Lü±Ý‡ª°â¿g¥ÂÊǘÎV7ת€ØŠR›
+¿p¸Á…‹”Uþ »T
+ž%â þ¹ ö”kô<"²t+á—³‚òÊZN_»¿\œÜ¬g‘^%eÂKw2WügÀ3”ÏådRÇ>*ºf7øl0í£†4³’ôTûȚʼMnÿ]]è’0W]º™x6H›6{š ¼•3ß¼?Xkþ¯ìEÏNév°„n6»]÷ræd5Þ¤-92Ì0ºa ÝØm#*ë¸D=ýÆχOÙ¯ª‹Œùæˆ{FÃóù
+Âûé
+=m_ºí]µíSGf ѦZžw˜và¬ãd™­ß,2®pôùŠžÔ›9í|"ó³6?£k¯ðjÒ|Â;s1u§ƒ}µÂ[ß´øm›…Q·‘·þnÀ¯ØHÚÄ)§®Œ¡lCfvQ· ˆÌ-~\ÅV~Л•¼¤nãVËø>»ß(óǃ[W1¸ÉnÑÊgwj÷³Fz¿°íAÖP¯ž50xÇê½bõMŠY†—Ëêø?S6<í8ÒÈ⌢ÉÓŠzºÚhǪh߶mHg„ȃ—FÒçÇà MÐ}þóÃÁ_Ðv‰s |oIÏ”…Ü<ϤeR{o%ú´ËxÚ*|†0¡vß²‡òHU¦£fSNa³…ØJsËO(yéA¾ì”¯Þ[$° ˜Jº?\"yÚrPZYî}²wïl©{ýABóÊãÖ"êBðT¡Ï‹Æ,Ÿüb¸H÷»[ËîéÍ3cµ/eOÒ:Ÿ1^÷!»•ÿ‘½ ½|üJÖÂÈ)}¦Ž¾)ÒT3ÄkÒD;TѾ»ðŒíúf›‘(³Á˜LnRžuk,!x&OŠì´ÝxN­Ó5½],ážÃuMT†”&U8s„ÏÍ¥äùë kÿ©”_ö*xþDšØ`Ï0™<éó²ÃâœF©4»î
+þ +1¦jgu°æxß uï²› ýë—X¸ŒPUå!mc)2’^Vä_ ¬©/F{¶i })ÒVÓEjk¶ í=û‡´hD§´´úî}HWÓ x$Ë,ÍÏÙN4sI\bîvc%<$u šÏ827Ú Ì³*ˆïn|ÖÚ‡Ï$ÝR&TÊ‹7—§ NûŒ¦þ¡&Ík>OgõRܳ.61Jð<3qýÖ"Â%féœ0O虵Ø8¡n‹qÖ “›_UM¢J7ðRTŒn|Ýa”±lË3©ø›Ô¤èo´ÁÃßwñÜSgóæ§|ÛAæô“&‘­›¯DLÚÄÌ^
+œb,:4LMeÚ¶tÚ³AàsGu ϲÁ,=é%Ïi0‹~¹žÌìÒ?¨‹ÖŠ˜¬fJt§Q@eôéÁÖRNÑsëàŒ}Â\êJ4ö·Ñ³‰kÉ àòoökùfâšÓÄ£Ï|þÍo‚ôª‚_öQz(¦¨õ¬(¯õ„àæ÷}Âó^© î §”yüØúmÔË™´¹êêÑÎG1Lg³q.Ë3zÎj…õ­1tÈQÚgtéQgŒ.ÇM6Éfµ¾Ï–IÎ*ð-lGÍ.7&)¨ïTÇço=RÅx„¼è5Y˜Þ©çƈ133`n1}àÌpÙEŸé¿ç›EI:db©š0©j/Ò¢3 dw«¤‚Ìn òj†2å>‹vK^
+i#Ÿ. Åq>c@MW½Ýäf¿šða¿1ñºKF½è’’¯z͘¼öÃDN¿€÷‡ù¬_Ì¿õë>â¤û8CÆ|˜±ÙYEx~‹Ìø¬+}VwÌ´ü­³ì}©=•Û+5Îþ‡–à1kÄó}»D[p­QZ‚VOX€?ÎCZ4âµ)8f3ÒÄâìpâÐå‘Ù…ájû4Ñ^ì?÷ªìäô؈óÞ©3Žãøæ–
++D§/•\¼:•ÓŒ:j=†±8=\tòÒ˜• ºÑ`,¹× ¡²:M¨y¤•ïTArÝN*µKæR—}¦ˆì”¨ä: éÓw–EÏœV=6{YzžJí׆gЗ»‹(yÍ6Ê÷áJúj¢2ôjåwo%Æ +ù7¾¨ñÊכ؆Nå;§Í1öÉ],89ECó…-»Ðn ¤¾Sòƒç,ù'<ÆlY¶-;-™0 ­™<íÁøð•©SüBqÀýõðLžôú£µLdåSÌ•"³ÓÃùB¢eLJs³A ã¼ûd±Kð\&ôÑf*áí^aBÅ.Œ¥×Âþ ¢*·²>ë2÷zHAjËÐQ ÎyMÝ2èÙ:"¦nW·‹NéÕáκ߽Ôµ”…DxéVúN« õ U{K½î0§ó[‘Oº(w®ó'\ÇðÈã
+ÚZÒRã!̹?ê4š<0™´Kžs£HK‡Q<ê(ö§ÈŸƒ§`[ø‰rÅ—_þ:xn…º1 O{f-'N8Œ!ι§œq<¿‡ñ`ØLÊZ>ä#ý²Wqe»¨„æ}Ô­}úö™Ñ­ÉÍÛ¾ÛeD=èÀs„¦Ý—kù™ýjðpYèù¦^ôË)ƒ{ø!o×ò“¾î‚×OZ¹Ož¶Cyß_.LP'R÷ÁÜLÂçÞ2ÂóÁR¡üÝ~R÷Nã[ßU—"§j™£ÍË7 µÓ¡mKÖ£]6¡ýû÷#]#´_Ç6ŒõL¤gD!-ÒÑ3FƧ…VÁSaö øxFf-¬?š´P øØ÷‡8ý¸ð7*LbÓ~2©YfvgœÆQÞKè›MFÒ;b°]Ú3}1ã9fb‰nÕ
+Å9uRQv‹„ºÓÃ#Ò?j_´á™02ªzÜC‘sàlÒ;u± æÝên¯‰èYÛAÁß´ù¾¯V}K×'ön3IìÛ)ð¸µÀø ÝcÑY=áÁaÆ.'ÎLä»2rÇÆmhýOËЮ­û¶ªö›‘0^ríæ
+iÜ;-qDÙ^Ð]ƒ9t0¯/”!…8=LÇàÙð¬?Ì}y¥,ƒçHqø‰²—+Q®±ó…qM»ÈÛƒúDæG-2ðùZÚ&J‰ÂÌ‹§/ùLåžÉ³œÃá›ÂÜ\Aïì•DèË dð³u”GæBÒóîAjÇ^"«ÇˆÊê6&R¾h×î/†y|Ù9EuDof=œ8î9ÎtDØ?Ÿq3õfÖ#`ÎÌ$8¦íãçÒžÙ+ˆðZ°/˜ù‹qÅOÔ9ŸIäÙÿ½÷Ž«ºFeƒé¢:„ÎP 6 ñéŦIrÁX¶„FÓG#idi„4²-cã‚q°1ÍwÀ˜ !Jrù’J!äææÞ”Û¾÷~ïûýÞûã¾µÖ©3#Yg„ÊŒ8Öœ³æì}öZ{ïUö^{­-§:ÖžâO­: cG†6¼rEÃÓŸ©tyÇw+öÿJų• ÿš¿ó۶țŸ56ýèÃtä'¿[xý¯·5<ùK>²¿á¡ïNó‰x~-ø“n­áÿªô­Þ÷M_æ‘3Ö¾Èwäÿ¾ÙwôU¨ïÀجò=ÿ¿«0XâîI¸¦Qk›HqZvÀ×øT¬9tÁm·÷_uýü²ë¯SËfͼÆe}ÙB_ ÌkØ
+ï;úŸ³}Ïýå¦ðºÝïÚ19¼ñÕ+1×F`åÎÉ¡•ådhí“çSL»À\ºø½Ï^ZóäùKrÅ®oÒ+O¤ï=•âílýîTú^úðYþE«NÄXóXÏácŒ*ßâ•'à9iŒ·Þúi‘mß÷ºî=í6Û„…¾æ2ÏþÎõ§†×ì»ç‹ï…ÿ¬ö½ò¹þçþ­Êäßg7øâ†ð}¯^…±Ý1NAððŸª1ÆÆ
+<©Å°öý—¹á#_.½þdžÐÛ_6¿ûÇ°ï¹TúîµwåFÓÿ‹÷¿ö÷þWþk^ÃcïsþÕÏÇuµ†¾ÇÏ lžyð‹P‡ð?õ±ŠçÇ1ž?ÆŽôÅ`®µtç¿ëáspm áПn<úsÞ¿èÞ“n;hNYÍüHY8³õÌð}‡/ÇØ”á{_
+´<7¼|×d¤±/u÷I¾æÞãë[;Ãœ§>œ¹z0&PtÛÑkÂ;¾ÏalŒ÷I1®×ºcR,m¾=ïñ¾CŸ_óqFðñ·ÙÐîR{?˜yæã[~ê þõÜà3¿|þ¯·^ýËÂð;ÿÜùèã•M|ÿ¦O¶ÏßÇú£¾ðw>‹"Ï ®~ü<˜»Bð¥¿ÕàYÜÀËÿï|ßê£çÏž(»Q¾©¬¡ãÓ‚þR:ò—y_Ì¿îà [Þ¼²aég£.:§
+s¶6—a|Š¹éù«(câî#wn;“r=Üõè¹Só*a><”uMßùÅ¢È+Ÿø0.L°eÀ7‰1Ñ/þýVßs«ÄØfþ''cÿb,:ÌYL]yçæÓƒëö_\rì‹ðŠàªGÏ ¯xhrpÕcçú×}´ô¡³‚K>;Ø»ã¬HçúÓwn,€ Ƽ¸˜7„ò€Æ:'†úvNÆó­þÃÿ¨ôþÓÍÇ#¼~ÿ%”«èA°svÿBÆüb˜óòbn&Œ1Zºá Œá|ùŸk"o}‹½ñûÆðËŸúÐFÀ˜Ñ¸vB1„xijhó~Æz
+<ú.‡±g07H
+ŒaÜ:å#ßgBKwœs[,1u½Ð¦—¯@9‹vµ¯¥óxŒíï﹯cú{<Ó×¹xæúSCÀë–m=;‚ñ&Wì>¯aѲI € l—aœdʱã óXáÚ£c Òrœî¹ó„—­?#r×–s0.#â…yP1wdËKWc¼:a•ZŒ¬g/ÇXw˜·ˆbF-Ý>ãb¬†C¿¿ó P.X̧ºëÇ<ê]á7þHýè¾ç´†Û“ÇùoOiy1Æ2Èʆ§?TBËž˜\í˜x[xc01!Ô¾âD”!¡Õ»Ï,ÝrF]såöµu0çÙm·ß1‘âl¬?x1ÊÔQÖEÊ-wNÂüE`§œY»ó|̉…òó°:VŒëdu‘%AG˜Ðжò„`ïö³‚‹Vžè /¡8EaŒ•¿ú‘o†·<{%Øí7aÜÄÐ3ŸÞ<ð››Ã¼ÅRÌ»‡¾U9;1w_ìÅOZ~ð“ÞÄ¿ß×üò‡Mr×»<ÎцÝ?P–G~ðEKäçLã9=´á1Žkðö8ð²;Ž .{äãþ‹‚ÝÛÏÀµªÀÊ'ÏE¡¦¡uÂÍ××”©W+e³oZPV߶|’¯±ë¸y`»VßRº4èÑ$åß®kˆOÀ˜Üã—bìÿ@kf’/°hb ¥gR¤ïÁÉÁ^¹y Æm
+<ö¾Øøò§‘Æ¿F¶ë:Š]¸á©K/þËüÈÛ_6¾÷ÿ„o{íæîûö’;˜Ÿlåîóü‹3“jêêË0ï,ž«Çpõ‹Vž0w^}òEÊSz@hÕékNÁÜœDêxŒ‹Iù*a|aL¨Z_¤,زäøH7Œ±¥Î uÃ\Z³çBÌG€±‹¢½^Aq™A‡µtM¢xU¾9=¶ýÕ
+ŒË…9«BÉô §.´ûgjdûË×b|C-¿ášÓbÝ÷‰ùº1¿F`ïû3B‡~[ºÆ ¥¼ÙkŸ¸ã`F_û,ÚôÎGwD_ý](°ç
+ÎaÌMàZbÞTŒ™\ñÈä`ǦSÚz'a®ŒðÒG(Ç&Ž1œ—uá– þ;úN \Bx‚=›N¯¿ôàwû7¶Éòe;ÎÁXï±õG¯ |3÷î¾ó>QNWÄ쌕Ž¹º| #0ßV°çþ3‚Ë9‡r¬Ûwqló+S)ž®sîúÎôÈ¡çÄžû¤.ºÿã9¡G¿ÇḌÀ?Ü3Gy|ò§Jhÿ¯*ÑŒùr¡ÿÐç7…ïÞtzd2æ”iØû™êþ¿ç`Ì ß¾/ÔÀ}G/‹¬yêBlÛ¼Ys`>…Ê‚K6žê¿cÝÉ·E;'úÛûNð§Ë&Í« ƒÍS]&_%–©RÙìJŒËÙ2¡.ž:.°lçÙÁû_¾2¸tûY'c©Ráe[Ύݽs÷…ùÌkFË0îågÃøTÀ_ÑeÆ
+ø¨c1oê¾û´†}¿žAñ~ø·xðíÿŠúŸúÓ Ì9ìzàt˜çƒíµà¶@ŽÁÀá?V7ìú±ùäܹ e·ÜR[†ù®¨–=8óNQ'ÌÉÜŸˆñŽoóÇÊ|‘–‰Ë›bD§WîZ~²?Þ;‰bÊ? ?õÞõ{ß­Š<üÝé8®ƒí™I,ôÄÏÕо÷o¸_áÕžKºÖ“ï)¿¼ó04®ÛyalÃþË0@ã¯_‡±{ÞScÏ\8ò—¹ÁžÍ§7´¤Ž§<盞¾<úÐÑk1ï`èÈßn ýÛ|’õ‡ÿPI±˜6½xe(¹é”Ð’5§øaþÕC`\éðöw*O}v}dç2ÆŠÃ<jØg¸–†±‰BÏýy.å<~º{ï¡5.$}ýÁxÃOÿñæÈ?Ím<ð‡šÆ¿« îÿ͘ 1Ú·}røÞƒ—b,CŒ£‡þ ß8¸îðŤslýÎ5¡ÇÞ—"ûþ<+rèO·6ú¸ööÿ­>óÑ|ŒŸsÙ]¿ç’Ƶ;.ˆî|“ x¿*²÷ƒj›2éd Û7={ȺiO¯sËé˜3°ï³BGþ1?|ôo pÝ×I1tpÓÁKIîwŸ¾ïÅ)¸>\óÂ% ÷XúÈÙþ®måþÅ+N¨ Å'TÞ0«ìú™7•ážÐBÿ¢ ˜Ëc÷~3Æñ%][W* $:&aŽŠØÎÉ”­wÛÙ”›æ9Ò"vøÚÐã?S"k¿
+¿ôi]è¡ï\Xzo9Æðeî=sãw(½æTÔÍqí!|ï3ŒùŒòãŒ7¼pYè®C4´ßuæØ™q&Æå ükeèñOTC´ý"+÷]H±ëÿ®ºaÿog Í‹9³p]ŒÖá6¹ Ç|ãÞOç`¬·ÐÁ/ªBOýæFÌ}Y¼ê$Ì뇹f‚û}SÃáOoÀ8¡¸&Büé¼ùÅ+‚{¿¸±qÿïçþy”¯Æ¸Mwmÿf¸µgÎ{\sŠ=ü&<øaeìÈGuÍG>F÷ývv`Ï/UÌÙÞùFƺ oxé
+Ê{µù[Ó¢‡ÿ2?rôÏuÁgþk¶ÿàŸn ozm
+­o>zÅ·{áËÚ¦7“ˆ}ëóæÀÃ?õÒ>F÷Ž3ý]÷†¶îm`bÞõÚðâ 1Üûè9¨ŸâHbÎwõ¡EknñQ¼cÌ­‚ñ ·½É4m|öªpïgE»¶ž]µûüÐÞOnŠøè–ÐΟ ±•“b!£|Åx×=÷œŽ9ÎÂzî,ÿ —½ú§ºØ[¿k£˜j÷ì¿ØÈ…zT Öü°ã¸pÆÝóMÄ·qõ¾K—ïü&Æ@mZýÄÅe-åÜ
+Ä[«™-«€Mž¸ûD|fa¿Ì×Ô21r×öɸŽˆòí7¬×00ï´¿ ôŸ»Ÿ8?¼ý[×`¾
+ÌÍ=NCÙüy e¨o‡’Ë€ï<?¶õù©˜Ë—ôJÛä'÷Ï[&Ò·ƒrþ¡¿•ÿ™?TFžý¢†rgaŒôTßÉ>3wÖr=wVïÉM”;ëeotÇ÷„Xf󙾆øl;æÛƽÒÆ•œ{ðÅëš7¸²9³žò[“=¾ò±ó(ûžŸÏ | ‡0/ ŲÇ|”›|×y‘»Ýë…+Q†öüâúÈþg÷þâÆÀîw%ÌOkaèŸC¶Ì~â~äûÆ’G¿ÇØ–o_‡yIcÏ~²0òè÷ÅæeÏ µ¦Žoºcå)`¯]~òýëQ ƒ-«å—Ôrg)wÖ'7Fžù—ùÑ£_܆>ÈhP.Œ®u§ÚWŸX¿hù$rýIFî,\_Âœ”_é¾SbÛ_©ˆÝóð…$ßïÙã ?üÒµÑG~ 4nyý:Ì]íZ}úŠáÇu“Æuû<¡ÇÞâ´ü?(o̦§<ø,ÊŽ(æãÚþ&Óxÿk×ÄÖ<|>òâ(–oIù·0Ï}x÷÷äоOoÆõ5ÚsÇ\‚ëv
+Ü¿¢íòêïýHÓЦƒžÐ’•'ûB‰‰ ÍmQv’þ‹1ýWlŸ<N¨ì¶ú– ¡Ö»NhìØ|:Ú·+>sž O?ôÚµ±CŸ. 8ȸW±øî“燻7ŸŽ²Ðߘ>®Î×2¡}~@ö .…r¬qõÞKHF‚\£<»¸æ vú§áz©–¿äÈÁ‡ßÆØú2Ú\Á]o3˜‡ qÅcçQ~°5{.F¹Ó¼iñ‡Ø¶oO‚­Š9pp}SË)¼ýl-ÈPÔSw¾#`î7Ô('
+æà]ùêšèw‚¹€q|á ÌŒôÆu¨‡„}“‰<öžŠº"î«`îxÌ‹‚y~B;ßšNcsˬ"YtUä©_ߌã3|è_oÁýºØ¡OæÇü6þ‰yéj`þÄö‰”zÃþK#=›ÏÀ=}ì“`úîSp_*øÈØÀ“ïK˜;«ñ…Ï‚ Ï|y3æÎ
+=ôò4<óÞøüåá5/ÂXÖAZsþá4Ê…¹Bp=럛N€/æκWËyì»bh÷O”´Þ
+2¿qÍî‹I×¾9[P>ñ=!²ðÞ|à²Èƃ—Q®ùG¦Äv½#†ŸxW¡¼¶¸ç’ÙtVÓ°0‡ß–£SÃû>¨ŒøíìÀn< u=ø浘Ïó|`¾§ØÖ·¼+ž<?ØÞ1)òàË×âšF쥨ÑÚÆá?ÜìêŸ$Êï6Ù[¿}]dÏ/nŒ<þÞ Ô“jëãe¦¥Ç‡ãËOÀ5ŸØ÷œŽyPcKúNi\¶urxÿ¯ª›þ¦ŽrÉܵã\Ô`ÝVözŒí`cæ0ÂucÌGƒë¤ƒQžÓU§4®Þ}æîB›/²vßŘs#²ñ¹ËñŒ ­3­?zEÇ+®_¦WŸ¹síi¨‡QKÑm¯^‹û”ã½óžòPÛrÒ÷Q‹nzýêп˜k"ч.Çœß(¿CÀã0·ÒíQâ‹ëŸ¸sVÓ9—/hÅ6ÊÚØ÷À7(3ô ê¡‘ ·ÁFC}ŸòØ ^´ñ€'´'Ûóá®
+ãœzò‡”c=vï³Whõ¼ÇÙ‚˜‡zÛóW‡w¼QÚýcƘÞõ#ÒYhÍjÛÑiXå†ÛãÞ‡º
+÷Ô׸ބù¸Öï¹×®#‡>¹ø·7ܽ®<’\yr¨¥{RtÙÎo _Oè¥?-l|õ÷Ñ賿¯ íþp&åìÁ5Ê;ý&ÚûËÂOýòÆØ}Ï_M9Í1ç-è|¤³n{uú"ˆ®{âBÌzì{|àÙ?TûwÿLÄý]Üo¦³Ž© §’LzàåkÏ£.íÛpé)w?vAã½{=´'ü=°ûÇ¢ÿ±·§#}0Ï:Úó¾hÇDÌ_A9U@®ÏÛ´}X®¦¼Aˆ7è$#`Þ‡¶¿<5ú9Ø-<êõaàO ‡­:Û¾g¡ç¾¸s
+íþ½?¯DžJ{ÓñÄqh÷¢ŒÅúƒ‰ô$ôÉÀµpÌSº½g’¯¾Yˉ¸òñó0§
+â„{cÁö;Ž_pë<Ði£e‘¸Ç¼ü¡s´|æßõFxi®¡â$êŒÑîõ§SN,Ѩ#aÛ7½:ºë‡®ÏD7ÁøƒöÅ6¿1-Ü÷È7Ð'"Ô±ú”h汄ú‘ÝýÔ('£˜Ë>}÷©¸~yä"æ<¢üA˜k sí|â<´³iy5ô/æ Ã|y;^«@}„òVcÎöÏ\6
+åçÀ½sä唋gïû30w–!{mU·¨aˆÀ¾?Üxú£™Èó¢€.y•PÖ>ôzEàà畱ç?òažÜ«§\_K·œM¾'¸Öˆ>@[^žÞz-æ7Æ{äO˜wùàG74ìý¥xôÇíé,Ùc昖ßxÏ…´ˆëè;¼ê±ó5yÏ%èGàßû3Ò"›\éoí›ÔÐØsÚ˜·
+uÌ Zù0È™G¿ý3‚þV[žŸ»çÑ i¯ìÑï°¡}ïß~ô]÷郭wŸP¾c‚1Ȳ Ïxü{~&cý´_s7Œ‡µ{/Ä9ÞxØxøå©þ}¿˜áßýžä⧞E ¥VŒù1C}'Gï{f
+å‡C’{ž¿<rÈÐŽ{Nõ=þMÌUÅ\Ú †·=<ô•kqL‚Íuî½!Á|SÑ®§†z6Ÿ]¶íœÈúCÀ£ö^Dë|`3‘½åF˜_ºv~}Ùm>êÑh› ½‹tG= ÷[Ã0fÃ+N¦±9¦fÑõû.A_žHçªSb(Ïw½-¢¾‚ù´ÐDŸ­ØÆÃW ïÎ+lîG—?q.ÚÎÈ¿Q¤¼é½[Ï&Ÿ#Ì¿ü¡É Ç&“œÇ|¯ÀSÂ+v‹9)Ÿ0ú+®ÞC9»c¨û`ž[\£½kË9”«‰xðwYÊóŠk& ‡â?ü–Æ0÷)ð8Ês…¹bqæXtÐn=Œ3°OP/Â16ÜõûuÂàžH‘¡À“ò‰aþPÌ?Œë<¸N¾|óY´W
+:æg‹>ó»xŽ.¸ômô¥Ýt»ÿ…«0å+Ã}º•['£„¹ëpn?<ôíkÉxëKW¢¿+æMÄ„è/ˆó‹t -ò«Æµ{/!¹´íõ
+Ê 8‡ïß9Ó-Ï]xèkÛÞšZ¾k2ês„ú½<õË8Ÿ(ÇÖ¢®I˜'¼þè?ßØð­?/ ýó‚ð‘?Î<øòÕÁEËNÀó!¨ÿAßMÁ<= ¦Ñ|Ä܃éͧS»i^gúÿ¸÷ã~Üûq?îÇý¸÷ã~Üûq?îÇý¸÷ã~Üûq?îÇý¸÷ã~Üûq?îÇý¸÷ã~Üûq?îÇýŒðgÊ”Ùm³â™xyè–ò)•óÄf¸¯÷dÝå ˧4O¯ìÎÌJ¶f’éÎxwŸg‚B jüófyfx¦ÖÄûÝÍL³Ø<Í3Ó3µrË4Cøušç:x”ñr‚gz}"žòLÕ*õÀÏžÚîä¢d'
+–ûmW@éQÕÝÛ³¸.žöwšDj^˜î¬ëNvf’‹**4pUð²ÿP¾° ²ÐO¾ÀÜ9ÉÒvºy 4EŠ.L·%ð2‹Øþ
+é4íéQÇ°§+ÑZÛ;È1ê{ƒŽ» ЛŠwÏ^Þ•îLt:Ç-¿àècY(’ÕéΞL|HZKÉRs >N‰´Â1UVŒ…é)€J‘[Ñl!Ý2ìvôˆ¨"uédg¦¦¦‘Y«Løô[£‹®ÒÓŽ†´¾àî>ŒÅîCÚC±«{£¥ •ÎvJ±ðÇšÎÞqà£Å«²-qÎÑ–ŒCs,¿— ²8dGD(jDé;;"lñs¯â—™ñîdfqG"ã|c»”dçèìÜú‚I¦.žÌÀtE¨³(é[øJr©x˜,Ht/J %KO%*tªã.¹v¸ŽGãõ²®ãQI8U§Ó©ªîDb…ãmŽ¢õ:ú?©Å"_.`V[ÿª¶d*î|›±”Lçë¹mÎu•±à-ãÐÎ1"%³ìuì¢;Þ–ìuÎìÇÇNENww-N§Ò‹óÀâ1[Æ/ws~V¦È¹Û¸ái#ªÌåi.OCµu¼8ò¶vÚ¤ˆ™X'‹œ‰9î’R[L/U÷Ýñ#À±ƒréÅp,@Ýý"8F1Z÷[Ñ &ç"¶Ø%“se´Ä$S)GmÄÊ&–
+;U2VÇIœOü¢whiqÜ7.+¾>)•E‚JÇ;(Ջ㉔/‘J´²È–_pÔ‘¬w¼á5T$ó Ž™8š•ìéJÅ[‰ÎÌ‚xWéÉ$ÆcüçÉ»d³.v+]97:ŒÇG}œvÄ¡*Ç[Ï%¡‰š²˜…˜sq\ìBÌqŸ”š&^o8˜DÅÈöZ¯£ýTq>é‹|ª8?3[Š¡^¸äÅ2ûœw Eóõ w‡ÔÉ)U¼cº½;ÝáܧýµçA´:Ûfšó˜?Ú³£¿Üì—Ì"æ|•Y{zô=RËâ}Žq¦‘‰wÄd´çÇàØJg"îøpCk<Õº íÜAÝV xwr2iç†Gz éLw:ÞЈ·¶övôîgdgá¶"£Ž[w‚Ì{Çèµµ%3É¥ gƒý¨BœÉÛ“©T!>ש1³LâÉŽÆ×Q)íðwÊxq›iuÝfŠÍÎsÞ%¥¶$âºÍ«ÛŒó¨c¥ç73ÞÓ+ŽWÇ™Öqã8S€-vÙä:Ρ|r¬–†ãL¿ègZÇãÌ8bb®ãŒë8Ó’®ãÌ:ΰ®ãLÉjâãÆq¦
+˜ôE>UƵãŒóWj|`˜·ˆJÇý§
+Ô\ØÚŸ#%°t¤Øø —4.ã_;_ý„çqù›#þ&¹üÍåo%ÂßU—¿¹ümv7
+báEÎïZÓ]éÐZk{™ì¥Ëª K/8^`[2ˆˆ­?ðÑâ=†·Ä9O[2,Íñ²î’AvàìˆEÈ }gG„--´Ø%g¼;™YÜ‘È8×JI‚Eê”’$·A‡S”–ÎöǺÖ=…8„v¸ûÏîþsûÏ…‰,Æ%4wÿÙÝv÷ŸÝýç±Û&Y;Ð3³ ¹Q*{Îã7KŠ»çìî9ˆœ»ç<Üö»çœ{…ÙÝsv÷œ-ÉÝs…-ξ‚ÂÇg•)Þݦ¶d{{oO¢:Ý êw§ó¡—WnôÕvÇL£·»º/»Ð¨#×—H¥ÒËœb˜J.Zœß+Z1x¬cs‹:–ú /’y<¹EØ5_ƒ´Ä…L²’_‡s“ùŽ»72oæ¢îD¢s&ðÒÄÌdg[rQzæÒd:•ÈÌìN´ÍLwÇ;Û$sèrðrèÜ:w.í.Я).9ÞtI¤à¦ õ[‰ÑW¤LjÅW$;z3ƒdYµOãù1[ý™•$Û¿ã1ö™¥™+5ºŽ^z€×Ë º÷µŒñdü÷t%ZAëè#Å;Ït"Ì^ÞJ^K£ùÇÀ¦P, ^
+EžÃ9"nxŽ"sa-öð…z9½ìß¡9Æe™T2SO¶¼ïŠÐb>…Pì"ÔpUl"tÜD¸’]ãŠÑ±£…JœR‘ nd«qÙªànu£Z ¡cÛ†qÕªr^³oq¼-½ÌÍ;äÿzÄ}‡‡ý‡,sû—‚PÚ‡ý§msœ–õ!æ‘AXª‘åE>WŠ©¥ÛÛ{œ݉¶‚Øu©qZÂôke# ½sDZ±P,3:Ëõ¥Ó/®WäF+0SœŽÓeɶœÈô§GáŸwŽÑâD!>Yæ㣎“ej»!–¿Š©=ʨV°¢ã¡è\= í¸Lœ[,}îòÇ[
+’»üQš†Oi/(ãeùÃ9"îòG XÈ¥ÆÜåwù£˜øº»üá.”ÔòÖ™xNO®Y]Ò;Øi_&™idËnöàÓ ÉTgý³ÊŒþò—c7ËÎÞŽÚÖL|i¨Ù‹Œ¾ÿ¨×q´œ–xObNwâÎÞDg«s "§Ô¨#ØÞ⦦“ÎÏgh…"h¼i”ñj-lÑÒ¡*0L¶uäóŠ¶O¾Á´ `¥~©
+&5^ƒ/ßDŒ×q® LÚ¹”N*n4%7šÒ€È¹Ñ”†{¥àhJ#²’ÔÐÛÝÒ›¥§d—Ý80%pø®
+v¼X…`2níÀ‚ÎmùéŠq™ë±­çFØ(.‹¨´#l¸F…ÈXˆ«´ƒX ¥Ã«Ýx!¥ÈÓ†-^Èh{§Sƒ­o”ÎÔiOÝTA(ÍhIÅ[—Ìôh tW¼5™é›QÀqO¦/å|ÝTzôÀ é¾R›Ss°ïJoJ}•8:îÚ阤ӥ Õã‰Æ×]5¢HXÞ×!¿¡Fd_k¼
+Øêt'å¥wn6å–u{õôv·Ç[…u_v¡QGnÙâN_§pÙ~¯pÀBm(æu$ M?\äl<™ÁvÍ× .Œä8–V"7­ÜÚJŒ¾¤à3ÒøŠdGo[¬æ󣎱¶‘‹45FªÖ¬$ÉÚšB6…G(ZÀ,?Ôè"¤ôt?W{(uía<‰Û!d‘²È-Ú”f/ïJw&
+°Eò ¯½e´µ`ƒ+¿ «=¹ÚÓÈiO®ò4bÊ“OŸÊ¥«=¹^Ö¥³SP¸jájKîªúW8Òä´O– 5ÈÖøèèŸÍrŒˆsζd,›sDñ5°#"³–½d'툰c€H¡+ßE/;ãÝÉÌâŽDÉ3JI†ŽKgäT2SOfº"´˜7¦‹]„:GġņH‘‹Ð!Ù5®K1Z¨Äq%èø‘ ¥³Tí&•,bÍhÄYHétÉȵ£ô†Åø€4~Sùû8¸ã5Ò6Š[£sù¨tuºRŽíÄzý¿þ®LˆÓ®£+çLÒx|ÔeGªr…¤8GáÓ¬ØÇ\(Ú3¸‹`éò :j¶ÀÁH,FÆ1%Õ¸%òu87WÚ!E*ëìÅS¤bÜ•%«QÆ©öksŽ¶TÃq ½‡Š;f|z¬«;“À}
+€ ã8&s {3 ¥{Š}ȱ^çÈJP·w™ãc”¥6¥J[—\<Ôžèž“ì.†U”bégÎãxç'oI%…­jf•õ>§·èÊæñ–9½­õ¥ÇT¼²‡ñ¸Ã­$‡ÛÜn¬ËÜJt´U±£
+ÙCxØ»¡;ÞÙÓî<ÛEñŒþ!ž*pMÆbÑd(Úi)hÜÚ ,Û]9Éî òÆ«L¥Š kŠ…$C³®èÚ1¶mJ
+«)•óX¦yvg›™Ê
+A"Bš¦;ë 
+
+YT¡«‹’öÊvQ‚ö“¯¯£%*ŸZÙÖæ™_šîF&RÎx*á_h^$Ê{­¯ÚrÆ+©2«ªªÀH
++ˆŠ‡ñ²‚"È §p¢(Hœ¤9)yY‰‘gy™
+,‹EâdAd endstream endobj 29 0 obj <</Length 65536>>stream
+T…áUŽó„âå–»S¨nn…‹;
+'qšJVD ‚寪p‚í)ÕË ƒïã¼ë©€jßÏ*^–xl¹I…
+–õÂk%hºàUYI´«)W¼<V¨Õ/bT†·^Ä
+€—ýÍ­å
+A¢Q=*£à»¼<#JTê…q*ÙA<:ªÆÎUdÕó^^Vwˆ"I
+ŒöðÇaM´ZUxA«†³F2!Y8¨Z7ÀÐ`Eì<x”ç¡×€>0:YU"ÀCá0%Ydõ„h-‡v1/Z hÁÊø&{UôØÆ
+Ïr¢…}ÒLâD‹@<gÍ1‚@#M˜Al˜wPR°^Ž‘­ ú
+iêH]£Ðùð°(ÊNñ"¼’ À
+;›Ò<D†ƒfH,MÞC`jÚŒ
+[ƒ’ý06„µAÿÊܦ4ç³7è®<7¥y(,nJs'¨½S+;Ó•“ˆÇÙD¨CUyÆ$+CÿÀL"•NSë@㪄0z$EE^h@ ƒU'^
+dÕ©úRI-œ-XIs»“mó}Z½\~0 gwÆz5Ô\•N§²ŸéÄÅñ¹½É6ͬžÒ Ö[s¹jŒÓÓL°~Œ²ªÞL&ÝÙœ^
+Vbÿ6Ù5½@ÁYú¼Àp²í&Ƴ¨8 ð({qö)tyì‡Ó~¯Ð$Ç((«ðFÖ7¦¬qúkÓ
+¡F "çʳ¨šÑwñNºÆ'AšÀµQ^ôP kÓjÊת‚ìÑÇæØZŽÊÈó,ìÀ/èw¤<0kID!ÏÕÖFGS¿Àel´˜á»S
+#ª1eµÑþ*r²Ç,
+
+G£›þŠ
+ªÚl&£™!Ô¼3*ÁWh5WkÔ”Wµàlðw¢ÉßæYÔoK&`ØñÓ¨S+Tì`Öv ˆõT-*GÅDÿ
+ÚB…¬Ê²õ£x@m³Õ$+žP‡íu,Ëq«i¨f],ƒ$)üu,çQ ¬y/‚À©jU䪆9 Ç”ö¡«€¼·ÊÁ
+}œeò¼) MŽjk–äS*Un›iÖôÓ'Ž1oì#Þ>lH¶4ö9§c_Qe9Çä ÉzJ–eÞÞ_ÐY xŠÔ_¶ne$¬mx9cŸáÁ6Ò¬«ïy¬©ð×±8<XF°?ŽÆÖQÅ®j˜±“­ÁÏâë$Ö6øyÛàÿª"_ðH0ÀÖQéÎŽˆt¯îN´%3žêxw›é^,ˮڡ®µêWïáTZxà45
+šú<™œÚÜ€™ ß’ÝLfeú E ¿ªËµo©Æo¶"Z5šaÕžõf½Aú…Q‹­ý:V†rê$<ÞAß20/˜tœþͪø0ü­&ZÀ’Âú±ÂV¦B«ŸTímË»£¶µëiîÐï$Ôd¼ê•ô6‰¾‰FÔûÏörzmÕ嶗Ôd½›
+ÁÍ>4¼&8XMp°)è_E"8²· ýI]T½‡ò6EÌÖ(F@p ‚ÛàE!¸ÙƱ£É Nœ&-ó«(d“K¯<™Áʪˆ¦Ÿý™‚x¬œU9¼ÍÞÖá ýáS5¼øHNeC"ƒ#áÀ‘¤`ô¿Å".²úfPqÑ´ŽÊ émšÙiÓ†]\ †Û šDa¸INÅCÒ‚#¹Ày4^ ý-Ia§Ûà’¢?1[7Í65³Tˆá—ƒá6¸
+Qn’SIA–DG¹nHˆæ9†i_c/)rçЀօmQt®qeÏÏlö
+ŠÈs,#^Òè
+Ί’飡yM³tæM0÷CìJˆ¹7Âj¹P?-ztËÆ¢k|qÆ?ë©ì¢ÆÖV-nëgìdc×Ö¾]«oâ0œeÇ»°–U§9äÛàrÕe‰çN#{k‘äÜõS˜Øx
+´˜½¦²J¯°W† ¨¶ý.UεÄCÕ0ã`[(8ce½nØ°xf kéx¯XŠŽÝ鮶ô²c:Z[Y Θœ®YÃéšÖ DtÛé0QG¤Æ„
+
+•ÊI"Ïf{¤Cw0l¶˜ømä¸+Áï0mxU³_Çj.'£ˆ\Õp"§0œö65çm„k×â]~2
+‚Às 9…ƒÍ˲²X‹€ñræ¿ü£$´lapVç*å¼ÁÚX“Ñ0h?Òs©~ŠÔ ¬écg°N%B~å#G^Æ"k~‘
+¢•Þ!¤9ÉTDZMÞ~ àcؽ¹ÐðeyŒ[ÄB]ŽNÓàF>§àÁtTcð‚YÔ˜ûYÛÉÇè Œªé v0@( –J³^£ŸäCŒbZ
+à)‰…ÚxRAD–gN”e•Ååz'ïî¥`#YãTAÔY@S@€,kkmÃEEx0H ù£Ìó¬±?®b=²Q¤âóœ¯Åz`BÓÄ{–Е¹Ò5¯si¢;“hËY
+˜Þ8Lqu¼úXG°y²H@
+ŠºËâF(„ ècÍ‹Þcp·Âh B
+øÂj¿€jÍ<cxÁ‚Õ Wì9/ŒÅV· @ ЪÒaœ—…ñ WeÂx™ö6ÊáBd­.­ ëbÍ÷HÛÚÔб
+š›•Û Ô„ê~h¥Y«úþq…Œ¡$Á*Ò‘ Ó*ÆéÊö—Ë^…‚Ú lP•%«ÕÈÃ$ÅŽ®êeµÍ³r;Ähµ3[ÓûQ¯Üì(³ ¶.6Zjëa³ …²^·`ôp­(J†
+ÓÄVRôª2cïwÀ   ²ègŠfÅ&Ì×ÛÈg6ÓF?³¤…°^¹`Ð/RD?êÒN?;LÚ^¥‚
+¸ «Ùó§á,úqÏV¶ U€È´XjÕn‡´` í0BӬܤ„Ù;—1šjç2B—1‘6¸Œ `r™\j! 9qtÚA„#*Šh#kÆÄ5é,ä_6ãÁu|>‹¦yƒãÛ΂èô³ÁLúeÁE«rƒ
+V,ú™-µÈgbc€,|µší÷:íò¨„¤‘¯JÙ¤³ƒ=jí”á‚”Åý–¸Þ`£¨0¼p¼WTÁÆì
+í²(¤XŒ› &®z•¶{B¹Ô°+\… ˆŽ¡¨˜3N×e,
+
+E"C'2Ëè:“Y§~o‘È„˜$²A´em½N_ã­¶™¦·Ì¢‘Ñv³Œ­Q§u¯Ó(—Ç­9ÂÀŒ¶q0lûÀJXò4bHQžéØ|AÚsÚ_ûÀе_uXߪ2þÿëþ«þX–ý¿qå~Üùég • ÏèøÇ¡~¾Úf+z½y¦jzà Omwæ1
+ö³mÐ!nœPɼ­“¨óÍÂ+wû„€CÙ@év“»¿•h[+P²ŸÍ‚a{…Êån°do±Ry›,Ê6K”;•ûÙ~É°ƒéÊò·`:¤M*™· “u¾CˆåmÅt(›1ýQo`J÷³I“ t¼MƒIµò7j(ÕÖ¶j°dþfMÔùv fyËÛ°AT ß²é‡j¸Ÿ­œl ãÍt°ÏÛÎÁsæCØÐÁby[:Ù@§›:ˆMÞ¶ ßØé‡Z¶Ÿ Ÿl ã-ôñÉÝô¡dŒ…oû wRÞÆO6ÐáÖâ’·ùƒÀ·ú¡Õ1ô‰üm¡l ã!(–¿5DÀÂ7‡¨XîöP6Ðéa“»EDÀ‚7‰ú¡Ö±dZÞæ‘ XÀö‘M¶–lÊp![H6¥×ZÊ:ÞF²Ô`kUȦ³l%õC­c6‹É,`“ɦöfv(M6å6‹°CÙl²ôÝ,Âeéj9Ðu³;”­(›ž›EÙ·£,u6‹¬CØ’²)¸YdʶT?´r Üf3‚!lXÙÛ,²eÓʦ¾fQv(W66› aóªz ®ÍÚ)[ø¶–M“µ“uH[[6}ÕNÖ!moY*¬ª…oqåÓipõÕNÑÂ7¿,ÕÕNÐÂ7À, ÕNÌÂ7Á,ÕNÉÂ7Âòé3¸¾j§dá[d¦®j'dáÛd–Jj'dÁ[e–’j§cáÛeùÔ\AµÓ±ð4K9µ²ðÍ4Kµ²ð 5K+µS²ðMµ|ú LÉ‚–Œ¸·¿r¬“ž…žÓ¾%Ý‘8KdÎá"IÉ ^Íjà¬J‰ 9`É<R^ðª¼H¾ ˆ‡— <¦AdùA˜†ž‘(¦!úWeY;Âóä9¢½“yŽå4/dÕËÉ_ŸÒNr )qšºÁ Fc‡QmxV‰
+(=”cÅ-uœ9ÐÃÚBxŠ¼¢d%'Ö‹ª¿=ªžÁL6TËÆœÄ3' © §Â‡KÊëXÌ4m«'?ÓôHãV5œ¸3³%öà(­\V< =ͺlM<1ZšÉ¬QXAÃÐlúà©ÐFõeTÛðÍ×ö¿Ö3VAm€kõé£Üö^[sô!þU“¤÷—~Kï\{´|~€˜~F¼>ýCa·U{ˆ¦œ«ˆ<¥‹dU{‡“-]øëJefËš.åFâq쪆;ƺ1]²'ÙSú ­Ek­°MœW¡“â $ ©£{h ®Ö¿‘ӯ©¬GûOWð ­kòª:f0'h«*Ž‚9U/è0_ÕO{úiµõP^UÇh#‡çµYUø*§Xç§D<‚¯ÿŠ/ÄòW¨Uä:Ñ Ó]þ.M#<Vé!Ä6ÃhñàYÅOƒ;º„ÉÅ[—œyYa{¢‚W¼2K7êÆà šÍ[íÔ^’?]Ñ#¨Ði…±,UÉb HãªÆl–vbö0¸ÉªC¯ººÜx]M¹­hc鱉vD U PÁ«TK‡~¥£×.)n4nÙò)5–ñ$`ÐãÓ/u"±ŒI#ýR/Hå°NÅÐmõ×bS̘O(œ‡JÒ6œÙtz¥U9Çg]iÍ0WcëZF#"Õ‡wvØíj£!_]›5t)›ÂÅsÚ-f¼Âe‡ÞåÅLnâX1êJò`«HÌI)Á²`l³ø6ÑV•Ì åm,‡Ê¬_r3JŒ4jUÚ`茪…¶4‹qò1UYûøé°,Ûp³Æ 5.mÃÕvƨ3F·1ú­9—3(íÃÕÖ¯®°Ê’]£Ò²Ø!
+›38EA¡r¼`õ„0Ä×±ÚZ¬hOàkk4vUÃŽYÅ×I¶×eÙZßí(ÏaÈ9ÌÚäg&CËe¾v¶¬Üj ·ñõ
+ÛÀ`è±_aèq’€Awì‰^r©Å©¨ˆ“eª`[²º„“…œ'°‡n<kv$ z‰U8Έr®…4B8U ;NÖ0ËeÙ©:GÁâQ˜I‡´+à~¬Æã8OÊüÝ ìÂèeYúª£ºÍ
+sfôË›éwëJû¹ÝåPŒµŠ±Y³ w>´CvU$ÓOÑNè”XxÛ:0Î2Nuñ¢Ù7A.íeDQB››§Ð_0byÞé^×*dЖáýN²®«qÈH’lAjLn¥á¾» ‚æ.K™`~"@ô*¸6¯/IÛ­6Æè粄Š—QEmÓE•dm7…ÉuÔhi²ÞR‘ÛŽŠÜ¦â ã<|*ìk[;Ù©°“«ÂNÉÖrºë^¤U;¸ÆðÀÀÂô `(‘;±Q'†-'ßhɸ¬Ö1Óo D-Äû»5¶ê¡m#û;l¯·šU]no¯•¥ºQ–Eòò3Š—x:ŽÊäa«CjL'k;¦5ùÅ´Ó¿æcÔúBݨ…˜ÍnµÝÛºc
+«"ºñŠ¯
+ÜôÃM,
+Ã'[]F7^‘@ƒxȽ¦XÅsj¶ÞZ=L{p’GPpçMYí­
+_Š;oõ>_>#×en1ï
+Û0Giý^å=$™‚). <%ó"y\(´I‹þ*KNA •²u ¬d=¢êþ>f%ÀxQk¹ ‚úA;WD•`–µÞc
+ˆt•<µT‘—HÝ#Çtˆ§S7 ÓVsÅbYQãO`S1xî†Q1;KŠÜt‰Ã¹Âk9·U‰Q -à•qŸu2/ £„©ŽÐw«âÐ
+dl§O9™gpÃT%RÑ‹ ¬/ܤÛAKe—²d oLÍÁHÇ@3É «7Ve@
+#Š'ñ*Š¸öj‚@æ)ý‹a¸)ù(®>i†êê´­TA3NEô×sg´tÑ*:²a^‰òf‰'(ZNµ
+HÒ˜*24ÖꑼN«ÎïÇc»x¢t‹1Ëø8”1<GF~E•ìTCÁråUž~µÕNdKQg\œ¦Mžêx÷1%‹m=’õjÞüè@¨/Ð0¬–Š™áŒ%†µ­¥p²æ†Íâj;CžØx!šá…NÕ,®¤0¨6à¡5„(´²H;>8aL
+2-œ@  ¿2ŽNÕïQ‚±/æ©ô8¤Zã H B;¢bqK
+*‹I[ASEÜš…WêQ x¢@…±€»VD‚{P0'\¥4`˜Ú€C?>¨³>Ø
+Fä`i$$4ÀxÝ}¥{M*i}­Ý¹õfè
+[ãƽÞ$£°Þd½n#ÜĵhÀ³ô
+£°qkÔmÜë¯6
+ë Ënwëp¬¼@U¨d"¨Y2.óö 2´,ƒb\‚b´!ÞRï®ÈÄ[ô´sîXWÁi+~ò`G_Òiy:) gäB¤]Ðv1mº¥íV!Æ-–í:S{Ô¨ÔHZUú-LOsâ@*b»U4©‰UršßºÓ™­¡;[cég»†¢¬~KûjFt£5±Bcߦxsîôf àm!:÷B8“ÁjÈq
+Ú¿0”·±è[5ZãUáûñIäªF9Áæ—6ÐxÕO ÜCCHAe‹Ñì%UB›ŠS0'› YPǪxüT„¨ + .¼a%™ÒEóðaÔüi` ¾Ž~ø¦jf·7žÎ‡X%Úµwðùï0JuäÔŠwJ^ù«Äp8 %F
+}ãfãJ55vCby¦²;onO·ööôk¯ãÞs=ꊦ0YN„D†:Œ'Aûk]Ôítô1“ìv8+‘inê ʬ'TÙ¿ö‚ç…Xøgž#£„ jZŒuS£ßTèwù7úu/Éz%
+*÷žeå2:¸ º‚dÝÔè7ú]þ~ÝóÕXt“
+(0'Ï ú|Cº·uqÞÏTEÏb£4 ¥ÚNèŽÅYE«Ç»[Óñ”§ÂS—èlM¦ŒÇÛð)ª"§@<su\w.êMÏêÜOõ5 ªÀ@\_"Þ1}šÇ«õtoV_ sŸ·iÍ°½jo;ÜbøtTâµ<úÁâB º¢y*ç5WuìJ%¨†šd LÀæj<)5c§4buiô“%”úëAÄ*· ÓÔchiòtñLû餕M÷螶ÇdÍ+†PC¥ntðhø
+ÚU,˜šÇ lU*ÑÙ6L”N•< -<¬ò"R>}öòDk/¶~ ²yL²·Ø‹™?~õ6äô£&ÚtvYÛÞÞ“ÈL£ ¼^`^*ÕK†cºÛï›cº&Á0Å‘N¾©Y•zj€”žÙíí ààé†df( {jmo¦,A›‡Ä¬dOW*Þ§ÝNA¦nÎ ®¡5¯SkŽ#fTjsf¸…×°Þ±àî´(Ä«Š¬²²JËú6 `D¹ñ¸Nã'ÇbÅ£r’+Z\ÑâŠW´ h8‰÷¡+™ÆN…H&y$%S¿R=ÕéîÎDwÏpI…œJMIp̾`½,:êÙÑ-¡·g aî®o÷õ­¡È]Ié—±(Å­òº³±¸g#êD /3‚¢2/q"úuxNdãœJ,:;õA#]PV5%G±ZLÕDœ=;ïðÄ9Ú¨SQˆN\ uš‰…%
+¿FLLu™˜ËÄJJ¥(~¢àqL—Ÿèü¤*Õ›ð,LûÓ3ôîĸ²ÈŠ,'rxJžñ²2'«<+`MVî×g§l¹uâŠH¦9¾ž, –|=%1ßÏ“ýêlk,è'2’Ìã"f¤P;œÌ)‹YÞxPv¢ä˜®H òe‰×•&!‡X ¹Ö–™PSÂðŽŠ±A´Ï÷5èÉŽ'zJÐA¦±&p*….EL€ñdI6Üy;ùxòÌ]ª“ÕlÈ@ôà’ã…|²"1*zó#qözóCµT<æ £QìŽÙH>ûº¦L3\ÊZÙ~œdÜP‘yOY°üQ‰00yeEa)ª²ωfpž‰lM_xLj û‚á˜Ìw^y†XI… Î’¯¨,qËÉ"Oü“â ’ÊGxmþç ÎÿŸ½ÿÜN^I†áï|&gHd“3ã€MMØ3{ÿxý«n „¶göÌý̵Öå¨ÕU]]]©«ºQÉüY
+ï•Ù#É>,‰C‘BùX$t´Îbz.%<žê\ò¯åîZÇÿB&ñÿ[‹
+þ{çØøÅ)þ-“Þ®7·io¸þÇUæ)\ÿaËùoKápðï¸`ÂE¡­D‚3Kû‹¦ÎÉûc´ÅÎØéÜ®Mo†xÿÉÐö¶s™ÌÞ_?ð»™»»Áb+Æa7ª5ÊÉÅa+ît½ýKës-ðéOGuÓØxDì¶ìwúèpá©bËo3ÿÜô@ð&GãõvtÛmwœ+ðÿjŽ\dóÿN©ùŸ¼þé)5ˆ$ϨAgÓ ËHñ_âÖë÷£´-t/!ÒM’Dðÿ#j@ˆ¢ÛíH*Hø|l E¢ýÃø½>†Â'Ú¡8(Šš¢«aHÂÏ2ž;@óÿ1?•½ÿ³Y…ò¯z@¨çë ³ÿ»¶ÿ'ÿÃäàßf·ž¹ø×vx=j³Z)‘Õú_lj38ÿg`j°/ðkï°Ø¿ñDkc¶Ü,N¢•;æçd<ìÜþ»6°¥È@r S ¿ç ü˜Y ÏÇ>ªžYë-Fûý°Öÿå1Y_ø'J¿Ù0Ÿþºÿ~S\’ØÚžÎö#öÙo/M`PmG¸Ê'8Yë¹äm}4ä0!ht7/éó8t™~Ÿö“¾€7ôzƒ>lG²VæñíÎh$ÛJö¡ël(?d˜ÛsïüBn;­¸ö~”ÔMC¿AšôûðÞ¼›¤ü€1íõÃH)n¿þH6ô~êÏÞñõ@ÀK#ÃÍGø¤ŸÁ)óA’&}€ LúnÏ”?¾Ž*“¸×)eêû´í+ÐÕ£„×
+¯$£>ÿq¶ßO{QZ- °G»£ $Ê À9Þ€$ôƒ¬Z?  Ùï :Ÿ1è‚ *À\P"ƒpà'ÜS¸VI”oÉbE-rQ*
+0èŽB/º<ÈVê$Eÿ€˜c!LóÇõ(´‘ÆFš‹ ¨`Š¤Ñµ¦lÕ
+LLºßÍ+ A øi?°10!E3ÇU žíN
+§è„¢  âŒEz¡{/Aûña—^Xç?ꉢpñG€!½„AxýA†Å" H¹@rAPÕíÅy±¼Dàˆ…Ñ••$£þà Ÿ ^ d!xI´¨€q|$ºƒ…*.UYÀÿ‡­WŽP)Ä^ÌÞã¢A÷cÂ’?>Tƒç¾x}~€Ëò
+QÚð
+ð"Pa]å¢hJ‚'íGÂê'ü`!•n”ÇÙF p2€xÑdG`Àøs ¦‚ÁkL¤Ö¥ØBDŠ£ú£Ž|$Î^ƒÔ
+ƒÜ €ŠÖ!Ų>^‚äŒKPdâ dRay ß
+nÇ·°¬æ/Xÿiî‘eNz}Xö3'»Ã‹®5Ff8¸
+!}.6
+.k_½Vš¸B›Ã ”XÅh%NX1È‹«œ†5Ê¢
+k
+ÚbOÀ/È%&°À£,Ü,
+'½'] >0hO‹.X^ äAÔÀ\{)Ió첸ÐÇ×¢~æÄJhñ}±D=.Hc ÉèCN;»€kЕõ0£`£áºw/:¾Hàcœ€¥Ð¤ú‘tÁ‚ìòü{ŸH‰"rJHy0TVØš PG¤À*
+ Ý ýcGOûX‹HLÂúG“¼HKZ·Þ Cl|ò­[lÜž, /’&AœÛ`€]c4˜w æËhše Ú‚™ ±–bþ
+ó¬pô±8 t§X.ò^šýbµ
+gƒÍ‚, v
+€QSŸdr/F¤þËÑ_ p Éê%ý÷ž‡‰ƒµØYò!Ž‡¿GÛõoSëÅz{›Û®›“°½2 VÐ È®>à""(¹Ÿ•Äêeï)rCœi°Dàà¶^¯ÿ´Kƒ‚((F²e9ŸØøf.\J„Æq±.#6È™“Ï„öú±™«»  ïhð;0óQÜvöȸßg‡B€ö&@ha{Œeì
+àhü9¦
+™X¡¡D±ûËÇSeHød`ŽKd¹75Z,Rà½r ½²}¢†Ù_Üh(y4óëíì¯õ*Ï‹Q2oòM2¶·äb4¢‘¶Îôȵ©ízƒvÓÙs;.Ý ‘¬ Aâ6€òˆD ¤~XŒ¶ü@Âù”X|n…;a ¤_b»ï¯{Ûá-yytîyc<Ñ"QçFL qü4t}´h®ë,Xv®w³Ój¦Ø÷˜à­‹
+h~‹Ù~…Ýa.­âþRÉ[ðäÿÉ NHúv¼@–új´½í­ö³ÛÞbÖÛ‰à D^»õa¿˜­F·;| Èî²S©ÆûÑ?ÂáxÌB!ˆO)†vˆÀ
+Mg»5PgtÛG7pÇ5 o7½ x7[§3ù¨o{GŽœ]1Š÷œoöN³!ôv"ªQ ÈöuKf­M'<!ªÖöä^ñ-‰–$Õ¦<TÛž@‰hÞSË£ ”ê­þèí|VàÍ_m;Ú¶ŒnQ6Ðmf8Û÷ú³OŠ»ü¡¦Äç‰cÑÞê­f»)p
+¸Ýû8v`àcŒø;'¤Ò
+«Áâ0D£@s«!Îìß÷dL5ñw!Ê ´—†ŽÄaž¾Å'é­s!Úßr“ë»æW‚ðó=ß7ßór愶׀tg‹!x%(ÎòçÙMÚÞ£xf¬2vbÓµN6ÐÙ ç7’£iïÙ)ª¯¸~Є›,‚„45TÞò
+ãtj/ñéN]ˆ’æ •·˜o½Eso]‡a@’U^:²;qÕ[ä·†åóŸü4qjr†„ðN Ñ‹X6ß6ý1ªŠÜòT¡ òÅÝ Jo ý?%;¿Q…= P±M{¶®ÿ± Ž×bÆ7ùE=îFâáHäDóíS¥&ÙOj½ùó6ÙÌ‘+y´QOÈ`sä>ï¨*5@ÒM´,|üÂ5®ÌIh^àp¦Kbw1.1?ˆ!°/²÷b±žÃ0è¨U´¤ÆÊk#ö©ßÒ–ØÛX×â=ã|›³}|š[¬Áp¬6‡ÅŽïÒŸLTøfƒŒÙÝ-®Ž¾­íYQÛy¢PëmÙ›vµtVš51}M3ËþhXÛ®Q
+Fi$fbASÔ%Âä„(%Õ! 9˜Š;’ƒuxô Ïöª /X3`
+gÁôØÕ‘]w‰ ·:ñ¦ç1þuœ?ïLM‹Üäõyd_õÄ6ïE“éúùÙP.*ƒÁ}Dé˜öAòC:«õÙ?¹­°ÿb€šÝê6QPr„Ñ?ÝBa¿
+û‚L|vÃýaj¦8W¨Îw….šV¹€_C.:(hÕ<…ù>nÂú&žëL%ùÎ)jZytZœ­L­¡L¨±
+صŠm«J)a3iR±m´ÑŠëOD,•5p&›çœàù\÷ݹ[pE€.š!X½…Èw·ÚÍg›> =Wn¶ö»Bo«Ür°^,NúÆzÏ·?F¯Ññ¾rÀ@´v‹ë~a5^ßž7WU}*Ž¼múžˆŽµ§²i=zSÆt„{ìQ\ ¾Û/ÜCÁ‘‚*ÄA¯qíÏ{×ZÞÙ —ðx±ÒŒÔf¨¹s¶Þäô†€ŽäšÉCGm8èœ)Mž.U·ãex3AÙVü´iB®6rÝ‹ÑX[Ãýz£ŠÛr{®€#ۖͲå(¬2fxÛÿó6½¡ŠSÅ)@½¬ø²òÐ@D3ùFª$c»Zóv8:5»˜rÜ
+o{(Ëáh7›¬x¡#JIô¹”`U± eȬxÙõgûåÑÊÐ ¿Óq9êÅÖ½äoNI¶¬WèJ"´%¦@Ôòd£ôÙc|0ÇQ’­·C÷z‹.c“ÉŽA}o Â6±d« ·)ªÄ êÄ­È|\›?.,Nq«Ê©8ö¥Úîå1î›ÅàOyVaÛ Vâ
+% )I]Ôjw<f^•sqsVJŸ†–w€å÷è7å—”v¨)xd@ e‘4â}䋨´lו&È2šòWi¶å鮹ªýÞVìgJ
+[1RrþŸ·`ÿ £&Õj»íZá½1©–qK™vœ<g¬Hñ×¹›£Ür1SÐ
+…€?=B“‚êtºÌ!X+&ßuXÌ›öTóÁp¶gÚF“qÅPö†ïuºm›Ð™}ùz<Tlåõ¯@µs˜f͹ò毿þÒéliÎnÑëtÖ¢þÆð—3Õ¿Îÿ
+$|0nÑ×f‚y›,àƒéþè¹d|”Ãø˜§è¹?Þzû²Á‹Í|
+Eô5Œ¿&½ðúZe7Ÿ!ôu€¿&Þ |°êQß‘D ö9†O¶(úÚ¼1å,î„>ÛQ#}=gšß{á“ó½IÍvMúŠõ§Ýu×>¸Hü4›m¿Ð×GôÕ•ùˆ}Yчü ú“Ô´¿Å_ñX‚€í_žŸgSã·è_ô3½™fúMBŸ¤ ··|g÷&=®Z¢ùµ3e3I;´¶¾eúÆÐKzlɛҥƒ·‹I†‰é½1aâ;Ý”J¼*m| -²þ×_æq§éâlB7]g*£s%=ÓeÌqœú‹§MÞ㘛<ûü™ý‘÷Ô¸ÒôˆÎŽwü#¼ ?a˜–R~žÏŽmõ!4;ÕwxR¨Ÿ±e0·$wïë½›Ì%;ÏõD}xgNf<ÂÇêž|uéØ<š1¯Ÿì¹ä+ý‘œ‡†ÎøWg–ä±Ò¹×*ðê—7ü¡yþ•X®'‡l$[¨ÒtiÐJÍ¢ù#S)“ñ¯»ãÈ”³÷´×xüõ—g^,é±ý–á(´*† g|•šM†û³|¹Ó£Ý“yg“ñÐýçÜS;|Ìò…|aS vùj¦O8‰RÇ0†™üt$]Á‡—taX°Ü˜’‹ø›\øM}†ñìÆÞÄvP óàZú‡"@.¯ƒnêHf¨q.An]ŽxÊÒO\n}zìzõ¦“•JL<¥ì\þ…yø/ÁFºtu:ý0ÿ©Ó¥Û>àÙmJ§»+îžzn®lö7½Îvÿô¥³‡‚vÌãx^¡·b­oè›!k]ˆ¿è¶káˆïl“
+ÕAWrºrÏô®»¿sØt53]Ð=ô3]£Pñ鉧G]ëð©×=­Ýó{t
+P^Ÿ]÷añªûhúº~«ÞÐ Ÿ6FÝx+ë¦ëÞ^77yÝ2ÔùÒ­«îœîkÐþÒíT^¯+ôzÃ&YÑ›“³Þ:}zÔ;Rw„Þµ3}è‰J/¬÷’•åIïÿ õ{‹U­^õ1K/¢o;_úÔ´ÞÐg»%Ÿ¾ðVXè˯ùª¾:¬øôõÅÃJÿ¸o5õúyM,ôú÷†î]ß_äq¸@égÐÁÒ°yÓoj@Ù[iƒ¾±5̾»©Á6ë· ®7ÞNÀà7{†À²·3D>ÂcC¼þùlHß«†|ƒÈÊíyÔP{}ðšŸQ—¡c°Y oÁÞЫõ¶†Ñ¤±4|R¥Ï“aUOM ;sbbÔWïÆF‹351:º¹©‘—>~ÝãÒ|}ÿ2ÆJ1•&-Ƽ7á2Vm¿±îÜEmw(g|õ´jÆ^ÈðbWJSãücw0nö9·I>DoL&óÓ}Ùä8X^Mä}oe¢÷ ‡)roŽ™’ĸaÊM¦¦J)j35wÜÔÑïŸLÝÅüË4üœÑ¦Ï÷ši3,ͺaÏg¶Ì‡f·y¹1û}ت‘/æø,a½1™st«d®<ÍWæ¦Ù5??äúæ1ó™'#ÿ‹y•n»Í—­m1ïÚ.‹käy²øZonKø!üjI–Ö>K¡ÚZj¯±;K{fÝXº‡iÅ2¦;˲\x·ìçñ;–XTguƒOV:H‡¬ÑÏÀޚɆŸ¬ŠÖæªa¶¾¾öÖaqS¶.’mÝ'Kz›%9Ø<)GÍÆ”Ë1Û]wç¶å¾Ò;[Í=ÚžŠ©¶íc­+Ùf±&@±}-~»)ýå°»Í/;ý–þ²ßå}s{ÞkÙÌëž½³uíýEïÕ>Ÿ½½Ø÷ë÷‡Í6ysPõ»#œ×÷ébì¸w¦Žvåiëèéw&Çg%àvìõuæÆä´¾’N*[¸wF\ëgf—9«ƒÁÙy«yƒoƹìÏÛ.ýª9w¹L1‡‹ ¹®ÄýWÛUZŒ×®–ÿÕëúxmW\sw}ê:Lž ·#ùRqÓæþŸn
+à’¦‚µ|c"É{›‡Œ6lS²Ð#*äãš¡È>™Z“«|­E™¾f ŠŠZTlYP¥T·C=ÙÝ9
+L^†ú*,^[º±òÒ>Û‡7åÿxôÖ˜dÑû4ƽŸåIÀ§oW‰“ϳO9|Ñcö;½ïÉnÜûFãηów~Çܾ÷یޟK¥LþGOÕæ¸&„ÿËigh»=yGÈ<Mzt³Þx§û ë‚þ
+vÌŒýÕG3AÛ0 ú,×-=1­5g†ÛµÙ ‘n©TÛH>¿ ”RI_à9¾ÌJñÏ ¡§‚Ô¨T &Í­Mð!3?FFXïˆ3dŸuB¡¬^2ë.ꌦ›Ð¬MߘÂÆÒbö¥rÙp:mÙ…›é·rxØ.ZÂûÑŽVƒ?O}Î"µé é^m‘¯ñóGÔu×IEcö¡-zß›¢ï-c)º)ú½1g®´EÓý·Ø}É^ˆ½?W`öc›ÙÆ|çr¥æw±ûíÛ]uS®Ýõ²ÎôÝvÓ Æ=Õœ'ž`¼–xÃjÒŇËù&¡ë¾ÍÞÞË,‘v&‰ö¤=N|ZzÓ¤%2ÿLËdiCl“ÝdÎÜlŽSÊ}o÷¦T9–jì÷ÅÔ¸Ÿk¥O‡aš©ÞïÒŪÛ~kOéÍG¥‘ñ˜c³L2`·e_u‰Ì̾ìd-íÏ]6왳÷£ùc¶_Ýïrº-šó»Ý\ÁvPro¦A%÷å°móD°”ʧkÛyþiš‰å—öŤàl–b…„ÍöYx|¤
+ŸÁܶh;P÷ÅØÈà(6šÓ·â´5Š•¬Õ—])úÜm•À傼œíËÖÀ¶SŽ¾SÉS¹aIØËÓÖËgÅFêZ•Ø,™ª4gTå3ÖÝ;˜Éô>Ag^îÛ~Ãýý2òš®º+Ùp5Ý%¨ê‹þà¬~eæ–5íj…»×Cí}ßÝ?èÞƇ‡@v­¨­¦ÓÃØAÛêVO¨ßy?™z+๫/ï‹ ÏÈüØÈyêýF·jÛ4uúWG3м‹4k!kµ9ÙûöAËð˜|)…Ÿñ‡Çm3<où»Q²U™Æ*­±9óÙ¶%¾S;1?¶Ÿ&}{;ŽežèüÛçSÕa ?Mæ•AÇñad:é·Ç~çí…
+<ëz³ñshZ¾{n:CëçeÆV~!Ç;ûKÉ;é¾ »ýØ«-:н¦L³ç××þ&ö¦{s›oLoáûPÿíñ¡Q~[7L××£ ݪîyÜ1öÇw÷ãcæ½`%™÷ÁÓÔñaó©9ÿè¾ì=c¡ÿÚ»‹·Ú½çx­Ñ;jýp½Vë·†­Zkï×û}ëÆ4hìÈ—ÁºTè içäsø0 ¶ÃeëÅ6ò ÿ¨}NŽ©p}ìÍ ÆÕöÓa<ǽ/å-Lª óûüHÝÔû°
+Okžekº˜o·3ß«-<{x ½ÌV÷e°>?éÚ ðÙxu,?7“Bt4/†óV:ÁÌwŸ›Þ"’y,:r´Ô?-cËx¤±\v©lqe±-«Œ…|] <DtídÜûu1ïm¯§ýXdCUæÖxÿجºâé+ðóµ =ýVçu¶q÷[kûngr;›iüÿb'w•:§qÙ1·i\Á,ÎðóÎþ9ZÔF[t9-#}ç¤<©>yy§ü´q6u"·í ÑæÌ-ºå–Í#WÊg_*£|„Ä–} ×¹ˆ_Bb®ž¥ëÚ4uÕ}xÞ}Ê·¼Ûna °–΢ÊÞÕð”•$NA£AMO%’Š½úPÓcLD>¤s„ßÜö6•†:N‘Kžöd ã¦—ih²MÙ1Í”’=ŽM³½Ý¾=ê£Bj.ÀÖœŽv£ÛÞvt»ŸŽn¹ÝûÛÝ1ƒñÓÑêvÇ&>öVü»±oñjèíÐÏìÏ
+­X —:¹“ê{×¾»ªùÅiG-áÞ“³è5W]Éø6·œ†&+]1«sZ-©YϽ3Òù mÅs±Šï.T~µTâÛÀÉf¨JÀDú|‚Ø¥?Ó'aŒ‡»n{<âÜìâ»å¹1ÅÃeÝöب¸ONòåxÄ7j¤fÑØ ív[& ÊÃÀcÒYSˆyÎíÓŸoI߳˙X®Ë»D¡±Ÿ:b´áMûŒíäçÂÒ¾1¥ÇD±/Ù™‘ Ž™ÖÃËk¢™r·äòÛ…Þâ‘yö-Ú¹—Ž´ÓtÈZsÃñ +û«1=~k3hKò)4NN÷©)óL
+ÈñaNÈòW<rgi³ý
+‚'ì"~B>vz#Œ› lj¥Óp‘&;`„SËWšè·0îì w!&Ñe1PüõÔ_ƒƒrz¿FÏñ0îΤÄÍ1z,W“ðÉ LÏ”ˆhê`ö…%1µß˜Ñ4pPØw±Î}ãa`: ÉÅ£:Å ç$pˆKŽ%¦>%,ÊøÓ©G¨ð+Ë ùåC–-PãòiTgV‘$~
+¶×³Žx[„!Þ²Xƒ©é¡þœ.•¾’ü%ßG‰ú*]7ºÛ>ÎÔ\’B(ì;„î‰Å{Äõ‘]‹Ÿzô¶pB[›ÌÀÙô$i'åâùd²?Iì™üÙ¶B–Rñ<†³Â^UžëÆ7"À5E¾mp‘]Yó좃'¼æZ{*õ× ,%°ÖýÏ?qN4¸&ÈRú¡s¢Á5ᬾ‡ºÐÐX—Yàûvçg%°poóÜ<šæœ}ôTLb3öL§sWÿ·< ìHý©ükº”¤-
+®—:QÌ|¥D=jðòyÝ>è@sW¯Ì—Ò7 ‘ØüY[§¶O”:äÆhé~˜.ƒÎ#óYõà§ßéTÞÀ*#×Zs³
+/¹×ÅI¿âmås<Í,0霉lº“·K MÐÎï¸1…ßÖ/¯JZvæ~®Šš„G]ÛÇÑB÷“ð,ã\?“ ýd¢áϾå–{»µû<J˜ .2ì@—T¦¬!sG?åR÷©Öˆ7¸Ý‹­îÌæ¯:Lrü‹gr]n o{sc sà†õY¢éhö+I/Êþ³ÌMb× KëÔLoôcûª‰U¬°–â!4/ˆéªëÁ&X{ÈD5”)ÅÃÉ ßòæ0‹Xã[Wð€dr<Á¼ ïÓãà‡'ó<Ú›Eô ~n-MÐûÝNb=­ÚbBf9™Køëëy@ê®Àã’X”öJ1HpžÈ4L°ŽÍÆ÷ôøa™¶yC6•x›dSñI=oŒ’…DÐ3OH7IØ?ã­f¡—¤÷<l@ôñP{4‰6Ûw—¼„ÏpQmªu¤¬™'ì%’[T–Ž“˃~ùzwNåA™Ù¡0ýpǧ9Þ7¼¾ctñvׇ.\ßÆ3ÎáO“ÖgW)nëå´\¿È{M.Aû ÈoYx¦£îÇ‘Ô#Ÿùê!ïîvig?›‰ØŒ¦GàÅÎWrYù/ùåAêkþŒ,¥0i9ç3©Öô¤ÇÍ-8{ÄxÉ[…ÝÛGΔՕâ[CwŸ¯·n † ‚ÖœØÐÞÎS65¾óž—ç¿ ã€AXÖÄÊŸ>gåŸOÓ¹˜i&Ffc°ƒÖóîÔm8k- Ûȹ|E2â)=Št‘«ppœÀã.×nµüÛp¬¢Üg¢J&½àfßÍã‘ØÆÀ_‹G3> =<*;ç3{ôe~Wé
+ò
+n„íf©¦¤NÒgË«ÌÀ¿È.·M‚X–Ó¨da:µÄ:1¶JCÊ—r]XÁz"&¡ŠÃ š´iÖiZ©¶gçEŽñOÁwb‹¸¹JÔ]ö˜êƒÈ :[:žß|;×È £YFÊuâ ¼qÈYŽhñ¹È£h·ä‚‰±+ÁmdÒhs±¼¨‡\ãÈö4R~¢’·ÉÅbó!ràÏ<ÆSÛýLŸˆXø<×#Í>H,z#´+a@›5D¢¾.ïÓÎê×ðh)Í'¬ùúC1gzú <Ý6› Ôóbcã+_/cG9<^šÍà¶Òg[H¨€Äθñd›"ÜÎ8ª°ëRj«À2,rÖ-ùÆt‚ÝŽGYßwÖ_wh ¥î3Á¬P±Ýsð,AZ¢!E­¶òPî=3C(´ÇFÙ÷…‡I/âÌÓ$“äv{´õíÊZ‹®VŠ|\î£y c®Ûøc_KlE"™|7 ¥å!èo&<•€îóC/¶Þš£­Xô®íiïÓÆ0fšýE`o7²Ùø˜¼qhÕù—ÆN/¦ò*À>m
+ì‘HåX m_ñ¡`æÌ úw¶4 BZÄ^ ŽV£¤o>Ò­Ç·V€¹KåSÓ—¡yXúxäÁÛM—Jýi³XüØcÙž9¿=‚ÙÉ<8Êù5
+c.¡LïãÓ™XÝéjÙë…Ãkº¨gôŽ}¿wÃ…j¾N‡žû0–Q–3Õ8iQ$&0û`æÙ
+1ÿã¸kõ=„ÇQq9î¦{/úDù"!ïéÁÃé~öÞ5÷I°’ró¼¡í!÷&vzJ9¢uzª³yóQËc©ß˜tŽØ<¢³Ý?uÎé }ŒÝ:Ç!ÔÐ9+Oi‹¨P„'Ú±bð~]ÊöàÛQ;PÎþôÜwWýˆy“o
+ýèV t·6G9 û;‡h¤º×Þ‹šì¡ tnw1@°îK©Tpá±ÐÔþBæõ4 ôŽ,¹D‚йñݳšÆk ¥J(‚Â5n·½þ
+%D@·ÛÄh}äߢNtçÿ qšæ.ôà‘W¿}4o8ûaÔ{§…HåÍÝuHöiç\¶äžN‰ü‡ép~z!ùAô¦Í2oØ©#^Ÿ#Fô”ïMîén¸X•ôjª’zÎ
+ÅZ!ô*û4@ÙëòO§½®åD±Ëç Êü<}Zv¬î(ù§ýê8|~*¢m¨êý¼ÌÛ¼9yܱOÇ–¯ èÝGÇìhœŽI}è‚býbc%õœ•riÇ|+û´mê{tòO_Ó¡è‘bÏ?L]Æ(ûôs_ÛäeŸÎ[Tòáüô‚bËy6Ö•{PzûeŸ)_ìIžb¦Áªß(˽mÖ™ ¯vÙ§™D¥?’}Z¤îô¤<Å:Êh É<õç‰LÔ~sÈ=u4vwÜÓ”;"^•ùæGΞ8?÷í|κÐKCËKŠ“?¦zºáÜÑ컟=Éõîžý$cÔÞˆ<Ì”ÎU vÀÃül¢?nô[VçL×SèOûo'^=y”|[=e‰Ö\œ<?G`Å ^ ¼X\âµ<ÞŠðT+ ø±O­z3ÀGNð žY´oé¤Ïln—@Ünõ7¦3XìéÈ
+fu<‚ÇŸ¸‰°¥ž‡K-íº‡åŠ¿öeZÒ†¯n橪ÚÎ?åøŽ“Iók‚“–K÷úDÔ©ó4±ìaË s#.Zñh÷ËyþÛX‡MÎYG2‰õ÷csêÑŠ»ˆóÆOŒE,˜{IƒàêedïY4qàc÷ÇYYs
+©y° BŠÒûÁ¬[qR–;‚G…1ÉAZ¾’%5¢£?ò¬3/1>‹Nv|7¦óñÙ<Î_C¯>†ÓøìI¯
+ÄÒ>kÌŸ¬g¡‘X
+‘öägV¶«-ì~$VØugùJ ‘YÎʽ~]OyIºƒqóÌqò)O%ŸƒEeºßÈK(zl—¢§›Š¯¬è¹QcÝÌkaË'à eͬ葦]U+ ,ƒ3ãdÿp´#WÒ´ë¸t²b[nUâxœäÐ:úë‡Æ×bxpÞ»V³¢Fê\ÉÌí&H"’vˆFÅ×b¼Qjn37ûb4PZë«$%a€wÀ{âÑö´ ù|þa3rOi™irnȞђÇ8°qþo†×ÒÓµ#zä'ã Žtg¤ÖΤºÂtçíòØ/×]/«uÝ)¯:Е=ýÓAq. ¤ó‘t¢?/Þ&Å[€d´fJRÓ ãO(úzD_òŒï$/y£úpB‰‡Ë>'‰Y,×ßÉ 2NŒöž +ìrJÎ_Åq9%Ãœš¦UôÌ»“¬bÒ`3žƒ5ó²—UK7¦kæ7‡h’¿Þz’ZûÃœPNK«²>+^”öwEY]Y­søh1é
+]¿\ᓳ›’Â$£Snõ¶ë»ymøT@<Ÿ¹€LP,A‚ #)>dHAÙì¸1]ƒ”á›@(-Ñ’{Û›”Õ²VP8
+ÉŠ"$ˢЂ—qŠÕC²04ÞBâfÿê0Iå%T´†7N^’•âA¨–¿Þ
+~Ó ²«ŽÇÉ)ÀÇ}]ÌûrÌO )m'ÜÕ¼ ÉÅ[¥¢­¬g!oE]±ø¤ý%X47¦oRàYSVy7šû:’×aÃ퉳ýüt²½œ¼És/G™|M?×뽓¿/Ñ™`‡ð:%*Ü´`ëÂiZœ)œ¦ú+; )œ|zcR_†Ô êŒr_½Ç'cD \N»&RòÌÏЗ@‹‰%Únn»h»¹xOƒD“Œ¤€0ñ¯ŸJ´Ç³D;z¯×XðâÎÔ%ÚÆ$ÔÙ÷%ÚiUæZë_h0kRíêµý\/Ñ.bl??—h¨—Ÿï½â~vƒœIëiÇsc’²J¨µVò ù[‡Ò6ŠÏYæ[‚ÏsG¿ýtö¨_Æ–/y1¤Ñ2KÁ:¯î¥3¿NÌBg-ÝUBöÆ$+f¿™ý \Ì-ìK <ñï(0k¢¤&9 £Þ6Ó^¶‡~~ž{‘q¨E;ïêý7Ý5†—%vpg¿«fu!ŒÏ¬ ¡6„_]?±ïyLÚÓ×w?öøžÚZ£Y¼Ø…¬6l_eß+Ç`Qg?·ï_¿¤táµZ ÍÚõ!­K-†úù‰}Ïëå¤ ¿¯Åp?ö½T/'ïU¦­ÚPYb óúõcm(Ð…ïâ}b ~ý•t$$$ó°8])Hž:§aÈÚï[…)á“Ò©a÷íéé'±jQœ:ûéêæá%±¶•s­(¦ÉÜ=Î$‚"çÁ\º5­s…ÝÓгåQˆ\iH§¡$Ë8·Guy‰SÊíºPK)·G“_©A1Qɧ¡lzž|暌¿˜QÚH©aqõw¿—m ÉîÝœ¢=Zê¡3¯1\*ÿF„(Æ\gbÈä ¢™|wkŠÁ²É,öŽbò-Ë7Çø½&¤4rÄÅââ42»tÏú,毬$= npµÜn¢s­ÞuÎV7£s%¼]T7—‘ª cOnùy _‹]VЉ*†¾]C§\A‡eò/ÔÐÉÅt²Õ‚WÖÐ)WÐñ«RC§\A'°ú~PC§\A'¨üA rBµàU5tÊt¸Zðjè”ÛqµÕ?®¡»X¸‚
+º“gñÃ:å
+:l©×Ð ’*Ìj–¬”µ-Ÿ/_ $JvÑ€’d¤7­ž¸m×V/•ùÈßN†M‹­_‰à€ÖHïKZ¨í¯›:Þ_Zœ°ñm:…ívÖŠžt¼UK1ØèsÔR ¢÷ø”:SÎÃÒ6>ëS«œÓ<>Qäêr½h'ºçz”d*U"WJ(I•Ì¡±\U4§IÖdD© çÜžë
+¨öW¥‚°ùc’É ×‡å‚Æød°Ç«:.ƒòÐn4» 3!¯ bN†9ÿiĘ-v“Û¶zIjÅnòþ©ò†OZf“A®©š’U3*…µu&LÁ"/wlúÔ—Zå£6™ÕË^åôâU)çöö½ò)”W•˜âÚ·ŠÆªCu߈%µ—}²Ç.CgjÃy`#
+“À»’I³ßرÊÉš]²U`<KI\¦jvi®ã;¨åÀ_QÇ×W«1‚Vò¥iòE0ʦôe¼%:5È!—*Ñ”Ÿ?ÕxÍYÃœ0‚)9Zëø[µš%ff§£Î~­Bt{Þù«L¹¦3uŽ×N1a€õ‡S-Õ>ȳDûÅ„_*ùÔq ò¢Äz‰J.m¶ìEÌ÷ÒÍ:-õºtÜR¹^NÔ…Ls½P#KtñAuIôçCquç58{'OÅÙ›ä5;{rˆs¿Ñ…ÚÑ(0ϧS5´•Ê}k†Þ uýr4i¤—*qS2Ü(†¤QUšŒwÁöJ5r7*eζ<ñ€”<¹¹p¯ìÈÐî"•ßšÞk 9ogDŽ“? ×…w$\%ÖRR)»:òQ{Imþ {¬ uş׻¬=öY¸.¼#_f'Î ú6¦*‘†‘+!ÏWFd( ê‘)êšð‡JÂŬ®ÅèäÓŠ’rvºzQœJâ³;Ü¢ø/[’ô™"ŽÈü0K ,a£†ˆ ·Ç§Ržc ¹Í?‰ÈðüýâÏ#2ÐU!»ãŠ2´ïDd.ª‘Aeh¢ˆŒ\EªZ}žïªˆŒdœ¿¨¡<G[q*у§ÎÉÚÒ÷ÐU„ÐX.eù¼q-Ʋ÷îÑaÐÀ Ê5‰›Òïd2 y =X~'¨C YUrzµ”¡}3¯_P™|téŠò±‹ÔÉjAµºº«“f/3Tq]Æ|=ź:^é¨B¥°z´¤xHoõòlKÅT½ÚåY¤è7ŠîXó.—˜ô;õpÊoäÔ)×Ã]þØwêᤲ kËß®‡ûAÅõpJª¿W‡¢Ö?\êá$N•-âú~=œ êøŽå·ëáÄ玲q¿]§zJÀ¯Ôà v¬4¤Z~¯Nì‹Émë J¶ŸWÖ#÷k9‘Е0'RζԒÙZkʉT[û»¹÷§f@
+'Hü¼÷ãT›}ýh©#‘í…µÇp?¿PÉu‘É ¯.ÑPq|@ì2ß™w—LƳåË~‘ñlùR™Ñ"”ö<µ~² ÏÅG¼¨ÂO—!t¦x¬Œ”“]†Öe¨`#z_ç/J2Úû¹nùÈÔ#C?¿R™öhÓbªýÈ ,sš–\šõå‘Àª§¡ £Ò¢ÓmÎË*>S>ØIÕ¡>U¤’úï&ˆðÆ,w°ð·*R{úw E¤+R{ú¾–J©ß¯T¤¾~ýNE*êç7*RQ½ØÏ+RQ/¿Q‘ŠúÑv ´È%–Êëà DþÐÔ«“Œl.nö…ËðéÇËPT
+'-Ç~»çó+fôüF)œä¼üz)Ü÷ã–BŠ)ûîWø•?(…ãŸA„‹áþ%¥pQ…A)œt|L£ÖQ2 ù¢€~²RáÓT6WUˉðB{,åVq‹´&z¡®üš"ŠȨ3ù“í®´a.¾vsWÞѸ…£t:/ˆr)•w†¢^Ü,®«{•=G¬ŽÑQ õp^¿èÖ8§<nð—±ê4·hõÞÓ†á!“ ãÝl3VËÄ={ HþlóŽéàkÃÓÏ™m<‘§›ÅTÒ=H¥’žº„ ±9ª#ÓBˆ2qÖbIU!/‰«Qz‘¯; <„j|ö»…Õ
+?øÌêŸÚMÝZ®ÂÎ×yR*vzdÙfR©ÂÎTUzr@?€æ\APq-VȱãEáÄÅn¾§iùt3¡¨LoU*v#Ý" ÂûøÂK¹
+;Ú`ø¢¯rÅn/JUgKå
+»u³) Ô\M‡r@GÊ÷ñ=<ÉÍÜ¿ädÉk\yÃïr@„vxVaÁr£ÆŸ8>il–jÇF-}¯eM=úl5¶§:Ë´„!zô’bÙÃB¬P•bÇRn…¬cÅŽE°GT3¯§´G=CU5‘¿ÇêKJ¼}1¤Ô’SÕò<Xïõ7o’“ºvDâL Ñ%¥›ä®ŠÂ½¤5§HªTCâ3!¯ÈëS»DN1¯O;?©\"';>©{ßÔ.Ñ:>õ»4]ížÑYj?¸?NûzÉä/"’MwÕzr¤÷;Õtß‹Ã\[M'åïâü½j:çÃü°šN*&(^/?¯¦“ª¥ûnå£|5T,^:Óþ'Õt²pkVòü±UÓIu¥rBÈ7ªé¾©‘¯¬¦“Ú§9éÊ_«¦“ª¥ãûû¿SM'UK§1·çŠj:©Xûñöß«¦“š]éýÕj:)㆟;ú;ÕtRµt2§Íÿ šî¥©AÞRún5”qzcúíj:©ù“Ȇúa5¸+Õ;…¿UM'g[þn5vŠý¤šNÔ•xOü—ªé¾E±««ék¬~­šNº¶ú·«é¤:
+2UÏrH‰PÒ*
+4Ü.'ܘúJˆb€ÔU×.+¡$H!+aè¤pí²ŒÈDZLèÝ‘ÅÈ#òƒ•‹Í•#s§Û²”.ºûñ5w¼s®4šäß¹æNöv¹’¦Z%×ÜÉUri+¤Ó” ¡œŸ|¾èîgs•ël´Ü2£¥ÒtÍjDæÇ×Üq6ŒòEw?¾æŽ­}S¹èNÛæѦô ç\yïIåIÔ^gQúµ¥Mélr»–†µiåOÙ]tAjî¡¢2:ä<+Fà5ÒiÉh¾Q¯0”OâÐ\_PÒ¯H"CÔ‘ ý 9YÛ [
+˜J%\s6t¥š?¦9
+:Ó–Ñ­œØŒe߯T>þ|+Ý(¨p87ûûÑt·«T/¼Ì®Æo¬@ÜËE%»d¥°z-;îLSa­ÜâÂÚÆê²°¶±ú½SQg¿r‘1æ1ÀV‹0ãë.YR6¥H©zß«RµýrKUâ]fP+zâr9Ô£ÝüW*SN'_oI\vU>üÖ †ð &¿E¬yí?^uQµÜîºxíÇæÛ‹RVçýüÂ)l??½­ší帥N8¼.WõQC!ÃU;¼6‡Ä2li(dÐÿñ wÇúJ¹;î¾± %’+¾{oõu7Ü)U>þ`»áîWnÊS­'ÒvSÞOë‰N7åý|*Üp'¬KÒRòî”î{EwÜ]ÃÖSÍQõÓÏ k_¿ÎfŽœ÷ª¹°:S7sn´:ìÝtß+¬W>ú?Bõ…ÉrèëιÂý|Cn^œúù•zÎ
+¡ÍSíG¾VTÄt£v̾.ïšúv©"&þ®(΋e²ªL„†¸ÖñÞ7eLZŠ˜,Ñ®Øåi1-eLÂAªÄNÏ]æE¶Œ)dÕT¡®è¶ŸVeȪeUj)b²DWbãû»~åÓUELrDèîDM{aøÄÕðþàT~‘a(qXâS‡½â7j\SnùSÅÿrítW]÷ˆI)ou~ïhªÞ}û¥׎ìÑT×Û0ýÝU×=ªÜ”çùf+o}žÒ04T=«×¸Jš«ž•j\¹šˆ2# ïhú¡Š·|´™ž“©¤§ØNFÅÆ)}çh4£ë Ÿr5\Ý—}zÍ)KLŸfíòbÇÜ'AÞý]TPwcÚZ?T%¼‡-”zéÈÔÃÙä‹ð¶‡)”É¢2<Â.WûGŒLÝö&W„÷* Æ¢Ïn¼²c%r†çGY –Bß=‘»‡Ívzªä:¸æ§x@…¥i; c>ß#èU9Ú¬w/ ) 7&D`ñs‚2¼ž¸öOÞR¤&”6˜|÷és V\÷®
+2»
+‰´ÊÏ(¦ZË£}ÂËRLõ>«(Vö½ÊtvQ.,erûÿ³÷æÑmœ÷¹0ÿù¾{îwªs{}¾Ü´¶€03
+TSôõ›z©›4
+z}ý’¥I&n½¹õãKCÎûŒúúM½jçOG_¿©*‹RÞÎ\ßÇg¤Î¶¯_©iéêgíÎP2‡¾~ãnÃ’±]ýÆÔìšqzJ‰Ù×oÚ¼×´ôõ›º«Ÿ9’çØ×oê€kKFêœúú%ò·’Åqu®fÝ×oêÈlúúMq¯]<»<Mýø–L½•”ûñMÓN.å~|sêëgn%éí3ÓlŽ }ý¦È{˜6ÚöÄLûúM­äiŃtôõ›ì¾{¢'qvù[)ÈyÓ8Ým8]_¿©ýÍc£fß×oìÙ¿Zœm?¾™iLÞ/ ·ÙÕoîýøRIbš®zÃÄX™µâŸ‘:·¾~c ÛºúñŒ¡¹÷õ3S¥¦ê+:ç¾~SËœIÆØŒûúMÝÕoÎU›ô¾~s´õ¥Ø×/…¼×4ôõ›º«ßŒûñÍ* wÜl9±¯ßì“á-]ý,eN}ý&š’­]ý&«r6Ó¾~S‡w{ŠÍº¯ßÔNãlJ³îë—äºXºúM].õ¾~³·[Ž=c3Ïyšd]9‡¾~‰‰+YW¿YGŽëë7到t
+×/ÛS´¼f­ÏH{{¼¸åâó´ÙÜZ‘çVOœCÆä—>º¯¦qí¦c;.еْö“l;\*/ÙT^S•ìd±“A·ÕO¯ËrÉ;é±²ŒÆü#ÛÅÝûê6HM-ÅAÙŠSmâ¹ãÞã4“´ÊHõ¶-½°b+W«mb9‰ÞMÁº:¹D:qœ­÷·Ÿ+Ù/Œ»}È¡mßbIšKØ[-‡F¦µdçaÃ*yKÛ"¹b_ðDk ¹å ²³aÕÖ-Ç}åÅ­U•_<þhp­xv{åžòå‡ÈikÚ œÛÝp`Sh•÷(ÙÎîfc³¼}f~iáÙÕ4•qï¡òGk¼-ì¨6=qžŽäMÕ{ö4VînÑw䀷Ÿ+¢I»Kù²~Ãʽ-låTRÜšO£[ùL\¼²(`¼+Íg¶crFV7‘«—°¬_2á„/ë—²F §ØþòÅ–"㋃•eµkÈfC%…Kå¶`~(.]8ýDå±³ÍkKŠ7¬.`;Jwî`é’-¥n9s¤¸”ü`}¡åG¤-ëÉƶ,Kü¨ló¾úÆÂæß«¶þ½eRø´qb¶)ãüÙR¥ÆwÄü®0ñË‹äRåPÑ1óGË,ÛQ.¬+¡ßëúhåÖšeôDihUMýXÆ·}ôln{G!ÿ•£J©Bß±Ìbƒ•Êòi¸ÕŽ"þKÇVm¡ÛÙQBƒÃZJ…¶±úfíÛ_ª_«½ÁÂâÚ]g—“ŸÖ-e?-+Xµî¸ñG늌¿RR ­));·K®\º¶€ŒŽ’Ý’u½8_wËñÁ0Á~¤›|È‹ù`O²½±qã©o±Ä²ÅÒbñâc…õ¶¬ÚP¿bë¦ÕçÓ»nsYÁ¾]^6TèÛ»¿Ì¼ð‡—K=v8ØX°¿º¬ íøYãÐ÷,M\°²ŠÐz:¦÷ñST±/\JäRYűm+õwçêËôwmûéÚ²¬²àH£þ®ìÔJº‰•|ûÊé÷Ñ|óeçjJø¿nlÛ©oûpAƒ9Úö•Yöæð£Çg?`glß
+ó®<j9–Ã{¼[è“æQ¦°só¹¢SK6m?v²¦¢:ìÝ•˜HLgÎÓ8à·ØžÄÍËå¶ð c³ÃXî/«_Áöv¹ÿÑý+õwGΘ¿·\ÿ½ÝOl¿7Û¶Ô VœóÛ´³î@`‘\ytYùú°~ŒÅ³é÷~ë…Uü^+Æ:ýcæMsZ›8oO1:sŽ›7×Üv>¿rÏæÚªÍçZh‘‚U¡Í•%EuçÍñm‡ìÀÉ´¶†•¨-0}|dú×£ál!¿ª›],)>ë+*>ãÛî_.­}¢µ¤$¿è¢>‘Ù’‚3{+ù¸¢€¥9—V(§×–’'Ç:Ò5²qá³›N)¡"¦ëhèM³DÐIˆZBÅ“Ø”B%I®>ýAu>}m¦y%M‡ Z½„Ï!K·ÈGÍï–êßÕ—Ò1]MÆÆêÝ¡-‡Ïn:>fV­))Yy´š^ˆêRël¸¹yÓɧ¶Ñ¹ü½çÙ£…úMô»RCžÕ¬ÖÏ„\Æ~…¬äv6“5Åƶé\J÷†Ì¥‰ÉšÏ|äXÈ”º,å¡ÄÞƒn]ß –5´^_ü¸nçg­ä„oeqBV²ïhÕ‚%Çå¦
+òë-…V™Ã6ñØÆ]– „,-»Óê—𸾭T`Ö)$Qs‘~'’ïÖ´q•éßWVe‘Ú\v=¶­ÒÜÀŽ‰hã ÇÂ7ò‡¬ª—ŒùBZ]"Ä·–ÑôVò`Z*¤ïŠÌïŠÍïÈuYº«™êƒ>ØÉ°ßgyŠùÚ‹öÌ>lH¬õe†º"¢ì¨´ó
+é/-ÕmÐÛÃËŒ¥wÛý‚n¯)b¿Â*‰;K蚦”¼§ÊØF—o¬kâ×j‘\V ÕðRúóBëÕß»­ˆý•å›×,_óè‰C'·œ^ܶùÜqM2ƒßÔD¯hÂ&±wgñœ·8f{õ%ºmqUýúu[6Õû=¼åôêê ›ê651ËÜÚ²Íû—Ò¥ÇL3_Ýò„g€]_ýÀÖ,5/Ørg½ytg¿.KiüXwÄ·›ÙsèIßµ„¿Û¼oyˆzéö–l{,ÌÞé—öè©•ôW–鸳õEdJ©i€[F¶¼)Ÿÿ•eÌæ¯ïÏÙ# ÃïQ«mêì©Æ]¹o¥Åžº±>Híê‡ÉVí[VQ|ä1ÿºSMúàc•+·Ø.º[GiØ¡
+;â«bW¨Ðø%2S÷/-¢Vy2ƒ®<p‘þ´8aˆ$W·0W·[Ò:Šc\=»Vó™©š ©|«“I§«}…–îÖ}I'¶¯~Œ{úÉìµ?i\êÉCåtùÂã-©{ˆz«« ¬³ÒÚV:[VZ¿«)¤Sfõ2ÝŒyj}qEÕcçKÈÄ,²L\ÒÚ³ç6Ÿó5Ž f!ÙZÀF?·J¯¨¬bÙþB6±›Š»uø¦lYÊM›Ü饄¹¥“Ú|çÛ- –r›§Õ—Ú¸“:iv,I8²»6,ZSRZêYS²ºÔS¼³í܉–m-gNiò,]ôè¢âMáÒÒú¦ãçƒ-'NÔxªµâü±¶'N4µzÖyŠ7íÚ¯YYqâØùã'<,ÚjåáÕ¦f™¾³ú<bõ¹±2kþ抓k•³!qçú#'Kön°L?\F]¨kö.=ýxˆè½ÂcE2}¼î÷.- îòæ‡..¥÷rÂm¼I=¿lÀ/+N´ln«,¬­Ù3ÎÁ¬Ek×)ëÉ•{6ŸØY^|ñÔcÅ¡Mûª+öwï*/n-9oX,©ÃuLxƒÅ-ŸÄ‹O”V«ß[ðØÖÞeÅÝÔ›_AŽEªXSì]ZP^N¿­òîðm¥Ç·•þ`£wÙ¦åÇ©|y—4‹ä†8Ò¼Æ:%§¦É3W 3×4ú=•˜·fàkMxZÉ“úZ­·Ø£§6?ØVšxØë3½²~‰EXþ2¹­,~êCÖ¿Mo12e-!·ØB~³¼ø8ÑÀÊÎRö‘Lò^òq{ybÛºûe{Ý­K3&¦Ö°¸Áš5äÞF.íömÅ\/lnh–ÈÇúR.ø³jûþ妇•œ~ñ1‘ͧúÃpoMBÑ6þŠ>»/’“=o&>mÌ0 O›µd›¶Ìüù5ÅŠÝl‹Ukv¬]£Ë'ê*ÂÇ×{ 5ÑPj<Më¸ãr‘Ì]—çE}xí=²Â¢ ,Ãëè6.t‰v´¾XöGJJÖ„ È»ý¥ú“ê衲 kÃeäZ=B£zô÷ÇW°Mè—öìÎe\/ÐP?ò±ÁŒg÷—ï•Z”A`cÍC_nùÁ!ïòFr,ÜÃZÛ,ëÇrö‰U³c‰—ñr¬µ¡Èr¿ÓKë¡’R¥´<Ÿ¼;Rj¼;žP4ÇtgXëã+&ìÍÊÖÝÁ%]½{™¯6x¸VæR€è=ãÅÕ%UJ!õN\¥?É©†˜:dE“¬Y7ÙÃAŸþ— ’«O
+ºíg¬]4U›$›ÂèéŽY½þÿ’ò=KŽ>R »É㽤¬lûì}¤É܃Ôf•²ƒ°tζijk.'¡|¹å$0·µ~V'NÝ›³)+õ7Ù)0l¼×m2NÂ’q>Òesô•¯oMĤn¶Œƒë¶·¦à+×c “yËõÌg~™ƒ;ÙPšÂÝ®çl’ «Ÿâhœ° Öu.µ}à±C7Á:fÍå0X†qKY|î38ŒúuÅ3Š\˜xW’…ñ’¹Œij!,·ýŒ¥z&¨-qÙt‡11öÀšÅSºô–’¤‡‘⩤KûR¶‹>%´¹Ðì5²H¦Í–ßT67è¿|¼´0IW}œi ÌqŒ’?·1V³¢(±IÇØ”›8T^2×18?·1VÒT0ÉKy5…K§ Ö °ƒ;Æ­.šËÕ`¦d c,ÕM(5¾éo×äÐãl©àKyîK¾‡Š’ŸJº¬jú´WƒÌiïø©öFY_X7·«AUíÔ§’=_¦:ŒÐ²àÌî û°ª¦”ªñ9Ü¡;˦ه– Å¥–'rhEkQýc–M=$ÏípôTa¡ñDžr/¦Ø‡ ¥“ªqû ßûã÷☴zÙœFıeë‹æG#ð“Þâ“îÃÄÙòØÆðFëÇжrëÇõ›ôðÕ•¥ùLQ&º©±}]³Ì{lEÅÆÂƆŠ¶#JÍ–ƒU,â‚[V–' O˜k‹›¯õˆ[#0|ƒ²‡-®ó-ær‹CnÛ‰&ÝÒpvYYcèøR¶æÖ-ü4Œ›-RùòqùÆz_MÖ%1À*T°0gî0ÃœõU7³g}å^<Áìq¶ºÑí0ôÁtÊ\öZwt\Üò윙ºåŠÎÙ'-‹ëÙ%…LšÂç±4%…LšÂFrº’B&M IÔhMCRHád)!‹ä4&…LšB}»iK
+™4%„KÚ’B
+'K !Ç’¾¤ISB¨E1mI!“¦„»ÒL
+¡ËÕ•c0Šý|ÎÒo¤Ú&ýn;±„ŸEÓÉÌìlž¢f‰}žÚSyÄ°õñN/ ¡¦A²f¥eJBKtGJ©¯Xwö­\¿Ô4+.c©©,ƒ&À6˜®É½ÂÜÊ`ñ¸zf€•á’ ndöƒ +Ø,_d”Ø°ŽF¾uNÞP¾”ùä¹!Ì3#ؽ?6@ƒ,• ?ç8_ º»rý#á„Ìc/ç!öìÚª»LÉÜUÌæ.úWt³ã =`BÙiÙvÂ×b¤E^ìÚ°èÑE2õV6V6·z*É2ùf׉ֶ ôV6n>qêLSÍ‘§O´,*õðÿJÈôuõZOiÙOÙÊ•äÃJúmÍÑEùìw=¥žš¦E%žM•‹äÆâM-­gŽµž9ßt¤åiÏ:úUCmM}¸Â³ÎÃÿA#ùzòÉ.•4’ß&?* >ÒÆROñæóçÏÑŸì
+îñT>uá|K«‡ÿÝg.ž9zî¼gË®]Óÿ¾õ÷Èá7ÒÝ#ÿkx’¾9±¨mQ‰~p仧ɇ*òæqòÕ“žÒO­gÿÁÏqúû;ù™ ž9wbå$í<r±•œ¥üúï•EÅ'Þwæ؉ÊfOÃÖEû=%E¥%¥ËW—­^¹ªduéš’UüOMøv횢ÕkK×®^±jåª5¥¥+<ËV¬ðô¬YSâY»b5Ýöé¹oþ²±Eóÿ=Ëéå]ÍNÂ
+òù%2رUi=²Ž\é’’’5Ë5„ÿŸ8
+=
+.&;kEÞþfaÄ$ד¼(¥ÊŠœS –
+
+B
+ =Ü2i·œ³—–ÜÁ<M6^#
+
+jLjyU]׺üCªt-"vÉ£Qù•ŽÀŸ5ŠA„TÙŠ„e’uQÌíÆÜéboµ *Ї»
+19rC._K"
+“F“3¤Æ)7†¤
+›>¯?.
+JÏ™KûŸfX&m—^9IõÍ¡’²’
+|Ça|
+aÆ
+Z•ÇŠ
+uv£ë.° 0ê]S1©í™ì?à|¬TEÐêÿ{’
+훓‡VŒ
+í•ó>«ó¸5ã
+cJæ\L¶ì~ea¿°í"—”4–2ìÒÇæ
+ÌÕÈß,æ×z¡Gà$p”Vûi·]Ò€¶“OAÑ“”˜‚
+-2ÉÄ$˜„f+F-ì6Gc
+ûd̀ɽ ~`§Ð‘“V²ÊH™æ2rt1YµX/í’+&0W©±ŠÑ*:wEîK
+RiåùqD€¹fŠ$Šq\<ä0-ãy•õ:4½Õ·b4§&‘šÝGvN‘¯ˆ˜üA›üẌ¨09‘tQÏr$5”Ý
+äæ
+ŠqHJ`æ ž;3$RåõÆu¼ªæ wH#]ëDFRU@}Ù£Qy+æç’'‰Z€œŒ<`rHõõq__+[&­dÓ¬Ç L ³—¢B‡ Ä$˜]ÔŒµs[ð÷ã–¢©
+½²2æ0NcÁãêQ콈ÝÃÓH5/»\ëþy‡ø»ç™¤¼ªÓ|OÞ<¸*ò÷ü yÕ¿±üþÌþ•ù¯ŒÿçäwøFÆýóß\Ñ·`ݲ¹뿲þ÷¦üWæž,Ä®fó®ÐJ€ƒ]ò| Ð94&Ð*~¸Nh¯´>œ;­=¡'+¸e’ŠÉ²oÀÜ$‘”íîOò¼qYz›è®g춆É[=è  ¦4`2"jò?>!>³5ûÊ•'™HÙkŒz0õ$G$w&xðƒ¶õ¡b9˜óìRÜßjñýöYzLÊ{}â|k Ð!4&_>å‹Ue}À$'K¬`ÉÝAOcÀ$iAŸY(<&¥ÆŠ?·C¸¦‰ï@R‚Éxÿ2SvK0«iLþ¢]úÜ!/YÆveyÀ¤•ÔÙriå¿GEÀ€ELºúj`™ÁöJ÷KG=o_‰x@n8Žd•1E%8{òr壚üã'¥wgqQ ÉØWãÑx“ˆI€A“ŠKU¸¹Aç0¢¸£Uîoó½ûÍçµ]À€E¢'ouKГàìÈGΰ&û‚øü¡#˜SùfÁX•+Ž‹
+'#OÌù`ûV/¼Þ`Þ탞gC09‘¾rZì«v嘘T™ždÆI÷‹'‹L!8¼:¦¸x‘I'A§±£Òõå“ÞL?Àë ê|F"CâˆIpÆ䓯vÊ_<â‹(îÎ
+˜ä4=Øšâ¹ú‡øZÃöQ
+‚ Ï.Å«rÿ¤Ý÷»çáõ ²‘ðæeT¡g@3ûæ§OIŸØ'ä@¹ò¤4+Àt×ÐJAÈì´rfœ /6‰í˜ZØ}©Òõ§{=wû¤wPŽË›ÝГ`J4Ë•§Y|ÎLŽ™3YÏnÞciÝ
+ϳ&Œ¿}V†¤ \‘nõ 
+%8žƒ‰€Iß•­4ûÆ Qn€ÒA+„+ ›¥ `7t1Yž§*.ÞªA•Í–í•î¿8îyÀ„¼Þ ¯÷1ý`·€3‡DL«Ôjýåã¾h8Ç&­Ó£ÊzvkÜ8‰àIÀÈÄ!C‚¦h…¡'A0A^/îûïó!1ä¼Yº¡Âå RbòW—üŸ9èÍù€I+YE·¦¸»«=qôX8¸}2äî­q„‰S§Æj}¨Îs«WBF)9àuK…ɶIRO³olŸ¯xnì­Ô°«e÷{L!8|M¡)>•®m¢ ˜$’òå3^¢'ƒ&Œ ¯jn·˜í¥)&¿Ù$]Ý&8$ûf{ªôXLèÎîðâZ4XÁ$ÔXƾ×]áõ ïöÁ8éhòìòæ+§ÅÞ§dߌ#‹œtwWºâ(cÆÉî ¨†” ÁÉÈs>¶Ïso@|€&ŒŽçý&*ìV5 -¤“šüJ‡ôùFoDqPÀä8ÔzÐcH€ rGô"­§#yp|ý ß»Ï"ÑÛé$àB(G³\ùŸ”>º‡V˜ŒØ=)ÙB-¤×Œ†„8œÝ€ééÞþ°Šæ 8i9ÊJ×å­îW"â»Ï¡Â¹£Iôäh zÒYä—ûfTþN³øü¡½ÒþIɶÉ0äî«ñ°YQˆ£L7Òºƒ.s­aû(ÁL&¹MÚ+ÜŸkôÜ¿,ÁëípÞéEUs‘\ë!Õ?¬É_=ãë­v;3`21òJAè‰0˜
+½¾=vƒ`
+Œ°Š”ßnaå(í–4 -|‹U5c
+“¯uÉ_>î#ò©3w‚L6xµú
+Œ±^M¡öÉ(Œ“ΆVÎË-ÖX'wÜ> ˜vòÄœ?Þ-Üí—PŽÒQ‰BOfù5e“ïß!\båÊÁTf6]O2!Ìn'à uÐB®~Ô0ÁùdGPø»³^˜(ÅÛ=ðwg:iöê¿¡Ê_;ëë¯qÑ€I»çŠ¬ ?K4çBñr=a§šì¯;ª±ŽöÑ° "Pç‡<×»Ÿ6aô½ûœô&$¥3x¯_´]/SL¾Ú)ÿå1o,Ì*LÚ=Wd ¹OSUtg7*9Ü>©…]ˆœÁù&k¸øðÜ¿,!1Ç!|ó2-v«&p"yö͈&ÿ×SÒ'÷y‰’DÀäÌ&´»¿ÖƒÌn n6X¬õj¨a‚ EòØúçó(Gé’«ŒÊ $WøDL~¿UüP§½Òþ™!»¨öIevëñ“€³¡¡†9.µ°»£ÒõüaPCF§†PBOfy¹òaUþÆ9ß•­BGæ”™Oe,rR¥ d1Ž2æ3M“1@FE7Œ“ ¸P$’²½ÒýÒ/“ðzç<É%~½z2ƒÈ&Éë—{£˜œõ<fŒCL:¼NTDqi!Íı{p‚ saNï½^ï\'[2¼1@Ó‡m×Qàu&&G5ù——¤Ïòv….LΖD60·&í±ˆL§ƒÛ'úÉÁ#™‡;*]¬söˆ(G™ó|!”@ž}s3*ÿg›ôÇõ¬\9¢¼æ0ƒõ±ƒZù#qdâ8Ü:«ñªa¡ »AÐIù¥DQ:·º¥kГ6ŠI09¢Éÿr^|f+ʕω\0°JAB=q½ìdØÓ‡æ hy9ÊÞj÷ž¦^o”£ÌU¾uEzpU¼Û‹J;Å$˜üÊ)±»Š®ãÐ’{Žä9ZU
+‚žt0¸q²'èVî^'AÐ&ÒÄœ
+÷G<·û¤wàõÎ]>`U͇ì–UÎ$¯0ùëùϽ….â &ç:qzR—Г¢æ$ÚMÞ×ûÎù¨×›Ù²l?à|ðÍËÒ°†Ê…U’ŒDLþäIé#{XÀ$²oÒ1eñnz‘`·–l†^Ãœ&t»‰‚ö’z½ƒî­î_G$Ræ6GcГ (&Ù©&þ_›Åç¶#`2S/CTD•‚œ : Q=©"» í&¹Û+ÝŸ:èyã2 ´ƒ¤Ì=òÊÛ=~èÉ“7TʯžñõÕ¸:‚ëJ'{ªM´ú
+Ïm®G}ðzç*ß¼,Ý@å¼*I#`ògOËŸØë!J“i'ÍÄ =A´Åq:xÑQÕÈÄÁ‚Bêõ®p¿tÔó€i$æä$QÕ|Å$;±DL~ï¢ï…˜œ¯iªŸöX¸ž°WÏ
+ÀqàÆÉ ¼Ç"‚¹ÁˆB_¿ÝâûÊQf9ß 9‡›(rå¿h—>{ÐÛ¥ `2#¨±˜mJ¦'9éL˜×]U\1'A0·Ès>¸Ë=Ú#ÃëÕ$×Îá)9<`rD“Ð&ÿq½&3‡šÂŒQaﱈÌn‡‚éÉ…nôÄÁ\$‘”_:á}Àe‰Ýºœ5oÆœ«'ùkò7›¤«Û}“qìe•a Y=éDðvHª9 = ‚¹GÞ„ñ‡OyQŽ2«y·×~]g—˜¼¡R=ùòI_w ˜´ûžMš×"z$Ž2æNÏèתVõ²QöLÓN-Lk½Èš0Âë½|cÀ‰ÆI0©Ê¯tHŸ;äð€I»o(p{˜s³w ʘ;Z¹^Ãœ…Ñâ&Á\fGPø›3Þ·¯Š¿×;;ùæe‰ç5Û®ñHI2Žjòž”>ºÇs©Ò˜ÌHÔz4VÆbҙГáÿ[ ½è‰‚¹ÎΠ»¿Öý‹NñÝg‘ë•$WmÔ1!”ü0G£òwšÅçw `2s ÓzMZ5NÂÙíLðë®…ÖB0N‚`î“—£üÄ>áˬ%$eòNä=ÉË•ßP寞ñõ°€IÛop2öÓ`¹Å/ž¢Š™8N¿èyyZˆ'm .
+“¯vÊ~Ä×…€É &·DÅÂzsžÞ 8 zÃnÅ­²‹¸[AÐ äå(ŸÛ!¼¦Q¯7$e6ñª'õªævK¾ùR’LLŽFåŸ<%}¬V˜DÀd&S32q´Z/0N:¦EZ ÝU‚
+g7:†<×û¥#Þ·ž×;ûH–
+“D$ÿåQ¯Æ
+à©”Œ1{Ô%Vv2
+=é<ðEÄ tY!ô¢Á":•íî/ð¼ó¬ü”£Ì*¾1 çLJ09¢É¿h—>uÀƒì›l!ÏÄ¡mõ—©-ìT6€ÐËUÑÐÚÀÝîa ‚ -$îžj÷ž¦^o$ædÉʼnæBJ3`ò{¥× 4ûÆî›L‘\óǪhåÉ8ʘ;d$ô×¢L:—¼åG„Û}¾·áõÎ*ÞÌþªæ<`rX•ÿ¥Izf«»åʳTL*îKÊÃqèIG‚—‡Òj–ŒÁ8 ‚Ž'‘”û¸‰9YÄWÅ;½Ùíï&b’»ì_>鋱råðqg5VƼ3L#'‘‰ãLðë /îGƒEt<yîÃ
+Òñ
+rt=YåÒÂnØ'AL½ £å(3–®Š÷Äëªßv19•yÉÿé(Wž³deÌ…(ËÄqÒiHÔ0¹x‚?îqS$OÌyÿNa(FûzCRf&ï_¶³
+%/WNÄä¾Oúp
+FÙ? AÌ.Fúúƒ'}ï>‹ÄœÌ#Óù·{l¡ä“äÍË'}Ñ0-WÎ4`îQ3©Pg7Œ“N_A<]ýd
+Y±ºÿãIs2‡äB̽ª9Ͼ¹•¿wQúpÐ^iÿxm¡iŽŽ²žÝ¼!à pûdÈÝ[ƒÊ` Îi9ÊJ÷G„[½Ò;HÌÉ ’«p36'=ÉË•hò7Ή˜t6Í‹Õž8ÊN: z™ J/œÝ Î7y®÷WXF*fìVS áÞÙW5'ÿpX•¯uÉ}Ò #`¤zR/; 1é0p= .î«ñØ>AÌyv)ä‰ãþy§¹Þö“Upº×/ÎNOò€ÉŸ·ËŸ9è!—µ &Î0ï±èÖ!ã¤ÃÀ#'{ÈŠRqÁ8 ‚à›(?¹_¸7 ¢e&ðþå‡Pò€ÉQMþÑû¤?ÙͲoPµ4¼œ¼Ç"ì“Ž‚^v’É#rÁb„Y)¿öMÌž´äŒÎ$„’LÞPåoŸßN[rÛ>¢@ÛÉ%­_FEÇA“µ™´ ‚ @òÄ!"äê6á5M„×Ûv>¸"Ýî‘®¥¦'y…ÉÁˆô7§¼=U4`Òöáf5v_“71¦'áìvx óí„¥¡a7‚ Hšë]áþ\£ça"³]V9“o]¡!”wûR*AÉ&_é?ßè `Ëst¢Ç¢Ó`¢ÕœÝ Ú@"H¢a÷¿·Âëm?ß`VÇÉM”<`’ˆÉ?)}¬ÁÓ¤—ÐÊþZOgÈ;Nc
+ ªââe'óB%Ùƒ´n3‰Üë}e›ðJMmâ3ÒÚä?ª:‚¨0 ¦Äh˜eâT-æ"ÃN‰, ô†ÝA7j˜ƒ ˜iä‰ÞÏn~Ñ—· |ëŠDNûw[¥î*f™DÌ$˜™–ðjõ8zv; yFÃnîé†}Á !ï•óþÂۤѨüæeûõ•ÓÈ‹É¿Ñ/ÿÝŸB;EpòáÑ]%DC‚Uc
+¯coÿ8A¼TéúâßDË$ÿH$ͽñÝúÊ|ëi4*ÒÆ‹ì*IùÙƒÞK°R‚M«T4DËNò&΀ÀûijÕ^-äêFÙI3€Aáó^îW%ÒåúX=ÉM”·{$èÉ…“ÌåMÎ<¿(ÜJù«Kþ5xÚ+í6`&ÐLÄè ÿ*2‰ãè=«Ö½”½í£A'³½Âý™ƒ*&™_u¢˜äJf$*¿‰øÉ'Ñð¯÷‹C– 1¬Ê?ZþÓ¬” '«:(P…1é$p[tÌèÖ = ‚ $š„(“_]’n¨òdbÒôzßë‡ËÛ?¬%®O÷þE»ôÑ=TRâ!âpê=Ãè±è8håôrG‚îþíãAÇ’wTüÈQ&ÓŠI.cnuÛ/®H¢áGcc.5kòŸ”>°S€¤t8»«MqZΔ$ô¤£Àóq¡·Á“ ÚC.&_ØéùÉ“Òˆ6½˜äöI¢´‹wz“E hò´ŠÏï:‚xš8‘| *+;GE'ÁZ,¨mA´ƒdæé º‰!jdT£Uh¦“¦¤DïE[x@šÝJë8EuII.((N£Þ_¶YâF¶/à0=Y¿;Oå´h³‚àÂ’‹ÉZÏ÷.J7£)Y&­z…(má[cC(­’’\Äï^ôõV»!)HV%f±Vþ{qèI§éÉ–µ †¼Ý(> ‚àÂ’‹I¢=¾Ù$ÎPLrõ2¤úïÃåmou¯ ju|ÿs“.)mcàB²·Fˆò2æðt; zñÉík¬;’¶4‚ èòöÜDuíAc&'Ô-OÑDy»Ç,ï…ç½~1¹žävã¨.)É%þÿÙ{óè6®óîŸÿ¼üÎy缧¿æM_[ –™´Û’âX¶µÀ’\%JdbDZ-ï²­}I
+m•¶ ¯øÉË#8‰SxÁ‹™7WØU~& ùI
+
+;ÃüäEKÞÙf¢[ºÒšÔöWr¹ÉQÊ¿yÈŽnŒ¦G6/æs ”¦¸f‹¬Xè
+
+›gÏ'»¥+­º]¾–a>Û |©ÎV_‚Švæ‡+eJ™oÁ}2èµvVÙá“
+ž™$_~ð4mÏ]h25 ô^Ì"WÛ$QcŒÿs‡ˆR>#µ”[ÉÈÇ ˜…' ÿòFe§¹s9¦ß¹ñ–×d÷‹ê-n­°%œàÆ}
+[ ­??ye….
+Qf…á°"vÉ[»èD)Ï7*¯=
+Æ€
+z’¾cB&3s ¿rQUFQˆÒxFšåÜôɾؽÕ’L¯PÊܧ+Ûh¢’nÿ‹À'3‹øZLjyôn.Çò7
+—É€·øÍmŽAÈd†.áW®bÉÛ`&XÕ œõɾX–r8äüîŽF½¹ ”¹
+„x™äs_.ç|ò…þ€Œ%o£!Æž›UƒâéeƒaR)Eßï…Ll–nðKð„^QTTôFmlùÛ]õn)Ç9
+-DÙ-!EiѪAù3Œi“wUyïüÇ[¬Xø6ŽØin d2‡"nSeS¹-è‹Ö–>Z
+øÍd„I"!â[êxi¢² Ëß
+NåÇpØ<>ÙËR?$¿²™vMþ´É%,U¶`©5‚“ÝÄ*µ· ?QʘLâå €4Ðd’˜äÅ ©&SóA®Îeô^4’«­ìw}¡õ3ƒªòSJtcÔ ¿C-Ehyõ‰¥Ü+„z "{QÄ*‘—ˆ7j‹¦¦¦ùªwȇ‚B
+y³àÇpÔÒÉO
+[%ƒr>âW±©ùß¼­ÖºèîGŸ5Pz+Ý
+Ìzkô2ˆ0ÿðéBWJò0l¯´52ŸÄþÉÜ ÍCEE3»'ö.µÒ4Þyj,÷ØRnmáêHׯ§i¤@/Èýu¤¤økígê*öLæ+tÉ[EïE¹ÚjZŸì‹¥¸˜R6•ÑF…9Ï’ÿêÖŠhIóJ‰ŽÚ:ºx=ÓUè¨r„½óB´+â<vù¢ç¯;ªlä"òî6jÜ6†àÍß
+LeŸ&î“ÞODP‚Rhì©ûD¸Ì¢zŠñM´™I†|V¾M2¶„mC r6@&MGÐy­MBïE#˜`UƒL¿!„×
+ _¾õˆCøcJa^‚r¶P
+ ¾ÀM”žº¢·¸³ÊÚTFÏÎKÃ2 €8ÈýX_by~“õ݃ty 2izÐ{Ñ8Ÿì–®¶IÂ/qàJÙÿæ!{¡5øf%(‹µ’æ(A)*¢J龕m¤ùÉæòh– @ŽÀe’¼ñ½½GBfÒdðÂ/c8•c £…’ÌçJy¶AùÚýö†BRJ.*ͬ’L%ƒ„†v ç%š¥¼…­h[šÊ&7I
+eç>É–¼±Þ->ˆRjUåÉš¨ôF+7Á*­3“ÉAȤI!p©Y¼w™’‰.z‚^ø%ÎæX¢JÙ¨|õ>[,|Oú¤¯X¬J!&£è¦–7¬:E³J¬}eÈM×è)i2 Ÿ4%¼%Ny¯TKÞÚpP•“G”W¶ØŽ”˜¿Î9—“¦8ŸD Ê\ VÏ\û#¿çVVpÒÒRÁÚÜÄ]>
+Ö{QAas#ëˆ6‘~•³=¨X–ò»¥Î*¦”¢nÆÁWN[×ÿaG¼s>ŠnÞW©z?*µñÓ:¬;½ &«
+åõö½¡ø2Ç€ªüàiG¸ŒnÏþ¸Ó•mÀSY›¿êåg„ŠŠ´ÞFªoòÜwK9µÊ VÀH.“ßä2YHµò@<t·[½ a¬³P/N?´Ø'ù¾¿*eÀ\J©í¸ ±9ˆü›Î€»o x£›~ù¾JT`N “€Ã{/"Ei—š
+:íÏ•rPUÞÜæ°­Ú¦™šÕX Ê 7ê“HQæu¥Œ¿‚|Õ[õ2«ôãÀ
+øþZj ²z•!´×`
+õ%–¯Ýo?ÛPX-áÀLôä‹A,yâ“ÑÆ‹¢/±àÆ”’À•RøPGhCä'ÍoÔF¯fm]QØC_iU½è1p(%
+™"<W[Å ˜ù¸јR²­5fRJ^½¶‡.»…š|Ò\QwZ'BKVÒ½ |“ÍK‹~
+QêÎxa7^œe¼‘GÓ±ò ›¬ y¨”ü_8ì³ò–‹Ø?YÐ'–´¸—¾e„ˬá2«ð
+@&p™ì¨²ýt—„‰ $/D9Ñ- w0“A«‰¾¸9WÊ·÷ÈäaEYy§”¼¡ê¾5‚zæˆZÉJf•·`/%Èkâer(D÷Lb"I‚Þ‹q­M~qs“^Öà›<¬È#«Ñ“7“o¬˜¹E-ùdÅ'Z=¹b9ÿª–Ý¢¢šÈ[È %ÏäI™ôã H~*g”-y㬷ŽŒuÈh¼8Ó#‡ydµUç…Rò&)´3Ž‡žìÆJ7"ÂÔÚ µÌÒèn¤Ìýñ ÀT¸L¶TXÉ“y2 Ò‚ ô^Ô4^œmȱQGYo=#‘ù×ŸÛ G´7­ì$Vº <hv:6Tï'B¬-#-uŽÍ“ ?!˜<‡ÉÓø‡Ï`™¤ï½HüG¸ƒ™Œ+-h¼8ó¨c ¨Ê›Û¹¬”üߊn›d=qh@& 9âs’î[C>Úõ)+oÄ27ÈC4™üþ6Ç€
+™éCGNlÉèC'=ât½29×Àc{)¿ŸÛJ=ƒ³ñ–Vº ;4“Üsש¥7•4 á2I^íÉÓ¸2 2f¤Å)^ÃÌÅX§<Â’÷lð×PHùÎ㎆K@ôsu*MÌü^[' 8è{ËK“/a_´Ó"Z.‚|‡ Ý€·8 ™úÁ Q
+0óq©YîOÎ>ör?ûòÍ­ŽFOqN)e¬[7]éÆî Þ¿[ûCÕ3ï¦6‹¹šQ ¸L’§îwž€LÝÐz/
+031Ñ-]iÅšÄðó+\)¿Å”Røc6K:…ˬ*kÕÍÝBŒÓ E|wEµÌ¦z©C¶W¢µ"0 Vj’<uyÒSÐ ^ˆ’ö^ÄÁým—/¢¿@rÃOËRæHƒï–héòÿÁ¶É r¹µ+Þ{Ái.ç½oò¯¯
+öG%Û&Mq‡nÞ¨-R=VÕkå9I””æãHIñŸÎv¡Q¡dqž‹Ae´ƒí¢:1Þ‰-”)ŽC¶õâäaå•-¶ú’loWk­ .4Ó&9ã#~u›˜dÈ=kÓRa…CSBž¨_»ßN^ØÉ\Y 
+z/Á0/¦>Uå7ä—6g/K9¹m²ä“¬t›=´j¢ª{­J›ÈÓýôp“¢Éä
+B) ˆL~å>Ûézç
+Qê@'m¼x­MÂz·øéçpÈùö~;17j!“ˆŒ‚+eëú?¤Ç»X]J(%È2šLB&Aþƒ%o½íñ‚i ~¹? _
+;¯…æ x+x—hAä}ðÊ
+`2Èî:Ñ{Q™ì¢KÞ—š°ämd”^mv‘ÏØIø$Bçˆf)+íÁX–V ôBõÑ=“]UÖÿÞO‹c™˜¾8{¥E¼™ƒ«­ô2–¼u‡˜äõg_ÐûQÉa@D•Òãbáè‘ɵ­Âò³]2“Àı=Â’·>Œu Ç1øåñ6W_ÐAñI„‘¡e)±—è‚&“?…L³£õ^.cæ`0Œ'†øåm®^¿DæúwžX(Z:fŽh]J(%ȘD™þ À`h!ʺýO¸Œ™€Ë-I½ ÒJAD){‚¬øäëÈO"Œ¨RzD)y!áfò.“­Ú27¶B€/y£÷¢.\o§>‰ç†žøé.Ú"ÇÏöOÂ'Æ_øn*•T¯¥YJ"ô4·—~ù×gC¬î&P8\k“¢Ì¢å±IFo†C´XPͻ٠>ÒBåÔ
+¥É£úhi òùæS^”2
+ô^ÔT ÒZ|2èì . Ó<Š™#²¼Ò©êµ½¨K ’‚×™ 1™¼TPñôTŽª ¥.\m“ð
+@v!ýua´CFãE=ñË£­ó{‚òñà­ÚüŽ@d'ŠÈx+ŠËRB)Á `{&¿÷¤c ˆô p!>9Æ© ¿áªéÊö½ìp7’“ˆìQÊPœR"K ¦…Èd£§ø›[ý±)Uø“
+ùüýóéyAŠ¼(E?SáãÊõZP‚0ÊHêK§|©Eê;.†åT9”N4PN2´ï'núßþù<vØñö>Ç;ûSàíýŽ_püx§ƒËsJ¼ù´ýGlùyÛ×´½Æо$|O€ü©/ÖY_¨±¾8Ĩ¿ôÛ»å!UÁ¡K
+‡O"r&˜OÞxŽVW#–%ð!£©ì8ÓËÉÏΤÿTŠdÕ™;ä´g¢xÉL .ϳða·4Ü„g;
+ªõ&HQ (D© c2
+Â
+NãðB”XòNöÓv°ªA¢¯f^â—¯4¹ú‚ÎXÛnø$"âu:'º¥È‹Ø9 ¢`n¸¡e†!FÕ t¡ùIZÌ>‰Èà¯6¯Hã]2»Á„vÐ[ô£€§Ç¯ 7aA'³N·t¹EFåÛ” Ò•îá³?Z|2ŸD·X“¦±îô‹"ó%
+í] |2c"
+¿‚¹CÐ9¦>y¢aAQQÅ'Ùæ“£I%&¢`:z™\k“p(2 ¢Uƒð`áWšh1ówvQŸ ªðI„ÑÁÆØ«Ö]” Yc ›
++f>¨ºÎÕ++–=ÉR”Ÿ)b!Ú:& ¶Ø=Ñí$/Â(; ²jQ0~*g /ø©3ŽÆ‹?BäËùF'ñI·ÛÍW½á“­èI<»€pЀ©ô¢÷bú⓬9Ή†Ä'ëÔÁ'KNÞè´ßèvDP)»(˜
+/D)üöÌ/øA¿ëíx˜Phs¿|ìÈ‚E ëjkkc)J,y# ˆàšœtq™D;
+¤(H
+Ú.µ(¸™è’7v¶§]òî–®¶Â'åKagßÙñÈÊ%OmíJî“,E ŸDè±±Dî¾ÈËHNñ ]
+/D ŸLZ5(,ôû©_¾D|²aþ¶M%Î{ª×Ö®-^»)J„þÁÒnǺAÞ
+ç=ÕK<,y#Ò *“§_útKHN‚|½ž$HÝÌî7»2Ó‹ƒ‰J<çÙƹsñ‡9Hó]þ=ºBM‚í¶ÇC çx,Íul»ýÂam”ŸL’NÚxñRHâŠõÃØq•™Dñ½Ø‘áZ˜‰O[&#üj³ëLƒëŽUÄ'ïX³q¡»NqWi…ƒø)oÞÎ[´¢ ò'Xrò·/ÚÇ»äß…O‚ü
+Q.^UA|’_òFŠ1m¼¼‹|^gwíª úŽ .5ÑÅå“û¨1¾»ÝU»Y¬oÊâ¯p1
+›§Do}–ò“Çv:z÷Kûè’;î­¤%×l<´åž3{È?ÝaÜ‚;Ýq0qódÛ1vþæð‚òåÄ'o+©˜¿n³óžj^Ø\ë½H|rŲ'¡”ˆ)Áʱ²“¿{'» ¡Jߊ:è$s.yœR«D®ÌL~ òo{f:I £ÜðÉä™è–†CRvŽäÊŃò×¾˜ä’µÕäsÙ½Ußغ´g¿)J2TÎß¼/br eÈy¶ÑõØ–u®U5| å÷æEë«]ëk¯ªàKÞÜ'q*1m|Э ì$0ñ{)êœ÷=ÊÙCÔ*ó΀ÑÐÒ ;'¦«š³çs‡å©­6é)ï2†B”I>4XÊk­Ò‰¬l¡<¶Ã1tHùâç—SŸ\SM _ªK=?yF¡YJÎzóÊ“= Ò4>é§-ÆÈçˮ֎äðF9ËVE ݵ2z*'¶‹>‰àÁvN¶ÌïrD^„O33U)µ\%-.´w²Õ p1
++É+%y÷4À*ó•ã“Ç·éùš×¶.ý|Åúø‰{êlŸ&Ú¶q-ù˳ÖÖ9µÿ4~gVIàž@¼ðû.ëÏì3pÉ›Œ(ò’ò¬˜ù´>ÉWÀo_[ýGnϼÎ
+—{“æ“|É›ɹyÉ[( -xO9òMNŽ3d’¥ä+à<Wyz¬¸hÓ(@øŽVš¯Û/½ý¬òÂç>Uáõj‹†é™d‚R>Q}ï ¶L™#×—6€>¬OrU¸Ì–¼ñðOƒª'$fø«íR™·tQ\1óÙ³”‡·ÜC^gŽ§þÞÊ‹J%ù|ã[(O78_Øz'¹qV¸«–¬©Òº.ò%o¢—Ä' ðÉÂŒ J/÷õ‰<Lp²€2UÊ@´‹ÙùzÖ´1¦7•£8ΪùÓ;»—®!þéƒËj|-!9çd \G—®­þÚC·÷ìË¡òæç§æ“ÃaeKÞÉÁ«éØ¡Fƒ7Ç!o=w²ms¾ìh«Þdø¥Q •ožœ£CÜÛqKeÿÕS+ˆOÞµaã´>y×ʺ›/b e!+;9Þåø°·
+­ìdMNÞèrˆ¿OÈM ÈRr«ìiÎD{LámnNî¶÷ì—þói×á-÷¬^_®Éž9Éi•rǦ5¼ä‹ÀKI1“¨dž¨
+ìs´]ô–ðFÞW[ï뺅’ÿ­ˆO¶Ýwg|Þ;ùáGW½ŸJvÕ›½w¤Ð^–â§û'É—¶­+‰O®^ï[²†v]\zw _òžÁ'Ñ(§
+¾½;ýê ³äÙ=´Ð7]òTµ[;¾ýÕíÙsD;6­!³yjÅ[tr’³‡¤46Oj¶0€%ïäŸò¹ƒv½–¼ù6à<9ß½¾,í!½8v;üéƒËα}¼Ó>4ø{G:›lÙéñ+ßx–n¡\¾n“‹å$§vñNðI¤(ÍôÊ^m“Æ»‘áw%
+Gd~ùÈ8!ƒüË-[ÎúÎdR.•¿amß´æýéÚÊG7OÖ§?H.79Y°huµk=âMÿ¡ìHÏOò#Þ¼‹7|²@âF—=òvN>ÙËRÆAÛë0{¾UòÄ.GÏ~éÇÛœmŸ½“ï+‹OÂä8÷}š˜ðÔ Ý¸_ìä^G†£‹/hŽvˆ¿¹òòCÚ«Ï’÷ñt¨wÞÿéx'LÓ'ÙݱdíÆ?}V8OH’Óq²'£M¶×š]g]eeôˆ÷Oåüuôˆ÷²UuZ~2¾ë"|ÒÌÁÊNNÐm“ŽŸÇ{(
+Ñâäyk’ tÝwÇ,Å
+¶ØýásóntÑü$z,`£•20Y]³Ê,„Îs’Ä$Ïîuüäåð–{Ön(×Òz9UR2´Ž9DŒî˜sæ`F•‚nòÉ
+Õ3ù$=åüdR\o“Îìw¼›Ö­D,ô}v³ìäÅÌ3¾5âM²¼Ü÷å§?}ºiáo*‘—£í²>ëÝL)¯4¹þeçm‹WmáùÉe«ê¸Oâ<Ž™ƒ•ï–?À1
+wet²3Ññí4fù}›WÖ»©7ù[ÑJ晲˜2TúƒÎkmÒ„èÛ'/è9âH¯‘7­õ´ÛþγÒ#U´˜y&¯Zñ'Ú*Ê}_|jeOóüžsFغäh'ͦòî6ºŒ+Í®·÷/q¹7-]W¹bõfâ“ õ‚âê™Ã'MEÑ“8ÝRä$'Cne)o¶JÛëðãÛ§vK½û¥ms…ëVÞ½®‚Op‹u-„’wð‰~¹»êë[—ž×/EI;žìvè{gR)ýÊH³ Ÿœ¾ä=Lsg,/>ù㧛|%‹ÒºGøÖí/¬®(ý“wõ4/ˆ¼¨üŽ—à&Éÿmõj¸Ð϶P¾_¿àñûÜKÜ›—{½<? Ÿ4s°ää.2œ>DÙI
+v¬ûƒnš–üèyø$
+KÉÊåÒ+¿™óЗ}ïr¿Ü!ôÀy¼1§~jv”T<¹\ŽR3N rèʇ7ÈÄô(eË\a¹‰ªb™\øÓ çŒ]<É+‡þyÛÍ×=~ßE59©¢N’®'#ê$Ç¢¯HiÎŽØ•§-[«K×~yÛuLFžóÍ¢~rÁE?bzr!_Гq²x²û«g±Ãì+ÌÄÀ68 –2ûâãudshcùR×÷µú‡_<Ô¾ F@“‘”<~{×WþëÁ)MÌa?X±2ê
+ÝÕœ}ˆ`zrß½g™‡ÄÏo[ôò²y'òRØ´S%rà¨ÄHAyùµäˆìñãg3=y­_O
+³ SOZ-‰°&¿erÛÉ"3q
+:q
+Ô“k"¬I/žì>YÚ_¬Â&
+)”¬wÍ:+vº[m÷XjØv
+¢>ݲ-W‰€žtk[¼€éÉëyñäÂ… ¡'ºx[÷ÀF‰·° °¤ÕtÝñUM7Üô’ Õ¿¡Ë-Ô×ÓUH­=Ç3Ïz™æõ\ü›;¯¾ñ†ë/½æ¦ Îñ€¸ådúz„åÝ7_ùùðÆjÆY+û¬Kv êÝj[ôÝGŽ°ýé-Tj×Ê“èõö¥G=ëÍ>LQOöx4v0ÜrËf]~Ï ò ГÎ^\Oö–¤° >- ØHR2i‘«ÄÌ4/ö iKî»H†ê CuAk¾úþúsŸ}`~î=—þîΫn¿éº‹Föõ„i¨.B”짻k^íJ#D)Š'-lÆ ÜéM™j,ç¹8”>Þ›ÃÎÖêURX’R alÏ•£¢d‚¡§`ªGB_~J]ºzö¢EýˆŠ'ýbÍ8N\|—mŸÆŽoyp2^/é
+ù‘!mYHÏyϸ:ø(Íg_iô¤Ö䤾¾ú¼Ç~¿`éO¯¸þ†.¾ú¦ó+̳Íy=—‰‰97¿ôÛ³ëVÊŸ/qU­–-Ov›r‚xHy‡™R†9‡‘>A,÷aŒ‚¤dçl»‡ªa's ðãðDfJõ†Téúë¡'½ø.«|øÿë/V· 8 @‚b¹¤)oÈÁÔµ·ì-RŒ¾žÍê·›T*w/‘»
+Õ/ô9;–^Pø›‹ï[|Õm7]·pQð´ñóxùïn½â_KäŠerÕZÅòfœ@IÙ_­Xцíôf]9>öpöQs–¸ê¢3„QÔv²=8Ɉ·››tµ:-…éI¶übΓ\¢‡]¦Šå¯J­?S
+o,?;
+þØ…îŒ(`jË>îGÔSHU‹^ÿ6·m¹¸ M&)«W‡¥üb aŒx•2;¢:óÕ†IN\OÊÿX§-\¸zÒ©‹'O•jâ`°ü¤
+CRÆVT°?×’ƒPUtÙR&,Ûrù6·M ’2ì]iúœ¯
+ÕAˆý·†4©¿$¯„œ¬&åjÞ–MÃß]~öb¾ìvÞòï/ªœ|§0
+{3q '¹x²ûdAj?ïD4
+ERŠ!Œ]y‘œëÝ%|!ÂÔ“-YLOj¢ zÒ‹ö—ø`=
+””(ò¶ÅÈç|Â%lÉŒdˆ2¼–1¼›>¿È¦ž´Za…µ¸˜Ì=­¯XⶓÑrË
+–ïœê-”O•`Š
+èÄÁŒE
+•f‹¬„ )Ã…IÊÖ,y,SÊ/–¸Ó]“¨¢ F­ ¦x‹ïvyRÜÜ,èNèIÛ/œ<U¬öc&
+a%ã¾oHÊÐGöè]?úèöÅúd†06_öà¦cƒ=ñé.*ÈwÛ|ñød_‰rªD> ÷6
+Imš2ä£CÛÆÂ8À-FÍ´‚[éöhõºÒVp.—/ГvZ<8ùei2û€d7
+Í?ê¬L
+ä(Ѥ …>~:wæË4¼Û­4¸µ‰´Vô÷ÓÈõ“Hv
+Îé/v >ŒN
+'¯¡ŠX2Ý =tñŽcHʘñU)/¼·út’5ГÖ,ÚìGõ3©çQ'
+208ï— ¥žÿZvËcÂîèq;P{øÜ–hHÊNHÊ|½Që.P{ò$Ò5Û¡'­X|³Ÿ,’úáw
+N®¬®kaàŽÞœ wt»Ó‘G{*"JHÊ ¾Ú¨õ«ð=ÕÅ7]!¦~½Q³|·
+wô®|îèö¤»@ÈD)ƒྔ¥ ÐEXa/næÙ_äêçwËw+
+]ýÅ’Ø,
+øc"P@m¶ì¼H:ó”Ò!'ýÄ|žðdÔoõç<a~+o2ßj÷Ð¥2ºä*ÍYrÕ*ê¬9jFZ-ŸÀHª×Ê00KÌΞ
+g'¾»U:ìRnîÛ””–¿x;0ø°ÖÇ‹.&™•0’òD6õÊ5gS”›=Ž„}½Q§O|âÑÄü'{ø<èIÐÿùõP¾5Ö_ŸÜo›à[þË
+ê6XH
+7ÝÑûÑ>œpsß”öñäëZ_±Ô[Ä„ãwÀ7·poà­Ít  F€ˆÂ.ª+‘õ¶š®ˆà$˜£%œ»£3a)Z‡‘س?£IiòÍ&aÌϦ”z&½¯æì³ÜJGN
+RÞ
+oɦÉb=ÜÄ2‘…eGȹo!;Û=Ö¿fË|D£ÒÜ‚s˜îÚ±8þ$%Gú|¶»[³¡'ˆ•«Ñ›c Uk0]DCXf(M™jKŽÚ‘§ö&jçÎ
+qŒ$¥AE)icél.½âKRú[¨93ÅÇv:ª(ˆ09=N‚(aº£ aÙ5Â=A 1:¡å¾!)}|À7–]zò`üE)uÊÛMµÇГ
+#Î[ÂÛ=ÜÝÉáJöúÇ£IÙç—”ƒE“s²¤˧+mÙ<Ù”7
+B”
+Nâó/ˆkÌ<8ÝÉV;òHžõ;-bÉÔo»Çx;c½M¦9\Rž,‘{™°Cs*)ºrȈ×g
+ŒRZþ:­@¢ßÅÊ—Å2i3'Rò×Ü¢ÓÞlÏñ'¾
+”±Æè JùÍ&>à»(…äÙ””<¬Š”7
+“ó±ôdÕjx0yM,™°^C”
+·Z51z‹”ælªÿôŽxÍMYjOõ¯Ð2Iù0™ n<“ô™ƒÚstQBéjp#å €èLÎG“Ç—Iõi00 ŒéŽnue›Gó°‘ÕîÕº×DÇ÷`¾ËÔiö_¢„²I§b†6¤¼°]«Y“óázÓˆCîè¼%¼3_¦är‰l¡rëÊ—G侇IJ'ØlFJ|—(~­æ I)^'»n·çP—7|9
+o2ÝÑ£3̱ÝÃÿ—%öRö «~4ž÷óˆ+Ü,>BÒ›-}´J~ù÷ÒwKi7'ß}iÒÕç%«ÉIÿuzÒô3“Î<“4äÌ™$#™ž”’ ˜¤¤'ìqÆ C½ÙLUŠY9ÕkR`D €=H“ó£%Sp2Íú 
+[@Ž¥*ÅmÖ,!åì!)ùkØ2)É®Üty`=ºV»^9¶Ôzá==‰à$
+¶ä:““”Âó§¯XYy½ëôé<ÛêÇ(aØTΚ¥YUTÉC”>]a’’º¼a€m¨Š“óÚõÖoL
+“”ƒx„;З¥ªç׌<^gµ´³
+3ý-%'+ŠbªÊëIñ ·Ocz²7/z
+¦ƒeC‰e‰Ü™OÖCBRŠXå7›”'ï–(47+Aƒ“AªRâÝßRô¦4êó)Dé¿ ä
+µä å €±‰É9{•˜®€JOkÁ¢Qt¾pÅè[{†oÝtúSŒ9çQçKÑ¥õ%WÖmº¾nËÍÕÿóªc|aÕ1î}¬âàŸËÞ~IÈ?.ÞRÚ(h|Óˆ1òÜôqÊM ÑÈT⨢qªºzr*zRæmÝQœåÍõdg>éItå
+I €ÝѵnrKIIÁÉå®út$»A2¡}·fŒ–.ÅØŠ1æ~Ï‹›®«}ä¶Ú?ý¬æéßV?»´jkõJïy”bŒ‡¶U-Ž Œ7JsÌ:Æý#ÃŒñ*¡'''&]I´b$& ã J}.;kºrSPE €е굱.¤¬^‹6¯¶H§w¾Ùwk~¡¾iöH)i&)%}CíTûÄÝÕÏ<@YéízåËy•»®8ð?åo>WþÎK¤‚†*1güRF뵜€žGOFËÀ|ì%RÞ¾ ­)S5ÎëÏn
+uy»ÌÊÀèZ]ZÔMÎÙ//_!!8 ìĈÓ¢cÚÈJ'‰Æu§ûÖžÁE£F/L.\L~Œ¯­Ûr)Æ?ß[ý÷Ô+½³Týöݤú¸õb€}·øB/¯ñ:FÒ3Ã;¦£nß  'C“IIÊÌ™VèI£Š²!S9‘™Ò¨«Hyà ü&çQÍw×®·úm‚D!ûneØhiÓ¾{ý Š1fŸCŠ±äÊÚ‡o¥OýªæÏ÷Qã6wå«Å•{-ý¯å‡¶3h¤¡Í
+F¿}7׊¯´½ð×1Ž2`ºÑr 'Gד<8ižÔ”wƒ›Œ(‹
+&tðö禇ڥgP爙^>ó…äbáe¼íåæÚÇRóä/ªŸ]RÅ{¥«^)äfŒÏ—Þ‚ƒ÷köÝ£8x#%à@Oëɘ{NŽ¾xˆ’}À$#J1žÞúË
+=é²I[÷ð¥gÒë©Õià)RÞ
+N®p¾6fÇ´á«“L™è gúÖO§d41Ê ÜŒ‘¬uÈñbš¸ùÆš'î¢:ÆçÖÐÌ—Ý›+öÿÉЊdß½›é@ºQ2}ÈT"Ó†ÇΛÇ?öÝþ"ÆÑt#D#H4 ' ›ŠI¾xWN½®œÈäWK+
+Zr
+Éfk=¹]ÌÊQ|ºfd½
+N
+2Sêõ³Æ9Ë<ÿ?ï¼ú÷÷÷lÿäàKÿ~{»D=²ÿè‘}e,ÿð`´o
+
+:CÚÈH_s‚T%[ídzò…÷wogbòÓ×_þìõW>ÜOÂòý=Û>Ü·ý“ƒ/~ö….™¼ÚÒò›
+>þÈβö­9K>]>]ñºµ†tÍ·nöÐÙ¨‹tvä5äÈ5m´þwwÿíÝ]L[ncbòÃýÛ?:°ãÓ×^þ`ßöûž?²{ëû¶}´‡º«º™q
+týžaþsÛ¶mïÙz„©J*üßxåo¾úþ^öO£êòý½$/?9ø"ûú¿ßÞmvôfÆ™°,ƒ¶
+]r£Ë½–ß°
+Ù´.Þ_Ã5dB\B\#톶m=¼óïB+
+¿Ê¾$ ÒŒ-,ƒ´%ïèÙñ17ºäÚrß·!ëo…
+¢Æ£•F6eªTKÌ#2IéÕåÁ'’†Î’;yF;Q® SYk˜˜4ÿñŶ­íÜúþ^²#ÚÀÿùÖÎÏÞxeI9jÉ%Ó–];¼÷è‘ý|ä]ØPOúÕc2SLCº(ê8cÆÓ§Ÿvúw¿ó_ÓO?=yÖ,M–榦œöÜÌ¿àö®½÷-»cöúmOnÞûÜ“;þüˆ…×âØ/ÑMàËTÜŠ™ .…‘n#©Ýœ¥õŠþš Í«3ä†ty˜ÕÏ`<÷×D{Q¸2#=ð+xîð®ÞÛË„åóìÛî7HŸXXŽ(¹¤=Âèò_‡†:z`¢€s±VOšik‘¹fR¨Ç3Ï8ãŒÓNÿ¯ÿ÷Óþë»LRž}Vê‚ Î¿êÒ‹oºæÊ_ü莕÷ÿ6/må“¥¹¯<óØ»»ž{}ì%Ÿ´ý;¾8¼ïoî´êòkÝ¢{eÃƹì>Û–%ˆ;†Wq°M]ž”QÝA2’
+#‡Í@'EbFFt­ Êõp»¡ç¸AúVnþj€Azxò’êž­b¶¸˜ÿøù»0QÀyÄ@OŠÆÀßO"m}Æô駟~ú}÷»ßù/¦*çsö5—_rÇ×ýú§‹Wüá7ùé«þX˜¹õ‰Mû·>ýÉAºà|úúËŸ¼öÒÇ^d— öùý½Û~E:¼{ëk/=cÕ5ײå¿Ô³{ks&¿óÂ8ÄúÐÁÌì–,/oº©wk¾,é³{gN6wÊÅ }ß ¼…g+]–‡ Ò_EU3Q÷kË÷mg¿Ä4º<þþþQï\0ºÀVD\O]f§LÒŒ³Î<“ý~âL‚ÉșӧÏNÑ.ùþüÞtýo~þ£uÝWè^õxQÖ³ï|öñ7^|†)ÆÚÍ$»°°çTί9GFg맯½üÞÞ­#¯x ±xWŽOŸÝÀÇÆAOç"æ×…‘¼A»Q§ªHŸ[©ÏP}n­)ç\r÷/²8С!cºè;¼ÆòƒƒÛIUúƒ“Ÿ¤‡´6 G˜¨óÜÓ§¼[œÒâC&ê„y³üN
+
+ÒW?YšûÒŸÝõìŸ^ßñÌ»;ŸcHÿýÖ.ªôPïîzþ0'ÈJ7øú³gë?ÞÜùþž­ÿ:Àƒ“Ãk~cÑÍô³{g³Û.ºr€#n?üy[6FšÅÀ>]iÒÕ}ö°Cþθš_ãÄ5Ò =ûÀsGv=oWšé{ ƒôñ{ÃÙl¢Îä¥ÈRýçÝ¢£ç8ÏŒ£ê
+%@B„céÜ€ÀGI@À«ºêÔÜdl5wclÓq‘{Ãlíî|3³w§S³ÚI73÷ÿ=ó!ËöÝîþï}çm#:eŠN™þ}û129!þÌ1§wöY—\tÁõW]ñà=·§>öàk/LÊzóŸ‹f¼³xö{KÅGÍòÂlö!Ã\Göá°L 7s½Ç¥ðk¯åbîny~ºøD˨÷ãOoDˆr«7ÎD¹-âîVƒ+Ð_ã~½gRâÑç’D 0÷-·¦$nŸXÇsŽÂHù¨= ½,zYÎô²¼,7â.6)'^3'ŬƊyþnñ–æn,Éÿ´ ­âXX[5üI‘¤®Yñè.æ+½Gæ:öîÕ›ù“Ìu¼ø¼s¯ºôG?¿á§¿»ýO?rÿ‹Þ¿LûçósÞyµ\œÆÅôÎW!_̇\VUžŸézÅ9顱Ç&%DBV¦ûaU’›‘OQ‰ð§¼‡UxÑ•ƒ%õ
+ÔcTˆò æF˜š´Jb…—S´i }´E3ás ”žÚåF+æ¾ï?(\4ïTÞÄ2Ëiñ!ê™n·xè Kø–XXm¹‚þ$ó E|røˆ¡¼MÆ­xt<0Ðí³þþ÷μò’ÞvãµÜýëñüáʼnOýï¥g³ßüç¼Ì·x¶úÛ*®Z0‹}º­»Ü1·ù#5v¸+ç1g2£hNfeÑ…;Û<5þØs˜„%ßíØÂÜ;™ïzÄQ¡îÞ'qkJò.ïiÕžç›
+#U¥Ö€töuyûÐæ9˜{ÉgQΛ¹rþLœ…æ‚€o™¢ž ]†Qÿ´ší‹¼ýÅÂÒi¹þdÞôÿžš”4°_ÿ`^{tB¸ λ庫øͯS{ð•çRßù×óÌud?Y4ë]æ.2ﱞZÇš®cxüÆú×òÂ¥Nºˆ&…Š”ÛS1ˆKš2ígÿ”¤ÃÏ&W0¯’ÏùáÊ’¶>9,ô)FvÔ^–?=øÎÜ¿‹rVΛYÈ7µpù}Ë€ƒÊþþåÙÁnqwˆúæyḎ„o‰…ÕÂ%tÄýÉy™oýüúk~uÓõO=ü‡¼O¾ûÊÿå¼÷:û&s™0™×.âÆxž¢Ð‘±t®¿Ö±¸MœÆú‚“þJï9oP'i`pPaÆš[íˆ;XQ»ÜÂÈÔx÷Lù½“¿û«x yˆ’ýÊ‹$kzŒYˆFjNíéKò˜¿—.ÜÈLöaÎ\>>Ç’—?…ǦÔnˆA—îÙâ¹›Šó0D +,‹‰ˆ©iý9n?‹›&X^˜Í¶Šl1×q™˜îÈ~«¸fŸu$¼ÇZ‹{¶¢ã0EcOw]ˆ%?uNÌèÃà ¬6]!ÏÛ//Œ<ìoÓndJÜŽ§“j>±^¸‘QHÍéKs§SÞkÍ]½`¶ûñ.âa3%¡fn:?C QwC—ð-±°š½6,ñ­˜7#púU¦ë: QŠÃ^ëîÅœÞÒܬH} ÊŠ8+güˆŠÔøS’àObµÅJñÇ!]Ò]ÛÝI’Þ¤­< ò„ ABóJ‹ßzk©8v§„£L7²±¢pFË›wêv/ƮԢ^ȇ¨ûC—õÌ´Df «Æb{±UógŠ™`é¡Ê’Ù{¬¶|él[š—¹*'G|=©Céž•“·{’ÿ@ºÈûXZ®`7‘m^Nõ—ì27r[Jâ® É_{…>š¼0s~@-D¬²Zeqñìò¼Œ2fŒòü•¼Ùsþ¬Ö³)¡9qžªËÏZ9oÆÚEsÜIDu Q¼ÇŠìÚTœÏ¶`îÄžˆÕ=¶Pø<!2‡í^ÌœIëš{õp“ýµ—'Ñ•ƒþ2xüÀÔ¤£b˜€¿X7%nûä‘Ÿ?Ø3ôqô÷×
+˜V®²')”Î'˜ñ¯s²jø
+añ÷z“·yãø •SÞXa_îÄ{÷©àùëɉÜÿËö ìww=3²Ž'ÊK’Ú@2¸E¨užEiAb)Š*k HokËê^²—áž-.†¨çn.Áu,¹–ÿ¤›¢¹l/¦™'ÉÛÖ±-çâ”Åù°RqVsü]9XQ¿x+MЇ sÈÅÄȸÝÞ¡ÁLJ粃ƒÇP…ßò³¼ÜÒ^.U›w2jHÄ
+Q¾eUGO°[ +‚ëÞ¾Ã4¢Ÿ'Y*¦•ù2JgN«ñAÆ림¹ÿ°w2\Ê(^þš]ùÔñ}“ÝøäÖÔ¸mÞø“ã·>9,øÔðæš,ø@užXìM þOñfGfç¦Ood–%8 ½-+-ëò-ý%—þÐ%ï÷K.?­Þ3ŽY—Xá]îå–^°M îrÒNË´ £&›ÈNnó&BÊ;Ê/€Lñ—Gîð&|ó ?J›}¿"Eœ_ãMâ=ÚÞs‚OŠÛ_7hFíéÌ »=๙UÒƒ>^D}Ë gg¾e°£CÔ±Zi},šn‚ÏaÄ}¿°¯Õ g³_—æ ¡»ù¸í·Û¼¼^n§WíÁAX /w¤OjÕ´ŸƒókDCVÜoÂ×ÞQն㸠ý5@sêΖ8+<t@z¤Â•!¾eµ’KözxZܶ¸/8èU—X-\Ÿ”óöí5‹fëÔ¾]sù2–ds±ç¥GäÃG#¸ŸðÕSC¶!å­ñr@ôú+!wOLÜ79ÑmÂrµÓ~N¯þ\k#ˆ.jwt–ç¥çø#–«Î^9o&ï
+ÏÍhãÆðúÝËôÐÌø²‚ì•ógº=ß2òž –Z‹{’¥l¥eÓMˆ3™înKr§GäÓF+ݸÞÀÙ‹¤Ù
+F¸{?¶¦"…‰âÇ NH8ø\\ÕÃàŸóƒm
+1 }ypÜŒ¼=­Û·ôQÏãCÔWÎ÷‡.1D]ãåž™¸fÑœeùYÅZ—JÖX«æÏ*ÉË(ËçÎ$FM†™Àã¶ÔÄ#Ï&WDÜ_ªkm ~›§NMb>ä6Ѹ]!j_wŒ½ýï§UÝÖ,ÂgÇ Õ©Yc¹Ô÷^i^÷ó¸oYžŸÅܳófD|ÖPƒ«ªUÜ¢^èºäÝâÁŽD/•]þ1øÚ7ÝÔ\¾ôÕ f3a–ºj}"R:“å?{ÑKˆ®‰–éÆ$wOJ<ú\s&>s#yadˆÓÈ}È›Ñ 2-~ºÆÿ–䧕Š*WÍŸµ¾(g™;ïNz#^R½£§T ºdæØ=[|SqÍ!êXò/ÿéÛøVf»UµÌÚnùÒ—¹U(ùþ­†™´üª~òøYÌKáxð'#»¼þ[àú»&òªH~̺7Ñ#¹sR|èá5îäž$ÜH
+/“`FzcV ÷ryA6s?,šËœ“Eè¾¥Ì+xfâªù3K¢¦é&t±}\©t äøœÉÖCx#t[Š[‰‡A”r#_°{R¢h$?J;i›7nû„ÄÅ!ÙBÚH
++¸>åíÛyî¦Xg,\Ë?j2£&ÛwtÌîI ÛRã÷Mq°ˆûWQ²Búkö’»ô¢ö`[jâ–v/F|zâ¡;x{+
+ñÌ™'¹{?q÷Dqx s2yF;¾ÖÍÀàq
+æbùÒËsÒÝŠJæn­^0»ªyG»ð-ÓJÅu·£'8è2$Žy0¼‹9ϫо]Ïíiyù/qI¤Nˆ”6A|à!ݒƒ“þã£y
+#™y`JÒaq¾¹ ™Ä‡FNúÉãg…^<·¿&Bw
+ÏkW¤$PÇ…‚
+ §sÅMˆg¬]4G³éYµ‡¨—‹A—Í%—yKjwô´–oùqqskùéíK6´xÍ»D>L’áDm}vs´öLJä5„‘ö[îCn´iy6Y¸‘IîÄÈããêxû8
+o¼,gå}Z>"ÒŸÔv #+ØJåžäo|Í÷áuk#
+#
+æObÔ¤ò¥ÆóCdÚÄÜ–Zu ⮉|êøþ)I¼0Òßb¿Û;4t‡ÂsÙYWÃ
+GYb…e•åòÐwi^VÕSÔExn[SZ÷¬¯{j¶ß“Ü9‘Ÿ_ÃVEJÜöT^¹%%ùË¿&ÔxaÙ7£0
+ô×
+³™o)æXf Ì«ÎåKÏ™ÁÇ„·Ë{Û„„ÞJºΤë4î™”xøÑ£p/wz¾zjˆ;ôÒÏMè¯
+²Ä}O¯ói:À†t÷¤æ(ž¬+Çu#E§öîI‰{'óŒöΉ "P™¸}"õóu艇Þ@s &”
+#Ýþø
+(}‚/L.^Ñ_7
+påþH=àî€ôe"Ûê.eÀ{ )ã¬ê€v‰n,‘9ŠËÅ€M^”ÈóÎÌWœµvÑöR×.âÎÌf_—Õ®odƒ88Æ]¥yénj»,?³Ô—Yœ—Vš7½¤pFQÎû«rrZrQƒŽbU k5ÑÿS´ß
+²‹çM_ê{oUNNaá´&½?ž_T¥˜QŽ
+nAÄL
+b&
+ŽÚ@p  ÓýŸ(z>Ø[ýÉž°GJª°éákàQ‚Zÿ¢ûèÞÑ#8>Ôu_øŠJêÀ¢Ÿ‚˜ ÅøžÓ>©°øܨù@fïóþŽ.m16]Ò‚ ÿaèwóß
+?aÏÞQãP2¹=`·²Ü¸à¦µ‹–+
+NŠaÆSÛ÷Ç©_OGåƒÑbÞ<¤Ý‹áÏrסtšá¢žÀ~­ó¨qÏ®¨tµf[tû°(ù0ö3Ì%“õ`SçVx”Q ߯ MÉ×<žñ™ÿ©°lña<+JÜI0­MäÆ7ˆ{Ï…à¢Ãô»‹Ãn˜˜½^Ø5DZý (öëÏ¢EnýòÚHn\p«1å<
+ ì×H§‹ŸÈÙ|P<
+LjUÉ^‡n‰Ž.I’ß:5\ubӢ⺂ †'†ÿ§c¿³Êüêþ¨±ýšSó¹x!*ÜI³ªÕŠJê€ýKÏEÅ…žÌ…##/úý´OÜGÀª£d}çò(ð{ “œ¾± ­ŽëýRFÁýÚ+}{¥»aqìº6›. ¿ÛÃûK>m¥
+å“nßú_Ú(Ç0=îGjìyOf¯ÚÏï»eÛõûQ}ZóÆ®È5­[ÃU'6ýd,§1¦[8Óõôß½»~—S­ýZÍGbß´×{ä¯ßÛörãf‹ú@pzâ/ô7žyçëŽ ‘U6ì@UÒS÷M=», ¹ñf¸W §‡1ð¢{^)?áÞj«1Áö#Oèn޸ܜˆÈM\ßñRê„aú ýÛ]øÐK÷Š›ìœlÃV ‹~ ùãà!ž‰­_¡\6=ñs8]ðï×H»¤;_/«÷×j¬ÔüCŽæ¿ÒîÕÖî¿9ýêLÝ=ˆ¨À0c¸PŒžI·þcÅÞãüÞ6b¿Vöãwè.·Nÿm³®:±èŠÁœÒrÙ¤ïY·¾°ä°+‘ubÓ¯õŽŸyÈ€9‘•\VG­/²Ö÷k¾ÿ›¿Íßå×M“œÈ*úš¡³}3IÿmYÃU÷EvèdÍv]qCþŒ‘¿x탯øÍ´íjÅÇM|(ý±ÎŸ¼&SÔ¶5\ubÓã÷Boªá߯‘NC®{aéÖ£üF6y¿VëAXÙW_½&»I¹ñë¼w¶p
+aø‘=“¯š´`¿¶Õ.ôo:ïúô{k-Ø;S[—LÖƒE?N€à” ؘÝqìMs*Üûg‡å1rè‘‘˜H¿ÁV‚™íëvD0P‹Îë
+ÁIد%ýò…ÜOÅ«jÌn1•Ô×EWûÆ®Ûhex.TËqlú/­#Sêد‘žWMž÷ù1~×*[©›>®«ycr»S"¹‰ÐÔÃh†“ÓmÌî2ø‡ãówá7¬¡Bÿ¦cÑ-ºv‹°wõ—ÈÕpÕ‰M¿»
+¥„þ¶É—ý9{»{³êjÌn1©©‡Ãäö”á,w-,ºu,'Á!ã$ñ†§3>vïS}Ù-Å¡•÷êiÞ<$öuéäÆW6
+ç~"³ÜDC}®Mñï×Úõ=ãî·>:È“²Íêm-è¡Û}goçŠM2•ÔûLý»~~…¬³Ÿ׿W»ƒ´Úh¿V›þYC¹ý⹊JêÀ¦ô!vµÁÆìÞãî­øqñ[+—݈»þÕ÷4Ó{7¿<$½Üø¥?rf—^:‚û5cÌ=o,Û!.{kæ²Ä¢34+Wg×wüq)Ón5±è¦$í¶Îá?Êìÿ«WWíà ¶ìתãPë>½n9“[ŠœYîÚXtqoX¸VÁ0Ü‘~cnþ[ù!2÷ßÈbÑÏFjeÞLû¼*rãÍpoy ¸0lÌîùý_¿°è {©#©CßÖ*Hf’Žo+#7QØ•¢Õõ4ÁC¡Hò]ÿ^¸U\ã¶Lf7€C+µªå2I§·¹ÕP›~{›N7 ¢ø÷kÄ|Ëß—~΃þ|¿&‰Ô6Ý SòÍCFú„ÑP‹n?W¯ t„0cÄUì1üêg—îs‡ H°_«^H=døb)ÆÞ5‹®
+Áµ„`.»ûé×NÌ÷ï×Z:!²Up¨s¡6æÍ0ÉYÅÊÉMt×·×æ&´5UÙ§ýò™œ¯Ü+ÑÛÉ°éBmZ˜Ü.jóƒ¹Ã{6^ÒÈÉhCü!B^÷Œo3w[4d¼õ±ècÚÈÍ ã¾P ¨¤؃r.·¡Í0ÌqÉ:ô¿Ì;ïËCü:¶vcv‹qh….{u&·Ûö¨“¨ŽM^¬É}h ÿÄ‘.q—<1g§(KxáHc¨¤ÙíôpdØGÝíÇT•÷3>Á”óFÌe›£¯}2ó ÷òE¦Ð¿É0G÷=Ƽ2¹Ý{XMgÒÅ¢ {Â¥lˆ`cvß+¼³Ö‹ÛíD¬Ð¿éXtÓ(-Ì» ^…ŠJê€}ôýËÔâ^´B£ûÅOÎÚ N§·Ô0kA,š®Å-6‰©¸ÜDŽþ )ëÈì8𼇲¾§ø†ãP¨6ƦßÞ ƒã!]_U]nânü [¸Ú’Ùæ¨=0m³ÿZÉW8Òlº©»Ÿ¨Òå]õåƽ/0å¼:ÁýZ¯+Ç?A¡ýZuØ«þ? <4C¹ñ÷P:T#< ýcÏ{ø½eûÅ’:—Ýì•_ þíõ„¥ŠU(ׇcÓôXõïH8ðï×Úõ8ý¾w?Ú#
+GÔÛ¯ÕÀ¡ËÔA{H|™‚%“uÃÞÆD <ŽâDƒÏ¾ó?ëýCÆ+5¸Ã6}Tõ›kxÈÅ«eYÞ Øù]ÄTûž´>HK¼ûã~÷ïrWkŽbAÿúpèѳOv³{óÃmÚX7ŽM÷‹Ò˜IUcöÙ¿}³d¿"—­Ëݵhf'µÍ{ñ?ÙªrQIØtC4vù…2bóß[ø- ÿ!¾‘…mί¶ycNþGµL†bÓÜ(›rî/ô7ú$þüŸk 'RÊ^Ñ–aÑONSú¾²×~×wšY7*>_&Jߘ&lÌîwö­ÿ·ô;÷hfØüTÒéJ{“&1Ÿ¨ÔOn"Hùˆêq¬Æ2nŽ½çå»Ý7¯Ñ~­:ýöv•?E=ĘBu”÷(ýTå[ÓCÆIÜ/^^ð™x×j'³¢»)ü!ê!^ÔTnâD‡³5Ž™°ýšxð:»áÿJ¶ñÓéuܯU‡½½WvZbHL=j¸êĦôÕSpÆ잣¯™¼è€¸êŽ4›»H]¹yHWMJ&ëƱé4íb&ÁÆì˜3o™ìÛé¾S[wÃæǦk:({C=$nÎrîÇ$…ÝÚ÷kÃoœ<Gì×d2Þê°÷ù˜²÷Ó$ :ÕpÕ‰M+oSöó°ÂOÿ«¦~"N;lÛ³#C¿=]Õ ‚IƬVqÊdÓ°éÎsT½C¡ø ý» ÿñÓùÛÅñ¨Ø¯ÕÀ¦¹ÝÕüø4Lò£
+]“¡XtÃH¥'rÙÜ°uý“'flõ¿+í?(ëĦ÷¨y/ÙýûÑŽhÜœÎ<ͨ&ÆìÁ×x³6ºoHÙÆìcÓ¯ÏTRo|Êä¾èß¡>«v²û¥ãg®§gXZ粤’¾­d°„=|÷œ •‘¾|m„Méý‘¾âÍ%¶ÏùÍúì
+å”GÉÚ<“ òñ2^
+{rRª–Ë$#6¡¶(ŠC')• ðñð&ªØ4­½Zæ­Ïb˜7 *½M1óv3‚“@Ulº9A¥d·A:f¼U©¤/+-9ï;D'¢8Ôù…ZæürªRIËûªeÞ†îBt¨ŠEÿ¡’yc ˜  *6Ý÷c•¢“é¼
+Ñ *-U*Zâ!÷Z0o@QØ“ût¤%Ô ♃9
+@Ulº?^%w2†\þ ÌP‡úTj `¯ô_ؽUa–â
+ÉíÞN«@2
+SI‹Ô‰–˜dÀJ˜7 .µQǼäzäºÂ0w2^ófO.äÆ¡3Õq' rÁQ¸“@]˜±¸Q!¹‘7aÞ€Â8ôëAÊlß ’„#q€ÊØôyuÜI™ÌG?
+#j¹Tq'=dÜwˆN…©¤ùíT‰–Äøro@aØfèieÌ›IâÀ¼…±è–duÌñ¢t¨ŒMs”I¾¤Ç§p'Â8Ôþµ*rcîäý6ÌP›nW&ùfØ"$€Â8ý·2\ƒ„Ê0çìUÌã-”r•±éʪèÍCÎÚóTÆ¢ãUñ&ÙëÝP‡Gb"-¤Æá!#¾Bp¨ŒEçvVžänäºÒØôqUj¹LÒ©r*cÓ/ÏP%Zb«,è ¨ s'Õñ&É,'Ê8Ôú½*æÍ$ßC2
+Î$?Fy Л:”PprËQ¤ß€~°M’„‚óߣÛèóÚäs)cÈ$„K€–È(¸òwz"Ò€ÖÀ’Npìµ¼‡t7Ðéöpéêƒ? tŦÎÑÖX(&VŽt
+ràGÝq¸MYýxnkÚVm\l1£Y²“Š=Ä¢›íãJÕ©½Jƒ´?ûîœ}ß³Ak š¨d¢+½µ+o¨n3LÒë]þo[سhƒ‡*iÁ•íÚrg.¿ý Æ D33VæOI*Žý;C&B‘$ˆJ¸â¾{çÒvE^û‡Îžc‰€hÃaû¸½o~ÏB›Àþv·¯…‰Ñ OzytÛ9•< ÑïÙ½ØÆè„?÷_OMÚlÚ2WÜ…Y”bŽ2ˆF¾›ú"µwÛ¨cš¤Ã­+aâ@”b³}ÜÚ?÷k»s¼Ù6®gjÅQo :±,zâö¶Ó›Ø.ž–a¡`D%µÆm¨7¡8óærŠÜ
+¢ˆJ!·È4|ód\—Ç¿Dn
+h{šS#-®:á±ÊWÏ>Šì
+mÞü@p@IZy§jÖÃ÷twÅpú‚‰îš˜$æ¯P ‹Îy#\p(…E7&¨·yóÁµ°éÑŸ*jÝ8P ‡Ò?)0Ž«~LbBp@‡¦©+ Â÷2Å!‹@Z6DaoR`’Î3!8 
+:´ÓÅÀyÈÇ‘
+Ï 2IÜ!$€ìØ´âò‘ÃöíÉ#&ewpìƒâO¨-ÒcÓ£Å< w÷N˜ÞT5piC€ü° Ü+ññCöéÕ¹S¬ºE”&¹ö(ôäÇ¢¹‰ñ#öíÕµs‡e œAÞ„Ü€Øtý¸øQCû‹ˆ‰GQg’ÄÏPª À¦ûnOL6 o÷®]b=Šv xÈÃH¾plš’˜<lp¿ݺtfzSÑÀ¤GÌP‹¾•œ8r耞ݺvn¯¦‹!—}‡d
+fj§ 8 tÅqäÒ›Iú~ ótÅ¡»ÆÊäOäg¨-ÚâÐ2鹓ùp'¶Øtc¢Då\9µ%@_lúÁ@‰ôf’©p'¾Ø´h€<z3HÏ•˜ôÅ¢éåÉw{ÈmÇaÞ€¾XôuC½±×ñÌЋþ×”ForÆ—ˆ–
+úí‘Ö›IÆa ˆ
+lzl\¤õæ!‡Ü@T`Ó£çGXo´ÉnØtÏ·ãÄ_£D6Ý×5²z3Hû4”*ƒèÀ¦ßÄGv|‰‡|ÿ̈º $ÇöŽF´D ̲¤ÇDУ4Iß¡75ð
+Ê‘œA®Fm ˆ"ØÃþw)Á1w2rѳ/ã#%8ƒ G©2ˆ.lê<¡¦“<äˆ2,zäçœA:•¢¶DÝ#1Ú^próQ˜7uTÒçG` g×P[¢‹n>«ÍóÞ’´Ñ0ÁBbÚVo&ù䢋·qe—IzBo :qlºp@›
+ÎC¾1x Za‚ËîІ‚3yž—“•°gÿ¿mXJi’[àN‚è…Ùš¶]e—Aî‚; ¢fmžh+Á1w2æ D56µm£Ê.“œƒReåX”ÞÜ6‚ó¨ wD7Ý][x”²¥Ê ê±è¾‹Û +C~‰N
+MLò’o
+
+
+‡€–ÀWp^cLû·`ß
+}MbÀFÃFð‚|Â7÷vón%PÆð‚<«÷Ñܨ¯]±98Âspòñ0߆“ȘÜüá1y2ǧä$ãಾEÂS\ä_£7ÚÞ°—½±zw7$ÀÉ#é¾»7@;šcâ7Ž“„ =·‚œÜæ»wÃ@
+ç»%?ÀÉ}sYÈ–`ôJËO#ÿ6%LIûÛ7¶­\@wÕ¤üÈ ]K§O°ùu|p†ŽB9±B ®“ cƒ×€”“ p˜\<¾ëËh<¾<Þ˜o]ÙôÀ§ð¬¨£ÅN¾{KÑXiùc4 pûm–t‘dæmz“ƒ6·|í}GÇœ!&pÒÎÎh£g¨lBÊ1ÀüÈÐáß4Æ\HõÌómú>ËóU §F±œÈp‘¯_Á–{ë¡%Ì÷žŠy ƒ½Èœ‰ ˜œl‰õÿâ´“C.(Yõ²PêQ,|9Ìw£ø‡`b¶ÃÏÿ¢@m„­16æt=‚9–JŸˆùò|öÜppÎ_
+ ¨c›Ðõt,§¬ì+ð
+_l}â8rrÂ'¿_Áj-€AŠU‡‚oiƒf~´óštØn=Û˜R¸¢û‘á]†€,Ä
+GUV!prׂ€˜u‘Œ/Åcp0?rö讵±`2ïïz³+y,*…³‹|WÉm%` ö„H”ÐØNì´~a­!dl4L)\9ø,˜ÖŒœ[¸ÈƒêÀx7 8¸µgŸ1!˜¥ÀO¼tçÊ9£ªz¸Ká?ÞfŸ ÒÙ
+Ÿ¼áµoHËù5 ¿ Xðb=-Ä%ß=þâæÊÙô}†hÈ6-ËeßüP—s¡XΨ>{ 0…·1rÃlB³7÷VÚŸïø±ùBúC:d›X
+?¿àºgO‚îB±œ—P涋ÅmL=C†)
+ÉàÜëŽ~КÂõVQ¢GKá—f þytŠå¼ÁE¾¯TámTd¶E8ëÁY¹?ìß^±˜­­´ƒËÍMºöÕ“$šÖì8ùqJ ½\¥02&ÌVQG_»Ó<˜26O‹G„¥Ý´‡‰åø¥ÀÉoÊX &÷9&Lz„<ôäõ9p«(dl^Káý†çÀ„/År3á"]«0^ò2ì§ü–àÜ‹Ø|°%›°Ö èÊõ?~îЛÈäÎN-¼"Å–Οƒcò#®ÿÇ¢º
+G&Ç€“Òx47¡L:0{ƒ[iŸxãgy‹èªrlœKás4?yx9År4.òÛ|þ“
+Ù„ 3­9¼xóžS”Üp"ˆÓ'TÓnáë·©  ãj¿8f)äïŸÞ°l‚(‘ …µD
+o£H°°û}+ÁÁüÈéOnS€uÇÑR?âÃ]
+¿u_p–Â]äkW ËÜ0, k&½À3%í¯ß¼§n}”)îRøí ¾R¸‹< Pì‘`‹^÷ÊÁ¹W];þìÆ¢ùô)¤Bk ܥð·ºKáœ(à¡ oÂSMv‡&?òÕŽÞ4:dCé‘ €)…_nº‘.…Ç+ª8y²ž•]gBŠåóÐàpz«¨¡C¿mŒºCù‘ –ÂççÜü]
+½ÉQš*¤ÂÛ(Ô-½à‰½ÁÉZ_ïÛ²rh2¶ Ærá†û>
+ŸWÏ´ÜE›>!pr»@ͺ«Ë¿<‡ƒs¯«uäÑÞ,°o=zI;¨a¤»¤ö¿÷ÑÒç´fùøE57¸7ÕtÏ1f§£ƒ÷6ŃGÑ«l¡
+²5Ä´0¥ðâÛ9)…»ƒ0×ðÙɯˆÃÃC§øè•7vlÝv]gOYVvbtô•óæOx¡T$A„Yw\w‹àw)ü×L)Üßå¦FmlxÂG'O÷ù?øè¯>r×Õ×®1®H^°èÒ‹/¹P6á–dç…Éd2©T\ ž¢’6Â#Ü¥ð•Ûßò*”#FÀÆI]çúôõ½/îØùà¦?ªª³ÄÇ/œú0i˜mläÙž3R
+¿óMÚ¦ñr#ÆårM7AåÔ±cïî}å÷m߸᧫›Vê2’ÌŸò’ (…&C†@°S
+_Zv׿€ÝàîXnt€8<]¢ã³÷>xö‘G~~݆Õåå9ééË_uÁø!¢Ôd~Z‰@º.]Zóèazÿ1ƒM †‡8ñýñ/¾xs×3÷þìçݵ ¹1qK]17|ö„s…‰|€ˆ@
+¿ÜúØG#¡ØÐñã_îÿðo/½òä–-m5YQ³Âg…M±£„ ÙáÌÒ£KÛïfç–ÿ½}]¿Õ\”{Õ’‹§>X"¥ LŠÆˆ„0éùyÿÎ0‰ñpsDB»9z|(1/¾ï b‚ÝÀ”JS_›Ñê´Êë‹äJCqZ3õï•V‡Ó6 /“+›Õ†§±³ÕÙÙßg¸F¡ª/-©)6*tŠ˜ë5¶fMsRs¬"Kc(NÒ4S_ >U$P‡&)Ô+mÖE <£‚úLQ>ÐÙÞÙGý±ªÕÚcƒÇeQÿÉk¦¹\~'ü]¡6Tg¤m­ým6ðÅÔ¼¾^Wc5g*còÓbµE ©¦Ä†x‡®:)µ>n %Ó¶ZפmЬ7g袲ìYí¥ÉÙzGíº¨sWö`êº.£#¥-·¤É˜¸ÒîŒ7+­¹F‹¾kmj}|¶ÙØÖ›™#W‚?Ôªkó´ñŽ¬øî¦õFCAQ]÷rCF˺öøüÚ¼ôx}A´Ý`©ëlN6ªŒ}[—M“bˆ[fLQe•©5E«•»®&;Ųܬ.]Ñ—§±9ÛŒš¢æMñÙµm%re|vç`-ø½ÃÔ¢j-È2›œêRé樾Ü
+C—2·Ül27kÔʲ¾B]_ÌzuEkFV\L6Ú QçêÒÁwµæ¸Ú³>Ûj0˜#ŒÝ½Ë´5EZúÌr%}n­³Ä\bj©¶¤ç÷è{Rè¿éuæD§9¯ÄÞ3rx üáüîG^‚r0&ϤꯣþfΡ»@Ý—Ñ®Óh úó ÝÝr¥fENMݘS€î¶T4›¢Ó
+ÜmI±ªûT:µ¾V©QíÊÄ
+}Vow•ºÃ¶^5Ý”è{c£¨sŸ"ÓfjéÕ™ZôÊL}w­Qc¨ê‰0›2c;Õý‘ÑÓ§>¿R‘lŽ±[’)qW®6ýš´–Žµz]½®ÕPš¸"™’~Œ½Ë`´Ûûsò+•[EbZBDQníèSMºCçÚÒ(½Î‘X™ßœ‘:Ø[—š›dë2ô™cÖ£Ûsb“mù–֖ ߥ,Ïým³¡j0Q•o±™Ó’×X3@§ggT­ïµ*ò+óµéö²± ªkk§ÑæêÊ›u9…ú¬jg¤¡¬½Ð8^négÙ2R'ö ¼•§)¥UUÒŸÑ•nHoëÉÉoí.šp¸¨ù4¾$G£MªÎ ¿FŸh2§s\^m–“ê1êÈe†êÌ^ý¸²#<è·ÀtN£ÚZ–`ŽTi¦ÕmYP‰G> t ~ÔTP:ùÛ-J éÔ“Á‘ ï+¨\e¨6Z“¨êUÀ®*“–ëSSè»ÑuÔ·víÑÑË)«‹ª6Z,EI¦„þ²}v^ª’Ò±©/Ðœ˜ß•C4îöÆ0åw»#¨d«Ì*­¹]×Ñ¢n•+ Ú¢We»O1éó‚6U’eŠFÆê³V—ôkµ]UùÝ¥+Õ“ïfì!rå؃&Ü™sÍš”5«ÖGPŸF[ÀSRBŒY¯.µÄ¤kìYý-I­mÙe)«UöšÝí&¥92ͨn.6µ¨W-3”[Z’cu ž¶ÙZßm¬kðæ´IF[\e¡£'¦y’‚P'•+©ÓRBÔÕÙÚõé©å…†²Žîh½ &+Ù¸¬^Ÿ­Z–Ò¥±5e)ÊÆv}JS¶T£íÈ­œôµÉçv÷ƒ9Q®ÌNhlêN‹X»Æ©¯]Ö¸² 3R›a6%ÙSŒöJ‡][i[žM9ef×úòBJwìÙùÅ•Jà
+š´•Ö"³±'9ÂhÏ,¬ÿd¨Ó÷ØRóL­QZJ“Ó”jcIAǪ|»Ù˜Ö˜¬ÑÚ£íc€¹IiÕ)-¦¬2êIUV:þ<­£ÇQ÷ÝA©}Ue—!}Õú&êk ¶‘‡#5` ” ­ÑÔ\S<¹GãÔ¦iv½U­­)_Õe´e¯¡L³³dÀÛ0S舰FŒ¹TsVS¼®sÍŠ¶üeži¬ƒÏ†5mQúVŠnPêºNc5ýl
+p*—àEú©€wmñõòlõعU€{¹
+xÐTÀ¯ãs4>…
+ððLæL<m‹*àñ9¯|yd.TÀ«¶ø¬,õŸ£ñàu<Ʋ
+xß_T€Íãs4¯âUrˆ¹°§>ö˜—*Àº\øƒÿq¬3¶…ð§Ç<WnäÂwv”Kð¬-þª€ß=æ‘
+p(¾³£©€mñCØé±™T€k¹ðe_¼m‹o*ÀbC"¾³£¬ª€OmñZØU rá7;Ê–
+øÞcÞ¨
+p'—HÞÇc<W«ýR6zlfàX.‘¼Çx®Vûª¬õØ9U r‰ä}<ÆsµÚ`·Ç¦S
+½\Êòår¥²ÂÚn«°vöØäíël
+k__¿Óê´­£>Q´ØÎþ›ÂÑÑ5ø õ÷áJ¥©Ü,ÿÕ(óI endstream endobj 15 0 obj [/ICCBased 19 0 R] endobj 6 0 obj [5 0 R] endobj 32 0 obj <</CreationDate(D:20160615142312-04'00')/Creator(Adobe Illustrator CC 2015 \(Macintosh\))/ModDate(D:20160615142312-04'00')/Producer(Adobe PDF library 15.00)/Title(metamask_icon)>> endobj xref 0 33 0000000000 65535 f
+0000000016 00000 n
+0000000144 00000 n
+0000047649 00000 n
+0000000000 00000 f
+0000163121 00000 n
+0000593503 00000 n
+0000047700 00000 n
+0000048109 00000 n
+0000048283 00000 n
+0000163420 00000 n
+0000139682 00000 n
+0000163307 00000 n
+0000049181 00000 n
+0000048344 00000 n
+0000593468 00000 n
+0000048620 00000 n
+0000048668 00000 n
+0000139717 00000 n
+0000160473 00000 n
+0000163191 00000 n
+0000163222 00000 n
+0000163494 00000 n
+0000163800 00000 n
+0000165099 00000 n
+0000187851 00000 n
+0000253439 00000 n
+0000319027 00000 n
+0000384615 00000 n
+0000450203 00000 n
+0000515791 00000 n
+0000581379 00000 n
+0000593526 00000 n
+trailer <</Size 33/Root 1 0 R/Info 32 0 R/ID[<858D18969ABF4CF88593CFB9A20C1759><B33F39DA517C42B9A50D10EC91C85574>]>> startxref 593722 %%EOF \ No newline at end of file
diff --git a/old-ui/design/chromeStorePics/promo1400560.png b/old-ui/design/chromeStorePics/promo1400560.png
new file mode 100644
index 000000000..d3637ecc8
--- /dev/null
+++ b/old-ui/design/chromeStorePics/promo1400560.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/promo440280.png b/old-ui/design/chromeStorePics/promo440280.png
new file mode 100644
index 000000000..c1f92b1c0
--- /dev/null
+++ b/old-ui/design/chromeStorePics/promo440280.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/promo920680.png b/old-ui/design/chromeStorePics/promo920680.png
new file mode 100644
index 000000000..726bd810a
--- /dev/null
+++ b/old-ui/design/chromeStorePics/promo920680.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/screen_dao_accounts.png b/old-ui/design/chromeStorePics/screen_dao_accounts.png
new file mode 100644
index 000000000..1a2e8052c
--- /dev/null
+++ b/old-ui/design/chromeStorePics/screen_dao_accounts.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/screen_dao_locked.png b/old-ui/design/chromeStorePics/screen_dao_locked.png
new file mode 100644
index 000000000..6592c17e4
--- /dev/null
+++ b/old-ui/design/chromeStorePics/screen_dao_locked.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/screen_dao_notification.png b/old-ui/design/chromeStorePics/screen_dao_notification.png
new file mode 100644
index 000000000..baeb2ec39
--- /dev/null
+++ b/old-ui/design/chromeStorePics/screen_dao_notification.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/screen_wei_account.png b/old-ui/design/chromeStorePics/screen_wei_account.png
new file mode 100644
index 000000000..23301e4bf
--- /dev/null
+++ b/old-ui/design/chromeStorePics/screen_wei_account.png
Binary files differ
diff --git a/old-ui/design/chromeStorePics/screen_wei_notification.png b/old-ui/design/chromeStorePics/screen_wei_notification.png
new file mode 100644
index 000000000..7a763e5df
--- /dev/null
+++ b/old-ui/design/chromeStorePics/screen_wei_notification.png
Binary files differ
diff --git a/old-ui/design/metamask-logo-eyes.png b/old-ui/design/metamask-logo-eyes.png
new file mode 100644
index 000000000..c29331b28
--- /dev/null
+++ b/old-ui/design/metamask-logo-eyes.png
Binary files differ
diff --git a/old-ui/design/wireframes/1st_time_use.png b/old-ui/design/wireframes/1st_time_use.png
new file mode 100644
index 000000000..c18ced5e2
--- /dev/null
+++ b/old-ui/design/wireframes/1st_time_use.png
Binary files differ
diff --git a/old-ui/design/wireframes/metamask_wfs_jan_13.pdf b/old-ui/design/wireframes/metamask_wfs_jan_13.pdf
new file mode 100644
index 000000000..c77c9274a
--- /dev/null
+++ b/old-ui/design/wireframes/metamask_wfs_jan_13.pdf
Binary files differ
diff --git a/old-ui/design/wireframes/metamask_wfs_jan_13.png b/old-ui/design/wireframes/metamask_wfs_jan_13.png
new file mode 100644
index 000000000..d71d7bdb4
--- /dev/null
+++ b/old-ui/design/wireframes/metamask_wfs_jan_13.png
Binary files differ
diff --git a/old-ui/design/wireframes/metamask_wfs_jan_18.pdf b/old-ui/design/wireframes/metamask_wfs_jan_18.pdf
new file mode 100644
index 000000000..592ba8532
--- /dev/null
+++ b/old-ui/design/wireframes/metamask_wfs_jan_18.pdf
Binary files differ
diff --git a/old-ui/example.js b/old-ui/example.js
new file mode 100644
index 000000000..4627c0e9c
--- /dev/null
+++ b/old-ui/example.js
@@ -0,0 +1,123 @@
+const injectCss = require('inject-css')
+const MetaMaskUi = require('./index.js')
+const MetaMaskUiCss = require('./css.js')
+const EventEmitter = require('events').EventEmitter
+
+// account management
+
+var identities = {
+ '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111': {
+ name: 'Walrus',
+ img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
+ address: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
+ balance: 220,
+ txCount: 4,
+ },
+ '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222': {
+ name: 'Tardus',
+ img: 'QmQYaRdrf2EhRhJWaHnts8Meu1mZiXrNib5W1P6cYmXWRL',
+ address: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
+ balance: 10.005,
+ txCount: 16,
+ },
+ '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333': {
+ name: 'Gambler',
+ img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
+ address: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333',
+ balance: 0.000001,
+ txCount: 1,
+ },
+}
+
+var unapprovedTxs = {}
+addUnconfTx({
+ from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
+ to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
+ value: '0x123',
+})
+addUnconfTx({
+ from: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
+ to: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333',
+ value: '0x0000',
+ data: '0x000462427bcc9133bb46e88bcbe39cd7ef0e7000',
+})
+
+function addUnconfTx (txParams) {
+ var time = (new Date()).getTime()
+ var id = createRandomId()
+ unapprovedTxs[id] = {
+ id: id,
+ txParams: txParams,
+ time: time,
+ }
+}
+
+var isUnlocked = false
+var selectedAccount = null
+
+function getState () {
+ return {
+ isUnlocked: isUnlocked,
+ identities: isUnlocked ? identities : {},
+ unapprovedTxs: isUnlocked ? unapprovedTxs : {},
+ selectedAccount: selectedAccount,
+ }
+}
+
+var accountManager = new EventEmitter()
+
+accountManager.getState = function (cb) {
+ cb(null, getState())
+}
+
+accountManager.setLocked = function () {
+ isUnlocked = false
+ this._didUpdate()
+}
+
+accountManager.submitPassword = function (password, cb) {
+ if (password === 'test') {
+ isUnlocked = true
+ cb(null, getState())
+ this._didUpdate()
+ } else {
+ cb(new Error('Bad password -- try "test"'))
+ }
+}
+
+accountManager.setSelectedAccount = function (address, cb) {
+ selectedAccount = address
+ cb(null, getState())
+ this._didUpdate()
+}
+
+accountManager.signTransaction = function (txParams, cb) {
+ alert('signing tx....')
+}
+
+accountManager._didUpdate = function () {
+ this.emit('update', getState())
+}
+
+// start app
+
+var container = document.getElementById('app-content')
+
+var css = MetaMaskUiCss()
+injectCss(css)
+
+MetaMaskUi({
+ container: container,
+ accountManager: accountManager,
+})
+
+// util
+
+function createRandomId () {
+ // 13 time digits
+ var datePart = new Date().getTime() * Math.pow(10, 3)
+ // 3 random digits
+ var extraPart = Math.floor(Math.random() * Math.pow(10, 3))
+ // 16 digits
+ return datePart + extraPart
+}
diff --git a/old-ui/lib/contract-namer.js b/old-ui/lib/contract-namer.js
new file mode 100644
index 000000000..f05e770cc
--- /dev/null
+++ b/old-ui/lib/contract-namer.js
@@ -0,0 +1,33 @@
+/* CONTRACT NAMER
+ *
+ * Takes an address,
+ * Returns a nicname if we have one stored,
+ * otherwise returns null.
+ */
+
+const contractMap = require('eth-contract-metadata')
+const ethUtil = require('ethereumjs-util')
+
+module.exports = function (addr, identities = {}) {
+ const checksummed = ethUtil.toChecksumAddress(addr)
+ if (contractMap[checksummed] && contractMap[checksummed].name) {
+ return contractMap[checksummed].name
+ }
+
+ const address = addr.toLowerCase()
+ const ids = hashFromIdentities(identities)
+ return addrFromHash(address, ids)
+}
+
+function hashFromIdentities (identities) {
+ const result = {}
+ for (const key in identities) {
+ result[key] = identities[key].name
+ }
+ return result
+}
+
+function addrFromHash (addr, hash) {
+ const address = addr.toLowerCase()
+ return hash[address] || null
+}
diff --git a/old-ui/lib/etherscan-prefix-for-network.js b/old-ui/lib/etherscan-prefix-for-network.js
new file mode 100644
index 000000000..2c1904f1c
--- /dev/null
+++ b/old-ui/lib/etherscan-prefix-for-network.js
@@ -0,0 +1,21 @@
+module.exports = function (network) {
+ const net = parseInt(network)
+ let prefix
+ switch (net) {
+ case 1: // main net
+ prefix = ''
+ break
+ case 3: // ropsten test net
+ prefix = 'ropsten.'
+ break
+ case 4: // rinkeby test net
+ prefix = 'rinkeby.'
+ break
+ case 42: // kovan test net
+ prefix = 'kovan.'
+ break
+ default:
+ prefix = ''
+ }
+ return prefix
+}
diff --git a/old-ui/lib/icon-factory.js b/old-ui/lib/icon-factory.js
new file mode 100644
index 000000000..27a74de66
--- /dev/null
+++ b/old-ui/lib/icon-factory.js
@@ -0,0 +1,65 @@
+var iconFactory
+const isValidAddress = require('ethereumjs-util').isValidAddress
+const toChecksumAddress = require('ethereumjs-util').toChecksumAddress
+const contractMap = require('eth-contract-metadata')
+
+module.exports = function (jazzicon) {
+ if (!iconFactory) {
+ iconFactory = new IconFactory(jazzicon)
+ }
+ return iconFactory
+}
+
+function IconFactory (jazzicon) {
+ this.jazzicon = jazzicon
+ this.cache = {}
+}
+
+IconFactory.prototype.iconForAddress = function (address, diameter) {
+ const addr = toChecksumAddress(address)
+ if (iconExistsFor(addr)) {
+ return imageElFor(addr)
+ }
+
+ return this.generateIdenticonSvg(address, diameter)
+}
+
+// returns svg dom element
+IconFactory.prototype.generateIdenticonSvg = function (address, diameter) {
+ var cacheId = `${address}:${diameter}`
+ // check cache, lazily generate and populate cache
+ var identicon = this.cache[cacheId] || (this.cache[cacheId] = this.generateNewIdenticon(address, diameter))
+ // create a clean copy so you can modify it
+ var cleanCopy = identicon.cloneNode(true)
+ return cleanCopy
+}
+
+// creates a new identicon
+IconFactory.prototype.generateNewIdenticon = function (address, diameter) {
+ var numericRepresentation = jsNumberForAddress(address)
+ var identicon = this.jazzicon(diameter, numericRepresentation)
+ return identicon
+}
+
+// util
+
+function iconExistsFor (address) {
+ return contractMap[address] && isValidAddress(address) && contractMap[address].logo
+}
+
+function imageElFor (address) {
+ const contract = contractMap[address]
+ const fileName = contract.logo
+ const path = `images/contract/${fileName}`
+ const img = document.createElement('img')
+ img.src = path
+ img.style.width = '75%'
+ return img
+}
+
+function jsNumberForAddress (address) {
+ var addr = address.slice(2, 10)
+ var seed = parseInt(addr, 16)
+ return seed
+}
+
diff --git a/old-ui/lib/lost-accounts-notice.js b/old-ui/lib/lost-accounts-notice.js
new file mode 100644
index 000000000..948b13db6
--- /dev/null
+++ b/old-ui/lib/lost-accounts-notice.js
@@ -0,0 +1,23 @@
+const summary = require('../app/util').addressSummary
+
+module.exports = function (lostAccounts) {
+ return {
+ date: new Date().toDateString(),
+ title: 'Account Problem Caught',
+ body: `MetaMask has fixed a bug where some accounts were previously mis-generated. This was a rare issue, but you were affected!
+
+We have successfully imported the accounts that were mis-generated, but they will no longer be recovered with your normal seed phrase.
+
+We have marked the affected accounts as "Loose", and recommend you transfer ether and tokens away from those accounts, or export & back them up elsewhere.
+
+Your affected accounts are:
+${lostAccounts.map(acct => ` - ${summary(acct)}`).join('\n')}
+
+These accounts have been marked as "Loose" so they will be easy to recognize in the account list.
+
+For more information, please read [our blog post.][1]
+
+[1]: https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd#.7d8ktj4h3
+ `,
+ }
+}
diff --git a/old-ui/lib/persistent-form.js b/old-ui/lib/persistent-form.js
new file mode 100644
index 000000000..d4dc20b03
--- /dev/null
+++ b/old-ui/lib/persistent-form.js
@@ -0,0 +1,61 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const defaultKey = 'persistent-form-default'
+const eventName = 'keyup'
+
+module.exports = PersistentForm
+
+function PersistentForm () {
+ Component.call(this)
+}
+
+inherits(PersistentForm, Component)
+
+PersistentForm.prototype.componentDidMount = function () {
+ const fields = document.querySelectorAll('[data-persistent-formid]')
+ const store = this.getPersistentStore()
+
+ for (var i = 0; i < fields.length; i++) {
+ const field = fields[i]
+ const key = field.getAttribute('data-persistent-formid')
+ const cached = store[key]
+ if (cached !== undefined) {
+ field.value = cached
+ }
+
+ field.addEventListener(eventName, this.persistentFieldDidUpdate.bind(this))
+ }
+}
+
+PersistentForm.prototype.getPersistentStore = function () {
+ let store = window.localStorage[this.persistentFormParentId || defaultKey]
+ if (store && store !== 'null') {
+ store = JSON.parse(store)
+ } else {
+ store = {}
+ }
+ return store
+}
+
+PersistentForm.prototype.setPersistentStore = function (newStore) {
+ window.localStorage[this.persistentFormParentId || defaultKey] = JSON.stringify(newStore)
+}
+
+PersistentForm.prototype.persistentFieldDidUpdate = function (event) {
+ const field = event.target
+ const store = this.getPersistentStore()
+ const key = field.getAttribute('data-persistent-formid')
+ const val = field.value
+ store[key] = val
+ this.setPersistentStore(store)
+}
+
+PersistentForm.prototype.componentWillUnmount = function () {
+ const fields = document.querySelectorAll('[data-persistent-formid]')
+ for (var i = 0; i < fields.length; i++) {
+ const field = fields[i]
+ field.removeEventListener(eventName, this.persistentFieldDidUpdate.bind(this))
+ }
+ this.setPersistentStore({})
+}
+
diff --git a/old-ui/lib/tx-helper.js b/old-ui/lib/tx-helper.js
new file mode 100644
index 000000000..de3f00d2d
--- /dev/null
+++ b/old-ui/lib/tx-helper.js
@@ -0,0 +1,27 @@
+const valuesFor = require('../app/util').valuesFor
+
+module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network) {
+ log.debug('tx-helper called with params:')
+ log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network })
+
+ const txValues = network ? valuesFor(unapprovedTxs).filter(txMeta => txMeta.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
+ log.debug(`tx helper found ${txValues.length} unapproved txs`)
+
+ const msgValues = valuesFor(unapprovedMsgs)
+ log.debug(`tx helper found ${msgValues.length} unsigned messages`)
+ let allValues = txValues.concat(msgValues)
+
+ const personalValues = valuesFor(personalMsgs)
+ log.debug(`tx helper found ${personalValues.length} unsigned personal messages`)
+ allValues = allValues.concat(personalValues)
+
+ const typedValues = valuesFor(typedMessages)
+ log.debug(`tx helper found ${typedValues.length} unsigned typed messages`)
+ allValues = allValues.concat(typedValues)
+
+ allValues = allValues.sort((a, b) => {
+ return a.time > b.time
+ })
+
+ return allValues
+}
diff --git a/package.json b/package.json
index c47c46004..4d1742d6a 100644
--- a/package.json
+++ b/package.json
@@ -9,13 +9,13 @@
"ui": "npm run test:flat:build:states && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"watch": "mocha watch --recursive \"test/unit/**/*.js\"",
- "mascara": "METAMASK_DEBUG=true node ./mascara/example/server",
+ "mascara": "gulp build && METAMASK_DEBUG=true node ./mascara/example/server",
"dist": "npm run dist:clear && npm install && gulp dist",
"dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect",
"test": "npm run lint && npm run test:coverage && npm run test:integration",
"test:unit": "METAMASK_ENV=test mocha --exit --compilers js:babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"",
"test:single": "METAMASK_ENV=test mocha --require test/helper.js",
- "test:integration": "npm run test:flat && npm run test:mascara",
+ "test:integration": "gulp build:scss && npm run test:flat && npm run test:mascara",
"test:coverage": "nyc npm run test:unit && npm run test:coveralls-upload",
"test:coveralls-upload": "if [ $COVERALLS_REPO_TOKEN ]; then nyc report --reporter=text-lcov | coveralls; fi",
"test:flat": "npm run test:flat:build && karma start test/flat.conf.js",
@@ -46,17 +46,23 @@
]
}
],
+ "reactify",
"envify",
"brfs"
]
},
"dependencies": {
+ "abi-decoder": "^1.0.9",
"asmcrypto.js": "0.22.0",
"async": "^2.5.0",
"await-semaphore": "^0.1.1",
"babel-runtime": "^6.23.0",
+ "bignumber.js": "^4.1.0",
+ "bip39": "^2.2.0",
"bluebird": "^3.5.0",
"bn.js": "^4.11.7",
+ "boron": "^0.2.3",
+ "browser-passworder": "^2.0.3",
"browserify-derequire": "^0.9.4",
"classnames": "^2.2.5",
"client-sw-ready-event": "^3.3.0",
@@ -72,18 +78,21 @@
"eslint-plugin-react": "^7.4.0",
"eth-bin-to-ops": "^1.0.1",
"eth-block-tracker": "^2.3.0",
- "eth-contract-metadata": "^1.1.4",
"eth-json-rpc-filters": "^1.2.5",
"eth-json-rpc-infura": "^3.0.0",
"eth-keyring-controller": "^2.1.4",
+ "eth-contract-metadata": "^1.1.5",
+ "eth-hd-keyring": "^1.2.1",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.4.2",
"eth-token-tracker": "^1.1.4",
+ "ethereumjs-abi": "^0.6.4",
"ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
"etherscan-link": "^1.0.2",
+ "ethjs": "^0.2.8",
"ethjs-contract": "^0.1.9",
"ethjs-ens": "^2.0.0",
"ethjs-query": "^0.3.1",
@@ -92,6 +101,11 @@
"extensionizer": "^1.0.0",
"fast-json-patch": "^2.0.4",
"fast-levenshtein": "^2.0.6",
+ "fuse.js": "^3.2.0",
+ "gulp": "github:gulpjs/gulp#4.0",
+ "gulp-autoprefixer": "^4.0.0",
+ "gulp-eslint": "^4.0.0",
+ "gulp-sass": "^3.1.0",
"hat": "0.0.3",
"human-standard-token-abi": "^1.0.2",
"idb-global": "^2.1.0",
@@ -126,16 +140,21 @@
"pump": "^1.0.2",
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
+ "ramda": "^0.24.1",
"react": "^15.6.2",
"react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.2",
"react-hyperscript": "^3.0.0",
"react-markdown": "^3.0.0",
"react-redux": "^5.0.5",
- "react-select": "^1.0.0-rc.2",
+ "react-select": "^1.0.0",
"react-simple-file-input": "^2.0.0",
+ "react-tippy": "^1.2.2",
+ "react-toggle-button": "^2.2.0",
"react-tooltip-component": "^0.3.0",
+ "react-transition-group": "^2.2.1",
"react-trigger-change": "^1.0.2",
+ "reactify": "^1.1.1",
"readable-stream": "^2.3.3",
"recompose": "^0.25.0",
"redux": "^3.0.5",
@@ -145,6 +164,7 @@
"sandwich-expando": "^1.1.3",
"semaphore": "^1.0.5",
"semver": "^5.4.1",
+ "shallow-copy": "0.0.1",
"sw-stream": "^2.0.0",
"textarea-caret": "^3.0.1",
"through2": "^2.0.3",
@@ -169,6 +189,7 @@
"brfs": "^1.4.3",
"browserify": "^14.4.0",
"chai": "^4.1.0",
+ "compression": "^1.7.1",
"coveralls": "^3.0.0",
"deep-freeze-strict": "^1.1.1",
"del": "^3.0.0",
@@ -177,15 +198,21 @@
"enzyme-adapter-react-15": "^1.0.5",
"eslint-plugin-chai": "0.0.1",
"eslint-plugin-mocha": "^4.9.0",
+ "eslint-plugin-react": "^7.4.0",
"eth-json-rpc-middleware": "^1.2.7",
"fs-promise": "^2.0.3",
"gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed",
+ "gulp-babel": "^7.0.0",
"gulp-eslint": "^4.0.0",
- "gulp-if": "^2.0.1",
+ "gulp-if": "^2.0.2",
"gulp-json-editor": "^2.2.1",
"gulp-livereload": "^3.8.1",
"gulp-replace": "^0.6.1",
"gulp-sourcemaps": "^2.6.0",
+ "gulp-stylefmt": "^1.1.0",
+ "gulp-stylelint": "^4.0.0",
+ "gulp-uglify": "^3.0.0",
+ "gulp-uglify-es": "^1.0.0",
"gulp-util": "^3.0.7",
"gulp-watch": "^5.0.0",
"gulp-zip": "^4.0.0",
@@ -204,6 +231,7 @@
"mocha-jsdom": "^1.1.0",
"mocha-sinon": "^2.0.0",
"nock": "^9.0.14",
+ "node-sass": "^4.7.2",
"nyc": "^11.0.3",
"open": "0.0.5",
"prompt": "^1.0.0",
@@ -214,6 +242,7 @@
"react-testutils-additions": "^15.2.0",
"redux-test-utils": "^0.2.2",
"sinon": "^4.0.0",
+ "stylelint-config-standard": "^17.0.0",
"tape": "^4.5.1",
"testem": "^2.0.0",
"uglifyify": "^4.0.2",
diff --git a/test/base.conf.js b/test/base.conf.js
index 122392822..82b9d8eec 100644
--- a/test/base.conf.js
+++ b/test/base.conf.js
@@ -54,6 +54,8 @@ module.exports = function(config) {
// Concurrency level
// how many browser should be started simultaneous
- concurrency: Infinity
+ concurrency: 1,
+
+ nocache: true,
}
}
diff --git a/test/integration/lib/add-token.js b/test/integration/lib/add-token.js
new file mode 100644
index 000000000..dd4251cc4
--- /dev/null
+++ b/test/integration/lib/add-token.js
@@ -0,0 +1,153 @@
+const reactTriggerChange = require('react-trigger-change')
+
+QUnit.module('Add token flow')
+
+QUnit.test('successful add token flow', (assert) => {
+ const done = assert.async()
+ runAddTokenFlowTest(assert)
+ .then(done)
+ .catch(err => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+async function runAddTokenFlowTest (assert, done) {
+ const selectState = $('select')
+ selectState.val('add token')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
+
+ // Check that no tokens have been added
+ assert.ok($('.token-list-item').length === 0, 'no tokens added')
+
+ // Go to Add Token screen
+ let addTokenButton = $('button.btn-clear.wallet-view__add-token-button')
+ assert.ok(addTokenButton[0], 'add token button present')
+ addTokenButton[0].click()
+
+ await timeout(1000)
+
+ // Verify Add Token screen
+ let addTokenWrapper = $('.add-token__wrapper')
+ assert.ok(addTokenWrapper[0], 'add token wrapper renders')
+
+ let addTokenTitle = $('.add-token__title')
+ assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct')
+
+ // Cancel Add Token
+ const cancelAddTokenButton = $('button.btn-cancel.add-token__button')
+ assert.ok(cancelAddTokenButton[0], 'cancel add token button present')
+ cancelAddTokenButton.click()
+
+ await timeout(1000)
+
+ assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view')
+
+ // Return to Add Token Screen
+ addTokenButton = $('button.btn-clear.wallet-view__add-token-button')
+ assert.ok(addTokenButton[0], 'add token button present')
+ addTokenButton[0].click()
+
+ await timeout(1000)
+
+ // Verify Add Token Screen
+ addTokenWrapper = $('.add-token__wrapper')
+ addTokenTitle = $('.add-token__title')
+ assert.ok(addTokenWrapper[0], 'add token wrapper renders')
+ assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct')
+
+ // Search for token
+ const searchInput = $('input.add-token__input')
+ searchInput.val('a')
+ reactTriggerChange(searchInput[0])
+
+ await timeout()
+
+ // Click token to add
+ const tokenWrapper = $('div.add-token__token-wrapper')
+ assert.ok(tokenWrapper[0], 'token found')
+ const tokenImageProp = tokenWrapper.find('.add-token__token-icon').css('background-image')
+ const tokenImageUrl = tokenImageProp.slice(5, -2)
+ tokenWrapper[0].click()
+
+ await timeout()
+
+ // Click Next button
+ let nextButton = $('button.btn-clear.add-token__button')
+ assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
+ nextButton[0].click()
+
+ await timeout()
+
+ // Confirm Add token
+ assert.equal(
+ $('.add-token__description')[0].textContent,
+ 'Would you like to add these tokens?',
+ 'confirm add token rendered'
+ )
+ assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
+ $('button.btn-clear.add-token__button')[0].click()
+
+ await timeout(2000)
+
+ // Verify added token image
+ let heroBalance = $('.hero-balance')
+ assert.ok(heroBalance, 'rendered hero balance')
+ assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added')
+
+ // Return to Add Token Screen
+ addTokenButton = $('button.btn-clear.wallet-view__add-token-button')
+ assert.ok(addTokenButton[0], 'add token button present')
+ addTokenButton[0].click()
+
+ await timeout(1000)
+
+ const addCustom = $('.add-token__add-custom')
+ assert.ok(addCustom[0], 'add custom token button present')
+ addCustom[0].click()
+
+ await timeout()
+
+ // Input token contract address
+ const customInput = $('input.add-token__add-custom-input')
+ customInput.val('0x177af043D3A1Aed7cc5f2397C70248Fc6cDC056c')
+ reactTriggerChange(customInput[0])
+
+ await timeout(1000)
+
+ // Click Next button
+ nextButton = $('button.btn-clear.add-token__button')
+ assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
+ nextButton[0].click()
+
+ await timeout(1000)
+
+ // Verify symbol length error since contract address won't return symbol
+ const errorMessage = $('.add-token__add-custom-error-message')
+ assert.ok(errorMessage[0], 'error rendered')
+ $('button.btn-cancel.add-token__button')[0].click()
+
+ await timeout(2000)
+
+ // // Confirm Add token
+ // assert.equal(
+ // $('.add-token__description')[0].textContent,
+ // 'Would you like to add these tokens?',
+ // 'confirm add token rendered'
+ // )
+ // assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
+ // $('button.btn-clear.add-token__button')[0].click()
+
+ // // Verify added token image
+ // heroBalance = $('.hero-balance')
+ // assert.ok(heroBalance, 'rendered hero balance')
+ // assert.ok(heroBalance.find('.identicon')[0], 'token added')
+}
+
+function timeout (time) {
+ return new Promise((resolve, reject) => {
+ setTimeout(resolve, time || 1500)
+ })
+}
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
new file mode 100644
index 000000000..e49424c37
--- /dev/null
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -0,0 +1,67 @@
+const reactTriggerChange = require('react-trigger-change')
+
+const PASSWORD = 'password123'
+
+QUnit.module('confirm sig requests')
+
+QUnit.test('successful confirmation of sig requests', (assert) => {
+ const done = assert.async()
+ runConfirmSigRequestsTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+async function runConfirmSigRequestsTest(assert, done) {
+ let selectState = $('select')
+ selectState.val('confirm sig requests')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
+
+ let confirmSigHeadline = $('.request-signature__headline')
+ assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+
+ let confirmSigRowValue = $('.request-signature__row-value')
+ assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
+
+ let confirmSigSignButton = $('.request-signature__footer__sign-button')
+ confirmSigSignButton[0].click()
+
+ await timeout(2000)
+
+ confirmSigHeadline = $('.request-signature__headline')
+ assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+
+ let confirmSigMessage = $('.request-signature__notice')
+ assert.ok(confirmSigMessage[0].textContent.match(/^Signing\sthis\smessage/))
+
+ confirmSigRowValue = $('.request-signature__row-value')
+ assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
+
+ confirmSigSignButton = $('.request-signature__footer__sign-button')
+ confirmSigSignButton[0].click()
+
+ await timeout(2000)
+
+ confirmSigHeadline = $('.request-signature__headline')
+ assert.equal(confirmSigHeadline[0].textContent, 'Your signature is being requested')
+
+ confirmSigRowValue = $('.request-signature__row-value')
+ assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
+ assert.equal(confirmSigRowValue[1].textContent, '1337')
+
+ confirmSigSignButton = $('.request-signature__footer__sign-button')
+ confirmSigSignButton[0].click()
+
+ await timeout(2000)
+
+ const txView = $('.tx-view')
+ assert.ok(txView[0], 'Should return to the account details screen after confirming')
+}
+
+function timeout (time) {
+ return new Promise((resolve, reject) => {
+ setTimeout(resolve, time || 1500)
+ })
+} \ No newline at end of file
diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js
index 61b38897e..764eae47c 100644
--- a/test/integration/lib/first-time.js
+++ b/test/integration/lib/first-time.js
@@ -1,3 +1,4 @@
+const reactTriggerChange = require('react-trigger-change')
const PASSWORD = 'password123'
const runMascaraFirstTimeTest = require('./mascara-first-time')
@@ -16,6 +17,11 @@ async function runFirstTimeUsageTest(assert, done) {
return runMascaraFirstTimeTest(assert, done)
}
+ const selectState = $('select')
+ selectState.val('first time')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
const app = $('#app-content')
// recurse notices
@@ -39,8 +45,8 @@ async function runFirstTimeUsageTest(assert, done) {
await timeout()
// Scroll through terms
- const title = app.find('h1').text()
- assert.equal(title, 'MetaMask', 'title screen')
+ const title = app.find('h1')[0]
+ assert.equal(title.textContent, 'MetaMask', 'title screen')
// enter password
const pwBox = app.find('#password-box')[0]
@@ -76,9 +82,9 @@ async function runFirstTimeUsageTest(assert, done) {
const menu = app.find('.menu-droppo')[0]
const children = menu.children
- const lock = children[children.length - 2]
- assert.ok(lock, 'Lock menu item found')
- lock.click()
+ const logout = children[2]
+ assert.ok(logout, 'Lock menu item found')
+ logout.click()
await timeout(1000)
diff --git a/test/integration/lib/mascara-first-time.js b/test/integration/lib/mascara-first-time.js
index 5c18cd254..515c7f383 100644
--- a/test/integration/lib/mascara-first-time.js
+++ b/test/integration/lib/mascara-first-time.js
@@ -71,14 +71,12 @@ async function runFirstTimeUsageTest (assert, done) {
app.find('.buy-ether__do-it-later').click()
await timeout(1000)
- const sandwich = app.find('.sandwich-expando')[0]
- sandwich.click()
+ const menu = app.find('.account-menu__icon')[0]
+ menu.click()
await timeout()
- const menu = app.find('.menu-droppo')[0]
- const children = menu.children
- const lock = children[children.length - 2]
+ const lock = app.find('.account-menu__logout-button')[0]
assert.ok(lock, 'Lock menu item found')
lock.click()
@@ -92,31 +90,25 @@ async function runFirstTimeUsageTest (assert, done) {
await timeout(1000)
- const detail2 = app.find('.account-detail-section')[0]
+ const detail2 = app.find('.wallet-view')[0]
assert.ok(detail2, 'Account detail section loaded again.')
await timeout()
// open account settings dropdown
- const qrButton = app.find('.fa.fa-ellipsis-h')[0]
+ const qrButton = app.find('.wallet-view__details-button')[0]
qrButton.click()
await timeout(1000)
- // qr code item
- const qrButton2 = app.find('.dropdown-menu-item')[1]
- qrButton2.click()
-
- await timeout(1000)
-
- const qrHeader = app.find('.qr-header')[0]
- const qrContainer = app.find('#qr-container')[0]
+ const qrHeader = app.find('.editable-label__value')[0]
+ const qrContainer = app.find('.qr-wrapper')[0]
assert.equal(qrHeader.textContent, 'Account 1', 'Should show account label.')
assert.ok(qrContainer, 'QR Container found')
await timeout()
- const networkMenu = app.find('.network-indicator')[0]
+ const networkMenu = app.find('.network-component')[0]
networkMenu.click()
await timeout()
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
new file mode 100644
index 000000000..3456f2367
--- /dev/null
+++ b/test/integration/lib/send-new-ui.js
@@ -0,0 +1,225 @@
+const reactTriggerChange = require('react-trigger-change')
+
+const PASSWORD = 'password123'
+
+QUnit.module('new ui send flow')
+
+QUnit.test('successful send flow', (assert) => {
+ const done = assert.async()
+ runSendFlowTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+global.ethQuery = {
+ sendTransaction: () => {},
+}
+
+async function runSendFlowTest(assert, done) {
+ console.log('*** start runSendFlowTest')
+ const selectState = $('select')
+ selectState.val('send new ui')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
+
+ const sendScreenButton = $('button.btn-clear.hero-balance-button')
+ assert.ok(sendScreenButton[1], 'send screen button present')
+ sendScreenButton[1].click()
+
+ await timeout(1000)
+
+ const sendTitle = $('.page-container__title')
+ assert.equal(sendTitle[0].textContent, 'Send ETH', 'Send screen title is correct')
+
+ const sendCopy = $('.page-container__subtitle')
+ assert.equal(sendCopy[0].textContent, 'Only send ETH to an Ethereum address.', 'Send screen has copy')
+
+ const sendFromField = $('.send-v2__form-field')
+ assert.ok(sendFromField[0], 'send screen has a from field')
+
+ let sendFromFieldItemAddress = $('.account-list-item__account-name')
+ assert.equal(sendFromFieldItemAddress[0].textContent, 'Send Account 4', 'send from field shows correct account name')
+
+ const sendFromFieldItem = $('.account-list-item')
+ sendFromFieldItem[0].click()
+
+ await timeout()
+
+ const sendFromDropdownList = $('.send-v2__from-dropdown__list')
+ assert.equal(sendFromDropdownList.children().length, 4, 'send from dropdown shows all accounts')
+ console.log(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sendFromDropdownList.children()[1]`, sendFromDropdownList.children()[1]);
+ sendFromDropdownList.children()[1].click()
+
+ await timeout()
+
+ sendFromFieldItemAddress = $('.account-list-item__account-name')
+ console.log(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sendFromFieldItemAddress[0]`, sendFromFieldItemAddress[0]);
+ assert.equal(sendFromFieldItemAddress[0].textContent, 'Send Account 2', 'send from field dropdown changes account name')
+
+ let sendToFieldInput = $('.send-v2__to-autocomplete__input')
+ sendToFieldInput[0].focus()
+
+ await timeout()
+
+ const sendToDropdownList = $('.send-v2__from-dropdown__list')
+ assert.equal(sendToDropdownList.children().length, 5, 'send to dropdown shows all accounts and address book accounts')
+
+ sendToDropdownList.children()[2].click()
+
+ await timeout()
+
+ const sendToAccountAddress = sendToFieldInput.val()
+ assert.equal(sendToAccountAddress, '0x2f8d4a878cfa04a6e60d46362f5644deab66572d', 'send to dropdown selects the correct address')
+
+ const sendAmountField = $('.send-v2__form-row:eq(2)')
+ sendAmountField.find('.currency-display')[0].click()
+
+ await timeout()
+
+ const sendAmountFieldInput = sendAmountField.find('input:text')
+ sendAmountFieldInput.val('5.1')
+ reactTriggerChange(sendAmountField.find('input')[0])
+
+ await timeout()
+
+ let errorMessage = $('.send-v2__error')
+ assert.equal(errorMessage[0].textContent, 'Insufficient funds.', 'send should render an insufficient fund error message')
+
+ sendAmountFieldInput.val('2.0')
+ reactTriggerChange(sendAmountFieldInput[0])
+
+ await timeout()
+ errorMessage = $('.send-v2__error')
+ assert.equal(errorMessage.length, 0, 'send should stop rendering amount error message after amount is corrected')
+
+ const sendGasField = $('.send-v2__gas-fee-display')
+ assert.equal(
+ sendGasField.find('.currency-display__input-wrapper > input').val(),
+ '0.000198',
+ 'send gas field should show estimated gas total'
+ )
+ assert.equal(
+ sendGasField.find('.currency-display__converted-value')[0].textContent,
+ '0.24 USD',
+ 'send gas field should show estimated gas total converted to USD'
+ )
+
+ const sendGasOpenCustomizeModalButton = $('.send-v2__sliders-icon-container'
+ )
+ sendGasOpenCustomizeModalButton[0].click()
+
+ await timeout(1000)
+
+ const customizeGasModal = $('.send-v2__customize-gas')
+ assert.ok(customizeGasModal[0], 'should render the customize gas modal')
+
+ const customizeGasPriceInput = $('.send-v2__gas-modal-card').first().find('input')
+ customizeGasPriceInput.val(50)
+ reactTriggerChange(customizeGasPriceInput[0])
+ const customizeGasLimitInput = $('.send-v2__gas-modal-card').last().find('input')
+ customizeGasLimitInput.val(60000)
+ reactTriggerChange(customizeGasLimitInput[0])
+
+ await timeout()
+
+ const customizeGasSaveButton = $('.send-v2__customize-gas__save')
+ customizeGasSaveButton[0].click()
+
+ await timeout()
+
+ assert.equal(
+ sendGasField.find('.currency-display__input-wrapper > input').val(),
+ '0.003',
+ 'send gas field should show customized gas total'
+ )
+ assert.equal(
+ sendGasField.find('.currency-display__converted-value')[0].textContent,
+ '3.60 USD',
+ 'send gas field should show customized gas total converted to USD'
+ )
+
+ const sendButton = $('button.btn-clear.page-container__footer-button')
+ assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
+ sendButton[0].click()
+
+ await timeout(2000)
+
+ selectState.val('send edit')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
+
+ const confirmFromName = $('.confirm-screen-account-name').first()
+ assert.equal(confirmFromName[0].textContent, 'Send Account 2', 'confirm screen should show correct from name')
+
+ const confirmToName = $('.confirm-screen-account-name').last()
+ assert.equal(confirmToName[0].textContent, 'Send Account 3', 'confirm screen should show correct to name')
+
+ const confirmScreenRows = $('.confirm-screen-rows')
+ const confirmScreenGas = confirmScreenRows.find('.confirm-screen-row-info')[2]
+ assert.equal(confirmScreenGas.textContent, '3.6 USD', 'confirm screen should show correct gas')
+ const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[3]
+ assert.equal(confirmScreenTotal.textContent, '2405.36 USD', 'confirm screen should show correct total')
+
+ const confirmScreenBackButton = $('.confirm-screen-back-button')
+ confirmScreenBackButton[0].click()
+
+ await timeout(1000)
+
+ const sendFromFieldItemInEdit = $('.account-list-item')
+ sendFromFieldItemInEdit[0].click()
+
+ await timeout()
+
+ const sendFromDropdownListInEdit = $('.send-v2__from-dropdown__list')
+ sendFromDropdownListInEdit.children()[2].click()
+
+ await timeout()
+
+ const sendToFieldInputInEdit = $('.send-v2__to-autocomplete__input')
+ sendToFieldInputInEdit[0].focus()
+ sendToFieldInputInEdit.val('0xd85a4b6a394794842887b8284293d69163007bbb')
+
+ await timeout()
+
+ const sendAmountFieldInEdit = $('.send-v2__form-row:eq(2)')
+ sendAmountFieldInEdit.find('.currency-display')[0].click()
+
+ await timeout()
+
+ const sendAmountFieldInputInEdit = sendAmountFieldInEdit.find('input:text')
+ sendAmountFieldInputInEdit.val('1.0')
+ reactTriggerChange(sendAmountFieldInputInEdit[0])
+
+ await timeout()
+
+ const sendButtonInEdit = $('.btn-clear.page-container__footer-button')
+ assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
+ sendButtonInEdit[0].click()
+
+ await timeout()
+
+ // TODO: Need a way to mock background so that we can test correct transition from editing to confirm
+ selectState.val('confirm new ui')
+ reactTriggerChange(selectState[0])
+
+ await timeout(2000)
+ const confirmScreenConfirmButton = $('.confirm-screen-confirm-button')
+ console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
+ confirmScreenConfirmButton[0].click()
+
+ await timeout(2000)
+
+ const txView = $('.tx-view')
+ console.log(`++++++++++++++++++++++++++++++++ txView[0]`, txView[0]);
+
+ assert.ok(txView[0], 'Should return to the account details screen after confirming')
+}
+
+function timeout (time) {
+ return new Promise((resolve, reject) => {
+ setTimeout(resolve, time || 1500)
+ })
+} \ No newline at end of file
diff --git a/test/lib/shallow-with-store.js b/test/lib/shallow-with-store.js
index 10c02a18c..9df10a3c5 100644
--- a/test/lib/shallow-with-store.js
+++ b/test/lib/shallow-with-store.js
@@ -17,4 +17,4 @@ function mountWithStore (component, store) {
store,
}
return mount(component, {context})
-} \ No newline at end of file
+}
diff --git a/test/unit/actions/tx_test.js b/test/unit/actions/tx_test.js
index ea6dfda6a..b6a691860 100644
--- a/test/unit/actions/tx_test.js
+++ b/test/unit/actions/tx_test.js
@@ -51,9 +51,8 @@ describe('tx confirmation screen', function () {
actions.cancelTx({value: firstTxId})((action) => {
result = reducers(initialState, action)
- done()
})
-
+ done()
})
it('should transition to the account detail view', function () {
diff --git a/test/unit/components/balance-component-test.js b/test/unit/components/balance-component-test.js
new file mode 100644
index 000000000..9b1e82acf
--- /dev/null
+++ b/test/unit/components/balance-component-test.js
@@ -0,0 +1,45 @@
+const assert = require('assert')
+const h = require('react-hyperscript')
+const { createMockStore } = require('redux-test-utils')
+const { shallowWithStore } = require('../../lib/shallow-with-store')
+const BalanceComponent = require('../../../ui/app/components/balance-component')
+const mockState = {
+ metamask: {
+ accounts: { abc: {} },
+ network: 1,
+ selectedAddress: 'abc',
+ }
+}
+
+describe('BalanceComponent', function () {
+ let balanceComponent
+ let store
+ let component
+ beforeEach(function () {
+ store = createMockStore(mockState)
+ component = shallowWithStore(h(BalanceComponent), store)
+ balanceComponent = component.dive()
+ })
+
+ it('shows token balance and convert to fiat value based on conversion rate', function () {
+ const formattedBalance = '1.23 ETH'
+
+ const tokenBalance = balanceComponent.instance().getTokenBalance(formattedBalance, false)
+ const fiatDisplayNumber = balanceComponent.instance().getFiatDisplayNumber(formattedBalance, 2)
+
+ assert.equal('1.23 ETH', tokenBalance)
+ assert.equal(2.46, fiatDisplayNumber)
+ })
+
+ it('shows only the token balance when conversion rate is not available', function () {
+ const formattedBalance = '1.23 ETH'
+
+ const tokenBalance = balanceComponent.instance().getTokenBalance(formattedBalance, false)
+ const fiatDisplayNumber = balanceComponent.instance().getFiatDisplayNumber(formattedBalance, 0)
+
+ assert.equal('1.23 ETH', tokenBalance)
+ assert.equal('N/A', fiatDisplayNumber)
+ })
+
+})
+
diff --git a/test/unit/components/pending-tx-test.js b/test/unit/components/pending-tx-test.js
index 20feba2a3..c6c588e1c 100644
--- a/test/unit/components/pending-tx-test.js
+++ b/test/unit/components/pending-tx-test.js
@@ -1,18 +1,22 @@
const assert = require('assert')
-const additions = require('react-testutils-additions')
const h = require('react-hyperscript')
const PendingTx = require('../../../ui/app/components/pending-tx')
-const ReactTestUtils = require('react-addons-test-utils')
const ethUtil = require('ethereumjs-util')
-describe('PendingTx', function () {
- const identities = {
- '0xfdea65c8e26263f6d9a1b5de9555d2931a33b826': {
- name: 'Main Account 1',
- balance: '0x00000000000000056bc75e2d63100000',
- },
+const { createMockStore } = require('redux-test-utils')
+const { shallowWithStore } = require('../../lib/shallow-with-store')
+
+const identities = { abc: {}, def: {} }
+const mockState = {
+ metamask: {
+ accounts: { abc: {} },
+ identities,
+ conversionRate: 10,
+ selectedAddress: 'abc',
}
+}
+describe('PendingTx', function () {
const gasPrice = '0x4A817C800' // 20 Gwei
const txData = {
'id': 5021615666270214,
@@ -29,55 +33,35 @@ describe('PendingTx', function () {
'gasLimitSpecified': false,
'estimatedGas': '0x5208',
}
+ const newGasPrice = '0x77359400'
+ const computedBalances = {}
+ computedBalances[Object.keys(identities)[0]] = {
+ ethBalance: '0x00000000000000056bc75e2d63100000',
+ }
+ const props = {
+ txData,
+ computedBalances,
+ sendTransaction: (txMeta, event) => {
+ // Assert changes:
+ const result = ethUtil.addHexPrefix(txMeta.txParams.gasPrice)
+ assert.notEqual(result, gasPrice, 'gas price should change')
+ assert.equal(result, newGasPrice, 'gas price assigned.')
+ },
+ }
- it('should use updated values when edited.', function (done) {
- const renderer = ReactTestUtils.createRenderer()
- const newGasPrice = '0x77359400'
-
- const computedBalances = {}
- computedBalances[Object.keys(identities)[0]] = {
- ethBalance: '0x00000000000000056bc75e2d63100000',
- }
- const props = {
- identities,
- accounts: identities,
- txData,
- computedBalances,
- sendTransaction: (txMeta, event) => {
- // Assert changes:
- const result = ethUtil.addHexPrefix(txMeta.txParams.gasPrice)
- assert.notEqual(result, gasPrice, 'gas price should change')
- assert.equal(result, newGasPrice, 'gas price assigned.')
- done()
- },
- }
-
- const pendingTxComponent = h(PendingTx, props)
- const component = additions.renderIntoDocument(pendingTxComponent)
- renderer.render(pendingTxComponent)
- const result = renderer.getRenderOutput()
- assert.equal(result.type, 'div', 'should create a div')
-
- try {
- const input = additions.find(component, '.cell.row input[type="number"]')[1]
- ReactTestUtils.Simulate.change(input, {
- target: {
- value: 2,
- checkValidity () { return true },
- },
- })
+ let pendingTxComponent
+ let store
+ let component
+ beforeEach(function () {
+ store = createMockStore(mockState)
+ component = shallowWithStore(h(PendingTx, props), store)
+ pendingTxComponent = component
+ })
- const form = additions.find(component, 'form')[0]
- form.checkValidity = () => true
- form.getFormEl = () => { return { checkValidity () { return true } } }
- ReactTestUtils.Simulate.submit(form, { preventDefault () {}, target: { checkValidity () {
- return true
- } } })
- } catch (e) {
- console.log('WHAAAA')
- console.error(e)
- }
+ it('should render correctly', function (done) {
+ assert.equal(pendingTxComponent.props().identities, identities)
+ done()
})
})
diff --git a/test/unit/pending-tx-test.js b/test/unit/pending-tx-test.js
index cb29ddafd..f0b4e3bfc 100644
--- a/test/unit/pending-tx-test.js
+++ b/test/unit/pending-tx-test.js
@@ -12,6 +12,7 @@ const currentNetworkId = 42
const otherNetworkId = 36
const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
+
describe('PendingTransactionTracker', function () {
let pendingTxTracker, txMeta, txMetaNoHash, txMetaNoRawTx, providerResultStub,
provider, txMeta3, txList, knownErrors
diff --git a/test/unit/responsive/components/dropdown-test.js b/test/unit/responsive/components/dropdown-test.js
index 3ad2c390e..982d8c6ec 100644
--- a/test/unit/responsive/components/dropdown-test.js
+++ b/test/unit/responsive/components/dropdown-test.js
@@ -1,40 +1,45 @@
-var assert = require('assert');
+const assert = require('assert');
-const additions = require('react-testutils-additions');
const h = require('react-hyperscript');
-const ReactTestUtils = require('react-addons-test-utils');
const sinon = require('sinon');
const path = require('path');
-const Dropdown = require(path.join(__dirname, '..', '..', '..', '..', 'ui', 'app', 'components', 'dropdown.js')).Dropdown;
-const DropdownMenuItem = require(path.join(__dirname, '..', '..', '..', '..', 'ui', 'app', 'components', 'dropdown.js')).DropdownMenuItem;
+const Dropdown = require(path.join(__dirname, '..', '..', '..', '..', 'ui', 'app', 'components', 'dropdowns', 'index.js')).Dropdown;
+
+const { createMockStore } = require('redux-test-utils')
+const { mountWithStore } = require('../../../lib/shallow-with-store')
+
+const mockState = {
+ metamask: {
+ }
+}
describe('Dropdown components', function () {
let onClickOutside;
let closeMenu;
let onClick;
- let dropdownComponentProps;
- const renderer = ReactTestUtils.createRenderer()
+ let dropdownComponentProps = {
+ isOpen: true,
+ zIndex: 11,
+ onClickOutside,
+ style: {
+ position: 'absolute',
+ right: 0,
+ top: '36px',
+ },
+ innerStyle: {},
+ }
+
+ let dropdownComponent
+ let store
+ let component
beforeEach(function () {
onClickOutside = sinon.spy();
closeMenu = sinon.spy();
onClick = sinon.spy();
- dropdownComponentProps = {
- isOpen: true,
- zIndex: 11,
- onClickOutside,
- style: {
- position: 'absolute',
- right: 0,
- top: '36px',
- },
- innerStyle: {},
- }
- });
-
- it('can render two items', function () {
- const dropdownComponent = h(
+ store = createMockStore(mockState)
+ component = mountWithStore(h(
Dropdown,
dropdownComponentProps,
[
@@ -42,74 +47,35 @@ describe('Dropdown components', function () {
.drop-menu-item:hover { background:rgb(235, 235, 235); }
.drop-menu-item i { margin: 11px; }
`),
- h(DropdownMenuItem, {
+ h('li', {
closeMenu,
onClick,
}, 'Item 1'),
- h(DropdownMenuItem, {
+ h('li', {
closeMenu,
onClick,
}, 'Item 2'),
]
- )
+ ), store)
+ dropdownComponent = component
+ })
- const component = additions.renderIntoDocument(dropdownComponent);
- renderer.render(dropdownComponent);
- const items = additions.find(component, 'li');
+ it('can render two items', function () {
+ const items = dropdownComponent.find('li');
assert.equal(items.length, 2);
});
it('closes when item clicked', function() {
- const dropdownComponent = h(
- Dropdown,
- dropdownComponentProps,
- [
- h('style', `
- .drop-menu-item:hover { background:rgb(235, 235, 235); }
- .drop-menu-item i { margin: 11px; }
- `),
- h(DropdownMenuItem, {
- closeMenu,
- onClick,
- }, 'Item 1'),
- h(DropdownMenuItem, {
- closeMenu,
- onClick,
- }, 'Item 2'),
- ]
- )
- const component = additions.renderIntoDocument(dropdownComponent);
- renderer.render(dropdownComponent);
- const items = additions.find(component, 'li');
- const node = items[0];
- ReactTestUtils.Simulate.click(node);
- assert.equal(closeMenu.calledOnce, true);
+ const items = dropdownComponent.find('li');
+ const node = items.at(0);
+ node.simulate('click');
+ assert.equal(node.props().closeMenu, closeMenu);
});
it('invokes click handler when item clicked', function() {
- const dropdownComponent = h(
- Dropdown,
- dropdownComponentProps,
- [
- h('style', `
- .drop-menu-item:hover { background:rgb(235, 235, 235); }
- .drop-menu-item i { margin: 11px; }
- `),
- h(DropdownMenuItem, {
- closeMenu,
- onClick,
- }, 'Item 1'),
- h(DropdownMenuItem, {
- closeMenu,
- onClick,
- }, 'Item 2'),
- ]
- )
- const component = additions.renderIntoDocument(dropdownComponent);
- renderer.render(dropdownComponent);
- const items = additions.find(component, 'li');
- const node = items[0];
- ReactTestUtils.Simulate.click(node);
+ const items = dropdownComponent.find('li');
+ const node = items.at(0);
+ node.simulate('click');
assert.equal(onClick.calledOnce, true);
});
});
diff --git a/test/unit/ui/add-token.spec.js b/test/unit/ui/add-token.spec.js
index 9e74aa37e..69b7fb620 100644
--- a/test/unit/ui/add-token.spec.js
+++ b/test/unit/ui/add-token.spec.js
@@ -2,7 +2,7 @@ const assert = require('assert')
const { createMockStore } = require('redux-test-utils')
const h = require('react-hyperscript')
const { shallowWithStore } = require('../../lib/shallow-with-store')
-const AddTokenScreen = require('../../../ui/app/add-token')
+const AddTokenScreen = require('../../../old-ui/app/add-token')
describe('Add Token Screen', function () {
let addTokenComponent, store, component
diff --git a/ui/app/account-and-transaction-details.js b/ui/app/account-and-transaction-details.js
new file mode 100644
index 000000000..03101d37a
--- /dev/null
+++ b/ui/app/account-and-transaction-details.js
@@ -0,0 +1,33 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+// Main Views
+const TxView = require('./components/tx-view')
+const WalletView = require('./components/wallet-view')
+
+module.exports = AccountAndTransactionDetails
+
+inherits(AccountAndTransactionDetails, Component)
+function AccountAndTransactionDetails () {
+ Component.call(this)
+}
+
+AccountAndTransactionDetails.prototype.render = function () {
+ return h('div.account-and-transaction-details', [
+ // wallet
+ h(WalletView, {
+ style: {
+ },
+ responsiveDisplayClassname: '.lap-visible',
+ }, [
+ ]),
+
+ // transaction
+ h(TxView, {
+ style: {
+ },
+ }, [
+ ]),
+ ])
+}
+
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index c9a8a774d..0da435298 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -5,15 +5,10 @@ const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
const valuesFor = require('./util').valuesFor
-const Identicon = require('./components/identicon')
-const EthBalance = require('./components/eth-balance')
const TransactionList = require('./components/transaction-list')
const ExportAccountView = require('./components/account-export')
-const ethUtil = require('ethereumjs-util')
-const EditableLabel = require('./components/editable-label')
const TabBar = require('./components/tab-bar')
const TokenList = require('./components/token-list')
-const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
module.exports = connect(mapStateToProps)(AccountDetailScreen)
@@ -41,181 +36,11 @@ function AccountDetailScreen () {
Component.call(this)
}
-AccountDetailScreen.prototype.render = function () {
- var props = this.props
- var selected = props.address || Object.keys(props.accounts)[0]
- var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
- var identity = props.identities[selected]
- var account = props.accounts[selected]
- const { network, conversionRate, currentCurrency } = props
-
- return (
-
- h('.account-detail-section.full-flex-height', [
-
- // identicon, label, balance, etc
- h('.account-data-subsection', {
- style: {
- margin: '0 20px',
- flex: '1 0 auto',
- },
- }, [
-
- // header - identicon + nav
- h('div', {
- style: {
- paddingTop: '20px',
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'flex-start',
- },
- }, [
-
- // large identicon and addresses
- h('.identicon-wrapper.select-none', [
- h(Identicon, {
- diameter: 62,
- address: selected,
- }),
- ]),
- h('flex-column', {
- style: {
- lineHeight: '10px',
- marginLeft: '15px',
- width: '100%',
- },
- }, [
- h(EditableLabel, {
- textValue: identity ? identity.name : '',
- state: {
- isEditingLabel: false,
- },
- saveText: (text) => {
- props.dispatch(actions.saveAccountLabel(selected, text))
- },
- }, [
-
- // What is shown when not editing + edit text:
- h('label.editing-label', [h('.edit-text', 'edit')]),
- h(
- 'div',
- {
- style: {
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'center',
- },
- },
- [
- h(
- 'div.font-medium.color-forest',
- {
- name: 'edit',
- style: {
- },
- },
- [
- h('h2', {
- style: {
- maxWidth: '180px',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- padding: '5px 0px',
- lineHeight: '25px',
- },
- }, [
- identity && identity.name,
- ]),
- ]
- ),
- h(
- AccountDropdowns,
- {
- style: {
- marginRight: '8px',
- marginLeft: 'auto',
- cursor: 'pointer',
- },
- selected,
- network,
- identities: props.identities,
- enableAccountOptions: true,
- },
- ),
- ]
- ),
- ]),
- h('.flex-row', {
- style: {
- width: '15em',
- justifyContent: 'space-between',
- alignItems: 'baseline',
- },
- }, [
-
- // address
-
- h('div', {
- style: {
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- paddingTop: '3px',
- width: '5em',
- height: '15px',
- fontSize: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- marginBottom: '15px',
- color: '#AEAEAE',
- },
- }, checksumAddress),
- ]),
-
- // account ballence
-
- ]),
- ]),
- h('.flex-row', {
- style: {
- justifyContent: 'space-between',
- alignItems: 'flex-start',
- },
- }, [
-
- h(EthBalance, {
- value: account && account.balance,
- conversionRate,
- currentCurrency,
- style: {
- lineHeight: '7px',
- marginTop: '10px',
- },
- }),
-
- h('.flex-grow'),
-
- h('button', {
- onClick: () => props.dispatch(actions.buyEthView(selected)),
- style: { marginRight: '10px' },
- }, 'BUY'),
-
- h('button', {
- onClick: () => props.dispatch(actions.showSendPage()),
- style: {
- marginBottom: '20px',
- marginRight: '8px',
- },
- }, 'SEND'),
-
- ]),
- ]),
-
- // subview (tx history, pk export confirm, buy eth warning)
- this.subview(),
-
- ])
- )
-}
+// Note: This component is no longer used. Leaving the file for reference:
+// - structuring routing for add token
+// - state required for TxList
+// Delete file when those features are complete
+AccountDetailScreen.prototype.render = function () {}
AccountDetailScreen.prototype.subview = function () {
var subview
diff --git a/ui/app/accounts/import/index.js b/ui/app/accounts/import/index.js
index 46260c3e7..71eb9ae23 100644
--- a/ui/app/accounts/import/index.js
+++ b/ui/app/accounts/import/index.js
@@ -2,7 +2,6 @@ const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const actions = require('../../actions')
import Select from 'react-select'
// Subviews
@@ -34,34 +33,14 @@ AccountImportSubview.prototype.render = function () {
const { type } = state
return (
- h('div', {
- style: {
- },
- }, [
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- props.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Import Accounts'),
- ]),
- h('div', {
- style: {
- padding: '10px',
- color: 'rgb(174, 174, 174)',
- },
- }, [
+ h('div.new-account-import-form', [
- h('h3', { style: { padding: '3px' } }, 'SELECT TYPE'),
+ h('div.new-account-import-form__select-section', [
- h('style', `
- .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label {
- color: rgb(174,174,174);
- }
- `),
+ h('div.new-account-import-form__select-label', 'Select Type'),
h(Select, {
+ className: 'new-account-import-form__select',
name: 'import-type-select',
clearable: false,
value: type || menuItems[0],
@@ -72,10 +51,10 @@ AccountImportSubview.prototype.render = function () {
}
}),
onChange: (opt) => {
- props.dispatch(actions.showImportPage())
this.setState({ type: opt.value })
},
}),
+
]),
this.renderImportView(),
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js
index 15f9816e7..dd5dfad22 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/accounts/import/json.js
@@ -5,7 +5,7 @@ const connect = require('react-redux').connect
const actions = require('../../actions')
const FileInput = require('react-simple-file-input').default
-const HELP_LINK = 'https://github.com/MetaMask/faq/blob/master/README.md#q-i-cant-use-the-import-feature-for-uploading-a-json-file-the-window-keeps-closing-when-i-try-to-select-a-file'
+const HELP_LINK = 'https://support.metamask.io/kb/article/7-importing-accounts'
module.exports = connect(mapStateToProps)(JsonImportSubview)
@@ -24,14 +24,7 @@ JsonImportSubview.prototype.render = function () {
const { error } = this.props
return (
- h('div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- padding: '5px 15px 0px 15px',
- },
- }, [
+ h('div.new-account-import-form__json', [
h('p', 'Used by a variety of different clients'),
h('a.warning', { href: HELP_LINK, target: '_blank' }, 'File import not working? Click here!'),
@@ -40,28 +33,35 @@ JsonImportSubview.prototype.render = function () {
readAs: 'text',
onLoad: this.onLoad.bind(this),
style: {
- margin: '20px 0px 12px 20px',
+ margin: '20px 0px 12px 34%',
fontSize: '15px',
+ display: 'flex',
+ justifyContent: 'center',
},
}),
- h('input.large-input.letter-spacey', {
+ h('input.new-account-import-form__input-password', {
type: 'password',
placeholder: 'Enter password',
id: 'json-password-box',
onKeyPress: this.createKeyringOnEnter.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
}),
- h('button.primary', {
- onClick: this.createNewKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Import'),
+ h('div.new-account-create-form__buttons', {}, [
+
+ h('button.new-account-create-form__button-cancel', {
+ onClick: () => this.props.goHome(),
+ }, [
+ 'CANCEL',
+ ]),
+
+ h('button.new-account-create-form__button-create', {
+ onClick: () => this.createNewKeychain.bind(this),
+ }, [
+ 'IMPORT',
+ ]),
+
+ ]),
error ? h('span.error', error) : null,
])
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js
index 68ccee58e..12f3a6430 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/accounts/import/private-key.js
@@ -4,7 +4,7 @@ const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('../../actions')
-module.exports = connect(mapStateToProps)(PrivateKeyImportView)
+module.exports = connect(mapStateToProps, mapDispatchToProps)(PrivateKeyImportView)
function mapStateToProps (state) {
return {
@@ -12,41 +12,54 @@ function mapStateToProps (state) {
}
}
+function mapDispatchToProps (dispatch) {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ importNewAccount: (strategy, [ privateKey ]) => {
+ dispatch(actions.importNewAccount(strategy, [ privateKey ]))
+ },
+ displayWarning: () => dispatch(actions.displayWarning(null)),
+ }
+}
+
inherits(PrivateKeyImportView, Component)
function PrivateKeyImportView () {
Component.call(this)
}
PrivateKeyImportView.prototype.render = function () {
- const { error } = this.props
+ const { error, goHome } = this.props
return (
- h('div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- padding: '5px 15px 0px 15px',
- },
- }, [
- h('span', 'Paste your private key string here'),
-
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'private-key-box',
- onKeyPress: this.createKeyringOnEnter.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- h('button.primary', {
- onClick: this.createNewKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Import'),
+ h('div.new-account-import-form__private-key', [
+
+ h('div.new-account-import-form__private-key-password-container', [
+
+ h('span.new-account-import-form__instruction', 'Paste your private key string here:'),
+
+ h('input.new-account-import-form__input-password', {
+ type: 'password',
+ id: 'private-key-box',
+ onKeyPress: () => this.createKeyringOnEnter(),
+ }),
+
+ ]),
+
+ h('div.new-account-import-form__buttons', {}, [
+
+ h('button.new-account-create-form__button-cancel', {
+ onClick: () => goHome(),
+ }, [
+ 'CANCEL',
+ ]),
+
+ h('button.new-account-create-form__button-create', {
+ onClick: () => this.createNewKeychain(),
+ }, [
+ 'IMPORT',
+ ]),
+
+ ]),
error ? h('span.error', error) : null,
])
@@ -63,5 +76,6 @@ PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
PrivateKeyImportView.prototype.createNewKeychain = function () {
const input = document.getElementById('private-key-box')
const privateKey = input.value
- this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ]))
+
+ this.props.importNewAccount('Private Key', [ privateKey ])
}
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/accounts/new-account/create-form.js
new file mode 100644
index 000000000..a6b3bba4b
--- /dev/null
+++ b/ui/app/accounts/new-account/create-form.js
@@ -0,0 +1,99 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const actions = require('../../actions')
+
+class NewAccountCreateForm extends Component {
+ constructor (props) {
+ super(props)
+
+ const { numberOfExistingAccounts = 0 } = props
+ const newAccountNumber = numberOfExistingAccounts + 1
+
+ this.state = {
+ newAccountName: '',
+ defaultAccountName: `Account ${newAccountNumber}`,
+ }
+ }
+
+ render () {
+ const { newAccountName, defaultAccountName } = this.state
+
+
+ return h('div.new-account-create-form', [
+
+ h('div.new-account-create-form__input-label', {}, [
+ 'Account Name',
+ ]),
+
+ h('div.new-account-create-form__input-wrapper', {}, [
+ h('input.new-account-create-form__input', {
+ value: newAccountName,
+ placeholder: defaultAccountName,
+ onChange: event => this.setState({ newAccountName: event.target.value }),
+ }, []),
+ ]),
+
+ h('div.new-account-create-form__buttons', {}, [
+
+ h('button.new-account-create-form__button-cancel', {
+ onClick: () => this.props.goHome(),
+ }, [
+ 'CANCEL',
+ ]),
+
+ h('button.new-account-create-form__button-create', {
+ onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
+ }, [
+ 'CREATE',
+ ]),
+
+ ]),
+
+ ])
+ }
+}
+
+NewAccountCreateForm.propTypes = {
+ hideModal: PropTypes.func,
+ showImportPage: PropTypes.func,
+ createAccount: PropTypes.func,
+ goHome: PropTypes.func,
+ numberOfExistingAccounts: PropTypes.number,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { network, selectedAddress, identities = {} } } = state
+ const numberOfExistingAccounts = Object.keys(identities).length
+
+ return {
+ network,
+ address: selectedAddress,
+ numberOfExistingAccounts,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ toCoinbase: (address) => {
+ dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+ },
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ createAccount: (newAccountName) => {
+ dispatch(actions.addNewAccount())
+ .then((newAccountAddress) => {
+ if (newAccountName) {
+ dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName))
+ }
+ dispatch(actions.goHome())
+ })
+ },
+ showImportPage: () => dispatch(actions.showImportPage()),
+ goHome: () => dispatch(actions.goHome()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm)
diff --git a/ui/app/accounts/new-account/index.js b/ui/app/accounts/new-account/index.js
new file mode 100644
index 000000000..acf0dc6e4
--- /dev/null
+++ b/ui/app/accounts/new-account/index.js
@@ -0,0 +1,81 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const { getCurrentViewContext } = require('../../selectors')
+const classnames = require('classnames')
+
+const NewAccountCreateForm = require('./create-form')
+const NewAccountImportForm = require('../import')
+
+function mapStateToProps (state) {
+ return {
+ displayedForm: getCurrentViewContext(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ displayForm: form => dispatch(actions.setNewAccountForm(form)),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
+ }
+}
+
+inherits(AccountDetailsModal, Component)
+function AccountDetailsModal (props) {
+ Component.call(this)
+
+ this.state = {
+ displayedForm: props.displayedForm,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
+
+AccountDetailsModal.prototype.render = function () {
+ const { displayedForm, displayForm } = this.props
+
+ return h('div.new-account', {}, [
+
+ h('div.new-account__header', [
+
+ h('div.new-account__title', 'New Account'),
+
+ h('div.new-account__tabs', [
+
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': displayedForm === 'CREATE',
+ 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'CREATE',
+ }),
+ onClick: () => displayForm('CREATE'),
+ }, 'Create'),
+
+ h('div.new-account__tabs__tab', {
+ className: classnames('new-account__tabs__tab', {
+ 'new-account__tabs__selected': displayedForm === 'IMPORT',
+ 'new-account__tabs__unselected cursor-pointer': displayedForm !== 'IMPORT',
+ }),
+ onClick: () => displayForm('IMPORT'),
+ }, 'Import'),
+
+ ]),
+
+ ]),
+
+ h('div.new-account__form', [
+
+ displayedForm === 'CREATE'
+ ? h(NewAccountCreateForm)
+ : h(NewAccountImportForm),
+
+ ]),
+
+ ])
+}
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 90acdc821..64d5b67e0 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1,10 +1,28 @@
+const abi = require('human-standard-token-abi')
const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
+const { getTokenAddressFromTokenObject } = require('./util')
+const ethUtil = require('ethereumjs-util')
var actions = {
_setBackgroundConnection: _setBackgroundConnection,
GO_HOME: 'GO_HOME',
goHome: goHome,
+ // modal state
+ MODAL_OPEN: 'UI_MODAL_OPEN',
+ MODAL_CLOSE: 'UI_MODAL_CLOSE',
+ showModal: showModal,
+ hideModal: hideModal,
+ // sidebar state
+ SIDEBAR_OPEN: 'UI_SIDEBAR_OPEN',
+ SIDEBAR_CLOSE: 'UI_SIDEBAR_CLOSE',
+ showSidebar: showSidebar,
+ hideSidebar: hideSidebar,
+ // network dropdown open
+ NETWORK_DROPDOWN_OPEN: 'UI_NETWORK_DROPDOWN_OPEN',
+ NETWORK_DROPDOWN_CLOSE: 'UI_NETWORK_DROPDOWN_CLOSE',
+ showNetworkDropdown: showNetworkDropdown,
+ hideNetworkDropdown: hideNetworkDropdown,
// menu state
getNetworkStatus: 'getNetworkStatus',
// transition state
@@ -29,16 +47,23 @@ var actions = {
SHOW_RESTORE_VAULT: 'SHOW_RESTORE_VAULT',
FORGOT_PASSWORD: 'FORGOT_PASSWORD',
forgotPassword: forgotPassword,
+ markPasswordForgotten,
+ unMarkPasswordForgotten,
SHOW_INIT_MENU: 'SHOW_INIT_MENU',
SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED',
SHOW_INFO_PAGE: 'SHOW_INFO_PAGE',
SHOW_IMPORT_PAGE: 'SHOW_IMPORT_PAGE',
+ SHOW_NEW_ACCOUNT_PAGE: 'SHOW_NEW_ACCOUNT_PAGE',
+ SET_NEW_ACCOUNT_FORM: 'SET_NEW_ACCOUNT_FORM',
unlockMetamask: unlockMetamask,
unlockFailed: unlockFailed,
+ unlockSucceeded,
showCreateVault: showCreateVault,
showRestoreVault: showRestoreVault,
showInitializeMenu: showInitializeMenu,
showImportPage,
+ showNewAccountPage,
+ setNewAccountForm,
createNewVaultAndKeychain: createNewVaultAndKeychain,
createNewVaultAndRestore: createNewVaultAndRestore,
createNewVaultInProgress: createNewVaultInProgress,
@@ -58,6 +83,7 @@ var actions = {
// unlock screen
UNLOCK_IN_PROGRESS: 'UNLOCK_IN_PROGRESS',
UNLOCK_FAILED: 'UNLOCK_FAILED',
+ UNLOCK_SUCCEEDED: 'UNLOCK_SUCCEEDED',
UNLOCK_METAMASK: 'UNLOCK_METAMASK',
LOCK_METAMASK: 'LOCK_METAMASK',
tryUnlockMetamask: tryUnlockMetamask,
@@ -70,6 +96,8 @@ var actions = {
hideWarning: hideWarning,
// accounts screen
SET_SELECTED_ACCOUNT: 'SET_SELECTED_ACCOUNT',
+ SET_SELECTED_TOKEN: 'SET_SELECTED_TOKEN',
+ setSelectedToken,
SHOW_ACCOUNT_DETAIL: 'SHOW_ACCOUNT_DETAIL',
SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE',
SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE',
@@ -80,6 +108,8 @@ var actions = {
// account detail screen
SHOW_SEND_PAGE: 'SHOW_SEND_PAGE',
showSendPage: showSendPage,
+ SHOW_SEND_TOKEN_PAGE: 'SHOW_SEND_TOKEN_PAGE',
+ showSendTokenPage,
ADD_TO_ADDRESS_BOOK: 'ADD_TO_ADDRESS_BOOK',
addToAddressBook: addToAddressBook,
REQUEST_ACCOUNT_EXPORT: 'REQUEST_ACCOUNT_EXPORT',
@@ -88,6 +118,7 @@ var actions = {
exportAccount: exportAccount,
SHOW_PRIVATE_KEY: 'SHOW_PRIVATE_KEY',
showPrivateKey: showPrivateKey,
+ exportAccountComplete,
SAVE_ACCOUNT_LABEL: 'SAVE_ACCOUNT_LABEL',
saveAccountLabel: saveAccountLabel,
// tx conf screen
@@ -95,22 +126,57 @@ var actions = {
TRANSACTION_ERROR: 'TRANSACTION_ERROR',
NEXT_TX: 'NEXT_TX',
PREVIOUS_TX: 'PREV_TX',
+ EDIT_TX: 'EDIT_TX',
signMsg: signMsg,
cancelMsg: cancelMsg,
signPersonalMsg,
cancelPersonalMsg,
signTypedMsg,
cancelTypedMsg,
+ sendTx: sendTx,
signTx: signTx,
+ signTokenTx: signTokenTx,
+ updateTransaction,
updateAndApproveTx,
cancelTx: cancelTx,
completedTx: completedTx,
txError: txError,
nextTx: nextTx,
+ editTx,
previousTx: previousTx,
cancelAllTx: cancelAllTx,
viewPendingTx: viewPendingTx,
VIEW_PENDING_TX: 'VIEW_PENDING_TX',
+ updateTransactionParams,
+ UPDATE_TRANSACTION_PARAMS: 'UPDATE_TRANSACTION_PARAMS',
+ // send screen
+ estimateGas,
+ getGasPrice,
+ UPDATE_GAS_LIMIT: 'UPDATE_GAS_LIMIT',
+ UPDATE_GAS_PRICE: 'UPDATE_GAS_PRICE',
+ UPDATE_GAS_TOTAL: 'UPDATE_GAS_TOTAL',
+ UPDATE_SEND_FROM: 'UPDATE_SEND_FROM',
+ UPDATE_SEND_TOKEN_BALANCE: 'UPDATE_SEND_TOKEN_BALANCE',
+ UPDATE_SEND_TO: 'UPDATE_SEND_TO',
+ UPDATE_SEND_AMOUNT: 'UPDATE_SEND_AMOUNT',
+ UPDATE_SEND_MEMO: 'UPDATE_SEND_MEMO',
+ UPDATE_SEND_ERRORS: 'UPDATE_SEND_ERRORS',
+ UPDATE_MAX_MODE: 'UPDATE_MAX_MODE',
+ UPDATE_SEND: 'UPDATE_SEND',
+ CLEAR_SEND: 'CLEAR_SEND',
+ updateGasLimit,
+ updateGasPrice,
+ updateGasTotal,
+ updateSendTokenBalance,
+ updateSendFrom,
+ updateSendTo,
+ updateSendAmount,
+ updateSendMemo,
+ updateSendErrors,
+ setMaxModeTo,
+ updateSend,
+ clearSend,
+ setSelectedAddress,
// app messages
confirmSeedWords: confirmSeedWords,
showAccountDetail: showAccountDetail,
@@ -127,8 +193,13 @@ var actions = {
SHOW_ADD_TOKEN_PAGE: 'SHOW_ADD_TOKEN_PAGE',
showAddTokenPage,
addToken,
+ addTokens,
+ removeToken,
+ updateTokens,
+ UPDATE_TOKENS: 'UPDATE_TOKENS',
setRpcTarget: setRpcTarget,
setProviderType: setProviderType,
+ updateProviderType,
// loading overlay
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
HIDE_LOADING: 'HIDE_LOADING_INDICATION',
@@ -146,6 +217,8 @@ var actions = {
coinBaseSubview: coinBaseSubview,
SHAPESHIFT_SUBVIEW: 'SHAPESHIFT_SUBVIEW',
shapeShiftSubview: shapeShiftSubview,
+ UPDATE_TOKEN_EXCHANGE_RATE: 'UPDATE_TOKEN_EXCHANGE_RATE',
+ updateTokenExchangeRate,
PAIR_UPDATE: 'PAIR_UPDATE',
pairUpdate: pairUpdate,
coinShiftRquest: coinShiftRquest,
@@ -170,6 +243,28 @@ var actions = {
callBackgroundThenUpdate,
forceUpdateMetamaskState,
+
+ TOGGLE_ACCOUNT_MENU: 'TOGGLE_ACCOUNT_MENU',
+ toggleAccountMenu,
+
+ useEtherscanProvider,
+
+ SET_USE_BLOCKIE: 'SET_USE_BLOCKIE',
+ setUseBlockie,
+
+ // Feature Flags
+ setFeatureFlag,
+ updateFeatureFlags,
+ UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS',
+
+ setMouseUserState,
+ SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
+
+ // Network
+ setNetworkEndpoints,
+ updateNetworkEndpointType,
+ UPDATE_NETWORK_ENDPOINT_TYPE: 'UPDATE_NETWORK_ENDPOINT_TYPE',
+
retryTransaction,
}
@@ -198,6 +293,7 @@ function tryUnlockMetamask (password) {
if (err) {
dispatch(actions.unlockFailed(err.message))
} else {
+ dispatch(actions.unlockSucceeded())
dispatch(actions.transitionForward())
forceUpdateMetamaskState(dispatch)
}
@@ -373,7 +469,24 @@ function navigateToNewAccountScreen () {
function addNewAccount () {
log.debug(`background.addNewAccount`)
- return callBackgroundThenUpdate(background.addNewAccount)
+ return (dispatch, getState) => {
+ const oldIdentities = getState().metamask.identities
+ dispatch(actions.showLoadingIndication())
+ return new Promise((resolve, reject) => {
+ background.addNewAccount((err, { identities: newIdentities}) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ const newAccountAddress = Object.keys(newIdentities).find(address => !oldIdentities[address])
+
+ dispatch(actions.hideLoadingIndication())
+
+ forceUpdateMetamaskState(dispatch)
+ return resolve(newAccountAddress)
+ })
+ })
+ }
}
function showInfoPage () {
@@ -384,16 +497,16 @@ function showInfoPage () {
function setCurrentCurrency (currencyCode) {
return (dispatch) => {
- dispatch(this.showLoadingIndication())
+ dispatch(actions.showLoadingIndication())
log.debug(`background.setCurrentCurrency`)
background.setCurrentCurrency(currencyCode, (err, data) => {
- dispatch(this.hideLoadingIndication())
+ dispatch(actions.hideLoadingIndication())
if (err) {
log.error(err.stack)
return dispatch(actions.displayWarning(err.message))
}
dispatch({
- type: this.SET_CURRENT_FIAT,
+ type: actions.SET_CURRENT_FIAT,
value: {
currentCurrency: data.currentCurrency,
conversionRate: data.conversionRate,
@@ -466,10 +579,170 @@ function signTx (txData) {
dispatch(actions.showLoadingIndication())
global.ethQuery.sendTransaction(txData, (err, data) => {
dispatch(actions.hideLoadingIndication())
- if (err) dispatch(actions.displayWarning(err.message))
- dispatch(this.goHome())
+ if (err) return dispatch(actions.displayWarning(err.message))
+ dispatch(actions.hideWarning())
+ })
+ dispatch(actions.showConfTxPage({}))
+ }
+}
+
+function estimateGas (params = {}) {
+ return (dispatch) => {
+ return new Promise((resolve, reject) => {
+ global.ethQuery.estimateGas(params, (err, data) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ dispatch(actions.hideWarning())
+ dispatch(actions.updateGasLimit(data))
+ return resolve(data)
+ })
+ })
+ }
+}
+
+function updateGasLimit (gasLimit) {
+ return {
+ type: actions.UPDATE_GAS_LIMIT,
+ value: gasLimit,
+ }
+}
+
+function getGasPrice () {
+ return (dispatch) => {
+ return new Promise((resolve, reject) => {
+ global.ethQuery.gasPrice((err, data) => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ dispatch(actions.hideWarning())
+ dispatch(actions.updateGasPrice(data))
+ return resolve(data)
+ })
+ })
+ }
+}
+
+function updateGasPrice (gasPrice) {
+ return {
+ type: actions.UPDATE_GAS_PRICE,
+ value: gasPrice,
+ }
+}
+
+function updateGasTotal (gasTotal) {
+ return {
+ type: actions.UPDATE_GAS_TOTAL,
+ value: gasTotal,
+ }
+}
+
+function updateSendTokenBalance (tokenBalance) {
+ return {
+ type: actions.UPDATE_SEND_TOKEN_BALANCE,
+ value: tokenBalance,
+ }
+}
+
+function updateSendFrom (from) {
+ return {
+ type: actions.UPDATE_SEND_FROM,
+ value: from,
+ }
+}
+
+function updateSendTo (to) {
+ return {
+ type: actions.UPDATE_SEND_TO,
+ value: to,
+ }
+}
+
+function updateSendAmount (amount) {
+ return {
+ type: actions.UPDATE_SEND_AMOUNT,
+ value: amount,
+ }
+}
+
+function updateSendMemo (memo) {
+ return {
+ type: actions.UPDATE_SEND_MEMO,
+ value: memo,
+ }
+}
+
+function updateSendErrors (error) {
+ return {
+ type: actions.UPDATE_SEND_ERRORS,
+ value: error,
+ }
+}
+
+function setMaxModeTo (bool) {
+ return {
+ type: actions.UPDATE_MAX_MODE,
+ value: bool,
+ }
+}
+
+function updateSend (newSend) {
+ return {
+ type: actions.UPDATE_SEND,
+ value: newSend,
+ }
+}
+
+function clearSend () {
+ return {
+ type: actions.CLEAR_SEND,
+ }
+}
+
+
+function sendTx (txData) {
+ log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`)
+ return (dispatch) => {
+ log.debug(`actions calling background.approveTransaction`)
+ background.approveTransaction(txData.id, (err) => {
+ if (err) {
+ dispatch(actions.txError(err))
+ return log.error(err.message)
+ }
+ dispatch(actions.completedTx(txData.id))
+ })
+ }
+}
+
+function signTokenTx (tokenAddress, toAddress, amount, txData) {
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+ const token = global.eth.contract(abi).at(tokenAddress)
+ token.transfer(toAddress, ethUtil.addHexPrefix(amount), txData)
+ .catch(err => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.displayWarning(err.message))
+ })
+ dispatch(actions.showConfTxPage({}))
+ }
+}
+
+function updateTransaction (txData) {
+ log.info('actions: updateTx: ' + JSON.stringify(txData))
+ return (dispatch) => {
+ log.debug(`actions calling background.updateTx`)
+ background.updateTransaction(txData, (err) => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
+ if (err) {
+ dispatch(actions.txError(err))
+ dispatch(actions.goHome())
+ return log.error(err.message)
+ }
+ dispatch(actions.showConfTxPage({ id: txData.id }))
})
- dispatch(actions.showConfTxPage())
}
}
@@ -479,6 +752,8 @@ function updateAndApproveTx (txData) {
log.debug(`actions calling background.updateAndApproveTx`)
background.updateAndApproveTransaction(txData, (err) => {
dispatch(actions.hideLoadingIndication())
+ dispatch(actions.updateTransactionParams(txData.id, txData.txParams))
+ dispatch(actions.clearSend())
if (err) {
dispatch(actions.txError(err))
dispatch(actions.goHome())
@@ -496,6 +771,14 @@ function completedTx (id) {
}
}
+function updateTransactionParams (id, txParams) {
+ return {
+ type: actions.UPDATE_TRANSACTION_PARAMS,
+ id,
+ value: txParams,
+ }
+}
+
function txError (err) {
return {
type: actions.TRANSACTION_ERROR,
@@ -525,6 +808,7 @@ function cancelTx (txData) {
return (dispatch) => {
log.debug(`background.cancelTransaction`)
background.cancelTransaction(txData.id, () => {
+ dispatch(actions.clearSend())
dispatch(actions.completedTx(txData.id))
})
}
@@ -556,6 +840,25 @@ function showRestoreVault () {
}
}
+function markPasswordForgotten () {
+ return (dispatch) => {
+ return background.markPasswordForgotten(() => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch(actions.forgotPassword())
+ forceUpdateMetamaskState(dispatch)
+ })
+ }
+}
+
+function unMarkPasswordForgotten () {
+ return (dispatch) => {
+ return background.unMarkPasswordForgotten(() => {
+ dispatch(actions.forgotPassword())
+ forceUpdateMetamaskState(dispatch)
+ })
+ }
+}
+
function forgotPassword () {
return {
type: actions.FORGOT_PASSWORD,
@@ -574,6 +877,20 @@ function showImportPage () {
}
}
+function showNewAccountPage (formToSelect) {
+ return {
+ type: actions.SHOW_NEW_ACCOUNT_PAGE,
+ formToSelect,
+ }
+}
+
+function setNewAccountForm (formToSelect) {
+ return {
+ type: actions.SET_NEW_ACCOUNT_FORM,
+ formToSelect,
+ }
+}
+
function createNewVaultInProgress () {
return {
type: actions.CREATE_NEW_VAULT_IN_PROGRESS,
@@ -616,6 +933,13 @@ function unlockFailed (message) {
}
}
+function unlockSucceeded (message) {
+ return {
+ type: actions.UNLOCK_SUCCEEDED,
+ value: message,
+ }
+}
+
function unlockMetamask (account) {
return {
type: actions.UNLOCK_METAMASK,
@@ -630,9 +954,54 @@ function updateMetamaskState (newState) {
}
}
+const backgroundSetLocked = () => {
+ return new Promise((resolve, reject) => {
+ background.setLocked(error => {
+ if (error) {
+ return reject(error)
+ }
+
+ resolve()
+ })
+ })
+}
+
+const updateMetamaskStateFromBackground = () => {
+ log.debug(`background.getState`)
+
+ return new Promise((resolve, reject) => {
+ background.getState((error, newState) => {
+ if (error) {
+ return reject(error)
+ }
+
+ resolve(newState)
+ })
+ })
+}
+
function lockMetamask () {
log.debug(`background.setLocked`)
- return callBackgroundThenUpdate(background.setLocked)
+
+ return dispatch => {
+ dispatch(actions.showLoadingIndication())
+
+ return backgroundSetLocked()
+ .then(() => updateMetamaskStateFromBackground())
+ .catch(error => {
+ dispatch(actions.displayWarning(error.message))
+ return Promise.reject(error)
+ })
+ .then(newState => {
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch(actions.hideLoadingIndication())
+ dispatch({ type: actions.LOCK_METAMASK })
+ })
+ .catch(() => {
+ dispatch(actions.hideLoadingIndication())
+ dispatch({ type: actions.LOCK_METAMASK })
+ })
+ }
}
function setCurrentAccountTab (newTabName) {
@@ -640,6 +1009,26 @@ function setCurrentAccountTab (newTabName) {
return callBackgroundThenUpdateNoSpinner(background.setCurrentAccountTab, newTabName)
}
+function setSelectedToken (tokenAddress) {
+ return {
+ type: actions.SET_SELECTED_TOKEN,
+ value: tokenAddress || null,
+ }
+}
+
+function setSelectedAddress (address) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ log.debug(`background.setSelectedAddress`)
+ background.setSelectedAddress(address, (err) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ })
+ }
+}
+
function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
@@ -653,6 +1042,7 @@ function showAccountDetail (address) {
type: actions.SHOW_ACCOUNT_DETAIL,
value: address,
})
+ dispatch(actions.setSelectedToken())
})
}
}
@@ -670,10 +1060,11 @@ function showAccountsPage () {
}
}
-function showConfTxPage (transForward = true) {
+function showConfTxPage ({transForward = true, id}) {
return {
type: actions.SHOW_CONF_TX_PAGE,
- transForward: transForward,
+ transForward,
+ id,
}
}
@@ -696,6 +1087,13 @@ function previousTx () {
}
}
+function editTx (txId) {
+ return {
+ type: actions.EDIT_TX,
+ value: txId,
+ }
+}
+
function showConfigPage (transitionForward = true) {
return {
type: actions.SHOW_CONFIG_PAGE,
@@ -713,18 +1111,64 @@ function showAddTokenPage (transitionForward = true) {
function addToken (address, symbol, decimals) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.addToken(address, symbol, decimals, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- setTimeout(() => {
- dispatch(actions.goHome())
- }, 250)
+ return new Promise((resolve, reject) => {
+ background.addToken(address, symbol, decimals, (err, tokens) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ reject(err)
+ }
+ dispatch(actions.updateTokens(tokens))
+ resolve(tokens)
+ })
})
}
}
+function removeToken (address) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ return new Promise((resolve, reject) => {
+ background.removeToken(address, (err, tokens) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ reject(err)
+ }
+ dispatch(actions.updateTokens(tokens))
+ resolve(tokens)
+ })
+ })
+ }
+}
+
+function addTokens (tokens) {
+ return dispatch => {
+ if (Array.isArray(tokens)) {
+ dispatch(actions.setSelectedToken(getTokenAddressFromTokenObject(tokens[0])))
+ return Promise.all(tokens.map(({ address, symbol, decimals }) => (
+ dispatch(addToken(address, symbol, decimals))
+ )))
+ } else {
+ dispatch(actions.setSelectedToken(getTokenAddressFromTokenObject(tokens)))
+ return Promise.all(
+ Object
+ .entries(tokens)
+ .map(([_, { address, symbol, decimals }]) => (
+ dispatch(addToken(address, symbol, decimals))
+ ))
+ )
+ }
+ }
+}
+
+function updateTokens (newTokens) {
+ return {
+ type: actions.UPDATE_TOKENS,
+ newTokens,
+ }
+}
+
function goBackToInitView () {
return {
type: actions.BACK_TO_INIT_MENU,
@@ -801,11 +1245,17 @@ function setProviderType (type) {
log.error(err)
return dispatch(self.displayWarning('Had a problem changing networks!'))
}
+ dispatch(actions.updateProviderType(type))
+ dispatch(actions.setSelectedToken())
})
- return {
- type: actions.SET_PROVIDER_TYPE,
- value: type,
- }
+
+ }
+}
+
+function updateProviderType (type) {
+ return {
+ type: actions.SET_PROVIDER_TYPE,
+ value: type,
}
}
@@ -822,7 +1272,7 @@ function setRpcTarget (newRpc) {
}
// Calls the addressBookController to add a new address.
-function addToAddressBook (recipient, nickname) {
+function addToAddressBook (recipient, nickname = '') {
log.debug(`background.addToAddressBook`)
return (dispatch) => {
background.setAddressBook(recipient, nickname, (err, result) => {
@@ -834,6 +1284,54 @@ function addToAddressBook (recipient, nickname) {
}
}
+function useEtherscanProvider () {
+ log.debug(`background.useEtherscanProvider`)
+ background.useEtherscanProvider()
+ return {
+ type: actions.USE_ETHERSCAN_PROVIDER,
+ }
+}
+
+function showNetworkDropdown () {
+ return {
+ type: actions.NETWORK_DROPDOWN_OPEN,
+ }
+}
+
+function hideNetworkDropdown () {
+ return {
+ type: actions.NETWORK_DROPDOWN_CLOSE,
+ }
+}
+
+
+function showModal (payload) {
+ return {
+ type: actions.MODAL_OPEN,
+ payload,
+ }
+}
+
+function hideModal (payload) {
+ return {
+ type: actions.MODAL_CLOSE,
+ payload,
+ }
+}
+
+function showSidebar () {
+ return {
+ type: actions.SIDEBAR_OPEN,
+ }
+}
+
+function hideSidebar () {
+ return {
+ type: actions.SIDEBAR_CLOSE,
+ }
+}
+
+
function showLoadingIndication (message) {
return {
type: actions.SHOW_LOADING,
@@ -885,27 +1383,40 @@ function exportAccount (password, address) {
dispatch(self.showLoadingIndication())
log.debug(`background.submitPassword`)
- background.submitPassword(password, function (err) {
- if (err) {
- log.error('Error in submiting password.')
- dispatch(self.hideLoadingIndication())
- return dispatch(self.displayWarning('Incorrect Password.'))
- }
- log.debug(`background.exportAccount`)
- background.exportAccount(address, function (err, result) {
- dispatch(self.hideLoadingIndication())
-
+ return new Promise((resolve, reject) => {
+ background.submitPassword(password, function (err) {
if (err) {
- log.error(err)
- return dispatch(self.displayWarning('Had a problem exporting the account.'))
+ log.error('Error in submiting password.')
+ dispatch(self.hideLoadingIndication())
+ dispatch(self.displayWarning('Incorrect Password.'))
+ return reject(err)
}
+ log.debug(`background.exportAccount`)
+ return background.exportAccount(address, function (err, result) {
+ dispatch(self.hideLoadingIndication())
+
+ if (err) {
+ log.error(err)
+ dispatch(self.displayWarning('Had a problem exporting the account.'))
+ return reject(err)
+ }
+
+ // dispatch(self.exportAccountComplete())
+ dispatch(self.showPrivateKey(result))
- dispatch(self.showPrivateKey(result))
+ return resolve(result)
+ })
})
})
}
}
+function exportAccountComplete () {
+ return {
+ type: actions.EXPORT_ACCOUNT,
+ }
+}
+
function showPrivateKey (key) {
return {
type: actions.SHOW_PRIVATE_KEY,
@@ -917,14 +1428,22 @@ function saveAccountLabel (account, label) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
log.debug(`background.saveAccountLabel`)
- background.saveAccountLabel(account, label, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch({
- type: actions.SAVE_ACCOUNT_LABEL,
- value: { account, label },
+
+ return new Promise((resolve, reject) => {
+ background.saveAccountLabel(account, label, (err) => {
+ dispatch(actions.hideLoadingIndication())
+
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ reject(err)
+ }
+
+ dispatch({
+ type: actions.SAVE_ACCOUNT_LABEL,
+ value: { account, label },
+ })
+
+ resolve(account)
})
})
}
@@ -936,6 +1455,12 @@ function showSendPage () {
}
}
+function showSendTokenPage () {
+ return {
+ type: actions.SHOW_SEND_TOKEN_PAGE,
+ }
+}
+
function buyEth (opts) {
return (dispatch) => {
const url = getBuyEthUrl(opts)
@@ -984,7 +1509,6 @@ function pairUpdate (coin) {
function shapeShiftSubview (network) {
var pair = 'btc_eth'
-
return (dispatch) => {
dispatch(actions.showSubLoadingIndication())
shapeShiftRequest('marketinfo', {pair}, (mktResponse) => {
@@ -1010,7 +1534,7 @@ function coinShiftRquest (data, marketData) {
dispatch(actions.hideLoadingIndication())
if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
- Deposit your ${response.depositType} to the address bellow:`
+ Deposit your ${response.depositType} to the address below:`
log.debug(`background.createShapeShiftTx`)
background.createShapeShiftTx(response.deposit, response.depositType)
dispatch(actions.showQrView(response.deposit, [message].concat(marketData)))
@@ -1046,13 +1570,17 @@ function reshowQrCode (data, coin) {
if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
var message = [
- `Deposit your ${coin} to the address bellow:`,
+ `Deposit your ${coin} to the address below:`,
`Deposit Limit: ${mktResponse.limit}`,
`Deposit Minimum:${mktResponse.minimum}`,
]
dispatch(actions.hideLoadingIndication())
return dispatch(actions.showQrView(data, message))
+ // return dispatch(actions.showModal({
+ // name: 'SHAPESHIFT_DEPOSIT_TX',
+ // Qr: { data, message },
+ // }))
})
}
}
@@ -1086,6 +1614,60 @@ function shapeShiftRequest (query, options, cb) {
}
}
+function updateTokenExchangeRate (token = '') {
+ const pair = `${token.toLowerCase()}_eth`
+
+ return dispatch => {
+ if (!token) {
+ return
+ }
+
+ shapeShiftRequest('marketinfo', { pair }, marketinfo => {
+ if (!marketinfo.error) {
+ dispatch({
+ type: actions.UPDATE_TOKEN_EXCHANGE_RATE,
+ payload: {
+ pair,
+ marketinfo,
+ },
+ })
+ }
+ })
+ }
+}
+
+function setFeatureFlag (feature, activated, notificationType) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ return new Promise((resolve, reject) => {
+ background.setFeatureFlag(feature, activated, (err, updatedFeatureFlags) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+ dispatch(actions.updateFeatureFlags(updatedFeatureFlags))
+ notificationType && dispatch(actions.showModal({ name: notificationType }))
+ resolve(updatedFeatureFlags)
+ })
+ })
+ }
+}
+
+function updateFeatureFlags (updatedFeatureFlags) {
+ return {
+ type: actions.UPDATE_FEATURE_FLAGS,
+ value: updatedFeatureFlags,
+ }
+}
+
+function setMouseUserState (isMouseUser) {
+ return {
+ type: actions.SET_MOUSE_USER_STATE,
+ value: isMouseUser,
+ }
+}
+
// Call Background Then Update
//
// A function generator for a common pattern wherein:
@@ -1127,3 +1709,50 @@ function forceUpdateMetamaskState (dispatch) {
dispatch(actions.updateMetamaskState(newState))
})
}
+
+function toggleAccountMenu () {
+ return {
+ type: actions.TOGGLE_ACCOUNT_MENU,
+ }
+}
+
+function setUseBlockie (val) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ log.debug(`background.setUseBlockie`)
+ background.setUseBlockie(val, (err) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ })
+ dispatch({
+ type: actions.SET_USE_BLOCKIE,
+ value: val,
+ })
+ }
+}
+
+function setNetworkEndpoints (networkEndpointType) {
+ return dispatch => {
+ log.debug('background.setNetworkEndpoints')
+ return new Promise((resolve, reject) => {
+ background.setNetworkEndpoints(networkEndpointType, err => {
+ if (err) {
+ dispatch(actions.displayWarning(err.message))
+ return reject(err)
+ }
+
+ dispatch(actions.updateNetworkEndpointType(networkEndpointType))
+ resolve(networkEndpointType)
+ })
+ })
+ }
+}
+
+function updateNetworkEndpointType (networkEndpointType) {
+ return {
+ type: actions.UPDATE_NETWORK_ENDPOINT_TYPE,
+ value: networkEndpointType,
+ }
+}
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index d5a23c360..3a806d34b 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -1,238 +1,362 @@
const inherits = require('util').inherits
const Component = require('react').Component
+const classnames = require('classnames')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
+const R = require('ramda')
+const Fuse = require('fuse.js')
+const contractMap = require('eth-contract-metadata')
+const TokenBalance = require('./components/token-balance')
+const Identicon = require('./components/identicon')
+const contractList = Object.entries(contractMap)
+ .map(([ _, tokenData]) => tokenData)
+ .filter(tokenData => Boolean(tokenData.erc20))
+const fuse = new Fuse(contractList, {
+ shouldSort: true,
+ threshold: 0.45,
+ location: 0,
+ distance: 100,
+ maxPatternLength: 32,
+ minMatchCharLength: 1,
+ keys: [
+ { name: 'name', weight: 0.5 },
+ { name: 'symbol', weight: 0.5 },
+ ],
+})
const actions = require('./actions')
-const Tooltip = require('./components/tooltip.js')
-
-
const ethUtil = require('ethereumjs-util')
-const abi = require('human-standard-token-abi')
-const Eth = require('ethjs-query')
-const EthContract = require('ethjs-contract')
+const { tokenInfoGetter } = require('./token-util')
const emptyAddr = '0x0000000000000000000000000000000000000000'
-module.exports = connect(mapStateToProps)(AddTokenScreen)
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AddTokenScreen)
function mapStateToProps (state) {
+ const { identities, tokens } = state.metamask
return {
- identities: state.metamask.identities,
+ identities,
+ tokens,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ addTokens: tokens => dispatch(actions.addTokens(tokens)),
}
}
inherits(AddTokenScreen, Component)
function AddTokenScreen () {
this.state = {
- warning: null,
- address: '',
- symbol: 'TOKEN',
- decimals: 18,
+ isShowingConfirmation: false,
+ customAddress: '',
+ customSymbol: '',
+ customDecimals: 0,
+ searchQuery: '',
+ isCollapsed: true,
+ selectedTokens: {},
+ errors: {},
}
+ this.tokenAddressDidChange = this.tokenAddressDidChange.bind(this)
+ this.onNext = this.onNext.bind(this)
Component.call(this)
}
-AddTokenScreen.prototype.render = function () {
- const state = this.state
- const props = this.props
- const { warning, symbol, decimals } = state
-
- return (
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- props.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Add Token'),
- ]),
-
- h('.error', {
- style: {
- display: warning ? 'block' : 'none',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, warning),
-
- // conf view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
-
- h('div', [
- h(Tooltip, {
- position: 'top',
- title: 'The contract of the actual token contract. Click for more info.',
- }, [
- h('a', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- href: 'https://support.metamask.io/kb/article/24-what-is-a-token-contract-address',
- target: '_blank',
- }, [
- h('span', 'Token Contract Address '),
- h('i.fa.fa-question-circle'),
- ]),
- ]),
- ]),
-
- h('section.flex-row.flex-center', [
- h('input#token-address', {
- name: 'address',
- placeholder: 'Token Contract Address',
- onChange: this.tokenAddressDidChange.bind(this),
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- }),
- ]),
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Symbol'),
- ]),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#token_symbol', {
- placeholder: `Like "ETH"`,
- value: symbol,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var symbol = element.value
- this.setState({ symbol })
- },
- }),
- ]),
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Decimals of Precision'),
- ]),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#token_decimals', {
- value: decimals,
- type: 'number',
- min: 0,
- max: 36,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var decimals = element.value.trim()
- this.setState({ decimals })
- },
- }),
- ]),
-
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick: (event) => {
- const valid = this.validateInputs()
- if (!valid) return
+AddTokenScreen.prototype.componentWillMount = function () {
+ this.tokenInfoGetter = tokenInfoGetter()
+}
- const { address, symbol, decimals } = this.state
- this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
- },
- }, 'Add'),
- ]),
- ]),
- ])
- )
+AddTokenScreen.prototype.toggleToken = function (address, token) {
+ const { selectedTokens, errors } = this.state
+ const { [address]: selectedToken } = selectedTokens
+ this.setState({
+ selectedTokens: {
+ ...selectedTokens,
+ [address]: selectedToken ? null : token,
+ },
+ errors: {
+ ...errors,
+ tokenSelector: null,
+ },
+ })
}
-AddTokenScreen.prototype.componentWillMount = function () {
- if (typeof global.ethereumProvider === 'undefined') return
+AddTokenScreen.prototype.onNext = function () {
+ const { isValid, errors } = this.validate()
- this.eth = new Eth(global.ethereumProvider)
- this.contract = new EthContract(this.eth)
- this.TokenContract = this.contract(abi)
+ return !isValid
+ ? this.setState({ errors })
+ : this.setState({ isShowingConfirmation: true })
}
-AddTokenScreen.prototype.tokenAddressDidChange = function (event) {
- const el = event.target
- const address = el.value.trim()
- if (ethUtil.isValidAddress(address) && address !== emptyAddr) {
- this.setState({ address })
- this.attemptToAutoFillTokenParams(address)
+AddTokenScreen.prototype.tokenAddressDidChange = function (e) {
+ const customAddress = e.target.value.trim()
+ this.setState({ customAddress })
+ if (ethUtil.isValidAddress(customAddress) && customAddress !== emptyAddr) {
+ this.attemptToAutoFillTokenParams(customAddress)
+ } else {
+ this.setState({
+ customSymbol: '',
+ customDecimals: 0,
+ })
}
}
-AddTokenScreen.prototype.validateInputs = function () {
- let msg = ''
- const state = this.state
- const identitiesList = Object.keys(this.props.identities)
- const { address, symbol, decimals } = state
- const standardAddress = ethUtil.addHexPrefix(address).toLowerCase()
-
- const validAddress = ethUtil.isValidAddress(address)
- if (!validAddress) {
- msg += 'Address is invalid.'
+AddTokenScreen.prototype.checkExistingAddresses = function (address) {
+ if (!address) return false
+ const tokensList = this.props.tokens
+ const matchesAddress = existingToken => {
+ return existingToken.address.toLowerCase() === address.toLowerCase()
}
- const validDecimals = decimals >= 0 && decimals < 36
- if (!validDecimals) {
- msg += 'Decimals must be at least 0, and not over 36. '
- }
+ return R.any(matchesAddress)(tokensList)
+}
- const symbolLen = symbol.trim().length
- const validSymbol = symbolLen > 0 && symbolLen < 10
- if (!validSymbol) {
- msg += 'Symbol must be between 0 and 10 characters.'
+AddTokenScreen.prototype.validate = function () {
+ const errors = {}
+ const identitiesList = Object.keys(this.props.identities)
+ const { customAddress, customSymbol, customDecimals, selectedTokens } = this.state
+ const standardAddress = ethUtil.addHexPrefix(customAddress).toLowerCase()
+
+ if (customAddress) {
+ const validAddress = ethUtil.isValidAddress(customAddress)
+ if (!validAddress) {
+ errors.customAddress = 'Address is invalid. '
+ }
+
+ const validDecimals = customDecimals >= 0 && customDecimals < 36
+ if (!validDecimals) {
+ errors.customDecimals = 'Decimals must be at least 0, and not over 36.'
+ }
+
+ const symbolLen = customSymbol.trim().length
+ const validSymbol = symbolLen > 0 && symbolLen < 10
+ if (!validSymbol) {
+ errors.customSymbol = 'Symbol must be between 0 and 10 characters.'
+ }
+
+ const ownAddress = identitiesList.includes(standardAddress)
+ if (ownAddress) {
+ errors.customAddress = 'Personal address detected. Input the token contract address.'
+ }
+
+ const tokenAlreadyAdded = this.checkExistingAddresses(customAddress)
+ if (tokenAlreadyAdded) {
+ errors.customAddress = 'Token has already been added.'
+ }
+ } else if (
+ Object.entries(selectedTokens)
+ .reduce((isEmpty, [ symbol, isSelected ]) => (
+ isEmpty && !isSelected
+ ), true)
+ ) {
+ errors.tokenSelector = 'Must select at least 1 token.'
}
- const ownAddress = identitiesList.includes(standardAddress)
- if (ownAddress) {
- msg = 'Personal address detected. Input the token contract address.'
+ return {
+ isValid: !Object.keys(errors).length,
+ errors,
}
+}
- const isValid = validAddress && validDecimals && !ownAddress
-
- if (!isValid) {
+AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) {
+ const { symbol, decimals } = await this.tokenInfoGetter(address)
+ if (symbol && decimals) {
this.setState({
- warning: msg,
+ customSymbol: symbol,
+ customDecimals: decimals.toString(),
})
- } else {
- this.setState({ warning: null })
}
+}
+
+AddTokenScreen.prototype.renderCustomForm = function () {
+ const { customAddress, customSymbol, customDecimals, errors } = this.state
- return isValid
+ return !this.state.isCollapsed && (
+ h('div.add-token__add-custom-form', [
+ h('div', {
+ className: classnames('add-token__add-custom-field', {
+ 'add-token__add-custom-field--error': errors.customAddress,
+ }),
+ }, [
+ h('div.add-token__add-custom-label', 'Token Address'),
+ h('input.add-token__add-custom-input', {
+ type: 'text',
+ onChange: this.tokenAddressDidChange,
+ value: customAddress,
+ }),
+ h('div.add-token__add-custom-error-message', errors.customAddress),
+ ]),
+ h('div', {
+ className: classnames('add-token__add-custom-field', {
+ 'add-token__add-custom-field--error': errors.customSymbol,
+ }),
+ }, [
+ h('div.add-token__add-custom-label', 'Token Symbol'),
+ h('input.add-token__add-custom-input', {
+ type: 'text',
+ value: customSymbol,
+ disabled: true,
+ }),
+ h('div.add-token__add-custom-error-message', errors.customSymbol),
+ ]),
+ h('div', {
+ className: classnames('add-token__add-custom-field', {
+ 'add-token__add-custom-field--error': errors.customDecimals,
+ }),
+ }, [
+ h('div.add-token__add-custom-label', 'Decimals of Precision'),
+ h('input.add-token__add-custom-input', {
+ type: 'number',
+ value: customDecimals,
+ disabled: true,
+ }),
+ h('div.add-token__add-custom-error-message', errors.customDecimals),
+ ]),
+ ])
+ )
}
-AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) {
- const contract = this.TokenContract.at(address)
+AddTokenScreen.prototype.renderTokenList = function () {
+ const { searchQuery = '', selectedTokens } = this.state
+ const fuseSearchResult = fuse.search(searchQuery)
+ const addressSearchResult = contractList.filter(token => {
+ return token.address.toLowerCase() === searchQuery.toLowerCase()
+ })
+ const results = [...addressSearchResult, ...fuseSearchResult]
+
+ return Array(6).fill(undefined)
+ .map((_, i) => {
+ const { logo, symbol, name, address } = results[i] || {}
+ const tokenAlreadyAdded = this.checkExistingAddresses(address)
+ return Boolean(logo || symbol || name) && (
+ h('div.add-token__token-wrapper', {
+ className: classnames({
+ 'add-token__token-wrapper--selected': selectedTokens[address],
+ 'add-token__token-wrapper--disabled': tokenAlreadyAdded,
+ }),
+ onClick: () => !tokenAlreadyAdded && this.toggleToken(address, results[i]),
+ }, [
+ h('div.add-token__token-icon', {
+ style: {
+ backgroundImage: `url(images/contract/${logo})`,
+ },
+ }),
+ h('div.add-token__token-data', [
+ h('div.add-token__token-symbol', symbol),
+ h('div.add-token__token-name', name),
+ ]),
+ // tokenAlreadyAdded && (
+ // h('div.add-token__token-message', 'Already added')
+ // ),
+ ])
+ )
+ })
+}
- const results = await Promise.all([
- contract.symbol(),
- contract.decimals(),
- ])
+AddTokenScreen.prototype.renderConfirmation = function () {
+ const {
+ customAddress: address,
+ customSymbol: symbol,
+ customDecimals: decimals,
+ selectedTokens,
+ } = this.state
- const [ symbol, decimals ] = results
- if (symbol && decimals) {
- console.log('SETTING SYMBOL AND DECIMALS', { symbol, decimals })
- this.setState({ symbol: symbol[0], decimals: decimals[0].toString() })
+ const { addTokens, goHome } = this.props
+
+ const customToken = {
+ address,
+ symbol,
+ decimals,
}
+
+ const tokens = address && symbol && decimals
+ ? { ...selectedTokens, [address]: customToken }
+ : selectedTokens
+
+ return (
+ h('div.add-token', [
+ h('div.add-token__wrapper', [
+ h('div.add-token__title-container.add-token__confirmation-title', [
+ h('div.add-token__title', 'Add Token'),
+ h('div.add-token__description', 'Would you like to add these tokens?'),
+ ]),
+ h('div.add-token__content-container.add-token__confirmation-content', [
+ h('div.add-token__description.add-token__confirmation-description', 'Your balances'),
+ h('div.add-token__confirmation-token-list',
+ Object.entries(tokens)
+ .map(([ address, token ]) => (
+ h('span.add-token__confirmation-token-list-item', [
+ h(Identicon, {
+ className: 'add-token__confirmation-token-icon',
+ diameter: 75,
+ address,
+ }),
+ h(TokenBalance, { token }),
+ ])
+ ))
+ ),
+ ]),
+ ]),
+ h('div.add-token__buttons', [
+ h('button.btn-cancel.add-token__button', {
+ onClick: () => this.setState({ isShowingConfirmation: false }),
+ }, 'Back'),
+ h('button.btn-clear.add-token__button', {
+ onClick: () => addTokens(tokens).then(goHome),
+ }, 'Add Tokens'),
+ ]),
+ ])
+ )
+}
+
+AddTokenScreen.prototype.render = function () {
+ const { isCollapsed, errors, isShowingConfirmation } = this.state
+ const { goHome } = this.props
+
+ return isShowingConfirmation
+ ? this.renderConfirmation()
+ : (
+ h('div.add-token', [
+ h('div.add-token__wrapper', [
+ h('div.add-token__title-container', [
+ h('div.add-token__title', 'Add Token'),
+ h('div.add-token__description', 'Keep track of the tokens you’ve bought with your MetaMask account. If you bought tokens using a different account, those tokens will not appear here.'),
+ h('div.add-token__description', 'Search for tokens or select from our list of popular tokens.'),
+ ]),
+ h('div.add-token__content-container', [
+ h('div.add-token__input-container', [
+ h('input.add-token__input', {
+ type: 'text',
+ placeholder: 'Search',
+ onChange: e => this.setState({ searchQuery: e.target.value }),
+ }),
+ h('div.add-token__search-input-error-message', errors.tokenSelector),
+ ]),
+ h(
+ 'div.add-token__token-icons-container',
+ this.renderTokenList(),
+ ),
+ ]),
+ h('div.add-token__footers', [
+ h('div.add-token__add-custom', {
+ onClick: () => this.setState({ isCollapsed: !isCollapsed }),
+ }, [
+ 'Add custom token',
+ h(`i.fa.fa-angle-${isCollapsed ? 'down' : 'up'}`),
+ ]),
+ this.renderCustomForm(),
+ ]),
+ ]),
+ h('div.add-token__buttons', [
+ h('button.btn-cancel.add-token__button', {
+ onClick: goHome,
+ }, 'Cancel'),
+ h('button.btn-clear.add-token__button', {
+ onClick: this.onNext,
+ }, 'Next'),
+ ]),
+ ])
+ )
}
diff --git a/ui/app/app.js b/ui/app/app.js
index f0dfef34f..58e38a077 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -3,39 +3,47 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('./actions')
+const classnames = require('classnames')
+
// mascara
const MascaraFirstTime = require('../../mascara/src/app/first-time').default
const MascaraBuyEtherScreen = require('../../mascara/src/app/first-time/buy-ether-screen').default
// init
-const InitializeMenuScreen = require('./first-time/init-menu')
+const OldUIInitializeMenuScreen = require('./first-time/init-menu')
+const InitializeMenuScreen = MascaraFirstTime
const NewKeyChainScreen = require('./new-keychain')
-// unlock
-const UnlockScreen = require('./unlock')
// accounts
-const AccountDetailScreen = require('./account-detail')
-const SendTransactionScreen = require('./send')
+const MainContainer = require('./main-container')
+const SendTransactionScreen2 = require('./components/send/send-v2-container')
const ConfirmTxScreen = require('./conf-tx')
// notice
const NoticeScreen = require('./components/notice')
const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
+
+// slideout menu
+const WalletView = require('./components/wallet-view')
+
// other views
-const ConfigScreen = require('./config')
+const Settings = require('./settings')
const AddTokenScreen = require('./add-token')
const Import = require('./accounts/import')
-const InfoScreen = require('./info')
+const NewAccount = require('./accounts/new-account')
const Loading = require('./components/loading')
-const SandwichExpando = require('sandwich-expando')
-const Dropdown = require('./components/dropdown').Dropdown
-const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
const NetworkIndicator = require('./components/network')
+const Identicon = require('./components/identicon')
const BuyView = require('./components/buy-button-subview')
-const QrView = require('./components/qr-code')
const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
-const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
+const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
+const NetworkDropdown = require('./components/dropdowns/network-dropdown')
+const AccountMenu = require('./components/account-menu')
+const QrView = require('./components/qr-code')
+
+// Global Modals
+const Modal = require('./components/modals/index').Modal
-module.exports = connect(mapStateToProps)(App)
+module.exports = connect(mapStateToProps, mapDispatchToProps)(App)
inherits(App, Component)
function App () { Component.call(this) }
@@ -54,26 +62,33 @@ function mapStateToProps (state) {
return {
// state from plugin
+ networkDropdownOpen: state.appState.networkDropdownOpen,
+ sidebarOpen: state.appState.sidebarOpen,
isLoading: state.appState.isLoading,
loadingMessage: state.appState.loadingMessage,
noActiveNotices: state.metamask.noActiveNotices,
isInitialized: state.metamask.isInitialized,
isUnlocked: state.metamask.isUnlocked,
+ selectedAddress: state.metamask.selectedAddress,
currentView: state.appState.currentView,
activeAddress: state.appState.activeAddress,
transForward: state.appState.transForward,
isMascara: state.metamask.isMascara,
isOnboarding: Boolean(!noActiveNotices || seedWords || !isInitialized),
+ isPopup: state.metamask.isPopup,
seedWords: state.metamask.seedWords,
unapprovedTxs: state.metamask.unapprovedTxs,
unapprovedMsgs: state.metamask.unapprovedMsgs,
menuOpen: state.appState.menuOpen,
network: state.metamask.network,
provider: state.metamask.provider,
- forgottenPassword: state.appState.forgottenPassword,
+ forgottenPassword: state.metamask.forgottenPassword,
lastUnreadNotice: state.metamask.lastUnreadNotice,
lostAccounts: state.metamask.lostAccounts,
frequentRpcList: state.metamask.frequentRpcList || [],
+ currentCurrency: state.metamask.currentCurrency,
+ isMouseUser: state.appState.isMouseUser,
+ betaUI: state.metamask.featureFlags.betaUI,
// state needed to get account dropdown temporarily rendering from app bar
identities,
@@ -82,52 +97,155 @@ function mapStateToProps (state) {
}
}
+function mapDispatchToProps (dispatch, ownProps) {
+ return {
+ dispatch,
+ hideSidebar: () => dispatch(actions.hideSidebar()),
+ showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
+ hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
+ setCurrentCurrencyToUSD: () => dispatch(actions.setCurrentCurrency('usd')),
+ toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
+ setMouseUserState: (isMouseUser) => dispatch(actions.setMouseUserState(isMouseUser)),
+ }
+}
+
+App.prototype.componentWillMount = function () {
+ if (!this.props.currentCurrency) {
+ this.props.setCurrentCurrencyToUSD()
+ }
+}
+
App.prototype.render = function () {
var props = this.props
- const { isLoading, loadingMessage, transForward, network } = props
+ const {
+ isLoading,
+ loadingMessage,
+ network,
+ isMouseUser,
+ setMouseUserState,
+ } = props
const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
const loadMessage = loadingMessage || isLoadingNetwork ?
`Connecting to ${this.getNetworkName()}` : null
log.debug('Main ui render function')
return (
-
h('.flex-column.full-height', {
+ className: classnames({ 'mouse-user-styles': isMouseUser }),
style: {
- // Windows was showing a vertical scroll bar:
- overflow: 'hidden',
+ overflowX: 'hidden',
position: 'relative',
alignItems: 'center',
},
+ tabIndex: '0',
+ onClick: () => setMouseUserState(true),
+ onKeyDown: (e) => {
+ if (e.keyCode === 9) {
+ setMouseUserState(false)
+ }
+ },
}, [
+ // global modal
+ h(Modal, {}, []),
+
// app bar
this.renderAppBar(),
- this.renderNetworkDropdown(),
- this.renderDropdown(),
- this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
+ // sidebar
+ this.renderSidebar(),
- // panel content
- h('.app-primary' + (transForward ? '.from-right' : '.from-left'), {
- style: {
- width: '100%',
- },
- }, [
- this.renderPrimary(),
- ]),
+ // network dropdown
+ h(NetworkDropdown, {
+ provider: this.props.provider,
+ frequentRpcList: this.props.frequentRpcList,
+ }, []),
+
+ h(AccountMenu),
+
+ (isLoading || isLoadingNetwork) && h(Loading, {
+ loadingMessage: loadMessage,
+ }),
+
+ // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }),
+
+ // content
+ this.renderPrimary(),
])
)
}
+App.prototype.renderGlobalModal = function () {
+ return h(Modal, {
+ ref: 'modalRef',
+ }, [
+ // h(BuyOptions, {}, []),
+ ])
+}
+
+App.prototype.renderSidebar = function () {
+
+ return h('div', {
+ }, [
+ h('style', `
+ .sidebar-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(-100%);
+ }
+ .sidebar-enter.sidebar-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+ }
+ .sidebar-leave.sidebar-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(-100%);
+ }
+ `),
+
+ h(ReactCSSTransitionGroup, {
+ transitionName: 'sidebar',
+ transitionEnterTimeout: 300,
+ transitionLeaveTimeout: 200,
+ }, [
+ // A second instance of Walletview is used for non-mobile viewports
+ this.props.sidebarOpen ? h(WalletView, {
+ responsiveDisplayClassname: '.sidebar',
+ style: {},
+ }) : undefined,
+
+ ]),
+
+ // overlay
+ // TODO: add onClick for overlay to close sidebar
+ this.props.sidebarOpen ? h('div.sidebar-overlay', {
+ style: {},
+ onClick: () => {
+ this.props.hideSidebar()
+ },
+ }, []) : undefined,
+ ])
+}
+
App.prototype.renderAppBar = function () {
+ const {
+ isUnlocked,
+ network,
+ provider,
+ networkDropdownOpen,
+ showNetworkDropdown,
+ hideNetworkDropdown,
+ currentView,
+ } = this.props
+
if (window.METAMASK_UI_TYPE === 'notification') {
return null
}
const props = this.props
- const state = this.state || {}
- const isNetworkMenuOpen = state.isNetworkMenuOpen || false
const {isMascara, isOnboarding} = props
// Do not render header if user is in mascara onboarding
@@ -143,267 +261,66 @@ App.prototype.renderAppBar = function () {
return (
h('.full-width', {
- height: '38px',
+ style: {},
}, [
h('.app-header.flex-row.flex-space-between', {
- style: {
- alignItems: 'center',
- visibility: props.isUnlocked ? 'visible' : 'none',
- background: props.isUnlocked ? 'white' : 'none',
- height: '38px',
- position: 'relative',
- zIndex: 12,
- },
+ className: classnames({
+ 'app-header--initialized': !isOnboarding,
+ }),
}, [
-
- h('div.left-menu-section', {
- style: {
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- },
- }, [
-
- // mini logo
- h('img', {
- height: 24,
- width: 24,
- src: '/images/icon-128.png',
- }),
-
- h(NetworkIndicator, {
- network: this.props.network,
- provider: this.props.provider,
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
- },
- }),
- ]),
-
- props.isUnlocked && h('div', {
- style: {
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- },
- }, [
-
- props.isUnlocked && h(AccountDropdowns, {
- style: {},
- enableAccountsSelector: true,
- identities: this.props.identities,
- selected: this.props.currentView.context,
- network: this.props.network,
- keyrings: this.props.keyrings,
- }, []),
-
- // hamburger
- props.isUnlocked && h(SandwichExpando, {
- className: 'sandwich-expando',
- width: 16,
- barHeight: 2,
- padding: 0,
- isOpen: state.isMainMenuOpen,
- color: 'rgb(247,146,30)',
+ h('div.app-header-contents', {}, [
+ h('div.left-menu-wrapper', {
onClick: () => {
- this.setState({
- isMainMenuOpen: !state.isMainMenuOpen,
- })
+ props.dispatch(actions.backToAccountDetail(props.activeAddress))
},
- }),
+ }, [
+ // mini logo
+ h('img.metafox-icon', {
+ height: 42,
+ width: 42,
+ src: '/images/metamask-fox.svg',
+ }),
+
+ // metamask name
+ h('h1', 'MetaMask'),
+
+ ]),
+
+ h('div.header__right-actions', [
+ h('div.network-component-wrapper', {
+ style: {},
+ }, [
+ // Network Indicator
+ h(NetworkIndicator, {
+ network,
+ provider,
+ disabled: currentView.name === 'confTx',
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ return networkDropdownOpen === false
+ ? showNetworkDropdown()
+ : hideNetworkDropdown()
+ },
+ }),
+
+ ]),
+
+ isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [
+ h(Identicon, {
+ address: this.props.selectedAddress,
+ diameter: 32,
+ }),
+ ]),
+ ]),
]),
]),
+
])
)
}
-App.prototype.renderNetworkDropdown = function () {
- const props = this.props
- const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
- const rpcList = props.frequentRpcList
- const state = this.state || {}
- const isOpen = state.isNetworkMenuOpen
-
- return h(Dropdown, {
- useCssTransition: true,
- isOpen,
- onClickOutside: (event) => {
- const { classList } = event.target
- const isNotToggleElement = [
- classList.contains('menu-icon'),
- classList.contains('network-name'),
- classList.contains('network-indicator'),
- ].filter(bool => bool).length === 0
- // classes from three constituent nodes of the toggle element
-
- if (isNotToggleElement) {
- this.setState({ isNetworkMenuOpen: false })
- }
- },
- zIndex: 11,
- style: {
- position: 'absolute',
- left: '2px',
- top: '36px',
- },
- innerStyle: {
- padding: '2px 16px 2px 0px',
- },
- }, [
-
- h(
- DropdownMenuItem,
- {
- key: 'main',
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('mainnet')),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('.menu-icon.diamond'),
- 'Main Ethereum Network',
- providerType === 'mainnet' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- key: 'ropsten',
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('ropsten')),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('.menu-icon.red-dot'),
- 'Ropsten Test Network',
- providerType === 'ropsten' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- key: 'kovan',
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('kovan')),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('.menu-icon.hollow-diamond'),
- 'Kovan Test Network',
- providerType === 'kovan' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- key: 'rinkeby',
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('rinkeby')),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('.menu-icon.golden-square'),
- 'Rinkeby Test Network',
- providerType === 'rinkeby' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- key: 'default',
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('localhost')),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- 'Localhost 8545',
- activeNetwork === 'http://localhost:8545' ? h('.check', '✓') : null,
- ]
- ),
-
- this.renderCustomOption(props.provider),
- this.renderCommonRpc(rpcList, props.provider),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => this.props.dispatch(actions.showConfigPage()),
- style: {
- fontSize: '18px',
- },
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- 'Custom RPC',
- activeNetwork === 'custom' ? h('.check', '✓') : null,
- ]
- ),
-
- ])
-}
-
-App.prototype.renderDropdown = function () {
- const state = this.state || {}
- const isOpen = state.isMainMenuOpen
-
- return h(Dropdown, {
- useCssTransition: true,
- isOpen: isOpen,
- zIndex: 11,
- onClickOutside: (event) => {
- const classList = event.target.classList
- const parentClassList = event.target.parentElement.classList
-
- const isToggleElement = classList.contains('sandwich-expando') ||
- parentClassList.contains('sandwich-expando')
-
- if (isOpen && !isToggleElement) {
- this.setState({ isMainMenuOpen: false })
- }
- },
- style: {
- position: 'absolute',
- right: '2px',
- top: '38px',
- },
- innerStyle: {},
- }, [
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.showConfigPage()) },
- }, 'Settings'),
-
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.lockMetamask()) },
- }, 'Log Out'),
-
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.showInfoPage()) },
- }, 'Info/Help'),
- ])
-}
-
App.prototype.renderLoadingIndicator = function ({ isLoading, isLoadingNetwork, loadMessage }) {
const { isMascara } = this.props
@@ -437,9 +354,9 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
App.prototype.renderPrimary = function () {
log.debug('rendering primary')
var props = this.props
- const {isMascara, isOnboarding} = props
+ const {isMascara, isOnboarding, betaUI} = props
- if (isMascara && isOnboarding) {
+ if ((isMascara || betaUI) && isOnboarding && !props.isPopup) {
return h(MascaraFirstTime)
}
@@ -460,38 +377,22 @@ App.prototype.renderPrimary = function () {
})
}
- // show initialize screen
- if (!props.isInitialized || props.forgottenPassword) {
- // show current view
- log.debug('rendering an initialize screen')
- switch (props.currentView.name) {
-
- case 'restoreVault':
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
-
- default:
- log.debug('rendering menu screen')
- return h(InitializeMenuScreen, {key: 'menuScreenInit'})
- }
+ if (props.isInitialized && props.forgottenPassword) {
+ log.debug('rendering restore vault screen')
+ return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+ } else if (!props.isInitialized && !props.isUnlocked) {
+ log.debug('rendering menu screen')
+ return props.isPopup
+ ? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'})
+ : h(InitializeMenuScreen, {key: 'menuScreenInit'})
}
// show unlock screen
if (!props.isUnlocked) {
- switch (props.currentView.name) {
-
- case 'restoreVault':
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
-
- case 'config':
- log.debug('rendering config screen from unlock screen.')
- return h(ConfigScreen, {key: 'config'})
-
- default:
- log.debug('rendering locked screen')
- return h(UnlockScreen, {key: 'locked'})
- }
+ return h(MainContainer, {
+ currentViewName: props.currentView.name,
+ isUnlocked: props.isUnlocked,
+ })
}
// show seed words screen
@@ -504,12 +405,28 @@ App.prototype.renderPrimary = function () {
switch (props.currentView.name) {
case 'accountDetail':
- log.debug('rendering account detail screen')
- return h(AccountDetailScreen, {key: 'account-detail'})
+ log.debug('rendering main container')
+ return h(MainContainer, {key: 'account-detail'})
case 'sendTransaction':
log.debug('rendering send tx screen')
- return h(SendTransactionScreen, {key: 'send-transaction'})
+
+ // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // const SendComponentToRender = checkFeatureToggle('send-v2')
+ // ? SendTransactionScreen2
+ // : SendTransactionScreen
+
+ return h(SendTransactionScreen2, {key: 'send-transaction'})
+
+ case 'sendToken':
+ log.debug('rendering send token screen')
+
+ // Going to leave this here until we are ready to delete SendTransactionScreen v1
+ // const SendTokenComponentToRender = checkFeatureToggle('send-v2')
+ // ? SendTransactionScreen2
+ // : SendTokenScreen
+
+ return h(SendTransactionScreen2, {key: 'sendToken'})
case 'newKeychain':
log.debug('rendering new keychain screen')
@@ -525,19 +442,23 @@ App.prototype.renderPrimary = function () {
case 'config':
log.debug('rendering config screen')
- return h(ConfigScreen, {key: 'config'})
+ return h(Settings, {key: 'config'})
case 'import-menu':
log.debug('rendering import screen')
return h(Import, {key: 'import-menu'})
+ case 'new-account-page':
+ log.debug('rendering new account screen')
+ return h(NewAccount, {key: 'new-account'})
+
case 'reveal-seed-conf':
log.debug('rendering reveal seed confirmation screen')
return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
case 'info':
log.debug('rendering info screen')
- return h(InfoScreen, {key: 'info'})
+ return h(Settings, {key: 'info', tab: 'info'})
case 'buyEth':
log.debug('rendering buy ether screen')
@@ -577,7 +498,7 @@ App.prototype.renderPrimary = function () {
default:
log.debug('rendering default, account detail screen')
- return h(AccountDetailScreen, {key: 'account-detail'})
+ return h(MainContainer, {key: 'account-detail'})
}
}
@@ -593,40 +514,6 @@ App.prototype.toggleMetamaskActive = function () {
}
}
-App.prototype.renderCustomOption = function (provider) {
- const { rpcTarget, type } = provider
- const props = this.props
-
- if (type !== 'rpc') return null
-
- // Concatenate long URLs
- let label = rpcTarget
- if (rpcTarget.length > 31) {
- label = label.substr(0, 34) + '...'
- }
-
- switch (rpcTarget) {
-
- case 'http://localhost:8545':
- return null
-
- default:
- return h(
- DropdownMenuItem,
- {
- key: rpcTarget,
- onClick: () => props.dispatch(actions.setRpcTarget(rpcTarget)),
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- label,
- h('.check', '✓'),
- ]
- )
- }
-}
-
App.prototype.getNetworkName = function () {
const { provider } = this.props
const providerName = provider.type
@@ -647,28 +534,3 @@ App.prototype.getNetworkName = function () {
return name
}
-
-App.prototype.renderCommonRpc = function (rpcList, provider) {
- const props = this.props
- const rpcTarget = provider.rpcTarget
-
- return rpcList.map((rpc) => {
- if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
- return null
- } else {
- return h(
- DropdownMenuItem,
- {
- key: `common${rpc}`,
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- onClick: () => props.dispatch(actions.setRpcTarget(rpc)),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- rpc,
- rpcTarget === rpc ? h('.check', '✓') : null,
- ]
- )
- }
- })
-}
diff --git a/ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index 0c34a5154..f69a6ca68 100644
--- a/ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
@@ -1,5 +1,5 @@
const Component = require('react').Component
-const PropTypes = require('react').PropTypes
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const actions = require('../actions')
const genAccountLink = require('etherscan-link').createAccountLink
diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js
new file mode 100644
index 000000000..1a0103d4f
--- /dev/null
+++ b/ui/app/components/account-menu/index.js
@@ -0,0 +1,160 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const actions = require('../../actions')
+const { Menu, Item, Divider, CloseArea } = require('../dropdowns/components/menu')
+const Identicon = require('../identicon')
+const { formatBalance } = require('../../util')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountMenu)
+
+inherits(AccountMenu, Component)
+function AccountMenu () { Component.call(this) }
+
+function mapStateToProps (state) {
+ return {
+ selectedAddress: state.metamask.selectedAddress,
+ isAccountMenuOpen: state.metamask.isAccountMenuOpen,
+ keyrings: state.metamask.keyrings,
+ identities: state.metamask.identities,
+ accounts: state.metamask.accounts,
+
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ toggleAccountMenu: () => dispatch(actions.toggleAccountMenu()),
+ showAccountDetail: address => {
+ dispatch(actions.showAccountDetail(address))
+ dispatch(actions.hideSidebar())
+ dispatch(actions.toggleAccountMenu())
+ },
+ lockMetamask: () => {
+ dispatch(actions.lockMetamask())
+ dispatch(actions.hideWarning())
+ dispatch(actions.hideSidebar())
+ dispatch(actions.toggleAccountMenu())
+ },
+ showConfigPage: () => {
+ dispatch(actions.showConfigPage())
+ dispatch(actions.hideSidebar())
+ dispatch(actions.toggleAccountMenu())
+ },
+ showNewAccountPage: (formToSelect) => {
+ dispatch(actions.showNewAccountPage(formToSelect))
+ dispatch(actions.hideSidebar())
+ dispatch(actions.toggleAccountMenu())
+ },
+ showInfoPage: () => {
+ dispatch(actions.showInfoPage())
+ dispatch(actions.hideSidebar())
+ dispatch(actions.toggleAccountMenu())
+ },
+ }
+}
+
+AccountMenu.prototype.render = function () {
+ const {
+ isAccountMenuOpen,
+ toggleAccountMenu,
+ showNewAccountPage,
+ lockMetamask,
+ showConfigPage,
+ showInfoPage,
+ } = this.props
+
+ return h(Menu, { className: 'account-menu', isShowing: isAccountMenuOpen }, [
+ h(CloseArea, { onClick: toggleAccountMenu }),
+ h(Item, {
+ className: 'account-menu__header',
+ }, [
+ 'My Accounts',
+ h('button.account-menu__logout-button', {
+ onClick: lockMetamask,
+ }, 'Log out'),
+ ]),
+ h(Divider),
+ h('div.account-menu__accounts', this.renderAccounts()),
+ h(Divider),
+ h(Item, {
+ onClick: () => showNewAccountPage('CREATE'),
+ icon: h('img.account-menu__item-icon', { src: 'images/plus-btn-white.svg' }),
+ text: 'Create Account',
+ }),
+ h(Item, {
+ onClick: () => showNewAccountPage('IMPORT'),
+ icon: h('img.account-menu__item-icon', { src: 'images/import-account.svg' }),
+ text: 'Import Account',
+ }),
+ h(Divider),
+ h(Item, {
+ onClick: showInfoPage,
+ icon: h('img.account-menu__item-icon', { src: 'images/mm-info-icon.svg' }),
+ text: 'Info & Help',
+ }),
+ h(Item, {
+ onClick: showConfigPage,
+ icon: h('img.account-menu__item-icon', { src: 'images/settings.svg' }),
+ text: 'Settings',
+ }),
+ ])
+}
+
+AccountMenu.prototype.renderAccounts = function () {
+ const {
+ identities,
+ accounts,
+ selectedAddress,
+ keyrings,
+ showAccountDetail,
+ } = this.props
+
+ return Object.keys(identities).map((key, index) => {
+ const identity = identities[key]
+ const isSelected = identity.address === selectedAddress
+
+ const balanceValue = accounts[key] ? accounts[key].balance : ''
+ const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...'
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress) ||
+ kr.accounts.includes(identity.address)
+ })
+
+ return h(
+ 'div.account-menu__account.menu__item--clickable',
+ { onClick: () => showAccountDetail(identity.address) },
+ [
+ h('div.account-menu__check-mark', [
+ isSelected ? h('div.account-menu__check-mark-icon') : null,
+ ]),
+
+ h(
+ Identicon,
+ {
+ address: identity.address,
+ diameter: 24,
+ },
+ ),
+
+ h('div.account-menu__account-info', [
+ h('div.account-menu__name', identity.name || ''),
+ h('div.account-menu__balance', formattedBalance),
+ ]),
+
+ this.indicateIfLoose(keyring),
+ ],
+ )
+ })
+}
+
+AccountMenu.prototype.indicateIfLoose = function (keyring) {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'IMPORTED') : null
+ } catch (e) { return }
+}
diff --git a/ui/app/components/balance-component.js b/ui/app/components/balance-component.js
new file mode 100644
index 000000000..d591ab455
--- /dev/null
+++ b/ui/app/components/balance-component.js
@@ -0,0 +1,121 @@
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const TokenBalance = require('./token-balance')
+const Identicon = require('./identicon')
+
+const { formatBalance, generateBalanceObject } = require('../util')
+
+module.exports = connect(mapStateToProps)(BalanceComponent)
+
+function mapStateToProps (state) {
+ const accounts = state.metamask.accounts
+ const network = state.metamask.network
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ const account = accounts[selectedAddress]
+
+ return {
+ account,
+ network,
+ conversionRate: state.metamask.conversionRate,
+ currentCurrency: state.metamask.currentCurrency,
+ }
+}
+
+inherits(BalanceComponent, Component)
+function BalanceComponent () {
+ Component.call(this)
+}
+
+BalanceComponent.prototype.render = function () {
+ const props = this.props
+ const { token, network } = props
+
+ return h('div.balance-container', {}, [
+
+ // TODO: balance icon needs to be passed in
+ // h('img.balance-icon', {
+ // src: '../images/eth_logo.svg',
+ // style: {},
+ // }),
+ h(Identicon, {
+ diameter: 50,
+ address: token && token.address,
+ network,
+ }),
+
+ token ? this.renderTokenBalance() : this.renderBalance(),
+ ])
+}
+
+BalanceComponent.prototype.renderTokenBalance = function () {
+ const { token } = this.props
+
+ return h('div.flex-column.balance-display', [
+ h('div.token-amount', [ h(TokenBalance, { token }) ]),
+ ])
+}
+
+BalanceComponent.prototype.renderBalance = function () {
+ const props = this.props
+ const { shorten, account } = props
+ const balanceValue = account && account.balance
+ const needsParse = 'needsParse' in props ? props.needsParse : true
+ const formattedBalance = balanceValue ? formatBalance(balanceValue, 6, needsParse) : '...'
+ const showFiat = 'showFiat' in props ? props.showFiat : true
+
+ if (formattedBalance === 'None' || formattedBalance === '...') {
+ return h('div.flex-column.balance-display', {}, [
+ h('div.token-amount', {
+ style: {},
+ }, formattedBalance),
+ ])
+ }
+
+ return h('div.flex-column.balance-display', {}, [
+ h('div.token-amount', {
+ style: {},
+ }, this.getTokenBalance(formattedBalance, shorten)),
+
+ showFiat ? this.renderFiatValue(formattedBalance) : null,
+ ])
+}
+
+BalanceComponent.prototype.renderFiatValue = function (formattedBalance) {
+
+ const { conversionRate, currentCurrency } = this.props
+
+ const fiatDisplayNumber = this.getFiatDisplayNumber(formattedBalance, conversionRate)
+
+ const fiatPrefix = currentCurrency === 'USD' ? '$' : ''
+
+ return this.renderFiatAmount(fiatDisplayNumber, currentCurrency, fiatPrefix)
+}
+
+BalanceComponent.prototype.renderFiatAmount = function (fiatDisplayNumber, fiatSuffix, fiatPrefix) {
+ const shouldNotRenderFiat = fiatDisplayNumber === 'N/A' || Number(fiatDisplayNumber) === 0
+ if (shouldNotRenderFiat) return null
+
+ return h('div.fiat-amount', {
+ style: {},
+ }, `${fiatPrefix}${fiatDisplayNumber} ${fiatSuffix}`)
+}
+
+BalanceComponent.prototype.getTokenBalance = function (formattedBalance, shorten) {
+ const balanceObj = generateBalanceObject(formattedBalance, shorten ? 1 : 3)
+
+ const balanceValue = shorten ? balanceObj.shortBalance : balanceObj.balance
+ const label = balanceObj.label
+
+ return `${balanceValue} ${label}`
+}
+
+BalanceComponent.prototype.getFiatDisplayNumber = function (formattedBalance, conversionRate) {
+ if (formattedBalance === 'None') return formattedBalance
+ if (conversionRate === 0) return 'N/A'
+
+ const splitBalance = formattedBalance.split(' ')
+
+ return (Number(splitBalance[0]) * conversionRate).toFixed(2)
+}
diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js
index 15281171c..d5958787b 100644
--- a/ui/app/components/buy-button-subview.js
+++ b/ui/app/components/buy-button-subview.js
@@ -76,7 +76,7 @@ BuyButtonSubview.prototype.headerSubview = function () {
paddingTop: '4px',
paddingBottom: '4px',
},
- }, 'Buy Eth'),
+ }, 'Deposit Eth'),
]),
// loading indication
@@ -87,7 +87,7 @@ BuyButtonSubview.prototype.headerSubview = function () {
left: '49vw',
},
}, [
- h(Loading, { isLoading }),
+ isLoading && h(Loading),
]),
// account panel
@@ -245,7 +245,7 @@ BuyButtonSubview.prototype.navigateTo = function (url) {
BuyButtonSubview.prototype.backButtonContext = function () {
if (this.props.context === 'confTx') {
- this.props.dispatch(actions.showConfTxPage(false))
+ this.props.dispatch(actions.showConfTxPage({transForward: false}))
} else {
this.props.dispatch(actions.goHome())
}
diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js
new file mode 100644
index 000000000..6f7862e51
--- /dev/null
+++ b/ui/app/components/currency-input.js
@@ -0,0 +1,103 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = CurrencyInput
+
+inherits(CurrencyInput, Component)
+function CurrencyInput (props) {
+ Component.call(this)
+
+ this.state = {
+ value: sanitizeValue(props.value),
+ }
+}
+
+function removeNonDigits (str) {
+ return str.match(/\d|$/g).join('')
+}
+
+// Removes characters that are not digits, then removes leading zeros
+function sanitizeInteger (val) {
+ return String(parseInt(removeNonDigits(val) || '0', 10))
+}
+
+function sanitizeDecimal (val) {
+ return removeNonDigits(val)
+}
+
+// Take a single string param and returns a non-negative integer or float as a string.
+// Breaks the input into three parts: the integer, the decimal point, and the decimal/fractional part.
+// Removes leading zeros from the integer, and non-digits from the integer and decimal
+// The integer is returned as '0' in cases where it would be empty. A decimal point is
+// included in the returned string if one is included in the param
+// Examples:
+// sanitizeValue('0') -> '0'
+// sanitizeValue('a') -> '0'
+// sanitizeValue('010.') -> '10.'
+// sanitizeValue('0.005') -> '0.005'
+// sanitizeValue('22.200') -> '22.200'
+// sanitizeValue('.200') -> '0.200'
+// sanitizeValue('a.b.1.c,89.123') -> '0.189123'
+function sanitizeValue (value) {
+ let [ , integer, point, decimal] = (/([^.]*)([.]?)([^.]*)/).exec(value)
+
+ integer = sanitizeInteger(integer) || '0'
+ decimal = sanitizeDecimal(decimal)
+
+ return `${integer}${point}${decimal}`
+}
+
+CurrencyInput.prototype.handleChange = function (newValue) {
+ const { onInputChange } = this.props
+ const { value } = this.state
+
+ let parsedValue = newValue
+ const newValueLastIndex = newValue.length - 1
+
+ if (value === '0' && newValue[newValueLastIndex] === '0') {
+ parsedValue = parsedValue.slice(0, newValueLastIndex)
+ }
+
+ const sanitizedValue = sanitizeValue(parsedValue)
+ this.setState({ value: sanitizedValue })
+ onInputChange(sanitizedValue)
+}
+
+// If state.value === props.value plus a decimal point, or at least one
+// zero or a decimal point and at least one zero, then this returns state.value
+// after it is sanitized with getValueParts
+CurrencyInput.prototype.getValueToRender = function () {
+ const { value } = this.props
+ const { value: stateValue } = this.state
+
+ const trailingStateString = (new RegExp(`^${value}(.+)`)).exec(stateValue)
+ const trailingDecimalAndZeroes = trailingStateString && (/^[.0]0*/).test(trailingStateString[1])
+
+ return sanitizeValue(trailingDecimalAndZeroes
+ ? stateValue
+ : value)
+}
+
+CurrencyInput.prototype.render = function () {
+ const {
+ className,
+ placeholder,
+ readOnly,
+ inputRef,
+ } = this.props
+
+ const inputSizeMultiplier = readOnly ? 1 : 1.2
+
+ const valueToRender = this.getValueToRender()
+
+ return h('input', {
+ className,
+ value: valueToRender,
+ placeholder,
+ size: valueToRender.length * inputSizeMultiplier,
+ readOnly,
+ onChange: e => this.handleChange(e.target.value),
+ ref: inputRef,
+ })
+}
diff --git a/ui/app/components/customize-gas-modal/gas-modal-card.js b/ui/app/components/customize-gas-modal/gas-modal-card.js
new file mode 100644
index 000000000..23754d819
--- /dev/null
+++ b/ui/app/components/customize-gas-modal/gas-modal-card.js
@@ -0,0 +1,54 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const InputNumber = require('../input-number.js')
+// const GasSlider = require('./gas-slider.js')
+
+module.exports = GasModalCard
+
+inherits(GasModalCard, Component)
+function GasModalCard () {
+ Component.call(this)
+}
+
+GasModalCard.prototype.render = function () {
+ const {
+ // memo,
+ onChange,
+ unitLabel,
+ value,
+ min,
+ // max,
+ step,
+ title,
+ copy,
+ } = this.props
+
+ return h('div.send-v2__gas-modal-card', [
+
+ h('div.send-v2__gas-modal-card__title', {}, title),
+
+ h('div.send-v2__gas-modal-card__copy', {}, copy),
+
+ h(InputNumber, {
+ unitLabel,
+ step,
+ // max,
+ min,
+ placeholder: '0',
+ value,
+ onChange,
+ }),
+
+ // h(GasSlider, {
+ // value,
+ // step,
+ // max,
+ // min,
+ // onChange,
+ // }),
+
+ ])
+
+}
+
diff --git a/ui/app/components/customize-gas-modal/gas-slider.js b/ui/app/components/customize-gas-modal/gas-slider.js
new file mode 100644
index 000000000..69fd6f985
--- /dev/null
+++ b/ui/app/components/customize-gas-modal/gas-slider.js
@@ -0,0 +1,50 @@
+// const Component = require('react').Component
+// const h = require('react-hyperscript')
+// const inherits = require('util').inherits
+
+// module.exports = GasSlider
+
+// inherits(GasSlider, Component)
+// function GasSlider () {
+// Component.call(this)
+// }
+
+// GasSlider.prototype.render = function () {
+// const {
+// memo,
+// identities,
+// onChange,
+// unitLabel,
+// value,
+// id,
+// step,
+// max,
+// min,
+// } = this.props
+
+// return h('div.gas-slider', [
+
+// h('input.gas-slider__input', {
+// type: 'range',
+// step,
+// max,
+// min,
+// value,
+// id: 'gasSlider',
+// onChange: event => onChange(event.target.value),
+// }, []),
+
+// h('div.gas-slider__bar', [
+
+// h('div.gas-slider__low'),
+
+// h('div.gas-slider__mid'),
+
+// h('div.gas-slider__high'),
+
+// ]),
+
+// ])
+
+// }
+
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
new file mode 100644
index 000000000..826d2cd4b
--- /dev/null
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -0,0 +1,298 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const GasModalCard = require('./gas-modal-card')
+
+const ethUtil = require('ethereumjs-util')
+
+const {
+ MIN_GAS_PRICE_DEC,
+ MIN_GAS_LIMIT_DEC,
+ MIN_GAS_PRICE_GWEI,
+} = require('../send/send-constants')
+
+const {
+ isBalanceSufficient,
+} = require('../send/send-utils')
+
+const {
+ conversionUtil,
+ multiplyCurrencies,
+ conversionGreaterThan,
+ subtractCurrencies,
+} = require('../../conversion-util')
+
+const {
+ getGasPrice,
+ getGasLimit,
+ conversionRateSelector,
+ getSendAmount,
+ getSelectedToken,
+ getSendFrom,
+ getCurrentAccountWithSendEtherInfo,
+ getSelectedTokenToFiatRate,
+ getSendMaxModeState,
+} = require('../../selectors')
+
+function mapStateToProps (state) {
+ const selectedToken = getSelectedToken(state)
+ const currentAccount = getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state)
+ const conversionRate = conversionRateSelector(state)
+
+ return {
+ gasPrice: getGasPrice(state),
+ gasLimit: getGasLimit(state),
+ conversionRate,
+ amount: getSendAmount(state),
+ maxModeOn: getSendMaxModeState(state),
+ balance: currentAccount.balance,
+ primaryCurrency: selectedToken && selectedToken.symbol,
+ selectedToken,
+ amountConversionRate: selectedToken ? getSelectedTokenToFiatRate(state) : conversionRate,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => dispatch(actions.hideModal()),
+ updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)),
+ updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
+ updateGasTotal: newGasTotal => dispatch(actions.updateGasTotal(newGasTotal)),
+ updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
+ }
+}
+
+function getOriginalState (props) {
+ const gasPrice = props.gasPrice || MIN_GAS_PRICE_DEC
+ const gasLimit = props.gasLimit || MIN_GAS_LIMIT_DEC
+
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ return {
+ gasPrice,
+ gasLimit,
+ gasTotal,
+ error: null,
+ priceSigZeros: '',
+ priceSigDec: '',
+ }
+}
+
+inherits(CustomizeGasModal, Component)
+function CustomizeGasModal (props) {
+ Component.call(this)
+
+ this.state = getOriginalState(props)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(CustomizeGasModal)
+
+CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) {
+ const {
+ updateGasPrice,
+ updateGasLimit,
+ hideModal,
+ updateGasTotal,
+ maxModeOn,
+ selectedToken,
+ balance,
+ updateSendAmount,
+ } = this.props
+
+ if (maxModeOn && !selectedToken) {
+ const maxAmount = subtractCurrencies(
+ ethUtil.addHexPrefix(balance),
+ ethUtil.addHexPrefix(gasTotal),
+ { toNumericBase: 'hex' }
+ )
+ updateSendAmount(maxAmount)
+ }
+
+ updateGasPrice(gasPrice)
+ updateGasLimit(gasLimit)
+ updateGasTotal(gasTotal)
+ hideModal()
+}
+
+CustomizeGasModal.prototype.revert = function () {
+ this.setState(getOriginalState(this.props))
+}
+
+CustomizeGasModal.prototype.validate = function ({ gasTotal, gasLimit }) {
+ const {
+ amount,
+ balance,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
+ maxModeOn,
+ } = this.props
+
+ let error = null
+
+ const balanceIsSufficient = isBalanceSufficient({
+ amount: selectedToken || maxModeOn ? '0' : amount,
+ gasTotal,
+ balance,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
+ })
+
+ if (!balanceIsSufficient) {
+ error = 'Insufficient balance for current gas total'
+ }
+
+ const gasLimitTooLow = gasLimit && conversionGreaterThan(
+ {
+ value: MIN_GAS_LIMIT_DEC,
+ fromNumericBase: 'dec',
+ conversionRate,
+ },
+ {
+ value: gasLimit,
+ fromNumericBase: 'hex',
+ },
+ )
+
+ if (gasLimitTooLow) {
+ error = 'Gas limit must be at least 21000'
+ }
+
+ this.setState({ error })
+ return error
+}
+
+CustomizeGasModal.prototype.convertAndSetGasLimit = function (newGasLimit) {
+ const { gasPrice } = this.state
+
+ const gasLimit = conversionUtil(newGasLimit, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ })
+
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ this.validate({ gasTotal, gasLimit })
+
+ this.setState({ gasTotal, gasLimit })
+}
+
+CustomizeGasModal.prototype.convertAndSetGasPrice = function (newGasPrice) {
+ const { gasLimit } = this.state
+ const sigZeros = String(newGasPrice).match(/^\d+[.]\d*?(0+)$/)
+ const sigDec = String(newGasPrice).match(/^\d+([.])0*$/)
+
+ this.setState({
+ priceSigZeros: sigZeros && sigZeros[1] || '',
+ priceSigDec: sigDec && sigDec[1] || '',
+ })
+
+ const gasPrice = conversionUtil(newGasPrice, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ fromDenomination: 'GWEI',
+ toDenomination: 'WEI',
+ })
+
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ this.validate({ gasTotal })
+
+ this.setState({ gasTotal, gasPrice })
+}
+
+CustomizeGasModal.prototype.render = function () {
+ const { hideModal } = this.props
+ const { gasPrice, gasLimit, gasTotal, error, priceSigZeros, priceSigDec } = this.state
+
+ let convertedGasPrice = conversionUtil(gasPrice, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ toDenomination: 'GWEI',
+ })
+
+ convertedGasPrice += convertedGasPrice.match(/[.]/) ? priceSigZeros : `${priceSigDec}${priceSigZeros}`
+
+ const convertedGasLimit = conversionUtil(gasLimit, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ })
+
+ return h('div.send-v2__customize-gas', {}, [
+ h('div.send-v2__customize-gas__content', {
+ }, [
+ h('div.send-v2__customize-gas__header', {}, [
+
+ h('div.send-v2__customize-gas__title', 'Customize Gas'),
+
+ h('div.send-v2__customize-gas__close', {
+ onClick: hideModal,
+ }),
+
+ ]),
+
+ h('div.send-v2__customize-gas__body', {}, [
+
+ h(GasModalCard, {
+ value: convertedGasPrice,
+ min: MIN_GAS_PRICE_GWEI,
+ // max: 1000,
+ step: multiplyCurrencies(MIN_GAS_PRICE_GWEI, 10),
+ onChange: value => this.convertAndSetGasPrice(value),
+ title: 'Gas Price (GWEI)',
+ copy: 'We calculate the suggested gas prices based on network success rates.',
+ }),
+
+ h(GasModalCard, {
+ value: convertedGasLimit,
+ min: 1,
+ // max: 100000,
+ step: 1,
+ onChange: value => this.convertAndSetGasLimit(value),
+ title: 'Gas Limit',
+ copy: 'We calculate the suggested gas limit based on network success rates.',
+ }),
+
+ ]),
+
+ h('div.send-v2__customize-gas__footer', {}, [
+
+ error && h('div.send-v2__customize-gas__error-message', [
+ error,
+ ]),
+
+ h('div.send-v2__customize-gas__revert', {
+ onClick: () => this.revert(),
+ }, ['Revert']),
+
+ h('div.send-v2__customize-gas__buttons', [
+ h('div.send-v2__customize-gas__cancel', {
+ onClick: this.props.hideModal,
+ }, ['CANCEL']),
+
+ h(`div.send-v2__customize-gas__save${error ? '__error' : ''}`, {
+ onClick: () => !error && this.save(gasPrice, gasLimit, gasTotal),
+ }, ['SAVE']),
+ ]),
+
+ ]),
+
+ ]),
+ ])
+}
diff --git a/ui/app/components/dropdowns/account-dropdown-mini.js b/ui/app/components/dropdowns/account-dropdown-mini.js
new file mode 100644
index 000000000..a3d41af90
--- /dev/null
+++ b/ui/app/components/dropdowns/account-dropdown-mini.js
@@ -0,0 +1,75 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountListItem = require('../send/account-list-item')
+
+module.exports = AccountDropdownMini
+
+inherits(AccountDropdownMini, Component)
+function AccountDropdownMini () {
+ Component.call(this)
+}
+
+AccountDropdownMini.prototype.getListItemIcon = function (currentAccount, selectedAccount) {
+ const listItemIcon = h(`i.fa.fa-check.fa-lg`, { style: { color: '#02c9b1' } })
+
+ return currentAccount.address === selectedAccount.address
+ ? listItemIcon
+ : null
+}
+
+AccountDropdownMini.prototype.renderDropdown = function () {
+ const {
+ accounts,
+ selectedAccount,
+ closeDropdown,
+ onSelect,
+ } = this.props
+
+ return h('div', {}, [
+
+ h('div.account-dropdown-mini__close-area', {
+ onClick: closeDropdown,
+ }),
+
+ h('div.account-dropdown-mini__list', {}, [
+
+ ...accounts.map(account => h(AccountListItem, {
+ account,
+ displayBalance: false,
+ displayAddress: false,
+ handleClick: () => {
+ onSelect(account)
+ closeDropdown()
+ },
+ icon: this.getListItemIcon(account, selectedAccount),
+ })),
+
+ ]),
+
+ ])
+}
+
+AccountDropdownMini.prototype.render = function () {
+ const {
+ selectedAccount,
+ openDropdown,
+ dropdownOpen,
+ } = this.props
+
+ return h('div.account-dropdown-mini', {}, [
+
+ h(AccountListItem, {
+ account: selectedAccount,
+ handleClick: openDropdown,
+ displayBalance: false,
+ displayAddress: false,
+ icon: h(`i.fa.fa-caret-down.fa-lg`, { style: { color: '#dedede' } }),
+ }),
+
+ dropdownOpen && this.renderDropdown(),
+
+ ])
+
+}
+
diff --git a/ui/app/components/dropdowns/account-options-dropdown.js b/ui/app/components/dropdowns/account-options-dropdown.js
new file mode 100644
index 000000000..f74c0a2d4
--- /dev/null
+++ b/ui/app/components/dropdowns/account-options-dropdown.js
@@ -0,0 +1,29 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountDropdowns = require('./components/account-dropdowns')
+
+inherits(AccountOptionsDropdown, Component)
+function AccountOptionsDropdown () {
+ Component.call(this)
+}
+
+module.exports = AccountOptionsDropdown
+
+// TODO: specify default props and proptypes
+// TODO: hook up to state, connect to redux to clean up API
+// TODO: selectedAddress is not defined... should we use selected?
+AccountOptionsDropdown.prototype.render = function () {
+ const { selected, network, identities, style, dropdownWrapperStyle, menuItemStyles } = this.props
+
+ return h(AccountDropdowns, {
+ enableAccountOptions: true,
+ enableAccountsSelector: false,
+ selected,
+ network,
+ identities,
+ style: style || {},
+ dropdownWrapperStyle: dropdownWrapperStyle || {},
+ menuItemStyles: menuItemStyles || {},
+ }, [])
+}
diff --git a/ui/app/components/dropdowns/account-selection-dropdown.js b/ui/app/components/dropdowns/account-selection-dropdown.js
new file mode 100644
index 000000000..2f6452b15
--- /dev/null
+++ b/ui/app/components/dropdowns/account-selection-dropdown.js
@@ -0,0 +1,29 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountDropdowns = require('./components/account-dropdowns')
+
+inherits(AccountSelectionDropdown, Component)
+function AccountSelectionDropdown () {
+ Component.call(this)
+}
+
+module.exports = AccountSelectionDropdown
+
+// TODO: specify default props and proptypes
+// TODO: hook up to state, connect to redux to clean up API
+// TODO: selectedAddress is not defined... should we use selected?
+AccountSelectionDropdown.prototype.render = function () {
+ const { selected, network, identities, style, dropdownWrapperStyle, menuItemStyles } = this.props
+
+ return h(AccountDropdowns, {
+ enableAccountOptions: false,
+ enableAccountsSelector: true,
+ selected,
+ network,
+ identities,
+ style: style || {},
+ dropdownWrapperStyle: dropdownWrapperStyle || {},
+ menuItemStyles: menuItemStyles || {},
+ }, [])
+}
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
new file mode 100644
index 000000000..d3a549884
--- /dev/null
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -0,0 +1,482 @@
+const Component = require('react').Component
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const actions = require('../../../actions')
+const genAccountLink = require('../../../../lib/account-link.js')
+const connect = require('react-redux').connect
+const Dropdown = require('./dropdown').Dropdown
+const DropdownMenuItem = require('./dropdown').DropdownMenuItem
+const Identicon = require('../../identicon')
+const ethUtil = require('ethereumjs-util')
+const copyToClipboard = require('copy-to-clipboard')
+const { formatBalance } = require('../../../util')
+
+class AccountDropdowns extends Component {
+ constructor (props) {
+ super(props)
+ this.state = {
+ accountSelectorActive: false,
+ optionsMenuActive: false,
+ }
+ // Used for orangeaccount selector icon
+ // this.accountSelectorToggleClassName = 'accounts-selector'
+ this.accountSelectorToggleClassName = 'fa-angle-down'
+ this.optionsMenuToggleClassName = 'fa-ellipsis-h'
+ }
+
+ renderAccounts () {
+ const { identities, accounts, selected, menuItemStyles, actions, keyrings } = this.props
+
+ return Object.keys(identities).map((key, index) => {
+ const identity = identities[key]
+ const isSelected = identity.address === selected
+
+ const balanceValue = accounts[key].balance
+ const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...'
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress) ||
+ kr.accounts.includes(identity.address)
+ })
+
+ return h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ this.props.actions.showAccountDetail(identity.address)
+ },
+ style: Object.assign(
+ {
+ marginTop: index === 0 ? '5px' : '',
+ fontSize: '24px',
+ width: '260px',
+ },
+ menuItemStyles,
+ ),
+ },
+ [
+ h('div.flex-row.flex-center', {}, [
+
+ h('span', {
+ style: {
+ flex: '1 1 0',
+ minWidth: '20px',
+ minHeight: '30px',
+ },
+ }, [
+ h('span', {
+ style: {
+ flex: '1 1 auto',
+ fontSize: '14px',
+ },
+ }, isSelected ? h('i.fa.fa-check') : null),
+ ]),
+
+ h(
+ Identicon,
+ {
+ address: identity.address,
+ diameter: 24,
+ style: {
+ flex: '1 1 auto',
+ marginLeft: '10px',
+ },
+ },
+ ),
+
+ h('span.flex-column', {
+ style: {
+ flex: '10 10 auto',
+ width: '175px',
+ alignItems: 'flex-start',
+ justifyContent: 'center',
+ marginLeft: '10px',
+ position: 'relative',
+ },
+ }, [
+ this.indicateIfLoose(keyring),
+ h('span.account-dropdown-name', {
+ style: {
+ fontSize: '18px',
+ maxWidth: '145px',
+ whiteSpace: 'nowrap',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ },
+ }, identity.name || ''),
+
+ h('span.account-dropdown-balance', {
+ style: {
+ fontSize: '14px',
+ fontFamily: 'Avenir',
+ fontWeight: 500,
+ },
+ }, formattedBalance),
+ ]),
+
+ h('span', {
+ style: {
+ flex: '3 3 auto',
+ },
+ }, [
+ h('span.account-dropdown-edit-button', {
+ style: {
+ fontSize: '16px',
+ },
+ onClick: () => {
+ actions.showEditAccountModal(identity)
+ },
+ }, [
+ 'Edit',
+ ]),
+ ]),
+
+ ]),
+// =======
+// },
+// ),
+// this.indicateIfLoose(keyring),
+// h('span', {
+// style: {
+// marginLeft: '20px',
+// fontSize: '24px',
+// maxWidth: '145px',
+// whiteSpace: 'nowrap',
+// overflow: 'hidden',
+// textOverflow: 'ellipsis',
+// },
+// }, identity.name || ''),
+// h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
+// >>>>>>> master:ui/app/components/account-dropdowns.js
+ ]
+ )
+ })
+ }
+
+ indicateIfLoose (keyring) {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'LOOSE') : null
+ } catch (e) { return }
+ }
+
+ renderAccountSelector () {
+ const { actions, useCssTransition, innerStyle, sidebarOpen } = this.props
+ const { accountSelectorActive, menuItemStyles } = this.state
+
+ return h(
+ Dropdown,
+ {
+ useCssTransition,
+ style: {
+ marginLeft: '-185px',
+ marginTop: '50px',
+ minWidth: '180px',
+ overflowY: 'auto',
+ maxHeight: '300px',
+ width: '300px',
+ },
+ innerStyle,
+ isOpen: accountSelectorActive,
+ onClickOutside: (event) => {
+ const { classList } = event.target
+ const isNotToggleElement = !classList.contains(this.accountSelectorToggleClassName)
+ if (accountSelectorActive && isNotToggleElement) {
+ this.setState({ accountSelectorActive: false })
+ }
+ },
+ },
+ [
+ ...this.renderAccounts(),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ style: Object.assign(
+ {},
+ menuItemStyles,
+ ),
+ onClick: () => actions.showNewAccountPageCreateForm(),
+ },
+ [
+ h(
+ 'i.fa.fa-plus.fa-lg',
+ {
+ style: {
+ marginLeft: '8px',
+ },
+ }
+ ),
+ h('span', {
+ style: {
+ marginLeft: '14px',
+ fontFamily: 'DIN OT',
+ fontSize: '16px',
+ lineHeight: '23px',
+ },
+ }, 'Create Account'),
+ ],
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {
+ if (sidebarOpen) {
+ actions.hideSidebar()
+ }
+ },
+ onClick: () => actions.showNewAccountPageImportForm(),
+ style: Object.assign(
+ {},
+ menuItemStyles,
+ ),
+ },
+ [
+ h(
+ 'i.fa.fa-download.fa-lg',
+ {
+ style: {
+ marginLeft: '8px',
+ },
+ }
+ ),
+ h('span', {
+ style: {
+ marginLeft: '20px',
+ marginBottom: '5px',
+ fontFamily: 'DIN OT',
+ fontSize: '16px',
+ lineHeight: '23px',
+ },
+ }, 'Import Account'),
+ ]
+ ),
+ ]
+ )
+ }
+
+ renderAccountOptions () {
+ const { actions, dropdownWrapperStyle, useCssTransition } = this.props
+ const { optionsMenuActive, menuItemStyles } = this.state
+ const dropdownMenuItemStyle = {
+ fontFamily: 'DIN OT',
+ fontSize: 16,
+ lineHeight: '24px',
+ padding: '8px',
+ }
+
+ return h(
+ Dropdown,
+ {
+ useCssTransition,
+ style: Object.assign(
+ {
+ marginLeft: '-10px',
+ position: 'absolute',
+ width: '29vh', // affects both mobile and laptop views
+ },
+ dropdownWrapperStyle,
+ ),
+ isOpen: optionsMenuActive,
+ onClickOutside: () => {
+ const { classList } = event.target
+ const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
+ if (optionsMenuActive && isNotToggleElement) {
+ this.setState({ optionsMenuActive: false })
+ }
+ },
+ },
+ [
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ this.props.actions.showAccountDetailModal()
+ },
+ style: Object.assign(
+ dropdownMenuItemStyle,
+ menuItemStyles,
+ ),
+ },
+ 'Account Details',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ const { selected, network } = this.props
+ const url = genAccountLink(selected, network)
+ global.platform.openWindow({ url })
+ },
+ style: Object.assign(
+ dropdownMenuItemStyle,
+ menuItemStyles,
+ ),
+ },
+ 'View account on Etherscan',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ const { selected } = this.props
+ const checkSumAddress = selected && ethUtil.toChecksumAddress(selected)
+ copyToClipboard(checkSumAddress)
+ },
+ style: Object.assign(
+ dropdownMenuItemStyle,
+ menuItemStyles,
+ ),
+ },
+ 'Copy Address to clipboard',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => this.props.actions.showExportPrivateKeyModal(),
+ style: Object.assign(
+ dropdownMenuItemStyle,
+ menuItemStyles,
+ ),
+ },
+ 'Export Private Key',
+ ),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => {},
+ onClick: () => {
+ actions.hideSidebar()
+ actions.showAddTokenPage()
+ },
+ style: Object.assign(
+ dropdownMenuItemStyle,
+ menuItemStyles,
+ ),
+ },
+ 'Add Token',
+ ),
+
+ ]
+ )
+ }
+
+ render () {
+ const { style, enableAccountsSelector, enableAccountOptions } = this.props
+ const { optionsMenuActive, accountSelectorActive } = this.state
+
+ return h(
+ 'span',
+ {
+ style: style,
+ },
+ [
+ enableAccountsSelector && h(
+ 'i.fa.fa-angle-down',
+ {
+ style: {
+ cursor: 'pointer',
+ },
+ onClick: (event) => {
+ event.stopPropagation()
+ this.setState({
+ accountSelectorActive: !accountSelectorActive,
+ optionsMenuActive: false,
+ })
+ },
+ },
+ this.renderAccountSelector(),
+ ),
+ enableAccountOptions && h(
+ 'i.fa.fa-ellipsis-h',
+ {
+ style: {
+ fontSize: '135%',
+ cursor: 'pointer',
+ },
+ onClick: (event) => {
+ event.stopPropagation()
+ this.setState({
+ accountSelectorActive: false,
+ optionsMenuActive: !optionsMenuActive,
+ })
+ },
+ },
+ this.renderAccountOptions()
+ ),
+ ]
+ )
+ }
+}
+
+AccountDropdowns.defaultProps = {
+ enableAccountsSelector: false,
+ enableAccountOptions: false,
+}
+
+AccountDropdowns.propTypes = {
+ identities: PropTypes.objectOf(PropTypes.object),
+ selected: PropTypes.string,
+ keyrings: PropTypes.array,
+ accounts: PropTypes.object,
+ menuItemStyles: PropTypes.object,
+ actions: PropTypes.object,
+ // actions.showAccountDetail: ,
+ useCssTransition: PropTypes.bool,
+ innerStyle: PropTypes.object,
+ sidebarOpen: PropTypes.bool,
+ dropdownWrapperStyle: PropTypes.string,
+ // actions.showAccountDetailModal: ,
+ network: PropTypes.number,
+ // actions.showExportPrivateKeyModal: ,
+ style: PropTypes.object,
+ enableAccountsSelector: PropTypes.bool,
+ enableAccountOption: PropTypes.bool,
+ enableAccountOptions: PropTypes.bool,
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ actions: {
+ hideSidebar: () => dispatch(actions.hideSidebar()),
+ showConfigPage: () => dispatch(actions.showConfigPage()),
+ showAccountDetail: (address) => dispatch(actions.showAccountDetail(address)),
+ showAccountDetailModal: () => {
+ dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
+ },
+ showEditAccountModal: (identity) => {
+ dispatch(actions.showModal({
+ name: 'EDIT_ACCOUNT_NAME',
+ identity,
+ }))
+ },
+ showNewAccountPageCreateForm: () => dispatch(actions.showNewAccountPage({ form: 'CREATE' })),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ showAddTokenPage: () => {
+ dispatch(actions.showAddTokenPage())
+ },
+ addNewAccount: () => dispatch(actions.addNewAccount()),
+ showNewAccountPageImportForm: () => dispatch(actions.showNewAccountPage({ form: 'IMPORT' })),
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ },
+ }
+}
+
+function mapStateToProps (state) {
+ return {
+ keyrings: state.metamask.keyrings,
+ sidebarOpen: state.appState.sidebarOpen,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDropdowns)
+
diff --git a/ui/app/components/dropdowns/components/dropdown.js b/ui/app/components/dropdowns/components/dropdown.js
new file mode 100644
index 000000000..0336dbb8b
--- /dev/null
+++ b/ui/app/components/dropdowns/components/dropdown.js
@@ -0,0 +1,113 @@
+const Component = require('react').Component
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const MenuDroppo = require('../../menu-droppo')
+const extend = require('xtend')
+
+const noop = () => {}
+
+class Dropdown extends Component {
+ render () {
+ const {
+ containerClassName,
+ isOpen,
+ onClickOutside,
+ style,
+ innerStyle,
+ children,
+ useCssTransition,
+ } = this.props
+
+ const innerStyleDefaults = extend({
+ borderRadius: '4px',
+ padding: '8px 16px',
+ background: 'rgba(0, 0, 0, 0.8)',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px',
+ }, innerStyle)
+
+ return h(
+ MenuDroppo,
+ {
+ containerClassName,
+ useCssTransition,
+ isOpen,
+ zIndex: 55,
+ onClickOutside,
+ style,
+ innerStyle: innerStyleDefaults,
+ },
+ [
+ h(
+ 'style',
+ `
+ li.dropdown-menu-item:hover {
+ color:rgb(225, 225, 225);
+ background-color: rgba(255, 255, 255, 0.05);
+ border-radius: 4px;
+ }
+ li.dropdown-menu-item { color: rgb(185, 185, 185); }
+ `
+ ),
+ ...children,
+ ]
+ )
+ }
+}
+
+Dropdown.defaultProps = {
+ isOpen: false,
+ onClick: noop,
+ useCssTransition: false,
+}
+
+Dropdown.propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ onClick: PropTypes.func.isRequired,
+ children: PropTypes.node,
+ style: PropTypes.object.isRequired,
+ onClickOutside: PropTypes.func,
+ innerStyle: PropTypes.object,
+ useCssTransition: PropTypes.bool,
+ containerClassName: PropTypes.string,
+}
+
+class DropdownMenuItem extends Component {
+ render () {
+ const { onClick, closeMenu, children, style } = this.props
+
+ return h(
+ 'li.dropdown-menu-item',
+ {
+ onClick: () => {
+ onClick()
+ closeMenu()
+ },
+ style: Object.assign({
+ listStyle: 'none',
+ padding: '8px 0px',
+ fontSize: '18px',
+ fontStyle: 'normal',
+ fontFamily: 'Montserrat Regular',
+ cursor: 'pointer',
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ color: 'white',
+ }, style),
+ },
+ children
+ )
+ }
+}
+
+DropdownMenuItem.propTypes = {
+ closeMenu: PropTypes.func.isRequired,
+ onClick: PropTypes.func.isRequired,
+ children: PropTypes.node,
+ style: PropTypes.object,
+}
+
+module.exports = {
+ Dropdown,
+ DropdownMenuItem,
+}
diff --git a/ui/app/components/dropdowns/components/menu.js b/ui/app/components/dropdowns/components/menu.js
new file mode 100644
index 000000000..f6d8a139e
--- /dev/null
+++ b/ui/app/components/dropdowns/components/menu.js
@@ -0,0 +1,51 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+
+inherits(Menu, Component)
+function Menu () { Component.call(this) }
+
+Menu.prototype.render = function () {
+ const { className = '', children, isShowing } = this.props
+ return isShowing
+ ? h('div', { className: `menu ${className}` }, children)
+ : h('noscript')
+}
+
+inherits(Item, Component)
+function Item () { Component.call(this) }
+
+Item.prototype.render = function () {
+ const {
+ icon,
+ children,
+ text,
+ className = '',
+ onClick,
+ } = this.props
+ const itemClassName = `menu__item ${className} ${onClick ? 'menu__item--clickable' : ''}`
+ const iconComponent = icon ? h('div.menu__item__icon', [icon]) : null
+ const textComponent = text ? h('div.menu__item__text', text) : null
+
+ return children
+ ? h('div', { className: itemClassName, onClick }, children)
+ : h('div.menu__item', { className: itemClassName, onClick }, [ iconComponent, textComponent ]
+ .filter(d => Boolean(d))
+ )
+}
+
+inherits(Divider, Component)
+function Divider () { Component.call(this) }
+
+Divider.prototype.render = function () {
+ return h('div.menu__divider')
+}
+
+inherits(CloseArea, Component)
+function CloseArea () { Component.call(this) }
+
+CloseArea.prototype.render = function () {
+ return h('div.menu__close-area', { onClick: this.props.onClick })
+}
+
+module.exports = { Menu, Item, Divider, CloseArea }
diff --git a/ui/app/components/dropdowns/components/network-dropdown-icon.js b/ui/app/components/dropdowns/components/network-dropdown-icon.js
new file mode 100644
index 000000000..7e94e0af5
--- /dev/null
+++ b/ui/app/components/dropdowns/components/network-dropdown-icon.js
@@ -0,0 +1,28 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+
+
+inherits(NetworkDropdownIcon, Component)
+module.exports = NetworkDropdownIcon
+
+function NetworkDropdownIcon () {
+ Component.call(this)
+}
+
+NetworkDropdownIcon.prototype.render = function () {
+ const {
+ backgroundColor,
+ isSelected,
+ innerBorder = 'none',
+ } = this.props
+
+ return h(`.menu-icon-circle${isSelected ? '--active' : ''}`, {},
+ h('div', {
+ style: {
+ background: backgroundColor,
+ border: innerBorder,
+ },
+ })
+ )
+}
diff --git a/ui/app/components/dropdowns/index.js b/ui/app/components/dropdowns/index.js
new file mode 100644
index 000000000..fa66f5000
--- /dev/null
+++ b/ui/app/components/dropdowns/index.js
@@ -0,0 +1,17 @@
+// Reusable Dropdown Components
+// TODO: Refactor into separate components
+const Dropdown = require('./components/dropdown').Dropdown
+const AccountDropdowns = require('./components/account-dropdowns')
+
+// App-Specific Instances
+const AccountSelectionDropdown = require('./account-selection-dropdown')
+const AccountOptionsDropdown = require('./account-options-dropdown')
+const NetworkDropdown = require('./network-dropdown').default
+
+module.exports = {
+ AccountSelectionDropdown,
+ AccountOptionsDropdown,
+ NetworkDropdown,
+ Dropdown,
+ AccountDropdowns,
+}
diff --git a/ui/app/components/dropdowns/network-dropdown.js b/ui/app/components/dropdowns/network-dropdown.js
new file mode 100644
index 000000000..dfaa6b22c
--- /dev/null
+++ b/ui/app/components/dropdowns/network-dropdown.js
@@ -0,0 +1,322 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const Dropdown = require('./components/dropdown').Dropdown
+const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
+const NetworkDropdownIcon = require('./components/network-dropdown-icon')
+const R = require('ramda')
+
+// classes from nodes of the toggle element.
+const notToggleElementClassnames = [
+ 'menu-icon',
+ 'network-name',
+ 'network-indicator',
+ 'network-caret',
+ 'network-component',
+]
+
+function mapStateToProps (state) {
+ return {
+ provider: state.metamask.provider,
+ frequentRpcList: state.metamask.frequentRpcList || [],
+ networkDropdownOpen: state.appState.networkDropdownOpen,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ setProviderType: (type) => {
+ dispatch(actions.setProviderType(type))
+ },
+ setDefaultRpcTarget: type => {
+ dispatch(actions.setDefaultRpcTarget(type))
+ },
+ setRpcTarget: (target) => {
+ dispatch(actions.setRpcTarget(target))
+ },
+ showConfigPage: () => {
+ dispatch(actions.showConfigPage())
+ },
+ showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
+ hideNetworkDropdown: () => dispatch(actions.hideNetworkDropdown()),
+ }
+}
+
+
+inherits(NetworkDropdown, Component)
+function NetworkDropdown () {
+ Component.call(this)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(NetworkDropdown)
+
+// TODO: specify default props and proptypes
+NetworkDropdown.prototype.render = function () {
+ const props = this.props
+ const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
+ const rpcList = props.frequentRpcList
+ const isOpen = this.props.networkDropdownOpen
+ const dropdownMenuItemStyle = {
+ fontFamily: 'DIN OT',
+ fontSize: '16px',
+ lineHeight: '20px',
+ padding: '12px 0',
+ }
+
+ return h(Dropdown, {
+ isOpen,
+ onClickOutside: (event) => {
+ const { classList } = event.target
+ const isInClassList = className => classList.contains(className)
+ const notToggleElementIndex = R.findIndex(isInClassList)(notToggleElementClassnames)
+
+ if (notToggleElementIndex === -1) {
+ this.props.hideNetworkDropdown()
+ }
+ },
+ containerClassName: 'network-droppo',
+ zIndex: 55,
+ style: {
+ position: 'absolute',
+ top: '58px',
+ minWidth: '309px',
+ zIndex: '55px',
+ },
+ innerStyle: {
+ padding: '18px 8px',
+ },
+ }, [
+
+ h('div.network-dropdown-header', {}, [
+ h('div.network-dropdown-title', {}, 'Networks'),
+
+ h('div.network-dropdown-divider'),
+
+ h('div.network-dropdown-content',
+ {},
+ 'The default network for Ether transactions is Main Net.'
+ ),
+ ]),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'main',
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setProviderType('mainnet'),
+ style: { ...dropdownMenuItemStyle, borderColor: '#038789' },
+ },
+ [
+ providerType === 'mainnet' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#038789', // $blue-lagoon
+ isSelected: providerType === 'mainnet',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: providerType === 'mainnet' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Main Ethereum Network'),
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'ropsten',
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setProviderType('ropsten'),
+ style: dropdownMenuItemStyle,
+ },
+ [
+ providerType === 'ropsten' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#e91550', // $crimson
+ isSelected: providerType === 'ropsten',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: providerType === 'ropsten' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Ropsten Test Network'),
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'kovan',
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setProviderType('kovan'),
+ style: dropdownMenuItemStyle,
+ },
+ [
+ providerType === 'kovan' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#690496', // $purple
+ isSelected: providerType === 'kovan',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: providerType === 'kovan' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Kovan Test Network'),
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'rinkeby',
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setProviderType('rinkeby'),
+ style: dropdownMenuItemStyle,
+ },
+ [
+ providerType === 'rinkeby' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#ebb33f', // $tulip-tree
+ isSelected: providerType === 'rinkeby',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: providerType === 'rinkeby' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Rinkeby Test Network'),
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ key: 'default',
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setRpcTarget('http://localhost:8545'),
+ style: dropdownMenuItemStyle,
+ },
+ [
+ activeNetwork === 'http://localhost:8545' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ isSelected: activeNetwork === 'http://localhost:8545',
+ innerBorder: '1px solid #9b9b9b',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: activeNetwork === 'http://localhost:8545' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Localhost 8545'),
+ ]
+ ),
+
+ this.renderCustomOption(props.provider),
+ this.renderCommonRpc(rpcList, props.provider),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => this.props.showConfigPage(),
+ style: dropdownMenuItemStyle,
+ },
+ [
+ activeNetwork === 'custom' ? h('i.fa.fa-check') : h('.network-check__transparent', '✓'),
+ h(NetworkDropdownIcon, {
+ isSelected: activeNetwork === 'custom',
+ innerBorder: '1px solid #9b9b9b',
+ }),
+ h('span.network-name-item', {
+ style: {
+ color: activeNetwork === 'custom' ? '#ffffff' : '#9b9b9b',
+ },
+ }, 'Custom RPC'),
+ ]
+ ),
+
+ ])
+}
+
+
+NetworkDropdown.prototype.getNetworkName = function () {
+ const { provider } = this.props
+ const providerName = provider.type
+
+ let name
+
+ if (providerName === 'mainnet') {
+ name = 'Main Ethereum Network'
+ } else if (providerName === 'ropsten') {
+ name = 'Ropsten Test Network'
+ } else if (providerName === 'kovan') {
+ name = 'Kovan Test Network'
+ } else if (providerName === 'rinkeby') {
+ name = 'Rinkeby Test Network'
+ } else {
+ name = 'Unknown Private Network'
+ }
+
+ return name
+}
+
+NetworkDropdown.prototype.renderCommonRpc = function (rpcList, provider) {
+ const props = this.props
+ const rpcTarget = provider.rpcTarget
+
+ return rpcList.map((rpc) => {
+ if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
+ return null
+ } else {
+ return h(
+ DropdownMenuItem,
+ {
+ key: `common${rpc}`,
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ onClick: () => props.setRpcTarget(rpc),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ rpc,
+ rpcTarget === rpc ? h('.check', '✓') : null,
+ ]
+ )
+ }
+ })
+}
+
+NetworkDropdown.prototype.renderCustomOption = function (provider) {
+ const { rpcTarget, type } = provider
+ const props = this.props
+
+ if (type !== 'rpc') return null
+
+ // Concatenate long URLs
+ let label = rpcTarget
+ if (rpcTarget.length > 31) {
+ label = label.substr(0, 34) + '...'
+ }
+
+ switch (rpcTarget) {
+
+ case 'http://localhost:8545':
+ return null
+
+ default:
+ return h(
+ DropdownMenuItem,
+ {
+ key: rpcTarget,
+ onClick: () => props.setRpcTarget(rpcTarget),
+ closeMenu: () => this.props.hideNetworkDropdown(),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ label,
+ h('.check', '✓'),
+ ]
+ )
+ }
+}
diff --git a/ui/app/components/dropdowns/simple-dropdown.js b/ui/app/components/dropdowns/simple-dropdown.js
new file mode 100644
index 000000000..bba088ed1
--- /dev/null
+++ b/ui/app/components/dropdowns/simple-dropdown.js
@@ -0,0 +1,92 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const classnames = require('classnames')
+const R = require('ramda')
+
+class SimpleDropdown extends Component {
+ constructor (props) {
+ super(props)
+ this.state = {
+ isOpen: false,
+ }
+ }
+
+ getDisplayValue () {
+ const { selectedOption, options } = this.props
+ const matchesOption = option => option.value === selectedOption
+ const matchingOption = R.find(matchesOption)(options)
+ return matchingOption
+ ? matchingOption.displayValue || matchingOption.value
+ : selectedOption
+ }
+
+ handleClose () {
+ this.setState({ isOpen: false })
+ }
+
+ toggleOpen () {
+ const { isOpen } = this.state
+ this.setState({ isOpen: !isOpen })
+ }
+
+ renderOptions () {
+ const { options, onSelect, selectedOption } = this.props
+
+ return h('div', [
+ h('div.simple-dropdown__close-area', {
+ onClick: event => {
+ event.stopPropagation()
+ this.handleClose()
+ },
+ }),
+ h('div.simple-dropdown__options', [
+ ...options.map(option => {
+ return h(
+ 'div.simple-dropdown__option',
+ {
+ className: classnames({
+ 'simple-dropdown__option--selected': option.value === selectedOption,
+ }),
+ key: option.value,
+ onClick: () => {
+ if (option.value !== selectedOption) {
+ onSelect(option.value)
+ }
+
+ this.handleClose()
+ },
+ },
+ option.displayValue || option.value,
+ )
+ }),
+ ]),
+ ])
+ }
+
+ render () {
+ const { placeholder } = this.props
+ const { isOpen } = this.state
+
+ return h(
+ 'div.simple-dropdown',
+ {
+ onClick: () => this.toggleOpen(),
+ },
+ [
+ h('div.simple-dropdown__selected', this.getDisplayValue() || placeholder || 'Select'),
+ h('i.fa.fa-caret-down.fa-lg.simple-dropdown__caret'),
+ isOpen && this.renderOptions(),
+ ]
+ )
+ }
+}
+
+SimpleDropdown.propTypes = {
+ options: PropTypes.array.isRequired,
+ placeholder: PropTypes.string,
+ onSelect: PropTypes.func,
+ selectedOption: PropTypes.string,
+}
+
+module.exports = SimpleDropdown
diff --git a/ui/app/components/dropdowns/token-menu-dropdown.js b/ui/app/components/dropdowns/token-menu-dropdown.js
new file mode 100644
index 000000000..dc7a985e3
--- /dev/null
+++ b/ui/app/components/dropdowns/token-menu-dropdown.js
@@ -0,0 +1,51 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+
+module.exports = connect(null, mapDispatchToProps)(TokenMenuDropdown)
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showHideTokenConfirmationModal: (token) => {
+ dispatch(actions.showModal({ name: 'HIDE_TOKEN_CONFIRMATION', token }))
+ },
+ }
+}
+
+
+inherits(TokenMenuDropdown, Component)
+function TokenMenuDropdown () {
+ Component.call(this)
+
+ this.onClose = this.onClose.bind(this)
+}
+
+TokenMenuDropdown.prototype.onClose = function (e) {
+ e.stopPropagation()
+ this.props.onClose()
+}
+
+TokenMenuDropdown.prototype.render = function () {
+ const { showHideTokenConfirmationModal } = this.props
+
+ return h('div.token-menu-dropdown', {}, [
+ h('div.token-menu-dropdown__close-area', {
+ onClick: this.onClose,
+ }),
+ h('div.token-menu-dropdown__container', {}, [
+ h('div.token-menu-dropdown__options', {}, [
+
+ h('div.token-menu-dropdown__option', {
+ onClick: (e) => {
+ e.stopPropagation()
+ showHideTokenConfirmationModal(this.props.token)
+ this.props.onClose()
+ },
+ }, 'Hide Token'),
+
+ ]),
+ ]),
+ ])
+}
diff --git a/ui/app/components/editable-label.js b/ui/app/components/editable-label.js
index 8a5c8954f..eb41ec50c 100644
--- a/ui/app/components/editable-label.js
+++ b/ui/app/components/editable-label.js
@@ -1,57 +1,88 @@
-const Component = require('react').Component
+const { Component } = require('react')
+const PropTypes = require('prop-types')
const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const findDOMNode = require('react-dom').findDOMNode
+const classnames = require('classnames')
-module.exports = EditableLabel
+class EditableLabel extends Component {
+ constructor (props) {
+ super(props)
-inherits(EditableLabel, Component)
-function EditableLabel () {
- Component.call(this)
-}
+ this.state = {
+ isEditing: false,
+ value: props.defaultValue || '',
+ }
+ }
+
+ handleSubmit () {
+ const { value } = this.state
+
+ if (value === '') {
+ return
+ }
+
+ Promise.resolve(this.props.onSubmit(value))
+ .then(() => this.setState({ isEditing: false }))
+ }
+
+ saveIfEnter (event) {
+ if (event.key === 'Enter') {
+ this.handleSubmit()
+ }
+ }
-EditableLabel.prototype.render = function () {
- const props = this.props
- const state = this.state
+ renderEditing () {
+ const { value } = this.state
- if (state && state.isEditingLabel) {
- return h('div.editable-label', [
- h('input.sizing-input', {
- defaultValue: props.textValue,
- maxLength: '20',
+ return ([
+ h('input.large-input.editable-label__input', {
+ type: 'text',
+ required: true,
+ value: this.state.value,
onKeyPress: (event) => {
- this.saveIfEnter(event)
+ if (event.key === 'Enter') {
+ this.handleSubmit()
+ }
},
+ onChange: event => this.setState({ value: event.target.value }),
+ className: classnames({ 'editable-label__input--error': value === '' }),
}),
- h('button.editable-button', {
- onClick: () => this.saveText(),
- }, 'Save'),
+ h('div.editable-label__icon-wrapper', [
+ h('i.fa.fa-check.editable-label__icon', {
+ onClick: () => this.handleSubmit(),
+ }),
+ ]),
])
- } else {
- return h('div.name-label', {
- onClick: (event) => {
- const nameAttribute = event.target.getAttribute('name')
- // checks for class to handle smaller CTA above the account name
- const classAttribute = event.target.getAttribute('class')
- if (nameAttribute === 'edit' || classAttribute === 'edit-text') {
- this.setState({ isEditingLabel: true })
- }
- },
- }, this.props.children)
}
-}
-EditableLabel.prototype.saveIfEnter = function (event) {
- if (event.key === 'Enter') {
- this.saveText()
+ renderReadonly () {
+ return ([
+ h('div.editable-label__value', this.state.value),
+ h('div.editable-label__icon-wrapper', [
+ h('i.fa.fa-pencil.editable-label__icon', {
+ onClick: () => this.setState({ isEditing: true }),
+ }),
+ ]),
+ ])
+ }
+
+ render () {
+ const { isEditing } = this.state
+ const { className } = this.props
+
+ return (
+ h('div.editable-label', { className: classnames(className) },
+ isEditing
+ ? this.renderEditing()
+ : this.renderReadonly()
+ )
+ )
}
}
-EditableLabel.prototype.saveText = function () {
- // eslint-disable-next-line react/no-find-dom-node
- var container = findDOMNode(this)
- var text = container.querySelector('.editable-label input').value
- var truncatedText = text.substring(0, 20)
- this.props.saveText(truncatedText)
- this.setState({ isEditingLabel: false, textLabel: truncatedText })
+EditableLabel.propTypes = {
+ onSubmit: PropTypes.func.isRequired,
+ defaultValue: PropTypes.string,
+ className: PropTypes.string,
}
+
+module.exports = EditableLabel
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index c85a23514..6553053f7 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -44,7 +44,7 @@ EnsInput.prototype.render = function () {
return h('div', {
style: { width: '100%' },
}, [
- h('input.large-input', opts),
+ h('input.large-input.send-screen-input', opts),
// The address book functionality.
h('datalist#addresses',
[
@@ -125,7 +125,7 @@ EnsInput.prototype.componentDidUpdate = function (prevProps, prevState) {
EnsInput.prototype.ensIcon = function (recipient) {
const { hoverText } = this.state || {}
- return h('span', {
+ return h('span.#ensIcon', {
title: hoverText,
style: {
position: 'absolute',
diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js
index 4f538fd31..1be8c9731 100644
--- a/ui/app/components/eth-balance.js
+++ b/ui/app/components/eth-balance.js
@@ -1,8 +1,10 @@
-const Component = require('react').Component
+const { Component } = require('react')
const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const formatBalance = require('../util').formatBalance
-const generateBalanceObject = require('../util').generateBalanceObject
+const { inherits } = require('util')
+const {
+ formatBalance,
+ generateBalanceObject,
+} = require('../util')
const Tooltip = require('./tooltip.js')
const FiatValue = require('./fiat-value.js')
@@ -14,11 +16,10 @@ function EthBalanceComponent () {
}
EthBalanceComponent.prototype.render = function () {
- var props = this.props
- let { value } = props
- const { style, width } = props
- var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
- value = value ? formatBalance(value, 6, needsParse) : '...'
+ const props = this.props
+ const { value, style, width, needsParse = true } = props
+
+ const formattedValue = value ? formatBalance(value, 6, needsParse) : '...'
return (
@@ -30,60 +31,66 @@ EthBalanceComponent.prototype.render = function () {
display: 'inline',
width,
},
- }, this.renderBalance(value)),
+ }, this.renderBalance(formattedValue)),
])
)
}
EthBalanceComponent.prototype.renderBalance = function (value) {
- var props = this.props
- const { conversionRate, shorten, incoming, currentCurrency } = props
if (value === 'None') return value
if (value === '...') return value
- var balanceObj = generateBalanceObject(value, shorten ? 1 : 3)
- var balance
- var splitBalance = value.split(' ')
- var ethNumber = splitBalance[0]
- var ethSuffix = splitBalance[1]
- const showFiat = 'showFiat' in props ? props.showFiat : true
- if (shorten) {
- balance = balanceObj.shortBalance
- } else {
- balance = balanceObj.balance
- }
+ const {
+ conversionRate,
+ shorten,
+ incoming,
+ currentCurrency,
+ hideTooltip,
+ styleOveride,
+ showFiat = true,
+ } = this.props
+ const { fontSize, color, fontFamily, lineHeight } = styleOveride
- var label = balanceObj.label
+ const { shortBalance, balance, label } = generateBalanceObject(value, shorten ? 1 : 3)
+ const balanceToRender = shorten ? shortBalance : balance
+
+ const [ethNumber, ethSuffix] = value.split(' ')
+ const containerProps = hideTooltip ? {} : {
+ position: 'bottom',
+ title: `${ethNumber} ${ethSuffix}`,
+ }
return (
- h(Tooltip, {
- position: 'bottom',
- title: `${ethNumber} ${ethSuffix}`,
- }, h('div.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('div', {
- style: {
- width: '100%',
- textAlign: 'right',
- },
- }, incoming ? `+${balance}` : balance),
- h('div', {
+ h(hideTooltip ? 'div' : Tooltip,
+ containerProps,
+ h('div.flex-column', [
+ h('.flex-row', {
style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
+ alignItems: 'flex-end',
+ lineHeight: lineHeight || '13px',
+ fontFamily: fontFamily || 'Montserrat Light',
+ textRendering: 'geometricPrecision',
},
- }, label),
- ]),
+ }, [
+ h('div', {
+ style: {
+ width: '100%',
+ textAlign: 'right',
+ fontSize: fontSize || 'inherit',
+ color: color || 'inherit',
+ },
+ }, incoming ? `+${balanceToRender}` : balanceToRender),
+ h('div', {
+ style: {
+ color: color || '#AEAEAE',
+ fontSize: fontSize || '12px',
+ marginLeft: '5px',
+ },
+ }, label),
+ ]),
- showFiat ? h(FiatValue, { value: props.value, conversionRate, currentCurrency }) : null,
- ]))
+ showFiat ? h(FiatValue, { value: this.props.value, conversionRate, currentCurrency }) : null,
+ ])
+ )
)
}
diff --git a/ui/app/components/fiat-value.js b/ui/app/components/fiat-value.js
index d69f41d11..56465fc9d 100644
--- a/ui/app/components/fiat-value.js
+++ b/ui/app/components/fiat-value.js
@@ -12,7 +12,7 @@ function FiatValue () {
FiatValue.prototype.render = function () {
const props = this.props
- const { conversionRate, currentCurrency } = props
+ const { conversionRate, currentCurrency, style } = props
const renderedCurrency = currentCurrency || ''
const value = formatBalance(props.value, 6)
@@ -29,16 +29,18 @@ FiatValue.prototype.render = function () {
fiatTooltipNumber = 'Unknown'
}
- return fiatDisplay(fiatDisplayNumber, renderedCurrency.toUpperCase())
+ return fiatDisplay(fiatDisplayNumber, renderedCurrency.toUpperCase(), style)
}
-function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
+function fiatDisplay (fiatDisplayNumber, fiatSuffix, styleOveride = {}) {
+ const { fontSize, color, fontFamily, lineHeight } = styleOveride
+
if (fiatDisplayNumber !== 'N/A') {
return h('.flex-row', {
style: {
alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
+ lineHeight: lineHeight || '13px',
+ fontFamily: fontFamily || 'Montserrat Light',
textRendering: 'geometricPrecision',
},
}, [
@@ -46,15 +48,15 @@ function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
style: {
width: '100%',
textAlign: 'right',
- fontSize: '12px',
- color: '#333333',
+ fontSize: fontSize || '12px',
+ color: color || '#333333',
},
}, fiatDisplayNumber),
h('div', {
style: {
- color: '#AEAEAE',
+ color: color || '#AEAEAE',
marginLeft: '5px',
- fontSize: '12px',
+ fontSize: fontSize || '12px',
},
}, fiatSuffix),
])
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index bb476ca7b..b803b7ceb 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -1,13 +1,15 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const connect = require('react-redux').connect
const isNode = require('detect-node')
const findDOMNode = require('react-dom').findDOMNode
const jazzicon = require('jazzicon')
const iconFactoryGen = require('../../lib/icon-factory')
const iconFactory = iconFactoryGen(jazzicon)
+const { toDataUrl } = require('../../lib/blockies')
-module.exports = IdenticonComponent
+module.exports = connect(mapStateToProps)(IdenticonComponent)
inherits(IdenticonComponent, Component)
function IdenticonComponent () {
@@ -16,59 +18,100 @@ function IdenticonComponent () {
this.defaultDiameter = 46
}
+function mapStateToProps (state) {
+ return {
+ useBlockie: state.metamask.useBlockie,
+ }
+}
+
IdenticonComponent.prototype.render = function () {
var props = this.props
+ const { className = '', address } = props
var diameter = props.diameter || this.defaultDiameter
- return (
- h('div', {
- key: 'identicon-' + this.props.address,
- style: {
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- height: diameter,
- width: diameter,
- borderRadius: diameter / 2,
- overflow: 'hidden',
- },
- })
- )
+
+ return address
+ ? (
+ h('div', {
+ className: `${className} identicon`,
+ key: 'identicon-' + address,
+ style: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: diameter,
+ width: diameter,
+ borderRadius: diameter / 2,
+ overflow: 'hidden',
+ },
+ })
+ )
+ : (
+ h('img.balance-icon', {
+ src: '../images/eth_logo.svg',
+ style: {
+ height: diameter,
+ width: diameter,
+ borderRadius: diameter / 2,
+ },
+ })
+ )
}
IdenticonComponent.prototype.componentDidMount = function () {
var props = this.props
- const { address } = props
+ const { address, useBlockie } = props
if (!address) return
- // eslint-disable-next-line react/no-find-dom-node
- var container = findDOMNode(this)
-
- var diameter = props.diameter || this.defaultDiameter
if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter)
- container.appendChild(img)
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
+
+ const diameter = props.diameter || this.defaultDiameter
+
+ if (useBlockie) {
+ _generateBlockie(container, address, diameter)
+ } else {
+ _generateJazzicon(container, address, diameter)
+ }
}
}
IdenticonComponent.prototype.componentDidUpdate = function () {
var props = this.props
- const { address } = props
+ const { address, useBlockie } = props
if (!address) return
- // eslint-disable-next-line react/no-find-dom-node
- var container = findDOMNode(this)
+ if (!isNode) {
+ // eslint-disable-next-line react/no-find-dom-node
+ var container = findDOMNode(this)
- var children = container.children
- for (var i = 0; i < children.length; i++) {
- container.removeChild(children[i])
- }
+ var children = container.children
+ for (var i = 0; i < children.length; i++) {
+ container.removeChild(children[i])
+ }
- var diameter = props.diameter || this.defaultDiameter
- if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter)
- container.appendChild(img)
+ const diameter = props.diameter || this.defaultDiameter
+
+ if (useBlockie) {
+ _generateBlockie(container, address, diameter)
+ } else {
+ _generateJazzicon(container, address, diameter)
+ }
}
}
+function _generateBlockie (container, address, diameter) {
+ const img = new Image()
+ img.src = toDataUrl(address)
+ const dia = !diameter || diameter < 50 ? 50 : diameter
+ img.height = dia * 1.25
+ img.width = dia * 1.25
+ container.appendChild(img)
+}
+
+function _generateJazzicon (container, address, diameter) {
+ const img = iconFactory.iconForAddress(address, diameter)
+ container.appendChild(img)
+}
diff --git a/ui/app/components/input-number.js b/ui/app/components/input-number.js
new file mode 100644
index 000000000..fd8c5c309
--- /dev/null
+++ b/ui/app/components/input-number.js
@@ -0,0 +1,73 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const CurrencyInput = require('./currency-input')
+const {
+ addCurrencies,
+ conversionGTE,
+ conversionLTE,
+ subtractCurrencies,
+} = require('../conversion-util')
+
+module.exports = InputNumber
+
+inherits(InputNumber, Component)
+function InputNumber () {
+ Component.call(this)
+
+ this.setValue = this.setValue.bind(this)
+}
+
+function isValidInput (text) {
+ const re = /^([1-9]\d*|0)(\.|\.\d*)?$/
+ return re.test(text)
+}
+
+InputNumber.prototype.setValue = function (newValue) {
+ if (newValue && !isValidInput(newValue)) return
+ const { fixed, min = -1, max = Infinity, onChange } = this.props
+
+ newValue = fixed ? newValue.toFixed(4) : newValue
+
+ const newValueGreaterThanMin = conversionGTE(
+ { value: newValue || '0', fromNumericBase: 'dec' },
+ { value: min, fromNumericBase: 'hex' },
+ )
+
+ const newValueLessThanMax = conversionLTE(
+ { value: newValue || '0', fromNumericBase: 'dec' },
+ { value: max, fromNumericBase: 'hex' },
+ )
+ if (newValueGreaterThanMin && newValueLessThanMax) {
+ onChange(newValue)
+ } else if (!newValueGreaterThanMin) {
+ onChange(min)
+ } else if (!newValueLessThanMax) {
+ onChange(max)
+ }
+}
+
+InputNumber.prototype.render = function () {
+ const { unitLabel, step = 1, placeholder, value = 0 } = this.props
+
+ return h('div.customize-gas-input-wrapper', {}, [
+ h(CurrencyInput, {
+ className: 'customize-gas-input',
+ value,
+ placeholder,
+ onInputChange: newValue => {
+ this.setValue(newValue)
+ },
+ }),
+ h('span.gas-tooltip-input-detail', {}, [unitLabel]),
+ h('div.gas-tooltip-input-arrows', {}, [
+ h('i.fa.fa-angle-up', {
+ onClick: () => this.setValue(addCurrencies(value, step)),
+ }),
+ h('i.fa.fa-angle-down', {
+ style: { cursor: 'pointer' },
+ onClick: () => this.setValue(subtractCurrencies(value, step)),
+ }),
+ ]),
+ ])
+}
diff --git a/ui/app/components/loading.js b/ui/app/components/loading.js
index b8e2eb599..cb6fa51fb 100644
--- a/ui/app/components/loading.js
+++ b/ui/app/components/loading.js
@@ -1,55 +1,30 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
+const { Component } = require('react')
const h = require('react-hyperscript')
-
-
-inherits(LoadingIndicator, Component)
-module.exports = LoadingIndicator
-
-function LoadingIndicator () {
- Component.call(this)
+const PropTypes = require('prop-types')
+
+class LoadingIndicator extends Component {
+ renderMessage () {
+ const { loadingMessage } = this.props
+ return loadingMessage && h('span', loadingMessage)
+ }
+
+ render () {
+ return (
+ h('.full-flex-height.loading-overlay', {}, [
+ h('img', {
+ src: 'images/loading.svg',
+ }),
+
+ h('br'),
+
+ this.renderMessage(),
+ ])
+ )
+ }
}
-LoadingIndicator.prototype.render = function () {
- const { isLoading, loadingMessage, canBypass, bypass } = this.props
-
- return (
- isLoading ? h('.full-flex-height', {
- style: {
- left: '0px',
- zIndex: 10,
- position: 'absolute',
- flexDirection: 'column',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '100%',
- width: '100%',
- background: 'rgba(255, 255, 255, 0.8)',
- },
- }, [
- canBypass ? h( 'i.fa.fa-close.cursor-pointer.close-loading', {
- style: {
- position: 'absolute',
- top: '1px',
- right: '15px',
- color: '#AEAEAE',
- },
- onClick: bypass,
- }) : null,
-
- h('img', {
- src: 'images/loading.svg',
- }),
-
- h('br'),
-
- showMessageIfAny(loadingMessage),
- ]) : null
- )
+LoadingIndicator.propTypes = {
+ loadingMessage: PropTypes.string,
}
-function showMessageIfAny (loadingMessage) {
- if (!loadingMessage) return null
- return h('span', loadingMessage)
-}
+module.exports = LoadingIndicator
diff --git a/ui/app/components/mascot.js b/ui/app/components/mascot.js
index 973ec2cad..3b0d3e31b 100644
--- a/ui/app/components/mascot.js
+++ b/ui/app/components/mascot.js
@@ -7,13 +7,13 @@ const debounce = require('debounce')
module.exports = Mascot
inherits(Mascot, Component)
-function Mascot () {
+function Mascot ({width = '200', height = '200'}) {
Component.call(this)
this.logo = metamaskLogo({
followMouse: true,
pxNotRatio: true,
- width: 200,
- height: 200,
+ width,
+ height,
})
this.refollowMouse = debounce(this.logo.setFollowMouse.bind(this.logo, true), 1000)
diff --git a/ui/app/components/menu-droppo.js b/ui/app/components/menu-droppo.js
index e6276f3b1..c80bee2be 100644
--- a/ui/app/components/menu-droppo.js
+++ b/ui/app/components/menu-droppo.js
@@ -13,6 +13,7 @@ function MenuDroppoComponent () {
}
MenuDroppoComponent.prototype.render = function () {
+ const { containerClassName = '' } = this.props
const speed = this.props.speed || '300ms'
const useCssTransition = this.props.useCssTransition
const zIndex = ('zIndex' in this.props) ? this.props.zIndex : 0
@@ -26,8 +27,9 @@ MenuDroppoComponent.prototype.render = function () {
style.zIndex = zIndex
return (
- h('.menu-droppo-container', {
+ h('div', {
style,
+ className: `.menu-droppo-container ${containerClassName}`,
}, [
h('style', `
.menu-droppo-enter {
diff --git a/ui/app/components/modals/account-details-modal.js b/ui/app/components/modals/account-details-modal.js
new file mode 100644
index 000000000..c1f7a3236
--- /dev/null
+++ b/ui/app/components/modals/account-details-modal.js
@@ -0,0 +1,75 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const AccountModalContainer = require('./account-modal-container')
+const { getSelectedIdentity } = require('../../selectors')
+const genAccountLink = require('../../../lib/account-link.js')
+const QrView = require('../qr-code')
+const EditableLabel = require('../editable-label')
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ selectedIdentity: getSelectedIdentity(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ // Is this supposed to be used somewhere?
+ showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
+ showExportPrivateKeyModal: () => {
+ dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
+ },
+ hideModal: () => dispatch(actions.hideModal()),
+ saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)),
+ }
+}
+
+inherits(AccountDetailsModal, Component)
+function AccountDetailsModal () {
+ Component.call(this)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal)
+
+// Not yet pixel perfect todos:
+ // fonts of qr-header
+
+AccountDetailsModal.prototype.render = function () {
+ const {
+ selectedIdentity,
+ network,
+ showExportPrivateKeyModal,
+ saveAccountLabel,
+ } = this.props
+ const { name, address } = selectedIdentity
+
+ return h(AccountModalContainer, {}, [
+ h(EditableLabel, {
+ className: 'account-modal__name',
+ defaultValue: name,
+ onSubmit: label => saveAccountLabel(address, label),
+ }),
+
+ h(QrView, {
+ Qr: {
+ data: address,
+ },
+ }),
+
+ h('div.account-modal-divider'),
+
+ h('button.btn-clear.account-modal__button', {
+ onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }),
+ }, 'View account on Etherscan'),
+
+ // Holding on redesign for Export Private Key functionality
+ h('button.btn-clear.account-modal__button', {
+ onClick: () => showExportPrivateKeyModal(),
+ }, 'Export private key'),
+
+ ])
+}
diff --git a/ui/app/components/modals/account-modal-container.js b/ui/app/components/modals/account-modal-container.js
new file mode 100644
index 000000000..c548fb7b3
--- /dev/null
+++ b/ui/app/components/modals/account-modal-container.js
@@ -0,0 +1,74 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const { getSelectedIdentity } = require('../../selectors')
+const Identicon = require('../identicon')
+
+function mapStateToProps (state) {
+ return {
+ selectedIdentity: getSelectedIdentity(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ }
+}
+
+inherits(AccountModalContainer, Component)
+function AccountModalContainer () {
+ Component.call(this)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountModalContainer)
+
+AccountModalContainer.prototype.render = function () {
+ const {
+ selectedIdentity,
+ showBackButton = false,
+ backButtonAction,
+ } = this.props
+ let { children } = this.props
+
+ if (children.constructor !== Array) {
+ children = [children]
+ }
+
+ return h('div', { style: { borderRadius: '4px' }}, [
+ h('div.account-modal-container', [
+
+ h('div', [
+
+ // Needs a border; requires changes to svg
+ h(Identicon, {
+ address: selectedIdentity.address,
+ diameter: 64,
+ style: {},
+ }),
+
+ ]),
+
+ showBackButton && h('div.account-modal-back', {
+ onClick: backButtonAction,
+ }, [
+
+ h('i.fa.fa-angle-left.fa-lg'),
+
+ h('span.account-modal-back__text', ' Back'),
+
+ ]),
+
+ h('div.account-modal-close', {
+ onClick: this.props.hideModal,
+ }),
+
+ ...children,
+
+ ]),
+ ])
+}
diff --git a/ui/app/components/modals/buy-options-modal.js b/ui/app/components/modals/buy-options-modal.js
new file mode 100644
index 000000000..74a7a847e
--- /dev/null
+++ b/ui/app/components/modals/buy-options-modal.js
@@ -0,0 +1,95 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const networkNames = require('../../../../app/scripts/config.js').networkNames
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ address: state.metamask.selectedAddress,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ toCoinbase: (address) => {
+ dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+ },
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ showAccountDetailModal: () => {
+ dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
+ },
+ toFaucet: network => dispatch(actions.buyEth({ network })),
+ }
+}
+
+inherits(BuyOptions, Component)
+function BuyOptions () {
+ Component.call(this)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(BuyOptions)
+
+BuyOptions.prototype.renderModalContentOption = function (title, header, onClick) {
+ return h('div.buy-modal-content-option', {
+ onClick,
+ }, [
+ h('div.buy-modal-content-option-title', {}, title),
+ h('div.buy-modal-content-option-subtitle', {}, header),
+ ])
+}
+
+BuyOptions.prototype.render = function () {
+ const { network, toCoinbase, address, toFaucet } = this.props
+ const isTestNetwork = ['3', '4', '42'].find(n => n === network)
+ const networkName = networkNames[network]
+
+ return h('div', {}, [
+ h('div.buy-modal-content.transfers-subview', {
+ }, [
+ h('div.buy-modal-content-title-wrapper.flex-column.flex-center', {
+ style: {},
+ }, [
+ h('div.buy-modal-content-title', {
+ style: {},
+ }, 'Transfers'),
+ h('div', {}, 'How would you like to deposit Ether?'),
+ ]),
+
+ h('div.buy-modal-content-options.flex-column.flex-center', {}, [
+
+ isTestNetwork
+ ? this.renderModalContentOption(networkName, 'Test Faucet', () => toFaucet(network))
+ : this.renderModalContentOption('Coinbase', 'Deposit with Fiat', () => toCoinbase(address)),
+
+ // h('div.buy-modal-content-option', {}, [
+ // h('div.buy-modal-content-option-title', {}, 'Shapeshift'),
+ // h('div.buy-modal-content-option-subtitle', {}, 'Trade any digital asset for any other'),
+ // ]),,
+
+ this.renderModalContentOption(
+ 'Direct Deposit',
+ 'Deposit from another account',
+ () => this.goToAccountDetailsModal()
+ ),
+
+ ]),
+
+ h('button', {
+ style: {
+ background: 'white',
+ },
+ onClick: () => { this.props.hideModal() },
+ }, h('div.buy-modal-content-footer#buy-modal-content-footer-text', {}, 'Cancel')),
+ ]),
+ ])
+}
+
+BuyOptions.prototype.goToAccountDetailsModal = function () {
+ this.props.hideModal()
+ this.props.showAccountDetailModal()
+}
diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js
new file mode 100644
index 000000000..532d66653
--- /dev/null
+++ b/ui/app/components/modals/deposit-ether-modal.js
@@ -0,0 +1,184 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const networkNames = require('../../../../app/scripts/config.js').networkNames
+const ShapeshiftForm = require('../shapeshift-form')
+
+const DIRECT_DEPOSIT_ROW_TITLE = 'Directly Deposit Ether'
+const DIRECT_DEPOSIT_ROW_TEXT = `If you already have some Ether, the quickest way to get Ether in
+your new wallet by direct deposit.`
+const COINBASE_ROW_TITLE = 'Buy on Coinbase'
+const COINBASE_ROW_TEXT = `Coinbase is the world’s most popular way to buy and sell bitcoin,
+ethereum, and litecoin.`
+const SHAPESHIFT_ROW_TITLE = 'Deposit with ShapeShift'
+const SHAPESHIFT_ROW_TEXT = `If you own other cryptocurrencies, you can trade and deposit Ether
+directly into your MetaMask wallet. No Account Needed.`
+const FAUCET_ROW_TITLE = 'Test Faucet'
+const facuetRowText = networkName => `Get Ether from a faucet for the ${networkName}`
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ address: state.metamask.selectedAddress,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ toCoinbase: (address) => {
+ dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+ },
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ showAccountDetailModal: () => {
+ dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
+ },
+ toFaucet: network => dispatch(actions.buyEth({ network })),
+ }
+}
+
+inherits(DepositEtherModal, Component)
+function DepositEtherModal () {
+ Component.call(this)
+
+ this.state = {
+ buyingWithShapeshift: false,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal)
+
+DepositEtherModal.prototype.renderRow = function ({
+ logo,
+ title,
+ text,
+ buttonLabel,
+ onButtonClick,
+ hide,
+ className,
+ hideButton,
+ hideTitle,
+ onBackClick,
+ showBackButton,
+}) {
+ if (hide) {
+ return null
+ }
+
+ return h('div', {
+ className: className || 'deposit-ether-modal__buy-row',
+ }, [
+
+ onBackClick && showBackButton && h('div.deposit-ether-modal__buy-row__back', {
+ onClick: onBackClick,
+ }, [
+
+ h('i.fa.fa-arrow-left.cursor-pointer'),
+
+ ]),
+
+ h('div.deposit-ether-modal__buy-row__logo', [logo]),
+
+ h('div.deposit-ether-modal__buy-row__description', [
+
+ !hideTitle && h('div.deposit-ether-modal__buy-row__description__title', [title]),
+
+ h('div.deposit-ether-modal__buy-row__description__text', [text]),
+
+ ]),
+
+ !hideButton && h('div.deposit-ether-modal__buy-row__button', [
+ h('button.deposit-ether-modal__deposit-button', {
+ onClick: onButtonClick,
+ }, [buttonLabel]),
+ ]),
+
+ ])
+}
+
+DepositEtherModal.prototype.render = function () {
+ const { network, toCoinbase, address, toFaucet } = this.props
+ const { buyingWithShapeshift } = this.state
+
+ const isTestNetwork = ['3', '4', '42'].find(n => n === network)
+ const networkName = networkNames[network]
+
+ return h('div.deposit-ether-modal', {}, [
+
+ h('div.deposit-ether-modal__header', [
+
+ h('div.deposit-ether-modal__header__title', ['Deposit Ether']),
+
+ h('div.deposit-ether-modal__header__description', [
+ 'To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet.',
+ ]),
+
+ h('div.deposit-ether-modal__header__close', {
+ onClick: () => {
+ this.setState({ buyingWithShapeshift: false })
+ this.props.hideModal()
+ },
+ }),
+
+ ]),
+
+ h('div.deposit-ether-modal__buy-rows', [
+
+ this.renderRow({
+ logo: h('img.deposit-ether-modal__buy-row__eth-logo', { src: '../../../images/eth_logo.svg' }),
+ title: DIRECT_DEPOSIT_ROW_TITLE,
+ text: DIRECT_DEPOSIT_ROW_TEXT,
+ buttonLabel: 'View Account',
+ onButtonClick: () => this.goToAccountDetailsModal(),
+ hide: buyingWithShapeshift,
+ }),
+
+ this.renderRow({
+ logo: h('i.fa.fa-tint.fa-2x'),
+ title: FAUCET_ROW_TITLE,
+ text: facuetRowText(networkName),
+ buttonLabel: 'Get Ether',
+ onButtonClick: () => toFaucet(network),
+ hide: !isTestNetwork || buyingWithShapeshift,
+ }),
+
+ this.renderRow({
+ logo: h('img.deposit-ether-modal__buy-row__coinbase-logo', {
+ src: '../../../images/coinbase logo.png',
+ }),
+ title: COINBASE_ROW_TITLE,
+ text: COINBASE_ROW_TEXT,
+ buttonLabel: 'Continue to Coinbase',
+ onButtonClick: () => toCoinbase(address),
+ hide: isTestNetwork || buyingWithShapeshift,
+ }),
+
+ this.renderRow({
+ logo: h('img.deposit-ether-modal__buy-row__shapeshift-logo', {
+ src: '../../../images/shapeshift logo.png',
+ }),
+ title: SHAPESHIFT_ROW_TITLE,
+ text: SHAPESHIFT_ROW_TEXT,
+ buttonLabel: 'Buy with Shapeshift',
+ onButtonClick: () => this.setState({ buyingWithShapeshift: true }),
+ hide: isTestNetwork,
+ hideButton: buyingWithShapeshift,
+ hideTitle: buyingWithShapeshift,
+ onBackClick: () => this.setState({ buyingWithShapeshift: false }),
+ showBackButton: this.state.buyingWithShapeshift,
+ className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy',
+ }),
+
+ buyingWithShapeshift && h(ShapeshiftForm),
+
+ ]),
+ ])
+}
+
+DepositEtherModal.prototype.goToAccountDetailsModal = function () {
+ this.props.hideModal()
+ this.props.showAccountDetailModal()
+}
diff --git a/ui/app/components/modals/edit-account-name-modal.js b/ui/app/components/modals/edit-account-name-modal.js
new file mode 100644
index 000000000..e2361140d
--- /dev/null
+++ b/ui/app/components/modals/edit-account-name-modal.js
@@ -0,0 +1,77 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const { getSelectedAccount } = require('../../selectors')
+
+function mapStateToProps (state) {
+ return {
+ selectedAccount: getSelectedAccount(state),
+ identity: state.appState.modal.modalState.identity,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ saveAccountLabel: (account, label) => {
+ dispatch(actions.saveAccountLabel(account, label))
+ },
+ }
+}
+
+inherits(EditAccountNameModal, Component)
+function EditAccountNameModal (props) {
+ Component.call(this)
+
+ this.state = {
+ inputText: props.identity.name,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(EditAccountNameModal)
+
+EditAccountNameModal.prototype.render = function () {
+ const { hideModal, saveAccountLabel, identity } = this.props
+
+ return h('div', {}, [
+ h('div.flex-column.edit-account-name-modal-content', {
+ }, [
+
+ h('div.edit-account-name-modal-cancel', {
+ onClick: () => {
+ hideModal()
+ },
+ }, [
+ h('i.fa.fa-times'),
+ ]),
+
+ h('div.edit-account-name-modal-title', {
+ }, ['Edit Account Name']),
+
+ h('input.edit-account-name-modal-input', {
+ placeholder: identity.name,
+ onChange: (event) => {
+ this.setState({ inputText: event.target.value })
+ },
+ value: this.state.inputText,
+ }, []),
+
+ h('button.btn-clear.edit-account-name-modal-save-button', {
+ onClick: () => {
+ if (this.state.inputText.length !== 0) {
+ saveAccountLabel(identity.address, this.state.inputText)
+ hideModal()
+ }
+ },
+ disabled: this.state.inputText.length === 0,
+ }, [
+ 'SAVE',
+ ]),
+
+ ]),
+ ])
+}
diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js
new file mode 100644
index 000000000..422f23f44
--- /dev/null
+++ b/ui/app/components/modals/export-private-key-modal.js
@@ -0,0 +1,141 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const ethUtil = require('ethereumjs-util')
+const actions = require('../../actions')
+const AccountModalContainer = require('./account-modal-container')
+const { getSelectedIdentity } = require('../../selectors')
+const ReadOnlyInput = require('../readonly-input')
+const copyToClipboard = require('copy-to-clipboard')
+
+function mapStateToProps (state) {
+ return {
+ warning: state.appState.warning,
+ privateKey: state.appState.accountDetail.privateKey,
+ network: state.metamask.network,
+ selectedIdentity: getSelectedIdentity(state),
+ previousModalState: state.appState.modal.previousModalState.name,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ exportAccount: (password, address) => dispatch(actions.exportAccount(password, address)),
+ showAccountDetailModal: () => dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })),
+ hideModal: () => dispatch(actions.hideModal()),
+ }
+}
+
+inherits(ExportPrivateKeyModal, Component)
+function ExportPrivateKeyModal () {
+ Component.call(this)
+
+ this.state = {
+ password: '',
+ privateKey: null,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ExportPrivateKeyModal)
+
+ExportPrivateKeyModal.prototype.exportAccountAndGetPrivateKey = function (password, address) {
+ const { exportAccount } = this.props
+
+ exportAccount(password, address)
+ .then(privateKey => this.setState({ privateKey }))
+}
+
+ExportPrivateKeyModal.prototype.renderPasswordLabel = function (privateKey) {
+ return h('span.private-key-password-label', privateKey
+ ? 'This is your private key (click to copy)'
+ : 'Type Your Password'
+ )
+}
+
+ExportPrivateKeyModal.prototype.renderPasswordInput = function (privateKey) {
+ const plainKey = privateKey && ethUtil.stripHexPrefix(privateKey)
+
+ return privateKey
+ ? h(ReadOnlyInput, {
+ wrapperClass: 'private-key-password-display-wrapper',
+ inputClass: 'private-key-password-display-textarea',
+ textarea: true,
+ value: plainKey,
+ onClick: () => copyToClipboard(plainKey),
+ })
+ : h('input.private-key-password-input', {
+ type: 'password',
+ onChange: event => this.setState({ password: event.target.value }),
+ })
+}
+
+ExportPrivateKeyModal.prototype.renderButton = function (className, onClick, label) {
+ return h('button', {
+ className,
+ onClick,
+ }, label)
+}
+
+ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) {
+ return h('div.export-private-key-buttons', {}, [
+ !privateKey && this.renderButton(
+ 'btn-cancel export-private-key__button export-private-key__button--cancel',
+ () => hideModal(),
+ 'Cancel'
+ ),
+
+ (privateKey
+ ? this.renderButton('btn-clear export-private-key__button', () => hideModal(), 'Done')
+ : this.renderButton('btn-clear export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), 'Confirm')
+ ),
+
+ ])
+}
+
+ExportPrivateKeyModal.prototype.render = function () {
+ const {
+ selectedIdentity,
+ warning,
+ showAccountDetailModal,
+ hideModal,
+ previousModalState,
+ } = this.props
+ const { name, address } = selectedIdentity
+
+ const { privateKey } = this.state
+
+ return h(AccountModalContainer, {
+ showBackButton: previousModalState === 'ACCOUNT_DETAILS',
+ backButtonAction: () => showAccountDetailModal(),
+ }, [
+
+ h('span.account-name', name),
+
+ h(ReadOnlyInput, {
+ wrapperClass: 'ellip-address-wrapper',
+ inputClass: 'qr-ellip-address ellip-address',
+ value: address,
+ }),
+
+ h('div.account-modal-divider'),
+
+ h('span.modal-body-title', 'Show Private Keys'),
+
+ h('div.private-key-password', {}, [
+ this.renderPasswordLabel(privateKey),
+
+ this.renderPasswordInput(privateKey),
+
+ !warning ? null : h('span.private-key-password-error', warning),
+ ]),
+
+ h('div.private-key-password-warning', `Warning: Never disclose this key.
+ Anyone with your private keys can take steal any assets held in your
+ account.`
+ ),
+
+ this.renderButtons(privateKey, this.state.password, address, hideModal),
+
+ ])
+}
diff --git a/ui/app/components/modals/hide-token-confirmation-modal.js b/ui/app/components/modals/hide-token-confirmation-modal.js
new file mode 100644
index 000000000..56c7ba299
--- /dev/null
+++ b/ui/app/components/modals/hide-token-confirmation-modal.js
@@ -0,0 +1,74 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const Identicon = require('../identicon')
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ token: state.appState.modal.modalState.token,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => dispatch(actions.hideModal()),
+ hideToken: address => {
+ dispatch(actions.removeToken(address))
+ .then(() => {
+ dispatch(actions.hideModal())
+ })
+ },
+ }
+}
+
+inherits(HideTokenConfirmationModal, Component)
+function HideTokenConfirmationModal () {
+ Component.call(this)
+
+ this.state = {}
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(HideTokenConfirmationModal)
+
+HideTokenConfirmationModal.prototype.render = function () {
+ const { token, network, hideToken, hideModal } = this.props
+ const { symbol, address } = token
+
+ return h('div.hide-token-confirmation', {}, [
+ h('div.hide-token-confirmation__container', {
+ }, [
+ h('div.hide-token-confirmation__title', {}, [
+ 'Hide Token?',
+ ]),
+
+ h(Identicon, {
+ className: 'hide-token-confirmation__identicon',
+ diameter: 45,
+ address,
+ network,
+ }),
+
+ h('div.hide-token-confirmation__symbol', {}, symbol),
+
+ h('div.hide-token-confirmation__copy', {}, [
+ 'You can add this token back in the future by going go to “Add token†in your accounts options menu.',
+ ]),
+
+ h('div.hide-token-confirmation__buttons', {}, [
+ h('button.btn-cancel.hide-token-confirmation__button', {
+ onClick: () => hideModal(),
+ }, [
+ 'CANCEL',
+ ]),
+ h('button.btn-clear.hide-token-confirmation__button', {
+ onClick: () => hideToken(address),
+ }, [
+ 'HIDE',
+ ]),
+ ]),
+ ]),
+ ])
+}
diff --git a/ui/app/components/modals/index.js b/ui/app/components/modals/index.js
new file mode 100644
index 000000000..1db1d33d4
--- /dev/null
+++ b/ui/app/components/modals/index.js
@@ -0,0 +1,5 @@
+const Modal = require('./modal')
+
+module.exports = {
+ Modal,
+}
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
new file mode 100644
index 000000000..97fe38292
--- /dev/null
+++ b/ui/app/components/modals/modal.js
@@ -0,0 +1,344 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const FadeModal = require('boron').FadeModal
+const actions = require('../../actions')
+const isMobileView = require('../../../lib/is-mobile-view')
+const isPopupOrNotification = require('../../../../app/scripts/lib/is-popup-or-notification')
+
+// Modal Components
+const BuyOptions = require('./buy-options-modal')
+const DepositEtherModal = require('./deposit-ether-modal')
+const AccountDetailsModal = require('./account-details-modal')
+const EditAccountNameModal = require('./edit-account-name-modal')
+const ExportPrivateKeyModal = require('./export-private-key-modal')
+const NewAccountModal = require('./new-account-modal')
+const ShapeshiftDepositTxModal = require('./shapeshift-deposit-tx-modal.js')
+const HideTokenConfirmationModal = require('./hide-token-confirmation-modal')
+const CustomizeGasModal = require('../customize-gas-modal')
+const NotifcationModal = require('./notification-modal')
+const ConfirmResetAccount = require('./notification-modals/confirm-reset-account')
+
+const accountModalStyle = {
+ mobileModalStyle: {
+ width: '95%',
+ // top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px',
+ borderRadius: '4px',
+ top: '10%',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ laptopModalStyle: {
+ width: '360px',
+ // top: 'calc(33% + 45px)',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px',
+ borderRadius: '4px',
+ top: '10%',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ contentStyle: {
+ borderRadius: '4px',
+ },
+}
+
+const MODALS = {
+ BUY: {
+ contents: [
+ h(BuyOptions, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ // top: isPopupOrNotification() === 'popup' ? '48vh' : '36.5vh',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ boxShadow: '0 0 7px 0 rgba(0,0,0,0.08)',
+ top: '10%',
+ },
+ laptopModalStyle: {
+ width: '66%',
+ maxWidth: '550px',
+ top: 'calc(10% + 10px)',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ boxShadow: '0 0 7px 0 rgba(0,0,0,0.08)',
+ transform: 'none',
+ },
+ },
+
+ DEPOSIT_ETHER: {
+ contents: [
+ h(DepositEtherModal, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '100%',
+ height: '100%',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ boxShadow: '0 0 7px 0 rgba(0,0,0,0.08)',
+ top: '0',
+ display: 'flex',
+ },
+ laptopModalStyle: {
+ width: '900px',
+ maxWidth: '900px',
+ top: 'calc(10% + 10px)',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ boxShadow: '0 0 6px 0 rgba(0,0,0,0.3)',
+ borderRadius: '8px',
+ transform: 'none',
+ },
+ contentStyle: {
+ borderRadius: '8px',
+ },
+ },
+
+ EDIT_ACCOUNT_NAME: {
+ contents: [
+ h(EditAccountNameModal, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ // top: isPopupOrNotification() === 'popup' ? '48vh' : '36.5vh',
+ top: '10%',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ laptopModalStyle: {
+ width: '375px',
+ // top: 'calc(30% + 10px)',
+ top: '10%',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 2px 2px 2px',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ },
+
+ ACCOUNT_DETAILS: {
+ contents: [
+ h(AccountDetailsModal, {}, []),
+ ],
+ ...accountModalStyle,
+ },
+
+ EXPORT_PRIVATE_KEY: {
+ contents: [
+ h(ExportPrivateKeyModal, {}, []),
+ ],
+ ...accountModalStyle,
+ },
+
+ SHAPESHIFT_DEPOSIT_TX: {
+ contents: [
+ h(ShapeshiftDepositTxModal),
+ ],
+ ...accountModalStyle,
+ },
+
+ HIDE_TOKEN_CONFIRMATION: {
+ contents: [
+ h(HideTokenConfirmationModal, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ },
+ laptopModalStyle: {
+ width: '449px',
+ top: 'calc(33% + 45px)',
+ },
+ },
+
+ BETA_UI_NOTIFICATION_MODAL: {
+ contents: [
+ h(NotifcationModal, {
+ header: 'Welcome to the New UI (Beta)',
+ message: `You are now using the new Metamask UI. Take a look around, try out new features like sending tokens,
+ and let us know if you have any issues.`,
+ }),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ },
+ laptopModalStyle: {
+ width: '449px',
+ top: 'calc(33% + 45px)',
+ },
+ },
+
+ OLD_UI_NOTIFICATION_MODAL: {
+ contents: [
+ h(NotifcationModal, {
+ header: 'Old UI',
+ message: `You have returned to the old UI. You can switch back to the New UI through the option in the top
+ right dropdown menu.`,
+ }),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ },
+ laptopModalStyle: {
+ width: '449px',
+ top: 'calc(33% + 45px)',
+ },
+ },
+
+ CONFIRM_RESET_ACCOUNT: {
+ contents: h(ConfirmResetAccount),
+ mobileModalStyle: {
+ width: '95%',
+ top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ },
+ laptopModalStyle: {
+ width: '473px',
+ top: 'calc(33% + 45px)',
+ },
+ },
+
+ NEW_ACCOUNT: {
+ contents: [
+ h(NewAccountModal, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '95%',
+ // top: isPopupOrNotification() === 'popup' ? '52vh' : '36.5vh',
+ top: '10%',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ laptopModalStyle: {
+ width: '449px',
+ // top: 'calc(33% + 45px)',
+ top: '10%',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ },
+
+ CUSTOMIZE_GAS: {
+ contents: [
+ h(CustomizeGasModal, {}, []),
+ ],
+ mobileModalStyle: {
+ width: '100vw',
+ height: '100vh',
+ top: '0',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ laptopModalStyle: {
+ width: '720px',
+ height: '377px',
+ top: '80px',
+ transform: 'none',
+ left: '0',
+ right: '0',
+ margin: '0 auto',
+ },
+ },
+
+ DEFAULT: {
+ contents: [],
+ mobileModalStyle: {},
+ laptopModalStyle: {},
+ },
+}
+
+const BACKDROPSTYLE = {
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
+}
+
+function mapStateToProps (state) {
+ return {
+ active: state.appState.modal.open,
+ modalState: state.appState.modal.modalState,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ }
+}
+
+// Global Modal Component
+inherits(Modal, Component)
+function Modal () {
+ Component.call(this)
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(Modal)
+
+Modal.prototype.render = function () {
+ const modal = MODALS[this.props.modalState.name || 'DEFAULT']
+
+ const children = modal.contents
+ const modalStyle = modal[isMobileView() ? 'mobileModalStyle' : 'laptopModalStyle']
+ const contentStyle = modal.contentStyle || {}
+
+ return h(FadeModal,
+ {
+ className: 'modal',
+ keyboard: false,
+ onHide: () => { this.onHide() },
+ ref: (ref) => {
+ this.modalRef = ref
+ },
+ modalStyle,
+ contentStyle,
+ backdropStyle: BACKDROPSTYLE,
+ },
+ children,
+ )
+}
+
+Modal.prototype.componentWillReceiveProps = function (nextProps) {
+ if (nextProps.active) {
+ this.show()
+ } else if (this.props.active) {
+ this.hide()
+ }
+}
+
+Modal.prototype.onHide = function () {
+ if (this.props.onHideCallback) {
+ this.props.onHideCallback()
+ }
+ this.props.hideModal()
+}
+
+Modal.prototype.hide = function () {
+ this.modalRef.hide()
+}
+
+Modal.prototype.show = function () {
+ this.modalRef.show()
+}
diff --git a/ui/app/components/modals/new-account-modal.js b/ui/app/components/modals/new-account-modal.js
new file mode 100644
index 000000000..fc1fd413d
--- /dev/null
+++ b/ui/app/components/modals/new-account-modal.js
@@ -0,0 +1,106 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const actions = require('../../actions')
+
+class NewAccountModal extends Component {
+ constructor (props) {
+ super(props)
+ const { numberOfExistingAccounts = 0 } = props
+ const newAccountNumber = numberOfExistingAccounts + 1
+
+ this.state = {
+ newAccountName: `Account ${newAccountNumber}`,
+ }
+ }
+
+ render () {
+ const { newAccountName } = this.state
+
+ return h('div', [
+ h('div.new-account-modal-wrapper', {
+ }, [
+ h('div.new-account-modal-header', {}, [
+ 'New Account',
+ ]),
+
+ h('div.modal-close-x', {
+ onClick: this.props.hideModal,
+ }),
+
+ h('div.new-account-modal-content', {}, [
+ 'Account Name',
+ ]),
+
+ h('div.new-account-input-wrapper', {}, [
+ h('input.new-account-input', {
+ value: this.state.newAccountName,
+ placeholder: 'E.g. My new account',
+ onChange: event => this.setState({ newAccountName: event.target.value }),
+ }, []),
+ ]),
+
+ h('div.new-account-modal-content.after-input', {}, [
+ 'or',
+ ]),
+
+ h('div.new-account-modal-content.after-input.pointer', {
+ onClick: () => {
+ this.props.hideModal()
+ this.props.showImportPage()
+ },
+ }, 'Import an account'),
+
+ h('div.new-account-modal-content.button', {}, [
+ h('button.btn-clear', {
+ onClick: () => this.props.createAccount(newAccountName),
+ }, [
+ 'SAVE',
+ ]),
+ ]),
+ ]),
+ ])
+ }
+}
+
+NewAccountModal.propTypes = {
+ hideModal: PropTypes.func,
+ showImportPage: PropTypes.func,
+ createAccount: PropTypes.func,
+ numberOfExistingAccounts: PropTypes.number,
+}
+
+const mapStateToProps = state => {
+ const { metamask: { network, selectedAddress, identities = {} } } = state
+ const numberOfExistingAccounts = Object.keys(identities).length
+
+ return {
+ network,
+ address: selectedAddress,
+ numberOfExistingAccounts,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ toCoinbase: (address) => {
+ dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
+ },
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ createAccount: (newAccountName) => {
+ dispatch(actions.addNewAccount())
+ .then((newAccountAddress) => {
+ if (newAccountName) {
+ dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName))
+ }
+ dispatch(actions.hideModal())
+ })
+ },
+ showImportPage: () => dispatch(actions.showImportPage()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountModal)
diff --git a/ui/app/components/modals/notification-modal.js b/ui/app/components/modals/notification-modal.js
new file mode 100644
index 000000000..621a974d0
--- /dev/null
+++ b/ui/app/components/modals/notification-modal.js
@@ -0,0 +1,75 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const actions = require('../../actions')
+
+class NotificationModal extends Component {
+ render () {
+ const {
+ header,
+ message,
+ showCancelButton = false,
+ showConfirmButton = false,
+ hideModal,
+ onConfirm,
+ } = this.props
+
+ const showButtons = showCancelButton || showConfirmButton
+
+ return h('div', [
+ h('div.notification-modal__wrapper', {
+ }, [
+
+ h('div.notification-modal__header', {}, [
+ header,
+ ]),
+
+ h('div.notification-modal__message-wrapper', {}, [
+ h('div.notification-modal__message', {}, [
+ message,
+ ]),
+ ]),
+
+ h('div.modal-close-x', {
+ onClick: hideModal,
+ }),
+
+ showButtons && h('div.notification-modal__buttons', [
+
+ showCancelButton && h('div.btn-cancel.notification-modal__buttons__btn', {
+ onClick: hideModal,
+ }, 'Cancel'),
+
+ showConfirmButton && h('div.btn-clear.notification-modal__buttons__btn', {
+ onClick: () => {
+ onConfirm()
+ hideModal()
+ },
+ }, 'Confirm'),
+
+ ]),
+
+ ]),
+ ])
+ }
+}
+
+NotificationModal.propTypes = {
+ hideModal: PropTypes.func,
+ header: PropTypes.string,
+ message: PropTypes.node,
+ showCancelButton: PropTypes.bool,
+ showConfirmButton: PropTypes.bool,
+ onConfirm: PropTypes.func,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ }
+}
+
+module.exports = connect(null, mapDispatchToProps)(NotificationModal)
diff --git a/ui/app/components/modals/notification-modals/confirm-reset-account.js b/ui/app/components/modals/notification-modals/confirm-reset-account.js
new file mode 100644
index 000000000..e1bc91b24
--- /dev/null
+++ b/ui/app/components/modals/notification-modals/confirm-reset-account.js
@@ -0,0 +1,46 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const actions = require('../../../actions')
+const NotifcationModal = require('../notification-modal')
+
+class ConfirmResetAccount extends Component {
+ render () {
+ const { resetAccount } = this.props
+
+ return h(NotifcationModal, {
+ header: 'Are you sure you want to reset account?',
+ message: h('div', [
+
+ h('span', `Resetting is for developer use only. This button wipes the current account's transaction history,
+ which is used to calculate the current account nonce. `),
+
+ h('a.notification-modal__link', {
+ href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account',
+ target: '_blank',
+ onClick (event) { global.platform.openWindow({ url: event.target.href }) },
+ }, 'Read more.'),
+
+ ]),
+ showCancelButton: true,
+ showConfirmButton: true,
+ onConfirm: resetAccount,
+
+ })
+ }
+}
+
+ConfirmResetAccount.propTypes = {
+ resetAccount: PropTypes.func,
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ resetAccount: () => {
+ dispatch(actions.resetAccount())
+ },
+ }
+}
+
+module.exports = connect(null, mapDispatchToProps)(ConfirmResetAccount)
diff --git a/ui/app/components/modals/shapeshift-deposit-tx-modal.js b/ui/app/components/modals/shapeshift-deposit-tx-modal.js
new file mode 100644
index 000000000..24af5a0de
--- /dev/null
+++ b/ui/app/components/modals/shapeshift-deposit-tx-modal.js
@@ -0,0 +1,40 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const QrView = require('../qr-code')
+const AccountModalContainer = require('./account-modal-container')
+
+function mapStateToProps (state) {
+ return {
+ Qr: state.appState.modal.modalState.Qr,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ hideModal: () => {
+ dispatch(actions.hideModal())
+ },
+ }
+}
+
+inherits(ShapeshiftDepositTxModal, Component)
+function ShapeshiftDepositTxModal () {
+ Component.call(this)
+
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftDepositTxModal)
+
+ShapeshiftDepositTxModal.prototype.render = function () {
+ const { Qr } = this.props
+
+ return h(AccountModalContainer, {
+ }, [
+ h('div', {}, [
+ h(QrView, {key: 'qr', Qr}),
+ ]),
+ ])
+}
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 18fca1db7..3e91fa807 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -1,6 +1,8 @@
const Component = require('react').Component
const h = require('react-hyperscript')
+const classnames = require('classnames')
const inherits = require('util').inherits
+const NetworkDropdownIcon = require('./dropdowns/components/network-dropdown-icon')
module.exports = Network
@@ -37,7 +39,6 @@ Network.prototype.render = function () {
},
src: 'images/loading.svg',
}),
- h('i.fa.fa-caret-down'),
])
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
@@ -60,51 +61,58 @@ Network.prototype.render = function () {
}
return (
- h('#network_component.pointer', {
+ h('div.network-component.pointer', {
+ className: classnames({
+ 'network-component--disabled': this.props.disabled,
+ 'ethereum-network': providerName === 'mainnet',
+ 'ropsten-test-network': providerName === 'ropsten' || parseInt(networkNumber) === 3,
+ 'kovan-test-network': providerName === 'kovan',
+ 'rinkeby-test-network': providerName === 'rinkeby',
+ }),
title: hoverText,
- onClick: (event) => this.props.onClick(event),
+ onClick: (event) => {
+ if (!this.props.disabled) {
+ this.props.onClick(event)
+ }
+ },
}, [
(function () {
switch (iconName) {
case 'ethereum-network':
return h('.network-indicator', [
- h('.menu-icon.diamond'),
- h('.network-name', {
- style: {
- color: '#039396',
- }},
- 'Main Network'),
- h('i.fa.fa-caret-down.fa-lg'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#038789', // $blue-lagoon
+ nonSelectBackgroundColor: '#15afb2',
+ }),
+ h('.network-name', 'Main Network'),
+ h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
case 'ropsten-test-network':
return h('.network-indicator', [
- h('.menu-icon.red-dot'),
- h('.network-name', {
- style: {
- color: '#ff6666',
- }},
- 'Ropsten Test Net'),
- h('i.fa.fa-caret-down.fa-lg'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#e91550', // $crimson
+ nonSelectBackgroundColor: '#ec2c50',
+ }),
+ h('.network-name', 'Ropsten Test Net'),
+ h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
case 'kovan-test-network':
return h('.network-indicator', [
- h('.menu-icon.hollow-diamond'),
- h('.network-name', {
- style: {
- color: '#690496',
- }},
- 'Kovan Test Net'),
- h('i.fa.fa-caret-down.fa-lg'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#690496', // $purple
+ nonSelectBackgroundColor: '#b039f3',
+ }),
+ h('.network-name', 'Kovan Test Net'),
+ h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
case 'rinkeby-test-network':
return h('.network-indicator', [
- h('.menu-icon.golden-square'),
- h('.network-name', {
- style: {
- color: '#e7a218',
- }},
- 'Rinkeby Test Net'),
- h('i.fa.fa-caret-down.fa-lg'),
+ h(NetworkDropdownIcon, {
+ backgroundColor: '#ebb33f', // $tulip-tree
+ nonSelectBackgroundColor: '#ecb23e',
+ }),
+ h('.network-name', 'Rinkeby Test Net'),
+ h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
default:
return h('.network-indicator', [
@@ -115,12 +123,8 @@ Network.prototype.render = function () {
},
}),
- h('.network-name', {
- style: {
- color: '#AEAEAE',
- }},
- 'Private Network'),
- h('i.fa.fa-caret-down.fa-lg'),
+ h('.network-name', 'Private Network'),
+ h('i.fa.fa-chevron-down.fa-lg.network-caret'),
])
}
})(),
diff --git a/ui/app/components/notice.js b/ui/app/components/notice.js
index 09d461c7b..9d2e89cb0 100644
--- a/ui/app/components/notice.js
+++ b/ui/app/components/notice.js
@@ -102,11 +102,10 @@ Notice.prototype.render = function () {
}),
]),
- h('button', {
+ h('button.primary', {
disabled,
onClick: () => {
- this.setState({disclaimerDisabled: true})
- onConfirm()
+ this.setState({disclaimerDisabled: true}, () => onConfirm())
},
style: {
marginTop: '18px',
diff --git a/ui/app/components/pending-tx/confirm-deploy-contract.js b/ui/app/components/pending-tx/confirm-deploy-contract.js
new file mode 100644
index 000000000..ae6c6ef7b
--- /dev/null
+++ b/ui/app/components/pending-tx/confirm-deploy-contract.js
@@ -0,0 +1,348 @@
+const Component = require('react').Component
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const actions = require('../../actions')
+const clone = require('clone')
+const Identicon = require('../identicon')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
+const { conversionUtil } = require('../../conversion-util')
+
+const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract)
+
+function mapStateToProps (state) {
+ const {
+ conversionRate,
+ identities,
+ currentCurrency,
+ } = state.metamask
+ const accounts = state.metamask.accounts
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ return {
+ currentCurrency,
+ conversionRate,
+ identities,
+ selectedAddress,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
+ cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ }
+}
+
+
+inherits(ConfirmDeployContract, Component)
+function ConfirmDeployContract () {
+ Component.call(this)
+ this.state = {}
+ this.onSubmit = this.onSubmit.bind(this)
+}
+
+ConfirmDeployContract.prototype.onSubmit = function (event) {
+ event.preventDefault()
+ const txMeta = this.gatherTxMeta()
+ const valid = this.checkValidity()
+ this.setState({ valid, submitting: true })
+
+ if (valid && this.verifyGasParams()) {
+ this.props.sendTransaction(txMeta, event)
+ } else {
+ this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
+ this.setState({ submitting: false })
+ }
+}
+
+ConfirmDeployContract.prototype.cancel = function (event, txMeta) {
+ event.preventDefault()
+ this.props.cancelTransaction(txMeta)
+}
+
+ConfirmDeployContract.prototype.checkValidity = function () {
+ const form = this.getFormEl()
+ const valid = form.checkValidity()
+ return valid
+}
+
+ConfirmDeployContract.prototype.getFormEl = function () {
+ const form = document.querySelector('form#pending-tx-form')
+ // Stub out form for unit tests:
+ if (!form) {
+ return { checkValidity () { return true } }
+ }
+ return form
+}
+
+// After a customizable state value has been updated,
+ConfirmDeployContract.prototype.gatherTxMeta = function () {
+ const props = this.props
+ const state = this.state
+ const txData = clone(state.txData) || clone(props.txData)
+
+ // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
+ return txData
+}
+
+ConfirmDeployContract.prototype.verifyGasParams = function () {
+ // We call this in case the gas has not been modified at all
+ if (!this.state) { return true }
+ return (
+ this._notZeroOrEmptyString(this.state.gas) &&
+ this._notZeroOrEmptyString(this.state.gasPrice)
+ )
+}
+
+ConfirmDeployContract.prototype._notZeroOrEmptyString = function (obj) {
+ return obj !== '' && obj !== '0x0'
+}
+
+ConfirmDeployContract.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) {
+ const numBN = new BN(numerator)
+ const denomBN = new BN(denominator)
+ return targetBN.mul(numBN).div(denomBN)
+}
+
+ConfirmDeployContract.prototype.getData = function () {
+ const { identities } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ return {
+ from: {
+ address: txParams.from,
+ name: identities[txParams.from].name,
+ },
+ memo: txParams.memo || '',
+ }
+}
+
+ConfirmDeployContract.prototype.getAmount = function () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ const FIAT = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ fromDenomination: 'WEI',
+ conversionRate,
+ })
+ const ETH = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ fromDenomination: 'WEI',
+ conversionRate,
+ numberOfDecimals: 6,
+ })
+
+ return {
+ fiat: Number(FIAT),
+ token: Number(ETH),
+ }
+
+}
+
+ConfirmDeployContract.prototype.getGasFee = function () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ // Gas
+ const gas = txParams.gas
+ const gasBn = hexToBn(gas)
+
+ // Gas Price
+ const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_HEX
+ const gasPriceBn = hexToBn(gasPrice)
+
+ const txFeeBn = gasBn.mul(gasPriceBn)
+
+ const FIAT = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const ETH = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ return {
+ fiat: Number(FIAT),
+ eth: Number(ETH),
+ }
+}
+
+ConfirmDeployContract.prototype.renderGasFee = function () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
+
+ return (
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'Gas Fee' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency.toUpperCase()}`),
+
+ h(
+ 'div.confirm-screen-row-detail',
+ `${ethGas} ETH`
+ ),
+ ]),
+ ])
+ )
+}
+
+ConfirmDeployContract.prototype.renderHeroAmount = function () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatAmount } = this.getAmount()
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+ const { memo = '' } = txParams
+
+ return (
+ h('div.confirm-send-token__hero-amount-wrapper', [
+ h('h3.flex-center.confirm-screen-send-amount', `${fiatAmount}`),
+ h('h3.flex-center.confirm-screen-send-amount-currency', currentCurrency.toUpperCase()),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', memo),
+ ]),
+ ])
+ )
+}
+
+ConfirmDeployContract.prototype.renderTotalPlusGas = function () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
+ const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
+
+ return (
+ h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ 'Total ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ 'Amount + Gas' ]),
+ ]),
+
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${fiatAmount + fiatGas} ${currentCurrency.toUpperCase()}`),
+ h('div.confirm-screen-row-detail', `${tokenAmount + ethGas} ETH`),
+ ]),
+ ])
+ )
+}
+
+ConfirmDeployContract.prototype.render = function () {
+ const { backToAccountDetail, selectedAddress } = this.props
+ const txMeta = this.gatherTxMeta()
+
+ const {
+ from: {
+ address: fromAddress,
+ name: fromName,
+ },
+ } = this.getData()
+
+ this.inputs = []
+
+ return (
+ h('div.flex-column.flex-grow.confirm-screen-container', {
+ style: { minWidth: '355px' },
+ }, [
+ // Main Send token Card
+ h('div.confirm-screen-wrapper.flex-column.flex-grow', [
+ h('h3.flex-center.confirm-screen-header', [
+ h('button.confirm-screen-back-button', {
+ onClick: () => backToAccountDetail(selectedAddress),
+ }, 'BACK'),
+ h('div.confirm-screen-title', 'Confirm Contract'),
+ h('div.confirm-screen-header-tip'),
+ ]),
+ h('div.flex-row.flex-center.confirm-screen-identicons', [
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: fromAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', fromName),
+ // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
+ ]),
+ h('i.fa.fa-arrow-right.fa-lg'),
+ h('div.confirm-screen-account-wrapper', [
+ h('i.fa.fa-file-text-o'),
+ h('span.confirm-screen-account-name', 'New Contract'),
+ h('span.confirm-screen-account-number', ' '),
+ ]),
+ ]),
+
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're deploying a new contract.`,
+ // ]),
+
+ this.renderHeroAmount(),
+
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'From' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
+ ]),
+
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'To' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', 'New Contract'),
+ ]),
+ ]),
+
+ this.renderGasFee(),
+
+ this.renderTotalPlusGas(),
+
+ ]),
+ ]),
+
+ h('form#pending-tx-form', {
+ onSubmit: this.onSubmit,
+ }, [
+ // Cancel Button
+ h('div.cancel.btn-light.confirm-screen-cancel-button', {
+ onClick: (event) => this.cancel(event, txMeta),
+ }, 'CANCEL'),
+
+ // Accept Button
+ h('button.confirm-screen-confirm-button', ['CONFIRM']),
+
+ ]),
+ ])
+ )
+}
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
new file mode 100644
index 000000000..3f8d9c28f
--- /dev/null
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -0,0 +1,469 @@
+const Component = require('react').Component
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const actions = require('../../actions')
+const clone = require('clone')
+const Identicon = require('../identicon')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
+const { conversionUtil, addCurrencies } = require('../../conversion-util')
+
+const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendEther)
+
+function mapStateToProps (state) {
+ const {
+ conversionRate,
+ identities,
+ currentCurrency,
+ send,
+ } = state.metamask
+ const accounts = state.metamask.accounts
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ return {
+ conversionRate,
+ identities,
+ selectedAddress,
+ currentCurrency,
+ send,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ clearSend: () => dispatch(actions.clearSend()),
+ editTransaction: txMeta => {
+ const { id, txParams } = txMeta
+ const {
+ gas: gasLimit,
+ gasPrice,
+ to,
+ value: amount,
+ } = txParams
+ dispatch(actions.updateSend({
+ gasLimit,
+ gasPrice,
+ gasTotal: null,
+ to,
+ amount,
+ errors: { to: null, amount: null },
+ editingTransactionId: id,
+ }))
+ dispatch(actions.showSendPage())
+ },
+ cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ }
+}
+
+inherits(ConfirmSendEther, Component)
+function ConfirmSendEther () {
+ Component.call(this)
+ this.state = {}
+ this.onSubmit = this.onSubmit.bind(this)
+}
+
+ConfirmSendEther.prototype.getAmount = function () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ const FIAT = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ fromDenomination: 'WEI',
+ conversionRate,
+ })
+ const ETH = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ fromDenomination: 'WEI',
+ conversionRate,
+ numberOfDecimals: 6,
+ })
+
+ return {
+ FIAT,
+ ETH,
+ }
+
+}
+
+ConfirmSendEther.prototype.getGasFee = function () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ // Gas
+ const gas = txParams.gas
+ const gasBn = hexToBn(gas)
+
+ // From latest master
+// const gasLimit = new BN(parseInt(blockGasLimit))
+// const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 19, 20)
+// const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 18, 20)
+// const safeGasLimit = safeGasLimitBN.toString(10)
+
+ // Gas Price
+ const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_HEX
+ const gasPriceBn = hexToBn(gasPrice)
+
+ const txFeeBn = gasBn.mul(gasPriceBn)
+
+ const FIAT = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const ETH = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ return {
+ FIAT,
+ ETH,
+ }
+}
+
+ConfirmSendEther.prototype.getData = function () {
+ const { identities } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+ const { FIAT: gasFeeInFIAT, ETH: gasFeeInETH } = this.getGasFee()
+ const { FIAT: amountInFIAT, ETH: amountInETH } = this.getAmount()
+
+ const totalInFIAT = addCurrencies(gasFeeInFIAT, amountInFIAT, {
+ toNumericBase: 'dec',
+ numberOfDecimals: 2,
+ })
+ const totalInETH = addCurrencies(gasFeeInETH, amountInETH, {
+ toNumericBase: 'dec',
+ numberOfDecimals: 6,
+ })
+
+ return {
+ from: {
+ address: txParams.from,
+ name: identities[txParams.from].name,
+ },
+ to: {
+ address: txParams.to,
+ name: identities[txParams.to] ? identities[txParams.to].name : 'New Recipient',
+ },
+ memo: txParams.memo || '',
+ gasFeeInFIAT,
+ gasFeeInETH,
+ amountInFIAT,
+ amountInETH,
+ totalInFIAT,
+ totalInETH,
+ }
+}
+
+ConfirmSendEther.prototype.render = function () {
+ const { editTransaction, currentCurrency, clearSend } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ const {
+ from: {
+ address: fromAddress,
+ name: fromName,
+ },
+ to: {
+ address: toAddress,
+ name: toName,
+ },
+ memo,
+ gasFeeInFIAT,
+ gasFeeInETH,
+ amountInFIAT,
+ totalInFIAT,
+ totalInETH,
+ } = this.getData()
+
+ // This is from the latest master
+ // It handles some of the errors that we are not currently handling
+ // Leaving as comments fo reference
+
+ // const balanceBn = hexToBn(balance)
+ // const insufficientBalance = balanceBn.lt(maxCost)
+ // const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting
+ // const showRejectAll = props.unconfTxListLength > 1
+// const dangerousGasLimit = gasBn.gte(saferGasLimitBN)
+// const gasLimitSpecified = txMeta.gasLimitSpecified
+
+ this.inputs = []
+
+ return (
+ h('div.confirm-screen-container.confirm-send-ether', [
+ // Main Send token Card
+ h('div.page-container', [
+ h('div.page-container__header', [
+ h('button.confirm-screen-back-button', {
+ onClick: () => editTransaction(txMeta),
+ }, 'Edit'),
+ h('div.page-container__title', 'Confirm'),
+ h('div.page-container__subtitle', `Please review your transaction.`),
+ ]),
+ h('div.flex-row.flex-center.confirm-screen-identicons', [
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: fromAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', fromName),
+ // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
+ ]),
+ h('i.fa.fa-arrow-right.fa-lg'),
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: txParams.to,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', toName),
+ // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
+ ]),
+ ]),
+
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
+ // ]),
+
+ h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]),
+ h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
+ ]),
+
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'From' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
+ ]),
+
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'To' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', toName),
+ h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
+ ]),
+ ]),
+
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'Gas Fee' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${gasFeeInFIAT} ${currentCurrency.toUpperCase()}`),
+
+ h('div.confirm-screen-row-detail', `${gasFeeInETH} ETH`),
+ ]),
+ ]),
+
+
+ h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ 'Total ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ 'Amount + Gas' ]),
+ ]),
+
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`),
+ h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
+ ]),
+ ]),
+ ]),
+
+// These are latest errors handling from master
+// Leaving as comments as reference when we start implementing error handling
+// h('style', `
+// .conf-buttons button {
+// margin-left: 10px;
+// text-transform: uppercase;
+// }
+// `),
+
+// txMeta.simulationFails ?
+// h('.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Transaction Error. Exception thrown in contract code.')
+// : null,
+
+// !isValidAddress ?
+// h('.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
+// : null,
+
+// insufficientBalance ?
+// h('span.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Insufficient balance for transaction')
+// : null,
+
+// // send + cancel
+// h('.flex-row.flex-space-around.conf-buttons', {
+// style: {
+// display: 'flex',
+// justifyContent: 'flex-end',
+// margin: '14px 25px',
+// },
+// }, [
+// h('button', {
+// onClick: (event) => {
+// this.resetGasFields()
+// event.preventDefault()
+// },
+// }, 'Reset'),
+
+// // Accept Button or Buy Button
+// insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') :
+// h('input.confirm.btn-green', {
+// type: 'submit',
+// value: 'SUBMIT',
+// style: { marginLeft: '10px' },
+// disabled: buyDisabled,
+// }),
+
+// h('button.cancel.btn-red', {
+// onClick: props.cancelTransaction,
+// }, 'Reject'),
+// ]),
+// showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', {
+// style: {
+// display: 'flex',
+// justifyContent: 'flex-end',
+// margin: '14px 25px',
+// },
+// }, [
+// h('button.cancel.btn-red', {
+// onClick: props.cancelAllTransactions,
+// }, 'Reject All'),
+// ]) : null,
+// ]),
+// ])
+// )
+// }
+ ]),
+
+ h('form#pending-tx-form', {
+ onSubmit: this.onSubmit,
+ }, [
+ // Cancel Button
+ h('div.cancel.btn-light.confirm-screen-cancel-button', {
+ onClick: (event) => {
+ clearSend()
+ this.cancel(event, txMeta)
+ },
+ }, 'CANCEL'),
+
+ // Accept Button
+ h('button.confirm-screen-confirm-button', ['CONFIRM']),
+ ]),
+ ])
+ )
+}
+
+ConfirmSendEther.prototype.onSubmit = function (event) {
+ event.preventDefault()
+ const txMeta = this.gatherTxMeta()
+ const valid = this.checkValidity()
+ this.setState({ valid, submitting: true })
+
+ if (valid && this.verifyGasParams()) {
+ this.props.sendTransaction(txMeta, event)
+ } else {
+ this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
+ this.setState({ submitting: false })
+ }
+}
+
+ConfirmSendEther.prototype.cancel = function (event, txMeta) {
+ event.preventDefault()
+ const { cancelTransaction } = this.props
+
+ cancelTransaction(txMeta)
+}
+
+ConfirmSendEther.prototype.checkValidity = function () {
+ const form = this.getFormEl()
+ const valid = form.checkValidity()
+ return valid
+}
+
+ConfirmSendEther.prototype.getFormEl = function () {
+ const form = document.querySelector('form#pending-tx-form')
+ // Stub out form for unit tests:
+ if (!form) {
+ return { checkValidity () { return true } }
+ }
+ return form
+}
+
+// After a customizable state value has been updated,
+ConfirmSendEther.prototype.gatherTxMeta = function () {
+ const props = this.props
+ const state = this.state
+ const txData = clone(state.txData) || clone(props.txData)
+
+ // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
+ return txData
+}
+
+ConfirmSendEther.prototype.verifyGasParams = function () {
+ // We call this in case the gas has not been modified at all
+ if (!this.state) { return true }
+ return (
+ this._notZeroOrEmptyString(this.state.gas) &&
+ this._notZeroOrEmptyString(this.state.gasPrice)
+ )
+}
+
+ConfirmSendEther.prototype._notZeroOrEmptyString = function (obj) {
+ return obj !== '' && obj !== '0x0'
+}
+
+ConfirmSendEther.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) {
+ const numBN = new BN(numerator)
+ const denomBN = new BN(denominator)
+ return targetBN.mul(numBN).div(denomBN)
+}
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
new file mode 100644
index 000000000..e4b0c186a
--- /dev/null
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -0,0 +1,462 @@
+const Component = require('react').Component
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const tokenAbi = require('human-standard-token-abi')
+const abiDecoder = require('abi-decoder')
+abiDecoder.addABI(tokenAbi)
+const actions = require('../../actions')
+const clone = require('clone')
+const Identicon = require('../identicon')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const {
+ conversionUtil,
+ multiplyCurrencies,
+ addCurrencies,
+} = require('../../conversion-util')
+const {
+ calcTokenAmount,
+} = require('../../token-util')
+
+const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+
+const {
+ getTokenExchangeRate,
+ getSelectedAddress,
+ getSelectedTokenContract,
+} = require('../../selectors')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmSendToken)
+
+function mapStateToProps (state, ownProps) {
+ const { token: { symbol }, txData } = ownProps
+ const { txParams } = txData || {}
+ const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+
+ const {
+ conversionRate,
+ identities,
+ currentCurrency,
+ } = state.metamask
+ const selectedAddress = getSelectedAddress(state)
+ const tokenExchangeRate = getTokenExchangeRate(state, symbol)
+
+ return {
+ conversionRate,
+ identities,
+ selectedAddress,
+ tokenExchangeRate,
+ tokenData: tokenData || {},
+ currentCurrency: currentCurrency.toUpperCase(),
+ send: state.metamask.send,
+ tokenContract: getSelectedTokenContract(state),
+ }
+}
+
+function mapDispatchToProps (dispatch, ownProps) {
+ const { token: { symbol } } = ownProps
+
+ return {
+ backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
+ cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ updateTokenExchangeRate: () => dispatch(actions.updateTokenExchangeRate(symbol)),
+ editTransaction: txMeta => {
+ const { token: { address } } = ownProps
+ const { txParams, id } = txMeta
+ const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { params = [] } = tokenData
+ const { value: to } = params[0] || {}
+ const { value: tokenAmountInDec } = params[1] || {}
+ const tokenAmountInHex = conversionUtil(tokenAmountInDec, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ })
+ const {
+ gas: gasLimit,
+ gasPrice,
+ } = txParams
+ dispatch(actions.setSelectedToken(address))
+ dispatch(actions.updateSend({
+ gasLimit,
+ gasPrice,
+ gasTotal: null,
+ to,
+ amount: tokenAmountInHex,
+ errors: { to: null, amount: null },
+ editingTransactionId: id,
+ }))
+ dispatch(actions.showSendTokenPage())
+ },
+ }
+}
+
+inherits(ConfirmSendToken, Component)
+function ConfirmSendToken () {
+ Component.call(this)
+ this.state = {}
+ this.onSubmit = this.onSubmit.bind(this)
+}
+
+ConfirmSendToken.prototype.componentWillMount = function () {
+ const { tokenContract, selectedAddress } = this.props
+ tokenContract && tokenContract
+ .balanceOf(selectedAddress)
+ .then(usersToken => {
+ })
+ this.props.updateTokenExchangeRate()
+}
+
+ConfirmSendToken.prototype.getAmount = function () {
+ const {
+ conversionRate,
+ tokenExchangeRate,
+ token,
+ tokenData,
+ send: { amount, editingTransactionId },
+ } = this.props
+ const { params = [] } = tokenData
+ let { value } = params[1] || {}
+ const { decimals } = token
+
+ if (editingTransactionId) {
+ value = conversionUtil(amount, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ })
+ }
+
+ const sendTokenAmount = calcTokenAmount(value, decimals)
+
+ return {
+ fiat: tokenExchangeRate
+ ? +(sendTokenAmount * tokenExchangeRate * conversionRate).toFixed(2)
+ : null,
+ token: typeof value === 'undefined'
+ ? 'Unknown'
+ : +sendTokenAmount.toFixed(decimals),
+ }
+
+}
+
+ConfirmSendToken.prototype.getGasFee = function () {
+ const { conversionRate, tokenExchangeRate, token, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+ const { decimals } = token
+
+ const gas = txParams.gas
+ const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_HEX
+ const gasTotal = multiplyCurrencies(gas, gasPrice, {
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ const FIAT = conversionUtil(gasTotal, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const ETH = conversionUtil(gasTotal, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+ const tokenGas = multiplyCurrencies(gas, gasPrice, {
+ toNumericBase: 'dec',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ toCurrency: 'BAT',
+ conversionRate: tokenExchangeRate,
+ invertConversionRate: true,
+ fromDenomination: 'WEI',
+ numberOfDecimals: decimals || 4,
+ })
+
+ return {
+ fiat: +Number(FIAT).toFixed(2),
+ eth: ETH,
+ token: tokenExchangeRate
+ ? tokenGas
+ : null,
+ }
+}
+
+ConfirmSendToken.prototype.getData = function () {
+ const { identities, tokenData } = this.props
+ const { params = [] } = tokenData
+ const { value } = params[0] || {}
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ return {
+ from: {
+ address: txParams.from,
+ name: identities[txParams.from].name,
+ },
+ to: {
+ address: value,
+ name: identities[value] ? identities[value].name : 'New Recipient',
+ },
+ memo: txParams.memo || '',
+ }
+}
+
+ConfirmSendToken.prototype.renderHeroAmount = function () {
+ const { token: { symbol }, currentCurrency } = this.props
+ const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+ const { memo = '' } = txParams
+
+ return fiatAmount
+ ? (
+ h('div.confirm-send-token__hero-amount-wrapper', [
+ h('h3.flex-center.confirm-screen-send-amount', `${fiatAmount}`),
+ h('h3.flex-center.confirm-screen-send-amount-currency', currentCurrency),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
+ ]),
+ ])
+ )
+ : (
+ h('div.confirm-send-token__hero-amount-wrapper', [
+ h('h3.flex-center.confirm-screen-send-amount', tokenAmount),
+ h('h3.flex-center.confirm-screen-send-amount-currency', symbol),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
+ ]),
+ ])
+ )
+}
+
+ConfirmSendToken.prototype.renderGasFee = function () {
+ const { token: { symbol }, currentCurrency } = this.props
+ const { fiat: fiatGas, token: tokenGas, eth: ethGas } = this.getGasFee()
+
+ return (
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'Gas Fee' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency}`),
+
+ h(
+ 'div.confirm-screen-row-detail',
+ tokenGas ? `${tokenGas} ${symbol}` : `${ethGas} ETH`
+ ),
+ ]),
+ ])
+ )
+}
+
+ConfirmSendToken.prototype.renderTotalPlusGas = function () {
+ const { token: { symbol }, currentCurrency } = this.props
+ const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
+ const { fiat: fiatGas, token: tokenGas } = this.getGasFee()
+
+ return fiatAmount && fiatGas
+ ? (
+ h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ 'Total ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ 'Amount + Gas' ]),
+ ]),
+
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${addCurrencies(fiatAmount, fiatGas)} ${currentCurrency}`),
+ h('div.confirm-screen-row-detail', `${addCurrencies(tokenAmount, tokenGas || '0')} ${symbol}`),
+ ]),
+ ])
+ )
+ : (
+ h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ 'Total ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ 'Amount + Gas' ]),
+ ]),
+
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${tokenAmount} ${symbol}`),
+ h('div.confirm-screen-row-detail', `+ ${fiatGas} ${currentCurrency} Gas`),
+ ]),
+ ])
+ )
+}
+
+ConfirmSendToken.prototype.render = function () {
+ const { editTransaction } = this.props
+ const txMeta = this.gatherTxMeta()
+ const {
+ from: {
+ address: fromAddress,
+ name: fromName,
+ },
+ to: {
+ address: toAddress,
+ name: toName,
+ },
+ } = this.getData()
+
+ this.inputs = []
+
+ return (
+ h('div.confirm-screen-container.confirm-send-token', [
+ // Main Send token Card
+ h('div.page-container', [
+ h('div.page-container__header', [
+ h('button.confirm-screen-back-button', {
+ onClick: () => editTransaction(txMeta),
+ }, 'Edit'),
+ h('div.page-container__title', 'Confirm'),
+ h('div.page-container__subtitle', `Please review your transaction.`),
+ ]),
+ h('div.flex-row.flex-center.confirm-screen-identicons', [
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: fromAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', fromName),
+ // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
+ ]),
+ h('i.fa.fa-arrow-right.fa-lg'),
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: toAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', toName),
+ // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
+ ]),
+ ]),
+
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
+ // ]),
+
+ this.renderHeroAmount(),
+
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'From' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
+ ]),
+
+ toAddress && h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ 'To' ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', toName),
+ h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
+ ]),
+ ]),
+
+ this.renderGasFee(),
+
+ this.renderTotalPlusGas(),
+
+ ]),
+ ]),
+
+ h('form#pending-tx-form', {
+ onSubmit: this.onSubmit,
+ }, [
+ // Cancel Button
+ h('div.cancel.btn-light.confirm-screen-cancel-button', {
+ onClick: (event) => this.cancel(event, txMeta),
+ }, 'CANCEL'),
+
+ // Accept Button
+ h('button.confirm-screen-confirm-button', ['CONFIRM']),
+ ]),
+
+
+ ])
+ )
+}
+
+ConfirmSendToken.prototype.onSubmit = function (event) {
+ event.preventDefault()
+ const txMeta = this.gatherTxMeta()
+ const valid = this.checkValidity()
+ this.setState({ valid, submitting: true })
+
+ if (valid && this.verifyGasParams()) {
+ this.props.sendTransaction(txMeta, event)
+ } else {
+ this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
+ this.setState({ submitting: false })
+ }
+}
+
+ConfirmSendToken.prototype.cancel = function (event, txMeta) {
+ event.preventDefault()
+ const { cancelTransaction } = this.props
+
+ cancelTransaction(txMeta)
+}
+
+ConfirmSendToken.prototype.checkValidity = function () {
+ const form = this.getFormEl()
+ const valid = form.checkValidity()
+ return valid
+}
+
+ConfirmSendToken.prototype.getFormEl = function () {
+ const form = document.querySelector('form#pending-tx-form')
+ // Stub out form for unit tests:
+ if (!form) {
+ return { checkValidity () { return true } }
+ }
+ return form
+}
+
+// After a customizable state value has been updated,
+ConfirmSendToken.prototype.gatherTxMeta = function () {
+ const props = this.props
+ const state = this.state
+ const txData = clone(state.txData) || clone(props.txData)
+
+ // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
+ return txData
+}
+
+ConfirmSendToken.prototype.verifyGasParams = function () {
+ // We call this in case the gas has not been modified at all
+ if (!this.state) { return true }
+ return (
+ this._notZeroOrEmptyString(this.state.gas) &&
+ this._notZeroOrEmptyString(this.state.gasPrice)
+ )
+}
+
+ConfirmSendToken.prototype._notZeroOrEmptyString = function (obj) {
+ return obj !== '' && obj !== '0x0'
+}
+
+ConfirmSendToken.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) {
+ const numBN = new BN(numerator)
+ const denomBN = new BN(denominator)
+ return targetBN.mul(numBN).div(denomBN)
+}
diff --git a/ui/app/components/pending-tx/index.js b/ui/app/components/pending-tx/index.js
new file mode 100644
index 000000000..f4f6afb8f
--- /dev/null
+++ b/ui/app/components/pending-tx/index.js
@@ -0,0 +1,145 @@
+const Component = require('react').Component
+const { connect } = require('react-redux')
+const h = require('react-hyperscript')
+const clone = require('clone')
+const abi = require('human-standard-token-abi')
+const abiDecoder = require('abi-decoder')
+abiDecoder.addABI(abi)
+const inherits = require('util').inherits
+const actions = require('../../actions')
+const util = require('../../util')
+const ConfirmSendEther = require('./confirm-send-ether')
+const ConfirmSendToken = require('./confirm-send-token')
+const ConfirmDeployContract = require('./confirm-deploy-contract')
+
+const TX_TYPES = {
+ DEPLOY_CONTRACT: 'deploy_contract',
+ SEND_ETHER: 'send_ether',
+ SEND_TOKEN: 'send_token',
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(PendingTx)
+
+function mapStateToProps (state) {
+ const {
+ conversionRate,
+ identities,
+ } = state.metamask
+ const accounts = state.metamask.accounts
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ return {
+ conversionRate,
+ identities,
+ selectedAddress,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
+ cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ }
+}
+
+inherits(PendingTx, Component)
+function PendingTx () {
+ Component.call(this)
+ this.state = {
+ isFetching: true,
+ transactionType: '',
+ tokenAddress: '',
+ tokenSymbol: '',
+ tokenDecimals: '',
+ }
+}
+
+PendingTx.prototype.componentWillMount = async function () {
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ if (!txParams.to) {
+ return this.setState({
+ transactionType: TX_TYPES.DEPLOY_CONTRACT,
+ isFetching: false,
+ })
+ }
+
+ try {
+ const token = util.getContractAtAddress(txParams.to)
+ const results = await Promise.all([
+ token.symbol(),
+ token.decimals(),
+ ])
+
+ const [ symbol, decimals ] = results
+
+ if (symbol[0] && decimals[0]) {
+ this.setState({
+ transactionType: TX_TYPES.SEND_TOKEN,
+ tokenAddress: txParams.to,
+ tokenSymbol: symbol[0],
+ tokenDecimals: decimals[0],
+ isFetching: false,
+ })
+ } else {
+ this.setState({
+ transactionType: TX_TYPES.SEND_ETHER,
+ isFetching: false,
+ })
+ }
+ } catch (e) {
+ this.setState({
+ transactionType: TX_TYPES.SEND_ETHER,
+ isFetching: false,
+ })
+ }
+}
+
+PendingTx.prototype.gatherTxMeta = function () {
+ const props = this.props
+ const state = this.state
+ const txData = clone(state.txData) || clone(props.txData)
+
+ return txData
+}
+
+PendingTx.prototype.render = function () {
+ const {
+ isFetching,
+ transactionType,
+ tokenAddress,
+ tokenSymbol,
+ tokenDecimals,
+ } = this.state
+
+ const { sendTransaction } = this.props
+
+ if (isFetching) {
+ return h('noscript')
+ }
+
+ switch (transactionType) {
+ case TX_TYPES.SEND_ETHER:
+ return h(ConfirmSendEther, {
+ txData: this.gatherTxMeta(),
+ sendTransaction,
+ })
+ case TX_TYPES.SEND_TOKEN:
+ return h(ConfirmSendToken, {
+ txData: this.gatherTxMeta(),
+ sendTransaction,
+ token: {
+ address: tokenAddress,
+ symbol: tokenSymbol,
+ decimals: tokenDecimals,
+ },
+ })
+ case TX_TYPES.DEPLOY_CONTRACT:
+ return h(ConfirmDeployContract, {
+ txData: this.gatherTxMeta(),
+ sendTransaction,
+ })
+ default:
+ return h('noscript')
+ }
+}
diff --git a/ui/app/components/qr-code.js b/ui/app/components/qr-code.js
index 06b9aed9b..83885539c 100644
--- a/ui/app/components/qr-code.js
+++ b/ui/app/components/qr-code.js
@@ -4,13 +4,13 @@ const qrCode = require('qrcode-npm').qrcode
const inherits = require('util').inherits
const connect = require('react-redux').connect
const isHexPrefixed = require('ethereumjs-util').isHexPrefixed
-const CopyButton = require('./copyButton')
+const ReadOnlyInput = require('./readonly-input')
module.exports = connect(mapStateToProps)(QrCodeView)
function mapStateToProps (state) {
return {
- Qr: state.appState.Qr,
+ // Qr code is not fetched from state. 'message' and 'data' props are passed instead.
buyView: state.appState.buyView,
warning: state.appState.warning,
}
@@ -29,46 +29,29 @@ QrCodeView.prototype.render = function () {
const qrImage = qrCode(4, 'M')
qrImage.addData(address)
qrImage.make()
- return h('.main-container.flex-column', {
- key: 'qr',
- style: {
- justifyContent: 'center',
- paddingBottom: '45px',
- paddingLeft: '45px',
- paddingRight: '45px',
- alignItems: 'center',
- },
- }, [
- Array.isArray(Qr.message) ? h('.message-container', this.renderMultiMessage()) : h('.qr-header', Qr.message),
+
+ return h('.div.flex-column.flex-center', [
+ Array.isArray(Qr.message)
+ ? h('.message-container', this.renderMultiMessage())
+ : Qr.message && h('.qr-header', Qr.message),
this.props.warning ? this.props.warning && h('span.error.flex-center', {
style: {
- textAlign: 'center',
- width: '229px',
- height: '82px',
},
},
this.props.warning) : null,
- h('#qr-container.flex-column', {
- style: {
- marginTop: '25px',
- marginBottom: '15px',
- },
+ h('.div.qr-wrapper', {
+ style: {},
dangerouslySetInnerHTML: {
__html: qrImage.createTableTag(4),
},
}),
- h('.flex-row', [
- h('h3.ellip-address', {
- style: {
- width: '247px',
- },
- }, Qr.data),
- h(CopyButton, {
- value: Qr.data,
- }),
- ]),
+ h(ReadOnlyInput, {
+ wrapperClass: 'ellip-address-wrapper',
+ inputClass: 'qr-ellip-address',
+ value: Qr.data,
+ }),
])
}
diff --git a/ui/app/components/readonly-input.js b/ui/app/components/readonly-input.js
new file mode 100644
index 000000000..fcf05fb9e
--- /dev/null
+++ b/ui/app/components/readonly-input.js
@@ -0,0 +1,33 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = ReadOnlyInput
+
+inherits(ReadOnlyInput, Component)
+function ReadOnlyInput () {
+ Component.call(this)
+}
+
+ReadOnlyInput.prototype.render = function () {
+ const {
+ wrapperClass = '',
+ inputClass = '',
+ value,
+ textarea,
+ onClick,
+ } = this.props
+
+ const inputType = textarea ? 'textarea' : 'input'
+
+ return h('div', {className: wrapperClass}, [
+ h(inputType, {
+ className: inputClass,
+ value,
+ readOnly: true,
+ onFocus: event => event.target.select(),
+ onClick,
+ }),
+ ])
+}
+
diff --git a/ui/app/components/send-token/index.js b/ui/app/components/send-token/index.js
new file mode 100644
index 000000000..99d078251
--- /dev/null
+++ b/ui/app/components/send-token/index.js
@@ -0,0 +1,439 @@
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const classnames = require('classnames')
+const abi = require('ethereumjs-abi')
+const inherits = require('util').inherits
+const actions = require('../../actions')
+const selectors = require('../../selectors')
+const { isValidAddress, allNull } = require('../../util')
+
+// const BalanceComponent = require('./balance-component')
+const Identicon = require('../identicon')
+const TokenBalance = require('../token-balance')
+const CurrencyToggle = require('../send/currency-toggle')
+const GasTooltip = require('../send/gas-tooltip')
+const GasFeeDisplay = require('../send/gas-fee-display')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(SendTokenScreen)
+
+function mapStateToProps (state) {
+ // const sidebarOpen = state.appState.sidebarOpen
+
+ const { warning } = state.appState
+ const identities = state.metamask.identities
+ const addressBook = state.metamask.addressBook
+ const conversionRate = state.metamask.conversionRate
+ const currentBlockGasLimit = state.metamask.currentBlockGasLimit
+ const accounts = state.metamask.accounts
+ const selectedTokenAddress = state.metamask.selectedTokenAddress
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ const selectedToken = selectors.getSelectedToken(state)
+ const tokenExchangeRates = state.metamask.tokenExchangeRates
+ const pair = `${selectedToken.symbol.toLowerCase()}_eth`
+ const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
+
+ return {
+ selectedAddress,
+ selectedTokenAddress,
+ identities,
+ addressBook,
+ conversionRate,
+ tokenExchangeRate,
+ currentBlockGasLimit,
+ selectedToken,
+ warning,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
+ hideWarning: () => dispatch(actions.hideWarning()),
+ addToAddressBook: (recipient, nickname) => dispatch(
+ actions.addToAddressBook(recipient, nickname)
+ ),
+ signTx: txParams => dispatch(actions.signTx(txParams)),
+ signTokenTx: (tokenAddress, toAddress, amount, txData) => (
+ dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
+ ),
+ updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
+ estimateGas: params => dispatch(actions.estimateGas(params)),
+ getGasPrice: () => dispatch(actions.getGasPrice()),
+ }
+}
+
+inherits(SendTokenScreen, Component)
+function SendTokenScreen () {
+ Component.call(this)
+ this.state = {
+ to: '',
+ amount: '0x0',
+ amountToSend: '0x0',
+ selectedCurrency: 'USD',
+ isGasTooltipOpen: false,
+ gasPrice: null,
+ gasLimit: null,
+ errors: {},
+ }
+}
+
+SendTokenScreen.prototype.componentWillMount = function () {
+ const {
+ updateTokenExchangeRate,
+ selectedToken: { symbol },
+ getGasPrice,
+ estimateGas,
+ selectedAddress,
+ } = this.props
+
+ updateTokenExchangeRate(symbol)
+
+ const data = Array.prototype.map.call(
+ abi.rawEncode(['address', 'uint256'], [selectedAddress, '0x0']),
+ x => ('00' + x.toString(16)).slice(-2)
+ ).join('')
+
+ console.log(data)
+ Promise.all([
+ getGasPrice(),
+ estimateGas({
+ from: selectedAddress,
+ value: '0x0',
+ gas: '746a528800',
+ data,
+ }),
+ ])
+ .then(([blockGasPrice, estimatedGas]) => {
+ console.log({ blockGasPrice, estimatedGas})
+ this.setState({
+ gasPrice: blockGasPrice,
+ gasLimit: estimatedGas,
+ })
+ })
+}
+
+SendTokenScreen.prototype.validate = function () {
+ const {
+ to,
+ amount: stringAmount,
+ gasPrice: hexGasPrice,
+ gasLimit: hexGasLimit,
+ } = this.state
+
+ const gasPrice = parseInt(hexGasPrice, 16)
+ const gasLimit = parseInt(hexGasLimit, 16) / 1000000000
+ const amount = Number(stringAmount)
+
+ const errors = {
+ to: !to ? 'Required' : null,
+ amount: !amount ? 'Required' : null,
+ gasPrice: !gasPrice ? 'Gas Price Required' : null,
+ gasLimit: !gasLimit ? 'Gas Limit Required' : null,
+ }
+
+ if (to && !isValidAddress(to)) {
+ errors.to = 'Invalid address'
+ }
+
+ const isValid = Object.entries(errors).every(([key, value]) => value === null)
+ return {
+ isValid,
+ errors: isValid ? {} : errors,
+ }
+}
+
+SendTokenScreen.prototype.setErrorsFor = function (field) {
+ const { errors: previousErrors } = this.state
+
+ const {
+ isValid,
+ errors: newErrors,
+ } = this.validate()
+
+ const nextErrors = Object.assign({}, previousErrors, {
+ [field]: newErrors[field] || null,
+ })
+
+ if (!isValid) {
+ this.setState({
+ errors: nextErrors,
+ isValid,
+ })
+ }
+}
+
+SendTokenScreen.prototype.clearErrorsFor = function (field) {
+ const { errors: previousErrors } = this.state
+ const nextErrors = Object.assign({}, previousErrors, {
+ [field]: null,
+ })
+
+ this.setState({
+ errors: nextErrors,
+ isValid: allNull(nextErrors),
+ })
+}
+
+SendTokenScreen.prototype.getAmountToSend = function (amount, selectedToken) {
+ const { decimals } = selectedToken || {}
+ const multiplier = Math.pow(10, Number(decimals || 0))
+ const sendAmount = '0x' + Number(amount * multiplier).toString(16)
+ return sendAmount
+}
+
+SendTokenScreen.prototype.submit = function () {
+ const {
+ to,
+ amount,
+ gasPrice,
+ gasLimit,
+ } = this.state
+
+ const {
+ identities,
+ selectedAddress,
+ selectedTokenAddress,
+ hideWarning,
+ addToAddressBook,
+ signTokenTx,
+ selectedToken,
+ } = this.props
+
+ const { nickname = ' ' } = identities[to] || {}
+
+ hideWarning()
+ addToAddressBook(to, nickname)
+
+ const txParams = {
+ from: selectedAddress,
+ value: '0',
+ gas: gasLimit,
+ gasPrice: gasPrice,
+ }
+
+ const sendAmount = this.getAmountToSend(amount, selectedToken)
+
+ signTokenTx(selectedTokenAddress, to, sendAmount, txParams)
+}
+
+SendTokenScreen.prototype.renderToAddressInput = function () {
+ const {
+ identities,
+ addressBook,
+ } = this.props
+
+ const {
+ to,
+ errors: { to: errorMessage },
+ } = this.state
+
+ return h('div', {
+ className: classnames('send-screen-input-wrapper', {
+ 'send-screen-input-wrapper--error': errorMessage,
+ }),
+ }, [
+ h('div', ['To:']),
+ h('input.large-input.send-screen-input', {
+ name: 'address',
+ list: 'addresses',
+ placeholder: 'Address',
+ value: to,
+ onChange: e => this.setState({
+ to: e.target.value,
+ errors: {},
+ }),
+ onBlur: () => {
+ this.setErrorsFor('to')
+ },
+ onFocus: event => {
+ if (to) event.target.select()
+ this.clearErrorsFor('to')
+ },
+ }),
+ h('datalist#addresses', [
+ // Corresponds to the addresses owned.
+ Object.entries(identities).map(([key, { address, name }]) => {
+ return h('option', {
+ value: address,
+ label: name,
+ key: address,
+ })
+ }),
+ addressBook.map(({ address, name }) => {
+ return h('option', {
+ value: address,
+ label: name,
+ key: address,
+ })
+ }),
+ ]),
+ h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
+ ])
+}
+
+SendTokenScreen.prototype.renderAmountInput = function () {
+ const {
+ selectedCurrency,
+ amount,
+ errors: { amount: errorMessage },
+ } = this.state
+
+ const {
+ tokenExchangeRate,
+ selectedToken: {symbol},
+ } = this.props
+
+ return h('div.send-screen-input-wrapper', {
+ className: classnames('send-screen-input-wrapper', {
+ 'send-screen-input-wrapper--error': errorMessage,
+ }),
+ }, [
+ h('div.send-screen-amount-labels', [
+ h('span', ['Amount']),
+ h(CurrencyToggle, {
+ currentCurrency: tokenExchangeRate ? selectedCurrency : 'USD',
+ currencies: tokenExchangeRate ? [ symbol, 'USD' ] : [],
+ onClick: currency => this.setState({ selectedCurrency: currency }),
+ }),
+ ]),
+ h('input.large-input.send-screen-input', {
+ placeholder: `0 ${symbol}`,
+ type: 'number',
+ value: amount,
+ onChange: e => this.setState({
+ amount: e.target.value,
+ }),
+ onBlur: () => {
+ this.setErrorsFor('amount')
+ },
+ onFocus: () => this.clearErrorsFor('amount'),
+ }),
+ h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
+ ])
+}
+
+SendTokenScreen.prototype.renderGasInput = function () {
+ const {
+ isGasTooltipOpen,
+ gasPrice,
+ gasLimit,
+ selectedCurrency,
+ errors: {
+ gasPrice: gasPriceErrorMessage,
+ gasLimit: gasLimitErrorMessage,
+ },
+ } = this.state
+
+ const {
+ conversionRate,
+ tokenExchangeRate,
+ currentBlockGasLimit,
+ } = this.props
+
+ return h('div.send-screen-input-wrapper', {
+ className: classnames('send-screen-input-wrapper', {
+ 'send-screen-input-wrapper--error': gasPriceErrorMessage || gasLimitErrorMessage,
+ }),
+ }, [
+ isGasTooltipOpen && h(GasTooltip, {
+ className: 'send-tooltip',
+ gasPrice: gasPrice || '0x0',
+ gasLimit: gasLimit || '0x0',
+ onClose: () => this.setState({ isGasTooltipOpen: false }),
+ onFeeChange: ({ gasLimit, gasPrice }) => {
+ this.setState({ gasLimit, gasPrice, errors: {} })
+ },
+ onBlur: () => {
+ this.setErrorsFor('gasLimit')
+ this.setErrorsFor('gasPrice')
+ },
+ onFocus: () => {
+ this.clearErrorsFor('gasLimit')
+ this.clearErrorsFor('gasPrice')
+ },
+ }),
+
+ h('div.send-screen-gas-labels', {}, [
+ h('span', [ h('i.fa.fa-bolt'), 'Gas fee:']),
+ h('span', ['What\'s this?']),
+ ]),
+ h('div.large-input.send-screen-gas-input', [
+ h(GasFeeDisplay, {
+ conversionRate,
+ tokenExchangeRate,
+ gasPrice: gasPrice || '0x0',
+ activeCurrency: selectedCurrency,
+ gas: gasLimit || '0x0',
+ blockGasLimit: currentBlockGasLimit,
+ }),
+ h(
+ 'div.send-screen-gas-input-customize',
+ { onClick: () => this.setState({ isGasTooltipOpen: !isGasTooltipOpen }) },
+ ['Customize']
+ ),
+ ]),
+ h('div.send-screen-input-wrapper__error-message', [
+ gasPriceErrorMessage || gasLimitErrorMessage,
+ ]),
+ ])
+}
+
+SendTokenScreen.prototype.renderMemoInput = function () {
+ return h('div.send-screen-input-wrapper', [
+ h('div', {}, ['Transaction memo (optional)']),
+ h(
+ 'input.large-input.send-screen-input',
+ { onChange: e => this.setState({ memo: e.target.value }) }
+ ),
+ ])
+}
+
+SendTokenScreen.prototype.renderButtons = function () {
+ const { selectedAddress, backToAccountDetail } = this.props
+ const { isValid } = this.validate()
+
+ return h('div.send-token__button-group', [
+ h('button.send-token__button-next.btn-secondary', {
+ className: !isValid && 'send-screen__send-button__disabled',
+ onClick: () => isValid && this.submit(),
+ }, ['Next']),
+ h('button.send-token__button-cancel.btn-tertiary', {
+ onClick: () => backToAccountDetail(selectedAddress),
+ }, ['Cancel']),
+ ])
+}
+
+SendTokenScreen.prototype.render = function () {
+ const {
+ selectedTokenAddress,
+ selectedToken,
+ warning,
+ } = this.props
+
+ return h('div.send-token', [
+ h('div.send-token__content', [
+ h(Identicon, {
+ diameter: 75,
+ address: selectedTokenAddress,
+ }),
+ h('div.send-token__title', ['Send Tokens']),
+ h('div.send-token__description', ['Send Tokens to anyone with an Ethereum account']),
+ h('div.send-token__balance-text', ['Your Token Balance is:']),
+ h('div.send-token__token-balance', [
+ h(TokenBalance, { token: selectedToken, balanceOnly: true }),
+ ]),
+ h('div.send-token__token-symbol', [selectedToken.symbol]),
+ this.renderToAddressInput(),
+ this.renderAmountInput(),
+ this.renderGasInput(),
+ this.renderMemoInput(),
+ warning && h('div.send-screen-input-wrapper--error', {},
+ h('div.send-screen-input-wrapper__error-message', [
+ warning,
+ ])
+ ),
+ ]),
+ this.renderButtons(),
+ ])
+}
diff --git a/ui/app/components/send/account-list-item.js b/ui/app/components/send/account-list-item.js
new file mode 100644
index 000000000..1ad3f69c1
--- /dev/null
+++ b/ui/app/components/send/account-list-item.js
@@ -0,0 +1,73 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const connect = require('react-redux').connect
+const Identicon = require('../identicon')
+const CurrencyDisplay = require('./currency-display')
+const { conversionRateSelector, getCurrentCurrency } = require('../../selectors')
+
+inherits(AccountListItem, Component)
+function AccountListItem () {
+ Component.call(this)
+}
+
+function mapStateToProps (state) {
+ return {
+ conversionRate: conversionRateSelector(state),
+ currentCurrency: getCurrentCurrency(state),
+ }
+}
+
+module.exports = connect(mapStateToProps)(AccountListItem)
+
+AccountListItem.prototype.render = function () {
+ const {
+ className,
+ account,
+ handleClick,
+ icon = null,
+ conversionRate,
+ currentCurrency,
+ displayBalance = true,
+ displayAddress = false,
+ } = this.props
+
+ const { name, address, balance } = account || {}
+
+ return h('div.account-list-item', {
+ className,
+ onClick: () => handleClick({ name, address, balance }),
+ }, [
+
+ h('div.account-list-item__top-row', {}, [
+
+ h(
+ Identicon,
+ {
+ address,
+ diameter: 18,
+ className: 'account-list-item__identicon',
+ },
+ ),
+
+ h('div.account-list-item__account-name', {}, name || address),
+
+ icon && h('div.account-list-item__icon', [icon]),
+
+ ]),
+
+ displayAddress && name && h('div.account-list-item__account-address', address),
+
+ displayBalance && h(CurrencyDisplay, {
+ primaryCurrency: 'ETH',
+ convertedCurrency: currentCurrency,
+ value: balance,
+ conversionRate,
+ readOnly: true,
+ className: 'account-list-item__account-balances',
+ primaryBalanceClassName: 'account-list-item__account-primary-balance',
+ convertedBalanceClassName: 'account-list-item__account-secondary-balance',
+ }, name),
+
+ ])
+}
diff --git a/ui/app/components/send/currency-display.js b/ui/app/components/send/currency-display.js
new file mode 100644
index 000000000..819fee0a0
--- /dev/null
+++ b/ui/app/components/send/currency-display.js
@@ -0,0 +1,116 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const CurrencyInput = require('../currency-input')
+const { conversionUtil, multiplyCurrencies } = require('../../conversion-util')
+
+module.exports = CurrencyDisplay
+
+inherits(CurrencyDisplay, Component)
+function CurrencyDisplay () {
+ Component.call(this)
+}
+
+function toHexWei (value) {
+ return conversionUtil(value, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ toDenomination: 'WEI',
+ })
+}
+
+CurrencyDisplay.prototype.getAmount = function (value) {
+ const { selectedToken } = this.props
+ const { decimals } = selectedToken || {}
+ const multiplier = Math.pow(10, Number(decimals || 0))
+
+ const sendAmount = multiplyCurrencies(value, multiplier, {toNumericBase: 'hex'})
+
+ return selectedToken
+ ? sendAmount
+ : toHexWei(value)
+}
+
+CurrencyDisplay.prototype.getValueToRender = function () {
+ const { selectedToken, conversionRate, value } = this.props
+
+ const { decimals, symbol } = selectedToken || {}
+ const multiplier = Math.pow(10, Number(decimals || 0))
+
+ return selectedToken
+ ? conversionUtil(value, {
+ fromNumericBase: 'hex',
+ toCurrency: symbol,
+ conversionRate: multiplier,
+ invertConversionRate: true,
+ })
+ : conversionUtil(value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+}
+
+CurrencyDisplay.prototype.render = function () {
+ const {
+ className = 'currency-display',
+ primaryBalanceClassName = 'currency-display__input',
+ convertedBalanceClassName = 'currency-display__converted-value',
+ conversionRate,
+ primaryCurrency,
+ convertedCurrency,
+ readOnly = false,
+ inError = false,
+ handleChange,
+ } = this.props
+
+ const valueToRender = this.getValueToRender()
+
+ let convertedValue = conversionUtil(valueToRender, {
+ fromNumericBase: 'dec',
+ fromCurrency: primaryCurrency,
+ toCurrency: convertedCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ convertedValue = Number(convertedValue).toFixed(2)
+
+ return h('div', {
+ className,
+ style: {
+ borderColor: inError ? 'red' : null,
+ },
+ onClick: () => this.currencyInput.focus(),
+ }, [
+
+ h('div.currency-display__primary-row', [
+
+ h('div.currency-display__input-wrapper', [
+
+ h(CurrencyInput, {
+ className: primaryBalanceClassName,
+ value: `${valueToRender}`,
+ placeholder: '0',
+ readOnly,
+ onInputChange: newValue => {
+ handleChange(this.getAmount(newValue))
+ },
+ inputRef: input => { this.currencyInput = input },
+ }),
+
+ h('span.currency-display__currency-symbol', primaryCurrency),
+
+ ]),
+
+ ]),
+
+ h('div', {
+ className: convertedBalanceClassName,
+ }, `${convertedValue} ${convertedCurrency.toUpperCase()}`),
+
+ ])
+
+}
+
diff --git a/ui/app/components/send/currency-toggle.js b/ui/app/components/send/currency-toggle.js
new file mode 100644
index 000000000..7aaccd490
--- /dev/null
+++ b/ui/app/components/send/currency-toggle.js
@@ -0,0 +1,44 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const classnames = require('classnames')
+
+module.exports = CurrencyToggle
+
+inherits(CurrencyToggle, Component)
+function CurrencyToggle () {
+ Component.call(this)
+}
+
+const defaultCurrencies = [ 'ETH', 'USD' ]
+
+CurrencyToggle.prototype.renderToggles = function () {
+ const { onClick, activeCurrency } = this.props
+ const [currencyA, currencyB] = this.props.currencies || defaultCurrencies
+
+ return [
+ h('span', {
+ className: classnames('currency-toggle__item', {
+ 'currency-toggle__item--selected': currencyA === activeCurrency,
+ }),
+ onClick: () => onClick(currencyA),
+ }, [ currencyA ]),
+ '<>',
+ h('span', {
+ className: classnames('currency-toggle__item', {
+ 'currency-toggle__item--selected': currencyB === activeCurrency,
+ }),
+ onClick: () => onClick(currencyB),
+ }, [ currencyB ]),
+ ]
+}
+
+CurrencyToggle.prototype.render = function () {
+ const currencies = this.props.currencies || defaultCurrencies
+
+ return h('span.currency-toggle', currencies.length
+ ? this.renderToggles()
+ : []
+ )
+}
+
diff --git a/ui/app/components/send/eth-fee-display.js b/ui/app/components/send/eth-fee-display.js
new file mode 100644
index 000000000..9eda5ec62
--- /dev/null
+++ b/ui/app/components/send/eth-fee-display.js
@@ -0,0 +1,37 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const EthBalance = require('../eth-balance')
+const { getTxFeeBn } = require('../../util')
+
+module.exports = EthFeeDisplay
+
+inherits(EthFeeDisplay, Component)
+function EthFeeDisplay () {
+ Component.call(this)
+}
+
+EthFeeDisplay.prototype.render = function () {
+ const {
+ activeCurrency,
+ conversionRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ } = this.props
+
+ return h(EthBalance, {
+ value: getTxFeeBn(gas, gasPrice, blockGasLimit),
+ currentCurrency: activeCurrency,
+ conversionRate,
+ showFiat: false,
+ hideTooltip: true,
+ styleOveride: {
+ color: '#5d5d5d',
+ fontSize: '16px',
+ fontFamily: 'DIN OT',
+ lineHeight: '22.4px',
+ },
+ })
+}
+
diff --git a/ui/app/components/send/from-dropdown.js b/ui/app/components/send/from-dropdown.js
new file mode 100644
index 000000000..0686fbe73
--- /dev/null
+++ b/ui/app/components/send/from-dropdown.js
@@ -0,0 +1,72 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountListItem = require('./account-list-item')
+
+module.exports = FromDropdown
+
+inherits(FromDropdown, Component)
+function FromDropdown () {
+ Component.call(this)
+}
+
+FromDropdown.prototype.getListItemIcon = function (currentAccount, selectedAccount) {
+ const listItemIcon = h(`i.fa.fa-check.fa-lg`, { style: { color: '#02c9b1' } })
+
+ return currentAccount.address === selectedAccount.address
+ ? listItemIcon
+ : null
+}
+
+FromDropdown.prototype.renderDropdown = function () {
+ const {
+ accounts,
+ selectedAccount,
+ closeDropdown,
+ onSelect,
+ } = this.props
+
+ return h('div', {}, [
+
+ h('div.send-v2__from-dropdown__close-area', {
+ onClick: closeDropdown,
+ }),
+
+ h('div.send-v2__from-dropdown__list', {}, [
+
+ ...accounts.map(account => h(AccountListItem, {
+ className: 'account-list-item__dropdown',
+ account,
+ handleClick: () => {
+ onSelect(account)
+ closeDropdown()
+ },
+ icon: this.getListItemIcon(account, selectedAccount),
+ })),
+
+ ]),
+
+ ])
+}
+
+FromDropdown.prototype.render = function () {
+ const {
+ selectedAccount,
+ openDropdown,
+ dropdownOpen,
+ } = this.props
+
+ return h('div.send-v2__from-dropdown', {}, [
+
+ h(AccountListItem, {
+ account: selectedAccount,
+ handleClick: openDropdown,
+ icon: h(`i.fa.fa-caret-down.fa-lg`, { style: { color: '#dedede' } }),
+ }),
+
+ dropdownOpen && this.renderDropdown(),
+
+ ])
+
+}
+
diff --git a/ui/app/components/send/gas-fee-display-v2.js b/ui/app/components/send/gas-fee-display-v2.js
new file mode 100644
index 000000000..0c4c3f7a9
--- /dev/null
+++ b/ui/app/components/send/gas-fee-display-v2.js
@@ -0,0 +1,44 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const CurrencyDisplay = require('./currency-display')
+
+module.exports = GasFeeDisplay
+
+inherits(GasFeeDisplay, Component)
+function GasFeeDisplay () {
+ Component.call(this)
+}
+
+GasFeeDisplay.prototype.render = function () {
+ const {
+ conversionRate,
+ gasTotal,
+ onClick,
+ primaryCurrency = 'ETH',
+ convertedCurrency,
+ } = this.props
+
+ return h('div.send-v2__gas-fee-display', [
+
+ gasTotal
+ ? h(CurrencyDisplay, {
+ primaryCurrency,
+ convertedCurrency,
+ value: gasTotal,
+ conversionRate,
+ convertedPrefix: '$',
+ readOnly: true,
+ })
+ : h('div.currency-display', 'Loading...'),
+
+ h('button.send-v2__sliders-icon-container', {
+ onClick,
+ disabled: !gasTotal,
+ }, [
+ h('i.fa.fa-sliders.send-v2__sliders-icon'),
+ ]),
+
+ ])
+}
+
diff --git a/ui/app/components/send/gas-fee-display.js b/ui/app/components/send/gas-fee-display.js
new file mode 100644
index 000000000..a9a3f3f49
--- /dev/null
+++ b/ui/app/components/send/gas-fee-display.js
@@ -0,0 +1,62 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const USDFeeDisplay = require('./usd-fee-display')
+const EthFeeDisplay = require('./eth-fee-display')
+const { getTxFeeBn, formatBalance, shortenBalance } = require('../../util')
+
+module.exports = GasFeeDisplay
+
+inherits(GasFeeDisplay, Component)
+function GasFeeDisplay () {
+ Component.call(this)
+}
+
+GasFeeDisplay.prototype.getTokenValue = function () {
+ const {
+ tokenExchangeRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ } = this.props
+
+ const value = formatBalance(getTxFeeBn(gas, gasPrice, blockGasLimit), 6, true)
+ const [ethNumber] = value.split(' ')
+
+ return shortenBalance(Number(ethNumber) / tokenExchangeRate, 6)
+}
+
+GasFeeDisplay.prototype.render = function () {
+ const {
+ activeCurrency,
+ conversionRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ } = this.props
+
+ switch (activeCurrency) {
+ case 'USD':
+ return h(USDFeeDisplay, {
+ activeCurrency,
+ conversionRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ })
+ case 'ETH':
+ return h(EthFeeDisplay, {
+ activeCurrency,
+ conversionRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ })
+ default:
+ return h('div.token-gas', [
+ h('div.token-gas__amount', this.getTokenValue()),
+ h('div.token-gas__symbol', activeCurrency),
+ ])
+ }
+}
+
diff --git a/ui/app/components/send/gas-tooltip.js b/ui/app/components/send/gas-tooltip.js
new file mode 100644
index 000000000..46aff3499
--- /dev/null
+++ b/ui/app/components/send/gas-tooltip.js
@@ -0,0 +1,100 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const InputNumber = require('../input-number.js')
+
+module.exports = GasTooltip
+
+inherits(GasTooltip, Component)
+function GasTooltip () {
+ Component.call(this)
+ this.state = {
+ gasLimit: 0,
+ gasPrice: 0,
+ }
+
+ this.updateGasPrice = this.updateGasPrice.bind(this)
+ this.updateGasLimit = this.updateGasLimit.bind(this)
+ this.onClose = this.onClose.bind(this)
+}
+
+GasTooltip.prototype.componentWillMount = function () {
+ const { gasPrice = 0, gasLimit = 0} = this.props
+
+ this.setState({
+ gasPrice: parseInt(gasPrice, 16) / 1000000000,
+ gasLimit: parseInt(gasLimit, 16),
+ })
+}
+
+GasTooltip.prototype.updateGasPrice = function (newPrice) {
+ const { onFeeChange } = this.props
+ const { gasLimit } = this.state
+
+ this.setState({ gasPrice: newPrice })
+ onFeeChange({
+ gasLimit: gasLimit.toString(16),
+ gasPrice: (newPrice * 1000000000).toString(16),
+ })
+}
+
+GasTooltip.prototype.updateGasLimit = function (newLimit) {
+ const { onFeeChange } = this.props
+ const { gasPrice } = this.state
+
+ this.setState({ gasLimit: newLimit })
+ onFeeChange({
+ gasLimit: newLimit.toString(16),
+ gasPrice: (gasPrice * 1000000000).toString(16),
+ })
+}
+
+GasTooltip.prototype.onClose = function (e) {
+ e.stopPropagation()
+ this.props.onClose()
+}
+
+GasTooltip.prototype.render = function () {
+ const { gasPrice, gasLimit } = this.state
+
+ return h('div.gas-tooltip', {}, [
+ h('div.gas-tooltip-close-area', {
+ onClick: this.onClose,
+ }),
+ h('div.customize-gas-tooltip-container', {}, [
+ h('div.customize-gas-tooltip', {}, [
+ h('div.gas-tooltip-header.gas-tooltip-label', {}, ['Customize Gas']),
+ h('div.gas-tooltip-input-label', {}, [
+ h('span.gas-tooltip-label', {}, ['Gas Price']),
+ h('i.fa.fa-info-circle'),
+ ]),
+ h(InputNumber, {
+ unitLabel: 'GWEI',
+ step: 1,
+ min: 0,
+ placeholder: '0',
+ value: gasPrice,
+ onChange: (newPrice) => this.updateGasPrice(newPrice),
+ }),
+ h('div.gas-tooltip-input-label', {
+ style: {
+ 'marginTop': '81px',
+ },
+ }, [
+ h('span.gas-tooltip-label', {}, ['Gas Limit']),
+ h('i.fa.fa-info-circle'),
+ ]),
+ h(InputNumber, {
+ unitLabel: 'UNITS',
+ step: 1,
+ min: 0,
+ placeholder: '0',
+ value: gasLimit,
+ onChange: (newLimit) => this.updateGasLimit(newLimit),
+ }),
+ ]),
+ h('div.gas-tooltip-arrow', {}),
+ ]),
+ ])
+}
+
diff --git a/ui/app/components/send/memo-textarea.js b/ui/app/components/send/memo-textarea.js
new file mode 100644
index 000000000..f4bb24bf8
--- /dev/null
+++ b/ui/app/components/send/memo-textarea.js
@@ -0,0 +1,33 @@
+// const Component = require('react').Component
+// const h = require('react-hyperscript')
+// const inherits = require('util').inherits
+// const Identicon = require('../identicon')
+
+// module.exports = MemoTextArea
+
+// inherits(MemoTextArea, Component)
+// function MemoTextArea () {
+// Component.call(this)
+// }
+
+// MemoTextArea.prototype.render = function () {
+// const { memo, identities, onChange } = this.props
+
+// return h('div.send-v2__memo-text-area', [
+
+// h('textarea.send-v2__memo-text-area__input', {
+// placeholder: 'Optional',
+// value: memo,
+// onChange,
+// // onBlur: () => {
+// // this.setErrorsFor('memo')
+// // },
+// onFocus: event => {
+// // this.clearErrorsFor('memo')
+// },
+// }),
+
+// ])
+
+// }
+
diff --git a/ui/app/components/send/send-constants.js b/ui/app/components/send/send-constants.js
new file mode 100644
index 000000000..b3ee0899a
--- /dev/null
+++ b/ui/app/components/send/send-constants.js
@@ -0,0 +1,33 @@
+const ethUtil = require('ethereumjs-util')
+const { conversionUtil, multiplyCurrencies } = require('../../conversion-util')
+
+const MIN_GAS_PRICE_HEX = (100000000).toString(16)
+const MIN_GAS_PRICE_DEC = '100000000'
+const MIN_GAS_LIMIT_DEC = '21000'
+const MIN_GAS_LIMIT_HEX = (parseInt(MIN_GAS_LIMIT_DEC)).toString(16)
+
+const MIN_GAS_PRICE_GWEI = ethUtil.addHexPrefix(conversionUtil(MIN_GAS_PRICE_HEX, {
+ fromDenomination: 'WEI',
+ toDenomination: 'GWEI',
+ fromNumericBase: 'hex',
+ toNumericBase: 'hex',
+ numberOfDecimals: 1,
+}))
+
+const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+})
+
+const TOKEN_TRANSFER_FUNCTION_SIGNATURE = '0xa9059cbb'
+
+module.exports = {
+ MIN_GAS_PRICE_GWEI,
+ MIN_GAS_PRICE_HEX,
+ MIN_GAS_PRICE_DEC,
+ MIN_GAS_LIMIT_HEX,
+ MIN_GAS_LIMIT_DEC,
+ MIN_GAS_TOTAL,
+ TOKEN_TRANSFER_FUNCTION_SIGNATURE,
+}
diff --git a/ui/app/components/send/send-utils.js b/ui/app/components/send/send-utils.js
new file mode 100644
index 000000000..d8211930d
--- /dev/null
+++ b/ui/app/components/send/send-utils.js
@@ -0,0 +1,68 @@
+const {
+ addCurrencies,
+ conversionUtil,
+ conversionGTE,
+} = require('../../conversion-util')
+const {
+ calcTokenAmount,
+} = require('../../token-util')
+
+function isBalanceSufficient ({
+ amount = '0x0',
+ gasTotal = '0x0',
+ balance,
+ primaryCurrency,
+ amountConversionRate,
+ conversionRate,
+}) {
+ const totalAmount = addCurrencies(amount, gasTotal, {
+ aBase: 16,
+ bBase: 16,
+ toNumericBase: 'hex',
+ })
+
+ const balanceIsSufficient = conversionGTE(
+ {
+ value: balance,
+ fromNumericBase: 'hex',
+ fromCurrency: primaryCurrency,
+ conversionRate,
+ },
+ {
+ value: totalAmount,
+ fromNumericBase: 'hex',
+ conversionRate: amountConversionRate,
+ fromCurrency: primaryCurrency,
+ },
+ )
+
+ return balanceIsSufficient
+}
+
+function isTokenBalanceSufficient ({
+ amount = '0x0',
+ tokenBalance,
+ decimals,
+}) {
+ const amountInDec = conversionUtil(amount, {
+ fromNumericBase: 'hex',
+ })
+
+ const tokenBalanceIsSufficient = conversionGTE(
+ {
+ value: tokenBalance,
+ fromNumericBase: 'dec',
+ },
+ {
+ value: calcTokenAmount(amountInDec, decimals),
+ fromNumericBase: 'dec',
+ },
+ )
+
+ return tokenBalanceIsSufficient
+}
+
+module.exports = {
+ isBalanceSufficient,
+ isTokenBalanceSufficient,
+}
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
new file mode 100644
index 000000000..1106902b7
--- /dev/null
+++ b/ui/app/components/send/send-v2-container.js
@@ -0,0 +1,85 @@
+const connect = require('react-redux').connect
+const actions = require('../../actions')
+const abi = require('ethereumjs-abi')
+const SendEther = require('../../send-v2')
+
+const {
+ accountsWithSendEtherInfoSelector,
+ getCurrentAccountWithSendEtherInfo,
+ conversionRateSelector,
+ getSelectedToken,
+ getSelectedAddress,
+ getAddressBook,
+ getSendFrom,
+ getCurrentCurrency,
+ getSelectedTokenToFiatRate,
+ getSelectedTokenContract,
+} = require('../../selectors')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther)
+
+function mapStateToProps (state) {
+ const fromAccounts = accountsWithSendEtherInfoSelector(state)
+ const selectedAddress = getSelectedAddress(state)
+ const selectedToken = getSelectedToken(state)
+ const conversionRate = conversionRateSelector(state)
+
+ let data
+ let primaryCurrency
+ let tokenToFiatRate
+ if (selectedToken) {
+ data = Array.prototype.map.call(
+ abi.rawEncode(['address', 'uint256'], [selectedAddress, '0x0']),
+ x => ('00' + x.toString(16)).slice(-2)
+ ).join('')
+
+ primaryCurrency = selectedToken.symbol
+
+ tokenToFiatRate = getSelectedTokenToFiatRate(state)
+ }
+
+ return {
+ ...state.metamask.send,
+ from: getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state),
+ fromAccounts,
+ toAccounts: [...fromAccounts, ...getAddressBook(state)],
+ conversionRate,
+ selectedToken,
+ primaryCurrency,
+ convertedCurrency: getCurrentCurrency(state),
+ data,
+ amountConversionRate: selectedToken ? tokenToFiatRate : conversionRate,
+ tokenContract: getSelectedTokenContract(state),
+ unapprovedTxs: state.metamask.unapprovedTxs,
+ network: state.metamask.network,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showCustomizeGasModal: () => dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' })),
+ estimateGas: params => dispatch(actions.estimateGas(params)),
+ getGasPrice: () => dispatch(actions.getGasPrice()),
+ updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
+ signTokenTx: (tokenAddress, toAddress, amount, txData) => (
+ dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
+ ),
+ signTx: txParams => dispatch(actions.signTx(txParams)),
+ updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)),
+ updateTx: txData => dispatch(actions.updateTransaction(txData)),
+ setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)),
+ addToAddressBook: address => dispatch(actions.addToAddressBook(address)),
+ updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)),
+ updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)),
+ updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
+ updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)),
+ updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)),
+ updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)),
+ updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
+ updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
+ updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
+ goHome: () => dispatch(actions.goHome()),
+ clearSend: () => dispatch(actions.clearSend()),
+ setMaxModeTo: bool => dispatch(actions.setMaxModeTo(bool)),
+ }
+}
diff --git a/ui/app/components/send/to-autocomplete.js b/ui/app/components/send/to-autocomplete.js
new file mode 100644
index 000000000..e0cdd0a58
--- /dev/null
+++ b/ui/app/components/send/to-autocomplete.js
@@ -0,0 +1,114 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountListItem = require('./account-list-item')
+
+module.exports = ToAutoComplete
+
+inherits(ToAutoComplete, Component)
+function ToAutoComplete () {
+ Component.call(this)
+
+ this.state = { accountsToRender: [] }
+}
+
+ToAutoComplete.prototype.getListItemIcon = function (listItemAddress, toAddress) {
+ const listItemIcon = h(`i.fa.fa-check.fa-lg`, { style: { color: '#02c9b1' } })
+
+ return toAddress && listItemAddress === toAddress
+ ? listItemIcon
+ : null
+}
+
+ToAutoComplete.prototype.renderDropdown = function () {
+ const {
+ closeDropdown,
+ onChange,
+ to,
+ } = this.props
+ const { accountsToRender } = this.state
+
+ return accountsToRender.length && h('div', {}, [
+
+ h('div.send-v2__from-dropdown__close-area', {
+ onClick: closeDropdown,
+ }),
+
+ h('div.send-v2__from-dropdown__list', {}, [
+
+ ...accountsToRender.map(account => h(AccountListItem, {
+ account,
+ className: 'account-list-item__dropdown',
+ handleClick: () => {
+ onChange(account.address)
+ closeDropdown()
+ },
+ icon: this.getListItemIcon(account.address, to),
+ displayBalance: false,
+ displayAddress: true,
+ })),
+
+ ]),
+
+ ])
+}
+
+ToAutoComplete.prototype.handleInputEvent = function (event = {}, cb) {
+ const {
+ to,
+ accounts,
+ closeDropdown,
+ openDropdown,
+ } = this.props
+
+ const matchingAccounts = accounts.filter(({ address }) => address.match(to || ''))
+ const matches = matchingAccounts.length
+
+ if (!matches || matchingAccounts[0].address === to) {
+ this.setState({ accountsToRender: [] })
+ event.target && event.target.select()
+ closeDropdown()
+ } else {
+ this.setState({ accountsToRender: matchingAccounts })
+ openDropdown()
+ }
+ cb && cb(event.target.value)
+}
+
+ToAutoComplete.prototype.componentDidUpdate = function (nextProps, nextState) {
+ if (this.props.to !== nextProps.to) {
+ this.handleInputEvent()
+ }
+}
+
+ToAutoComplete.prototype.render = function () {
+ const {
+ to,
+ dropdownOpen,
+ onChange,
+ inError,
+ } = this.props
+
+ return h('div.send-v2__to-autocomplete', {}, [
+
+ h('input.send-v2__to-autocomplete__input', {
+ placeholder: 'Recipient Address',
+ className: inError ? `send-v2__error-border` : '',
+ value: to,
+ onChange: event => onChange(event.target.value),
+ onFocus: event => this.handleInputEvent(event),
+ style: {
+ borderColor: inError ? 'red' : null,
+ },
+ }),
+
+ !to && h(`i.fa.fa-caret-down.fa-lg.send-v2__to-autocomplete__down-caret`, {
+ style: { color: '#dedede' },
+ onClick: () => this.handleInputEvent(),
+ }),
+
+ dropdownOpen && this.renderDropdown(),
+
+ ])
+}
+
diff --git a/ui/app/components/send/usd-fee-display.js b/ui/app/components/send/usd-fee-display.js
new file mode 100644
index 000000000..4cf31a493
--- /dev/null
+++ b/ui/app/components/send/usd-fee-display.js
@@ -0,0 +1,35 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const FiatValue = require('../fiat-value')
+const { getTxFeeBn } = require('../../util')
+
+module.exports = USDFeeDisplay
+
+inherits(USDFeeDisplay, Component)
+function USDFeeDisplay () {
+ Component.call(this)
+}
+
+USDFeeDisplay.prototype.render = function () {
+ const {
+ activeCurrency,
+ conversionRate,
+ gas,
+ gasPrice,
+ blockGasLimit,
+ } = this.props
+
+ return h(FiatValue, {
+ value: getTxFeeBn(gas, gasPrice, blockGasLimit),
+ conversionRate,
+ currentCurrency: activeCurrency,
+ style: {
+ color: '#5d5d5d',
+ fontSize: '16px',
+ fontFamily: 'DIN OT',
+ lineHeight: '22.4px',
+ },
+ })
+}
+
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index c5993e3d3..2270b8236 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -1,308 +1,242 @@
-const PersistentForm = require('../../lib/persistent-form')
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const Component = require('react').Component
const connect = require('react-redux').connect
-const actions = require('../actions')
-const Qr = require('./qr-code')
-const isValidAddress = require('../util').isValidAddress
-module.exports = connect(mapStateToProps)(ShapeshiftForm)
+const classnames = require('classnames')
+const { qrcode } = require('qrcode-npm')
+const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../actions')
+const { isValidAddress } = require('../util')
+const SimpleDropdown = require('./dropdowns/simple-dropdown')
function mapStateToProps (state) {
+ const {
+ coinOptions,
+ tokenExchangeRates,
+ selectedAddress,
+ } = state.metamask
+
return {
- warning: state.appState.warning,
- isSubLoading: state.appState.isSubLoading,
- qrRequested: state.appState.qrRequested,
+ coinOptions,
+ tokenExchangeRates,
+ selectedAddress,
}
}
-inherits(ShapeshiftForm, PersistentForm)
+function mapDispatchToProps (dispatch) {
+ return {
+ shapeShiftSubview: () => dispatch(shapeShiftSubview()),
+ pairUpdate: coin => dispatch(pairUpdate(coin)),
+ buyWithShapeShift: data => dispatch(buyWithShapeShift(data)),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm)
+inherits(ShapeshiftForm, Component)
function ShapeshiftForm () {
- PersistentForm.call(this)
- this.persistentFormParentId = 'shapeshift-buy-form'
+ Component.call(this)
+
+ this.state = {
+ depositCoin: 'btc',
+ refundAddress: '',
+ showQrCode: false,
+ depositAddress: '',
+ errorMessage: '',
+ isLoading: false,
+ bought: false,
+ }
}
-ShapeshiftForm.prototype.render = function () {
- return this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain()
+ShapeshiftForm.prototype.componentWillMount = function () {
+ this.props.shapeShiftSubview()
}
-ShapeshiftForm.prototype.renderMain = function () {
- const marketinfo = this.props.buyView.formView.marketinfo
- const coinOptions = this.props.buyView.formView.coinOptions
- var coin = marketinfo.pair.split('_')[0].toUpperCase()
-
- return h('.flex-column', {
- style: {
- position: 'relative',
- padding: '25px',
- paddingTop: '5px',
- width: '90%',
- minHeight: '215px',
- alignItems: 'center',
- overflowY: 'auto',
- },
- }, [
- h('.flex-row', {
- style: {
- justifyContent: 'center',
- alignItems: 'baseline',
- height: '42px',
- },
- }, [
- h('img', {
- src: coinOptions[coin].image,
- width: '25px',
- height: '25px',
- style: {
- marginRight: '5px',
- },
- }),
-
- h('.input-container', {
- position: 'relative',
- }, [
- h('input#fromCoin.buy-inputs.ex-coins', {
- type: 'text',
- list: 'coinList',
- autoFocus: true,
- dataset: {
- persistentFormId: 'input-coin',
- },
- style: {
- boxSizing: 'border-box',
- },
- onChange: this.handleLiveInput.bind(this),
- defaultValue: 'BTC',
- }),
+ShapeshiftForm.prototype.onCoinChange = function (e) {
+ const coin = e.target.value
+ this.setState({
+ depositCoin: coin,
+ errorMessage: '',
+ })
+ this.props.pairUpdate(coin)
+}
- this.renderCoinList(),
+ShapeshiftForm.prototype.onBuyWithShapeShift = function () {
+ this.setState({
+ isLoading: true,
+ showQrCode: true,
+ })
- h('i.fa.fa-pencil-square-o.edit-text', {
- style: {
- fontSize: '12px',
- color: '#F7861C',
- position: 'absolute',
- },
- }),
- ]),
+ const {
+ buyWithShapeShift,
+ selectedAddress: withdrawal,
+ } = this.props
+ const {
+ refundAddress: returnAddress,
+ depositCoin,
+ } = this.state
+ const pair = `${depositCoin}_eth`
+ const data = {
+ withdrawal,
+ pair,
+ returnAddress,
+ // Public api key
+ 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
+ }
- h('.icon-control', {
- style: {
- position: 'relative',
- },
- }, [
- // Not visible on the screen, can't see it on master.
-
- // h('i.fa.fa-refresh.fa-4.orange', {
- // style: {
- // bottom: '5px',
- // left: '5px',
- // color: '#F7861C',
- // },
- // onClick: this.updateCoin.bind(this),
- // }),
- h('i.fa.fa-chevron-right.fa-4.orange', {
- style: {
- position: 'absolute',
- bottom: '35%',
- left: '0%',
- color: '#F7861C',
- },
- onClick: this.updateCoin.bind(this),
- }),
- ]),
+ if (isValidAddress(withdrawal)) {
+ buyWithShapeShift(data)
+ .then(d => this.setState({
+ showQrCode: true,
+ depositAddress: d.deposit,
+ isLoading: false,
+ }))
+ .catch(() => this.setState({
+ showQrCode: false,
+ errorMessage: 'Invalid Request',
+ isLoading: false,
+ }))
+ }
+}
- h('#toCoin.ex-coins', marketinfo.pair.split('_')[1].toUpperCase()),
+ShapeshiftForm.prototype.renderMetadata = function (label, value) {
+ return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [
- h('img', {
- src: coinOptions[marketinfo.pair.split('_')[1].toUpperCase()].image,
- width: '25px',
- height: '25px',
- style: {
- marginLeft: '5px',
- },
- }),
+ h('div.shapeshift-form__metadata-label', {}, [
+ h('span', `${label}:`),
]),
- h('.flex-column', {
- style: {
- marginTop: '1%',
- alignItems: 'flex-start',
- },
- }, [
- this.props.warning ?
- this.props.warning &&
- h('span.error.flex-center', {
- style: {
- textAlign: 'center',
- width: '229px',
- height: '82px',
- },
- }, this.props.warning)
- : this.renderInfo(),
-
- this.renderRefundAddressForCoin(coin),
+ h('div.shapeshift-form__metadata-value', {}, [
+ h('span', value),
]),
])
}
-ShapeshiftForm.prototype.renderRefundAddressForCoin = function (coin) {
- return h(this.activeToggle('.input-container'), {
- style: {
- marginTop: '1%',
- },
- }, [
-
- h('div', `${coin} Address:`),
-
- h('input#fromCoinAddress.buy-inputs', {
- type: 'text',
- placeholder: `Your ${coin} Refund Address`,
- dataset: {
- persistentFormId: 'refund-address',
-
- },
- style: {
- boxSizing: 'border-box',
- width: '227px',
- height: '30px',
- padding: ' 5px ',
- },
- }),
-
- h('i.fa.fa-pencil-square-o.edit-text', {
- style: {
- fontSize: '12px',
- color: '#F7861C',
- position: 'absolute',
- },
- }),
- h('div.flex-row', {
- style: {
- justifyContent: 'flex-start',
- },
- }, [
- h('button', {
- onClick: this.shift.bind(this),
- style: {
- marginTop: '1%',
- },
- },
- 'Submit'),
- ]),
+ShapeshiftForm.prototype.renderMarketInfo = function () {
+ const { depositCoin } = this.state
+ const coinPair = `${depositCoin}_eth`
+ const { tokenExchangeRates } = this.props
+ const {
+ limit,
+ rate,
+ minimum,
+ } = tokenExchangeRates[coinPair] || {}
+
+ return h('div.shapeshift-form__metadata', {}, [
+
+ this.renderMetadata('Status', limit ? 'Available' : 'Unavailable'),
+ this.renderMetadata('Limit', limit),
+ this.renderMetadata('Exchange Rate', rate),
+ this.renderMetadata('Minimum', minimum),
+
])
}
-ShapeshiftForm.prototype.shift = function () {
- var props = this.props
- var withdrawal = this.props.buyView.buyAddress
- var returnAddress = document.getElementById('fromCoinAddress').value
- var pair = this.props.buyView.formView.marketinfo.pair
- var data = {
- 'withdrawal': withdrawal,
- 'pair': pair,
- 'returnAddress': returnAddress,
- // Public api key
- 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
- }
- var message = [
- `Deposit Limit: ${props.buyView.formView.marketinfo.limit}`,
- `Deposit Minimum:${props.buyView.formView.marketinfo.minimum}`,
- ]
- if (isValidAddress(withdrawal)) {
- this.props.dispatch(actions.coinShiftRquest(data, message))
- }
-}
+ShapeshiftForm.prototype.renderQrCode = function () {
+ const { depositAddress, isLoading } = this.state
+ const qrImage = qrcode(4, 'M')
+ qrImage.addData(depositAddress)
+ qrImage.make()
-ShapeshiftForm.prototype.renderCoinList = function () {
- var list = Object.keys(this.props.buyView.formView.coinOptions).map((item) => {
- return h('option', {
- value: item,
- }, item)
- })
+ return h('div.shapeshift-form', {}, [
- return h('datalist#coinList', {
- onClick: (event) => {
- event.preventDefault()
- },
- }, list)
-}
+ h('div.shapeshift-form__deposit-instruction', [
+ 'Deposit your BTC to the address below:',
+ ]),
-ShapeshiftForm.prototype.updateCoin = function (event) {
- event.preventDefault()
- const props = this.props
- var coinOptions = this.props.buyView.formView.coinOptions
- var coin = document.getElementById('fromCoin').value
-
- if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
- var message = 'Not a valid coin'
- return props.dispatch(actions.displayWarning(message))
- } else {
- return props.dispatch(actions.pairUpdate(coin))
- }
-}
+ h('div', depositAddress),
-ShapeshiftForm.prototype.handleLiveInput = function () {
- const props = this.props
- var coinOptions = this.props.buyView.formView.coinOptions
- var coin = document.getElementById('fromCoin').value
+ h('div.shapeshift-form__qr-code', [
+ isLoading
+ ? h('img', {
+ src: 'images/loading.svg',
+ style: { width: '60px'},
+ })
+ : h('div', {
+ dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) },
+ }),
+ ]),
- if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
- return null
- } else {
- return props.dispatch(actions.pairUpdate(coin))
- }
-}
+ this.renderMarketInfo(),
-ShapeshiftForm.prototype.renderInfo = function () {
- const marketinfo = this.props.buyView.formView.marketinfo
- const coinOptions = this.props.buyView.formView.coinOptions
- var coin = marketinfo.pair.split('_')[0].toUpperCase()
-
- return h('span', {
- style: {
- },
- }, [
- h('h3.flex-row.text-transform-uppercase', {
- style: {
- color: '#868686',
- paddingTop: '4px',
- justifyContent: 'space-around',
- textAlign: 'center',
- fontSize: '17px',
- },
- }, `Market Info for ${marketinfo.pair.replace('_', ' to ').toUpperCase()}:`),
- h('.marketinfo', ['Status : ', `${coinOptions[coin].status}`]),
- h('.marketinfo', ['Exchange Rate: ', `${marketinfo.rate}`]),
- h('.marketinfo', ['Limit: ', `${marketinfo.limit}`]),
- h('.marketinfo', ['Minimum : ', `${marketinfo.minimum}`]),
])
}
-ShapeshiftForm.prototype.activeToggle = function (elementType) {
- if (!this.props.buyView.formView.response || this.props.warning) return elementType
- return `${elementType}.inactive`
-}
-ShapeshiftForm.prototype.renderLoading = function () {
- return h('span', {
- style: {
- position: 'absolute',
- left: '70px',
- bottom: '194px',
- background: 'transparent',
- width: '229px',
- height: '82px',
- display: 'flex',
- justifyContent: 'center',
- },
- }, [
- h('img', {
- style: {
- width: '60px',
- },
- src: 'images/loading.svg',
- }),
- ])
+ShapeshiftForm.prototype.render = function () {
+ const { coinOptions, btnClass } = this.props
+ const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state
+ const coinPair = `${depositCoin}_eth`
+ const { tokenExchangeRates } = this.props
+ const token = tokenExchangeRates[coinPair]
+
+ return h('div.shapeshift-form-wrapper', [
+ showQrCode
+ ? this.renderQrCode()
+ : h('div.shapeshift-form', [
+ h('div.shapeshift-form__selectors', [
+
+ h('div.shapeshift-form__selector', [
+
+ h('div.shapeshift-form__selector-label', 'Deposit'),
+
+ h(SimpleDropdown, {
+ selectedOption: this.state.depositCoin,
+ onSelect: this.onCoinChange,
+ options: Object.entries(coinOptions).map(([coin]) => ({
+ value: coin.toLowerCase(),
+ displayValue: coin,
+ })),
+ }),
+
+ ]),
+
+ h('div.icon.shapeshift-form__caret', {
+ style: { backgroundImage: 'url(images/caret-right.svg)'},
+ }),
+
+ h('div.shapeshift-form__selector', [
+
+ h('div.shapeshift-form__selector-label', [
+ 'Receive',
+ ]),
+
+ h('div.shapeshift-form__selector-input', ['ETH']),
+
+ ]),
+
+ ]),
+
+ h('div', {
+ className: classnames('shapeshift-form__address-input-wrapper', {
+ 'shapeshift-form__address-input-wrapper--error': errorMessage,
+ }),
+ }, [
+
+ h('div.shapeshift-form__address-input-label', [
+ 'Your Refund Address',
+ ]),
+
+ h('input.shapeshift-form__address-input', {
+ type: 'text',
+ onChange: e => this.setState({
+ refundAddress: e.target.value,
+ errorMessage: '',
+ }),
+ }),
+
+ h('divshapeshift-form__address-input-error-message', [errorMessage]),
+ ]),
+
+ this.renderMarketInfo(),
+
+ ]),
+
+ !depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', {
+ className: btnClass,
+ disabled: !token,
+ onClick: () => this.onBuyWithShapeShift(),
+ }, ['Buy']),
+
+ ])
}
diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js
index b555dee84..017bf9f0c 100644
--- a/ui/app/components/shift-list-item.js
+++ b/ui/app/components/shift-list-item.js
@@ -16,6 +16,7 @@ module.exports = connect(mapStateToProps)(ShiftListItem)
function mapStateToProps (state) {
return {
+ selectedAddress: state.metamask.selectedAddress,
conversionRate: state.metamask.conversionRate,
currentCurrency: state.metamask.currentCurrency,
}
@@ -28,37 +29,35 @@ function ShiftListItem () {
}
ShiftListItem.prototype.render = function () {
- return (
- h('.transaction-list-item.flex-row', {
+ return h('div.tx-list-item.tx-list-clickable', {
+ style: {
+ paddingTop: '20px',
+ paddingBottom: '20px',
+ justifyContent: 'space-around',
+ alignItems: 'center',
+ },
+ }, [
+ h('div', {
style: {
- paddingTop: '20px',
- paddingBottom: '20px',
- justifyContent: 'space-around',
- alignItems: 'center',
+ width: '0px',
+ position: 'relative',
+ bottom: '19px',
},
}, [
- h('div', {
+ h('img', {
+ src: 'https://info.shapeshift.io/sites/default/files/logo.png',
style: {
- width: '0px',
- position: 'relative',
- bottom: '19px',
+ height: '35px',
+ width: '132px',
+ position: 'absolute',
+ clip: 'rect(0px,23px,34px,0px)',
},
- }, [
- h('img', {
- src: 'https://info.shapeshift.io/sites/default/files/logo.png',
- style: {
- height: '35px',
- width: '132px',
- position: 'absolute',
- clip: 'rect(0px,23px,34px,0px)',
- },
- }),
- ]),
+ }),
+ ]),
- this.renderInfo(),
- this.renderUtilComponents(),
- ])
- )
+ this.renderInfo(),
+ this.renderUtilComponents(),
+ ])
}
function formatDate (date) {
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
new file mode 100644
index 000000000..c5cc23aa8
--- /dev/null
+++ b/ui/app/components/signature-request.js
@@ -0,0 +1,253 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const Identicon = require('./identicon')
+const connect = require('react-redux').connect
+const ethUtil = require('ethereumjs-util')
+const classnames = require('classnames')
+
+const AccountDropdownMini = require('./dropdowns/account-dropdown-mini')
+
+const actions = require('../actions')
+const { conversionUtil } = require('../conversion-util')
+
+const {
+ getSelectedAccount,
+ getCurrentAccountWithSendEtherInfo,
+ getSelectedAddress,
+ accountsWithSendEtherInfoSelector,
+ conversionRateSelector,
+} = require('../selectors.js')
+
+function mapStateToProps (state) {
+ return {
+ balance: getSelectedAccount(state).balance,
+ selectedAccount: getCurrentAccountWithSendEtherInfo(state),
+ selectedAddress: getSelectedAddress(state),
+ requester: null,
+ requesterAddress: null,
+ accounts: accountsWithSendEtherInfoSelector(state),
+ conversionRate: conversionRateSelector(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(SignatureRequest)
+
+inherits(SignatureRequest, Component)
+function SignatureRequest (props) {
+ Component.call(this)
+
+ this.state = {
+ selectedAccount: props.selectedAccount,
+ accountDropdownOpen: false,
+ }
+}
+
+SignatureRequest.prototype.renderHeader = function () {
+ return h('div.request-signature__header', [
+
+ h('div.request-signature__header-background'),
+
+ h('div.request-signature__header__text', 'Signature Request'),
+
+ h('div.request-signature__header__tip-container', [
+ h('div.request-signature__header__tip'),
+ ]),
+
+ ])
+}
+
+SignatureRequest.prototype.renderAccountDropdown = function () {
+ const {
+ selectedAccount,
+ accountDropdownOpen,
+ } = this.state
+
+ const {
+ accounts,
+ } = this.props
+
+ return h('div.request-signature__account', [
+
+ h('div.request-signature__account-text', ['Account:']),
+
+ h(AccountDropdownMini, {
+ selectedAccount,
+ accounts,
+ onSelect: selectedAccount => this.setState({ selectedAccount }),
+ dropdownOpen: accountDropdownOpen,
+ openDropdown: () => this.setState({ accountDropdownOpen: true }),
+ closeDropdown: () => this.setState({ accountDropdownOpen: false }),
+ }),
+
+ ])
+}
+
+SignatureRequest.prototype.renderBalance = function () {
+ const { balance, conversionRate } = this.props
+
+ const balanceInEther = conversionUtil(balance, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ return h('div.request-signature__balance', [
+
+ h('div.request-signature__balance-text', ['Balance:']),
+
+ h('div.request-signature__balance-value', `${balanceInEther} ETH`),
+
+ ])
+}
+
+SignatureRequest.prototype.renderAccountInfo = function () {
+ return h('div.request-signature__account-info', [
+
+ this.renderAccountDropdown(),
+
+ this.renderRequestIcon(),
+
+ this.renderBalance(),
+
+ ])
+}
+
+SignatureRequest.prototype.renderRequestIcon = function () {
+ const { requesterAddress } = this.props
+
+ return h('div.request-signature__request-icon', [
+ h(Identicon, {
+ diameter: 40,
+ address: requesterAddress,
+ }),
+ ])
+}
+
+SignatureRequest.prototype.renderRequestInfo = function () {
+ return h('div.request-signature__request-info', [
+
+ h('div.request-signature__headline', [
+ `Your signature is being requested`,
+ ]),
+
+ ])
+}
+
+SignatureRequest.prototype.msgHexToText = function (hex) {
+ try {
+ const stripped = ethUtil.stripHexPrefix(hex)
+ const buff = Buffer.from(stripped, 'hex')
+ return buff.toString('utf8')
+ } catch (e) {
+ return hex
+ }
+}
+
+SignatureRequest.prototype.renderBody = function () {
+ let rows
+ let notice = 'You are signing:'
+
+ const { txData } = this.props
+ const { type, msgParams: { data } } = txData
+
+ if (type === 'personal_sign') {
+ rows = [{ name: 'Message', value: this.msgHexToText(data) }]
+ } else if (type === 'eth_signTypedData') {
+ rows = data
+ } else if (type === 'eth_sign') {
+ rows = [{ name: 'Message', value: data }]
+ notice = `Signing this message can have
+ dangerous side effects. Only sign messages from
+ sites you fully trust with your entire account.
+ This dangerous method will be removed in a future version. `
+ }
+
+ return h('div.request-signature__body', {}, [
+
+ this.renderAccountInfo(),
+
+ this.renderRequestInfo(),
+
+ h('div.request-signature__notice', {
+ className: classnames({
+ 'request-signature__notice': type === 'personal_sign' || type === 'eth_signTypedData',
+ 'request-signature__warning': type === 'eth_sign',
+ }),
+ }, [notice]),
+
+ h('div.request-signature__rows', [
+
+ ...rows.map(({ name, value }) => {
+ return h('div.request-signature__row', [
+ h('div.request-signature__row-title', [`${name}:`]),
+ h('div.request-signature__row-value', value),
+ ])
+ }),
+
+ ]),
+
+ ])
+}
+
+SignatureRequest.prototype.renderFooter = function () {
+ const {
+ signPersonalMessage,
+ signTypedMessage,
+ cancelPersonalMessage,
+ cancelTypedMessage,
+ signMessage,
+ cancelMessage,
+ } = this.props
+
+ const { txData } = this.props
+ const { type } = txData
+
+ let cancel
+ let sign
+ if (type === 'personal_sign') {
+ cancel = cancelPersonalMessage
+ sign = signPersonalMessage
+ } else if (type === 'eth_signTypedData') {
+ cancel = cancelTypedMessage
+ sign = signTypedMessage
+ } else if (type === 'eth_sign') {
+ cancel = cancelMessage
+ sign = signMessage
+ }
+
+ return h('div.request-signature__footer', [
+ h('button.request-signature__footer__cancel-button', {
+ onClick: cancel,
+ }, 'CANCEL'),
+ h('button.request-signature__footer__sign-button', {
+ onClick: sign,
+ }, 'SIGN'),
+ ])
+}
+
+SignatureRequest.prototype.render = function () {
+ return (
+
+ h('div.request-signature__container', [
+
+ this.renderHeader(),
+
+ this.renderBody(),
+
+ this.renderFooter(),
+
+ ])
+
+ )
+
+}
+
diff --git a/ui/app/components/tab-bar.js b/ui/app/components/tab-bar.js
index bef444a48..a80640116 100644
--- a/ui/app/components/tab-bar.js
+++ b/ui/app/components/tab-bar.js
@@ -1,37 +1,47 @@
-const Component = require('react').Component
+const { Component } = require('react')
const h = require('react-hyperscript')
-const inherits = require('util').inherits
+const PropTypes = require('prop-types')
+const classnames = require('classnames')
-module.exports = TabBar
+class TabBar extends Component {
+ constructor (props) {
+ super(props)
+ const { defaultTab, tabs } = props
-inherits(TabBar, Component)
-function TabBar () {
- Component.call(this)
-}
+ this.state = {
+ subview: defaultTab || tabs[0].key,
+ }
+ }
-TabBar.prototype.render = function () {
- const props = this.props
- const state = this.state || {}
- const { tabs = [], defaultTab, tabSelected } = props
- const { subview = defaultTab } = state
+ render () {
+ const { tabs = [], tabSelected } = this.props
+ const { subview } = this.state
- return (
- h('.flex-row.space-around.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- paddingTop: '4px',
- minHeight: '30px',
- },
- }, tabs.map((tab) => {
- const { key, content } = tab
- return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', {
- onClick: () => {
- this.setState({ subview: key })
- tabSelected(key)
- },
- }, content)
- }))
- )
+ return (
+ h('.tab-bar', {}, [
+ tabs.map((tab) => {
+ const { key, content } = tab
+ return h('div', {
+ className: classnames('tab-bar__tab pointer', {
+ 'tab-bar__tab--active': subview === key,
+ }),
+ onClick: () => {
+ this.setState({ subview: key })
+ tabSelected(key)
+ },
+ key,
+ }, content)
+ }),
+ h('div.tab-bar__tab.tab-bar__grow-tab'),
+ ])
+ )
+ }
}
+TabBar.propTypes = {
+ defaultTab: PropTypes.string,
+ tabs: PropTypes.array,
+ tabSelected: PropTypes.func,
+}
+
+module.exports = TabBar
diff --git a/ui/app/components/token-balance.js b/ui/app/components/token-balance.js
new file mode 100644
index 000000000..2f71c0687
--- /dev/null
+++ b/ui/app/components/token-balance.js
@@ -0,0 +1,113 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const TokenTracker = require('eth-token-tracker')
+const connect = require('react-redux').connect
+const selectors = require('../selectors')
+
+function mapStateToProps (state) {
+ return {
+ userAddress: selectors.getSelectedAddress(state),
+ }
+}
+
+module.exports = connect(mapStateToProps)(TokenBalance)
+
+
+inherits(TokenBalance, Component)
+function TokenBalance () {
+ this.state = {
+ string: '',
+ symbol: '',
+ isLoading: true,
+ error: null,
+ }
+ Component.call(this)
+}
+
+TokenBalance.prototype.render = function () {
+ const state = this.state
+ const { symbol, string, isLoading } = state
+ const { balanceOnly } = this.props
+
+ return isLoading
+ ? h('span', '')
+ : h('span.token-balance', [
+ h('span.token-balance__amount', string),
+ !balanceOnly && h('span.token-balance__symbol', symbol),
+ ])
+}
+
+TokenBalance.prototype.componentDidMount = function () {
+ this.createFreshTokenTracker()
+}
+
+TokenBalance.prototype.createFreshTokenTracker = function () {
+ if (this.tracker) {
+ // Clean up old trackers when refreshing:
+ this.tracker.stop()
+ this.tracker.removeListener('update', this.balanceUpdater)
+ this.tracker.removeListener('error', this.showError)
+ }
+
+ if (!global.ethereumProvider) return
+ const { userAddress, token } = this.props
+
+ this.tracker = new TokenTracker({
+ userAddress,
+ provider: global.ethereumProvider,
+ tokens: [token],
+ pollingInterval: 8000,
+ })
+
+
+ // Set up listener instances for cleaning up
+ this.balanceUpdater = this.updateBalance.bind(this)
+ this.showError = error => {
+ this.setState({ error, isLoading: false })
+ }
+ this.tracker.on('update', this.balanceUpdater)
+ this.tracker.on('error', this.showError)
+
+ this.tracker.updateBalances()
+ .then(() => {
+ this.updateBalance(this.tracker.serialize())
+ })
+ .catch((reason) => {
+ log.error(`Problem updating balances`, reason)
+ this.setState({ isLoading: false })
+ })
+}
+
+TokenBalance.prototype.componentDidUpdate = function (nextProps) {
+ const {
+ userAddress: oldAddress,
+ token: { address: oldTokenAddress },
+ } = this.props
+ const {
+ userAddress: newAddress,
+ token: { address: newTokenAddress },
+ } = nextProps
+
+ if ((!oldAddress || !newAddress) && (!oldTokenAddress || !newTokenAddress)) return
+ if ((oldAddress === newAddress) && (oldTokenAddress === newTokenAddress)) return
+
+ this.setState({ isLoading: true })
+ this.createFreshTokenTracker()
+}
+
+TokenBalance.prototype.updateBalance = function (tokens = []) {
+ const [{ string, symbol }] = tokens
+
+ this.setState({
+ string,
+ symbol,
+ isLoading: false,
+ })
+}
+
+TokenBalance.prototype.componentWillUnmount = function () {
+ if (!this.tracker) return
+ this.tracker.stop()
+}
+
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
index 19d7139bb..0332fde88 100644
--- a/ui/app/components/token-cell.js
+++ b/ui/app/components/token-cell.js
@@ -1,35 +1,139 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const connect = require('react-redux').connect
const Identicon = require('./identicon')
const prefixForNetwork = require('../../lib/etherscan-prefix-for-network')
+const selectors = require('../selectors')
+const actions = require('../actions')
+const { conversionUtil, multiplyCurrencies } = require('../conversion-util')
-module.exports = TokenCell
+const TokenMenuDropdown = require('./dropdowns/token-menu-dropdown.js')
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ currentCurrency: state.metamask.currentCurrency,
+ selectedTokenAddress: state.metamask.selectedTokenAddress,
+ userAddress: selectors.getSelectedAddress(state),
+ tokenExchangeRates: state.metamask.tokenExchangeRates,
+ conversionRate: state.metamask.conversionRate,
+ sidebarOpen: state.appState.sidebarOpen,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ setSelectedToken: address => dispatch(actions.setSelectedToken(address)),
+ updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
+ hideSidebar: () => dispatch(actions.hideSidebar()),
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(TokenCell)
inherits(TokenCell, Component)
function TokenCell () {
Component.call(this)
+
+ this.state = {
+ tokenMenuOpen: false,
+ }
+}
+
+TokenCell.prototype.componentWillMount = function () {
+ const {
+ updateTokenExchangeRate,
+ symbol,
+ } = this.props
+
+ updateTokenExchangeRate(symbol)
}
TokenCell.prototype.render = function () {
+ const { tokenMenuOpen } = this.state
const props = this.props
- const { address, symbol, string, network, userAddress } = props
+ const {
+ address,
+ symbol,
+ string,
+ network,
+ setSelectedToken,
+ selectedTokenAddress,
+ tokenExchangeRates,
+ conversionRate,
+ hideSidebar,
+ sidebarOpen,
+ currentCurrency,
+ // userAddress,
+ } = props
+
+ const pair = `${symbol.toLowerCase()}_eth`
+
+ let currentTokenToFiatRate
+ let currentTokenInFiat
+ let formattedFiat = ''
+
+ if (tokenExchangeRates[pair]) {
+ currentTokenToFiatRate = multiplyCurrencies(
+ tokenExchangeRates[pair].rate,
+ conversionRate
+ )
+ currentTokenInFiat = conversionUtil(string, {
+ fromNumericBase: 'dec',
+ fromCurrency: symbol,
+ toCurrency: currentCurrency.toUpperCase(),
+ numberOfDecimals: 2,
+ conversionRate: currentTokenToFiatRate,
+ })
+ formattedFiat = currentTokenInFiat.toString() === '0'
+ ? ''
+ : `${currentTokenInFiat} ${currentCurrency.toUpperCase()}`
+ }
+
+ const showFiat = Boolean(currentTokenInFiat) && currentCurrency.toUpperCase() !== symbol
return (
- h('li.token-cell', {
- style: { cursor: network === '1' ? 'pointer' : 'default' },
- onClick: this.view.bind(this, address, userAddress, network),
+ h('div.token-list-item', {
+ className: `token-list-item ${selectedTokenAddress === address ? 'token-list-item--active' : ''}`,
+ // style: { cursor: network === '1' ? 'pointer' : 'default' },
+ // onClick: this.view.bind(this, address, userAddress, network),
+ onClick: () => {
+ setSelectedToken(address)
+ selectedTokenAddress !== address && sidebarOpen && hideSidebar()
+ },
}, [
h(Identicon, {
+ className: 'token-list-item__identicon',
diameter: 50,
address,
network,
}),
- h('h3', `${string || 0} ${symbol}`),
+ h('div.token-list-item__balance-ellipsis', null, [
+ h('div.token-list-item__balance-wrapper', null, [
+ h('h3.token-list-item__token-balance', `${string || 0} ${symbol}`),
- h('span', { style: { flex: '1 0 auto' } }),
+ showFiat && h('div.token-list-item__fiat-amount', {
+ style: {},
+ }, formattedFiat),
+ ]),
+
+ h('i.fa.fa-ellipsis-h.fa-lg.token-list-item__ellipsis.cursor-pointer', {
+ onClick: (e) => {
+ e.stopPropagation()
+ this.setState({ tokenMenuOpen: true })
+ },
+ }),
+
+ ]),
+
+
+ tokenMenuOpen && h(TokenMenuDropdown, {
+ onClose: () => this.setState({ tokenMenuOpen: false }),
+ token: { symbol, address },
+ }),
/*
h('button', {
diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js
index 149733b89..8e06e0f27 100644
--- a/ui/app/components/token-list.js
+++ b/ui/app/components/token-list.js
@@ -3,8 +3,28 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits
const TokenTracker = require('eth-token-tracker')
const TokenCell = require('./token-cell.js')
+const connect = require('react-redux').connect
+const selectors = require('../selectors')
+
+function mapStateToProps (state) {
+ return {
+ network: state.metamask.network,
+ tokens: state.metamask.tokens,
+ userAddress: selectors.getSelectedAddress(state),
+ }
+}
+
+const defaultTokens = []
+const contracts = require('eth-contract-metadata')
+for (const address in contracts) {
+ const contract = contracts[address]
+ if (contract.erc20) {
+ contract.address = address
+ defaultTokens.push(contract)
+ }
+}
-module.exports = TokenList
+module.exports = connect(mapStateToProps)(TokenList)
inherits(TokenList, Component)
function TokenList () {
@@ -17,12 +37,12 @@ function TokenList () {
}
TokenList.prototype.render = function () {
+ const { userAddress } = this.props
const state = this.state
const { tokens, isLoading, error } = state
- const { userAddress, network } = this.props
if (isLoading) {
- return this.message('Loading')
+ return this.message('Loading Tokens...')
}
if (error) {
@@ -47,87 +67,8 @@ TokenList.prototype.render = function () {
])
}
- const tokenViews = tokens.map((tokenData) => {
- tokenData.network = network
- tokenData.userAddress = userAddress
- return h(TokenCell, tokenData)
- })
-
- return h('.full-flex-height', [
- this.renderTokenStatusBar(),
+ return h('div', tokens.map((tokenData) => h(TokenCell, tokenData)))
- h('ol.full-flex-height.flex-column', {
- style: {
- overflowY: 'auto',
- display: 'flex',
- flexDirection: 'column',
- },
- }, [
- h('style', `
-
- li.token-cell {
- display: flex;
- flex-direction: row;
- align-items: center;
- padding: 10px;
- min-height: 50px;
- }
-
- li.token-cell > h3 {
- margin-left: 12px;
- }
-
- li.token-cell:hover {
- background: white;
- cursor: pointer;
- }
-
- `),
- ...tokenViews,
- h('.flex-grow'),
- ]),
- ])
-}
-
-TokenList.prototype.renderTokenStatusBar = function () {
- const { tokens } = this.state
-
- let msg
- if (tokens.length === 1) {
- msg = `You own 1 token`
- } else if (tokens.length > 1) {
- msg = `You own ${tokens.length} tokens`
- } else {
- msg = `No tokens found`
- }
-
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'space-between',
- alignItems: 'center',
- minHeight: '70px',
- padding: '10px',
- },
- }, [
- h('span', msg),
- h('button', {
- key: 'reveal-account-bar',
- onClick: (event) => {
- event.preventDefault()
- this.props.addToken()
- },
- style: {
- display: 'flex',
- height: '40px',
- padding: '10px',
- justifyContent: 'center',
- alignItems: 'center',
- },
- }, [
- 'ADD TOKEN',
- ]),
- ])
}
TokenList.prototype.message = function (body) {
@@ -156,6 +97,7 @@ TokenList.prototype.createFreshTokenTracker = function () {
if (!global.ethereumProvider) return
const { userAddress } = this.props
+
this.tracker = new TokenTracker({
userAddress,
provider: global.ethereumProvider,
@@ -182,15 +124,30 @@ TokenList.prototype.createFreshTokenTracker = function () {
})
}
-TokenList.prototype.componentWillUpdate = function (nextProps) {
- if (nextProps.network === 'loading') return
- const oldNet = this.props.network
- const newNet = nextProps.network
-
- if (oldNet && newNet && newNet !== oldNet) {
- this.setState({ isLoading: true })
- this.createFreshTokenTracker()
- }
+TokenList.prototype.componentDidUpdate = function (nextProps) {
+ const {
+ network: oldNet,
+ userAddress: oldAddress,
+ tokens,
+ } = this.props
+ const {
+ network: newNet,
+ userAddress: newAddress,
+ tokens: newTokens,
+ } = nextProps
+
+ const isLoading = newNet === 'loading'
+ const missingInfo = !oldNet || !newNet || !oldAddress || !newAddress
+ const sameUserAndNetwork = oldAddress === newAddress && oldNet === newNet
+ const shouldUpdateTokens = isLoading || missingInfo || sameUserAndNetwork
+
+ const oldTokensLength = tokens ? tokens.length : 0
+ const tokensLengthUnchanged = oldTokensLength === newTokens.length
+
+ if (tokensLengthUnchanged && shouldUpdateTokens) return
+
+ this.setState({ isLoading: true })
+ this.createFreshTokenTracker()
}
TokenList.prototype.updateBalances = function (tokens) {
@@ -202,3 +159,15 @@ TokenList.prototype.componentWillUnmount = function () {
this.tracker.stop()
}
+// function uniqueMergeTokens (tokensA, tokensB = []) {
+// const uniqueAddresses = []
+// const result = []
+// tokensA.concat(tokensB).forEach((token) => {
+// const normal = normalizeAddress(token.address)
+// if (!uniqueAddresses.includes(normal)) {
+// uniqueAddresses.push(normal)
+// result.push(token)
+// }
+// })
+// return result
+// }
diff --git a/ui/app/components/tooltip-v2.js b/ui/app/components/tooltip-v2.js
new file mode 100644
index 000000000..133a0f16a
--- /dev/null
+++ b/ui/app/components/tooltip-v2.js
@@ -0,0 +1,31 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const ReactTippy = require('react-tippy').Tooltip
+
+module.exports = Tooltip
+
+inherits(Tooltip, Component)
+function Tooltip () {
+ Component.call(this)
+}
+
+Tooltip.prototype.render = function () {
+ const props = this.props
+ const { position, title, children, wrapperClassName } = props
+
+ return h('div', {
+ className: wrapperClassName,
+ }, [
+
+ h(ReactTippy, {
+ title,
+ position: position || 'left',
+ trigger: 'mouseenter',
+ hideOnClick: false,
+ size: 'small',
+ arrow: true,
+ }, children),
+
+ ])
+}
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 42ef665b1..4e3d2cb93 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -199,34 +199,40 @@ function formatDate (date) {
}
function renderErrorOrWarning (transaction) {
- const { status, err, warning } = transaction
+ const { status } = transaction
// show rejected
if (status === 'rejected') {
return h('span.error', ' (Rejected)')
}
-
- // show error
- if (err) {
- const message = err.message || ''
- return (
- h(Tooltip, {
- title: message,
- position: 'bottom',
- }, [
- h(`span.error`, ` (Failed)`),
- ])
- )
- }
-
- // show warning
- if (warning) {
- const message = warning.message
- return h(Tooltip, {
- title: message,
- position: 'bottom',
- }, [
- h(`span.warning`, ` (Warning)`),
- ])
+ if (transaction.err || transaction.warning) {
+ const { err, warning = {} } = transaction
+ const errFirst = !!((err && warning) || err)
+
+ errFirst ? err.message : warning.message
+
+ // show error
+ if (err) {
+ const message = err.message || ''
+ return (
+ h(Tooltip, {
+ title: message,
+ position: 'bottom',
+ }, [
+ h(`span.error`, ` (Failed)`),
+ ])
+ )
+ }
+
+ // show warning
+ if (warning) {
+ const message = warning.message
+ return h(Tooltip, {
+ title: message,
+ position: 'bottom',
+ }, [
+ h(`span.warning`, ` (Warning)`),
+ ])
+ }
}
}
diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js
new file mode 100644
index 000000000..7ccc5c315
--- /dev/null
+++ b/ui/app/components/tx-list-item.js
@@ -0,0 +1,245 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+const inherits = require('util').inherits
+const classnames = require('classnames')
+const abi = require('human-standard-token-abi')
+const abiDecoder = require('abi-decoder')
+abiDecoder.addABI(abi)
+const Identicon = require('./identicon')
+const contractMap = require('eth-contract-metadata')
+
+const { conversionUtil, multiplyCurrencies } = require('../conversion-util')
+const { calcTokenAmount } = require('../token-util')
+
+const { getCurrentCurrency } = require('../selectors')
+
+module.exports = connect(mapStateToProps)(TxListItem)
+
+function mapStateToProps (state) {
+ return {
+ tokens: state.metamask.tokens,
+ currentCurrency: getCurrentCurrency(state),
+ tokenExchangeRates: state.metamask.tokenExchangeRates,
+ }
+}
+
+inherits(TxListItem, Component)
+function TxListItem () {
+ Component.call(this)
+
+ this.state = {
+ total: null,
+ fiatTotal: null,
+ }
+}
+
+TxListItem.prototype.componentDidMount = async function () {
+ const { txParams = {} } = this.props
+
+ const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { name: txDataName } = decodedData || {}
+
+ const { total, fiatTotal } = txDataName === 'transfer'
+ ? await this.getSendTokenTotal()
+ : this.getSendEtherTotal()
+
+ this.setState({ total, fiatTotal })
+}
+
+TxListItem.prototype.getAddressText = function () {
+ const {
+ address,
+ txParams = {},
+ } = this.props
+
+ const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { name: txDataName, params = [] } = decodedData || {}
+ const { value } = params[0] || {}
+
+ switch (txDataName) {
+ case 'transfer':
+ return `${value.slice(0, 10)}...${value.slice(-4)}`
+ default:
+ return address
+ ? `${address.slice(0, 10)}...${address.slice(-4)}`
+ : 'Contract Published'
+ }
+}
+
+TxListItem.prototype.getSendEtherTotal = function () {
+ const {
+ transactionAmount,
+ conversionRate,
+ address,
+ currentCurrency,
+ } = this.props
+
+ if (!address) {
+ return {}
+ }
+
+ const totalInFiat = conversionUtil(transactionAmount, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ fromDenomination: 'WEI',
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const totalInETH = conversionUtil(transactionAmount, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ fromDenomination: 'WEI',
+ conversionRate,
+ numberOfDecimals: 6,
+ })
+
+ return {
+ total: `${totalInETH} ETH`,
+ fiatTotal: `${totalInFiat} ${currentCurrency.toUpperCase()}`,
+ }
+}
+
+TxListItem.prototype.getTokenInfo = async function () {
+ const { txParams = {}, tokenInfoGetter, tokens } = this.props
+ const toAddress = txParams.to
+
+ let decimals
+ let symbol
+
+ ({ decimals, symbol } = tokens.filter(({ address }) => address === toAddress)[0] || {})
+
+ if (!decimals && !symbol) {
+ ({ decimals, symbol } = contractMap[toAddress] || {})
+ }
+
+ if (!decimals && !symbol) {
+ ({ decimals, symbol } = await tokenInfoGetter(toAddress))
+ }
+
+ return { decimals, symbol }
+}
+
+TxListItem.prototype.getSendTokenTotal = async function () {
+ const {
+ txParams = {},
+ conversionRate,
+ tokenExchangeRates,
+ currentCurrency,
+ } = this.props
+
+ const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { params = [] } = decodedData || {}
+ const { value } = params[1] || {}
+ const { decimals, symbol } = await this.getTokenInfo()
+ const total = calcTokenAmount(value, decimals)
+
+ const pair = symbol && `${symbol.toLowerCase()}_eth`
+
+ let tokenToFiatRate
+ let totalInFiat
+
+ if (tokenExchangeRates[pair]) {
+ tokenToFiatRate = multiplyCurrencies(
+ tokenExchangeRates[pair].rate,
+ conversionRate
+ )
+
+ totalInFiat = conversionUtil(total, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'dec',
+ fromCurrency: symbol,
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate: tokenToFiatRate,
+ })
+ }
+
+ const showFiat = Boolean(totalInFiat) && currentCurrency.toUpperCase() !== symbol
+
+ return {
+ total: `${total} ${symbol}`,
+ fiatTotal: showFiat && `${totalInFiat} ${currentCurrency.toUpperCase()}`,
+ }
+}
+
+TxListItem.prototype.render = function () {
+ const {
+ transactionStatus,
+ transactionAmount,
+ onClick,
+ transActionId,
+ dateString,
+ address,
+ className,
+ } = this.props
+ const { total, fiatTotal } = this.state
+ const showFiatTotal = transactionAmount !== '0x0' && fiatTotal
+
+ return h(`div${className || ''}`, {
+ key: transActionId,
+ onClick: () => onClick && onClick(transActionId),
+ }, [
+ h(`div.flex-column.tx-list-item-wrapper`, {}, [
+
+ h('div.tx-list-date-wrapper', {
+ style: {},
+ }, [
+ h('span.tx-list-date', {}, [
+ dateString,
+ ]),
+ ]),
+
+ h('div.flex-row.tx-list-content-wrapper', {
+ style: {},
+ }, [
+
+ h('div.tx-list-identicon-wrapper', {
+ style: {},
+ }, [
+ h(Identicon, {
+ address,
+ diameter: 28,
+ }),
+ ]),
+
+ h('div.tx-list-account-and-status-wrapper', {}, [
+ h('div.tx-list-account-wrapper', {
+ style: {},
+ }, [
+ h('span.tx-list-account', {}, [
+ this.getAddressText(address),
+ ]),
+ ]),
+
+ h('div.tx-list-status-wrapper', {
+ style: {},
+ }, [
+ h('span', {
+ className: classnames('tx-list-status', {
+ 'tx-list-status--rejected': transactionStatus === 'rejected',
+ 'tx-list-status--failed': transactionStatus === 'failed',
+ }),
+ },
+ transactionStatus,
+ ),
+ ]),
+ ]),
+
+ h('div.flex-column.tx-list-details-wrapper', {
+ style: {},
+ }, [
+
+ h('span.tx-list-value', total),
+
+ showFiatTotal && h('span.tx-list-fiat-value', fiatTotal),
+
+ ]),
+ ]),
+ ]), // holding on icon from design
+ ])
+}
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
new file mode 100644
index 000000000..1729e6a6f
--- /dev/null
+++ b/ui/app/components/tx-list.js
@@ -0,0 +1,137 @@
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const prefixForNetwork = require('../../lib/etherscan-prefix-for-network')
+const selectors = require('../selectors')
+const TxListItem = require('./tx-list-item')
+const ShiftListItem = require('./shift-list-item')
+const { formatDate } = require('../util')
+const { showConfTxPage } = require('../actions')
+const classnames = require('classnames')
+const { tokenInfoGetter } = require('../token-util')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(TxList)
+
+function mapStateToProps (state) {
+ return {
+ txsToRender: selectors.transactionsSelector(state),
+ conversionRate: selectors.conversionRateSelector(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showConfTxPage: ({ id }) => dispatch(showConfTxPage({ id })),
+ }
+}
+
+inherits(TxList, Component)
+function TxList () {
+ Component.call(this)
+}
+
+TxList.prototype.componentWillMount = function () {
+ this.tokenInfoGetter = tokenInfoGetter()
+}
+
+TxList.prototype.render = function () {
+ return h('div.flex-column', [
+ h('div.flex-row.tx-list-header-wrapper', [
+ h('div.flex-row.tx-list-header', [
+ h('div', 'transactions'),
+ ]),
+ ]),
+ h('div.flex-column.tx-list-container', {}, [
+ this.renderTransaction(),
+ ]),
+ ])
+}
+
+TxList.prototype.renderTransaction = function () {
+ const { txsToRender, conversionRate } = this.props
+
+ return txsToRender.length
+ ? txsToRender.map((transaction, i) => this.renderTransactionListItem(transaction, conversionRate, i))
+ : [h(
+ 'div.tx-list-item.tx-list-item--empty',
+ { key: 'tx-list-none' },
+ [ 'No Transactions' ],
+ )]
+}
+
+// TODO: Consider moving TxListItem into a separate component
+TxList.prototype.renderTransactionListItem = function (transaction, conversionRate, index) {
+ // console.log({transaction})
+ // refer to transaction-list.js:line 58
+
+ if (transaction.key === 'shapeshift') {
+ return h(ShiftListItem, { ...transaction, key: `shapeshift${index}` })
+ }
+
+ const props = {
+ dateString: formatDate(transaction.time),
+ address: transaction.txParams.to,
+ transactionStatus: transaction.status,
+ transactionAmount: transaction.txParams.value,
+ transActionId: transaction.id,
+ transactionHash: transaction.hash,
+ transactionNetworkId: transaction.metamaskNetworkId,
+ }
+
+ const {
+ address,
+ transactionStatus,
+ transactionAmount,
+ dateString,
+ transActionId,
+ transactionHash,
+ transactionNetworkId,
+ } = props
+ const { showConfTxPage } = this.props
+
+ const opts = {
+ key: transActionId || transactionHash,
+ txParams: transaction.txParams,
+ transactionStatus,
+ transActionId,
+ dateString,
+ address,
+ transactionAmount,
+ transactionHash,
+ conversionRate,
+ tokenInfoGetter: this.tokenInfoGetter,
+ }
+
+ const isUnapproved = transactionStatus === 'unapproved'
+
+ if (isUnapproved) {
+ opts.onClick = () => showConfTxPage({id: transActionId})
+ opts.transactionStatus = 'Not Started'
+ } else if (transactionHash) {
+ opts.onClick = () => this.view(transactionHash, transactionNetworkId)
+ }
+
+ opts.className = classnames('.tx-list-item', {
+ '.tx-list-pending-item-container': isUnapproved,
+ '.tx-list-clickable': Boolean(transactionHash) || isUnapproved,
+ })
+
+ return h(TxListItem, opts)
+}
+
+TxList.prototype.view = function (txHash, network) {
+ const url = etherscanLinkFor(txHash, network)
+ if (url) {
+ navigateTo(url)
+ }
+}
+
+function navigateTo (url) {
+ global.platform.openWindow({ url })
+}
+
+function etherscanLinkFor (txHash, network) {
+ const prefix = prefixForNetwork(network)
+ return `https://${prefix}etherscan.io/tx/${txHash}`
+}
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
new file mode 100644
index 000000000..b25d8e0f9
--- /dev/null
+++ b/ui/app/components/tx-view.js
@@ -0,0 +1,148 @@
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const ethUtil = require('ethereumjs-util')
+const inherits = require('util').inherits
+const actions = require('../actions')
+const selectors = require('../selectors')
+
+const BalanceComponent = require('./balance-component')
+const TxList = require('./tx-list')
+const Identicon = require('./identicon')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(TxView)
+
+function mapStateToProps (state) {
+ const sidebarOpen = state.appState.sidebarOpen
+ const isMascara = state.appState.isMascara
+
+ const identities = state.metamask.identities
+ const accounts = state.metamask.accounts
+ const network = state.metamask.network
+ const selectedTokenAddress = state.metamask.selectedTokenAddress
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ const checksumAddress = selectedAddress && ethUtil.toChecksumAddress(selectedAddress)
+ const identity = identities[selectedAddress]
+
+ return {
+ sidebarOpen,
+ selectedAddress,
+ checksumAddress,
+ selectedTokenAddress,
+ selectedToken: selectors.getSelectedToken(state),
+ identity,
+ network,
+ isMascara,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showSidebar: () => { dispatch(actions.showSidebar()) },
+ hideSidebar: () => { dispatch(actions.hideSidebar()) },
+ showModal: (payload) => { dispatch(actions.showModal(payload)) },
+ showSendPage: () => { dispatch(actions.showSendPage()) },
+ showSendTokenPage: () => { dispatch(actions.showSendTokenPage()) },
+ }
+}
+
+inherits(TxView, Component)
+function TxView () {
+ Component.call(this)
+}
+
+TxView.prototype.renderHeroBalance = function () {
+ const { selectedToken } = this.props
+
+ return h('div.hero-balance', {}, [
+
+ h(BalanceComponent, { token: selectedToken }),
+
+ this.renderButtons(),
+ ])
+}
+
+TxView.prototype.renderButtons = function () {
+ const {selectedToken, showModal, showSendPage, showSendTokenPage } = this.props
+
+ return !selectedToken
+ ? (
+ h('div.flex-row.flex-center.hero-balance-buttons', [
+ h('button.btn-clear.hero-balance-button', {
+ onClick: () => showModal({
+ name: 'DEPOSIT_ETHER',
+ }),
+ }, 'DEPOSIT'),
+
+ h('button.btn-clear.hero-balance-button', {
+ style: {
+ marginLeft: '0.8em',
+ },
+ onClick: showSendPage,
+ }, 'SEND'),
+ ])
+ )
+ : (
+ h('div.flex-row.flex-center.hero-balance-buttons', [
+ h('button.btn-clear.hero-balance-button', {
+ onClick: showSendTokenPage,
+ }, 'SEND'),
+ ])
+ )
+}
+
+TxView.prototype.render = function () {
+ const { selectedAddress, identity, network, isMascara } = this.props
+
+ return h('div.tx-view.flex-column', {
+ style: {},
+ }, [
+
+ h('div.flex-row.phone-visible', {
+ style: {
+ margin: '1.5em 1.2em 0',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ },
+ }, [
+
+ h('div.fa.fa-bars', {
+ style: {
+ fontSize: '1.3em',
+ cursor: 'pointer',
+ },
+ onClick: () => {
+ this.props.sidebarOpen ? this.props.hideSidebar() : this.props.showSidebar()
+ },
+ }, []),
+
+ h('.identicon-wrapper.select-none', {
+ style: {
+ marginLeft: '0.9em',
+ },
+ }, [
+ h(Identicon, {
+ diameter: 24,
+ address: selectedAddress,
+ network,
+ }),
+ ]),
+
+ h('span.account-name', {
+ style: {},
+ }, [
+ identity.name,
+ ]),
+
+ !isMascara && h('div.open-in-browser', {
+ onClick: () => global.platform.openExtensionInBrowser(),
+ }, [h('img', { src: 'images/popout.svg' })]),
+
+ ]),
+
+ this.renderHeroBalance(),
+
+ h(TxList),
+
+ ])
+}
diff --git a/ui/app/components/wallet-content-display.js b/ui/app/components/wallet-content-display.js
new file mode 100644
index 000000000..bfa061be4
--- /dev/null
+++ b/ui/app/components/wallet-content-display.js
@@ -0,0 +1,56 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = WalletContentDisplay
+
+inherits(WalletContentDisplay, Component)
+function WalletContentDisplay () {
+ Component.call(this)
+}
+
+WalletContentDisplay.prototype.render = function () {
+ const { title, amount, fiatValue, active, style } = this.props
+
+ // TODO: Separate component: wallet-content-account
+ return h('div.flex-column', {
+ style: {
+ marginLeft: '1.3em',
+ alignItems: 'flex-start',
+ ...style,
+ },
+ }, [
+
+ h('span', {
+ style: {
+ fontSize: '1.1em',
+ },
+ }, title),
+
+ h('span', {
+ style: {
+ fontSize: '1.8em',
+ margin: '0.4em 0em',
+ },
+ }, amount),
+
+ h('span', {
+ style: {
+ fontSize: '1.3em',
+ },
+ }, fiatValue),
+
+ active && h('div', {
+ style: {
+ position: 'absolute',
+ marginLeft: '-1.3em',
+ height: '6em',
+ width: '0.3em',
+ background: '#D8D8D8', // $alto
+ },
+ }, [
+ ]),
+ ])
+
+}
+
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
new file mode 100644
index 000000000..34f27ca2a
--- /dev/null
+++ b/ui/app/components/wallet-view.js
@@ -0,0 +1,187 @@
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const classnames = require('classnames')
+const Identicon = require('./identicon')
+// const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns
+const Tooltip = require('./tooltip-v2.js')
+const copyToClipboard = require('copy-to-clipboard')
+const actions = require('../actions')
+const BalanceComponent = require('./balance-component')
+const TokenList = require('./token-list')
+const selectors = require('../selectors')
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(WalletView)
+
+function mapStateToProps (state) {
+
+ return {
+ network: state.metamask.network,
+ sidebarOpen: state.appState.sidebarOpen,
+ identities: state.metamask.identities,
+ accounts: state.metamask.accounts,
+ tokens: state.metamask.tokens,
+ keyrings: state.metamask.keyrings,
+ selectedAddress: selectors.getSelectedAddress(state),
+ selectedIdentity: selectors.getSelectedIdentity(state),
+ selectedAccount: selectors.getSelectedAccount(state),
+ selectedTokenAddress: state.metamask.selectedTokenAddress,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showSendPage: () => dispatch(actions.showSendPage()),
+ hideSidebar: () => dispatch(actions.hideSidebar()),
+ unsetSelectedToken: () => dispatch(actions.setSelectedToken()),
+ showAccountDetailModal: () => {
+ dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
+ },
+ showAddTokenPage: () => dispatch(actions.showAddTokenPage()),
+ }
+}
+
+inherits(WalletView, Component)
+function WalletView () {
+ Component.call(this)
+ this.state = {
+ hasCopied: false,
+ copyToClipboardPressed: false,
+ }
+}
+
+WalletView.prototype.renderWalletBalance = function () {
+ const {
+ selectedTokenAddress,
+ selectedAccount,
+ unsetSelectedToken,
+ hideSidebar,
+ sidebarOpen,
+ } = this.props
+
+ const selectedClass = selectedTokenAddress
+ ? ''
+ : 'wallet-balance-wrapper--active'
+ const className = `flex-column wallet-balance-wrapper ${selectedClass}`
+
+ return h('div', { className }, [
+ h('div.wallet-balance',
+ {
+ onClick: () => {
+ unsetSelectedToken()
+ selectedTokenAddress && sidebarOpen && hideSidebar()
+ },
+ },
+ [
+ h(BalanceComponent, {
+ balanceValue: selectedAccount ? selectedAccount.balance : '',
+ style: {},
+ }),
+ ]
+ ),
+ ])
+}
+
+WalletView.prototype.render = function () {
+ const {
+ responsiveDisplayClassname,
+ selectedAddress,
+ selectedIdentity,
+ keyrings,
+ showAccountDetailModal,
+ hideSidebar,
+ showAddTokenPage,
+ } = this.props
+ // temporary logs + fake extra wallets
+ // console.log('walletview, selectedAccount:', selectedAccount)
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(selectedAddress) ||
+ kr.accounts.includes(selectedIdentity.address)
+ })
+
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+
+ return h('div.wallet-view.flex-column' + (responsiveDisplayClassname || ''), {
+ style: {},
+ }, [
+
+ // TODO: Separate component: wallet account details
+ h('div.flex-column.wallet-view-account-details', {
+ style: {},
+ }, [
+ h('div.wallet-view__sidebar-close', {
+ onClick: hideSidebar,
+ }),
+
+ h('div.wallet-view__keyring-label', isLoose ? 'IMPORTED' : ''),
+
+ h('div.flex-column.flex-center.wallet-view__name-container', {
+ style: { margin: '0 auto' },
+ onClick: showAccountDetailModal,
+ }, [
+ h(Identicon, {
+ diameter: 54,
+ address: selectedAddress,
+ }),
+
+ h('span.account-name', {
+ style: {},
+ }, [
+ selectedIdentity.name,
+ ]),
+
+ h('button.btn-clear.wallet-view__details-button', 'DETAILS'),
+ ]),
+ ]),
+
+ h(Tooltip, {
+ position: 'bottom',
+ title: this.state.hasCopied ? 'Copied!' : 'Copy to clipboard',
+ wrapperClassName: 'wallet-view__tooltip',
+ }, [
+ h('button.wallet-view__address', {
+ className: classnames({
+ 'wallet-view__address__pressed': this.state.copyToClipboardPressed,
+ }),
+ onClick: () => {
+ copyToClipboard(selectedAddress)
+ this.setState({ hasCopied: true })
+ setTimeout(() => this.setState({ hasCopied: false }), 3000)
+ },
+ onMouseDown: () => {
+ this.setState({ copyToClipboardPressed: true })
+ },
+ onMouseUp: () => {
+ this.setState({ copyToClipboardPressed: false })
+ },
+ }, [
+ `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`,
+ h('i.fa.fa-clipboard', { style: { marginLeft: '8px' } }),
+ ]),
+ ]),
+
+ this.renderWalletBalance(),
+
+ h(TokenList),
+
+ h('button.btn-clear.wallet-view__add-token-button', {
+ onClick: () => {
+ showAddTokenPage()
+ hideSidebar()
+ },
+ }, 'Add Token'),
+ ])
+}
+
+// TODO: Extra wallets, for dev testing. Remove when PRing to master.
+// const extraWallet = h('div.flex-column.wallet-balance-wrapper', {}, [
+// h('div.wallet-balance', {}, [
+// h(BalanceComponent, {
+// balanceValue: selectedAccount.balance,
+// style: {},
+// }),
+// ]),
+// ])
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 9c8f98fa8..b4ffc48b7 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -3,17 +3,24 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
-const NetworkIndicator = require('./components/network')
-const LoadingIndicator = require('./components/loading')
const txHelper = require('../lib/tx-helper')
-const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
const PendingTx = require('./components/pending-tx')
-const PendingMsg = require('./components/pending-msg')
-const PendingPersonalMsg = require('./components/pending-personal-msg')
-const PendingTypedMsg = require('./components/pending-typed-msg')
+const SignatureRequest = require('./components/signature-request')
+// const PendingMsg = require('./components/pending-msg')
+// const PendingPersonalMsg = require('./components/pending-personal-msg')
+// const PendingTypedMsg = require('./components/pending-typed-msg')
const Loading = require('./components/loading')
+// const contentDivider = h('div', {
+// style: {
+// marginLeft: '16px',
+// marginRight: '16px',
+// height:'1px',
+// background:'#E7E7E7',
+// },
+// })
+
module.exports = connect(mapStateToProps)(ConfirmTxScreen)
function mapStateToProps (state) {
@@ -43,100 +50,70 @@ function ConfirmTxScreen () {
ConfirmTxScreen.prototype.render = function () {
const props = this.props
- const { network, provider, unapprovedTxs, currentCurrency, computedBalances,
- unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, conversionRate, blockGasLimit } = props
+ const {
+ network,
+ unapprovedTxs,
+ currentCurrency,
+ unapprovedMsgs,
+ unapprovedPersonalMsgs,
+ unapprovedTypedMessages,
+ conversionRate,
+ blockGasLimit,
+ // provider,
+ // computedBalances,
+ } = props
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network)
var txData = unconfTxList[props.index] || {}
var txParams = txData.params || {}
- var isNotification = isPopupOrNotification() === 'notification'
+
+ // var isNotification = isPopupOrNotification() === 'notification'
+ /*
+ Client is using the flag above to render the following in conf screen
+ // subtitle and nav
+ h('.section-title.flex-row.flex-center', [
+ !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
+ onClick: this.goHome.bind(this),
+ }) : null,
+ h('h2.page-subtitle', 'Confirm Transaction'),
+ isNotification ? h(NetworkIndicator, {
+ network: network,
+ provider: provider,
+ }) : null,
+ ]),
+ */
log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
- if (unconfTxList.length === 0) return h(Loading, { isLoading: true })
-
- const unconfTxListLength = unconfTxList.length
-
- return (
-
- h('.flex-column.flex-grow', [
-
- h(LoadingIndicator, {
- isLoading: this.state ? !this.state.bypassLoadingScreen : txData.loadingDefaults,
- loadingMessage: 'Estimating transaction cost…',
- canBypass: true,
- bypass: () => {
- this.setState({bypassLoadingScreen: true})
- },
- }),
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: this.goHome.bind(this),
- }) : null,
- h('h2.page-subtitle', 'Confirm Transaction'),
- isNotification ? h(NetworkIndicator, {
- network: network,
- provider: provider,
- }) : null,
- ]),
-
- h('h3', {
- style: {
- alignSelf: 'center',
- display: unconfTxList.length > 1 ? 'block' : 'none',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- style: {
- display: props.index === 0 ? 'none' : 'inline-block',
- },
- onClick: () => props.dispatch(actions.previousTx()),
- }),
- ` ${props.index + 1} of ${unconfTxList.length} `,
- h('i.fa.fa-arrow-right.fa-lg.cursor-pointer', {
- style: {
- display: props.index + 1 === unconfTxList.length ? 'none' : 'inline-block',
- },
- onClick: () => props.dispatch(actions.nextTx()),
- }),
- ]),
-
- warningIfExists(props.warning),
-
- currentTxView({
- // Properties
- txData: txData,
- key: txData.id,
- selectedAddress: props.selectedAddress,
- accounts: props.accounts,
- identities: props.identities,
- conversionRate,
- currentCurrency,
- blockGasLimit,
- unconfTxListLength,
- computedBalances,
- // Actions
- buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress),
- sendTransaction: this.sendTransaction.bind(this),
- cancelTransaction: this.cancelTransaction.bind(this, txData),
- cancelAllTransactions: this.cancelAllTransactions.bind(this, unconfTxList),
- signMessage: this.signMessage.bind(this, txData),
- signPersonalMessage: this.signPersonalMessage.bind(this, txData),
- signTypedMessage: this.signTypedMessage.bind(this, txData),
- cancelMessage: this.cancelMessage.bind(this, txData),
- cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
- cancelTypedMessage: this.cancelTypedMessage.bind(this, txData),
- }),
- ])
- )
+ if (unconfTxList.length === 0) return h(Loading)
+
+ return currentTxView({
+ // Properties
+ txData: txData,
+ key: txData.id,
+ selectedAddress: props.selectedAddress,
+ accounts: props.accounts,
+ identities: props.identities,
+ conversionRate,
+ currentCurrency,
+ blockGasLimit,
+ // Actions
+ buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress),
+ sendTransaction: this.sendTransaction.bind(this),
+ cancelTransaction: this.cancelTransaction.bind(this, txData),
+ signMessage: this.signMessage.bind(this, txData),
+ signPersonalMessage: this.signPersonalMessage.bind(this, txData),
+ signTypedMessage: this.signTypedMessage.bind(this, txData),
+ cancelMessage: this.cancelMessage.bind(this, txData),
+ cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
+ cancelTypedMessage: this.cancelTypedMessage.bind(this, txData),
+ })
}
function currentTxView (opts) {
log.info('rendering current tx view')
const { txData } = opts
- const { txParams, msgParams, type } = txData
+ const { txParams, msgParams } = txData
if (txParams) {
log.debug('txParams detected, rendering pending tx')
@@ -144,17 +121,20 @@ function currentTxView (opts) {
} else if (msgParams) {
log.debug('msgParams detected, rendering pending msg')
- if (type === 'eth_sign') {
- log.debug('rendering eth_sign message')
- return h(PendingMsg, opts)
- } else if (type === 'personal_sign') {
- log.debug('rendering personal_sign message')
- return h(PendingPersonalMsg, opts)
- } else if (type === 'eth_signTypedData') {
- log.debug('rendering eth_signTypedData message')
- return h(PendingTypedMsg, opts)
- }
+ return h(SignatureRequest, opts)
+
+ // if (type === 'eth_sign') {
+ // log.debug('rendering eth_sign message')
+ // return h(PendingMsg, opts)
+ // } else if (type === 'personal_sign') {
+ // log.debug('rendering personal_sign message')
+ // return h(PendingPersonalMsg, opts)
+ // } else if (type === 'eth_signTypedData') {
+ // log.debug('rendering eth_signTypedData message')
+ // return h(PendingTypedMsg, opts)
+ // }
}
+ return h(Loading)
}
ConfirmTxScreen.prototype.buyEth = function (address, event) {
@@ -232,14 +212,14 @@ ConfirmTxScreen.prototype.goHome = function (event) {
this.props.dispatch(actions.goHome())
}
-function warningIfExists (warning) {
- if (warning &&
- // Do not display user rejections on this screen:
- warning.indexOf('User denied transaction signature') === -1) {
- return h('.error', {
- style: {
- margin: 'auto',
- },
- }, warning)
- }
-}
+// function warningIfExists (warning) {
+// if (warning &&
+// // Do not display user rejections on this screen:
+// warning.indexOf('User denied transaction signature') === -1) {
+// return h('.error', {
+// style: {
+// margin: 'auto',
+// },
+// }, warning)
+// }
+// }
diff --git a/ui/app/conversion-util.js b/ui/app/conversion-util.js
new file mode 100644
index 000000000..ee42ebea1
--- /dev/null
+++ b/ui/app/conversion-util.js
@@ -0,0 +1,221 @@
+/* Currency Conversion Utility
+* This utility function can be used for converting currency related values within metamask.
+* The caller should be able to pass it a value, along with information about the value's
+* numeric base, denomination and currency, and the desired numeric base, denomination and
+* currency. It should return a single value.
+*
+* @param {(number | string | BN)} value The value to convert.
+* @param {Object} [options] Options to specify details of the conversion
+* @param {string} [options.fromCurrency = 'ETH' | 'USD'] The currency of the passed value
+* @param {string} [options.toCurrency = 'ETH' | 'USD'] The desired currency of the result
+* @param {string} [options.fromNumericBase = 'hex' | 'dec' | 'BN'] The numeric basic of the passed value.
+* @param {string} [options.toNumericBase = 'hex' | 'dec' | 'BN'] The desired numeric basic of the result.
+* @param {string} [options.fromDenomination = 'WEI'] The denomination of the passed value
+* @param {number} [options.numberOfDecimals] The desired number of in the result
+* @param {number} [options.conversionRate] The rate to use to make the fromCurrency -> toCurrency conversion
+* @returns {(number | string | BN)}
+*
+* The utility passes value along with the options as a single object to the `converter` function.
+* `converter` uses Ramda.js to apply a composition of conditional setters to the `value` property, depending
+* on the accompanying options. Some of these conditional setters are selected via key-value maps, where
+* the keys are specified in the options parameters and the values are setter functions.
+*/
+
+const BigNumber = require('bignumber.js')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const R = require('ramda')
+const { stripHexPrefix } = require('ethereumjs-util')
+
+BigNumber.config({
+ ROUNDING_MODE: BigNumber.ROUND_HALF_DOWN,
+})
+
+// Big Number Constants
+const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000')
+const BIG_NUMBER_GWEI_MULTIPLIER = new BigNumber('1000000000')
+
+// Individual Setters
+const convert = R.invoker(1, 'times')
+const round = R.invoker(2, 'round')(R.__, BigNumber.ROUND_HALF_DOWN)
+const invertConversionRate = conversionRate => () => new BigNumber(1.0).div(conversionRate)
+const decToBigNumberViaString = n => R.pipe(String, toBigNumber['dec'])
+
+// Setter Maps
+const toBigNumber = {
+ hex: n => new BigNumber(stripHexPrefix(n), 16),
+ dec: n => new BigNumber(n, 10),
+ BN: n => new BigNumber(n.toString(16), 16),
+}
+const toNormalizedDenomination = {
+ WEI: bigNumber => bigNumber.div(BIG_NUMBER_WEI_MULTIPLIER),
+ GWEI: bigNumber => bigNumber.div(BIG_NUMBER_GWEI_MULTIPLIER),
+}
+const toSpecifiedDenomination = {
+ WEI: bigNumber => bigNumber.times(BIG_NUMBER_WEI_MULTIPLIER).round(),
+ GWEI: bigNumber => bigNumber.times(BIG_NUMBER_GWEI_MULTIPLIER).round(9),
+}
+const baseChange = {
+ hex: n => n.toString(16),
+ dec: n => Number(n).toString(10),
+ BN: n => new BN(n.toString(16)),
+}
+
+// Predicates
+const fromAndToCurrencyPropsNotEqual = R.compose(
+ R.not,
+ R.eqBy(R.__, 'fromCurrency', 'toCurrency'),
+ R.flip(R.prop)
+)
+
+// Lens
+const valuePropertyLens = R.over(R.lensProp('value'))
+const conversionRateLens = R.over(R.lensProp('conversionRate'))
+
+// conditional conversionRate setting wrapper
+const whenPredSetCRWithPropAndSetter = (pred, prop, setter) => R.when(
+ pred,
+ R.converge(
+ conversionRateLens,
+ [R.pipe(R.prop(prop), setter), R.identity]
+ )
+)
+
+// conditional 'value' setting wrappers
+const whenPredSetWithPropAndSetter = (pred, prop, setter) => R.when(
+ pred,
+ R.converge(
+ valuePropertyLens,
+ [R.pipe(R.prop(prop), setter), R.identity]
+ )
+)
+const whenPropApplySetterMap = (prop, setterMap) => whenPredSetWithPropAndSetter(
+ R.prop(prop),
+ prop,
+ R.prop(R.__, setterMap)
+)
+
+// Conversion utility function
+const converter = R.pipe(
+ whenPredSetCRWithPropAndSetter(R.prop('conversionRate'), 'conversionRate', decToBigNumberViaString),
+ whenPredSetCRWithPropAndSetter(R.prop('invertConversionRate'), 'conversionRate', invertConversionRate),
+ whenPropApplySetterMap('fromNumericBase', toBigNumber),
+ whenPropApplySetterMap('fromDenomination', toNormalizedDenomination),
+ whenPredSetWithPropAndSetter(fromAndToCurrencyPropsNotEqual, 'conversionRate', convert),
+ whenPropApplySetterMap('toDenomination', toSpecifiedDenomination),
+ whenPredSetWithPropAndSetter(R.prop('numberOfDecimals'), 'numberOfDecimals', round),
+ whenPropApplySetterMap('toNumericBase', baseChange),
+ R.view(R.lensProp('value'))
+)
+
+const conversionUtil = (value, {
+ fromCurrency = null,
+ toCurrency = fromCurrency,
+ fromNumericBase,
+ toNumericBase,
+ fromDenomination,
+ toDenomination,
+ numberOfDecimals,
+ conversionRate,
+ invertConversionRate,
+}) => converter({
+ fromCurrency,
+ toCurrency,
+ fromNumericBase,
+ toNumericBase,
+ fromDenomination,
+ toDenomination,
+ numberOfDecimals,
+ conversionRate,
+ invertConversionRate,
+ value: value || '0',
+})
+
+const addCurrencies = (a, b, options = {}) => {
+ const {
+ aBase,
+ bBase,
+ ...conversionOptions
+ } = options
+ const value = (new BigNumber(a, aBase)).add(b, bBase)
+
+ return converter({
+ value,
+ ...conversionOptions,
+ })
+}
+
+const subtractCurrencies = (a, b, options = {}) => {
+ const {
+ aBase,
+ bBase,
+ ...conversionOptions
+ } = options
+ const value = (new BigNumber(a, aBase)).minus(b, bBase)
+
+ return converter({
+ value,
+ ...conversionOptions,
+ })
+}
+
+const multiplyCurrencies = (a, b, options = {}) => {
+ const {
+ multiplicandBase,
+ multiplierBase,
+ ...conversionOptions
+ } = options
+
+ const bigNumberA = new BigNumber(String(a), multiplicandBase)
+ const bigNumberB = new BigNumber(String(b), multiplierBase)
+
+ const value = bigNumberA.times(bigNumberB)
+
+ return converter({
+ value,
+ ...conversionOptions,
+ })
+}
+
+const conversionGreaterThan = (
+ { ...firstProps },
+ { ...secondProps },
+) => {
+ const firstValue = converter({ ...firstProps })
+ const secondValue = converter({ ...secondProps })
+
+ return firstValue.gt(secondValue)
+}
+
+const conversionGTE = (
+ { ...firstProps },
+ { ...secondProps },
+) => {
+ const firstValue = converter({ ...firstProps })
+ const secondValue = converter({ ...secondProps })
+ return firstValue.greaterThanOrEqualTo(secondValue)
+}
+
+const conversionLTE = (
+ { ...firstProps },
+ { ...secondProps },
+) => {
+ const firstValue = converter({ ...firstProps })
+ const secondValue = converter({ ...secondProps })
+ return firstValue.lessThanOrEqualTo(secondValue)
+}
+
+const toNegative = (n, options = {}) => {
+ return multiplyCurrencies(n, -1, options)
+}
+
+module.exports = {
+ conversionUtil,
+ addCurrencies,
+ multiplyCurrencies,
+ conversionGreaterThan,
+ conversionGTE,
+ conversionLTE,
+ toNegative,
+ subtractCurrencies,
+}
diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss
new file mode 100644
index 000000000..445c819ff
--- /dev/null
+++ b/ui/app/css/index.scss
@@ -0,0 +1,14 @@
+/*
+ ITCSS
+
+ http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
+ https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
+ */
+
+@import './itcss/settings/index.scss';
+@import './itcss/tools/index.scss';
+@import './itcss/generic/index.scss';
+@import './itcss/base/index.scss';
+@import './itcss/objects/index.scss';
+@import './itcss/components/index.scss';
+@import './itcss/trumps/index.scss';
diff --git a/ui/app/css/itcss/base/index.scss b/ui/app/css/itcss/base/index.scss
new file mode 100644
index 000000000..1475e8bb5
--- /dev/null
+++ b/ui/app/css/itcss/base/index.scss
@@ -0,0 +1,7 @@
+// Base
+
+.mouse-user-styles {
+ button:focus {
+ outline: 0;
+ }
+}
diff --git a/ui/app/css/itcss/components/account-dropdown-mini.scss b/ui/app/css/itcss/components/account-dropdown-mini.scss
new file mode 100644
index 000000000..996993db7
--- /dev/null
+++ b/ui/app/css/itcss/components/account-dropdown-mini.scss
@@ -0,0 +1,48 @@
+.account-dropdown-mini {
+ height: 22px;
+ background-color: $white;
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ width: 124px;
+
+ &__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%;
+ }
+
+ &__list {
+ z-index: 1050;
+ position: absolute;
+ height: 180px;
+ width: 96pxpx;
+ border: 1px solid $geyser;
+ border-radius: 4px;
+ background-color: $white;
+ box-shadow: 0 3px 6px 0 rgba(0 ,0 ,0 ,.11);
+ overflow-y: scroll;
+ }
+
+ .account-list-item {
+ margin-top: 6px;
+ }
+
+ .account-list-item__account-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ width: 80px;
+ }
+
+ .account-list-item__top-row {
+ margin: 0;
+ }
+
+ .account-list-item__icon {
+ position: initial;
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/account-dropdown.scss b/ui/app/css/itcss/components/account-dropdown.scss
new file mode 100644
index 000000000..725da9d39
--- /dev/null
+++ b/ui/app/css/itcss/components/account-dropdown.scss
@@ -0,0 +1,83 @@
+.account-dropdown-name {
+ font-family: Roboto;
+}
+
+.account-dropdown-balance {
+ color: $dusty-gray;
+ line-height: 19px;
+}
+
+.account-dropdown-edit-button {
+ color: $dusty-gray;
+ font-family: Roboto;
+
+ &:hover {
+ color: $white;
+ }
+}
+
+.account-list-item {
+ &__top-row {
+ display: flex;
+ margin-top: 10px;
+ margin-left: 8px;
+ position: relative;
+ }
+
+ &__account-balances {
+ height: auto;
+ border: none;
+ background-color: transparent;
+ color: #9b9b9b;
+ margin-left: 34px;
+ margin-top: 4px;
+ position: relative;
+ }
+
+ &__account-name {
+ font-size: 16px;
+ margin-left: 8px;
+ }
+
+ &__icon {
+ position: absolute;
+ right: 12px;
+ top: 1px;
+ }
+
+ &__account-primary-balance,
+ &__account-secondary-balance {
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ font-weight: 300;
+ }
+
+ &__account-primary-balance {
+ color: $scorpion;
+ border: none;
+ outline: 0 !important;
+ }
+
+ &__account-secondary-balance {
+ color: $dusty-gray;
+ }
+
+ &__account-address {
+ margin-left: 35px;
+ width: 80%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ &__dropdown {
+ &:hover {
+ background: rgba($alto, .2);
+ cursor: pointer;
+
+ input {
+ background: rgba($alto, .1);
+ }
+ }
+ }
+}
diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss
new file mode 100644
index 000000000..8ad7481c7
--- /dev/null
+++ b/ui/app/css/itcss/components/account-menu.scss
@@ -0,0 +1,132 @@
+.account-menu {
+ position: fixed;
+ z-index: 100;
+ top: 58px;
+ width: 310px;
+
+ @media screen and (max-width: 575px) {
+ right: calc(((100vw - 100%) / 2) + 8px);
+ }
+
+ @media screen and (min-width: 576px) {
+ right: calc((100vw - 85vw) / 2);
+ }
+
+ @media screen and (min-width: 769px) {
+ right: calc((100vw - 80vw) / 2);
+ }
+
+ @media screen and (min-width: 1281px) {
+ right: calc((100vw - 65vw) / 2);
+ }
+
+ &__icon {
+ margin-left: 20px;
+ cursor: pointer;
+ }
+
+ &__header {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ &__logout-button {
+ border: 1px solid $dusty-gray;
+ background-color: transparent;
+ color: $white;
+ border-radius: 4px;
+ font-size: 12px;
+ line-height: 23px;
+ padding: 0 24px;
+ font-weight: 300;
+ }
+
+ &__item-icon {
+ width: 16px;
+ height: 16px;
+ }
+
+ &__accounts {
+ display: flex;
+ flex-flow: column nowrap;
+ overflow-y: auto;
+ max-height: 240px;
+ position: relative;
+ z-index: 200;
+
+ &::-webkit-scrollbar {
+ display: none;
+ }
+
+ @media screen and (max-width: 575px) {
+ max-height: 215px;
+ }
+
+ .keyring-label {
+ margin-top: 5px;
+ background-color: $black;
+ color: $dusty-gray;
+ }
+ }
+
+ &__account {
+ display: flex;
+ flex-flow: row nowrap;
+ padding: 16px 14px;
+ flex: 0 0 auto;
+
+ @media screen and (max-width: 575px) {
+ padding: 12px 14px;
+ }
+ }
+
+ &__account-info {
+ flex: 1 0 auto;
+ display: flex;
+ flex-flow: column nowrap;
+ padding-top: 4px;
+ }
+
+ &__check-mark {
+ width: 14px;
+ margin-right: 12px;
+ flex: 0 0 auto;
+ }
+
+ &__check-mark-icon {
+ background-image: url("images/check-white.svg");
+ height: 18px;
+ width: 18px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ margin: 3px 0;
+ }
+
+ .identicon {
+ margin: 0 12px 0 0;
+ flex: 0 0 auto;
+ }
+
+ &__name {
+ color: $white;
+ font-size: 18px;
+ font-weight: 300;
+ line-height: 16px;
+ }
+
+ &__balance {
+ color: $dusty-gray;
+ font-size: 14px;
+ line-height: 19px;
+ }
+
+ &__action {
+ font-size: 16px;
+ line-height: 18px;
+ font-weight: 300;
+ cursor: pointer;
+ }
+}
diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss
new file mode 100644
index 000000000..13020f62f
--- /dev/null
+++ b/ui/app/css/itcss/components/add-token.scss
@@ -0,0 +1,343 @@
+.add-token {
+ width: 498px;
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ position: relative;
+ z-index: 12;
+ font-family: 'DIN Next Light';
+
+ &__wrapper {
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba($black, .08);
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ flex: 0 0 auto;
+ }
+
+ &__title-container {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ padding: 30px 60px 12px;
+ border-bottom: 1px solid $gallery;
+ flex: 0 0 auto;
+ }
+
+ &__title {
+ color: $scorpion;
+ font-size: 20px;
+ line-height: 26px;
+ text-align: center;
+ font-weight: 600;
+ margin-bottom: 12px;
+ }
+
+ &__description {
+ text-align: center;
+ }
+
+ &__description + &__description {
+ margin-top: 24px;
+ }
+
+ &__confirmation-description {
+ margin: 12px 0;
+ }
+
+ &__content-container {
+ width: 100%;
+ border-bottom: 1px solid $gallery;
+ }
+
+ &__input-container {
+ padding: 11px 0;
+ width: 263px;
+ margin: 0 auto;
+ position: relative;
+ }
+
+ &__search-input-error-message {
+ position: absolute;
+ bottom: -10px;
+ font-size: 12px;
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ color: $red;
+ }
+
+ &__input {
+ width: 100%;
+ border: 2px solid $gallery;
+ border-radius: 4px;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px;
+
+ &::placeholder {
+ color: $silver;
+ }
+ }
+
+ &__footers {
+ width: 100%;
+ }
+
+ &__add-custom {
+ color: $scorpion;
+ font-size: 18px;
+ line-height: 24px;
+ text-align: center;
+ padding: 12px 0;
+ font-weight: 600;
+ cursor: pointer;
+ position: relative;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, .05);
+ }
+
+ &:active {
+ background-color: rgba(0, 0, 0, .1);
+ }
+
+ .fa {
+ position: absolute;
+ right: 24px;
+ font-size: 24px;
+ line-height: 24px;
+ }
+ }
+
+ &__add-custom-form {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 8px 0 51px;
+ }
+
+ &__add-custom-field {
+ width: 290px;
+ margin: 0 auto;
+ position: relative;
+
+ &--error {
+ .add-token__add-custom-input {
+ border-color: $red;
+ }
+ }
+ }
+
+ &__add-custom-error-message {
+ position: absolute;
+ bottom: -21px;
+ font-size: 12px;
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ color: $red;
+ }
+
+ &__add-custom-label {
+ font-size: 16px;
+ line-height: 21px;
+ margin-bottom: 8px;
+ }
+
+ &__add-custom-input {
+ width: 100%;
+ border: 1px solid $silver;
+ padding: 5px 15px;
+ font-size: 14px;
+ line-height: 19px;
+
+ &::placeholder {
+ color: $silver;
+ }
+ }
+
+ &__add-custom-field + &__add-custom-field {
+ margin-top: 21px;
+ }
+
+ &__buttons {
+ display: flex;
+ flex-flow: row nowrap;
+ margin: 30px 0 51px;
+ flex: 0 0 auto;
+ align-items: center;
+ justify-content: center;
+ }
+
+ &__button {
+ flex: 1 0 141px;
+ margin: 0 12px;
+ padding: 10px 22px;
+ height: 54px;
+ }
+
+ &__token-icons-container {
+ display: flex;
+ flex-flow: row wrap;
+ }
+
+ &__token-wrapper {
+ transition: 200ms ease-in-out;
+ display: flex;
+ flex-flow: row nowrap;
+ flex: 0 0 42.5%;
+ align-items: center;
+ padding: 12px;
+ margin: 2.5%;
+ box-sizing: border-box;
+ border-radius: 10px;
+ cursor: pointer;
+ border: 2px solid transparent;
+ position: relative;
+
+ &:hover {
+ border: 2px solid rgba($malibu-blue, .5);
+ }
+
+ &--selected {
+ border: 2px solid $malibu-blue !important;
+ }
+
+ &--disabled {
+ opacity: .4;
+ pointer-events: none;
+ }
+ }
+
+ &__token-data {
+ align-self: flex-start;
+ }
+
+ &__token-name {
+ font-size: 14px;
+ line-height: 19px;
+ }
+
+ &__token-symbol {
+ font-size: 22px;
+ line-height: 29px;
+ font-weight: 600;
+ }
+
+ &__token-icon {
+ width: 60px;
+ height: 60px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+ border-radius: 50%;
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba($black, .24);
+ margin-right: 12px;
+ flex: 0 0 auto;
+ }
+
+ &__token-message {
+ position: absolute;
+ color: $caribbean-green;
+ font-size: 11px;
+ bottom: 0;
+ left: 85px;
+ }
+
+ &__confirmation-token-list {
+ display: flex;
+ flex-flow: column nowrap;
+
+ .token-balance {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: flex-start;
+
+ &__amount {
+ color: $scorpion;
+ font-size: 43px;
+ font-weight: 300;
+ line-height: 43px;
+ margin-right: 8px;
+ }
+
+ &__symbol {
+ color: $scorpion;
+ font-size: 16px;
+ line-height: 24px;
+ }
+ }
+ }
+
+ &__confirmation-title {
+ padding: 30px 120px 12px;
+
+ @media screen and (max-width: $break-small) {
+ padding: 20px 0;
+ width: 100%;
+ }
+ }
+
+ &__confirmation-content {
+ padding-bottom: 60px;
+ }
+
+ &__confirmation-token-list-item {
+ display: flex;
+ flex-flow: row nowrap;
+ margin: 0 auto;
+ align-items: center;
+ }
+
+ &__confirmation-token-list-item + &__confirmation-token-list-item {
+ margin-top: 30px;
+ }
+
+ &__confirmation-token-icon {
+ margin-right: 18px;
+ }
+
+ @media screen and (max-width: $break-small) {
+ top: 0;
+ width: 100%;
+ overflow: hidden;
+ height: 100%;
+
+ &__wrapper {
+ box-shadow: none !important;
+ flex: 1 1 auto;
+ width: 100%;
+ overflow-y: auto;
+ }
+
+ &__footers {
+ border-bottom: 1px solid $gallery;
+ }
+
+ &__token-icon {
+ width: 50px;
+ height: 50px;
+ }
+
+ &__token-symbol {
+ font-size: 18px;
+ line-height: 24px;
+ }
+
+ &__token-name {
+ font-size: 12px;
+ line-height: 16px;
+ }
+
+ &__buttons {
+ padding: 12px 0;
+ margin: 0;
+ border-top: 1px solid $gallery;
+ width: 100%;
+ }
+ }
+}
diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss
new file mode 100644
index 000000000..1450b71cc
--- /dev/null
+++ b/ui/app/css/itcss/components/buttons.scss
@@ -0,0 +1,142 @@
+/*
+ Buttons
+ */
+
+.btn-green {
+ background-color: #02c9b1; // TODO: reusable color in colors.css
+}
+
+.btn-clear {
+ background: $white;
+ text-align: center;
+ padding: .8rem 1rem;
+ color: $curious-blue;
+ border: 2px solid $spindle;
+ border-radius: 4px;
+ font-size: .85rem;
+ font-weight: 400;
+ transition: border-color .3s ease;
+
+ &:hover {
+ border-color: $curious-blue;
+ }
+
+ &--disabled,
+ &[disabled] {
+ cursor: auto;
+ opacity: .5;
+ pointer-events: none;
+ }
+}
+
+.btn-cancel {
+ background: $white;
+ text-align: center;
+ padding: .9rem 1rem;
+ color: $scorpion;
+ border: 2px solid $dusty-gray;
+ border-radius: 4px;
+ font-size: .85rem;
+ font-weight: 400;
+ transition: border-color .3s ease;
+
+ &:hover {
+ border-color: $scorpion;
+ }
+}
+
+// No longer used in flat design, remove when modal buttons done
+// div.wallet-btn {
+// border: 1px solid rgb(91, 93, 103);
+// border-radius: 2px;
+// height: 30px;
+// width: 75px;
+// font-size: 0.8em;
+// text-align: center;
+// line-height: 25px;
+// }
+
+// .btn-red {
+// background: rgba(254, 35, 17, 1);
+// box-shadow: 0px 3px 6px rgba(254, 35, 17, 0.36);
+// }
+
+button[disabled],
+input[type="submit"][disabled] {
+ cursor: not-allowed;
+ opacity: .5;
+ // background: rgba(197, 197, 197, 1);
+ // box-shadow: 0 3px 6px rgba(197, 197, 197, .36);
+}
+
+// button.spaced {
+// margin: 2px;
+// }
+
+// button:not([disabled]):hover, input[type="submit"]:not([disabled]):hover {
+// transform: scale(1.1);
+// }
+// button:not([disabled]):active, input[type="submit"]:not([disabled]):active {
+// transform: scale(0.95);
+// }
+
+button.primary {
+ padding: 8px 12px;
+ background: #f7861c;
+ box-shadow: 0 3px 6px rgba(247, 134, 28, .36);
+ color: $white;
+ font-size: 1.1em;
+ font-family: Roboto;
+ text-transform: uppercase;
+}
+
+.btn-light {
+ padding: 8px 12px;
+ // background: #FFFFFF; // $bg-white
+ box-shadow: 0 3px 6px rgba(247, 134, 28, .36);
+ color: #585d67; // TODO: make reusable light button color
+ font-size: 1.1em;
+ font-family: Roboto;
+ text-transform: uppercase;
+ text-align: center;
+ line-height: 20px;
+ border-radius: 2px;
+ border: 1px solid #979797; // #TODO: make reusable light border color
+ opacity: .5;
+}
+
+// TODO: cleanup: not used anywhere
+button.btn-thin {
+ border: 1px solid;
+ border-color: #4d4d4d;
+ color: #4d4d4d;
+ background: rgb(255, 174, 41);
+ border-radius: 4px;
+ min-width: 200px;
+ margin: 12px 0;
+ padding: 6px;
+ font-size: 13px;
+}
+
+.btn-secondary {
+ border: 1px solid #979797;
+ border-radius: 2px;
+ background-color: $white;
+ font-size: 16px;
+ line-height: 24px;
+ padding: 16px 42px;
+
+ &[disabled] {
+ background-color: $white !important;
+ opacity: .5;
+ }
+}
+
+.btn-tertiary {
+ border: 1px solid transparent;
+ border-radius: 2px;
+ background-color: transparent;
+ font-size: 16px;
+ line-height: 24px;
+ padding: 16px 42px;
+}
diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss
new file mode 100644
index 000000000..878495290
--- /dev/null
+++ b/ui/app/css/itcss/components/confirm.scss
@@ -0,0 +1,324 @@
+.confirm-screen-container {
+ position: relative;
+ align-items: center;
+ font-family: Roboto;
+ flex: 1 0 auto;
+ flex-flow: column nowrap;
+ box-shadow: 0 2px 4px 0 rgba($black, .08);
+ border-radius: 8px;
+ display: flex;
+
+ @media screen and (max-width: 575px) {
+ width: 100%;
+ box-shadow: initial;
+ }
+
+ @media screen and (min-width: 576px) {
+ // top: -26px;
+ }
+}
+
+.notification {
+ .confirm-screen-wrapper {
+
+ @media screen and (max-width: $break-small) {
+ height: calc(100vh - 85px);
+ }
+ }
+}
+
+.confirm-screen-wrapper {
+ height: 100%;
+ width: 380px;
+ background-color: $white;
+ display: flex;
+ flex-flow: column nowrap;
+ z-index: 25;
+ align-items: center;
+ font-family: Roboto;
+ position: relative;
+ overflow-y: auto;
+ overflow-x: hidden;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px;
+
+ @media screen and (max-width: $break-small) {
+ width: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ top: 0;
+ box-shadow: none;
+ height: calc(100vh - 58px - 85px);
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+}
+
+.confirm-screen-wrapper > .confirm-screen-total-box {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.confirm-screen-wrapper > .confirm-memo-wrapper {
+ margin: 0;
+}
+
+.confirm-screen-header {
+ height: 88px;
+ background-color: $athens-grey;
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 22px;
+ line-height: 29px;
+ width: 100%;
+ padding: 25px 0;
+ flex: 0 0 auto;
+
+ @media screen and (max-width: $break-small) {
+ font-size: 20px;
+ }
+}
+
+.confirm-screen-header-tip {
+ height: 25px;
+ width: 25px;
+ background: $athens-grey;
+ position: absolute;
+ transform: rotate(45deg);
+ top: 71px;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+}
+
+.confirm-screen-title {
+ line-height: 27px;
+
+ @media screen and (max-width: $break-small) {
+ margin-left: 22px;
+ margin-right: 8px;
+ }
+}
+
+.confirm-screen-back-button {
+ color: $curious-blue;
+ font-family: Roboto;
+ font-size: 1rem;
+ position: absolute;
+ top: 38px;
+ right: 38px;
+ background: none;
+}
+
+.confirm-screen-account-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.confirm-screen-account-name {
+ margin-top: 12px;
+ font-size: 14px;
+ line-height: 19px;
+ color: $scorpion;
+ text-align: center;
+}
+
+.confirm-screen-row-info {
+ font-size: 16px;
+ line-height: 21px;
+}
+
+.confirm-screen-account-number {
+ font-size: 10px;
+ line-height: 16px;
+ color: $dusty-gray;
+ text-align: center;
+ height: 16px;
+}
+
+.confirm-send-ether,
+.confirm-send-token {
+ i.fa-arrow-right {
+ align-self: start;
+ margin: 24px 14px 0 !important;
+ }
+}
+
+.confirm-screen-identicons {
+ margin-top: 24px;
+ flex: 0 0 auto;
+
+ i.fa-arrow-right {
+ align-self: start;
+ margin: 42px 14px 0;
+ }
+
+ i.fa-file-text-o {
+ font-size: 60px;
+ margin: 16px 8px 0 8px;
+ text-align: center;
+ }
+}
+
+.confirm-screen-sending-to-message {
+ text-align: center;
+ font-size: 16px;
+ margin-top: 30px;
+ font-family: 'DIN NEXT Light';
+}
+
+.confirm-screen-send-amount {
+ color: $scorpion;
+ margin-top: 12px;
+ text-align: center;
+ font-size: 40px;
+ font-weight: 300;
+ line-height: 53px;
+ flex: 0 0 auto;
+}
+
+.confirm-screen-send-amount-currency {
+ font-size: 20px;
+ line-height: 20px;
+ text-align: center;
+ flex: 0 0 auto;
+}
+
+.confirm-memo-wrapper {
+ min-height: 24px;
+ width: 100%;
+ border-bottom: 1px solid $alto;
+ flex: 0 0 auto;
+}
+
+.confirm-screen-send-memo {
+ color: $scorpion;
+ font-size: 16px;
+ line-height: 19px;
+ font-weight: 400;
+}
+
+.confirm-screen-label {
+ font-size: 18px;
+ line-height: 40px;
+ color: $scorpion;
+ text-align: left;
+}
+
+section .confirm-screen-account-name,
+section .confirm-screen-account-number,
+.confirm-screen-row-info,
+.confirm-screen-row-detail {
+ text-align: left;
+}
+
+.confirm-screen-rows {
+ display: flex;
+ flex-flow: column nowrap;
+ width: 100%;
+ flex: 0 0 auto;
+}
+
+.confirm-screen-section-column {
+ flex: .5;
+}
+
+.confirm-screen-row {
+ display: flex;
+ flex-flow: row nowrap;
+ border-bottom: 1px solid $alto;
+ width: 100%;
+ align-items: center;
+ padding: 12px;
+ padding-left: 35px;
+ font-size: 16px;
+ line-height: 22px;
+ font-weight: 300;
+}
+
+.confirm-screen-row-detail {
+ font-size: 12px;
+ line-height: 16px;
+ color: $dusty-gray;
+}
+
+.confirm-screen-total-box {
+ background-color: $wild-sand;
+ padding: 20px;
+ padding-left: 35px;
+ border-bottom: 1px solid $alto;
+
+ .confirm-screen-label {
+ line-height: 18px;
+ }
+
+ .confirm-screen-row-detail {
+ color: $scorpion;
+ }
+
+ &__subtitle {
+ font-size: 12px;
+ line-height: 22px;
+ }
+
+ .confirm-screen-row-info {
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 21px;
+ }
+}
+
+.confirm-screen-confirm-button {
+ height: 50px;
+ border-radius: 4px;
+ background-color: #02c9b1;
+ font-size: 16px;
+ color: $white;
+ text-align: center;
+ font-family: Roboto;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ border-width: 0;
+ box-shadow: none;
+ flex: 1 0 auto;
+ font-weight: 300;
+ margin: 0 5px;
+}
+
+.btn-light.confirm-screen-cancel-button {
+ height: 50px;
+ background: none;
+ border: none;
+ opacity: 1;
+ font-family: Roboto;
+ border-width: 0;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ font-size: 16px;
+ box-shadow: none;
+ cursor: pointer;
+ flex: 1 0 auto;
+ font-weight: 300;
+ margin: 0 5px;
+}
+
+#pending-tx-form {
+ flex: 1 0 auto;
+ position: relative;
+ display: flex;
+ flex-flow: row nowrap;
+ background-color: $white;
+ padding: 12px;
+ border-bottom-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ width: 100%;
+
+ @media screen and (max-width: $break-small) {
+ border-top: 1px solid $alto;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+}
diff --git a/ui/app/css/itcss/components/currency-display.scss b/ui/app/css/itcss/components/currency-display.scss
new file mode 100644
index 000000000..e043c1966
--- /dev/null
+++ b/ui/app/css/itcss/components/currency-display.scss
@@ -0,0 +1,57 @@
+.currency-display {
+ height: 54px;
+ width: 100%ß;
+ border: 1px solid $alto;
+ border-radius: 4px;
+ background-color: $white;
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: 300;
+ padding: 8px 10px;
+ position: relative;
+
+ &__primary-row {
+ display: flex;
+ }
+
+ &__input {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ border: none;
+ outline: 0 !important;
+ max-width: 100%;
+ }
+
+ &__primary-currency {
+ color: $scorpion;
+ font-weight: 400;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ }
+
+ &__converted-row {
+ display: flex;
+ }
+
+ &__converted-value,
+ &__converted-currency {
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 12px;
+ line-height: 12px;
+ }
+
+ &__input-wrapper {
+ position: relative;
+ display: flex;
+ }
+
+ &__currency-symbol {
+ margin-top: 1px;
+ color: $scorpion;
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/editable-label.scss b/ui/app/css/itcss/components/editable-label.scss
new file mode 100644
index 000000000..c69ea1428
--- /dev/null
+++ b/ui/app/css/itcss/components/editable-label.scss
@@ -0,0 +1,35 @@
+.editable-label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+
+ &__value {
+ max-width: 250px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ &__input {
+ width: 250px;
+ font-size: 14px;
+ text-align: center;
+ border: 1px solid $alto;
+
+ &--error {
+ border: 1px solid $monzo;
+ }
+ }
+
+ &__icon-wrapper {
+ position: absolute;
+ margin-left: 10px;
+ left: 100%;
+ }
+
+ &__icon {
+ cursor: pointer;
+ color: $dusty-gray;
+ }
+}
diff --git a/ui/app/css/itcss/components/footer.scss b/ui/app/css/itcss/components/footer.scss
new file mode 100644
index 000000000..000a53eed
--- /dev/null
+++ b/ui/app/css/itcss/components/footer.scss
@@ -0,0 +1,4 @@
+.app-footer {
+ padding-bottom: 10px;
+ align-items: center;
+}
diff --git a/ui/app/css/itcss/components/gas-slider.scss b/ui/app/css/itcss/components/gas-slider.scss
new file mode 100644
index 000000000..c27a560bd
--- /dev/null
+++ b/ui/app/css/itcss/components/gas-slider.scss
@@ -0,0 +1,51 @@
+.gas-slider {
+ position: relative;
+ width: 313px;
+
+ &__input {
+ width: 317px;
+ margin-left: -2px;
+ z-index: 2;
+ }
+
+ input[type=range] {
+ -webkit-appearance: none !important;
+ }
+
+ input[type=range]::-webkit-slider-thumb {
+ -webkit-appearance: none !important;
+ height: 26px;
+ width: 26px;
+ border: 2px solid #B8B8B8;
+ background-color: #FFFFFF;
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08);
+ border-radius: 50%;
+ position: relative;
+ z-index: 10;
+ }
+
+ &__bar {
+ height: 6px;
+ width: 313px;
+ background: $alto;
+ display: flex;
+ justify-content: space-between;
+ position: absolute;
+ top: 11px;
+ z-index: 0;
+ }
+
+ &__low, &__high {
+ height: 6px;
+ width: 49px;
+ z-index: 1;
+ }
+
+ &__low {
+ background-color: $crimson;
+ }
+
+ &__high {
+ background-color: $caribbean-green;
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/header.scss b/ui/app/css/itcss/components/header.scss
new file mode 100644
index 000000000..ac2cecf7e
--- /dev/null
+++ b/ui/app/css/itcss/components/header.scss
@@ -0,0 +1,107 @@
+.app-header {
+ align-items: center;
+ visibility: visible;
+ background: $gallery;
+ position: relative;
+ z-index: $header-z-index;
+ display: flex;
+ flex-flow: column nowrap;
+
+ @media screen and (max-width: 575px) {
+ padding: 12px;
+ width: 100%;
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, .08);
+ z-index: $mobile-header-z-index;
+ }
+
+ @media screen and (min-width: 576px) {
+ height: 75px;
+ justify-content: center;
+ }
+
+ .metafox-icon {
+ cursor: pointer;
+ }
+}
+
+.app-header--initialized {
+
+ @media screen and (min-width: 576px) {
+ &::after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ height: 32px;
+ background: $gallery;
+ bottom: -32px;
+ }
+ }
+}
+
+.app-header-contents {
+ display: flex;
+ justify-content: space-between;
+ flex-flow: row nowrap;
+ width: 100%;
+ height: 6.9vh;
+
+ @media screen and (max-width: 575px) {
+ height: 100%;
+ }
+
+ @media screen and (min-width: 576px) {
+ width: 85vw;
+ }
+
+ @media screen and (min-width: 769px) {
+ width: 80vw;
+ }
+
+ @media screen and (min-width: 1281px) {
+ width: 62vw;
+ }
+}
+
+.app-header h1 {
+ font-family: Roboto;
+ text-transform: uppercase;
+ font-weight: 400;
+ font-size: 1.1rem;
+ position: relative;
+ padding-left: 15px;
+ color: #5b5d67;
+
+ @media screen and (max-width: 575px) {
+ display: none;
+ }
+}
+
+h2.page-subtitle {
+ text-transform: uppercase;
+ color: #aeaeae;
+ font-size: 1em;
+ margin: 12px;
+}
+
+.network-component-wrapper {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+
+.left-menu-wrapper {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ cursor: pointer;
+}
+
+.header__right-actions {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+
+ .identicon {
+ cursor: pointer;
+ }
+}
diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss
new file mode 100644
index 000000000..4af0c2c55
--- /dev/null
+++ b/ui/app/css/itcss/components/hero-balance.scss
@@ -0,0 +1,118 @@
+.hero-balance {
+
+ @media screen and (max-width: $break-small) {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ margin: .3em .9em 0;
+ // height: 80vh;
+ // max-height: 225px;
+ flex: 0 0 auto;
+ }
+
+ @media screen and (min-width: $break-large) {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+ margin: 2.3em 2.37em .8em;
+ flex: 0 0 auto;
+ }
+
+ .balance-container {
+ display: flex;
+ margin: 0;
+ justify-content: flex-start;
+ align-items: center;
+
+ @media screen and (max-width: $break-small) {
+ flex-direction: column;
+ flex: 0 0 auto;
+ }
+
+ @media screen and (min-width: $break-large) {
+ flex-direction: row;
+ flex-grow: 3;
+ }
+ }
+
+ .balance-display {
+ .token-amount {
+ color: $black;
+ }
+
+ @media screen and (max-width: $break-small) {
+ text-align: center;
+
+ .token-amount {
+ font-size: 1.75rem;
+ margin-top: 1rem;
+ }
+
+ .fiat-amount {
+ font-size: 115%;
+ margin-top: 8.5%;
+ color: #a0a0a0;
+ }
+ }
+
+ @media screen and (min-width: $break-large) {
+ margin-left: .8em;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ .token-amount {
+ font-size: 1.5rem;
+ }
+
+ .fiat-amount {
+ margin-top: .25%;
+ font-size: 105%;
+ }
+ }
+
+ @media #{$sub-mid-size-breakpoint-range} {
+ margin-left: .4em;
+ margin-right: .4em;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ .token-amount {
+ font-size: 1rem;
+ }
+
+ .fiat-amount {
+ margin-top: .25%;
+ font-size: 1rem;
+ }
+ }
+ }
+
+ .hero-balance-buttons {
+
+ @media screen and (max-width: $break-small) {
+ width: 100%;
+ // height: 100px; // needed a round number to set the heights of the buttons inside
+ flex: 0 0 auto;
+ padding: 16px 0;
+ }
+
+ @media screen and (min-width: $break-large) {
+ flex-grow: 2;
+ justify-content: flex-end;
+ }
+ }
+}
+
+.hero-balance-button {
+ width: 6rem;
+
+ @media #{$sub-mid-size-breakpoint-range} {
+ padding: 0.4rem;
+ width: 4rem;
+ display: flex;
+ flex: 1;
+ justify-content: center;
+ }
+}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
new file mode 100644
index 000000000..0219f9fb2
--- /dev/null
+++ b/ui/app/css/itcss/components/index.scss
@@ -0,0 +1,57 @@
+@import './buttons.scss';
+
+@import './header.scss';
+
+@import './footer.scss';
+
+@import './network.scss';
+
+@import './modal.scss';
+
+@import './newui-sections.scss';
+
+@import './account-dropdown.scss';
+
+@import './send.scss';
+
+@import './confirm.scss';
+
+@import './loading-overlay.scss';
+
+// Balances
+@import './hero-balance.scss';
+
+@import './wallet-balance.scss';
+
+// Tx List and Sections
+@import './transaction-list.scss';
+
+@import './sections.scss';
+
+@import './token-list.scss';
+
+@import './add-token.scss';
+
+@import './currency-display.scss';
+
+@import './account-menu.scss';
+
+@import './menu.scss';
+
+@import './gas-slider.scss';
+
+@import './settings.scss';
+
+@import './tab-bar.scss';
+
+@import './simple-dropdown.scss';
+
+@import './request-signature.scss';
+
+@import './account-dropdown-mini.scss';
+
+@import './editable-label.scss';
+
+@import './new-account.scss';
+
+@import './tooltip.scss';
diff --git a/ui/app/css/itcss/components/loading-overlay.scss b/ui/app/css/itcss/components/loading-overlay.scss
new file mode 100644
index 000000000..15009c1e6
--- /dev/null
+++ b/ui/app/css/itcss/components/loading-overlay.scss
@@ -0,0 +1,21 @@
+.loading-overlay {
+ left: 0px;
+ z-index: 50;
+ position: absolute;
+ flex-direction: column;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ background: rgba(255, 255, 255, 0.8);
+
+ @media screen and (max-width: 575px) {
+ margin-top: 56px;
+ height: calc(100% - 56px);
+ }
+
+ @media screen and (min-width: 576px) {
+ margin-top: 75px;
+ height: calc(100% - 75px);
+ }
+}
diff --git a/ui/app/css/itcss/components/menu.scss b/ui/app/css/itcss/components/menu.scss
new file mode 100644
index 000000000..eb92a1b70
--- /dev/null
+++ b/ui/app/css/itcss/components/menu.scss
@@ -0,0 +1,59 @@
+.menu {
+ border-radius: 4px;
+ background: rgba($black, .8);
+ box-shadow: rgba($black, .15) 0 2px 2px 2px;
+ min-width: 150px;
+ color: $white;
+
+ &__item {
+ padding: 18px;
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ position: relative;
+ font-weight: 300;
+ z-index: 201;
+
+ @media screen and (max-width: 575px) {
+ padding: 14px;
+ }
+
+ &--clickable {
+ cursor: pointer;
+
+ &:hover {
+ background-color: rgba($white, .05);
+ }
+
+ &:active {
+ background-color: rgba($white, .1);
+ }
+ }
+
+ &__icon {
+ height: 16px;
+ width: 16px;
+ margin-right: 14px;
+ }
+
+ &__text {
+ font-size: 16px;
+ line-height: 21px;
+ }
+ }
+
+ &__divider {
+ background-color: $scorpion;
+ width: 100%;
+ height: 1px;
+ }
+
+ &__close-area {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ z-index: 100;
+ }
+}
diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss
new file mode 100644
index 000000000..919e1793b
--- /dev/null
+++ b/ui/app/css/itcss/components/modal.scss
@@ -0,0 +1,851 @@
+.modal > div:focus {
+ outline: none !important;
+}
+
+// Buy Modal
+.buy-modal-content {
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ font-family: Roboto;
+ padding: 0 16px;
+}
+
+.buy-modal-content-option {
+ cursor: pointer;
+ color: #5B5D67;
+}
+
+.qr-ellip-address, .ellip-address {
+ width: 247px;
+ border: none;
+ font-family: Roboto;
+ font-size: 14px;
+}
+
+@media screen and (max-width: 575px) {
+ .buy-modal-content-title-wrapper {
+ justify-content: space-around;
+ width: 100%;
+ height: 100px;
+ }
+
+ .buy-modal-content-title {
+ font-size: 26px;
+ margin-top: 15px;
+ }
+
+ .buy-modal-content-options {
+ flex-direction: column;
+ padding: 5% 33%;
+ }
+
+ .buy-modal-content-footer {
+ text-transform: uppercase;
+ width: 100%;
+ height: 50px;
+ }
+
+ div.buy-modal-content-option {
+ display: flex;
+ flex-direction: column;
+ width: 80vw;
+ height: 15vh;
+ margin: 10px;
+ text-align: center;
+ border-radius: 6px;
+ border: 1px solid $black;
+ padding: 0% 7%;
+ justify-content: center;
+
+ div.buy-modal-content-option-title {
+ font-size: 20px;
+ }
+
+ div.buy-modal-content-option-subtitle {
+ font-size: 16px;
+ }
+ }
+}
+
+@media screen and (min-width: 576px) {
+ .buy-modal-content-title-wrapper {
+ justify-content: space-around;
+ width: 100%;
+ height: 110px;
+ }
+
+ .buy-modal-content-title {
+ font-size: 26px;
+ margin-top: 15px;
+ }
+
+ .buy-modal-content-footer {
+ text-transform: uppercase;
+ width: 100%;
+ height: 50px;
+ }
+
+ .buy-modal-content-options {
+ flex-direction: row;
+ margin: 20px 0 60px;
+ }
+
+ div.buy-modal-content-option {
+ display: flex;
+ flex-direction: column;
+ width: 20vw;
+ height: 120px;
+ text-align: center;
+ border-radius: 6px;
+ border: 1px solid $black;
+ margin: 0 8px;
+ padding: 18px 0;
+
+ div.buy-modal-content-option-title {
+ font-size: 20px;
+ margin-bottom: 12px;
+
+ @media screen and (max-width: 679px) {
+ font-size: 14px;
+ }
+
+ @media screen and (min-width: 1281px) {
+ font-size: 20px;
+ }
+ }
+
+ div.buy-modal-content-option-subtitle {
+ font-size: 16px;
+ padding: 0 10px;
+ height: 25%;
+
+ @media screen and (max-width: 679px) {
+ font-size: 10px;
+ padding: 0 10px;
+ margin-bottom: 5px;
+ line-height: 15px;
+ }
+
+ @media screen and (min-width: 680px) {
+ font-size: 14px;
+ padding: 0 4px;
+ margin-bottom: 2px;
+ }
+
+ @media screen and (min-width: 1281px) {
+ font-size: 16px;
+ padding: 0;
+ }
+ }
+
+ div.buy-modal-content-footer {
+ margin-top: 8vh;
+ }
+ }
+}
+
+// Edit Account Name Modal
+.edit-account-name-modal-content {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+}
+
+.edit-account-name-modal-cancel {
+ position: absolute;
+ top: 12px;
+ right: 20px;
+ font-size: 25px;
+}
+
+.edit-account-name-modal-title {
+ margin: 15px;
+}
+
+.edit-account-name-modal-save-button {
+ width: 33%;
+ height: 45px;
+ margin: 15px;
+ font-weight: 700;
+ margin-top: 25px;
+}
+
+.edit-account-name-modal-input {
+ width: 90%;
+ height: 50px;
+ text-align: left;
+ margin: 10px;
+ padding: 10px;
+ font-size: 18px;
+}
+
+// Account Modal Container
+.account-modal-container {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ padding: 5px 0 31px 0;
+ border: 1px solid $silver;
+ border-radius: 4px;
+ font-family: Roboto;
+
+ button {
+ cursor: pointer;
+ }
+}
+
+.account-modal-back {
+ color: $dusty-gray;
+ position: absolute;
+ top: 13px;
+ left: 17px;
+ cursor: pointer;
+
+ &__text {
+ margin-top: 2px;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px;
+ }
+}
+
+.account-modal-close::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: $dusty-gray;
+ position: absolute;
+ top: 10px;
+ right: 12px;
+ cursor: pointer;
+}
+
+.account-modal-container .identicon {
+ position: relative;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ top: -32px;
+ margin-bottom: -32px;
+}
+
+
+// Account Details Modal
+
+.account-modal-container {
+
+ .qr-header {
+ margin-top: 9px;
+ font-size: 20px;
+ }
+
+ .qr-wrapper {
+ margin-top: 5px;
+ }
+
+ .ellip-address-wrapper {
+ display: flex;
+ justify-content: center;
+ border: 1px solid $alto;
+ padding: 5px 10px;
+ font-family: Roboto;
+ margin-top: 7px;
+ width: 286px;
+ }
+
+ .account-modal__button {
+ margin-top: 17px;
+ padding: 10px 22px;
+ width: 235px;
+ }
+}
+
+.account-modal-divider {
+ width: 100%;
+ height: 1px;
+ margin: 19px 0 8px 0;
+ background-color: $alto;
+}
+
+// Export Private Key Modal
+
+.account-modal-container .account-name {
+ margin-top: 9px;
+ font-size: 20px;
+}
+
+.account-modal-container .modal-body-title {
+ margin-top: 16px;
+ margin-bottom: 16px;
+ font-size: 18px;
+}
+
+.account-modal__name {
+ margin-top: 9px;
+ font-size: 20px;
+}
+
+.private-key-password {
+ display: flex;
+ flex-direction: column;
+}
+
+.private-key-password-label, .private-key-password-error {
+ color: $scorpion;
+ font-size: 14px;
+ line-height: 18px;
+ margin-bottom: 10px;
+}
+
+.private-key-password-error {
+ color: $crimson;
+ margin-bottom: 0;
+}
+
+.private-key-password-input {
+ padding: 10px 0 13px 17px;
+ font-size: 16px;
+ line-height: 21px;
+ width: 291px;
+ height: 44px;
+}
+
+.private-key-password::-webkit-input-placeholder {
+ color: $dusty-gray;
+ font-family: Roboto;
+}
+
+.private-key-password-warning {
+ border-radius: 8px;
+ background-color: #FFF6F6;
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 15px;
+ color: $crimson;
+ width: 292px;
+ padding: 9px 15px;
+ margin-top: 18px;
+ font-family: Roboto;
+}
+
+.export-private-key-buttons {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+}
+
+.export-private-key__button {
+ margin-top: 17px;
+ padding: 10px 22px;
+ width: 141px;
+ height: 54px;
+}
+
+.export-private-key__button--cancel {
+ margin-right: 15px;
+}
+
+.private-key-password-display-wrapper {
+ height: 80px;
+ width: 291px;
+ border: 1px solid $silver;
+ border-radius: 2px;
+}
+
+.private-key-password-display-textarea {
+ color: $crimson;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ border: none;
+ height: 75px;
+ width: 100%;
+ overflow: hidden;
+ resize: none;
+ padding: 9px 13px 8px;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+
+
+// New Account Modal
+.new-account-modal-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ border: 1px solid $alto;
+ box-shadow: 0 0 2px 2px $alto;
+ font-family: Roboto;
+}
+
+.new-account-modal-header {
+ background: $wild-sand;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 30px;
+ font-size: 22px;
+ color: $nile-blue;
+ height: 79px;
+}
+
+.modal-close-x::after {
+ content: '\00D7';
+ font-size: 2em;
+ color: $dusty-gray;
+ position: absolute;
+ top: 25px;
+ right: 17.5px;
+ font-family: sans-serif;
+ cursor: pointer;
+}
+
+.new-account-modal-content {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ margin-top: 15px;
+ font-size: 17px;
+ color: $nile-blue;
+}
+
+.new-account-modal-content.after-input {
+ margin-top: 15px;
+ line-height: 25px;
+}
+
+.new-account-input-wrapper {
+ display: flex;
+ width: 100%;
+ justify-content: center;
+ padding-bottom: 2px;
+ margin-top: 13px;
+}
+
+.new-account-input {
+ padding: 15px;
+ padding-bottom: 20px;
+ border-radius: 8px;
+ border: 1px solid $alto;
+ width: 100%;
+ font-size: 1em;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 17px;
+ margin: 0 60px;
+}
+
+// For reference on below placeholder selectors: https://stackoverflow.com/questions/2610497/change-an-html5-inputs-placeholder-color-with-css
+.new-account-input::-webkit-input-placeholder {
+ color: $dusty-gray;
+}
+
+.new-account-input:-moz-placeholder {
+ color: $dusty-gray;
+ opacity: 1;
+}
+
+.new-account-input::-moz-placeholder {
+ color: $dusty-gray;
+ opacity: 1;
+}
+
+.new-account-input:-ms-input-placeholder {
+ color: $dusty-gray;
+}
+
+.new-account-input::-ms-input-placeholder {
+ color: $dusty-gray;
+}
+
+.new-account-modal-content.button {
+ margin-top: 22px;
+ margin-bottom: 30px;
+ width: 113px;
+ height: 44px;
+}
+
+.new-account-modal-wrapper .btn-clear {
+ font-size: 14px;
+ font-weight: 700;
+ background: $white;
+ border: 1px solid;
+ border-radius: 2px;
+ color: $tundora;
+ flex: 1;
+}
+
+// Hide token confirmation
+
+.hide-token-confirmation {
+ min-height: 250.72px;
+ border-radius: 4px;
+ background-color: $white;
+ box-shadow: 0 1px 7px 0 rgba(0, 0, 0, .5);
+
+ &__container {
+ padding: 24px 27px 21px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ &__identicon {
+ margin-bottom: 10px;
+ }
+
+ &__symbol {
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 24px;
+ text-align: center;
+ margin-bottom: 7.5px;
+ }
+
+ &__title {
+ height: 30px;
+ width: 271.28px;
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 22px;
+ line-height: 30px;
+ text-align: center;
+ margin-bottom: 10.5px;
+ }
+
+ &__copy {
+ height: 41px;
+ width: 318px;
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px;
+ text-align: center;
+ }
+
+ &__buttons {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ margin-top: 15px;
+ width: 100%;
+ }
+
+ &__button {
+ width: 141px;
+ margin: 0 5px;
+ }
+}
+
+//Notification Modal
+
+.notification-modal {
+
+ &__wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ border: 1px solid $alto;
+ box-shadow: 0 0 2px 2px $alto;
+ font-family: Roboto;
+ }
+
+ &__header {
+ background: $wild-sand;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ padding: 30px;
+ font-size: 22px;
+ color: $nile-blue;
+ height: 79px;
+ }
+
+ &__message {
+ padding: 20px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ font-size: 17px;
+ color: $nile-blue;
+ }
+
+ &__buttons {
+ display: flex;
+ justify-content: space-evenly;
+ width: 100%;
+ margin-bottom: 24px;
+ padding: 0px 42px;
+
+ &__btn {
+ cursor: pointer;
+ }
+ }
+
+ &__link {
+ color: $curious-blue;
+ }
+}
+
+// Deposit Ether Modal
+.deposit-ether-modal {
+ border-radius: 8px;
+ font-family: Roboto;
+ display: flex;
+ flex-flow: column;
+ height: 100%;
+
+ &__header {
+ width: 100%;
+ border-radius: 8px 8px 0 0;
+ background-color: $mid-gray;
+ display: flex;
+ position: relative;
+ padding: 25px;
+ flex-flow: column;
+ align-items: flex-start;
+
+ &__title {
+ color: $white;
+ font-size: 24px;
+ line-height: 32px;
+ }
+
+ &__description {
+ color: $white;
+ font-size: 16px;
+ line-height: 22px;
+ margin-top: 10px;
+ }
+
+ &__close::after {
+ content: '\00D7';
+ font-size: 2em;
+ color: $white;
+ position: absolute;
+ top: 20.8px;
+ right: 28px;
+ cursor: pointer;
+ }
+ }
+
+ &__buy-rows {
+ width: 100%;
+ padding: 33px;
+ padding-top: 0px;
+ display: flex;
+ flex-flow: column nowrap;
+ flex: 1;
+ overflow-y: auto;
+
+ @media screen and (max-width: 575px) {
+ height: 0;
+ }
+ }
+
+ &__buy-row {
+ border-bottom: 1px solid $alto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex: 1;
+ padding-bottom: 25px;
+ padding-top: 25px;
+
+ @media screen and (max-width: 575px) {
+ min-height: 360px;
+ flex-flow: column;
+ justify-content: center;
+ padding-top: 45px;
+ }
+
+ &__back {
+ position: absolute;
+ top: 10px;
+ left: 0px;
+ }
+
+ &__shapeshift-buy {
+ padding-top: 25px;
+ position: relative;
+ @media screen and (max-width: 575px) {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex: 1;
+ padding-bottom: 25px;
+ flex-flow: column;
+ justify-content: center;
+ padding-top: 20px;
+ min-height: 240px;
+ border: none;
+ }
+ }
+
+ &__logo {
+ display: flex;
+ justify-content: center;
+ flex: 0.3 1 auto;
+
+ @media screen and (min-width: 575px) {
+ min-width: 215px;
+ }
+ }
+
+ &__coinbase-logo {
+ height: 40px;
+ width: 180px;
+ }
+
+ &__shapeshift-logo {
+ height: 60px;
+ width: 174px;
+ }
+
+ &__eth-logo {
+ border-radius: 50%;
+ width: 68px;
+ height: 68px;
+ border: 3px solid $tundora;
+ z-index: 25;
+ padding: 4px;
+ background-color: #fff;
+ }
+
+ &__right {
+ display: flex;
+ }
+
+ &__description {
+ color: $cape-cod;
+ flex: 0.5 1 auto;
+
+ @media screen and (min-width: 575px) {
+ min-width: 315px;
+ }
+
+ &__title {
+ font-size: 20px;
+ line-height: 30px;
+ }
+
+ &__text {
+ font-size: 14px;
+ line-height: 22px;
+ margin-top: 7px;
+ }
+ }
+
+ &__button {
+ display: flex;
+ justify-content: flex-end;
+
+ @media screen and (min-width: 575px) {
+ min-width: 300px;
+ }
+ }
+ }
+
+ &__buy-row:last-of-type {
+ border-bottom: 0px;
+ }
+
+ &__deposit-button, .shapeshift-form__shapeshift-buy-btn {
+ height: 54px;
+ width: 257px;
+ border: 1px solid $curious-blue;
+ border-radius: 4px;
+ display: flex;
+ justify-content: center;
+ font-size: 16px;
+ color: $curious-blue;
+ background-color: $white;
+ }
+
+ .shapeshift-form-wrapper {
+ display: flex;
+ flex-flow: column;
+ justify-content: center;
+ align-items: center;
+ margin-top: 28px;
+ flex: 1 0 auto;
+
+ .shapeshift-form {
+ width: auto;
+
+ &__caret {
+ width: auto;
+ flex: 1;
+ }
+ }
+ }
+
+ .shapeshift-form__shapeshift-buy-btn {
+ margin-top: 10px;
+ }
+
+ .simple-dropdown {
+ color: #5B5D67;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 21px;
+ border: 1px solid #D8D8D8;
+ background-color: #FFFFFF;
+ text-align: center;
+ width: 100%;
+ height: 45px;
+ line-height: 44px;
+ font-family: Montserrat Light;
+ }
+
+ .simple-dropdown__selected {
+ text-align: center;
+ }
+}
+
+//Notification Modal
+
+.notification-modal-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ position: relative;
+ border: 1px solid $alto;
+ box-shadow: 0 0 2px 2px $alto;
+ font-family: Roboto;
+}
+
+.notification-modal-header {
+ background: $wild-sand;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 30px;
+ font-size: 22px;
+ color: $nile-blue;
+ height: 79px;
+}
+
+.notification-modal-message {
+ padding: 20px;
+}
+
+.notification-modal-message {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ font-size: 17px;
+ color: $nile-blue;
+}
diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss
new file mode 100644
index 000000000..d9a39b8d5
--- /dev/null
+++ b/ui/app/css/itcss/components/network.scss
@@ -0,0 +1,157 @@
+.network-component--disabled {
+ // border-color: transparent !important;
+ cursor: default;
+
+ .fa-caret-down {
+ opacity: 0;
+ }
+}
+
+.network-component.pointer {
+ border: 2px solid $silver;
+ border-radius: 82px;
+ padding: 3px;
+ flex: 0 0 auto;
+
+ &.ethereum-network .menu-icon-circle div {
+ background-color: rgba(3, 135, 137, .7) !important;
+ }
+
+ &.ropsten-test-network .menu-icon-circle div {
+ background-color: rgba(233, 21, 80, .7) !important;
+ }
+
+ &.kovan-test-network .menu-icon-circle div {
+ background-color: rgba(105, 4, 150, .7) !important;
+ }
+
+ &.rinkeby-test-network .menu-icon-circle div {
+ background-color: rgba(235, 179, 63, .7) !important;
+ }
+}
+
+.dropdown-menu-item {
+ .menu-icon-circle,
+ .menu-icon-circle--active {
+ margin: 0 14px;
+ }
+}
+
+.network-indicator {
+ display: flex;
+ align-items: center;
+ font-size: .6em;
+
+ .fa-caret-down {
+ line-height: 15px;
+ font-size: 12px;
+ padding: 0 4px;
+ }
+}
+
+.network-name {
+ padding: 0 4px;
+ font-family: Roboto;
+ font-size: 12px;
+ flex: 1 0 auto;
+ color: $tundora;
+ font-weight: 500;
+}
+
+.network-droppo {
+ right: 2px;
+
+ @media screen and (min-width: 576px) {
+ right: calc(((100% - 85vw) / 2) + 2px);
+ }
+
+ @media screen and (min-width: 769px) {
+ right: calc(((100% - 80vw) / 2) + 2px);
+ }
+
+ @media screen and (min-width: 1281px) {
+ right: calc(((100% - 65vw) / 2) + 2px);
+ }
+}
+
+.network-name-item {
+ font-weight: 100;
+ flex: 1 0 auto;
+ color: $dusty-gray;
+}
+
+.network-check,
+.network-check__transparent {
+ color: $white;
+ margin-left: 7px;
+}
+
+.network-check__transparent {
+ opacity: 0;
+ width: 16px;
+ margin: 0;
+}
+
+.menu-icon-circle,
+.menu-icon-circle--active {
+ background: none;
+ border-radius: 22px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid transparent;
+ margin: 0 4px;
+}
+
+.menu-icon-circle--active {
+ border: 1px solid $white;
+ background: rgba(100, 100, 100, .4);
+}
+
+.menu-icon-circle div,
+.menu-icon-circle--active div {
+ height: 12px;
+ width: 12px;
+ border-radius: 17px;
+}
+
+.menu-icon-circle--active div {
+ opacity: 1;
+}
+
+.network-dropdown-header {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+}
+
+.network-dropdown-divider {
+ width: 100%;
+ height: 1px;
+ margin: 10px 0;
+ background-color: $scorpion;
+}
+
+.network-dropdown-title {
+ height: 25px;
+ width: 75px;
+ color: $white;
+ font-family: Roboto;
+ font-size: 18px;
+ line-height: 25px;
+ text-align: center;
+}
+
+.network-dropdown-content {
+ height: 36px;
+ width: 265px;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 18px;
+}
+
+.network-caret {
+ margin: 0 8px 2px;
+}
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
new file mode 100644
index 000000000..81f919df3
--- /dev/null
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -0,0 +1,211 @@
+.new-account {
+ width: 376px;
+ background-color: #FFFFFF;
+ box-shadow: 0 0 7px 0 rgba(0,0,0,0.08);
+ z-index: 25;
+ padding-bottom: 31px;
+
+ &__header {
+ display: flex;
+ flex-flow: column;
+ border-bottom: 1px solid $geyser;
+ }
+
+ &__title {
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 32px;
+ font-weight: 500;
+ line-height: 43px;
+ margin-top: 22px;
+ margin-left: 29px;
+ }
+
+ &__tabs {
+ margin-left: 22px;
+ display: flex;
+ margin-top: 10px;
+
+ &__tab {
+ height: 54px;
+ width: 75px;
+ padding: 15px 10px;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 18px;
+ line-height: 24px;
+ text-align: center;
+ }
+
+ &__tab:first-of-type {
+ margin-right: 20px;
+ }
+
+ &__unselected:hover {
+ color: $black;
+ border-bottom: none;
+ }
+
+ &__selected {
+ color: $curious-blue;
+ border-bottom: 3px solid $curious-blue;
+ }
+ }
+
+}
+
+.new-account-import-form {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ padding: 0 30px;
+
+ &__select-section {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 29px;
+ width: 100%;
+ }
+
+ &__select-label {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ }
+
+ &__select {
+ height: 54px;
+ width: 210px;
+ border: 1px solid #D2D8DD;
+ border-radius: 4px;
+ background-color: #FFFFFF;
+ display: flex;
+ align-items: center;
+
+ .Select-control,
+ .Select-control:hover {
+ height: 100%;
+ border: none;
+ box-shadow: none;
+
+ .Select-value {
+ display: flex;
+ align-items: center;
+ }
+ }
+ }
+
+ &__private-key-password-container {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ width: 100%;
+ }
+
+ &__instruction {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ align-self: flex-start;
+ }
+
+ &__private-key {
+ display: flex;
+ flex-flow: column;
+ align-items: flex-start;
+ margin-top: 34px;
+ }
+
+ &__input-password {
+ height: 54px;
+ width: 315px;
+ border: 1px solid $geyser;
+ border-radius: 4px;
+ background-color: $white;
+ margin-top: 16px;
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ padding: 0px 20px;
+ }
+
+ &__json {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ margin-top: 29px;
+ }
+
+ &__buttons {
+ margin-top: 39px;
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ }
+}
+
+.new-account-create-form {
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+
+ &__input-label {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ margin-top: 29px;
+ align-self: flex-start;
+ margin-left: 30px;
+ }
+
+ &__input {
+ height: 54px;
+ width: 315.84px;
+ border: 1px solid $geyser;
+ border-radius: 4px;
+ background-color: $white;
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ margin-top: 15px;
+ padding: 0px 20px;
+ }
+
+ &__buttons {
+ margin-top: 39px;
+ display: flex;
+ width: 100%;
+ justify-content: space-evenly;
+ }
+
+ &__button-cancel,
+ &__button-create {
+ height: 55px;
+ width: 150px;
+ border-radius: 2px;
+ background-color: #FFFFFF;
+ }
+
+ &__button-cancel {
+ border: 1px solid $dusty-gray;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ text-align: center;
+ }
+
+ &__button-create {
+ border: 1px solid $curious-blue;
+ color: $curious-blue;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ text-align: center;
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss
new file mode 100644
index 000000000..73faebe8b
--- /dev/null
+++ b/ui/app/css/itcss/components/newui-sections.scss
@@ -0,0 +1,292 @@
+$sub-mid-size-breakpoint: 667px;
+$sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$sub-mid-size-breakpoint})";
+
+/*
+ NewUI Container Elements
+ */
+
+// Component Colors
+$tx-view-bg: $white;
+$wallet-view-bg: $alabaster;
+
+// Main container
+.main-container {
+ // position: absolute;
+ z-index: $main-container-z-index;
+ font-family: Roboto;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: stretch;
+}
+
+.main-container::-webkit-scrollbar {
+ display: none;
+}
+
+//Account and transaction details
+.account-and-transaction-details {
+ display: flex;
+ flex: 1 0 auto;
+}
+
+// tx view
+
+.tx-view {
+ flex: 63.5 0 66.5%;
+ background: $tx-view-bg;
+
+ // No title on mobile
+ @media screen and (max-width: 575px) {
+ .identicon-wrapper {
+ display: none;
+ }
+
+ .account-name {
+ display: none;
+ }
+ }
+}
+
+.open-in-browser {
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+}
+
+// wallet view and sidebar
+
+.wallet-view {
+ display: flex;
+ flex-direction: column;
+ flex: 32 1 32%;
+ width: 0;
+ background: $wallet-view-bg;
+ z-index: 200;
+ position: relative;
+
+ @media screen and (min-width: 576px) {
+ overflow-y: scroll;
+ overflow-x: hidden;
+ }
+
+ @media #{$sub-mid-size-breakpoint-range} {
+ min-width: 160px;
+ }
+
+ .wallet-view-account-details {
+ flex: 0 0 auto;
+ }
+
+ &__name-container {
+ flex: 0 0 auto;
+ cursor: pointer;
+ width: 100%;
+ }
+
+ &__keyring-label {
+ height: 50px;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 10px;
+ text-align: right;
+ padding: 17px 20px 0;
+ box-sizing: border-box;
+ }
+
+ &__details-button {
+ font-size: 10px;
+ border-radius: 17px;
+ background-color: transparent;
+ margin: 0 auto;
+ padding: 4px 12px;
+ flex: 0 0 auto;
+ }
+
+ &__tooltip {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 24px;
+ }
+
+ &__address {
+ border-radius: 3px;
+ background-color: $alto;
+ color: $scorpion;
+ font-size: 14px;
+ line-height: 12px;
+ padding: 4px 12px;
+ font-weight: 300;
+ cursor: pointer;
+ flex: 0 0 auto;
+
+ &__pressed {
+ background-color: $manatee,
+ }
+ }
+
+ &__sidebar-close {
+
+ @media screen and (max-width: 575px) {
+ &::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: $tundora;
+ position: absolute;
+ top: 12px;
+ left: 12px;
+ cursor: pointer;
+ }
+ }
+ }
+
+ &__add-token-button {
+ flex: 0 0 auto;
+ margin: 36px auto;
+ background: none;
+ padding: .7rem 2rem;
+ transition: border-color .3s ease;
+
+ &:hover {
+ border-color: $curious-blue;
+ }
+ }
+}
+
+@media screen and (min-width: 576px) {
+ .wallet-view::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+.wallet-view-title-wrapper {
+ flex: 0 0 25px;
+}
+
+.wallet-view-title {
+ margin-left: 15px;
+ font-size: 16px;
+
+ // No title on mobile
+ @media screen and (max-width: 575px) {
+ display: none;
+ }
+}
+
+.wallet-view.sidebar {
+ flex: 1 0 230px;
+ background: rgb(250, 250, 250);
+ z-index: $sidebar-z-index;
+ position: fixed;
+ top: 66px;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ will-change: transform;
+ overflow-y: auto;
+ box-shadow: rgba(0, 0, 0, .15) 2px 2px 4px;
+ width: 85%;
+ height: calc(100% - 56px);
+}
+
+.sidebar-overlay {
+ z-index: $sidebar-overlay-z-index;
+ position: fixed;
+ // top: 41px;
+ height: 100%;
+ width: 100%;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ background-color: rgba(0, 0, 0, .3);
+}
+
+// main-container media queries
+
+@media screen and (min-width: 576px) {
+ .lap-visible {
+ display: flex;
+ }
+
+ .phone-visible {
+ display: none;
+ }
+
+ .main-container {
+ // margin-top: 6.9vh;
+ width: 85vw;
+ height: 90vh;
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08);
+ }
+}
+
+@media screen and (min-width: 769px) {
+ .main-container {
+ // margin-top: 6.9vh;
+ width: 80vw;
+ height: 82vh;
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08);
+ }
+}
+
+@media screen and (min-width: 1281px) {
+ .main-container {
+ // margin-top: 6.9vh;
+ width: 62vw;
+ height: 82vh;
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08);
+ }
+}
+
+@media screen and (max-width: 575px) {
+ .lap-visible {
+ display: none;
+ }
+
+ .phone-visible {
+ display: flex;
+ }
+
+ .main-container {
+ // margin-top: 41px;
+ height: 100%;
+ width: 100%;
+ overflow-y: auto;
+ background-color: $white;
+ }
+}
+
+// wallet view
+.account-name {
+ font-size: 24px;
+ font-weight: 300;
+ line-height: 20px;
+ color: $black;
+ margin-top: 8px;
+ margin-bottom: .9rem;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ width: 100%;
+ padding: 0 8px;
+ text-align: center;
+}
+
+// account options dropdown
+.account-options-menu {
+ align-items: center;
+ justify-content: flex-start;
+ margin: 5% 7% 0%;
+}
+
+.fiat-amount {
+ text-transform: uppercase;
+}
+
+.token-balance__amount {
+ padding-right: 6px;
+}
diff --git a/ui/app/css/itcss/components/request-signature.scss b/ui/app/css/itcss/components/request-signature.scss
new file mode 100644
index 000000000..d81099bfa
--- /dev/null
+++ b/ui/app/css/itcss/components/request-signature.scss
@@ -0,0 +1,230 @@
+.request-signature {
+ &__container {
+ width: 380px;
+ border-radius: 8px;
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08);
+ display: flex;
+ flex-flow: column nowrap;
+ z-index: 25;
+ align-items: center;
+ font-family: Roboto;
+ position: relative;
+ height: 100%;
+
+ @media screen and (max-width: $break-small) {
+ width: 100%;
+ top: 0;
+ box-shadow: none;
+ }
+
+ @media screen and (min-width: $break-large) {
+ max-height: 620px;
+ }
+ }
+
+ &__header {
+ height: 64px;
+ width: 100%;
+ position: relative;
+ display: flex;
+ flex-flow: column;
+ justify-content: center;
+ align-items: center;
+ flex: 0 0 auto;
+ }
+
+ &__header-background {
+ position: absolute;
+ background-color: $athens-grey;
+ z-index: 2;
+ width: 100%;
+ height: 100%;
+ }
+
+ &__header__text {
+ height: 29px;
+ width: 179px;
+ color: #5B5D67;
+ font-family: Roboto;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 29px;
+ z-index: 3;
+ }
+
+ &__header__tip-container {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ }
+
+ &__header__tip {
+ height: 25px;
+ width: 25px;
+ background: $athens-grey;
+ transform: rotate(45deg);
+ position: absolute;
+ bottom: -8px;
+ z-index: 1;
+ }
+
+ &__account-info {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 18px;
+ margin-bottom: 20px;
+ }
+
+ &__account {
+ color: $dusty-gray;
+ margin-left: 17px;
+ }
+
+ &__account-text {
+ font-size: 14px;
+ }
+
+ &__balance {
+ color: $dusty-gray;
+ margin-right: 17px;
+ width: 124px;
+ }
+
+ &__balance-text {
+ text-align: right;
+ font-size: 14px;
+ }
+
+ &__balance-value {
+ text-align: right;
+ margin-top: 2.5px;
+ }
+
+ &__request-icon {
+ margin-top: 25px;
+ }
+
+ &__body {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-flow: column;
+ flex: 1 1 auto;
+ height: 0;
+ }
+
+ &__request-info {
+ display: flex;
+ justify-content: center;
+ }
+
+ &__headline {
+ height: 48px;
+ width: 240px;
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 18px;
+ font-weight: 300;
+ line-height: 24px;
+ text-align: center;
+ margin-top: 20px;
+ }
+
+ &__notice,
+ &__warning {
+ font-family: "Avenir Next";
+ font-size: 14px;
+ line-height: 19px;
+ text-align: center;
+ margin-top: 41px;
+ margin-bottom: 11px;
+ width: 100%;
+ }
+
+ &__notice {
+ color: $dusty-gray;
+ }
+
+ &__warning {
+ color: $crimson;
+ }
+
+ &__rows {
+ height: 100%;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ border-top: 1px solid $geyser;
+ display: flex;
+ flex-flow: column;
+ }
+
+ &__row {
+ display: flex;
+ flex-flow: column;
+ }
+
+ &__row-title {
+ width: 80px;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ margin-top: 12px;
+ margin-left: 18px;
+ width: 100%;
+ }
+
+ &__row-value {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 19px;
+ width: 100%;
+ overflow-wrap: break-word;
+ border-bottom: 1px solid #d2d8dd;
+ padding: 6px 18px 15px;
+ }
+
+ &__footer {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-evenly;
+ font-size: 22px;
+ position: relative;
+ flex: 0 0 auto;
+ border-top: 1px solid $geyser;
+
+ &__cancel-button,
+ &__sign-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 1 0 auto;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: 300;
+ height: 55px;
+ line-height: 32px;
+ cursor: pointer;
+ border-radius: 2px;
+ box-shadow: none;
+ max-width: 162px;
+ margin: 12px;
+ }
+
+ &__cancel-button {
+ background: none;
+ border: 1px solid $dusty-gray;
+ margin-right: 6px;
+ }
+
+ &__sign-button {
+ background-color: $caribbean-green;
+ border-width: 0;
+ color: $white;
+ margin-left: 6px;
+ }
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/sections.scss b/ui/app/css/itcss/components/sections.scss
new file mode 100644
index 000000000..388aea175
--- /dev/null
+++ b/ui/app/css/itcss/components/sections.scss
@@ -0,0 +1,476 @@
+// Old scss, do not lint - clean up later
+/* stylelint-disable */
+
+
+/*
+App Sections
+ TODO: Move into separate files.
+*/
+
+/* initialize */
+textarea.twelve-word-phrase {
+ padding: 12px;
+ width: 300px;
+ height: 140px;
+ font-size: 16px;
+ background: $white;
+ resize: none;
+}
+
+.initialize-screen hr {
+ width: 60px;
+ margin: 12px;
+ border-color: #f7861c;
+ border-style: solid;
+}
+
+.initialize-screen label {
+ margin-top: 20px;
+}
+
+.initialize-screen button.create-vault {
+ margin-top: 40px;
+}
+
+.initialize-screen .warning {
+ font-size: 14px;
+ margin: 0 16px;
+}
+
+/* unlock */
+.error {
+ // color: #e20202;
+ color: #f7861c;
+ margin-bottom: 9px;
+}
+
+.warning {
+ color: #ffae00;
+}
+
+.lock {
+ width: 50px;
+ height: 50px;
+}
+
+.lock.locked {
+ transform: scale(1.5);
+ opacity: 0;
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+}
+
+.lock.unlocked {
+ transform: scale(1);
+ opacity: 1;
+ transition: opacity 500ms ease-out, transform 500ms ease-out, background 200ms ease-in;
+}
+
+.lock.locked .lock-top {
+ transform: scaleX(1) translateX(0);
+ transition: transform 250ms ease-in;
+}
+
+.lock.unlocked .lock-top {
+ transform: scaleX(-1) translateX(-12px);
+ transition: transform 250ms ease-in;
+}
+
+.lock.unlocked:hover {
+ border-radius: 4px;
+ background: #e5e5e5;
+ border: 1px solid #b1b1b1;
+}
+
+.lock.unlocked:active {
+ background: #c3c3c3;
+}
+
+.section-title .fa-arrow-left {
+ margin: -2px 8px 0px -8px;
+}
+
+.unlock-screen #metamask-mascot-container {
+ margin-top: 24px;
+}
+
+.unlock-screen h1 {
+ margin-top: -28px;
+ margin-bottom: 42px;
+}
+
+.unlock-screen input[type=password] {
+ width: 260px;
+}
+
+.sizing-input {
+ font-size: 14px;
+ height: 30px;
+ padding-left: 5px;
+}
+
+.editable-label {
+ display: flex;
+}
+
+/* Webkit */
+
+.unlock-screen input::-webkit-input-placeholder {
+ text-align: center;
+ font-size: 1.2em;
+}
+
+/* Firefox 18- */
+
+.unlock-screen input:-moz-placeholder {
+ text-align: center;
+ font-size: 1.2em;
+}
+
+/* Firefox 19+ */
+
+.unlock-screen input::-moz-placeholder {
+ text-align: center;
+ font-size: 1.2em;
+}
+
+/* IE */
+
+.unlock-screen input:-ms-input-placeholder {
+ text-align: center;
+ font-size: 1.2em;
+}
+
+/* accounts */
+
+.accounts-section {
+ margin: 0 0px;
+}
+
+.accounts-section .horizontal-line {
+ margin: 0 18px;
+}
+
+.accounts-list-option {
+ height: 120px;
+}
+
+.accounts-list-option .identicon-wrapper {
+ width: 100px;
+}
+
+.unconftx-link {
+ margin-top: 24px;
+ cursor: pointer;
+}
+
+.unconftx-link .fa-arrow-right {
+ margin: 0 -8px 0px 8px;
+}
+
+/* identity panel */
+
+.identity-panel {
+ font-weight: 500;
+}
+
+.identity-panel .identicon-wrapper {
+ margin: 4px;
+ margin-top: 8px;
+ display: flex;
+ align-items: center;
+}
+
+.identity-panel .identicon-wrapper span {
+ margin: 0 auto;
+}
+
+.identity-panel .identity-data {
+ margin: 8px 8px 8px 18px;
+}
+
+.identity-panel i {
+ margin-top: 32px;
+ margin-right: 6px;
+ color: #b9b9b9;
+}
+
+.identity-panel .arrow-right {
+ padding-left: 18px;
+ width: 42px;
+ min-width: 18px;
+ height: 100%;
+}
+
+.identity-copy.flex-column {
+ flex: .25 0 auto;
+ justify-content: center;
+}
+
+/* accounts screen */
+
+.identity-section {
+}
+
+.identity-section .identity-panel {
+ background: #e9e9e9;
+ border-bottom: 1px solid #b1b1b1;
+ cursor: pointer;
+}
+
+.identity-section .identity-panel.selected {
+ background: $white;
+ color: #f3c83e;
+}
+
+.identity-section .identity-panel.selected .identicon {
+ border-color: $orange;
+}
+
+.identity-section .accounts-list-option:hover,
+.identity-section .accounts-list-option.selected {
+ background: $white;
+}
+
+/* account detail screen */
+
+.account-detail-section {
+ display: flex;
+ flex-wrap: wrap;
+ overflow-y: auto;
+ flex-direction: inherit;
+}
+
+.grow-tenx {
+ flex-grow: 10;
+}
+
+.name-label {
+}
+
+.unapproved-tx-icon {
+ height: 16px;
+ width: 16px;
+ background: rgb(47, 174, 244);
+ border-color: $silver-chalice;
+ border-radius: 13px;
+}
+
+.edit-text {
+ height: 100%;
+ visibility: hidden;
+}
+
+.editing-label {
+ display: flex;
+ justify-content: flex-start;
+ margin-left: 50px;
+ margin-bottom: 2px;
+ font-size: 11px;
+ text-rendering: geometricPrecision;
+ color: #f7861c;
+}
+
+.name-label:hover .edit-text {
+ visibility: visible;
+}
+/* tx confirm */
+
+.unconftx-section input[type=password] {
+ height: 22px;
+ padding: 2px;
+ margin: 12px;
+ margin-bottom: 24px;
+ border-radius: 4px;
+ border: 2px solid #f3c83e;
+ background: #faf6f0;
+}
+
+/* Ether Balance Widget */
+
+.ether-balance-amount {
+ color: #f7861c;
+}
+
+.ether-balance-label {
+ color: #aba9aa;
+}
+
+/* Info screen */
+.info-gray {
+ font-family: Roboto;
+ text-transform: uppercase;
+ color: $silver-chalice;
+}
+
+.icon-size {
+ width: 20px;
+}
+
+.info {
+ font-family: Roboto, Arial;
+ padding-bottom: 10px;
+ display: inline-block;
+ padding-left: 5px;
+}
+
+/* buy eth warning screen */
+.custom-radios {
+ justify-content: space-around;
+ align-items: center;
+}
+
+.custom-radio-selected {
+ width: 17px;
+ height: 17px;
+ border: solid;
+ border-style: double;
+ border-radius: 15px;
+ border-width: 5px;
+ background: rgba(247, 134, 28, 1);
+ border-color: #f7f7f7;
+}
+
+.custom-radio-inactive {
+ width: 14px;
+ height: 14px;
+ border: solid;
+ border-width: 1px;
+ border-radius: 24px;
+ border-color: $silver-chalice;
+}
+
+.radio-titles {
+ color: rgba(247, 134, 28, 1);
+}
+
+.eth-warning {
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+}
+
+.buy-subview {
+ transition: opacity 400ms ease-in, transform 400ms ease-in;
+}
+
+.input-container:hover .edit-text {
+ visibility: visible;
+}
+
+.buy-inputs {
+ font-family: Roboto;
+ font-size: 13px;
+ height: 20px;
+ background: transparent;
+ box-sizing: border-box;
+ border: solid;
+ border-color: transparent;
+ border-width: .5px;
+ border-radius: 2px;
+}
+
+.input-container:hover .buy-inputs {
+ box-sizing: inherit;
+ border: solid;
+ border-color: #f7861c;
+ border-width: .5px;
+ border-radius: 2px;
+}
+
+.buy-inputs:focus {
+ border: solid;
+ border-color: #f7861c;
+ border-width: .5px;
+ border-radius: 2px;
+}
+
+.activeForm {
+ background: #f7f7f7;
+ border: none;
+ border-radius: 8px 8px 0px 0px;
+ width: 50%;
+ text-align: center;
+ padding-bottom: 4px;
+}
+
+.inactiveForm {
+ border: none;
+ border-radius: 8px 8px 0px 0px;
+ width: 50%;
+ text-align: center;
+ padding-bottom: 4px;
+}
+
+.ex-coins {
+ font-family: Roboto;
+ text-transform: uppercase;
+ text-align: center;
+ font-size: 33px;
+ width: 118px;
+ height: 42px;
+ padding: 1px;
+ color: #4d4d4d;
+}
+
+.marketinfo {
+ font-family: Roboto;
+ color: $silver-chalice;
+ font-size: 15px;
+ line-height: 17px;
+}
+
+#fromCoin::-webkit-calendar-picker-indicator {
+ display: none;
+}
+
+#coinList {
+ width: 400px;
+ height: 500px;
+ overflow: scroll;
+}
+
+.icon-control .fa-refresh {
+ visibility: hidden;
+}
+
+.icon-control:hover .fa-refresh {
+ visibility: visible;
+}
+
+.icon-control:hover .fa-chevron-right {
+ visibility: hidden;
+}
+
+.inactive {
+ color: $silver-chalice;
+}
+
+.inactive button {
+ background: $silver-chalice;
+ color: $white;
+}
+
+.qr-ellip-address, .ellip-address {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.qr-header {
+ font-size: 25px;
+ margin-top: 40px;
+}
+
+.qr-message {
+ font-size: 12px;
+ color: #f7861c;
+}
+
+div.message-container > div:first-child {
+ margin-top: 18px;
+ font-size: 15px;
+ color: #4d4d4d;
+}
+
+.pop-hover:hover {
+ transform: scale(1.1);
+}
+
+/* stylelint-enable */
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
new file mode 100644
index 000000000..bb17e53cd
--- /dev/null
+++ b/ui/app/css/itcss/components/send.scss
@@ -0,0 +1,887 @@
+.send-screen-wrapper {
+ display: flex;
+ flex-flow: column nowrap;
+ z-index: 25;
+ font-family: Roboto;
+
+ @media screen and (max-width: $break-small) {
+ width: 100%;
+ overflow-y: auto;
+ }
+
+ section {
+ flex: 0 0 auto;
+ }
+}
+
+.send-screen-card {
+ background-color: #fff;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .08);
+ padding: 46px 40.5px 26px;
+ position: relative;
+ // top: -26px;
+ align-items: center;
+ display: flex;
+ flex-flow: column nowrap;
+ width: 498px;
+ flex: 1 0 auto;
+
+ @media screen and (max-width: $break-small) {
+ top: 0;
+ width: 100%;
+ box-shadow: none;
+ padding: 12px;
+ }
+}
+
+/* Send Screen */
+
+.send-screen section {
+ margin: 4px 16px;
+}
+
+.send-screen input {
+ width: 100%;
+ font-size: 12px;
+}
+
+.send-eth-icon {
+ border-radius: 50%;
+ width: 70px;
+ height: 70px;
+ border: 1px solid $alto;
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, .2);
+ position: absolute;
+ top: -35px;
+ z-index: 25;
+ padding: 4px;
+ background-color: $white;
+
+ @media screen and (max-width: $break-small) {
+ position: relative;
+ top: 0;
+ }
+}
+
+.send-screen-input-wrapper {
+ width: 95%;
+ position: relative;
+
+ .fa-bolt {
+ padding-right: 4px;
+ }
+
+ .large-input {
+ border: 1px solid $dusty-gray;
+ border-radius: 4px;
+ margin: 4px 0 20px;
+ font-size: 16px;
+ line-height: 22.4px;
+ font-family: Roboto;
+ }
+
+ .send-screen-gas-input {
+ border: 1px solid transparent;
+ }
+
+ &__error-message {
+ display: none;
+ }
+
+ &--error {
+ input,
+ .send-screen-gas-input {
+ border-color: $red !important;
+ }
+
+ .send-screen-input-wrapper__error-message {
+ display: block;
+ position: absolute;
+ bottom: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: $red;
+ }
+ }
+
+ .send-screen-input-wrapper__error-message {
+ display: block;
+ position: absolute;
+ bottom: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: $red;
+ }
+}
+
+.send-screen-input {
+ width: 100%;
+}
+
+.send-screen-gas-input {
+ width: 100%;
+ height: 41px;
+ border-radius: 3px;
+ background-color: #f3f3f3;
+ border-width: 0;
+ border-style: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-left: 10px;
+ padding-right: 12px;
+ font-size: 16px;
+ color: $scorpion;
+}
+
+.send-screen-amount-labels {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
+.send-screen-gas-labels {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
+.currency-toggle {
+ &__item {
+ color: $curious-blue;
+ cursor: pointer;
+
+ &--selected {
+ color: $black;
+ cursor: default;
+ }
+ }
+}
+
+.send-screen-gas-input-customize {
+ color: $curious-blue;
+ font-size: 12px;
+ cursor: pointer;
+}
+
+.gas-tooltip-close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%;
+}
+
+.customize-gas-tooltip-container {
+ position: absolute;
+ bottom: 50px;
+ width: 237px;
+ height: 307px;
+ background-color: $white;
+ opacity: 1;
+ box-shadow: $alto 0 0 5px;
+ z-index: 1050;
+ padding: 13px 19px;
+ font-size: 16px;
+ border-radius: 4px;
+ font-family: "Lato";
+ font-weight: 500;
+}
+
+.gas-tooltip-arrow {
+ height: 25px;
+ width: 25px;
+ z-index: 1200;
+ background: $white;
+ position: absolute;
+ transform: rotate(45deg);
+ left: 107px;
+ top: 294px;
+ box-shadow: 2px 2px 2px $alto;
+}
+
+.customize-gas-tooltip-container input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none;
+}
+
+.customize-gas-tooltip-container input[type="number"]:hover::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none;
+}
+
+.customize-gas-tooltip {
+ position: relative;
+}
+
+.gas-tooltip {
+ display: flex;
+ justify-content: center;
+}
+
+.gas-tooltip-label {
+ font-size: 16px;
+ color: $tundora;
+}
+
+.gas-tooltip-header {
+ padding-bottom: 12px;
+}
+
+.gas-tooltip-input-label {
+ margin-bottom: 5px;
+}
+
+.gas-tooltip-input-label i {
+ color: $silver-chalice;
+ margin-left: 6px;
+}
+
+.customize-gas-input {
+ width: 178px;
+ height: 28px;
+ border: 1px solid $alto;
+ font-size: 16px;
+ color: $nile-blue;
+ padding-left: 8px;
+}
+
+.customize-gas-input-wrapper {
+ position: relative;
+}
+
+.gas-tooltip-input-detail {
+ position: absolute;
+ top: 4px;
+ right: 26px;
+ font-size: 12px;
+ color: $silver-chalice;
+}
+
+.gas-tooltip-input-arrows {
+ position: absolute;
+ top: 0;
+ right: 4px;
+ width: 17px;
+ height: 28px;
+ border: 1px solid #dadada;
+ border-left: 0;
+ display: flex;
+ flex-direction: column;
+ color: #9b9b9b;
+ font-size: .8em;
+ padding: 1px 4px;
+ cursor: pointer;
+}
+
+.token-gas {
+ &__amount {
+ display: inline-block;
+ margin-right: 4px;
+ }
+
+ &__symbol {
+ display: inline-block;
+ }
+}
+
+.send-screen {
+ &__title {
+ color: $scorpion;
+ font-size: 18px;
+ line-height: 29px;
+ }
+
+ &__subtitle {
+ margin: 10px 0 20px;
+ font-size: 14px;
+ line-height: 24px;
+ }
+
+ &__send-button,
+ &__cancel-button {
+ width: 163px;
+ text-align: center;
+ }
+
+ &__send-button__disabled {
+ opacity: .5;
+ cursor: auto;
+ }
+}
+
+.send-token {
+ display: flex;
+ flex-flow: column nowrap;
+ z-index: 25;
+ font-family: Roboto;
+
+ &__content {
+ width: 498px;
+ height: 605px;
+ background-color: #fff;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .08);
+ padding: 46px 40.5px 26px;
+ position: relative;
+ // top: -26px;
+ align-items: center;
+ display: flex;
+ flex-flow: column nowrap;
+ flex: 1 0 auto;
+
+ @media screen and (max-width: $break-small) {
+ top: 0;
+ width: 100%;
+ box-shadow: none;
+ padding: 12px;
+ }
+ }
+
+ .identicon {
+ position: absolute;
+ top: -35px;
+ z-index: 25;
+
+ @media screen and (max-width: $break-small) {
+ position: relative;
+ top: 0;
+ flex: 0 0 auto;
+ }
+ }
+
+ &__title {
+ color: $scorpion;
+ font-size: 18px;
+ line-height: 29px;
+ }
+
+ &__description,
+ &__balance-text,
+ &__token-symbol {
+ margin-top: 10px;
+ font-size: 14px;
+ line-height: 24px;
+ text-align: center;
+ }
+
+ &__token-balance {
+ font-size: 40px;
+ line-height: 40px;
+ margin-top: 13px;
+
+ .token-balance__amount {
+ padding-right: 12px;
+ }
+ }
+
+ &__button-group {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ flex: 0 0 auto;
+
+ @media screen and (max-width: $break-small) {
+ margin-top: 24px;
+ }
+
+ button {
+ width: 163px;
+ }
+ }
+}
+
+.confirm-send-token {
+ &__hero-amount-wrapper {
+ width: 100%;
+ }
+}
+
+.send-v2 {
+ &__container {
+ // height: 701px;
+ width: 380px;
+ border-radius: 8px;
+ background-color: $white;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .08);
+ display: flex;
+ flex-flow: column nowrap;
+ z-index: 25;
+ align-items: center;
+ font-family: Roboto;
+ position: relative;
+
+ @media screen and (max-width: $break-small) {
+ width: 100%;
+ top: 0;
+ box-shadow: none;
+ flex: 1 1 auto;
+ }
+ }
+
+ &__send-header-icon-container {
+ z-index: 25;
+
+ @media screen and (max-width: $break-small) {
+ position: relative;
+ top: 0;
+ }
+ }
+
+ &__send-header-icon {
+ border-radius: 50%;
+ width: 48px;
+ height: 48px;
+ border: 1px solid $alto;
+ z-index: 25;
+ padding: 4px;
+ background-color: $white;
+ }
+
+ &__send-arrow-icon {
+ color: #f28930;
+ transform: rotate(-45deg);
+ position: absolute;
+ top: -2px;
+ left: 0;
+ font-size: 1.12em;
+ }
+
+ &__arrow-background {
+ background-color: $white;
+ height: 14px;
+ width: 14px;
+ position: absolute;
+ top: 52px;
+ left: 199px;
+ border-radius: 50%;
+ z-index: 100;
+
+ @media screen and (max-width: $break-small) {
+ top: 36px;
+ }
+ }
+
+ &__header {
+ height: 88px;
+ width: 380px;
+ background-color: $athens-grey;
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ @media screen and (max-width: $break-small) {
+ height: 59px;
+ width: 100vw;
+ }
+ }
+
+ &__header-tip {
+ height: 25px;
+ width: 25px;
+ background: $athens-grey;
+ position: absolute;
+ transform: rotate(45deg);
+ left: 178px;
+ top: 75px;
+
+ @media screen and (max-width: $break-small) {
+ top: 46px;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ }
+ }
+
+ &__title {
+ color: $scorpion;
+ font-size: 22px;
+ line-height: 29px;
+ text-align: center;
+ margin-top: 25px;
+ }
+
+ &__copy {
+ color: $gray;
+ font-size: 14px;
+ font-weight: 300;
+ line-height: 19px;
+ text-align: center;
+ margin-top: 10px;
+ width: 287px;
+ }
+
+ &__error {
+ font-size: 12px;
+ line-height: 12px;
+ left: 8px;
+ color: $red;
+ }
+
+ &__error-border {
+ color: $red;
+ }
+
+ &__form {
+ padding: 13px 0;
+ width: 100%;
+ overflow-y: auto;
+
+ @media screen and (max-width: $break-small) {
+ padding: 13px 0;
+ margin: 0;
+ overflow-y: auto;
+ flex: 1 1 auto;
+ }
+ }
+
+ &__form-header,
+ &__form-header-copy {
+ width: 100%;
+ display: flex;
+ flex-flow: column;
+ align-items: center;
+ }
+
+ &__form-row {
+ margin: 14.5px 18px 0px;
+ position: relative;
+ display: flex;
+ flex-flow: row;
+ flex: 1 0 auto;
+ justify-content: space-between;
+ }
+
+ &__form-field {
+ flex: 1 1 auto;
+
+ .currency-display {
+ color: $tundora;
+
+ &__currency-symbol {
+ color: $tundora;
+ }
+
+ &__converted-value,
+ &__converted-currency {
+ color: $tundora;
+ }
+ }
+
+ .account-list-item {
+ &__account-secondary-balance {
+ color: $tundora;
+ }
+ }
+ }
+
+ &__form-label {
+ color: $scorpion;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 22px;
+ width: 88px;
+ font-weight: 400;
+ }
+
+ &__from-dropdown {
+ height: 73px;
+ width: 100%;
+ border: 1px solid $alto;
+ border-radius: 4px;
+ background-color: $white;
+ font-family: Roboto;
+ line-height: 16px;
+ font-size: 12px;
+ color: $tundora;
+ position: relative;
+
+ &__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%;
+ }
+
+ &__list {
+ z-index: 1050;
+ position: absolute;
+ height: 220px;
+ width: 100%;
+ border: 1px solid $geyser;
+ border-radius: 4px;
+ background-color: $white;
+ box-shadow: 0 3px 6px 0 rgba(0 ,0 ,0 ,.11);
+ margin-top: 11px;
+ margin-left: -1px;
+ overflow-y: scroll;
+ }
+ }
+
+ &__to-autocomplete {
+ position: relative;
+
+ &__down-caret {
+ position: absolute;
+ top: 18px;
+ right: 12px;
+ }
+ }
+
+ &__to-autocomplete, &__memo-text-area {
+ &__input {
+ height: 54px;
+ width: 100%;
+ border: 1px solid $alto;
+ border-radius: 4px;
+ background-color: $white;
+ color: $tundora;
+ padding: 10px;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ font-weight: 300;
+ }
+ }
+
+ &__amount-max {
+ color: $curious-blue;
+ font-family: Roboto;
+ font-size: 12px;
+ left: 8px;
+ border: none;
+ cursor: pointer;
+ }
+
+ &__gas-fee-display {
+ width: 100%;
+ }
+
+ &__sliders-icon-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 24px;
+ width: 24px;
+ border: 1px solid $curious-blue;
+ border-radius: 4px;
+ background-color: $white;
+ position: absolute;
+ right: 15px;
+ top: 14px;
+ cursor: pointer;
+ font-size: 1em;
+ }
+
+ &__sliders-icon {
+ color: $curious-blue;
+ }
+
+ &__memo-text-area {
+ &__input {
+ padding: 6px 10px;
+ }
+ }
+
+ &__footer {
+ height: 92px;
+ width: 100%;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+ border-top: 1px solid $alto;
+ background: $white;
+ padding: 0 12px;
+ flex-shrink: 0;
+ }
+
+ &__next-btn,
+ &__cancel-btn {
+ width: 163px;
+ margin: 0 4px;
+ }
+
+ &__customize-gas {
+ border: 1px solid #D8D8D8;
+ border-radius: 4px;
+ background-color: #FFFFFF;
+ box-shadow: 0 2px 4px 0 rgba(0,0,0,0.14);
+ font-family: Roboto;
+ display: flex;
+ flex-flow: column;
+
+ @media screen and (max-width: $break-small) {
+ width: 100vw;
+ height: 100vh;
+ }
+
+ &__header {
+ height: 52px;
+ border-bottom: 1px solid $alto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 22px;
+
+ @media screen and (max-width: $break-small) {
+ flex: 0 0 auto;
+ }
+ }
+
+ &__title {
+ margin-left: 19.25px;
+ }
+
+ &__close::after {
+ content: '\00D7';
+ font-size: 1.8em;
+ color: $dusty-gray;
+ font-family: sans-serif;
+ cursor: pointer;
+ margin-right: 19.25px;
+ }
+
+ &__content {
+ display: flex;
+ flex-flow: column nowrap;
+ height: 100%;
+ }
+
+ &__body {
+ display: flex;
+ margin-bottom: 24px;
+
+ @media screen and (max-width: $break-small) {
+ flex-flow: column;
+ flex: 1 1 auto;
+ }
+ }
+
+ &__footer {
+ height: 75px;
+ border-top: 1px solid $alto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 22px;
+ position: relative;
+
+ @media screen and (max-width: $break-small) {
+ flex: 0 0 auto;
+ }
+ }
+
+ &__buttons {
+ display: flex;
+ justify-content: space-between;
+ width: 181.75px;
+ margin-right: 21.25px;
+ }
+
+ &__revert, &__cancel, &__save, &__save__error {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ }
+
+ &__revert {
+ color: $silver-chalice;
+ font-size: 16px;
+ margin-left: 21.25px;
+ }
+
+ &__cancel, &__save, &__save__error {
+ height: 34.64px;
+ width: 85.74px;
+ border: 1px solid $dusty-gray;
+ border-radius: 2px;
+ font-family: 'DIN OT';
+ font-size: 12px;
+ color: $dusty-gray;
+ }
+
+ &__save__error {
+ opacity: 0.5;
+ cursor: auto;
+ }
+
+ &__error-message {
+ display: block;
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ color: $red;
+ }
+ }
+
+ &__gas-modal-card {
+ width: 360px;
+ display: flex;
+ flex-flow: column;
+ align-items: flex-start;
+ padding-left: 20px;
+
+ &__title {
+ height: 26px;
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 20px;
+ font-weight: 300;
+ line-height: 26px;
+ margin-top: 17px;
+ }
+
+ &__copy {
+ height: 38px;
+ width: 314px;
+ color: $tundora;
+ font-family: Roboto;
+ font-size: 14px;
+ line-height: 19px;
+ margin-top: 17px;
+ }
+
+ .customize-gas-input-wrapper {
+ margin-top: 17px;
+ }
+
+ .customize-gas-input {
+ height: 54px;
+ width: 315px;
+ border: 1px solid $geyser;
+ background-color: $white;
+ padding-left: 15px;
+ }
+
+ .gas-tooltip-input-arrows {
+ width: 32px;
+ height: 54px;
+ border-left: 1px solid #dadada;
+ font-size: 18px;
+ color: $tundora;
+ right: 0px;
+ padding: 1px 4px;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ }
+
+ input[type="number"]::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none;
+ }
+
+ input[type="number"]:hover::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none;
+ }
+ }
+}
diff --git a/ui/app/css/itcss/components/settings.scss b/ui/app/css/itcss/components/settings.scss
new file mode 100644
index 000000000..d60ebd934
--- /dev/null
+++ b/ui/app/css/itcss/components/settings.scss
@@ -0,0 +1,206 @@
+.settings {
+ position: relative;
+ background: $white;
+ display: flex;
+ flex-flow: column nowrap;
+ height: auto;
+ overflow: auto;
+}
+
+.settings__header {
+ padding: 25px;
+}
+
+.settings__close-button::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: $dusty-gray;
+ position: absolute;
+ top: 25px;
+ right: 30px;
+ cursor: pointer;
+}
+
+.settings__error {
+ padding-bottom: 20px;
+ text-align: center;
+ color: $crimson;
+}
+
+.settings__content {
+ padding: 0 25px;
+}
+
+.settings__content-row {
+ display: flex;
+ flex-direction: row;
+ padding: 10px 0 20px;
+
+ @media screen and (max-width: 575px) {
+ flex-direction: column;
+ padding: 10px 0;
+ }
+}
+
+.settings__content-item {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ padding: 0 5px;
+ height: 71px;
+
+ @media screen and (max-width: 575px) {
+ height: initial;
+ padding: 5px 0;
+ }
+
+ &--without-height {
+ height: initial;
+ }
+}
+
+.settings__content-item-col {
+ max-width: 300px;
+ display: flex;
+ flex-direction: column;
+
+ @media screen and (max-width: 575px) {
+ max-width: 100%;
+ width: 100%;
+ }
+}
+
+.settings__content-description {
+ font-size: 14px;
+ color: $dusty-gray;
+ padding-top: 5px;
+}
+
+.settings__input {
+ padding-left: 10px;
+ font-size: 14px;
+ height: 40px;
+ border: 1px solid $alto;
+}
+
+.settings__input::-webkit-input-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+}
+
+.settings__input::-moz-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+}
+
+.settings__input:-ms-input-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+}
+
+.settings__input:-moz-placeholder {
+ font-weight: 100;
+ color: $dusty-gray;
+}
+
+.settings__provider-wrapper {
+ font-size: 16px;
+ border: 1px solid $alto;
+ border-radius: 2px;
+ padding: 15px;
+ background-color: $white;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.settings__provider-icon {
+ height: 10px;
+ width: 10px;
+ margin-right: 10px;
+ border-radius: 10px;
+}
+
+.settings__rpc-save-button {
+ align-self: flex-end;
+ padding: 5px;
+ text-transform: uppercase;
+ color: $dusty-gray;
+ cursor: pointer;
+}
+
+.settings__clear-button {
+ font-size: 16px;
+ border: 1px solid $curious-blue;
+ color: $curious-blue;
+ border-radius: 2px;
+ padding: 18px;
+ background-color: $white;
+ text-transform: uppercase;
+}
+
+.settings__clear-button--red {
+ border: 1px solid $monzo;
+ color: $monzo;
+}
+
+.settings__clear-button--orange {
+ border: 1px solid rgba(247, 134, 28, 1);
+ color: rgba(247, 134, 28, 1);
+}
+
+.settings__info-logo-wrapper {
+ height: 80px;
+ margin-bottom: 20px;
+}
+
+.settings__info-logo {
+ max-height: 100%;
+ max-width: 100%;
+}
+
+.settings__info-item {
+ padding: 10px 0;
+}
+
+.settings__info-link-header {
+ padding-bottom: 15px;
+
+ @media screen and (max-width: 575px) {
+ padding-bottom: 5px;
+ }
+}
+
+.settings__info-link-item {
+ padding: 15px 0;
+
+ @media screen and (max-width: 575px) {
+ padding: 5px 0;
+ }
+}
+
+.settings__info-version-number {
+ padding-top: 5px;
+ font-size: 13px;
+ color: $dusty-gray;
+}
+
+.settings__info-about {
+ color: $dusty-gray;
+ margin-bottom: 15px;
+}
+
+.settings__info-link {
+ color: $curious-blue;
+}
+
+.settings__info-separator {
+ margin: 15px 0;
+ width: 80px;
+ border-color: $alto;
+ border: none;
+ height: 1px;
+ background-color: $alto;
+ color: $alto;
+}
diff --git a/ui/app/css/itcss/components/simple-dropdown.scss b/ui/app/css/itcss/components/simple-dropdown.scss
new file mode 100644
index 000000000..a21095a3e
--- /dev/null
+++ b/ui/app/css/itcss/components/simple-dropdown.scss
@@ -0,0 +1,65 @@
+.simple-dropdown {
+ height: 56px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ border: 1px solid $alto;
+ border-radius: 4px;
+ background-color: $white;
+ font-size: 16px;
+ color: #4d4d4d;
+ cursor: pointer;
+ position: relative;
+}
+
+.simple-dropdown__caret {
+ color: $silver;
+ padding: 0 10px;
+}
+
+.simple-dropdown__selected {
+ flex-grow: 1;
+ padding: 0 15px;
+}
+
+.simple-dropdown__options {
+ z-index: 1050;
+ position: absolute;
+ height: 220px;
+ width: 100%;
+ border: 1px solid #d2d8dd;
+ border-radius: 4px;
+ background-color: #fff;
+ -webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .11);
+ box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .11);
+ margin-top: 10px;
+ overflow-y: scroll;
+ left: 0;
+ top: 100%;
+}
+
+.simple-dropdown__option {
+ padding: 10px;
+
+ &:hover {
+ background-color: $gallery;
+ }
+}
+
+.simple-dropdown__option--selected {
+ background-color: $alto;
+
+ &:hover {
+ background-color: $alto;
+ cursor: default;
+ }
+}
+
+.simple-dropdown__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ width: 100%;
+ height: 100%;
+}
diff --git a/ui/app/css/itcss/components/tab-bar.scss b/ui/app/css/itcss/components/tab-bar.scss
new file mode 100644
index 000000000..4f3077974
--- /dev/null
+++ b/ui/app/css/itcss/components/tab-bar.scss
@@ -0,0 +1,23 @@
+.tab-bar {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-end;
+}
+
+.tab-bar__tab {
+ min-width: 0;
+ flex: 0 0 auto;
+ padding: 15px 25px;
+ border-bottom: 1px solid $alto;
+ box-sizing: border-box;
+ font-size: 18px;
+}
+
+.tab-bar__tab--active {
+ border-color: $black;
+}
+
+.tab-bar__grow-tab {
+ flex-grow: 1;
+}
diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss
new file mode 100644
index 000000000..9dc4f1055
--- /dev/null
+++ b/ui/app/css/itcss/components/token-list.scss
@@ -0,0 +1,111 @@
+$wallet-balance-breakpoint: 890px;
+$wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$wallet-balance-breakpoint})";
+
+.token-list-item {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ padding: 20px 24px;
+ cursor: pointer;
+ transition: linear 200ms;
+ background-color: rgba($wallet-balance-bg, 0);
+ position: relative;
+
+ &__token-balance {
+ font-size: 1.5rem;
+
+ @media #{$wallet-balance-breakpoint-range} {
+ font-size: 95%;
+ }
+ }
+
+ &__fiat-amount {
+ margin-top: .25%;
+ font-size: 105%;
+ text-transform: uppercase;
+
+ @media #{$wallet-balance-breakpoint-range} {
+ font-size: 95%;
+ }
+ }
+
+ @media #{$wallet-balance-breakpoint-range} {
+ padding: 10% 4%;
+ }
+
+ &--active {
+ background-color: $manatee;
+ color: $white;
+ }
+
+ &__identicon {
+ margin-right: 15px;
+ border: '1px solid #dedede';
+ min-width: 50px;
+
+ @media #{$wallet-balance-breakpoint-range} {
+ margin-right: 4%;
+ }
+ }
+
+ &__balance-ellipsis {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ }
+
+ &__ellipsis {
+ line-height: 45px;
+ margin-left: 5px;
+ }
+
+ &__balance-wrapper {
+ flex: 1 1 auto;
+ }
+}
+
+.token-menu-dropdown {
+ height: 55px;
+ width: 80%;
+ border-radius: 4px;
+ background-color: rgba(0, 0, 0, .82);
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5);
+ position: absolute;
+ top: 60px;
+ right: 25px;
+ z-index: 2000;
+
+ @media #{$wallet-balance-breakpoint-range} {
+ right: 18px;
+ }
+
+ &__close-area {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 2100;
+ width: 100%;
+ height: 100%;
+ cursor: default;
+ }
+
+ &__container {
+ padding: 16px;
+ z-index: 2200;
+ position: relative;
+ }
+
+ &__options {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ }
+
+ &__option {
+ color: $white;
+ font-family: Roboto;
+ font-size: 16px;
+ line-height: 21px;
+ text-align: center;
+ }
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/tooltip.scss b/ui/app/css/itcss/components/tooltip.scss
new file mode 100644
index 000000000..78325865e
--- /dev/null
+++ b/ui/app/css/itcss/components/tooltip.scss
@@ -0,0 +1,7 @@
+.metamask-tooltip {
+ padding: 5px !important;
+}
+
+// needed for react-tippy
+// copied from node_modules/react-tippy/dist/tippy.css
+.tippy-touch{cursor:pointer!important}.tippy-notransition{transition:none!important}.tippy-popper{max-width:400px;-webkit-perspective:800px;perspective:800px;z-index:9999;outline:0;transition-timing-function:cubic-bezier(.165,.84,.44,1);pointer-events:none}.tippy-popper.html-template{max-width:96%;max-width:calc(100% - 20px)}.tippy-popper[x-placement^=top] [x-arrow]{border-top:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;bottom:-7px;margin:0 9px}.tippy-popper[x-placement^=top] [x-arrow].arrow-small{border-top:5px solid #333;border-right:5px solid transparent;border-left:5px solid transparent;bottom:-5px}.tippy-popper[x-placement^=top] [x-arrow].arrow-big{border-top:10px solid #333;border-right:10px solid transparent;border-left:10px solid transparent;bottom:-10px}.tippy-popper[x-placement^=top] [x-circle]{-webkit-transform-origin:0 33%;transform-origin:0 33%}.tippy-popper[x-placement^=top] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-55%);transform:scale(1) translate(-50%,-55%);opacity:1}.tippy-popper[x-placement^=top] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow]{border-top:7px solid #fff;border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-top:5px solid #fff;border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-top:10px solid #fff;border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow]{border-top:7px solid rgba(0,0,0,.7);border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-top:5px solid rgba(0,0,0,.7);border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=top] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-top:10px solid rgba(0,0,0,.7);border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=top] [data-animation=perspective]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateY(-10px) rotateX(0);transform:translateY(-10px) rotateX(0)}.tippy-popper[x-placement^=top] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateY(0) rotateX(90deg);transform:translateY(0) rotateX(90deg)}.tippy-popper[x-placement^=top] [data-animation=fade].enter{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=fade].leave{opacity:0;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift].enter{opacity:1;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift].leave{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=top] [data-animation=scale].enter{opacity:1;-webkit-transform:translateY(-10px) scale(1);transform:translateY(-10px) scale(1)}.tippy-popper[x-placement^=top] [data-animation=scale].leave{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=bottom] [x-arrow]{border-bottom:7px solid #333;border-right:7px solid transparent;border-left:7px solid transparent;top:-7px;margin:0 9px}.tippy-popper[x-placement^=bottom] [x-arrow].arrow-small{border-bottom:5px solid #333;border-right:5px solid transparent;border-left:5px solid transparent;top:-5px}.tippy-popper[x-placement^=bottom] [x-arrow].arrow-big{border-bottom:10px solid #333;border-right:10px solid transparent;border-left:10px solid transparent;top:-10px}.tippy-popper[x-placement^=bottom] [x-circle]{-webkit-transform-origin:0 -50%;transform-origin:0 -50%}.tippy-popper[x-placement^=bottom] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-45%);transform:scale(1) translate(-50%,-45%);opacity:1}.tippy-popper[x-placement^=bottom] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-5%);transform:scale(.15) translate(-50%,-5%);opacity:0}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow]{border-bottom:7px solid #fff;border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-bottom:5px solid #fff;border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-bottom:10px solid #fff;border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow]{border-bottom:7px solid rgba(0,0,0,.7);border-right:7px solid transparent;border-left:7px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-bottom:5px solid rgba(0,0,0,.7);border-right:5px solid transparent;border-left:5px solid transparent}.tippy-popper[x-placement^=bottom] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-bottom:10px solid rgba(0,0,0,.7);border-right:10px solid transparent;border-left:10px solid transparent}.tippy-popper[x-placement^=bottom] [data-animation=perspective]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateY(10px) rotateX(0);transform:translateY(10px) rotateX(0)}.tippy-popper[x-placement^=bottom] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateY(0) rotateX(-90deg);transform:translateY(0) rotateX(-90deg)}.tippy-popper[x-placement^=bottom] [data-animation=fade].enter{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=fade].leave{opacity:0;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift].enter{opacity:1;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift].leave{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=bottom] [data-animation=scale].enter{opacity:1;-webkit-transform:translateY(10px) scale(1);transform:translateY(10px) scale(1)}.tippy-popper[x-placement^=bottom] [data-animation=scale].leave{opacity:0;-webkit-transform:translateY(0) scale(0);transform:translateY(0) scale(0)}.tippy-popper[x-placement^=left] [x-arrow]{border-left:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;right:-7px;margin:6px 0}.tippy-popper[x-placement^=left] [x-arrow].arrow-small{border-left:5px solid #333;border-top:5px solid transparent;border-bottom:5px solid transparent;right:-5px}.tippy-popper[x-placement^=left] [x-arrow].arrow-big{border-left:10px solid #333;border-top:10px solid transparent;border-bottom:10px solid transparent;right:-10px}.tippy-popper[x-placement^=left] [x-circle]{-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=left] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-50%);transform:scale(1) translate(-50%,-50%);opacity:1}.tippy-popper[x-placement^=left] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow]{border-left:7px solid #fff;border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-left:5px solid #fff;border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-left:10px solid #fff;border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow]{border-left:7px solid rgba(0,0,0,.7);border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-left:5px solid rgba(0,0,0,.7);border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=left] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-left:10px solid rgba(0,0,0,.7);border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=left] [data-animation=perspective]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateX(-10px) rotateY(0);transform:translateX(-10px) rotateY(0)}.tippy-popper[x-placement^=left] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateX(0) rotateY(-90deg);transform:translateX(0) rotateY(-90deg)}.tippy-popper[x-placement^=left] [data-animation=fade].enter{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=fade].leave{opacity:0;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift].enter{opacity:1;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift].leave{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=left] [data-animation=scale].enter{opacity:1;-webkit-transform:translateX(-10px) scale(1);transform:translateX(-10px) scale(1)}.tippy-popper[x-placement^=left] [data-animation=scale].leave{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-popper[x-placement^=right] [x-arrow]{border-right:7px solid #333;border-top:7px solid transparent;border-bottom:7px solid transparent;left:-7px;margin:6px 0}.tippy-popper[x-placement^=right] [x-arrow].arrow-small{border-right:5px solid #333;border-top:5px solid transparent;border-bottom:5px solid transparent;left:-5px}.tippy-popper[x-placement^=right] [x-arrow].arrow-big{border-right:10px solid #333;border-top:10px solid transparent;border-bottom:10px solid transparent;left:-10px}.tippy-popper[x-placement^=right] [x-circle]{-webkit-transform-origin:-50% 0;transform-origin:-50% 0}.tippy-popper[x-placement^=right] [x-circle].enter{-webkit-transform:scale(1) translate(-50%,-50%);transform:scale(1) translate(-50%,-50%);opacity:1}.tippy-popper[x-placement^=right] [x-circle].leave{-webkit-transform:scale(.15) translate(-50%,-50%);transform:scale(.15) translate(-50%,-50%);opacity:0}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-circle]{background-color:#fff}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow]{border-right:7px solid #fff;border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow].arrow-small{border-right:5px solid #fff;border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.light-theme [x-arrow].arrow-big{border-right:10px solid #fff;border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-circle]{background-color:rgba(0,0,0,.7)}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow]{border-right:7px solid rgba(0,0,0,.7);border-top:7px solid transparent;border-bottom:7px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow].arrow-small{border-right:5px solid rgba(0,0,0,.7);border-top:5px solid transparent;border-bottom:5px solid transparent}.tippy-popper[x-placement^=right] .tippy-tooltip.transparent-theme [x-arrow].arrow-big{border-right:10px solid rgba(0,0,0,.7);border-top:10px solid transparent;border-bottom:10px solid transparent}.tippy-popper[x-placement^=right] [data-animation=perspective]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=perspective].enter{opacity:1;-webkit-transform:translateX(10px) rotateY(0);transform:translateX(10px) rotateY(0)}.tippy-popper[x-placement^=right] [data-animation=perspective].leave{opacity:0;-webkit-transform:translateX(0) rotateY(90deg);transform:translateX(0) rotateY(90deg)}.tippy-popper[x-placement^=right] [data-animation=fade].enter{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=fade].leave{opacity:0;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift].enter{opacity:1;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift].leave{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=right] [data-animation=scale].enter{opacity:1;-webkit-transform:translateX(10px) scale(1);transform:translateX(10px) scale(1)}.tippy-popper[x-placement^=right] [data-animation=scale].leave{opacity:0;-webkit-transform:translateX(0) scale(0);transform:translateX(0) scale(0)}.tippy-popper .tippy-tooltip.transparent-theme{background-color:rgba(0,0,0,.7)}.tippy-popper .tippy-tooltip.transparent-theme[data-animatefill]{background-color:transparent}.tippy-popper .tippy-tooltip.light-theme{color:#26323d;box-shadow:0 4px 20px 4px rgba(0,20,60,.1),0 4px 80px -8px rgba(0,20,60,.2);background-color:#fff}.tippy-popper .tippy-tooltip.light-theme[data-animatefill]{background-color:transparent}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:.95rem;padding:.4rem .8rem;text-align:center;will-change:transform;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#333}.tippy-tooltip--small{padding:.25rem .5rem;font-size:.8rem}.tippy-tooltip--big{padding:.6rem 1.2rem;font-size:1.2rem}.tippy-tooltip[data-animatefill]{overflow:hidden;background-color:transparent}.tippy-tooltip[data-interactive]{pointer-events:auto}.tippy-tooltip[data-inertia]{transition-timing-function:cubic-bezier(.53,2,.36,.85)}.tippy-tooltip [x-arrow]{position:absolute;width:0;height:0}.tippy-tooltip [x-circle]{position:absolute;will-change:transform;background-color:#333;border-radius:50%;width:130%;width:calc(110% + 2rem);left:50%;top:50%;z-index:-1;overflow:hidden;transition:all ease}.tippy-tooltip [x-circle]:before{content:"";padding-top:90%;float:left}@media (max-width:450px){.tippy-popper{max-width:96%;max-width:calc(100% - 20px)}}
diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss
new file mode 100644
index 000000000..c3df493df
--- /dev/null
+++ b/ui/app/css/itcss/components/transaction-list.scss
@@ -0,0 +1,264 @@
+.tx-list-container {
+ height: 87.5%;
+
+ @media screen and (min-width: $break-large) {
+ overflow-y: scroll;
+ }
+}
+
+.tx-list-header-wrapper {
+ flex: 0 0 auto;
+}
+
+.tx-list-header {
+ text-transform: capitalize;
+}
+
+@media screen and (max-width: $break-small) {
+ .tx-list-header-wrapper {
+ margin-top: .2em;
+ margin-bottom: .6em;
+ // TODO: Resolve Layout Conflicst in Wallet View
+ // - This fixes txlist "transactions" title dispay
+ // margin-top: 0.2em;
+ // margin-bottom: 0.6em;
+ justify-content: center;
+ flex: 0 0 auto;
+ }
+
+ .tx-list-header {
+ align-self: center;
+ font-size: 12px;
+ color: $dusty-gray;
+ font-family: Roboto;
+ text-transform: uppercase;
+ }
+}
+
+@media screen and (min-width: $break-large) {
+ .tx-list-header {
+ font-size: 16px;
+ margin: 1.1em 2.37em .8em;
+ }
+
+ .tx-list-container::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+.tx-list-content-divider {
+ height: 1px;
+ background: rgb(231, 231, 231);
+ flex: 0 0 1px;
+
+ @media screen and (max-width: $break-small) {
+ margin: .1em 0;
+ }
+
+ @media screen and (min-width: $break-large) {
+ margin: .1em 2.37em;
+ }
+}
+
+.tx-list-item-wrapper {
+ flex: 1 1 auto;
+ width: 0;
+ align-items: stretch;
+ justify-content: flex-start;
+ display: flex;
+ flex-flow: column nowrap;
+
+ @media screen and (max-width: $break-small) {
+ padding: 0 1.3em .8em;
+ }
+
+ @media screen and (min-width: $break-large) {
+ padding-bottom: 8px;
+ }
+}
+
+.tx-list-clickable {
+ cursor: pointer;
+
+ &:hover {
+ background: rgba($alto, .2);
+ }
+}
+
+.tx-list-pending-item-container {
+ cursor: pointer;
+ opacity: .5;
+}
+
+.tx-list-date-wrapper {
+ margin-top: 6px;
+ flex: 1 1 auto;
+}
+
+.tx-list-content-wrapper {
+ align-items: stretch;
+ margin-bottom: 4px;
+ flex: 1 0 auto;
+ width: 100%;
+ display: flex;
+ flex-flow: row nowrap;
+
+ @media screen and (max-width: $break-small) {
+ font-size: 12px;
+
+ .tx-list-status {
+ font-size: 12px !important;
+ }
+
+ .tx-list-account {
+ font-size: 14px !important;
+ }
+
+ .tx-list-value {
+ font-size: 14px;
+ line-height: 18px;
+ }
+
+ .tx-list-fiat-value {
+ font-size: 12px;
+ line-height: 22px;
+ }
+ }
+}
+
+.tx-list-date {
+ color: $dusty-gray;
+ font-size: 12px;
+ font-family: Roboto;
+}
+
+.tx-list-identicon-wrapper {
+ align-self: center;
+ flex: 0 0 auto;
+ margin-right: 16px;
+}
+
+.tx-list-account-and-status-wrapper {
+ display: flex;
+ flex: 1 1 auto;
+ flex-flow: row wrap;
+ width: 0;
+
+ @media screen and (max-width: $break-small) {
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: flex-start;
+ align-self: center;
+
+ .tx-list-account-wrapper {
+ height: 18px;
+
+ .tx-list-account {
+ line-height: 14px;
+ }
+ }
+ }
+
+ @media screen and (min-width: $break-large) {
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+
+ .tx-list-account-wrapper {
+ flex: 1.3 2 auto;
+ min-width: 153px;
+ }
+
+ .tx-list-status-wrapper {
+ flex: 6 6 auto;
+ }
+ }
+
+ .tx-list-account {
+ font-size: 16px;
+ color: $scorpion;
+ }
+
+ .tx-list-status {
+ color: $dusty-gray;
+ font-size: 16px;
+ text-transform: capitalize;
+ }
+
+ .tx-list-status--rejected,
+ .tx-list-status--failed {
+ color: $monzo;
+ }
+}
+
+.tx-list-item {
+ border-top: 1px solid rgb(231, 231, 231);
+ flex: 0 0 auto;
+ display: flex;
+ flex-flow: row nowrap;
+
+ @media screen and (max-width: $break-small) {
+ // margin: 0 1.3em .95em; !important
+ }
+
+ @media screen and (min-width: $break-large) {
+ padding: 0 2.37em;
+ }
+
+ &:last-of-type {
+ border-bottom: 1px solid rgb(231, 231, 231);
+ margin-bottom: 32px;
+ }
+
+ &__wrapper {
+ align-self: center;
+ flex: 2 2 auto;
+ color: $dusty-gray;
+
+ .tx-list-value {
+ font-size: 16px;
+ text-align: right;
+ }
+
+ .tx-list-value--confirmed {
+ color: $caribbean-green;
+ }
+
+ .tx-list-fiat-value {
+ font-size: 12px;
+ text-align: right;
+ }
+ }
+
+ &--empty {
+ text-align: center;
+ border-bottom: none !important;
+ padding: 16px;
+ }
+}
+
+.tx-list-details-wrapper {
+ overflow: hidden;
+ flex: 0 0 35%;
+}
+
+.tx-list-value {
+ font-size: 16px;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.tx-list-fiat-value {
+ font-size: 12px;
+ line-height: initial;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.tx-list-value--confirmed {
+ color: $caribbean-green;
+}
diff --git a/ui/app/css/itcss/components/wallet-balance.scss b/ui/app/css/itcss/components/wallet-balance.scss
new file mode 100644
index 000000000..293771550
--- /dev/null
+++ b/ui/app/css/itcss/components/wallet-balance.scss
@@ -0,0 +1,74 @@
+$wallet-balance-bg: #e7e7e7;
+$wallet-balance-breakpoint: 890px;
+$wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$wallet-balance-breakpoint})";
+
+.wallet-balance-wrapper {
+ flex: 0 0 auto;
+ transition: linear 200ms;
+ background: rgba($wallet-balance-bg, 0);
+
+ &--active {
+ background: $manatee;
+ color: $white;
+ }
+}
+
+.wallet-balance {
+ background: inherit;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+ flex: 0 0 auto;
+ cursor: pointer;
+ border-top: 1px solid $wallet-balance-bg;
+
+ .balance-container {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ margin: 20px 24px;
+ flex-direction: row;
+ flex-grow: 3;
+
+ @media #{$wallet-balance-breakpoint-range} {
+ margin: 10% 4%;
+ }
+ }
+
+ .balance-display {
+ margin-left: 15px;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ .token-amount {
+ font-size: 1.5rem;
+ }
+
+ .fiat-amount {
+ margin-top: .25%;
+ font-size: 105%;
+ }
+
+ @media #{$wallet-balance-breakpoint-range} {
+ margin-left: 4%;
+
+ .token-amount {
+ font-size: 105%;
+ }
+
+ .fiat-amount {
+ font-size: 95%;
+ }
+ }
+ }
+}
+
+.balance-icon {
+ border-radius: 25px;
+ width: 50px;
+ height: 50px;
+ border: 1px solid $alto;
+ padding: 5px;
+ background: $white;
+}
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
new file mode 100644
index 000000000..9b3d7475b
--- /dev/null
+++ b/ui/app/css/itcss/generic/index.scss
@@ -0,0 +1,204 @@
+/*
+ Generic
+ */
+
+@import './reset.scss';
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ font-family: Roboto, Arial;
+ color: #4d4d4d;
+ font-weight: 300;
+ line-height: 1.4em;
+ background: #f7f7f7;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ min-height: 500px;
+}
+
+.app-root {
+ overflow: hidden;
+ position: relative;
+}
+
+.app-primary {
+ display: flex;
+}
+
+input:focus,
+textarea:focus {
+ outline: none;
+}
+
+/* stylelint-disable */
+#app-content {
+ overflow-x: hidden;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ @media screen and (max-width: $break-small) {
+ background-color: $white;
+ }
+}
+/* stylelint-enable */
+
+a {
+ text-decoration: none;
+ color: inherit;
+}
+
+a:hover {
+ color: #df6b0e;
+}
+
+input.large-input,
+textarea.large-input {
+ padding: 8px;
+}
+
+input.large-input {
+ height: 36px;
+}
+
+.page-container {
+ width: 400px;
+ background-color: $white;
+ box-shadow: 0 0 7px 0 rgba(0, 0, 0, .08);
+ z-index: 25;
+ display: flex;
+ flex-flow: column;
+
+ &__header {
+ display: flex;
+ flex-flow: column;
+ border-bottom: 1px solid $geyser;
+ padding: 1.15rem 0.95rem;
+ flex: 0 0 auto;
+ background: $alabaster;
+ position: relative;
+ }
+
+ &__header-close::after {
+ content: '\00D7';
+ font-size: 40px;
+ color: $tundora;
+ position: absolute;
+ top: 21.5px;
+ right: 28.5px;
+ cursor: pointer;
+ }
+
+ &__footer {
+ display: flex;
+ flex-flow: row;
+ justify-content: center;
+ border-top: 1px solid $geyser;
+ padding: 1.6rem;
+ flex: 0 0 auto;
+
+ .btn-clear,
+ .btn-cancel {
+ font-size: 1rem;
+ }
+ }
+
+ &__footer-button {
+ width: 165px;
+ height: 60px;
+ font-size: 1rem;
+ text-transform: uppercase;
+ margin-right: 1rem;
+ border-radius: 2px;
+
+ &:last-of-type {
+ margin-right: 0;
+ }
+ }
+
+ &__title {
+ color: $black;
+ font-family: Roboto;
+ font-size: 2rem;
+ font-weight: 500;
+ line-height: initial;
+ }
+
+ &__subtitle {
+ padding-top: .5rem;
+ line-height: initial;
+ font-size: .9rem;
+ color: $gray;
+ }
+
+ &__tabs {
+ padding: 0 1.3rem;
+ display: flex;
+ }
+
+ &__tab {
+ min-width: 5rem;
+ padding: .2rem .8rem .9rem;
+ color: $dusty-gray;
+ font-family: Roboto;
+ font-size: 1.1rem;
+ line-height: initial;
+ text-align: center;
+ cursor: pointer;
+ border-bottom: none;
+ margin-right: 1rem;
+
+ &:hover {
+ color: $black;
+ }
+
+ &:last-of-type {
+ margin-right: 0;
+ }
+
+ &--selected {
+ color: $curious-blue;
+ border-bottom: 3px solid $curious-blue;
+
+ &:hover {
+ color: $curious-blue;
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 250px) {
+ .page-container {
+ &__footer {
+ flex-flow: column-reverse;
+ }
+
+ &__footer-button {
+ width: 100%;
+ margin-bottom: 1rem;
+ margin-right: 0;
+
+ &:first-of-type {
+ margin-bottom: 0;
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 575px) {
+ .page-container {
+ height: 100%;
+ width: 100%;
+ overflow-y: auto;
+ background-color: $white;
+ }
+}
diff --git a/ui/app/css/itcss/generic/reset.scss b/ui/app/css/itcss/generic/reset.scss
new file mode 100644
index 000000000..e054d533e
--- /dev/null
+++ b/ui/app/css/itcss/generic/reset.scss
@@ -0,0 +1,147 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ /* stylelint-disable */
+ font: inherit;
+ /* stylelint-enable */
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+
+/* stylelint-disable */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+ol,
+ul {
+ list-style: none;
+}
+
+blockquote,
+q {
+ quotes: none;
+}
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+button {
+ border-style: none;
+ cursor: pointer;
+}
+
+/* stylelint-enable */
diff --git a/ui/app/css/itcss/objects/index.scss b/ui/app/css/itcss/objects/index.scss
new file mode 100644
index 000000000..220775682
--- /dev/null
+++ b/ui/app/css/itcss/objects/index.scss
@@ -0,0 +1 @@
+// Objects
diff --git a/ui/app/css/itcss/settings/index.scss b/ui/app/css/itcss/settings/index.scss
new file mode 100644
index 000000000..58a7ca7b7
--- /dev/null
+++ b/ui/app/css/itcss/settings/index.scss
@@ -0,0 +1,3 @@
+@import './variables.scss';
+
+@import './typography.scss';
diff --git a/ui/app/css/itcss/settings/typography.scss b/ui/app/css/itcss/settings/typography.scss
new file mode 100644
index 000000000..ac8c41336
--- /dev/null
+++ b/ui/app/css/itcss/settings/typography.scss
@@ -0,0 +1,71 @@
+@import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900');
+
+@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css');
+
+@font-face {
+ font-family: 'Montserrat Regular';
+ src: url('/fonts/Montserrat/Montserrat-Regular.woff') format('woff');
+ src: url('/fonts/Montserrat/Montserrat-Regular.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+ font-size: 'small';
+}
+
+@font-face {
+ font-family: 'Montserrat Bold';
+ src: url('/fonts/Montserrat/Montserrat-Bold.woff') format('woff');
+ src: url('/fonts/Montserrat/Montserrat-Bold.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Montserrat Light';
+ src: url('/fonts/Montserrat/Montserrat-Light.woff') format('woff');
+ src: url('/fonts/Montserrat/Montserrat-Light.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Montserrat UltraLight';
+ src: url('/fonts/Montserrat/Montserrat-UltraLight.woff') format('woff');
+ src: url('/fonts/Montserrat/Montserrat-UltraLight.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'DIN OT';
+ src: url('/fonts/DIN_OT/DINOT-2.otf') format('opentype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'DIN OT Light';
+ src: url('/fonts/DIN_OT/DINOT-2.otf') format('opentype');
+ font-weight: 200;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'DIN NEXT';
+ src: url('/fonts/DIN Next/DIN Next W01 Regular.otf') format('opentype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'DIN NEXT Light';
+ src: url('/fonts/DIN Next/DIN Next W10 Light.otf') format('opentype');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato/Lato-Regular.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+}
diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss
new file mode 100644
index 000000000..4c0972527
--- /dev/null
+++ b/ui/app/css/itcss/settings/variables.scss
@@ -0,0 +1,81 @@
+/*
+ Variables
+ */
+
+// Base Colors
+$white: #fff;
+$black: #000;
+$orange: #ffa500;
+$red: #f00;
+$gray: #808080;
+
+/*
+ Colors
+ http://chir.ag/projects/name-that-color
+ */
+$white-linen: #faf6f0; // formerly 'faint orange (textfield shades)'
+$rajah: #f5c26d; // formerly 'light orange (button shades)'
+$buttercup: #f5a623; // formerly 'dark orange (text)'
+$tundora: #4a4a4a; // formerly 'borders/font/any gray'
+$gallery: #efefef;
+$alabaster: #f7f7f7;
+$shark: #22232c;
+$wild-sand: #f6f6f6;
+$white: #fff;
+$dusty-gray: #9b9b9b;
+$alto: #dedede;
+$alabaster: #fafafa;
+$silver-chalice: #aeaeae;
+$curious-blue: #2f9ae0;
+$concrete: #f3f3f3;
+$tundora: #4d4d4d;
+$nile-blue: #1b344d;
+$scorpion: #5d5d5d;
+$silver: #cdcdcd;
+$caribbean-green: #02c9b1;
+$monzo: #d0021b;
+$crimson: #e91550;
+$blue-lagoon: #038789;
+$purple: #690496;
+$tulip-tree: #ebb33f;
+$malibu-blue: #7ac9fd;
+$athens-grey: #e9edf0;
+$jaffa: #f28930;
+$geyser: #d2d8dd;
+$manatee: #93949d;
+$spindle: #c7ddec;
+$mid-gray: #5b5d67;
+$cape-cod: #38393a;
+
+/*
+ Z-Indicies
+ */
+$dropdown-z-index: 30;
+$token-icon-z-index: 15;
+$container-z-index: 15;
+$header-z-index: 12;
+$mobile-header-z-index: 26;
+$main-container-z-index: 18;
+$send-card-z-index: 20;
+$sidebar-z-index: 26;
+$sidebar-overlay-z-index: 25;
+
+/*
+ Z Indicies - Current
+ app - 11
+ hex/bn as decimal input - 1 - remove?
+ dropdown - 11
+ loading - 10 - higher?
+ mascot - 0 - remove?
+ */
+
+/*
+ Responsive Breakpoints
+ */
+$break-small: 575px;
+$break-midpoint: 780px;
+$break-large: 576px;
+
+
+$primary-font-type: Roboto;
+
diff --git a/ui/app/css/itcss/tools/index.scss b/ui/app/css/itcss/tools/index.scss
new file mode 100644
index 000000000..2236729e8
--- /dev/null
+++ b/ui/app/css/itcss/tools/index.scss
@@ -0,0 +1 @@
+@import './utilities.scss';
diff --git a/ui/app/css/itcss/tools/utilities.scss b/ui/app/css/itcss/tools/utilities.scss
new file mode 100644
index 000000000..ee867640d
--- /dev/null
+++ b/ui/app/css/itcss/tools/utilities.scss
@@ -0,0 +1,309 @@
+/*
+ Utility Classes
+ */
+
+/* color */
+
+.color-orange {
+ color: #f7861c; // TODO: move to settings/variables
+}
+
+.color-forest {
+ color: #0a5448; // TODO: move to settings/variables
+}
+
+/* lib */
+
+.full-size {
+ height: 100%;
+ width: 100%;
+}
+
+.full-width {
+ width: 100%;
+}
+
+.full-flex-height {
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+}
+
+.full-height {
+ height: 100%;
+}
+
+.flex-column {
+ display: flex;
+ flex-direction: column;
+}
+
+.space-between {
+ justify-content: space-between;
+}
+
+.space-around {
+ justify-content: space-around;
+}
+
+.flex-column-bottom {
+ display: flex;
+ flex-direction: column-reverse;
+}
+
+.flex-row {
+ display: flex;
+ flex-direction: row;
+}
+
+.flex-space-between {
+ justify-content: space-between;
+}
+
+.flex-space-around {
+ justify-content: space-around;
+}
+
+.flex-right {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+}
+
+.flex-left {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+}
+
+.flex-fixed {
+ flex: none;
+}
+
+.flex-basis-auto {
+ flex-basis: auto;
+}
+
+.flex-grow {
+ flex: 1 1 auto;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.flex-center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.flex-justify-center {
+ justify-content: center;
+}
+
+.flex-align-center {
+ align-items: center;
+}
+
+.flex-self-end {
+ align-self: flex-end;
+}
+
+.flex-self-stretch {
+ align-self: stretch;
+}
+
+.flex-vertical {
+ flex-direction: column;
+}
+
+.z-bump {
+ z-index: 1;
+}
+
+.select-none {
+ cursor: inherit;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.pointer {
+ cursor: pointer;
+}
+
+.cursor-pointer {
+ cursor: pointer;
+ transform-origin: center center;
+ transition: transform 50ms ease-in-out;
+}
+
+.cursor-pointer:hover {
+ transform: scale(1.1);
+}
+
+.cursor-pointer:active {
+ transform: scale(.95);
+}
+
+.cursor-disabled {
+ cursor: not-allowed;
+}
+
+.margin-bottom-sml {
+ margin-bottom: 20px;
+}
+
+.margin-bottom-med {
+ margin-bottom: 40px;
+}
+
+.margin-right-left {
+ margin: 0 20px;
+}
+
+.bold {
+ font-weight: 700;
+}
+
+.text-transform-uppercase {
+ text-transform: uppercase;
+}
+
+.font-small {
+ font-size: 12px;
+}
+
+.font-medium {
+ font-size: 1.2em;
+}
+
+hr.horizontal-line {
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #ccc;
+ margin: 1em 0;
+ padding: 0;
+}
+
+.hover-white:hover {
+ background: $white;
+}
+
+.red-dot {
+ background: #e91550;
+ color: $white;
+ border-radius: 10px;
+}
+
+.diamond {
+ transform: rotate(45deg);
+ background: #038789;
+}
+
+.hollow-diamond {
+ transform: rotate(45deg);
+ border: 3px solid #690496;
+}
+
+.golden-square {
+ background: #ebb33f;
+}
+
+.pending-dot {
+ background: $red;
+ left: 14px;
+ top: 14px;
+ color: $white;
+ border-radius: 10px;
+ height: 20px;
+ min-width: 20px;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 4px;
+ z-index: 1;
+}
+
+.keyring-label {
+ z-index: 1;
+ font-size: 8px;
+ line-height: 8px;
+ background: rgba(255, 255, 255, 0.4);
+ color: #fff;
+ border-radius: 10px;
+ padding: 4px;
+ text-align: center;
+ height: 15px;
+}
+
+.ether-balance {
+ display: flex;
+ align-items: center;
+}
+
+.tabSection {
+ min-width: 350px;
+}
+
+.menu-icon {
+ display: inline-block;
+ height: 12px;
+ min-width: 12px;
+ margin: 13px;
+}
+
+.ether-icon {
+ background: rgb(0, 163, 68);
+ border-radius: 20px;
+}
+
+.testnet-icon {
+ background: #2465e1;
+}
+
+.drop-menu-item {
+ display: flex;
+ align-items: center;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.one-line-concat {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.critical-error {
+ text-align: center;
+ margin-top: 20px;
+ color: $red;
+}
+
+/*
+ Misc
+ */
+
+// TODO: move into component-level contextual 'active' state
+.letter-spacey {
+ letter-spacing: .1em;
+}
+
+.active {
+ color: #909090;
+}
+
+.check {
+ margin-left: 7px;
+ color: #f7861c;
+ flex: 1 0 auto;
+ display: flex;
+ justify-content: flex-end;
+}
diff --git a/ui/app/css/itcss/trumps/index.scss b/ui/app/css/itcss/trumps/index.scss
new file mode 100644
index 000000000..d9a4202a4
--- /dev/null
+++ b/ui/app/css/itcss/trumps/index.scss
@@ -0,0 +1,72 @@
+/*
+ Trumps
+ */
+
+// Transitions
+
+/* universal */
+.app-primary .main-enter {
+ position: absolute;
+ width: 100%;
+}
+
+/* center position */
+.app-primary.from-right .main-enter-active,
+.app-primary.from-left .main-enter-active {
+ overflow-x: hidden;
+ transform: translateX(0);
+ transition: transform 300ms ease-in;
+}
+
+/* exited positions */
+.app-primary.from-left .main-leave-active {
+ transform: translateX(360px);
+ transition: transform 300ms ease-in;
+}
+
+.app-primary.from-right .main-leave-active {
+ transform: translateX(-360px);
+ transition: transform 300ms ease-in;
+}
+
+.sidebar.from-left {
+ transform: translateX(-320px);
+ transition: transform 300ms ease-in;
+}
+
+/* loader transitions */
+.loader-enter,
+.loader-leave-active {
+ opacity: 0;
+ transition: opacity 150 ease-in;
+}
+
+.loader-enter-active,
+.loader-leave {
+ opacity: 1;
+ transition: opacity 150 ease-in;
+}
+
+/* entering positions */
+.app-primary.from-right .main-enter:not(.main-enter-active) {
+ transform: translateX(360px);
+}
+
+.app-primary.from-left .main-enter:not(.main-enter-active) {
+ transform: translateX(-360px);
+}
+
+i.fa.fa-question-circle.fa-lg.menu-icon {
+ font-size: 18px;
+}
+
+// This text is contained inside a div.
+// ID needed to override user agent stylesheet.
+// See components/modal.scss
+
+/* stylelint-disable */
+#buy-modal-content-footer-text {
+ font-family: 'DIN OT';
+ font-size: 16px;
+}
+/* stylelint-enable */
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index b4587f1ee..0e08da8db 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -7,6 +7,8 @@ const Mascot = require('../components/mascot')
const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const getCaretCoordinates = require('textarea-caret')
+const environmentType = require('../../../app/scripts/lib/environment-type')
+const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
let isSubmitting = false
@@ -130,6 +132,18 @@ InitializeMenuScreen.prototype.renderMenu = function (state) {
}, 'Import Existing DEN'),
]),
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showOldUI.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Use classic interface'),
+ ]),
+
])
)
}
@@ -146,7 +160,15 @@ InitializeMenuScreen.prototype.componentDidMount = function () {
}
InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.showRestoreVault())
+ this.props.dispatch(actions.markPasswordForgotten())
+ if (environmentType() === 'popup') {
+ global.platform.openExtensionInBrowser()
+ }
+}
+
+InitializeMenuScreen.prototype.showOldUI = function () {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
}
InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index 24b37a83d..a4ed137f9 100644
--- a/ui/app/keychains/hd/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -107,6 +107,7 @@ RestoreVaultScreen.prototype.render = function () {
}
RestoreVaultScreen.prototype.showInitializeMenu = function () {
+ this.props.dispatch(actions.unMarkPasswordForgotten())
if (this.props.forgottenPassword) {
this.props.dispatch(actions.backToUnlockView())
} else {
@@ -149,6 +150,9 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
this.warning = null
this.props.dispatch(actions.displayWarning(this.warning))
this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
+ .then(() => {
+ this.props.dispatch(actions.unMarkPasswordForgotten())
+ })
.catch((err) => {
log.error(err.message)
})
diff --git a/ui/app/main-container.js b/ui/app/main-container.js
new file mode 100644
index 000000000..292abcc3d
--- /dev/null
+++ b/ui/app/main-container.js
@@ -0,0 +1,59 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+const AccountAndTransactionDetails = require('./account-and-transaction-details')
+const Settings = require('./settings')
+const UnlockScreen = require('./unlock')
+
+module.exports = MainContainer
+
+inherits(MainContainer, Component)
+function MainContainer () {
+ Component.call(this)
+}
+
+MainContainer.prototype.render = function () {
+ // 3. summarize:
+ // switch statement goes inside MainContainer,
+ // or a method in renderPrimary
+ // - pass resulting h() to MainContainer
+ // - error checking in separate func
+ // - router in separate func
+ let contents = {
+ component: AccountAndTransactionDetails,
+ key: 'account-detail',
+ style: {},
+ }
+
+ if (this.props.isUnlocked === false) {
+ switch (this.props.currentViewName) {
+ case 'config':
+ log.debug('rendering config screen from unlock screen.')
+ return h(Settings, {key: 'config'})
+ default:
+ log.debug('rendering locked screen')
+ contents = {
+ component: UnlockScreen,
+ style: {
+ boxShadow: 'none',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ background: '#F7F7F7',
+ // must force 100%, because lock screen is full-width
+ width: '100%',
+ },
+ key: 'locked',
+ }
+ }
+ }
+
+ return h('div.main-container', {
+ style: contents.style,
+ }, [
+ h(contents.component, {
+ key: contents.key,
+ }, []),
+ ])
+}
+
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 8558d6dca..02f024f7c 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -14,6 +14,7 @@ function reduceApp (state, action) {
if (selectedAddress) {
name = 'accountDetail'
}
+
if (hasUnconfActions) {
log.debug('pending txs detected, defaulting to conf-tx view.')
name = 'confTx'
@@ -36,6 +37,17 @@ function reduceApp (state, action) {
var appState = extend({
shouldClose: false,
menuOpen: false,
+ modal: {
+ open: false,
+ modalState: {
+ name: null,
+ },
+ previousModalState: {
+ name: null,
+ },
+ },
+ sidebarOpen: false,
+ networkDropdownOpen: false,
currentView: seedWords ? seedConfView : defaultView,
accountDetail: {
subview: 'transactions',
@@ -46,12 +58,55 @@ function reduceApp (state, action) {
isLoading: false,
// Used to display error text
warning: null,
+ buyView: {},
+ isMouseUser: false,
}, state.appState)
switch (action.type) {
+ // dropdown methods
+ case actions.NETWORK_DROPDOWN_OPEN:
+ return extend(appState, {
+ networkDropdownOpen: true,
+ })
- // transition methods
+ case actions.NETWORK_DROPDOWN_CLOSE:
+ return extend(appState, {
+ networkDropdownOpen: false,
+ })
+
+ // sidebar methods
+ case actions.SIDEBAR_OPEN:
+ return extend(appState, {
+ sidebarOpen: true,
+ })
+
+ case actions.SIDEBAR_CLOSE:
+ return extend(appState, {
+ sidebarOpen: false,
+ })
+ // modal methods:
+ case actions.MODAL_OPEN:
+ return extend(appState, {
+ modal: Object.assign(
+ state.appState.modal,
+ { open: true },
+ { modalState: action.payload },
+ { previousModalState: appState.modal.modalState},
+ ),
+ })
+
+ case actions.MODAL_CLOSE:
+ return extend(appState, {
+ modal: Object.assign(
+ state.appState.modal,
+ { open: false },
+ { modalState: { name: null } },
+ { previousModalState: appState.modal.modalState},
+ ),
+ })
+
+ // transition methods
case actions.TRANSITION_FORWARD:
return extend(appState, {
transForward: true,
@@ -116,7 +171,6 @@ function reduceApp (state, action) {
})
case actions.SHOW_IMPORT_PAGE:
-
return extend(appState, {
currentView: {
name: 'import-menu',
@@ -125,6 +179,24 @@ function reduceApp (state, action) {
warning: null,
})
+ case actions.SHOW_NEW_ACCOUNT_PAGE:
+ return extend(appState, {
+ currentView: {
+ name: 'new-account-page',
+ context: action.formToSelect,
+ },
+ transForward: true,
+ warning: null,
+ })
+
+ case actions.SET_NEW_ACCOUNT_FORM:
+ return extend(appState, {
+ currentView: {
+ name: appState.currentView.name,
+ context: action.formToSelect,
+ },
+ })
+
case actions.SHOW_INFO_PAGE:
return extend(appState, {
currentView: {
@@ -134,7 +206,7 @@ function reduceApp (state, action) {
transForward: true,
})
- case actions.CREATE_NEW_VAULT_IN_PROGRESS:
+ case actions.CREATE_NEW_VAULT_IN_PROGRESS:
return extend(appState, {
currentView: {
name: 'createVault',
@@ -173,6 +245,16 @@ function reduceApp (state, action) {
warning: null,
})
+ case actions.SHOW_SEND_TOKEN_PAGE:
+ return extend(appState, {
+ currentView: {
+ name: 'sendToken',
+ context: appState.currentView.context,
+ },
+ transForward: true,
+ warning: null,
+ })
+
case actions.SHOW_NEW_KEYCHAIN:
return extend(appState, {
currentView: {
@@ -308,7 +390,7 @@ function reduceApp (state, action) {
return extend(appState, {
currentView: {
name: 'confTx',
- context: 0,
+ context: action.id ? indexForPending(state, action.id) : 0,
},
transForward: action.transForward,
warning: null,
@@ -329,7 +411,7 @@ function reduceApp (state, action) {
case actions.COMPLETED_TX:
log.debug('reducing COMPLETED_TX for tx ' + action.value)
const otherUnconfActions = getUnconfActionList(state)
- .filter(tx => tx.id !== action.value)
+ .filter(tx => tx.id !== action.value)
const hasOtherUnconfActions = otherUnconfActions.length > 0
if (hasOtherUnconfActions) {
@@ -403,6 +485,11 @@ function reduceApp (state, action) {
warning: action.value || 'Incorrect password. Try again.',
})
+ case actions.UNLOCK_SUCCEEDED:
+ return extend(appState, {
+ warning: '',
+ })
+
case actions.SHOW_LOADING:
return extend(appState, {
isLoading: true,
@@ -528,8 +615,8 @@ function reduceApp (state, action) {
marketinfo: action.value.marketinfo,
coinOptions: action.value.coinOptions,
},
- buyAddress: appState.buyView.buyAddress,
- amount: appState.buyView.amount,
+ buyAddress: action.value.buyAddress || appState.buyView.buyAddress,
+ amount: appState.buyView.amount || 0,
},
})
@@ -572,6 +659,12 @@ function reduceApp (state, action) {
data: action.value.data,
},
})
+
+ case actions.SET_MOUSE_USER_STATE:
+ return extend(appState, {
+ isMouseUser: action.value,
+ })
+
default:
return appState
}
@@ -597,3 +690,7 @@ function indexForPending (state, txId) {
const index = unconfTxList.indexOf(match)
return index
}
+
+// function indexForLastPending (state) {
+// return getUnconfActionList(state).length
+// }
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 85ac3e201..beeba948d 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -1,6 +1,8 @@
const extend = require('xtend')
const actions = require('../actions')
const MetamascaraPlatform = require('../../../app/scripts/platforms/window')
+const environmentType = require('../../../app/scripts/lib/environment-type')
+const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums
module.exports = reduceMetamask
@@ -11,7 +13,9 @@ function reduceMetamask (state, action) {
var metamaskState = extend({
isInitialized: false,
isUnlocked: false,
+ isAccountMenuOpen: false,
isMascara: window.platform instanceof MetamascaraPlatform,
+ isPopup: environmentType() === 'popup',
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
unapprovedTxs: {},
@@ -19,8 +23,26 @@ function reduceMetamask (state, action) {
lastUnreadNotice: undefined,
frequentRpcList: [],
addressBook: [],
+ selectedTokenAddress: null,
tokenExchangeRates: {},
+ tokens: [],
+ send: {
+ gasLimit: null,
+ gasPrice: null,
+ gasTotal: null,
+ tokenBalance: null,
+ from: '',
+ to: '',
+ amount: '0x0',
+ memo: '',
+ errors: {},
+ maxModeOn: false,
+ editingTransactionId: null,
+ },
coinOptions: {},
+ useBlockie: false,
+ featureFlags: {},
+ networkEndpointType: OLD_UI_NETWORK_TYPE,
}, state.metamask)
switch (action.type) {
@@ -94,6 +116,14 @@ function reduceMetamask (state, action) {
}
return newState
+ case actions.EDIT_TX:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ editingTransactionId: action.value,
+ },
+ })
+
case actions.SHOW_NEW_VAULT_SEED:
return extend(metamaskState, {
isUnlocked: true,
@@ -119,12 +149,17 @@ function reduceMetamask (state, action) {
delete newState.seedWords
return newState
+ case actions.SET_SELECTED_TOKEN:
+ return extend(metamaskState, {
+ selectedTokenAddress: action.value,
+ })
+
case actions.SAVE_ACCOUNT_LABEL:
const account = action.value.account
const name = action.value.label
- var id = {}
+ const id = {}
id[account] = extend(metamaskState.identities[account], { name })
- var identities = extend(metamaskState.identities, id)
+ const identities = extend(metamaskState.identities, id)
return extend(metamaskState, { identities })
case actions.SET_CURRENT_FIAT:
@@ -134,6 +169,147 @@ function reduceMetamask (state, action) {
conversionDate: action.value.conversionDate,
})
+ case actions.UPDATE_TOKEN_EXCHANGE_RATE:
+ const { payload: { pair, marketinfo } } = action
+ return extend(metamaskState, {
+ tokenExchangeRates: {
+ ...metamaskState.tokenExchangeRates,
+ [pair]: marketinfo,
+ },
+ })
+
+ case actions.UPDATE_TOKENS:
+ return extend(metamaskState, {
+ tokens: action.newTokens,
+ })
+
+ // metamask.send
+ case actions.UPDATE_GAS_LIMIT:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ gasLimit: action.value,
+ },
+ })
+
+ case actions.UPDATE_GAS_PRICE:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ gasPrice: action.value,
+ },
+ })
+
+ case actions.TOGGLE_ACCOUNT_MENU:
+ return extend(metamaskState, {
+ isAccountMenuOpen: !metamaskState.isAccountMenuOpen,
+ })
+
+ case actions.UPDATE_GAS_TOTAL:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ gasTotal: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_TOKEN_BALANCE:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ tokenBalance: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_FROM:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ from: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_TO:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ to: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_AMOUNT:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ amount: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_MEMO:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ memo: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND_ERRORS:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ errors: {
+ ...metamaskState.send.errors,
+ ...action.value,
+ },
+ },
+ })
+
+ case actions.UPDATE_MAX_MODE:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ maxModeOn: action.value,
+ },
+ })
+
+ case actions.UPDATE_SEND:
+ return extend(metamaskState, {
+ send: {
+ ...metamaskState.send,
+ ...action.value,
+ },
+ })
+
+ case actions.CLEAR_SEND:
+ return extend(metamaskState, {
+ send: {
+ gasLimit: null,
+ gasPrice: null,
+ gasTotal: null,
+ tokenBalance: null,
+ from: '',
+ to: '',
+ amount: '0x0',
+ memo: '',
+ errors: {},
+ editingTransactionId: null,
+ },
+ })
+
+ case actions.UPDATE_TRANSACTION_PARAMS:
+ const { id: txId, value } = action
+ let { selectedAddressTxList } = metamaskState
+ selectedAddressTxList = selectedAddressTxList.map(tx => {
+ if (tx.id === txId) {
+ tx.txParams = value
+ }
+ return tx
+ })
+
+ return extend(metamaskState, {
+ selectedAddressTxList,
+ })
+
case actions.PAIR_UPDATE:
const { value: { marketinfo: pairMarketInfo } } = action
return extend(metamaskState, {
@@ -144,15 +320,30 @@ function reduceMetamask (state, action) {
})
case actions.SHAPESHIFT_SUBVIEW:
- const { value: { marketinfo, coinOptions } } = action
+ const { value: { marketinfo: ssMarketInfo, coinOptions } } = action
return extend(metamaskState, {
tokenExchangeRates: {
...metamaskState.tokenExchangeRates,
- [marketinfo.pair]: marketinfo,
+ [ssMarketInfo.pair]: ssMarketInfo,
},
coinOptions,
})
+ case actions.SET_USE_BLOCKIE:
+ return extend(metamaskState, {
+ useBlockie: action.value,
+ })
+
+ case actions.UPDATE_FEATURE_FLAGS:
+ return extend(metamaskState, {
+ featureFlags: action.value,
+ })
+
+ case actions.UPDATE_NETWORK_ENDPOINT_TYPE:
+ return extend(metamaskState, {
+ networkEndpointType: action.value,
+ })
+
default:
return metamaskState
diff --git a/ui/app/root.js b/ui/app/root.js
index 9e7314b20..21d6d1829 100644
--- a/ui/app/root.js
+++ b/ui/app/root.js
@@ -2,7 +2,7 @@ const inherits = require('util').inherits
const Component = require('react').Component
const Provider = require('react-redux').Provider
const h = require('react-hyperscript')
-const App = require('./app')
+const SelectedApp = require('./select-app')
module.exports = Root
@@ -15,7 +15,7 @@ Root.prototype.render = function () {
h(Provider, {
store: this.props.store,
}, [
- h(App),
+ h(SelectedApp),
])
)
diff --git a/ui/app/select-app.js b/ui/app/select-app.js
new file mode 100644
index 000000000..193c98353
--- /dev/null
+++ b/ui/app/select-app.js
@@ -0,0 +1,68 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const connect = require('react-redux').connect
+const h = require('react-hyperscript')
+const App = require('./app')
+const OldApp = require('../../old-ui/app/app')
+const { autoAddToBetaUI } = require('./selectors')
+const { setFeatureFlag, setNetworkEndpoints } = require('./actions')
+const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+
+function mapStateToProps (state) {
+ return {
+ betaUI: state.metamask.featureFlags.betaUI,
+ autoAdd: autoAddToBetaUI(state),
+ isUnlocked: state.metamask.isUnlocked,
+ isMascara: state.metamask.isMascara,
+ firstTime: Object.keys(state.metamask.identities).length === 0,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ setFeatureFlagWithModal: () => {
+ return dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
+ .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
+ },
+ setFeatureFlagWithoutModal: () => {
+ return dispatch(setFeatureFlag('betaUI', true))
+ .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
+ },
+ }
+}
+module.exports = connect(mapStateToProps, mapDispatchToProps)(SelectedApp)
+
+inherits(SelectedApp, Component)
+function SelectedApp () {
+ Component.call(this)
+}
+
+SelectedApp.prototype.componentWillReceiveProps = function (nextProps) {
+ // Code commented out until we begin auto adding users to NewUI
+ const {
+ // isUnlocked,
+ // setFeatureFlagWithModal,
+ setFeatureFlagWithoutModal,
+ isMascara,
+ // firstTime,
+ } = this.props
+
+ // if (isMascara || firstTime) {
+ if (isMascara) {
+ setFeatureFlagWithoutModal()
+ }
+ // } else if (!isUnlocked && nextProps.isUnlocked && (nextProps.autoAdd)) {
+ // setFeatureFlagWithModal()
+ // }
+}
+
+SelectedApp.prototype.render = function () {
+ // Code commented out until we begin auto adding users to NewUI
+ // const { betaUI, isMascara, firstTime } = this.props
+ // const Selected = betaUI || isMascara || firstTime ? App : OldApp
+
+ const { betaUI, isMascara } = this.props
+ const Selected = betaUI || isMascara ? App : OldApp
+
+ return h(Selected)
+}
diff --git a/ui/app/selectors.js b/ui/app/selectors.js
new file mode 100644
index 000000000..5d2635775
--- /dev/null
+++ b/ui/app/selectors.js
@@ -0,0 +1,189 @@
+const valuesFor = require('./util').valuesFor
+const abi = require('human-standard-token-abi')
+
+const {
+ multiplyCurrencies,
+} = require('./conversion-util')
+
+const selectors = {
+ getSelectedAddress,
+ getSelectedIdentity,
+ getSelectedAccount,
+ getSelectedToken,
+ getSelectedTokenExchangeRate,
+ getTokenExchangeRate,
+ conversionRateSelector,
+ transactionsSelector,
+ accountsWithSendEtherInfoSelector,
+ getCurrentAccountWithSendEtherInfo,
+ getGasPrice,
+ getGasLimit,
+ getAddressBook,
+ getSendFrom,
+ getCurrentCurrency,
+ getSendAmount,
+ getSelectedTokenToFiatRate,
+ getSelectedTokenContract,
+ autoAddToBetaUI,
+ getSendMaxModeState,
+ getCurrentViewContext,
+}
+
+module.exports = selectors
+
+function getSelectedAddress (state) {
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(state.metamask.accounts)[0]
+
+ return selectedAddress
+}
+
+function getSelectedIdentity (state) {
+ const selectedAddress = getSelectedAddress(state)
+ const identities = state.metamask.identities
+
+ return identities[selectedAddress]
+}
+
+function getSelectedAccount (state) {
+ const accounts = state.metamask.accounts
+ const selectedAddress = getSelectedAddress(state)
+
+ return accounts[selectedAddress]
+}
+
+function getSelectedToken (state) {
+ const tokens = state.metamask.tokens || []
+ const selectedTokenAddress = state.metamask.selectedTokenAddress
+ const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
+
+ return selectedToken || null
+}
+
+function getSelectedTokenExchangeRate (state) {
+ const tokenExchangeRates = state.metamask.tokenExchangeRates
+ const selectedToken = getSelectedToken(state) || {}
+ const { symbol = '' } = selectedToken
+
+ const pair = `${symbol.toLowerCase()}_eth`
+ const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
+
+ return tokenExchangeRate
+}
+
+function getTokenExchangeRate (state, tokenSymbol) {
+ const pair = `${tokenSymbol.toLowerCase()}_eth`
+ const tokenExchangeRates = state.metamask.tokenExchangeRates
+ const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
+
+ return tokenExchangeRate
+}
+
+function conversionRateSelector (state) {
+ return state.metamask.conversionRate
+}
+
+function getAddressBook (state) {
+ return state.metamask.addressBook
+}
+
+function accountsWithSendEtherInfoSelector (state) {
+ const {
+ accounts,
+ identities,
+ } = state.metamask
+
+ const accountsWithSendEtherInfo = Object.entries(accounts).map(([key, account]) => {
+ return Object.assign({}, account, identities[key])
+ })
+
+ return accountsWithSendEtherInfo
+}
+
+function getCurrentAccountWithSendEtherInfo (state) {
+ const currentAddress = getSelectedAddress(state)
+ const accounts = accountsWithSendEtherInfoSelector(state)
+
+ return accounts.find(({ address }) => address === currentAddress)
+}
+
+function transactionsSelector (state) {
+ const { network, selectedTokenAddress } = state.metamask
+ const unapprovedMsgs = valuesFor(state.metamask.unapprovedMsgs)
+ const shapeShiftTxList = (network === '1') ? state.metamask.shapeShiftTxList : undefined
+ const transactions = state.metamask.selectedAddressTxList || []
+ const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
+
+ // console.log({txsToRender, selectedTokenAddress})
+ return selectedTokenAddress
+ ? txsToRender
+ .filter(({ txParams }) => txParams && txParams.to === selectedTokenAddress)
+ .sort((a, b) => b.time - a.time)
+ : txsToRender
+ .sort((a, b) => b.time - a.time)
+}
+
+function getGasPrice (state) {
+ return state.metamask.send.gasPrice
+}
+
+function getGasLimit (state) {
+ return state.metamask.send.gasLimit
+}
+
+function getSendFrom (state) {
+ return state.metamask.send.from
+}
+
+function getSendAmount (state) {
+ return state.metamask.send.amount
+}
+
+function getSendMaxModeState (state) {
+ return state.metamask.send.maxModeOn
+}
+
+function getCurrentCurrency (state) {
+ return state.metamask.currentCurrency
+}
+
+function getSelectedTokenToFiatRate (state) {
+ const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
+ const conversionRate = conversionRateSelector(state)
+
+ const tokenToFiatRate = multiplyCurrencies(
+ conversionRate,
+ selectedTokenExchangeRate,
+ { toNumericBase: 'dec' }
+ )
+
+ return tokenToFiatRate
+}
+
+function getSelectedTokenContract (state) {
+ const selectedToken = getSelectedToken(state)
+ return selectedToken
+ ? global.eth.contract(abi).at(selectedToken.address)
+ : null
+}
+
+function autoAddToBetaUI (state) {
+ const autoAddTransactionThreshold = 12
+ const autoAddAccountsThreshold = 2
+ const autoAddTokensThreshold = 1
+
+ const numberOfTransactions = state.metamask.selectedAddressTxList.length
+ const numberOfAccounts = Object.keys(state.metamask.accounts).length
+ const numberOfTokensAdded = state.metamask.tokens.length
+
+ const userPassesThreshold = (numberOfTransactions > autoAddTransactionThreshold) &&
+ (numberOfAccounts > autoAddAccountsThreshold) &&
+ (numberOfTokensAdded > autoAddTokensThreshold)
+ const userIsNotInBeta = !state.metamask.featureFlags.betaUI
+
+ return userIsNotInBeta && userPassesThreshold
+}
+
+function getCurrentViewContext (state) {
+ const { currentView = {} } = state.appState
+ return currentView.context
+} \ No newline at end of file
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
new file mode 100644
index 000000000..1d67150e3
--- /dev/null
+++ b/ui/app/send-v2.js
@@ -0,0 +1,624 @@
+const { inherits } = require('util')
+const PersistentForm = require('../lib/persistent-form')
+const h = require('react-hyperscript')
+
+const ethAbi = require('ethereumjs-abi')
+const ethUtil = require('ethereumjs-util')
+
+const FromDropdown = require('./components/send/from-dropdown')
+const ToAutoComplete = require('./components/send/to-autocomplete')
+const CurrencyDisplay = require('./components/send/currency-display')
+const MemoTextArea = require('./components/send/memo-textarea')
+const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
+
+const {
+ TOKEN_TRANSFER_FUNCTION_SIGNATURE,
+} = require('./components/send/send-constants')
+
+const {
+ multiplyCurrencies,
+ conversionGreaterThan,
+ subtractCurrencies,
+} = require('./conversion-util')
+const {
+ calcTokenAmount,
+} = require('./token-util')
+const {
+ isBalanceSufficient,
+ isTokenBalanceSufficient,
+} = require('./components/send/send-utils')
+const { isValidAddress } = require('./util')
+
+module.exports = SendTransactionScreen
+
+inherits(SendTransactionScreen, PersistentForm)
+function SendTransactionScreen () {
+ PersistentForm.call(this)
+
+ this.state = {
+ fromDropdownOpen: false,
+ toDropdownOpen: false,
+ errors: {
+ to: null,
+ amount: null,
+ },
+ }
+
+ this.handleToChange = this.handleToChange.bind(this)
+ this.handleAmountChange = this.handleAmountChange.bind(this)
+ this.validateAmount = this.validateAmount.bind(this)
+}
+
+const getParamsForGasEstimate = function (selectedAddress, symbol, data) {
+ const estimatedGasParams = {
+ from: selectedAddress,
+ gas: '746a528800',
+ }
+
+ if (symbol) {
+ Object.assign(estimatedGasParams, { value: '0x0' })
+ }
+
+ if (data) {
+ Object.assign(estimatedGasParams, { data })
+ }
+
+ return estimatedGasParams
+}
+
+SendTransactionScreen.prototype.updateSendTokenBalance = function (usersToken) {
+ if (!usersToken) return
+
+ const {
+ selectedToken = {},
+ updateSendTokenBalance,
+ } = this.props
+ const { decimals } = selectedToken || {}
+ const tokenBalance = calcTokenAmount(usersToken.balance.toString(), decimals)
+
+ updateSendTokenBalance(tokenBalance)
+}
+
+SendTransactionScreen.prototype.componentWillMount = function () {
+ const {
+ updateTokenExchangeRate,
+ selectedToken = {},
+ } = this.props
+
+ const { symbol } = selectedToken || {}
+
+ if (symbol) {
+ updateTokenExchangeRate(symbol)
+ }
+
+ this.updateGas()
+}
+
+SendTransactionScreen.prototype.updateGas = function () {
+ const {
+ selectedToken = {},
+ getGasPrice,
+ estimateGas,
+ selectedAddress,
+ data,
+ updateGasTotal,
+ from,
+ tokenContract,
+ editingTransactionId,
+ gasPrice,
+ gasLimit,
+ } = this.props
+
+ const { symbol } = selectedToken || {}
+
+ const tokenBalancePromise = tokenContract
+ ? tokenContract.balanceOf(from.address)
+ : Promise.resolve()
+ tokenBalancePromise
+ .then(usersToken => this.updateSendTokenBalance(usersToken))
+
+ if (!editingTransactionId) {
+ const estimateGasParams = getParamsForGasEstimate(selectedAddress, symbol, data)
+
+ Promise
+ .all([
+ getGasPrice(),
+ estimateGas(estimateGasParams),
+ ])
+ .then(([gasPrice, gas]) => {
+ const newGasTotal = this.getGasTotal(gas, gasPrice)
+ updateGasTotal(newGasTotal)
+ })
+ } else {
+ const newGasTotal = this.getGasTotal(gasLimit, gasPrice)
+ updateGasTotal(newGasTotal)
+ }
+}
+
+SendTransactionScreen.prototype.getGasTotal = function (gasLimit, gasPrice) {
+ return multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+}
+
+SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) {
+ const {
+ from: { balance },
+ gasTotal,
+ tokenBalance,
+ amount,
+ selectedToken,
+ network,
+ } = this.props
+
+ const {
+ from: { balance: prevBalance },
+ gasTotal: prevGasTotal,
+ tokenBalance: prevTokenBalance,
+ network: prevNetwork,
+ } = prevProps
+
+ const uninitialized = [prevBalance, prevGasTotal].every(n => n === null)
+
+ const balanceHasChanged = balance !== prevBalance
+ const gasTotalHasChange = gasTotal !== prevGasTotal
+ const tokenBalanceHasChanged = selectedToken && tokenBalance !== prevTokenBalance
+ const amountValidationChange = balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged
+
+ if (!uninitialized) {
+ if (amountValidationChange) {
+ this.validateAmount(amount)
+ }
+
+ if (network !== prevNetwork && network !== 'loading') {
+ this.updateGas()
+ }
+ }
+}
+
+SendTransactionScreen.prototype.renderHeader = function () {
+ const { selectedToken, clearSend, goHome } = this.props
+ const tokenText = selectedToken ? 'tokens' : 'ETH'
+
+ return h('div.page-container__header', [
+
+ h('div.page-container__title', selectedToken ? 'Send Tokens' : 'Send ETH'),
+
+ h('div.page-container__subtitle', `Only send ${tokenText} to an Ethereum address.`),
+
+ h('div.page-container__header-close', {
+ onClick: () => {
+ clearSend()
+ goHome()
+ },
+ }),
+
+ ])
+}
+
+SendTransactionScreen.prototype.renderErrorMessage = function (errorType) {
+ const { errors } = this.props
+ const errorMessage = errors[errorType]
+
+ return errorMessage
+ ? h('div.send-v2__error', [ errorMessage ])
+ : null
+}
+
+SendTransactionScreen.prototype.handleFromChange = async function (newFrom) {
+ const {
+ updateSendFrom,
+ tokenContract,
+ } = this.props
+
+ if (tokenContract) {
+ const usersToken = await tokenContract.balanceOf(newFrom.address)
+ this.updateSendTokenBalance(usersToken)
+ }
+ updateSendFrom(newFrom)
+}
+
+SendTransactionScreen.prototype.renderFromRow = function () {
+ const {
+ from,
+ fromAccounts,
+ conversionRate,
+ } = this.props
+
+ const { fromDropdownOpen } = this.state
+
+ return h('div.send-v2__form-row', [
+
+ h('div.send-v2__form-label', 'From:'),
+
+ h('div.send-v2__form-field', [
+ h(FromDropdown, {
+ dropdownOpen: fromDropdownOpen,
+ accounts: fromAccounts,
+ selectedAccount: from,
+ onSelect: newFrom => this.handleFromChange(newFrom),
+ openDropdown: () => this.setState({ fromDropdownOpen: true }),
+ closeDropdown: () => this.setState({ fromDropdownOpen: false }),
+ conversionRate,
+ }),
+ ]),
+
+ ])
+}
+
+SendTransactionScreen.prototype.handleToChange = function (to) {
+ const {
+ updateSendTo,
+ updateSendErrors,
+ from: {address: from},
+ } = this.props
+ let toError = null
+
+ if (!to) {
+ toError = 'Required'
+ } else if (!isValidAddress(to)) {
+ toError = 'Recipient address is invalid'
+ } else if (to === from) {
+ toError = 'From and To address cannot be the same'
+ }
+
+ updateSendTo(to)
+ updateSendErrors({ to: toError })
+}
+
+SendTransactionScreen.prototype.renderToRow = function () {
+ const { toAccounts, errors, to } = this.props
+
+ const { toDropdownOpen } = this.state
+
+ return h('div.send-v2__form-row', [
+
+ h('div.send-v2__form-label', [
+
+ 'To:',
+
+ this.renderErrorMessage('to'),
+
+ ]),
+
+ h('div.send-v2__form-field', [
+ h(ToAutoComplete, {
+ to,
+ accounts: Object.entries(toAccounts).map(([key, account]) => account),
+ dropdownOpen: toDropdownOpen,
+ openDropdown: () => this.setState({ toDropdownOpen: true }),
+ closeDropdown: () => this.setState({ toDropdownOpen: false }),
+ onChange: this.handleToChange,
+ inError: Boolean(errors.to),
+ }),
+ ]),
+
+ ])
+}
+
+SendTransactionScreen.prototype.handleAmountChange = function (value) {
+ const amount = value
+ const { updateSendAmount, setMaxModeTo } = this.props
+
+ setMaxModeTo(false)
+ this.validateAmount(amount)
+ updateSendAmount(amount)
+}
+
+SendTransactionScreen.prototype.setAmountToMax = function () {
+ const {
+ from: { balance },
+ updateSendAmount,
+ updateSendErrors,
+ tokenBalance,
+ selectedToken,
+ gasTotal,
+ } = this.props
+ const { decimals } = selectedToken || {}
+ const multiplier = Math.pow(10, Number(decimals || 0))
+
+ const maxAmount = selectedToken
+ ? multiplyCurrencies(tokenBalance, multiplier, {toNumericBase: 'hex'})
+ : subtractCurrencies(
+ ethUtil.addHexPrefix(balance),
+ ethUtil.addHexPrefix(gasTotal),
+ { toNumericBase: 'hex' }
+ )
+
+ updateSendErrors({ amount: null })
+
+ updateSendAmount(maxAmount)
+}
+
+SendTransactionScreen.prototype.validateAmount = function (value) {
+ const {
+ from: { balance },
+ updateSendErrors,
+ amountConversionRate,
+ conversionRate,
+ primaryCurrency,
+ selectedToken,
+ gasTotal,
+ tokenBalance,
+ } = this.props
+ const { decimals } = selectedToken || {}
+ const amount = value
+
+ let amountError = null
+
+ let sufficientBalance = true
+
+ if (gasTotal) {
+ sufficientBalance = isBalanceSufficient({
+ amount: selectedToken ? '0x0' : amount,
+ gasTotal,
+ balance,
+ primaryCurrency,
+ amountConversionRate,
+ conversionRate,
+ })
+ }
+
+ let sufficientTokens
+ if (selectedToken) {
+ sufficientTokens = isTokenBalanceSufficient({
+ tokenBalance,
+ amount,
+ decimals,
+ })
+ }
+
+ const amountLessThanZero = conversionGreaterThan(
+ { value: 0, fromNumericBase: 'dec' },
+ { value: amount, fromNumericBase: 'hex' },
+ )
+
+ if (conversionRate && !sufficientBalance) {
+ amountError = 'Insufficient funds.'
+ } else if (selectedToken && !sufficientTokens) {
+ amountError = 'Insufficient tokens.'
+ } else if (amountLessThanZero) {
+ amountError = 'Can not send negative amounts of ETH.'
+ }
+
+ updateSendErrors({ amount: amountError })
+}
+
+SendTransactionScreen.prototype.renderAmountRow = function () {
+ const {
+ selectedToken,
+ primaryCurrency = 'ETH',
+ convertedCurrency,
+ amountConversionRate,
+ errors,
+ amount,
+ setMaxModeTo,
+ maxModeOn,
+ } = this.props
+
+ return h('div.send-v2__form-row', [
+
+ h('div.send-v2__form-label', [
+ 'Amount:',
+ this.renderErrorMessage('amount'),
+ !errors.amount && h('div.send-v2__amount-max', {
+ onClick: (event) => {
+ event.preventDefault()
+ setMaxModeTo(true)
+ this.setAmountToMax()
+ },
+ }, [ !maxModeOn ? 'Max' : '' ]),
+ ]),
+
+ h('div.send-v2__form-field', [
+ h(CurrencyDisplay, {
+ inError: Boolean(errors.amount),
+ primaryCurrency,
+ convertedCurrency,
+ selectedToken,
+ value: amount || '0x0',
+ conversionRate: amountConversionRate,
+ handleChange: this.handleAmountChange,
+ }),
+ ]),
+
+ ])
+}
+
+SendTransactionScreen.prototype.renderGasRow = function () {
+ const {
+ conversionRate,
+ convertedCurrency,
+ showCustomizeGasModal,
+ gasTotal,
+ } = this.props
+
+ return h('div.send-v2__form-row', [
+
+ h('div.send-v2__form-label', 'Gas fee:'),
+
+ h('div.send-v2__form-field', [
+
+ h(GasFeeDisplay, {
+ gasTotal,
+ conversionRate,
+ convertedCurrency,
+ onClick: showCustomizeGasModal,
+ }),
+
+ ]),
+
+ ])
+}
+
+SendTransactionScreen.prototype.renderMemoRow = function () {
+ const { updateSendMemo, memo } = this.props
+
+ return h('div.send-v2__form-row', [
+
+ h('div.send-v2__form-label', 'Transaction Memo:'),
+
+ h('div.send-v2__form-field', [
+ h(MemoTextArea, {
+ memo,
+ onChange: (event) => updateSendMemo(event.target.value),
+ }),
+ ]),
+
+ ])
+}
+
+SendTransactionScreen.prototype.renderForm = function () {
+ return h('div.send-v2__form', {}, [
+
+ this.renderFromRow(),
+
+ this.renderToRow(),
+
+ this.renderAmountRow(),
+
+ this.renderGasRow(),
+
+ // this.renderMemoRow(),
+
+ ])
+}
+
+SendTransactionScreen.prototype.renderFooter = function () {
+ const {
+ goHome,
+ clearSend,
+ gasTotal,
+ errors: { amount: amountError, to: toError },
+ } = this.props
+
+ const noErrors = !amountError && toError === null
+
+ return h('div.page-container__footer', [
+ h('button.btn-cancel.page-container__footer-button', {
+ onClick: () => {
+ clearSend()
+ goHome()
+ },
+ }, 'Cancel'),
+ h('button.btn-clear.page-container__footer-button', {
+ disabled: !noErrors || !gasTotal,
+ onClick: event => this.onSubmit(event),
+ }, 'Next'),
+ ])
+}
+
+SendTransactionScreen.prototype.render = function () {
+ return (
+
+ h('div.page-container', [
+
+ this.renderHeader(),
+
+ this.renderForm(),
+
+ this.renderFooter(),
+ ])
+
+ )
+}
+
+SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) {
+ const { toAccounts, addToAddressBook } = this.props
+ if (!toAccounts.find(({ address }) => newAddress === address)) {
+ // TODO: nickname, i.e. addToAddressBook(recipient, nickname)
+ addToAddressBook(newAddress)
+ }
+}
+
+SendTransactionScreen.prototype.getEditedTx = function () {
+ const {
+ from: {address: from},
+ to,
+ amount,
+ gasLimit: gas,
+ gasPrice,
+ selectedToken,
+ editingTransactionId,
+ unapprovedTxs,
+ } = this.props
+
+ const editingTx = {
+ ...unapprovedTxs[editingTransactionId],
+ txParams: {
+ from: ethUtil.addHexPrefix(from),
+ gas: ethUtil.addHexPrefix(gas),
+ gasPrice: ethUtil.addHexPrefix(gasPrice),
+ },
+ }
+
+ if (selectedToken) {
+ const data = TOKEN_TRANSFER_FUNCTION_SIGNATURE + Array.prototype.map.call(
+ ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]),
+ x => ('00' + x.toString(16)).slice(-2)
+ ).join('')
+
+ Object.assign(editingTx.txParams, {
+ value: ethUtil.addHexPrefix('0'),
+ to: ethUtil.addHexPrefix(selectedToken.address),
+ data,
+ })
+ } else {
+ Object.assign(editingTx.txParams, {
+ value: ethUtil.addHexPrefix(amount),
+ to: ethUtil.addHexPrefix(to),
+ })
+ }
+
+ return editingTx
+}
+
+SendTransactionScreen.prototype.onSubmit = function (event) {
+ event.preventDefault()
+ const {
+ from: {address: from},
+ to,
+ amount,
+ gasLimit: gas,
+ gasPrice,
+ signTokenTx,
+ signTx,
+ updateTx,
+ selectedToken,
+ editingTransactionId,
+ errors: { amount: amountError, to: toError },
+ } = this.props
+
+ const noErrors = !amountError && toError === null
+
+ if (!noErrors) {
+ return
+ }
+
+ this.addToAddressBookIfNew(to)
+
+ if (editingTransactionId) {
+ const editedTx = this.getEditedTx()
+
+ updateTx(editedTx)
+ } else {
+
+ const txParams = {
+ from,
+ value: '0',
+ gas,
+ gasPrice,
+ }
+
+ if (!selectedToken) {
+ txParams.value = amount
+ txParams.to = to
+ }
+
+ selectedToken
+ ? signTokenTx(selectedToken.address, to, amount, txParams)
+ : signTx(txParams)
+ }
+}
diff --git a/ui/app/send.js b/ui/app/send.js
index 09c9e03d4..517b7690d 100644
--- a/ui/app/send.js
+++ b/ui/app/send.js
@@ -1,309 +1,547 @@
-const inherits = require('util').inherits
-const PersistentForm = require('../lib/persistent-form')
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const Identicon = require('./components/identicon')
-const actions = require('./actions')
-const util = require('./util')
-const numericBalance = require('./util').numericBalance
-const addressSummary = require('./util').addressSummary
-const isHex = require('./util').isHex
-const EthBalance = require('./components/eth-balance')
-const EnsInput = require('./components/ens-input')
-const ethUtil = require('ethereumjs-util')
-module.exports = connect(mapStateToProps)(SendTransactionScreen)
-
-function mapStateToProps (state) {
- var result = {
- address: state.metamask.selectedAddress,
- accounts: state.metamask.accounts,
- identities: state.metamask.identities,
- warning: state.appState.warning,
- network: state.metamask.network,
- addressBook: state.metamask.addressBook,
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- }
-
- result.error = result.warning && result.warning.split('.')[0]
-
- result.account = result.accounts[result.address]
- result.identity = result.identities[result.address]
- result.balance = result.account ? numericBalance(result.account.balance) : null
-
- return result
-}
-
-inherits(SendTransactionScreen, PersistentForm)
-function SendTransactionScreen () {
- PersistentForm.call(this)
-}
-
-SendTransactionScreen.prototype.render = function () {
- this.persistentFormParentId = 'send-tx-form'
-
- const props = this.props
- const {
- address,
- account,
- identity,
- network,
- identities,
- addressBook,
- conversionRate,
- currentCurrency,
- } = props
-
- return (
-
- h('.send-screen.flex-column.flex-grow', [
-
- //
- // Sender Profile
- //
-
- h('.account-data-subsection.flex-row.flex-grow', {
- style: {
- margin: '0 20px',
- },
- }, [
-
- // header - identicon + nav
- h('.flex-row.flex-space-between', {
- style: {
- marginTop: '15px',
- },
- }, [
- // back button
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: this.back.bind(this),
- }),
-
- // large identicon
- h('.identicon-wrapper.flex-column.flex-center.select-none', [
- h(Identicon, {
- diameter: 62,
- address: address,
- }),
- ]),
-
- // invisible place holder
- h('i.fa.fa-users.fa-lg.invisible', {
- style: {
- marginTop: '28px',
- },
- }),
-
- ]),
-
- // account label
-
- h('.flex-column', {
- style: {
- marginTop: '10px',
- alignItems: 'flex-start',
- },
- }, [
- h('h2.font-medium.color-forest.flex-center', {
- style: {
- paddingTop: '8px',
- marginBottom: '8px',
- },
- }, identity && identity.name),
-
- // address and getter actions
- h('.flex-row.flex-center', {
- style: {
- marginBottom: '8px',
- },
- }, [
-
- h('div', {
- style: {
- lineHeight: '16px',
- },
- }, addressSummary(address)),
-
- ]),
-
- // balance
- h('.flex-row.flex-center', [
-
- h(EthBalance, {
- value: account && account.balance,
- conversionRate,
- currentCurrency,
- }),
-
- ]),
- ]),
- ]),
-
- //
- // Required Fields
- //
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: '15px',
- marginBottom: '16px',
- },
- }, [
- 'Send Transaction',
- ]),
-
- // error message
- props.error && h('span.error.flex-center', props.error),
-
- // 'to' field
- h('section.flex-row.flex-center', [
- h(EnsInput, {
- name: 'address',
- placeholder: 'Recipient Address',
- onChange: this.recipientDidChange.bind(this),
- network,
- identities,
- addressBook,
- }),
- ]),
-
- // 'amount' and send button
- h('section.flex-row.flex-center', [
-
- h('input.large-input', {
- name: 'amount',
- placeholder: 'Amount',
- type: 'number',
- style: {
- marginRight: '6px',
- },
- dataset: {
- persistentFormId: 'tx-amount',
- },
- }),
-
- h('button.primary', {
- onClick: this.onSubmit.bind(this),
- style: {
- textTransform: 'uppercase',
- },
- }, 'Next'),
-
- ]),
-
- //
- // Optional Fields
- //
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: '16px',
- marginBottom: '16px',
- },
- }, [
- 'Transaction Data (optional)',
- ]),
-
- // 'data' field
- h('section.flex-column.flex-center', [
- h('input.large-input', {
- name: 'txData',
- placeholder: '0x01234',
- style: {
- width: '100%',
- resize: 'none',
- },
- dataset: {
- persistentFormId: 'tx-data',
- },
- }),
- ]),
- ])
- )
-}
-
-SendTransactionScreen.prototype.navigateToAccounts = function (event) {
- event.stopPropagation()
- this.props.dispatch(actions.showAccountsPage())
-}
-
-SendTransactionScreen.prototype.back = function () {
- var address = this.props.address
- this.props.dispatch(actions.backToAccountDetail(address))
-}
-
-SendTransactionScreen.prototype.recipientDidChange = function (recipient, nickname) {
- this.setState({
- recipient: recipient,
- nickname: nickname,
- })
-}
-
-SendTransactionScreen.prototype.onSubmit = function () {
- const state = this.state || {}
- const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '')
- const nickname = state.nickname || ' '
- const input = document.querySelector('input[name="amount"]').value
- const parts = input.split('')
-
- let message
-
- if (isNaN(input) || input === '') {
- message = 'Invalid ether value.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if (parts[1]) {
- var decimal = parts[1]
- if (decimal.length > 18) {
- message = 'Ether amount is too precise.'
- return this.props.dispatch(actions.displayWarning(message))
- }
- }
-
- const value = util.normalizeEthStringToWei(input)
- const txData = document.querySelector('input[name="txData"]').value
- const balance = this.props.balance
-
- if (value.gt(balance)) {
- message = 'Insufficient funds.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if (input < 0) {
- message = 'Can not send negative amounts of ETH.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if ((util.isInvalidChecksumAddress(recipient))) {
- message = 'Recipient address checksum is invalid.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) {
- message = 'Recipient address is invalid.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if (!isHex(ethUtil.stripHexPrefix(txData)) && txData) {
- message = 'Transaction data must be hex string.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- this.props.dispatch(actions.hideWarning())
-
- this.props.dispatch(actions.addToAddressBook(recipient, nickname))
-
- var txParams = {
- from: this.props.address,
- value: '0x' + value.toString(16),
- }
-
- if (recipient) txParams.to = ethUtil.addHexPrefix(recipient)
- if (txData) txParams.data = txData
-
- this.props.dispatch(actions.signTx(txParams))
-}
+// const { inherits } = require('util')
+// const PersistentForm = require('../lib/persistent-form')
+// const h = require('react-hyperscript')
+// const connect = require('react-redux').connect
+// const Identicon = require('./components/identicon')
+// const EnsInput = require('./components/ens-input')
+// const GasTooltip = require('./components/send/gas-tooltip')
+// const CurrencyToggle = require('./components/send/currency-toggle')
+// const GasFeeDisplay = require('./components/send/gas-fee-display')
+// const { getSelectedIdentity } = require('./selectors')
+
+// const {
+// showAccountsPage,
+// backToAccountDetail,
+// displayWarning,
+// hideWarning,
+// addToAddressBook,
+// signTx,
+// estimateGas,
+// getGasPrice,
+// } = require('./actions')
+// const { stripHexPrefix, addHexPrefix } = require('ethereumjs-util')
+// const { isHex, numericBalance, isValidAddress, allNull } = require('./util')
+// const { conversionUtil, conversionGreaterThan } = require('./conversion-util')
+
+// module.exports = connect(mapStateToProps)(SendTransactionScreen)
+
+// function mapStateToProps (state) {
+// const {
+// selectedAddress: address,
+// accounts,
+// identities,
+// network,
+// addressBook,
+// conversionRate,
+// currentBlockGasLimit: blockGasLimit,
+// } = state.metamask
+// const { warning } = state.appState
+// const selectedIdentity = getSelectedIdentity(state)
+// const account = accounts[address]
+
+// return {
+// address,
+// accounts,
+// identities,
+// network,
+// addressBook,
+// conversionRate,
+// blockGasLimit,
+// warning,
+// selectedIdentity,
+// error: warning && warning.split('.')[0],
+// account,
+// identity: identities[address],
+// balance: account ? account.balance : null,
+// }
+// }
+
+// inherits(SendTransactionScreen, PersistentForm)
+// function SendTransactionScreen () {
+// PersistentForm.call(this)
+
+// // [WIP] These are the bare minimum of tx props needed to sign a transaction
+// // We will need a few more for contract-related interactions
+// this.state = {
+// newTx: {
+// from: '',
+// to: '',
+// amountToSend: '0x0',
+// gasPrice: null,
+// gas: null,
+// amount: '0x0',
+// txData: null,
+// memo: '',
+// },
+// activeCurrency: 'USD',
+// tooltipIsOpen: false,
+// errors: {},
+// isValid: false,
+// }
+
+// this.back = this.back.bind(this)
+// this.closeTooltip = this.closeTooltip.bind(this)
+// this.onSubmit = this.onSubmit.bind(this)
+// this.setActiveCurrency = this.setActiveCurrency.bind(this)
+// this.toggleTooltip = this.toggleTooltip.bind(this)
+// this.validate = this.validate.bind(this)
+// this.getAmountToSend = this.getAmountToSend.bind(this)
+// this.setErrorsFor = this.setErrorsFor.bind(this)
+// this.clearErrorsFor = this.clearErrorsFor.bind(this)
+
+// this.renderFromInput = this.renderFromInput.bind(this)
+// this.renderToInput = this.renderToInput.bind(this)
+// this.renderAmountInput = this.renderAmountInput.bind(this)
+// this.renderGasInput = this.renderGasInput.bind(this)
+// this.renderMemoInput = this.renderMemoInput.bind(this)
+// this.renderErrorMessage = this.renderErrorMessage.bind(this)
+// }
+
+// SendTransactionScreen.prototype.componentWillMount = function () {
+// const { newTx } = this.state
+// const { address } = this.props
+
+// Promise.all([
+// this.props.dispatch(getGasPrice()),
+// this.props.dispatch(estimateGas({
+// from: address,
+// gas: '746a528800',
+// })),
+// ])
+// .then(([blockGasPrice, estimatedGas]) => {
+// console.log({ blockGasPrice, estimatedGas})
+// this.setState({
+// newTx: {
+// ...newTx,
+// gasPrice: blockGasPrice,
+// gas: estimatedGas,
+// },
+// })
+// })
+// }
+
+// SendTransactionScreen.prototype.renderErrorMessage = function(errorType, warning) {
+// const { errors } = this.state
+// const errorMessage = errors[errorType];
+
+// return errorMessage || warning
+// ? h('div.send-screen-input-wrapper__error-message', [ errorMessage || warning ])
+// : null
+// }
+
+// SendTransactionScreen.prototype.renderFromInput = function (from, identities) {
+// return h('div.send-screen-input-wrapper', [
+
+// h('div', 'From:'),
+
+// h('input.large-input.send-screen-input', {
+// list: 'accounts',
+// placeholder: 'Account',
+// value: from,
+// onChange: (event) => {
+// this.setState({
+// newTx: {
+// ...this.state.newTx,
+// from: event.target.value,
+// },
+// })
+// },
+// onBlur: () => this.setErrorsFor('from'),
+// onFocus: event => {
+// this.clearErrorsFor('from')
+// this.state.newTx.from && event.target.select()
+// },
+// }),
+
+// h('datalist#accounts', [
+// Object.entries(identities).map(([key, { address, name }]) => {
+// return h('option', {
+// value: address,
+// label: name,
+// key: address,
+// })
+// }),
+// ]),
+
+// this.renderErrorMessage('from'),
+
+// ])
+// }
+
+// SendTransactionScreen.prototype.renderToInput = function (to, identities, addressBook) {
+// return h('div.send-screen-input-wrapper', [
+
+// h('div', 'To:'),
+
+// h('input.large-input.send-screen-input', {
+// name: 'address',
+// list: 'addresses',
+// placeholder: 'Address',
+// value: to,
+// onChange: (event) => {
+// this.setState({
+// newTx: {
+// ...this.state.newTx,
+// to: event.target.value,
+// },
+// })
+// },
+// onBlur: () => {
+// this.setErrorsFor('to')
+// },
+// onFocus: event => {
+// this.clearErrorsFor('to')
+// this.state.newTx.to && event.target.select()
+// },
+// }),
+
+// h('datalist#addresses', [
+// // Corresponds to the addresses owned.
+// ...Object.entries(identities).map(([key, { address, name }]) => {
+// return h('option', {
+// value: address,
+// label: name,
+// key: address,
+// })
+// }),
+// // Corresponds to previously sent-to addresses.
+// ...addressBook.map(({ address, name }) => {
+// return h('option', {
+// value: address,
+// label: name,
+// key: address,
+// })
+// }),
+// ]),
+
+// this.renderErrorMessage('to'),
+
+// ])
+// }
+
+// SendTransactionScreen.prototype.renderAmountInput = function (activeCurrency) {
+// return h('div.send-screen-input-wrapper', [
+
+// h('div.send-screen-amount-labels', [
+// h('span', 'Amount'),
+// h(CurrencyToggle, {
+// activeCurrency,
+// onClick: (newCurrency) => this.setActiveCurrency(newCurrency),
+// }), // holding on icon from design
+// ]),
+
+// h('input.large-input.send-screen-input', {
+// placeholder: `0 ${activeCurrency}`,
+// type: 'number',
+// onChange: (event) => {
+// const amountToSend = event.target.value
+// ? this.getAmountToSend(event.target.value)
+// : '0x0'
+
+// this.setState({
+// newTx: Object.assign(
+// this.state.newTx,
+// {
+// amount: event.target.value,
+// amountToSend: amountToSend,
+// }
+// ),
+// })
+// },
+// onBlur: () => {
+// this.setErrorsFor('amount')
+// },
+// onFocus: () => this.clearErrorsFor('amount'),
+// }),
+
+// this.renderErrorMessage('amount'),
+
+// ])
+// }
+
+// SendTransactionScreen.prototype.renderGasInput = function (gasPrice, gas, activeCurrency, conversionRate, blockGasLimit) {
+// return h('div.send-screen-input-wrapper', [
+// this.state.tooltipIsOpen && h(GasTooltip, {
+// className: 'send-tooltip',
+// gasPrice,
+// gasLimit: gas,
+// onClose: this.closeTooltip,
+// onFeeChange: ({gasLimit, gasPrice}) => {
+// this.setState({
+// newTx: {
+// ...this.state.newTx,
+// gas: gasLimit,
+// gasPrice,
+// },
+// })
+// },
+// }),
+
+// h('div.send-screen-gas-labels', [
+// h('span', [
+// h('i.fa.fa-bolt'),
+// 'Gas fee:',
+// ]),
+// h('span', 'What\'s this?'),
+// ]),
+
+// // TODO: handle loading time when switching to USD
+// h('div.large-input.send-screen-gas-input', {}, [
+// h(GasFeeDisplay, {
+// activeCurrency,
+// conversionRate,
+// gas,
+// gasPrice,
+// blockGasLimit,
+// }),
+// h('div.send-screen-gas-input-customize', {
+// onClick: this.toggleTooltip,
+// }, [
+// 'Customize',
+// ]),
+// ]),
+
+// ])
+// }
+
+// SendTransactionScreen.prototype.renderMemoInput = function () {
+// return h('div.send-screen-input-wrapper', [
+// h('div', 'Transaction memo (optional)'),
+// h('input.large-input.send-screen-input', {
+// onChange: () => {
+// this.setState({
+// newTx: Object.assign(
+// this.state.newTx,
+// {
+// memo: event.target.value,
+// }
+// ),
+// })
+// },
+// }),
+// ])
+// }
+
+// SendTransactionScreen.prototype.render = function () {
+// this.persistentFormParentId = 'send-tx-form'
+
+// const props = this.props
+// const {
+// warning,
+// identities,
+// addressBook,
+// conversionRate,
+// } = props
+
+// const {
+// blockGasLimit,
+// newTx,
+// activeCurrency,
+// isValid,
+// } = this.state
+// const { gas, gasPrice } = newTx
+
+// return (
+
+// h('div.send-screen-wrapper', [
+// // Main Send token Card
+// h('div.send-screen-card', [
+
+// h('img.send-eth-icon', { src: '../images/eth_logo.svg' }),
+
+// h('div.send-screen__title', 'Send'),
+
+// h('div.send-screen__subtitle', 'Send Ethereum to anyone with an Ethereum account'),
+
+// this.renderFromInput(this.state.newTx.from, identities),
+
+// this.renderToInput(this.state.newTx.to, identities, addressBook),
+
+// this.renderAmountInput(activeCurrency),
+
+// this.renderGasInput(
+// gasPrice || '0x0',
+// gas || '0x0',
+// activeCurrency,
+// conversionRate,
+// blockGasLimit
+// ),
+
+// this.renderMemoInput(),
+
+// this.renderErrorMessage(null, warning),
+
+// ]),
+
+// // Buttons underneath card
+// h('section.flex-column.flex-center', [
+// h('button.btn-secondary.send-screen__send-button', {
+// className: !isValid && 'send-screen__send-button__disabled',
+// onClick: (event) => isValid && this.onSubmit(event),
+// }, 'Next'),
+// h('button.btn-tertiary.send-screen__cancel-button', {
+// onClick: this.back,
+// }, 'Cancel'),
+// ]),
+// ])
+
+// )
+// }
+
+// SendTransactionScreen.prototype.toggleTooltip = function () {
+// this.setState({ tooltipIsOpen: !this.state.tooltipIsOpen })
+// }
+
+// SendTransactionScreen.prototype.closeTooltip = function () {
+// this.setState({ tooltipIsOpen: false })
+// }
+
+// SendTransactionScreen.prototype.setActiveCurrency = function (newCurrency) {
+// this.setState({ activeCurrency: newCurrency })
+// }
+
+// SendTransactionScreen.prototype.back = function () {
+// var address = this.props.address
+// this.props.dispatch(backToAccountDetail(address))
+// }
+
+// SendTransactionScreen.prototype.validate = function (balance, amountToSend, { to, from }) {
+// const sufficientBalance = conversionGreaterThan(
+// {
+// value: balance,
+// fromNumericBase: 'hex',
+// },
+// {
+// value: amountToSend,
+// fromNumericBase: 'hex',
+// },
+// )
+
+// const amountLessThanZero = conversionGreaterThan(
+// {
+// value: 0,
+// fromNumericBase: 'dec',
+// },
+// {
+// value: amountToSend,
+// fromNumericBase: 'hex',
+// },
+// )
+
+// const errors = {}
+
+// if (!sufficientBalance) {
+// errors.amount = 'Insufficient funds.'
+// }
+
+// if (amountLessThanZero) {
+// errors.amount = 'Can not send negative amounts of ETH.'
+// }
+
+// if (!from) {
+// errors.from = 'Required'
+// }
+
+// if (from && !isValidAddress(from)) {
+// errors.from = 'Sender address is invalid.'
+// }
+
+// if (!to) {
+// errors.to = 'Required'
+// }
+
+// if (to && !isValidAddress(to)) {
+// errors.to = 'Recipient address is invalid.'
+// }
+
+// // if (txData && !isHex(stripHexPrefix(txData))) {
+// // message = 'Transaction data must be hex string.'
+// // return this.props.dispatch(displayWarning(message))
+// // }
+
+// return {
+// isValid: allNull(errors),
+// errors,
+// }
+// }
+
+// SendTransactionScreen.prototype.getAmountToSend = function (amount) {
+// const { activeCurrency } = this.state
+// const { conversionRate } = this.props
+
+// return conversionUtil(amount, {
+// fromNumericBase: 'dec',
+// toNumericBase: 'hex',
+// fromCurrency: activeCurrency,
+// toCurrency: 'ETH',
+// toDenomination: 'WEI',
+// conversionRate,
+// invertConversionRate: activeCurrency !== 'ETH',
+// })
+// }
+
+// SendTransactionScreen.prototype.setErrorsFor = function (field) {
+// const { balance } = this.props
+// const { newTx, errors: previousErrors } = this.state
+// const { amountToSend } = newTx
+
+// const {
+// isValid,
+// errors: newErrors
+// } = this.validate(balance, amountToSend, newTx)
+
+// const nextErrors = Object.assign({}, previousErrors, {
+// [field]: newErrors[field] || null
+// })
+
+// if (!isValid) {
+// this.setState({
+// errors: nextErrors,
+// isValid,
+// })
+// }
+// }
+
+// SendTransactionScreen.prototype.clearErrorsFor = function (field) {
+// const { errors: previousErrors } = this.state
+// const nextErrors = Object.assign({}, previousErrors, {
+// [field]: null
+// })
+
+// this.setState({
+// errors: nextErrors,
+// isValid: allNull(nextErrors),
+// })
+// }
+
+// SendTransactionScreen.prototype.onSubmit = function (event) {
+// event.preventDefault()
+// const { warning, balance } = this.props
+// const state = this.state || {}
+
+// const recipient = state.newTx.to
+// const sender = state.newTx.from
+// const nickname = state.nickname || ' '
+
+// // TODO: convert this to hex when created and include it in send
+// const txData = state.newTx.memo
+
+// this.props.dispatch(hideWarning())
+
+// this.props.dispatch(addToAddressBook(recipient, nickname))
+
+// var txParams = {
+// from: this.state.newTx.from,
+// to: this.state.newTx.to,
+
+// value: this.state.newTx.amountToSend,
+
+// gas: this.state.newTx.gas,
+// gasPrice: this.state.newTx.gasPrice,
+// }
+
+// if (recipient) txParams.to = addHexPrefix(recipient)
+// if (txData) txParams.data = txData
+
+// this.props.dispatch(signTx(txParams))
+// }
diff --git a/ui/app/settings.js b/ui/app/settings.js
new file mode 100644
index 000000000..466f739d5
--- /dev/null
+++ b/ui/app/settings.js
@@ -0,0 +1,447 @@
+const { Component } = require('react')
+const PropTypes = require('prop-types')
+const h = require('react-hyperscript')
+const { connect } = require('react-redux')
+const actions = require('./actions')
+const infuraCurrencies = require('./infura-conversion.json')
+const validUrl = require('valid-url')
+const { exportAsFile } = require('./util')
+const TabBar = require('./components/tab-bar')
+const SimpleDropdown = require('./components/dropdowns/simple-dropdown')
+const ToggleButton = require('react-toggle-button')
+const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+
+const getInfuraCurrencyOptions = () => {
+ const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
+ return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
+ })
+
+ return sortedCurrencies.map(({ quote: { code, name } }) => {
+ return {
+ displayValue: `${code.toUpperCase()} - ${name}`,
+ key: code,
+ value: code,
+ }
+ })
+}
+
+class Settings extends Component {
+ constructor (props) {
+ super(props)
+
+ const { tab } = props
+ const activeTab = tab === 'info' ? 'info' : 'settings'
+
+ this.state = {
+ activeTab,
+ newRpc: '',
+ }
+ }
+
+ renderTabs () {
+ const { activeTab } = this.state
+
+ return h('div.settings__tabs', [
+ h(TabBar, {
+ tabs: [
+ { content: 'Settings', key: 'settings' },
+ { content: 'Info', key: 'info' },
+ ],
+ defaultTab: activeTab,
+ tabSelected: key => this.setState({ activeTab: key }),
+ }),
+ ])
+ }
+
+ renderBlockieOptIn () {
+ const { metamask: { useBlockie }, setUseBlockie } = this.props
+
+ return h('div.settings__content-row', [
+ h('div.settings__content-item', [
+ h('span', 'Use Blockies Identicon'),
+ ]),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h(ToggleButton, {
+ value: useBlockie,
+ onToggle: (value) => setUseBlockie(!value),
+ activeLabel: '',
+ inactiveLabel: '',
+ }),
+ ]),
+ ]),
+ ])
+ }
+
+ renderCurrentConversion () {
+ const { metamask: { currentCurrency, conversionDate }, setCurrentCurrency } = this.props
+
+ return h('div.settings__content-row', [
+ h('div.settings__content-item', [
+ h('span', 'Current Conversion'),
+ h('span.settings__content-description', `Updated ${Date(conversionDate)}`),
+ ]),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h(SimpleDropdown, {
+ placeholder: 'Select Currency',
+ options: getInfuraCurrencyOptions(),
+ selectedOption: currentCurrency,
+ onSelect: newCurrency => setCurrentCurrency(newCurrency),
+ }),
+ ]),
+ ]),
+ ])
+ }
+
+ renderCurrentProvider () {
+ const { metamask: { provider = {} } } = this.props
+ let title, value, color
+
+ switch (provider.type) {
+
+ case 'mainnet':
+ title = 'Current Network'
+ value = 'Main Ethereum Network'
+ color = '#038789'
+ break
+
+ case 'ropsten':
+ title = 'Current Network'
+ value = 'Ropsten Test Network'
+ color = '#e91550'
+ break
+
+ case 'kovan':
+ title = 'Current Network'
+ value = 'Kovan Test Network'
+ color = '#690496'
+ break
+
+ case 'rinkeby':
+ title = 'Current Network'
+ value = 'Rinkeby Test Network'
+ color = '#ebb33f'
+ break
+
+ default:
+ title = 'Current RPC'
+ value = provider.rpcTarget
+ }
+
+ return h('div.settings__content-row', [
+ h('div.settings__content-item', title),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('div.settings__provider-wrapper', [
+ h('div.settings__provider-icon', { style: { background: color } }),
+ h('div', value),
+ ]),
+ ]),
+ ]),
+ ])
+ }
+
+ renderNewRpcUrl () {
+ return (
+ h('div.settings__content-row', [
+ h('div.settings__content-item', [
+ h('span', 'New RPC URL'),
+ ]),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('input.settings__input', {
+ placeholder: 'New RPC URL',
+ onChange: event => this.setState({ newRpc: event.target.value }),
+ onKeyPress: event => {
+ if (event.key === 'Enter') {
+ this.validateRpc(this.state.newRpc)
+ }
+ },
+ }),
+ h('div.settings__rpc-save-button', {
+ onClick: event => {
+ event.preventDefault()
+ this.validateRpc(this.state.newRpc)
+ },
+ }, 'Save'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ validateRpc (newRpc) {
+ const { setRpcTarget, displayWarning } = this.props
+
+ if (validUrl.isWebUri(newRpc)) {
+ setRpcTarget(newRpc)
+ } else {
+ const appendedRpc = `http://${newRpc}`
+
+ if (validUrl.isWebUri(appendedRpc)) {
+ displayWarning('URIs require the appropriate HTTP/HTTPS prefix.')
+ } else {
+ displayWarning('Invalid RPC URI')
+ }
+ }
+ }
+
+ renderStateLogs () {
+ return (
+ h('div.settings__content-row', [
+ h('div.settings__content-item', [
+ h('div', 'State Logs'),
+ h(
+ 'div.settings__content-description',
+ 'State logs contain your public account addresses and sent transactions.'
+ ),
+ ]),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('button.settings__clear-button', {
+ onClick (event) {
+ window.logStateString((err, result) => {
+ if (err) {
+ this.state.dispatch(actions.displayWarning('Error in retrieving state logs.'))
+ } else {
+ exportAsFile('MetaMask State Logs.json', result)
+ }
+ })
+ },
+ }, 'Download State Logs'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ renderSeedWords () {
+ const { revealSeedConfirmation } = this.props
+
+ return (
+ h('div.settings__content-row', [
+ h('div.settings__content-item', 'Reveal Seed Words'),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('button.settings__clear-button.settings__clear-button--red', {
+ onClick (event) {
+ event.preventDefault()
+ revealSeedConfirmation()
+ },
+ }, 'Reveal Seed Words'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ renderOldUI () {
+ const { setFeatureFlagToBeta } = this.props
+
+ return (
+ h('div.settings__content-row', [
+ h('div.settings__content-item', 'Use old UI'),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('button.settings__clear-button.settings__clear-button--orange', {
+ onClick (event) {
+ event.preventDefault()
+ setFeatureFlagToBeta()
+ },
+ }, 'Use old UI'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ renderResetAccount () {
+ const { showResetAccountConfirmationModal } = this.props
+
+ return h('div.settings__content-row', [
+ h('div.settings__content-item', 'Reset Account'),
+ h('div.settings__content-item', [
+ h('div.settings__content-item-col', [
+ h('button.settings__clear-button.settings__clear-button--orange', {
+ onClick (event) {
+ event.preventDefault()
+ showResetAccountConfirmationModal()
+ },
+ }, 'Reset Account'),
+ ]),
+ ]),
+ ])
+ }
+
+ renderSettingsContent () {
+ const { warning, isMascara } = this.props
+
+ return (
+ h('div.settings__content', [
+ warning && h('div.settings__error', warning),
+ this.renderCurrentConversion(),
+ // this.renderCurrentProvider(),
+ this.renderNewRpcUrl(),
+ this.renderStateLogs(),
+ this.renderSeedWords(),
+ !isMascara && this.renderOldUI(),
+ this.renderResetAccount(),
+ this.renderBlockieOptIn(),
+ ])
+ )
+ }
+
+ renderLogo () {
+ return (
+ h('div.settings__info-logo-wrapper', [
+ h('img.settings__info-logo', { src: 'images/info-logo.png' }),
+ ])
+ )
+ }
+
+ renderInfoLinks () {
+ return (
+ h('div.settings__content-item.settings__content-item--without-height', [
+ h('div.settings__info-link-header', 'Links'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/privacy.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Privacy Policy'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/terms.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Terms of Use'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/attributions.html',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Attributions'),
+ ]),
+ ]),
+ h('hr.settings__info-separator'),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://support.metamask.io',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our Support Center'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ href: 'https://metamask.io/',
+ target: '_blank',
+ }, [
+ h('span.settings__info-link', 'Visit our web site'),
+ ]),
+ ]),
+ h('div.settings__info-link-item', [
+ h('a', {
+ target: '_blank',
+ href: 'mailto:help@metamask.io?subject=Feedback',
+ }, [
+ h('span.settings__info-link', 'Email us!'),
+ ]),
+ ]),
+ ])
+ )
+ }
+
+ renderInfoContent () {
+ const version = global.platform.getVersion()
+
+ return (
+ h('div.settings__content', [
+ h('div.settings__content-row', [
+ h('div.settings__content-item.settings__content-item--without-height', [
+ this.renderLogo(),
+ h('div.settings__info-item', [
+ h('div.settings__info-version-header', 'MetaMask Version'),
+ h('div.settings__info-version-number', `${version}`),
+ ]),
+ h('div.settings__info-item', [
+ h(
+ 'div.settings__info-about',
+ 'MetaMask is designed and built in California.'
+ ),
+ ]),
+ ]),
+ this.renderInfoLinks(),
+ ]),
+ ])
+ )
+ }
+
+ render () {
+ const { goHome } = this.props
+ const { activeTab } = this.state
+
+ return (
+ h('.main-container.settings', {}, [
+ h('.settings__header', [
+ h('div.settings__close-button', {
+ onClick: goHome,
+ }),
+ this.renderTabs(),
+ ]),
+
+ activeTab === 'settings'
+ ? this.renderSettingsContent()
+ : this.renderInfoContent(),
+ ])
+ )
+ }
+}
+
+Settings.propTypes = {
+ tab: PropTypes.string,
+ metamask: PropTypes.object,
+ setUseBlockie: PropTypes.func,
+ setCurrentCurrency: PropTypes.func,
+ setRpcTarget: PropTypes.func,
+ displayWarning: PropTypes.func,
+ revealSeedConfirmation: PropTypes.func,
+ setFeatureFlagToBeta: PropTypes.func,
+ showResetAccountConfirmationModal: PropTypes.func,
+ warning: PropTypes.string,
+ goHome: PropTypes.func,
+ isMascara: PropTypes.bool,
+}
+
+const mapStateToProps = state => {
+ return {
+ metamask: state.metamask,
+ warning: state.appState.warning,
+ isMascara: state.metamask.isMascara,
+ }
+}
+
+const mapDispatchToProps = dispatch => {
+ return {
+ goHome: () => dispatch(actions.goHome()),
+ setCurrentCurrency: currency => dispatch(actions.setCurrentCurrency(currency)),
+ setRpcTarget: newRpc => dispatch(actions.setRpcTarget(newRpc)),
+ displayWarning: warning => dispatch(actions.displayWarning(warning)),
+ revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()),
+ setUseBlockie: value => dispatch(actions.setUseBlockie(value)),
+ setFeatureFlagToBeta: () => {
+ return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
+ },
+ showResetAccountConfirmationModal: () => {
+ return dispatch(actions.showModal({ name: 'CONFIRM_RESET_ACCOUNT' }))
+ },
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(Settings)
diff --git a/ui/app/token-tracker.js b/ui/app/token-tracker.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ui/app/token-tracker.js
diff --git a/ui/app/token-util.js b/ui/app/token-util.js
new file mode 100644
index 000000000..f84051ef5
--- /dev/null
+++ b/ui/app/token-util.js
@@ -0,0 +1,45 @@
+const abi = require('human-standard-token-abi')
+const Eth = require('ethjs-query')
+const EthContract = require('ethjs-contract')
+
+const tokenInfoGetter = function () {
+ if (typeof global.ethereumProvider === 'undefined') return
+
+ const eth = new Eth(global.ethereumProvider)
+ const contract = new EthContract(eth)
+ const TokenContract = contract(abi)
+
+ const tokens = {}
+
+ return async (address) => {
+ if (tokens[address]) {
+ return tokens[address]
+ }
+
+ const contract = TokenContract.at(address)
+
+ const result = await Promise.all([
+ contract.symbol(),
+ contract.decimals(),
+ ])
+
+ const [ symbol = [], decimals = [] ] = result
+
+ tokens[address] = { symbol: symbol[0], decimals: decimals[0] }
+
+ return tokens[address]
+ }
+}
+
+function calcTokenAmount (value, decimals) {
+ const multiplier = Math.pow(10, Number(decimals || 0))
+ const amount = Number(value / multiplier)
+
+ return amount
+}
+
+
+module.exports = {
+ tokenInfoGetter,
+ calcTokenAmount,
+}
diff --git a/ui/app/unlock.js b/ui/app/unlock.js
index 4180791c4..13c3f1274 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -5,6 +5,8 @@ const connect = require('react-redux').connect
const actions = require('./actions')
const getCaretCoordinates = require('textarea-caret')
const EventEmitter = require('events').EventEmitter
+const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums
+const environmentType = require('../../app/scripts/lib/environment-type')
const Mascot = require('./components/mascot')
@@ -50,7 +52,7 @@ UnlockScreen.prototype.render = function () {
id: 'password-box',
placeholder: 'enter password',
style: {
-
+ background: 'white',
},
onKeyPress: this.onKeyPress.bind(this),
onInput: this.inputChanged.bind(this),
@@ -74,7 +76,12 @@ UnlockScreen.prototype.render = function () {
h('.flex-row.flex-center.flex-grow', [
h('p.pointer', {
- onClick: () => this.props.dispatch(actions.forgotPassword()),
+ onClick: () => {
+ this.props.dispatch(actions.markPasswordForgotten())
+ if (environmentType() === 'popup') {
+ global.platform.openExtensionInBrowser()
+ }
+ },
style: {
fontSize: '0.8em',
color: 'rgb(247, 134, 28)',
@@ -82,6 +89,22 @@ UnlockScreen.prototype.render = function () {
},
}, 'Restore from seed phrase'),
]),
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => {
+ this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
+ .then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
+ },
+ style: {
+ fontSize: '0.8em',
+ color: '#aeaeae',
+ textDecoration: 'underline',
+ marginTop: '32px',
+ },
+ }, 'Use classic interface'),
+ ]),
+
])
)
}
diff --git a/ui/app/util.js b/ui/app/util.js
index 293f4228c..800ccb218 100644
--- a/ui/app/util.js
+++ b/ui/app/util.js
@@ -1,4 +1,16 @@
+const abi = require('human-standard-token-abi')
const ethUtil = require('ethereumjs-util')
+const hexToBn = require('../../app/scripts/lib/hex-to-bn')
+const vreme = new (require('vreme'))()
+
+const MIN_GAS_PRICE_GWEI_BN = new ethUtil.BN(1)
+const GWEI_FACTOR = new ethUtil.BN(1e9)
+const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR)
+
+// formatData :: ( date: <Unix Timestamp> ) -> String
+function formatDate (date) {
+ return vreme.format(new Date(date), 'March 16 2014 14:30')
+}
var valueTable = {
wei: '1000000000000000000',
@@ -36,8 +48,15 @@ module.exports = {
valueTable: valueTable,
bnTable: bnTable,
isHex: isHex,
+ formatDate,
+ bnMultiplyByFraction,
+ getTxFeeBn,
+ shortenBalance,
+ getContractAtAddress,
exportAsFile: exportAsFile,
isInvalidChecksumAddress,
+ allNull,
+ getTokenAddressFromTokenObject,
}
function valuesFor (obj) {
@@ -227,6 +246,24 @@ function isHex (str) {
return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/))
}
+function bnMultiplyByFraction (targetBN, numerator, denominator) {
+ const numBN = new ethUtil.BN(numerator)
+ const denomBN = new ethUtil.BN(denominator)
+ return targetBN.mul(numBN).div(denomBN)
+}
+
+function getTxFeeBn (gas, gasPrice = MIN_GAS_PRICE_BN.toString(16), blockGasLimit) {
+ const gasBn = hexToBn(gas)
+ const gasPriceBn = hexToBn(gasPrice)
+ const txFeeBn = gasBn.mul(gasPriceBn)
+
+ return txFeeBn.toString(16)
+}
+
+function getContractAtAddress (tokenAddress) {
+ return global.eth.contract(abi).at(tokenAddress)
+}
+
function exportAsFile (filename, data) {
// source: https://stackoverflow.com/a/33542499 by Ludovic Feltz
const blob = new Blob([data], {type: 'text/csv'})
@@ -241,3 +278,11 @@ function exportAsFile (filename, data) {
document.body.removeChild(elem)
}
}
+
+function allNull (obj) {
+ return Object.entries(obj).every(([key, value]) => value === null)
+}
+
+function getTokenAddressFromTokenObject (token) {
+ return Object.values(token)[0].address.toLowerCase()
+}
diff --git a/ui/css.js b/ui/css.js
index 21b311c28..0d0f60806 100644
--- a/ui/css.js
+++ b/ui/css.js
@@ -4,11 +4,7 @@ const path = require('path')
module.exports = bundleCss
var cssFiles = {
- 'fonts.css': fs.readFileSync(path.join(__dirname, '/app/css/fonts.css'), 'utf8'),
- 'reset.css': fs.readFileSync(path.join(__dirname, '/app/css/reset.css'), 'utf8'),
- 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'),
- 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'),
- 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'),
+ 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/output/index.css'), 'utf8'),
'first-time.css': fs.readFileSync(path.join(__dirname, '../mascara/src/app/first-time/index.css'), 'utf8'),
'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
diff --git a/ui/index.js b/ui/index.js
index ae05cbe67..bc3676c1f 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -4,11 +4,12 @@ const Root = require('./app/root')
const actions = require('./app/actions')
const configureStore = require('./app/store')
const txHelper = require('./lib/tx-helper')
+const { OLD_UI_NETWORK_TYPE, BETA_UI_NETWORK_TYPE } = require('../app/scripts/config').enums
+
global.log = require('loglevel')
module.exports = launchMetamaskUi
-
log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
function launchMetamaskUi (opts, cb) {
@@ -36,10 +37,17 @@ function startApp (metamaskState, accountManager, opts) {
networkVersion: opts.networkVersion,
})
+ const useBetaUi = metamaskState.featureFlags.betaUI
+ const networkEndpointType = useBetaUi ? BETA_UI_NETWORK_TYPE : OLD_UI_NETWORK_TYPE
+ store.dispatch(actions.setNetworkEndpoints(networkEndpointType))
+
// if unconfirmed txs, start on txConf page
const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network)
- if (unapprovedTxsAll.length > 0) {
- store.dispatch(actions.showConfTxPage())
+ const numberOfUnapprivedTx = unapprovedTxsAll.length
+ if (numberOfUnapprivedTx > 0) {
+ store.dispatch(actions.showConfTxPage({
+ id: unapprovedTxsAll[numberOfUnapprivedTx - 1].id,
+ }))
}
accountManager.on('update', function (metamaskState) {
diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js
new file mode 100644
index 000000000..037d990fa
--- /dev/null
+++ b/ui/lib/account-link.js
@@ -0,0 +1,26 @@
+module.exports = function (address, network) {
+ const net = parseInt(network)
+ let link
+ switch (net) {
+ case 1: // main net
+ link = `https://etherscan.io/address/${address}`
+ break
+ case 2: // morden test net
+ link = `https://morden.etherscan.io/address/${address}`
+ break
+ case 3: // ropsten test net
+ link = `https://ropsten.etherscan.io/address/${address}`
+ break
+ case 4: // rinkeby test net
+ link = `https://rinkeby.etherscan.io/address/${address}`
+ break
+ case 42: // kovan test net
+ link = `https://kovan.etherscan.io/address/${address}`
+ break
+ default:
+ link = ''
+ break
+ }
+
+ return link
+}
diff --git a/ui/lib/blockies.js b/ui/lib/blockies.js
new file mode 100644
index 000000000..ee5a2a5ca
--- /dev/null
+++ b/ui/lib/blockies.js
@@ -0,0 +1,364 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (factory((global.blockies = {})));
+}(this, (function (exports) { 'use strict';
+
+ /**
+ * A handy class to calculate color values.
+ *
+ * @version 1.0
+ * @author Robert Eisele <robert@xarg.org>
+ * @copyright Copyright (c) 2010, Robert Eisele
+ * @link http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ *
+ */
+
+
+// helper functions for that ctx
+ function write(buffer, offs) {
+ for (var i = 2; i < arguments.length; i++) {
+ for (var j = 0; j < arguments[i].length; j++) {
+ buffer[offs++] = arguments[i].charAt(j);
+ }
+ }
+ }
+
+ function byte2(w) {
+ return String.fromCharCode((w >> 8) & 255, w & 255);
+ }
+
+ function byte4(w) {
+ return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255);
+ }
+
+ function byte2lsb(w) {
+ return String.fromCharCode(w & 255, (w >> 8) & 255);
+ }
+
+ var PNG = function(width,height,depth) {
+
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+
+ // pixel data and row filter identifier size
+ this.pix_size = height * (width + 1);
+
+ // deflate header, pix_size, block headers, adler32 checksum
+ this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4;
+
+ // offsets and sizes of Png chunks
+ this.ihdr_offs = 0; // IHDR offset and size
+ this.ihdr_size = 4 + 4 + 13 + 4;
+ this.plte_offs = this.ihdr_offs + this.ihdr_size; // PLTE offset and size
+ this.plte_size = 4 + 4 + 3 * depth + 4;
+ this.trns_offs = this.plte_offs + this.plte_size; // tRNS offset and size
+ this.trns_size = 4 + 4 + depth + 4;
+ this.idat_offs = this.trns_offs + this.trns_size; // IDAT offset and size
+ this.idat_size = 4 + 4 + this.data_size + 4;
+ this.iend_offs = this.idat_offs + this.idat_size; // IEND offset and size
+ this.iend_size = 4 + 4 + 4;
+ this.buffer_size = this.iend_offs + this.iend_size; // total PNG size
+
+ this.buffer = new Array();
+ this.palette = new Object();
+ this.pindex = 0;
+
+ var _crc32 = new Array();
+
+ // initialize buffer with zero bytes
+ for (var i = 0; i < this.buffer_size; i++) {
+ this.buffer[i] = "\x00";
+ }
+
+ // initialize non-zero elements
+ write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), "\x08\x03");
+ write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE');
+ write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS');
+ write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT');
+ write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND');
+
+ // initialize deflate header
+ var header = ((8 + (7 << 4)) << 8) | (3 << 6);
+ header+= 31 - (header % 31);
+
+ write(this.buffer, this.idat_offs + 8, byte2(header));
+
+ // initialize deflate block headers
+ for (var i = 0; (i << 16) - 1 < this.pix_size; i++) {
+ var size, bits;
+ if (i + 0xffff < this.pix_size) {
+ size = 0xffff;
+ bits = "\x00";
+ } else {
+ size = this.pix_size - (i << 16) - i;
+ bits = "\x01";
+ }
+ write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size));
+ }
+
+ /* Create crc32 lookup table */
+ for (var i = 0; i < 256; i++) {
+ var c = i;
+ for (var j = 0; j < 8; j++) {
+ if (c & 1) {
+ c = -306674912 ^ ((c >> 1) & 0x7fffffff);
+ } else {
+ c = (c >> 1) & 0x7fffffff;
+ }
+ }
+ _crc32[i] = c;
+ }
+
+ // compute the index into a png for a given pixel
+ this.index = function(x,y) {
+ var i = y * (this.width + 1) + x + 1;
+ var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i;
+ return j;
+ };
+
+ // convert a color and build up the palette
+ this.color = function(red, green, blue, alpha) {
+
+ alpha = alpha >= 0 ? alpha : 255;
+ var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue;
+
+ if (typeof this.palette[color] == "undefined") {
+ if (this.pindex == this.depth) return "\x00";
+
+ var ndx = this.plte_offs + 8 + 3 * this.pindex;
+
+ this.buffer[ndx + 0] = String.fromCharCode(red);
+ this.buffer[ndx + 1] = String.fromCharCode(green);
+ this.buffer[ndx + 2] = String.fromCharCode(blue);
+ this.buffer[this.trns_offs+8+this.pindex] = String.fromCharCode(alpha);
+
+ this.palette[color] = String.fromCharCode(this.pindex++);
+ }
+ return this.palette[color];
+ };
+
+ // output a PNG string, Base64 encoded
+ this.getBase64 = function() {
+
+ var s = this.getDump();
+
+ var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ var c1, c2, c3, e1, e2, e3, e4;
+ var l = s.length;
+ var i = 0;
+ var r = "";
+
+ do {
+ c1 = s.charCodeAt(i);
+ e1 = c1 >> 2;
+ c2 = s.charCodeAt(i+1);
+ e2 = ((c1 & 3) << 4) | (c2 >> 4);
+ c3 = s.charCodeAt(i+2);
+ if (l < i+2) { e3 = 64; } else { e3 = ((c2 & 0xf) << 2) | (c3 >> 6); }
+ if (l < i+3) { e4 = 64; } else { e4 = c3 & 0x3f; }
+ r+= ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4);
+ } while ((i+= 3) < l);
+ return r;
+ };
+
+ // output a PNG string
+ this.getDump = function() {
+
+ // compute adler32 of output pixels + row filter bytes
+ var BASE = 65521; /* largest prime smaller than 65536 */
+ var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+ var s1 = 1;
+ var s2 = 0;
+ var n = NMAX;
+
+ for (var y = 0; y < this.height; y++) {
+ for (var x = -1; x < this.width; x++) {
+ s1+= this.buffer[this.index(x, y)].charCodeAt(0);
+ s2+= s1;
+ if ((n-= 1) == 0) {
+ s1%= BASE;
+ s2%= BASE;
+ n = NMAX;
+ }
+ }
+ }
+ s1%= BASE;
+ s2%= BASE;
+ write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1));
+
+ // compute crc32 of the PNG chunks
+ function crc32(png, offs, size) {
+ var crc = -1;
+ for (var i = 4; i < size-4; i += 1) {
+ crc = _crc32[(crc ^ png[offs+i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff);
+ }
+ write(png, offs+size-4, byte4(crc ^ -1));
+ }
+
+ crc32(this.buffer, this.ihdr_offs, this.ihdr_size);
+ crc32(this.buffer, this.plte_offs, this.plte_size);
+ crc32(this.buffer, this.trns_offs, this.trns_size);
+ crc32(this.buffer, this.idat_offs, this.idat_size);
+ crc32(this.buffer, this.iend_offs, this.iend_size);
+
+ // convert PNG to string
+ return "\x89PNG\r\n\x1A\n"+this.buffer.join('');
+ };
+
+ this.fillRect = function (x, y, w, h, color) {
+ for(var i = 0; i < w; i++) {
+ for (var j = 0; j < h; j++) {
+ this.buffer[this.index(x+i, y+j)] = color;
+ }
+ }
+ };
+ };
+
+// https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
+ /**
+ * Converts an HSL color value to RGB. Conversion formula
+ * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
+ * Assumes h, s, and l are contained in the set [0, 1] and
+ * returns r, g, and b in the set [0, 255].
+ *
+ * @param {number} h The hue
+ * @param {number} s The saturation
+ * @param {number} l The lightness
+ * @return {Array} The RGB representation
+ */
+
+ function hue2rgb(p, q, t) {
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ }
+
+ function hsl2rgb(h, s, l){
+ var r, g, b;
+
+ if(s == 0){
+ r = g = b = l; // achromatic
+ }else{
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3);
+ }
+
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255];
+ }
+
+// The random number is a js implementation of the Xorshift PRNG
+ var randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values
+
+ function seedrand(seed) {
+ for (var i = 0; i < randseed.length; i++) {
+ randseed[i] = 0;
+ }
+ for (var i = 0; i < seed.length; i++) {
+ randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i);
+ }
+ }
+
+ function rand() {
+ // based on Java's String.hashCode(), expanded to 4 32bit values
+ var t = randseed[0] ^ (randseed[0] << 11);
+
+ randseed[0] = randseed[1];
+ randseed[1] = randseed[2];
+ randseed[2] = randseed[3];
+ randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);
+
+ return (randseed[3] >>> 0) / (1 << 31 >>> 0);
+ }
+
+ function createColor() {
+ //saturation is the whole color spectrum
+ var h = Math.floor(rand() * 360);
+ //saturation goes from 40 to 100, it avoids greyish colors
+ var s = rand() * 60 + 40;
+ //lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
+ var l = (rand() + rand() + rand() + rand()) * 25;
+
+ return [h / 360,s / 100,l / 100];
+ }
+
+ function createImageData(size) {
+ var width = size; // Only support square icons for now
+ var height = size;
+
+ var dataWidth = Math.ceil(width / 2);
+ var mirrorWidth = width - dataWidth;
+
+ var data = [];
+ for (var y = 0; y < height; y++) {
+ var row = [];
+ for (var x = 0; x < dataWidth; x++) {
+ // this makes foreground and background color to have a 43% (1/2.3) probability
+ // spot color has 13% chance
+ row[x] = Math.floor(rand() * 2.3);
+ }
+ var r = row.slice(0, mirrorWidth);
+ r.reverse();
+ row = row.concat(r);
+
+ for (var i = 0; i < row.length; i++) {
+ data.push(row[i]);
+ }
+ }
+
+ return data;
+ }
+
+ function buildOpts(opts) {
+ if (!opts.seed) {
+ throw 'No seed provided'
+ }
+
+ seedrand(opts.seed);
+
+ return Object.assign({
+ size: 8,
+ scale: 16,
+ color: createColor(),
+ bgcolor: createColor(),
+ spotcolor: createColor(),
+ }, opts)
+ }
+
+ function toDataUrl(address) {
+ const opts = buildOpts({seed: address.toLowerCase()});
+
+ const imageData = createImageData(opts.size);
+ const width = Math.sqrt(imageData.length);
+
+ const p = new PNG(opts.size*opts.scale, opts.size*opts.scale, 3);
+ const bgcolor = p.color(...hsl2rgb(...opts.bgcolor));
+ const color = p.color(...hsl2rgb(...opts.color));
+ const spotcolor = p.color(...hsl2rgb(...opts.spotcolor));
+
+ for (var i = 0; i < imageData.length; i++) {
+ var row = Math.floor(i / width);
+ var col = i % width;
+ // if data is 0, leave the background
+ if (imageData[i]) {
+ // if data is 2, choose spot color, if 1 choose foreground
+ const pngColor = imageData[i] == 1 ? color : spotcolor;
+ p.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale, pngColor);
+ }
+ }
+ return `data:image/png;base64,${p.getBase64()}`;
+ }
+
+ exports.toDataUrl = toDataUrl;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/ui/lib/feature-toggle-utils.js b/ui/lib/feature-toggle-utils.js
new file mode 100644
index 000000000..6d4e461ca
--- /dev/null
+++ b/ui/lib/feature-toggle-utils.js
@@ -0,0 +1,11 @@
+function checkFeatureToggle (name) {
+ const queryPairMap = window.location.search.substr(1).split('&')
+ .map(pair => pair.split('='))
+ .reduce((pairs, [key, value]) => ({...pairs, [key]: value }), {})
+ const featureToggles = queryPairMap['ft'] ? queryPairMap['ft'].split(',') : []
+ return Boolean(featureToggles.find(ft => ft === name))
+}
+
+module.exports = {
+ checkFeatureToggle,
+}
diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js
index 27a74de66..31498a3a9 100644
--- a/ui/lib/icon-factory.js
+++ b/ui/lib/icon-factory.js
@@ -53,7 +53,7 @@ function imageElFor (address) {
const path = `images/contract/${fileName}`
const img = document.createElement('img')
img.src = path
- img.style.width = '75%'
+ img.style.width = '100%'
return img
}
diff --git a/ui/lib/is-mobile-view.js b/ui/lib/is-mobile-view.js
new file mode 100644
index 000000000..78fd6cb54
--- /dev/null
+++ b/ui/lib/is-mobile-view.js
@@ -0,0 +1,5 @@
+// Checks if viewport at invoke time fits mobile dimensions
+// isMobileView :: () => Bool
+const isMobileView = () => window.matchMedia('screen and (max-width: 575px)').matches
+
+module.exports = isMobileView
diff --git a/yarn.lock b/yarn.lock
index 428a56c99..a24806923 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,59 @@
# yarn lockfile v1
+"@babel/code-frame@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz#473d021ecc573a2cce1c07d5b509d5215f46ba35"
+ dependencies:
+ chalk "^2.0.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
+"@babel/helper-function-name@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz#afe63ad799209989348b1109b44feb66aa245f57"
+ dependencies:
+ "@babel/helper-get-function-arity" "7.0.0-beta.31"
+ "@babel/template" "7.0.0-beta.31"
+ "@babel/traverse" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.31"
+
+"@babel/helper-get-function-arity@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz#1176d79252741218e0aec872ada07efb2b37a493"
+ dependencies:
+ "@babel/types" "7.0.0-beta.31"
+
+"@babel/template@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.31"
+ babylon "7.0.0-beta.31"
+ lodash "^4.2.0"
+
+"@babel/traverse@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.31.tgz#db399499ad74aefda014f0c10321ab255134b1df"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.31"
+ "@babel/helper-function-name" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.31"
+ babylon "7.0.0-beta.31"
+ debug "^3.0.1"
+ globals "^10.0.0"
+ invariant "^2.2.0"
+ lodash "^4.2.0"
+
+"@babel/types@7.0.0-beta.31":
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.31.tgz#42c9c86784f674c173fb21882ca9643334029de4"
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^2.0.0"
+
"@gulp-sourcemaps/identity-map@1.X":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1"
@@ -19,34 +72,44 @@
normalize-path "^2.0.1"
through2 "^2.0.3"
-"@types/node@^6.0.46":
- version "6.0.88"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.88.tgz#f618f11a944f6a18d92b5c472028728a3e3d4b66"
+"@types/node@*":
+ version "8.5.2"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
+
+JSONStream@^0.8.4:
+ version "0.8.4"
+ resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.8.4.tgz#91657dfe6ff857483066132b4618b62e8f4887bd"
+ dependencies:
+ jsonparse "0.0.5"
+ through ">=2.2.7 <3"
JSONStream@^1.0.3:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea"
dependencies:
jsonparse "^1.2.0"
through ">=2.2.7 <3"
abab@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
abbrev@1:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
-abbrev@1.0.x:
+abi-decoder@^1.0.9:
version "1.0.9"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
-
-abstract-leveldown@2.7.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.0.tgz#985052daf3d7d0ac0029dca8eb793f4cdd2a6834"
+ resolved "https://registry.yarnpkg.com/abi-decoder/-/abi-decoder-1.0.9.tgz#6bcfd86f7f63fbec8573d9778b3a4f92bb92e01f"
dependencies:
- xtend "~4.0.0"
+ babel-core "^6.23.1"
+ babel-loader "^6.3.2"
+ babel-plugin-add-module-exports "^0.2.1"
+ babel-plugin-transform-es2015-modules-amd "^6.22.0"
+ babel-preset-es2015 "^6.22.0"
+ chai "^3.5.0"
+ web3 "^0.18.4"
+ webpack "^2.2.1"
abstract-leveldown@~2.6.0:
version "2.6.3"
@@ -54,6 +117,12 @@ abstract-leveldown@~2.6.0:
dependencies:
xtend "~4.0.0"
+abstract-leveldown@~2.7.1:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93"
+ dependencies:
+ xtend "~4.0.0"
+
accepts@1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca"
@@ -61,18 +130,24 @@ accepts@1.3.3:
mime-types "~2.1.11"
negotiator "0.6.1"
-accepts@~1.3.3, accepts@~1.3.4:
+accepts@~1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f"
dependencies:
mime-types "~2.1.16"
negotiator "0.6.1"
-acorn-globals@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
+acorn-dynamic-import@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4"
+ dependencies:
+ acorn "^4.0.3"
+
+acorn-globals@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538"
dependencies:
- acorn "^4.0.4"
+ acorn "^5.0.0"
acorn-jsx@^3.0.0:
version "3.0.1"
@@ -80,17 +155,17 @@ acorn-jsx@^3.0.0:
dependencies:
acorn "^3.0.4"
-acorn@4.X, acorn@^4.0.3, acorn@^4.0.4:
- version "4.0.13"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
+acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.2, acorn@^5.2.1:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
acorn@^3.0.4:
version "3.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
-acorn@^5.0.0, acorn@^5.0.3, acorn@^5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7"
+acorn@^4.0.3:
+ version "4.0.13"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
aes-js@^0.2.3:
version "0.2.4"
@@ -104,10 +179,14 @@ after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
-ajv-keywords@^1.0.0:
+ajv-keywords@^1.1.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
+ajv-keywords@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+
ajv@^4.7.0, ajv@^4.9.1:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
@@ -115,14 +194,14 @@ ajv@^4.7.0, ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^5.2.0:
- version "5.2.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39"
+ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0:
+ version "5.5.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
- json-stable-stringify "^1.0.1"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
@@ -136,10 +215,34 @@ amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
+ansi-colors@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.0.1.tgz#e94c6c306005af8b482240241e2f3dea4b855ff3"
+ dependencies:
+ ansi-wrap "^0.1.0"
+
+ansi-cyan@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873"
+ dependencies:
+ ansi-wrap "0.1.0"
+
ansi-escapes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
+ansi-gray@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
+ dependencies:
+ ansi-wrap "0.1.0"
+
+ansi-red@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c"
+ dependencies:
+ ansi-wrap "0.1.0"
+
ansi-regex@^0.2.0, ansi-regex@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9"
@@ -166,6 +269,10 @@ ansi-styles@^3.1.0:
dependencies:
color-convert "^1.9.0"
+ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
+
ansicolors@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
@@ -185,6 +292,12 @@ anymatch@^1.3.0:
micromatch "^2.1.5"
normalize-path "^2.0.0"
+append-buffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1"
+ dependencies:
+ buffer-equal "^1.0.0"
+
append-transform@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
@@ -192,8 +305,8 @@ append-transform@^0.4.0:
default-require-extensions "^1.0.0"
aproba@^1.0.3:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
archy@^1.0.0:
version "1.0.0"
@@ -212,9 +325,12 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
-argsparser@^0.0.7:
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/argsparser/-/argsparser-0.0.7.tgz#41c85e0c3de757b350f12e6ed0e490b1e82dbe06"
+arr-diff@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
+ dependencies:
+ arr-flatten "^1.0.1"
+ array-slice "^0.2.3"
arr-diff@^2.0.0:
version "2.0.0"
@@ -222,13 +338,17 @@ arr-diff@^2.0.0:
dependencies:
arr-flatten "^1.0.1"
+arr-diff@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
+
arr-filter@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee"
dependencies:
make-iterator "^1.0.0"
-arr-flatten@^1.0.1:
+arr-flatten@^1.0.1, arr-flatten@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
@@ -238,6 +358,14 @@ arr-map@^2.0.0, arr-map@^2.0.2:
dependencies:
make-iterator "^1.0.0"
+arr-union@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d"
+
+arr-union@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
+
array-differ@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
@@ -254,6 +382,10 @@ array-filter@~0.0.0:
version "0.0.1"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
+array-find-index@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -266,17 +398,21 @@ array-includes@^3.0.3:
es-abstract "^1.7.0"
array-initial@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.0.1.tgz#86122222a29c1ed42347f6334111afa40f8b20ec"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795"
dependencies:
array-slice "^1.0.0"
- is-number "^3.0.0"
+ is-number "^4.0.0"
+
+array-iterate@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.1.tgz#865bf7f8af39d6b0982c60902914ac76bc0108f6"
array-last@^1.1.1:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.2.0.tgz#0884a67ec2ac2a08133fc00f66779cfedb010986"
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336"
dependencies:
- is-number "^3.0.0"
+ is-number "^4.0.0"
array-map@~0.0.0:
version "0.0.0"
@@ -291,8 +427,16 @@ array-slice@^0.2.3:
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
array-slice@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
+
+array-sort@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.0.0.tgz#e73034f00dcc1f40876008fd20feae77bd4b7c2f"
+ resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a"
+ dependencies:
+ default-compare "^1.0.0"
+ get-value "^2.0.6"
+ kind-of "^5.0.2"
array-union@^1.0.1:
version "1.0.2"
@@ -308,6 +452,10 @@ array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+array-unique@^0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
+
arraybuffer.slice@0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca"
@@ -321,8 +469,8 @@ asap@~2.0.3:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
asn1.js@^4.0.0:
- version "4.9.1"
- resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
+ version "4.9.2"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
dependencies:
bn.js "^4.0.0"
inherits "^2.0.1"
@@ -340,7 +488,7 @@ assert-plus@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
-assert@^1.4.0:
+assert@^1.1.1, assert@^1.4.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
dependencies:
@@ -350,6 +498,14 @@ assertion-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
+assign-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+
+ast-types@0.9.6:
+ version "0.9.6"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
+
astw@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917"
@@ -370,8 +526,8 @@ async-each@^1.0.0:
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
async-eventemitter@^0.2.2:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.3.tgz#f79f480dfda6645a97bd6142c017150d63b4e70e"
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca"
dependencies:
async "^2.4.0"
@@ -381,6 +537,10 @@ async-eventemitter@ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a
dependencies:
async "^2.4.0"
+async-foreach@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
+
async-reduce@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/async-reduce/-/async-reduce-0.0.1.tgz#b236b5f376d6fae381cded9006aa7f2c73b17f31"
@@ -391,13 +551,13 @@ async-settle@^1.0.0:
dependencies:
async-done "^1.2.2"
-async@1.x, async@^1.4.0, async@^1.4.2:
+async@^1.4.0, async@^1.4.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
lodash "^4.14.0"
@@ -417,30 +577,52 @@ asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+atob@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
+
atob@~1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
+autoprefixer@^6.0.0:
+ version "6.7.7"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
+ dependencies:
+ browserslist "^1.7.6"
+ caniuse-db "^1.0.30000634"
+ normalize-range "^0.1.2"
+ num2fraction "^1.2.2"
+ postcss "^5.2.16"
+ postcss-value-parser "^3.2.3"
+
+autoprefixer@^7.0.0, autoprefixer@^7.1.2:
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.3.tgz#c2841e38b7940c2d0a9bbffd72c75f33637854f8"
+ dependencies:
+ browserslist "^2.10.0"
+ caniuse-lite "^1.0.30000783"
+ normalize-range "^0.1.2"
+ num2fraction "^1.2.2"
+ postcss "^6.0.14"
+ postcss-value-parser "^3.2.3"
+
await-semaphore@^0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.2.tgz#0ceba1bdb2cfc537496032f167bd8b7dedb97493"
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.3.tgz#2b88018cc8c28e06167ae1cdff02504f1f9688d3"
aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
-aws4@^1.2.1:
+aws-sign2@~0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+
+aws4@^1.2.1, aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
-babel-code-frame@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz#418a7b5f3f7dc9a4670e61b1158b4c5661bec98d"
- dependencies:
- chalk "^2.0.0"
- esutils "^2.0.2"
- js-tokens "^3.0.0"
-
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -449,7 +631,7 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
esutils "^2.0.2"
js-tokens "^3.0.2"
-babel-core@^6.0.14, babel-core@^6.24.1, babel-core@^6.26.0:
+babel-core@^6.0.14, babel-core@^6.23.1, babel-core@^6.24.1, babel-core@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8"
dependencies:
@@ -474,13 +656,15 @@ babel-core@^6.0.14, babel-core@^6.24.1, babel-core@^6.26.0:
source-map "^0.5.6"
babel-eslint@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.0.tgz#ce06f385bdfb5b6d7e603f06222f891abd14c240"
+ version "8.1.2"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.1.2.tgz#a39230b0c20ecbaa19a35d5633bf9b9ca2c8116f"
dependencies:
- babel-code-frame "7.0.0-beta.0"
- babel-traverse "7.0.0-beta.0"
- babel-types "7.0.0-beta.0"
- babylon "7.0.0-beta.22"
+ "@babel/code-frame" "7.0.0-beta.31"
+ "@babel/traverse" "7.0.0-beta.31"
+ "@babel/types" "7.0.0-beta.31"
+ babylon "7.0.0-beta.31"
+ eslint-scope "~3.7.1"
+ eslint-visitor-keys "^1.0.0"
babel-generator@^6.18.0, babel-generator@^6.26.0:
version "6.26.0"
@@ -554,15 +738,6 @@ babel-helper-explode-class@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
-babel-helper-function-name@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz#d1b6779b647e5c5c31ebeb05e13b998e4d352d56"
- dependencies:
- babel-helper-get-function-arity "7.0.0-beta.0"
- babel-template "7.0.0-beta.0"
- babel-traverse "7.0.0-beta.0"
- babel-types "7.0.0-beta.0"
-
babel-helper-function-name@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -573,12 +748,6 @@ babel-helper-function-name@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
-babel-helper-get-function-arity@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz#9d1ab7213bb5efe1ef1638a8ea1489969b5a8b6e"
- dependencies:
- babel-types "7.0.0-beta.0"
-
babel-helper-get-function-arity@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
@@ -636,9 +805,14 @@ babel-helpers@^6.24.1:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-messages@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-beta.0.tgz#6df01296e49fc8fbd0637394326a167f36da817b"
+babel-loader@^6.3.2:
+ version "6.4.1"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca"
+ dependencies:
+ find-cache-dir "^0.1.1"
+ loader-utils "^0.2.16"
+ mkdirp "^0.5.1"
+ object-assign "^4.0.1"
babel-messages@^6.23.0:
version "6.23.0"
@@ -646,6 +820,10 @@ babel-messages@^6.23.0:
dependencies:
babel-runtime "^6.22.0"
+babel-plugin-add-module-exports@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25"
+
babel-plugin-check-es2015-constants@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
@@ -1018,8 +1196,8 @@ babel-polyfill@^6.23.0:
regenerator-runtime "^0.10.5"
babel-preset-env@^1.3.2:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4"
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
dependencies:
babel-plugin-check-es2015-constants "^6.22.0"
babel-plugin-syntax-trailing-function-commas "^6.22.0"
@@ -1152,15 +1330,6 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runti
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
-babel-template@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.0.tgz#85083cf9e4395d5e48bf5154d7a8d6991cafecfb"
- dependencies:
- babel-traverse "7.0.0-beta.0"
- babel-types "7.0.0-beta.0"
- babylon "7.0.0-beta.22"
- lodash "^4.2.0"
-
babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
@@ -1171,20 +1340,6 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
babylon "^6.18.0"
lodash "^4.17.4"
-babel-traverse@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz#da14be9b762f62a2f060db464eaafdd8cd072a41"
- dependencies:
- babel-code-frame "7.0.0-beta.0"
- babel-helper-function-name "7.0.0-beta.0"
- babel-messages "7.0.0-beta.0"
- babel-types "7.0.0-beta.0"
- babylon "7.0.0-beta.22"
- debug "^3.0.1"
- globals "^10.0.0"
- invariant "^2.2.0"
- lodash "^4.2.0"
-
babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
@@ -1199,14 +1354,6 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"
-babel-types@7.0.0-beta.0:
- version "7.0.0-beta.0"
- resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.0.tgz#eb8b6e556470e6dcc4aef982d79ad229469b5169"
- dependencies:
- esutils "^2.0.2"
- lodash "^4.2.0"
- to-fast-properties "^2.0.0"
-
babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
@@ -1216,16 +1363,20 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26
lodash "^4.17.4"
to-fast-properties "^1.0.3"
-babelify@^7.2.0, babelify@^7.3.0:
+babelify@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5"
dependencies:
babel-core "^6.0.14"
object-assign "^4.0.0"
-babylon@7.0.0-beta.22:
- version "7.0.0-beta.22"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.22.tgz#74f0ad82ed7c7c3cfeab74cf684f815104161b65"
+babelify@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3"
+
+babylon@7.0.0-beta.31:
+ version "7.0.0-beta.31"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f"
babylon@^6.18.0:
version "6.18.0"
@@ -1255,6 +1406,14 @@ backo2@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
+bail@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.2.tgz#f7d6c1731630a9f9f0d4d35ed1f962e2074a1764"
+
+balanced-match@^0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -1263,14 +1422,14 @@ base-x@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac"
+base62@0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/base62/-/base62-0.1.1.tgz#7b4174c2f94449753b11c2651c083da841a7b084"
+
base64-arraybuffer@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
-base64-js@0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.2.tgz#024f0f72afa25b75f9c0ee73cd4f55ec1bed9784"
-
base64-js@^1.0.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886"
@@ -1283,6 +1442,18 @@ base64id@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
+base@^0.11.1:
+ version "0.11.2"
+ resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
+ dependencies:
+ cache-base "^1.0.1"
+ class-utils "^0.3.5"
+ component-emitter "^1.2.1"
+ define-property "^1.0.0"
+ isobject "^3.0.1"
+ mixin-deep "^1.2.0"
+ pascalcase "^0.1.1"
+
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
@@ -1322,13 +1493,25 @@ better-assert@~1.0.0:
dependencies:
callsite "1.0.0"
+big.js@^3.1.3:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
+
+bignumber.js@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1"
+
+"bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2":
+ version "2.0.7"
+ resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2"
+
"bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git":
version "2.0.7"
resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934"
binary-extensions@^1.0.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0"
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
binaryextensions@~1.0.0:
version "1.0.1"
@@ -1354,19 +1537,7 @@ bip66@^1.1.3:
dependencies:
safe-buffer "^5.0.1"
-bl@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/bl/-/bl-0.7.0.tgz#3fb0670602ac2878eb770dc2039f1836be62ae5b"
- dependencies:
- readable-stream "~1.0.2"
-
-bl@^0.9.1:
- version "0.9.5"
- resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054"
- dependencies:
- readable-stream "~1.0.26"
-
-bl@^1.0.0:
+bl@^1.2.0, bl@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e"
dependencies:
@@ -1382,9 +1553,9 @@ block-stream@*:
dependencies:
inherits "~2.0.0"
-bluebird@^3.1.1, bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
+bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.5.0:
+ version "3.5.1"
+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
bn.js@4.11.6:
version "4.11.6"
@@ -1394,7 +1565,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.3, bn.js@^4
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
-body-parser@1.18.2:
+body-parser@1.18.2, body-parser@^1.16.1:
version "1.18.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
dependencies:
@@ -1409,21 +1580,6 @@ body-parser@1.18.2:
raw-body "2.3.2"
type-is "~1.6.15"
-body-parser@^1.16.1:
- version "1.18.1"
- resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.1.tgz#9c1629370bcfd42917f30641a2dcbe2ec50d4c26"
- dependencies:
- bytes "3.0.0"
- content-type "~1.0.4"
- debug "2.6.8"
- depd "~1.1.1"
- http-errors "~1.6.2"
- iconv-lite "0.4.19"
- on-finished "~2.3.0"
- qs "6.5.1"
- raw-body "2.3.2"
- type-is "~1.6.15"
-
body-parser@~1.14.0:
version "1.14.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9"
@@ -1449,12 +1605,23 @@ boom@2.x.x:
dependencies:
hoek "2.x.x"
-bops@0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/bops/-/bops-0.0.6.tgz#082d1d55fa01e60dbdc2ebc2dba37f659554cf3a"
+boom@4.x.x:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
+ dependencies:
+ hoek "4.x.x"
+
+boom@5.x.x:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
+ dependencies:
+ hoek "4.x.x"
+
+boron@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/boron/-/boron-0.2.3.tgz#63a1800771c0cb2b0d8f616687c62c1248cfb8a0"
dependencies:
- base64-js "0.0.2"
- to-utf8 "0.0.1"
+ domkit "^0.0.1"
brace-expansion@^1.1.7:
version "1.1.8"
@@ -1477,6 +1644,22 @@ braces@^1.8.2:
preserve "^0.2.0"
repeat-element "^1.1.2"
+braces@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e"
+ dependencies:
+ arr-flatten "^1.1.0"
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ extend-shallow "^2.0.1"
+ fill-range "^4.0.0"
+ isobject "^3.0.1"
+ repeat-element "^1.1.2"
+ snapdragon "^0.8.1"
+ snapdragon-node "^2.0.1"
+ split-string "^3.0.2"
+ to-regex "^3.0.1"
+
brfs@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.4.3.tgz#db675d6f5e923e6df087fca5859c9090aaed3216"
@@ -1490,6 +1673,16 @@ brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+browser-pack@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-5.0.1.tgz#4197719b20c6e0aaa09451c5111e53efb6fbc18d"
+ dependencies:
+ JSONStream "^1.0.3"
+ combine-source-map "~0.6.1"
+ defined "^1.0.0"
+ through2 "^1.0.0"
+ umd "^3.0.0"
+
browser-pack@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531"
@@ -1506,6 +1699,10 @@ browser-passworder@^2.0.3:
dependencies:
browserify-unibabel "^3.0.0"
+browser-process-hrtime@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e"
+
browser-resolve@^1.11.0, browser-resolve@^1.7.0:
version "1.11.2"
resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
@@ -1516,17 +1713,18 @@ browser-stdout@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
-browser-unpack@^0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/browser-unpack/-/browser-unpack-0.2.3.tgz#88fe04cc266257e52650095cd8e0585dc7b6e2f1"
+browser-unpack@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/browser-unpack/-/browser-unpack-1.2.0.tgz#357aee31fc467831684d063e4355e070a782970d"
dependencies:
- concat-stream "~1.2.1"
- esprima-fb "3001.1.0-dev-harmony-fb"
- minimist "0.0.5"
+ acorn "^4.0.3"
+ browser-pack "^5.0.1"
+ concat-stream "^1.5.0"
+ minimist "^1.1.1"
browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6:
- version "1.0.8"
- resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.8.tgz#c8fa3b1b7585bb7ba77c5560b60996ddec6d5309"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
dependencies:
buffer-xor "^1.0.3"
cipher-base "^1.0.0"
@@ -1587,21 +1785,21 @@ browserify-unibabel@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/browserify-unibabel/-/browserify-unibabel-3.0.0.tgz#5a6b8f0f704ce388d3927df47337e25830f71dda"
-browserify-zlib@~0.1.2:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
+browserify-zlib@^0.2.0, browserify-zlib@~0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
dependencies:
- pako "~0.2.0"
+ pako "~1.0.5"
browserify@^14.0.0, browserify@^14.4.0:
- version "14.4.0"
- resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.4.0.tgz#089a3463af58d0e48d8cd4070b3f74654d5abca9"
+ version "14.5.0"
+ resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5"
dependencies:
JSONStream "^1.0.3"
assert "^1.4.0"
browser-pack "^6.0.1"
browser-resolve "^1.11.0"
- browserify-zlib "~0.1.2"
+ browserify-zlib "~0.2.0"
buffer "^5.0.2"
cached-path-relative "^1.0.0"
concat-stream "~1.5.1"
@@ -1621,7 +1819,7 @@ browserify@^14.0.0, browserify@^14.4.0:
insert-module-globals "^7.0.0"
labeled-stream-splicer "^2.0.0"
module-deps "^4.0.8"
- os-browserify "~0.1.1"
+ os-browserify "~0.3.0"
parents "^1.0.1"
path-browserify "~0.0.0"
process "~0.11.0"
@@ -1645,12 +1843,19 @@ browserify@^14.0.0, browserify@^14.4.0:
vm-browserify "~0.0.1"
xtend "^4.0.0"
-browserslist@^2.1.2:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8"
+browserslist@^1.1.1, browserslist@^1.1.3, browserslist@^1.7.6:
+ version "1.7.7"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
dependencies:
- caniuse-lite "^1.0.30000718"
- electron-to-chromium "^1.3.18"
+ caniuse-db "^1.0.30000639"
+ electron-to-chromium "^1.2.7"
+
+browserslist@^2.1.2, browserslist@^2.10.0:
+ version "2.10.0"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346"
+ dependencies:
+ caniuse-lite "^1.0.30000780"
+ electron-to-chromium "^1.3.28"
bs58@^2.0.1:
version "2.0.1"
@@ -1677,13 +1882,25 @@ buffer-equal@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b"
+buffer-equal@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
+
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
+buffer@^4.3.0:
+ version "4.9.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+ isarray "^1.0.0"
+
buffer@^5.0.2:
- version "5.0.7"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.7.tgz#570a290b625cf2603290c1149223d27ccf04db97"
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.8.tgz#84daa52e7cf2fa8ce4195bc5cf0f7809e0930b24"
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
@@ -1712,6 +1929,20 @@ bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+cache-base@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
+ dependencies:
+ collection-visit "^1.0.0"
+ component-emitter "^1.2.1"
+ get-value "^2.0.6"
+ has-value "^1.0.0"
+ isobject "^3.0.1"
+ set-value "^2.0.0"
+ to-object-path "^0.3.0"
+ union-value "^1.0.0"
+ unset-value "^1.0.0"
+
cached-path-relative@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7"
@@ -1738,11 +1969,26 @@ callsites@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
+camelcase-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
+ dependencies:
+ camelcase "^2.0.0"
+ map-obj "^1.0.0"
+
+camelcase-keys@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77"
+ dependencies:
+ camelcase "^4.1.0"
+ map-obj "^2.0.0"
+ quick-lru "^1.0.0"
+
camelcase@^1.0.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
-camelcase@^2.0.1:
+camelcase@^2.0.0, camelcase@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
@@ -1754,14 +2000,26 @@ camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
-caniuse-lite@^1.0.30000718:
- version "1.0.30000733"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000733.tgz#ebfc48254117cc0c66197a4536cb4397a6cfbccd"
+caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
+ version "1.0.30000784"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000784.tgz#1be95012d9489c7719074f81aee57dbdffe6361b"
+
+caniuse-lite@^1.0.30000780, caniuse-lite@^1.0.30000783:
+ version "1.0.30000784"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0"
+
+caseless@~0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+ccount@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.2.tgz#53b6a2f815bb77b9c2871f7b9a72c3a25f1d8e89"
+
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
@@ -1769,7 +2027,7 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
-"chai@>=1.9.2 <4.0.0":
+"chai@>=1.9.2 <4.0.0", chai@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247"
dependencies:
@@ -1812,9 +2070,9 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.0, chalk@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
@@ -1824,6 +2082,26 @@ change-emitter@^0.1.2:
version "0.1.6"
resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515"
+character-entities-html4@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.1.tgz#359a2a4a0f7e29d3dc2ac99bdbe21ee39438ea50"
+
+character-entities-legacy@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz#f40779df1a101872bb510a3d295e1fccf147202f"
+
+character-entities@^1.0.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.1.tgz#f76871be5ef66ddb7f8f8e3478ecc374c27d6dca"
+
+character-reference-invalid@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz#942835f750e4ec61a308e60c2ef8cc1011202efc"
+
+chardet@^0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
+
charm@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/charm/-/charm-1.0.2.tgz#8add367153a6d9a581331052c4090991da995e35"
@@ -1840,28 +2118,33 @@ checkpoint-store@^1.1.0:
dependencies:
functional-red-black-tree "^1.0.1"
-cheerio@^0.22.0:
- version "0.22.0"
- resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
+cheerio@^1.0.0-rc.2:
+ version "1.0.0-rc.2"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
dependencies:
css-select "~1.2.0"
dom-serializer "~0.1.0"
entities "~1.1.1"
htmlparser2 "^3.9.1"
- lodash.assignin "^4.0.9"
- lodash.bind "^4.1.4"
- lodash.defaults "^4.0.1"
- lodash.filter "^4.4.0"
- lodash.flatten "^4.2.0"
- lodash.foreach "^4.3.0"
- lodash.map "^4.4.0"
- lodash.merge "^4.4.0"
- lodash.pick "^4.2.1"
- lodash.reduce "^4.4.0"
- lodash.reject "^4.4.0"
- lodash.some "^4.4.0"
-
-chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.1:
+ lodash "^4.15.0"
+ parse5 "^3.0.1"
+
+chokidar@1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
+ dependencies:
+ anymatch "^1.3.0"
+ async-each "^1.0.0"
+ glob-parent "^2.0.0"
+ inherits "^2.0.1"
+ is-binary-path "^1.0.0"
+ is-glob "^2.0.0"
+ path-is-absolute "^1.0.0"
+ readdirp "^2.0.0"
+ optionalDependencies:
+ fsevents "^1.0.0"
+
+chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.1, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
@@ -1876,10 +2159,6 @@ chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.1:
optionalDependencies:
fsevents "^1.0.0"
-chownr@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
-
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -1891,6 +2170,16 @@ circular-json@^0.3.1:
version "0.3.3"
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
+class-utils@^0.3.5:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.5.tgz#17e793103750f9627b2176ea34cfd1b565903c80"
+ dependencies:
+ arr-union "^3.1.0"
+ define-property "^0.2.5"
+ isobject "^3.0.0"
+ lazy-cache "^2.0.2"
+ static-extend "^0.1.1"
+
classnames@^2.2.4, classnames@^2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
@@ -1901,12 +2190,6 @@ cli-cursor@^2.1.0:
dependencies:
restore-cursor "^2.0.0"
-cli-table@^0.3.0:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
- dependencies:
- colors "1.0.3"
-
cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
@@ -1931,22 +2214,41 @@ cliui@^3.0.3, cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+clone-buffer@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
+
+clone-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c"
+ dependencies:
+ is-regexp "^1.0.0"
+ is-supported-regexp-flag "^1.0.0"
+
clone-stats@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
-clone@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f"
+clone-stats@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
clone@^1.0.0, clone@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
clone@^2.0.0, clone@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
+cloneable-readable@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117"
+ dependencies:
+ inherits "^2.0.1"
+ process-nextick-args "^1.0.6"
+ through2 "^2.0.1"
+
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -1962,6 +2264,10 @@ coinstring@^2.0.0:
bs58 "^2.0.1"
create-hash "^1.1.1"
+collapse-white-space@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.3.tgz#4b906f670e5a963a87b76b0e1689643341b6023c"
+
collection-map@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c"
@@ -1970,12 +2276,23 @@ collection-map@^1.0.0:
for-own "^1.0.0"
make-iterator "^1.0.0"
+collection-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
+ dependencies:
+ map-visit "^1.0.0"
+ object-visit "^1.0.0"
+
color-convert@^1.3.0, color-convert@^1.9.0:
- version "1.9.0"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
dependencies:
color-name "^1.1.1"
+color-diff@^0.1.3:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/color-diff/-/color-diff-0.1.7.tgz#6db78cd9482a8e459d40821eaf4b503283dcb8e2"
+
color-name@^1.0.0, color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
@@ -1986,6 +2303,10 @@ color-string@^0.3.0:
dependencies:
color-name "^1.0.0"
+color-support@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
+
color@^0.11.1:
version "0.11.4"
resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764"
@@ -1994,7 +2315,26 @@ color@^0.11.1:
color-convert "^1.3.0"
color-string "^0.3.0"
-colors@1.0.3, colors@1.0.x:
+colorguard@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/colorguard/-/colorguard-1.2.1.tgz#249647c9702481d9143384fc9813662311afde98"
+ dependencies:
+ chalk "^1.1.1"
+ color-diff "^0.1.3"
+ log-symbols "^1.0.2"
+ object-assign "^4.0.1"
+ pipetteur "^2.0.0"
+ plur "^2.0.0"
+ postcss "^5.0.4"
+ postcss-reporter "^1.2.1"
+ text-table "^0.2.0"
+ yargs "^1.2.6"
+
+colors@0.5.x:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
+
+colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
@@ -2008,6 +2348,15 @@ combine-lists@^1.0.0:
dependencies:
lodash "^4.5.0"
+combine-source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.6.1.tgz#9b4a09c316033d768e0f11e029fa2730e079ad96"
+ dependencies:
+ convert-source-map "~1.1.0"
+ inline-source-map "~0.5.0"
+ lodash.memoize "~3.0.3"
+ source-map "~0.4.2"
+
combine-source-map@~0.7.1:
version "0.7.2"
resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e"
@@ -2023,10 +2372,24 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
-commander@2.11.0, commander@^2.6.0, commander@~2.11.0:
+commander@2.11.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
+commander@2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
+ dependencies:
+ graceful-readlink ">= 1.0.0"
+
+commander@^2.5.0, commander@^2.6.0, commander@^2.9.0, commander@~2.12.1:
+ version "2.12.2"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
+
+commander@~2.13.0:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
+
commondir@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-0.0.1.tgz#89f00fdcd51b519c578733fec563e6a6da7f5be2"
@@ -2035,23 +2398,19 @@ commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
-commonmark-react-renderer@^4.2.4:
- version "4.3.3"
- resolved "https://registry.yarnpkg.com/commonmark-react-renderer/-/commonmark-react-renderer-4.3.3.tgz#9c4bca138bc83287bae792ccf133738be9cbc6fa"
- dependencies:
- in-publish "^2.0.0"
- lodash.assign "^4.2.0"
- lodash.isplainobject "^4.0.6"
- pascalcase "^0.1.1"
- xss-filters "^1.2.6"
-
-commonmark@^0.24.0:
- version "0.24.0"
- resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.24.0.tgz#b80de0182c546355643aa15db12bfb282368278f"
+commoner@^0.10.0:
+ version "0.10.8"
+ resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5"
dependencies:
- entities "~ 1.1.1"
- mdurl "~ 1.0.1"
- string.prototype.repeat "^0.2.0"
+ commander "^2.5.0"
+ detective "^4.3.1"
+ glob "^5.0.15"
+ graceful-fs "^4.1.2"
+ iconv-lite "^0.4.5"
+ mkdirp "^0.5.0"
+ private "^0.1.6"
+ q "^1.1.2"
+ recast "^0.11.17"
component-bind@1.0.0:
version "1.0.0"
@@ -2061,7 +2420,7 @@ component-emitter@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3"
-component-emitter@1.2.1:
+component-emitter@1.2.1, component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
@@ -2069,11 +2428,29 @@ component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
+compressible@~2.0.11:
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
+ dependencies:
+ mime-db ">= 1.30.0 < 2"
+
+compression@^1.7.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db"
+ dependencies:
+ accepts "~1.3.4"
+ bytes "3.0.0"
+ compressible "~2.0.11"
+ debug "2.6.9"
+ on-headers "~1.0.1"
+ safe-buffer "5.1.1"
+ vary "~1.1.2"
+
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@~1.6.0:
+concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@~1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
dependencies:
@@ -2081,12 +2458,6 @@ concat-stream@^1.4.3, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@
readable-stream "^2.2.2"
typedarray "^0.0.6"
-concat-stream@~1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.2.1.tgz#f35100b6c46378bfba8b6b80f9f0d0ccdf13dc60"
- dependencies:
- bops "0.0.6"
-
concat-stream@~1.5.0, concat-stream@~1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
@@ -2103,13 +2474,13 @@ config-chain@~1.1.5:
proto-list "~1.2.1"
connect@^3.6.0:
- version "3.6.3"
- resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.3.tgz#f7320d46a25b4be7b483a2236517f24b1e27e301"
+ version "3.6.5"
+ resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.5.tgz#fb8dde7ba0763877d0ec9df9dac0b4b40e72c7da"
dependencies:
- debug "2.6.8"
- finalhandler "1.0.4"
- parseurl "~1.3.1"
- utils-merge "1.0.0"
+ debug "2.6.9"
+ finalhandler "1.0.6"
+ parseurl "~1.3.2"
+ utils-merge "1.0.1"
console-browserify@^1.1.0:
version "1.1.0"
@@ -2127,7 +2498,7 @@ consolidate@^0.14.0:
dependencies:
bluebird "^3.1.1"
-constants-browserify@~1.0.0:
+constants-browserify@^1.0.0, constants-browserify@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@@ -2136,16 +2507,16 @@ content-disposition@0.5.2:
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
content-type-parser@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.1.tgz#c3e56988c53c65127fb46d4032a3a900246fdc94"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
-content-type@~1.0.1, content-type@~1.0.2, content-type@~1.0.4:
+content-type@~1.0.1, content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-convert-source-map@1.X, convert-source-map@^1.1.1, convert-source-map@^1.3.0, convert-source-map@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
+convert-source-map@1.X, convert-source-map@^1.3.0, convert-source-map@^1.5.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
convert-source-map@~1.1.0:
version "1.1.3"
@@ -2159,11 +2530,15 @@ cookie@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
-copy-props@^1.4.1:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-1.6.0.tgz#f0324bbee99771101e7b3ada112f313c393db8ed"
+copy-descriptor@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
+
+copy-props@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.1.tgz#665fc32046ca84a898abaa3c5945e7f248ccba00"
dependencies:
- each-props "^1.2.1"
+ each-props "^1.3.0"
is-plain-object "^2.0.1"
copy-to-clipboard@^3.0.8:
@@ -2177,13 +2552,34 @@ core-js@^1.0.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
+ version "2.5.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+cosmiconfig@^2.1.1:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892"
+ dependencies:
+ is-directory "^0.3.1"
+ js-yaml "^3.4.3"
+ minimist "^1.2.0"
+ object-assign "^4.1.0"
+ os-homedir "^1.0.1"
+ parse-json "^2.2.0"
+ require-from-string "^1.1.0"
+
+cosmiconfig@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
+ dependencies:
+ is-directory "^0.3.1"
+ js-yaml "^3.9.0"
+ parse-json "^3.0.0"
+ require-from-string "^2.0.1"
+
coveralls@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.0.tgz#22ef730330538080d29b8c151dc9146afde88a99"
@@ -2221,14 +2617,21 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-create-react-class@^15.5.2, create-react-class@^15.6.0:
- version "15.6.0"
- resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
+create-react-class@^15.6.0:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
object-assign "^4.1.1"
+cross-spawn@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
+ dependencies:
+ lru-cache "^4.0.1"
+ which "^1.2.9"
+
cross-spawn@^4:
version "4.0.2"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
@@ -2250,9 +2653,15 @@ cryptiles@2.x.x:
dependencies:
boom "2.x.x"
-crypto-browserify@^3.0.0:
- version "3.11.1"
- resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f"
+cryptiles@3.x.x:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
+ dependencies:
+ boom "5.x.x"
+
+crypto-browserify@^3.0.0, crypto-browserify@^3.11.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
dependencies:
browserify-cipher "^1.0.0"
browserify-sign "^4.0.0"
@@ -2264,11 +2673,35 @@ crypto-browserify@^3.0.0:
pbkdf2 "^3.0.3"
public-encrypt "^4.0.0"
randombytes "^2.0.0"
+ randomfill "^1.0.3"
crypto-js@^3.1.4:
version "3.1.8"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.8.tgz#715f070bf6014f2ae992a98b3929258b713f08d5"
+css-color-list@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/css-color-list/-/css-color-list-0.0.1.tgz#8718e8695ae7a2cc8787be8715f1c008a7f28b15"
+ dependencies:
+ css-color-names "0.0.1"
+
+css-color-names@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.1.tgz#5d0548fa256456ede4a9a0c2ac7ab19d3eb1ad81"
+
+css-color-names@0.0.3:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.3.tgz#de0cef16f4d8aa8222a320d5b6d7e9bbada7b9f6"
+
+css-rule-stream@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/css-rule-stream/-/css-rule-stream-1.1.0.tgz#3786e7198983d965a26e31957e09078cbb7705a2"
+ dependencies:
+ css-tokenize "^1.0.1"
+ duplexer2 "0.0.2"
+ ldjson-stream "^1.2.1"
+ through2 "^0.6.3"
+
css-select@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
@@ -2278,6 +2711,13 @@ css-select@~1.2.0:
domutils "1.5.1"
nth-check "~1.0.1"
+css-tokenize@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/css-tokenize/-/css-tokenize-1.0.1.tgz#4625cb1eda21c143858b7f81d6803c1d26fc14be"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^1.0.33"
+
css-what@2.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
@@ -2307,6 +2747,12 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
dependencies:
cssom "0.3.x"
+currently-unhandled@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
+ dependencies:
+ array-find-index "^1.0.1"
+
custom-event@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425"
@@ -2340,20 +2786,20 @@ date-now@^0.1.4:
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
dateformat@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17"
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
debounce@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.0.2.tgz#503cc674d8d7f737099664fb75ddbd36b9626dc6"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.1.0.tgz#6a1a4ee2a9dc4b7c24bb012558dbcdb05b37f408"
-debug-fabulous@>=0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.1.1.tgz#1b970878c9fa4fbd1c88306eab323c830c58f1d6"
+debug-fabulous@1.X:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.0.0.tgz#57f6648646097b1b0849dcda0017362c1ec00f8b"
dependencies:
- debug "2.3.0"
- memoizee "^0.4.5"
- object-assign "4.1.0"
+ debug "3.X"
+ memoizee "0.4.X"
+ object-assign "4.X"
debug-log@^1.0.1:
version "1.0.1"
@@ -2365,46 +2811,39 @@ debug@2.2.0, debug@~2.2.0:
dependencies:
ms "0.7.1"
-debug@2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.0.tgz#3912dc55d7167fc3af17d2b85c13f93deaedaa43"
- dependencies:
- ms "0.7.2"
-
debug@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c"
dependencies:
ms "0.7.2"
-debug@2.6.8, debug@^2.1.0, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8:
- version "2.6.8"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
- dependencies:
- ms "2.0.0"
-
-debug@2.6.9:
+debug@2.6.9, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
-debug@3.1.0:
+debug@3.1.0, debug@3.X, debug@^3.0.0, debug@^3.0.1, debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
ms "2.0.0"
-debug@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64"
+decamelize-keys@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
dependencies:
- ms "2.0.0"
+ decamelize "^1.1.0"
+ map-obj "^1.0.0"
-decamelize@^1.0.0, decamelize@^1.1.1:
+decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+decode-uri-component@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+
deep-diff@^0.3.5:
version "0.3.8"
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
@@ -2449,6 +2888,12 @@ deepmerge@~0.2.7:
version "0.2.10"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-0.2.10.tgz#8906bf9e525a4fbf1b203b2afcb4640249821219"
+default-compare@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f"
+ dependencies:
+ kind-of "^5.0.2"
+
default-require-extensions@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
@@ -2472,6 +2917,18 @@ define-properties@^1.1.2:
foreach "^2.0.5"
object-keys "^1.0.8"
+define-property@^0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
+ dependencies:
+ is-descriptor "^0.1.0"
+
+define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
+ dependencies:
+ is-descriptor "^1.0.0"
+
defined@^1.0.0, defined@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
@@ -2547,6 +3004,10 @@ detect-file@^0.1.0:
dependencies:
fs-exists-sync "^0.1.0"
+detect-file@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
+
detect-indent@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-2.0.0.tgz#720ff51e4d97b76884f6bf57292348b13dfde939"
@@ -2561,6 +3022,10 @@ detect-indent@^4.0.0:
dependencies:
repeating "^2.0.0"
+detect-libc@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
+
detect-newline@2.X:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
@@ -2569,21 +3034,25 @@ detect-node@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127"
-detective@^4.0.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1"
+detective@^4.0.0, detective@^4.3.1:
+ version "4.7.1"
+ resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e"
dependencies:
- acorn "^4.0.3"
+ acorn "^5.2.1"
defined "^1.0.0"
di@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
-diff@3.3.1, diff@^3.1.0:
+diff@3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75"
+diff@^3.1.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+
diffie-hellman@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
@@ -2592,12 +3061,19 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
+dir-glob@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
+ dependencies:
+ arrify "^1.0.1"
+ path-type "^3.0.0"
+
disc@^1.3.2:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/disc/-/disc-1.3.2.tgz#32a6f02e486edf77860a5363d22718425d296e40"
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/disc/-/disc-1.3.3.tgz#61d455180c2a115468bb85015a33e71a82fc02c2"
dependencies:
- bl "^0.7.0"
- browser-unpack "^0.2.3"
+ bl "^1.2.0"
+ browser-unpack "^1.2.0"
builtins "0.0.3"
commondir "0.0.1"
d3 "^3.4.3"
@@ -2611,6 +3087,10 @@ disc@^1.3.2:
through "^2.3.4"
uniq "^1.0.0"
+discontinuous-range@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+
dnode-protocol@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dnode-protocol/-/dnode-protocol-0.2.2.tgz#51151d16fc3b5f84815ee0b9497a1061d0d1949d"
@@ -2627,16 +3107,32 @@ dnode@^1.2.2:
optionalDependencies:
weak "^1.0.0"
-doctrine@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
+doctrine@^2.0.0, doctrine@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
dependencies:
esutils "^2.0.2"
- isarray "^1.0.0"
+
+doiuse@^2.4.1:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/doiuse/-/doiuse-2.6.0.tgz#1892d10b61a9a356addbf2b614933e81f8bb3834"
+ dependencies:
+ browserslist "^1.1.1"
+ caniuse-db "^1.0.30000187"
+ css-rule-stream "^1.1.0"
+ duplexer2 "0.0.2"
+ jsonfilter "^1.1.2"
+ ldjson-stream "^1.2.1"
+ lodash "^4.0.0"
+ multimatch "^2.0.0"
+ postcss "^5.0.8"
+ source-map "^0.4.2"
+ through2 "^0.6.3"
+ yargs "^3.5.4"
dom-helpers@^3.2.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
dom-serialize@^2.2.0:
version "2.2.1"
@@ -2658,7 +3154,7 @@ dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
-domain-browser@~1.1.0:
+domain-browser@^1.1.1, domain-browser@~1.1.0:
version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
@@ -2670,12 +3166,20 @@ domelementtype@~1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+domexception@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.0.tgz#81fe5df81b3f057052cde3a9fa9bf536a85b9ab0"
+
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
dependencies:
domelementtype "1"
+domkit@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/domkit/-/domkit-0.0.1.tgz#88399d586794efc1154fec6c22cfe50f19bd4dbb"
+
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
@@ -2690,6 +3194,12 @@ domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
+dot-prop@^4.1.1:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
+ dependencies:
+ is-obj "^1.0.0"
+
drbg.js@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b"
@@ -2714,7 +3224,7 @@ duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
-duplexify@^3.1.2, duplexify@^3.2.0, duplexify@^3.4.2, duplexify@^3.5.0:
+duplexify@^3.1.2, duplexify@^3.4.2, duplexify@^3.5.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd"
dependencies:
@@ -2723,7 +3233,7 @@ duplexify@^3.1.2, duplexify@^3.2.0, duplexify@^3.4.2, duplexify@^3.5.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
-each-props@^1.2.1:
+each-props@^1.3.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.1.tgz#fc138f51e3a2774286d4858e02d6e7de462de158"
dependencies:
@@ -2736,13 +3246,29 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
+editorconfig@^0.13.2:
+ version "0.13.3"
+ resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.13.3.tgz#e5219e587951d60958fd94ea9a9a008cdeff1b34"
+ dependencies:
+ bluebird "^3.0.5"
+ commander "^2.9.0"
+ lru-cache "^3.2.0"
+ semver "^5.1.0"
+ sigmund "^1.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-electron-to-chromium@^1.3.18:
- version "1.3.21"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.21.tgz#a967ebdcfe8ed0083fc244d1894022a8e8113ea2"
+electron-releases@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e"
+
+electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.28:
+ version "1.3.30"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80"
+ dependencies:
+ electron-releases "^2.1.0"
elliptic@^6.0.0, elliptic@^6.2.3:
version "6.4.0"
@@ -2756,6 +3282,10 @@ elliptic@^6.0.0, elliptic@^6.2.3:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
+emojis-list@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
+
encodeurl@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20"
@@ -2850,17 +3380,30 @@ engine.io@1.8.3:
engine.io-parser "1.3.2"
ws "1.1.2"
+enhanced-resolve@^3.3.0:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
+ dependencies:
+ graceful-fs "^4.1.2"
+ memory-fs "^0.4.0"
+ object-assign "^4.0.1"
+ tapable "^0.2.7"
+
ensnare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ensnare/-/ensnare-1.0.0.tgz#72d2bf7ef48aba21f66adf29d00a0904eddb61c7"
dependencies:
tape "^4.6.0"
+ensure-posix-path@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz#a65b3e42d0b71cfc585eb774f9943c8d9b91b0c2"
+
ent@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
-entities@^1.1.1, "entities@~ 1.1.1", entities@~1.1.1:
+entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -2871,36 +3414,60 @@ envify@^4.0.0:
esprima "^4.0.0"
through "~2.3.4"
-enzyme@^2.8.2:
- version "2.9.1"
- resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-2.9.1.tgz#07d5ce691241240fb817bf2c4b18d6e530240df6"
+enzyme-adapter-react-15@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-15/-/enzyme-adapter-react-15-1.0.5.tgz#99f9a03ff2c2303e517342935798a6bdfbb75fac"
dependencies:
- cheerio "^0.22.0"
- function.prototype.name "^1.0.0"
+ enzyme-adapter-utils "^1.1.0"
+ lodash "^4.17.4"
+ object.assign "^4.0.4"
+ object.values "^1.0.4"
+ prop-types "^15.5.10"
+
+enzyme-adapter-utils@^1.1.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
+ dependencies:
+ lodash "^4.17.4"
+ object.assign "^4.0.4"
+ prop-types "^15.6.0"
+
+enzyme@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.3.0.tgz#0971abd167f2d4bf3f5bd508229e1c4b6dc50479"
+ dependencies:
+ cheerio "^1.0.0-rc.2"
+ function.prototype.name "^1.0.3"
+ has "^1.0.1"
+ is-boolean-object "^1.0.0"
+ is-callable "^1.1.3"
+ is-number-object "^1.0.3"
+ is-string "^1.0.4"
is-subset "^0.1.1"
lodash "^4.17.4"
+ object-inspect "^1.5.0"
object-is "^1.0.1"
- object.assign "^4.0.4"
+ object.assign "^4.1.0"
object.entries "^1.0.4"
object.values "^1.0.4"
- prop-types "^15.5.10"
- uuid "^3.0.1"
+ raf "^3.4.0"
+ rst-selector-parser "^2.2.3"
-errno@~0.1.1:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
+errno@^0.1.3, errno@~0.1.1:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026"
dependencies:
- prr "~0.0.0"
+ prr "~1.0.1"
-error-ex@^1.2.0:
+error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0:
- version "1.8.2"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.8.2.tgz#25103263dc4decbda60e0c737ca32313518027ee"
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
dependencies:
es-to-primitive "^1.1.1"
function-bind "^1.1.1"
@@ -2916,20 +3483,20 @@ es-to-primitive@^1.1.1:
is-date-object "^1.0.1"
is-symbol "^1.0.1"
-es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
- version "0.10.30"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.30.tgz#7141a16836697dbabfaaaeee41495ce29f52c939"
+es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2:
+ version "0.10.37"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3"
dependencies:
- es6-iterator "2"
- es6-symbol "~3.1"
+ es6-iterator "~2.0.1"
+ es6-symbol "~3.1.1"
-es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
+es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
dependencies:
d "1"
- es5-ext "^0.10.14"
- es6-symbol "^3.1"
+ es5-ext "^0.10.35"
+ es6-symbol "^3.1.1"
es6-map@^0.1.3:
version "0.1.5"
@@ -2952,7 +3519,7 @@ es6-set@~0.1.5:
es6-symbol "3.1.1"
event-emitter "~0.3.5"
-es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1:
+es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies:
@@ -2976,18 +3543,7 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-escodegen@1.8.x:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"
- dependencies:
- esprima "^2.7.1"
- estraverse "^1.9.1"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.2.0"
-
-escodegen@^1.6.1:
+escodegen@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852"
dependencies:
@@ -3037,47 +3593,51 @@ eslint-plugin-mocha@^4.9.0:
ramda "^0.24.1"
eslint-plugin-react@^7.4.0:
- version "7.4.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz#300a95861b9729c087d362dd64abcc351a74364a"
+ version "7.5.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b"
dependencies:
doctrine "^2.0.0"
has "^1.0.1"
jsx-ast-utils "^2.0.0"
- prop-types "^15.5.10"
+ prop-types "^15.6.0"
-eslint-scope@^3.7.1:
+eslint-scope@^3.7.1, eslint-scope@~3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
+eslint-visitor-keys@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
+
eslint@^4.0.0, eslint@^4.2.0:
- version "4.7.1"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.7.1.tgz#849804136953ebe366782f9f8611e2cbd1b54681"
+ version "4.14.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82"
dependencies:
- ajv "^5.2.0"
+ ajv "^5.3.0"
babel-code-frame "^6.22.0"
chalk "^2.1.0"
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
- debug "^3.0.1"
- doctrine "^2.0.0"
+ debug "^3.1.0"
+ doctrine "^2.0.2"
eslint-scope "^3.7.1"
- espree "^3.5.1"
+ eslint-visitor-keys "^1.0.0"
+ espree "^3.5.2"
esquery "^1.0.0"
- estraverse "^4.2.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
functional-red-black-tree "^1.0.1"
glob "^7.1.2"
- globals "^9.17.0"
+ globals "^11.0.1"
ignore "^3.3.3"
imurmurhash "^0.1.4"
inquirer "^3.0.6"
is-resolvable "^1.0.0"
js-yaml "^3.9.1"
- json-stable-stringify "^1.0.1"
+ json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
lodash "^4.17.4"
minimatch "^3.0.2"
@@ -3094,22 +3654,18 @@ eslint@^4.0.0, eslint@^4.2.0:
table "^4.0.1"
text-table "~0.2.0"
-espree@^3.5.1:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.1.tgz#0c988b8ab46db53100a1954ae4ba995ddd27d87e"
+espree@^3.5.2:
+ version "3.5.2"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca"
dependencies:
- acorn "^5.1.1"
+ acorn "^5.2.1"
acorn-jsx "^3.0.0"
-esprima-fb@3001.1.0-dev-harmony-fb:
- version "3001.1.0-dev-harmony-fb"
- resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz#b77d37abcd38ea0b77426bb8bc2922ce6b426411"
+esprima-fb@13001.1001.0-dev-harmony-fb:
+ version "13001.1001.0-dev-harmony-fb"
+ resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-13001.1001.0-dev-harmony-fb.tgz#633acdb40d9bd4db8a1c1d68c06a942959fad2b0"
-esprima@2.7.x, esprima@^2.7.1:
- version "2.7.3"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
-
-esprima@^3.1.3:
+esprima@^3.1.3, esprima@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
@@ -3138,10 +3694,6 @@ esrecurse@^4.1.0:
estraverse "^4.1.0"
object-assign "^4.0.1"
-estraverse@^1.9.1:
- version "1.9.3"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
-
estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
@@ -3162,7 +3714,7 @@ esutils@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570"
-etag@~1.8.0, etag@~1.8.1:
+etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@@ -3184,31 +3736,33 @@ eth-block-tracker@^1.0.7:
pify "^2.3.0"
tape "^4.6.3"
-eth-block-tracker@^2.1.2:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.1.3.tgz#ef24ab415f18445bd5c0ef49b9ac248f847e34f9"
+eth-block-tracker@^2.1.2, eth-block-tracker@^2.2.2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.2.2.tgz#b3d72cd82ba5ee37471d22bac4f56387ee4137cf"
dependencies:
- async-eventemitter "^0.2.2"
+ async-eventemitter ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c
babelify "^7.3.0"
eth-query "^2.1.0"
ethjs-util "^0.1.3"
pify "^2.3.0"
tape "^4.6.3"
-eth-block-tracker@^2.2.0, eth-block-tracker@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.2.2.tgz#b3d72cd82ba5ee37471d22bac4f56387ee4137cf"
+eth-block-tracker@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.3.0.tgz#4cb782c8ef8fde2f5dc894921ae1f5c1077c35a4"
dependencies:
async-eventemitter ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c
- babelify "^7.3.0"
eth-query "^2.1.0"
+ ethereumjs-tx "^1.3.3"
+ ethereumjs-util "^5.1.3"
ethjs-util "^0.1.3"
+ json-rpc-engine "^3.6.0"
pify "^2.3.0"
tape "^4.6.3"
-eth-contract-metadata@^1.1.4:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.1.5.tgz#301f51b0460b8dd044997dc05870751fb7f4cfcb"
+eth-contract-metadata@^1.1.5:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.3.0.tgz#caf3cdc3d69995b6d7532c9d96fedbad46361ca8"
eth-ens-namehash@^1.0.2:
version "1.0.2"
@@ -3217,43 +3771,55 @@ eth-ens-namehash@^1.0.2:
idna-uts46 "^1.0.1"
js-sha3 "^0.5.7"
-eth-hd-keyring@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.0.tgz#40bcc7ea877ef5c746f54c0c87a6b39ceb5edde3"
+eth-hd-keyring@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.1.tgz#15ab3919b4153a8497e14673e8e8039e5965131c"
dependencies:
bip39 "^2.2.0"
- eth-sig-util "^1.1.0"
+ eth-sig-util "^1.3.0"
ethereumjs-util "^5.1.1"
ethereumjs-wallet "^0.6.0"
events "^1.1.1"
-eth-hd-keyring@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.1.tgz#15ab3919b4153a8497e14673e8e8039e5965131c"
+eth-hd-keyring@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/eth-hd-keyring/-/eth-hd-keyring-1.2.2.tgz#ad5f479074436a93b439b0b95c79095c28791882"
dependencies:
bip39 "^2.2.0"
- eth-sig-util "^1.3.0"
+ eth-sig-util "^1.4.2"
ethereumjs-util "^5.1.1"
ethereumjs-wallet "^0.6.0"
events "^1.1.1"
+ xtend "^4.0.1"
-eth-json-rpc-filters@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.4.tgz#716109b1cf4d0ec01f30f848d65c60c34400e975"
+eth-json-rpc-filters@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-1.2.5.tgz#2d119830d91c300396e0b00a00e884de69a5cd8b"
dependencies:
await-semaphore "^0.1.1"
eth-json-rpc-middleware "^1.0.0"
json-rpc-engine "^3.4.0"
lodash.flatmap "^4.5.0"
-eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.2.7.tgz#7c36e0972945255bdb486f18df53d4314a1c048a"
+eth-json-rpc-infura@^2.0.11:
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-2.0.11.tgz#134bf54ff15e96a9116424c0db9b66aa079bfbbe"
+ dependencies:
+ eth-json-rpc-middleware "^1.5.0"
+ json-rpc-engine "^3.4.0"
+ json-rpc-error "^2.0.0"
+ tape "^4.8.0"
+
+eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7, eth-json-rpc-middleware@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz#16b1053386aa3803b125732aa6de07eadf068729"
dependencies:
async "^2.5.0"
eth-query "^2.1.2"
+ eth-tx-summary "^3.1.2"
ethereumjs-block "^1.6.0"
ethereumjs-tx "^1.3.3"
+ ethereumjs-util "^5.1.2"
ethereumjs-vm "^2.1.0"
fetch-ponyfill "^4.0.0"
json-rpc-error "^2.0.0"
@@ -3261,71 +3827,57 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7:
promise-to-callback "^1.0.0"
tape "^4.6.3"
-eth-keyring-controller@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.2.tgz#1af179d8fd7ff470eb91e113a0fd3a440bd66bcc"
+eth-keyring-controller@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.4.tgz#0518d9d89af0d8af362a2821e4d550a8be14a807"
dependencies:
bip39 "^2.4.0"
bluebird "^3.5.0"
browser-passworder "^2.0.3"
- eth-hd-keyring "^1.2.0"
- eth-sig-util "^1.2.2"
- eth-simple-keyring "^1.1.1"
+ eth-hd-keyring "^1.2.2"
+ eth-sig-util "^1.4.0"
+ eth-simple-keyring "^1.2.1"
ethereumjs-util "^5.1.2"
loglevel "^1.5.0"
obs-store "^2.4.1"
promise-filter "^1.1.0"
eth-phishing-detect@^1.1.4:
- version "1.1.11"
- resolved "https://registry.yarnpkg.com/eth-phishing-detect/-/eth-phishing-detect-1.1.11.tgz#e29c38b84abed3d41df4131c56d6a41308c3e56d"
+ version "1.1.12"
+ resolved "https://registry.yarnpkg.com/eth-phishing-detect/-/eth-phishing-detect-1.1.12.tgz#3db7e88c754510c94e6736db85108b90e227fe41"
dependencies:
fast-levenshtein "^2.0.6"
-eth-query@^2.1.0, eth-query@^2.1.2:
+eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e"
dependencies:
json-rpc-random-id "^1.0.0"
xtend "^4.0.1"
-eth-sig-util@^1.1.0, eth-sig-util@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.2.2.tgz#7e982f5f8d94e79027d8c69e6006cdbd2f57942f"
- dependencies:
- ethereumjs-util "^5.1.1"
-
-eth-sig-util@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.3.0.tgz#14c1c02367a4264dbfeae611b4dc7f8d9d6ee4ba"
+eth-sig-util@^1.3.0, eth-sig-util@^1.4.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.1.tgz#dfcde3cbd03c38d429ad8695938a2678ec56f1ae"
dependencies:
ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
ethereumjs-util "^5.1.1"
-eth-sig-util@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.0.tgz#ad42fd1d9c60fff19bdef7377b42fb38e92ee7e1"
+eth-sig-util@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210"
dependencies:
ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
ethereumjs-util "^5.1.1"
-eth-simple-keyring@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/eth-simple-keyring/-/eth-simple-keyring-1.1.1.tgz#6dd75d7cc6edea7c788cf19ef9431c830cd961ae"
- dependencies:
- eth-sig-util "^1.1.0"
- ethereumjs-util "^5.1.1"
- ethereumjs-wallet "^0.6.0"
- events "^1.1.1"
-
-eth-simple-keyring@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/eth-simple-keyring/-/eth-simple-keyring-1.2.0.tgz#b151d2c75877e2cddf94ae5feae78214cf198846"
+eth-simple-keyring@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/eth-simple-keyring/-/eth-simple-keyring-1.2.1.tgz#6d7b352dc5a9a5020d61f69faf21efb2f6363f45"
dependencies:
- eth-sig-util "^1.3.0"
+ eth-sig-util "^1.4.2"
ethereumjs-util "^5.1.1"
ethereumjs-wallet "^0.6.0"
events "^1.1.1"
+ xtend "^4.0.1"
eth-token-tracker@^1.1.4:
version "1.1.4"
@@ -3338,21 +3890,38 @@ eth-token-tracker@^1.1.4:
ethjs-query "^0.2.6"
human-standard-token-abi "^1.0.2"
-ethereum-common@0.0.18, ethereum-common@^0.0.18:
+eth-tx-summary@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.1.2.tgz#e38836fc9f8b56f14d75952f0f5e570f88fb2220"
+ dependencies:
+ async "^2.1.2"
+ clone "^2.0.0"
+ concat-stream "^1.5.1"
+ end-of-stream "^1.1.0"
+ eth-query "^2.0.2"
+ ethereumjs-block "^1.4.1"
+ ethereumjs-tx "^1.1.1"
+ ethereumjs-util "^5.0.1"
+ ethereumjs-vm "^2.0.2"
+ through2 "^2.0.3"
+ treeify "^1.0.1"
+ web3-provider-engine "^13.3.2"
+
+ethereum-common@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca"
+
+ethereum-common@^0.0.18:
version "0.0.18"
resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f"
-ethereum-common@0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.1.0.tgz#874dd0fae5e962a56c50ebf28efa6fe39492b0e7"
-
ethereum-ens-network-map@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ethereum-ens-network-map/-/ethereum-ens-network-map-1.0.0.tgz#43cd7669ce950a789e151001118d4d65f210eeb7"
-"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
- version "0.6.4"
- resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee6ded67235a98f3ef4ae2a338aee70a9f68fe20"
+ethereumjs-abi@^0.6.4, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
+ version "0.6.5"
+ resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#71f123b676f2b2d81bc20f343670d90045a3d3d8"
dependencies:
bn.js "^4.10.0"
ethereumjs-util "^4.3.0"
@@ -3364,24 +3933,24 @@ ethereumjs-account@^2.0.3:
ethereumjs-util "^4.0.1"
rlp "^2.0.0"
-ethereumjs-block@^1.2.2, ethereumjs-block@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.6.0.tgz#cded4962deaca1eef17372b4d290e84b35c84372"
+ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0, ethereumjs-block@~1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.0.tgz#23d6a765b069500a9f35d1c093ab6b216cbbeb06"
dependencies:
async "^2.0.1"
- ethereum-common "0.0.18"
+ ethereum-common "0.2.0"
ethereumjs-tx "^1.2.2"
ethereumjs-util "^5.0.0"
merkle-patricia-tree "^2.1.2"
-ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.0, ethereumjs-tx@^1.3.3:
+ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.0, ethereumjs-tx@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.3.tgz#ece051d3efdbe771ad2a518d61632ca2ab75ecbb"
dependencies:
ethereum-common "^0.0.18"
ethereumjs-util "^5.0.0"
-ethereumjs-util@4.5.0, ethereumjs-util@^4.0.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0:
+ethereumjs-util@4.5.0, ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6"
dependencies:
@@ -3391,7 +3960,7 @@ ethereumjs-util@4.5.0, ethereumjs-util@^4.0.0, ethereumjs-util@^4.0.1, ethereumj
rlp "^2.0.0"
secp256k1 "^3.0.1"
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
+ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz#25ba0215cbb4c2f0b108a6f96af2a2e62e45921f"
dependencies:
@@ -3404,6 +3973,18 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
rlp "^2.0.0"
secp256k1 "^3.0.1"
+ethereumjs-util@^5.1.3:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.3.tgz#0c1f6efb1da9c5b6720a65697859fc0be6672df0"
+ dependencies:
+ bn.js "^4.8.0"
+ create-hash "^1.1.2"
+ ethjs-util "^0.1.3"
+ keccak "^1.0.2"
+ rlp "^2.0.0"
+ safe-buffer "^5.1.1"
+ secp256k1 "^3.0.1"
+
"ethereumjs-util@github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9":
version "5.0.1"
resolved "https://codeload.github.com/ethereumjs/ethereumjs-util/tar.gz/ac5d0908536b447083ea422b435da27f26615de9"
@@ -3415,18 +3996,20 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2:
secp256k1 "^3.0.1"
ethereumjs-vm@^2.0.0, ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.2.1.tgz#183406cc40e4d9f4248e7e047dea7c191beab3a1"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.2.tgz#4f939e22b89e9b298f0c87a7e0f0d8949f485abd"
dependencies:
async "^2.1.2"
async-eventemitter "^0.2.2"
- ethereum-common "0.1.0"
+ ethereum-common "0.2.0"
ethereumjs-account "^2.0.3"
- ethereumjs-block "^1.2.2"
+ ethereumjs-block "~1.7.0"
ethereumjs-util "4.5.0"
fake-merkle-patricia-tree "^1.0.1"
functional-red-black-tree "^1.0.1"
merkle-patricia-tree "^2.1.2"
+ rustbn.js "~0.1.1"
+ safe-buffer "^5.1.1"
ethereumjs-wallet@^0.6.0:
version "0.6.0"
@@ -3474,9 +4057,9 @@ ethjs-filter@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/ethjs-filter/-/ethjs-filter-0.1.5.tgz#0112af6017c24677e32b8fdeb20e6196019b7598"
-ethjs-format@0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.0.tgz#b4aa513fc1d50270d8f102bf06f03c9490d31391"
+ethjs-format@0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.2.tgz#d73b3a605c2e1257079f7077fd5448e998ce0fcd"
dependencies:
bn.js "4.11.6"
ethjs-schema "0.1.5"
@@ -3485,12 +4068,23 @@ ethjs-format@0.2.0:
number-to-bn "1.7.0"
strip-hex-prefix "1.0.0"
-ethjs-format@0.2.2:
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.2.tgz#d73b3a605c2e1257079f7077fd5448e998ce0fcd"
+ethjs-format@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.3.tgz#9bd867caee82b2dbed984600bb30220cf3cb5830"
dependencies:
bn.js "4.11.6"
- ethjs-schema "0.1.5"
+ ethjs-schema "^0.1.6"
+ ethjs-util "0.1.3"
+ is-hex-prefixed "1.0.0"
+ number-to-bn "1.7.0"
+ strip-hex-prefix "1.0.0"
+
+ethjs-format@0.2.4:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.4.tgz#5bbbc44a5ad24e68ab393312ff9039a73b65bf81"
+ dependencies:
+ bn.js "4.11.6"
+ ethjs-schema "^0.1.9"
ethjs-util "0.1.3"
is-hex-prefixed "1.0.0"
number-to-bn "1.7.0"
@@ -3502,11 +4096,11 @@ ethjs-provider-http@0.1.6:
dependencies:
xhr2 "0.1.3"
-ethjs-query@0.2.6:
- version "0.2.6"
- resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.2.6.tgz#9d8e6044b8bf76dd3340f843716a2259b9c91d3c"
+ethjs-query@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.0.tgz#08098d610f81bd5f954a7a57ab4989f7e9815fc4"
dependencies:
- ethjs-format "0.2.0"
+ ethjs-format "0.2.3"
ethjs-rpc "0.1.5"
ethjs-query@^0.2.4, ethjs-query@^0.2.6, ethjs-query@^0.2.9:
@@ -3516,14 +4110,29 @@ ethjs-query@^0.2.4, ethjs-query@^0.2.6, ethjs-query@^0.2.9:
ethjs-format "0.2.2"
ethjs-rpc "0.1.5"
+ethjs-query@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.2.tgz#f488a48ce1994cd4c77eccb7b52902c6f29cfd85"
+ dependencies:
+ ethjs-format "0.2.4"
+ ethjs-rpc "0.1.8"
+
ethjs-rpc@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.5.tgz#099e22f27dc4c18b6978a485fc36b1b0f7969080"
+ethjs-rpc@0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.8.tgz#1676740e41c7228196a71189d33f15c9c85b599d"
+
ethjs-schema@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.5.tgz#59740e3b3977bcdbb9b11bc3068201e8aceabb0d"
+ethjs-schema@^0.1.6, ethjs-schema@^0.1.9:
+ version "0.1.9"
+ resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.9.tgz#858c2a5da706ae04812b4ce8b1eb4b4921e33092"
+
ethjs-unit@0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
@@ -3545,16 +4154,16 @@ ethjs-util@^0.1.3:
is-hex-prefixed "1.0.0"
strip-hex-prefix "1.0.0"
-ethjs@^0.2.7:
- version "0.2.8"
- resolved "https://registry.yarnpkg.com/ethjs/-/ethjs-0.2.8.tgz#65ed276c5e58e89d51d4573585b7a16142ccf8f0"
+ethjs@^0.2.7, ethjs@^0.2.8:
+ version "0.2.9"
+ resolved "https://registry.yarnpkg.com/ethjs/-/ethjs-0.2.9.tgz#c9a80d47bc9d560f59e778049d22255e581f312b"
dependencies:
bn.js "4.11.6"
ethjs-abi "0.2.0"
ethjs-contract "0.1.9"
ethjs-filter "0.1.5"
ethjs-provider-http "0.1.6"
- ethjs-query "0.2.6"
+ ethjs-query "0.3.0"
ethjs-unit "0.1.6"
ethjs-util "0.1.3"
js-sha3 "0.5.5"
@@ -3591,7 +4200,7 @@ events-to-array@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/events-to-array/-/events-to-array-1.1.2.tgz#2d41f563e1fe400ed4962fe1a4d5c6a7539df7f6"
-events@^1.1.1, events@~1.1.0:
+events@^1.0.0, events@^1.1.1, events@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
@@ -3614,6 +4223,16 @@ execa@^0.7.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
+execall@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73"
+ dependencies:
+ clone-regexp "^1.0.0"
+
+exists-stat@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/exists-stat/-/exists-stat-1.0.0.tgz#0660e3525a2e89d9e446129440c272edfa24b529"
+
expand-braces@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
@@ -3628,6 +4247,18 @@ expand-brackets@^0.1.4:
dependencies:
is-posix-bracket "^0.1.0"
+expand-brackets@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
+ dependencies:
+ debug "^2.3.3"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ posix-character-classes "^0.1.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
expand-range@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044"
@@ -3641,58 +4272,21 @@ expand-range@^1.8.1:
dependencies:
fill-range "^2.1.0"
-expand-template@^1.0.2:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.0.tgz#e09efba977bf98f9ee0ed25abd0c692e02aec3fc"
-
expand-tilde@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449"
dependencies:
os-homedir "^1.0.1"
-expand-tilde@^2.0.2:
+expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
dependencies:
homedir-polyfill "^1.0.1"
-express@^4.10.7:
- version "4.15.4"
- resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1"
- dependencies:
- accepts "~1.3.3"
- array-flatten "1.1.1"
- content-disposition "0.5.2"
- content-type "~1.0.2"
- cookie "0.3.1"
- cookie-signature "1.0.6"
- debug "2.6.8"
- depd "~1.1.1"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- etag "~1.8.0"
- finalhandler "~1.0.4"
- fresh "0.5.0"
- merge-descriptors "1.0.1"
- methods "~1.1.2"
- on-finished "~2.3.0"
- parseurl "~1.3.1"
- path-to-regexp "0.1.7"
- proxy-addr "~1.1.5"
- qs "6.5.0"
- range-parser "~1.2.0"
- send "0.15.4"
- serve-static "1.12.4"
- setprototypeof "1.0.3"
- statuses "~1.3.1"
- type-is "~1.6.15"
- utils-merge "1.0.0"
- vary "~1.1.1"
-
-express@^4.15.5:
- version "4.16.1"
- resolved "https://registry.yarnpkg.com/express/-/express-4.16.1.tgz#6b33b560183c9b253b7b62144df33a4654ac9ed0"
+express@^4.10.7, express@^4.15.5:
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
dependencies:
accepts "~1.3.4"
array-flatten "1.1.1"
@@ -3725,17 +4319,30 @@ express@^4.15.5:
utils-merge "1.0.1"
vary "~1.1.2"
+extend-shallow@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071"
+ dependencies:
+ kind-of "^1.1.0"
+
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
dependencies:
is-extendable "^0.1.0"
+extend-shallow@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
+ dependencies:
+ assign-symbols "^1.0.0"
+ is-extendable "^1.0.1"
+
extend@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extend/-/extend-1.3.0.tgz#d1516fb0ff5624d2ebf9123ea1dac5a1994004f8"
-extend@^3.0.0, extend@~3.0.0:
+extend@^3.0.0, extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -3750,12 +4357,12 @@ extensionizer@^1.0.0:
resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.0.tgz#01c209bbea6d9c0acba77129c3aa4a9a98fc3538"
external-editor@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972"
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
dependencies:
+ chardet "^0.4.0"
iconv-lite "^0.4.17"
- jschardet "^1.4.2"
- tmp "^0.0.31"
+ tmp "^0.0.33"
extglob@^0.3.1:
version "0.3.2"
@@ -3763,10 +4370,27 @@ extglob@^0.3.1:
dependencies:
is-extglob "^1.0.0"
-extsprintf@1.3.0, extsprintf@^1.2.0:
+extglob@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.3.tgz#55e019d0c95bf873949c737b7e5172dba84ebb29"
+ dependencies:
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ expand-brackets "^2.1.4"
+ extend-shallow "^2.0.1"
+ fragment-cache "^0.2.1"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+extsprintf@^1.2.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+
eyes@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
@@ -3787,10 +4411,11 @@ falafel@^2.1.0:
object-keys "^1.0.6"
fancy-log@^1.1.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1"
dependencies:
- chalk "^1.1.1"
+ ansi-gray "^0.1.1"
+ color-support "^1.1.3"
time-stamp "^1.0.0"
fast-deep-equal@^1.0.0:
@@ -3798,11 +4423,15 @@ fast-deep-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
fast-json-patch@^2.0.4:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.0.5.tgz#a712e829be69ab707514440c5404bdd9b0d3c609"
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.0.6.tgz#86fff8f8662391aa819722864d632e603e6ee605"
dependencies:
deep-equal "^1.0.1"
+fast-json-stable-stringify@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
@@ -3813,19 +4442,7 @@ faye-websocket@~0.7.2:
dependencies:
websocket-driver ">=0.3.6"
-fbjs@^0.8.1, fbjs@^0.8.9:
- version "0.8.15"
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9"
- dependencies:
- core-js "^1.0.0"
- isomorphic-fetch "^2.1.1"
- loose-envify "^1.0.0"
- object-assign "^4.1.0"
- promise "^7.1.1"
- setimmediate "^1.0.5"
- ua-parser-js "^0.7.9"
-
-fbjs@^0.8.16:
+fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.9:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
@@ -3878,21 +4495,18 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
-finalhandler@1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7"
+fill-range@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
dependencies:
- debug "2.6.8"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.1"
- statuses "~1.3.1"
- unpipe "~1.0.0"
+ extend-shallow "^2.0.1"
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+ to-regex-range "^2.1.0"
-finalhandler@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
+finalhandler@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.6.tgz#007aea33d1a4d3e42017f624848ad58d212f814f"
dependencies:
debug "2.6.9"
encodeurl "~1.0.1"
@@ -3902,11 +4516,11 @@ finalhandler@1.1.0:
statuses "~1.3.1"
unpipe "~1.0.0"
-finalhandler@~1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.5.tgz#a701303d257a1bc82fea547a33e5ae89531723df"
+finalhandler@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
dependencies:
- debug "2.6.8"
+ debug "2.6.9"
encodeurl "~1.0.1"
escape-html "~1.0.3"
on-finished "~2.3.0"
@@ -3941,7 +4555,7 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
-findup-sync@^0.4.2:
+findup-sync@0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12"
dependencies:
@@ -3950,11 +4564,14 @@ findup-sync@^0.4.2:
micromatch "^2.3.7"
resolve-dir "^0.1.0"
-findup-sync@~0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16"
+findup-sync@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
dependencies:
- glob "~5.0.0"
+ detect-file "^1.0.0"
+ is-glob "^3.1.0"
+ micromatch "^3.0.4"
+ resolve-dir "^1.0.1"
fined@^1.0.1:
version "1.1.0"
@@ -3976,23 +4593,19 @@ fireworm@^0.7.0:
lodash.flatten "^3.0.2"
minimatch "^3.0.2"
-first-chunk-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e"
-
first-chunk-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
dependencies:
readable-stream "^2.0.2"
-flagged-respawn@^0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5"
+flagged-respawn@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7"
flat-cache@^1.2.1:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
dependencies:
circular-json "^0.3.1"
del "^2.0.2"
@@ -4007,7 +4620,11 @@ flatten@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-0.0.1.tgz#554440766da0a0d603999f433453f6c2fc6a75c1"
-flush-write-stream@^1.0.0:
+flatten@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
+
+flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
dependencies:
@@ -4020,7 +4637,7 @@ for-each@^0.3.2, for-each@~0.3.2:
dependencies:
is-function "~1.0.0"
-for-in@^1.0.1:
+for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -4063,19 +4680,29 @@ form-data@~2.1.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
+form-data@~2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
formatio@1.2.0, formatio@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
dependencies:
samsam "1.x"
-forwarded@~0.1.0, forwarded@~0.1.2:
+forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
-fresh@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e"
+fragment-cache@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
+ dependencies:
+ map-cache "^0.2.2"
fresh@0.5.2:
version "0.5.2"
@@ -4119,6 +4746,13 @@ fs-extra@^2.0.0:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"
+fs-mkdirp-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb"
+ dependencies:
+ graceful-fs "^4.1.11"
+ through2 "^2.0.3"
+
fs-promise@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854"
@@ -4133,11 +4767,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
fsevents@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4"
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
dependencies:
nan "^2.3.0"
- node-pre-gyp "^0.6.36"
+ node-pre-gyp "^0.6.39"
fstream-ignore@^1.0.5:
version "1.0.5"
@@ -4160,7 +4794,7 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1, function-bind@
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
-function.prototype.name@^1.0.0:
+function.prototype.name@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
dependencies:
@@ -4172,6 +4806,14 @@ functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+fuse.js@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.2.0.tgz#f0448e8069855bf2a3e683cdc1d320e7e2a07ef4"
+
+gather-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b"
+
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@@ -4185,6 +4827,22 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
+gaze@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105"
+ dependencies:
+ globule "^1.0.0"
+
+generate-function@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
+
+generate-object-property@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
+ dependencies:
+ is-property "^1.0.0"
+
get-caller-file@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
@@ -4197,20 +4855,28 @@ get-stdin@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-3.0.2.tgz#c1ced24b9039b38ded85bdf161e57713b6dd4abe"
+get-stdin@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
+
+get-stdin@^5.0.0, get-stdin@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
+
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
+get-value@^2.0.3, get-value@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
+
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
-github-from-package@0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
-
gl-mat4@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.1.4.tgz#1e895b55892e56a896867abd837d38f37a178086"
@@ -4239,36 +4905,38 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
-glob-parent@^3.0.0, glob-parent@^3.0.1:
+glob-parent@^3.0.1, glob-parent@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
dependencies:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob-stream@^5.3.2:
- version "5.3.5"
- resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22"
+glob-stream@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4"
dependencies:
extend "^3.0.0"
- glob "^5.0.3"
- glob-parent "^3.0.0"
- micromatch "^2.3.7"
- ordered-read-streams "^0.3.0"
- through2 "^0.6.0"
- to-absolute-glob "^0.1.1"
+ glob "^7.1.1"
+ glob-parent "^3.1.0"
+ is-negated-glob "^1.0.0"
+ ordered-read-streams "^1.0.0"
+ pumpify "^1.3.5"
+ readable-stream "^2.1.5"
+ remove-trailing-separator "^1.0.1"
+ to-absolute-glob "^2.0.0"
unique-stream "^2.0.2"
-glob-watcher@^3.0.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-3.2.0.tgz#ffc1a2d3d07783b672f5e21799a4d0b3fed92daf"
+glob-watcher@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-4.0.0.tgz#9e63a8ff6e61e932de6cc2caece5071a6d737329"
dependencies:
async-done "^1.2.0"
chokidar "^1.4.3"
- lodash.debounce "^4.0.6"
- object.defaults "^1.0.0"
+ just-debounce "^1.0.0"
+ object.defaults "^1.1.0"
-glob@7.1.2, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.2:
+glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@@ -4279,7 +4947,7 @@ glob@7.1.2, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glo
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^5.0.15, glob@^5.0.3, glob@~5.0.0:
+glob@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
dependencies:
@@ -4289,6 +4957,16 @@ glob@^5.0.15, glob@^5.0.3, glob@~5.0.0:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^6.0.4:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
global-modules@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d"
@@ -4296,6 +4974,14 @@ global-modules@^0.2.3:
global-prefix "^0.1.4"
is-windows "^0.2.0"
+global-modules@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
+ dependencies:
+ global-prefix "^1.0.1"
+ is-windows "^1.0.1"
+ resolve-dir "^1.0.0"
+
global-prefix@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f"
@@ -4305,6 +4991,16 @@ global-prefix@^0.1.4:
is-windows "^0.2.0"
which "^1.2.12"
+global-prefix@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
+ dependencies:
+ expand-tilde "^2.0.2"
+ homedir-polyfill "^1.0.1"
+ ini "^1.3.4"
+ is-windows "^1.0.1"
+ which "^1.2.14"
+
global@~4.3.0:
version "4.3.2"
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
@@ -4313,10 +5009,14 @@ global@~4.3.0:
process "~0.5.1"
globals@^10.0.0:
- version "10.1.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-10.1.0.tgz#4425a1881be0d336b4a823a82a7be725d5dd987c"
+ version "10.4.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7"
+
+globals@^11.0.1:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4"
-globals@^9.17.0, globals@^9.18.0:
+globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@@ -4331,7 +5031,7 @@ globby@^5.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
-globby@^6.1.0:
+globby@^6.0.0, globby@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
dependencies:
@@ -4341,16 +5041,49 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+globby@^7.0.0:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680"
+ dependencies:
+ array-union "^1.0.1"
+ dir-glob "^2.0.0"
+ glob "^7.1.2"
+ ignore "^3.3.5"
+ pify "^3.0.0"
+ slash "^1.0.0"
+
+globjoin@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
+
+globule@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09"
+ dependencies:
+ glob "~7.1.1"
+ lodash "~4.17.4"
+ minimatch "~3.0.2"
+
glogg@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5"
dependencies:
sparkles "^1.0.0"
+gonzales-pe@^4.0.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.2.3.tgz#41091703625433285e0aee3aa47829fc1fbeb6f2"
+ dependencies:
+ minimist "1.1.x"
+
graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+"graceful-readlink@>= 1.0.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
+
growl@1.10.3:
version "1.10.3"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f"
@@ -4359,28 +5092,47 @@ growly@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
-gulp-cli@^1.0.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-1.4.0.tgz#6f5bbe2cd0bdb4849d12cf9e1246a5861f8b4f88"
+gulp-autoprefixer@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-autoprefixer/-/gulp-autoprefixer-4.0.0.tgz#e00a8c571b85d06516ac26341be90dfd9fc1eab0"
+ dependencies:
+ autoprefixer "^7.0.0"
+ gulp-util "^3.0.0"
+ postcss "^6.0.1"
+ through2 "^2.0.0"
+ vinyl-sourcemaps-apply "^0.2.0"
+
+gulp-babel@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.0.tgz#7b93c975159f7a0553e4263b4a55100ccc239b28"
+ dependencies:
+ gulp-util "^3.0.0"
+ replace-ext "0.0.1"
+ through2 "^2.0.0"
+ vinyl-sourcemaps-apply "^0.2.0"
+
+gulp-cli@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.0.0.tgz#7f049ad298ed388cda9bd813b5d7062407d62cad"
dependencies:
+ ansi-colors "^1.0.1"
archy "^1.0.0"
- chalk "^1.1.0"
- copy-props "^1.4.1"
+ array-sort "^1.0.0"
+ color-support "^1.1.3"
+ concat-stream "^1.6.0"
+ copy-props "^2.0.1"
fancy-log "^1.1.0"
gulplog "^1.0.0"
interpret "^1.0.0"
+ isobject "^3.0.1"
liftoff "^2.3.0"
- lodash.isfunction "^3.0.8"
- lodash.isplainobject "^4.0.4"
- lodash.sortby "^4.5.0"
- matchdep "^1.0.0"
+ matchdep "^2.0.0"
mute-stdout "^1.0.0"
pretty-hrtime "^1.0.0"
+ replace-homedir "^1.0.0"
semver-greatest-satisfied-range "^1.0.0"
- tildify "^1.0.0"
- v8flags "^2.0.9"
- wreck "^6.3.0"
- yargs "^3.28.0"
+ v8flags "^3.0.1"
+ yargs "^7.1.0"
gulp-eslint@^4.0.0:
version "4.0.0"
@@ -4389,7 +5141,7 @@ gulp-eslint@^4.0.0:
eslint "^4.0.0"
gulp-util "^3.0.8"
-gulp-if@^2.0.1:
+gulp-if@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/gulp-if/-/gulp-if-2.0.2.tgz#a497b7e7573005041caa2bc8b7dda3c80444d629"
dependencies:
@@ -4432,34 +5184,78 @@ gulp-replace@^0.6.1:
readable-stream "^2.0.1"
replacestream "^4.0.0"
-gulp-sourcemaps@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c"
+gulp-sass@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.1.0.tgz#53dc4b68a1f5ddfe4424ab4c247655269a8b74b7"
dependencies:
- convert-source-map "^1.1.1"
- graceful-fs "^4.1.2"
- strip-bom "^2.0.0"
+ gulp-util "^3.0"
+ lodash.clonedeep "^4.3.2"
+ node-sass "^4.2.0"
through2 "^2.0.0"
- vinyl "^1.0.0"
+ vinyl-sourcemaps-apply "^0.2.0"
gulp-sourcemaps@^2.6.0:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz#833a4e28f0b8f4661075032cd782417f7cd8fb0b"
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.2.tgz#4f41c72b35a7ea06b666d2e3f57917e2c0e71c4e"
dependencies:
"@gulp-sourcemaps/identity-map" "1.X"
"@gulp-sourcemaps/map-sources" "1.X"
- acorn "4.X"
+ acorn "5.X"
convert-source-map "1.X"
css "2.X"
- debug-fabulous ">=0.1.1"
+ debug-fabulous "1.X"
detect-newline "2.X"
graceful-fs "4.X"
source-map "0.X"
strip-bom-string "1.X"
through2 "2.X"
- vinyl "1.X"
-gulp-util@^3.0.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
+gulp-stylefmt@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/gulp-stylefmt/-/gulp-stylefmt-1.1.0.tgz#7aea00a0a9bd2fbd8a2482dc01f133edca303d52"
+ dependencies:
+ gulp-util "^3.0.7"
+ postcss "^5.0.21"
+ postcss-scss "^0.4.0"
+ stylefmt "^5.0.4"
+ through2 "^2.0.1"
+
+gulp-stylelint@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-stylelint/-/gulp-stylelint-4.0.0.tgz#440fa7e6c447e92644700e1e2a06a73e6e457750"
+ dependencies:
+ chalk "^2.0.1"
+ deep-extend "^0.5.0"
+ gulp-util "^3.0.8"
+ mkdirp "^0.5.1"
+ promise "^8.0.1"
+ strip-ansi "^4.0.0"
+ stylelint "^8.0.0"
+ through2 "^2.0.3"
+
+gulp-uglify-es@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-uglify-es/-/gulp-uglify-es-1.0.0.tgz#80b2f8e2fa7211c1706c597f08bbf620c870e545"
+ dependencies:
+ o-stream "^0.2.2"
+ plugin-error "^0.1.2"
+ uglify-es "^3.2.0"
+ vinyl "^2.1.0"
+ vinyl-sourcemaps-apply "^0.2.1"
+
+gulp-uglify@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.0.tgz#0df0331d72a0d302e3e37e109485dddf33c6d1ca"
+ dependencies:
+ gulplog "^1.0.0"
+ has-gulplog "^0.1.0"
+ lodash "^4.13.1"
+ make-error-cause "^1.1.1"
+ through2 "^2.0.0"
+ uglify-js "^3.0.5"
+ vinyl-sourcemaps-apply "^0.2.0"
+
+gulp-util@^3.0, gulp-util@^3.0.0, gulp-util@^3.0.2, gulp-util@^3.0.7, gulp-util@^3.0.8, gulp-util@~3.0.0:
version "3.0.8"
resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
dependencies:
@@ -4507,13 +5303,13 @@ gulp-zip@^4.0.0:
yazl "^2.1.0"
"gulp@github:gulpjs/gulp#4.0":
- version "4.0.0-alpha.2"
- resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/6d71a658c61edb3090221579d8f97dbe086ba2ed"
+ version "4.0.0-alpha.3"
+ resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/71c094a51c7972d26f557899ddecab0210ef3776"
dependencies:
- glob-watcher "^3.0.0"
- gulp-cli "^1.0.0"
+ glob-watcher "^4.0.0"
+ gulp-cli "^2.0.0"
undertaker "^1.0.0"
- vinyl-fs "^2.0.0"
+ vinyl-fs "^3.0.0"
gulplog@^1.0.0:
version "1.0.0"
@@ -4521,9 +5317,9 @@ gulplog@^1.0.0:
dependencies:
glogg "^1.0.0"
-handlebars@^4.0.1, handlebars@^4.0.3:
- version "4.0.10"
- resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f"
+handlebars@^4.0.3:
+ version "4.0.11"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
dependencies:
async "^1.4.0"
optimist "^0.6.1"
@@ -4535,6 +5331,19 @@ har-schema@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+har-schema@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+
+har-validator@~2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
+ dependencies:
+ chalk "^1.1.1"
+ commander "^2.9.0"
+ is-my-json-valid "^2.12.4"
+ pinkie-promise "^2.0.0"
+
har-validator@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
@@ -4542,6 +5351,13 @@ har-validator@~4.2.1:
ajv "^4.9.1"
har-schema "^1.0.5"
+har-validator@~5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
+ dependencies:
+ ajv "^5.1.0"
+ har-schema "^2.0.0"
+
has-ansi@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e"
@@ -4584,10 +5400,41 @@ has-gulplog@^0.1.0:
dependencies:
sparkles "^1.0.0"
+has-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+has-value@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
+ dependencies:
+ get-value "^2.0.3"
+ has-values "^0.1.4"
+ isobject "^2.0.0"
+
+has-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
+ dependencies:
+ get-value "^2.0.6"
+ has-values "^1.0.0"
+ isobject "^3.0.0"
+
+has-values@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
+
+has-values@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
+ dependencies:
+ is-number "^3.0.0"
+ kind-of "^4.0.0"
+
has@^1.0.0, has@^1.0.1, has@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
@@ -4618,7 +5465,7 @@ hat@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/hat/-/hat-0.0.3.tgz#bb014a9e64b3788aed8005917413d4ff3d502d8a"
-hawk@~3.1.3:
+hawk@3.1.3, hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
@@ -4627,6 +5474,15 @@ hawk@~3.1.3:
hoek "2.x.x"
sntp "1.x.x"
+hawk@~6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
+ dependencies:
+ boom "4.x.x"
+ cryptiles "3.x.x"
+ hoek "4.x.x"
+ sntp "2.x.x"
+
hdkey@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.7.1.tgz#caee4be81aa77921e909b8d228dd0f29acaee632"
@@ -4650,11 +5506,11 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
-hoist-non-react-statics@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
+hoek@4.x.x:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
-hoist-non-react-statics@^2.2.1:
+hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -4676,8 +5532,8 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
html-encoding-sniffer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz#79bf7a785ea495fe66165e734153f363ff5437da"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
dependencies:
whatwg-encoding "^1.0.1"
@@ -4694,6 +5550,10 @@ html-select@^2.3.5:
stream-splicer "^1.2.0"
through2 "^1.0.0"
+html-tags@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b"
+
html-tokenize@^1.1.1:
version "1.2.5"
resolved "https://registry.yarnpkg.com/html-tokenize/-/html-tokenize-1.2.5.tgz#7e5ba99ecb51ef906ec9a7fcdee6ca3267c7897e"
@@ -4707,7 +5567,7 @@ htmlescape@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351"
-htmlparser2@^3.9.1:
+htmlparser2@^3.9.1, htmlparser2@^3.9.2:
version "3.9.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
dependencies:
@@ -4735,8 +5595,8 @@ http-errors@~1.3.1:
statuses "1"
http-parser-js@>=0.4.0:
- version "0.4.6"
- resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.6.tgz#195273f58704c452d671076be201329dd341dc55"
+ version "0.4.9"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1"
http-proxy@^1.13.0, http-proxy@^1.13.1:
version "1.16.2"
@@ -4753,6 +5613,14 @@ http-signature@~1.1.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
+http-signature@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+ dependencies:
+ assert-plus "^1.0.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -4762,14 +5630,14 @@ human-standard-token-abi@^1.0.2:
resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz#207d7846796ee5bb85fdd336e769cb38045b2ae0"
i@0.3.x:
- version "0.3.5"
- resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5"
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d"
iconv-lite@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
-iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13:
+iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@@ -4803,9 +5671,9 @@ iframe@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/iframe/-/iframe-1.0.0.tgz#58e74822b178a0579d09cd169640fb9537470ef5"
-ignore@^3.3.3:
- version "3.3.5"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.5.tgz#c4e715455f6073a8d7e5dae72d2fc9d71663dba6"
+ignore@^3.2.0, ignore@^3.3.3, ignore@^3.3.5:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
ignorepatterns@^1.0.1:
version "1.1.0"
@@ -4823,6 +5691,20 @@ in-publish@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51"
+indent-string@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
+ dependencies:
+ repeating "^2.0.0"
+
+indent-string@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
+indexes-of@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
+
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
@@ -4843,13 +5725,19 @@ inherits@2.0.1:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
ini@^1.3.4, ini@~1.3.0:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
inject-css@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/inject-css/-/inject-css-0.1.1.tgz#ef3ffc78ec026c96e2355da0df32917e3526415c"
+inline-source-map@~0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.5.0.tgz#4a4c5dd8e4fb5e9b3cda60c822dfadcaee66e0af"
+ dependencies:
+ source-map "~0.4.0"
+
inline-source-map@~0.6.0:
version "0.6.2"
resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5"
@@ -4889,8 +5777,8 @@ insert-module-globals@^7.0.0:
xtend "^4.0.0"
interpret@^1.0.0:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2:
version "2.2.2"
@@ -4902,24 +5790,47 @@ invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
-ipaddr.js@1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0"
-
ipaddr.js@1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0"
irregular-plurals@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.3.0.tgz#7af06931bdf74be33dcf585a13e06fccc16caecf"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766"
+
+is-absolute@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
+ dependencies:
+ is-relative "^1.0.0"
+ is-windows "^1.0.1"
-is-absolute@^0.2.3:
- version "0.2.6"
- resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb"
+is-accessor-descriptor@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
dependencies:
- is-relative "^0.2.1"
- is-windows "^0.2.0"
+ kind-of "^3.0.2"
+
+is-accessor-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
+ dependencies:
+ kind-of "^6.0.0"
+
+is-alphabetical@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.1.tgz#c77079cc91d4efac775be1034bf2d243f95e6f08"
+
+is-alphanumeric@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4"
+
+is-alphanumerical@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz#dfb4aa4d1085e33bdb61c2dee9c80e9c6c19f53b"
+ dependencies:
+ is-alphabetical "^1.0.0"
+ is-decimal "^1.0.0"
is-arrayish@^0.2.1:
version "0.2.1"
@@ -4931,9 +5842,13 @@ is-binary-path@^1.0.0:
dependencies:
binary-extensions "^1.0.0"
-is-buffer@^1.1.0, is-buffer@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
+is-boolean-object@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
+
+is-buffer@^1.1.0, is-buffer@^1.1.4, is-buffer@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-builtin-module@^1.0.0:
version "1.0.0"
@@ -4945,10 +5860,46 @@ is-callable@^1.1.1, is-callable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+is-data-descriptor@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-data-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
+ dependencies:
+ kind-of "^6.0.0"
+
is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+is-decimal@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.1.tgz#f5fb6a94996ad9e8e3761fbfbd091f1fca8c4e82"
+
+is-descriptor@^0.1.0:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
+ dependencies:
+ is-accessor-descriptor "^0.1.6"
+ is-data-descriptor "^0.1.4"
+ kind-of "^5.0.0"
+
+is-descriptor@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
+ dependencies:
+ is-accessor-descriptor "^1.0.0"
+ is-data-descriptor "^1.0.0"
+ kind-of "^6.0.2"
+
+is-directory@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
+
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
@@ -4963,6 +5914,12 @@ is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+is-extendable@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
+ dependencies:
+ is-plain-object "^2.0.4"
+
is-extglob@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
@@ -5011,6 +5968,27 @@ is-hex-prefixed@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554"
+is-hexadecimal@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69"
+
+is-my-json-valid@^2.12.4:
+ version "2.17.1"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471"
+ dependencies:
+ generate-function "^2.0.0"
+ generate-object-property "^1.1.0"
+ jsonpointer "^4.0.0"
+ xtend "^4.0.0"
+
+is-negated-glob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2"
+
+is-number-object@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
+
is-number@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806"
@@ -5027,6 +6005,20 @@ is-number@^3.0.0:
dependencies:
kind-of "^3.0.2"
+is-number@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
+
+is-obj@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
+
+is-odd@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088"
+ dependencies:
+ is-number "^3.0.0"
+
is-path-cwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
@@ -5038,12 +6030,16 @@ is-path-in-cwd@^1.0.0:
is-path-inside "^1.0.0"
is-path-inside@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
dependencies:
path-is-inside "^1.0.1"
-is-plain-object@^2.0.1, is-plain-object@^2.0.3:
+is-plain-obj@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
+
+is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
dependencies:
@@ -5061,32 +6057,46 @@ is-promise@^2.1, is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
+is-property@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
dependencies:
has "^1.0.1"
-is-relative@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5"
- dependencies:
- is-unc-path "^0.1.1"
+is-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
-is-resolvable@^1.0.0:
+is-relative@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
+ resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
dependencies:
- tryit "^1.0.1"
+ is-unc-path "^1.0.0"
+
+is-resolvable@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4"
is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+is-string@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
+
is-subset@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
+is-supported-regexp-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8"
+
is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
@@ -5101,24 +6111,36 @@ is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
-is-unc-path@^0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9"
+is-unc-path@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
dependencies:
- unc-path-regex "^0.1.0"
+ unc-path-regex "^0.1.2"
-is-utf8@^0.2.0:
+is-utf8@^0.2.0, is-utf8@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
-is-valid-glob@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe"
+is-valid-glob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa"
+
+is-whitespace-character@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz#9ae0176f3282b65457a1992cdb084f8a5f833e3b"
is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
+is-windows@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
+
+is-word-character@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb"
+
isarray@0.0.1, isarray@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@@ -5160,15 +6182,15 @@ istanbul-lib-coverage@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
-istanbul-lib-hook@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc"
+istanbul-lib-hook@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b"
dependencies:
append-transform "^0.4.0"
-istanbul-lib-instrument@^1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz#66f6c9421cc9ec4704f76f2db084ba9078a2b532"
+istanbul-lib-instrument@^1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
@@ -5178,50 +6200,31 @@ istanbul-lib-instrument@^1.8.0:
istanbul-lib-coverage "^1.1.1"
semver "^5.3.0"
-istanbul-lib-report@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9"
+istanbul-lib-report@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425"
dependencies:
istanbul-lib-coverage "^1.1.1"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c"
+istanbul-lib-source-maps@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c"
dependencies:
- debug "^2.6.3"
+ debug "^3.1.0"
istanbul-lib-coverage "^1.1.1"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.2.tgz#0fb2e3f6aa9922bd3ce45d05d8ab4d5e8e07bd4f"
+istanbul-reports@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10"
dependencies:
handlebars "^4.0.3"
-istanbul@0.4.5:
- version "0.4.5"
- resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b"
- dependencies:
- abbrev "1.0.x"
- async "1.x"
- escodegen "1.8.x"
- esprima "2.7.x"
- glob "^5.0.15"
- handlebars "^4.0.1"
- js-yaml "3.x"
- mkdirp "0.5.x"
- nopt "3.x"
- once "1.x"
- resolve "1.1.x"
- supports-color "^3.1.0"
- which "^1.1.1"
- wordwrap "^1.0.0"
-
istextorbinary@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-1.0.2.tgz#ace19354d1a9a0173efeb1084ce0f87b0ad7decf"
@@ -5237,6 +6240,10 @@ jazzicon@^1.2.0:
mersenne-twister "^1.0.1"
raphael "^2.2.0"
+js-base64@^2.1.8, js-base64@^2.1.9:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
+
js-beautify@~1.5.4:
version "1.5.10"
resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.5.10.tgz#4d95371702699344a516ca26bf59f0a27bb75719"
@@ -5245,6 +6252,10 @@ js-beautify@~1.5.4:
mkdirp "~0.5.0"
nopt "~3.0.1"
+js-reporters@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/js-reporters/-/js-reporters-1.2.0.tgz#7cf2cb698196684790350d0c4ca07f4aed9ec17e"
+
js-sha3@0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a"
@@ -5261,7 +6272,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-js-yaml@3.x, js-yaml@^3.2.5, js-yaml@^3.2.7, js-yaml@^3.6.1, js-yaml@^3.9.1:
+js-yaml@^3.2.5, js-yaml@^3.2.7, js-yaml@^3.4.3, js-yaml@^3.6.1, js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
@@ -5272,38 +6283,37 @@ jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
-jschardet@^1.4.2:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.1.tgz#c519f629f86b3a5bedba58a88d311309eec097f9"
-
jsdom-global@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"
jsdom@^11.1.0:
- version "11.2.0"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.2.0.tgz#4f6b8736af3357c3af7227a3b54a5bda1c513fd6"
+ version "11.5.1"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.5.1.tgz#5df753b8d0bca20142ce21f4f6c039f99a992929"
dependencies:
abab "^1.0.3"
- acorn "^4.0.4"
- acorn-globals "^3.1.0"
+ acorn "^5.1.2"
+ acorn-globals "^4.0.0"
array-equal "^1.0.0"
+ browser-process-hrtime "^0.1.2"
content-type-parser "^1.0.1"
cssom ">= 0.3.2 < 0.4.0"
cssstyle ">= 0.2.37 < 0.3.0"
- escodegen "^1.6.1"
+ domexception "^1.0.0"
+ escodegen "^1.9.0"
html-encoding-sniffer "^1.0.1"
- nwmatcher "^1.4.1"
+ left-pad "^1.2.0"
+ nwmatcher "^1.4.3"
parse5 "^3.0.2"
pn "^1.0.0"
- request "^2.79.0"
+ request "^2.83.0"
request-promise-native "^1.0.3"
sax "^1.2.1"
symbol-tree "^3.2.1"
- tough-cookie "^2.3.2"
- webidl-conversions "^4.0.0"
+ tough-cookie "^2.3.3"
+ webidl-conversions "^4.0.2"
whatwg-encoding "^1.0.1"
- whatwg-url "^6.1.0"
+ whatwg-url "^6.3.0"
xml-name-validator "^2.0.1"
jsesc@^1.3.0:
@@ -5325,26 +6335,37 @@ jshint-stylish@~2.2.1:
string-length "^1.0.0"
text-table "^0.2.0"
-json-rpc-engine@^3.0.1:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.1.0.tgz#09285363372857569d75f61df6591b1b0afb0758"
+json-loader@^0.5.4:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
+
+json-parse-better-errors@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a"
+
+json-rpc-engine@^3.0.1, json-rpc-engine@^3.1.0, json-rpc-engine@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.4.0.tgz#8a1647a7f2cc7018f4802f41ec8208d281f78bfc"
dependencies:
async "^2.0.1"
babel-preset-env "^1.3.2"
babelify "^7.3.0"
+ json-rpc-error "^2.0.0"
+ promise-to-callback "^1.0.0"
-json-rpc-engine@^3.1.0, json-rpc-engine@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.2.0.tgz#d34dff106c8339c337a894da801f73b1f77b1bc8"
+json-rpc-engine@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.0.tgz#0cc673dcb4b71103523fec81d1bba195a457f993"
dependencies:
async "^2.0.1"
babel-preset-env "^1.3.2"
babelify "^7.3.0"
json-rpc-error "^2.0.0"
+ promise-to-callback "^1.0.0"
-json-rpc-engine@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.4.0.tgz#8a1647a7f2cc7018f4802f41ec8208d281f78bfc"
+json-rpc-engine@^3.6.1:
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz#f53084726dc6dedeead0e2c457eeb997135f1e25"
dependencies:
async "^2.0.1"
babel-preset-env "^1.3.2"
@@ -5380,6 +6401,10 @@ json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+
json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
@@ -5400,7 +6425,7 @@ json3@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
-json5@^0.5.1:
+json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
@@ -5410,14 +6435,31 @@ jsonfile@^2.1.0:
optionalDependencies:
graceful-fs "^4.1.6"
+jsonfilter@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/jsonfilter/-/jsonfilter-1.1.2.tgz#21ef7cedc75193813c75932e96a98be205ba5a11"
+ dependencies:
+ JSONStream "^0.8.4"
+ minimist "^1.1.0"
+ stream-combiner "^0.2.1"
+ through2 "^0.6.3"
+
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+jsonparse@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-0.0.5.tgz#330542ad3f0a654665b778f3eb2d9a9fa507ac64"
+
jsonparse@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
+jsonpointer@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -5427,15 +6469,27 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
+jstransform@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-10.1.0.tgz#b4c49bf63f162c108b0348399a8737c713b0a83a"
+ dependencies:
+ base62 "0.1.1"
+ esprima-fb "13001.1001.0-dev-harmony-fb"
+ source-map "0.1.31"
+
jsx-ast-utils@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
dependencies:
array-includes "^3.0.3"
-just-extend@^1.1.22:
- version "1.1.22"
- resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.22.tgz#3330af756cab6a542700c64b2e4e4aa062d52fff"
+just-debounce@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea"
+
+just-extend@^1.1.26:
+ version "1.1.27"
+ resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905"
karma-chrome-launcher@^2.2.0:
version "2.2.0"
@@ -5451,8 +6505,8 @@ karma-cli@^1.0.1:
resolve "^1.1.6"
karma-firefox-launcher@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.0.1.tgz#ce58f47c2013a88156d55a5d61337c099cf5bb51"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz#2c47030452f04531eb7d13d4fc7669630bb93339"
karma-qunit@^1.2.1:
version "1.2.1"
@@ -5491,13 +6545,12 @@ karma@^1.7.1:
useragent "^2.1.12"
keccak@^1.0.2:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.3.0.tgz#3681bd99ad3d0354ddb29b9040c1b6560cce08ac"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80"
dependencies:
bindings "^1.2.1"
inherits "^2.0.3"
nan "^2.2.1"
- prebuild-install "^2.0.0"
safe-buffer "^5.1.0"
keccakjs@^0.2.0:
@@ -5507,7 +6560,11 @@ keccakjs@^0.2.0:
browserify-sha3 "^0.0.1"
sha3 "^1.1.0"
-kind-of@^3.0.2, kind-of@^3.1.0:
+kind-of@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44"
+
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
@@ -5519,12 +6576,28 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
+kind-of@^5.0.0, kind-of@^5.0.2:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
+
+kind-of@^6.0.0, kind-of@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
+
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
optionalDependencies:
graceful-fs "^4.1.9"
+known-css-properties@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.2.0.tgz#899c94be368e55b42d7db8d5be7d73a4a4a41454"
+
+known-css-properties@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.5.0.tgz#6ff66943ed4a5b55657ee095779a91f4536f8084"
+
labeled-stream-splicer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59"
@@ -5544,6 +6617,12 @@ lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+lazy-cache@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
+ dependencies:
+ set-getter "^0.1.0"
+
lazystream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
@@ -5560,6 +6639,23 @@ lcov-parse@^0.0.10:
version "0.0.10"
resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3"
+ldjson-stream@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/ldjson-stream/-/ldjson-stream-1.2.1.tgz#91beceda5ac4ed2b17e649fb777e7abfa0189c2b"
+ dependencies:
+ split2 "^0.2.1"
+ through2 "^0.6.1"
+
+lead@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42"
+ dependencies:
+ flush-write-stream "^1.0.2"
+
+left-pad@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee"
+
leftpad@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/leftpad/-/leftpad-0.0.0.tgz#020c9ad0787216ba0f30d79d479b4b355d7d39c3"
@@ -5569,8 +6665,8 @@ level-codec@~7.0.0:
resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7"
level-errors@^1.0.3:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.1.tgz#52fdc2dbbaf395cf767db843929a38b7015678d2"
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d"
dependencies:
errno "~0.1.1"
@@ -5622,16 +6718,15 @@ lexical-scope@^1.2.0:
astw "^2.0.0"
liftoff@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
dependencies:
extend "^3.0.0"
- findup-sync "^0.4.2"
+ findup-sync "^2.0.0"
fined "^1.0.1"
- flagged-respawn "^0.3.2"
- lodash.isplainobject "^4.0.4"
- lodash.isstring "^4.0.1"
- lodash.mapvalues "^4.4.0"
+ flagged-respawn "^1.0.0"
+ is-plain-object "^2.0.4"
+ object.map "^1.0.0"
rechoir "^0.6.2"
resolve "^1.1.7"
@@ -5649,15 +6744,28 @@ load-json-file@^1.0.0:
pinkie-promise "^2.0.0"
strip-bom "^2.0.0"
-load-json-file@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+load-json-file@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
dependencies:
graceful-fs "^4.1.2"
- parse-json "^2.2.0"
- pify "^2.0.0"
+ parse-json "^4.0.0"
+ pify "^3.0.0"
strip-bom "^3.0.0"
+loader-runner@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
+
+loader-utils@^0.2.16:
+ version "0.2.17"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
+ dependencies:
+ big.js "^3.1.3"
+ emojis-list "^2.0.0"
+ json5 "^0.5.0"
+ object-assign "^4.0.1"
+
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -5743,15 +6851,11 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
-lodash.assignin@^4.0.9, lodash.assignin@^4.1.0:
+lodash.assignin@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
-lodash.bind@^4.1.4:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
-
-lodash.clonedeep@^4.4.1:
+lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.4.1:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
@@ -5761,24 +6865,16 @@ lodash.debounce@^3.1.1:
dependencies:
lodash._getnative "^3.0.0"
-lodash.debounce@^4.0.6, lodash.debounce@^4.0.8:
+lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
-lodash.defaults@^4.0.1:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
-
lodash.escape@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698"
dependencies:
lodash._root "^3.0.0"
-lodash.filter@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
-
lodash.find@^4.5.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
@@ -5794,13 +6890,9 @@ lodash.flatten@^3.0.2:
lodash._baseflatten "^3.0.0"
lodash._isiterateecall "^3.0.0"
-lodash.flatten@^4.2.0:
+lodash.flattendeep@^4.4.0:
version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
-
-lodash.foreach@^4.3.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
+ resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
lodash.get@^4.4.2:
version "4.4.2"
@@ -5814,22 +6906,6 @@ lodash.isarray@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
-lodash.isequal@^4.0.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
-
-lodash.isfunction@^3.0.8:
- version "3.0.8"
- resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.8.tgz#4db709fc81bc4a8fd7127a458a5346c5cdce2c6b"
-
-lodash.isplainobject@^4.0.4, lodash.isplainobject@^4.0.6:
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
-
-lodash.isstring@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
-
lodash.keys@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
@@ -5838,14 +6914,6 @@ lodash.keys@^3.0.0:
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
-lodash.map@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
-
-lodash.mapvalues@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
-
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -5854,21 +6922,9 @@ lodash.memoize@~3.0.3:
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
-lodash.merge@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5"
-
-lodash.pick@^4.2.1:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
-
-lodash.reduce@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
-
-lodash.reject@^4.4.0:
+lodash.mergewith@^4.6.0:
version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
+ resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55"
lodash.restparam@^3.0.0:
version "3.6.1"
@@ -5878,11 +6934,7 @@ lodash.shuffle@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz#145b5053cf875f6f5c2a33f48b6e9948c6ec7b4b"
-lodash.some@^4.4.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
-
-lodash.sortby@^4.5.0, lodash.sortby@^4.7.0:
+lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
@@ -5915,7 +6967,7 @@ lodash@^3.8.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
-lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.2:
+lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.2, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@@ -5923,12 +6975,18 @@ log-driver@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
-log-symbols@^1.0.0:
+log-symbols@^1.0.0, log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
dependencies:
chalk "^1.0.0"
+log-symbols@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6"
+ dependencies:
+ chalk "^2.0.1"
+
log4js@^0.6.31:
version "0.6.38"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd"
@@ -5937,16 +6995,20 @@ log4js@^0.6.31:
semver "~4.3.3"
loglevel@^1.4.1, loglevel@^1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.5.0.tgz#3863984a2c326b986fbb965f378758a6dc8a4324"
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934"
lolex@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
-lolex@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.1.2.tgz#2694b953c9ea4d013e5b8bfba891c991025b2629"
+lolex@^2.2.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.1.tgz#3d2319894471ea0950ef64692ead2a5318cff362"
+
+longest-streak@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e"
longest@^1.0.1:
version "1.0.1"
@@ -5958,10 +7020,23 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
dependencies:
js-tokens "^3.0.0"
+loud-rejection@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
+ dependencies:
+ currently-unhandled "^0.4.1"
+ signal-exit "^3.0.0"
+
lru-cache@2.2.x:
version "2.2.4"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
+lru-cache@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee"
+ dependencies:
+ pseudomap "^1.0.1"
+
lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
@@ -5979,6 +7054,16 @@ ltgt@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.0.tgz#b65ba5fcb349a29924c8e333f7c6a5562f2e4842"
+make-error-cause@^1.1.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d"
+ dependencies:
+ make-error "^1.2.0"
+
+make-error@^1.2.0:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.2.tgz#8762ffad2444dd8ff1f7c819629fa28e24fea1c4"
+
make-iterator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.0.tgz#57bef5dc85d23923ba23767324d8e8f8f3d9694b"
@@ -5989,22 +7074,54 @@ map-async@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/map-async/-/map-async-0.1.1.tgz#c897c0449f85864c74b5a3f196edb42156431745"
-map-cache@^0.2.0:
+map-cache@^0.2.0, map-cache@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+map-obj@^1.0.0, map-obj@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
+
+map-obj@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9"
+
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
-matchdep@^1.0.0:
+map-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
+ dependencies:
+ object-visit "^1.0.0"
+
+markdown-escapes@^1.0.0:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-1.0.1.tgz#a57a33804491fbae208aba8f68380437abc2dca5"
+ resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.1.tgz#1994df2d3af4811de59a6714934c2b2292734518"
+
+markdown-table@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.1.tgz#4b3dd3a133d1518b8ef0dbc709bf2a1b4824bc8c"
+
+matchdep@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e"
dependencies:
- findup-sync "~0.3.0"
- micromatch "^2.3.7"
- resolve "~1.1.6"
- stack-trace "0.0.9"
+ findup-sync "^2.0.0"
+ micromatch "^3.0.4"
+ resolve "^1.4.0"
+ stack-trace "0.0.10"
+
+matcher-collection@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-1.0.5.tgz#2ee095438372cb8884f058234138c05c644ec339"
+ dependencies:
+ minimatch "^3.0.2"
+
+mathml-tag-names@^2.0.0, mathml-tag-names@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.0.1.tgz#8d41268168bf86d1102b98109e28e531e7a34578"
md5-hex@^1.2.0:
version "1.3.0"
@@ -6023,9 +7140,12 @@ md5.js@^1.3.4:
hash-base "^3.0.0"
inherits "^2.0.1"
-"mdurl@~ 1.0.1":
+mdast-util-compact@^1.0.0:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
+ resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz#cdb5f84e2b6a2d3114df33bd05d9cb32e3c4083a"
+ dependencies:
+ unist-util-modify-children "^1.0.0"
+ unist-util-visit "^1.1.0"
media-typer@0.3.0:
version "0.3.0"
@@ -6038,16 +7158,17 @@ mem@^1.1.0:
mimic-fn "^1.0.0"
memdown@^1.0.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.3.1.tgz#071499332e3a74b88c3d9551b0750d61fdf0c5b7"
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215"
dependencies:
- abstract-leveldown "2.7.0"
+ abstract-leveldown "~2.7.1"
functional-red-black-tree "^1.0.1"
immediate "^3.2.3"
inherits "~2.0.1"
ltgt "~2.2.0"
+ safe-buffer "~5.1.1"
-memoizee@^0.4.5:
+memoizee@0.4.X:
version "0.4.11"
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.11.tgz#bde9817663c9e40fdb2a4ea1c367296087ae8c8f"
dependencies:
@@ -6060,19 +7181,55 @@ memoizee@^0.4.5:
next-tick "1"
timers-ext "^0.1.2"
+memory-fs@^0.4.0, memory-fs@~0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
+ dependencies:
+ errno "^0.1.3"
+ readable-stream "^2.0.1"
+
memorystream@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
+meow@^3.3.0, meow@^3.7.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
+ dependencies:
+ camelcase-keys "^2.0.0"
+ decamelize "^1.1.2"
+ loud-rejection "^1.0.0"
+ map-obj "^1.0.1"
+ minimist "^1.1.3"
+ normalize-package-data "^2.3.4"
+ object-assign "^4.0.1"
+ read-pkg-up "^1.0.1"
+ redent "^1.0.0"
+ trim-newlines "^1.0.0"
+
+meow@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.0.tgz#fd5855dd008db5b92c552082db1c307cba20b29d"
+ dependencies:
+ camelcase-keys "^4.0.0"
+ decamelize-keys "^1.0.0"
+ loud-rejection "^1.0.0"
+ minimist "^1.1.3"
+ minimist-options "^3.0.1"
+ normalize-package-data "^2.3.4"
+ read-pkg-up "^3.0.0"
+ redent "^2.0.0"
+ trim-newlines "^2.0.0"
+
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
merge-source-map@^1.0.2:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646"
dependencies:
- source-map "^0.5.6"
+ source-map "^0.6.1"
merge-stream@^1.0.0:
version "1.0.1"
@@ -6081,11 +7238,11 @@ merge-stream@^1.0.0:
readable-stream "^2.0.1"
merkle-patricia-tree@^2.1.2:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.2.0.tgz#7a4787b1262ab00fe9b204ab471b005332306efa"
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.0.tgz#84c606232ef343f1b96fc972e697708754f08573"
dependencies:
async "^1.4.2"
- ethereumjs-util "^4.0.0"
+ ethereumjs-util "^5.0.0"
level-ws "0.0.0"
levelup "^1.2.1"
memdown "^1.0.0"
@@ -6138,34 +7295,52 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
+micromatch@^3.0.4:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.4.tgz#bb812e741a41f982c854e42b421a7eac458796f4"
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ braces "^2.3.0"
+ define-property "^1.0.0"
+ extend-shallow "^2.0.1"
+ extglob "^2.0.2"
+ fragment-cache "^0.2.1"
+ kind-of "^6.0.0"
+ nanomatch "^1.2.5"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
miller-rabin@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d"
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
dependencies:
bn.js "^4.0.0"
brorand "^1.0.1"
+"mime-db@>= 1.30.0 < 2":
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.32.0.tgz#485b3848b01a3cda5f968b4882c0771e58e09414"
+
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
-mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.7:
+mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
-mime@1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
-
mime@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
mime@^1.3.4:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343"
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
mime@~1.2.9:
version "1.2.11"
@@ -6200,25 +7375,32 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
-"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
+"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
-minimist@0.0.5:
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.5.tgz#d7aa327bcecf518f9106ac6b8f003fa3bcea8566"
+minimist-options@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954"
+ dependencies:
+ arrify "^1.0.1"
+ is-plain-obj "^1.1.0"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+minimist@1.1.x:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
+
minimist@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de"
-minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0:
+minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@@ -6241,11 +7423,18 @@ mississippi@^1.2.0:
stream-each "^1.1.0"
through2 "^2.0.0"
+mixin-deep@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a"
+ dependencies:
+ for-in "^1.0.2"
+ is-extendable "^1.0.1"
+
mkdirp@0.0.x:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.0.7.tgz#d89b4f0e4c3e5e5ca54235931675e094fe1a5072"
-mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0:
+mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
@@ -6269,8 +7458,8 @@ mocha-sinon@^2.0.0:
resolved "https://registry.yarnpkg.com/mocha-sinon/-/mocha-sinon-2.0.0.tgz#723a9310e7d737d7b77c7a66821237425b032d48"
mocha@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.0.1.tgz#0aee5a95cf69a4618820f5e51fa31717117daf1b"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794"
dependencies:
browser-stdout "1.3.0"
commander "2.11.0"
@@ -6315,6 +7504,15 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+multimatch@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
+ dependencies:
+ array-differ "^1.0.0"
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ minimatch "^3.0.0"
+
multipipe@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b"
@@ -6351,13 +7549,25 @@ mz@^2.6.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
-nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46"
+nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.2:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
-native-promise-only@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11"
+nanomatch@^1.2.5:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.6.tgz#f27233e97c34a8706b7e781a4bc611c957a81625"
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ extend-shallow "^2.0.1"
+ fragment-cache "^0.2.1"
+ is-odd "^1.0.0"
+ kind-of "^5.0.2"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
natural-compare@^1.4.0:
version "1.4.0"
@@ -6367,6 +7577,14 @@ ncp@1.0.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
+nearley@^2.7.10:
+ version "2.11.0"
+ resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.11.0.tgz#5e626c79a6cd2f6ab9e7e5d5805e7668967757ae"
+ dependencies:
+ nomnom "~1.6.2"
+ railroad-diagrams "^1.0.0"
+ randexp "^0.4.2"
+
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@@ -6375,19 +7593,19 @@ next-tick@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
-nise@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/nise/-/nise-1.1.0.tgz#37e41b9bf0041ccb83d1bf03e79440bbc0db10ad"
+nise@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
dependencies:
formatio "^1.2.0"
- just-extend "^1.1.22"
+ just-extend "^1.1.26"
lolex "^1.6.0"
path-to-regexp "^1.7.0"
text-encoding "^0.6.4"
nock@^9.0.14:
- version "9.0.14"
- resolved "https://registry.yarnpkg.com/nock/-/nock-9.0.14.tgz#2211550253173ce298bcd89fca825e83813ca72b"
+ version "9.1.5"
+ resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.5.tgz#9e4878e0e1c050bdd93ae1e326e89461ea15618b"
dependencies:
chai ">=1.9.2 <4.0.0"
debug "^2.2.0"
@@ -6396,13 +7614,9 @@ nock@^9.0.14:
lodash "~4.17.2"
mkdirp "^0.5.0"
propagate "0.4.0"
- qs "^6.0.2"
+ qs "^6.5.1"
semver "^5.3.0"
-node-abi@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.1.1.tgz#c9cda256ec8aa99bcab2f6446db38af143338b2a"
-
node-fetch@^1.0.1, node-fetch@~1.7.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -6410,6 +7624,52 @@ node-fetch@^1.0.1, node-fetch@~1.7.1:
encoding "^0.1.11"
is-stream "^1.0.1"
+node-gyp@^3.3.1:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60"
+ dependencies:
+ fstream "^1.0.0"
+ glob "^7.0.3"
+ graceful-fs "^4.1.2"
+ minimatch "^3.0.2"
+ mkdirp "^0.5.0"
+ nopt "2 || 3"
+ npmlog "0 || 1 || 2 || 3 || 4"
+ osenv "0"
+ request "2"
+ rimraf "2"
+ semver "~5.3.0"
+ tar "^2.0.0"
+ which "1"
+
+node-libs-browser@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df"
+ dependencies:
+ assert "^1.1.1"
+ browserify-zlib "^0.2.0"
+ buffer "^4.3.0"
+ console-browserify "^1.1.0"
+ constants-browserify "^1.0.0"
+ crypto-browserify "^3.11.0"
+ domain-browser "^1.1.1"
+ events "^1.0.0"
+ https-browserify "^1.0.0"
+ os-browserify "^0.3.0"
+ path-browserify "0.0.0"
+ process "^0.11.10"
+ punycode "^1.2.4"
+ querystring-es3 "^0.2.0"
+ readable-stream "^2.3.3"
+ stream-browserify "^2.0.1"
+ stream-http "^2.7.2"
+ string_decoder "^1.0.0"
+ timers-browserify "^2.0.4"
+ tty-browserify "0.0.0"
+ url "^0.11.0"
+ util "^0.10.3"
+ vm-browserify "0.0.4"
+
node-notifier@^5.0.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
@@ -6419,26 +7679,54 @@ node-notifier@^5.0.1:
shellwords "^0.1.0"
which "^1.2.12"
-node-pre-gyp@^0.6.36:
- version "0.6.37"
- resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.37.tgz#3c872b236b2e266e4140578fe1ee88f693323a05"
+node-pre-gyp@^0.6.39:
+ version "0.6.39"
+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
dependencies:
+ detect-libc "^1.0.2"
+ hawk "3.1.3"
mkdirp "^0.5.1"
nopt "^4.0.1"
npmlog "^4.0.2"
rc "^1.1.7"
- request "^2.81.0"
+ request "2.81.0"
rimraf "^2.6.1"
semver "^5.3.0"
- tape "^4.6.3"
tar "^2.2.1"
tar-pack "^3.4.0"
-noop-logger@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
+node-sass@^4.2.0:
+ version "4.7.2"
+ resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e"
+ dependencies:
+ async-foreach "^0.1.3"
+ chalk "^1.1.1"
+ cross-spawn "^3.0.0"
+ gaze "^1.0.0"
+ get-stdin "^4.0.1"
+ glob "^7.0.3"
+ in-publish "^2.0.0"
+ lodash.assign "^4.2.0"
+ lodash.clonedeep "^4.3.2"
+ lodash.mergewith "^4.6.0"
+ meow "^3.7.0"
+ mkdirp "^0.5.1"
+ nan "^2.3.2"
+ node-gyp "^3.3.1"
+ npmlog "^4.0.0"
+ request "~2.79.0"
+ sass-graph "^2.2.4"
+ stdout-stream "^1.4.0"
+ "true-case-path" "^1.0.2"
+
+nomnom@~1.6.2:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
+ dependencies:
+ colors "0.5.x"
+ underscore "~1.4.4"
-nopt@3.x, nopt@~3.0.1:
+"nopt@2 || 3", nopt@~3.0.1:
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
dependencies:
@@ -6451,7 +7739,7 @@ nopt@^4.0.1:
abbrev "1"
osenv "^0.1.4"
-normalize-package-data@^2.3.2:
+normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
version "2.4.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
dependencies:
@@ -6466,6 +7754,14 @@ normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1:
dependencies:
remove-trailing-separator "^1.0.1"
+normalize-range@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
+
+normalize-selector@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
+
now-and-later@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee"
@@ -6478,7 +7774,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
-npmlog@^4.0.0, npmlog@^4.0.1, npmlog@^4.0.2:
+"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
dependencies:
@@ -6497,6 +7793,10 @@ null-check@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd"
+num2fraction@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
+
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
@@ -6508,13 +7808,13 @@ number-to-bn@1.7.0, number-to-bn@^1.7.0:
bn.js "4.11.6"
strip-hex-prefix "1.0.0"
-nwmatcher@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.1.tgz#7ae9b07b0ea804db7e25f05cb5fe4097d4e4949f"
+nwmatcher@^1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
nyc@^11.0.3:
- version "11.2.1"
- resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.2.1.tgz#ad850afe9dbad7f4970728b4b2e47fed1c38721c"
+ version "11.4.1"
+ resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.4.1.tgz#13fdf7e7ef22d027c61d174758f6978a68f4f5e5"
dependencies:
archy "^1.0.0"
arrify "^1.0.1"
@@ -6527,11 +7827,11 @@ nyc@^11.0.3:
foreground-child "^1.5.3"
glob "^7.0.6"
istanbul-lib-coverage "^1.1.1"
- istanbul-lib-hook "^1.0.7"
- istanbul-lib-instrument "^1.8.0"
- istanbul-lib-report "^1.1.1"
- istanbul-lib-source-maps "^1.2.1"
- istanbul-reports "^1.1.1"
+ istanbul-lib-hook "^1.1.0"
+ istanbul-lib-instrument "^1.9.1"
+ istanbul-lib-report "^1.1.2"
+ istanbul-lib-source-maps "^1.2.2"
+ istanbul-reports "^1.1.3"
md5-hex "^1.2.0"
merge-source-map "^1.0.2"
micromatch "^2.3.11"
@@ -6539,12 +7839,16 @@ nyc@^11.0.3:
resolve-from "^2.0.0"
rimraf "^2.5.4"
signal-exit "^3.0.1"
- spawn-wrap "^1.3.8"
+ spawn-wrap "^1.4.2"
test-exclude "^4.1.1"
- yargs "^8.0.1"
- yargs-parser "^5.0.0"
+ yargs "^10.0.3"
+ yargs-parser "^8.0.0"
-oauth-sign@~0.8.1:
+o-stream@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/o-stream/-/o-stream-0.2.2.tgz#7fe03af870b8f9537af33b312b381b3034ab410f"
+
+oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
@@ -6564,7 +7868,7 @@ object-assign@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
-object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@4.X, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -6572,6 +7876,18 @@ object-component@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291"
+object-copy@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
+ dependencies:
+ copy-descriptor "^0.1.0"
+ define-property "^0.2.5"
+ kind-of "^3.0.3"
+
+object-inspect@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.5.0.tgz#9d876c11e40f485c79215670281b767488f9bfe3"
+
object-inspect@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec"
@@ -6584,7 +7900,7 @@ object-is@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6"
-object-keys@^1.0.10, object-keys@^1.0.6, object-keys@^1.0.8:
+object-keys@^1.0.11, object-keys@^1.0.6, object-keys@^1.0.8:
version "1.0.11"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
@@ -6592,13 +7908,20 @@ object-keys@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
-object.assign@^4.0.4:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc"
+object-visit@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
+ dependencies:
+ isobject "^3.0.0"
+
+object.assign@^4.0.4, object.assign@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
dependencies:
define-properties "^1.1.2"
- function-bind "^1.1.0"
- object-keys "^1.0.10"
+ function-bind "^1.1.1"
+ has-symbols "^1.0.0"
+ object-keys "^1.0.11"
object.defaults@^1.0.0, object.defaults@^1.1.0:
version "1.1.0"
@@ -6618,6 +7941,13 @@ object.entries@^1.0.4:
function-bind "^1.1.0"
has "^1.0.1"
+object.map@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
+ dependencies:
+ for-own "^1.0.0"
+ make-iterator "^1.0.0"
+
object.omit@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
@@ -6625,7 +7955,7 @@ object.omit@^2.0.0:
for-own "^0.1.4"
is-extendable "^0.1.1"
-object.pick@^1.2.0:
+object.pick@^1.2.0, object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
dependencies:
@@ -6647,7 +7977,7 @@ object.values@^1.0.4:
function-bind "^1.1.0"
has "^1.0.1"
-obs-store@^2.3.1, obs-store@^2.4.1:
+obs-store@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/obs-store/-/obs-store-2.4.1.tgz#5425b85dabaf08d913464000ba65aaf25296492f"
dependencies:
@@ -6657,18 +7987,36 @@ obs-store@^2.3.1, obs-store@^2.4.1:
through2 "^2.0.3"
xtend "^4.0.1"
+obs-store@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/obs-store/-/obs-store-3.0.0.tgz#f44aa9ad73c65ceeeaa00476d434d4e5c3f0a9e8"
+ dependencies:
+ babel-preset-es2015 "^6.22.0"
+ babelify "^7.3.0"
+ readable-stream "^2.2.2"
+ through2 "^2.0.3"
+ xtend "^4.0.1"
+
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
dependencies:
ee-first "1.1.1"
-once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0:
+on-headers@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7"
+
+once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
+onecolor@^3.0.4:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.5.tgz#36eff32201379efdf1180fb445e51a8e2425f9f6"
+
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -6709,16 +8057,15 @@ options@>=0.0.5:
version "0.0.6"
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
-ordered-read-streams@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b"
+ordered-read-streams@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e"
dependencies:
- is-stream "^1.0.1"
readable-stream "^2.0.1"
-os-browserify@~0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54"
+os-browserify@^0.3.0, os-browserify@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
os-homedir@^1.0.0, os-homedir@^1.0.1:
version "1.0.2"
@@ -6742,7 +8089,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
-osenv@^0.1.4:
+osenv@0, osenv@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
dependencies:
@@ -6773,9 +8120,9 @@ p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
-pako@~0.2.0:
- version "0.2.9"
- resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
+pako@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
parallel-transform@^1.1.0:
version "1.1.0"
@@ -6801,11 +8148,22 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
+parse-entities@^1.0.2:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890"
+ dependencies:
+ character-entities "^1.0.0"
+ character-entities-legacy "^1.0.0"
+ character-reference-invalid "^1.0.0"
+ is-alphanumerical "^1.0.0"
+ is-decimal "^1.0.0"
+ is-hexadecimal "^1.0.0"
+
parse-filepath@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
dependencies:
- is-absolute "^0.2.3"
+ is-absolute "^1.0.0"
map-cache "^0.2.0"
path-root "^0.1.1"
@@ -6831,15 +8189,28 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-json@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
+ dependencies:
+ error-ex "^1.3.1"
+
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
-parse5@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.2.tgz#05eff57f0ef4577fb144a79f8b9a967a6cc44510"
+parse5@^3.0.1, parse5@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
dependencies:
- "@types/node" "^6.0.46"
+ "@types/node" "*"
parsejson@0.0.3:
version "0.0.3"
@@ -6859,7 +8230,7 @@ parseuri@0.0.5:
dependencies:
better-assert "~1.0.0"
-parseurl@~1.3.0, parseurl@~1.3.1, parseurl@~1.3.2:
+parseurl@~1.3.0, parseurl@~1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
@@ -6867,7 +8238,7 @@ pascalcase@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
-path-browserify@~0.0.0:
+path-browserify@0.0.0, path-browserify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
@@ -6933,11 +8304,11 @@ path-type@^1.0.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
-path-type@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
+path-type@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
dependencies:
- pify "^2.0.0"
+ pify "^3.0.0"
pathval@^1.0.0:
version "1.1.0"
@@ -6959,10 +8330,18 @@ pbkdf2@^3.0.3, pbkdf2@^3.0.9:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+percentile@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/percentile/-/percentile-1.2.0.tgz#fa3b05c1ffd355b35228529834e5fa37f0bd465d"
+
performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+performance-now@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -6989,6 +8368,13 @@ pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+pipetteur@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/pipetteur/-/pipetteur-2.0.3.tgz#1955760959e8d1a11cb2a50ec83eec470633e49f"
+ dependencies:
+ onecolor "^3.0.4"
+ synesthesia "^1.0.1"
+
pkg-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
@@ -7007,7 +8393,17 @@ plucker@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/plucker/-/plucker-0.0.0.tgz#2ffa24e03ab2cffa4e75adc1df70f25623c45d09"
-plur@^2.1.0:
+plugin-error@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace"
+ dependencies:
+ ansi-cyan "^0.1.1"
+ ansi-red "^0.1.1"
+ arr-diff "^1.0.1"
+ arr-union "^2.0.1"
+ extend-shallow "^1.1.2"
+
+plur@^2.0.0, plur@^2.1.0, plur@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a"
dependencies:
@@ -7031,36 +8427,149 @@ polyfill-crypto.getrandomvalues@^1.0.0:
dependencies:
mersenne-twister "^1.0.1"
+popper.js@^1.11.1:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.13.0.tgz#e1e7ff65cc43f7cf9cf16f1510a75e81f84f4565"
+
portfinder@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-0.2.1.tgz#b2b9b0164f9e17fa3a9c7db2304d0a75140c71ad"
dependencies:
mkdirp "0.0.x"
+posix-character-classes@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
+
post-message-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/post-message-stream/-/post-message-stream-3.0.0.tgz#90d9f54bd209e6b6f5d74795b87588205b547048"
dependencies:
readable-stream "^2.1.4"
-prebuild-install@^2.0.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.2.2.tgz#dd47c4d61f3754fb17bbf601759e5922e16e0671"
+postcss-html@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-0.12.0.tgz#39b6adb4005dfc5464df7999c0f81c95bced7e50"
dependencies:
- expand-template "^1.0.2"
- github-from-package "0.0.0"
- minimist "^1.2.0"
- mkdirp "^0.5.1"
- node-abi "^2.0.0"
- noop-logger "^0.1.1"
- npmlog "^4.0.1"
- os-homedir "^1.0.1"
- pump "^1.0.1"
- rc "^1.1.6"
- simple-get "^1.4.2"
- tar-fs "^1.13.0"
- tunnel-agent "^0.6.0"
- xtend "4.0.1"
+ htmlparser2 "^3.9.2"
+ remark "^8.0.0"
+ unist-util-find-all-after "^1.0.1"
+
+postcss-less@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-0.14.0.tgz#c631b089c6cce422b9a10f3a958d2bedd3819324"
+ dependencies:
+ postcss "^5.0.21"
+
+postcss-less@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-1.1.3.tgz#6930525271bfe38d5793d33ac09c1a546b87bb51"
+ dependencies:
+ postcss "^5.2.16"
+
+postcss-media-query-parser@^0.2.0, postcss-media-query-parser@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
+
+postcss-reporter@^1.2.1, postcss-reporter@^1.3.3:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-1.4.1.tgz#c136f0a5b161915f379dd3765c61075f7e7b9af2"
+ dependencies:
+ chalk "^1.0.0"
+ lodash "^4.1.0"
+ log-symbols "^1.0.2"
+ postcss "^5.0.0"
+
+postcss-reporter@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-3.0.0.tgz#09ea0f37a444c5693878606e09b018ebeff7cf8f"
+ dependencies:
+ chalk "^1.0.0"
+ lodash "^4.1.0"
+ log-symbols "^1.0.2"
+ postcss "^5.0.0"
+
+postcss-reporter@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-5.0.0.tgz#a14177fd1342829d291653f2786efd67110332c3"
+ dependencies:
+ chalk "^2.0.1"
+ lodash "^4.17.4"
+ log-symbols "^2.0.0"
+ postcss "^6.0.8"
+
+postcss-resolve-nested-selector@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e"
+
+postcss-safe-parser@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-3.0.1.tgz#b753eff6c7c0aea5e8375fbe4cde8bf9063ff142"
+ dependencies:
+ postcss "^6.0.6"
+
+postcss-sass@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-sass/-/postcss-sass-0.2.0.tgz#e55516441e9526ba4b380a730d3a02e9eaa78c7a"
+ dependencies:
+ gonzales-pe "^4.0.3"
+ postcss "^6.0.6"
+
+postcss-scss@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-0.4.1.tgz#ad771b81f0f72f5f4845d08aa60f93557653d54c"
+ dependencies:
+ postcss "^5.2.13"
+
+postcss-scss@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-1.0.2.tgz#ff45cf3354b879ee89a4eb68680f46ac9bb14f94"
+ dependencies:
+ postcss "^6.0.3"
+
+postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.1.1:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
+ dependencies:
+ flatten "^1.0.2"
+ indexes-of "^1.0.1"
+ uniq "^1.0.1"
+
+postcss-selector-parser@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865"
+ dependencies:
+ dot-prop "^4.1.1"
+ indexes-of "^1.0.1"
+ uniq "^1.0.1"
+
+postcss-sorting@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/postcss-sorting/-/postcss-sorting-2.1.0.tgz#32b1e9afa913bb225a6ad076d503d8f983bb4a82"
+ dependencies:
+ lodash "^4.17.4"
+ postcss "^5.2.17"
+
+postcss-value-parser@^3.1.1, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15"
+
+postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.17, postcss@^5.2.4, postcss@^5.2.5:
+ version "5.2.18"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5"
+ dependencies:
+ chalk "^1.1.3"
+ js-base64 "^2.1.9"
+ source-map "^0.5.6"
+ supports-color "^3.2.3"
+
+postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.8:
+ version "6.0.14"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.14.tgz#5534c72114739e75d0afcf017db853099f562885"
+ dependencies:
+ chalk "^2.3.0"
+ source-map "^0.6.1"
+ supports-color "^4.4.0"
prelude-ls@~1.1.2:
version "1.1.2"
@@ -7082,15 +8591,15 @@ printf@^0.2.3:
version "0.2.5"
resolved "https://registry.yarnpkg.com/printf/-/printf-0.2.5.tgz#c438ca2ca33e3927671db4ab69c0e52f936a4f0f"
-private@^0.1.6, private@^0.1.7:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
+private@^0.1.6, private@^0.1.7, private@~0.1.5:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
-process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
+process-nextick-args@^1.0.6, process-nextick-args@^1.0.7, process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
-process@~0.11.0:
+process@^0.11.10, process@~0.11.0:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
@@ -7121,6 +8630,12 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
+promise@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.1.tgz#e45d68b00a17647b6da711bf85ed6ed47208f450"
+ dependencies:
+ asap "~2.0.3"
+
prompt@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe"
@@ -7132,14 +8647,7 @@ prompt@^1.0.0:
utile "0.3.x"
winston "2.1.x"
-prop-types@^15.5.1, prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8:
- version "15.5.10"
- resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
- dependencies:
- fbjs "^0.8.9"
- loose-envify "^1.3.1"
-
-prop-types@^15.5.7:
+prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@@ -7155,13 +8663,6 @@ proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
-proxy-addr@~1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918"
- dependencies:
- forwarded "~0.1.0"
- ipaddr.js "1.4.0"
-
proxy-addr@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@@ -7169,15 +8670,11 @@ proxy-addr@~2.0.2:
forwarded "~0.1.2"
ipaddr.js "1.5.2"
-prr@~0.0.0:
- version "0.0.0"
- resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
-
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
-pseudomap@^1.0.2:
+pseudomap@^1.0.1, pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@@ -7191,14 +8688,14 @@ public-encrypt@^4.0.0:
parse-asn1 "^5.0.0"
randombytes "^2.0.1"
-pump@^1.0.0, pump@^1.0.1, pump@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51"
+pump@^1.0.0, pump@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
-pumpify@^1.3.3, pumpify@^1.3.4:
+pumpify@^1.3.3, pumpify@^1.3.4, pumpify@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b"
dependencies:
@@ -7210,7 +8707,7 @@ punycode@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-punycode@^1.3.2, punycode@^1.4.1:
+punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@@ -7218,6 +8715,10 @@ punycode@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
+q@^1.1.2:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
+
qjobs@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73"
@@ -7230,11 +8731,7 @@ qs@5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be"
-qs@6.5.0:
- version "6.5.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49"
-
-qs@6.5.1, qs@^6.0.2, qs@^6.2.0:
+qs@6.5.1, qs@^6.2.0, qs@^6.5.1, qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
@@ -7242,11 +8739,15 @@ qs@~2.2.3:
version "2.2.5"
resolved "https://registry.yarnpkg.com/qs/-/qs-2.2.5.tgz#1088abaf9dcc0ae5ae45b709e6c6b5888b23923c"
+qs@~6.3.0:
+ version "6.3.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c"
+
qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
-querystring-es3@~0.2.0:
+querystring-es3@^0.2.0, querystring-es3@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -7254,22 +8755,21 @@ querystring@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-qunit@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/qunit/-/qunit-1.0.0.tgz#1d3dcfbfaec81979cb4bdaee45450bb5e5914f8c"
- dependencies:
- argsparser "^0.0.7"
- cli-table "^0.3.0"
- co "^4.6.0"
- qunitjs "2.1.1"
- tracejs "^0.1.8"
- underscore "^1.6.0"
- optionalDependencies:
- istanbul "0.4.5"
+quick-lru@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8"
-qunitjs@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/qunitjs/-/qunitjs-2.1.1.tgz#c3087c864d9a9443103bdbdecc0ef359c7a82281"
+qunitjs@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/qunitjs/-/qunitjs-2.4.1.tgz#88aba055a9e2ec3dbebfaad02471b2cb002c530b"
+ dependencies:
+ chokidar "1.6.1"
+ commander "2.9.0"
+ exists-stat "1.0.0"
+ findup-sync "0.4.3"
+ js-reporters "1.2.0"
+ resolve "1.3.2"
+ walk-sync "0.3.1"
quote-stream@^1.0.1:
version "1.0.2"
@@ -7286,10 +8786,27 @@ quote-stream@~0.0.0:
minimist "0.0.8"
through2 "~0.4.1"
+raf@^3.1.0, raf@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
+ dependencies:
+ performance-now "^2.1.0"
+
+railroad-diagrams@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
+
ramda@^0.24.1:
version "0.24.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857"
+randexp@^0.4.2:
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
+ dependencies:
+ discontinuous-range "1.0.0"
+ ret "~0.1.10"
+
randomatic@^1.1.3:
version "1.1.7"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
@@ -7297,12 +8814,19 @@ randomatic@^1.1.3:
is-number "^3.0.0"
kind-of "^4.0.0"
-randombytes@^2.0.0, randombytes@^2.0.1:
+randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
dependencies:
safe-buffer "^5.1.0"
+randomfill@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62"
+ dependencies:
+ randombytes "^2.0.5"
+ safe-buffer "^5.1.0"
+
range-parser@^1.2.0, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
@@ -7330,9 +8854,9 @@ raw-body@~2.1.5:
iconv-lite "0.4.13"
unpipe "1.0.0"
-rc@^1.1.6, rc@^1.1.7:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95"
+rc@^1.1.7:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
@@ -7340,18 +8864,18 @@ rc@^1.1.6, rc@^1.1.7:
strip-json-comments "~2.0.1"
react-addons-css-transition-group@^15.6.0:
- version "15.6.0"
- resolved "https://registry.yarnpkg.com/react-addons-css-transition-group/-/react-addons-css-transition-group-15.6.0.tgz#69887cf6e4874d25cd66e22a699e29f0d648aba0"
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/react-addons-css-transition-group/-/react-addons-css-transition-group-15.6.2.tgz#9e4376bcf40b5217d14ec68553081cee4b08a6d6"
dependencies:
react-transition-group "^1.2.0"
react-addons-test-utils@^15.5.1:
- version "15.6.0"
- resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.6.0.tgz#062d36117fe8d18f3ba5e06eb33383b0b85ea5b9"
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.6.2.tgz#c12b6efdc2247c10da7b8770d185080a7b047156"
-react-dom@^15.0.2, react-dom@^15.5.4:
- version "15.6.1"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470"
+react-dom@^15.0.2, react-dom@^15.6.2:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.1.0"
@@ -7368,21 +8892,29 @@ react-hyperscript@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/react-hyperscript/-/react-hyperscript-3.0.0.tgz#3c16010b33175de6bc01fd1ebad0a16a9a6dc9ab"
-react-input-autosize@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.0.1.tgz#e92190497b4026c2780ad0f2fd703c835ba03e33"
+react-input-autosize@^2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.1.2.tgz#a3dc11a5517c434db25229925541309de3f7a8f5"
dependencies:
- create-react-class "^15.5.2"
prop-types "^15.5.8"
-react-markdown@^2.3.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-2.5.0.tgz#b1c61904fee5895886803bd9df7db23c3dc3a89e"
+react-markdown@^3.0.0:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.1.3.tgz#5ac1f20cb5a3e8c47b6ae3c8522e813b08f58c34"
dependencies:
- commonmark "^0.24.0"
- commonmark-react-renderer "^4.2.4"
- in-publish "^2.0.0"
- prop-types "^15.5.1"
+ prop-types "^15.6.0"
+ remark-parse "^4.0.0"
+ unified "^6.1.5"
+ unist-util-visit "^1.1.3"
+ xtend "^4.0.1"
+
+react-motion@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
+ dependencies:
+ performance-now "^0.2.0"
+ prop-types "^15.5.8"
+ raf "^3.1.0"
react-redux@^5.0.5:
version "5.0.6"
@@ -7395,41 +8927,68 @@ react-redux@^5.0.5:
loose-envify "^1.1.0"
prop-types "^15.5.10"
-react-select@^1.0.0-rc.2:
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.0.0-rc.10.tgz#f137346250f9255c979fbfa21860899928772350"
+react-select@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.1.0.tgz#626a2de839fdea2ade74dd1b143a9bde34be6c82"
dependencies:
classnames "^2.2.4"
prop-types "^15.5.8"
- react-input-autosize "^2.0.1"
+ react-input-autosize "^2.1.0"
react-simple-file-input@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/react-simple-file-input/-/react-simple-file-input-2.0.0.tgz#3686982ee26f50b22a69468e22aeeb2f392826c9"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/react-simple-file-input/-/react-simple-file-input-2.0.1.tgz#15ad4ffc78feb1b882649ad6b01c033ef27571e6"
dependencies:
prop-types "^15.5.7"
-react-test-renderer@^15.5.4:
- version "15.6.1"
- resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.6.1.tgz#026f4a5bb5552661fd2cc4bbcd0d4bc8a35ebf7e"
+react-test-renderer@^15.6.2:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.6.2.tgz#d0333434fc2c438092696ca770da5ed48037efa8"
dependencies:
fbjs "^0.8.9"
object-assign "^4.1.0"
react-testutils-additions@^15.2.0:
- version "15.2.0"
- resolved "https://registry.yarnpkg.com/react-testutils-additions/-/react-testutils-additions-15.2.0.tgz#7802a6f28dff9cfb673cbeaf32801cd6a054e6b7"
+ version "15.3.0"
+ resolved "https://registry.yarnpkg.com/react-testutils-additions/-/react-testutils-additions-15.3.0.tgz#0ee96a5998f54e2bda2cf0a3430a345df04b7f64"
dependencies:
object-assign "3.0.0"
sizzle "2.3.3"
+react-tippy@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/react-tippy/-/react-tippy-1.2.2.tgz#061467d34d29e7a5a9421822d125c451d6bb5153"
+ dependencies:
+ popper.js "^1.11.1"
+
+react-toggle-button@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/react-toggle-button/-/react-toggle-button-2.2.0.tgz#a1b92143aa0df414642fcb141f0879f545bc5a89"
+ dependencies:
+ prop-types "^15.6.0"
+ react-motion "^0.5.2"
+
+react-tools@~0.13.0:
+ version "0.13.3"
+ resolved "https://registry.yarnpkg.com/react-tools/-/react-tools-0.13.3.tgz#da6ac7d4d7777a59a5e951cf46e72fd4b6b40a2c"
+ dependencies:
+ commoner "^0.10.0"
+ jstransform "^10.1.0"
+
react-tooltip-component@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/react-tooltip-component/-/react-tooltip-component-0.3.0.tgz#fb3ec78c3270fe919692bc31f1404108bcf4785e"
+react-tooltip@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-3.4.0.tgz#037f38f797c3e6b1b58d2534ccc8c2c76af4f52d"
+ dependencies:
+ classnames "^2.2.5"
+ prop-types "^15.6.0"
+
react-transition-group@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.0.tgz#b51fc921b0c3835a7ef7c571c79fc82c73e9204f"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
dependencies:
chain-function "^1.0.0"
dom-helpers "^3.2.0"
@@ -7437,13 +8996,24 @@ react-transition-group@^1.2.0:
prop-types "^15.5.6"
warning "^3.0.0"
+react-transition-group@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
+ dependencies:
+ chain-function "^1.0.0"
+ classnames "^2.2.5"
+ dom-helpers "^3.2.0"
+ loose-envify "^1.3.1"
+ prop-types "^15.5.8"
+ warning "^3.0.0"
+
react-trigger-change@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-trigger-change/-/react-trigger-change-1.0.2.tgz#af573398ecef2475362b84f8c08c07fea23914c3"
-"react@>= 0.12.0 < 16.0.0", react@^15.0.2:
- version "15.6.1"
- resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
+"react@>= 0.12.0 < 16.0.0", react@^15.0.2, react@^15.6.2:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72"
dependencies:
create-react-class "^15.6.0"
fbjs "^0.8.9"
@@ -7451,6 +9021,19 @@ react-trigger-change@^1.0.2:
object-assign "^4.1.0"
prop-types "^15.5.10"
+reactify@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/reactify/-/reactify-1.1.1.tgz#a8f119596273c0d4bfb1abea0c14c2601ea03bba"
+ dependencies:
+ react-tools "~0.13.0"
+ through "~2.3.4"
+
+read-file-stdin@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/read-file-stdin/-/read-file-stdin-0.2.1.tgz#25eccff3a153b6809afacb23ee15387db9e0ee61"
+ dependencies:
+ gather-stream "^1.0.0"
+
read-only-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
@@ -7464,12 +9047,12 @@ read-pkg-up@^1.0.1:
find-up "^1.0.0"
read-pkg "^1.0.0"
-read-pkg-up@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
+read-pkg-up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
dependencies:
find-up "^2.0.0"
- read-pkg "^2.0.0"
+ read-pkg "^3.0.0"
read-pkg@^1.0.0:
version "1.1.0"
@@ -7479,13 +9062,13 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
-read-pkg@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
+read-pkg@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
dependencies:
- load-json-file "^2.0.0"
+ load-json-file "^4.0.0"
normalize-package-data "^2.3.2"
- path-type "^2.0.0"
+ path-type "^3.0.0"
read@1.0.x:
version "1.0.7"
@@ -7493,7 +9076,7 @@ read@1.0.x:
dependencies:
mute-stream "~0.0.4"
-"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.15, readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.26, readable-stream@~1.0.27-1:
+"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.15, readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.27-1:
version "1.0.34"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
dependencies:
@@ -7549,6 +9132,15 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
+recast@^0.11.17:
+ version "0.11.23"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
+ dependencies:
+ ast-types "0.9.6"
+ esprima "~3.1.0"
+ private "~0.1.5"
+ source-map "~0.5.0"
+
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@@ -7556,20 +9148,38 @@ rechoir@^0.6.2:
resolve "^1.1.6"
recompose@^0.25.0:
- version "0.25.0"
- resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.25.0.tgz#e2ec723692ff0fdab3d62bd22c1da69af1985acd"
+ version "0.25.1"
+ resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.25.1.tgz#5eb9d6cf6e25a9ffad73cbbae5658b5b55d6e728"
dependencies:
change-emitter "^0.1.2"
fbjs "^0.8.1"
- hoist-non-react-statics "^1.0.0"
+ hoist-non-react-statics "^2.3.1"
symbol-observable "^1.0.4"
+redent@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
+ dependencies:
+ indent-string "^2.1.0"
+ strip-indent "^1.0.1"
+
+redent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa"
+ dependencies:
+ indent-string "^3.0.0"
+ strip-indent "^2.0.0"
+
redux-logger@^3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf"
dependencies:
deep-diff "^0.3.5"
+redux-test-utils@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/redux-test-utils/-/redux-test-utils-0.1.3.tgz#0d89100f100f86c7c7214976eaece88e7e45bf74"
+
redux-thunk@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"
@@ -7592,8 +9202,8 @@ regenerator-runtime@^0.10.5:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
regenerator-runtime@^0.11.0:
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
regenerator-transform@^0.10.0:
version "0.10.1"
@@ -7609,6 +9219,12 @@ regex-cache@^0.4.2:
dependencies:
is-equal-shallow "^0.1.3"
+regex-not@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9"
+ dependencies:
+ extend-shallow "^2.0.1"
+
regexpu-core@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
@@ -7627,7 +9243,69 @@ regjsparser@^0.1.4:
dependencies:
jsesc "~0.5.0"
-remove-trailing-separator@^1.0.1:
+remark-parse@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-4.0.0.tgz#99f1f049afac80382366e2e0d0bd55429dd45d8b"
+ dependencies:
+ collapse-white-space "^1.0.2"
+ is-alphabetical "^1.0.0"
+ is-decimal "^1.0.0"
+ is-whitespace-character "^1.0.0"
+ is-word-character "^1.0.0"
+ markdown-escapes "^1.0.0"
+ parse-entities "^1.0.2"
+ repeat-string "^1.5.4"
+ state-toggle "^1.0.0"
+ trim "0.0.1"
+ trim-trailing-lines "^1.0.0"
+ unherit "^1.0.4"
+ unist-util-remove-position "^1.0.0"
+ vfile-location "^2.0.0"
+ xtend "^4.0.1"
+
+remark-stringify@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-4.0.0.tgz#4431884c0418f112da44991b4e356cfe37facd87"
+ dependencies:
+ ccount "^1.0.0"
+ is-alphanumeric "^1.0.0"
+ is-decimal "^1.0.0"
+ is-whitespace-character "^1.0.0"
+ longest-streak "^2.0.1"
+ markdown-escapes "^1.0.0"
+ markdown-table "^1.1.0"
+ mdast-util-compact "^1.0.0"
+ parse-entities "^1.0.2"
+ repeat-string "^1.5.4"
+ state-toggle "^1.0.0"
+ stringify-entities "^1.0.1"
+ unherit "^1.0.4"
+ xtend "^4.0.1"
+
+remark@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/remark/-/remark-8.0.0.tgz#287b6df2fe1190e263c1d15e486d3fa835594d6d"
+ dependencies:
+ remark-parse "^4.0.0"
+ remark-stringify "^4.0.0"
+ unified "^6.0.0"
+
+remove-bom-buffer@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53"
+ dependencies:
+ is-buffer "^1.1.5"
+ is-utf8 "^0.2.1"
+
+remove-bom-stream@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523"
+ dependencies:
+ remove-bom-buffer "^3.0.0"
+ safe-buffer "^5.1.0"
+ through2 "^2.0.3"
+
+remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -7639,7 +9317,7 @@ repeat-string@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae"
-repeat-string@^1.5.2:
+repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
@@ -7659,6 +9337,18 @@ replace-ext@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
+replace-ext@1.0.0, replace-ext@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
+
+replace-homedir@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c"
+ dependencies:
+ homedir-polyfill "^1.0.1"
+ is-absolute "^1.0.0"
+ remove-trailing-separator "^1.1.0"
+
replaceall@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/replaceall/-/replaceall-0.1.6.tgz#81d81ac7aeb72d7f5c4942adf2697a3220688d8e"
@@ -7678,12 +9368,12 @@ request-promise-core@1.1.1:
lodash "^4.13.1"
request-promise-native@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.4.tgz#86988ec8eee408e45579fce83bfd05b3adf9a155"
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
dependencies:
request-promise-core "1.1.1"
stealthy-require "^1.1.0"
- tough-cookie ">=2.3.0"
+ tough-cookie ">=2.3.3"
request-promise@^4.2.1:
version "4.2.2"
@@ -7694,7 +9384,34 @@ request-promise@^4.2.1:
stealthy-require "^1.1.0"
tough-cookie ">=2.3.3"
-request@^2.67.0, request@^2.79.0, request@^2.81.0:
+request@2, request@^2.67.0, request@^2.79.0, request@^2.83.0:
+ version "2.83.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
+ dependencies:
+ aws-sign2 "~0.7.0"
+ aws4 "^1.6.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.1"
+ forever-agent "~0.6.1"
+ form-data "~2.3.1"
+ har-validator "~5.0.3"
+ hawk "~6.0.2"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.17"
+ oauth-sign "~0.8.2"
+ performance-now "^2.1.0"
+ qs "~6.5.1"
+ safe-buffer "^5.1.1"
+ stringstream "~0.0.5"
+ tough-cookie "~2.3.3"
+ tunnel-agent "^0.6.0"
+ uuid "^3.1.0"
+
+request@2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies:
@@ -7721,6 +9438,31 @@ request@^2.67.0, request@^2.79.0, request@^2.81.0:
tunnel-agent "^0.6.0"
uuid "^3.0.0"
+request@~2.79.0:
+ version "2.79.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.11.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~2.0.6"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ qs "~6.3.0"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "~0.4.1"
+ uuid "^3.0.0"
+
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -7729,6 +9471,10 @@ require-from-string@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
+require-from-string@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"
+
require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
@@ -7751,6 +9497,13 @@ resolve-dir@^0.1.0:
expand-tilde "^1.2.2"
global-modules "^0.2.3"
+resolve-dir@^1.0.0, resolve-dir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
+ dependencies:
+ expand-tilde "^2.0.0"
+ global-modules "^1.0.0"
+
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
@@ -7759,19 +9512,45 @@ resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
-resolve-url@~0.2.1:
+resolve-from@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
+
+resolve-from@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
+
+resolve-options@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131"
+ dependencies:
+ value-or-function "^3.0.0"
+
+resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
-resolve@1.1.7, resolve@1.1.x, resolve@~1.1.6:
+resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
+resolve@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235"
+ dependencies:
+ path-parse "^1.0.5"
+
resolve@^0.6.1:
version "0.6.3"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46"
-resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@~1.4.0:
+resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
+ dependencies:
+ path-parse "^1.0.5"
+
+resolve@~1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86"
dependencies:
@@ -7794,6 +9573,10 @@ resumer@~0.0.0:
dependencies:
through "~2.3.4"
+ret@~0.1.10:
+ version "0.1.15"
+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
+
revalidator@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b"
@@ -7804,7 +9587,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1:
+rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@@ -7821,12 +9604,23 @@ rlp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0"
+rst-selector-parser@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
+ dependencies:
+ lodash.flattendeep "^4.4.0"
+ nearley "^2.7.10"
+
run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
dependencies:
is-promise "^2.1.0"
+rustbn.js@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.1.1.tgz#088b8c29d5f6d7d9f56ffb545f5d110e4a6801eb"
+
rx-lite-aggregates@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
@@ -7841,9 +9635,9 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
-samsam@1.x, samsam@^1.1.3:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67"
+samsam@1.x:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
sandwich-expando@^1.1.3:
version "1.1.3"
@@ -7855,6 +9649,15 @@ sandwich-expando@^1.1.3:
react-dom "^15.0.2"
react-hyperscript "^2.4.0"
+sass-graph@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49"
+ dependencies:
+ glob "^7.0.0"
+ lodash "^4.0.0"
+ scss-tokenizer "^0.2.3"
+ yargs "^7.0.0"
+
sax@^1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -7886,9 +9689,16 @@ scryptsy@^1.2.1:
dependencies:
pbkdf2 "^3.0.3"
+scss-tokenizer@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
+ dependencies:
+ js-base64 "^2.1.8"
+ source-map "^0.4.2"
+
secp256k1@^3.0.1:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.3.0.tgz#50ec9b201ba401403dd13ccbf21d31eeb3ff43cf"
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.4.0.tgz#1c905b256fa4ae5b9cc170e672dd59b4c5de46a4"
dependencies:
bindings "^1.2.1"
bip66 "^1.1.3"
@@ -7897,7 +9707,6 @@ secp256k1@^3.0.1:
drbg.js "^1.0.1"
elliptic "^6.2.3"
nan "^2.2.1"
- prebuild-install "^2.0.0"
safe-buffer "^5.1.0"
semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.0.5:
@@ -7910,7 +9719,7 @@ semver-greatest-satisfied-range@^1.0.0:
dependencies:
sver-compat "^1.5.0"
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@~5.4.1:
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@~5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
@@ -7918,23 +9727,9 @@ semver@~4.3.3:
version "4.3.6"
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
-send@0.15.4:
- version "0.15.4"
- resolved "https://registry.yarnpkg.com/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9"
- dependencies:
- debug "2.6.8"
- depd "~1.1.1"
- destroy "~1.0.4"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- etag "~1.8.0"
- fresh "0.5.0"
- http-errors "~1.6.2"
- mime "1.3.4"
- ms "2.0.0"
- on-finished "~2.3.0"
- range-parser "~1.2.0"
- statuses "~1.3.1"
+semver@~5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
send@0.16.1:
version "0.16.1"
@@ -7954,15 +9749,6 @@ send@0.16.1:
range-parser "~1.2.0"
statuses "~1.3.1"
-serve-static@1.12.4:
- version "1.12.4"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961"
- dependencies:
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- parseurl "~1.3.1"
- send "0.15.4"
-
serve-static@1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
@@ -7976,11 +9762,35 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+set-getter@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
+ dependencies:
+ to-object-path "^0.3.0"
+
set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
-setimmediate@^1.0.5:
+set-value@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-extendable "^0.1.1"
+ is-plain-object "^2.0.1"
+ to-object-path "^0.3.0"
+
+set-value@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274"
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-extendable "^0.1.1"
+ is-plain-object "^2.0.3"
+ split-string "^3.0.1"
+
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@@ -7993,10 +9803,11 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
- version "2.4.8"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f"
+ version "2.4.9"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
dependencies:
inherits "^2.0.1"
+ safe-buffer "^5.0.1"
sha3@^1.1.0:
version "1.2.0"
@@ -8004,7 +9815,7 @@ sha3@^1.1.0:
dependencies:
nan "^2.0.5"
-shallow-copy@~0.0.1:
+shallow-copy@0.0.1, shallow-copy@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170"
@@ -8038,32 +9849,25 @@ shellwords@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
+sigmund@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
+
signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
-simple-get@^1.4.2:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-1.4.3.tgz#e9755eda407e96da40c5e5158c9ea37b33becbeb"
- dependencies:
- once "^1.3.1"
- unzip-response "^1.0.0"
- xtend "^4.0.0"
-
sinon@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.0.0.tgz#a54a5f0237aa1dd2215e5e81c89b42b50c4fdb6b"
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.3.tgz#fc599eda47ed9f1a694ce774b94ab44260bd7ac5"
dependencies:
diff "^3.1.0"
formatio "1.2.0"
lodash.get "^4.4.2"
- lolex "^2.1.2"
- native-promise-only "^0.8.1"
- nise "^1.1.0"
- path-to-regexp "^1.7.0"
- samsam "^1.1.3"
- text-encoding "0.6.4"
- type-detect "^4.0.0"
+ lolex "^2.2.0"
+ nise "^1.2.0"
+ supports-color "^4.4.0"
+ type-detect "^4.0.5"
sizzle@2.3.3:
version "2.3.3"
@@ -8073,20 +9877,55 @@ slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
-slice-ansi@0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+slice-ansi@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
+ dependencies:
+ is-fullwidth-code-point "^2.0.0"
slide@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
+snapdragon-node@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
+ dependencies:
+ define-property "^1.0.0"
+ isobject "^3.0.0"
+ snapdragon-util "^3.0.1"
+
+snapdragon-util@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
+ dependencies:
+ kind-of "^3.2.0"
+
+snapdragon@^0.8.1:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370"
+ dependencies:
+ base "^0.11.1"
+ debug "^2.2.0"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ map-cache "^0.2.2"
+ source-map "^0.5.6"
+ source-map-resolve "^0.5.0"
+ use "^2.0.0"
+
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
dependencies:
hoek "2.x.x"
+sntp@2.x.x:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
+ dependencies:
+ hoek "4.x.x"
+
socket.io-adapter@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b"
@@ -8160,8 +9999,8 @@ socket.io@1.7.3:
socket.io-parser "2.3.1"
solc@^0.4.2:
- version "0.4.16"
- resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.16.tgz#809a5b1257c7c200e11a841b377eaec274698539"
+ version "0.4.19"
+ resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.19.tgz#1af1c4c292a0365a6977d4cbe3fbee7139b4b561"
dependencies:
fs-extra "^0.30.0"
memorystream "^0.3.1"
@@ -8169,6 +10008,10 @@ solc@^0.4.2:
semver "^5.3.0"
yargs "^4.7.1"
+source-list-map@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
+
source-map-resolve@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761"
@@ -8178,19 +10021,39 @@ source-map-resolve@^0.3.0:
source-map-url "~0.3.0"
urix "~0.1.0"
+source-map-resolve@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a"
+ dependencies:
+ atob "^2.0.0"
+ decode-uri-component "^0.2.0"
+ resolve-url "^0.2.1"
+ source-map-url "^0.4.0"
+ urix "^0.1.0"
+
source-map-support@^0.4.15:
version "0.4.18"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
dependencies:
source-map "^0.5.6"
+source-map-url@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
+
source-map-url@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9"
-source-map@0.X, "source-map@>= 0.1.2", source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6:
- version "0.5.7"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+source-map@0.1.31:
+ version "0.1.31"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.31.tgz#9f704d0d69d9e138a81badf6ebb4fde33d151c61"
+ dependencies:
+ amdefine ">=0.0.4"
+
+source-map@0.X, "source-map@>= 0.1.2", source-map@^0.6.1, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
source-map@^0.1.38, source-map@~0.1.33:
version "0.1.43"
@@ -8198,17 +10061,15 @@ source-map@^0.1.38, source-map@~0.1.33:
dependencies:
amdefine ">=0.0.4"
-source-map@^0.4.4:
+source-map@^0.4.2, source-map@^0.4.4, source-map@~0.4.0, source-map@~0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
dependencies:
amdefine ">=0.0.4"
-source-map@~0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
- dependencies:
- amdefine ">=0.0.4"
+source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
sparkles@^1.0.0:
version "1.0.0"
@@ -8218,16 +10079,16 @@ spawn-args@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb"
-spawn-wrap@^1.3.8:
- version "1.3.8"
- resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31"
+spawn-wrap@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c"
dependencies:
foreground-child "^1.5.6"
mkdirp "^0.5.0"
os-homedir "^1.0.1"
- rimraf "^2.3.3"
+ rimraf "^2.6.2"
signal-exit "^3.0.2"
- which "^1.2.4"
+ which "^1.3.0"
spdx-correct@~1.0.0:
version "1.0.2"
@@ -8243,6 +10104,22 @@ spdx-license-ids@^1.0.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
+specificity@^0.3.0, specificity@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.3.2.tgz#99e6511eceef0f8d9b57924937aac2cb13d13c42"
+
+split-string@^3.0.1, split-string@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
+ dependencies:
+ extend-shallow "^3.0.0"
+
+split2@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/split2/-/split2-0.2.1.tgz#02ddac9adc03ec0bb78c1282ec079ca6e85ae900"
+ dependencies:
+ through2 "~0.6.1"
+
split@0.3, split@~0.3.0:
version "0.3.3"
resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
@@ -8267,20 +10144,27 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
-stack-trace@0.0.9:
- version "0.0.9"
- resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
-
-stack-trace@0.0.x:
+stack-trace@0.0.10, stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
+state-toggle@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425"
+
static-eval@~0.2.0:
version "0.2.4"
resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b"
dependencies:
escodegen "~0.0.24"
+static-extend@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
+ dependencies:
+ define-property "^0.2.5"
+ object-copy "^0.1.0"
+
static-module@^1.1.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.5.0.tgz#27da9883c41a8cd09236f842f0c1ebc6edf63d86"
@@ -8297,15 +10181,29 @@ static-module@^1.1.0:
static-eval "~0.2.0"
through2 "~0.4.1"
-statuses@1, "statuses@>= 1.3.1 < 2", statuses@~1.3.1:
+statuses@1, "statuses@>= 1.3.1 < 2":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+
+statuses@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+stdin@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/stdin/-/stdin-0.0.1.tgz#d3041981aaec3dfdbc77a1b38d6372e38f5fb71e"
+
+stdout-stream@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b"
+ dependencies:
+ readable-stream "^2.0.1"
+
stealthy-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
-stream-browserify@^2.0.0:
+stream-browserify@^2.0.0, stream-browserify@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
dependencies:
@@ -8319,6 +10217,13 @@ stream-combiner2@^1.1.1:
duplexer2 "~0.1.0"
readable-stream "^2.0.2"
+stream-combiner@^0.2.1:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858"
+ dependencies:
+ duplexer "~0.1.1"
+ through "~2.3.4"
+
stream-combiner@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
@@ -8326,8 +10231,8 @@ stream-combiner@~0.0.4:
duplexer "~0.1.1"
stream-each@^1.1.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.0.tgz#1e95d47573f580d814dc0ff8cd0f66f1ce53c991"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd"
dependencies:
end-of-stream "^1.1.0"
stream-shift "^1.0.0"
@@ -8336,7 +10241,7 @@ stream-exhaust@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d"
-stream-http@^2.0.0:
+stream-http@^2.0.0, stream-http@^2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
dependencies:
@@ -8382,17 +10287,13 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
-string-width@^2.0.0, string-width@^2.1.0:
+string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
dependencies:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
-string.prototype.repeat@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf"
-
string.prototype.trim@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
@@ -8401,17 +10302,26 @@ string.prototype.trim@~1.1.2:
es-abstract "^1.5.0"
function-bind "^1.0.2"
+string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+ dependencies:
+ safe-buffer "~5.1.0"
+
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
-string_decoder@~1.0.0, string_decoder@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+stringify-entities@^1.0.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.1.tgz#b150ec2d72ac4c1b5f324b51fb6b28c9cdff058c"
dependencies:
- safe-buffer "~5.1.0"
+ character-entities-html4 "^1.0.0"
+ character-entities-legacy "^1.0.0"
+ is-alphanumerical "^1.0.0"
+ is-hexadecimal "^1.0.0"
-stringstream@~0.0.4:
+stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -8433,13 +10343,6 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
-strip-bom-stream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee"
- dependencies:
- first-chunk-stream "^1.0.0"
- strip-bom "^2.0.0"
-
strip-bom-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
@@ -8471,21 +10374,187 @@ strip-hex-prefix@1.0.0:
dependencies:
is-hex-prefixed "1.0.0"
+strip-indent@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
+ dependencies:
+ get-stdin "^4.0.1"
+
+strip-indent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
+
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+style-search@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902"
+
styled_string@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/styled_string/-/styled_string-0.0.1.tgz#d22782bd81295459bc4f1df18c4bad8e94dd124a"
+stylefmt@^5.0.4:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/stylefmt/-/stylefmt-5.3.2.tgz#32013437aa54d8c5253cbc107ac914dfb5ee9eea"
+ dependencies:
+ chalk "^1.1.3"
+ css-color-list "0.0.1"
+ diff "^3.1.0"
+ editorconfig "^0.13.2"
+ globby "^6.1.0"
+ minimist "^1.2.0"
+ postcss "^5.2.5"
+ postcss-scss "^0.4.0"
+ postcss-sorting "^2.0.1"
+ postcss-value-parser "^3.3.0"
+ stdin "0.0.1"
+ stylelint "^7.5.0"
+ stylelint-order "0.4.x"
+
+stylehacks@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-2.3.2.tgz#64c83e0438a68c9edf449e8c552a7d9ab6009b0b"
+ dependencies:
+ browserslist "^1.1.3"
+ chalk "^1.1.1"
+ log-symbols "^1.0.2"
+ minimist "^1.2.0"
+ plur "^2.1.2"
+ postcss "^5.0.18"
+ postcss-reporter "^1.3.3"
+ postcss-selector-parser "^2.0.0"
+ read-file-stdin "^0.2.1"
+ text-table "^0.2.0"
+ write-file-stdout "0.0.2"
+
+stylelint-config-recommended@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-1.0.0.tgz#752c17fc68fa64cd5e7589e24f6e46e77e14a735"
+
+stylelint-config-standard@^17.0.0:
+ version "17.0.0"
+ resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-17.0.0.tgz#42103a090054ee2a3dde9ecaed55e5d4d9d059fc"
+ dependencies:
+ stylelint-config-recommended "^1.0.0"
+
+stylelint-order@0.4.x:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-0.4.4.tgz#db7dfca0541b5062010c7e2e21e745791fc088ac"
+ dependencies:
+ lodash "^4.17.4"
+ postcss "^5.2.16"
+ stylelint "^7.9.0"
+
+stylelint@^7.5.0, stylelint@^7.9.0:
+ version "7.13.0"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-7.13.0.tgz#111f97b6da72e775c80800d6bb6f5f869997785d"
+ dependencies:
+ autoprefixer "^6.0.0"
+ balanced-match "^0.4.0"
+ chalk "^2.0.1"
+ colorguard "^1.2.0"
+ cosmiconfig "^2.1.1"
+ debug "^2.6.0"
+ doiuse "^2.4.1"
+ execall "^1.0.0"
+ file-entry-cache "^2.0.0"
+ get-stdin "^5.0.0"
+ globby "^6.0.0"
+ globjoin "^0.1.4"
+ html-tags "^2.0.0"
+ ignore "^3.2.0"
+ imurmurhash "^0.1.4"
+ known-css-properties "^0.2.0"
+ lodash "^4.17.4"
+ log-symbols "^1.0.2"
+ mathml-tag-names "^2.0.0"
+ meow "^3.3.0"
+ micromatch "^2.3.11"
+ normalize-selector "^0.2.0"
+ pify "^2.3.0"
+ postcss "^5.0.20"
+ postcss-less "^0.14.0"
+ postcss-media-query-parser "^0.2.0"
+ postcss-reporter "^3.0.0"
+ postcss-resolve-nested-selector "^0.1.1"
+ postcss-scss "^0.4.0"
+ postcss-selector-parser "^2.1.1"
+ postcss-value-parser "^3.1.1"
+ resolve-from "^3.0.0"
+ specificity "^0.3.0"
+ string-width "^2.0.0"
+ style-search "^0.1.0"
+ stylehacks "^2.3.2"
+ sugarss "^0.2.0"
+ svg-tags "^1.0.0"
+ table "^4.0.1"
+
+stylelint@^8.0.0:
+ version "8.4.0"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-8.4.0.tgz#c2dbaeb17236917819f9206e1c0df5fddf6f83c3"
+ dependencies:
+ autoprefixer "^7.1.2"
+ balanced-match "^1.0.0"
+ chalk "^2.0.1"
+ cosmiconfig "^3.1.0"
+ debug "^3.0.0"
+ execall "^1.0.0"
+ file-entry-cache "^2.0.0"
+ get-stdin "^5.0.1"
+ globby "^7.0.0"
+ globjoin "^0.1.4"
+ html-tags "^2.0.0"
+ ignore "^3.3.3"
+ imurmurhash "^0.1.4"
+ known-css-properties "^0.5.0"
+ lodash "^4.17.4"
+ log-symbols "^2.0.0"
+ mathml-tag-names "^2.0.1"
+ meow "^4.0.0"
+ micromatch "^2.3.11"
+ normalize-selector "^0.2.0"
+ pify "^3.0.0"
+ postcss "^6.0.6"
+ postcss-html "^0.12.0"
+ postcss-less "^1.1.0"
+ postcss-media-query-parser "^0.2.3"
+ postcss-reporter "^5.0.0"
+ postcss-resolve-nested-selector "^0.1.1"
+ postcss-safe-parser "^3.0.1"
+ postcss-sass "^0.2.0"
+ postcss-scss "^1.0.2"
+ postcss-selector-parser "^3.1.0"
+ postcss-value-parser "^3.3.0"
+ resolve-from "^4.0.0"
+ specificity "^0.3.1"
+ string-width "^2.1.0"
+ style-search "^0.1.0"
+ sugarss "^1.0.0"
+ svg-tags "^1.0.0"
+ table "^4.0.1"
+
subarg@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"
dependencies:
minimist "^1.1.0"
-supports-color@4.4.0, supports-color@^4.0.0:
+sugarss@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-0.2.0.tgz#ac34237563327c6ff897b64742bf6aec190ad39e"
+ dependencies:
+ postcss "^5.2.4"
+
+sugarss@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-1.0.1.tgz#be826d9003e0f247735f92365dc3fd7f1bae9e44"
+ dependencies:
+ postcss "^6.0.14"
+
+supports-color@4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
dependencies:
@@ -8499,12 +10568,18 @@ supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
-supports-color@^3.1.0, supports-color@^3.1.2:
+supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
dependencies:
has-flag "^1.0.0"
+supports-color@^4.0.0, supports-color@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
+ dependencies:
+ has-flag "^2.0.0"
+
sver-compat@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8"
@@ -8512,23 +10587,36 @@ sver-compat@^1.5.0:
es6-iterator "^2.0.1"
es6-symbol "^3.1.1"
+svg-tags@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
+
sw-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/sw-stream/-/sw-stream-2.0.0.tgz#628ebbeeb9eee0b66b03ec52fc55fcc4eeb23cf3"
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/sw-stream/-/sw-stream-2.0.2.tgz#68cd1ce959f3fe79b76f583f98c9172543880a0f"
dependencies:
+ babel-preset-es2015 "^6.22.0"
+ babel-runtime "^6.23.0"
+ babelify "^7.3.0"
end-of-stream "^1.1.0"
pump "^1.0.2"
readable-stream "^2.2.2"
through2 "^2.0.3"
symbol-observable@^1.0.3, symbol-observable@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
symbol-tree@^3.2.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
+synesthesia@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/synesthesia/-/synesthesia-1.0.1.tgz#5ef95ea548c0d5c6e6f9bb4b0d0731dff864a777"
+ dependencies:
+ css-color-names "0.0.3"
+
syntax-error@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.3.0.tgz#1ed9266c4d40be75dc55bf9bb1cb77062bb96ca1"
@@ -8536,15 +10624,15 @@ syntax-error@^1.1.1:
acorn "^4.0.3"
table@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
dependencies:
- ajv "^4.7.0"
- ajv-keywords "^1.0.0"
- chalk "^1.1.1"
- lodash "^4.0.0"
- slice-ansi "0.0.4"
- string-width "^2.0.0"
+ ajv "^5.2.3"
+ ajv-keywords "^2.1.0"
+ chalk "^2.1.0"
+ lodash "^4.17.4"
+ slice-ansi "1.0.0"
+ string-width "^2.1.1"
tap-parser@^5.1.0:
version "5.4.0"
@@ -8555,7 +10643,11 @@ tap-parser@^5.1.0:
optionalDependencies:
readable-stream "^2"
-tape@^4.4.0, tape@^4.5.1, tape@^4.6.0, tape@^4.6.2, tape@^4.6.3:
+tapable@^0.2.7, tapable@~0.2.5:
+ version "0.2.8"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
+
+tape@^4.4.0, tape@^4.5.1, tape@^4.6.0, tape@^4.6.2, tape@^4.6.3, tape@^4.8.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e"
dependencies:
@@ -8573,18 +10665,9 @@ tape@^4.4.0, tape@^4.5.1, tape@^4.6.0, tape@^4.6.2, tape@^4.6.3:
string.prototype.trim "~1.1.2"
through "~2.3.8"
-tar-fs@^1.13.0:
- version "1.15.3"
- resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.15.3.tgz#eccf935e941493d8151028e636e51ce4c3ca7f20"
- dependencies:
- chownr "^1.0.1"
- mkdirp "^0.5.1"
- pump "^1.0.0"
- tar-stream "^1.1.2"
-
tar-pack@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984"
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
dependencies:
debug "^2.2.0"
fstream "^1.0.10"
@@ -8595,16 +10678,7 @@ tar-pack@^3.4.0:
tar "^2.2.1"
uid-number "^0.0.6"
-tar-stream@^1.1.2:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016"
- dependencies:
- bl "^1.0.0"
- end-of-stream "^1.0.0"
- readable-stream "^2.0.0"
- xtend "^4.0.0"
-
-tar@^2.2.1:
+tar@^2.0.0, tar@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
dependencies:
@@ -8662,7 +10736,7 @@ testem@^1.10.3:
tap-parser "^5.1.0"
xmldom "^0.1.19"
-text-encoding@0.6.4, text-encoding@^0.6.4:
+text-encoding@^0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
@@ -8704,7 +10778,7 @@ through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3, through2@~2.0.0
readable-stream "^2.1.5"
xtend "~4.0.1"
-through2@^0.6.0, through2@^0.6.1, through2@^0.6.5:
+through2@^0.6.1, through2@^0.6.3, through2@^0.6.5, through2@~0.6.1:
version "0.6.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
dependencies:
@@ -8740,12 +10814,6 @@ through@~2.2.0:
version "2.2.7"
resolved "https://registry.yarnpkg.com/through/-/through-2.2.7.tgz#6e8e21200191d4eb6a99f6f010df46aa1c6eb2bd"
-tildify@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a"
- dependencies:
- os-homedir "^1.0.0"
-
time-stamp@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
@@ -8756,6 +10824,12 @@ timers-browserify@^1.0.1:
dependencies:
process "~0.11.0"
+timers-browserify@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
+ dependencies:
+ setimmediate "^1.0.4"
+
timers-ext@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204"
@@ -8763,23 +10837,24 @@ timers-ext@^0.1.2:
es5-ext "~0.10.14"
next-tick "1"
-tmp@0.0.31, tmp@^0.0.31:
+tmp@0.0.31:
version "0.0.31"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
dependencies:
os-tmpdir "~1.0.1"
-tmp@0.0.x:
+tmp@0.0.x, tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
dependencies:
os-tmpdir "~1.0.2"
-to-absolute-glob@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f"
+to-absolute-glob@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b"
dependencies:
- extend-shallow "^2.0.1"
+ is-absolute "^1.0.0"
+ is-negated-glob "^1.0.0"
to-array@0.1.4:
version "0.1.4"
@@ -8797,21 +10872,38 @@ to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
-to-utf8@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/to-utf8/-/to-utf8-0.0.1.tgz#d17aea72ff2fba39b9e43601be7b3ff72e089852"
+to-object-path@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
+ dependencies:
+ kind-of "^3.0.2"
+
+to-regex-range@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
+ dependencies:
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+
+to-regex@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae"
+ dependencies:
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ regex-not "^1.0.0"
+
+to-through@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6"
+ dependencies:
+ through2 "^2.0.3"
toggle-selection@^1.0.3:
version "1.0.6"
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
-tough-cookie@>=2.3.0, tough-cookie@^2.3.2, tough-cookie@~2.3.0:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
- dependencies:
- punycode "^1.4.1"
-
-tough-cookie@>=2.3.3:
+tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
@@ -8823,22 +10915,44 @@ tr46@^1.0.0:
dependencies:
punycode "^2.1.0"
-tracejs@^0.1.8:
- version "0.1.8"
- resolved "https://registry.yarnpkg.com/tracejs/-/tracejs-0.1.8.tgz#6c26787b1853f1371634622c1c80bc44026c5d70"
-
traverse@~0.6.3:
version "0.6.6"
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"
+treeify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.0.1.tgz#69b3cd022022a168424e7cfa1ced44c939d3eb2f"
+
+trim-newlines@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
+
+trim-newlines@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20"
+
trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+trim-trailing-lines@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz#7aefbb7808df9d669f6da2e438cac8c46ada7684"
+
trim@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
+trough@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.1.tgz#a9fd8b0394b0ae8fff82e0633a0a36ccad5b5f86"
+
+"true-case-path@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62"
+ dependencies:
+ glob "^6.0.4"
+
trumpet@^1.7.1:
version "1.7.2"
resolved "https://registry.yarnpkg.com/trumpet/-/trumpet-1.7.2.tgz#b02c69e465d171f55e44924bf9b5bdd20974c830"
@@ -8850,11 +10964,7 @@ trumpet@^1.7.1:
readable-stream "^1.0.27-1"
through2 "^1.0.0"
-tryit@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
-
-tty-browserify@~0.0.0:
+tty-browserify@0.0.0, tty-browserify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@@ -8864,6 +10974,10 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
+tunnel-agent@~0.4.1:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
+
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -8882,9 +10996,9 @@ type-detect@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
-type-detect@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea"
+type-detect@^4.0.0, type-detect@^4.0.5:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2"
type-is@~1.6.10, type-is@~1.6.15:
version "1.6.15"
@@ -8898,17 +11012,24 @@ typedarray@^0.0.6, typedarray@~0.0.5:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
ua-parser-js@^0.7.9:
- version "0.7.14"
- resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca"
+ version "0.7.17"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
uglify-es@^3.0.15:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.1.tgz#27615a1203cd0b351d8b5bda743ac92ed482b826"
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.3.tgz#095f5314d2a5d27e215390e50fa90751473dac2f"
dependencies:
- commander "~2.11.0"
- source-map "~0.5.1"
+ commander "~2.12.1"
+ source-map "~0.6.1"
-uglify-js@^2.6:
+uglify-es@^3.2.0:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.7.tgz#d1249af668666aba7cb1163e277455be9eb393cf"
+ dependencies:
+ commander "~2.13.0"
+ source-map "~0.6.1"
+
+uglify-js@^2.6, uglify-js@^2.8.27:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
dependencies:
@@ -8917,13 +11038,20 @@ uglify-js@^2.6:
optionalDependencies:
uglify-to-browserify "~1.0.0"
+uglify-js@^3.0.5:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.7.tgz#28463e7c7451f89061d2b235e30925bf5625e14d"
+ dependencies:
+ commander "~2.13.0"
+ source-map "~0.6.1"
+
uglify-to-browserify@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
uglifyify@^4.0.2:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/uglifyify/-/uglifyify-4.0.3.tgz#ff16ce11033faa54f782a050e0a77a55e7416724"
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/uglifyify/-/uglifyify-4.0.5.tgz#49c1fca9828c10a5a8e8d70f191a95f7ab475911"
dependencies:
convert-source-map "~1.1.0"
extend "^1.2.1"
@@ -8943,17 +11071,21 @@ umd@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
-unc-path-regex@^0.1.0:
+unc-path-regex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
-underscore@>=1.8.3, underscore@^1.6.0:
+underscore@>=1.8.3:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
+underscore@~1.4.4:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+
undertaker-registry@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.0.tgz#2da716c765999d8c94b9f9ed2c006df4923b052b"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"
undertaker@^1.0.0:
version "1.2.0"
@@ -8969,7 +11101,35 @@ undertaker@^1.0.0:
object.reduce "^1.0.0"
undertaker-registry "^1.0.0"
-uniq@^1.0.0:
+unherit@^1.0.4:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d"
+ dependencies:
+ inherits "^2.0.1"
+ xtend "^4.0.1"
+
+unified@^6.0.0, unified@^6.1.5:
+ version "6.1.6"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-6.1.6.tgz#5ea7f807a0898f1f8acdeefe5f25faa010cc42b1"
+ dependencies:
+ bail "^1.0.0"
+ extend "^3.0.0"
+ is-plain-obj "^1.1.0"
+ trough "^1.0.0"
+ vfile "^2.0.0"
+ x-is-function "^1.0.4"
+ x-is-string "^0.1.0"
+
+union-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
+ dependencies:
+ arr-union "^3.1.0"
+ get-value "^2.0.6"
+ is-extendable "^0.1.1"
+ set-value "^0.4.3"
+
+uniq@^1.0.0, uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
@@ -8980,6 +11140,38 @@ unique-stream@^2.0.2:
json-stable-stringify "^1.0.0"
through2-filter "^2.0.0"
+unist-util-find-all-after@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/unist-util-find-all-after/-/unist-util-find-all-after-1.0.1.tgz#4e5512abfef7e0616781aecf7b1ed751c00af908"
+ dependencies:
+ unist-util-is "^2.0.0"
+
+unist-util-is@^2.0.0, unist-util-is@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b"
+
+unist-util-modify-children@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz#66d7e6a449e6f67220b976ab3cb8b5ebac39e51d"
+ dependencies:
+ array-iterate "^1.0.0"
+
+unist-util-remove-position@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz#5a85c1555fc1ba0c101b86707d15e50fa4c871bb"
+ dependencies:
+ unist-util-visit "^1.1.0"
+
+unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c"
+
+unist-util-visit@^1.1.0, unist-util-visit@^1.1.3:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444"
+ dependencies:
+ unist-util-is "^2.1.1"
+
unorm@^1.3.3:
version "1.4.1"
resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300"
@@ -8988,24 +11180,31 @@ unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
-unzip-response@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe"
+unset-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
+ dependencies:
+ has-value "^0.3.1"
+ isobject "^3.0.0"
urix@^0.1.0, urix@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
-url@~0.11.0:
+url@^0.11.0, url@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
dependencies:
punycode "1.3.2"
querystring "0.2.0"
-user-home@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
+use@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8"
+ dependencies:
+ define-property "^0.2.5"
+ isobject "^3.0.0"
+ lazy-cache "^2.0.2"
useragent@^2.1.12:
version "2.2.1"
@@ -9022,7 +11221,7 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-util@0.10.3, util@~0.10.1:
+util@0.10.3, util@^0.10.3, util@~0.10.1:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
dependencies:
@@ -9039,10 +11238,6 @@ utile@0.3.x:
ncp "1.0.x"
rimraf "2.x.x"
-utils-merge@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
-
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@@ -9051,19 +11246,15 @@ uuid@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
-uuid@^3.0.0, uuid@^3.0.1:
+uuid@^3.0.0, uuid@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
-v8flags@^2.0.9:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
+v8flags@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b"
dependencies:
- user-home "^1.1.1"
-
-vali-date@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6"
+ homedir-polyfill "^1.0.1"
valid-url@^1.0.9:
version "1.0.9"
@@ -9076,14 +11267,14 @@ validate-npm-package-license@^3.0.1:
spdx-correct "~1.0.0"
spdx-expression-parse "~1.0.0"
+value-or-function@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"
+
varint@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/varint/-/varint-4.0.1.tgz#490829b942d248463b2b35097995c3bf737198e9"
-vary@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"
-
vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@@ -9096,12 +11287,31 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
-vinyl-buffer@^1.0.0:
+vfile-location@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.2.tgz#d3675c59c877498e492b4756ff65e4af1a752255"
+
+vfile-message@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/vinyl-buffer/-/vinyl-buffer-1.0.0.tgz#ca067ea08431d507722b1de5083f602616ebc234"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359"
dependencies:
- bl "^0.9.1"
- through2 "^0.6.1"
+ unist-util-stringify-position "^1.1.1"
+
+vfile@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
+ dependencies:
+ is-buffer "^1.1.4"
+ replace-ext "1.0.0"
+ unist-util-stringify-position "^1.0.0"
+ vfile-message "^1.0.0"
+
+vinyl-buffer@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz#96c1a3479b8c5392542c612029013b5b27f88bbf"
+ dependencies:
+ bl "^1.2.1"
+ through2 "^2.0.3"
vinyl-file@^2.0.0:
version "2.0.0"
@@ -9114,49 +11324,52 @@ vinyl-file@^2.0.0:
strip-bom-stream "^2.0.0"
vinyl "^1.1.0"
-vinyl-fs@^2.0.0:
- version "2.4.4"
- resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239"
+vinyl-fs@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.1.tgz#74af5f6836a1cf414d35eeb3c10f2e65fc2a2c10"
dependencies:
- duplexify "^3.2.0"
- glob-stream "^5.3.2"
+ flush-write-stream "^1.0.0"
+ fs-mkdirp-stream "^1.0.0"
+ glob-stream "^6.1.0"
graceful-fs "^4.0.0"
- gulp-sourcemaps "1.6.0"
- is-valid-glob "^0.3.0"
+ is-valid-glob "^1.0.0"
lazystream "^1.0.0"
- lodash.isequal "^4.0.0"
- merge-stream "^1.0.0"
- mkdirp "^0.5.0"
- object-assign "^4.0.0"
- readable-stream "^2.0.4"
- strip-bom "^2.0.0"
- strip-bom-stream "^1.0.0"
+ lead "^1.0.0"
+ object.assign "^4.0.4"
+ pumpify "^1.3.5"
+ remove-bom-buffer "^3.0.0"
+ remove-bom-stream "^1.2.0"
+ resolve-options "^1.1.0"
through2 "^2.0.0"
- through2-filter "^2.0.0"
- vali-date "^1.0.0"
- vinyl "^1.0.0"
+ to-through "^2.0.0"
+ value-or-function "^3.0.0"
+ vinyl "^2.0.0"
+ vinyl-sourcemap "^1.1.0"
-vinyl-source-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz#44cbe5108205279deb0c5653c094a2887938b1ab"
+vinyl-source-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz#f38a5afb9dd1e93b65d550469ac6182ac4f54b8e"
dependencies:
- through2 "^0.6.1"
- vinyl "^0.4.3"
+ through2 "^2.0.3"
+ vinyl "^2.1.0"
-vinyl@1.X, vinyl@^1.0.0, vinyl@^1.1.0, vinyl@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+vinyl-sourcemap@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16"
dependencies:
- clone "^1.0.0"
- clone-stats "^0.0.1"
- replace-ext "0.0.1"
+ append-buffer "^1.0.2"
+ convert-source-map "^1.5.0"
+ graceful-fs "^4.1.6"
+ normalize-path "^2.1.1"
+ now-and-later "^2.0.0"
+ remove-bom-buffer "^3.0.0"
+ vinyl "^2.0.0"
-vinyl@^0.4.3:
- version "0.4.6"
- resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847"
+vinyl-sourcemaps-apply@^0.2.0, vinyl-sourcemaps-apply@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705"
dependencies:
- clone "^0.2.0"
- clone-stats "^0.0.1"
+ source-map "^0.5.1"
vinyl@^0.5.0:
version "0.5.3"
@@ -9166,7 +11379,26 @@ vinyl@^0.5.0:
clone-stats "^0.0.1"
replace-ext "0.0.1"
-vm-browserify@~0.0.1:
+vinyl@^1.1.0, vinyl@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+vinyl@^2.0.0, vinyl@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c"
+ dependencies:
+ clone "^2.1.1"
+ clone-buffer "^1.0.0"
+ clone-stats "^1.0.0"
+ cloneable-readable "^1.0.0"
+ remove-trailing-separator "^1.0.1"
+ replace-ext "^1.0.0"
+
+vm-browserify@0.0.4, vm-browserify@~0.0.1:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
dependencies:
@@ -9180,6 +11412,13 @@ vreme@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/vreme/-/vreme-3.0.2.tgz#4721376b449457fefde8a849d3340933b90b5686"
+walk-sync@0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465"
+ dependencies:
+ ensure-posix-path "^1.0.0"
+ matcher-collection "^1.0.0"
+
warning@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
@@ -9198,6 +11437,14 @@ watchify@^3.9.0:
through2 "^2.0.0"
xtend "^4.0.0"
+watchpack@^1.3.1:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
+ dependencies:
+ async "^2.1.2"
+ chokidar "^1.7.0"
+ graceful-fs "^4.1.2"
+
weak@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/weak/-/weak-1.0.1.tgz#ab99aab30706959aa0200cb8cf545bb9cb33b99e"
@@ -9206,8 +11453,32 @@ weak@^1.0.0:
nan "^2.0.5"
web3-provider-engine@^13.3.2:
- version "13.3.2"
- resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.3.2.tgz#a5954aa637f96f0dde5131bc20a6ce9e33e6fcd1"
+ version "13.4.0"
+ resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.4.0.tgz#78c2794ba926d0c5b94c6e8955abb994bb8e8854"
+ dependencies:
+ async "^2.5.0"
+ clone "^2.0.0"
+ eth-block-tracker "^2.2.2"
+ eth-sig-util "^1.3.0"
+ ethereumjs-block "^1.2.2"
+ ethereumjs-tx "^1.2.0"
+ ethereumjs-util "^5.1.1"
+ ethereumjs-vm "^2.0.2"
+ fetch-ponyfill "^4.0.0"
+ json-rpc-error "^2.0.0"
+ json-stable-stringify "^1.0.1"
+ promise-to-callback "^1.0.0"
+ readable-stream "^2.2.9"
+ request "^2.67.0"
+ semaphore "^1.0.3"
+ solc "^0.4.2"
+ tape "^4.4.0"
+ xhr "^2.2.0"
+ xtend "^4.0.1"
+
+web3-provider-engine@^13.5.6:
+ version "13.6.0"
+ resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.6.0.tgz#836f51c4ee48bd7583acf3696033779c704c2214"
dependencies:
async "^2.5.0"
clone "^2.0.0"
@@ -9235,9 +11506,19 @@ web3-stream-provider@^3.0.1:
dependencies:
readable-stream "^2.0.5"
+web3@^0.18.4:
+ version "0.18.4"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d"
+ dependencies:
+ bignumber.js "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2"
+ crypto-js "^3.1.4"
+ utf8 "^2.1.1"
+ xhr2 "*"
+ xmlhttprequest "*"
+
web3@^0.20.1:
- version "0.20.2"
- resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.2.tgz#c54dac5fc0e377399c04c1a6ecbb12e4513278d6"
+ version "0.20.3"
+ resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.3.tgz#caa44373dc8815ac8767bddb6ba73073964caa8b"
dependencies:
bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
crypto-js "^3.1.4"
@@ -9245,10 +11526,43 @@ web3@^0.20.1:
xhr2 "*"
xmlhttprequest "*"
-webidl-conversions@^4.0.0, webidl-conversions@^4.0.1:
+webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+webpack-sources@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
+ dependencies:
+ source-list-map "^2.0.0"
+ source-map "~0.6.1"
+
+webpack@^2.2.1:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.7.0.tgz#b2a1226804373ffd3d03ea9c6bd525067034f6b1"
+ dependencies:
+ acorn "^5.0.0"
+ acorn-dynamic-import "^2.0.0"
+ ajv "^4.7.0"
+ ajv-keywords "^1.1.1"
+ async "^2.1.2"
+ enhanced-resolve "^3.3.0"
+ interpret "^1.0.0"
+ json-loader "^0.5.4"
+ json5 "^0.5.1"
+ loader-runner "^2.3.0"
+ loader-utils "^0.2.16"
+ memory-fs "~0.4.1"
+ mkdirp "~0.5.0"
+ node-libs-browser "^2.0.0"
+ source-map "^0.5.3"
+ supports-color "^3.1.0"
+ tapable "~0.2.5"
+ uglify-js "^2.8.27"
+ watchpack "^1.3.1"
+ webpack-sources "^1.0.1"
+ yargs "^6.0.0"
+
websocket-driver@>=0.3.6:
version "0.7.0"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"
@@ -9257,22 +11571,22 @@ websocket-driver@>=0.3.6:
websocket-extensions ">=0.1.1"
websocket-extensions@>=0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d"
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
whatwg-encoding@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz#3c6c451a198ee7aec55b1ec61d0920c67801a5f4"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3"
dependencies:
- iconv-lite "0.4.13"
+ iconv-lite "0.4.19"
whatwg-fetch@>=0.10.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
-whatwg-url@^6.1.0:
- version "6.2.1"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.2.1.tgz#db8fb96d7f02661af266e3cefc18425923900a00"
+whatwg-url@^6.3.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08"
dependencies:
lodash.sortby "^4.7.0"
tr46 "^1.0.0"
@@ -9286,7 +11600,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@^1.0.5, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.4, which@^1.2.9:
+which@1, which@^1.0.5, which@^1.2.1, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
@@ -9330,14 +11644,14 @@ wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
-wordwrap@^1.0.0, wordwrap@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
-
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
+wordwrap@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
@@ -9349,13 +11663,6 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-wreck@^6.3.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/wreck/-/wreck-6.3.0.tgz#a1369769f07bbb62d6a378336a7871fc773c740b"
- dependencies:
- boom "2.x.x"
- hoek "2.x.x"
-
write-file-atomic@^1.1.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
@@ -9364,6 +11671,10 @@ write-file-atomic@^1.1.4:
imurmurhash "^0.1.4"
slide "^1.1.5"
+write-file-stdout@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/write-file-stdout/-/write-file-stdout-0.0.2.tgz#c252d7c7c5b1b402897630e3453c7bfe690d9ca1"
+
write@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
@@ -9388,6 +11699,14 @@ wtf-8@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"
+x-is-function@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e"
+
+x-is-string@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
+
xhr2@*:
version "0.1.4"
resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f"
@@ -9397,8 +11716,8 @@ xhr2@0.1.3:
resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.3.tgz#cbfc4759a69b4a888e78cf4f20b051038757bd11"
xhr@^2.2.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.0.tgz#e16e66a45f869861eeefab416d5eff722dc40993"
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.1.tgz#ba982cced205ae5eec387169ac9dc77ca4853d38"
dependencies:
global "~4.3.0"
is-function "^1.0.1"
@@ -9421,11 +11740,7 @@ xmlhttprequest@*:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
-xss-filters@^1.2.6:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a"
-
-xtend@4.0.1, "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
+"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
@@ -9466,13 +11781,34 @@ yargs-parser@^5.0.0:
dependencies:
camelcase "^3.0.0"
-yargs-parser@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
+yargs-parser@^8.0.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
dependencies:
camelcase "^4.1.0"
-yargs@^3.28.0:
+yargs@^1.2.6:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a"
+
+yargs@^10.0.3:
+ version "10.0.3"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"
+ dependencies:
+ cliui "^3.2.0"
+ decamelize "^1.1.1"
+ find-up "^2.1.0"
+ get-caller-file "^1.0.1"
+ os-locale "^2.0.0"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^2.0.0"
+ which-module "^2.0.0"
+ y18n "^3.2.1"
+ yargs-parser "^8.0.0"
+
+yargs@^3.5.4:
version "3.32.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
dependencies:
@@ -9503,7 +11839,7 @@ yargs@^4.7.1:
y18n "^3.2.1"
yargs-parser "^2.4.1"
-yargs@^6.5.0:
+yargs@^6.0.0, yargs@^6.5.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
dependencies:
@@ -9521,23 +11857,23 @@ yargs@^6.5.0:
y18n "^3.2.1"
yargs-parser "^4.2.0"
-yargs@^8.0.1:
- version "8.0.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
+yargs@^7.0.0, yargs@^7.1.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
dependencies:
- camelcase "^4.1.0"
+ camelcase "^3.0.0"
cliui "^3.2.0"
decamelize "^1.1.1"
get-caller-file "^1.0.1"
- os-locale "^2.0.0"
- read-pkg-up "^2.0.0"
+ os-locale "^1.4.0"
+ read-pkg-up "^1.0.1"
require-directory "^2.1.1"
require-main-filename "^1.0.1"
set-blocking "^2.0.0"
- string-width "^2.0.0"
- which-module "^2.0.0"
+ string-width "^1.0.2"
+ which-module "^1.0.0"
y18n "^3.2.1"
- yargs-parser "^7.0.0"
+ yargs-parser "^5.0.0"
yargs@~1.2.6:
version "1.2.6"
@@ -9555,8 +11891,8 @@ yargs@~3.10.0:
window-size "0.1.0"
yazl@^2.1.0:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.2.tgz#14cb19083e1e25a70092c1588aabe0f4e4dd4d88"
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.3.tgz#ec26e5cc87d5601b9df8432dbdd3cd2e5173a071"
dependencies:
buffer-crc32 "~0.2.3"