PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-sol/dist/test/unit/transactionBuilder

Просмотр файла: stakingDeactivateBuilder.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 should_1 = __importDefault(require("should"));
const getBuilderFactory_1 = require("../getBuilderFactory");
const src_1 = require("../../../src");
const testData = __importStar(require("../../resources/sol"));
const sdk_core_1 = require("@bitgo/sdk-core");
const bs58 = __importStar(require("bs58"));
describe('Sol Staking Deactivate Builder', () => {
    const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
    const walletKeyPair = new src_1.KeyPair(testData.authAccount);
    const wallet = walletKeyPair.getKeys();
    const stakeAccount = new src_1.KeyPair(testData.stakeAccount).getKeys();
    const splitAccount = new src_1.KeyPair(testData.splitStakeAccount).getKeys();
    const recentBlockHash = 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi';
    const invalidPubKey = testData.pubKeys.invalidPubKeys[0];
    describe('Should succeed', () => {
        const marinadeRecipientsObject = [];
        marinadeRecipientsObject.push({
            address: 'opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP',
            amount: '2300000',
        });
        const marinadeMemo = `{\\"PrepareForRevoke\\":{\\"user\\":\\"${wallet.pub}}\\",\\"amount\\":\\"500000000000\\"}`;
        it('building a staking deactivate tx', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash);
            const txUnsigned = await txBuilder.build();
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_DEACTIVATE_SIGNED_TX);
            const tx2 = await factory.from(txUnsigned.toBroadcastFormat()).build();
            const signed = tx.signature[0];
            should_1.default.equal(tx2.toBroadcastFormat(), txUnsigned.toBroadcastFormat());
            should_1.default.equal(tx2.signablePayload.toString('hex'), txUnsigned.signablePayload.toString('hex'));
            const txBuilder2 = factory.getStakingDeactivateBuilder();
            txBuilder2.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash);
            await txBuilder2.addSignature({ pub: wallet.pub }, Buffer.from(bs58.decode(signed)));
            const signedTx = await txBuilder2.build();
            should_1.default.equal(signedTx.type, sdk_core_1.TransactionType.StakingDeactivate);
            const rawSignedTx = signedTx.toBroadcastFormat();
            should_1.default.equal(rawSignedTx, testData.STAKING_DEACTIVATE_SIGNED_TX);
        });
        it('Marinade: build and sign a staking deactivate tx', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder
                .sender(wallet.pub)
                .stakingAddress(stakeAccount.pub)
                .nonce(recentBlockHash)
                .isMarinade(true)
                .memo(marinadeMemo)
                .recipients(marinadeRecipientsObject);
            const txUnsigned = await txBuilder.build();
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            txJson.instructionsData.should.deepEqual([
                {
                    params: {
                        memo: marinadeMemo,
                    },
                    type: 'Memo',
                },
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: '',
                        stakingAddress: '',
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: true,
                        recipients: marinadeRecipientsObject,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.MARINADE_STAKING_DEACTIVATE_SIGNED_TX);
            const tx2 = await factory.from(txUnsigned.toBroadcastFormat()).build();
            const signed = tx.signature[0];
            should_1.default.equal(tx2.toBroadcastFormat(), txUnsigned.toBroadcastFormat());
            should_1.default.equal(tx2.signablePayload.toString('hex'), txUnsigned.signablePayload.toString('hex'));
            const txBuilder2 = factory.getStakingDeactivateBuilder();
            txBuilder2
                .sender(wallet.pub)
                .stakingAddress(stakeAccount.pub)
                .nonce(recentBlockHash)
                .isMarinade(true)
                .memo(marinadeMemo)
                .recipients(marinadeRecipientsObject);
            await txBuilder2.addSignature({ pub: wallet.pub }, Buffer.from(bs58.decode(signed)));
            const signedTx = await txBuilder2.build();
            should_1.default.equal(signedTx.type, sdk_core_1.TransactionType.StakingDeactivate);
            const rawSignedTx = signedTx.toBroadcastFormat();
            should_1.default.equal(rawSignedTx, testData.MARINADE_STAKING_DEACTIVATE_SIGNED_TX);
        });
        it('building a staking multi deactivate tx', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddresses([stakeAccount.pub, splitAccount.pub]).nonce(recentBlockHash);
            const txUnsigned = await txBuilder.build();
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: splitAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_MULTI_DEACTIVATE_UNSIGNED_TX);
            const tx2 = await factory.from(txUnsigned.toBroadcastFormat()).build();
            const signed = tx.signature[0];
            should_1.default.equal(tx2.toBroadcastFormat(), txUnsigned.toBroadcastFormat());
            should_1.default.equal(tx2.signablePayload.toString('hex'), txUnsigned.signablePayload.toString('hex'));
            const txBuilder2 = factory.getStakingDeactivateBuilder();
            txBuilder2.sender(wallet.pub).stakingAddresses([stakeAccount.pub, splitAccount.pub]).nonce(recentBlockHash);
            await txBuilder2.addSignature({ pub: wallet.pub }, Buffer.from(bs58.decode(signed)));
            const signedTx = await txBuilder2.build();
            should_1.default.equal(signedTx.type, sdk_core_1.TransactionType.StakingDeactivate);
            const rawSignedTx = signedTx.toBroadcastFormat();
            should_1.default.equal(rawSignedTx, testData.STAKING_MULTI_DEACTIVATE_SIGNED_TX);
        });
        it('should build and sign a multi deactivate single', async function () {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddresses([stakeAccount.pub]).nonce(recentBlockHash);
            const txUnsigned = await txBuilder.build();
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            const rawTx = tx.toBroadcastFormat();
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_MULTI_DEACTIVATE_SIGNED_TX_single);
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            const tx2 = await factory.from(txUnsigned.toBroadcastFormat()).build();
            const signed = tx.signature[0];
            should_1.default.equal(tx2.toBroadcastFormat(), txUnsigned.toBroadcastFormat());
            should_1.default.equal(tx2.signablePayload.toString('hex'), txUnsigned.signablePayload.toString('hex'));
            const txBuilder2 = factory.getStakingDeactivateBuilder();
            txBuilder2.sender(wallet.pub).stakingAddresses([stakeAccount.pub]).nonce(recentBlockHash);
            await txBuilder2.addSignature({ pub: wallet.pub }, Buffer.from(bs58.decode(signed)));
            const signedTx = await txBuilder2.build();
            should_1.default.equal(signedTx.type, sdk_core_1.TransactionType.StakingDeactivate);
            const rawSignedTx = signedTx.toBroadcastFormat();
            should_1.default.equal(rawSignedTx, testData.STAKING_MULTI_DEACTIVATE_SIGNED_TX_single);
        });
        it('should build and sign a deactivate single', async function () {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash);
            txBuilder.sign({ key: wallet.prv });
            const txUnsigned = await txBuilder.build();
            const tx = await txBuilder.build();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(rawTx, testData.STAKING_DEACTIVATE_SIGNED_TX_single);
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            const tx2 = await factory.from(testData.STAKING_DEACTIVATE_UNSIGNED_TX_single).build();
            const signed = tx.signature[0];
            should_1.default.equal(tx2.toBroadcastFormat(), txUnsigned.toBroadcastFormat());
            should_1.default.equal(tx2.signablePayload.toString('hex'), txUnsigned.signablePayload.toString('hex'));
            const txBuilder2 = factory.getStakingDeactivateBuilder();
            txBuilder2.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash);
            await txBuilder2.addSignature({ pub: wallet.pub }, Buffer.from(bs58.decode(signed)));
            const signedTx = await txBuilder2.build();
            should_1.default.equal(signedTx.type, sdk_core_1.TransactionType.StakingDeactivate);
            const rawSignedTx = signedTx.toBroadcastFormat();
            should_1.default.equal(rawSignedTx, testData.STAKING_DEACTIVATE_SIGNED_TX_single);
        });
        it('building a staking deactivate signed tx with memo', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash).memo('Test deactivate');
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            const txJson = tx.toJson();
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Memo',
                    params: {
                        memo: 'Test deactivate',
                    },
                },
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_DEACTIVATE_SIGNED_TX_WITH_MEMO);
        });
        it('building a staking deactivate unsigned tx', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash);
            const tx = await txBuilder.build();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            const txJson = tx.toJson();
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_DEACTIVATE_UNSIGNED_TX);
        });
        it('building a staking deactivate unsigned tx with memo', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).stakingAddress(stakeAccount.pub).nonce(recentBlockHash).memo('Test deactivate');
            const tx = await txBuilder.build();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            const txJson = tx.toJson();
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Memo',
                    params: {
                        memo: 'Test deactivate',
                    },
                },
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: undefined,
                        unstakingAddress: undefined,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_DEACTIVATE_UNSIGNED_TX_WITH_MEMO);
        });
        it('building an encoded unsigned transaction and signing it', async () => {
            const txBuilder = factory.from(testData.STAKING_DEACTIVATE_UNSIGNED_TX_WITH_MEMO);
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            should_1.default.equal(tx.toBroadcastFormat(), testData.STAKING_DEACTIVATE_SIGNED_TX_WITH_MEMO);
        });
        it('building an encoded signed transaction', async () => {
            const txBuilder = factory.from(testData.STAKING_DEACTIVATE_SIGNED_TX_WITH_MEMO);
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            should_1.default.equal(tx.toBroadcastFormat(), testData.STAKING_DEACTIVATE_SIGNED_TX_WITH_MEMO);
        });
        it('building a partial staking deactivate tx', async () => {
            const txBuilder = factory
                .getStakingDeactivateBuilder()
                .sender(wallet.pub)
                .stakingAddress(stakeAccount.pub)
                .unstakingAddress(testData.splitStakeAccount.pub)
                .amount('100000')
                .nonce(recentBlockHash);
            txBuilder.sign({ key: wallet.prv });
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            const rawTx = tx.toBroadcastFormat();
            should_1.default.equal(src_1.Utils.isValidRawTransaction(rawTx), true);
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'Deactivate',
                    params: {
                        fromAddress: wallet.pub,
                        stakingAddress: stakeAccount.pub,
                        amount: '100000',
                        unstakingAddress: testData.splitStakeAccount.pub,
                        isMarinade: false,
                        recipients: undefined,
                    },
                },
            ]);
            should_1.default.equal(rawTx, testData.STAKING_PARTIAL_DEACTIVATE_SIGNED_TX);
            const tx2 = await factory.from(testData.STAKING_PARTIAL_DEACTIVATE_SIGNED_TX).build();
            const txJson2 = tx2.toJson();
            tx2.toBroadcastFormat();
            delete tx['_id'];
            delete tx2['_id'];
            should_1.default.deepEqual(tx, tx2);
            should_1.default.deepEqual(txJson2, txJson2);
        });
    });
    describe('Should fail', () => {
        it('building a staking deactivate tx without staking address', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).nonce(recentBlockHash);
            txBuilder.sign({ key: wallet.prv });
            await txBuilder.build().should.be.rejectedWith('Staking address must be set before building the transaction');
        });
        it('building a staking deactivate tx with a wrong staking address', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).nonce(recentBlockHash);
            (0, should_1.default)(() => txBuilder.stakingAddress(invalidPubKey)).throwError(`Invalid or missing stakingAddress, got: ${invalidPubKey}`);
        });
        it('building a staking deactivate tx with the same address as sender and staking', async () => {
            const txBuilder = factory.getStakingDeactivateBuilder();
            txBuilder.sender(wallet.pub).nonce(recentBlockHash);
            txBuilder.stakingAddress(wallet.pub);
            await txBuilder.build().should.rejectedWith('Sender address cannot be the same as the Staking address');
        });
        it('building a partial staking deactivate tx without an amount', async () => {
            const txBuilder = factory
                .getStakingDeactivateBuilder()
                .sender(wallet.pub)
                .nonce(recentBlockHash)
                .stakingAddress(testData.stakeAccount.pub)
                .unstakingAddress(testData.splitStakeAccount.pub);
            txBuilder.sign({ key: wallet.prv });
            await txBuilder
                .build()
                .should.be.rejectedWith('If an unstaking address is given then a partial amount to unstake must also be set before building the transaction');
        });
        it('building a partial staking deactivate tx without an unstaking address', async () => {
            const txBuilder = factory
                .getStakingDeactivateBuilder()
                .sender(wallet.pub)
                .nonce(recentBlockHash)
                .stakingAddress(testData.stakeAccount.pub)
                .amount('10');
            txBuilder.sign({ key: wallet.prv });
            await txBuilder
                .build()
                .should.be.rejectedWith('When partially unstaking the unstaking address must be set before building the transaction');
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci9zdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFFNUIsNERBQXlEO0FBQ3pELHNDQUE4QztBQUM5Qyw4REFBZ0Q7QUFDaEQsOENBQTZEO0FBQzdELDJDQUE2QjtBQUU3QixRQUFRLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO0lBQzlDLE1BQU0sT0FBTyxHQUFHLElBQUEscUNBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7SUFFMUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxhQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN2QyxNQUFNLFlBQVksR0FBRyxJQUFJLGFBQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbEUsTUFBTSxZQUFZLEdBQUcsSUFBSSxhQUFPLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDdkUsTUFBTSxlQUFlLEdBQUcsOENBQThDLENBQUM7SUFDdkUsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFekQsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtRQUM5QixNQUFNLHdCQUF3QixHQUFnQixFQUFFLENBQUM7UUFDakQsd0JBQXdCLENBQUMsSUFBSSxDQUFDO1lBQzVCLE9BQU8sRUFBRSw2Q0FBNkM7WUFDdEQsTUFBTSxFQUFFLFNBQVM7U0FDbEIsQ0FBQyxDQUFDO1FB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U0FBUyxHQUFHLE9BQU87aUJBQ3RCLDJCQUEyQixFQUFFO2lCQUM3QixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztpQkFDbEIsS0FBSyxDQUFDLGVBQWUsQ0FBQztpQkFDdEIsY0FBYyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDO2lCQUN6QyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDaEIsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUVwQyxNQUFNLFNBQVM7aUJBQ1osS0FBSyxFQUFFO2lCQUNQLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUNyQiw0RkFBNEYsQ0FDN0YsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcblxuaW1wb3J0IHsgZ2V0QnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi9nZXRCdWlsZGVyRmFjdG9yeSc7XG5pbXBvcnQgeyBLZXlQYWlyLCBVdGlscyB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvc29sJztcbmltcG9ydCB7IFJlY2lwaWVudCwgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIGJzNTggZnJvbSAnYnM1OCc7XG5cbmRlc2NyaWJlKCdTb2wgU3Rha2luZyBEZWFjdGl2YXRlIEJ1aWxkZXInLCAoKSA9PiB7XG4gIGNvbnN0IGZhY3RvcnkgPSBnZXRCdWlsZGVyRmFjdG9yeSgndHNvbCcpO1xuXG4gIGNvbnN0IHdhbGxldEtleVBhaXIgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5hdXRoQWNjb3VudCk7XG4gIGNvbnN0IHdhbGxldCA9IHdhbGxldEtleVBhaXIuZ2V0S2V5cygpO1xuICBjb25zdCBzdGFrZUFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5zdGFrZUFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3Qgc3BsaXRBY2NvdW50ID0gbmV3IEtleVBhaXIodGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3QgcmVjZW50QmxvY2tIYXNoID0gJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJztcbiAgY29uc3QgaW52YWxpZFB1YktleSA9IHRlc3REYXRhLnB1YktleXMuaW52YWxpZFB1YktleXNbMF07XG5cbiAgZGVzY3JpYmUoJ1Nob3VsZCBzdWNjZWVkJywgKCkgPT4ge1xuICAgIGNvbnN0IG1hcmluYWRlUmVjaXBpZW50c09iamVjdDogUmVjaXBpZW50W10gPSBbXTtcbiAgICBtYXJpbmFkZVJlY2lwaWVudHNPYmplY3QucHVzaCh7XG4gICAgICBhZGRyZXNzOiAnb3BOUzhFTnBFTVdkWGNKVWdKQ3NKVERwN2FyVFhheW9CRWVCVWc2VWV6UCcsXG4gICAgICBhbW91bnQ6ICcyMzAwMDAwJyxcbiAgICB9KTtcbiAgICBjb25zdCBtYXJpbmFkZU1lbW8gPSBge1xcXFxcIlByZXBhcmVGb3JSZXZva2VcXFxcXCI6e1xcXFxcInVzZXJcXFxcXCI6XFxcXFwiJHt3YWxsZXQucHVifX1cXFxcXCIsXFxcXFwiYW1vdW50XFxcXFwiOlxcXFxcIjUwMDAwMDAwMDAwMFxcXFxcIn1gO1xuXG4gICAgaXQoJ2J1aWxkaW5nIGEgc3Rha2luZyBkZWFjdGl2YXRlIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIod2FsbGV0LnB1Yikuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1Yikubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIGNvbnN0IHR4VW5zaWduZWQgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgcmF3VHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKFV0aWxzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUeCksIHRydWUpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEuc2hvdWxkLmRlZXBFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpc01hcmluYWRlOiBmYWxzZSxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBzaG91bGQuZXF1YWwocmF3VHgsIHRlc3REYXRhLlNUQUtJTkdfREVBQ1RJVkFURV9TSUdORURfVFgpO1xuXG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCBmYWN0b3J5LmZyb20odHhVbnNpZ25lZC50b0Jyb2FkY2FzdEZvcm1hdCgpKS5idWlsZCgpO1xuICAgICAgY29uc3Qgc2lnbmVkID0gdHguc2lnbmF0dXJlWzBdO1xuXG4gICAgICBzaG91bGQuZXF1YWwodHgyLnRvQnJvYWRjYXN0Rm9ybWF0KCksIHR4VW5zaWduZWQudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHgyLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4JyksIHR4VW5zaWduZWQuc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBmYWN0b3J5LmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyMi5zZW5kZXIod2FsbGV0LnB1Yikuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1Yikubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlcjIuYWRkU2lnbmF0dXJlKHsgcHViOiB3YWxsZXQucHViIH0sIEJ1ZmZlci5mcm9tKGJzNTguZGVjb2RlKHNpZ25lZCkpKTtcbiAgICAgIGNvbnN0IHNpZ25lZFR4ID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHNpZ25lZFR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSk7XG5cbiAgICAgIGNvbnN0IHJhd1NpZ25lZFR4ID0gc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdTaWduZWRUeCwgdGVzdERhdGEuU1RBS0lOR19ERUFDVElWQVRFX1NJR05FRF9UWCk7XG4gICAgfSk7XG5cbiAgICBpdCgnTWFyaW5hZGU6IGJ1aWxkIGFuZCBzaWduIGEgc3Rha2luZyBkZWFjdGl2YXRlIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAubm9uY2UocmVjZW50QmxvY2tIYXNoKVxuICAgICAgICAuaXNNYXJpbmFkZSh0cnVlKVxuICAgICAgICAubWVtbyhtYXJpbmFkZU1lbW8pXG4gICAgICAgIC5yZWNpcGllbnRzKG1hcmluYWRlUmVjaXBpZW50c09iamVjdCk7XG4gICAgICBjb25zdCB0eFVuc2lnbmVkID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogd2FsbGV0LnBydiB9KTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChVdGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHgpLCB0cnVlKTtcbiAgICAgIHR4SnNvbi5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtZW1vOiBtYXJpbmFkZU1lbW8sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eXBlOiAnTWVtbycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogJycsXG4gICAgICAgICAgICBzdGFraW5nQWRkcmVzczogJycsXG4gICAgICAgICAgICBhbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVuc3Rha2luZ0FkZHJlc3M6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzTWFyaW5hZGU6IHRydWUsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBtYXJpbmFkZVJlY2lwaWVudHNPYmplY3QsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgICAgc2hvdWxkLmVxdWFsKHJhd1R4LCB0ZXN0RGF0YS5NQVJJTkFERV9TVEFLSU5HX0RFQUNUSVZBVEVfU0lHTkVEX1RYKTtcblxuICAgICAgY29uc3QgdHgyID0gYXdhaXQgZmFjdG9yeS5mcm9tKHR4VW5zaWduZWQudG9Ccm9hZGNhc3RGb3JtYXQoKSkuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IHR4LnNpZ25hdHVyZVswXTtcblxuICAgICAgc2hvdWxkLmVxdWFsKHR4Mi50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0eFVuc2lnbmVkLnRvQnJvYWRjYXN0Rm9ybWF0KCkpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4Mi5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpLCB0eFVuc2lnbmVkLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4JykpO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlcjJcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLm5vbmNlKHJlY2VudEJsb2NrSGFzaClcbiAgICAgICAgLmlzTWFyaW5hZGUodHJ1ZSlcbiAgICAgICAgLm1lbW8obWFyaW5hZGVNZW1vKVxuICAgICAgICAucmVjaXBpZW50cyhtYXJpbmFkZVJlY2lwaWVudHNPYmplY3QpO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyMi5hZGRTaWduYXR1cmUoeyBwdWI6IHdhbGxldC5wdWIgfSwgQnVmZmVyLmZyb20oYnM1OC5kZWNvZGUoc2lnbmVkKSkpO1xuICAgICAgY29uc3Qgc2lnbmVkVHggPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gICAgICBzaG91bGQuZXF1YWwoc2lnbmVkVHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlKTtcblxuICAgICAgY29uc3QgcmF3U2lnbmVkVHggPSBzaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHJhd1NpZ25lZFR4LCB0ZXN0RGF0YS5NQVJJTkFERV9TVEFLSU5HX0RFQUNUSVZBVEVfU0lHTkVEX1RYKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZGluZyBhIHN0YWtpbmcgbXVsdGkgZGVhY3RpdmF0ZSB0eCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKHdhbGxldC5wdWIpLnN0YWtpbmdBZGRyZXNzZXMoW3N0YWtlQWNjb3VudC5wdWIsIHNwbGl0QWNjb3VudC5wdWJdKS5ub25jZShyZWNlbnRCbG9ja0hhc2gpO1xuICAgICAgY29uc3QgdHhVbnNpZ25lZCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHdhbGxldC5wcnYgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBjb25zdCByYXdUeCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBzaG91bGQuZXF1YWwoVXRpbHMuaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHJhd1R4KSwgdHJ1ZSk7XG4gICAgICB0eEpzb24uaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdEZWFjdGl2YXRlJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiB3YWxsZXQucHViLFxuICAgICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtlQWNjb3VudC5wdWIsXG4gICAgICAgICAgICBhbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVuc3Rha2luZ0FkZHJlc3M6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgICAgcmVjaXBpZW50czogdW5kZWZpbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzcGxpdEFjY291bnQucHViLFxuICAgICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpc01hcmluYWRlOiBmYWxzZSxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBzaG91bGQuZXF1YWwocmF3VHgsIHRlc3REYXRhLlNUQUtJTkdfTVVMVElfREVBQ1RJVkFURV9VTlNJR05FRF9UWCk7XG5cbiAgICAgIGNvbnN0IHR4MiA9IGF3YWl0IGZhY3RvcnkuZnJvbSh0eFVuc2lnbmVkLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLmJ1aWxkKCk7XG4gICAgICBjb25zdCBzaWduZWQgPSB0eC5zaWduYXR1cmVbMF07XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0eDIudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdHhVbnNpZ25lZC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eDIuc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSwgdHhVbnNpZ25lZC5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGZhY3RvcnkuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIyLnNlbmRlcih3YWxsZXQucHViKS5zdGFraW5nQWRkcmVzc2VzKFtzdGFrZUFjY291bnQucHViLCBzcGxpdEFjY291bnQucHViXSkubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlcjIuYWRkU2lnbmF0dXJlKHsgcHViOiB3YWxsZXQucHViIH0sIEJ1ZmZlci5mcm9tKGJzNTguZGVjb2RlKHNpZ25lZCkpKTtcbiAgICAgIGNvbnN0IHNpZ25lZFR4ID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHNpZ25lZFR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSk7XG5cbiAgICAgIGNvbnN0IHJhd1NpZ25lZFR4ID0gc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdTaWduZWRUeCwgdGVzdERhdGEuU1RBS0lOR19NVUxUSV9ERUFDVElWQVRFX1NJR05FRF9UWCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGFuZCBzaWduIGEgbXVsdGkgZGVhY3RpdmF0ZSBzaW5nbGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcih3YWxsZXQucHViKS5zdGFraW5nQWRkcmVzc2VzKFtzdGFrZUFjY291bnQucHViXSkubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIGNvbnN0IHR4VW5zaWduZWQgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgcmF3VHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEuc2hvdWxkLmRlZXBFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpc01hcmluYWRlOiBmYWxzZSxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBzaG91bGQuZXF1YWwocmF3VHgsIHRlc3REYXRhLlNUQUtJTkdfTVVMVElfREVBQ1RJVkFURV9TSUdORURfVFhfc2luZ2xlKTtcbiAgICAgIHNob3VsZC5lcXVhbChVdGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHgpLCB0cnVlKTtcblxuICAgICAgY29uc3QgdHgyID0gYXdhaXQgZmFjdG9yeS5mcm9tKHR4VW5zaWduZWQudG9Ccm9hZGNhc3RGb3JtYXQoKSkuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IHR4LnNpZ25hdHVyZVswXTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eDIudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdHhVbnNpZ25lZC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eDIuc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSwgdHhVbnNpZ25lZC5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGZhY3RvcnkuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIyLnNlbmRlcih3YWxsZXQucHViKS5zdGFraW5nQWRkcmVzc2VzKFtzdGFrZUFjY291bnQucHViXSkubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlcjIuYWRkU2lnbmF0dXJlKHsgcHViOiB3YWxsZXQucHViIH0sIEJ1ZmZlci5mcm9tKGJzNTguZGVjb2RlKHNpZ25lZCkpKTtcbiAgICAgIGNvbnN0IHNpZ25lZFR4ID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHNpZ25lZFR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSk7XG5cbiAgICAgIGNvbnN0IHJhd1NpZ25lZFR4ID0gc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdTaWduZWRUeCwgdGVzdERhdGEuU1RBS0lOR19NVUxUSV9ERUFDVElWQVRFX1NJR05FRF9UWF9zaW5nbGUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhbmQgc2lnbiBhIGRlYWN0aXZhdGUgc2luZ2xlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIod2FsbGV0LnB1Yikuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1Yikubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHhVbnNpZ25lZCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdUeCwgdGVzdERhdGEuU1RBS0lOR19ERUFDVElWQVRFX1NJR05FRF9UWF9zaW5nbGUpO1xuICAgICAgc2hvdWxkLmVxdWFsKFV0aWxzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUeCksIHRydWUpO1xuXG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCBmYWN0b3J5LmZyb20odGVzdERhdGEuU1RBS0lOR19ERUFDVElWQVRFX1VOU0lHTkVEX1RYX3NpbmdsZSkuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IHR4LnNpZ25hdHVyZVswXTtcblxuICAgICAgc2hvdWxkLmVxdWFsKHR4Mi50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0eFVuc2lnbmVkLnRvQnJvYWRjYXN0Rm9ybWF0KCkpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4Mi5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpLCB0eFVuc2lnbmVkLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4JykpO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlcjIuc2VuZGVyKHdhbGxldC5wdWIpLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpLm5vbmNlKHJlY2VudEJsb2NrSGFzaCk7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIyLmFkZFNpZ25hdHVyZSh7IHB1Yjogd2FsbGV0LnB1YiB9LCBCdWZmZXIuZnJvbShiczU4LmRlY29kZShzaWduZWQpKSk7XG4gICAgICBjb25zdCBzaWduZWRUeCA9IGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChzaWduZWRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUpO1xuXG4gICAgICBjb25zdCByYXdTaWduZWRUeCA9IHNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBzaG91bGQuZXF1YWwocmF3U2lnbmVkVHgsIHRlc3REYXRhLlNUQUtJTkdfREVBQ1RJVkFURV9TSUdORURfVFhfc2luZ2xlKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZGluZyBhIHN0YWtpbmcgZGVhY3RpdmF0ZSBzaWduZWQgdHggd2l0aCBtZW1vJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIod2FsbGV0LnB1Yikuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1Yikubm9uY2UocmVjZW50QmxvY2tIYXNoKS5tZW1vKCdUZXN0IGRlYWN0aXZhdGUnKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChVdGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHgpLCB0cnVlKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEuc2hvdWxkLmRlZXBFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnTWVtbycsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtZW1vOiAnVGVzdCBkZWFjdGl2YXRlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ0RlYWN0aXZhdGUnLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgZnJvbUFkZHJlc3M6IHdhbGxldC5wdWIsXG4gICAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2VBY2NvdW50LnB1YixcbiAgICAgICAgICAgIGFtb3VudDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5zdGFraW5nQWRkcmVzczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgICAgICByZWNpcGllbnRzOiB1bmRlZmluZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgICAgc2hvdWxkLmVxdWFsKHJhd1R4LCB0ZXN0RGF0YS5TVEFLSU5HX0RFQUNUSVZBVEVfU0lHTkVEX1RYX1dJVEhfTUVNTyk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRpbmcgYSBzdGFraW5nIGRlYWN0aXZhdGUgdW5zaWduZWQgdHgnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcih3YWxsZXQucHViKS5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKS5ub25jZShyZWNlbnRCbG9ja0hhc2gpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbChVdGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHgpLCB0cnVlKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEuc2hvdWxkLmRlZXBFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBpc01hcmluYWRlOiBmYWxzZSxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgICBzaG91bGQuZXF1YWwocmF3VHgsIHRlc3REYXRhLlNUQUtJTkdfREVBQ1RJVkFURV9VTlNJR05FRF9UWCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRpbmcgYSBzdGFraW5nIGRlYWN0aXZhdGUgdW5zaWduZWQgdHggd2l0aCBtZW1vJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIod2FsbGV0LnB1Yikuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1Yikubm9uY2UocmVjZW50QmxvY2tIYXNoKS5tZW1vKCdUZXN0IGRlYWN0aXZhdGUnKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCByYXdUeCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBzaG91bGQuZXF1YWwoVXRpbHMuaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHJhd1R4KSwgdHJ1ZSk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHR4SnNvbi5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgbWVtbzogJ1Rlc3QgZGVhY3RpdmF0ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdEZWFjdGl2YXRlJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiB3YWxsZXQucHViLFxuICAgICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtlQWNjb3VudC5wdWIsXG4gICAgICAgICAgICBhbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVuc3Rha2luZ0FkZHJlc3M6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgICAgcmVjaXBpZW50czogdW5kZWZpbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdUeCwgdGVzdERhdGEuU1RBS0lOR19ERUFDVElWQVRFX1VOU0lHTkVEX1RYX1dJVEhfTUVNTyk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRpbmcgYW4gZW5jb2RlZCB1bnNpZ25lZCB0cmFuc2FjdGlvbiBhbmQgc2lnbmluZyBpdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbSh0ZXN0RGF0YS5TVEFLSU5HX0RFQUNUSVZBVEVfVU5TSUdORURfVFhfV0lUSF9NRU1PKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5TVEFLSU5HX0RFQUNUSVZBVEVfU0lHTkVEX1RYX1dJVEhfTUVNTyk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRpbmcgYW4gZW5jb2RlZCBzaWduZWQgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuU1RBS0lOR19ERUFDVElWQVRFX1NJR05FRF9UWF9XSVRIX01FTU8pO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHdhbGxldC5wcnYgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlNUQUtJTkdfREVBQ1RJVkFURV9TSUdORURfVFhfV0lUSF9NRU1PKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZGluZyBhIHBhcnRpYWwgc3Rha2luZyBkZWFjdGl2YXRlIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLnVuc3Rha2luZ0FkZHJlc3ModGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKVxuICAgICAgICAuYW1vdW50KCcxMDAwMDAnKVxuICAgICAgICAubm9uY2UocmVjZW50QmxvY2tIYXNoKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgcmF3VHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKFV0aWxzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUeCksIHRydWUpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEuc2hvdWxkLmRlZXBFcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnRGVhY3RpdmF0ZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBmcm9tQWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAwJyxcbiAgICAgICAgICAgIHVuc3Rha2luZ0FkZHJlc3M6IHRlc3REYXRhLnNwbGl0U3Rha2VBY2NvdW50LnB1YixcbiAgICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgICAgcmVjaXBpZW50czogdW5kZWZpbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdUeCwgdGVzdERhdGEuU1RBS0lOR19QQVJUSUFMX0RFQUNUSVZBVEVfU0lHTkVEX1RYKTtcblxuICAgICAgY29uc3QgdHgyID0gYXdhaXQgZmFjdG9yeS5mcm9tKHRlc3REYXRhLlNUQUtJTkdfUEFSVElBTF9ERUFDVElWQVRFX1NJR05FRF9UWCkuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbjIgPSB0eDIudG9Kc29uKCk7XG4gICAgICB0eDIudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgZGVsZXRlIHR4WydfaWQnXTtcbiAgICAgIGRlbGV0ZSB0eDJbJ19pZCddO1xuXG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LCB0eDIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLCB0eEpzb24yKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Nob3VsZCBmYWlsJywgKCkgPT4ge1xuICAgIGl0KCdidWlsZGluZyBhIHN0YWtpbmcgZGVhY3RpdmF0ZSB0eCB3aXRob3V0IHN0YWtpbmcgYWRkcmVzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKHdhbGxldC5wdWIpLm5vbmNlKHJlY2VudEJsb2NrSGFzaCk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogd2FsbGV0LnBydiB9KTtcbiAgICAgIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1N0YWtpbmcgYWRkcmVzcyBtdXN0IGJlIHNldCBiZWZvcmUgYnVpbGRpbmcgdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnYnVpbGRpbmcgYSBzdGFraW5nIGRlYWN0aXZhdGUgdHggd2l0aCBhIHdyb25nIHN0YWtpbmcgYWRkcmVzcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKHdhbGxldC5wdWIpLm5vbmNlKHJlY2VudEJsb2NrSGFzaCk7XG4gICAgICBzaG91bGQoKCkgPT4gdHhCdWlsZGVyLnN0YWtpbmdBZGRyZXNzKGludmFsaWRQdWJLZXkpKS50aHJvd0Vycm9yKFxuICAgICAgICBgSW52YWxpZCBvciBtaXNzaW5nIHN0YWtpbmdBZGRyZXNzLCBnb3Q6ICR7aW52YWxpZFB1YktleX1gXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2J1aWxkaW5nIGEgc3Rha2luZyBkZWFjdGl2YXRlIHR4IHdpdGggdGhlIHNhbWUgYWRkcmVzcyBhcyBzZW5kZXIgYW5kIHN0YWtpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcih3YWxsZXQucHViKS5ub25jZShyZWNlbnRCbG9ja0hhc2gpO1xuICAgICAgdHhCdWlsZGVyLnN0YWtpbmdBZGRyZXNzKHdhbGxldC5wdWIpO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkuc2hvdWxkLnJlamVjdGVkV2l0aCgnU2VuZGVyIGFkZHJlc3MgY2Fubm90IGJlIHRoZSBzYW1lIGFzIHRoZSBTdGFraW5nIGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZGluZyBhIHBhcnRpYWwgc3Rha2luZyBkZWFjdGl2YXRlIHR4IHdpdGhvdXQgYW4gYW1vdW50JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAubm9uY2UocmVjZW50QmxvY2tIYXNoKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3ModGVzdERhdGEuc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLnVuc3Rha2luZ0FkZHJlc3ModGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB3YWxsZXQucHJ2IH0pO1xuXG4gICAgICBhd2FpdCB0eEJ1aWxkZXJcbiAgICAgICAgLmJ1aWxkKClcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0lmIGFuIHVuc3Rha2luZyBhZGRyZXNzIGlzIGdpdmVuIHRoZW4gYSBwYXJ0aWFsIGFtb3VudCB0byB1bnN0YWtlIG11c3QgYWxzbyBiZSBzZXQgYmVmb3JlIGJ1aWxkaW5nIHRoZSB0cmFuc2FjdGlvbidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdidWlsZGluZyBhIHBhcnRpYWwgc3Rha2luZyBkZWFjdGl2YXRlIHR4IHdpdGhvdXQgYW4gdW5zdGFraW5nIGFkZHJlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRTdGFraW5nRGVhY3RpdmF0ZUJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShyZWNlbnRCbG9ja0hhc2gpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKVxuICAgICAgICAuYW1vdW50KCcxMCcpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHdhbGxldC5wcnYgfSk7XG5cbiAgICAgIGF3YWl0IHR4QnVpbGRlclxuICAgICAgICAuYnVpbGQoKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnV2hlbiBwYXJ0aWFsbHkgdW5zdGFraW5nIHRoZSB1bnN0YWtpbmcgYWRkcmVzcyBtdXN0IGJlIHNldCBiZWZvcmUgYnVpbGRpbmcgdGhlIHRyYW5zYWN0aW9uJ1xuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19

Выполнить команду


Для локальной разработки. Не используйте в интернете!