@versatiledatakit/shared
Version:
Versatile Data Kit Shared library enables reusability of shared features like: NgRx Redux, Error Handlers, Utils, Generic Components, etc.
192 lines • 29.1 kB
JavaScript
/*
* Copyright 2023-2025 Broadcom
* SPDX-License-Identifier: Apache-2.0
*/
import { Injectable } from '@angular/core';
import { CollectionsUtil } from '../../../utils';
import { TaurusObject } from '../../../common';
import { DynamicContainerComponent, DynamicContextComponent } from '../components';
import * as i0 from "@angular/core";
/**
* ** Dynamic Components Service that generates ViewContainerRefs in context that could be used once or reused multiple times.
*/
export class DynamicComponentsService extends TaurusObject {
/**
* ** Constructor.
*/
constructor() {
super(DynamicComponentsService.CLASS_NAME);
this._uniqueComponentRefsStore = new Map();
}
/**
* ** Create or retrieve unique ViewContainerRef together with ViewRef and bound UUID.
*
* - if UUID is provided it will try to retrieve such reference if exists,
* otherwise will create new ViewContainerRef which will be stored under provided UUID key.
* - if no UUID provided will proceed to issue new UUID,
* then will create new ViewContainerRef which will be stored under the issued UUID,
* and both together with ViewRef will be returned to the invoker according provided return interface.
* - if some error is thrown in process of ViewContainerRef acquisition,
* service will return <code>null</code> instead of reference and that should be handled on invoker side.
* - Currently there is no automatic garbage collection, but only manual destroy utilizing {@link this.destroyUniqueViewContainerRef},
* so be careful not to acquire too many unique ViewContainerRef references,
* because they could downgrade Application performance (they are created as Component instances in root of the application).
* - Automatic GC is not currently developed because there is possibility to retrieve existing
* contextual ViewContainerRef instances with issued UUIDs for re-usage,
* or created instances refs could be kept into the invoker scope (context),
* or instances refs could be destroyed using the provided method with issued UUIDs {@link this.destroyUniqueViewContainerRef}
*/
getUniqueViewContainerRef(requestedUUID) {
const isContainerComponentSuccessfullyCreated = this._createDynamicContainerComponent();
if (!isContainerComponentSuccessfullyCreated) {
return null;
}
const isContainerComponentHealthy = this._validateDynamicContainerComponent();
if (!isContainerComponentHealthy) {
return null;
}
const uuid = DynamicComponentsService._getOrGenerateUUID(requestedUUID);
if (!this._uniqueComponentRefsStore.has(uuid)) {
const isContextComponentSuccessfullyCreated = this._createDynamicContextComponent(uuid);
if (!isContextComponentSuccessfullyCreated) {
return null;
}
}
const isContextComponentHealthy = this._validateDynamicContextComponent(uuid);
if (!isContextComponentHealthy) {
return null;
}
return {
uuid: uuid,
viewContainerRef: this._uniqueComponentRefsStore.get(uuid).instance.viewContainerRef,
hostView: this._uniqueComponentRefsStore.get(uuid).hostView
};
}
/**
* ** Destroy unique ViewContainerRef for provided UUID.
*
* - If reference is found for provided UUID and is successfully destroyed will return true otherwise false.
* - If reference for provided UUID is not found will return null.
*/
destroyUniqueViewContainerRef(uuid) {
if (!this._uniqueComponentRefsStore.has(uuid)) {
return null;
}
try {
this._uniqueComponentRefsStore.get(uuid).destroy();
this._uniqueComponentRefsStore.delete(uuid);
return true;
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, Failed to destroy unique ViewContainerRef instance in DynamicContextComponent`);
return false;
}
}
/**
* ** Initialize service.
*
* - Should be invoked only once.
* - Ideal place for invoking is <code>AppComponent.ngOnInit()</code>.
*/
initialize(viewContainerRef) {
this._appRootViewContainerRef = viewContainerRef;
}
/**
* @inheritDoc
*/
ngOnDestroy() {
this._clearUniqueComponentsRef();
this._clearContextContainerRef();
this._clearAppRootViewContainerRef();
super.ngOnDestroy();
}
_createDynamicContainerComponent() {
if (!this._appRootViewContainerRef) {
return false;
}
if (this._dynamicContainerRef && this._dynamicContainerRef.hostView && !this._dynamicContainerRef.hostView.destroyed) {
return true;
}
try {
this._dynamicContainerRef = this._appRootViewContainerRef.createComponent(DynamicContainerComponent);
this._dynamicContainerRef.changeDetectorRef.detectChanges();
return true;
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, Failed to create instance of DynamicContainerComponent`);
return false;
}
}
_validateDynamicContainerComponent() {
if (!(this._dynamicContainerRef && this._dynamicContainerRef.instance && this._dynamicContainerRef.instance.viewContainerRef)) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, Service is not initialized correctly ` +
`or during initialization failed to create instance of DynamicContainerComponent`);
return false;
}
return true;
}
_createDynamicContextComponent(uuid) {
try {
const uniqueDynamicComponentRef = this._dynamicContainerRef.instance.viewContainerRef.createComponent(DynamicContextComponent);
uniqueDynamicComponentRef.changeDetectorRef.detectChanges();
this._uniqueComponentRefsStore.set(uuid, uniqueDynamicComponentRef);
return true;
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, Failed to create instance of DynamicContextComponent`);
return false;
}
}
_validateDynamicContextComponent(uuid) {
const retrievedComponentRef = this._uniqueComponentRefsStore.get(uuid);
if (!(retrievedComponentRef && retrievedComponentRef.instance && retrievedComponentRef.instance.viewContainerRef)) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, Failed to retrieve context instance of DynamicContextComponent`);
return false;
}
return true;
}
_clearUniqueComponentsRef() {
this._uniqueComponentRefsStore.forEach((componentRef, uuid) => {
try {
if (!componentRef.hostView.destroyed) {
componentRef.destroy();
}
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, failed to destroy unique component ref ${uuid}`);
}
});
this._uniqueComponentRefsStore.clear();
}
_clearContextContainerRef() {
try {
this._dynamicContainerRef.destroy();
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, failed to destroy DynamicContextContainer ref`);
}
this._dynamicContainerRef = null;
}
_clearAppRootViewContainerRef() {
try {
this._appRootViewContainerRef.clear();
}
catch (e) {
console.error(`${DynamicComponentsService.CLASS_NAME}: Potential bug found, failed to destroy root ViewContainerRef`);
}
this._appRootViewContainerRef = null;
}
static _getOrGenerateUUID(uuid) {
return uuid ?? CollectionsUtil.generateUUID();
}
}
/**
* @inheritDoc
*/
DynamicComponentsService.CLASS_NAME = 'DynamicComponentsService';
DynamicComponentsService.ɵfac = function DynamicComponentsService_Factory(t) { return new (t || DynamicComponentsService)(); };
DynamicComponentsService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: DynamicComponentsService, factory: DynamicComponentsService.ɵfac });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DynamicComponentsService, [{
type: Injectable
}], function () { return []; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1jb21wb25lbnRzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaGFyZWQvc3JjL2xpYi9mZWF0dXJlcy9keW5hbWljLWNvbXBvbmVudHMvc2VydmljZXMvZHluYW1pYy1jb21wb25lbnRzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFnQixVQUFVLEVBQXdDLE1BQU0sZUFBZSxDQUFDO0FBRS9GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxFQUFFLHlCQUF5QixFQUFFLHVCQUF1QixFQUFFLE1BQU0sZUFBZSxDQUFDOztBQXlCbkY7O0dBRUc7QUFFSCxNQUFNLE9BQU8sd0JBQXlCLFNBQVEsWUFBWTtJQTBCdEQ7O09BRUc7SUFDSDtRQUNJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUUzQyxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxHQUFHLEVBQWlELENBQUM7SUFDOUYsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILHlCQUF5QixDQUFDLGFBQXNCO1FBQzVDLE1BQU0sdUNBQXVDLEdBQUcsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7UUFDeEYsSUFBSSxDQUFDLHVDQUF1QyxFQUFFO1lBQzFDLE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFFRCxNQUFNLDJCQUEyQixHQUFHLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO1FBQzlFLElBQUksQ0FBQywyQkFBMkIsRUFBRTtZQUM5QixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsTUFBTSxJQUFJLEdBQUcsd0JBQXdCLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFeEUs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XG4gKiBDb3B5cmlnaHQgMjAyMy0yMDI1IEJyb2FkY29tXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudFJlZiwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBWaWV3Q29udGFpbmVyUmVmLCBWaWV3UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IENvbGxlY3Rpb25zVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzJztcblxuaW1wb3J0IHsgVGF1cnVzT2JqZWN0IH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uJztcblxuaW1wb3J0IHsgRHluYW1pY0NvbnRhaW5lckNvbXBvbmVudCwgRHluYW1pY0NvbnRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzJztcblxuLyoqXG4gKiAqKiBJbnRlcm5hbCBzZXJ2aWNlIG1vZGVsLlxuICovXG5pbnRlcmZhY2UgQWNxdWlyZVZpZXdDb250YWluZXJSZWZNb2RlbCB7XG4gICAgLyoqXG4gICAgICogKiogVmlld0NvbnRhaW5lclJlZiB1dWlkLlxuICAgICAqXG4gICAgICogICAgICAtIFZpZXdDb250YWluZXJSZWZzIGNvdWxkIGJlIHJldXNlZCBieSBwcm92aWRpbmcgaXNzdWVkIFVVSUQuXG4gICAgICogICAgICAtIFJlZmVyZW5jZXMgYXJlIHN0b3JlZCBpbiB0aGUgc2VydmljZSBNYXAgd2hlcmUgZm9yIGV2ZXJ5IGlzc3VlZCBVVUlEIGtleSB0aGVyZSBpcyBWaWV3Q29udGFpbmVyUmVmIGJlaGluZCBhcyB2YWx1ZS5cbiAgICAgKi9cbiAgICB1dWlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiAqKiBVbmlxdWUgVmlld0NvbnRhaW5lclJlZiBjcmVhdGVkIG9uIGJlaGFsZiBvZiB0aGUgaW52b2tlci5cbiAgICAgKi9cbiAgICB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmO1xuXG4gICAgLyoqXG4gICAgICogKiogVmlld1JlZiB0byB0aGUgdW5pcXVlIFZpZXdDb250YWluZXJSZWYgY3JlYXRlZCBvbiBiZWhhbGYgb2YgdGhlIGludm9rZXIuXG4gICAgICovXG4gICAgaG9zdFZpZXc6IFZpZXdSZWY7XG59XG5cbi8qKlxuICogKiogRHluYW1pYyBDb21wb25lbnRzIFNlcnZpY2UgdGhhdCBnZW5lcmF0ZXMgVmlld0NvbnRhaW5lclJlZnMgaW4gY29udGV4dCB0aGF0IGNvdWxkIGJlIHVzZWQgb25jZSBvciByZXVzZWQgbXVsdGlwbGUgdGltZXMuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UgZXh0ZW5kcyBUYXVydXNPYmplY3QgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAgIC8qKlxuICAgICAqIEBpbmhlcml0RG9jXG4gICAgICovXG4gICAgc3RhdGljIG92ZXJyaWRlIHJlYWRvbmx5IENMQVNTX05BTUU6IHN0cmluZyA9ICdEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UnO1xuXG4gICAgLyoqXG4gICAgICogKiogQWNxdWlyZWQgVmlld0NvbnRhaW5lclJlZiB3aXRoIGRlcGVuZGVuY3kgaW5qZWN0aW9uIGR1cmluZyBzZXJ2aWNlIGluaXRpYWxpemF0aW9uIHtAbGluayBEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UuaW5pdGlhbGl6ZX0sXG4gICAgICogICAgICB3aGVyZSBEeW5hbWljIENvbnRhaW5lciB7QGxpbmsgRHluYW1pY0NvbnRhaW5lckNvbXBvbmVudH0gd2lsbCBiZSBpbnNlcnRlZC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgX2FwcFJvb3RWaWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmO1xuXG4gICAgLyoqXG4gICAgICogKiogRHluYW1pYyBDb250YWluZXIgcmVmZXJlbmNlIHtAbGluayBEeW5hbWljQ29udGFpbmVyQ29tcG9uZW50fSxcbiAgICAgKiAgICAgIHdoZXJlIGFsbCBjb250ZXh0dWFsIER5bmFtaWMgY29tcG9uZW50cyB7QGxpbmsgRHluYW1pY0NvbnRleHRDb21wb25lbnR9IHdpbGwgYmUgaW5zZXJ0ZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIF9keW5hbWljQ29udGFpbmVyUmVmOiBDb21wb25lbnRSZWY8RHluYW1pY0NvbnRhaW5lckNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiAqKiBMb2NhbCBzdG9yZSB3aGVyZSBhbGwgY3JlYXRlZCBEeW5hbWljIENvbnRleHQgQ29tcG9uZW50cyBhcmUgc3RvcmVkIHVuZGVyIHRoZWlyIGNvcnJlc3BvbmRpbmcgaXNzdWVkIFVVSUQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF91bmlxdWVDb21wb25lbnRSZWZzU3RvcmU6IE1hcDxzdHJpbmcsIENvbXBvbmVudFJlZjxEeW5hbWljQ29udGV4dENvbXBvbmVudD4+O1xuXG4gICAgLyoqXG4gICAgICogKiogQ29uc3RydWN0b3IuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKER5bmFtaWNDb21wb25lbnRzU2VydmljZS5DTEFTU19OQU1FKTtcblxuICAgICAgICB0aGlzLl91bmlxdWVDb21wb25lbnRSZWZzU3RvcmUgPSBuZXcgTWFwPHN0cmluZywgQ29tcG9uZW50UmVmPER5bmFtaWNDb250ZXh0Q29tcG9uZW50Pj4oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDcmVhdGUgb3IgcmV0cmlldmUgdW5pcXVlIFZpZXdDb250YWluZXJSZWYgdG9nZXRoZXIgd2l0aCBWaWV3UmVmIGFuZCBib3VuZCBVVUlELlxuICAgICAqXG4gICAgICogICAgICAtIGlmIFVVSUQgaXMgcHJvdmlkZWQgaXQgd2lsbCB0cnkgdG8gcmV0cmlldmUgc3VjaCByZWZlcmVuY2UgaWYgZXhpc3RzLFxuICAgICAqICAgICAgICAgICAgICBvdGhlcndpc2Ugd2lsbCBjcmVhdGUgbmV3IFZpZXdDb250YWluZXJSZWYgd2hpY2ggd2lsbCBiZSBzdG9yZWQgdW5kZXIgcHJvdmlkZWQgVVVJRCBrZXkuXG4gICAgICogICAgICAtIGlmIG5vIFVVSUQgcHJvdmlkZWQgd2lsbCBwcm9jZWVkIHRvIGlzc3VlIG5ldyBVVUlELFxuICAgICAqICAgICAgICAgICAgICB0aGVuIHdpbGwgY3JlYXRlIG5ldyBWaWV3Q29udGFpbmVyUmVmIHdoaWNoIHdpbGwgYmUgc3RvcmVkIHVuZGVyIHRoZSBpc3N1ZWQgVVVJRCxcbiAgICAgKiAgICAgICAgICAgICAgYW5kIGJvdGggdG9nZXRoZXIgd2l0aCBWaWV3UmVmIHdpbGwgYmUgcmV0dXJuZWQgdG8gdGhlIGludm9rZXIgYWNjb3JkaW5nIHByb3ZpZGVkIHJldHVybiBpbnRlcmZhY2UuXG4gICAgICogICAgICAtIGlmIHNvbWUgZXJyb3IgaXMgdGhyb3duIGluIHByb2Nlc3Mgb2YgVmlld0NvbnRhaW5lclJlZiBhY3F1aXNpdGlvbixcbiAgICAgKiAgICAgICAgICAgICAgc2VydmljZSB3aWxsIHJldHVybiA8Y29kZT5udWxsPC9jb2RlPiBpbnN0ZWFkIG9mIHJlZmVyZW5jZSBhbmQgdGhhdCBzaG91bGQgYmUgaGFuZGxlZCBvbiBpbnZva2VyIHNpZGUuXG4gICAgICogICAgICAtIEN1cnJlbnRseSB0aGVyZSBpcyBubyBhdXRvbWF0aWMgZ2FyYmFnZSBjb2xsZWN0aW9uLCBidXQgb25seSBtYW51YWwgZGVzdHJveSB1dGlsaXppbmcge0BsaW5rIHRoaXMuZGVzdHJveVVuaXF1ZVZpZXdDb250YWluZXJSZWZ9LFxuICAgICAqICAgICAgICAgICAgICBzbyBiZSBjYXJlZnVsIG5vdCB0byBhY3F1aXJlIHRvbyBtYW55IHVuaXF1ZSBWaWV3Q29udGFpbmVyUmVmIHJlZmVyZW5jZXMsXG4gICAgICogICAgICAgICAgICAgIGJlY2F1c2UgdGhleSBjb3VsZCBkb3duZ3JhZGUgQXBwbGljYXRpb24gcGVyZm9ybWFuY2UgKHRoZXkgYXJlIGNyZWF0ZWQgYXMgQ29tcG9uZW50IGluc3RhbmNlcyBpbiByb290IG9mIHRoZSBhcHBsaWNhdGlvbikuXG4gICAgICogICAgICAtIEF1dG9tYXRpYyBHQyBpcyBub3QgY3VycmVudGx5IGRldmVsb3BlZCBiZWNhdXNlIHRoZXJlIGlzIHBvc3NpYmlsaXR5IHRvIHJldHJpZXZlIGV4aXN0aW5nXG4gICAgICogICAgICAgICAgICAgIGNvbnRleHR1YWwgVmlld0NvbnRhaW5lclJlZiBpbnN0YW5jZXMgd2l0aCBpc3N1ZWQgVVVJRHMgZm9yIHJlLXVzYWdlLFxuICAgICAqICAgICAgICAgICAgICBvciBjcmVhdGVkIGluc3RhbmNlcyByZWZzIGNvdWxkIGJlIGtlcHQgaW50byB0aGUgaW52b2tlciBzY29wZSAoY29udGV4dCksXG4gICAgICogICAgICAgICAgICAgIG9yIGluc3RhbmNlcyByZWZzIGNvdWxkIGJlIGRlc3Ryb3llZCB1c2luZyB0aGUgcHJvdmlkZWQgbWV0aG9kIHdpdGggaXNzdWVkIFVVSURzIHtAbGluayB0aGlzLmRlc3Ryb3lVbmlxdWVWaWV3Q29udGFpbmVyUmVmfVxuICAgICAqL1xuICAgIGdldFVuaXF1ZVZpZXdDb250YWluZXJSZWYocmVxdWVzdGVkVVVJRD86IHN0cmluZyk6IEFjcXVpcmVWaWV3Q29udGFpbmVyUmVmTW9kZWwge1xuICAgICAgICBjb25zdCBpc0NvbnRhaW5lckNvbXBvbmVudFN1Y2Nlc3NmdWxseUNyZWF0ZWQgPSB0aGlzLl9jcmVhdGVEeW5hbWljQ29udGFpbmVyQ29tcG9uZW50KCk7XG4gICAgICAgIGlmICghaXNDb250YWluZXJDb21wb25lbnRTdWNjZXNzZnVsbHlDcmVhdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzQ29udGFpbmVyQ29tcG9uZW50SGVhbHRoeSA9IHRoaXMuX3ZhbGlkYXRlRHluYW1pY0NvbnRhaW5lckNvbXBvbmVudCgpO1xuICAgICAgICBpZiAoIWlzQ29udGFpbmVyQ29tcG9uZW50SGVhbHRoeSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1dWlkID0gRHluYW1pY0NvbXBvbmVudHNTZXJ2aWNlLl9nZXRPckdlbmVyYXRlVVVJRChyZXF1ZXN0ZWRVVUlEKTtcblxuICAgICAgICBpZiAoIXRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5oYXModXVpZCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzQ29udGV4dENvbXBvbmVudFN1Y2Nlc3NmdWxseUNyZWF0ZWQgPSB0aGlzLl9jcmVhdGVEeW5hbWljQ29udGV4dENvbXBvbmVudCh1dWlkKTtcbiAgICAgICAgICAgIGlmICghaXNDb250ZXh0Q29tcG9uZW50U3VjY2Vzc2Z1bGx5Q3JlYXRlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNDb250ZXh0Q29tcG9uZW50SGVhbHRoeSA9IHRoaXMuX3ZhbGlkYXRlRHluYW1pY0NvbnRleHRDb21wb25lbnQodXVpZCk7XG4gICAgICAgIGlmICghaXNDb250ZXh0Q29tcG9uZW50SGVhbHRoeSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXVpZDogdXVpZCxcbiAgICAgICAgICAgIHZpZXdDb250YWluZXJSZWY6IHRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5nZXQodXVpZCkuaW5zdGFuY2Uudmlld0NvbnRhaW5lclJlZixcbiAgICAgICAgICAgIGhvc3RWaWV3OiB0aGlzLl91bmlxdWVDb21wb25lbnRSZWZzU3RvcmUuZ2V0KHV1aWQpLmhvc3RWaWV3XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogRGVzdHJveSB1bmlxdWUgVmlld0NvbnRhaW5lclJlZiBmb3IgcHJvdmlkZWQgVVVJRC5cbiAgICAgKlxuICAgICAqICAgICAgLSBJZiByZWZlcmVuY2UgaXMgZm91bmQgZm9yIHByb3ZpZGVkIFVVSUQgYW5kIGlzIHN1Y2Nlc3NmdWxseSBkZXN0cm95ZWQgd2lsbCByZXR1cm4gdHJ1ZSBvdGhlcndpc2UgZmFsc2UuXG4gICAgICogICAgICAtIElmIHJlZmVyZW5jZSBmb3IgcHJvdmlkZWQgVVVJRCBpcyBub3QgZm91bmQgd2lsbCByZXR1cm4gbnVsbC5cbiAgICAgKi9cbiAgICBkZXN0cm95VW5pcXVlVmlld0NvbnRhaW5lclJlZih1dWlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLl91bmlxdWVDb21wb25lbnRSZWZzU3RvcmUuaGFzKHV1aWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl91bmlxdWVDb21wb25lbnRSZWZzU3RvcmUuZ2V0KHV1aWQpLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5kZWxldGUodXVpZCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgIGAke0R5bmFtaWNDb21wb25lbnRzU2VydmljZS5DTEFTU19OQU1FfTogUG90ZW50aWFsIGJ1ZyBmb3VuZCwgRmFpbGVkIHRvIGRlc3Ryb3kgdW5pcXVlIFZpZXdDb250YWluZXJSZWYgaW5zdGFuY2UgaW4gRHluYW1pY0NvbnRleHRDb21wb25lbnRgXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBJbml0aWFsaXplIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiAgICAgIC0gU2hvdWxkIGJlIGludm9rZWQgb25seSBvbmNlLlxuICAgICAqICAgICAgLSBJZGVhbCBwbGFjZSBmb3IgaW52b2tpbmcgaXMgPGNvZGU+QXBwQ29tcG9uZW50Lm5nT25Jbml0KCk8L2NvZGU+LlxuICAgICAqL1xuICAgIGluaXRpYWxpemUodmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZik6IHZvaWQge1xuICAgICAgICB0aGlzLl9hcHBSb290Vmlld0NvbnRhaW5lclJlZiA9IHZpZXdDb250YWluZXJSZWY7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGluaGVyaXREb2NcbiAgICAgKi9cbiAgICBvdmVycmlkZSBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY2xlYXJVbmlxdWVDb21wb25lbnRzUmVmKCk7XG4gICAgICAgIHRoaXMuX2NsZWFyQ29udGV4dENvbnRhaW5lclJlZigpO1xuICAgICAgICB0aGlzLl9jbGVhckFwcFJvb3RWaWV3Q29udGFpbmVyUmVmKCk7XG5cbiAgICAgICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jcmVhdGVEeW5hbWljQ29udGFpbmVyQ29tcG9uZW50KCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXRoaXMuX2FwcFJvb3RWaWV3Q29udGFpbmVyUmVmKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fZHluYW1pY0NvbnRhaW5lclJlZiAmJiB0aGlzLl9keW5hbWljQ29udGFpbmVyUmVmLmhvc3RWaWV3ICYmICF0aGlzLl9keW5hbWljQ29udGFpbmVyUmVmLmhvc3RWaWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fZHluYW1pY0NvbnRhaW5lclJlZiA9IHRoaXMuX2FwcFJvb3RWaWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudChEeW5hbWljQ29udGFpbmVyQ29tcG9uZW50KTtcbiAgICAgICAgICAgIHRoaXMuX2R5bmFtaWNDb250YWluZXJSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgICBgJHtEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UuQ0xBU1NfTkFNRX06IFBvdGVudGlhbCBidWcgZm91bmQsIEZhaWxlZCB0byBjcmVhdGUgaW5zdGFuY2Ugb2YgRHluYW1pY0NvbnRhaW5lckNvbXBvbmVudGBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3ZhbGlkYXRlRHluYW1pY0NvbnRhaW5lckNvbXBvbmVudCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCEodGhpcy5fZHluYW1pY0NvbnRhaW5lclJlZiAmJiB0aGlzLl9keW5hbWljQ29udGFpbmVyUmVmLmluc3RhbmNlICYmIHRoaXMuX2R5bmFtaWNDb250YWluZXJSZWYuaW5zdGFuY2Uudmlld0NvbnRhaW5lclJlZikpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgYCR7RHluYW1pY0NvbXBvbmVudHNTZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBTZXJ2aWNlIGlzIG5vdCBpbml0aWFsaXplZCBjb3JyZWN0bHkgYCArXG4gICAgICAgICAgICAgICAgICAgIGBvciBkdXJpbmcgaW5pdGlhbGl6YXRpb24gZmFpbGVkIHRvIGNyZWF0ZSBpbnN0YW5jZSBvZiBEeW5hbWljQ29udGFpbmVyQ29tcG9uZW50YFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JlYXRlRHluYW1pY0NvbnRleHRDb21wb25lbnQodXVpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB1bmlxdWVEeW5hbWljQ29tcG9uZW50UmVmID0gdGhpcy5fZHluYW1pY0NvbnRhaW5lclJlZi5pbnN0YW5jZS52aWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudChEeW5hbWljQ29udGV4dENvbXBvbmVudCk7XG4gICAgICAgICAgICB1bmlxdWVEeW5hbWljQ29tcG9uZW50UmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIHRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5zZXQodXVpZCwgdW5pcXVlRHluYW1pY0NvbXBvbmVudFJlZik7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgIGAke0R5bmFtaWNDb21wb25lbnRzU2VydmljZS5DTEFTU19OQU1FfTogUG90ZW50aWFsIGJ1ZyBmb3VuZCwgRmFpbGVkIHRvIGNyZWF0ZSBpbnN0YW5jZSBvZiBEeW5hbWljQ29udGV4dENvbXBvbmVudGBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3ZhbGlkYXRlRHluYW1pY0NvbnRleHRDb21wb25lbnQodXVpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHJldHJpZXZlZENvbXBvbmVudFJlZiA9IHRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5nZXQodXVpZCk7XG4gICAgICAgIGlmICghKHJldHJpZXZlZENvbXBvbmVudFJlZiAmJiByZXRyaWV2ZWRDb21wb25lbnRSZWYuaW5zdGFuY2UgJiYgcmV0cmlldmVkQ29tcG9uZW50UmVmLmluc3RhbmNlLnZpZXdDb250YWluZXJSZWYpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgIGAke0R5bmFtaWNDb21wb25lbnRzU2VydmljZS5DTEFTU19OQU1FfTogUG90ZW50aWFsIGJ1ZyBmb3VuZCwgRmFpbGVkIHRvIHJldHJpZXZlIGNvbnRleHQgaW5zdGFuY2Ugb2YgRHluYW1pY0NvbnRleHRDb21wb25lbnRgXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jbGVhclVuaXF1ZUNvbXBvbmVudHNSZWYoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3VuaXF1ZUNvbXBvbmVudFJlZnNTdG9yZS5mb3JFYWNoKChjb21wb25lbnRSZWYsIHV1aWQpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjb21wb25lbnRSZWYuaG9zdFZpZXcuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFJlZi5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGAke0R5bmFtaWNDb21wb25lbnRzU2VydmljZS5DTEFTU19OQU1FfTogUG90ZW50aWFsIGJ1ZyBmb3VuZCwgZmFpbGVkIHRvIGRlc3Ryb3kgdW5pcXVlIGNvbXBvbmVudCByZWYgJHt1dWlkfWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl91bmlxdWVDb21wb25lbnRSZWZzU3RvcmUuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jbGVhckNvbnRleHRDb250YWluZXJSZWYoKTogdm9pZCB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl9keW5hbWljQ29udGFpbmVyUmVmLmRlc3Ryb3koKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHtEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UuQ0xBU1NfTkFNRX06IFBvdGVudGlhbCBidWcgZm91bmQsIGZhaWxlZCB0byBkZXN0cm95IER5bmFtaWNDb250ZXh0Q29udGFpbmVyIHJlZmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZHluYW1pY0NvbnRhaW5lclJlZiA9IG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2xlYXJBcHBSb290Vmlld0NvbnRhaW5lclJlZigpOiB2b2lkIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2FwcFJvb3RWaWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7RHluYW1pY0NvbXBvbmVudHNTZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBmYWlsZWQgdG8gZGVzdHJveSByb290IFZpZXdDb250YWluZXJSZWZgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2FwcFJvb3RWaWV3Q29udGFpbmVyUmVmID0gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfZ2V0T3JHZW5lcmF0ZVVVSUQodXVpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHV1aWQgPz8gQ29sbGVjdGlvbnNVdGlsLmdlbmVyYXRlVVVJRCgpO1xuICAgIH1cbn1cbiJdfQ==