PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/utxo-lib/dist/src/bitgo/wallet

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPsbtBip32DerivationOutputUpdate = getPsbtBip32DerivationOutputUpdate;
exports.getPsbtOutputUpdateFromPsbtOutput = getPsbtOutputUpdateFromPsbtOutput;
exports.getPsbtOutputUpdate = getPsbtOutputUpdate;
exports.updateWalletOutputForPsbt = updateWalletOutputForPsbt;
exports.addWalletOutputToPsbt = addWalletOutputToPsbt;
exports.getScriptIdFromOutput = getScriptIdFromOutput;
const assert_1 = require("assert");
const bitcoinjs_lib_1 = require("bitcoinjs-lib");
const chains_1 = require("./chains");
const ScriptId_1 = require("./ScriptId");
const outputScripts_1 = require("../outputScripts");
/**
 * Get the BIP32 derivation data for a PSBT output.
 *
 * @param rootWalletKeys root wallet keys used for master fingerprints
 * @param walletKeys derived wallet keys for the specific chain and index
 * @param scriptType the script type to determine whether to use regular or taproot derivation
 * @param payment optional payment object for taproot scripts to calculate leaf hashes
 * @returns Object containing BIP32 derivation data
 */
function getPsbtBip32DerivationOutputUpdate(rootWalletKeys, walletKeys, scriptType, payment) {
    const update = {};
    if (scriptType === 'p2tr' || scriptType === 'p2trMusig2') {
        if (!payment || !payment.redeems) {
            throw new Error('Payment object with redeems is required for taproot derivation');
        }
        const allLeafHashes = payment.redeems.map((r) => bitcoinjs_lib_1.taproot.hashTapLeaf(r.output));
        update.tapBip32Derivation = [0, 1, 2].map((idx) => {
            const pubkey = (0, outputScripts_1.toXOnlyPublicKey)(walletKeys.triple[idx].publicKey);
            const leafHashes = [];
            (0, assert_1.ok)(payment.redeems);
            payment.redeems.forEach((r, redeemIdx) => {
                if (r.pubkeys.find((pk) => pk.equals(pubkey))) {
                    leafHashes.push(allLeafHashes[redeemIdx]);
                }
            });
            return {
                leafHashes,
                pubkey,
                path: walletKeys.paths[idx],
                masterFingerprint: rootWalletKeys.triple[idx].fingerprint,
            };
        });
    }
    else {
        update.bip32Derivation = [0, 1, 2].map((idx) => ({
            pubkey: walletKeys.triple[idx].publicKey,
            path: walletKeys.paths[idx],
            masterFingerprint: rootWalletKeys.triple[idx].fingerprint,
        }));
    }
    return update;
}
/**
 * Get the PSBT output update object from a PSBT output and output script.
 *
 * @param output the PSBT output to get update for
 * @param outputScript the output script
 * @param rootWalletKeys keys that will be able to spend the output
 * @param chain chain code to use for deriving scripts (and to determine script type)
 * @param index derivation index for the change address
 * @returns PsbtOutputUpdate object with the required information
 */
function getPsbtOutputUpdateFromPsbtOutput(output, outputScript, rootWalletKeys, chain, index) {
    const walletKeys = rootWalletKeys.deriveForChainAndIndex(chain, index);
    const scriptType = (0, chains_1.scriptTypeForChain)(chain);
    const update = {};
    if (scriptType === 'p2tr' || scriptType === 'p2trMusig2') {
        const payment = scriptType === 'p2tr' ? (0, outputScripts_1.createPaymentP2tr)(walletKeys.publicKeys) : (0, outputScripts_1.createPaymentP2trMusig2)(walletKeys.publicKeys);
        if (!payment.output || !payment.output.equals(outputScript)) {
            throw new Error(`cannot update a p2tr output where the scripts do not match - Failing.`);
        }
        if (!output.tapTree) {
            update.tapTree = payment.tapTree;
        }
        if (!output.tapInternalKey) {
            update.tapInternalKey = payment.internalPubkey;
        }
        if (!output.tapBip32Derivation) {
            const derivationUpdate = getPsbtBip32DerivationOutputUpdate(rootWalletKeys, walletKeys, scriptType, payment);
            update.tapBip32Derivation = derivationUpdate.tapBip32Derivation;
        }
    }
    else {
        const { scriptPubKey, witnessScript, redeemScript } = (0, outputScripts_1.createOutputScript2of3)(walletKeys.publicKeys, scriptType);
        if (!scriptPubKey.equals(outputScript)) {
            throw new Error(`cannot update an output where the scripts do not match - Failing.`);
        }
        if (!output.bip32Derivation) {
            const derivationUpdate = getPsbtBip32DerivationOutputUpdate(rootWalletKeys, walletKeys, scriptType);
            update.bip32Derivation = derivationUpdate.bip32Derivation;
        }
        if (!output.witnessScript && witnessScript) {
            update.witnessScript = witnessScript;
        }
        if (!output.redeemScript && redeemScript) {
            update.redeemScript = redeemScript;
        }
    }
    return update;
}
/**
 * Get the PSBT output update object with the required information.
 *
 * @param psbt the PSBT to get output update for
 * @param rootWalletKeys keys that will be able to spend the output
 * @param outputIndex output index where to update the output
 * @param chain chain code to use for deriving scripts (and to determine script
 *              type) chain is an API parameter in the BitGo API, and may be
 *              any valid ChainCode
 * @param index derivation index for the change address
 * @returns PsbtOutputUpdate object with the required information
 */
function getPsbtOutputUpdate(psbt, rootWalletKeys, outputIndex, chain, index) {
    if (psbt.data.outputs.length <= outputIndex) {
        throw new Error(`outputIndex (${outputIndex}) is too large for the number of outputs (${psbt.data.outputs.length})`);
    }
    const outputScript = psbt.getOutputScript(outputIndex);
    const output = psbt.data.outputs[outputIndex];
    return getPsbtOutputUpdateFromPsbtOutput(output, outputScript, rootWalletKeys, chain, index);
}
/**
 * Update the wallet output with the required information when necessary. If the
 * information is there already, it will skip over it.
 *
 * This function assumes that the output script and value have already been set.
 *
 * @param psbt the PSBT to update change output at
 * @param rootWalletKeys keys that will be able to spend the output
 * @param outputIndex output index where to update the output
 * @param chain chain code to use for deriving scripts (and to determine script
 *              type) chain is an API parameter in the BitGo API, and may be
 *              any valid ChainCode
 * @param index derivation index for the change address
 */
function updateWalletOutputForPsbt(psbt, rootWalletKeys, outputIndex, chain, index) {
    psbt.updateOutput(outputIndex, getPsbtOutputUpdate(psbt, rootWalletKeys, outputIndex, chain, index));
}
/**
 * Add a verifiable wallet output to the PSBT. The output and all data
 * needed to verify it from public keys only are added to the PSBT.
 * Typically these are change outputs.
 *
 * @param psbt the PSBT to add change output to
 * @param rootWalletKeys keys that will be able to spend the output
 * @param chain chain code to use for deriving scripts (and to determine script
 *              type) chain is an API parameter in the BitGo API, and may be
 *              any valid ChainCode
 * @param index derivation index for the change address
 * @param value value of the change output
 */
function addWalletOutputToPsbt(psbt, rootWalletKeys, chain, index, value) {
    const walletKeys = rootWalletKeys.deriveForChainAndIndex(chain, index);
    const scriptType = (0, chains_1.scriptTypeForChain)(chain);
    if (scriptType === 'p2tr' || scriptType === 'p2trMusig2') {
        const payment = scriptType === 'p2tr' ? (0, outputScripts_1.createPaymentP2tr)(walletKeys.publicKeys) : (0, outputScripts_1.createPaymentP2trMusig2)(walletKeys.publicKeys);
        psbt.addOutput({ script: payment.output, value });
    }
    else {
        const { scriptPubKey: script } = (0, outputScripts_1.createOutputScript2of3)(walletKeys.publicKeys, scriptType);
        psbt.addOutput({ script, value });
    }
    updateWalletOutputForPsbt(psbt, rootWalletKeys, psbt.data.outputs.length - 1, chain, index);
}
/**
 * Fold the script ids into a single script id, if they are all the same.
 * @param scriptIds
 */
function foldScriptIds(scriptIds) {
    if (scriptIds.length === 0) {
        throw new Error('cannot fold empty script ids');
    }
    scriptIds.forEach((scriptId, i) => {
        if (scriptId.chain !== scriptIds[0].chain) {
            throw new Error(`chain mismatch: ${scriptId.chain} != ${scriptIds[0].chain}`);
        }
        if (scriptId.index !== scriptIds[0].index) {
            throw new Error(`index mismatch: ${scriptId.index} != ${scriptIds[0].index}`);
        }
    });
    return scriptIds[0];
}
/**
 * Get the script id from the output.
 * The output can have either bip32Derivation or tapBip32Derivation, but not both.
 * @param output
 * @throws Error if neither or both bip32Derivation and tapBip32Derivation are present
 * @throws Error if the output is empty
 * @throws Error if we cannot fold the script ids into a single script id
 */
function getScriptIdFromOutput(output) {
    if (output.bip32Derivation && output.tapBip32Derivation) {
        throw new Error('cannot get script id from output with both bip32Derivation and tapBip32Derivation');
    }
    if (output.bip32Derivation) {
        return foldScriptIds(output.bip32Derivation.map((d) => (0, ScriptId_1.getScriptIdFromPath)(d.path)));
    }
    if (output.tapBip32Derivation) {
        return foldScriptIds(output.tapBip32Derivation.map((d) => (0, ScriptId_1.getScriptIdFromPath)(d.path)));
    }
    throw new Error('cannot get script id from output without bip32Derivation or tapBip32Derivation');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2FsbGV0T3V0cHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3dhbGxldC9XYWxsZXRPdXRwdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFtQkEsZ0ZBMENDO0FBWUQsOEVBaURDO0FBY0Qsa0RBaUJDO0FBZ0JELDhEQVFDO0FBZUQsc0RBa0JDO0FBNkJELHNEQWNDO0FBN1BELG1DQUFzQztBQUV0QyxpREFBaUQ7QUFJakQscUNBQXlEO0FBQ3pELHlDQUEyRDtBQUMzRCxvREFBd0g7QUFFeEg7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQixrQ0FBa0MsQ0FDaEQsY0FBOEIsRUFDOUIsVUFBNkIsRUFDN0IsVUFBa0IsRUFDbEIsT0FBaUI7SUFFakIsTUFBTSxNQUFNLEdBQXFCLEVBQUUsQ0FBQztJQUVwQyxJQUFJLFVBQVUsS0FBSyxNQUFNLElBQUksVUFBVSxLQUFLLFlBQVksRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO1FBQ3BGLENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsdUJBQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU8sQ0FBQyxDQUFDLENBQUM7UUFFakYsTUFBTSxDQUFDLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNoRCxNQUFNLE1BQU0sR0FBRyxJQUFBLGdDQUFnQixFQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEUsTUFBTSxVQUFVLEdBQWEsRUFBRSxDQUFDO1lBRWhDLElBQUEsV0FBTSxFQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN4QixPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxTQUFpQixFQUFFLEVBQUU7Z0JBQ3BELElBQUksQ0FBQyxDQUFDLE9BQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUN2RCxVQUFVLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPO2dCQUNMLFVBQVU7Z0JBQ1YsTUFBTTtnQkFDTixJQUFJLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7Z0JBQzNCLGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVzthQUMxRCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMvQyxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTO1lBQ3hDLElBQUksRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztZQUMzQixpQkFBaUIsRUFBRSxjQUFjLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVc7U0FDMUQsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLGlDQUFpQyxDQUMvQyxNQUFrQixFQUNsQixZQUFvQixFQUNwQixjQUE4QixFQUM5QixLQUFnQixFQUNoQixLQUFhO0lBRWIsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RSxNQUFNLFVBQVUsR0FBRyxJQUFBLDJCQUFrQixFQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLE1BQU0sTUFBTSxHQUFxQixFQUFFLENBQUM7SUFFcEMsSUFBSSxVQUFVLEtBQUssTUFBTSxJQUFJLFVBQVUsS0FBSyxZQUFZLEVBQUUsQ0FBQztRQUN6RCxNQUFNLE9BQU8sR0FDWCxVQUFVLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFBLGlDQUFpQixFQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBQSx1Q0FBdUIsRUFBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDcEgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQzVELE1BQU0sSUFBSSxLQUFLLENBQUMsdUVBQXVFLENBQUMsQ0FBQztRQUMzRixDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixNQUFNLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDM0IsTUFBTSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQ2pELENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDL0IsTUFBTSxnQkFBZ0IsR0FBRyxrQ0FBa0MsQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM3RyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUM7UUFDbEUsQ0FBQztJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLEdBQUcsSUFBQSxzQ0FBc0IsRUFBQyxVQUFVLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2hILElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDdkMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtRUFBbUUsQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzVCLE1BQU0sZ0JBQWdCLEdBQUcsa0NBQWtDLENBQUMsY0FBYyxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNwRyxNQUFNLENBQUMsZUFBZSxHQUFHLGdCQUFnQixDQUFDLGVBQWUsQ0FBQztRQUM1RCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLElBQUksYUFBYSxFQUFFLENBQUM7WUFDM0MsTUFBTSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDdkMsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ3JDLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0IsbUJBQW1CLENBQ2pDLElBQWMsRUFDZCxjQUE4QixFQUM5QixXQUFtQixFQUNuQixLQUFnQixFQUNoQixLQUFhO0lBRWIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksV0FBVyxFQUFFLENBQUM7UUFDNUMsTUFBTSxJQUFJLEtBQUssQ0FDYixnQkFBZ0IsV0FBVyw2Q0FBNkMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQ3BHLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN2RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUU5QyxPQUFPLGlDQUFpQyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUMvRixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQWdCLHlCQUF5QixDQUN2QyxJQUFjLEVBQ2QsY0FBOEIsRUFDOUIsV0FBbUIsRUFDbkIsS0FBZ0IsRUFDaEIsS0FBYTtJQUViLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLG1CQUFtQixDQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3ZHLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixxQkFBcUIsQ0FDbkMsSUFBYyxFQUNkLGNBQThCLEVBQzlCLEtBQWdCLEVBQ2hCLEtBQWEsRUFDYixLQUFhO0lBRWIsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RSxNQUFNLFVBQVUsR0FBRyxJQUFBLDJCQUFrQixFQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLElBQUksVUFBVSxLQUFLLE1BQU0sSUFBSSxVQUFVLEtBQUssWUFBWSxFQUFFLENBQUM7UUFDekQsTUFBTSxPQUFPLEdBQ1gsVUFBVSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBQSxpQ0FBaUIsRUFBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUEsdUNBQXVCLEVBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BILElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFBLHNDQUFzQixFQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDM0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCx5QkFBeUIsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzlGLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGFBQWEsQ0FBQyxTQUFxQjtJQUMxQyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2hDLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsUUFBUSxDQUFDLEtBQUssT0FBTyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNoRixDQUFDO1FBQ0QsSUFBSSxRQUFRLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixRQUFRLENBQUMsS0FBSyxPQUFPLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IscUJBQXFCLENBQUMsTUFHckM7SUFDQyxJQUFJLE1BQU0sQ0FBQyxlQUFlLElBQUksTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDeEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxtRkFBbUYsQ0FBQyxDQUFDO0lBQ3ZHLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUMzQixPQUFPLGFBQWEsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBQSw4QkFBbUIsRUFBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzlCLE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUEsOEJBQW1CLEVBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxnRkFBZ0YsQ0FBQyxDQUFDO0FBQ3BHLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBvayBhcyBhc3NlcnQgfSBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgeyBQYXltZW50LCB0YXByb290IH0gZnJvbSAnYml0Y29pbmpzLWxpYic7XG5pbXBvcnQgeyBQc2J0T3V0cHV0LCBQc2J0T3V0cHV0VXBkYXRlIH0gZnJvbSAnYmlwMTc0L3NyYy9saWIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBVdHhvUHNidCB9IGZyb20gJy4uL1V0eG9Qc2J0JztcbmltcG9ydCB7IFJvb3RXYWxsZXRLZXlzLCBEZXJpdmVkV2FsbGV0S2V5cyB9IGZyb20gJy4vV2FsbGV0S2V5cyc7XG5pbXBvcnQgeyBDaGFpbkNvZGUsIHNjcmlwdFR5cGVGb3JDaGFpbiB9IGZyb20gJy4vY2hhaW5zJztcbmltcG9ydCB7IGdldFNjcmlwdElkRnJvbVBhdGgsIFNjcmlwdElkIH0gZnJvbSAnLi9TY3JpcHRJZCc7XG5pbXBvcnQgeyBjcmVhdGVPdXRwdXRTY3JpcHQyb2YzLCBjcmVhdGVQYXltZW50UDJ0ciwgY3JlYXRlUGF5bWVudFAydHJNdXNpZzIsIHRvWE9ubHlQdWJsaWNLZXkgfSBmcm9tICcuLi9vdXRwdXRTY3JpcHRzJztcblxuLyoqXG4gKiBHZXQgdGhlIEJJUDMyIGRlcml2YXRpb24gZGF0YSBmb3IgYSBQU0JUIG91dHB1dC5cbiAqXG4gKiBAcGFyYW0gcm9vdFdhbGxldEtleXMgcm9vdCB3YWxsZXQga2V5cyB1c2VkIGZvciBtYXN0ZXIgZmluZ2VycHJpbnRzXG4gKiBAcGFyYW0gd2FsbGV0S2V5cyBkZXJpdmVkIHdhbGxldCBrZXlzIGZvciB0aGUgc3BlY2lmaWMgY2hhaW4gYW5kIGluZGV4XG4gKiBAcGFyYW0gc2NyaXB0VHlwZSB0aGUgc2NyaXB0IHR5cGUgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gdXNlIHJlZ3VsYXIgb3IgdGFwcm9vdCBkZXJpdmF0aW9uXG4gKiBAcGFyYW0gcGF5bWVudCBvcHRpb25hbCBwYXltZW50IG9iamVjdCBmb3IgdGFwcm9vdCBzY3JpcHRzIHRvIGNhbGN1bGF0ZSBsZWFmIGhhc2hlc1xuICogQHJldHVybnMgT2JqZWN0IGNvbnRhaW5pbmcgQklQMzIgZGVyaXZhdGlvbiBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQc2J0QmlwMzJEZXJpdmF0aW9uT3V0cHV0VXBkYXRlKFxuICByb290V2FsbGV0S2V5czogUm9vdFdhbGxldEtleXMsXG4gIHdhbGxldEtleXM6IERlcml2ZWRXYWxsZXRLZXlzLFxuICBzY3JpcHRUeXBlOiBzdHJpbmcsXG4gIHBheW1lbnQ/OiBQYXltZW50XG4pOiBQc2J0T3V0cHV0VXBkYXRlIHtcbiAgY29uc3QgdXBkYXRlOiBQc2J0T3V0cHV0VXBkYXRlID0ge307XG5cbiAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnRyJyB8fCBzY3JpcHRUeXBlID09PSAncDJ0ck11c2lnMicpIHtcbiAgICBpZiAoIXBheW1lbnQgfHwgIXBheW1lbnQucmVkZWVtcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXltZW50IG9iamVjdCB3aXRoIHJlZGVlbXMgaXMgcmVxdWlyZWQgZm9yIHRhcHJvb3QgZGVyaXZhdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGFsbExlYWZIYXNoZXMgPSBwYXltZW50LnJlZGVlbXMubWFwKChyKSA9PiB0YXByb290Lmhhc2hUYXBMZWFmKHIub3V0cHV0ISkpO1xuXG4gICAgdXBkYXRlLnRhcEJpcDMyRGVyaXZhdGlvbiA9IFswLCAxLCAyXS5tYXAoKGlkeCkgPT4ge1xuICAgICAgY29uc3QgcHVia2V5ID0gdG9YT25seVB1YmxpY0tleSh3YWxsZXRLZXlzLnRyaXBsZVtpZHhdLnB1YmxpY0tleSk7XG4gICAgICBjb25zdCBsZWFmSGFzaGVzOiBCdWZmZXJbXSA9IFtdO1xuXG4gICAgICBhc3NlcnQocGF5bWVudC5yZWRlZW1zKTtcbiAgICAgIHBheW1lbnQucmVkZWVtcy5mb3JFYWNoKChyOiBhbnksIHJlZGVlbUlkeDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmIChyLnB1YmtleXMhLmZpbmQoKHBrOiBCdWZmZXIpID0+IHBrLmVxdWFscyhwdWJrZXkpKSkge1xuICAgICAgICAgIGxlYWZIYXNoZXMucHVzaChhbGxMZWFmSGFzaGVzW3JlZGVlbUlkeF0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbGVhZkhhc2hlcyxcbiAgICAgICAgcHVia2V5LFxuICAgICAgICBwYXRoOiB3YWxsZXRLZXlzLnBhdGhzW2lkeF0sXG4gICAgICAgIG1hc3RlckZpbmdlcnByaW50OiByb290V2FsbGV0S2V5cy50cmlwbGVbaWR4XS5maW5nZXJwcmludCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLmJpcDMyRGVyaXZhdGlvbiA9IFswLCAxLCAyXS5tYXAoKGlkeCkgPT4gKHtcbiAgICAgIHB1YmtleTogd2FsbGV0S2V5cy50cmlwbGVbaWR4XS5wdWJsaWNLZXksXG4gICAgICBwYXRoOiB3YWxsZXRLZXlzLnBhdGhzW2lkeF0sXG4gICAgICBtYXN0ZXJGaW5nZXJwcmludDogcm9vdFdhbGxldEtleXMudHJpcGxlW2lkeF0uZmluZ2VycHJpbnQsXG4gICAgfSkpO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFBTQlQgb3V0cHV0IHVwZGF0ZSBvYmplY3QgZnJvbSBhIFBTQlQgb3V0cHV0IGFuZCBvdXRwdXQgc2NyaXB0LlxuICpcbiAqIEBwYXJhbSBvdXRwdXQgdGhlIFBTQlQgb3V0cHV0IHRvIGdldCB1cGRhdGUgZm9yXG4gKiBAcGFyYW0gb3V0cHV0U2NyaXB0IHRoZSBvdXRwdXQgc2NyaXB0XG4gKiBAcGFyYW0gcm9vdFdhbGxldEtleXMga2V5cyB0aGF0IHdpbGwgYmUgYWJsZSB0byBzcGVuZCB0aGUgb3V0cHV0XG4gKiBAcGFyYW0gY2hhaW4gY2hhaW4gY29kZSB0byB1c2UgZm9yIGRlcml2aW5nIHNjcmlwdHMgKGFuZCB0byBkZXRlcm1pbmUgc2NyaXB0IHR5cGUpXG4gKiBAcGFyYW0gaW5kZXggZGVyaXZhdGlvbiBpbmRleCBmb3IgdGhlIGNoYW5nZSBhZGRyZXNzXG4gKiBAcmV0dXJucyBQc2J0T3V0cHV0VXBkYXRlIG9iamVjdCB3aXRoIHRoZSByZXF1aXJlZCBpbmZvcm1hdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHNidE91dHB1dFVwZGF0ZUZyb21Qc2J0T3V0cHV0KFxuICBvdXRwdXQ6IFBzYnRPdXRwdXQsXG4gIG91dHB1dFNjcmlwdDogQnVmZmVyLFxuICByb290V2FsbGV0S2V5czogUm9vdFdhbGxldEtleXMsXG4gIGNoYWluOiBDaGFpbkNvZGUsXG4gIGluZGV4OiBudW1iZXJcbik6IFBzYnRPdXRwdXRVcGRhdGUge1xuICBjb25zdCB3YWxsZXRLZXlzID0gcm9vdFdhbGxldEtleXMuZGVyaXZlRm9yQ2hhaW5BbmRJbmRleChjaGFpbiwgaW5kZXgpO1xuICBjb25zdCBzY3JpcHRUeXBlID0gc2NyaXB0VHlwZUZvckNoYWluKGNoYWluKTtcbiAgY29uc3QgdXBkYXRlOiBQc2J0T3V0cHV0VXBkYXRlID0ge307XG5cbiAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnRyJyB8fCBzY3JpcHRUeXBlID09PSAncDJ0ck11c2lnMicpIHtcbiAgICBjb25zdCBwYXltZW50ID1cbiAgICAgIHNjcmlwdFR5cGUgPT09ICdwMnRyJyA/IGNyZWF0ZVBheW1lbnRQMnRyKHdhbGxldEtleXMucHVibGljS2V5cykgOiBjcmVhdGVQYXltZW50UDJ0ck11c2lnMih3YWxsZXRLZXlzLnB1YmxpY0tleXMpO1xuICAgIGlmICghcGF5bWVudC5vdXRwdXQgfHwgIXBheW1lbnQub3V0cHV0LmVxdWFscyhvdXRwdXRTY3JpcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCB1cGRhdGUgYSBwMnRyIG91dHB1dCB3aGVyZSB0aGUgc2NyaXB0cyBkbyBub3QgbWF0Y2ggLSBGYWlsaW5nLmApO1xuICAgIH1cblxuICAgIGlmICghb3V0cHV0LnRhcFRyZWUpIHtcbiAgICAgIHVwZGF0ZS50YXBUcmVlID0gcGF5bWVudC50YXBUcmVlO1xuICAgIH1cbiAgICBpZiAoIW91dHB1dC50YXBJbnRlcm5hbEtleSkge1xuICAgICAgdXBkYXRlLnRhcEludGVybmFsS2V5ID0gcGF5bWVudC5pbnRlcm5hbFB1YmtleTtcbiAgICB9XG5cbiAgICBpZiAoIW91dHB1dC50YXBCaXAzMkRlcml2YXRpb24pIHtcbiAgICAgIGNvbnN0IGRlcml2YXRpb25VcGRhdGUgPSBnZXRQc2J0QmlwMzJEZXJpdmF0aW9uT3V0cHV0VXBkYXRlKHJvb3RXYWxsZXRLZXlzLCB3YWxsZXRLZXlzLCBzY3JpcHRUeXBlLCBwYXltZW50KTtcbiAgICAgIHVwZGF0ZS50YXBCaXAzMkRlcml2YXRpb24gPSBkZXJpdmF0aW9uVXBkYXRlLnRhcEJpcDMyRGVyaXZhdGlvbjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgeyBzY3JpcHRQdWJLZXksIHdpdG5lc3NTY3JpcHQsIHJlZGVlbVNjcmlwdCB9ID0gY3JlYXRlT3V0cHV0U2NyaXB0Mm9mMyh3YWxsZXRLZXlzLnB1YmxpY0tleXMsIHNjcmlwdFR5cGUpO1xuICAgIGlmICghc2NyaXB0UHViS2V5LmVxdWFscyhvdXRwdXRTY3JpcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCB1cGRhdGUgYW4gb3V0cHV0IHdoZXJlIHRoZSBzY3JpcHRzIGRvIG5vdCBtYXRjaCAtIEZhaWxpbmcuYCk7XG4gICAgfVxuXG4gICAgaWYgKCFvdXRwdXQuYmlwMzJEZXJpdmF0aW9uKSB7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uVXBkYXRlID0gZ2V0UHNidEJpcDMyRGVyaXZhdGlvbk91dHB1dFVwZGF0ZShyb290V2FsbGV0S2V5cywgd2FsbGV0S2V5cywgc2NyaXB0VHlwZSk7XG4gICAgICB1cGRhdGUuYmlwMzJEZXJpdmF0aW9uID0gZGVyaXZhdGlvblVwZGF0ZS5iaXAzMkRlcml2YXRpb247XG4gICAgfVxuXG4gICAgaWYgKCFvdXRwdXQud2l0bmVzc1NjcmlwdCAmJiB3aXRuZXNzU2NyaXB0KSB7XG4gICAgICB1cGRhdGUud2l0bmVzc1NjcmlwdCA9IHdpdG5lc3NTY3JpcHQ7XG4gICAgfVxuICAgIGlmICghb3V0cHV0LnJlZGVlbVNjcmlwdCAmJiByZWRlZW1TY3JpcHQpIHtcbiAgICAgIHVwZGF0ZS5yZWRlZW1TY3JpcHQgPSByZWRlZW1TY3JpcHQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFBTQlQgb3V0cHV0IHVwZGF0ZSBvYmplY3Qgd2l0aCB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHBzYnQgdGhlIFBTQlQgdG8gZ2V0IG91dHB1dCB1cGRhdGUgZm9yXG4gKiBAcGFyYW0gcm9vdFdhbGxldEtleXMga2V5cyB0aGF0IHdpbGwgYmUgYWJsZSB0byBzcGVuZCB0aGUgb3V0cHV0XG4gKiBAcGFyYW0gb3V0cHV0SW5kZXggb3V0cHV0IGluZGV4IHdoZXJlIHRvIHVwZGF0ZSB0aGUgb3V0cHV0XG4gKiBAcGFyYW0gY2hhaW4gY2hhaW4gY29kZSB0byB1c2UgZm9yIGRlcml2aW5nIHNjcmlwdHMgKGFuZCB0byBkZXRlcm1pbmUgc2NyaXB0XG4gKiAgICAgICAgICAgICAgdHlwZSkgY2hhaW4gaXMgYW4gQVBJIHBhcmFtZXRlciBpbiB0aGUgQml0R28gQVBJLCBhbmQgbWF5IGJlXG4gKiAgICAgICAgICAgICAgYW55IHZhbGlkIENoYWluQ29kZVxuICogQHBhcmFtIGluZGV4IGRlcml2YXRpb24gaW5kZXggZm9yIHRoZSBjaGFuZ2UgYWRkcmVzc1xuICogQHJldHVybnMgUHNidE91dHB1dFVwZGF0ZSBvYmplY3Qgd2l0aCB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBzYnRPdXRwdXRVcGRhdGUoXG4gIHBzYnQ6IFV0eG9Qc2J0LFxuICByb290V2FsbGV0S2V5czogUm9vdFdhbGxldEtleXMsXG4gIG91dHB1dEluZGV4OiBudW1iZXIsXG4gIGNoYWluOiBDaGFpbkNvZGUsXG4gIGluZGV4OiBudW1iZXJcbik6IFBzYnRPdXRwdXRVcGRhdGUge1xuICBpZiAocHNidC5kYXRhLm91dHB1dHMubGVuZ3RoIDw9IG91dHB1dEluZGV4KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYG91dHB1dEluZGV4ICgke291dHB1dEluZGV4fSkgaXMgdG9vIGxhcmdlIGZvciB0aGUgbnVtYmVyIG9mIG91dHB1dHMgKCR7cHNidC5kYXRhLm91dHB1dHMubGVuZ3RofSlgXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dFNjcmlwdCA9IHBzYnQuZ2V0T3V0cHV0U2NyaXB0KG91dHB1dEluZGV4KTtcbiAgY29uc3Qgb3V0cHV0ID0gcHNidC5kYXRhLm91dHB1dHNbb3V0cHV0SW5kZXhdO1xuXG4gIHJldHVybiBnZXRQc2J0T3V0cHV0VXBkYXRlRnJvbVBzYnRPdXRwdXQob3V0cHV0LCBvdXRwdXRTY3JpcHQsIHJvb3RXYWxsZXRLZXlzLCBjaGFpbiwgaW5kZXgpO1xufVxuXG4vKipcbiAqIFVwZGF0ZSB0aGUgd2FsbGV0IG91dHB1dCB3aXRoIHRoZSByZXF1aXJlZCBpbmZvcm1hdGlvbiB3aGVuIG5lY2Vzc2FyeS4gSWYgdGhlXG4gKiBpbmZvcm1hdGlvbiBpcyB0aGVyZSBhbHJlYWR5LCBpdCB3aWxsIHNraXAgb3ZlciBpdC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgb3V0cHV0IHNjcmlwdCBhbmQgdmFsdWUgaGF2ZSBhbHJlYWR5IGJlZW4gc2V0LlxuICpcbiAqIEBwYXJhbSBwc2J0IHRoZSBQU0JUIHRvIHVwZGF0ZSBjaGFuZ2Ugb3V0cHV0IGF0XG4gKiBAcGFyYW0gcm9vdFdhbGxldEtleXMga2V5cyB0aGF0IHdpbGwgYmUgYWJsZSB0byBzcGVuZCB0aGUgb3V0cHV0XG4gKiBAcGFyYW0gb3V0cHV0SW5kZXggb3V0cHV0IGluZGV4IHdoZXJlIHRvIHVwZGF0ZSB0aGUgb3V0cHV0XG4gKiBAcGFyYW0gY2hhaW4gY2hhaW4gY29kZSB0byB1c2UgZm9yIGRlcml2aW5nIHNjcmlwdHMgKGFuZCB0byBkZXRlcm1pbmUgc2NyaXB0XG4gKiAgICAgICAgICAgICAgdHlwZSkgY2hhaW4gaXMgYW4gQVBJIHBhcmFtZXRlciBpbiB0aGUgQml0R28gQVBJLCBhbmQgbWF5IGJlXG4gKiAgICAgICAgICAgICAgYW55IHZhbGlkIENoYWluQ29kZVxuICogQHBhcmFtIGluZGV4IGRlcml2YXRpb24gaW5kZXggZm9yIHRoZSBjaGFuZ2UgYWRkcmVzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlV2FsbGV0T3V0cHV0Rm9yUHNidChcbiAgcHNidDogVXR4b1BzYnQsXG4gIHJvb3RXYWxsZXRLZXlzOiBSb290V2FsbGV0S2V5cyxcbiAgb3V0cHV0SW5kZXg6IG51bWJlcixcbiAgY2hhaW46IENoYWluQ29kZSxcbiAgaW5kZXg6IG51bWJlclxuKTogdm9pZCB7XG4gIHBzYnQudXBkYXRlT3V0cHV0KG91dHB1dEluZGV4LCBnZXRQc2J0T3V0cHV0VXBkYXRlKHBzYnQsIHJvb3RXYWxsZXRLZXlzLCBvdXRwdXRJbmRleCwgY2hhaW4sIGluZGV4KSk7XG59XG5cbi8qKlxuICogQWRkIGEgdmVyaWZpYWJsZSB3YWxsZXQgb3V0cHV0IHRvIHRoZSBQU0JULiBUaGUgb3V0cHV0IGFuZCBhbGwgZGF0YVxuICogbmVlZGVkIHRvIHZlcmlmeSBpdCBmcm9tIHB1YmxpYyBrZXlzIG9ubHkgYXJlIGFkZGVkIHRvIHRoZSBQU0JULlxuICogVHlwaWNhbGx5IHRoZXNlIGFyZSBjaGFuZ2Ugb3V0cHV0cy5cbiAqXG4gKiBAcGFyYW0gcHNidCB0aGUgUFNCVCB0byBhZGQgY2hhbmdlIG91dHB1dCB0b1xuICogQHBhcmFtIHJvb3RXYWxsZXRLZXlzIGtleXMgdGhhdCB3aWxsIGJlIGFibGUgdG8gc3BlbmQgdGhlIG91dHB1dFxuICogQHBhcmFtIGNoYWluIGNoYWluIGNvZGUgdG8gdXNlIGZvciBkZXJpdmluZyBzY3JpcHRzIChhbmQgdG8gZGV0ZXJtaW5lIHNjcmlwdFxuICogICAgICAgICAgICAgIHR5cGUpIGNoYWluIGlzIGFuIEFQSSBwYXJhbWV0ZXIgaW4gdGhlIEJpdEdvIEFQSSwgYW5kIG1heSBiZVxuICogICAgICAgICAgICAgIGFueSB2YWxpZCBDaGFpbkNvZGVcbiAqIEBwYXJhbSBpbmRleCBkZXJpdmF0aW9uIGluZGV4IGZvciB0aGUgY2hhbmdlIGFkZHJlc3NcbiAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSBvZiB0aGUgY2hhbmdlIG91dHB1dFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkV2FsbGV0T3V0cHV0VG9Qc2J0KFxuICBwc2J0OiBVdHhvUHNidCxcbiAgcm9vdFdhbGxldEtleXM6IFJvb3RXYWxsZXRLZXlzLFxuICBjaGFpbjogQ2hhaW5Db2RlLFxuICBpbmRleDogbnVtYmVyLFxuICB2YWx1ZTogYmlnaW50XG4pOiB2b2lkIHtcbiAgY29uc3Qgd2FsbGV0S2V5cyA9IHJvb3RXYWxsZXRLZXlzLmRlcml2ZUZvckNoYWluQW5kSW5kZXgoY2hhaW4sIGluZGV4KTtcbiAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbik7XG4gIGlmIChzY3JpcHRUeXBlID09PSAncDJ0cicgfHwgc2NyaXB0VHlwZSA9PT0gJ3AydHJNdXNpZzInKSB7XG4gICAgY29uc3QgcGF5bWVudCA9XG4gICAgICBzY3JpcHRUeXBlID09PSAncDJ0cicgPyBjcmVhdGVQYXltZW50UDJ0cih3YWxsZXRLZXlzLnB1YmxpY0tleXMpIDogY3JlYXRlUGF5bWVudFAydHJNdXNpZzIod2FsbGV0S2V5cy5wdWJsaWNLZXlzKTtcbiAgICBwc2J0LmFkZE91dHB1dCh7IHNjcmlwdDogcGF5bWVudC5vdXRwdXQhLCB2YWx1ZSB9KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB7IHNjcmlwdFB1YktleTogc2NyaXB0IH0gPSBjcmVhdGVPdXRwdXRTY3JpcHQyb2YzKHdhbGxldEtleXMucHVibGljS2V5cywgc2NyaXB0VHlwZSk7XG4gICAgcHNidC5hZGRPdXRwdXQoeyBzY3JpcHQsIHZhbHVlIH0pO1xuICB9XG4gIHVwZGF0ZVdhbGxldE91dHB1dEZvclBzYnQocHNidCwgcm9vdFdhbGxldEtleXMsIHBzYnQuZGF0YS5vdXRwdXRzLmxlbmd0aCAtIDEsIGNoYWluLCBpbmRleCk7XG59XG5cbi8qKlxuICogRm9sZCB0aGUgc2NyaXB0IGlkcyBpbnRvIGEgc2luZ2xlIHNjcmlwdCBpZCwgaWYgdGhleSBhcmUgYWxsIHRoZSBzYW1lLlxuICogQHBhcmFtIHNjcmlwdElkc1xuICovXG5mdW5jdGlvbiBmb2xkU2NyaXB0SWRzKHNjcmlwdElkczogU2NyaXB0SWRbXSk6IFNjcmlwdElkIHtcbiAgaWYgKHNjcmlwdElkcy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBmb2xkIGVtcHR5IHNjcmlwdCBpZHMnKTtcbiAgfVxuICBzY3JpcHRJZHMuZm9yRWFjaCgoc2NyaXB0SWQsIGkpID0+IHtcbiAgICBpZiAoc2NyaXB0SWQuY2hhaW4gIT09IHNjcmlwdElkc1swXS5jaGFpbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjaGFpbiBtaXNtYXRjaDogJHtzY3JpcHRJZC5jaGFpbn0gIT0gJHtzY3JpcHRJZHNbMF0uY2hhaW59YCk7XG4gICAgfVxuICAgIGlmIChzY3JpcHRJZC5pbmRleCAhPT0gc2NyaXB0SWRzWzBdLmluZGV4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGluZGV4IG1pc21hdGNoOiAke3NjcmlwdElkLmluZGV4fSAhPSAke3NjcmlwdElkc1swXS5pbmRleH1gKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gc2NyaXB0SWRzWzBdO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc2NyaXB0IGlkIGZyb20gdGhlIG91dHB1dC5cbiAqIFRoZSBvdXRwdXQgY2FuIGhhdmUgZWl0aGVyIGJpcDMyRGVyaXZhdGlvbiBvciB0YXBCaXAzMkRlcml2YXRpb24sIGJ1dCBub3QgYm90aC5cbiAqIEBwYXJhbSBvdXRwdXRcbiAqIEB0aHJvd3MgRXJyb3IgaWYgbmVpdGhlciBvciBib3RoIGJpcDMyRGVyaXZhdGlvbiBhbmQgdGFwQmlwMzJEZXJpdmF0aW9uIGFyZSBwcmVzZW50XG4gKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBvdXRwdXQgaXMgZW1wdHlcbiAqIEB0aHJvd3MgRXJyb3IgaWYgd2UgY2Fubm90IGZvbGQgdGhlIHNjcmlwdCBpZHMgaW50byBhIHNpbmdsZSBzY3JpcHQgaWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNjcmlwdElkRnJvbU91dHB1dChvdXRwdXQ6IHtcbiAgYmlwMzJEZXJpdmF0aW9uPzogeyBwYXRoOiBzdHJpbmcgfVtdO1xuICB0YXBCaXAzMkRlcml2YXRpb24/OiB7IHBhdGg6IHN0cmluZyB9W107XG59KTogU2NyaXB0SWQge1xuICBpZiAob3V0cHV0LmJpcDMyRGVyaXZhdGlvbiAmJiBvdXRwdXQudGFwQmlwMzJEZXJpdmF0aW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgZ2V0IHNjcmlwdCBpZCBmcm9tIG91dHB1dCB3aXRoIGJvdGggYmlwMzJEZXJpdmF0aW9uIGFuZCB0YXBCaXAzMkRlcml2YXRpb24nKTtcbiAgfVxuICBpZiAob3V0cHV0LmJpcDMyRGVyaXZhdGlvbikge1xuICAgIHJldHVybiBmb2xkU2NyaXB0SWRzKG91dHB1dC5iaXAzMkRlcml2YXRpb24ubWFwKChkKSA9PiBnZXRTY3JpcHRJZEZyb21QYXRoKGQucGF0aCkpKTtcbiAgfVxuICBpZiAob3V0cHV0LnRhcEJpcDMyRGVyaXZhdGlvbikge1xuICAgIHJldHVybiBmb2xkU2NyaXB0SWRzKG91dHB1dC50YXBCaXAzMkRlcml2YXRpb24ubWFwKChkKSA9PiBnZXRTY3JpcHRJZEZyb21QYXRoKGQucGF0aCkpKTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBnZXQgc2NyaXB0IGlkIGZyb20gb3V0cHV0IHdpdGhvdXQgYmlwMzJEZXJpdmF0aW9uIG9yIHRhcEJpcDMyRGVyaXZhdGlvbicpO1xufVxuIl19

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


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