PHP WebShell

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

Просмотр файла: util.js

"use strict";
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 resources_1 = require("../resources");
const src_1 = require("../../src");
describe('XTZ util library', function () {
    describe('address', function () {
        it('should validate addresses', function () {
            const validAddresses = [
                'tz1aWXP237BLwNHJcCD4b3DutCevhqq2T1Z9',
                'tz2SHdGxFGhs68wYNC4hEqxbWARxp2J4mVxv',
                'tz3gN8NTLNLJg5KRsUU47NHNVHbdhcFXjjaB',
                'KT1EGbAxguaWQFkV3Egb2Z1r933MWuEYyrJS',
            ];
            for (const address of validAddresses) {
                src_1.XtzLib.Utils.isValidAddress(address).should.be.true();
            }
        });
        it('should fail to validate invalid addresses', function () {
            const invalidAddresses = [
                'tz4aWXP237BLwNHJcCD4b3DutCevhqq2T1Z9',
                'xtz2SHdGxFGhs68wYNC4hEqxbWARxp2J4mVxv',
                'KT2EGbAxguaWQFkV3Egb2Z1r933MWuEYyrJS',
                'abc',
            ];
            for (const address of invalidAddresses) {
                should_1.default.doesNotThrow(() => src_1.XtzLib.Utils.isValidAddress(address));
                src_1.XtzLib.Utils.isValidAddress(address).should.be.false();
            }
        });
    });
    describe('block hash', function () {
        it('should validate block hashes', function () {
            const validHashes = [
                'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku',
                'BL4oxWAkozJ3mJHwVFQqga5dQMBi8kBCPAQyBKgF78z7SQT1AvN',
                'BL29n92KHaarq1r7XjwTFotzCpxq7LtXMc9bF2qD9Qt26ZTYQia',
            ];
            for (const hash of validHashes) {
                src_1.XtzLib.Utils.isValidBlockHash(hash).should.be.true();
            }
        });
        it('should fail to validate invalid block hashes', function () {
            const invalidHashes = [
                'AKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku',
                'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku1111111111',
                'invalid',
            ];
            for (const hash of invalidHashes) {
                src_1.XtzLib.Utils.isValidBlockHash(hash).should.be.false();
            }
        });
    });
    describe('transaction hash', function () {
        it('should validate tx hashes', function () {
            const validHashes = [
                'opUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu',
                'ookyzxsYF7vyTeDzsgs58XJ4PXuvBkK8wWqZJ4EoRS6RWQb4Y9P',
                'ooXQoUX32szALRvgzD2TDzeRPXtPfmfqwoehPaK5khbrBiMAtSw',
            ];
            for (const hash of validHashes) {
                src_1.XtzLib.Utils.isValidTransactionHash(hash).should.be.true();
            }
        });
        it('should fail to validate invalid tx hashes', function () {
            const invalidHashes = [
                'lpUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu',
                'opUmZNMueryYFxTbzzocS7K4dzs3NmgKqhhr9TkcftszDDnoRVu1111111111',
                'invalid',
            ];
            for (const hash of invalidHashes) {
                src_1.XtzLib.Utils.isValidTransactionHash(hash).should.be.false();
            }
        });
        it('should calculate the transaction hash', async function () {
            const operationId = await src_1.XtzLib.Utils.calculateTransactionId(resources_1.signedSerializedOriginationTransaction);
            operationId.should.equal('opPsNbm7EcqPyryBDDR28BjdthnriktK8TbMvpwc9r4NwmvToYP');
        });
        it('should calculate the originated account address', async function () {
            const accountAddress = await src_1.XtzLib.Utils.calculateOriginatedAddress('opPsNbm7EcqPyryBDDR28BjdthnriktK8TbMvpwc9r4NwmvToYP', 0);
            accountAddress.should.equal('KT1LJvp55fbdNwbisJFign9wA4cPgq9T9oc4');
        });
    });
    describe('sign', function () {
        it('should produce a valid signature', async function () {
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, resources_1.defaultDataToSign);
            signatures.bytes.should.equal('0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b');
            signatures.prefixSig.should.equal('spsig19yWAc5nBpGmNCWdvEWHnpJXEiTqZjhNgWwWa1Lz6kVgakb7qCPj9z6G6LLEFWmsmNcPCZYseERVDUXh99N7wqDppcDKQM');
            signatures.sbytes.should.equal('0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b1fd49502ba8dc7adb01716093abe715d1eef87f47a88d8ec104fcc1d6baca7ba06cc2ced6c5baa880d6045b44be926d63bc3aeb3b9124f3b32ac6d9c63584fe5');
            signatures.sig.should.equal('sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZy9gwJedKMCrcQPxm9C7i1gesETbhFD6Gm8BpadGgd2cgiGoQbiY');
        });
        it('should produce a valid signature with watermark', async function () {
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, resources_1.defaultDataToSign, new Uint8Array());
            signatures.bytes.should.equal('0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b');
            signatures.prefixSig.should.equal('spsig1DWTuXdgUg2t64PLRfaapsYejCoCVVkqy2Zjv41Zirt7MjoqSfBnP38qoAg3SWicfQNiG25yMqGYge4jrfrwv9H8hRKDyY');
            signatures.sbytes.should.equal('0507070a000000160196369c90625575ba44594b23794832a9337f7a2d0007070000050502000000320320053d036d0743035d0a00000015006b5ddaef3fb5d7c151cfb36fbe43a7a066777394031e0743036a0001034f034d031b3ad76776913e2c0cfe827b572c417b73a14debcf9e5db726ce9b10aa4bea6aa1173b313ff67eb9bdfdcf9a753178e6ac78ac5f53aef8bcca6d56706f5c3fb01f');
            signatures.sig.should.equal('sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk');
        });
        it('should validate a signature belongs to a public key for a string message', async function () {
            const message = 'helloworld';
            const messageHex = Buffer.from(message).toString('hex');
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, messageHex, new Uint8Array(0));
            const result = await src_1.XtzLib.Utils.verifySignature(messageHex, resources_1.defaultKeyPairFromPub.getKeys().pub, signatures.sig, new Uint8Array(0));
            result.should.be.true();
        });
        it('should validate a signature belongs to a public key for dataToSign', async function () {
            const messageHex = Buffer.from(resources_1.defaultDataToSign).toString('hex');
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, messageHex, new Uint8Array(0));
            const result = await src_1.XtzLib.Utils.verifySignature(messageHex, resources_1.defaultKeyPairFromPub.getKeys().pub, signatures.sig, new Uint8Array(0));
            result.should.be.true();
        });
        it('should fail to validate a signature with the wrong watermark', async function () {
            const messageHex = Buffer.from(resources_1.defaultDataToSign).toString('hex');
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, messageHex);
            const result = await src_1.XtzLib.Utils.verifySignature(messageHex, resources_1.defaultKeyPairFromPub.getKeys().pub, signatures.sig, new Uint8Array(3));
            result.should.be.false();
        });
        it('should fail to validate a signature with the wrong public key', async function () {
            const messageHex = Buffer.from(resources_1.defaultDataToSign).toString('hex');
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, messageHex);
            const result = await src_1.XtzLib.Utils.verifySignature(messageHex, 'sppk7d2ztzbrLdBaTB7yzaWRkPfcWGsrNQNJdkBE9bCTSSzekLNzpvf', signatures.sig);
            result.should.be.false();
        });
        it('should fail to validate a signature with the wrong message', async function () {
            const messageHex = Buffer.from(resources_1.defaultDataToSign).toString('hex');
            const signatures = await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPrv, messageHex);
            const secondMessageHex = Buffer.from('helloWorld').toString('hex');
            const result = await src_1.XtzLib.Utils.verifySignature(secondMessageHex, resources_1.defaultKeyPairFromPub.getKeys().pub, signatures.sig);
            result.should.be.false();
        });
        it('should fail if the key pair does not have the private key', async function () {
            await src_1.XtzLib.Utils.sign(resources_1.defaultKeyPairFromPub, resources_1.defaultDataToSign).should.be.rejectedWith(new RegExp('Missing private key'));
        });
    });
    describe('generateDataToSign', function () {
        it('should build transfer data to sign', function () {
            const dataToSign = src_1.XtzLib.Utils.generateDataToSign('KT1NH2M23xovhw7uwWVuoGTYxykeCcVfSqhL', 'tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS', '100', '0');
            JSON.stringify(dataToSign).should.equal(JSON.stringify(resources_1.validDataToSign));
        });
        it('should fail if the contract address has the wrong format', function () {
            assert_1.default.throws(() => src_1.XtzLib.Utils.generateDataToSign('tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS', 'tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS', '0', '0'), new RegExp('Invalid contract address'));
        });
        it('should fail if the destination address has the wrong format', function () {
            assert_1.default.throws(() => src_1.XtzLib.Utils.generateDataToSign('KT1NH2M23xovhw7uwWVuoGTYxykeCcVfSqhL', 'abc', '0', '0'), new RegExp('Invalid destination address'));
        });
    });
    describe('signature', function () {
        it('should validate signature', function () {
            const validSignatures = [
                'sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk',
                'spsig1DWTuXdgUg2t64PLRfaapsYejCoCVVkqy2Zjv41Zirt7MjoqSfBnP38qoAg3SWicfQNiG25yMqGYge4jrfrwv9H8hRKDyY',
                'sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZy9gwJedKMCrcQPxm9C7i1gesETbhFD6Gm8BpadGgd2cgiGoQbiY',
                'spsig19yWAc5nBpGmNCWdvEWHnpJXEiTqZjhNgWwWa1Lz6kVgakb7qCPj9z6G6LLEFWmsmNcPCZYseERVDUXh99N7wqDppcDKQM',
            ];
            for (const hash of validSignatures) {
                src_1.XtzLib.Utils.isValidSignature(hash).should.be.true();
            }
        });
        it('should fail to validate invalid signature', function () {
            const invalidHashes = [
                'sigS9pqYUXiUJcz2Wsx5x98ud9KtgGVg4gCwpBoDBgHrZ',
                'sig',
                'BKoifs5gGffAzuRBcg3ygxbLdrCXyDDS1ALvMG8SFYWahzoYMku1111111111',
                'invalid',
            ];
            for (const hash of invalidHashes) {
                src_1.XtzLib.Utils.isValidSignature(hash).should.be.false();
            }
        });
    });
    describe('decodeKey', function () {
        it('should decode the key', function () {
            const validKeys = [['spsk2cbiVsAvpGKmau9XcMscL3NRwjkyT575N5AyAofcoj41x6g6TL', src_1.XtzLib.Utils.hashTypes.spsk]];
            for (const data of validKeys) {
                src_1.XtzLib.Utils.decodeKey(data[0], data[1])
                    .toString('hex')
                    .should.equal('9cc0aaa9ef687e70f7780e60de08d7a443488a9cf8e1ebe9689118763376c07c');
            }
        });
        it('should fail to decode an invalid key', function () {
            const invalidKeys = [
                [
                    'sigVgnaU2S1L4jhtPaTX2SAxsGpP1dRS89VTSR9FrFuxxPvgA2G67QRuez6o6xP7ekagdZX4ELvh7pbMMdLoBSzvk2AVyQpk',
                    src_1.XtzLib.Utils.hashTypes.tz1,
                ],
                ['sppk', src_1.XtzLib.Utils.hashTypes.sppk],
            ];
            for (const data of invalidKeys) {
                assert_1.default.throws(() => src_1.XtzLib.Utils.decodeKey(data[0], data[1]), new RegExp('Unsupported private key'));
            }
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLG9EQUE0QjtBQUU1Qiw0Q0FNc0I7QUFDdEIsbUNBQW1DO0FBR25DLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRTtJQUMzQixRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQywyQkFBMkIsRUFBRTtZQUM5QixNQUFNLGNBQWMsR0FBRztnQkFDckIsc0NBQXNDO2dCQUN0QyxzQ0FBc0M7Z0JBQ3RDLHNDQUFzQztnQkFDdEMsc0NBQXNDO2FBQ3ZDLENBQUM7WUFFRixLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNyQyxZQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3hELENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtZQUM5QyxNQUFNLGdCQUFnQixHQUFHO2dCQUN2QixzQ0FBc0M7Z0JBQ3RDLHVDQUF1QztnQkFDdkMsc0NBQXNDO2dCQUN0QyxLQUFLO2FBQ04sQ0FBQztZQUVGLEtBQUssTUFBTSxPQUFPLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDdkMsZ0JBQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsWUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDaEUsWUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZ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QyxJQUFJLENBQUMsQ0FBQyxDQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBYSxDQUFDO3FCQUMzRCxRQUFRLENBQUMsS0FBSyxDQUFDO3FCQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUN0RixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUU7WUFDekMsTUFBTSxXQUFXLEdBQUc7Z0JBQ2xCO29CQUNFLGtHQUFrRztvQkFDbEcsWUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRztpQkFDM0I7Z0JBQ0QsQ0FBQyxNQUFNLEVBQUUsWUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO2FBQ3RDLENBQUM7WUFFRixLQUFLLE1BQU0sSUFBSSxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUMvQixnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxZQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBYSxDQUFDLEVBQ3BFLElBQUksTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQ3RDLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuXG5pbXBvcnQge1xuICBkZWZhdWx0RGF0YVRvU2lnbixcbiAgZGVmYXVsdEtleVBhaXJGcm9tUHJ2LFxuICBkZWZhdWx0S2V5UGFpckZyb21QdWIsXG4gIHNpZ25lZFNlcmlhbGl6ZWRPcmlnaW5hdGlvblRyYW5zYWN0aW9uLFxuICB2YWxpZERhdGFUb1NpZ24sXG59IGZyb20gJy4uL3Jlc291cmNlcyc7XG5pbXBvcnQgeyBYdHpMaWIgfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgSGFzaFR5cGUgfSBmcm9tICcuLi8uLi9zcmMvbGliL2lmYWNlJztcblxuZGVzY3JpYmUoJ1hUWiB1dGlsIGxpYnJhcnknLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRBZGRyZXNzZXMgPSBbXG4gICAgICAgICd0ejFhV1hQMjM3Qkx3TkhKY0NENGIzRHV0Q2V2aHFxMlQxWjknLFxuICAgICAgICAndHoyU0hkR3hGR2hzNjh3WU5DNGhFcXhiV0FSeHAySjRtVnh2JyxcbiAgICAgICAgJ3R6M2dOOE5UTE5MSmc1S1JzVVU0N05ITlZIYmRoY0ZYamphQicsXG4gICAgICAgICdLVDFFR2JBeGd1YVdRRmtWM0VnYjJaMXI5MzNNV3VFWXlySlMnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIHZhbGlkQWRkcmVzc2VzKSB7XG4gICAgICAgIFh0ekxpYi5VdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEFkZHJlc3NlcyA9IFtcbiAgICAgICAgJ3R6NGFXWFAyMzdCTHdOSEpjQ0Q0YjNEdXRDZXZocXEyVDFaOScsXG4gICAgICAgICd4dHoyU0hkR3hGR2hzNjh3WU5DNGhFcXhiV0FSeHAySjRtVnh2JyxcbiAgICAgICAgJ0tUMkVHYkF4Z3VhV1FGa1YzRWdiMloxcjkzM01XdUVZeXJKUycsXG4gICAgICAgICdhYmMnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGludmFsaWRBZGRyZXNzZXMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBYdHpMaWIuVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpO1xuICAgICAgICBYdHpMaWIuVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdibG9jayBoYXNoJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYmxvY2sgaGFzaGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRIYXNoZXMgPSBbXG4gICAgICAgICdCS29pZnM1Z0dmZkF6dVJCY2czeWd4YkxkckNYeUREUzFBTHZNRzhTRllXYWh6b1lNa3UnLFxuICAgICAgICAnQkw0b3hXQWtvekozbUpId1ZGUXFnYTVkUU1CaThrQkNQQVF5QktnRjc4ejdTUVQxQXZOJyxcbiAgICAgICAgJ0JMMjluOTJLSGFhcnExcjdYandURm90ekNweHE3THRYTWM5YkYycUQ5UXQyNlpUWVFpYScsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IGhhc2ggb2YgdmFsaWRIYXNoZXMpIHtcbiAgICAgICAgWHR6TGliLlV0aWxzLmlzVmFsaWRCbG9ja0hhc2goaGFzaCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2YWxpZGF0ZSBpbnZhbGlkIGJsb2NrIGhhc2hlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRIYXNoZXMgPSBbXG4gICAgICAgICdBS29pZnM1Z0dmZkF6dVJCY2czeWd4YkxkckNYeUREUzFBTHZNRzhTRllXYWh6b1lNa3UnLFxuICAgICAgICAnQktvaWZzNWdHZmZBenVSQmNnM3lneGJMZHJDWHlERFMxQUx2TUc4U0ZZV2Foem9ZTWt1MTExMTExMTExMScsXG4gICAgICAgICdpbnZhbGlkJyxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3QgaGFzaCBvZiBpbnZhbGlkSGFzaGVzKSB7XG4gICAgICAgIFh0ekxpYi5VdGlscy5pc1ZhbGlkQmxvY2tIYXNoKGhhc2gpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndHJhbnNhY3Rpb24gaGFzaCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHR4IGhhc2hlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkSGFzaGVzID0gW1xuICAgICAgICAnb3BVbVpOTXVlcnlZRnhUYnp6b2NTN0s0ZHpzM05tZ0txaGhyOVRrY2Z0c3pERG5vUlZ1JyxcbiAgICAgICAgJ29va3l6eHNZRjd2eVRlRHpzZ3M1OFhKNFBYdXZCa0s4d1dxWko0RW9SUzZSV1FiNFk5UCcsXG4gICAgICAgICdvb1hRb1VYMzJzekFMUnZnekQyVER6ZVJQWHRQZm1mcXdvZWhQYUs1a2hickJpTUF0U3cnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBoYXNoIG9mIHZhbGlkSGFzaGVzKSB7XG4gICAgICAgIFh0ekxpYi5VdGlscy5pc1ZhbGlkVHJhbnNhY3Rpb25IYXNoKGhhc2gpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmFsaWRhdGUgaW52YWxpZCB0eCBoYXNoZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkSGFzaGVzID0gW1xuICAgICAgICAnbHBVbVpOTXVlcnlZRnhUYnp6b2NTN0s0ZHpzM05tZ0txaGhyOVRrY2Z0c3pERG5vUlZ1JyxcbiAgICAgICAgJ29wVW1aTk11ZXJ5WUZ4VGJ6em9jUzdLNGR6czNObWdLcWhocjlUa2NmdHN6RERub1JWdTExMTExMTExMTEnLFxuICAgICAgICAnaW52YWxpZCcsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IGhhc2ggb2YgaW52YWxpZEhhc2hlcykge1xuICAgICAgICBYdHpMaWIuVXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSGFzaChoYXNoKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsY3VsYXRlIHRoZSB0cmFuc2FjdGlvbiBoYXNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3BlcmF0aW9uSWQgPSBhd2FpdCBYdHpMaWIuVXRpbHMuY2FsY3VsYXRlVHJhbnNhY3Rpb25JZChzaWduZWRTZXJpYWxpemVkT3JpZ2luYXRpb25UcmFuc2FjdGlvbik7XG4gICAgICBvcGVyYXRpb25JZC5zaG91bGQuZXF1YWwoJ29wUHNOYm03RWNxUHlyeUJERFIyOEJqZHRobnJpa3RLOFRiTXZwd2M5cjROd212VG9ZUCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjYWxjdWxhdGUgdGhlIG9yaWdpbmF0ZWQgYWNjb3VudCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEFkZHJlc3MgPSBhd2FpdCBYdHpMaWIuVXRpbHMuY2FsY3VsYXRlT3JpZ2luYXRlZEFkZHJlc3MoXG4gICAgICAgICdvcFBzTmJtN0VjcVB5cnlCRERSMjhCamR0aG5yaWt0SzhUYk12cHdjOXI0TndtdlRvWVAnLFxuICAgICAgICAwXG4gICAgICApO1xuICAgICAgYWNjb3VudEFkZHJlc3Muc2hvdWxkLmVxdWFsKCdLVDFMSnZwNTVmYmROd2Jpc0pGaWduOXdBNGNQZ3E5VDlvYzQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NpZ24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGEgdmFsaWQgc2lnbmF0dXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IFh0ekxpYi5VdGlscy5zaWduKGRlZmF1bHRLZXlQYWlyRnJvbVBydiwgZGVmYXVsdERhdGFUb1NpZ24pO1xuICAgICAgc2lnbmF0dXJlcy5ieXRlcy5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwNTA3MDcwYTAwMDAwMDE2MDE5NjM2OWM5MDYyNTU3NWJhNDQ1OTRiMjM3OTQ4MzJhOTMzN2Y3YTJkMDAwNzA3MDAwMDA1MDUwMjAwMDAwMDMyMDMyMDA1M2QwMzZkMDc0MzAzNWQwYTAwMDAwMDE1MDA2YjVkZGFlZjNmYjVkN2MxNTFjZmIzNmZiZTQzYTdhMDY2Nzc3Mzk0MDMxZTA3NDMwMzZhMDAwMTAzNGYwMzRkMDMxYidcbiAgICAgICk7XG4gICAgICBzaWduYXR1cmVzLnByZWZpeFNpZy5zaG91bGQuZXF1YWwoXG4gICAgICAgICdzcHNpZzE5eVdBYzVuQnBHbU5DV2R2RVdIbnBKWEVpVHFaamhOZ1d3V2ExTHo2a1ZnYWtiN3FDUGo5ejZHNkxMRUZXbXNtTmNQQ1pZc2VFUlZEVVhoOTlON3dxRHBwY0RLUU0nXG4gICAgICApO1xuICAgICAgc2lnbmF0dXJlcy5zYnl0ZXMuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDUwNzA3MGEwMDAwMDAxNjAxOTYzNjljOTA2MjU1NzViYTQ0NTk0YjIzNzk0ODMyYTkzMzdmN2EyZDAwMDcwNzAwMDAwNTA1MDIwMDAwMDAzMjAzMjAwNTNkMDM2ZDA3NDMwMzVkMGEwMDAwMDAxNTAwNmI1ZGRhZWYzZmI1ZDdjMTUxY2ZiMzZmYmU0M2E3YTA2Njc3NzM5NDAzMWUwNzQzMDM2YTAwMDEwMzRmMDM0ZDAzMWIxZmQ0OTUwMmJhOGRjN2FkYjAxNzE2MDkzYWJlNzE1ZDFlZWY4N2Y0N2E4OGQ4ZWMxMDRmY2MxZDZiYWNhN2JhMDZjYzJjZWQ2YzViYWE4ODBkNjA0NWI0NGJlOTI2ZDYzYmMzYWViM2I5MTI0ZjNiMzJhYzZkOWM2MzU4NGZlNSdcbiAgICAgICk7XG4gICAgICBzaWduYXR1cmVzLnNpZy5zaG91bGQuZXF1YWwoXG4gICAgICAgICdzaWdTOXBxWVVYaVVKY3oyV3N4NXg5OHVkOUt0Z0dWZzRnQ3dwQm9EQmdIclp5OWd3SmVkS01DcmNRUHhtOUM3aTFnZXNFVGJoRkQ2R204QnBhZEdnZDJjZ2lHb1FiaVknXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGEgdmFsaWQgc2lnbmF0dXJlIHdpdGggd2F0ZXJtYXJrJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IFh0ekxpYi5VdGlscy5zaWduKGRlZmF1bHRLZXlQYWlyRnJvbVBydiwgZGVmYXVsdERhdGFUb1NpZ24sIG5ldyBVaW50OEFycmF5KCkpO1xuICAgICAgc2lnbmF0dXJlcy5ieXRlcy5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwNTA3MDcwYTAwMDAwMDE2MDE5NjM2OWM5MDYyNTU3NWJhNDQ1OTRiMjM3OTQ4MzJhOTMzN2Y3YTJkMDAwNzA3MDAwMDA1MDUwMjAwMDAwMDMyMDMyMDA1M2QwMzZkMDc0MzAzNWQwYTAwMDAwMDE1MDA2YjVkZGFlZjNmYjVkN2MxNTFjZmIzNmZiZTQzYTdhMDY2Nzc3Mzk0MDMxZTA3NDMwMzZhMDAwMTAzNGYwMzRkMDMxYidcbiAgICAgICk7XG4gICAgICBzaWduYXR1cmVzLnByZWZpeFNpZy5zaG91bGQuZXF1YWwoXG4gICAgICAgICdzcHNpZzFEV1R1WGRnVWcydDY0UExSZmFhcHNZZWpDb0NWVmtxeTJaanY0MVppcnQ3TWpvcVNmQm5QMzhxb0FnM1NXaWNmUU5pRzI1eU1xR1lnZTRqcmZyd3Y5SDhoUktEeVknXG4gICAgICApO1xuICAgICAgc2lnbmF0dXJlcy5zYnl0ZXMuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDUwNzA3MGEwMDAwMDAxNjAxOTYzNjljOTA2MjU1NzViYTQ0NTk0YjIzNzk0ODMyYTkzMzdmN2EyZDAwMDcwNzAwMDAwNTA1MDIwMDAwMDAzMjAzMjAwNTNkMDM2ZDA3NDMwMzVkMGEwMDAwMDAxNTAwNmI1ZGRhZWYzZmI1ZDdjMTUxY2ZiMzZmYmU0M2E3YTA2Njc3NzM5NDAzMWUwNzQzMDM2YTAwMDEwMzRmMDM0ZDAzMWIzYWQ3Njc3NjkxM2UyYzBjZmU4MjdiNTcyYzQxN2I3M2ExNGRlYmNmOWU1ZGI3MjZjZTliMTBhYTRiZWE2YWExMTczYjMxM2ZmNjdlYjliZGZkY2Y5YTc1MzE3OGU2YWM3OGFjNWY1M2FlZjhiY2NhNmQ1NjcwNmY1YzNmYjAxZidcbiAgICAgICk7XG4gICAgICBzaWduYXR1cmVzLnNpZy5zaG91bGQuZXF1YWwoXG4gICAgICAgICdzaWdWZ25hVTJTMUw0amh0UGFUWDJTQXhzR3BQMWRSUzg5VlRTUjlGckZ1eHhQdmdBMkc2N1FSdWV6Nm82eFA3ZWthZ2RaWDRFTHZoN3BiTU1kTG9CU3p2azJBVnlRcGsnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhIHNpZ25hdHVyZSBiZWxvbmdzIHRvIGEgcHVibGljIGtleSBmb3IgYSBzdHJpbmcgbWVzc2FnZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSAnaGVsbG93b3JsZCc7XG4gICAgICBjb25zdCBtZXNzYWdlSGV4ID0gQnVmZmVyLmZyb20obWVzc2FnZSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IFh0ekxpYi5VdGlscy5zaWduKGRlZmF1bHRLZXlQYWlyRnJvbVBydiwgbWVzc2FnZUhleCwgbmV3IFVpbnQ4QXJyYXkoMCkpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgWHR6TGliLlV0aWxzLnZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgbWVzc2FnZUhleCxcbiAgICAgICAgZGVmYXVsdEtleVBhaXJGcm9tUHViLmdldEtleXMoKS5wdWIsXG4gICAgICAgIHNpZ25hdHVyZXMuc2lnLFxuICAgICAgICBuZXcgVWludDhBcnJheSgwKVxuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhIHNpZ25hdHVyZSBiZWxvbmdzIHRvIGEgcHVibGljIGtleSBmb3IgZGF0YVRvU2lnbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2VIZXggPSBCdWZmZXIuZnJvbShkZWZhdWx0RGF0YVRvU2lnbikudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IFh0ekxpYi5VdGlscy5zaWduKGRlZmF1bHRLZXlQYWlyRnJvbVBydiwgbWVzc2FnZUhleCwgbmV3IFVpbnQ4QXJyYXkoMCkpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgWHR6TGliLlV0aWxzLnZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgbWVzc2FnZUhleCxcbiAgICAgICAgZGVmYXVsdEtleVBhaXJGcm9tUHViLmdldEtleXMoKS5wdWIsXG4gICAgICAgIHNpZ25hdHVyZXMuc2lnLFxuICAgICAgICBuZXcgVWludDhBcnJheSgwKVxuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGEgc2lnbmF0dXJlIHdpdGggdGhlIHdyb25nIHdhdGVybWFyaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2VIZXggPSBCdWZmZXIuZnJvbShkZWZhdWx0RGF0YVRvU2lnbikudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IFh0ekxpYi5VdGlscy5zaWduKGRlZmF1bHRLZXlQYWlyRnJvbVBydiwgbWVzc2FnZUhleCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBYdHpMaWIuVXRpbHMudmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICBtZXNzYWdlSGV4LFxuICAgICAgICBkZWZhdWx0S2V5UGFpckZyb21QdWIuZ2V0S2V5cygpLnB1YixcbiAgICAgICAgc2lnbmF0dXJlcy5zaWcsXG4gICAgICAgIG5ldyBVaW50OEFycmF5KDMpXG4gICAgICApO1xuICAgICAgcmVzdWx0LnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGEgc2lnbmF0dXJlIHdpdGggdGhlIHdyb25nIHB1YmxpYyBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSGV4ID0gQnVmZmVyLmZyb20oZGVmYXVsdERhdGFUb1NpZ24pLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZXMgPSBhd2FpdCBYdHpMaWIuVXRpbHMuc2lnbihkZWZhdWx0S2V5UGFpckZyb21QcnYsIG1lc3NhZ2VIZXgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgWHR6TGliLlV0aWxzLnZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgbWVzc2FnZUhleCxcbiAgICAgICAgJ3NwcGs3ZDJ6dHpickxkQmFUQjd5emFXUmtQZmNXR3NyTlFOSmRrQkU5YkNUU1N6ZWtMTnpwdmYnLFxuICAgICAgICBzaWduYXR1cmVzLnNpZ1xuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2YWxpZGF0ZSBhIHNpZ25hdHVyZSB3aXRoIHRoZSB3cm9uZyBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZUhleCA9IEJ1ZmZlci5mcm9tKGRlZmF1bHREYXRhVG9TaWduKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBzaWduYXR1cmVzID0gYXdhaXQgWHR6TGliLlV0aWxzLnNpZ24oZGVmYXVsdEtleVBhaXJGcm9tUHJ2LCBtZXNzYWdlSGV4KTtcbiAgICAgIGNvbnN0IHNlY29uZE1lc3NhZ2VIZXggPSBCdWZmZXIuZnJvbSgnaGVsbG9Xb3JsZCcpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFh0ekxpYi5VdGlscy52ZXJpZnlTaWduYXR1cmUoXG4gICAgICAgIHNlY29uZE1lc3NhZ2VIZXgsXG4gICAgICAgIGRlZmF1bHRLZXlQYWlyRnJvbVB1Yi5nZXRLZXlzKCkucHViLFxuICAgICAgICBzaWduYXR1cmVzLnNpZ1xuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUga2V5IHBhaXIgZG9lcyBub3QgaGF2ZSB0aGUgcHJpdmF0ZSBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBYdHpMaWIuVXRpbHMuc2lnbihkZWZhdWx0S2V5UGFpckZyb21QdWIsIGRlZmF1bHREYXRhVG9TaWduKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICBuZXcgUmVnRXhwKCdNaXNzaW5nIHByaXZhdGUga2V5JylcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZW5lcmF0ZURhdGFUb1NpZ24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCB0cmFuc2ZlciBkYXRhIHRvIHNpZ24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhVG9TaWduID0gWHR6TGliLlV0aWxzLmdlbmVyYXRlRGF0YVRvU2lnbihcbiAgICAgICAgJ0tUMU5IMk0yM3hvdmh3N3V3V1Z1b0dUWXh5a2VDY1ZmU3FoTCcsXG4gICAgICAgICd0ejJQdEo5emdFZ0ZWVFJxeTZHWHNzdDU0dEgza3NFbll2dlMnLFxuICAgICAgICAnMTAwJyxcbiAgICAgICAgJzAnXG4gICAgICApO1xuICAgICAgSlNPTi5zdHJpbmdpZnkoZGF0YVRvU2lnbikuc2hvdWxkLmVxdWFsKEpTT04uc3RyaW5naWZ5KHZhbGlkRGF0YVRvU2lnbikpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBjb250cmFjdCBhZGRyZXNzIGhhcyB0aGUgd3JvbmcgZm9ybWF0JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBYdHpMaWIuVXRpbHMuZ2VuZXJhdGVEYXRhVG9TaWduKFxuICAgICAgICAgICAgJ3R6MlB0Sjl6Z0VnRlZUUnF5NkdYc3N0NTR0SDNrc0VuWXZ2UycsXG4gICAgICAgICAgICAndHoyUHRKOXpnRWdGVlRScXk2R1hzc3Q1NHRIM2tzRW5ZdnZTJyxcbiAgICAgICAgICAgICcwJyxcbiAgICAgICAgICAgICcwJ1xuICAgICAgICAgICksXG4gICAgICAgIG5ldyBSZWdFeHAoJ0ludmFsaWQgY29udHJhY3QgYWRkcmVzcycpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzIGhhcyB0aGUgd3JvbmcgZm9ybWF0JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gWHR6TGliLlV0aWxzLmdlbmVyYXRlRGF0YVRvU2lnbignS1QxTkgyTTIzeG92aHc3dXdXVnVvR1RZeHlrZUNjVmZTcWhMJywgJ2FiYycsICcwJywgJzAnKSxcbiAgICAgICAgbmV3IFJlZ0V4cCgnSW52YWxpZCBkZXN0aW5hdGlvbiBhZGRyZXNzJylcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZFNpZ25hdHVyZXMgPSBbXG4gICAgICAgICdzaWdWZ25hVTJTMUw0amh0UGFUWDJTQXhzR3BQMWRSUzg5VlRTUjlGckZ1eHhQdmdBMkc2N1FSdWV6Nm82eFA3ZWthZ2RaWDRFTHZoN3BiTU1kTG9CU3p2azJBVnlRcGsnLFxuICAgICAgICAnc3BzaWcxRFdUdVhkZ1VnMnQ2NFBMUmZhYXBzWWVqQ29DVlZrcXkyWmp2NDFaaXJ0N01qb3FTZkJuUDM4cW9BZzNTV2ljZlFOaUcyNXlNcUdZZ2U0anJmcnd2OUg4aFJLRHlZJyxcbiAgICAgICAgJ3NpZ1M5cHFZVVhpVUpjejJXc3g1eDk4dWQ5S3RnR1ZnNGdDd3BCb0RCZ0hyWnk5Z3dKZWRLTUNyY1FQeG05QzdpMWdlc0VUYmhGRDZHbThCcGFkR2dkMmNnaUdvUWJpWScsXG4gICAgICAgICdzcHNpZzE5eVdBYzVuQnBHbU5DV2R2RVdIbnBKWEVpVHFaamhOZ1d3V2ExTHo2a1ZnYWtiN3FDUGo5ejZHNkxMRUZXbXNtTmNQQ1pZc2VFUlZEVVhoOTlON3dxRHBwY0RLUU0nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBoYXNoIG9mIHZhbGlkU2lnbmF0dXJlcykge1xuICAgICAgICBYdHpMaWIuVXRpbHMuaXNWYWxpZFNpZ25hdHVyZShoYXNoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEhhc2hlcyA9IFtcbiAgICAgICAgJ3NpZ1M5cHFZVVhpVUpjejJXc3g1eDk4dWQ5S3RnR1ZnNGdDd3BCb0RCZ0hyWicsXG4gICAgICAgICdzaWcnLFxuICAgICAgICAnQktvaWZzNWdHZmZBenVSQmNnM3lneGJMZHJDWHlERFMxQUx2TUc4U0ZZV2Foem9ZTWt1MTExMTExMTExMScsXG4gICAgICAgICdpbnZhbGlkJyxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3QgaGFzaCBvZiBpbnZhbGlkSGFzaGVzKSB7XG4gICAgICAgIFh0ekxpYi5VdGlscy5pc1ZhbGlkU2lnbmF0dXJlKGhhc2gpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZGVjb2RlS2V5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZGVjb2RlIHRoZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZEtleXMgPSBbWydzcHNrMmNiaVZzQXZwR0ttYXU5WGNNc2NMM05Sd2preVQ1NzVONUF5QW9mY29qNDF4Nmc2VEwnLCBYdHpMaWIuVXRpbHMuaGFzaFR5cGVzLnNwc2tdXTtcblxuICAgICAgZm9yIChjb25zdCBkYXRhIG9mIHZhbGlkS2V5cykge1xuICAgICAgICBYdHpMaWIuVXRpbHMuZGVjb2RlS2V5KGRhdGFbMF0gYXMgc3RyaW5nLCBkYXRhWzFdIGFzIEhhc2hUeXBlKVxuICAgICAgICAgIC50b1N0cmluZygnaGV4JylcbiAgICAgICAgICAuc2hvdWxkLmVxdWFsKCc5Y2MwYWFhOWVmNjg3ZTcwZjc3ODBlNjBkZTA4ZDdhNDQzNDg4YTljZjhlMWViZTk2ODkxMTg3NjMzNzZjMDdjJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZGVjb2RlIGFuIGludmFsaWQga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleXMgPSBbXG4gICAgICAgIFtcbiAgICAgICAgICAnc2lnVmduYVUyUzFMNGpodFBhVFgyU0F4c0dwUDFkUlM4OVZUU1I5RnJGdXh4UHZnQTJHNjdRUnVlejZvNnhQN2VrYWdkWlg0RUx2aDdwYk1NZExvQlN6dmsyQVZ5UXBrJyxcbiAgICAgICAgICBYdHpMaWIuVXRpbHMuaGFzaFR5cGVzLnR6MSxcbiAgICAgICAgXSxcbiAgICAgICAgWydzcHBrJywgWHR6TGliLlV0aWxzLmhhc2hUeXBlcy5zcHBrXSxcbiAgICAgIF07XG5cbiAgICAgIGZvciAoY29uc3QgZGF0YSBvZiBpbnZhbGlkS2V5cykge1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IFh0ekxpYi5VdGlscy5kZWNvZGVLZXkoZGF0YVswXSBhcyBzdHJpbmcsIGRhdGFbMV0gYXMgSGFzaFR5cGUpLFxuICAgICAgICAgIG5ldyBSZWdFeHAoJ1Vuc3VwcG9ydGVkIHByaXZhdGUga2V5JylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

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


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