PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-etc/dist/test/unit
Просмотр файла: etc.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const src_1 = require("../../src");
const sinon_1 = __importDefault(require("sinon"));
const ethereumjs_util_1 = require("ethereumjs-util");
const getBuilder_1 = require("./getBuilder");
const should = __importStar(require("should"));
describe('Ethereum Classic', function () {
let bitgo;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
bitgo.initializeTestVars();
bitgo.safeRegister('etc', src_1.Etc.createInstance);
bitgo.safeRegister('tetc', src_1.Tetc.createInstance);
});
it('should instantiate the coin', function () {
let localBasecoin = bitgo.coin('tetc');
localBasecoin.should.be.an.instanceof(src_1.Tetc);
localBasecoin = bitgo.coin('etc');
localBasecoin.should.be.an.instanceof(src_1.Etc);
});
});
describe('Wallet Recovery Wizard', function () {
let sandbox;
let bitgo;
let tetcCoin;
const sourceRootAddress = '0x321cbe223ff1c3d0c03b73b8c648ef2d91e4aaa1';
const backupKeyAddress = '0x921f162bfd472424d6065b919c3f6e3bf13fe3d7';
const destinationWalletAddress = '0x76e2dcc49618f3b9769fc8a80b6991388570b3ae';
const walletPassPhrase = 'Z@oOQ6fkpzjkJXxM<bN1';
beforeEach(function () {
sandbox = sinon_1.default.createSandbox();
const callBack = sandbox.stub(src_1.Etc.prototype, 'queryAddressBalance');
callBack.withArgs(sourceRootAddress).resolves(new ethereumjs_util_1.BN('2190000000000000000'));
callBack.withArgs(backupKeyAddress).resolves(new ethereumjs_util_1.BN('190000000000000000'));
callBack.withArgs('0x5273e0d869226ccf579a81b6d291fb3702ba9dec').resolves(new ethereumjs_util_1.BN('0'));
callBack.withArgs('0x1b9af47cc3048fe1d31ad72299611d3df3926755').resolves(new ethereumjs_util_1.BN('190000000000000000'));
callBack.withArgs('0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23').resolves(new ethereumjs_util_1.BN('2190000000000000000'));
});
afterEach(function () {
sandbox.restore();
});
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
bitgo.safeRegister('tetc', src_1.Tetc.createInstance);
bitgo.initializeTestVars();
});
describe('Non-BitGo Recovery', function () {
beforeEach(function () {
tetcCoin = bitgo.coin('tetc');
});
it('should build a recovery transaction for non-bitgo recovery', async function () {
const walletContractAddress = sourceRootAddress;
const recovery = (await tetcCoin.recover({
userKey: '{"iv":"rP+aJBBP5VkYiGmc0KPz4A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"/B4OU/PQ1Eg=","ct":"HvCzOA23n6WxgFcBdH3ZqrLnZl5NckPPUyC/UDSv/KO8ZPBb1xZVTTY2ZY6/JBG8dHp/ApvAlRFm1SC+MjZ/OF9LC6Zjz8vsoLiS0BHB+z8Z6qB/16aWJbEIRzEmgEkWRn10l9m646GS00qGNHKG1VBURvUOYN4="}',
backupKey: '{"iv":"rDHtZUUKxaCQaIzGMB0b0w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0bmqSuxoVlA=","ct":"LyKRuUNVcRzhY5LUF15jKdKOpP04nUHs88FYPK1ZB9yuBSEGduQPjJs+xO62NCDh3pyiX1YeHBe9N6Gsm5Va0jSCk8XQ5pCwNuiO1RXvESAhfrXCivJMfRLVmCgaM79YMWapL7syUa//6mhu/1l4tPBBoZoBYc8="}',
walletContractAddress,
walletPassphrase: walletPassPhrase,
recoveryDestination: destinationWalletAddress,
}));
recovery.should.not.be.undefined();
recovery.should.have.property('id');
recovery.should.have.property('tx');
const txBuilder = (0, getBuilder_1.getBuilder)('tetc');
txBuilder.from(recovery.tx);
const tx = await txBuilder.build();
tx.toBroadcastFormat().should.not.be.empty();
});
it('should error when the backup key is unfunded (cannot pay gas)', async function () {
await tetcCoin
.recover({
userKey: '{"iv":"RI3d7nXJnnMTJFEKE5U6CA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"qZtZ8FXlr5I=","ct":"F49E7Pi3duSQ9v1iauXuQ6q6SqmGHLPQ9RNJTmfJp0AH2mwNe1bl/pMpwsaT12Ay3x3roLsi5+WFzePK8q1z43xwKfMWjTdsxj0yHpwa+8kOyckEnKyZ5J/AUw0nS7ujegTelaKR/wT2D+mvpJejQ+NRs9Lvyrg="}\n',
backupKey: '{"iv":"XJPzySPeTTAbLVol9fsQUA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"6LzbWSvK9Wo=","ct":"8fBnXkAX38ZtoHjN9MBUSkJ3dGgR8FuAmOo1sO7XfOu6Pan23YVpy468dKgl0C+UkzBQbnepNQ0UOf3kEudTYqt3/HgtvUcDdkkD3YDfEF1gVN7ndiBabF2C3SwnMNxUkuD0n5YWaRmaBPo+A2AGj4VrQ0wzFZs="}',
walletContractAddress: destinationWalletAddress,
walletPassphrase: walletPassPhrase,
recoveryDestination: sourceRootAddress,
})
.should.be.rejectedWith('Backup key address 0x5273e0d869226ccf579a81b6d291fb3702ba9dec has balance 0 Gwei.This address must have a balance of at least 10000000 Gwei to perform recoveries. Try sending some funds to this address then retry.');
});
it('should get the next sequence id for an address', async function () {
const baseCoin = bitgo.coin('tetc');
const walletContractAddress = '0x2E0b5638Bf3F774AF116029b09415AA9FDD812d5';
const sequenceId = await baseCoin.querySequenceId(walletContractAddress);
sequenceId.should.not.be.undefined();
});
});
describe('Unsigned sweep for cold wallet', function () {
const userXprv = 'xprv9s21ZrQH143K38Cfd5PyKGajVbA1sZYwAKQif8qvJMfMmSY85spqTnd4taexRHc9F92QCgBzHosCauYcnJWT9eWxfFKvSjAKoSgQkf74DoM';
const userXpub = 'xpub661MyMwAqRbcFcH8j6vygQXU3czWH2GnXYLKTXFXrhCLeEsGdR961awYjr3yC8eUj9rqhgFWHVbQJWqZS7kXpLBDzvoCKDLaBujsCH12Zfj';
const backupXprv = 'xprv9s21ZrQH143K3WkGc7rUw4NU5ZZTPczbMk9GajGxpJYhJXtfnYUL4j1x6vAGcxUg9XFzEHpQWPy3aYyJZcuGnYbc2eNzrsyNn3SRNdQa1PC';
const backupXpub = 'xpub661MyMwAqRbcGYaF52itktGhGDfiL9CBBTh4TSXV6QqGgXRbhSS5DAaTbdCPJA425XwkvwyCKtTmoxcUTAUgKUf7Qr5Ks9gJP9DTfiV2PhU';
const walletContractAddress = '0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23';
// tetc wallet 1 receiveAddress 4
const recoveryDestination = '0x321cbe223ff1c3d0c03b73b8c648ef2d91e4aaa1';
const gasPrice = 25000000000;
beforeEach(function () {
tetcCoin = bitgo.coin('tetc');
});
afterEach(function () {
sandbox.restore();
});
it('should generate an ETH unsigned sweep', async function () {
const transaction = (await tetcCoin.recover({
userKey: userXpub,
backupKey: backupXpub,
walletContractAddress,
recoveryDestination,
gasPrice,
}));
should.exist(transaction);
transaction.should.have.property('txHex');
transaction.should.have.property('userKey');
transaction.should.have.property('backupKey');
transaction.should.have.property('gasLimit');
transaction.gasLimit.should.equal('500000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('25000000000');
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal('0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23');
transaction.should.have.property('recipient');
});
it('should add a second signature', async function () {
const transaction = (await tetcCoin.recover({
userKey: userXpub,
backupKey: backupXpub,
walletContractAddress,
recoveryDestination,
gasPrice,
}));
const txPrebuild = {
txHex: transaction.txHex,
};
const params = {
txPrebuild,
prv: userXprv,
};
// sign transaction once
const halfSigned = await tetcCoin.signTransaction(params);
const halfSignedParams = {
txPrebuild: halfSigned,
isLastSignature: true,
walletContractAddress: walletContractAddress,
prv: backupXprv,
};
// sign transaction twice with the "isLastSignature" flag
const finalSignedTx = (await tetcCoin.signTransaction(halfSignedParams));
finalSignedTx.should.have.property('txHex');
const txBuilder = tetcCoin.getTransactionBuilder();
txBuilder.from(finalSignedTx.txHex);
const rebuiltTx = await txBuilder.build();
rebuiltTx.signature.length.should.equal(2);
rebuiltTx.outputs.length.should.equal(1);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0Yy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUEwRDtBQUMxRCw0Q0FBMEM7QUFDMUMsbUNBQTBEO0FBQzFELGtEQUEwQjtBQUcxQixxREFBcUM7QUFDckMsNkNBQTBDO0FBRTFDLCtDQUFpQztBQUVqQyxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsSUFBSSxLQUFtQixDQUFDO0lBRXhCLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNsRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUNoQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBSSxDQUFDLENBQUM7UUFFNUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFHLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLHdCQUF3QixF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QyxLQUFLLENBQUMsQ0FBQztZQUNwQyxNQUFNLFNBQVMsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBFdGMsIFRldGMsIFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgT2ZmbGluZVZhdWx0VHhJbmZvLCBTaWduVHJhbnNhY3Rpb25PcHRpb25zIH0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWV0aCc7XG5cbmltcG9ydCB7IEJOIH0gZnJvbSAnZXRoZXJldW1qcy11dGlsJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0IHsgRnVsbHlTaWduZWRUcmFuc2FjdGlvbiB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcblxuZGVzY3JpYmUoJ0V0aGVyZXVtIENsYXNzaWMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdldGMnLCBFdGMuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGV0YycsIFRldGMuY3JlYXRlSW5zdGFuY2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIHRoZSBjb2luJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbigndGV0YycpO1xuICAgIGxvY2FsQmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVGV0Yyk7XG5cbiAgICBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbignZXRjJyk7XG4gICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihFdGMpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnV2FsbGV0IFJlY292ZXJ5IFdpemFyZCcsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHNhbmRib3g7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgdGV0Y0NvaW46IFRldGM7XG5cbiAgY29uc3Qgc291cmNlUm9vdEFkZHJlc3MgPSAnMHgzMjFjYmUyMjNmZjFjM2QwYzAzYjczYjhjNjQ4ZWYyZDkxZTRhYWExJztcbiAgY29uc3QgYmFja3VwS2V5QWRkcmVzcyA9ICcweDkyMWYxNjJiZmQ0NzI0MjRkNjA2NWI5MTljM2Y2ZTNiZjEzZmUzZDcnO1xuICBjb25zdCBkZXN0aW5hdGlvbldhbGxldEFkZHJlc3MgPSAnMHg3NmUyZGNjNDk2MThmM2I5NzY5ZmM4YTgwYjY5OTEzODg1NzBiM2FlJztcbiAgY29uc3Qgd2FsbGV0UGFzc1BocmFzZSA9ICdaQG9PUTZma3B6amtKWHhNPGJOMSc7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRib3guc3R1YihFdGMucHJvdG90eXBlLCAncXVlcnlBZGRyZXNzQmFsYW5jZScgYXMga2V5b2YgRXRjKTtcbiAgICBjYWxsQmFjay53aXRoQXJncyhzb3VyY2VSb290QWRkcmVzcykucmVzb2x2ZXMobmV3IEJOKCcyMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKGJhY2t1cEtleUFkZHJlc3MpLnJlc29sdmVzKG5ldyBCTignMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKCcweDUyNzNlMGQ4NjkyMjZjY2Y1NzlhODFiNmQyOTFmYjM3MDJiYTlkZWMnKS5yZXNvbHZlcyhuZXcgQk4oJzAnKSk7XG4gICAgY2FsbEJhY2sud2l0aEFyZ3MoJzB4MWI5YWY0N2NjMzA0OGZlMWQzMWFkNzIyOTk2MTFkM2RmMzkyNjc1NScpLnJlc29sdmVzKG5ldyBCTignMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKCcweDdmY2Y5NWE5MTA2YTBlZDNiZDA5ZTY1M2M4ZWEzZDVlNDg5YmZiMjMnKS5yZXNvbHZlcyhuZXcgQk4oJzIxOTAwMDAwMDAwMDAwMDAwMDAnKSk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRjJywgVGV0Yy5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdOb24tQml0R28gUmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB0ZXRjQ29pbiA9IGJpdGdvLmNvaW4oJ3RldGMnKSBhcyBUZXRjO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBub24tYml0Z28gcmVjb3ZlcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBzb3VyY2VSb290QWRkcmVzcztcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gKGF3YWl0IHRldGNDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiclArYUpCQlA1VmtZaUdtYzBLUHo0QT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIi9CNE9VL1BRMUVnPVwiLFwiY3RcIjpcIkh2Q3pPQTIzbjZXeGdGY0JkSDNacXJMblpsNU5ja1BQVXlDL1VEU3YvS084WlBCYjF4WlZUVFkyWlk2L0pCRzhkSHAvQXB2QWxSRm0xU0MrTWpaL09GOUxDNlpqejh2c29MaVMwQkhCK3o4WjZxQi8xNmFXSmJFSVJ6RW1nRWtXUm4xMGw5bTY0NkdTMDBxR05IS0cxVkJVUnZVT1lOND1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJyREh0WlVVS3hhQ1FhSXpHTUIwYjB3PT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiMGJtcVN1eG9WbEE9XCIsXCJjdFwiOlwiTHlLUnVVTlZjUnpoWTVMVUYxNWpLZEtPcFAwNG5VSHM4OEZZUEsxWkI5eXVCU0VHZHVRUGpKcyt4TzYyTkNEaDNweWlYMVllSEJlOU42R3NtNVZhMGpTQ2s4WFE1cEN3TnVpTzFSWHZFU0FoZnJYQ2l2Sk1mUkxWbUNnYU03OVlNV2FwTDdzeVVhLy82bWh1LzFsNHRQQkJvWm9CWWM4PVwifScsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc1BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25XYWxsZXRBZGRyZXNzLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RldGMnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIuZnJvbShyZWNvdmVyeS50eCk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgdHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVycm9yIHdoZW4gdGhlIGJhY2t1cCBrZXkgaXMgdW5mdW5kZWQgKGNhbm5vdCBwYXkgZ2FzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHRldGNDb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJSSTNkN25YSm5uTVRKRkVLRTVVNkNBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwicVp0WjhGWGxyNUk9XCIsXCJjdFwiOlwiRjQ5RTdQaTNkdVNROXYxaWF1WHVRNnE2U3FtR0hMUFE5Uk5KVG1mSnAwQUgybXdOZTFibC9wTXB3c2FUMTJBeTN4M3JvTHNpNStXRnplUEs4cTF6NDN4d0tmTVdqVGRzeGoweUhwd2ErOGtPeWNrRW5LeVo1Si9BVXcwblM3dWplZ1RlbGFLUi93VDJEK212cEplalErTlJzOUx2eXJnPVwifVxcbicsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJYSlB6eVNQZVRUQWJMVm9sOWZzUVVBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiNkx6YldTdks5V289XCIsXCJjdFwiOlwiOGZCblhrQVgzOFp0b0hqTjlNQlVTa0ozZEdnUjhGdUFtT28xc083WGZPdTZQYW4yM1lWcHk0NjhkS2dsMEMrVWt6QlFibmVwTlEwVU9mM2tFdWRUWXF0My9IZ3R2VWNEZGtrRDNZRGZFRjFnVk43bmRpQmFiRjJDM1N3bk1OeFVrdUQwbjVZV2FSbWFCUG8rQTJBR2o0VnJRMHd6RlpzPVwifScsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBkZXN0aW5hdGlvbldhbGxldEFkZHJlc3MsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc1BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBzb3VyY2VSb290QWRkcmVzcyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweDUyNzNlMGQ4NjkyMjZjY2Y1NzlhODFiNmQyOTFmYjM3MDJiYTlkZWMgaGFzIGJhbGFuY2UgIDAgR3dlaS5UaGlzIGFkZHJlc3MgbXVzdCBoYXZlIGEgYmFsYW5jZSBvZiBhdCBsZWFzdCAxMDAwMDAwMCBHd2VpIHRvIHBlcmZvcm0gcmVjb3Zlcmllcy4gVHJ5IHNlbmRpbmcgc29tZSBmdW5kcyB0byB0aGlzIGFkZHJlc3MgdGhlbiByZXRyeS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgbmV4dCBzZXF1ZW5jZSBpZCBmb3IgYW4gYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbigndGV0YycpIGFzIFRldGM7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSAnMHgyRTBiNTYzOEJmM0Y3NzRBRjExNjAyOWIwOTQxNUFBOUZERDgxMmQ1JztcbiAgICAgIGNvbnN0IHNlcXVlbmNlSWQgPSBhd2FpdCBiYXNlQ29pbi5xdWVyeVNlcXVlbmNlSWQod2FsbGV0Q29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHNlcXVlbmNlSWQuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Vuc2lnbmVkIHN3ZWVwIGZvciBjb2xkIHdhbGxldCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB1c2VyWHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzM4Q2ZkNVB5S0dhalZiQTFzWll3QUtRaWY4cXZKTWZNbVNZODVzcHFUbmQ0dGFleFJIYzlGOTJRQ2dCekhvc0NhdVljbkpXVDllV3hmRkt2U2pBS29TZ1FrZjc0RG9NJztcbiAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0ZjSDhqNnZ5Z1FYVTNjeldIMkduWFlMS1RYRlhyaENMZUVzR2RSOTYxYXdZanIzeUM4ZVVqOXJxaGdGV0hWYlFKV3FaUzdrWHBMQkR6dm9DS0RMYUJ1anNDSDEyWmZqJztcbiAgICBjb25zdCBiYWNrdXBYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLM1drR2M3clV3NE5VNVpaVFBjemJNazlHYWpHeHBKWWhKWHRmbllVTDRqMXg2dkFHY3hVZzlYRnpFSHBRV1B5M2FZeUpaY3VHblliYzJlTnpyc3lObjNTUk5kUWExUEMnO1xuICAgIGNvbnN0IGJhY2t1cFhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHWWFGNTJpdGt0R2hHRGZpTDlDQkJUaDRUU1hWNlFxR2dYUmJoU1M1REFhVGJkQ1BKQTQyNVh3a3Z3eUNLdFRtb3hjVVRBVWdLVWY3UXI1S3M5Z0pQOURUZmlWMlBoVSc7XG5cbiAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSAnMHg3ZmNmOTVhOTEwNmEwZWQzYmQwOWU2NTNjOGVhM2Q1ZTQ4OWJmYjIzJztcbiAgICAvLyB0ZXRjIHdhbGxldCAxIHJlY2VpdmVBZGRyZXNzIDRcbiAgICBjb25zdCByZWNvdmVyeURlc3RpbmF0aW9uID0gJzB4MzIxY2JlMjIzZmYxYzNkMGMwM2I3M2I4YzY0OGVmMmQ5MWU0YWFhMSc7XG4gICAgY29uc3QgZ2FzUHJpY2UgPSAyNTAwMDAwMDAwMDtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgdGV0Y0NvaW4gPSBiaXRnby5jb2luKCd0ZXRjJykgYXMgVGV0YztcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gRVRIIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb246IE9mZmxpbmVWYXVsdFR4SW5mbyA9IChhd2FpdCB0ZXRjQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdXNlclhwdWIsXG4gICAgICAgIGJhY2t1cEtleTogYmFja3VwWHB1YixcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICBnYXNQcmljZSxcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndXNlcktleScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2JhY2t1cEtleScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNQcmljZS5zaG91bGQuZXF1YWwoJzI1MDAwMDAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweDdmY2Y5NWE5MTA2YTBlZDNiZDA5ZTY1M2M4ZWEzZDVlNDg5YmZiMjMnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWRkIGEgc2Vjb25kIHNpZ25hdHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IHRldGNDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiBiYWNrdXBYcHViLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgIGdhc1ByaWNlLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IHRyYW5zYWN0aW9uLnR4SGV4LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBwcnY6IHVzZXJYcHJ2LFxuICAgICAgfTtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gb25jZVxuICAgICAgY29uc3QgaGFsZlNpZ25lZCA9IGF3YWl0IHRldGNDb2luLnNpZ25UcmFuc2FjdGlvbihwYXJhbXMgYXMgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkUGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkOiBoYWxmU2lnbmVkLFxuICAgICAgICBpc0xhc3RTaWduYXR1cmU6IHRydWUsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBwcnY6IGJhY2t1cFhwcnYsXG4gICAgICB9O1xuICAgICAgLy8gc2lnbiB0cmFuc2FjdGlvbiB0d2ljZSB3aXRoIHRoZSBcImlzTGFzdFNpZ25hdHVyZVwiIGZsYWdcbiAgICAgIGNvbnN0IGZpbmFsU2lnbmVkVHggPSAoYXdhaXQgdGV0Y0NvaW4uc2lnblRyYW5zYWN0aW9uKFxuICAgICAgICBoYWxmU2lnbmVkUGFyYW1zIGFzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnNcbiAgICAgICkpIGFzIEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb247XG4gICAgICBmaW5hbFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gdGV0Y0NvaW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCkgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLmZyb20oZmluYWxTaWduZWRUeC50eEhleCk7XG4gICAgICBjb25zdCByZWJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRUeC5zaWduYXR1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHJlYnVpbHRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!