@hapiness/ng-elements-loader
Version:
Service to load Angular Custom Elements inside Angular's applications
274 lines (268 loc) • 35.3 kB
JavaScript
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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