UNPKG

@glimmer/application-test-helpers

Version:

Test helpers for developing @glimmer/component and @glimmer/application

292 lines (244 loc) 29.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildApp = exports.AppBuilder = exports.TestApplication = undefined; var _resolver = require("@glimmer/resolver"); var _resolver2 = _interopRequireDefault(_resolver); var _defaultResolverConfiguration = require("./default-resolver-configuration"); var _defaultResolverConfiguration2 = _interopRequireDefault(_defaultResolverConfiguration); var _compiler = require("./compiler"); var _application = require("@glimmer/application"); var _application2 = _interopRequireDefault(_application); var _util = require("@glimmer/util"); var _bundleCompiler = require("@glimmer/bundle-compiler"); var _opcodeCompiler = require("@glimmer/opcode-compiler"); var _ssr = require("@glimmer/ssr"); var _didRender = require("./did-render"); var _didRender2 = _interopRequireDefault(_didRender); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class TestApplication extends _application2.default {} exports.TestApplication = TestApplication; function locatorFor(module, name) { return { kind: 'template', module, name, meta: { module, name } }; } class AppBuilder { constructor(name, options) { this.modules = {}; this.templates = {}; this.rootName = name; this.options = options; this.template('Main', '<div />'); this.helper('action', _application.buildAction, true); } template(name, template) { (0, _util.assert)(name.charAt(0) === name.charAt(0).toUpperCase(), 'template names must start with a capital letter'); let specifier = `template:/${this.rootName}/components/${name}`; this.modules[specifier] = (0, _compiler.precompile)(template, { meta: { specifier } }); this.templates[specifier] = template; return this; } component(name, componentFactory) { let specifier = `component:/${this.rootName}/components/${name}`; this.modules[specifier] = componentFactory; return this; } helper(name, helperFunc, isFactory = false) { let specifier = `helper:/${this.rootName}/components/${name}`; helperFunc.isFactory = isFactory; this.modules[specifier] = helperFunc; return this; } buildResolver() { let resolverConfiguration = this.options.resolverConfiguration || _defaultResolverConfiguration2.default; resolverConfiguration.app = resolverConfiguration.app || { name: this.rootName, rootName: this.rootName }; let registry = new _resolver.BasicModuleRegistry(this.modules); return new _resolver2.default(resolverConfiguration, registry); } buildRuntimeCompilerLoader() { return new _application.RuntimeCompilerLoader(); } buildBytecodeLoader(resolver) { let delegate = new CompilerDelegate(resolver); let compiler = new _bundleCompiler.BundleCompiler(delegate); let mainLocator = locatorFor('template:mainTemplate', 'default'); mainLocator.meta.module = 'template:mainTemplate'; let block = JSON.parse(_application.mainTemplate.block); let compilableTemplate = (0, _opcodeCompiler.compilable)({ block, referrer: mainLocator.meta }); compiler.addCompilableTemplate(mainLocator, compilableTemplate); for (let module in this.templates) { compiler.addTemplateSource(locatorFor(module, 'default'), this.templates[module]); } let { heap, pool, table } = compiler.compile(); let resolverTable = []; let meta = {}; table.vmHandleByModuleLocator.forEach((vmHandle, locator) => { let handle = table.byModuleLocator.get(locator); let template = compiler.getTemplate(locator); meta[locator.module] = { v: vmHandle, h: handle, sT: template.symbolTable }; }); table.byHandle.forEach((locator, handle) => { let module = locator.module.replace('template:/', 'component:/'); if (this.modules[module]) { if (module.indexOf('helper:') === 0) { const moduleType = this.modules[module].isFactory ? 0 /* HELPER_FACTORY */ : 1 /* HELPER */ ; resolverTable[handle] = [moduleType, this.modules[module]]; } else { resolverTable[handle] = this.modules[module]; } } }); let bytecode = heap.buffer; let data = { prefix: '', mainEntry: table.vmHandleByModuleLocator.get(mainLocator), pool, table: resolverTable, meta, heap: { table: heap.table, handle: heap.handle } }; return new _application.BytecodeLoader({ bytecode, data }); } buildLoader(resolver) { switch (this.options.loader) { case 'runtime-compiler': return this.buildRuntimeCompilerLoader(); case 'bytecode': return this.buildBytecodeLoader(resolver); default: throw new Error(`Unrecognized loader ${this.options.loader}`); } } renderToString(componentName, data, options) { const resolver = this.buildResolver(); let loader = this.buildLoader(resolver); return _ssr.SSRApplication.renderToString(componentName, data, Object.assign({ rootName: this.rootName, resolver, loader, renderer: new _application.SyncRenderer() }, options)); } async boot() { let resolver = this.buildResolver(); let loader = this.buildLoader(resolver); let doc = this.options.document || document; let element = doc.body; let builder = new _application.DOMBuilder({ element }); let renderer = new _application.SyncRenderer(); let app = new this.options.ApplicationClass({ resolver, builder, loader, renderer, rootName: this.rootName, document: this.options.document }); let rootElement = doc.createElement('div'); app.rootElement = rootElement; app.renderComponent('Main', rootElement); app.boot(); await (0, _didRender2.default)(app); return app; } } exports.AppBuilder = AppBuilder; const CAPABILITIES = { createInstance: true, dynamicLayout: false, dynamicTag: false, wrapped: false, prepareArgs: false, createArgs: true, attributeHook: false, elementHook: false, updateHook: true, createCaller: false, dynamicScope: true }; class CompilerDelegate { constructor(resolver) { this.resolver = resolver; } hasComponentInScope(name, referrer) { return !!this.resolver.identify(`template:${name}`, referrer.module); } resolveComponent(name, referrer) { let resolved = this.resolver.identify(`template:${name}`, referrer.module); return { module: resolved, name: 'default' }; } getComponentCapabilities() { return CAPABILITIES; } hasHelperInScope(helperName, referrer) { return !!this.resolver.identify(`helper:${helperName}`, referrer.module); } resolveHelper(helperName, referrer) { let resolved = this.resolver.identify(`helper:${helperName}`, referrer.module); return { module: resolved, name: 'default' }; } hasPartialInScope(partialName, referrer) { throw new Error('Method not implemented.'); } resolvePartial(partialName, referrer) { throw new Error('Method not implemented.'); } hasModifierInScope(modifierName, referrer) { throw new Error('Method not implemented.'); } resolveModifier(modifierName, referrer) { throw new Error('Method not implemented.'); } } function buildApp(options = {}) { options.appName = options.appName || 'test-app'; options.loader = options.loader || 'runtime-compiler'; options.ApplicationClass = options.ApplicationClass || TestApplication; return new AppBuilder(options.appName, options); } exports.buildApp = buildApp; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2FwcGxpY2F0aW9uLXRlc3QtaGVscGVycy9zcmMvYXBwLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUE7Ozs7QUFDQTs7QUFDQTs7OztBQVVBOztBQUNBOztBQUVBOztBQUdBOztBQUVBOzs7Ozs7QUFhTSxNQUFPLGVBQVAsU0FBK0IscUJBQS9CLENBQTBDOztRQUFuQyxlLEdBQUEsZTs7QUFxQmIsU0FBUyxVQUFULENBQW9CLE1BQXBCLEVBQW9DLElBQXBDLEVBQWdEO0FBQzlDLFNBQU87QUFDTCxJQUFBLElBQUksRUFBRSxVQUREO0FBRUwsSUFBQSxNQUZLO0FBR0wsSUFBQSxJQUhLO0FBSUwsSUFBQSxJQUFJLEVBQUU7QUFDSixNQUFBLE1BREk7QUFFSixNQUFBO0FBRkk7QUFKRCxHQUFQO0FBU0Q7O0FBRUssTUFBTyxVQUFQLENBQWlCO0FBTXJCLEVBQUEsV0FBQSxDQUFZLElBQVosRUFBMEIsT0FBMUIsRUFBdUQ7QUFKdkQsU0FBQSxPQUFBLEdBQXlCLEVBQXpCO0FBQ0EsU0FBQSxTQUFBLEdBQTBCLEVBQTFCO0FBSUUsU0FBSyxRQUFMLEdBQWdCLElBQWhCO0FBQ0EsU0FBSyxPQUFMLEdBQWUsT0FBZjtBQUNBLFNBQUssUUFBTCxDQUFjLE1BQWQsRUFBc0IsU0FBdEI7QUFDQSxTQUFLLE1BQUwsQ0FBWSxRQUFaLEVBQXNCLHdCQUF0QixFQUFtQyxJQUFuQztBQUNEOztBQUVELEVBQUEsUUFBUSxDQUFDLElBQUQsRUFBZSxRQUFmLEVBQStCO0FBQ3JDLHNCQUNFLElBQUksQ0FBQyxNQUFMLENBQVksQ0FBWixNQUFtQixJQUFJLENBQUMsTUFBTCxDQUFZLENBQVosRUFBZSxXQUFmLEVBRHJCLEVBRUUsaURBRkY7QUFLQSxRQUFJLFNBQVMsR0FBRyxhQUFhLEtBQUssUUFBUSxlQUFlLElBQUksRUFBN0Q7QUFDQSxTQUFLLE9BQUwsQ0FBYSxTQUFi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LFVBQU0sSUFBSSxLQUFKLENBQVUseUJBQVYsQ0FBTjtBQUNEOztBQUVELEVBQUEsa0JBQWtCLENBQUMsWUFBRCxFQUF1QixRQUF2QixFQUE4QztBQUM5RCxVQUFNLElBQUksS0FBSixDQUFVLHlCQUFWLENBQU47QUFDRDs7QUFFRCxFQUFBLGVBQWUsQ0FBQyxZQUFELEVBQXVCLFFBQXZCLEVBQThDO0FBQzNELFVBQU0sSUFBSSxLQUFKLENBQVUseUJBQVYsQ0FBTjtBQUNEOztBQXZDbUI7O0FBMEN0QixTQUFTLFFBQVQsQ0FBNkMsT0FBQSxHQUFnQyxFQUE3RSxFQUErRTtBQUM3RSxFQUFBLE9BQU8sQ0FBQyxPQUFSLEdBQWtCLE9BQU8sQ0FBQyxPQUFSLElBQW1CLFVBQXJDO0FBQ0EsRUFBQSxPQUFPLENBQUMsTUFBUixHQUFpQixPQUFPLENBQUMsTUFBUixJQUFrQixrQkFBbkM7QUFDQSxFQUFBLE9BQU8sQ0FBQyxnQkFBUixHQUNFLE9BQU8sQ0FBQyxnQkFBUixJQUE2QixlQUQvQjtBQUdBLFNBQU8sSUFBSSxVQUFKLENBQWUsT0FBTyxDQUFDLE9BQXZCLEVBQWdDLE9BQWhDLENBQVA7QUFDRDs7UUFFUSxRLEdBQUEsUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZXNvbHZlciwgeyBCYXNpY01vZHVsZVJlZ2lzdHJ5LCBSZXNvbHZlckNvbmZpZ3VyYXRpb24gfSBmcm9tICdAZ2xpbW1lci9yZXNvbHZlcic7XG5pbXBvcnQgeyBEaWN0LCBNb2R1bGVMb2NhdG9yLCBUZW1wbGF0ZUxvY2F0b3IsIENvbXBvbmVudENhcGFiaWxpdGllcyB9IGZyb20gJ0BnbGltbWVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IGRlZmF1bHRSZXNvbHZlckNvbmZpZ3VyYXRpb24gZnJvbSAnLi9kZWZhdWx0LXJlc29sdmVyLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgcHJlY29tcGlsZSB9IGZyb20gJy4vY29tcGlsZXInO1xuaW1wb3J0IEFwcGxpY2F0aW9uLCB7XG4gIEFwcGxpY2F0aW9uQ29uc3RydWN0b3IsXG4gIEJ5dGVjb2RlTG9hZGVyLFxuICBET01CdWlsZGVyLFxuICBMb2FkZXIsXG4gIFJ1bnRpbWVDb21waWxlckxvYWRlcixcbiAgU3luY1JlbmRlcmVyLFxuICBNb2R1bGVUeXBlcyxcbiAgSU5URVJOQUxfRFlOQU1JQ19TQ09QRVxufSBmcm9tICdAZ2xpbW1lci9hcHBsaWNhdGlvbic7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IEJ1bmRsZUNvbXBpbGVyLCBDb21waWxlckRlbGVnYXRlIGFzIElDb21waWxlckRlbGVnYXRlIH0gZnJvbSAnQGdsaW1tZXIvYnVuZGxlLWNvbXBpbGVyJztcbmltcG9ydCB7IGJ1aWxkQWN0aW9uLCBtYWluVGVtcGxhdGUsIFJlbmRlcmVyLCBCeXRlY29kZU1ldGFkYXRhIH0gZnJvbSAnQGdsaW1tZXIvYXBwbGljYXRpb24nO1xuaW1wb3J0IHsgY29tcGlsYWJsZSB9IGZyb20gJ0BnbGltbWVyL29wY29kZS1jb21waWxlcic7XG5pbXBvcnQgeyBTaW1wbGVEb2N1bWVudCB9IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5pbXBvcnQgSFRNTFNlcmlhbGl6ZXIgZnJvbSAnQHNpbXBsZS1kb20vc2VyaWFsaXplcic7XG5pbXBvcnQgeyBTU1JBcHBsaWNhdGlvbiB9IGZyb20gJ0BnbGltbWVyL3Nzcic7XG5cbmltcG9ydCBkaWRSZW5kZXIgZnJvbSAnLi9kaWQtcmVuZGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBBcHBCdWlsZGVyT3B0aW9uczxUPiB7XG4gIGFwcE5hbWU/OiBzdHJpbmc7XG4gIGxvYWRlcj86IHN0cmluZztcbiAgQXBwbGljYXRpb25DbGFzcz86IEFwcGxpY2F0aW9uQ29uc3RydWN0b3I8VD47XG4gIENvbXBvbmVudE1hbmFnZXI/OiBhbnk7IC8vIFRPRE8gLSB0eXBpbmdcbiAgcmVzb2x2ZXJDb25maWd1cmF0aW9uPzogUmVzb2x2ZXJDb25maWd1cmF0aW9uO1xuICBkb2N1bWVudD86IFNpbXBsZURvY3VtZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudEZhY3Rvcnkge31cblxuZXhwb3J0IGNsYXNzIFRlc3RBcHBsaWNhdGlvbiBleHRlbmRzIEFwcGxpY2F0aW9uIHtcbiAgcm9vdEVsZW1lbnQ6IEVsZW1lbnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwQnVpbGRlclRlbXBsYXRlTWV0YSB7XG4gIHNwZWNpZmllcjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSGVscGVyRnVuY3Rpb24gZXh0ZW5kcyBGdW5jdGlvbiB7XG4gIGlzRmFjdG9yeT86IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBUZXN0U1NSQXBwbGljYXRpb25PcHRpb25zIHtcbiAgcm9vdE5hbWU/OiBzdHJpbmc7XG4gIHJlc29sdmVyPzogUmVzb2x2ZXI7XG4gIGxvYWRlcj86IExvYWRlcjtcbiAgcmVuZGVyZXI/OiBSZW5kZXJlcjtcbiAgc2VyaWFsaXplcj86IEhUTUxTZXJpYWxpemVyO1xuICBbSU5URVJOQUxfRFlOQU1JQ19TQ09QRV0/OiBEaWN0PHVua25vd24+O1xufVxuXG5mdW5jdGlvbiBsb2NhdG9yRm9yKG1vZHVsZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBUZW1wbGF0ZUxvY2F0b3I8TW9kdWxlTG9jYXRvcj4ge1xuICByZXR1cm4ge1xuICAgIGtpbmQ6ICd0ZW1wbGF0ZScsXG4gICAgbW9kdWxlLFxuICAgIG5hbWUsXG4gICAgbWV0YToge1xuICAgICAgbW9kdWxlLFxuICAgICAgbmFtZSxcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgQXBwQnVpbGRlcjxUIGV4dGVuZHMgVGVzdEFwcGxpY2F0aW9uPiB7XG4gIHJvb3ROYW1lOiBzdHJpbmc7XG4gIG1vZHVsZXM6IERpY3Q8dW5rbm93bj4gPSB7fTtcbiAgdGVtcGxhdGVzOiBEaWN0PHN0cmluZz4gPSB7fTtcbiAgb3B0aW9uczogQXBwQnVpbGRlck9wdGlvbnM8VD47XG5cbiAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCBvcHRpb25zOiBBcHBCdWlsZGVyT3B0aW9uczxUPikge1xuICAgIHRoaXMucm9vdE5hbWUgPSBuYW1lO1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy50ZW1wbGF0ZSgnTWFpbicsICc8ZGl2IC8+Jyk7XG4gICAgdGhpcy5oZWxwZXIoJ2FjdGlvbicsIGJ1aWxkQWN0aW9uLCB0cnVlKTtcbiAgfVxuXG4gIHRlbXBsYXRlKG5hbWU6IHN0cmluZywgdGVtcGxhdGU6IHN0cmluZykge1xuICAgIGFzc2VydChcbiAgICAgIG5hbWUuY2hhckF0KDApID09PSBuYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgJ3RlbXBsYXRlIG5hbWVzIG11c3Qgc3RhcnQgd2l0aCBhIGNhcGl0YWwgbGV0dGVyJ1xuICAgICk7XG5cbiAgICBsZXQgc3BlY2lmaWVyID0gYHRlbXBsYXRlOi8ke3RoaXMucm9vdE5hbWV9L2NvbXBvbmVudHMvJHtuYW1lfWA7XG4gICAgdGhpcy5tb2R1bGVzW3NwZWNpZmllcl0gPSBwcmVjb21waWxlKHRlbXBsYXRlLCB7IG1ldGE6IHsgc3BlY2lmaWVyIH0gfSk7XG4gICAgdGhpcy50ZW1wbGF0ZXNbc3BlY2lmaWVyXSA9IHRlbXBsYXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgY29tcG9uZW50KG5hbWU6IHN0cmluZywgY29tcG9uZW50RmFjdG9yeTogQ29tcG9uZW50RmFjdG9yeSkge1xuICAgIGxldCBzcGVjaWZpZXIgPSBgY29tcG9uZW50Oi8ke3RoaXMucm9vdE5hbWV9L2NvbXBvbmVudHMvJHtuYW1lfWA7XG4gICAgdGhpcy5tb2R1bGVzW3NwZWNpZmllcl0gPSBjb21wb25lbnRGYWN0b3J5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaGVscGVyKG5hbWU6IHN0cmluZywgaGVscGVyRnVuYzogSGVscGVyRnVuY3Rpb24sIGlzRmFjdG9yeSA9IGZhbHNlKSB7XG4gICAgbGV0IHNwZWNpZmllciA9IGBoZWxwZXI6LyR7dGhpcy5yb290TmFtZX0vY29tcG9uZW50cy8ke25hbWV9YDtcbiAgICBoZWxwZXJGdW5jLmlzRmFjdG9yeSA9IGlzRmFjdG9yeTtcbiAgICB0aGlzLm1vZHVsZXNbc3BlY2lmaWVyXSA9IGhlbHBlckZ1bmM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgYnVpbGRSZXNvbHZlcigpOiBSZXNvbHZlciB7XG4gICAgbGV0IHJlc29sdmVyQ29uZmlndXJhdGlvbiA9IHRoaXMub3B0aW9ucy5yZXNvbHZlckNvbmZpZ3VyYXRpb24gfHwgZGVmYXVsdFJlc29sdmVyQ29uZmlndXJhdGlvbjtcbiAgICByZXNvbHZlckNvbmZpZ3VyYXRpb24uYXBwID0gcmVzb2x2ZXJDb25maWd1cmF0aW9uLmFwcCB8fCB7XG4gICAgICBuYW1lOiB0aGlzLnJvb3ROYW1lLFxuICAgICAgcm9vdE5hbWU6IHRoaXMucm9vdE5hbWUsXG4gICAgfTtcblxuICAgIGxldCByZWdpc3RyeSA9IG5ldyBCYXNpY01vZHVsZVJlZ2lzdHJ5KHRoaXMubW9kdWxlcyk7XG4gICAgcmV0dXJuIG5ldyBSZXNvbHZlcihyZXNvbHZlckNvbmZpZ3VyYXRpb24sIHJlZ2lzdHJ5KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZFJ1bnRpbWVDb21waWxlckxvYWRlcigpOiBMb2FkZXIge1xuICAgIHJldHVybiBuZXcgUnVudGltZUNvbXBpbGVyTG9hZGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYnVpbGRCeXRlY29kZUxvYWRlcihyZXNvbHZlcjogUmVzb2x2ZXIpIHtcbiAgICBsZXQgZGVsZWdhdGUgPSBuZXcgQ29tcGlsZXJEZWxlZ2F0ZShyZXNvbHZlcik7XG4gICAgbGV0IGNvbXBpbGVyID0gbmV3IEJ1bmRsZUNvbXBpbGVyKGRlbGVnYXRlKTtcblxuICAgIGxldCBtYWluTG9jYXRvciA9IGxvY2F0b3JGb3IoJ3RlbXBsYXRlOm1haW5UZW1wbGF0ZScsICdkZWZhdWx0Jyk7XG4gICAgbWFpbkxvY2F0b3IubWV0YS5tb2R1bGUgPSAndGVtcGxhdGU6bWFpblRlbXBsYXRlJztcblxuICAgIGxldCBibG9jayA9IEpTT04ucGFyc2UobWFpblRlbXBsYXRlLmJsb2NrKTtcbiAgICBsZXQgY29tcGlsYWJsZVRlbXBsYXRlID0gY29tcGlsYWJsZSh7XG4gICAgICBibG9jayxcbiAgICAgIHJlZmVycmVyOiBtYWluTG9jYXRvci5tZXRhLFxuICAgIH0pO1xuXG4gICAgY29tcGlsZXIuYWRkQ29tcGlsYWJsZVRlbXBsYXRlKG1haW5Mb2NhdG9yLCBjb21waWxhYmxlVGVtcGxhdGUpO1xuXG4gICAgZm9yIChsZXQgbW9kdWxlIGluIHRoaXMudGVtcGxhdGVzKSB7XG4gICAgICBjb21waWxlci5hZGRUZW1wbGF0ZVNvdXJjZShsb2NhdG9yRm9yKG1vZHVsZSwgJ2RlZmF1bHQnKSwgdGhpcy50ZW1wbGF0ZXNbbW9kdWxlXSk7XG4gICAgfVxuXG4gICAgbGV0IHsgaGVhcCwgcG9vbCwgdGFibGUgfSA9IGNvbXBpbGVyLmNvbXBpbGUoKTtcblxuICAgIGxldCByZXNvbHZlclRhYmxlOiB1bmtub3duW10gPSBbXTtcblxuICAgIGxldCBtZXRhOiBEaWN0PEJ5dGVjb2RlTWV0YWRhdGE+ID0ge307XG5cbiAgICB0YWJsZS52bUhhbmRsZUJ5TW9kdWxlTG9jYXRvci5mb3JFYWNoKCh2bUhhbmRsZSwgbG9jYXRvcikgPT4ge1xuICAgICAgbGV0IGhhbmRsZSA9IHRhYmxlLmJ5TW9kdWxlTG9jYXRvci5nZXQobG9jYXRvcik7XG4gICAgICBsZXQgdGVtcGxhdGUgPSBjb21waWxlci5nZXRUZW1wbGF0ZShsb2NhdG9yKTtcblxuICAgICAgbWV0YVtsb2NhdG9yLm1vZHVsZV0gPSB7XG4gICAgICAgIHY6IHZtSGFuZGxlLFxuICAgICAgICBoOiBoYW5kbGUsXG4gICAgICAgIHNUOiB0ZW1wbGF0ZS5zeW1ib2xUYWJsZSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICB0YWJsZS5ieUhhbmRsZS5mb3JFYWNoKChsb2NhdG9yLCBoYW5kbGUpID0+IHtcbiAgICAgIGxldCBtb2R1bGUgPSBsb2NhdG9yLm1vZHVsZS5yZXBsYWNlKCd0ZW1wbGF0ZTovJywgJ2NvbXBvbmVudDovJyk7XG4gICAgICBpZiAodGhpcy5tb2R1bGVzW21vZHVsZV0pIHtcbiAgICAgICAgaWYgKG1vZHVsZS5pbmRleE9mKCdoZWxwZXI6JykgPT09IDApIHtcbiAgICAgICAgICBjb25zdCBtb2R1bGVUeXBlID0gKHRoaXMubW9kdWxlc1ttb2R1bGVdIGFzIEhlbHBlckZ1bmN0aW9uKS5pc0ZhY3RvcnkgPyBNb2R1bGVUeXBlcy5IRUxQRVJfRkFDVE9SWSA6IE1vZHVsZVR5cGVzLkhFTFBFUjtcbiAgICAgICAgICByZXNvbHZlclRhYmxlW2hhbmRsZV0gPSBbbW9kdWxlVHlwZSwgdGhpcy5tb2R1bGVzW21vZHVsZV1dO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc29sdmVyVGFibGVbaGFuZGxlXSA9IHRoaXMubW9kdWxlc1ttb2R1bGVdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgYnl0ZWNvZGUgPSBoZWFwLmJ1ZmZlcjtcbiAgICBsZXQgZGF0YSA9IHtcbiAgICAgIHByZWZpeDogJycsXG4gICAgICBtYWluRW50cnk6IHRhYmxlLnZtSGFuZGxlQnlNb2R1bGVMb2NhdG9yLmdldChtYWluTG9jYXRvciksXG4gICAgICBwb29sLFxuICAgICAgdGFibGU6IHJlc29sdmVyVGFibGUsXG4gICAgICBtZXRhLFxuICAgICAgaGVhcDoge1xuICAgICAgICB0YWJsZTogaGVhcC50YWJsZSxcbiAgICAgICAgaGFuZGxlOiBoZWFwLmhhbmRsZSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgQnl0ZWNvZGVMb2FkZXIoeyBieXRlY29kZSwgZGF0YSB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZExvYWRlcihyZXNvbHZlcik6IExvYWRlciB7XG4gICAgc3dpdGNoICh0aGlzLm9wdGlvbnMubG9hZGVyKSB7XG4gICAgICBjYXNlICdydW50aW1lLWNvbXBpbGVyJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRSdW50aW1lQ29tcGlsZXJMb2FkZXIoKTtcbiAgICAgIGNhc2UgJ2J5dGVjb2RlJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRCeXRlY29kZUxvYWRlcihyZXNvbHZlcik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBsb2FkZXIgJHt0aGlzLm9wdGlvbnMubG9hZGVyfWApO1xuICAgIH1cbiAgfVxuXG4gIHJlbmRlclRvU3RyaW5nKGNvbXBvbmVudE5hbWU6IHN0cmluZywgZGF0YTogRGljdDx1bmtub3duPiwgb3B0aW9ucz86IFRlc3RTU1JBcHBsaWNhdGlvbk9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHJlc29sdmVyID0gdGhpcy5idWlsZFJlc29sdmVyKCk7XG4gICAgbGV0IGxvYWRlciA9IHRoaXMuYnVpbGRMb2FkZXIocmVzb2x2ZXIpO1xuXG4gICAgcmV0dXJuIFNTUkFwcGxpY2F0aW9uLnJlbmRlclRvU3RyaW5nKGNvbXBvbmVudE5hbWUsIGRhdGEsIHtcbiAgICAgIHJvb3ROYW1lOiB0aGlzLnJvb3ROYW1lLFxuICAgICAgcmVzb2x2ZXIsXG4gICAgICBsb2FkZXIsXG4gICAgICByZW5kZXJlcjogbmV3IFN5bmNSZW5kZXJlcigpLFxuICAgICAgLi4ub3B0aW9uc1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgYm9vdCgpOiBQcm9taXNlPFQ+IHtcbiAgICBsZXQgcmVzb2x2ZXIgPSB0aGlzLmJ1aWxkUmVzb2x2ZXIoKTtcbiAgICBsZXQgbG9hZGVyOiBMb2FkZXIgPSB0aGlzLmJ1aWxkTG9hZGVyKHJlc29sdmVyKTtcblxuICAgIGxldCBkb2M6IERvY3VtZW50ID0gKHRoaXMub3B0aW9ucy5kb2N1bWVudCBhcyBEb2N1bWVudCkgfHwgZG9jdW1lbnQ7XG4gICAgbGV0IGVsZW1lbnQgPSBkb2MuYm9keTtcbiAgICBsZXQgYnVpbGRlciA9IG5ldyBET01CdWlsZGVyKHsgZWxlbWVudCB9KTtcbiAgICBsZXQgcmVuZGVyZXIgPSBuZXcgU3luY1JlbmRlcmVyKCk7XG5cbiAgICBsZXQgYXBwID0gbmV3IHRoaXMub3B0aW9ucy5BcHBsaWNhdGlvbkNsYXNzKHtcbiAgICAgIHJlc29sdmVyLFxuICAgICAgYnVpbGRlcixcbiAgICAgIGxvYWRlcixcbiAgICAgIHJlbmRlcmVyLFxuICAgICAgcm9vdE5hbWU6IHRoaXMucm9vdE5hbWUsXG4gICAgICBkb2N1bWVudDogdGhpcy5vcHRpb25zLmRvY3VtZW50LFxuICAgIH0pO1xuXG4gICAgbGV0IHJvb3RFbGVtZW50ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGFwcC5yb290RWxlbWVudCA9IHJvb3RFbGVtZW50O1xuICAgIGFwcC5yZW5kZXJDb21wb25lbnQoJ01haW4nLCByb290RWxlbWVudCk7XG4gICAgYXBwLmJvb3QoKTtcblxuICAgIGF3YWl0IGRpZFJlbmRlcihhcHApO1xuXG4gICAgcmV0dXJuIGFwcDtcbiAgfVxufVxuXG5jb25zdCBDQVBBQklMSVRJRVM6IENvbXBvbmVudENhcGFiaWxpdGllcyA9IHtcbiAgY3JlYXRlSW5zdGFuY2U6IHRydWUsXG4gIGR5bmFtaWNMYXlvdXQ6IGZhbHNlLFxuICBkeW5hbWljVGFnOiBmYWxzZSxcbiAgd3JhcHBlZDogZmFsc2UsXG4gIHByZXBhcmVBcmdzOiBmYWxzZSxcbiAgY3JlYXRlQXJnczogdHJ1ZSxcbiAgYXR0cmlidXRlSG9vazogZmFsc2UsXG4gIGVsZW1lbnRIb29rOiBmYWxzZSxcbiAgdXBkYXRlSG9vazogdHJ1ZSxcbiAgY3JlYXRlQ2FsbGVyOiBmYWxzZSxcbiAgZHluYW1pY1Njb3BlOiB0cnVlLFxufTtcblxuY2xhc3MgQ29tcGlsZXJEZWxlZ2F0ZSBpbXBsZW1lbnRzIElDb21waWxlckRlbGVnYXRlPE1vZHVsZUxvY2F0b3I+IHtcbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHJlc29sdmVyOiBSZXNvbHZlcikge31cblxuICBoYXNDb21wb25lbnRJblNjb3BlKG5hbWU6IHN0cmluZywgcmVmZXJyZXI6IE1vZHVsZUxvY2F0b3IpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnJlc29sdmVyLmlkZW50aWZ5KGB0ZW1wbGF0ZToke25hbWV9YCwgcmVmZXJyZXIubW9kdWxlKTtcbiAgfVxuXG4gIHJlc29sdmVDb21wb25lbnQobmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IE1vZHVsZUxvY2F0b3Ige1xuICAgIGxldCByZXNvbHZlZCA9IHRoaXMucmVzb2x2ZXIuaWRlbnRpZnkoYHRlbXBsYXRlOiR7bmFtZX1gLCByZWZlcnJlci5tb2R1bGUpO1xuICAgIHJldHVybiB7IG1vZHVsZTogcmVzb2x2ZWQsIG5hbWU6ICdkZWZhdWx0JyB9O1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50Q2FwYWJpbGl0aWVzKCkge1xuICAgIHJldHVybiBDQVBBQklMSVRJRVM7XG4gIH1cblxuICBoYXNIZWxwZXJJblNjb3BlKGhlbHBlck5hbWU6IHN0cmluZywgcmVmZXJyZXI6IE1vZHVsZUxvY2F0b3IpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnJlc29sdmVyLmlkZW50aWZ5KGBoZWxwZXI6JHtoZWxwZXJOYW1lfWAsIHJlZmVycmVyLm1vZHVsZSk7XG4gIH1cblxuICByZXNvbHZlSGVscGVyKGhlbHBlck5hbWU6IHN0cmluZywgcmVmZXJyZXI6IE1vZHVsZUxvY2F0b3IpOiBNb2R1bGVMb2NhdG9yIHtcbiAgICBsZXQgcmVzb2x2ZWQgPSB0aGlzLnJlc29sdmVyLmlkZW50aWZ5KGBoZWxwZXI6JHtoZWxwZXJOYW1lfWAsIHJlZmVycmVyLm1vZHVsZSk7XG4gICAgcmV0dXJuIHsgbW9kdWxlOiByZXNvbHZlZCwgbmFtZTogJ2RlZmF1bHQnIH07XG4gIH1cblxuICBoYXNQYXJ0aWFsSW5TY29wZShwYXJ0aWFsTmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIHJlc29sdmVQYXJ0aWFsKHBhcnRpYWxOYW1lOiBzdHJpbmcsIHJlZmVycmVyOiBNb2R1bGVMb2NhdG9yKTogTW9kdWxlTG9jYXRvciB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgaGFzTW9kaWZpZXJJblNjb3BlKG1vZGlmaWVyTmFtZTogc3RyaW5nLCByZWZlcnJlcjogTW9kdWxlTG9jYXRvcik6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIHJlc29sdmVNb2RpZmllcihtb2RpZmllck5hbWU6IHN0cmluZywgcmVmZXJyZXI6IE1vZHVsZUxvY2F0b3IpOiBNb2R1bGVMb2NhdG9yIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYnVpbGRBcHA8VCBleHRlbmRzIFRlc3RBcHBsaWNhdGlvbj4ob3B0aW9uczogQXBwQnVpbGRlck9wdGlvbnM8VD4gPSB7fSk6IEFwcEJ1aWxkZXI8VD4ge1xuICBvcHRpb25zLmFwcE5hbWUgPSBvcHRpb25zLmFwcE5hbWUgfHwgJ3Rlc3QtYXBwJztcbiAgb3B0aW9ucy5sb2FkZXIgPSBvcHRpb25zLmxvYWRlciB8fCAncnVudGltZS1jb21waWxlcic7XG4gIG9wdGlvbnMuQXBwbGljYXRpb25DbGFzcyA9XG4gICAgb3B0aW9ucy5BcHBsaWNhdGlvbkNsYXNzIHx8IChUZXN0QXBwbGljYXRpb24gYXMgQXBwbGljYXRpb25Db25zdHJ1Y3RvcjxUPik7XG5cbiAgcmV0dXJuIG5ldyBBcHBCdWlsZGVyKG9wdGlvbnMuYXBwTmFtZSwgb3B0aW9ucyk7XG59XG5cbmV4cG9ydCB7IGJ1aWxkQXBwIH07XG4iXSwic291cmNlUm9vdCI6IiJ9