PHP WebShell

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

Просмотр файла: dimensions.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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dimensions = exports.OutputDimensions = void 0;
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const utxo_lib_1 = require("@bitgo/utxo-lib");
const { isChainCode, scriptTypeForChain } = utxo_lib_1.bitgo;
const scriptSizes_1 = require("./scriptSizes");
const types_1 = require("./types");
const virtualSizes_1 = require("./virtualSizes");
/**
 * Apply `f` to all properties of `d`
 */
function mapDimensions(d, f) {
    return new Dimensions(Object.fromEntries(Object.entries(d).map(([key, value]) => [key, f(key, value)])));
}
/**
 * Aggregate count and size of transaction outputs
 */
class OutputDimensions {
    constructor({ count = 0, size = 0 } = { count: 0, size: 0 }) {
        if (count === 0 || size === 0) {
            if (count !== 0 || size !== 0) {
                throw new Error(`count and size must both be zero if one is zero`);
            }
        }
        this.count = count;
        this.size = size;
        Object.freeze(this);
    }
}
exports.OutputDimensions = OutputDimensions;
const defaultUnspentParams = {
    p2tr: {
        // Default to recovery script paths, to make it easier for recovery case callers (WRW etc).
        // WP can explicitly pass scriptPathLevel: 1 to use happy path.
        scriptPathLevel: 2,
    },
    p2trMusig2: {
        // Default to script path spend, to make it easier for recovery case callers (WRW etc).
        // WP can explicitly pass scriptPathLevel: undefined to use key path.
        scriptPathLevel: 1,
    },
};
/**
 * Dimensions of a BitGo wallet transactions.
 */
class Dimensions {
    constructor(d = {}) {
        /** Input counts for BitGo wallet multi-signature inputs */
        this.nP2shInputs = 0;
        this.nP2shP2wshInputs = 0;
        this.nP2wshInputs = 0;
        this.nP2trKeypathInputs = 0;
        this.nP2trScriptPathLevel1Inputs = 0;
        this.nP2trScriptPathLevel2Inputs = 0;
        /* Input count for single-signature inputs (Replay Protection inputs) */
        this.nP2shP2pkInputs = 0;
        this.outputs = new OutputDimensions();
        Object.entries(d).forEach(([key, value]) => this.setProperty(key, value));
        Object.freeze(this);
    }
    setProperty(k, v) {
        switch (k) {
            case 'nP2shInputs':
            case 'nP2shP2wshInputs':
            case 'nP2wshInputs':
            case 'nP2trKeypathInputs':
            case 'nP2trScriptPathLevel1Inputs':
            case 'nP2trScriptPathLevel2Inputs':
            case 'nP2shP2pkInputs':
                if (typeof v !== 'number') {
                    throw new Error(`property ${k} must be number`);
                }
                if (!Number.isSafeInteger(v) || v < 0) {
                    throw new Error(`property ${k} must be zero or positive integer`);
                }
                break;
            case 'outputs':
                if (!(v instanceof OutputDimensions)) {
                    v = new OutputDimensions(v);
                }
                break;
            default:
                throw new Error(`unknown property ${k}`);
        }
        this[k] = v;
    }
    /**
     * @deprecated use ZERO
     * @return Dimensions for an empty transaction
     */
    static zero() {
        return this.ZERO;
    }
    /**
     * @param size
     * @return Dimensions for a single output with given size
     */
    static singleOutput(size) {
        return Dimensions.sum({ outputs: { count: 1, size } });
    }
    /**
     * @return Number of total inputs (p2sh + p2shP2wsh + p2wsh + p2tr)
     */
    get nInputs() {
        return (this.nP2shInputs +
            this.nP2shP2wshInputs +
            this.nP2wshInputs +
            this.nP2trKeypathInputs +
            this.nP2trScriptPathLevel1Inputs +
            this.nP2trScriptPathLevel2Inputs +
            this.nP2shP2pkInputs);
    }
    set nInputs(_) {
        throw new Error('read-only property nInputs');
    }
    /**
     * @return Number of total outputs
     */
    get nOutputs() {
        return this.outputs.count;
    }
    set nOutputs(_) {
        throw new Error(`read-only property nOutputs`);
    }
    /**
     * @param args - Dimensions (can be partially defined)
     * @return {Dimensions} sum of arguments
     */
    static sum(...args) {
        return args.reduce((a, b) => a.plus(b), new Dimensions());
    }
    /**
     * @param chain
     * @return {Number}
     */
    static getOutputScriptLengthForChain(chain) {
        switch (scriptTypeForChain(chain)) {
            case 'p2wsh':
            case 'p2tr':
            case 'p2trMusig2':
                return 34;
            default:
                return 23;
        }
    }
    /**
     * @param scriptLength
     * @return {Number} vSize of an output with script length
     */
    static getVSizeForOutputWithScriptLength(scriptLength) {
        if (!types_1.PositiveInteger.is(scriptLength)) {
            throw new TypeError(`expected positive integer for scriptLength, got ${scriptLength}`);
        }
        return scriptLength + (0, scriptSizes_1.compactSize)(scriptLength) + virtualSizes_1.VirtualSizes.txOutputAmountSize;
    }
    /**
     * @return
     */
    static fromScriptType(scriptType, params = {}) {
        switch (scriptType) {
            case 'p2sh':
            case 'p2shP2wsh':
            case 'p2wsh':
            case 'p2shP2pk':
                return Dimensions.SingleInput[scriptType];
            case 'p2tr':
            case 'taprootScriptPathSpend':
                switch (params.scriptPathLevel) {
                    case 1:
                        return Dimensions.SingleInput.p2trScriptPathLevel1;
                    case 2:
                        return Dimensions.SingleInput.p2trScriptPathLevel2;
                    default:
                        throw new Error(`unexpected script path level`);
                }
            case 'p2trMusig2':
                switch (params.scriptPathLevel) {
                    case undefined:
                        return Dimensions.SingleInput.p2trKeypath;
                    case 1:
                        return Dimensions.SingleInput.p2trScriptPathLevel1;
                    default:
                        throw new Error(`unexpected script path level`);
                }
            case 'taprootKeyPathSpend':
                return Dimensions.SingleInput.p2trKeypath;
            default:
                throw new Error(`unexpected scriptType ${scriptType}`);
        }
    }
    static getAssumedDimension(params = {}, index) {
        const { assumeUnsigned } = params;
        if (!assumeUnsigned) {
            throw new Error(`illegal input ${index}: empty script and assumeUnsigned not set`);
        }
        return assumeUnsigned;
    }
    /**
     * @param input - the transaction input to count
     * @param params
     *        [param.assumeUnsigned] - default type for unsigned input
     */
    static fromInput(input, params = {}) {
        if (input.script?.length || input.witness?.length) {
            const parsed = utxolib.bitgo.parseSignatureScript(input);
            return Dimensions.fromScriptType(parsed.scriptType, parsed);
        }
        return Dimensions.getAssumedDimension(params, input.index);
    }
    /**
     * Create Dimensions from psbt input
     * @param input - psbt input
     */
    static fromPsbtInput(input) {
        const parsed = utxo_lib_1.bitgo.parsePsbtInput(input);
        return Dimensions.fromScriptType(parsed.scriptType, parsed);
    }
    /**
     * @param inputs - Array of inputs
     * @param params - @see Dimensions.fromInput()
     * @return {Dimensions} sum of the dimensions for each input (@see Dimensions.fromInput())
     */
    static fromInputs(inputs, params) {
        if (!Array.isArray(inputs)) {
            throw new TypeError(`inputs must be array`);
        }
        return Dimensions.sum(...inputs.map((i) => Dimensions.fromInput(i, params)));
    }
    /**
     * Create Dimensions from multiple psbt inputs
     * @param inputs psbt input array
     * @return {Dimensions} sum of the dimensions for each input (@see Dimensions.fromPsbtInput())
     */
    static fromPsbtInputs(inputs) {
        if (!Array.isArray(inputs)) {
            throw new TypeError(`inputs must be array`);
        }
        return Dimensions.sum(...inputs.map((input, _) => Dimensions.fromPsbtInput(input)));
    }
    /**
     * @param scriptLength {number} - size of the output script in bytes
     * @return {Dimensions} - Dimensions of the output
     */
    static fromOutputScriptLength(scriptLength) {
        return Dimensions.sum({
            outputs: {
                count: 1,
                size: Dimensions.getVSizeForOutputWithScriptLength(scriptLength),
            },
        });
    }
    /**
     * @param output - a tx output
     * @return Dimensions - the dimensions of the given output
     */
    static fromOutput({ script }) {
        if (!script) {
            throw new Error('expected output script to be defined');
        }
        if (!Buffer.isBuffer(script)) {
            throw new TypeError('expected script to be buffer, got ' + typeof script);
        }
        return Dimensions.fromOutputScriptLength(script.length);
    }
    /**
     * @param outputs - Array of outputs
     * @return {Dimensions} sum of the dimensions for each output (@see Dimensions.fromOutput())
     */
    static fromOutputs(outputs) {
        if (!Array.isArray(outputs)) {
            throw new TypeError(`outputs must be array`);
        }
        return Dimensions.sum(...outputs.map(Dimensions.fromOutput));
    }
    /**
     * Returns the dimensions of an output that will be created on a specific chain.
     * Currently, this simply adds a default output.
     *
     * @param chain - Chain code as defined by utxolib.bitgo
     * @return {Dimensions} - Dimensions for a single output on the given chain.
     */
    static fromOutputOnChain(chain) {
        return Dimensions.fromOutputScriptLength(Dimensions.getOutputScriptLengthForChain(chain));
    }
    /**
     * Return dimensions of an unspent according to `chain` parameter
     * @param chain - Chain code as defined by utxo.chain
     * @param params - Hint for unspents with variable input sizes (p2tr, p2trMusig2)
     * @return {Dimensions} of the unspent
     * @throws if the chain code is invalid or unsupported
     */
    static fromUnspent({ chain }, params = defaultUnspentParams) {
        if (!isChainCode(chain)) {
            throw new TypeError('invalid chain code');
        }
        const scriptType = scriptTypeForChain(chain);
        return Dimensions.fromScriptType(scriptType, scriptType === 'p2tr' ? params.p2tr : scriptType === 'p2trMusig2' ? params.p2trMusig2 : {});
    }
    /**
     * @param unspents
     * @param params - Hint for unspents with variable input sizes (p2tr, p2trMusig2)
     * @return {Dimensions} sum of the dimensions for each unspent (@see Dimensions.fromUnspent())
     */
    static fromUnspents(unspents, params = defaultUnspentParams) {
        if (!Array.isArray(unspents)) {
            throw new TypeError(`unspents must be array`);
        }
        // Convert the individual unspents into dimensions and sum them up
        return Dimensions.sum(...unspents.map((u) => Dimensions.fromUnspent(u, params)));
    }
    /**
     * @param transaction - bitcoin-like transaction
     * @param [param.assumeUnsigned] - default type for unsigned inputs
     * @return {Dimensions}
     */
    static fromTransaction({ ins, outs, }, params) {
        return Dimensions.fromInputs(ins, params).plus(Dimensions.fromOutputs(outs));
    }
    /**
     * Create Dimensions from psbt inputs and outputs
     * @param psbt
     * @return {Dimensions}
     */
    static fromPsbt(psbt) {
        return Dimensions.fromPsbtInputs(psbt.data.inputs).plus(Dimensions.fromOutputs(psbt.getUnsignedTx().outs));
    }
    /**
     * @param dimensions (can be partially defined)
     * @return new dimensions with argument added
     */
    plus(dimensions) {
        if (typeof dimensions !== 'object') {
            throw new TypeError(`expected argument to be object`);
        }
        if (!(dimensions instanceof Dimensions)) {
            dimensions = new Dimensions(dimensions);
        }
        // Catch instances where we try to initialize Dimensions from partial data using deprecated parameters
        // using only "nOutputs".
        if ('nOutputs' in dimensions) {
            if (!('outputs' in dimensions)) {
                throw new Error('deprecated partial addition: argument has key "nOutputs" but no "outputs"');
            }
            const { outputs, nOutputs } = dimensions;
            if (outputs.count !== nOutputs) {
                throw new Error('deprecated partial addition: inconsistent values for "nOutputs" and "outputs.count"');
            }
        }
        return mapDimensions(this, (key, v) => {
            const w = dimensions[key] ?? Dimensions.ZERO[key];
            if (key === 'outputs') {
                const vOutputs = v;
                const wOutputs = w;
                return new OutputDimensions({
                    count: vOutputs.count + wOutputs.count,
                    size: vOutputs.size + wOutputs.size,
                });
            }
            return v + w;
        });
    }
    /**
     * Multiply dimensions by a given factor
     * @param factor - Positive integer
     * @return {Dimensions}
     */
    times(factor) {
        if (!types_1.PositiveInteger.is(factor)) {
            throw new TypeError(`expected factor to be positive integer`);
        }
        return mapDimensions(this, (key, value) => {
            if (key === 'outputs') {
                const vOutputs = value;
                return {
                    count: vOutputs.count * factor,
                    size: vOutputs.size * factor,
                };
            }
            return value * factor;
        });
    }
    /**
     * @return Number of total inputs (p2sh, p2shP2wsh and p2wsh)
     * @deprecated use `dimension.nInputs` instead
     */
    getNInputs() {
        return this.nInputs;
    }
    /**
     * @returns {boolean} true iff dimensions have one or more (p2sh)p2wsh inputs
     */
    isSegwit() {
        return (this.nP2wshInputs +
            this.nP2shP2wshInputs +
            this.nP2trKeypathInputs +
            this.nP2trScriptPathLevel1Inputs +
            this.nP2trScriptPathLevel2Inputs >
            0);
    }
    /**
     * @return {Number} overhead vsize, based on result isSegwit().
     */
    getOverheadVSize() {
        return this.isSegwit() ? virtualSizes_1.VirtualSizes.txSegOverheadVSize : virtualSizes_1.VirtualSizes.txOverheadSize;
    }
    /**
     * @returns {number} vsize of inputs, without transaction overhead
     */
    getInputsVSize() {
        const { txP2shInputSize, txP2shP2wshInputSize, txP2wshInputSize, txP2trKeypathInputSize, txP2trScriptPathLevel1InputSize, txP2trScriptPathLevel2InputSize, txP2shP2pkInputSize, } = virtualSizes_1.VirtualSizes;
        const { nP2shInputs, nP2shP2wshInputs, nP2wshInputs, nP2trKeypathInputs, nP2trScriptPathLevel1Inputs, nP2trScriptPathLevel2Inputs, nP2shP2pkInputs, } = this;
        const size = nP2shInputs * txP2shInputSize +
            nP2shP2wshInputs * txP2shP2wshInputSize +
            nP2wshInputs * txP2wshInputSize +
            nP2trKeypathInputs * txP2trKeypathInputSize +
            nP2shP2pkInputs * txP2shP2pkInputSize +
            nP2trScriptPathLevel1Inputs * txP2trScriptPathLevel1InputSize +
            nP2trScriptPathLevel2Inputs * txP2trScriptPathLevel2InputSize;
        if (Number.isNaN(size)) {
            throw new Error(`invalid size`);
        }
        return size;
    }
    /**
     * @returns {number} return vsize of outputs, without overhead
     */
    getOutputsVSize() {
        return this.outputs.size;
    }
    /**
     * Estimates the virtual size (1/4 weight) of a signed transaction as sum of
     * overhead vsize, input vsize and output vsize.
     * @returns {Number} The estimated vsize of the transaction dimensions.
     */
    getVSize() {
        return this.getOverheadVSize() + this.getInputsVSize() + this.getOutputsVSize();
    }
}
exports.Dimensions = Dimensions;
Dimensions.ZERO = Object.freeze(new Dimensions());
// Initialize static properties that require the class to be fully defined first
Dimensions.SingleOutput = Object.freeze({
    p2sh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2shOutputSize),
    p2shP2wsh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2shP2wshOutputSize),
    p2wsh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2wshOutputSize),
    p2tr: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2trOutputSize),
    p2pkh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2pkhOutputSize),
    p2wpkh: Dimensions.singleOutput(virtualSizes_1.VirtualSizes.txP2wpkhOutputSize),
});
// Initialize SingleInput after the class is fully defined
Dimensions.SingleInput = Object.freeze({
    p2sh: Dimensions.sum({ nP2shInputs: 1 }),
    p2shP2wsh: Dimensions.sum({ nP2shP2wshInputs: 1 }),
    p2wsh: Dimensions.sum({ nP2wshInputs: 1 }),
    p2trKeypath: Dimensions.sum({ nP2trKeypathInputs: 1 }),
    p2trScriptPathLevel1: Dimensions.sum({ nP2trScriptPathLevel1Inputs: 1 }),
    p2trScriptPathLevel2: Dimensions.sum({ nP2trScriptPathLevel2Inputs: 1 }),
    p2shP2pk: Dimensions.sum({ nP2shP2pkInputs: 1 }),
});
// Initialize the ASSUME_ constants
Dimensions.ASSUME_P2SH = Dimensions.SingleInput.p2sh;
Dimensions.ASSUME_P2SH_P2WSH = Dimensions.SingleInput.p2shP2wsh;
Dimensions.ASSUME_P2WSH = Dimensions.SingleInput.p2wsh;
Dimensions.ASSUME_P2TR_KEYPATH = Dimensions.SingleInput.p2trKeypath;
Dimensions.ASSUME_P2TR_SCRIPTPATH_LEVEL1 = Dimensions.SingleInput.p2trScriptPathLevel1;
Dimensions.ASSUME_P2TR_SCRIPTPATH_LEVEL2 = Dimensions.SingleInput.p2trScriptPathLevel2;
Dimensions.ASSUME_P2SH_P2PK_INPUT = Dimensions.SingleInput.p2shP2pk;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGltZW5zaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaW1lbnNpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUEyQztBQUMzQyw4Q0FBd0M7QUFDeEMsTUFBTSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxHQUFHLGdCQUFLLENBQUM7QUFHbEQsK0NBQTRDO0FBQzVDLG1DQUEwQztBQUUxQyxpREFBOEM7QUFFOUM7O0dBRUc7QUFDSCxTQUFTLGFBQWEsQ0FDcEIsQ0FBc0IsRUFDdEIsQ0FBZ0Y7SUFFaEYsT0FBTyxJQUFJLFVBQVUsQ0FDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBdUIsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDdEcsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQWEsZ0JBQWdCO0lBVTNCLFlBQVksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLEtBQXVCLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO1FBQzNFLElBQUksS0FBSyxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDOUIsSUFBSSxLQUFLLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLElBQUks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QixHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDO0FBQ2hFLFVBQVUsQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7QUFDdkQsVUFBVSxDQUFDLG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBQ3BFLFVBQVUsQ0FBQyw2QkFBNkIsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO0FBQ3ZGLFVBQVUsQ0FBQyw2QkFBNkIsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO0FBQ3ZGLFVBQVUsQ0FBQyxzQkFBc0IsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IGJpdGdvIH0gZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmNvbnN0IHsgaXNDaGFpbkNvZGUsIHNjcmlwdFR5cGVGb3JDaGFpbiB9ID0gYml0Z287XG50eXBlIENoYWluQ29kZSA9IGJpdGdvLkNoYWluQ29kZTtcblxuaW1wb3J0IHsgY29tcGFjdFNpemUgfSBmcm9tICcuL3NjcmlwdFNpemVzJztcbmltcG9ydCB7IFBvc2l0aXZlSW50ZWdlciB9IGZyb20gJy4vdHlwZXMnO1xuXG5pbXBvcnQgeyBWaXJ0dWFsU2l6ZXMgfSBmcm9tICcuL3ZpcnR1YWxTaXplcyc7XG5cbi8qKlxuICogQXBwbHkgYGZgIHRvIGFsbCBwcm9wZXJ0aWVzIG9mIGBkYFxuICovXG5mdW5jdGlvbiBtYXBEaW1lbnNpb25zKFxuICBkOiBQYXJ0aWFsPERpbWVuc2lvbnM+LFxuICBmOiA8VCBleHRlbmRzIGtleW9mIERpbWVuc2lvbnM+KGtleTogVCwgdjogRGltZW5zaW9uc1tUXSB8IHVuZGVmaW5lZCkgPT4gdW5rbm93blxuKTogRGltZW5zaW9ucyB7XG4gIHJldHVybiBuZXcgRGltZW5zaW9ucyhcbiAgICBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoZCkubWFwKChba2V5LCB2YWx1ZV0pID0+IFtrZXksIGYoa2V5IGFzIGtleW9mIERpbWVuc2lvbnMsIHZhbHVlKV0pKVxuICApO1xufVxuXG4vKipcbiAqIEFnZ3JlZ2F0ZSBjb3VudCBhbmQgc2l6ZSBvZiB0cmFuc2FjdGlvbiBvdXRwdXRzXG4gKi9cbmV4cG9ydCBjbGFzcyBPdXRwdXREaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIE51bWJlciBvZiBvdXRwdXRzXG4gICAqL1xuICBjb3VudDogbnVtYmVyO1xuICAvKipcbiAgICogQWdncmVnYXRlIHZTaXplXG4gICAqL1xuICBzaXplOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoeyBjb3VudCA9IDAsIHNpemUgPSAwIH06IE91dHB1dERpbWVuc2lvbnMgPSB7IGNvdW50OiAwLCBzaXplOiAwIH0pIHtcbiAgICBpZiAoY291bnQgPT09IDAgfHwgc2l6ZSA9PT0gMCkge1xuICAgICAgaWYgKGNvdW50ICE9PSAwIHx8IHNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb3VudCBhbmQgc2l6ZSBtdXN0IGJvdGggYmUgemVybyBpZiBvbmUgaXMgemVyb2ApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY291bnQgPSBjb3VudDtcbiAgICB0aGlzLnNpemUgPSBzaXplO1xuXG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxufVxuXG5pbnRlcmZhY2UgRnJvbUlucHV0UGFyYW1zIHtcbiAgLy8gSW4gY2FzZXMgd2hlcmUgdGhlIGlucHV0IHR5cGUgaXMgYW1iaWd1b3VzLCB3ZSBtdXN0IHByb3ZpZGUgYSBoaW50IGFib3V0IHNwZW5kIHNjcmlwdCB0eXBlLlxuICBhc3N1bWVVbnNpZ25lZD86IERpbWVuc2lvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRnJvbVVuc3BlbnRQYXJhbXMge1xuICBwMnRyOiB7XG4gICAgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyO1xuICB9O1xuICBwMnRyTXVzaWcyOiB7XG4gICAgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyO1xuICB9O1xufVxuXG5jb25zdCBkZWZhdWx0VW5zcGVudFBhcmFtczogRnJvbVVuc3BlbnRQYXJhbXMgPSB7XG4gIHAydHI6IHtcbiAgICAvLyBEZWZhdWx0IHRvIHJlY292ZXJ5IHNjcmlwdCBwYXRocywgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIHJlY292ZXJ5IGNhc2UgY2FsbGVycyAoV1JXIGV0YykuXG4gICAgLy8gV1AgY2FuIGV4cGxpY2l0bHkgcGFzcyBzY3JpcHRQYXRoTGV2ZWw6IDEgdG8gdXNlIGhhcHB5IHBhdGguXG4gICAgc2NyaXB0UGF0aExldmVsOiAyLFxuICB9LFxuICBwMnRyTXVzaWcyOiB7XG4gICAgLy8gRGVmYXVsdCB0byBzY3JpcHQgcGF0aCBzcGVuZCwgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIHJlY292ZXJ5IGNhc2UgY2FsbGVycyAoV1JXIGV0YykuXG4gICAgLy8gV1AgY2FuIGV4cGxpY2l0bHkgcGFzcyBzY3JpcHRQYXRoTGV2ZWw6IHVuZGVmaW5lZCB0byB1c2Uga2V5IHBhdGguXG4gICAgc2NyaXB0UGF0aExldmVsOiAxLFxuICB9LFxufTtcblxuLyoqXG4gKiBEaW1lbnNpb25zIG9mIGEgQml0R28gd2FsbGV0IHRyYW5zYWN0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIERpbWVuc2lvbnMge1xuICAvKiogSW5wdXQgY291bnRzIGZvciBCaXRHbyB3YWxsZXQgbXVsdGktc2lnbmF0dXJlIGlucHV0cyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgblAyc2hJbnB1dHM6IG51bWJlciA9IDA7XG4gIHB1YmxpYyByZWFkb25seSBuUDJzaFAyd3NoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAyd3NoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJLZXlwYXRoSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgcmVhZG9ubHkgblAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRzOiBudW1iZXIgPSAwO1xuXG4gIC8qIElucHV0IGNvdW50IGZvciBzaW5nbGUtc2lnbmF0dXJlIGlucHV0cyAoUmVwbGF5IFByb3RlY3Rpb24gaW5wdXRzKSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgblAyc2hQMnBrSW5wdXRzOiBudW1iZXIgPSAwO1xuXG4gIHB1YmxpYyByZWFkb25seSBvdXRwdXRzOiBPdXRwdXREaW1lbnNpb25zID0gbmV3IE91dHB1dERpbWVuc2lvbnMoKTtcblxuICBjb25zdHJ1Y3RvcihkOiBQYXJ0aWFsPERpbWVuc2lvbnM+ID0ge30pIHtcbiAgICBPYmplY3QuZW50cmllcyhkKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHRoaXMuc2V0UHJvcGVydHkoa2V5LCB2YWx1ZSkpO1xuXG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UHJvcGVydHkoazogc3RyaW5nLCB2OiB1bmtub3duKTogdm9pZCB7XG4gICAgc3dpdGNoIChrKSB7XG4gICAgICBjYXNlICduUDJzaElucHV0cyc6XG4gICAgICBjYXNlICduUDJzaFAyd3NoSW5wdXRzJzpcbiAgICAgIGNhc2UgJ25QMndzaElucHV0cyc6XG4gICAgICBjYXNlICduUDJ0cktleXBhdGhJbnB1dHMnOlxuICAgICAgY2FzZSAnblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzJzpcbiAgICAgIGNhc2UgJ25QMnRyU2NyaXB0UGF0aExldmVsMklucHV0cyc6XG4gICAgICBjYXNlICduUDJzaFAycGtJbnB1dHMnOlxuICAgICAgICBpZiAodHlwZW9mIHYgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcm9wZXJ0eSAke2t9IG11c3QgYmUgbnVtYmVyYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2KSB8fCB2IDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgcHJvcGVydHkgJHtrfSBtdXN0IGJlIHplcm8gb3IgcG9zaXRpdmUgaW50ZWdlcmApO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb3V0cHV0cyc6XG4gICAgICAgIGlmICghKHYgaW5zdGFuY2VvZiBPdXRwdXREaW1lbnNpb25zKSkge1xuICAgICAgICAgIHYgPSBuZXcgT3V0cHV0RGltZW5zaW9ucyh2IGFzIE91dHB1dERpbWVuc2lvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3duIHByb3BlcnR5ICR7a31gKTtcbiAgICB9XG5cbiAgICAodGhpcyBhcyBhbnkpW2tdID0gdjtcbiAgfVxuXG4gIHN0YXRpYyByZWFkb25seSBaRVJPID0gT2JqZWN0LmZyZWV6ZShuZXcgRGltZW5zaW9ucygpKTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIFpFUk9cbiAgICogQHJldHVybiBEaW1lbnNpb25zIGZvciBhbiBlbXB0eSB0cmFuc2FjdGlvblxuICAgKi9cbiAgc3RhdGljIHplcm8oKTogUmVhZG9ubHk8RGltZW5zaW9ucz4ge1xuICAgIHJldHVybiB0aGlzLlpFUk87XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHNpemVcbiAgICogQHJldHVybiBEaW1lbnNpb25zIGZvciBhIHNpbmdsZSBvdXRwdXQgd2l0aCBnaXZlbiBzaXplXG4gICAqL1xuICBzdGF0aWMgc2luZ2xlT3V0cHV0KHNpemU6IG51bWJlcik6IERpbWVuc2lvbnMge1xuICAgIHJldHVybiBEaW1lbnNpb25zLnN1bSh7IG91dHB1dHM6IHsgY291bnQ6IDEsIHNpemUgfSB9KTtcbiAgfVxuXG4gIHN0YXRpYyBTaW5nbGVPdXRwdXQ6IHtcbiAgICBwMnNoOiBEaW1lbnNpb25zO1xuICAgIHAyc2hQMndzaDogRGltZW5zaW9ucztcbiAgICBwMndzaDogRGltZW5zaW9ucztcbiAgICBwMnRyOiBEaW1lbnNpb25zO1xuICAgIHAycGtoOiBEaW1lbnNpb25zO1xuICAgIHAyd3BraDogRGltZW5zaW9ucztcbiAgfTtcblxuICAvKipcbiAgICogQHJldHVybiBOdW1iZXIgb2YgdG90YWwgaW5wdXRzIChwMnNoICsgcDJzaFAyd3NoICsgcDJ3c2ggKyBwMnRyKVxuICAgKi9cbiAgZ2V0IG5JbnB1dHMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5uUDJzaElucHV0cyArXG4gICAgICB0aGlzLm5QMnNoUDJ3c2hJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ3c2hJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0cktleXBhdGhJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDJJbnB1dHMgK1xuICAgICAgdGhpcy5uUDJzaFAycGtJbnB1dHNcbiAgICApO1xuICB9XG5cbiAgc2V0IG5JbnB1dHMoXzogbnVtYmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZWFkLW9ubHkgcHJvcGVydHkgbklucHV0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4gTnVtYmVyIG9mIHRvdGFsIG91dHB1dHNcbiAgICovXG4gIGdldCBuT3V0cHV0cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm91dHB1dHMuY291bnQ7XG4gIH1cblxuICBzZXQgbk91dHB1dHMoXzogbnVtYmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGByZWFkLW9ubHkgcHJvcGVydHkgbk91dHB1dHNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gYXJncyAtIERpbWVuc2lvbnMgKGNhbiBiZSBwYXJ0aWFsbHkgZGVmaW5lZClcbiAgICogQHJldHVybiB7RGltZW5zaW9uc30gc3VtIG9mIGFyZ3VtZW50c1xuICAgKi9cbiAgc3RhdGljIHN1bSguLi5hcmdzOiBQYXJ0aWFsPERpbWVuc2lvbnM+W10pOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gYXJncy5yZWR1Y2UoKGE6IERpbWVuc2lvbnMsIGI6IFBhcnRpYWw8RGltZW5zaW9ucz4pID0+IGEucGx1cyhiKSwgbmV3IERpbWVuc2lvbnMoKSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGNoYWluXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICovXG4gIHN0YXRpYyBnZXRPdXRwdXRTY3JpcHRMZW5ndGhGb3JDaGFpbihjaGFpbjogQ2hhaW5Db2RlKTogbnVtYmVyIHtcbiAgICBzd2l0Y2ggKHNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbikpIHtcbiAgICAgIGNhc2UgJ3Ayd3NoJzpcbiAgICAgIGNhc2UgJ3AydHInOlxuICAgICAgY2FzZSAncDJ0ck11c2lnMic6XG4gICAgICAgIHJldHVybiAzNDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAyMztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHNjcmlwdExlbmd0aFxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHZTaXplIG9mIGFuIG91dHB1dCB3aXRoIHNjcmlwdCBsZW5ndGhcbiAgICovXG4gIHN0YXRpYyBnZXRWU2l6ZUZvck91dHB1dFdpdGhTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmICghUG9zaXRpdmVJbnRlZ2VyLmlzKHNjcmlwdExlbmd0aCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGV4cGVjdGVkIHBvc2l0aXZlIGludGVnZXIgZm9yIHNjcmlwdExlbmd0aCwgZ290ICR7c2NyaXB0TGVuZ3RofWApO1xuICAgIH1cbiAgICByZXR1cm4gc2NyaXB0TGVuZ3RoICsgY29tcGFjdFNpemUoc2NyaXB0TGVuZ3RoKSArIFZpcnR1YWxTaXplcy50eE91dHB1dEFtb3VudFNpemU7XG4gIH1cblxuICBzdGF0aWMgU2luZ2xlSW5wdXQ6IHtcbiAgICBwMnNoOiBEaW1lbnNpb25zO1xuICAgIHAyc2hQMndzaDogRGltZW5zaW9ucztcbiAgICBwMndzaDogRGltZW5zaW9ucztcbiAgICBwMnRyS2V5cGF0aDogRGltZW5zaW9ucztcbiAgICBwMnRyU2NyaXB0UGF0aExldmVsMTogRGltZW5zaW9ucztcbiAgICBwMnRyU2NyaXB0UGF0aExldmVsMjogRGltZW5zaW9ucztcbiAgICBwMnNoUDJwazogRGltZW5zaW9ucztcbiAgfTtcblxuICAvKipcbiAgICogQHJldHVyblxuICAgKi9cbiAgc3RhdGljIGZyb21TY3JpcHRUeXBlKFxuICAgIHNjcmlwdFR5cGU6IHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5TY3JpcHRUeXBlIHwgdXR4b2xpYi5iaXRnby5QYXJzZWRTY3JpcHRUeXBlMk9mMyB8ICdwMnBraCcsXG4gICAgcGFyYW1zOiB7XG4gICAgICBzY3JpcHRQYXRoTGV2ZWw/OiBudW1iZXI7XG4gICAgfSA9IHt9XG4gICk6IERpbWVuc2lvbnMge1xuICAgIHN3aXRjaCAoc2NyaXB0VHlwZSkge1xuICAgICAgY2FzZSAncDJzaCc6XG4gICAgICBjYXNlICdwMnNoUDJ3c2gnOlxuICAgICAgY2FzZSAncDJ3c2gnOlxuICAgICAgY2FzZSAncDJzaFAycGsnOlxuICAgICAgICByZXR1cm4gRGltZW5zaW9ucy5TaW5nbGVJbnB1dFtzY3JpcHRUeXBlXTtcbiAgICAgIGNhc2UgJ3AydHInOlxuICAgICAgY2FzZSAndGFwcm9vdFNjcmlwdFBhdGhTcGVuZCc6XG4gICAgICAgIHN3aXRjaCAocGFyYW1zLnNjcmlwdFBhdGhMZXZlbCkge1xuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHJldHVybiBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwxO1xuICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHJldHVybiBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwyO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgc2NyaXB0IHBhdGggbGV2ZWxgKTtcbiAgICAgICAgfVxuICAgICAgY2FzZSAncDJ0ck11c2lnMic6XG4gICAgICAgIHN3aXRjaCAocGFyYW1zLnNjcmlwdFBhdGhMZXZlbCkge1xuICAgICAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0cktleXBhdGg7XG4gICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0clNjcmlwdFBhdGhMZXZlbDE7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5leHBlY3RlZCBzY3JpcHQgcGF0aCBsZXZlbGApO1xuICAgICAgICB9XG4gICAgICBjYXNlICd0YXByb290S2V5UGF0aFNwZW5kJzpcbiAgICAgICAgcmV0dXJuIERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0cktleXBhdGg7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgc2NyaXB0VHlwZSAke3NjcmlwdFR5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIEFTU1VNRV9QMlNIOiBEaW1lbnNpb25zO1xuICBzdGF0aWMgQVNTVU1FX1AyU0hfUDJXU0g6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJXU0g6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJUUl9LRVlQQVRIOiBEaW1lbnNpb25zO1xuICBzdGF0aWMgQVNTVU1FX1AyVFJfU0NSSVBUUEFUSF9MRVZFTDE6IERpbWVuc2lvbnM7XG4gIHN0YXRpYyBBU1NVTUVfUDJUUl9TQ1JJUFRQQVRIX0xFVkVMMjogRGltZW5zaW9ucztcbiAgc3RhdGljIEFTU1VNRV9QMlNIX1AyUEtfSU5QVVQ6IERpbWVuc2lvbnM7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0QXNzdW1lZERpbWVuc2lvbihwYXJhbXM6IEZyb21JbnB1dFBhcmFtcyA9IHt9LCBpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgeyBhc3N1bWVVbnNpZ25lZCB9ID0gcGFyYW1zO1xuICAgIGlmICghYXNzdW1lVW5zaWduZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaWxsZWdhbCBpbnB1dCAke2luZGV4fTogZW1wdHkgc2NyaXB0IGFuZCBhc3N1bWVVbnNpZ25lZCBub3Qgc2V0YCk7XG4gICAgfVxuICAgIHJldHVybiBhc3N1bWVVbnNpZ25lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaW5wdXQgLSB0aGUgdHJhbnNhY3Rpb24gaW5wdXQgdG8gY291bnRcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiAgICAgICAgW3BhcmFtLmFzc3VtZVVuc2lnbmVkXSAtIGRlZmF1bHQgdHlwZSBmb3IgdW5zaWduZWQgaW5wdXRcbiAgICovXG4gIHN0YXRpYyBmcm9tSW5wdXQoaW5wdXQ6IHV0eG9saWIuVHhJbnB1dCwgcGFyYW1zOiBGcm9tSW5wdXRQYXJhbXMgPSB7fSk6IERpbWVuc2lvbnMge1xuICAgIGlmIChpbnB1dC5zY3JpcHQ/Lmxlbmd0aCB8fCBpbnB1dC53aXRuZXNzPy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHV0eG9saWIuYml0Z28ucGFyc2VTaWduYXR1cmVTY3JpcHQoaW5wdXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvbnMuZnJvbVNjcmlwdFR5cGUocGFyc2VkLnNjcmlwdFR5cGUsIHBhcnNlZCBhcyB7IHNjcmlwdFBhdGhMZXZlbD86IG51bWJlciB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gRGltZW5zaW9ucy5nZXRBc3N1bWVkRGltZW5zaW9uKHBhcmFtcywgaW5wdXQuaW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBEaW1lbnNpb25zIGZyb20gcHNidCBpbnB1dFxuICAgKiBAcGFyYW0gaW5wdXQgLSBwc2J0IGlucHV0XG4gICAqL1xuICBzdGF0aWMgZnJvbVBzYnRJbnB1dChpbnB1dDogYml0Z28uUHNidElucHV0VHlwZSk6IERpbWVuc2lvbnMge1xuICAgIGNvbnN0IHBhcnNlZCA9IGJpdGdvLnBhcnNlUHNidElucHV0KGlucHV0KTtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tU2NyaXB0VHlwZShwYXJzZWQuc2NyaXB0VHlwZSwgcGFyc2VkIGFzIHsgc2NyaXB0UGF0aExldmVsPzogbnVtYmVyIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBpbnB1dHMgLSBBcnJheSBvZiBpbnB1dHNcbiAgICogQHBhcmFtIHBhcmFtcyAtIEBzZWUgRGltZW5zaW9ucy5mcm9tSW5wdXQoKVxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBzdW0gb2YgdGhlIGRpbWVuc2lvbnMgZm9yIGVhY2ggaW5wdXQgKEBzZWUgRGltZW5zaW9ucy5mcm9tSW5wdXQoKSlcbiAgICovXG4gIHN0YXRpYyBmcm9tSW5wdXRzKGlucHV0czogdXR4b2xpYi5UeElucHV0W10sIHBhcmFtcz86IEZyb21JbnB1dFBhcmFtcyk6IERpbWVuc2lvbnMge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4uaW5wdXRzLm1hcCgoaSkgPT4gRGltZW5zaW9ucy5mcm9tSW5wdXQoaSwgcGFyYW1zKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBEaW1lbnNpb25zIGZyb20gbXVsdGlwbGUgcHNidCBpbnB1dHNcbiAgICogQHBhcmFtIGlucHV0cyBwc2J0IGlucHV0IGFycmF5XG4gICAqIEByZXR1cm4ge0RpbWVuc2lvbnN9IHN1bSBvZiB0aGUgZGltZW5zaW9ucyBmb3IgZWFjaCBpbnB1dCAoQHNlZSBEaW1lbnNpb25zLmZyb21Qc2J0SW5wdXQoKSlcbiAgICovXG4gIHN0YXRpYyBmcm9tUHNidElucHV0cyhpbnB1dHM6IGJpdGdvLlBzYnRJbnB1dFR5cGVbXSk6IERpbWVuc2lvbnMge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4uaW5wdXRzLm1hcCgoaW5wdXQsIF8pID0+IERpbWVuc2lvbnMuZnJvbVBzYnRJbnB1dChpbnB1dCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gc2NyaXB0TGVuZ3RoIHtudW1iZXJ9IC0gc2l6ZSBvZiB0aGUgb3V0cHV0IHNjcmlwdCBpbiBieXRlc1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSAtIERpbWVuc2lvbnMgb2YgdGhlIG91dHB1dFxuICAgKi9cbiAgc3RhdGljIGZyb21PdXRwdXRTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoOiBudW1iZXIpOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oe1xuICAgICAgb3V0cHV0czoge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgc2l6ZTogRGltZW5zaW9ucy5nZXRWU2l6ZUZvck91dHB1dFdpdGhTY3JpcHRMZW5ndGgoc2NyaXB0TGVuZ3RoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIG91dHB1dCAtIGEgdHggb3V0cHV0XG4gICAqIEByZXR1cm4gRGltZW5zaW9ucyAtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBnaXZlbiBvdXRwdXRcbiAgICovXG4gIHN0YXRpYyBmcm9tT3V0cHV0KHsgc2NyaXB0IH06IHsgc2NyaXB0OiBCdWZmZXIgfSk6IERpbWVuc2lvbnMge1xuICAgIGlmICghc2NyaXB0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG91dHB1dCBzY3JpcHQgdG8gYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihzY3JpcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdleHBlY3RlZCBzY3JpcHQgdG8gYmUgYnVmZmVyLCBnb3QgJyArIHR5cGVvZiBzY3JpcHQpO1xuICAgIH1cbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tT3V0cHV0U2NyaXB0TGVuZ3RoKHNjcmlwdC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBvdXRwdXRzIC0gQXJyYXkgb2Ygb3V0cHV0c1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBzdW0gb2YgdGhlIGRpbWVuc2lvbnMgZm9yIGVhY2ggb3V0cHV0IChAc2VlIERpbWVuc2lvbnMuZnJvbU91dHB1dCgpKVxuICAgKi9cbiAgc3RhdGljIGZyb21PdXRwdXRzKG91dHB1dHM6IHsgc2NyaXB0OiBCdWZmZXIgfVtdKTogRGltZW5zaW9ucyB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG91dHB1dHMpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBvdXRwdXRzIG11c3QgYmUgYXJyYXlgKTtcbiAgICB9XG4gICAgcmV0dXJuIERpbWVuc2lvbnMuc3VtKC4uLm91dHB1dHMubWFwKERpbWVuc2lvbnMuZnJvbU91dHB1dCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGRpbWVuc2lvbnMgb2YgYW4gb3V0cHV0IHRoYXQgd2lsbCBiZSBjcmVhdGVkIG9uIGEgc3BlY2lmaWMgY2hhaW4uXG4gICAqIEN1cnJlbnRseSwgdGhpcyBzaW1wbHkgYWRkcyBhIGRlZmF1bHQgb3V0cHV0LlxuICAgKlxuICAgKiBAcGFyYW0gY2hhaW4gLSBDaGFpbiBjb2RlIGFzIGRlZmluZWQgYnkgdXR4b2xpYi5iaXRnb1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSAtIERpbWVuc2lvbnMgZm9yIGEgc2luZ2xlIG91dHB1dCBvbiB0aGUgZ2l2ZW4gY2hhaW4uXG4gICAqL1xuICBzdGF0aWMgZnJvbU91dHB1dE9uQ2hhaW4oY2hhaW46IENoYWluQ29kZSk6IERpbWVuc2lvbnMge1xuICAgIHJldHVybiBEaW1lbnNpb25zLmZyb21PdXRwdXRTY3JpcHRMZW5ndGgoRGltZW5zaW9ucy5nZXRPdXRwdXRTY3JpcHRMZW5ndGhGb3JDaGFpbihjaGFpbikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBkaW1lbnNpb25zIG9mIGFuIHVuc3BlbnQgYWNjb3JkaW5nIHRvIGBjaGFpbmAgcGFyYW1ldGVyXG4gICAqIEBwYXJhbSBjaGFpbiAtIENoYWluIGNvZGUgYXMgZGVmaW5lZCBieSB1dHhvLmNoYWluXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBIaW50IGZvciB1bnNwZW50cyB3aXRoIHZhcmlhYmxlIGlucHV0IHNpemVzIChwMnRyLCBwMnRyTXVzaWcyKVxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfSBvZiB0aGUgdW5zcGVudFxuICAgKiBAdGhyb3dzIGlmIHRoZSBjaGFpbiBjb2RlIGlzIGludmFsaWQgb3IgdW5zdXBwb3J0ZWRcbiAgICovXG4gIHN0YXRpYyBmcm9tVW5zcGVudCh7IGNoYWluIH06IHsgY2hhaW46IG51bWJlciB9LCBwYXJhbXM6IEZyb21VbnNwZW50UGFyYW1zID0gZGVmYXVsdFVuc3BlbnRQYXJhbXMpOiBEaW1lbnNpb25zIHtcbiAgICBpZiAoIWlzQ2hhaW5Db2RlKGNoYWluKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBjaGFpbiBjb2RlJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbik7XG5cbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tU2NyaXB0VHlwZShcbiAgICAgIHNjcmlwdFR5cGUsXG4gICAgICBzY3JpcHRUeXBlID09PSAncDJ0cicgPyBwYXJhbXMucDJ0ciA6IHNjcmlwdFR5cGUgPT09ICdwMnRyTXVzaWcyJyA/IHBhcmFtcy5wMnRyTXVzaWcyIDoge31cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB1bnNwZW50c1xuICAgKiBAcGFyYW0gcGFyYW1zIC0gSGludCBmb3IgdW5zcGVudHMgd2l0aCB2YXJpYWJsZSBpbnB1dCBzaXplcyAocDJ0ciwgcDJ0ck11c2lnMilcbiAgICogQHJldHVybiB7RGltZW5zaW9uc30gc3VtIG9mIHRoZSBkaW1lbnNpb25zIGZvciBlYWNoIHVuc3BlbnQgKEBzZWUgRGltZW5zaW9ucy5mcm9tVW5zcGVudCgpKVxuICAgKi9cbiAgc3RhdGljIGZyb21VbnNwZW50cyh1bnNwZW50czogeyBjaGFpbjogQ2hhaW5Db2RlIH1bXSwgcGFyYW1zOiBGcm9tVW5zcGVudFBhcmFtcyA9IGRlZmF1bHRVbnNwZW50UGFyYW1zKTogRGltZW5zaW9ucyB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHVuc3BlbnRzKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zcGVudHMgbXVzdCBiZSBhcnJheWApO1xuICAgIH1cbiAgICAvLyBDb252ZXJ0IHRoZSBpbmRpdmlkdWFsIHVuc3BlbnRzIGludG8gZGltZW5zaW9ucyBhbmQgc3VtIHRoZW0gdXBcbiAgICByZXR1cm4gRGltZW5zaW9ucy5zdW0oLi4udW5zcGVudHMubWFwKCh1KSA9PiBEaW1lbnNpb25zLmZyb21VbnNwZW50KHUsIHBhcmFtcykpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb24gLSBiaXRjb2luLWxpa2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIFtwYXJhbS5hc3N1bWVVbnNpZ25lZF0gLSBkZWZhdWx0IHR5cGUgZm9yIHVuc2lnbmVkIGlucHV0c1xuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfVxuICAgKi9cbiAgc3RhdGljIGZyb21UcmFuc2FjdGlvbihcbiAgICB7XG4gICAgICBpbnMsXG4gICAgICBvdXRzLFxuICAgIH06IHtcbiAgICAgIGluczogdXR4b2xpYi5UeElucHV0W107XG4gICAgICBvdXRzOiB1dHhvbGliLlR4T3V0cHV0W107XG4gICAgfSxcbiAgICBwYXJhbXM/OiBGcm9tSW5wdXRQYXJhbXNcbiAgKTogRGltZW5zaW9ucyB7XG4gICAgcmV0dXJuIERpbWVuc2lvbnMuZnJvbUlucHV0cyhpbnMsIHBhcmFtcykucGx1cyhEaW1lbnNpb25zLmZyb21PdXRwdXRzKG91dHMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgRGltZW5zaW9ucyBmcm9tIHBzYnQgaW5wdXRzIGFuZCBvdXRwdXRzXG4gICAqIEBwYXJhbSBwc2J0XG4gICAqIEByZXR1cm4ge0RpbWVuc2lvbnN9XG4gICAqL1xuICBzdGF0aWMgZnJvbVBzYnQocHNidDogYml0Z28uVXR4b1BzYnQpOiBEaW1lbnNpb25zIHtcbiAgICByZXR1cm4gRGltZW5zaW9ucy5mcm9tUHNidElucHV0cyhwc2J0LmRhdGEuaW5wdXRzKS5wbHVzKERpbWVuc2lvbnMuZnJvbU91dHB1dHMocHNidC5nZXRVbnNpZ25lZFR4KCkub3V0cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBkaW1lbnNpb25zIChjYW4gYmUgcGFydGlhbGx5IGRlZmluZWQpXG4gICAqIEByZXR1cm4gbmV3IGRpbWVuc2lvbnMgd2l0aCBhcmd1bWVudCBhZGRlZFxuICAgKi9cbiAgcGx1cyhkaW1lbnNpb25zOiBQYXJ0aWFsPERpbWVuc2lvbnM+KTogRGltZW5zaW9ucyB7XG4gICAgaWYgKHR5cGVvZiBkaW1lbnNpb25zICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgZXhwZWN0ZWQgYXJndW1lbnQgdG8gYmUgb2JqZWN0YCk7XG4gICAgfVxuXG4gICAgaWYgKCEoZGltZW5zaW9ucyBpbnN0YW5jZW9mIERpbWVuc2lvbnMpKSB7XG4gICAgICBkaW1lbnNpb25zID0gbmV3IERpbWVuc2lvbnMoZGltZW5zaW9ucyk7XG4gICAgfVxuXG4gICAgLy8gQ2F0Y2ggaW5zdGFuY2VzIHdoZXJlIHdlIHRyeSB0byBpbml0aWFsaXplIERpbWVuc2lvbnMgZnJvbSBwYXJ0aWFsIGRhdGEgdXNpbmcgZGVwcmVjYXRlZCBwYXJhbWV0ZXJzXG4gICAgLy8gdXNpbmcgb25seSBcIm5PdXRwdXRzXCIuXG4gICAgaWYgKCduT3V0cHV0cycgaW4gZGltZW5zaW9ucykge1xuICAgICAgaWYgKCEoJ291dHB1dHMnIGluIGRpbWVuc2lvbnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZGVwcmVjYXRlZCBwYXJ0aWFsIGFkZGl0aW9uOiBhcmd1bWVudCBoYXMga2V5IFwibk91dHB1dHNcIiBidXQgbm8gXCJvdXRwdXRzXCInKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBvdXRwdXRzLCBuT3V0cHV0cyB9ID0gZGltZW5zaW9ucyBhcyBEaW1lbnNpb25zO1xuXG4gICAgICBpZiAob3V0cHV0cy5jb3VudCAhPT0gbk91dHB1dHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXByZWNhdGVkIHBhcnRpYWwgYWRkaXRpb246IGluY29uc2lzdGVudCB2YWx1ZXMgZm9yIFwibk91dHB1dHNcIiBhbmQgXCJvdXRwdXRzLmNvdW50XCInKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWFwRGltZW5zaW9ucyh0aGlzLCAoa2V5LCB2KSA9PiB7XG4gICAgICBjb25zdCB3ID0gZGltZW5zaW9uc1trZXldID8/IERpbWVuc2lvbnMuWkVST1trZXldO1xuICAgICAgaWYgKGtleSA9PT0gJ291dHB1dHMnKSB7XG4gICAgICAgIGNvbnN0IHZPdXRwdXRzID0gdiBhcyBPdXRwdXREaW1lbnNpb25zO1xuICAgICAgICBjb25zdCB3T3V0cHV0cyA9IHcgYXMgT3V0cHV0RGltZW5zaW9ucztcbiAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXREaW1lbnNpb25zKHtcbiAgICAgICAgICBjb3VudDogdk91dHB1dHMuY291bnQgKyB3T3V0cHV0cy5jb3VudCxcbiAgICAgICAgICBzaXplOiB2T3V0cHV0cy5zaXplICsgd091dHB1dHMuc2l6ZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKHYgYXMgbnVtYmVyKSArICh3IGFzIG51bWJlcik7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTXVsdGlwbHkgZGltZW5zaW9ucyBieSBhIGdpdmVuIGZhY3RvclxuICAgKiBAcGFyYW0gZmFjdG9yIC0gUG9zaXRpdmUgaW50ZWdlclxuICAgKiBAcmV0dXJuIHtEaW1lbnNpb25zfVxuICAgKi9cbiAgdGltZXMoZmFjdG9yOiBudW1iZXIpOiBEaW1lbnNpb25zIHtcbiAgICBpZiAoIVBvc2l0aXZlSW50ZWdlci5pcyhmYWN0b3IpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBleHBlY3RlZCBmYWN0b3IgdG8gYmUgcG9zaXRpdmUgaW50ZWdlcmApO1xuICAgIH1cblxuICAgIHJldHVybiBtYXBEaW1lbnNpb25zKHRoaXMsIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICBpZiAoa2V5ID09PSAnb3V0cHV0cycpIHtcbiAgICAgICAgY29uc3Qgdk91dHB1dHMgPSB2YWx1ZSBhcyBPdXRwdXREaW1lbnNpb25zO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvdW50OiB2T3V0cHV0cy5jb3VudCAqIGZhY3RvcixcbiAgICAgICAgICBzaXplOiB2T3V0cHV0cy5zaXplICogZmFjdG9yLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh2YWx1ZSBhcyBudW1iZXIpICogZmFjdG9yO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4gTnVtYmVyIG9mIHRvdGFsIGlucHV0cyAocDJzaCwgcDJzaFAyd3NoIGFuZCBwMndzaClcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGBkaW1lbnNpb24ubklucHV0c2AgaW5zdGVhZFxuICAgKi9cbiAgZ2V0TklucHV0cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm5JbnB1dHM7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWZmIGRpbWVuc2lvbnMgaGF2ZSBvbmUgb3IgbW9yZSAocDJzaClwMndzaCBpbnB1dHNcbiAgICovXG4gIGlzU2Vnd2l0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLm5QMndzaElucHV0cyArXG4gICAgICAgIHRoaXMublAyc2hQMndzaElucHV0cyArXG4gICAgICAgIHRoaXMublAydHJLZXlwYXRoSW5wdXRzICtcbiAgICAgICAgdGhpcy5uUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHMgK1xuICAgICAgICB0aGlzLm5QMnRyU2NyaXB0UGF0aExldmVsMklucHV0cyA+XG4gICAgICAwXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IG92ZXJoZWFkIHZzaXplLCBiYXNlZCBvbiByZXN1bHQgaXNTZWd3aXQoKS5cbiAgICovXG4gIGdldE92ZXJoZWFkVlNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5pc1NlZ3dpdCgpID8gVmlydHVhbFNpemVzLnR4U2VnT3ZlcmhlYWRWU2l6ZSA6IFZpcnR1YWxTaXplcy50eE92ZXJoZWFkU2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSB2c2l6ZSBvZiBpbnB1dHMsIHdpdGhvdXQgdHJhbnNhY3Rpb24gb3ZlcmhlYWRcbiAgICovXG4gIGdldElucHV0c1ZTaXplKCk6IG51bWJlciB7XG4gICAgY29uc3Qge1xuICAgICAgdHhQMnNoSW5wdXRTaXplLFxuICAgICAgdHhQMnNoUDJ3c2hJbnB1dFNpemUsXG4gICAgICB0eFAyd3NoSW5wdXRTaXplLFxuICAgICAgdHhQMnRyS2V5cGF0aElucHV0U2l6ZSxcbiAgICAgIHR4UDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dFNpemUsXG4gICAgICB0eFAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRTaXplLFxuICAgICAgdHhQMnNoUDJwa0lucHV0U2l6ZSxcbiAgICB9ID0gVmlydHVhbFNpemVzO1xuXG4gICAgY29uc3Qge1xuICAgICAgblAyc2hJbnB1dHMsXG4gICAgICBuUDJzaFAyd3NoSW5wdXRzLFxuICAgICAgblAyd3NoSW5wdXRzLFxuICAgICAgblAydHJLZXlwYXRoSW5wdXRzLFxuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzLFxuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRzLFxuICAgICAgblAyc2hQMnBrSW5wdXRzLFxuICAgIH0gPSB0aGlzO1xuXG4gICAgY29uc3Qgc2l6ZSA9XG4gICAgICBuUDJzaElucHV0cyAqIHR4UDJzaElucHV0U2l6ZSArXG4gICAgICBuUDJzaFAyd3NoSW5wdXRzICogdHhQMnNoUDJ3c2hJbnB1dFNpemUgK1xuICAgICAgblAyd3NoSW5wdXRzICogdHhQMndzaElucHV0U2l6ZSArXG4gICAgICBuUDJ0cktleXBhdGhJbnB1dHMgKiB0eFAydHJLZXlwYXRoSW5wdXRTaXplICtcbiAgICAgIG5QMnNoUDJwa0lucHV0cyAqIHR4UDJzaFAycGtJbnB1dFNpemUgK1xuICAgICAgblAydHJTY3JpcHRQYXRoTGV2ZWwxSW5wdXRzICogdHhQMnRyU2NyaXB0UGF0aExldmVsMUlucHV0U2l6ZSArXG4gICAgICBuUDJ0clNjcmlwdFBhdGhMZXZlbDJJbnB1dHMgKiB0eFAydHJTY3JpcHRQYXRoTGV2ZWwySW5wdXRTaXplO1xuICAgIGlmIChOdW1iZXIuaXNOYU4oc2l6ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBzaXplYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge251bWJlcn0gcmV0dXJuIHZzaXplIG9mIG91dHB1dHMsIHdpdGhvdXQgb3ZlcmhlYWRcbiAgICovXG4gIGdldE91dHB1dHNWU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm91dHB1dHMuc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFc3RpbWF0ZXMgdGhlIHZpcnR1YWwgc2l6ZSAoMS80IHdlaWdodCkgb2YgYSBzaWduZWQgdHJhbnNhY3Rpb24gYXMgc3VtIG9mXG4gICAqIG92ZXJoZWFkIHZzaXplLCBpbnB1dCB2c2l6ZSBhbmQgb3V0cHV0IHZzaXplLlxuICAgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgZXN0aW1hdGVkIHZzaXplIG9mIHRoZSB0cmFuc2FjdGlvbiBkaW1lbnNpb25zLlxuICAgKi9cbiAgZ2V0VlNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPdmVyaGVhZFZTaXplKCkgKyB0aGlzLmdldElucHV0c1ZTaXplKCkgKyB0aGlzLmdldE91dHB1dHNWU2l6ZSgpO1xuICB9XG59XG5cbi8vIEluaXRpYWxpemUgc3RhdGljIHByb3BlcnRpZXMgdGhhdCByZXF1aXJlIHRoZSBjbGFzcyB0byBiZSBmdWxseSBkZWZpbmVkIGZpcnN0XG5EaW1lbnNpb25zLlNpbmdsZU91dHB1dCA9IE9iamVjdC5mcmVlemUoe1xuICBwMnNoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnNoT3V0cHV0U2l6ZSksXG4gIHAyc2hQMndzaDogRGltZW5zaW9ucy5zaW5nbGVPdXRwdXQoVmlydHVhbFNpemVzLnR4UDJzaFAyd3NoT3V0cHV0U2l6ZSksXG4gIHAyd3NoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMndzaE91dHB1dFNpemUpLFxuICBwMnRyOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnRyT3V0cHV0U2l6ZSksXG4gIHAycGtoOiBEaW1lbnNpb25zLnNpbmdsZU91dHB1dChWaXJ0dWFsU2l6ZXMudHhQMnBraE91dHB1dFNpemUpLFxuICBwMndwa2g6IERpbWVuc2lvbnMuc2luZ2xlT3V0cHV0KFZpcnR1YWxTaXplcy50eFAyd3BraE91dHB1dFNpemUpLFxufSk7XG5cbi8vIEluaXRpYWxpemUgU2luZ2xlSW5wdXQgYWZ0ZXIgdGhlIGNsYXNzIGlzIGZ1bGx5IGRlZmluZWRcbkRpbWVuc2lvbnMuU2luZ2xlSW5wdXQgPSBPYmplY3QuZnJlZXplKHtcbiAgcDJzaDogRGltZW5zaW9ucy5zdW0oeyBuUDJzaElucHV0czogMSB9KSxcbiAgcDJzaFAyd3NoOiBEaW1lbnNpb25zLnN1bSh7IG5QMnNoUDJ3c2hJbnB1dHM6IDEgfSksXG4gIHAyd3NoOiBEaW1lbnNpb25zLnN1bSh7IG5QMndzaElucHV0czogMSB9KSxcbiAgcDJ0cktleXBhdGg6IERpbWVuc2lvbnMuc3VtKHsgblAydHJLZXlwYXRoSW5wdXRzOiAxIH0pLFxuICBwMnRyU2NyaXB0UGF0aExldmVsMTogRGltZW5zaW9ucy5zdW0oeyBuUDJ0clNjcmlwdFBhdGhMZXZlbDFJbnB1dHM6IDEgfSksXG4gIHAydHJTY3JpcHRQYXRoTGV2ZWwyOiBEaW1lbnNpb25zLnN1bSh7IG5QMnRyU2NyaXB0UGF0aExldmVsMklucHV0czogMSB9KSxcbiAgcDJzaFAycGs6IERpbWVuc2lvbnMuc3VtKHsgblAyc2hQMnBrSW5wdXRzOiAxIH0pLFxufSk7XG5cbi8vIEluaXRpYWxpemUgdGhlIEFTU1VNRV8gY29uc3RhbnRzXG5EaW1lbnNpb25zLkFTU1VNRV9QMlNIID0gRGltZW5zaW9ucy5TaW5nbGVJbnB1dC5wMnNoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJTSF9QMldTSCA9IERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJzaFAyd3NoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJXU0ggPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAyd3NoO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJUUl9LRVlQQVRIID0gRGltZW5zaW9ucy5TaW5nbGVJbnB1dC5wMnRyS2V5cGF0aDtcbkRpbWVuc2lvbnMuQVNTVU1FX1AyVFJfU0NSSVBUUEFUSF9MRVZFTDEgPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAydHJTY3JpcHRQYXRoTGV2ZWwxO1xuRGltZW5zaW9ucy5BU1NVTUVfUDJUUl9TQ1JJUFRQQVRIX0xFVkVMMiA9IERpbWVuc2lvbnMuU2luZ2xlSW5wdXQucDJ0clNjcmlwdFBhdGhMZXZlbDI7XG5EaW1lbnNpb25zLkFTU1VNRV9QMlNIX1AyUEtfSU5QVVQgPSBEaW1lbnNpb25zLlNpbmdsZUlucHV0LnAyc2hQMnBrO1xuIl19

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


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