eulith-web3js-core
Version:
Eulith core web3js SDK (code to access Eulith services via web3js)
308 lines • 40.6 kB
JavaScript
;
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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.Tokens = void 0;
const web3_1 = __importDefault(require("web3"));
const Eulith = __importStar(require("../src/index"));
/**
* Module for code relating to (mostly ERC20) tokens.
*/
var Tokens;
(function (Tokens) {
/**
* The Symbols enumeration lists the ERC20 symbol (property of the contract) values associated with
* some common ERC20 token contracts.
*
* Historical Note: Cloned from erc20.py TokenSymbol
*/
let Symbols;
(function (Symbols) {
Symbols["USDT"] = "USDT";
Symbols["BNB"] = "BNB";
Symbols["USDC"] = "USDC";
Symbols["BUSD"] = "BUSD";
Symbols["MATIC"] = "MATIC";
Symbols["STETH"] = "stETH";
Symbols["WETH"] = "WETH";
Symbols["LDO"] = "LDO";
Symbols["CRV"] = "CRV";
Symbols["CVX"] = "CVX";
Symbols["BAL"] = "BAL";
Symbols["BADGER"] = "BADGER";
Symbols["ONEINCH"] = "1INCH";
Symbols["UNI"] = "UNI";
Symbols["LINK"] = "LINK";
Symbols["APE"] = "APE";
Symbols["GMT"] = "GMT";
Symbols["WBTC"] = "WBTC";
Symbols["LUSD"] = "LUSD";
Symbols["FRAX"] = "FRAX";
Symbols["CBETH"] = "cbETH";
Symbols["GALA"] = "GALA";
Symbols["HEX"] = "HEX";
Symbols["RPL"] = "RPL";
Symbols["DYDX"] = "DYDX";
Symbols["BONE"] = "BONE";
Symbols["LOOKS"] = "LOOKS";
Symbols["AGEUR"] = "agEUR";
Symbols["OSQTH"] = "oSQTH";
Symbols["WSTETH"] = "wstETH";
Symbols["ALBT"] = "ALBT";
})(Symbols = Tokens.Symbols || (Tokens.Symbols = {}));
/**
* Eulith.Token.getTokenContract - erc20-token-based smart contract factory
*
* Return the ERC20based token contract object, for the given symbol.
*
* This function always returns a valid ERC20 contract, or raises an exception.
*
* This function requires a valid 'provider' (which is bound to the returned contract),
* and EITHER an valid symbol, or contract address (from which the symbol can be retrieved).
*
* See also Eulith.Contracts.ERC20TokenContract - if you don't have a 'symbol' - but an address/etc for the contract.
*
* \note - this replaces Eulith.Web3.getERCToken()
*/
function getTokenContract({ provider, symbol, address }) {
return __awaiter(this, void 0, void 0, function* () {
try {
let contractAddr;
let decimals;
if (symbol != undefined) {
const result = (yield provider.request({ method: "eulith_erc_lookup", params: [{ symbol }] }))[0];
contractAddr = result === null || result === void 0 ? void 0 : result.contract_address;
decimals = result === null || result === void 0 ? void 0 : result.decimals;
}
else {
contractAddr = address;
}
if (contractAddr === undefined) {
throw new Error("Unrecognized token contract");
}
if (symbol == Eulith.Tokens.Symbols.WETH) {
if (decimals != 18) {
throw new Error("unexpected decimal count in getTokenContract");
}
return Eulith.Contracts.WethTokenContract.mk({ provider, contractAddress: contractAddr });
}
else {
return Eulith.Contracts.ERC20TokenContract.mk({
provider,
contractAddress: contractAddr,
decimals,
symbol
});
}
}
catch (e) {
// check if is 'Error' type and prepend 'while' ... stuff to message
// LogErr_(this.logger_, "calling getERCToken", e);
throw e;
}
});
}
Tokens.getTokenContract = getTokenContract;
/**
* The API for web3js is somewhat confusing/flexible about units. These utility classes
* make easier converting a particular value to/from its web/wire format, and to/from a
* sensible numeric value in that tokens 'base' units.
*
* \note It would be nice to support operator overloading, and conversion operators and such
* but this appears to be a weakness in typescript, that it doesn't support this (making a utility like this
* far less useful)
*/
let Value;
(function (Value) {
/**
* An ETH token value is NOT an ERC20 compatible token value, but rather a value from the native blockchain.
*/
class ETH {
/**
* if v is a number, its interpretted in ether units
* if v is a string or bigint, its interpretted as being in fundamental units (wei).
*/
constructor(v) {
if (typeof v === "number") {
this.fundementalValue_ = BigInt(v * Math.pow(10, 18));
}
else if (typeof v === "bigint") {
this.fundementalValue_ = v;
}
else {
this.fundementalValue_ = BigInt(web3_1.default.utils.toWei(v, "wei"));
}
}
/**
* Return the value as a native javascript number, in the units of this currency (ETH)
*/
get asFloat() {
return Number(this.fundementalValue_) / Math.pow(10, 18);
}
/*
* wire format is the 'Fundamental' format, as Hex string
*/
get asWire() {
return this.asWeiHex;
}
get asFundamentalFloat() {
return Number(this.fundementalValue_);
}
get asFundamentalBN() {
return web3_1.default.utils.toBN(this.asFundamentalFloat);
}
get asFundamentalHex() {
return web3_1.default.utils.fromWei(this.asFundamentalBN, "wei");
}
get asFundamentalBigInt() {
return this.fundementalValue_;
}
/*
* 'Wei' is the 'Fundamental' currency for ETH
*/
get asWeiBN() {
return this.asFundamentalBN;
}
get asWeiHex() {
return this.asFundamentalHex;
}
get asWeiBigInt() {
return this.asFundamentalBigInt;
}
get symbol() {
return "ETH";
}
get asDisplayString() {
return `${this.asFloat} ${this.symbol}`;
}
cloneWithNewValue(newV) {
return new ETH(newV);
}
}
Value.ETH = ETH;
/**
* Eulith.Tokens.Value.ERC20 is an object that refers to a value of a token from an ERC20
* contract (see https://eips.ethereum.org/EIPS/eip-20).
*
* This contains a number, and a level of precision, used when converting to the native form.
*/
class ERC20 {
/**
* if v is a number, its interpretted in ERC20 token units
* if v is a string | BigInt, its interpretted as being in fundamental units.
*/
constructor({ v, decimals, contract, symbol }) {
if (contract && !decimals) {
decimals = contract.decimals;
}
if (!decimals) {
throw new Error("Expected either decimals or contract as argument to Eulith.Tokens.Value.ERC20");
}
if (contract && !symbol) {
symbol = contract.symbol;
}
if (!symbol) {
throw new Error("Expected either symbol or contract as argument to Eulith.Tokens.Value.ERC20");
}
this.symbol_ = symbol;
this.decimals_ = decimals;
this.toWireFactor_ = Math.pow(10, decimals);
if (typeof v === "number") {
this.fundementalValue_ = BigInt(Math.round(v * this.toWireFactor_));
}
else if (typeof v === "bigint") {
this.fundementalValue_ = v;
}
else if (typeof v === "string") {
this.fundementalValue_ = BigInt(v);
}
else {
this.fundementalValue_ = v.asFundamentalBigInt;
}
}
get asFloat() {
// @todo this isn't necesarily the best way to convert - probably better to shift decimals first and then convert.
return Number(this.fundementalValue_) / this.toWireFactor_;
}
get asWire() {
return this.asFundamentalHex;
}
get asFundamentalHex() {
return "0x" + this.fundementalValue_.toString(16);
}
get asFundamentalBN() {
return web3_1.default.utils.toBN(this.asFundamentalHex);
}
get asFundamentalBigInt() {
return this.fundementalValue_;
}
get asFundamentalFloat() {
return Number(this.fundementalValue_);
}
get symbol() {
return this.symbol_;
}
get asDisplayString() {
return `${this.asFloat} ${this.symbol}`;
}
cloneWithNewValue(newV) {
return new ERC20({ v: newV, symbol: this.symbol_, decimals: this.decimals_ });
}
}
Value.ERC20 = ERC20;
/**
* @todo DISCUSS IF THIS SHOULD BE DEPRECATED? IMHO NO, but Kristian at one point I think thought it should...
*/
class USDC extends ERC20 {
constructor(v) {
super({ v: v, decimals: 6 });
}
}
Value.USDC = USDC;
/**
* Really BEST word here would be Atomic, but too risky of confusion with atomic in "Atomic Transactions"
*
* This is the smallest indivisible unit of money for a given ERC20 token.
*/
class Fundamental extends ERC20 {
constructor(v) {
super({ v: v, decimals: 1 });
}
}
Value.Fundamental = Fundamental;
})(Value = Tokens.Value || (Tokens.Value = {}));
})(Tokens = exports.Tokens || (exports.Tokens = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rva2Vucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLGdEQUF3QjtBQUV4QixxREFBdUM7QUFFdkM7O0dBRUc7QUFDSCxJQUFjLE1BQU0sQ0F3WG5CO0FBeFhELFdBQWMsTUFBTTtJQUNoQjs7Ozs7T0FLRztJQUNILElBQVksT0FnQ1g7SUFoQ0QsV0FBWSxPQUFPO1FBQ2Ysd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCx3QkFBYSxDQUFBO1FBQ2Isd0JBQWEsQ0FBQTtRQUNiLDBCQUFlLENBQUE7UUFDZiwwQkFBZSxDQUFBO1FBQ2Ysd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCxzQkFBVyxDQUFBO1FBQ1gsc0JBQVcsQ0FBQTtRQUNYLHNCQUFXLENBQUE7UUFDWCw0QkFBaUIsQ0FBQTtRQUNqQiw0QkFBaUIsQ0FBQTtRQUNqQixzQkFBVyxDQUFBO1FBQ1gsd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCxzQkFBVyxDQUFBO1FBQ1gsd0JBQWEsQ0FBQTtRQUNiLHdCQUFhLENBQUE7UUFDYix3QkFBYSxDQUFBO1FBQ2IsMEJBQWUsQ0FBQTtRQUNmLHdCQUFhLENBQUE7UUFDYixzQkFBVyxDQUFBO1FBQ1gsc0JBQVcsQ0FBQTtRQUNYLHdCQUFhLENBQUE7UUFDYix3QkFBYSxDQUFBO1FBQ2IsMEJBQWUsQ0FBQTtRQUNmLDBCQUFlLENBQUE7UUFDZiwwQkFBZSxDQUFBO1FBQ2YsNEJBQWlCLENBQUE7UUFDakIsd0JBQWEsQ0FBQTtJQUNqQixDQUFDLEVBaENXLE9BQU8sR0FBUCxjQUFPLEtBQVAsY0FBTyxRQWdDbEI7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsU0FBc0IsZ0JBQWdCLENBQUMsRUFDbkMsUUFBUSxFQUNSLE1BQU0sRUFDTixPQUFPLEVBS1Y7O1lB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QUFLLEdBQUwsWUFBSyxLQUFMLFlBQUssUUE0UWxCO0FBQ0wsQ0FBQyxFQXhYYSxNQUFNLEdBQU4sY0FBTSxLQUFOLGNBQU0sUUF3WG5CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJOIGZyb20gXCJiblwiO1xuaW1wb3J0IFdlYjMgZnJvbSBcIndlYjNcIjtcblxuaW1wb3J0ICogYXMgRXVsaXRoIGZyb20gXCIuLi9zcmMvaW5kZXhcIjtcblxuLyoqXG4gKiAgTW9kdWxlIGZvciBjb2RlIHJlbGF0aW5nIHRvIChtb3N0bHkgRVJDMjApIHRva2Vucy5cbiAqL1xuZXhwb3J0IG1vZHVsZSBUb2tlbnMge1xuICAgIC8qKlxuICAgICAqICBUaGUgU3ltYm9scyBlbnVtZXJhdGlvbiBsaXN0cyB0aGUgRVJDMjAgc3ltYm9sIChwcm9wZXJ0eSBvZiB0aGUgY29udHJhY3QpIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAgKiAgc29tZSBjb21tb24gRVJDMjAgdG9rZW4gY29udHJhY3RzLlxuICAgICAqXG4gICAgICogIEhpc3RvcmljYWwgTm90ZTogQ2xvbmVkIGZyb20gZXJjMjAucHkgVG9rZW5TeW1ib2xcbiAgICAgKi9cbiAgICBleHBvcnQgZW51bSBTeW1ib2xzIHtcbiAgICAgICAgVVNEVCA9IFwiVVNEVFwiLFxuICAgICAgICBCTkIgPSBcIkJOQlwiLFxuICAgICAgICBVU0RDID0gXCJVU0RDXCIsXG4gICAgICAgIEJVU0QgPSBcIkJVU0RcIixcbiAgICAgICAgTUFUSUMgPSBcIk1BVElDXCIsXG4gICAgICAgIFNURVRIID0gXCJzdEVUSFwiLFxuICAgICAgICBXRVRIID0gXCJXRVRIXCIsXG4gICAgICAgIExETyA9IFwiTERPXCIsXG4gICAgICAgIENSViA9IFwiQ1JWXCIsXG4gICAgICAgIENWWCA9IFwiQ1ZYXCIsXG4gICAgICAgIEJBTCA9IFwiQkFMXCIsXG4gICAgICAgIEJBREdFUiA9IFwiQkFER0VSXCIsXG4gICAgICAgIE9ORUlOQ0ggPSBcIjFJTkNIXCIsXG4gICAgICAgIFVOSSA9IFwiVU5JXCIsXG4gICAgICAgIExJTksgPSBcIkxJTktcIixcbiAgICAgICAgQVBFID0gXCJBUEVcIixcbiAgICAgICAgR01UID0gXCJHTVRcIixcbiAgICAgICAgV0JUQyA9IFwiV0JUQ1wiLFxuICAgICAgICBMVVNEID0gXCJMVVNEXCIsXG4gICAgICAgIEZSQVggPSBcIkZSQVhcIixcbiAgICAgICAgQ0JFVEggPSBcImNiRVRIXCIsXG4gICAgICAgIEdBTEEgPSBcIkdBTEFcIixcbiAgICAgICAgSEVYID0gXCJIRVhcIixcbiAgICAgICAgUlBMID0gXCJSUExcIixcbiAgICAgICAgRFlEWCA9IFwiRFlEWFwiLFxuICAgICAgICBCT05FID0gXCJCT05FXCIsXG4gICAgICAgIExPT0tTID0gXCJMT09LU1wiLFxuICAgICAgICBBR0VVUiA9IFwiYWdFVVJcIixcbiAgICAgICAgT1NRVEggPSBcIm9TUVRIXCIsXG4gICAgICAgIFdTVEVUSCA9IFwid3N0RVRIXCIsXG4gICAgICAgIEFMQlQgPSBcIkFMQlRcIlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV1bGl0aC5Ub2tlbi5nZXRUb2tlbkNvbnRyYWN0IC0gZXJjMjAtdG9rZW4tYmFzZWQgc21hcnQgY29udHJhY3QgZmFjdG9yeVxuICAgICAqXG4gICAgICogIFJldHVybiB0aGUgRVJDMjBiYXNlZCB0b2tlbiBjb250cmFjdCBvYmplY3QsIGZvciB0aGUgZ2l2ZW4gc3ltYm9sLlxuICAgICAqXG4gICAgICogIFRoaXMgZnVuY3Rpb24gYWx3YXlzIHJldHVybnMgYSB2YWxpZCBFUkMyMCBjb250cmFjdCwgb3IgcmFpc2VzIGFuIGV4Y2VwdGlvbi5cbiAgICAgKlxuICAgICAqICBUaGlzIGZ1bmN0aW9uIHJlcXVpcmVzIGEgdmFsaWQgJ3Byb3ZpZGVyJyAod2hpY2ggaXMgYm91bmQgdG8gdGhlIHJldHVybmVkIGNvbnRyYWN0KSxcbiAgICAgKiAgYW5kIEVJVEhFUiBhbiB2YWxpZCBzeW1ib2wsIG9yIGNvbnRyYWN0IGFkZHJlc3MgKGZyb20gd2hpY2ggdGhlIHN5bWJvbCBjYW4gYmUgcmV0cmlldmVkKS5cbiAgICAgKlxuICAgICAqICBTZWUgYWxzbyBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdCAtIGlmIHlvdSBkb24ndCBoYXZlIGEgJ3N5bWJvbCcgLSBidXQgYW4gYWRkcmVzcy9ldGMgZm9yIHRoZSBjb250cmFjdC5cbiAgICAgKlxuICAgICAqICBcXG5vdGUgLSB0aGlzIHJlcGxhY2VzIEV1bGl0aC5XZWIzLmdldEVSQ1Rva2VuKClcbiAgICAgKi9cbiAgICBleHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0VG9rZW5Db250cmFjdCh7XG4gICAgICAgIHByb3ZpZGVyLFxuICAgICAgICBzeW1ib2wsXG4gICAgICAgIGFkZHJlc3NcbiAgICB9OiB7XG4gICAgICAgIHByb3ZpZGVyOiBFdWxpdGguUHJvdmlkZXI7XG4gICAgICAgIHN5bWJvbD86IFN5bWJvbHM7XG4gICAgICAgIGFkZHJlc3M/OiBzdHJpbmc7XG4gICAgfSk6IFByb21pc2U8RXVsaXRoLkNvbnRyYWN0cy5FUkMyMFRva2VuQ29udHJhY3QgfCBFdWxpdGguQ29udHJhY3RzLldldGhUb2tlbkNvbnRyYWN0PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgY29udHJhY3RBZGRyOiBzdHJpbmc7XG4gICAgICAgICAgICBsZXQgZGVjaW1hbHM6IG51bWJlcjtcbiAgICAgICAgICAgIGlmIChzeW1ib2wgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IHByb3ZpZGVyLnJlcXVlc3QoeyBtZXRob2Q6IFwiZXVsaXRoX2VyY19sb29rdXBcIiwgcGFyYW1zOiBbeyBzeW1ib2wgfV0gfSkpWzBdO1xuICAgICAgICAgICAgICAgIGNvbnRyYWN0QWRkciA9IHJlc3VsdD8uY29udHJhY3RfYWRkcmVzcztcbiAgICAgICAgICAgICAgICBkZWNpbWFscyA9IHJlc3VsdD8uZGVjaW1hbHMgYXMgbnVtYmVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250cmFjdEFkZHIgPSBhZGRyZXNzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbnRyYWN0QWRkciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5yZWNvZ25pemVkIHRva2VuIGNvbnRyYWN0XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN5bWJvbCA9PSBFdWxpdGguVG9rZW5zLlN5bWJvbHMuV0VUSCkge1xuICAgICAgICAgICAgICAgIGlmIChkZWNpbWFscyAhPSAxOCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmV4cGVjdGVkIGRlY2ltYWwgY291bnQgaW4gZ2V0VG9rZW5Db250cmFjdFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEV1bGl0aC5Db250cmFjdHMuV2V0aFRva2VuQ29udHJhY3QubWsoeyBwcm92aWRlciwgY29udHJhY3RBZGRyZXNzOiBjb250cmFjdEFkZHIgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdC5tayh7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICAgICBjb250cmFjdEFkZHJlc3M6IGNvbnRyYWN0QWRkcixcbiAgICAgICAgICAgICAgICAgICAgZGVjaW1hbHMsXG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGlzICdFcnJvcicgdHlwZSBhbmQgcHJlcGVuZCAnd2hpbGUnIC4uLiBzdHVmZiB0byBtZXNzYWdlXG4gICAgICAgICAgICAvLyBMb2dFcnJfKHRoaXMubG9nZ2VyXywgXCJjYWxsaW5nIGdldEVSQ1Rva2VuXCIsIGUpO1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqICBUaGUgQVBJIGZvciB3ZWIzanMgaXMgc29tZXdoYXQgY29uZnVzaW5nL2ZsZXhpYmxlIGFib3V0IHVuaXRzLiBUaGVzZSB1dGlsaXR5IGNsYXNzZXNcbiAgICAgKiAgbWFrZSBlYXNpZXIgY29udmVydGluZyBhIHBhcnRpY3VsYXIgdmFsdWUgdG8vZnJvbSBpdHMgd2ViL3dpcmUgZm9ybWF0LCBhbmQgdG8vZnJvbSBhXG4gICAgICogIHNlbnNpYmxlIG51bWVyaWMgdmFsdWUgaW4gdGhhdCB0b2tlbnMgJ2Jhc2UnIHVuaXRzLlxuICAgICAqXG4gICAgICogIFxcbm90ZSBJdCB3b3VsZCBiZSBuaWNlIHRvIHN1cHBvcnQgb3BlcmF0b3Igb3ZlcmxvYWRpbmcsIGFuZCBjb252ZXJzaW9uIG9wZXJhdG9ycyBhbmQgc3VjaFxuICAgICAqICAgICAgICBidXQgdGhpcyBhcHBlYXJzIHRvIGJlIGEgd2Vha25lc3MgaW4gdHlwZXNjcmlwdCwgdGhhdCBpdCBkb2Vzbid0IHN1cHBvcnQgdGhpcyAobWFraW5nIGEgdXRpbGl0eSBsaWtlIHRoaXNcbiAgICAgKiAgICAgICAgZmFyIGxlc3MgdXNlZnVsKVxuICAgICAqL1xuXG4gICAgZXhwb3J0IG1vZHVsZSBWYWx1ZSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgQWJzdHJhY3QgQVBJIHRvIGNhcHR1cmUgYmFzaWMgaW50ZXJvcGVyYXRpb24gb2YgdG9rZW4gdmFsdWVzIGFzIGV4Y2hhbmdlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogIE9uZSBrZXkgaWRlYSBoZXJlIC0gaXMgdGhhdCBmb3IgSVRva2VuVmFsdWUsIHRoZXJlIGFyZSB0d28gQkFTSUMgTlVNQkVSUyB5b3UgY2FuIGdldC5cbiAgICAgICAgICogICAgICBvICAgdGhlIHZhbHVlIGluIGl0cyBiYXNpYyBhdG9taWMgKGZ1bmRlbWVudGFsKSB1bml0c1xuICAgICAgICAgKiAgICAgIG8gICBhbmQgdGhlIHZhbHVlIGluIGl0cyBuYXRpdmUgKGUuZy4gV0VUSCBvciBVRFNDIGV0YykgRVJDMjAgdW5pdHMuXG4gICAgICAgICAqXG4gICAgICAgICAqICBUaGVuIHRoZXJlIGlzIHRoZSBPUlRIT0dBTkFMIGlzc3VlIG9mIGhvdyB5b3UgcmVwcmVzZW50IHRoYXQgbnVtYmVyIChmbG9hdCwgb3IgaGV4IHN0cmluZykuXG4gICAgICAgICAqXG4gICAgICAgICAqICBJdCB0dXJucyBvdXQgLSB0aGUgT05MWSB1c2UgZm9yIHRoZSBoZXggc3RyaW5ncywgYXJlIGluIGZ1bmRlbWVudGFsIHVuaXRzLCAod2lyZSBmb3JtYXQpIC1cbiAgICAgICAgICogIHNvIHRoYXRzIHRoZSBvbmx5IGNhc2Ugd2hlcmUgd2Ugb2ZmZXIgdGhhdCByZXByZXNlbnRhdGlvbiB0eXBlLiBTaW1pbGFybHksIEJpZ051bSdzIGFyZSB1c2VkXG4gICAgICAgICAqICBlc3NlbnRpYWxseSBhbHdheXMgZm9yIHRoZSBmdW5kZW1lbnRhbCByZXByZXNlbnRhdGlvbiAoYXRvbWljIHVuaXRzKSAtIHNvIHRoaXMgaXMgdGhlIHByZWZlcmVkXG4gICAgICAgICAqICBkYXRhIGZvcm1hdCBmb3IgdGhlIGZ1bmRlbWVudGFsIHJlcHJlc2VudGF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiAgQHRvZG8gRElTQ1VTUyBpZiBJVG9rZW5WYWx1ZSBzaG91bGQgaGF2ZSBhIHJlYWRvbmx5ICd1bml0cycgc3RyaW5nIHByb3BlcnR5LCBvcHRpb25hbCxcbiAgICAgICAgICogICAgICAgIGZvciBkb2N1bWVudGF0aW9uIHB1cnBvc2VzIChhc0Rpc3BsYXlTdHJpbmcgbWV0aG9kKS4gTUlHSFQgQkUgVVNFRlVMIHRvIHRyYWNrXG4gICAgICAgICAqICAgICAgICBkaWZmZXJlbmNlIGJldHdlZW4gRVRIIGFuZCBVU0RDIHRva2VuIHZhbHVlcy4gSW50ZXJvcGVyYWJsZSwgYnV0IHRoYXRzIHByb2JhYmx5IHVuZm9ydHVuYXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiAgQHRvZG8gRElTQ1VTUyBpZiBJVG9rZW5WYWx1ZSBzaG91bGQgaGF2ZSBhIHJlYWRvbmx5ICdkZWNpbWFscycgdmFsdWUuIEl0IGhhcyB0aGlzIElNUExJQ0lUTFkgYmVjYXVzZVxuICAgICAgICAgKiAgICAgICAgb2YgdGhlIGNvdm5lcnNpb24gYmV0d2VlbiBhc0Zsb2F0IGFuZCBhc0Z1bmRhbWVudGFsRmxvYXQgKGRlY2ltYWxzPT1sb2coYXNGdW5kYW1lbnRhbEZsb2F0L2FzRmxvYXQpKVxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0IGludGVyZmFjZSBJVG9rZW5WYWx1ZSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm4gdGhlIHZhbHVlIGFzIGEgbmF0aXZlIGphdmFzY3JpcHQgbnVtYmVyLCBpbiB0aGUgdW5pdHMgb2YgdGhpcyBjdXJyZW5jeVxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBOT1RFIC0gdGhpcyBjb252ZXJzaW9uIHRvIGEgamF2YXNjcmlwdCBudW1iZXIgY2FuIGJlIGxvc3N5LlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBcXG5vdGUgLSB3ZSBjYW5ub3QgcmV0dXJuIHRoZSBFUkMyMCB0b2tlbiByZXByZXNlbnRhdGlvbiBhcyBCTiwgb3IgQmlnSW50LCAgYmVjYXVzZVxuICAgICAgICAgICAgICogICAgICAgICAgdGhpcyB3aWxsIGZyZXF1ZW50bHkgYmUgYSBmcmFjdGlvbmFsIChkZWNpbWFsKSBxdWFudGl0eSBpbiB0aGUgbmF0aXZlIHRva2VuIHVuaXRzIChsaWtlIFVTREMsIG9yIFdFVEgpLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEB0b2RvIElNSE8sIG91ciB1c2Ugb2YgdGhlIHRlcm0gJ0Zsb2F0JyBpbiB0aGlzIEFQSSBjb3VsZCByZWFzb25hYmx5IGJlIHJlcGxhY2VkIHdpdGggJ051bWJlcicsIGFuZCB3b3VsZCBmaXQgYmV0dGVyXG4gICAgICAgICAgICAgKiAgICAgICB3aXRoIEpTIC0gQEtyaXN0aWFuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGdldCBhc0Zsb2F0KCk6IG51bWJlcjtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgdG9rZW4gdmFsdWUgaW4gdGhlIG5hdGl2ZSBmb3JtIGFzIGl0IGdvZXMgb3ZlciB0aGUgd2lyZSB0by9mcm9tIHRoZSBldGhlcmV1bSBuZXR3b3JrL2NvbnRyYWN0LlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBUaGlzIGlzIGVxdWl2aWxlbnQgdG8gYXNGdW5kYW1lbnRhbEhleFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNXaXJlKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgdG9rZW4gdmFsdWUgYXMgYW4gaW50ZWdyYWwgIyBmbG9hdCBpbiB0aGUgRnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXI7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogIFJldHVybnMgdGhlIHRva2VuIHZhbHVlIGFzIGFuIGludGVncmFsICMgQk4gKG9sZCBCaWdOdW1iZXIgQVBJKSBpbiB0aGUgRnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiAgXFxub3RlIC0gQk4gdXNlZCBpbnRlcm5hbGx5IGJ5IHdlYjNqcyBhcyBvZiAxLjgueFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNGdW5kYW1lbnRhbEJOKCk6IEJOO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm5zIHRoZSB0b2tlbiB2YWx1ZSBhcyBhbiBpbnRlZ3JhbCAjIEJpZ0ludCAoTkVXIEJpZ051bWJlciBBUEkpIGluIHRoZSBGdW5kYW1lbnRhbCAoYXRvbWljKSB1bml0c1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNGdW5kYW1lbnRhbEJpZ0ludCgpOiBiaWdpbnQ7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogIFJldHVybnMgdGhlIHRva2VuIHZhbHVlIGFzIGEgaGV4IHN0cmluZyBpbiB0aGUgZnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm4gdGhlIHN5bWJvbCBhc3NvY2lhdGVkIHdpdGggdGhpcyB0b2tlbiB2YWx1ZSAoZnJvbSBFUkMyMCBzeW1ib2wgQVBJKVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgc3ltYm9sKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgbnVtYmVyIGluIG5hdHVyYWwgKG5vdCBhdG9taWMvZnVuZGVtZW50YWwpIHVuaXRzLCB3aXRoIHRoZSBsYWJlbCBvZiB0aGUgc3ltYm9sLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBFeGFtcGxlOlxuICAgICAgICAgICAgICogICAgICAyMy40IFdFVEhcbiAgICAgICAgICAgICAqICAgICAgMTguNDUgVVNEQ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNEaXNwbGF5U3RyaW5nKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyBhIGNsb25lZCB2YWx1ZSwgYnV0IHdpdGggdGhlIG5ldyB2YWx1ZS4gbmV3ViB0eXBlIGludGVycHJldGF0aW9uIHNhbWUgYXMgdGhlXG4gICAgICAgICAgICAgKiAgdmFsdWUgY29uc3RydWN0b3IgKG51bWJlciBpbnRyaW5zaWMgdmFsdWUsIEJpZ0ludCBmdW5kZW1lbnRhbCwgYW5kIHN0cmluZyBmdW5kZW1lbnRhbClcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiAgVXNlZnVsIGZvciBhcml0aG1hdGljIChsaWtlIC8gMilcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNsb25lV2l0aE5ld1ZhbHVlKG5ld1Y6IG51bWJlciB8IHN0cmluZyB8IGJpZ2ludCk6IElUb2tlblZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICBBbiBFVEggdG9rZW4gdmFsdWUgaXMgTk9UIGFuIEVSQzIwIGNvbXBhdGlibGUgdG9rZW4gdmFsdWUsIGJ1dCByYXRoZXIgYSB2YWx1ZSBmcm9tIHRoZSBuYXRpdmUgYmxvY2tjaGFpbi5cbiAgICAgICAgICovXG4gICAgICAgIGV4cG9ydCBjbGFzcyBFVEggaW1wbGVtZW50cyBJVG9rZW5WYWx1ZSB7XG4gICAgICAgICAgICBwcml2YXRlIGZ1bmRlbWVudGFsVmFsdWVfOiBiaWdpbnQ7IC8vIHZhbHVlIGluICd3ZWknIChmdW5kZW1lbnRhbCB1bml0KSwgdXNpbmcgdGhlIEJpZ0ludCBwYWNrYWdlXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogaWYgdiBpcyBhIG51bWJlciwgaXRzIGludGVycHJldHRlZCBpbiBldGhlciB1bml0c1xuICAgICAgICAgICAgICogaWYgdiBpcyBhIHN0cmluZyBvciBiaWdpbnQsIGl0cyBpbnRlcnByZXR0ZWQgYXMgYmVpbmcgaW4gZnVuZGFtZW50YWwgdW5pdHMgKHdlaSkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih2OiBudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IEJpZ0ludCgodiBhcyBudW1iZXIpICogMTAgKiogMTgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IHYgYXMgYmlnaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZnVuZGVtZW50YWxWYWx1ZV8gPSBCaWdJbnQoV2ViMy51dGlscy50b1dlaSh2IGFzIHN0cmluZywgXCJ3ZWlcIikpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJuIHRoZSB2YWx1ZSBhcyBhIG5hdGl2ZSBqYXZhc2NyaXB0IG51bWJlciwgaW4gdGhlIHVuaXRzIG9mIHRoaXMgY3VycmVuY3kgKEVUSClcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcHVibGljIGdldCBhc0Zsb2F0KCk6IG51bWJlciB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0aGlzLmZ1bmRlbWVudGFsVmFsdWVfKSAvIDEwICoqIDE4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogIHdpcmUgZm9ybWF0IGlzIHRoZSAnRnVuZGFtZW50YWwnIGZvcm1hdCwgYXMgSGV4IHN0cmluZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzV2lyZSgpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFzV2VpSGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXIge1xuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5mdW5kZW1lbnRhbFZhbHVlXyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxCTigpOiBCTiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFdlYjMudXRpbHMudG9CTih0aGlzLmFzRnVuZGFtZW50YWxGbG9hdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gV2ViMy51dGlscy5mcm9tV2VpKHRoaXMuYXNGdW5kYW1lbnRhbEJOLCBcIndlaVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNGdW5kYW1lbnRhbEJpZ0ludCgpOiBiaWdpbnQge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZ1bmRlbWVudGFsVmFsdWVfO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogICdXZWknIGlzIHRoZSAnRnVuZGFtZW50YWwnIGN1cnJlbmN5IGZvciBFVEhcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcHVibGljIGdldCBhc1dlaUJOKCk6IEJOIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsQk47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzV2VpSGV4KCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXNGdW5kYW1lbnRhbEhleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNXZWlCaWdJbnQoKTogYmlnaW50IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsQmlnSW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IHN5bWJvbCgpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIkVUSFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRGlzcGxheVN0cmluZygpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLmFzRmxvYXR9ICR7dGhpcy5zeW1ib2x9YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGNsb25lV2l0aE5ld1ZhbHVlKG5ld1Y6IG51bWJlciB8IHN0cmluZyB8IGJpZ2ludCk6IElUb2tlblZhbHVlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVUSChuZXdWKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgRXVsaXRoLlRva2Vucy5WYWx1ZS5FUkMyMCBpcyBhbiBvYmplY3QgdGhhdCByZWZlcnMgdG8gYSB2YWx1ZSBvZiBhIHRva2VuIGZyb20gYW4gRVJDMjBcbiAgICAgICAgICogIGNvbnRyYWN0IChzZWUgaHR0cHM6Ly9laXBzLmV0aGVyZXVtLm9yZy9FSVBTL2VpcC0yMCkuXG4gICAgICAgICAqXG4gICAgICAgICAqICBUaGlzIGNvbnRhaW5zIGEgbnVtYmVyLCBhbmQgYSBsZXZlbCBvZiBwcmVjaXNpb24sIHVzZWQgd2hlbiBjb252ZXJ0aW5nIHRvIHRoZSBuYXRpdmUgZm9ybS5cbiAgICAgICAgICovXG4gICAgICAgIGV4cG9ydCBjbGFzcyBFUkMyMCBpbXBsZW1lbnRzIElUb2tlblZhbHVlIHtcbiAgICAgICAgICAgIHByaXZhdGUgZnVuZGVtZW50YWxWYWx1ZV86IGJpZ2ludDtcbiAgICAgICAgICAgIHByaXZhdGUgdG9XaXJlRmFjdG9yXzogbnVtYmVyO1xuICAgICAgICAgICAgcHJpdmF0ZSBzeW1ib2xfOiBzdHJpbmc7XG4gICAgICAgICAgICBwcml2YXRlIGRlY2ltYWxzXzogbnVtYmVyO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGlmIHYgaXMgYSBudW1iZXIsIGl0cyBpbnRlcnByZXR0ZWQgaW4gRVJDMjAgdG9rZW4gdW5pdHNcbiAgICAgICAgICAgICAqIGlmIHYgaXMgYSBzdHJpbmcgfCBCaWdJbnQsIGl0cyBpbnRlcnByZXR0ZWQgYXMgYmVpbmcgaW4gZnVuZGFtZW50YWwgdW5pdHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgICAgICAgdixcbiAgICAgICAgICAgICAgICBkZWNpbWFscyxcbiAgICAgICAgICAgICAgICBjb250cmFjdCxcbiAgICAgICAgICAgICAgICBzeW1ib2xcbiAgICAgICAgICAgIH06IHtcbiAgICAgICAgICAgICAgICB2OiBudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQgfCBJVG9rZW5WYWx1ZTtcbiAgICAgICAgICAgICAgICBkZWNpbWFscz86IG51bWJlcjtcbiAgICAgICAgICAgICAgICBzeW1ib2w/OiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgY29udHJhY3Q/OiBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdDtcbiAgICAgICAgICAgIH0pIHtcbiAgICAgICAgICAgICAgICBpZiAoY29udHJhY3QgJiYgIWRlY2ltYWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlY2ltYWxzID0gY29udHJhY3QuZGVjaW1hbHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghZGVjaW1hbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgZWl0aGVyIGRlY2ltYWxzIG9yIGNvbnRyYWN0IGFzIGFyZ3VtZW50IHRvIEV1bGl0aC5Ub2tlbnMuVmFsdWUuRVJDMjBcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjb250cmFjdCAmJiAhc3ltYm9sKSB7XG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbCA9IGNvbnRyYWN0LnN5bWJvbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFzeW1ib2wpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgZWl0aGVyIHN5bWJvbCBvciBjb250cmFjdCBhcyBhcmd1bWVudCB0byBFdWxpdGguVG9rZW5zLlZhbHVlLkVSQzIwXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN5bWJvbF8gPSBzeW1ib2w7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWNpbWFsc18gPSBkZWNpbWFscztcbiAgICAgICAgICAgICAgICB0aGlzLnRvV2lyZUZhY3Rvcl8gPSBNYXRoLnBvdygxMCwgZGVjaW1hbHMpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZ1bmRlbWVudGFsVmFsdWVfID0gQmlnSW50KE1hdGgucm91bmQoKHYgYXMgbnVtYmVyKSAqIHRoaXMudG9XaXJlRmFjdG9yXykpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IHYgYXMgYmlnaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IEJpZ0ludCh2IGFzIHN0cmluZyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9ICh2IGFzIElUb2tlblZhbHVlKS5hc0Z1bmRhbWVudGFsQmlnSW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGdldCBhc0Zsb2F0KCk6IG51bWJlciB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gdGhpcyBpc24ndCBuZWNlc2FyaWx5IHRoZSBiZXN0IHdheSB0byBjb252ZXJ0IC0gcHJvYmFibHkgYmV0dGVyIHRvIHNoaWZ0IGRlY2ltYWxzIGZpcnN0IGFuZCB0aGVuIGNvbnZlcnQuXG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0aGlzLmZ1bmRlbWVudGFsVmFsdWVfKSAvIHRoaXMudG9XaXJlRmFjdG9yXztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGdldCBhc1dpcmUoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsSGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCIweFwiICsgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXy50b1N0cmluZygxNik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxCTigpOiBCTiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFdlYjMudXRpbHMudG9CTih0aGlzLmFzRnVuZGFtZW50YWxIZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHVibGljIGdldCBhc0Z1bmRhbWVudGFsQmlnSW50KCk6IGJpZ2ludCB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZnVuZGVtZW50YWxWYWx1ZV87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXIge1xuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5mdW5kZW1lbnRhbFZhbHVlXyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgc3ltYm9sKCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3ltYm9sXztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNEaXNwbGF5U3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMuYXNGbG9hdH0gJHt0aGlzLnN5bWJvbH1gO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgY2xvbmVXaXRoTmV3VmFsdWUobmV3VjogbnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50KTogSVRva2VuVmFsdWUge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRVJDMjAoeyB2OiBuZXdWLCBzeW1ib2w6IHRoaXMuc3ltYm9sXywgZGVjaW1hbHM6IHRoaXMuZGVjaW1hbHNfIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICBAdG9kbyBESVNDVVNTIElGIFRISVMgU0hPVUxEIEJFIERFUFJFQ0FURUQ/IElNSE8gTk8sIGJ1dCBLcmlzdGlhbiBhdCBvbmUgcG9pbnQgSSB0aGluayB0aG91Z2h0IGl0IHNob3VsZC4uLlxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0IGNsYXNzIFVTREMgZXh0ZW5kcyBFUkMyMCB7XG4gICAgICAgICAgICBwdWJsaWMgY29uc3RydWN0b3IodjogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoeyB2OiB2LCBkZWNpbWFsczogNiB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgUmVhbGx5IEJFU1Qgd29yZCBoZXJlIHdvdWxkIGJlIEF0b21pYywgYnV0IHRvbyByaXNreSBvZiBjb25mdXNpb24gd2l0aCBhdG9taWMgaW4gXCJBdG9taWMgVHJhbnNhY3Rpb25zXCJcbiAgICAgICAgICpcbiAgICAgICAgICogIFRoaXMgaXMgdGhlIHNtYWxsZXN0IGluZGl2aXNpYmxlIHVuaXQgb2YgbW9uZXkgZm9yIGEgZ2l2ZW4gRVJDMjAgdG9rZW4uXG4gICAgICAgICAqL1xuICAgICAgICBleHBvcnQgY2xhc3MgRnVuZGFtZW50YWwgZXh0ZW5kcyBFUkMyMCB7XG4gICAgICAgICAgICBwdWJsaWMgY29uc3RydWN0b3IodjogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoeyB2OiB2LCBkZWNpbWFsczogMSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==