diff --git a/TODO.json b/TODO.json new file mode 100644 index 00000000..3449044c --- /dev/null +++ b/TODO.json @@ -0,0 +1,46 @@ +{ + "groups": [ + { + "code": "balanceAlerts", + "fields": [ + "cashInAlertThreshold" + ] + }, + { + "code": "compliance", + "fields": [ + "smsVerificationActive", + "smsVerificationThreshold", + "idCardDataVerificationActive", + "idCardDataVerificationThreshold", + "idCardPhotoVerificationActive", + "idCardPhotoVerificationThreshold", + "sanctionsVerificationActive", + "sanctionsVerificationThreshold", + "frontCameraVerificationActive", + "frontCameraVerificationThreshold", + "hardLimitVerificationActive", + "hardLimitVerificationThreshold", + "receiptPrintingActive", + "rejectAddressReuseActive" + ] + }, + { + "code": "walletSettings", + "fields": [ + "ticker", + "wallet", + "layer2", + "exchange", + "zeroConf" + ] + }, + { + "code": "notifications", + "fields": [ + "sms", + "email" + ] + } + ] +} \ No newline at end of file diff --git a/bin/lamassu-display-config.js b/bin/lamassu-display-config.js index ed29d4b7..2b4cb00b 100644 --- a/bin/lamassu-display-config.js +++ b/bin/lamassu-display-config.js @@ -1,4 +1,4 @@ -const settingsLoader = require('../lib/settings-loader') +const settingsLoader = require('../lib/new-settings-loader') const pp = require('../lib/pp') settingsLoader.loadLatest() @@ -9,4 +9,4 @@ settingsLoader.loadLatest() .catch(e => { console.log(e.stack) process.exit(1) - }) + }) \ No newline at end of file diff --git a/bin/lamassu-send-coins b/bin/lamassu-send-coins index 51ac67b3..9d829002 100755 --- a/bin/lamassu-send-coins +++ b/bin/lamassu-send-coins @@ -1,7 +1,7 @@ #!/usr/bin/env node -const settingsLoader = require('../lib/settings-loader') -const configManager = require('../lib/config-manager') +const settingsLoader = require('../lib/new-settings-loader') +const configManager = require('../lib/new-config-manager') const wallet = require('../lib/wallet') const coinUtils = require('../lib/coin-utils') const BN = require('../lib/bn') @@ -40,8 +40,7 @@ console.log('Loading ticker...') settingsLoader.loadLatest() .then(settings => { - const config = configManager.unscoped(settings.config) - const fiatCode = config.fiatCurrency + const fiatCode = configManager.getGlobalLocale(settings.config).fiatCurrency return wallet.isStrictAddress(settings, cryptoCode, toAddress) .then(isValid => { diff --git a/dev/coinatmradar.js b/dev/coinatmradar.js index 62161f25..4f4cf1be 100644 --- a/dev/coinatmradar.js +++ b/dev/coinatmradar.js @@ -1,14 +1,13 @@ const car = require('../lib/coinatmradar/coinatmradar') const plugins = require('../lib/plugins') -require('../lib/settings-loader').loadLatest() +require('../lib/new-settings-loader').loadLatest() .then(settings => { const pi = plugins(settings) - const config = settings.config return pi.getRawRates() .then(rates => { - return car.update({rates, config}, settings) + return car.update(rates, settings) .then(require('../lib/pp')('DEBUG100')) .catch(console.log) .then(() => process.exit()) diff --git a/dev/config.js b/dev/config.js index 51dc2c3e..97a2d33a 100644 --- a/dev/config.js +++ b/dev/config.js @@ -1,8 +1,8 @@ -const settingsLoader = require('../lib/settings-loader') -const configManager = require('../lib/config-manager') +const settingsLoader = require('../lib/new-settings-loader') +const configManager = require('../lib/new-config-manager') settingsLoader.loadLatest() .then(settings => { const config = settings.config - require('../lib/pp')('config')(configManager.all('cryptoCurrencies', config)) + require('../lib/pp')('config')(configManager.getAllCryptoCurrencies(config)) }) diff --git a/dev/plugins.js b/dev/plugins.js index aea224a3..30488199 100644 --- a/dev/plugins.js +++ b/dev/plugins.js @@ -1,5 +1,5 @@ const plugins = require('../lib/plugins') -const settingsLoader = require('../lib/settings-loader') +const settingsLoader = require('../lib/new-settings-loader') const pp = require('../lib/pp') settingsLoader.loadLatest() diff --git a/dev/send-message.js b/dev/send-message.js index f72f6faf..dcf8acd2 100644 --- a/dev/send-message.js +++ b/dev/send-message.js @@ -1,6 +1,6 @@ require('es6-promise').polyfill() -var config = require('../lib/settings-loader') +var config = require('../lib/new-settings-loader') var sms = require('../lib/sms') var rand = Math.floor(Math.random() * 1e6) diff --git a/lamassu-admin-elm/src/NavBar.elm b/lamassu-admin-elm/src/NavBar.elm index a0233995..ad94776a 100644 --- a/lamassu-admin-elm/src/NavBar.elm +++ b/lamassu-admin-elm/src/NavBar.elm @@ -156,7 +156,7 @@ determineConfigCategory : String -> Maybe Category determineConfigCategory configCode = if List.member configCode [ "definition", "setup", "cashOut", "commissions", "balanceAlerts" ] then Just MachineSettingsCat - else if List.member configCode [ "walletSettings", "notifications", "compliance", "coinAtmRadar", "terms", "operatorInfo" ] then + else if List.member configCode [ "walletSettings", "notifications", "compliance", "coinAtmRadar", "terms", "operatorInfo", "fudgeFactor" ] then Just GlobalSettingsCat else Nothing @@ -253,6 +253,7 @@ view route invalidGroups = , configLink "coinAtmRadar" "Coin ATM Radar" , configLink "terms" "Terms and Conditions" , configLink "operatorInfo" "Operator Info" + , configLink "fudgeFactor" "Fudge Factor" ] , ll ( "Third Party Services", AccountCat, AccountRoute "bitgo", True ) [ ( "BitGo", AccountRoute "bitgo", True ) diff --git a/lamassu-schema.json b/lamassu-schema.json index 3169522c..2e41936a 100644 --- a/lamassu-schema.json +++ b/lamassu-schema.json @@ -147,6 +147,15 @@ "operatorInfoWebsite", "operatorInfoCompanyNumber" ] + }, + { + "code": "fudgeFactor", + "display": "Fudge Factor", + "cryptoScope": "global", + "machineScope": "global", + "fields": [ + "fudgeFactorActive" + ] } ], "fields": [ @@ -846,7 +855,8 @@ "notificationsSMSEnabled", "cashOutEnabled" ], - "fieldValidation": [{"code": "required"}] + "fieldValidation": [{"code": "required"}], + "default": "twilio" }, { "code": "email", @@ -857,7 +867,8 @@ "enabledIfAny": [ "notificationsEmailEnabled" ], - "fieldValidation": [{"code": "required"}] + "fieldValidation": [{"code": "required"}], + "default": "mailgun" }, { "code": "coinAtmRadarActive", @@ -939,6 +950,14 @@ ], "fieldValidation": [] }, + { + "code": "fudgeFactorActive", + "displayBottom": "Enabled", + "fieldType": "onOff", + "fieldClass": null, + "fieldValidation": [], + "default": false + }, { "code": "operatorInfoActive", "displayBottom": "Info card enabled", diff --git a/lib/admin/funding.js b/lib/admin/funding.js index b927b0bd..c912d913 100644 --- a/lib/admin/funding.js +++ b/lib/admin/funding.js @@ -78,7 +78,7 @@ function getFunding (_cryptoCode) { const rate = (rates.ask.add(rates.bid)).div(2) const fundingConfirmedBalance = fundingRec.fundingConfirmedBalance const fiatConfirmedBalance = computeFiat(rate, cryptoCode, fundingConfirmedBalance) - const pending = fundingRec.fundingPendingBalance.sub(fundingConfirmedBalance) + const pending = fundingRec.fundingPendingBalance const fiatPending = computeFiat(rate, cryptoCode, pending) const fundingAddress = fundingRec.fundingAddress const fundingAddressUrl = coinUtils.buildUrl(cryptoCode, fundingAddress) diff --git a/lib/app.js b/lib/app.js index a5661ebf..293f5b74 100644 --- a/lib/app.js +++ b/lib/app.js @@ -6,8 +6,9 @@ const argv = require('minimist')(process.argv.slice(2)) const routes = require('./routes') const logger = require('./logger') const poller = require('./poller') -const settingsLoader = require('./settings-loader') -const configManager = require('./config-manager') +const settingsLoader = require('./new-settings-loader') +const configManager = require('./new-config-manager') +const complianceTriggers = require('./compliance-triggers') const options = require('./options') const ofac = require('./ofac/index') const ofacUpdate = require('./ofac/update') @@ -43,9 +44,10 @@ function run () { function loadSanctions (settings) { return Promise.resolve() .then(() => { - const config = configManager.unscoped(settings.config) + const triggers = configManager.getTriggers(settings.config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) - if (!config.sanctionsVerificationActive) return + if (!compatTriggers.sanctions) return logger.info('Loading sanctions DB...') return ofacUpdate.update() diff --git a/lib/blockchain/common.js b/lib/blockchain/common.js index 6162ec90..951152b3 100644 --- a/lib/blockchain/common.js +++ b/lib/blockchain/common.js @@ -21,28 +21,28 @@ module.exports = { const BINARIES = { BTC: { - url: 'https://bitcoin.org/bin/bitcoin-core-0.18.1/bitcoin-0.18.1-x86_64-linux-gnu.tar.gz', - dir: 'bitcoin-0.18.1/bin' + url: 'https://bitcoincore.org/bin/bitcoin-core-0.19.1/bitcoin-0.19.1-x86_64-linux-gnu.tar.gz', + dir: 'bitcoin-0.19.1/bin' }, ETH: { - url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.7-a718daa6.tar.gz', - dir: 'geth-linux-amd64-1.9.7-a718daa6' + url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.14-6d74d1e5.tar.gz', + dir: 'geth-linux-amd64-1.9.14-6d74d1e5' }, ZEC: { - url: 'https://z.cash/downloads/zcash-2.1.0-1-linux64-debian-jessie.tar.gz', - dir: 'zcash-2.1.0-1/bin' + url: 'https://z.cash/downloads/zcash-2.1.2-3-linux64-debian-jessie.tar.gz', + dir: 'zcash-2.1.2-3/bin' }, DASH: { - url: 'https://github.com/dashpay/dash/releases/download/v0.14.0.3/dashcore-0.14.0.3-x86_64-linux-gnu.tar.gz', - dir: 'dashcore-0.14.0/bin' + url: 'https://github.com/dashpay/dash/releases/download/v0.15.0.0/dashcore-0.15.0.0-x86_64-linux-gnu.tar.gz', + dir: 'dashcore-0.15.0/bin' }, LTC: { url: 'https://download.litecoin.org/litecoin-0.17.1/linux/litecoin-0.17.1-x86_64-linux-gnu.tar.gz', dir: 'litecoin-0.17.1/bin' }, BCH: { - url: 'https://download.bitcoinabc.org/0.20.5/linux/bitcoin-abc-0.20.5-x86_64-linux-gnu.tar.gz', - dir: 'bitcoin-abc-0.20.5/bin', + url: 'https://download.bitcoinabc.org/0.21.7/linux/bitcoin-abc-0.21.7-x86_64-linux-gnu.tar.gz', + dir: 'bitcoin-abc-0.21.7/bin', files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']] } } diff --git a/lib/blockchain/dash.js b/lib/blockchain/dash.js index 868734b3..8afb2f55 100644 --- a/lib/blockchain/dash.js +++ b/lib/blockchain/dash.js @@ -23,5 +23,7 @@ dbcache=500 keypool=10000 litemode=1 prune=4000 -txindex=0` +txindex=0 +enableprivatesend=1 +privatesendautostart=1` } diff --git a/lib/cash-in/cash-in-tx.js b/lib/cash-in/cash-in-tx.js index 0ef93717..2c8da04f 100644 --- a/lib/cash-in/cash-in-tx.js +++ b/lib/cash-in/cash-in-tx.js @@ -6,8 +6,8 @@ const blacklist = require('../blacklist') const db = require('../db') const plugins = require('../plugins') const logger = require('../logger') -const settingsLoader = require('../settings-loader') -const configManager = require('../config-manager') +const settingsLoader = require('../new-settings-loader') +// const configManager = require('../new-config-manager') const cashInAtomic = require('./cash-in-atomic') const cashInLow = require('./cash-in-low') @@ -26,7 +26,9 @@ function post (machineTx, pi) { return Promise.all([settingsLoader.loadLatest(), checkForBlacklisted(updatedTx)]) .then(([{ config }, blacklistItems]) => { - const rejectAddressReuseActive = configManager.unscoped(config).rejectAddressReuseActive + // TODO new-admin: addressReuse doesnt exist + // const rejectAddressReuseActive = configManager.unscoped(config).rejectAddressReuseActive + const rejectAddressReuseActive = true if (_.some(it => it.created_by_operator === true)(blacklistItems)) { blacklisted = true @@ -123,8 +125,9 @@ function postProcess (r, pi, isBlacklisted, addressReuse) { }) .then(sendRec => { settingsLoader.loadLatest().then(it => { - const config = configManager.unscoped(it.config) - if (config.rejectAddressReuseActive) { + // TODO new-admin: addressReuse doesnt exist + // const config = configManager.unscoped(it.config) + if (true) { blacklist.addToUsedAddresses(r.tx.toAddress, r.tx.cryptoCode) .catch(err => logger.error('Failure adding to addressReuse', err)) } diff --git a/lib/cash-out/cash-out-atomic.js b/lib/cash-out/cash-out-atomic.js index 69854c19..f3365123 100644 --- a/lib/cash-out/cash-out-atomic.js +++ b/lib/cash-out/cash-out-atomic.js @@ -65,11 +65,7 @@ function preProcess (t, oldTx, newTx, pi) { .then(updatedTx => { if (updatedTx.status !== oldTx.status) { const isZeroConf = pi.isZeroConf(updatedTx) - if (wasJustAuthorized(oldTx, updatedTx, isZeroConf)) { - pi.sell(updatedTx) - pi.notifyOperator(updatedTx, { isRedemption: false }) - .catch((err) => logger.error('Failure sending transaction notification', err)) - } + updatedTx.justAuthorized = wasJustAuthorized(oldTx, updatedTx, isZeroConf) const rec = { to_address: updatedTx.toAddress, diff --git a/lib/cash-out/cash-out-helper.js b/lib/cash-out/cash-out-helper.js index 7ce41156..dc4597fd 100644 --- a/lib/cash-out/cash-out-helper.js +++ b/lib/cash-out/cash-out-helper.js @@ -11,14 +11,18 @@ module.exports = { redeemableTxs, toObj, toDb, REDEEMABLE_AGE } const mapValuesWithKey = _.mapValues.convert({cap: false}) function convertBigNumFields (obj) { - const convert = (value, key) => _.includes(key, [ - 'cryptoAtoms', - 'fiat', - 'commissionPercentage', - 'rawTickerPrice' - ]) - ? value.toString() - : value + const convert = (value, key) => { + if (_.includes(key, [ 'cryptoAtoms', 'receivedCryptoAtoms', 'fiat' ])) { + return value.toString() + } + + // Only test isNil for these fields since the others should not be empty. + if (_.includes(key, [ 'commissionPercentage', 'rawTickerPrice' ]) && !_.isNil(value)) { + return value.toString() + } + + return value + } const convertKey = key => _.includes(key, ['cryptoAtoms', 'fiat']) ? key + '#' @@ -58,6 +62,10 @@ function toObj (row) { keys.forEach(key => { const objKey = _.camelCase(key) + if (key === 'received_crypto_atoms' && row[key]) { + newObj[objKey] = BN(row[key]) + return + } if (_.includes(key, ['crypto_atoms', 'fiat', 'commission_percentage', 'raw_ticker_price'])) { newObj[objKey] = BN(row[key]) return diff --git a/lib/cash-out/cash-out-low.js b/lib/cash-out/cash-out-low.js index b47f3c76..b5fdd22c 100644 --- a/lib/cash-out/cash-out-low.js +++ b/lib/cash-out/cash-out-low.js @@ -7,7 +7,8 @@ const toDb = helper.toDb const toObj = helper.toObj const UPDATEABLE_FIELDS = ['txHash', 'txVersion', 'status', 'dispense', 'dispenseConfirmed', - 'notified', 'redeem', 'phone', 'error', 'swept', 'publishedAt', 'confirmedAt', 'errorCode'] + 'notified', 'redeem', 'phone', 'error', 'swept', 'publishedAt', 'confirmedAt', 'errorCode', + 'receivedCryptoAtoms' ] module.exports = {upsert, update, insert} @@ -18,7 +19,7 @@ function upsert (t, oldTx, tx) { } return update(t, tx, diff(oldTx, tx)) - .then(newTx => [oldTx, newTx]) + .then(newTx => [oldTx, newTx, tx.justAuthorized]) } function insert (t, tx) { diff --git a/lib/cash-out/cash-out-tx.js b/lib/cash-out/cash-out-tx.js index 41ee2261..2a2ebac0 100644 --- a/lib/cash-out/cash-out-tx.js +++ b/lib/cash-out/cash-out-tx.js @@ -45,15 +45,21 @@ function selfPost (tx, pi) { function post (tx, pi, fromClient = true) { return db.tx(cashOutAtomic.atomic(tx, pi, fromClient)) .then(txVector => { - const [, newTx] = txVector - return postProcess(txVector, pi) + const [, newTx, justAuthorized] = txVector + return postProcess(txVector, justAuthorized, pi) .then(changes => cashOutLow.update(db, newTx, changes)) }) } -function postProcess (txVector, pi) { +function postProcess (txVector, justAuthorized, pi) { const [oldTx, newTx] = txVector + if (justAuthorized) { + pi.sell(newTx) + pi.notifyOperator(newTx, { isRedemption: false }) + .catch((err) => logger.error('Failure sending transaction notification', err)) + } + if ((newTx.dispense && !oldTx.dispense) || (newTx.redeem && !oldTx.redeem)) { return pi.buildAvailableCassettes(newTx.id) .then(cassettes => { @@ -106,7 +112,7 @@ function processTxStatus (tx, settings) { const pi = plugins(settings, tx.deviceId) return pi.getStatus(tx) - .then(res => _.assign(tx, {status: res.status})) + .then(res => _.assign(tx, { receivedCryptoAtoms: res.receivedCryptoAtoms, status: res.status })) .then(_tx => selfPost(_tx, pi)) } diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js index 78acf983..87f8cafa 100644 --- a/lib/coinatmradar/coinatmradar.js +++ b/lib/coinatmradar/coinatmradar.js @@ -7,7 +7,8 @@ const fs = pify(require('fs')) const db = require('../db') const mnemonicHelpers = require('../mnemonic-helpers') -const configManager = require('../config-manager') +const configManager = require('../new-config-manager') +const complianceTriggers = require('../compliance-triggers') const options = require('../options') const logger = require('../logger') const plugins = require('../plugins') @@ -18,56 +19,77 @@ const MAX_CONTENT_LENGTH = 2000 // How long a machine can be down before it's considered offline const STALE_INTERVAL = '2 minutes' -module.exports = { update, mapRecord } +module.exports = { update } -function mapCoin (info, deviceId, settings, cryptoCode) { - const config = info.config - const rates = plugins(settings, deviceId).buildRates(info.rates)[cryptoCode] || { cashIn: null, cashOut: null } - const cryptoConfig = configManager.scoped(cryptoCode, deviceId, config) - const unscoped = configManager.unscoped(config) - const showRates = unscoped.coinAtmRadarShowRates +function mapCoin (rates, deviceId, settings, cryptoCode) { + const config = settings.config + const buildedRates = plugins(settings, deviceId).buildRates(rates)[cryptoCode] || { cashIn: null, cashOut: null } - const cashInFee = showRates ? cryptoConfig.cashInCommission / 100 : null - const cashOutFee = showRates ? cryptoConfig.cashOutCommission / 100 : null - const cashInRate = showRates ? _.invoke('cashIn.toNumber', rates) : null - const cashOutRate = showRates ? _.invoke('cashOut.toNumber', rates) : null + const commissions = configManager.getCommissions(cryptoCode, deviceId, config) + const coinAtmRadar = configManager.getCoinAtmRadar(config) + + const showCommissions = coinAtmRadar.commissions + + const cashInFee = showCommissions ? commissions.cashIn / 100 : null + const cashOutFee = showCommissions ? commissions.cashOut / 100 : null + const cashInRate = showCommissions ? _.invoke('cashIn.toNumber', buildedRates) : null + const cashOutRate = showCommissions ? _.invoke('cashOut.toNumber', buildedRates) : null return { cryptoCode, cashInFee, cashOutFee, + cashInFixedFee, cashInRate, cashOutRate } } -function mapIdentification (info, deviceId) { - const machineConfig = configManager.machineScoped(deviceId, info.config) +function mapIdentification (config, deviceId) { + const triggers = configManager.getTriggers(deviceId, config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) return { - isPhone: machineConfig.smsVerificationActive, + isPhone: !!compatTriggers.sms, isPalmVein: false, - isPhoto: false, - isIdDocScan: machineConfig.idCardDataVerificationActive, + isPhoto: !!compatTriggers.facephoto, + isIdDocScan: !!compatTriggers.idData, isFingerprint: false } } -function mapMachine (info, settings, machineRow) { +function mapMachine (rates, settings, machineRow) { const deviceId = machineRow.device_id - const config = info.config - const machineConfig = configManager.machineScoped(deviceId, config) + const config = settings.config + + const coinAtmRadar = configManager.getCoinAtmRadar(config) + const triggers = configManager.getTriggers(deviceId, config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) + const locale = configManager.getLocale(deviceId, config) + const cashOutConfig = configManager.getCashOut(deviceId, config) const lastOnline = machineRow.last_online.toISOString() const status = machineRow.stale ? 'online' : 'offline' + const showSupportedCryptocurrencies = coinAtmRadar.supportedCryptocurrencies + const showSupportedFiat = coinAtmRadar.supportedFiat + const showSupportedBuySellDirection = coinAtmRadar.supportedBuySellDirection + const showLimitsAndVerification = coinAtmRadar.limitsAndVerification - const cashLimit = machineConfig.hardLimitVerificationActive - ? machineConfig.hardLimitVerificationThreshold - : Infinity + // TODO new-admin: this is relaying info with backwards compatible triggers + // need to get in touch with coinatmradar before updating this + const cashLimit = showLimitsAndVerification ? ( + !!compatTriggers.block + ? compatTriggers.block + : Infinity ) : null - const cryptoCurrencies = machineConfig.cryptoCurrencies - const identification = mapIdentification(info, deviceId) - const coins = _.map(_.partial(mapCoin, [info, deviceId, settings]), cryptoCurrencies) + const cryptoCurrencies = locale.cryptoCurrencies + const cashInEnabled = showSupportedBuySellDirection ? true : null + const cashOutEnabled = showSupportedBuySellDirection ? cashOutConfig.active : null + const fiat = showSupportedFiat ? locale.fiatCurrency : null + const identification = mapIdentification(config, deviceId) + const coins = showSupportedCryptocurrencies ? + _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies) + : null return { machineId: deviceId, @@ -85,27 +107,27 @@ function mapMachine (info, settings, machineRow) { }, status, lastOnline, - cashIn: true, - cashOut: machineConfig.cashOutEnabled, + cashIn: cashInEnabled, + cashOut: cashOutEnabled, manufacturer: 'lamassu', cashInTxLimit: cashLimit, cashOutTxLimit: cashLimit, cashInDailyLimit: cashLimit, cashOutDailyLimit: cashLimit, - fiatCurrency: machineConfig.fiatCurrency, + fiatCurrency: fiat, identification, coins } } -function getMachines (info, settings) { +function getMachines (rates, settings) { const sql = `select device_id, last_online, now() - last_online < $1 as stale from devices where display=TRUE and paired=TRUE order by created` return db.any(sql, [STALE_INTERVAL]) - .then(_.map(_.partial(mapMachine, [info, settings]))) + .then(_.map(_.partial(mapMachine, [rates, settings]))) } function sendRadar (data) { @@ -129,9 +151,9 @@ function sendRadar (data) { .then(r => console.log(r.status)) } -function mapRecord (info, settings) { +function mapRecord (rates, settings) { const timestamp = new Date().toISOString() - return Promise.all([getMachines(info, settings), fs.readFile(options.mnemonicPath, 'utf8')]) + return Promise.all([getMachines(rates, settings), fs.readFile(options.mnemonicPath, 'utf8')]) .then(([machines, mnemonic]) => { return { operatorId: computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)), @@ -146,12 +168,12 @@ function mapRecord (info, settings) { }) } -function update (info, settings) { - const config = configManager.unscoped(info.config) +function update (rates, settings) { + const coinAtmRadar = configManager.getCoinAtmRadar(settings.config) - if (!config.coinAtmRadarActive) return Promise.resolve() + if (!coinAtmRadar.active) return Promise.resolve() - return mapRecord(info, settings) + return mapRecord(rates, settings) .then(sendRadar) .catch(err => logger.error(`Failure to update CoinATMRadar`, err)) } diff --git a/lib/coinatmradar/new-coinatmradar.js b/lib/coinatmradar/new-coinatmradar.js deleted file mode 100644 index 5c590d11..00000000 --- a/lib/coinatmradar/new-coinatmradar.js +++ /dev/null @@ -1,178 +0,0 @@ -const axios = require('axios') -const _ = require('lodash/fp') -const hkdf = require('futoin-hkdf') - -const pify = require('pify') -const fs = pify(require('fs')) - -const db = require('../db') -const mnemonicHelpers = require('../mnemonic-helpers') -const configManager = require('../config-manager') -const options = require('../options') -const logger = require('../logger') -const plugins = require('../plugins') - -const TIMEOUT = 10000 -const MAX_CONTENT_LENGTH = 2000 - -// How long a machine can be down before it's considered offline -const STALE_INTERVAL = '2 minutes' - -module.exports = { update, mapRecord } - -function mapCoin (info, deviceId, settings, cryptoCode) { - const config = info.config - const rates = plugins(settings, deviceId).buildRates(info.rates)[cryptoCode] || { cashIn: null, cashOut: null } - const cryptoConfig = configManager.scoped(cryptoCode, deviceId, config) - const unscoped = configManager.unscoped(config) - const showCommissions = unscoped.coinAtmRadar.sendCommissions - - const cashInFee = showCommissions ? cryptoConfig.cashInCommission / 100 : null - const cashOutFee = showCommissions ? cryptoConfig.cashOutCommission / 100 : null - const cashInRate = showCommissions ? _.invoke('cashIn.toNumber', rates) : null - const cashOutRate = showCommissions ? _.invoke('cashOut.toNumber', rates) : null - - return { - cryptoCode, - cashInFee, - cashOutFee, - cashInRate, - cashOutRate - } -} - -function mapIdentification (info, deviceId) { - const machineConfig = configManager.machineScoped(deviceId, info.config) - - return { - isPhone: machineConfig.smsVerificationActive, - isPalmVein: false, - isPhoto: false, - isIdDocScan: machineConfig.idCardDataVerificationActive, - isFingerprint: false - } -} - -function mapMachine (info, settings, machineRow) { - const deviceId = machineRow.device_id - const config = info.config - const unscoped = configManager.unscoped(config) - const machineConfig = configManager.machineScoped(deviceId, config) - - const lastOnline = machineRow.last_online.toISOString() - const status = machineRow.stale ? 'online' : 'offline' - const showSupportedCryptocurrencies = - unscoped.coinAtmRadar.sendSupportedCryptocurrencies - const showSupportedFiat = - unscoped.coinAtmRadar.sendSupportedFiat - const showSupportedBuySellDirection = - unscoped.coinAtmRadar.sendSupportedBuySellDirection - const showLimitsAndVerification = - unscoped.coinAtmRadar.sendLimitsAndVerification - - const cashLimit = showLimitsAndVerification ? ( - machineConfig.hardLimitVerificationActive - ? machineConfig.hardLimitVerificationThreshold - : Infinity ) : null - - const cryptoCurrencies = machineConfig.cryptoCurrencies - const cashInEnabled = showSupportedBuySellDirection ? true : null - const cashOutEnabled = showSupportedBuySellDirection - ? machineConfig.cashOutEnabled - : null - const fiat = showSupportedFiat ? machineConfig.fiatCurrency : null - const identification = mapIdentification(info, deviceId) - const coins = showSupportedCryptocurrencies ? - _.map(_.partial(mapCoin, [info, deviceId, settings]), cryptoCurrencies) - : null - - return { - machineId: deviceId, - address: { - streetAddress: null, - city: null, - region: null, - postalCode: null, - country: null - }, - location: { - name: null, - url: null, - phone: null - }, - status, - lastOnline, - cashIn: cashInEnabled, - cashOut: cashOutEnabled, - manufacturer: 'lamassu', - cashInTxLimit: cashLimit, - cashOutTxLimit: cashLimit, - cashInDailyLimit: cashLimit, - cashOutDailyLimit: cashLimit, - fiatCurrency: fiat, - identification, - coins - } -} - -function getMachines (info, settings) { - const sql = `select device_id, last_online, now() - last_online < $1 as stale from devices - where display=TRUE and - paired=TRUE - order by created` - - return db.any(sql, [STALE_INTERVAL]) - .then(_.map(_.partial(mapMachine, [info, settings]))) -} - -function sendRadar (data) { - const url = _.get(['coinAtmRadar', 'url'], options) - - if (_.isEmpty(url)) { - return Promise.reject(new Error('Missing coinAtmRadar url!')) - } - - const config = { - url, - method: 'post', - data, - timeout: TIMEOUT, - maxContentLength: MAX_CONTENT_LENGTH - } - - console.log('%j', data) - - return axios(config) - .then(r => console.log(r.status)) -} - -function mapRecord (info, settings) { - const timestamp = new Date().toISOString() - return Promise.all([getMachines(info, settings), fs.readFile(options.mnemonicPath, 'utf8')]) - .then(([machines, mnemonic]) => { - return { - operatorId: computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)), - operator: { - name: null, - phone: null, - email: null - }, - timestamp, - machines - } - }) -} - -function update (info, settings) { - const config = configManager.unscoped(info.config) - - if (!config.coinAtmRadar.active) return Promise.resolve() - - return mapRecord(info, settings) - .then(sendRadar) - .catch(err => logger.error(`Failure to update CoinATMRadar`, err)) -} - -function computeOperatorId (masterSeed) { - return hkdf(masterSeed, 16, { salt: 'lamassu-server-salt', info: 'operator-id' }).toString('hex') -} diff --git a/lib/compliance-triggers.js b/lib/compliance-triggers.js new file mode 100644 index 00000000..d08cfdb7 --- /dev/null +++ b/lib/compliance-triggers.js @@ -0,0 +1,9 @@ +const _ = require('lodash/fp') + +function getBackwardsCompatibleTriggers (triggers) { + const filtered = _.filter(_.matches({ triggerType: 'volume', cashDirection: 'both' }))(triggers) + const grouped = _.groupBy(_.prop('requirement'))(filtered) + return _.mapValues(_.compose(_.get('threshold'), _.minBy('threshold')))(grouped) +} + +module.exports = { getBackwardsCompatibleTriggers} \ No newline at end of file diff --git a/lib/email.js b/lib/email.js index 73c46b04..b69b2124 100644 --- a/lib/email.js +++ b/lib/email.js @@ -1,10 +1,13 @@ -const configManager = require('./config-manager') +// const configManager = require('./new-config-manager') +const logger = require('./logger') const ph = require('./plugin-helper') function sendMessage (settings, rec) { return Promise.resolve() .then(() => { - const pluginCode = configManager.unscoped(settings.config).email + // TODO new-admin + // const pluginCode = configManager.unscoped(settings.config).email + const pluginCode = 'mailgun' const plugin = ph.load(ph.EMAIL, pluginCode) const account = settings.accounts[pluginCode] diff --git a/lib/exchange.js b/lib/exchange.js index a15a4b5b..10070c2b 100644 --- a/lib/exchange.js +++ b/lib/exchange.js @@ -1,8 +1,8 @@ -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') const ph = require('./plugin-helper') function lookupExchange (settings, cryptoCode) { - const exchange = configManager.cryptoScoped(cryptoCode, settings.config).exchange + const exchange = configManager.getWalletSettings(cryptoCode, settings.config).exchange if (exchange === 'no-exchange') return null return exchange } diff --git a/lib/layer2.js b/lib/layer2.js index 3376eb53..b77403da 100644 --- a/lib/layer2.js +++ b/lib/layer2.js @@ -1,10 +1,9 @@ -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') const ph = require('./plugin-helper') const _ = require('lodash/fp') -const logger = require('./logger') function fetch (settings, cryptoCode) { - const plugin = configManager.cryptoScoped(cryptoCode, settings.config).layer2 + const plugin = configManager.getWalletSettings(cryptoCode, settings.config).layer2 if (_.isEmpty(plugin) || plugin === 'no-layer2') return Promise.resolve() @@ -34,7 +33,7 @@ function getStatus (settings, tx) { } function cryptoNetwork (settings, cryptoCode) { - const plugin = configManager.cryptoScoped(cryptoCode, settings.config).layer2 + const plugin = configManager.getWalletSettings(cryptoCode, settings.config).layer2 const layer2 = ph.load(ph.LAYER2, plugin) const account = settings.accounts[plugin] diff --git a/lib/machine-loader.js b/lib/machine-loader.js index 4bce608b..37e5f11f 100644 --- a/lib/machine-loader.js +++ b/lib/machine-loader.js @@ -3,8 +3,8 @@ const axios = require('axios') const db = require('./db') const pairing = require('./pairing') -const configManager = require('./config-manager') -const settingsLoader = require('./settings-loader') +const configManager = require('./new-config-manager') +const settingsLoader = require('./new-settings-loader') module.exports = {getMachineName, getMachines, getMachineNames, setMachine} @@ -17,6 +17,7 @@ function getMachines () { cassette2: r.cassette2, pairedAt: new Date(r.created).valueOf(), lastPing: new Date(r.last_online).valueOf(), + name: r.name, // TODO: we shall start using this JSON field at some point // location: r.location, paired: r.paired @@ -26,18 +27,20 @@ function getMachines () { function getConfig (defaultConfig) { if (defaultConfig) return Promise.resolve(defaultConfig) - return settingsLoader.loadRecentConfig() + return settingsLoader.loadLatest().config } function getMachineNames (config) { return Promise.all([getMachines(), getConfig(config)]) .then(([machines, config]) => { const addName = r => { - const machineScoped = configManager.machineScoped(r.deviceId, config) - const name = _.defaultTo('', machineScoped.machineName) - const cashOut = machineScoped.cashOutEnabled - const machineModel = _.defaultTo('', machineScoped.machineModel) - const machineLocation = _.defaultTo('', machineScoped.machineLocation) + const cashOutConfig = configManager.getCashOut(r.deviceId, config) + + const cashOut = cashOutConfig.active + + // TODO new-admin: these two fields were not ever working + const machineModel = '' + const machineLocation = '' // TODO: obtain next fields from somewhere const printer = null @@ -45,7 +48,7 @@ function getMachineNames (config) { const statuses = [{label: 'Unknown detailed status', type: 'warning'}] const softwareVersion = '' - return _.assign(r, {name, cashOut, machineModel, machineLocation, printer, pingTime, statuses, softwareVersion}) + return _.assign(r, {cashOut, machineModel, machineLocation, printer, pingTime, statuses, softwareVersion}) } return _.map(addName, machines) @@ -63,11 +66,9 @@ function getMachineNames (config) { * @returns {string} machine name */ function getMachineName (machineId) { - return settingsLoader.loadRecentConfig() - .then(config => { - const machineScoped = configManager.machineScoped(machineId, config) - return machineScoped.machineName - }) + const sql = 'select * from devices where device_id=$1' + return db.oneOrNone(sql, [machineId]) + .then(it => it.name) } function resetCashOutBills (rec) { diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index 9c4e3751..0f416fff 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -59,8 +59,8 @@ apolloServer.applyMiddleware({ // cors on app for /api/register endpoint. app.use(cors({ credentials: true, origin: devMode && 'https://localhost:3000' })) -app.use('/id-card-photo', serveStatic(idPhotoCardBasedir, {index: false})) -app.use('/front-camera-photo', serveStatic(frontCameraBasedir, {index: false})) +app.use('/id-card-photo', serveStatic(idPhotoCardBasedir, { index: false })) +app.use('/front-camera-photo', serveStatic(frontCameraBasedir, { index: false })) app.get('/api/register', (req, res, next) => { const otp = req.query.otp @@ -90,7 +90,7 @@ app.get('/api/register', (req, res, next) => { }) // Everything not on graphql or api/register is redirected to the front-end -app.get('*', (req, res) => res.sendFile(path.resolve('client', 'build', 'index.html'))) +app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'public', 'index.html'))) const certOptions = { key: fs.readFileSync(options.keyPath), diff --git a/lib/new-admin/config/accounts.js b/lib/new-admin/config/accounts.js index a972a4e3..4d0a9ac4 100644 --- a/lib/new-admin/config/accounts.js +++ b/lib/new-admin/config/accounts.js @@ -11,7 +11,7 @@ const ID_VERIFIER = 'idVerifier' const EMAIL = 'email' const ZERO_CONF = 'zeroConf' -const ACCOUNT_LIST = [ +const ALL_ACCOUNTS = [ { code: 'bitpay', display: 'Bitpay', class: TICKER, cryptos: [BTC, BCH] }, { code: 'kraken', display: 'Kraken', class: TICKER, cryptos: [BTC, ETH, LTC, DASH, ZEC, BCH] }, { code: 'bitstamp', display: 'Bitstamp', class: TICKER, cryptos: [BTC, ETH, LTC, BCH] }, @@ -43,4 +43,7 @@ const ACCOUNT_LIST = [ { code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: [BTC, ZEC, LTC, DASH, BCH, ETH], dev: true } ] +const devMode = require('minimist')(process.argv.slice(2)).dev +const ACCOUNT_LIST = devMode ? ALL_ACCOUNTS : _.filter(it => !it.dev)(ALL_ACCOUNTS) + module.exports = { ACCOUNT_LIST } diff --git a/lib/new-admin/funding.js b/lib/new-admin/funding.js index c896a4bb..cbb32b37 100644 --- a/lib/new-admin/funding.js +++ b/lib/new-admin/funding.js @@ -1,11 +1,10 @@ const _ = require('lodash/fp') const BN = require('../bn') -const settingsLoader = require('../settings-loader') -const configManager = require('../config-manager') +const settingsLoader = require('../new-settings-loader') +const configManager = require('../new-config-manager') const wallet = require('../wallet') const ticker = require('../ticker') const coinUtils = require('../coin-utils') -const machineLoader = require('../machine-loader') function allScopes (cryptoScopes, machineScopes) { const scopes = [] @@ -25,18 +24,6 @@ function allMachineScopes (machineList, machineScope) { return machineScopes } -function getCryptos (config, machineList) { - const scopes = allScopes(['global'], allMachineScopes(machineList, 'both')) - const scoped = scope => configManager.scopedValue(scope[0], scope[1], 'cryptoCurrencies', config) - - return _.uniq(_.flatten(_.map(scoped, scopes))) -} - -function fetchMachines () { - return machineLoader.getMachines() - .then(machineList => machineList.map(r => r.deviceId)) -} - function computeCrypto (cryptoCode, _balance) { const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode) const unitScale = cryptoRec.unitScale @@ -82,11 +69,9 @@ function getSingleCoinFunding (settings, fiatCode, cryptoCode) { } function getFunding () { - return Promise.all([settingsLoader.loadLatest(), fetchMachines()]) - .then(([settings, machineList]) => { - const config = configManager.unscoped(settings.config) - const cryptoCodes = getCryptos(settings.config, machineList) - const fiatCode = config.fiatCurrency + return settingsLoader.loadLatest().then(settings => { + const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config) + const fiatCode = configManager.getGlobalLocale(settings.config).fiatCurrency const pareCoins = c => _.includes(c.cryptoCode, cryptoCodes) const cryptoCurrencies = coinUtils.cryptoCurrencies() const cryptoDisplays = _.filter(pareCoins, cryptoCurrencies) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index a59fa041..07bedf12 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -62,7 +62,7 @@ const typeDefs = gql` type Customer { id: ID! - name: String! + name: String authorizedOverride: String frontCameraPath: String phone: String @@ -196,7 +196,7 @@ const typeDefs = gql` uptime: [ProcessStatus] serverLogs: [ServerLog] transactions: [Transaction] - accounts: [JSONObject] + accounts: JSONObject config: JSONObject } @@ -215,14 +215,13 @@ const typeDefs = gql` } type Mutation { - machineAction(deviceId:ID!, action: MachineAction!, cassettes: [Int]): Machine + machineAction(deviceId:ID!, action: MachineAction!, cassette1: Int, cassette2: Int): Machine machineSupportLogs(deviceId: ID!): SupportLogsResponse serverSupportLogs: SupportLogsResponse setCustomer(customerId: ID!, customerInput: CustomerInput): Customer saveConfig(config: JSONObject): JSONObject createPairingTotem(name: String!): String - saveAccount(account: JSONObject): [JSONObject] - saveAccounts(accounts: [JSONObject]): [JSONObject] + saveAccounts(accounts: JSONObject): JSONObject } ` @@ -255,11 +254,10 @@ const resolvers = { accounts: () => settingsLoader.getAccounts() }, Mutation: { - machineAction: (...[, { deviceId, action, cassettes }]) => machineAction({ deviceId, action, cassettes }), + machineAction: (...[, { deviceId, action, cassette1, cassette2 }]) => machineAction({ deviceId, action, cassette1, cassette2 }), machineSupportLogs: (...[, { deviceId }]) => supportLogs.insert(deviceId), createPairingTotem: (...[, { name }]) => pairing.totem(name), serverSupportLogs: () => serverLogs.insert(), - saveAccount: (...[, { account }]) => settingsLoader.saveAccounts([account]), saveAccounts: (...[, { accounts }]) => settingsLoader.saveAccounts(accounts), setCustomer: (...[, { customerId, customerInput } ]) => customers.updateCustomer(customerId, customerInput), saveConfig: (...[, { config }]) => settingsLoader.saveConfig(config) diff --git a/lib/new-admin/machines.js b/lib/new-admin/machines.js index cb0924ff..9fd779ef 100644 --- a/lib/new-admin/machines.js +++ b/lib/new-admin/machines.js @@ -6,13 +6,13 @@ function getMachine (machineId) { .then(machines => machines.find(({ deviceId }) => deviceId === machineId)) } -function machineAction ({ deviceId, action, cassettes }) { +function machineAction ({ deviceId, action, cassette1, cassette2 }) { return getMachine(deviceId) .then(machine => { if (!machine) throw new UserInputError(`machine:${deviceId} not found`, { deviceId }) return machine }) - .then(machineLoader.setMachine({ deviceId, action, cassettes })) + .then(machineLoader.setMachine({ deviceId, action, cassettes: [cassette1, cassette2] })) .then(getMachine(deviceId)) } diff --git a/lib/new-admin/transactions.js b/lib/new-admin/transactions.js index 57131786..249722aa 100644 --- a/lib/new-admin/transactions.js +++ b/lib/new-admin/transactions.js @@ -62,7 +62,10 @@ function batch () { } function getCustomerTransactions (customerId) { - const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), + const packager = _.flow(it => { + console.log() + return it + }, _.flatten, _.orderBy(_.property('created'), ['desc']), _.take(NUM_RESULTS), _.map(camelize), addNames) const cashInSql = `select 'cashIn' as tx_class, txs.*, diff --git a/lib/new-config-manager.js b/lib/new-config-manager.js new file mode 100644 index 00000000..caddcbb4 --- /dev/null +++ b/lib/new-config-manager.js @@ -0,0 +1,93 @@ +const _ = require('lodash/fp') +const logger = require('./logger') + +const namespaces = { + WALLETS: 'wallets', + OPERATOR_INFO: 'operatorInfo', + NOTIFICATIONS: 'notifications', + LOCALE: 'locale', + COMMISSIONS: 'commissions', + RECEIPT: 'receipt', + COIN_ATM_RADAR: 'coinAtmRadar', + TERMS_CONDITIONS: 'termsConditions', + CASH_OUT: 'cashOut' +} + +const stripl = _.curry((q, str) => _.startsWith(q, str) ? str.slice(q.length) : str) +const filter = namespace => _.pickBy((value, key) => _.startsWith(`${namespace}_`)(key)) +const strip = key => _.mapKeys(stripl(`${key}_`)) + +const fromNamespace = _.curry((key, config) => _.compose(strip(key), filter(key))(config)) +const toNamespace = (key, config) => _.mapKeys(it => `${key}_${it}`)(config) + +const resolveOverrides = (original, filter, overrides, overridesPath = 'overrides') => { + if (_.isEmpty(overrides)) return original + + return _.omit(overridesPath, _.mergeAll([original, ..._.filter(filter)(overrides)])) +} + +const getCommissions = (cryptoCode, deviceId, config) => { + const commissions = fromNamespace(namespaces.COMMISSIONS)(config) + + const filter = it => it.machine === deviceId && _.includes(cryptoCode)(it.cryptoCurrencies) + return resolveOverrides(commissions, filter, commissions.overrides) +} + +const getLocale = (deviceId, it) => { + const locale = fromNamespace(namespaces.LOCALE)(it) + + const filter = _.matches({ machine: deviceId }) + return resolveOverrides(locale, filter, locale.overrides) +} + +const getGlobalLocale = it => getLocale(null, it) + +const getWalletSettings = (key, it) => _.compose(fromNamespace(key), fromNamespace(namespaces.WALLETS))(it) +const getCashOut = (key, it) => _.compose(fromNamespace(key), fromNamespace(namespaces.CASH_OUT))(it) +const getOperatorInfo = fromNamespace(namespaces.OPERATOR_INFO) +const getCoinAtmRadar = fromNamespace(namespaces.COIN_ATM_RADAR) +const getTermsConditions = fromNamespace(namespaces.TERMS_CONDITIONS) +const getReceipt = fromNamespace(namespaces.RECEIPT) + +const getAllCryptoCurrencies = (config) => { + const locale = fromNamespace(namespaces.LOCALE)(config) + const cryptos = locale.cryptoCurrencies + const overridesCryptos = _.map(_.get('cryptoCurrencies'))(locale.overrides) + return _.uniq(_.flatten([cryptos, ...overridesCryptos])) +} + +const getNotifications = (cryptoCurrency, machine, config) => { + const notifications = fromNamespace(namespaces.NOTIFICATIONS)(config) + + const cryptoFilter = _.matches({ cryptoCurrency }) + const withCryptoBalance = resolveOverrides(notifications, cryptoFilter, notifications.cryptoBalanceOverrides, 'cryptoBalanceOverrides') + + const fiatFilter = _.matches({ machine }) + const withFiatBalance = resolveOverrides(withCryptoBalance, fiatFilter, withCryptoBalance.fiatBalanceOverrides, 'fiatBalanceOverrides') + + const withSms = fromNamespace('sms', withFiatBalance) + const withEmail = fromNamespace('email', withFiatBalance) + + const final = { ...withFiatBalance, sms: withSms, email: withEmail } + return final +} + +const getGlobalNotifications = config => getNotifications(null, null, config) + +const getTriggers = _.get('triggers') + +module.exports = { + getWalletSettings, + getOperatorInfo, + getNotifications, + getGlobalNotifications, + getLocale, + getGlobalLocale, + getCommissions, + getReceipt, + getCoinAtmRadar, + getTermsConditions, + getAllCryptoCurrencies, + getTriggers, + getCashOut +} diff --git a/lib/new-settings-loader.js b/lib/new-settings-loader.js index 7ae6a3ab..3c53bd08 100644 --- a/lib/new-settings-loader.js +++ b/lib/new-settings-loader.js @@ -9,20 +9,11 @@ low(adapter).then(it => { db = it }) -function replace (array, index, value) { - return array.slice(0, index).concat([value]).concat(array.slice(index + 1)) -} - -function replaceOrAdd (accounts, account) { - const index = _.findIndex(['code', account.code], accounts) - return index !== -1 ? replace(accounts, index, account) : _.concat(accounts)(account) -} - function saveAccounts (accountsToSave) { const currentState = db.getState() || {} - const accounts = currentState.accounts || [] + const accounts = currentState.accounts || {} - const newAccounts = _.reduce(replaceOrAdd)(accounts)(accountsToSave) + const newAccounts = _.assign(accounts)(accountsToSave) const newState = _.set('accounts', newAccounts, currentState) db.setState(newState) @@ -51,4 +42,28 @@ function getConfig () { return (state && state.config) || {} } -module.exports = { getConfig, saveConfig, saveAccounts, getAccounts } +function loadLatest () { + return new Promise((resolve) => { + if (!db) { + setTimeout(() => { + return resolve(db.getState()) + }, 1000) + } else { + return resolve(db.getState()) + } + }) +} + +function load (versionId) { + return new Promise((resolve) => { + if (!db) { + setTimeout(() => { + return resolve(db.getState()) + }, 1000) + } else { + return resolve(db.getState()) + } + }) +} + +module.exports = { getConfig, saveConfig, saveAccounts, getAccounts, loadLatest, load } diff --git a/lib/notifier.js b/lib/notifier.js index 0885fd12..5413062f 100644 --- a/lib/notifier.js +++ b/lib/notifier.js @@ -15,6 +15,7 @@ const ALERT_SEND_INTERVAL = T.hour const PING = 'PING' const STALE = 'STALE' const LOW_CRYPTO_BALANCE = 'LOW_CRYPTO_BALANCE' +const HIGH_CRYPTO_BALANCE = 'HIGH_CRYPTO_BALANCE' const CASH_BOX_FULL = 'CASH_BOX_FULL' const LOW_CASH_OUT = 'LOW_CASH_OUT' @@ -22,6 +23,7 @@ const CODES_DISPLAY = { PING: 'Machine Down', STALE: 'Machine Stuck', LOW_CRYPTO_BALANCE: 'Low Crypto Balance', + HIGH_CRYPTO_BALANCE: 'High Crypto Balance', CASH_BOX_FULL: 'Cash box full', LOW_CASH_OUT: 'Low Cash-out' } @@ -41,47 +43,54 @@ function sameState (a, b) { return a.note.txId === b.note.txId && a.note.state === b.note.state } -function sendNoAlerts (plugins) { +function sendNoAlerts (plugins, smsEnabled, emailEnabled) { const subject = '[Lamassu] All clear' - const rec = { - sms: { - body: subject - }, - email: { - subject, - body: 'No errors are reported for your machines.' - } + + let rec = {} + if (smsEnabled) { + rec = _.set(['sms', 'body'])(subject)(rec) + } + + if (emailEnabled) { + rec = _.set(['email', 'subject'])(subject)(rec) + rec = _.set(['email', 'body'])('No errors are reported for your machines.')(rec) } return plugins.sendMessage(rec) } function checkNotification (plugins) { - if (!plugins.notificationsEnabled()) return Promise.resolve() + const notifications = plugins.getNotificationConfig() + const isActive = it => it.active && (it.balance || it.errors) + const smsEnabled = isActive(notifications.sms) + const emailEnabled = isActive(notifications.email) + + if (!smsEnabled && !emailEnabled) return Promise.resolve() return checkStatus(plugins) .then(alertRec => { - const currentAlertFingerprint = buildAlertFingerprint(alertRec) + const currentAlertFingerprint = buildAlertFingerprint(alertRec, notifications) if (!currentAlertFingerprint) { const inAlert = !!alertFingerprint alertFingerprint = null lastAlertTime = null - if (inAlert) return sendNoAlerts(plugins) + if (inAlert) return sendNoAlerts(plugins, smsEnabled, emailEnabled) } const alertChanged = currentAlertFingerprint === alertFingerprint && lastAlertTime - Date.now() < ALERT_SEND_INTERVAL if (alertChanged) return - const rec = { - sms: { - body: printSmsAlerts(alertRec) - }, - email: { - subject: alertSubject(alertRec), - body: printEmailAlerts(alertRec) - } + let rec = {} + if (smsEnabled) { + rec = _.set(['sms', 'body'])(printSmsAlerts(alertRec, notifications.sms))(rec) } + + if (emailEnabled) { + rec = _.set(['email', 'subject'])(alertSubject(alertRec, notifications.email))(rec) + rec = _.set(['email', 'body'])(printEmailAlerts(alertRec, notifications.email))(rec) + } + alertFingerprint = currentAlertFingerprint lastAlertTime = Date.now() @@ -162,12 +171,13 @@ function checkStatus (plugins) { return eventRow.device_id === deviceId }) - const balanceAlerts = _.filter(['deviceId', deviceId], balances) const ping = pings[deviceId] || [] const stuckScreen = checkStuckScreen(deviceEvents, deviceName) - const deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping - alerts.devices[deviceId] = _.concat(deviceAlerts, balanceAlerts) + if (!alerts.devices[deviceId]) alerts.devices[deviceId] = {} + alerts.devices[deviceId].balanceAlerts = _.filter(['deviceId', deviceId], balances) + alerts.devices[deviceId].deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping + alerts.deviceNames[deviceId] = deviceName }) @@ -194,6 +204,9 @@ function emailAlert (alert) { case LOW_CRYPTO_BALANCE: const balance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode) return `Low balance in ${alert.cryptoCode} [${balance}]` + case HIGH_CRYPTO_BALANCE: + const highBalance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode) + return `High balance in ${alert.cryptoCode} [${highBalance}]` case CASH_BOX_FULL: return `Cash box full on ${alert.machineName} [${alert.notes} banknotes]` case LOW_CASH_OUT: @@ -205,28 +218,48 @@ function emailAlerts (alerts) { return alerts.map(emailAlert).join('\n') + '\n' } -function printEmailAlerts (alertRec) { +function printEmailAlerts (alertRec, config) { let body = 'Errors were reported by your Lamassu Machines.\n' - if (alertRec.general.length !== 0) { + if (config.balance && alertRec.general.length !== 0) { body = body + '\nGeneral errors:\n' - body = body + emailAlerts(alertRec.general) + body = body + emailAlerts(alertRec.general) + '\n' } _.keys(alertRec.devices).forEach(function (device) { const deviceName = alertRec.deviceNames[device] body = body + '\nErrors for ' + deviceName + ':\n' - body = body + emailAlerts(alertRec.devices[device]) + + let alerts = [] + if (config.balance) { + alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts) + } + + if (config.errors) { + alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts) + } + + body = body + emailAlerts(alerts) }) return body } -function alertSubject (alertRec) { - let alerts = alertRec.general +function alertSubject (alertRec, config) { + let alerts = [] + + if (config.balance) { + alerts = _.concat(alerts, alertRec.general) + } _.keys(alertRec.devices).forEach(function (device) { - alerts = _.concat(alerts, alertRec.devices[device]) + if (config.balance) { + alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts) + } + + if (config.errors) { + alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts) + } }) if (alerts.length === 0) return null @@ -235,11 +268,21 @@ function alertSubject (alertRec) { return '[Lamassu] Errors reported: ' + alertTypes.join(', ') } -function printSmsAlerts (alertRec) { - let alerts = alertRec.general +function printSmsAlerts (alertRec, config) { + let alerts = [] + + if (config.balance) { + alerts = _.concat(alerts, alertRec.general) + } _.keys(alertRec.devices).forEach(function (device) { - alerts = _.concat(alerts, alertRec.devices[device]) + if (config.balance) { + alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts) + } + + if (config.errors) { + alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts) + } }) if (alerts.length === 0) return null @@ -265,9 +308,39 @@ function printSmsAlerts (alertRec) { return '[Lamassu] Errors reported: ' + displayAlertTypes.join(', ') } -function buildAlertFingerprint (alertRec) { - const subject = alertSubject(alertRec) - if (!subject) return null +function getAlertTypes (alertRec, config) { + let alerts = [] + + if (!config.active || (!config.balance && !config.errors)) return alerts + + if (config.balance) { + alerts = _.concat(alerts, alertRec.general) + } + + _.keys(alertRec.devices).forEach(function (device) { + if (config.balance) { + alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts) + } + + if (config.errors) { + alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts) + } + }) + + return alerts +} + +function buildAlertFingerprint (alertRec, notifications) { + const sms = getAlertTypes(alertRec, notifications.sms) + const email = getAlertTypes(alertRec, notifications.email) + + if (sms.length === 0 && email.length === 0) return null + + const smsTypes = _.map(codeDisplay, _.uniq(_.map('code', sms))).sort() + const emailTypes = _.map(codeDisplay, _.uniq(_.map('code', email))).sort() + + const subject = _.concat(smsTypes, emailTypes).join(', ') + return crypto.createHash('sha256').update(subject).digest('hex') } diff --git a/lib/pairing.js b/lib/pairing.js index 180aae6b..5932878c 100644 --- a/lib/pairing.js +++ b/lib/pairing.js @@ -4,7 +4,6 @@ const readFile = pify(fs.readFile) const db = require('./db') const options = require('./options') const logger = require('./logger') -const settingsLoader = require('./settings-loader') function pullToken (token) { const sql = `delete from pairing_tokens @@ -13,33 +12,12 @@ function pullToken (token) { return db.one(sql, [token]) } -function configureNewDevice (deviceId, machineName, machineModel) { - const scope = {crypto: 'global', machine: deviceId} - const newFields = [ - settingsLoader.configAddField(scope, 'cashOutEnabled', 'onOff', null, false), - settingsLoader.configAddField(scope, 'machineName', 'string', null, machineName), - settingsLoader.configAddField(scope, 'machineModel', 'string', null, machineModel) - ] - - return settingsLoader.modifyConfig(newFields) -} - -function removeDeviceConfig (deviceId) { - const scope = {crypto: 'global', machine: deviceId} - const newFields = [ - settingsLoader.configDeleteField(scope, 'cashOutEnabled'), - settingsLoader.configDeleteField(scope, 'machineName'), - settingsLoader.configDeleteField(scope, 'machineModel') - ] - - return settingsLoader.modifyConfig(newFields) -} - function unpair (deviceId) { const sql = 'delete from devices where device_id=$1' const deleteMachinePings = 'delete from machine_pings where device_id=$1' + + // TODO new-admin: We should remove all configs related to that device. This can get tricky. return Promise.all([db.none(sql, [deviceId]), db.none(deleteMachinePings, [deviceId])]) - .then(() => removeDeviceConfig(deviceId)) } function pair (token, deviceId, machineModel) { @@ -51,8 +29,7 @@ function pair (token, deviceId, machineModel) { on conflict (device_id) do update set paired=TRUE, display=TRUE` - return configureNewDevice(deviceId, r.name, machineModel) - .then(() => db.none(insertSql, [deviceId, r.name])) + return db.none(insertSql, [deviceId, r.name]) .then(() => true) }) .catch(err => { diff --git a/lib/plugins.js b/lib/plugins.js index 0b55a815..62dec217 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -11,7 +11,7 @@ const db = require('./db') const logger = require('./logger') const logs = require('./logs') const T = require('./time') -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') const ticker = require('./ticker') const wallet = require('./wallet') const exchange = require('./exchange') @@ -34,22 +34,22 @@ const tradesQueues = {} function plugins (settings, deviceId) { function buildRates (tickers) { - const config = configManager.machineScoped(deviceId, settings.config) - const cryptoCodes = config.cryptoCurrencies + const localeConfig = configManager.getLocale(deviceId, settings.config) + const cryptoCodes = localeConfig.cryptoCurrencies const rates = {} cryptoCodes.forEach((cryptoCode, i) => { - const cryptoConfig = configManager.scoped(cryptoCode, deviceId, settings.config) + const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config) const rateRec = tickers[i] if (!rateRec) return - const cashInCommission = BN(1).add(BN(cryptoConfig.cashInCommission).div(100)) + const cashInCommission = BN(1).add(BN(commissions.cashIn).div(100)) - const cashOutCommission = _.isNil(cryptoConfig.cashOutCommission) + const cashOutCommission = _.isNil(commissions.cashOut) ? undefined - : BN(1).add(BN(cryptoConfig.cashOutCommission).div(100)) + : BN(1).add(BN(commissions.cashOut).div(100)) if (Date.now() - rateRec.timestamp > STALE_TICKER) return logger.warn('Stale rate for ' + cryptoCode) const rate = rateRec.rates @@ -62,19 +62,13 @@ function plugins (settings, deviceId) { return rates } - function transactionNotificationsEnabled () { - const config = configManager.unscoped(settings.config) - return config.transactionNotificationsEnabled - } - - function notificationsEnabled () { - const config = configManager.unscoped(settings.config) - return config.notificationsEnabled + function getNotificationConfig () { + return configManager.getGlobalNotifications(settings.config) } function buildBalances (balanceRecs) { - const config = configManager.machineScoped(deviceId, settings.config) - const cryptoCodes = config.cryptoCurrencies + const localeConfig = configManager.getLocale(deviceId, settings.config) + const cryptoCodes = localeConfig.cryptoCurrencies const balances = {} @@ -90,8 +84,8 @@ function plugins (settings, deviceId) { } function isZeroConf (tx) { - const config = configManager.scoped(tx.cryptoCode, deviceId, settings.config) - const zeroConfLimit = config.zeroConfLimit + const cashOutConfig = configManager.getCashOut(deviceId, settings.config) + const zeroConfLimit = cashOutConfig.zeroConfLimit return tx.fiat.lte(zeroConfLimit) } @@ -131,14 +125,14 @@ function plugins (settings, deviceId) { } function buildAvailableCassettes (excludeTxId) { - const config = configManager.machineScoped(deviceId, settings.config) + const cashOutConfig = configManager.getCashOut(deviceId, settings.config) - if (!config.cashOutEnabled) return Promise.resolve() + if (!cashOutConfig.active) return Promise.resolve() - const denominations = [config.topCashOutDenomination, - config.bottomCashOutDenomination - ] - const virtualCassettes = [config.virtualCashOutDenomination] + const denominations = [cashOutConfig.top, cashOutConfig.bottom] + + // TODO new-admin: will this actually be calculated? + const virtualCassettes = [cashOutConfig.top + cashOutConfig.bottom] return Promise.all([dbm.cassetteCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)]) .then(([rec, _redeemableTxs]) => { @@ -188,11 +182,12 @@ function plugins (settings, deviceId) { function mapCoinSettings (coinParams) { const cryptoCode = coinParams[0] const cryptoNetwork = coinParams[1] - const config = configManager.scoped(cryptoCode, deviceId, settings.config) - const minimumTx = BN(config.minimumTx) - const cashInFee = BN(config.cashInFee) - const cashInCommission = BN(config.cashInCommission) - const cashOutCommission = _.isNumber(config.cashOutCommission) ? BN(config.cashOutCommission) : null + const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config) + const minimumTx = BN(commissions.minimumTx) + const cashInFee = BN(commissions.fixedFee) + logger.info('FEE', cashInFee) + const cashInCommission = BN(commissions.cashIn) + const cashOutCommission = _.isNumber(commissions.cashOut) ? BN(commissions.cashOut) : null const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode) return { @@ -207,9 +202,10 @@ function plugins (settings, deviceId) { } function pollQueries (serialNumber, deviceTime, deviceRec) { - const config = configManager.machineScoped(deviceId, settings.config) - const fiatCode = config.fiatCurrency - const cryptoCodes = config.cryptoCurrencies + const localeConfig = configManager.getLocale(deviceId, settings.config) + + const fiatCode = localeConfig.fiatCurrency + const cryptoCodes = localeConfig.cryptoCurrencies const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c)) const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c)) @@ -283,16 +279,14 @@ function plugins (settings, deviceId) { } function dispenseAck (tx) { - const config = configManager.machineScoped(deviceId, settings.config) - const cassettes = [config.topCashOutDenomination, - config.bottomCashOutDenomination - ] + const cashOutConfig = configManager.getCashOut(deviceId, settings.config) + const cassettes = [cashOutConfig.top, cashOutConfig.bottom] return dbm.addDispense(deviceId, tx, cassettes) } function fiatBalance (fiatCode, cryptoCode) { - const config = configManager.scoped(cryptoCode, deviceId, settings.config) + const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config) return Promise.all([ ticker.getRates(settings, fiatCode, cryptoCode), wallet.balance(settings, cryptoCode) @@ -301,14 +295,14 @@ function plugins (settings, deviceId) { if (!rates || !balanceRec) return null const rawRate = rates.rates.ask - const cashInCommission = BN(1).minus(BN(config.cashInCommission).div(100)) + const cashInCommission = BN(1).minus(BN(commissions.cashIn).div(100)) const balance = balanceRec.balance if (!rawRate || !balance) return null const rate = rawRate.div(cashInCommission) - const lowBalanceMargin = BN(1) + const lowBalanceMargin = BN(1.03) const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode) const unitScale = cryptoRec.unitScale @@ -344,7 +338,12 @@ function plugins (settings, deviceId) { } function notifyOperator (tx, rec) { - if (!transactionNotificationsEnabled()) return Promise.resolve() + const notifications = configManager.getGlobalNotifications(settings.config) + + const notificationsEnabled = notifications.sms.transactions || notifications.email.transactions + const highValueTx = tx.fiat.gt(notifications.highValueTransaction) + + if (!notificationsEnabled || !highValueTx) return Promise.resolve() const isCashOut = tx.direction === 'cashOut' const zeroConf = isCashOut && isZeroConf(tx) @@ -504,9 +503,9 @@ function plugins (settings, deviceId) { .then(devices => { const deviceIds = devices.map(device => device.deviceId) const lists = deviceIds.map(deviceId => { - const config = configManager.machineScoped(deviceId, settings.config) - const fiatCode = config.fiatCurrency - const cryptoCodes = config.cryptoCurrencies + const localeConfig = configManager.getLocale(deviceId, settings.config) + const fiatCode = localeConfig.fiatCurrency + const cryptoCodes = localeConfig.cryptoCurrencies return cryptoCodes.map(cryptoCode => ({ fiatCode, @@ -591,21 +590,25 @@ function plugins (settings, deviceId) { } function sendMessage (rec) { - const config = configManager.unscoped(settings.config) + const notifications = configManager.getGlobalNotifications(settings.config) let promises = [] - if (config.notificationsEmailEnabled) promises.push(email.sendMessage(settings, rec)) - if (config.notificationsSMSEnabled) promises.push(sms.sendMessage(settings, rec)) + if (notifications.email.active && rec.email) promises.push(email.sendMessage(settings, rec)) + if (notifications.sms.active && rec.sms) promises.push(sms.sendMessage(settings, rec)) return Promise.all(promises) } function sendTransactionMessage (rec) { - const config = configManager.unscoped(settings.config) + const notifications = configManager.getGlobalNotifications(settings.config) let promises = [] - if (config.transactionNotificationsEmailEnabled) promises.push(email.sendMessage(settings, rec)) - if (config.transactionNotificationsSMSEnabled) promises.push(sms.sendMessage(settings, rec)) + + const emailActive = notifications.email.active && notifications.email.transactions + if (emailActive) promises.push(email.sendMessage(settings, rec)) + + const smsActive = notifications.sms.active && notifications.sms.transactions + if (smsActive) promises.push(sms.sendMessage(settings, rec)) return Promise.all(promises) } @@ -615,13 +618,16 @@ function plugins (settings, deviceId) { } function checkDeviceCashBalances (fiatCode, device) { - const config = configManager.machineScoped(device.deviceId, settings.config) - const denomination1 = config.topCashOutDenomination - const denomination2 = config.bottomCashOutDenomination - const machineName = config.machineName - const cashOutEnabled = config.cashOutEnabled + const cashOutConfig = configManager.getCashOut(device.deviceId, settings.config) + const denomination1 = cashOutConfig.top + const denomination2 = cashOutConfig.bottom + const cashOutEnabled = cashOutConfig.active - const cashInAlert = device.cashbox > config.cashInAlertThreshold + const notifications = configManager.getNotifications(null, device.deviceId, settings.config) + + const machineName = device.machineName + + const cashInAlert = device.cashbox > notifications.cashInAlertThreshold ? { code: 'CASH_BOX_FULL', machineName, @@ -630,7 +636,7 @@ function plugins (settings, deviceId) { } : null - const cassette1Alert = cashOutEnabled && device.cassette1 < config.cashOutCassette1AlertThreshold + const cassette1Alert = cashOutEnabled && device.cassette1 < notifications.fiatBalanceCassette1 ? { code: 'LOW_CASH_OUT', cassette: 1, @@ -642,7 +648,7 @@ function plugins (settings, deviceId) { } : null - const cassette2Alert = cashOutEnabled && device.cassette2 < config.cashOutCassette2AlertThreshold + const cassette2Alert = cashOutEnabled && device.cassette2 < notifications.fiatBalanceCassette2 ? { code: 'LOW_CASH_OUT', cassette: 2, @@ -661,8 +667,8 @@ function plugins (settings, deviceId) { const fiatBalancePromises = cryptoCodes => _.map(c => fiatBalance(fiatCode, c), cryptoCodes) const fetchCryptoCodes = _deviceId => { - const config = configManager.machineScoped(_deviceId, settings.config) - return config.cryptoCurrencies + const localeConfig = configManager.getLocale(_deviceId, settings.config) + return localeConfig.cryptoCurrencies } const union = _.flow(_.map(fetchCryptoCodes), _.flatten, _.uniq) @@ -678,22 +684,28 @@ function plugins (settings, deviceId) { if (!fiatBalance) return null - const config = configManager.cryptoScoped(cryptoCode, settings.config) - const cryptoAlertThreshold = config.cryptoAlertThreshold + const notifications = configManager.getNotifications(cryptoCode, null, settings.config) + const lowAlertThreshold = notifications.cryptoLowBalance + const highAlertThreshold = notifications.cryptoHighBalance - return BN(fiatBalance.balance).lt(cryptoAlertThreshold) - ? { - code: 'LOW_CRYPTO_BALANCE', - cryptoCode, - fiatBalance, - fiatCode - } - : null + const req = { + cryptoCode, + fiatBalance, + fiatCode, + } + + if (BN(fiatBalance.balance).lt(lowAlertThreshold)) + return _.set('code')('LOW_CRYPTO_BALANCE')(req) + + if (BN(fiatBalance.balance).gt(highAlertThreshold)) + return _.set('code')('HIGH_CRYPTO_BALANCE')(req) + + return null } function checkBalances () { - const globalConfig = configManager.unscoped(settings.config) - const fiatCode = globalConfig.fiatCurrency + const localeConfig = configManager.getGlobalLocale(settings.config) + const fiatCode = localeConfig.fiatCurrency return machineLoader.getMachines() .then(devices => { @@ -756,9 +768,10 @@ function plugins (settings, deviceId) { } function getRawRates () { - const config = configManager.unscoped(settings.config) - const cryptoCodes = _.flatten(configManager.all('cryptoCurrencies', settings.config)) - const fiatCode = config.fiatCurrency + const localeConfig = configManager.getGlobalLocale(settings.config) + const fiatCode = localeConfig.fiatCurrency + + const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config) const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c)) return Promise.all(tickerPromises) @@ -792,7 +805,7 @@ function plugins (settings, deviceId) { buildAvailableCassettes, buy, sell, - notificationsEnabled, + getNotificationConfig, notifyOperator, fetchCurrentConfigVersion } diff --git a/lib/plugins/wallet/bitcoincashd/bitcoincashd.js b/lib/plugins/wallet/bitcoincashd/bitcoincashd.js index e7c4e322..fd141ede 100644 --- a/lib/plugins/wallet/bitcoincashd/bitcoincashd.js +++ b/lib/plugins/wallet/bitcoincashd/bitcoincashd.js @@ -25,16 +25,22 @@ function checkCryptoCode (cryptoCode) { return Promise.resolve() } -function accountBalance (account, cryptoCode, confirmations) { +function accountBalance (cryptoCode) { return checkCryptoCode(cryptoCode) - .then(() => fetch('getbalance', ['', confirmations])) - .then(r => BN(r).shift(unitScale).round()) + .then(() => fetch('getwalletinfo')) + .then(({ balance }) => BN(balance).shift(unitScale).round()) +} + +function accountUnconfirmedBalance (cryptoCode) { + return checkCryptoCode(cryptoCode) + .then(() => fetch('getwalletinfo')) + .then(({ unconfirmed_balance: balance }) => BN(balance).shift(unitScale).round()) } // We want a balance that includes all spends (0 conf) but only deposits that // have at least 1 confirmation. getbalance does this for us automatically. function balance (account, cryptoCode) { - return accountBalance(account, cryptoCode, 1) + return accountBalance(cryptoCode) } function sendCoins (account, address, cryptoAtoms, cryptoCode) { @@ -80,13 +86,13 @@ function getStatus (account, toAddress, requested, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress, cryptoCode)) .then(confirmed => { - if (confirmed.gte(requested)) return {status: 'confirmed'} + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress, cryptoCode) .then(pending => { - if (pending.gte(requested)) return {status: 'authorized'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } @@ -95,9 +101,9 @@ function newFunding (account, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => { const promises = [ - accountBalance(account, cryptoCode, 0), - accountBalance(account, cryptoCode, 1), - newAddress(account, {cryptoCode}) + accountUnconfirmedBalance(cryptoCode), + accountBalance(cryptoCode), + newAddress(account, { cryptoCode }) ] return Promise.all(promises) diff --git a/lib/plugins/wallet/bitcoind/bitcoind.js b/lib/plugins/wallet/bitcoind/bitcoind.js index 68ed5a8d..e424eeef 100644 --- a/lib/plugins/wallet/bitcoind/bitcoind.js +++ b/lib/plugins/wallet/bitcoind/bitcoind.js @@ -25,16 +25,22 @@ function checkCryptoCode (cryptoCode) { return Promise.resolve() } -function accountBalance (account, cryptoCode, confirmations) { +function accountBalance (cryptoCode) { return checkCryptoCode(cryptoCode) - .then(() => fetch('getbalance', ['*', confirmations])) - .then(r => BN(r).shift(unitScale).round()) + .then(() => fetch('getwalletinfo')) + .then(({ balance }) => BN(balance).shift(unitScale).round()) +} + +function accountUnconfirmedBalance (cryptoCode) { + return checkCryptoCode(cryptoCode) + .then(() => fetch('getwalletinfo')) + .then(({ unconfirmed_balance: balance }) => BN(balance).shift(unitScale).round()) } // We want a balance that includes all spends (0 conf) but only deposits that // have at least 1 confirmation. getbalance does this for us automatically. function balance (account, cryptoCode) { - return accountBalance(account, cryptoCode, 1) + return accountBalance(cryptoCode) } function sendCoins (account, address, cryptoAtoms, cryptoCode) { @@ -80,13 +86,13 @@ function getStatus (account, toAddress, requested, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress, cryptoCode)) .then(confirmed => { - if (confirmed.gte(requested)) return {status: 'confirmed'} + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress, cryptoCode) .then(pending => { - if (pending.gte(requested)) return {status: 'authorized'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } @@ -95,9 +101,9 @@ function newFunding (account, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => { const promises = [ - accountBalance(account, cryptoCode, 0), - accountBalance(account, cryptoCode, 1), - newAddress(account, {cryptoCode}) + accountUnconfirmedBalance(cryptoCode), + accountBalance(cryptoCode), + newAddress(account, { cryptoCode }) ] return Promise.all(promises) diff --git a/lib/plugins/wallet/bitgo/bitgo.js b/lib/plugins/wallet/bitgo/bitgo.js index 60820efd..26b1c9db 100644 --- a/lib/plugins/wallet/bitgo/bitgo.js +++ b/lib/plugins/wallet/bitgo/bitgo.js @@ -124,10 +124,10 @@ function getStatus (account, toAddress, requested, cryptoCode) { const confirmed = _.compose(sum, toBn, filterConfirmed)(transfers) const pending = _.compose(sum, toBn, filterPending)(transfers) - if (confirmed.gte(requested)) return { status: 'confirmed' } - if (pending.gte(requested)) return { status: 'authorized' } - if (pending.gt(0)) return { status: 'insufficientFunds' } - return { status: 'notSeen' } + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) } diff --git a/lib/plugins/wallet/dashd/dashd.js b/lib/plugins/wallet/dashd/dashd.js index 8fec7587..33c86c13 100644 --- a/lib/plugins/wallet/dashd/dashd.js +++ b/lib/plugins/wallet/dashd/dashd.js @@ -26,16 +26,22 @@ function checkCryptoCode (cryptoCode) { return Promise.resolve() } -function accountBalance (acount, cryptoCode, confirmations) { +function accountBalance (cryptoCode) { return checkCryptoCode(cryptoCode) - .then(() => fetch('getbalance', ['', confirmations])) - .then(r => BN(r).shift(unitScale).round()) + .then(() => fetch('getwalletinfo')) + .then(({ balance }) => BN(balance).shift(unitScale).round()) +} + +function accountUnconfirmedBalance (cryptoCode) { + return checkCryptoCode(cryptoCode) + .then(() => fetch('getwalletinfo')) + .then(({ unconfirmed_balance: balance }) => BN(balance).shift(unitScale).round()) } // We want a balance that includes all spends (0 conf) but only deposits that // have at least 1 confirmation. getbalance does this for us automatically. function balance (account, cryptoCode) { - return accountBalance(account, cryptoCode, 1) + return accountBalance(cryptoCode) } function sendCoins (account, address, cryptoAtoms, cryptoCode) { @@ -81,13 +87,13 @@ function getStatus (account, toAddress, requested, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress, cryptoCode)) .then(confirmed => { - if (confirmed.gte(requested)) return {status: 'confirmed'} + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress, cryptoCode) .then(pending => { - if (pending.gte(requested)) return {status: 'authorized'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } @@ -96,9 +102,9 @@ function newFunding (account, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => { const promises = [ - accountBalance(account, cryptoCode, 0), - accountBalance(account, cryptoCode, 1), - newAddress(account, {cryptoCode}) + accountUnconfirmedBalance(cryptoCode), + accountBalance(cryptoCode), + newAddress(account, { cryptoCode }) ] return Promise.all(promises) diff --git a/lib/plugins/wallet/geth/base.js b/lib/plugins/wallet/geth/base.js index 381bf90d..0e8b8dfa 100644 --- a/lib/plugins/wallet/geth/base.js +++ b/lib/plugins/wallet/geth/base.js @@ -158,13 +158,13 @@ function getStatus (account, toAddress, cryptoAtoms, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress)) .then(confirmed => { - if (confirmed.gte(cryptoAtoms)) return {status: 'confirmed'} + if (confirmed.gte(cryptoAtoms)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress) .then(pending => { - if (pending.gte(cryptoAtoms)) return {status: 'published'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(cryptoAtoms)) return { receivedCryptoAtoms: pending, status: 'published' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } diff --git a/lib/plugins/wallet/litecoind/litecoind.js b/lib/plugins/wallet/litecoind/litecoind.js index 1c8dba56..234b816e 100644 --- a/lib/plugins/wallet/litecoind/litecoind.js +++ b/lib/plugins/wallet/litecoind/litecoind.js @@ -26,16 +26,22 @@ function checkCryptoCode (cryptoCode) { return Promise.resolve() } -function accountBalance (acount, cryptoCode, confirmations) { +function accountBalance (cryptoCode) { return checkCryptoCode(cryptoCode) - .then(() => fetch('getbalance', ['*', confirmations])) - .then(r => BN(r).shift(unitScale).round()) + .then(() => fetch('getwalletinfo')) + .then(({ balance }) => BN(balance).shift(unitScale).round()) +} + +function accountUnconfirmedBalance (cryptoCode) { + return checkCryptoCode(cryptoCode) + .then(() => fetch('getwalletinfo')) + .then(({ unconfirmed_balance: balance }) => BN(balance).shift(unitScale).round()) } // We want a balance that includes all spends (0 conf) but only deposits that // have at least 1 confirmation. getbalance does this for us automatically. function balance (account, cryptoCode) { - return accountBalance(account, cryptoCode, 1) + return accountBalance(cryptoCode) } function sendCoins (account, address, cryptoAtoms, cryptoCode) { @@ -81,13 +87,13 @@ function getStatus (account, toAddress, requested, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress, cryptoCode)) .then(confirmed => { - if (confirmed.gte(requested)) return {status: 'confirmed'} + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress, cryptoCode) .then(pending => { - if (pending.gte(requested)) return {status: 'authorized'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } @@ -96,9 +102,9 @@ function newFunding (account, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => { const promises = [ - accountBalance(account, cryptoCode, 0), - accountBalance(account, cryptoCode, 1), - newAddress(account, {cryptoCode}) + accountUnconfirmedBalance(cryptoCode), + accountBalance(cryptoCode), + newAddress(account, { cryptoCode }) ] return Promise.all(promises) diff --git a/lib/plugins/wallet/mock-wallet/mock-wallet.js b/lib/plugins/wallet/mock-wallet/mock-wallet.js index 2a15e7b0..abaff6f7 100644 --- a/lib/plugins/wallet/mock-wallet/mock-wallet.js +++ b/lib/plugins/wallet/mock-wallet/mock-wallet.js @@ -79,9 +79,9 @@ function newFunding (account, cryptoCode) { function getStatus (account, toAddress, cryptoAtoms, cryptoCode) { const elapsed = Date.now() - t0 - if (elapsed < PUBLISH_TIME) return Promise.resolve({status: 'notSeen'}) - if (elapsed < AUTHORIZE_TIME) return Promise.resolve({status: 'published'}) - if (elapsed < CONFIRM_TIME) return Promise.resolve({status: 'authorized'}) + if (elapsed < PUBLISH_TIME) return Promise.resolve({ receivedCryptoAtoms: BN(0), status: 'notSeen' }) + if (elapsed < AUTHORIZE_TIME) return Promise.resolve({ receivedCryptoAtoms: cryptoAtoms, status: 'published' }) + if (elapsed < CONFIRM_TIME) return Promise.resolve({ receivedCryptoAtoms: cryptoAtoms, status: 'authorized' }) console.log('[%s] DEBUG: Mock wallet has confirmed transaction [%s]', cryptoCode, toAddress.slice(0, 5)) diff --git a/lib/plugins/wallet/zcashd/zcashd.js b/lib/plugins/wallet/zcashd/zcashd.js index 25618fe7..b5b23da6 100644 --- a/lib/plugins/wallet/zcashd/zcashd.js +++ b/lib/plugins/wallet/zcashd/zcashd.js @@ -26,16 +26,22 @@ function checkCryptoCode (cryptoCode) { return Promise.resolve() } -function accountBalance (acount, cryptoCode, confirmations) { +function accountBalance (cryptoCode) { return checkCryptoCode(cryptoCode) - .then(() => fetch('getbalance', ['', confirmations])) - .then(r => BN(r).shift(unitScale).round()) + .then(() => fetch('getwalletinfo')) + .then(({ balance }) => BN(balance).shift(unitScale).round()) +} + +function accountUnconfirmedBalance (cryptoCode) { + return checkCryptoCode(cryptoCode) + .then(() => fetch('getwalletinfo')) + .then(({ unconfirmed_balance: balance }) => BN(balance).shift(unitScale).round()) } // We want a balance that includes all spends (0 conf) but only deposits that // have at least 1 confirmation. getbalance does this for us automatically. function balance (account, cryptoCode) { - return accountBalance(account, cryptoCode, 1) + return accountBalance(cryptoCode) } function sendCoins (account, address, cryptoAtoms, cryptoCode) { @@ -81,13 +87,13 @@ function getStatus (account, toAddress, requested, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => confirmedBalance(toAddress, cryptoCode)) .then(confirmed => { - if (confirmed.gte(requested)) return {status: 'confirmed'} + if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } return pendingBalance(toAddress, cryptoCode) .then(pending => { - if (pending.gte(requested)) return {status: 'authorized'} - if (pending.gt(0)) return {status: 'insufficientFunds'} - return {status: 'notSeen'} + if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } + if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } + return { receivedCryptoAtoms: pending, status: 'notSeen' } }) }) } @@ -96,9 +102,9 @@ function newFunding (account, cryptoCode) { return checkCryptoCode(cryptoCode) .then(() => { const promises = [ - accountBalance(account, cryptoCode, 0), - accountBalance(account, cryptoCode, 1), - newAddress(account, {cryptoCode}) + accountUnconfirmedBalance(cryptoCode), + accountBalance(cryptoCode), + newAddress(account, { cryptoCode }) ] return Promise.all(promises) diff --git a/lib/poller.js b/lib/poller.js index 22b15b27..bbd3f708 100644 --- a/lib/poller.js +++ b/lib/poller.js @@ -9,7 +9,8 @@ const cashInTx = require('./cash-in/cash-in-tx') const sanctionsUpdater = require('./ofac/update') const sanctions = require('./ofac/index') const coinAtmRadar = require('./coinatmradar/coinatmradar') -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') +const complianceTriggers = require('./compliance-triggers') const INCOMING_TX_INTERVAL = 30 * T.seconds const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds @@ -48,9 +49,10 @@ function initialSanctionsDownload () { } function updateAndLoadSanctions () { - const config = configManager.unscoped(settings().config) + const triggers = configManager.getTriggers(settings().config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) - if (!config.sanctionsVerificationActive) return Promise.resolve() + if (!compatTriggers.sanctions) return Promise.resolve() logger.info('Updating sanctions database...') return sanctionsUpdater.update() @@ -59,10 +61,8 @@ function updateAndLoadSanctions () { } function updateCoinAtmRadar () { - const config = settings().config - return pi().getRawRates() - .then(rates => coinAtmRadar.update({ rates, config }, settings())) + .then(rates => coinAtmRadar.update(rates, settings())) } function start (__settings) { diff --git a/lib/route-helpers.js b/lib/route-helpers.js index 857dded8..4351f7d9 100644 --- a/lib/route-helpers.js +++ b/lib/route-helpers.js @@ -4,7 +4,6 @@ const db = require('./db') const dbm = require('./postgresql_interface') const T = require('./time') const BN = require('./bn') -const settingsLoader = require('./settings-loader') const TRANSACTION_EXPIRATION = T.day @@ -90,33 +89,9 @@ function updateDeviceConfigVersion (versionId) { return db.none('update devices set user_config_id=$1', [versionId]) } -function updateMachineDefaults (deviceId) { - const newFields = [{ - fieldLocator: { - fieldScope: { - crypto: 'global', - machine: deviceId - }, - code: 'cashOutEnabled', - fieldType: 'onOff', - fieldClass: null - }, - fieldValue: { - fieldType: 'onOff', - value: false - } - }] - - return settingsLoader.loadLatest() - .then(settings => { - return settingsLoader.save(settingsLoader.mergeValues(settings.config, newFields)) - }) -} - module.exports = { stateChange, fetchPhoneTx, fetchStatusTx, - updateDeviceConfigVersion, - updateMachineDefaults + updateDeviceConfigVersion } diff --git a/lib/routes.js b/lib/routes.js index 52ba93fb..493de594 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -12,9 +12,11 @@ const semver = require('semver') const dbErrorCodes = require('./db-error-codes') const options = require('./options') const logger = require('./logger') -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') +const complianceTriggers = require('./compliance-triggers') const pairing = require('./pairing') -const settingsLoader = require('./settings-loader') +// TODO new-admin: remove old settings loader from here. +const newSettingsLoader = require('./new-settings-loader') const plugins = require('./plugins') const helpers = require('./route-helpers') const poller = require('./poller') @@ -44,7 +46,7 @@ const settingsCache = {} const devMode = argv.dev || options.http function checkHasLightning (settings) { - return configManager.cryptoScoped('BTC', settings.config).layer2 !== 'no-layer2' + return configManager.getWalletSettings('BTC', settings.config).layer2 !== 'no-layer2' } function poll (req, res, next) { @@ -54,10 +56,18 @@ function poll (req, res, next) { const serialNumber = req.query.sn const pid = req.query.pid const settings = req.settings - const config = configManager.machineScoped(deviceId, settings.config) + const localeConfig = configManager.getLocale(deviceId, settings.config) const pi = plugins(settings, deviceId) const hasLightning = checkHasLightning(settings) + const triggers = configManager.getTriggers(settings.config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) + + const operatorInfo = configManager.getOperatorInfo(settings.config) + const terms = configManager.getTermsConditions(settings.config) + const cashOutConfig = configManager.getCashOut(deviceId, settings.config) + const receipt = configManager.getReceipt(settings.config) + pids[deviceId] = { pid, ts: Date.now() } return pi.pollQueries(serialNumber, deviceTime, req.query) @@ -66,14 +76,14 @@ function poll (req, res, next) { const reboot = pid && reboots[deviceId] && reboots[deviceId] === pid const restartServices = pid && restartServicesMap[deviceId] && restartServicesMap[deviceId] === pid - const langs = config.machineLanguages + const langs = localeConfig.languages const locale = { - fiatCode: config.fiatCurrency, + fiatCode: localeConfig.fiatCurrency, localeInfo: { primaryLocale: langs[0], primaryLocales: langs, - country: config.country + country: localeConfig.country } } @@ -81,49 +91,35 @@ function poll (req, res, next) { error: null, locale, version, - txLimit: config.cashInTransactionLimit, - idVerificationEnabled: config.idVerificationEnabled, - smsVerificationActive: config.smsVerificationActive, - smsVerificationThreshold: config.smsVerificationThreshold, - hardLimitVerificationActive: config.hardLimitVerificationActive, - hardLimitVerificationThreshold: config.hardLimitVerificationThreshold, - idCardDataVerificationActive: config.idCardDataVerificationActive, - idCardDataVerificationThreshold: config.idCardDataVerificationThreshold, - idCardPhotoVerificationActive: config.idCardPhotoVerificationActive, - idCardPhotoVerificationThreshold: config.idCardPhotoVerificationThreshold, - sanctionsVerificationActive: config.sanctionsVerificationActive, - sanctionsVerificationThreshold: config.sanctionsVerificationThreshold, - crossRefVerificationActive: config.crossRefVerificationActive, - crossRefVerificationThreshold: config.crossRefVerificationThreshold, - frontCameraVerificationActive: config.frontCameraVerificationActive, - frontCameraVerificationThreshold: config.frontCameraVerificationThreshold, - receiptPrintingActive: config.receiptPrintingActive, + smsVerificationActive: !!compatTriggers.sms, + smsVerificationThreshold: compatTriggers.sms, + hardLimitVerificationActive: !!compatTriggers.block, + hardLimitVerificationThreshold: compatTriggers.block, + idCardDataVerificationActive: !!compatTriggers.idData, + idCardDataVerificationThreshold: compatTriggers.idData, + idCardPhotoVerificationActive: !!compatTriggers.idPhoto, + idCardPhotoVerificationThreshold: compatTriggers.idPhoto, + sanctionsVerificationActive: !!compatTriggers.sancations, + sanctionsVerificationThreshold: compatTriggers.sancations, + frontCameraVerificationActive: !!compatTriggers.facephoto, + frontCameraVerificationThreshold: compatTriggers.facephoto, + receiptPrintingActive: receipt.active, cassettes, - twoWayMode: config.cashOutEnabled, - zeroConfLimit: config.zeroConfLimit, + twoWayMode: cashOutConfig.active, + zeroConfLimit: cashOutConfig.zeroConfLimit, reboot, restartServices, hasLightning, - operatorInfo: { - active: config.operatorInfoActive, - name: config.operatorInfoName, - phone: config.operatorInfoPhone, - email: config.operatorInfoEmail, - website: config.operatorInfoWebsite, - companyNumber: config.operatorInfoCompanyNumber - } + receipt, + operatorInfo } - // BACKWARDS_COMPATIBILITY 7.5 - // machines before 7.5 expect t&c on poll - if (!machineVersion || semver.lt(machineVersion, '7.5.0-beta')) { + // BACKWARDS_COMPATIBILITY 7.4.9 + // machines before 7.4.9 expect t&c on poll + if (!machineVersion || semver.lt(machineVersion, '7.4.9')) { response.terms = config.termsScreenActive && config.termsScreenText ? createTerms(config) : null } - if (response.idVerificationEnabled) { - response.idVerificationLimit = config.idVerificationLimit - } - return res.json(_.assign(response, results)) }) .catch(next) @@ -133,13 +129,12 @@ function getTermsConditions (req, res, next) { const deviceId = req.deviceId const settings = req.settings - const config = configManager.unscoped(req.settings.config) + const terms = configManager.getTermsConditions(settings.config) + const pi = plugins(settings, deviceId) - const terms = config.termsScreenActive && config.termsScreenText ? createTerms(config) : null - return pi.fetchCurrentConfigVersion().then(version => { - return res.json({ terms, version }) + return res.json({ terms: createTerms(terms), version }) }) .catch(next) } @@ -213,7 +208,8 @@ function verifyTx (req, res, next) { function addOrUpdateCustomer (req) { const customerData = req.body - const config = configManager.unscoped(req.settings.config) + const triggers = configManager.getTriggers(req.settings.config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) return customers.get(customerData.phone) .then(customer => { @@ -222,7 +218,7 @@ function addOrUpdateCustomer (req) { return customers.add(req.body) }) .then(customer => { - return compliance.validationPatch(req.deviceId, config, customer) + return compliance.validationPatch(req.deviceId, !!compatTriggers.sanctions, customer) .then(patch => { if (_.isEmpty(patch)) return customer return customers.update(customer.id, patch) @@ -250,14 +246,15 @@ function updateCustomer (req, res, next) { const id = req.params.id const txId = req.query.txId const patch = req.body - const config = configManager.unscoped(req.settings.config) + const triggers = configManager.getTriggers(req.settings.config) + const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) customers.getById(id) .then(customer => { if (!customer) { throw httpError('Not Found', 404) } const mergedCustomer = _.merge(customer, patch) - return compliance.validationPatch(req.deviceId, config, mergedCustomer) + return compliance.validationPatch(req.deviceId, !!compatTriggers.sanctions, mergedCustomer) .then(_.merge(patch)) .then(newPatch => customers.updatePhotoCard(id, newPatch)) .then(newPatch => customers.updateFrontCamera(id, newPatch)) @@ -305,8 +302,7 @@ function pair (req, res, next) { return pairing.pair(token, deviceId, model) .then(valid => { if (valid) { - return helpers.updateMachineDefaults(deviceId) - .then(() => res.json({ status: 'paired' })) + return res.json({ status: 'paired' }) } throw httpError('Pairing failed') @@ -457,7 +453,7 @@ localApp.post('/restartServices', (req, res) => { localApp.post('/dbChange', (req, res, next) => { settingsCache.cache = null - return settingsLoader.loadLatest() + return newSettingsLoader.loadLatest() .then(poller.reload) .then(() => logger.info('Config reloaded')) .catch(err => { @@ -504,7 +500,7 @@ function populateSettings (req, res, next) { } if (!versionId && !settingsCache.cache) { - return settingsLoader.loadLatest() + return newSettingsLoader.loadLatest() .then(settings => { settingsCache.cache = settings settingsCache.timestamp = Date.now() @@ -514,20 +510,22 @@ function populateSettings (req, res, next) { .catch(next) } - settingsLoader.load(versionId) + newSettingsLoader.load(versionId) .then(settings => { req.settings = settings }) .then(() => helpers.updateDeviceConfigVersion(versionId)) .then(() => next()) .catch(next) } -function createTerms (config) { +function createTerms (terms) { + if (!terms.active || !terms.text) return null + return { - active: config.termsScreenActive, - title: config.termsScreenTitle, - text: nmd(config.termsScreenText), - accept: config.termsAcceptButtonText, - cancel: config.termsCancelButtonText + active: terms.active, + title: terms.title, + text: nmd(terms.text), + accept: terms.acceptButtonText, + cancel: terms.cancelButtonText } } diff --git a/lib/sms.js b/lib/sms.js index b6b0a82e..c338113b 100644 --- a/lib/sms.js +++ b/lib/sms.js @@ -1,10 +1,12 @@ -const configManager = require('./config-manager') +// const configManager = require('./config-manager') const ph = require('./plugin-helper') function sendMessage (settings, rec) { return Promise.resolve() .then(() => { - const pluginCode = configManager.unscoped(settings.config).sms + // TODO new-admin: how to load mock here? Only on dev? + // const pluginCode = configManager.unscoped(settings.config).sms + const pluginCode = 'twilio' const plugin = ph.load(ph.SMS, pluginCode) const account = settings.accounts[pluginCode] diff --git a/lib/ticker.js b/lib/ticker.js index ed42c7af..5ea068ec 100644 --- a/lib/ticker.js +++ b/lib/ticker.js @@ -1,5 +1,5 @@ const mem = require('mem') -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') const ph = require('./plugin-helper') const logger = require('./logger') @@ -11,8 +11,9 @@ function _getRates (settings, fiatCode, cryptoCode) { return Promise.resolve() .then(() => { const config = settings.config - const plugin = configManager.cryptoScoped(cryptoCode, config).ticker + const plugin = configManager.getWalletSettings(cryptoCode, config).ticker + logger.info(plugin) const account = settings.accounts[plugin] const ticker = ph.load(ph.TICKER, plugin) diff --git a/lib/tx.js b/lib/tx.js index 32eb3366..9d290ce5 100644 --- a/lib/tx.js +++ b/lib/tx.js @@ -29,13 +29,13 @@ function massage (tx, pi) { cashInFee: BN(r.cashInFee), cashInFeeCrypto: BN(r.cashInFeeCrypto), commissionPercentage: BN(r.commissionPercentage), - rawTickerPrice: BN(r.rawTickerPrice), + rawTickerPrice: r.rawTickerPrice ? BN(r.rawTickerPrice) : null, minimumTx: BN(r.minimumTx) } : { cryptoAtoms: BN(r.cryptoAtoms), fiat: BN(r.fiat), - rawTickerPrice: BN(r.rawTickerPrice), + rawTickerPrice: r.rawTickerPrice ? BN(r.rawTickerPrice) : null, commissionPercentage: BN(r.commissionPercentage) } diff --git a/lib/wallet.js b/lib/wallet.js index 0e069f8c..523bdc23 100644 --- a/lib/wallet.js +++ b/lib/wallet.js @@ -2,7 +2,7 @@ const _ = require('lodash/fp') const mem = require('mem') const hkdf = require('futoin-hkdf') -const configManager = require('./config-manager') +const configManager = require('./new-config-manager') const pify = require('pify') const fs = pify(require('fs')) @@ -32,7 +32,7 @@ function fetchWallet (settings, cryptoCode) { return fs.readFile(options.mnemonicPath, 'utf8') .then(mnemonic => { const masterSeed = mnemonicHelpers.toEntropyBuffer(mnemonic) - const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet + const plugin = configManager.getWalletSettings(cryptoCode, settings.config).wallet const wallet = ph.load(ph.WALLET, plugin) const rawAccount = settings.accounts[plugin] const account = _.set('seed', computeSeed(masterSeed), rawAccount) @@ -104,7 +104,7 @@ function mergeStatus (a, b) { if (!a) return b if (!b) return a - return { status: mergeStatusMode(a.status, b.status) } + return { receivedCryptoAtoms: a.receivedCryptoAtoms, status: mergeStatusMode(a.status, b.status) } } function mergeStatusMode (a, b) { @@ -122,8 +122,11 @@ function mergeStatusMode (a, b) { } function getWalletStatus (settings, tx) { + const fudgeFactorEnabled = configManager.unscoped(settings.config).fudgeFactorActive + const fudgeFactor = fudgeFactorEnabled ? 100 : 0 + const walletStatusPromise = fetchWallet(settings, tx.cryptoCode) - .then(r => r.wallet.getStatus(r.account, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode)) + .then(r => r.wallet.getStatus(r.account, tx.toAddress, tx.cryptoAtoms.minus(fudgeFactor), tx.cryptoCode)) return Promise.all([ walletStatusPromise, @@ -135,10 +138,9 @@ function getWalletStatus (settings, tx) { } function authorizeZeroConf (settings, tx, machineId) { - const cryptoConfig = configManager.cryptoScoped(tx.cryptoCode, settings.config) - const machineConfig = configManager.machineScoped(machineId, settings.config) - const plugin = cryptoConfig.zeroConf - const zeroConfLimit = machineConfig.zeroConfLimit + const plugin = configManager.getWalletSettings(tx.cryptoCode, settings.config).zeroConf + const cashOutConfig = configManager.cashOutConfig(machineId, settings.config) + const zeroConfLimit = cashOutConfig.zeroConfLimit if (!_.isObject(tx.fiat)) { return Promise.reject(new Error('tx.fiat is undefined!')) @@ -170,7 +172,7 @@ function getStatus (settings, tx, machineId) { const status = isAuthorized ? 'authorized' : unauthorizedStatus - return { status } + return { receivedCryptoAtoms: statusRec.receivedCryptoAtoms, status } }) } @@ -189,7 +191,7 @@ function isHd (settings, cryptoCode) { } function cryptoNetwork (settings, cryptoCode) { - const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet + const plugin = configManager.getWalletSettings(cryptoCode, settings.config).wallet const wallet = ph.load(ph.WALLET, plugin) const account = settings.accounts[plugin] diff --git a/migrations/1581455088977-add-amount-received.js b/migrations/1581455088977-add-amount-received.js new file mode 100644 index 00000000..89c27426 --- /dev/null +++ b/migrations/1581455088977-add-amount-received.js @@ -0,0 +1,13 @@ +const db = require('./db') + +exports.up = function (next) { + var sql = [ + 'ALTER TABLE cash_out_txs ADD COLUMN received_crypto_atoms numeric(30) null DEFAULT null' + ] + + db.multi(sql, next) +} + +exports.down = function (next) { + next() +} diff --git a/new-lamassu-admin/src/components/Modal.js b/new-lamassu-admin/src/components/Modal.js index 7651be26..fc84d0a8 100644 --- a/new-lamassu-admin/src/components/Modal.js +++ b/new-lamassu-admin/src/components/Modal.js @@ -3,17 +3,19 @@ import classnames from 'classnames' import React from 'react' import { IconButton } from 'src/components/buttons' -import { H1 } from 'src/components/typography' +import { H1, H2 } from 'src/components/typography' import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg' const styles = { modal: { display: 'flex', justifyContent: 'center', + flexDirection: 'column', alignItems: 'center' }, - wrapper: ({ width }) => ({ + wrapper: ({ width, height }) => ({ width, + height, display: 'flex', flexDirection: 'column', minHeight: 400, @@ -45,7 +47,10 @@ const useStyles = makeStyles(styles) const Modal = ({ width, + height, title, + titleSmall, + infoPanel, handleClose, children, className, @@ -53,7 +58,9 @@ const Modal = ({ closeOnBackdropClick, ...props }) => { - const classes = useStyles({ width }) + const classes = useStyles({ width, height }) + const TitleCase = titleSmall ? H2 : H1 + const closeSize = titleSmall ? 16 : 20 const innerClose = (evt, reason) => { if (!closeOnBackdropClick && reason === 'backdropClick') return @@ -63,18 +70,25 @@ const Modal = ({ return ( - -
- {title &&

{title}

} - handleClose()}> - - -
-
{children}
-
+ <> + +
+ {title && {title}} + handleClose()}> + + +
+
{children}
+
+ {infoPanel && ( + + {infoPanel} + + )} +
) } diff --git a/new-lamassu-admin/src/components/editableTable/Row.js b/new-lamassu-admin/src/components/editableTable/Row.js index 0a6b91dc..ab95f363 100644 --- a/new-lamassu-admin/src/components/editableTable/Row.js +++ b/new-lamassu-admin/src/components/editableTable/Row.js @@ -154,6 +154,7 @@ const ERow = ({ editing, disabled }) => { enableEdit, enableDelete, enableToggle, + rowSize, stripeWhen } = useContext(TableCtx) @@ -163,6 +164,7 @@ const ERow = ({ editing, disabled }) => { const innerElements = shouldStripe ? groupStriped(elements) : elements return ( {innerElements.map((it, idx) => { diff --git a/new-lamassu-admin/src/components/editableTable/Table.js b/new-lamassu-admin/src/components/editableTable/Table.js index 5e89ba18..7477bcca 100644 --- a/new-lamassu-admin/src/components/editableTable/Table.js +++ b/new-lamassu-admin/src/components/editableTable/Table.js @@ -31,6 +31,7 @@ const ETable = ({ elements = [], data = [], save, + rowSize = 'md', validationSchema, enableCreate, enableEdit, @@ -51,7 +52,8 @@ const ETable = ({ const [editingId, setEditingId] = useState(null) const [adding, setAdding] = useState(false) - const innerSave = async it => { + const innerSave = async value => { + const it = validationSchema.cast(value) const index = R.findIndex(R.propEq('id', it.id))(data) const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data) @@ -107,6 +109,7 @@ const ETable = ({ onDelete, deleteWidth, enableToggle, + rowSize, onToggle, toggleWidth, actionColSize, diff --git a/new-lamassu-admin/src/components/fake-table/Table.js b/new-lamassu-admin/src/components/fake-table/Table.js index b5a84760..2ceaee30 100644 --- a/new-lamassu-admin/src/components/fake-table/Table.js +++ b/new-lamassu-admin/src/components/fake-table/Table.js @@ -76,18 +76,8 @@ const ThDoubleLevel = ({ title, children, className }) => { ) } -const CellDoubleLevel = ({ children, className }) => { - const classes = useStyles() - - return ( -
- {children} -
- ) -} - -const Tr = ({ error, errorMessage, children, className }) => { - const classes = useStyles() +const Tr = ({ onClick, error, errorMessage, children, className, size }) => { + const classes = useStyles({ size }) const cardClasses = { root: classes.cardContentRoot } const classNames = { [classes.tr]: true, @@ -98,7 +88,7 @@ const Tr = ({ error, errorMessage, children, className }) => { return ( <> - +
{children}
{error &&
{errorMessage}
} @@ -128,6 +118,5 @@ export { Td, Th, ThDoubleLevel, - CellDoubleLevel, EditCell } diff --git a/new-lamassu-admin/src/components/fake-table/Table.styles.js b/new-lamassu-admin/src/components/fake-table/Table.styles.js index 84acf4a9..bc459a5c 100644 --- a/new-lamassu-admin/src/components/fake-table/Table.styles.js +++ b/new-lamassu-admin/src/components/fake-table/Table.styles.js @@ -70,14 +70,16 @@ export default { trError: { backgroundColor: tableErrorColor }, - mainContent: { - display: 'flex', - alignItems: 'center', - minHeight: 48 + mainContent: ({ size }) => { + const minHeight = size === 'lg' ? 68 : 48 + return { + display: 'flex', + alignItems: 'center', + minHeight + } }, // mui-overrides cardContentRoot: { - // display: 'flex', margin: 0, padding: 0, '&:last-child': { @@ -89,7 +91,7 @@ export default { '&:before': { height: 0 }, - margin: [[4, 0]], + margin: [[4, 0, 0, 0]], width: '100%', boxShadow: [[0, 0, 4, 0, 'rgba(0, 0, 0, 0.08)']] }, diff --git a/new-lamassu-admin/src/components/inputs/base/TextInput.js b/new-lamassu-admin/src/components/inputs/base/TextInput.js index b4b41f3c..243cf829 100644 --- a/new-lamassu-admin/src/components/inputs/base/TextInput.js +++ b/new-lamassu-admin/src/components/inputs/base/TextInput.js @@ -26,7 +26,7 @@ const TextInput = memo( ...props }) => { const classes = useStyles({ textAlign, width, size }) - const filled = !error && value && !R.isEmpty(value) + const filled = !error && !R.isNil(value) && !R.isEmpty(value) const inputClasses = { [classes.bold]: bold diff --git a/new-lamassu-admin/src/components/inputs/formik/RadioGroup.js b/new-lamassu-admin/src/components/inputs/formik/RadioGroup.js index 3702101c..e7b94554 100644 --- a/new-lamassu-admin/src/components/inputs/formik/RadioGroup.js +++ b/new-lamassu-admin/src/components/inputs/formik/RadioGroup.js @@ -13,8 +13,9 @@ const RadioGroupFormik = memo(({ label, ...props }) => { options={props.options} ariaLabel={name} onChange={e => { + console.log(e) onChange(e) - props.resetError() + props.resetError && props.resetError() }} className={props.className} {...props} diff --git a/new-lamassu-admin/src/components/inputs/formik/index.js b/new-lamassu-admin/src/components/inputs/formik/index.js index 66e1e1e2..30937441 100644 --- a/new-lamassu-admin/src/components/inputs/formik/index.js +++ b/new-lamassu-admin/src/components/inputs/formik/index.js @@ -1,4 +1,6 @@ +import Autocomplete from './Autocomplete' import Checkbox from './Checkbox' +import RadioGroup from './RadioGroup' import TextInput from './TextInput' -export { Checkbox, TextInput } +export { Autocomplete, Checkbox, TextInput, RadioGroup } diff --git a/new-lamassu-admin/src/components/tables/DataTable.js b/new-lamassu-admin/src/components/tables/DataTable.js index dcb8f91b..0da307e0 100644 --- a/new-lamassu-admin/src/components/tables/DataTable.js +++ b/new-lamassu-admin/src/components/tables/DataTable.js @@ -38,36 +38,49 @@ const Row = ({ }) => { const classes = useStyles() + const hasPointer = onClick || expandable + const trClasses = { + [classes.pointer]: hasPointer, + [classes.row]: true, + [classes.expanded]: expanded + } + return ( -
onClick && onClick(data)}> - - {elements.map(({ view = it => it?.toString(), ...props }, idx) => ( - - {view(data)} - - ))} - {expandable && ( - - - - )} - - {expandable && expanded && ( - - -
- +
+
+ { + expandable && expandRow(id) + onClick && onClick(data) + }} + error={data.error} + errorMessage={data.errorMessage}> + {elements.map(({ view = it => it?.toString(), ...props }, idx) => ( + + {view(data)} + + ))} + {expandable && ( + + + + )} +
+ {expandable && expanded && ( +
+ + +
+ + +
)}
) diff --git a/new-lamassu-admin/src/components/tables/DataTable.styles.js b/new-lamassu-admin/src/components/tables/DataTable.styles.js index dc0e3e58..6c5dbc58 100644 --- a/new-lamassu-admin/src/components/tables/DataTable.styles.js +++ b/new-lamassu-admin/src/components/tables/DataTable.styles.js @@ -1,3 +1,5 @@ +import { zircon } from 'src/styling/variables' + export default { expandButton: { border: 'none', @@ -8,6 +10,19 @@ export default { row: { borderRadius: 0 }, + expanded: { + border: [[2, 'solid', zircon]], + boxShadow: '0 0 8px 0 rgba(0,0,0,0.08)' + }, + before: { + paddingTop: 12 + }, + after: { + paddingBottom: 12 + }, + pointer: { + cursor: 'pointer' + }, body: { flex: [[1, 1, 'auto']] }, diff --git a/new-lamassu-admin/src/pages/Cashout/Cashout.js b/new-lamassu-admin/src/pages/Cashout/Cashout.js index 5a82d083..03dbd611 100644 --- a/new-lamassu-admin/src/pages/Cashout/Cashout.js +++ b/new-lamassu-admin/src/pages/Cashout/Cashout.js @@ -11,9 +11,8 @@ import Wizard from './Wizard' import { DenominationsSchema, getElements } from './helper' const SAVE_CONFIG = gql` - mutation Save($config: JSONObject, $accounts: [JSONObject]) { + mutation Save($config: JSONObject) { saveConfig(config: $config) - saveAccounts(accounts: $accounts) } ` @@ -44,7 +43,6 @@ const CashOut = ({ name: SCREEN_KEY }) => { const save = (rawConfig, accounts) => { const config = toNamespace(SCREEN_KEY)(rawConfig) setError(false) - return saveConfig({ variables: { config, accounts } }) } diff --git a/new-lamassu-admin/src/pages/Cashout/Wizard.js b/new-lamassu-admin/src/pages/Cashout/Wizard.js index a49576b3..2411f7f8 100644 --- a/new-lamassu-admin/src/pages/Cashout/Wizard.js +++ b/new-lamassu-admin/src/pages/Cashout/Wizard.js @@ -1,11 +1,13 @@ import * as R from 'ramda' import React, { useState } from 'react' +import * as Yup from 'yup' import Modal from 'src/components/Modal' import { toNamespace } from 'src/utils/config' import WizardSplash from './WizardSplash' import WizardStep from './WizardStep' +import { DenominationsSchema } from './helper' const LAST_STEP = 3 const MODAL_WIDTH = 554 @@ -20,12 +22,14 @@ const Wizard = ({ machine, onClose, save, error }) => { const isLastStep = step === LAST_STEP const onContinue = async it => { - const newConfig = R.merge(config, it) - if (isLastStep) { - return save(toNamespace(machine.deviceId, newConfig)) + return save( + toNamespace(machine.deviceId, DenominationsSchema.cast(config)) + ) } + const newConfig = R.merge(config, it) + setState({ step: step + 1, config: newConfig @@ -35,11 +39,17 @@ const Wizard = ({ machine, onClose, save, error }) => { const getStepData = () => { switch (step) { case 1: - return { type: 'top', display: 'Cassete 1 (Top)' } + return { + type: 'top', + display: 'Cassete 1 (Top)', + schema: Yup.object().shape({ top: Yup.number().required() }) + } case 2: - return { type: 'bottom', display: 'Cassete 2' } - case 3: - return { type: 'agreed' } + return { + type: 'bottom', + display: 'Cassete 2', + schema: Yup.object().shape({ bottom: Yup.number().required() }) + } default: return null } diff --git a/new-lamassu-admin/src/pages/Cashout/WizardStep.js b/new-lamassu-admin/src/pages/Cashout/WizardStep.js index e2fe99fa..b0a0a3e9 100644 --- a/new-lamassu-admin/src/pages/Cashout/WizardStep.js +++ b/new-lamassu-admin/src/pages/Cashout/WizardStep.js @@ -1,77 +1,33 @@ import { makeStyles } from '@material-ui/core' import classnames from 'classnames' -import * as R from 'ramda' -import React, { useReducer, useEffect } from 'react' +import { Formik, Form, Field } from 'formik' +import React from 'react' import ErrorMessage from 'src/components/ErrorMessage' import Stepper from 'src/components/Stepper' import { Button } from 'src/components/buttons' -import { TextInput } from 'src/components/inputs' +import { TextInput } from 'src/components/inputs/formik' import { Info2, H4, P } from 'src/components/typography' import styles from './WizardStep.styles' const useStyles = makeStyles(styles) -const initialState = { - selected: null, - iError: false -} - -const reducer = (state, action) => { - switch (action.type) { - case 'select': - return { - form: null, - selected: action.selected, - isNew: null, - iError: false - } - case 'form': - return { - form: action.form, - selected: action.form.code, - isNew: true, - iError: false - } - case 'error': - return R.merge(state, { iError: true }) - case 'reset': - return initialState - default: - throw new Error() - } -} - const WizardStep = ({ type, name, step, + schema, error, lastStep, onContinue, display }) => { const classes = useStyles() - const [{ iError, selected }, dispatch] = useReducer(reducer, initialState) - - useEffect(() => { - dispatch({ type: 'reset' }) - }, [step]) - - const iContinue = config => { - if (lastStep) config[type] = true - - if (!config || !config[type]) { - return dispatch({ type: 'error' }) - } - - onContinue(config) - } const label = lastStep ? 'Finish' : 'Next' const subtitleClass = { [classes.subtitle]: true, - [classes.error]: iError + [classes.error]: error } return ( @@ -81,19 +37,26 @@ const WizardStep = ({ {display &&

Edit {display}

} {!lastStep && ( - - dispatch({ type: 'select', selected: evt.target.value }) - } - autoFocus - id="confirm-input" - type="text" - size="lg" - touched={{}} - error={false} - InputLabelProps={{ shrink: true }} - /> + +
+ +
+ +
+ +
// TODO: there was a disabled link here showing the currency code; restore it )} @@ -112,17 +75,14 @@ const WizardStep = ({ Settings. where you can set exceptions for each of the available cryptocurrencies.

+
+ {error && Failed to save} + +
)} - -
- {error && Failed to save} - -
) } diff --git a/new-lamassu-admin/src/pages/Cashout/helper.js b/new-lamassu-admin/src/pages/Cashout/helper.js index 466da650..8eb9a786 100644 --- a/new-lamassu-admin/src/pages/Cashout/helper.js +++ b/new-lamassu-admin/src/pages/Cashout/helper.js @@ -4,7 +4,8 @@ import TextInput from 'src/components/inputs/formik/TextInput' const DenominationsSchema = Yup.object().shape({ top: Yup.number().required('Required'), - bottom: Yup.number().required('Required') + bottom: Yup.number().required('Required'), + zeroConfLimit: Yup.number().required('Required') }) const getElements = (machines, { fiatCurrency } = {}) => { @@ -28,12 +29,20 @@ const getElements = (machines, { fiatCurrency } = {}) => { }, { name: 'bottom', - header: 'Cassette 2', + header: 'Cassette 2 (Bottom)', view: it => `${it} ${fiatCurrency}`, size: 'sm', stripe: true, width: 265, input: TextInput + }, + { + name: 'zeroConfLimit', + header: '0-conf Limit', + size: 'sm', + stripe: true, + width: 200, + input: TextInput } ] } diff --git a/new-lamassu-admin/src/pages/Cashout/index.js b/new-lamassu-admin/src/pages/Cashout/index.js new file mode 100644 index 00000000..e625c749 --- /dev/null +++ b/new-lamassu-admin/src/pages/Cashout/index.js @@ -0,0 +1,3 @@ +import Cashout from './Cashout' + +export default Cashout diff --git a/new-lamassu-admin/src/pages/Commissions.js b/new-lamassu-admin/src/pages/Commissions.js deleted file mode 100644 index 60c440ba..00000000 --- a/new-lamassu-admin/src/pages/Commissions.js +++ /dev/null @@ -1,179 +0,0 @@ -import React, { useState } from 'react' - -import { Link } from 'src/components/buttons' -import { TextInput } from 'src/components/inputs' -import { - Table, - TableHead, - TableRow, - TableHeader, - TableBody, - TableCell -} from 'src/components/table' -import { H1, H3, Info1, TL2 } from 'src/components/typography' - -const styles = {} -const EditRow = ({ data = {}, commitValues, setEditing }) => { - const [values, setValues] = React.useState(data) - - const handleChange = name => event => { - setValues({ ...values, [name]: event.target.value }) - } - - return ( - <> - - - - - - - - - - - - - - { - setEditing(false) - }}> - Cancel - - { - commitValues(values) - setEditing(false) - }}> - Save - - - - ) -} - -const ViewRow = ({ data, setEditing }) => ( - <> - - - {data.cashInCommission} - - {data.cashInCommission && ( - - % - - )} - - - - {data.cashOutCommission} - - {data.cashOutCommission && ( - - % - - )} - - - - {data.cashInFee} - - {data.cashOutCommission && ( - - EUR - - )} - - - - {data.minimumTx} - - {data.cashOutCommission && ( - - EUR - - )} - - - setEditing(true)}> - Edit - - - -) - -const Commissions = () => { - const [dataset, setDataset] = useState([{}]) - - const commitValues = (values, idx) => { - const clonedDs = dataset.slice() - clonedDs[idx] = Object.assign({}, clonedDs[idx], values) - setDataset(clonedDs) - } - - const EditableRow = () => - - return ( - <> -

Commissions

-

Default Setup

-
- - - - Cash-in - Cash-out - - Cash-in only - - - Edit - - - - Fixed Fee - Minimum Tx - - - - commitValues(value)} - EditRow={EditRow} - ViewRow={ViewRow} - /> - -
-
- - ) -} - -export default Commissions diff --git a/new-lamassu-admin/src/pages/Commissions.module.scss b/new-lamassu-admin/src/pages/Commissions.module.scss deleted file mode 100644 index 5537de93..00000000 --- a/new-lamassu-admin/src/pages/Commissions.module.scss +++ /dev/null @@ -1,30 +0,0 @@ -.multiRowHeader { - border-bottom-left-radius: 10px; - border-bottom-right-radius: 10px; - text-align: center; - background-color: white; //$placeholder-color; -} - -.tableWrapper { - width: 855px; -} - -.centerAlign { - text-align: center; -} - -.firstLink { - margin-right: 32px; -} - -.noMargin { - margin: 0; -} - -.suffix { - margin-left: 8px; -} - -.numberSmallInput { - width: 85px; -} diff --git a/new-lamassu-admin/src/pages/Commissions/Commissions.js b/new-lamassu-admin/src/pages/Commissions/Commissions.js new file mode 100644 index 00000000..140199e7 --- /dev/null +++ b/new-lamassu-admin/src/pages/Commissions/Commissions.js @@ -0,0 +1,96 @@ +import { useQuery, useMutation } from '@apollo/react-hooks' +import { gql } from 'apollo-boost' +import * as R from 'ramda' +import React from 'react' + +import { Table as EditableTable } from 'src/components/editableTable' +import Section from 'src/components/layout/Section' +import TitleSection from 'src/components/layout/TitleSection' +import { fromNamespace, toNamespace } from 'src/utils/config' + +import { + mainFields, + overrides, + schema, + OverridesSchema, + defaults, + overridesDefaults +} from './helper' + +const GET_DATA = gql` + query getData { + config + cryptoCurrencies { + code + display + } + machines { + name + deviceId + } + } +` + +const SAVE_CONFIG = gql` + mutation Save($config: JSONObject) { + saveConfig(config: $config) + } +` + +const Commissions = ({ name: SCREEN_KEY }) => { + const { data } = useQuery(GET_DATA) + const [saveConfig] = useMutation(SAVE_CONFIG, { + refetchQueries: () => ['getData'] + }) + + const config = data?.config && fromNamespace(SCREEN_KEY)(data.config) + + const commission = config && !R.isEmpty(config) ? config : defaults + + const save = it => { + const config = toNamespace(SCREEN_KEY)(it.commissions[0]) + return saveConfig({ variables: { config } }) + } + + const saveOverrides = it => { + const config = toNamespace(SCREEN_KEY)(it) + return saveConfig({ variables: { config } }) + } + + return ( + <> + +
+ +
+
+ +
+ + ) +} + +export default Commissions diff --git a/new-lamassu-admin/src/pages/Commissions/helper.js b/new-lamassu-admin/src/pages/Commissions/helper.js new file mode 100644 index 00000000..5b2bb2e9 --- /dev/null +++ b/new-lamassu-admin/src/pages/Commissions/helper.js @@ -0,0 +1,156 @@ +import * as R from 'ramda' +import * as Yup from 'yup' + +import { TextInput } from 'src/components/inputs/formik' +import Autocomplete from 'src/components/inputs/formik/Autocomplete.js' + +const getOverridesFields = getData => { + const getView = (data, code, compare) => it => { + if (!data) return '' + + return R.compose( + R.prop(code), + R.find(R.propEq(compare ?? 'code', it)) + )(data) + } + + const displayCodeArray = data => it => { + if (!it) return it + + return R.compose(R.join(', '), R.map(getView(data, 'code')))(it) + } + + const machineData = getData(['machines']) + const cryptoData = getData(['cryptoCurrencies']) + + return [ + { + name: 'machine', + width: 196, + size: 'sm', + view: getView(machineData, 'name', 'deviceId'), + input: Autocomplete, + inputProps: { + options: machineData, + valueProp: 'deviceId', + getLabel: R.path(['name']), + limit: null + } + }, + { + name: 'cryptoCurrencies', + width: 270, + size: 'sm', + view: displayCodeArray(cryptoData), + input: Autocomplete, + inputProps: { + options: cryptoData, + valueProp: 'code', + getLabel: R.path(['code']), + multiple: true + } + }, + { + name: 'cashIn', + display: 'Cash-in', + width: 140, + input: TextInput + }, + { + name: 'cashOut', + display: 'Cash-out', + width: 140, + input: TextInput + }, + { + name: 'fixedFee', + display: 'Fixed fee', + width: 140, + input: TextInput + }, + { + name: 'minimumTx', + display: 'Minimun Tx', + width: 140, + input: TextInput + } + ] +} + +const mainFields = auxData => [ + { + name: 'cashIn', + display: 'Cash-in', + width: 169, + size: 'lg', + input: TextInput + }, + { + name: 'cashOut', + display: 'Cash-out', + width: 169, + size: 'lg', + input: TextInput + }, + { + name: 'fixedFee', + display: 'Fixed fee', + width: 169, + size: 'lg', + input: TextInput + }, + { + name: 'minimumTx', + display: 'Minimun Tx', + width: 169, + size: 'lg', + input: TextInput + } +] + +const overrides = auxData => { + const getData = R.path(R.__, auxData) + + return getOverridesFields(getData) +} + +const schema = Yup.object().shape({ + cashIn: Yup.number().required('Required'), + cashOut: Yup.number().required('Required'), + fixedFee: Yup.number().required('Required'), + minimumTx: Yup.number().required('Required') +}) + +const OverridesSchema = Yup.object().shape({ + machine: Yup.string().required('Required'), + cryptoCurrencies: Yup.array().required('Required'), + cashIn: Yup.number().required('Required'), + cashOut: Yup.number().required('Required'), + fixedFee: Yup.number().required('Required'), + minimumTx: Yup.number().required('Required') +}) + +const defaults = { + cashIn: '', + cashOut: '', + fixedFee: '', + minimumTx: '' +} + +const overridesDefaults = { + machine: '', + cryptoCurrencies: [], + cashIn: '', + cashOut: '', + fixedFee: '', + minimumTx: '' +} + +export { + mainFields, + overrides, + schema, + OverridesSchema, + defaults, + overridesDefaults +} diff --git a/new-lamassu-admin/src/pages/Commissions/index.js b/new-lamassu-admin/src/pages/Commissions/index.js new file mode 100644 index 00000000..3e3f2b53 --- /dev/null +++ b/new-lamassu-admin/src/pages/Commissions/index.js @@ -0,0 +1,3 @@ +import Commissions from './Commissions' + +export default Commissions diff --git a/new-lamassu-admin/src/pages/Customers/Customers.js b/new-lamassu-admin/src/pages/Customers/Customers.js index 9f421323..4e0402df 100644 --- a/new-lamassu-admin/src/pages/Customers/Customers.js +++ b/new-lamassu-admin/src/pages/Customers/Customers.js @@ -1,8 +1,8 @@ import { useQuery } from '@apollo/react-hooks' import { gql } from 'apollo-boost' -import { useHistory } from 'react-router-dom' import * as R from 'ramda' import React from 'react' +import { useHistory } from 'react-router-dom' import CustomersList from './CustomersList' @@ -29,7 +29,7 @@ const Customers = () => { const handleCustomerClicked = customer => history.push(`/compliance/customer/${customer.id}`) - const customersData = R.sortWith([R.descend('lastActive')])( + const customersData = R.sortWith([R.descend(R.prop('lastActive'))])( R.path(['customers'])(customersResponse) ?? [] ) diff --git a/new-lamassu-admin/src/pages/Maintenance/Cashboxes.js b/new-lamassu-admin/src/pages/Maintenance/Cashboxes.js new file mode 100644 index 00000000..adfeea98 --- /dev/null +++ b/new-lamassu-admin/src/pages/Maintenance/Cashboxes.js @@ -0,0 +1,117 @@ +import { useQuery, useMutation } from '@apollo/react-hooks' +import { gql } from 'apollo-boost' +import React from 'react' +import * as Yup from 'yup' + +import { Table as EditableTable } from 'src/components/editableTable' +import TextInputFormik from 'src/components/inputs/formik/TextInput' +import TitleSection from 'src/components/layout/TitleSection' + +const ValidationSchema = Yup.object().shape({ + name: Yup.string().required('Required'), + cassette1: Yup.number() + .required('Required') + .integer() + .min(0), + cassette2: Yup.number() + .required('Required') + .integer() + .min(0) +}) + +const GET_MACHINES_AND_CONFIG = gql` + { + machines { + name + id: deviceId + cassette1 + cassette2 + } + config + } +` + +const RESET_CASHOUT_BILLS = gql` + mutation MachineAction( + $deviceId: ID! + $action: MachineAction! + $cassette1: Int! + $cassette2: Int! + ) { + machineAction( + deviceId: $deviceId + action: $action + cassette1: $cassette1 + cassette2: $cassette2 + ) { + deviceId + cassette1 + cassette2 + } + } +` + +const Cashboxes = () => { + const { data } = useQuery(GET_MACHINES_AND_CONFIG) + + const [resetCashOut] = useMutation(RESET_CASHOUT_BILLS, { + onError: ({ graphQLErrors, message }) => { + const errorMessage = graphQLErrors[0] ? graphQLErrors[0].message : message + // TODO: this should not be final + alert(JSON.stringify(errorMessage)) + } + }) + + const onSave = (...[, { id, cassette1, cassette2 }]) => { + return resetCashOut({ + variables: { + action: 'resetCashOutBills', + deviceId: id, + cassette1, + cassette2 + } + }) + } + + const elements = [ + { + name: 'name', + header: 'Machine', + width: 254, + textAlign: 'left', + view: name => <>{name}, + input: ({ field: { value: name } }) => <>{name} + }, + { + name: 'cassette1', + header: 'Cash-out 1', + width: 265, + textAlign: 'left', + input: TextInputFormik + }, + { + name: 'cassette2', + header: 'Cash-out 2', + width: 265, + textAlign: 'left', + input: TextInputFormik + } + ] + + return ( + <> + + + + + ) +} + +export default Cashboxes diff --git a/new-lamassu-admin/src/pages/maintenance/MachineDetailsCard.js b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js similarity index 100% rename from new-lamassu-admin/src/pages/maintenance/MachineDetailsCard.js rename to new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js index 510c33fe..1e39947e 100644 --- a/new-lamassu-admin/src/pages/maintenance/MachineDetailsCard.js +++ b/new-lamassu-admin/src/pages/Maintenance/MachineDetailsCard.js @@ -1,16 +1,16 @@ +import { useMutation } from '@apollo/react-hooks' +import { Dialog, DialogContent } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' +import { gql } from 'apollo-boost' import classnames from 'classnames' import moment from 'moment' import React, { useState } from 'react' -import { useMutation } from '@apollo/react-hooks' -import { gql } from 'apollo-boost' -import { Dialog, DialogContent } from '@material-ui/core' import { H4 } from 'src/components/typography' -import ActionButton from '../../components/buttons/ActionButton' import { DialogTitle, ConfirmDialog } from '../../components/ConfirmDialog' import { Status } from '../../components/Status' +import ActionButton from '../../components/buttons/ActionButton' import { ReactComponent as DownloadReversedIcon } from '../../styling/icons/button/download/white.svg' import { ReactComponent as DownloadIcon } from '../../styling/icons/button/download/zodiac.svg' import { ReactComponent as RebootReversedIcon } from '../../styling/icons/button/reboot/white.svg' @@ -19,11 +19,11 @@ import { ReactComponent as ShutdownReversedIcon } from '../../styling/icons/butt import { ReactComponent as ShutdownIcon } from '../../styling/icons/button/shut down/zodiac.svg' import { ReactComponent as UnpairReversedIcon } from '../../styling/icons/button/unpair/white.svg' import { ReactComponent as UnpairIcon } from '../../styling/icons/button/unpair/zodiac.svg' +import { zircon } from '../../styling/variables' import { detailsRowStyles, labelStyles } from '../Transactions/Transactions.styles' -import { zircon } from '../../styling/variables' const MACHINE_ACTION = gql` mutation MachineAction($deviceId: ID!, $action: MachineAction!) { diff --git a/new-lamassu-admin/src/pages/maintenance/MachineStatus.js b/new-lamassu-admin/src/pages/Maintenance/MachineStatus.js similarity index 100% rename from new-lamassu-admin/src/pages/maintenance/MachineStatus.js rename to new-lamassu-admin/src/pages/Maintenance/MachineStatus.js diff --git a/new-lamassu-admin/src/pages/Notifications/components/EditableNumber.js b/new-lamassu-admin/src/pages/Notifications/components/EditableNumber.js index 56fde906..51369e14 100644 --- a/new-lamassu-admin/src/pages/Notifications/components/EditableNumber.js +++ b/new-lamassu-admin/src/pages/Notifications/components/EditableNumber.js @@ -42,7 +42,6 @@ const EditableNumber = ({ name={name} component={TextInput} textAlign="right" - type="text" width={width} /> )} diff --git a/new-lamassu-admin/src/pages/Notifications/components/SingleFieldEditableNumber.js b/new-lamassu-admin/src/pages/Notifications/components/SingleFieldEditableNumber.js index 126d8e9e..52a0e866 100644 --- a/new-lamassu-admin/src/pages/Notifications/components/SingleFieldEditableNumber.js +++ b/new-lamassu-admin/src/pages/Notifications/components/SingleFieldEditableNumber.js @@ -36,7 +36,7 @@ const SingleFieldEditableNumber = ({ enableReinitialize initialValues={{ [name]: (data && data[name]) ?? '' }} validationSchema={schema} - onSubmit={it => save(section, it)} + onSubmit={it => save(section, schema.cast(it))} onReset={() => { setEditing(name, false) }}> diff --git a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceAlerts.js b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceAlerts.js index f6d5cd92..769ff9fd 100644 --- a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceAlerts.js +++ b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceAlerts.js @@ -42,7 +42,7 @@ const FiatBalance = ({ section }) => { fiatBalanceCassette2: data?.fiatBalanceCassette2 ?? '' }} validationSchema={schema} - onSubmit={it => save(section, it)} + onSubmit={it => save(section, schema.cast(it))} onReset={() => { setEditing(NAME, false) }}> diff --git a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js index 0e7a8f56..2e6484e9 100644 --- a/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js +++ b/new-lamassu-admin/src/pages/Notifications/sections/FiatBalanceOverrides.js @@ -23,7 +23,7 @@ const FiatBalanceOverrides = ({ section }) => { const overridenMachines = R.map(override => override.machine, setupValues) const suggestionFilter = R.filter( - it => !R.contains(it.code, overridenMachines) + it => !R.contains(it.deviceId, overridenMachines) ) const suggestions = suggestionFilter(machines) @@ -50,17 +50,21 @@ const FiatBalanceOverrides = ({ section }) => { .required() }) + const viewMachine = it => + R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines) + const elements = [ { name: MACHINE_KEY, width: 238, size: 'sm', - view: R.path(['name']), + view: viewMachine, input: Autocomplete, inputProps: { options: it => R.concat(suggestions, findSuggestion(it)), limit: null, - getOptionSelected: R.eqProps('display') + valueProp: 'deviceId', + getLabel: R.path(['name']) } }, { @@ -90,7 +94,7 @@ const FiatBalanceOverrides = ({ section }) => { enableDelete enableEdit enableCreate - save={it => save(section, it)} + save={it => save(section, validationSchema.cast(it))} initialValues={initialValues} validationSchema={validationSchema} forceDisable={isDisabled(NAME) || !machines} diff --git a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js index cf2d8508..0736dbf8 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/CoinATMRadar/CoinATMRadar.js @@ -1,6 +1,7 @@ import { useQuery, useMutation } from '@apollo/react-hooks' import { makeStyles } from '@material-ui/core/styles' import { gql } from 'apollo-boost' +import * as R from 'ramda' import React, { useState, memo } from 'react' import Popper from 'src/components/Popper' @@ -9,6 +10,7 @@ import { Button } from 'src/components/buttons' import { Switch } from 'src/components/inputs' import { H4, P, Label2 } from 'src/components/typography' import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg' +import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import { mainStyles } from './CoinATMRadar.styles' @@ -48,17 +50,25 @@ const CoinATMRadar = memo(() => { // TODO: treat errors on useMutation and useQuery const [saveConfig] = useMutation(SAVE_CONFIG, { onCompleted: configResponse => - setCoinAtmRadarConfig(configResponse.saveConfig.coinAtmRadar) + setCoinAtmRadarConfig( + fromNamespace(namespaces.COIN_ATM_RADAR, configResponse.saveConfig) + ) }) useQuery(GET_CONFIG, { onCompleted: configResponse => { - setCoinAtmRadarConfig( - configResponse?.config?.coinAtmRadar ?? initialValues + const response = fromNamespace( + namespaces.COIN_ATM_RADAR, + configResponse.config ) + const values = R.merge(initialValues, response) + setCoinAtmRadarConfig(values) } }) - const save = it => saveConfig({ variables: { config: { coinAtmRadar: it } } }) + const save = it => + saveConfig({ + variables: { config: toNamespace(namespaces.COIN_ATM_RADAR, it) } + }) const handleOpenHelpPopper = event => { setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget) diff --git a/new-lamassu-admin/src/pages/OperatorInfo/ContactInfo.js b/new-lamassu-admin/src/pages/OperatorInfo/ContactInfo.js index 87dd0a4f..8b1adfe3 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/ContactInfo.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/ContactInfo.js @@ -1,30 +1,37 @@ -import React, { useState } from 'react' -import classnames from 'classnames' -import * as R from 'ramda' -import * as Yup from 'yup' -import { gql } from 'apollo-boost' -import { Form, Formik, Field as FormikField } from 'formik' -import { makeStyles } from '@material-ui/core' import { useQuery, useMutation } from '@apollo/react-hooks' +import { makeStyles } from '@material-ui/core' +import { gql } from 'apollo-boost' +import classnames from 'classnames' +import { Form, Formik, Field as FormikField } from 'formik' +import * as R from 'ramda' +import React, { useState } from 'react' +import * as Yup from 'yup' -import { Info2, Info3, Label1 } from 'src/components/typography' -import TextInputFormik from 'src/components/inputs/formik/TextInput' -import RadioGroupFormik from 'src/components/inputs/formik/RadioGroup' -import { - PhoneNumberInputFormik, - maskValue, - mask -} from 'src/components/inputs/formik/PhoneNumberInput' -import { Link } from 'src/components/buttons' import ErrorMessage from 'src/components/ErrorMessage' +import { Link } from 'src/components/buttons' +import RadioGroupFormik from 'src/components/inputs/formik/RadioGroup' +import TextInputFormik from 'src/components/inputs/formik/TextInput' +import { Info2, Info3, Label1, Label3 } from 'src/components/typography' import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg' import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg' +import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import { styles as globalStyles, contactInfoStyles } from './OperatorInfo.styles' +const validationSchema = Yup.object().shape({ + active: Yup.boolean().required(), + name: Yup.string().required(), + phone: Yup.string().required(), + email: Yup.string() + .email('Please enter a valid email address') + .required(), + website: Yup.string().required(), + companyNumber: Yup.string().required() +}) + const fieldStyles = { field: { position: 'relative', @@ -38,12 +45,13 @@ const fieldStyles = { '& > p:first-child': { height: 16, lineHeight: '16px', - paddingLeft: 3, + transform: 'scale(0.75)', + transformOrigin: 'left', + paddingLeft: 0, margin: [[0, 0, 5, 0]] }, '& > p:last-child': { - margin: 0, - paddingLeft: 4 + margin: 0 } } } @@ -62,7 +70,7 @@ const Field = ({ editing, field, displayValue, ...props }) => {
{!editing && ( <> - {field.label} + {field.label} {displayValue(field.value)} )} @@ -93,9 +101,6 @@ const SAVE_CONFIG = gql` } ` -const INFO_CARD_ENABLED = 'On' -const INFO_CARD_DISABLED = 'Off' - const styles = R.merge(globalStyles, contactInfoStyles) const contactUseStyles = makeStyles(styles) @@ -106,8 +111,7 @@ const ContactInfo = () => { const [error, setError] = useState(null) const [saveConfig] = useMutation(SAVE_CONFIG, { onCompleted: data => { - const { operatorInfo } = data.saveConfig - setInfo(operatorInfo) + setInfo(fromNamespace(namespaces.OPERATOR_INFO, data.saveConfig)) setEditing(false) }, onError: e => setError(e) @@ -115,13 +119,14 @@ const ContactInfo = () => { useQuery(GET_CONFIG, { onCompleted: data => { - const { operatorInfo } = data.config - setInfo(operatorInfo ?? {}) + setInfo(fromNamespace(namespaces.OPERATOR_INFO, data.config)) } }) const save = it => { - return saveConfig({ variables: { config: { operatorInfo: it } } }) + return saveConfig({ + variables: { config: toNamespace(namespaces.OPERATOR_INFO, it) } + }) } const classes = contactUseStyles() @@ -130,45 +135,39 @@ const ContactInfo = () => { const fields = [ { - name: 'infoCardEnabled', + name: 'active', label: 'Info Card Enabled', - value: info.infoCardEnabled ?? INFO_CARD_DISABLED, - type: 'select', + value: String(info.active), component: RadioGroupFormik }, { - name: 'fullName', + name: 'name', label: 'Full name', - value: info.fullName ?? '', - type: 'text', + value: info.name ?? '', component: TextInputFormik }, { - name: 'phoneNumber', + name: 'phone', label: 'Phone number', - value: maskValue(info.phoneNumber) ?? '', - type: 'text', - component: PhoneNumberInputFormik + value: info.phone ?? '', + component: TextInputFormik }, { name: 'email', label: 'Email', value: info.email ?? '', - type: 'text', component: TextInputFormik }, { name: 'website', label: 'Website', value: info.website ?? '', - type: 'text', component: TextInputFormik }, { name: 'companyNumber', label: 'Company number', value: info.companyNumber ?? '', - type: 'text', component: TextInputFormik } ] @@ -180,33 +179,13 @@ const ContactInfo = () => { const form = { initialValues: { - infoCardEnabled: findValue('infoCardEnabled'), - fullName: findValue('fullName'), - phoneNumber: info.phoneNumber ?? '', + active: findValue('active'), + name: findValue('name'), + phone: info.phone ?? '', email: findValue('email'), website: findValue('website'), companyNumber: findValue('companyNumber') - }, - validationSchema: Yup.object().shape({ - fullName: Yup.string() - .max(100, 'Too long') - .required(), - phoneNumber: Yup.string() - .matches(mask, { excludeEmptyString: true }) - .max(100, 'Too long') - .required(), - email: Yup.string() - .email('Please enter a valid email address') - .max(100, 'Too long') - .required(), - website: Yup.string() - .url('Please enter a valid url') - .max(100, 'Too long') - .required(), - companyNumber: Yup.string() - .max(30, 'Too long') - .required() - }) + } } return ( @@ -225,21 +204,21 @@ const ContactInfo = () => { save(values)} - onReset={(values, bag) => { + validationSchema={validationSchema} + onSubmit={values => save(validationSchema.cast(values))} + onReset={() => { setEditing(false) setError(null) }}>
(it === 'true' ? 'On' : 'Off')} options={[ - { label: 'On', value: INFO_CARD_ENABLED }, - { label: 'Off', value: INFO_CARD_DISABLED } + { display: 'On', code: 'true' }, + { display: 'Off', code: 'false' } ]} className={classes.radioButtons} resetError={() => setError(null)} @@ -247,13 +226,13 @@ const ContactInfo = () => {
setError(null)} /> setError(null)} diff --git a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js b/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js index e38be6c7..998f0c0f 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/OperatorInfo.js @@ -1,27 +1,26 @@ import { makeStyles } from '@material-ui/core' -import * as R from 'ramda' +import Grid from '@material-ui/core/Grid' import React, { useState } from 'react' -import Title from 'src/components/Title' import Sidebar from 'src/components/layout/Sidebar' - -import logsStyles from '../Logs.styles' +import TitleSection from 'src/components/layout/TitleSection' import CoinAtmRadar from './CoinATMRadar' import ContactInfo from './ContactInfo' import ReceiptPrinting from './ReceiptPrinting' import TermsConditions from './TermsConditions' -const localStyles = { - contentWrapper: { - width: '100%', +const styles = { + grid: { + flex: 1, + height: '100%' + }, + content: { marginLeft: 48, paddingTop: 15 } } -const styles = R.merge(logsStyles, localStyles) - const useStyles = makeStyles(styles) const CONTACT_INFORMATION = 'Contact information' @@ -39,25 +38,21 @@ const OperatorInfo = () => { return ( <> -
-
- Operator information -
-
-
+ + it} onClick={it => setSelected(it)} /> -
+
{isSelected(CONTACT_INFORMATION) && } {isSelected(RECEIPT) && } {isSelected(TERMS_CONDITIONS) && } {isSelected(COIN_ATM_RADAR) && }
-
+
) } diff --git a/new-lamassu-admin/src/pages/OperatorInfo/ReceiptPrinting/ReceiptPrinting.js b/new-lamassu-admin/src/pages/OperatorInfo/ReceiptPrinting/ReceiptPrinting.js index dc5e8565..556637ee 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/ReceiptPrinting/ReceiptPrinting.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/ReceiptPrinting/ReceiptPrinting.js @@ -1,10 +1,12 @@ // import { makeStyles } from '@material-ui/core/styles' import { useQuery, useMutation } from '@apollo/react-hooks' import { gql } from 'apollo-boost' +import * as R from 'ramda' import React, { useState, memo } from 'react' import { BooleanPropertiesTable } from 'src/components/booleanPropertiesTable' import { EditableProperty } from 'src/components/editableProperty' +import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' // import { ActionButton } from 'src/components/buttons' // import { ReactComponent as UploadIcon } from 'src/styling/icons/button/upload/zodiac.svg' // import { ReactComponent as UploadIconInverse } from 'src/styling/icons/button/upload/white.svg' @@ -64,21 +66,28 @@ const ReceiptPrinting = memo(() => { // TODO: treat errors on useMutation and useQuery const [saveConfig] = useMutation(SAVE_CONFIG, { - onCompleted: configResponse => - setReceiptPrintingConfig(configResponse.saveConfig.receiptPrinting) + onCompleted: configResponse => { + console.log(configResponse.saveConfig) + return setReceiptPrintingConfig( + fromNamespace(namespaces.RECEIPT, configResponse.saveConfig) + ) + } }) useQuery(GET_CONFIG, { onCompleted: configResponse => { - setReceiptPrintingConfig( - configResponse?.config?.receiptPrinting ?? initialValues - ) + const response = fromNamespace(namespaces.RECEIPT, configResponse.config) + const values = R.merge(initialValues, response) + setReceiptPrintingConfig(values) } }) const save = it => - saveConfig({ variables: { config: { receiptPrinting: it } } }) + saveConfig({ + variables: { config: toNamespace(namespaces.RECEIPT, it) } + }) if (!receiptPrintingConfig) return null + console.log(receiptPrintingConfig) return ( <> @@ -90,7 +99,12 @@ const ReceiptPrinting = memo(() => { code={receiptPrintingConfig.active} save={it => saveConfig({ - variables: { config: { receiptPrinting: { active: it } } } + variables: { + config: toNamespace( + namespaces.RECEIPT, + R.merge(receiptPrintingConfig, { active: it }) + ) + } }) } /> diff --git a/new-lamassu-admin/src/pages/OperatorInfo/TermsConditions.js b/new-lamassu-admin/src/pages/OperatorInfo/TermsConditions.js index a15e3724..ccfa0e52 100644 --- a/new-lamassu-admin/src/pages/OperatorInfo/TermsConditions.js +++ b/new-lamassu-admin/src/pages/OperatorInfo/TermsConditions.js @@ -1,17 +1,18 @@ -import React, { useState } from 'react' -import classnames from 'classnames' -import * as R from 'ramda' -import * as Yup from 'yup' -import { Form, Formik, Field } from 'formik' -import { gql } from 'apollo-boost' -import { makeStyles } from '@material-ui/core' import { useQuery, useMutation } from '@apollo/react-hooks' +import { makeStyles } from '@material-ui/core' +import { gql } from 'apollo-boost' +import classnames from 'classnames' +import { Form, Formik, Field } from 'formik' +import * as R from 'ramda' +import React, { useState } from 'react' +import * as Yup from 'yup' -import { Info2, Label2 } from 'src/components/typography' +import ErrorMessage from 'src/components/ErrorMessage' +import { Button } from 'src/components/buttons' import { Switch } from 'src/components/inputs' import TextInputFormik from 'src/components/inputs/formik/TextInput' -import { Button } from 'src/components/buttons' -import ErrorMessage from 'src/components/ErrorMessage' +import { Info2, Label2 } from 'src/components/typography' +import { fromNamespace, toNamespace, namespaces } from 'src/utils/config' import { styles as globalStyles, @@ -40,9 +41,12 @@ const TermsConditions = () => { const [error, setError] = useState(null) const [saveConfig] = useMutation(SAVE_CONFIG, { onCompleted: data => { - const { termsAndConditions } = data.saveConfig + const termsAndConditions = fromNamespace( + namespaces.TERMS_CONDITIONS, + data.saveConfig + ) setFormData(termsAndConditions) - setShowOnScreen(termsAndConditions.show) + setShowOnScreen(termsAndConditions.active) setError(null) }, onError: e => setError(e) @@ -52,36 +56,39 @@ const TermsConditions = () => { useQuery(GET_CONFIG, { onCompleted: data => { - const { termsAndConditions } = data.config + const termsAndConditions = fromNamespace( + namespaces.TERMS_CONDITIONS, + data.config + ) setFormData(termsAndConditions ?? {}) - setShowOnScreen(termsAndConditions?.show ?? false) + setShowOnScreen(termsAndConditions?.active ?? false) } }) const save = it => { setError(null) return saveConfig({ - variables: { config: { termsAndConditions: it } } + variables: { config: toNamespace(namespaces.TERMS_CONDITIONS, it) } }) } const handleEnable = () => { const s = !showOnScreen - save({ show: s }) + save({ active: s }) } if (!formData) return null const fields = [ { - name: 'screenTitle', + name: 'title', label: 'Screen title', - value: formData.screenTitle ?? '' + value: formData.title ?? '' }, { - name: 'textContent', + name: 'text', label: 'Text content', - value: formData.textContent ?? '', + value: formData.text ?? '', multiline: true }, { @@ -102,14 +109,14 @@ const TermsConditions = () => { const findValue = name => findField(name).value const initialValues = { - screenTitle: findValue('screenTitle'), - textContent: findValue('textContent'), + title: findValue('title'), + text: findValue('text'), acceptButtonText: findValue('acceptButtonText'), cancelButtonText: findValue('cancelButtonText') } const validationSchema = Yup.object().shape({ - screenTitle: Yup.string().max(50, 'Too long'), + title: Yup.string().max(50, 'Too long'), acceptButtonText: Yup.string().max(15, 'Too long'), cancelButtonText: Yup.string().max(15, 'Too long') }) diff --git a/new-lamassu-admin/src/pages/Services/Services.js b/new-lamassu-admin/src/pages/Services/Services.js index 62c5af9b..0bc63367 100644 --- a/new-lamassu-admin/src/pages/Services/Services.js +++ b/new-lamassu-admin/src/pages/Services/Services.js @@ -19,8 +19,8 @@ const GET_INFO = gql` ` const SAVE_ACCOUNT = gql` - mutation Save($account: JSONObject) { - saveAccount(account: $account) + mutation Save($accounts: JSONObject) { + saveAccounts(accounts: $accounts) } ` @@ -34,7 +34,7 @@ const styles = { const useStyles = makeStyles(styles) -const Services = ({ key: SCREEN_KEY }) => { +const Services = () => { const [editingSchema, setEditingSchema] = useState(null) const { data } = useQuery(GET_INFO) @@ -45,13 +45,11 @@ const Services = ({ key: SCREEN_KEY }) => { const classes = useStyles() - const accounts = data?.accounts ?? [] - - const getValue = code => R.find(R.propEq('code', code))(accounts) + const accounts = data?.accounts ?? {} const getItems = (code, elements) => { const faceElements = R.filter(R.prop('face'))(elements) - const values = getValue(code) || {} + const values = accounts[code] || {} return R.map(({ display, code, long }) => ({ label: display, value: long ? formatLong(values[code]) : values[code] @@ -81,12 +79,12 @@ const Services = ({ key: SCREEN_KEY }) => { saveAccount({ - variables: { account: { code: editingSchema.code, ...it } } + variables: { accounts: { [editingSchema.code]: it } } }) } elements={editingSchema.elements} validationSchema={editingSchema.validationSchema} - value={getValue(editingSchema.code)} + value={accounts[editingSchema.code]} /> )} diff --git a/new-lamassu-admin/src/pages/Transactions/DetailsCard.js b/new-lamassu-admin/src/pages/Transactions/DetailsCard.js index 0ec9694d..c19b9b20 100644 --- a/new-lamassu-admin/src/pages/Transactions/DetailsCard.js +++ b/new-lamassu-admin/src/pages/Transactions/DetailsCard.js @@ -39,10 +39,7 @@ const DetailsRow = ({ it: tx, ...props }) => { 5 ) const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2) - const commission = - tx.txClass === 'cashOut' - ? fiat * commissionPercentage - : fiat * commissionPercentage + Number.parseFloat(tx.fee) + const commission = fiat * commissionPercentage const customer = tx.customerIdCardData && { name: `${onlyFirstToUpper( tx.customerIdCardData.firstName @@ -163,6 +160,12 @@ const DetailsRow = ({ it: tx, ...props }) => { 100} %)`}
+ {tx.txClass === 'cashIn' && ( +
+ +
{Number.parseFloat(tx.cashInFee)}
+
+ )}
diff --git a/new-lamassu-admin/src/pages/Transactions/Transactions.js b/new-lamassu-admin/src/pages/Transactions/Transactions.js index 50e84533..bed3fa4b 100644 --- a/new-lamassu-admin/src/pages/Transactions/Transactions.js +++ b/new-lamassu-admin/src/pages/Transactions/Transactions.js @@ -33,7 +33,7 @@ const GET_TRANSACTIONS = gql` machineName deviceId fiat - fee + cashInFee fiatCode cryptoAtoms cryptoCode diff --git a/new-lamassu-admin/src/pages/Triggers/NewTriggerWizard.js b/new-lamassu-admin/src/pages/Triggers/NewTriggerWizard.js deleted file mode 100644 index e169f3bc..00000000 --- a/new-lamassu-admin/src/pages/Triggers/NewTriggerWizard.js +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useState } from 'react' -import { useQuery } from '@apollo/react-hooks' -import { gql } from 'apollo-boost' -import { makeStyles } from '@material-ui/core' - -import { Wizard } from 'src/components/wizard' -import { H2, P } from 'src/components/typography' -import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg' -import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg' -import Popper from 'src/components/Popper' - -import SelectTriggerDirection from './SelectTriggerDirection' -import SelectTriggerType from './SelectTriggerType' -import SelectTriggerRequirements from './SelectTriggerRequirements' -import { mainStyles } from './Triggers.styles' - -const useStyles = makeStyles(mainStyles) - -const GET_CONFIG = gql` - { - config - } -` - -const NewTriggerWizard = ({ close, finish }) => { - const { data: configResponse } = useQuery(GET_CONFIG) - const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null) - - const classes = useStyles() - - const fiatCurrencyCode = configResponse?.config?.['locale_fiatCurrency']?.code - - const handleOpenHelpPopper = event => { - setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget) - } - - const handleCloseHelpPopper = () => { - setHelpPopperAnchorEl(null) - } - - const helpPopperOpen = Boolean(helpPopperAnchorEl) - - const wizardHeader = ( -
-

New Compliance Trigger

-
- -
-
- -
-
- ) - - return ( - - - - - - ) -} - -export { NewTriggerWizard } diff --git a/new-lamassu-admin/src/pages/Triggers/SelectTriggerDirection.js b/new-lamassu-admin/src/pages/Triggers/SelectTriggerDirection.js deleted file mode 100644 index 8156543c..00000000 --- a/new-lamassu-admin/src/pages/Triggers/SelectTriggerDirection.js +++ /dev/null @@ -1,77 +0,0 @@ -import { makeStyles } from '@material-ui/core' -import classnames from 'classnames' -import React, { useState } from 'react' - -import Popper from 'src/components/Popper' -import { RadioGroup } from 'src/components/inputs' -import { H4, P } from 'src/components/typography' -import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg' - -import { mainStyles } from './Triggers.styles' - -const useStyles = makeStyles(mainStyles) - -const SelectTriggerDirection = () => { - const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null) - const [radioGroupValue, setRadioGroupValue] = useState('both') - - const classes = useStyles() - - const handleOpenHelpPopper = event => { - setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget) - } - - const handleCloseHelpPopper = () => { - setHelpPopperAnchorEl(null) - } - - const handleRadioButtons = newValue => { - setRadioGroupValue(newValue) - } - - const helpPopperOpen = Boolean(helpPopperAnchorEl) - - const radioButtonOptions = [ - { display: 'Both', code: 'both' }, - { display: 'Only cash-in', code: 'cash-in' }, - { display: 'Only cash-out', code: 'cash-out' } - ] - - return ( -
-
-

In which type of transactions will it trigger?

-
- -
-
-
- handleRadioButtons(event.target.value)} - className={classnames( - classes.radioButtons, - classes.stepOneRadioButtons - )} - /> -
-
- ) -} -export default SelectTriggerDirection diff --git a/new-lamassu-admin/src/pages/Triggers/SelectTriggerRequirements.js b/new-lamassu-admin/src/pages/Triggers/SelectTriggerRequirements.js deleted file mode 100644 index f9d222b2..00000000 --- a/new-lamassu-admin/src/pages/Triggers/SelectTriggerRequirements.js +++ /dev/null @@ -1,141 +0,0 @@ -import { makeStyles } from '@material-ui/core' -import classnames from 'classnames' -import React, { useState } from 'react' - -import Popper from 'src/components/Popper' -import { RadioGroup } from 'src/components/inputs' -import { H4, P } from 'src/components/typography' -import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg' - -import { mainStyles } from './Triggers.styles' - -const useStyles = makeStyles(mainStyles) - -const SelectTriggerRequirements = () => { - const [ - requirementHelpPopperAnchorEl, - setRequirementHelpPopperAnchorEl - ] = useState(null) - const [typeHelpPopperAnchorEl, setTypeHelpPopperAnchorEl] = useState(null) - const [requirementRadioGroupValue, setRequirementRadioGroupValue] = useState( - 'sms' - ) - const [typeRadioGroupValue, setTypeRadioGroupValue] = useState('automatic') - - const classes = useStyles() - - const handleOpenRequirementHelpPopper = event => { - setRequirementHelpPopperAnchorEl( - requirementHelpPopperAnchorEl ? null : event.currentTarget - ) - } - - const handleOpenTypeHelpPopper = event => { - setTypeHelpPopperAnchorEl( - typeHelpPopperAnchorEl ? null : event.currentTarget - ) - } - - const handleCloseRequirementHelpPopper = () => { - setRequirementHelpPopperAnchorEl(null) - } - - const handleCloseTypeHelpPopper = () => { - setTypeHelpPopperAnchorEl(null) - } - - const handleRequirementRadioButtons = newValue => { - setRequirementRadioGroupValue(newValue) - } - - const handleTypeRadioButtons = newValue => { - setTypeRadioGroupValue(newValue) - } - - const requirementHelpPopperOpen = Boolean(requirementHelpPopperAnchorEl) - const typeHelpPopperOpen = Boolean(typeHelpPopperAnchorEl) - - const requirementRadioButtonOptions = [ - { display: 'SMS verification', code: 'sms' }, - { display: 'ID card image', code: 'id-card' }, - { display: 'ID data', code: 'id-data' }, - { display: 'Customer camera', code: 'camera' }, - { display: 'Sanctions', code: 'sanctions' }, - { display: 'Super user', code: 'super-user' }, - { display: 'Suspend', code: 'suspend' }, - { display: 'Block', code: 'block' } - ] - - const typeRadioButtonOptions = [ - { display: 'Fully automatic', code: 'automatic' }, - { display: 'Semi automatic', code: 'semi-automatic' }, - { display: 'Manual', code: 'manual' } - ] - - return ( -
-
-

Choose a requirement

-
- -
-
- handleRequirementRadioButtons(event.target.value)} - className={classnames( - classes.radioButtons, - classes.stepThreeRadioButtons - )} - /> -
-

Choose trigger type

-
- -
-
- handleTypeRadioButtons(event.target.value)} - className={classnames( - classes.radioButtons, - classes.stepThreeRadioButtons - )} - /> -
- ) -} - -export default SelectTriggerRequirements diff --git a/new-lamassu-admin/src/pages/Triggers/SelectTriggerType.js b/new-lamassu-admin/src/pages/Triggers/SelectTriggerType.js deleted file mode 100644 index df5e30b4..00000000 --- a/new-lamassu-admin/src/pages/Triggers/SelectTriggerType.js +++ /dev/null @@ -1,104 +0,0 @@ -import { makeStyles } from '@material-ui/core' -import classnames from 'classnames' -import React, { useState } from 'react' - -import Popper from 'src/components/Popper' -import { RadioGroup, TextInput } from 'src/components/inputs' -import { H4, TL1, P } from 'src/components/typography' -import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg' - -import { mainStyles } from './Triggers.styles' - -const useStyles = makeStyles(mainStyles) - -const SelectTriggerType = ({ fiatCurrencyCode }) => { - const [helpPopperAnchorEl, setHelpPopperAnchorEl] = useState(null) - const [radioGroupValue, setRadioGroupValue] = useState('amount') - const [thresholdValue, setThresholdValue] = useState('') - const [thresholdError, setThresholdError] = useState(false) - - const classes = useStyles() - - const handleOpenHelpPopper = event => { - setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget) - } - - const handleCloseHelpPopper = () => { - setHelpPopperAnchorEl(null) - } - - const handleRadioButtons = newValue => { - setRadioGroupValue(newValue) - } - - const validateThresholdInputIsPositiveInteger = value => { - if ( - (parseFloat(value) === value >>> 0 && !value.includes('.')) || - value === '' - ) { - setThresholdValue(value) - setThresholdError(value === '') - } - } - - const helpPopperOpen = Boolean(helpPopperAnchorEl) - - const radioButtonOptions = [ - { display: 'Transaction amount', code: 'amount' }, - { display: 'Transaction velocity', code: 'velocity' }, - { display: 'Transaction volume', code: 'volume' }, - { display: 'Consecutive days', code: 'days' } - ] - - return ( -
-
-

Choose trigger type

-
- -
-
-
- handleRadioButtons(event.target.value)} - className={classnames( - classes.radioButtons, - classes.stepTwoRadioButtons - )} - /> -
-

Threshold

-
- - validateThresholdInputIsPositiveInteger(event.target.value) - } - error={thresholdError} - size="lg" - value={thresholdValue} - /> - {fiatCurrencyCode} -
-
- ) -} - -export default SelectTriggerType diff --git a/new-lamassu-admin/src/pages/Triggers/Triggers.js b/new-lamassu-admin/src/pages/Triggers/Triggers.js index a5067353..1ebfd830 100644 --- a/new-lamassu-admin/src/pages/Triggers/Triggers.js +++ b/new-lamassu-admin/src/pages/Triggers/Triggers.js @@ -1,5 +1,9 @@ +import { useQuery, useMutation } from '@apollo/react-hooks' +import { makeStyles } from '@material-ui/core' +import { gql } from 'apollo-boost' +import * as R from 'ramda' import React, { useState } from 'react' -import { makeStyles, Modal, Paper } from '@material-ui/core' +import { v4 } from 'uuid' import Title from 'src/components/Title' import { FeatureButton, Link } from 'src/components/buttons' @@ -7,35 +11,50 @@ import { Table as EditableTable } from 'src/components/editableTable' import { ReactComponent as ConfigureInverseIcon } from 'src/styling/icons/button/configure/white.svg' import { ReactComponent as Configure } from 'src/styling/icons/button/configure/zodiac.svg' -import { NewTriggerWizard } from './NewTriggerWizard' import { mainStyles } from './Triggers.styles' +import Wizard from './Wizard' +import { Schema, elements } from './helper' const useStyles = makeStyles(mainStyles) -const sizes = { - triggerType: 236, - requirement: 293, - threshold: 231, - cashDirection: 296 -} +const SAVE_CONFIG = gql` + mutation Save($config: JSONObject) { + saveConfig(config: $config) + } +` + +const GET_INFO = gql` + query getData { + config + } +` const Triggers = () => { - const [wizardModalOpen, setWizardModalOpen] = useState(false) + const [wizard, setWizard] = useState(false) + const [error, setError] = useState(false) + + const { data } = useQuery(GET_INFO) + const triggers = data?.config?.triggers ?? [] + + const [saveConfig] = useMutation(SAVE_CONFIG, { + onCompleted: () => setWizard(false), + onError: () => setError(true), + refetchQueries: () => ['getData'] + }) + + const add = rawConfig => { + const toSave = R.concat([{ id: v4(), ...rawConfig }])(triggers) + setError(false) + return saveConfig({ variables: { config: { triggers: toSave } } }) + } + + const save = config => { + setError(false) + return saveConfig({ variables: { config } }) + } const classes = useStyles() - const handleOpenWizard = () => { - setWizardModalOpen(true) - } - - const handleCloseWizard = () => { - handleFinishWizard() - } - - const handleFinishWizard = () => { - setWizardModalOpen(false) - } - return ( <>
@@ -50,46 +69,22 @@ const Triggers = () => {
- + setWizard(true)}> + Add new trigger
- {wizardModalOpen && ( - - - - - + {wizard && ( + setWizard(null)} /> )} ) diff --git a/new-lamassu-admin/src/pages/Triggers/Triggers.styles.js b/new-lamassu-admin/src/pages/Triggers/Triggers.styles.js index 61584b81..eeae173a 100644 --- a/new-lamassu-admin/src/pages/Triggers/Triggers.styles.js +++ b/new-lamassu-admin/src/pages/Triggers/Triggers.styles.js @@ -1,5 +1,5 @@ -import baseStyles from 'src/pages/Logs.styles' import { booleanPropertiesTableStyles } from 'src/components/booleanPropertiesTable/BooleanPropertiesTable.styles' +import baseStyles from 'src/pages/Logs.styles' const { titleWrapper, titleAndButtonsContainer, buttonsWrapper } = baseStyles const { rowWrapper, radioButtons } = booleanPropertiesTableStyles @@ -10,6 +10,17 @@ const mainStyles = { buttonsWrapper, rowWrapper, radioButtons, + radioGroup: { + flexDirection: 'row' + }, + radioLabel: { + width: 150, + height: 40 + }, + radio: { + padding: 4, + margin: 4 + }, closeButton: { position: 'absolute', width: 16, @@ -34,14 +45,6 @@ const mainStyles = { marginRight: 12 } }, - modal: { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - '& > div': { - outline: 'none' - } - }, wizardHeaderText: { display: 'flex', margin: [[24, 0]] diff --git a/new-lamassu-admin/src/pages/Triggers/Wizard.js b/new-lamassu-admin/src/pages/Triggers/Wizard.js new file mode 100644 index 00000000..ff76c550 --- /dev/null +++ b/new-lamassu-admin/src/pages/Triggers/Wizard.js @@ -0,0 +1,103 @@ +import { makeStyles } from '@material-ui/core' +import { Form, Formik } from 'formik' +import * as R from 'ramda' +import React, { useState, Fragment } from 'react' + +import ErrorMessage from 'src/components/ErrorMessage' +import Modal from 'src/components/Modal' +import Stepper from 'src/components/Stepper' +import { Button } from 'src/components/buttons' + +import { direction, type, requirements } from './helper' + +const LAST_STEP = 3 + +const styles = { + stepper: { + margin: [[16, 0, 14, 0]] + }, + submit: { + display: 'flex', + flexDirection: 'row', + margin: [['auto', 0, 24]] + }, + button: { + marginLeft: 'auto' + }, + form: { + height: '100%', + display: 'flex', + flexDirection: 'column' + } +} + +const useStyles = makeStyles(styles) + +const getStep = step => { + switch (step) { + case 1: + return direction + case 2: + return type + case 3: + return requirements + default: + return Fragment + } +} + +const Wizard = ({ machine, onClose, save, error }) => { + const classes = useStyles() + + const [{ step, config }, setState] = useState({ + step: 1 + }) + + const isLastStep = step === LAST_STEP + const stepOptions = getStep(step) + + const onContinue = async it => { + const newConfig = R.merge(config, stepOptions.schema.cast(it)) + + if (isLastStep) { + return save(newConfig) + } + + setState({ + step: step + 1, + config: newConfig + }) + } + + return ( + + + + + +
+ {error && Failed to save} + +
+ +
+
+ ) +} + +export default Wizard diff --git a/new-lamassu-admin/src/pages/Triggers/helper.js b/new-lamassu-admin/src/pages/Triggers/helper.js new file mode 100644 index 00000000..bebc7dc4 --- /dev/null +++ b/new-lamassu-admin/src/pages/Triggers/helper.js @@ -0,0 +1,250 @@ +import { makeStyles, Box } from '@material-ui/core' +import classnames from 'classnames' +import { Field, useFormikContext } from 'formik' +import * as R from 'ramda' +import React from 'react' +import * as Yup from 'yup' + +import { TextInput, RadioGroup } from 'src/components/inputs/formik' +import Autocomplete from 'src/components/inputs/formik/Autocomplete' +import { H4 } from 'src/components/typography' +import { errorColor } from 'src/styling/variables' + +const useStyles = makeStyles({ + radioLabel: { + height: 40, + padding: [[0, 10]] + }, + radio: { + padding: 4, + margin: 4 + }, + radioGroup: { + flexDirection: 'row' + }, + error: { + color: errorColor + }, + specialLabel: { + height: 40, + padding: 0 + }, + specialGrid: { + display: 'grid', + gridTemplateColumns: [[182, 162, 141]] + } +}) + +const cashDirection = Yup.string().required('Required') +const triggerType = Yup.string().required('Required') +const threshold = Yup.number().required('Required') +const requirement = Yup.string().required('Required') + +const Schema = Yup.object().shape({ + triggerType, + requirement, + threshold, + cashDirection +}) + +// Direction +const directionSchema = Yup.object().shape({ cashDirection }) + +const directionOptions = [ + { display: 'Both', code: 'both' }, + { display: 'Only cash-in', code: 'cashIn' }, + { display: 'Only cash-out', code: 'cashOut' } +] + +const Direction = () => { + const classes = useStyles() + const { errors } = useFormikContext() + + const titleClass = { + [classes.error]: errors.cashDirection + } + + return ( + <> + +

+ In which type of transactions will it trigger? +

+
+ + + ) +} + +const direction = { + schema: directionSchema, + options: directionOptions, + Component: Direction, + initialValues: { cashDirection: '' } +} + +// TYPE +const typeSchema = Yup.object().shape({ + triggerType, + threshold +}) + +const typeOptions = [ + { display: 'Transaction amount', code: 'txAmount' }, + { display: 'Transaction velocity', code: 'txVelocity' }, + { display: 'Transaction volume', code: 'txVolume' }, + { display: 'Consecutive days', code: 'consecutiveDays' } +] + +const Type = () => { + const classes = useStyles() + const { errors, touched } = useFormikContext() + + const typeClass = { + [classes.error]: errors.triggerType && touched.triggerType + } + + return ( + <> + +

Choose trigger type

+
+ + + + + ) +} + +const type = { + schema: typeSchema, + options: typeOptions, + Component: Type, + initialValues: { triggerType: '', threshold: '' } +} + +const requirementSchema = Yup.object().shape({ + requirement +}) + +const requirementOptions = [ + { display: 'SMS verification', code: 'sms' }, + { display: 'ID card image', code: 'idPhoto' }, + { display: 'ID data', code: 'idData' }, + { display: 'Customer camera', code: 'facephoto' }, + { display: 'Sanctions', code: 'sanctions' }, + { display: 'Super user', code: 'superuser' }, + { display: 'Suspend', code: 'suspend' }, + { display: 'Block', code: 'block' } +] + +const Requirement = () => { + const classes = useStyles() + const { errors } = useFormikContext() + + const titleClass = { + [classes.error]: errors.requirement + } + + return ( + <> + +

Choose a requirement

+
+ + + ) +} + +const requirements = { + schema: requirementSchema, + options: requirementOptions, + Component: Requirement, + initialValues: { requirement: '' } +} + +const getView = (data, code, compare) => it => { + if (!data) return '' + + return R.compose(R.prop(code), R.find(R.propEq(compare ?? 'code', it)))(data) +} + +const elements = [ + { + name: 'triggerType', + size: 'sm', + width: 271, + input: Autocomplete, + view: getView(typeOptions, 'display'), + inputProps: { + options: typeOptions, + valueProp: 'code', + getLabel: R.path(['display']), + limit: null + } + }, + { + name: 'requirement', + size: 'sm', + width: 271, + input: Autocomplete, + view: getView(requirementOptions, 'display'), + inputProps: { + options: requirementOptions, + valueProp: 'code', + getLabel: R.path(['display']), + limit: null + } + }, + { + name: 'threshold', + size: 'sm', + width: 271, + input: TextInput + }, + { + name: 'cashDirection', + size: 'sm', + width: 200, + view: getView(directionOptions, 'display'), + input: Autocomplete, + inputProps: { + options: directionOptions, + valueProp: 'code', + getLabel: R.path(['display']), + limit: null + } + } +] + +export { Schema, elements, direction, type, requirements } diff --git a/new-lamassu-admin/src/pages/Wallet/Wallet.js b/new-lamassu-admin/src/pages/Wallet/Wallet.js index 9285969c..492916ed 100644 --- a/new-lamassu-admin/src/pages/Wallet/Wallet.js +++ b/new-lamassu-admin/src/pages/Wallet/Wallet.js @@ -11,7 +11,7 @@ import Wizard from './Wizard' import { WalletSchema, getElements } from './helper' const SAVE_CONFIG = gql` - mutation Save($config: JSONObject, $accounts: [JSONObject]) { + mutation Save($config: JSONObject, $accounts: JSONObject) { saveConfig(config: $config) saveAccounts(accounts: $accounts) } diff --git a/new-lamassu-admin/src/pages/Wallet/Wizard.js b/new-lamassu-admin/src/pages/Wallet/Wizard.js index 71fddde4..b75efd31 100644 --- a/new-lamassu-admin/src/pages/Wallet/Wizard.js +++ b/new-lamassu-admin/src/pages/Wallet/Wizard.js @@ -18,7 +18,7 @@ const filterConfig = (crypto, type) => const getItems = (accountsConfig, accounts, type, crypto) => { const fConfig = filterConfig(crypto, type)(accountsConfig) - const find = code => R.find(R.propEq('code', code))(accounts) + const find = code => accounts && accounts[code] const [filled, unfilled] = R.partition(({ code }) => { const account = find(code) @@ -35,7 +35,7 @@ const Wizard = ({ coin, onClose, accountsConfig, accounts, save, error }) => { const [{ step, config, accountsToSave }, setState] = useState({ step: 0, config: { active: true }, - accountsToSave: [] + accountsToSave: {} }) const title = `Enable ${coin.display}` @@ -48,9 +48,11 @@ const Wizard = ({ coin, onClose, accountsConfig, accounts, save, error }) => { const getValue = code => R.find(R.propEq('code', code))(accounts) - const onContinue = async (it, it2) => { - const newConfig = R.merge(config, it) - const newAccounts = it2 ? R.concat(accountsToSave, [it2]) : accountsToSave + const onContinue = async (stepConfig, stepAccount) => { + const newConfig = R.merge(config, stepConfig) + const newAccounts = stepAccount + ? R.merge(accountsToSave, stepAccount) + : accountsToSave if (isLastStep) { return save(toNamespace(coin.code, newConfig), newAccounts) diff --git a/new-lamassu-admin/src/pages/Wallet/WizardStep.js b/new-lamassu-admin/src/pages/Wallet/WizardStep.js index 4482764f..752e57b4 100644 --- a/new-lamassu-admin/src/pages/Wallet/WizardStep.js +++ b/new-lamassu-admin/src/pages/Wallet/WizardStep.js @@ -7,12 +7,13 @@ import ErrorMessage from 'src/components/ErrorMessage' import Stepper from 'src/components/Stepper' import { Button } from 'src/components/buttons' import { RadioGroup, Autocomplete } from 'src/components/inputs' -import { Info2, H4 } from 'src/components/typography' +import { H4, Info2 } from 'src/components/typography' import FormRenderer from 'src/pages/Services/FormRenderer' import schema from 'src/pages/Services/schemas' import { startCase } from 'src/utils/string' import styles from './WizardStep.styles' + const useStyles = makeStyles(styles) const initialState = { @@ -41,7 +42,7 @@ const reducer = (state, action) => { iError: false } case 'error': - return R.merge(state, { iError: true }) + return R.merge(state, { innerError: true }) case 'reset': return initialState default: @@ -61,7 +62,7 @@ const WizardStep = ({ getValue }) => { const classes = useStyles() - const [{ iError, selected, form, isNew }, dispatch] = useReducer( + const [{ innerError, selected, form, isNew }, dispatch] = useReducer( reducer, initialState ) @@ -70,7 +71,7 @@ const WizardStep = ({ dispatch({ type: 'reset' }) }, [step]) - const iContinue = (config, account) => { + const innerContinue = (config, account) => { if (!config || !config[type]) { return dispatch({ type: 'error' }) } @@ -81,7 +82,7 @@ const WizardStep = ({ const displayName = name ?? type const subtitleClass = { [classes.subtitle]: true, - [classes.error]: iError + [classes.error]: innerError } return ( @@ -129,9 +130,7 @@ const WizardStep = ({ {form && ( - iContinue({ [type]: form.code }, R.merge(it, { code: form.code })) - } + save={it => innerContinue({ [type]: form.code }, { [form.code]: it })} elements={schema[form.code].elements} validationSchema={schema[form.code].validationSchema} value={getValue(form.code)} @@ -143,7 +142,7 @@ const WizardStep = ({ {error && Failed to save} diff --git a/new-lamassu-admin/src/pages/common.styles.js b/new-lamassu-admin/src/pages/common.styles.js deleted file mode 100644 index db9958b5..00000000 --- a/new-lamassu-admin/src/pages/common.styles.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - titleWrapper: { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - flexDirection: 'row' - }, - titleAndButtonsContainer: { - display: 'flex' - }, - iconButton: { - border: 'none', - outline: 0, - backgroundColor: 'transparent', - cursor: 'pointer' - } -} diff --git a/new-lamassu-admin/src/pages/maintenance/Cashboxes.js b/new-lamassu-admin/src/pages/maintenance/Cashboxes.js deleted file mode 100644 index 214f2ab2..00000000 --- a/new-lamassu-admin/src/pages/maintenance/Cashboxes.js +++ /dev/null @@ -1,210 +0,0 @@ -import { useQuery, useMutation } from '@apollo/react-hooks' -import { gql } from 'apollo-boost' -import React, { useState } from 'react' -import * as Yup from 'yup' - -import { Table as EditableTable } from 'src/components/editableTable' -import { - CashIn, - CashOut, - CashOutFormik, - CashInFormik -} from 'src/components/inputs/cashbox/Cashbox' -import TitleSection from 'src/components/layout/TitleSection' -import { ReactComponent as ErrorIcon } from 'src/styling/icons/status/tomato.svg' - -const ValidationSchema = Yup.object().shape({ - name: Yup.string().required('Required'), - cashin: Yup.object() - .required('Required') - .shape({ - notes: Yup.number() - .required('Required') - .integer() - .min(0) - }), - cashout1: Yup.object() - .required('Required') - .shape({ - notes: Yup.number() - .required('Required') - .integer() - .min(0), - denomination: Yup.number() - .required('Required') - .integer() - .default(0) - }), - cashout2: Yup.object() - .required('Required') - .shape({ - notes: Yup.number() - .required('Required') - .integer() - .min(0), - denomination: Yup.number() - .required('Required') - .integer() - .default(0) - }) -}) - -const GET_MACHINES_AND_CONFIG = gql` - { - machines { - name - deviceId - cashbox - cassette1 - cassette2 - } - config - } -` - -const EMPTY_CASHIN_BILLS = gql` - mutation MachineAction($deviceId: ID!, $action: MachineAction!) { - machineAction(deviceId: $deviceId, action: $action) { - deviceId - cashbox - cassette1 - cassette2 - } - } -` - -const RESET_CASHOUT_BILLS = gql` - mutation MachineAction( - $deviceId: ID! - $action: MachineAction! - $cassettes: [Int]! - ) { - machineAction(deviceId: $deviceId, action: $action, cassettes: $cassettes) { - deviceId - cashbox - cassette1 - cassette2 - } - } -` - -const Cashboxes = () => { - const [machines, setMachines] = useState([]) - - useQuery(GET_MACHINES_AND_CONFIG, { - onCompleted: ({ machines, config }) => - setMachines( - machines.map(m => ({ - ...m, - currency: { code: config.locale_fiatCurrency ?? '' }, - denominations: { - top: config[`denominations_${m.deviceId}_top`], - bottom: config[`denominations_${m.deviceId}_bottom`] - } - })) - ) - }) - - const [resetCashOut] = useMutation(RESET_CASHOUT_BILLS, { - onError: ({ graphQLErrors, message }) => { - const errorMessage = graphQLErrors[0] ? graphQLErrors[0].message : message - // TODO: this should not be final - alert(JSON.stringify(errorMessage)) - } - }) - - const [onEmpty] = useMutation(EMPTY_CASHIN_BILLS, { - onError: ({ graphQLErrors, message }) => { - const errorMessage = graphQLErrors[0] ? graphQLErrors[0].message : message - // TODO: this should not be final - alert(JSON.stringify(errorMessage)) - } - }) - - const onSave = (_, { cashin, cashout1, cashout2 }) => - resetCashOut({ - variables: { - deviceId: cashin.deviceId, - action: 'resetCashOutBills', - cassettes: [Number(cashout1.notes), Number(cashout2.notes)] - } - }) - - const elements = [ - { - name: 'name', - header: 'Machine', - width: 254, - textAlign: 'left', - view: name => <>{name}, - input: ({ field: { value: name } }) => <>{name} - }, - { - name: 'cashin', - header: 'Cash-in', - width: 265, - textAlign: 'left', - view: props => , - input: props => - }, - { - name: 'cashout1', - header: 'Cash-out 1', - width: 265, - textAlign: 'left', - view: props => , - input: CashOutFormik - }, - { - name: 'cashout2', - header: 'Cash-out 2', - width: 265, - textAlign: 'left', - view: props => , - input: CashOutFormik - } - ] - - const data = machines.map( - ({ - name, - cassette1, - cassette2, - currency, - denominations: { top, bottom }, - cashbox, - deviceId - }) => ({ - id: deviceId, - name, - cashin: { notes: cashbox, deviceId }, - cashout1: { notes: cassette1, denomination: top, currency }, - cashout2: { notes: cassette2, denomination: bottom, currency } - }) - ) - - return ( - <> - - - Action required - - } - /> - - - - ) -} - -export default Cashboxes diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index 7266898e..d65af0ce 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -3,12 +3,14 @@ import React from 'react' import { Route, Redirect, Switch } from 'react-router-dom' import AuthRegister from 'src/pages/AuthRegister' -import Cashout from 'src/pages/Cashout/Cashout' +import Cashout from 'src/pages/Cashout' import Commissions from 'src/pages/Commissions' import { Customers, CustomerProfile } from 'src/pages/Customers' import Funding from 'src/pages/Funding' import Locales from 'src/pages/Locales' import MachineLogs from 'src/pages/MachineLogs' +import Cashboxes from 'src/pages/Maintenance/Cashboxes' +import MachineStatus from 'src/pages/Maintenance/MachineStatus' import Notifications from 'src/pages/Notifications/Notifications' import OperatorInfo from 'src/pages/OperatorInfo/OperatorInfo' import ServerLogs from 'src/pages/ServerLogs' @@ -16,11 +18,8 @@ import Services from 'src/pages/Services/Services' import Transactions from 'src/pages/Transactions/Transactions' import Triggers from 'src/pages/Triggers' import WalletSettings from 'src/pages/Wallet/Wallet' -import MachineStatus from 'src/pages/maintenance/MachineStatus' import { namespaces } from 'src/utils/config' -import Cashboxes from '../pages/maintenance/Cashboxes' - const tree = [ { key: 'transactions', @@ -95,7 +94,7 @@ const tree = [ component: Cashout }, { - key: namespaces.SERVICES, + key: 'services', label: '3rd party services', route: '/settings/3rd-party-services', component: Services diff --git a/new-lamassu-admin/src/utils/config.js b/new-lamassu-admin/src/utils/config.js index f4f3c810..12f4ba7c 100644 --- a/new-lamassu-admin/src/utils/config.js +++ b/new-lamassu-admin/src/utils/config.js @@ -1,13 +1,15 @@ import * as R from 'ramda' const namespaces = { - CASH_OUT: 'denominations', + CASH_OUT: 'cashOut', WALLETS: 'wallets', OPERATOR_INFO: 'operatorInfo', NOTIFICATIONS: 'notifications', - SERVICES: 'services', LOCALE: 'locale', - COMMISSIONS: 'commissions' + COMMISSIONS: 'commissions', + RECEIPT: 'receipt', + COIN_ATM_RADAR: 'coinAtmRadar', + TERMS_CONDITIONS: 'termsConditions' } const mapKeys = R.curry((fn, obj) => diff --git a/new-lamassu-admin/todo.md b/new-lamassu-admin/todo.md new file mode 100644 index 00000000..24027d7c --- /dev/null +++ b/new-lamassu-admin/todo.md @@ -0,0 +1,41 @@ +UI: +- Large input fields wiggle on editable table edit/non-edit mode change. +- all (machines/coins/...) should be a option on some overrides + +Compliance: +- Reject Address Reuse missing + +CoinATMRadar: +- We now have photo, should we relay that info? + +Locale: +- should we show the user wallet needs to be configured after adding in a new coin? +- check if coin is active before considering it active on other screens + +Commission: +- overrides can be tighter. Hide coins already used by the same machine on another line. + +Sms/email: +- There's no place to pick a third party provider anymore. + +Cashout: +- I've just added a zero conf limit column. Should it be like this? + +Notifications: +- cashInAlertThreshold missing, used to warn to full cashbox + +Machine name: +- Previously we were grabbing that from the config, but since new admin still cant change the name i`m now grabbing it from the db. Possible issues if users change the machine name from the initial one. Investivate alternatives. + +Migrate: +- Need to write config migration. +- Rewrite config validate +- remove apply defaults + +Compliance: +- Currently admin only handles { type: 'volume', direction: 'both' } +- Sanctions should have more care in customers.js, currently just looking if is active as if old config + +Other stuff: +- sms.js +- email.js \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9457b220..d99c94f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,70 +49,90 @@ "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz", "integrity": "sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ==" }, - "@ava/babel-plugin-throws-helper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz", - "integrity": "sha1-L8H+PCEacQcaTsp7j3r1hCzRrnw=", - "dev": true - }, - "@ava/babel-preset-stage-4": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz", - "integrity": "sha1-rmC+iBoLq/fTX1Krp3DR9hlPdr0=", + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.8.0", - "babel-plugin-syntax-trailing-function-commas": "^6.20.0", - "babel-plugin-transform-async-to-generator": "^6.16.0", - "babel-plugin-transform-es2015-destructuring": "^6.19.0", - "babel-plugin-transform-es2015-function-name": "^6.9.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.18.0", - "babel-plugin-transform-es2015-parameters": "^6.21.0", - "babel-plugin-transform-es2015-spread": "^6.8.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.8.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.11.0", - "babel-plugin-transform-exponentiation-operator": "^6.8.0", - "package-hash": "^1.2.0" + "@babel/highlight": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" }, "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "md5-o-matic": "^0.1.1" + "color-convert": "^1.9.0" } }, - "package-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", - "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "md5-hex": "^1.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } }, - "@ava/babel-preset-transform-test-files": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz", - "integrity": "sha1-ze0RlqjY2TgaUJJAq5LpGl7Aafc=", + "@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", "dev": true, "requires": { - "@ava/babel-plugin-throws-helper": "^2.0.0", - "babel-plugin-espower": "^2.3.2" - } - }, - "@ava/pretty-format": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ava/pretty-format/-/pretty-format-1.1.0.tgz", - "integrity": "sha1-0KV9Jeua6rlkO90aAwZCuRwSPig=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "esutils": "^2.0.2" + "arrify": "^1.0.1" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } } }, "@fczbkk/uuid4": { @@ -120,6 +140,32 @@ "resolved": "https://registry.npmjs.org/@fczbkk/uuid4/-/uuid4-3.0.0.tgz", "integrity": "sha1-lksiHLlV4csPBEdnqWaCgCOjhLs=" }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -174,6 +220,21 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, "@types/accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", @@ -191,6 +252,12 @@ "@types/node": "*" } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/connect": { "version": "3.4.33", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", @@ -218,6 +285,12 @@ "@types/express": "*" } }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, "@types/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", @@ -245,6 +318,17 @@ "@types/node": "*" } }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/graphql-upload": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/@types/graphql-upload/-/graphql-upload-8.0.3.tgz", @@ -288,24 +372,36 @@ } }, "@types/lodash": { - "version": "4.14.144", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz", - "integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==" + "version": "4.14.149", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", + "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==" }, "@types/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", - "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/mime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", - "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.2.tgz", + "integrity": "sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==" + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true }, "@types/node": { - "version": "12.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz", - "integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==" + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz", + "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true }, "@types/range-parser": { "version": "1.2.3", @@ -313,9 +409,9 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" }, "@types/serve-static": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", - "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.4.tgz", + "integrity": "sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug==", "requires": { "@types/express-serve-static-core": "*", "@types/mime": "*" @@ -337,13 +433,6 @@ "tslib": "^1.9.3" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, "accepts": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", @@ -365,6 +454,12 @@ "integrity": "sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg==", "dev": true }, + "acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true + }, "aes-js": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", @@ -383,6 +478,16 @@ "es6-promisify": "^5.0.0" } }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", @@ -412,18 +517,24 @@ "optional": true }, "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", "dev": true, "requires": { - "string-width": "^2.0.0" + "string-width": "^3.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "is-fullwidth-code-point": { @@ -433,22 +544,23 @@ "dev": true }, "string-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", - "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } @@ -469,13 +581,13 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "anymatch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", - "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "arrify": "^1.0.0", - "micromatch": "^2.1.5" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "apollo-cache-control": { @@ -1010,33 +1122,6 @@ "sprintf-js": "~1.0.2" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-exclude": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/arr-exclude/-/arr-exclude-1.0.0.tgz", - "integrity": "sha1-38fC5VKicHI8zaBM8xKMjL/lxjE=", - "dev": true - }, - "arr-flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", - "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -1059,89 +1144,26 @@ } }, "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", - "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } - } - }, "arraybuffer.slice": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" }, + "arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true + }, "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, "asap": { @@ -1181,6 +1203,12 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.12.tgz", "integrity": "sha1-sTYwDWcCZiWuFTJpgsqZGOXbc8k=" }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "async": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", @@ -1189,21 +1217,15 @@ "lodash": "^4.14.0" } }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "async-retry": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", - "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", "requires": { "retry": "0.12.0" } @@ -1213,213 +1235,426 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "auto-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-1.1.0.tgz", - "integrity": "sha1-k7hk3H7gGjJigXddXHXKCnUeWWE=", - "dev": true - }, "ava": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/ava/-/ava-0.19.1.tgz", - "integrity": "sha1-Q92CQ1rRmzmA/8okiPBdqrlAsnM=", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.8.2.tgz", + "integrity": "sha512-sph3oUsVTGsq4qbgeWys03QKCmXjkZUO3oPnFWXEW6g1SReCY9vuONGghMgw1G6VOzkg1k+niqJsOzwfO8h9Ng==", "dev": true, "requires": { - "@ava/babel-preset-stage-4": "^1.0.0", - "@ava/babel-preset-transform-test-files": "^3.0.0", - "@ava/pretty-format": "^1.1.0", - "arr-flatten": "^1.0.1", - "array-union": "^1.0.1", - "array-uniq": "^1.0.2", - "arrify": "^1.0.0", - "auto-bind": "^1.1.0", - "ava-init": "^0.2.0", - "babel-code-frame": "^6.16.0", - "babel-core": "^6.17.0", - "bluebird": "^3.0.0", - "caching-transform": "^1.0.0", - "chalk": "^1.0.0", - "chokidar": "^1.4.2", - "clean-stack": "^1.1.1", + "@concordance/react": "^2.0.0", + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "ansi-styles": "^4.2.1", + "arrgv": "^1.0.2", + "arrify": "^2.0.1", + "callsites": "^3.1.0", + "chalk": "^4.0.0", + "chokidar": "^3.4.0", + "chunkd": "^2.0.1", + "ci-info": "^2.0.0", + "ci-parallel-vars": "^1.0.0", "clean-yaml-object": "^0.1.0", - "cli-cursor": "^2.1.0", - "cli-spinners": "^1.0.0", - "cli-truncate": "^1.0.0", - "co-with-promise": "^4.6.0", - "code-excerpt": "^2.1.0", - "common-path-prefix": "^1.0.0", - "convert-source-map": "^1.2.0", - "core-assert": "^0.2.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^2.1.1", + "common-path-prefix": "^3.0.0", + "concordance": "^4.0.0", + "convert-source-map": "^1.7.0", "currently-unhandled": "^0.4.1", - "debug": "^2.2.0", - "diff": "^3.0.1", - "diff-match-patch": "^1.0.0", - "dot-prop": "^4.1.0", - "empower-core": "^0.6.1", + "debug": "^4.1.1", + "del": "^5.1.0", + "emittery": "^0.6.0", "equal-length": "^1.0.0", - "figures": "^2.0.0", - "find-cache-dir": "^0.1.1", - "fn-name": "^2.0.0", - "get-port": "^3.0.0", - "globby": "^6.0.0", - "has-flag": "^2.0.0", - "hullabaloo-config-manager": "^1.0.0", + "figures": "^3.2.0", + "globby": "^11.0.0", "ignore-by-default": "^1.0.0", - "indent-string": "^3.0.0", - "is-ci": "^1.0.7", - "is-generator-fn": "^1.0.0", - "is-obj": "^1.0.0", - "is-observable": "^0.2.0", - "is-promise": "^2.1.0", - "jest-diff": "19.0.0", - "jest-snapshot": "19.0.2", - "js-yaml": "^3.8.2", - "last-line-stream": "^1.0.0", - "lodash.debounce": "^4.0.3", - "lodash.difference": "^4.3.0", - "lodash.flatten": "^4.2.0", - "lodash.isequal": "^4.5.0", - "loud-rejection": "^1.2.0", - "matcher": "^0.1.1", - "md5-hex": "^2.0.0", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "ms": "^0.7.1", - "multimatch": "^2.1.0", - "observable-to-promise": "^0.5.0", - "option-chain": "^0.1.0", - "package-hash": "^2.0.0", - "pkg-conf": "^2.0.0", - "plur": "^2.0.0", - "pretty-ms": "^2.0.0", - "require-precompiled": "^0.1.0", - "resolve-cwd": "^1.0.0", - "slash": "^1.0.0", - "source-map-support": "^0.4.0", - "stack-utils": "^1.0.0", - "strip-ansi": "^3.0.1", - "strip-bom-buf": "^1.0.0", - "supports-color": "^3.2.3", - "time-require": "^0.1.2", - "unique-temp-dir": "^1.0.0", - "update-notifier": "^2.1.0" + "import-local": "^3.0.2", + "indent-string": "^4.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^3.0.0", + "is-promise": "^4.0.0", + "lodash": "^4.17.15", + "matcher": "^3.0.0", + "md5-hex": "^3.0.1", + "mem": "^6.1.0", + "ms": "^2.1.2", + "ora": "^4.0.4", + "p-map": "^4.0.0", + "picomatch": "^2.2.2", + "pkg-conf": "^3.1.0", + "plur": "^4.0.0", + "pretty-ms": "^7.0.0", + "read-pkg": "^5.2.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.2", + "strip-ansi": "^6.0.0", + "supertap": "^1.0.0", + "temp-dir": "^2.0.0", + "trim-off-newlines": "^1.0.1", + "update-notifier": "^4.1.0", + "write-file-atomic": "^3.0.3", + "yargs": "^15.3.1" }, "dependencies": { - "indent-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.1.0.tgz", - "integrity": "sha1-CP9DNGAziDmbMp5rlTjcejz13n0=", + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", "dev": true }, - "ms": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", - "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "irregular-plurals": "^1.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "has-flag": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "mem": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz", + "integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.0.0" }, "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "mimic-fn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz", + "integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==", "dev": true } } - } - } - }, - "ava-init": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ava-init/-/ava-init-0.2.0.tgz", - "integrity": "sha1-kwTItMNX1m49/a4fv/R7EZnVxV0=", - "dev": true, - "requires": { - "arr-exclude": "^1.0.0", - "execa": "^0.5.0", - "has-yarn": "^1.0.0", - "read-pkg-up": "^2.0.0", - "write-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { + }, + "mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "mimic-fn": "^2.1.0" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { + "p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "p-try": "^2.0.0" } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "strip-bom": { + "p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + } + }, + "plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.2.0" + } + }, + "pretty-ms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", + "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", + "dev": true, + "requires": { + "parse-ms": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } } } }, @@ -1453,355 +1688,6 @@ "js-tokens": "^3.0.0" } }, - "babel-core": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", - "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "babel-generator": "^6.25.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.25.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "convert-source-map": "^1.1.0", - "debug": "^2.1.1", - "json5": "^0.5.0", - "lodash": "^4.2.0", - "minimatch": "^3.0.2", - "path-is-absolute": "^1.0.0", - "private": "^0.1.6", - "slash": "^1.0.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", - "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.2.0", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", - "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-espower": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", - "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", - "dev": true, - "requires": { - "babel-generator": "^6.1.0", - "babylon": "^6.1.0", - "call-matcher": "^1.0.0", - "core-js": "^2.0.0", - "espower-location-detector": "^1.0.0", - "espurify": "^1.6.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - } - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", - "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-register": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true, - "requires": { - "babel-core": "^6.24.1", - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.2" - } - }, "babel-runtime": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", @@ -1811,54 +1697,6 @@ "regenerator-runtime": "^0.10.0" } }, - "babel-template": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", - "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "lodash": "^4.2.0" - } - }, - "babel-traverse": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", - "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "debug": "^2.2.0", - "globals": "^9.0.0", - "invariant": "^2.2.0", - "lodash": "^4.2.0" - } - }, - "babel-types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", - "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "esutils": "^2.0.2", - "lodash": "^4.2.0", - "to-fast-properties": "^1.0.1" - } - }, - "babylon": { - "version": "6.17.4", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", - "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", - "dev": true - }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -1989,9 +1827,9 @@ "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" }, "binary-extensions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", - "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, "bindings": { @@ -2475,16 +2313,16 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.43.0" } }, "minimist": { @@ -2676,9 +2514,9 @@ } }, "elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "optional": true, "requires": { "bn.js": "^4.4.0", @@ -2703,9 +2541,9 @@ "optional": true }, "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", + "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", "optional": true, "requires": { "bindings": "^1.5.0", @@ -2713,7 +2551,7 @@ "bn.js": "^4.11.8", "create-hash": "^1.2.0", "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", + "elliptic": "^6.5.2", "nan": "^2.14.0", "safe-buffer": "^5.1.2" }, @@ -2769,18 +2607,10 @@ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "blueimp-md5": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.16.0.tgz", + "integrity": "sha512-j4nzWIqEFpLSbdhUApHRGDwfXbV8ALhqOn+FY5L6XBdKPAXU9BpGgFSbDsgqogfqPPR9R2WooseWCsfhfEC6uQ==", "dev": true }, "bn.js": { @@ -2824,56 +2654,114 @@ } }, "boxen": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.1.0.tgz", - "integrity": "sha1-sbad1SIwXoB6md7ud329blFnsQI=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "dev": true, "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^1.1.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^0.1.0", - "widest-line": "^1.0.0" + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", - "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -2887,14 +2775,12 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "fill-range": "^7.0.1" } }, "brorand": { @@ -2941,12 +2827,6 @@ "bs58": "^2.0.1" } }, - "buf-compare": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", - "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", - "dev": true - }, "buffer-compare": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz", @@ -2962,6 +2842,12 @@ "resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz", "integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U=" }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, "buffer-writer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz", @@ -2999,65 +2885,48 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" }, - "caching-transform": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", - "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "dev": true, "requires": { - "md5-hex": "^1.2.0", - "mkdirp": "^0.5.1", - "write-file-atomic": "^1.1.4" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" }, "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "dev": true, "requires": { - "md5-o-matic": "^0.1.1" + "pump": "^3.0.0" } }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } } }, - "call-matcher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", - "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", - "dev": true, - "requires": { - "core-js": "^2.0.0", - "deep-equal": "^1.0.0", - "espurify": "^1.6.0", - "estraverse": "^4.0.0" - }, - "dependencies": { - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - } - } - }, - "call-signature": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", - "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", - "dev": true - }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", @@ -3083,27 +2952,11 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, "camelize": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -3150,20 +3003,19 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" } }, "chownr": { @@ -3171,10 +3023,22 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, + "chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "ci-parallel-vars": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", - "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz", + "integrity": "sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g==", "dev": true }, "cipher-base": { @@ -3192,9 +3056,9 @@ "dev": true }, "clean-stack": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", - "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, "clean-yaml-object": { @@ -3204,9 +3068,9 @@ "dev": true }, "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", + "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", "dev": true }, "cli-cursor": { @@ -3218,50 +3082,51 @@ } }, "cli-spinners": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz", - "integrity": "sha1-75h+09SDkaw9q5GAtAanQhgNbmo=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", + "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", "dev": true }, "cli-truncate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.0.0.tgz", - "integrity": "sha1-IeuR9Hs/ZWDwBNt3p2m0Zo2cVRg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "requires": { - "slice-ansi": "0.0.4", - "string-width": "^2.0.0" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", - "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } } } @@ -3286,41 +3151,24 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, - "co-with-promise": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", - "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", - "dev": true, - "requires": { - "pinkie-promise": "^1.0.0" - }, - "dependencies": { - "pinkie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", - "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", - "dev": true - }, - "pinkie-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", - "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", - "dev": true, - "requires": { - "pinkie": "^1.0.0" - } - } - } - }, "code-excerpt": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.0.tgz", - "integrity": "sha1-XcwIHoj0p+O1VOnjXX7yMtR/gUc=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.1.tgz", + "integrity": "sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==", "dev": true, "requires": { "convert-to-spaces": "^1.0.1" @@ -3499,15 +3347,9 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" }, "common-path-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", - "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "dev": true }, "component-bind": { @@ -3626,18 +3468,71 @@ "typedarray": "^0.0.6" } }, - "configstore": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.0.tgz", - "integrity": "sha1-Rd+QcHPibfoc9LLVL1tgVF6qEdE=", + "concordance": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-4.0.0.tgz", + "integrity": "sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "date-time": "^2.1.0", + "esutils": "^2.0.2", + "fast-diff": "^1.1.2", + "js-string-escape": "^1.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.flattendeep": "^4.4.0", + "lodash.islength": "^4.0.1", + "lodash.merge": "^4.6.1", + "md5-hex": "^2.0.0", + "semver": "^5.5.1", + "well-known-symbols": "^2.0.0" + }, + "dependencies": { + "md5-hex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", + "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", + "dev": true, + "requires": { + "md5-o-matic": "^0.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "connect": { @@ -3696,10 +3591,13 @@ "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" }, "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", - "dev": true + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } }, "convert-to-spaces": { "version": "1.0.2", @@ -3731,16 +3629,6 @@ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, - "core-assert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", - "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", - "dev": true, - "requires": { - "buf-compare": "^1.0.0", - "is-error": "^2.2.0" - } - }, "core-js": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", @@ -3765,15 +3653,6 @@ "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz", "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=" }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, "create-hash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", @@ -3798,50 +3677,6 @@ "sha.js": "^2.4.8" } }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - } - } - }, - "cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", - "dev": true, - "requires": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - } - } - }, "cryptiles": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", @@ -3856,9 +3691,9 @@ "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, "currently-unhandled": { @@ -3911,10 +3746,13 @@ "integrity": "sha1-RuE6udqOMJdFyNAc5UchPr2y/j8=" }, "date-time": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-0.1.1.tgz", - "integrity": "sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", + "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", + "dev": true, + "requires": { + "time-zone": "^1.0.0" + } }, "dateformat": { "version": "2.2.0", @@ -3953,12 +3791,6 @@ "mimic-response": "^1.0.0" } }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, "deep-extend": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", @@ -3977,6 +3809,12 @@ "clone": "^1.0.2" } }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -4017,6 +3855,84 @@ } } }, + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -4047,22 +3963,6 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, "dicer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", @@ -4071,17 +3971,14 @@ "streamsearch": "0.1.2" } }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "diff-match-patch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz", - "integrity": "sha1-HMPIOkkNZ/ldkeOfatHy4Ia2MEg=", - "dev": true + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } }, "dns-prefetch-control": { "version": "0.1.0", @@ -4098,9 +3995,9 @@ } }, "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "requires": { "domelementtype": "^2.0.1", "entities": "^2.0.0" @@ -4146,12 +4043,12 @@ "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" }, "dot-prop": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.1.1.tgz", - "integrity": "sha1-qEk/C3te7sglJbXHWH+n3nyoWcE=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "^2.0.0" } }, "dotenv": { @@ -4230,15 +4127,17 @@ "minimalistic-crypto-utils": "^1.0.0" } }, - "empower-core": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz", - "integrity": "sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ=", - "dev": true, - "requires": { - "call-signature": "0.0.2", - "core-js": "^2.0.0" - } + "emittery": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.6.0.tgz", + "integrity": "sha512-6EMRGr9KzYWp8DzHFZsKVZBsMO6QhAeHMeHND8rhyBNCHKMLpgW9tZv40bwN3rAIKRS5CxcK8oLRKUJSB9h7yQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "encodeurl": { "version": "1.0.1", @@ -4369,6 +4268,7 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, "requires": { "es-to-primitive": "^1.1.1", "function-bind": "^1.1.1", @@ -4381,18 +4281,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" } }, - "es6-error": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.0.2.tgz", - "integrity": "sha1-7sXHJurO9Rt/a3PCDbbhsTsGnJg=", - "dev": true - }, "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", @@ -4406,6 +4301,12 @@ "es6-promise": "^4.0.3" } }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -4737,119 +4638,6 @@ "regexpp": "^2.0.1" } }, - "eslint-plugin-import": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz", - "integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-uviWSi5N67j3t3UKFxej1loCH0VZn5XuqdNxoLShPcYPw6cUZn74K1VRj+9myynRX03bxIBEkwlkob/ujLsJVw==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, "eslint-plugin-node": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", @@ -4927,26 +4715,6 @@ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, - "espower-location-detector": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", - "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", - "dev": true, - "requires": { - "is-url": "^1.2.1", - "path-is-absolute": "^1.0.0", - "source-map": "^0.5.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - } - } - }, "espree": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", @@ -4963,15 +4731,6 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" }, - "espurify": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", - "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", - "dev": true, - "requires": { - "core-js": "^2.0.0" - } - }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", @@ -5180,51 +4939,6 @@ "create-hash": "^1.1.1" } }, - "execa": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", - "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", - "dev": true, - "requires": { - "cross-spawn": "^4.0.0", - "get-stream": "^2.2.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, "expand-template": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.0.3.tgz", @@ -5435,15 +5149,6 @@ } } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, "extract-zip": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", @@ -5494,6 +5199,26 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", + "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -5504,6 +5229,15 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fd-slicer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", @@ -5535,23 +5269,13 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-0.0.2.tgz", "integrity": "sha1-N83RtbkFQEs/BeGyNkW+aU/3D4I=" }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "to-regex-range": "^5.0.1" } }, "finalhandler": { @@ -5578,17 +5302,6 @@ } } }, - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -5596,13 +5309,42 @@ "dev": true }, "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } } }, "flat-cache": { @@ -5617,12 +5359,6 @@ "write": "^0.2.1" } }, - "fn-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", - "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", - "dev": true - }, "follow-redirects": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.4.tgz", @@ -5631,21 +5367,6 @@ "debug": "^2.4.5" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -5712,448 +5433,11 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, - "optional": true, - "requires": { - "nan": "^2.3.0", - "node-pre-gyp": "^0.6.36" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "aproba": { - "version": "1.1.1", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "requires": { - "balanced-match": "^0.4.1", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "co": { - "version": "4.6.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "har-schema": { - "version": "1.0.5", - "bundled": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true - }, - "mime-db": { - "version": "1.27.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "requires": { - "mime-db": "~1.27.0" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "qs": { - "version": "6.4.0", - "bundled": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true - }, - "semver": { - "version": "5.3.0", - "bundled": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "^1.0.2" - } - } - } - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } + "optional": true }, "ftp": { "version": "0.3.10", @@ -6231,16 +5515,10 @@ "is-property": "^1.0.0" } }, - "get-port": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.1.0.tgz", - "integrity": "sha1-7wGxioTKZIaXD/meVERhQac//T4=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-stream": { @@ -6294,48 +5572,50 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "^4.0.1" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", - "dev": true - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", "dev": true, "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "ini": "^1.3.5" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + } + } + }, + "globby": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", + "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } @@ -6930,12 +6210,6 @@ } } }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, "has-cors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", @@ -6971,9 +6245,9 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "has-yarn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz", - "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, "hash-base": { @@ -7092,16 +6366,6 @@ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "hosted-git-info": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", @@ -7132,9 +6396,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", + "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7156,6 +6420,12 @@ } } }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "http-errors": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz", @@ -7229,54 +6499,6 @@ } } }, - "hullabaloo-config-manager": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz", - "integrity": "sha1-HZEXgTEprQNf2ehHfq8GaREmn+M=", - "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "es6-error": "^4.0.2", - "graceful-fs": "^4.1.11", - "indent-string": "^3.1.0", - "json5": "^0.5.1", - "lodash.clonedeep": "^4.5.0", - "lodash.clonedeepwith": "^4.5.0", - "lodash.isequal": "^4.5.0", - "lodash.merge": "^4.6.0", - "md5-hex": "^2.0.0", - "package-hash": "^2.0.0", - "pkg-dir": "^2.0.0", - "resolve-from": "^3.0.0", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "indent-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.1.0.tgz", - "integrity": "sha1-CP9DNGAziDmbMp5rlTjcejz13n0=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, "iconv": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/iconv/-/iconv-2.3.0.tgz", @@ -7313,6 +6535,16 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -7320,13 +6552,10 @@ "dev": true }, "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true }, "indexof": { "version": "0.0.1", @@ -7437,15 +6666,6 @@ } } }, - "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -7462,9 +6682,9 @@ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, "irregular-plurals": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", - "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", "dev": true }, "is-arguments": { @@ -7479,12 +6699,12 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { @@ -7504,15 +6724,16 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true }, "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { - "ci-info": "^1.0.0" + "ci-info": "^2.0.0" } }, "is-date-object": { @@ -7520,37 +6741,16 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-error": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", - "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { @@ -7569,24 +6769,18 @@ "number-is-nan": "^1.0.0" } }, - "is-generator-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", - "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", - "dev": true - }, "is-generator-function": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==" }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "^2.1.1" } }, "is-hex-prefixed": { @@ -7594,6 +6788,22 @@ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-my-json-valid": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", @@ -7606,24 +6816,21 @@ } }, "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-object": { @@ -7631,31 +6838,31 @@ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" }, - "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", - "dev": true, - "requires": { - "symbol-observable": "^0.2.2" - } + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } }, "is-promise": { "version": "2.1.0", @@ -7667,16 +6874,11 @@ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, "requires": { "has": "^1.0.1" } @@ -7710,16 +6912,10 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "is-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", - "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, "isarray": { @@ -7738,13 +6934,10 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true }, "isstream": { "version": "0.1.2", @@ -7765,93 +6958,6 @@ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" }, - "jest-diff": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-19.0.0.tgz", - "integrity": "sha1-0VY8/FbItgIymI+8BdTRbtkPBjw=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "diff": "^3.0.0", - "jest-matcher-utils": "^19.0.0", - "pretty-format": "^19.0.0" - } - }, - "jest-file-exists": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jest-file-exists/-/jest-file-exists-19.0.0.tgz", - "integrity": "sha1-zKLlh6EeyS4kz+qz+KlNZX8/zrg=", - "dev": true - }, - "jest-matcher-utils": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz", - "integrity": "sha1-Xs2bY1ZdKwAfYfv37Ex/U3lkVk0=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "pretty-format": "^19.0.0" - } - }, - "jest-message-util": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-19.0.0.tgz", - "integrity": "sha1-cheWuJwOTXYWBvm6jLgoo7YkZBY=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "micromatch": "^2.3.11" - } - }, - "jest-mock": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-19.0.0.tgz", - "integrity": "sha1-ZwOGQelgerLOCOxKjLg6q7yJnQE=", - "dev": true - }, - "jest-snapshot": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-19.0.2.tgz", - "integrity": "sha1-nBshYhT3GHw4v9XHCx76sWsP9Qs=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "jest-diff": "^19.0.0", - "jest-file-exists": "^19.0.0", - "jest-matcher-utils": "^19.0.0", - "jest-util": "^19.0.2", - "natural-compare": "^1.4.0", - "pretty-format": "^19.0.0" - } - }, - "jest-util": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-19.0.2.tgz", - "integrity": "sha1-4KAjKiq55rK1Nmi9s1NMK1l37UE=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "graceful-fs": "^4.1.6", - "jest-file-exists": "^19.0.0", - "jest-message-util": "^19.0.0", - "jest-mock": "^19.0.0", - "jest-validate": "^19.0.2", - "leven": "^2.0.0", - "mkdirp": "^0.5.1" - } - }, - "jest-validate": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-19.0.2.tgz", - "integrity": "sha1-3FNN9fEnjVtj3zKxQkHU2/ckTAw=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "jest-matcher-utils": "^19.0.0", - "leven": "^2.0.0", - "pretty-format": "^19.0.0" - } - }, "joi": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", @@ -7880,9 +6986,9 @@ "dev": true }, "js-xdr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/js-xdr/-/js-xdr-1.1.2.tgz", - "integrity": "sha512-ipiz1CnsyjLsba+QQd5jezGXddNKGa4oO9EODy0kWr3G3R8MNslIxkhQFpyRfY3yoY7YplhRVfC3cmXb4AobZQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/js-xdr/-/js-xdr-1.1.3.tgz", + "integrity": "sha512-zFg7dIc6lI7LiZ/eru5U/cOur/SJGkbKflgkwoFIiHewgpmBGsRJNKbeOh/8Ffzz5mYvfmsO6gHAe5wv/ZYM2g==", "requires": { "core-js": "^2.6.3", "cursor": "^0.1.5", @@ -7891,9 +6997,9 @@ }, "dependencies": { "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "long": { "version": "2.4.0", @@ -7903,35 +7009,39 @@ } }, "js-yaml": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", - "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", - "esprima": "^3.1.1" + "esprima": "^4.0.0" }, "dependencies": { - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true } } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema": { @@ -7964,12 +7074,6 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -8066,13 +7170,13 @@ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=" }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "json-buffer": "3.0.0" } }, "klaw": { @@ -8091,22 +7195,13 @@ "request": ">=2.27.0" } }, - "last-line-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", - "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", - "dev": true, - "requires": { - "through2": "^2.0.0" - } - }, "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dev": true, "requires": { - "package-json": "^4.0.0" + "package-json": "^6.3.0" } }, "lcid": { @@ -8117,12 +7212,6 @@ "invert-kv": "^1.0.0" } }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -8150,6 +7239,12 @@ "nan": "^2.3.0" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "lnd-async": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/lnd-async/-/lnd-async-1.2.0.tgz", @@ -8159,22 +7254,38 @@ } }, "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" }, "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } @@ -8208,46 +7319,22 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.clonedeepwith": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", - "integrity": "sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "lodash.islength": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.islength/-/lodash.islength-4.0.1.tgz", + "integrity": "sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc=", "dev": true }, "lodash.merge": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", - "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.once": { @@ -8265,6 +7352,52 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "long": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", @@ -8287,16 +7420,6 @@ "js-tokens": "^3.0.0" } }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, "lowdb": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", @@ -8500,28 +7623,39 @@ } } }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "matcher": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-0.1.2.tgz", - "integrity": "sha1-7yDL3mTCTFDMYa9bg+4LG4/wAQE=", + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.4" + "p-defer": "^1.0.0" + } + }, + "matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "requires": { + "escape-string-regexp": "^4.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + } } }, "md5-hex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", - "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", "dev": true, "requires": { - "md5-o-matic": "^0.1.1" + "blueimp-md5": "^2.10.0" } }, "md5-o-matic": { @@ -8571,29 +7705,17 @@ "mimic-fn": "^1.0.0" } }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, "merkle-lib": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", @@ -8605,24 +7727,13 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "migrate": { @@ -8787,18 +7898,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" - } - }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", @@ -8876,51 +7975,11 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, - "node-pre-gyp": { - "version": "0.6.39", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz", - "integrity": "sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "hawk": "3.1.3", - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "request": "2.81.0", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^2.2.1", - "tar-pack": "^3.4.0" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true, - "optional": true - } - } - }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -8942,22 +8001,16 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true }, "npmlog": { "version": "4.1.2", @@ -9022,41 +8075,32 @@ } }, "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" }, "dependencies": { "es-abstract": { - "version": "1.17.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", - "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { @@ -9074,6 +8118,19 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "requires": { + "has": "^1.0.3" + } + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -9081,52 +8138,37 @@ } } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.17.0-next.1" }, "dependencies": { "es-abstract": { - "version": "1.17.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", - "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", - "dev": true, + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -9136,14 +8178,25 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "requires": { + "has": "^1.0.3" + } }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" } } }, @@ -9152,24 +8205,6 @@ "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.2.1.tgz", "integrity": "sha512-KMA0nZW3Z0UdG9Qtt5Ti8aFg8WvWHE8dKEL2/U5/+PfqyzpVyeLVXOrwhFskyrxnYjn936JZVm76rshSOYHgxQ==" }, - "observable-to-promise": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.5.0.tgz", - "integrity": "sha1-yCjw8NxH6fhq+KSXfF1VB2znqR8=", - "dev": true, - "requires": { - "is-observable": "^0.2.0", - "symbol-observable": "^1.0.4" - }, - "dependencies": { - "symbol-observable": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", - "dev": true - } - } - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -9199,15 +8234,6 @@ "mimic-fn": "^1.0.0" } }, - "option-chain": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-0.1.1.tgz", - "integrity": "sha1-6bgR4AbxwPVIAvKClb/Ilw+Nz70=", - "dev": true, - "requires": { - "object-assign": "^4.0.1" - } - }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -9226,6 +8252,129 @@ "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" }, + "ora": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", + "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -9252,22 +8401,17 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", "integrity": "sha1-ueEjgAvOu3rBOkeb4ZW1B7mNMPo=" }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, "p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", @@ -9296,6 +8440,15 @@ "p-limit": "^1.1.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", @@ -9309,6 +8462,12 @@ "p-finally": "^1.0.0" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "pac-proxy-agent": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", @@ -9351,60 +8510,94 @@ "thunkify": "^2.1.2" } }, - "package-hash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-2.0.0.tgz", - "integrity": "sha1-eK4ybIngWk2BO2hgGXevBcANKg0=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "lodash.flattendeep": "^4.4.0", - "md5-hex": "^2.0.0", - "release-zalgo": "^1.0.0" - } - }, "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dev": true, "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" }, "dependencies": { - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { - "create-error-class": "^3.0.0", + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", - "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", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } } } }, @@ -9418,18 +8611,6 @@ "resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-1.4.1.tgz", "integrity": "sha512-KhwY9xv8tZGQE8L7FfzaTHrLH+JnarUsDlsa8mqfisjtU3J00P362IL52Ei/EhDp025yBDzPuES/zMdWvvAR5g==" }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -9474,13 +8655,10 @@ "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" }, "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -9526,23 +8704,10 @@ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "pbkdf2": { "version": "3.0.12", @@ -9711,6 +8876,12 @@ "which": "^1.2.10" } }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -9786,12 +8957,12 @@ } }, "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^1.0.0" + "find-up": "^4.0.0" } }, "plur": { @@ -9864,32 +9035,6 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-format": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-19.0.0.tgz", - "integrity": "sha1-VlMNMqy5ij+khRxOK503tCBoTIQ=", - "dev": true, - "requires": { - "ansi-styles": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.1.0.tgz", - "integrity": "sha1-CcIC1ckX7CMYjKpcnLkXnNlUd1A=", - "dev": true, - "requires": { - "color-convert": "^1.0.0" - } - } - } - }, "pretty-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", @@ -9900,12 +9045,6 @@ "plur": "^1.0.0" } }, - "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", - "dev": true - }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", @@ -10094,6 +9233,15 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, + "pupa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", + "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, "pushdata-bitcoin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz", @@ -10117,47 +9265,6 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "randombytes": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", @@ -10193,24 +9300,62 @@ } }, "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "readable-stream": { @@ -10228,25 +9373,12 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "picomatch": "^2.2.1" } }, "referrer-policy": { @@ -10254,27 +9386,11 @@ "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz", "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" }, - "regenerate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", - "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", - "dev": true - }, "regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" }, - "regex-cache": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3", - "is-primitive": "^2.0.0" - } - }, "regexp-quote": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz", @@ -10286,85 +9402,62 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, "registry-auth-token": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", - "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", + "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", "dev": true, "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" + "rc": "^1.2.8" + }, + "dependencies": { + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + } } }, "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dev": true, "requires": { - "rc": "^1.0.1" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "remove-trailing-separator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" + "rc": "^1.2.8" + }, + "dependencies": { + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + } } }, "request": { @@ -10424,10 +9517,16 @@ "throttleit": "^1.0.0" } }, - "require-precompiled": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", - "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "require-uncached": { @@ -10463,28 +9562,29 @@ } }, "resolve-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", - "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "resolve-from": "^2.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - } + "resolve-from": "^5.0.0" } }, "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -10499,6 +9599,12 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rewire": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/rewire/-/rewire-4.0.1.tgz", @@ -10853,6 +9959,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, "requires": { "glob": "^7.0.5" } @@ -10908,6 +10015,16 @@ "safe-buffer": "^5.0.1" } }, + "bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==" + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==" + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -10923,17 +10040,36 @@ } }, "ripple-binary-codec": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.2.4.tgz", - "integrity": "sha512-lfT9bybaVqA8IJmGFnSWaISCXmwvNY/P5HHKm6zQ1yTIXJpC+hDIeQqm/eD/2HLv82y2IvqGYd0GhEQ41lpNpQ==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.2.6.tgz", + "integrity": "sha512-k0efyjpcde7p+rJ9PXW9tJSYsUDdlC9Z9xU7OPM7fJiHVKlR1E7nfu0jqw9vVXtTG3tujqKeEgtcb8yaa7rMXA==", "requires": { "babel-runtime": "^6.6.1", - "bn.js": "^4.11.3", + "bn.js": "^5.1.1", "create-hash": "^1.1.2", - "decimal.js": "^5.0.8", + "decimal.js": "^10.2.0", "inherits": "^2.0.1", "lodash": "^4.17.15", - "ripple-address-codec": "^3.0.4" + "ripple-address-codec": "^4.0.0" + }, + "dependencies": { + "base-x": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.7.tgz", + "integrity": "sha512-zAKJGuQPihXW22fkrfOclUUZXM2g92z5GzlSMHxhO6r6Qj+Nm0ccaGNBzDZojzwOMkpjAv4J0fOv1U4go+a4iw==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ripple-address-codec": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.1.0.tgz", + "integrity": "sha512-C72gJpwvDagaOUiHyh67otqNqFduB4hjvJFiiPz/8I3FCiUYuvFLXeLhb29CEkoAEdoN9p7pPreLgoHUvwzt9w==", + "requires": { + "base-x": "3.0.7", + "create-hash": "^1.1.2" + } + } } } } @@ -11157,18 +10293,18 @@ "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==" }, "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dev": true, "requires": { - "semver": "^5.0.3" + "semver": "^6.3.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -11249,6 +10385,12 @@ } } }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true + }, "serve-static": { "version": "1.12.4", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz", @@ -11315,12 +10457,6 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, "setprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", @@ -11380,22 +10516,54 @@ } }, "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } }, "slug": { "version": "0.9.2", @@ -11510,15 +10678,6 @@ "socks": "^1.1.10" } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -11613,10 +10772,21 @@ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } }, "standard": { "version": "12.0.1", @@ -11769,9 +10939,9 @@ }, "dependencies": { "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.2.tgz", + "integrity": "sha512-+8aPRjmXgf1VqvyxSlBUzKzeYqVS9Ai8vZ28g+mL7dNQl1jlUTCMDZnvNQdAS1xTywMkIXwJsfipsR/6s2+syw==" } } }, @@ -11846,18 +11016,18 @@ } }, "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" } }, "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", "requires": { "define-properties": "^1.1.3", "function-bind": "^1.1.1" @@ -11885,27 +11055,9 @@ } }, "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "^0.2.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-hex-prefix": { @@ -11916,15 +11068,6 @@ "is-hex-prefixed": "1.0.0" } }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -12003,14 +11146,14 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "qs": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", - "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==" + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", + "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==" }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12055,17 +11198,53 @@ } } }, + "supertap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz", + "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "indent-string": "^3.2.0", + "js-yaml": "^3.10.0", + "serialize-error": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, - "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", - "dev": true - }, "table": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", @@ -12182,16 +11361,6 @@ "pandemonium": "^1.0.2" } }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, "tar-fs": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz", @@ -12203,23 +11372,6 @@ "tar-stream": "^1.1.2" } }, - "tar-pack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", - "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" - } - }, "tar-stream": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", @@ -12231,45 +11383,17 @@ "xtend": "^4.0.0" } }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true + }, "term-size": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-0.1.1.tgz", - "integrity": "sha1-hzYLljlsq1dgljcUzaDQy+7K2co=", - "dev": true, - "requires": { - "execa": "^0.4.0" - }, - "dependencies": { - "execa": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.4.0.tgz", - "integrity": "sha1-TrZGejaglfq7KXD/nV4/t7zm68M=", - "dev": true, - "requires": { - "cross-spawn-async": "^2.1.1", - "is-stream": "^1.1.0", - "npm-run-path": "^1.0.0", - "object-assign": "^4.0.1", - "path-key": "^1.0.0", - "strip-eof": "^1.0.0" - } - }, - "npm-run-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", - "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", - "dev": true, - "requires": { - "path-key": "^1.0.0" - } - }, - "path-key": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", - "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", - "dev": true - } - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", + "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "dev": true }, "text-table": { "version": "0.2.0", @@ -12301,57 +11425,11 @@ "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=" }, - "time-require": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", - "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", - "dev": true, - "requires": { - "chalk": "^0.4.0", - "date-time": "^0.1.1", - "pretty-ms": "^0.2.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" - } - }, - "parse-ms": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", - "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", - "dev": true - }, - "pretty-ms": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", - "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", - "dev": true, - "requires": { - "parse-ms": "^0.1.0" - } - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - } - } + "time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true }, "timed-out": { "version": "4.0.1", @@ -12371,12 +11449,21 @@ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -12403,16 +11490,10 @@ "punycode": "^1.4.1" } }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-right": { + "trim-off-newlines": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, "triple-beam": { @@ -12507,6 +11588,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + }, "type-is": { "version": "1.6.15", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", @@ -12521,24 +11608,20 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typeforce": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", - "dev": true, - "optional": true - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", - "dev": true - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -12556,23 +11639,12 @@ "dev": true }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unique-temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", - "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1", - "os-tmpdir": "^1.0.1", - "uid2": "0.0.3" + "crypto-random-string": "^2.0.0" } }, "unorm": { @@ -12591,19 +11663,76 @@ "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=" }, "update-notifier": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz", - "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", + "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", "dev": true, "requires": { - "boxen": "^1.0.0", - "chalk": "^1.0.0", - "configstore": "^3.0.0", + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "uri-js": { @@ -12742,6 +11871,15 @@ "extsprintf": "1.0.2" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "weak-map": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz", @@ -12765,6 +11903,12 @@ } } }, + "well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true + }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", @@ -12773,6 +11917,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", @@ -12782,12 +11932,46 @@ } }, "widest-line": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", - "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { - "string-width": "^1.0.1" + "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "wif": { @@ -12895,52 +12079,15 @@ } }, "write-file-atomic": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", - "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - }, - "write-json-file": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.2.0.tgz", - "integrity": "sha1-UYYlBruzthnu+reFnx/WxtBTCHY=", - "dev": true, - "requires": { - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "pify": "^2.0.0", - "sort-keys": "^1.1.1", - "write-file-atomic": "^2.0.0" - }, - "dependencies": { - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "write-pkg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-2.1.0.tgz", - "integrity": "sha1-NTqkTDnEjCFED1wIzmq9RhQcnAg=", - "dev": true, - "requires": { - "sort-keys": "^1.1.2", - "write-json-file": "^2.0.0" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { @@ -12980,9 +12127,9 @@ "integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk=" }, "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, "xhr2": { @@ -13097,6 +12244,24 @@ "y18n": "^3.2.0" } }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, "yauzl": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", diff --git a/package.json b/package.json index 8c5e38e2..32f479d8 100644 --- a/package.json +++ b/package.json @@ -112,8 +112,7 @@ "build-admin": "npm run build-admin:css && npm run build-admin:main && npm run build-admin:lamassu" }, "devDependencies": { - "ava": "^0.19.1", - "eslint-plugin-import": "^2.19.1", + "ava": "3.8.2", "mocha": "^5.0.1", "rewire": "^4.0.1", "standard": "^12.0.1" @@ -121,7 +120,8 @@ "standard": { "ignore": [ "/lamassu-admin-elm", - "/public" + "/public", + "/new-lamassu-admin" ] } } diff --git a/public/elm.js b/public/elm.js index 80c247d2..cede45d8 100644 --- a/public/elm.js +++ b/public/elm.js @@ -37383,7 +37383,11 @@ var _user$project$NavBar$determineConfigCategory = function (configCode) { _1: { ctor: '::', _0: 'operatorInfo', - _1: {ctor: '[]'} + _1: { + ctor: '::', + _0: 'fudgeFactor', + _1: {ctor: '[]'} + } } } } @@ -37836,7 +37840,11 @@ var _user$project$NavBar$view = F2( _1: { ctor: '::', _0: A2(configLink, 'operatorInfo', 'Operator Info'), - _1: {ctor: '[]'} + _1: { + ctor: '::', + _0: A2(configLink, 'fudgeFactor', 'Fudge Factor'), + _1: {ctor: '[]'} + } } } } diff --git a/schemas/infura.json b/schemas/infura.json index 153a70fb..1c58f6f1 100644 --- a/schemas/infura.json +++ b/schemas/infura.json @@ -4,7 +4,7 @@ "fields": [ { "code": "apiKey", - "display": "API key", + "display": "Project ID", "fieldType": "string", "secret": true, "required": true, @@ -12,7 +12,7 @@ }, { "code": "apiSecret", - "display": "API secret", + "display": "Project secret", "fieldType": "password", "secret": true, "required": true, diff --git a/test/fixtures/new-settings.json b/test/fixtures/new-settings.json new file mode 100644 index 00000000..58f51f7d --- /dev/null +++ b/test/fixtures/new-settings.json @@ -0,0 +1,139 @@ +{ + "config": { + "triggers": [ + { + "id": "ce8f240f-7235-4948-b833-4af56ccfa90f", + "cashDirection": "cash-out", + "triggerType": "volume", + "threshold": "12", + "requirement": "block" + } + ], + "denominations_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_bottom": 12, + "denominations_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_top": 12, + "denominations_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_active": true, + "locale_country": "US", + "locale_fiatCurrency": "USD", + "locale_languages": [ + "en-US" + ], + "locale_cryptoCurrencies": [ + "BTC" + ], + "commissions_minimumTx": 12, + "commissions_fixedFee": 12, + "commissions_cashOut": 12, + "commissions_cashIn": 12, + "operatorInfo_companyNumber": "123", + "operatorInfo_website": "123", + "operatorInfo_email": "123@gmail.com", + "operatorInfo_phone": "123", + "operatorInfo_name": "123", + "operatorInfo_active": true, + "receiptPrinting": { + "active": "on", + "operatorWebsite": true, + "operatorEmail": false, + "operatorPhone": false, + "companyRegistration": false, + "machineLocation": true, + "customerNameOrPhoneNumber": true, + "exchangeRate": false, + "addressQRCode": true + }, + "coinAtmRadar_active": true, + "coinAtmRadar_commissions": true, + "coinAtmRadar_supportedCryptocurrencies": true, + "coinAtmRadar_supportedFiat": true, + "coinAtmRadar_supportedBuySellDirection": true, + "coinAtmRadar_limitsAndVerification": true, + "termsConditions_active": true, + "termsConditions_title": "Rasdkl", + "termsConditions_text": "123oh12", + "termsConditions_acceptButtonText": "op1i2jh3po", + "termsConditions_cancelButtonText": "12341", + "wallets_BTC_active": true, + "wallets_BTC_ticker": "mock-ticker", + "wallets_BTC_wallet": "mock-wallet", + "wallets_BTC_exchange": "mock-exchange", + "wallets_BTC_zeroConf": "mock-zero-conf", + "commissions_overrides": [ + { + "minimumTx": 33, + "fixedFee": 33, + "cashOut": 33, + "cashIn": 33, + "cryptoCurrencies": [ + "BTC" + ], + "machine": "9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a", + "id": "423a32a9-0bbb-4997-b15a-c6db12334195", + "country": "", + "languages": [] + } + ], + "cashOut_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_bottom": 33, + "cashOut_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_top": 12, + "cashOut_9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a_active": true, + "notifications_email_active": true, + "notifications_sms_active": true, + "notifications_sms_transactions": true, + "notifications_email_compliance": true, + "notifications_highValueTransaction": 12, + "notifications_fiatBalanceCassette2": 42, + "notifications_fiatBalanceCassette1": 32, + "notifications_fiatBalanceOverrides": [ + { + "cassette2": 67, + "cassette1": 556, + "machine": "9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a", + "id": "18114e5b-e6e6-4e0e-a7bc-2cc4ad605d12" + } + ], + "notifications_cryptoLowBalance": 23, + "notifications_cryptoHighBalance": 56, + "notifications_cryptoBalanceOverrides": [ + { + "highBalance": 66, + "lowBalance": 545, + "cryptoCurrency": "ETH", + "id": "b59e4310-bca1-435c-a89e-b861a7de9b93" + }, + { + "highBalance": 23, + "lowBalance": 51, + "cryptoCurrency": "DASH", + "id": "a1f5ac7a-4b05-4ec7-8744-4d77c0555f5b" + } + ], + "locale_overrides": [ + { + "id": "f0f9248d-96da-4db5-b592-625251da0203", + "machine": "9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a", + "country": "US", + "languages": [ + "en-CA" + ], + "cryptoCurrencies": [ + "ETH" + ] + } + ], + "receipt_active": "on", + "receipt_operatorWebsite": false, + "receipt_operatorEmail": false, + "receipt_operatorPhone": false, + "receipt_companyRegistration": true, + "receipt_machineLocation": false, + "receipt_customerNameOrPhoneNumber": true, + "receipt_exchangeRate": false, + "receipt_addressQRCode": false, + "notifications_sms_balance": true, + "notifications_sms_compliance": true, + "notifications_sms_errors": true, + "notifications_email_errors": true, + "notifications_email_transactions": true, + "notifications_email_balance": true + }, + "accounts": {} +} \ No newline at end of file diff --git a/test/integration/README.md b/test/integration/README.md new file mode 100644 index 00000000..3ad283f6 --- /dev/null +++ b/test/integration/README.md @@ -0,0 +1 @@ +### Early experiments in regtest diff --git a/test/integration/balance.sh b/test/integration/balance.sh new file mode 100644 index 00000000..81709b8c --- /dev/null +++ b/test/integration/balance.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +PREFIX_W1='docker exec --user bitcoin bitcoin-server bitcoin-cli -rpcwallet=wallet1.dat -regtest ' +PREFIX_W2='docker exec --user bitcoin bitcoin-server bitcoin-cli -rpcwallet=wallet2.dat -regtest ' + +# Create address and generate mine blocks +ADDRESS_1=`$PREFIX_W1 getnewaddress` +ADDRESS_2=`$PREFIX_W2 getnewaddress` +$PREFIX_W1 generatetoaddress 101 $ADDRESS_1 > /dev/null 2>&1 + +echo -e 'Wallet 1 balance' +$PREFIX_W1 getwalletinfo | grep balance + +echo -e '\nWallet 2 balance' +$PREFIX_W2 getwalletinfo | grep balance + +# Wallet one has one UTXO, so this also tests change +echo -e '\n\nCreate send\n' +$PREFIX_W1 sendtoaddress $ADDRESS_2 0.3 > /dev/null 2>&1 + +echo -e 'Wallet 1 balance' +$PREFIX_W1 getwalletinfo | grep balance + +echo -e '\nWallet 2 balance' +$PREFIX_W2 getwalletinfo | grep balance + +echo -e '\n\nMine one block \n' +$PREFIX_W1 generatetoaddress 1 $ADDRESS_1 > /dev/null 2>&1 + +echo -e 'Wallet 1 balance' +$PREFIX_W1 getwalletinfo | grep balance + +echo -e '\nWallet 2 balance' +$PREFIX_W2 getwalletinfo | grep balance + diff --git a/test/integration/bitcoind.sh b/test/integration/bitcoind.sh new file mode 100644 index 00000000..33313887 --- /dev/null +++ b/test/integration/bitcoind.sh @@ -0,0 +1,7 @@ +#!/bin/bash + + docker run --rm --name bitcoin-server -it ruimarinho/bitcoin-core \ + -regtest=1 \ + -wallet=wallet1.dat \ + -wallet=wallet2.dat + diff --git a/test/unit/new-settings-loader.js b/test/unit/new-settings-loader.js new file mode 100644 index 00000000..8948f06d --- /dev/null +++ b/test/unit/new-settings-loader.js @@ -0,0 +1,17 @@ +import test from 'ava' +import _ from 'lodash/fp' +import settings from '../../db.json' + +import configManager from '../../lib/new-config-manager' + +const machineId = '9682f15e40539e40d3e4050a993cf74e3e157d6d9b7866fb1ebd5206024ae68a' +const config = settings.config + +test('first examples', () => { + const triggers = configManager.getTriggers(config) + const filtered = _.filter(_.matches({ triggerType: 'volume', cashDirection: 'both' }))(triggers) + const grouped = _.groupBy(_.prop('requirement'))(filtered) + const final = _.mapValues(_.compose(_.get('threshold'), _.minBy('threshold')))(grouped) + + console.log(final) +}) \ No newline at end of file