PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-celo/dist/test/unit/transactionBuilder
Просмотр файла: staking.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 assert_1 = __importDefault(require("assert"));
const should_1 = __importDefault(require("should"));
const statics_1 = require("@bitgo/statics");
const getBuilder_1 = require("../getBuilder");
const sdk_core_1 = require("@bitgo/sdk-core");
const testData = __importStar(require("../../resources/celo"));
describe('Celo staking transaction builder', () => {
let txBuilder;
beforeEach(() => {
txBuilder = (0, getBuilder_1.getBuilder)('tcelo');
txBuilder.type(sdk_core_1.TransactionType.StakingLock);
txBuilder.fee({
fee: '1000000000',
gasLimit: '12100000',
});
txBuilder.counter(1);
});
const coin = statics_1.coins.get('tcelo');
const LockOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.LOCK, coin.network.type);
const UnlockOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.UNLOCK, coin.network.type);
const WithdrawOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.WITHDRAW, coin.network.type);
const VoteOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.VOTE, coin.network.type);
const UnvoteOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.UNVOTE, coin.network.type);
const ActivateOperation = (0, sdk_core_1.getOperationConfig)(sdk_core_1.StakingOperationTypes.ACTIVATE, coin.network.type);
describe('lock', () => {
it('should build a lock transaction', async function () {
txBuilder.lock().amount('100');
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, LockOperation.contractAddress);
txJson.data.should.startWith(LockOperation.methodId);
should_1.default.equal(txJson.data, LockOperation.methodId);
});
it('should build a lock transaction using the previous instance', async function () {
txBuilder.lock().amount('200');
txBuilder.lock().amount('100');
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, LockOperation.contractAddress);
txJson.data.should.startWith(LockOperation.methodId);
should_1.default.equal(txJson.data, LockOperation.methodId);
});
it('should sign and build a lock transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.from(testData.LOCK_SERIALIZED);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, LockOperation.contractAddress);
txJson.data.should.startWith(LockOperation.methodId);
should_1.default.equal(txJson.data, LockOperation.methodId);
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.LOCK_BROADCAST_TX);
});
});
describe('vote', () => {
it('should build a vote transaction', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingVote);
txBuilder
.vote()
.group(testData.GROUP_ADDRESS)
.lesser(testData.LESSER_ADDRESS)
.greater(testData.GREATER_ADDRESS)
.amount('100');
txBuilder.sign({ key: testData.PRIVATE_KEY });
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, VoteOperation.contractAddress);
txJson.data.should.startWith(testData.VOTE_DATA_2);
should_1.default.equal(txJson.data, testData.VOTE_DATA_2);
});
it('should build a vote transaction using the previous instance', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingVote);
txBuilder
.vote()
.group(testData.GROUP_ADDRESS_2)
.lesser(testData.LESSER_ADDRESS)
.greater(testData.GREATER_ADDRESS)
.amount('500');
txBuilder
.vote()
.group(testData.GROUP_ADDRESS)
.lesser(testData.LESSER_ADDRESS_2)
.greater(testData.GREATER_ADDRESS_2)
.amount('100');
txBuilder.sign({ key: testData.PRIVATE_KEY });
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, VoteOperation.contractAddress);
txJson.data.should.startWith(testData.VOTE_DATA);
should_1.default.equal(txJson.data, testData.VOTE_DATA);
});
it('should sign and build a vote transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.from(testData.VOTE_BROADCAST_TX);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, VoteOperation.contractAddress);
should_1.default.equal(txJson.data, testData.VOTE_DATA_2);
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.VOTE_BROADCAST_TX);
});
});
describe('activate', () => {
it('should build an activate transaction', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingActivate);
txBuilder.activate().group(testData.GROUP_ADDRESS);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const tx = await txBuilder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, ActivateOperation.contractAddress);
txJson.data.should.startWith(testData.ACTIVATE_DATA);
should_1.default.equal(txJson.data, testData.ACTIVATE_DATA);
should_1.default.equal(tx.toBroadcastFormat(), testData.ACTIVATE_BROADCAST_TX);
});
it('should build an activate transaction from a previous instance', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingActivate);
txBuilder.activate().group(testData.GROUP_ADDRESS_2);
txBuilder.activate().group(testData.GROUP_ADDRESS);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const tx = await txBuilder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, ActivateOperation.contractAddress);
txJson.data.should.startWith(testData.ACTIVATE_DATA);
should_1.default.equal(txJson.data, testData.ACTIVATE_DATA);
should_1.default.equal(tx.toBroadcastFormat(), testData.ACTIVATE_BROADCAST_TX);
});
it('should sign and build an activate transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.from(testData.ACTIVATE_BROADCAST_TX);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, ActivateOperation.contractAddress);
should_1.default.equal(txJson.data, testData.ACTIVATE_DATA);
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.ACTIVATE_BROADCAST_TX);
});
});
describe('unvote', () => {
it('should build a unvote transaction', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingUnvote);
txBuilder
.unvote()
.group(testData.GROUP_ADDRESS)
.lesser(testData.LESSER_ADDRESS)
.greater(testData.GREATER_ADDRESS)
.amount('100')
.index(1);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, UnvoteOperation.contractAddress);
txJson.data.should.startWith(testData.UNVOTE_DATA);
should_1.default.equal(txJson.data, testData.UNVOTE_DATA);
});
it('should build a unvote transaction using the previous instance', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingUnvote);
txBuilder
.unvote()
.group(testData.GROUP_ADDRESS_2)
.lesser(testData.LESSER_ADDRESS)
.greater(testData.GREATER_ADDRESS)
.amount('500')
.index(1);
txBuilder
.unvote()
.group(testData.GROUP_ADDRESS)
.lesser(testData.LESSER_ADDRESS_2)
.greater(testData.GREATER_ADDRESS_2)
.amount('100')
.index(1);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, UnvoteOperation.contractAddress);
txJson.data.should.startWith(testData.UNVOTE_DATA_2);
should_1.default.equal(txJson.data, testData.UNVOTE_DATA_2);
});
it('should sign and build a unvote transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.from(testData.UNVOTE_BROADCAST_TX);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, UnvoteOperation.contractAddress);
should_1.default.equal(txJson.data, testData.UNVOTE_DATA);
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.UNVOTE_BROADCAST_TX);
});
});
describe('unlock', () => {
it('should build an unlock transaction', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingUnlock);
txBuilder.unlock().amount('100');
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, UnlockOperation.contractAddress);
txJson.data.should.startWith(UnlockOperation.methodId);
should_1.default.equal(txJson.data, testData.UNLOCK_DATA);
});
it('should build an unlock transaction from a previous instance', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingUnlock);
txBuilder.unlock().amount('500');
txBuilder.unlock().amount('100');
const txJson = (await txBuilder.build()).toJson();
should_1.default.equal(txJson.to, UnlockOperation.contractAddress);
txJson.data.should.startWith(UnlockOperation.methodId);
should_1.default.equal(txJson.data, testData.UNLOCK_DATA);
});
it('should sign and build an unlock transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.type(sdk_core_1.TransactionType.StakingLock);
builder.from(testData.UNLOCK_BROADCAST_TX);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, UnlockOperation.contractAddress);
txJson.data.should.startWith(UnlockOperation.methodId);
should_1.default.equal(txJson.data, testData.UNLOCK_DATA);
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.UNLOCK_BROADCAST_TX);
});
});
describe('withdraw', () => {
it('should build a withdraw transaction', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingWithdraw);
txBuilder.withdraw().index(0);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const tx = await txBuilder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, WithdrawOperation.contractAddress);
txJson.data.should.startWith(WithdrawOperation.methodId);
should_1.default.equal(txJson.data, testData.WITHDRAW_DATA);
should_1.default.equal(tx.toBroadcastFormat(), testData.WITHDRAW_BROADCAST_TX);
});
it('should build a withdraw transaction from a previous instance', async function () {
txBuilder.type(sdk_core_1.TransactionType.StakingWithdraw);
txBuilder.withdraw().index(2);
txBuilder.withdraw().index(0);
txBuilder.sign({ key: testData.PRIVATE_KEY });
const tx = await txBuilder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, WithdrawOperation.contractAddress);
txJson.data.should.startWith(WithdrawOperation.methodId);
should_1.default.equal(txJson.data, testData.WITHDRAW_DATA);
should_1.default.equal(txJson.from, testData.KEYPAIR_PRV.getAddress());
should_1.default.equal(tx.toBroadcastFormat(), testData.WITHDRAW_BROADCAST_TX);
});
it('should sign and build a withdraw transaction from serialized', async function () {
const builder = (0, getBuilder_1.getBuilder)('tcelo');
builder.type(sdk_core_1.TransactionType.StakingWithdraw);
builder.from(testData.WITHDRAW_BROADCAST_TX);
builder.sign({ key: testData.PRIVATE_KEY });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.equal(txJson.to, WithdrawOperation.contractAddress);
txJson.data.should.startWith(WithdrawOperation.methodId);
should_1.default.equal(txJson.from, testData.KEYPAIR_PRV.getAddress());
should_1.default.equal(txJson.from, testData.ACCOUNT1);
should_1.default.equal(tx.toBroadcastFormat(), testData.WITHDRAW_BROADCAST_TX);
});
});
describe('type validation', () => {
it('should not fail if the type is changed', () => {
txBuilder.lock();
txBuilder.type(sdk_core_1.TransactionType.StakingVote);
should_1.default.doesNotThrow(() => {
txBuilder.vote();
});
});
it('should fail to call lock if it is not an staking lock type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.lock();
}, (e) => e.message === testData.LOCK_TRANSACTION_TYPE_ERROR);
});
it('should fail to call vote if it is not an staking vote type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.vote();
}, (e) => e.message === testData.VOTE_TRANSACTION_TYPE_ERROR);
});
it('should fail to call activate if it is not an staking activate type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.activate();
}, (e) => e.message === testData.ACTIVATION_TRANSACTION_TYPE_ERROR);
});
it('should fail to call unlock if it is not an staking unlock type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.unlock();
}, (e) => e.message === testData.UNLOCK_TRANSACTION_TYPE_ERROR);
});
it('should fail to call unvote if it is not an staking unvote type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.unvote();
}, (e) => e.message === testData.UNVOTE_TRANSACTION_TYPE_ERROR);
});
it('should fail to call withdraw if it is not an staking withdraw type transaction', () => {
txBuilder.type(sdk_core_1.TransactionType.AddressInitialization);
assert_1.default.throws(() => {
txBuilder.withdraw();
}, (e) => e.message === testData.WITHDRAW_TRANSACTION_TYPE_ERROR);
});
it('should fail to build and staking lock operation if operationBuilder is not set', async () => {
await txBuilder.build().should.be.rejectedWith('No staking information set');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Rha2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC90cmFuc2FjdGlvbkJ1aWxkZXIvc3Rha2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QixvREFBNEI7QUFDNUIsNENBQXVDO0FBQ3ZDLDhDQUEyQztBQUUzQyw4Q0FBNkY7QUFDN0YsK0RBQWlEO0FBRWpELFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7SUFDaEQsSUFBSSxTQUFTLENBQUM7SUFDZCxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsU0FBUyxHQUFHLElBQUEsdUJBQVUsRUFBQyxPQUFPLENBQXVCLENBQUM7UUFDdEQsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzVDLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDWixHQUFHLEVBQUUsWUFBWTtZQUNqQixRQUFRLEVBQUUsVUFBVTtTQUNyQixDQUFDLENBQUM7UUFDSCxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxJQUFJLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxNQUFNLGFBQWEsR0FBRyxJQUFBLDZCQUFrQixFQUFDLGdDQUFxQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hGLE1BQU0sZUFBZSxHQUFHLElBQUEsNkJBQWtCLEVBQUMsZ0NBQXFCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUYsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLDZCQUFrQixFQUFDLGdDQUFxQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FB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Q0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyw2QkFBNkIsQ0FDakUsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRFQUE0RSxFQUFFLEdBQUcsRUFBRTtZQUNwRixTQUFTLENBQUMsSUFBSSxDQUFDLDBCQUFlLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN0RCxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUU7Z0JBQ0gsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3JCLENBQUMsRUFDRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxRQUFRLENBQUMsNkJBQTZCLENBQ2pFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnRkFBZ0YsRUFBRSxHQUFHLEVBQUU7WUFDeEYsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDdEQsZ0JBQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFO2dCQUNILFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN2QixDQUFDLEVBQ0QsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLCtCQUErQixDQUNuRSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0ZBQWdGLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDOUYsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUMvRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuLi9nZXRCdWlsZGVyJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBnZXRPcGVyYXRpb25Db25maWcsIFN0YWtpbmdPcGVyYXRpb25UeXBlcywgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uLy4uL3Jlc291cmNlcy9jZWxvJztcblxuZGVzY3JpYmUoJ0NlbG8gc3Rha2luZyB0cmFuc2FjdGlvbiBidWlsZGVyJywgKCkgPT4ge1xuICBsZXQgdHhCdWlsZGVyO1xuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0Y2VsbycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0xvY2spO1xuICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgZmVlOiAnMTAwMDAwMDAwMCcsXG4gICAgICBnYXNMaW1pdDogJzEyMTAwMDAwJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgfSk7XG5cbiAgY29uc3QgY29pbiA9IGNvaW5zLmdldCgndGNlbG8nKTtcbiAgY29uc3QgTG9ja09wZXJhdGlvbiA9IGdldE9wZXJhdGlvbkNvbmZpZyhTdGFraW5nT3BlcmF0aW9uVHlwZXMuTE9DSywgY29pbi5uZXR3b3JrLnR5cGUpO1xuICBjb25zdCBVbmxvY2tPcGVyYXRpb24gPSBnZXRPcGVyYXRpb25Db25maWcoU3Rha2luZ09wZXJhdGlvblR5cGVzLlVOTE9DSywgY29pbi5uZXR3b3JrLnR5cGUpO1xuICBjb25zdCBXaXRoZHJhd09wZXJhdGlvbiA9IGdldE9wZXJhdGlvbkNvbmZpZyhTdGFraW5nT3BlcmF0aW9uVHlwZXMuV0lUSERSQVcsIGNvaW4ubmV0d29yay50eXBlKTtcbiAgY29uc3QgVm90ZU9wZXJhdGlvbiA9IGdldE9wZXJhdGlvbkNvbmZpZyhTdGFraW5nT3BlcmF0aW9uVHlwZXMuVk9URSwgY29pbi5uZXR3b3JrLnR5cGUpO1xuICBjb25zdCBVbnZvdGVPcGVyYXRpb24gPSBnZXRPcGVyYXRpb25Db25maWcoU3Rha2luZ09wZXJhdGlvblR5cGVzLlVOVk9URSwgY29pbi5uZXR3b3JrLnR5cGUpO1xuICBjb25zdCBBY3RpdmF0ZU9wZXJhdGlvbiA9IGdldE9wZXJhdGlvbkNvbmZpZyhTdGFraW5nT3BlcmF0aW9uVHlwZXMuQUNUSVZBVEUsIGNvaW4ubmV0d29yay50eXBlKTtcblxuICBkZXNjcmliZSgnbG9jaycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgbG9jayB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci5sb2NrKCkuYW1vdW50KCcxMDAnKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBMb2NrT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKExvY2tPcGVyYXRpb24ubWV0aG9kSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5kYXRhLCBMb2NrT3BlcmF0aW9uLm1ldGhvZElkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYSBsb2NrIHRyYW5zYWN0aW9uIHVzaW5nIHRoZSBwcmV2aW91cyBpbnN0YW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci5sb2NrKCkuYW1vdW50KCcyMDAnKTtcbiAgICAgIHR4QnVpbGRlci5sb2NrKCkuYW1vdW50KCcxMDAnKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBMb2NrT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKExvY2tPcGVyYXRpb24ubWV0aG9kSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5kYXRhLCBMb2NrT3BlcmF0aW9uLm1ldGhvZElkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbmQgYnVpbGQgYSBsb2NrIHRyYW5zYWN0aW9uIGZyb20gc2VyaWFsaXplZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0Y2VsbycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIuZnJvbSh0ZXN0RGF0YS5MT0NLX1NFUklBTElaRUQpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5QUklWQVRFX0tFWSB9KTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBMb2NrT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKExvY2tPcGVyYXRpb24ubWV0aG9kSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5kYXRhLCBMb2NrT3BlcmF0aW9uLm1ldGhvZElkKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZnJvbSwgdGVzdERhdGEuQUNDT1VOVDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLkxPQ0tfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZvdGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHZvdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1ZvdGUpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC52b3RlKClcbiAgICAgICAgLmdyb3VwKHRlc3REYXRhLkdST1VQX0FERFJFU1MpXG4gICAgICAgIC5sZXNzZXIodGVzdERhdGEuTEVTU0VSX0FERFJFU1MpXG4gICAgICAgIC5ncmVhdGVyKHRlc3REYXRhLkdSRUFURVJfQUREUkVTUylcbiAgICAgICAgLmFtb3VudCgnMTAwJyk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eEpzb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgVm90ZU9wZXJhdGlvbi5jb250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhKc29uLmRhdGEuc2hvdWxkLnN0YXJ0V2l0aCh0ZXN0RGF0YS5WT1RFX0RBVEFfMik7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmRhdGEsIHRlc3REYXRhLlZPVEVfREFUQV8yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYSB2b3RlIHRyYW5zYWN0aW9uIHVzaW5nIHRoZSBwcmV2aW91cyBpbnN0YW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nVm90ZSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnZvdGUoKVxuICAgICAgICAuZ3JvdXAodGVzdERhdGEuR1JPVVBfQUREUkVTU18yKVxuICAgICAgICAubGVzc2VyKHRlc3REYXRhLkxFU1NFUl9BRERSRVNTKVxuICAgICAgICAuZ3JlYXRlcih0ZXN0RGF0YS5HUkVBVEVSX0FERFJFU1MpXG4gICAgICAgIC5hbW91bnQoJzUwMCcpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC52b3RlKClcbiAgICAgICAgLmdyb3VwKHRlc3REYXRhLkdST1VQX0FERFJFU1MpXG4gICAgICAgIC5sZXNzZXIodGVzdERhdGEuTEVTU0VSX0FERFJFU1NfMilcbiAgICAgICAgLmdyZWF0ZXIodGVzdERhdGEuR1JFQVRFUl9BRERSRVNTXzIpXG4gICAgICAgIC5hbW91bnQoJzEwMCcpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZIH0pO1xuICAgICAgY29uc3QgdHhKc29uID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24udG8sIFZvdGVPcGVyYXRpb24uY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgodGVzdERhdGEuVk9URV9EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuVk9URV9EQVRBKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbmQgYnVpbGQgYSB2b3RlIHRyYW5zYWN0aW9uIGZyb20gc2VyaWFsaXplZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0Y2VsbycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIuZnJvbSh0ZXN0RGF0YS5WT1RFX0JST0FEQ0FTVF9UWCk7XG4gICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24udG8sIFZvdGVPcGVyYXRpb24uY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuVk9URV9EQVRBXzIpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5BQ0NPVU5UMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuVk9URV9CUk9BRENBU1RfVFgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYWN0aXZhdGUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhbiBhY3RpdmF0ZSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQWN0aXZhdGUpO1xuICAgICAgdHhCdWlsZGVyLmFjdGl2YXRlKCkuZ3JvdXAodGVzdERhdGEuR1JPVVBfQUREUkVTUyk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBBY3RpdmF0ZU9wZXJhdGlvbi5jb250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhKc29uLmRhdGEuc2hvdWxkLnN0YXJ0V2l0aCh0ZXN0RGF0YS5BQ1RJVkFURV9EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuQUNUSVZBVEVfREFUQSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuQUNUSVZBVEVfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYW4gYWN0aXZhdGUgdHJhbnNhY3Rpb24gZnJvbSBhIHByZXZpb3VzIGluc3RhbmNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSk7XG4gICAgICB0eEJ1aWxkZXIuYWN0aXZhdGUoKS5ncm91cCh0ZXN0RGF0YS5HUk9VUF9BRERSRVNTXzIpO1xuICAgICAgdHhCdWlsZGVyLmFjdGl2YXRlKCkuZ3JvdXAodGVzdERhdGEuR1JPVVBfQUREUkVTUyk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBBY3RpdmF0ZU9wZXJhdGlvbi5jb250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhKc29uLmRhdGEuc2hvdWxkLnN0YXJ0V2l0aCh0ZXN0RGF0YS5BQ1RJVkFURV9EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuQUNUSVZBVEVfREFUQSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuQUNUSVZBVEVfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbmQgYnVpbGQgYW4gYWN0aXZhdGUgdHJhbnNhY3Rpb24gZnJvbSBzZXJpYWxpemVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RjZWxvJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgYnVpbGRlci5mcm9tKHRlc3REYXRhLkFDVElWQVRFX0JST0FEQ0FTVF9UWCk7XG4gICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24udG8sIEFjdGl2YXRlT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmRhdGEsIHRlc3REYXRhLkFDVElWQVRFX0RBVEEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5BQ0NPVU5UMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuQUNUSVZBVEVfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Vudm90ZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgdW52b3RlIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdVbnZvdGUpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC51bnZvdGUoKVxuICAgICAgICAuZ3JvdXAodGVzdERhdGEuR1JPVVBfQUREUkVTUylcbiAgICAgICAgLmxlc3Nlcih0ZXN0RGF0YS5MRVNTRVJfQUREUkVTUylcbiAgICAgICAgLmdyZWF0ZXIodGVzdERhdGEuR1JFQVRFUl9BRERSRVNTKVxuICAgICAgICAuYW1vdW50KCcxMDAnKVxuICAgICAgICAuaW5kZXgoMSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eEpzb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgVW52b3RlT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKHRlc3REYXRhLlVOVk9URV9EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuVU5WT1RFX0RBVEEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHVudm90ZSB0cmFuc2FjdGlvbiB1c2luZyB0aGUgcHJldmlvdXMgaW5zdGFuY2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1Vudm90ZSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnVudm90ZSgpXG4gICAgICAgIC5ncm91cCh0ZXN0RGF0YS5HUk9VUF9BRERSRVNTXzIpXG4gICAgICAgIC5sZXNzZXIodGVzdERhdGEuTEVTU0VSX0FERFJFU1MpXG4gICAgICAgIC5ncmVhdGVyKHRlc3REYXRhLkdSRUFURVJfQUREUkVTUylcbiAgICAgICAgLmFtb3VudCgnNTAwJylcbiAgICAgICAgLmluZGV4KDEpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC51bnZvdGUoKVxuICAgICAgICAuZ3JvdXAodGVzdERhdGEuR1JPVVBfQUREUkVTUylcbiAgICAgICAgLmxlc3Nlcih0ZXN0RGF0YS5MRVNTRVJfQUREUkVTU18yKVxuICAgICAgICAuZ3JlYXRlcih0ZXN0RGF0YS5HUkVBVEVSX0FERFJFU1NfMilcbiAgICAgICAgLmFtb3VudCgnMTAwJylcbiAgICAgICAgLmluZGV4KDEpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZIH0pO1xuICAgICAgY29uc3QgdHhKc29uID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24udG8sIFVudm90ZU9wZXJhdGlvbi5jb250cmFjdEFkZHJlc3MpO1xuICAgICAgdHhKc29uLmRhdGEuc2hvdWxkLnN0YXJ0V2l0aCh0ZXN0RGF0YS5VTlZPVEVfREFUQV8yKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuVU5WT1RFX0RBVEFfMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYW5kIGJ1aWxkIGEgdW52b3RlIHRyYW5zYWN0aW9uIGZyb20gc2VyaWFsaXplZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0Y2VsbycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIuZnJvbSh0ZXN0RGF0YS5VTlZPVEVfQlJPQURDQVNUX1RYKTtcbiAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgVW52b3RlT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmRhdGEsIHRlc3REYXRhLlVOVk9URV9EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZnJvbSwgdGVzdERhdGEuQUNDT1VOVDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlVOVk9URV9CUk9BRENBU1RfVFgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndW5sb2NrJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYnVpbGQgYW4gdW5sb2NrIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdVbmxvY2spO1xuICAgICAgdHhCdWlsZGVyLnVubG9jaygpLmFtb3VudCgnMTAwJyk7XG4gICAgICBjb25zdCB0eEpzb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgVW5sb2NrT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKFVubG9ja09wZXJhdGlvbi5tZXRob2RJZCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmRhdGEsIHRlc3REYXRhLlVOTE9DS19EQVRBKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYW4gdW5sb2NrIHRyYW5zYWN0aW9uIGZyb20gYSBwcmV2aW91cyBpbnN0YW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nVW5sb2NrKTtcbiAgICAgIHR4QnVpbGRlci51bmxvY2soKS5hbW91bnQoJzUwMCcpO1xuICAgICAgdHhCdWlsZGVyLnVubG9jaygpLmFtb3VudCgnMTAwJyk7XG4gICAgICBjb25zdCB0eEpzb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgVW5sb2NrT3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKFVubG9ja09wZXJhdGlvbi5tZXRob2RJZCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmRhdGEsIHRlc3REYXRhLlVOTE9DS19EQVRBKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbmQgYnVpbGQgYW4gdW5sb2NrIHRyYW5zYWN0aW9uIGZyb20gc2VyaWFsaXplZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0Y2VsbycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0xvY2spO1xuICAgICAgYnVpbGRlci5mcm9tKHRlc3REYXRhLlVOTE9DS19CUk9BRENBU1RfVFgpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5QUklWQVRFX0tFWSB9KTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRvLCBVbmxvY2tPcGVyYXRpb24uY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgoVW5sb2NrT3BlcmF0aW9uLm1ldGhvZElkKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuVU5MT0NLX0RBVEEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5BQ0NPVU5UMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuVU5MT0NLX0JST0FEQ0FTVF9UWCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3aXRoZHJhdycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgd2l0aGRyYXcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1dpdGhkcmF3KTtcbiAgICAgIHR4QnVpbGRlci53aXRoZHJhdygpLmluZGV4KDApO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgV2l0aGRyYXdPcGVyYXRpb24uY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgoV2l0aGRyYXdPcGVyYXRpb24ubWV0aG9kSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5kYXRhLCB0ZXN0RGF0YS5XSVRIRFJBV19EQVRBKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5XSVRIRFJBV19CUk9BRENBU1RfVFgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHdpdGhkcmF3IHRyYW5zYWN0aW9uIGZyb20gYSBwcmV2aW91cyBpbnN0YW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcpO1xuICAgICAgdHhCdWlsZGVyLndpdGhkcmF3KCkuaW5kZXgoMik7XG4gICAgICB0eEJ1aWxkZXIud2l0aGRyYXcoKS5pbmRleCgwKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5QUklWQVRFX0tFWSB9KTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24udG8sIFdpdGhkcmF3T3BlcmF0aW9uLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB0eEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKFdpdGhkcmF3T3BlcmF0aW9uLm1ldGhvZElkKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZGF0YSwgdGVzdERhdGEuV0lUSERSQVdfREFUQSk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmZyb20sIHRlc3REYXRhLktFWVBBSVJfUFJWLmdldEFkZHJlc3MoKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuV0lUSERSQVdfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbmQgYnVpbGQgYSB3aXRoZHJhdyB0cmFuc2FjdGlvbiBmcm9tIHNlcmlhbGl6ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZ2V0QnVpbGRlcigndGNlbG8nKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICBidWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdyk7XG4gICAgICBidWlsZGVyLmZyb20odGVzdERhdGEuV0lUSERSQVdfQlJPQURDQVNUX1RYKTtcbiAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUFJJVkFURV9LRVkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgV2l0aGRyYXdPcGVyYXRpb24uY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHR4SnNvbi5kYXRhLnNob3VsZC5zdGFydFdpdGgoV2l0aGRyYXdPcGVyYXRpb24ubWV0aG9kSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5LRVlQQUlSX1BSVi5nZXRBZGRyZXNzKCkpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5BQ0NPVU5UMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuV0lUSERSQVdfQlJPQURDQVNUX1RYKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3R5cGUgdmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG5vdCBmYWlsIGlmIHRoZSB0eXBlIGlzIGNoYW5nZWQnLCAoKSA9PiB7XG4gICAgICB0eEJ1aWxkZXIubG9jaygpO1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdWb3RlKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICB0eEJ1aWxkZXIudm90ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gY2FsbCBsb2NrIGlmIGl0IGlzIG5vdCBhbiBzdGFraW5nIGxvY2sgdHlwZSB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5BZGRyZXNzSW5pdGlhbGl6YXRpb24pO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5sb2NrKCk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gdGVzdERhdGEuTE9DS19UUkFOU0FDVElPTl9UWVBFX0VSUk9SXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGNhbGwgdm90ZSBpZiBpdCBpcyBub3QgYW4gc3Rha2luZyB2b3RlIHR5cGUgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQWRkcmVzc0luaXRpYWxpemF0aW9uKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIudm90ZSgpO1xuICAgICAgICB9LFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IHRlc3REYXRhLlZPVEVfVFJBTlNBQ1RJT05fVFlQRV9FUlJPUlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBjYWxsIGFjdGl2YXRlIGlmIGl0IGlzIG5vdCBhbiBzdGFraW5nIGFjdGl2YXRlIHR5cGUgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQWRkcmVzc0luaXRpYWxpemF0aW9uKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIuYWN0aXZhdGUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSB0ZXN0RGF0YS5BQ1RJVkFUSU9OX1RSQU5TQUNUSU9OX1RZUEVfRVJST1JcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gY2FsbCB1bmxvY2sgaWYgaXQgaXMgbm90IGFuIHN0YWtpbmcgdW5sb2NrIHR5cGUgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQWRkcmVzc0luaXRpYWxpemF0aW9uKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIudW5sb2NrKCk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gdGVzdERhdGEuVU5MT0NLX1RSQU5TQUNUSU9OX1RZUEVfRVJST1JcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gY2FsbCB1bnZvdGUgaWYgaXQgaXMgbm90IGFuIHN0YWtpbmcgdW52b3RlIHR5cGUgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQWRkcmVzc0luaXRpYWxpemF0aW9uKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIudW52b3RlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gdGVzdERhdGEuVU5WT1RFX1RSQU5TQUNUSU9OX1RZUEVfRVJST1JcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gY2FsbCB3aXRoZHJhdyBpZiBpdCBpcyBub3QgYW4gc3Rha2luZyB3aXRoZHJhdyB0eXBlIHRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLkFkZHJlc3NJbml0aWFsaXphdGlvbik7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLndpdGhkcmF3KCk7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gdGVzdERhdGEuV0lUSERSQVdfVFJBTlNBQ1RJT05fVFlQRV9FUlJPUlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBidWlsZCBhbmQgc3Rha2luZyBsb2NrIG9wZXJhdGlvbiBpZiBvcGVyYXRpb25CdWlsZGVyIGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdObyBzdGFraW5nIGluZm9ybWF0aW9uIHNldCcpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!