PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/avalanche/dist/apis/evm
Просмотр файла: api.js
"use strict";
/**
* @packageDocumentation
* @module API-EVM
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EVMAPI = void 0;
const buffer_1 = require("buffer/");
const bn_js_1 = __importDefault(require("bn.js"));
const jrpcapi_1 = require("../../common/jrpcapi");
const bintools_1 = __importDefault(require("../../utils/bintools"));
const utxos_1 = require("./utxos");
const keychain_1 = require("./keychain");
const constants_1 = require("../../utils/constants");
const tx_1 = require("./tx");
const constants_2 = require("./constants");
const inputs_1 = require("./inputs");
const outputs_1 = require("./outputs");
const exporttx_1 = require("./exporttx");
const errors_1 = require("../../utils/errors");
const utils_1 = require("../../utils");
/**
* @ignore
*/
const bintools = bintools_1.default.getInstance();
const serialization = utils_1.Serialization.getInstance();
/**
* Class for interacting with a node's EVMAPI
*
* @category RPCAPIs
*
* @remarks This extends the [[JRPCAPI]] class. This class should not be directly called. Instead, use the [[Avalanche.addAPI]] function to register this interface with Avalanche.
*/
class EVMAPI extends jrpcapi_1.JRPCAPI {
/**
* This class should not be instantiated directly.
* Instead use the [[Avalanche.addAPI]] method.
*
* @param core A reference to the Avalanche class
* @param baseURL Defaults to the string "/ext/bc/C/avax" as the path to blockchain's baseURL
* @param blockchainID The Blockchain's ID. Defaults to an empty string: ""
*/
constructor(core, baseURL = "/ext/bc/C/avax", blockchainID = "") {
super(core, baseURL);
/**
* @ignore
*/
this.keychain = new keychain_1.KeyChain("", "");
this.blockchainID = "";
this.blockchainAlias = undefined;
this.AVAXAssetID = undefined;
this.txFee = undefined;
/**
* Gets the alias for the blockchainID if it exists, otherwise returns `undefined`.
*
* @returns The alias for the blockchainID
*/
this.getBlockchainAlias = () => {
if (typeof this.blockchainAlias === "undefined") {
const netID = this.core.getNetworkID();
if (netID in constants_1.Defaults.network &&
this.blockchainID in constants_1.Defaults.network[`${netID}`]) {
this.blockchainAlias =
constants_1.Defaults.network[`${netID}`][this.blockchainID]["alias"];
return this.blockchainAlias;
}
else {
/* istanbul ignore next */
return undefined;
}
}
return this.blockchainAlias;
};
/**
* Sets the alias for the blockchainID.
*
* @param alias The alias for the blockchainID.
*
*/
this.setBlockchainAlias = (alias) => {
this.blockchainAlias = alias;
/* istanbul ignore next */
return undefined;
};
/**
* Gets the blockchainID and returns it.
*
* @returns The blockchainID
*/
this.getBlockchainID = () => this.blockchainID;
/**
* Refresh blockchainID, and if a blockchainID is passed in, use that.
*
* @param Optional. BlockchainID to assign, if none, uses the default based on networkID.
*
* @returns A boolean if the blockchainID was successfully refreshed.
*/
this.refreshBlockchainID = (blockchainID = undefined) => {
const netID = this.core.getNetworkID();
if (typeof blockchainID === "undefined" &&
typeof constants_1.Defaults.network[`${netID}`] !== "undefined") {
this.blockchainID = constants_1.Defaults.network[`${netID}`].C.blockchainID; //default to C-Chain
return true;
}
if (typeof blockchainID === "string") {
this.blockchainID = blockchainID;
return true;
}
return false;
};
/**
* Takes an address string and returns its {@link https://github.com/feross/buffer|Buffer} representation if valid.
*
* @returns A {@link https://github.com/feross/buffer|Buffer} for the address if valid, undefined if not valid.
*/
this.parseAddress = (addr) => {
const alias = this.getBlockchainAlias();
const blockchainID = this.getBlockchainID();
return bintools.parseAddress(addr, blockchainID, alias, constants_2.EVMConstants.ADDRESSLENGTH);
};
this.addressFromBuffer = (address) => {
const chainID = this.getBlockchainAlias()
? this.getBlockchainAlias()
: this.getBlockchainID();
const type = "bech32";
return serialization.bufferToType(address, type, this.core.getHRP(), chainID);
};
/**
* Retrieves an assets name and symbol.
*
* @param assetID Either a {@link https://github.com/feross/buffer|Buffer} or an b58 serialized string for the AssetID or its alias.
*
* @returns Returns a Promise Asset with keys "name", "symbol", "assetID" and "denomination".
*/
this.getAssetDescription = (assetID) => __awaiter(this, void 0, void 0, function* () {
let asset;
if (typeof assetID !== "string") {
asset = bintools.cb58Encode(assetID);
}
else {
asset = assetID;
}
const params = {
assetID: asset
};
const tmpBaseURL = this.getBaseURL();
// set base url to get asset description
this.setBaseURL("/ext/bc/X");
const response = yield this.callMethod("avm.getAssetDescription", params);
// set base url back what it originally was
this.setBaseURL(tmpBaseURL);
return {
name: response.data.result.name,
symbol: response.data.result.symbol,
assetID: bintools.cb58Decode(response.data.result.assetID),
denomination: parseInt(response.data.result.denomination, 10)
};
});
/**
* Fetches the AVAX AssetID and returns it in a Promise.
*
* @param refresh This function caches the response. Refresh = true will bust the cache.
*
* @returns The the provided string representing the AVAX AssetID
*/
this.getAVAXAssetID = (refresh = false) => __awaiter(this, void 0, void 0, function* () {
if (typeof this.AVAXAssetID === "undefined" || refresh) {
const asset = yield this.getAssetDescription(constants_1.PrimaryAssetAlias);
this.AVAXAssetID = asset.assetID;
}
return this.AVAXAssetID;
});
/**
* Overrides the defaults and sets the cache to a specific AVAX AssetID
*
* @param avaxAssetID A cb58 string or Buffer representing the AVAX AssetID
*
* @returns The the provided string representing the AVAX AssetID
*/
this.setAVAXAssetID = (avaxAssetID) => {
if (typeof avaxAssetID === "string") {
avaxAssetID = bintools.cb58Decode(avaxAssetID);
}
this.AVAXAssetID = avaxAssetID;
};
/**
* Gets the default tx fee for this chain.
*
* @returns The default tx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getDefaultTxFee = () => {
return this.core.getNetworkID() in constants_1.Defaults.network
? new bn_js_1.default(constants_1.Defaults.network[this.core.getNetworkID()]["C"]["txFee"])
: new bn_js_1.default(0);
};
/**
* returns the amount of [assetID] for the given address in the state of the given block number.
* "latest", "pending", and "accepted" meta block numbers are also allowed.
*
* @param hexAddress The hex representation of the address
* @param blockHeight The block height
* @param assetID The asset ID
*
* @returns Returns a Promise object containing the balance
*/
this.getAssetBalance = (hexAddress, blockHeight, assetID) => __awaiter(this, void 0, void 0, function* () {
const params = [hexAddress, blockHeight, assetID];
const method = "eth_getAssetBalance";
const path = "ext/bc/C/rpc";
const response = yield this.callMethod(method, params, path);
return response.data;
});
/**
* Returns the status of a provided atomic transaction ID by calling the node's `getAtomicTxStatus` method.
*
* @param txID The string representation of the transaction ID
*
* @returns Returns a Promise string containing the status retrieved from the node
*/
this.getAtomicTxStatus = (txID) => __awaiter(this, void 0, void 0, function* () {
const params = {
txID
};
const response = yield this.callMethod("avax.getAtomicTxStatus", params);
return response.data.result.status
? response.data.result.status
: response.data.result;
});
/**
* Returns the transaction data of a provided transaction ID by calling the node's `getAtomicTx` method.
*
* @param txID The string representation of the transaction ID
*
* @returns Returns a Promise string containing the bytes retrieved from the node
*/
this.getAtomicTx = (txID) => __awaiter(this, void 0, void 0, function* () {
const params = {
txID
};
const response = yield this.callMethod("avax.getAtomicTx", params);
return response.data.result.tx;
});
/**
* Gets the tx fee for this chain.
*
* @returns The tx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getTxFee = () => {
if (typeof this.txFee === "undefined") {
this.txFee = this.getDefaultTxFee();
}
return this.txFee;
};
/**
* Send ANT (Avalanche Native Token) assets including AVAX from the C-Chain to an account on the X-Chain.
*
* After calling this method, you must call the X-Chain’s import method to complete the transfer.
*
* @param username The Keystore user that controls the X-Chain account specified in `to`
* @param password The password of the Keystore user
* @param to The account on the X-Chain to send the AVAX to.
* @param amount Amount of asset to export as a {@link https://github.com/indutny/bn.js/|BN}
* @param assetID The asset id which is being sent
*
* @returns String representing the transaction id
*/
this.export = (username, password, to, amount, assetID) => __awaiter(this, void 0, void 0, function* () {
const params = {
to,
amount: amount.toString(10),
username,
password,
assetID
};
const response = yield this.callMethod("avax.export", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Send AVAX from the C-Chain to an account on the X-Chain.
*
* After calling this method, you must call the X-Chain’s importAVAX method to complete the transfer.
*
* @param username The Keystore user that controls the X-Chain account specified in `to`
* @param password The password of the Keystore user
* @param to The account on the X-Chain to send the AVAX to.
* @param amount Amount of AVAX to export as a {@link https://github.com/indutny/bn.js/|BN}
*
* @returns String representing the transaction id
*/
this.exportAVAX = (username, password, to, amount) => __awaiter(this, void 0, void 0, function* () {
const params = {
to,
amount: amount.toString(10),
username,
password
};
const response = yield this.callMethod("avax.exportAVAX", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Retrieves the UTXOs related to the addresses provided from the node's `getUTXOs` method.
*
* @param addresses An array of addresses as cb58 strings or addresses as {@link https://github.com/feross/buffer|Buffer}s
* @param sourceChain A string for the chain to look for the UTXO's. Default is to use this chain, but if exported UTXOs exist
* from other chains, this can used to pull them instead.
* @param limit Optional. Returns at most [limit] addresses. If [limit] == 0 or > [maxUTXOsToFetch], fetches up to [maxUTXOsToFetch].
* @param startIndex Optional. [StartIndex] defines where to start fetching UTXOs (for pagination.)
* UTXOs fetched are from addresses equal to or greater than [StartIndex.Address]
* For address [StartIndex.Address], only UTXOs with IDs greater than [StartIndex.Utxo] will be returned.
*/
this.getUTXOs = (addresses, sourceChain = undefined, limit = 0, startIndex = undefined, encoding = "hex") => __awaiter(this, void 0, void 0, function* () {
if (typeof addresses === "string") {
addresses = [addresses];
}
const params = {
addresses: addresses,
limit,
encoding
};
if (typeof startIndex !== "undefined" && startIndex) {
params.startIndex = startIndex;
}
if (typeof sourceChain !== "undefined") {
params.sourceChain = sourceChain;
}
const response = yield this.callMethod("avax.getUTXOs", params);
const utxos = new utxos_1.UTXOSet();
const data = response.data.result.utxos;
if (data.length > 0 && data[0].substring(0, 2) === "0x") {
const cb58Strs = [];
data.forEach((str) => {
cb58Strs.push(bintools.cb58Encode(new buffer_1.Buffer(str.slice(2), "hex")));
});
utxos.addArray(cb58Strs, false);
}
else {
utxos.addArray(data, false);
}
response.data.result.utxos = utxos;
return response.data.result;
});
/**
* Send ANT (Avalanche Native Token) assets including AVAX from an account on the X-Chain to an address on the C-Chain. This transaction
* must be signed with the key of the account that the asset is sent from and which pays
* the transaction fee.
*
* @param username The Keystore user that controls the account specified in `to`
* @param password The password of the Keystore user
* @param to The address of the account the asset is sent to.
* @param sourceChain The chainID where the funds are coming from. Ex: "X"
*
* @returns Promise for a string for the transaction, which should be sent to the network
* by calling issueTx.
*/
this.import = (username, password, to, sourceChain) => __awaiter(this, void 0, void 0, function* () {
const params = {
to,
sourceChain,
username,
password
};
const response = yield this.callMethod("avax.import", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Send AVAX from an account on the X-Chain to an address on the C-Chain. This transaction
* must be signed with the key of the account that the AVAX is sent from and which pays
* the transaction fee.
*
* @param username The Keystore user that controls the account specified in `to`
* @param password The password of the Keystore user
* @param to The address of the account the AVAX is sent to. This must be the same as the to
* argument in the corresponding call to the X-Chain’s exportAVAX
* @param sourceChain The chainID where the funds are coming from.
*
* @returns Promise for a string for the transaction, which should be sent to the network
* by calling issueTx.
*/
this.importAVAX = (username, password, to, sourceChain) => __awaiter(this, void 0, void 0, function* () {
const params = {
to,
sourceChain,
username,
password
};
const response = yield this.callMethod("avax.importAVAX", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Give a user control over an address by providing the private key that controls the address.
*
* @param username The name of the user to store the private key
* @param password The password that unlocks the user
* @param privateKey A string representing the private key in the vm"s format
*
* @returns The address for the imported private key.
*/
this.importKey = (username, password, privateKey) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
privateKey
};
const response = yield this.callMethod("avax.importKey", params);
return response.data.result.address
? response.data.result.address
: response.data.result;
});
/**
* Calls the node's issueTx method from the API and returns the resulting transaction ID as a string.
*
* @param tx A string, {@link https://github.com/feross/buffer|Buffer}, or [[Tx]] representing a transaction
*
* @returns A Promise string representing the transaction ID of the posted transaction.
*/
this.issueTx = (tx) => __awaiter(this, void 0, void 0, function* () {
let Transaction = "";
if (typeof tx === "string") {
Transaction = tx;
}
else if (tx instanceof buffer_1.Buffer) {
const txobj = new tx_1.Tx();
txobj.fromBuffer(tx);
Transaction = txobj.toStringHex();
}
else if (tx instanceof tx_1.Tx) {
Transaction = tx.toStringHex();
}
else {
/* istanbul ignore next */
throw new errors_1.TransactionError("Error - avax.issueTx: provided tx is not expected type of string, Buffer, or Tx");
}
const params = {
tx: Transaction.toString(),
encoding: "hex"
};
const response = yield this.callMethod("avax.issueTx", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Exports the private key for an address.
*
* @param username The name of the user with the private key
* @param password The password used to decrypt the private key
* @param address The address whose private key should be exported
*
* @returns Promise with the decrypted private key and private key hex as store in the database
*/
this.exportKey = (username, password, address) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
address
};
const response = yield this.callMethod("avax.exportKey", params);
return response.data.result;
});
/**
* Helper function which creates an unsigned Import Tx. For more granular control, you may create your own
* [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s).
*
* @param utxoset A set of UTXOs that the transaction is built on
* @param toAddress The address to send the funds
* @param ownerAddresses The addresses being used to import
* @param sourceChain The chainid for where the import is coming from
* @param fromAddresses The addresses being used to send the funds from the UTXOs provided
*
* @returns An unsigned transaction ([[UnsignedTx]]) which contains a [[ImportTx]].
*
* @remarks
* This helper exists because the endpoint API should be the primary point of entry for most functionality.
*/
this.buildImportTx = (utxoset, toAddress, ownerAddresses, sourceChain, fromAddresses, fee = new bn_js_1.default(0)) => __awaiter(this, void 0, void 0, function* () {
const from = this._cleanAddressArray(fromAddresses, "buildImportTx").map((a) => bintools.stringToAddress(a));
let srcChain = undefined;
if (typeof sourceChain === "string") {
// if there is a sourceChain passed in and it's a string then save the string value and cast the original
// variable from a string to a Buffer
srcChain = sourceChain;
sourceChain = bintools.cb58Decode(sourceChain);
}
else if (typeof sourceChain === "undefined" ||
!(sourceChain instanceof buffer_1.Buffer)) {
// if there is no sourceChain passed in or the sourceChain is any data type other than a Buffer then throw an error
throw new errors_1.ChainIdError("Error - EVMAPI.buildImportTx: sourceChain is undefined or invalid sourceChain type.");
}
const utxoResponse = yield this.getUTXOs(ownerAddresses, srcChain, 0, undefined);
const atomicUTXOs = utxoResponse.utxos;
const networkID = this.core.getNetworkID();
const avaxAssetID = constants_1.Defaults.network[`${networkID}`].X.avaxAssetID;
const avaxAssetIDBuf = bintools.cb58Decode(avaxAssetID);
const atomics = atomicUTXOs.getAllUTXOs();
if (atomics.length === 0) {
throw new errors_1.NoAtomicUTXOsError("Error - EVMAPI.buildImportTx: no atomic utxos to import");
}
const builtUnsignedTx = utxoset.buildImportTx(networkID, bintools.cb58Decode(this.blockchainID), toAddress, atomics, sourceChain, fee, avaxAssetIDBuf);
return builtUnsignedTx;
});
/**
* Helper function which creates an unsigned Export Tx. For more granular control, you may create your own
* [[UnsignedTx]] manually (with their corresponding [[TransferableInput]]s, [[TransferableOutput]]s).
*
* @param amount The amount being exported as a {@link https://github.com/indutny/bn.js/|BN}
* @param assetID The asset id which is being sent
* @param destinationChain The chainid for where the assets will be sent.
* @param toAddresses The addresses to send the funds
* @param fromAddresses The addresses being used to send the funds from the UTXOs provided
* @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs
* @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN}
* @param locktime Optional. The locktime field created in the resulting outputs
* @param threshold Optional. The number of signatures required to spend the funds in the resultant UTXO
*
* @returns An unsigned transaction ([[UnsignedTx]]) which contains an [[ExportTx]].
*/
this.buildExportTx = (amount, assetID, destinationChain, fromAddressHex, fromAddressBech, toAddresses, nonce = 0, locktime = new bn_js_1.default(0), threshold = 1, fee = new bn_js_1.default(0)) => __awaiter(this, void 0, void 0, function* () {
const prefixes = {};
toAddresses.map((address) => {
prefixes[address.split("-")[0]] = true;
});
if (Object.keys(prefixes).length !== 1) {
throw new errors_1.AddressError("Error - EVMAPI.buildExportTx: To addresses must have the same chainID prefix.");
}
if (typeof destinationChain === "undefined") {
throw new errors_1.ChainIdError("Error - EVMAPI.buildExportTx: Destination ChainID is undefined.");
}
else if (typeof destinationChain === "string") {
destinationChain = bintools.cb58Decode(destinationChain);
}
else if (!(destinationChain instanceof buffer_1.Buffer)) {
throw new errors_1.ChainIdError("Error - EVMAPI.buildExportTx: Invalid destinationChain type");
}
if (destinationChain.length !== 32) {
throw new errors_1.ChainIdError("Error - EVMAPI.buildExportTx: Destination ChainID must be 32 bytes in length.");
}
const assetDescription = yield this.getAssetDescription("AVAX");
let evmInputs = [];
if (bintools.cb58Encode(assetDescription.assetID) === assetID) {
const evmInput = new inputs_1.EVMInput(fromAddressHex, amount.add(fee), assetID, nonce);
evmInput.addSignatureIdx(0, bintools.stringToAddress(fromAddressBech));
evmInputs.push(evmInput);
}
else {
// if asset id isn't AVAX asset id then create 2 inputs
// first input will be AVAX and will be for the amount of the fee
// second input will be the ANT
const evmAVAXInput = new inputs_1.EVMInput(fromAddressHex, fee, assetDescription.assetID, nonce);
evmAVAXInput.addSignatureIdx(0, bintools.stringToAddress(fromAddressBech));
evmInputs.push(evmAVAXInput);
const evmANTInput = new inputs_1.EVMInput(fromAddressHex, amount, assetID, nonce);
evmANTInput.addSignatureIdx(0, bintools.stringToAddress(fromAddressBech));
evmInputs.push(evmANTInput);
}
const to = [];
toAddresses.map((address) => {
to.push(bintools.stringToAddress(address));
});
let exportedOuts = [];
const secpTransferOutput = new outputs_1.SECPTransferOutput(amount, to, locktime, threshold);
const transferableOutput = new outputs_1.TransferableOutput(bintools.cb58Decode(assetID), secpTransferOutput);
exportedOuts.push(transferableOutput);
// lexicographically sort ins and outs
evmInputs = evmInputs.sort(inputs_1.EVMInput.comparator());
exportedOuts = exportedOuts.sort(outputs_1.TransferableOutput.comparator());
const exportTx = new exporttx_1.ExportTx(this.core.getNetworkID(), bintools.cb58Decode(this.blockchainID), destinationChain, evmInputs, exportedOuts);
const unsignedTx = new tx_1.UnsignedTx(exportTx);
return unsignedTx;
});
/**
* Gets a reference to the keychain for this class.
*
* @returns The instance of [[KeyChain]] for this class
*/
this.keyChain = () => this.keychain;
/**
*
* @returns new instance of [[KeyChain]]
*/
this.newKeyChain = () => {
// warning, overwrites the old keychain
const alias = this.getBlockchainAlias();
if (alias) {
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), alias);
}
else {
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), this.blockchainID);
}
return this.keychain;
};
/**
* @returns a Promise string containing the base fee for the next block.
*/
this.getBaseFee = () => __awaiter(this, void 0, void 0, function* () {
const params = [];
const method = "eth_baseFee";
const path = "ext/bc/C/rpc";
const response = yield this.callMethod(method, params, path);
return response.data.result;
});
/**
* returns the priority fee needed to be included in a block.
*
* @returns Returns a Promise string containing the priority fee needed to be included in a block.
*/
this.getMaxPriorityFeePerGas = () => __awaiter(this, void 0, void 0, function* () {
const params = [];
const method = "eth_maxPriorityFeePerGas";
const path = "ext/bc/C/rpc";
const response = yield this.callMethod(method, params, path);
return response.data.result;
});
this.blockchainID = blockchainID;
const netID = core.getNetworkID();
if (netID in constants_1.Defaults.network &&
blockchainID in constants_1.Defaults.network[`${netID}`]) {
const alias = constants_1.Defaults.network[`${netID}`][`${blockchainID}`]["alias"];
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), alias);
}
else {
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), blockchainID);
}
}
/**
* @ignore
*/
_cleanAddressArray(addresses, caller) {
const addrs = [];
const chainid = this.getBlockchainAlias()
? this.getBlockchainAlias()
: this.getBlockchainID();
if (addresses && addresses.length > 0) {
addresses.forEach((address) => {
if (typeof address === "string") {
if (typeof this.parseAddress(address) === "undefined") {
/* istanbul ignore next */
throw new errors_1.AddressError("Error - Invalid address format");
}
addrs.push(address);
}
else {
const type = "bech32";
addrs.push(serialization.bufferToType(address, type, this.core.getHRP(), chainid));
}
});
}
return addrs;
}
}
exports.EVMAPI = EVMAPI;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwaXMvZXZtL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOzs7Ozs7Ozs7Ozs7Ozs7QUFFSCxvQ0FBZ0M7QUFDaEMsa0RBQXNCO0FBRXRCLGtEQUE4QztBQUU5QyxvRUFBMkM7QUFDM0MsbUNBQXVDO0FBQ3ZDLHlDQUFxQztBQUNyQyxxREFBbUU7QUFDbkUsNkJBQXFDO0FBQ3JDLDJDQUEwQztBQU8xQyxxQ0FBbUM7QUFDbkMsdUNBQWtFO0FBQ2xFLHlDQUFxQztBQUNyQywrQ0FLMkI7QUFDM0IsdUNBQTJEO0FBYzNEOztHQUVHO0FBQ0gsTUFBTSxRQUFRLEdBQWEsa0JBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtBQUNqRCxNQUFNLGFBQWEsR0FBa0IscUJBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtBQUVoRTs7Ozs7O0dBTUc7QUFDSCxNQUFhLE1BQU8sU0FBUSxpQkFBTztJQW15QmpDOzs7Ozs7O09BT0c7SUFDSCxZQUNFLElBQW1CLEVBQ25CLFVBQWtCLGdCQUFnQixFQUNsQyxlQUF1QixFQUFFO1FBRXpCLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7UUEveUJ0Qjs7V0FFRztRQUNPLGFBQVEsR0FBYSxJQUFJLG1CQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQ3pDLGlCQUFZLEdBQVcsRUFBRSxDQUFBO1FBQ3pCLG9CQUFlLEdBQVcsU0FBUyxDQUFBO1FBQ25DLGdCQUFXLEdBQVcsU0FBUyxDQUFBO1FBQy9CLFVBQUssR0FBTyxTQUFTLENBQUE7UUFFL0I7Ozs7V0FJRztRQUNILHVCQUFrQixHQUFHLEdBQVcsRUFBRTtZQUNoQyxJQUFJLE9BQU8sSUFBSSxDQUFDLGVBQWUsS0FBSyxXQUFXLEVBQUU7Z0JBQy9DLE1BQU0sS0FBSyxHQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENB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QUFNLElBQUkscUJBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFBO3FCQUN6RDtvQkFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQWlCLENBQUMsQ0FBQTtpQkFDOUI7cUJBQU07b0JBQ0wsTUFBTSxJQUFJLEdBQW1CLFFBQVEsQ0FBQTtvQkFDckMsS0FBSyxDQUFDLElBQUksQ0FDUixhQUFhLENBQUMsWUFBWSxDQUN4QixPQUFpQixFQUNqQixJQUFJLEVBQ0osSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFDbEIsT0FBTyxDQUNSLENBQ0YsQ0FBQTtpQkFDRjtZQUNILENBQUMsQ0FBQyxDQUFBO1NBQ0g7UUFDRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7Q0E4REY7QUEvMUJELHdCQSsxQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICogQG1vZHVsZSBBUEktRVZNXG4gKi9cblxuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSBcImJ1ZmZlci9cIlxuaW1wb3J0IEJOIGZyb20gXCJibi5qc1wiXG5pbXBvcnQgQXZhbGFuY2hlQ29yZSBmcm9tIFwiLi4vLi4vYXZhbGFuY2hlXCJcbmltcG9ydCB7IEpSUENBUEkgfSBmcm9tIFwiLi4vLi4vY29tbW9uL2pycGNhcGlcIlxuaW1wb3J0IHsgUmVxdWVzdFJlc3BvbnNlRGF0YSB9IGZyb20gXCIuLi8uLi9jb21tb24vYXBpYmFzZVwiXG5pbXBvcnQgQmluVG9vbHMgZnJvbSBcIi4uLy4uL3V0aWxzL2JpbnRvb2xzXCJcbmltcG9ydCB7IFVUWE9TZXQsIFVUWE8gfSBmcm9tIFwiLi91dHhvc1wiXG5pbXBvcnQgeyBLZXlDaGFpbiB9IGZyb20gXCIuL2tleWNoYWluXCJcbmltcG9ydCB7IERlZmF1bHRzLCBQcmltYXJ5QXNzZXRBbGlhcyB9IGZyb20gXCIuLi8uLi91dGlscy9jb25zdGFudHNcIlxuaW1wb3J0IHsgVHgsIFVuc2lnbmVkVHggfSBmcm9tIFwiLi90eFwiXG5pbXBvcnQgeyBFVk1Db25zdGFudHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIlxuaW1wb3J0IHtcbiAgQXNzZXQsXG4gIEluZGV4LFxuICBJc3N1ZVR4UGFyYW1zLFxuICBVVFhPUmVzcG9uc2Vcbn0gZnJvbSBcIi4vLi4vLi4vY29tbW9uL2ludGVyZmFjZXNcIlxuaW1wb3J0IHsgRVZNSW5wdXQgfSBmcm9tIFwiLi9pbnB1dHNcIlxuaW1wb3J0IHsgU0VDUFRyYW5zZmVyT3V0cHV0LCBUcmFuc2ZlcmFibGVPdXRwdXQgfSBmcm9tIFwiLi9vdXRwdXRzXCJcbmltcG9ydCB7IEV4cG9ydFR4IH0gZnJvbSBcIi4vZXhwb3J0dHhcIlxuaW1wb3J0IHtcbiAgVHJhbnNhY3Rpb25FcnJvcixcbiAgQ2hhaW5JZEVycm9yLFxuICBOb0F0b21pY1VUWE9zRXJyb3IsXG4gIEFkZHJlc3NFcnJvclxufSBmcm9tIFwiLi4vLi4vdXRpbHMvZXJyb3JzXCJcbmltcG9ydCB7IFNlcmlhbGl6YXRpb24sIFNlcmlhbGl6ZWRUeXBlIH0gZnJvbSBcIi4uLy4uL3V0aWxzXCJcbmltcG9ydCB7XG4gIEV4cG9ydEFWQVhQYXJhbXMsXG4gIEV4cG9ydEtleVBhcmFtcyxcbiAgRXhwb3J0UGFyYW1zLFxuICBHZXRBdG9taWNUeFBhcmFtcyxcbiAgR2V0QXNzZXREZXNjcmlwdGlvblBhcmFtcyxcbiAgR2V0QXRvbWljVHhTdGF0dXNQYXJhbXMsXG4gIEdldFVUWE9zUGFyYW1zLFxuICBJbXBvcnRBVkFYUGFyYW1zLFxuICBJbXBvcnRLZXlQYXJhbXMsXG4gIEltcG9ydFBhcmFtc1xufSBmcm9tIFwiLi9pbnRlcmZhY2VzXCJcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmNvbnN0IGJpbnRvb2xzOiBCaW5Ub29scyA9IEJpblRvb2xzLmdldEluc3RhbmNlKClcbmNvbnN0IHNlcmlhbGl6YXRpb246IFNlcmlhbGl6YXRpb24gPSBTZXJpYWxpemF0aW9uLmdldEluc3RhbmNlKClcblxuLyoqXG4gKiBDbGFzcyBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBhIG5vZGUncyBFVk1BUElcbiAqXG4gKiBAY2F0ZWdvcnkgUlBDQVBJc1xuICpcbiAqIEByZW1hcmtzIFRoaXMgZXh0ZW5kcyB0aGUgW1tKUlBDQVBJXV0gY2xhc3MuIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBkaXJlY3RseSBjYWxsZWQuIEluc3RlYWQsIHVzZSB0aGUgW1tBdmFsYW5jaGUuYWRkQVBJXV0gZnVuY3Rpb24gdG8gcmVnaXN0ZXIgdGhpcyBpbnRlcmZhY2Ugd2l0aCBBdmFsYW5jaGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBFVk1BUEkgZXh0ZW5kcyBKUlBDQVBJIHtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHByb3RlY3RlZCBrZXljaGFpbjogS2V5Q2hhaW4gPSBuZXcgS2V5Q2hhaW4oXCJcIiwgXCJcIilcbiAgcHJvdGVjdGVkIGJsb2NrY2hhaW5JRDogc3RyaW5nID0gXCJcIlxuICBwcm90ZWN0ZWQgYmxvY2tjaGFpbkFsaWFzOiBzdHJpbmcgPSB1bmRlZmluZWRcbiAgcHJvdGVjdGVkIEFWQVhBc3NldElEOiBCdWZmZXIgPSB1bmRlZmluZWRcbiAgcHJvdGVjdGVkIHR4RmVlOiBCTiA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBhbGlhcyBmb3IgdGhlIGJsb2NrY2hhaW5JRCBpZiBpdCBleGlzdHMsIG90aGVyd2lzZSByZXR1cm5zIGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgYWxpYXMgZm9yIHRoZSBibG9ja2NoYWluSURcbiAgICovXG4gIGdldEJsb2NrY2hhaW5BbGlhcyA9ICgpOiBzdHJpbmcgPT4ge1xuICAgIGlmICh0eXBlb2YgdGhpcy5ibG9ja2NoYWluQWxpYXMgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIGNvbnN0IG5ldElEOiBudW1iZXIgPSB0aGlzLmNvcmUuZ2V0TmV0d29ya0lEKClcbiAgICAgIGlmIChcbiAgICAgICAgbmV0SUQgaW4gRGVmYXVsdHMubmV0d29yayAmJlxuICAgICAgICB0aGlzLmJsb2NrY2hhaW5JRCBpbiBEZWZhdWx0cy5uZXR3b3JrW2Ake25ldElEfWBdXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5ibG9ja2NoYWluQWxpYXMgPVxuICAgICAgICAgIERlZmF1bHRzLm5ldHdvcmtbYCR7bmV0SUR9YF1bdGhpcy5ibG9ja2NoYWluSURdW1wiYWxpYXNcIl1cbiAgICAgICAgcmV0dXJuIHRoaXMuYmxvY2tjaGFpbkFsaWFzXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJsb2NrY2hhaW5BbGlhc1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGFsaWFzIGZvciB0aGUgYmxvY2tjaGFpbklELlxuICAgKlxuICAgKiBAcGFyYW0gYWxpYXMgVGhlIGFsaWFzIGZvciB0aGUgYmxvY2tjaGFpbklELlxuICAgKlxuICAgKi9cbiAgc2V0QmxvY2tjaGFpbkFsaWFzID0gKGFsaWFzOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIHRoaXMuYmxvY2tjaGFpbkFsaWFzID0gYWxpYXNcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBibG9ja2NoYWluSUQgYW5kIHJldHVybnMgaXQuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBibG9ja2NoYWluSURcbiAgICovXG4gIGdldEJsb2NrY2hhaW5JRCA9ICgpOiBzdHJpbmcgPT4gdGhpcy5ibG9ja2NoYWluSURcblxuICAvKipcbiAgICogUmVmcmVzaCBibG9ja2NoYWluSUQsIGFuZCBpZiBhIGJsb2NrY2hhaW5JRCBpcyBwYXNzZWQgaW4sIHVzZSB0aGF0LlxuICAgKlxuICAgKiBAcGFyYW0gT3B0aW9uYWwuIEJsb2NrY2hhaW5JRCB0byBhc3NpZ24sIGlmIG5vbmUsIHVzZXMgdGhlIGRlZmF1bHQgYmFzZWQgb24gbmV0d29ya0lELlxuICAgKlxuICAgKiBAcmV0dXJucyBBIGJvb2xlYW4gaWYgdGhlIGJsb2NrY2hhaW5JRCB3YXMgc3VjY2Vzc2Z1bGx5IHJlZnJlc2hlZC5cbiAgICovXG4gIHJlZnJlc2hCbG9ja2NoYWluSUQgPSAoYmxvY2tjaGFpbklEOiBzdHJpbmcgPSB1bmRlZmluZWQpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBuZXRJRDogbnVtYmVyID0gdGhpcy5jb3JlLmdldE5ldHdvcmtJRCgpXG4gICAgaWYgKFxuICAgICAgdHlwZW9mIGJsb2NrY2hhaW5JRCA9PT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgdHlwZW9mIERlZmF1bHRzLm5ldHdvcmtbYCR7bmV0SUR9YF0gIT09IFwidW5kZWZpbmVkXCJcbiAgICApIHtcbiAgICAgIHRoaXMuYmxvY2tjaGFpbklEID0gRGVmYXVsdHMubmV0d29ya1tgJHtuZXRJRH1gXS5DLmJsb2NrY2hhaW5JRCAvL2RlZmF1bHQgdG8gQy1DaGFpblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGJsb2NrY2hhaW5JRCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhpcy5ibG9ja2NoYWluSUQgPSBibG9ja2NoYWluSURcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogVGFrZXMgYW4gYWRkcmVzcyBzdHJpbmcgYW5kIHJldHVybnMgaXRzIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9IHJlcHJlc2VudGF0aW9uIGlmIHZhbGlkLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlcnxCdWZmZXJ9IGZvciB0aGUgYWRkcmVzcyBpZiB2YWxpZCwgdW5kZWZpbmVkIGlmIG5vdCB2YWxpZC5cbiAgICovXG4gIHBhcnNlQWRkcmVzcyA9IChhZGRyOiBzdHJpbmcpOiBCdWZmZXIgPT4ge1xuICAgIGNvbnN0IGFsaWFzOiBzdHJpbmcgPSB0aGlzLmdldEJsb2NrY2hhaW5BbGlhcygpXG4gICAgY29uc3QgYmxvY2tjaGFpbklEOiBzdHJpbmcgPSB0aGlzLmdldEJsb2NrY2hhaW5JRCgpXG4gICAgcmV0dXJuIGJpbnRvb2xzLnBhcnNlQWRkcmVzcyhcbiAgICAgIGFkZHIsXG4gICAgICBibG9ja2NoYWluSUQsXG4gICAgICBhbGlhcyxcbiAgICAgIEVWTUNvbnN0YW50cy5BRERSRVNTTEVOR1RIXG4gICAgKVxuICB9XG5cbiAgYWRkcmVzc0Zyb21CdWZmZXIgPSAoYWRkcmVzczogQnVmZmVyKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCBjaGFpbklEOiBzdHJpbmcgPSB0aGlzLmdldEJsb2NrY2hhaW5BbGlhcygpXG4gICAgICA/IHRoaXMuZ2V0QmxvY2tjaGFpbkFsaWFzKClcbiAgICAgIDogdGhpcy5nZXRCbG9ja2NoYWluSUQoKVxuICAgIGNvbnN0IHR5cGU6IFNlcmlhbGl6ZWRUeXBlID0gXCJiZWNoMzJcIlxuICAgIHJldHVybiBzZXJpYWxpemF0aW9uLmJ1ZmZlclRvVHlwZShcbiAgICAgIGFkZHJlc3MsXG4gICAgICB0eXBlLFxuICAgICAgdGhpcy5jb3JlLmdldEhSUCgpLFxuICAgICAgY2hhaW5JRFxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYW4gYXNzZXRzIG5hbWUgYW5kIHN5bWJvbC5cbiAgICpcbiAgICogQHBhcmFtIGFzc2V0SUQgRWl0aGVyIGEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn0gb3IgYW4gYjU4IHNlcmlhbGl6ZWQgc3RyaW5nIGZvciB0aGUgQXNzZXRJRCBvciBpdHMgYWxpYXMuXG4gICAqXG4gICAqIEByZXR1cm5zIFJldHVybnMgYSBQcm9taXNlIEFzc2V0IHdpdGgga2V5cyBcIm5hbWVcIiwgXCJzeW1ib2xcIiwgXCJhc3NldElEXCIgYW5kIFwiZGVub21pbmF0aW9uXCIuXG4gICAqL1xuICBnZXRBc3NldERlc2NyaXB0aW9uID0gYXN5bmMgKGFzc2V0SUQ6IEJ1ZmZlciB8IHN0cmluZyk6IFByb21pc2U8YW55PiA9PiB7XG4gICAgbGV0IGFzc2V0OiBzdHJpbmdcbiAgICBpZiAodHlwZW9mIGFzc2V0SUQgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGFzc2V0ID0gYmludG9vbHMuY2I1OEVuY29kZShhc3NldElEKVxuICAgIH0gZWxzZSB7XG4gICAgICBhc3NldCA9IGFzc2V0SURcbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbXM6IEdldEFzc2V0RGVzY3JpcHRpb25QYXJhbXMgPSB7XG4gICAgICBhc3NldElEOiBhc3NldFxuICAgIH1cblxuICAgIGNvbnN0IHRtcEJhc2VVUkw6IHN0cmluZyA9IHRoaXMuZ2V0QmFzZVVSTCgpXG5cbiAgICAvLyBzZXQgYmFzZSB1cmwgdG8gZ2V0IGFzc2V0IGRlc2NyaXB0aW9uXG4gICAgdGhpcy5zZXRCYXNlVVJMKFwiL2V4dC9iYy9YXCIpXG4gICAgY29uc3QgcmVzcG9uc2U6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLmNhbGxNZXRob2QoXG4gICAgICBcImF2bS5nZXRBc3NldERlc2NyaXB0aW9uXCIsXG4gICAgICBwYXJhbXNcbiAgICApXG5cbiAgICAvLyBzZXQgYmFzZSB1cmwgYmFjayB3aGF0IGl0IG9yaWdpbmFsbHkgd2FzXG4gICAgdGhpcy5zZXRCYXNlVVJMKHRtcEJhc2VVUkwpXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHJlc3BvbnNlLmRhdGEucmVzdWx0Lm5hbWUsXG4gICAgICBzeW1ib2w6IHJlc3BvbnNlLmRhdGEucmVzdWx0LnN5bWJvbCxcbiAgICAgIGFzc2V0SUQ6IGJpbnRvb2xzLmNiNThEZWNvZGUocmVzcG9uc2UuZGF0YS5yZXN1bHQuYXNzZXRJRCksXG4gICAgICBkZW5vbWluYXRpb246IHBhcnNlSW50KHJlc3BvbnNlLmRhdGEucmVzdWx0LmRlbm9taW5hdGlvbiwgMTApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIEFWQVggQXNzZXRJRCBhbmQgcmV0dXJucyBpdCBpbiBhIFByb21pc2UuXG4gICAqXG4gICAqIEBwYXJhbSByZWZyZXNoIFRoaXMgZnVuY3Rpb24gY2FjaGVzIHRoZSByZXNwb25zZS4gUmVmcmVzaCA9IHRydWUgd2lsbCBidXN0IHRoZSBjYWNoZS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHRoZSBwcm92aWRlZCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBBVkFYIEFzc2V0SURcbiAgICovXG4gIGdldEFWQVhBc3NldElEID0gYXN5bmMgKHJlZnJlc2g6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8QnVmZmVyPiA9PiB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLkFWQVhBc3NldElEID09PSBcInVuZGVmaW5lZFwiIHx8IHJlZnJlc2gpIHtcbiAgICAgIGNvbnN0IGFzc2V0OiBBc3NldCA9IGF3YWl0IHRoaXMuZ2V0QXNzZXREZXNjcmlwdGlvbihQcmltYXJ5QXNzZXRBbGlhcylcbiAgICAgIHRoaXMuQVZBWEFzc2V0SUQgPSBhc3NldC5hc3NldElEXG4gICAgfVxuICAgIHJldHVybiB0aGlzLkFWQVhBc3NldElEXG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGVzIHRoZSBkZWZhdWx0cyBhbmQgc2V0cyB0aGUgY2FjaGUgdG8gYSBzcGVjaWZpYyBBVkFYIEFzc2V0SURcbiAgICpcbiAgICogQHBhcmFtIGF2YXhBc3NldElEIEEgY2I1OCBzdHJpbmcgb3IgQnVmZmVyIHJlcHJlc2VudGluZyB0aGUgQVZBWCBBc3NldElEXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSB0aGUgcHJvdmlkZWQgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgQVZBWCBBc3NldElEXG4gICAqL1xuICBzZXRBVkFYQXNzZXRJRCA9IChhdmF4QXNzZXRJRDogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBhdmF4QXNzZXRJRCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgYXZheEFzc2V0SUQgPSBiaW50b29scy5jYjU4RGVjb2RlKGF2YXhBc3NldElEKVxuICAgIH1cbiAgICB0aGlzLkFWQVhBc3NldElEID0gYXZheEFzc2V0SURcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR4IGZlZSBmb3IgdGhpcyBjaGFpbi5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGRlZmF1bHQgdHggZmVlIGFzIGEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L2JuLmpzL3xCTn1cbiAgICovXG4gIGdldERlZmF1bHRUeEZlZSA9ICgpOiBCTiA9PiB7XG4gICAgcmV0dXJuIHRoaXMuY29yZS5nZXROZXR3b3JrSUQoKSBpbiBEZWZhdWx0cy5uZXR3b3JrXG4gICAgICA/IG5ldyBCTihEZWZhdWx0cy5uZXR3b3JrW3RoaXMuY29yZS5nZXROZXR3b3JrSUQoKV1bXCJDXCJdW1widHhGZWVcIl0pXG4gICAgICA6IG5ldyBCTigwKVxuICB9XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIGFtb3VudCBvZiBbYXNzZXRJRF0gZm9yIHRoZSBnaXZlbiBhZGRyZXNzIGluIHRoZSBzdGF0ZSBvZiB0aGUgZ2l2ZW4gYmxvY2sgbnVtYmVyLlxuICAgKiBcImxhdGVzdFwiLCBcInBlbmRpbmdcIiwgYW5kIFwiYWNjZXB0ZWRcIiBtZXRhIGJsb2NrIG51bWJlcnMgYXJlIGFsc28gYWxsb3dlZC5cbiAgICpcbiAgICogQHBhcmFtIGhleEFkZHJlc3MgVGhlIGhleCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWRkcmVzc1xuICAgKiBAcGFyYW0gYmxvY2tIZWlnaHQgVGhlIGJsb2NrIGhlaWdodFxuICAgKiBAcGFyYW0gYXNzZXRJRCBUaGUgYXNzZXQgSURcbiAgICpcbiAgICogQHJldHVybnMgUmV0dXJucyBhIFByb21pc2Ugb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGJhbGFuY2VcbiAgICovXG4gIGdldEFzc2V0QmFsYW5jZSA9IGFzeW5jIChcbiAgICBoZXhBZGRyZXNzOiBzdHJpbmcsXG4gICAgYmxvY2tIZWlnaHQ6IHN0cmluZyxcbiAgICBhc3NldElEOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxvYmplY3Q+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IHN0cmluZ1tdID0gW2hleEFkZHJlc3MsIGJsb2NrSGVpZ2h0LCBhc3NldElEXVxuXG4gICAgY29uc3QgbWV0aG9kOiBzdHJpbmcgPSBcImV0aF9nZXRBc3NldEJhbGFuY2VcIlxuICAgIGNvbnN0IHBhdGg6IHN0cmluZyA9IFwiZXh0L2JjL0MvcnBjXCJcbiAgICBjb25zdCByZXNwb25zZTogUmVxdWVzdFJlc3BvbnNlRGF0YSA9IGF3YWl0IHRoaXMuY2FsbE1ldGhvZChcbiAgICAgIG1ldGhvZCxcbiAgICAgIHBhcmFtcyxcbiAgICAgIHBhdGhcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGFcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzdGF0dXMgb2YgYSBwcm92aWRlZCBhdG9taWMgdHJhbnNhY3Rpb24gSUQgYnkgY2FsbGluZyB0aGUgbm9kZSdzIGBnZXRBdG9taWNUeFN0YXR1c2AgbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0gdHhJRCBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiBJRFxuICAgKlxuICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgUHJvbWlzZSBzdHJpbmcgY29udGFpbmluZyB0aGUgc3RhdHVzIHJldHJpZXZlZCBmcm9tIHRoZSBub2RlXG4gICAqL1xuICBnZXRBdG9taWNUeFN0YXR1cyA9IGFzeW5jICh0eElEOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHBhcmFtczogR2V0QXRvbWljVHhTdGF0dXNQYXJhbXMgPSB7XG4gICAgICB0eElEXG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2U6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLmNhbGxNZXRob2QoXG4gICAgICBcImF2YXguZ2V0QXRvbWljVHhTdGF0dXNcIixcbiAgICAgIHBhcmFtc1xuICAgIClcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5yZXN1bHQuc3RhdHVzXG4gICAgICA/IHJlc3BvbnNlLmRhdGEucmVzdWx0LnN0YXR1c1xuICAgICAgOiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRyYW5zYWN0aW9uIGRhdGEgb2YgYSBwcm92aWRlZCB0cmFuc2FjdGlvbiBJRCBieSBjYWxsaW5nIHRoZSBub2RlJ3MgYGdldEF0b21pY1R4YCBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB0eElEIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRyYW5zYWN0aW9uIElEXG4gICAqXG4gICAqIEByZXR1cm5zIFJldHVybnMgYSBQcm9taXNlIHN0cmluZyBjb250YWluaW5nIHRoZSBieXRlcyByZXRyaWV2ZWQgZnJvbSB0aGUgbm9kZVxuICAgKi9cbiAgZ2V0QXRvbWljVHggPSBhc3luYyAodHhJRDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IEdldEF0b21pY1R4UGFyYW1zID0ge1xuICAgICAgdHhJRFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlOiBSZXF1ZXN0UmVzcG9uc2VEYXRhID0gYXdhaXQgdGhpcy5jYWxsTWV0aG9kKFxuICAgICAgXCJhdmF4LmdldEF0b21pY1R4XCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgdHggZmVlIGZvciB0aGlzIGNoYWluLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgdHggZmVlIGFzIGEge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L2JuLmpzL3xCTn1cbiAgICovXG4gIGdldFR4RmVlID0gKCk6IEJOID0+IHtcbiAgICBpZiAodHlwZW9mIHRoaXMudHhGZWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMudHhGZWUgPSB0aGlzLmdldERlZmF1bHRUeEZlZSgpXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnR4RmVlXG4gIH1cblxuICAvKipcbiAgICogU2VuZCBBTlQgKEF2YWxhbmNoZSBOYXRpdmUgVG9rZW4pIGFzc2V0cyBpbmNsdWRpbmcgQVZBWCBmcm9tIHRoZSBDLUNoYWluIHRvIGFuIGFjY291bnQgb24gdGhlIFgtQ2hhaW4uXG4gICAqXG4gICAqIEFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QsIHlvdSBtdXN0IGNhbGwgdGhlIFgtQ2hhaW7igJlzIGltcG9ydCBtZXRob2QgdG8gY29tcGxldGUgdGhlIHRyYW5zZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdXNlcm5hbWUgVGhlIEtleXN0b3JlIHVzZXIgdGhhdCBjb250cm9scyB0aGUgWC1DaGFpbiBhY2NvdW50IHNwZWNpZmllZCBpbiBgdG9gXG4gICAqIEBwYXJhbSBwYXNzd29yZCBUaGUgcGFzc3dvcmQgb2YgdGhlIEtleXN0b3JlIHVzZXJcbiAgICogQHBhcmFtIHRvIFRoZSBhY2NvdW50IG9uIHRoZSBYLUNoYWluIHRvIHNlbmQgdGhlIEFWQVggdG8uXG4gICAqIEBwYXJhbSBhbW91bnQgQW1vdW50IG9mIGFzc2V0IHRvIGV4cG9ydCBhcyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9ibi5qcy98Qk59XG4gICAqIEBwYXJhbSBhc3NldElEIFRoZSBhc3NldCBpZCB3aGljaCBpcyBiZWluZyBzZW50XG4gICAqXG4gICAqIEByZXR1cm5zIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIHRyYW5zYWN0aW9uIGlkXG4gICAqL1xuICBleHBvcnQgPSBhc3luYyAoXG4gICAgdXNlcm5hbWU6IHN0cmluZyxcbiAgICBwYXNzd29yZDogc3RyaW5nLFxuICAgIHRvOiBzdHJpbmcsXG4gICAgYW1vdW50OiBCTixcbiAgICBhc3NldElEOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IEV4cG9ydFBhcmFtcyA9IHtcbiAgICAgIHRvLFxuICAgICAgYW1vdW50OiBhbW91bnQudG9TdHJpbmcoMTApLFxuICAgICAgdXNlcm5hbWUsXG4gICAgICBwYXNzd29yZCxcbiAgICAgIGFzc2V0SURcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2U6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLmNhbGxNZXRob2QoXG4gICAgICBcImF2YXguZXhwb3J0XCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4SURcbiAgICAgID8gcmVzcG9uc2UuZGF0YS5yZXN1bHQudHhJRFxuICAgICAgOiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgQVZBWCBmcm9tIHRoZSBDLUNoYWluIHRvIGFuIGFjY291bnQgb24gdGhlIFgtQ2hhaW4uXG4gICAqXG4gICAqIEFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QsIHlvdSBtdXN0IGNhbGwgdGhlIFgtQ2hhaW7igJlzIGltcG9ydEFWQVggbWV0aG9kIHRvIGNvbXBsZXRlIHRoZSB0cmFuc2Zlci5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJuYW1lIFRoZSBLZXlzdG9yZSB1c2VyIHRoYXQgY29udHJvbHMgdGhlIFgtQ2hhaW4gYWNjb3VudCBzcGVjaWZpZWQgaW4gYHRvYFxuICAgKiBAcGFyYW0gcGFzc3dvcmQgVGhlIHBhc3N3b3JkIG9mIHRoZSBLZXlzdG9yZSB1c2VyXG4gICAqIEBwYXJhbSB0byBUaGUgYWNjb3VudCBvbiB0aGUgWC1DaGFpbiB0byBzZW5kIHRoZSBBVkFYIHRvLlxuICAgKiBAcGFyYW0gYW1vdW50IEFtb3VudCBvZiBBVkFYIHRvIGV4cG9ydCBhcyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9ibi5qcy98Qk59XG4gICAqXG4gICAqIEByZXR1cm5zIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIHRyYW5zYWN0aW9uIGlkXG4gICAqL1xuICBleHBvcnRBVkFYID0gYXN5bmMgKFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgICB0bzogc3RyaW5nLFxuICAgIGFtb3VudDogQk5cbiAgKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IEV4cG9ydEFWQVhQYXJhbXMgPSB7XG4gICAgICB0byxcbiAgICAgIGFtb3VudDogYW1vdW50LnRvU3RyaW5nKDEwKSxcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgcGFzc3dvcmRcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2U6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLmNhbGxNZXRob2QoXG4gICAgICBcImF2YXguZXhwb3J0QVZBWFwiLFxuICAgICAgcGFyYW1zXG4gICAgKVxuICAgIHJldHVybiByZXNwb25zZS5kYXRhLnJlc3VsdC50eElEXG4gICAgICA/IHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4SURcbiAgICAgIDogcmVzcG9uc2UuZGF0YS5yZXN1bHRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIFVUWE9zIHJlbGF0ZWQgdG8gdGhlIGFkZHJlc3NlcyBwcm92aWRlZCBmcm9tIHRoZSBub2RlJ3MgYGdldFVUWE9zYCBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSBhZGRyZXNzZXMgQW4gYXJyYXkgb2YgYWRkcmVzc2VzIGFzIGNiNTggc3RyaW5ncyBvciBhZGRyZXNzZXMgYXMge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyfEJ1ZmZlcn1zXG4gICAqIEBwYXJhbSBzb3VyY2VDaGFpbiBBIHN0cmluZyBmb3IgdGhlIGNoYWluIHRvIGxvb2sgZm9yIHRoZSBVVFhPJ3MuIERlZmF1bHQgaXMgdG8gdXNlIHRoaXMgY2hhaW4sIGJ1dCBpZiBleHBvcnRlZCBVVFhPcyBleGlzdFxuICAgKiBmcm9tIG90aGVyIGNoYWlucywgdGhpcyBjYW4gdXNlZCB0byBwdWxsIHRoZW0gaW5zdGVhZC5cbiAgICogQHBhcmFtIGxpbWl0IE9wdGlvbmFsLiBSZXR1cm5zIGF0IG1vc3QgW2xpbWl0XSBhZGRyZXNzZXMuIElmIFtsaW1pdF0gPT0gMCBvciA+IFttYXhVVFhPc1RvRmV0Y2hdLCBmZXRjaGVzIHVwIHRvIFttYXhVVFhPc1RvRmV0Y2hdLlxuICAgKiBAcGFyYW0gc3RhcnRJbmRleCBPcHRpb25hbC4gW1N0YXJ0SW5kZXhdIGRlZmluZXMgd2hlcmUgdG8gc3RhcnQgZmV0Y2hpbmcgVVRYT3MgKGZvciBwYWdpbmF0aW9uLilcbiAgICogVVRYT3MgZmV0Y2hlZCBhcmUgZnJvbSBhZGRyZXNzZXMgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIFtTdGFydEluZGV4LkFkZHJlc3NdXG4gICAqIEZvciBhZGRyZXNzIFtTdGFydEluZGV4LkFkZHJlc3NdLCBvbmx5IFVUWE9zIHdpdGggSURzIGdyZWF0ZXIgdGhhbiBbU3RhcnRJbmRleC5VdHhvXSB3aWxsIGJlIHJldHVybmVkLlxuICAgKi9cbiAgZ2V0VVRYT3MgPSBhc3luYyAoXG4gICAgYWRkcmVzc2VzOiBzdHJpbmdbXSB8IHN0cmluZyxcbiAgICBzb3VyY2VDaGFpbjogc3RyaW5nID0gdW5kZWZpbmVkLFxuICAgIGxpbWl0OiBudW1iZXIgPSAwLFxuICAgIHN0YXJ0SW5kZXg6IEluZGV4ID0gdW5kZWZpbmVkLFxuICAgIGVuY29kaW5nOiBzdHJpbmcgPSBcImhleFwiXG4gICk6IFByb21pc2U8e1xuICAgIG51bUZldGNoZWQ6IG51bWJlclxuICAgIHV0eG9zXG4gICAgZW5kSW5kZXg6IEluZGV4XG4gIH0+ID0+IHtcbiAgICBpZiAodHlwZW9mIGFkZHJlc3NlcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgYWRkcmVzc2VzID0gW2FkZHJlc3Nlc11cbiAgICB9XG5cbiAgICBjb25zdCBwYXJhbXM6IEdldFVUWE9zUGFyYW1zID0ge1xuICAgICAgYWRkcmVzc2VzOiBhZGRyZXNzZXMsXG4gICAgICBsaW1pdCxcbiAgICAgIGVuY29kaW5nXG4gICAgfVxuICAgIGlmICh0eXBlb2Ygc3RhcnRJbmRleCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzdGFydEluZGV4KSB7XG4gICAgICBwYXJhbXMuc3RhcnRJbmRleCA9IHN0YXJ0SW5kZXhcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZUNoYWluICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBwYXJhbXMuc291cmNlQ2hhaW4gPSBzb3VyY2VDaGFpblxuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlOiBSZXF1ZXN0UmVzcG9uc2VEYXRhID0gYXdhaXQgdGhpcy5jYWxsTWV0aG9kKFxuICAgICAgXCJhdmF4LmdldFVUWE9zXCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgY29uc3QgdXR4b3M6IFVUWE9TZXQgPSBuZXcgVVRYT1NldCgpXG4gICAgY29uc3QgZGF0YTogYW55ID0gcmVzcG9uc2UuZGF0YS5yZXN1bHQudXR4b3NcbiAgICBpZiAoZGF0YS5sZW5ndGggPiAwICYmIGRhdGFbMF0uc3Vic3RyaW5nKDAsIDIpID09PSBcIjB4XCIpIHtcbiAgICAgIGNvbnN0IGNiNThTdHJzOiBzdHJpbmdbXSA9IFtdXG4gICAgICBkYXRhLmZvckVhY2goKHN0cjogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGNiNThTdHJzLnB1c2goYmludG9vbHMuY2I1OEVuY29kZShuZXcgQnVmZmVyKHN0ci5zbGljZSgyKSwgXCJoZXhcIikpKVxuICAgICAgfSlcblxuICAgICAgdXR4b3MuYWRkQXJyYXkoY2I1OFN0cnMsIGZhbHNlKVxuICAgIH0gZWxzZSB7XG4gICAgICB1dHhvcy5hZGRBcnJheShkYXRhLCBmYWxzZSlcbiAgICB9XG4gICAgcmVzcG9uc2UuZGF0YS5yZXN1bHQudXR4b3MgPSB1dHhvc1xuICAgIHJldHVybiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgQU5UIChBdmFsYW5jaGUgTmF0aXZlIFRva2VuKSBhc3NldHMgaW5jbHVkaW5nIEFWQVggZnJvbSBhbiBhY2NvdW50IG9uIHRoZSBYLUNoYWluIHRvIGFuIGFkZHJlc3Mgb24gdGhlIEMtQ2hhaW4uIFRoaXMgdHJhbnNhY3Rpb25cbiAgICogbXVzdCBiZSBzaWduZWQgd2l0aCB0aGUga2V5IG9mIHRoZSBhY2NvdW50IHRoYXQgdGhlIGFzc2V0IGlzIHNlbnQgZnJvbSBhbmQgd2hpY2ggcGF5c1xuICAgKiB0aGUgdHJhbnNhY3Rpb24gZmVlLlxuICAgKlxuICAgKiBAcGFyYW0gdXNlcm5hbWUgVGhlIEtleXN0b3JlIHVzZXIgdGhhdCBjb250cm9scyB0aGUgYWNjb3VudCBzcGVjaWZpZWQgaW4gYHRvYFxuICAgKiBAcGFyYW0gcGFzc3dvcmQgVGhlIHBhc3N3b3JkIG9mIHRoZSBLZXlzdG9yZSB1c2VyXG4gICAqIEBwYXJhbSB0byBUaGUgYWRkcmVzcyBvZiB0aGUgYWNjb3VudCB0aGUgYXNzZXQgaXMgc2VudCB0by5cbiAgICogQHBhcmFtIHNvdXJjZUNoYWluIFRoZSBjaGFpbklEIHdoZXJlIHRoZSBmdW5kcyBhcmUgY29taW5nIGZyb20uIEV4OiBcIlhcIlxuICAgKlxuICAgKiBAcmV0dXJucyBQcm9taXNlIGZvciBhIHN0cmluZyBmb3IgdGhlIHRyYW5zYWN0aW9uLCB3aGljaCBzaG91bGQgYmUgc2VudCB0byB0aGUgbmV0d29ya1xuICAgKiBieSBjYWxsaW5nIGlzc3VlVHguXG4gICAqL1xuICBpbXBvcnQgPSBhc3luYyAoXG4gICAgdXNlcm5hbWU6IHN0cmluZyxcbiAgICBwYXNzd29yZDogc3RyaW5nLFxuICAgIHRvOiBzdHJpbmcsXG4gICAgc291cmNlQ2hhaW46IHN0cmluZ1xuICApOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHBhcmFtczogSW1wb3J0UGFyYW1zID0ge1xuICAgICAgdG8sXG4gICAgICBzb3VyY2VDaGFpbixcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgcGFzc3dvcmRcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2U6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLmNhbGxNZXRob2QoXG4gICAgICBcImF2YXguaW1wb3J0XCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4SURcbiAgICAgID8gcmVzcG9uc2UuZGF0YS5yZXN1bHQudHhJRFxuICAgICAgOiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgQVZBWCBmcm9tIGFuIGFjY291bnQgb24gdGhlIFgtQ2hhaW4gdG8gYW4gYWRkcmVzcyBvbiB0aGUgQy1DaGFpbi4gVGhpcyB0cmFuc2FjdGlvblxuICAgKiBtdXN0IGJlIHNpZ25lZCB3aXRoIHRoZSBrZXkgb2YgdGhlIGFjY291bnQgdGhhdCB0aGUgQVZBWCBpcyBzZW50IGZyb20gYW5kIHdoaWNoIHBheXNcbiAgICogdGhlIHRyYW5zYWN0aW9uIGZlZS5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJuYW1lIFRoZSBLZXlzdG9yZSB1c2VyIHRoYXQgY29udHJvbHMgdGhlIGFjY291bnQgc3BlY2lmaWVkIGluIGB0b2BcbiAgICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCBvZiB0aGUgS2V5c3RvcmUgdXNlclxuICAgKiBAcGFyYW0gdG8gVGhlIGFkZHJlc3Mgb2YgdGhlIGFjY291bnQgdGhlIEFWQVggaXMgc2VudCB0by4gVGhpcyBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSB0b1xuICAgKiBhcmd1bWVudCBpbiB0aGUgY29ycmVzcG9uZGluZyBjYWxsIHRvIHRoZSBYLUNoYWlu4oCZcyBleHBvcnRBVkFYXG4gICAqIEBwYXJhbSBzb3VyY2VDaGFpbiBUaGUgY2hhaW5JRCB3aGVyZSB0aGUgZnVuZHMgYXJlIGNvbWluZyBmcm9tLlxuICAgKlxuICAgKiBAcmV0dXJucyBQcm9taXNlIGZvciBhIHN0cmluZyBmb3IgdGhlIHRyYW5zYWN0aW9uLCB3aGljaCBzaG91bGQgYmUgc2VudCB0byB0aGUgbmV0d29ya1xuICAgKiBieSBjYWxsaW5nIGlzc3VlVHguXG4gICAqL1xuICBpbXBvcnRBVkFYID0gYXN5bmMgKFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgICB0bzogc3RyaW5nLFxuICAgIHNvdXJjZUNoYWluOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IEltcG9ydEFWQVhQYXJhbXMgPSB7XG4gICAgICB0byxcbiAgICAgIHNvdXJjZUNoYWluLFxuICAgICAgdXNlcm5hbWUsXG4gICAgICBwYXNzd29yZFxuICAgIH1cbiAgICBjb25zdCByZXNwb25zZTogUmVxdWVzdFJlc3BvbnNlRGF0YSA9IGF3YWl0IHRoaXMuY2FsbE1ldGhvZChcbiAgICAgIFwiYXZheC5pbXBvcnRBVkFYXCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4SURcbiAgICAgID8gcmVzcG9uc2UuZGF0YS5yZXN1bHQudHhJRFxuICAgICAgOiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIEdpdmUgYSB1c2VyIGNvbnRyb2wgb3ZlciBhbiBhZGRyZXNzIGJ5IHByb3ZpZGluZyB0aGUgcHJpdmF0ZSBrZXkgdGhhdCBjb250cm9scyB0aGUgYWRkcmVzcy5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJuYW1lIFRoZSBuYW1lIG9mIHRoZSB1c2VyIHRvIHN0b3JlIHRoZSBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0gcGFzc3dvcmQgVGhlIHBhc3N3b3JkIHRoYXQgdW5sb2NrcyB0aGUgdXNlclxuICAgKiBAcGFyYW0gcHJpdmF0ZUtleSBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHByaXZhdGUga2V5IGluIHRoZSB2bVwicyBmb3JtYXRcbiAgICpcbiAgICogQHJldHVybnMgVGhlIGFkZHJlc3MgZm9yIHRoZSBpbXBvcnRlZCBwcml2YXRlIGtleS5cbiAgICovXG4gIGltcG9ydEtleSA9IGFzeW5jIChcbiAgICB1c2VybmFtZTogc3RyaW5nLFxuICAgIHBhc3N3b3JkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZUtleTogc3RyaW5nXG4gICk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgY29uc3QgcGFyYW1zOiBJbXBvcnRLZXlQYXJhbXMgPSB7XG4gICAgICB1c2VybmFtZSxcbiAgICAgIHBhc3N3b3JkLFxuICAgICAgcHJpdmF0ZUtleVxuICAgIH1cbiAgICBjb25zdCByZXNwb25zZTogUmVxdWVzdFJlc3BvbnNlRGF0YSA9IGF3YWl0IHRoaXMuY2FsbE1ldGhvZChcbiAgICAgIFwiYXZheC5pbXBvcnRLZXlcIixcbiAgICAgIHBhcmFtc1xuICAgIClcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5yZXN1bHQuYWRkcmVzc1xuICAgICAgPyByZXNwb25zZS5kYXRhLnJlc3VsdC5hZGRyZXNzXG4gICAgICA6IHJlc3BvbnNlLmRhdGEucmVzdWx0XG4gIH1cblxuICAvKipcbiAgICogQ2FsbHMgdGhlIG5vZGUncyBpc3N1ZVR4IG1ldGhvZCBmcm9tIHRoZSBBUEkgYW5kIHJldHVybnMgdGhlIHJlc3VsdGluZyB0cmFuc2FjdGlvbiBJRCBhcyBhIHN0cmluZy5cbiAgICpcbiAgICogQHBhcmFtIHR4IEEgc3RyaW5nLCB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXJ8QnVmZmVyfSwgb3IgW1tUeF1dIHJlcHJlc2VudGluZyBhIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSB0cmFuc2FjdGlvbiBJRCBvZiB0aGUgcG9zdGVkIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgaXNzdWVUeCA9IGFzeW5jICh0eDogc3RyaW5nIHwgQnVmZmVyIHwgVHgpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGxldCBUcmFuc2FjdGlvbjogc3RyaW5nID0gXCJcIlxuICAgIGlmICh0eXBlb2YgdHggPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIFRyYW5zYWN0aW9uID0gdHhcbiAgICB9IGVsc2UgaWYgKHR4IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICBjb25zdCB0eG9iajogVHggPSBuZXcgVHgoKVxuICAgICAgdHhvYmouZnJvbUJ1ZmZlcih0eClcbiAgICAgIFRyYW5zYWN0aW9uID0gdHhvYmoudG9TdHJpbmdIZXgoKVxuICAgIH0gZWxzZSBpZiAodHggaW5zdGFuY2VvZiBUeCkge1xuICAgICAgVHJhbnNhY3Rpb24gPSB0eC50b1N0cmluZ0hleCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICB0aHJvdyBuZXcgVHJhbnNhY3Rpb25FcnJvcihcbiAgICAgICAgXCJFcnJvciAtIGF2YXguaXNzdWVUeDogcHJvdmlkZWQgdHggaXMgbm90IGV4cGVjdGVkIHR5cGUgb2Ygc3RyaW5nLCBCdWZmZXIsIG9yIFR4XCJcbiAgICAgIClcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zOiBJc3N1ZVR4UGFyYW1zID0ge1xuICAgICAgdHg6IFRyYW5zYWN0aW9uLnRvU3RyaW5nKCksXG4gICAgICBlbmNvZGluZzogXCJoZXhcIlxuICAgIH1cbiAgICBjb25zdCByZXNwb25zZTogUmVxdWVzdFJlc3BvbnNlRGF0YSA9IGF3YWl0IHRoaXMuY2FsbE1ldGhvZChcbiAgICAgIFwiYXZheC5pc3N1ZVR4XCIsXG4gICAgICBwYXJhbXNcbiAgICApXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEucmVzdWx0LnR4SURcbiAgICAgID8gcmVzcG9uc2UuZGF0YS5yZXN1bHQudHhJRFxuICAgICAgOiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydHMgdGhlIHByaXZhdGUga2V5IGZvciBhbiBhZGRyZXNzLlxuICAgKlxuICAgKiBAcGFyYW0gdXNlcm5hbWUgVGhlIG5hbWUgb2YgdGhlIHVzZXIgd2l0aCB0aGUgcHJpdmF0ZSBrZXlcbiAgICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCB1c2VkIHRvIGRlY3J5cHQgdGhlIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSBhZGRyZXNzIFRoZSBhZGRyZXNzIHdob3NlIHByaXZhdGUga2V5IHNob3VsZCBiZSBleHBvcnRlZFxuICAgKlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHdpdGggdGhlIGRlY3J5cHRlZCBwcml2YXRlIGtleSBhbmQgcHJpdmF0ZSBrZXkgaGV4IGFzIHN0b3JlIGluIHRoZSBkYXRhYmFzZVxuICAgKi9cbiAgZXhwb3J0S2V5ID0gYXN5bmMgKFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgICBhZGRyZXNzOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxvYmplY3Q+ID0+IHtcbiAgICBjb25zdCBwYXJhbXM6IEV4cG9ydEtleVBhcmFtcyA9IHtcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgcGFzc3dvcmQsXG4gICAgICBhZGRyZXNzXG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlOiBSZXF1ZXN0UmVzcG9uc2VEYXRhID0gYXdhaXQgdGhpcy5jYWxsTWV0aG9kKFxuICAgICAgXCJhdmF4LmV4cG9ydEtleVwiLFxuICAgICAgcGFyYW1zXG4gICAgKVxuICAgIHJldHVybiByZXNwb25zZS5kYXRhLnJlc3VsdFxuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB3aGljaCBjcmVhdGVzIGFuIHVuc2lnbmVkIEltcG9ydCBUeC4gRm9yIG1vcmUgZ3JhbnVsYXIgY29udHJvbCwgeW91IG1heSBjcmVhdGUgeW91ciBvd25cbiAgICogW1tVbnNpZ25lZFR4XV0gbWFudWFsbHkgKHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBbW1RyYW5zZmVyYWJsZUlucHV0XV1zLCBbW1RyYW5zZmVyYWJsZU91dHB1dF1dcykuXG4gICAqXG4gICAqIEBwYXJhbSB1dHhvc2V0IEEgc2V0IG9mIFVUWE9zIHRoYXQgdGhlIHRyYW5zYWN0aW9uIGlzIGJ1aWx0IG9uXG4gICAqIEBwYXJhbSB0b0FkZHJlc3MgVGhlIGFkZHJlc3MgdG8gc2VuZCB0aGUgZnVuZHNcbiAgICogQHBhcmFtIG93bmVyQWRkcmVzc2VzIFRoZSBhZGRyZXNzZXMgYmVpbmcgdXNlZCB0byBpbXBvcnRcbiAgICogQHBhcmFtIHNvdXJjZUNoYWluIFRoZSBjaGFpbmlkIGZvciB3aGVyZSB0aGUgaW1wb3J0IGlzIGNvbWluZyBmcm9tXG4gICAqIEBwYXJhbSBmcm9tQWRkcmVzc2VzIFRoZSBhZGRyZXNzZXMgYmVpbmcgdXNlZCB0byBzZW5kIHRoZSBmdW5kcyBmcm9tIHRoZSBVVFhPcyBwcm92aWRlZFxuICAgKlxuICAgKiBAcmV0dXJucyBBbiB1bnNpZ25lZCB0cmFuc2FjdGlvbiAoW1tVbnNpZ25lZFR4XV0pIHdoaWNoIGNvbnRhaW5zIGEgW1tJbXBvcnRUeF1dLlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBUaGlzIGhlbHBlciBleGlzdHMgYmVjYXVzZSB0aGUgZW5kcG9pbnQgQVBJIHNob3VsZCBiZSB0aGUgcHJpbWFyeSBwb2ludCBvZiBlbnRyeSBmb3IgbW9zdCBmdW5jdGlvbmFsaXR5LlxuICAgKi9cbiAgYnVpbGRJbXBvcnRUeCA9IGFzeW5jIChcbiAgICB1dHhvc2V0OiBVVFhPU2V0LFxuICAgIHRvQWRkcmVzczogc3RyaW5nLFxuICAgIG93bmVyQWRkcmVzc2VzOiBzdHJpbmdbXSxcbiAgICBzb3VyY2VDaGFpbjogQnVmZmVyIHwgc3RyaW5nLFxuICAgIGZyb21BZGRyZXNzZXM6IHN0cmluZ1tdLFxuICAgIGZlZTogQk4gPSBuZXcgQk4oMClcbiAgKTogUHJvbWlzZTxVbnNpZ25lZFR4PiA9PiB7XG4gICAgY29uc3QgZnJvbTogQnVmZmVyW10gPSB0aGlzLl9jbGVhbkFkZHJlc3NBcnJheShcbiAgICAgIGZyb21BZGRyZXNzZXMsXG4gICAgICBcImJ1aWxkSW1wb3J0VHhcIlxuICAgICkubWFwKChhOiBzdHJpbmcpOiBCdWZmZXIgPT4gYmludG9vbHMuc3RyaW5nVG9BZGRyZXNzKGEpKVxuICAgIGxldCBzcmNDaGFpbjogc3RyaW5nID0gdW5kZWZpbmVkXG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZUNoYWluID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAvLyBpZiB0aGVyZSBpcyBhIHNvdXJjZUNoYWluIHBhc3NlZCBpbiBhbmQgaXQncyBhIHN0cmluZyB0aGVuIHNhdmUgdGhlIHN0cmluZyB2YWx1ZSBhbmQgY2FzdCB0aGUgb3JpZ2luYWxcbiAgICAgIC8vIHZhcmlhYmxlIGZyb20gYSBzdHJpbmcgdG8gYSBCdWZmZXJcbiAgICAgIHNyY0NoYWluID0gc291cmNlQ2hhaW5cbiAgICAgIHNvdXJjZUNoYWluID0gYmludG9vbHMuY2I1OERlY29kZShzb3VyY2VDaGFpbilcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZW9mIHNvdXJjZUNoYWluID09PSBcInVuZGVmaW5lZFwiIHx8XG4gICAgICAhKHNvdXJjZUNoYWluIGluc3RhbmNlb2YgQnVmZmVyKVxuICAgICkge1xuICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gc291cmNlQ2hhaW4gcGFzc2VkIGluIG9yIHRoZSBzb3VyY2VDaGFpbiBpcyBhbnkgZGF0YSB0eXBlIG90aGVyIHRoYW4gYSBCdWZmZXIgdGhlbiB0aHJvdyBhbiBlcnJvclxuICAgICAgdGhyb3cgbmV3IENoYWluSWRFcnJvcihcbiAgICAgICAgXCJFcnJvciAtIEVWTUFQSS5idWlsZEltcG9ydFR4OiBzb3VyY2VDaGFpbiBpcyB1bmRlZmluZWQgb3IgaW52YWxpZCBzb3VyY2VDaGFpbiB0eXBlLlwiXG4gICAgICApXG4gICAgfVxuICAgIGNvbnN0IHV0eG9SZXNwb25zZTogVVRYT1Jlc3BvbnNlID0gYXdhaXQgdGhpcy5nZXRVVFhPcyhcbiAgICAgIG93bmVyQWRkcmVzc2VzLFxuICAgICAgc3JjQ2hhaW4sXG4gICAgICAwLFxuICAgICAgdW5kZWZpbmVkXG4gICAgKVxuICAgIGNvbnN0IGF0b21pY1VUWE9zOiBVVFhPU2V0ID0gdXR4b1Jlc3BvbnNlLnV0eG9zXG4gICAgY29uc3QgbmV0d29ya0lEOiBudW1iZXIgPSB0aGlzLmNvcmUuZ2V0TmV0d29ya0lEKClcbiAgICBjb25zdCBhdmF4QXNzZXRJRDogc3RyaW5nID0gRGVmYXVsdHMubmV0d29ya1tgJHtuZXR3b3JrSUR9YF0uWC5hdmF4QXNzZXRJRFxuICAgIGNvbnN0IGF2YXhBc3NldElEQnVmOiBCdWZmZXIgPSBiaW50b29scy5jYjU4RGVjb2RlKGF2YXhBc3NldElEKVxuICAgIGNvbnN0IGF0b21pY3M6IFVUWE9bXSA9IGF0b21pY1VUWE9zLmdldEFsbFVUWE9zKClcblxuICAgIGlmIChhdG9taWNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IE5vQXRvbWljVVRYT3NFcnJvcihcbiAgICAgICAgXCJFcnJvciAtIEVWTUFQSS5idWlsZEltcG9ydFR4OiBubyBhdG9taWMgdXR4b3MgdG8gaW1wb3J0XCJcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCBidWlsdFVuc2lnbmVkVHg6IFVuc2lnbmVkVHggPSB1dHhvc2V0LmJ1aWxkSW1wb3J0VHgoXG4gICAgICBuZXR3b3JrSUQsXG4gICAgICBiaW50b29scy5jYjU4RGVjb2RlKHRoaXMuYmxvY2tjaGFpbklEKSxcbiAgICAgIHRvQWRkcmVzcyxcbiAgICAgIGF0b21pY3MsXG4gICAgICBzb3VyY2VDaGFpbixcbiAgICAgIGZlZSxcbiAgICAgIGF2YXhBc3NldElEQnVmXG4gICAgKVxuXG4gICAgcmV0dXJuIGJ1aWx0VW5zaWduZWRUeFxuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB3aGljaCBjcmVhdGVzIGFuIHVuc2lnbmVkIEV4cG9ydCBUeC4gRm9yIG1vcmUgZ3JhbnVsYXIgY29udHJvbCwgeW91IG1heSBjcmVhdGUgeW91ciBvd25cbiAgICogW1tVbnNpZ25lZFR4XV0gbWFudWFsbHkgKHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBbW1RyYW5zZmVyYWJsZUlucHV0XV1zLCBbW1RyYW5zZmVyYWJsZU91dHB1dF1dcykuXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgVGhlIGFtb3VudCBiZWluZyBleHBvcnRlZCBhcyBhIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9ibi5qcy98Qk59XG4gICAqIEBwYXJhbSBhc3NldElEIFRoZSBhc3NldCBpZCB3aGljaCBpcyBiZWluZyBzZW50XG4gICAqIEBwYXJhbSBkZXN0aW5hdGlvbkNoYWluIFRoZSBjaGFpbmlkIGZvciB3aGVyZSB0aGUgYXNzZXRzIHdpbGwgYmUgc2VudC5cbiAgICogQHBhcmFtIHRvQWRkcmVzc2VzIFRoZSBhZGRyZXNzZXMgdG8gc2VuZCB0aGUgZnVuZHNcbiAgICogQHBhcmFtIGZyb21BZGRyZXNzZXMgVGhlIGFkZHJlc3NlcyBiZWluZyB1c2VkIHRvIHNlbmQgdGhlIGZ1bmRzIGZyb20gdGhlIFVUWE9zIHByb3ZpZGVkXG4gICAqIEBwYXJhbSBjaGFuZ2VBZGRyZXNzZXMgVGhlIGFkZHJlc3NlcyB0aGF0IGNhbiBzcGVuZCB0aGUgY2hhbmdlIHJlbWFpbmluZyBmcm9tIHRoZSBzcGVudCBVVFhPc1xuICAgKiBAcGFyYW0gYXNPZiBPcHRpb25hbC4gVGhlIHRpbWVzdGFtcCB0byB2ZXJpZnkgdGhlIHRyYW5zYWN0aW9uIGFnYWluc3QgYXMgYSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvYm4uanMvfEJOfVxuICAgKiBAcGFyYW0gbG9ja3RpbWUgT3B0aW9uYWwuIFRoZSBsb2NrdGltZSBmaWVsZCBjcmVhdGVkIGluIHRoZSByZXN1bHRpbmcgb3V0cHV0c1xuICAgKiBAcGFyYW0gdGhyZXNob2xkIE9wdGlvbmFsLiBUaGUgbnVtYmVyIG9mIHNpZ25hdHVyZXMgcmVxdWlyZWQgdG8gc3BlbmQgdGhlIGZ1bmRzIGluIHRoZSByZXN1bHRhbnQgVVRYT1xuICAgKlxuICAgKiBAcmV0dXJucyBBbiB1bnNpZ25lZCB0cmFuc2FjdGlvbiAoW1tVbnNpZ25lZFR4XV0pIHdoaWNoIGNvbnRhaW5zIGFuIFtbRXhwb3J0VHhdXS5cbiAgICovXG4gIGJ1aWxkRXhwb3J0VHggPSBhc3luYyAoXG4gICAgYW1vdW50OiBCTixcbiAgICBhc3NldElEOiBCdWZmZXIgfCBzdHJpbmcsXG4gICAgZGVzdGluYXRpb25DaGFpbjogQnVmZmVyIHwgc3RyaW5nLFxuICAgIGZyb21BZGRyZXNzSGV4OiBzdHJpbmcsXG4gICAgZnJvbUFkZHJlc3NCZWNoOiBzdHJpbmcsXG4gICAgdG9BZGRyZXNzZXM6IHN0cmluZ1tdLFxuICAgIG5vbmNlOiBudW1iZXIgPSAwLFxuICAgIGxvY2t0aW1lOiBCTiA9IG5ldyBCTigwKSxcbiAgICB0aHJlc2hvbGQ6IG51bWJlciA9IDEsXG4gICAgZmVlOiBCTiA9IG5ldyBCTigwKVxuICApOiBQcm9taXNlPFVuc2lnbmVkVHg+ID0+IHtcbiAgICBjb25zdCBwcmVmaXhlczogb2JqZWN0ID0ge31cbiAgICB0b0FkZHJlc3Nlcy5tYXAoKGFkZHJlc3M6IHN0cmluZykgPT4ge1xuICAgICAgcHJlZml4ZXNbYWRkcmVzcy5zcGxpdChcIi1cIilbMF1dID0gdHJ1ZVxuICAgIH0pXG4gICAgaWYgKE9iamVjdC5rZXlzKHByZWZpeGVzKS5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBBZGRyZXNzRXJyb3IoXG4gICAgICAgIFwiRXJyb3IgLSBFVk1BUEkuYnVpbGRFeHBvcnRUeDogVG8gYWRkcmVzc2VzIG11c3QgaGF2ZSB0aGUgc2FtZSBjaGFpbklEIHByZWZpeC5cIlxuICAgICAgKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZGVzdGluYXRpb25DaGFpbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgdGhyb3cgbmV3IENoYWluSWRFcnJvcihcbiAgICAgICAgXCJFcnJvciAtIEVWTUFQSS5idWlsZEV4cG9ydFR4OiBEZXN0aW5hdGlvbiBDaGFpbklEIGlzIHVuZGVmaW5lZC5cIlxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uQ2hhaW4gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGRlc3RpbmF0aW9uQ2hhaW4gPSBiaW50b29scy5jYjU4RGVjb2RlKGRlc3RpbmF0aW9uQ2hhaW4pXG4gICAgfSBlbHNlIGlmICghKGRlc3RpbmF0aW9uQ2hhaW4gaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgQ2hhaW5JZEVycm9yKFxuICAgICAgICBcIkVycm9yIC0gRVZNQVBJLmJ1aWxkRXhwb3J0VHg6IEludmFsaWQgZGVzdGluYXRpb25DaGFpbiB0eXBlXCJcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKGRlc3RpbmF0aW9uQ2hhaW4ubGVuZ3RoICE9PSAzMikge1xuICAgICAgdGhyb3cgbmV3IENoYWluSWRFcnJvcihcbiAgICAgICAgXCJFcnJvciAtIEVWTUFQSS5idWlsZEV4cG9ydFR4OiBEZXN0aW5hdGlvbiBDaGFpbklEIG11c3QgYmUgMzIgYnl0ZXMgaW4gbGVuZ3RoLlwiXG4gICAgICApXG4gICAgfVxuICAgIGNvbnN0IGFzc2V0RGVzY3JpcHRpb246IGFueSA9IGF3YWl0IHRoaXMuZ2V0QXNzZXREZXNjcmlwdGlvbihcIkFWQVhcIilcbiAgICBsZXQgZXZtSW5wdXRzOiBFVk1JbnB1dFtdID0gW11cbiAgICBpZiAoYmludG9vbHMuY2I1OEVuY29kZShhc3NldERlc2NyaXB0aW9uLmFzc2V0SUQpID09PSBhc3NldElEKSB7XG4gICAgICBjb25zdCBldm1JbnB1dDogRVZNSW5wdXQgPSBuZXcgRVZNSW5wdXQoXG4gICAgICAgIGZyb21BZGRyZXNzSGV4LFxuICAgICAgICBhbW91bnQuYWRkKGZlZSksXG4gICAgICAgIGFzc2V0SUQsXG4gICAgICAgIG5vbmNlXG4gICAgICApXG4gICAgICBldm1JbnB1dC5hZGRTaWduYXR1cmVJZHgoMCwgYmludG9vbHMuc3RyaW5nVG9BZGRyZXNzKGZyb21BZGRyZXNzQmVjaCkpXG4gICAgICBldm1JbnB1dHMucHVzaChldm1JbnB1dClcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgYXNzZXQgaWQgaXNuJ3QgQVZBWCBhc3NldCBpZCB0aGVuIGNyZWF0ZSAyIGlucHV0c1xuICAgICAgLy8gZmlyc3QgaW5wdXQgd2lsbCBiZSBBVkFYIGFuZCB3aWxsIGJlIGZvciB0aGUgYW1vdW50IG9mIHRoZSBmZWVcbiAgICAgIC8vIHNlY29uZCBpbnB1dCB3aWxsIGJlIHRoZSBBTlRcbiAgICAgIGNvbnN0IGV2bUFWQVhJbnB1dDogRVZNSW5wdXQgPSBuZXcgRVZNSW5wdXQoXG4gICAgICAgIGZyb21BZGRyZXNzSGV4LFxuICAgICAgICBmZWUsXG4gICAgICAgIGFzc2V0RGVzY3JpcHRpb24uYXNzZXRJRCxcbiAgICAgICAgbm9uY2VcbiAgICAgIClcbiAgICAgIGV2bUFWQVhJbnB1dC5hZGRTaWduYXR1cmVJZHgoMCwgYmludG9vbHMuc3RyaW5nVG9BZGRyZXNzKGZyb21BZGRyZXNzQmVjaCkpXG4gICAgICBldm1JbnB1dHMucHVzaChldm1BVkFYSW5wdXQpXG5cbiAgICAgIGNvbnN0IGV2bUFOVElucHV0OiBFVk1JbnB1dCA9IG5ldyBFVk1JbnB1dChcbiAgICAgICAgZnJvbUFkZHJlc3NIZXgsXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgYXNzZXRJRCxcbiAgICAgICAgbm9uY2VcbiAgICAgIClcbiAgICAgIGV2bUFOVElucHV0LmFkZFNpZ25hdHVyZUlkeCgwLCBiaW50b29scy5zdHJpbmdUb0FkZHJlc3MoZnJvbUFkZHJlc3NCZWNoKSlcbiAgICAgIGV2bUlucHV0cy5wdXNoKGV2bUFOVElucHV0KVxuICAgIH1cblxuICAgIGNvbnN0IHRvOiBCdWZmZXJbXSA9IFtdXG4gICAgdG9BZGRyZXNzZXMubWFwKChhZGRyZXNzOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgIHRvLnB1c2goYmludG9vbHMuc3RyaW5nVG9BZGRyZXNzKGFkZHJlc3MpKVxuICAgIH0pXG5cbiAgICBsZXQgZXhwb3J0ZWRPdXRzOiBUcmFuc2ZlcmFibGVPdXRwdXRbXSA9IFtdXG4gICAgY29uc3Qgc2VjcFRyYW5zZmVyT3V0cHV0OiBTRUNQVHJhbnNmZXJPdXRwdXQgPSBuZXcgU0VDUFRyYW5zZmVyT3V0cHV0KFxuICAgICAgYW1vdW50LFxuICAgICAgdG8sXG4gICAgICBsb2NrdGltZSxcbiAgICAgIHRocmVzaG9sZFxuICAgIClcbiAgICBjb25zdCB0cmFuc2ZlcmFibGVPdXRwdXQ6IFRyYW5zZmVyYWJsZU91dHB1dCA9IG5ldyBUcmFuc2ZlcmFibGVPdXRwdXQoXG4gICAgICBiaW50b29scy5jYjU4RGVjb2RlKGFzc2V0SUQpLFxuICAgICAgc2VjcFRyYW5zZmVyT3V0cHV0XG4gICAgKVxuICAgIGV4cG9ydGVkT3V0cy5wdXNoKHRyYW5zZmVyYWJsZU91dHB1dClcblxuICAgIC8vIGxleGljb2dyYXBoaWNhbGx5IHNvcnQgaW5zIGFuZCBvdXRzXG4gICAgZXZtSW5wdXRzID0gZXZtSW5wdXRzLnNvcnQoRVZNSW5wdXQuY29tcGFyYXRvcigpKVxuICAgIGV4cG9ydGVkT3V0cyA9IGV4cG9ydGVkT3V0cy5zb3J0KFRyYW5zZmVyYWJsZU91dHB1dC5jb21wYXJhdG9yKCkpXG5cbiAgICBjb25zdCBleHBvcnRUeDogRXhwb3J0VHggPSBuZXcgRXhwb3J0VHgoXG4gICAgICB0aGlzLmNvcmUuZ2V0TmV0d29ya0lEKCksXG4gICAgICBiaW50b29scy5jYjU4RGVjb2RlKHRoaXMuYmxvY2tjaGFpbklEKSxcbiAgICAgIGRlc3RpbmF0aW9uQ2hhaW4sXG4gICAgICBldm1JbnB1dHMsXG4gICAgICBleHBvcnRlZE91dHNcbiAgICApXG5cbiAgICBjb25zdCB1bnNpZ25lZFR4OiBVbnNpZ25lZFR4ID0gbmV3IFVuc2lnbmVkVHgoZXhwb3J0VHgpXG4gICAgcmV0dXJuIHVuc2lnbmVkVHhcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgcmVmZXJlbmNlIHRvIHRoZSBrZXljaGFpbiBmb3IgdGhpcyBjbGFzcy5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGluc3RhbmNlIG9mIFtbS2V5Q2hhaW5dXSBmb3IgdGhpcyBjbGFzc1xuICAgKi9cbiAga2V5Q2hhaW4gPSAoKTogS2V5Q2hhaW4gPT4gdGhpcy5rZXljaGFpblxuXG4gIC8qKlxuICAgKlxuICAgKiBAcmV0dXJucyBuZXcgaW5zdGFuY2Ugb2YgW1tLZXlDaGFpbl1dXG4gICAqL1xuICBuZXdLZXlDaGFpbiA9ICgpOiBLZXlDaGFpbiA9PiB7XG4gICAgLy8gd2FybmluZywgb3ZlcndyaXRlcyB0aGUgb2xkIGtleWNoYWluXG4gICAgY29uc3QgYWxpYXMgPSB0aGlzLmdldEJsb2NrY2hhaW5BbGlhcygpXG4gICAgaWYgKGFsaWFzKSB7XG4gICAgICB0aGlzLmtleWNoYWluID0gbmV3IEtleUNoYWluKHRoaXMuY29yZS5nZXRIUlAoKSwgYWxpYXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua2V5Y2hhaW4gPSBuZXcgS2V5Q2hhaW4odGhpcy5jb3JlLmdldEhSUCgpLCB0aGlzLmJsb2NrY2hhaW5JRClcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMua2V5Y2hhaW5cbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBwcm90ZWN0ZWQgX2NsZWFuQWRkcmVzc0FycmF5KFxuICAgIGFkZHJlc3Nlczogc3RyaW5nW10gfCBCdWZmZXJbXSxcbiAgICBjYWxsZXI6IHN0cmluZ1xuICApOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgYWRkcnM6IHN0cmluZ1tdID0gW11cbiAgICBjb25zdCBjaGFpbmlkOiBzdHJpbmcgPSB0aGlzLmdldEJsb2NrY2hhaW5BbGlhcygpXG4gICAgICA/IHRoaXMuZ2V0QmxvY2tjaGFpbkFsaWFzKClcbiAgICAgIDogdGhpcy5nZXRCbG9ja2NoYWluSUQoKVxuICAgIGlmIChhZGRyZXNzZXMgJiYgYWRkcmVzc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIGFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyZXNzOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBhZGRyZXNzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnBhcnNlQWRkcmVzcyhhZGRyZXNzIGFzIHN0cmluZykgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgICB0aHJvdyBuZXcgQWRkcmVzc0Vycm9yKFwiRXJyb3IgLSBJbnZhbGlkIGFkZHJlc3MgZm9ybWF0XCIpXG4gICAgICAgICAgfVxuICAgICAgICAgIGFkZHJzLnB1c2goYWRkcmVzcyBhcyBzdHJpbmcpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgdHlwZTogU2VyaWFsaXplZFR5cGUgPSBcImJlY2gzMlwiXG4gICAgICAgICAgYWRkcnMucHVzaChcbiAgICAgICAgICAgIHNlcmlhbGl6YXRpb24uYnVmZmVyVG9UeXBlKFxuICAgICAgICAgICAgICBhZGRyZXNzIGFzIEJ1ZmZlcixcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgdGhpcy5jb3JlLmdldEhSUCgpLFxuICAgICAgICAgICAgICBjaGFpbmlkXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gYWRkcnNcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGNsYXNzIHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LlxuICAgKiBJbnN0ZWFkIHVzZSB0aGUgW1tBdmFsYW5jaGUuYWRkQVBJXV0gbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0gY29yZSBBIHJlZmVyZW5jZSB0byB0aGUgQXZhbGFuY2hlIGNsYXNzXG4gICAqIEBwYXJhbSBiYXNlVVJMIERlZmF1bHRzIHRvIHRoZSBzdHJpbmcgXCIvZXh0L2JjL0MvYXZheFwiIGFzIHRoZSBwYXRoIHRvIGJsb2NrY2hhaW4ncyBiYXNlVVJMXG4gICAqIEBwYXJhbSBibG9ja2NoYWluSUQgVGhlIEJsb2NrY2hhaW4ncyBJRC4gRGVmYXVsdHMgdG8gYW4gZW1wdHkgc3RyaW5nOiBcIlwiXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBjb3JlOiBBdmFsYW5jaGVDb3JlLFxuICAgIGJhc2VVUkw6IHN0cmluZyA9IFwiL2V4dC9iYy9DL2F2YXhcIixcbiAgICBibG9ja2NoYWluSUQ6IHN0cmluZyA9IFwiXCJcbiAgKSB7XG4gICAgc3VwZXIoY29yZSwgYmFzZVVSTClcbiAgICB0aGlzLmJsb2NrY2hhaW5JRCA9IGJsb2NrY2hhaW5JRFxuICAgIGNvbnN0IG5ldElEOiBudW1iZXIgPSBjb3JlLmdldE5ldHdvcmtJRCgpXG4gICAgaWYgKFxuICAgICAgbmV0SUQgaW4gRGVmYXVsdHMubmV0d29yayAmJlxuICAgICAgYmxvY2tjaGFpbklEIGluIERlZmF1bHRzLm5ldHdvcmtbYCR7bmV0SUR9YF1cbiAgICApIHtcbiAgICAgIGNvbnN0IGFsaWFzOiBzdHJpbmcgPVxuICAgICAgICBEZWZhdWx0cy5uZXR3b3JrW2Ake25ldElEfWBdW2Ake2Jsb2NrY2hhaW5JRH1gXVtcImFsaWFzXCJdXG4gICAgICB0aGlzLmtleWNoYWluID0gbmV3IEtleUNoYWluKHRoaXMuY29yZS5nZXRIUlAoKSwgYWxpYXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua2V5Y2hhaW4gPSBuZXcgS2V5Q2hhaW4odGhpcy5jb3JlLmdldEhSUCgpLCBibG9ja2NoYWluSUQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIGEgUHJvbWlzZSBzdHJpbmcgY29udGFpbmluZyB0aGUgYmFzZSBmZWUgZm9yIHRoZSBuZXh0IGJsb2NrLlxuICAgKi9cbiAgZ2V0QmFzZUZlZSA9IGFzeW5jICgpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHBhcmFtczogc3RyaW5nW10gPSBbXVxuICAgIGNvbnN0IG1ldGhvZDogc3RyaW5nID0gXCJldGhfYmFzZUZlZVwiXG4gICAgY29uc3QgcGF0aDogc3RyaW5nID0gXCJleHQvYmMvQy9ycGNcIlxuICAgIGNvbnN0IHJlc3BvbnNlOiBSZXF1ZXN0UmVzcG9uc2VEYXRhID0gYXdhaXQgdGhpcy5jYWxsTWV0aG9kKFxuICAgICAgbWV0aG9kLFxuICAgICAgcGFyYW1zLFxuICAgICAgcGF0aFxuICAgIClcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5yZXN1bHRcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSBwcmlvcml0eSBmZWUgbmVlZGVkIHRvIGJlIGluY2x1ZGVkIGluIGEgYmxvY2suXG4gICAqXG4gICAqIEByZXR1cm5zIFJldHVybnMgYSBQcm9taXNlIHN0cmluZyBjb250YWluaW5nIHRoZSBwcmlvcml0eSBmZWUgbmVlZGVkIHRvIGJlIGluY2x1ZGVkIGluIGEgYmxvY2suXG4gICAqL1xuICBnZXRNYXhQcmlvcml0eUZlZVBlckdhcyA9IGFzeW5jICgpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHBhcmFtczogc3RyaW5nW10gPSBbXVxuXG4gICAgY29uc3QgbWV0aG9kOiBzdHJpbmcgPSBcImV0aF9tYXhQcmlvcml0eUZlZVBlckdhc1wiXG4gICAgY29uc3QgcGF0aDogc3RyaW5nID0gXCJleHQvYmMvQy9ycGNcIlxuICAgIGNvbnN0IHJlc3BvbnNlOiBSZXF1ZXN0UmVzcG9uc2VEYXRhID0gYXdhaXQgdGhpcy5jYWxsTWV0aG9kKFxuICAgICAgbWV0aG9kLFxuICAgICAgcGFyYW1zLFxuICAgICAgcGF0aFxuICAgIClcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5yZXN1bHRcbiAgfVxufVxuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!