From 5aa42e69cd5560a2caef3b503171872a35a9180b Mon Sep 17 00:00:00 2001 From: Ev Date: Wed, 1 Feb 2017 20:18:01 -0200 Subject: [PATCH] Merge develop into master for v0.8.9 (#1632) * updated solc again * updated solc to 0.4.6 * Update geth to 1.5.5 (#1520) * Update geth to 1.5.5 * corrected windows zip's internal paths * changed sanity check * made node starting better * also log path from which to fetch * show fetching origin URL * fix ESLint errors * removed -stable * fixes the immediate startup issue (#1540) * fixes #1532 (#1534) * [ESLint] autofix 'modules' (#1536) * [ESLint] update customProtocols.js (#1538) * added postinstall step for interface dir (#1546) * [ESLint] update 'scripts' (#1539) * [ESLint] update 'scripts' * add comments to .eslintrc * update paths * update comments * Adding badges for (up|out)dated dependencies (#1525) * Changes to splash screen and onboarding (#1545) * change fast to light * light client * remove '--cache' flag * remove cache * text changes` * changes to onboarding screen * changes to onboarding * ropstein in eth * experimental label` * checking network label position * Theres no I in Ropsten * changes algotithm for displaying * allows app to be ready if no sync is happening * bring changes to splash screen * remove changes from ethereumNode * remove changes from menuItems * speed changes * clean up and add comments * fixes onboarding shapeshift window loading * simplify code * add comments * shows ready to launch when there are less than a 100 blocks * Error pages (#1559) * added not found and crash error page * add source sans * [readme] minor typo * [mistAPI] add 'mist.solidity.version' (#1586) * add 'mist.solidity.version' to mistAPI * Adding tests for in Mist API * fixes (#1600) * add hash and queries to breadcrumb (#1596) * fix offline-startup edge-case (#1571) * NSIS installer (#1499) * Update travis config to new format * fixes * install gulp * fixes * tweaks * use same install & script tasks for all builds * Expand build matrix * tweaks * fixes * try to fix wine installation * Enable mac build * Extend run time to 30 minutes * see if extra dependencies resolves build issue for linwin * Install yarn with npm on osx * linux and windows in one * Add gulp to Mac * Bump timeout to 60 minutes * remove download-signatures from processing / travis tweaks * cleanup * enable gitter notifications * fix bash double ampersand * try to build nsis script * fix nsis verbosity flag * Customized NSIS installer * Fix order of commands * Improve uninstaller * Add logic and movefile plugins * Enable separate DATADIR location * Remove INSTDIR and replace with FILEDIR * Fix compiler warnings about unknown variables * Enforce UAC admin requirement * Move NSI to scripts directory and add plugins * Include version in output filename * Remove duplicate execution level command * Move files from nested folder into main folder * Update shortcut names and params * initial architecture detection + various cleanup * More flexible environment vars * Cleanup * User-selectable location for Mist's data files * Include icon in installation directory * Cleanup * Improve/fix registry entries * Show shortcuts after successful installation * Estimate installation size * Fix removal of start menu shortcuts * Open DATADIR and NODEDATADIR on uninstallation * Handle firewall rules * Disable firewall updates * Include multiple architectures into single installer * Don't allow user to select Mist data directory * Integrate NSIS build into Gulp * Cleanup lint suggestions * Cleanup more lint suggestions * One more linter fix * Remove testnet startmenu entry * Double the estimated installed size * Create desktop shortcut * Delete temporary zips * Store user settings in HKCU for uninstallation * Remove user registry settings on uninstallation * Improved uninstallation to not rely on stack variables * Compute actual program directory size * Cleanup * [travis] various fixes (#1601) * various fixes * disable code-signing on 'develop' * fix yarn on xcode8 image * rectify if statement * comments * improvement * Adjust formatter for addPeer #1543 (#1599) * recreate PR * add fixes * fix [null] * [gulp] new task 'upload-binaries' (to github) (#1578) * add gulp-task 'upload-binaries' * fix ESLint errors * improvements and fixes * switch URLs to ethereum/mist repo * also build wallet if on master branch * make sure all sendTransaction is valid HEX (#1606) * Adding a develop menu option to open Remix IDE (#1608) * Adding browser solidity menu item * Adding i18n keys for Remix menu item * Moving Remix menu option UP * Opening Remix on a separated popup * Changing display name * minor refactor * reverting travis change * Update app.nl.i18n.json (#1609) Dutch translation * adjust content order, feather and window size (#1585) * fix mention-bot (#1587) * Improve importer (#1598) * rename 'presaleFile' IPC actions to generic 'walletFile' * update the import-screen depending on wallet type * leverage ethereum-keyfile-recognizer * update yarn.lock * fix merge relic * [ESLint] * polish * update dependency and fix ESLint * improvements * update menu-label * Dutch translation improved (#1610) * Update mist.nl.i18n.json Dutch translations * Corrected proposed changes for Dutch translations. Capital "E"ther and changed from formal to informal throughout the file. * change window height (#1612) * Allow for operators while parsing 'mist.solidity.version' (#1613) * Allow for operators while parsing 'mist.solidity.version' * minor improvement in regex * Sync Dutch translation file to English + corrections (#1616) * Sync Dutch translations to English + corrections Mostly rearranged the lines to get equal to the English translation file for easier future maintenance. Also did some small spelling corrections and improved a few translations when I matched the Dutch and English files. * Fixed JSON syntax Fixed JSON syntax * Processed suggestions, many thanks! * update i18n files according to english base files (#1618) * [travis] don't wait for mac build on PR check (#1611) * 36 * 37 * [gulp] don't build NSIS installer on 'wallet' task (#1614) * don't build NSIS installer in 'wallet' task * [readme] add 'makensis' to brew install * Bump version string to 0.8.9 (#1626) * Spectron testing suite (#1553) * Spectron iteration * Updating spectron * Creating switch for mist.lokidb for automated tests * Adding chai-as-expected * Changing IPC flag * Pairing spectron and electron versions * [ESLint] Minor fixes * Adding chai-string * Couple of tests passing * update .eslintrc.yml * Simplifying code * Removing delay in favor of better window management * Adding tests for URL bar * Focusing window before each test * Minor fixes * Improving mist setup and teardown * Fixing wallet test * adding html fixture * Improving test helpers * Tests for ETH-01-002 * Updating tests * Starting local HTTP server to deal with html fixtures * Updating tests setup * Adding more tests * Updating travis file to run spectron tests * Refactoring tests * Tests for ETH-01-007 * Downloading geth on the fly * Fine-tuning geth download during tests * Changing linux binary dir * Fixing binary path on linux * Travis debug * Travis debug * Changing fixtures * Fixing tests * Fixing travis file * More tests * Adjusting timeouts * Adjusting GULP_PLATFORM test env variable * Adjusting timeouts * Disabling some tests for now * Disabling a test * Fix raw data display ('0x') in data-less TXs (#1625) * Update dependencies (#1623) * Update dependencies * Updating yarn lock * udpate (#1622) * Cleaner mocha-in-browser test results (#1630) * Removing DavidDM broken badges (#1631) * Update geth to 1.5.5 (#1520) (#1522) (#1633) * updated solc again * updated solc to 0.4.6 * Update geth to 1.5.5 (#1520) * Update geth to 1.5.5 * corrected windows zip's internal paths * changed sanity check * made node starting better * also log path from which to fetch * show fetching origin URL * fix ESLint errors * removed -stable --- .eslintrc.yml | 9 +- .mention-bot | 1 + .travis.yml | 101 +- README.md | 12 +- customProtocols.js | 9 +- errorPages/400.html | 2 +- errorPages/404.html | 19 + errorPages/500.html | 19 + gulpfile.js | 122 +- interface/client/collections.js | 1 - .../client/lib/helpers/helperFunctions.js | 7 +- interface/client/lib/signatures.js | 173 ++- .../styles/networkIndicator.import.less | 8 +- .../client/styles/popupWindows.import.less | 16 +- .../popupWindows/onboardingScreen.html | 73 +- .../popupWindows/onboardingScreen.js | 137 ++- .../sendTransactionConfirmation.html | 81 +- .../sendTransactionConfirmation.js | 17 +- .../templates/popupWindows/splashScreen.js | 9 +- interface/client/templates/views/webview.js | 10 +- interface/client/templates/webviewEvents.js | 27 + interface/i18n/app.nl.i18n.json | 4 +- interface/i18n/mist.de.i18n.json | 17 +- interface/i18n/mist.en.i18n.json | 14 +- interface/i18n/mist.es.i18n.json | 15 +- interface/i18n/mist.fa.i18n.json | 15 +- interface/i18n/mist.fr.i18n.json | 15 +- interface/i18n/mist.it.i18n.json | 15 +- interface/i18n/mist.ja.i18n.json | 15 +- interface/i18n/mist.ko.i18n.json | 15 +- interface/i18n/mist.kr.i18n.json | 13 +- interface/i18n/mist.nb.i18n.json | 15 +- interface/i18n/mist.nl.i18n.json | 245 ++-- interface/i18n/mist.pt.i18n.json | 15 +- interface/i18n/mist.ru.i18n.json | 31 +- interface/i18n/mist.sq.i18n.json | 13 +- interface/i18n/mist.zh-TW.i18n.json | 15 +- interface/i18n/mist.zh.i18n.json | 15 +- main.js | 7 +- modules/clientBinaryManager.js | 6 +- modules/db.js | 3 +- modules/dbSync.js | 36 +- modules/ethereumNode.js | 9 +- modules/ipc/dechunker.js | 5 +- modules/ipc/ipcProviderBackend.js | 16 +- modules/ipc/methods/eth_sendTransaction.js | 11 +- modules/ipcCommunicator.js | 97 +- modules/menuItems.js | 40 +- modules/nodeSync.js | 2 +- modules/preloader/browser.js | 2 +- modules/preloader/include/getFavicon.js | 9 +- modules/preloader/include/getMetaTags.js | 11 +- modules/preloader/include/mistAPI.js | 5 +- modules/preloader/include/openExternal.js | 9 +- modules/preloader/include/openPopup.js | 11 +- modules/preloader/mistUI.js | 50 +- modules/preloader/walletMain.js | 5 +- modules/settings.js | 5 + modules/web3Admin.js | 7 +- package.json | 59 +- scripts/Locate.nsh | 51 + scripts/MoveFileFolder.nsh | 256 ++++ scripts/SimpleFC.dll | Bin 0 -> 179712 bytes scripts/ZipDLL.dll | Bin 0 -> 167424 bytes scripts/locate.dll | Bin 0 -> 17920 bytes scripts/windows-installer.nsi | 269 +++++ scripts/zipdll.nsh | 417 +++++++ tests/_base.js | 277 +++-- tests/fixtures/fixture-popup.html | 10 + tests/fixtures/index.html | 11 + tests/fixtures/page-01.html | 8 + tests/mist/basic.test.js | 230 ++++ tests/mocha-in-browser/spec/general-spec.js | 11 +- tests/wallet/basic.test.js | 13 +- yarn.lock | 1063 ++++++----------- 75 files changed, 3038 insertions(+), 1323 deletions(-) create mode 100644 errorPages/404.html create mode 100644 errorPages/500.html create mode 100755 scripts/Locate.nsh create mode 100644 scripts/MoveFileFolder.nsh create mode 100755 scripts/SimpleFC.dll create mode 100755 scripts/ZipDLL.dll create mode 100755 scripts/locate.dll create mode 100644 scripts/windows-installer.nsi create mode 100755 scripts/zipdll.nsh create mode 100644 tests/fixtures/fixture-popup.html create mode 100644 tests/fixtures/index.html create mode 100644 tests/fixtures/page-01.html create mode 100644 tests/mist/basic.test.js diff --git a/.eslintrc.yml b/.eslintrc.yml index b0d68de7d..59576da16 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -7,7 +7,6 @@ settings: import/core-modules: ## don't lint for these missing packages in package.json - electron ## 'electron' is only needed as devDependency / global installation - rules: # "off" or 0 - turn the rule off # "warn" or 1 - turn the rule on as a warning (doesn’t affect exit code) @@ -22,7 +21,13 @@ rules: no-underscore-dangle: off comma-dangle: - error - - only-multiline + - only-multiline ## no comma after last item if one line, though allow comma if multiline + import/no-extraneous-dependencies: ## checks if required modules are missing in packages.json + - error + - devDependencies: ## declares files, whose imports belong to devDependencies + - "**/scripts/build-dist.js" + - "**/tests/_base.js" + - "**/*.test.js" globals: # don't warn about missing declarations i18n: true diff --git a/.mention-bot b/.mention-bot index 829792b61..4e426ab8a 100644 --- a/.mention-bot +++ b/.mention-bot @@ -1,4 +1,5 @@ { + "actions": ["labeled"], "withLabel": "please review", "maxReviewers": 3, "numFilesToCheck": 5, diff --git a/.travis.yml b/.travis.yml index abfda8b8d..9b471516c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,40 +1,89 @@ -sudo: required -dist: trusty - language: node_js -node_js: 6 - -cache: - yarn: true +sudo: required branches: only: - develop + - master + +matrix: + include: + + # WINDOWS cross-built from linux + - os: linux + dist: trusty + node_js: 6 + env: + - GULP_PLATFORM=win + addons: + apt: + packages: + - icnsutils + - graphicsmagick + - xz-utils + - nsis + sources: + - mono + before_install: + - sudo dpkg --add-architecture i386 && sudo add-apt-repository ppa:ubuntu-wine/ppa -y + - sudo apt-get update -q + - sudo apt-get install --no-install-recommends -y mono-devel ca-certificates-mono wine1.8 + after_script: + - makensis -V2 scripts/windows-installer.nsi + -addons: - apt: - packages: - - icnsutils - - graphicsmagick - - xz-utils - - gcc-multilib - - g++-multilib - -before_script: - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - curl https://install.meteor.com/ | sh - - npm install -g meteor-build-client + # LINUX + - os: linux + dist: trusty + node_js: 6 + env: + - GULP_PLATFORM=linux + addons: + apt: + packages: + - icnsutils + - graphicsmagick + - xz-utils + - gcc-multilib + - g++-multilib + + # MAC + - os: osx + osx_image: xcode8 # currently xcode8.1+ doesn't support electron-builder macOS code-signing (https://github.com/electron-userland/electron-builder/issues/820#issuecomment-267777060) + node_js: 6 + env: + - GULP_PLATFORM=mac + before_install: + - npm install -g yarn # macOS xcode8 image doesn't natively support yarn yet + + allow_failures: + - os: osx + + fast_finish: true + +cache: + yarn: true + +install: + - PATH=$PATH:$HOME/.meteor && curl -L https://raw.githubusercontent.com/arunoda/travis-ci-meteor-packages/master/configure.sh | /bin/sh + - yarn global add gulp-cli meteor-build-client + - yarn script: - - npm run ci + - if [[ $TRAVIS_BRANCH != "master" ]]; then unset CSC_LINK CSC_KEY_PASSWORD; fi # disable macOS code-signing (production certificate) on develop branch + - travis_wait 60 gulp mist --platform $GULP_PLATFORM + - if [[ $TRAVIS_BRANCH == "master" ]]; then travis_wait 60 gulp wallet --platform $GULP_PLATFORM; fi # also build wallet if on master branch + - if [[ $TRAVIS_OS_NAME == "linux" ]]; then export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start; sleep 3; fi + - if [[ $GULP_PLATFORM != "win" ]]; then gulp test-mist; fi + +after_success: + - gulp mist-checksums --platform $GULP_PLATFORM + - if [[ $TRAVIS_BRANCH == "master" ]]; then gulp wallet-checksums --platform $GULP_PLATFORM; fi notifications: - email: - - EMAIL webhooks: urls: - - YOUR_WEBHOOK_URL - on_success: change # options: [always|never|change] default: always + - https://webhooks.gitter.im/e/33972d9e627a142c57a6 + on_success: change on_failure: always on_start: never diff --git a/README.md b/README.md index 1ca1bb7bc..d7a10ebf3 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ To run mist in development you need [Node.js NPM](https://nodejs.org) and [Meteo $ npm install -g electron@1.3.13 $ npm install -g gulp -And some futher tools to help with downloading and unzipping client nodes: +And some further tools to help with downloading and unzipping client nodes: _Linux:_ @@ -154,7 +154,7 @@ Mist normally. To create a binaries you need to install [`electron-builder` dependencies](https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build#macos): // tools for the windows binaries - $ brew install wine --without-x11 mono + $ brew install wine --without-x11 mono makensis // tools for the Linux binaries $ brew install gnu-tar libicns graphicsmagick xz // general dependencies @@ -223,3 +223,11 @@ It expects installer/zip files to be in the generated folders e.g. `dist_mist/re ### Code signing for production **As of [#972](https://github.com/ethereum/mist/pull/972) we've updated the build process and thus need to redo code-signing.** + + +## Testing + +First make sure to build Mist with: +`gulp mist --platform [mac,linux]` or `gulp wallet --platform [mac,linux]`. + +Then run `gulp test-mist` or `gulp test-wallet`, accordingly. diff --git a/customProtocols.js b/customProtocols.js index b0b9fb2af..05fd52ef0 100644 --- a/customProtocols.js +++ b/customProtocols.js @@ -1,6 +1,4 @@ -const electron = require('electron'); -const protocol = electron.protocol; -const path = require('path'); +const { protocol } = require('electron'); protocol.registerHttpProtocol('mist', (request, callback) => { @@ -19,8 +17,9 @@ protocol.registerHttpProtocol('mist', (request, callback) => { callback(call); }, (error) => { - if (error) - { console.error('Failed to register protocol'); } + if (error) { + console.error('Failed to register protocol'); + } }); diff --git a/errorPages/400.html b/errorPages/400.html index 06d5acc2d..e4ceb706d 100644 --- a/errorPages/400.html +++ b/errorPages/400.html @@ -7,7 +7,7 @@ background-color: #f0f0f0; color: #ACACAC; text-shadow: 0 -1px #fff; - font: 20px Helvetica Neue, Arial; + font: 20px Source Sans Pro, Helvetica Neue, Arial; font-weight: 200; text-align: center; padding: 10px; diff --git a/errorPages/404.html b/errorPages/404.html new file mode 100644 index 000000000..c0eafb982 --- /dev/null +++ b/errorPages/404.html @@ -0,0 +1,19 @@ + + + Error 404 + + + + ﴾๏๏﴿

+ URL not found. + + \ No newline at end of file diff --git a/errorPages/500.html b/errorPages/500.html new file mode 100644 index 000000000..57aee2e60 --- /dev/null +++ b/errorPages/500.html @@ -0,0 +1,19 @@ + + + Error 500 + + + + (ノಠ益ಠ)ノ

+ Oops.. Something went wrong! + + \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index fe3b4efd2..5996b0197 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -21,6 +21,8 @@ const mocha = require('gulp-spawn-mocha'); const minimist = require('minimist'); const fs = require('fs'); const got = require('got'); +const Q = require('bluebird'); +const githubUpload = Q.promisify(require('gh-release-assets')); const options = minimist(process.argv.slice(2), { string: ['platform', 'walletSource'], @@ -55,8 +57,6 @@ const osArchList = [ console.log('You can select a platform like: --platform '); - -console.log('App type:', type); console.log('Mist version:', version); console.log('Electron version:', electronVersion); @@ -110,8 +110,10 @@ gulp.task('copy-app-source-files', ['clean:dist'], () => { './*.js', './clientBinaries.json', '!gulpfile.js', - ], { base: './' }) - .pipe(gulp.dest(`./dist_${type}/app`)); + ], { + base: './' + }) + .pipe(gulp.dest(`./dist_${type}/app`)); }); @@ -134,9 +136,11 @@ gulp.task('copy-build-folder-files', ['clean:dist', 'copy-app-folder-files'], () return gulp.src([ `./icons/${type}/*`, './interface/public/images/dmg-background.jpg', - ], { base: './' }) - .pipe(flatten()) - .pipe(gulp.dest(`./dist_${type}/build`)); + ], { + base: './' + }) + .pipe(flatten()) + .pipe(gulp.dest(`./dist_${type}/build`)); }); @@ -149,7 +153,7 @@ gulp.task('copy-node-folder-files', ['clean:dist'], () => { streams.push(gulp.src([ `./nodes/eth/${osArch}/*`, ]) - .pipe(gulp.dest(`./dist_${type}/app/nodes/eth/${osArch}`))); + .pipe(gulp.dest(`./dist_${type}/app/nodes/eth/${osArch}`))); } }); @@ -188,7 +192,7 @@ gulp.task('bundling-interface', ['switch-production'], (cb) => { if (options.walletSource === 'local') { console.log('Use local wallet at ../meteor-dapp-wallet/app'); exec(`cd interface/ && meteor-build-client ../dist_${type}/app/interface/ -p "" &&` + - `cd ../../meteor-dapp-wallet/app && meteor-build-client ../../mist/dist_${type}/app/interface/wallet -p ""`, (err, stdout) => { + `cd ../../meteor-dapp-wallet/app && meteor-build-client ../../mist/dist_${type}/app/interface/wallet -p ""`, (err, stdout) => { console.log(stdout); cb(err); @@ -196,7 +200,7 @@ gulp.task('bundling-interface', ['switch-production'], (cb) => { } else { console.log(`Pulling https://github.com/ethereum/meteor-dapp-wallet/tree/${options.walletSource} "${options.walletSource}" branch...`); exec(`cd interface/ && meteor-build-client ../dist_${type}/app/interface/ -p "" &&` + - `cd ../dist_${type}/ && git clone --depth 1 https://github.com/ethereum/meteor-dapp-wallet.git && cd meteor-dapp-wallet/app && meteor-build-client ../../app/interface/wallet -p "" && cd ../../ && rm -rf meteor-dapp-wallet`, (err, stdout) => { + `cd ../dist_${type}/ && git clone --depth 1 https://github.com/ethereum/meteor-dapp-wallet.git && cd meteor-dapp-wallet/app && meteor-build-client ../../app/interface/wallet -p "" && cd ../../ && rm -rf meteor-dapp-wallet`, (err, stdout) => { console.log(stdout); cb(err); @@ -211,12 +215,14 @@ gulp.task('copy-i18n', ['bundling-interface'], () => { return gulp.src([ './interface/i18n/*.*', './interface/project-tap.i18n', - ], { base: './' }) - .pipe(gulp.dest(`./dist_${type}/app`)); + ], { + base: './' + }) + .pipe(gulp.dest(`./dist_${type}/app`)); }); -gulp.task('build-dist', ['download-signatures', 'copy-i18n'], (cb) => { +gulp.task('build-dist', ['copy-i18n'], (cb) => { console.log('Bundling platforms: ', options.platform); const appPackageJson = _.extend({}, packJson, { @@ -225,7 +231,7 @@ gulp.task('build-dist', ['download-signatures', 'copy-i18n'], (cb) => { description: applicationName, homepage: 'https://github.com/ethereum/mist', build: { - appId: `com.ethereum.mist.${type}`, + appId: `com.ethereum.${type}`, category: 'public.app-category.productivity', asar: true, files: [ @@ -234,7 +240,7 @@ gulp.task('build-dist', ['download-signatures', 'copy-i18n'], (cb) => { 'build-dist.js', ], extraFiles: [ - 'nodes/eth/${os}-${arch}', // eslint-disable-line no-template-curly-in-string + 'nodes/eth/${os}-${arch}', // eslint-disable-line no-template-curly-in-string ], linux: { target: [ @@ -250,7 +256,7 @@ gulp.task('build-dist', ['download-signatures', 'copy-i18n'], (cb) => { }, dmg: { background: '../build/dmg-background.jpg', - 'icon-size': 128, + iconSize: 128, contents: [{ x: 441, y: 448, @@ -261,7 +267,8 @@ gulp.task('build-dist', ['download-signatures', 'copy-i18n'], (cb) => { x: 441, y: 142, type: 'file', - }], + } + ], }, }, directories: { @@ -320,13 +327,11 @@ gulp.task('release-dist', ['build-dist'], (done) => { _.each(osArchList, (osArch) => { if (platformIsActive(osArch)) { - switch (osArch) { // eslint-disable-line default-case + switch (osArch) { // eslint-disable-line default-case case 'win-ia32': - // cp(path.join('win-ia32', `${applicationName} Setup ${version}-ia32.exe`), `${appNameHypen}-win32-${versionDashed}.exe`); cp(`${applicationName}-${version}-ia32-win.zip`, `${appNameHypen}-win32-${versionDashed}.zip`); break; case 'win-x64': - // cp(path.join('win', `${applicationName} Setup ${version}.exe`), `${appNameHypen}-win64-${versionDashed}.exe`); cp(`${applicationName}-${version}-win.zip`, `${appNameHypen}-win64-${versionDashed}.zip`); break; case 'mac-x64': @@ -342,11 +347,53 @@ gulp.task('release-dist', ['build-dist'], (done) => { break; } } + + if (platformIsActive('win') && type === 'mist') { + runSeq('build-nsis'); + } }); done(); }); +gulp.task('upload-binaries', () => { + // token must be set using travis' ENVs + const GITHUB_TOKEN = process.env.GITHUB_TOKEN; + + // query github releases + return got(`https://api.github.com/repos/ethereum/mist/releases?access_token=${GITHUB_TOKEN}`, { + json: true, + }) + // filter draft with current version's tag + .then((res) => { + const draft = res.body[_.indexOf(_.pluck(res.body, 'tag_name'), `v${version}`)]; + + if (draft === undefined) throw new Error(`Couldn't find github release draft for v${version} release tag`); + + return draft; + }) + // upload binaries from release folders + .then((draft) => { + const dir = `dist_${type}/release`; + const files = fs.readdirSync(dir); + const filePaths = _.map(files, (file) => { return path.join(dir, file); }); + + // check if draft already contains target binaries + const existingAssets = _.intersection(files, _.pluck(draft.assets, 'name')); + if (!_.isEmpty(existingAssets)) throw new Error(`Github release draft already contains assets (${existingAssets}); will not upload, please remove and trigger rebuild`); + + return githubUpload({ + url: `https://uploads.github.com/repos/ethereum/mist/releases/${draft.id}/assets{?name}`, + token: [GITHUB_TOKEN], + assets: filePaths, + }).then((res) => { + console.log(`Successfully uploaded ${res} to v${version} release draft.`); + }); + }) + .catch((err) => { + console.log(err); + }); +}); gulp.task('get-release-checksums', (done) => { const releasePath = `./dist_${type}/release`; @@ -354,7 +401,9 @@ gulp.task('get-release-checksums', (done) => { const files = fs.readdirSync(releasePath); for (const file of files) { - const sha = shell.exec(`shasum -a 256 "${file}"`, { cwd: releasePath }); + const sha = shell.exec(`shasum -a 256 "${file}"`, { + cwd: releasePath + }); if (sha.code !== 0) { return done(new Error(`Error executing shasum: ${sha.stderr}`)); @@ -388,9 +437,11 @@ gulp.task('download-signatures', (cb) => { .catch(cb); }); -gulp.task('taskQueue', [ - 'release-dist', -]); +gulp.task('taskQueue', ['release-dist'], (cb) => { + if (process.env.TRAVIS_BRANCH === 'master') { + runSeq('upload-binaries', cb); + } +}); // MIST task gulp.task('mist', (cb) => { @@ -410,16 +461,31 @@ gulp.task('wallet-checksums', (cb) => { runSeq('set-variables-wallet', 'get-release-checksums', cb); }); +gulp.task('build-nsis', (cb) => { + const versionParts = version.split('.'); + const versionString = `-DVERSIONMAJOR=${versionParts[0]} -DVERSIONMINOR=${versionParts[1]} -DVERSIONBUILD=${versionParts[2]}`; + const cmdString = `makensis -V3 ${versionString} scripts/windows-installer.nsi`; + console.log(cmdString); + shell.exec(cmdString, cb); +}); -gulp.task('test-wallet', () => { + +const testApp = (app) => { return gulp.src([ - './tests/wallet/*.test.js', - ]) - .pipe(mocha({ + `./tests/${app}/*.test.js`, + ]).pipe(mocha({ timeout: 60000, ui: 'exports', reporter: 'spec', })); +}; + +gulp.task('test-wallet', () => { + testApp('wallet'); +}); + +gulp.task('test-mist', () => { + testApp('mist'); }); diff --git a/interface/client/collections.js b/interface/client/collections.js index 209f19737..b8545051f 100644 --- a/interface/client/collections.js +++ b/interface/client/collections.js @@ -4,7 +4,6 @@ */ - // BROWSER RELATED // Contains the accounts Tabs = new Mongo.Collection('tabs', {connection: null}); diff --git a/interface/client/lib/helpers/helperFunctions.js b/interface/client/lib/helpers/helperFunctions.js index 2133045c9..bb6dbb32e 100644 --- a/interface/client/lib/helpers/helperFunctions.js +++ b/interface/client/lib/helpers/helperFunctions.js @@ -116,9 +116,14 @@ Helpers.generateBreadcrumb = function (url) { filteredUrl = { protocol: Blaze._escape(url.protocol), host: Blaze._escape(url.host), - pathname: Blaze._escape(url.pathname) + pathname: Blaze._escape(url.pathname), + search: Blaze._escape(url.search), + hash: Blaze._escape(url.hash) }; + filteredUrl.pathname += filteredUrl.search.replace(/\?/g, '/'); + filteredUrl.pathname += filteredUrl.hash.replace(/#/g, '/'); + pathname = _.reject(filteredUrl.pathname.replace(/\/$/g, '').split('/'), function (el) { return el === ''; }); diff --git a/interface/client/lib/signatures.js b/interface/client/lib/signatures.js index d5371bba5..30234c664 100644 --- a/interface/client/lib/signatures.js +++ b/interface/client/lib/signatures.js @@ -10015,5 +10015,176 @@ window.SIGNATURES = { ], "0x38bbfa50": [ "__callback(bytes32,string,bytes)" + ], + "0xbc08afd9": [ + "WebOfTrustToken(address,uint256)" + ], + "0xa5bfa9a9": [ + "claimToken(bytes32)" + ], + "0x5669c94f": [ + "issueToken(address,string)" + ], + "0xcdcd77c0": [ + "baz(uint32,bool)" + ], + "0x0b811cb6": [ + "executeProposal(uint256,bytes32)" + ], + "0x1f5d0b4c": [ + "address(address,address,uint256)" + ], + "0x8ac0ca36": [ + "buyViaJohan()" + ], + "0xc1246d39": [ + "simulatePathwayFromBeneficiary()" + ], + "0x59e148fc": [ + "getLastOfferId()" + ], + "0x152583de": [ + "getAttributes()" + ], + "0x446d5aa4": [ + "getAttributes(address)" + ], + "0x88782386": [ + "UnicornMilk()" + ], + "0x13df7091": [ + "mintAll(int256)" + ], + "0xfa9acb05": [ + "addressInArray(address,address)" + ], + "0xb76e4890": [ + "Tester()" + ], + "0x0d2560ee": [ + "addMe()" + ], + "0x8894dd2b": [ + "addEther()" + ], + "0x1e9ea66a": [ + "balanceEther10000000(uint256)" + ], + "0xe5bf93b9": [ + "balanceEther(uint256)" + ], + "0xcd9f05b8": [ + "balanceEtherAddress(address)" + ], + "0xfd7ac203": [ + "TestToken()" + ], + "0x35b09a6e": [ + "someFunction()" + ], + "0x8f2c44a2": [ + "UnicornMilker()" + ], + "0xc26aa3c9": [ + "lockUnicorn(uint256)" + ], + "0xff556ecb": [ + "releaseUnicorn(uint256)" + ], + "0x27e8c2d8": [ + "burnUnicornShares()" + ], + "0xfff3c457": [ + "readMessages(uint256)" + ], + "0x6a226a49": [ + "addMessage(string)" + ], + "0x200ebe34": [ + "addTokensToGive(address)" + ], + "0x7a427d98": [ + "forceReturn()" + ], + "0xe53e04a5": [ + "refillGas()" + ], + "0x323082d7": [ + "Vote(string)" + ], + "0x90cf581c": [ + "voteYes()" + ], + "0x41c12a70": [ + "voteNo()" + ], + "0x49aa4ee2": [ + "removeVote()" + ], + "0xa48bdb7c": [ + "results()" + ], + "0x9832ee65": [ + "resultsWeightedByTokens()" + ], + "0x9dcb5c65": [ + "resultsWeightedByEther()" + ], + "0x49407a44": [ + "claimEther(uint256)" + ], + "0x509f8633": [ + "create_account()" + ], + "0x32fefb4c": [ + "add_account(address,address)" + ], + "0x9b5adea2": [ + "setMinter()" + ], + "0x0ecaea73": [ + "create(address,uint256)" + ], + "0xa24835d1": [ + "destroy(address,uint256)" + ], + "0x36f66528": [ + "EtherDelta(address,uint256,uint256)" + ], + "0x338b5dea": [ + "depositToken(address,uint256)" + ], + "0x9e281a98": [ + "withdrawToken(address,uint256)" + ], + "0xf7888aec": [ + "balanceOf(address,address)" + ], + "0x93f0bb51": [ + "order(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)" + ], + "0x0a19b14a": [ + "trade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256)" + ], + "0x6c86888b": [ + "testTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address)" + ], + "0xfb6e155f": [ + "availableVolume(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)" + ], + "0xbb8be064": [ + "HardwareToken()" + ], + "0x57a373a1": [ + "uintInArray(uint256,uint256,int256,uint256[],uint256)" + ], + "0x32afa2f9": [ + "claimEtherOwner(uint256)" + ], + "0xa2a8336f": [ + "claimEtherSigner(uint256)" + ], + "0x4e077f2a": [ + "addGasEther()" ] -}; +}; \ No newline at end of file diff --git a/interface/client/styles/networkIndicator.import.less b/interface/client/styles/networkIndicator.import.less index c46672228..0cc4165a0 100644 --- a/interface/client/styles/networkIndicator.import.less +++ b/interface/client/styles/networkIndicator.import.less @@ -1,3 +1,4 @@ +// Applies to both onboarding and splash screen .network-indicator { position: absolute; top: 10px; @@ -9,8 +10,10 @@ opacity: 0.8; color: @colorGrey; text-transform: uppercase; +} - .unknown { +// Applies only to the splash screen +.splash-screen .network-indicator .unknown { position: absolute; top: 155px; text-align: center; @@ -21,5 +24,4 @@ font-weight: normal; text-transform: none; color: #fff; - } -} +} \ No newline at end of file diff --git a/interface/client/styles/popupWindows.import.less b/interface/client/styles/popupWindows.import.less index f8f9e23b3..f2685de8f 100644 --- a/interface/client/styles/popupWindows.import.less +++ b/interface/client/styles/popupWindows.import.less @@ -63,10 +63,10 @@ right: 0; padding: 0 @gridHeight; padding-top: @gridHeight * 3; - background: linear-gradient(transparent 0%, @colorGrayLight 20%); + background: linear-gradient(transparent 0%, @colorGrayLight 35%); &.dapp-small { - background: linear-gradient(transparent 50%, @colorGrayLight 70%); + background: linear-gradient(transparent 50%, @colorGrayLight 70%); } } @@ -75,7 +75,7 @@ font-weight: 600; } - &.update-available { + &.update-available { -webkit-user-select: all; .text { @@ -183,7 +183,7 @@ } } - // Parameters + // Parameters .fees, .parameters { font-size: 0.9em; @@ -216,7 +216,7 @@ &:hover strong { word-break: break-all; } - + } .type { text-align: right; @@ -230,9 +230,9 @@ } ::selection { - color: #FFF; + color: #FFF; background: @colorLink; - } + } } ol li::before { @@ -574,7 +574,7 @@ } .data { font-size: 0.9em; - + pre { margin: 0 -@defaultMargin; overflow: auto; diff --git a/interface/client/templates/popupWindows/onboardingScreen.html b/interface/client/templates/popupWindows/onboardingScreen.html index 4774ffbab..e7f415eba 100644 --- a/interface/client/templates/popupWindows/onboardingScreen.html +++ b/interface/client/templates/popupWindows/onboardingScreen.html @@ -3,15 +3,15 @@ {{> elements_networkIndicator}} -
+

{{i18n "mist.popupWindows.onboarding.description"}}

-

- +

+ {{i18n "mist.popupWindows.onboarding.goToTestnetDescription"}}

-

- +

+ {{i18n "mist.popupWindows.onboarding.gotoMainnetDescription"}}

@@ -20,8 +20,8 @@ {{> popupWindows_onboardingScreen_importAccount}}
@@ -66,8 +66,8 @@
{{{i18n "mist.popupWindows.onboarding.viaShapeshift"}}}
{{/if}}
@@ -79,8 +79,8 @@

{{i18n "mist.popupWindows.onboarding.learnIt"}}

@@ -90,10 +90,10 @@

{{i18n "mist.popupWindows.onboarding.learnIt"}}

{{{i18n "mist.popupWindows.onboarding.tutorial2Description"}}}

{{i18n "mist.popupWindows.onboarding.buttons.learnReceipt"}}

-
+
@@ -105,7 +105,7 @@

{{i18n "mist.popupWindows.onboarding.learnIt"}}

@@ -114,28 +114,25 @@

{{i18n "mist.popupWindows.onboarding.learnIt"}}

- {{#with TemplateVar.get "syncing"}} -
{{i18n "mist.popupWindows.onboarding.downloadingBlocks"}} ({{TemplateVar.get "peerCount"}} {{i18n 'mist.nodeInfo.peers'}})
-
- - {{ syncStatus }} - -
+ {{syncStatus}} + {{#if TemplateVar.get 'readyToLaunch'}} + {{else}} - {{#if TemplateVar.get 'readyToLaunch'}} - + {{#with TemplateVar.get "syncing"}} +
{{i18n "mist.popupWindows.onboarding.downloadingBlocks"}} ({{TemplateVar.get "peerCount"}} {{i18n 'mist.nodeInfo.peers'}})
+
{{syncStatusMessage}}
{{else}}
{{#if TemplateVar.get "peerCount"}} - {{TemplateVar.get "peerCount"}} {{i18n 'mist.nodeInfo.peers'}} + {{i18n 'mist.startScreen.nodeSyncFoundPeers' peers=(TemplateVar.get 'peerCount')}} {{else}} {{i18n 'mist.startScreen.nodeSyncConnecting'}} {{/if}}
- {{/if}} - {{/with}} + {{/with}} + {{/if}} - + @@ -151,14 +148,14 @@

{{i18n "mist.popupWindows.onboarding.doYouHaveAWalletFile"}}

{{i18n "mist.popupWindows.onboarding.importing"}}

{{else}} -
- -

- - -

- -
+
+ +

+ + +

+ +
{{/if}} {{else}} @@ -187,11 +184,11 @@

{{i18n "mist.popupWindows.onboar diff --git a/interface/client/templates/popupWindows/onboardingScreen.js b/interface/client/templates/popupWindows/onboardingScreen.js index 93d955790..35ba0b732 100644 --- a/interface/client/templates/popupWindows/onboardingScreen.js +++ b/interface/client/templates/popupWindows/onboardingScreen.js @@ -38,12 +38,12 @@ Template['popupWindows_onboardingScreen'].onCreated(function(){ if(syncing === true) { web3.reset(true); - } else if(_.isObject(syncing)) { // loads syncing data and adds it to old by using 'extend' var oldData = TemplateVar.get(template, 'syncing'); + TemplateVar.set(template, 'syncing', _.extend(oldData||{}, syncing||{})); - + } else { TemplateVar.set(template, 'syncing', false); } @@ -78,7 +78,7 @@ Template['popupWindows_onboardingScreen'].helpers({ return (account) ? account.toLowerCase() : ''; }, /** - Updates the Sync Message live + Updates the Sync Data @method syncStatus */ @@ -86,42 +86,61 @@ Template['popupWindows_onboardingScreen'].helpers({ // This functions loops trhough numbers while waiting for the node to respond var template = Template.instance(); + Meteor.clearInterval(template._intervalId); // Create an interval to quickly iterate trough the numbers template._intervalId = Meteor.setInterval(function(){ // load the sync information - var syncing = TemplateVar.get(template, 'syncing'); - - // Calculates a block t display that is always getting 1% closer to target - syncing._displayBlock = (syncing._displayBlock + (syncing.currentBlock - syncing._displayBlock) / 100 )|| syncing.currentBlock; + var syncing = TemplateVar.get(template, 'syncing'); - syncing._displayStatesDownload = Number(syncing._displayStatesDownload + (syncing.pulledStates/syncing.knownStates - syncing._displayStatesDownload) / 100 ) || syncing.pulledStates/syncing.knownStates; + if (syncing) { + // If it's syncing, then it's not ready + TemplateVar.set(template, 'readyToLaunch', false); + // Calculates a block t display that is always getting a few % closer to target + syncing._displayBlock = (syncing._displayBlock + 2*(syncing.currentBlock - syncing._displayBlock) / 100 ) || Number(syncing.startingBlock); - // Calculates progress - syncing.progress = Math.round(((syncing._displayBlock - syncing.startingBlock) / (syncing.highestBlock - syncing.startingBlock)) * 100); - - // Makes fancy strings - syncing.blockDiff = numeral(syncing.highestBlock - syncing.currentBlock).format('0,0'); - syncing.highestBlockString = numeral(syncing.highestBlock).format('0,0'); - syncing.displayBlock = numeral(Math.round(syncing._displayBlock)).format('0,0'); - syncing.statesPercent = numeral(Math.round(syncing._displayStatesDownload*10000)/100).format('0.00'); + syncing._displayStatesDownload = Number(syncing._displayStatesDownload + (syncing.pulledStates/(1 +syncing.knownStates) - syncing._displayStatesDownload) / 100 ) || Number(syncing.pulledStates)/Number(syncing.knownStates + 1); - // Saves the data back to the object - TemplateVar.set(template, 'syncing', syncing); + // Calculates progress + syncing.progress = 100 * (syncing._displayBlock - syncing.startingBlock) / (1 + Number(syncing.highestBlock) - syncing.startingBlock); + + // Makes fancy strings + syncing.blockDiff = numeral(syncing.highestBlock - syncing.currentBlock).format('0,0'); + syncing.highestBlockString = numeral(syncing.highestBlock).format('0,0'); + syncing.displayBlock = numeral(Math.round(syncing._displayBlock)).format('0,0'); + syncing.statesPercent = numeral(Math.round(syncing._displayStatesDownload*10000)/100).format('0.00'); + + // Saves the data back to the object + TemplateVar.set(template, 'syncing', syncing); - // Only show states if they are less than 50% downloaded - if (Math.round(1000*Number(syncing._displayStatesDownload)) !== Math.round(1000*Number(syncing.pulledStates/syncing.knownStates))) { - TemplateVar.set(template, "syncStatusMessageLive", TAPi18n.__('mist.popupWindows.onboarding.syncMessageWithStates', syncing)); - } else { - TemplateVar.set(template, "syncStatusMessageLive", TAPi18n.__('mist.popupWindows.onboarding.syncMessage', syncing)); - } + // If it's close enough, show the synced button + + if (Number(syncing.highestBlock) - syncing.currentBlock < 100 ) { + TemplateVar.set(template, 'readyToLaunch', true); + } + + // Only show states if they are changing + if (Math.round(1000*Number(syncing._displayStatesDownload)) !== Math.round(1000*Number(syncing.pulledStates/(syncing.knownStates+1)))) { + TemplateVar.set(template, "syncStatusMessageLive", TAPi18n.__('mist.popupWindows.onboarding.syncMessageWithStates', syncing)); + } else if (syncing.displayBlock == '0') { + TemplateVar.set(template, "syncStatusMessageLive", ''); + } else { + TemplateVar.set(template, "syncStatusMessageLive", TAPi18n.__('mist.popupWindows.onboarding.syncMessage', syncing)); + } + } }, 50); + }, + /** + Updates the Sync Message live - return TemplateVar.get(template, "syncStatusMessageLive"); + @method syncStatusMessage + */ + 'syncStatusMessage' : function() { + return TemplateVar.get("syncStatusMessageLive"); } }); @@ -136,12 +155,14 @@ Template['popupWindows_onboardingScreen'].events({ if(TemplateVar.get('testnet')) { ipc.send('onBoarding_changeNet', false); TemplateVar.set('testnet', false); + TemplateVar.set('syncing', null); } }, 'click .start-testnet': function(e, template){ if(!TemplateVar.get('testnet')) { ipc.send('onBoarding_changeNet', true); TemplateVar.set('testnet', true); + TemplateVar.set('syncing', null); } TemplateVar.set('currentActive','testnet'); @@ -156,15 +177,18 @@ Template['popupWindows_onboardingScreen'].events({ }, 'click .goto-tutorial-1': function(){ TemplateVar.set('currentActive','tutorial-1'); - TemplateVar.set('readyToLaunch', true); + if (!TemplateVar.get('syncing')) + TemplateVar.set('readyToLaunch', true); }, 'click .goto-tutorial-2': function(){ TemplateVar.set('currentActive','tutorial-2'); - TemplateVar.set('readyToLaunch', true); + if (!TemplateVar.get('syncing')) + TemplateVar.set('readyToLaunch', true); }, 'click .goto-tutorial-3': function(){ TemplateVar.set('currentActive','tutorial-3'); - TemplateVar.set('readyToLaunch', true); + if (!TemplateVar.get('syncing')) + TemplateVar.set('readyToLaunch', true); }, /** Start the application @@ -226,18 +250,35 @@ Template['popupWindows_onboardingScreen_importAccount'].events({ @event drop .dropable */ - 'drop .dropable': function(e, template){ + 'drop .dropable': function(e, template) { e.preventDefault(); - if(e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) { - TemplateVar.set('filePath', e.originalEvent.dataTransfer.files[0].path); - Tracker.afterFlush(function(){ - template.$('.password').focus(); - }); - } else { - GlobalNotification.warning({ - content: TAPi18n.__('mist.popupWindows.onboarding.errors.unknownFile'), - duration: 4 + if (e.originalEvent.dataTransfer) files = e.originalEvent.dataTransfer.files; + + if (files.length) { + ipc.send('backendAction_checkWalletFile', files[0].path); + + ipc.on('uiAction_checkedWalletFile', function(e, error, type) { + switch (type) { + case 'presale': + TemplateVar.set(template, 'filePath', files[0].path); + Tracker.afterFlush(function() { + template.$('.password').focus(); + }); + break; + case 'web3': + TemplateVar.set(template, 'filePath', files[0].path); + TemplateVar.set(template, 'importing', true); + setTimeout(function() { + ipc.send('backendAction_closePopupWindow'); + }, 750); + break; + default: + GlobalNotification.warning({ + content: TAPi18n.__('mist.popupWindows.onboarding.errors.unknownFile'), + duration: 4 + }); + } }); } @@ -261,29 +302,29 @@ Template['popupWindows_onboardingScreen_importAccount'].events({ }, /** Checks the password match sends the file path and password to the mist backend to import - + @event submit form */ 'submit form': function(e, template){ var pw = template.find('input.password').value; - ipc.send('backendAction_importPresaleFile', TemplateVar.get('filePath'), pw); + ipc.send('backendAction_importWalletFile', TemplateVar.get('filePath'), pw); TemplateVar.set('importing', true); - ipc.on('uiAction_importedPresaleFile', function(e, error, address){ + ipc.on('uiAction_importedWalletFile', function(e, error, address){ TemplateVar.set(template, 'importing', false); TemplateVar.set(template, 'filePath', false); if(address) { - ipc.removeAllListeners('uiAction_importedPresaleFile'); + ipc.removeAllListeners('uiAction_importedWalletFile'); console.log('Imported account: ', address); // move to add account screen, when in the onboarding window if($('.onboarding-start')[0]) { TemplateVar.setTo('.onboarding-account', 'newAccount', web3.toChecksumAddress(address)); TemplateVar.setTo('.onboarding-screen', 'currentActive', 'account'); - + // otherwise simply close the window } else { ipc.send('backendAction_closePopupWindow'); @@ -337,7 +378,7 @@ Template['popupWindows_onboardingScreen_password'].helpers({ Template['popupWindows_onboardingScreen_password'].events({ /** Clear the form - + @event click button[type="button"] */ 'click button[type="button"]': function(e, template){ @@ -354,7 +395,7 @@ Template['popupWindows_onboardingScreen_password'].events({ }, /** Password checks - + @event click button[type="button"] */ 'input input, change input': function(e, template){ @@ -367,7 +408,7 @@ Template['popupWindows_onboardingScreen_password'].events({ }, /** Checks the password match and creates a new account - + @event submit form */ 'submit form': function(e, template){ @@ -392,7 +433,7 @@ Template['popupWindows_onboardingScreen_password'].events({ if(!e) { TemplateVar.setTo('.onboarding-account', 'newAccount', web3.toChecksumAddress(res)); TemplateVar.setTo('.onboarding-screen', 'currentActive', 'account'); - + // clear form pw = pwRepeat = null; @@ -405,4 +446,4 @@ Template['popupWindows_onboardingScreen_password'].events({ }); } } -}); \ No newline at end of file +}); diff --git a/interface/client/templates/popupWindows/sendTransactionConfirmation.html b/interface/client/templates/popupWindows/sendTransactionConfirmation.html index 3dbf4db12..4cc9c5ff8 100644 --- a/interface/client/templates/popupWindows/sendTransactionConfirmation.html +++ b/interface/client/templates/popupWindows/sendTransactionConfirmation.html @@ -11,7 +11,7 @@

{{i18n "mist.popupWindows.sendTransactionConfirmation.title.sendTransaction"

{{i18n "mist.popupWindows.sendTransactionConfirmation.title.createContract"}}

{{/if}} {{/if}} - +
@@ -34,7 +34,7 @@

{{i18n "mist.popupWindows.sendTransactionConfirmation.title.createContract"}

{{/if}}
- +
{{#if to}} {{#if TemplateVar.get "toIsContract"}} @@ -65,45 +65,11 @@

{{i18n "mist.popupWindows.sendTransactionConfirmation.title.createContract"} {{/unless}} {{/if}} - {{#if data}} - - {{#if showFormattedParams}} -
-

{{{i18n "mist.popupWindows.sendTransactionConfirmation.parameters"}}} - {{{i18n "mist.popupWindows.sendTransactionConfirmation.showRawBytecode"}}} -

-
    - {{# each param in params}} -
  1. {{> dapp_output output=param }}
  2. - {{/each}} -
-
- {{else}} -
-

{{i18n "mist.popupWindows.sendTransactionConfirmation.data"}} - - {{# if params}} - {{{i18n "mist.popupWindows.sendTransactionConfirmation.showDecodedParameters"}}} - {{else}} - {{#if to}} - {{#unless (TemplateVar.get "lookingUpFunctionSignature")}} - {{i18n "mist.popupWindows.sendTransactionConfirmation.lookupData"}} - - {{/unless}} - {{/if}} - {{/if}} -

- -
{{{formattedData}}}
-
- {{/if}} - {{/if}} -
  • - {{i18n "mist.popupWindows.sendTransactionConfirmation.estimatedFee"}} + {{i18n "mist.popupWindows.sendTransactionConfirmation.estimatedFee"}}
    {{#if $eq (TemplateVar.get "estimatedGas") "invalid"}} @@ -120,7 +86,7 @@

    {{i18n "mist.popupWindows.sendTransactionConfirmation.data"}} {{/if}}

    -
  • +
  • {{i18n "mist.popupWindows.sendTransactionConfirmation.gasLimit"}} @@ -138,23 +104,56 @@

    {{i18n "mist.popupWindows.sendTransactionConfirmation.data"}}

+ {{#if data}} + {{#if showFormattedParams}} +
+

{{{i18n "mist.popupWindows.sendTransactionConfirmation.parameters"}}} + {{{i18n "mist.popupWindows.sendTransactionConfirmation.showRawBytecode"}}} +

+
    + {{# each param in params}} +
  1. {{> dapp_output output=param }}
  2. + {{/each}} +
+
+ {{else}} +
+

{{i18n "mist.popupWindows.sendTransactionConfirmation.data"}} + + {{# if params}} + {{{i18n "mist.popupWindows.sendTransactionConfirmation.showDecodedParameters"}}} + {{else}} + {{#if to}} + {{#unless (TemplateVar.get "lookingUpFunctionSignature")}} + {{i18n "mist.popupWindows.sendTransactionConfirmation.lookupData"}} + + {{/unless}} + {{/if}} + {{/if}} +

+ +
{{{formattedData}}}
+
+ {{/if}} + {{/if}} +

{{#if TemplateVar.get "unlocking"}}

{{i18n "mist.popupWindows.sendTransactionConfirmation.unlocking"}}

{{else}} - +
- + {{/if}}
{{/with}} - +
diff --git a/interface/client/templates/popupWindows/sendTransactionConfirmation.js b/interface/client/templates/popupWindows/sendTransactionConfirmation.js index c0c9e5c48..52d913731 100644 --- a/interface/client/templates/popupWindows/sendTransactionConfirmation.js +++ b/interface/client/templates/popupWindows/sendTransactionConfirmation.js @@ -6,7 +6,7 @@ Template Controllers var setWindowSize = function(template){ Tracker.afterFlush(function(){ - ipc.send('backendAction_setWindowSize', 580, template.$('.popup-windows').height() + 60); + ipc.send('backendAction_setWindowSize', 580, template.$('.popup-windows').height() + 120); }); } @@ -103,7 +103,7 @@ Template['popupWindows_sendTransactionConfirmation'].onCreated(function(){ var data = Session.get('data'); if(data) { - + // set window size setWindowSize(template); @@ -127,10 +127,10 @@ Template['popupWindows_sendTransactionConfirmation'].onCreated(function(){ web3.eth.getCode(data.to, function(e, res){ if(!e && res && res.length > 2) { TemplateVar.set(template, 'toIsContract', true); - setWindowSize(template); + setWindowSize(template); } }); - + if (data.data) { localSignatureLookup(data.data).then(function(textSignature) { // Clean version of function signature. Striping params @@ -261,7 +261,7 @@ Template['popupWindows_sendTransactionConfirmation'].helpers({ @method (transactionInvalid) */ 'transactionInvalid': function() { - return TemplateVar.get('estimatedGas') === 'invalid' + return TemplateVar.get('estimatedGas') === 'invalid' || TemplateVar.get('estimatedGas') === 0 || typeof TemplateVar.get('estimatedGas') === 'undefined'; } @@ -294,7 +294,7 @@ Template['popupWindows_sendTransactionConfirmation'].events({ */ 'submit form': function(e, template){ e.preventDefault(); - + var data = Session.get('data'), pw = template.find('input[type="password"]').value, gas = web3.fromDecimal(TemplateVar.get('providedGas')); @@ -373,7 +373,7 @@ Template['popupWindows_sendTransactionConfirmation'].events({ remoteSignatureLookup(data.data).then(function(textSignature) { TemplateVar.set(template, 'lookingUpFunctionSignature', false); - + // Clean version of function signature. Striping params TemplateVar.set(template, 'executionFunction', textSignature.replace(/\(.+$/g, '')); TemplateVar.set(template, 'hasSignature', true); @@ -385,10 +385,9 @@ Template['popupWindows_sendTransactionConfirmation'].events({ ipc.send('backendAction_decodeFunctionSignature', textSignature, data.data); } }).catch(function(bytesSignature) { - TemplateVar.set(template, 'lookingUpFunctionSignature', false); + TemplateVar.set(template, 'lookingUpFunctionSignature', false); TemplateVar.set(template, 'executionFunction', bytesSignature); TemplateVar.set(template, 'hasSignature', false); }); } }); - diff --git a/interface/client/templates/popupWindows/splashScreen.js b/interface/client/templates/popupWindows/splashScreen.js index 8d51aaa57..4aea7fd79 100644 --- a/interface/client/templates/popupWindows/splashScreen.js +++ b/interface/client/templates/popupWindows/splashScreen.js @@ -92,6 +92,7 @@ Template['popupWindows_splashScreen'].onCreated(function(){ if (status === 'inProgress') { TemplateVar.set(template, 'showStartAppButton', true); TemplateVar.set(template, 'startAppButtonText', TAPi18n.__('mist.startScreen.launchApp')); + ipc.send('backendAction_skipSync'); if (data !== false) { // if state is "in progress" and we have data @@ -189,9 +190,9 @@ Template['popupWindows_splashScreen'].helpers({ syncData._displayKnownStates = Number(syncData.knownStates || 0); } else { // Increment each them slowly to match target number - syncData._displayBlock += (Number(syncData.currentBlock) - syncData._displayBlock) / 10; - syncData._displayState += (Number(syncData.pulledStates || 0) - syncData._displayState) / 10; - syncData._displayKnownStates += (Number(syncData.knownStates || 0) - syncData._displayKnownStates) / 10; + syncData._displayBlock += (Number(syncData.currentBlock) - syncData._displayBlock) / 100; + syncData._displayState += (Number(syncData.pulledStates || 0) - syncData._displayState) / 100; + syncData._displayKnownStates += (Number(syncData.knownStates || 0) - syncData._displayKnownStates) / 100; } // Create the fancy strings @@ -224,7 +225,7 @@ Template['popupWindows_splashScreen'].helpers({ } } - }, 100); + }, 10); return TemplateVar.get(template, "syncStatusMessageLive"); } diff --git a/interface/client/templates/views/webview.js b/interface/client/templates/views/webview.js index b64aa6ec6..e28d4b848 100644 --- a/interface/client/templates/views/webview.js +++ b/interface/client/templates/views/webview.js @@ -60,6 +60,10 @@ Template['views_webview'].onRendered(function(){ webviewLoadStop.call(this, tabId, e); }); + // show error pages + webview.addEventListener('did-fail-load', showError.bind(webview, tabId)); + webview.addEventListener('crashed', showError.bind(webview, tabId)); + // navigate page, and redirect to browser tab if necessary webview.addEventListener('will-navigate', webviewLoadStart.bind(webview, tabId)); webview.addEventListener('did-get-redirect-request', webviewLoadStart.bind(webview, tabId)); @@ -122,6 +126,10 @@ Template['views_webview'].helpers({ }}); } + // allow error pages + if(url && url.indexOf('file://'+ dirname + '/errorPages/') === 0) { + return url; + } // CHECK URL and throw error if not allowed if(!Helpers.sanitizeUrl(url, true)) { @@ -137,7 +145,7 @@ Template['views_webview'].helpers({ return 'file://'+ dirname + '/errorPages/400.html'; } - // remove redirect + // add url if(url) { template.url = url; Tabs.update(this._id, {$set: { diff --git a/interface/client/templates/webviewEvents.js b/interface/client/templates/webviewEvents.js index 26e10bfc8..332676911 100644 --- a/interface/client/templates/webviewEvents.js +++ b/interface/client/templates/webviewEvents.js @@ -1,4 +1,31 @@ +showError = function(tabId, e){ + if(e.isMainFrame || e.killed) { + var url, + path = 'file://'+ dirname + '/errorPages/'; + + if(e.killed) { + e.errorCode = 500; + } + + switch(e.errorCode) { + case -105: + url = path +'404.html'; + break; + case 500: + url = path +'500.html'; + break; + } + + if(url) { + Tabs.update(tabId, {$set: { + redirect: url + }}); + } + } +}; + + webviewChangeUrl = function(tabId, e){ if(e.type === 'did-navigate-in-page' && !e.isMainFrame) return; diff --git a/interface/i18n/app.nl.i18n.json b/interface/i18n/app.nl.i18n.json index 97b9670a1..a0eceea97 100644 --- a/interface/i18n/app.nl.i18n.json +++ b/interface/i18n/app.nl.i18n.json @@ -20,8 +20,8 @@ "sending": "Verzenden...", "create": "Aanmaken", "tryToReconnect": "Probeer te verbinden", - "stayAnonymous": "Stay anonymous", - "authorize": "Authorize" + "stayAnonymous": "Blijf anoniem", + "authorize": "Autoriseren" }, "commonWords": { "you": "u", diff --git a/interface/i18n/mist.de.i18n.json b/interface/i18n/mist.de.i18n.json index fa21cdcc1..2c8016b32 100644 --- a/interface/i18n/mist.de.i18n.json +++ b/interface/i18n/mist.de.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Konten", - "importPresale": "Pre-sale-Konto importieren", + "importPresale": "Konto importieren", "newAccount": "Neues Konto", "backup": "Sicherung", "backupKeyStore": "Konten", @@ -42,12 +42,16 @@ "devToolsWebview": "__webview__", "runTests": "Tests durchführen", "logFiles": "Logdatei anzeigen", + "openRemix": "Remix IDE öffnen", "ethereumNode": "Ethereum Node", "network": "Netzwerk", "mainNetwork": "Hauptnetzwerk", "startMining": "⛏ Mining starten (nur auf Testnetz)", "stopMining": "⛏ Mining stoppen", - "externalNode": "using external node" + "externalNode": "using external node", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Fenster", @@ -70,7 +74,7 @@ "linux": "Um Zeit Synchronisation einzuschalten installiere \"ntp\" via \"apt-get install ntp\".", "darwin": "Um Zeit Synchronisation einzuschalten, öffne die System Einstellungen und checke \"Zeit Datum automatisch\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -202,7 +206,7 @@ "gotoMainnet": "Verwende das Hauptnetz", "gotoMainnetDescription": " Sie werden etwas Ether benötigen, um Verträge anzulegen und auszuführen. Wir werden Ihnen helfen, etwas zu bekommen ...", "doYouHaveAWalletFile": "Haben Sie eine Wallet-Datei?", - "walletFileDescription": "

Wenn Sie 2014 am Ethereum-Pre-sale teilgenommen haben, sollten Sie über eine Datei mit dem Dateinamen ethereum_wallet_backup.json verfügen. Sie wurde nach dem Kauf heruntergeladen und Ihnen auch per E-Mail geschickt.

", + "walletFileDescription": "

Wallet-Datei zum importieren in dieses Fenster ziehen.
Wenn Sie 2014 am Ethereum-Pre-sale teilgenommen haben, sollten Sie über eine Datei mit dem Dateinamen ethereum_wallet_backup.json verfügen. Sie wurde nach dem Kauf heruntergeladen und Ihnen auch per E-Mail geschickt.

", "dropFilesHere": "Pre-sale Datei hochladen", "creating": "Erstellen...", "importing": "Importieren...", @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.en.i18n.json b/interface/i18n/mist.en.i18n.json index 2b0b04f29..cf3bd86b7 100644 --- a/interface/i18n/mist.en.i18n.json +++ b/interface/i18n/mist.en.i18n.json @@ -46,7 +46,7 @@ }, "accounts": { "label": "Accounts", - "importPresale": "Import Pre-sale Accounts", + "importPresale": "Import Accounts", "newAccount": "New account", "backup": "Backup", "backupKeyStore": "Accounts", @@ -60,10 +60,15 @@ "devToolsWebview": "__webview__", "runTests": "Run tests", "logFiles": "Show log file", + "openRemix": "Open Remix IDE", "externalNode": "using external node", "ethereumNode": "Ethereum Node", "network": "Network", "mainNetwork": "Main Network", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)", + "mainNetwork": "Main Network", "startMining": "⛏ Start Mining (Testnet only)", "stopMining": "⛏ Stop Mining" }, @@ -226,14 +231,14 @@ "lookupDataExplainer": "Look this up on the internet" }, "onboarding": { - "description" : "Ethereum is a public blockchain that features a turing complete programming for building solid, decentralized applications.", + "description" : "Ethereum is a platform for decentralized blockchain apps with a fully featured programming language", "goToTestnet" : "Use the test network", "goToTestnetDescription" : "Test the technology freely in a sandboxed testnet, without using real ether.", "gotoMainnet" : "Use the main network", "gotoMainnetDescription" : "You’ll need some Ether in order to create and execute contracts. Don't worry, we'll help you get some...", "doYouHaveAWalletFile" : "Do you have a wallet file?", - "walletFileDescription" : "

If you participated on the Ethereum Pre-sale 2014, you should have a file named ethereum_wallet_backup.json. It was downloaded after the sale and also sent to your email

", - "dropFilesHere" : "Drop pre-sale file", + "walletFileDescription" : "

Move any wallet file here to import.
If you participated on the Ethereum Pre-sale 2014, you should have a file named ethereum_wallet_backup.json. It was downloaded after the sale and also sent to your email

", + "dropFilesHere" : "Drop wallet file", "creating": "Creating...", "importing": "Importing...", "skip" : "Skip this step", @@ -253,6 +258,7 @@ "downloadingBlocks": "Downloading blocks", "syncMessage": "Block __displayBlock__ of __highestBlockString__", "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync..", "tutorial1Description" : "

Now the only thing left to do is wait for the download to finish. Here's some reading suggestions:

Make your own money

Make a cryptocurrency with a fixed market supply, tokens representing real world assets, etc

", "tutorial2Description" : "

Create a crowdsale

Raise funds for a common goal, fully trustable without a third party. Sidestep the hurdle of traditional funding system and go directly to the source by funding an organization via the blockchain.

", "tutorial3Description" : "

Create a blockchain organization

Create an autonomous organization with rules on spending money and making decisions for you and your investors.

", diff --git a/interface/i18n/mist.es.i18n.json b/interface/i18n/mist.es.i18n.json index 50747a5d0..1e7059e9b 100644 --- a/interface/i18n/mist.es.i18n.json +++ b/interface/i18n/mist.es.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Cuentas", - "importPresale": "Importar Cuentas de la Pre-venta", + "importPresale": "Importar Cuentas", "newAccount": "Nueva cuenta", "backup": "Copia de seguridad", "backupKeyStore": "Cuentas", @@ -47,7 +47,11 @@ "mainNetwork": "Red principal", "startMining": "⛏ Empezar a minar (sólo Testnet)", "stopMining": "⛏ Parar de minar", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Ventana", @@ -70,7 +74,7 @@ "linux": "Para permitir la sincronización con un servidor de tiempo instale \"ntp\" vía \"apt-get install ntp\".", "darwin": "Para habilitar la sincronización del tiempo, abra las preferencias de tiempo y marque \"Ajuste la hora y la fecha automáticamente\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "connectAccount": { "chooseAccountTitle": "Elegir sus cuentas", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.fa.i18n.json b/interface/i18n/mist.fa.i18n.json index 89faf57fe..b2d807e66 100644 --- a/interface/i18n/mist.fa.i18n.json +++ b/interface/i18n/mist.fa.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Accounts", - "importPresale": "Import Pre-sale Accounts", + "importPresale": "Import Accounts", "newAccount": "New account", "backup": "Backup", "backupKeyStore": "Accounts", @@ -47,7 +47,11 @@ "network": "Network", "mainNetwork": "Main Network", "startMining": "⛏ Start Mining (Testnet only)", - "stopMining": "⛏ Stop Mining" + "stopMining": "⛏ Stop Mining", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Window", @@ -70,7 +74,7 @@ "linux": "To enable a time sync server install \"ntp\" via \"apt-get install ntp\".", "darwin": "To enable time sync, open the time preferences and check \"Set the time and date automatically\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -249,7 +253,8 @@ "unknownFile": "File not recognised.", "wrongPassword": "Wrong password.", "importFailed": "Couldn't import the file, got: __error__" - } + }, + "startingSync": "Getting ready to sync.." }, "connectAccount": { "chooseAccountTitle": "Choose account", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.fr.i18n.json b/interface/i18n/mist.fr.i18n.json index 9a043b95c..74eda619f 100644 --- a/interface/i18n/mist.fr.i18n.json +++ b/interface/i18n/mist.fr.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Comptes", - "importPresale": "Importer les comptes de prévente", + "importPresale": "Importer les comptes", "newAccount": "Nouveau compte", "backup": "Sauvegarder", "backupKeyStore": "Comptes", @@ -47,7 +47,11 @@ "mainNetwork": "Réseau principal", "startMining": "⛏ Commencer à miner (seulement pour Testnet)", "stopMining": "⛏ Arrêter de miner", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Fenêtre", @@ -70,7 +74,7 @@ "linux": "Pour activer un serveur de synchronisation de temps, installez \"ntp\" via \"apt-get install ntp\".", "darwin": "Pour activer la synchronisation du temps, ouvrez les préférences de temps et cochez \"Régler la date et l'heure automatiquement\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.it.i18n.json b/interface/i18n/mist.it.i18n.json index d81d833f3..b6a312829 100644 --- a/interface/i18n/mist.it.i18n.json +++ b/interface/i18n/mist.it.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Accounts", - "importPresale": "Importa Accounts pre-vendita", + "importPresale": "Importa Accounts", "newAccount": "Nuovo account", "backup": "Backup", "backupKeyStore": "Accounts", @@ -47,7 +47,11 @@ "mainNetwork": "Rete principale", "startMining": "⛏ Inizia mining (solo Testnet)", "stopMining": "⛏ Ferma mining", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Finestra", @@ -70,7 +74,7 @@ "linux": "Per abilitare la sincronia con un time server installa \"ntp\" via \"apt-get install ntp\".", "darwin": "Per abilitare la sincronia dell'ora, apri le preferenze di orario e spunta \"Setta ora e data automaticamente\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.ja.i18n.json b/interface/i18n/mist.ja.i18n.json index 6d71de12b..9cbb4835b 100644 --- a/interface/i18n/mist.ja.i18n.json +++ b/interface/i18n/mist.ja.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "アカウント", - "importPresale": "プリセールアカウントを読み込む", + "importPresale": "アカウントを読み込む", "newAccount": "新規アカウント", "backup": "バックアップ", "backupKeyStore": "アカウント", @@ -47,7 +47,11 @@ "mainNetwork": "メインネットワーク", "startMining": "⛏ マイニングを始める (テストネット のみ)", "stopMining": "⛏ マイニングを中止する", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Window", @@ -70,7 +74,7 @@ "linux": "時間を同期させるサーバーを使うためには、 \"ntp\" を \"apt-get install ntp\" をコマンドラインから入力してインストールする必要があります。", "darwin": "時間を同期するためには、時間設定を開き \"時間と日にちを同期自動で同期\" にチェックすることが必要です." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.ko.i18n.json b/interface/i18n/mist.ko.i18n.json index b8d03ced8..948738ecf 100644 --- a/interface/i18n/mist.ko.i18n.json +++ b/interface/i18n/mist.ko.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "계정", - "importPresale": "프리세일 계정 추가하기", + "importPresale": "계정 추가하기", "newAccount": "새 계정", "backup": "백업", "backupKeyStore": "계정키 백업", @@ -47,7 +47,11 @@ "mainNetwork": "메인 네트워크", "startMining": "⛏ 채굴 시작(테스트넷만 해당)", "stopMining": "⛏ 채굴 중단", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "창", @@ -70,7 +74,7 @@ "linux": "시간 동기화 서버를 가동시키기 위해서는 \"ntp\" 를 \"apt-get install ntp\" 의 방법으로 설치하세요.", "darwin": "시간 동기화를 위해서, 시간 옵션을 열고 \"시간과 날짜 자동설정(Set the time and date automatically)\" 옵션을 선택하세요." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.kr.i18n.json b/interface/i18n/mist.kr.i18n.json index a93c84efc..41babc6ba 100644 --- a/interface/i18n/mist.kr.i18n.json +++ b/interface/i18n/mist.kr.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "계정", - "importPresale": "프리세일 계정 추가하기", + "importPresale": "계정 추가하기", "newAccount": "새 계정", "backup": "백업", "backupKeyStore": "계정키 백업", @@ -47,7 +47,11 @@ "mainNetwork": "메인 네트워크", "startMining": "⛏ 채굴 시작(테스트넷만 해당)", "stopMining": "⛏ 채굴 중단", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "창", @@ -70,7 +74,7 @@ "linux": "시간 동기화 서버를 가동시키기 위해서는 \"ntp\" 를 \"apt-get install ntp\" 의 방법으로 설치하세요.", "darwin": "시간 동기화를 위해서, 시간 옵션을 열고 \"시간과 날짜 자동설정(Set the time and date automatically)\" 옵션을 선택하세요." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", diff --git a/interface/i18n/mist.nb.i18n.json b/interface/i18n/mist.nb.i18n.json index 1f1b848d1..91ce3fe5c 100644 --- a/interface/i18n/mist.nb.i18n.json +++ b/interface/i18n/mist.nb.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Kontoer", - "importPresale": "Importer Forhåndssalg Kontoer", + "importPresale": "Importer Kontoer", "newAccount": "Ny konto", "backup": "Sikkerhetskopier", "backupKeyStore": "Kontoer", @@ -47,7 +47,11 @@ "mainNetwork": "Hovednettverk", "startMining": "⛏ Start Mining (Kun testnett)", "stopMining": "⛏ Stopp Mining", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Vindu", @@ -70,7 +74,7 @@ "linux": "For å aktivere en tidssynkroniseringsserver installer \"ntp\" via \"apt-get install ntp\".", "darwin": "For å aktivere tidssynkronisering, åpne tidsinnstillinger og velg \"Angi klokkeslett og dato automatisk\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.nl.i18n.json b/interface/i18n/mist.nl.i18n.json index dca843648..9440f6b4c 100644 --- a/interface/i18n/mist.nl.i18n.json +++ b/interface/i18n/mist.nl.i18n.json @@ -5,7 +5,7 @@ "label": "__app__", "about": "Over __app__", "checkForUpdates": "Op updates controleren...", - "checkForNodeUpdates": "Check for Ethereum node updates...", + "checkForNodeUpdates": "Controleer op Ethereum node updates...", "services": "Diensten", "hide": "__app__ verbergen", "hideOthers": "Andere verbergen", @@ -22,13 +22,31 @@ "selectAll": "Alles selecteren" }, "view": { - "label": "Bekijken", + "label": "Weergave", "fullscreen": "Volledig Scherm Inschakelen", - "default": "Default" + "languages": "Wijzig taal", + "default": "Standaard", + "langCodes": { + "de": "Deutsch", + "en": "English", + "es": "Español", + "fa": "فارسى", + "fr": "Français", + "it": "Italiano", + "ja": "日本語", + "ko": "한국어 ", + "nl": "Nederlands", + "nb": "Norsk", + "pt": "Português", + "sq": "Shqip", + "ru": "Pусский", + "zh": "普通話", + "zh-TW": "國語" + } }, "accounts": { "label": "Accounts", - "importPresale": "Importeer voorverkoop Accounts", + "importPresale": "Importeer Accounts", "newAccount": "Nieuw account", "backup": "Backup", "backupKeyStore": "Accounts", @@ -42,12 +60,16 @@ "devToolsWebview": "__webview__", "runTests": "Tests uitvoeren", "logFiles": "Toon log bestand", + "openRemix": "Open Remix IDE", + "externalNode": "Externe Node in gebruik", "ethereumNode": "Ethereum Node", "network": "Netwerk", + "nodeMode": "Chain download", + "fullNode": "Bewaar volledige blockchain", + "lightNode": "Gebruik light Node (experimenteel!)", "mainNetwork": "Hoofdnetwerk", "startMining": "⛏ Start Mining (Alleen testnet)", - "stopMining": "⛏ Stop Mining", - "externalNode": "using external node" + "stopMining": "⛏ Stop Mining" }, "window": { "label": "Scherm", @@ -57,26 +79,26 @@ }, "help": { "label": "Help", - "reportBug": "Report an issue on Github" + "reportBug": "Rapporteer een probleem op Github" } }, "errors": { - "nodeConnect": "Verbinden naar node niet mogelijk? Zie de logboek bestanden voor meer informatie:", - "nodeStartup": "Het lijkt erop dat de node niet kan worden opgestart, heeft u er al een aan staan? Is deze de database aan het upgraden?", + "nodeConnect": "Verbinden met node niet mogelijk? Zie de logboek bestanden voor meer informatie:", + "nodeStartup": "Het lijkt erop dat de node niet kan worden opgestart, draait er al een? Is deze de database aan het upgraden?", "timeSync": { - "title": "Uw computer's klok is niet gesynchroniseerd.", - "description": "Om succesvol met het Ethereum netwerk te verbinden moet u uw computer's klok synchroniseren met een tijdssynchronisatie server.", - "win32": "Ga naat uw Internet Tijd Instellingen in uw configuratiescherm en selecteer de optie. Zie deze uitleg voor details: http://www.guidingtech.com/3119/windows-clock-sync/", + "title": "Je computer's klok is niet gesynchroniseerd.", + "description": "Om succesvol met het Ethereum netwerk te verbinden moet je computer's klok gesynchroniseerd zijn met een tijdssynchronisatie server.", + "win32": "Ga naar je Internet Tijd Instellingen in je configuratiescherm en selecteer de optie. Zie deze uitleg voor details: http://www.guidingtech.com/3119/windows-clock-sync/", "linux": "Installeer voor een tijdssynchronisatieserver \"ntp\" via \"apt-get install ntp\".", - "darwin": "Om tijdssynchronisatie aan de zetten opent u uw instellingen en activeert u \"Tijd en datum automatisch instellen\"." + "darwin": "Zet tijdssynchronisatie aan door in je instellingen de optie \"Tijd en datum automatisch instellen\" te activeren." }, - "nodeChecksumMismatch": { - "title": "Checksum mismatch in downloaded node!", - "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." + "nodeChecksumMismatch": { + "title": "Checksum mismatch in gedownloade node!", + "description": "__algorithm__: __hash__\n\nInstalleer de __type__ node versie __version__ handmatig." }, "legacyChain": { - "title": "Legacy chain detected", - "description": "Your node is currently on the unsupported Ethereum Classic chain. To use this chain use tools provided by the ethereum classic project at\nhttps://ethereumclassic.github.io.\n\nTo revert to the main ethereum chain follow the tutorial here:\nhttps://github.com/ethereum/mist/releases/0.8.2" + "title": "Legacy chain gedetecteerd", + "description": "Je node draait momenteel op de niet ondersteunde Ethereum Classic chain. Om deze chain te gebruiken dien je de tools te gebruiken van het Ethereum Classic project op\nhttps://ethereumclassic.github.io.\n\nOm terug te gaan naar de standaard Ethereum chain kun je deze tutorial volgen:\nhttps://github.com/ethereum/mist/releases/0.8.2" } }, "rightClick": { @@ -87,17 +109,17 @@ "nodeInfo": { "nodeSyncing": "__blockDiff__ blokken te gaan", "blockReceived": "Nieuw blok ontvangen", - "blockNumber": "Uw laatste bloknummer", + "blockNumber": "Jouw laatste bloknummer", "timeSinceBlock": "Verstreken tijd sinds laatste blok", - "testnetExplain": "U best actief op een testnet, VERSTUUR GEEN echte ether naar deze adressen", - "peers": "peers", - "checkingWhichNetwork": "Checking network...", + "checkingWhichNetwork": "Netwerk aan het controleren...", "mainNetwork": "Main-net", "testNetwork": "Test-net", "privateNetwork": "Private-net", - "mainnetExplain": "You are on the main Ethereum global network", - "privatenetExplain": "You are on a private net, DO NOT SEND any real ether to these addresses", - "unknownnetExplain": "Unable to determine which network you are on" + "mainnetExplain": "Je zit op het main Ethereum wereldwijde netwerk", + "testnetExplain": "Je bent actief op het __name__, VERSTUUR GEEN echte Ether naar deze adressen", + "privatenetExplain": "Je zit op een private net, VERSTUUR GEEN echte Ether naar deze adressen", + "unknownnetExplain": "Niet in staat om te bepalen op welk netwerk je zit", + "peers": "peers" }, "sidebar": { "buttons": { @@ -107,54 +129,66 @@ "browserBar": { "buttons": { "noAccounts": "Geen accounts ingesteld", - "connect": "Connect" + "connect": "Verbind" } }, "startScreen": { "runningNodeFound": "Lopende Ethereum node gevonden!", "startingNode": "Ethereum node starten...", + "stoppingNode": "Ethereum node stoppen...", "startedNode": "Applicatie starten...", - "nodeConnectionTimeout": "Ethereum node opstarten niet mogelijk!
Als u Geth geinstalleerd heeft, gebruik dan dit commando om het op te starten:
geth --ipcpath __path__

Of meld een fout ", - "nodeBinaryNotFound": "Geen Ethereun node uitvoerbaar bestand gevonden!
Start er a.u.b. handmatig een. ", - "nodeSyncing": "Ethereum node moet synchroniseren, even gedult alstublieft...", + "nodeConnectionTimeout": "Ethereum node opstarten niet mogelijk!
Als je Geth geinstalleerd hebt, gebruik dan dit commando om het op te starten:
geth --ipcpath __path__

Of meld een fout ", + "nodeBinaryNotFound": "Geen Ethereum node gevonden!
Start er a.u.b. handmatig een. ", + "nodeStarting": "Ethereum node opstarten...", + "nodeStarted": "Ethereum node gestart", + "nodeConnected": "Ethereum node verbonden", + "nodeStopping": "Ethereum node afsluiten...", + "nodeStopped": "Ethereum node gestopt", + "nodeError": "Ethereum node verbindingsfout :'(", + "unableToBindPort": "Ethereum node kan niet opstarten. Draait er al een?", + "nodeSyncing": "Ethereum node moet synchroniseren, even geduld alstublieft...", "nodeSyncInfo": "Blok __currentBlock__ van __highestBlock__ aan het downloaden.", + "nodeSyncInfoStates": "Blok __displayBlock__ van __highestBlock__ aan het downloaden,
Chain structuur __displayState__ van __displayKnownStates__ aan het downloaden", "nodeSyncConnecting": "Zoeken naar peers...", - "stoppingNode": "Stopping Ethereum node...", - "nodeStarting": "Ethereum node starting up...", - "nodeStarted": "Ethereum node started", - "nodeConnected": "Ethereum node connected", - "nodeStopping": "Ethereum node stopping...", - "nodeStopped": "Ethereum node stopped", - "nodeError": "Ethereum node connection error :'(", - "unableToBindPort": "Ethereum node cannot run. Is another instance already running?", - "nodeSyncInfoStates": "Downloading block __displayBlock__ of __highestBlock__,
Downloading chain structure __displayState__ of __displayKnownStates__", - "nodeSyncFoundPeers": "Connecting to __peers__ peers...", - "nodeSyncingStopped": "Ethereum node sync stopped", - "peerSearchTimeout": "Skip peer search", - "launchApp": "Launch Application", + "nodeSyncFoundPeers": "Verbinden met __peers__ peers...", + "nodeSyncingStopped": "Ethereum node sync gestopt", + "peerSearchTimeout": "Sla peer search over", + "launchApp": "Applicatie Opstarten", "clientBinaries": { - "scanning": "Checking for node update...", - "downloading": "Downloading new node...", - "loadConfig": "Loading client config...", - "filtering": "Filtering client binaries...", + "scanning": "Controleren op node update...", + "downloading": "Downloaden van nieuwe node...", + "loadConfig": "Laden van client config...", + "filtering": "Filteren van client binaries...", "done": "Ethereum node up-to-date...", - "error": "Error running downloaded binary." + "error": "Fout bij het uitvoeren van de gedownloade binary." } }, "popupWindows": { + "updateAvailable": { + "newVersionAvailable": "Nieuwe __name__ versie beschikbaar", + "version": "Versie", + "downloadURL": "Download URL", + "checksum": "Checksum", + "downloadAndRestart": "Updaten en opnieuw opstarten", + "download": "Download nieuwe versie", + "skipUpdate": "Sla update over", + "notNow": "Vraag me later opnieuw", + "checking": "Controleren op updates voor __name__...", + "noUpdateFound": "Geen updates gevonden. Je hebt de laatste versie __name__." + }, "requestAccount": { "title": "Account aanmaken", "enterPassword": "Wachtwoord invoeren", "repeatPassword": "Wachtwoord herhalen", "creating": "Account genereren...", "errors": { - "passwordMismatch": "Uw wachtwoorden komen niet overeen.", - "passwordTooShort": "Make a longer password" + "passwordMismatch": "Je wachtwoorden komen niet overeen.", + "passwordTooShort": "Kies een langer wachtwoord" } }, "unlockMasterPassword": { - "title": "Voer meesterwachtwoord in", - "enterPassword": "Voer meesterwachtwoord in", + "title": "Voer hoofdwachtwoord in", + "enterPassword": "Voer hoofdwachtwoord in", "unlocking": "Ontgrendelen...", "errors": { "wrongPassword": "Wachtwoord is niet correct, probeer het nog eens." @@ -162,67 +196,71 @@ }, "sendTransactionConfirmation": { "title": { - "sendTransaction": "Send transaction", - "contractExecution": "Execute contract", - "createContract": "Create contract" + "sendTransaction": "Verzend transactie", + "contractExecution": "Voer contract uit", + "createContract": "Contract aanmaken" }, - "contractExecutionInfo": "U staat op het punt een functie uit te voeren op een contract. Dit kan overdrachten van waarde tot gevolg hebben.", - "contractCreationInfo": "U staat op het punt een contract aan te maken met de gegeven gevevens.", + "contractExecutionInfo": "Je staat op het punt een functie uit te voeren op een contract. Dit kan overdrachten van waarde tot gevolg hebben.", + "contractCreationInfo": "Je staat op het punt een contract aan te maken met de gegeven gevevens.", "enterPassword": "Voer wachtwoord in om de transactie te bevestigen", "unlocking": "Bevestigen...", "createContract": "Contract aanmaken", - "estimatedFee": "Ingeschatte kosten", - "estimatedGasError": "Data kon niet worden uitgevoerd, dus het zal alle mogelijke gas gebruiken.", + "estimatedFee": "Ingeschatte transactie kosten", + "estimatedGasError": "De kans is groot dat de transactie zal mislukken. Als je de transactie toch wilt uitvoeren zal misschien alle gas worden verbruikt.", + "transactionThrow": "Het contract staat niet toe dat deze transactie wordt uitgevoerd", + "noEstimate": "We konden de hoeveelheid gas niet inschatten.", "gasPrice": "Gas prijs", - "perMillionGas": "ether per millioen gas", - "gasLimit": "Geef maximum kosten aan", - "data": "Data", + "perMillionGas": "Ether per millioen gas", + "gasLimit": "Geef maximum transactie kosten aan", + "data": "Ruwe Data", + "parameters": "Parameters", "buttons": { "sendTransaction": "Verstuur transactie" }, "errors": { - "connectionTimeout": "Kon niet verbinden naar de node, is het in de achtergrond uitgevallen?", + "connectionTimeout": "Kon niet verbinden met de node, is het in de achtergrond uitgevallen?", "wrongPassword": "Onjuist wachtwoord", - "multipleKeysMatchAddress": "Multiple keys match address, please remove duplicates from keystore (menu -> accounts -> backup -> accounts)", - "insufficientFundsForGas": "Insufficient funds in main account (etherbase) to pay for gas", - "sameAccount": "Can't send to itself" + "multipleKeysMatchAddress": "Meerdere keys matchen hebben hetzelfde adres, verwijder duplicaten uit de keystore (menu -> accounts -> backup -> accounts)", + "insufficientFundsForGas": "Onvoldoende saldo in hoofd account (Etherbase) om gas te betalen", + "sameAccount": "Kan niet naar zichzelf versturen" }, - "transactionThrow": "The contract won't allow this transaction to be executed", - "noEstimate": "We couldn't estimate the gas.", - "parameters": "Parameters", - "showRawBytecode": "show raw data", - "showDecodedParameters": "show decoded parameters", - "lookupData": "Try to decode data", - "lookupDataExplainer": "Look this up on the internet" + "showRawBytecode": "Toon ruwe data", + "showDecodedParameters": "Toon gedecodeerde parameters", + "lookupData": "Probeer de data te decoderen", + "lookupDataExplainer": "Zoek hiernaar op het internet" }, "onboarding": { - "description": "Ethereum is een decentraal platform voor het bouwen van applicaties op een blockchain: software die immuun is voor fruide en levenslang waarde en eigendom over kan brengen", + "description": "Ethereum is een decentraal platform voor het bouwen van applicaties op een blockchain: software die immuun is voor fraude en levenslang waarde en eigendom over kan brengen", "goToTestnet": "Gebruik het test netwerk", - "goToTestnetDescription": "Test de technologie vrij in een testongeving, zonder echte ether te gebruiken.", + "goToTestnetDescription": "Test de technologie vrij in een testongeving, zonder echte Ether te gebruiken.", "gotoMainnet": "Gebruik hoofdnetwerk", - "gotoMainnetDescription": "U zal een beetje Ether nodig hebben om contracten uit te voeren. Geen zorgen, we helpen u met het verkrijgen...", - "doYouHaveAWalletFile": "Heeft u een wallet bestand?", - "walletFileDescription": "

Als u mee heeft gedaan met de Ethereum voorverkoop van 2014 zou u een bestand met de naam ethereum_wallet_backup.json ontvangen moeten hebben. U kon deze downloaden na uw contributie en is ook per email verstuurd

", + "gotoMainnetDescription": "Je zult een beetje Ether nodig hebben om contracten uit te voeren. Geen zorgen, we helpen je met het verkrijgen...", + "doYouHaveAWalletFile": "Heb je een wallet bestand?", + "walletFileDescription": "

Als je mee hebt gedaan met de Ethereum voorverkoop van 2014 zou je een bestand met de naam ethereum_wallet_backup.json ontvangen moeten hebben. Je kon dit bestand downloaden na je contributie en is ook per email verstuurd

", "dropFilesHere": "Sleep voorverkoop bestand hier", "creating": "Aanmaken...", "importing": "Importeren...", "skip": "Sla deze stap over", "next": "Volgende", - "protectTitle": "Bescherm uw account", - "protectDescription": "Kies een wachtwoord voor uw nieuwe account. Maak het even veilig alsof het uw huissleutels zijn!", + "protectTitle": "Bescherm je account", + "protectDescription": "Kies een wachtwoord voor je nieuwe account. Maak het even veilig alsof het uw huissleutels zijn!", "accountTitle": "Opladen!", "accountTitleTestnet": "Mine wat!", - "etherDescription": "Het ethereum netwerk is gebaseerd op het “Ether” token. U zal een kleine hoeveelheid nodig hebben om dingen op het netwerk te doen.", - "loadItDescription": "Als u al Bitcoins of een andere cryptocurrency heeft kan u deze makkelijk omzetten in ether met Shapeshift.

Wij raden aan een hoeveelheid van tussen de 0.25 en 1 ether om te zetten.", - "mineItDescription": "Op het testnetwerk kan u zelf ether minen door te gaan naar het Ontwikkelaars menu en te kiezen voor Begin Mining.
PROBEER GEEN ECHTE ETHER NAAR DIT ADRES TE VERSTUREN ", - "you": "U", - "etherbase": "Centrale account (etherbase)", + "etherDescription": "Het Ethereum netwerk is gebaseerd op het “Ether” token. Je zal een kleine hoeveelheid nodig hebben om dingen op het netwerk te doen.", + "loadItDescription": "Als je al Bitcoins of een andere cryptocurrency hebt kan je deze makkelijk inwisselen voor Ether met Shapeshift.

Wij raden aan een hoeveelheid van tussen de 0.25 en 1 Ether om te wisselen.", + "mineItDescription": "Op het testnetwerk kun je zelf Ether mijnen door te gaan naar het Ontwikkelaars menu en te kiezen voor Begin Mining.
PROBEER GEEN ECHTE ETHER NAAR DIT ADRES TE VERSTUREN ", + "you": "Je", + "etherbase": "Centrale account (Etherbase)", "depositBitcoin": "Bitcoin Storten", - "learnIt": "Leer terwijl u wacht", + "viaShapeshift": "Direct omwisselen via Shapeshift", + "learnIt": "Leer terwijl je wacht", "downloadingBlocks": "Blokken downloaden", - "tutorial1Description": "

Het enige wat er nog moet gebeuren is wachten tot de download compleet is. Hier zijn een aantal leessuggesties:

Maak uw eigen geld

Maak een cryptocurrency met een vaste uitgeveven hoeveelheid, tokens die vermogen uit de echte wereld voorstellen, etc

", + "syncMessage": "Blok __displayBlock__ van __highestBlockString__", + "syncMessageWithStates": "Blok __displayBlock__ van __highestBlockString__ (Chain structuur __statesPercent__%)", + "startingSync": "Wachten op synchronisatie..", + "tutorial1Description": "

Het enige wat er nog moet gebeuren is wachten tot de download compleet is. Hier zijn een aantal leessuggesties:

Maak je eigen geld

Maak een cryptocurrency met een vaste uitgeveven hoeveelheid, tokens die vermogen uit de echte wereld voorstellen, etc

", "tutorial2Description": "

Start een crowdsale

Haal geld op voor een gemeenschappelijk doel, volledig betrouwbaar zonder derde partij. Ga om het traditionele systeem heen en haal geld direct bij de bron op door een organisatie te crowdfunden via de blockchain

", - "tutorial3Description": "

Blockchain Organisatie

Maak een autonome organisatie aan met onbreekbare regels over het uitgeven van geld en wie beslissingen kan maken. Laat uw investeerders een actieve rol nemen in het besluiten hoe geld wordt uitgegeven

", + "tutorial3Description": "

Blockchain Organisatie

Maak een autonome organisatie aan met onbreekbare regels over het uitgeven van geld en wie beslissingen kan maken. Laat je investeerders een actieve rol nemen in het besluiten hoe geld wordt uitgegeven

", "buttons": { "showPassword": "Toon wachtwoord", "importAccount": "Importeer account", @@ -230,40 +268,25 @@ "learnReceipt": "Leer dit recept" }, "errors": { - "nodeNotStartedYet": "Wacht nog een aantal seconden tot uw node volledig is opgestart en probeer het nog een keer", + "nodeNotStartedYet": "Wacht nog een aantal seconden tot je node volledig is opgestart en probeer het nog een keer", "unknownFile": "Bestand niet herkent.", "wrongPassword": "Incorrect wachtwoord.", - "importFailed": "Kon bestand niet inporteren en kreeg: __error__" - }, - "viaShapeshift": "Instant conversion via Shapeshift", - "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" - }, - "updateAvailable": { - "newVersionAvailable": "New __name__ version available", - "version": "Version", - "downloadURL": "Download URL", - "checksum": "Checksum", - "downloadAndRestart": "Update and Restart", - "download": "Download new version", - "skipUpdate": "Skip Update", - "notNow": "Ask me later", - "checking": "Checking for updates to __name__...", - "noUpdateFound": "No update found. You are running the latest version of __name__." + "importFailed": "Bestand importeren mislukt: __error__" + } }, "connectAccount": { - "chooseAccountTitle": "Choose account", - "createAccount": "Create new account", - "pinToSidebar": "Pin app to the sidebar", - "connectAccountDescription": "You are sharing your identity with __dappName__. This allows the app to see any public information of your accounts, including balances connected to it." + "chooseAccountTitle": "Kies account", + "createAccount": "Creëer nieuw account", + "pinToSidebar": "Pin app aan de sidebar", + "connectAccountDescription": "Je deelt je indentiteit met __dappName__. Hierdoor heeft de app toegen tot alle openbare informatie van uw accounts inclusief de saldi." } } }, "elements": { - "checksumAlert": "Dit adres ziet er valide uit, maar het mist een aantal beveiligingsfuncties die u zullen beschermen teken typfouten, dus ga graag even na of dit de goede is. Als aangeveven, ga na of het beveiligingsicoon klopt.", + "checksumAlert": "Dit adres ziet er valide uit, maar het mist een aantal beveiligingsfuncties die je zullen beschermen teken typfouten, dus ga graag even na of dit de goede is. Als aangeveven, ga na of het beveiligingsicoon klopt.", "identiconHelper": "Dit is een beveilliginsicoon, als er enige veranderingen op dit adres plaats vinden dan zou er een volledig ander icoon moeten staan", "type": { - "address": "Address", + "address": "Adres", "bool": "Boolean", "int": "Integer", "uint": "Natural Number", diff --git a/interface/i18n/mist.pt.i18n.json b/interface/i18n/mist.pt.i18n.json index a6293987b..8a63a7806 100644 --- a/interface/i18n/mist.pt.i18n.json +++ b/interface/i18n/mist.pt.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Contas", - "importPresale": "Importar conta da pré-venda", + "importPresale": "Importar conta", "newAccount": "Nova conta", "backup": "Cópia de segurança", "backupKeyStore": "Contas", @@ -47,7 +47,11 @@ "mainNetwork": "Rede principal", "startMining": "⛏ Iniciar mineração (somente em teste)", "stopMining": "⛏ Parar mineração", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Janela", @@ -70,7 +74,7 @@ "linux": "Para instalar um servidor de tempo, instale \"ntp\" via \"apt-get install ntp\".", "darwin": "Abra suas preferências, escolha \"preferências de tempo\" e marque \"Ajustar o tempo automaticamente\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.ru.i18n.json b/interface/i18n/mist.ru.i18n.json index 8ce816d1f..7f4a73b8a 100644 --- a/interface/i18n/mist.ru.i18n.json +++ b/interface/i18n/mist.ru.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Аккаунты", - "importPresale": "Импорт предпродажных аккаунтов", + "importPresale": "Импорт аккаунтов", "newAccount": "Создать аккаунт", "backup": "Резервное копирование", "backupKeyStore": "Аккаунтов", @@ -47,7 +47,11 @@ "mainNetwork": "Основная сеть", "startMining": "⛏ Запустить майнинг (только для тестовой сети)", "stopMining": "⛏ Остановить майнинг", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Окно", @@ -70,7 +74,7 @@ "linux": "Чтобы использовать сервер синхронизации времени установите \"ntp\" через команду \"apt-get install ntp\".", "darwin": "Для включения синхронизации времени откройте системные настройки и укажите: \"Устанавливать время и дату автоматически\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -239,19 +243,24 @@ "wrongPassword": "Неверный пароль.", "importFailed": "Не удалось импортировать файл, дополнительно: __error__" }, - "accountTitleTestnet": "Mine some!" - }, - "clientUpdateAvailable": { - "downloadAndRestart": "Update and Restart", - "download": "Update", - "skipUpdate": "Skip Update", - "newVersionAvailable": "New Ethereum node versions are available!" + "accountTitleTestnet": "Mine some!", + "startingSync": "Getting ready to sync.." }, "connectAccount": { "chooseAccountTitle": "Choose account", "createAccount": "Create new account", "pinToSidebar": "Pin app to the sidebar", "connectAccountDescription": "You are sharing your identity with __dappName__. This allows the app to see any public information of your accounts, including balances connected to it." + }, + "requestAccount": { + "title": "Create account", + "enterPassword": "Enter password", + "repeatPassword": "Repeat password", + "creating": "Generating account...", + "errors": { + "passwordMismatch": "Your passwords don't match.", + "passwordTooShort": "Make a longer password" + } } } }, @@ -267,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.sq.i18n.json b/interface/i18n/mist.sq.i18n.json index c8312af25..8f7713eaa 100644 --- a/interface/i18n/mist.sq.i18n.json +++ b/interface/i18n/mist.sq.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "Llogari", - "importPresale": "Merr llogari të para-shitur", + "importPresale": "Merr llogari", "newAccount": "Llogari e re", "backup": "Ruaj një kopje rezervë", "backupKeyStore": "Llogari", @@ -47,7 +47,11 @@ "mainNetwork": "Rrjeti kryesor", "startMining": "⛏ Fillo të Prodhosh (Rrjet testimi)", "stopMining": "⛏ Ndalo së Prodhuari", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "Dritare", @@ -70,7 +74,7 @@ "linux": "Që të fusni në punë një server kohe të sinkronizuar instaloni \"ntp\" nëpërmjet \"apt-get install ntp\".", "darwin": "Që të mundësoni një sinkronizim kohe, hapni preferencat e kohes dhe përzgjidhni \"Set the time and date automatically\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", diff --git a/interface/i18n/mist.zh-TW.i18n.json b/interface/i18n/mist.zh-TW.i18n.json index eb33f3286..0a204209c 100644 --- a/interface/i18n/mist.zh-TW.i18n.json +++ b/interface/i18n/mist.zh-TW.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "帳號", - "importPresale": "導入預售帳號", + "importPresale": "導入帳號", "newAccount": "新建帳號", "backup": "備份", "backupKeyStore": "帳號", @@ -47,7 +47,11 @@ "mainNetwork": "主網路", "startMining": "⛏ 開啓挖礦(僅限Testnet網路)", "stopMining": "⛏ 停止挖礦", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "視窗", @@ -70,7 +74,7 @@ "linux": "爲開啓時間同步伺服器,請通過\"apt-get install ntp\"安裝\"ntp\"。", "darwin": "爲開啓時間同步,打開時間選項並勾選\"Set the time and date automatically\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/interface/i18n/mist.zh.i18n.json b/interface/i18n/mist.zh.i18n.json index fb2754d7d..32b67136a 100644 --- a/interface/i18n/mist.zh.i18n.json +++ b/interface/i18n/mist.zh.i18n.json @@ -28,7 +28,7 @@ }, "accounts": { "label": "账户", - "importPresale": "导入预售账户", + "importPresale": "导入账户", "newAccount": "新建账户", "backup": "备份", "backupKeyStore": "账户", @@ -47,7 +47,11 @@ "mainNetwork": "主网络", "startMining": "⛏ 开启挖矿(仅限Testnet网络)", "stopMining": "⛏ 停止挖矿", - "externalNode": "using external node" + "externalNode": "using external node", + "openRemix": "Open Remix IDE", + "nodeMode": "Chain download", + "fullNode": "Store full blockchain", + "lightNode": "Use light Node (experimental!)" }, "window": { "label": "窗口", @@ -70,7 +74,7 @@ "linux": "为开启时间同步服务器,请通过\"apt-get install ntp\"安装\"ntp\"。", "darwin": "为开启时间同步,打开时间选项并勾选\"Set the time and date automatically\"." }, - "nodeChecksumMismatch": { + "nodeChecksumMismatch": { "title": "Checksum mismatch in downloaded node!", "description": "__algorithm__: __hash__\n\nPlease install the __type__ node version __version__ manually." }, @@ -237,7 +241,8 @@ }, "viaShapeshift": "Instant conversion via Shapeshift", "syncMessage": "Block __displayBlock__ of __highestBlockString__", - "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)" + "syncMessageWithStates": "Block __displayBlock__ of __highestBlockString__ (Chain structure __statesPercent__%)", + "startingSync": "Getting ready to sync.." }, "updateAvailable": { "newVersionAvailable": "New __name__ version available", @@ -271,4 +276,4 @@ "bytes": "Bytes" } } -} +} \ No newline at end of file diff --git a/main.js b/main.js index 302a1662e..b11a553b6 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,3 @@ -const squirrelStartup = require('electron-squirrel-startup'); -// windows only: don't run app during squirrel-install -function exit() { return; } -if (squirrelStartup) exit(); - global._ = require('./modules/utils/underscore'); const { app, dialog, ipcMain, shell } = require('electron'); @@ -415,7 +410,7 @@ onReady = () => { splashWindow.show(); } - if (Settings.inAutoTestMode) { + if (!Settings.inAutoTestMode) { return syncResultPromise; } diff --git a/modules/clientBinaryManager.js b/modules/clientBinaryManager.js index 7cb5c5e1a..0fa9b5817 100644 --- a/modules/clientBinaryManager.js +++ b/modules/clientBinaryManager.js @@ -73,6 +73,8 @@ class Manager extends EventEmitter { log.warn('Error fetching client binaries config from repo', err); }) .then((latestConfig) => { + if(!latestConfig) return; + let localConfig; let skipedVersion; const nodeVersion = latestConfig.clients[nodeType].version; @@ -178,7 +180,9 @@ class Manager extends EventEmitter { .then((localConfig) => { if (!localConfig) { log.info('No config for the ClientBinaryManager could be loaded, using local clientBinaries.json.'); - localConfig = require('../clientBinaries.json'); + + const localConfigPath = path.join(Settings.userDataPath, 'clientBinaries.json'); + localConfig = (fs.existsSync(localConfigPath)) ? require(localConfigPath) : require('../clientBinaries.json'); // eslint-disable-line no-param-reassign, global-require, import/no-dynamic-require, import/no-unresolved } // scan for node diff --git a/modules/db.js b/modules/db.js index 3b5fbd102..c7d95ce58 100644 --- a/modules/db.js +++ b/modules/db.js @@ -1,5 +1,4 @@ const fs = require('fs'); -const path = require('path'); const Q = require('bluebird'); const Loki = require('lokijs'); const Settings = require('./settings'); @@ -10,7 +9,7 @@ let db; exports.init = () => { - const filePath = path.join(Settings.userDataPath, 'mist.lokidb'); + const filePath = Settings.dbFilePath; return Q.try(() => { // if db file doesn't exist then create it diff --git a/modules/dbSync.js b/modules/dbSync.js index eda6e81f8..b21f9b22d 100644 --- a/modules/dbSync.js +++ b/modules/dbSync.js @@ -14,13 +14,13 @@ exports.backendSyncInit = function () { ipc.on('dbSync-add', (event, args) => { let collName = args.collName, - coll = db.getCollection('UI_'+ collName); + coll = db.getCollection(`UI_${collName}`); log.trace('dbSync-add', collName, args._id); const _id = args._id; - if (!coll.by("_id", _id)) { + if (!coll.by('_id', _id)) { args.fields._id = _id; coll.insert(args.fields); } @@ -28,12 +28,12 @@ exports.backendSyncInit = function () { ipc.on('dbSync-changed', (event, args) => { let collName = args.collName, - coll = db.getCollection('UI_'+ collName); + coll = db.getCollection(`UI_${collName}`); log.trace('dbSync-changed', collName, args._id); const _id = args._id; - const item = coll.by("_id", _id); + const item = coll.by('_id', _id); if (item) { for (const k in args.fields) { @@ -50,12 +50,12 @@ exports.backendSyncInit = function () { ipc.on('dbSync-removed', (event, args) => { let collName = args.collName, - coll = db.getCollection('UI_'+ collName); + coll = db.getCollection(`UI_${collName}`); log.trace('dbSync-removed', collName, args._id); const _id = args._id; - const item = coll.by("_id", _id); + const item = coll.by('_id', _id); if (item) { coll.remove(item); @@ -67,7 +67,7 @@ exports.backendSyncInit = function () { // Get all data (synchronous) ipc.on('dbSync-reloadSync', (event, args) => { let collName = args.collName, - coll = db.getCollection('UI_'+ collName), + coll = db.getCollection(`UI_${collName}`), docs = coll.find(); log.debug('dbSync-reloadSync, no. of docs:', collName, docs.length); @@ -88,15 +88,15 @@ exports.backendSyncInit = function () { }); }; -var syncDataFromBackend = function(coll){ - let ipc = ipcRenderer; +const syncDataFromBackend = function (coll) { + const ipc = ipcRenderer; - let collName = coll._name; + const collName = coll._name; console.debug('Load collection data from backend: ', collName); return new Promise((resolve, reject) => { - let dataJson = ipc.sendSync('dbSync-reloadSync', { + const dataJson = ipc.sendSync('dbSync-reloadSync', { collName, }); @@ -105,8 +105,9 @@ var syncDataFromBackend = function(coll){ coll.remove({}); - if(!dataJson.length) + if (!dataJson.length) { resolve(); + } // we do inserts slowly, to avoid race conditions when it comes // to updating the UI @@ -120,10 +121,11 @@ var syncDataFromBackend = function(coll){ record.redirect = null; } - if(record._id) + if (record._id) { coll.upsert(record._id, record); - else + } else { coll.insert(record); + } } catch (err) { console.error(err.toString()); } @@ -138,7 +140,7 @@ var syncDataFromBackend = function(coll){ } catch (err) { reject(err); } - }) + }); }; exports.syncDataFromBackend = syncDataFromBackend; @@ -146,8 +148,8 @@ exports.frontendSyncInit = function (coll) { let ipc = ipcRenderer, syncDoneResolver; - let collName = coll._name; - + const collName = coll._name; + coll.onceSynced = new Promise((resolve, reject) => { syncDoneResolver = resolve; }); diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index 2932dac0a..b37c67e8e 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -315,13 +315,14 @@ class EthereumNode extends EventEmitter { this._network = network; this._type = nodeType; - let client = ClientBinaryManager.getClient(nodeType); + const client = ClientBinaryManager.getClient(nodeType); let binPath; - if(client) + if (client) { binPath = client.binPath; - else + } else { throw new Error(`Node "${nodeType}" binPath is not available.`); + } log.info(`Start node using ${binPath}`); @@ -358,7 +359,7 @@ class EthereumNode extends EventEmitter { // START MAINNET else { args = (nodeType === 'geth') - ? ['--fast', '--cache', '1024'] + ? ['--fast', '--cache', '1024'] : ['--unsafe-transactions']; } diff --git a/modules/ipc/dechunker.js b/modules/ipc/dechunker.js index a77e54866..3bf74b22c 100644 --- a/modules/ipc/dechunker.js +++ b/modules/ipc/dechunker.js @@ -39,8 +39,9 @@ module.exports = class Dechunker { return _.each(dechunkedData, (data) => { // prepend the last chunk - if (this.lastChunk) - { data = this.lastChunk + data; } + if (this.lastChunk) { + data = this.lastChunk + data; + } let result = data; diff --git a/modules/ipc/ipcProviderBackend.js b/modules/ipc/ipcProviderBackend.js index 8ce1b4040..ee9bb46d3 100644 --- a/modules/ipc/ipcProviderBackend.js +++ b/modules/ipc/ipcProviderBackend.js @@ -20,7 +20,7 @@ const Windows = require('../windows'); const ERRORS = { - INVALID_PAYLOAD: { code: -32600, message: 'Payload invalid.' }, + INVALID_PAYLOAD: { code: -32600, message: 'Payload, or some of its content properties are invalid. Please check if they are valid HEX.' }, METHOD_DENIED: { code: -32601, message: "Method \'__method__\' not allowed." }, METHOD_TIMEOUT: { code: -32603, message: "Request timed out for method \'__method__\'." }, TX_DENIED: { code: -32603, message: 'Transaction denied' }, @@ -100,8 +100,7 @@ class IpcProviderBackend { socket.destroy().finally(() => { - if(!owner.isDestroyed()) - owner.send(`ipcProvider-${ev}`, JSON.stringify(data)); + if (!owner.isDestroyed()) { owner.send(`ipcProvider-${ev}`, JSON.stringify(data)); } }); delete this._connections[ownerId]; @@ -110,8 +109,9 @@ class IpcProviderBackend { }); socket.on('connect', (data) => { - if(!owner.isDestroyed()) + if (!owner.isDestroyed()) { owner.send('ipcProvider-connect', JSON.stringify(data)); + } }); // pass notifications back up the chain @@ -124,8 +124,9 @@ class IpcProviderBackend { data = this._makeResponsePayload(data, data); } - if(!owner.isDestroyed()) + if (!owner.isDestroyed()) { owner.send('ipcProvider-data', JSON.stringify(data)); + } }); } }) @@ -172,8 +173,9 @@ class IpcProviderBackend { } }) .then(() => { - if(!owner.isDestroyed()) + if (!owner.isDestroyed()) { owner.send('ipcProvider-setWritable', true); + } return this._connections[ownerId]; }); @@ -356,7 +358,7 @@ class IpcProviderBackend { if (isSync) { event.returnValue = returnValue; - } else if(!event.sender.isDestroyed()) { + } else if (!event.sender.isDestroyed()) { event.sender.send('ipcProvider-data', returnValue); } }); diff --git a/modules/ipc/methods/eth_sendTransaction.js b/modules/ipc/methods/eth_sendTransaction.js index fc90f073f..d6e4b29b2 100644 --- a/modules/ipc/methods/eth_sendTransaction.js +++ b/modules/ipc/methods/eth_sendTransaction.js @@ -34,13 +34,19 @@ module.exports = class extends BaseProcessor { // validate data try { - _.each(payload.params[0], (val) => { + _.each(payload.params[0], (val, key) => { // if doesn't have hex then leave if (_.isString(val)) { + + // make sure all data is lowercase and has 0x + if (val) val = `0x${val.toLowerCase().replace('0x', '')}`; + if (val.match(/[^0-9a-fx]/igm)) { throw this.ERRORS.INVALID_PAYLOAD; } } + + payload.params[0][key] = val; }); } catch (err) { return reject(err); @@ -70,8 +76,7 @@ module.exports = class extends BaseProcessor { ipc.once('backendAction_unlockedAccountAndSentTransaction', (ev, err, result) => { if (Windows.getById(ev.sender.id) === modalWindow - && !modalWindow.isClosed) - { + && !modalWindow.isClosed) { if (err || !result) { this._log.debug('Confirmation error', err); diff --git a/modules/ipcCommunicator.js b/modules/ipcCommunicator.js index a833daea5..0d0affe35 100644 --- a/modules/ipcCommunicator.js +++ b/modules/ipcCommunicator.js @@ -5,10 +5,14 @@ Window communication */ const _ = global._; +const fs = require('fs'); const { app, ipcMain: ipc, shell, webContents } = require('electron'); const Windows = require('./windows'); const logger = require('./utils/logger'); const appMenu = require('./menuItems'); +const Settings = require('./settings'); +const ethereumNode = require('./ethereumNode.js'); +const keyfileRecognizer = require('ethereum-keyfile-recognizer'); const log = logger.create('ipcCommunicator'); @@ -62,7 +66,7 @@ ipc.on('backendAction_windowCallback', (e, value1, value2, value3) => { const windowId = e.sender.id; const senderWindow = Windows.getById(windowId); - if(senderWindow.callback) { + if (senderWindow.callback) { senderWindow.callback(value1, value2, value3); } }); @@ -100,48 +104,99 @@ ipc.on('backendAction_setLanguage', (e, lang) => { ipc.on('backendAction_stopWebviewNavigation', (e, id) => { console.log('webcontent ID', id); - var webContent = webContents.fromId(id); + const webContent = webContents.fromId(id); - if(webContent && !webContent.isDestroyed()) + if (webContent && !webContent.isDestroyed()) { webContent.stop(); + } e.returnValue = true; }); +// check wallet file +ipc.on('backendAction_checkWalletFile', (e, path) => { + + log.warn(111); + fs.readFile(path, 'utf8', (event, data) => { + try { + const wallet = JSON.parse(data); + const result = keyfileRecognizer(wallet); + /** result + * [ 'ethersale', undefined ] Ethersale keyfile + * [ 'web3', 3 ] web3 (v3) keyfile + * null no valid keyfile + */ + + if (_.first(result) === 'ethersale') { + e.sender.send('uiAction_checkedWalletFile', null, 'presale'); + } else if (_.first(result) === 'web3') { + e.sender.send('uiAction_checkedWalletFile', null, 'web3'); + + let keystorePath = Settings.userHomePath; + // eth + if (ethereumNode.isEth) { + if (process.platform === 'win32') { + keystorePath = `${Settings.appDataPath}\\Web3\\keys`; + } else { + keystorePath += '/.web3/keys'; + } + // geth + } else { + if (process.platform === 'darwin') keystorePath += '/Library/Ethereum/keystore'; + + if (process.platform === 'freebsd' || + process.platform === 'linux' || + process.platform === 'sunos') keystorePath += '/.ethereum/keystore'; + + if (process.platform === 'win32') keystorePath = `${Settings.appDataPath}\\Ethereum\\keystore`; + } + + fs.writeFile(`${keystorePath}/0x${wallet.address}`, data, (err) => { + if (err) throw new Error("Can't write file to disk"); + }); + } else { + throw new Error('Wallet import: Cannot recognize keyfile'); + } + } catch (err) { + e.sender.send('uiAction_checkedWalletFile', null, 'invalid'); + log.error(err); + } + }); +}); + -// import presale file -ipc.on('backendAction_importPresaleFile', (e, path, pw) => { - const spawn = require('child_process').spawn; - const ClientBinaryManager = require('./clientBinaryManager'); +// import presale wallet +ipc.on('backendAction_importWalletFile', (e, path, pw) => { + const spawn = require('child_process').spawn; // eslint-disable-line global-require + const ClientBinaryManager = require('./clientBinaryManager'); // eslint-disable-line global-require let error = false; const binPath = ClientBinaryManager.getClient('geth').binPath; - - // start import process const nodeProcess = spawn(binPath, ['wallet', 'import', path]); nodeProcess.once('error', () => { error = true; - e.sender.send('uiAction_importedPresaleFile', 'Couldn\'t start the "geth wallet import " process.'); + e.sender.send('uiAction_importedWalletFile', 'Couldn\'t start the "geth wallet import " process.'); }); - nodeProcess.stdout.on('data', (data) => { - var data = data.toString(); - if (data) - { log.info('Imported presale: ', data); } + nodeProcess.stdout.on('data', (_data) => { + const data = _data.toString(); + if (data) { + log.info('Imported presale: ', data); + } if (/Decryption failed|not equal to expected addr|could not decrypt/.test(data)) { - e.sender.send('uiAction_importedPresaleFile', 'Decryption Failed'); + e.sender.send('uiAction_importedWalletFile', 'Decryption Failed'); - // if imported, return the address + // if imported, return the address } else if (data.indexOf('Address:') !== -1) { const find = data.match(/\{([a-f0-9]+)\}/i); if (find.length && find[1]) { - e.sender.send('uiAction_importedPresaleFile', null, `0x${find[1]}`); + e.sender.send('uiAction_importedWalletFile', null, `0x${find[1]}`); } else { - e.sender.send('uiAction_importedPresaleFile', data); + e.sender.send('uiAction_importedWalletFile', data); } - // if not stop, so we don't kill the process + // if not stop, so we don't kill the process } else { return; } @@ -155,7 +210,7 @@ ipc.on('backendAction_importPresaleFile', (e, path, pw) => { setTimeout(() => { if (!error) { nodeProcess.stdin.write(`${pw}\n`); - pw = null; + pw = null; // eslint-disable-line no-param-reassign } }, 2000); }); @@ -183,7 +238,7 @@ ipc.on('mistAPI_requestAccount', (e) => { ownerId: e.sender.id, electronOptions: { width: 460, - height: 497, + height: 520, maximizable: false, minimizable: false, alwaysOnTop: true, diff --git a/modules/menuItems.js b/modules/menuItems.js index 39b26a8c2..7545068dd 100644 --- a/modules/menuItems.js +++ b/modules/menuItems.js @@ -13,10 +13,10 @@ const ClientBinaryManager = require('./clientBinaryManager'); const switchForSystem = function (options) { if (process.platform in options) { return options[process.platform]; - } - else if ('default' in options) { + } else if ('default' in options) { return options.default; } + return null; }; @@ -298,7 +298,7 @@ let menuTempl = function (webviews) { // DEVELOP - let devToolsMenu = []; + const devToolsMenu = []; // change for wallet if (Settings.uiMode === 'mist') { @@ -338,16 +338,40 @@ let menuTempl = function (webviews) { } const externalNodeMsg = (ethereumNode.isOwnNode) ? '' : ` (${i18n.t('mist.applicationMenu.develop.externalNode')})`; - devToolsMenu = [{ + devToolsMenu.push({ label: i18n.t('mist.applicationMenu.develop.devTools'), submenu: devtToolsSubMenu, - }, { + }); + + if (Settings.uiMode === 'mist') { + devToolsMenu.push({ + label: i18n.t('mist.applicationMenu.develop.openRemix'), + enabled: true, + click() { + Windows.createPopup('remix', { + url: 'https://remix.ethereum.org', + electronOptions: { + width: 1024, + height: 720, + center: true, + frame: true, + resizable: true, + titleBarStyle: 'default', + } + }); + }, + }); + } + + devToolsMenu.push({ label: i18n.t('mist.applicationMenu.develop.runTests'), enabled: (Settings.uiMode === 'mist'), click() { Windows.getByType('main').send('uiAction_runTests', 'webview'); }, - }, { + }); + + devToolsMenu.push({ label: i18n.t('mist.applicationMenu.develop.logFiles') + externalNodeMsg, enabled: ethereumNode.isOwnNode, click() { @@ -358,9 +382,7 @@ let menuTempl = function (webviews) { log = 'Couldn\'t load log file.'; } }, - }, - ]; - + }); // add node switching menu devToolsMenu.push({ diff --git a/modules/nodeSync.js b/modules/nodeSync.js index 294ffca8e..558b19584 100644 --- a/modules/nodeSync.js +++ b/modules/nodeSync.js @@ -149,7 +149,7 @@ class NodeSync extends EventEmitter { const diff = now - +blockResult.timestamp; - log.debug(`Last block: ${blockResult.number}, ${diff}s ago`); + log.debug(`Last block: ${Number(blockResult.number)}, ${diff}s ago`); // need sync if > 1 minute if (diff > 60) { diff --git a/modules/preloader/browser.js b/modules/preloader/browser.js index 92b1241e5..1ba237466 100644 --- a/modules/preloader/browser.js +++ b/modules/preloader/browser.js @@ -18,7 +18,7 @@ ipcRenderer.sendToHost('setWebviewId'); ipcRenderer.send('ipcProvider-destroy'); // Security -process.on('loaded',function () { +process.on('loaded', function () { Object.freeze(window.JSON); // Object.freeze(window.Function); // Object.freeze(window.Function.prototype); diff --git a/modules/preloader/include/getFavicon.js b/modules/preloader/include/getFavicon.js index 6e67db48f..be7e26f2d 100644 --- a/modules/preloader/include/getFavicon.js +++ b/modules/preloader/include/getFavicon.js @@ -12,10 +12,11 @@ const { ipcRenderer } = require('electron'); function DOMContentLoaded(event) { const icon = document.querySelector('link[rel="apple-touch-icon"]') || document.querySelector('link[type="image/x-icon"]') || document.querySelector('link[rel="shortcut"]') || document.querySelector('link[rel="shortcut icon"]') || document.querySelector('link[rel="icon"]'); - if (icon) - { ipcRenderer.sendToHost('favicon', icon.href); } - else - { ipcRenderer.sendToHost('favicon', null); } + if (icon) { + ipcRenderer.sendToHost('favicon', icon.href); + } else { + ipcRenderer.sendToHost('favicon', null); + } document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false); } diff --git a/modules/preloader/include/getMetaTags.js b/modules/preloader/include/getMetaTags.js index 233a1260b..6186ddade 100644 --- a/modules/preloader/include/getMetaTags.js +++ b/modules/preloader/include/getMetaTags.js @@ -4,7 +4,7 @@ Gest the meta[name="ethereum-dapp-url-bar-style"] meta tag @module getMetaTags */ -const { ipcRenderer } = require('electron'); +const { ipcRenderer } = require('electron'); module.export = (function () { document.addEventListener('DOMContentLoaded', DOMContentLoaded, false); @@ -12,10 +12,11 @@ module.export = (function () { function DOMContentLoaded(event) { const appBar = document.querySelector('meta[name="ethereum-dapp-url-bar-style"]'); - if (appBar) - { ipcRenderer.sendToHost('appBar', appBar.content); } - else - { ipcRenderer.sendToHost('appBar', null); } + if (appBar) { + ipcRenderer.sendToHost('appBar', appBar.content); + } else { + ipcRenderer.sendToHost('appBar', null); + } document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false); } diff --git a/modules/preloader/include/mistAPI.js b/modules/preloader/include/mistAPI.js index bd2389128..d931ac38a 100644 --- a/modules/preloader/include/mistAPI.js +++ b/modules/preloader/include/mistAPI.js @@ -56,6 +56,9 @@ module.exports = () => { ipcRenderer.send('mistAPI_requestAccount'); }, + solidity: { + version: String(packageJson.dependencies.solc).match(/\d+\.\d+\.\d+/)[0], + }, sounds: { bip: function playSound() { ipcRenderer.sendToHost('mistAPI_sound', `file://${__dirname}/../../../sounds/bip.mp3`); @@ -102,7 +105,7 @@ module.exports = () => { @param {Function} callback Change the callback to be called when the menu is pressed. */ add(id, options, callback) { - var args = Array.prototype.slice.call(arguments); + const args = Array.prototype.slice.call(arguments); callback = _.isFunction(args[args.length - 1]) ? args.pop() : null; options = _.isObject(args[args.length - 1]) ? args.pop() : null; id = _.isString(args[args.length - 1]) || _.isFinite(args[args.length - 1]) ? args.pop() : null; diff --git a/modules/preloader/include/openExternal.js b/modules/preloader/include/openExternal.js index 962eebb19..b4f484d64 100644 --- a/modules/preloader/include/openExternal.js +++ b/modules/preloader/include/openExternal.js @@ -12,10 +12,11 @@ document.addEventListener('click', (e) => { let node = false; - if (e.target.nodeName === 'A') - { node = e.target; } - else if (e.target.parentNode && e.target.parentNode.nodeName === 'A') - { node = e.target.parentNode; } + if (e.target.nodeName === 'A') { + node = e.target; + } else if (e.target.parentNode && e.target.parentNode.nodeName === 'A') { + node = e.target.parentNode; + } // open in browser if (node && node.attributes.target && node.attributes.target.value === '_blank') { diff --git a/modules/preloader/include/openPopup.js b/modules/preloader/include/openPopup.js index 54a1e1278..ddaa73720 100644 --- a/modules/preloader/include/openPopup.js +++ b/modules/preloader/include/openPopup.js @@ -10,10 +10,11 @@ const { remote } = require('electron'); document.addEventListener('click', (e) => { let node = false; - if (e.target.nodeName === 'A') - { node = e.target; } - else if (e.target.parentNode && e.target.parentNode.nodeName === 'A') - { node = e.target.parentNode; } + if (e.target.nodeName === 'A') { + node = e.target; + } else if (e.target.parentNode && e.target.parentNode.nodeName === 'A') { + node = e.target.parentNode; + } // open popup if (node && node.attributes.target && node.attributes.target.value === '_popup') { @@ -25,6 +26,6 @@ document.addEventListener('click', (e) => { nodeIntegration: false, } }); - win.loadURL(node.href, true); + win.loadURL(node.href); } }, false); diff --git a/modules/preloader/mistUI.js b/modules/preloader/mistUI.js index b1dd85be2..a42f50508 100644 --- a/modules/preloader/mistUI.js +++ b/modules/preloader/mistUI.js @@ -56,11 +56,12 @@ ipcRenderer.on('uiAction_windowMessage', (e, type, id, error, value) => { } // forward to the webview (TODO: remove and manage in the ipcCommunicator?) - var tab = Tabs.findOne({ webviewId: id }); - if(tab) { - webview = $('webview[data-id='+ tab._id +']')[0]; - if(webview) + const tab = Tabs.findOne({ webviewId: id }); + if (tab) { + webview = $(`webview[data-id=${tab._id}]`)[0]; + if (webview) { webview.send('uiAction_windowMessage', type, error, value); + } } }); @@ -73,20 +74,22 @@ ipcRenderer.on('uiAction_enableBlurOverlay', (e, value) => { ipcRenderer.on('uiAction_toggleWebviewDevTool', (e, id) => { const webview = Helpers.getWebview(id); - if (!webview) - { return; } + if (!webview) { + return; + } - if (webview.isDevToolsOpened()) - { webview.closeDevTools(); } - else - { webview.openDevTools(); } + if (webview.isDevToolsOpened()) { + webview.closeDevTools(); + } else { + webview.openDevTools(); + } }); // randomize accounts and drop half // also certainly remove the web3.ethbase one -var randomizeAccounts = (acc, coinbase) => { - var accounts = _.shuffle(acc); +const randomizeAccounts = (acc, coinbase) => { + let accounts = _.shuffle(acc); accounts = _.rest(accounts, (accounts.length / 2).toFixed(0)); accounts = _.without(accounts, coinbase); return accounts; @@ -117,7 +120,7 @@ ipcRenderer.on('uiAction_runTests', (e, type) => { // update the permissions, when accounts change Tracker.autorun(() => { - var accountList = _.pluck(EthAccounts.find({}, { fields: { address: 1 } }).fetch(), 'address'); + const accountList = _.pluck(EthAccounts.find({}, { fields: { address: 1 } }).fetch(), 'address'); Tabs.update('tests', { $set: { 'permissions.accounts': randomizeAccounts(accountList, coinbase), @@ -128,7 +131,6 @@ ipcRenderer.on('uiAction_runTests', (e, type) => { } }); - // CONTEXT MENU const currentMousePosition = { x: 0, y: 0 }; @@ -136,18 +138,21 @@ const menu = new Menu(); // menu.append(new MenuItem({ type: 'separator' })); menu.append(new MenuItem({ label: i18n.t('mist.rightClick.reload'), accelerator: 'Command+R', click() { const webview = Helpers.getWebview(LocalStore.get('selectedTab')); - if (webview) - { webview.reloadIgnoringCache(); } + if (webview) { + webview.reloadIgnoringCache(); + } } })); menu.append(new MenuItem({ label: i18n.t('mist.rightClick.openDevTools'), click() { const webview = Helpers.getWebview(LocalStore.get('selectedTab')); - if (webview) - { webview.openDevTools(); } + if (webview) { + webview.openDevTools(); + } } })); menu.append(new MenuItem({ label: i18n.t('mist.rightClick.inspectElements'), click() { const webview = Helpers.getWebview(LocalStore.get('selectedTab')); - if (webview) - { webview.inspectElement(currentMousePosition.x, currentMousePosition.y); } + if (webview) { + webview.inspectElement(currentMousePosition.x, currentMousePosition.y); + } } })); @@ -167,7 +172,8 @@ document.addEventListener('keydown', (e) => { // RELOAD current webview if (e.metaKey && e.keyCode === 82) { const webview = Helpers.getWebview(LocalStore.get('selectedTab')); - if (webview) - { webview.reloadIgnoringCache(); } + if (webview) { + webview.reloadIgnoringCache(); + } } }, false); diff --git a/modules/preloader/walletMain.js b/modules/preloader/walletMain.js index 9b4909579..7bb9115f8 100644 --- a/modules/preloader/walletMain.js +++ b/modules/preloader/walletMain.js @@ -17,6 +17,7 @@ setTimeout(() => { }, 1000); setTimeout(() => { - if (document.getElementsByTagName('html')[0]) - { document.getElementsByTagName('html')[0].className = window.platform; } + if (document.getElementsByTagName('html')[0]) { + document.getElementsByTagName('html')[0].className = window.platform; + } }, 500); diff --git a/modules/settings.js b/modules/settings.js index 353cc0fb4..6f81ff7ec 100644 --- a/modules/settings.js +++ b/modules/settings.js @@ -156,6 +156,11 @@ class Settings { return app.getPath('userData'); } + get dbFilePath() { + const dbFileName = (this.inAutoTestMode) ? 'mist.test.lokidb' : 'mist.lokidb'; + return path.join(this.userDataPath, dbFileName); + } + get appDataPath() { // Application Support/ return app.getPath('appData'); diff --git a/modules/web3Admin.js b/modules/web3Admin.js index cde4400a7..b0bc656ae 100644 --- a/modules/web3Admin.js +++ b/modules/web3Admin.js @@ -13,7 +13,7 @@ module.exports = { property: 'admin', methods: [ - insertMethod('addPeer', 'admin_addPeer', 1, [web3._extend.utils.fromDecimal], web3._extend.formatters.formatOutputBool), + insertMethod('addPeer', 'admin_addPeer', 1, [null], web3._extend.formatters.formatOutputBool), insertMethod('exportChain', 'admin_exportChain', 1, [null], null), insertMethod('importChain', 'admin_importChain', 1, [null], null), insertMethod('verbosity', 'admin_verbosity', 1, [web3._extend.utils.formatInputInt], web3._extend.formatters.formatOutputBool), @@ -52,8 +52,8 @@ module.exports = { [ insertMethod('start', 'miner_start', 1, [web3._extend.formatters.formatInputInt], web3._extend.formatters.formatOutputBool), insertMethod('stop', 'miner_stop', 1, [web3._extend.formatters.formatInputInt], web3._extend.formatters.formatOutputBool), - insertMethod('setExtra', 'miner_setExtra', 1, [web3._extend.utils.formatInputString], web3._extend.formatters.formatOutputBool), - insertMethod('setGasPrice', 'miner_setGasPrice', 1, [web3._extend.utils.formatInputString], web3._extend.formatters.formatOutputBool), + insertMethod('setExtra', 'miner_setExtra', 1, [null], web3._extend.formatters.formatOutputBool), + insertMethod('setGasPrice', 'miner_setGasPrice', 1, [web3._extend.utils.fromDecimal], web3._extend.formatters.formatOutputBool), insertMethod('startAutoDAG', 'miner_startAutoDAG', 0, [], web3._extend.formatters.formatOutputBool), insertMethod('stopAutoDAG', 'miner_stopAutoDAG', 0, [], web3._extend.formatters.formatOutputBool), insertMethod('makeDAG', 'miner_makeDAG', 1, [web3._extend.formatters.inputDefaultBlockNumberFormatter], web3._extend.formatters.formatOutputBool), @@ -69,7 +69,6 @@ module.exports = { property: 'network', methods: [ - insertMethod('addPeer', 'net_addPeer', 1, [web3._extend.utils.formatInputString], web3._extend.formatters.formatOutputBool), insertMethod('getPeerCount', 'net_peerCount', 0, [], web3._extend.formatters.formatOutputString), ], properties: diff --git a/package.json b/package.json index 049540c38..1842ed745 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Mist", - "version": "0.8.8", + "version": "0.8.9", "license": "GPL-3.0", "author": "Ethereum Mist Team ", "repository": { @@ -8,53 +8,60 @@ "url": "https://github.com/ethereum/mist.git" }, "scripts": { - "ci": "gulp --platform=linux" + "postinstall": "cd interface && yarn" }, "main": "main.js", "dependencies": { - "babel-runtime": "^6.18.0", - "bignumber.js": "^2.1.4", - "bluebird": "^3.3.5", + "babel-runtime": "^6.22.0", + "bignumber.js": "^4.0.0", + "bluebird": "^3.4.7", + "chai-as-promised": "^6.0.0", + "chai-string": "^1.3.0", "electron-squirrel-startup": "^1.0.0", "ethereum-client-binaries": "^1.6.1", + "ethereum-keyfile-recognizer": "^1.0.2", "ethereumjs-abi": "^0.6.3", - "got": "^6.3.0", - "i18next": "^2.3.4", + "got": "^6.7.1", + "i18next": "^6.1.1", "log-rotate": "^0.2.7", - "log4js": "^0.6.35", - "lokijs": "^1.4.1", - "minimongo-standalone": "0.0.9", - "numeral": "^1.5.3", - "os-timesync": "^1.0.6", + "log4js": "^1.1.0", + "lokijs": "^1.4.2", + "minimongo-standalone": "^1.1.0-3", + "numeral": "^2.0.4", + "os-timesync": "^1.0.7", "semver": "^5.1.0", - "solc": "0.4.6", - "typescript": "^1.7.3", + "solc": "^0.4.8", + "typescript": "^2.1.5", "underscore": "^1.8.3", "underscore-deep-extend": "^1.1.5", - "uuid": "^2.0.2", + "uuid": "^3.0.1", "web3": "^0.17.0-alpha", - "yargs": "^4.3.1" + "yargs": "^6.6.0" }, "devDependencies": { "chai": "^3.5.0", - "co-mocha": "^1.1.2", - "del": "^1.2.1", + "chai-as-promised": "^6.0.0", + "co-mocha": "^1.2.0", + "del": "^2.2.2", + "ecstatic": "^2.1.0", "electron": "1.3.13", - "electron-builder": "=9.1.0", - "eslint": "^3.8.0", - "eslint-config-airbnb-base": "^8.0.0", - "eslint-plugin-import": "^1.16.0", + "electron-builder": "^12.2.2", + "eslint": "^3.14.1", + "eslint-config-airbnb-base": "^11.0.1", + "eslint-plugin-import": "^2.2.0", "genomatic": "^1.0.0", "geth-private": "^1.3.0", + "gh-release-assets": "^1.1.0", "gulp": "^3.9.0", "gulp-flatten": "^0.3.0", - "gulp-spawn-mocha": "^2.2.2", + "gulp-spawn-mocha": "^3.1.0", + "istanbul": "^0.4.5", "merge-stream": "^1.0.0", "minimist": "^1.2.0", + "mocha": "^3.2.0", "optimist": "^0.6.1", "run-sequence": "^1.2.1", - "shelljs": "^0.7.0", - "spectron": "^3.2.2", - "sync-request": "^3.0.1" + "shelljs": "^0.7.6", + "spectron": "3.3.0" } } diff --git a/scripts/Locate.nsh b/scripts/Locate.nsh new file mode 100755 index 000000000..a4ed00826 --- /dev/null +++ b/scripts/Locate.nsh @@ -0,0 +1,51 @@ +!define locate::Open `!insertmacro locate::Open` + +!macro locate::Open _PATH _OPTIONS _HANDLE + locate::_Open /NOUNLOAD `${_PATH}` `${_OPTIONS}` + Pop ${_HANDLE} +!macroend + + +!define locate::Find `!insertmacro locate::Find` + +!macro locate::Find _HANDLE _PATHANDNAME _PATH _NAME _SIZE _TIME _ATTRIB + locate::_Find /NOUNLOAD `${_HANDLE}` + Pop ${_PATHANDNAME} + Pop ${_PATH} + Pop ${_NAME} + Pop ${_SIZE} + Pop ${_TIME} + Pop ${_ATTRIB} +!macroend + + +!define locate::Close `!insertmacro locate::Close` + +!macro locate::Close _HANDLE + locate::_Close /NOUNLOAD `${_HANDLE}` +!macroend + + +!define locate::GetSize `!insertmacro locate::GetSize` + +!macro locate::GetSize _PATH _OPTIONS _SIZE _FILES _DIRS + locate::_GetSize /NOUNLOAD `${_PATH}` `${_OPTIONS}` + Pop ${_SIZE} + Pop ${_FILES} + Pop ${_DIRS} +!macroend + + +!define locate::RMDirEmpty `!insertmacro locate::RMDirEmpty` + +!macro locate::RMDirEmpty _PATH _OPTIONS _REMOVED + locate::_RMDirEmpty /NOUNLOAD `${_PATH}` `${_OPTIONS}` + Pop ${_REMOVED} +!macroend + + +!define locate::Unload `!insertmacro locate::Unload` + +!macro locate::Unload + locate::_Unload +!macroend diff --git a/scripts/MoveFileFolder.nsh b/scripts/MoveFileFolder.nsh new file mode 100644 index 000000000..dea78c357 --- /dev/null +++ b/scripts/MoveFileFolder.nsh @@ -0,0 +1,256 @@ +;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +; MoveFile and MoveFolder macros +; +; Author: theblazingangel@aol.com (for the AutoPatcher project - www.autopatcher.com) +; Created: June 2007 +;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +;================== +; MoveFile macro +;================== + + !macro MoveFile sourceFile destinationFile + + !define MOVEFILE_JUMP ${__LINE__} + + ; Check source actually exists + + IfFileExists "${sourceFile}" +3 0 + SetErrors + goto done_${MOVEFILE_JUMP} + + ; Add message to details-view/install-log + + DetailPrint "Moving/renaming file: ${sourceFile} to ${destinationFile}" + + ; If destination does not already exists simply move file + + IfFileExists "${destinationFile}" +3 0 + rename "${sourceFile}" "${destinationFile}" + goto done_${MOVEFILE_JUMP} + + ; If overwriting without 'ifnewer' check + + ${If} $switch_overwrite == 1 + delete "${destinationFile}" + rename "${sourceFile}" "${destinationFile}" + delete "${sourceFile}" + goto done_${MOVEFILE_JUMP} + ${EndIf} + + ; If destination already exists + + Push $R0 + Push $R1 + Push $R2 + push $R3 + + GetFileTime "${sourceFile}" $R0 $R1 + GetFileTime "${destinationFile}" $R2 $R3 + + IntCmp $R0 $R2 0 older_${MOVEFILE_JUMP} newer_${MOVEFILE_JUMP} + IntCmp $R1 $R3 older_${MOVEFILE_JUMP} older_${MOVEFILE_JUMP} newer_${MOVEFILE_JUMP} + + older_${MOVEFILE_JUMP}: + delete "${sourceFile}" + goto time_check_done_${MOVEFILE_JUMP} + + newer_${MOVEFILE_JUMP}: + delete "${destinationFile}" + rename "${sourceFile}" "${destinationFile}" + delete "${sourceFile}" ;incase above failed! + + time_check_done_${MOVEFILE_JUMP}: + + Pop $R3 + Pop $R2 + Pop $R1 + Pop $R0 + + done_${MOVEFILE_JUMP}: + + !undef MOVEFILE_JUMP + + !macroend + +;================== +; MoveFolder macro +;================== + + !macro MoveFolder source destination mask + + !define MOVEFOLDER_JUMP ${__LINE__} + + Push $R0 + Push $R1 + + ; Move path parameters into registers so they can be altered if necessary + + StrCpy $R0 "${source}" + StrCpy $R1 "${destination}" + + ; Sort out paths - remove final backslash if supplied + + Push $0 + + ; Source + StrCpy $0 "$R0" 1 -1 + StrCmp $0 '\' 0 +2 + StrCpy $R0 "$R0" -1 + + ; Destination + StrCpy $0 "$R1" 1 -1 + StrCmp $0 '\' 0 +2 + StrCpy $R1 "$R1" -1 + + Pop $0 + + ; Create destination dir + + CreateDirectory "$R1\" + + ; Add message to details-view/install-log + + DetailPrint "Moving files: $R0\${mask} to $R1\" + + ; Push registers used by ${Locate} onto stack + + Push $R6 + Push $R7 + Push $R8 + Push $R9 + + ; Duplicate dir structure (to preserve empty folders and such) + + ${Locate} "$R0" "/L=D" ".MoveFolder_Locate_createDir" + + ; Locate files and move (via callback function) + + ${Locate} "$R0" "/L=F /M=${mask} /S= /G=1" ".MoveFolder_Locate_moveFile" + + ; Delete subfolders left over after move + + Push $R2 + deldir_loop_${MOVEFOLDER_JUMP}: + StrCpy $R2 0 + ${Locate} "$R0" "/L=DE" ".MoveFolder_Locate_deleteDir" + StrCmp $R2 0 0 deldir_loop_${MOVEFOLDER_JUMP} + Pop $R2 + + ; Delete empty subfolders moved - say the user just wanted to move *.apm files, they now also have a load of empty dir's from dir structure duplication! + + Push $R2 + delnewdir_loop_${MOVEFOLDER_JUMP}: + StrCpy $R2 0 + ${Locate} "$R1" "/L=DE" ".MoveFolder_Locate_deleteDir" + StrCmp $R2 0 0 delnewdir_loop_${MOVEFOLDER_JUMP} + Pop $R2 + + ; Pop registers used by ${Locate} off the stack again + + Pop $R9 + Pop $R8 + Pop $R7 + Pop $R6 + + ; Delete source folder if empty + + rmdir "$R0" + + Pop $R1 + Pop $R0 + + !undef MOVEFOLDER_JUMP + + !macroend + +;================== +; MoveFolder macro's ${Locate} callback functions +;================== + + Function .MoveFolder_Locate_createDir + + ${If} $R6 == "" + Push $R2 + StrLen $R2 "$R0" + StrCpy $R2 $R9 '' $R2 + CreateDirectory "$R1$R2" + Pop $R2 + ${EndIf} + + Push $R1 + + FunctionEnd + + Function .MoveFolder_Locate_moveFile + + Push $R2 + + ; Get path to file + + StrLen $R2 "$R0" + StrCpy $R2 $R9 '' $R2 + StrCpy $R2 "$R1$R2" + + ; If destination does not already exists simply move file + + IfFileExists "$R2" +3 0 + rename "$R9" "$R2" + goto done + + ; If overwriting without 'ifnewer' check + + ${If} $switch_overwrite == 1 + delete "$R2" + rename "$R9" "$R2" + delete "$R9" + goto done + ${EndIf} + + ; If destination already exists + + Push $0 + Push $1 + Push $2 + push $3 + + GetFileTime "$R9" $0 $1 + GetFileTime "$R2" $2 $3 + + IntCmp $0 $2 0 older newer + IntCmp $1 $3 older older newer + + older: + delete "$R9" + goto time_check_done + + newer: + delete "$R2" + rename "$R9" "$R2" + delete "$R9" ;incase above failed! + + time_check_done: + + Pop $3 + Pop $2 + Pop $1 + Pop $0 + + done: + + Pop $R2 + + Push $R1 + + FunctionEnd + + Function .MoveFolder_Locate_deleteDir + + ${If} $R6 == "" + RMDir $R9 + IntOp $R2 $R2 + 1 + ${EndIf} + + Push $R1 + + FunctionEnd diff --git a/scripts/SimpleFC.dll b/scripts/SimpleFC.dll new file mode 100755 index 0000000000000000000000000000000000000000..73b7d9634deddc41966698106dfcf3950c3cfb65 GIT binary patch literal 179712 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ν51={dZ1BY4A`^N;@_Z7WppVw&qD2_?OGw@eIc_w%^l<9ZW6-6g zfF*(WL&Y5wUo7UhL&ZWR^;NQu1}{DFqACvSe8PcHzQbC|X9%J!3Fnp>%vn;LODIkw zI`HWxDOMZy)Zj9El4CC(S>7ST*l&PdHe=ELb%a&D@NfnXIOh0~PT<{%V1{TlA+1V$ zfppMhB2!$DMieZ8u9 za^*UDP6I(6ya`R?IHM3}@M~Or<=S;EoW5`A@xJsCMw*B~Xyv*XDb{NDHSS`h`jLq!$hS1v63sECUOxs=p8=R@wUxGQ;CLqSl3de zAOG23X?jbC1B**LR4Z>L-Ol^2#Upo9RC+%yz6K?Duc@PCg+a;M#bj_tp=kwzDEa_Y z%j3O-2=aBMc4F^KSMl>otZj%T5%U)igY$nTu%c7;8~E>FmtOp@M**m(=nE1^d)rS2 zY43`}x#)xgiQ!oE#6CA{*5c>+@E*JbA}a^HDhJHLLKOUj1{BT^v&lETQzGWgRY4jp z8KqFXaVQnv{}P3~gLu;n@VknV9a?hB3^5i@PuZb5$a^;&wR6DaJ!DjgJc#&HdW6Zk zxU`}1l`uqGK&k2E;%g+OGfPCnhv=O-OZ?*I$B6Q|ae5pmC9){8r?kNgRe`m^*-IvD zqv9ZmVicmDKJ-)r%#3ZFSYs{0ZT4;xuhpZ^dd8F#U-xEQ`#9BGWQaVCpOUtp_`XO< zTXy+-2W!DAXOQ2Zs(G3a0@vazr@C~w@Ehfs?BJYr-2(|8gM z2t99i#o;@i1k?cU-#i+^B$hA;xA^zAPzOpq<pz-5byCOxKL}X+R@q=RUvF}>5oVt zz6O<2L2jj>C3srWR}26RPtgFpq_^mT*HbhAFBvFK(ld>|*{XZVI1#r{#L4gwQRqR7 zc8{U8yyaLX6Vccp@f6i}(e7x)^K2VDsp`R=-;*bCfffoOeWH>&BXQWjE|>`e<|)#M zevcXCL2TV!C9t)p8h^H>P^o+Fz_{W50e)-oXWLxzdj@`NZ&G`%I2~xu&B#FERS5z- z-XSRgUQuwEht?t2V(v?Los8GZ_ BC*}K5P`+D&^F74*?m_?Xw*du*dDI>MzQ0m9 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 literal 0 HcmV?d00001 diff --git a/scripts/ZipDLL.dll b/scripts/ZipDLL.dll new file mode 100755 index 0000000000000000000000000000000000000000..5925d5916b7e74d2ec4e5f14779c3ccf01ea0d4d GIT binary patch literal 167424 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%0DTOL?>OC_kR4i%4Ljx=K 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�)8$?5WD&aECZDs9cxmCwxXZD4kj^ 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 AdjJ3c literal 0 HcmV?d00001 diff --git a/scripts/windows-installer.nsi b/scripts/windows-installer.nsi new file mode 100644 index 000000000..4c76e03cb --- /dev/null +++ b/scripts/windows-installer.nsi @@ -0,0 +1,269 @@ +# Add current directory to plugin path +!addplugindir .\ + +# Architecture detection +!include x64.nsh + +# Include LogicLib (http://nsis.sourceforge.net/LogicLib) +!include 'LogicLib.nsh' + +# Include ZipDLL plugin (http://nsis.sourceforge.net/ZipDLL_plug-in) +!include 'ZipDLL.nsh' + +# Include Locate plugin (http://nsis.sourceforge.net/Locate_plugin) +!include 'locate.nsh' + +# Include MoveFileFolder plugin (http://nsis.sourceforge.net/MoveFileFolder) +!include 'FileFunc.nsh' +!insertmacro Locate +Var /GLOBAL switch_overwrite +!include 'MoveFileFolder.nsh' + +# Enable CRC +CRCCheck on + +# Require admin privledges when UAC is on +RequestExecutionLevel admin + +!define APPNAME "Mist" +!define GROUPNAME "Ethereum" +!define HELPURL "https://github.com/ethereum/mist/releases/issues" +!define UPDATEURL "https://github.com/ethereum/mist/releases" +!define ABOUTURL "https://ethereum.org" +!define /date NOW "%Y%m%d" + +## These must be integers and can be set on the command line by NSIS with "/DMAJORVERSION=0 /DMINORVERSION=8 /DBUILDVERSION=7" +#!define VERSIONMAJOR 0 +#!define VERSIONMINOR 8 +#!define VERSIONBUILD 7 + +# Define some script globals +Name "${GROUPNAME} ${APPNAME}" +Icon "..\dist_mist\build\icon.ico" +OutFile "..\dist_mist\release\mist-installer-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.exe" +var FILEDIR +var DATADIR +var NODEDATADIR +var ARCHDIR +var SHORTCUTDIR +var DESKTOPDIR + +# Check for administrative rights +!macro VerifyUserIsAdmin +UserInfo::GetAccountType +pop $0 +${If} $0 != "admin" + messageBox mb_iconstop "Administrator rights required!" + setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED + quit +${EndIf} +!macroend + +# Create a shared function function for setting environment variables +!macro ENVFUNC un + Function ${un}setenv + + SetShellVarContext current + StrCpy $DATADIR "$APPDATA\${APPNAME}" + StrCpy $NODEDATADIR "$APPDATA\Ethereum" + StrCpy $SHORTCUTDIR "$SMPROGRAMS\${APPNAME}" + StrCpy $DESKTOPDIR "$DESKTOP" + + ${If} ${RunningX64} + StrCpy $FILEDIR "$PROGRAMFILES64\${APPNAME}" + StrCpy $ARCHDIR "win-unpacked" + ${Else} + StrCpy $FILEDIR "$PROGRAMFILES32\${APPNAME}" + StrCpy $ARCHDIR "win-ia32-unpacked" + ${Endif} + + SetShellVarContext all + + FunctionEnd +!macroend + +!insertmacro ENVFUNC "" +!insertmacro ENVFUNC "un." + +function .onInit + !insertmacro VerifyUserIsAdmin + call setenv +functionEnd + +# The license page. Can use .txt or .rtf data +PageEx license + LicenseData ..\LICENSE +PageExEnd + +# Components is a good place to allow the user to select optional software to install +# For example, it could be used to allow the user to select which node they want installed and then download it +#Page components + +# Select the location to install the main program files +PageEx directory + DirVar $FILEDIR +PageExEnd + +## Select the location for Mist's data directory +#PageEx directory +# DirText "Select a location for Mist's data files (watched contracts, etc.)" +# DirVar $DATADIR +#PageExEnd + +# Select the location for the node's data directory +PageEx directory + DirText "Select a location where blockchain data will be stored" + DirVar $NODEDATADIR +PageExEnd + +# Installation +Page instfiles + +# Uninstaller confirmation page. Useful to remind the user what data (if any) will remain, for example chaindata or keystore +UninstPage uninstConfirm + +# Uninstallation section +UninstPage instfiles + +# Show details by default +ShowInstDetails show +ShowUninstDetails show + +# Mist installer instructions +Section Mist MIST_IDX + StrCpy $switch_overwrite 1 + + # set the installation directory as the destination for the following actions + SetOutPath $TEMP + # include both architecture zip files + file "..\dist_mist\release\${APPNAME}-win64-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" + file "..\dist_mist\release\${APPNAME}-win32-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" + file "..\dist_mist\build\icon.ico" + + # Extract the zip file from TEMP to the user's selected installation directory + ${If} ${RunningX64} + ZipDLL::extractALL "$TEMP\${APPNAME}-win64-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" "$FILEDIR" + StrCpy $ARCHDIR "win-unpacked" + ${Else} + ZipDLL::extractALL "$TEMP\${APPNAME}-win32-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" "$FILEDIR" + StrCpy $ARCHDIR "win-ia32-unpacked" + ${Endif} + + # Move files out of subfolder + !insertmacro MoveFolder "$FILEDIR\$ARCHDIR" "$FILEDIR" "*.*" + # Copy icon from installer (not included in zip) + !insertmacro MoveFile "$TEMP\icon.ico" "$FILEDIR\logo.ico" + + # create the uninstaller + WriteUninstaller "$FILEDIR\uninstall.exe" + + # create shortcuts with flags in the start menu programs directory + createDirectory "$SHORTCUTDIR" + createShortCut "$SHORTCUTDIR\${APPNAME}.lnk" "$FILEDIR\${APPNAME}.exe" '--node-datadir="$NODEDATADIR"' "$FILEDIR\${APPNAME}.exe" 0 + + # create desktop shortcut + createShortCut "$DESKTOPDIR\${APPNAME}.lnk" "$FILEDIR\${APPNAME}.exe" '--node-datadir="$NODEDATADIR"' "$FILEDIR\${APPNAME}.exe" 0 + + # create a shortcut for the program uninstaller + CreateShortCut "$SHORTCUTDIR\Uninstall.lnk" "$FILEDIR\uninstall.exe" + + ## Firewall - add rules + #SimpleFC::AdvAddRule "Geth incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$DATADIR\binaries\Geth\unpacked\geth.exe" "" "" "Ethereum" 30303 "" "" "" + #SimpleFC::AdvAddRule "Geth outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$DATADIR\binaries\Geth\unpacked\geth.exe" "" "" "Ethereum" "" 30303 "" "" + #SimpleFC::AdvAddRule "Geth UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$DATADIR\binaries\Geth\unpacked\geth.exe" "" "" "Ethereum" "" 30303 "" "" + + # write registry strings for uninstallation + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayName" "${GROUPNAME} ${APPNAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "UninstallString" '"$FILEDIR\uninstall.exe"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallLocation" '"$FILEDIR"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallDate" "${NOW}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayIcon" '"$FILEDIR\logo.ico"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "Publisher" "${GROUPNAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "HelpLink" '"${HELPURL}"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLUpdateInfo" '"${UPDATEURL}"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLInfoAbout" '"${ABOUTURL}"' + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayVersion" "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR} + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR} + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoRepair" 1 + # calculate and store installation size + Call GetInstalledSize + Pop $0 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "EstimatedSize" "$0" + + # write registry strings for current user options + WriteRegStr HKCU "Software\${GROUPNAME} ${APPNAME}" "DATADIR" "$DATADIR" + WriteRegStr HKCU "Software\${GROUPNAME} ${APPNAME}" "NODEDATADIR" "$NODEDATADIR" + WriteRegStr HKCU "Software\${GROUPNAME} ${APPNAME}" "DESKTOPDIR" "$DESKTOPDIR" + + # Clean up temporary files + Delete "$TEMP\${APPNAME}-win32-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" + Delete "$TEMP\${APPNAME}-win64-${VERSIONMAJOR}-${VERSIONMINOR}-${VERSIONBUILD}.zip" +SectionEnd + +Function .onInstSuccess + ExecShell "open" "$SHORTCUTDIR" +FunctionEnd + +function un.onInit + call un.setenv + !insertmacro VerifyUserIsAdmin +functionEnd + +# uninstaller section start +Section "uninstall" + # get user settings from registry + ClearErrors + ReadRegStr $0 HKCU "Software\${GROUPNAME} ${APPNAME}" 'DATADIR' + ReadRegStr $1 HKCU "Software\${GROUPNAME} ${APPNAME}" 'NODEDATADIR' + ReadRegStr $2 HKCU "Software\${GROUPNAME} ${APPNAME}" 'DESKTOPDIR' + + IfErrors 0 +2 + MessageBox MB_ICONEXCLAMATION|MB_OK "Unable to read from the registry. Not all shortcuts will be removed" + + StrCpy $DATADIR $0 + StrCpy $NODEDATADIR $1 + StrCpy $DESKTOPDIR $2 + + # remove the link from the start menu + rmDir /r "$SHORTCUTDIR" + + # remove desktop shortcut + Delete "$DESKTOPDIR\${APPNAME}.lnk" + + # remove files from installation directory + rmDir /r /REBOOTOK "$FILEDIR" + + ## Firewall - remove rules (if exists) + #SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" + #SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" + #SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" + + # delete registry strings + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" + DeleteRegKey HKCU "Software\${GROUPNAME} ${APPNAME}" +SectionEnd + +Function un.onUnInstSuccess + MessageBox MB_OK "Opening leftover data directories (backup before deleting!)" + ExecShell "open" "$DATADIR" + ExecShell "open" "$NODEDATADIR" +FunctionEnd + + +# Return on top of stack the total size (as DWORD) of the selected/installed sections. +Var GetInstalledSize.total +Function GetInstalledSize + StrCpy $GetInstalledSize.total 0 + + ${if} ${SectionIsSelected} ${MIST_IDX} + ${locate::GetSize} "$FILEDIR" "/S=Kb" $0 $1 $2 + # TODO check for return of -1 for error + IntOp $GetInstalledSize.total $GetInstalledSize.total + $0 + ${endif} + + IntFmt $GetInstalledSize.total "0x%08X" $GetInstalledSize.total + Push $GetInstalledSize.total +FunctionEnd diff --git a/scripts/zipdll.nsh b/scripts/zipdll.nsh new file mode 100755 index 000000000..32e8b7c88 --- /dev/null +++ b/scripts/zipdll.nsh @@ -0,0 +1,417 @@ +;ZipDLL include file for NSIS +;Written by Tim Kosse (mailto:tim.kosse@gmx.de) +;some improvements by deguix + +;Supported languages with their translators in alphabetical order: + +;Arabic translation by asdfuae +;Brazilian Portuguese translation by "deguix" +;Chinese, Simplified translation by Kii Ali +;Chinese, Traditional traslation by "matini" and Kii Ali +;Croatian translation by "iostriz" +;Danish translation by Claus Futtrup +;French translation by "veekee" +;German translation by Tim Kosse +;Hungarian translation by Toth Laszlo +;Korean translation by Seongab Kim +;Lithuanian translation by Vytautas Krivickas +;Polish translation by Krzysztof Galuszka +;Russion translation by Sergey +;Spanish translation by "dark_boy" + +!ifndef ZIPDLL_USED + +!define ZIPDLL_USED + +!macro ZIPDLL_EXTRACT SOURCE DESTINATION FILE + + !define "FILE_${FILE}" + + !ifndef FILE_ + Push "${FILE}" + !endif + + IfFileExists "${DESTINATION}" +2 + CreateDirectory "${DESTINATION}" + + Push "${DESTINATION}" + + IfFileExists "${SOURCE}" +2 + SetErrors + + Push "${SOURCE}" + + ;The strings that will be translated are (ready to copy, + ;remove leading semicolons in your language block): + + !ifdef LANG_ENGLISH + + ;English is default language of ZipDLL, no need to push the untranslated strings + + ;StrCmp $LANGUAGE ${LANG_ENGLISH} 0 +1 + + ;Push " Error: %s" + ;Push "Could not get file attributes." + ;Push "Error: Could not get file attributes." + ;Push "Could not extract %s" + ;Push " Error: Could not extract %s" + + ;!ifdef FILE_ + ;Push " Extract: %s" + ;Push " Extracting %d files and directories" + ;Push "Extracting contents of %s to %s" + ;!else + ;Push "Specified file does not exist in archive." + ;Push "Error: Specified file does not exist in archive." + ;Push "Extracting the file %s from %s to %s" + ;!endif + + ;Push "/TRANSLATE" + + !endif + + !ifdef LANG_HUNGARIAN + + StrCmp $LANGUAGE ${LANG_HUNGARIAN} 0 +10 + + Push " Hiba: %s" + Push "Nem olvasható a fájl attribútumai." + Push "Hiba: Nem olvasható a fájl attribútumai." + Push "Nem sikerült kicsomagolni a(z) %s" + Push " Hiba: Nem sikerült kicsomagolni a(z) %s" + + !ifdef FILE_ + Push " Kicsomagolás: %s" + Push " %d fájl és mappa kicsomagolása" + Push "%s tartalom kicsomagolása a %s helyre" + !else + Push "A megadott fájl nem található az arhívumban." + Push "Hiba: A megadott fájl nem található az arhívumban." + Push "%s fájl kcsomagolása a(z) %s fájlból a %s helyre" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_FRENCH + + StrCmp $LANGUAGE ${LANG_FRENCH} 0 +10 + + Push " Erreur : %s" + Push "Impossible de récupérer les informations sur le fichier." + Push "Erreur : Impossible de récupérer les informations sur le fichier." + Push "Impossible de décompresser %s." + Push " Erreur : Impossible de décompresser %s." + + !ifdef FILE_ + Push " Décompression : %s" + Push " Décompression de %d fichiers et répertoires" + Push "Décompression des données de %s vers %s" + !else + Push "Le fichier spécifié n'existe pas dans l'archive" + Push "Erreur : Le fichier spécifié n'existe pas dans l'archive" + Push "Décompression du fichier %s depuis %s vers %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_GERMAN + + StrCmp $LANGUAGE ${LANG_GERMAN} 0 +10 + + Push " Fehler: %s" + Push "Dateiattribute konnten nicht ermittelt werden." + Push "Fehler: Dateiattribute konnten nicht ermittelt werden." + Push "%s konnte nicht dekomprimiert werden." + Push " Fehler: %s konnte nicht dekomprimiert werden." + + !ifdef FILE_ + Push " Dekomprimiere: %s" + Push " Dekomprimiere %d Dateien und Verzeichnisse" + Push "Dekomprimiere Inhalt von %s nach %s" + !else + Push "Die angegebene Datei existiert nicht im Archiv" + Push "Fehler: Die angegebene Datei existiert nicht im Archiv" + Push "Dekomprimiere Datei %s von %s nach %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_SPANISH + + StrCmp $LANGUAGE ${LANG_SPANISH} 0 +10 + + Push " Error: %s" + Push "No se obtuvieron atributos del archivo" + Push "Error: No se obtuvieron atributos del archivo" + Push "No se pudo extraer %s" + Push " Error: No se pudo extraer %s" + + !ifdef FILE_ + Push " Extraer: %s" + Push " Extrayendo %d archivos y directorios" + Push "Extraer archivos de %s a %s" + !else + Push "Archivo especificado no existe en el ZIP" + Push "Error: El archivo especificado no existe en el ZIP" + Push "Extrayendo el archivo %s de %s a %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_PORTUGUESEBR + + StrCmp $LANGUAGE ${LANG_PORTUGUESEBR} 0 +10 + + Push " Erro: %s" + Push "Não se pode ler os atributos do arquivo" + Push "Error: Não se pode ler os atributos do arquivo" + Push "Não se pode extrair %s" + Push " Erro: Não se pode extrair %s" + + !ifdef FILE_ + Push " Extraindo: %s" + Push " Extraindo %d arquivos e diretórios" + Push "Extraindo arquivos de %s a %s" + !else + Push "O arquivo especificado não existe no ZIP" + Push "Erro: O arquivo especificado não existe no ZIP" + Push "Extraindo o arquivo %s de %s a %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_TRADCHINESE + + StrCmp $LANGUAGE ${LANG_TRADCHINESE} 0 +11 + + Push " ¿ù»~: %s" + Push "µLªk¨ú±oÀÉ®×ÄÝ©Ê¡C" + Push "¿ù»~: µLªk¨ú±oÀÉ®×ÄÝ©Ê¡C" + Push "µLªk¸ÑÀ£ÁY %s" + Push " ¿ù»~¡GµLªk¸ÑÀ£ÁY %s" + + !ifdef FILE_ + Push " ¸ÑÀ£ÁY¡G%s" + Push " ¥¿¦b¸ÑÀ£ÁY %d ÀÉ®×»P¥Ø¿ý" + Push "¥¿¦b¸ÑÀ£ÁY %s ªº¤º®e¨ì %s" + !else + Push "«ü©wªºÀɮר䣦s¦b©óÀ£ÁY¥]¡C" + Push "¿ù»~¡G«ü©wªºÀɮר䣦s¦b©óÀ£ÁY¥]¡C" + Push "¥¿¦b¸ÑÀ£ÁYÀÉ®× %s ¡A±q %s ¨ì %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_SIMPCHINESE + + StrCmp $LANGUAGE ${LANG_SIMPCHINESE} 0 +11 + + Push " ´íÎó: %s" + Push "ÎÞ·¨È¡µÃÎļþÊôÐÔ¡£" + Push "´íÎó: ÎÞ·¨È¡µÃÎļþÊôÐÔ¡£" + Push "ÎÞ·¨½âѹËõ %s" + Push " ´íÎó£ºÎÞ·¨½âѹËõ %s" + + !ifdef FILE_ + Push " ½âѹËõ£º%s" + Push " ÕýÔÚ½âѹËõ %d ÎļþÓëĿ¼" + Push "ÕýÔÚ½âѹËõ %s µÄÄÚÈݵ½ %s" + !else + Push "Ö¸¶¨µÄÎļþ²¢²»´æÔÚÓÚѹËõ°ü¡£" + Push "´íÎó£ºÖ¸¶¨µÄÎļþ²¢²»´æÔÚÓÚѹËõ°ü¡£" + Push "ÕýÔÚ½âѹËõÎļþ %s £¬´Ó %s µ½ %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_LITHUANIAN + + StrCmp $LANGUAGE ${LANG_LITHUANIAN} 0 +10 + + Push " Klaida: %s" + Push "Negaleta gauti bylos nuorodu." + Push "Klaida: Negaleta gauti bylos nuorodu." + Push "Negaleta ištraukti %s" + Push " Klaida: Negaleta ištraukti %s" + + !ifdef FILE_ + Push " Ištraukiam : %s" + Push " Ištraukiame %d bylas ir katalogus" + Push "Ištraukiame viska is %s i %s" + !else + Push "Parinkta byla nesurasta šiame archyve." + Push "Klaida: Parinkta byla nesurasta šiame archyve." + Push "Ištraukiame byla %s iš %s i %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef "LANG_POLISH" + + strcmp $LANGUAGE ${LANG_POLISH} 0 +10 + + Push " B³¹d: %s" + Push "Nie mo¿e pobraæ atrybutu pliku." + Push "B³¹d: Nie mo¿e pobraæ atrybutu pliku." + Push "Nie mo¿e rozpakowaæ %s." + Push " B³¹d: Nie mo¿e rozpakowaæ %s." + + !ifdef FILE_ + Push " Rozpakuj: %s" + Push " Rozpakowywanie %d plików i katalogów" + Push "Rozpakowywanie zawartoœci %s do %s" + !else + Push "Plik nie istnieje w archiwum" + Push "B³¹d: Plik nie istnieje w archiwum" + Push "Rozpakowywanie pliku %s z %s do %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef "LANG_KOREAN" + strcmp $LANGUAGE ${LANG_KOREAN} 0 +10 + Push " ¿À·ù : %s" + Push "È­ÀÏ ¼Ó¼ºÀ» ¾ò¾î¿Ã ¼ö ¾ø½À´Ï´Ù." + Push "¿À·ù: È­ÀÏ ¼Ó¼ºÀ» ¾ò¾î¿Ã ¼ö ¾ø½À´Ï´Ù." + Push "%sÀ»(¸¦) Ç® ¼ö ¾ø½À´Ï´Ù." + Push " ¿À·ù: %sÀ»(¸¦) Ç® ¼ö ¾ø½À´Ï´Ù." + + !ifdef FILE_ + Push " Ç®±â : %s" + Push " %d°³ÀÇ ÆÄÀÏ°ú Æú´õ¸¦ Ǫ´Â Áß" + Push "%sÀÇ ³»¿ëÀ» %s¿¡ Ǫ´Â Áß" + !else + Push "ÁöÁ¤µÈ ÆÄÀÏÀÌ ¾ÐÃà ÆÄÀÏ ¾È¿¡ ¾ø½À´Ï´Ù." + Push "¿À·ù: ÁöÁ¤µÈ ÆÄÀÏÀÌ ¾ÐÃà ÆÄÀÏ ¾È¿¡ ¾ø½À´Ï´Ù." + Push "%s ÆÄÀÏÀ» %s¿¡¼­ %s·Î Ǫ´Â Áß" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef "LANG_RUSSIAN" + + strcmp $LANGUAGE ${LANG_RUSSIAN} 0 +10 + + Push " Îøèáêà: %s" + Push "Íå ìîãó ïîëó÷èòü àòðèáóòû ôàéëà." + Push "Îøèáêà: Íå ìîãó ïîëó÷èòü àòðèáóòû ôàéëà." + Push "Íå ìîãó èçâëå÷ü %s" + Push " Îøèáêà: Íå ìîãó èçâëå÷ü %s" + + !ifdef LANG_ + Push " Èçâëåêàþ : %s" + Push " Èçâëå÷åíèå %d ôàéëîâ è ïàïîê" + Push "Ñïèñîê èçâëåêàåìûõ ôàéëîâ èç %s â %s" + !else + Push "Èçâëåêàåìûé ôàéë íå îáíàðóæåí â àðõèâå." + Push "Îøèáêà: SÈçâëåêàåìûé ôàéë íå îáíàðóæåí â àðõèâå." + Push "Èçâëå÷åíèå ôàéëà %s èç %s â %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_ARABIC + + StrCmp $LANGUAGE ${LANG_ARABIC} 0 +10 + + Push " ÎØÇÁ: %s" + Push "áã íÍÕá Úáì ÎÕÇÆÕ ÇáãáÝ." + Push "ÎØÇÁ: áã íÍÕá Úáì ÎÕÇÆÕ ÇáãáÝ." + Push "áÇ íãßä ÇÓÊÎÑÇÌ %s" + Push " ÎØÇÁ: áÇ íãßä ÇÓÊÎÑÇÌ %s" + + !ifdef FILE_ + Push " ÇÓÊÎÑÇÌ : %s" + Push " ÇÓÊÎÑÇÌ ãÌáÏÇÊ æ ãáÝÇÊ %d" + Push "ÇÓÊÎÑÇÌ ãÍÊæíÇÊ %s Åáì %s" + !else + Push "ÇáãáÝ ÛíÑ ãæÌæÏ Ýí ÇáÓÌá." + Push "ÎØÇÁ: ÇáãáÝ ÛíÑ ãæÌæÏ Ýí ÇáÓÌá." + Push "ÇÓÊÎÑÇÌ ÇáãáÝ %s ãä %s Åáì %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_DANISH + + StrCmp $LANGUAGE ${LANG_DANISH} 0 +10 + + Push " Fejl: %s" + Push "Kunne ikke læse fil attributter." + Push "Fejl: Kunne ikke læse fil attributter." + Push "Kunne ikke udpakke %s" + Push " Fejl: Kunne ikke udpakke %s" + + !ifdef FILE_ + Push " Udpakker: %s" + Push " Udpakker %d filer og mapper" + Push "Udpakker indhold fra %s til %s" + !else + Push "Specificeret fil eksisterer ikke i filarkivet" + Push "Fejl: Specificeret fil eksisterer ikke i filarkivet" + Push "Udpakker fil %s fra %s til %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef LANG_CROATIAN + + StrCmp $LANGUAGE ${LANG_CROATIAN} 0 +10 + + Push " Greška: %s" + Push "Ne mogu dohvatiti atribute datoteke." + Push "Greška: Ne mogu dohvatiti atribute datoteke." + Push "Ne mogu ekstrahirati %s" + Push " Greška: Ne mogu ekstrahirati %s" + + !ifdef FILE_ + Push " Ekstrakcija: %s" + Push " Ekstrakcija %d datoteka i mapa" + Push "Ekstrakcija sadržaja %s u %s" + !else + Push "Tražena datoteka ne postoji u arhivi." + Push "Greška: Tražena datoteka ne postoji u arhivi." + Push "Ekstrakcija datoteke %s iz %s u %s" + !endif + + Push "/TRANSLATE" + + !endif + + !ifdef FILE_ + ZipDLL::extractall + !else + ZipDLL::extractfile + !endif + + !undef "FILE_${FILE}" + +!macroend + +!endif diff --git a/tests/_base.js b/tests/_base.js index 12d8a5bbf..a224fce53 100644 --- a/tests/_base.js +++ b/tests/_base.js @@ -1,7 +1,4 @@ - - require('co-mocha'); - const _ = require('underscore'); const genomatic = require('genomatic'); const Q = require('bluebird'); @@ -12,14 +9,52 @@ const path = require('path'); const packageJson = require('../package.json'); const gethPrivate = require('geth-private'); const Application = require('spectron').Application; - const chai = require('chai'); +const http = require('http'); +const ecstatic = require('ecstatic'); +const ClientBinaryManager = require('ethereum-client-binaries').Manager; +const Settings = require('../modules/settings'); + chai.should(); process.env.TEST_MODE = 'true'; +const startGeth = function* () { + let gethPath; -exports.mocha = function (_module, options) { + const config = JSON.parse( + fs.readFileSync(path.join('clientBinaries.json')).toString() + ); + const manager = new ClientBinaryManager(config); + yield manager.init(); + + if (manager.clients.Geth.state.available) { + gethPath = manager.clients.Geth.activeCli.fullPath; + } + else { + console.info('Downloading geth...'); + let downloadedGeth = yield manager.download('Geth'); + gethPath = downloadedGeth.client.activeCli.fullPath; + console.info('Geth downloaded at:', gethPath); + } + + const geth = gethPrivate({ + gethPath, + balance: 5, + genesisBlock: { + difficulty: '0x1', + extraData: '0x1', + }, + gethOptions: { + port: 58546, + rpcport: 58545, + }, + }); + yield geth.start(); + return geth; +}; + +exports.mocha = (_module, options) => { const tests = {}; options = _.extend({ @@ -28,7 +63,7 @@ exports.mocha = function (_module, options) { _module.exports[options.name || path.basename(_module.filename)] = { * before() { - this.timeout(10000000); + this.timeout(1e7); this.assert = chai.assert; this.expect = chai.expect; @@ -36,65 +71,38 @@ exports.mocha = function (_module, options) { const logFilePath = path.join(__dirname, 'mist.log'); shell.rm('-rf', logFilePath); - const appFileName = (options.app === 'wallet') ? 'Ethereum Wallet' : 'Mist', - appVers = packageJson.version.replace(/\./ig, '-'), - platformArch = `${process.platform}-${process.arch}`; + this.geth = yield startGeth(); - let appPath, - gethPath; + const appFileName = (options.app === 'wallet') ? 'Ethereum Wallet' : 'Mist'; + const appVers = packageJson.version.replace(/\./ig, '-'); + const platformArch = `${process.platform}-${process.arch}`; + + let appPath; + let ipcProviderPath = path.join(this.geth.dataDir, 'geth.ipc'); switch (platformArch) { case 'darwin-x64': - appPath = path.join( - process.cwd(), - `dist_${options.app}`, - 'dist', - 'mac', - `${appFileName}.app`, - 'Contents', - 'MacOS', - appFileName - ); + appPath = path.join(process.cwd(), `dist_${options.app}`, 'dist', 'mac', + `${appFileName}.app`, 'Contents', 'MacOS', appFileName + ); break; case 'linux-x64': - appPath = path.join( - process.cwd(), - `dist_${options.app}`, - `${appFileName}-linux64-${appVers}`, - appFileName - ); + appPath = path.join(process.cwd(), `dist_${options.app}`, 'dist', 'linux-unpacked', appFileName.toLowerCase()); break; default: throw new Error(`Cannot run tests on ${platformArch}, please run on: darwin-x64, linux-x64`); } - // check that appPath exists + // check that appPath exists if (!shell.test('-f', appPath)) { throw new Error(`Cannot find binary: ${appPath}`); } - this.geth = gethPrivate({ - gethPath: path.join(process.cwd(), 'nodes', 'geth', platformArch, 'geth'), - balance: 5, - genesisBlock: { - difficulty: '0x1', - extraData: '0x1', - }, - gethOptions: { - port: 58546, - rpcport: 58545, - }, - }); - - yield this.geth.start(); - this.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:58545')); - - this.app = new Application({ requireName: 'electronRequire', - startTimeout: 5000, - waitTimeout: 5000, + startTimeout: 10000, + waitTimeout: 10000, quitTimeout: 10000, path: appPath, args: [ @@ -102,39 +110,101 @@ exports.mocha = function (_module, options) { '--loglevel', 'debug', '--logfile', logFilePath, '--node-datadir', this.geth.dataDir, - '--ipcpath', path.join(this.geth.dataDir, 'geth.ipc'), + '--rpc', ipcProviderPath, ], }); - yield this.app.start(); - this.client = this.app.client; + /* + Starting HTTP server for HTML fixtures + */ + const serverPort = 8080; + this.httpServer = http.createServer( + ecstatic({root: path.join(__dirname, 'fixtures')}) + ).listen(serverPort); + this.fixtureBaseUrl = `http://localhost:${serverPort}/`; - yield this.client.waitUntilWindowLoaded(); - // wait a small amount of time to ensure main app window is ready with data - yield Q.delay(8000); - - // console.log(this.app.chromeDriver.logLines); + this.client = this.app.client; + yield this.client.waitUntilWindowLoaded(); + // console.log(this.app.chromeDriver.logLines); - /* - Utility methods - */ + /* + Utility methods + */ for (const key in Utils) { this[key] = genomatic.bind(Utils[key], this); } + // Loop over windows trying to select Main Window + let app = this; + let selectMainWindow = function* (mainWindowSearch) { + let windowHandles = (yield app.client.windowHandles()).value; + + for (let handle in windowHandles) { + yield app.client.window(windowHandles[handle]); + const windowUrl = yield app.client.getUrl(); + const isMainWindow = mainWindowSearch.test(windowUrl); + if (isMainWindow) return true; + } + + // not main window. try again after 1 second. + yield Q.delay(1000); + yield selectMainWindow(mainWindowSearch); + } + + const mainWindowSearch = (options.app === 'wallet') ? /^file:\/\/\/$/ : /interface\/index\.html$/; + yield selectMainWindow(mainWindowSearch); + this.mainWindowHandle = (yield this.client.windowHandle()).value; }, - * after() { + * beforeEach () { + yield this.app.client.window(this.mainWindowHandle); + + yield this.client.execute(() => { // Code executed in context of browser + Tabs.remove({}); + LastVisitedPages.remove({}); + History.remove({}); + + Tabs.insert({ + _id: 'browser', + url: 'http://localhost:8080/', + redirect: 'http://localhost:8080/', + position: 0 + }); + Tabs.upsert({_id: 'wallet'}, {$set: { + url: 'https://wallet.ethereum.org', + redirect: 'https://wallet.ethereum.org', + position: 1, + permissions: { admin: true } + }}); + + LocalStore.set('selectedTab', 'browser'); + }); + yield Q.delay(2000); + // yield this.client.reload(); + }, + + * afterEach () { + }, + + * after () { + console.log('After tests triggered'); if (this.app && this.app.isRunning()) { + console.log('Stopping app...'); yield this.app.stop(); } if (this.geth && this.geth.isRunning) { + console.log('Stopping geth...'); yield this.geth.stop(); } + + if (this.httpServer && this.httpServer.isListening) { + console.log('Stopping http server...'); + yield this.httpServer.close(); + } }, tests, @@ -146,10 +216,15 @@ exports.mocha = function (_module, options) { const Utils = { * waitUntil(msg, promiseFn) { - yield this.client.waitUntil(promiseFn, - 10000, - msg, - 500); + yield this.client.waitUntil(promiseFn, 10000, msg, 500); + }, + * waitForText(selector, text, ms = 5000, message = 'Element couldn\'t be found') { + const client = this.client; + yield client.waitUntil(() => { + return client.getText(selector).then((e) => { + return e === text; + }); + }, ms, message); }, * getUiElements(selector) { const elems = yield this.client.elements(selector); @@ -176,7 +251,7 @@ const Utils = { const newHandles = (yield client.windowHandles()).value; - // focus on new window + // focus on new window yield client.window(newHandles.pop()); }, * execElemsMethod(clientElementIdMethod, selector) { @@ -214,17 +289,17 @@ const Utils = { ); accounts = accounts.map(a => a.toLowerCase()); - balances = balances.map(b => parseInt(b)); + balances = balances.map(b => parseInt(b, 10)); return _.object(accounts, balances); }, * getUiAccountBalances() { - // check balances on the pgetUiAccountsBalancesage + // check balances on the pgetUiAccountsBalancesage let _accounts = yield this.execElemsMethod('elementIdText', '.wallet-box .account-id'); let _balances = yield this.execElemsMethod('elementIdText', '.wallet-box .account-balance'); _accounts = _accounts.map(a => a.toLowerCase()); - _balances = _balances.map(b => parseInt(b)); + _balances = _balances.map(b => parseInt(b, 10)); return _.object(_accounts, _balances); }, @@ -233,10 +308,10 @@ const Utils = { let idx = -1; - accId = accId.toLowerCase(); + const accountId = accId.toLowerCase(); for (const i in _accounts) { - if (_accounts[i].toLowerCase() === accId) { + if (_accounts[i].toLowerCase() === accountId) { idx = i; } } @@ -257,5 +332,69 @@ const Utils = { * stopMining() { yield this.geth.consoleExec('miner.stop();'); }, + + * selectTab(tabId) { + const tab = yield this.getUiElement(`.sidebar [data-tab-id=${tabId}]`); + yield this.client.click(`.sidebar [data-tab-id=${tabId}] button.main`); + // TODO: returns webview reference + }, + * getActiveWebview() { + const webview = ''; + return webview; + }, + * loadFixture(uri = '') { + const client = this.client; + yield client.setValue('#url-input', `${this.fixtureBaseUrl}${uri}`); + yield client.submitForm('form.url'); + yield client.waitUntil(() => { + return client.getText('.dapp-info span', (e) => { + /Fixture/.test(e); + }); + }, 3000, 'expected to properly load fixture'); + }, + * getBrowserBarText() { + return yield this.client.getText('.url-breadcrumb'); + }, + *pinCurrentTab() { + const client = this.client; + + yield this.openAndFocusNewWindow(() => { + return client.click('span.connect-button'); + }); + yield client.click('.dapp-primary-button'); + + yield client.window(this.mainWindowHandle); // selects main window again + yield Q.delay(500); + + const pinnedWebview = (yield client.windowHandles()).value.pop(); + return pinnedWebview; + }, + *navigateTo(url) { + const client = this.client; + yield client.setValue('#url-input', url); + yield client.submitForm('form.url'); + }, + + /* + @method getWindowByUrl + + @param search: function that tells how to search by window + @param tries: amount of tries left until give up searching for + */ + *getWindowByUrl(search, tries = 5) { + if (tries < 0) throw new Error('Couldn\'t select window using given parameters.'); + + let windowHandles = (yield this.client.windowHandles()).value; + + for (let handle in windowHandles) { + yield this.client.window(windowHandles[handle]); + + const found = !!search(yield this.client.getUrl()); + if (found) return true; + } + yield Q.delay(500); + yield this.getWindowByUrl(search, --tries); + } + }; diff --git a/tests/fixtures/fixture-popup.html b/tests/fixtures/fixture-popup.html new file mode 100644 index 000000000..c9a6a1645 --- /dev/null +++ b/tests/fixtures/fixture-popup.html @@ -0,0 +1,10 @@ + + + Fixture Popup + + +

Fixture Popup

+ Target blank + Target popup + + diff --git a/tests/fixtures/index.html b/tests/fixtures/index.html new file mode 100644 index 000000000..6a1364a1d --- /dev/null +++ b/tests/fixtures/index.html @@ -0,0 +1,11 @@ + + + Fixture title + + +

Index page

+

This is a fixture page

+ + + diff --git a/tests/fixtures/page-01.html b/tests/fixtures/page-01.html new file mode 100644 index 000000000..4779eba84 --- /dev/null +++ b/tests/fixtures/page-01.html @@ -0,0 +1,8 @@ + + + Fixture 01 + + +

Fixture 01

+ + diff --git a/tests/mist/basic.test.js b/tests/mist/basic.test.js new file mode 100644 index 000000000..74ef89ff2 --- /dev/null +++ b/tests/mist/basic.test.js @@ -0,0 +1,230 @@ +const _ = require('underscore'); +const Q = require('bluebird'); +const fs = require('fs'); +const path = require('path'); +const should = require('chai').should(); + +const test = require('../_base').mocha(module, { + app: 'mist', +}); + +test['Check for Mist title'] = function* () { + (yield this.client.getTitle()).should.eql('Mist'); +}; + +test['Sanity Check: main window is focused'] = function* () { + const client = this.client; + (yield client.getUrl()).should.match(/interface\/index\.html$/); +}; + +// FAILING ON TRAVIS +test['Browser bar should render urls with separators'] = function* () { + const client = this.client; + + yield this.navigateTo('http://localhost:8080/page1/page2?param=value#hash'); + yield this.waitForText('.url-breadcrumb', 'http://localhost:8080 ▸ page1 ▸ page2 ▸ param=value ▸ hash'); +}; + +test['Browser bar should not render script tags on breadcrumb view'] = function* () { // ETH-01-001 + const client = this.client; + + yield this.navigateTo(''); + yield client.waitUntil(() => { + return client.getText('.url-breadcrumb').then((e) => { + return /404\.html$/.test(e); + }); + }, 5000, 'expected breadcrumb to render as HTML encoded'); + + should.exist(yield this.getUiElement('form.url')); + should.not.exist(yield this.getUiElement('form.url script')); +}; + +test['Browser bar should not render script tags in disguise on breadcrumb view'] = function* () { // ETH-01-001 + const client = this.client; + + yield client.setValue('#url-input', '<script>alert()</script>'); + const isUrlBlocked = (yield client.execute(() => { // Code executed in context of browser + try { $('form.url').submit(); } + catch(e) { return /Invalid URL/.test(e); } + return false; + })).value; + + isUrlBlocked.should.be.true; + should.not.exist(yield this.getUiElement('form.url script')); +}; + +test['Browser bar should not render script tags in disguise (2) on breadcrumb view'] = function* () { // ETH-01-001 + const client = this.client; + + yield this.navigateTo(''); + yield client.waitUntil(() => { + return client.getText('.url-breadcrumb').then((e) => { + return /404\.html$/.test(e); + }); + }, 5000, 'expected breadcrumb to render as HTML encoded'); + + should.exist(yield this.getUiElement('form.url')); + should.not.exist(yield this.getUiElement('form.url svg')); + should.not.exist(yield this.getUiElement('form.url script')); +}; + +test['Browser bar should not render arbitrary code as HTML'] = function* () { // ETH-01-001 + const client = this.client; + + yield client.waitUntil(() => { + return client.getText('.url-breadcrumb', (e) => { + return e === '%3Ciframe onload="alert%28%29%"%3E'; + }); + }, 5000, 'expected breadcrumb to render as HTML encoded'); +}; + +test['Browser bar should not execute JS'] = function* () { // ETH-01-001 + const client = this.client; + + yield this.navigateTo(''); + const mist = yield client.execute(() => { return window.mist }); // checking if `execute` works + const pwned = yield client.execute(() => { return window.pwned }); + + should.exist(mist.value); + should.not.exist(pwned.value); +}; + +test['Should select Wallet and Browse tabs properly'] = function* () { + const client = this.client; + const walletTab = yield this.selectTab('wallet'); +}; + +test['Load fixture page'] = function* () { + const client = this.client; + yield this.loadFixture(); +}; + +test['"http://" protocol should be allowed on browser bar'] = function* () { // ETH-01-002 + const client = this.client; + yield this.loadFixture(); + + yield client.setValue('#url-input', `${this.fixtureBaseUrl}index.html`); + const isProtocolBlocked = (yield client.execute(() => { // Code executed in context of browser + try { $('form.url').submit(); } + catch(e) { return /Invalid URL/.test(e); } + return false; + })).value; + isProtocolBlocked.should.be.false; + + yield this.waitForText('.url-breadcrumb', 'http://localhost:8080 ▸ index.html'); + + const browserBarText = yield this.client.getText('.url-breadcrumb'); + browserBarText.should.eql('http://localhost:8080 ▸ index.html'); // checks that did change displayed URL +}; + +test['"javascript:" protocol should be disallowed on browser bar'] = function* () { // ETH-01-002 + const client = this.client; + yield this.loadFixture(); + yield client.setValue('#url-input', 'javascript:window.close()'); + + const isProtocolBlocked = (yield client.execute(() => { // Code executed in context of browser + try { $('form.url').submit(); } + catch(e) { return /Invalid URL/.test(e); } + return false; + })).value; + isProtocolBlocked.should.be.true; + + yield Q.delay(500); + const browserBarText = yield this.getBrowserBarText(); + browserBarText.should.eql('http://localhost:8080'); // checks that hasn't changed displayed URL +}; + +test['"data:" protocol should be disallowed on browser bar'] = function* () { // ETH-01-002 + const client = this.client; + yield this.loadFixture(); + yield client.setValue('#url-input', 'data:text/plain;charset=utf-8;base64,dGhpcyB0ZXN0IGlzIG9uIGZpcmU='); + + const isProtocolBlocked = (yield client.execute(() => { // Code executed in context of browser + try { $('form.url').submit(); } + catch(e) { return /Invalid URL/.test(e); } + return false; + })).value; + isProtocolBlocked.should.be.true; + + yield Q.delay(500); + const browserBarText = yield this.getBrowserBarText(); + browserBarText.should.eql('http://localhost:8080'); // checks that hasn't changed displayed URL +}; + +// test['"file:///" protocol should be disallowed'] = function* () { // ETH-01-002 +// const client = this.client; +// const filePath = 'file://' + path.join(__dirname, '..', 'fixtures', 'index.html'); + +// yield this.navigateTo(filePath); +// yield Q.delay(1500); +// const browserBarText = yield this.getBrowserBarText(); +// browserBarText.should.match(/errorPages ▸ 400.html$/); +// }; + +test['Pin tab test'] = function* () { + const client = this.client; + const sidebarItems = (yield client.elements('.sidebar nav > ul > li')).value; + + yield this.selectTab('browser'); + yield this.pinCurrentTab(); + + const sidebarItemsAfterAdd = (yield client.elements('.sidebar nav > ul > li')).value; + + sidebarItems.length.should.eql(2); + sidebarItemsAfterAdd.length.should.eql(3); +}; + +// test['Browse tab should be changed to pinned tab if the URL is the same'] = function* () { // ETH-01-007 +// const client = this.client; +// yield this.selectTab('browser'); + +// yield this.navigateTo('https://wallet.ethereum.org' ); +// yield Q.delay(1000); +// const el = (yield client.element('.sidebar nav > ul > .selected')); +// console.log('el', el); + +// el.getAttribute('data-tab-id').should.eql('wallet'); + +// }; + +// test['Wallet tab shouldn\'t have the page replaced if URLs does not match'] = function* () { // ETH-01-007 +// const client = this.client; +// const app = this; +// yield this.selectTab('wallet'); + +// yield this.navigateTo(`${this.fixtureBaseUrl}index.html?https://wallet.ethereum.org`); +// yield client.waitUntil(() => { +// return client.element('.sidebar nav > ul > .selected').then((e) => { +// console.log('e', e); +// return e.getAttribute('data-tab-id') === 'browse'; +// }); +// }, 2000); +// }; + +// test['Wallet tab shouldn\'t have the page replaced if URLs does not match - 2'] = function* () { // ETH-01-007 +// const client = this.client; +// const app = this; +// yield this.selectTab('wallet'); + +// // Now changing address via JS +// yield client.setValue('#url-input', `${this.fixtureBaseUrl}index.html?https://wallet.ethereum.org`); +// const isProtocolBlocked = yield client.execute(() => { // Code executed in context of browser +// $('form.url').submit(); +// }); + +// yield client.waitUntil(() => { +// return client.element('.sidebar nav > ul > .selected').then((e) => { +// console.log('e', e); +// return e.getAttribute('data-tab-id') === 'browser'; +// }); +// }, 2000); +// }; + +test['Links with target _blank or _popup should open inside Mist'] = function* () { + const client = this.client; + yield this.navigateTo(`${this.fixtureBaseUrl}/fixture-popup.html`); + yield this.getWindowByUrl(e => /popup.html$/.test(e)); + + // TODO: click on the fixtures' links and assert if they opened on the same page +}; + diff --git a/tests/mocha-in-browser/spec/general-spec.js b/tests/mocha-in-browser/spec/general-spec.js index d5773843b..5a4786b95 100644 --- a/tests/mocha-in-browser/spec/general-spec.js +++ b/tests/mocha-in-browser/spec/general-spec.js @@ -26,6 +26,7 @@ describe('General', function () { 'requestAccount', 'sounds', 'menu', + 'solidity' ]; expect(mist).to.have.all.keys(allowedAttributes); @@ -34,10 +35,18 @@ describe('General', function () { it('should return platform', function () { expect(mist.platform).to.be.oneOf(['darwin', 'win32', 'freebsd', 'linux', 'sunos']); }); + + it('should report solidity version', function () { + expect(mist.solidity.version).to.match(/^\d\.\d{1,2}\.\d{1,2}$/); // match examples: 0.4.6, 0.5.10, 0.10.0 + }); }); describe('mist.menu', function () { - beforeEach(function () { + before(function () { + mist.menu.clear(); + }); + + afterEach(function () { mist.menu.clear(); }); diff --git a/tests/wallet/basic.test.js b/tests/wallet/basic.test.js index 4f1c2763d..c338f1ab5 100644 --- a/tests/wallet/basic.test.js +++ b/tests/wallet/basic.test.js @@ -8,13 +8,12 @@ const test = require('../_base').mocha(module, { app: 'wallet', }); +test['Title test'] = function* () { + const client = this.client; -test.title = function* () { - yield this.client.window(this.mainWindowHandle); - - (yield this.client.getTitle()).should.eql('Ethereum Wallet'); -}; - + yield client.waitUntilWindowLoaded(); + (yield client.getTitle()).should.eql('Ethereum Wallet'); +} test['account balances'] = function* () { const web3 = this.web3; @@ -23,6 +22,8 @@ test['account balances'] = function* () { const realBalances = this.getRealAccountBalances(); const appBalances = this.getUiAccountBalances(); + realBalances.should.not.be.null; + realBalances.should.eql('5'); appBalances.should.eql(realBalances); }; diff --git a/yarn.lock b/yarn.lock index ec86b88a9..31cca18ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,22 +69,14 @@ ansi-align@^1.1.0: dependencies: string-width "^1.0.1" -ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: +ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" -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" - ansi-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" -ansi-styles@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" - ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -113,19 +105,6 @@ archiver@1.0.0: tar-stream "^1.5.0" zip-stream "^1.0.0" -archiver@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-1.2.0.tgz#fb5c6af5443b3fa6a426344753bad2a7b444aadd" - dependencies: - archiver-utils "^1.3.0" - async "^2.0.0" - buffer-crc32 "^0.2.1" - glob "^7.0.0" - lodash "^4.8.0" - readable-stream "^2.0.0" - tar-stream "^1.5.0" - zip-stream "^1.1.0" - archy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" @@ -172,10 +151,6 @@ arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" -asap@^2.0.0, asap@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" - asar-electron-builder@^0.13.5: version "0.13.5" resolved "https://registry.yarnpkg.com/asar-electron-builder/-/asar-electron-builder-0.13.5.tgz#4ccd4d11fd7c9d3b3cffc782fde3deed9ef91af6" @@ -202,11 +177,15 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" -async@1.x, async@^1.2.1, async@^1.4.0, async@^1.5.0: +async@1.x, async@^1.4.0, async@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@>=0.1.0, async@^2.0.0, async@^2.0.1: +async@>=0.1.0, async@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25" dependencies: @@ -246,12 +225,12 @@ babel-runtime@^5.8.25: dependencies: core-js "^1.0.0" -babel-runtime@^6.18.0, babel-runtime@^6.9.2: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.18.0.tgz#0f4177ffd98492ef13b9f823e9994a02584c9078" +babel-runtime@^6.22.0, babel-runtime@^6.9.2: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611" dependencies: core-js "^2.4.0" - regenerator-runtime "^0.9.5" + regenerator-runtime "^0.10.0" balanced-match@^0.4.1: version "0.4.2" @@ -271,9 +250,9 @@ beeper@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" -bignumber.js@^2.1.4: - version "2.4.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" +bignumber.js@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.0.0.tgz#26b23a3240820fb6b875f07de822004c7d34b682" "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": version "2.0.7" @@ -300,15 +279,15 @@ bl@^1.0.0, bl@~1.1.2: dependencies: readable-stream "~2.0.5" -bluebird-lst-c@^1.0.4, bluebird-lst-c@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bluebird-lst-c/-/bluebird-lst-c-1.0.5.tgz#50da657dcde337a0e29d9e080ba714c5a52016e2" +bluebird-lst-c@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/bluebird-lst-c/-/bluebird-lst-c-1.0.6.tgz#81f881d13f9df700f67d577f13480bc32d84bba9" dependencies: - bluebird "^3.4.6" + bluebird "^3.4.7" -bluebird@^3.3.4, bluebird@^3.3.5, bluebird@^3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" +bluebird@^3.3.4, bluebird@^3.4.7: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" bn.js@^4.10.0, bn.js@^4.11.3, bn.js@^4.4.0, bn.js@^4.8.0: version "4.11.6" @@ -353,6 +332,10 @@ brorand@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.0.6.tgz#4028706b915f91f7b349a2e0bf3c376039d216e5" +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + browserify-aes@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" @@ -448,6 +431,16 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chai-as-promised: + version "6.0.0" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-6.0.0.tgz#1a02a433a6f24dafac63b9c96fa1684db1aa8da6" + dependencies: + check-error "^1.0.2" + +chai-string: + version "1.3.0" + resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.3.0.tgz#df6139f294391b1035be5606f60a843b3a5041e7" + chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" @@ -472,20 +465,18 @@ chalk@*, 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@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" - dependencies: - ansi-styles "^1.1.0" - escape-string-regexp "^1.0.0" - has-ansi "^0.1.0" - strip-ansi "^0.3.0" - supports-color "^0.2.0" +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" chromium-pickle-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" +ci-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" + cipher-base@^1.0.0, cipher-base@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07" @@ -500,7 +491,7 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" -cli-cursor@^1.0.1, cli-cursor@^1.0.2: +cli-cursor@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" dependencies: @@ -526,7 +517,7 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -clone-stats@^0.0.1, clone-stats@~0.0.1: +clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" @@ -538,9 +529,9 @@ clone@^1.0.0, clone@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" -co-mocha@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.1.3.tgz#49bb9c85bcd17e3250f8b84b875dc76668bc41dc" +co-mocha@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.2.0.tgz#d9be35a2a2d16f4b1b0e83f6973401ca4b6660af" dependencies: co "^4.0.0" is-generator "^1.0.1" @@ -563,15 +554,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" - -commander@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" - -commander@^2.9.0: +commander@2.9.0, commander@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: @@ -737,33 +720,33 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -dateformat@^1.0.11, dateformat@^1.0.7-1.2.3: +date-format@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-0.0.0.tgz#09206863ab070eb459acea5542cbd856b11966b3" + +dateformat@^1.0.11: version "1.0.12" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" dependencies: get-stdin "^4.0.1" meow "^3.3.0" -debug@0.7.4: +debug@0.7.4, debug@^0.7.2: version "0.7.4" resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" -debug@2.2.0, debug@^2.2.0: +debug@2.2.0, debug@^2.1.1, debug@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: ms "0.7.1" -debug@^2.1.1, debug@^2.1.3, debug@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" +debug@2.6.0, debug@^2.1.3, debug@^2.3.2, debug@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" dependencies: ms "0.7.2" -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -838,7 +821,7 @@ deep-extend@~0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" -deep-is@~0.1.2, deep-is@~0.1.3: +deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -852,18 +835,7 @@ defaults@^1.0.0: dependencies: clone "^1.0.2" -del@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/del/-/del-1.2.1.tgz#aed6e5bcd7cb7325df34f563125fa265b2c1a014" - dependencies: - each-async "^1.0.0" - globby "^2.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^3.0.0" - rimraf "^2.2.8" - -del@^2.0.2: +del@^2.0.2, del@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" dependencies: @@ -893,25 +865,11 @@ dev-null@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/dev-null/-/dev-null-0.1.1.tgz#5a205ce3c2b2ef77b6238d6ba179eb74c6a0e818" -dezalgo@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - dependencies: - asap "^2.0.0" - wrappy "1" - diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" -doctrine@1.3.x: - version "1.3.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.3.0.tgz#13e75682b55518424276f7c173783456ef913d26" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^1.2.2: +doctrine@1.5.0, doctrine@^1.2.2: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" dependencies: @@ -957,67 +915,88 @@ duplexify@^3.2.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -each-async@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/each-async/-/each-async-1.1.1.tgz#dee5229bdf0ab6ba2012a395e1b869abf8813473" - dependencies: - onetime "^1.0.0" - set-immediate-shim "^1.0.0" - ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" dependencies: jsbn "~0.1.0" +ecstatic: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-2.1.0.tgz#477a4a6b25cecb112f697dbd2c7fa354154ea6be" + dependencies: + he "^0.5.0" + mime "^1.2.11" + minimist "^1.1.0" + url-join "^1.0.0" + ejs@^2.3.1: version "2.5.3" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.3.tgz#bfeae1e2f7fa51c4527769fcaa14c5ca73eb5e47" -electron-builder@=9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-9.1.0.tgz#dce80e1e44791d635f01d4466225ed6383cc7f82" +electron-builder-core@11.2.1: + version "11.2.1" + resolved "https://registry.yarnpkg.com/electron-builder-core/-/electron-builder-core-11.2.1.tgz#1dca8c1a1cee8b51750b7708a04913aeffacf8a8" + +electron-builder-http@12.1.0, electron-builder-http@~12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/electron-builder-http/-/electron-builder-http-12.1.0.tgz#4469498f36a5c7af74a94c637b4d874ca1300b7e" + dependencies: + debug "2.6.0" + fs-extra-p "^3.1.0" + +electron-builder-util@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/electron-builder-util/-/electron-builder-util-12.1.0.tgz#2d2ef87ba54710cc35caa1a0d3b80dcc4f52eb30" + dependencies: + "7zip-bin" "^2.0.4" + bluebird-lst-c "^1.0.6" + chalk "^1.1.3" + debug "2.6.0" + electron-builder-http "~12.1.0" + fs-extra-p "^3.1.0" + is-ci "^1.0.10" + node-emoji "^1.5.1" + source-map-support "^0.4.11" + stat-mode "^0.2.2" + +electron-builder@^12.2.2: + version "12.2.2" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-12.2.2.tgz#f26979e27bd9232acf8f8de720816186ddf36470" dependencies: "7zip-bin" "^2.0.4" - ansi-escapes "^1.4.0" - archiver "^1.2.0" - archiver-utils "^1.3.0" asar-electron-builder "^0.13.5" - bluebird-lst-c "^1.0.5" + bluebird-lst-c "^1.0.6" chalk "^1.1.3" chromium-pickle-js "^0.2.0" - cli-cursor "^1.0.2" cuint "^0.2.2" - debug "^2.3.2" + electron-builder-core "11.2.1" + electron-builder-http "12.1.0" + electron-builder-util "12.1.0" electron-download-tf "3.1.0" - electron-macos-sign "^1.3.4" - fs-extra-p "^2.0.7" + electron-macos-sign "~1.5.0" + fs-extra-p "^3.1.0" hosted-git-info "^2.1.5" ini "^1.3.4" - isbinaryfile "^3.0.1" + is-ci "^1.0.10" + isbinaryfile "^3.0.2" js-yaml "^3.7.0" - lodash.template "^4.4.0" mime "^1.3.4" minimatch "^3.0.3" - node-emoji "^1.4.1" normalize-package-data "^2.3.5" parse-color "^1.0.0" plist "^2.0.1" - pretty-ms "^2.1.0" progress "^1.1.8" - progress-stream "^1.2.0" - read-installed "^4.0.3" sanitize-filename "^1.6.1" semver "^5.3.0" - source-map-support "^0.4.6" tunnel-agent "^0.4.3" - update-notifier "^1.0.2" + update-notifier "^1.0.3" uuid-1345 "^0.99.6" - yargs "^6.4.0" + yargs "^6.6.0" -electron-chromedriver@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/electron-chromedriver/-/electron-chromedriver-1.4.0.tgz#8e3fad1113288e9988a193eab279e36c2cd32103" +electron-chromedriver@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/electron-chromedriver/-/electron-chromedriver-1.3.2.tgz#4cb41d8cba675a5eaf4c9aebce8dc405e1347f92" dependencies: decompress "^3.0.0" mkdirp "^0.5.1" @@ -1050,15 +1029,14 @@ electron-download@^3.0.1: semver "^5.3.0" sumchecker "^1.2.0" -electron-macos-sign@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/electron-macos-sign/-/electron-macos-sign-1.3.4.tgz#641e011f974b26879f05ac505dde94b86481376a" +electron-macos-sign@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/electron-macos-sign/-/electron-macos-sign-1.5.0.tgz#fe3a8acb755b5f568f1fe144e9e66cee44019448" dependencies: - bluebird "^3.4.6" + bluebird "^3.4.7" compare-version "^0.1.2" - debug "^2.3.2" - isbinaryfile "^3.0.1" - minimist "^1.2.0" + debug "^2.6.0" + isbinaryfile "^3.0.2" plist "^2.0.1" electron-squirrel-startup@^1.0.0: @@ -1137,7 +1115,7 @@ es6-promise@^3.2.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" -es6-set@^0.1.4, es6-set@~0.1.3: +es6-set@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" dependencies: @@ -1163,22 +1141,18 @@ es6-weak-map@^2.0.1: es6-iterator "2" es6-symbol "3" -escape-string-regexp@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" - -escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escodegen@1.7.x: - version "1.7.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.7.1.tgz#30ecfcf66ca98dc67cd2fd162abeb6eafa8ce6fc" +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" dependencies: - esprima "^1.2.2" + esprima "^2.7.1" estraverse "^1.9.1" esutils "^2.0.2" - optionator "^0.5.0" + optionator "^0.8.1" optionalDependencies: source-map "~0.2.0" @@ -1191,9 +1165,9 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-config-airbnb-base@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-8.0.0.tgz#c5e958a469ab8af76aff068b43d784e5afe74ca7" +eslint-config-airbnb-base@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.0.1.tgz#5401dba284c6b7d7c8fb1c2ee19aba018f9dfa21" eslint-import-resolver-node@^0.2.0: version "0.2.3" @@ -1203,30 +1177,31 @@ eslint-import-resolver-node@^0.2.0: object-assign "^4.0.1" resolve "^1.1.6" -eslint-plugin-import@^1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-1.16.0.tgz#b2fa07ebcc53504d0f2a4477582ec8bff1871b9f" +eslint-module-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" + dependencies: + debug "2.2.0" + pkg-dir "^1.0.0" + +eslint-plugin-import@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" debug "^2.2.0" - doctrine "1.3.x" - es6-map "^0.1.3" - es6-set "^0.1.4" + doctrine "1.5.0" eslint-import-resolver-node "^0.2.0" + eslint-module-utils "^2.0.0" has "^1.0.1" lodash.cond "^4.3.0" - lodash.endswith "^4.0.1" - lodash.find "^4.3.0" - lodash.findindex "^4.3.0" minimatch "^3.0.3" - object-assign "^4.0.1" - pkg-dir "^1.0.0" pkg-up "^1.0.0" -eslint@^3.8.0: - version "3.11.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.11.1.tgz#408be581041385cba947cd8d1cd2227782b55dbf" +eslint@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.14.1.tgz#8a62175f2255109494747a1b25128d97b8eb3d97" dependencies: babel-code-frame "^6.16.0" chalk "^1.1.3" @@ -1239,7 +1214,7 @@ eslint@^3.8.0: esutils "^2.0.2" file-entry-cache "^2.0.0" glob "^7.0.3" - globals "^9.2.0" + globals "^9.14.0" ignore "^3.2.0" imurmurhash "^0.1.4" inquirer "^0.12.0" @@ -1258,7 +1233,7 @@ eslint@^3.8.0: require-uncached "^1.0.2" shelljs "^0.7.5" strip-bom "^3.0.0" - strip-json-comments "~1.0.1" + strip-json-comments "~2.0.1" table "^3.7.8" text-table "~0.2.0" user-home "^2.0.0" @@ -1270,15 +1245,7 @@ espree@^3.3.1: acorn "^4.0.1" acorn-jsx "^3.0.0" -esprima@2.5.x: - version "2.5.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.5.0.tgz#f387a46fd344c1b1a39baf8c20bfb43b6d0058cc" - -esprima@^1.2.2: - version "1.2.5" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9" - -esprima@^2.6.0: +esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -1318,6 +1285,13 @@ ethereum-client-binaries@^1.6.1: node-unzip-2 "^0.2.1" tmp "0.0.29" +ethereum-keyfile-recognizer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ethereum-keyfile-recognizer/-/ethereum-keyfile-recognizer-1.0.2.tgz#c0315f91c77e076621e9f6b5f8099fd370f7a11d" + dependencies: + json-structure-diff "0.0.2" + underscore "^1.8.3" + ethereumjs-abi@^0.6.3: version "0.6.4" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.4.tgz#9ba1bb056492d00c27279f6eccd4d58275912c1a" @@ -1414,10 +1388,6 @@ fancy-log@^1.1.0: chalk "^1.1.1" time-stamp "^1.0.0" -fast-levenshtein@~1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz#0178dcdee023b92905193af0959e8a7639cfdcb9" - fast-levenshtein@~2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.5.tgz#bd33145744519ab1c36c3ee9f31f08e9079b67f2" @@ -1450,13 +1420,6 @@ filename-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" -fileset@0.2.x: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.2.1.tgz#588ef8973c6623b2a76df465105696b96aac8067" - dependencies: - glob "5.x" - minimatch "2.x" - fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -1554,20 +1517,12 @@ fs-exists-sync@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" -fs-extra-p@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-2.0.7.tgz#525a86ee1250510210defe1ea39f473c23ecfa96" - dependencies: - bluebird-lst-c "^1.0.4" - fs-extra-tf "^1.0.0" - -fs-extra-tf@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra-tf/-/fs-extra-tf-1.0.0.tgz#77d3d7dc2199fbc618a42fe5ea81137db95eeb2e" +fs-extra-p@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-3.1.0.tgz#eddf7bb8d9385d79014decb21f45b1d0c57900d3" dependencies: - graceful-fs "^4.1.10" - jsonfile "^2.4.0" - klaw "^1.3.1" + bluebird-lst-c "^1.0.6" + fs-extra "^2.0.0" fs-extra@^0.30.0: version "0.30.0" @@ -1587,6 +1542,13 @@ fs-extra@^1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" +fs-extra@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.0.0.tgz#337352bded4a0b714f3eb84de8cea765e9d37600" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1632,12 +1594,9 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" -get-stream@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" geth-private@^1.3.0: version "1.7.0" @@ -1656,6 +1615,16 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gh-release-assets@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gh-release-assets/-/gh-release-assets-1.1.0.tgz#00f76bd151d020032de10712f525d2a944814595" + dependencies: + async "^0.9.0" + mime "^1.3.4" + progress-stream "^1.1.1" + request "^2.55.0" + util-extend "^1.0.1" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -1712,20 +1681,14 @@ glob2base@^0.0.12: dependencies: find-index "^0.1.1" -glob@3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" - dependencies: - inherits "2" - minimatch "0.3" - -glob@5.x, glob@^5.0.3: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" +glob@7.0.5, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" dependencies: + fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "2 || 3" + minimatch "^3.0.2" once "^1.3.0" path-is-absolute "^1.0.0" @@ -1738,9 +1701,9 @@ glob@^4.3.1: minimatch "^2.0.1" once "^1.3.0" -glob@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" +glob@^5.0.15, glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: inflight "^1.0.4" inherits "2" @@ -1748,17 +1711,6 @@ glob@^6.0.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@~3.1.21: version "3.1.21" resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" @@ -1783,19 +1735,10 @@ global-prefix@^0.1.4: osenv "^0.1.3" which "^1.2.10" -globals@^9.2.0: +globals@^9.14.0: version "9.14.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" -globby@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-2.1.0.tgz#9e9192bcd33f4ab6a4f894e5e7ea8b713213c482" - dependencies: - array-union "^1.0.1" - async "^1.2.1" - glob "^5.0.3" - object-assign "^3.0.0" - globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -1841,19 +1784,19 @@ got@^5.0.0: unzip-response "^1.0.2" url-parse-lax "^1.0.0" -got@^6.3.0, got@^6.5.0: - version "6.6.3" - resolved "https://registry.yarnpkg.com/got/-/got-6.6.3.tgz#ff72c56d7f040eb8918ffb80fb62bcaf489d4eec" +got@^6.5.0, got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" dependencies: create-error-class "^3.0.0" duplexer3 "^0.1.4" - get-stream "^2.3.0" + get-stream "^3.0.0" is-redirect "^1.0.0" is-retry-allowed "^1.0.0" is-stream "^1.0.0" lowercase-keys "^1.0.0" - node-status-codes "^2.0.0" - timed-out "^3.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" unzip-response "^2.0.1" url-parse-lax "^1.0.0" @@ -1863,11 +1806,7 @@ graceful-fs@^3.0.0, graceful-fs@~3.0.2: dependencies: natives "^1.1.0" -graceful-fs@^4.0.0, graceful-fs@^4.1.10, 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-fs@^4.1.0, graceful-fs@^4.1.2: +graceful-fs@^4.0.0, graceful-fs@^4.1.0, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.9" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.9.tgz#baacba37d19d11f9d146d3578bc99958c3787e29" @@ -1900,17 +1839,15 @@ gulp-sourcemaps@1.6.0: through2 "^2.0.0" vinyl "^1.0.0" -gulp-spawn-mocha@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/gulp-spawn-mocha/-/gulp-spawn-mocha-2.2.2.tgz#c2aaa353d3e8ef8930b2dc39fb1d72148959ed35" +gulp-spawn-mocha@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/gulp-spawn-mocha/-/gulp-spawn-mocha-3.1.0.tgz#b11e3b8e3b3d3ed1c88de5624de42a9e780c27c3" dependencies: - gulp-util "~2.2.10" - istanbul "^0.3.5" - lodash "^3.0.1" - mocha "^2" + gulp-util "~3.0.7" + lodash "^4.11.1" through "~2.3.4" -gulp-util@*, gulp-util@^3.0.0, gulp-util@^3.0.7: +gulp-util@*, gulp-util@^3.0.0, gulp-util@^3.0.7, gulp-util@~3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.7.tgz#78925c4b8f8b49005ac01a011c557e6218941cbb" dependencies: @@ -1933,19 +1870,6 @@ gulp-util@*, gulp-util@^3.0.0, gulp-util@^3.0.7: through2 "^2.0.0" vinyl "^0.5.0" -gulp-util@~2.2.10: - version "2.2.20" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-2.2.20.tgz#d7146e5728910bd8f047a6b0b1e549bc22dbd64c" - dependencies: - chalk "^0.5.0" - dateformat "^1.0.7-1.2.3" - lodash._reinterpolate "^2.4.1" - lodash.template "^2.4.1" - minimist "^0.2.0" - multipipe "^0.1.0" - through2 "^0.5.0" - vinyl "^0.2.1" - gulp@^3.9.0: version "3.9.1" resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" @@ -1989,12 +1913,6 @@ har-validator@~2.0.6: is-my-json-valid "^2.12.4" pinkie-promise "^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" - dependencies: - ansi-regex "^0.2.0" - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -2032,6 +1950,10 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +he@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2044,18 +1966,6 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" -http-basic@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-2.5.1.tgz#8ce447bdb5b6c577f8a63e3fa78056ec4bb4dbfb" - dependencies: - caseless "~0.11.0" - concat-stream "^1.4.6" - http-response-object "^1.0.0" - -http-response-object@^1.0.0, http-response-object@^1.0.1, http-response-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-1.1.0.tgz#a7c4e75aae82f3bb4904e4f43f615673b4d518c3" - http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -2064,9 +1974,9 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" -i18next@^2.3.4: - version "2.5.1" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-2.5.1.tgz#597c833e4b72b766a089f9b4cd8181df5577127b" +i18next@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-6.1.1.tgz#69a2c24993f99a4ef90fcac61c13c6007caff0ab" ignore@^3.2.0: version "3.2.0" @@ -2177,6 +2087,12 @@ is-bzip2@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-bzip2/-/is-bzip2-1.0.0.tgz#5ee58eaa5a2e9c80e21407bedf23ae5ac091b3fc" +is-ci@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + dependencies: + ci-info "^1.0.0" + is-dotfile@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" @@ -2199,7 +2115,7 @@ is-extglob@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.0.tgz#33411a482b046bf95e6b0cb27ee2711af4cf15ad" -is-finite@^1.0.0, is-finite@^1.0.1: +is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" dependencies: @@ -2360,9 +2276,9 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isbinaryfile@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.1.tgz#6e99573675372e841a0520c036b41513d783e79e" +isbinaryfile@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" isexe@^1.1.1: version "1.1.2" @@ -2378,15 +2294,15 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" -istanbul@^0.3.5: - version "0.3.22" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.3.22.tgz#3e164d85021fe19c985d1f0e7ef0c3e22d012eb6" +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.7.x" - esprima "2.5.x" - fileset "0.2.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" @@ -2397,17 +2313,6 @@ istanbul@^0.3.5: which "^1.1.1" wordwrap "^1.0.0" -jade@0.26.3: - version "0.26.3" - resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" - dependencies: - commander "0.6.1" - mkdirp "0.3.0" - -jju@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jju/-/jju-1.3.0.tgz#dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa" - jodid25519@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" @@ -2433,12 +2338,6 @@ jsbn@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" -json-parse-helpfulerror@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" - dependencies: - jju "^1.1.0" - json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -2453,7 +2352,15 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -jsonfile@^2.1.0, jsonfile@^2.4.0: +json-structure-diff@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/json-structure-diff/-/json-structure-diff-0.0.2.tgz#838277f5c0a9562981b9a2af86fe5e90c131b0b3" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" optionalDependencies: @@ -2488,7 +2395,7 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.0.2" -klaw@^1.0.0, klaw@^1.3.1: +klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" optionalDependencies: @@ -2527,13 +2434,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -levn@~0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054" - dependencies: - prelude-ls "~1.1.0" - type-check "~0.3.1" - liftoff@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" @@ -2558,10 +2458,21 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + lodash._basetostring@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" @@ -2570,36 +2481,14 @@ lodash._basevalues@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" -lodash._escapehtmlchar@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" - dependencies: - lodash._htmlescapes "~2.4.1" - -lodash._escapestringchar@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz#ecfe22618a2ade50bfeea43937e51df66f0edb72" - lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" -lodash._htmlescapes@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz#32d14bf0844b6de6f8b62a051b4f67c228b624cb" - lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" -lodash._isnative@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" - -lodash._objecttypes@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" - lodash._reescape@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" @@ -2608,31 +2497,14 @@ lodash._reevaluate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" -lodash._reinterpolate@^2.4.1, lodash._reinterpolate@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz#4f1227aa5a8711fc632f5b07a1f4607aab8b3222" - -lodash._reinterpolate@^3.0.0, lodash._reinterpolate@~3.0.0: +lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" -lodash._reunescapedhtml@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz#747c4fc40103eb3bb8a0976e571f7a2659e93ba7" - dependencies: - lodash._htmlescapes "~2.4.1" - lodash.keys "~2.4.1" - lodash._root@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" -lodash._shimkeys@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" - dependencies: - lodash._objecttypes "~2.4.1" - lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -2645,16 +2517,13 @@ lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" -lodash.defaults@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" dependencies: - lodash._objecttypes "~2.4.1" - lodash.keys "~2.4.1" - -lodash.endswith@^4.0.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" lodash.escape@^3.0.0: version "3.2.0" @@ -2662,22 +2531,6 @@ lodash.escape@^3.0.0: dependencies: lodash._root "^3.0.0" -lodash.escape@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-2.4.1.tgz#2ce12c5e084db0a57dda5e5d1eeeb9f5d175a3b4" - dependencies: - lodash._escapehtmlchar "~2.4.1" - lodash._reunescapedhtml "~2.4.1" - lodash.keys "~2.4.1" - -lodash.find@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" - -lodash.findindex@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106" - lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -2698,12 +2551,6 @@ lodash.isequal@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031" -lodash.isobject@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" - dependencies: - lodash._objecttypes "~2.4.1" - lodash.isplainobject@^4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -2720,14 +2567,6 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.keys@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" - dependencies: - lodash._isnative "~2.4.1" - lodash._shimkeys "~2.4.1" - lodash.isobject "~2.4.1" - lodash.mapvalues@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" @@ -2740,18 +2579,6 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" -lodash.template@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-2.4.1.tgz#9e611007edf629129a974ab3c48b817b3e1cf20d" - dependencies: - lodash._escapestringchar "~2.4.1" - lodash._reinterpolate "~2.4.1" - lodash.defaults "~2.4.1" - lodash.escape "~2.4.1" - lodash.keys "~2.4.1" - lodash.templatesettings "~2.4.1" - lodash.values "~2.4.1" - lodash.template@^3.0.0: version "3.6.2" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" @@ -2766,13 +2593,6 @@ lodash.template@^3.0.0: lodash.restparam "^3.0.0" lodash.templatesettings "^3.0.0" -lodash.template@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" - dependencies: - lodash._reinterpolate "~3.0.0" - lodash.templatesettings "^4.0.0" - lodash.templatesettings@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" @@ -2780,34 +2600,11 @@ lodash.templatesettings@^3.0.0: lodash._reinterpolate "^3.0.0" lodash.escape "^3.0.0" -lodash.templatesettings@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" - dependencies: - lodash._reinterpolate "~3.0.0" - -lodash.templatesettings@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz#ea76c75d11eb86d4dbe89a83893bb861929ac699" - dependencies: - lodash._reinterpolate "~2.4.1" - lodash.escape "~2.4.1" - lodash.values@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-4.3.0.tgz#a3a6c2b0ebecc5c2cba1c17e6e620fe81b53d347" -lodash.values@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" - dependencies: - lodash.keys "~2.4.1" - -lodash@^3.0.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" - -lodash@^4.0.0, lodash@^4.3.0, lodash@^4.8.0: +lodash@^4.0.0, lodash@^4.11.1, lodash@^4.3.0, lodash@^4.8.0: version "4.17.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42" @@ -2819,16 +2616,17 @@ log-rotate@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/log-rotate/-/log-rotate-0.2.7.tgz#aadb64259eea49e5668842342c864d0b142e8c2d" -log4js@^0.6.35: - version "0.6.38" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" +log4js@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-1.1.0.tgz#c7d2b616d91bbf47cc65fb79d6fe04581c8096fa" dependencies: - readable-stream "~1.0.2" - semver "~4.3.3" + debug "^2.2.0" + semver "^5.3.0" + streamroller "^0.2.1" -lokijs@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.4.1.tgz#ea17be92d2ea7caba1c816d6c2006424e8db0bfe" +lokijs@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.4.2.tgz#0f176380f9930d117946fc7c15ccb4ca001ddb4a" longest@^1.0.1: version "1.0.1" @@ -2928,24 +2726,17 @@ mime-types@^2.1.11, mime-types@~2.1.7: dependencies: mime-db "~1.25.0" -mime@^1.3.4: +mime@^1.2.11, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -minimatch@0.3: - version "0.3.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" - dependencies: - lru-cache "2" - sigmund "~1.0.0" - "minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" -minimatch@2.x, minimatch@^2.0.1: +minimatch@^2.0.1: version "2.0.10" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" dependencies: @@ -2962,10 +2753,6 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" - minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -2974,17 +2761,13 @@ minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" -minimongo-standalone@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/minimongo-standalone/-/minimongo-standalone-0.0.9.tgz#1c67a498ba83c479995c5fac60dcc5538f8c29b0" +minimongo-standalone@^1.1.0-3: + version "1.1.0-3" + resolved "https://registry.yarnpkg.com/minimongo-standalone/-/minimongo-standalone-1.1.0-3.tgz#cfdb3d0136811bab7fb92f6c13e0c74bd64dd5bd" dependencies: async ">=0.1.0" underscore ">=1.0.0" -mkdirp@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" - mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -2997,20 +2780,21 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mocha@^2: - version "2.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" +mocha@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" dependencies: - commander "2.3.0" + browser-stdout "1.3.0" + commander "2.9.0" debug "2.2.0" diff "1.4.0" - escape-string-regexp "1.0.2" - glob "3.2.11" + escape-string-regexp "1.0.5" + glob "7.0.5" growl "1.9.2" - jade "0.26.3" + json3 "3.3.2" + lodash.create "3.1.1" mkdirp "0.5.1" - supports-color "1.2.0" - to-iso-string "0.0.2" + supports-color "3.1.2" ms@0.7.1: version "0.7.1" @@ -3020,7 +2804,7 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -multipipe@^0.1.0, multipipe@^0.1.2: +multipipe@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" dependencies: @@ -3046,9 +2830,9 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -node-emoji@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.4.1.tgz#c9fa0cf91094335bcb967a6f42b2305c15af2ebc" +node-emoji@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.5.1.tgz#fd918e412769bf8c448051238233840b2aff16a1" dependencies: string.prototype.codepointat "^0.2.0" @@ -3056,10 +2840,6 @@ node-status-codes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" -node-status-codes@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-2.0.1.tgz#298067659cb68a2b4670abbefde02a3819981f5b" - node-unzip-2@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-unzip-2/-/node-unzip-2-0.2.1.tgz#8e4a0e5a68f7b03d33b8dc52b83a93d1d003cdd8" @@ -3085,7 +2865,7 @@ nopt@3.x: dependencies: abbrev "1" -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" dependencies: @@ -3120,9 +2900,9 @@ 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" -numeral@^1.5.3: - version "1.5.6" - resolved "https://registry.yarnpkg.com/numeral/-/numeral-1.5.6.tgz#3831db968451b9cf6aff9bf95925f1ef8e37b33f" +numeral@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.4.tgz#545a0c709e090a9cf79bebec802b93f60061f038" oauth-sign@~0.8.1: version "0.8.2" @@ -3174,18 +2954,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.5.0.tgz#b75a8995a2d417df25b6e4e3862f50aa88651368" - dependencies: - deep-is "~0.1.2" - fast-levenshtein "~1.0.0" - levn "~0.2.5" - prelude-ls "~1.1.1" - type-check "~0.3.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -3229,9 +2998,9 @@ os-shim@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" -os-timesync@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/os-timesync/-/os-timesync-1.0.6.tgz#0b315b0009ccbbd1796dedc38e3c590ac5cad1b7" +os-timesync@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/os-timesync/-/os-timesync-1.0.7.tgz#fc7ea7e6de1fc88742880cd08ff284327678e20d" os-tmpdir@^1.0.0, os-tmpdir@~1.0.1: version "1.0.2" @@ -3286,10 +3055,6 @@ parse-json@^2.1.0, parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-ms@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -3368,15 +3133,11 @@ plist@^2.0.1: xmlbuilder "8.2.2" xmldom "0.1.x" -plur@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" - pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" -prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2: +prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -3399,19 +3160,11 @@ pretty-hrtime@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" -pretty-ms@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" - dependencies: - is-finite "^1.0.1" - parse-ms "^1.0.0" - plur "^1.0.0" - 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" -progress-stream@^1.1.0, progress-stream@^1.2.0: +progress-stream@^1.1.0, progress-stream@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77" dependencies: @@ -3422,12 +3175,6 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" -promise@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" - dependencies: - asap "~2.0.3" - pseudomap@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -3453,7 +3200,7 @@ q@~1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" -qs@^6.1.0, qs@~6.2.0: +qs@~6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" @@ -3484,29 +3231,6 @@ read-all-stream@^3.0.0: pinkie-promise "^2.0.0" readable-stream "^2.0.0" -read-installed@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" - dependencies: - debuglog "^1.0.1" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - semver "2 || 3 || 4 || 5" - slide "~1.1.3" - util-extend "^1.0.1" - optionalDependencies: - graceful-fs "^4.1.2" - -read-package-json@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.4.tgz#61ed1b2256ea438d8008895090be84b8e799c853" - dependencies: - glob "^6.0.0" - json-parse-helpfulerror "^1.0.2" - normalize-package-data "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.2" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -3522,7 +3246,7 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.0, readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.31: +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.0, readable-stream@~1.0.31: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: @@ -3531,6 +3255,15 @@ read-pkg@^1.0.0: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@^1.1.7, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5: version "2.1.5" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" @@ -3543,15 +3276,6 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readable-stream@~2.0.0, readable-stream@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" @@ -3563,15 +3287,6 @@ readable-stream@~2.0.0, readable-stream@~2.0.5: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readdir-scoped-modules@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -3593,9 +3308,9 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" -regenerator-runtime@^0.9.5: - version "0.9.6" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" +regenerator-runtime@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb" regex-cache@^0.4.2: version "0.4.3" @@ -3660,7 +3375,7 @@ request@2.74.0: tough-cookie "~2.3.0" tunnel-agent "~0.4.1" -request@^2.45.0, request@^2.65.0: +request@^2.45.0, request@^2.55.0, request@^2.65.0: version "2.75.0" resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" dependencies: @@ -3783,6 +3498,10 @@ rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + sanitize-filename@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" @@ -3817,7 +3536,7 @@ semver-diff@^2.0.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" -semver@^4.1.0, semver@~4.3.3: +semver@^4.1.0: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" @@ -3829,10 +3548,6 @@ set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" -set-immediate-shim@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - "setimmediate@>= 1.0.2 < 2", setimmediate@~1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -3853,9 +3568,9 @@ shelljs@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" -shelljs@^0.7.0, shelljs@^0.7.5: - version "0.7.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675" +shelljs@^0.7.5, shelljs@^0.7.6: + version "0.7.6" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -3885,7 +3600,7 @@ slice-ansi@0.0.4: dependencies: readable-stream "~1.0.31" -slide@^1.1.5, slide@~1.1.3: +slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -3895,13 +3610,14 @@ sntp@1.x.x: dependencies: hoek "2.x.x" -solc@0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.6.tgz#afa929a1ceafc0252cfbb4217c8e2b1dab139db7" +solc@^0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.8.tgz#96abbee1266341ae97fb4bdc3abcc9bc1b5052ab" dependencies: fs-extra "^0.30.0" memorystream "^0.3.1" require-from-string "^1.1.0" + semver "^5.3.0" yargs "^4.7.1" source-map-resolve@^0.3.0: @@ -3913,9 +3629,9 @@ source-map-resolve@^0.3.0: source-map-url "~0.3.0" urix "~0.1.0" -source-map-support@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.6.tgz#32552aa64b458392a85eab3b0b5ee61527167aeb" +source-map-support@^0.4.11: + version "0.4.11" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" dependencies: source-map "^0.5.3" @@ -3970,12 +3686,12 @@ 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" -spectron@^3.2.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/spectron/-/spectron-3.4.0.tgz#ff9e54dc34428ec4f99ab1c5efa050b9ad200b31" +spectron@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/spectron/-/spectron-3.3.0.tgz#b4f0b9fa00771715aa04aa31b336f1bd763d660f" dependencies: dev-null "^0.1.1" - electron-chromedriver "~1.4.0" + electron-chromedriver "~1.3.0" request "^2.65.0" split "^1.0.0" webdriverio "^4.0.4" @@ -4009,7 +3725,7 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -stat-mode@^0.2.0: +stat-mode@^0.2.0, stat-mode@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" @@ -4028,6 +3744,14 @@ stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" +streamroller@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.2.2.tgz#a13420e04169e573db068f5920ee23d881abfe33" + dependencies: + date-format "^0.0.0" + debug "^0.7.2" + readable-stream "^1.1.7" + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -4055,12 +3779,6 @@ stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -strip-ansi@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" - dependencies: - ansi-regex "^0.2.1" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -4108,10 +3826,14 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@~1.0.1, strip-json-comments@~1.0.4: +strip-json-comments@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + sum-up@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" @@ -4125,31 +3847,15 @@ sumchecker@^1.2.0: debug "^2.2.0" es6-promise "^3.2.1" -supports-color@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" - -supports-color@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - -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.2, supports-color@^3.1.0, supports-color@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" dependencies: has-flag "^1.0.0" -sync-request@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-3.0.1.tgz#caa1235aaf889ba501076a1834c436830a82fb73" - dependencies: - concat-stream "^1.4.7" - http-response-object "^1.0.1" - then-request "^2.0.1" +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" table@^3.7.8: version "3.8.3" @@ -4175,17 +3881,6 @@ text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -then-request@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/then-request/-/then-request-2.2.0.tgz#6678b32fa0ca218fe569981bbd8871b594060d81" - dependencies: - caseless "~0.11.0" - concat-stream "^1.4.7" - http-basic "^2.5.1" - http-response-object "^1.1.0" - promise "^7.1.1" - qs "^6.1.0" - throttleit@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" @@ -4197,13 +3892,6 @@ through2-filter@^2.0.0: through2 "~2.0.0" xtend "~4.0.0" -through2@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" - dependencies: - readable-stream "~1.0.17" - xtend "~3.0.0" - through2@^0.6.0, through2@^0.6.1: version "0.6.5" resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" @@ -4243,6 +3931,10 @@ timed-out@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.0.0.tgz#ff88de96030ce960eabd42487db61d3add229273" +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" @@ -4261,10 +3953,6 @@ to-absolute-glob@^0.1.1: dependencies: extend-shallow "^2.0.1" -to-iso-string@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" - tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" @@ -4297,7 +3985,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.3.tgz#3da382f670f25ded78d7b3d1792119bca0b7132d" -type-check@~0.3.1, type-check@~0.3.2: +type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" dependencies: @@ -4315,13 +4003,13 @@ typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^1.7.3: - version "1.8.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-1.8.10.tgz#b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e" +typescript@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.1.5.tgz#6fe9479e00e01855247cea216e7561bafcdbcd4a" uglify-js@^2.6: - version "2.7.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.4.tgz#a295a0de12b6a650c031c40deb0dc40b14568bd2" + version "2.7.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" dependencies: async "~0.2.6" source-map "~0.5.1" @@ -4363,9 +4051,9 @@ unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" -update-notifier@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.2.tgz#27c90519196dc15015be02a34ea52986feab8877" +update-notifier@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" dependencies: boxen "^0.6.0" chalk "^1.0.0" @@ -4380,6 +4068,10 @@ 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-join@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" + url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" @@ -4425,10 +4117,14 @@ uuid-1345@^0.99.6: dependencies: macaddress "^0.2.7" -uuid@^2.0.1, uuid@^2.0.2: +uuid@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" +uuid@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + v8flags@^2.0.2: version "2.0.11" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" @@ -4498,12 +4194,6 @@ vinyl-fs@^2.2.0: vali-date "^1.0.0" vinyl "^1.0.0" -vinyl@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.2.3.tgz#bca938209582ec5a49ad538a00fa1f125e513252" - dependencies: - clone-stats "~0.0.1" - vinyl@^0.4.0, vinyl@^0.4.3: version "0.4.6" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" @@ -4659,10 +4349,6 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xtend@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" - y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" @@ -4678,13 +4364,13 @@ yargs-parser@^2.4.1: camelcase "^3.0.0" lodash.assign "^4.0.6" -yargs-parser@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.1.0.tgz#313df030f20124124aeae8fbab2da53ec28c56d7" +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" dependencies: camelcase "^3.0.0" -yargs@^4.3.1, yargs@^4.3.2, yargs@^4.7.1: +yargs@^4.3.2, yargs@^4.7.1: version "4.8.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" dependencies: @@ -4703,9 +4389,9 @@ yargs@^4.3.1, yargs@^4.3.2, yargs@^4.7.1: y18n "^3.2.1" yargs-parser "^2.4.1" -yargs@^6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4" +yargs@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" dependencies: camelcase "^3.0.0" cliui "^3.2.0" @@ -4718,9 +4404,8 @@ yargs@^6.4.0: set-blocking "^2.0.0" string-width "^1.0.2" which-module "^1.0.0" - window-size "^0.2.0" y18n "^3.2.1" - yargs-parser "^4.1.0" + yargs-parser "^4.2.0" yargs@~3.10.0: version "3.10.0" @@ -4737,7 +4422,7 @@ yauzl@2.4.1, yauzl@^2.2.1: dependencies: fd-slicer "~1.0.1" -zip-stream@^1.0.0, zip-stream@^1.1.0: +zip-stream@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.1.0.tgz#2ad479fffc168e05a888e8c348ff6813b3f13733" dependencies: