UNPKG

@neo-one/server-plugin-compiler

Version:

NEO•ONE Server compiler plugin.

176 lines (174 loc) 28.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const server_plugin_1 = require("@neo-one/server-plugin"); const fs = tslib_1.__importStar(require("fs-extra")); const path = tslib_1.__importStar(require("path")); const of_1 = require("rxjs/internal/observable/of"); const ReplaySubject_1 = require("rxjs/internal/ReplaySubject"); const shareReplay_1 = require("rxjs/internal/operators/shareReplay"); const switchMap_1 = require("rxjs/internal/operators/switchMap"); const compileSmartContract_1 = require("./compileSmartContract"); const errors_1 = require("./errors"); const ABI_PATH = 'abi.json'; const AVM_PATH = 'sc.avm'; const CONFIG_PATH = 'sc.json'; class ContractResourceAdapter { static async init(options) { const staticOptions = this.getStaticOptions(options); const [abi, script, { hasStorage, hasDynamicInvoke, payable }] = await Promise.all([fs.readJSON(staticOptions.abiPath), fs.readFile(staticOptions.avmPath, 'hex'), fs.readJSON(staticOptions.configPath)]); return new this({ name: staticOptions.name, binary: staticOptions.binary, dataPath: staticOptions.dataPath, resourceType: staticOptions.resourceType, abiPath: staticOptions.abiPath, avmPath: staticOptions.avmPath, configPath: staticOptions.configPath, abi, script, hasStorage, hasDynamicInvoke, payable }); } static create(adapterOptions, options) { const staticOptions = this.getStaticOptions(adapterOptions); return new server_plugin_1.TaskList({ tasks: [{ title: 'Create data directory', task: async () => { await fs.ensureDir(staticOptions.dataPath); } }, { title: 'Compile smart contract', task: async (ctx) => { if (options.scPath === undefined) { throw new Error('Something went wrong, smart contract path was null.'); } try { let { abi, hasStorage, hasDynamicInvoke, payable } = await compileSmartContract_1.compileSmartContract({ scPath: options.scPath, avmPath: staticOptions.avmPath, binary: staticOptions.binary }); if (abi === undefined) { abi = options.abi; } if (abi === undefined) { throw new errors_1.ABIRequiredError(); } if (hasStorage === undefined) { hasStorage = options.hasStorage; } if (hasDynamicInvoke === undefined) { hasDynamicInvoke = options.hasDynamicInvoke; } if (payable === undefined) { ({ payable } = options); } const script = await fs.readFile(staticOptions.avmPath, 'hex'); ctx.abi = abi; ctx.hasDynamicInvoke = hasDynamicInvoke; ctx.hasStorage = hasStorage; ctx.payable = payable; ctx.script = script; } catch (error) { await fs.remove(staticOptions.dataPath); throw error; } } }, { title: 'Save ABI and configuration', task: async (ctx) => { const { abi, hasDynamicInvoke, hasStorage, payable, script } = ctx; await Promise.all([fs.writeJSON(staticOptions.abiPath, abi), fs.writeJSON(staticOptions.configPath, { hasDynamicInvoke, hasStorage, payable })]); ctx.resourceAdapter = new this({ name: staticOptions.name, binary: staticOptions.binary, dataPath: staticOptions.dataPath, resourceType: staticOptions.resourceType, abiPath: staticOptions.abiPath, avmPath: staticOptions.avmPath, configPath: staticOptions.configPath, script, abi, hasStorage, hasDynamicInvoke, payable }); ctx.dependencies = []; } }] }); } static getStaticOptions(options) { return { name: options.name, binary: options.binary, dataPath: options.dataPath, resourceType: options.resourceType, abiPath: path.resolve(options.dataPath, ABI_PATH), avmPath: path.resolve(options.dataPath, AVM_PATH), configPath: path.resolve(options.dataPath, CONFIG_PATH) }; } constructor({ name, dataPath, resourceType, avmPath, abiPath, configPath, script, abi, hasStorage, hasDynamicInvoke, payable }) { this.name = name; this.dataPath = dataPath; this.resourceType = resourceType; this.avmPath = avmPath; this.abiPath = abiPath; this.configPath = configPath; this.script = script; this.abi = abi; this.hasStorage = hasStorage; this.hasDynamicInvoke = hasDynamicInvoke; this.payable = payable; this.update$ = new ReplaySubject_1.ReplaySubject(1); this.resource$ = this.update$.pipe(switchMap_1.switchMap(() => of_1.of({ plugin: this.resourceType.plugin.name, resourceType: this.resourceType.name, name: this.name, baseName: this.name, state: 'stopped', avmPath: this.avmPath, script: this.script, abi: this.abi, hasStorage: this.hasStorage, hasDynamicInvoke: this.hasDynamicInvoke, payable: this.payable })), shareReplay_1.shareReplay(1)); this.update$.next(); } async destroy() { } delete(_options) { return new server_plugin_1.TaskList({ tasks: [{ title: 'Clean local files', task: async () => { await fs.remove(this.dataPath); } }] }); } start(_options) { throw new Error('Cannot be started'); } stop(_options) { throw new Error('Cannot be stopped'); } getDebug() { return [['Data Path', this.dataPath], ['AVM Path', this.avmPath], ['ABI Path', this.abiPath], ['Config Path', this.configPath], ['Storage', this.hasStorage ? 'Yes' : 'No'], ['Dynamic Invoke', this.hasDynamicInvoke ? 'Yes' : 'No'], ['Payable', this.payable ? 'Yes' : 'No'], ['ABI', JSON.stringify(this.abi, undefined, 2)]]; } } exports.ContractResourceAdapter = ContractResourceAdapter; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbnRyYWN0UmVzb3VyY2VBZGFwdGVyLnRzIl0sIm5hbWVzIjpbIkFCSV9QQVRIIiwiQVZNX1BBVEgiLCJDT05GSUdfUEFUSCIsIkNvbnRyYWN0UmVzb3VyY2VBZGFwdGVyIiwiaW5pdCIsIm9wdGlvbnMiLCJzdGF0aWNPcHRpb25zIiwiZ2V0U3RhdGljT3B0aW9ucyIsImFiaSIsInNjcmlwdCIsImhhc1N0b3JhZ2UiLCJoYXNEeW5hbWljSW52b2tlIiwicGF5YWJsZSIsIlByb21pc2UiLCJhbGwiLCJmcyIsInJlYWRKU09OIiwiYWJpUGF0aCIsInJlYWRGaWxlIiwiYXZtUGF0aCIsImNvbmZpZ1BhdGgiLCJuYW1lIiwiYmluYXJ5IiwiZGF0YVBhdGgiLCJyZXNvdXJjZVR5cGUiLCJjcmVhdGUiLCJhZGFwdGVyT3B0aW9ucyIsIlRhc2tMaXN0IiwidGFza3MiLCJ0aXRsZSIsInRhc2siLCJlbnN1cmVEaXIiLCJjdHgiLCJzY1BhdGgiLCJ1bmRlZmluZWQiLCJFcnJvciIsImNvbXBpbGVTbWFydENvbnRyYWN0IiwiQUJJUmVxdWlyZWRFcnJvciIsImVycm9yIiwicmVtb3ZlIiwid3JpdGVKU09OIiwicmVzb3VyY2VBZGFwdGVyIiwiZGVwZW5kZW5jaWVzIiwicGF0aCIsInJlc29sdmUiLCJ1cGRhdGUkIiwiUmVwbGF5U3ViamVjdCIsInJlc291cmNlJCIsInBpcGUiLCJzd2l0Y2hNYXAiLCJfb2YiLCJwbHVnaW4iLCJiYXNlTmFtZSIsInN0YXRlIiwic2hhcmVSZXBsYXkiLCJuZXh0IiwiZGVzdHJveSIsImRlbGV0ZSIsIl9vcHRpb25zIiwic3RhcnQiLCJzdG9wIiwiZ2V0RGVidWciLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiOzs7QUFDQSwwREFBQTtBQUNBLHFEQUFBO0FBQ0EsbURBQUE7QUFFQSxvREFBd0Q7QUFDeEQsK0RBQTREO0FBRTVELHFFQUFrRTtBQUNsRSxpRUFBOEQ7QUFIOUQsaUVBQUE7QUFFQSxxQ0FBQTtBQUVBLE1BQU1B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TTBCLFFBQVA7UUFDRSxPQUFPLENBQ0wsQ0FBQyxXQUFELEVBQWMsSUFBQSxDQUFLdEMsUUFBbkIsQ0FESyxFQUVMLENBQUMsVUFBRCxFQUFhLElBQUEsQ0FBS0osT0FBbEIsQ0FGSyxFQUdMLENBQUMsVUFBRCxFQUFhLElBQUEsQ0FBS0YsT0FBbEIsQ0FISyxFQUlMLENBQUMsYUFBRCxFQUFnQixJQUFBLENBQUtHLFVBQXJCLENBSkssRUFLTCxDQUFDLFNBQUQsRUFBWSxJQUFBLENBQUtWLFVBQUwsQ0FBQSxDQUFBLENBQWtCLEtBQWxCLENBQUEsQ0FBQSxDQUEwQixJQUF0QyxDQUxLLEVBTUwsQ0FBQyxnQkFBRCxFQUFtQixJQUFBLENBQUtDLGdCQUFMLENBQUEsQ0FBQSxDQUF3QixLQUF4QixDQUFBLENBQUEsQ0FBZ0MsSUFBbkQsQ0FOSyxFQU9MLENBQUMsU0FBRCxFQUFZLElBQUEsQ0FBS0MsT0FBTCxDQUFBLENBQUEsQ0FBZSxLQUFmLENBQUEsQ0FBQSxDQUF1QixJQUFuQyxDQVBLLEVBUUwsQ0FBQyxLQUFELEVBQVFrRCxJQUFJLENBQUNDLFNBQUwsQ0FBZSxJQUFBLENBQUt2RCxHQUFwQixFQUF5QjBCLFNBQXpCLEVBQW9DLENBQXBDLENBQVIsQ0FSSyxDQUFQLENBQUE7SUFVRCxDQUFBO0NBck9rQztBQUFyQywwREFBcUMiLCJmaWxlIjoibmVvLW9uZS1zZXJ2ZXItcGx1Z2luLWNvbXBpbGVyL3NyYy9Db250cmFjdFJlc291cmNlQWRhcHRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFCSSB9IGZyb20gJ0BuZW8tb25lL2NsaWVudCc7XG5pbXBvcnQgeyBCaW5hcnksIERlc2NyaWJlVGFibGUsIFRhc2tMaXN0IH0gZnJvbSAnQG5lby1vbmUvc2VydmVyLXBsdWdpbic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgYXMgX29mLCBSZXBsYXlTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzaGFyZVJlcGxheSwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgY29tcGlsZVNtYXJ0Q29udHJhY3QgfSBmcm9tICcuL2NvbXBpbGVTbWFydENvbnRyYWN0JztcbmltcG9ydCB7IENvbnRyYWN0LCBDb250cmFjdFJlc291cmNlT3B0aW9ucywgQ29udHJhY3RSZXNvdXJjZVR5cGUgfSBmcm9tICcuL0NvbnRyYWN0UmVzb3VyY2VUeXBlJztcbmltcG9ydCB7IEFCSVJlcXVpcmVkRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5cbmNvbnN0IEFCSV9QQVRIID0gJ2FiaS5qc29uJztcbmNvbnN0IEFWTV9QQVRIID0gJ3NjLmF2bSc7XG5jb25zdCBDT05GSUdfUEFUSCA9ICdzYy5qc29uJztcblxuZXhwb3J0IGludGVyZmFjZSBDb250cmFjdFJlc291cmNlQWRhcHRlckluaXRPcHRpb25zIHtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBkYXRhUGF0aDogc3RyaW5nO1xuICByZWFkb25seSBiaW5hcnk6IEJpbmFyeTtcbiAgcmVhZG9ubHkgcmVzb3VyY2VUeXBlOiBDb250cmFjdFJlc291cmNlVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250cmFjdFJlc291cmNlQWRhcHRlclN0YXRpY09wdGlvbnMgZXh0ZW5kcyBDb250cmFjdFJlc291cmNlQWRhcHRlckluaXRPcHRpb25zIHtcbiAgcmVhZG9ubHkgYXZtUGF0aDogc3RyaW5nO1xuICByZWFkb25seSBhYmlQYXRoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNvbmZpZ1BhdGg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250cmFjdFJlc291cmNlQWRhcHRlck9wdGlvbnMgZXh0ZW5kcyBDb250cmFjdFJlc291cmNlQWRhcHRlclN0YXRpY09wdGlvbnMge1xuICByZWFkb25seSBzY3JpcHQ6IHN0cmluZztcbiAgcmVhZG9ubHkgYWJpOiBBQkk7XG4gIHJlYWRvbmx5IGhhc1N0b3JhZ2U6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGhhc0R5bmFtaWNJbnZva2U6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHBheWFibGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBDb250cmFjdFJlc291cmNlQWRhcHRlciB7XG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgaW5pdChvcHRpb25zOiBDb250cmFjdFJlc291cmNlQWRhcHRlckluaXRPcHRpb25zKTogUHJvbWlzZTxDb250cmFjdFJlc291cmNlQWRhcHRlcj4ge1xuICAgIGNvbnN0IHN0YXRpY09wdGlvbnMgPSB0aGlzLmdldFN0YXRpY09wdGlvbnMob3B0aW9ucyk7XG4gICAgY29uc3QgW2FiaSwgc2NyaXB0LCB7IGhhc1N0b3JhZ2UsIGhhc0R5bmFtaWNJbnZva2UsIHBheWFibGUgfV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBmcy5yZWFkSlNPTihzdGF0aWNPcHRpb25zLmFiaVBhdGgpLFxuICAgICAgZnMucmVhZEZpbGUoc3RhdGljT3B0aW9ucy5hdm1QYXRoLCAnaGV4JyksXG4gICAgICBmcy5yZWFkSlNPTihzdGF0aWNPcHRpb25zLmNvbmZpZ1BhdGgpLFxuICAgIF0pO1xuXG4gICAgcmV0dXJuIG5ldyB0aGlzKHtcbiAgICAgIG5hbWU6IHN0YXRpY09wdGlvbnMubmFtZSxcbiAgICAgIGJpbmFyeTogc3RhdGljT3B0aW9ucy5iaW5hcnksXG4gICAgICBkYXRhUGF0aDogc3RhdGljT3B0aW9ucy5kYXRhUGF0aCxcbiAgICAgIHJlc291cmNlVHlwZTogc3RhdGljT3B0aW9ucy5yZXNvdXJjZVR5cGUsXG4gICAgICBhYmlQYXRoOiBzdGF0aWNPcHRpb25zLmFiaVBhdGgsXG4gICAgICBhdm1QYXRoOiBzdGF0aWNPcHRpb25zLmF2bVBhdGgsXG4gICAgICBjb25maWdQYXRoOiBzdGF0aWNPcHRpb25zLmNvbmZpZ1BhdGgsXG4gICAgICBhYmksXG4gICAgICBzY3JpcHQsXG4gICAgICBoYXNTdG9yYWdlLFxuICAgICAgaGFzRHluYW1pY0ludm9rZSxcbiAgICAgIHBheWFibGUsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGNyZWF0ZShhZGFwdGVyT3B0aW9uczogQ29udHJhY3RSZXNvdXJjZUFkYXB0ZXJJbml0T3B0aW9ucywgb3B0aW9uczogQ29udHJhY3RSZXNvdXJjZU9wdGlvbnMpOiBUYXNrTGlzdCB7XG4gICAgY29uc3Qgc3RhdGljT3B0aW9ucyA9IHRoaXMuZ2V0U3RhdGljT3B0aW9ucyhhZGFwdGVyT3B0aW9ucyk7XG5cbiAgICByZXR1cm4gbmV3IFRhc2tMaXN0KHtcbiAgICAgIHRhc2tzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogJ0NyZWF0ZSBkYXRhIGRpcmVjdG9yeScsXG4gICAgICAgICAgdGFzazogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgZnMuZW5zdXJlRGlyKHN0YXRpY09wdGlvbnMuZGF0YVBhdGgpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG5cbiAgICAgICAge1xuICAgICAgICAgIHRpdGxlOiAnQ29tcGlsZSBzbWFydCBjb250cmFjdCcsXG4gICAgICAgICAgdGFzazogYXN5bmMgKGN0eCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2NQYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZywgc21hcnQgY29udHJhY3QgcGF0aCB3YXMgbnVsbC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGxldCB7IGFiaSwgaGFzU3RvcmFnZSwgaGFzRHluYW1pY0ludm9rZSwgcGF5YWJsZSB9ID0gYXdhaXQgY29tcGlsZVNtYXJ0Q29udHJhY3Qoe1xuICAgICAgICAgICAgICAgIHNjUGF0aDogb3B0aW9ucy5zY1BhdGgsXG4gICAgICAgICAgICAgICAgYXZtUGF0aDogc3RhdGljT3B0aW9ucy5hdm1QYXRoLFxuICAgICAgICAgICAgICAgIGJpbmFyeTogc3RhdGljT3B0aW9ucy5iaW5hcnksXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmIChhYmkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGFiaSA9IG9wdGlvbnMuYWJpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKGFiaSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFCSVJlcXVpcmVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChoYXNTdG9yYWdlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBoYXNTdG9yYWdlID0gb3B0aW9ucy5oYXNTdG9yYWdlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKGhhc0R5bmFtaWNJbnZva2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGhhc0R5bmFtaWNJbnZva2UgPSBvcHRpb25zLmhhc0R5bmFtaWNJbnZva2U7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAocGF5YWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgKHsgcGF5YWJsZSB9ID0gb3B0aW9ucyk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBzY3JpcHQgPSBhd2FpdCBmcy5yZWFkRmlsZShzdGF0aWNPcHRpb25zLmF2bVBhdGgsICdoZXgnKTtcblxuICAgICAgICAgICAgICBjdHguYWJpID0gYWJpO1xuICAgICAgICAgICAgICBjdHguaGFzRHluYW1pY0ludm9rZSA9IGhhc0R5bmFtaWNJbnZva2U7XG4gICAgICAgICAgICAgIGN0eC5oYXNTdG9yYWdlID0gaGFzU3RvcmFnZTtcbiAgICAgICAgICAgICAgY3R4LnBheWFibGUgPSBwYXlhYmxlO1xuICAgICAgICAgICAgICBjdHguc2NyaXB0ID0gc2NyaXB0O1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZnMucmVtb3ZlKHN0YXRpY09wdGlvbnMuZGF0YVBhdGgpO1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogJ1NhdmUgQUJJIGFuZCBjb25maWd1cmF0aW9uJyxcbiAgICAgICAgICB0YXNrOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGFiaSwgaGFzRHluYW1pY0ludm9rZSwgaGFzU3RvcmFnZSwgcGF5YWJsZSwgc2NyaXB0IH0gPSBjdHg7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgIGZzLndyaXRlSlNPTihzdGF0aWNPcHRpb25zLmFiaVBhdGgsIGFiaSksXG4gICAgICAgICAgICAgIGZzLndyaXRlSlNPTihzdGF0aWNPcHRpb25zLmNvbmZpZ1BhdGgsIHtcbiAgICAgICAgICAgICAgICBoYXNEeW5hbWljSW52b2tlLFxuICAgICAgICAgICAgICAgIGhhc1N0b3JhZ2UsXG4gICAgICAgICAgICAgICAgcGF5YWJsZSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgY3R4LnJlc291cmNlQWRhcHRlciA9IG5ldyB0aGlzKHtcbiAgICAgICAgICAgICAgbmFtZTogc3RhdGljT3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgICBiaW5hcnk6IHN0YXRpY09wdGlvbnMuYmluYXJ5LFxuICAgICAgICAgICAgICBkYXRhUGF0aDogc3RhdGljT3B0aW9ucy5kYXRhUGF0aCxcbiAgICAgICAgICAgICAgcmVzb3VyY2VUeXBlOiBzdGF0aWNPcHRpb25zLnJlc291cmNlVHlwZSxcbiAgICAgICAgICAgICAgYWJpUGF0aDogc3RhdGljT3B0aW9ucy5hYmlQYXRoLFxuICAgICAgICAgICAgICBhdm1QYXRoOiBzdGF0aWNPcHRpb25zLmF2bVBhdGgsXG4gICAgICAgICAgICAgIGNvbmZpZ1BhdGg6IHN0YXRpY09wdGlvbnMuY29uZmlnUGF0aCxcbiAgICAgICAgICAgICAgc2NyaXB0LFxuICAgICAgICAgICAgICBhYmksXG4gICAgICAgICAgICAgIGhhc1N0b3JhZ2UsXG4gICAgICAgICAgICAgIGhhc0R5bmFtaWNJbnZva2UsXG4gICAgICAgICAgICAgIHBheWFibGUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY3R4LmRlcGVuZGVuY2llcyA9IFtdO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0U3RhdGljT3B0aW9ucyhvcHRpb25zOiBDb250cmFjdFJlc291cmNlQWRhcHRlckluaXRPcHRpb25zKTogQ29udHJhY3RSZXNvdXJjZUFkYXB0ZXJTdGF0aWNPcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgYmluYXJ5OiBvcHRpb25zLmJpbmFyeSxcbiAgICAgIGRhdGFQYXRoOiBvcHRpb25zLmRhdGFQYXRoLFxuICAgICAgcmVzb3VyY2VUeXBlOiBvcHRpb25zLnJlc291cmNlVHlwZSxcbiAgICAgIGFiaVBhdGg6IHBhdGgucmVzb2x2ZShvcHRpb25zLmRhdGFQYXRoLCBBQklfUEFUSCksXG4gICAgICBhdm1QYXRoOiBwYXRoLnJlc29sdmUob3B0aW9ucy5kYXRhUGF0aCwgQVZNX1BBVEgpLFxuICAgICAgY29uZmlnUGF0aDogcGF0aC5yZXNvbHZlKG9wdGlvbnMuZGF0YVBhdGgsIENPTkZJR19QQVRIKSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHJlc291cmNlJDogT2JzZXJ2YWJsZTxDb250cmFjdD47XG4gIHByaXZhdGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRhdGFQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VUeXBlOiBDb250cmFjdFJlc291cmNlVHlwZTtcbiAgcHJpdmF0ZSByZWFkb25seSBhdm1QYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgYWJpUGF0aDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZ1BhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBzY3JpcHQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBhYmk6IEFCSTtcbiAgcHJpdmF0ZSByZWFkb25seSBoYXNTdG9yYWdlOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGhhc0R5bmFtaWNJbnZva2U6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgcGF5YWJsZTogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSB1cGRhdGUkOiBTdWJqZWN0PHZvaWQ+O1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcih7XG4gICAgbmFtZSxcbiAgICBkYXRhUGF0aCxcbiAgICByZXNvdXJjZVR5cGUsXG4gICAgYXZtUGF0aCxcbiAgICBhYmlQYXRoLFxuICAgIGNvbmZpZ1BhdGgsXG4gICAgc2NyaXB0LFxuICAgIGFiaSxcbiAgICBoYXNTdG9yYWdlLFxuICAgIGhhc0R5bmFtaWNJbnZva2UsXG4gICAgcGF5YWJsZSxcbiAgfTogQ29udHJhY3RSZXNvdXJjZUFkYXB0ZXJPcHRpb25zKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmRhdGFQYXRoID0gZGF0YVBhdGg7XG4gICAgdGhpcy5yZXNvdXJjZVR5cGUgPSByZXNvdXJjZVR5cGU7XG4gICAgdGhpcy5hdm1QYXRoID0gYXZtUGF0aDtcbiAgICB0aGlzLmFiaVBhdGggPSBhYmlQYXRoO1xuICAgIHRoaXMuY29uZmlnUGF0aCA9IGNvbmZpZ1BhdGg7XG4gICAgdGhpcy5zY3JpcHQgPSBzY3JpcHQ7XG4gICAgdGhpcy5hYmkgPSBhYmk7XG4gICAgdGhpcy5oYXNTdG9yYWdlID0gaGFzU3RvcmFnZTtcbiAgICB0aGlzLmhhc0R5bmFtaWNJbnZva2UgPSBoYXNEeW5hbWljSW52b2tlO1xuICAgIHRoaXMucGF5YWJsZSA9IHBheWFibGU7XG5cbiAgICB0aGlzLnVwZGF0ZSQgPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcbiAgICB0aGlzLnJlc291cmNlJCA9IHRoaXMudXBkYXRlJC5waXBlKFxuICAgICAgc3dpdGNoTWFwKCgpID0+XG4gICAgICAgIF9vZjxDb250cmFjdD4oe1xuICAgICAgICAgIHBsdWdpbjogdGhpcy5yZXNvdXJjZVR5cGUucGx1Z2luLm5hbWUsXG4gICAgICAgICAgcmVzb3VyY2VUeXBlOiB0aGlzLnJlc291cmNlVHlwZS5uYW1lLFxuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICBiYXNlTmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgIHN0YXRlOiAnc3RvcHBlZCcsXG4gICAgICAgICAgYXZtUGF0aDogdGhpcy5hdm1QYXRoLFxuICAgICAgICAgIHNjcmlwdDogdGhpcy5zY3JpcHQsXG4gICAgICAgICAgYWJpOiB0aGlzLmFiaSxcbiAgICAgICAgICBoYXNTdG9yYWdlOiB0aGlzLmhhc1N0b3JhZ2UsXG4gICAgICAgICAgaGFzRHluYW1pY0ludm9rZTogdGhpcy5oYXNEeW5hbWljSW52b2tlLFxuICAgICAgICAgIHBheWFibGU6IHRoaXMucGF5YWJsZSxcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICAgc2hhcmVSZXBsYXkoMSksXG4gICAgKTtcblxuICAgIHRoaXMudXBkYXRlJC5uZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBkbyBub3RoaW5nXG4gIH1cblxuICBwdWJsaWMgZGVsZXRlKF9vcHRpb25zOiBDb250cmFjdFJlc291cmNlT3B0aW9ucyk6IFRhc2tMaXN0IHtcbiAgICByZXR1cm4gbmV3IFRhc2tMaXN0KHtcbiAgICAgIHRhc2tzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogJ0NsZWFuIGxvY2FsIGZpbGVzJyxcbiAgICAgICAgICB0YXNrOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBmcy5yZW1vdmUodGhpcy5kYXRhUGF0aCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhcnQoX29wdGlvbnM6IENvbnRyYWN0UmVzb3VyY2VPcHRpb25zKTogVGFza0xpc3Qge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGJlIHN0YXJ0ZWQnKTtcbiAgfVxuXG4gIHB1YmxpYyBzdG9wKF9vcHRpb25zOiBDb250cmFjdFJlc291cmNlT3B0aW9ucyk6IFRhc2tMaXN0IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBiZSBzdG9wcGVkJyk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RGVidWcoKTogRGVzY3JpYmVUYWJsZSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFsnRGF0YSBQYXRoJywgdGhpcy5kYXRhUGF0aF0sXG4gICAgICBbJ0FWTSBQYXRoJywgdGhpcy5hdm1QYXRoXSxcbiAgICAgIFsnQUJJIFBhdGgnLCB0aGlzLmFiaVBhdGhdLFxuICAgICAgWydDb25maWcgUGF0aCcsIHRoaXMuY29uZmlnUGF0aF0sXG4gICAgICBbJ1N0b3JhZ2UnLCB0aGlzLmhhc1N0b3JhZ2UgPyAnWWVzJyA6ICdObyddLFxuICAgICAgWydEeW5hbWljIEludm9rZScsIHRoaXMuaGFzRHluYW1pY0ludm9rZSA/ICdZZXMnIDogJ05vJ10sXG4gICAgICBbJ1BheWFibGUnLCB0aGlzLnBheWFibGUgPyAnWWVzJyA6ICdObyddLFxuICAgICAgWydBQkknLCBKU09OLnN0cmluZ2lmeSh0aGlzLmFiaSwgdW5kZWZpbmVkLCAyKV0sXG4gICAgXTtcbiAgfVxufVxuIl19