UNPKG

ngx-dynamic-hooks

Version:

Automatically insert live Angular components into a dynamic string of content (based on their selector or any pattern of your choice) and render the result in the DOM.

154 lines 20.8 kB
import { NgZone, createEnvironmentInjector } from '@angular/core'; import { createApplication } from '@angular/platform-browser'; import { firstValueFrom } from 'rxjs'; import { DynamicHooksService } from './services/dynamicHooksService'; // Global state // ---------- let sharedInjector = null; let scopes = []; let allParseResults = []; const createInjector = async (providers = [], parent) => { // If no parent, create new root injector, so passed providers will also be actual root providers return parent ? createEnvironmentInjector(providers, parent) : (await createApplication({ providers })).injector; }; /** * Destroys all scopes and components created by standalone mode */ export const destroyAll = () => { // Destroy all scopes for (const scope of scopes) { scope.destroy(); } // Then all remaining independent parseResults for (const parseResult of allParseResults) { parseResult.destroy(); } sharedInjector = null; scopes = []; allParseResults = []; }; // Providers scope // ---------- /** * Creates an isolated scope with its own providers that the dynamically-created components will then have access to. * * @param providers - A list of providers * @param parentScope - An optional parent scope created previously. Makes the parent providers also accessible to this scope. */ export const createProviders = (providers = [], parentScope) => { return new ProvidersScope(providers, parentScope); }; /** * A scope with an internal list of providers. All dynamic components created by its `parse` method will have access to them. */ export class ProvidersScope { get injector() { return this._injector; } ; get parseResults() { return this._parseResults; } ; get isDestroyed() { return this._isDestroyed; } ; constructor(providers = [], parentScope) { this.providers = providers; this.parentScope = parentScope; this._injector = null; this._parseResults = []; this._isDestroyed = false; scopes.push(this); } /** * Parses content and loads components for all found hooks in standalone mode * * @param content - The content to parse * @param parsers - The parsers to use * @param context - An optional context object * @param options - An optional list of options * @param targetElement - An optional HTML element to use as the container for the loaded content. * @param targetHookIndex - An optional object to fill with the programmatic hook data. If none is provided, one is created and returned for you. * @param environmentInjector - An optional environmentInjector to use for the dynamically-loaded components. If none is provided, the default environmentInjector is used. */ async parse(content, parsers, context = null, options = null, targetElement = null, targetHookIndex = {}, environmentInjector = null) { this.checkIfDestroyed(); return parse(content, parsers, context, options, targetElement, targetHookIndex, environmentInjector || await this.resolveInjector()) .then(parseResult => { this.parseResults.push(parseResult); return parseResult; }); } /** * Returns the injector for this scope */ async resolveInjector() { this.checkIfDestroyed(); if (!this.injector) { const parentInjector = this.parentScope ? await this.parentScope.resolveInjector() : undefined; this._injector = await createInjector(this.providers, parentInjector); } return this.injector; } /** * Destroys this scope and all of its created components */ destroy() { this.checkIfDestroyed(); for (const parseResult of this.parseResults) { parseResult.destroy(); allParseResults = allParseResults.filter(entry => entry !== parseResult); } if (this.injector) { this.injector.destroy(); } scopes = scopes.filter(scope => scope !== this); this._isDestroyed = true; } checkIfDestroyed() { if (this.isDestroyed) { throw new Error('This scope has already been destroyed. It or its methods cannot be used any longer.'); } } } // parse // ---------- /** * Parses content and loads components for all found hooks in standalone mode * * @param content - The content to parse * @param parsers - The parsers to use * @param context - An optional context object * @param options - An optional list of options * @param targetElement - An optional HTML element to use as the container for the loaded content. * @param targetHookIndex - An optional object to fill with the programmatic hook data. If none is provided, one is created and returned for you. * @param environmentInjector - An optional environmentInjector to use for the dynamically-loaded components. If none is provided, the default environmentInjector is used. */ export const parse = async (content, parsers, context = null, options = null, targetElement = null, targetHookIndex = {}, environmentInjector = null) => { // Reuse the same global injector for all independent parse calls if (!environmentInjector) { if (!sharedInjector) { sharedInjector = await createInjector(); } environmentInjector = sharedInjector; } // In standalone mode, emit HTML events from outputs by default if (!options) { options = {}; } if (!options.hasOwnProperty('triggerDOMEvents')) { options.triggerDOMEvents = true; } const dynHooksService = environmentInjector.get(DynamicHooksService); // Needs to be run inside NgZone manually return environmentInjector.get(NgZone).run(() => { return firstValueFrom(dynHooksService .parse(content, parsers, context, options, null, null, targetElement, targetHookIndex, environmentInjector, null)).then(parseResult => { allParseResults.push(parseResult); return parseResult; }); }); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1keW5hbWljLWhvb2tzL3NyYy9saWIvc3RhbmRhbG9uZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTZDLE1BQU0sRUFBWSx5QkFBeUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBS3RDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRXJFLGVBQWU7QUFDZixhQUFhO0FBRWIsSUFBSSxjQUFjLEdBQTZCLElBQUksQ0FBQztBQUNwRCxJQUFJLE1BQU0sR0FBcUIsRUFBRSxDQUFDO0FBQ2xDLElBQUksZUFBZSxHQUFrQixFQUFFLENBQUM7QUFFeEMsTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLFlBQWlELEVBQUUsRUFBRSxNQUE0QixFQUFFLEVBQUU7SUFDakgsaUdBQWlHO0lBQ2pHLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxpQkFBaUIsQ0FBQyxFQUFDLFNBQVMsRUFBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7QUFDakgsQ0FBQyxDQUFBO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxFQUFFO0lBQzdCLHFCQUFxQjtJQUNyQixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsOENBQThDO0lBQzlDLEtBQUssTUFBTSxXQUFXLElBQUksZUFBZSxFQUFFLENBQUM7UUFDMUMsV0FBVyxDQUFDLE9B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QUFPLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO1FBQzlDLE9BQU8sY0FBYyxDQUFDLGVBQWU7YUFDbEMsS0FBSyxDQUNKLE9BQU8sRUFDUCxPQUFPLEVBQ1AsT0FBTyxFQUNQLE9BQU8sRUFDUCxJQUFJLEVBQ0osSUFBSSxFQUNKLGFBQWEsRUFDYixlQUFlLEVBQ2YsbUJBQW1CLEVBQ25CLElBQUksQ0FDTCxDQUNGLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ25CLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEMsT0FBTyxXQUFXLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVudmlyb25tZW50SW5qZWN0b3IsIEVudmlyb25tZW50UHJvdmlkZXJzLCBOZ1pvbmUsIFByb3ZpZGVyLCBjcmVhdGVFbnZpcm9ubWVudEluamVjdG9yIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjcmVhdGVBcHBsaWNhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSG9va1BhcnNlckVudHJ5IH0gZnJvbSAnLi9zZXJ2aWNlcy9zZXR0aW5ncy9wYXJzZXJFbnRyeSc7XG5pbXBvcnQgeyBQYXJzZU9wdGlvbnMgfSBmcm9tICcuL3NlcnZpY2VzL3NldHRpbmdzL29wdGlvbnMnO1xuaW1wb3J0IHsgSG9va0luZGV4LCBQYXJzZVJlc3VsdCB9IGZyb20gJy4vaW50ZXJmYWNlc1B1YmxpYyc7XG5pbXBvcnQgeyBEeW5hbWljSG9va3NTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9keW5hbWljSG9va3NTZXJ2aWNlJztcblxuLy8gR2xvYmFsIHN0YXRlXG4vLyAtLS0tLS0tLS0tXG5cbmxldCBzaGFyZWRJbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcnxudWxsID0gbnVsbDtcbmxldCBzY29wZXM6IFByb3ZpZGVyc1Njb3BlW10gPSBbXTtcbmxldCBhbGxQYXJzZVJlc3VsdHM6IFBhcnNlUmVzdWx0W10gPSBbXTtcblxuY29uc3QgY3JlYXRlSW5qZWN0b3IgPSBhc3luYyAocHJvdmlkZXJzOiAoUHJvdmlkZXIgfCBFbnZpcm9ubWVudFByb3ZpZGVycylbXSA9IFtdLCBwYXJlbnQ/OiBFbnZpcm9ubWVudEluamVjdG9yKSA9PiB7XG4gIC8vIElmIG5vIHBhcmVudCwgY3JlYXRlIG5ldyByb290IGluamVjdG9yLCBzbyBwYXNzZWQgcHJvdmlkZXJzIHdpbGwgYWxzbyBiZSBhY3R1YWwgcm9vdCBwcm92aWRlcnNcbiAgcmV0dXJuIHBhcmVudCA/IGNyZWF0ZUVudmlyb25tZW50SW5qZWN0b3IocHJvdmlkZXJzLCBwYXJlbnQpIDogKGF3YWl0IGNyZWF0ZUFwcGxpY2F0aW9uKHtwcm92aWRlcnN9KSkuaW5qZWN0b3I7XG59XG5cbi8qKlxuICogRGVzdHJveXMgYWxsIHNjb3BlcyBhbmQgY29tcG9uZW50cyBjcmVhdGVkIGJ5IHN0YW5kYWxvbmUgbW9kZVxuICovXG5leHBvcnQgY29uc3QgZGVzdHJveUFsbCA9ICgpID0+IHtcbiAgLy8gRGVzdHJveSBhbGwgc2NvcGVzXG4gIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKSB7XG4gICAgc2NvcGUuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gVGhlbiBhbGwgcmVtYWluaW5nIGluZGVwZW5kZW50IHBhcnNlUmVzdWx0c1xuICBmb3IgKGNvbnN0IHBhcnNlUmVzdWx0IG9mIGFsbFBhcnNlUmVzdWx0cykge1xuICAgIHBhcnNlUmVzdWx0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIHNoYXJlZEluamVjdG9yID0gbnVsbDtcbiAgc2NvcGVzID0gW107XG4gIGFsbFBhcnNlUmVzdWx0cyA9IFtdO1xufVxuXG4vLyBQcm92aWRlcnMgc2NvcGVcbi8vIC0tLS0tLS0tLS1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGlzb2xhdGVkIHNjb3BlIHdpdGggaXRzIG93biBwcm92aWRlcnMgdGhhdCB0aGUgZHluYW1pY2FsbHktY3JlYXRlZCBjb21wb25lbnRzIHdpbGwgdGhlbiBoYXZlIGFjY2VzcyB0by5cbiAqIFxuICogQHBhcmFtIHByb3ZpZGVycyAtIEEgbGlzdCBvZiBwcm92aWRlcnNcbiAqIEBwYXJhbSBwYXJlbnRTY29wZSAtIEFuIG9wdGlvbmFsIHBhcmVudCBzY29wZSBjcmVhdGVkIHByZXZpb3VzbHkuIE1ha2VzIHRoZSBwYXJlbnQgcHJvdmlkZXJzIGFsc28gYWNjZXNzaWJsZSB0byB0aGlzIHNjb3BlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlUHJvdmlkZXJzID0gKHByb3ZpZGVyczogKFByb3ZpZGVyIHwgRW52aXJvbm1lbnRQcm92aWRlcnMpW10gPSBbXSwgcGFyZW50U2NvcGU/OiBQcm92aWRlcnNTY29wZSk6IFByb3ZpZGVyc1Njb3BlID0+IHtcbiAgcmV0dXJuIG5ldyBQcm92aWRlcnNTY29wZShwcm92aWRlcnMsIHBhcmVudFNjb3BlKTtcbn1cblxuLyoqXG4gKiBBIHNjb3BlIHdpdGggYW4gaW50ZXJuYWwgbGlzdCBvZiBwcm92aWRlcnMuIEFsbCBkeW5hbWljIGNvbXBvbmVudHMgY3JlYXRlZCBieSBpdHMgYHBhcnNlYCBtZXRob2Qgd2lsbCBoYXZlIGFjY2VzcyB0byB0aGVtLlxuICovXG5leHBvcnQgY2xhc3MgUHJvdmlkZXJzU2NvcGUge1xuICBwcml2YXRlIF9pbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcnxudWxsID0gbnVsbDtcbiAgcHVibGljIGdldCBpbmplY3RvcigpOiBFbnZpcm9ubWVudEluamVjdG9yfG51bGwgeyBcbiAgICByZXR1cm4gdGhpcy5faW5qZWN0b3I7XG4gIH07XG4gIHByaXZhdGUgX3BhcnNlUmVzdWx0czogUGFyc2VSZXN1bHRbXSA9IFtdO1xuICBwdWJsaWMgZ2V0IHBhcnNlUmVzdWx0cygpOiBQYXJzZVJlc3VsdFtdIHsgXG4gICAgcmV0dXJuIHRoaXMuX3BhcnNlUmVzdWx0cztcbiAgfTtcbiAgcHJpdmF0ZSBfaXNEZXN0cm95ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgZ2V0IGlzRGVzdHJveWVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pc0Rlc3Ryb3llZDtcbiAgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHByb3ZpZGVyczogKFByb3ZpZGVyIHwgRW52aXJvbm1lbnRQcm92aWRlcnMpW10gPSBbXSwgcHJpdmF0ZSBwYXJlbnRTY29wZT86IFByb3ZpZGVyc1Njb3BlKSB7XG4gICAgc2NvcGVzLnB1c2godGhpcyk7XG4gIH1cblxuICAvKipcbiAgKiBQYXJzZXMgY29udGVudCBhbmQgbG9hZHMgY29tcG9uZW50cyBmb3IgYWxsIGZvdW5kIGhvb2tzIGluIHN0YW5kYWxvbmUgbW9kZVxuICAqIFxuICAqIEBwYXJhbSBjb250ZW50IC0gVGhlIGNvbnRlbnQgdG8gcGFyc2VcbiAgKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIHRvIHVzZVxuICAqIEBwYXJhbSBjb250ZXh0IC0gQW4gb3B0aW9uYWwgY29udGV4dCBvYmplY3RcbiAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIGxpc3Qgb2Ygb3B0aW9uc1xuICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IC0gQW4gb3B0aW9uYWwgSFRNTCBlbGVtZW50IHRvIHVzZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gICogQHBhcmFtIHRhcmdldEhvb2tJbmRleCAtIEFuIG9wdGlvbmFsIG9iamVjdCB0byBmaWxsIHdpdGggdGhlIHByb2dyYW1tYXRpYyBob29rIGRhdGEuIElmIG5vbmUgaXMgcHJvdmlkZWQsIG9uZSBpcyBjcmVhdGVkIGFuZCByZXR1cm5lZCBmb3IgeW91LlxuICAqIEBwYXJhbSBlbnZpcm9ubWVudEluamVjdG9yIC0gQW4gb3B0aW9uYWwgZW52aXJvbm1lbnRJbmplY3RvciB0byB1c2UgZm9yIHRoZSBkeW5hbWljYWxseS1sb2FkZWQgY29tcG9uZW50cy4gSWYgbm9uZSBpcyBwcm92aWRlZCwgdGhlIGRlZmF1bHQgZW52aXJvbm1lbnRJbmplY3RvciBpcyB1c2VkLlxuICAqL1xuICBwdWJsaWMgYXN5bmMgcGFyc2UoXG4gICAgY29udGVudDogYW55LFxuICAgIHBhcnNlcnM6IEhvb2tQYXJzZXJFbnRyeVtdLFxuICAgIGNvbnRleHQ6IGFueSA9IG51bGwsICBcbiAgICBvcHRpb25zOiBQYXJzZU9wdGlvbnN8bnVsbCA9IG51bGwsXG4gICAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnR8bnVsbCA9IG51bGwsXG4gICAgdGFyZ2V0SG9va0luZGV4OiBIb29rSW5kZXggPSB7fSxcbiAgICBlbnZpcm9ubWVudEluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yfG51bGwgPSBudWxsXG4gICk6IFByb21pc2U8UGFyc2VSZXN1bHQ+IHtcbiAgICB0aGlzLmNoZWNrSWZEZXN0cm95ZWQoKTtcblxuICAgIHJldHVybiBwYXJzZShjb250ZW50LCBwYXJzZXJzLCBjb250ZXh0LCBvcHRpb25zLCAgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0SG9va0luZGV4LCBlbnZpcm9ubWVudEluamVjdG9yIHx8IGF3YWl0IHRoaXMucmVzb2x2ZUluamVjdG9yKCkpXG4gICAgLnRoZW4ocGFyc2VSZXN1bHQgPT4ge1xuICAgICAgdGhpcy5wYXJzZVJlc3VsdHMucHVzaChwYXJzZVJlc3VsdCk7XG4gICAgICByZXR1cm4gcGFyc2VSZXN1bHQ7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaW5qZWN0b3IgZm9yIHRoaXMgc2NvcGVcbiAgICovXG4gIHB1YmxpYyBhc3luYyByZXNvbHZlSW5qZWN0b3IoKSB7XG4gICAgdGhpcy5jaGVja0lmRGVzdHJveWVkKCk7XG5cbiAgICBpZiAoIXRoaXMuaW5qZWN0b3IpIHtcbiAgICAgIGNvbnN0IHBhcmVudEluamVjdG9yID0gdGhpcy5wYXJlbnRTY29wZSA/IGF3YWl0IHRoaXMucGFyZW50U2NvcGUucmVzb2x2ZUluamVjdG9yKCkgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9pbmplY3RvciA9IGF3YWl0IGNyZWF0ZUluamVjdG9yKHRoaXMucHJvdmlkZXJzLCBwYXJlbnRJbmplY3Rvcik7XG4gICAgfVxuICBcbiAgICByZXR1cm4gdGhpcy5pbmplY3RvciE7XG4gIH1cblxuICAvKipcbiAgICogRGVzdHJveXMgdGhpcyBzY29wZSBhbmQgYWxsIG9mIGl0cyBjcmVhdGVkIGNvbXBvbmVudHNcbiAgICovXG4gIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tJZkRlc3Ryb3llZCgpO1xuXG4gICAgZm9yIChjb25zdCBwYXJzZVJlc3VsdCBvZiB0aGlzLnBhcnNlUmVzdWx0cykge1xuICAgICAgcGFyc2VSZXN1bHQuZGVzdHJveSgpO1xuICAgICAgYWxsUGFyc2VSZXN1bHRzID0gYWxsUGFyc2VSZXN1bHRzLmZpbHRlcihlbnRyeSA9PiBlbnRyeSAhPT0gcGFyc2VSZXN1bHQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmluamVjdG9yKSB7XG4gICAgICB0aGlzLmluamVjdG9yLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBzY29wZXMgPSBzY29wZXMuZmlsdGVyKHNjb3BlID0+IHNjb3BlICE9PSB0aGlzKTtcbiAgICB0aGlzLl9pc0Rlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSWZEZXN0cm95ZWQoKSB7XG4gICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhpcyBzY29wZSBoYXMgYWxyZWFkeSBiZWVuIGRlc3Ryb3llZC4gSXQgb3IgaXRzIG1ldGhvZHMgY2Fubm90IGJlIHVzZWQgYW55IGxvbmdlci4nKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gcGFyc2Vcbi8vIC0tLS0tLS0tLS1cblxuLyoqXG4gKiBQYXJzZXMgY29udGVudCBhbmQgbG9hZHMgY29tcG9uZW50cyBmb3IgYWxsIGZvdW5kIGhvb2tzIGluIHN0YW5kYWxvbmUgbW9kZVxuICogXG4gKiBAcGFyYW0gY29udGVudCAtIFRoZSBjb250ZW50IHRvIHBhcnNlXG4gKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIHRvIHVzZVxuICogQHBhcmFtIGNvbnRleHQgLSBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdFxuICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBsaXN0IG9mIG9wdGlvbnNcbiAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IC0gQW4gb3B0aW9uYWwgSFRNTCBlbGVtZW50IHRvIHVzZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gKiBAcGFyYW0gdGFyZ2V0SG9va0luZGV4IC0gQW4gb3B0aW9uYWwgb2JqZWN0IHRvIGZpbGwgd2l0aCB0aGUgcHJvZ3JhbW1hdGljIGhvb2sgZGF0YS4gSWYgbm9uZSBpcyBwcm92aWRlZCwgb25lIGlzIGNyZWF0ZWQgYW5kIHJldHVybmVkIGZvciB5b3UuXG4gKiBAcGFyYW0gZW52aXJvbm1lbnRJbmplY3RvciAtIEFuIG9wdGlvbmFsIGVudmlyb25tZW50SW5qZWN0b3IgdG8gdXNlIGZvciB0aGUgZHluYW1pY2FsbHktbG9hZGVkIGNvbXBvbmVudHMuIElmIG5vbmUgaXMgcHJvdmlkZWQsIHRoZSBkZWZhdWx0IGVudmlyb25tZW50SW5qZWN0b3IgaXMgdXNlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHBhcnNlID0gYXN5bmMgKFxuICBjb250ZW50OiBhbnksXG4gIHBhcnNlcnM6IEhvb2tQYXJzZXJFbnRyeVtdLFxuICBjb250ZXh0OiBhbnkgPSBudWxsLCAgXG4gIG9wdGlvbnM6IFBhcnNlT3B0aW9uc3xudWxsID0gbnVsbCxcbiAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnR8bnVsbCA9IG51bGwsXG4gIHRhcmdldEhvb2tJbmRleDogSG9va0luZGV4ID0ge30sXG4gIGVudmlyb25tZW50SW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3J8bnVsbCA9IG51bGwsXG4pOiBQcm9taXNlPFBhcnNlUmVzdWx0PiA9PiB7XG5cbiAgLy8gUmV1c2UgdGhlIHNhbWUgZ2xvYmFsIGluamVjdG9yIGZvciBhbGwgaW5kZXBlbmRlbnQgcGFyc2UgY2FsbHNcbiAgaWYgKCFlbnZpcm9ubWVudEluamVjdG9yKSB7XG4gICAgaWYgKCFzaGFyZWRJbmplY3Rvcikge1xuICAgICAgc2hhcmVkSW5qZWN0b3IgPSBhd2FpdCBjcmVhdGVJbmplY3RvcigpO1xuICAgIH1cbiAgICBlbnZpcm9ubWVudEluamVjdG9yID0gc2hhcmVkSW5qZWN0b3I7XG4gIH1cblxuICAvLyBJbiBzdGFuZGFsb25lIG1vZGUsIGVtaXQgSFRNTCBldmVudHMgZnJvbSBvdXRwdXRzIGJ5IGRlZmF1bHRcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cbiAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCd0cmlnZ2VyRE9NRXZlbnRzJykpIHtcbiAgICBvcHRpb25zLnRyaWdnZXJET01FdmVudHMgPSB0cnVlO1xuICB9XG5cbiAgY29uc3QgZHluSG9va3NTZXJ2aWNlID0gZW52aXJvbm1lbnRJbmplY3Rvci5nZXQoRHluYW1pY0hvb2tzU2VydmljZSk7XG5cbiAgLy8gTmVlZHMgdG8gYmUgcnVuIGluc2lkZSBOZ1pvbmUgbWFudWFsbHlcbiAgcmV0dXJuIGVudmlyb25tZW50SW5qZWN0b3IuZ2V0KE5nWm9uZSkucnVuKCgpID0+IHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZUZyb20oZHluSG9va3NTZXJ2aWNlXG4gICAgICAucGFyc2UoXG4gICAgICAgIGNvbnRlbnQsIFxuICAgICAgICBwYXJzZXJzLFxuICAgICAgICBjb250ZXh0LCBcbiAgICAgICAgb3B0aW9ucywgXG4gICAgICAgIG51bGwsIFxuICAgICAgICBudWxsLFxuICAgICAgICB0YXJnZXRFbGVtZW50LCBcbiAgICAgICAgdGFyZ2V0SG9va0luZGV4LCBcbiAgICAgICAgZW52aXJvbm1lbnRJbmplY3RvcixcbiAgICAgICAgbnVsbFxuICAgICAgKVxuICAgICkudGhlbihwYXJzZVJlc3VsdCA9PiB7XG4gICAgICBhbGxQYXJzZVJlc3VsdHMucHVzaChwYXJzZVJlc3VsdCk7XG4gICAgICByZXR1cm4gcGFyc2VSZXN1bHQ7XG4gICAgfSk7XG4gIH0pO1xufSJdfQ==