ngx-smart-modal
Version:
Smart modal handler to manage modals and data everywhere in Angular apps.
471 lines • 54.8 kB
JavaScript
import { ApplicationRef, Inject, Injectable, PLATFORM_ID, TemplateRef, Type } from '@angular/core';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { NgxSmartModalComponent } from '../components/ngx-smart-modal.component';
import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
import * as i0 from "@angular/core";
import * as i1 from "./ngx-smart-modal-stack.service";
export class NgxSmartModalService {
constructor(_injector, _modalStack, _document, _platformId) {
this._injector = _injector;
this._modalStack = _modalStack;
this._document = _document;
this._platformId = _platformId;
/**
* Close the latest opened modal if escape key event is emitted
* @param event The Keyboard Event
*/
this._escapeKeyboardEvent = (event) => {
if (event.key === 'Escape') {
try {
const modal = this.getTopOpenedModal();
if (!modal.escapable) {
return false;
}
modal.onEscape.emit(modal);
this.closeLatestModal();
return true;
}
catch (e) {
return false;
}
}
return false;
};
/**
* While modal is open, the focus stay on it
* @param event The Keyboar dEvent
*/
this._trapFocusModal = (event) => {
if (event.key === 'Tab') {
try {
const modal = this.getTopOpenedModal();
if (!modal.nsmDialog.first.nativeElement.contains(document.activeElement)) {
event.preventDefault();
event.stopPropagation();
modal.nsmDialog.first.nativeElement.focus();
}
return true;
}
catch (e) {
return false;
}
}
return false;
};
this._addEvents();
}
/**
* Add a new modal instance. This step is essential and allows to retrieve any modal at any time.
* It stores an object that contains the given modal identifier and the modal itself directly in the `modalStack`.
*
* @param modalInstance The object that contains the given modal identifier and the modal itself.
* @param force Optional parameter that forces the overriding of modal instance if it already exists.
* @returns nothing special.
*/
addModal(modalInstance, force) {
this._modalStack.addModal(modalInstance, force);
}
/**
* Retrieve a modal instance by its identifier.
*
* @param id The modal identifier used at creation time.
*/
getModal(id) {
return this._modalStack.getModal(id);
}
/**
* Alias of `getModal` to retrieve a modal instance by its identifier.
*
* @param id The modal identifier used at creation time.
*/
get(id) {
return this.getModal(id);
}
/**
* Open a given modal
*
* @param id The modal identifier used at creation time.
* @param force Tell the modal to open top of all other opened modals
*/
open(id, force = false) {
return this._openModal(this.get(id), force);
}
/**
* Close a given modal
*
* @param id The modal identifier used at creation time.
*/
close(id) {
return this._closeModal(this.get(id));
}
/**
* Close all opened modals
*/
closeAll() {
this.getOpenedModals().forEach((instance) => {
this._closeModal(instance.modal);
});
}
/**
* Toggles a given modal
* If the retrieved modal is opened it closes it, else it opens it.
*
* @param id The modal identifier used at creation time.
* @param force Tell the modal to open top of all other opened modals
*/
toggle(id, force = false) {
return this._toggleModal(this.get(id), force);
}
/**
* Retrieve all the created modals.
*
* @returns an array that contains all modal instances.
*/
getModalStack() {
return this._modalStack.getModalStack();
}
/**
* Retrieve all the opened modals. It looks for all modal instances with their `visible` property set to `true`.
*
* @returns an array that contains all the opened modals.
*/
getOpenedModals() {
return this._modalStack.getOpenedModals();
}
/**
* Retrieve the opened modal with highest z-index.
*
* @returns the opened modal with highest z-index.
*/
getTopOpenedModal() {
return this._modalStack.getTopOpenedModal();
}
/**
* Get the higher `z-index` value between all the modal instances. It iterates over the `ModalStack` array and
* calculates a higher value (it takes the highest index value between all the modal instances and adds 1).
* Use it to make a modal appear foreground.
*
* @returns a higher index from all the existing modal instances.
*/
getHigherIndex() {
return this._modalStack.getHigherIndex();
}
/**
* It gives the number of modal instances. It's helpful to know if the modal stack is empty or not.
*
* @returns the number of modal instances.
*/
getModalStackCount() {
return this._modalStack.getModalStackCount();
}
/**
* Remove a modal instance from the modal stack.
*
* @param id The modal identifier.
* @returns the removed modal instance.
*/
removeModal(id) {
const modalInstance = this._modalStack.removeModal(id);
if (modalInstance) {
this._destroyModal(modalInstance.modal);
}
}
/**
* Associate data to an identified modal. If the modal isn't already associated to some data, it creates a new
* entry in the `modalData` array with its `id` and the given `data`. If the modal already has data, it rewrites
* them with the new ones. Finally if no modal found it returns an error message in the console and false value
* as method output.
*
* @param data The data you want to associate to the modal.
* @param id The modal identifier.
* @param force If true, overrides the previous stored data if there was.
* @returns true if the given modal exists and the process has been tried, either false.
*/
setModalData(data, id, force) {
const modal = this.get(id);
if (modal) {
modal.setData(data, force);
return true;
}
else {
return false;
}
}
/**
* Retrieve modal data by its identifier.
*
* @param id The modal identifier used at creation time.
* @returns the associated modal data.
*/
getModalData(id) {
const modal = this.get(id);
if (modal) {
return modal.getData();
}
return null;
}
/**
* Reset the data attached to a given modal.
*
* @param id The modal identifier used at creation time.
* @returns the removed data or false if modal doesn't exist.
*/
resetModalData(id) {
if (this._modalStack.getModalStack().find((o) => o.id === id)) {
const removed = this.getModal(id).getData();
this.getModal(id).removeData();
return removed;
}
else {
return false;
}
}
/**
* Close the latest opened modal
*/
closeLatestModal() {
this.getTopOpenedModal().close();
}
/**
* Create dynamic NgxSmartModalComponent
* @param vcr A ViewContainerRef reference
* @param id The modal identifier used at creation time
* @param content The modal content (string, templateRef or Component)
* @param options Any NgxSmartModalComponent available options
*/
create(id, content, vcr, options = {}) {
try {
return this.getModal(id);
}
catch (e) {
const ngContent = this._resolveNgContent(content);
const componentRef = vcr.createComponent(NgxSmartModalComponent, { injector: this._injector, projectableNodes: ngContent });
if (content instanceof Type) {
componentRef.instance.contentComponent = content;
}
componentRef.instance.identifier = id;
componentRef.instance.createFrom = 'service';
if (typeof options.closable === 'boolean') {
componentRef.instance.closable = options.closable;
}
if (typeof options.escapable === 'boolean') {
componentRef.instance.escapable = options.escapable;
}
if (typeof options.dismissable === 'boolean') {
componentRef.instance.dismissable = options.dismissable;
}
if (typeof options.customClass === 'string') {
componentRef.instance.customClass = options.customClass;
}
if (typeof options.backdrop === 'boolean') {
componentRef.instance.backdrop = options.backdrop;
}
if (typeof options.force === 'boolean') {
componentRef.instance.force = options.force;
}
if (typeof options.hideDelay === 'number') {
componentRef.instance.hideDelay = options.hideDelay;
}
if (typeof options.autostart === 'boolean') {
componentRef.instance.autostart = options.autostart;
}
if (typeof options.target === 'string') {
componentRef.instance.target = options.target;
}
if (typeof options.ariaLabel === 'string') {
componentRef.instance.ariaLabel = options.ariaLabel;
}
if (typeof options.ariaLabelledBy === 'string') {
componentRef.instance.ariaLabelledBy = options.ariaLabelledBy;
}
if (typeof options.ariaDescribedBy === 'string') {
componentRef.instance.ariaDescribedBy = options.ariaDescribedBy;
}
if (typeof options.refocus === 'boolean') {
componentRef.instance.refocus = options.refocus;
}
const domElem = componentRef.hostView.rootNodes[0];
this._document.body.appendChild(domElem);
return componentRef.instance;
}
}
_addEvents() {
if (!this.isBrowser) {
return false;
}
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'create', ((e) => {
this._initModal(e.detail.instance);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'delete', ((e) => {
this._deleteModal(e.detail.instance);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'open', ((e) => {
this._openModal(e.detail.instance.modal, e.detail.extraData.top);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'toggle', ((e) => {
this._toggleModal(e.detail.instance.modal, e.detail.extraData.top);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'close', ((e) => {
this._closeModal(e.detail.instance.modal);
}));
window.addEventListener(NgxSmartModalConfig.prefixEvent + 'dismiss', ((e) => {
this._dismissModal(e.detail.instance.modal);
}));
window.addEventListener('keyup', this._escapeKeyboardEvent);
return true;
}
_initModal(modalInstance) {
modalInstance.modal.layerPosition += this.getModalStackCount();
this.addModal(modalInstance, modalInstance.modal.force);
if (modalInstance.modal.autostart) {
this.open(modalInstance.id);
}
}
_openModal(modal, top) {
if (modal.visible) {
return false;
}
this.lastElementFocused = document.activeElement;
if (modal.escapable) {
window.addEventListener('keyup', this._escapeKeyboardEvent);
}
if (modal.backdrop) {
window.addEventListener('keydown', this._trapFocusModal);
}
if (top) {
modal.layerPosition = this.getHigherIndex();
}
modal.addBodyClass();
modal.overlayVisible = true;
modal.visible = true;
modal.onOpen.emit(modal);
modal.markForCheck();
setTimeout(() => {
modal.openedClass = true;
if (modal.target) {
modal.targetPlacement();
}
modal.nsmDialog.first.nativeElement.setAttribute('role', 'dialog');
modal.nsmDialog.first.nativeElement.setAttribute('tabIndex', '-1');
modal.nsmDialog.first.nativeElement.setAttribute('aria-modal', 'true');
modal.nsmDialog.first.nativeElement.focus();
modal.markForCheck();
modal.onOpenFinished.emit(modal);
});
return true;
}
_toggleModal(modal, top) {
if (modal.visible) {
return this._closeModal(modal);
}
else {
return this._openModal(modal, top);
}
}
_closeModal(modal) {
if (!modal.openedClass) {
return false;
}
modal.openedClass = false;
modal.onClose.emit(modal);
modal.onAnyCloseEvent.emit(modal);
if (this.getOpenedModals().length < 2) {
modal.removeBodyClass();
window.removeEventListener('keyup', this._escapeKeyboardEvent);
window.removeEventListener('keydown', this._trapFocusModal);
}
setTimeout(() => {
modal.visibleChange.emit(modal.visible);
modal.visible = false;
modal.overlayVisible = false;
modal.nsmDialog.first.nativeElement.removeAttribute('tabIndex');
modal.markForCheck();
modal.onCloseFinished.emit(modal);
modal.onAnyCloseEventFinished.emit(modal);
if (modal.refocus) {
this.lastElementFocused.focus();
}
}, modal.hideDelay);
return true;
}
_dismissModal(modal) {
if (!modal.openedClass) {
return false;
}
modal.openedClass = false;
modal.onDismiss.emit(modal);
modal.onAnyCloseEvent.emit(modal);
if (this.getOpenedModals().length < 2) {
modal.removeBodyClass();
}
setTimeout(() => {
modal.visible = false;
modal.visibleChange.emit(modal.visible);
modal.overlayVisible = false;
modal.markForCheck();
modal.onDismissFinished.emit(modal);
modal.onAnyCloseEventFinished.emit(modal);
}, modal.hideDelay);
return true;
}
_deleteModal(modalInstance) {
this.removeModal(modalInstance.id);
if (!this.getModalStack().length) {
modalInstance.modal.removeBodyClass();
}
}
/**
* Resolve content according to the types
* @param content The modal content (string, templateRef or Component)
*/
_resolveNgContent(content) {
if (typeof content === 'string') {
const element = this._document.createTextNode(content);
return [[element]];
}
if (content instanceof TemplateRef) {
const viewRef = content.createEmbeddedView(null);
this.appRef.attachView(viewRef);
return [viewRef.rootNodes];
}
return [];
}
/**
* Is current platform browser
*/
get isBrowser() {
return isPlatformBrowser(this._platformId);
}
/**
* Remove dynamically created modal from DOM
*/
_destroyModal(modal) {
// Prevent destruction of the inline modals
if (modal.createFrom !== 'service') {
return;
}
this._document.body.removeChild(modal.elementRef.nativeElement);
}
/**
* getter function to avoid circular dependency error
* @returns ApplicationRef instance
* */
get appRef() {
return this._injector.get(ApplicationRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, deps: [{ token: i0.Injector }, { token: i1.NgxSmartModalStackService }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.10", ngImport: i0, type: NgxSmartModalService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.NgxSmartModalStackService }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNtYXJ0LW1vZGFsLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc21hcnQtbW9kYWwvc3JjL2xpYi9zZXJ2aWNlcy9uZ3gtc21hcnQtbW9kYWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFtQixNQUFNLEVBQUUsVUFBVSxFQUFZLFdBQVcsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUNoSixPQUFPLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDOUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxFQUF5QixtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7QUFTOUYsTUFBTSxPQUFPLG9CQUFvQjtJQUcvQixZQUNVLFNBQW1CLEVBQ25CLFdBQXNDLEVBQ3BCLFNBQWMsRUFDWCxXQUFnQjtRQUhyQyxjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQ25CLGdCQUFXLEdBQVgsV0FBVyxDQUEyQjtRQUNwQixjQUFTLEdBQVQsU0FBUyxDQUFLO1FBQ1gsZ0JBQVcsR0FBWCxXQUFXLENBQUs7UUE4Wi9DOzs7V0FHRztRQUNLLHlCQUFvQixHQUFHLENBQUMsS0FBb0IsRUFBRSxFQUFFO1lBQ3RELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxRQUFRLEVBQUU7Z0JBQzFCLElBQUk7b0JBQ0YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7b0JBRXZDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO3dCQUNwQixPQUFPLEtBQUssQ0FBQztxQkFDZDtvQkFFRCxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDM0IsSUFBSSxDQUFDLGdCQUFnQixF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bGljYXRpb25SZWYsIEVtYmVkZGVkVmlld1JlZiwgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3RvciwgUExBVEZPUk1fSUQsIFRlbXBsYXRlUmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCwgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTmd4U21hcnRNb2RhbENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvbmd4LXNtYXJ0LW1vZGFsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJTmd4U21hcnRNb2RhbE9wdGlvbnMsIE5neFNtYXJ0TW9kYWxDb25maWcgfSBmcm9tICcuLi9jb25maWcvbmd4LXNtYXJ0LW1vZGFsLmNvbmZpZyc7XG5pbXBvcnQgeyBOZ3hTbWFydE1vZGFsU3RhY2tTZXJ2aWNlIH0gZnJvbSAnLi9uZ3gtc21hcnQtbW9kYWwtc3RhY2suc2VydmljZSc7XG5pbXBvcnQgeyBNb2RhbEluc3RhbmNlIH0gZnJvbSAnLi9tb2RhbC1pbnN0YW5jZSc7XG5cbmV4cG9ydCB0eXBlIENvbnRlbnQ8VD4gPSBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxUPiB8IFR5cGU8VD47XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIE5neFNtYXJ0TW9kYWxTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBsYXN0RWxlbWVudEZvY3VzZWQ6IGFueTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9pbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSBfbW9kYWxTdGFjazogTmd4U21hcnRNb2RhbFN0YWNrU2VydmljZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2N1bWVudDogYW55LFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgX3BsYXRmb3JtSWQ6IGFueVxuICApIHtcbiAgICB0aGlzLl9hZGRFdmVudHMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgbW9kYWwgaW5zdGFuY2UuIFRoaXMgc3RlcCBpcyBlc3NlbnRpYWwgYW5kIGFsbG93cyB0byByZXRyaWV2ZSBhbnkgbW9kYWwgYXQgYW55IHRpbWUuXG4gICAqIEl0IHN0b3JlcyBhbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgZ2l2ZW4gbW9kYWwgaWRlbnRpZmllciBhbmQgdGhlIG1vZGFsIGl0c2VsZiBkaXJlY3RseSBpbiB0aGUgYG1vZGFsU3RhY2tgLlxuICAgKlxuICAgKiBAcGFyYW0gbW9kYWxJbnN0YW5jZSBUaGUgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGdpdmVuIG1vZGFsIGlkZW50aWZpZXIgYW5kIHRoZSBtb2RhbCBpdHNlbGYuXG4gICAqIEBwYXJhbSBmb3JjZSBPcHRpb25hbCBwYXJhbWV0ZXIgdGhhdCBmb3JjZXMgdGhlIG92ZXJyaWRpbmcgb2YgbW9kYWwgaW5zdGFuY2UgaWYgaXQgYWxyZWFkeSBleGlzdHMuXG4gICAqIEByZXR1cm5zIG5vdGhpbmcgc3BlY2lhbC5cbiAgICovXG4gIHB1YmxpYyBhZGRNb2RhbChtb2RhbEluc3RhbmNlOiBNb2RhbEluc3RhbmNlLCBmb3JjZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLl9tb2RhbFN0YWNrLmFkZE1vZGFsKG1vZGFsSW5zdGFuY2UsIGZvcmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIG1vZGFsIGluc3RhbmNlIGJ5IGl0cyBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKi9cbiAgcHVibGljIGdldE1vZGFsKGlkOiBzdHJpbmcpOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRNb2RhbChpZCk7XG4gIH1cblxuICAvKipcbiAgICogQWxpYXMgb2YgYGdldE1vZGFsYCB0byByZXRyaWV2ZSBhIG1vZGFsIGluc3RhbmNlIGJ5IGl0cyBpZGVudGlmaWVyLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKi9cbiAgcHVibGljIGdldChpZDogc3RyaW5nKTogTmd4U21hcnRNb2RhbENvbXBvbmVudCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kYWwoaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW4gYSBnaXZlbiBtb2RhbFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lLlxuICAgKiBAcGFyYW0gZm9yY2UgVGVsbCB0aGUgbW9kYWwgdG8gb3BlbiB0b3Agb2YgYWxsIG90aGVyIG9wZW5lZCBtb2RhbHNcbiAgICovXG4gIHB1YmxpYyBvcGVuKGlkOiBzdHJpbmcsIGZvcmNlID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3Blbk1vZGFsKHRoaXMuZ2V0KGlkKSwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGEgZ2l2ZW4gbW9kYWxcbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyIHVzZWQgYXQgY3JlYXRpb24gdGltZS5cbiAgICovXG4gIHB1YmxpYyBjbG9zZShpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Nsb3NlTW9kYWwodGhpcy5nZXQoaWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgb3BlbmVkIG1vZGFsc1xuICAgKi9cbiAgcHVibGljIGNsb3NlQWxsKCk6IHZvaWQge1xuICAgIHRoaXMuZ2V0T3BlbmVkTW9kYWxzKCkuZm9yRWFjaCgoaW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpID0+IHtcbiAgICAgIHRoaXMuX2Nsb3NlTW9kYWwoaW5zdGFuY2UubW9kYWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgYSBnaXZlbiBtb2RhbFxuICAgKiBJZiB0aGUgcmV0cmlldmVkIG1vZGFsIGlzIG9wZW5lZCBpdCBjbG9zZXMgaXQsIGVsc2UgaXQgb3BlbnMgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllciB1c2VkIGF0IGNyZWF0aW9uIHRpbWUuXG4gICAqIEBwYXJhbSBmb3JjZSBUZWxsIHRoZSBtb2RhbCB0byBvcGVuIHRvcCBvZiBhbGwgb3RoZXIgb3BlbmVkIG1vZGFsc1xuICAgKi9cbiAgcHVibGljIHRvZ2dsZShpZDogc3RyaW5nLCBmb3JjZSA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3RvZ2dsZU1vZGFsKHRoaXMuZ2V0KGlkKSwgZm9yY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGFsbCB0aGUgY3JlYXRlZCBtb2RhbHMuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGFycmF5IHRoYXQgY29udGFpbnMgYWxsIG1vZGFsIGluc3RhbmNlcy5cbiAgICovXG4gIHB1YmxpYyBnZXRNb2RhbFN0YWNrKCk6IE1vZGFsSW5zdGFuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGFsU3RhY2suZ2V0TW9kYWxTdGFjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGFsbCB0aGUgb3BlbmVkIG1vZGFscy4gSXQgbG9va3MgZm9yIGFsbCBtb2RhbCBpbnN0YW5jZXMgd2l0aCB0aGVpciBgdmlzaWJsZWAgcHJvcGVydHkgc2V0IHRvIGB0cnVlYC5cbiAgICpcbiAgICogQHJldHVybnMgYW4gYXJyYXkgdGhhdCBjb250YWlucyBhbGwgdGhlIG9wZW5lZCBtb2RhbHMuXG4gICAqL1xuICBwdWJsaWMgZ2V0T3BlbmVkTW9kYWxzKCk6IE1vZGFsSW5zdGFuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGFsU3RhY2suZ2V0T3BlbmVkTW9kYWxzKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIG9wZW5lZCBtb2RhbCB3aXRoIGhpZ2hlc3Qgei1pbmRleC5cbiAgICpcbiAgICogQHJldHVybnMgdGhlIG9wZW5lZCBtb2RhbCB3aXRoIGhpZ2hlc3Qgei1pbmRleC5cbiAgICovXG4gIHB1YmxpYyBnZXRUb3BPcGVuZWRNb2RhbCgpOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50IHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRUb3BPcGVuZWRNb2RhbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaGlnaGVyIGB6LWluZGV4YCB2YWx1ZSBiZXR3ZWVuIGFsbCB0aGUgbW9kYWwgaW5zdGFuY2VzLiBJdCBpdGVyYXRlcyBvdmVyIHRoZSBgTW9kYWxTdGFja2AgYXJyYXkgYW5kXG4gICAqIGNhbGN1bGF0ZXMgYSBoaWdoZXIgdmFsdWUgKGl0IHRha2VzIHRoZSBoaWdoZXN0IGluZGV4IHZhbHVlIGJldHdlZW4gYWxsIHRoZSBtb2RhbCBpbnN0YW5jZXMgYW5kIGFkZHMgMSkuXG4gICAqIFVzZSBpdCB0byBtYWtlIGEgbW9kYWwgYXBwZWFyIGZvcmVncm91bmQuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgaGlnaGVyIGluZGV4IGZyb20gYWxsIHRoZSBleGlzdGluZyBtb2RhbCBpbnN0YW5jZXMuXG4gICAqL1xuICBwdWJsaWMgZ2V0SGlnaGVySW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRIaWdoZXJJbmRleCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IGdpdmVzIHRoZSBudW1iZXIgb2YgbW9kYWwgaW5zdGFuY2VzLiBJdCdzIGhlbHBmdWwgdG8ga25vdyBpZiB0aGUgbW9kYWwgc3RhY2sgaXMgZW1wdHkgb3Igbm90LlxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgbnVtYmVyIG9mIG1vZGFsIGluc3RhbmNlcy5cbiAgICovXG4gIHB1YmxpYyBnZXRNb2RhbFN0YWNrQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kYWxTdGFjay5nZXRNb2RhbFN0YWNrQ291bnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBtb2RhbCBpbnN0YW5jZSBmcm9tIHRoZSBtb2RhbCBzdGFjay5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJucyB0aGUgcmVtb3ZlZCBtb2RhbCBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyByZW1vdmVNb2RhbChpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbW9kYWxJbnN0YW5jZSA9IHRoaXMuX21vZGFsU3RhY2sucmVtb3ZlTW9kYWwoaWQpO1xuICAgIGlmIChtb2RhbEluc3RhbmNlKSB7XG4gICAgICB0aGlzLl9kZXN0cm95TW9kYWwobW9kYWxJbnN0YW5jZS5tb2RhbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFzc29jaWF0ZSBkYXRhIHRvIGFuIGlkZW50aWZpZWQgbW9kYWwuIElmIHRoZSBtb2RhbCBpc24ndCBhbHJlYWR5IGFzc29jaWF0ZWQgdG8gc29tZSBkYXRhLCBpdCBjcmVhdGVzIGEgbmV3XG4gICAqIGVudHJ5IGluIHRoZSBgbW9kYWxEYXRhYCBhcnJheSB3aXRoIGl0cyBgaWRgIGFuZCB0aGUgZ2l2ZW4gYGRhdGFgLiBJZiB0aGUgbW9kYWwgYWxyZWFkeSBoYXMgZGF0YSwgaXQgcmV3cml0ZXNcbiAgICogdGhlbSB3aXRoIHRoZSBuZXcgb25lcy4gRmluYWxseSBpZiBubyBtb2RhbCBmb3VuZCBpdCByZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UgaW4gdGhlIGNvbnNvbGUgYW5kIGZhbHNlIHZhbHVlXG4gICAqIGFzIG1ldGhvZCBvdXRwdXQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIHlvdSB3YW50IHRvIGFzc29jaWF0ZSB0byB0aGUgbW9kYWwuXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIGZvcmNlIElmIHRydWUsIG92ZXJyaWRlcyB0aGUgcHJldmlvdXMgc3RvcmVkIGRhdGEgaWYgdGhlcmUgd2FzLlxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RhbCBleGlzdHMgYW5kIHRoZSBwcm9jZXNzIGhhcyBiZWVuIHRyaWVkLCBlaXRoZXIgZmFsc2UuXG4gICAqL1xuICBwdWJsaWMgc2V0TW9kYWxEYXRhKGRhdGE6IGFueSwgaWQ6IHN0cmluZywgZm9yY2U/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbW9kYWwgPSB0aGlzLmdldChpZCk7XG4gICAgaWYgKG1vZGFsKSB7XG4gICAgICBtb2RhbC5zZXREYXRhKGRhdGEsIGZvcmNlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIG1vZGFsIGRhdGEgYnkgaXRzIGlkZW50aWZpZXIuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgbW9kYWwgaWRlbnRpZmllciB1c2VkIGF0IGNyZWF0aW9uIHRpbWUuXG4gICAqIEByZXR1cm5zIHRoZSBhc3NvY2lhdGVkIG1vZGFsIGRhdGEuXG4gICAqL1xuICBwdWJsaWMgZ2V0TW9kYWxEYXRhKGlkOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICBjb25zdCBtb2RhbCA9IHRoaXMuZ2V0KGlkKTtcbiAgICBpZiAobW9kYWwpIHtcbiAgICAgIHJldHVybiBtb2RhbC5nZXREYXRhKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdGhlIGRhdGEgYXR0YWNoZWQgdG8gYSBnaXZlbiBtb2RhbC5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBtb2RhbCBpZGVudGlmaWVyIHVzZWQgYXQgY3JlYXRpb24gdGltZS5cbiAgICogQHJldHVybnMgdGhlIHJlbW92ZWQgZGF0YSBvciBmYWxzZSBpZiBtb2RhbCBkb2Vzbid0IGV4aXN0LlxuICAgKi9cbiAgcHVibGljIHJlc2V0TW9kYWxEYXRhKGlkOiBzdHJpbmcpOiB1bmtub3duIHwgYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX21vZGFsU3RhY2suZ2V0TW9kYWxTdGFjaygpLmZpbmQoKG86IE1vZGFsSW5zdGFuY2UpID0+IG8uaWQgPT09IGlkKSkge1xuICAgICAgY29uc3QgcmVtb3ZlZDogdW5rbm93biA9IHRoaXMuZ2V0TW9kYWwoaWQpLmdldERhdGEoKTtcbiAgICAgIHRoaXMuZ2V0TW9kYWwoaWQpLnJlbW92ZURhdGEoKTtcbiAgICAgIHJldHVybiByZW1vdmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBsYXRlc3Qgb3BlbmVkIG1vZGFsXG4gICAqL1xuICBwdWJsaWMgY2xvc2VMYXRlc3RNb2RhbCgpOiB2b2lkIHtcbiAgICB0aGlzLmdldFRvcE9wZW5lZE1vZGFsKCkuY2xvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgZHluYW1pYyBOZ3hTbWFydE1vZGFsQ29tcG9uZW50XG4gICAqIEBwYXJhbSB2Y3IgQSBWaWV3Q29udGFpbmVyUmVmIHJlZmVyZW5jZVxuICAgKiBAcGFyYW0gaWQgVGhlIG1vZGFsIGlkZW50aWZpZXIgdXNlZCBhdCBjcmVhdGlvbiB0aW1lXG4gICAqIEBwYXJhbSBjb250ZW50IFRoZSBtb2RhbCBjb250ZW50IChzdHJpbmcsIHRlbXBsYXRlUmVmIG9yIENvbXBvbmVudClcbiAgICogQHBhcmFtIG9wdGlvbnMgQW55IE5neFNtYXJ0TW9kYWxDb21wb25lbnQgYXZhaWxhYmxlIG9wdGlvbnNcbiAgICovXG4gIHB1YmxpYyBjcmVhdGU8VD4oaWQ6IHN0cmluZywgY29udGVudDogQ29udGVudDxUPiwgdmNyOiBWaWV3Q29udGFpbmVyUmVmLCBvcHRpb25zOiBJTmd4U21hcnRNb2RhbE9wdGlvbnMgPSB7fSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRNb2RhbChpZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc3QgbmdDb250ZW50ID0gdGhpcy5fcmVzb2x2ZU5nQ29udGVudChjb250ZW50KTtcblxuICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gdmNyLmNyZWF0ZUNvbXBvbmVudChOZ3hTbWFydE1vZGFsQ29tcG9uZW50LCB7IGluamVjdG9yOiB0aGlzLl9pbmplY3RvciwgcHJvamVjdGFibGVOb2RlczogbmdDb250ZW50IH0pO1xuXG4gICAgICBpZiAoY29udGVudCBpbnN0YW5jZW9mIFR5cGUpIHtcbiAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmNvbnRlbnRDb21wb25lbnQgPSBjb250ZW50O1xuICAgICAgfVxuXG4gICAgICBjb21wb25lbnRSZWYuaW5zdGFuY2UuaWRlbnRpZmllciA9IGlkO1xuICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlLmNyZWF0ZUZyb20gPSAnc2VydmljZSc7XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jbG9zYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5jbG9zYWJsZSA9IG9wdGlvbnMuY2xvc2FibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5lc2NhcGFibGUgPT09ICdib29sZWFuJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuZXNjYXBhYmxlID0gb3B0aW9ucy5lc2NhcGFibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kaXNtaXNzYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5kaXNtaXNzYWJsZSA9IG9wdGlvbnMuZGlzbWlzc2FibGU7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jdXN0b21DbGFzcyA9PT0gJ3N0cmluZycpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmN1c3RvbUNsYXNzID0gb3B0aW9ucy5jdXN0b21DbGFzczsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmJhY2tkcm9wID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmJhY2tkcm9wID0gb3B0aW9ucy5iYWNrZHJvcDsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmZvcmNlID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmZvcmNlID0gb3B0aW9ucy5mb3JjZTsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmhpZGVEZWxheSA9PT0gJ251bWJlcicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmhpZGVEZWxheSA9IG9wdGlvbnMuaGlkZURlbGF5OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuYXV0b3N0YXJ0ID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLmF1dG9zdGFydCA9IG9wdGlvbnMuYXV0b3N0YXJ0OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMudGFyZ2V0ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UudGFyZ2V0ID0gb3B0aW9ucy50YXJnZXQ7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5hcmlhTGFiZWwgPT09ICdzdHJpbmcnKSB7IGNvbXBvbmVudFJlZi5pbnN0YW5jZS5hcmlhTGFiZWwgPSBvcHRpb25zLmFyaWFMYWJlbDsgfVxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmFyaWFMYWJlbGxlZEJ5ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuYXJpYUxhYmVsbGVkQnkgPSBvcHRpb25zLmFyaWFMYWJlbGxlZEJ5OyB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuYXJpYURlc2NyaWJlZEJ5ID09PSAnc3RyaW5nJykgeyBjb21wb25lbnRSZWYuaW5zdGFuY2UuYXJpYURlc2NyaWJlZEJ5ID0gb3B0aW9ucy5hcmlhRGVzY3JpYmVkQnk7IH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWZvY3VzID09PSAnYm9vbGVhbicpIHsgY29tcG9uZW50UmVmLmluc3RhbmNlLnJlZm9jdXMgPSBvcHRpb25zLnJlZm9jdXM7IH1cblxuICAgICAgY29uc3QgZG9tRWxlbSA9IChjb21wb25lbnRSZWYuaG9zdFZpZXcgYXMgRW1iZWRkZWRWaWV3UmVmPGFueT4pLnJvb3ROb2Rlc1swXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZG9tRWxlbSk7XG5cbiAgICAgIHJldHVybiBjb21wb25lbnRSZWYuaW5zdGFuY2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYWRkRXZlbnRzKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ2NyZWF0ZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2luaXRNb2RhbChlLmRldGFpbC5pbnN0YW5jZSk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ2RlbGV0ZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2RlbGV0ZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnb3BlbicsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX29wZW5Nb2RhbChlLmRldGFpbC5pbnN0YW5jZS5tb2RhbCwgZS5kZXRhaWwuZXh0cmFEYXRhLnRvcCk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihOZ3hTbWFydE1vZGFsQ29uZmlnLnByZWZpeEV2ZW50ICsgJ3RvZ2dsZScsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX3RvZ2dsZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlLm1vZGFsLCBlLmRldGFpbC5leHRyYURhdGEudG9wKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnY2xvc2UnLCAoKGU6IEN1c3RvbUV2ZW50KSA9PiB7XG4gICAgICB0aGlzLl9jbG9zZU1vZGFsKGUuZGV0YWlsLmluc3RhbmNlLm1vZGFsKTtcbiAgICB9KSBhcyBFdmVudExpc3RlbmVyKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKE5neFNtYXJ0TW9kYWxDb25maWcucHJlZml4RXZlbnQgKyAnZGlzbWlzcycsICgoZTogQ3VzdG9tRXZlbnQpID0+IHtcbiAgICAgIHRoaXMuX2Rpc21pc3NNb2RhbChlLmRldGFpbC5pbnN0YW5jZS5tb2RhbCk7XG4gICAgfSkgYXMgRXZlbnRMaXN0ZW5lcik7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9lc2NhcGVLZXlib2FyZEV2ZW50KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdE1vZGFsKG1vZGFsSW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpIHtcbiAgICBtb2RhbEluc3RhbmNlLm1vZGFsLmxheWVyUG9zaXRpb24gKz0gdGhpcy5nZXRNb2RhbFN0YWNrQ291bnQoKTtcbiAgICB0aGlzLmFkZE1vZGFsKG1vZGFsSW5zdGFuY2UsIG1vZGFsSW5zdGFuY2UubW9kYWwuZm9yY2UpO1xuXG4gICAgaWYgKG1vZGFsSW5zdGFuY2UubW9kYWwuYXV0b3N0YXJ0KSB7XG4gICAgICB0aGlzLm9wZW4obW9kYWxJbnN0YW5jZS5pZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfb3Blbk1vZGFsKG1vZGFsOiBOZ3hTbWFydE1vZGFsQ29tcG9uZW50LCB0b3A/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgaWYgKG1vZGFsLnZpc2libGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmxhc3RFbGVtZW50Rm9jdXNlZCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAobW9kYWwuZXNjYXBhYmxlKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLl9lc2NhcGVLZXlib2FyZEV2ZW50KTtcbiAgICB9XG5cbiAgICBpZiAobW9kYWwuYmFja2Ryb3ApIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5fdHJhcEZvY3VzTW9kYWwpO1xuICAgIH1cblxuICAgIGlmICh0b3ApIHtcbiAgICAgIG1vZGFsLmxheWVyUG9zaXRpb24gPSB0aGlzLmdldEhpZ2hlckluZGV4KCk7XG4gICAgfVxuXG4gICAgbW9kYWwuYWRkQm9keUNsYXNzKCk7XG4gICAgbW9kYWwub3ZlcmxheVZpc2libGUgPSB0cnVlO1xuICAgIG1vZGFsLnZpc2libGUgPSB0cnVlO1xuICAgIG1vZGFsLm9uT3Blbi5lbWl0KG1vZGFsKTtcbiAgICBtb2RhbC5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbW9kYWwub3BlbmVkQ2xhc3MgPSB0cnVlO1xuXG4gICAgICBpZiAobW9kYWwudGFyZ2V0KSB7XG4gICAgICAgIG1vZGFsLnRhcmdldFBsYWNlbWVudCgpO1xuICAgICAgfVxuXG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnZGlhbG9nJyk7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYkluZGV4JywgJy0xJyk7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbW9kYWwnLCAndHJ1ZScpO1xuICAgICAgbW9kYWwubnNtRGlhbG9nLmZpcnN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblxuICAgICAgbW9kYWwubWFya0ZvckNoZWNrKCk7XG4gICAgICBtb2RhbC5vbk9wZW5GaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfdG9nZ2xlTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQsIHRvcD86IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBpZiAobW9kYWwudmlzaWJsZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlTW9kYWwobW9kYWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fb3Blbk1vZGFsKG1vZGFsLCB0b3ApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2Nsb3NlTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQpOiBib29sZWFuIHtcbiAgICBpZiAoIW1vZGFsLm9wZW5lZENsYXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbW9kYWwub3BlbmVkQ2xhc3MgPSBmYWxzZTtcbiAgICBtb2RhbC5vbkNsb3NlLmVtaXQobW9kYWwpO1xuICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudC5lbWl0KG1vZGFsKTtcblxuICAgIGlmICh0aGlzLmdldE9wZW5lZE1vZGFscygpLmxlbmd0aCA8IDIpIHtcbiAgICAgIG1vZGFsLnJlbW92ZUJvZHlDbGFzcygpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5fZXNjYXBlS2V5Ym9hcmRFdmVudCk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuX3RyYXBGb2N1c01vZGFsKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIG1vZGFsLnZpc2libGVDaGFuZ2UuZW1pdChtb2RhbC52aXNpYmxlKTtcbiAgICAgIG1vZGFsLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIG1vZGFsLm92ZXJsYXlWaXNpYmxlID0gZmFsc2U7XG4gICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3RhYkluZGV4Jyk7XG4gICAgICBtb2RhbC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIG1vZGFsLm9uQ2xvc2VGaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudEZpbmlzaGVkLmVtaXQobW9kYWwpO1xuICAgICAgaWYgKG1vZGFsLnJlZm9jdXMpIHtcbiAgICAgICAgdGhpcy5sYXN0RWxlbWVudEZvY3VzZWQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9LCBtb2RhbC5oaWRlRGVsYXkpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIF9kaXNtaXNzTW9kYWwobW9kYWw6IE5neFNtYXJ0TW9kYWxDb21wb25lbnQpOiBib29sZWFuIHtcbiAgICBpZiAoIW1vZGFsLm9wZW5lZENsYXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbW9kYWwub3BlbmVkQ2xhc3MgPSBmYWxzZTtcbiAgICBtb2RhbC5vbkRpc21pc3MuZW1pdChtb2RhbCk7XG4gICAgbW9kYWwub25BbnlDbG9zZUV2ZW50LmVtaXQobW9kYWwpO1xuXG4gICAgaWYgKHRoaXMuZ2V0T3BlbmVkTW9kYWxzKCkubGVuZ3RoIDwgMikge1xuICAgICAgbW9kYWwucmVtb3ZlQm9keUNsYXNzKCk7XG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBtb2RhbC52aXNpYmxlID0gZmFsc2U7XG4gICAgICBtb2RhbC52aXNpYmxlQ2hhbmdlLmVtaXQobW9kYWwudmlzaWJsZSk7XG4gICAgICBtb2RhbC5vdmVybGF5VmlzaWJsZSA9IGZhbHNlO1xuICAgICAgbW9kYWwubWFya0ZvckNoZWNrKCk7XG4gICAgICBtb2RhbC5vbkRpc21pc3NGaW5pc2hlZC5lbWl0KG1vZGFsKTtcbiAgICAgIG1vZGFsLm9uQW55Q2xvc2VFdmVudEZpbmlzaGVkLmVtaXQobW9kYWwpO1xuICAgIH0sIG1vZGFsLmhpZGVEZWxheSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgX2RlbGV0ZU1vZGFsKG1vZGFsSW5zdGFuY2U6IE1vZGFsSW5zdGFuY2UpIHtcbiAgICB0aGlzLnJlbW92ZU1vZGFsKG1vZGFsSW5zdGFuY2UuaWQpO1xuXG4gICAgaWYgKCF0aGlzLmdldE1vZGFsU3RhY2soKS5sZW5ndGgpIHtcbiAgICAgIG1vZGFsSW5zdGFuY2UubW9kYWwucmVtb3ZlQm9keUNsYXNzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgY29udGVudCBhY2NvcmRpbmcgdG8gdGhlIHR5cGVzXG4gICAqIEBwYXJhbSBjb250ZW50IFRoZSBtb2RhbCBjb250ZW50IChzdHJpbmcsIHRlbXBsYXRlUmVmIG9yIENvbXBvbmVudClcbiAgICovXG4gIHByaXZhdGUgX3Jlc29sdmVOZ0NvbnRlbnQ8VD4oY29udGVudDogQ29udGVudDxUPik6IGFueVtdW10gfCBUZXh0W11bXSB7XG4gICAgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIFtbZWxlbWVudF1dO1xuICAgIH1cblxuICAgIGlmIChjb250ZW50IGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSBjb250ZW50LmNyZWF0ZUVtYmVkZGVkVmlldyhudWxsIGFzIGFueSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHZpZXdSZWYpO1xuICAgICAgcmV0dXJuIFt2aWV3UmVmLnJvb3ROb2Rlc107XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBsYXRlc3Qgb3BlbmVkIG1vZGFsIGlmIGVzY2FwZSBrZXkgZXZlbnQgaXMgZW1pdHRlZFxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIEtleWJvYXJkIEV2ZW50XG4gICAqL1xuICBwcml2YXRlIF9lc2NhcGVLZXlib2FyZEV2ZW50ID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1vZGFsID0gdGhpcy5nZXRUb3BPcGVuZWRNb2RhbCgpO1xuXG4gICAgICAgIGlmICghbW9kYWwuZXNjYXBhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgbW9kYWwub25Fc2NhcGUuZW1pdChtb2RhbCk7XG4gICAgICAgIHRoaXMuY2xvc2VMYXRlc3RNb2RhbCgpO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIElzIGN1cnJlbnQgcGxhdGZvcm0gYnJvd3NlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgaXNCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLl9wbGF0Zm9ybUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGlsZSBtb2RhbCBpcyBvcGVuLCB0aGUgZm9jdXMgc3RheSBvbiBpdFxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIEtleWJvYXIgZEV2ZW50XG4gICAqL1xuICBwcml2YXRlIF90cmFwRm9jdXNNb2RhbCA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdUYWInKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtb2RhbCA9IHRoaXMuZ2V0VG9wT3BlbmVkTW9kYWwoKTtcblxuICAgICAgICBpZiAoIW1vZGFsLm5zbURpYWxvZy5maXJzdC5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBtb2RhbC5uc21EaWFsb2cuZmlyc3QubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGR5bmFtaWNhbGx5IGNyZWF0ZWQgbW9kYWwgZnJvbSBET01cbiAgICovXG4gIHByaXZhdGUgX2Rlc3Ryb3lNb2RhbChtb2RhbDogTmd4U21hcnRNb2RhbENvbXBvbmVudCk6IHZvaWQge1xuICAgIC8vIFByZXZlbnQgZGVzdHJ1Y3Rpb24gb2YgdGhlIGlubGluZSBtb2RhbHNcbiAgICBpZiAobW9kYWwuY3JlYXRlRnJvbSAhPT0gJ3NlcnZpY2UnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChtb2RhbC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldHRlciBmdW5jdGlvbiB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRlbmN5IGVycm9yXG4gICAqIEByZXR1cm5zIEFwcGxpY2F0aW9uUmVmIGluc3RhbmNlXG4gICAqICovXG4gIHByaXZhdGUgZ2V0IGFwcFJlZigpOiBBcHBsaWNhdGlvblJlZiB7XG4gICAgcmV0dXJuIHRoaXMuX2luamVjdG9yLmdldChBcHBsaWNhdGlvblJlZik7XG4gIH1cbn1cbiJdfQ==