UNPKG

@witnet/ethers

Version:

Wit/Oracle Ethers Framework package for EVM-compatible projects

225 lines 37.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WitOracle = void 0; const ethers_1 = require("ethers"); const utils_1 = require("../utils"); const WitArtifact_1 = require("./WitArtifact"); const WitOracleConsumer_1 = require("./WitOracleConsumer"); const WitOracleRadonRegistry_1 = require("./WitOracleRadonRegistry"); const WitOracleRadonRequestFactory_1 = require("./WitOracleRadonRequestFactory"); const WitPriceFeeds_1 = require("./WitPriceFeeds"); const WitPriceFeedsLegacy_1 = require("./WitPriceFeedsLegacy"); const WitRandomness_1 = require("./WitRandomness"); /** * Wrapper class for the Wit/Oracle contract as deployed in some specified EVM network. * It provides wrappers to other main artifacts of the Wit/Oracle Framework, as well * as factory methods for wrapping existing `WitOracleRadonRequestTemplate` and `WitOracleConsumer` * compliant contracts, provably bound to the Wit/Oracle core contract. * */ class WitOracle extends WitArtifact_1.WitArtifact { constructor(signer, network) { super(signer, network, "WitOracle"); } /** * Create a WitOracle attached to the Wit/Oracle main address on the connected EVM network. * Fails if the EVM network served at the specified JSON ETH/RPC endpoint, is not currently bridged * to the Witnet blockchain. * @param url ETH/RPC endpoint URL. * @param signer Specific signer address, other than default, to use for signing EVM transactions. */ static async fromJsonRpcUrl(url, signerId) { const provider = new ethers_1.JsonRpcProvider(url, undefined, { pollingInterval: 5000 }); const signer = await provider.getSigner(signerId); const chainId = Number((await provider.getNetwork()).chainId); const network = (0, utils_1.getEvmNetworkByChainId)(chainId); if (!network) { throw new Error(`WitOracle: unsupported chain id: ${chainId}`); } return new WitOracle(signer, network); } async estimateBaseFee(evmGasPrice) { return this.contract .getFunction("estimateBaseFee(uint256)") .staticCall(evmGasPrice); } async estimateBaseFeeWithCallback(evmGasPrice, evmCallbackGas) { return this.contract .getFunction("estimateBaseFeeWithCallback(uint256,uint24)") .staticCall(evmGasPrice, evmCallbackGas); } async estimateExtraFee(evmGasPrice, evmWitPrice, queryParams) { return this.contract .getFunction("estimateExtraFee(uint256,uint256,(uint16,uint16,uint64)") .staticCall(evmGasPrice, evmWitPrice, (0, utils_1.abiEncodeWitOracleQueryParams)(queryParams)); } async filterWitOracleQueryEvents(options) { const witOracleQueryEvent = this.contract.filters["WitOracleQuery(address indexed,uint256,uint256,uint64,bytes32,(uint16,uint16,uint64))"](options?.where?.evmRequester); return this.contract .queryFilter(witOracleQueryEvent, options.fromBlock, options?.toBlock) .then(logs => logs.filter(log => !log.removed // && (!options?.where?.evmRequester || (log as EventLog).args?.requester === options.where.evmRequester) && (!options?.where?.queryRadHash || log.args?.radonHash.indexOf(options.where.queryRadHash) >= 0))) .then(logs => logs.map(log => ({ evmBlockNumber: BigInt(log.blockNumber), evmRequester: log.args?.evmRequester, evmTransactionHash: log.transactionHash, queryId: BigInt(log.args.queryId), queryRadHash: log.args.radonHash, queryParams: { witnesses: log.args.radonParams[1], unitaryReward: BigInt(log.args.radonParams[2]), resultMaxSize: log.args.radonParams[0], }, }))); } async filterWitOracleReportEvents(options) { const witOracleReportEvent = this.contract.filters.WitOracleReport(options?.where?.evmOrigin, options?.where?.evmConsumer); return this.contract .queryFilter(witOracleReportEvent, options.fromBlock, options?.toBlock) .then(logs => logs.filter(log => !log.removed && (!options?.where?.queryRadHash || log.args?.queryRadHash.indexOf(options.where.queryRadHash) >= 0))) .then(logs => logs.map(log => ({ evmBlockNumber: BigInt(log.blockNumber), evmOrigin: log.args.evmOrigin, evmConsumer: log.args.evmConsumer, evmReporter: log.args.evmReporter, evmTransactionHash: log.transactionHash, witDrTxHash: log.args.witDrTxHash, queryRadHash: log.args.queryRadHash, queryParams: { witnesses: log.args.queryParams[1], unitaryReward: BigInt(log.args.queryParams[2]), resultMaxSize: log.args.queryParams[0], }, resultCborBytes: log.args.resultCborBytes, resultTimestamp: Number(log.args.resultTimestamp), }))); } async getEvmChainId() { return this.provider.getNetwork().then(network => Number(network.chainId)); } async getEvmChannel() { return this.contract .getFunction("channel()") .staticCall(); } async getNextQueryId() { return this.contract .getFunction("getNextQueryId()") .staticCall(); } async getQuery(queryId) { return this.contract .getQuery .staticCall(queryId) .then(result => ({ checkpoint: BigInt(result[5]), hash: result[3], params: { resultMaxSize: result[2][0], unitaryReward: result[2][2], witnesses: result[2][1], }, request: { callbackGas: Number(result[0][1]), radonHash: result[0][3], requester: result[0][0], }, response: { disputer: result[1][4], reporter: result[1][0], resultTimestamp: Number(result[1][1].toString()), resultDrTxHash: result[1][2], resultCborBytes: result[1][3], }, })); } async getQueryResponse(queryId) { return this.contract .getQueryResponse .staticCall(queryId) .then(result => ({ disputer: result[4], reporter: result[0], resultTimestamp: Number(result[1].toString()), resultDrTxHash: result[2], resultCborBytes: result[3], })); } async getQueryResultStatusDescription(queryId) { let reason; try { try { reason = await this.contract.getQueryResultStatusDescription.staticCall(queryId); } catch { const legacy = new ethers_1.Contract(this.address, [ "function getQueryResultError(uint256) public view returns ((uint8,string))", ], this.signer); reason = await legacy.getQueryResultError.staticCall(queryId).then(result => result[1]); } } catch { reason = "(unparsable error)"; } return reason; } async getQueryStatuses(queryIds) { return this.contract .getQueryStatusBatch .staticCall(queryIds) .then((statuses) => statuses.map(value => (0, utils_1.abiDecodeQueryStatus)(value))); } async getWitOracleConsumerAt(target) { return WitOracleConsumer_1.WitOracleConsumer.at(this, target); } /** * Wrapper class for the Wit/Oracle Radon Registry core contract as deployed in some supported EVM network. * It allows formal verification of Radon Requests and Witnet-compliant data sources into such network, * as to be securely referred on both Wit/Oracle queries pulled from within smart contracts, * or Wit/Oracle query results pushed into smart contracts from offchain workflows. */ async getWitOracleRadonRegistry() { return new WitOracleRadonRegistry_1.WitOracleRadonRegistry(this.signer, this.network); } /** * Wrapper class for the Wit/Oracle Request Factory core contract as deployed in some supported EVM network. * It allows construction of `WitOracleRadonRequestTemplate` minimal-proxy contracts out of one ore more * parameterized Radon Retievals (Witnet-compliant data sources). Template addresses are counter-factual to * the set of data sources they are built on. */ async getWitOracleRadonRequestFactory() { return WitOracleRadonRequestFactory_1.WitOracleRadonRequestFactory.deployed(this, await this.getWitOracleRadonRegistry()); } /** * Wrapper class for Wit/Oracle Radon Template artifacts as deployed in some supported EVM network. * `IWitOracleRadonRequestTemplate` contracts enable smart contracts to formally verify Radon Requests * built out out of a set of parameterized Witnet-compliant data sources, on the fly. */ async getWitOracleRadonRequestTemplateAt(target) { return WitOracleRadonRequestFactory_1.WitOracleRadonRequestTemplate.at(this, target); } /** * Wrapper class for Wit/Oracle Radon Modal artifacts as deployed in some supported EVM network. * `IWitOracleRadonRequestModal` contracts enable smart contracts to formally verify Radon Requests * built out out of a single Radon Retrieval and multiple data providers, all of them expected to * provided exactly the same data. */ async getWitOracleRadonRequestModalAt(target) { return WitOracleRadonRequestFactory_1.WitOracleRadonRequestModal.arguments(this, target); } async getWitPriceFeedsAt(target) { return WitPriceFeeds_1.WitPriceFeeds.at(this, target); } async getWitPriceFeedsLegacyAt(target) { return WitPriceFeedsLegacy_1.WitPriceFeedsLegacy.at(this, target); } async getWitRandomnessAt(target) { return WitRandomness_1.WitRandomness.at(this, target); } } exports.WitOracle = WitOracle; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2l0T3JhY2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi93cmFwcGVycy9XaXRPcmFjbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBTWU7QUFJZixvQ0FJaUI7QUFVakIsK0NBQTJDO0FBQzNDLDJEQUF1RDtBQUN2RCxxRUFBaUU7QUFDakUsaUZBQXdJO0FBQ3hJLG1EQUErQztBQUMvQywrREFBMkQ7QUFDM0QsbURBQStDO0FBRS9DOzs7Ozs7R0FNRztBQUNILE1BQWEsU0FBVSxTQUFRLHlCQUFXO0lBRXRDLFlBQWEsTUFBcUIsRUFBRSxPQUFlO1FBQy9DLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFBO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFXLEVBQUUsUUFBMEI7UUFDdEUsTUFBTSxRQUFRLEdBQUcsSUFBSSx3QkFBZSxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUU7WUFDakQsZUFBZSxFQUFFLElBQUk7U0FDeEIsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ2pELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLE1BQU0sUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDN0QsTUFBTSxPQUFPLEdBQUcsSUFBQSw4QkFBc0IsRUFBQyxPQUFPLENBQUMsQ0FBQTtRQUMvQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBQ2xFLENBQUM7UUFDRCxPQUFPLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUN6QyxDQUFDO0lBRU0sS0FB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QUMsSUFBSSxFQUFFLE1BQU0sSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQTtJQUM5RixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxNQUFjO1FBQzFELE9BQU8sNERBQTZCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUN6RCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsK0JBQStCLENBQUMsTUFBYztRQUN2RCxPQUFPLHlEQUEwQixDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDN0QsQ0FBQztJQUVNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFjO1FBQzFDLE9BQU8sNkJBQWEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3pDLENBQUM7SUFFTSxLQUFLLENBQUMsd0JBQXdCLENBQUMsTUFBYztRQUNoRCxPQUFPLHlDQUFtQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDL0MsQ0FBQztJQUVNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFjO1FBQzFDLE9BQU8sNkJBQWEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3pDLENBQUM7Q0FDSjtBQTFRRCw4QkEwUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBcclxuICAgIEJsb2NrVGFnLFxyXG4gICAgQ29udHJhY3QsIFxyXG4gICAgRXZlbnRMb2csXHJcbiAgICBKc29uUnBjUHJvdmlkZXIsIFxyXG4gICAgSnNvblJwY1NpZ25lcixcclxufSBmcm9tIFwiZXRoZXJzXCJcclxuXHJcbmltcG9ydCB7IFdpdG5ldCB9IGZyb20gXCJAd2l0bmV0L3Nka1wiXHJcblxyXG5pbXBvcnQge1xyXG4gICAgYWJpRGVjb2RlUXVlcnlTdGF0dXMsXHJcbiAgICBhYmlFbmNvZGVXaXRPcmFjbGVRdWVyeVBhcmFtcyxcclxuICAgIGdldEV2bU5ldHdvcmtCeUNoYWluSWQsXHJcbn0gZnJvbSBcIi4uL3V0aWxzXCJcclxuXHJcbmltcG9ydCB7IFxyXG4gICAgV2l0T3JhY2xlUXVlcnksXHJcbiAgICBXaXRPcmFjbGVRdWVyeVBhcmFtcywgXHJcbiAgICBXaXRPcmFjbGVRdWVyeVJlc3BvbnNlLFxyXG4gICAgV2l0T3JhY2xlUXVlcnlTdGF0dXNcclxufSBmcm9tIFwiLi4vdHlwZXNcIlxyXG5cclxuXHJcbmltcG9ydCB7IFdpdEFydGlmYWN0IH0gZnJvbSBcIi4vV2l0QXJ0aWZhY3RcIlxyXG5pbXBvcnQgeyBXaXRPcmFjbGVDb25zdW1lciB9IGZyb20gXCIuL1dpdE9yYWNsZUNvbnN1bWVyXCJcclxuaW1wb3J0IHsgV2l0T3JhY2xlUmFkb25SZWdpc3RyeSB9IGZyb20gXCIuL1dpdE9yYWNsZVJhZG9uUmVnaXN0cnlcIlxyXG5pbXBvcnQgeyBXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5LCBXaXRPcmFjbGVSYWRvblJlcXVlc3RNb2RhbCwgV2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGUgfSBmcm9tIFwiLi9XaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5XCJcclxuaW1wb3J0IHsgV2l0UHJpY2VGZWVkcyB9IGZyb20gXCIuL1dpdFByaWNlRmVlZHNcIlxyXG5pbXBvcnQgeyBXaXRQcmljZUZlZWRzTGVnYWN5IH0gZnJvbSBcIi4vV2l0UHJpY2VGZWVkc0xlZ2FjeVwiXHJcbmltcG9ydCB7IFdpdFJhbmRvbW5lc3MgfSBmcm9tIFwiLi9XaXRSYW5kb21uZXNzXCJcclxuXHJcbi8qKlxyXG4gKiBXcmFwcGVyIGNsYXNzIGZvciB0aGUgV2l0L09yYWNsZSBjb250cmFjdCBhcyBkZXBsb3llZCBpbiBzb21lIHNwZWNpZmllZCBFVk0gbmV0d29yay5cclxuICogSXQgcHJvdmlkZXMgd3JhcHBlcnMgdG8gb3RoZXIgbWFpbiBhcnRpZmFjdHMgb2YgdGhlIFdpdC9PcmFjbGUgRnJhbWV3b3JrLCBhcyB3ZWxsXHJcbiAqIGFzIGZhY3RvcnkgbWV0aG9kcyBmb3Igd3JhcHBpbmcgZXhpc3RpbmcgYFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlYCBhbmQgYFdpdE9yYWNsZUNvbnN1bWVyYFxyXG4gKiBjb21wbGlhbnQgY29udHJhY3RzLCBwcm92YWJseSBib3VuZCB0byB0aGUgV2l0L09yYWNsZSBjb3JlIGNvbnRyYWN0LiBcclxuICogXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgV2l0T3JhY2xlIGV4dGVuZHMgV2l0QXJ0aWZhY3Qge1xyXG4gICAgXHJcbiAgICBjb25zdHJ1Y3RvciAoc2lnbmVyOiBKc29uUnBjU2lnbmVyLCBuZXR3b3JrOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihzaWduZXIsIG5ldHdvcmssIFwiV2l0T3JhY2xlXCIpXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgYSBXaXRPcmFjbGUgYXR0YWNoZWQgdG8gdGhlIFdpdC9PcmFjbGUgbWFpbiBhZGRyZXNzIG9uIHRoZSBjb25uZWN0ZWQgRVZNIG5ldHdvcmsuXHJcbiAgICAgKiBGYWlscyBpZiB0aGUgRVZNIG5ldHdvcmsgc2VydmVkIGF0IHRoZSBzcGVjaWZpZWQgSlNPTiBFVEgvUlBDIGVuZHBvaW50LCBpcyBub3QgY3VycmVudGx5IGJyaWRnZWQgXHJcbiAgICAgKiB0byB0aGUgV2l0bmV0IGJsb2NrY2hhaW4uIFxyXG4gICAgICogQHBhcmFtIHVybCBFVEgvUlBDIGVuZHBvaW50IFVSTC5cclxuICAgICAqIEBwYXJhbSBzaWduZXIgU3BlY2lmaWMgc2lnbmVyIGFkZHJlc3MsIG90aGVyIHRoYW4gZGVmYXVsdCwgdG8gdXNlIGZvciBzaWduaW5nIEVWTSB0cmFuc2FjdGlvbnMuIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGZyb21Kc29uUnBjVXJsKHVybDogc3RyaW5nLCBzaWduZXJJZD86IG51bWJlciB8IHN0cmluZyk6IFByb21pc2U8V2l0T3JhY2xlPiB7XHJcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgSnNvblJwY1Byb3ZpZGVyKHVybCwgdW5kZWZpbmVkLCB7XHJcbiAgICAgICAgICAgIHBvbGxpbmdJbnRlcnZhbDogNTAwMFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgY29uc3Qgc2lnbmVyID0gYXdhaXQgcHJvdmlkZXIuZ2V0U2lnbmVyKHNpZ25lcklkKVxyXG4gICAgICAgIGNvbnN0IGNoYWluSWQgPSBOdW1iZXIoKGF3YWl0IHByb3ZpZGVyLmdldE5ldHdvcmsoKSkuY2hhaW5JZClcclxuICAgICAgICBjb25zdCBuZXR3b3JrID0gZ2V0RXZtTmV0d29ya0J5Q2hhaW5JZChjaGFpbklkKVxyXG4gICAgICAgIGlmICghbmV0d29yaykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFdpdE9yYWNsZTogdW5zdXBwb3J0ZWQgY2hhaW4gaWQ6ICR7Y2hhaW5JZH1gKVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IFdpdE9yYWNsZShzaWduZXIsIG5ldHdvcmspXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGVzdGltYXRlQmFzZUZlZShldm1HYXNQcmljZTogYmlnaW50KTogUHJvbWlzZTxiaWdpbnQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0RnVuY3Rpb24oXCJlc3RpbWF0ZUJhc2VGZWUodWludDI1NilcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoZXZtR2FzUHJpY2UpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGVzdGltYXRlQmFzZUZlZVdpdGhDYWxsYmFjayhldm1HYXNQcmljZTogYmlnaW50LCBldm1DYWxsYmFja0dhczogbnVtYmVyKTogUHJvbWlzZTxiaWdpbnQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0RnVuY3Rpb24oXCJlc3RpbWF0ZUJhc2VGZWVXaXRoQ2FsbGJhY2sodWludDI1Nix1aW50MjQpXCIpXHJcbiAgICAgICAgICAgIC5zdGF0aWNDYWxsKGV2bUdhc1ByaWNlLCBldm1DYWxsYmFja0dhcylcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZXN0aW1hdGVFeHRyYUZlZShldm1HYXNQcmljZTogYmlnaW50LCBldm1XaXRQcmljZTogYmlnaW50LCBxdWVyeVBhcmFtczogV2l0T3JhY2xlUXVlcnlQYXJhbXMpOiBQcm9taXNlPGJpZ2ludD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRyYWN0XHJcbiAgICAgICAgICAgIC5nZXRGdW5jdGlvbihcImVzdGltYXRlRXh0cmFGZWUodWludDI1Nix1aW50MjU2LCh1aW50MTYsdWludDE2LHVpbnQ2NClcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoXHJcbiAgICAgICAgICAgICAgICBldm1HYXNQcmljZSxcclxuICAgICAgICAgICAgICAgIGV2bVdpdFByaWNlLFxyXG4gICAgICAgICAgICAgICAgYWJpRW5jb2RlV2l0T3JhY2xlUXVlcnlQYXJhbXMocXVlcnlQYXJhbXMpLFxyXG4gICAgICAgICAgICApXHJcbiAgICB9XHJcbiAgICBcclxuICAgIHB1YmxpYyBhc3luYyBmaWx0ZXJXaXRPcmFjbGVRdWVyeUV2ZW50cyhvcHRpb25zOiB7XHJcbiAgICAgICAgZnJvbUJsb2NrOiBCbG9ja1RhZyxcclxuICAgICAgICB0b0Jsb2NrPzogQmxvY2tUYWcsXHJcbiAgICAgICAgd2hlcmU/OiB7XHJcbiAgICAgICAgICAgIGV2bVJlcXVlc3Rlcj86IHN0cmluZyxcclxuICAgICAgICAgICAgcXVlcnlSYWRIYXNoPzogV2l0bmV0Lkhhc2gsXHJcbiAgICAgICAgfVxyXG4gICAgfSk6IFByb21pc2U8QXJyYXk8e1xyXG4gICAgICAgIGV2bUJsb2NrTnVtYmVyOiBiaWdpbnQsXHJcbiAgICAgICAgZXZtUmVxdWVzdGVyOiBzdHJpbmcsXHJcbiAgICAgICAgZXZtVHJhbnNhY3Rpb25IYXNoOiBzdHJpbmcsXHJcbiAgICAgICAgcXVlcnlJZDogYmlnaW50LFxyXG4gICAgICAgIHF1ZXJ5UmFkSGFzaDogV2l0bmV0Lkhhc2gsXHJcbiAgICAgICAgcXVlcnlQYXJhbXM6IFdpdE9yYWNsZVF1ZXJ5UGFyYW1zXHJcbiAgICB9Pj4ge1xyXG4gICAgICAgIGNvbnN0IHdpdE9yYWNsZVF1ZXJ5RXZlbnQgPSB0aGlzLmNvbnRyYWN0LmZpbHRlcnNbXCJXaXRPcmFjbGVRdWVyeShhZGRyZXNzIGluZGV4ZWQsdWludDI1Nix1aW50MjU2LHVpbnQ2NCxieXRlczMyLCh1aW50MTYsdWludDE2LHVpbnQ2NCkpXCJdKG9wdGlvbnM/LndoZXJlPy5ldm1SZXF1ZXN0ZXIpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLnF1ZXJ5RmlsdGVyKHdpdE9yYWNsZVF1ZXJ5RXZlbnQsIG9wdGlvbnMuZnJvbUJsb2NrLCBvcHRpb25zPy50b0Jsb2NrKVxyXG4gICAgICAgICAgICAudGhlbihsb2dzID0+IGxvZ3MuZmlsdGVyKGxvZyA9PiBcclxuICAgICAgICAgICAgICAgICFsb2cucmVtb3ZlZFxyXG4gICAgICAgICAgICAgICAgLy8gJiYgKCFvcHRpb25zPy53aGVyZT8uZXZtUmVxdWVzdGVyIHx8IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3M/LnJlcXVlc3RlciA9PT0gb3B0aW9ucy53aGVyZS5ldm1SZXF1ZXN0ZXIpXHJcbiAgICAgICAgICAgICAgICAmJiAoIW9wdGlvbnM/LndoZXJlPy5xdWVyeVJhZEhhc2ggfHwgKGxvZyBhcyBFdmVudExvZykuYXJncz8ucmFkb25IYXNoLmluZGV4T2Yob3B0aW9ucy53aGVyZS5xdWVyeVJhZEhhc2gpID49IDApXHJcbiAgICAgICAgICAgICkpXHJcbiAgICAgICAgICAgIC50aGVuKGxvZ3MgPT4gbG9ncy5tYXAobG9nID0+ICh7XHJcbiAgICAgICAgICAgICAgICBldm1CbG9ja051bWJlcjogQmlnSW50KGxvZy5ibG9ja051bWJlciksXHJcbiAgICAgICAgICAgICAgICBldm1SZXF1ZXN0ZXI6IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3M/LmV2bVJlcXVlc3RlciBhcyBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgICBldm1UcmFuc2FjdGlvbkhhc2g6IGxvZy50cmFuc2FjdGlvbkhhc2gsXHJcbiAgICAgICAgICAgICAgICBxdWVyeUlkOiBCaWdJbnQoKGxvZyBhcyBFdmVudExvZykuYXJncy5xdWVyeUlkKSxcclxuICAgICAgICAgICAgICAgIHF1ZXJ5UmFkSGFzaDogKGxvZyBhcyBFdmVudExvZykuYXJncy5yYWRvbkhhc2ggYXMgV2l0bmV0Lkhhc2gsXHJcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczoge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpdG5lc3NlczogKGxvZyBhcyBFdmVudExvZykuYXJncy5yYWRvblBhcmFtc1sxXSBhcyBudW1iZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgdW5pdGFyeVJld2FyZDogQmlnSW50KChsb2cgYXMgRXZlbnRMb2cpLmFyZ3MucmFkb25QYXJhbXNbMl0pLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdE1heFNpemU6IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3MucmFkb25QYXJhbXNbMF0gYXMgbnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgfSBhcyBXaXRPcmFjbGVRdWVyeVBhcmFtcyxcclxuICAgICAgICAgICAgfSkpKVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBmaWx0ZXJXaXRPcmFjbGVSZXBvcnRFdmVudHMob3B0aW9uczoge1xyXG4gICAgICAgIGZyb21CbG9jazogQmxvY2tUYWcsXHJcbiAgICAgICAgdG9CbG9jaz86IEJsb2NrVGFnLFxyXG4gICAgICAgIHdoZXJlPzoge1xyXG4gICAgICAgICAgICBldm1PcmlnaW4/OiBzdHJpbmcsXHJcbiAgICAgICAgICAgIGV2bUNvbnN1bWVyPzogc3RyaW5nLFxyXG4gICAgICAgICAgICBxdWVyeVJhZEhhc2g/OiBXaXRuZXQuSGFzaFxyXG4gICAgICAgIH1cclxuICAgIH0pOiBQcm9taXNlPEFycmF5PHtcclxuICAgICAgICBldm1CbG9ja051bWJlcjogYmlnaW50LFxyXG4gICAgICAgIGV2bU9yaWdpbjogc3RyaW5nLFxyXG4gICAgICAgIGV2bUNvbnN1bWVyOiBzdHJpbmcsXHJcbiAgICAgICAgZXZtUmVwb3J0ZXI6IHN0cmluZyxcclxuICAgICAgICBldm1UcmFuc2FjdGlvbkhhc2g6IHN0cmluZyxcclxuICAgICAgICB3aXREclR4SGFzaDogV2l0bmV0Lkhhc2gsXHJcbiAgICAgICAgcXVlcnlSYWRIYXNoOiBXaXRuZXQuSGFzaCxcclxuICAgICAgICBxdWVyeVBhcmFtczogV2l0T3JhY2xlUXVlcnlQYXJhbXMsXHJcbiAgICAgICAgcmVzdWx0Q2JvckJ5dGVzOiBXaXRuZXQuSGV4U3RyaW5nLFxyXG4gICAgICAgIHJlc3VsdFRpbWVzdGFtcDogbnVtYmVyLFxyXG4gICAgfT4+IHtcclxuICAgICAgICBjb25zdCB3aXRPcmFjbGVSZXBvcnRFdmVudCA9IHRoaXMuY29udHJhY3QuZmlsdGVycy5XaXRPcmFjbGVSZXBvcnQoXHJcbiAgICAgICAgICAgIG9wdGlvbnM/LndoZXJlPy5ldm1PcmlnaW4sIFxyXG4gICAgICAgICAgICBvcHRpb25zPy53aGVyZT8uZXZtQ29uc3VtZXIsXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAucXVlcnlGaWx0ZXIod2l0T3JhY2xlUmVwb3J0RXZlbnQsIG9wdGlvbnMuZnJvbUJsb2NrLCBvcHRpb25zPy50b0Jsb2NrKVxyXG4gICAgICAgICAgICAudGhlbihsb2dzID0+IGxvZ3MuZmlsdGVyKGxvZyA9PiBcclxuICAgICAgICAgICAgICAgICFsb2cucmVtb3ZlZFxyXG4gICAgICAgICAgICAgICAgJiYgKCFvcHRpb25zPy53aGVyZT8ucXVlcnlSYWRIYXNoIHx8IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3M/LnF1ZXJ5UmFkSGFzaC5pbmRleE9mKG9wdGlvbnMud2hlcmUucXVlcnlSYWRIYXNoKSA+PSAwKVxyXG4gICAgICAgICAgICApKVxyXG4gICAgICAgICAgICAudGhlbihsb2dzID0+IGxvZ3MubWFwKGxvZyA9PiAoe1xyXG4gICAgICAgICAgICAgICAgZXZtQmxvY2tOdW1iZXI6IEJpZ0ludChsb2cuYmxvY2tOdW1iZXIpLFxyXG4gICAgICAgICAgICAgICAgZXZtT3JpZ2luOiAobG9nIGFzIEV2ZW50TG9nKS5hcmdzLmV2bU9yaWdpbixcclxuICAgICAgICAgICAgICAgIGV2bUNvbnN1bWVyOiAobG9nIGFzIEV2ZW50TG9nKS5hcmdzLmV2bUNvbnN1bWVyLFxyXG4gICAgICAgICAgICAgICAgZXZtUmVwb3J0ZXI6IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3MuZXZtUmVwb3J0ZXIsXHJcbiAgICAgICAgICAgICAgICBldm1UcmFuc2FjdGlvbkhhc2g6IGxvZy50cmFuc2FjdGlvbkhhc2gsXHJcbiAgICAgICAgICAgICAgICB3aXREclR4SGFzaDogKGxvZyBhcyBFdmVudExvZykuYXJncy53aXREclR4SGFzaCxcclxuICAgICAgICAgICAgICAgIHF1ZXJ5UmFkSGFzaDogKGxvZyBhcyBFdmVudExvZykuYXJncy5xdWVyeVJhZEhhc2gsXHJcbiAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczoge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpdG5lc3NlczogKGxvZyBhcyBFdmVudExvZykuYXJncy5xdWVyeVBhcmFtc1sxXSBhcyBudW1iZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgdW5pdGFyeVJld2FyZDogQmlnSW50KChsb2cgYXMgRXZlbnRMb2cpLmFyZ3MucXVlcnlQYXJhbXNbMl0pLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdE1heFNpemU6IChsb2cgYXMgRXZlbnRMb2cpLmFyZ3MucXVlcnlQYXJhbXNbMF0gYXMgbnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHJlc3VsdENib3JCeXRlczogKGxvZyBhcyBFdmVudExvZykuYXJncy5yZXN1bHRDYm9yQnl0ZXMsXHJcbiAgICAgICAgICAgICAgICByZXN1bHRUaW1lc3RhbXA6IE51bWJlcigobG9nIGFzIEV2ZW50TG9nKS5hcmdzLnJlc3VsdFRpbWVzdGFtcCksXHJcbiAgICAgICAgICAgIH0pKSlcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0RXZtQ2hhaW5JZCgpOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb3ZpZGVyLmdldE5ldHdvcmsoKS50aGVuKG5ldHdvcmsgPT4gTnVtYmVyKG5ldHdvcmsuY2hhaW5JZCkpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldEV2bUNoYW5uZWwoKTogUHJvbWlzZTxXaXRuZXQuSGV4U3RyaW5nPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiY2hhbm5lbCgpXCIpXHJcbiAgICAgICAgICAgIC5zdGF0aWNDYWxsKClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0TmV4dFF1ZXJ5SWQoKTogUHJvbWlzZTxiaWdpbnQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0RnVuY3Rpb24oXCJnZXROZXh0UXVlcnlJZCgpXCIpXHJcbiAgICAgICAgICAgIC5zdGF0aWNDYWxsKClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0UXVlcnkocXVlcnlJZDogYmlnaW50KTogUHJvbWlzZTxXaXRPcmFjbGVRdWVyeT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRyYWN0XHJcbiAgICAgICAgICAgIC5nZXRRdWVyeVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbChxdWVyeUlkKVxyXG4gICAgICAgICAgICAudGhlbihyZXN1bHQgPT4gKHtcclxuICAgICAgICAgICAgICAgICAgICBjaGVja3BvaW50OiBCaWdJbnQocmVzdWx0WzVdKSxcclxuICAgICAgICAgICAgICAgICAgICBoYXNoOiByZXN1bHRbM10sXHJcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdE1heFNpemU6IHJlc3VsdFsyXVswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdW5pdGFyeVJld2FyZDogcmVzdWx0WzJdWzJdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aXRuZXNzZXM6IHJlc3VsdFsyXVsxXSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIHJlcXVlc3Q6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tHYXM6IE51bWJlcihyZXN1bHRbMF1bMV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByYWRvbkhhc2g6IHJlc3VsdFswXVszXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdGVyOiByZXN1bHRbMF1bMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwdXRlcjogcmVzdWx0WzFdWzRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRlcjogcmVzdWx0WzFdWzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRUaW1lc3RhbXA6IE51bWJlcihyZXN1bHRbMV1bMV0udG9TdHJpbmcoKSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdERyVHhIYXNoOiByZXN1bHRbMV1bMl0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdENib3JCeXRlczogcmVzdWx0WzFdWzNdLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0UXVlcnlSZXNwb25zZShxdWVyeUlkOiBiaWdpbnQpOiBQcm9taXNlPFdpdE9yYWNsZVF1ZXJ5UmVzcG9uc2U+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0UXVlcnlSZXNwb25zZVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbChxdWVyeUlkKVxyXG4gICAgICAgICAgICAudGhlbihyZXN1bHQgPT4gKHtcclxuICAgICAgICAgICAgICAgIGRpc3B1dGVyOiByZXN1bHRbNF0sXHJcbiAgICAgICAgICAgICAgICByZXBvcnRlcjogcmVzdWx0WzBdLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0VGltZXN0YW1wOiBOdW1iZXIocmVzdWx0WzFdLnRvU3RyaW5nKCkpLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0RHJUeEhhc2g6IHJlc3VsdFsyXSxcclxuICAgICAgICAgICAgICAgIHJlc3VsdENib3JCeXRlczogcmVzdWx0WzNdLFxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFF1ZXJ5UmVzdWx0U3RhdHVzRGVzY3JpcHRpb24ocXVlcnlJZDogYmlnaW50KTogUHJvbWlzZTxzdHJpbmc+IHtcclxuICAgICAgICBsZXQgcmVhc29uIFxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHRyeSB7IHJlYXNvbiA9IGF3YWl0IHRoaXMuY29udHJhY3QuZ2V0UXVlcnlSZXN1bHRTdGF0dXNEZXNjcmlwdGlvbi5zdGF0aWNDYWxsKHF1ZXJ5SWQpXHJcbiAgICAgICAgICAgIH0gY2F0Y2ggeyBcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxlZ2FjeSA9IG5ldyBDb250cmFjdCh0aGlzLmFkZHJlc3MsIFtcclxuICAgICAgICAgICAgICAgICAgICBcImZ1bmN0aW9uIGdldFF1ZXJ5UmVzdWx0RXJyb3IodWludDI1NikgcHVibGljIHZpZXcgcmV0dXJucyAoKHVpbnQ4LHN0cmluZykpXCIsXHJcbiAgICAgICAgICAgICAgICBdLCB0aGlzLnNpZ25lcilcclxuICAgICAgICAgICAgICAgIHJlYXNvbiA9IGF3YWl0IGxlZ2FjeS5nZXRRdWVyeVJlc3VsdEVycm9yLnN0YXRpY0NhbGwocXVlcnlJZCkudGhlbihyZXN1bHQgPT4gcmVzdWx0WzFdKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgIHJlYXNvbiA9IFwiKHVucGFyc2FibGUgZXJyb3IpXCJcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlYXNvblxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBnZXRRdWVyeVN0YXR1c2VzKHF1ZXJ5SWRzOiBiaWdpbnRbXSk6IFByb21pc2U8QXJyYXk8V2l0T3JhY2xlUXVlcnlTdGF0dXM+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldFF1ZXJ5U3RhdHVzQmF0Y2hcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwocXVlcnlJZHMpXHJcbiAgICAgICAgICAgIC50aGVuKChzdGF0dXNlczogQXJyYXk8YmlnaW50PikgPT4gc3RhdHVzZXMubWFwKHZhbHVlID0+IGFiaURlY29kZVF1ZXJ5U3RhdHVzKHZhbHVlKSkpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFdpdE9yYWNsZUNvbnN1bWVyQXQodGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdE9yYWNsZUNvbnN1bWVyPiB7XHJcbiAgICAgICAgcmV0dXJuIFdpdE9yYWNsZUNvbnN1bWVyLmF0KHRoaXMsIHRhcmdldClcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyYXBwZXIgY2xhc3MgZm9yIHRoZSBXaXQvT3JhY2xlIFJhZG9uIFJlZ2lzdHJ5IGNvcmUgY29udHJhY3QgYXMgZGVwbG95ZWQgaW4gc29tZSBzdXBwb3J0ZWQgRVZNIG5ldHdvcmsuXHJcbiAgICAgKiBJdCBhbGxvd3MgZm9ybWFsIHZlcmlmaWNhdGlvbiBvZiBSYWRvbiBSZXF1ZXN0cyBhbmQgV2l0bmV0LWNvbXBsaWFudCBkYXRhIHNvdXJjZXMgaW50byBzdWNoIG5ldHdvcmssIFxyXG4gICAgICogYXMgdG8gYmUgc2VjdXJlbHkgcmVmZXJyZWQgb24gYm90aCBXaXQvT3JhY2xlIHF1ZXJpZXMgcHVsbGVkIGZyb20gd2l0aGluIHNtYXJ0IGNvbnRyYWN0cywgXHJcbiAgICAgKiBvciBXaXQvT3JhY2xlIHF1ZXJ5IHJlc3VsdHMgcHVzaGVkIGludG8gc21hcnQgY29udHJhY3RzIGZyb20gb2ZmY2hhaW4gd29ya2Zsb3dzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0V2l0T3JhY2xlUmFkb25SZWdpc3RyeSgpOiBQcm9taXNlPFdpdE9yYWNsZVJhZG9uUmVnaXN0cnk+IHtcclxuICAgICAgICByZXR1cm4gbmV3IFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkodGhpcy5zaWduZXIsIHRoaXMubmV0d29yaylcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyYXBwZXIgY2xhc3MgZm9yIHRoZSBXaXQvT3JhY2xlIFJlcXVlc3QgRmFjdG9yeSBjb3JlIGNvbnRyYWN0IGFzIGRlcGxveWVkIGluIHNvbWUgc3VwcG9ydGVkIEVWTSBuZXR3b3JrLlxyXG4gICAgICogSXQgYWxsb3dzIGNvbnN0cnVjdGlvbiBvZiBgV2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGVgIG1pbmltYWwtcHJveHkgY29udHJhY3RzIG91dCBvZiBvbmUgb3JlIG1vcmVcclxuICAgICAqIHBhcmFtZXRlcml6ZWQgUmFkb24gUmV0aWV2YWxzIChXaXRuZXQtY29tcGxpYW50IGRhdGEgc291cmNlcykuIFRlbXBsYXRlIGFkZHJlc3NlcyBhcmUgY291bnRlci1mYWN0dWFsIHRvXHJcbiAgICAgKiB0aGUgc2V0IG9mIGRhdGEgc291cmNlcyB0aGV5IGFyZSBidWlsdCBvbi4gXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBnZXRXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5KCk6IFByb21pc2U8V2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeT4ge1xyXG4gICAgICAgIHJldHVybiBXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5LmRlcGxveWVkKHRoaXMsIGF3YWl0IHRoaXMuZ2V0V2l0T3JhY2xlUmFkb25SZWdpc3RyeSgpKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JhcHBlciBjbGFzcyBmb3IgV2l0L09yYWNsZSBSYWRvbiBUZW1wbGF0ZSBhcnRpZmFjdHMgYXMgZGVwbG95ZWQgaW4gc29tZSBzdXBwb3J0ZWQgRVZNIG5ldHdvcmsuXHJcbiAgICAgKiBgSVdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlYCBjb250cmFjdHMgZW5hYmxlIHNtYXJ0IGNvbnRyYWN0cyB0byBmb3JtYWxseSB2ZXJpZnkgUmFkb24gUmVxdWVzdHMgXHJcbiAgICAgKiBidWlsdCBvdXQgb3V0IG9mIGEgc2V0IG9mIHBhcmFtZXRlcml6ZWQgV2l0bmV0LWNvbXBsaWFudCBkYXRhIHNvdXJjZXMsIG9uIHRoZSBmbHkuIFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0V2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGVBdCh0YXJnZXQ6IHN0cmluZyk6IFByb21pc2U8V2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGU+IHtcclxuICAgICAgICByZXR1cm4gV2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGUuYXQodGhpcywgdGFyZ2V0KVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JhcHBlciBjbGFzcyBmb3IgV2l0L09yYWNsZSBSYWRvbiBNb2RhbCBhcnRpZmFjdHMgYXMgZGVwbG95ZWQgaW4gc29tZSBzdXBwb3J0ZWQgRVZNIG5ldHdvcmsuXHJcbiAgICAgKiBgSVdpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsYCBjb250cmFjdHMgZW5hYmxlIHNtYXJ0IGNvbnRyYWN0cyB0byBmb3JtYWxseSB2ZXJpZnkgUmFkb24gUmVxdWVzdHMgXHJcbiAgICAgKiBidWlsdCBvdXQgb3V0IG9mIGEgc2luZ2xlIFJhZG9uIFJldHJpZXZhbCBhbmQgbXVsdGlwbGUgZGF0YSBwcm92aWRlcnMsIGFsbCBvZiB0aGVtIGV4cGVjdGVkIHRvIFxyXG4gICAgICogcHJvdmlkZWQgZXhhY3RseSB0aGUgc2FtZSBkYXRhLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0V2l0T3JhY2xlUmFkb25SZXF1ZXN0TW9kYWxBdCh0YXJnZXQ6IHN0cmluZyk6IFByb21pc2U8V2l0T3JhY2xlUmFkb25SZXF1ZXN0TW9kYWw+IHtcclxuICAgICAgICByZXR1cm4gV2l0T3JhY2xlUmFkb25SZXF1ZXN0TW9kYWwuYXJndW1lbnRzKHRoaXMsIHRhcmdldClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0V2l0UHJpY2VGZWVkc0F0KHRhcmdldDogc3RyaW5nKTogUHJvbWlzZTxXaXRQcmljZUZlZWRzPiB7XHJcbiAgICAgICAgcmV0dXJuIFdpdFByaWNlRmVlZHMuYXQodGhpcywgdGFyZ2V0KVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBnZXRXaXRQcmljZUZlZWRzTGVnYWN5QXQodGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdFByaWNlRmVlZHNMZWdhY3k+IHtcclxuICAgICAgICByZXR1cm4gV2l0UHJpY2VGZWVkc0xlZ2FjeS5hdCh0aGlzLCB0YXJnZXQpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFdpdFJhbmRvbW5lc3NBdCh0YXJnZXQ6IHN0cmluZyk6IFByb21pc2U8V2l0UmFuZG9tbmVzcz4ge1xyXG4gICAgICAgIHJldHVybiBXaXRSYW5kb21uZXNzLmF0KHRoaXMsIHRhcmdldClcclxuICAgIH1cclxufVxyXG5cclxuXHJcblxyXG4iXX0=