ng-devui
Version:
DevUI components based on Angular
224 lines • 38 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, Input, Output, TemplateRef, } from '@angular/core';
import { Subscription, fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class BackTopComponent {
constructor(cdr, el, doc) {
this.cdr = cdr;
this.el = el;
this.doc = doc;
this.visibleHeight = 300;
this.bottom = '50px';
this.right = '30px';
this.draggable = false;
this.backTopEvent = new EventEmitter();
this.dragEvent = new EventEmitter();
this.currScrollTop = 0;
this.duration = 0;
this.moveCursor = false;
this.moveToggle = false;
this.isVisible = false;
this.subs = new Subscription();
this.SCROLL_REFRESH_INTERVAL = 100;
this.MOUSEDOWN_DELAY = 180;
this.RESIZE_DELAY = 300;
this.document = this.doc;
}
ngOnChanges(changes) {
if (changes.scrollTarget) {
if (this.subs) {
this.subs.unsubscribe();
}
this.subs = new Subscription();
this.addScrollEvent();
}
}
ngOnInit() {
this.addScrollEvent();
this.showButton();
}
ngAfterViewInit() {
if (this.draggable) {
// 窗口大小改变时,如缩放比例或组件超出显示范围重置到默认位置
this.subs.add(fromEvent(window, 'resize')
.pipe(debounceTime(this.RESIZE_DELAY))
.subscribe(() => {
const dom = this.dragBoundary?.dom || this.el.nativeElement.querySelector('div.devui-backtop');
if (dom) {
// 不显示时无法获取getBoundingClientRect,使用style获取
const style = getComputedStyle(dom);
const left = parseInt(style.left, 10) || 0;
const top = parseInt(style.top, 10) || 0;
if (window.devicePixelRatio !== 1 || left > window.innerWidth || top > window.innerHeight) {
this.onMouseUp();
this.duration = 0;
dom.style.left = 'unset';
dom.style.top = 'unset';
}
}
}));
}
}
ngOnDestroy() {
if (this.subs) {
this.subs.unsubscribe();
}
}
addScrollEvent() {
this.subs.add(fromEvent(this.getScrollTarget(), 'scroll')
.pipe(debounceTime(this.SCROLL_REFRESH_INTERVAL))
.subscribe(() => {
this.showButton();
this.cdr.detectChanges();
}));
}
getScrollTarget() {
if (this.scrollTarget) {
this.el.nativeElement.querySelector('.devui-backtop').style.position = 'absolute';
this.scrollTarget.parentElement.style.position = 'relative';
}
this.target = this.scrollTarget || window;
return this.target;
}
showButton() {
this.currScrollTop =
this.target === window
? window.pageYOffset || this.document.documentElement.scrollTop || this.document.body.scrollTop
: this.scrollTarget.scrollTop;
if (this.isVisible !== this.currScrollTop >= this.visibleHeight) {
this.isVisible = !this.isVisible;
}
}
goTop() {
if (this.draggable && this.duration > this.MOUSEDOWN_DELAY) {
this.duration = 0;
return;
}
if (this.target === window) {
this.document.documentElement.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
this.document.body.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
}
else {
this.scrollTarget.style.scrollBehavior = 'smooth';
this.scrollTarget.scrollTop = 0;
}
this.duration = 0;
this.backTopEvent.emit(true);
}
setDragBoundary() {
const dom = this.el.nativeElement.querySelector('div.devui-backtop');
let boxRect;
let minLeft;
let minTop;
let maxLeft;
let maxTop;
if (dom) {
const { width, height } = dom.getBoundingClientRect();
if (this.scrollTarget) {
boxRect = this.scrollTarget.getBoundingClientRect();
minLeft = -1 * boxRect.x;
minTop = -1 * boxRect.y;
maxLeft = window.innerWidth - boxRect.x - width;
maxTop = window.innerHeight - boxRect.y - height;
}
else {
boxRect = { x: 0, y: 0 };
minLeft = 0;
minTop = 0;
maxLeft = window.innerWidth - width;
maxTop = window.innerHeight - height;
}
this.dragBoundary = { dom, boxRect, minLeft, minTop, maxLeft, maxTop };
}
}
// mousedown mouseup click 按顺序触发且前一个结束触发下一个
mousedownEvent(event) {
if (this.draggable) {
event.preventDefault();
this.setDragBoundary();
this.duration = new Date().getTime();
this.moveToggle = true;
this.cursorTimer = setTimeout(() => {
this.moveCursor = true;
this.dragEvent.emit(true);
}, this.MOUSEDOWN_DELAY);
}
}
mouseleaveEvent() {
if (this.draggable && this.cursorTimer) {
clearTimeout(this.cursorTimer);
}
}
onMouseUp() {
if (this.draggable) {
if (this.cursorTimer) {
clearTimeout(this.cursorTimer);
}
if (this.moveToggle) {
this.moveToggle = false;
this.moveCursor = false;
this.dragEvent.emit(false);
}
this.duration = this.duration && new Date().getTime() - this.duration;
}
}
onMouseMove(event) {
if (this.draggable && this.moveToggle && this.dragBoundary) {
// 先判断再执行阻止默认事件,否则可能影响鼠标拖选功能
event.preventDefault();
this.moveCursor = true;
const posX = event.movementX;
const posY = event.movementY;
const rect = this.dragBoundary.dom.getBoundingClientRect();
const left = rect.x - this.dragBoundary.boxRect.x + posX;
const top = rect.y - this.dragBoundary.boxRect.y + posY;
const isLeft = left < this.dragBoundary.minLeft;
const isRight = left > this.dragBoundary.maxLeft;
const isTop = top < this.dragBoundary.minTop;
const isBottom = top > this.dragBoundary.maxTop;
const leftResult = isLeft ? this.dragBoundary.minLeft : left;
const topResult = isTop ? this.dragBoundary.minTop : top;
this.dragBoundary.dom.style.left = `${isRight ? this.dragBoundary.maxLeft : leftResult}px`;
this.dragBoundary.dom.style.top = `${isBottom ? this.dragBoundary.maxTop : topResult}px`;
// 如到达边界释放拖拽动作,避免鼠标偏移较大距离后返回主视窗仍可拖拽
if ([isLeft, isRight, isTop, isBottom].includes(true)) {
this.onMouseUp();
this.duration = 0;
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BackTopComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BackTopComponent, selector: "d-back-top", inputs: { customTemplate: "customTemplate", visibleHeight: "visibleHeight", bottom: "bottom", right: "right", scrollTarget: "scrollTarget", draggable: "draggable" }, outputs: { backTopEvent: "backTopEvent", dragEvent: "dragEvent" }, host: { listeners: { "document:mouseup": "onMouseUp()", "document:mousemove": "onMouseMove($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"devui-backtop\"\n [ngStyle]=\"{\n display: isVisible ? 'block' : 'none',\n bottom: bottom,\n right: right,\n cursor: moveCursor && draggable ? 'move' : 'pointer'\n }\"\n (click)=\"goTop()\"\n>\n <div class=\"devui-backtop-drag-handle\" (mousedown)=\"mousedownEvent($event)\" (mouseleave)=\"mouseleaveEvent()\">\n <ng-template [ngTemplateOutlet]=\"customTemplate ? customTemplate : default\"></ng-template>\n <ng-template #default>\n <div class=\"devui-backtop-content\">\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M8.71335931,15.2865297 C8.61179683,16.2090609 7.32293758,16.1267953 7.27304695,15.2865297 C7.27175008,14.6475142 7.27175008,5.26479636 7.27175008,5.26479636 L2.83675052,9.54548344 C2.14185995,10.1440615 1.3143288,9.18731159 1.83135998,8.55773353 C3.79557855,6.65310872 7.3202657,3.24515592 7.40179694,3.16632781 C7.72696878,2.81306222 8.23887498,2.79476534 8.58495308,3.16632781 C9.23193739,3.7919215 14.0334057,8.42146792 14.1791557,8.58804603 C14.66614,9.19338972 13.8787807,10.0892021 13.2066089,9.58451469 C13.0329683,9.43717095 8.71468744,5.26462448 8.71468744,5.26462448 L8.71335931,15.2865297 Z M1.81868811,-8.54871729e-14 L14.1075619,-8.54871729e-14 L14.1075619,1.39509361 L1.81868811,1.39509361 L1.81868811,-8.54871729e-14 Z\"\n fill=\"#FFFFFF\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".devui-backtop{width:40px;height:40px;position:fixed;z-index:1}.devui-backtop .devui-backtop-drag-handle{cursor:unset!important}.devui-backtop-content{width:40px;height:40px;background-color:var(--devui-text-weak, #333333);opacity:.4;border-radius:50%;display:flex;align-items:center;justify-content:center}.devui-backtop-content:hover{opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BackTopComponent, decorators: [{
type: Component,
args: [{ selector: 'd-back-top', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<div\n class=\"devui-backtop\"\n [ngStyle]=\"{\n display: isVisible ? 'block' : 'none',\n bottom: bottom,\n right: right,\n cursor: moveCursor && draggable ? 'move' : 'pointer'\n }\"\n (click)=\"goTop()\"\n>\n <div class=\"devui-backtop-drag-handle\" (mousedown)=\"mousedownEvent($event)\" (mouseleave)=\"mouseleaveEvent()\">\n <ng-template [ngTemplateOutlet]=\"customTemplate ? customTemplate : default\"></ng-template>\n <ng-template #default>\n <div class=\"devui-backtop-content\">\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M8.71335931,15.2865297 C8.61179683,16.2090609 7.32293758,16.1267953 7.27304695,15.2865297 C7.27175008,14.6475142 7.27175008,5.26479636 7.27175008,5.26479636 L2.83675052,9.54548344 C2.14185995,10.1440615 1.3143288,9.18731159 1.83135998,8.55773353 C3.79557855,6.65310872 7.3202657,3.24515592 7.40179694,3.16632781 C7.72696878,2.81306222 8.23887498,2.79476534 8.58495308,3.16632781 C9.23193739,3.7919215 14.0334057,8.42146792 14.1791557,8.58804603 C14.66614,9.19338972 13.8787807,10.0892021 13.2066089,9.58451469 C13.0329683,9.43717095 8.71468744,5.26462448 8.71468744,5.26462448 L8.71335931,15.2865297 Z M1.81868811,-8.54871729e-14 L14.1075619,-8.54871729e-14 L14.1075619,1.39509361 L1.81868811,1.39509361 L1.81868811,-8.54871729e-14 Z\"\n fill=\"#FFFFFF\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".devui-backtop{width:40px;height:40px;position:fixed;z-index:1}.devui-backtop .devui-backtop-drag-handle{cursor:unset!important}.devui-backtop-content{width:40px;height:40px;background-color:var(--devui-text-weak, #333333);opacity:.4;border-radius:50%;display:flex;align-items:center;justify-content:center}.devui-backtop-content:hover{opacity:1}\n"] }]
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { customTemplate: [{
type: Input
}], visibleHeight: [{
type: Input
}], bottom: [{
type: Input
}], right: [{
type: Input
}], scrollTarget: [{
type: Input
}], draggable: [{
type: Input
}], backTopEvent: [{
type: Output
}], dragEvent: [{
type: Output
}], onMouseUp: [{
type: HostListener,
args: ['document:mouseup', []]
}], onMouseMove: [{
type: HostListener,
args: ['document:mousemove', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFjay10b3AuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2dWkvYmFjay10b3AvYmFjay10b3AuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vZGV2dWkvYmFjay10b3AvYmFjay10b3AuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUlMLE1BQU0sRUFFTixXQUFXLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFTOUMsTUFBTSxPQUFPLGdCQUFnQjtJQXlCM0IsWUFBb0IsR0FBc0IsRUFBVSxFQUFjLEVBQTRCLEdBQVE7UUFBbEYsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQTRCLFFBQUcsR0FBSCxHQUFHLENBQUs7UUF2QjdGLGtCQUFhLEdBQUcsR0FBRyxDQUFDO1FBQ3BCLFdBQU0sR0FBRyxNQUFNLENBQUM7UUFDaEIsVUFBSyxHQUFHLE1BQU0sQ0FBQztRQUVmLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDakIsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBQzNDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBRWxELGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFHYixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsY0FB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O1lBQ25DLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNwQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7K0dBL01VLGdCQUFnQiw2RUF5QmlELFFBQVE7bUdBekJ6RSxnQkFBZ0IseVpDNUI3Qixrd0RBa0NBOzs0RkROYSxnQkFBZ0I7a0JBUDVCLFNBQVM7K0JBQ0UsWUFBWSxtQkFHTCx1QkFBdUIsQ0FBQyxNQUFNLHVCQUMxQixLQUFLOzswQkEyQjJDLE1BQU07MkJBQUMsUUFBUTt5Q0F4QjNFLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBZ0tQLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxFQUFFO2dCQWdCcEMsV0FBVztzQkFEVixZQUFZO3VCQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uRGVzdHJveSxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZC1iYWNrLXRvcCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2JhY2stdG9wLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9iYWNrLXRvcC5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQmFja1RvcENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xyXG4gIEBJbnB1dCgpIGN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBJbnB1dCgpIHZpc2libGVIZWlnaHQgPSAzMDA7XHJcbiAgQElucHV0KCkgYm90dG9tID0gJzUwcHgnO1xyXG4gIEBJbnB1dCgpIHJpZ2h0ID0gJzMwcHgnO1xyXG4gIEBJbnB1dCgpIHNjcm9sbFRhcmdldDogSFRNTEVsZW1lbnQ7XHJcbiAgQElucHV0KCkgZHJhZ2dhYmxlID0gZmFsc2U7XHJcbiAgQE91dHB1dCgpIGJhY2tUb3BFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuICBAT3V0cHV0KCkgZHJhZ0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG5cclxuICBjdXJyU2Nyb2xsVG9wID0gMDtcclxuICBkdXJhdGlvbiA9IDA7XHJcbiAgY3Vyc29yVGltZXI6IGFueTtcclxuICBkcmFnQm91bmRhcnk6IGFueTtcclxuICBtb3ZlQ3Vyc29yID0gZmFsc2U7XHJcbiAgbW92ZVRvZ2dsZSA9IGZhbHNlO1xyXG4gIGlzVmlzaWJsZSA9IGZhbHNlO1xyXG4gIHRhcmdldDogSFRNTEVsZW1lbnQgfCBXaW5kb3c7XHJcbiAgc3ViczogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG4gIGRvY3VtZW50OiBEb2N1bWVudDtcclxuXHJcbiAgU0NST0xMX1JFRlJFU0hfSU5URVJWQUwgPSAxMDA7XHJcbiAgTU9VU0VET1dOX0RFTEFZID0gMTgwO1xyXG4gIFJFU0laRV9ERUxBWSA9IDMwMDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYzogYW55KSB7XHJcbiAgICB0aGlzLmRvY3VtZW50ID0gdGhpcy5kb2M7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlcy5zY3JvbGxUYXJnZXQpIHtcclxuICAgICAgaWYgKHRoaXMuc3Vicykge1xyXG4gICAgICAgIHRoaXMuc3Vicy51bnN1YnNjcmliZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuICAgICAgdGhpcy5hZGRTY3JvbGxFdmVudCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmFkZFNjcm9sbEV2ZW50KCk7XHJcbiAgICB0aGlzLnNob3dCdXR0b24oKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRyYWdnYWJsZSkge1xyXG4gICAgICAvLyDnqpflj6PlpKflsI/mlLnlj5jml7bvvIzlpoLnvKnmlL7mr5TkvovmiJbnu4Tku7botoXlh7rmmL7npLrojIPlm7Tph43nva7liLDpu5jorqTkvY3nva5cclxuICAgICAgdGhpcy5zdWJzLmFkZChcclxuICAgICAgICBmcm9tRXZlbnQod2luZG93LCAncmVzaXplJylcclxuICAgICAgICAgIC5waXBlKGRlYm91bmNlVGltZSh0aGlzLlJFU0laRV9ERUxBWSkpXHJcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZG9tID0gdGhpcy5kcmFnQm91bmRhcnk/LmRvbSB8fCB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignZGl2LmRldnVpLWJhY2t0b3AnKTtcclxuICAgICAgICAgICAgaWYgKGRvbSkge1xyXG4gICAgICAgICAgICAgIC8vIOS4jeaYvuekuuaXtuaXoOazleiOt+WPlmdldEJvdW5kaW5nQ2xpZW50UmVjdCzkvb/nlKhzdHlsZeiOt+WPllxyXG4gICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShkb20pO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBwYXJzZUludChzdHlsZS5sZWZ0LCAxMCkgfHwgMDtcclxuICAgICAgICAgICAgICBjb25zdCB0b3AgPSBwYXJzZUludChzdHlsZS50b3AsIDEwKSB8fCAwO1xyXG4gICAgICAgICAgICAgIGlmICh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyAhPT0gMSB8fCBsZWZ0ID4gd2luZG93LmlubmVyV2lkdGggfHwgdG9wID4gd2luZG93LmlubmVySGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uTW91c2VVcCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUubGVmdCA9ICd1bnNldCc7XHJcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUudG9wID0gJ3Vuc2V0JztcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnN1YnMpIHtcclxuICAgICAgdGhpcy5zdWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhZGRTY3JvbGxFdmVudCgpIHtcclxuICAgIHRoaXMuc3Vicy5hZGQoXHJcbiAgICAgIGZyb21FdmVudCh0aGlzLmdldFNjcm9sbFRhcmdldCgpLCAnc2Nyb2xsJylcclxuICAgICAgICAucGlwZShkZWJvdW5jZVRpbWUodGhpcy5TQ1JPTExfUkVGUkVTSF9JTlRFUlZBTCkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLnNob3dCdXR0b24oKTtcclxuICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGdldFNjcm9sbFRhcmdldCgpIHtcclxuICAgIGlmICh0aGlzLnNjcm9sbFRhcmdldCkge1xyXG4gICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmRldnVpLWJhY2t0b3AnKS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XHJcbiAgICAgIHRoaXMuc2Nyb2xsVGFyZ2V0LnBhcmVudEVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xyXG4gICAgfVxyXG4gICAgdGhpcy50YXJnZXQgPSB0aGlzLnNjcm9sbFRhcmdldCB8fCB3aW5kb3c7XHJcbiAgICByZXR1cm4gdGhpcy50YXJnZXQ7XHJcbiAgfVxyXG5cclxuICBzaG93QnV0dG9uKCkge1xyXG4gICAgdGhpcy5jdXJyU2Nyb2xsVG9wID1cclxuICAgICAgdGhpcy50YXJnZXQgPT09IHdpbmRvd1xyXG4gICAgICAgID8gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCB0aGlzLmRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wXHJcbiAgICAgICAgOiB0aGlzLnNjcm9sbFRhcmdldC5zY3JvbGxUb3A7XHJcbiAgICBpZiAodGhpcy5pc1Zpc2libGUgIT09IHRoaXMuY3VyclNjcm9sbFRvcCA+PSB0aGlzLnZpc2libGVIZWlnaHQpIHtcclxuICAgICAgdGhpcy5pc1Zpc2libGUgPSAhdGhpcy5pc1Zpc2libGU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnb1RvcCgpIHtcclxuICAgIGlmICh0aGlzLmRyYWdnYWJsZSAmJiB0aGlzLmR1cmF0aW9uID4gdGhpcy5NT1VTRURPV05fREVMQVkpIHtcclxuICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnRhcmdldCA9PT0gd2luZG93KSB7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ3N0YXJ0JywgaW5saW5lOiAnbmVhcmVzdCcgfSk7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdzdGFydCcsIGlubGluZTogJ25lYXJlc3QnIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zY3JvbGxUYXJnZXQuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAnc21vb3RoJztcclxuICAgICAgdGhpcy5zY3JvbGxUYXJnZXQuc2Nyb2xsVG9wID0gMDtcclxuICAgIH1cclxuICAgIHRoaXMuZHVyYXRpb24gPSAwO1xyXG4gICAgdGhpcy5iYWNrVG9wRXZlbnQuZW1pdCh0cnVlKTtcclxuICB9XHJcblxyXG4gIHNldERyYWdCb3VuZGFyeSgpIHtcclxuICAgIGNvbnN0IGRvbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdkaXYuZGV2dWktYmFja3RvcCcpO1xyXG4gICAgbGV0IGJveFJlY3Q7XHJcbiAgICBsZXQgbWluTGVmdDtcclxuICAgIGxldCBtaW5Ub3A7XHJcbiAgICBsZXQgbWF4TGVmdDtcclxuICAgIGxldCBtYXhUb3A7XHJcbiAgICBpZiAoZG9tKSB7XHJcbiAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBpZiAodGhpcy5zY3JvbGxUYXJnZXQpIHtcclxuICAgICAgICBib3hSZWN0ID0gdGhpcy5zY3JvbGxUYXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgbWluTGVmdCA9IC0xICogYm94UmVjdC54O1xyXG4gICAgICAgIG1pblRvcCA9IC0xICogYm94UmVjdC55O1xyXG4gICAgICAgIG1heExlZnQgPSB3aW5kb3cuaW5uZXJXaWR0aCAtIGJveFJlY3QueCAtIHdpZHRoO1xyXG4gICAgICAgIG1heFRvcCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGJveFJlY3QueSAtIGhlaWdodDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBib3hSZWN0ID0geyB4OiAwLCB5OiAwIH07XHJcbiAgICAgICAgbWluTGVmdCA9IDA7XHJcbiAgICAgICAgbWluVG9wID0gMDtcclxuICAgICAgICBtYXhMZWZ0ID0gd2luZG93LmlubmVyV2lkdGggLSB3aWR0aDtcclxuICAgICAgICBtYXhUb3AgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSBoZWlnaHQ7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5kcmFnQm91bmRhcnkgPSB7IGRvbSwgYm94UmVjdCwgbWluTGVmdCwgbWluVG9wLCBtYXhMZWZ0LCBtYXhUb3AgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIG1vdXNlZG93biBtb3VzZXVwIGNsaWNrIOaMiemhuuW6j+inpuWPkeS4lOWJjeS4gOS4que7k+adn+inpuWPkeS4i+S4gOS4qlxyXG4gIG1vdXNlZG93bkV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdGhpcy5zZXREcmFnQm91bmRhcnkoKTtcclxuICAgICAgdGhpcy5kdXJhdGlvbiA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICB0aGlzLm1vdmVUb2dnbGUgPSB0cnVlO1xyXG4gICAgICB0aGlzLmN1cnNvclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5tb3ZlQ3Vyc29yID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmRyYWdFdmVudC5lbWl0KHRydWUpO1xyXG4gICAgICB9LCB0aGlzLk1PVVNFRE9XTl9ERUxBWSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBtb3VzZWxlYXZlRXZlbnQoKSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUgJiYgdGhpcy5jdXJzb3JUaW1lcikge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jdXJzb3JUaW1lcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZXVwJywgW10pXHJcbiAgb25Nb3VzZVVwKCkge1xyXG4gICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XHJcbiAgICAgIGlmICh0aGlzLmN1cnNvclRpbWVyKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuY3Vyc29yVGltZXIpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLm1vdmVUb2dnbGUpIHtcclxuICAgICAgICB0aGlzLm1vdmVUb2dnbGUgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm1vdmVDdXJzb3IgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmRyYWdFdmVudC5lbWl0KGZhbHNlKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmR1cmF0aW9uID0gdGhpcy5kdXJhdGlvbiAmJiBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuZHVyYXRpb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUgJiYgdGhpcy5tb3ZlVG9nZ2xlICYmIHRoaXMuZHJhZ0JvdW5kYXJ5KSB7XHJcbiAgICAgIC8vIOWFiOWIpOaWreWGjeaJp+ihjOmYu+atoum7mOiupOS6i+S7tu+8jOWQpuWImeWPr+iDveW9seWTjem8oOagh+aLlumAieWKn+iDvVxyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB0aGlzLm1vdmVDdXJzb3IgPSB0cnVlO1xyXG4gICAgICBjb25zdCBwb3NYID0gZXZlbnQubW92ZW1lbnRYO1xyXG4gICAgICBjb25zdCBwb3NZID0gZXZlbnQubW92ZW1lbnRZO1xyXG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5kcmFnQm91bmRhcnkuZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBjb25zdCBsZWZ0ID0gcmVjdC54IC0gdGhpcy5kcmFnQm91bmRhcnkuYm94UmVjdC54ICsgcG9zWDtcclxuICAgICAgY29uc3QgdG9wID0gcmVjdC55IC0gdGhpcy5kcmFnQm91bmRhcnkuYm94UmVjdC55ICsgcG9zWTtcclxuICAgICAgY29uc3QgaXNMZWZ0ID0gbGVmdCA8IHRoaXMuZHJhZ0JvdW5kYXJ5Lm1pbkxlZnQ7XHJcbiAgICAgIGNvbnN0IGlzUmlnaHQgPSBsZWZ0ID4gdGhpcy5kcmFnQm91bmRhcnkubWF4TGVmdDtcclxuICAgICAgY29uc3QgaXNUb3AgPSB0b3AgPCB0aGlzLmRyYWdCb3VuZGFyeS5taW5Ub3A7XHJcbiAgICAgIGNvbnN0IGlzQm90dG9tID0gdG9wID4gdGhpcy5kcmFnQm91bmRhcnkubWF4VG9wO1xyXG4gICAgICBjb25zdCBsZWZ0UmVzdWx0ID0gaXNMZWZ0ID8gdGhpcy5kcmFnQm91bmRhcnkubWluTGVmdCA6IGxlZnQ7XHJcbiAgICAgIGNvbnN0IHRvcFJlc3VsdCA9IGlzVG9wID8gdGhpcy5kcmFnQm91bmRhcnkubWluVG9wIDogdG9wO1xyXG4gICAgICB0aGlzLmRyYWdCb3VuZGFyeS5kb20uc3R5bGUubGVmdCA9IGAke2lzUmlnaHQgPyB0aGlzLmRyYWdCb3VuZGFyeS5tYXhMZWZ0IDogbGVmdFJlc3VsdH1weGA7XHJcbiAgICAgIHRoaXMuZHJhZ0JvdW5kYXJ5LmRvbS5zdHlsZS50b3AgPSBgJHtpc0JvdHRvbSA/IHRoaXMuZHJhZ0JvdW5kYXJ5Lm1heFRvcCA6IHRvcFJlc3VsdH1weGA7XHJcbiAgICAgIC8vIOWmguWIsOi+vui+ueeVjOmHiuaUvuaLluaLveWKqOS9nO+8jOmBv+WFjem8oOagh+WBj+enu+i+g+Wkp+i3neemu+WQjui/lOWbnuS4u+inhueql+S7jeWPr+aLluaLvVxyXG4gICAgICBpZiAoW2lzTGVmdCwgaXNSaWdodCwgaXNUb3AsIGlzQm90dG9tXS5pbmNsdWRlcyh0cnVlKSkge1xyXG4gICAgICAgIHRoaXMub25Nb3VzZVVwKCk7XHJcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdlxuICBjbGFzcz1cImRldnVpLWJhY2t0b3BcIlxuICBbbmdTdHlsZV09XCJ7XG4gICAgZGlzcGxheTogaXNWaXNpYmxlID8gJ2Jsb2NrJyA6ICdub25lJyxcbiAgICBib3R0b206IGJvdHRvbSxcbiAgICByaWdodDogcmlnaHQsXG4gICAgY3Vyc29yOiBtb3ZlQ3Vyc29yICYmIGRyYWdnYWJsZSA/ICdtb3ZlJyA6ICdwb2ludGVyJ1xuICB9XCJcbiAgKGNsaWNrKT1cImdvVG9wKClcIlxuPlxuICA8ZGl2IGNsYXNzPVwiZGV2dWktYmFja3RvcC1kcmFnLWhhbmRsZVwiIChtb3VzZWRvd24pPVwibW91c2Vkb3duRXZlbnQoJGV2ZW50KVwiIChtb3VzZWxlYXZlKT1cIm1vdXNlbGVhdmVFdmVudCgpXCI+XG4gICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlID8gY3VzdG9tVGVtcGxhdGUgOiBkZWZhdWx0XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHQ+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGV2dWktYmFja3RvcC1jb250ZW50XCI+XG4gICAgICAgIDxzdmdcbiAgICAgICAgICB3aWR0aD1cIjE2cHhcIlxuICAgICAgICAgIGhlaWdodD1cIjE2cHhcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuICAgICAgICAgIHZlcnNpb249XCIxLjFcIlxuICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICAgIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICAgID5cbiAgICAgICAgICA8ZyBzdHJva2U9XCJub25lXCIgc3Ryb2tlLXdpZHRoPVwiMVwiIGZpbGw9XCJub25lXCIgZmlsbC1ydWxlPVwiZXZlbm9kZFwiPlxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgZD1cIk04LjcxMzM1OTMxLDE1LjI4NjUyOTcgQzguNjExNzk2ODMsMTYuMjA5MDYwOSA3LjMyMjkzNzU4LDE2LjEyNjc5NTMgNy4yNzMwNDY5NSwxNS4yODY1Mjk3IEM3LjI3MTc1MDA4LDE0LjY0NzUxNDIgNy4yNzE3NTAwOCw1LjI2NDc5NjM2IDcuMjcxNzUwMDgsNS4yNjQ3OTYzNiBMMi44MzY3NTA1Miw5LjU0NTQ4MzQ0IEMyLjE0MTg1OTk1LDEwLjE0NDA2MTUgMS4zMTQzMjg4LDkuMTg3MzExNTkgMS44MzEzNTk5OCw4LjU1NzczMzUzIEMzLjc5NTU3ODU1LDYuNjUzMTA4NzIgNy4zMjAyNjU3LDMuMjQ1MTU1OTIgNy40MDE3OTY5NCwzLjE2NjMyNzgxIEM3LjcyNjk2ODc4LDIuODEzMDYyMjIgOC4yMzg4NzQ5OCwyLjc5NDc2NTM0IDguNTg0OTUzMDgsMy4xNjYzMjc4MSBDOS4yMzE5MzczOSwzLjc5MTkyMTUgMTQuMDMzNDA1Nyw4LjQyMTQ2NzkyIDE0LjE3OTE1NTcsOC41ODgwNDYwMyBDMTQuNjY2MTQsOS4xOTMzODk3MiAxMy44Nzg3ODA3LDEwLjA4OTIwMjEgMTMuMjA2NjA4OSw5LjU4NDUxNDY5IEMxMy4wMzI5NjgzLDkuNDM3MTcwOTUgOC43MTQ2ODc0NCw1LjI2NDYyNDQ4IDguNzE0Njg3NDQsNS4yNjQ2MjQ0OCBMOC43MTMzNTkzMSwxNS4yODY1Mjk3IFogTTEuODE4Njg4MTEsLTguNTQ4NzE3MjllLTE0IEwxNC4xMDc1NjE5LC04LjU0ODcxNzI5ZS0xNCBMMTQuMTA3NTYxOSwxLjM5NTA5MzYxIEwxLjgxODY4ODExLDEuMzk1MDkzNjEgTDEuODE4Njg4MTEsLTguNTQ4NzE3MjllLTE0IFpcIlxuICAgICAgICAgICAgICBmaWxsPVwiI0ZGRkZGRlwiXG4gICAgICAgICAgICAgIGZpbGwtcnVsZT1cIm5vbnplcm9cIlxuICAgICAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgICA8L2c+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==