PHP WebShell

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

Просмотр файла: apt.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 });
require("should");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const src_1 = require("../../src");
const testData = __importStar(require("../resources/apt"));
const lodash_1 = __importDefault(require("lodash"));
const sinon_1 = __importDefault(require("sinon"));
const assert_1 = __importDefault(require("assert"));
const ts_sdk_1 = require("@aptos-labs/ts-sdk");
const utils_1 = __importDefault(require("../../src/lib/utils"));
const statics_1 = require("@bitgo/statics");
describe('APT:', function () {
    let bitgo;
    let basecoin;
    let newTxPrebuild;
    let newTxParams;
    const txPreBuild = {
        txHex: testData.TRANSACTION_USING_TRANSFER_COINS,
        txInfo: {},
    };
    const txParams = {
        recipients: testData.recipients,
    };
    const batchFungibleTxPrebuild = {
        txHex: testData.FUNGIBLE_BATCH_RAW_TX_HEX,
        txInfo: {},
    };
    const batchFungibleTxParams = {
        recipients: testData.batchFungibleRecipients,
        type: 'transfer',
    };
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
        bitgo.safeRegister('apt', src_1.Apt.createInstance);
        bitgo.safeRegister('tapt', src_1.Tapt.createInstance);
        bitgo.safeRegister('apt:usdt', src_1.AptToken.createInstance);
        bitgo.initializeTestVars();
        basecoin = bitgo.coin('tapt');
        newTxPrebuild = () => {
            return lodash_1.default.cloneDeep(txPreBuild);
        };
        newTxParams = () => {
            return lodash_1.default.cloneDeep(txParams);
        };
    });
    it('should return the right info', function () {
        const apt = bitgo.coin('apt');
        const tapt = bitgo.coin('tapt');
        const aptUsdt = bitgo.coin('apt:usdt');
        const aptStatics = statics_1.coins.get('apt');
        const taptStatics = statics_1.coins.get('tapt');
        apt.getChain().should.equal('apt');
        apt.getFamily().should.equal('apt');
        apt.getFullName().should.equal('Aptos');
        apt.getBaseFactor().should.equal(1e8);
        tapt.getChain().should.equal('tapt');
        tapt.getFamily().should.equal('apt');
        tapt.getFullName().should.equal('Testnet Aptos');
        tapt.getBaseFactor().should.equal(1e8);
        aptStatics.gasTankLowBalanceAlertFactor.should.equal(80);
        taptStatics.gasTankLowBalanceAlertFactor.should.equal(80);
        aptStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
        taptStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
        aptUsdt.getFamily().should.equal('apt');
        aptUsdt.getChain().should.equal('apt');
        const aptUsdtStatics = aptUsdt.getConfig();
        aptUsdtStatics.fullName.should.equal('USD Tether');
        aptUsdtStatics.assetId.should.equal('0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b');
        aptUsdtStatics.decimalPlaces.should.equal(6);
    });
    it('is valid pub', function () {
        // with 0x prefix
        basecoin.isValidPub('0x9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(false);
        // without 0x prefix
        basecoin.isValidPub('9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(true);
    });
    describe('Verify transaction: ', () => {
        it('should succeed to verify transaction', async function () {
            const txPrebuild = newTxPrebuild();
            const txParams = newTxParams();
            const verification = {};
            const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
            isTransactionVerified.should.equal(true);
        });
        it('should succeed to verify fungible transaction', async function () {
            const verification = {};
            const isTransactionVerified = await basecoin.verifyTransaction({
                txPrebuild: batchFungibleTxPrebuild,
                txParams: batchFungibleTxParams,
                verification,
            });
            isTransactionVerified.should.equal(true);
        });
        it('should succeed to verify transaction when recipients amount are numbers', async function () {
            const txPrebuild = newTxPrebuild();
            const txParamsWithNumberAmounts = newTxParams();
            txParamsWithNumberAmounts.recipients = txParamsWithNumberAmounts.recipients.map(({ address, amount }) => {
                return { address, amount: Number(amount) };
            });
            const verification = {};
            const isTransactionVerified = await basecoin.verifyTransaction({
                txParams: txParamsWithNumberAmounts,
                txPrebuild,
                verification,
            });
            isTransactionVerified.should.equal(true);
        });
        it('should fail to verify transaction with invalid param', async function () {
            const txPrebuild = {};
            const txParams = newTxParams();
            txParams.recipients = undefined;
            await basecoin
                .verifyTransaction({
                txParams,
                txPrebuild,
            })
                .should.rejectedWith('missing required tx prebuild property txHex');
        });
    });
    describe('Parse and Explain Transactions: ', () => {
        const transferInputsResponse = [
            {
                address: testData.sender2.address,
                amount: testData.AMOUNT.toString(),
            },
        ];
        const transferOutputsResponse = [
            {
                address: testData.recipients[0].address,
                amount: testData.recipients[0].amount,
            },
        ];
        const transferFungibleInputResponse = [
            {
                address: testData.fungibleSender.address,
                amount: testData.FUNGIBLE_TOKEN_AMOUNT.toString(),
            },
        ];
        const tranferFungibleOutputResponse = [
            {
                address: testData.fungibleTokenRecipients[1].address,
                amount: testData.fungibleTokenRecipients[1].amount,
            },
        ];
        it('should parse a transfer transaction', async function () {
            const parsedTransaction = await basecoin.parseTransaction({
                txHex: testData.TRANSACTION_USING_TRANSFER_COINS,
            });
            parsedTransaction.should.deepEqual({
                inputs: transferInputsResponse,
                outputs: transferOutputsResponse,
            });
        });
        it('should parse signed fungible transaction, only work if amount parsing correctly done from payload', async function () {
            const parsedTransaction = await basecoin.parseTransaction({
                txHex: testData.FUNGIBLE_SERIALIZED_TX_HEX,
            });
            parsedTransaction.should.deepEqual({
                inputs: transferFungibleInputResponse,
                outputs: tranferFungibleOutputResponse,
            });
        });
        it('should explain a transfer transaction', async function () {
            const rawTx = newTxPrebuild().txHex;
            const transaction = new src_1.TransferTransaction(statics_1.coins.get('tapt'));
            transaction.fromRawTransaction(rawTx);
            const explainedTx = transaction.explainTransaction();
            console.log(explainedTx);
            explainedTx.should.deepEqual({
                displayOrder: [
                    'id',
                    'outputs',
                    'outputAmount',
                    'changeOutputs',
                    'changeAmount',
                    'fee',
                    'withdrawAmount',
                    'sender',
                    'type',
                ],
                id: '0x249289a8178e4b9cdb89fad6e8e436ccc435753e4ea3c9d50e0c8b525582e90d',
                outputs: [
                    {
                        address: '0xf7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad9',
                        amount: '1000',
                    },
                ],
                outputAmount: '1000',
                changeOutputs: [],
                changeAmount: '0',
                fee: { fee: '0' },
                sender: '0x1aed808916ab9b1b30b07abb53561afd46847285ce28651221d406173a372449',
                type: 0,
            });
        });
        it('should fail to explain a invalid raw transaction', async function () {
            const rawTx = 'invalidRawTransaction';
            const transaction = new src_1.TransferTransaction(statics_1.coins.get('tapt'));
            await assert_1.default.rejects(async () => transaction.fromRawTransaction(rawTx), {
                message: 'invalid raw transaction',
            });
        });
        it('should fail to parse a transfer transaction when explainTransaction response is undefined', async function () {
            const stub = sinon_1.default.stub(src_1.Apt.prototype, 'explainTransaction');
            stub.resolves(undefined);
            await basecoin.parseTransaction({ txHex: testData.TRANSFER }).should.be.rejectedWith('Invalid transaction');
            stub.restore();
        });
    });
    describe('Address Validation', () => {
        let keychains;
        let commonKeychain;
        before(function () {
            commonKeychain =
                '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
            keychains = [
                {
                    id: '6424c353eaf78d000766e95949868468',
                    source: 'user',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    encryptedPrv: '{"iv":"cZd5i7L4RxtwrALW2rK7UA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"5zgoH1Bd3Fw=","ct":"9vVlnXFRtrM9FVEo+d2chbGHlM9lFZemueBuAs3BIkPo33Fo7jzwwNK/kIWkEyg+NmEBd5IaqAS157nvvvwzzsmMWlQdUz9qbmXNv3pg987cXFR08exS+4uhwP1YNOjJTRvRNcO9ZqHb46d4fmyJ/yC9/susCge7r/EsbaN5C3afv1dzybuq912FwaQElZLYYp5BICudFOMZ9k0UDMfKM/PMDkH7WexoGHr9GKq/bgCH2B39TZZyHKU6Uy47lXep2s6h0DrMwHOrnmiL3DZjOj88Ynvphlzxuo4eOlD2UHia2+nvIaISYs29Pr0DAvREutchvcBpExj1kWWPv7hQYrv8F0NAdatsbWl3w+xKyfiMKo1USlrwyJviypGtQtXOJyw0XPN0rv2+L5lW8BbjpzHfYYN13fJTedlGTFhhkzVtbbPAKE02kx7zCJcjYaiexdSTsrDLScYNT9/Jhdt27KpsooehwVohLfSKz4vbFfRu2MPZw3/+c/hfiJNgtz6esWbnxGrcE8U2IwPYCaK+Ghk4DcqWNIni59RI5B5kAsQOToII40qPN510uTgxBSPO7q7MHgkxdd4CqBq+ojr9j0P7oao8E5Y+CBDJrojDoCh1oCCDW9vo2dXlVcD8SIbw7U/9AfvEbA4xyE/5md1M7CIwLnWs2Ynv0YtaKoqhdS9x6FmHlMDhN/DKHinrwmowtrTT82fOkpO5g9saSmgU7Qy3gLt8t+VwdEyeFeQUKRSyci8qgqXQaZIg4+aXgaSOnlCFMtmB8ekYxEhTY5uzRfrNgS4s1QeqFBpNtUF+Ydi297pbVXnJoXAN+SVWd80GCx+yI2dpVC89k3rOWK9WeyqlnzuLJWp2RIOB9cdW8GFv/fN+QAJpYeVxOE4+nZDsKnsj8nKcg9t4Dlx1G6gLM1/Vq9YxNLbuzuRC0asUYvdMnoMvszmpm++TxndYisgNYscpZSoz7wvcazJNEPfhPVjEkd6tUUuN4GM35H0DmKCUQNT+a6B6hmHlTZvjxiyGAg5bY59hdjvJ+22QduazlEEC6LI3HrA7uK0TpplWzS1tCIFvTMUhj65DEZmNJ2+ZY9bQ4vsMf+DRR3OOG4t+DMlNfjOd3zNv3QoY95BjfWpryFwPzDq7bCP67JDsoj7j2TY5FRSrRkD77H0Ewlux2cWfjRTwcMHcdQxxuV0OP0aNjGDjybFN"}',
                },
                {
                    id: '6424c353eaf78d000766e96137d4404b',
                    source: 'backup',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    encryptedPrv: '{"iv":"vi0dPef/Rx7kG/pRySQi6Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"9efhQsiEvVs=","ct":"Gw6atvf6gxKzsjtl3xseipO3rAxp1mAz7Yu1ihFsi5/lf2vMZegApgZx+pyILFS9KKLHbNF3U6WgSYdrr2t4vzdLsXkH1WIxfHS+cd2C5N59yADZDnPJBT6pv/IRvaYelP0Ck3nIYQ2hSMm8op+VOWC/SzHeh7slYDqwEHTGan0Wigfvk1yRd7CCJTaEAomnc/4eFi2NY3X3gt/3opy9IAgknnwUFohn96EWpEQ0F6pbzH/Z8VF6gF+DUcrrByAxExUPnHQZiFk3YHU/vVV4FxBU/mVAE8xBsBn5ul5e5SUMPfc7TBuJWv4BByTNg9xDShF/91Yx2nbfUm5d9QmM8lpKgzzQvcK8POAPk87gRCuKnsGh5vNS0UppkHc+ocfzRQlGA6jze7QyyQO0rMj5Ly8kWjwk2vISvKYHYS1NR7VU549UIXo7NXjatunKSc3+IreoRUHIshiaLg6hl+pxCCuc0qQ43V0mdIfCjTN8gkGWLNk8R7tAGPz9jyapQPcPEGHgEz0ATIi6yMNWCsibS2eLiE1uVEJONoM4lk6FPl3Q2CHbW2MeEbqjY8hbaw18mNb2xSBH/Fwpiial+Tvi2imqgnCO4ZpO9bllKftZPcQy0stN+eGBlb5ufyflKkDSiChHYroGjEpmiFicdde48cJszF52uKNnf1q67fA9/S2FAHQab3EXojxH2Gbk+kkV2h/TYKFFZSWC3vi4e8mO+vjMUcR0AdsgPFyEIz0SCGuba3CnTLNdEuZwsauAeHkx2vUTnRgJPVgNeeuXmsVG76Sy2ggJHuals0Hj8U2Xda0qO1RuFfoCWfss9wn6HGRwPPkhSB/8oNguAqmRVGKkd8Zwt3IvrTd9fk0/rFFDJKGz7WyNHkYgUmNiGcItD12v0jx7FZ52EJzl3Av1RyJUQK18+8EYPh3SGiU9dt7VX0aF0uo6JouKhOeldUvMP+AugQz8fUclwTQsbboVg27Yxo0DyATVwThW5a56R6Qf5ZiQJluFuzs5y98rq0S5q046lE6o3vVmJpEdwjeSCJoET5CL4nTgkXyWvhm4eB8u/e66l3o0qbaSx8q9YYmT9EpRcl5TP4ThLBKETYdzVvg4exjQfektMatk5EyUpEIhZPXh5vXpJZesdfO9LJ8zTaHBsBjDPU7cdNgQMbebpataRi8A0el2/IJXl+E+olgAz5zC4i2O1Q=="}',
                },
                {
                    id: '6424c353eaf78d000766e9510b125fba',
                    source: 'bitgo',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    verifiedVssProof: true,
                    isBitGo: true,
                },
            ];
        });
        it('should return true when validating a well formatted address prefixed with 0x', async function () {
            const address = '0xf941ae3cbe5645dccc15da8346b533f7f91f202089a5521653c062b2ff10b304';
            basecoin.isValidAddress(address).should.equal(true);
        });
        it('should return false when validating an old address', async function () {
            const address = '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59';
            basecoin.isValidAddress(address).should.equal(false);
        });
        it('should return false when validating an incorrectly formatted', async function () {
            const address = 'wrongaddress';
            basecoin.isValidAddress(address).should.equal(false);
        });
        it('should return true for isWalletAddress with valid address for index 4', async function () {
            const newAddress = '0x8b3c7807730d75792dd6c49732cf9f014d6984a9c77d386bdb1072a9e537d8d8';
            const index = 4;
            const params = { commonKeychain, address: newAddress, index, keychains };
            (await basecoin.isWalletAddress(params)).should.equal(true);
        });
        it('should throw error for isWalletAddress when keychains is missing', async function () {
            const address = '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59';
            const index = 0;
            const params = { commonKeychain, address, index };
            await assert_1.default.rejects(async () => basecoin.isWalletAddress(params));
        });
        it('should throw error for isWalletAddress when new address is invalid', async function () {
            const wrongAddress = 'badAddress';
            const index = 0;
            const params = { commonKeychain, address: wrongAddress, index };
            await assert_1.default.rejects(async () => basecoin.isWalletAddress(params), {
                message: `invalid address: ${wrongAddress}`,
            });
        });
    });
    describe('ID Validation', () => {
        it('check id', async function () {
            const network = ts_sdk_1.Network.TESTNET;
            const aptos = new ts_sdk_1.Aptos(new ts_sdk_1.AptosConfig({ network }));
            const senderAddress = ts_sdk_1.AccountAddress.fromString('0xc8f02d25aa698b3e9fbd8a08e8da4c8ee261832a25a4cde8731b5ec356537d09');
            const recipientAddress = ts_sdk_1.AccountAddress.fromString('0xf7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad9');
            const transaction = await aptos.transaction.build.simple({
                sender: senderAddress,
                data: {
                    function: '0x1::coin::transfer',
                    typeArguments: [ts_sdk_1.APTOS_COIN],
                    functionArguments: [recipientAddress, 1000],
                },
                options: {
                    maxGasAmount: 200000,
                    gasUnitPrice: 100,
                    expireTimestamp: 1732699236,
                    accountSequenceNumber: 14,
                },
            });
            const DEFAULT_PUBLIC_KEY = Buffer.alloc(32);
            const DEFAULT_SIGNATURE = Buffer.alloc(64);
            const publicKey = new ts_sdk_1.Ed25519PublicKey(utils_1.default.getBufferFromHexString(DEFAULT_PUBLIC_KEY.toString('hex')));
            const signature = new ts_sdk_1.Ed25519Signature(DEFAULT_SIGNATURE);
            const senderAuthenticator = new ts_sdk_1.AccountAuthenticatorEd25519(publicKey, signature);
            const id = (0, ts_sdk_1.generateUserTransactionHash)({ transaction, senderAuthenticator });
            id.should.equal('0x923d1cfed3afac24048451160337db75ba282912157ee43407b572923801d5ba');
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2FwdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGtCQUFnQjtBQUNoQiw4Q0FBMEQ7QUFDMUQsNENBQTBDO0FBQzFDLG1DQUFxRTtBQUNyRSwyREFBNkM7QUFDN0Msb0RBQXVCO0FBQ3ZCLGtEQUEwQjtBQUMxQixvREFBNEI7QUFDNUIsK0NBVTRCO0FBQzVCLGdFQUF3QztBQUN4Qyw0Q0FBb0U7QUFFcEUsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksYUFBYSxDQUFDO0lBQ2xCLElBQUksV0FBVyxDQUFDO0lBRWhCLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLEtBQUssRUFBRSxRQUFRLENBQUMsZ0NBQWdDO1FBQ2hELE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQztJQUVGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVO0tBQ2hDLENBQUM7SUFFRixNQUFNLHVCQUF1QixHQUFHO1FBQzlCLEtBQUssRUFBRSxRQUFRLENBQUMseUJBQXlCO1FBQ3pDLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQztJQUVGLE1BQU0scUJBQXFCLEdBQUc7UUFDNUIsVUFBVSxFQUFFLFFBQVEsQ0FBQyx1QkFBdUI7UUFDNUMsSUFBSSxFQUFFLFVBQVU7S0FDakIsQ0FBQztJQUVGLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMs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QUUsQ0FBQyxDQUFDO1lBRTdFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7UUFDeEYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBBcHQsIEFwdFRva2VuLCBUYXB0LCBUcmFuc2ZlclRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL3Jlc291cmNlcy9hcHQnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQge1xuICBBY2NvdW50QWRkcmVzcyxcbiAgQWNjb3VudEF1dGhlbnRpY2F0b3JFZDI1NTE5LFxuICBBcHRvcyxcbiAgQVBUT1NfQ09JTixcbiAgQXB0b3NDb25maWcsXG4gIEVkMjU1MTlQdWJsaWNLZXksXG4gIEVkMjU1MTlTaWduYXR1cmUsXG4gIGdlbmVyYXRlVXNlclRyYW5zYWN0aW9uSGFzaCxcbiAgTmV0d29yayxcbn0gZnJvbSAnQGFwdG9zLWxhYnMvdHMtc2RrJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi8uLi9zcmMvbGliL3V0aWxzJztcbmltcG9ydCB7IEFwdENvaW4sIGNvaW5zLCBHYXNUYW5rQWNjb3VudENvaW4gfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5cbmRlc2NyaWJlKCdBUFQ6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQgbmV3VHhQcmVidWlsZDtcbiAgbGV0IG5ld1R4UGFyYW1zO1xuXG4gIGNvbnN0IHR4UHJlQnVpbGQgPSB7XG4gICAgdHhIZXg6IHRlc3REYXRhLlRSQU5TQUNUSU9OX1VTSU5HX1RSQU5TRkVSX0NPSU5TLFxuICAgIHR4SW5mbzoge30sXG4gIH07XG5cbiAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgcmVjaXBpZW50czogdGVzdERhdGEucmVjaXBpZW50cyxcbiAgfTtcblxuICBjb25zdCBiYXRjaEZ1bmdpYmxlVHhQcmVidWlsZCA9IHtcbiAgICB0eEhleDogdGVzdERhdGEuRlVOR0lCTEVfQkFUQ0hfUkFXX1RYX0hFWCxcbiAgICB0eEluZm86IHt9LFxuICB9O1xuXG4gIGNvbnN0IGJhdGNoRnVuZ2libGVUeFBhcmFtcyA9IHtcbiAgICByZWNpcGllbnRzOiB0ZXN0RGF0YS5iYXRjaEZ1bmdpYmxlUmVjaXBpZW50cyxcbiAgICB0eXBlOiAndHJhbnNmZXInLFxuICB9O1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdhcHQnLCBBcHQuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGFwdCcsIFRhcHQuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignYXB0OnVzZHQnLCBBcHRUb2tlbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YXB0Jyk7XG4gICAgbmV3VHhQcmVidWlsZCA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFByZUJ1aWxkKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UGFyYW1zKTtcbiAgICB9O1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJldHVybiB0aGUgcmlnaHQgaW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhcHQgPSBiaXRnby5jb2luKCdhcHQnKTtcbiAgICBjb25zdCB0YXB0ID0gYml0Z28uY29pbigndGFwdCcpO1xuICAgIGNvbnN0IGFwdFVzZHQgPSBiaXRnby5jb2luKCdhcHQ6dXNkdCcpO1xuICAgIGNvbnN0IGFwdFN0YXRpY3MgPSBjb2lucy5nZXQoJ2FwdCcpIGFzIEdhc1RhbmtBY2NvdW50Q29pbjtcbiAgICBjb25zdCB0YXB0U3RhdGljcyA9IGNvaW5zLmdldCgndGFwdCcpIGFzIEdhc1RhbmtBY2NvdW50Q29pbjtcblxuICAgIGFwdC5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgnYXB0Jyk7XG4gICAgYXB0LmdldEZhbWlseSgpLnNob3VsZC5lcXVhbCgnYXB0Jyk7XG4gICAgYXB0LmdldEZ1bGxOYW1lKCkuc2hvdWxkLmVxdWFsKCdBcHRvcycpO1xuICAgIGFwdC5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlOCk7XG5cbiAgICB0YXB0LmdldENoYWluKCkuc2hvdWxkLmVxdWFsKCd0YXB0Jyk7XG4gICAgdGFwdC5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ2FwdCcpO1xuICAgIHRhcHQuZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1Rlc3RuZXQgQXB0b3MnKTtcbiAgICB0YXB0LmdldEJhc2VGYWN0b3IoKS5zaG91bGQuZXF1YWwoMWU4KTtcblxuICAgIGFwdFN0YXRpY3MuZ2FzVGFua0xvd0JhbGFuY2VBbGVydEZhY3Rvci5zaG91bGQuZXF1YWwoODApO1xuICAgIHRhcHRTdGF0aWNzLmdhc1RhbmtMb3dCYWxhbmNlQWxlcnRGYWN0b3Iuc2hvdWxkLmVxdWFsKDgwKTtcbiAgICBhcHRTdGF0aWNzLmdhc1RhbmtNaW5CYWxhbmNlUmVjb21tZW5kYXRpb25GYWN0b3Iuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgdGFwdFN0YXRpY3MuZ2FzVGFua01pbkJhbGFuY2VSZWNvbW1lbmRhdGlvbkZhY3Rvci5zaG91bGQuZXF1YWwoMjAwKTtcblxuICAgIGFwdFVzZHQuZ2V0RmFtaWx5KCkuc2hvdWxkLmVxdWFsKCdhcHQnKTtcbiAgICBhcHRVc2R0LmdldENoYWluKCkuc2hvdWxkLmVxdWFsKCdhcHQnKTtcbiAgICBjb25zdCBhcHRVc2R0U3RhdGljcyA9IGFwdFVzZHQuZ2V0Q29uZmlnKCkgYXMgQXB0Q29pbjtcbiAgICBhcHRVc2R0U3RhdGljcy5mdWxsTmFtZS5zaG91bGQuZXF1YWwoJ1VTRCBUZXRoZXInKTtcbiAgICBhcHRVc2R0U3RhdGljcy5hc3NldElkLnNob3VsZC5lcXVhbCgnMHgzNTdiMGI3NGJjODMzZTk1YTExNWFkMjI2MDQ4NTRkNmIwZmNhMTUxY2VjZDk0MTExNzcwZTVkNmZmYzlkYzJiJyk7XG4gICAgYXB0VXNkdFN0YXRpY3MuZGVjaW1hbFBsYWNlcy5zaG91bGQuZXF1YWwoNik7XG4gIH0pO1xuXG4gIGl0KCdpcyB2YWxpZCBwdWInLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gd2l0aCAweCBwcmVmaXhcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHViKCcweDliNGU5NjA4NmQxMTE1MDAyNTlmOWIzODY4MGIwNTA5YTQwNWMxOTA0ZGExODk3NjQ1NWEyMGM2OTFkM2JiMDcnKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIC8vIHdpdGhvdXQgMHggcHJlZml4XG4gICAgYmFzZWNvaW4uaXNWYWxpZFB1YignOWI0ZTk2MDg2ZDExMTUwMDI1OWY5YjM4NjgwYjA1MDlhNDA1YzE5MDRkYTE4OTc2NDU1YTIwYzY5MWQzYmIwNycpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0cmFuc2FjdGlvbjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSBmdW5naWJsZSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiBiYXRjaEZ1bmdpYmxlVHhQcmVidWlsZCxcbiAgICAgICAgdHhQYXJhbXM6IGJhdGNoRnVuZ2libGVUeFBhcmFtcyxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aGVuIHJlY2lwaWVudHMgYW1vdW50IGFyZSBudW1iZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zV2l0aE51bWJlckFtb3VudHMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzID0gdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzLm1hcCgoeyBhZGRyZXNzLCBhbW91bnQgfSkgPT4ge1xuICAgICAgICByZXR1cm4geyBhZGRyZXNzLCBhbW91bnQ6IE51bWJlcihhbW91bnQpIH07XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aXRoIGludmFsaWQgcGFyYW0nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge307XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gdW5kZWZpbmVkO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCB0eCBwcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGFyc2UgYW5kIEV4cGxhaW4gVHJhbnNhY3Rpb25zOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNmZXJJbnB1dHNSZXNwb25zZSA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyMi5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IHRlc3REYXRhLkFNT1VOVC50b1N0cmluZygpLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgY29uc3QgdHJhbnNmZXJPdXRwdXRzUmVzcG9uc2UgPSBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJlY2lwaWVudHNbMF0uYWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiB0ZXN0RGF0YS5yZWNpcGllbnRzWzBdLmFtb3VudCxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IHRyYW5zZmVyRnVuZ2libGVJbnB1dFJlc3BvbnNlID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5mdW5naWJsZVNlbmRlci5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX0FNT1VOVC50b1N0cmluZygpLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgY29uc3QgdHJhbmZlckZ1bmdpYmxlT3V0cHV0UmVzcG9uc2UgPSBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLmZ1bmdpYmxlVG9rZW5SZWNpcGllbnRzWzFdLmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogdGVzdERhdGEuZnVuZ2libGVUb2tlblJlY2lwaWVudHNbMV0uYW1vdW50LFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5wYXJzZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IHRlc3REYXRhLlRSQU5TQUNUSU9OX1VTSU5HX1RSQU5TRkVSX0NPSU5TLFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IHRyYW5zZmVySW5wdXRzUmVzcG9uc2UsXG4gICAgICAgIG91dHB1dHM6IHRyYW5zZmVyT3V0cHV0c1Jlc3BvbnNlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIHNpZ25lZCBmdW5naWJsZSB0cmFuc2FjdGlvbiwgb25seSB3b3JrIGlmIGFtb3VudCBwYXJzaW5nIGNvcnJlY3RseSBkb25lIGZyb20gcGF5bG9hZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiB0ZXN0RGF0YS5GVU5HSUJMRV9TRVJJQUxJWkVEX1RYX0hFWCxcbiAgICAgIH0pO1xuXG4gICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgaW5wdXRzOiB0cmFuc2ZlckZ1bmdpYmxlSW5wdXRSZXNwb25zZSxcbiAgICAgICAgb3V0cHV0czogdHJhbmZlckZ1bmdpYmxlT3V0cHV0UmVzcG9uc2UsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSBuZXdUeFByZWJ1aWxkKCkudHhIZXg7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2ZlclRyYW5zYWN0aW9uKGNvaW5zLmdldCgndGFwdCcpKTtcbiAgICAgIHRyYW5zYWN0aW9uLmZyb21SYXdUcmFuc2FjdGlvbihyYXdUeCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUeCA9IHRyYW5zYWN0aW9uLmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgY29uc29sZS5sb2coZXhwbGFpbmVkVHgpO1xuICAgICAgZXhwbGFpbmVkVHguc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnd2l0aGRyYXdBbW91bnQnLFxuICAgICAgICAgICdzZW5kZXInLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICcweDI0OTI4OWE4MTc4ZTRiOWNkYjg5ZmFkNmU4ZTQzNmNjYzQzNTc1M2U0ZWEzYzlkNTBlMGM4YjUyNTU4MmU5MGQnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4Zjc0MDVjMjhhMDJjZjViYWI0ZWE0NDk4MjQwYmIzNTc5ZGI0NTk1MTc5NGViMWM4NDNiZWYwNTM0YzA5M2FkOScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnMCcgfSxcbiAgICAgICAgc2VuZGVyOiAnMHgxYWVkODA4OTE2YWI5YjFiMzBiMDdhYmI1MzU2MWFmZDQ2ODQ3Mjg1Y2UyODY1MTIyMWQ0MDYxNzNhMzcyNDQ5JyxcbiAgICAgICAgdHlwZTogMCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gYSBpbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gJ2ludmFsaWRSYXdUcmFuc2FjdGlvbic7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2ZlclRyYW5zYWN0aW9uKGNvaW5zLmdldCgndGFwdCcpKTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IHRyYW5zYWN0aW9uLmZyb21SYXdUcmFuc2FjdGlvbihyYXdUeCksIHtcbiAgICAgICAgbWVzc2FnZTogJ2ludmFsaWQgcmF3IHRyYW5zYWN0aW9uJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHBhcnNlIGEgdHJhbnNmZXIgdHJhbnNhY3Rpb24gd2hlbiBleHBsYWluVHJhbnNhY3Rpb24gcmVzcG9uc2UgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YiA9IHNpbm9uLnN0dWIoQXB0LnByb3RvdHlwZSwgJ2V4cGxhaW5UcmFuc2FjdGlvbicpO1xuICAgICAgc3R1Yi5yZXNvbHZlcyh1bmRlZmluZWQpO1xuICAgICAgYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7IHR4SGV4OiB0ZXN0RGF0YS5UUkFOU0ZFUiB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgICBzdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZHJlc3MgVmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBsZXQga2V5Y2hhaW5zO1xuICAgIGxldCBjb21tb25LZXljaGFpbjtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICcxOWJkZmUyYTRiNDk4YTA1NTExMzgxMjM1YTg4OTJkNTQyNjc4MDdjNGEzZjY1NGUzMTBiOTM4YjhiNDI0ZmY0YWRlZGJlOTJmNGMxNDZkZTY0MWM2NzUwOGE5NjEzMjRjODUwNGNkZjhlMGMwYWNiYjY4ZDYxMDRjY2NjZDc4MSc7XG4gICAgICBrZXljaGFpbnMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzY0MjRjMzUzZWFmNzhkMDAwNzY2ZTk1OTQ5ODY4NDY4JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICcxOWJkZmUyYTRiNDk4YTA1NTExMzgxMjM1YTg4OTJkNTQyNjc4MDdjNGEzZjY1NGUzMTBiOTM4YjhiNDI0ZmY0YWRlZGJlOTJmNGMxNDZkZTY0MWM2NzUwOGE5NjEzMjRjODUwNGNkZjhlMGMwYWNiYjY4ZDYxMDRjY2NjZDc4MScsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJjWmQ1aTdMNFJ4dHdyQUxXMnJLN1VBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiNXpnb0gxQmQzRnc9XCIsXCJjdFwiOlwiOXZWbG5YRlJ0ck05RlZFbytkMmNoYkdIbE05bEZaZW11ZUJ1QXMzQklrUG8zM0ZvN2p6d3dOSy9rSVdrRXlnK05tRUJkNUlhcUFTMTU3bnZ2dnd6enNtTVdsUWRVejlxYm1YTnYzcGc5ODdjWEZSMDhleFMrNHVod1AxWU5PakpUUnZSTmNPOVpxSGI0NmQ0Zm15Si95Qzkvc3VzQ2dlN3IvRXNiYU41QzNhZnYxZHp5YnVxOTEyRndhUUVsWkxZWXA1QklDdWRGT01aOWswVURNZktNL1BNRGtIN1dleG9HSHI5R0txL2JnQ0gyQjM5VFpaeUhLVTZVeTQ3bFhlcDJzNmgwRHJNd0hPcm5taUwzRFpqT2o4OFludnBobHp4dW80ZU9sRDJVSGlhMitudklhSVNZczI5UHIwREF2UkV1dGNodmNCcEV4ajFrV1dQdjdoUVlydjhGME5BZGF0c2JXbDN3K3hLeWZpTUtvMVVTbHJ3eUp2aXlwR3RRdFhPSnl3MFhQTjBydjIrTDVsVzhCYmpwekhmWVlOMTNmSlRlZGxHVEZoaGt6VnRiYlBBS0UwMmt4N3pDSmNqWWFpZXhkU1RzckRMU2NZTlQ5L0poZHQyN0twc29vZWh3Vm9oTGZTS3o0dmJGZlJ1Mk1QWnczLytjL2hmaUpOZ3R6NmVzV2JueEdyY0U4VTJJd1BZQ2FLK0doazREY3FXTkluaTU5Ukk1QjVrQXNRT1RvSUk0MHFQTjUxMHVUZ3hCU1BPN3E3TUhna3hkZDRDcUJxK29qcjlqMFA3b2FvOEU1WStDQkRKcm9qRG9DaDFvQ0NEVzl2bzJkWGxWY0Q4U0lidzdVLzlBZnZFYkE0eHlFLzVtZDFNN0NJd0xuV3MyWW52MFl0YUtvcWhkUzl4NkZtSGxNRGhOL0RLSGlucndtb3d0clRUODJmT2twTzVnOXNhU21nVTdReTNnTHQ4dCtWd2RFeWVGZVFVS1JTeWNpOHFncVhRYVpJZzQrYVhnYVNPbmxDRk10bUI4ZWtZeEVoVFk1dXpSZnJOZ1M0czFRZXFGQnBOdFVGK1lkaTI5N3BiVlhuSm9YQU4rU1ZXZDgwR0N4K3lJMmRwVkM4OWszck9XSzlXZXlxbG56dUxKV3AyUklPQjljZFc4R0Z2L2ZOK1FBSnBZZVZ4T0U0K25aRHNLbnNqOG5LY2c5dDREbHgxRzZnTE0xL1ZxOVl4TkxidXp1UkMwYXNVWXZkTW5vTXZzem1wbSsrVHhuZFlpc2dOWXNjcFpTb3o3d3ZjYXpKTkVQZmhQVmpFa2Q2dFVVdU40R00zNUgwRG1LQ1VRTlQrYTZCNmhtSGxUWnZqeGl5R0FnNWJZNTloZGp2SisyMlFkdWF6bEVFQzZMSTNIckE3dUswVHBwbFd6UzF0Q0lGdlRNVWhqNjVERVptTkoyK1pZOWJRNHZzTWYrRFJSM09PRzR0K0RNbE5mak9kM3pOdjNRb1k5NUJqZldwcnlGd1B6RHE3YkNQNjdKRHNvajdqMlRZNUZSU3JSa0Q3N0gwRXdsdXgyY1dmalJUd2NNSGNkUXh4dVYwT1AwYU5qR0RqeWJGTlwifScsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzY0MjRjMzUzZWFmNzhkMDAwNzY2ZTk2MTM3ZDQ0MDRiJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAne1wiaXZcIjpcInZpMGRQZWYvUng3a0cvcFJ5U1FpNlE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCI5ZWZoUXNpRXZWcz1cIixcImN0XCI6XCJHdzZhdHZmNmd4S3pzanRsM3hzZWlwTzNyQXhwMW1BejdZdTFpaEZzaTUvbGYydk1aZWdBcGdaeCtweUlMRlM5S0tMSGJORjNVNldnU1lkcnIydDR2emRMc1hrSDFXSXhmSFMrY2QyQzVONTl5QURaRG5QSkJUNnB2L0lSdmFZZWxQMENrM25JWVEyaFNNbThvcCtWT1dDL1N6SGVoN3NsWURxd0VIVEdhbjBXaWdmdmsxeVJkN0NDSlRhRUFvbW5jLzRlRmkyTlkzWDNndC8zb3B5OUlBZ2tubndVRm9objk2RVdwRVEwRjZwYnpIL1o4VkY2Z0YrRFVjcnJCeUF4RXhVUG5IUVppRmszWUhVL3ZWVjRGeEJVL21WQUU4eEJzQm41dWw1ZTVTVU1QZmM3VEJ1Sld2NEJCeVROZzl4RFNoRi85MVl4Mm5iZlVtNWQ5UW1NOGxwS2d6elF2Y0s4UE9BUGs4N2dSQ3VLbnNHaDV2TlMwVXBwa0hjK29jZnpSUWxHQTZqemU3UXl5UU8wck1qNUx5OGtXandrMnZJU3ZLWUhZUzFOUjdWVTU0OVVJWG83TlhqYXR1bktTYzMrSXJlb1JVSElzaGlhTGc2aGwrcHhDQ3VjMHFRNDNWMG1kSWZDalROOGdrR1dMTms4Ujd0QUdQejlqeWFwUVBjUEVHSGdFejBBVElpNnlNTldDc2liUzJlTGlFMXVWRUpPTm9NNGxrNkZQbDNRMkNIYlcyTWVFYnFqWThoYmF3MThtTmIyeFNCSC9Gd3BpaWFsK1R2aTJpbXFnbkNPNFpwTzlibGxLZnRaUGNReTBzdE4rZUdCbGI1dWZ5ZmxLa0RTaUNoSFlyb0dqRXBtaUZpY2RkZTQ4Y0pzekY1MnVLTm5mMXE2N2ZBOS9TMkZBSFFhYjNFWG9qeEgyR2JrK2trVjJoL1RZS0ZGWlNXQzN2aTRlOG1PK3ZqTVVjUjBBZHNnUEZ5RUl6MFNDR3ViYTNDblRMTmRFdVp3c2F1QWVIa3gydlVUblJnSlBWZ05lZXVYbXNWRzc2U3kyZ2dKSHVhbHMwSGo4VTJYZGEwcU8xUnVGZm9DV2Zzczl3bjZIR1J3UFBraFNCLzhvTmd1QXFtUlZHS2tkOFp3dDNJdnJUZDlmazAvckZGREpLR3o3V3lOSGtZZ1VtTmlHY0l0RDEydjBqeDdGWjUyRUp6bDNBdjFSeUpVUUsxOCs4RVlQaDNTR2lVOWR0N1ZYMGFGMHVvNkpvdUtoT2VsZFV2TVArQXVnUXo4ZlVjbHdUUXNiYm9WZzI3WXhvMER5QVRWd1RoVzVhNTZSNlFmNVppUUpsdUZ1enM1eTk4cnEwUzVxMDQ2bEU2bzN2Vm1KcEVkd2plU0NKb0VUNUNMNG5UZ2tYeVd2aG00ZUI4dS9lNjZsM28wcWJhU3g4cTlZWW1UOUVwUmNsNVRQNFRoTEJLRVRZZHpWdmc0ZXhqUWZla3RNYXRrNUV5VXBFSWhaUFhoNXZYcEpaZXNkZk85TEo4elRhSEJzQmpEUFU3Y2ROZ1FNYmVicGF0YVJpOEEwZWwyL0lKWGwrRStvbGdBejV6QzRpMk8xUT09XCJ9JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTUxMGIxMjVmYmEnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICcxOWJkZmUyYTRiNDk4YTA1NTExMzgxMjM1YTg4OTJkNTQyNjc4MDdjNGEzZjY1NGUzMTBiOTM4YjhiNDI0ZmY0YWRlZGJlOTJmNGMxNDZkZTY0MWM2NzUwOGE5NjEzMjRjODUwNGNkZjhlMGMwYWNiYjY4ZDYxMDRjY2NjZDc4MScsXG4gICAgICAgICAgdmVyaWZpZWRWc3NQcm9vZjogdHJ1ZSxcbiAgICAgICAgICBpc0JpdEdvOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiB2YWxpZGF0aW5nIGEgd2VsbCBmb3JtYXR0ZWQgYWRkcmVzcyBwcmVmaXhlZCB3aXRoIDB4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcweGY5NDFhZTNjYmU1NjQ1ZGNjYzE1ZGE4MzQ2YjUzM2Y3ZjkxZjIwMjA4OWE1NTIxNjUzYzA2MmIyZmYxMGIzMDQnO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiB2YWxpZGF0aW5nIGFuIG9sZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcweDI5NTliZmMzZmRiN2RjMjNmZWQ4ZGViYTJmYWZiNzBmM2U2MDZhNTknO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gdmFsaWRhdGluZyBhbiBpbmNvcnJlY3RseSBmb3JtYXR0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ3dyb25nYWRkcmVzcyc7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgaXNXYWxsZXRBZGRyZXNzIHdpdGggdmFsaWQgYWRkcmVzcyBmb3IgaW5kZXggNCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ld0FkZHJlc3MgPSAnMHg4YjNjNzgwNzczMGQ3NTc5MmRkNmM0OTczMmNmOWYwMTRkNjk4NGE5Yzc3ZDM4NmJkYjEwNzJhOWU1MzdkOGQ4JztcbiAgICAgIGNvbnN0IGluZGV4ID0gNDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogbmV3QWRkcmVzcywgaW5kZXgsIGtleWNoYWlucyB9O1xuICAgICAgKGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpc1dhbGxldEFkZHJlc3Mgd2hlbiBrZXljaGFpbnMgaXMgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnMHgyOTU5YmZjM2ZkYjdkYzIzZmVkOGRlYmEyZmFmYjcwZjNlNjA2YTU5JztcbiAgICAgIGNvbnN0IGluZGV4ID0gMDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzcywgaW5kZXggfTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGlzV2FsbGV0QWRkcmVzcyB3aGVuIG5ldyBhZGRyZXNzIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnYmFkQWRkcmVzcyc7XG4gICAgICBjb25zdCBpbmRleCA9IDA7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHsgY29tbW9uS2V5Y2hhaW4sIGFkZHJlc3M6IHdyb25nQWRkcmVzcywgaW5kZXggfTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCB7XG4gICAgICAgIG1lc3NhZ2U6IGBpbnZhbGlkIGFkZHJlc3M6ICR7d3JvbmdBZGRyZXNzfWAsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0lEIFZhbGlkYXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ2NoZWNrIGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yazogTmV0d29yayA9IE5ldHdvcmsuVEVTVE5FVDtcbiAgICAgIGNvbnN0IGFwdG9zID0gbmV3IEFwdG9zKG5ldyBBcHRvc0NvbmZpZyh7IG5ldHdvcmsgfSkpO1xuICAgICAgY29uc3Qgc2VuZGVyQWRkcmVzcyA9IEFjY291bnRBZGRyZXNzLmZyb21TdHJpbmcoXG4gICAgICAgICcweGM4ZjAyZDI1YWE2OThiM2U5ZmJkOGEwOGU4ZGE0YzhlZTI2MTgzMmEyNWE0Y2RlODczMWI1ZWMzNTY1MzdkMDknXG4gICAgICApO1xuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9IEFjY291bnRBZGRyZXNzLmZyb21TdHJpbmcoXG4gICAgICAgICcweGY3NDA1YzI4YTAyY2Y1YmFiNGVhNDQ5ODI0MGJiMzU3OWRiNDU5NTE3OTRlYjFjODQzYmVmMDUzNGMwOTNhZDknXG4gICAgICApO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IGFwdG9zLnRyYW5zYWN0aW9uLmJ1aWxkLnNpbXBsZSh7XG4gICAgICAgIHNlbmRlcjogc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgZGF0YToge1xuICAgICAgICAgIGZ1bmN0aW9uOiAnMHgxOjpjb2luOjp0cmFuc2ZlcicsXG4gICAgICAgICAgdHlwZUFyZ3VtZW50czogW0FQVE9TX0NPSU5dLFxuICAgICAgICAgIGZ1bmN0aW9uQXJndW1lbnRzOiBbcmVjaXBpZW50QWRkcmVzcywgMTAwMF0sXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBtYXhHYXNBbW91bnQ6IDIwMDAwMCxcbiAgICAgICAgICBnYXNVbml0UHJpY2U6IDEwMCxcbiAgICAgICAgICBleHBpcmVUaW1lc3RhbXA6IDE3MzI2OTkyMzYsXG4gICAgICAgICAgYWNjb3VudFNlcXVlbmNlTnVtYmVyOiAxNCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBERUZBVUxUX1BVQkxJQ19LRVkgPSBCdWZmZXIuYWxsb2MoMzIpO1xuICAgICAgY29uc3QgREVGQVVMVF9TSUdOQVRVUkUgPSBCdWZmZXIuYWxsb2MoNjQpO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gbmV3IEVkMjU1MTlQdWJsaWNLZXkodXRpbHMuZ2V0QnVmZmVyRnJvbUhleFN0cmluZyhERUZBVUxUX1BVQkxJQ19LRVkudG9TdHJpbmcoJ2hleCcpKSk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBuZXcgRWQyNTUxOVNpZ25hdHVyZShERUZBVUxUX1NJR05BVFVSRSk7XG4gICAgICBjb25zdCBzZW5kZXJBdXRoZW50aWNhdG9yID0gbmV3IEFjY291bnRBdXRoZW50aWNhdG9yRWQyNTUxOShwdWJsaWNLZXksIHNpZ25hdHVyZSk7XG4gICAgICBjb25zdCBpZCA9IGdlbmVyYXRlVXNlclRyYW5zYWN0aW9uSGFzaCh7IHRyYW5zYWN0aW9uLCBzZW5kZXJBdXRoZW50aWNhdG9yIH0pO1xuXG4gICAgICBpZC5zaG91bGQuZXF1YWwoJzB4OTIzZDFjZmVkM2FmYWMyNDA0ODQ1MTE2MDMzN2RiNzViYTI4MjkxMjE1N2VlNDM0MDdiNTcyOTIzODAxZDViYScpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19

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


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