ngx-simple-modal
Version:
A simple unopinionated framework to implement simple modal based behaviour in angular (v2+) projects.
215 lines • 26.2 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, ComponentFactoryResolver, ElementRef, Inject, Type, ViewContainerRef, ViewChild, Renderer2, ComponentRef, NgZone } from '@angular/core';
import { of } from 'rxjs';
import { DefaultSimpleModalOptionConfig } from './simple-modal-options';
import { SimpleModalWrapperComponent } from './simple-modal-wrapper.component';
import { DraggableDirective } from './simple-modal-draggable.directive';
/**
* View container manager which manages a list of modals currently active
* inside the viewvontainer
*/
let SimpleModalHolderComponent = class SimpleModalHolderComponent {
/**
* Constructor
* @param {ComponentFactoryResolver} resolver
* @param renderer
* @param ngZone
* @param defaultSimpleModalOptions
*/
constructor(resolver, renderer, ngZone, defaultSimpleModalOptions) {
this.resolver = resolver;
this.renderer = renderer;
this.ngZone = ngZone;
this.defaultSimpleModalOptions = defaultSimpleModalOptions;
/**
* modal collection, maintained by addModal and removeModal
* @type {Array<SimpleModalComponent> }
*/
this.modals = [];
/**
* if auto focus is on and no element focused, store it here to be restored back after close
*/
this.previousActiveElement = null;
}
/**
* Configures then adds modal to the modals array, and populates with data passed in
* @param {Type<SimpleModalComponent>} component
* @param {object?} data
* @param {SimpleModalOptionsOverrides?} options
* @return {Observable<*>}
*/
addModal(component, data, options) {
// create component
if (!this.viewContainer) {
return of(null);
}
const factory = this.resolver.resolveComponentFactory(SimpleModalWrapperComponent);
const componentRef = this.viewContainer.createComponent(factory);
const modalWrapper = (componentRef.instance);
const { ref: _componentRef, component: _component } = modalWrapper.addComponent(component);
// assign options refs
_component.options = options = Object.assign({}, this.defaultSimpleModalOptions, options);
// set base classes for wrapper
modalWrapper.modalClasses = options.wrapperDefaultClasses;
// add to stack
this.modals.push(_component);
// wait a tick then setup the following while adding a modal
this.wait().then(() => {
this.toggleWrapperClass(modalWrapper.wrapper, options.wrapperClass);
this.toggleBodyClass(options.bodyClass);
if (options.draggable) {
this.setDraggable(_componentRef, options);
}
this.wait(options.animationDuration).then(() => {
this.autoFocusFirstElement(_component.wrapper, options.autoFocus);
_component.markAsReady();
});
});
// when closing modal remove it
_component.onClosing(modal => this.removeModal(modal));
// if clicking on background closes modal
this.configureCloseOnClickOutside(modalWrapper);
// map and return observable
_component.mapDataObject(data);
return _component.setupObserver();
}
/**
* triggers components close function
* to take effect
* @returns {Promise<void>}
* @param closingModal
*/
removeModal(closingModal) {
const options = closingModal.options;
this.toggleWrapperClass(closingModal.wrapper, options.wrapperClass);
return this.wait(options.animationDuration).then(() => {
this.removeModalFromArray(closingModal);
this.toggleBodyClass(options.bodyClass);
this.restorePreviousFocus();
});
}
/**
* Instructs all open modals to
*/
removeAllModals() {
return Promise.all(this.modals.map(modal => this.removeModal(modal)));
}
/**
* Bind a body class 'modal-open' to a condition of modals in pool > 0
* @param bodyClass - string to add and remove from body in document
*/
toggleBodyClass(bodyClass) {
if (!bodyClass) {
return;
}
const body = document.getElementsByTagName('body')[0];
const bodyClassItems = bodyClass.split(' ');
if (!this.modals.length) {
body.classList.remove(...bodyClassItems);
}
else {
body.classList.add(...bodyClassItems);
}
}
/**
* if the option to close on background click is set, then hook up a callback
* @param modalWrapper
*/
configureCloseOnClickOutside(modalWrapper) {
modalWrapper.onClickOutsideModalContent(() => {
if (modalWrapper.content.options.closeOnClickOutside) {
modalWrapper.content.close();
}
});
}
/**
* Auto focus o the first element if autofocus is on
* @param componentWrapper
* @param autoFocus
*/
autoFocusFirstElement(componentWrapper, autoFocus) {
if (autoFocus) {
const focusable = componentWrapper.nativeElement.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
if (focusable && focusable.length) {
this.previousActiveElement = document.activeElement;
focusable[0].focus();
}
}
}
/**
* Restores the last focus is there was one
*/
restorePreviousFocus() {
if (this.previousActiveElement) {
this.previousActiveElement.focus();
this.previousActiveElement = null;
}
}
/**
* Configure the adding and removal of a wrapper class - predominantly animation focused
* @param modalWrapperEl
* @param wrapperClass
*/
toggleWrapperClass(modalWrapperEl, wrapperClass) {
const wrapperClassList = modalWrapperEl.nativeElement.classList;
const wrapperClassItems = wrapperClass.split(' ');
if (wrapperClassList.toString().indexOf(wrapperClass) !== -1) {
wrapperClassList.remove(...wrapperClassItems);
}
else {
wrapperClassList.add(...wrapperClassItems);
}
}
/**
* Enables the drag option on the modal if the options have it enabled
* @param component
* @param options
* @private
*/
setDraggable(component, options) {
const draggableDirective = new DraggableDirective(component.location, this.ngZone, this.renderer);
draggableDirective.dragTarget = component.location.nativeElement;
draggableDirective.dragHandle = component.instance.handle ? component.instance.handle.nativeElement : undefined;
draggableDirective.ngAfterViewInit();
component.location.nativeElement.classList.add(options.draggableClass);
}
/**
* Helper function for a more readable timeout
* @param ms
*/
wait(ms = 0) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), ms);
});
}
/**
* Instructs the holder to remove the modal and
* removes this component from the collection
* @param {SimpleModalComponent} component
*/
removeModalFromArray(component) {
const index = this.modals.indexOf(component);
if (index > -1) {
this.viewContainer.remove(index);
this.modals.splice(index, 1);
}
}
};
SimpleModalHolderComponent.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: Renderer2 },
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [DefaultSimpleModalOptionConfig,] }] }
];
tslib_1.__decorate([
ViewChild('viewContainer', { read: ViewContainerRef, static: true })
], SimpleModalHolderComponent.prototype, "viewContainer", void 0);
SimpleModalHolderComponent = tslib_1.__decorate([
Component({
selector: 'simple-modal-holder',
template: '<ng-template #viewContainer></ng-template>'
}),
tslib_1.__param(3, Inject(DefaultSimpleModalOptionConfig))
], SimpleModalHolderComponent);
export { SimpleModalHolderComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltcGxlLW1vZGFsLWhvbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtc2ltcGxlLW1vZGFsLyIsInNvdXJjZXMiOlsic2ltcGxlLW1vZGFsL3NpbXBsZS1tb2RhbC1ob2xkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLHdCQUF3QixFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1SixPQUFPLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSw4QkFBOEIsRUFBbUQsTUFBTSx3QkFBd0IsQ0FBQztBQUN6SCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUUvRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUV4RTs7O0dBR0c7QUFLSCxJQUFhLDBCQUEwQixHQUF2QyxNQUFhLDBCQUEwQjtJQWlCckM7Ozs7OztPQU1HO0lBQ0gsWUFDVSxRQUFrQyxFQUNsQyxRQUFtQixFQUNuQixNQUFjLEVBQzBCLHlCQUE2QztRQUhyRixhQUFRLEdBQVIsUUFBUSxDQUEwQjtRQUNsQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDMEIsOEJBQXlCLEdBQXpCLHlCQUF5QixDQUFvQjtRQXRCL0Y7OztXQUdHO1FBQ0gsV0FBTSxHQUEwQyxFQUFFLENBQUM7UUFFbkQ7O1dBRUc7UUFDSCwwQkFBcUIsR0FBRyxJQUFJLENBQUM7SUFlN0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFFBQVEsQ0FDTixTQUE0QyxFQUM1QyxJQUFRLEVBQ1IsT0FBcUM7UUFFckMsbUJBQW1CO1FBQ25CLElBQUksQ0FBQyxJQUFJLENB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QkFBMEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgRWxlbWVudFJlZiwgSW5qZWN0LCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmLCBWaWV3Q2hpbGQsIFJlbmRlcmVyMiwgQ29tcG9uZW50UmVmLCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBEZWZhdWx0U2ltcGxlTW9kYWxPcHRpb25Db25maWcsIFNpbXBsZU1vZGFsT3B0aW9ucywgU2ltcGxlTW9kYWxPcHRpb25zT3ZlcnJpZGVzIH0gZnJvbSAnLi9zaW1wbGUtbW9kYWwtb3B0aW9ucyc7XG5pbXBvcnQgeyBTaW1wbGVNb2RhbFdyYXBwZXJDb21wb25lbnQgfSBmcm9tICcuL3NpbXBsZS1tb2RhbC13cmFwcGVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTaW1wbGVNb2RhbENvbXBvbmVudCB9IGZyb20gJy4vc2ltcGxlLW1vZGFsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEcmFnZ2FibGVEaXJlY3RpdmUgfSBmcm9tICcuL3NpbXBsZS1tb2RhbC1kcmFnZ2FibGUuZGlyZWN0aXZlJztcblxuLyoqXG4gKiBWaWV3IGNvbnRhaW5lciBtYW5hZ2VyIHdoaWNoIG1hbmFnZXMgYSBsaXN0IG9mIG1vZGFscyBjdXJyZW50bHkgYWN0aXZlXG4gKiBpbnNpZGUgdGhlIHZpZXd2b250YWluZXJcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2ltcGxlLW1vZGFsLWhvbGRlcicsXG4gIHRlbXBsYXRlOiAnPG5nLXRlbXBsYXRlICN2aWV3Q29udGFpbmVyPjwvbmctdGVtcGxhdGU+Jyxcbn0pXG5leHBvcnQgY2xhc3MgU2ltcGxlTW9kYWxIb2xkZXJDb21wb25lbnQge1xuICAvKipcbiAgICogVGFyZ2V0IHZpZXdDb250YWluZXIgdG8gaW5zZXJ0IG1vZGFsc1xuICAgKi9cbiAgQFZpZXdDaGlsZCgndmlld0NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pIHZpZXdDb250YWluZXI7XG5cbiAgLyoqXG4gICAqIG1vZGFsIGNvbGxlY3Rpb24sIG1haW50YWluZWQgYnkgYWRkTW9kYWwgYW5kIHJlbW92ZU1vZGFsXG4gICAqIEB0eXBlIHtBcnJheTxTaW1wbGVNb2RhbENvbXBvbmVudD4gfVxuICAgKi9cbiAgbW9kYWxzOiBBcnJheTxTaW1wbGVNb2RhbENvbXBvbmVudDxhbnksIGFueT4+ID0gW107XG5cbiAgLyoqXG4gICAqIGlmIGF1dG8gZm9jdXMgaXMgb24gYW5kIG5vIGVsZW1lbnQgZm9jdXNlZCwgc3RvcmUgaXQgaGVyZSB0byBiZSByZXN0b3JlZCBiYWNrIGFmdGVyIGNsb3NlXG4gICAqL1xuICBwcmV2aW91c0FjdGl2ZUVsZW1lbnQgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge0NvbXBvbmVudEZhY3RvcnlSZXNvbHZlcn0gcmVzb2x2ZXJcbiAgICogQHBhcmFtIHJlbmRlcmVyXG4gICAqIEBwYXJhbSBuZ1pvbmVcbiAgICogQHBhcmFtIGRlZmF1bHRTaW1wbGVNb2RhbE9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBASW5qZWN0KERlZmF1bHRTaW1wbGVNb2RhbE9wdGlvbkNvbmZpZykgcHJpdmF0ZSBkZWZhdWx0U2ltcGxlTW9kYWxPcHRpb25zOiBTaW1wbGVNb2RhbE9wdGlvbnMsXG4gICkge1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZXMgdGhlbiBhZGRzIG1vZGFsIHRvIHRoZSBtb2RhbHMgYXJyYXksIGFuZCBwb3B1bGF0ZXMgd2l0aCBkYXRhIHBhc3NlZCBpblxuICAgKiBAcGFyYW0ge1R5cGU8U2ltcGxlTW9kYWxDb21wb25lbnQ+fSBjb21wb25lbnRcbiAgICogQHBhcmFtIHtvYmplY3Q/fSBkYXRhXG4gICAqIEBwYXJhbSB7U2ltcGxlTW9kYWxPcHRpb25zT3ZlcnJpZGVzP30gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPCo+fVxuICAgKi9cbiAgYWRkTW9kYWw8VCwgVDE+KFxuICAgIGNvbXBvbmVudDogVHlwZTxTaW1wbGVNb2RhbENvbXBvbmVudDxULCBUMT4+LFxuICAgIGRhdGE/OiBULFxuICAgIG9wdGlvbnM/OiBTaW1wbGVNb2RhbE9wdGlvbnNPdmVycmlkZXMsXG4gICk6IE9ic2VydmFibGU8VDE+IHtcbiAgICAvLyBjcmVhdGUgY29tcG9uZW50XG4gICAgaWYgKCF0aGlzLnZpZXdDb250YWluZXIpIHtcbiAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICB9XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMucmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoU2ltcGxlTW9kYWxXcmFwcGVyQ29tcG9uZW50KTtcbiAgICBjb25zdCBjb21wb25lbnRSZWYgPSB0aGlzLnZpZXdDb250YWluZXIuY3JlYXRlQ29tcG9uZW50KGZhY3RvcnkpO1xuICAgIGNvbnN0IG1vZGFsV3JhcHBlcjogU2ltcGxlTW9kYWxXcmFwcGVyQ29tcG9uZW50ID0gPFNpbXBsZU1vZGFsV3JhcHBlckNvbXBvbmVudD4oXG4gICAgICBjb21wb25lbnRSZWYuaW5zdGFuY2VcbiAgICApO1xuICAgIGNvbnN0IHsgcmVmOiBfY29tcG9uZW50UmVmLCBjb21wb25lbnQ6IF9jb21wb25lbnQgfSA9IG1vZGFsV3JhcHBlci5hZGRDb21wb25lbnQoY29tcG9uZW50KTtcblxuICAgIC8vIGFzc2lnbiBvcHRpb25zIHJlZnNcbiAgICBfY29tcG9uZW50Lm9wdGlvbnMgPSBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5kZWZhdWx0U2ltcGxlTW9kYWxPcHRpb25zLCBvcHRpb25zKSBhcyBTaW1wbGVNb2RhbE9wdGlvbnM7XG5cbiAgICAvLyBzZXQgYmFzZSBjbGFzc2VzIGZvciB3cmFwcGVyXG4gICAgbW9kYWxXcmFwcGVyLm1vZGFsQ2xhc3NlcyA9IG9wdGlvbnMud3JhcHBlckRlZmF1bHRDbGFzc2VzO1xuXG4gICAgLy8gYWRkIHRvIHN0YWNrXG4gICAgdGhpcy5tb2RhbHMucHVzaChfY29tcG9uZW50KTtcblxuICAgIC8vIHdhaXQgYSB0aWNrIHRoZW4gc2V0dXAgdGhlIGZvbGxvd2luZyB3aGlsZSBhZGRpbmcgYSBtb2RhbFxuICAgIHRoaXMud2FpdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy50b2dnbGVXcmFwcGVyQ2xhc3MobW9kYWxXcmFwcGVyLndyYXBwZXIsIG9wdGlvbnMud3JhcHBlckNsYXNzKTtcbiAgICAgIHRoaXMudG9nZ2xlQm9keUNsYXNzKG9wdGlvbnMuYm9keUNsYXNzKTtcbiAgICAgIGlmIChvcHRpb25zLmRyYWdnYWJsZSkge1xuICAgICAgICB0aGlzLnNldERyYWdnYWJsZShfY29tcG9uZW50UmVmLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHRoaXMud2FpdChvcHRpb25zLmFuaW1hdGlvbkR1cmF0aW9uKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5hdXRvRm9jdXNGaXJzdEVsZW1lbnQoX2NvbXBvbmVudC53cmFwcGVyLCBvcHRpb25zLmF1dG9Gb2N1cyk7XG4gICAgICAgIF9jb21wb25lbnQubWFya0FzUmVhZHkoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gd2hlbiBjbG9zaW5nIG1vZGFsIHJlbW92ZSBpdFxuICAgIF9jb21wb25lbnQub25DbG9zaW5nKG1vZGFsID0+IHRoaXMucmVtb3ZlTW9kYWwobW9kYWwpKTtcblxuICAgIC8vIGlmIGNsaWNraW5nIG9uIGJhY2tncm91bmQgY2xvc2VzIG1vZGFsXG4gICAgdGhpcy5jb25maWd1cmVDbG9zZU9uQ2xpY2tPdXRzaWRlKG1vZGFsV3JhcHBlcik7XG5cbiAgICAvLyBtYXAgYW5kIHJldHVybiBvYnNlcnZhYmxlXG4gICAgX2NvbXBvbmVudC5tYXBEYXRhT2JqZWN0KGRhdGEpO1xuXG4gICAgcmV0dXJuIF9jb21wb25lbnQuc2V0dXBPYnNlcnZlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJzIGNvbXBvbmVudHMgY2xvc2UgZnVuY3Rpb25cbiAgICogdG8gdGFrZSBlZmZlY3RcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqIEBwYXJhbSBjbG9zaW5nTW9kYWxcbiAgICovXG4gIHJlbW92ZU1vZGFsKGNsb3NpbmdNb2RhbDogU2ltcGxlTW9kYWxDb21wb25lbnQ8YW55LCBhbnk+KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBvcHRpb25zID0gY2xvc2luZ01vZGFsLm9wdGlvbnM7XG4gICAgdGhpcy50b2dnbGVXcmFwcGVyQ2xhc3MoY2xvc2luZ01vZGFsLndyYXBwZXIsIG9wdGlvbnMud3JhcHBlckNsYXNzKTtcbiAgICByZXR1cm4gdGhpcy53YWl0KG9wdGlvbnMuYW5pbWF0aW9uRHVyYXRpb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5yZW1vdmVNb2RhbEZyb21BcnJheShjbG9zaW5nTW9kYWwpO1xuICAgICAgdGhpcy50b2dnbGVCb2R5Q2xhc3Mob3B0aW9ucy5ib2R5Q2xhc3MpO1xuICAgICAgdGhpcy5yZXN0b3JlUHJldmlvdXNGb2N1cygpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RydWN0cyBhbGwgb3BlbiBtb2RhbHMgdG9cbiAgICovXG4gIHJlbW92ZUFsbE1vZGFscygpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBQcm9taXNlLmFsbCh0aGlzLm1vZGFscy5tYXAobW9kYWwgPT4gdGhpcy5yZW1vdmVNb2RhbChtb2RhbCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kIGEgYm9keSBjbGFzcyAnbW9kYWwtb3BlbicgdG8gYSBjb25kaXRpb24gb2YgbW9kYWxzIGluIHBvb2wgPiAwXG4gICAqIEBwYXJhbSBib2R5Q2xhc3MgLSBzdHJpbmcgdG8gYWRkIGFuZCByZW1vdmUgZnJvbSBib2R5IGluIGRvY3VtZW50XG4gICAqL1xuICBwcml2YXRlIHRvZ2dsZUJvZHlDbGFzcyhib2R5Q2xhc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghYm9keUNsYXNzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYm9keScpWzBdO1xuICAgIGNvbnN0IGJvZHlDbGFzc0l0ZW1zID0gYm9keUNsYXNzLnNwbGl0KCcgJyk7XG4gICAgaWYgKCF0aGlzLm1vZGFscy5sZW5ndGgpIHtcbiAgICAgIGJvZHkuY2xhc3NMaXN0LnJlbW92ZSguLi5ib2R5Q2xhc3NJdGVtcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJvZHkuY2xhc3NMaXN0LmFkZCguLi5ib2R5Q2xhc3NJdGVtcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGlmIHRoZSBvcHRpb24gdG8gY2xvc2Ugb24gYmFja2dyb3VuZCBjbGljayBpcyBzZXQsIHRoZW4gaG9vayB1cCBhIGNhbGxiYWNrXG4gICAqIEBwYXJhbSBtb2RhbFdyYXBwZXJcbiAgICovXG4gIHByaXZhdGUgY29uZmlndXJlQ2xvc2VPbkNsaWNrT3V0c2lkZShtb2RhbFdyYXBwZXI6IFNpbXBsZU1vZGFsV3JhcHBlckNvbXBvbmVudCkge1xuICAgIG1vZGFsV3JhcHBlci5vbkNsaWNrT3V0c2lkZU1vZGFsQ29udGVudCgoKSA9PiB7XG4gICAgICBpZiAobW9kYWxXcmFwcGVyLmNvbnRlbnQub3B0aW9ucy5jbG9zZU9uQ2xpY2tPdXRzaWRlKSB7XG4gICAgICAgIG1vZGFsV3JhcHBlci5jb250ZW50LmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQXV0byBmb2N1cyBvIHRoZSBmaXJzdCBlbGVtZW50IGlmIGF1dG9mb2N1cyBpcyBvblxuICAgKiBAcGFyYW0gY29tcG9uZW50V3JhcHBlclxuICAgKiBAcGFyYW0gYXV0b0ZvY3VzXG4gICAqL1xuICBwcml2YXRlIGF1dG9Gb2N1c0ZpcnN0RWxlbWVudChjb21wb25lbnRXcmFwcGVyOiBFbGVtZW50UmVmLCBhdXRvRm9jdXM6IGJvb2xlYW4pIHtcbiAgICBpZiAoYXV0b0ZvY3VzKSB7XG4gICAgICBjb25zdCBmb2N1c2FibGUgPSBjb21wb25lbnRXcmFwcGVyLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgJ2J1dHRvbiwgW2hyZWZdLCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgW3RhYmluZGV4XTpub3QoW3RhYmluZGV4PVwiLTFcIl0pJyxcbiAgICAgICk7XG4gICAgICBpZiAoZm9jdXNhYmxlICYmIGZvY3VzYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5wcmV2aW91c0FjdGl2ZUVsZW1lbnQgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgICAgICBmb2N1c2FibGVbMF0uZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzdG9yZXMgdGhlIGxhc3QgZm9jdXMgaXMgdGhlcmUgd2FzIG9uZVxuICAgKi9cbiAgcHJpdmF0ZSByZXN0b3JlUHJldmlvdXNGb2N1cygpIHtcbiAgICBpZiAodGhpcy5wcmV2aW91c0FjdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMucHJldmlvdXNBY3RpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICB0aGlzLnByZXZpb3VzQWN0aXZlRWxlbWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyZSB0aGUgYWRkaW5nIGFuZCByZW1vdmFsIG9mIGEgd3JhcHBlciBjbGFzcyAtIHByZWRvbWluYW50bHkgYW5pbWF0aW9uIGZvY3VzZWRcbiAgICogQHBhcmFtIG1vZGFsV3JhcHBlckVsXG4gICAqIEBwYXJhbSB3cmFwcGVyQ2xhc3NcbiAgICovXG4gIHByaXZhdGUgdG9nZ2xlV3JhcHBlckNsYXNzKG1vZGFsV3JhcHBlckVsOiBFbGVtZW50UmVmLCB3cmFwcGVyQ2xhc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHdyYXBwZXJDbGFzc0xpc3QgPSBtb2RhbFdyYXBwZXJFbC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdDtcbiAgICBjb25zdCB3cmFwcGVyQ2xhc3NJdGVtcyA9IHdyYXBwZXJDbGFzcy5zcGxpdCgnICcpO1xuICAgIGlmICh3cmFwcGVyQ2xhc3NMaXN0LnRvU3RyaW5nKCkuaW5kZXhPZih3cmFwcGVyQ2xhc3MpICE9PSAtMSkge1xuICAgICAgd3JhcHBlckNsYXNzTGlzdC5yZW1vdmUoLi4ud3JhcHBlckNsYXNzSXRlbXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3cmFwcGVyQ2xhc3NMaXN0LmFkZCguLi53cmFwcGVyQ2xhc3NJdGVtcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgdGhlIGRyYWcgb3B0aW9uIG9uIHRoZSBtb2RhbCBpZiB0aGUgb3B0aW9ucyBoYXZlIGl0IGVuYWJsZWRcbiAgICogQHBhcmFtIGNvbXBvbmVudFxuICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzZXREcmFnZ2FibGUoY29tcG9uZW50OiBDb21wb25lbnRSZWY8U2ltcGxlTW9kYWxDb21wb25lbnQ8YW55LCBhbnk+Piwgb3B0aW9uczogU2ltcGxlTW9kYWxPcHRpb25zT3ZlcnJpZGVzKTogdm9pZCB7XG4gICAgY29uc3QgZHJhZ2dhYmxlRGlyZWN0aXZlID0gbmV3IERyYWdnYWJsZURpcmVjdGl2ZShjb21wb25lbnQubG9jYXRpb24sIHRoaXMubmdab25lLCB0aGlzLnJlbmRlcmVyKTtcbiAgICBkcmFnZ2FibGVEaXJlY3RpdmUuZHJhZ1RhcmdldCA9IGNvbXBvbmVudC5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuICAgIGRyYWdnYWJsZURpcmVjdGl2ZS5kcmFnSGFuZGxlID0gY29tcG9uZW50Lmluc3RhbmNlLmhhbmRsZSA/IGNvbXBvbmVudC5pbnN0YW5jZS5oYW5kbGUubmF0aXZlRWxlbWVudCA6IHVuZGVmaW5lZDtcbiAgICBkcmFnZ2FibGVEaXJlY3RpdmUubmdBZnRlclZpZXdJbml0KCk7XG4gICAgY29tcG9uZW50LmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZChvcHRpb25zLmRyYWdnYWJsZUNsYXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGEgbW9yZSByZWFkYWJsZSB0aW1lb3V0XG4gICAqIEBwYXJhbSBtc1xuICAgKi9cbiAgcHJpdmF0ZSB3YWl0KG1zOiBudW1iZXIgPSAwKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSgpLCBtcyk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5zdHJ1Y3RzIHRoZSBob2xkZXIgdG8gcmVtb3ZlIHRoZSBtb2RhbCBhbmRcbiAgICogcmVtb3ZlcyB0aGlzIGNvbXBvbmVudCBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7U2ltcGxlTW9kYWxDb21wb25lbnR9IGNvbXBvbmVudFxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVNb2RhbEZyb21BcnJheShjb21wb25lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMubW9kYWxzLmluZGV4T2YoY29tcG9uZW50KTtcbiAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgdGhpcy52aWV3Q29udGFpbmVyLnJlbW92ZShpbmRleCk7XG4gICAgICB0aGlzLm1vZGFscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxufVxuIl19