@neo-one/server-plugin-compiler
Version:
NEO•ONE Server compiler plugin.
176 lines (174 loc) • 28.2 kB
JavaScript
"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