PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/sdk-coin-xtz/dist/src/lib
Просмотр файла: transaction.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;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transaction = void 0;
const sdk_core_1 = require("@bitgo/sdk-core");
const local_forging_1 = require("@taquito/local-forging");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const multisigUtils_1 = require("./multisigUtils");
const Utils = __importStar(require("./utils"));
/**
* Tezos transaction model.
*/
class Transaction extends sdk_core_1.BaseTransaction {
/**
* Public constructor.
*
* @param {Readonly<CoinConfig>} coinConfig
*/
constructor(coinConfig) {
super(coinConfig);
this._owners = [];
}
/**
* Initialize the transaction fields based on another serialized transaction.
*
* @param serializedTransaction Transaction in broadcast format.
*/
async initFromSerializedTransaction(serializedTransaction) {
this._encodedTransaction = serializedTransaction;
try {
const parsedTransaction = await local_forging_1.localForger.parse(serializedTransaction);
await this.initFromParsedTransaction(parsedTransaction);
}
catch (e) {
// If it throws, it is possible the serialized transaction is signed, which is not supported
// by local-forging. Try extracting the last 64 bytes and parse it again.
const unsignedSerializedTransaction = serializedTransaction.slice(0, -128);
const signature = serializedTransaction.slice(-128);
if (Utils.isValidSignature(signature)) {
throw new sdk_core_1.ParseTransactionError('Invalid transaction');
}
// TODO: encode the signature and save it in _signature
const parsedTransaction = await local_forging_1.localForger.parse(unsignedSerializedTransaction);
const transactionId = await Utils.calculateTransactionId(serializedTransaction);
await this.initFromParsedTransaction(parsedTransaction, transactionId);
}
}
/**
* Initialize the transaction fields based on another parsed transaction.
*
* @param {ParsedTransaction} parsedTransaction A Tezos transaction object
* @param {string} transactionId The transaction id of the parsedTransaction if it is signed
*/
async initFromParsedTransaction(parsedTransaction, transactionId) {
if (!this._encodedTransaction) {
this._encodedTransaction = await local_forging_1.localForger.forge(parsedTransaction);
}
if (transactionId) {
// If the transaction id is passed, save it and clean up the entries since they will be
// recalculated
this._id = transactionId;
this._inputs = [];
this._outputs = [];
}
else {
this._id = '';
}
this._parsedTransaction = parsedTransaction;
let operationIndex = 0;
for (const operation of parsedTransaction.contents) {
if (this._source && this._source !== operation.source) {
throw new sdk_core_1.InvalidTransactionError('Source must be the same for every operation but it changed from ' + this._source + ' to ' + operation.source);
}
else {
this._source = operation.source;
}
switch (operation.kind) {
case local_forging_1.CODEC.OP_ORIGINATION:
await this.recordOriginationOpFields(operation, operationIndex);
operationIndex++;
break;
case local_forging_1.CODEC.OP_REVEAL:
this.recordRevealOpFields(operation);
break;
case local_forging_1.CODEC.OP_TRANSACTION:
this.recordTransactionOpFields(operation);
break;
default:
break;
}
}
}
/**
* Record the most important fields from an origination operation.
*
* @param {Operation} operation An operation object from a Tezos transaction
* @param {number} index The origination operation index in the transaction. Used to calculate the
* originated address
*/
async recordOriginationOpFields(operation, index) {
const originationData = (0, multisigUtils_1.getOriginationDataFromOperation)(operation);
if (originationData.forwarderDestination) {
this._type = sdk_core_1.TransactionType.AddressInitialization;
this._forwarderDestination = originationData.forwarderDestination;
}
else {
this._type = sdk_core_1.TransactionType.WalletInitialization;
this._owners = (0, multisigUtils_1.getOwnersPublicKeys)(operation);
}
this._delegate = operation.delegate;
this._outputs.push({
// Kt addresses can only be calculated for signed transactions with an id
address: this._id ? await Utils.calculateOriginatedAddress(this._id, index) : '',
// Balance
value: operation.balance,
});
this._inputs.push({
address: operation.source,
// Balance + fees + max gas + max storage are paid by the source account
value: new bignumber_js_1.default(operation.balance).plus(operation.fee).toString(),
});
}
/**
* Record the most important fields from a reveal operation.
*
* @param {RevealOp} operation A reveal operation object from a Tezos transaction
*/
recordRevealOpFields(operation) {
this._type = sdk_core_1.TransactionType.AccountUpdate;
this._publicKeyToReveal = operation.public_key;
this._inputs.push({
address: operation.source,
// Balance + fees + max gas + max storage are paid by the source account
value: operation.fee,
});
}
/**
* Record the most important fields for a Transaction operation.
*
* @param {TransactionOp} operation A transaction object from a Tezos operation
*/
recordTransactionOpFields(operation) {
if (operation.parameters) {
this._type = sdk_core_1.TransactionType.Send;
}
else {
this._type = sdk_core_1.TransactionType.SingleSigSend;
}
const transferData = (0, multisigUtils_1.getMultisigTransferDataFromOperation)(operation);
// Fees are paid by the source account, along with the amount in the transaction
this._inputs.push({
address: operation.source,
value: new bignumber_js_1.default(transferData.fee.fee).toFixed(0),
});
if (transferData.coin === 'mutez') {
this._outputs.push({
// Kt addresses can only be calculated for signed transactions with an id
address: transferData.to,
// Balance
value: transferData.amount,
});
// The funds being transferred from the wallet
this._inputs.push({
address: transferData.from,
// Balance + fees + max gas + max storage are paid by the source account
value: transferData.amount,
});
}
}
/**
* Sign the transaction with the provided key. It does not check if the signer is allowed to sign
* it or not.
*
* @param {KeyPair} keyPair The key to sign the transaction with
*/
async sign(keyPair) {
// TODO: fail if the transaction is already signed
// Check if there is a transaction to sign
if (!this._parsedTransaction) {
throw new sdk_core_1.InvalidTransactionError('Empty transaction');
}
// Get the transaction body to sign
const encodedTransaction = await local_forging_1.localForger.forge(this._parsedTransaction);
const signedTransaction = await Utils.sign(keyPair, encodedTransaction);
this._encodedTransaction = signedTransaction.sbytes;
// The transaction id can only be calculated for signed transactions
this._id = await Utils.calculateTransactionId(this._encodedTransaction);
await this.initFromParsedTransaction(this._parsedTransaction, this._id);
this._signatures.push(signedTransaction.sig);
}
/**
* Update the list of signatures for a multisig transaction operation.
*
* @param {IndexedSignature[]} signatures List of signatures and the index they should be put on
* in the multisig transfer
* @param {number} index The transfer index to add the signatures to
*/
async addTransferSignature(signatures, index) {
if (!this._parsedTransaction) {
throw new sdk_core_1.InvalidTransactionError('Empty transaction');
}
(0, multisigUtils_1.updateMultisigTransferSignatures)(this._parsedTransaction.contents[index], signatures);
this._encodedTransaction = await local_forging_1.localForger.forge(this._parsedTransaction);
}
/** @inheritdoc */
canSign(key) {
// TODO: check the key belongs to the _source account in _parsedTransaction
return true;
}
/** @inheritdoc */
toJson() {
if (!this._parsedTransaction) {
throw new sdk_core_1.InvalidTransactionError('Empty transaction');
}
return this._parsedTransaction;
}
/** @inheritdoc */
toBroadcastFormat() {
if (!this._encodedTransaction) {
throw new sdk_core_1.InvalidTransactionError('Missing encoded transaction');
}
return this._encodedTransaction;
}
/**
* Get the transaction source if it is available.
*
* @returns {string} Source of the transaction
*/
get source() {
if (!this._source) {
throw new sdk_core_1.InvalidTransactionError('Transaction not initialized');
}
return this._source;
}
/**
* Get the transaction delegation address if it is available.
*
* @returns {string} transaction delegation address
*/
get delegate() {
return this._delegate;
}
/**
* Get the public key revealed by the transaction if it exists
*
* @returns {string} public key
*/
get publicKeyToReveal() {
return this._publicKeyToReveal;
}
/**
* Get the destination of an address initialization transaction if it exists
*
* @returns {string} forwarder destination
*/
get forwarderDestination() {
return this._forwarderDestination;
}
get owners() {
return this._owners;
}
/**
* Get the signatures for the given multisig transfer,
*
* @param {number} transferIndex The transfer script index in the Tezos transaction
* @returns {IndexedSignature[]} A list of signatures with their index inside the multisig transfer
* script
*/
getTransferSignatures(transferIndex = 0) {
if (!this._parsedTransaction) {
return [];
}
return (0, multisigUtils_1.getMultisigTransferSignatures)(this._parsedTransaction.contents[transferIndex]);
}
/**
* Get the list of index per tezos transaction type. This is useful to locate specific operations
* within the transaction and verify or sign them.
*
* @returns {{[p: string]: number[]}} List of indexes where the key is the transaction kind
*/
getIndexesByTransactionType() {
if (!this._parsedTransaction) {
return {};
}
const indexes = {};
for (let i = 0; i < this._parsedTransaction.contents.length; i++) {
const kind = this._parsedTransaction.contents[i].kind;
indexes[kind] = indexes[kind] ? indexes[kind].concat([i]) : [i];
}
return indexes;
}
}
exports.Transaction = Transaction;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQU15QjtBQUV6QiwwREFBNEQ7QUFDNUQsZ0VBQXFDO0FBR3JDLG1EQU15QjtBQUN6QiwrQ0FBaUM7QUFFakM7O0dBRUc7QUFDSCxNQUFhLFdBQVksU0FBUSwwQkFBZTtJQVM5Qzs7OztPQUlHO0lBQ0gsWUFBWSxVQUFnQztRQUMxQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsNkJBQTZCLENBQUMscUJBQTZCO1FBQy9ELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxxQkFBcUIsQ0FBQztRQUNqRCxJQUFJLENBQUM7WUFDSCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sMkJBQVcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN6RSxNQUFNLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsNEZBQTRGO1lBQzVGLHlFQUF5RTtZQUN6RSxNQUFNLDZCQUE2QixHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzRSxNQUFNLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwRCxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLElBQUksZ0NBQXFCLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lB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QztRQUNaLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDbkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDakUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDdEQsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQWxURCxrQ0FrVEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBCYXNlS2V5LFxuICBCYXNlVHJhbnNhY3Rpb24sXG4gIEludmFsaWRUcmFuc2FjdGlvbkVycm9yLFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG4gIFRyYW5zYWN0aW9uVHlwZSxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgeyBDT0RFQywgbG9jYWxGb3JnZXIgfSBmcm9tICdAdGFxdWl0by9sb2NhbC1mb3JnaW5nJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IEluZGV4ZWRTaWduYXR1cmUsIE9yaWdpbmF0aW9uT3AsIFBhcnNlZFRyYW5zYWN0aW9uLCBSZXZlYWxPcCwgVHJhbnNhY3Rpb25PcCB9IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHsgS2V5UGFpciB9IGZyb20gJy4va2V5UGFpcic7XG5pbXBvcnQge1xuICBnZXRNdWx0aXNpZ1RyYW5zZmVyRGF0YUZyb21PcGVyYXRpb24sXG4gIGdldE11bHRpc2lnVHJhbnNmZXJTaWduYXR1cmVzLFxuICBnZXRPcmlnaW5hdGlvbkRhdGFGcm9tT3BlcmF0aW9uLFxuICBnZXRPd25lcnNQdWJsaWNLZXlzLFxuICB1cGRhdGVNdWx0aXNpZ1RyYW5zZmVyU2lnbmF0dXJlcyxcbn0gZnJvbSAnLi9tdWx0aXNpZ1V0aWxzJztcbmltcG9ydCAqIGFzIFV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIFRlem9zIHRyYW5zYWN0aW9uIG1vZGVsLlxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb24gZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb24ge1xuICBwcml2YXRlIF9wYXJzZWRUcmFuc2FjdGlvbj86IFBhcnNlZFRyYW5zYWN0aW9uOyAvLyB0cmFuc2FjdGlvbiBpbiBKU09OIGZvcm1hdFxuICBwcml2YXRlIF9lbmNvZGVkVHJhbnNhY3Rpb24/OiBzdHJpbmc7IC8vIHRyYW5zYWN0aW9uIGluIGhleCBmb3JtYXRcbiAgcHJpdmF0ZSBfc291cmNlOiBzdHJpbmc7XG4gIHByaXZhdGUgX2RlbGVnYXRlPzogc3RyaW5nO1xuICBwcml2YXRlIF9mb3J3YXJkZXJEZXN0aW5hdGlvbj86IHN0cmluZztcbiAgcHJpdmF0ZSBfcHVibGljS2V5VG9SZXZlYWw/OiBzdHJpbmc7XG4gIHByaXZhdGUgX293bmVyczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFB1YmxpYyBjb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFkb25seTxDb2luQ29uZmlnPn0gY29pbkNvbmZpZ1xuICAgKi9cbiAgY29uc3RydWN0b3IoY29pbkNvbmZpZzogUmVhZG9ubHk8Q29pbkNvbmZpZz4pIHtcbiAgICBzdXBlcihjb2luQ29uZmlnKTtcbiAgICB0aGlzLl9vd25lcnMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSB0cmFuc2FjdGlvbiBmaWVsZHMgYmFzZWQgb24gYW5vdGhlciBzZXJpYWxpemVkIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gc2VyaWFsaXplZFRyYW5zYWN0aW9uIFRyYW5zYWN0aW9uIGluIGJyb2FkY2FzdCBmb3JtYXQuXG4gICAqL1xuICBhc3luYyBpbml0RnJvbVNlcmlhbGl6ZWRUcmFuc2FjdGlvbihzZXJpYWxpemVkVHJhbnNhY3Rpb246IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuX2VuY29kZWRUcmFuc2FjdGlvbiA9IHNlcmlhbGl6ZWRUcmFuc2FjdGlvbjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBsb2NhbEZvcmdlci5wYXJzZShzZXJpYWxpemVkVHJhbnNhY3Rpb24pO1xuICAgICAgYXdhaXQgdGhpcy5pbml0RnJvbVBhcnNlZFRyYW5zYWN0aW9uKHBhcnNlZFRyYW5zYWN0aW9uKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBJZiBpdCB0aHJvd3MsIGl0IGlzIHBvc3NpYmxlIHRoZSBzZXJpYWxpemVkIHRyYW5zYWN0aW9uIGlzIHNpZ25lZCwgd2hpY2ggaXMgbm90IHN1cHBvcnRlZFxuICAgICAgLy8gYnkgbG9jYWwtZm9yZ2luZy4gVHJ5IGV4dHJhY3RpbmcgdGhlIGxhc3QgNjQgYnl0ZXMgYW5kIHBhcnNlIGl0IGFnYWluLlxuICAgICAgY29uc3QgdW5zaWduZWRTZXJpYWxpemVkVHJhbnNhY3Rpb24gPSBzZXJpYWxpemVkVHJhbnNhY3Rpb24uc2xpY2UoMCwgLTEyOCk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBzZXJpYWxpemVkVHJhbnNhY3Rpb24uc2xpY2UoLTEyOCk7XG4gICAgICBpZiAoVXRpbHMuaXNWYWxpZFNpZ25hdHVyZShzaWduYXR1cmUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE86IGVuY29kZSB0aGUgc2lnbmF0dXJlIGFuZCBzYXZlIGl0IGluIF9zaWduYXR1cmVcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgbG9jYWxGb3JnZXIucGFyc2UodW5zaWduZWRTZXJpYWxpemVkVHJhbnNhY3Rpb24pO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25JZCA9IGF3YWl0IFV0aWxzLmNhbGN1bGF0ZVRyYW5zYWN0aW9uSWQoc2VyaWFsaXplZFRyYW5zYWN0aW9uKTtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdEZyb21QYXJzZWRUcmFuc2FjdGlvbihwYXJzZWRUcmFuc2FjdGlvbiwgdHJhbnNhY3Rpb25JZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIHRyYW5zYWN0aW9uIGZpZWxkcyBiYXNlZCBvbiBhbm90aGVyIHBhcnNlZCB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtQYXJzZWRUcmFuc2FjdGlvbn0gcGFyc2VkVHJhbnNhY3Rpb24gQSBUZXpvcyB0cmFuc2FjdGlvbiBvYmplY3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRyYW5zYWN0aW9uSWQgVGhlIHRyYW5zYWN0aW9uIGlkIG9mIHRoZSBwYXJzZWRUcmFuc2FjdGlvbiBpZiBpdCBpcyBzaWduZWRcbiAgICovXG4gIGFzeW5jIGluaXRGcm9tUGFyc2VkVHJhbnNhY3Rpb24ocGFyc2VkVHJhbnNhY3Rpb246IFBhcnNlZFRyYW5zYWN0aW9uLCB0cmFuc2FjdGlvbklkPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLl9lbmNvZGVkVHJhbnNhY3Rpb24pIHtcbiAgICAgIHRoaXMuX2VuY29kZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGxvY2FsRm9yZ2VyLmZvcmdlKHBhcnNlZFRyYW5zYWN0aW9uKTtcbiAgICB9XG4gICAgaWYgKHRyYW5zYWN0aW9uSWQpIHtcbiAgICAgIC8vIElmIHRoZSB0cmFuc2FjdGlvbiBpZCBpcyBwYXNzZWQsIHNhdmUgaXQgYW5kIGNsZWFuIHVwIHRoZSBlbnRyaWVzIHNpbmNlIHRoZXkgd2lsbCBiZVxuICAgICAgLy8gcmVjYWxjdWxhdGVkXG4gICAgICB0aGlzLl9pZCA9IHRyYW5zYWN0aW9uSWQ7XG4gICAgICB0aGlzLl9pbnB1dHMgPSBbXTtcbiAgICAgIHRoaXMuX291dHB1dHMgPSBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faWQgPSAnJztcbiAgICB9XG4gICAgdGhpcy5fcGFyc2VkVHJhbnNhY3Rpb24gPSBwYXJzZWRUcmFuc2FjdGlvbjtcbiAgICBsZXQgb3BlcmF0aW9uSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHBhcnNlZFRyYW5zYWN0aW9uLmNvbnRlbnRzKSB7XG4gICAgICBpZiAodGhpcy5fc291cmNlICYmIHRoaXMuX3NvdXJjZSAhPT0gb3BlcmF0aW9uLnNvdXJjZSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoXG4gICAgICAgICAgJ1NvdXJjZSBtdXN0IGJlIHRoZSBzYW1lIGZvciBldmVyeSBvcGVyYXRpb24gYnV0IGl0IGNoYW5nZWQgZnJvbSAnICsgdGhpcy5fc291cmNlICsgJyB0byAnICsgb3BlcmF0aW9uLnNvdXJjZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc291cmNlID0gb3BlcmF0aW9uLnNvdXJjZTtcbiAgICAgIH1cbiAgICAgIHN3aXRjaCAob3BlcmF0aW9uLmtpbmQpIHtcbiAgICAgICAgY2FzZSBDT0RFQy5PUF9PUklHSU5BVElPTjpcbiAgICAgICAgICBhd2FpdCB0aGlzLnJlY29yZE9yaWdpbmF0aW9uT3BGaWVsZHMob3BlcmF0aW9uIGFzIE9yaWdpbmF0aW9uT3AsIG9wZXJhdGlvbkluZGV4KTtcbiAgICAgICAgICBvcGVyYXRpb25JbmRleCsrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENPREVDLk9QX1JFVkVBTDpcbiAgICAgICAgICB0aGlzLnJlY29yZFJldmVhbE9wRmllbGRzKG9wZXJhdGlvbiBhcyBSZXZlYWxPcCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ09ERUMuT1BfVFJBTlNBQ1RJT046XG4gICAgICAgICAgdGhpcy5yZWNvcmRUcmFuc2FjdGlvbk9wRmllbGRzKG9wZXJhdGlvbiBhcyBUcmFuc2FjdGlvbk9wKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHRoZSBtb3N0IGltcG9ydGFudCBmaWVsZHMgZnJvbSBhbiBvcmlnaW5hdGlvbiBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9ufSBvcGVyYXRpb24gQW4gb3BlcmF0aW9uIG9iamVjdCBmcm9tIGEgVGV6b3MgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBvcmlnaW5hdGlvbiBvcGVyYXRpb24gaW5kZXggaW4gdGhlIHRyYW5zYWN0aW9uLiBVc2VkIHRvIGNhbGN1bGF0ZSB0aGVcbiAgICogICAgICBvcmlnaW5hdGVkIGFkZHJlc3NcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVjb3JkT3JpZ2luYXRpb25PcEZpZWxkcyhvcGVyYXRpb246IE9yaWdpbmF0aW9uT3AsIGluZGV4OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvcmlnaW5hdGlvbkRhdGEgPSBnZXRPcmlnaW5hdGlvbkRhdGFGcm9tT3BlcmF0aW9uKG9wZXJhdGlvbik7XG4gICAgaWYgKG9yaWdpbmF0aW9uRGF0YS5mb3J3YXJkZXJEZXN0aW5hdGlvbikge1xuICAgICAgdGhpcy5fdHlwZSA9IFRyYW5zYWN0aW9uVHlwZS5BZGRyZXNzSW5pdGlhbGl6YXRpb247XG4gICAgICB0aGlzLl9mb3J3YXJkZXJEZXN0aW5hdGlvbiA9IG9yaWdpbmF0aW9uRGF0YS5mb3J3YXJkZXJEZXN0aW5hdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdHlwZSA9IFRyYW5zYWN0aW9uVHlwZS5XYWxsZXRJbml0aWFsaXphdGlvbjtcbiAgICAgIHRoaXMuX293bmVycyA9IGdldE93bmVyc1B1YmxpY0tleXMob3BlcmF0aW9uKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kZWxlZ2F0ZSA9IG9wZXJhdGlvbi5kZWxlZ2F0ZTtcbiAgICB0aGlzLl9vdXRwdXRzLnB1c2goe1xuICAgICAgLy8gS3QgYWRkcmVzc2VzIGNhbiBvbmx5IGJlIGNhbGN1bGF0ZWQgZm9yIHNpZ25lZCB0cmFuc2FjdGlvbnMgd2l0aCBhbiBpZFxuICAgICAgYWRkcmVzczogdGhpcy5faWQgPyBhd2FpdCBVdGlscy5jYWxjdWxhdGVPcmlnaW5hdGVkQWRkcmVzcyh0aGlzLl9pZCwgaW5kZXgpIDogJycsXG4gICAgICAvLyBCYWxhbmNlXG4gICAgICB2YWx1ZTogb3BlcmF0aW9uLmJhbGFuY2UsXG4gICAgfSk7XG4gICAgdGhpcy5faW5wdXRzLnB1c2goe1xuICAgICAgYWRkcmVzczogb3BlcmF0aW9uLnNvdXJjZSxcbiAgICAgIC8vIEJhbGFuY2UgKyBmZWVzICsgbWF4IGdhcyArIG1heCBzdG9yYWdlIGFyZSBwYWlkIGJ5IHRoZSBzb3VyY2UgYWNjb3VudFxuICAgICAgdmFsdWU6IG5ldyBCaWdOdW1iZXIob3BlcmF0aW9uLmJhbGFuY2UpLnBsdXMob3BlcmF0aW9uLmZlZSkudG9TdHJpbmcoKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhlIG1vc3QgaW1wb3J0YW50IGZpZWxkcyBmcm9tIGEgcmV2ZWFsIG9wZXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtSZXZlYWxPcH0gb3BlcmF0aW9uIEEgcmV2ZWFsIG9wZXJhdGlvbiBvYmplY3QgZnJvbSBhIFRlem9zIHRyYW5zYWN0aW9uXG4gICAqL1xuICBwcml2YXRlIHJlY29yZFJldmVhbE9wRmllbGRzKG9wZXJhdGlvbjogUmV2ZWFsT3ApOiB2b2lkIHtcbiAgICB0aGlzLl90eXBlID0gVHJhbnNhY3Rpb25UeXBlLkFjY291bnRVcGRhdGU7XG4gICAgdGhpcy5fcHVibGljS2V5VG9SZXZlYWwgPSBvcGVyYXRpb24ucHVibGljX2tleTtcbiAgICB0aGlzLl9pbnB1dHMucHVzaCh7XG4gICAgICBhZGRyZXNzOiBvcGVyYXRpb24uc291cmNlLFxuICAgICAgLy8gQmFsYW5jZSArIGZlZXMgKyBtYXggZ2FzICsgbWF4IHN0b3JhZ2UgYXJlIHBhaWQgYnkgdGhlIHNvdXJjZSBhY2NvdW50XG4gICAgICB2YWx1ZTogb3BlcmF0aW9uLmZlZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhlIG1vc3QgaW1wb3J0YW50IGZpZWxkcyBmb3IgYSBUcmFuc2FjdGlvbiBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb25PcH0gb3BlcmF0aW9uIEEgdHJhbnNhY3Rpb24gb2JqZWN0IGZyb20gYSBUZXpvcyBvcGVyYXRpb25cbiAgICovXG4gIHByaXZhdGUgcmVjb3JkVHJhbnNhY3Rpb25PcEZpZWxkcyhvcGVyYXRpb246IFRyYW5zYWN0aW9uT3ApOiB2b2lkIHtcbiAgICBpZiAob3BlcmF0aW9uLnBhcmFtZXRlcnMpIHtcbiAgICAgIHRoaXMuX3R5cGUgPSBUcmFuc2FjdGlvblR5cGUuU2VuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdHlwZSA9IFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kO1xuICAgIH1cbiAgICBjb25zdCB0cmFuc2ZlckRhdGEgPSBnZXRNdWx0aXNpZ1RyYW5zZmVyRGF0YUZyb21PcGVyYXRpb24ob3BlcmF0aW9uKTtcbiAgICAvLyBGZWVzIGFyZSBwYWlkIGJ5IHRoZSBzb3VyY2UgYWNjb3VudCwgYWxvbmcgd2l0aCB0aGUgYW1vdW50IGluIHRoZSB0cmFuc2FjdGlvblxuICAgIHRoaXMuX2lucHV0cy5wdXNoKHtcbiAgICAgIGFkZHJlc3M6IG9wZXJhdGlvbi5zb3VyY2UsXG4gICAgICB2YWx1ZTogbmV3IEJpZ051bWJlcih0cmFuc2ZlckRhdGEuZmVlLmZlZSkudG9GaXhlZCgwKSxcbiAgICB9KTtcblxuICAgIGlmICh0cmFuc2ZlckRhdGEuY29pbiA9PT0gJ211dGV6Jykge1xuICAgICAgdGhpcy5fb3V0cHV0cy5wdXNoKHtcbiAgICAgICAgLy8gS3QgYWRkcmVzc2VzIGNhbiBvbmx5IGJlIGNhbGN1bGF0ZWQgZm9yIHNpZ25lZCB0cmFuc2FjdGlvbnMgd2l0aCBhbiBpZFxuICAgICAgICBhZGRyZXNzOiB0cmFuc2ZlckRhdGEudG8sXG4gICAgICAgIC8vIEJhbGFuY2VcbiAgICAgICAgdmFsdWU6IHRyYW5zZmVyRGF0YS5hbW91bnQsXG4gICAgICB9KTtcbiAgICAgIC8vIFRoZSBmdW5kcyBiZWluZyB0cmFuc2ZlcnJlZCBmcm9tIHRoZSB3YWxsZXRcbiAgICAgIHRoaXMuX2lucHV0cy5wdXNoKHtcbiAgICAgICAgYWRkcmVzczogdHJhbnNmZXJEYXRhLmZyb20sXG4gICAgICAgIC8vIEJhbGFuY2UgKyBmZWVzICsgbWF4IGdhcyArIG1heCBzdG9yYWdlIGFyZSBwYWlkIGJ5IHRoZSBzb3VyY2UgYWNjb3VudFxuICAgICAgICB2YWx1ZTogdHJhbnNmZXJEYXRhLmFtb3VudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIHRoZSB0cmFuc2FjdGlvbiB3aXRoIHRoZSBwcm92aWRlZCBrZXkuIEl0IGRvZXMgbm90IGNoZWNrIGlmIHRoZSBzaWduZXIgaXMgYWxsb3dlZCB0byBzaWduXG4gICAqIGl0IG9yIG5vdC5cbiAgICpcbiAgICogQHBhcmFtIHtLZXlQYWlyfSBrZXlQYWlyIFRoZSBrZXkgdG8gc2lnbiB0aGUgdHJhbnNhY3Rpb24gd2l0aFxuICAgKi9cbiAgYXN5bmMgc2lnbihrZXlQYWlyOiBLZXlQYWlyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gVE9ETzogZmFpbCBpZiB0aGUgdHJhbnNhY3Rpb24gaXMgYWxyZWFkeSBzaWduZWRcbiAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhIHRyYW5zYWN0aW9uIHRvIHNpZ25cbiAgICBpZiAoIXRoaXMuX3BhcnNlZFRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIC8vIEdldCB0aGUgdHJhbnNhY3Rpb24gYm9keSB0byBzaWduXG4gICAgY29uc3QgZW5jb2RlZFRyYW5zYWN0aW9uID0gYXdhaXQgbG9jYWxGb3JnZXIuZm9yZ2UodGhpcy5fcGFyc2VkVHJhbnNhY3Rpb24pO1xuXG4gICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBVdGlscy5zaWduKGtleVBhaXIsIGVuY29kZWRUcmFuc2FjdGlvbik7XG4gICAgdGhpcy5fZW5jb2RlZFRyYW5zYWN0aW9uID0gc2lnbmVkVHJhbnNhY3Rpb24uc2J5dGVzO1xuXG4gICAgLy8gVGhlIHRyYW5zYWN0aW9uIGlkIGNhbiBvbmx5IGJlIGNhbGN1bGF0ZWQgZm9yIHNpZ25lZCB0cmFuc2FjdGlvbnNcbiAgICB0aGlzLl9pZCA9IGF3YWl0IFV0aWxzLmNhbGN1bGF0ZVRyYW5zYWN0aW9uSWQodGhpcy5fZW5jb2RlZFRyYW5zYWN0aW9uKTtcbiAgICBhd2FpdCB0aGlzLmluaXRGcm9tUGFyc2VkVHJhbnNhY3Rpb24odGhpcy5fcGFyc2VkVHJhbnNhY3Rpb24sIHRoaXMuX2lkKTtcblxuICAgIHRoaXMuX3NpZ25hdHVyZXMucHVzaChzaWduZWRUcmFuc2FjdGlvbi5zaWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgbGlzdCBvZiBzaWduYXR1cmVzIGZvciBhIG11bHRpc2lnIHRyYW5zYWN0aW9uIG9wZXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtJbmRleGVkU2lnbmF0dXJlW119IHNpZ25hdHVyZXMgTGlzdCBvZiBzaWduYXR1cmVzIGFuZCB0aGUgaW5kZXggdGhleSBzaG91bGQgYmUgcHV0IG9uXG4gICAqICAgIGluIHRoZSBtdWx0aXNpZyB0cmFuc2ZlclxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIHRyYW5zZmVyIGluZGV4IHRvIGFkZCB0aGUgc2lnbmF0dXJlcyB0b1xuICAgKi9cbiAgYXN5bmMgYWRkVHJhbnNmZXJTaWduYXR1cmUoc2lnbmF0dXJlczogSW5kZXhlZFNpZ25hdHVyZVtdLCBpbmRleDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdFbXB0eSB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgICB1cGRhdGVNdWx0aXNpZ1RyYW5zZmVyU2lnbmF0dXJlcyh0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbi5jb250ZW50c1tpbmRleF0gYXMgVHJhbnNhY3Rpb25PcCwgc2lnbmF0dXJlcyk7XG4gICAgdGhpcy5fZW5jb2RlZFRyYW5zYWN0aW9uID0gYXdhaXQgbG9jYWxGb3JnZXIuZm9yZ2UodGhpcy5fcGFyc2VkVHJhbnNhY3Rpb24pO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGNhblNpZ24oa2V5OiBCYXNlS2V5KTogYm9vbGVhbiB7XG4gICAgLy8gVE9ETzogY2hlY2sgdGhlIGtleSBiZWxvbmdzIHRvIHRoZSBfc291cmNlIGFjY291bnQgaW4gX3BhcnNlZFRyYW5zYWN0aW9uXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdG9Kc29uKCk6IFBhcnNlZFRyYW5zYWN0aW9uIHtcbiAgICBpZiAoIXRoaXMuX3BhcnNlZFRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB0b0Jyb2FkY2FzdEZvcm1hdCgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5fZW5jb2RlZFRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ01pc3NpbmcgZW5jb2RlZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlZFRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdHJhbnNhY3Rpb24gc291cmNlIGlmIGl0IGlzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gU291cmNlIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZ2V0IHNvdXJjZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5fc291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ1RyYW5zYWN0aW9uIG5vdCBpbml0aWFsaXplZCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdHJhbnNhY3Rpb24gZGVsZWdhdGlvbiBhZGRyZXNzIGlmIGl0IGlzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gdHJhbnNhY3Rpb24gZGVsZWdhdGlvbiBhZGRyZXNzXG4gICAqL1xuICBnZXQgZGVsZWdhdGUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fZGVsZWdhdGU7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBwdWJsaWMga2V5IHJldmVhbGVkIGJ5IHRoZSB0cmFuc2FjdGlvbiBpZiBpdCBleGlzdHNcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gcHVibGljIGtleVxuICAgKi9cbiAgZ2V0IHB1YmxpY0tleVRvUmV2ZWFsKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3B1YmxpY0tleVRvUmV2ZWFsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGVzdGluYXRpb24gb2YgYW4gYWRkcmVzcyBpbml0aWFsaXphdGlvbiB0cmFuc2FjdGlvbiBpZiBpdCBleGlzdHNcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gZm9yd2FyZGVyIGRlc3RpbmF0aW9uXG4gICAqL1xuICBnZXQgZm9yd2FyZGVyRGVzdGluYXRpb24oKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fZm9yd2FyZGVyRGVzdGluYXRpb247XG4gIH1cblxuICBnZXQgb3duZXJzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fb3duZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2lnbmF0dXJlcyBmb3IgdGhlIGdpdmVuIG11bHRpc2lnIHRyYW5zZmVyLFxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdHJhbnNmZXJJbmRleCBUaGUgdHJhbnNmZXIgc2NyaXB0IGluZGV4IGluIHRoZSBUZXpvcyB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7SW5kZXhlZFNpZ25hdHVyZVtdfSBBIGxpc3Qgb2Ygc2lnbmF0dXJlcyB3aXRoIHRoZWlyIGluZGV4IGluc2lkZSB0aGUgbXVsdGlzaWcgdHJhbnNmZXJcbiAgICogICAgICBzY3JpcHRcbiAgICovXG4gIGdldFRyYW5zZmVyU2lnbmF0dXJlcyh0cmFuc2ZlckluZGV4ID0gMCk6IEluZGV4ZWRTaWduYXR1cmVbXSB7XG4gICAgaWYgKCF0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbikge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0TXVsdGlzaWdUcmFuc2ZlclNpZ25hdHVyZXModGhpcy5fcGFyc2VkVHJhbnNhY3Rpb24uY29udGVudHNbdHJhbnNmZXJJbmRleF0gYXMgVHJhbnNhY3Rpb25PcCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBsaXN0IG9mIGluZGV4IHBlciB0ZXpvcyB0cmFuc2FjdGlvbiB0eXBlLiBUaGlzIGlzIHVzZWZ1bCB0byBsb2NhdGUgc3BlY2lmaWMgb3BlcmF0aW9uc1xuICAgKiB3aXRoaW4gdGhlIHRyYW5zYWN0aW9uIGFuZCB2ZXJpZnkgb3Igc2lnbiB0aGVtLlxuICAgKlxuICAgKiBAcmV0dXJucyB7e1twOiBzdHJpbmddOiBudW1iZXJbXX19IExpc3Qgb2YgaW5kZXhlcyB3aGVyZSB0aGUga2V5IGlzIHRoZSB0cmFuc2FjdGlvbiBraW5kXG4gICAqL1xuICBnZXRJbmRleGVzQnlUcmFuc2FjdGlvblR5cGUoKTogeyBba2luZDogc3RyaW5nXTogbnVtYmVyW10gfSB7XG4gICAgaWYgKCF0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbikge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBpbmRleGVzID0ge307XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9wYXJzZWRUcmFuc2FjdGlvbi5jb250ZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qga2luZCA9IHRoaXMuX3BhcnNlZFRyYW5zYWN0aW9uLmNvbnRlbnRzW2ldLmtpbmQ7XG4gICAgICBpbmRleGVzW2tpbmRdID0gaW5kZXhlc1traW5kXSA/IGluZGV4ZXNba2luZF0uY29uY2F0KFtpXSkgOiBbaV07XG4gICAgfVxuICAgIHJldHVybiBpbmRleGVzO1xuICB9XG59XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!