UNPKG

primeng

Version:

[![npm version](https://badge.fury.io/js/primeng.svg)](https://badge.fury.io/js/primeng) [![npm downloads](https://img.shields.io/npm/dm/primeng.svg)](https://www.npmjs.com/package/primeng) [![Actions CI](https://github.com/primefaces/primeng/workflows/No

495 lines 65.5 kB
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChildren, Inject, Input, NgModule, PLATFORM_ID, ViewChild, ViewEncapsulation } from '@angular/core'; import { PrimeTemplate } from 'primeng/api'; import { DomHandler } from 'primeng/dom'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * ScrollPanel is a cross browser, lightweight and themable alternative to native browser scrollbar. * @group Components */ class ScrollPanel { platformId; el; zone; cd; document; renderer; /** * Inline style of the component. * @group Props */ style; /** * Style class of the component. * @group Props */ styleClass; /** * Step factor to scroll the content while pressing the arrow keys. * @group Props */ step = 5; containerViewChild; contentViewChild; xBarViewChild; yBarViewChild; templates; scrollYRatio; scrollXRatio; timeoutFrame = (fn) => setTimeout(fn, 0); initialized = false; lastPageY; lastPageX; isXBarClicked = false; isYBarClicked = false; contentTemplate; lastScrollLeft = 0; lastScrollTop = 0; orientation = 'vertical'; timer; windowResizeListener; contentScrollListener; mouseEnterListener; xBarMouseDownListener; yBarMouseDownListener; documentMouseMoveListener; documentMouseUpListener; constructor(platformId, el, zone, cd, document, renderer) { this.platformId = platformId; this.el = el; this.zone = zone; this.cd = cd; this.document = document; this.renderer = renderer; } ngAfterViewInit() { if (isPlatformBrowser(this.platformId)) { this.zone.runOutsideAngular(() => { this.moveBar(); this.moveBar = this.moveBar.bind(this); this.onXBarMouseDown = this.onXBarMouseDown.bind(this); this.onYBarMouseDown = this.onYBarMouseDown.bind(this); this.onDocumentMouseMove = this.onDocumentMouseMove.bind(this); this.onDocumentMouseUp = this.onDocumentMouseUp.bind(this); this.windowResizeListener = this.renderer.listen(window, 'resize', this.moveBar); this.contentScrollListener = this.renderer.listen(this.contentViewChild.nativeElement, 'scroll', this.moveBar); this.mouseEnterListener = this.renderer.listen(this.contentViewChild.nativeElement, 'mouseenter', this.moveBar); this.xBarMouseDownListener = this.renderer.listen(this.xBarViewChild.nativeElement, 'mousedown', this.onXBarMouseDown); this.yBarMouseDownListener = this.renderer.listen(this.yBarViewChild.nativeElement, 'mousedown', this.onYBarMouseDown); this.calculateContainerHeight(); this.initialized = true; }); } } ngAfterContentInit() { this.templates.forEach((item) => { switch (item.getType()) { case 'content': this.contentTemplate = item.template; break; default: this.contentTemplate = item.template; break; } }); } calculateContainerHeight() { let container = this.containerViewChild.nativeElement; let content = this.contentViewChild.nativeElement; let xBar = this.xBarViewChild.nativeElement; const window = this.document.defaultView; let containerStyles = window.getComputedStyle(container), xBarStyles = window.getComputedStyle(xBar), pureContainerHeight = DomHandler.getHeight(container) - parseInt(xBarStyles['height'], 10); if (containerStyles['max-height'] != 'none' && pureContainerHeight == 0) { if (content.offsetHeight + parseInt(xBarStyles['height'], 10) > parseInt(containerStyles['max-height'], 10)) { container.style.height = containerStyles['max-height']; } else { container.style.height = content.offsetHeight + parseFloat(containerStyles.paddingTop) + parseFloat(containerStyles.paddingBottom) + parseFloat(containerStyles.borderTopWidth) + parseFloat(containerStyles.borderBottomWidth) + 'px'; } } } moveBar() { let container = this.containerViewChild.nativeElement; let content = this.contentViewChild.nativeElement; /* horizontal scroll */ let xBar = this.xBarViewChild.nativeElement; let totalWidth = content.scrollWidth; let ownWidth = content.clientWidth; let bottom = (container.clientHeight - xBar.clientHeight) * -1; this.scrollXRatio = ownWidth / totalWidth; /* vertical scroll */ let yBar = this.yBarViewChild.nativeElement; let totalHeight = content.scrollHeight; let ownHeight = content.clientHeight; let right = (container.clientWidth - yBar.clientWidth) * -1; this.scrollYRatio = ownHeight / totalHeight; this.requestAnimationFrame(() => { if (this.scrollXRatio >= 1) { xBar.setAttribute('data-p-scrollpanel-hidden', 'true'); DomHandler.addClass(xBar, 'p-scrollpanel-hidden'); } else { xBar.setAttribute('data-p-scrollpanel-hidden', 'false'); DomHandler.removeClass(xBar, 'p-scrollpanel-hidden'); const xBarWidth = Math.max(this.scrollXRatio * 100, 10); const xBarLeft = (content.scrollLeft * (100 - xBarWidth)) / (totalWidth - ownWidth); xBar.style.cssText = 'width:' + xBarWidth + '%; left:' + xBarLeft + '%;bottom:' + bottom + 'px;'; } if (this.scrollYRatio >= 1) { yBar.setAttribute('data-p-scrollpanel-hidden', 'true'); DomHandler.addClass(yBar, 'p-scrollpanel-hidden'); } else { yBar.setAttribute('data-p-scrollpanel-hidden', 'false'); DomHandler.removeClass(yBar, 'p-scrollpanel-hidden'); const yBarHeight = Math.max(this.scrollYRatio * 100, 10); const yBarTop = (content.scrollTop * (100 - yBarHeight)) / (totalHeight - ownHeight); yBar.style.cssText = 'height:' + yBarHeight + '%; top: calc(' + yBarTop + '% - ' + xBar.clientHeight + 'px);right:' + right + 'px;'; } }); this.cd.markForCheck(); } onScroll(event) { if (this.lastScrollLeft !== event.target.scrollLeft) { this.lastScrollLeft = event.target.scrollLeft; this.orientation = 'horizontal'; } else if (this.lastScrollTop !== event.target.scrollTop) { this.lastScrollTop = event.target.scrollTop; this.orientation = 'vertical'; } this.moveBar(); } onKeyDown(event) { if (this.orientation === 'vertical') { switch (event.code) { case 'ArrowDown': { this.setTimer('scrollTop', this.step); event.preventDefault(); break; } case 'ArrowUp': { this.setTimer('scrollTop', this.step * -1); event.preventDefault(); break; } case 'ArrowLeft': case 'ArrowRight': { event.preventDefault(); break; } default: //no op break; } } else if (this.orientation === 'horizontal') { switch (event.code) { case 'ArrowRight': { this.setTimer('scrollLeft', this.step); event.preventDefault(); break; } case 'ArrowLeft': { this.setTimer('scrollLeft', this.step * -1); event.preventDefault(); break; } case 'ArrowDown': case 'ArrowUp': { event.preventDefault(); break; } default: //no op break; } } } onKeyUp() { this.clearTimer(); } repeat(bar, step) { this.contentViewChild.nativeElement[bar] += step; this.moveBar(); } setTimer(bar, step) { this.clearTimer(); this.timer = setTimeout(() => { this.repeat(bar, step); }, 40); } clearTimer() { if (this.timer) { clearTimeout(this.timer); } } bindDocumentMouseListeners() { if (!this.documentMouseMoveListener) { this.documentMouseMoveListener = (e) => { this.onDocumentMouseMove(e); }; this.document.addEventListener('mousemove', this.documentMouseMoveListener); } if (!this.documentMouseUpListener) { this.documentMouseUpListener = (e) => { this.onDocumentMouseUp(e); }; this.document.addEventListener('mouseup', this.documentMouseUpListener); } } unbindDocumentMouseListeners() { if (this.documentMouseMoveListener) { this.document.removeEventListener('mousemove', this.documentMouseMoveListener); this.documentMouseMoveListener = null; } if (this.documentMouseUpListener) { document.removeEventListener('mouseup', this.documentMouseUpListener); this.documentMouseUpListener = null; } } onYBarMouseDown(e) { this.isYBarClicked = true; this.yBarViewChild.nativeElement.focus(); this.lastPageY = e.pageY; this.yBarViewChild.nativeElement.setAttribute('data-p-scrollpanel-grabbed', 'true'); DomHandler.addClass(this.yBarViewChild.nativeElement, 'p-scrollpanel-grabbed'); this.document.body.setAttribute('data-p-scrollpanel-grabbed', 'true'); DomHandler.addClass(this.document.body, 'p-scrollpanel-grabbed'); this.bindDocumentMouseListeners(); e.preventDefault(); } onXBarMouseDown(e) { this.isXBarClicked = true; this.xBarViewChild.nativeElement.focus(); this.lastPageX = e.pageX; this.xBarViewChild.nativeElement.setAttribute('data-p-scrollpanel-grabbed', 'false'); DomHandler.addClass(this.xBarViewChild.nativeElement, 'p-scrollpanel-grabbed'); this.document.body.setAttribute('data-p-scrollpanel-grabbed', 'false'); DomHandler.addClass(this.document.body, 'p-scrollpanel-grabbed'); this.bindDocumentMouseListeners(); e.preventDefault(); } onDocumentMouseMove(e) { if (this.isXBarClicked) { this.onMouseMoveForXBar(e); } else if (this.isYBarClicked) { this.onMouseMoveForYBar(e); } else { this.onMouseMoveForXBar(e); this.onMouseMoveForYBar(e); } } onMouseMoveForXBar(e) { let deltaX = e.pageX - this.lastPageX; this.lastPageX = e.pageX; this.requestAnimationFrame(() => { this.contentViewChild.nativeElement.scrollLeft += deltaX / this.scrollXRatio; }); } onMouseMoveForYBar(e) { let deltaY = e.pageY - this.lastPageY; this.lastPageY = e.pageY; this.requestAnimationFrame(() => { this.contentViewChild.nativeElement.scrollTop += deltaY / this.scrollYRatio; }); } /** * Scrolls the top location to the given value. * @param scrollTop * @group Method */ scrollTop(scrollTop) { let scrollableHeight = this.contentViewChild.nativeElement.scrollHeight - this.contentViewChild.nativeElement.clientHeight; scrollTop = scrollTop > scrollableHeight ? scrollableHeight : scrollTop > 0 ? scrollTop : 0; this.contentViewChild.nativeElement.scrollTop = scrollTop; } onFocus(event) { if (this.xBarViewChild.nativeElement.isSameNode(event.target)) { this.orientation = 'horizontal'; } else if (this.yBarViewChild.nativeElement.isSameNode(event.target)) { this.orientation = 'vertical'; } } onBlur() { if (this.orientation === 'horizontal') { this.orientation = 'vertical'; } } onDocumentMouseUp(e) { this.yBarViewChild.nativeElement.setAttribute('data-p-scrollpanel-grabbed', 'false'); DomHandler.removeClass(this.yBarViewChild.nativeElement, 'p-scrollpanel-grabbed'); this.xBarViewChild.nativeElement.setAttribute('data-p-scrollpanel-grabbed', 'false'); DomHandler.removeClass(this.xBarViewChild.nativeElement, 'p-scrollpanel-grabbed'); this.document.body.setAttribute('data-p-scrollpanel-grabbed', 'false'); DomHandler.removeClass(this.document.body, 'p-scrollpanel-grabbed'); this.unbindDocumentMouseListeners(); this.isXBarClicked = false; this.isYBarClicked = false; } requestAnimationFrame(f) { let frame = window.requestAnimationFrame || this.timeoutFrame; frame(f); } unbindListeners() { if (this.windowResizeListener) { this.windowResizeListener(); this.windowResizeListener = null; } if (this.contentScrollListener) { this.contentScrollListener(); this.contentScrollListener = null; } if (this.mouseEnterListener) { this.mouseEnterListener(); this.mouseEnterListener = null; } if (this.xBarMouseDownListener) { this.xBarMouseDownListener(); this.xBarMouseDownListener = null; } if (this.yBarMouseDownListener) { this.yBarMouseDownListener(); this.yBarMouseDownListener = null; } } ngOnDestroy() { if (this.initialized) { this.unbindListeners(); } } /** * Refreshes the position and size of the scrollbar. * @group Method */ refresh() { this.moveBar(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanel, deps: [{ token: PLATFORM_ID }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.0", type: ScrollPanel, selector: "p-scrollPanel", inputs: { style: "style", styleClass: "styleClass", step: "step" }, host: { classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }, { propertyName: "contentViewChild", first: true, predicate: ["content"], descendants: true }, { propertyName: "xBarViewChild", first: true, predicate: ["xBar"], descendants: true }, { propertyName: "yBarViewChild", first: true, predicate: ["yBar"], descendants: true }], ngImport: i0, template: ` <div #container [ngClass]="'p-scrollpanel p-component'" [ngStyle]="style" [class]="styleClass" [attr.data-pc-name]="'scrollpanel'"> <div class="p-scrollpanel-wrapper" [attr.data-pc-section]="'wrapper'"> <div #content class="p-scrollpanel-content" [attr.data-pc-section]="'content'" (mouseenter)="moveBar()" (scroll)="onScroll($event)"> <ng-content></ng-content> <ng-container *ngTemplateOutlet="contentTemplate"></ng-container> </div> </div> <div #xBar class="p-scrollpanel-bar p-scrollpanel-bar-x" tabindex="0" role="scrollbar" [attr.aria-orientation]="'horizontal'" [attr.aria-valuenow]="lastScrollLeft" [attr.data-pc-section]="'barx'" (mousedown)="onXBarMouseDown($event)" (keydown)="onKeyDown($event)" (keyup)="onKeyUp()" (focus)="onFocus($event)" (blur)="onBlur()" ></div> <div #yBar class="p-scrollpanel-bar p-scrollpanel-bar-y" tabindex="0" role="scrollbar" [attr.aria-orientation]="'vertical'" [attr.aria-valuenow]="lastScrollTop" [attr.data-pc-section]="'bary'" (mousedown)="onYBarMouseDown($event)" (keydown)="onKeyDown($event)" (keyup)="onKeyUp()" (focus)="onFocus($event)" ></div> </div> `, isInline: true, styles: [".p-scrollpanel-wrapper{overflow:hidden;width:100%;height:100%;position:relative;float:left}.p-scrollpanel-content{height:calc(100% + 18px);width:calc(100% + 18px);padding:0 18px 18px 0;position:relative;overflow:auto;box-sizing:border-box}.p-scrollpanel-bar{position:relative;background:#c1c1c1;border-radius:3px;cursor:pointer;opacity:0;transition:opacity .25s linear}.p-scrollpanel-bar-y{width:9px;top:0}.p-scrollpanel-bar-x{height:9px;bottom:0}.p-scrollpanel-hidden{visibility:hidden}.p-scrollpanel:hover .p-scrollpanel-bar,.p-scrollpanel:active .p-scrollpanel-bar{opacity:1}.p-scrollpanel-grabbed{-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } export { ScrollPanel }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanel, decorators: [{ type: Component, args: [{ selector: 'p-scrollPanel', template: ` <div #container [ngClass]="'p-scrollpanel p-component'" [ngStyle]="style" [class]="styleClass" [attr.data-pc-name]="'scrollpanel'"> <div class="p-scrollpanel-wrapper" [attr.data-pc-section]="'wrapper'"> <div #content class="p-scrollpanel-content" [attr.data-pc-section]="'content'" (mouseenter)="moveBar()" (scroll)="onScroll($event)"> <ng-content></ng-content> <ng-container *ngTemplateOutlet="contentTemplate"></ng-container> </div> </div> <div #xBar class="p-scrollpanel-bar p-scrollpanel-bar-x" tabindex="0" role="scrollbar" [attr.aria-orientation]="'horizontal'" [attr.aria-valuenow]="lastScrollLeft" [attr.data-pc-section]="'barx'" (mousedown)="onXBarMouseDown($event)" (keydown)="onKeyDown($event)" (keyup)="onKeyUp()" (focus)="onFocus($event)" (blur)="onBlur()" ></div> <div #yBar class="p-scrollpanel-bar p-scrollpanel-bar-y" tabindex="0" role="scrollbar" [attr.aria-orientation]="'vertical'" [attr.aria-valuenow]="lastScrollTop" [attr.data-pc-section]="'bary'" (mousedown)="onYBarMouseDown($event)" (keydown)="onKeyDown($event)" (keyup)="onKeyUp()" (focus)="onFocus($event)" ></div> </div> `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'p-element' }, styles: [".p-scrollpanel-wrapper{overflow:hidden;width:100%;height:100%;position:relative;float:left}.p-scrollpanel-content{height:calc(100% + 18px);width:calc(100% + 18px);padding:0 18px 18px 0;position:relative;overflow:auto;box-sizing:border-box}.p-scrollpanel-bar{position:relative;background:#c1c1c1;border-radius:3px;cursor:pointer;opacity:0;transition:opacity .25s linear}.p-scrollpanel-bar-y{width:9px;top:0}.p-scrollpanel-bar-x{height:9px;bottom:0}.p-scrollpanel-hidden{visibility:hidden}.p-scrollpanel:hover .p-scrollpanel-bar,.p-scrollpanel:active .p-scrollpanel-bar{opacity:1}.p-scrollpanel-grabbed{-webkit-user-select:none;user-select:none}\n"] }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: i0.Renderer2 }]; }, propDecorators: { style: [{ type: Input }], styleClass: [{ type: Input }], step: [{ type: Input }], containerViewChild: [{ type: ViewChild, args: ['container'] }], contentViewChild: [{ type: ViewChild, args: ['content'] }], xBarViewChild: [{ type: ViewChild, args: ['xBar'] }], yBarViewChild: [{ type: ViewChild, args: ['yBar'] }], templates: [{ type: ContentChildren, args: [PrimeTemplate] }] } }); class ScrollPanelModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanelModule, declarations: [ScrollPanel], imports: [CommonModule], exports: [ScrollPanel] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanelModule, imports: [CommonModule] }); } export { ScrollPanelModule }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.0", ngImport: i0, type: ScrollPanelModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule], exports: [ScrollPanel], declarations: [ScrollPanel] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xscGFuZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvc2Nyb2xscGFuZWwvc2Nyb2xscGFuZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RSxPQUFPLEVBR0gsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxlQUFlLEVBRWYsTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBR1IsV0FBVyxFQUlYLFNBQVMsRUFDVCxpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDOzs7QUFFekM7OztHQUdHO0FBQ0gsTUE4Q2EsV0FBVztJQW1FcUI7SUFBd0I7SUFBdUI7SUFBcUI7SUFBaUQ7SUFBNEI7SUFsRTFMOzs7T0FHRztJQUNNLEtBQUssQ0FBOEM7SUFDNUQ7OztPQUdHO0lBQ00sVUFBVSxDQUFxQjtJQUN4Qzs7O09BR0c7SUFDTSxJQUFJLEdBQVcsQ0FBQyxDQUFDO0lBRUYsa0JBQWtCLENBQXlCO0lBRTdDLGdCQUFnQixDQUF5QjtJQUU1QyxhQUFhLENBQXlCO0lBRXRDLGFBQWEsQ0FBeUI7SUFFekIsU0FBUyxDQUF1QztJQUVoRixZQUFZLENBQXFCO0lBRWpDLFlBQVksQ0FBcUI7SUFFakMsWUFBWSxHQUFRLENBQUMsRUFBZ0IsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU1RCxXQUFXLEdBQVksS0FBSyxDQUFDO0lBRTdCLFNBQVMsQ0FBcUI7SUFFOUIsU0FBUyxDQUFxQjtJQUU5QixhQUFhLEdBQVksS0FBSyxDQUFDO0lBRS9CLGFBQWEsR0FBWSxLQUFLLENBQUM7SUFFL0Is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QWUsWUFDZjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBb0NULG1CQUNnQix1QkFBdUIsQ0FBQyxNQUFNLGlCQUNoQyxpQkFBaUIsQ0FBQyxJQUFJLFFBRS9CO3dCQUNGLEtBQUssRUFBRSxXQUFXO3FCQUNyQjs7MEJBcUVZLE1BQU07MkJBQUMsV0FBVzs7MEJBQXNHLE1BQU07MkJBQUMsUUFBUTtvRUE5RDNJLEtBQUs7c0JBQWIsS0FBSztnQkFLRyxVQUFVO3NCQUFsQixLQUFLO2dCQUtHLElBQUk7c0JBQVosS0FBSztnQkFFa0Isa0JBQWtCO3NCQUF6QyxTQUFTO3VCQUFDLFdBQVc7Z0JBRUEsZ0JBQWdCO3NCQUFyQyxTQUFTO3VCQUFDLFNBQVM7Z0JBRUQsYUFBYTtzQkFBL0IsU0FBUzt1QkFBQyxNQUFNO2dCQUVFLGFBQWE7c0JBQS9CLFNBQVM7dUJBQUMsTUFBTTtnQkFFZSxTQUFTO3NCQUF4QyxlQUFlO3VCQUFDLGFBQWE7O0FBa1psQyxNQUthLGlCQUFpQjt1R0FBakIsaUJBQWlCO3dHQUFqQixpQkFBaUIsaUJBaGJqQixXQUFXLGFBNGFWLFlBQVksYUE1YWIsV0FBVzt3R0FnYlgsaUJBQWlCLFlBSmhCLFlBQVk7O1NBSWIsaUJBQWlCOzJGQUFqQixpQkFBaUI7a0JBTDdCLFFBQVE7bUJBQUM7b0JBQ04sT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDO29CQUN2QixPQUFPLEVBQUUsQ0FBQyxXQUFXLENBQUM7b0JBQ3RCLFlBQVksRUFBRSxDQUFDLFdBQVcsQ0FBQztpQkFDOUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUsIERPQ1VNRU5ULCBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgQWZ0ZXJWaWV3SW5pdCxcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkcmVuLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgSW5qZWN0LFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE5nWm9uZSxcbiAgICBPbkRlc3Ryb3ksXG4gICAgUExBVEZPUk1fSUQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFJlbmRlcmVyMixcbiAgICBUZW1wbGF0ZVJlZixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQcmltZVRlbXBsYXRlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgRG9tSGFuZGxlciB9IGZyb20gJ3ByaW1lbmcvZG9tJztcbmltcG9ydCB7IE51bGxhYmxlIH0gZnJvbSAncHJpbWVuZy90cy1oZWxwZXJzJztcbi8qKlxuICogU2Nyb2xsUGFuZWwgaXMgYSBjcm9zcyBicm93c2VyLCBsaWdodHdlaWdodCBhbmQgdGhlbWFibGUgYWx0ZXJuYXRpdmUgdG8gbmF0aXZlIGJyb3dzZXIgc2Nyb2xsYmFyLlxuICogQGdyb3VwIENvbXBvbmVudHNcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwLXNjcm9sbFBhbmVsJyxcbiAgICB0ZW1wbGF0ZTogYFxuICAgICAgICA8ZGl2ICNjb250YWluZXIgW25nQ2xhc3NdPVwiJ3Atc2Nyb2xscGFuZWwgcC1jb21wb25lbnQnXCIgW25nU3R5bGVdPVwic3R5bGVcIiBbY2xhc3NdPVwic3R5bGVDbGFzc1wiIFthdHRyLmRhdGEtcGMtbmFtZV09XCInc2Nyb2xscGFuZWwnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1zY3JvbGxwYW5lbC13cmFwcGVyXCIgW2F0dHIuZGF0YS1wYy1zZWN0aW9uXT1cIid3cmFwcGVyJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgI2NvbnRlbnQgY2xhc3M9XCJwLXNjcm9sbHBhbmVsLWNvbnRlbnRcIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2NvbnRlbnQnXCIgKG1vdXNlZW50ZXIpPVwibW92ZUJhcigpXCIgKHNjcm9sbCk9XCJvblNjcm9sbCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbnRlbnRUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgI3hCYXJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtc2Nyb2xscGFuZWwtYmFyIHAtc2Nyb2xscGFuZWwtYmFyLXhcIlxuICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgcm9sZT1cInNjcm9sbGJhclwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1vcmllbnRhdGlvbl09XCInaG9yaXpvbnRhbCdcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtdmFsdWVub3ddPVwibGFzdFNjcm9sbExlZnRcIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInYmFyeCdcIlxuICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25YQmFyTW91c2VEb3duKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoa2V5dXApPVwib25LZXlVcCgpXCJcbiAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXG4gICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgI3lCYXJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInAtc2Nyb2xscGFuZWwtYmFyIHAtc2Nyb2xscGFuZWwtYmFyLXlcIlxuICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgcm9sZT1cInNjcm9sbGJhclwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1vcmllbnRhdGlvbl09XCIndmVydGljYWwnXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXZhbHVlbm93XT1cImxhc3RTY3JvbGxUb3BcIlxuICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtcGMtc2VjdGlvbl09XCInYmFyeSdcIlxuICAgICAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25ZQmFyTW91c2VEb3duKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoa2V5dXApPVwib25LZXlVcCgpXCJcbiAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygkZXZlbnQpXCJcbiAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgYCxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIHN0eWxlVXJsczogWycuL3Njcm9sbHBhbmVsLmNzcyddLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgY2xhc3M6ICdwLWVsZW1lbnQnXG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBTY3JvbGxQYW5lbCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqXG4gICAgICogSW5saW5lIHN0eWxlIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgc3R5bGU6IHsgW2tsYXNzOiBzdHJpbmddOiBhbnkgfSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogU3R5bGUgY2xhc3Mgb2YgdGhlIGNvbXBvbmVudC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBzdHlsZUNsYXNzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogU3RlcCBmYWN0b3IgdG8gc2Nyb2xsIHRoZSBjb250ZW50IHdoaWxlIHByZXNzaW5nIHRoZSBhcnJvdyBrZXlzLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHN0ZXA6IG51bWJlciA9IDU7XG5cbiAgICBAVmlld0NoaWxkKCdjb250YWluZXInKSBjb250YWluZXJWaWV3Q2hpbGQ6IEVsZW1lbnRSZWYgfCB1bmRlZmluZWQ7XG5cbiAgICBAVmlld0NoaWxkKCdjb250ZW50JykgY29udGVudFZpZXdDaGlsZDogRWxlbWVudFJlZiB8IHVuZGVmaW5lZDtcblxuICAgIEBWaWV3Q2hpbGQoJ3hCYXInKSB4QmFyVmlld0NoaWxkOiBFbGVtZW50UmVmIHwgdW5kZWZpbmVkO1xuXG4gICAgQFZpZXdDaGlsZCgneUJhcicpIHlCYXJWaWV3Q2hpbGQ6IEVsZW1lbnRSZWYgfCB1bmRlZmluZWQ7XG5cbiAgICBAQ29udGVudENoaWxkcmVuKFByaW1lVGVtcGxhdGUpIHRlbXBsYXRlczogUXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+IHwgdW5kZWZpbmVkO1xuXG4gICAgc2Nyb2xsWVJhdGlvOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICBzY3JvbGxYUmF0aW86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIHRpbWVvdXRGcmFtZTogYW55ID0gKGZuOiBWb2lkRnVuY3Rpb24pID0+IHNldFRpbWVvdXQoZm4sIDApO1xuXG4gICAgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGxhc3RQYWdlWTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gICAgbGFzdFBhZ2VYOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICBpc1hCYXJDbGlja2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBpc1lCYXJDbGlja2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb250ZW50VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XG5cbiAgICBsYXN0U2Nyb2xsTGVmdDogbnVtYmVyID0gMDtcblxuICAgIGxhc3RTY3JvbGxUb3A6IG51bWJlciA9IDA7XG5cbiAgICBvcmllbnRhdGlvbjogc3RyaW5nID0gJ3ZlcnRpY2FsJztcblxuICAgIHRpbWVyOiBhbnk7XG5cbiAgICB3aW5kb3dSZXNpemVMaXN0ZW5lcjogVm9pZEZ1bmN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnRlbnRTY3JvbGxMaXN0ZW5lcjogVm9pZEZ1bmN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIG1vdXNlRW50ZXJMaXN0ZW5lcjogVm9pZEZ1bmN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIHhCYXJNb3VzZURvd25MaXN0ZW5lcjogVm9pZEZ1bmN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIHlCYXJNb3VzZURvd25MaXN0ZW5lcjogVm9pZEZ1bmN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIGRvY3VtZW50TW91c2VNb3ZlTGlzdGVuZXI6IE51bGxhYmxlPChldmVudD86IGFueSkgPT4gdm9pZD47XG5cbiAgICBkb2N1bWVudE1vdXNlVXBMaXN0ZW5lcjogTnVsbGFibGU8KGV2ZW50PzogYW55KSA9PiB2b2lkPjtcblxuICAgIGNvbnN0cnVjdG9yKEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogYW55LCBwdWJsaWMgZWw6IEVsZW1lbnRSZWYsIHB1YmxpYyB6b25lOiBOZ1pvbmUsIHB1YmxpYyBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50LCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHt9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubW92ZUJhcigpO1xuICAgICAgICAgICAgICAgIHRoaXMubW92ZUJhciA9IHRoaXMubW92ZUJhci5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub25YQmFyTW91c2VEb3duID0gdGhpcy5vblhCYXJNb3VzZURvd24uYmluZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uWUJhck1vdXNlRG93biA9IHRoaXMub25ZQmFyTW91c2VEb3duLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkRvY3VtZW50TW91c2VNb3ZlID0gdGhpcy5vbkRvY3VtZW50TW91c2VNb3ZlLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkRvY3VtZW50TW91c2VVcCA9IHRoaXMub25Eb2N1bWVudE1vdXNlVXAuYmluZCh0aGlzKTtcblxuICAgICAgICAgICAgICAgIHRoaXMud2luZG93UmVzaXplTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbih3aW5kb3csICdyZXNpemUnLCB0aGlzLm1vdmVCYXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGVudFNjcm9sbExpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oKHRoaXMuY29udGVudFZpZXdDaGlsZCBhcyBFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJywgdGhpcy5tb3ZlQmFyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1vdXNlRW50ZXJMaXN0ZW5lciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKCh0aGlzLmNvbnRlbnRWaWV3Q2hpbGQgYXMgRWxlbWVudFJlZikubmF0aXZlRWxlbWVudCwgJ21vdXNlZW50ZXInLCB0aGlzLm1vdmVCYXIpO1xuICAgICAgICAgICAgICAgIHRoaXMueEJhck1vdXNlRG93bkxpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oKHRoaXMueEJhclZpZXdDaGlsZCBhcyBFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50LCAnbW91c2Vkb3duJywgdGhpcy5vblhCYXJNb3VzZURvd24pO1xuICAgICAgICAgICAgICAgIHRoaXMueUJhck1vdXNlRG93bkxpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oKHRoaXMueUJhclZpZXdDaGlsZCBhcyBFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50LCAnbW91c2Vkb3duJywgdGhpcy5vbllCYXJNb3VzZURvd24pO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQ29udGFpbmVySGVpZ2h0KCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICAodGhpcy50ZW1wbGF0ZXMgYXMgUXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+KS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGl0ZW0uZ2V0VHlwZSgpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnY29udGVudCc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudFRlbXBsYXRlID0gaXRlbS50ZW1wbGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVDb250YWluZXJIZWlnaHQoKSB7XG4gICAgICAgIGxldCBjb250YWluZXIgPSAodGhpcy5jb250YWluZXJWaWV3Q2hpbGQgYXMgRWxlbWVudFJlZikubmF0aXZlRWxlbWVudDtcbiAgICAgICAgbGV0IGNvbnRlbnQgPSAodGhpcy5jb250ZW50Vmlld0NoaWxkIGFzIEVsZW1lbnRSZWYpLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGxldCB4QmFyID0gKHRoaXMueEJhclZpZXdDaGlsZCBhcyBFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50O1xuICAgICAgICBjb25zdCB3aW5kb3cgPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3IGFzIFdpbmRvdztcblxuICAgICAgICBsZXQgY29udGFpbmVyU3R5bGVzOiB7IFtrbGFzczogc3RyaW5nXTogYW55IH0gPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShjb250YWluZXIpLFxuICAgICAgICAgICAgeEJ