PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit
Просмотр файла: accountConsolidations.js
"use strict";
//
// Account consolidation tests
//
Object.defineProperty(exports, "__esModule", { value: true });
const sinon = require("sinon");
require('should-sinon');
require("../lib/asserts");
const nock = require("nock");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("../../../src/bitgo");
const algoFixtures = require('../../../../sdk-coin-algo/test/fixtures/algo');
nock.disableNetConnect();
describe('Account Consolidations:', function () {
let bitgo;
let wallet;
let basecoin;
let bgUrl;
let fixtures;
for (const coinName of ['talgo', 'txtz']) {
describe(coinName + ' Account Consolidations: ', function () {
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'test' });
bitgo.initializeTestVars();
basecoin = bitgo.coin(coinName);
const walletData = {
id: '5e4168f4403d0c5c1c3bdd15486e757f',
coin: coinName,
};
wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
if (coinName === 'talgo') {
fixtures = algoFixtures.prebuild();
}
});
describe('Building', function () {
it('should not allow a non-account consolidation coin build', async function () {
const unsupportedCoin = bitgo.coin('tbtc');
const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {});
await invalidWallet.buildAccountConsolidations().should.be.rejectedWith({
message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`,
});
});
it('should build with no params', async function () {
const scope = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`)
.query({})
.reply(200, fixtures.buildAccountConsolidation);
const accountConsolidationBuild = await wallet.buildAccountConsolidations();
accountConsolidationBuild.length.should.equal(2);
scope.isDone().should.be.True();
});
it('should throw if the result is an empty array', async function () {
const scope = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`)
.query({})
.reply(200, []);
await wallet
.buildAccountConsolidations()
.should.be.rejectedWith('No receive addresses with balance found to consolidate.');
scope.isDone().should.be.True();
});
});
describe('Sending', function () {
afterEach(function () {
sinon.restore();
});
it('should use params.apiVersion if specified', async function () {
const scope = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`, { apiVersion: 'lite' })
.reply(200, fixtures.buildAccountConsolidation);
const sendAccountConsolidationStub = sinon
.stub(wallet, 'sendAccountConsolidation')
.resolves(fixtures.signedAccountConsolidationBuilds);
sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
wallet.tssUtils = {
supportedTxRequestVersions: () => ['lite', 'full'],
};
const params = { apiVersion: 'lite' };
await wallet.sendAccountConsolidations(params);
sinon.assert.calledWith(sendAccountConsolidationStub, sinon.match({ apiVersion: 'lite' }));
scope.isDone().should.be.True();
});
it('should use apiVersion full for the transaction if it is supported and no apiVersion is passed', async function () {
const scope = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`, { apiVersion: 'full' })
.reply(200, fixtures.buildAccountConsolidation);
const sendAccountConsolidationStub = sinon
.stub(wallet, 'sendAccountConsolidation')
.resolves(fixtures.signedAccountConsolidationBuilds);
sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
wallet.tssUtils = {
supportedTxRequestVersions: () => ['lite', 'full'],
};
const params = {};
await wallet.sendAccountConsolidations(params);
sinon.assert.calledWith(sendAccountConsolidationStub, sinon.match({ apiVersion: 'full' }));
scope.isDone().should.be.True();
});
it('should utilize codec for custodial consolidation', async function () {
const custodialWallet = new sdk_core_1.Wallet(bitgo, basecoin, {
id: '5f4168f4403d0c5c1c3bdd15486e757f',
coin: coinName,
type: 'custodial',
});
const initiateTxPath = `/api/v2/${custodialWallet.coin()}/wallet/${custodialWallet.id()}/tx/initiate`;
let req;
nock(bgUrl)
.post(initiateTxPath, (body) => {
req = body;
return true;
})
.reply(200);
const params = { prebuildTx: fixtures.buildAccountConsolidation[0] };
const paramsWithJunk = { ...params, junk: 'junk', otp: '000000' };
const paramsAfterCodec = { type: 'consolidate', otp: '000000' };
sinon.stub(wallet, 'prebuildAndSignTransaction').resolves(fixtures.signedAccountConsolidationBuilds[0]);
await custodialWallet.sendAccountConsolidation(paramsWithJunk);
req.should.deepEqual(paramsAfterCodec);
});
it('should not allow a non-account consolidation coin send', async function () {
const unsupportedCoin = bitgo.coin('tbtc');
const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {});
await invalidWallet.sendAccountConsolidation({}).should.be.rejectedWith({
message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`,
});
});
it('should not allow a non-account consolidation coin send multiples', async function () {
const unsupportedCoin = bitgo.coin('tbtc');
const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {});
await invalidWallet.sendAccountConsolidations({}).should.be.rejectedWith({
message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`,
});
});
it('should not allow a bad pre-build to be passed', async function () {
await wallet
.sendAccountConsolidation({ prebuildTx: 'some string' })
.should.be.rejectedWith({ message: 'Invalid build of account consolidation.' });
await wallet
.sendAccountConsolidation({ prebuildTx: undefined })
.should.be.rejectedWith({ message: 'Invalid build of account consolidation.' });
});
it('should require a consolidation id to be passed', async function () {
await wallet
.sendAccountConsolidation({ prebuildTx: {} })
.should.be.rejectedWith({ message: 'Failed to find consolidation id on consolidation transaction.' });
});
it('should submit a consolidation transaction', async function () {
const params = { prebuildTx: fixtures.buildAccountConsolidation[0] };
sinon.stub(wallet, 'prebuildAndSignTransaction').resolves(fixtures.signedAccountConsolidationBuilds[0]);
const scope = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuild)
.reply(200);
await wallet.sendAccountConsolidation(params);
scope.isDone().should.be.True();
});
it('should submit a consolidation account send (build + send) with two successes', async function () {
const scopeBuild = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`)
.query({})
.reply(200, fixtures.buildAccountConsolidation);
sinon
.stub(wallet, 'prebuildAndSignTransaction')
.onCall(0)
.resolves(fixtures.signedAccountConsolidationBuilds[0])
.onCall(1)
.resolves(fixtures.signedAccountConsolidationBuilds[1]);
sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
const scopeFirstSigned = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[0])
.reply(200);
const scopeTwoSigned = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[1])
.reply(200);
const consolidations = await wallet.sendAccountConsolidations();
consolidations.success.length.should.equal(2);
consolidations.failure.length.should.equal(0);
scopeFirstSigned.isDone().should.be.True();
scopeTwoSigned.isDone().should.be.True();
scopeBuild.isDone().should.be.True();
});
it('should submit a consolidation account send (build + send) with one success, one failure', async function () {
const scopeBuild = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`)
.query({})
.reply(200, fixtures.buildAccountConsolidation);
sinon
.stub(wallet, 'prebuildAndSignTransaction')
.onCall(0)
.resolves(fixtures.signedAccountConsolidationBuilds[0])
.onCall(1)
.resolves(fixtures.signedAccountConsolidationBuilds[1]);
sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
const scopeWithSuccess = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[0])
.reply(200);
const scopeWithError = nock(bgUrl)
.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[1])
.reply(500);
const consolidations = await wallet.sendAccountConsolidations();
consolidations.success.length.should.equal(1);
consolidations.failure.length.should.equal(1);
scopeWithSuccess.isDone().should.be.True();
scopeWithError.isDone().should.be.True();
scopeBuild.isDone().should.be.True();
});
});
});
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudENvbnNvbGlkYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2FjY291bnRDb25zb2xpZGF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLDhCQUE4QjtBQUM5QixFQUFFOztBQUVGLCtCQUErQjtBQUMvQixPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFeEIsMEJBQXdCO0FBQ3hCLDZCQUE2QjtBQUU3Qiw4Q0FBaUQ7QUFFakQsOENBQTRDO0FBQzVDLDhDQUEyQztBQUMzQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsOENBQThDLENBQUMsQ0FBQztBQUU3RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztBQUV6QixRQUFRLENBQUMseUJBQXlCLEVBQUU7SUFDbEMsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLE1BQU0sQ0FBQztJQUNYLElBQUksUUFBUSxDQUFDO0lBQ2IsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUViLEtBQUssTUFBTSxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUN6QyxRQUFRLENBQUMsUUFBUSxHQUFHLDJCQUEyQixFQUFFO1lBQy9DLE1BQU0sQ0FBQztnQkFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQ25ELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFaEMsTUFBTSxVQUFVLEdBQUc7b0JBQ2pCLEVBQUUsRUFBRSxrQ0FBa0M7b0JBQ3RDLElBQUksRUFBRSxRQUFRO2lCQUNmLENBQUM7Z0JBRUYsTUFBTSxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFL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TSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzlDLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBRTlDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQzNDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUN6QyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkMsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIEFjY291bnQgY29uc29saWRhdGlvbiB0ZXN0c1xuLy9cblxuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xucmVxdWlyZSgnc2hvdWxkLXNpbm9uJyk7XG5cbmltcG9ydCAnLi4vbGliL2Fzc2VydHMnO1xuaW1wb3J0ICogYXMgbm9jayBmcm9tICdub2NrJztcblxuaW1wb3J0IHsgY29tbW9uLCBXYWxsZXQgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuXG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28nO1xuY29uc3QgYWxnb0ZpeHR1cmVzID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vc2RrLWNvaW4tYWxnby90ZXN0L2ZpeHR1cmVzL2FsZ28nKTtcblxubm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuXG5kZXNjcmliZSgnQWNjb3VudCBDb25zb2xpZGF0aW9uczonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbztcbiAgbGV0IHdhbGxldDtcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQgYmdVcmw7XG4gIGxldCBmaXh0dXJlcztcblxuICBmb3IgKGNvbnN0IGNvaW5OYW1lIG9mIFsndGFsZ28nLCAndHh0eiddKSB7XG4gICAgZGVzY3JpYmUoY29pbk5hbWUgKyAnIEFjY291bnQgQ29uc29saWRhdGlvbnM6ICcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKGNvaW5OYW1lKTtcblxuICAgICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICAgIGlkOiAnNWU0MTY4ZjQ0MDNkMGM1YzFjM2JkZDE1NDg2ZTc1N2YnLFxuICAgICAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgICB9O1xuXG4gICAgICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICAgICAgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICAgIGlmIChjb2luTmFtZSA9PT0gJ3RhbGdvJykge1xuICAgICAgICAgIGZpeHR1cmVzID0gYWxnb0ZpeHR1cmVzLnByZWJ1aWxkKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnQnVpbGRpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGEgbm9uLWFjY291bnQgY29uc29saWRhdGlvbiBjb2luIGJ1aWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHVuc3VwcG9ydGVkQ29pbiA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgICAgICBjb25zdCBpbnZhbGlkV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdW5zdXBwb3J0ZWRDb2luLCB7fSk7XG4gICAgICAgICAgYXdhaXQgaW52YWxpZFdhbGxldC5idWlsZEFjY291bnRDb25zb2xpZGF0aW9ucygpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoe1xuICAgICAgICAgICAgbWVzc2FnZTogYCR7dW5zdXBwb3J0ZWRDb2luLmdldEZ1bGxOYW1lKCl9IGRvZXMgbm90IGFsbG93IGFjY291bnQgY29uc29saWRhdGlvbnMuYCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBidWlsZCB3aXRoIG5vIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZUFjY291bnQvYnVpbGRgKVxuICAgICAgICAgICAgLnF1ZXJ5KHt9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbik7XG5cbiAgICAgICAgICBjb25zdCBhY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkID0gYXdhaXQgd2FsbGV0LmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb25zKCk7XG5cbiAgICAgICAgICBhY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG5cbiAgICAgICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSByZXN1bHQgaXMgYW4gZW1wdHkgYXJyYXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vY29uc29saWRhdGVBY2NvdW50L2J1aWxkYClcbiAgICAgICAgICAgIC5xdWVyeSh7fSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIFtdKTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgICAgLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb25zKClcbiAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdObyByZWNlaXZlIGFkZHJlc3NlcyB3aXRoIGJhbGFuY2UgZm91bmQgdG8gY29uc29saWRhdGUuJyk7XG5cbiAgICAgICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnU2VuZGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdXNlIHBhcmFtcy5hcGlWZXJzaW9uIGlmIHNwZWNpZmllZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZUFjY291bnQvYnVpbGRgLCB7IGFwaVZlcnNpb246ICdsaXRlJyB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbik7XG4gICAgICAgICAgY29uc3Qgc2VuZEFjY291bnRDb25zb2xpZGF0aW9uU3R1YiA9IHNpbm9uXG4gICAgICAgICAgICAuc3R1Yih3YWxsZXQsICdzZW5kQWNjb3VudENvbnNvbGlkYXRpb24nKVxuICAgICAgICAgICAgLnJlc29sdmVzKGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzKTtcbiAgICAgICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZScpLnJlc29sdmVzKFtdKTtcblxuICAgICAgICAgIHdhbGxldC50c3NVdGlscyA9IHtcbiAgICAgICAgICAgIHN1cHBvcnRlZFR4UmVxdWVzdFZlcnNpb25zOiAoKSA9PiBbJ2xpdGUnLCAnZnVsbCddLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7IGFwaVZlcnNpb246ICdsaXRlJyB9O1xuICAgICAgICAgIGF3YWl0IHdhbGxldC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKHBhcmFtcyk7XG4gICAgICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgoc2VuZEFjY291bnRDb25zb2xpZGF0aW9uU3R1Yiwgc2lub24ubWF0Y2goeyBhcGlWZXJzaW9uOiAnbGl0ZScgfSkpO1xuXG4gICAgICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB1c2UgYXBpVmVyc2lvbiBmdWxsIGZvciB0aGUgdHJhbnNhY3Rpb24gaWYgaXQgaXMgc3VwcG9ydGVkIGFuZCBubyBhcGlWZXJzaW9uIGlzIHBhc3NlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZUFjY291bnQvYnVpbGRgLCB7IGFwaVZlcnNpb246ICdmdWxsJyB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbik7XG4gICAgICAgICAgY29uc3Qgc2VuZEFjY291bnRDb25zb2xpZGF0aW9uU3R1YiA9IHNpbm9uXG4gICAgICAgICAgICAuc3R1Yih3YWxsZXQsICdzZW5kQWNjb3VudENvbnNvbGlkYXRpb24nKVxuICAgICAgICAgICAgLnJlc29sdmVzKGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzKTtcbiAgICAgICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZScpLnJlc29sdmVzKFtdKTtcblxuICAgICAgICAgIHdhbGxldC50c3NVdGlscyA9IHtcbiAgICAgICAgICAgIHN1cHBvcnRlZFR4UmVxdWVzdFZlcnNpb25zOiAoKSA9PiBbJ2xpdGUnLCAnZnVsbCddLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcbiAgICAgICAgICBhd2FpdCB3YWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9ucyhwYXJhbXMpO1xuICAgICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHNlbmRBY2NvdW50Q29uc29saWRhdGlvblN0dWIsIHNpbm9uLm1hdGNoKHsgYXBpVmVyc2lvbjogJ2Z1bGwnIH0pKTtcblxuICAgICAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdXRpbGl6ZSBjb2RlYyBmb3IgY3VzdG9kaWFsIGNvbnNvbGlkYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9kaWFsV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHtcbiAgICAgICAgICAgIGlkOiAnNWY0MTY4ZjQ0MDNkMGM1YzFjM2JkZDE1NDg2ZTc1N2YnLFxuICAgICAgICAgICAgY29pbjogY29pbk5hbWUsXG4gICAgICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGluaXRpYXRlVHhQYXRoID0gYC9hcGkvdjIvJHtjdXN0b2RpYWxXYWxsZXQuY29pbigpfS93YWxsZXQvJHtjdXN0b2RpYWxXYWxsZXQuaWQoKX0vdHgvaW5pdGlhdGVgO1xuICAgICAgICAgIGxldCByZXE7XG4gICAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KGluaXRpYXRlVHhQYXRoLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICByZXEgPSBib2R5O1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHsgcHJlYnVpbGRUeDogZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvblswXSB9O1xuICAgICAgICAgIGNvbnN0IHBhcmFtc1dpdGhKdW5rID0geyAuLi5wYXJhbXMsIGp1bms6ICdqdW5rJywgb3RwOiAnMDAwMDAwJyB9O1xuICAgICAgICAgIGNvbnN0IHBhcmFtc0FmdGVyQ29kZWMgPSB7IHR5cGU6ICdjb25zb2xpZGF0ZScsIG90cDogJzAwMDAwMCcgfTtcblxuICAgICAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAncHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1swXSk7XG4gICAgICAgICAgYXdhaXQgY3VzdG9kaWFsV2FsbGV0LnNlbmRBY2NvdW50Q29uc29saWRhdGlvbihwYXJhbXNXaXRoSnVuayk7XG5cbiAgICAgICAgICByZXEuc2hvdWxkLmRlZXBFcXVhbChwYXJhbXNBZnRlckNvZGVjKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBub3QgYWxsb3cgYSBub24tYWNjb3VudCBjb25zb2xpZGF0aW9uIGNvaW4gc2VuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB1bnN1cHBvcnRlZENvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICAgICAgY29uc3QgaW52YWxpZFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHVuc3VwcG9ydGVkQ29pbiwge30pO1xuICAgICAgICAgIGF3YWl0IGludmFsaWRXYWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9uKHt9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGAke3Vuc3VwcG9ydGVkQ29pbi5nZXRGdWxsTmFtZSgpfSBkb2VzIG5vdCBhbGxvdyBhY2NvdW50IGNvbnNvbGlkYXRpb25zLmAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGEgbm9uLWFjY291bnQgY29uc29saWRhdGlvbiBjb2luIHNlbmQgbXVsdGlwbGVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHVuc3VwcG9ydGVkQ29pbiA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgICAgICBjb25zdCBpbnZhbGlkV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdW5zdXBwb3J0ZWRDb2luLCB7fSk7XG4gICAgICAgICAgYXdhaXQgaW52YWxpZFdhbGxldC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKHt9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGAke3Vuc3VwcG9ydGVkQ29pbi5nZXRGdWxsTmFtZSgpfSBkb2VzIG5vdCBhbGxvdyBhY2NvdW50IGNvbnNvbGlkYXRpb25zLmAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGEgYmFkIHByZS1idWlsZCB0byBiZSBwYXNzZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgICAuc2VuZEFjY291bnRDb25zb2xpZGF0aW9uKHsgcHJlYnVpbGRUeDogJ3NvbWUgc3RyaW5nJyB9KVxuICAgICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBtZXNzYWdlOiAnSW52YWxpZCBidWlsZCBvZiBhY2NvdW50IGNvbnNvbGlkYXRpb24uJyB9KTtcbiAgICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAgIC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb24oeyBwcmVidWlsZFR4OiB1bmRlZmluZWQgfSlcbiAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgbWVzc2FnZTogJ0ludmFsaWQgYnVpbGQgb2YgYWNjb3VudCBjb25zb2xpZGF0aW9uLicgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVxdWlyZSBhIGNvbnNvbGlkYXRpb24gaWQgdG8gYmUgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgICAgLnNlbmRBY2NvdW50Q29uc29saWRhdGlvbih7IHByZWJ1aWxkVHg6IHt9IH0pXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IG1lc3NhZ2U6ICdGYWlsZWQgdG8gZmluZCBjb25zb2xpZGF0aW9uIGlkIG9uIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24uJyB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBzdWJtaXQgYSBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHsgcHJlYnVpbGRUeDogZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvblswXSB9O1xuXG4gICAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzWzBdKTtcblxuICAgICAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L3NlbmRgLCBmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9uKHBhcmFtcyk7XG5cbiAgICAgICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHN1Ym1pdCBhIGNvbnNvbGlkYXRpb24gYWNjb3VudCBzZW5kIChidWlsZCArIHNlbmQpIHdpdGggdHdvIHN1Y2Nlc3NlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY29wZUJ1aWxkID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2NvbnNvbGlkYXRlQWNjb3VudC9idWlsZGApXG4gICAgICAgICAgICAucXVlcnkoe30pXG4gICAgICAgICAgICAucmVwbHkoMjAwLCBmaXh0dXJlcy5idWlsZEFjY291bnRDb25zb2xpZGF0aW9uKTtcblxuICAgICAgICAgIHNpbm9uXG4gICAgICAgICAgICAuc3R1Yih3YWxsZXQsICdwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbicpXG4gICAgICAgICAgICAub25DYWxsKDApXG4gICAgICAgICAgICAucmVzb2x2ZXMoZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMF0pXG4gICAgICAgICAgICAub25DYWxsKDEpXG4gICAgICAgICAgICAucmVzb2x2ZXMoZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMV0pO1xuXG4gICAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnKS5yZXNvbHZlcyhbXSk7XG5cbiAgICAgICAgICBjb25zdCBzY29wZUZpcnN0U2lnbmVkID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KFxuICAgICAgICAgICAgICBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCxcbiAgICAgICAgICAgICAgZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMF1cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgICAgY29uc3Qgc2NvcGVUd29TaWduZWQgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoXG4gICAgICAgICAgICAgIGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L3NlbmRgLFxuICAgICAgICAgICAgICBmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1sxXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9ucyA9IGF3YWl0IHdhbGxldC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKCk7XG5cbiAgICAgICAgICBjb25zb2xpZGF0aW9ucy5zdWNjZXNzLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgICAgY29uc29saWRhdGlvbnMuZmFpbHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgICAgc2NvcGVGaXJzdFNpZ25lZC5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICAgIHNjb3BlVHdvU2lnbmVkLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgICAgc2NvcGVCdWlsZC5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHN1Ym1pdCBhIGNvbnNvbGlkYXRpb24gYWNjb3VudCBzZW5kIChidWlsZCArIHNlbmQpIHdpdGggb25lIHN1Y2Nlc3MsIG9uZSBmYWlsdXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjb3BlQnVpbGQgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vY29uc29saWRhdGVBY2NvdW50L2J1aWxkYClcbiAgICAgICAgICAgIC5xdWVyeSh7fSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb24pO1xuXG4gICAgICAgICAgc2lub25cbiAgICAgICAgICAgIC5zdHViKHdhbGxldCwgJ3ByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uJylcbiAgICAgICAgICAgIC5vbkNhbGwoMClcbiAgICAgICAgICAgIC5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1swXSlcbiAgICAgICAgICAgIC5vbkNhbGwoMSlcbiAgICAgICAgICAgIC5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1sxXSk7XG5cbiAgICAgICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZScpLnJlc29sdmVzKFtdKTtcblxuICAgICAgICAgIGNvbnN0IHNjb3BlV2l0aFN1Y2Nlc3MgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoXG4gICAgICAgICAgICAgIGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L3NlbmRgLFxuICAgICAgICAgICAgICBmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1swXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgICBjb25zdCBzY29wZVdpdGhFcnJvciA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChcbiAgICAgICAgICAgICAgYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvc2VuZGAsXG4gICAgICAgICAgICAgIGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzWzFdXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoNTAwKTtcblxuICAgICAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25zID0gYXdhaXQgd2FsbGV0LnNlbmRBY2NvdW50Q29uc29saWRhdGlvbnMoKTtcblxuICAgICAgICAgIGNvbnNvbGlkYXRpb25zLnN1Y2Nlc3MubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBjb25zb2xpZGF0aW9ucy5mYWlsdXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgICBzY29wZVdpdGhTdWNjZXNzLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgICAgc2NvcGVXaXRoRXJyb3IuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgICBzY29wZUJ1aWxkLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!