@versatiledatakit/shared
Version:
Versatile Data Kit Shared library enables reusability of shared features like: NgRx Redux, Error Handlers, Utils, Generic Components, etc.
241 lines • 35.3 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 { ConfirmationModelImpl, ERROR_CODE_CONFIRMATION_FORCEFULLY_DESTROYED_COMPONENT } from '../model/confirmation.model';
import { ConfirmationComponent, ConfirmationContainerComponent } from '../components';
import * as i0 from "@angular/core";
import * as i1 from "../../dynamic-components";
/**
* ** Confirmation Service that create confirmation view for every confirm request,
* and upon User action Confirm/Reject returns flow to the Invoker.
*
* - Utilizes <code>Promise<ConfirmationOutputModel></code> for communication.
*/
export class ConfirmationService extends TaurusObject {
/**
* ** Constructor.
*/
constructor(dynamicComponentsService) {
super(ConfirmationService.CLASS_NAME);
this.dynamicComponentsService = dynamicComponentsService;
}
/**
* ** Show confirm view according the provided model instructions, and return flow to the invoker upon User action Confirm/Reject.
*
* - Utilizes <b><code>Promise<ConfirmationOutputModel></code></b> for communication.
* - Sets some default values if model instructions are incomplete because most of them are optional.
*/
confirm(model) {
const modelImpl = new ConfirmationModelImpl(model);
const promise = new Promise((resolve, reject) => {
modelImpl.handler.confirm = resolve;
modelImpl.handler.dismiss = reject;
});
const acquireViewContainerRefStatus = this._acquireDynamicViewContainerRef();
if (!acquireViewContainerRefStatus.status) {
return Promise.reject(new Error(acquireViewContainerRefStatus.error));
}
const createConfContainerComponentStatus = this._createConfirmationContainerComponent();
if (!createConfContainerComponentStatus.status) {
return Promise.reject(new Error(createConfContainerComponentStatus.error));
}
const createConfComponentStatus = this._createConfirmationComponent(modelImpl);
if (!createConfComponentStatus.status) {
return Promise.reject(new Error(createConfComponentStatus.error));
}
if (!this._confirmationContainerRef.instance.open) {
this._confirmationContainerRef.instance.open = true;
this._confirmationContainerRef.changeDetectorRef.detectChanges();
}
return promise
.catch((reason) => {
if (reason instanceof Error && reason.message === ERROR_CODE_CONFIRMATION_FORCEFULLY_DESTROYED_COMPONENT) {
console.error(`${ConfirmationService.CLASS_NAME}: Potential bug found, views where destroyed externally from unknown source`);
}
throw reason;
})
.finally(() => {
this._clearSingleConfirmationResources(createConfComponentStatus);
});
}
/**
* ** Initialize service.
*
* - Should be invoked only once.
* - Ideal place for invoking is <code>AppComponent.ngOnInit()</code>.
*/
initialize() {
// No-op.
}
/**
* @inheritDoc
*/
ngOnDestroy() {
this._clearResources();
super.ngOnDestroy();
}
_acquireDynamicViewContainerRef() {
if (this._isAcquiredViewContainerRefUnhealthy()) {
this._clearResources();
}
if (!this._acquiredViewContainerRef) {
const acquiredViewContainerRef = this.dynamicComponentsService.getUniqueViewContainerRef();
if (!acquiredViewContainerRef) {
const errorMessage = `${ConfirmationService.CLASS_NAME}: Potential bug found, cannot acquire unique ViewContainerRef where to insert confirmation Views`;
console.error(errorMessage);
return {
status: false,
error: errorMessage
};
}
this._acquiredViewContainerRef = acquiredViewContainerRef;
}
return {
status: true
};
}
_createConfirmationContainerComponent() {
if (!this._confirmationContainerRef) {
try {
this._confirmationContainerRef =
this._acquiredViewContainerRef.viewContainerRef.createComponent(ConfirmationContainerComponent);
this._confirmationContainerRef.changeDetectorRef.detectChanges();
}
catch (e) {
const errorMessage = `${ConfirmationService.CLASS_NAME}: Potential bug found, Failed to create instance of ConfirmationContainerComponent`;
console.error(errorMessage);
return {
status: false,
error: errorMessage
};
}
}
return {
status: true
};
}
_createConfirmationComponent(model) {
try {
const confirmationComponentRef = this._confirmationContainerRef.instance.viewContainerRef.createComponent(ConfirmationComponent);
const assignMessageAndModelStatus = ConfirmationService._assignMessageAndModel(confirmationComponentRef, model);
if (!assignMessageAndModelStatus.status) {
console.error(assignMessageAndModelStatus.error);
return {
status: false,
error: assignMessageAndModelStatus.error
};
}
confirmationComponentRef.changeDetectorRef.detectChanges();
return {
status: true,
componentRef: confirmationComponentRef
};
}
catch (e) {
const errorMessage = `${ConfirmationService.CLASS_NAME}: Potential bug found, Failed to create instance of ConfirmationComponent`;
console.error(errorMessage);
return {
status: false,
error: errorMessage
};
}
}
_isAcquiredViewContainerRefUnhealthy() {
return (this._acquiredViewContainerRef && this._acquiredViewContainerRef.hostView && this._acquiredViewContainerRef.hostView.destroyed);
}
_refineConfirmationContainerVisibility(forceHide = false) {
if (this._confirmationContainerRef.instance.viewContainerRef.length === 0 || forceHide) {
this._confirmationContainerRef.instance.open = false;
this._confirmationContainerRef.changeDetectorRef.detectChanges();
}
}
_clearSingleConfirmationResources(internalModelRef) {
try {
const foundViewRefIndex = this._confirmationContainerRef.instance.viewContainerRef.indexOf(internalModelRef.componentRef.hostView);
if (foundViewRefIndex !== -1) {
this._confirmationContainerRef.instance.viewContainerRef.remove(foundViewRefIndex);
}
if (!internalModelRef.componentRef.hostView.destroyed) {
internalModelRef.componentRef.destroy();
}
internalModelRef.componentRef = null;
this._refineConfirmationContainerVisibility();
return;
}
catch (e) {
console.error(`${ConfirmationService.CLASS_NAME}: Potential bug found, failed to cleanup confirmation views after User action`);
}
try {
this._refineConfirmationContainerVisibility(true);
}
catch (e) {
console.error(`${ConfirmationService.CLASS_NAME}: Potential bug found, failed to force container to hide`);
}
}
_clearResources() {
try {
if (this._confirmationContainerRef?.hostView && !this._confirmationContainerRef.hostView.destroyed) {
this._confirmationContainerRef.destroy();
}
}
catch (e) {
console.error(`${ConfirmationService.CLASS_NAME}: Potential bug found, failed to destroy ConfirmationContainerComponent reference`);
}
this._confirmationContainerRef = null;
if (!this._acquiredViewContainerRef) {
return;
}
try {
this._acquiredViewContainerRef.viewContainerRef.clear();
}
catch (e) {
console.error(`${ConfirmationService.CLASS_NAME}: Potential bug found, failed to clear views in acquired ViewContainerRef`);
}
this.dynamicComponentsService.destroyUniqueViewContainerRef(this._acquiredViewContainerRef.uuid);
this._acquiredViewContainerRef = null;
}
static _assignMessageAndModel(confirmationComponentRef, model) {
let isMessageComponentCreated = false;
if (CollectionsUtil.isDefined(model.messageComponent)) {
try {
const messageComponentRef = confirmationComponentRef.instance.viewContainerRef.createComponent(model.messageComponent);
isMessageComponentCreated = true;
if (CollectionsUtil.isStringWithContent(model.messageCode)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
messageComponentRef.instance.messageCode = model.messageCode;
}
}
catch (e) {
const errorMessage = `${ConfirmationService.CLASS_NAME}: Potential bug found, Failed to create Component instance for Confirmation Message`;
console.error(errorMessage);
return {
status: false,
error: errorMessage
};
}
}
confirmationComponentRef.instance.model = new ConfirmationModelImpl({
...model,
messageComponent: undefined,
messageCode: undefined,
message: isMessageComponentCreated ? undefined : model.message
});
return {
status: true
};
}
}
/**
* @inheritDoc
*/
ConfirmationService.CLASS_NAME = 'ConfirmationService';
ConfirmationService.ɵfac = function ConfirmationService_Factory(t) { return new (t || ConfirmationService)(i0.ɵɵinject(i1.DynamicComponentsService)); };
ConfirmationService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ConfirmationService, factory: ConfirmationService.ɵfac });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConfirmationService, [{
type: Injectable
}], function () { return [{ type: i1.DynamicComponentsService }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlybWF0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaGFyZWQvc3JjL2xpYi9mZWF0dXJlcy9jb25maXJtYXRpb24vc2VydmljZXMvY29uZmlybWF0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFnQixVQUFVLEVBQXdDLE1BQU0sZUFBZSxDQUFDO0FBRS9GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFLL0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLHNEQUFzRCxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLDhCQUE4QixFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFFdEY7Ozs7O0dBS0c7QUFFSCxNQUFNLE9BQU8sbUJBQW9CLFNBQVEsWUFBWTtJQW9CakQ7O09BRUc7SUFDSCxZQUE2Qix3QkFBa0Q7UUFDM0UsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRGIsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtJQUUvRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxPQUFPLENBQUMsS0FBNkI7UUFDakMsTUFBTSxTQUFTLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBMEIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1lBQ3BDLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sNkJBQTZCLEdBQUcsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFDN0UsSUFBSSxDQUFDLDZCQUE2QixDQUFDLE1BQU0sRUFBRTtZQUN2QyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUN6RTtRQUVELE1BQU0sa0NBQWtDLEdBQUcsSUFBSSxDQUFDLHFDQUFxQyxFQUFFLENBQUM7UUFDeEYsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLE1BQU0sRUFBRTtZQUM1QyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUM5RTtRQUVELE1BQU0seUJBQXlCLEdBQUcsSUFBSSxDQUFDLDRCQUE0QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUU7WUFDbkMsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDckU7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUU7WUFDL0MsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUNwRTtRQUVELE9BQU8sT0FBTzthQUNULEtBQUssQ0FBQyxDQUFDLE1BQStCLEVBQUUsRUFBRTtZQUN2QyxJQUFJLE1BQU0sWUFBWSxLQUFLLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxzREFBc0QsRUFBRTtnQkFDdEcsT0FBTyxDQUFDLEtBQUssQ0FDVCxHQUFHLG1CQUFtQixDQUFDLFVBQVUsNkVBQTZFLENBQ2pILENBQUM7YUFDTDtZQUVELE1BQU0sTUFBTSxDQUFDO1FBQ2pCLENBQUMsQ0FBQzthQUNELE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDVixJQUFJLENBQUMsaUNBQWlDLENBQUMseUJBQWtGLENBQUMsQ0FBQztRQUMvSCxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFVBQVU7UUFDTixTQUFTO0lBQ2IsQ0FBQztJQUVEOztPQUVHO0lBQ00sV0FBVztRQUNoQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkIsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTywrQkFBK0I7UUFDbkMsSUFBSSxJQUFJLENBQUMsb0NBQW9DLEVBQUUsRUFBRTtZQUM3QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDMUI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFO1lBQ2pDLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHlCQUF5QixFQUFFLENBQUM7WUFDM0YsSUFBSSxDQUFDLHdCQUF3QixFQUFFO2dCQUMzQixNQUFNLFlBQVksR0FBRyxHQUFHLG1CQUFtQixDQUFDLFVBQVUsa0dBQWtHLENBQUM7Z0JBQ3pKLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBRTVCLE9BQU87b0JBQ0gsTUFBTSxFQUFFLEtBQUs7b0JBQ2IsS0FBSyxFQUFFLFlBQVk7aUJBQ3RCLENBQUM7YUFDTDtZQUVELElBQUksQ0FBQyx5QkFBeUIsR0FBRyx3QkFBd0IsQ0FBQztTQUM3RDtRQUVELE9BQU87WUFDSCxNQUFNLEVBQUUsSUFBSTtTQUNmLENBQUM7SUFDTixDQUFDO0lBRU8scUNBQXFDO1FBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMseUJBQXlCLEVBQUU7WUFDakMsSUFBSTtnQkFDQSxJQUFJLENBQUMseUJBQXlCO29CQUMxQixJQUFJLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLDhCQUE4QixDQUFDLENBQUM7Z0JBQ3BHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUNwRTtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLE1BQU0sWUFBWSxHQUFHLEdBQUcsbUJBQW1CLENBQUMsVUFBVSxvRkFBb0YsQ0FBQztnQkFDM0ksT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFFNUIsT0FBTztvQkFDSCxNQUFNLEVBQUUsS0FBSztvQkFDYixLQUFLLEVBQUUsWUFBWTtpQkFDdEIsQ0FBQzthQUNMO1NBQ0o7UUFFRCxPQUFPO1lBQ0gsTUFBTSxFQUFFLElBQUk7U0FDZixDQUFDO0lBQ04sQ0FBQztJQUVPLDRCQUE0QixDQUFDLEtBQTRCO1FBSzdELElBQUk7WUFDQSxNQUFNLHdCQUF3QixHQUMxQixJQUFJLENBQUMseUJBQXlCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBRXBHLE1BQU0sMkJBQTJCLEdBQUcsbUJBQW1CLENBQUMsc0JBQXNCLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFaEgsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE1BQU0sRUFBRTtnQkFDckMsT0FBTyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFakQsT0FBTztvQkFDSCxNQUFNLEVBQUUsS0FBSztvQkFDYixLQUFLLEVBQUUsMkJBQTJCLENBQUMsS0FBSztpQkFDM0MsQ0FBQzthQUNMO1lBRUQsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7WUFFM0QsT0FBTztnQkFDSCxNQUFNLEVBQUUsSUFBSTtnQkFDWixZQUFZLEVBQUUsd0JBQXdCO2FBQ3pDLENBQUM7U0FDTDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1IsTUFBTSxZQUFZLEdBQUcsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLDJFQUEyRSxDQUFDO1lBQ2xJLE9BQU8sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFNUIsT0FBTztnQkFDSCxNQUFNLEVBQUUsS0FBSztnQkFDYixLQUFLLEVBQUUsWUFBWTthQUN0QixDQUFDO1NBQ0w7SUFDTCxDQUFDO0lBRU8sb0NBQW9DO1FBQ3hDLE9BQU8sQ0FDSCxJQUFJLENBQUMseUJBQXlCLElBQUksSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMseUJBQXlCLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FDakksQ0FBQztJQUNOLENBQUM7SUFFTyxzQ0FBc0MsQ0FBQyxTQUFTLEdBQUcsS0FBSztRQUM1RCxJQUFJLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxTQUFTLEVBQUU7WUFDcEYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBQ3JELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUNwRTtJQUNMLENBQUM7SUFFTyxpQ0FBaUMsQ0FBQyxnQkFBdUU7UUFDN0csSUFBSTtZQUNBLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQ3RGLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxRQUFRLENBQ3pDLENBQUM7WUFDRixJQUFJLGlCQUFpQixLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUMxQixJQUFJLENBQUMseUJBQXlCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2FBQ3RGO1lBRUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFO2dCQUNuRCxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDM0M7WUFFRCxnQkFBZ0IsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBRXJDLElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxDQUFDO1lBRTlDLE9BQU87U0FDVjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLG1CQUFtQixDQUFDLFVBQVUsK0VBQStFLENBQUMsQ0FBQztTQUNuSTtRQUVELElBQUk7WUFDQSxJQUFJLENBQUMsc0NBQXNDLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDckQ7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLDBEQUEwRCxDQUFDLENBQUM7U0FDOUc7SUFDTCxDQUFDO0lBRU8sZUFBZTtRQUNuQixJQUFJO1lBQ0EsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUUsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7Z0JBQ2hHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUM1QztTQUNKO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDUixPQUFPLENBQUMsS0FBSyxDQUNULEdBQUcsbUJBQW1CLENBQUMsVUFBVSxtRkFBbUYsQ0FDdkgsQ0FBQztTQUNMO1FBRUQsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQztRQUV0QyxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFO1lBQ2pDLE9BQU87U0FDVjtRQUVELElBQUk7WUFDQSxJQUFJLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDM0Q7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLDJFQUEyRSxDQUFDLENBQUM7U0FDL0g7UUFFRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpHLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUM7SUFDMUMsQ0FBQztJQUVPLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDakMsd0JBQTZELEVBQzdELEtBQTRCO1FBRTVCLElBQUkseUJBQXlCLEdBQUcsS0FBSyxDQUFDO1FBRXRDLElBQUksZUFBZSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUNuRCxJQUFJO2dCQUNBLE1BQU0sbUJBQW1CLEdBQUcsd0JBQXdCLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFFdkgseUJBQXlCLEdBQUcsSUFBSSxDQUFDO2dCQUVqQyxJQUFJLGVBQWUsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUU7b0JBQ3hELHNFQUFzRTtvQkFDdEUsbUJBQW1CLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO2lCQUNoRTthQUNKO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsTUFBTSxZQUFZLEdBQUcsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLHFGQUFxRixDQUFDO2dCQUM1SSxPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUU1QixPQUFPO29CQUNILE1BQU0sRUFBRSxLQUFLO29CQUNiLEtBQUssRUFBRSxZQUFZO2lCQUN0QixDQUFDO2FBQ0w7U0FDSjtRQUVELHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQztZQUNoRSxHQUFHLEtBQUs7WUFDUixnQkFBZ0IsRUFBRSxTQUFTO1lBQzNCLFdBQVcsRUFBRSxTQUFTO1lBQ3RCLE9BQU8sRUFBRSx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTztTQUNqRSxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0gsTUFBTSxFQUFFLElBQUk7U0FDZixDQUFDO0lBQ04sQ0FBQzs7QUE1UkQ7O0dBRUc7QUFDc0IsOEJBQVUsR0FBVyxxQkFBc0IsQ0FBQTtzRkFKM0QsbUJBQW1CO3lFQUFuQixtQkFBbUIsV0FBbkIsbUJBQW1CO3VGQUFuQixtQkFBbUI7Y0FEL0IsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAyMy0yMDI1IEJyb2FkY29tXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudFJlZiwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBWaWV3Q29udGFpbmVyUmVmLCBWaWV3UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IENvbGxlY3Rpb25zVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzJztcblxuaW1wb3J0IHsgVGF1cnVzT2JqZWN0IH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uJztcblxuaW1wb3J0IHsgRHluYW1pY0NvbXBvbmVudHNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZHluYW1pYy1jb21wb25lbnRzJztcblxuaW1wb3J0IHsgQ29uZmlybWF0aW9uSW5wdXRNb2RlbCwgQ29uZmlybWF0aW9uT3V0cHV0TW9kZWwgfSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQgeyBDb25maXJtYXRpb25Nb2RlbEltcGwsIEVSUk9SX0NPREVfQ09ORklSTUFUSU9OX0ZPUkNFRlVMTFlfREVTVFJPWUVEX0NPTVBPTkVOVCB9IGZyb20gJy4uL21vZGVsL2NvbmZpcm1hdGlvbi5tb2RlbCc7XG5cbmltcG9ydCB7IENvbmZpcm1hdGlvbkNvbXBvbmVudCwgQ29uZmlybWF0aW9uQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50cyc7XG5cbi8qKlxuICogKiogQ29uZmlybWF0aW9uIFNlcnZpY2UgdGhhdCBjcmVhdGUgY29uZmlybWF0aW9uIHZpZXcgZm9yIGV2ZXJ5IGNvbmZpcm0gcmVxdWVzdCxcbiAqICAgICAgYW5kIHVwb24gVXNlciBhY3Rpb24gQ29uZmlybS9SZWplY3QgcmV0dXJucyBmbG93IHRvIHRoZSBJbnZva2VyLlxuICpcbiAqICAgICAgLSBVdGlsaXplcyA8Y29kZT5Qcm9taXNlPENvbmZpcm1hdGlvbk91dHB1dE1vZGVsPjwvY29kZT4gZm9yIGNvbW11bmljYXRpb24uXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDb25maXJtYXRpb25TZXJ2aWNlIGV4dGVuZHMgVGF1cnVzT2JqZWN0IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdERvY1xuICAgICAqL1xuICAgIHN0YXRpYyBvdmVycmlkZSByZWFkb25seSBDTEFTU19OQU1FOiBzdHJpbmcgPSAnQ29uZmlybWF0aW9uU2VydmljZSc7XG5cbiAgICAvKipcbiAgICAgKiAqKiBBY3F1aXJlZCBWaWV3Q29udGFpbmVyUmVmIGZyb20ge0BsaW5rIER5bmFtaWNDb21wb25lbnRzU2VydmljZX0sXG4gICAgICogICAgICB3aGVyZSBDb25maXJtYXRpb24gQ29udGFpbmVyIHtAbGluayBDb25maXJtYXRpb25Db250YWluZXJDb21wb25lbnR9IHdpbGwgYmUgaW5zZXJ0ZWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIF9hY3F1aXJlZFZpZXdDb250YWluZXJSZWY6IHsgdXVpZDogc3RyaW5nOyB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmOyBob3N0VmlldzogVmlld1JlZiB9O1xuXG4gICAgLyoqXG4gICAgICogKiogQ29uZmlybWF0aW9uIENvbnRhaW5lciByZWZlcmVuY2Uge0BsaW5rIENvbmZpcm1hdGlvbkNvbnRhaW5lckNvbXBvbmVudH0sXG4gICAgICogICAgICB3aGVyZSBhbGwgY29udGV4dHVhbCBDb25maXJtYXRpb24gY29tcG9uZW50cyB7QGxpbmsgQ29uZmlybWF0aW9uQ29tcG9uZW50fSB3aWxsIGJlIGluc2VydGVkLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBfY29uZmlybWF0aW9uQ29udGFpbmVyUmVmOiBDb21wb25lbnRSZWY8Q29uZmlybWF0aW9uQ29udGFpbmVyQ29tcG9uZW50PjtcblxuICAgIC8qKlxuICAgICAqICoqIENvbnN0cnVjdG9yLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZHluYW1pY0NvbXBvbmVudHNTZXJ2aWNlOiBEeW5hbWljQ29tcG9uZW50c1NlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoQ29uZmlybWF0aW9uU2VydmljZS5DTEFTU19OQU1FKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBTaG93IGNvbmZpcm0gdmlldyBhY2NvcmRpbmcgdGhlIHByb3ZpZGVkIG1vZGVsIGluc3RydWN0aW9ucywgYW5kIHJldHVybiBmbG93IHRvIHRoZSBpbnZva2VyIHVwb24gVXNlciBhY3Rpb24gQ29uZmlybS9SZWplY3QuXG4gICAgICpcbiAgICAgKiAgICAgIC0gVXRpbGl6ZXMgPGI+PGNvZGU+UHJvbWlzZTxDb25maXJtYXRpb25PdXRwdXRNb2RlbD48L2NvZGU+PC9iPiBmb3IgY29tbXVuaWNhdGlvbi5cbiAgICAgKiAgICAgIC0gU2V0cyBzb21lIGRlZmF1bHQgdmFsdWVzIGlmIG1vZGVsIGluc3RydWN0aW9ucyBhcmUgaW5jb21wbGV0ZSBiZWNhdXNlIG1vc3Qgb2YgdGhlbSBhcmUgb3B0aW9uYWwuXG4gICAgICovXG4gICAgY29uZmlybShtb2RlbDogQ29uZmlybWF0aW9uSW5wdXRNb2RlbCk6IFByb21pc2U8Q29uZmlybWF0aW9uT3V0cHV0TW9kZWw+IHtcbiAgICAgICAgY29uc3QgbW9kZWxJbXBsID0gbmV3IENvbmZpcm1hdGlvbk1vZGVsSW1wbChtb2RlbCk7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxDb25maXJtYXRpb25PdXRwdXRNb2RlbD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbW9kZWxJbXBsLmhhbmRsZXIuY29uZmlybSA9IHJlc29sdmU7XG4gICAgICAgICAgICBtb2RlbEltcGwuaGFuZGxlci5kaXNtaXNzID0gcmVqZWN0O1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY3F1aXJlVmlld0NvbnRhaW5lclJlZlN0YXR1cyA9IHRoaXMuX2FjcXVpcmVEeW5hbWljVmlld0NvbnRhaW5lclJlZigpO1xuICAgICAgICBpZiAoIWFjcXVpcmVWaWV3Q29udGFpbmVyUmVmU3RhdHVzLnN0YXR1cykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihhY3F1aXJlVmlld0NvbnRhaW5lclJlZlN0YXR1cy5lcnJvcikpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3JlYXRlQ29uZkNvbnRhaW5lckNvbXBvbmVudFN0YXR1cyA9IHRoaXMuX2NyZWF0ZUNvbmZpcm1hdGlvbkNvbnRhaW5lckNvbXBvbmVudCgpO1xuICAgICAgICBpZiAoIWNyZWF0ZUNvbmZDb250YWluZXJDb21wb25lbnRTdGF0dXMuc3RhdHVzKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGNyZWF0ZUNvbmZDb250YWluZXJDb21wb25lbnRTdGF0dXMuZXJyb3IpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbmZDb21wb25lbnRTdGF0dXMgPSB0aGlzLl9jcmVhdGVDb25maXJtYXRpb25Db21wb25lbnQobW9kZWxJbXBsKTtcbiAgICAgICAgaWYgKCFjcmVhdGVDb25mQ29tcG9uZW50U3RhdHVzLnN0YXR1cykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihjcmVhdGVDb25mQ29tcG9uZW50U3RhdHVzLmVycm9yKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2NvbmZpcm1hdGlvbkNvbnRhaW5lclJlZi5pbnN0YW5jZS5vcGVuKSB7XG4gICAgICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYuaW5zdGFuY2Uub3BlbiA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByb21pc2VcbiAgICAgICAgICAgIC5jYXRjaCgocmVhc29uOiBDb25maXJtYXRpb25PdXRwdXRNb2RlbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZWFzb24gaW5zdGFuY2VvZiBFcnJvciAmJiByZWFzb24ubWVzc2FnZSA9PT0gRVJST1JfQ09ERV9DT05GSVJNQVRJT05fRk9SQ0VGVUxMWV9ERVNUUk9ZRURfQ09NUE9ORU5UKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHtDb25maXJtYXRpb25TZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCB2aWV3cyB3aGVyZSBkZXN0cm95ZWQgZXh0ZXJuYWxseSBmcm9tIHVua25vd24gc291cmNlYFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xlYXJTaW5nbGVDb25maXJtYXRpb25SZXNvdXJjZXMoY3JlYXRlQ29uZkNvbXBvbmVudFN0YXR1cyBhcyB7IGNvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPENvbmZpcm1hdGlvbkNvbXBvbmVudD4gfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBJbml0aWFsaXplIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiAgICAgIC0gU2hvdWxkIGJlIGludm9rZWQgb25seSBvbmNlLlxuICAgICAqICAgICAgLSBJZGVhbCBwbGFjZSBmb3IgaW52b2tpbmcgaXMgPGNvZGU+QXBwQ29tcG9uZW50Lm5nT25Jbml0KCk8L2NvZGU+LlxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKTogdm9pZCB7XG4gICAgICAgIC8vIE5vLW9wLlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBpbmhlcml0RG9jXG4gICAgICovXG4gICAgb3ZlcnJpZGUgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2NsZWFyUmVzb3VyY2VzKCk7XG5cbiAgICAgICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9hY3F1aXJlRHluYW1pY1ZpZXdDb250YWluZXJSZWYoKTogeyBzdGF0dXM6IGJvb2xlYW47IGVycm9yPzogc3RyaW5nIH0ge1xuICAgICAgICBpZiAodGhpcy5faXNBY3F1aXJlZFZpZXdDb250YWluZXJSZWZVbmhlYWx0aHkoKSkge1xuICAgICAgICAgICAgdGhpcy5fY2xlYXJSZXNvdXJjZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmKSB7XG4gICAgICAgICAgICBjb25zdCBhY3F1aXJlZFZpZXdDb250YWluZXJSZWYgPSB0aGlzLmR5bmFtaWNDb21wb25lbnRzU2VydmljZS5nZXRVbmlxdWVWaWV3Q29udGFpbmVyUmVmKCk7XG4gICAgICAgICAgICBpZiAoIWFjcXVpcmVkVmlld0NvbnRhaW5lclJlZikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGAke0NvbmZpcm1hdGlvblNlcnZpY2UuQ0xBU1NfTkFNRX06IFBvdGVudGlhbCBidWcgZm91bmQsIGNhbm5vdCBhY3F1aXJlIHVuaXF1ZSBWaWV3Q29udGFpbmVyUmVmIHdoZXJlIHRvIGluc2VydCBjb25maXJtYXRpb24gVmlld3NgO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9hY3F1aXJlZFZpZXdDb250YWluZXJSZWYgPSBhY3F1aXJlZFZpZXdDb250YWluZXJSZWY7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JlYXRlQ29uZmlybWF0aW9uQ29udGFpbmVyQ29tcG9uZW50KCk6IHsgc3RhdHVzOiBib29sZWFuOyBlcnJvcj86IHN0cmluZyB9IHtcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlybWF0aW9uQ29udGFpbmVyUmVmID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KENvbmZpcm1hdGlvbkNvbnRhaW5lckNvbXBvbmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlybWF0aW9uQ29udGFpbmVyUmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgJHtDb25maXJtYXRpb25TZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBGYWlsZWQgdG8gY3JlYXRlIGluc3RhbmNlIG9mIENvbmZpcm1hdGlvbkNvbnRhaW5lckNvbXBvbmVudGA7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvck1lc3NhZ2UpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JlYXRlQ29uZmlybWF0aW9uQ29tcG9uZW50KG1vZGVsOiBDb25maXJtYXRpb25Nb2RlbEltcGwpOiB7XG4gICAgICAgIHN0YXR1czogYm9vbGVhbjtcbiAgICAgICAgY29tcG9uZW50UmVmPzogQ29tcG9uZW50UmVmPENvbmZpcm1hdGlvbkNvbXBvbmVudD47XG4gICAgICAgIGVycm9yPzogc3RyaW5nO1xuICAgIH0ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY29uZmlybWF0aW9uQ29tcG9uZW50UmVmID1cbiAgICAgICAgICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYuaW5zdGFuY2Uudmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoQ29uZmlybWF0aW9uQ29tcG9uZW50KTtcblxuICAgICAgICAgICAgY29uc3QgYXNzaWduTWVzc2FnZUFuZE1vZGVsU3RhdHVzID0gQ29uZmlybWF0aW9uU2VydmljZS5fYXNzaWduTWVzc2FnZUFuZE1vZGVsKGNvbmZpcm1hdGlvbkNvbXBvbmVudFJlZiwgbW9kZWwpO1xuXG4gICAgICAgICAgICBpZiAoIWFzc2lnbk1lc3NhZ2VBbmRNb2RlbFN0YXR1cy5zdGF0dXMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGFzc2lnbk1lc3NhZ2VBbmRNb2RlbFN0YXR1cy5lcnJvcik7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogYXNzaWduTWVzc2FnZUFuZE1vZGVsU3RhdHVzLmVycm9yXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlybWF0aW9uQ29tcG9uZW50UmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHRydWUsXG4gICAgICAgICAgICAgICAgY29tcG9uZW50UmVmOiBjb25maXJtYXRpb25Db21wb25lbnRSZWZcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGAke0NvbmZpcm1hdGlvblNlcnZpY2UuQ0xBU1NfTkFNRX06IFBvdGVudGlhbCBidWcgZm91bmQsIEZhaWxlZCB0byBjcmVhdGUgaW5zdGFuY2Ugb2YgQ29uZmlybWF0aW9uQ29tcG9uZW50YDtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNZXNzYWdlKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9pc0FjcXVpcmVkVmlld0NvbnRhaW5lclJlZlVuaGVhbHRoeSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuX2FjcXVpcmVkVmlld0NvbnRhaW5lclJlZiAmJiB0aGlzLl9hY3F1aXJlZFZpZXdDb250YWluZXJSZWYuaG9zdFZpZXcgJiYgdGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmLmhvc3RWaWV3LmRlc3Ryb3llZFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlZmluZUNvbmZpcm1hdGlvbkNvbnRhaW5lclZpc2liaWxpdHkoZm9yY2VIaWRlID0gZmFsc2UpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2NvbmZpcm1hdGlvbkNvbnRhaW5lclJlZi5pbnN0YW5jZS52aWV3Q29udGFpbmVyUmVmLmxlbmd0aCA9PT0gMCB8fCBmb3JjZUhpZGUpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbmZpcm1hdGlvbkNvbnRhaW5lclJlZi5pbnN0YW5jZS5vcGVuID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2xlYXJTaW5nbGVDb25maXJtYXRpb25SZXNvdXJjZXMoaW50ZXJuYWxNb2RlbFJlZjogeyBjb21wb25lbnRSZWY6IENvbXBvbmVudFJlZjxDb25maXJtYXRpb25Db21wb25lbnQ+IH0pOiB2b2lkIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGZvdW5kVmlld1JlZkluZGV4ID0gdGhpcy5fY29uZmlybWF0aW9uQ29udGFpbmVyUmVmLmluc3RhbmNlLnZpZXdDb250YWluZXJSZWYuaW5kZXhPZihcbiAgICAgICAgICAgICAgICBpbnRlcm5hbE1vZGVsUmVmLmNvbXBvbmVudFJlZi5ob3N0Vmlld1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChmb3VuZFZpZXdSZWZJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYuaW5zdGFuY2Uudmlld0NvbnRhaW5lclJlZi5yZW1vdmUoZm91bmRWaWV3UmVmSW5kZXgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWludGVybmFsTW9kZWxSZWYuY29tcG9uZW50UmVmLmhvc3RWaWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgIGludGVybmFsTW9kZWxSZWYuY29tcG9uZW50UmVmLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW50ZXJuYWxNb2RlbFJlZi5jb21wb25lbnRSZWYgPSBudWxsO1xuXG4gICAgICAgICAgICB0aGlzLl9yZWZpbmVDb25maXJtYXRpb25Db250YWluZXJWaXNpYmlsaXR5KCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHtDb25maXJtYXRpb25TZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBmYWlsZWQgdG8gY2xlYW51cCBjb25maXJtYXRpb24gdmlld3MgYWZ0ZXIgVXNlciBhY3Rpb25gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLl9yZWZpbmVDb25maXJtYXRpb25Db250YWluZXJWaXNpYmlsaXR5KHRydWUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke0NvbmZpcm1hdGlvblNlcnZpY2UuQ0xBU1NfTkFNRX06IFBvdGVudGlhbCBidWcgZm91bmQsIGZhaWxlZCB0byBmb3JjZSBjb250YWluZXIgdG8gaGlkZWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2xlYXJSZXNvdXJjZXMoKTogdm9pZCB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uZmlybWF0aW9uQ29udGFpbmVyUmVmPy5ob3N0VmlldyAmJiAhdGhpcy5fY29uZmlybWF0aW9uQ29udGFpbmVyUmVmLmhvc3RWaWV3LmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbmZpcm1hdGlvbkNvbnRhaW5lclJlZi5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgYCR7Q29uZmlybWF0aW9uU2VydmljZS5DTEFTU19OQU1FfTogUG90ZW50aWFsIGJ1ZyBmb3VuZCwgZmFpbGVkIHRvIGRlc3Ryb3kgQ29uZmlybWF0aW9uQ29udGFpbmVyQ29tcG9uZW50IHJlZmVyZW5jZWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jb25maXJtYXRpb25Db250YWluZXJSZWYgPSBudWxsO1xuXG4gICAgICAgIGlmICghdGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmLnZpZXdDb250YWluZXJSZWYuY2xlYXIoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHtDb25maXJtYXRpb25TZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBmYWlsZWQgdG8gY2xlYXIgdmlld3MgaW4gYWNxdWlyZWQgVmlld0NvbnRhaW5lclJlZmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5keW5hbWljQ29tcG9uZW50c1NlcnZpY2UuZGVzdHJveVVuaXF1ZVZpZXdDb250YWluZXJSZWYodGhpcy5fYWNxdWlyZWRWaWV3Q29udGFpbmVyUmVmLnV1aWQpO1xuXG4gICAgICAgIHRoaXMuX2FjcXVpcmVkVmlld0NvbnRhaW5lclJlZiA9IG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX2Fzc2lnbk1lc3NhZ2VBbmRNb2RlbChcbiAgICAgICAgY29uZmlybWF0aW9uQ29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8Q29uZmlybWF0aW9uQ29tcG9uZW50PixcbiAgICAgICAgbW9kZWw6IENvbmZpcm1hdGlvbk1vZGVsSW1wbFxuICAgICk6IHsgc3RhdHVzOiBib29sZWFuOyBlcnJvcj86IHN0cmluZyB9IHtcbiAgICAgICAgbGV0IGlzTWVzc2FnZUNvbXBvbmVudENyZWF0ZWQgPSBmYWxzZTtcblxuICAgICAgICBpZiAoQ29sbGVjdGlvbnNVdGlsLmlzRGVmaW5lZChtb2RlbC5tZXNzYWdlQ29tcG9uZW50KSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlQ29tcG9uZW50UmVmID0gY29uZmlybWF0aW9uQ29tcG9uZW50UmVmLmluc3RhbmNlLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KG1vZGVsLm1lc3NhZ2VDb21wb25lbnQpO1xuXG4gICAgICAgICAgICAgICAgaXNNZXNzYWdlQ29tcG9uZW50Q3JlYXRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoQ29sbGVjdGlvbnNVdGlsLmlzU3RyaW5nV2l0aENvbnRlbnQobW9kZWwubWVzc2FnZUNvZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNvbXBvbmVudFJlZi5pbnN0YW5jZS5tZXNzYWdlQ29kZSA9IG1vZGVsLm1lc3NhZ2VDb2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgJHtDb25maXJtYXRpb25TZXJ2aWNlLkNMQVNTX05BTUV9OiBQb3RlbnRpYWwgYnVnIGZvdW5kLCBGYWlsZWQgdG8gY3JlYXRlIENvbXBvbmVudCBpbnN0YW5jZSBmb3IgQ29uZmlybWF0aW9uIE1lc3NhZ2VgO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlybWF0aW9uQ29tcG9uZW50UmVmLmluc3RhbmNlLm1vZGVsID0gbmV3IENvbmZpcm1hdGlvbk1vZGVsSW1wbCh7XG4gICAgICAgICAgICAuLi5tb2RlbCxcbiAgICAgICAgICAgIG1lc3NhZ2VDb21wb25lbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG1lc3NhZ2VDb2RlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBpc01lc3NhZ2VDb21wb25lbnRDcmVhdGVkID8gdW5kZWZpbmVkIDogbW9kZWwubWVzc2FnZVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhdHVzOiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxufVxuIl19