ng-devui
Version:
DevUI components based on Angular
209 lines • 39.3 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { Component, ElementRef, Inject, Input, Renderer2, ViewChild } from '@angular/core';
import { backdropFadeInOut, wipeInOutAnimation } from 'ng-devui/utils';
import { isUndefined } from 'lodash-es';
import { Subscription, fromEvent } from 'rxjs';
import { ModalContainerDirective } from './modal.directive';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "./modal.directive";
import * as i3 from "./movable.directive";
export class ModalComponent {
constructor(elementRef, renderer, doc) {
this.elementRef = elementRef;
this.renderer = renderer;
this.doc = doc;
this.showAnimation = true;
this.placement = 'center';
this.bodyScrollable = true; // 打开弹窗body是否可滚动
this.animateState = '';
this.ignoreBackDropClick = false;
this.pressEscToClose = new Subscription();
this.maximized = false;
this.onModalClick = ($event) => {
// 一定要document.contains($event.target),因为$event.target可能已经不在document里了,这个时候就不能进hide了,使用document.body兼容IE
if (this.backdropCloseable &&
!this.ignoreBackDropClick &&
!this.dialogElement.nativeElement.contains($event.target) &&
this.document.body.contains($event.target)) {
this.hide();
}
this.ignoreBackDropClick = false;
};
this.modalMouseDown = ($event) => {
this.mouseDwonEl = $event.target;
};
this.modalMouseUp = ($event) => {
if ($event.target !== this.mouseDwonEl) {
this.ignoreBackDropClick = true;
}
};
this.backdropCloseable = isUndefined(this.backdropCloseable) ? true : this.backdropCloseable;
this.document = this.doc;
}
ngOnInit() {
if (this.escapable) {
this.pressEscToClose.add(fromEvent(window, 'keydown').subscribe((event) => {
if (event.keyCode === 27) {
this.hide();
}
}));
}
const handle = this.elementRef.nativeElement.querySelector('#d-modal-header');
if (handle) {
this.draggableHandleEl = handle;
}
this._oldWidth = this.width;
}
ngOnDestroy() {
if (this.pressEscToClose) {
this.pressEscToClose.unsubscribe();
this.pressEscToClose = null;
}
}
// Will overwrite this method in modal service
onHidden() { }
updateButtonOptions(buttonOptions) { }
canHideModel() {
let hiddenResult = Promise.resolve(true);
if (this.beforeHidden) {
const result = this.beforeHidden();
if (typeof result !== 'undefined') {
if (result.then) {
hiddenResult = result;
}
else if (result.subscribe) {
hiddenResult = result.toPromise();
}
else {
hiddenResult = Promise.resolve(result);
}
}
}
return hiddenResult;
}
maximize() {
this.maximized = !this.maximized;
if (this.maximized) {
this.width = '100vw';
this.renderer.setStyle(this.document.body, 'overflow', 'hidden');
}
else {
this.width = this._oldWidth;
this.renderer.setStyle(this.document.body, 'overflow', 'auto');
}
}
onAnimationEnd($event) {
if ($event.fromState !== 'void' && this.animateState === 'void') {
this.onHidden();
}
}
show() {
this.documentOverFlow = this.document.documentElement.scrollHeight > this.document.documentElement.clientHeight;
if (this.documentOverFlow) {
this.scrollTop = this.document.documentElement.scrollTop || this.document.body.scrollTop;
this.scrollLeft = this.document.documentElement.scrollLeft || this.document.body.scrollLeft;
this.renderer.addClass(this.document.body, 'devui-body-scrollblock');
this.renderer.setStyle(this.document.body, 'top', `-${this.scrollTop}px`);
this.renderer.setStyle(this.document.body, 'left', `-${this.scrollLeft}px`);
}
this.bodyScrollBlock(true);
this.dialogElement.nativeElement.focus();
if (this.showAnimation) {
this.animateState = 'in';
}
}
hide() {
this.canHideModel().then((canHide) => {
if (!canHide) {
return;
}
this.bodyScrollBlock(false);
this.animateState = 'void';
});
}
bodyScrollBlock(toggle) {
if (this.bodyScrollable || !this.documentOverFlow) {
return;
}
if (toggle) {
this.renderer.addClass(this.document.documentElement, 'devui-body-scrollblock-modal');
this.renderer.setStyle(this.document.documentElement, 'top', `-${this.scrollTop}px`);
this.renderer.setStyle(this.document.documentElement, 'left', `-${this.scrollLeft}px`);
}
else {
this.renderer.removeClass(this.document.documentElement, 'devui-body-scrollblock-modal');
this.renderer.removeStyle(this.document.documentElement, 'top');
this.renderer.removeStyle(this.document.documentElement, 'left');
this.document.documentElement.scrollLeft = this.scrollLeft;
this.document.documentElement.scrollTop = this.scrollTop;
}
}
resolveTransformTranslate() {
let autoOffsetYByPlacement;
switch (this.placement) {
case 'top':
autoOffsetYByPlacement = '40px';
break;
case 'bottom':
autoOffsetYByPlacement = '-40px';
break;
case 'center':
default:
autoOffsetYByPlacement = 0;
break;
}
if (this.placement !== 'unset') {
const offsetX = this.offsetX ? this.offsetX : '0';
const offsetY = this.offsetY ? this.offsetY : autoOffsetYByPlacement;
return 'translate(' + offsetX + ',' + offsetY + ')';
}
else {
return 'unset';
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ModalComponent, selector: "d-modal", inputs: { id: "id", showAnimation: "showAnimation", width: "width", zIndex: "zIndex", backDropZIndex: "backDropZIndex", backdropCloseable: "backdropCloseable", beforeHidden: "beforeHidden", draggable: "draggable", placement: "placement", offsetX: "offsetX", offsetY: "offsetY", bodyScrollable: "bodyScrollable", escapable: "escapable", cssClass: "cssClass" }, viewQueries: [{ propertyName: "modalContainerHost", first: true, predicate: ModalContainerDirective, descendants: true, static: true }, { propertyName: "dialogElement", first: true, predicate: ["dialog"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"modal-backdrop\" [ngStyle]=\"{ 'z-index': backDropZIndex }\" [@backdropAnimation]=\"animateState\"></div>\n<div\n class=\"modal in\"\n [ngClass]=\"cssClass\"\n [ngStyle]=\"{ 'z-index': zIndex }\"\n [attr.id]=\"id\"\n (mousedown)=\"modalMouseDown($event)\"\n (mouseup)=\"modalMouseUp($event)\"\n (click)=\"onModalClick($event)\"\n>\n <div\n class=\"modal-dialog\"\n [ngClass]=\"{\n 'place-at-top': placement === 'top',\n 'place-at-bottom': placement === 'bottom',\n 'place-at-center': placement === 'center' || placement === 'unset'\n }\"\n [ngStyle]=\"{ width: width }\"\n [@wipeInOutAnimation]=\"animateState\"\n (@wipeInOutAnimation.done)=\"onAnimationEnd($event)\"\n [@.disabled]=\"!showAnimation\"\n tabindex=\"1\"\n #dialog\n >\n <div\n class=\"modal-content\"\n [class.maximize]=\"maximized\"\n [dMovable]=\"draggable\"\n [handle]=\"draggableHandleEl\"\n [ngStyle]=\"{ transform: resolveTransformTranslate() }\"\n >\n <ng-template dModalContainerHost></ng-template>\n <ng-container *ngIf=\"contentTemplate\">\n <ng-template [ngTemplateOutlet]=\"contentTemplate\" [ngTemplateOutletContext]=\"{ modalInstance: this }\"></ng-template>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.modal{position:fixed;top:0;right:0;bottom:0!important;left:0;z-index:var(--devui-z-index-modal, 1050);outline:0;overflow-y:auto;display:block;display:-ms-flexbox;display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.devui-body-scrollblock .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:0 auto}.modal-dialog .maximize{-webkit-transition:none;transition:none;transform:none;width:100vw;top:0;left:0;max-height:100vh;height:100vh}.modal-dialog.place-at-center{margin:auto}.modal-dialog.place-at-top{margin-bottom:auto}.modal-dialog.place-at-bottom{margin-top:auto}.modal-backdrop{position:fixed;top:0;right:0;bottom:0!important;left:0;z-index:calc(var(--devui-z-index-modal, 1050) - 1);background-color:var(--devui-feedback-overlay-backdrop, rgba(0, 0, 0, .3))}.modal-maximized{-webkit-transition:none;transition:none;transform:none;width:100vw!important;top:0!important;left:0!important;max-height:100vh;height:100vh}:host ::ng-deep .modal-content{position:relative;border-radius:var(--devui-border-radius-card, 6px);border:none;background-color:var(--devui-fullscreen-overlay-bg, #ffffff);background-clip:padding-box;outline:0;box-shadow:var(--devui-shadow-length-fullscreen-overlay, 0 16px 48px 0) var(--devui-shadow, rgba(0, 0, 0, .16))}:host ::ng-deep .modal-content .modal-body{padding:20px;color:var(--devui-text-weak, #333333)}:host ::ng-deep .modal-content .modal-footer{border-top:none;text-align:center;padding:0 20px 20px}:host ::ng-deep .modal-content .modal-footer button{margin:0 4px;width:auto}:host ::ng-deep .modal-content .modal-footer button.pull-left{padding-left:5px;padding-right:5px;position:relative;left:-5px}:host ::ng-deep .modal-content .modal-footer button+button{margin-bottom:16px}:host ::ng-deep .d-btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;white-space:nowrap;font-size:var(--devui-font-size-card-title, 14px);line-height:1.42857143;border-radius:var(--devui-border-radius, 2px);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:focus{outline:none}::ng-deep .devui-body-scrollblock-modal{width:100%;position:fixed;overflow-y:scroll}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.ModalContainerDirective, selector: "[dModalContainerHost]" }, { kind: "directive", type: i3.MovableDirective, selector: "[dMovable]", inputs: ["handle", "moveEl", "dMovable"] }], animations: [backdropFadeInOut, wipeInOutAnimation] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalComponent, decorators: [{
type: Component,
args: [{ selector: 'd-modal', animations: [backdropFadeInOut, wipeInOutAnimation], preserveWhitespaces: false, template: "<div class=\"modal-backdrop\" [ngStyle]=\"{ 'z-index': backDropZIndex }\" [@backdropAnimation]=\"animateState\"></div>\n<div\n class=\"modal in\"\n [ngClass]=\"cssClass\"\n [ngStyle]=\"{ 'z-index': zIndex }\"\n [attr.id]=\"id\"\n (mousedown)=\"modalMouseDown($event)\"\n (mouseup)=\"modalMouseUp($event)\"\n (click)=\"onModalClick($event)\"\n>\n <div\n class=\"modal-dialog\"\n [ngClass]=\"{\n 'place-at-top': placement === 'top',\n 'place-at-bottom': placement === 'bottom',\n 'place-at-center': placement === 'center' || placement === 'unset'\n }\"\n [ngStyle]=\"{ width: width }\"\n [@wipeInOutAnimation]=\"animateState\"\n (@wipeInOutAnimation.done)=\"onAnimationEnd($event)\"\n [@.disabled]=\"!showAnimation\"\n tabindex=\"1\"\n #dialog\n >\n <div\n class=\"modal-content\"\n [class.maximize]=\"maximized\"\n [dMovable]=\"draggable\"\n [handle]=\"draggableHandleEl\"\n [ngStyle]=\"{ transform: resolveTransformTranslate() }\"\n >\n <ng-template dModalContainerHost></ng-template>\n <ng-container *ngIf=\"contentTemplate\">\n <ng-template [ngTemplateOutlet]=\"contentTemplate\" [ngTemplateOutletContext]=\"{ modalInstance: this }\"></ng-template>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.modal{position:fixed;top:0;right:0;bottom:0!important;left:0;z-index:var(--devui-z-index-modal, 1050);outline:0;overflow-y:auto;display:block;display:-ms-flexbox;display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.devui-body-scrollblock .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:0 auto}.modal-dialog .maximize{-webkit-transition:none;transition:none;transform:none;width:100vw;top:0;left:0;max-height:100vh;height:100vh}.modal-dialog.place-at-center{margin:auto}.modal-dialog.place-at-top{margin-bottom:auto}.modal-dialog.place-at-bottom{margin-top:auto}.modal-backdrop{position:fixed;top:0;right:0;bottom:0!important;left:0;z-index:calc(var(--devui-z-index-modal, 1050) - 1);background-color:var(--devui-feedback-overlay-backdrop, rgba(0, 0, 0, .3))}.modal-maximized{-webkit-transition:none;transition:none;transform:none;width:100vw!important;top:0!important;left:0!important;max-height:100vh;height:100vh}:host ::ng-deep .modal-content{position:relative;border-radius:var(--devui-border-radius-card, 6px);border:none;background-color:var(--devui-fullscreen-overlay-bg, #ffffff);background-clip:padding-box;outline:0;box-shadow:var(--devui-shadow-length-fullscreen-overlay, 0 16px 48px 0) var(--devui-shadow, rgba(0, 0, 0, .16))}:host ::ng-deep .modal-content .modal-body{padding:20px;color:var(--devui-text-weak, #333333)}:host ::ng-deep .modal-content .modal-footer{border-top:none;text-align:center;padding:0 20px 20px}:host ::ng-deep .modal-content .modal-footer button{margin:0 4px;width:auto}:host ::ng-deep .modal-content .modal-footer button.pull-left{padding-left:5px;padding-right:5px;position:relative;left:-5px}:host ::ng-deep .modal-content .modal-footer button+button{margin-bottom:16px}:host ::ng-deep .d-btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;white-space:nowrap;font-size:var(--devui-font-size-card-title, 14px);line-height:1.42857143;border-radius:var(--devui-border-radius, 2px);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:focus{outline:none}::ng-deep .devui-body-scrollblock-modal{width:100%;position:fixed;overflow-y:scroll}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { id: [{
type: Input
}], showAnimation: [{
type: Input
}], width: [{
type: Input
}], zIndex: [{
type: Input
}], backDropZIndex: [{
type: Input
}], backdropCloseable: [{
type: Input
}], beforeHidden: [{
type: Input
}], draggable: [{
type: Input
}], placement: [{
type: Input
}], offsetX: [{
type: Input
}], offsetY: [{
type: Input
}], bodyScrollable: [{
type: Input
}], escapable: [{
type: Input
}], cssClass: [{
type: Input
}], modalContainerHost: [{
type: ViewChild,
args: [ModalContainerDirective, { static: true }]
}], dialogElement: [{
type: ViewChild,
args: ['dialog', { static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2dWkvbW9kYWwvbW9kYWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vZGV2dWkvbW9kYWwvbW9kYWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQXFCLFNBQVMsRUFBZSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0gsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN4QyxPQUFPLEVBQWMsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7QUFTNUQsTUFBTSxPQUFPLGNBQWM7SUFpQ3pCLFlBQW9CLFVBQXNCLEVBQVUsUUFBbUIsRUFBNEIsR0FBUTtRQUF2RixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUE0QixRQUFHLEdBQUgsR0FBRyxDQUFLO1FBL0JsRyxrQkFBYSxHQUFHLElBQUksQ0FBQztRQU9yQixjQUFTLEdBQTBDLFFBQVEsQ0FBQztRQUc1RCxtQkFBYyxHQUFHLElBQUksQ0FBQyxDQUFDLGdCQUFnQjtRQUtoRCxpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQU9sQix3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDNUIsb0JBQWUsR0FBaUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUtuRCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBMERsQixpQkFBWSxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDeEIsd0dBQXdHO1lBQ3hHLElBQ0UsSUFBSSxDQUFDLGlCQUFpQjtnQkFDdEIsQ0FBQyxJQUFJLENBQUMsbUJBQW1CO2dCQUN6QixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUN6RCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUMxQyxDQUFDO2dCQUNELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNkLENBQUM7WUFDRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO1FBQ25DLENBQUMsQ0FBQztRQUVGLG1CQUFjLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDbkMsQ0FBQyxDQUFDO1FBRUYsaUJBQVksR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3hCLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7WUFDbEMsQ0FBQztRQUNILENBQUMsQ0FBQztRQTNFQSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUM3RixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDM0IsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FDdEIsU0FBUyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTtnQkFDcEQsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLEVBQUUsRUFBRSxDQUFDO29CQUN6QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2QsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDOUUsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUM7UUFDbEMsQ0FBQztRQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUM7SUFFRCw4Q0FBOEM7SUFDOUMsUUFBUSxLQUFJLENBQUM7SUFFYixtQkFBbUIsQ0FBSSxhQUF1QixJQUFHLENBQUM7SUFFbEQsWUFBWTtRQUNWLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsTUFBTSxNQUFNLEdBQVEsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3hDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNoQixZQUFZLEdBQUcsTUFBTSxDQUFDO2dCQUN4QixDQUFDO3FCQUFNLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUM1QixZQUFZLEdBQUksTUFBOEIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDN0QsQ0FBQztxQkFBTSxDQUFDO29CQUNOLFlBQVksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0lBeUJELFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNqQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQztZQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkUsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pFLENBQUM7SUFDSCxDQUFDO0lBRUQsY0FBYyxDQUFDLE1BQU07UUFDbkIsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ2hFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUk7UUFDRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQztRQUNoSCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUN6RixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDNUYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztZQUMxRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN6QyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUk7UUFDRixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNiLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxlQUFlLENBQUMsTUFBZTtRQUM3QixJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNsRCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO1lBQ3RGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLEtBQUssRUFBRSxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO1lBQ3JGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDO1FBQ3pGLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsOEJBQThCLENBQUMsQ0FBQztZQUN6RixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNoRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMzRCxDQUFDO0lBQ0gsQ0FBQztJQUVELHlCQUF5QjtRQUN2QixJQUFJLHNCQUFzQixDQUFDO1FBQzNCLFFBQVEsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3pCLEtBQUssS0FBSztnQkFDUixzQkFBc0IsR0FBRyxNQUFNLENBQUM7Z0JBQ2hDLE1BQU07WUFDUixLQUFLLFFBQVE7Z0JBQ1gsc0JBQXNCLEdBQUcsT0FBTyxDQUFDO2dCQUNqQyxNQUFNO1lBQ1IsS0FBSyxRQUFRLENBQUM7WUFDZDtnQkFDRSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7Z0JBQzNCLE1BQU07UUFDUixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQy9CLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQztZQUNyRSxPQUFPLFlBQVksR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLE9BQU8sR0FBRyxHQUFHLENBQUM7UUFDdEQsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQzsrR0FoTVUsY0FBYyxxRUFpQ3dELFFBQVE7bUdBakM5RSxjQUFjLDJjQWVkLHVCQUF1QixzS0M3QnBDLDB4Q0FzQ0EsazdIRDNCYyxDQUFDLGlCQUFpQixFQUFFLGtCQUFrQixDQUFDOzs0RkFHeEMsY0FBYztrQkFQMUIsU0FBUzsrQkFDRSxTQUFTLGNBR1AsQ0FBQyxpQkFBaUIsRUFBRSxrQkFBa0IsQ0FBQyx1QkFDOUIsS0FBSzs7MEJBbUNnRCxNQUFNOzJCQUFDLFFBQVE7eUNBaENoRixFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ2dELGtCQUFrQjtzQkFBdkUsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ2IsYUFBYTtzQkFBbkQsU0FBUzt1QkFBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBSZW5kZXJlcjIsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgYmFja2Ryb3BGYWRlSW5PdXQsIHdpcGVJbk91dEFuaW1hdGlvbiB9IGZyb20gJ25nLWRldnVpL3V0aWxzJztcclxuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tICdsb2Rhc2gtZXMnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24sIGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBNb2RhbENvbnRhaW5lckRpcmVjdGl2ZSB9IGZyb20gJy4vbW9kYWwuZGlyZWN0aXZlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZC1tb2RhbCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21vZGFsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9tb2RhbC5jb21wb25lbnQuc2NzcyddLFxyXG4gIGFuaW1hdGlvbnM6IFtiYWNrZHJvcEZhZGVJbk91dCwgd2lwZUluT3V0QW5pbWF0aW9uXSxcclxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcclxufSlcclxuZXhwb3J0IGNsYXNzIE1vZGFsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIGlkOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgc2hvd0FuaW1hdGlvbiA9IHRydWU7XHJcbiAgQElucHV0KCkgd2lkdGg6IHN0cmluZztcclxuICBASW5wdXQoKSB6SW5kZXg6IG51bWJlcjtcclxuICBASW5wdXQoKSBiYWNrRHJvcFpJbmRleDogbnVtYmVyO1xyXG4gIEBJbnB1dCgpIGJhY2tkcm9wQ2xvc2VhYmxlOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGJlZm9yZUhpZGRlbjogKCkgPT4gYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj4gfCBPYnNlcnZhYmxlPGJvb2xlYW4+O1xyXG4gIEBJbnB1dCgpIGRyYWdnYWJsZTogYm9vbGVhbjtcclxuICBASW5wdXQoKSBwbGFjZW1lbnQ6ICdjZW50ZXInIHwgJ3RvcCcgfCAnYm90dG9tJyB8ICd1bnNldCcgPSAnY2VudGVyJztcclxuICBASW5wdXQoKSBvZmZzZXRYOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgb2Zmc2V0WTogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGJvZHlTY3JvbGxhYmxlID0gdHJ1ZTsgLy8g5omT5byA5by556qXYm9keeaYr+WQpuWPr+a7muWKqFxyXG4gIEBJbnB1dCgpIGVzY2FwYWJsZTogYm9vbGVhbjsgLy8g5piv5ZCm5pSv5oyBZXNj6ZSu5YWz6Zet5by556qXXHJcbiAgQElucHV0KCkgY3NzQ2xhc3M6IHN0cmluZztcclxuICBAVmlld0NoaWxkKE1vZGFsQ29udGFpbmVyRGlyZWN0aXZlLCB7IHN0YXRpYzogdHJ1ZSB9KSBtb2RhbENvbnRhaW5lckhvc3Q6IE1vZGFsQ29udGFpbmVyRGlyZWN0aXZlO1xyXG4gIEBWaWV3Q2hpbGQoJ2RpYWxvZycsIHsgc3RhdGljOiB0cnVlIH0pIGRpYWxvZ0VsZW1lbnQ6IEVsZW1lbnRSZWY7XHJcbiAgYW5pbWF0ZVN0YXRlID0gJyc7XHJcbiAgZHJhZ2dhYmxlSGFuZGxlRWw6IEhUTUxFbGVtZW50O1xyXG4gIHNjcm9sbFRvcDogbnVtYmVyO1xyXG4gIHNjcm9sbExlZnQ6IG51bWJlcjtcclxuICBkb2N1bWVudE92ZXJGbG93OiBib29sZWFuO1xyXG5cclxuICBtb3VzZUR3b25FbDogRWxlbWVudFJlZjtcclxuICBpZ25vcmVCYWNrRHJvcENsaWNrID0gZmFsc2U7XHJcbiAgcHJlc3NFc2NUb0Nsb3NlOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcblxyXG4gIGNvbnRlbnRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBkb2N1bWVudDogRG9jdW1lbnQ7XHJcblxyXG4gIG1heGltaXplZCA9IGZhbHNlO1xyXG4gIF9vbGRXaWR0aDogc3RyaW5nO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2M6IGFueSkge1xyXG4gICAgdGhpcy5iYWNrZHJvcENsb3NlYWJsZSA9IGlzVW5kZWZpbmVkKHRoaXMuYmFja2Ryb3BDbG9zZWFibGUpID8gdHJ1ZSA6IHRoaXMuYmFja2Ryb3BDbG9zZWFibGU7XHJcbiAgICB0aGlzLmRvY3VtZW50ID0gdGhpcy5kb2M7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIGlmICh0aGlzLmVzY2FwYWJsZSkge1xyXG4gICAgICB0aGlzLnByZXNzRXNjVG9DbG9zZS5hZGQoXHJcbiAgICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ2tleWRvd24nKS5zdWJzY3JpYmUoKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAyNykge1xyXG4gICAgICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGhhbmRsZSA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNkLW1vZGFsLWhlYWRlcicpO1xyXG4gICAgaWYgKGhhbmRsZSkge1xyXG4gICAgICB0aGlzLmRyYWdnYWJsZUhhbmRsZUVsID0gaGFuZGxlO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX29sZFdpZHRoID0gdGhpcy53aWR0aDtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMucHJlc3NFc2NUb0Nsb3NlKSB7XHJcbiAgICAgIHRoaXMucHJlc3NFc2NUb0Nsb3NlLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgIHRoaXMucHJlc3NFc2NUb0Nsb3NlID0gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFdpbGwgb3ZlcndyaXRlIHRoaXMgbWV0aG9kIGluIG1vZGFsIHNlcnZpY2VcclxuICBvbkhpZGRlbigpIHt9XHJcblxyXG4gIHVwZGF0ZUJ1dHRvbk9wdGlvbnM8VD4oYnV0dG9uT3B0aW9uczogQXJyYXk8VD4pIHt9XHJcblxyXG4gIGNhbkhpZGVNb2RlbCgpIHtcclxuICAgIGxldCBoaWRkZW5SZXN1bHQgPSBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XHJcblxyXG4gICAgaWYgKHRoaXMuYmVmb3JlSGlkZGVuKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdDogYW55ID0gdGhpcy5iZWZvcmVIaWRkZW4oKTtcclxuICAgICAgaWYgKHR5cGVvZiByZXN1bHQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgaWYgKHJlc3VsdC50aGVuKSB7XHJcbiAgICAgICAgICBoaWRkZW5SZXN1bHQgPSByZXN1bHQ7XHJcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuc3Vic2NyaWJlKSB7XHJcbiAgICAgICAgICBoaWRkZW5SZXN1bHQgPSAocmVzdWx0IGFzIE9ic2VydmFibGU8Ym9vbGVhbj4pLnRvUHJvbWlzZSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBoaWRkZW5SZXN1bHQgPSBQcm9taXNlLnJlc29sdmUocmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaGlkZGVuUmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgb25Nb2RhbENsaWNrID0gKCRldmVudCkgPT4ge1xyXG4gICAgLy8g5LiA5a6a6KaBZG9jdW1lbnQuY29udGFpbnMoJGV2ZW50LnRhcmdldCnvvIzlm6DkuLokZXZlbnQudGFyZ2V05Y+v6IO95bey57uP5LiN5ZyoZG9jdW1lbnTph4zkuobvvIzov5nkuKrml7blgJnlsLHkuI3og73ov5toaWRl5LqGLOS9v+eUqGRvY3VtZW50LmJvZHnlhbzlrrlJRVxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLmJhY2tkcm9wQ2xvc2VhYmxlICYmXHJcbiAgICAgICF0aGlzLmlnbm9yZUJhY2tEcm9wQ2xpY2sgJiZcclxuICAgICAgIXRoaXMuZGlhbG9nRWxlbWVudC5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKCRldmVudC50YXJnZXQpICYmXHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5jb250YWlucygkZXZlbnQudGFyZ2V0KVxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pZ25vcmVCYWNrRHJvcENsaWNrID0gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgbW9kYWxNb3VzZURvd24gPSAoJGV2ZW50KSA9PiB7XHJcbiAgICB0aGlzLm1vdXNlRHdvbkVsID0gJGV2ZW50LnRhcmdldDtcclxuICB9O1xyXG5cclxuICBtb2RhbE1vdXNlVXAgPSAoJGV2ZW50KSA9PiB7XHJcbiAgICBpZiAoJGV2ZW50LnRhcmdldCAhPT0gdGhpcy5tb3VzZUR3b25FbCkge1xyXG4gICAgICB0aGlzLmlnbm9yZUJhY2tEcm9wQ2xpY2sgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIG1heGltaXplKCkge1xyXG4gICAgdGhpcy5tYXhpbWl6ZWQgPSAhdGhpcy5tYXhpbWl6ZWQ7XHJcbiAgICBpZiAodGhpcy5tYXhpbWl6ZWQpIHtcclxuICAgICAgdGhpcy53aWR0aCA9ICcxMDB2dyc7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5kb2N1bWVudC5ib2R5LCAnb3ZlcmZsb3cnLCAnaGlkZGVuJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLndpZHRoID0gdGhpcy5fb2xkV2lkdGg7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5kb2N1bWVudC5ib2R5LCAnb3ZlcmZsb3cnLCAnYXV0bycpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25BbmltYXRpb25FbmQoJGV2ZW50KSB7XHJcbiAgICBpZiAoJGV2ZW50LmZyb21TdGF0ZSAhPT0gJ3ZvaWQnICYmIHRoaXMuYW5pbWF0ZVN0YXRlID09PSAndm9pZCcpIHtcclxuICAgICAgdGhpcy5vbkhpZGRlbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2hvdygpIHtcclxuICAgIHRoaXMuZG9jdW1lbnRPdmVyRmxvdyA9IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodCA+IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgIGlmICh0aGlzLmRvY3VtZW50T3ZlckZsb3cpIHtcclxuICAgICAgdGhpcy5zY3JvbGxUb3AgPSB0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgdGhpcy5kb2N1bWVudC5ib2R5LnNjcm9sbFRvcDtcclxuICAgICAgdGhpcy5zY3JvbGxMZWZ0ID0gdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCB0aGlzLmRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdDtcclxuICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmRvY3VtZW50LmJvZHksICdkZXZ1aS1ib2R5LXNjcm9sbGJsb2NrJyk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5kb2N1bWVudC5ib2R5LCAndG9wJywgYC0ke3RoaXMuc2Nyb2xsVG9wfXB4YCk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5kb2N1bWVudC5ib2R5LCAnbGVmdCcsIGAtJHt0aGlzLnNjcm9sbExlZnR9cHhgKTtcclxuICAgIH1cclxuICAgIHRoaXMuYm9keVNjcm9sbEJsb2NrKHRydWUpO1xyXG4gICAgdGhpcy5kaWFsb2dFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgIGlmICh0aGlzLnNob3dBbmltYXRpb24pIHtcclxuICAgICAgdGhpcy5hbmltYXRlU3RhdGUgPSAnaW4nO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaGlkZSgpIHtcclxuICAgIHRoaXMuY2FuSGlkZU1vZGVsKCkudGhlbigoY2FuSGlkZSkgPT4ge1xyXG4gICAgICBpZiAoIWNhbkhpZGUpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5ib2R5U2Nyb2xsQmxvY2soZmFsc2UpO1xyXG4gICAgICB0aGlzLmFuaW1hdGVTdGF0ZSA9ICd2b2lkJztcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgYm9keVNjcm9sbEJsb2NrKHRvZ2dsZTogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuYm9keVNjcm9sbGFibGUgfHwgIXRoaXMuZG9jdW1lbnRPdmVyRmxvdykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAodG9nZ2xlKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdkZXZ1aS1ib2R5LXNjcm9sbGJsb2NrLW1vZGFsJyk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICd0b3AnLCBgLSR7dGhpcy5zY3JvbGxUb3B9cHhgKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJ2xlZnQnLCBgLSR7dGhpcy5zY3JvbGxMZWZ0fXB4YCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnZGV2dWktYm9keS1zY3JvbGxibG9jay1tb2RhbCcpO1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAndG9wJyk7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlU3R5bGUodGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdsZWZ0Jyk7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgPSB0aGlzLnNjcm9sbExlZnQ7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsVG9wO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVzb2x2ZVRyYW5zZm9ybVRyYW5zbGF0ZSgpIHtcclxuICAgIGxldCBhdXRvT2Zmc2V0WUJ5UGxhY2VtZW50O1xyXG4gICAgc3dpdGNoICh0aGlzLnBsYWNlbWVudCkge1xyXG4gICAgY2FzZSAndG9wJzpcclxuICAgICAgYXV0b09mZnNldFlCeVBsYWNlbWVudCA9ICc0MHB4JztcclxuICAgICAgYnJlYWs7XHJcbiAgICBjYXNlICdib3R0b20nOlxyXG4gICAgICBhdXRvT2Zmc2V0WUJ5UGxhY2VtZW50ID0gJy00MHB4JztcclxuICAgICAgYnJlYWs7XHJcbiAgICBjYXNlICdjZW50ZXInOlxyXG4gICAgZGVmYXVsdDpcclxuICAgICAgYXV0b09mZnNldFlCeVBsYWNlbWVudCA9IDA7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMucGxhY2VtZW50ICE9PSAndW5zZXQnKSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSB0aGlzLm9mZnNldFggPyB0aGlzLm9mZnNldFggOiAnMCc7XHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSB0aGlzLm9mZnNldFkgPyB0aGlzLm9mZnNldFkgOiBhdXRvT2Zmc2V0WUJ5UGxhY2VtZW50O1xyXG4gICAgICByZXR1cm4gJ3RyYW5zbGF0ZSgnICsgb2Zmc2V0WCArICcsJyArIG9mZnNldFkgKyAnKSc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gJ3Vuc2V0JztcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cIm1vZGFsLWJhY2tkcm9wXCIgW25nU3R5bGVdPVwieyAnei1pbmRleCc6IGJhY2tEcm9wWkluZGV4IH1cIiBbQGJhY2tkcm9wQW5pbWF0aW9uXT1cImFuaW1hdGVTdGF0ZVwiPjwvZGl2PlxuPGRpdlxuICBjbGFzcz1cIm1vZGFsIGluXCJcbiAgW25nQ2xhc3NdPVwiY3NzQ2xhc3NcIlxuICBbbmdTdHlsZV09XCJ7ICd6LWluZGV4JzogekluZGV4IH1cIlxuICBbYXR0ci5pZF09XCJpZFwiXG4gIChtb3VzZWRvd24pPVwibW9kYWxNb3VzZURvd24oJGV2ZW50KVwiXG4gIChtb3VzZXVwKT1cIm1vZGFsTW91c2VVcCgkZXZlbnQpXCJcbiAgKGNsaWNrKT1cIm9uTW9kYWxDbGljaygkZXZlbnQpXCJcbj5cbiAgPGRpdlxuICAgIGNsYXNzPVwibW9kYWwtZGlhbG9nXCJcbiAgICBbbmdDbGFzc109XCJ7XG4gICAgICAncGxhY2UtYXQtdG9wJzogcGxhY2VtZW50ID09PSAndG9wJyxcbiAgICAgICdwbGFjZS1hdC1ib3R0b20nOiBwbGFjZW1lbnQgPT09ICdib3R0b20nLFxuICAgICAgJ3BsYWNlLWF0LWNlbnRlcic6IHBsYWNlbWVudCA9PT0gJ2NlbnRlcicgfHwgcGxhY2VtZW50ID09PSAndW5zZXQnXG4gICAgfVwiXG4gICAgW25nU3R5bGVdPVwieyB3aWR0aDogd2lkdGggfVwiXG4gICAgW0B3aXBlSW5PdXRBbmltYXRpb25dPVwiYW5pbWF0ZVN0YXRlXCJcbiAgICAoQHdpcGVJbk91dEFuaW1hdGlvbi5kb25lKT1cIm9uQW5pbWF0aW9uRW5kKCRldmVudClcIlxuICAgIFtALmRpc2FibGVkXT1cIiFzaG93QW5pbWF0aW9uXCJcbiAgICB0YWJpbmRleD1cIjFcIlxuICAgICNkaWFsb2dcbiAgPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwibW9kYWwtY29udGVudFwiXG4gICAgICBbY2xhc3MubWF4aW1pemVdPVwibWF4aW1pemVkXCJcbiAgICAgIFtkTW92YWJsZV09XCJkcmFnZ2FibGVcIlxuICAgICAgW2hhbmRsZV09XCJkcmFnZ2FibGVIYW5kbGVFbFwiXG4gICAgICBbbmdTdHlsZV09XCJ7IHRyYW5zZm9ybTogcmVzb2x2ZVRyYW5zZm9ybVRyYW5zbGF0ZSgpIH1cIlxuICAgID5cbiAgICAgIDxuZy10ZW1wbGF0ZSBkTW9kYWxDb250YWluZXJIb3N0PjwvbmctdGVtcGxhdGU+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudFRlbXBsYXRlXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50VGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBtb2RhbEluc3RhbmNlOiB0aGlzIH1cIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=