UNPKG

@hapiness/ng-elements-loader

Version:

Service to load Angular Custom Elements inside Angular's applications

274 lines (268 loc) 35.3 kB
import { Compiler, ComponentFactoryResolver, Injectable, Injector, defineInjectable, inject, INJECTOR } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { forkJoin, from, merge, of, throwError } from 'rxjs'; import { filter, flatMap, map, tap, toArray } from 'rxjs/operators'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var ElementsLoaderService = /** @class */ (function () { function ElementsLoaderService(_injector, _compiler, _componentFactoryResolver) { this._injector = _injector; this._compiler = _compiler; this._componentFactoryResolver = _componentFactoryResolver; this._elementsToLoad = new Map(); } /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Compile the module and its component * to be registered as custom elements. * This function is used in JIT mode */ /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Compile the module and its component * to be registered as custom elements. * This function is used in JIT mode * @param {?} data * @return {?} */ ElementsLoaderService.prototype.loadContainingCustomElements = /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Compile the module and its component * to be registered as custom elements. * This function is used in JIT mode * @param {?} data * @return {?} */ function (data) { var _this = this; return of(data) .pipe(flatMap(function (_) { return !!_ ? of([].concat(_)) : throwError(new Error('Parameter must be a `CustomElementModuleSelector` or an array of it')); }), flatMap(function (_) { return !!_.length ? of(_) : throwError(new Error('`CustomElementModuleSelector` array must have at least one element')); }), flatMap(function (_) { return from(_); }), filter(function (_) { return !!_.selector && !!_.module; }), toArray(), tap(function (_) { return _.forEach(function (e) { return _this._elementsToLoad.set(e.selector, e.module); }); }), flatMap(function () { return _this._customElements(true); })); }; /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Component will be registered as * custom elements. * This function is used in AOT mode */ /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Component will be registered as * custom elements. * This function is used in AOT mode * @param {?} data * @return {?} */ ElementsLoaderService.prototype.registerContainingCustomElements = /** * Queries the document element for any custom elements that have not yet been registered with * the browser. Custom elements that are registered will be removed from the list of unregistered * elements so that they will not be queried in subsequent calls. Component will be registered as * custom elements. * This function is used in AOT mode * @param {?} data * @return {?} */ function (data) { var _this = this; return of(data) .pipe(flatMap(function (_) { return !!_ ? of([].concat(_)) : throwError(new Error('Parameter must be a `CustomElementComponentSelector` or an array of it')); }), flatMap(function (_) { return !!_.length ? of(_) : throwError(new Error('`CustomElementComponentSelector` array must have at least one element')); }), flatMap(function (_) { return from(_); }), filter(function (_) { return !!_.selector && !!_.component; }), toArray(), tap(function (_) { return _.forEach(function (e) { return _this._elementsToLoad.set(e.selector, e.component); }); }), flatMap(function () { return _this._customElements(false); })); }; /** * Main process to load custom elements */ /** * Main process to load custom elements * @private * @param {?} compileModuleAndAllComponents * @return {?} */ ElementsLoaderService.prototype._customElements = /** * Main process to load custom elements * @private * @param {?} compileModuleAndAllComponents * @return {?} */ function (compileModuleAndAllComponents) { var _this = this; return of(of(Array.from(this._elementsToLoad.keys()))) .pipe(flatMap(function (obs) { return merge(obs.pipe(filter(function (_) { return !!_ && !!_.length; }), flatMap(function (_) { return forkJoin(_.map(function (s) { return _this._register(s, compileModuleAndAllComponents); })); })), obs.pipe(filter(function (_) { return !_ || !_.length; }), map(function (_) { return (/** @type {?} */ (undefined)); }))); })); }; /** * Registers the custom element defined on the WithCustomElement module factory */ /** * Registers the custom element defined on the WithCustomElement module factory * @private * @param {?} selector * @param {?} compileModuleAndAllComponents * @return {?} */ ElementsLoaderService.prototype._register = /** * Registers the custom element defined on the WithCustomElement module factory * @private * @param {?} selector * @param {?} compileModuleAndAllComponents * @return {?} */ function (selector, compileModuleAndAllComponents) { var _this = this; return of(of(this._elementsToLoad.has(selector))) .pipe(flatMap(function (obs) { return merge(obs .pipe(filter(function (_) { return !!_; }), // selector inside elements to load flatMap(function (_) { return of(of(customElements.get(selector))) .pipe(flatMap(function (o) { return merge(o.pipe(filter(function (__) { return !!__; }), // selector already loaded tap(function (__) { return _this._elementsToLoad.delete(selector); }) // so delete it ), o.pipe(filter(function (__) { return !__; }), // selector never loaded flatMap(function (__) { return _this._createCustomElement(selector, compileModuleAndAllComponents); }) // so create custom element )); })); })), obs .pipe(filter(function (_) { return !_; }), // selector not in elements to load map(function (_) { return (/** @type {?} */ (undefined)); }))); })); }; /** * Create custom element for current selector */ /** * Create custom element for current selector * @private * @param {?} selector * @param {?} compileModuleAndAllComponents * @return {?} */ ElementsLoaderService.prototype._createCustomElement = /** * Create custom element for current selector * @private * @param {?} selector * @param {?} compileModuleAndAllComponents * @return {?} */ function (selector, compileModuleAndAllComponents) { var _this = this; return of(of(compileModuleAndAllComponents)) .pipe(flatMap(function (obs) { return merge(obs.pipe(filter(function (_) { return !!_; }), flatMap(function (_) { return _this._componentAndInjectorFromCompiledModule((/** @type {?} */ (_this._elementsToLoad.get(selector)))); })), obs.pipe(filter(function (_) { return !_; }), flatMap(function (_) { return _this._componentAndInjectorFromComponentFactory((/** @type {?} */ (_this._elementsToLoad.get(selector)))); }))); }), map(function (_) { return createCustomElement(_.component, { injector: _.injector }); }), tap(function (customElement) { return (/** @type {?} */ (customElements)).define(selector, customElement); }), tap(function (_) { return _this._elementsToLoad.delete(selector); }), flatMap(function (_) { return from(customElements.whenDefined(selector)); })); }; /** * Compile module and all components to retrieve the component and the injector for custom element creation. * This function is only used in JIT mode. */ /** * Compile module and all components to retrieve the component and the injector for custom element creation. * This function is only used in JIT mode. * @private * @param {?} elementModule * @return {?} */ ElementsLoaderService.prototype._componentAndInjectorFromCompiledModule = /** * Compile module and all components to retrieve the component and the injector for custom element creation. * This function is only used in JIT mode. * @private * @param {?} elementModule * @return {?} */ function (elementModule) { var _this = this; return from(this._compiler.compileModuleAndAllComponentsAsync(elementModule)) .pipe(map(function (moduleWithComponentFactories) { return moduleWithComponentFactories.ngModuleFactory; }), map(function (elementModuleFactory) { return elementModuleFactory.create(_this._injector); }), flatMap(function (elementModuleRef) { return !!elementModuleRef.instance.customElementComponent ? of((/** @type {?} */ ({ component: elementModuleRef.instance.customElementComponent, injector: elementModuleRef.injector }))) : throwError(new Error('WithCustomElementComponent interface must' + ' be implemented by all modules that declare a component that can be used as a custom element.')); })); }; /** * Resolve component to get module injector for custom element creation. * This function is only used in AOT mode. */ /** * Resolve component to get module injector for custom element creation. * This function is only used in AOT mode. * @private * @template T * @param {?} elementComponent * @return {?} */ ElementsLoaderService.prototype._componentAndInjectorFromComponentFactory = /** * Resolve component to get module injector for custom element creation. * This function is only used in AOT mode. * @private * @template T * @param {?} elementComponent * @return {?} */ function (elementComponent) { return of(this._componentFactoryResolver.resolveComponentFactory(elementComponent)) .pipe(map(function (componentFactory) { return componentFactory.ngModule; }), map(function (elementModuleRef) { return (/** @type {?} */ (({ component: elementComponent, injector: elementModuleRef.injector }))); })); }; ElementsLoaderService.decorators = [ { type: Injectable, args: [(/** @type {?} */ ({ providedIn: 'root' })),] } ]; /** @nocollapse */ ElementsLoaderService.ctorParameters = function () { return [ { type: Injector }, { type: Compiler }, { type: ComponentFactoryResolver } ]; }; /** @nocollapse */ ElementsLoaderService.ngInjectableDef = defineInjectable({ factory: function ElementsLoaderService_Factory() { return new ElementsLoaderService(inject(INJECTOR), inject(Compiler), inject(ComponentFactoryResolver)); }, token: ElementsLoaderService, providedIn: "root" }); return ElementsLoaderService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { ElementsLoaderService }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFwaW5lc3MtbmctZWxlbWVudHMtbG9hZGVyLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AaGFwaW5lc3MvbmctZWxlbWVudHMtbG9hZGVyL2xpYi9lbGVtZW50cy1sb2FkZXIuc2VydmljZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENvbXBpbGVyLFxuICAgIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICBJbmplY3RhYmxlLFxuICAgIEluamVjdG9yLFxuICAgIE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMsXG4gICAgTmdNb2R1bGVGYWN0b3J5LFxuICAgIE5nTW9kdWxlUmVmLFxuICAgIFR5cGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjcmVhdGVDdXN0b21FbGVtZW50IH0gZnJvbSAnQGFuZ3VsYXIvZWxlbWVudHMnO1xuaW1wb3J0IHsgZm9ya0pvaW4sIGZyb20sIG1lcmdlLCBPYnNlcnZhYmxlLCBvZiwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBmbGF0TWFwLCBtYXAsIHRhcCwgdG9BcnJheSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gICAgQ3VzdG9tRWxlbWVudENvbXBvbmVudFNlbGVjdG9yLFxuICAgIEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvcixcbiAgICBXaXRoQ3VzdG9tRWxlbWVudENvbXBvbmVudFxufSBmcm9tICcuL2VsZW1lbnRzLXJlZ2lzdHJ5JztcblxuLy8gaW50ZXJmYWNlIHRvIG1hcCBkYXRhIGluc2VydGVkIGluIGNyZWF0ZUN1c3RvbUVsZW1lbnQoKVxuaW50ZXJmYWNlIEN1c3RvbUVsZW1lbnREYXRhIHtcbiAgICBjb21wb25lbnQ6IFR5cGU8YW55PjtcbiAgICBpbmplY3RvcjogSW5qZWN0b3I7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0gYXMgYW55KVxuZXhwb3J0IGNsYXNzIEVsZW1lbnRzTG9hZGVyU2VydmljZSB7XG4gICAgLyoqIE1hcCBvZiB1bnJlZ2lzdGVyZWQgY3VzdG9tIGVsZW1lbnRzIGFuZCB0aGVpciByZXNwZWN0aXZlIG1vZHVsZSB0byBsb2FkLiAqL1xuICAgIHByaXZhdGUgX2VsZW1lbnRzVG9Mb2FkOiBNYXA8c3RyaW5nLCBUeXBlPGFueT4+O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgX2NvbXBpbGVyOiBDb21waWxlcixcbiAgICAgICAgICAgICAgICBwcml2YXRlIF9jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcikge1xuICAgICAgICB0aGlzLl9lbGVtZW50c1RvTG9hZCA9IG5ldyBNYXA8c3RyaW5nLCBUeXBlPGFueT4+KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUXVlcmllcyB0aGUgZG9jdW1lbnQgZWxlbWVudCBmb3IgYW55IGN1c3RvbSBlbGVtZW50cyB0aGF0IGhhdmUgbm90IHlldCBiZWVuIHJlZ2lzdGVyZWQgd2l0aFxuICAgICAqIHRoZSBicm93c2VyLiBDdXN0b20gZWxlbWVudHMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgbGlzdCBvZiB1bnJlZ2lzdGVyZWRcbiAgICAgKiBlbGVtZW50cyBzbyB0aGF0IHRoZXkgd2lsbCBub3QgYmUgcXVlcmllZCBpbiBzdWJzZXF1ZW50IGNhbGxzLiBDb21waWxlIHRoZSBtb2R1bGUgYW5kIGl0cyBjb21wb25lbnRcbiAgICAgKiB0byBiZSByZWdpc3RlcmVkIGFzIGN1c3RvbSBlbGVtZW50cy5cbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gSklUIG1vZGVcbiAgICAgKi9cbiAgICBsb2FkQ29udGFpbmluZ0N1c3RvbUVsZW1lbnRzKGRhdGE6IEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvciB8IEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvcltdKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG9mKGRhdGEpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmbGF0TWFwKChfOiBDdXN0b21FbGVtZW50TW9kdWxlU2VsZWN0b3IgfCBDdXN0b21FbGVtZW50TW9kdWxlU2VsZWN0b3JbXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgISFfID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG9mKFtdLmNvbmNhdChfKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvcihuZXcgRXJyb3IoJ1BhcmFtZXRlciBtdXN0IGJlIGEgYEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvcmAgb3IgYW4gYXJyYXkgb2YgaXQnKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGZsYXRNYXAoKF86IEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvcltdKSA9PlxuICAgICAgICAgICAgICAgICAgICAhIV8ubGVuZ3RoID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG9mKF8pIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3IobmV3IEVycm9yKCdgQ3VzdG9tRWxlbWVudE1vZHVsZVNlbGVjdG9yYCBhcnJheSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGVsZW1lbnQnKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGZsYXRNYXAoKF86IEN1c3RvbUVsZW1lbnRNb2R1bGVTZWxlY3RvcltdKSA9PiBmcm9tKF8pKSxcbiAgICAgICAgICAgICAgICBmaWx0ZXIoXyA9PiAhIV8uc2VsZWN0b3IgJiYgISFfLm1vZHVsZSksXG4gICAgICAgICAgICAgICAgdG9BcnJheSgpLFxuICAgICAgICAgICAgICAgIHRhcCgoXzogQ3VzdG9tRWxlbWVudE1vZHVsZVNlbGVjdG9yW10pID0+XG4gICAgICAgICAgICAgICAgICAgIF8uZm9yRWFjaCgoZTogQ3VzdG9tRWxlbWVudE1vZHVsZVNlbGVjdG9yKSA9PiB0aGlzLl9lbGVtZW50c1RvTG9hZC5zZXQoZS5zZWxlY3RvciwgZS5tb2R1bGUpKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgZmxhdE1hcCgoKSA9PiB0aGlzLl9jdXN0b21FbGVtZW50cyh0cnVlKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUXVlcmllcyB0aGUgZG9jdW1lbnQgZWxlbWVudCBmb3IgYW55IGN1c3RvbSBlbGVtZW50cyB0aGF0IGhhdmUgbm90IHlldCBiZWVuIHJlZ2lzdGVyZWQgd2l0aFxuICAgICAqIHRoZSBicm93c2VyLiBDdXN0b20gZWxlbWVudHMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgbGlzdCBvZiB1bnJlZ2lzdGVyZWRcbiAgICAgKiBlbGVtZW50cyBzbyB0aGF0IHRoZXkgd2lsbCBub3QgYmUgcXVlcmllZCBpbiBzdWJzZXF1ZW50IGNhbGxzLiBDb21wb25lbnQgd2lsbCBiZSByZWdpc3RlcmVkIGFzXG4gICAgICogY3VzdG9tIGVsZW1lbnRzLlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBBT1QgbW9kZVxuICAgICAqL1xuICAgIHJlZ2lzdGVyQ29udGFpbmluZ0N1c3RvbUVsZW1lbnRzKGRhdGE6IEN1c3RvbUVsZW1lbnRDb21wb25lbnRTZWxlY3RvciB8IEN1c3RvbUVsZW1lbnRDb21wb25lbnRTZWxlY3RvcltdKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG9mKGRhdGEpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmbGF0TWFwKChfOiBDdXN0b21FbGVtZW50Q29tcG9uZW50U2VsZWN0b3IgfCBDdXN0b21FbGVtZW50Q29tcG9uZW50U2VsZWN0b3JbXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgISFfID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG9mKFtdLmNvbmNhdChfKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvcihuZXcgRXJyb3IoJ1BhcmFtZXRlciBtdXN0IGJlIGEgYEN1c3RvbUVsZW1lbnRDb21wb25lbnRTZWxlY3RvcmAgb3IgYW4gYXJyYXkgb2YgaXQnKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGZsYXRNYXAoKF86IEN1c3RvbUVsZW1lbnRDb21wb25lbnRTZWxlY3RvcltdKSA9PlxuICAgICAgICAgICAgICAgICAgICAhIV8ubGVuZ3RoID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG9mKF8pIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3IobmV3IEVycm9yKCdgQ3VzdG9tRWxlbWVudENvbXBvbmVudFNlbGVjdG9yYCBhcnJheSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGVsZW1lbnQnKSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGZsYXRNYXAoKF86IEN1c3RvbUVsZW1lbnRDb21wb25lbnRTZWxlY3RvcltdKSA9PiBmcm9tKF8pKSxcbiAgICAgICAgICAgICAgICBmaWx0ZXIoXyA9PiAhIV8uc2VsZWN0b3IgJiYgISFfLmNvbXBvbmVudCksXG4gICAgICAgICAgICAgICAgdG9BcnJheSgpLFxuICAgICAgICAgICAgICAgIHRhcCgoXzogQ3VzdG9tRWxlbWVudENvbXBvbmVudFNlbGVjdG9yW10pID0+XG4gICAgICAgICAgICAgICAgICAgIF8uZm9yRWFjaCgoZTogQ3VzdG9tRWxlbWVudENvbXBvbmVudFNlbGVjdG9yKSA9PiB0aGlzLl9lbGVtZW50c1RvTG9hZC5zZXQoZS5zZWxlY3RvciwgZS5jb21wb25lbnQpKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgZmxhdE1hcCgoKSA9PiB0aGlzLl9jdXN0b21FbGVtZW50cyhmYWxzZSkpXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1haW4gcHJvY2VzcyB0byBsb2FkIGN1c3RvbSBlbGVtZW50c1xuICAgICAqL1xuICAgIHByaXZhdGUgX2N1c3RvbUVsZW1lbnRzKGNvbXBpbGVNb2R1bGVBbmRBbGxDb21wb25lbnRzOiBib29sZWFuKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG9mKG9mKEFycmF5LmZyb20odGhpcy5fZWxlbWVudHNUb0xvYWQua2V5cygpKSkpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmbGF0TWFwKG9icyA9PlxuICAgICAgICAgICAgICAgICAgICBtZXJnZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG9icy5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihfID0+ICEhXyAmJiAhIV8ubGVuZ3RoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGF0TWFwKF8gPT4gZm9ya0pvaW4oXy5tYXAocyA9PiB0aGlzLl9yZWdpc3RlcihzLCBjb21waWxlTW9kdWxlQW5kQWxsQ29tcG9uZW50cykpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnMucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoXyA9PiAhXyB8fCAhXy5sZW5ndGgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcChfID0+IHVuZGVmaW5lZCBhcyBhbnkpXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVycyB0aGUgY3VzdG9tIGVsZW1lbnQgZGVmaW5lZCBvbiB0aGUgV2l0aEN1c3RvbUVsZW1lbnQgbW9kdWxlIGZhY3RvcnlcbiAgICAgKi9cbiAgICBwcml2YXRlIF9yZWdpc3RlcihzZWxlY3Rvcjogc3RyaW5nLCBjb21waWxlTW9kdWxlQW5kQWxsQ29tcG9uZW50czogYm9vbGVhbik6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgICAgICByZXR1cm4gb2YoXG4gICAgICAgICAgICBvZih0aGlzLl9lbGVtZW50c1RvTG9hZC5oYXMoc2VsZWN0b3IpKVxuICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmbGF0TWFwKChvYnM6IE9ic2VydmFibGU8Ym9vbGVhbj4pID0+XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlKFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihfID0+ICEhXyksIC8vIHNlbGVjdG9yIGluc2lkZSBlbGVtZW50cyB0byBsb2FkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYXRNYXAoXyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2YoY3VzdG9tRWxlbWVudHMuZ2V0KHNlbGVjdG9yKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhdE1hcCgobzogT2JzZXJ2YWJsZTxib29sZWFuPikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8ucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKF9fID0+ICEhX18pLCAvLyBzZWxlY3RvciBhbHJlYWR5IGxvYWRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXAoX18gPT4gdGhpcy5fZWxlbWVudHNUb0xvYWQuZGVsZXRlKHNlbGVjdG9yKSkgLy8gc28gZGVsZXRlIGl0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihfXyA9PiAhX18pLCAvLyBzZWxlY3RvciBuZXZlciBsb2FkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhdE1hcChfXyA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlQ3VzdG9tRWxlbWVudChzZWxlY3RvciwgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgLy8gc28gY3JlYXRlIGN1c3RvbSBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoXyA9PiAhXyksIC8vIHNlbGVjdG9yIG5vdCBpbiBlbGVtZW50cyB0byBsb2FkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcChfID0+IHVuZGVmaW5lZCBhcyBhbnkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgY3VzdG9tIGVsZW1lbnQgZm9yIGN1cnJlbnQgc2VsZWN0b3JcbiAgICAgKi9cbiAgICBwcml2YXRlIF9jcmVhdGVDdXN0b21FbGVtZW50KHNlbGVjdG9yOiBzdHJpbmcsIGNvbXBpbGVNb2R1bGVBbmRBbGxDb21wb25lbnRzOiBib29sZWFuKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBvZihcbiAgICAgICAgICAgIG9mKGNvbXBpbGVNb2R1bGVBbmRBbGxDb21wb25lbnRzKVxuICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmbGF0TWFwKChvYnM6IE9ic2VydmFibGU8Ym9vbGVhbj4pID0+XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlKFxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKF8gPT4gISFfKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGF0TWFwKF8gPT4gdGhpcy5fY29tcG9uZW50QW5kSW5qZWN0b3JGcm9tQ29tcGlsZWRNb2R1bGUodGhpcy5fZWxlbWVudHNUb0xvYWQuZ2V0KHNlbGVjdG9yKSEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9icy5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihfID0+ICFfKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGF0TWFwKF8gPT4gdGhpcy5fY29tcG9uZW50QW5kSW5qZWN0b3JGcm9tQ29tcG9uZW50RmFjdG9yeSh0aGlzLl9lbGVtZW50c1RvTG9hZC5nZXQoc2VsZWN0b3IpISkpXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIG1hcCgoXzogQ3VzdG9tRWxlbWVudERhdGEpID0+IGNyZWF0ZUN1c3RvbUVsZW1lbnQoXy5jb21wb25lbnQsIHsgaW5qZWN0b3I6IF8uaW5qZWN0b3IgfSkpLFxuICAgICAgICAgICAgICAgIHRhcCgoY3VzdG9tRWxlbWVudDogYW55KSA9PiBjdXN0b21FbGVtZW50cyEuZGVmaW5lKHNlbGVjdG9yLCBjdXN0b21FbGVtZW50KSksXG4gICAgICAgICAgICAgICAgdGFwKF8gPT4gdGhpcy5fZWxlbWVudHNUb0xvYWQuZGVsZXRlKHNlbGVjdG9yKSksXG4gICAgICAgICAgICAgICAgZmxhdE1hcChfID0+IGZyb20oY3VzdG9tRWxlbWVudHMud2hlbkRlZmluZWQoc2VsZWN0b3IpKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcGlsZSBtb2R1bGUgYW5kIGFsbCBjb21wb25lbnRzIHRvIHJldHJpZXZlIHRoZSBjb21wb25lbnQgYW5kIHRoZSBpbmplY3RvciBmb3IgY3VzdG9tIGVsZW1lbnQgY3JlYXRpb24uXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgaW4gSklUIG1vZGUuXG4gICAgICovXG4gICAgcHJpdmF0ZSBfY29tcG9uZW50QW5kSW5qZWN0b3JGcm9tQ29tcGlsZWRNb2R1bGUoZWxlbWVudE1vZHVsZTogVHlwZTxXaXRoQ3VzdG9tRWxlbWVudENvbXBvbmVudD4pOlxuICAgICAgICBPYnNlcnZhYmxlPEN1c3RvbUVsZW1lbnREYXRhIHwgbmV2ZXI+IHtcbiAgICAgICAgcmV0dXJuIGZyb20odGhpcy5fY29tcGlsZXIuY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNBc3luYyhlbGVtZW50TW9kdWxlKSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIG1hcCgobW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllczogTW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllczxXaXRoQ3VzdG9tRWxlbWVudENvbXBvbmVudD4pID0+XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMubmdNb2R1bGVGYWN0b3J5XG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBtYXAoKGVsZW1lbnRNb2R1bGVGYWN0b3J5OiBOZ01vZHVsZUZhY3Rvcnk8V2l0aEN1c3RvbUVsZW1lbnRDb21wb25lbnQ+KSA9PiBlbGVtZW50TW9kdWxlRmFjdG9yeS5jcmVhdGUodGhpcy5faW5qZWN0b3IpKSxcbiAgICAgICAgICAgICAgICBmbGF0TWFwKChlbGVtZW50TW9kdWxlUmVmOiBOZ01vZHVsZVJlZjxXaXRoQ3VzdG9tRWxlbWVudENvbXBvbmVudD4pID0+XG4gICAgICAgICAgICAgICAgICAgICEhZWxlbWVudE1vZHVsZVJlZi5pbnN0YW5jZS5jdXN0b21FbGVtZW50Q29tcG9uZW50ID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG9mKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IGVsZW1lbnRNb2R1bGVSZWYuaW5zdGFuY2UuY3VzdG9tRWxlbWVudENvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmplY3RvcjogZWxlbWVudE1vZHVsZVJlZi5pbmplY3RvclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBhcyBDdXN0b21FbGVtZW50RGF0YSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoJ1dpdGhDdXN0b21FbGVtZW50Q29tcG9uZW50IGludGVyZmFjZSBtdXN0JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgYmUgaW1wbGVtZW50ZWQgYnkgYWxsIG1vZHVsZXMgdGhhdCBkZWNsYXJlIGEgY29tcG9uZW50IHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBjdXN0b20gZWxlbWVudC4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzb2x2ZSBjb21wb25lbnQgdG8gZ2V0IG1vZHVsZSBpbmplY3RvciAgZm9yIGN1c3RvbSBlbGVtZW50IGNyZWF0aW9uLlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgb25seSB1c2VkIGluIEFPVCBtb2RlLlxuICAgICAqL1xuICAgIHByaXZhdGUgX2NvbXBvbmVudEFuZEluamVjdG9yRnJvbUNvbXBvbmVudEZhY3Rvcnk8VD4oZWxlbWVudENvbXBvbmVudDogVHlwZTxUPik6IE9ic2VydmFibGU8Q3VzdG9tRWxlbWVudERhdGE+IHtcbiAgICAgICAgcmV0dXJuIG9mKHRoaXMuX2NvbXBvbmVudEZhY3RvcnlSZXNvbHZlci5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeTxUPihlbGVtZW50Q29tcG9uZW50KSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIG1hcCgoY29tcG9uZW50RmFjdG9yeTogYW55KSA9PiBjb21wb25lbnRGYWN0b3J5Lm5nTW9kdWxlKSxcbiAgICAgICAgICAgICAgICBtYXAoKGVsZW1lbnRNb2R1bGVSZWY6IE5nTW9kdWxlUmVmPGFueT4pID0+XG4gICAgICAgICAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IGVsZW1lbnRDb21wb25lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmplY3RvcjogZWxlbWVudE1vZHVsZVJlZi5pbmplY3RvclxuICAgICAgICAgICAgICAgICAgICB9KSBhcyBDdXN0b21FbGVtZW50RGF0YVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0lBZ0NJLCtCQUFvQixTQUFtQixFQUNuQixTQUFtQixFQUNuQix5QkFBbUQ7UUFGbkQsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUNuQixjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQ25CLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBMEI7UUFDbkUsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztLQUN2RDs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFTRCw0REFBNEI7Ozs7Ozs7OztJQUE1QixVQUE2QixJQUFpRTtRQUE5RixpQkFxQkM7UUFwQkcsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDO2FBQ1YsSUFBSSxDQUNELE9BQU8sQ0FBQyxVQUFDLENBQThEO1lBQ25FLE9BQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0MsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hCLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxxRUFBcUUsQ0FBQyxDQUFDO1NBQUEsQ0FDbkcsRUFDRCxPQUFPLENBQUMsVUFBQyxDQUFnQztZQUNyQyxPQUFBLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTTtnQkFDTixFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNMLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO1NBQUEsQ0FD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