diff --git a/.drone.yml b/.drone.yml index e0337fc42e..6db95bd68c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -87,9 +87,9 @@ trigger: # - docker pull hollaex/hollaex-kit:$(cat .tags) # - export DOCKER_CONTENT_TRUST=1 # - mkdir $${HOME}/.docker/trust && mkdir $${HOME}/.docker/trust/private -# - echo -n $${DOCKER_CONTENT_TRUST_PRIVATE_KEY} | base64 -d > $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key -# - chmod 600 $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key -# - docker trust key load $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key --name bitholla-cicd +# - echo -n $${DOCKER_CONTENT_TRUST_PRIVATE_KEY} | base64 -d > $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key +# - chmod 600 $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key +# - docker trust key load $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key --name bitholla-cicd # - docker trust sign hollaex/hollaex-kit:$(cat .tags) # - name: docker_tagging_arm64v8_testnet @@ -194,6 +194,15 @@ steps: when: branch: master +# - name: docker_tagging_amd64_deployment +# image: alpine +# commands: +# - export TZ=UTC-9 && export GIT_COMMIT_SHORT="$(echo $DRONE_COMMIT | cut -c 1-7)" && export PACKAGE_VERSION="$(cat version)" && echo "2.7.0-testnet-86884d5" > .tags +# - echo "Current Docker tag is :" && cat .tags +# - echo "dockerTag:$(cat .tags)" > .dockerTag.yml +# when: +# branch: deployment + - name: docker_build_amd64 image: plugins/docker settings: @@ -228,9 +237,9 @@ steps: - docker pull hollaex/hollaex-kit:$(cat .tags) - export DOCKER_CONTENT_TRUST=1 - mkdir $${HOME}/.docker/trust && mkdir $${HOME}/.docker/trust/private - - echo -n $${DOCKER_CONTENT_TRUST_PRIVATE_KEY} | base64 -d > $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key - - chmod 600 $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key - - docker trust key load $${HOME}/.docker/trust/private/88ce8696c017268731701ad17ae8b59dda7c31a3b750e986282c66c74ecb0d32.key --name bitholla-cicd + - echo -n $${DOCKER_CONTENT_TRUST_PRIVATE_KEY} | base64 -d > $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key + - chmod 600 $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key + - docker trust key load $${HOME}/.docker/trust/private/2aa7f2853b764c97de67db773c493d379ee655d7d78ff909d68c04a442fe3b69.key --name bitholla-cicd - docker trust sign hollaex/hollaex-kit:$(cat .tags) - name: docker_tagging_arm64v8_master @@ -239,6 +248,8 @@ steps: - export TZ=UTC-9 && export GIT_COMMIT_SHORT="$(echo $DRONE_COMMIT | cut -c 1-7)" && export PACKAGE_VERSION="$(cat version)" && echo " $PACKAGE_VERSION-arm64v8" > .tags - echo "Current Docker tag is :" && cat .tags - echo "dockerTag:$(cat .tags)" > .dockerTag.yml + when: + branch: master - name: docker_build_arm64v8 image: plugins/docker diff --git a/server/api/controllers/admin.js b/server/api/controllers/admin.js index c22a6274ce..5c6a311b32 100644 --- a/server/api/controllers/admin.js +++ b/server/api/controllers/admin.js @@ -4,13 +4,14 @@ const { loggerAdmin } = require('../../config/logger'); const toolsLib = require('hollaex-tools-lib'); const { cloneDeep, pick } = require('lodash'); const { all } = require('bluebird'); -const { ROLES } = require('../../constants'); +const { INIT_CHANNEL, ROLES } = require('../../constants'); const { USER_NOT_FOUND, API_KEY_NOT_PERMITTED, PROVIDE_VALID_EMAIL, INVALID_PASSWORD, USER_EXISTS } = require('../../messages'); const { sendEmail, testSendSMTPEmail, sendRawEmail } = require('../../mail'); const { MAILTYPE } = require('../../mail/strings'); const { errorMessageConverter } = require('../../utils/conversion'); const { isDate } = require('moment'); const { isEmail } = require('validator'); +const { publisher } = require('../../db/pubsub'); const crypto = require('crypto'); const VERIFY_STATUS = { @@ -112,7 +113,34 @@ const putAdminKit = (req, res) => { const getUsersAdmin = (req, res) => { loggerAdmin.verbose(req.uuid, 'controllers/admin/getUsers/auth', req.auth); - const { id, search, type, pending, pending_type, limit, page, order_by, order, start_date, end_date, format } = req.swagger.params; + const { + id, + search, + type, + pending, + pending_type, + limit, + page, + order_by, + order, + start_date, + end_date, + format, + email, + username, + full_name, + dob_start_date, + dob_end_date, + gender, + nationality, + verification_level, + email_verified, + otp_enabled, + phone_number, + kyc, + bank + + } = req.swagger.params; if (order_by.value && typeof order_by.value !== 'string') { loggerAdmin.error( @@ -140,6 +168,19 @@ const getUsersAdmin = (req, res) => { end_date: end_date.value, format: format.value, type: type.value, + email: email.value, + username: username.value, + full_name: full_name.value, + dob_start_date: dob_start_date.value, + dob_end_date: dob_end_date.value, + gender: gender.value, + nationality: nationality.value, + verification_level: verification_level.value, + email_verified: email_verified.value, + otp_enabled: otp_enabled.value, + phone_number: phone_number.value, + kyc: kyc.value, + bank: bank.value, additionalHeaders: { 'x-forwarded-for': req.headers['x-forwarded-for'] } @@ -441,7 +482,7 @@ const getAdminUserLogins = (req, res) => { 'controllers/admin/getAdminUserLogins/auth', req.auth ); - const { user_id, limit, page, start_date, order_by, order, end_date, format } = req.swagger.params; + const { user_id, status, limit, page, start_date, order_by, order, end_date, format } = req.swagger.params; if (start_date.value && !isDate(start_date.value)) { loggerAdmin.error( @@ -472,6 +513,7 @@ const getAdminUserLogins = (req, res) => { toolsLib.user.getUserLogins({ userId: user_id.value, + status: status.value, limit: limit.value, page: page.value, orderBy: order_by.value, @@ -2343,6 +2385,116 @@ const sendRawEmailByAdmin = (req, res) => { }); }; +const getUserSessionsByAdmin = (req, res) => { + loggerAdmin.verbose(req.uuid, 'controllers/admin/getUserSessionsByAdmin/auth', req.auth); + + const { user_id, status, limit, page, order_by, order, start_date, end_date, format } = req.swagger.params; + + if (order_by.value && typeof order_by.value !== 'string') { + loggerAdmin.error( + req.uuid, + 'controllers/admin/getUserSessionsByAdmin invalid order_by', + order_by.value + ); + return res.status(400).json({ message: 'Invalid order by' }); + } + + toolsLib.user.getExchangeUserSessions({ + user_id: user_id.value, + status: status.value, + limit: limit.value, + page: page.value, + order_by: order_by.value, + order: order.value, + start_date: start_date.value, + end_date: end_date.value, + format: format.value + } + ) + .then((data) => { + if (format.value === 'csv') { + res.setHeader('Content-disposition', `attachment; filename=${toolsLib.getKitConfig().api_name}-logins.csv`); + res.set('Content-Type', 'text/csv'); + return res.status(202).send(data); + } else { + return res.json(data); + } + }) + .catch((err) => { + loggerAdmin.error(req.uuid, 'controllers/admin/getUserSessionsByAdmin', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +}; + +const revokeUserSessionByAdmin = (req, res) => { + loggerAdmin.verbose(req.uuid, 'controllers/admin/revokeUserSessionByAdmin/auth', req.auth); + + const { session_id } = req.swagger.params.data.value; + + toolsLib.user.revokeExchangeUserSession(session_id) + .then((data) => { + return res.json(data); + }) + .catch((err) => { + loggerAdmin.error(req.uuid, 'controllers/admin/revokeUserSessionByAdmin', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +} + +const updateQuickTradeConfig = (req, res) => { + loggerAdmin.verbose(req.uuid, 'controllers/admin/updateQuickTradeConfig/auth', req.auth); + + const { symbol, type, active } = req.swagger.params.data.value; + + toolsLib.order.updateQuickTradeConfig({ symbol, active, type } + ) + .then((data) => { + publisher.publish(INIT_CHANNEL, JSON.stringify({ type: 'refreshInit' })); + return res.json(data); + }) + .catch((err) => { + loggerAdmin.error(req.uuid, 'controllers/admin/updateQuickTradeConfig', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +}; + +const getBalancesAdmin = (req, res) => { + loggerAdmin.verbose(req.uuid, 'controllers/admin/getBalancesAdmin/auth', req.auth); + + const { + user_id, + currency, + format + } = req.swagger.params; + + + if (format.value && req.auth.scopes.indexOf(ROLES.ADMIN) === -1) { + return res.status(403).json({ message: API_KEY_NOT_PERMITTED }); + } + + toolsLib.user.getAllBalancesAdmin({ + user_id: user_id.value, + currency: currency.value, + format: format.value, + additionalHeaders: { + 'x-forwarded-for': req.headers['x-forwarded-for'] + } + }) + .then((data) => { + if (format.value === 'all') { + res.setHeader('Content-disposition', `attachment; filename=${toolsLib.getKitConfig().api_name}-users.csv`); + res.set('Content-Type', 'text/csv'); + return res.status(202).send(data); + } else { + return res.json(data); + } + }) + .catch((err) => { + loggerAdmin.error(req.uuid, 'controllers/admin/getBalancesAdmin', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +} + module.exports = { createInitialAdmin, getAdminKit, @@ -2400,6 +2552,10 @@ module.exports = { createUserByAdmin, createUserWalletByAdmin, getWalletsByAdmin, + getUserSessionsByAdmin, + revokeUserSessionByAdmin, sendEmailByAdmin, - sendRawEmailByAdmin + sendRawEmailByAdmin, + updateQuickTradeConfig, + getBalancesAdmin }; diff --git a/server/api/controllers/broker.js b/server/api/controllers/broker.js index 1836c3906f..0ab004079a 100644 --- a/server/api/controllers/broker.js +++ b/server/api/controllers/broker.js @@ -6,38 +6,30 @@ const { publisher } = require('../../db/pubsub'); const toolsLib = require('hollaex-tools-lib'); const { errorMessageConverter } = require('../../utils/conversion'); -const getBrokerQuote = (req, res) => { +const getTrackedExchangeMarkets = (req, res) => { + loggerBroker.verbose( req.uuid, - 'controllers/broker/getBrokerQuote get', + 'controllers/broker/getTrackedExchangeMarkets get', req.auth ); - const bearerToken = req.headers['authorization']; - const ip = req.headers['x-real-ip']; - const { - symbol, - side + exchange_name } = req.swagger.params; - toolsLib.broker.fetchBrokerQuote({ - symbol: symbol.value, - side: side.value, - bearerToken, - ip - }) - .then((brokerQuote) => { - return res.json(brokerQuote); + toolsLib.broker.fetchTrackedExchangeMarkets(exchange_name.value) + .then((data) => { + return res.json(data); }) .catch((err) => { loggerBroker.error( req.uuid, - 'controllers/broker/getBrokerQuote err', + 'controllers/broker/getTrackedExchangeMarkets err', err.message ); return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); }); -}; +} const createBrokerPair = (req, res) => { loggerBroker.verbose( @@ -55,15 +47,12 @@ const createBrokerPair = (req, res) => { user_id, min_size, max_size, - increment_size, type, quote_expiry_time, rebalancing_symbol, account, formula, - exchange_name, spread, - multiplier } = req.swagger.params.data.value; loggerBroker.verbose( @@ -77,15 +66,12 @@ const createBrokerPair = (req, res) => { user_id, min_size, max_size, - increment_size, type, quote_expiry_time, rebalancing_symbol, account, formula, - exchange_name, spread, - multiplier ); toolsLib.broker.createBrokerPair({ @@ -96,15 +82,12 @@ const createBrokerPair = (req, res) => { user_id, min_size, max_size, - increment_size, type, quote_expiry_time, rebalancing_symbol, account, formula, - exchange_name, spread, - multiplier }) .then((data) => { publisher.publish(INIT_CHANNEL, JSON.stringify({ type: 'refreshInit' })); @@ -128,18 +111,12 @@ const testBroker = (req, res) => { const { formula, - exchange_name, spread, - multiplier, - symbol } = req.swagger.params.data.value; toolsLib.broker.testBroker({ formula, - exchange_name, spread, - multiplier, - symbol }) .then((data) => { return res.json(data); @@ -154,6 +131,7 @@ const testBroker = (req, res) => { }); }; + const testRebalance = (req, res) => { loggerBroker.verbose( req.uuid, @@ -198,7 +176,6 @@ function updateBrokerPair(req, res) { sell_price, min_size, max_size, - increment_size, paused, user_id, type, @@ -206,9 +183,7 @@ function updateBrokerPair(req, res) { rebalancing_symbol, account, formula, - exchange_name, - spread, - multiplier } = req.swagger.params.data.value; + spread } = req.swagger.params.data.value; loggerBroker.verbose( req.uuid, @@ -219,7 +194,6 @@ function updateBrokerPair(req, res) { sell_price, min_size, max_size, - increment_size, paused, user_id, type, @@ -227,9 +201,7 @@ function updateBrokerPair(req, res) { rebalancing_symbol, account, formula, - exchange_name, - spread, - multiplier + spread ); toolsLib.broker.updateBrokerPair(id, req.swagger.params.data.value) @@ -276,9 +248,6 @@ function getBrokerPairs(req, res) { req.auth ); - const bearerToken = req.headers['authorization']; - const ip = req.headers['x-real-ip']; - const attributes = [ 'id', 'user_id', @@ -288,14 +257,16 @@ function getBrokerPairs(req, res) { 'paused', 'min_size', 'max_size', - 'increment_size', 'type', 'quote_expiry_time', - 'rebalancing_symbol' + 'rebalancing_symbol', + 'account', + 'spread', + 'formula' ]; - toolsLib.broker.fetchBrokerPairs(attributes, bearerToken, ip) + toolsLib.broker.fetchBrokerPairs(attributes) .then((brokerPairs) => { return res.json(brokerPairs); }) @@ -310,45 +281,12 @@ function getBrokerPairs(req, res) { } -const executeBrokerDeal = (req, res) => { - loggerBroker.verbose( - req.uuid, - 'controllers/broker/executeBrokerDeal auth', - req.auth - ); - - const { token, size } = req.swagger.params.data.value; - - const userId = req.auth.sub.id; - - toolsLib.broker.executeBrokerDeal(userId, token, size) - .then((data) => { - loggerBroker.verbose( - req.uuid, - 'controllers/broker/executeBrokerDeal done', - data - ); - const { symbol, side, size, price } = data; - toolsLib.broker.reverseTransaction({ userId, symbol, side, size }); - res.json(data); - }) - .catch((err) => { - loggerBroker.error( - req.uuid, - 'controllers/broker/executeBrokerDeal err', - err.message - ); - return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); - }); -}; - module.exports = { - getBrokerQuote, testBroker, testRebalance, createBrokerPair, updateBrokerPair, deleteBrokerPair, getBrokerPairs, - executeBrokerDeal + getTrackedExchangeMarkets }; \ No newline at end of file diff --git a/server/api/controllers/deposit.js b/server/api/controllers/deposit.js index bfcc1b192c..3f4c95bc47 100644 --- a/server/api/controllers/deposit.js +++ b/server/api/controllers/deposit.js @@ -1,6 +1,7 @@ 'use strict'; const { loggerDeposits } = require('../../config/logger'); +const { ROLES } = require('../../constants'); const toolsLib = require('hollaex-tools-lib'); const { errorMessageConverter } = require('../../utils/conversion'); diff --git a/server/api/controllers/order.js b/server/api/controllers/order.js index 704c1b2d10..b4f8ba582b 100644 --- a/server/api/controllers/order.js +++ b/server/api/controllers/order.js @@ -115,6 +115,8 @@ const orderExecute = (req, res) => { toolsLib.order.executeUserOrder(user_id, opts, token) .then((result) => { + const { symbol, side, size } = result; + toolsLib.broker.reverseTransaction({ symbol, side, size }); return res.json(result); }) .catch((err) => { diff --git a/server/api/controllers/public.js b/server/api/controllers/public.js index 3abe51fcbf..670da7516c 100644 --- a/server/api/controllers/public.js +++ b/server/api/controllers/public.js @@ -27,6 +27,8 @@ const getConstants = (req, res) => { coins: toolsLib.getKitCoinsConfig(), pairs: toolsLib.getKitPairsConfig(), broker: toolsLib.getBrokerDeals(), + quicktrade: toolsLib.getQuickTrades(), + networkQuickTrades: toolsLib.getNetworkQuickTrades(), network: HOLLAEX_NETWORK_ENDPOINT }); } catch (err) { diff --git a/server/api/controllers/user.js b/server/api/controllers/user.js index c6bb4343da..f421b8549b 100644 --- a/server/api/controllers/user.js +++ b/server/api/controllers/user.js @@ -25,9 +25,11 @@ const { INVALID_PASSWORD, USER_EXISTS, USER_EMAIL_IS_VERIFIED, - INVALID_VERIFICATION_CODE + INVALID_VERIFICATION_CODE, + LOGIN_NOT_ALLOW, + NO_IP_FOUND } = require('../../messages'); -const { DEFAULT_ORDER_RISK_PERCENTAGE, EVENTS_CHANNEL, API_HOST, DOMAIN, TOKEN_TIME_NORMAL, TOKEN_TIME_LONG, HOLLAEX_NETWORK_BASE_URL } = require('../../constants'); +const { DEFAULT_ORDER_RISK_PERCENTAGE, EVENTS_CHANNEL, API_HOST, DOMAIN, TOKEN_TIME_NORMAL, TOKEN_TIME_LONG, HOLLAEX_NETWORK_BASE_URL, NUMBER_OF_ALLOWED_ATTEMPTS } = require('../../constants'); const { all } = require('bluebird'); const { each } = require('lodash'); const { publisher } = require('../../db/pubsub'); @@ -291,6 +293,16 @@ const verifyUser = (req, res) => { }); }; + + +const createAttemptMessage = (loginData) => { + const currentNumberOfAttemps = NUMBER_OF_ALLOWED_ATTEMPTS - loginData.attempt; + if (currentNumberOfAttemps === NUMBER_OF_ALLOWED_ATTEMPTS - 1) + { return '' } + else if(currentNumberOfAttemps === 0) return ' ' + LOGIN_NOT_ALLOW; + return ` You have ${currentNumberOfAttemps} more ${currentNumberOfAttemps === 1 ? 'attempt' : 'attempts'} left`; +} + const loginPost = (req, res) => { const { password, @@ -351,7 +363,7 @@ const loginPost = (req, res) => { .then(() => { return toolsLib.user.getUserByEmail(email); }) - .then((user) => { + .then(async (user) => { if (!user) { throw new Error(USER_NOT_FOUND); } @@ -363,14 +375,22 @@ const loginPost = (req, res) => { throw new Error(USER_NOT_ACTIVATED); } + const loginData = await toolsLib.user.findUserLatestLogin(user, false); + if (loginData && loginData.attempt === NUMBER_OF_ALLOWED_ATTEMPTS && loginData.status == false) { + throw new Error(LOGIN_NOT_ALLOW); + } + return all([ user, toolsLib.security.validatePassword(user.password, password) ]); }) - .then(([user, passwordIsValid]) => { + .then(async ([user, passwordIsValid]) => { if (!passwordIsValid) { - throw new Error(INVALID_CREDENTIALS); + await toolsLib.user.createUserLogin(user, ip, device, domain, origin, referer, null, long_term, false); + const loginData = await toolsLib.user.findUserLatestLogin(user, false); + const message = createAttemptMessage(loginData); + throw new Error(INVALID_CREDENTIALS + message); } if (!user.otp_enabled) { @@ -378,25 +398,20 @@ const loginPost = (req, res) => { } else { return all([ user, - toolsLib.security.verifyOtpBeforeAction(user.id, otp_code).then((validOtp) => { - if (!validOtp) { - throw new Error(INVALID_OTP_CODE); - } else { - return toolsLib.security.checkCaptcha(captcha, ip); - } + toolsLib.security.verifyOtpBeforeAction(user.id, otp_code) + .then(async () => { + return toolsLib.security.checkCaptcha(captcha, ip); + }) + .catch(async (err) => { + await toolsLib.user.createUserLogin(user, ip, device, domain, origin, referer, null, long_term, false); + const loginData = await toolsLib.user.findUserLatestLogin(user, false); + const message = createAttemptMessage(loginData); + throw new Error(err.message + message); }) ]); } }) .then(([user]) => { - if (ip) { - toolsLib.user.registerUserLogin(user.id, ip, { - device, - domain, - origin, - referer - }); - } const data = { ip, time, @@ -414,8 +429,10 @@ const loginPost = (req, res) => { if (!service) { sendEmail(MAILTYPE.LOGIN, email, data, user.settings, domain); } - return res.status(201).json({ - token: toolsLib.security.issueToken( + + return all([ + user, + toolsLib.security.issueToken( user.id, user.network_id, email, @@ -427,7 +444,14 @@ const loginPost = (req, res) => { user.is_communicator, long_term ? TOKEN_TIME_LONG : TOKEN_TIME_NORMAL ) - }); + ]) + }) + .then(async ([user, token]) => { + if (!ip) { + throw new Error(NO_IP_FOUND) + } + await toolsLib.user.createUserLogin(user, ip, device, domain, origin, referer, token, long_term, true); + return res.status(201).json({ token }); }) .catch((err) => { loggerUser.error(req.uuid, 'controllers/user/loginPost catch', err.message); @@ -632,7 +656,7 @@ const getUserLogins = (req, res) => { loggerUser.debug(req.uuid, 'controllers/user/getUserLogins auth', req.auth.sub); const user_id = req.auth.sub.id; - const { limit, page, order_by, order, start_date, end_date, format } = req.swagger.params; + const { limit, status, page, order_by, order, start_date, end_date, format } = req.swagger.params; if (start_date.value && !isDate(start_date.value)) { loggerUser.error( @@ -663,6 +687,7 @@ const getUserLogins = (req, res) => { toolsLib.user.getUserLogins({ userId: user_id, + status: status.value, limit: limit.value, page: page.value, orderBy: order_by.value, @@ -1113,6 +1138,87 @@ const addUserBank = (req, res) => { }); }; +const getUserSessions = (req, res) => { + loggerUser.verbose(req.uuid, 'controllers/user/getUserSessions/auth', req.auth); + + const { limit, status, page, order_by, order, start_date, end_date, format } = req.swagger.params; + + const user_id = req.auth.sub.id; + + if (order_by.value && typeof order_by.value !== 'string') { + loggerUser.error( + req.uuid, + 'controllers/user/getUserSessions invalid order_by', + order_by.value + ); + return res.status(400).json({ message: 'Invalid order by' }); + } + + toolsLib.user.getExchangeUserSessions({ + user_id: user_id, + status: status.value, + limit: limit.value, + page: page.value, + order_by: order_by.value, + order: order.value, + start_date: start_date.value, + end_date: end_date.value, + format: format.value + } + ) + .then((data) => { + if (format.value === 'csv') { + res.setHeader('Content-disposition', `attachment; filename=${toolsLib.getKitConfig().api_name}-logins.csv`); + res.set('Content-Type', 'text/csv'); + return res.status(202).send(data); + } else { + return res.json(data); + } + }) + .catch((err) => { + loggerUser.error(req.uuid, 'controllers/user/getUserSessions', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +}; + +const revokeUserSession = (req, res) => { + loggerUser.verbose(req.uuid, 'controllers/user/revokeUserSession/auth', req.auth); + + const { session_id } = req.swagger.params.data.value; + + const user_id = req.auth.sub.id; + + toolsLib.user.revokeExchangeUserSession(session_id, user_id) + .then((data) => { + return res.json(data); + }) + .catch((err) => { + loggerUser.error(req.uuid, 'controllers/user/revokeUserSession', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +} + +const userLogout = (req, res) => { + loggerUser.verbose(req.uuid, 'controllers/user/userLogout/auth', req.auth); + + const user_id = req.auth.sub.id; + + const bearer = req.headers['authorization']; + const tokenString = bearer.split(' ')[1]; + + toolsLib.security.findSession(tokenString) + .then((session) => { + return toolsLib.user.revokeExchangeUserSession(session.id, user_id); + }) + .then(() => { + return res.json({ message: 'Success' }); + }) + .catch((err) => { + loggerUser.error(req.uuid, 'controllers/user/userLogout', err.message); + return res.status(err.statusCode || 400).json({ message: errorMessageConverter(err) }); + }); +}; + module.exports = { signUpUser, getVerifyUser, @@ -1138,5 +1244,8 @@ module.exports = { getUserStats, userCheckTransaction, requestEmailConfirmation, - addUserBank + addUserBank, + revokeUserSession, + getUserSessions, + userLogout }; diff --git a/server/api/swagger/admin.yaml b/server/api/swagger/admin.yaml index ae4e263209..6aa1609d81 100644 --- a/server/api/swagger/admin.yaml +++ b/server/api/swagger/admin.yaml @@ -1139,6 +1139,65 @@ paths: required: false type: string format: date-time + - in: query + name: email + required: false + type: string + maxLength: 256 + - in: query + name: username + required: false + type: string + maxLength: 256 + - in: query + name: full_name + required: false + type: string + maxLength: 256 + - in: query + name: dob_start_date + required: false + type: string + format: date-time + - in: query + name: dob_end_date + required: false + type: string + format: date-time + - in: query + name: gender + required: false + type: boolean + - in: query + name: nationality + required: false + type: string + maxLength: 256 + - in: query + name: phone_number + required: false + type: string + maxLength: 256 + - in: query + name: verification_level + required: false + type: number + - in: query + name: email_verified + required: false + type: boolean + - in: query + name: otp_enabled + required: false + type: boolean + - in: query + name: kyc + required: false + type: integer + - in: query + name: bank + required: false + type: integer - in: query name: format description: Specify data format @@ -1612,6 +1671,11 @@ paths: required: false type: number format: int32 + - in: query + name: status + description: fetch successful or failed logins + required: false + type: boolean - in: query name: limit description: "Number of elements to return. Default: 50. Maximun: 100" @@ -2969,4 +3033,202 @@ paths: x-security-scopes: - admin x-token-permissions: - - can_withdraw \ No newline at end of file + - can_withdraw + /admin/user/sessions: + x-swagger-router-controller: admin + get: + description: Get user sessions for admin + operationId: getUserSessionsByAdmin + parameters: + - in: query + name: user_id + description: User id + required: false + type: number + format: int32 + - in: query + name: status + description: fetch active or revoke sessions + required: false + type: boolean + - in: query + name: limit + description: "Number of elements to return. Default: 50. Maximun: 100" + required: false + type: number + format: int32 + - in: query + name: page + description: Page of data to retrieve + required: false + type: number + format: int32 + - in: query + name: order_by + description: Field to order data + required: false + type: string + - in: query + name: order + description: direction to order + required: false + type: string + enum: ['asc', 'desc'] + - in: query + name: start_date + description: Starting date of queried data + required: false + type: string + format: date-time + - in: query + name: end_date + description: Ending date of queried data + required: false + type: string + format: date-time + - in: query + name: format + description: Specify data format + required: false + enum: ['csv', 'all'] + type: string + tags: + - Admin + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + 202: + description: CSV + schema: + type: string + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - admin + /admin/user/revoke-session: + x-swagger-router-controller: admin + post: + description: Revoke user session By admin + operationId: revokeUserSessionByAdmin + tags: + - Admin + parameters: + - name: data + in: body + required: true + schema: + type: object + required: + - session_id + properties: + session_id: + type: number + format: int32 + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - admin + /admin/quicktrade/config: + x-swagger-router-controller: admin + put: + description: Update user quick trade config for admin + operationId: updateQuickTradeConfig + tags: + - Admin + parameters: + - name: data + in: body + required: true + schema: + type: object + required: + - symbol + properties: + symbol: + type: string + type: + type: string + enum: ['pro', 'broker', 'network'] + active: + type: boolean + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - admin + /admin/balances: + x-swagger-router-controller: admin + get: + description: Get exchange balances of users for admin + operationId: getBalancesAdmin + tags: + - Admin + parameters: + - name: user_id + in: query + required: false + type: number + - name: currency + in: query + required: false + type: string + - in: query + name: format + description: Specify data format + required: false + enum: ['csv', 'all'] + type: string + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + 202: + description: CSV + schema: + type: string + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - admin + x-token-permissions: + - can_read \ No newline at end of file diff --git a/server/api/swagger/broker.yaml b/server/api/swagger/broker.yaml index 6d06664c8e..7d64206a9f 100644 --- a/server/api/swagger/broker.yaml +++ b/server/api/swagger/broker.yaml @@ -11,7 +11,7 @@ paths: in: body required: true schema: - $ref: "#/definitions/BrokerPairCreate" + $ref: "#/definitions/BrokerPair" responses: 200: description: Success @@ -74,6 +74,12 @@ paths: description: Error schema: $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + x-security-scopes: + - admin delete: operationId: deleteBrokerPair description: Delete a broker deal @@ -100,34 +106,27 @@ paths: - bearer x-security-scopes: - admin - /broker/execute: + /broker/markets: x-swagger-router-controller: broker - post: - operationId: executeBrokerDeal - description: Execute a broker deal + get: + operationId: getTrackedExchangeMarkets + description: Get tracked exchange markets tags: - Broker parameters: - - name: data - in: body + - in: query + name: exchange_name + description: exchange name required: true - schema: - type: object - properties: - token: - type: string - maxLength: 256 - size: - type: number - format: double - required: - - token - - size + type: string + maxLength: 256 responses: 200: description: Success schema: - $ref: "#/definitions/ObjectResponse" + type: array + items: + type: object default: description: Error schema: @@ -137,36 +136,7 @@ paths: x-security-types: - bearer x-security-scopes: - - user - /broker/quote: - x-swagger-router-controller: broker - get: - operationId: getBrokerQuote - description: Get Quote Currency - tags: - - Broker - parameters: - - in: query - name: symbol - description: Currency symbol - required: true - type: string - maxLength: 256 - - in: query - name: side - description: buy or sell - required: true - type: string - enum: ['buy', 'sell'] - responses: - 200: - description: Success - schema: - $ref: "#/definitions/ObjectResponse" - default: - description: Error - schema: - $ref: "#/definitions/MessageResponse" + - admin /broker/test: x-swagger-router-controller: broker post: @@ -181,19 +151,14 @@ paths: schema: type: object properties: - formula: - type: string - maxLength: 256 - exchange_name: - type: string - maxLength: 256 - multiplier: - type: number spread: type: number - symbol: + increment_size: + type: number + format: double + formula: type: string - maxLength: 256 + maxLength: 1024 responses: 200: description: Success diff --git a/server/api/swagger/definitions.yaml b/server/api/swagger/definitions.yaml index 8ba3981b27..a54a9d08c7 100644 --- a/server/api/swagger/definitions.yaml +++ b/server/api/swagger/definitions.yaml @@ -1466,13 +1466,8 @@ definitions: type: ['object', 'null'] formula: type: ['string', 'null'] - exchange_name: - type: string - maxLength: 256 spread: type: number - multiplier: - type: number BrokerPairCreate: type: object required: @@ -1514,13 +1509,8 @@ definitions: formula: type: string maxLength: 256 - exchange_name: - type: string - maxLength: 256 spread: type: number - multiplier: - type: number BrokerPairUpdate: allOf: - $ref: "#/definitions/BrokerPair" diff --git a/server/api/swagger/swagger.js b/server/api/swagger/swagger.js index 228470efe7..a63291a6d3 100644 --- a/server/api/swagger/swagger.js +++ b/server/api/swagger/swagger.js @@ -4,7 +4,7 @@ const definition = { swagger: '2.0', info: { title: 'HollaEx Kit', - version: '2.6.6' + version: '2.7.0' }, host: 'api.hollaex.com', basePath: '/v2', diff --git a/server/api/swagger/user.yaml b/server/api/swagger/user.yaml index aa4216bbc6..f8d620246e 100644 --- a/server/api/swagger/user.yaml +++ b/server/api/swagger/user.yaml @@ -151,6 +151,11 @@ paths: required: false type: number format: int32 + - in: query + name: status + description: fetch successful or failed logins + required: false + type: boolean - in: query name: page description: Page of data to retrieve @@ -477,6 +482,115 @@ paths: - bearer x-security-scopes: - user + /user/sessions: + x-swagger-router-controller: user + get: + description: Get user sessions + operationId: getUserSessions + parameters: + - in: query + name: limit + description: "Number of elements to return. Default: 50. Maximun: 100" + required: false + type: number + format: int32 + - in: query + name: status + description: fetch active or revoke sessions + required: false + type: boolean + - in: query + name: page + description: Page of data to retrieve + required: false + type: number + format: int32 + - in: query + name: order_by + description: Field to order data + required: false + type: string + - in: query + name: order + description: direction to order + required: false + type: string + enum: ['asc', 'desc'] + - in: query + name: start_date + description: Starting date of queried data + required: false + type: string + format: date-time + - in: query + name: end_date + description: Ending date of queried data + required: false + type: string + format: date-time + - in: query + name: format + description: Specify data format + required: false + enum: ['csv', 'all'] + type: string + tags: + - User + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + 202: + description: CSV + schema: + type: string + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - user + /user/revoke-session: + x-swagger-router-controller: user + post: + description: Revoke user session + operationId: revokeUserSession + tags: + - User + parameters: + - name: data + in: body + required: true + schema: + type: object + required: + - session_id + properties: + session_id: + type: number + format: int32 + responses: + 200: + description: Success + schema: + $ref: "#/definitions/ObjectResponse" + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + - hmac + x-security-scopes: + - user /user/balance: x-swagger-router-controller: user get: @@ -1199,4 +1313,25 @@ paths: - bearer x-security-scopes: - user - \ No newline at end of file + /logout: + x-swagger-router-controller: user + get: + operationId: userLogout + description: Logout and revoke the user session + tags: + - User + responses: + 200: + description: Success + schema: + $ref: "#/definitions/MessageResponse" + default: + description: Error + schema: + $ref: "#/definitions/MessageResponse" + security: + - Token: [] + x-security-types: + - bearer + x-security-scopes: + - user \ No newline at end of file diff --git a/server/constants.js b/server/constants.js index c6b30bb66b..02b000f4a6 100644 --- a/server/constants.js +++ b/server/constants.js @@ -157,6 +157,8 @@ exports.GET_KIT_SECRETS = () => cloneDeep(secrets); exports.GET_FROZEN_USERS = () => cloneDeep(frozenUsers); exports.GET_EMAIL = () => cloneDeep(configuration.email); exports.GET_BROKER = () => cloneDeep(configuration.broker); +exports.GET_QUICKTRADE = () => cloneDeep(configuration.quicktrade); +exports.GET_NETWORK_QUICKTRADE = () => cloneDeep(configuration.networkQuickTrades); exports.USER_META_KEYS = [ 'description', @@ -336,17 +338,21 @@ const ROLES = { }; exports.DEFAULT_FEES = { - zero: { - maker: 0.2, - taker: 0.2 + fiat: { + maker: 0, + taker: 0 }, - lite: { + boost: { + maker: 0, + taker: 0 + }, + crypto: { maker: 0.05, taker: 0.1 }, - member: { - maker: 0, - taker: 0 + basic: { + maker: 0.2, + taker: 0.2 } }; @@ -605,6 +611,28 @@ exports.VERIFY_STATUS = { }; // PLUGIN CONSTANTS END ------------------------------ to be moved +// Login timeout START------------------------------ +exports.LOGIN_TIME_OUT = 1000 * 5 * 60; +exports.NUMBER_OF_ALLOWED_ATTEMPTS = 5; +// Login timeout END------------------------------ + +// BROKER CONSTANTS START + +exports.EXCHANGE_PLAN_INTERVAL_TIME = { + crypto: 5, + fiat: 5, + boost: 60 +}; +exports.EXCHANGE_PLAN_PRICE_SOURCE = { + fiat: ['hollaex', 'oracle', 'binance', 'bitfinex', 'coinbase', 'kraken', 'uniswap'], + boost: ['hollaex', 'oracle', 'binance', 'bitfinex', 'coinbase', 'kraken', 'uniswap'], + crypto: ['hollaex', 'oracle', 'binance'], + ALL: [ 'hollaex', 'oracle', 'binance', 'bitfinex', 'coinbase', 'kraken', 'uniswap'] +}; + + +// BROKER CONSTANTS END + exports.CUSTOM_CSS = ` .topbar-wrapper img { content:url('${exports.GET_KIT_CONFIG().logo_image}}'); diff --git a/server/db/migrations/20230422073930-create-session.js b/server/db/migrations/20230422073930-create-session.js new file mode 100644 index 0000000000..8102018ac8 --- /dev/null +++ b/server/db/migrations/20230422073930-create-session.js @@ -0,0 +1,57 @@ +'use strict'; +const { ROLES } = require('../../constants'); +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Sessions', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + token: { + type: Sequelize.STRING(1000), + allowNull: false + }, + login_id: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: 'Logins', + key: 'id' + } + }, + status: { + type: Sequelize.BOOLEAN, + allowNull: false + }, + last_seen: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('NOW()') + }, + expiry_date: { + type: Sequelize.DATE, + allowNull: false + }, + role: { + type: Sequelize.STRING, + allowNull: false, + defaultValue: ROLES.USER + }, + created_at: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('NOW()') + }, + updated_at: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('NOW()') + } + }, { + underscored: true + }); + }, + down: (queryInterface) => queryInterface.dropTable('Sessions') +}; diff --git a/server/db/migrations/20230422073933-update-login.js b/server/db/migrations/20230422073933-update-login.js new file mode 100644 index 0000000000..ab8a6b345f --- /dev/null +++ b/server/db/migrations/20230422073933-update-login.js @@ -0,0 +1,41 @@ +'use strict'; + +const TABLE = 'Logins'; + +module.exports = { + up: (queryInterface, Sequelize) => + Promise.all([ + queryInterface.addColumn(TABLE, 'attempt', { + type: Sequelize.INTEGER, + allowNull: true, + defaultValue: 0 + }), + queryInterface.addColumn(TABLE, 'status', { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: true + }), + queryInterface.addColumn(TABLE, 'country', { + type: Sequelize.STRING, + allowNull: true + }), + queryInterface.addColumn(TABLE, 'updated_at', { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('NOW()') + }), + queryInterface.addColumn(TABLE, 'created_at', { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('NOW()') + }), + ]), + down: (queryInterface) => + Promise.all([ + queryInterface.removeColumn(TABLE, 'attempt'), + queryInterface.removeColumn(TABLE, 'status'), + queryInterface.removeColumn(TABLE, 'country'), + queryInterface.removeColumn(TABLE, 'updated_at'), + queryInterface.removeColumn(TABLE, 'created_at'), + ]) +}; diff --git a/server/db/migrations/20230525045574-add-dynamic-broker.js b/server/db/migrations/20230525045574-add-dynamic-broker.js new file mode 100644 index 0000000000..4b4877dd37 --- /dev/null +++ b/server/db/migrations/20230525045574-add-dynamic-broker.js @@ -0,0 +1,29 @@ +'use strict'; + +const TABLE = 'Brokers'; + +module.exports = { + async up(queryInterface, Sequelize) { + return Promise.all([ + queryInterface + .addColumn(TABLE, 'spread', { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: true + }), + queryInterface + .addColumn(TABLE, 'refresh_interval', { + type: Sequelize.INTEGER, + allowNull: true + }) + ]); + + }, + + async down(queryInterface, Sequelize) { + return Promise.all([ + queryInterface.removeColumn(TABLE, 'spread'), + queryInterface.removeColumn(TABLE, 'refresh_interval'), + ]); + } +}; diff --git a/server/db/migrations/20230617100526-create-quicktrade.js b/server/db/migrations/20230617100526-create-quicktrade.js new file mode 100644 index 0000000000..67d5f74a19 --- /dev/null +++ b/server/db/migrations/20230617100526-create-quicktrade.js @@ -0,0 +1,45 @@ +'use strict'; + +const TABLE_NAME = 'QuickTrades'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable(TABLE_NAME, { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + symbol: { + type: Sequelize.STRING, + unique: true, + allowNull: false, + }, + type: { + type: Sequelize.STRING, + allowNull: true, + }, + active: { + type: Sequelize.BOOLEAN, + defaultValue: true, + allowNull: false, + }, + created_at: { + allowNull: false, + type: Sequelize.DATE, + defaultValue: Sequelize.literal('NOW()') + }, + updated_at: { + allowNull: false, + type: Sequelize.DATE, + defaultValue: Sequelize.literal('NOW()') + } + }, + { + timestamps: true, + underscored: true + }); + }, + down: (queryInterface) => queryInterface.dropTable(TABLE_NAME) +}; \ No newline at end of file diff --git a/server/db/migrations/20230617100527-add-broker-unique.js b/server/db/migrations/20230617100527-add-broker-unique.js new file mode 100644 index 0000000000..3312d39d53 --- /dev/null +++ b/server/db/migrations/20230617100527-add-broker-unique.js @@ -0,0 +1,19 @@ +'use strict'; + +const TABLE = 'Brokers'; +const COLUMN = 'symbol'; + +module.exports = { + up: (queryInterface, Sequelize) => + queryInterface.changeColumn(TABLE, COLUMN, { + type: Sequelize.STRING, + allowNull: false, + unique: true, + }), + down: (queryInterface, Sequelize) => + queryInterface.changeColumn(TABLE, COLUMN, { + type: Sequelize.STRING, + allowNull: false, + unique: false, + }) +}; \ No newline at end of file diff --git a/server/db/migrations/20230628100835-remove-broker-increment-size.js b/server/db/migrations/20230628100835-remove-broker-increment-size.js new file mode 100644 index 0000000000..7d5ccb9c3f --- /dev/null +++ b/server/db/migrations/20230628100835-remove-broker-increment-size.js @@ -0,0 +1,14 @@ +'use strict'; + +const TABLE = 'Brokers'; +const COLUMN = 'increment_size'; + +module.exports = { + up: (queryInterface, Sequelize) => + queryInterface.removeColumn(TABLE, COLUMN), + down: (queryInterface, Sequelize) => + queryInterface.addColumn(TABLE, COLUMN, { + type: Sequelize.DOUBLE, + allowNull: false + }) +}; \ No newline at end of file diff --git a/server/db/models/broker.js b/server/db/models/broker.js index 9564492fae..56ef3f6de7 100644 --- a/server/db/models/broker.js +++ b/server/db/models/broker.js @@ -13,6 +13,7 @@ module.exports = function (sequelize, DataTypes) { symbol: { type: DataTypes.STRING, allowNull: false, + unique: true }, buy_price: { type: DataTypes.DOUBLE, @@ -27,6 +28,7 @@ module.exports = function (sequelize, DataTypes) { paused: { type: DataTypes.BOOLEAN, allowNull: false, + defaultValue: false }, user_id: { type: DataTypes.INTEGER, @@ -45,10 +47,6 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.DOUBLE, allowNull: false }, - increment_size: { - type: DataTypes.DOUBLE, - allowNull: false - }, type: { type: DataTypes.ENUM('manual', 'dynamic'), defaultValue: 'manual', @@ -59,10 +57,20 @@ module.exports = function (sequelize, DataTypes) { defaultValue: 30, allowNull: true }, + spread: { + type: DataTypes.INTEGER, + defaultValue: 0, + allowNull: true + }, rebalancing_symbol: { type: DataTypes.STRING, allowNull: true, }, + refresh_interval: { + type: DataTypes.INTEGER, + defaultValue: 0, + allowNull: true + }, account: { type: DataTypes.JSONB, allowNull: true, diff --git a/server/db/models/index.js b/server/db/models/index.js index d2d1d641d3..935e7dae58 100644 --- a/server/db/models/index.js +++ b/server/db/models/index.js @@ -42,6 +42,10 @@ model = require(path.join(__dirname, './plugin'))(sequelize, Sequelize.DataTypes db[model.name] = model; model = require(path.join(__dirname, './broker'))(sequelize, Sequelize.DataTypes); db[model.name] = model; +model = require(path.join(__dirname, './session'))(sequelize, Sequelize.DataTypes); +db[model.name] = model; +model = require(path.join(__dirname, './quickTrade'))(sequelize, Sequelize.DataTypes); +db[model.name] = model; Object.keys(db).forEach(function (modelName) { if ('associate' in db[modelName]) { diff --git a/server/db/models/login.js b/server/db/models/login.js index e44bfce6e6..43ef7257b9 100644 --- a/server/db/models/login.js +++ b/server/db/models/login.js @@ -27,6 +27,21 @@ module.exports = function (sequelize, DataTypes) { allowNull: true, defaultValue: '' }, + attempt: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + status: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true + }, + country: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: '' + }, timestamp: { type: DataTypes.DATE, allowNull: false, @@ -46,6 +61,7 @@ module.exports = function (sequelize, DataTypes) { foreignKey: 'user_id', targetKey: 'id' }); + Login.hasOne(models.Session); }; return Login; diff --git a/server/db/models/quickTrade.js b/server/db/models/quickTrade.js new file mode 100644 index 0000000000..b4f199fa7f --- /dev/null +++ b/server/db/models/quickTrade.js @@ -0,0 +1,35 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const QuickTrade = sequelize.define( + 'QuickTrade', + { + id: { + type: DataTypes.INTEGER, + allowNull: false, + autoIncrement: true, + primaryKey: true, + }, + symbol: { + type: DataTypes.STRING, + allowNull: false, + }, + type: { + type: DataTypes.STRING, + allowNull: true, + }, + active: { + type: DataTypes.BOOLEAN, + defaultValue: true, + allowNull: false, + } + }, + { + timestamps: true, + underscored: true, + tableName: 'QuickTrades' + } + ); + + return QuickTrade; +}; diff --git a/server/db/models/session.js b/server/db/models/session.js new file mode 100644 index 0000000000..397cfc0f8c --- /dev/null +++ b/server/db/models/session.js @@ -0,0 +1,54 @@ +'use strict'; +const { ROLES } = require('../../constants'); + +module.exports = function (sequelize, DataTypes) { + const Session = sequelize.define( + 'Session', + { + token: { + type: DataTypes.STRING(1000), + allowNull: false + }, + login_id: { + type: DataTypes.INTEGER, + onDelete: 'CASCADE', + allowNull: false, + references: { + model: 'Logins', + key: 'id' + } + }, + status: { + type: DataTypes.BOOLEAN, + allowNull: false + }, + last_seen: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.NOW + }, + expiry_date: { + type: DataTypes.DATE, + allowNull: false + }, + role: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: ROLES.USER + } + }, + { + underscored: true, + tableName: 'Sessions' + } + ); + Session.associate = (models) => { + Session.belongsTo(models.Login, { + as: 'login', + foreignKey: 'login_id', + targetKey: 'id', + onDelete: 'CASCADE' + }); + }; + return Session; +}; diff --git a/server/db/seeders/20201014074533-add-tiers.js b/server/db/seeders/20201014074533-add-tiers.js index 26d9488492..6139edc117 100644 --- a/server/db/seeders/20201014074533-add-tiers.js +++ b/server/db/seeders/20201014074533-add-tiers.js @@ -30,7 +30,7 @@ module.exports = { return checkActivation(process.env.ACTIVATION_CODE) .then((exchange) => { - const minFees = DEFAULT_FEES[exchange.collateral_level]; + const minFees = DEFAULT_FEES[exchange.plan]; const fees = { maker: {}, taker: {} diff --git a/server/eslintrc.json b/server/eslintrc.json index 63223d811c..6e2e943f2f 100644 --- a/server/eslintrc.json +++ b/server/eslintrc.json @@ -8,7 +8,7 @@ }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 9, + "ecmaVersion": 2020, "sourceType": "module" }, "plugins": ["unused-imports"], diff --git a/server/init.js b/server/init.js index a28ce32341..866021e982 100644 --- a/server/init.js +++ b/server/init.js @@ -6,7 +6,7 @@ const moment = require('moment'); const rp = require('request-promise'); const { loggerInit } = require('./config/logger'); const { Op } = require('sequelize'); -const { User, Status, Tier, Broker } = require('./db/models'); +const { User, Status, Tier, Broker, QuickTrade } = require('./db/models'); const packageJson = require('./package.json'); const { subscriber, publisher } = require('./db/pubsub'); @@ -52,6 +52,8 @@ const checkStatus = () => { coins: {}, pairs: {}, tiers: {}, + quicktrade: [], + networkQuickTrades: [], kit: { info: {}, color: {}, @@ -123,12 +125,13 @@ const checkStatus = () => { status.constants ), Tier.findAll(), - Broker.findAll(), + Broker.findAll({ attributes: ['id', 'symbol', 'buy_price', 'sell_price', 'paused', 'min_size', 'max_size']}), + QuickTrade.findAll(), status.dataValues ]); } }) - .then(async ([exchange, tiers, deals, status]) => { + .then(async ([exchange, tiers, deals, quickTrades, status]) => { loggerInit.info('init/checkStatus/activation', exchange.name, exchange.active); const exchangePairs = []; @@ -143,23 +146,94 @@ const checkStatus = () => { } configuration.broker = deals; + configuration.networkQuickTrades = Object.values(exchange.brokers); + const brokerPairs = deals.map((d) => d.symbol); + const networkBrokerPairs = Object.keys(exchange.brokers).filter((e) => { + // only add the network pair if both coins in the market are already subscribed in the exchange + const [ base, quote ] = e.split('-'); + if (configuration.coins[base] && configuration.coins[quote]) { + return e; + } + }); + let quickTradePairs = quickTrades.map((q) => q.symbol) + + // check the status of quickTrades + for (let qt of quickTrades) { + if (qt.type === 'pro') { + if (!configuration.pairs[qt.symbol]) { + await qt.destroy(); + } + } + else if (qt.type === 'broker') { + if (!brokerPairs.includes(qt.symbol)) { + await qt.destroy(); + } + } + else if (qt.type === 'network') { + if (!networkBrokerPairs.includes(qt.symbol)) { + await qt.destroy(); + } + } + } + + // construct the missing quicktrades + let newQuickTrades = {}; + difference(exchangePairs, quickTradePairs).forEach((symbol) => { + newQuickTrades[symbol] = { symbol, type: 'pro' }; + }); + difference(brokerPairs, quickTradePairs).forEach((symbol) => { + // it would override the symbol in the previous condition + newQuickTrades[symbol] = { symbol, type: 'broker' }; + }); + difference(networkBrokerPairs, quickTradePairs).forEach((symbol) => { + // it would override the symbol in the previous conditions + newQuickTrades[symbol] = { symbol, type: 'network' }; + }); + + if (Object.keys(newQuickTrades).length > 0) { + for (let quicktrade in newQuickTrades) { + loggerInit.info('init/checkStatus/activation adding new pair', quicktrade); + await QuickTrade.upsert(newQuickTrades[quicktrade]); + loggerInit.info('init/checkStatus/activation new pair successfully added', quicktrade); + } + } + + quickTrades = await QuickTrade.findAll(); + quickTradePairs = quickTrades.map((q) => q.symbol); + + // build the data for client + quickTrades.forEach((qt) => { + let item = { + type: qt.type, + symbol: qt.symbol, + active: qt.active + }; + configuration.quicktrade.push(item) + }) + + for (let tier of tiers) { - const makerDiff = difference(exchangePairs, Object.keys(tier.fees.maker)); - const takerDiff = difference(exchangePairs, Object.keys(tier.fees.taker)); - const brokerDiff = difference(deals.map((d) => d.symbol), Object.keys(tier.fees.maker)); + if (!('maker' in tier.fees)) { + tier.fees.maker = {}; + } + if (!('taker' in tier.fees)) { + tier.fees.taker = {}; + } + const makerDiff = difference(quickTradePairs, Object.keys(tier.fees.maker)); + const takerDiff = difference(quickTradePairs, Object.keys(tier.fees.taker)); - if (makerDiff.length > 0 || takerDiff.length > 0 || brokerDiff.length > 0 || isNumber(tier.fees.maker.default) || isNumber(tier.fees.taker.default)) { + if (makerDiff.length > 0 || takerDiff.length > 0) { const fees = { maker: {}, taker: {} }; + console.log(DEFAULT_FEES[exchange.plan]) + const defaultFees = DEFAULT_FEES[exchange.plan] + ? DEFAULT_FEES[exchange.plan] + : { maker: 0.2, taker: 0.2 } - const defaultFees = exchange.type === 'Enterprise' - ? { maker: 0, taker: 0 } - : DEFAULT_FEES[exchange.collateral_level]; - - for (let pair of exchangePairs) { + for (let pair of quickTradePairs) { if (!isNumber(tier.fees.maker[pair])) { fees.maker[pair] = defaultFees.maker; } else { @@ -172,23 +246,6 @@ const checkStatus = () => { fees.taker[pair] = tier.fees.taker[pair]; } } - for (let deal of deals) { - const pair = deal.symbol; - // checking if the deal is already among the pairs - if (!exchangePairs.find((e) => e.name === pair)) { - if (!isNumber(tier.fees.maker[pair])) { - fees.maker[pair] = defaultFees.maker; - } else { - fees.maker[pair] = tier.fees.maker[pair]; - } - - if (!isNumber(tier.fees.taker[pair])) { - fees.taker[pair] = defaultFees.taker; - } else { - fees.taker[pair] = tier.fees.taker[pair]; - } - } - } const t = await tier.update({ fees }, { fields: ['fees'] }); diff --git a/server/messages.js b/server/messages.js index c3b6cfda21..cbbb4616b3 100644 --- a/server/messages.js +++ b/server/messages.js @@ -12,7 +12,7 @@ exports.USER_NOT_VERIFIED = 'User is not verified'; exports.USER_NOT_ACTIVATED = 'User is not activated'; exports.USER_EXISTS = 'User already exists'; exports.USER_REGISTERED = 'User successfully registered'; -exports.INVALID_CREDENTIALS = 'Credentials incorrect'; +exports.INVALID_CREDENTIALS = 'Incorrect credentials.'; exports.USER_VERIFIED = 'User is now verified'; exports.INVALID_PASSWORD = 'Invalid password. It has to contain at least 8 characters, at least one digit and one character.'; @@ -196,10 +196,30 @@ exports.BROKER_ERROR_DELETE_UNPAUSED = 'Broker pair could not be deleted while u exports.BROKER_EXISTS = 'A deal for this symbol alreadys exists'; exports.BROKER_FORMULA_NOT_FOUND = 'Broker formula not found'; exports.SPREAD_MISSING = 'Spread is missing'; +exports.REBALANCE_SYMBOL_MISSING = 'Rebalance symbol for hedge account is missing'; exports.MANUAL_BROKER_CREATE_ERROR = 'Manual broker cannot select an exchange'; +exports.DYNAMIC_BROKER_CREATE_ERROR = 'Cannot create a dynamic broker without required fields'; +exports.DYNAMIC_BROKER_UNSUPPORTED = 'Selected exchange is not supported by your exchange plan'; +exports.DYNAMIC_BROKER_EXCHANGE_PLAN_ERROR = 'Cannot create a dynamic broker with Basic plan'; exports.EXCHANGE_NOT_FOUND = 'Exchange not found'; exports.SYMBOL_NOT_FOUND = 'Symbol not found'; exports.INVALID_TOKEN_TYPE = 'invalid token type'; exports.NO_AUTH_TOKEN = 'no auth token sent'; exports.WHITELIST_DISABLE_ADMIN = 'Admin cannot disable whitelisting feature'; exports.WHITELIST_NOT_PROVIDED = 'Admin needs to provide whitelisted IP(s)'; +exports.SESSION_NOT_FOUND = 'Session not found'; +exports.SESSION_ALREADY_REVOKED = 'Session already revoked'; +exports.WRONG_USER_SESSION = 'this session does not belong to you'; +exports.LOGIN_NOT_ALLOW = 'You attempted to login too many times, please wait for a while to try again'; +exports.UNISWAP_PRICE_NOT_FOUND = 'Uniswap could not find price for this pair'; +exports.FORMULA_MARKET_PAIR_ERROR = 'Market pair(s) in the formula is in wrong format'; +exports.FAIR_PRICE_BROKER_ERROR = 'Order not executed, Price abnormality detected'; +exports.COIN_INPUT_MISSING = 'Coin inputs are missing'; +exports.AMOUNTS_MISSING = 'Coin amount inputs are missing'; +exports.AMOUNT_NEGATIVE_ERROR = 'Amount cannot be negative'; +exports.QUICK_TRADE_CONFIG_NOT_FOUND = 'Quick trade config not found'; +exports.QUICK_TRADE_TYPE_NOT_SUPPORTED = 'Quick trade type not supported'; +exports.PRICE_NOT_FOUND = 'Price could not found'; +exports.INVALID_PRICE = 'Invalid price'; +exports.INVALID_SIZE = 'Invalid size'; +exports.NO_IP_FOUND = 'Request can not be processed'; \ No newline at end of file diff --git a/server/package.json b/server/package.json index ccc56bb02c..28890e46d6 100644 --- a/server/package.json +++ b/server/package.json @@ -1,5 +1,5 @@ { - "version": "2.6.6", + "version": "2.7.0", "private": false, "description": "HollaEx Kit", "keywords": [ diff --git a/server/test/broker/broker-test.js b/server/test/broker/broker-test.js new file mode 100644 index 0000000000..80857d9482 --- /dev/null +++ b/server/test/broker/broker-test.js @@ -0,0 +1,273 @@ +const { + request, + getAdminUser, + loginAs, +} = require('../helpers'); +const assert = require('assert'); +const tools = require('hollaex-tools-lib'); + +describe('Dynamic Pricing', async () => { + let user, bearerToken, quoteData, createdBroker; + before(async () => { + user = await tools.user.getUserByEmail(getAdminUser().email); + user.should.be.an('object'); + bearerToken = await loginAs(user); + bearerToken.should.be.a('string'); + }); + + it('should create a dynamic broker', async () => { + const response = await request() + .post(`/v2/broker/`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + symbol: 'xht-usdt', + buy_price: 0.25, + sell_price: 0.25, + paused: false, + user_id: 1, + min_size: 1, + max_size: 10, + increment_size: 0.0001, + type: 'dynamic', + quote_expiry_time: 30, + formula: 'binance_btc-usdt', + spread: 1, + account: { + binance: { + apiKey: '1a3321381e9f2e8342449936bb0e5e0590435', + apiSecret: '93284092345543534435305905694646745645' + }, + }, + }); + createdBroker = response.body; + response.should.have.status(200); + response.should.be.json; + + assert.equal(createdBroker.symbol, 'xht-usdt', 'wrong symbol'); + assert.equal(createdBroker.type, 'dynamic', 'wrong type'); + + }); + + it('should not validate wrong formula format -1', async () => { + // server should check the keys in an object that client sends + //if one key is missing it should be replaced with the old record's key + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '3^binance_btc_usdt', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + assert.ok(response.body.message.startsWith('Error: Market pair(s) in the formula is in wrong format'), 'wrong message'); + }); + + it('should not validate wrong formula format -2', async () => { + // server should check the keys in an object that client sends + //if one key is missing it should be replaced with the old record's key + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '2*binance-btc_usdt', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + assert.ok(response.body.message.startsWith('Error: Market pair(s) in the formula is in wrong format'), 'wrong message'); + }); + + it('should not validate wrong formula format -3', async () => { + // server should check the keys in an object that client sends + //if one key is missing it should be replaced with the old record's key + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '5/binance_btc-', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + assert.ok(response.body.message.startsWith('Error: Market pair(s) in the formula is in wrong format'), 'wrong message'); + }); + + + it('should not validate wrong formula format -4', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '3*binance', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + assert.ok(response.body.message.startsWith('Error: Market pair(s) in the formula is in wrong format'), 'wrong message'); + }); + + it('should not validate wrong formula format -5', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: 'binance_btc-usdt*kraken_eth_usdt', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + }); + + it('should not validate formula with unsupported exchange', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: 'bitstamp_btc-usdt', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + }); + + it('should not validate formula with unsupported pair', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: 'binance_btc-abc', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(400); + }); + + + it('should validate correct formula with single market', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '3^binance_btc-usdt*12/5*9+9.4*2', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(200); + assert.ok(Number(response.body.buy_price), 'buy_price should be number'); + assert.ok(Number(response.body.sell_price), 'buy_price should be number'); + }); + + it('should validate correct formula with multiple market', async () => { + const response = await request() + .post(`/v2/broker/test`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + formula: '3^binance_btc-usdt*kraken_eth-usdt*12/5*9+9.4*2', + spread: 1, + increment_size: 0.0001, + }); + + response.should.have.status(200); + assert.ok(Number(response.body.buy_price), 'buy_price should be number'); + assert.ok(Number(response.body.sell_price), 'buy_price should be number'); + }); + + it('should get a quote without auth', async () => { + const response = await request() + .get(`/v2/quick-trade?spending_currency=xht&receiving_currency=usdt&spending_amount=2`) + + response.should.have.status(200); + response.should.be.json; + response.body.should.not.have.property('token'); + }); + + it('should get a quote with auth', async () => { + const response = await request() + .get(`/v2/quick-trade?spending_currency=xht&receiving_currency=usdt&spending_amount=2`) + .set('Authorization', `Bearer ${bearerToken}`) + quoteData = response.body; + + response.should.have.status(200); + response.should.be.json; + response.body.should.have.property('token'); + }); + + it('should validate jsonb object', async () => { + // server should check the keys in an object that client sends + //if one key is missing it should be replaced with the old record's key + const response = await request() + .put(`/v2/broker`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + id: createdBroker.id, + account: { + binance: { + apiKey: '1a3321381e9f2e8342449936bb0e5e0590435', + }, + }, + }); + + response.should.have.status(200); + response.body.account.binance.should.have.property('apiKey'); + response.body.account.binance.should.have.property('apiSecret'); + }); + + it('should only update that fields that client sends', async () => { + // server should not overwrite the whole record if clients send only a few columns to update + const response = await request() + .put(`/v2/broker`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + id: createdBroker.id, + increment_size: 0.001, + }); + response.should.have.status(200); + response.body.should.have.property('symbol'); + response.body.symbol.should.be.a('string'); + response.body.symbol.should.equal(createdBroker.symbol); + response.body.should.have.property('increment_size'); + }); + + // it('should execute broker order', async () => { + // const response = await request() + // .post(`/v2/order/execute`) + // .set('Authorization', `Bearer ${bearerToken}`) + // .send({ + // token: quoteData.token + // }); + + // response.should.have.status(200); + // response.should.be.json; + // }); + + + it('should update the broker', async () => { + const response = await request() + .put(`/v2/broker`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + id: createdBroker.id, + paused: true + }); + response.should.have.status(200); + }); + it('should delete the broker', async () => { + const response = await request() + .delete(`/v2/broker/`) + .set('Authorization', `Bearer ${bearerToken}`) + .send({ + id: createdBroker.id + }); + response.should.have.status(200); + }); + +}); \ No newline at end of file diff --git a/server/test/session/user-session-test.js b/server/test/session/user-session-test.js new file mode 100644 index 0000000000..3b10dc85a9 --- /dev/null +++ b/server/test/session/user-session-test.js @@ -0,0 +1,144 @@ +const { + request, + loginAs, + generateFuzz, + getAdminUser +} = require('../helpers'); +const tools = require('hollaex-tools-lib'); +const assert = require('assert'); +const moment = require('moment'); + + +describe('User Session', async () => { + let IP = `1.1.1.1`; + + const createSessionAndLogin = async () => { + const testUser = { + email: `test_auth${Math.floor(Math.random() * 10000)}@mail.com`, + password: "test112233.", + long_term: true + } + const response = await request() + .post(`/v2/signup/`) + .send(testUser); + const createdUser = testUser; + response.should.have.status(201); + response.should.be.json; + + const loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + const userSessions = await request() + .get(`/v2/user/sessions`) + .set('Authorization', `Bearer ${loginData.body.token}`) + + return { userSessions, createdUser, loginData }; + } + //Integration Testing + it('Integration -should get user sessions', async () => { + + const { userSessions, createdUser } = await createSessionAndLogin(); + + userSessions.should.have.status(200); + userSessions.should.be.json; + let user = await tools.user.getUserByEmail(createdUser.email); + assert.equal(userSessions.body.data.length, 1, 'body length is wrong'); + assert.equal(userSessions.body.data[0].user_id, user.id, 'wrong user id'); + assert.equal(userSessions.body.data[0].ip, IP, 'wrong ip'); + assert.equal(moment(userSessions.body.data[0].Session.expiry_date).startOf('day').diff(moment().startOf('day'), 'days'), 30, 'wrong expiration date'); + + }); + + it('Integration -should return session not found when token provided from non session creation flow ', async () => { + + let user = await tools.user.getUserByEmail(getAdminUser().email); + user.should.be.an('object'); + let bearerToken = await loginAs(user); + bearerToken.should.be.a('string'); + + const userSessions = await request() + .get(`/v2/user/sessions`) + .set('Authorization', `Bearer ${bearerToken}`) + + assert.equal(userSessions.body.message, 'Access denied: Session not found', 'wrong message'); + userSessions.should.have.status(403); + }); + + + it('Integration -should revoke user session', async () => { + + const { userSessions, loginData } = await createSessionAndLogin(); + + await request() + .post(`/v2/user/revoke-session`) + .set('Authorization', `Bearer ${loginData.body.token}`) + .send({ + 'session_id': userSessions.body.data[0].Session.id + }); + + const userBalance = await request() + .get(`/v2/user/balance`) + .set('Authorization', `Bearer ${loginData.body.token}`) + + assert.equal(userBalance.body.message, 'Access denied: Token is already revoked', 'wrong message'); + }); + + it('Integration -should increment attempt for wrong password', async () => { + + let { createdUser } = await createSessionAndLogin(); + createdUser.password = 'test324253.' + + let loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'Incorrect credentials.', 'wrong message content'); + + loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'Incorrect credentials. You have 3 more attempts left', 'wrong message content'); + + loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'Incorrect credentials. You have 2 more attempts left', 'wrong message content'); + + loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'Incorrect credentials. You have 1 more attempt left', 'wrong message content'); + + loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'Incorrect credentials. You attempted to login too many times, please wait for a while to try again', 'wrong message content'); + + loginData = await request() + .post(`/v2/login/`) + .set('x-real-ip', IP) + .send(createdUser); + + assert.equal(loginData.body.message, 'You attempted to login too many times, please wait for a while to try again', 'wrong message content'); + }); + + //Fuz Testing + it('Fuzz Test -should return error', async () => { + const userSessions = await request() + .get(`/v2/user/sessions`) + .set('Authorization', `Bearer ${generateFuzz()}`) + + userSessions.should.have.status(403); + }); +}); \ No newline at end of file diff --git a/server/utils/hollaex-network-lib/index.js b/server/utils/hollaex-network-lib/index.js index 6d022c72a6..5152454f36 100644 --- a/server/utils/hollaex-network-lib/index.js +++ b/server/utils/hollaex-network-lib/index.js @@ -3334,6 +3334,99 @@ class HollaExNetwork { return createRequest(verb, `${this.apiUrl}${path}`, headers); } + + + /** + * Get a broker quote from network + * @param {number} userId; - Optional Network id of user. + * @param {string} spendingCurrency - Currency user wants to convert from. + * @param {number} spendingAmount - Optional Amount user wants to spend. + * @param {string} receivingCurrency - Currency user wants to convert to. + * @param {number} receivingAmount - Optional Amount user wants to receive. + * @param {object} opts - Optional parameters. + * @param {object} opts.additionalHeaders - Object storing addtional headers to send with request. + * @return {object} Object with quote data. + */ + getQuote(userId, spendingCurrency, spendingAmount, receivingCurrency, receivingAmount, opts = { + additionalHeaders: null + }) { + checkKit(this.exchange_id); + + if (!spendingCurrency) { + return reject(parameterError('spendingCurrency', 'cannot be null')); + } else if (!receivingCurrency) { + return reject(parameterError('receivingCurrency', 'cannot be null')); + } + + const verb = 'GET'; + let path = `${this.baseUrl}/network/${this.exchange_id}/broker/quote?`; + + if (isNumber(userId)) { + path += `&user_id=${userId}`; + } + if (isString(spendingCurrency)) { + path += `&spending_currency=${spendingCurrency}`; + } + if (isNumber(spendingAmount)) { + path += `&spending_amount=${spendingAmount}`; + } + if (isString(receivingCurrency)) { + path += `&receiving_currency=${receivingCurrency}`; + } + if (isNumber(receivingAmount)) { + path += `&receiving_amount=${receivingAmount}`; + } + + const headers = generateHeaders( + isPlainObject(opts.additionalHeaders) ? { ...this.headers, ...opts.additionalHeaders } : this.headers, + this.apiSecret, + verb, + path, + this.apiExpiresAfter + ); + + return createRequest(verb, `${this.apiUrl}${path}`, headers); + } + + /** + * Execute the broker quote to network for a user + * @param {string} token; - Broker quote token. + * @param {number} user_id - User ID to execute the trade + * @param {number} fee - Fee in percentage to apply to the trade + * @param {object} opts - Optional parameters. + * @param {object} opts.additionalHeaders - Object storing addtional headers to send with request. + * @return {object} Object of the trade data. + */ + executeQuote(token, user_id, fee, opts = { + additionalHeaders: null + }) { + checkKit(this.exchange_id); + + if (!token) { + return reject(parameterError('token', 'cannot be null')); + } + + const verb = 'POST'; + const path = `${this.baseUrl}/network/${this.exchange_id}/broker/execute`; + + const data = { + token, + user_id, + fee + } + + const headers = generateHeaders( + isPlainObject(opts.additionalHeaders) ? { ...this.headers, ...opts.additionalHeaders } : this.headers, + this.apiSecret, + verb, + path, + this.apiExpiresAfter, + data + ); + + return createRequest(verb, `${this.apiUrl}${path}`, headers, { data }); + } + /** * Connect to websocket * @param {array} events - Array of events to connect to diff --git a/server/utils/hollaex-tools-lib/tools/broker.js b/server/utils/hollaex-tools-lib/tools/broker.js index a974580bda..8b43381f5a 100644 --- a/server/utils/hollaex-tools-lib/tools/broker.js +++ b/server/utils/hollaex-tools-lib/tools/broker.js @@ -3,20 +3,22 @@ const { getModel } = require('./database/model'); const math = require('mathjs'); const ccxt = require('ccxt'); -const rp = require('request-promise'); const randomString = require('random-string'); -const dbQuery = require('./database/query'); const { SERVER_PATH } = require('../constants'); +const { EXCHANGE_PLAN_INTERVAL_TIME, EXCHANGE_PLAN_PRICE_SOURCE } = require(`${SERVER_PATH}/constants`) const { getNodeLib } = require(`${SERVER_PATH}/init`); const { client } = require('./database/redis'); const { getUserByKitId } = require('./user'); -const { validatePair, getKitTier } = require('./common'); -const _eval = require('eval'); +const { validatePair, getKitTier, getKitConfig, getAssetsPrices, getQuickTrades, getKitCoin } = require('./common'); const { sendEmail } = require('../../../mail'); const { MAILTYPE } = require('../../../mail/strings'); const { verifyBearerTokenPromise } = require('./security'); const { Op } = require('sequelize'); const { loggerBroker } = require('../../../config/logger'); +const { isArray } = require('lodash'); +const BigNumber = require('bignumber.js'); +const connectedExchanges = {}; + const { TOKEN_EXPIRED, @@ -29,133 +31,237 @@ const { BROKER_FORMULA_NOT_FOUND, SPREAD_MISSING, MANUAL_BROKER_CREATE_ERROR, + DYNAMIC_BROKER_CREATE_ERROR, + DYNAMIC_BROKER_EXCHANGE_PLAN_ERROR, + DYNAMIC_BROKER_UNSUPPORTED, EXCHANGE_NOT_FOUND, - SYMBOL_NOT_FOUND } = require(`${SERVER_PATH}/messages`); + SYMBOL_NOT_FOUND, + UNISWAP_PRICE_NOT_FOUND, + FORMULA_MARKET_PAIR_ERROR, + COIN_INPUT_MISSING, + AMOUNTS_MISSING, + REBALANCE_SYMBOL_MISSING, + PRICE_NOT_FOUND +} = require(`${SERVER_PATH}/messages`); const validateBrokerPair = (brokerPair) => { - if (brokerPair.type === 'manual' && math.compare(brokerPair.buy_price, 0) !== 1) { + if (brokerPair.type === 'manual' && new BigNumber(brokerPair.buy_price).comparedTo(0) !== 1) { throw new Error('Broker buy price must be bigger than zero.'); - } else if (brokerPair.type === 'manual' && math.compare(brokerPair.sell_price, 0) !== 1) { + } else if (brokerPair.type === 'manual' && new BigNumber(brokerPair.sell_price).comparedTo(0) !== 1) { throw new Error('Broker sell price must be bigger than zero.'); - } else if (math.compare(brokerPair.min_size, 0) !== 1) { + } else if (new BigNumber(brokerPair.min_size).comparedTo(0) !== 1) { throw new Error('Broker minimum order size must be bigger than zero.'); - } else if (math.compare(brokerPair.max_size, brokerPair.min_size) !== 1) { + } else if (new BigNumber(brokerPair.max_size).comparedTo(new BigNumber(brokerPair.min_size)) !== 1) { throw new Error('Broker maximum order size must be bigger than minimum order size.'); - } else if (math.compare(brokerPair.increment_size, 0) !== 1) { - throw new Error('Broker order price increment must be bigger than zero.'); } else if (brokerPair.symbol && !validatePair(brokerPair.symbol)) { throw new Error('invalid symbol'); } }; -const getDecimals = (value = 0) => { - if (Math.floor(value) === value) return 0; +const setExchange = (data) => { + if (connectedExchanges[data.id]) { + return connectedExchanges[data.id].exchange + } + + const exchangeClass = ccxt[data.exchange]; + + const exchange = new exchangeClass({ + timeout: 5000, + ...(data.api_key && { 'apiKey': data.api_key }), + ...(data.api_secret && { 'secret': data.api_secret }), + }) + + if (data.id) { + connectedExchanges[data.id] = { exchange, api_key: data.api_key, api_secret: data.api_secret }; + } + + return exchange; +} - let str = value.toString(); - if (str.indexOf('.') !== -1 && str.indexOf('-') !== -1) { - return str.split('-')[1] || 0; - } else if (str.indexOf('.') !== -1) { - return str.split('.')[1].length || 0; +const getQuoteDynamicBroker = async (side, broker, user_id = null, orderData) => { + + const { symbol, spread, quote_expiry_time, refresh_interval, formula, id } = broker; + + const baseCurrencyPrice = await calculatePrice(side, spread, formula, refresh_interval, id); + + const responseObject = { + price: baseCurrencyPrice + }; + + const { size, receiving_amount, spending_amount } = calculateSize(orderData, side, responseObject, symbol); + responseObject.receiving_amount = receiving_amount; + responseObject.spending_amount = spending_amount; + + //check if there is user_id, if so, assing token + if (user_id) { + + // Generate randomToken to be used during deal execution + const randomToken = generateRandomToken(user_id, symbol, side, quote_expiry_time, baseCurrencyPrice, size, 'broker'); + responseObject.token = randomToken; + // set expiry + const expiryDate = new Date(); + expiryDate.setSeconds(expiryDate.getSeconds() + quote_expiry_time || 30); + responseObject.expiry = expiryDate; } - return str.split('-')[1] || 0; + + return responseObject; + }; -const binanceScript = async () => { - const BINANCE_URL = 'https://api3.binance.com/api/v3/ticker/price'; +const getQuoteManualBroker = async (broker, side, user_id = null, orderData) => { + const { symbol, quote_expiry_time, sell_price, buy_price } = broker; - // Get the price from redis - const formattedSymbol = symbol.split('-').join('').toUpperCase(); - const quotePrice = await client.getAsync('prices'); + const baseCurrencyPrice = side === 'buy' ? sell_price : buy_price; - const runScript = (prices) => { - //Calculate the price - const foundSymbol = JSON.parse(prices).find((data) => data.symbol === formattedSymbol); - if (!foundSymbol) { - throw new Error('Pair not found'); - } - const baseCurrencyPrice = calculatePrice(foundSymbol.price, side, spread, multiplier); + const responseObject = { + price: baseCurrencyPrice + }; - const decimalPoint = getDecimals(broker.increment_size); - const roundedPrice = math.round( - baseCurrencyPrice, - decimalPoint - ); + const { size, receiving_amount, spending_amount } = calculateSize(orderData, side, responseObject, symbol); + responseObject.receiving_amount = receiving_amount; + responseObject.spending_amount = spending_amount; - const responseObject = { - price: roundedPrice - }; - //check if there is user_id, if so, assing token - if (user_id) { - - let size; - if (orderData) { - let { spending_currency, receiving_currency, spending_amount, receiving_amount } = orderData; - - if (spending_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? spending_amount / responseObject.price : spending_amount * responseObject.price, - decimalPoint - ); - - receiving_amount = sourceAmount; - - } else if (receiving_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? receiving_amount * responseObject.price : receiving_amount / responseObject.price, - decimalPoint - ); - spending_amount = sourceAmount; - } + if (user_id) { - if (`${spending_currency}-${receiving_currency}` === symbol) { - size = spending_amount; - } else { - size = receiving_amount - } - } - // Generate randomToken to be used during deal execution - const randomToken = generateRandomToken(user_id, symbol, side, broker.quote_expiry_time, roundedPrice, size, 'broker'); - responseObject.token = randomToken; - // set expiry - const expiryDate = new Date(); - expiryDate.setSeconds(expiryDate.getSeconds() + broker.quote_expiry_time || 30); - responseObject.expiry = expiryDate; + const randomToken = generateRandomToken(user_id, symbol, side, quote_expiry_time, baseCurrencyPrice, size, 'broker'); + responseObject.token = randomToken; + // set expiry + const expiryDate = new Date(); + expiryDate.setSeconds(expiryDate.getSeconds() + quote_expiry_time || 30); + responseObject.expiry = expiryDate; + } + return responseObject; +} + +const calculateSize = (orderData, side, responseObject, symbol) => { + if (orderData == null) { + throw new Error(COIN_INPUT_MISSING); + } + + let size = null; + let { spending_currency, receiving_currency, spending_amount, receiving_amount } = orderData; + + const coins = symbol.split('-'); + const baseCoinInfo = getKitCoin(coins[0]); + const quoteCointInfo = getKitCoin(coins[1]); + + if (spending_currency == null && receiving_currency == null) { + throw new Error(AMOUNTS_MISSING); + } + + if (spending_amount != null) { + const incrementUnit = side === 'buy' ? baseCoinInfo.increment_unit : quoteCointInfo.increment_unit; + const targetedAmount = side === 'buy' ? spending_amount / responseObject.price : spending_amount * responseObject.price; + + if (incrementUnit < 1) { + const decimalPoint = new BigNumber(incrementUnit).dp(); + const sourceAmount = new BigNumber(targetedAmount).decimalPlaces(decimalPoint).toNumber(); + receiving_amount = sourceAmount; + } else { + receiving_amount = targetedAmount - (targetedAmount % incrementUnit); } - return responseObject; - }; - // If it doesn't exist, fetch all market from Binance - if (!quotePrice) { - return rp(BINANCE_URL) - .then((res) => { - //Store all market prices in Redis with 1 minute expiry time - //response is a stringfied object. - client.setexAsync('prices', 60, res); + } else if (receiving_amount != null) { + const incrementUnit = side === 'buy' ? quoteCointInfo.increment_unit : baseCoinInfo.increment_unit + const targetedAmount = side === 'buy' ? receiving_amount * responseObject.price : receiving_amount / responseObject.price; - return runScript(res); - }) - .catch((err) => { - throw new Error(err); - }); + if (incrementUnit < 1) { + const decimalPoint = new BigNumber(incrementUnit).dp(); + const sourceAmount = new BigNumber(targetedAmount).decimalPlaces(decimalPoint).toNumber(); + spending_amount = sourceAmount; + } else { + spending_amount = targetedAmount - (targetedAmount % incrementUnit); + } + } + if (`${spending_currency}-${receiving_currency}` === symbol) { + size = spending_amount; } else { - return runScript(quotePrice); + size = receiving_amount } -}; + return { size, spending_amount, receiving_amount }; +} -const calculatePrice = (price, side, spread, multiplier = 1) => { - // Calculate the price - const multipliedPrice = parseFloat(price) * multiplier; - let calculatedSize; + +const calculateFormula = (fn) => { + return new Function(`return ${fn}`)(); +} + +const isFairPriceForBroker = async (broker) => { + if (broker.type !== 'dynamic') return true; + + // with ccxt + const priceFromMarkets = await calculatePrice(null, null, broker.formula, null, broker.id, false); + // with oracle + const priceFromOracle = await calculatePrice(null, null, broker.formula, null, broker.id, true); + + //relative difference + const percDiff = 100 * Math.abs((priceFromMarkets - priceFromOracle) / ((priceFromMarkets + priceFromOracle) / 2)); + + // If difference more than 10 percent, price is not fair. + const priceDifferenceTreshold = 10; + if (priceFromOracle !== -1 && percDiff > priceDifferenceTreshold) return false; + else return true; +} + +const calculatePrice = async (side, spread, formula, refresh_interval, brokerId, isOracle = false) => { + const regex = /([a-zA-Z]+(?:_[a-zA-Z]+)+(?:-[a-zA-Z]+))/g; + const variables = formula.match(regex); + + if (!isArray(variables)) + throw new Error(FORMULA_MARKET_PAIR_ERROR); + + for (let variable of variables) { + const exchangePair = variable.split('_'); + const exchangeInfo = getKitConfig().info; + + if (exchangePair?.length !== 2) + throw new Error(FORMULA_MARKET_PAIR_ERROR + ' ' + exchangePair); + + if (!(EXCHANGE_PLAN_PRICE_SOURCE[exchangeInfo.plan] || [])?.includes(exchangePair[0])) + throw new Error(DYNAMIC_BROKER_UNSUPPORTED); + + const selectedExchange = exchangePair[0] !== 'oracle' && setExchange({ id: `${exchangePair[0]}-broker:fetch-markets`, exchange: exchangePair[0] }); + let marketPrice; + + if (!isOracle && exchangePair[0] !== 'oracle') { + const formattedSymbol = exchangePair[1].split('-').join('/').toUpperCase(); + const userCachekey = `${brokerId}-${exchangePair[1]}`; + marketPrice = await client.getAsync(userCachekey); + + if (!marketPrice) { + const ticker = await selectedExchange.fetchTicker(formattedSymbol); + marketPrice = ticker.last + if (refresh_interval) + client.setexAsync(userCachekey, refresh_interval, ticker.last); + } + } + else { + const coins = exchangePair[1].split('-'); + const userCachekey = `${brokerId}-${exchangePair[0]}-${exchangePair[1]}`; + marketPrice = await client.getAsync(userCachekey); + + if (!marketPrice) { + const conversions = await getAssetsPrices([coins[0]], coins[1], 1); + marketPrice = conversions[coins[0]]; + if (refresh_interval) + client.setexAsync(userCachekey, refresh_interval, marketPrice); + } + if(marketPrice === -1) return -1; + } + formula = formula.replace(variable, marketPrice); + + } + let convertedPrice = calculateFormula(formula); if (side === 'buy') { - calculatedSize = multipliedPrice * (1 + (spread / 100)) + convertedPrice = new BigNumber(convertedPrice).multipliedBy((1 + (spread / 100))).toNumber(); } else if (side === 'sell') { - calculatedSize = multipliedPrice * (1 - (spread / 100)) + convertedPrice = new BigNumber(convertedPrice).multipliedBy((1 - (spread / 100))).toNumber(); } - - return calculatedSize; + + return convertedPrice; }; const generateRandomToken = (user_id, symbol, side, expiryTime = 30, price, size, type) => { @@ -181,9 +287,7 @@ const generateRandomToken = (user_id, symbol, side, expiryTime = 30, price, size }; const fetchBrokerQuote = async (brokerQuote) => { - const { symbol, side, bearerToken, ip } = brokerQuote; - - const orderData = brokerQuote?.orderData; + const { symbol, side, bearerToken, ip, orderData } = brokerQuote; try { let user_id = null; @@ -203,109 +307,82 @@ const fetchBrokerQuote = async (brokerQuote) => { throw new Error(BROKER_PAUSED); } if (broker.type === 'dynamic') { - if (broker.formula) { - //Run formula - const resObject = _eval(broker.formula, 'formula', { - symbol, side, user_id, client, broker, calculatePrice, generateRandomToken, getDecimals, math, rp, orderData - }, true); - - return resObject; - - } else { - throw new Error(BROKER_FORMULA_NOT_FOUND); - } + return getQuoteDynamicBroker(side, broker, user_id, orderData); } else { - const baseCurrencyPrice = side === 'buy' ? broker.sell_price : broker.buy_price; - - const decimalPoint = getDecimals(broker.increment_size); - const roundedPrice = math.round( - baseCurrencyPrice, - decimalPoint - ); - const responseObject = { - price: roundedPrice - }; - - let size; - - if (orderData) { - let { spending_currency, receiving_currency, spending_amount, receiving_amount } = orderData - - if (spending_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? spending_amount / responseObject.price : spending_amount * responseObject.price, - decimalPoint - ); + return getQuoteManualBroker(broker, side, user_id, orderData); + } - receiving_amount = sourceAmount; + } catch (err) { + throw new Error(err); + } +}; - } else if (receiving_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? receiving_amount * responseObject.price : receiving_amount / responseObject.price, - decimalPoint - ); - spending_amount = sourceAmount; - } +const testBroker = async (data) => { + const { formula, spread } = data; + try { + if (spread == null) { + throw new Error(BROKER_FORMULA_NOT_FOUND); + } - if (`${spending_currency}-${receiving_currency}` === symbol) { - size = spending_amount; - } else { - size = receiving_amount - } - } + if (spread == null) { + throw new Error(SPREAD_MISSING); + } + + const price = await calculatePrice( + null, + spread, + formula, + 5, + 'test:broker' + ); - if (user_id) { - const randomToken = generateRandomToken(user_id, symbol, side, broker.quote_expiry_time, roundedPrice, size, 'broker'); - responseObject.token = randomToken; - // set expiry - const expiryDate = new Date(); - expiryDate.setSeconds(expiryDate.getSeconds() + broker.quote_expiry_time || 30); - responseObject.expiry = expiryDate; - } - return responseObject; + if (price < 0) { + throw new Error(PRICE_NOT_FOUND); } + const decimalPoint = new BigNumber(price).dp(); + return { + buy_price: new BigNumber(price * (1 - (spread / 100))).decimalPlaces(decimalPoint).toNumber(), + sell_price: new BigNumber(price * (1 + (spread / 100))).decimalPlaces(decimalPoint).toNumber() + } } catch (err) { throw new Error(err); } -}; -const testBroker = async (data) => { - const { formula, exchange_name, spread, multiplier, symbol } = data; +}; +const testBrokerUniswap = async (data) => { + const { base_coin, spread, quote_coin } = data; + const UNISWAP_COINS = {} try { - //if formula is sent, run it. - if (formula) { - const resObject = _eval(formula, 'formula', { - calculatePrice, generateRandomToken, getDecimals, math, rp - }, true); + if (!base_coin || !quote_coin || !UNISWAP_COINS[base_coin] || !UNISWAP_COINS[quote_coin]) { + throw new Error(SYMBOL_NOT_FOUND); + } + if (!spread) { + throw new Error(SPREAD_MISSING); + } - return resObject; - } else { - if (!exchange_name) { - throw new Error(EXCHANGE_NOT_FOUND); - } - if (!spread) { - throw new Error(SPREAD_MISSING); - } - if (!symbol) { - throw new Error(SYMBOL_NOT_FOUND); - } - if (exchange_name === 'binance') { - const formattedSymbol = symbol.split('-').join('').toUpperCase(); - - return rp(`https://api3.binance.com/api/v3/ticker/price?symbol=${formattedSymbol}`) - .then((res) => { - const multipliedPrice = parseFloat(JSON.parse(res).price) * (multiplier || 1); - return { - buy_price: multipliedPrice * (1 - (spread / 100)), - sell_price: multipliedPrice * (1 + (spread / 100)) - }; - }) - .catch((err) => { - throw new Error(err); - }); - } - throw new Error(EXCHANGE_NOT_FOUND); + const paraSwapMin = constructSimpleSDK({ chainId: 1, axios }); + const includeDEXS = '[Uniswap V3]'; + + const priceRoute = await paraSwapMin.swap.getRate({ + srcToken: UNISWAP_COINS[base_coin].token, + srcDecimals: UNISWAP_COINS[base_coin].decimals, + destToken: UNISWAP_COINS[quote_coin].token, + destDecimals: UNISWAP_COINS[quote_coin].decimals, + amount: Math.pow(10, UNISWAP_COINS[base_coin].decimals), + side: SwapSide.SELL, + includeDEXS + }) + + if (!priceRoute.destAmount) { + throw new Error(UNISWAP_PRICE_NOT_FOUND) + } + + const price = math.divide(priceRoute.destAmount,Math.pow(10, UNISWAP_COINS[quote_coin].decimals)) + + return { + buy_price: price * (1 - (spread / 100)), + sell_price: price * (1 + (spread / 100)) } } catch (err) { throw new Error(err); @@ -317,11 +394,7 @@ const testRebalance = async (data) => { const { exchange_id, api_key, api_secret } = data; try { - const exchangeClass = ccxt[exchange_id]; - const exchange = new exchangeClass({ - 'apiKey': api_key, - 'secret': api_secret - }); + const exchange = setExchange({ exchange: exchange_id, api_key, api_secret }) const userBalance = await exchange.fetchBalance(); return userBalance; } catch (err) { @@ -331,8 +404,8 @@ const testRebalance = async (data) => { }; const reverseTransaction = async (orderData) => { - const { userId, symbol, side, size } = orderData; - const notifyUser = async (data) => { + const { symbol, side, size } = orderData; + const notifyUser = async (data, userId) => { const user = await getUserByKitId(userId); sendEmail( MAILTYPE.ALERT, @@ -347,35 +420,24 @@ const reverseTransaction = async (orderData) => { try { const broker = await getModel('broker').findOne({ where: { symbol } }); - const decimalPoint = getDecimals(broker.increment_size); - - if (broker.account && broker.account.hasOwnProperty('binance')) { - const binanceInfo = broker.account.binance; - const exchangeId = 'binance' - , exchangeClass = ccxt[exchangeId] - , exchange = new exchangeClass({ - 'apiKey': binanceInfo.apiKey, - 'secret': binanceInfo.apiSecret - }); - - const formattedSymbol = symbol.split('-').join('').toUpperCase(); - const formattedRebalancingSymbol = broker.rebalancing_symbol && broker.rebalancing_symbol.split('-').join('').toUpperCase(); - - const orderbook = await exchange.fetchOrderBook(formattedSymbol); - - const roundedPrice = math.round( - side === 'buy' ? orderbook['asks'][0][0] * 1.01 : orderbook['bids'][0][0] * 0.99, - decimalPoint - ); - - if (side === 'buy') { - exchange.createLimitBuyOrder(formattedRebalancingSymbol || formattedSymbol, size, roundedPrice) - .then((res) => { notifyUser(res); }) - .catch((err) => { notifyUser(err); }); - } else if (side == 'sell') { - exchange.createLimitSellOrder(formattedRebalancingSymbol || formattedSymbol, size, roundedPrice) - .then((res) => { notifyUser(res); }) - .catch((err) => { notifyUser(err); }); + + const quickTrades = getQuickTrades(); + const quickTradeConfig = quickTrades.find(quickTrade => quickTrade.symbol === symbol); + + if (quickTradeConfig && quickTradeConfig.type === 'broker' && quickTradeConfig.active && broker && !broker.paused && broker.account) { + const objectKeys = Object.keys(broker.account); + const exchangeKey = objectKeys[0]; + + if (exchangeKey) { + const exchange = setExchange({ + exchange: exchangeKey, + api_key: broker.account[exchangeKey].apiKey, + api_secret: broker.account[exchangeKey].apiSecret + }) + + const formattedRebalancingSymbol = broker.rebalancing_symbol && broker.rebalancing_symbol.split('-').join('/').toUpperCase(); + exchange.createOrder(formattedRebalancingSymbol, 'market', side, size) + .catch((err) => { notifyUser(err.message, broker.user_id); }); } } } catch (err) { @@ -396,49 +458,58 @@ const createBrokerPair = async (brokerPair) => { ] } }) - .then((deal) => { + .then(async (deal) => { if (deal) { throw new Error(BROKER_EXISTS); } + const exchangeInfo = getKitConfig().info; + const { - formula, - exchange_name, spread, - multiplier, - type + quote_expiry_time, + type, + account, + formula, + rebalancing_symbol } = brokerPair; - if (exchange_name && type === 'manual') { - throw new Error(MANUAL_BROKER_CREATE_ERROR); + if (type !== 'manual' && (!spread || !quote_expiry_time || !formula)) { + throw new Error(DYNAMIC_BROKER_CREATE_ERROR); } - if (exchange_name && !spread) { - throw new Error(SPREAD_MISSING); + if (type !== 'manual' && exchangeInfo.plan === 'basic') { + throw new Error(DYNAMIC_BROKER_EXCHANGE_PLAN_ERROR); } - let adminFormula = null; + if(type === 'dynamic') { + brokerPair.refresh_interval = EXCHANGE_PLAN_INTERVAL_TIME[exchangeInfo.plan] || 60; + } + + if (account) { + for (const [key, value] of Object.entries(account)) { + if (!value.hasOwnProperty('apiKey')) { + value.apiKey = brokerPair?.account[key]?.apiKey; + } + + if (!value.hasOwnProperty('apiSecret')) { + value.apiSecret = brokerPair?.account[key]?.apiSecret; + } + } - if (type === 'dynamic') { - // If it is a custom script(users send their own formula) - if (formula) { - adminFormula = formula; + if (!rebalancing_symbol) { + throw new Error(REBALANCE_SYMBOL_MISSING); } - // If user selects a exchange - else if (exchange_name === 'binance') { - const binanceFormula = ` - const spread = ${spread}; - const multiplier = ${multiplier || 1}; - module.exports = (${binanceScript.toString()})() - `; - - adminFormula = binanceFormula; - } else { - throw new Error(EXCHANGE_NOT_FOUND); + } + + if (formula) { + const brokerPrice = await testBroker({ formula, spread }); + if (!Number(brokerPrice.sell_price) || !Number(brokerPrice.buy_price)) { + throw new Error(FORMULA_MARKET_PAIR_ERROR); } } + const newBrokerObject = { - ...brokerPair, - formula: adminFormula + ...brokerPair }; @@ -450,21 +521,16 @@ const fetchBrokerPair = (symbol) => { return getModel('broker').findOne({ where: { symbol } }); }; -async function fetchBrokerPairs(attributes, bearerToken, ip) { - let userId = null; - if (bearerToken) { - const auth = await verifyBearerTokenPromise(bearerToken, ip); - if (auth) { - userId = auth.sub.id; - const user = await getUserByKitId(userId); - if (user && user.is_admin) { - attributes.push('account', 'formula'); - } +const fetchBrokerPairs = async (attributes) => { + const brokers = await getModel('broker').findAll({ attributes }); + brokers.forEach(broker => { + for (const [key, value] of Object.entries(broker.account || [])) { + value.apiKey = '*****', + value.apiSecret = '*********' } - } + }) - - return await getModel('broker').findAll({ attributes }); + return brokers; } const updateBrokerPair = async (id, data) => { @@ -474,49 +540,53 @@ const updateBrokerPair = async (id, data) => { } const { - exchange_name, spread, - multiplier, type, - account } = data; - if (exchange_name && type === 'manual') { - throw new Error(MANUAL_BROKER_CREATE_ERROR); + account, + formula, + rebalancing_symbol + } = data; + + const exchangeInfo = getKitConfig().info; + + if (type !== 'manual' && exchangeInfo.plan === 'basic') { + throw new Error(DYNAMIC_BROKER_EXCHANGE_PLAN_ERROR); } - if (exchange_name && !spread) { - throw new Error(SPREAD_MISSING); + + if(type === 'dynamic') { + data.refresh_interval = EXCHANGE_PLAN_INTERVAL_TIME[exchangeInfo.plan] || 60; } - //Validate account JSONB object if (account) { for (const [key, value] of Object.entries(account)) { - if (!value.hasOwnProperty('apiKey')) { - value.apiKey = brokerPair.account[key].apiKey; + if (!value.hasOwnProperty('apiKey') || value?.apiKey?.includes('*****')) { + value.apiKey = brokerPair?.account[key]?.apiKey; } - if (!value.hasOwnProperty('apiSecret')) { - value.apiSecret = brokerPair.account[key].apiSecret; + if (!value.hasOwnProperty('apiSecret') || value?.apiSecret?.includes('*********')) { + value.apiSecret = brokerPair?.account[key]?.apiSecret; } } + + if (!rebalancing_symbol) { + throw new Error(REBALANCE_SYMBOL_MISSING); + } } + + if (formula) { + const brokerPrice = await testBroker({ formula, spread }); + if (!Number(brokerPrice.sell_price) || !Number(brokerPrice.buy_price)) { + throw new Error(FORMULA_MARKET_PAIR_ERROR); + } + } + const updatedPair = { ...brokerPair.get({ plain: true }), ...data, }; validateBrokerPair(updatedPair); - if (exchange_name === 'binance') { - - const binanceFormula = ` - const spread = ${spread}; - const multiplier = ${multiplier || 1}; - module.exports = (${binanceScript.toString()})() - `; - - updatedPair.formula = binanceFormula; - } else if (exchange_name && exchange_name !== 'binance') { - throw new Error(EXCHANGE_NOT_FOUND); - } return brokerPair.update(updatedPair, { fields: [ @@ -525,17 +595,22 @@ const updateBrokerPair = async (id, data) => { 'sell_price', 'min_size', 'max_size', - 'increment_size', 'paused', 'type', 'quote_expiry_time', 'rebalancing_symbol', 'account', - 'formula' + 'formula', + 'spread', ] }); }; +const fetchTrackedExchangeMarkets = async (exchange) => { + const selectedExchage = setExchange({ id: `${exchange}-broker:fetch-markets`, exchange }); + return selectedExchage.fetchMarkets(); +} + const deleteBrokerPair = async (id) => { const brokerPair = await getModel('broker').findOne({ where: { id } }); @@ -548,59 +623,19 @@ const deleteBrokerPair = async (id) => { return brokerPair.destroy(); }; -const executeBrokerDeal = async (userId, token, size) => { - const storedToken = await client.getAsync(token); - if (!storedToken) { - throw new Error(TOKEN_EXPIRED); - } - const { user_id, symbol, price, side } = JSON.parse(storedToken); - - if (user_id !== userId) { - throw new Error(AUTH_NOT_MATCHED); - } - - const brokerPair = await getModel('broker').findOne({ where: { symbol } }); - - if (!brokerPair) { - throw new Error(BROKER_NOT_FOUND); - } else if (brokerPair.paused) { - throw new Error(BROKER_PAUSED); - } - - if(size < brokerPair.min_size || size > brokerPair.max_size) { - throw new Error(BROKER_SIZE_EXCEED) - } - - const broker = await getUserByKitId(brokerPair.user_id); - const user = await getUserByKitId(userId); - - const tierBroker = getKitTier(broker.verification_level); - const tierUser = getKitTier(user.verification_level); - - const makerFee = tierBroker.fees.maker[symbol]; - const takerFee = tierUser.fees.taker[symbol]; - - return getNodeLib().createBrokerTrade( - symbol, - side, - price, - size, - broker.network_id, - user.network_id, - { maker: makerFee, taker: takerFee } - ); -}; - module.exports = { createBrokerPair, fetchBrokerPair, fetchBrokerPairs, updateBrokerPair, deleteBrokerPair, - executeBrokerDeal, fetchBrokerQuote, reverseTransaction, testBroker, testRebalance, - generateRandomToken + generateRandomToken, + fetchTrackedExchangeMarkets, + testBrokerUniswap, + isFairPriceForBroker, + calculatePrice }; \ No newline at end of file diff --git a/server/utils/hollaex-tools-lib/tools/common.js b/server/utils/hollaex-tools-lib/tools/common.js index f883bb447b..f663ad0439 100644 --- a/server/utils/hollaex-tools-lib/tools/common.js +++ b/server/utils/hollaex-tools-lib/tools/common.js @@ -44,7 +44,7 @@ const { checkStatus: checkExchangeStatus, getNodeLib } = require(`${SERVER_PATH} const rp = require('request-promise'); const { isEmail: isValidEmail } = require('validator'); const moment = require('moment'); -const { GET_BROKER } = require('../../../constants'); +const { GET_BROKER, GET_QUICKTRADE, GET_NETWORK_QUICKTRADE } = require('../../../constants'); const BigNumber = require('bignumber.js'); // const { Transform } = require('json2csv'); @@ -755,14 +755,14 @@ const getNetworkConstants = (opts = { const getNetworkEndpoint = () => HOLLAEX_NETWORK_ENDPOINT; const getDefaultFees = () => { - const { info: { type, collateral_level } } = getKitConfig(); + const { info: { type, plan } } = getKitConfig(); if (type === 'Enterprise') { return { maker: 0, taker: 0 }; } else { - return DEFAULT_FEES[collateral_level]; + return DEFAULT_FEES[plan]; } }; @@ -792,6 +792,15 @@ const validatePair = (pair) => { const getBrokerDeals = () => { return GET_BROKER(); }; + +const getQuickTrades = () => { + return GET_QUICKTRADE(); +}; + +const getNetworkQuickTrades = () => { + return GET_NETWORK_QUICKTRADE(); +} + const parseNumber = (number, precisionValue) => { return BigNumber(number).precision(precisionValue, BigNumber.ROUND_DOWN).toNumber(); } @@ -859,5 +868,7 @@ module.exports = { validateIp, validatePair, getBrokerDeals, - parseNumber + getQuickTrades, + getNetworkQuickTrades, + parseNumber, }; diff --git a/server/utils/hollaex-tools-lib/tools/order.js b/server/utils/hollaex-tools-lib/tools/order.js index 8191ab94a3..83b52663fa 100644 --- a/server/utils/hollaex-tools-lib/tools/order.js +++ b/server/utils/hollaex-tools-lib/tools/order.js @@ -3,11 +3,11 @@ const { getUserByKitId, getUserByEmail, getUserByNetworkId, mapNetworkIdToKitId, mapKitIdToNetworkId } = require('./user'); const { SERVER_PATH } = require('../constants'); const { getModel } = require('./database/model'); -const { fetchBrokerQuote, generateRandomToken, executeBrokerDeal } = require('./broker'); +const { fetchBrokerQuote, generateRandomToken, isFairPriceForBroker } = require('./broker'); const { getNodeLib } = require(`${SERVER_PATH}/init`); -const { INVALID_SYMBOL, NO_DATA_FOR_CSV, USER_NOT_FOUND, USER_NOT_REGISTERED_ON_NETWORK, TOKEN_EXPIRED, BROKER_NOT_FOUND, BROKER_PAUSED, BROKER_SIZE_EXCEED, QUICK_TRADE_ORDER_CAN_NOT_BE_FILLED, QUICK_TRADE_ORDER_CURRENT_PRICE_ERROR, QUICK_TRADE_VALUE_IS_TOO_SMALL } = require(`${SERVER_PATH}/messages`); +const { INVALID_SYMBOL, NO_DATA_FOR_CSV, USER_NOT_FOUND, USER_NOT_REGISTERED_ON_NETWORK, TOKEN_EXPIRED, BROKER_NOT_FOUND, BROKER_PAUSED, BROKER_SIZE_EXCEED, QUICK_TRADE_ORDER_CAN_NOT_BE_FILLED, QUICK_TRADE_ORDER_CURRENT_PRICE_ERROR, QUICK_TRADE_VALUE_IS_TOO_SMALL, FAIR_PRICE_BROKER_ERROR, AMOUNT_NEGATIVE_ERROR, QUICK_TRADE_CONFIG_NOT_FOUND, QUICK_TRADE_TYPE_NOT_SUPPORTED, PRICE_NOT_FOUND, INVALID_PRICE, INVALID_SIZE } = require(`${SERVER_PATH}/messages`); const { parse } = require('json2csv'); -const { subscribedToPair, getKitTier, getDefaultFees, getAssetsPrices, getPublicTrades, validatePair } = require('./common'); +const { subscribedToPair, getKitTier, getDefaultFees, getAssetsPrices, getPublicTrades, getQuickTrades, validatePair } = require('./common'); const { reject } = require('bluebird'); const { loggerOrders } = require(`${SERVER_PATH}/config/logger`); const math = require('mathjs'); @@ -17,6 +17,7 @@ const { getUserBalanceByKitId } = require('./wallet'); const { verifyBearerTokenPromise } = require('./security'); const { client } = require('./database/redis'); const { parseNumber } = require('./common'); +const BigNumber = require('bignumber.js'); const createUserOrderByKitId = (userKitId, symbol, side, size, type, price = 0, opts = { stop: null, meta: null, additionalHeaders: null }) => { if (symbol && !subscribedToPair(symbol)) { @@ -49,6 +50,14 @@ const executeUserOrder = async (user_id, opts, token) => { } const { symbol, price, side, size, type } = JSON.parse(storedToken); + if (size < 0) { + throw new Error(INVALID_SIZE); + } + + if (price < 0) { + throw new Error(INVALID_PRICE); + } + let res; if (type === 'market') { res = await createUserOrderByKitId(user_id, symbol, side, size, type, 0, opts); @@ -69,6 +78,12 @@ const executeUserOrder = async (user_id, opts, token) => { const broker = await getUserByKitId(brokerPair.user_id); const user = await getUserByKitId(user_id); + const isFairPrice = await isFairPriceForBroker(brokerPair); + + if (!isFairPrice) { + throw new Error(FAIR_PRICE_BROKER_ERROR); + } + const tierBroker = getKitTier(broker.verification_level); const tierUser = getKitTier(user.verification_level); @@ -85,32 +100,55 @@ const executeUserOrder = async (user_id, opts, token) => { { maker: makerFee, taker: takerFee } ); } + else if (type === 'network') { + const user = await getUserByKitId(user_id); + const tierUser = getKitTier(user.verification_level); + const fee = tierUser.fees.taker[symbol]; + res = await getNodeLib().executeQuote(token, user.network_id, fee, opts); + } + else { + throw new Error(QUICK_TRADE_TYPE_NOT_SUPPORTED); + } + await client.delAsync(token); res.type = type; return res; } const getUserQuickTrade = async (spending_currency, spending_amount, receiving_amount, receiving_currency, bearerToken, ip, opts) => { - if (spending_amount) spending_amount = math.number(spending_amount); - if (receiving_amount) receiving_amount = math.number(receiving_amount); + if (spending_amount) spending_amount = new BigNumber(spending_amount).toNumber(); + if (receiving_amount) receiving_amount = new BigNumber(receiving_amount).toNumber(); + if (receiving_amount < 0 || spending_amount < 0) { + throw new Error(AMOUNT_NEGATIVE_ERROR); + } const originalPair = `${spending_currency}-${receiving_currency}`; const flippedPair = `${receiving_currency}-${spending_currency}`; let symbol = originalPair; let side = 'sell'; - // find if broker exists - let broker = await getModel('broker').findOne({ where: { symbol: originalPair } }); + const quickTrades = getQuickTrades(); + let quickTradeConfig = quickTrades.find(quickTrade => quickTrade.symbol === originalPair); - if (!broker) { - broker = await getModel('broker').findOne({ where: { symbol: flippedPair } }); + if (!quickTradeConfig) { + quickTradeConfig = quickTrades.find(quickTrade => quickTrade.symbol === flippedPair); symbol = flippedPair; side = 'buy'; } + if (!quickTradeConfig) throw new Error(QUICK_TRADE_CONFIG_NOT_FOUND); + + if (quickTradeConfig && quickTradeConfig.active && quickTradeConfig.type === 'broker') { + const broker = await getModel('broker').findOne({ where: { symbol } }); + + if (!broker) { + throw new Error(BROKER_NOT_FOUND); + } + if (broker.paused) { + throw new Error(BROKER_PAUSED); + } - if (broker && !broker.paused) { return fetchBrokerQuote({ symbol: symbol, side: side, @@ -124,7 +162,6 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a } }) .then((brokerQuote) => { - const decimalPoint = getDecimals(broker.increment_size); const responseObj = { spending_currency, receiving_currency, @@ -134,18 +171,9 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a type: 'broker' } if (spending_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? spending_amount / brokerQuote.price : spending_amount * brokerQuote.price, - decimalPoint - ); - responseObj.receiving_amount = sourceAmount; - + responseObj.receiving_amount = brokerQuote.receiving_amount; } else if (receiving_amount != null) { - const sourceAmount = math.round( - side === 'buy' ? receiving_amount * brokerQuote.price : receiving_amount / brokerQuote.price, - decimalPoint - ); - responseObj.spending_amount = sourceAmount; + responseObj.spending_amount = brokerQuote.spending_amount;; } const baseCoinSize = side === 'buy' ? responseObj.receiving_amount : responseObj.spending_amount; @@ -153,21 +181,16 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a throw new Error(BROKER_SIZE_EXCEED) } + if (responseObj.receiving_amount < 0 || responseObj.spending_amount < 0) { + throw new Error(PRICE_NOT_FOUND); + } + return responseObj; }) - .catch((err) => { - return reject(new Error(err.message)); - }); } - else { + else if (quickTradeConfig && quickTradeConfig.active && quickTradeConfig.type === 'pro') { try { - symbol = originalPair; - side = 'sell'; - if (!subscribedToPair(symbol)) { - side = 'buy'; - symbol = flippedPair; - } - + if (!subscribedToPair(symbol)) { return reject(new Error(INVALID_SYMBOL(symbol))); } @@ -201,7 +224,7 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a //Check if the estimated price is 50% greater than the last trade const lastTrades = await getPublicTrades(symbol); if (Array.isArray(lastTrades[symbol]) && lastTrades[symbol].length > 0) { - const lastPrice = math.number(lastTrades[symbol][0].price) * 1.50 + const lastPrice = new BigNumber(lastTrades[symbol][0].price).multipliedBy(1.50).toNumber(); if (priceValues.estimatedPrice > lastPrice) { throw new Error(QUICK_TRADE_ORDER_CURRENT_PRICE_ERROR); @@ -238,6 +261,76 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a return reject(new Error(err.message)); } } + else if (quickTradeConfig && quickTradeConfig.active && quickTradeConfig.type === 'network') { + + let user_id = null; + let network_id = null; + if (bearerToken) { + const auth = await verifyBearerTokenPromise(bearerToken, ip); + if (auth) { + user_id = auth.sub.id; + network_id = auth.sub.networkId; + } + } + + const responseObj = { + spending_currency, + receiving_currency, + spending_amount, + receiving_amount, + type: 'network' + } + + const priceValues = await getNodeLib().getQuote( + network_id, + spending_currency, + spending_amount, + receiving_currency, + receiving_amount, + opts + ); + + responseObj.spending_amount = priceValues.spending_amount; + responseObj.receiving_amount = priceValues.receiving_amount; + if (responseObj.spending_amount === 0 || responseObj.receiving_amount === 0) { + throw new Error(QUICK_TRADE_VALUE_IS_TOO_SMALL); + } + + if (user_id) { + responseObj.expiry = priceValues.expiry; + responseObj.token = priceValues.token; + + const tradeData = { + user_id, + symbol, + type: 'network' + }; + + client.setexAsync(priceValues.token, 30, JSON.stringify(tradeData)); + } + + return responseObj; + } + else { + throw new Error(QUICK_TRADE_TYPE_NOT_SUPPORTED); + } +} + +const updateQuickTradeConfig = async ({ symbol, type, active }) => { + const QuickTrade = getModel('quickTrade'); + + const quickTradeData = await QuickTrade.findOne({ where: { symbol } }); + + if (!quickTradeData) { + throw new Error(QUICK_TRADE_CONFIG_NOT_FOUND); + } + + const updatedConfig = { + ...quickTradeData.dataValues, + type, + active + } + return quickTradeData.update(updatedConfig, { fields: ['type', 'active'], returning: true }); } const convertBalance = async (order, user_id, maker_id) => { @@ -1115,7 +1208,8 @@ module.exports = { generateOrderFeeData, dustUserBalance, executeUserOrder, - dustPriceEstimate + dustPriceEstimate, + updateQuickTradeConfig // getUserTradesByKitIdStream, // getUserTradesByNetworkIdStream, // getAllTradesNetworkStream, diff --git a/server/utils/hollaex-tools-lib/tools/security.js b/server/utils/hollaex-tools-lib/tools/security.js index 3e8b4c3359..6bd5453ddc 100644 --- a/server/utils/hollaex-tools-lib/tools/security.js +++ b/server/utils/hollaex-tools-lib/tools/security.js @@ -38,7 +38,8 @@ const { INVALID_TOKEN_TYPE, NO_AUTH_TOKEN, WHITELIST_DISABLE_ADMIN, - WHITELIST_NOT_PROVIDED + WHITELIST_NOT_PROVIDED, + SESSION_NOT_FOUND } = require(`${SERVER_PATH}/messages`); const { NODE_ENV, @@ -49,7 +50,7 @@ const { SECRET, TOKEN_TYPES, HMAC_TOKEN_EXPIRY, - HMAC_TOKEN_KEY + HMAC_TOKEN_KEY, } = require(`${SERVER_PATH}/constants`); const { getNodeLib } = require(`${SERVER_PATH}/init`); const { resolve, reject, promisify } = require('bluebird'); @@ -545,7 +546,7 @@ const verifyBearerTokenMiddleware = (req, authOrSecDef, token, cb, isSocket = fa if (token && token.indexOf('Bearer ') === 0) { const tokenString = token.split(' ')[1]; - jwt.verify(tokenString, SECRET, (verificationError, decodedToken) => { + jwt.verify(tokenString, SECRET, async (verificationError, decodedToken) => { //check if the JWT was verified correctly if (!verificationError && decodedToken) { loggerAuth.verbose( @@ -588,6 +589,11 @@ const verifyBearerTokenMiddleware = (req, authOrSecDef, token, cb, isSocket = fa return sendError(DEACTIVATED_USER); } + try { + await verifySession(tokenString); + } catch (err) { + return sendError(err.message); + } req.auth = decodedToken; return cb(null); } else { @@ -841,6 +847,98 @@ const verifyHmacTokenPromise = (apiKey, apiSignature, apiExpires, method, origin } }; + +const createSession = async (token, loginId, userId) => { + + const { getUserRole } = require('./user'); + + const userRole = await getUserRole({ kit_id: userId }); + + const base64Payload = token.split(".")[1]; + const payloadBuffer = Buffer.from(base64Payload, "base64"); + const decoded = JSON.parse(payloadBuffer.toString()); + + const hashedToken = crypto.createHash('md5').update(token).digest('hex'); + + return getModel('session').create({ + token: hashedToken, + role: userRole, + login_id: loginId, + status: true, + last_seen: new Date(), + expiry_date: new Date(decoded.exp * 1000) + }) +} + +const verifySession = async (token) => { + + const session = await findSession(token); + + if (!session) { + loggerAuth.error( + 'security/verifySession session not found'); + throw new Error(SESSION_NOT_FOUND); + } + + if (!session.status) { + loggerAuth.error( + 'security/verifySession invalid session', + session.status + ); + throw new Error(TOKEN_REVOKED); + } + + if(new Date(session.expiry_date).getTime() < new Date().getTime()) { + throw new Error(TOKEN_EXPIRED); + } + + if(new Date(session.last_seen).getTime() + 1000 * 60 * 5 < new Date().getTime()) { + const hashedToken = crypto.createHash('md5').update(token).digest('hex'); + const sessionData = await dbQuery.findOne('session', { where: { token: hashedToken } }); + const updatedSession = await sessionData.update( + { last_seen: new Date() } + ); + client.setexAsync(updatedSession.dataValues.token, new Date(updatedSession.dataValues.expiry_date).getTime() / 1000, JSON.stringify(updatedSession.dataValues)); + } +} + +const findSession = async (token) => { + + const hashedToken = crypto.createHash('md5').update(token).digest('hex'); + + let session = await client.getAsync(hashedToken) + + if (!session) { + loggerAuth.verbose( + 'security/findSession jwt token not found in redis', + hashedToken + ); + + session = await dbQuery.findOne('session', { + where: { + token: hashedToken + } + }); + + if(session && session.status && new Date(session.expiry_date).getTime() > new Date().getTime()) { + client.setexAsync(hashedToken, new Date(session.expiry_date).getTime() / 1000, JSON.stringify(session)); + + loggerAuth.verbose( + 'security/findSession token stored in redis', + hashedToken + ); + } + + return session; + } else { + loggerAuth.debug( + 'security/findSession token found in redis', + hashedToken + ); + return JSON.parse(session); + } +} + /** * Function that checks to see if user's scope is valid for the endpoint. * @param {array} endpointScopes - Authorized scopes for the endpoint. @@ -1243,5 +1341,8 @@ module.exports = { sendConfirmationEmail, confirmByEmail, calculateSignature, - generateDashToken + generateDashToken, + createSession, + verifySession, + findSession }; diff --git a/server/utils/hollaex-tools-lib/tools/user.js b/server/utils/hollaex-tools-lib/tools/user.js index 415725b9ac..815dc96805 100644 --- a/server/utils/hollaex-tools-lib/tools/user.js +++ b/server/utils/hollaex-tools-lib/tools/user.js @@ -50,9 +50,12 @@ const { USER_NOT_DEACTIVATED, CANNOT_CHANGE_ADMIN_ROLE, VERIFICATION_CODE_USED, - USER_NOT_REGISTERED_ON_NETWORK + USER_NOT_REGISTERED_ON_NETWORK, + SESSION_NOT_FOUND, + SESSION_ALREADY_REVOKED, + WRONG_USER_SESSION } = require(`${SERVER_PATH}/messages`); -const { publisher } = require('./database/redis'); +const { publisher, client } = require('./database/redis'); const { CONFIGURATION_CHANNEL, AUDIT_KEYS, @@ -62,12 +65,16 @@ const { SETTING_KEYS, OMITTED_USER_FIELDS, DEFAULT_ORDER_RISK_PERCENTAGE, - AFFILIATION_CODE_LENGTH + AFFILIATION_CODE_LENGTH, + LOGIN_TIME_OUT, + TOKEN_TIME_LONG, + TOKEN_TIME_NORMAL, + VERIFY_STATUS } = require(`${SERVER_PATH}/constants`); const { sendEmail } = require(`${SERVER_PATH}/mail`); const { MAILTYPE } = require(`${SERVER_PATH}/mail/strings`); const { getKitConfig, isValidTierLevel, getKitTier, isDatetime } = require('./common'); -const { isValidPassword } = require('./security'); +const { isValidPassword, createSession } = require('./security'); const { getNodeLib } = require(`${SERVER_PATH}/init`); const { all, reject } = require('bluebird'); const { Op } = require('sequelize'); @@ -76,6 +83,7 @@ const { parse } = require('json2csv'); const flatten = require('flat'); const uuid = require('uuid/v4'); const { checkCaptcha, validatePassword, verifyOtpBeforeAction } = require('./security'); +const geoip = require('geoip-lite'); let networkIdToKitId = {}; let kitIdToNetworkId = {}; @@ -324,7 +332,10 @@ const registerUserLogin = ( device: null, domain: null, origin: null, - referer: null + referer: null, + token: null, + expiry: null, + status: true, } ) => { const login = { @@ -348,9 +359,65 @@ const registerUserLogin = ( login.referer = opts.referer; } - return getModel('login').create(login); + if (isBoolean(opts.status)) { + login.status = opts.status; + } + + if (opts.status === false) { + login.attempt = 1; + } + const geo = geoip.lookup(ip); + if (geo?.country) login.country = geo.country; + return getModel('login').create(login) + .then((loginData) => { + if(opts.token && opts.status) { + return createSession(opts.token, loginData.id, userId, opts.expiry); + } + }) + .catch(err => reject(err)) }; +const updateLoginAttempt = (loginId) => { + return getModel('login').increment('attempt', { by: 1, where: { id: loginId }}); +} + +const updateLoginStatus = (loginId) => { + return getModel('login').update( { status: true }, { where: { id: loginId } }); +} + +const createUserLogin = async (user, ip, device, domain, origin, referer, token, long_term, status) => { + const loginData = await findUserLatestLogin(user, status); + + if (!loginData || loginData?.status == true) { + return registerUserLogin(user.id, ip, { + device, + domain, + origin, + referer, + token, + status, + expiry: long_term ? TOKEN_TIME_LONG : TOKEN_TIME_NORMAL + }); + } + else if (loginData.status == false) { + await updateLoginAttempt(loginData.id); + } +} + + +const findUserLatestLogin = (user, status) => { + return getModel('login').findOne({ + order: [ [ 'timestamp', 'DESC' ]], + where: { + user_id: user.id, + ...(status != null && { status }), + updated_at: { + [Op.gte]: new Date(new Date().getTime() - LOGIN_TIME_OUT) + }, + } + }); +} + /* Public Endpoints*/ @@ -518,188 +585,122 @@ const getAllUsersAdmin = (opts = { end_date: null, format: null, type: null, + email: null, + username: null, + full_name: null, + pending_verification: null, + dob_start_date: null, + dob_end_date: null, + gender: null, + nationality: null, + verification_level: null, + email_verified: null, + otp_enabled: null, + phone_number: null, + kyc: null, + bank: null, additionalHeaders: null }) => { + const { + id, + gender, + email_verified, + otp_enabled, + dob_start_date, + dob_end_date + } = opts; + const pagination = paginationQuery(opts.limit, opts.page); const timeframe = timeframeQuery(opts.start_date, opts.end_date); + const dob_timeframe = timeframeQuery(dob_start_date, dob_end_date); const ordering = orderingQuery(opts.order_by, opts.order); let query = { where: { - created_at: timeframe - } + created_at: timeframe, + ...(id != null && { id }), + ...((dob_start_date != null || dob_end_date != null) && { dob: dob_timeframe }), + ...(email_verified != null && { email_verified }), + ...(gender != null && { gender }), + ...(otp_enabled != null && { otp_enabled }), + [Op.and]: [], + }, + order: [ordering] + }; + query.attributes = { + exclude: ['balance', 'password', 'updated_at'] }; - if (opts.id || opts.search) { + + if (opts.search) { query.attributes = { exclude: ['balance', 'password', 'updated_at'] }; if (opts.id) { query.where.id = opts.id; } - else if (opts.type != null) { - query.where = { - [Op.or]: [] - }; - - switch (opts.type) { - case 'id': - query.where[Op.or].push( - { - id: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'email': - query.where[Op.or].push( - { - email: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'crypto_wallet': - query.where[Op.or].push( - { - crypto_wallet: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'createdAt': - query.where[Op.or].push( - { - createdAt: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'updatedAt': - query.where[Op.or].push( - { - updatedAt: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'id_data': - query.where[Op.or].push(getModel('sequelize').literal(`id_data ->> 'number'='${opts.search}'`)); - break; - case 'phone_number': - query.where[Op.or].push( - { - phone_number: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'verification_level': - query.where[Op.or].push( - { - verification_level: { - [Op.like]: `%${opts.search}%` - } - } - ); - break; - case 'pending_verification': - query.where[Op.or].push( - { - id_data: { - status: 1 - } - } - ); - break; - case 'pending_bank': - query.where[Op.or].push(getModel('sequelize').literal('bank_account @> \'[{"status":1}]\'')); - break; - default: - break; - } - - } - else { - query.where = { - [Op.or]: [ - { - email: { - [Op.like]: `%${opts.search}%` - } - }, - { - username: { - [Op.like]: `%${opts.search}%` - } - }, - { - full_name: { - [Op.like]: `%${opts.search}%` - } - }, - { - phone_number: { - [Op.like]: `%${opts.search}%` - } - }, - getModel('sequelize').literal(`id_data ->> 'number'='${opts.search}'`) - ] - }; - } - } else if (isBoolean(opts.pending) && opts.pending) { - - query = { - attributes: [ - 'id', - 'email', - 'verification_level', - 'id_data', - 'bank_account', - 'activated' - ], - order: [['updated_at', 'desc']] + query.where = { + [Op.or]: [ + { + email: { + [Op.like]: `%${opts.search}%` + } + }, + { + username: { + [Op.like]: `%${opts.search}%` + } + }, + { + full_name: { + [Op.like]: `%${opts.search}%` + } + }, + { + phone_number: { + [Op.like]: `%${opts.search}%` + } + }, + getModel('sequelize').literal(`id_data ->> 'number'='${opts.search}'`) + ] }; + } + Object.keys(pick(opts, ['email', 'nationality', 'username', 'full_name', 'phone_number'])).forEach(key => { + if(opts[key] != null) { + query.where[Op.and].push( + { + [key]: { + [Op.like]: `%${opts[key]}%` + } + } + ) + } + }) + + if (isNumber(opts.verification_level)) { + query.where[Op.and].push({ verification_level: opts.verification_level }); + } + if (isBoolean(opts.pending) && opts.pending) { + query.order = [['updated_at', 'desc']]; - if (opts.pending_type) { - if (opts.pending_type === 'id') { - query.where = { - activated: true, + if ((opts.kyc && Object.values(VERIFY_STATUS).includes(opts.kyc)) || opts.pending_type === 'id') { + query.where[Op.and] = [ + ...query.where[Op.and], + { activated: true }, + { id_data: { - status: 1 // users that have a pending id waiting for admin to confirm + status: opts.kyc != null ? opts.kyc : 1 // users that have a pending id waiting for admin to confirm } - }; - } else if (opts.pending_type === 'bank') { - query.where = { - [Op.and]: [ - { activated: true }, - { - id_data: { - status: 3 // users that have a pending id waiting for admin to confirm - } - }, - getModel('sequelize').literal('bank_account @> \'[{"status":1}]\'') // users that have a pending bank waiting for admin to confirm - ] - }; - } else { - throw new Error('pending type is not defined. You need to select id or bank is pending_type'); - } - } else { - throw new Error('pending type is not defined. You need to select id or bank is pending_type'); + }, + ] + } + + if (opts.bank || opts.pending_type === 'bank') { + query.where[Op.and] = [ + ...query.where[Op.and], + { activated: true }, + getModel('sequelize').literal('bank_account @> \'[{"status":1}]\'') // users that have a pending bank waiting for admin to confirm + ] } - } else { - query = { - where: {}, - attributes: { - exclude: ['password', 'is_admin', 'is_support', 'is_supervisor', 'is_kyc', 'is_communicator'] - }, - order: [ordering] - }; } if (!opts.format) { @@ -711,12 +712,7 @@ const getAllUsersAdmin = (opts = { return dbQuery.findAndCountAllWithRows('user', query) .then(async ({ count, data }) => { if (opts.id || opts.search) { - if (count === 0) { - // Need to throw error if query was for one user and the user is not found - const error = new Error(USER_NOT_FOUND); - error.status = 404; - throw error; - } else if (data[0].verification_level > 0 && data[0].network_id) { + if (count > 0 && data[0].verification_level > 0 && data[0].network_id) { const userNetworkData = await getNodeLib().getUser(data[0].network_id, { additionalHeaders: opts.additionalHeaders }); data[0].balance = userNetworkData.balance; data[0].wallet = userNetworkData.wallet; @@ -851,9 +847,31 @@ const freezeUserById = (userId) => { if (!user.activated) { throw new Error(USER_ALREADY_DEACTIVATED); } + if (user.is_admin) { + throw new Error(CANNOT_DEACTIVATE_ADMIN); + } return user.update({ activated: false }, { fields: ['activated'], returning: true }); }) - .then((user) => { + .then(async (user) => { + const sessions = await getModel('session').findAll( + { + where: { status: true }, + include: [ + { + model: getModel('login'), + as: 'login', + attributes: ['user_id'], + where: { user_id: userId } + } + ] + }); + + for (const session of sessions) { + await session.update({ status: false }, { fields: ['status'] }); + client.delAsync(session.token); + } + + publisher.publish(CONFIGURATION_CHANNEL, JSON.stringify({ type: 'freezeUser', data: user.id })); sendEmail( MAILTYPE.USER_DEACTIVATED, @@ -873,7 +891,7 @@ const freezeUserByEmail = (email) => { if (!user) { throw new Error(USER_NOT_FOUND); } - if (user.id === 1) { + if (user.is_admin) { throw new Error(CANNOT_DEACTIVATE_ADMIN); } if (!user.activated) { @@ -1251,6 +1269,7 @@ const toggleFlaggedUserById = (userId) => { const getUserLogins = (opts = { userId: null, + status: null, limit: null, page: null, orderBy: null, @@ -1264,7 +1283,8 @@ const getUserLogins = (opts = { const ordering = orderingQuery(opts.orderBy, opts.order); let options = { where: { - timestamp: timeframe + timestamp: timeframe, + ...(opts.status != null && { status: opts.status }) }, attributes: { exclude: ['id', 'origin', 'referer'] @@ -1876,6 +1896,148 @@ const updateUserInfo = async (userId, data = {}) => { return omitUserFields(user.dataValues); }; +const getExchangeUserSessions = (opts = { + user_id: null, + status: null, + limit: null, + page: null, + order_by: null, + order: null, + start_date: null, + end_date: null, + format: null +}) => { + + const pagination = paginationQuery(opts.limit, opts.page); + const ordering = orderingQuery(opts.order_by, opts.order); + const timeframe = timeframeQuery(opts.start_date, opts.end_date); + + return dbQuery.findAndCountAllWithRows('session', { + where: { + ...(opts.status != null && { status: opts.status }), + created_at: timeframe, + expiry_date: { + [Op.gt]: new Date() + }, + }, + attributes: { + exclude: ['token'] + }, + include: [ + { + model: getModel('login'), + as: 'login', + ...(opts.user_id && { where: { user_id: opts.user_id } }), + include: [ + { + model: getModel('user'), + attributes: ['id', 'email'] + }, + ] + } + ], + order: [ordering], + ...(!opts.format && pagination), + }) + .then((sessions) => { + if (opts.format && opts.format === 'csv') { + if (sessions.data.length === 0) { + throw new Error(NO_DATA_FOR_CSV); + } + const csv = parse(sessions.data, Object.keys(sessions.data[0])); + return csv; + } else { + return sessions; + } + }); +} + +const revokeExchangeUserSession = async (sessionId, userId = null) => { + const session = await getModel('session').findOne({ + include: [ + { + model: getModel('login'), + as: 'login', + attributes: ['user_id'], + ...(userId && { where: { user_id: userId } }) + } + ], + where: { id: sessionId } }); + + + if(!session) { + throw new Error(SESSION_NOT_FOUND); + } + + if(!session.status) { + throw new Error(SESSION_ALREADY_REVOKED); + } + + if (userId && session.login.user_id !== userId) { + throw new Error(WRONG_USER_SESSION); + } + + client.delAsync(session.token); + + const updatedSession = await session.update({ status: false }, { + fields: ['status'] + }); + + delete updatedSession.dataValues.token; + return updatedSession.dataValues; +} + +const getAllBalancesAdmin = async (opts = { + user_id: null, + currency: null, + format: null, + additionalHeaders: null +}) => { + + let network_id = null; + if (opts.user_id) { + // check mapKitIdToNetworkId + const idDictionary = await mapKitIdToNetworkId([opts.user_id]); + if (!has(idDictionary, opts.user_id)) { + throw new Error(USER_NOT_FOUND); + } else if (!idDictionary[opts.user_id]) { + throw new Error(USER_NOT_REGISTERED_ON_NETWORK); + } else { + network_id = idDictionary[opts.user_id]; + } + } + + return getNodeLib().getBalances({ + userId: network_id, + currency: opts.currency, + format: opts.format, + additionalHeaders: opts.additionalHeaders + }) + .then(async (balances) => { + if (balances.data.length > 0) { + const networkIds = balances.data.map((balance) => balance.user_id).filter(id => id); + const idDictionary = await mapNetworkIdToKitId(networkIds); + for (let balance of balances.data) { + const user_kit_id = idDictionary[balance.user_id]; + balance.network_id = balance.user_id; + balance.user_id = user_kit_id; + if (balance.User) balance.User.id = user_kit_id; + } + } + + if (opts.format && opts.format === 'all') { + if (balances.data.length === 0) { + throw new Error(NO_DATA_FOR_CSV); + } + const csv = parse(balances.data, Object.keys(balances.data[0])); + return csv; + } else { + return balances; + } + }); +} + + module.exports = { loginUser, getUserTier, @@ -1926,5 +2088,12 @@ module.exports = { updateUserMeta, mapNetworkIdToKitId, mapKitIdToNetworkId, - updateUserInfo + updateUserInfo, + updateLoginAttempt, + getExchangeUserSessions, + revokeExchangeUserSession, + updateLoginStatus, + findUserLatestLogin, + createUserLogin, + getAllBalancesAdmin }; diff --git a/server/utils/orderbook.js b/server/utils/orderbook.js index 6569188c83..20c480787f 100644 --- a/server/utils/orderbook.js +++ b/server/utils/orderbook.js @@ -1,17 +1,7 @@ 'use strict'; const { getOrderbook, getKitPairsConfig } = require('./hollaex-tools-lib/tools/common'); const math = require('mathjs'); -const getDecimals = (value = 0) => { - if (Math.floor(value) === value) return 0; - - let str = value.toString(); - if (str.indexOf('.') !== -1 && str.indexOf('-') !== -1) { - return str.split('-')[1] || 0; - } else if (str.indexOf('.') !== -1) { - return str.split('.')[1].length || 0; - } - return str.split('-')[1] || 0; -}; +const BigNumber = require('bignumber.js'); const sumQuantities = (orders) => orders.reduce((total, [, size]) => math.add(total, size), 0); @@ -70,7 +60,7 @@ const setPriceEssentials = async (priceEssentials, opts) => { const pairData = getKitPairsConfig()[pair] || {}; let priceValues = {}; - const decimalPoint = getDecimals(pairData.increment_size); + const decimalPoint = new BigNumber(pairData.increment_size).dp(); let [estimatedPrice] = estimatedQuickTradePriceSelector({ pairsOrders, pair, @@ -180,7 +170,6 @@ const calculateMarketPrice = (orderSize = 0, orders = []) => [0, 0] ); module.exports = { - getDecimals, sumQuantities, sumOrderTotal, estimatedQuickTradePriceSelector, diff --git a/version b/version index 952f449f1f..9aa34646dc 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.6.6 \ No newline at end of file +2.7.0 \ No newline at end of file diff --git a/web/docker/Dockerfile b/web/docker/Dockerfile index 4c6352c4bb..b9fa6ea857 100644 --- a/web/docker/Dockerfile +++ b/web/docker/Dockerfile @@ -1,10 +1,10 @@ # build environment -FROM node:12.22.7-buster as build +FROM node:14-buster-slim as build ENV NODE_OPTIONS=--max_old_space_size=4096 +ENV GENERATE_SOURCEMAP=false WORKDIR /app COPY package.json /app/package.json -RUN npm config set unsafe-perm true && \ - npm install -g node-gyp && \ +RUN npm install -g node-gyp && \ npm install --loglevel=error COPY . /app RUN npm run build diff --git a/web/package-lock.json b/web/package-lock.json index 00d18238f1..48e04ff277 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "hollaex-kit", - "version": "2.6.5", + "version": "2.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -132,7 +132,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -1876,12 +1876,12 @@ "@material/animation": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@material/animation/-/animation-0.4.1.tgz", - "integrity": "sha512-UOClBDK6Vsr1quD34x1bBfyx7Sx39TdIs38HJPU/dqq5xW15nQYPON+LSI+7XYKwf6OcxUdUAcDggjwf6tkRbA==" + "integrity": "sha1-v4tQrtrUz/zopbQo/cqPGruvF24=" }, "@material/base": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@material/base/-/base-0.2.6.tgz", - "integrity": "sha512-Bzj7sUrUXdQYPEV+SQU0nxZFCmO3XgyjngP0TrdEg93VFD8Fyj10f3/M3XD7LgoNoDxo9mWU6Thiqjfb32clKg==" + "integrity": "sha1-MAPz3ywG0XIVHUFguMiy5sZefAE=" }, "@material/button": { "version": "0.7.0", @@ -1897,7 +1897,7 @@ "@material/elevation": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-0.1.13.tgz", - "integrity": "sha512-erp/REf9gVVj42cATyxVV7DJqJBQyefYdbvuu9qgjug3UdCF46E3bcO8O558EX7tZCNDZy3A1vI16fG3ETN74Q==", + "integrity": "sha1-o4iF88r0OYymp0aMMIiH1wvUYFs=", "requires": { "@material/animation": "^0.4.1" } @@ -1905,7 +1905,7 @@ "@material/ripple": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-0.8.8.tgz", - "integrity": "sha512-9bJe2X0x2LyB93Lp4jspGQkUmI0OzOSUTXVrdcOwxhcj9/MH55iYM3YRON8bXY9dHaUrNldzY8J81RwQCCYBww==", + "integrity": "sha1-Irie2eY4g/F/pPANEjcOMuDEWbc=", "requires": { "@material/base": "^0.2.6", "@material/theme": "^0.4.0" @@ -1914,7 +1914,7 @@ "@material/theme": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@material/theme/-/theme-0.4.0.tgz", - "integrity": "sha512-2VXMuMR9yJTnXJF3gt5KmkiYVUA3Ts1TN3ihKKoluZjk8vxpHw1RmG4664Rrdhnoxn4KGdTOsOoAaPseKiL9lw==" + "integrity": "sha1-Cu8aAnm2XBWZBYT7i47KCVxzRkE=" } } }, @@ -1926,7 +1926,7 @@ "@material/typography": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@material/typography/-/typography-0.3.0.tgz", - "integrity": "sha512-H7YjYKoCJPd6MGWSlhauki+HpS7dQfJ1RQ2hm6Lu6tAu/xi/UqDxfRRYNHhIq79LTILBqqDm+e+LsQVydaFDqg==" + "integrity": "sha1-+CjC0yFb/WbFgHJwm0JgxkElOQo=" }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", @@ -2068,7 +2068,7 @@ "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { "caller-path": "^2.0.0", @@ -2078,7 +2078,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -2130,7 +2130,7 @@ "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { "caller-path": "^2.0.0", @@ -2140,7 +2140,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -2306,7 +2306,7 @@ "@types/object-assign": { "version": "4.0.30", "resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz", - "integrity": "sha512-HhE8gFfLj321pa6OE59QmOdL5NgIOhkdYn7MWnZTOcHOms8XFzNgr9+A0/GbN0XEX9wTM58yg4YXKhGr69QIUw==" + "integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI=" }, "@types/parse-json": { "version": "4.0.0", @@ -2740,7 +2740,7 @@ "add-px-to-style": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-px-to-style/-/add-px-to-style-1.0.0.tgz", - "integrity": "sha512-YMyxSlXpPjD8uWekCQGuN40lV4bnZagUwqa2m/uFv1z/tNImSk9fnXVMUI5qwME/zzI3MMQRvjZ+69zyfSSyew==" + "integrity": "sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo=" }, "address": { "version": "1.1.2", @@ -2770,7 +2770,7 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, "json5": { @@ -2847,13 +2847,13 @@ "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-colors": { @@ -2882,7 +2882,7 @@ "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", "dev": true }, "ansi-regex": { @@ -3156,7 +3156,7 @@ "aria-query": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", "dev": true, "requires": { "ast-types-flow": "0.0.7", @@ -3174,13 +3174,13 @@ "arity-n": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==", + "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=", "dev": true }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "arr-flatten": { @@ -3192,25 +3192,25 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-includes": { "version": "3.1.3", @@ -3238,7 +3238,7 @@ "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { "array-uniq": "^1.0.1" @@ -3247,13 +3247,13 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "array.prototype.find": { @@ -3284,7 +3284,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "asn1": { "version": "0.2.4", @@ -3308,7 +3308,7 @@ "assert": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha512-N+aAxov+CKVS3JuhDIQFr24XvZvwE96Wlhk9dytTg/GmwWoghdOvR8dspx8MVz71O+Y0pA3UPqHF68D6iy8UvQ==", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", "dev": true, "requires": { "util": "0.10.3" @@ -3317,13 +3317,13 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", "dev": true }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { "inherits": "2.0.1" @@ -3334,18 +3334,18 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", "dev": true }, "astral-regex": { @@ -3372,7 +3372,7 @@ "async-foreach": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, "async-limiter": { @@ -3388,7 +3388,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -3432,7 +3432,7 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.11.0", @@ -3456,7 +3456,7 @@ "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { "chalk": "^1.1.3", @@ -3467,19 +3467,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -3492,13 +3492,13 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -3507,7 +3507,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } @@ -3632,7 +3632,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } @@ -3737,13 +3737,13 @@ "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", "dev": true }, "babel-plugin-transform-object-rest-spread": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "dev": true, "requires": { "babel-plugin-syntax-object-rest-spread": "^6.8.0", @@ -3934,7 +3934,7 @@ "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -3981,7 +3981,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -4034,13 +4034,13 @@ "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "requires": { "tweetnacl": "^0.14.3" } @@ -4080,7 +4080,7 @@ "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ==", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { "inherits": "~2.0.0" @@ -4116,7 +4116,7 @@ "bonjour": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { "array-flatten": "^2.1.0", @@ -4138,7 +4138,7 @@ "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, "brace-expansion": { @@ -4171,7 +4171,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -4187,7 +4187,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-process-hrtime": { "version": "1.0.0", @@ -4207,7 +4207,7 @@ "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } } @@ -4228,7 +4228,7 @@ "browserify-bignum": { "version": "1.3.0-2", "resolved": "https://registry.npmjs.org/browserify-bignum/-/browserify-bignum-1.3.0-2.tgz", - "integrity": "sha512-PwVvKC3WIV7ENfsG6VAIDq4R5st6kQt+Fod3WL5l7+MRONClo3J6xGQvRJHHM/ScwcNCH3GfYX5UOCuoNN/rLw==" + "integrity": "sha1-3cO27WB/1slglmlQ4rNaKwxvub8=" }, "browserify-cipher": { "version": "1.0.1", @@ -4320,7 +4320,7 @@ "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "requires": { "base-x": "^3.0.2" } @@ -4367,12 +4367,12 @@ "buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" + "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "bufferutil": { "version": "4.0.3", @@ -4385,7 +4385,7 @@ "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, "bundle": { @@ -4549,7 +4549,7 @@ "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { "callsites": "^2.0.0" @@ -4558,7 +4558,7 @@ "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true } } @@ -4566,7 +4566,7 @@ "caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { "caller-callsite": "^2.0.0" @@ -4645,12 +4645,12 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "cbor-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cbor-js/-/cbor-js-0.1.0.tgz", - "integrity": "sha512-7sQ/TvDZPl7csT1Sif9G0+MA0I0JOVah8+wWlJVQdVEgIbCzlN/ab3x+uvMNsc34TUvO6osQTAmB2ls80JX6tw==" + "integrity": "sha1-yAzmEg84fo+qdDcN/aIdlluPx/k=" }, "chalk": { "version": "2.4.2", @@ -4797,7 +4797,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -4919,7 +4919,7 @@ "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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { @@ -4958,7 +4958,7 @@ "clone-deep": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", - "integrity": "sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg==", + "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", "dev": true, "requires": { "for-own": "^0.1.3", @@ -4971,7 +4971,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -4995,7 +4995,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, "coa": { @@ -5012,13 +5012,13 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { "map-visit": "^1.0.0", @@ -5045,7 +5045,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.6.0", @@ -5091,7 +5091,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "compare-versions": { @@ -5108,7 +5108,7 @@ "component-classes": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz", - "integrity": "sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==", + "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=", "requires": { "component-indexof": "0.0.3" } @@ -5122,12 +5122,12 @@ "component-indexof": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz", - "integrity": "sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==" + "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=" }, "compose-function": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", "dev": true, "requires": { "arity-n": "^1.0.4" @@ -5160,7 +5160,7 @@ "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true } } @@ -5173,12 +5173,12 @@ "computed-style": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz", - "integrity": "sha512-WpAmaKbMNmS3OProfHIdJiNleNJdgUrJfbKArXua28QF7+0CoZjlLn0lp6vlc+dl5r2/X9GQiQRQQU4BzSa69w==" + "integrity": "sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -5239,7 +5239,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "consolidated-events": { @@ -5250,13 +5250,13 @@ "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, "content-disposition": { @@ -5299,7 +5299,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "cookiejar": { "version": "2.1.2", @@ -5343,7 +5343,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "copy-to-clipboard": { @@ -5386,7 +5386,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cors": { "version": "2.8.5", @@ -5433,7 +5433,7 @@ "country-data": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/country-data/-/country-data-0.0.31.tgz", - "integrity": "sha512-YqlY/i6ikZwoBFfdjK+hJTGaBdTgDpXLI15MCj2UsXZ2cPBb+Kx86AXmDH7PRGt0LUleck0cCgNdWeIhfbcxkQ==", + "integrity": "sha1-gJZrjh0Uf6bWpYnTKTP4eTd0lW0=", "requires": { "currency-symbol-map": "~2", "underscore": ">1.4.4" @@ -5592,7 +5592,7 @@ "css-b64-images": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/css-b64-images/-/css-b64-images-0.2.5.tgz", - "integrity": "sha512-TgQBEdP07adhrDfXvI5o6bHGukKBNMzp2Ngckc/6d09zpjD2gc1Hl3Ca1CKgb8FXjHi88+Phv2Uegs2kTL4zjg==" + "integrity": "sha1-QgBdgyBLK0pdk7axpWRBM7WSegI=" }, "css-blank-pseudo": { "version": "0.1.4", @@ -5611,7 +5611,7 @@ "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", "dev": true }, "css-declaration-sorter": { @@ -5773,7 +5773,7 @@ "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { "caller-path": "^2.0.0", @@ -5783,7 +5783,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -5829,13 +5829,13 @@ "cssnano-util-get-arguments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", "dev": true }, "cssnano-util-get-match": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", "dev": true }, "cssnano-util-raw-cache": { @@ -5903,12 +5903,12 @@ "currency-symbol-map": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/currency-symbol-map/-/currency-symbol-map-2.2.0.tgz", - "integrity": "sha512-fPZJ3jqM68+AAgqQ7UaGbgHL/39rp6l7GyqS2k1HJPu/kpS8D07x/+Uup6a9tCUKIlOFcRrDCf1qxSt8jnI5BA==" + "integrity": "sha1-KzwYcv8aws5ZXYJz5Y4f/wJyrqI=" }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { "array-find-index": "^1.0.1" @@ -5923,7 +5923,7 @@ "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, "d": { @@ -5957,7 +5957,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "^1.0.0" } @@ -6007,7 +6007,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decamelize-keys": { @@ -6041,7 +6041,7 @@ "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "requires": { "mimic-response": "^1.0.0" } @@ -6049,13 +6049,13 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, "deep-diff": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", - "integrity": "sha512-yVn6RZmHiGnxRKR9sJb3iVV2XTF1Ghh2DiWRZ3dMnGc43yUdWWF/kX6lQyk3+P84iprfWKU/8zFTrlkvtFm1ug==" + "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" }, "deep-equal": { "version": "1.1.1", @@ -6119,7 +6119,7 @@ "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" @@ -6199,7 +6199,7 @@ "globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { "array-union": "^1.0.1", @@ -6212,7 +6212,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } @@ -6243,12 +6243,12 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, "depd": { @@ -6273,7 +6273,7 @@ "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, "detect-node": { @@ -6325,7 +6325,7 @@ "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", "dev": true }, "dns-packet": { @@ -6341,7 +6341,7 @@ "dns-txt": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", "dev": true, "requires": { "buffer-indexof": "^1.0.0" @@ -6381,7 +6381,7 @@ "dom-css": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dom-css/-/dom-css-2.1.0.tgz", - "integrity": "sha512-w9kU7FAbaSh3QKijL6n59ofAhkkmMJ31GclJIz/vyQdjogfyxcB6Zf8CZyibOERI5o0Hxz30VmJS7+7r5fEj2Q==", + "integrity": "sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI=", "requires": { "add-px-to-style": "1.0.0", "prefix-style": "2.0.1", @@ -6400,7 +6400,7 @@ "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", - "integrity": "sha512-LwNVg3GJOprWDO+QhLL1Z9MMgWe/KAFLxVWKzjRTxNSPn8/LLDIfmuG71YHznXCqaqTjvHJDYO1MEAgX6XCNbQ==" + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=" }, "dom-serializer": { "version": "0.2.2", @@ -6605,7 +6605,7 @@ "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -6614,7 +6614,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { "version": "1.3.806", @@ -6659,7 +6659,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "encoding": { "version": "0.1.13", @@ -6769,7 +6769,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" } } }, @@ -6825,7 +6825,7 @@ "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -6850,7 +6850,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-latex": { "version": "1.2.0", @@ -6860,7 +6860,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.14.3", @@ -7185,7 +7185,7 @@ "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { "esutils": "^2.0.2", @@ -7195,7 +7195,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -7204,7 +7204,7 @@ "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -7216,7 +7216,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -7235,7 +7235,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -7244,13 +7244,13 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -7259,13 +7259,13 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { "pify": "^2.0.0" @@ -7274,13 +7274,13 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "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": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { "load-json-file": "^2.0.0", @@ -7291,7 +7291,7 @@ "read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { "find-up": "^2.0.0", @@ -7459,12 +7459,12 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eth-ens-namehash": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", + "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", "requires": { "idna-uts46-hx": "^2.3.1", "js-sha3": "^0.5.7" @@ -7558,7 +7558,7 @@ "ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", "requires": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" @@ -7567,7 +7567,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" } } }, @@ -7694,12 +7694,12 @@ "exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "exit-on-epipe": { @@ -7710,7 +7710,7 @@ "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { "debug": "^2.3.3", @@ -7725,7 +7725,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -7734,7 +7734,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -7816,7 +7816,7 @@ "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { "assign-symbols": "^1.0.0", @@ -7864,7 +7864,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -7873,7 +7873,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -7913,7 +7913,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "eyes": { "version": "0.1.8", @@ -7948,13 +7948,13 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -8045,7 +8045,7 @@ "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -8057,7 +8057,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -8131,7 +8131,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "pify": { @@ -8258,13 +8258,13 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "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": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { "for-in": "^1.0.1" @@ -8278,7 +8278,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "fork-ts-checker-webpack-plugin": { "version": "3.1.1", @@ -8319,7 +8319,7 @@ "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { "map-cache": "^0.2.2" @@ -8328,12 +8328,12 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -8387,7 +8387,7 @@ "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -8485,7 +8485,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "functions-have-names": { @@ -8496,7 +8496,7 @@ "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "requires": { "aproba": "^1.0.3", @@ -8512,13 +8512,13 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -8527,7 +8527,7 @@ "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -8538,7 +8538,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -8586,7 +8586,7 @@ "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, "get-stream": { @@ -8597,13 +8597,13 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "^1.0.0" } @@ -8624,7 +8624,7 @@ "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { "is-glob": "^3.1.0", @@ -8634,7 +8634,7 @@ "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -8645,7 +8645,7 @@ "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", "dev": true }, "global": { @@ -8756,7 +8756,7 @@ "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, "gzip-size": { @@ -8786,7 +8786,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.5", @@ -8820,7 +8820,7 @@ "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -8829,7 +8829,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true } } @@ -8842,12 +8842,12 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", - "integrity": "sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g==", + "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", "dev": true, "requires": { "is-glob": "^3.0.0" @@ -8856,7 +8856,7 @@ "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -8893,13 +8893,13 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "^2.0.6", @@ -8910,7 +8910,7 @@ "has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -8920,7 +8920,7 @@ "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -8978,7 +8978,7 @@ "history": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", - "integrity": "sha512-ABLnJwKEZGXGqWsXaKYD8NNle49ZbKs1WEBlxrFsQ8dIudZpO5NJaH8WJOqh5lXVhAq7bHksfirrobBmrT7qBw==", + "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=", "requires": { "invariant": "^2.2.1", "loose-envify": "^1.2.0", @@ -8989,7 +8989,7 @@ "query-string": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", "requires": { "object-assign": "^4.1.0", "strict-uri-encode": "^1.0.0" @@ -8998,7 +8998,7 @@ "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", "requires": { "loose-envify": "^1.0.0" } @@ -9008,7 +9008,7 @@ "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -9041,7 +9041,7 @@ "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -9079,13 +9079,13 @@ "hsl-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", "dev": true }, "hsla-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", "dev": true }, "html-encoding-sniffer": { @@ -9223,7 +9223,7 @@ "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", "dev": true }, "http-errors": { @@ -9248,7 +9248,7 @@ "http-https": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==" + "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" }, "http-proxy": { "version": "1.18.1", @@ -9276,7 +9276,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -9286,7 +9286,7 @@ "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "human-signals": { @@ -9396,7 +9396,7 @@ "identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", "dev": true, "requires": { "harmony-reflect": "^1.4.6" @@ -9413,7 +9413,7 @@ "punycode": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==" + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" } } }, @@ -9425,7 +9425,7 @@ "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, "ignore": { @@ -9443,12 +9443,12 @@ "immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==" + "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", "dev": true, "requires": { "import-from": "^2.1.0" @@ -9467,7 +9467,7 @@ "import-from": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", "dev": true, "requires": { "resolve-from": "^3.0.0" @@ -9476,7 +9476,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -9522,7 +9522,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "pkg-dir": { @@ -9539,7 +9539,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "in-publish": { @@ -9557,7 +9557,7 @@ "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, "infer-owner": { @@ -9661,7 +9661,7 @@ "insert-css": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", - "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==" + "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ=" }, "internal-ip": { "version": "4.3.0", @@ -9694,7 +9694,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "ip": { @@ -9706,7 +9706,7 @@ "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true }, "ipaddr.js": { @@ -9717,13 +9717,13 @@ "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -9732,7 +9732,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -9803,7 +9803,7 @@ "is-color-stop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", "dev": true, "requires": { "css-color-names": "^0.0.4", @@ -9825,7 +9825,7 @@ "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -9834,7 +9834,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -9872,7 +9872,7 @@ "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, "is-docker": { @@ -9890,13 +9890,13 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { @@ -9942,7 +9942,7 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==" + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" }, "is-negative-zero": { "version": "2.0.1", @@ -9952,7 +9952,7 @@ "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -9961,7 +9961,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -9980,7 +9980,7 @@ "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, "is-object": { @@ -10015,7 +10015,7 @@ "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" }, "is-plain-object": { "version": "2.0.4", @@ -10042,7 +10042,7 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, "is-resolvable": { @@ -10065,7 +10065,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-string": { "version": "1.0.7", @@ -10103,7 +10103,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-unicode-supported": { "version": "0.1.0", @@ -10114,7 +10114,7 @@ "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-windows": { @@ -10126,29 +10126,29 @@ "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" @@ -10157,7 +10157,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -10307,7 +10307,7 @@ "javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" }, "jest": { "version": "24.9.0", @@ -10380,7 +10380,7 @@ "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" @@ -10606,7 +10606,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -11000,7 +11000,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { "version": "11.12.0", @@ -11068,7 +11068,7 @@ "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, "json-parse-better-errors": { "version": "1.0.2", @@ -11103,18 +11103,18 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", - "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", "requires": { "string-convert": "^0.2.0" } @@ -11137,7 +11137,7 @@ "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "requires": { "graceful-fs": "^4.1.6" } @@ -11183,7 +11183,7 @@ "jwt-decode": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", - "integrity": "sha512-86GgN2vzfUu7m9Wcj63iUkuDzFNYFVmjeDm2GzWpUk+opB0pEpMsw6ePCMrhYkumz2C1ihqtZzOMAg7FiXcNoQ==" + "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" }, "keccak": { "version": "3.0.1", @@ -11197,7 +11197,7 @@ "keycode": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", - "integrity": "sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A==" + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" }, "keyv": { "version": "3.1.0", @@ -11238,13 +11238,13 @@ "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" @@ -11274,7 +11274,7 @@ "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -11284,7 +11284,7 @@ "line-height": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz", - "integrity": "sha512-YExecgqPwnp5gplD2+Y8e8A5+jKpr25+DzMbFdI1/1UAr0FJrTFv4VkHLf8/6B590i1wUPJWMKKldkd/bdQ//w==", + "integrity": "sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=", "requires": { "computed-style": "~0.1.3" } @@ -11470,7 +11470,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -11491,7 +11491,7 @@ "find-cache-dir": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { "commondir": "^1.0.1", @@ -11502,7 +11502,7 @@ "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -11521,7 +11521,7 @@ "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -11530,7 +11530,7 @@ "pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { "find-up": "^1.0.0" @@ -11588,18 +11588,18 @@ "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.isempty": { "version": "4.4.0", @@ -11610,7 +11610,7 @@ "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" }, "lodash.isnumber": { "version": "3.0.3", @@ -11620,7 +11620,7 @@ "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, "lodash.merge": { @@ -11631,7 +11631,7 @@ "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, "lodash.template": { @@ -11656,13 +11656,13 @@ "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, "lodash.upperfirst": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==" + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=" }, "log-symbols": { "version": "4.1.0", @@ -11802,7 +11802,7 @@ "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { "currently-unhandled": "^0.4.1", @@ -11835,7 +11835,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } @@ -11875,7 +11875,7 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-obj": { @@ -11887,7 +11887,7 @@ "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { "object-visit": "^1.0.0" @@ -11927,12 +11927,12 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { "errno": "^0.1.3", @@ -11968,7 +11968,7 @@ "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==" + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" }, "meow": { "version": "6.1.1", @@ -12003,7 +12003,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -12014,7 +12014,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "merge-stream": { "version": "2.0.0", @@ -12031,7 +12031,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "microevent.ts": { "version": "0.1.1", @@ -12101,7 +12101,7 @@ "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", "requires": { "dom-walk": "^0.1.0" } @@ -12127,7 +12127,7 @@ "normalize-url": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", "dev": true, "requires": { "object-assign": "^4.0.1", @@ -12139,7 +12139,7 @@ "query-string": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", "dev": true, "requires": { "object-assign": "^4.1.0", @@ -12204,7 +12204,7 @@ "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", @@ -12233,7 +12233,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true } } @@ -12375,7 +12375,7 @@ "mixin-object": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", "dev": true, "requires": { "for-in": "^0.1.3", @@ -12385,7 +12385,7 @@ "for-in": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", "dev": true } } @@ -12398,7 +12398,7 @@ "mkdirp-promise": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", + "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", "requires": { "mkdirp": "*" } @@ -12406,7 +12406,7 @@ "mobile-detect": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.2.tgz", - "integrity": "sha512-LtqFVpey4qbL7DizjZ2osgpUJhJuBYdqWnnerCPIamKyUm6H3dyo1zoNjPSvHPcuQyOkBEqvpp0sf0KZp9ankw==" + "integrity": "sha1-1F//+NCmQa7svDWhXYgUmjShg1A=" }, "mock-fs": { "version": "4.14.0", @@ -12455,7 +12455,7 @@ "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", "dev": true, "requires": { "aproba": "^1.1.1", @@ -12513,7 +12513,7 @@ "multicast-dns-service-types": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, "multicodec": { @@ -12576,7 +12576,7 @@ "nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==" + "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" }, "nanomatch": { "version": "1.2.13", @@ -12605,7 +12605,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "ncp": { @@ -12717,7 +12717,7 @@ "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, "tar": { @@ -12741,7 +12741,7 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, "node-libs-browser": { @@ -12789,7 +12789,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, "readable-stream": { @@ -12830,7 +12830,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true } } @@ -12890,25 +12890,25 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", @@ -12918,7 +12918,7 @@ "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -12931,7 +12931,7 @@ "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ==", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -12941,7 +12941,7 @@ "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -12951,7 +12951,7 @@ "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" @@ -12960,7 +12960,7 @@ "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -12973,13 +12973,13 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", @@ -13006,7 +13006,7 @@ "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -13015,7 +13015,7 @@ "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -13024,7 +13024,7 @@ "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -13035,13 +13035,13 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -13052,7 +13052,7 @@ "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -13062,7 +13062,7 @@ "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", @@ -13084,7 +13084,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -13093,7 +13093,7 @@ "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -13102,7 +13102,7 @@ "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" @@ -13111,13 +13111,13 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true } } @@ -13141,13 +13141,13 @@ "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", @@ -13157,7 +13157,7 @@ "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -13167,7 +13167,7 @@ "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" @@ -13176,7 +13176,7 @@ "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -13189,13 +13189,13 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", @@ -13213,7 +13213,7 @@ "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -13222,7 +13222,7 @@ "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -13231,7 +13231,7 @@ "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -13242,13 +13242,13 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -13259,7 +13259,7 @@ "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -13269,7 +13269,7 @@ "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", @@ -13279,7 +13279,7 @@ "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -13288,7 +13288,7 @@ "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" @@ -13297,7 +13297,7 @@ "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true } } @@ -13305,7 +13305,7 @@ "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { "abbrev": "1" @@ -13331,7 +13331,7 @@ "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, "normalize-url": { @@ -13401,19 +13401,19 @@ "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", "dev": true }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", "requires": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" @@ -13422,7 +13422,7 @@ "bn.js": { "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" } } }, @@ -13445,12 +13445,12 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { "copy-descriptor": "^0.1.0", @@ -13461,7 +13461,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -13470,7 +13470,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -13506,13 +13506,13 @@ "object-path": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha512-ICbQN+aw/eAASDtaC7+SJXSAruz7fvvNjxMFfS3mTdvZaaiuuw81XXYu+9CSJeUVrS3YpRhTr862YGywMQUOWg==", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=", "dev": true }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { "isobject": "^3.0.0" @@ -13565,7 +13565,7 @@ "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -13612,7 +13612,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } @@ -13698,19 +13698,19 @@ "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { "lcid": "^1.0.0" @@ -13719,7 +13719,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "osenv": { @@ -13757,7 +13757,7 @@ "p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha512-J/e9xiZZQNrt+958FFzJ+auItsBGq+UrQ7nE89AUP7UOTtjHnkISANXLdayhVzh538UnLMCSlf13lFfRIAKQOA==", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", "dev": true, "requires": { "p-reduce": "^1.0.0" @@ -13803,7 +13803,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { "version": "2.3.0", @@ -13835,7 +13835,7 @@ "p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", "dev": true }, "p-retry": { @@ -13942,7 +13942,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -13971,7 +13971,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-browserify": { @@ -13983,7 +13983,7 @@ "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "path-exists": { @@ -13995,18 +13995,18 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.7", @@ -14016,7 +14016,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { "version": "3.0.0", @@ -14041,7 +14041,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { "version": "2.3.0", @@ -14057,18 +14057,18 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -14132,7 +14132,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } @@ -14207,7 +14207,7 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "postcss": { @@ -14578,7 +14578,7 @@ "import-fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { "caller-path": "^2.0.0", @@ -14588,7 +14588,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -15140,12 +15140,12 @@ "prefix-style": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/prefix-style/-/prefix-style-2.0.1.tgz", - "integrity": "sha512-gdr1MBNVT0drzTq95CbSNdsrBDoHGlb2aDJP/FoY+1e+jSDPOb1Cv554gH2MGiSr2WTcXi/zu+NaFzfcHQkfBQ==" + "integrity": "sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY=" }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "prepend-http": { @@ -15203,7 +15203,7 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { "version": "2.0.1", @@ -15228,7 +15228,7 @@ "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, "prompt": { @@ -15286,13 +15286,13 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { @@ -15353,13 +15353,13 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "qr.js": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", - "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==" + "integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=" }, "qrcode.react": { "version": "0.9.3", @@ -15388,13 +15388,13 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, "querystringify": { @@ -16557,7 +16557,7 @@ "react-custom-scrollbars": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/react-custom-scrollbars/-/react-custom-scrollbars-4.2.1.tgz", - "integrity": "sha512-VtJTUvZ7kPh/auZWIbBRceGPkE30XBYe+HktFxuMWBR2eVQQ+Ur6yFJMoaYcNpyGq22uYJ9Wx4UAEcC0K+LNPQ==", + "integrity": "sha1-gw/ZUCkn6X6KeMIIaBOJmyqLZts=", "requires": { "dom-css": "^2.0.0", "prop-types": "^15.5.10", @@ -16635,7 +16635,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "browserslist": { @@ -16680,7 +16680,7 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, "escape-string-regexp": { @@ -16786,7 +16786,7 @@ "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, "which": { @@ -16972,7 +16972,7 @@ "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", "requires": { "loose-envify": "^1.0.0" } @@ -17081,7 +17081,7 @@ "warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", "requires": { "loose-envify": "^1.0.0" } @@ -17305,7 +17305,7 @@ "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -17439,7 +17439,7 @@ "redux-logger": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", - "integrity": "sha512-JoCIok7bg/XpqA1JqCqXFypuqBbQzGQySrhFzewB7ThcnysTO30l4VCst86AuB9T9tuT03MAA56Jw2PNhRSNCg==", + "integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=", "requires": { "deep-diff": "^0.3.5" } @@ -17467,7 +17467,7 @@ "reflect.ownkeys": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", - "integrity": "sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==" + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" }, "regenerate": { "version": "1.4.2", @@ -17570,12 +17570,12 @@ "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, "renderkid": { @@ -17594,7 +17594,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "css-select": { @@ -17656,7 +17656,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -17673,13 +17673,13 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" @@ -17742,7 +17742,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { @@ -17754,7 +17754,7 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, "reselect": { @@ -17779,7 +17779,7 @@ "resolve-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { "resolve-from": "^3.0.0" @@ -17788,7 +17788,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true } } @@ -17802,7 +17802,7 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, "resolve-url-loader": { @@ -17835,7 +17835,7 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, "json5": { @@ -17883,7 +17883,7 @@ "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "requires": { "lowercase-keys": "^1.0.0" } @@ -17907,7 +17907,7 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, "revalidator": { @@ -17919,7 +17919,7 @@ "rework": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", + "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", "dev": true, "requires": { "convert-source-map": "^0.3.3", @@ -17929,7 +17929,7 @@ "convert-source-map": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", "dev": true } } @@ -17937,19 +17937,19 @@ "rework-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==", + "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", "dev": true }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", "dev": true }, "rgba-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "dev": true }, "rimraf": { @@ -18171,7 +18171,7 @@ "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", "dev": true, "requires": { "aproba": "^1.1.1" @@ -18202,7 +18202,7 @@ "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" @@ -18267,7 +18267,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -18276,7 +18276,7 @@ "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" @@ -18305,19 +18305,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { "string-width": "^1.0.1", @@ -18328,7 +18328,7 @@ "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", @@ -18344,7 +18344,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" @@ -18353,7 +18353,7 @@ "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -18366,7 +18366,7 @@ "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -18375,7 +18375,7 @@ "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" @@ -18384,7 +18384,7 @@ "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -18395,13 +18395,13 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", @@ -18412,7 +18412,7 @@ "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", @@ -18422,13 +18422,13 @@ "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", @@ -18439,7 +18439,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -18448,7 +18448,7 @@ "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" @@ -18457,13 +18457,13 @@ "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", @@ -18596,7 +18596,7 @@ "scss-tokenizer": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha512-dYE8LhncfBUar6POCxMTm0Ln+erjeczqEvCJib5/7XNkdw1FkUGgwMPY360FY0FgPWQxHWCx29Jl3oejyGLM9Q==", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "dev": true, "requires": { "js-base64": "^2.1.8", @@ -18606,7 +18606,7 @@ "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { "amdefine": ">=0.0.4" @@ -18627,12 +18627,12 @@ "seed-random": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", - "integrity": "sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==" + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=" }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, "selfsigned": { @@ -18652,7 +18652,7 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, "semver-regex": { @@ -18700,7 +18700,7 @@ "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { "accepts": "~1.3.4", @@ -18715,7 +18715,7 @@ "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { "depd": "~1.1.2", @@ -18727,7 +18727,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "setprototypeof": { @@ -18764,7 +18764,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-value": { @@ -18782,7 +18782,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -18793,7 +18793,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.1", @@ -18812,7 +18812,7 @@ "shallow-clone": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==", + "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", "dev": true, "requires": { "is-extendable": "^0.1.1", @@ -18824,7 +18824,7 @@ "kind-of": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg==", + "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", "dev": true, "requires": { "is-buffer": "^1.0.2" @@ -18833,7 +18833,7 @@ "lazy-cache": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==", + "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", "dev": true } } @@ -18846,7 +18846,7 @@ "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { "shebang-regex": "^1.0.0" } @@ -18854,7 +18854,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shell-quote": { "version": "1.7.2", @@ -18901,7 +18901,7 @@ "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", "requires": { "is-arrayish": "^0.3.1" } @@ -18974,7 +18974,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -18983,7 +18983,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" @@ -18992,7 +18992,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -19011,7 +19011,7 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" @@ -19060,7 +19060,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -19122,7 +19122,7 @@ "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", "dev": true, "requires": { "is-plain-obj": "^1.0.0" @@ -19277,7 +19277,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { @@ -19355,7 +19355,7 @@ "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { "define-property": "^0.2.5", @@ -19365,7 +19365,7 @@ "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" @@ -19416,7 +19416,7 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, "stream-browserify": { @@ -19513,7 +19513,7 @@ "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==" + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, "string-argv": { "version": "0.3.1", @@ -19524,12 +19524,12 @@ "string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", - "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha512-Qka42GGrS8Mm3SZ+7cH8UXiIWI867/b/Z/feQSpQx/rbfB8UGknGEZVaUQMOUVj+soY6NpWAxily63HI1OckVQ==", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", "dev": true, "requires": { "astral-regex": "^1.0.0", @@ -19551,7 +19551,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -19652,7 +19652,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "strip-comments": { "version": "1.0.2", @@ -19667,7 +19667,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "strip-final-newline": { @@ -19679,7 +19679,7 @@ "strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", "requires": { "is-hex-prefixed": "1.0.0" } @@ -20088,7 +20088,7 @@ "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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "slice-ansi": { @@ -20307,7 +20307,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "read-pkg-up": { @@ -20325,19 +20325,19 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { @@ -20385,7 +20385,7 @@ "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==" + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "timers-browserify": { "version": "2.0.12", @@ -20399,7 +20399,7 @@ "timsort": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, "tiny-emitter": { @@ -20430,13 +20430,13 @@ "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, "to-camel-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-camel-case/-/to-camel-case-1.0.0.tgz", - "integrity": "sha512-nD8pQi5H34kyu1QDMFjzEIYqk0xa9Alt6ZfrdEMuHCFOfTLhDG5pgTu/aAM9Wt9lXILwlXmWP43b8sav0GNE8Q==", + "integrity": "sha1-GlYFSy+daWKYzmamCJcyK29CPkY=", "requires": { "to-space-case": "^1.0.0" } @@ -20444,18 +20444,18 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { "kind-of": "^3.0.2" @@ -20464,7 +20464,7 @@ "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -20492,7 +20492,7 @@ "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { "is-number": "^3.0.0", @@ -20502,7 +20502,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", "requires": { "to-no-case": "^1.0.0" } @@ -20510,7 +20510,7 @@ "toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, "toidentifier": { "version": "1.0.0", @@ -20529,7 +20529,7 @@ "tr46": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "requires": { "punycode": "^2.1.0" @@ -20591,13 +20591,13 @@ "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { "safe-buffer": "^5.0.1" } @@ -20610,7 +20610,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type": { "version": "1.2.0", @@ -20620,7 +20620,7 @@ "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -20649,7 +20649,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typedarray-to-buffer": { @@ -20734,13 +20734,13 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", "dev": true }, "unique-filename": { @@ -20780,18 +20780,18 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", "dev": true }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { "has-value": "^0.3.1", @@ -20801,7 +20801,7 @@ "has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { "get-value": "^2.0.3", @@ -20812,7 +20812,7 @@ "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" @@ -20823,7 +20823,7 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } } @@ -20845,13 +20845,13 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, "requires": { "punycode": "1.3.2", @@ -20861,7 +20861,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", "dev": true } } @@ -20912,7 +20912,7 @@ "url-set-query": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==" + "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" }, "url-to-options": { "version": "1.0.1", @@ -20949,7 +20949,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { "version": "1.0.1", @@ -20966,7 +20966,7 @@ "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", "dev": true }, "utile": { @@ -21012,7 +21012,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "3.4.0", @@ -21057,7 +21057,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vendors": { "version": "1.0.4", @@ -21068,7 +21068,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -21154,7 +21154,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "optional": true, "requires": { @@ -21205,7 +21205,7 @@ "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "optional": true, "requires": { @@ -22500,7 +22500,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "anymatch": { @@ -22516,7 +22516,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -22579,7 +22579,7 @@ "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { "binary-extensions": "^1.0.0" @@ -22646,7 +22646,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -22728,7 +22728,7 @@ "websocket-driver": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha512-oBx6ZM1Gs5q2jwZuSN/Qxyy/fbgomV8+vqsmipaPKB/74hjHlKuM07jNmRhn4qa2AdUwsgxrltq+gaPsHgcl0Q==", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { "websocket-extensions": ">=0.1.1" @@ -22794,7 +22794,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "which-pm-runs": { @@ -23122,7 +23122,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", @@ -23228,7 +23228,7 @@ "xhr2-cookies": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", "requires": { "cookiejar": "^2.1.1" } @@ -23268,7 +23268,7 @@ "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==" + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" }, "yallist": { "version": "3.1.1", @@ -23323,7 +23323,7 @@ "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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "locate-path": { @@ -23348,7 +23348,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "string-width": { diff --git a/web/package.json b/web/package.json index b24ff22796..f3e841941f 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "hollaex-kit", - "version": "2.6.6", + "version": "2.7.0", "private": true, "dependencies": { "@ant-design/compatible": "1.0.5", @@ -109,10 +109,10 @@ "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive", "copy-cname": "cpy CNAME build/", "remove-build": "rimraf ./build", - "start-js": "react-scripts --max_old_space_size=3072 start", + "start-js": "react-scripts --max_old_space_size=4096 start", "start": "npm install && npm-run-all -p watch-css start-js", "dev:plugin": "REACT_APP_PLUGIN_DEV_MODE=true REACT_APP_PLUGIN=$npm_config_plugin npm run start", - "build": "react-scripts --max_old_space_size=3072 build", + "build": "react-scripts --max_old_space_size=4096 build", "pre-build": "npm run remove-build && npm install", "build:demo": "REACT_APP_SERVER_ENDPOINT=https://api.sandbox.hollaex.com npm run build", "publish:demo": "surge build", diff --git a/web/public/assets/images/stacked-pro-on-fiat.svg b/web/public/assets/images/stacked-pro-on-fiat.svg new file mode 100644 index 0000000000..e5604f7402 --- /dev/null +++ b/web/public/assets/images/stacked-pro-on-fiat.svg @@ -0,0 +1,17 @@ + + + diff --git a/web/src/_variables.scss b/web/src/_variables.scss index d2db80edb2..9b84cb363d 100644 --- a/web/src/_variables.scss +++ b/web/src/_variables.scss @@ -157,6 +157,12 @@ $chat-message-background-odd: var(--base_secondary-navigation-bar); $chat-message-color: var(--specials_chat-messages); $chat-box-border: $colors-main-border; +// intensity color +$low-intensity: var(--specials_chat-messages); +$medium-intensity: var(--specials_my-username-in-chat); +$high-intensity: var(--specials_pending-waiting-caution); +$extreme-intensity: var(--specials_notifications-alerts-warnings); + // this is for transaction history- ToDo: need to customize for common theme $history-color-buy: var(--trading_buying-related-elements); $history-color-sell: var(--trading_selling-related-elements); diff --git a/web/src/actions/appActions.js b/web/src/actions/appActions.js index 2a2b5495a9..17afc0ed02 100644 --- a/web/src/actions/appActions.js +++ b/web/src/actions/appActions.js @@ -65,6 +65,7 @@ export const SET_USER_PAYMENTS = 'SET_USER_PAYMENTS'; export const SET_ONRAMP = 'SET_ONRAMP'; export const SET_OFFRAMP = 'SET_OFFRAMP'; export const SET_BROKER = 'SET_BROKER'; +export const SET_QUICKTRADE = 'SET_QUICKTRADE'; export const SET_CONFIG = 'SET_CONFIG'; export const SET_PLUGINS = 'SET_PLUGINS'; export const SET_EXPLORE_PLUGINS = 'SET_EXPLORE_PLUGINS'; @@ -415,6 +416,13 @@ export const setBroker = (broker) => ({ }, }); +export const setQuickTrade = (quicktrade) => ({ + type: SET_QUICKTRADE, + payload: { + quicktrade, + }, +}); + export const setConfig = (constants = {}) => { let features = {}; if (constants) { diff --git a/web/src/actions/authAction.js b/web/src/actions/authAction.js index c1f8010857..ef35d451e8 100644 --- a/web/src/actions/authAction.js +++ b/web/src/actions/authAction.js @@ -76,7 +76,7 @@ const setTokenInApp = (token, setInStore = false) => { } }; -const cleatTokenInApp = (router, path = '/') => { +const clearTokenInApp = (router, path = '/') => { axios.defaults.headers.common['Authorization'] = {}; removeToken(); localStorage.removeItem('deposit_initial_display'); @@ -108,7 +108,7 @@ export function verifyToken(token) { dispatch({ type: 'VERIFY_TOKEN_REJECTED', }); - cleatTokenInApp(browserHistory, '/login'); + clearTokenInApp(browserHistory, '/login'); }); }; } @@ -120,9 +120,12 @@ export const logout = (message = '') => (dispatch) => { message, }, }); - cleatTokenInApp(browserHistory, '/login'); + requestLogout(); + clearTokenInApp(browserHistory, '/login'); }; +export const requestLogout = () => axios.get('/logout'); + export const setLogoutMessage = (message = '') => ({ type: 'SET_LOGOUT_MESSAGE', payload: { diff --git a/web/src/actions/userAction.js b/web/src/actions/userAction.js index 6e3fb22eaa..7b6da279d9 100644 --- a/web/src/actions/userAction.js +++ b/web/src/actions/userAction.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import moment from 'moment'; import { PLUGIN_URL } from 'config/constants'; import querystring from 'query-string'; @@ -339,3 +340,100 @@ export const getUserLogins = ({ limit = 50, page = 1, ...rest }) => { }); }; }; + +export const getSessions = ({ page = 1, limit = 20, ...rest }) => { + const params = { page, limit, status: true }; + const query = querystring.stringify(params); + + return axios.get(`/user/sessions?${query}`); +}; + +export const downloadSessions = () => { + const queryData = { + format: 'csv', + status: true, + }; + + const query = querystring.stringify(queryData); + return axios + .get(`/user/sessions?${query}`) + .then(({ data }) => { + const url = window.URL.createObjectURL(new Blob([data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute( + 'download', + `sessions_${moment().format('YYYY-MM-DD')}.csv` + ); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }) + .catch((err) => {}); +}; + +export const revokeSession = (session_id) => + axios.post('/user/revoke-session', { session_id }); + +export const downloadLogins = (params = {}) => { + const queryData = { + format: 'csv', + }; + + if (params && params.start_date) { + queryData.start_date = params.start_date; + } + + if (params && params.end_date) { + queryData.end_date = params.end_date; + } + + if (params && params.status) { + if (params.status === 'failed') { + queryData.status = false; + } else if (params.status === 'success') { + queryData.status = true; + } + } + + const query = querystring.stringify(queryData); + return axios + .get(`/user/logins?${query}`) + .then(({ data }) => { + const url = window.URL.createObjectURL(new Blob([data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute( + 'download', + `logins_${moment().format('YYYY-MM-DD')}.csv` + ); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }) + .catch((err) => {}); +}; + +export const getLogins = ({ page = 1, limit = 20, ...params }) => { + const queryData = { page, limit }; + + if (params && params.start_date) { + queryData.start_date = params.start_date; + } + + if (params && params.end_date) { + queryData.end_date = params.end_date; + } + + if (params && params.status) { + if (params.status === 'failed') { + queryData.status = false; + } else if (params.status === 'success') { + queryData.status = true; + } + } + + const query = querystring.stringify(queryData); + + return axios.get(`/user/logins?${query}`); +}; diff --git a/web/src/components/CheckTitle/HeaderSection.js b/web/src/components/CheckTitle/HeaderSection.js index 26b847f206..a9d44a784f 100644 --- a/web/src/components/CheckTitle/HeaderSection.js +++ b/web/src/components/CheckTitle/HeaderSection.js @@ -13,6 +13,7 @@ const HeaderSection = ({ iconId, stringId, icons: ICONS, + notification, }) => { return (
-{error}-
} +-{error}-
} -