UNPKG

@witnet/ethers

Version:

Wit/Oracle Ethers Framework package for EVM-compatible projects

250 lines 44.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WitOracleRadonRequestTemplate = exports.WitOracleRadonRequestModal = exports.WitOracleRadonRequestFactory = void 0; const sdk_1 = require("@witnet/sdk"); const utils_1 = require("../utils"); const WitAppliance_1 = require("./WitAppliance"); class WitOracleRadonRequestFactory extends WitAppliance_1.WitAppliance { constructor(witOracle, registry, at) { super(witOracle, "WitOracleRadonRequestFactory", at); this.registry = registry; } static async deployed(witOracle, registry) { const deployer = new WitOracleRadonRequestFactory(witOracle, registry); const witOracleRegistryAddress = await witOracle.contract.registry.staticCall(); if (registry.address !== witOracleRegistryAddress) { throw new Error(`${this.constructor.name} at ${deployer.address}: uncompliant WitOracleRadonRegistry at ${registry.address})`); } return deployer; } async deployRadonRequestTemplate(template, options) { const hashes = []; for (const index in template.sources) { const retrieval = template.sources[index]; const hash = `0x${await this.registry.determineRadonRetrievalHash(retrieval)}`; await this.registry.verifyRadonRetrieval(retrieval, options); hashes.push(hash); } const aggregator = (0, utils_1.abiEncodeRadonAsset)(template.sourcesReducer); const tally = (0, utils_1.abiEncodeRadonAsset)(template.witnessReducer); const target = await this.contract .getFunction("buildRadonRequestTemplate(bytes32[],(uint8,(uint8,bytes)[]),(uint8,(uint8,bytes)[]))") .staticCall(hashes, aggregator, tally); if (options?.onDeployRadonRequestTemplate) options.onDeployRadonRequestTemplate(target); await this.contract .getFunction("buildRadonRequestTemplate(bytes32[],(uint8,(uint8,bytes)[]),(uint8,(uint8,bytes)[]))") .send(hashes, aggregator, tally) .then(async (tx) => { const receipt = await tx.wait(options?.confirmations || 1); if (options?.onDeployRadonRequestTemplateReceipt) { options.onDeployRadonRequestTemplateReceipt(receipt); } }); return await WitOracleRadonRequestTemplate.at(this.witOracle, target); } async deployRadonRequestModal(modal, options) { const retrieval = [ modal.sources[0].method, modal.sources[0].body || "", modal.sources[0]?.headers ? Object.entries(modal.sources[0].headers) : [], modal.sources[0].script?.toBytecode() || "0x", ]; const tally = (0, utils_1.abiEncodeRadonAsset)(modal.witnessReducer); const target = await this.contract .buildRadonRequestModal //getFunction("buildRadonRequestModal((uint8,string,string[2][],bytes),(uint8,(uint8,bytes)[]))") .staticCall(retrieval, tally); if (options?.onDeployRadonRequestModal) options.onDeployRadonRequestModal(target); await this.contract .buildRadonRequestModal // .getFunction("buildRadonRequestModal((uint8,string,string[2][],bytes),(uint8,(uint8,bytes)[]))") .send(retrieval, tally) .then(async (tx) => { const receipt = await tx.wait(options?.confirmations || 1); if (options?.onDeployRadonRequestModalReceipt) { options.onDeployRadonRequestModalReceipt(receipt); } }); return await WitOracleRadonRequestModal.at(this.witOracle, target); } async verifyRadonRequest(request, _options) { // TODO: // return request.radHash; } } exports.WitOracleRadonRequestFactory = WitOracleRadonRequestFactory; class WitOracleRadonRequestModal extends WitAppliance_1.WitAppliance { constructor(witOracle, at) { super(witOracle, "WitOracleRadonRequestModal", at); } static async at(witOracle, target) { const template = new WitOracleRadonRequestModal(witOracle, target); const templateWitOracleAddr = await template.contract.witOracle.staticCall(); if (templateWitOracleAddr !== witOracle.address) { throw new Error(`${this.constructor.name} at ${target}: mismatching Wit/Oracle address (${templateWitOracleAddr})`); } return template; } async getDataResultType() { return this.contract .getFunction("getDataResultType()") .staticCall() .then((result) => { switch (Number(result)) { case 1: return "array"; case 2: return "boolean"; case 3: return "bytes"; case 4: return "integer"; case 5: return "float"; case 6: return "map"; case 7: return "string"; default: return "any"; } }); } async getDataSourcesArgsCount() { return this.contract .getFunction("getDataSourcesArgsCount()") .staticCall() .then((argsCount) => Number(argsCount)); } async getRadonModalRetrieval() { return this.contract .getFunction("getRadonModalRetrieval()") .staticCall() .then((result) => { return new sdk_1.Witnet.Radon.RadonRetrieval({ method: result[1], url: result[3], body: result[4], headers: Object.fromEntries(result[5]), script: (0, utils_1.parseRadonScript)(result[6]), }); }); } async verifyRadonRequest(dataProviders, commonRetrievalArgs, options) { const argsCount = await this.getDataSourcesArgsCount(); if (argsCount != 1 + (commonRetrievalArgs?.length || 0)) { throw TypeError(`${this.constructor.name}@${this.address}: unmatching args count != ${argsCount - 1}.`); } const method = this.contract.getFunction("verifyRadonRequest(string[],string[])"); const radHash = (await method.staticCall(commonRetrievalArgs || [], dataProviders)).slice(2); try { await (await this.witOracle.getWitOracleRadonRegistry()).lookupRadonRequestBytecode(radHash); } catch { if (options?.onVerifyRadonRequest) options.onVerifyRadonRequest(radHash); await method .send(commonRetrievalArgs || [], dataProviders) .then(tx => tx.wait(options?.confirmations || 1)) .then(receipt => { if (options?.onVerifyRadonRequestReceipt) { options.onVerifyRadonRequestReceipt(receipt); } return radHash; }); } return radHash; } } exports.WitOracleRadonRequestModal = WitOracleRadonRequestModal; class WitOracleRadonRequestTemplate extends WitAppliance_1.WitAppliance { constructor(witOracle, at) { super(witOracle, "WitOracleRadonRequestTemplate", at); } static async at(witOracle, target) { const template = new WitOracleRadonRequestTemplate(witOracle, target); const templateWitOracleAddr = await template.contract.witOracle.staticCall(); if (templateWitOracleAddr !== witOracle.address) { throw new Error(`${this.constructor.name} at ${target}: mismatching Wit/Oracle address (${templateWitOracleAddr})`); } return template; } async getDataResultType() { return this.contract .getFunction("getDataResultType()") .staticCall() .then((result) => { switch (Number(result)) { case 1: return "array"; case 2: return "boolean"; case 3: return "bytes"; case 4: return "integer"; case 5: return "float"; case 6: return "map"; case 7: return "string"; default: return "any"; } }); } async getDataSources() { return this.contract .getFunction("getDataSources()") .staticCall() .then((results) => { return results.map(result => new sdk_1.Witnet.Radon.RadonRetrieval({ method: result[1], url: result[3], body: result[4], headers: Object.fromEntries(result[5]), script: (0, utils_1.parseRadonScript)(result[6]), })); }); } async getDataSourcesArgsCount() { return this.contract .getFunction("getDataSourcesArgsCount()") .staticCall() .then((dims) => dims.map(dim => Number(dim))); } async verifyRadonRequest(args, options) { const argsCount = await this.getDataSourcesArgsCount(); let encodedArgs = []; if (typeof args === 'string') { if (argsCount.length === 1 && argsCount[0] === 1) { encodedArgs = [[args]]; } } else if (Array.isArray(args)) { if (Array.isArray(args[0])) { if (argsCount.length === args.length && !args.find((subargs, index) => subargs.length !== argsCount[index])) { encodedArgs = args; } } else if (args.length === argsCount[0] && !args.find(arg => typeof arg !== 'string')) { encodedArgs = [args]; } } if (encodedArgs.length === 0) { throw TypeError(`${this.constructor.name}@${this.address}: unmatching args count != [${argsCount}, ].`); } const method = this.contract.getFunction("verifyRadonRequest(string[][])"); const radHash = (await method.staticCall(encodedArgs)).slice(2); try { await (await this.witOracle.getWitOracleRadonRegistry()).lookupRadonRequestBytecode(radHash); } catch { if (options?.onVerifyRadonRequest) options.onVerifyRadonRequest(radHash); await method .send(encodedArgs) .then(tx => tx.wait(options?.confirmations || 1)) .then(receipt => { if (options?.onVerifyRadonRequestReceipt) { options.onVerifyRadonRequestReceipt(receipt); } return radHash; }); } return radHash; } } exports.WitOracleRadonRequestTemplate = WitOracleRadonRequestTemplate; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvd3JhcHBlcnMvV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxQ0FBb0M7QUFDcEMsb0NBQWdFO0FBRWhFLGlEQUE2QztBQUk3QyxNQUFhLDRCQUE2QixTQUFRLDJCQUFZO0lBSTFELFlBQXVCLFNBQW9CLEVBQUUsUUFBZ0MsRUFBRSxFQUFXO1FBQ3RGLEtBQUssQ0FBQyxTQUFTLEVBQUUsOEJBQThCLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDcEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDNUIsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFNBQW9CLEVBQUUsUUFBZ0M7UUFDeEUsTUFBTSxRQUFRLEdBQUcsSUFBSSw0QkFBNEIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDdEUsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQy9FLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksT0FBTyxRQUFRLENBQUMsT0FBTywyQ0FBMkMsUUFBUSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUE7UUFDbEksQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFBO0lBQ25CLENBQUM7SUFFTSxLQUFLLENBQUMsMEJBQTBCLENBQ25DLFFBQW9DLEVBQ3BDLE9BY0M7UUFHRCxNQUFNLE1BQU0sR0FBa0IsRUFBRSxDQUFBO1FBQ2hDLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25D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aUJBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDWixJQUFJLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxDQUFDO29CQUN2QyxPQUFPLENBQUMsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUE7Z0JBQ2hELENBQUM7Z0JBQ0QsT0FBTyxPQUFPLENBQUE7WUFDbEIsQ0FBQyxDQUFDLENBQUE7UUFDVixDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUE7SUFDbEIsQ0FBQztDQUNKO0FBMUdELHNFQTBHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0LCBSZXN1bHQgfSBmcm9tIFwiZXRoZXJzXCJcclxuaW1wb3J0IHsgV2l0bmV0IH0gZnJvbSBcIkB3aXRuZXQvc2RrXCJcclxuaW1wb3J0IHsgYWJpRW5jb2RlUmFkb25Bc3NldCwgcGFyc2VSYWRvblNjcmlwdCB9IGZyb20gXCIuLi91dGlsc1wiXHJcbmltcG9ydCB7IFdpdE9yYWNsZVJlc3VsdERhdGFUeXBlcyB9IGZyb20gXCIuLi90eXBlc1wiXHJcbmltcG9ydCB7IFdpdEFwcGxpYW5jZSB9IGZyb20gXCIuL1dpdEFwcGxpYW5jZVwiXHJcbmltcG9ydCB7IFdpdE9yYWNsZSB9IGZyb20gXCIuL1dpdE9yYWNsZVwiXHJcbmltcG9ydCB7IFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkgfSBmcm9tIFwiLi9XaXRPcmFjbGVSYWRvblJlZ2lzdHJ5XCJcclxuXHJcbmV4cG9ydCBjbGFzcyBXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5IGV4dGVuZHMgV2l0QXBwbGlhbmNlIHsgIFxyXG5cclxuICAgIHB1YmxpYyByZWFkb25seSByZWdpc3RyeTogV2l0T3JhY2xlUmFkb25SZWdpc3RyeVxyXG4gICAgXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCByZWdpc3RyeTogV2l0T3JhY2xlUmFkb25SZWdpc3RyeSwgYXQ/OiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcih3aXRPcmFjbGUsIFwiV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeVwiLCBhdClcclxuICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gcmVnaXN0cnlcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgYXN5bmMgZGVwbG95ZWQod2l0T3JhY2xlOiBXaXRPcmFjbGUsIHJlZ2lzdHJ5OiBXaXRPcmFjbGVSYWRvblJlZ2lzdHJ5KTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5PiB7XHJcbiAgICAgICAgY29uc3QgZGVwbG95ZXIgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeSh3aXRPcmFjbGUsIHJlZ2lzdHJ5KVxyXG4gICAgICAgIGNvbnN0IHdpdE9yYWNsZVJlZ2lzdHJ5QWRkcmVzcyA9IGF3YWl0IHdpdE9yYWNsZS5jb250cmFjdC5yZWdpc3RyeS5zdGF0aWNDYWxsKClcclxuICAgICAgICBpZiAocmVnaXN0cnkuYWRkcmVzcyAhPT0gd2l0T3JhY2xlUmVnaXN0cnlBZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7ZGVwbG95ZXIuYWRkcmVzc306IHVuY29tcGxpYW50IFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkgYXQgJHtyZWdpc3RyeS5hZGRyZXNzfSlgKVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZGVwbG95ZXJcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGUoXHJcbiAgICAgICAgdGVtcGxhdGU6IFdpdG5ldC5SYWRvbi5SYWRvblRlbXBsYXRlLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGU/OiAoYWRkcmVzczogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGVSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RUZW1wbGF0ZT4ge1xyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnN0IGhhc2hlczogQXJyYXk8c3RyaW5nPiA9IFtdXHJcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBpbiB0ZW1wbGF0ZS5zb3VyY2VzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldHJpZXZhbCA9IHRlbXBsYXRlLnNvdXJjZXNbaW5kZXhdXHJcbiAgICAgICAgICAgIGNvbnN0IGhhc2ggPSBgMHgke2F3YWl0IHRoaXMucmVnaXN0cnkuZGV0ZXJtaW5lUmFkb25SZXRyaWV2YWxIYXNoKHJldHJpZXZhbCl9YFxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdHJ5LnZlcmlmeVJhZG9uUmV0cmlldmFsKHJldHJpZXZhbCwgb3B0aW9ucylcclxuICAgICAgICAgICAgaGFzaGVzLnB1c2goaGFzaClcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgYWdncmVnYXRvciA9IGFiaUVuY29kZVJhZG9uQXNzZXQodGVtcGxhdGUuc291cmNlc1JlZHVjZXIpXHJcbiAgICAgICAgY29uc3QgdGFsbHkgPSBhYmlFbmNvZGVSYWRvbkFzc2V0KHRlbXBsYXRlLndpdG5lc3NSZWR1Y2VyKVxyXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGF3YWl0IHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RUZW1wbGF0ZShieXRlczMyW10sKHVpbnQ4LCh1aW50OCxieXRlcylbXSksKHVpbnQ4LCh1aW50OCxieXRlcylbXSkpXCIpXHJcbiAgICAgICAgICAgIC5zdGF0aWNDYWxsKGhhc2hlcywgYWdncmVnYXRvciwgdGFsbHkpXHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKG9wdGlvbnM/Lm9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGUpIG9wdGlvbnMub25EZXBsb3lSYWRvblJlcXVlc3RUZW1wbGF0ZSh0YXJnZXQpO1xyXG4gICAgICAgIGF3YWl0IHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RUZW1wbGF0ZShieXRlczMyW10sKHVpbnQ4LCh1aW50OCxieXRlcylbXSksKHVpbnQ4LCh1aW50OCxieXRlcylbXSkpXCIpXHJcbiAgICAgICAgICAgIC5zZW5kKGhhc2hlcywgYWdncmVnYXRvciwgdGFsbHkpXHJcbiAgICAgICAgICAgIC50aGVuKGFzeW5jICh0eCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVjZWlwdCA9IGF3YWl0IHR4LndhaXQob3B0aW9ucz8uY29uZmlybWF0aW9ucyB8fCAxKVxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGVSZWNlaXB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5vbkRlcGxveVJhZG9uUmVxdWVzdFRlbXBsYXRlUmVjZWlwdChyZWNlaXB0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlLmF0KFxyXG4gICAgICAgICAgICB0aGlzLndpdE9yYWNsZSwgXHJcbiAgICAgICAgICAgIHRhcmdldFxyXG4gICAgICAgIClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZGVwbG95UmFkb25SZXF1ZXN0TW9kYWwoXHJcbiAgICAgICAgbW9kYWw6IFdpdG5ldC5SYWRvbi5SYWRvbk1vZGFsLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0TW9kYWw/OiAoYWRkcmVzczogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0TW9kYWxSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RNb2RhbD4ge1xyXG5cclxuICAgICAgICBjb25zdCByZXRyaWV2YWwgPSBbXHJcbiAgICAgICAgICAgIG1vZGFsLnNvdXJjZXNbMF0ubWV0aG9kLFxyXG4gICAgICAgICAgICAgICAgbW9kYWwuc291cmNlc1swXS5ib2R5IHx8IFwiXCIsXHJcbiAgICAgICAgICAgICAgICBtb2RhbC5zb3VyY2VzWzBdPy5oZWFkZXJzID8gT2JqZWN0LmVudHJpZXMobW9kYWwuc291cmNlc1swXS5oZWFkZXJzKSA6IFtdLFxyXG4gICAgICAgICAgICAgICAgbW9kYWwuc291cmNlc1swXS5zY3JpcHQ/LnRvQnl0ZWNvZGUoKSB8fCBcIjB4XCIsXHJcbiAgICAgICAgXTtcclxuICAgICAgICBjb25zdCB0YWxseSA9IGFiaUVuY29kZVJhZG9uQXNzZXQobW9kYWwud2l0bmVzc1JlZHVjZXIpXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuYnVpbGRSYWRvblJlcXVlc3RNb2RhbCAvL2dldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RNb2RhbCgodWludDgsc3RyaW5nLHN0cmluZ1syXVtdLGJ5dGVzKSwodWludDgsKHVpbnQ4LGJ5dGVzKVtdKSlcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwocmV0cmlldmFsLCB0YWxseSlcclxuICAgICAgICBcclxuICAgICAgICBpZiAob3B0aW9ucz8ub25EZXBsb3lSYWRvblJlcXVlc3RNb2RhbCkgb3B0aW9ucy5vbkRlcGxveVJhZG9uUmVxdWVzdE1vZGFsKHRhcmdldCk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuYnVpbGRSYWRvblJlcXVlc3RNb2RhbFxyXG4gICAgICAgICAgICAvLyAuZ2V0RnVuY3Rpb24oXCJidWlsZFJhZG9uUmVxdWVzdE1vZGFsKCh1aW50OCxzdHJpbmcsc3RyaW5nWzJdW10sYnl0ZXMpLCh1aW50OCwodWludDgsYnl0ZXMpW10pKVwiKVxyXG4gICAgICAgICAgICAuc2VuZChyZXRyaWV2YWwsIHRhbGx5KVxyXG4gICAgICAgICAgICAudGhlbihhc3luYyAodHgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlY2VpcHQgPSBhd2FpdCB0eC53YWl0KG9wdGlvbnM/LmNvbmZpcm1hdGlvbnMgfHwgMSlcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zPy5vbkRlcGxveVJhZG9uUmVxdWVzdE1vZGFsUmVjZWlwdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25EZXBsb3lSYWRvblJlcXVlc3RNb2RhbFJlY2VpcHQocmVjZWlwdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBhd2FpdCBXaXRPcmFjbGVSYWRvblJlcXVlc3RNb2RhbC5hdChcclxuICAgICAgICAgICAgdGhpcy53aXRPcmFjbGUsIFxyXG4gICAgICAgICAgICB0YXJnZXRcclxuICAgICAgICApXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHZlcmlmeVJhZG9uUmVxdWVzdChcclxuICAgICAgICByZXF1ZXN0OiBXaXRuZXQuUmFkb24uUmFkb25SZXF1ZXN0LFxyXG4gICAgICAgIF9vcHRpb25zPzoge1xyXG4gICAgICAgICAgICBjb25maXJtYXRpb25zPzogbnVtYmVyLFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdD86IChhZGRyZXNzOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9XHJcbiAgICApOiBQcm9taXNlPFdpdG5ldC5IYXNoPiB7XHJcbiAgICAgICAgLy8gVE9ETzpcclxuICAgICAgICAvL1xyXG4gICAgICAgIHJldHVybiByZXF1ZXN0LnJhZEhhc2hcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFdpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsIGV4dGVuZHMgV2l0QXBwbGlhbmNlIHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCBhdDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIod2l0T3JhY2xlLCBcIldpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsXCIsIGF0KVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhc3luYyBhdCh3aXRPcmFjbGU6IFdpdE9yYWNsZSwgdGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsPiB7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0TW9kYWwod2l0T3JhY2xlLCB0YXJnZXQpXHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGVXaXRPcmFjbGVBZGRyID0gYXdhaXQgdGVtcGxhdGUuY29udHJhY3Qud2l0T3JhY2xlLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgIGlmICh0ZW1wbGF0ZVdpdE9yYWNsZUFkZHIgIT09IHdpdE9yYWNsZS5hZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7dGFyZ2V0fTogbWlzbWF0Y2hpbmcgV2l0L09yYWNsZSBhZGRyZXNzICgke3RlbXBsYXRlV2l0T3JhY2xlQWRkcn0pYClcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFSZXN1bHRUeXBlKCk6IFByb21pc2U8V2l0T3JhY2xlUmVzdWx0RGF0YVR5cGVzPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVJlc3VsdFR5cGUoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChyZXN1bHQ6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChOdW1iZXIocmVzdWx0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFwiYXJyYXlcIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBcImJvb2xlYW5cIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBcImJ5dGVzXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gXCJpbnRlZ2VyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiByZXR1cm4gXCJmbG9hdFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFwibWFwXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gXCJzdHJpbmdcIjtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYW55XCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFTb3VyY2VzQXJnc0NvdW50KCk6IFByb21pc2U8bnVtYmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChhcmdzQ291bnQ6IGJpZ2ludCkgPT4gTnVtYmVyKGFyZ3NDb3VudCkpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFJhZG9uTW9kYWxSZXRyaWV2YWwoKTogUHJvbWlzZTxXaXRuZXQuUmFkb24uUmFkb25SZXRyaWV2YWw+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0RnVuY3Rpb24oXCJnZXRSYWRvbk1vZGFsUmV0cmlldmFsKClcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgICAgICAudGhlbigocmVzdWx0OiBSZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsKHtcclxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlc3VsdFsxXSxcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IHJlc3VsdFszXSxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiByZXN1bHRbNF0sXHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKHJlc3VsdFs1XSksXHJcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0OiBwYXJzZVJhZG9uU2NyaXB0KHJlc3VsdFs2XSksXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB2ZXJpZnlSYWRvblJlcXVlc3QoXHJcbiAgICAgICAgZGF0YVByb3ZpZGVyczogc3RyaW5nW10sXHJcbiAgICAgICAgY29tbW9uUmV0cmlldmFsQXJncz86IHN0cmluZ1tdLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsIFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdDogKHJhZEhhc2g6IHN0cmluZykgPT4gYW55LFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdFJlY2VpcHQ6IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRuZXQuSGFzaD4ge1xyXG4gICAgICAgIGNvbnN0IGFyZ3NDb3VudCA9IGF3YWl0IHRoaXMuZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVxyXG4gICAgICAgIGlmIChhcmdzQ291bnQgIT0gMSArIChjb21tb25SZXRyaWV2YWxBcmdzPy5sZW5ndGggfHwgMCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHt0aGlzLmFkZHJlc3N9OiB1bm1hdGNoaW5nIGFyZ3MgY291bnQgIT0gJHthcmdzQ291bnQgLTEgfS5gKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmNvbnRyYWN0LmdldEZ1bmN0aW9uKFwidmVyaWZ5UmFkb25SZXF1ZXN0KHN0cmluZ1tdLHN0cmluZ1tdKVwiKVxyXG4gICAgICAgIGNvbnN0IHJhZEhhc2ggPSAoYXdhaXQgbWV0aG9kLnN0YXRpY0NhbGwoY29tbW9uUmV0cmlldmFsQXJncyB8fCBbXSwgZGF0YVByb3ZpZGVycykpLnNsaWNlKDIpXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgKGF3YWl0IHRoaXMud2l0T3JhY2xlLmdldFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkoKSkubG9va3VwUmFkb25SZXF1ZXN0Qnl0ZWNvZGUocmFkSGFzaClcclxuICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0KSBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0KHJhZEhhc2gpO1xyXG4gICAgICAgICAgICBhd2FpdCBtZXRob2RcclxuICAgICAgICAgICAgICAgIC5zZW5kKGNvbW1vblJldHJpZXZhbEFyZ3MgfHwgW10sIGRhdGFQcm92aWRlcnMpXHJcbiAgICAgICAgICAgICAgICAudGhlbih0eCA9PiB0eC53YWl0KG9wdGlvbnM/LmNvbmZpcm1hdGlvbnMgfHwgMSkpXHJcbiAgICAgICAgICAgICAgICAudGhlbihyZWNlaXB0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucz8ub25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0KHJlY2VpcHQpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByYWRIYXNoXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmFkSGFzaFxyXG4gICAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlIGV4dGVuZHMgV2l0QXBwbGlhbmNlIHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCBhdDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIod2l0T3JhY2xlLCBcIldpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlXCIsIGF0KVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhc3luYyBhdCh3aXRPcmFjbGU6IFdpdE9yYWNsZSwgdGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlPiB7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGUod2l0T3JhY2xlLCB0YXJnZXQpXHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGVXaXRPcmFjbGVBZGRyID0gYXdhaXQgdGVtcGxhdGUuY29udHJhY3Qud2l0T3JhY2xlLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgIGlmICh0ZW1wbGF0ZVdpdE9yYWNsZUFkZHIgIT09IHdpdE9yYWNsZS5hZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7dGFyZ2V0fTogbWlzbWF0Y2hpbmcgV2l0L09yYWNsZSBhZGRyZXNzICgke3RlbXBsYXRlV2l0T3JhY2xlQWRkcn0pYClcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFSZXN1bHRUeXBlKCk6IFByb21pc2U8V2l0T3JhY2xlUmVzdWx0RGF0YVR5cGVzPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVJlc3VsdFR5cGUoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChyZXN1bHQ6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChOdW1iZXIocmVzdWx0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFwiYXJyYXlcIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBcImJvb2xlYW5cIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBcImJ5dGVzXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gXCJpbnRlZ2VyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiByZXR1cm4gXCJmbG9hdFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFwibWFwXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gXCJzdHJpbmdcIjtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYW55XCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFTb3VyY2VzKCk6IFByb21pc2U8QXJyYXk8V2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRyYWN0XHJcbiAgICAgICAgICAgIC5nZXRGdW5jdGlvbihcImdldERhdGFTb3VyY2VzKClcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgICAgICAudGhlbigocmVzdWx0czogQXJyYXk8UmVzdWx0PikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHMubWFwKHJlc3VsdCA9PiBuZXcgV2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsKHtcclxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlc3VsdFsxXSxcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IHJlc3VsdFszXSxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiByZXN1bHRbNF0sXHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKHJlc3VsdFs1XSksXHJcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0OiBwYXJzZVJhZG9uU2NyaXB0KHJlc3VsdFs2XSksXHJcbiAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKTogUHJvbWlzZTxBcnJheTxudW1iZXI+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChkaW1zOiBBcnJheTxiaWdpbnQ+KSA9PiBkaW1zLm1hcChkaW0gPT4gTnVtYmVyKGRpbSkpKVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB2ZXJpZnlSYWRvblJlcXVlc3QoXHJcbiAgICAgICAgYXJnczogc3RyaW5nIHwgc3RyaW5nW10gfCBBcnJheTxzdHJpbmdbXT4sXHJcbiAgICAgICAgb3B0aW9ucz86IHtcclxuICAgICAgICAgICAgY29uZmlybWF0aW9ucz86IG51bWJlciwgXHJcbiAgICAgICAgICAgIG9uVmVyaWZ5UmFkb25SZXF1ZXN0OiAocmFkSGFzaDogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdDogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgIH0sXHJcbiAgICApOiBQcm9taXNlPFdpdG5ldC5IZXhTdHJpbmc+IHtcclxuICAgICAgICBjb25zdCBhcmdzQ291bnQgPSBhd2FpdCB0aGlzLmdldERhdGFTb3VyY2VzQXJnc0NvdW50KClcclxuICAgICAgICBsZXQgZW5jb2RlZEFyZ3M6IEFycmF5PHN0cmluZ1tdPiA9IFtdXHJcbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpZiAoYXJnc0NvdW50Lmxlbmd0aCA9PT0gMSAmJiBhcmdzQ291bnRbMF0gPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIGVuY29kZWRBcmdzID0gWyBbIGFyZ3MgYXMgc3RyaW5nIF1dXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJncykpIHtcclxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBhcmdzQ291bnQubGVuZ3RoID09PSBhcmdzLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiAhYXJncy5maW5kKChzdWJhcmdzLCBpbmRleCkgPT4gc3ViYXJncy5sZW5ndGggIT09IGFyZ3NDb3VudFtpbmRleF0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICBlbmNvZGVkQXJncyA9IGFyZ3MgYXMgQXJyYXk8c3RyaW5nW10+XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgICAgICBhcmdzLmxlbmd0aCA9PT0gYXJnc0NvdW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgIWFyZ3MuZmluZChhcmcgPT4gdHlwZW9mIGFyZyAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgZW5jb2RlZEFyZ3MgPSBbIGFyZ3MgYXMgc3RyaW5nW10gXVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbmNvZGVkQXJncy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHt0aGlzLmFkZHJlc3N9OiB1bm1hdGNoaW5nIGFyZ3MgY291bnQgIT0gWyR7YXJnc0NvdW50fSwgXS5gKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmNvbnRyYWN0LmdldEZ1bmN0aW9uKFwidmVyaWZ5UmFkb25SZXF1ZXN0KHN0cmluZ1tdW10pXCIpXHJcbiAgICAgICAgY29uc3QgcmFkSGFzaCA9IChhd2FpdCBtZXRob2Quc3RhdGljQ2FsbChlbmNvZGVkQXJncykpLnNsaWNlKDIpXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgKGF3YWl0IHRoaXMud2l0T3JhY2xlLmdldFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkoKSkubG9va3VwUmFkb25SZXF1ZXN0Qnl0ZWNvZGUocmFkSGFzaClcclxuICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0KSBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0KHJhZEhhc2gpO1xyXG4gICAgICAgICAgICBhd2FpdCBtZXRob2RcclxuICAgICAgICAgICAgICAgIC5zZW5kKGVuY29kZWRBcmdzKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4odHggPT4gdHgud2FpdChvcHRpb25zPy5jb25maXJtYXRpb25zIHx8IDEpKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVjZWlwdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdChyZWNlaXB0KVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmFkSGFzaFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJhZEhhc2hcclxuICAgIH1cclxufVxyXG5cclxuIl19