PHP WebShell

Текущая директория: /opt/BitGoJS/modules/unspents/dist/test/signedTx

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

"use strict";
/* eslint-disable @typescript-eslint/ban-ts-comment */
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 });
exports.runSignedTransactions = exports.runCombinations = exports.Histogram = exports.TxCombo = exports.createScriptPubKey = void 0;
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const utxo_lib_1 = require("@bitgo/utxo-lib");
const lodash_1 = __importDefault(require("lodash"));
require("lodash.combinations");
const src_1 = require("../../src");
const testutils_1 = require("../testutils");
function createUnspent(pubkeys, inputType, value) {
    let spendableScript;
    const scriptType = inputType === 'taprootKeyPathSpend' ? 'p2trMusig2' : inputType;
    if (scriptType === testutils_1.UnspentTypeP2shP2pk) {
        spendableScript = utxolib.bitgo.outputScripts.createOutputScriptP2shP2pk(pubkeys[0]);
    }
    else if (utxolib.bitgo.outputScripts.isScriptType2Of3(scriptType)) {
        spendableScript = utxolib.bitgo.outputScripts.createOutputScript2of3(pubkeys, scriptType);
    }
    else {
        throw new Error(`unexpected inputType ${scriptType}`);
    }
    return {
        ...spendableScript,
        value,
        inputType: scriptType,
    };
}
/**
 *
 * @param keys - Pubkeys to use for generating the address.
 *               If unspentType is one of UnspentTypePubKeyHash is used, the first key will be used.
 * @param unspentType {String} - one of UnspentTypeScript2of3 or UnspentTypePubKeyHash
 * @return {String} address
 */
const createScriptPubKey = (keys, unspentType) => {
    const pubkeys = keys.map((key) => key.publicKey);
    if (typeof unspentType === 'string' && unspentType in testutils_1.UnspentTypeScript2of3) {
        return createUnspent(pubkeys, unspentType, 0).scriptPubKey;
    }
    const pkHash = utxolib.crypto.hash160(pubkeys[0]);
    switch (unspentType) {
        case testutils_1.UnspentTypePubKeyHash.p2pkh:
            return utxolib.payments.p2pkh({ hash: pkHash }).output;
        case testutils_1.UnspentTypePubKeyHash.p2wpkh:
            return utxolib.payments.p2wpkh({ hash: pkHash }).output;
    }
    if (unspentType instanceof testutils_1.UnspentTypeOpReturn) {
        const payload = Buffer.alloc(unspentType.size).fill(pubkeys[0]);
        return utxolib.script.compile([0x6a, payload]);
    }
    throw new Error(`unsupported output type ${unspentType}`);
};
exports.createScriptPubKey = createScriptPubKey;
const createInputTx = (unspents, inputValue) => {
    const txInputBuilder = new utxolib.bitgo.UtxoTransactionBuilder(utxolib.networks.bitcoin);
    txInputBuilder.addInput(Array(32).fill('01').join(''), 0);
    unspents.forEach(({ scriptPubKey }) => txInputBuilder.addOutput(scriptPubKey, inputValue));
    return txInputBuilder.buildIncomplete();
};
function signInput(txBuilder, index, walletKeys, unspent, signKeys = unspent.inputType === 'p2shP2pk' ? [walletKeys[0]] : [walletKeys[0], walletKeys[2]]) {
    signKeys.forEach((keyPair) => {
        if (unspent.inputType === 'p2shP2pk') {
            utxolib.bitgo.signInputP2shP2pk(txBuilder, index, keyPair);
        }
        else {
            if (signKeys.length !== 2) {
                throw new Error(`invalid signKeys length`);
            }
            const cosigner = keyPair === signKeys[0] ? signKeys[1] : signKeys[0];
            utxolib.bitgo.signInput2Of3(txBuilder, index, unspent.inputType, walletKeys.map((k) => k.publicKey), keyPair, cosigner.publicKey, unspent.value);
        }
    });
}
class TxCombo {
    constructor(walletKeys, inputTypes, outputTypes, expectedDims = src_1.Dimensions.ZERO, signKeys, inputValue = 10) {
        this.walletKeys = walletKeys;
        this.inputTypes = inputTypes;
        this.outputTypes = outputTypes;
        this.expectedDims = expectedDims;
        this.signKeys = signKeys;
        this.inputValue = inputValue;
        this.unspents = inputTypes.map((inputType) => createUnspent(walletKeys.map((key) => key.publicKey), inputType, this.inputValue));
        this.inputTx = createInputTx(this.unspents, inputValue);
    }
    getBuilderWithUnsignedTx() {
        const txBuilder = utxolib.bitgo.createTransactionBuilderForNetwork(utxolib.networks.bitcoin);
        this.inputTx.outs.forEach(({}, i) => txBuilder.addInput(this.inputTx, i));
        this.outputTypes.forEach((unspentType) => txBuilder.addOutput((0, exports.createScriptPubKey)(this.walletKeys, unspentType), this.inputValue));
        return txBuilder;
    }
    getUnsignedTx() {
        return this.getBuilderWithUnsignedTx().buildIncomplete();
    }
    getSignedTx() {
        const txBuilder = this.getBuilderWithUnsignedTx();
        this.unspents.forEach((unspent, i) => {
            signInput(txBuilder, i, this.walletKeys, unspent, this.signKeys);
        });
        return txBuilder.build();
    }
}
exports.TxCombo = TxCombo;
const runCombinations = ({ inputTypes, maxNInputs, outputTypes, maxNOutputs, }, callback) => {
    // Create combinations of different input and output types. Length between 1 and 3.
    const inputCombinations = lodash_1.default.flatten(
    // @ts-ignore
    [...Array(maxNInputs)].map((__, i) => lodash_1.default.combinations(inputTypes, i + 1)));
    const outputCombinations = lodash_1.default.flatten(
    // @ts-ignore
    [...Array(maxNOutputs)].map((__, i) => lodash_1.default.combinations(outputTypes, i + 1)));
    inputCombinations.forEach((inputTypeCombo) => outputCombinations.forEach((outputTypeCombo) => {
        callback(inputTypeCombo, outputTypeCombo);
    }));
};
exports.runCombinations = runCombinations;
class Histogram {
    constructor(map = new Map()) {
        this.map = map;
        this.total = 0;
    }
    add(size) {
        this.map.set(size, (this.map.get(size) || 0) + 1);
        this.total++;
    }
    asSortedArray() {
        return [...this.map.entries()].sort(([a], [b]) => a - b);
    }
    asFullSortedArray() {
        return lodash_1.default.range(this.getPercentile(0), this.getPercentile(1)).map((v) => [v, this.map.get(v) || 0]);
    }
    getPercentile(p) {
        if (0 > p || p > 1) {
            throw new Error(`p must be between 0 and 1`);
        }
        let sum = 0;
        for (const [k, v] of this.asSortedArray()) {
            sum += v;
            if (sum / this.total >= p) {
                return k;
            }
        }
        throw new Error('could not find percentile');
    }
    toString() {
        const keys = [...this.map.keys()].sort((a, b) => a - b);
        return `[${keys.map((k) => `[${k}, ${this.map.get(k)}]`).join(' ')}]`;
    }
}
exports.Histogram = Histogram;
const getKeyTriplets = (prefix, count) => [...Array(count)].map((v, i) => [1, 2, 3].map((j) => utxo_lib_1.bip32.fromSeed(Buffer.alloc(16, `${prefix}/${i}/${j}`), utxolib.networks.bitcoin)));
/**
 *
 * Calls `callback` with a variety of signed txs, based on input parameters
 * Callback arguments are
 *   inputType, inputCount, outputType, txs
 *  where `txs` implements `forEach()`
 *
 * @param inputTypes - input types to test
 * @param nInputKeyTriplets - number of different input key triples to cycle through
 * @param outputTypes - output types to test
 * @param nOutputKeyTriplets - number of different output key triplets to cycle through
 * @param callback
 */
const runSignedTransactions = ({ inputTypes, nInputKeyTriplets, outputTypes, nOutputKeyTriplets, }, callback) => {
    const inputKeyTriplets = getKeyTriplets('test/input/', nInputKeyTriplets);
    const outputKeyTriplets = getKeyTriplets('test/output/', nOutputKeyTriplets);
    const outputValue = 1e8;
    inputTypes.forEach(({ inputType, count: inputCount }) => {
        const inputTxs = inputKeyTriplets.map((inputKeys) => {
            const unspents = [...Array(inputCount)].map(() => createUnspent(inputKeys.map((key) => key.publicKey), inputType, outputValue));
            const inputTx = createInputTx(unspents, outputValue);
            return { inputKeys, unspents, inputTx };
        });
        outputTypes.forEach((outputType) => {
            const outputs = outputKeyTriplets.map((outputKeys) => (0, exports.createScriptPubKey)(outputKeys, outputType));
            const txs = {
                forEach(cb) {
                    inputTxs.forEach(({ inputKeys, unspents, inputTx }) => {
                        outputs.forEach((scriptPubKey) => {
                            const txBuilder = utxolib.bitgo.createTransactionBuilderForNetwork(utxolib.networks.bitcoin);
                            inputTx.outs.forEach((v, i) => txBuilder.addInput(inputTx, i));
                            txBuilder.addOutput(scriptPubKey, outputValue);
                            unspents.forEach((unspent, i) => {
                                signInput(txBuilder, i, inputKeys, unspent);
                            });
                            cb(txBuilder.build());
                        });
                    });
                },
            };
            callback(inputType, inputCount, outputType, txs);
        });
    });
};
exports.runSignedTransactions = runSignedTransactions;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhHZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3NpZ25lZFR4L3R4R2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxzREFBc0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUV0RCx5REFBMkM7QUFDM0MsOENBQXdEO0FBQ3hELG9EQUF1QjtBQUN2QiwrQkFBNkI7QUFDN0IsbUNBQXVDO0FBQ3ZDLDRDQU9zQjtBQVV0QixTQUFTLGFBQWEsQ0FBQyxPQUFpQixFQUFFLFNBQWlCLEVBQUUsS0FBYTtJQUN4RSxJQUFJLGVBQWUsQ0FBQztJQUNwQixNQUFNLFVBQVUsR0FBRyxTQUFTLEtBQUsscUJBQXFCLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2xGLElBQUksVUFBVSxLQUFLLCtCQUFtQixFQUFFLENBQUM7UUFDdkMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7U0FBTSxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDcEUsZUFBZSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM1RixDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLGVBQWU7UUFDbEIsS0FBSztRQUNMLFNBQVMsRUFBRSxVQUFVO0tBQ3RCLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0ksTUFBTSxrQkFBa0IsR0FBRyxDQUFDLElBQXNCLEVB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LENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7NEJBQzdGLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBTSxFQUFFLENBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDNUUsU0FBUyxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUM7NEJBQy9DLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0NBQzlCLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQzs0QkFDOUMsQ0FBQyxDQUFDLENBQUM7NEJBRUgsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO3dCQUN4QixDQUFDLENBQUMsQ0FBQztvQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDO2FBQ0YsQ0FBQztZQUVGLFFBQVEsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRTRDLHNEQUFxQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudCAqL1xuXG5pbXBvcnQgKiBhcyB1dHhvbGliIGZyb20gJ0BiaXRnby91dHhvLWxpYic7XG5pbXBvcnQgeyBiaXAzMiwgQklQMzJJbnRlcmZhY2UgfSBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCAnbG9kYXNoLmNvbWJpbmF0aW9ucyc7XG5pbXBvcnQgeyBEaW1lbnNpb25zIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7XG4gIElucHV0U2NyaXB0VHlwZSxcbiAgVGVzdFVuc3BlbnRUeXBlLFxuICBVbnNwZW50VHlwZU9wUmV0dXJuLFxuICBVbnNwZW50VHlwZVAyc2hQMnBrLFxuICBVbnNwZW50VHlwZVB1YktleUhhc2gsXG4gIFVuc3BlbnRUeXBlU2NyaXB0Mm9mMyxcbn0gZnJvbSAnLi4vdGVzdHV0aWxzJztcblxuaW50ZXJmYWNlIElVbnNwZW50IHtcbiAgc2NyaXB0UHViS2V5OiBCdWZmZXI7XG4gIHJlZGVlbVNjcmlwdD86IEJ1ZmZlcjtcbiAgd2l0bmVzc1NjcmlwdD86IEJ1ZmZlcjtcbiAgdmFsdWU6IG51bWJlcjtcbiAgaW5wdXRUeXBlOiB1dHhvbGliLmJpdGdvLm91dHB1dFNjcmlwdHMuU2NyaXB0VHlwZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVW5zcGVudChwdWJrZXlzOiBCdWZmZXJbXSwgaW5wdXRUeXBlOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIpOiBJVW5zcGVudCB7XG4gIGxldCBzcGVuZGFibGVTY3JpcHQ7XG4gIGNvbnN0IHNjcmlwdFR5cGUgPSBpbnB1dFR5cGUgPT09ICd0YXByb290S2V5UGF0aFNwZW5kJyA/ICdwMnRyTXVzaWcyJyA6IGlucHV0VHlwZTtcbiAgaWYgKHNjcmlwdFR5cGUgPT09IFVuc3BlbnRUeXBlUDJzaFAycGspIHtcbiAgICBzcGVuZGFibGVTY3JpcHQgPSB1dHhvbGliLmJpdGdvLm91dHB1dFNjcmlwdHMuY3JlYXRlT3V0cHV0U2NyaXB0UDJzaFAycGsocHVia2V5c1swXSk7XG4gIH0gZWxzZSBpZiAodXR4b2xpYi5iaXRnby5vdXRwdXRTY3JpcHRzLmlzU2NyaXB0VHlwZTJPZjMoc2NyaXB0VHlwZSkpIHtcbiAgICBzcGVuZGFibGVTY3JpcHQgPSB1dHhvbGliLmJpdGdvLm91dHB1dFNjcmlwdHMuY3JlYXRlT3V0cHV0U2NyaXB0Mm9mMyhwdWJrZXlzLCBzY3JpcHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgaW5wdXRUeXBlICR7c2NyaXB0VHlwZX1gKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4uc3BlbmRhYmxlU2NyaXB0LFxuICAgIHZhbHVlLFxuICAgIGlucHV0VHlwZTogc2NyaXB0VHlwZSxcbiAgfTtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIGtleXMgLSBQdWJrZXlzIHRvIHVzZSBmb3IgZ2VuZXJhdGluZyB0aGUgYWRkcmVzcy5cbiAqICAgICAgICAgICAgICAgSWYgdW5zcGVudFR5cGUgaXMgb25lIG9mIFVuc3BlbnRUeXBlUHViS2V5SGFzaCBpcyB1c2VkLCB0aGUgZmlyc3Qga2V5IHdpbGwgYmUgdXNlZC5cbiAqIEBwYXJhbSB1bnNwZW50VHlwZSB7U3RyaW5nfSAtIG9uZSBvZiBVbnNwZW50VHlwZVNjcmlwdDJvZjMgb3IgVW5zcGVudFR5cGVQdWJLZXlIYXNoXG4gKiBAcmV0dXJuIHtTdHJpbmd9IGFkZHJlc3NcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVNjcmlwdFB1YktleSA9IChrZXlzOiBCSVAzMkludGVyZmFjZVtdLCB1bnNwZW50VHlwZTogVGVzdFVuc3BlbnRUeXBlKTogQnVmZmVyID0+IHtcbiAgY29uc3QgcHVia2V5cyA9IGtleXMubWFwKChrZXkpID0+IGtleS5wdWJsaWNLZXkpO1xuICBpZiAodHlwZW9mIHVuc3BlbnRUeXBlID09PSAnc3RyaW5nJyAmJiB1bnNwZW50VHlwZSBpbiBVbnNwZW50VHlwZVNjcmlwdDJvZjMpIHtcbiAgICByZXR1cm4gY3JlYXRlVW5zcGVudChwdWJrZXlzLCB1bnNwZW50VHlwZSwgMCkuc2NyaXB0UHViS2V5O1xuICB9XG5cbiAgY29uc3QgcGtIYXNoID0gdXR4b2xpYi5jcnlwdG8uaGFzaDE2MChwdWJrZXlzWzBdKTtcbiAgc3dpdGNoICh1bnNwZW50VHlwZSkge1xuICAgIGNhc2UgVW5zcGVudFR5cGVQdWJLZXlIYXNoLnAycGtoOlxuICAgICAgcmV0dXJuIHV0eG9saWIucGF5bWVudHMucDJwa2goeyBoYXNoOiBwa0hhc2ggfSkub3V0cHV0ITtcbiAgICBjYXNlIFVuc3BlbnRUeXBlUHViS2V5SGFzaC5wMndwa2g6XG4gICAgICByZXR1cm4gdXR4b2xpYi5wYXltZW50cy5wMndwa2goeyBoYXNoOiBwa0hhc2ggfSkub3V0cHV0ITtcbiAgfVxuXG4gIGlmICh1bnNwZW50VHlwZSBpbnN0YW5jZW9mIFVuc3BlbnRUeXBlT3BSZXR1cm4pIHtcbiAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmFsbG9jKHVuc3BlbnRUeXBlLnNpemUpLmZpbGwocHVia2V5c1swXSk7XG4gICAgcmV0dXJuIHV0eG9saWIuc2NyaXB0LmNvbXBpbGUoWzB4NmEsIHBheWxvYWRdKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgb3V0cHV0IHR5cGUgJHt1bnNwZW50VHlwZX1gKTtcbn07XG5cbmNvbnN0IGNyZWF0ZUlucHV0VHggPSAodW5zcGVudHM6IGFueVtdLCBpbnB1dFZhbHVlOiBudW1iZXIpID0+IHtcbiAgY29uc3QgdHhJbnB1dEJ1aWxkZXIgPSBuZXcgdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb25CdWlsZGVyKHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gIHR4SW5wdXRCdWlsZGVyLmFkZElucHV0KEFycmF5KDMyKS5maWxsKCcwMScpLmpvaW4oJycpLCAwKTtcbiAgdW5zcGVudHMuZm9yRWFjaCgoeyBzY3JpcHRQdWJLZXkgfSkgPT4gdHhJbnB1dEJ1aWxkZXIuYWRkT3V0cHV0KHNjcmlwdFB1YktleSwgaW5wdXRWYWx1ZSkpO1xuICByZXR1cm4gdHhJbnB1dEJ1aWxkZXIuYnVpbGRJbmNvbXBsZXRlKCk7XG59O1xuXG5mdW5jdGlvbiBzaWduSW5wdXQoXG4gIHR4QnVpbGRlcjogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBpbmRleDogbnVtYmVyLFxuICB3YWxsZXRLZXlzOiBCSVAzMkludGVyZmFjZVtdLFxuICB1bnNwZW50OiBJVW5zcGVudCxcbiAgc2lnbktleXM6IEJJUDMySW50ZXJmYWNlW10gPSB1bnNwZW50LmlucHV0VHlwZSA9PT0gJ3Ayc2hQMnBrJyA/IFt3YWxsZXRLZXlzWzBdXSA6IFt3YWxsZXRLZXlzWzBdLCB3YWxsZXRLZXlzWzJdXVxuKSB7XG4gIHNpZ25LZXlzLmZvckVhY2goKGtleVBhaXIpID0+IHtcbiAgICBpZiAodW5zcGVudC5pbnB1dFR5cGUgPT09ICdwMnNoUDJwaycpIHtcbiAgICAgIHV0eG9saWIuYml0Z28uc2lnbklucHV0UDJzaFAycGsodHhCdWlsZGVyLCBpbmRleCwga2V5UGFpcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzaWduS2V5cy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHNpZ25LZXlzIGxlbmd0aGApO1xuICAgICAgfVxuICAgICAgY29uc3QgY29zaWduZXIgPSBrZXlQYWlyID09PSBzaWduS2V5c1swXSA/IHNpZ25LZXlzWzFdIDogc2lnbktleXNbMF07XG4gICAgICB1dHhvbGliLmJpdGdvLnNpZ25JbnB1dDJPZjMoXG4gICAgICAgIHR4QnVpbGRlcixcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIHVuc3BlbnQuaW5wdXRUeXBlLFxuICAgICAgICB3YWxsZXRLZXlzLm1hcCgoaykgPT4gay5wdWJsaWNLZXkpIGFzIHV0eG9saWIuYml0Z28uVHJpcGxlPEJ1ZmZlcj4sXG4gICAgICAgIGtleVBhaXIsXG4gICAgICAgIGNvc2lnbmVyLnB1YmxpY0tleSxcbiAgICAgICAgdW5zcGVudC52YWx1ZVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xufVxuXG5jbGFzcyBUeENvbWJvIHtcbiAgcHVibGljIHVuc3BlbnRzOiBJVW5zcGVudFtdO1xuICBwdWJsaWMgaW5wdXRUeDogYW55O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB3YWxsZXRLZXlzOiBCSVAzMkludGVyZmFjZVtdLFxuICAgIHB1YmxpYyBpbnB1dFR5cGVzOiBzdHJpbmdbXSxcbiAgICBwdWJsaWMgb3V0cHV0VHlwZXM6IFRlc3RVbnNwZW50VHlwZVtdLFxuICAgIHB1YmxpYyBleHBlY3RlZERpbXM6IFJlYWRvbmx5PERpbWVuc2lvbnM+ID0gRGltZW5zaW9ucy5aRVJPLFxuICAgIHB1YmxpYyBzaWduS2V5cz86IEJJUDMySW50ZXJmYWNlW10sXG4gICAgcHVibGljIGlucHV0VmFsdWU6IG51bWJlciA9IDEwXG4gICkge1xuICAgIHRoaXMudW5zcGVudHMgPSBpbnB1dFR5cGVzLm1hcCgoaW5wdXRUeXBlKSA9PlxuICAgICAgY3JlYXRlVW5zcGVudChcbiAgICAgICAgd2FsbGV0S2V5cy5tYXAoKGtleSkgPT4ga2V5LnB1YmxpY0tleSksXG4gICAgICAgIGlucHV0VHlwZSxcbiAgICAgICAgdGhpcy5pbnB1dFZhbHVlXG4gICAgICApXG4gICAgKTtcbiAgICB0aGlzLmlucHV0VHggPSBjcmVhdGVJbnB1dFR4KHRoaXMudW5zcGVudHMsIGlucHV0VmFsdWUpO1xuICB9XG5cbiAgcHVibGljIGdldEJ1aWxkZXJXaXRoVW5zaWduZWRUeCgpOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbkJ1aWxkZXIge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25CdWlsZGVyRm9yTmV0d29yayh1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgIHRoaXMuaW5wdXRUeC5vdXRzLmZvckVhY2goKHt9LCBpOiBudW1iZXIpID0+IHR4QnVpbGRlci5hZGRJbnB1dCh0aGlzLmlucHV0VHgsIGkpKTtcbiAgICB0aGlzLm91dHB1dFR5cGVzLmZvckVhY2goKHVuc3BlbnRUeXBlKSA9PlxuICAgICAgdHhCdWlsZGVyLmFkZE91dHB1dChjcmVhdGVTY3JpcHRQdWJLZXkodGhpcy53YWxsZXRLZXlzLCB1bnNwZW50VHlwZSksIHRoaXMuaW5wdXRWYWx1ZSlcbiAgICApO1xuICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gIH1cblxuICBwdWJsaWMgZ2V0VW5zaWduZWRUeCgpOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QnVpbGRlcldpdGhVbnNpZ25lZFR4KCkuYnVpbGRJbmNvbXBsZXRlKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0U2lnbmVkVHgoKTogdXR4b2xpYi5UcmFuc2FjdGlvbiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gdGhpcy5nZXRCdWlsZGVyV2l0aFVuc2lnbmVkVHgoKTtcbiAgICB0aGlzLnVuc3BlbnRzLmZvckVhY2goKHVuc3BlbnQsIGkpID0+IHtcbiAgICAgIHNpZ25JbnB1dCh0eEJ1aWxkZXIsIGksIHRoaXMud2FsbGV0S2V5cywgdW5zcGVudCwgdGhpcy5zaWduS2V5cyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHR4QnVpbGRlci5idWlsZCgpO1xuICB9XG59XG5cbmNvbnN0IHJ1bkNvbWJpbmF0aW9ucyA9IChcbiAge1xuICAgIGlucHV0VHlwZXMsXG4gICAgbWF4TklucHV0cyxcbiAgICBvdXRwdXRUeXBlcyxcbiAgICBtYXhOT3V0cHV0cyxcbiAgfToge1xuICAgIGlucHV0VHlwZXM6IElucHV0U2NyaXB0VHlwZVtdO1xuICAgIG1heE5JbnB1dHM6IG51bWJlcjtcbiAgICBvdXRwdXRUeXBlczogVGVzdFVuc3BlbnRUeXBlW107XG4gICAgbWF4Tk91dHB1dHM6IG51bWJlcjtcbiAgfSxcbiAgY2FsbGJhY2s6IChpbnB1dENvbWJvOiBJbnB1dFNjcmlwdFR5cGVbXSwgb3V0cHV0Q29tYm86IFRlc3RVbnNwZW50VHlwZVtdKSA9PiB2b2lkXG4pOiB2b2lkID0+IHtcbiAgLy8gQ3JlYXRlIGNvbWJpbmF0aW9ucyBvZiBkaWZmZXJlbnQgaW5wdXQgYW5kIG91dHB1dCB0eXBlcy4gTGVuZ3RoIGJldHdlZW4gMSBhbmQgMy5cbiAgY29uc3QgaW5wdXRDb21iaW5hdGlvbnMgPSBfLmZsYXR0ZW4oXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIFsuLi5BcnJheShtYXhOSW5wdXRzKV0ubWFwKChfXywgaSkgPT4gXy5jb21iaW5hdGlvbnMoaW5wdXRUeXBlcywgaSArIDEpKVxuICApO1xuICBjb25zdCBvdXRwdXRDb21iaW5hdGlvbnMgPSBfLmZsYXR0ZW4oXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIFsuLi5BcnJheShtYXhOT3V0cHV0cyldLm1hcCgoX18sIGkpID0+IF8uY29tYmluYXRpb25zKG91dHB1dFR5cGVzLCBpICsgMSkpXG4gICk7XG5cbiAgaW5wdXRDb21iaW5hdGlvbnMuZm9yRWFjaCgoaW5wdXRUeXBlQ29tYm8pID0+XG4gICAgb3V0cHV0Q29tYmluYXRpb25zLmZvckVhY2goKG91dHB1dFR5cGVDb21ibykgPT4ge1xuICAgICAgY2FsbGJhY2soaW5wdXRUeXBlQ29tYm8sIG91dHB1dFR5cGVDb21ibyk7XG4gICAgfSlcbiAgKTtcbn07XG5cbmNsYXNzIEhpc3RvZ3JhbSB7XG4gIHB1YmxpYyB0b3RhbCA9IDA7XG5cbiAgY29uc3RydWN0b3IocHVibGljIG1hcDogTWFwPG51bWJlciwgbnVtYmVyPiA9IG5ldyBNYXAoKSkge31cblxuICBwdWJsaWMgYWRkKHNpemU6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubWFwLnNldChzaXplLCAodGhpcy5tYXAuZ2V0KHNpemUpIHx8IDApICsgMSk7XG4gICAgdGhpcy50b3RhbCsrO1xuICB9XG5cbiAgcHVibGljIGFzU29ydGVkQXJyYXkoKTogbnVtYmVyW11bXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLm1hcC5lbnRyaWVzKCldLnNvcnQoKFthXSwgW2JdKSA9PiBhIC0gYik7XG4gIH1cblxuICBwdWJsaWMgYXNGdWxsU29ydGVkQXJyYXkoKTogbnVtYmVyW11bXSB7XG4gICAgcmV0dXJuIF8ucmFuZ2UodGhpcy5nZXRQZXJjZW50aWxlKDApLCB0aGlzLmdldFBlcmNlbnRpbGUoMSkpLm1hcCgodikgPT4gW3YsIHRoaXMubWFwLmdldCh2KSB8fCAwXSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGVyY2VudGlsZShwOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICgwID4gcCB8fCBwID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBwIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxYCk7XG4gICAgfVxuXG4gICAgbGV0IHN1bSA9IDA7XG4gICAgZm9yIChjb25zdCBbaywgdl0gb2YgdGhpcy5hc1NvcnRlZEFycmF5KCkpIHtcbiAgICAgIHN1bSArPSB2O1xuICAgICAgaWYgKHN1bSAvIHRoaXMudG90YWwgPj0gcCkge1xuICAgICAgICByZXR1cm4gaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCBmaW5kIHBlcmNlbnRpbGUnKTtcbiAgfVxuXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IGtleXMgPSBbLi4udGhpcy5tYXAua2V5cygpXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gICAgcmV0dXJuIGBbJHtrZXlzLm1hcCgoaykgPT4gYFske2t9LCAke3RoaXMubWFwLmdldChrKX1dYCkuam9pbignICcpfV1gO1xuICB9XG59XG5cbmNvbnN0IGdldEtleVRyaXBsZXRzID0gKHByZWZpeDogc3RyaW5nLCBjb3VudDogbnVtYmVyKSA9PlxuICBbLi4uQXJyYXkoY291bnQpXS5tYXAoKHYsIGkpID0+XG4gICAgWzEsIDIsIDNdLm1hcCgoaikgPT4gYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmFsbG9jKDE2LCBgJHtwcmVmaXh9LyR7aX0vJHtqfWApLCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pKVxuICApO1xuXG4vKipcbiAqXG4gKiBDYWxscyBgY2FsbGJhY2tgIHdpdGggYSB2YXJpZXR5IG9mIHNpZ25lZCB0eHMsIGJhc2VkIG9uIGlucHV0IHBhcmFtZXRlcnNcbiAqIENhbGxiYWNrIGFyZ3VtZW50cyBhcmVcbiAqICAgaW5wdXRUeXBlLCBpbnB1dENvdW50LCBvdXRwdXRUeXBlLCB0eHNcbiAqICB3aGVyZSBgdHhzYCBpbXBsZW1lbnRzIGBmb3JFYWNoKClgXG4gKlxuICogQHBhcmFtIGlucHV0VHlwZXMgLSBpbnB1dCB0eXBlcyB0byB0ZXN0XG4gKiBAcGFyYW0gbklucHV0S2V5VHJpcGxldHMgLSBudW1iZXIgb2YgZGlmZmVyZW50IGlucHV0IGtleSB0cmlwbGVzIHRvIGN5Y2xlIHRocm91Z2hcbiAqIEBwYXJhbSBvdXRwdXRUeXBlcyAtIG91dHB1dCB0eXBlcyB0byB0ZXN0XG4gKiBAcGFyYW0gbk91dHB1dEtleVRyaXBsZXRzIC0gbnVtYmVyIG9mIGRpZmZlcmVudCBvdXRwdXQga2V5IHRyaXBsZXRzIHRvIGN5Y2xlIHRocm91Z2hcbiAqIEBwYXJhbSBjYWxsYmFja1xuICovXG5jb25zdCBydW5TaWduZWRUcmFuc2FjdGlvbnMgPSAoXG4gIHtcbiAgICBpbnB1dFR5cGVzLFxuICAgIG5JbnB1dEtleVRyaXBsZXRzLFxuICAgIG91dHB1dFR5cGVzLFxuICAgIG5PdXRwdXRLZXlUcmlwbGV0cyxcbiAgfToge1xuICAgIGlucHV0VHlwZXM6IEFycmF5PHsgaW5wdXRUeXBlOiBzdHJpbmc7IGNvdW50OiBudW1iZXIgfT47XG4gICAgbklucHV0S2V5VHJpcGxldHM6IG51bWJlcjtcbiAgICBvdXRwdXRUeXBlczogVGVzdFVuc3BlbnRUeXBlW107XG4gICAgbk91dHB1dEtleVRyaXBsZXRzOiBudW1iZXI7XG4gIH0sXG4gIGNhbGxiYWNrOiAoaW5wdXRUeXBlOiBzdHJpbmcsIGlucHV0Q291bnQ6IG51bWJlciwgb3V0cHV0VHlwZTogVGVzdFVuc3BlbnRUeXBlLCB0eHM6IGFueSkgPT4gdm9pZFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IGlucHV0S2V5VHJpcGxldHMgPSBnZXRLZXlUcmlwbGV0cygndGVzdC9pbnB1dC8nLCBuSW5wdXRLZXlUcmlwbGV0cyk7XG4gIGNvbnN0IG91dHB1dEtleVRyaXBsZXRzID0gZ2V0S2V5VHJpcGxldHMoJ3Rlc3Qvb3V0cHV0LycsIG5PdXRwdXRLZXlUcmlwbGV0cyk7XG4gIGNvbnN0IG91dHB1dFZhbHVlID0gMWU4O1xuXG4gIGlucHV0VHlwZXMuZm9yRWFjaCgoeyBpbnB1dFR5cGUsIGNvdW50OiBpbnB1dENvdW50IH0pID0+IHtcbiAgICBjb25zdCBpbnB1dFR4cyA9IGlucHV0S2V5VHJpcGxldHMubWFwKChpbnB1dEtleXMpID0+IHtcbiAgICAgIGNvbnN0IHVuc3BlbnRzID0gWy4uLkFycmF5KGlucHV0Q291bnQpXS5tYXAoKCkgPT5cbiAgICAgICAgY3JlYXRlVW5zcGVudChcbiAgICAgICAgICBpbnB1dEtleXMubWFwKChrZXkpID0+IGtleS5wdWJsaWNLZXkpLFxuICAgICAgICAgIGlucHV0VHlwZSxcbiAgICAgICAgICBvdXRwdXRWYWx1ZVxuICAgICAgICApXG4gICAgICApO1xuICAgICAgY29uc3QgaW5wdXRUeCA9IGNyZWF0ZUlucHV0VHgodW5zcGVudHMsIG91dHB1dFZhbHVlKTtcbiAgICAgIHJldHVybiB7IGlucHV0S2V5cywgdW5zcGVudHMsIGlucHV0VHggfTtcbiAgICB9KTtcblxuICAgIG91dHB1dFR5cGVzLmZvckVhY2goKG91dHB1dFR5cGUpID0+IHtcbiAgICAgIGNvbnN0IG91dHB1dHMgPSBvdXRwdXRLZXlUcmlwbGV0cy5tYXAoKG91dHB1dEtleXMpID0+IGNyZWF0ZVNjcmlwdFB1YktleShvdXRwdXRLZXlzLCBvdXRwdXRUeXBlKSk7XG5cbiAgICAgIGNvbnN0IHR4cyA9IHtcbiAgICAgICAgZm9yRWFjaChjYjogKHR4OiB1dHhvbGliLlRyYW5zYWN0aW9uKSA9PiB2b2lkKSB7XG4gICAgICAgICAgaW5wdXRUeHMuZm9yRWFjaCgoeyBpbnB1dEtleXMsIHVuc3BlbnRzLCBpbnB1dFR4IH0pID0+IHtcbiAgICAgICAgICAgIG91dHB1dHMuZm9yRWFjaCgoc2NyaXB0UHViS2V5KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25CdWlsZGVyRm9yTmV0d29yayh1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgICAgICAgICBpbnB1dFR4Lm91dHMuZm9yRWFjaCgodjogYW55LCBpOiBudW1iZXIpID0+IHR4QnVpbGRlci5hZGRJbnB1dChpbnB1dFR4LCBpKSk7XG4gICAgICAgICAgICAgIHR4QnVpbGRlci5hZGRPdXRwdXQoc2NyaXB0UHViS2V5LCBvdXRwdXRWYWx1ZSk7XG4gICAgICAgICAgICAgIHVuc3BlbnRzLmZvckVhY2goKHVuc3BlbnQsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBzaWduSW5wdXQodHhCdWlsZGVyLCBpLCBpbnB1dEtleXMsIHVuc3BlbnQpO1xuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYih0eEJ1aWxkZXIuYnVpbGQoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNhbGxiYWNrKGlucHV0VHlwZSwgaW5wdXRDb3VudCwgb3V0cHV0VHlwZSwgdHhzKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgeyBUeENvbWJvLCBIaXN0b2dyYW0sIHJ1bkNvbWJpbmF0aW9ucywgcnVuU2lnbmVkVHJhbnNhY3Rpb25zIH07XG4iXX0=

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


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