@indice/ng-components
Version:
Indice common components for Angular v12
220 lines • 32.4 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, Optional } from '@angular/core';
import { Subject } from 'rxjs';
import { animationTime, cssClassNames } from './modal-styles.class';
import { ModalBackdropComponent } from './modal-backdrop-component';
import { ModalContainerComponent } from './modal-container-component';
import { modalConfigDefaults, ModalOptions, MODAL_CONFIG_DEFAULT_OVERRIDE } from './modal-options.class';
import { Modal } from './modal.class';
import * as i0 from "@angular/core";
import * as i1 from "../component-loader/component-loader.factory";
import * as i2 from "./modal-options.class";
/**
* A service for using modals.
*
* @public
*/
export class ModalService {
constructor(clf, rendererFactory, document, modalDefaultOption) {
this.clf = clf;
this.document = document;
this.onBeforeShow = new Subject();
this.onShown = new Subject();
this.onBeforeHide = new Subject();
this.onHidden = new Subject();
this.loaders = [];
this.modalsCount = 0;
this.initialPadding = '0px';
this.backdropLoader = this.clf.createLoader();
this.defaultConfig = { ...modalConfigDefaults, ...modalDefaultOption };
this.renderer = rendererFactory.createRenderer(null, null);
}
ngOnDestroy() {
this.loaders.forEach((loader) => loader.instance?.hide());
}
/**
* Opens a new modal.
*
* @param content - `Component` or `TemplateRef` type.
* @param config - Specific {@link ModalOptions | options} for this modal. Global and specific options are merged.
* @returns An instance of {@link Modal}
*/
show(content, config) {
this.modalsCount++;
const combinedConfig = { ...this.defaultConfig, ...config };
combinedConfig.id = config?.id || new Date().getUTCMilliseconds();
console.log('show', combinedConfig);
this.createLoaders();
this.addBodyPadding();
if (this.modalsCount === 1) {
this.renderer.addClass(this.document.body, cssClassNames.modalOpen);
}
this.showBackdrop(combinedConfig);
return this.showModal(content, combinedConfig);
}
/**
* Hide an active modal.
* @param id - Id of modal to hide. If not provided all active modals are hidden.
* @param result - A result to be sent to observers.
*/
hide(id, result) {
if (this.modalsCount === 1 || id == null) {
this.hideBackdrop();
this.revertScrollbar();
this.renderer.removeClass(this.document.body, cssClassNames.modalOpen);
}
this.modalsCount = this.modalsCount >= 1 && id != null ? this.modalsCount - 1 : 0;
setTimeout(() => {
this.hideModal(id, result);
this.removeLoaders(id);
},
//Bug
//Should use combined config but for the moment is not possible to pass it this parameter.
//If config is an instance variable then every newly opened modal will override the config
//resulting in opened modals to get a new configuration
this.defaultConfig.animated ? animationTime.backdrop : 0);
}
getActiveModal() {
return this.loaders[this.modalsCount - 1].instance;
}
showModal(content, combinedConfig) {
const modalLoader = this.loaders[this.loaders.length - 1];
if (combinedConfig && combinedConfig.providers) {
combinedConfig.providers.forEach((provider) => modalLoader.provide(provider));
}
const modal = new Modal();
const modalContainerRef = modalLoader
.provide({ provide: ModalOptions, useValue: combinedConfig })
.provide({ provide: Modal, useValue: modal })
.attach(ModalContainerComponent)
.to('body');
modal.setClass = (newClass) => {
if (modalContainerRef.instance) {
modalContainerRef.instance.config.class = newClass;
}
};
modal.onBeforeHide = new Subject();
modal.onHidden = new Subject();
this.copyEvent(modalLoader.onBeforeHide, modal.onBeforeHide);
this.copyEvent(modalLoader.onHidden, modal.onHidden);
modalContainerRef.show({
content,
animationsEnabled: combinedConfig.animated,
initialState: combinedConfig.initialState,
modalService: this,
id: combinedConfig.id,
});
if (modalContainerRef.instance) {
modalContainerRef.instance.level = this.modalsCount;
modal.content = modalLoader.getInnerComponent();
modal.id = modalContainerRef.instance.config?.id;
modal.hide = (res) => modalContainerRef.instance?.hide(res);
}
return modal;
}
hideModal(id, result) {
if (id != null) {
const indexToRemove = this.loaders.findIndex((loader) => loader.instance?.config.id === id);
const modalLoader = this.loaders[indexToRemove];
if (modalLoader) {
modalLoader.hide(id, result);
}
}
else {
this.loaders.forEach((loader) => {
if (loader.instance) {
loader.hide(loader.instance.config.id);
}
});
}
}
showBackdrop(combinedConfig) {
const isBackdropEnabled = combinedConfig.backdrop === true || combinedConfig.backdrop === 'static';
const isBackdropInDOM = this.backdropRef != null;
if (isBackdropEnabled && !isBackdropInDOM) {
this.backdropLoader
.attach(ModalBackdropComponent)
.to('body')
.show({ animationsEnabled: combinedConfig.animated, backdropLoader: this.backdropLoader });
this.backdropRef = this.backdropLoader.componentRef;
}
}
hideBackdrop() {
if (!this.backdropRef) {
return;
}
this.backdropRef.instance.hide();
this.backdropRef = void 0;
}
removeLoaders(id) {
if (id != null) {
const indexToRemove = this.loaders.findIndex((loader) => loader.instance?.config.id === id);
if (indexToRemove >= 0) {
this.loaders.splice(indexToRemove, 1);
this.loaders.forEach((loader, i) => {
if (loader.instance) {
loader.instance.level = i + 1;
}
});
}
}
else {
this.loaders.splice(0, this.loaders.length);
}
}
addBodyPadding() {
if (this.modalsCount === 1) {
const width = this.getScrollbarWidth();
if (this.isScrollBarPresent(width)) {
this.initialPadding = this.document.body.style.paddingRight;
const actualPadding = parseFloat(window.getComputedStyle(this.document.body).paddingRight);
this.document.body.style.paddingRight = `${actualPadding + width}px`;
}
}
}
revertScrollbar() {
this.document.body.style.paddingRight = this.initialPadding;
}
getScrollbarWidth() {
const measurer = this.document.createElement('div');
measurer.className = 'modal-scrollbar-measure';
const body = this.document.body;
body.appendChild(measurer);
const width = measurer.getBoundingClientRect().width - measurer.clientWidth;
body.removeChild(measurer);
return width;
}
isScrollBarPresent(scrollbarWidth) {
const rect = this.document.body.getBoundingClientRect();
const bodyToViewportGap = window.innerWidth - (rect.left + rect.right);
const uncertainty = 0.1 * scrollbarWidth;
return bodyToViewportGap >= scrollbarWidth - uncertainty;
}
createLoaders() {
const loader = this.clf.createLoader();
this.copyEvent(loader.onBeforeShow, this.onBeforeShow);
this.copyEvent(loader.onShown, this.onShown);
this.copyEvent(loader.onBeforeHide, this.onBeforeHide);
this.copyEvent(loader.onHidden, this.onHidden);
this.loaders.push(loader);
}
copyEvent(from, to) {
from.subscribe((data) => {
to.next(data);
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: ModalService, deps: [{ token: i1.ComponentLoaderFactory }, { token: i0.RendererFactory2 }, { token: DOCUMENT }, { token: MODAL_CONFIG_DEFAULT_OVERRIDE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: ModalService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: ModalService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.ComponentLoaderFactory }, { type: i0.RendererFactory2 }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i2.ModalOptions, decorators: [{
type: Optional
}, {
type: Inject,
args: [MODAL_CONFIG_DEFAULT_OVERRIDE]
}] }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwtc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWNvbXBvbmVudHMvc3JjL2xpYi9zZXJ2aWNlcy9tb2RhbC1zZXJ2aWNlL21vZGFsLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBZ0IsTUFBTSxFQUFFLFVBQVUsRUFBYSxRQUFRLEVBQTRDLE1BQU0sZUFBZSxDQUFDO0FBQ2hJLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLDZCQUE2QixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDekcsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQUd0Qzs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLFlBQVk7SUFhdkIsWUFDVSxHQUEyQixFQUNuQyxlQUFpQyxFQUNQLFFBQWEsRUFDWSxrQkFBZ0M7UUFIM0UsUUFBRyxHQUFILEdBQUcsQ0FBd0I7UUFFVCxhQUFRLEdBQVIsUUFBUSxDQUFLO1FBZmpDLGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM3QixZQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUN4QixpQkFBWSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFLekIsWUFBTyxHQUErQyxFQUFFLENBQUM7UUFFekQsZ0JB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QUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUFzQixFQUFFLEVBQW9CO1FBQzVELElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUN0QixFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs4R0EzTlUsWUFBWSx3RkFnQmIsUUFBUSxhQUNJLDZCQUE2QjtrSEFqQnhDLFlBQVk7OzJGQUFaLFlBQVk7a0JBRHhCLFVBQVU7OzBCQWlCTixNQUFNOzJCQUFDLFFBQVE7OzBCQUNmLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsNkJBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnRSZWYsIEluamVjdCwgSW5qZWN0YWJsZSwgT25EZXN0cm95LCBPcHRpb25hbCwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENvbXBvbmVudExvYWRlciB9IGZyb20gJy4uL2NvbXBvbmVudC1sb2FkZXIvY29tcG9uZW50LWxvYWRlci5jbGFzcyc7XHJcbmltcG9ydCB7IGFuaW1hdGlvblRpbWUsIGNzc0NsYXNzTmFtZXMgfSBmcm9tICcuL21vZGFsLXN0eWxlcy5jbGFzcyc7XHJcbmltcG9ydCB7IE1vZGFsQmFja2Ryb3BDb21wb25lbnQgfSBmcm9tICcuL21vZGFsLWJhY2tkcm9wLWNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE1vZGFsQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9tb2RhbC1jb250YWluZXItY29tcG9uZW50JztcclxuaW1wb3J0IHsgbW9kYWxDb25maWdEZWZhdWx0cywgTW9kYWxPcHRpb25zLCBNT0RBTF9DT05GSUdfREVGQVVMVF9PVkVSUklERSB9IGZyb20gJy4vbW9kYWwtb3B0aW9ucy5jbGFzcyc7XHJcbmltcG9ydCB7IE1vZGFsIH0gZnJvbSAnLi9tb2RhbC5jbGFzcyc7XHJcbmltcG9ydCB7IENvbXBvbmVudExvYWRlckZhY3RvcnkgfSBmcm9tICcuLi9jb21wb25lbnQtbG9hZGVyL2NvbXBvbmVudC1sb2FkZXIuZmFjdG9yeSc7XHJcblxyXG4vKipcclxuICogQSBzZXJ2aWNlIGZvciB1c2luZyBtb2RhbHMuXHJcbiAqXHJcbiAqIEBwdWJsaWNcclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE1vZGFsU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcbiAgcHJpdmF0ZSBvbkJlZm9yZVNob3cgPSBuZXcgU3ViamVjdCgpO1xyXG4gIHByaXZhdGUgb25TaG93biA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgcHJpdmF0ZSBvbkJlZm9yZUhpZGUgPSBuZXcgU3ViamVjdCgpO1xyXG4gIHByaXZhdGUgb25IaWRkZW4gPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICBwcml2YXRlIGJhY2tkcm9wUmVmPzogQ29tcG9uZW50UmVmPE1vZGFsQmFja2Ryb3BDb21wb25lbnQ+O1xyXG4gIHByaXZhdGUgZGVmYXVsdENvbmZpZzogTW9kYWxPcHRpb25zO1xyXG4gIHByaXZhdGUgYmFja2Ryb3BMb2FkZXI6IENvbXBvbmVudExvYWRlcjxNb2RhbEJhY2tkcm9wQ29tcG9uZW50PjtcclxuICBwcml2YXRlIGxvYWRlcnM6IENvbXBvbmVudExvYWRlcjxNb2RhbENvbnRhaW5lckNvbXBvbmVudD5bXSA9IFtdO1xyXG4gIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMjtcclxuICBwcml2YXRlIG1vZGFsc0NvdW50ID0gMDtcclxuICBwcml2YXRlIGluaXRpYWxQYWRkaW5nID0gJzBweCc7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGNsZjogQ29tcG9uZW50TG9hZGVyRmFjdG9yeSxcclxuICAgIHJlbmRlcmVyRmFjdG9yeTogUmVuZGVyZXJGYWN0b3J5MixcclxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IGFueSxcclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTU9EQUxfQ09ORklHX0RFRkFVTFRfT1ZFUlJJREUpIG1vZGFsRGVmYXVsdE9wdGlvbjogTW9kYWxPcHRpb25zXHJcbiAgKSB7XHJcbiAgICB0aGlzLmJhY2tkcm9wTG9hZGVyID0gdGhpcy5jbGYuY3JlYXRlTG9hZGVyPE1vZGFsQmFja2Ryb3BDb21wb25lbnQ+KCk7XHJcbiAgICB0aGlzLmRlZmF1bHRDb25maWcgPSB7IC4uLm1vZGFsQ29uZmlnRGVmYXVsdHMsIC4uLm1vZGFsRGVmYXVsdE9wdGlvbiB9O1xyXG4gICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5sb2FkZXJzLmZvckVhY2goKGxvYWRlcikgPT4gbG9hZGVyLmluc3RhbmNlPy5oaWRlKCkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT3BlbnMgYSBuZXcgbW9kYWwuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY29udGVudCAtIGBDb21wb25lbnRgIG9yIGBUZW1wbGF0ZVJlZmAgdHlwZS5cclxuICAgKiBAcGFyYW0gY29uZmlnIC0gU3BlY2lmaWMge0BsaW5rIE1vZGFsT3B0aW9ucyB8IG9wdGlvbnN9ICBmb3IgdGhpcyBtb2RhbC4gR2xvYmFsIGFuZCBzcGVjaWZpYyBvcHRpb25zIGFyZSBtZXJnZWQuXHJcbiAgICogQHJldHVybnMgQW4gaW5zdGFuY2Ugb2Yge0BsaW5rIE1vZGFsfVxyXG4gICAqL1xyXG4gIHB1YmxpYyBzaG93PFQ+KGNvbnRlbnQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT4gfCB7IG5ldyAoLi4uYXJnczogYW55W10pOiBUIH0sIGNvbmZpZz86IE1vZGFsT3B0aW9uczxUPikge1xyXG4gICAgdGhpcy5tb2RhbHNDb3VudCsrO1xyXG4gICAgY29uc3QgY29tYmluZWRDb25maWcgPSB7IC4uLnRoaXMuZGVmYXVsdENvbmZpZywgLi4uY29uZmlnIH07XHJcbiAgICBjb21iaW5lZENvbmZpZy5pZCA9IGNvbmZpZz8uaWQgfHwgbmV3IERhdGUoKS5nZXRVVENNaWxsaXNlY29uZHMoKTtcclxuICAgIGNvbnNvbGUubG9nKCdzaG93JywgY29tYmluZWRDb25maWcpO1xyXG4gICAgdGhpcy5jcmVhdGVMb2FkZXJzKCk7XHJcblxyXG4gICAgdGhpcy5hZGRCb2R5UGFkZGluZygpO1xyXG4gICAgaWYgKHRoaXMubW9kYWxzQ291bnQgPT09IDEpIHtcclxuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmRvY3VtZW50LmJvZHksIGNzc0NsYXNzTmFtZXMubW9kYWxPcGVuKTtcclxuICAgIH1cclxuICAgIHRoaXMuc2hvd0JhY2tkcm9wKGNvbWJpbmVkQ29uZmlnKTtcclxuICAgIHJldHVybiB0aGlzLnNob3dNb2RhbDxUPihjb250ZW50LCBjb21iaW5lZENvbmZpZyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIaWRlIGFuIGFjdGl2ZSBtb2RhbC5cclxuICAgKiBAcGFyYW0gaWQgLSBJZCBvZiBtb2RhbCB0byBoaWRlLiBJZiBub3QgcHJvdmlkZWQgYWxsIGFjdGl2ZSBtb2RhbHMgYXJlIGhpZGRlbi5cclxuICAgKiBAcGFyYW0gcmVzdWx0IC0gQSByZXN1bHQgdG8gYmUgc2VudCB0byBvYnNlcnZlcnMuXHJcbiAgICovXHJcbiAgcHVibGljIGhpZGUoaWQ/OiBudW1iZXIgfCBzdHJpbmcsIHJlc3VsdD86IGFueSkge1xyXG4gICAgaWYgKHRoaXMubW9kYWxzQ291bnQgPT09IDEgfHwgaWQgPT0gbnVsbCkge1xyXG4gICAgICB0aGlzLmhpZGVCYWNrZHJvcCgpO1xyXG4gICAgICB0aGlzLnJldmVydFNjcm9sbGJhcigpO1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZG9jdW1lbnQuYm9keSwgY3NzQ2xhc3NOYW1lcy5tb2RhbE9wZW4pO1xyXG4gICAgfVxyXG4gICAgdGhpcy5tb2RhbHNDb3VudCA9IHRoaXMubW9kYWxzQ291bnQgPj0gMSAmJiBpZCAhPSBudWxsID8gdGhpcy5tb2RhbHNDb3VudCAtIDEgOiAwO1xyXG4gICAgc2V0VGltZW91dChcclxuICAgICAgKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuaGlkZU1vZGFsKGlkLCByZXN1bHQpO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlTG9hZGVycyhpZCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIC8vQnVnXHJcbiAgICAgIC8vU2hvdWxkIHVzZSBjb21iaW5lZCBjb25maWcgYnV0IGZvciB0aGUgbW9tZW50IGlzIG5vdCBwb3NzaWJsZSB0byBwYXNzIGl0IHRoaXMgcGFyYW1ldGVyLlxyXG4gICAgICAvL0lmIGNvbmZpZyBpcyBhbiBpbnN0YW5jZSB2YXJpYWJsZSB0aGVuIGV2ZXJ5IG5ld2x5IG9wZW5lZCBtb2RhbCB3aWxsIG92ZXJyaWRlIHRoZSBjb25maWdcclxuICAgICAgLy9yZXN1bHRpbmcgaW4gb3BlbmVkIG1vZGFscyB0byBnZXQgYSBuZXcgY29uZmlndXJhdGlvblxyXG4gICAgICB0aGlzLmRlZmF1bHRDb25maWcuYW5pbWF0ZWQgPyBhbmltYXRpb25UaW1lLmJhY2tkcm9wIDogMFxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRBY3RpdmVNb2RhbCgpOiBNb2RhbENvbnRhaW5lckNvbXBvbmVudCB7XHJcbiAgICByZXR1cm4gdGhpcy5sb2FkZXJzW3RoaXMubW9kYWxzQ291bnQgLSAxXS5pbnN0YW5jZSBhcyBNb2RhbENvbnRhaW5lckNvbXBvbmVudDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2hvd01vZGFsPFQ+KGNvbnRlbnQ6IGFueSwgY29tYmluZWRDb25maWc6IE1vZGFsT3B0aW9ucyk6IE1vZGFsPFQ+IHtcclxuICAgIGNvbnN0IG1vZGFsTG9hZGVyID0gdGhpcy5sb2FkZXJzW3RoaXMubG9hZGVycy5sZW5ndGggLSAxXTtcclxuICAgIGlmIChjb21iaW5lZENvbmZpZyAmJiBjb21iaW5lZENvbmZpZy5wcm92aWRlcnMpIHtcclxuICAgICAgY29tYmluZWRDb25maWcucHJvdmlkZXJzLmZvckVhY2goKHByb3ZpZGVyKSA9PiBtb2RhbExvYWRlci5wcm92aWRlKHByb3ZpZGVyKSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbW9kYWwgPSBuZXcgTW9kYWw8YW55PigpO1xyXG4gICAgY29uc3QgbW9kYWxDb250YWluZXJSZWYgPSBtb2RhbExvYWRlclxyXG4gICAgICAucHJvdmlkZSh7IHByb3ZpZGU6IE1vZGFsT3B0aW9ucywgdXNlVmFsdWU6IGNvbWJpbmVkQ29uZmlnIH0pXHJcbiAgICAgIC5wcm92aWRlKHsgcHJvdmlkZTogTW9kYWwsIHVzZVZhbHVlOiBtb2RhbCB9KVxyXG4gICAgICAuYXR0YWNoKE1vZGFsQ29udGFpbmVyQ29tcG9uZW50KVxyXG4gICAgICAudG8oJ2JvZHknKTtcclxuXHJcbiAgICBtb2RhbC5zZXRDbGFzcyA9IChuZXdDbGFzczogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmIChtb2RhbENvbnRhaW5lclJlZi5pbnN0YW5jZSkge1xyXG4gICAgICAgIG1vZGFsQ29udGFpbmVyUmVmLmluc3RhbmNlLmNvbmZpZy5jbGFzcyA9IG5ld0NsYXNzO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIG1vZGFsLm9uQmVmb3JlSGlkZSA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICBtb2RhbC5vbkhpZGRlbiA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICB0aGlzLmNvcHlFdmVudChtb2RhbExvYWRlci5vbkJlZm9yZUhpZGUsIG1vZGFsLm9uQmVmb3JlSGlkZSk7XHJcbiAgICB0aGlzLmNvcHlFdmVudChtb2RhbExvYWRlci5vbkhpZGRlbiwgbW9kYWwub25IaWRkZW4pO1xyXG4gICAgbW9kYWxDb250YWluZXJSZWYuc2hvdyh7XHJcbiAgICAgIGNvbnRlbnQsXHJcbiAgICAgIGFuaW1hdGlvbnNFbmFibGVkOiBjb21iaW5lZENvbmZpZy5hbmltYXRlZCxcclxuICAgICAgaW5pdGlhbFN0YXRlOiBjb21iaW5lZENvbmZpZy5pbml0aWFsU3RhdGUsXHJcbiAgICAgIG1vZGFsU2VydmljZTogdGhpcyxcclxuICAgICAgaWQ6IGNvbWJpbmVkQ29uZmlnLmlkLFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKG1vZGFsQ29udGFpbmVyUmVmLmluc3RhbmNlKSB7XHJcbiAgICAgIG1vZGFsQ29udGFpbmVyUmVmLmluc3RhbmNlLmxldmVsID0gdGhpcy5tb2RhbHNDb3VudDtcclxuICAgICAgbW9kYWwuY29udGVudCA9IG1vZGFsTG9hZGVyLmdldElubmVyQ29tcG9uZW50KCk7XHJcbiAgICAgIG1vZGFsLmlkID0gbW9kYWxDb250YWluZXJSZWYuaW5zdGFuY2UuY29uZmlnPy5pZDtcclxuICAgICAgbW9kYWwuaGlkZSA9IChyZXMpID0+IG1vZGFsQ29udGFpbmVyUmVmLmluc3RhbmNlPy5oaWRlKHJlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1vZGFsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoaWRlTW9kYWwoaWQ/OiBudW1iZXIgfCBzdHJpbmcsIHJlc3VsdD86IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKGlkICE9IG51bGwpIHtcclxuICAgICAgY29uc3QgaW5kZXhUb1JlbW92ZSA9IHRoaXMubG9hZGVycy5maW5kSW5kZXgoKGxvYWRlcikgPT4gbG9hZGVyLmluc3RhbmNlPy5jb25maWcuaWQgPT09IGlkKTtcclxuICAgICAgY29uc3QgbW9kYWxMb2FkZXIgPSB0aGlzLmxvYWRlcnNbaW5kZXhUb1JlbW92ZV07XHJcbiAgICAgIGlmIChtb2RhbExvYWRlcikge1xyXG4gICAgICAgIG1vZGFsTG9hZGVyLmhpZGUoaWQsIHJlc3VsdCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMubG9hZGVycy5mb3JFYWNoKChsb2FkZXI6IENvbXBvbmVudExvYWRlcjxNb2RhbENvbnRhaW5lckNvbXBvbmVudD4pID0+IHtcclxuICAgICAgICBpZiAobG9hZGVyLmluc3RhbmNlKSB7XHJcbiAgICAgICAgICBsb2FkZXIuaGlkZShsb2FkZXIuaW5zdGFuY2UuY29uZmlnLmlkKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzaG93QmFja2Ryb3AoY29tYmluZWRDb25maWc6IE1vZGFsT3B0aW9ucyk6IHZvaWQge1xyXG4gICAgY29uc3QgaXNCYWNrZHJvcEVuYWJsZWQgPSBjb21iaW5lZENvbmZpZy5iYWNrZHJvcCA9PT0gdHJ1ZSB8fCBjb21iaW5lZENvbmZpZy5iYWNrZHJvcCA9PT0gJ3N0YXRpYyc7XHJcbiAgICBjb25zdCBpc0JhY2tkcm9wSW5ET00gPSB0aGlzLmJhY2tkcm9wUmVmICE9IG51bGw7XHJcbiAgICBpZiAoaXNCYWNrZHJvcEVuYWJsZWQgJiYgIWlzQmFja2Ryb3BJbkRPTSkge1xyXG4gICAgICB0aGlzLmJhY2tkcm9wTG9hZGVyXHJcbiAgICAgICAgLmF0dGFjaChNb2RhbEJhY2tkcm9wQ29tcG9uZW50KVxyXG4gICAgICAgIC50bygnYm9keScpXHJcbiAgICAgICAgLnNob3coeyBhbmltYXRpb25zRW5hYmxlZDogY29tYmluZWRDb25maWcuYW5pbWF0ZWQsIGJhY2tkcm9wTG9hZGVyOiB0aGlzLmJhY2tkcm9wTG9hZGVyIH0pO1xyXG4gICAgICB0aGlzLmJhY2tkcm9wUmVmID0gdGhpcy5iYWNrZHJvcExvYWRlci5jb21wb25lbnRSZWY7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhpZGVCYWNrZHJvcCgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5iYWNrZHJvcFJlZikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmJhY2tkcm9wUmVmLmluc3RhbmNlLmhpZGUoKTtcclxuICAgIHRoaXMuYmFja2Ryb3BSZWYgPSB2b2lkIDA7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlbW92ZUxvYWRlcnMoaWQ/OiBudW1iZXIgfCBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmIChpZCAhPSBudWxsKSB7XHJcbiAgICAgIGNvbnN0IGluZGV4VG9SZW1vdmUgPSB0aGlzLmxvYWRlcnMuZmluZEluZGV4KChsb2FkZXIpID0+IGxvYWRlci5pbnN0YW5jZT8uY29uZmlnLmlkID09PSBpZCk7XHJcbiAgICAgIGlmIChpbmRleFRvUmVtb3ZlID49IDApIHtcclxuICAgICAgICB0aGlzLmxvYWRlcnMuc3BsaWNlKGluZGV4VG9SZW1vdmUsIDEpO1xyXG4gICAgICAgIHRoaXMubG9hZGVycy5mb3JFYWNoKChsb2FkZXI6IENvbXBvbmVudExvYWRlcjxNb2RhbENvbnRhaW5lckNvbXBvbmVudD4sIGk6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgaWYgKGxvYWRlci5pbnN0YW5jZSkge1xyXG4gICAgICAgICAgICBsb2FkZXIuaW5zdGFuY2UubGV2ZWwgPSBpICsgMTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5sb2FkZXJzLnNwbGljZSgwLCB0aGlzLmxvYWRlcnMubGVuZ3RoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkQm9keVBhZGRpbmcoKSB7XHJcbiAgICBpZiAodGhpcy5tb2RhbHNDb3VudCA9PT0gMSkge1xyXG4gICAgICBjb25zdCB3aWR0aCA9IHRoaXMuZ2V0U2Nyb2xsYmFyV2lkdGgoKTtcclxuICAgICAgaWYgKHRoaXMuaXNTY3JvbGxCYXJQcmVzZW50KHdpZHRoKSkge1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbFBhZGRpbmcgPSB0aGlzLmRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0O1xyXG4gICAgICAgIGNvbnN0IGFjdHVhbFBhZGRpbmcgPSBwYXJzZUZsb2F0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZG9jdW1lbnQuYm9keSkucGFkZGluZ1JpZ2h0KTtcclxuICAgICAgICB0aGlzLmRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gYCR7YWN0dWFsUGFkZGluZyArIHdpZHRofXB4YDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXZlcnRTY3JvbGxiYXIoKSB7XHJcbiAgICB0aGlzLmRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0ID0gdGhpcy5pbml0aWFsUGFkZGluZztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0U2Nyb2xsYmFyV2lkdGgoKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IG1lYXN1cmVyID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgIG1lYXN1cmVyLmNsYXNzTmFtZSA9ICdtb2RhbC1zY3JvbGxiYXItbWVhc3VyZSc7XHJcblxyXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZG9jdW1lbnQuYm9keTtcclxuICAgIGJvZHkuYXBwZW5kQ2hpbGQobWVhc3VyZXIpO1xyXG4gICAgY29uc3Qgd2lkdGggPSBtZWFzdXJlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCAtIG1lYXN1cmVyLmNsaWVudFdpZHRoO1xyXG4gICAgYm9keS5yZW1vdmVDaGlsZChtZWFzdXJlcik7XHJcblxyXG4gICAgcmV0dXJuIHdpZHRoO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpc1Njcm9sbEJhclByZXNlbnQoc2Nyb2xsYmFyV2lkdGg6IG51bWJlcikge1xyXG4gICAgY29uc3QgcmVjdCA9IHRoaXMuZG9jdW1lbnQuYm9keS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IGJvZHlUb1ZpZXdwb3J0R2FwID0gd2luZG93LmlubmVyV2lkdGggLSAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCk7XHJcbiAgICBjb25zdCB1bmNlcnRhaW50eSA9IDAuMSAqIHNjcm9sbGJhcldpZHRoO1xyXG4gICAgcmV0dXJuIGJvZHlUb1ZpZXdwb3J0R2FwID49IHNjcm9sbGJhcldpZHRoIC0gdW5jZXJ0YWludHk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNyZWF0ZUxvYWRlcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBsb2FkZXIgPSB0aGlzLmNsZi5jcmVhdGVMb2FkZXI8TW9kYWxDb250YWluZXJDb21wb25lbnQ+KCk7XHJcbiAgICB0aGlzLmNvcHlFdmVudChsb2FkZXIub25CZWZvcmVTaG93LCB0aGlzLm9uQmVmb3JlU2hvdyk7XHJcbiAgICB0aGlzLmNvcHlFdmVudChsb2FkZXIub25TaG93biwgdGhpcy5vblNob3duKTtcclxuICAgIHRoaXMuY29weUV2ZW50KGxvYWRlci5vbkJlZm9yZUhpZGUsIHRoaXMub25CZWZvcmVIaWRlKTtcclxuICAgIHRoaXMuY29weUV2ZW50KGxvYWRlci5vbkhpZGRlbiwgdGhpcy5vbkhpZGRlbik7XHJcbiAgICB0aGlzLmxvYWRlcnMucHVzaChsb2FkZXIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb3B5RXZlbnQoZnJvbTogU3ViamVjdDx1bmtub3duPiwgdG86IFN1YmplY3Q8dW5rbm93bj4pIHtcclxuICAgIGZyb20uc3Vic2NyaWJlKChkYXRhKSA9PiB7XHJcbiAgICAgIHRvLm5leHQoZGF0YSk7XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIl19