UNPKG

ng-cw-v12

Version:

Angular UI Component Library

326 lines 54.9 kB
import { Component, Input, ChangeDetectionStrategy, ContentChildren, Output, EventEmitter } from '@angular/core'; import { SplitterPanelComponent } from './splitter-panel.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class SplitterComponent { constructor(cdr, el) { this.cdr = cdr; this.el = el; /** 布局方向 */ this.ncLayout = 'horizontal'; /** 分割线大小 */ this.ncGutterSize = 2; /** 分割线热区大小(可点击区域),默认为分割线大小的3倍 */ this.ncGutterHitSize = this.ncGutterSize * 3; /** 分割线颜色 */ this.ncGutterColor = 'rgba(0, 0, 0, 0.04)'; /** 分割线悬停颜色 */ this.ncGutterHoverColor = 'rgb(230, 244, 255)'; /** 分割线移动颜色 */ this.ncGutterMoveColor = 'rgb(186, 224, 255)'; /** 分割线图标颜色 */ this.ncGutterIconColor = 'rgba(0, 0, 0, 0.15)'; /** 延迟渲染模式 */ this._lazy = false; /** 分割线移动事件 */ this.ncResize = new EventEmitter(); /** 分割线开始移动事件 */ this.ncResizeStart = new EventEmitter(); /** 分割线结束移动事件 */ this.ncResizeEnd = new EventEmitter(); this.panels = []; this.isResizing = false; this.resizingIndex = -1; this.startPosition = 0; this.startSizes = []; this.curGutterDom = null; // 懒加载模式相关属性 this.lazySizes = []; // 懒加载模式下计算的临时尺寸 this.lazyOffset = 0; // 分割线的偏移量 this.previewLine = null; // 预览线元素 this.onMouseMove = (event) => { this.handleMove(event, 'mouse'); }; this.onTouchMove = (event) => { // 防止页面滚动 event.preventDefault(); this.handleMove(event, 'touch'); }; this.onMouseUp = (event) => { this.endResize(event, 'mouse'); }; this.onTouchEnd = (event) => { this.endResize(event, 'touch'); }; } set ncLazy(val) { this._lazy = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncLazy() { return this._lazy; } ngAfterViewInit() { this.panels = this.panelComponents.toArray(); this.normalizeSizes(); this.cdr.detectChanges(); } normalizeSizes() { // 计算已设置尺寸的面板总和 const configuredPanels = this.panels.filter(panel => panel.ncPanelSize); const configuredSize = configuredPanels.reduce((sum, panel) => sum + panel.ncPanelSize, 0); // 计算未设置尺寸的面板数量 const unconfiguredCount = this.panels.length - configuredPanels.length; // 为未设置尺寸的面板平均分配剩余空间 const remainingSize = 100 - configuredSize; const defaultSize = unconfiguredCount > 0 ? remainingSize / unconfiguredCount : 0; // 设置每个面板的最终尺寸 this.panels.forEach(panel => { if (!panel.ncPanelSize) { panel.ncPanelSize = defaultSize; } }); // 若面板的最小尺寸大于面板的尺寸,则将面板的尺寸设置为最小尺寸,即无法再缩小 this.panels.forEach(panel => { if (panel.ncMinSize && panel.ncMinSize > panel.ncPanelSize) { panel.ncMinSize = panel.ncPanelSize; } }); } onMouseDown(event, index) { this.startResize(event, index, 'mouse'); } onTouchStart(event, index) { // 防止默认的滚动行为 event.preventDefault(); this.startResize(event, index, 'touch'); } startResize(event, index, type) { event.preventDefault(); // 防止默认行为 this.curGutterDom = event.target; this.curGutterDom.style.backgroundColor = this.ncGutterMoveColor; this.isResizing = true; this.resizingIndex = index; // 获取初始位置(兼容鼠标和触摸事件) const clientX = type === 'mouse' ? event.clientX : event.touches[0].clientX; const clientY = type === 'mouse' ? event.clientY : event.touches[0].clientY; this.startPosition = this.ncLayout === 'horizontal' ? clientX : clientY; this.startSizes = this.panels.map(panel => panel.ncPanelSize || 0); // 禁用文本选择 document.body.style.userSelect = 'none'; document.body.style.webkitUserSelect = 'none'; // 设置鼠标指针样式(仅对鼠标事件有效) if (type === 'mouse') { document.body.style.cursor = this.ncLayout === 'horizontal' ? 'col-resize' : 'row-resize'; } // 对于触摸事件,防止页面滚动和缩放 if (type === 'touch') { // 禁用触摸滚动 document.body.style.overflow = 'hidden'; document.body.style.touchAction = 'none'; } // 添加对应的事件监听器 if (type === 'mouse') { document.addEventListener('mousemove', this.onMouseMove); document.addEventListener('mouseup', this.onMouseUp); } else { document.addEventListener('touchmove', this.onTouchMove, { passive: false }); document.addEventListener('touchend', this.onTouchEnd); document.addEventListener('touchcancel', this.onTouchEnd); } this.ncResizeStart.emit({ gutterIndex: index, sizes: this.panels.map(panel => panel.ncPanelSize || 0), mouseEvent: event, containerSize: [this.el.nativeElement.offsetWidth, this.el.nativeElement.offsetHeight] }); } handleMove(event, type) { if (!this.isResizing) return; // 获取当前位置(兼容鼠标和触摸事件) const clientX = type === 'mouse' ? event.clientX : event.touches[0].clientX; const clientY = type === 'mouse' ? event.clientY : event.touches[0].clientY; const currentPosition = this.ncLayout === 'horizontal' ? clientX : clientY; let delta = ((currentPosition - this.startPosition) / this.getContainerSize()) * 100; const newSizes = [...this.startSizes]; const leftPanelMinSize = this.panels[this.resizingIndex].ncMinSize || 0; const rightPanelMinSize = this.panels[this.resizingIndex + 1].ncMinSize || 0; // 计算实际可移动的范围,限制delta //左面板最多能扩展多少(受右面板最小尺寸限制) const maxLeftExpansion = this.startSizes[this.resizingIndex + 1] - rightPanelMinSize; //右面板最多能扩展多少(受左面板最小尺寸限制) const maxRightExpansion = this.startSizes[this.resizingIndex] - leftPanelMinSize; // 限制delta在有效范围内 if (delta > maxLeftExpansion) { //如果delta > maxLeftExpansion,说明左面板想要扩展得太多,会导致右面板小于最小尺寸,所以限制delta = maxLeftExpansion delta = maxLeftExpansion; } else if (delta < -maxRightExpansion) { //如果delta < -maxRightExpansion,说明右面板想要扩展得太多,会导致左面板小于最小尺寸,所以限制delta = -maxRightExpansion delta = -maxRightExpansion; } newSizes[this.resizingIndex] = this.startSizes[this.resizingIndex] + delta; newSizes[this.resizingIndex + 1] = this.startSizes[this.resizingIndex + 1] - delta; if (this.ncLazy) { // 懒加载模式:显示预览线,不改变面板尺寸 this.lazySizes = [...newSizes]; this.lazyOffset = (delta / 100) * this.getContainerSize(); // 创建或更新预览线 if (!this.previewLine) { this.previewLine = this.createPreviewLine(); this.el.nativeElement.appendChild(this.previewLine); } // 计算预览线的位置 const gutterRect = this.curGutterDom.getBoundingClientRect(); const containerRect = this.el.nativeElement.getBoundingClientRect(); if (this.ncLayout === 'horizontal') { const originalLeft = gutterRect.left - containerRect.left; this.previewLine.style.left = `${originalLeft + this.lazyOffset}px`; } else { const originalTop = gutterRect.top - containerRect.top; this.previewLine.style.top = `${originalTop + this.lazyOffset}px`; } } else { // 正常模式:实时更新面板尺寸 const totalSize = newSizes.reduce((sum, size) => sum + size, 0); this.panels.forEach((panel, i) => panel.ncPanelSize = (newSizes[i] / totalSize) * 100); this.cdr.detectChanges(); } this.ncResize.emit({ gutterIndex: this.resizingIndex, sizes: this.ncLazy ? this.lazySizes : this.panels.map(panel => panel.ncPanelSize || 0), delta: delta, mouseEvent: event, containerSize: [this.el.nativeElement.offsetWidth, this.el.nativeElement.offsetHeight] }); } endResize(event, type) { if (this.curGutterDom) { this.curGutterDom.style.backgroundColor = ''; // 清空内联样式,让CSS样式生效 if (this.ncLazy) { // 懒加载模式:移除预览线,应用最终面板尺寸 this.removePreviewLine(); if (this.lazySizes.length > 0) { const totalSize = this.lazySizes.reduce((sum, size) => sum + size, 0); this.panels.forEach((panel, i) => panel.ncPanelSize = (this.lazySizes[i] / totalSize) * 100); this.cdr.detectChanges(); } // 清空懒加载状态 this.lazySizes = []; this.lazyOffset = 0; } } // 恢复文本选择和鼠标指针 document.body.style.userSelect = ''; document.body.style.webkitUserSelect = ''; document.body.style.cursor = ''; // 对于触摸事件,恢复页面滚动和缩放 if (type === 'touch') { document.body.style.overflow = ''; document.body.style.touchAction = ''; } this.isResizing = false; // 移除对应的事件监听器 if (type === 'mouse') { document.removeEventListener('mousemove', this.onMouseMove); document.removeEventListener('mouseup', this.onMouseUp); } else { document.removeEventListener('touchmove', this.onTouchMove); document.removeEventListener('touchend', this.onTouchEnd); document.removeEventListener('touchcancel', this.onTouchEnd); } this.ncResizeEnd.emit({ gutterIndex: this.resizingIndex, sizes: this.panels.map(panel => panel.ncPanelSize || 0), mouseEvent: event, containerSize: [this.el.nativeElement.offsetWidth, this.el.nativeElement.offsetHeight] }); } getContainerSize() { return this.ncLayout === 'horizontal' ? this.el.nativeElement.offsetWidth : this.el.nativeElement.offsetHeight; } // 创建预览线 createPreviewLine() { const previewLine = document.createElement('div'); previewLine.className = `nc-splitter-preview-line nc-splitter-preview-line-${this.ncLayout}`; previewLine.style.position = 'absolute'; previewLine.style.backgroundColor = this.ncGutterHoverColor; previewLine.style.pointerEvents = 'none'; previewLine.style.zIndex = '1000'; if (this.ncLayout === 'horizontal') { previewLine.style.width = `${this.ncGutterSize}px`; previewLine.style.height = '100%'; previewLine.style.top = '0'; } else { previewLine.style.height = `${this.ncGutterSize}px`; previewLine.style.width = '100%'; previewLine.style.left = '0'; } return previewLine; } // 移除预览线 removePreviewLine() { if (this.previewLine && this.previewLine.parentNode) { this.previewLine.parentNode.removeChild(this.previewLine); this.previewLine = null; } } ngOnDestroy() { // 清理预览线 this.removePreviewLine(); // 清理所有事件监听器 document.removeEventListener('mousemove', this.onMouseMove); document.removeEventListener('mouseup', this.onMouseUp); document.removeEventListener('touchmove', this.onTouchMove); document.removeEventListener('touchend', this.onTouchEnd); document.removeEventListener('touchcancel', this.onTouchEnd); // 恢复所有样式 document.body.style.userSelect = ''; document.body.style.webkitUserSelect = ''; document.body.style.cursor = ''; document.body.style.overflow = ''; document.body.style.touchAction = ''; } } SplitterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SplitterComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); SplitterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: SplitterComponent, selector: "nc-splitter", inputs: { ncLayout: "ncLayout", ncGutterSize: "ncGutterSize", ncGutterHitSize: "ncGutterHitSize", ncGutterColor: "ncGutterColor", ncGutterHoverColor: "ncGutterHoverColor", ncGutterMoveColor: "ncGutterMoveColor", ncGutterIconColor: "ncGutterIconColor", ncLazy: "ncLazy" }, outputs: { ncResize: "ncResize", ncResizeStart: "ncResizeStart", ncResizeEnd: "ncResizeEnd" }, queries: [{ propertyName: "panelComponents", predicate: SplitterPanelComponent }], ngImport: i0, template: "<div class=\"nc-splitter\" [ngClass]=\"'nc-splitter-' + ncLayout\" style=\"--ncGutterSize: {{ncGutterSize + 'px'}};\r\n --ncGutterColor: {{ncGutterColor}};\r\n --ncGutterHoverColor: {{ncGutterHoverColor}};\r\n --ncGutterIconColor: {{ncGutterIconColor}};\r\n --ncGutterHitSize: {{ncGutterHitSize + 'px'}};\">\r\n <ng-container *ngFor=\"let panel of panels; let i = index; let last = last\">\r\n <div class=\"panel\" [style.flexBasis.%]=\"panel.ncPanelSize\">\r\n <ng-container *ngTemplateOutlet=\"panel.contentTemplate\"></ng-container>\r\n </div>\r\n <div *ngIf=\"!last\" class=\"nc-splitter-gutter\" [ngClass]=\"'nc-splitter-gutter-' + ncLayout\"\r\n (mousedown)=\"onMouseDown($event, i)\" (touchstart)=\"onTouchStart($event, i)\"></div>\r\n </ng-container>\r\n</div>", styles: [":host{width:100%;height:100%}.nc-splitter{display:flex;width:100%;height:100%;overflow:hidden}.nc-splitter .panel{flex:1 1 auto;overflow:auto;display:flex}.nc-splitter .nc-splitter-gutter{background:var(--ncGutterColor);flex:0 0 var(--ncGutterSize);position:relative;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.nc-splitter .nc-splitter-gutter:hover{background:var(--ncGutterHoverColor)}.nc-splitter .nc-splitter-gutter:before{content:\"\";position:absolute;z-index:1}.nc-splitter .nc-splitter-gutter:after{position:absolute;content:\"\";background:var(--ncGutterIconColor);z-index:2;top:50%;left:50%;transform:translate(-50%,-50%)}.nc-splitter .nc-splitter-gutter-horizontal{cursor:col-resize}.nc-splitter .nc-splitter-gutter-horizontal:before{top:0;left:50%;width:var(--ncGutterHitSize);height:100%;transform:translate(-50%)}.nc-splitter .nc-splitter-gutter-horizontal:after{width:var(--ncGutterSize);height:20px}.nc-splitter .nc-splitter-gutter-vertical{cursor:row-resize}.nc-splitter .nc-splitter-gutter-vertical:before{top:50%;left:0;width:100%;height:var(--ncGutterHitSize);transform:translateY(-50%)}.nc-splitter .nc-splitter-gutter-vertical:after{width:20px;height:var(--ncGutterSize)}.nc-splitter-horizontal{flex-direction:row}.nc-splitter-vertical{flex-direction:column}.nc-splitter-preview-line{position:absolute;pointer-events:none;z-index:1000;opacity:.8;transition:opacity .1s ease}.nc-splitter-preview-line.nc-splitter-preview-line-horizontal{cursor:col-resize}.nc-splitter-preview-line.nc-splitter-preview-line-vertical{cursor:row-resize}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SplitterComponent, decorators: [{ type: Component, args: [{ selector: 'nc-splitter', templateUrl: './splitter.component.html', styleUrls: ['./splitter.component.less'], changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { ncLayout: [{ type: Input }], ncGutterSize: [{ type: Input }], ncGutterHitSize: [{ type: Input }], ncGutterColor: [{ type: Input }], ncGutterHoverColor: [{ type: Input }], ncGutterMoveColor: [{ type: Input }], ncGutterIconColor: [{ type: Input }], ncLazy: [{ type: Input }], panelComponents: [{ type: ContentChildren, args: [SplitterPanelComponent] }], ncResize: [{ type: Output }], ncResizeStart: [{ type: Output }], ncResizeEnd: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BsaXR0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcGxpdHRlci9zcGxpdHRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NwbGl0dGVyL3NwbGl0dGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFhLHVCQUF1QixFQUFnRCxlQUFlLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUNyTCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7O0FBa0JwRSxNQUFNLE9BQU8saUJBQWlCO0lBNkM1QixZQUFvQixHQUFzQixFQUFVLEVBQWM7UUFBOUMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBNUNsRSxXQUFXO1FBQ0YsYUFBUSxHQUFpQixZQUFZLENBQUM7UUFDL0MsWUFBWTtRQUNILGlCQUFZLEdBQVcsQ0FBQyxDQUFDO1FBQ2xDLGlDQUFpQztRQUN4QixvQkFBZSxHQUFXLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ3pELFlBQVk7UUFDSCxrQkFBYSxHQUFXLHFCQUFxQixDQUFDO1FBQ3ZELGNBQWM7UUFDTCx1QkFBa0IsR0FBVyxvQkFBb0IsQ0FBQztRQUMzRCxjQUFjO1FBQ0wsc0JBQWlCLEdBQVcsb0JBQW9CLENBQUM7UUFDMUQsY0FBYztRQUNMLHNCQUFpQixHQUFXLHFCQUFxQixDQUFDO1FBQzNELGFBQWE7UUFDTCxVQUFLLEdBQVksS0FBSyxDQUFDO1FBVS9CLGNBQWM7UUFDSixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQXlCLENBQUM7UUFDL0QsZ0JBQWdCO1FBQ04sa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBeUIsQ0FBQztR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LENBQUMsMkJBQTJCLENBQUM7b0JBQ3hDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2lCQUNoRDtpSUFHVSxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFFRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBRUcsaUJBQWlCO3NCQUF6QixLQUFLO2dCQUlGLE1BQU07c0JBRFQsS0FBSztnQkFRbUMsZUFBZTtzQkFBdkQsZUFBZTt1QkFBQyxzQkFBc0I7Z0JBRTdCLFFBQVE7c0JBQWpCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgUXVlcnlMaXN0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIEVsZW1lbnRSZWYsIEFmdGVyVmlld0luaXQsIENvbnRlbnRDaGlsZHJlbiwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTcGxpdHRlclBhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGxpdHRlci1wYW5lbC5jb21wb25lbnQnO1xyXG5cclxuZXhwb3J0IHR5cGUgTmNMYXlvdXRUeXBlID0gJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmNTcGxpdHRlclJlc2l6ZUV2ZW50IHtcclxuICBndXR0ZXJJbmRleDogbnVtYmVyO1xyXG4gIHNpemVzOiBudW1iZXJbXTtcclxuICBkZWx0YT86IG51bWJlcjtcclxuICBtb3VzZUV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudDtcclxuICBjb250YWluZXJTaXplOiBbbnVtYmVyLCBudW1iZXJdO1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25jLXNwbGl0dGVyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vc3BsaXR0ZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3NwbGl0dGVyLmNvbXBvbmVudC5sZXNzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcclxufSlcclxuZXhwb3J0IGNsYXNzIFNwbGl0dGVyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICAvKiog5biD5bGA5pa55ZCRICovXHJcbiAgQElucHV0KCkgbmNMYXlvdXQ6IE5jTGF5b3V0VHlwZSA9ICdob3Jpem9udGFsJztcclxuICAvKiog5YiG5Ymy57q/5aSn5bCPICovXHJcbiAgQElucHV0KCkgbmNHdXR0ZXJTaXplOiBudW1iZXIgPSAyO1xyXG4gIC8qKiDliIblibLnur/ng63ljLrlpKflsI/vvIjlj6/ngrnlh7vljLrln5/vvInvvIzpu5jorqTkuLrliIblibLnur/lpKflsI/nmoQz5YCNICovXHJcbiAgQElucHV0KCkgbmNHdXR0ZXJIaXRTaXplOiBudW1iZXIgPSB0aGlzLm5jR3V0dGVyU2l6ZSAqIDM7XHJcbiAgLyoqIOWIhuWJsue6v+minOiJsiAqL1xyXG4gIEBJbnB1dCgpIG5jR3V0dGVyQ29sb3I6IHN0cmluZyA9ICdyZ2JhKDAsIDAsIDAsIDAuMDQpJztcclxuICAvKiog5YiG5Ymy57q/5oKs5YGc6aKc6ImyICovXHJcbiAgQElucHV0KCkgbmNHdXR0ZXJIb3ZlckNvbG9yOiBzdHJpbmcgPSAncmdiKDIzMCwgMjQ0LCAyNTUpJztcclxuICAvKiog5YiG5Ymy57q/56e75Yqo6aKc6ImyICovXHJcbiAgQElucHV0KCkgbmNHdXR0ZXJNb3ZlQ29sb3I6IHN0cmluZyA9ICdyZ2IoMTg2LCAyMjQsIDI1NSknO1xyXG4gIC8qKiDliIblibLnur/lm77moIfpopzoibIgKi9cclxuICBASW5wdXQoKSBuY0d1dHRlckljb25Db2xvcjogc3RyaW5nID0gJ3JnYmEoMCwgMCwgMCwgMC4xNSknO1xyXG4gIC8qKiDlu7bov5/muLLmn5PmqKHlvI8gKi9cclxuICBwcml2YXRlIF9sYXp5OiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KClcclxuICBzZXQgbmNMYXp5KHZhbDogYm9vbGVhbiB8IHN0cmluZykge1xyXG4gICAgdGhpcy5fbGF6eSA9IHZhbCAhPT0gbnVsbCAmJiB2YWwgIT09IHVuZGVmaW5lZCAmJiB2YWwgIT09IGZhbHNlICYmIHZhbCAhPT0gJ2ZhbHNlJztcclxuICB9XHJcbiAgZ2V0IG5jTGF6eSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9sYXp5O1xyXG4gIH1cclxuICAvKiog6Z2i5p2/57uE5Lu2ICovXHJcbiAgQENvbnRlbnRDaGlsZHJlbihTcGxpdHRlclBhbmVsQ29tcG9uZW50KSBwYW5lbENvbXBvbmVudHMhOiBRdWVyeUxpc3Q8U3BsaXR0ZXJQYW5lbENvbXBvbmVudD47XHJcbiAgLyoqIOWIhuWJsue6v+enu+WKqOS6i+S7tiAqL1xyXG4gIEBPdXRwdXQoKSBuY1Jlc2l6ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TmNTcGxpdHRlclJlc2l6ZUV2ZW50PigpO1xyXG4gIC8qKiDliIblibLnur/lvIDlp4vnp7vliqjkuovku7YgKi9cclxuICBAT3V0cHV0KCkgbmNSZXNpemVTdGFydCA9IG5ldyBFdmVudEVtaXR0ZXI8TmNTcGxpdHRlclJlc2l6ZUV2ZW50PigpO1xyXG4gIC8qKiDliIblibLnur/nu5PmnZ/np7vliqjkuovku7YgKi9cclxuICBAT3V0cHV0KCkgbmNSZXNpemVFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPE5jU3BsaXR0ZXJSZXNpemVFdmVudD4oKTtcclxuXHJcbiAgcGFuZWxzOiBTcGxpdHRlclBhbmVsQ29tcG9uZW50W10gPSBbXTtcclxuICBpc1Jlc2l6aW5nID0gZmFsc2U7XHJcbiAgcmVzaXppbmdJbmRleCA9IC0xO1xyXG4gIHN0YXJ0UG9zaXRpb24gPSAwO1xyXG4gIHN0YXJ0U2l6ZXM6IG51bWJlcltdID0gW107XHJcbiAgY3VyR3V0dGVyRG9tOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyDmh5LliqDovb3mqKHlvI/nm7jlhbPlsZ7mgKdcclxuICBsYXp5U2l6ZXM6IG51bWJlcltdID0gW107ICAvLyDmh5LliqDovb3mqKHlvI/kuIvorqHnrpfnmoTkuLTml7blsLrlr7hcclxuICBsYXp5T2Zmc2V0ID0gMDsgIC8vIOWIhuWJsue6v+eahOWBj+enu+mHj1xyXG4gIHByZXZpZXdMaW5lOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsOyAgLy8g6aKE6KeI57q/5YWD57SgXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHJpdmF0ZSBlbDogRWxlbWVudFJlZikgeyB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMucGFuZWxzID0gdGhpcy5wYW5lbENvbXBvbmVudHMudG9BcnJheSgpO1xyXG4gICAgdGhpcy5ub3JtYWxpemVTaXplcygpO1xyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgbm9ybWFsaXplU2l6ZXMoKSB7XHJcbiAgICAvLyDorqHnrpflt7Lorr7nva7lsLrlr7jnmoTpnaLmnb/mgLvlkoxcclxuICAgIGNvbnN0IGNvbmZpZ3VyZWRQYW5lbHMgPSB0aGlzLnBhbmVscy5maWx0ZXIocGFuZWwgPT4gcGFuZWwubmNQYW5lbFNpemUpO1xyXG4gICAgY29uc3QgY29uZmlndXJlZFNpemUgPSBjb25maWd1cmVkUGFuZWxzLnJlZHVjZSgoc3VtLCBwYW5lbCkgPT4gc3VtICsgcGFuZWwubmNQYW5lbFNpemUhLCAwKTtcclxuXHJcbiAgICAvLyDorqHnrpfmnKrorr7nva7lsLrlr7jnmoTpnaLmnb/mlbDph49cclxuICAgIGNvbnN0IHVuY29uZmlndXJlZENvdW50ID0gdGhpcy5wYW5lbHMubGVuZ3RoIC0gY29uZmlndXJlZFBhbmVscy5sZW5ndGg7XHJcblxyXG4gICAgLy8g5Li65pyq6K6+572u5bC65a+455qE6Z2i5p2/5bmz5Z2H5YiG6YWN5Ymp5L2Z56m66Ze0XHJcbiAgICBjb25zdCByZW1haW5pbmdTaXplID0gMTAwIC0gY29uZmlndXJlZFNpemU7XHJcbiAgICBjb25zdCBkZWZhdWx0U2l6ZSA9IHVuY29uZmlndXJlZENvdW50ID4gMCA/IHJlbWFpbmluZ1NpemUgLyB1bmNvbmZpZ3VyZWRDb3VudCA6IDA7XHJcblxyXG4gICAgLy8g6K6+572u5q+P5Liq6Z2i5p2/55qE5pyA57uI5bC65a+4XHJcbiAgICB0aGlzLnBhbmVscy5mb3JFYWNoKHBhbmVsID0+IHtcclxuICAgICAgaWYgKCFwYW5lbC5uY1BhbmVsU2l6ZSkge1xyXG4gICAgICAgIHBhbmVsLm5jUGFuZWxTaXplID0gZGVmYXVsdFNpemU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIOiLpemdouadv+eahOacgOWwj+WwuuWvuOWkp+S6jumdouadv+eahOWwuuWvuO+8jOWImeWwhumdouadv+eahOWwuuWvuOiuvue9ruS4uuacgOWwj+WwuuWvuO+8jOWNs+aXoOazleWGjee8qeWwj1xyXG4gICAgdGhpcy5wYW5lbHMuZm9yRWFjaChwYW5lbCA9PiB7XHJcbiAgICAgIGlmIChwYW5lbC5uY01pblNpemUgJiYgcGFuZWwubmNNaW5TaXplID4gcGFuZWwubmNQYW5lbFNpemUhKSB7XHJcbiAgICAgICAgcGFuZWwubmNNaW5TaXplID0gcGFuZWwubmNQYW5lbFNpemUhO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50LCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnN0YXJ0UmVzaXplKGV2ZW50LCBpbmRleCwgJ21vdXNlJyk7XHJcbiAgfVxyXG5cclxuICBvblRvdWNoU3RhcnQoZXZlbnQ6IFRvdWNoRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcclxuICAgIC8vIOmYsuatoum7mOiupOeahOa7muWKqOihjOS4ulxyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIHRoaXMuc3RhcnRSZXNpemUoZXZlbnQsIGluZGV4LCAndG91Y2gnKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3RhcnRSZXNpemUoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50LCBpbmRleDogbnVtYmVyLCB0eXBlOiAnbW91c2UnIHwgJ3RvdWNoJykge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8g6Ziy5q2i6buY6K6k6KGM5Li6XHJcbiAgICB0aGlzLmN1ckd1dHRlckRvbSA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgIHRoaXMuY3VyR3V0dGVyRG9tLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMubmNHdXR0ZXJNb3ZlQ29sb3I7XHJcbiAgICB0aGlzLmlzUmVzaXppbmcgPSB0cnVlO1xyXG4gICAgdGhpcy5yZXNpemluZ0luZGV4ID0gaW5kZXg7XHJcblxyXG4gICAgLy8g6I635Y+W5Yid5aeL5L2N572u77yI5YW85a656byg5qCH5ZKM6Kem5pG45LqL5Lu277yJXHJcbiAgICBjb25zdCBjbGllbnRYID0gdHlwZSA9PT0gJ21vdXNlJyA/IChldmVudCBhcyBNb3VzZUV2ZW50KS5jbGllbnRYIDogKGV2ZW50IGFzIFRvdWNoRXZlbnQpLnRvdWNoZXNbMF0uY2xpZW50WDtcclxuICAgIGNvbnN0IGNsaWVudFkgPSB0eXBlID09PSAnbW91c2UnID8gKGV2ZW50IGFzIE1vdXNlRXZlbnQpLmNsaWVudFkgOiAoZXZlbnQgYXMgVG91Y2hFdmVudCkudG91Y2hlc1swXS5jbGllbnRZO1xyXG4gICAgdGhpcy5zdGFydFBvc2l0aW9uID0gdGhpcy5uY0xheW91dCA9PT0gJ2hvcml6b250YWwnID8gY2xpZW50WCA6IGNsaWVudFk7XHJcbiAgICB0aGlzLnN0YXJ0U2l6ZXMgPSB0aGlzLnBhbmVscy5tYXAocGFuZWwgPT4gcGFuZWwubmNQYW5lbFNpemUgfHwgMCk7XHJcblxyXG4gICAgLy8g56aB55So5paH5pys6YCJ5oupXHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnVzZXJTZWxlY3QgPSAnbm9uZSc7XHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLndlYmtpdFVzZXJTZWxlY3QgPSAnbm9uZSc7XHJcblxyXG4gICAgLy8g6K6+572u6byg5qCH5oyH6ZKI5qC35byP77yI5LuF5a+56byg5qCH5LqL5Lu25pyJ5pWI77yJXHJcbiAgICBpZiAodHlwZSA9PT0gJ21vdXNlJykge1xyXG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9IHRoaXMubmNMYXlvdXQgPT09ICdob3Jpem9udGFsJyA/ICdjb2wtcmVzaXplJyA6ICdyb3ctcmVzaXplJztcclxuICAgIH1cclxuXHJcbiAgICAvLyDlr7nkuo7op6bmkbjkuovku7bvvIzpmLLmraLpobXpnaLmu5rliqjlkoznvKnmlL5cclxuICAgIGlmICh0eXBlID09PSAndG91Y2gnKSB7XHJcbiAgICAgIC8vIOemgeeUqOinpuaRuOa7muWKqFxyXG4gICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XHJcbiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUudG91Y2hBY3Rpb24gPSAnbm9uZSc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5re75Yqg5a+55bqU55qE5LqL5Lu255uR5ZCs5ZmoXHJcbiAgICBpZiAodHlwZSA9PT0gJ21vdXNlJykge1xyXG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm9uTW91c2VNb3ZlKTtcclxuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZVVwKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMub25Ub3VjaE1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XHJcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoRW5kKTtcclxuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCB0aGlzLm9uVG91Y2hFbmQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubmNSZXNpemVTdGFydC5lbWl0KHtcclxuICAgICAgZ3V0dGVySW5kZXg6IGluZGV4LFxyXG4gICAgICBzaXplczogdGhpcy5wYW5lbHMubWFwKHBhbmVsID0+IHBhbmVsLm5jUGFuZWxTaXplIHx8IDApLFxyXG4gICAgICBtb3VzZUV2ZW50OiBldmVudCxcclxuICAgICAgY29udGFpbmVyU2l6ZTogW3RoaXMuZWwubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCwgdGhpcy5lbC5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodF1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25Nb3VzZU1vdmUgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcclxuICAgIHRoaXMuaGFuZGxlTW92ZShldmVudCwgJ21vdXNlJyk7XHJcbiAgfVxyXG5cclxuICBvblRvdWNoTW92ZSA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xyXG4gICAgLy8g6Ziy5q2i6aG16Z2i5rua5YqoXHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgdGhpcy5oYW5kbGVNb3ZlKGV2ZW50LCAndG91Y2gnKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlTW92ZShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIHR5cGU6ICdtb3VzZScgfCAndG91Y2gnKSB7XHJcbiAgICBpZiAoIXRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xyXG5cclxuICAgIC8vIOiOt+WPluW9k+WJjeS9jee9ru+8iOWFvOWuuem8oOagh+WSjOinpuaRuOS6i+S7tu+8iVxyXG4gICAgY29uc3QgY2xpZW50WCA9IHR5cGUgPT09ICdtb3VzZScgPyAoZXZlbnQgYXMgTW91c2VFdmVudCkuY2xpZW50WCA6IChldmVudCBhcyBUb3VjaEV2ZW50KS50b3VjaGVzWzBdLmNsaWVudFg7XHJcbiAgICBjb25zdCBjbGllbnRZID0gdHlwZSA9PT0gJ21vdXNlJyA/IChldmVudCBhcyBNb3VzZUV2ZW50KS5jbGllbnRZIDogKGV2ZW50IGFzIFRvdWNoRXZlbnQpLnRvdWNoZXNbMF0uY2xpZW50WTtcclxuICAgIGNvbnN0IGN1cnJlbnRQb3NpdGlvbiA9IHRoaXMubmNMYXlvdXQgPT09ICdob3Jpem9udGFsJyA/IGNsaWVudFggOiBjbGllbnRZO1xyXG4gICAgbGV0IGRlbHRhID0gKChjdXJyZW50UG9zaXRpb24gLSB0aGlzLnN0YXJ0UG9zaXRpb24pIC8gdGhpcy5nZXRDb250YWluZXJTaXplKCkpICogMTAwO1xyXG5cclxuICAgIGNvbnN0IG5ld1NpemVzID0gWy4uLnRoaXMuc3RhcnRTaXplc107XHJcbiAgICBjb25zdCBsZWZ0UGFuZWxNaW5TaXplID0gdGhpcy5wYW5lbHNbdGhpcy5yZXNpemluZ0luZGV4XS5uY01pblNpemUgfHwgMDtcclxuICAgIGNvbnN0IHJpZ2h0UGFuZWxNaW5TaXplID0gdGhpcy5wYW5lbHNbdGhpcy5yZXNpemluZ0luZGV4ICsgMV0ubmNNaW5TaXplIHx8IDA7XHJcblxyXG4gICAgLy8g6K6h566X5a6e6ZmF5Y+v56e75Yqo55qE6IyD5Zu077yM6ZmQ5Yi2ZGVsdGFcclxuICAgIC8v5bem6Z2i5p2/5pyA5aSa6IO95omp5bGV5aSa5bCR77yI5Y+X5Y+z6Z2i5p2/5pyA5bCP5bC65a+46ZmQ5Yi277yJXHJcbiAgICBjb25zdCBtYXhMZWZ0RXhwYW5zaW9uID0gdGhpcy5zdGFydFNpemVzW3RoaXMucmVzaXppbmdJbmRleCArIDFdIC0gcmlnaHRQYW5lbE1pblNpemU7XHJcbiAgICAvL+WPs+mdouadv+acgOWkmuiDveaJqeWxleWkmuWwke+8iOWPl+W3pumdouadv+acgOWwj+WwuuWvuOmZkOWItu+8iVxyXG4gICAgY29uc3QgbWF4UmlnaHRFeHBhbnNpb24gPSB0aGlzLnN0YXJ0U2l6ZXNbdGhpcy5yZXNpemluZ0luZGV4XSAtIGxlZnRQYW5lbE1pblNpemU7XHJcblxyXG4gICAgLy8g6ZmQ5Yi2ZGVsdGHlnKjmnInmlYjojIPlm7TlhoVcclxuICAgIGlmIChkZWx0YSA+IG1heExlZnRFeHBhbnNpb24pIHtcclxuICAgICAgLy/lpoLmnpxkZWx0YSA+IG1heExlZnRFeHBhbnNpb27vvIzor7TmmI7lt6bpnaLmnb/mg7PopoHmianlsZXlvpflpKrlpJrvvIzkvJrlr7zoh7Tlj7PpnaLmnb/lsI/kuo7mnIDlsI/lsLrlr7jvvIzmiYDku6XpmZDliLZkZWx0YSA9IG1heExlZnRFeHBhbnNpb25cclxuICAgICAgZGVsdGEgPSBtYXhMZWZ0RXhwYW5zaW9uO1xyXG4gICAgfSBlbHNlIGlmIChkZWx0YSA8IC1tYXhSaWdodEV4cGFuc2lvbikge1xyXG4gICAgICAvL+WmguaenGRlbHRhIDwgLW1heFJpZ2h0RXhwYW5zaW9u77yM6K+05piO5Y+z6Z2i5p2/5oOz6KaB5omp5bGV5b6X5aSq5aSa77yM5Lya5a+86Ie05bem6Z2i5p2/5bCP5LqO5pyA5bCP5bC65a+477yM5omA5Lul6ZmQ5Yi2ZGVsdGEgPSAtbWF4UmlnaHRFeHBhbnNpb25cclxuICAgICAgZGVsdGEgPSAtbWF4UmlnaHRFeHBhbnNpb247XHJcbiAgICB9XHJcblxyXG4gICAgbmV3U2l6ZXNbdGhpcy5yZXNpemluZ0luZGV4XSA9IHRoaXMuc3RhcnRTaXplc1t0aGlzLnJlc2l6aW5nSW5kZXhdICsgZGVsdGE7XHJcbiAgICBuZXdTaXplc1t0aGlzLnJlc2l6aW5nSW5kZXggKyAxXSA9IHRoaXMuc3RhcnRTaXplc1t0aGlzLnJlc2l6aW5nSW5kZXggKyAxXSAtIGRlbHRhO1xyXG5cclxuICAgIGlmICh0aGlzLm5jTGF6eSkge1xyXG4gICAgICAvLyDmh5LliqDovb3mqKHlvI/vvJrmmL7npLrpooTop4jnur/vvIzkuI3mlLnlj5jpnaLmnb/lsLrlr7hcclxuICAgICAgdGhpcy5sYXp5U2l6ZXMgPSBbLi4ubmV3U2l6ZXNdO1xyXG4gICAgICB0aGlzLmxhenlPZmZzZXQgPSAoZGVsdGEgLyAxMDApICogdGhpcy5nZXRDb250YWluZXJTaXplKCk7XHJcblxyXG4gICAgICAvLyDliJvlu7rmiJbmm7TmlrDpooTop4jnur9cclxuICAgICAgaWYgKCF0aGlzLnByZXZpZXdMaW5lKSB7XHJcbiAgICAgICAgdGhpcy5wcmV2aWV3TGluZSA9IHRoaXMuY3JlYXRlUHJldmlld0xpbmUoKTtcclxuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5wcmV2aWV3TGluZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIOiuoeeul+mihOiniOe6v+eahOS9jee9rlxyXG4gICAgICBjb25zdCBndXR0ZXJSZWN0ID0gdGhpcy5jdXJHdXR0ZXJEb20hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBjb25zdCBjb250YWluZXJSZWN0ID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgICAgaWYgKHRoaXMubmNMYXlvdXQgPT09ICdob3Jpem9udGFsJykge1xyXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsTGVmdCA9IGd1dHRlclJlY3QubGVmdCAtIGNvbnRhaW5lclJlY3QubGVmdDtcclxuICAgICAgICB0aGlzLnByZXZpZXdMaW5lLnN0eWxlLmxlZnQgPSBgJHtvcmlnaW5hbExlZnQgKyB0aGlzLmxhenlPZmZzZXR9cHhgO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsVG9wID0gZ3V0dGVyUmVjdC50b3AgLSBjb250YWluZXJSZWN0LnRvcDtcclxuICAgICAgICB0aGlzLnByZXZpZXdMaW5lLnN0eWxlLnRvcCA9IGAke29yaWdpbmFsVG9wICsgdGhpcy5sYXp5T2Zmc2V0fXB4YDtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8g5q2j5bi45qih5byP77ya5a6e5pe25pu05paw6Z2i5p2/5bC65a+4XHJcbiAgICAgIGNvbnN0IHRvdGFsU2l6ZSA9IG5ld1NpemVzLnJlZHVjZSgoc3VtLCBzaXplKSA9PiBzdW0gKyBzaXplLCAwKTtcclxuICAgICAgdGhpcy5wYW5lbHMuZm9yRWFjaCgocGFuZWwsIGkpID0+IHBhbmVsLm5jUGFuZWxTaXplID0gKG5ld1NpemVzW2ldIC8gdG90YWxTaXplKSAqIDEwMCk7XHJcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm5jUmVzaXplLmVtaXQoe1xyXG4gICAgICBndXR0ZXJJbmRleDogdGhpcy5yZXNpemluZ0luZGV4LFxyXG4gICAgICBzaXplczogdGhpcy5uY0xhenkgPyB0aGlzLmxhenlTaXplcyA6IHRoaXMucGFuZWxzLm1hcChwYW5lbCA9PiBwYW5lbC5uY1BhbmVsU2l6ZSB8fCAwKSxcclxuICAgICAgZGVsdGE6IGRlbHRhLFxyXG4gICAgICBtb3VzZUV2ZW50OiBldmVudCxcclxuICAgICAgY29udGFpbmVyU2l6ZTogW3RoaXMuZWwubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCwgdGhpcy5lbC5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodF1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25Nb3VzZVVwID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICB0aGlzLmVuZFJlc2l6ZShldmVudCwgJ21vdXNlJyk7XHJcbiAgfVxyXG5cclxuICBvblRvdWNoRW5kID0gKGV2ZW50OiBUb3VjaEV2ZW50KSA9PiB7XHJcbiAgICB0aGlzLmVuZFJlc2l6ZShldmVudCwgJ3RvdWNoJyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGVuZFJlc2l6ZShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQsIHR5cGU6ICdtb3VzZScgfCAndG91Y2gnKSB7XHJcbiAgICBpZiAodGhpcy5jdXJHdXR0ZXJEb20pIHtcclxuICAgICAgdGhpcy5jdXJHdXR0ZXJEb20uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gJyc7ICAvLyDmuIXnqbrlhoXogZTmoLflvI/vvIzorqlDU1PmoLflvI/nlJ/mlYhcclxuXHJcbiAgICAgIGlmICh0aGlzLm5jTGF6eSkge1xyXG4gICAgICAgIC8vIOaHkuWKoOi9veaooeW8j++8muenu+mZpOmihOiniOe6v++8jOW6lOeUqOacgOe7iOmdouadv+WwuuWvuFxyXG4gICAgICAgIHRoaXMucmVtb3ZlUHJldmlld0xpbmUoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMubGF6eVNpemVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGNvbnN0IHRvdGFsU2l6ZSA9IHRoaXMubGF6eVNpemVzLnJlZHVjZSgoc3VtLCBzaXplKSA9PiBzdW0gKyBzaXplLCAwKTtcclxuICAgICAgICAgIHRoaXMucGFuZWxzLmZvckVhY2goKHBhbmVsLCBpKSA9PiBwYW5lbC5uY1BhbmVsU2l6ZSA9ICh0aGlzLmxhenlTaXplc1tpXSAvIHRvdGFsU2l6ZSkgKiAxMDApO1xyXG4gICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8g5riF56m65oeS5Yqg6L2954q25oCBXHJcbiAgICAgICAgdGhpcy5sYXp5U2l6ZXMgPSBbXTtcclxuICAgICAgICB0aGlzLmxhenlPZmZzZXQgPSAwO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5oGi5aSN5paH5pys6YCJ5oup5ZKM6byg5qCH5oyH6ZKIXHJcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnVzZXJTZWxlY3QgPSAnJztcclxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUud2Via2l0VXNlclNlbGVjdCA9ICcnO1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnJztcclxuXHJcbiAgICAvLyDlr7nkuo7op6bmkbjkuovku7bvvIzmgaLlpI3pobXpnaLmu5rliqjlkoznvKnmlL5cclxuICAgIGlmICh0eXBlID09PSAndG91Y2gnKSB7XHJcbiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnJztcclxuICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS50b3VjaEFjdGlvbiA9ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIOenu+mZpOWvueW6lOeahOS6i+S7tuebkeWQrOWZqFxyXG4gICAgaWYgKHR5cGUgPT09ICdtb3VzZScpIHtcclxuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZSk7XHJcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlKTtcclxuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLm9uVG91Y2hFbmQpO1xyXG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMub25Ub3VjaEVuZCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5uY1Jlc2l6ZUVuZC5lbWl0KHtcclxuICAgICAgZ3V0dGVySW5kZXg6IHRoaXMucmVzaXppbmdJbmRleCxcclxuICAgICAgc2l6ZXM6IHRoaXMucGFuZWxzLm1hcChwYW5lbCA9PiBwYW5lbC5uY1BhbmVsU2l6ZSB8fCAwKSxcclxuICAgICAgbW91c2VFdmVudDogZXZlbnQsXHJcbiAgICAgIGNvbnRhaW5lclNpemU6IFt0aGlzLmVsLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGgsIHRoaXMuZWwubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHRdXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGdldENv