PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-sui/dist/src/lib

Просмотр файла: unstakingTransaction.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.UnstakingTransaction = void 0;
const sdk_core_1 = require("@bitgo/sdk-core");
const utils_1 = __importStar(require("./utils"));
const buffer_1 = require("buffer");
const transaction_1 = require("./transaction");
const builder_1 = require("./mystenlab/builder");
const types_1 = require("./mystenlab/types");
const bcs_1 = require("@mysten/bcs");
const constants_1 = require("./constants");
const unstakingBuilder_1 = require("./unstakingBuilder");
const compareTransactionBlocks_1 = require("./compareTransactionBlocks");
class UnstakingTransaction extends transaction_1.Transaction {
    constructor(_coinConfig) {
        super(_coinConfig);
    }
    get suiTransaction() {
        return this._suiTransaction;
    }
    setSuiTransaction(tx) {
        this._suiTransaction = tx;
    }
    addSignature(publicKey, signature) {
        this._signatures.push(signature.toString('hex'));
        this._signature = { publicKey, signature };
        this.serialize();
    }
    get suiSignature() {
        return this._signature;
    }
    /** @inheritdoc */
    canSign(key) {
        return true;
    }
    /** @inheritdoc */
    toBroadcastFormat() {
        if (!this._suiTransaction) {
            throw new sdk_core_1.InvalidTransactionError('Empty transaction');
        }
        return this.serialize();
    }
    /** @inheritdoc */
    toJson() {
        if (!this._suiTransaction) {
            throw new sdk_core_1.ParseTransactionError('Empty transaction');
        }
        const tx = this._suiTransaction;
        return {
            id: this._id,
            sender: tx.sender,
            kind: { ProgrammableTransaction: tx.tx },
            gasData: tx.gasData,
            expiration: { None: null },
        };
    }
    /** @inheritDoc */
    explainTransaction() {
        const result = this.toJson();
        const displayOrder = [
            'id',
            'outputs',
            'outputAmount',
            'changeOutputs',
            'changeAmount',
            'fee',
            'type',
            'module',
            'function',
            'validatorAddress',
        ];
        const outputs = [];
        const explanationResult = {
            displayOrder,
            id: this.id,
            outputs,
            outputAmount: '0',
            changeOutputs: [],
            changeAmount: '0',
            fee: { fee: this.suiTransaction.gasData.budget.toString() },
            type: this.type,
        };
        switch (this.type) {
            case sdk_core_1.TransactionType.StakingClaim:
                return this.explainWithdrawStakedSuiTransaction(result, explanationResult);
            default:
                throw new sdk_core_1.InvalidTransactionError('Transaction type not supported');
        }
    }
    /**
     * Set the transaction type.
     *
     * @param {TransactionType} transactionType The transaction type to be set.
     */
    transactionType(transactionType) {
        this._type = transactionType;
    }
    getEntriesForStakedSuiInput(stakedSuiInput, amount) {
        return {
            inputs: [
                {
                    address: (0, types_1.normalizeSuiAddress)(stakedSuiInput.objectId),
                    value: amount === undefined ? constants_1.AMOUNT_UNKNOWN_TEXT : amount.toString(),
                    coin: this._coinConfig.name,
                },
            ],
            outputs: [
                {
                    address: this.suiTransaction.sender,
                    value: amount === undefined ? constants_1.AMOUNT_UNKNOWN_TEXT : amount.toString(),
                    coin: this._coinConfig.name,
                },
            ],
        };
    }
    /**
     * @param inputs
     * @param transactions
     */
    static parseTransactionPairReserialized(inputs, transactions) {
        const [inputStakedSui, inputAmount, inputSharedObj] = inputs;
        if (!builder_1.ObjectCallArg.is(inputStakedSui)) {
            throw new Error('Invalid input staked sui');
        }
        if (!builder_1.PureCallArg.is(inputAmount)) {
            throw new Error('Invalid input amount');
        }
        if (!builder_1.ObjectCallArg.is(inputSharedObj)) {
            throw new Error('Invalid input shared object');
        }
        const amount = BigInt(types_1.bcs.de(bcs_1.BCS.U64, Uint8Array.from(inputAmount.Pure)));
        if (!(0, utils_1.isImmOrOwnedObj)(inputStakedSui.Object)) {
            throw new Error('Invalid input shared object');
        }
        // make sure we parsed the transaction correctly by rebuilding it and comparing the transaction blocks
        (0, compareTransactionBlocks_1.assertEqualTransactionBlocks)({ inputs, transactions }, unstakingBuilder_1.UnstakingBuilder.getTransactionBlockDataReserialized(inputStakedSui.Object.ImmOrOwned, amount));
        return {
            stakedObjectRef: inputStakedSui.Object.ImmOrOwned,
            amount,
        };
    }
    static parseTransactionPair(inputs, transactions) {
        if (transactions.length !== 2) {
            throw new Error('Invalid transaction pair');
        }
        if (!builder_1.MoveCallTransaction.is(transactions[0]) || !builder_1.MoveCallTransaction.is(transactions[1])) {
            throw new Error('Invalid transaction pair');
        }
        if (!Array.isArray(inputs) || inputs.length !== 3) {
            throw new Error('Invalid inputs');
        }
        const [inputStakedSui, inputAmount, inputSharedObj] = inputs;
        if (!builder_1.TransactionBlockInput.is(inputStakedSui) ||
            !builder_1.TransactionBlockInput.is(inputAmount) ||
            !builder_1.TransactionBlockInput.is(inputSharedObj)) {
            // for unclear reasons there seem to be two different serialization formats that we are dealing with
            // try the other one here
            return this.parseTransactionPairReserialized(
            // we have length checked these earlier
            inputs, transactions);
        }
        if (inputStakedSui.type !== 'object' ||
            inputAmount.type !== 'pure' ||
            typeof inputAmount.value !== 'string' ||
            inputSharedObj.type !== 'object' ||
            !builder_1.ObjectCallArg.is(inputStakedSui.value) ||
            !(0, utils_1.isImmOrOwnedObj)(inputStakedSui.value.Object)) {
            throw new Error('Invalid inputs');
        }
        const amount = BigInt(inputAmount.value);
        // make sure we parsed the transaction correctly by rebuilding it and comparing the transaction blocks
        (0, compareTransactionBlocks_1.assertEqualTransactionBlocks)({ inputs, transactions }, unstakingBuilder_1.UnstakingBuilder.getTransactionBlockData(inputStakedSui.value.Object.ImmOrOwned, amount));
        return {
            stakedObjectRef: inputStakedSui.value.Object.ImmOrOwned,
            amount,
        };
    }
    static parseTransactionSingle(inputs, tx) {
        if (!builder_1.MoveCallTransaction.is(tx) || !builder_1.TransactionBlockInput.is(tx.arguments[1])) {
            throw new Error('Invalid transaction');
        }
        const stakedSuiInputIdx = tx.arguments[1].index;
        let stakedSuiInput = inputs[stakedSuiInputIdx];
        if (!builder_1.TransactionBlockInput.is(stakedSuiInput)) {
            // for unclear reasons, in tests the stakedSuiInput is not a TransactionBlockInput sometimes
            if (!builder_1.ObjectCallArg.is(stakedSuiInput)) {
                throw new Error('Invalid transaction');
            }
        }
        if ('Object' in stakedSuiInput && (0, utils_1.isImmOrOwnedObj)(stakedSuiInput.Object)) {
            stakedSuiInput = stakedSuiInput.Object.ImmOrOwned;
        }
        else if ('value' in stakedSuiInput && (0, utils_1.isImmOrOwnedObj)(stakedSuiInput.value.Object)) {
            stakedSuiInput = stakedSuiInput.value.Object.ImmOrOwned;
        }
        else {
            throw new Error('Invalid transaction');
        }
        if (!types_1.SuiObjectRef.is(stakedSuiInput)) {
            throw new Error('Invalid transaction');
        }
        return {
            stakedObjectRef: stakedSuiInput,
        };
    }
    static parseTransaction(tx) {
        const { inputs, transactions } = tx;
        if (transactions.length === 1) {
            return UnstakingTransaction.parseTransactionSingle(inputs, transactions[0]);
        }
        else if (transactions.length === 2) {
            return UnstakingTransaction.parseTransactionPair(inputs, transactions);
        }
        else {
            throw new sdk_core_1.InvalidTransactionError('Invalid transaction');
        }
    }
    /**
     * Load the input and output data on this transaction.
     */
    loadInputsAndOutputs() {
        if (!this.suiTransaction) {
            return;
        }
        const parsed = UnstakingTransaction.parseTransaction(this.suiTransaction.tx);
        const { inputs, outputs } = this.getEntriesForStakedSuiInput(parsed.stakedObjectRef, parsed.amount);
        this._inputs = inputs;
        this._outputs = outputs;
    }
    /**
     * Sets this transaction payload
     *
     * @param {string} rawTransaction
     */
    fromRawTransaction(rawTransaction) {
        try {
            utils_1.default.isValidRawTransaction(rawTransaction);
            this._suiTransaction = transaction_1.Transaction.deserializeSuiTransaction(rawTransaction);
            this._type = utils_1.default.getTransactionType(this._suiTransaction.type);
            this._id = this._suiTransaction.id;
            this.loadInputsAndOutputs();
        }
        catch (e) {
            throw e;
        }
    }
    /**
     * Helper function for serialize() to get the correct txData with transaction type
     *
     * @return {TxData}
     */
    getTxData() {
        if (!this._suiTransaction) {
            throw new sdk_core_1.InvalidTransactionError('empty transaction');
        }
        const inputs = this._suiTransaction.tx.inputs.map((input, index) => {
            if (input.hasOwnProperty('Object')) {
                return input;
            }
            if (input.hasOwnProperty('Pure')) {
                if (input.Pure.length === constants_1.SUI_ADDRESS_LENGTH) {
                    const address = (0, types_1.normalizeSuiAddress)(builder_1.builder.de(bcs_1.BCS.ADDRESS, buffer_1.Buffer.from(input.Pure).toString('base64'), 'base64'));
                    return builder_1.Inputs.Pure(address, bcs_1.BCS.ADDRESS);
                }
                else {
                    const amount = builder_1.builder.de(bcs_1.BCS.U64, buffer_1.Buffer.from(input.Pure).toString('base64'), 'base64');
                    return builder_1.Inputs.Pure(amount, bcs_1.BCS.U64);
                }
            }
            if (input.kind === 'Input' && (input.value.hasOwnProperty('Object') || input.value.hasOwnProperty('Pure'))) {
                return input.value;
            }
            // what's left is the pure number or address string
            return builder_1.Inputs.Pure(input.value, input.type === 'pure' ? bcs_1.BCS.U64 : bcs_1.BCS.ADDRESS);
        });
        const programmableTx = {
            inputs: inputs,
            transactions: this._suiTransaction.tx.transactions,
        };
        return {
            sender: this._suiTransaction.sender,
            expiration: { None: null },
            gasData: this._suiTransaction.gasData,
            kind: {
                ProgrammableTransaction: programmableTx,
            },
        };
    }
    /**
     * Returns a complete explanation for a unstaking transaction
     *
     * @param {TxData} json The transaction data in json format
     * @param {TransactionExplanation} explanationResult The transaction explanation to be completed
     * @returns {TransactionExplanation}
     */
    explainWithdrawStakedSuiTransaction(json, explanationResult) {
        const outputs = [
            {
                address: this.suiTransaction.sender,
                amount: constants_1.AMOUNT_UNKNOWN_TEXT,
            },
        ];
        const outputAmount = constants_1.AMOUNT_UNKNOWN_TEXT;
        return {
            ...explanationResult,
            outputAmount,
            outputs,
        };
    }
}
exports.UnstakingTransaction = UnstakingTransaction;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5zdGFraW5nVHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Vuc3Rha2luZ1RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQVN5QjtBQUd6QixpREFBaUQ7QUFDakQsbUNBQWdDO0FBQ2hDLCtDQUE0QztBQUM1QyxpREFPNkI7QUFDN0IsNkNBQW9GO0FBQ3BGLHFDQUFrQztBQUNsQywyQ0FBc0U7QUFDdEUseURBQXNEO0FBQ3RELHlFQUEwRTtBQUUxRSxNQUFhLG9CQUFxQixTQUFRLHlCQUE2QztJQUNyRixZQUFZLFdBQWlDO1FBQzNDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM5QixDQUFDO0lBRUQsaUJBQWlCLENBQUMsRUFBb0Q7UUFDcEUsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELFlBQVksQ0FBQyxTQUF3QixFQUFFLFNBQWlCO1FBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsT0FBTyxDQUFDLEdBQVk7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGlCQUFpQjtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsZUFB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Q0osQ0FBQztDQUNGO0FBN1dELG9EQTZXQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJhc2VLZXksXG4gIEVudHJ5LFxuICBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcixcbiAgUGFyc2VUcmFuc2FjdGlvbkVycm9yLFxuICBQdWJsaWNLZXkgYXMgQmFzZVB1YmxpY0tleSxcbiAgU2lnbmF0dXJlLFxuICBUcmFuc2FjdGlvblJlY2lwaWVudCxcbiAgVHJhbnNhY3Rpb25UeXBlLFxufSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgVW5zdGFraW5nUHJvZ3JhbW1hYmxlVHJhbnNhY3Rpb24sIFN1aVRyYW5zYWN0aW9uLCBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLCBUeERhdGEgfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgdXRpbHMsIHsgaXNJbW1Pck93bmVkT2JqIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBCdWZmZXIgfSBmcm9tICdidWZmZXInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7XG4gIGJ1aWxkZXIsXG4gIElucHV0cyxcbiAgTW92ZUNhbGxUcmFuc2FjdGlvbixcbiAgT2JqZWN0Q2FsbEFyZyxcbiAgUHVyZUNhbGxBcmcsXG4gIFRyYW5zYWN0aW9uQmxvY2tJbnB1dCxcbn0gZnJvbSAnLi9teXN0ZW5sYWIvYnVpbGRlcic7XG5pbXBvcnQgeyBiY3MsIENhbGxBcmcsIG5vcm1hbGl6ZVN1aUFkZHJlc3MsIFN1aU9iamVjdFJlZiB9IGZyb20gJy4vbXlzdGVubGFiL3R5cGVzJztcbmltcG9ydCB7IEJDUyB9IGZyb20gJ0BteXN0ZW4vYmNzJztcbmltcG9ydCB7IEFNT1VOVF9VTktOT1dOX1RFWFQsIFNVSV9BRERSRVNTX0xFTkdUSCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IFVuc3Rha2luZ0J1aWxkZXIgfSBmcm9tICcuL3Vuc3Rha2luZ0J1aWxkZXInO1xuaW1wb3J0IHsgYXNzZXJ0RXF1YWxUcmFuc2FjdGlvbkJsb2NrcyB9IGZyb20gJy4vY29tcGFyZVRyYW5zYWN0aW9uQmxvY2tzJztcblxuZXhwb3J0IGNsYXNzIFVuc3Rha2luZ1RyYW5zYWN0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb248VW5zdGFraW5nUHJvZ3JhbW1hYmxlVHJhbnNhY3Rpb24+IHtcbiAgY29uc3RydWN0b3IoX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoX2NvaW5Db25maWcpO1xuICB9XG5cbiAgZ2V0IHN1aVRyYW5zYWN0aW9uKCk6IFN1aVRyYW5zYWN0aW9uPFVuc3Rha2luZ1Byb2dyYW1tYWJsZVRyYW5zYWN0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuX3N1aVRyYW5zYWN0aW9uO1xuICB9XG5cbiAgc2V0U3VpVHJhbnNhY3Rpb24odHg6IFN1aVRyYW5zYWN0aW9uPFVuc3Rha2luZ1Byb2dyYW1tYWJsZVRyYW5zYWN0aW9uPik6IHZvaWQge1xuICAgIHRoaXMuX3N1aVRyYW5zYWN0aW9uID0gdHg7XG4gIH1cblxuICBhZGRTaWduYXR1cmUocHVibGljS2V5OiBCYXNlUHVibGljS2V5LCBzaWduYXR1cmU6IEJ1ZmZlcik6IHZvaWQge1xuICAgIHRoaXMuX3NpZ25hdHVyZXMucHVzaChzaWduYXR1cmUudG9TdHJpbmcoJ2hleCcpKTtcbiAgICB0aGlzLl9zaWduYXR1cmUgPSB7IHB1YmxpY0tleSwgc2lnbmF0dXJlIH07XG4gICAgdGhpcy5zZXJpYWxpemUoKTtcbiAgfVxuXG4gIGdldCBzdWlTaWduYXR1cmUoKTogU2lnbmF0dXJlIHtcbiAgICByZXR1cm4gdGhpcy5fc2lnbmF0dXJlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGNhblNpZ24oa2V5OiBCYXNlS2V5KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdG9Ccm9hZGNhc3RGb3JtYXQoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuX3N1aVRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZSgpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHRvSnNvbigpOiBUeERhdGEge1xuICAgIGlmICghdGhpcy5fc3VpVHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHggPSB0aGlzLl9zdWlUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRoaXMuX2lkLFxuICAgICAgc2VuZGVyOiB0eC5zZW5kZXIsXG4gICAgICBraW5kOiB7IFByb2dyYW1tYWJsZVRyYW5zYWN0aW9uOiB0eC50eCB9LFxuICAgICAgZ2FzRGF0YTogdHguZ2FzRGF0YSxcbiAgICAgIGV4cGlyYXRpb246IHsgTm9uZTogbnVsbCB9LFxuICAgIH07XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgZXhwbGFpblRyYW5zYWN0aW9uKCk6IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMudG9Kc29uKCk7XG4gICAgY29uc3QgZGlzcGxheU9yZGVyID0gW1xuICAgICAgJ2lkJyxcbiAgICAgICdvdXRwdXRzJyxcbiAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAnZmVlJyxcbiAgICAgICd0eXBlJyxcbiAgICAgICdtb2R1bGUnLFxuICAgICAgJ2Z1bmN0aW9uJyxcbiAgICAgICd2YWxpZGF0b3JBZGRyZXNzJyxcbiAgICBdO1xuICAgIGNvbnN0IG91dHB1dHM6IFRyYW5zYWN0aW9uUmVjaXBpZW50W10gPSBbXTtcblxuICAgIGNvbnN0IGV4cGxhbmF0aW9uUmVzdWx0OiBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0ge1xuICAgICAgZGlzcGxheU9yZGVyLFxuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICBvdXRwdXRzLFxuICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgZmVlOiB7IGZlZTogdGhpcy5zdWlUcmFuc2FjdGlvbi5nYXNEYXRhLmJ1ZGdldC50b1N0cmluZygpIH0sXG4gICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgfTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQ2xhaW06XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGxhaW5XaXRoZHJhd1N0YWtlZFN1aVRyYW5zYWN0aW9uKHJlc3VsdCwgZXhwbGFuYXRpb25SZXN1bHQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdUcmFuc2FjdGlvbiB0eXBlIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSB0cmFuc2FjdGlvbiB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uVHlwZX0gdHJhbnNhY3Rpb25UeXBlIFRoZSB0cmFuc2FjdGlvbiB0eXBlIHRvIGJlIHNldC5cbiAgICovXG4gIHRyYW5zYWN0aW9uVHlwZSh0cmFuc2FjdGlvblR5cGU6IFRyYW5zYWN0aW9uVHlwZSk6IHZvaWQge1xuICAgIHRoaXMuX3R5cGUgPSB0cmFuc2FjdGlvblR5cGU7XG4gIH1cblxuICBnZXRFbnRyaWVzRm9yU3Rha2VkU3VpSW5wdXQoc3Rha2VkU3VpSW5wdXQ6IFN1aU9iamVjdFJlZiwgYW1vdW50PzogYmlnaW50KTogeyBpbnB1dHM6IEVudHJ5W107IG91dHB1dHM6IEVudHJ5W10gfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogbm9ybWFsaXplU3VpQWRkcmVzcyhzdGFrZWRTdWlJbnB1dC5vYmplY3RJZCksXG4gICAgICAgICAgdmFsdWU6IGFtb3VudCA9PT0gdW5kZWZpbmVkID8gQU1PVU5UX1VOS05PV05fVEVYVCA6IGFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIGNvaW46IHRoaXMuX2NvaW5Db25maWcubmFtZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiB0aGlzLnN1aVRyYW5zYWN0aW9uLnNlbmRlcixcbiAgICAgICAgICB2YWx1ZTogYW1vdW50ID09PSB1bmRlZmluZWQgPyBBTU9VTlRfVU5LTk9XTl9URVhUIDogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgY29pbjogdGhpcy5fY29pbkNvbmZpZy5uYW1lLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBpbnB1dHNcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uc1xuICAgKi9cbiAgc3RhdGljIHBhcnNlVHJhbnNhY3Rpb25QYWlyUmVzZXJpYWxpemVkKFxuICAgIGlucHV0czogW3Vua25vd24sIHVua25vd24sIHVua25vd25dLFxuICAgIHRyYW5zYWN0aW9uczogW3Vua25vd24sIHVua25vd25dXG4gICk6IHtcbiAgICBzdGFrZWRPYmplY3RSZWY6IFN1aU9iamVjdFJlZjtcbiAgICBhbW91bnQ6IGJpZ2ludDtcbiAgfSB7XG4gICAgY29uc3QgW2lucHV0U3Rha2VkU3VpLCBpbnB1dEFtb3VudCwgaW5wdXRTaGFyZWRPYmpdID0gaW5wdXRzO1xuXG4gICAgaWYgKCFPYmplY3RDYWxsQXJnLmlzKGlucHV0U3Rha2VkU3VpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHN0YWtlZCBzdWknKTtcbiAgICB9XG5cbiAgICBpZiAoIVB1cmVDYWxsQXJnLmlzKGlucHV0QW1vdW50KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IGFtb3VudCcpO1xuICAgIH1cblxuICAgIGlmICghT2JqZWN0Q2FsbEFyZy5pcyhpbnB1dFNoYXJlZE9iaikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFyZWQgb2JqZWN0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgYW1vdW50ID0gQmlnSW50KGJjcy5kZShCQ1MuVTY0LCBVaW50OEFycmF5LmZyb20oaW5wdXRBbW91bnQuUHVyZSkpKTtcbiAgICBpZiAoIWlzSW1tT3JPd25lZE9iaihpbnB1dFN0YWtlZFN1aS5PYmplY3QpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcmVkIG9iamVjdCcpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB3ZSBwYXJzZWQgdGhlIHRyYW5zYWN0aW9uIGNvcnJlY3RseSBieSByZWJ1aWxkaW5nIGl0IGFuZCBjb21wYXJpbmcgdGhlIHRyYW5zYWN0aW9uIGJsb2Nrc1xuICAgIGFzc2VydEVxdWFsVHJhbnNhY3Rpb25CbG9ja3MoXG4gICAgICB7IGlucHV0cywgdHJhbnNhY3Rpb25zIH0sXG4gICAgICBVbnN0YWtpbmdCdWlsZGVyLmdldFRyYW5zYWN0aW9uQmxvY2tEYXRhUmVzZXJpYWxpemVkKGlucHV0U3Rha2VkU3VpLk9iamVjdC5JbW1Pck93bmVkLCBhbW91bnQpXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBzdGFrZWRPYmplY3RSZWY6IGlucHV0U3Rha2VkU3VpLk9iamVjdC5JbW1Pck93bmVkLFxuICAgICAgYW1vdW50LFxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcGFyc2VUcmFuc2FjdGlvblBhaXIoXG4gICAgaW5wdXRzOiBTdWlUcmFuc2FjdGlvblsndHgnXVsnaW5wdXRzJ10sXG4gICAgdHJhbnNhY3Rpb25zOiB1bmtub3duW11cbiAgKToge1xuICAgIHN0YWtlZE9iamVjdFJlZjogU3VpT2JqZWN0UmVmO1xuICAgIGFtb3VudDogYmlnaW50O1xuICB9IHtcbiAgICBpZiAodHJhbnNhY3Rpb25zLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uIHBhaXInKTtcbiAgICB9XG5cbiAgICBpZiAoIU1vdmVDYWxsVHJhbnNhY3Rpb24uaXModHJhbnNhY3Rpb25zWzBdKSB8fCAhTW92ZUNhbGxUcmFuc2FjdGlvbi5pcyh0cmFuc2FjdGlvbnNbMV0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24gcGFpcicpO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShpbnB1dHMpIHx8IGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBbaW5wdXRTdGFrZWRTdWksIGlucHV0QW1vdW50LCBpbnB1dFNoYXJlZE9ial0gPSBpbnB1dHM7XG4gICAgaWYgKFxuICAgICAgIVRyYW5zYWN0aW9uQmxvY2tJbnB1dC5pcyhpbnB1dFN0YWtlZFN1aSkgfHxcbiAgICAgICFUcmFuc2FjdGlvbkJsb2NrSW5wdXQuaXMoaW5wdXRBbW91bnQpIHx8XG4gICAgICAhVHJhbnNhY3Rpb25CbG9ja0lucHV0LmlzKGlucHV0U2hhcmVkT2JqKVxuICAgICkge1xuICAgICAgLy8gZm9yIHVuY2xlYXIgcmVhc29ucyB0aGVyZSBzZWVtIHRvIGJlIHR3byBkaWZmZXJlbnQgc2VyaWFsaXphdGlvbiBmb3JtYXRzIHRoYXQgd2UgYXJlIGRlYWxpbmcgd2l0aFxuICAgICAgLy8gdHJ5IHRoZSBvdGhlciBvbmUgaGVyZVxuICAgICAgcmV0dXJuIHRoaXMucGFyc2VUcmFuc2FjdGlvblBhaXJSZXNlcmlhbGl6ZWQoXG4gICAgICAgIC8vIHdlIGhhdmUgbGVuZ3RoIGNoZWNrZWQgdGhlc2UgZWFybGllclxuICAgICAgICBpbnB1dHMgYXMgW3Vua25vd24sIHVua25vd24sIHVua25vd25dLFxuICAgICAgICB0cmFuc2FjdGlvbnMgYXMgW3Vua25vd24sIHVua25vd25dXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGlucHV0U3Rha2VkU3VpLnR5cGUgIT09ICdvYmplY3QnIHx8XG4gICAgICBpbnB1dEFtb3VudC50eXBlICE9PSAncHVyZScgfHxcbiAgICAgIHR5cGVvZiBpbnB1dEFtb3VudC52YWx1ZSAhPT0gJ3N0cmluZycgfHxcbiAgICAgIGlucHV0U2hhcmVkT2JqLnR5cGUgIT09ICdvYmplY3QnIHx8XG4gICAgICAhT2JqZWN0Q2FsbEFyZy5pcyhpbnB1dFN0YWtlZFN1aS52YWx1ZSkgfHxcbiAgICAgICFpc0ltbU9yT3duZWRPYmooaW5wdXRTdGFrZWRTdWkudmFsdWUuT2JqZWN0KVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0cycpO1xuICAgIH1cblxuICAgIGNvbnN0IGFtb3VudCA9IEJpZ0ludChpbnB1dEFtb3VudC52YWx1ZSk7XG5cbiAgICAvLyBtYWtlIHN1cmUgd2UgcGFyc2VkIHRoZSB0cmFuc2FjdGlvbiBjb3JyZWN0bHkgYnkgcmVidWlsZGluZyBpdCBhbmQgY29tcGFyaW5nIHRoZSB0cmFuc2FjdGlvbiBibG9ja3NcbiAgICBhc3NlcnRFcXVhbFRyYW5zYWN0aW9uQmxvY2tzKFxuICAgICAgeyBpbnB1dHMsIHRyYW5zYWN0aW9ucyB9LFxuICAgICAgVW5zdGFraW5nQnVpbGRlci5nZXRUcmFuc2FjdGlvbkJsb2NrRGF0YShpbnB1dFN0YWtlZFN1aS52YWx1ZS5PYmplY3QuSW1tT3JPd25lZCwgYW1vdW50KVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3Rha2VkT2JqZWN0UmVmOiBpbnB1dFN0YWtlZFN1aS52YWx1ZS5PYmplY3QuSW1tT3JPd25lZCxcbiAgICAgIGFtb3VudCxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHBhcnNlVHJhbnNhY3Rpb25TaW5nbGUoXG4gICAgaW5wdXRzOiBTdWlUcmFuc2FjdGlvblsndHgnXVsnaW5wdXRzJ10sXG4gICAgdHg6IHVua25vd25cbiAgKToge1xuICAgIHN0YWtlZE9iamVjdFJlZjogU3VpT2JqZWN0UmVmO1xuICB9IHtcbiAgICBpZiAoIU1vdmVDYWxsVHJhbnNhY3Rpb24uaXModHgpIHx8ICFUcmFuc2FjdGlvbkJsb2NrSW5wdXQuaXModHguYXJndW1lbnRzWzFdKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIGNvbnN0IHN0YWtlZFN1aUlucHV0SWR4ID0gdHguYXJndW1lbnRzWzFdLmluZGV4O1xuICAgIGxldCBzdGFrZWRTdWlJbnB1dDogdW5rbm93biB8IFN1aU9iamVjdFJlZiA9IGlucHV0c1tzdGFrZWRTdWlJbnB1dElkeF07XG4gICAgaWYgKCFUcmFuc2FjdGlvbkJsb2NrSW5wdXQuaXMoc3Rha2VkU3VpSW5wdXQpKSB7XG4gICAgICAvLyBmb3IgdW5jbGVhciByZWFzb25zLCBpbiB0ZXN0cyB0aGUgc3Rha2VkU3VpSW5wdXQgaXMgbm90IGEgVHJhbnNhY3Rpb25CbG9ja0lucHV0IHNvbWV0aW1lc1xuICAgICAgaWYgKCFPYmplY3RDYWxsQXJnLmlzKHN0YWtlZFN1aUlucHV0KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCdPYmplY3QnIGluIHN0YWtlZFN1aUlucHV0ICYmIGlzSW1tT3JPd25lZE9iaihzdGFrZWRTdWlJbnB1dC5PYmplY3QpKSB7XG4gICAgICBzdGFrZWRTdWlJbnB1dCA9IHN0YWtlZFN1aUlucHV0Lk9iamVjdC5JbW1Pck93bmVkIGFzIFN1aU9iamVjdFJlZjtcbiAgICB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gc3Rha2VkU3VpSW5wdXQgJiYgaXNJbW1Pck93bmVkT2JqKHN0YWtlZFN1aUlucHV0LnZhbHVlLk9iamVjdCkpIHtcbiAgICAgIHN0YWtlZFN1aUlucHV0ID0gc3Rha2VkU3VpSW5wdXQudmFsdWUuT2JqZWN0LkltbU9yT3duZWQgYXMgU3VpT2JqZWN0UmVmO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgaWYgKCFTdWlPYmplY3RSZWYuaXMoc3Rha2VkU3VpSW5wdXQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YWtlZE9iamVjdFJlZjogc3Rha2VkU3VpSW5wdXQsXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZVRyYW5zYWN0aW9uKHR4OiBVbnN0YWtpbmdQcm9ncmFtbWFibGVUcmFuc2FjdGlvbik6IHtcbiAgICBzdGFrZWRPYmplY3RSZWY6IFN1aU9iamVjdFJlZjtcbiAgICBhbW91bnQ/OiBiaWdpbnQ7XG4gIH0ge1xuICAgIGNvbnN0IHsgaW5wdXRzLCB0cmFuc2FjdGlvbnMgfSA9IHR4O1xuICAgIGlmICh0cmFuc2FjdGlvbnMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4gVW5zdGFraW5nVHJhbnNhY3Rpb24ucGFyc2VUcmFuc2FjdGlvblNpbmdsZShpbnB1dHMsIHRyYW5zYWN0aW9uc1swXSk7XG4gICAgfSBlbHNlIGlmICh0cmFuc2FjdGlvbnMubGVuZ3RoID09PSAyKSB7XG4gICAgICByZXR1cm4gVW5zdGFraW5nVHJhbnNhY3Rpb24ucGFyc2VUcmFuc2FjdGlvblBhaXIoaW5wdXRzLCB0cmFuc2FjdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9hZCB0aGUgaW5wdXQgYW5kIG91dHB1dCBkYXRhIG9uIHRoaXMgdHJhbnNhY3Rpb24uXG4gICAqL1xuICBsb2FkSW5wdXRzQW5kT3V0cHV0cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3VpVHJhbnNhY3Rpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZWQgPSBVbnN0YWtpbmdUcmFuc2FjdGlvbi5wYXJzZVRyYW5zYWN0aW9uKHRoaXMuc3VpVHJhbnNhY3Rpb24udHgpO1xuICAgIGNvbnN0IHsgaW5wdXRzLCBvdXRwdXRzIH0gPSB0aGlzLmdldEVudHJpZXNGb3JTdGFrZWRTdWlJbnB1dChwYXJzZWQuc3Rha2VkT2JqZWN0UmVmLCBwYXJzZWQuYW1vdW50KTtcbiAgICB0aGlzLl9pbnB1dHMgPSBpbnB1dHM7XG4gICAgdGhpcy5fb3V0cHV0cyA9IG91dHB1dHM7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGlzIHRyYW5zYWN0aW9uIHBheWxvYWRcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJhd1RyYW5zYWN0aW9uXG4gICAqL1xuICBmcm9tUmF3VHJhbnNhY3Rpb24ocmF3VHJhbnNhY3Rpb246IHN0cmluZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICB1dGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHJhbnNhY3Rpb24pO1xuICAgICAgdGhpcy5fc3VpVHJhbnNhY3Rpb24gPSBUcmFuc2FjdGlvbi5kZXNlcmlhbGl6ZVN1aVRyYW5zYWN0aW9uKFxuICAgICAgICByYXdUcmFuc2FjdGlvblxuICAgICAgKSBhcyBTdWlUcmFuc2FjdGlvbjxVbnN0YWtpbmdQcm9ncmFtbWFibGVUcmFuc2FjdGlvbj47XG4gICAgICB0aGlzLl90eXBlID0gdXRpbHMuZ2V0VHJhbnNhY3Rpb25UeXBlKHRoaXMuX3N1aVRyYW5zYWN0aW9uLnR5cGUpO1xuICAgICAgdGhpcy5faWQgPSB0aGlzLl9zdWlUcmFuc2FjdGlvbi5pZDtcbiAgICAgIHRoaXMubG9hZElucHV0c0FuZE91dHB1dHMoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIHNlcmlhbGl6ZSgpIHRvIGdldCB0aGUgY29ycmVjdCB0eERhdGEgd2l0aCB0cmFuc2FjdGlvbiB0eXBlXG4gICAqXG4gICAqIEByZXR1cm4ge1R4RGF0YX1cbiAgICovXG4gIGdldFR4RGF0YSgpOiBUeERhdGEge1xuICAgIGlmICghdGhpcy5fc3VpVHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignZW1wdHkgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRzOiBDYWxsQXJnW10gfCBUcmFuc2FjdGlvbkJsb2NrSW5wdXRbXSA9IHRoaXMuX3N1aVRyYW5zYWN0aW9uLnR4LmlucHV0cy5tYXAoKGlucHV0LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGlucHV0Lmhhc093blByb3BlcnR5KCdPYmplY3QnKSkge1xuICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICB9XG4gICAgICBpZiAoaW5wdXQuaGFzT3duUHJvcGVydHkoJ1B1cmUnKSkge1xuICAgICAgICBpZiAoaW5wdXQuUHVyZS5sZW5ndGggPT09IFNVSV9BRERSRVNTX0xFTkdUSCkge1xuICAgICAgICAgIGNvbnN0IGFkZHJlc3MgPSBub3JtYWxpemVTdWlBZGRyZXNzKFxuICAgICAgICAgICAgYnVpbGRlci5kZShCQ1MuQUREUkVTUywgQnVmZmVyLmZyb20oaW5wdXQuUHVyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpLCAnYmFzZTY0JylcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBJbnB1dHMuUHVyZShhZGRyZXNzLCBCQ1MuQUREUkVTUyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYW1vdW50ID0gYnVpbGRlci5kZShCQ1MuVTY0LCBCdWZmZXIuZnJvbShpbnB1dC5QdXJlKS50b1N0cmluZygnYmFzZTY0JyksICdiYXNlNjQnKTtcbiAgICAgICAgICByZXR1cm4gSW5wdXRzLlB1cmUoYW1vdW50LCBCQ1MuVTY0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlucHV0LmtpbmQgPT09ICdJbnB1dCcgJiYgKGlucHV0LnZhbHVlLmhhc093blByb3BlcnR5KCdPYmplY3QnKSB8fCBpbnB1dC52YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnUHVyZScpKSkge1xuICAgICAgICByZXR1cm4gaW5wdXQudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHdoYXQncyBsZWZ0IGlzIHRoZSBwdXJlIG51bWJlciBvciBhZGRyZXNzIHN0cmluZ1xuICAgICAgcmV0dXJuIElucHV0cy5QdXJlKGlucHV0LnZhbHVlLCBpbnB1dC50eXBlID09PSAncHVyZScgPyBCQ1MuVTY0IDogQkNTLkFERFJFU1MpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcHJvZ3JhbW1hYmxlVHggPSB7XG4gICAgICBpbnB1dHM6IGlucHV0cyxcbiAgICAgIHRyYW5zYWN0aW9uczogdGhpcy5fc3VpVHJhbnNhY3Rpb24udHgudHJhbnNhY3Rpb25zLFxuICAgIH0gYXMgVW5zdGFraW5nUHJvZ3JhbW1hYmxlVHJhbnNhY3Rpb247XG5cbiAgICByZXR1cm4ge1xuICAgICAgc2VuZGVyOiB0aGlzLl9zdWlUcmFuc2FjdGlvbi5zZW5kZXIsXG4gICAgICBleHBpcmF0aW9uOiB7IE5vbmU6IG51bGwgfSxcbiAgICAgIGdhc0RhdGE6IHRoaXMuX3N1aVRyYW5zYWN0aW9uLmdhc0RhdGEsXG4gICAgICBraW5kOiB7XG4gICAgICAgIFByb2dyYW1tYWJsZVRyYW5zYWN0aW9uOiBwcm9ncmFtbWFibGVUeCxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgY29tcGxldGUgZXhwbGFuYXRpb24gZm9yIGEgdW5zdGFraW5nIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7VHhEYXRhfSBqc29uIFRoZSB0cmFuc2FjdGlvbiBkYXRhIGluIGpzb24gZm9ybWF0XG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb25FeHBsYW5hdGlvbn0gZXhwbGFuYXRpb25SZXN1bHQgVGhlIHRyYW5zYWN0aW9uIGV4cGxhbmF0aW9uIHRvIGJlIGNvbXBsZXRlZFxuICAgKiBAcmV0dXJucyB7VHJhbnNhY3Rpb25FeHBsYW5hdGlvbn1cbiAgICovXG4gIGV4cGxhaW5XaXRoZHJhd1N0YWtlZFN1aVRyYW5zYWN0aW9uKGpzb246IFR4RGF0YSwgZXhwbGFuYXRpb25SZXN1bHQ6IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24pOiBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgICBjb25zdCBvdXRwdXRzOiBUcmFuc2FjdGlvblJlY2lwaWVudFtdID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiB0aGlzLnN1aVRyYW5zYWN0aW9uLnNlbmRlcixcbiAgICAgICAgYW1vdW50OiBBTU9VTlRfVU5LTk9XTl9URVhULFxuICAgICAgfSxcbiAgICBdO1xuICAgIGNvbnN0IG91dHB1dEFtb3VudCA9IEFNT1VOVF9VTktOT1dOX1RFWFQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uZXhwbGFuYXRpb25SZXN1bHQsXG4gICAgICBvdXRwdXRBbW91bnQsXG4gICAgICBvdXRwdXRzLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==

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


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