ngx-bimplus-components 0.0.83 → 0.0.84-draggable
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/languages/strings_de.json +3 -36
- package/assets/languages/strings_en.json +2 -3
- package/assets/languages/strings_us.json +3 -62
- package/esm2022/lib/components/bimplus-floating-bar/bimplus-floating-bar.component.mjs +65 -9
- package/esm2022/lib/components/bimplus-floating-bar-body/bimplus-floating-bar-body.component.mjs +17 -6
- package/esm2022/lib/components/bimplus-floating-bar-dragger/bimplus-floating-bar-dragger.component.mjs +16 -12
- package/esm2022/lib/components/bimplus-floating-bar-header-content/bimplus-floating-bar-header-content.component.mjs +20 -12
- package/esm2022/lib/components/bimplus-floating-bar-header-logo/bimplus-floating-bar-header-logo.component.mjs +26 -16
- package/esm2022/lib/components/bimplus-floating-bar-hide-objects/bimplus-floating-bar-hide-objects.component.mjs +16 -51
- package/esm2022/lib/components/bimplus-floating-bar-isolation-objects/bimplus-floating-bar-isolation-objects.component.mjs +12 -36
- package/esm2022/lib/components/bimplus-floating-bar-project-navigator/bimplus-floating-bar-project-navigator.component.mjs +18 -37
- package/esm2022/lib/components/bimplus-main-menu/bimplus-main-menu.component.mjs +12 -3
- package/esm2022/lib/components/bimplus-navbar/bimplus-navbar.component.mjs +3 -3
- package/esm2022/lib/components/bimplus-project-menu/bimplus-project-menu.component.mjs +9 -7
- package/esm2022/lib/components/bimplus-tool-hub/bimplus-tool-hub.component.mjs +53 -36
- package/esm2022/lib/directives/draggable.directive.mjs +8 -2
- package/esm2022/lib/directives/resizable.directive.mjs +290 -0
- package/esm2022/lib/services/layout-manager.service.mjs +245 -43
- package/esm2022/lib/services/local-storage.service.mjs +70 -0
- package/esm2022/lib/services/resize-observer.service.mjs +34 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ngx-bimplus-components.mjs +954 -332
- package/fesm2022/ngx-bimplus-components.mjs.map +1 -1
- package/lib/components/bimplus-floating-bar/bimplus-floating-bar.component.d.ts +22 -4
- package/lib/components/bimplus-floating-bar-body/bimplus-floating-bar-body.component.d.ts +8 -3
- package/lib/components/bimplus-floating-bar-dragger/bimplus-floating-bar-dragger.component.d.ts +6 -3
- package/lib/components/bimplus-floating-bar-header-content/bimplus-floating-bar-header-content.component.d.ts +6 -3
- package/lib/components/bimplus-floating-bar-header-logo/bimplus-floating-bar-header-logo.component.d.ts +10 -6
- package/lib/components/bimplus-floating-bar-hide-objects/bimplus-floating-bar-hide-objects.component.d.ts +10 -12
- package/lib/components/bimplus-floating-bar-isolation-objects/bimplus-floating-bar-isolation-objects.component.d.ts +6 -9
- package/lib/components/bimplus-floating-bar-project-navigator/bimplus-floating-bar-project-navigator.component.d.ts +6 -8
- package/lib/components/bimplus-main-menu/bimplus-main-menu.component.d.ts +4 -1
- package/lib/components/bimplus-project-menu/bimplus-project-menu.component.d.ts +3 -3
- package/lib/components/bimplus-tool-hub/bimplus-tool-hub.component.d.ts +18 -11
- package/lib/directives/draggable.directive.d.ts +2 -1
- package/lib/directives/resizable.directive.d.ts +80 -0
- package/lib/services/layout-manager.service.d.ts +60 -3
- package/lib/services/local-storage.service.d.ts +18 -0
- package/lib/services/resize-observer.service.d.ts +12 -0
- package/package.json +2 -2
- package/public-api.d.ts +1 -0
|
@@ -9,6 +9,7 @@ export class DraggableDirective {
|
|
|
9
9
|
this.wasDragging = false;
|
|
10
10
|
this.isMouseDown = false;
|
|
11
11
|
this.dragging = new EventEmitter();
|
|
12
|
+
this.dragEnd = new EventEmitter();
|
|
12
13
|
this.clicked = new EventEmitter();
|
|
13
14
|
}
|
|
14
15
|
onMouseMove(event) {
|
|
@@ -31,6 +32,9 @@ export class DraggableDirective {
|
|
|
31
32
|
this.oldY = event.clientY;
|
|
32
33
|
}
|
|
33
34
|
onMouseUp() {
|
|
35
|
+
if (this.isDragging || this.isMouseDown) {
|
|
36
|
+
fireEvent(this, "dragEnd", ['$event']);
|
|
37
|
+
}
|
|
34
38
|
this.isDragging = false;
|
|
35
39
|
this.isMouseDown = false;
|
|
36
40
|
}
|
|
@@ -46,7 +50,7 @@ export class DraggableDirective {
|
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: DraggableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
49
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.10", type: DraggableDirective, isStandalone: true, selector: "[libDraggable]", outputs: { dragging: "dragging", clicked: "clicked" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp($event)", "mousedown": "onMouseDown($event)", "click": "onMouseClick($event)" } }, ngImport: i0 }); }
|
|
53
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.10", type: DraggableDirective, isStandalone: true, selector: "[libDraggable]", outputs: { dragging: "dragging", dragEnd: "dragEnd", clicked: "clicked" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp($event)", "mousedown": "onMouseDown($event)", "click": "onMouseClick($event)" } }, ngImport: i0 }); }
|
|
50
54
|
}
|
|
51
55
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: DraggableDirective, decorators: [{
|
|
52
56
|
type: Directive,
|
|
@@ -56,6 +60,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImpo
|
|
|
56
60
|
}]
|
|
57
61
|
}], propDecorators: { dragging: [{
|
|
58
62
|
type: Output
|
|
63
|
+
}], dragEnd: [{
|
|
64
|
+
type: Output
|
|
59
65
|
}], clicked: [{
|
|
60
66
|
type: Output
|
|
61
67
|
}], onMouseMove: [{
|
|
@@ -71,4 +77,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImpo
|
|
|
71
77
|
type: HostListener,
|
|
72
78
|
args: ['click', ['$event']]
|
|
73
79
|
}] } });
|
|
74
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1iaW1wbHVzLWNvbXBvbmVudHMvc3JjL2xpYi9kaXJlY3RpdmVzL2RyYWdnYWJsZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7O0FBTTNDLE1BQU0sT0FBTyxrQkFBa0I7SUFKL0I7UUFNRSxTQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ1QsU0FBSSxHQUFHLENBQUMsQ0FBQztRQUNULGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFHcEIsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFtQixDQUFDO1FBRy9DLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBYyxDQUFDO1FBR3pDLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBYyxDQUFDO0tBaUQxQztJQTlDQyxXQUFXLENBQUMsS0FBaUI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNYLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFM0MsSUFBRyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUMsQ0FBQztZQUNuQixJQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFDLENBQUM7Z0JBQy9DLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztZQUMxQixDQUFDO2lCQUFJLENBQUM7Z0JBQ0osT0FBTztZQUNULENBQUM7UUFDSCxDQUFDO1FBQ0QsU0FBUyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxNQUFNLEVBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUU3QyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDMUIsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzVCLENBQUM7SUFHRCxTQUFTO1FBQ1AsSUFBRyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUMsQ0FBQztZQUN0QyxTQUFTLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQzNCLENBQUM7SUFHRCxXQUFXLENBQUMsS0FBaUI7UUFDM0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDekIsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUM1QixDQUFDO0lBR0QsWUFBWSxDQUFDLEtBQWlCO1FBQzVCLElBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFDLENBQUM7WUFDcEIsU0FBUyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7K0dBOURVLGtCQUFrQjttR0FBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUo5QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs4QkFVQyxRQUFRO3NCQURQLE1BQU07Z0JBSVAsT0FBTztzQkFETixNQUFNO2dCQUlQLE9BQU87c0JBRE4sTUFBTTtnQkFJUCxXQUFXO3NCQURWLFlBQVk7dUJBQUMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBd0I5QyxTQUFTO3NCQURSLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBVTVDLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBU3JDLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEhvc3RMaXN0ZW5lciwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZmlyZUV2ZW50IH0gZnJvbSAnLi4vdXRpbHMvdXRpbHMnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbbGliRHJhZ2dhYmxlXScsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRHJhZ2dhYmxlRGlyZWN0aXZlIHtcclxuXHJcbiAgb2xkWCA9IDA7XHJcbiAgb2xkWSA9IDA7XHJcbiAgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gIHdhc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgaXNNb3VzZURvd24gPSBmYWxzZTtcclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgZHJhZ2dpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPFtudW1iZXIsbnVtYmVyXT4oKTtcclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgZHJhZ0VuZCA9IG5ldyBFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4oKTtcclxuXHJcbiAgQE91dHB1dCgpXHJcbiAgY2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4oKTtcclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlTW92ZShldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcgJiYgIXRoaXMuaXNNb3VzZURvd24pIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZGVsdGFYID0gKGV2ZW50LmNsaWVudFggLSB0aGlzLm9sZFgpO1xyXG4gICAgY29uc3QgZGVsdGFZID0gKGV2ZW50LmNsaWVudFkgLSB0aGlzLm9sZFkpO1xyXG5cclxuICAgIGlmKCF0aGlzLmlzRHJhZ2dpbmcpe1xyXG4gICAgICBpZihNYXRoLmFicyhkZWx0YVgpID4gMiB8fCBNYXRoLmFicyhkZWx0YVkpID4gMil7XHJcbiAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLndhc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBmaXJlRXZlbnQodGhpcywgXCJkcmFnZ2luZ1wiLCBbZGVsdGFYLGRlbHRhWV0pO1xyXG5cclxuICAgIHRoaXMub2xkWCA9IGV2ZW50LmNsaWVudFg7XHJcbiAgICB0aGlzLm9sZFkgPSBldmVudC5jbGllbnRZO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2V1cCcsIFsnJGV2ZW50J10pXHJcbiAgb25Nb3VzZVVwKCkge1xyXG4gICAgaWYodGhpcy5pc0RyYWdnaW5nIHx8IHRoaXMuaXNNb3VzZURvd24pe1xyXG4gICAgICBmaXJlRXZlbnQodGhpcywgXCJkcmFnRW5kXCIsIFsnJGV2ZW50J10pO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICB0aGlzLmlzTW91c2VEb3duID0gZmFsc2U7ICAgIFxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vkb3duJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgdGhpcy5pc01vdXNlRG93biA9IHRydWU7XHJcbiAgICB0aGlzLndhc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICB0aGlzLm9sZFggPSBldmVudC5jbGllbnRYO1xyXG4gICAgdGhpcy5vbGRZID0gZXZlbnQuY2xpZW50WTsgICAgXHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgb25Nb3VzZUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZighdGhpcy53YXNEcmFnZ2luZyl7XHJcbiAgICAgIGZpcmVFdmVudCh0aGlzLCBcImNsaWNrZWRcIiwgZXZlbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn1cclxuIl19
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
//import { Directive, ElementRef , HostListener, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { Directive, Output, EventEmitter } from '@angular/core';
|
|
3
|
+
import { fireEvent } from '../utils/utils';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../services/layout-manager.service";
|
|
6
|
+
import * as i2 from "../services/resize-observer.service";
|
|
7
|
+
export class ResizableDirective {
|
|
8
|
+
constructor(elementRef, layoutManagerService, resizeObserverService) {
|
|
9
|
+
this.elementRef = elementRef;
|
|
10
|
+
this.layoutManagerService = layoutManagerService;
|
|
11
|
+
this.resizeObserverService = resizeObserverService;
|
|
12
|
+
this.resizeContactPointX = 0;
|
|
13
|
+
this.resizeContactPointY = 0;
|
|
14
|
+
this.resizableElements = [];
|
|
15
|
+
this.resizeEnabled = true;
|
|
16
|
+
this.resizeStarted = false;
|
|
17
|
+
this.actResizeStrategy = "se";
|
|
18
|
+
this.resizedEnd = new EventEmitter();
|
|
19
|
+
// list of resizers, resizers are specified by class name
|
|
20
|
+
this.resizersList = [
|
|
21
|
+
{ className: "resizer-nw", resizeStrategy: "nw" },
|
|
22
|
+
{ className: "resizer-n", resizeStrategy: "n" },
|
|
23
|
+
{ className: "resizer-ne", resizeStrategy: "ne" },
|
|
24
|
+
{ className: "resizer-e", resizeStrategy: "e" },
|
|
25
|
+
{ className: "resizer-se", resizeStrategy: "se" },
|
|
26
|
+
{ className: "resizer-s", resizeStrategy: "s" },
|
|
27
|
+
{ className: "resizer-sw", resizeStrategy: "sw" },
|
|
28
|
+
{ className: "resizer-w", resizeStrategy: "w" }
|
|
29
|
+
];
|
|
30
|
+
this._element = elementRef.nativeElement;
|
|
31
|
+
this.layoutManagerService = layoutManagerService;
|
|
32
|
+
this.resizeStart = (event) => {
|
|
33
|
+
//get mouse/finger X Y positions
|
|
34
|
+
event.stopPropagation();
|
|
35
|
+
if (this.resizeStarted) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.resizeStarted = true;
|
|
39
|
+
const touchList = event.targetTouches ? event.targetTouches : [];
|
|
40
|
+
const clientX = event.type === 'touchstart' ? touchList[0]?.clientX : event.clientX;
|
|
41
|
+
const clientY = event.type === 'touchstart' ? touchList[0]?.clientY : event.clientY;
|
|
42
|
+
this.resizeContactPointX = clientX;
|
|
43
|
+
this.resizeContactPointY = clientY;
|
|
44
|
+
this.openDocumentListenersResize();
|
|
45
|
+
this.setupResizeStrategy(event);
|
|
46
|
+
};
|
|
47
|
+
/**--------------------------------------------------------------------------
|
|
48
|
+
* calcuates and sets the new position
|
|
49
|
+
--------------------------------------------------------------------------*/
|
|
50
|
+
this.resizeInProgress = (event) => {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
event.stopPropagation();
|
|
53
|
+
//get mouse/finger X Y positions
|
|
54
|
+
const touchList = event.targetTouches ? event.targetTouches : [];
|
|
55
|
+
const clientX = event.type === 'touchmove' ? touchList[0]?.clientX : event.clientX;
|
|
56
|
+
const clientY = event.type === 'touchmove' ? touchList[0]?.clientY : event.clientY;
|
|
57
|
+
//const clientX = (event as MouseEvent).clientX;
|
|
58
|
+
//const clientY = (event as MouseEvent).clientY;
|
|
59
|
+
const moved = this.resizeFromTo(this._element, this.resizeContactPointX, this.resizeContactPointY, clientX, clientY, this.actResizeStrategy);
|
|
60
|
+
if (moved) {
|
|
61
|
+
this.resizeContactPointX = clientX;
|
|
62
|
+
this.resizeContactPointY = clientY;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.boundResizeStart = this.resizeStart.bind(this);
|
|
66
|
+
this.boundResizeInProgress = this.resizeInProgress.bind(this);
|
|
67
|
+
this.boundResizeEnd = this.resizeEnd.bind(this);
|
|
68
|
+
this.resizeInProgress.bind(this);
|
|
69
|
+
this.setResizers(this._element);
|
|
70
|
+
}
|
|
71
|
+
ngOnInit() {
|
|
72
|
+
this.boundResizeStart = this.resizeStart.bind(this);
|
|
73
|
+
this.boundResizeInProgress = this.resizeInProgress.bind(this);
|
|
74
|
+
this.boundResizeEnd = this.resizeEnd.bind(this);
|
|
75
|
+
}
|
|
76
|
+
ngOnDestroy() {
|
|
77
|
+
this.closeAllListenersResize();
|
|
78
|
+
}
|
|
79
|
+
resizeEnd() {
|
|
80
|
+
//this.closeDocumentListenersResize();
|
|
81
|
+
if (!this.resizeStarted) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.resizeStarted = false;
|
|
85
|
+
this.closeAllListenersResize();
|
|
86
|
+
this.openElementListenersResize();
|
|
87
|
+
fireEvent(this, "resizedEnd", ['$event']);
|
|
88
|
+
}
|
|
89
|
+
_getViewRect() {
|
|
90
|
+
const view = document.getElementById('#containerView'); // we should get here the parent object selector as input parameter
|
|
91
|
+
if (view) {
|
|
92
|
+
return view.getBoundingClientRect();
|
|
93
|
+
}
|
|
94
|
+
return new DOMRect(0, 0, 0, 0);
|
|
95
|
+
}
|
|
96
|
+
/**--------------------------------------------------------------------------
|
|
97
|
+
* find if rectangle 1 is inside rectangle 2
|
|
98
|
+
--------------------------------------------------------------------------*/
|
|
99
|
+
isInsideRect(rect1, rect2) {
|
|
100
|
+
if (!rect1 || !rect2) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const rect1Inside = rect2.left <= rect1.left
|
|
104
|
+
&& rect2.top <= rect1.top
|
|
105
|
+
&& rect2.right >= rect1.right
|
|
106
|
+
&& rect2.bottom >= rect1.bottom;
|
|
107
|
+
return rect1Inside;
|
|
108
|
+
}
|
|
109
|
+
/**--------------------------------------------------------------------------
|
|
110
|
+
* resize rectangle by x, y
|
|
111
|
+
--------------------------------------------------------------------------*/
|
|
112
|
+
_resizeRectangle(rect, resizeX, resizeY, resizeStrategy) {
|
|
113
|
+
if (!rect) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (['nw', 'w', 'sw'].includes(resizeStrategy)) {
|
|
117
|
+
rect.x += resizeX;
|
|
118
|
+
resizeX = resizeX * -1;
|
|
119
|
+
}
|
|
120
|
+
if (['nw', 'n', 'ne'].includes(resizeStrategy)) {
|
|
121
|
+
rect.y += resizeY;
|
|
122
|
+
resizeY = resizeY * -1;
|
|
123
|
+
}
|
|
124
|
+
if (typeof (resizeX) === 'number' && !['n', 's'].includes(resizeStrategy)) {
|
|
125
|
+
rect.width += resizeX;
|
|
126
|
+
}
|
|
127
|
+
if (typeof (resizeY) === 'number' && !['w', 'e'].includes(resizeStrategy)) {
|
|
128
|
+
rect.height += resizeY;
|
|
129
|
+
}
|
|
130
|
+
return rect;
|
|
131
|
+
}
|
|
132
|
+
_maxHeightReset(obj, elementRect) {
|
|
133
|
+
this.resizeFromTo(obj, elementRect.right, elementRect.bottom, elementRect.left, elementRect.top, "se");
|
|
134
|
+
}
|
|
135
|
+
/*--------------------------------------------------------------------
|
|
136
|
+
* resize object from {x,y} to {x,y} based on resize strategy
|
|
137
|
+
--------------------------------------------------------------------------*/
|
|
138
|
+
resizeFromTo(obj, fromX, fromY, toX, toY, resizeStrategy) {
|
|
139
|
+
const posXDelta = toX - fromX;
|
|
140
|
+
const posYDelta = toY - fromY;
|
|
141
|
+
const element = obj ? obj : this._element;
|
|
142
|
+
const elementRect = element.getBoundingClientRect();
|
|
143
|
+
//const viewRect = this._getViewRect();
|
|
144
|
+
const viewRect = this.resizeObserverService.getParentAppRect();
|
|
145
|
+
let checkBoundaries = true;
|
|
146
|
+
resizeStrategy = resizeStrategy || "se";
|
|
147
|
+
//if the object is outside the view rect because it's bigger, do not check boundaries,
|
|
148
|
+
//allow moving outside the view rect
|
|
149
|
+
if (this.isInsideRect(elementRect, viewRect) === false) {
|
|
150
|
+
checkBoundaries = false;
|
|
151
|
+
}
|
|
152
|
+
this._resizeRectangle(elementRect, posXDelta, posYDelta, resizeStrategy);
|
|
153
|
+
if (checkBoundaries && this.isInsideRect(elementRect, viewRect) === false) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const computedStyle = window.getComputedStyle(element);
|
|
157
|
+
let top = parseInt(computedStyle.top, 10);
|
|
158
|
+
let left = parseInt(computedStyle.left, 10);
|
|
159
|
+
let width = parseInt(computedStyle.width, 10);
|
|
160
|
+
let height = parseInt(computedStyle.height, 10);
|
|
161
|
+
if (['nw', 'w', 'sw'].includes(resizeStrategy)) {
|
|
162
|
+
left = left + posXDelta;
|
|
163
|
+
}
|
|
164
|
+
if (['nw', 'n', 'ne'].includes(resizeStrategy)) {
|
|
165
|
+
top = top + posYDelta;
|
|
166
|
+
}
|
|
167
|
+
if (!['n', 's'].includes(resizeStrategy)) {
|
|
168
|
+
width = elementRect.width;
|
|
169
|
+
}
|
|
170
|
+
if (viewRect.height < elementRect.height) {
|
|
171
|
+
this._maxHeightReset(element, elementRect);
|
|
172
|
+
}
|
|
173
|
+
else if (!['w', 'e'].includes(resizeStrategy)) {
|
|
174
|
+
height = elementRect.height;
|
|
175
|
+
}
|
|
176
|
+
element.style.top = top + 'px';
|
|
177
|
+
element.style.left = left + 'px';
|
|
178
|
+
element.style.width = width + 'px';
|
|
179
|
+
element.style.height = height + 'px';
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
/**--------------------------------------------------------------------------
|
|
183
|
+
* resize start at the layout managaer
|
|
184
|
+
* open document listeners
|
|
185
|
+
--------------------------------------------------------------------------*/
|
|
186
|
+
/**--------------------------------------------------------------------------
|
|
187
|
+
* set the elements used for resizing
|
|
188
|
+
--------------------------------------------------------------------------*/
|
|
189
|
+
setResizers(element) {
|
|
190
|
+
const setResizableElements = () => {
|
|
191
|
+
let resizableElements = [];
|
|
192
|
+
// get dom elements of all resizers
|
|
193
|
+
this.resizersList.forEach(item => {
|
|
194
|
+
const resizeElems = element.getElementsByClassName(item.className);
|
|
195
|
+
if (resizeElems?.length) {
|
|
196
|
+
// set resize strategy in each element so we know in which direction to resize
|
|
197
|
+
const decoratedResizeElems = Array.from(resizeElems).map(elem => {
|
|
198
|
+
const resizableElem = elem;
|
|
199
|
+
resizableElem.resizeStrategy = item.resizeStrategy;
|
|
200
|
+
return resizableElem;
|
|
201
|
+
});
|
|
202
|
+
// add it to list of all resizers
|
|
203
|
+
resizableElements = [...resizableElements, ...decoratedResizeElems];
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.resizableElements = [...resizableElements];
|
|
207
|
+
this.openElementListenersResize();
|
|
208
|
+
};
|
|
209
|
+
setTimeout(() => {
|
|
210
|
+
setResizableElements();
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**--------------------------------------------------------------------------
|
|
214
|
+
* open mousedown, touchstart listeners on all elements allowed for resizing
|
|
215
|
+
--------------------------------------------------------------------------*/
|
|
216
|
+
openElementListenersResize() {
|
|
217
|
+
this.resizableElements.forEach(element => {
|
|
218
|
+
element.addEventListener('mousedown', this.boundResizeStart);
|
|
219
|
+
element.addEventListener('touchstart', this.boundResizeStart);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**--------------------------------------------------------------------------
|
|
223
|
+
* open mouseup, touchend and mousemove, touchmove on document
|
|
224
|
+
--------------------------------------------------------------------------*/
|
|
225
|
+
openDocumentListenersResize() {
|
|
226
|
+
document.addEventListener('mouseup', this.boundResizeEnd);
|
|
227
|
+
document.addEventListener('touchend', this.boundResizeEnd);
|
|
228
|
+
document.addEventListener('mousemove', this.boundResizeInProgress);
|
|
229
|
+
document.addEventListener('touchmove', this.boundResizeInProgress);
|
|
230
|
+
}
|
|
231
|
+
/**--------------------------------------------------------------------------
|
|
232
|
+
* close mouseup, touchend and mousemove, touchmove on document
|
|
233
|
+
--------------------------------------------------------------------------*/
|
|
234
|
+
closeDocumentListenersResize() {
|
|
235
|
+
document.removeEventListener('mousemove', this.boundResizeInProgress);
|
|
236
|
+
document.removeEventListener('touchmove', this.boundResizeInProgress);
|
|
237
|
+
document.removeEventListener('mouseup', this.boundResizeEnd);
|
|
238
|
+
document.removeEventListener('touchend', this.boundResizeEnd);
|
|
239
|
+
}
|
|
240
|
+
/**--------------------------------------------------------------------------
|
|
241
|
+
* close mousedown, touchstart listeners on all elements allowed for resizing
|
|
242
|
+
--------------------------------------------------------------------------*/
|
|
243
|
+
closeElementListenersResize() {
|
|
244
|
+
this.resizableElements.forEach(element => {
|
|
245
|
+
element.removeEventListener('mousedown', this.boundResizeStart);
|
|
246
|
+
element.removeEventListener('touchstart', this.boundResizeStart);
|
|
247
|
+
element.removeEventListener('mousemove', this.boundResizeInProgress);
|
|
248
|
+
element.removeEventListener('touchmove', this.boundResizeInProgress);
|
|
249
|
+
element.removeEventListener('mouseup', this.boundResizeEnd);
|
|
250
|
+
element.removeEventListener('touchend', this.boundResizeEnd);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/**--------------------------------------------------------------------------
|
|
254
|
+
* close all listeners
|
|
255
|
+
--------------------------------------------------------------------------*/
|
|
256
|
+
closeAllListenersResize() {
|
|
257
|
+
this.closeElementListenersResize();
|
|
258
|
+
this.closeDocumentListenersResize();
|
|
259
|
+
}
|
|
260
|
+
/**--------------------------------------------------------------------------
|
|
261
|
+
* setup actual resize strategy
|
|
262
|
+
--------------------------------------------------------------------------*/
|
|
263
|
+
setupResizeStrategy(event) {
|
|
264
|
+
if (!event) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// find on which element resize started so we know in which direction to resize
|
|
268
|
+
let resizeStrategy = "se";
|
|
269
|
+
const resizeSourceElem = event?.target;
|
|
270
|
+
if (resizeSourceElem) {
|
|
271
|
+
const foundElem = this.resizableElements.find(item => item === resizeSourceElem);
|
|
272
|
+
if (foundElem && foundElem.resizeStrategy) {
|
|
273
|
+
resizeStrategy = foundElem?.resizeStrategy;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
this.actResizeStrategy = resizeStrategy;
|
|
277
|
+
}
|
|
278
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: ResizableDirective, deps: [{ token: i0.ElementRef }, { token: i1.LayoutManagerService }, { token: i2.ResizeObserverService }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
279
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.10", type: ResizableDirective, isStandalone: true, selector: "[libResizable]", outputs: { resizedEnd: "resizedEnd" }, ngImport: i0 }); }
|
|
280
|
+
}
|
|
281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: ResizableDirective, decorators: [{
|
|
282
|
+
type: Directive,
|
|
283
|
+
args: [{
|
|
284
|
+
selector: '[libResizable]',
|
|
285
|
+
standalone: true
|
|
286
|
+
}]
|
|
287
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.LayoutManagerService }, { type: i2.ResizeObserverService }], propDecorators: { resizedEnd: [{
|
|
288
|
+
type: Output
|
|
289
|
+
}] } });
|
|
290
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzaXphYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1iaW1wbHVzLWNvbXBvbmVudHMvc3JjL2xpYi9kaXJlY3RpdmVzL3Jlc2l6YWJsZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkZBQTZGO0FBQzdGLE9BQU8sRUFBRSxTQUFTLEVBQWUsTUFBTSxFQUFFLFlBQVksRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFHaEcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBZ0IzQyxNQUFNLE9BQU8sa0JBQWtCO0lBZ0M3QixZQUFvQixVQUFzQixFQUN0QixvQkFBMEMsRUFDMUMscUJBQTJDO1FBRjNDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFzQjtRQUMxQywwQkFBcUIsR0FBckIscUJBQXFCLENBQXNCO1FBakMvRCx3QkFBbUIsR0FBRyxDQUFDLENBQUM7UUFDeEIsd0JBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLHNCQUFpQixHQUFzQixFQUFFLENBQUM7UUFDMUMsa0JBQWEsR0FBUyxJQUFJLENBQUM7UUFDM0Isa0JBQWEsR0FBUyxLQUFLLENBQUM7UUFRNUIsc0JBQWlCLEdBQUssSUFBSSxDQUFDO1FBSTNCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBYyxDQUFDO1FBRzVDLHlEQUF5RDtRQUN6RCxpQkFBWSxHQUFrQjtZQUM1QixFQUFFLFNBQVMsRUFBRyxZQUFZLEVBQUcsY0FBYyxFQUFHLElBQUksRUFBRTtZQUNwRCxFQUFFLFNBQVMsRUFBRyxXQUFXLEVBQUksY0FBYyxFQUFFLEdBQUcsRUFBSTtZQUNwRCxFQUFFLFNBQVMsRUFBRyxZQUFZLEVBQUcsY0FBYyxFQUFFLElBQUksRUFBRztZQUNwRCxFQUFFLFNBQVMsRUFBRyxXQUFXLEVBQUksY0FBYyxFQUFFLEdBQUcs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IjpbIi8vaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmICwgSG9zdExpc3RlbmVyLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYgLCBPdXRwdXQsIEV2ZW50RW1pdHRlciAsIE9uSW5pdCwgT25EZXN0cm95fSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTGF5b3V0TWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9sYXlvdXQtbWFuYWdlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUmVzaXplT2JzZXJ2ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvcmVzaXplLW9ic2VydmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBmaXJlRXZlbnQgfSBmcm9tICcuLi91dGlscy91dGlscyc7XHJcblxyXG5pbnRlcmZhY2UgUmVzaXplckl0ZW0ge1xyXG4gICdjbGFzc05hbWUnIDogc3RyaW5nICxcclxuICAncmVzaXplU3RyYXRlZ3knIDogc3RyaW5nIFxyXG59XHJcblxyXG5pbnRlcmZhY2UgUmVzaXphYmxlRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50e1xyXG4gIHJlc2l6ZVN0cmF0ZWd5Pzogc3RyaW5nO1xyXG59XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICBzZWxlY3RvcjogJ1tsaWJSZXNpemFibGVdJyxcclxuICBzdGFuZGFsb25lOiB0cnVlXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgUmVzaXphYmxlRGlyZWN0aXZlICBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25Jbml0e1xyXG4gIHJlc2l6ZUNvbnRhY3RQb2ludFggPSAwO1xyXG4gIHJlc2l6ZUNvbnRhY3RQb2ludFkgPSAwO1xyXG4gIHJlc2l6YWJsZUVsZW1lbnRzOlJlc2l6YWJsZUVsZW1lbnRbXSA9IFtdO1xyXG4gIHJlc2l6ZUVuYWJsZWQgICAgICAgPSB0cnVlO1xyXG4gIHJlc2l6ZVN0YXJ0ZWQgICAgICAgPSBmYWxzZTtcclxuICByZXNpemVTdGFydCAgICAgOiAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB2b2lkO1xyXG4gIHJlc2l6ZUluUHJvZ3Jlc3M6IChldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpID0+IHZvaWQ7ICBcclxuICBib3VuZFJlc2l6ZVN0YXJ0OiAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB2b2lkO1xyXG4gIGJvdW5kUmVzaXplSW5Qcm9ncmVzczogKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4gdm9pZDtcclxuICBib3VuZFJlc2l6ZUVuZDogKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4gdm9pZDtcclxuICAgXHJcbiAgX2VsZW1lbnQ6SFRNTEVsZW1lbnQ7IFxyXG4gIGFjdFJlc2l6ZVN0cmF0ZWd5ICAgPSBcInNlXCI7XHJcbiAgXHJcblxyXG4gIEBPdXRwdXQoKVxyXG4gIHJlc2l6ZWRFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPE1vdXNlRXZlbnQ+KCk7XHJcblxyXG5cclxuICAvLyBsaXN0IG9mIHJlc2l6ZXJzLCByZXNpemVycyBhcmUgc3BlY2lmaWVkIGJ5IGNsYXNzIG5hbWVcclxuICByZXNpemVyc0xpc3Q6UmVzaXplckl0ZW1bXSA9ICBbIFxyXG4gICAgeyBjbGFzc05hbWUgOiBcInJlc2l6ZXItbndcIiAsIHJlc2l6ZVN0cmF0ZWd5IDogXCJud1wiIH0sXHJcbiAgICB7IGNsYXNzTmFtZSA6IFwicmVzaXplci1uXCIgICwgcmVzaXplU3RyYXRlZ3k6IFwiblwiICAgfSxcclxuICAgIHsgY2xhc3NOYW1lIDogXCJyZXNpemVyLW5lXCIgLCByZXNpemVTdHJhdGVneTogXCJuZVwiICB9LFxyXG4gICAgeyBjbGFzc05hbWUgOiBcInJlc2l6ZXItZVwiICAsIHJlc2l6ZVN0cmF0ZWd5OiBcImVcIiAgIH0sXHJcbiAgICB7IGNsYXNzTmFtZSA6IFwicmVzaXplci1zZVwiICwgcmVzaXplU3RyYXRlZ3k6IFwic2VcIiAgfSxcclxuICAgIHsgY2xhc3NOYW1lIDogXCJyZXNpemVyLXNcIiAgLCByZXNpemVTdHJhdGVneTogXCJzXCIgICB9LFxyXG4gICAgeyBjbGFzc05hbWUgOiBcInJlc2l6ZXItc3dcIiAsIHJlc2l6ZVN0cmF0ZWd5OiBcInN3XCIgIH0sXHJcbiAgICB7IGNsYXNzTmFtZSA6IFwicmVzaXplci13XCIgICwgcmVzaXplU3RyYXRlZ3k6IFwid1wiICAgfVxyXG4gIF07XHJcbiAgXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgbGF5b3V0TWFuYWdlclNlcnZpY2U6IExheW91dE1hbmFnZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXJTZXJ2aWNlOlJlc2l6ZU9ic2VydmVyU2VydmljZSkgeyAgICAgICAgICAgICAgXHJcbiAgICBcclxuICAgIHRoaXMuX2VsZW1lbnQgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLmxheW91dE1hbmFnZXJTZXJ2aWNlID0gbGF5b3V0TWFuYWdlclNlcnZpY2U7XHJcbiAgICBcclxuICAgIHRoaXMucmVzaXplU3RhcnQgPSAgIChldmVudDpNb3VzZUV2ZW50fFRvdWNoRXZlbnQpID0+IHtcclxuICAgICAgLy9nZXQgbW91c2UvZmluZ2VyIFggWSBwb3NpdGlvbnNcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIGlmKHRoaXMucmVzaXplU3RhcnRlZCl7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucmVzaXplU3RhcnRlZCA9IHRydWU7XHJcbiAgICAgIGNvbnN0IHRvdWNoTGlzdCA9IChldmVudCBhcyBUb3VjaEV2ZW50KS50YXJnZXRUb3VjaGVzPyAoZXZlbnQgYXMgVG91Y2hFdmVudCkudGFyZ2V0VG91Y2hlczogW107XHJcbiAgICAgIGNvbnN0IGNsaWVudFggPSBldmVudC50eXBlID09PSAndG91Y2hzdGFydCcgPyB0b3VjaExpc3RbMF0/LmNsaWVudFggOiAoZXZlbnQgYXMgTW91c2VFdmVudCkuY2xpZW50WDtcclxuICAgICAgY29uc3QgY2xpZW50WSA9IGV2ZW50LnR5cGUgPT09ICd0b3VjaHN0YXJ0JyA/IHRvdWNoTGlzdFswXT8uY2xpZW50WSA6IChldmVudCBhcyBNb3VzZUV2ZW50KS5jbGllbnRZO1xyXG4gICAgICB0aGlzLnJlc2l6ZUNvbnRhY3RQb2ludFggPSAoY2xpZW50WCBhcyBudW1iZXIpO1xyXG4gICAgICB0aGlzLnJlc2l6ZUNvbnRhY3RQb2ludFkgPSAoY2xpZW50WSBhcyBudW1iZXIpO1xyXG4gICAgICB0aGlzLm9wZW5Eb2N1bWVudExpc3RlbmVyc1Jlc2l6ZSgpOyAgICAgIFxyXG4gICAgICB0aGlzLnNldHVwUmVzaXplU3RyYXRlZ3koZXZlbnQpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICogY2FsY3VhdGVzIGFuZCBzZXRzIHRoZSBuZXcgcG9zaXRpb25cclxuICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cclxuICAgIHRoaXMucmVzaXplSW5Qcm9ncmVzcyA9IChldmVudDpNb3VzZUV2ZW50fFRvdWNoRXZlbnQpID0+IHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblxyXG4gICAgICAvL2dldCBtb3VzZS9maW5nZXIgWCBZIHBvc2l0aW9uc1xyXG4gICAgICBjb25zdCB0b3VjaExpc3QgPSAoZXZlbnQgYXMgVG91Y2hFdmVudCkudGFyZ2V0VG91Y2hlcyA/IChldmVudCBhcyBUb3VjaEV2ZW50KS50YXJnZXRUb3VjaGVzOiBbXTtcclxuICAgICAgY29uc3QgY2xpZW50WCA9IGV2ZW50LnR5cGUgPT09ICd0b3VjaG1vdmUnID8gdG91Y2hMaXN0WzBdPy5jbGllbnRYIDogKGV2ZW50IGFzIE1vdXNlRXZlbnQpLmNsaWVudFg7XHJcbiAgICAgIGNvbnN0IGNsaWVudFkgPSBldmVudC50eXBlID09PSAndG91Y2htb3ZlJyA/IHRvdWNoTGlzdFswXT8uY2xpZW50WSA6IChldmVudCBhcyBNb3VzZUV2ZW50KS5jbGllbnRZO1xyXG4gICAgICAvL2NvbnN0IGNsaWVudFggPSAgKGV2ZW50IGFzIE1vdXNlRXZlbnQpLmNsaWVudFg7XHJcbiAgICAgIC8vY29uc3QgY2xpZW50WSA9ICAoZXZlbnQgYXMgTW91c2VFdmVudCkuY2xpZW50WTtcclxuXHJcbiAgICAgIGNvbnN0IG1vdmVkID0gdGhpcy5yZXNpemVGcm9tVG8odGhpcy5fZWxlbWVudCx0aGlzLnJlc2l6ZUNvbnRhY3RQb2ludFgsIHRoaXMucmVzaXplQ29udGFjdFBvaW50WSxjbGllbnRYIGFzIG51bWJlcixjbGllbnRZIGFzIG51bWJlciwgdGhpcy5hY3RSZXNpemVTdHJhdGVneSk7XHJcbiAgICAgIGlmKG1vdmVkKSB7XHJcbiAgICAgICAgdGhpcy5yZXNpemVDb250YWN0UG9pbnRYID0gKGNsaWVudFggYXMgbnVtYmVyKTtcclxuICAgICAgICB0aGlzLnJlc2l6ZUNvbnRhY3RQb2ludFkgPSAoY2xpZW50WSBhcyBudW1iZXIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLmJvdW5kUmVzaXplU3RhcnQgPSB0aGlzLnJlc2l6ZVN0YXJ0LmJpbmQodGhpcyk7XHJcbiAgICB0aGlzLmJvdW5kUmVzaXplSW5Qcm9ncmVzcyA9IHRoaXMucmVzaXplSW5Qcm9ncmVzcy5iaW5kKHRoaXMpO1xyXG4gICAgdGhpcy5ib3VuZFJlc2l6ZUVuZCA9IHRoaXMucmVzaXplRW5kLmJpbmQodGhpcyk7XHJcbiAgICB0aGlzLnJlc2l6ZUluUHJvZ3Jlc3MuYmluZCh0aGlzKTtcclxuICAgIHRoaXMuc2V0UmVzaXplcnModGhpcy5fZWxlbWVudCk7ICAgICAgICBcclxuICB9XHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmJvdW5kUmVzaXplU3RhcnQgPSB0aGlzLnJlc2l6ZVN0YXJ0LmJpbmQodGhpcyk7XHJcbiAgICB0aGlzLmJvdW5kUmVzaXplSW5Qcm9ncmVzcyA9IHRoaXMucmVzaXplSW5Qcm9ncmVzcy5iaW5kKHRoaXMpO1xyXG4gICAgdGhpcy5ib3VuZFJlc2l6ZUVuZCA9IHRoaXMucmVzaXplRW5kLmJpbmQodGhpcyk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xvc2VBbGxMaXN0ZW5lcnNSZXNpemUoKTsgICAgXHJcbiAgfVxyXG5cclxuICByZXNpemVFbmQoKXsgICBcclxuICAgIC8vdGhpcy5jbG9zZURvY3VtZW50TGlzdGVuZXJzUmVzaXplKCk7XHJcbiAgICBpZighdGhpcy5yZXNpemVTdGFydGVkKXtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfSAgICAgXHJcbiAgICB0aGlzLnJlc2l6ZVN0YXJ0ZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuY2xvc2VBbGxMaXN0ZW5lcnNSZXNpemUoKTsgXHJcbiAgICB0aGlzLm9wZW5FbGVtZW50TGlzdGVuZXJzUmVzaXplKCk7XHJcbiAgICBmaXJlRXZlbnQodGhpcywgXCJyZXNpemVkRW5kXCIsIFsnJGV2ZW50J10pOyAgICBcclxuICB9XHJcbiAgXHJcblxyXG4gIF9nZXRWaWV3UmVjdCgpIHtcclxuICAgIGNvbnN0IHZpZXcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnI2NvbnRhaW5lclZpZXcnKTsgIC8vIHdlIHNob3VsZCBnZXQgaGVyZSB0aGUgcGFyZW50IG9iamVjdCBzZWxlY3RvciBhcyBpbnB1dCBwYXJhbWV0ZXJcclxuICAgIGlmKHZpZXcpe1xyXG4gICAgICByZXR1cm4gdmlldy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgRE9NUmVjdCgwLDAsMCwwKTtcclxuICB9XHJcblxyXG4vKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICogZmluZCBpZiByZWN0YW5nbGUgMSBpcyBpbnNpZGUgcmVjdGFuZ2xlIDJcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgaXNJbnNpZGVSZWN0KHJlY3QxOkRPTVJlY3QsIHJlY3QyOkRPTVJlY3QpIHtcclxuICAgIGlmKCFyZWN0MSB8fCAhcmVjdDIpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmVjdDFJbnNpZGU6Ym9vbGVhbiA9IHJlY3QyLmxlZnQgPD0gcmVjdDEubGVmdFxyXG4gICAgICAgICAgICAgICAgICAmJiByZWN0Mi50b3AgPD0gcmVjdDEudG9wIFxyXG4gICAgICAgICAgICAgICAgICAmJiByZWN0Mi5yaWdodCA+PSByZWN0MS5yaWdodCBcclxuICAgICAgICAgICAgICAgICAgJiYgcmVjdDIuYm90dG9tID49IHJlY3QxLmJvdHRvbTtcclxuXHJcbiAgICByZXR1cm4gcmVjdDFJbnNpZGU7XHJcbiAgfVxyXG4gICAgLyoqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAqIHJlc2l6ZSByZWN0YW5nbGUgYnkgeCwgeVxyXG4gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cclxuICBfcmVzaXplUmVjdGFuZ2xlKHJlY3Q6RE9NUmVjdCwgcmVzaXplWDpudW1iZXIsIHJlc2l6ZVk6bnVtYmVyLCByZXNpemVTdHJhdGVneTpzdHJpbmcpIHtcclxuICAgIGlmKCFyZWN0KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZihbJ253JywndycsICdzdyddLmluY2x1ZGVzKHJlc2l6ZVN0cmF0ZWd5KSkge1xyXG4gICAgICByZWN0LnggKz0gcmVzaXplWDtcclxuICAgICAgcmVzaXplWCA9IHJlc2l6ZVggKiAtMTtcclxuICAgIH1cclxuXHJcbiAgICBpZihbJ253JywnbicsICduZSddLmluY2x1ZGVzKHJlc2l6ZVN0cmF0ZWd5KSkge1xyXG4gICAgICByZWN0LnkgKz0gcmVzaXplWTtcclxuICAgICAgcmVzaXplWSA9IHJlc2l6ZVkgKiAtMTtcclxuICAgIH1cclxuXHJcbiAgICBpZih0eXBlb2YocmVzaXplWCkgPT09ICdudW1iZXInICYmICFbJ24nLCdzJ10uaW5jbHVkZXMocmVzaXplU3RyYXRlZ3kpKSB7XHJcbiAgICAgIHJlY3Qud2lkdGggKz0gcmVzaXplWDtcclxuICAgIH1cclxuXHJcbiAgICBpZih0eXBlb2YocmVzaXplWSkgPT09ICdudW1iZXInICYmICFbJ3cnLCdlJ10uaW5jbHVkZXMocmVzaXplU3RyYXRlZ3kpKSB7XHJcbiAgICAgIHJlY3QuaGVpZ2h0ICs9IHJlc2l6ZVk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlY3Q7XHJcbiAgfVxyXG5cclxuICBfbWF4SGVpZ2h0UmVzZXQob2JqOkhUTUxFbGVtZW50LCBlbGVtZW50UmVjdDpET01SZWN0KSB7ICAgIFxyXG4gICAgdGhpcy5yZXNpemVGcm9tVG8ob2JqLCBlbGVtZW50UmVjdC5yaWdodCwgZWxlbWVudFJlY3QuYm90dG9tLCBlbGVtZW50UmVjdC5sZWZ0LGVsZW1lbnRSZWN0LnRvcCwgXCJzZVwiKTtcclxuICB9XHJcblxyXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAqIHJlc2l6ZSBvYmplY3QgZnJvbSB7eCx5fSB0byB7eCx5fSBiYXNlZCBvbiByZXNpemUgc3RyYXRlZ3lcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgcmVzaXplRnJvbVRvIChvYmo6SFRNTEVsZW1lbnQsIGZyb21YOm51bWJlciwgZnJvbVk6bnVtYmVyLCB0b1g6bnVtYmVyLHRvWTpudW1iZXIsIHJlc2l6ZVN0cmF0ZWd5OnN0cmluZyl7XHJcbiAgICBjb25zdCBwb3NYRGVsdGEgPSB0b1ggLSBmcm9tWDtcclxuICAgIGNvbnN0IHBvc1lEZWx0YSA9IHRvWSAtIGZyb21ZO1xyXG4gICAgY29uc3QgZWxlbWVudCA9IG9iaiA/IG9iaiA6IHRoaXMuX2VsZW1lbnQ7XHJcbiAgICBjb25zdCBlbGVtZW50UmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAvL2NvbnN0IHZpZXdSZWN0ID0gdGhpcy5fZ2V0Vmlld1JlY3QoKTtcclxuICAgIGNvbnN0IHZpZXdSZWN0ID0gdGhpcy5yZXNpemVPYnNlcnZlclNlcnZpY2UuZ2V0UGFyZW50QXBwUmVjdCgpO1xyXG4gICAgXHJcbiAgICBsZXQgY2hlY2tCb3VuZGFyaWVzID0gdHJ1ZTtcclxuXHJcbiAgICByZXNpemVTdHJhdGVneSA9IHJlc2l6ZVN0cmF0ZWd5IHx8IFwic2VcIjtcclxuXHJcbiAgICAvL2lmIHRoZSBvYmplY3QgaXMgb3V0c2lkZSB0aGUgdmlldyByZWN0IGJlY2F1c2UgaXQncyBiaWdnZXIsIGRvIG5vdCBjaGVjayBib3VuZGFyaWVzLFxyXG4gICAgLy9hbGxvdyBtb3Zpbmcgb3V0c2lkZSB0aGUgdmlldyByZWN0XHJcbiAgICBpZih0aGlzLmlzSW5zaWRlUmVjdChlbGVtZW50UmVjdCwgdmlld1JlY3QpID09PSBmYWxzZSkge1xyXG4gICAgICBjaGVja0JvdW5kYXJpZXMgPSBmYWxzZTsgXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fcmVzaXplUmVjdGFuZ2xlKGVsZW1lbnRSZWN0LCBwb3NYRGVsdGEsIHBvc1lEZWx0YSwgcmVzaXplU3RyYXRlZ3kpO1xyXG5cclxuICAgIGlmIChjaGVja0JvdW5kYXJpZXMgJiYgdGhpcy5pc0luc2lkZVJlY3QoZWxlbWVudFJlY3QsIHZpZXdSZWN0KSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGNvbnN0IGNvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcclxuICAgIGxldCB0b3AgPSBwYXJzZUludChjb21wdXRlZFN0eWxlLnRvcCwgMTApO1xyXG4gICAgbGV0IGxlZnQgPSBwYXJzZUludChjb21wdXRlZFN0eWxlLmxlZnQsIDEwKTtcclxuICAgIGxldCB3aWR0aCA9IHBhcnNlSW50KGNvbXB1dGVkU3R5bGUud2lkdGgsIDEwKTtcclxuICAgIGxldCBoZWlnaHQgPSBwYXJzZUludChjb21wdXRlZFN0eWxlLmhlaWdodCwgMTApO1xyXG4gICAgXHJcbiAgICBpZihbJ253JywndycsICdzdyddLmluY2x1ZGVzKHJlc2l6ZVN0cmF0ZWd5KSkge1xyXG4gICAgICAgbGVmdCA9IGxlZnQgKyBwb3NYRGVsdGE7ICAgICAgXHJcbiAgICB9XHJcblxyXG4gICAgaWYoWydudycsJ24nLCAnbmUnXS5pbmNsdWRlcyhyZXNpemVTdHJhdGVneSkpIHtcclxuICAgICAgdG9wID0gdG9wICArICBwb3NZRGVsdGE7ICAgICAgXHJcbiAgICB9XHJcblxyXG4gICAgaWYoIVsnbicsJ3MnXS5pbmNsdWRlcyhyZXNpemVTdHJhdGVneSkpIHtcclxuICAgICAgd2lkdGggPSBlbGVtZW50UmVjdC53aWR0aDtcclxuICAgIH1cclxuICAgIFxyXG4gICAgaWYoIHZpZXdSZWN0LmhlaWdodCA8IGVsZW1lbnRSZWN0LmhlaWdodCApe1xyXG4gICAgICB0aGlzLl9tYXhIZWlnaHRSZXNldChlbGVtZW50LCBlbGVtZW50UmVjdCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmKCFbJ3cnLCdlJ10uaW5jbHVkZXMocmVzaXplU3RyYXRlZ3kpKSB7XHJcbiAgICAgIGhlaWdodCA9IGVsZW1lbnRSZWN0LmhlaWdodDtcclxuICAgIH1cclxuXHJcbiAgICBcclxuICAgIGVsZW1lbnQuc3R5bGUudG9wICAgID0gdG9wICAgKyAncHgnO1xyXG4gICAgZWxlbWVudC5zdHlsZS5sZWZ0ICAgPSBsZWZ0ICArICdweCc7XHJcbiAgICBlbGVtZW50LnN0eWxlLndpZHRoICA9IHdpZHRoICsgJ3B4JztcclxuICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ICA9IGhlaWdodCArICdweCc7XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG4vKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAqIHJlc2l6ZSBzdGFydCBhdCB0aGUgbGF5b3V0IG1hbmFnYWVyXHJcbiAgICogb3BlbiBkb2N1bWVudCBsaXN0ZW5lcnNcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgXHJcbiAgICAvKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAqIHNldCB0aGUgZWxlbWVudHMgdXNlZCBmb3IgcmVzaXppbmdcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgc2V0UmVzaXplcnMoZWxlbWVudDpIVE1MRWxlbWVudCkge1xyXG4gICAgY29uc3Qgc2V0UmVzaXphYmxlRWxlbWVudHMgPSAoKSA9PiB7XHJcbiAgICAgIGxldCByZXNpemFibGVFbGVtZW50czpSZXNpemFibGVFbGVtZW50W10gPSBbXTtcclxuICAgICAgLy8gZ2V0IGRvbSBlbGVtZW50cyBvZiBhbGwgcmVzaXplcnNcclxuICAgICAgdGhpcy5yZXNpemVyc0xpc3QuZm9yRWFjaCggaXRlbSA9PiB7XHJcbiAgICAgICAgY29uc3QgcmVzaXplRWxlbXMgPSAgZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGl0ZW0uY2xhc3NOYW1lKTtcclxuICAgICAgICBpZiggcmVzaXplRWxlbXM/Lmxlbmd0aCApIHtcclxuICAgICAgICAgIC8vIHNldCByZXNpemUgc3RyYXRlZ3kgaW4gZWFjaCBlbGVtZW50IHNvIHdlIGtub3cgaW4gd2hpY2ggZGlyZWN0aW9uIHRvIHJlc2l6ZVxyXG4gICAgICAgICAgY29uc3QgZGVjb3JhdGVkUmVzaXplRWxlbXM6IFJlc2l6YWJsZUVsZW1lbnRbXSA9IEFycmF5LmZyb20ocmVzaXplRWxlbXMpLm1hcCggZWxlbSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc2l6YWJsZUVsZW0gPSBlbGVtIGFzIFJlc2l6YWJsZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgIHJlc2l6YWJsZUVsZW0ucmVzaXplU3RyYXRlZ3kgPSBpdGVtLnJlc2l6ZVN0cmF0ZWd5O1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzaXphYmxlRWxlbTtcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIC8vIGFkZCBpdCB0byBsaXN0IG9mIGFsbCByZXNpemVyc1xyXG4gICAgICAgICAgcmVzaXphYmxlRWxlbWVudHMgPSBbLi4ucmVzaXphYmxlRWxlbWVudHMsIC4uLmRlY29yYXRlZFJlc2l6ZUVsZW1zXTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgdGhpcy5yZXNpemFibGVFbGVtZW50cyA9ICBbLi4ucmVzaXphYmxlRWxlbWVudHNdO1xyXG4gICAgICB0aGlzLm9wZW5FbGVtZW50TGlzdGVuZXJzUmVzaXplKCk7XHJcbiAgICB9XHJcbiAgICBzZXRUaW1lb3V0KCgpPT57XHJcbiAgICAgIHNldFJlc2l6YWJsZUVsZW1lbnRzKCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgKiBvcGVuIG1vdXNlZG93biwgdG91Y2hzdGFydCBsaXN0ZW5lcnMgb24gYWxsIGVsZW1lbnRzIGFsbG93ZWQgZm9yIHJlc2l6aW5nXHJcbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xyXG4gIG9wZW5FbGVtZW50TGlzdGVuZXJzUmVzaXplKCkge1xyXG4gICAgdGhpcy5yZXNpemFibGVFbGVtZW50cy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xyXG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuYm91bmRSZXNpemVTdGFydCk7XHJcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuYm91bmRSZXNpemVTdGFydCk7XHJcbiAgICB9KTtcclxuICB9XHJcbiAvKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAqIG9wZW4gbW91c2V1cCwgdG91Y2hlbmQgYW5kIG1vdXNlbW92ZSwgdG91Y2htb3ZlIG9uIGRvY3VtZW50XHJcbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xyXG4gIG9wZW5Eb2N1bWVudExpc3RlbmVyc1Jlc2l6ZSgpIHtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUmVzaXplRW5kKTtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5ib3VuZFJlc2l6ZUVuZCk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kUmVzaXplSW5Qcm9ncmVzcyk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLmJvdW5kUmVzaXplSW5Qcm9ncmVzcyk7ICAgIFxyXG4gIH1cclxuIFxyXG4gIC8qKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgKiBjbG9zZSBtb3VzZXVwLCB0b3VjaGVuZCBhbmQgbW91c2Vtb3ZlLCB0b3VjaG1vdmUgb24gZG9jdW1lbnRcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgY2xvc2VEb2N1bWVudExpc3RlbmVyc1Jlc2l6ZSgpIHtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRSZXNpemVJblByb2dyZXNzKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuYm91bmRSZXNpemVJblByb2dyZXNzKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kUmVzaXplRW5kKTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5ib3VuZFJlc2l6ZUVuZCk7XHJcbiAgfVxyXG5cclxuLyoqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAqIGNsb3NlIG1vdXNlZG93biwgdG91Y2hzdGFydCBsaXN0ZW5lcnMgb24gYWxsIGVsZW1lbnRzIGFsbG93ZWQgZm9yIHJlc2l6aW5nXHJcbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xyXG4gIGNsb3NlRWxlbWVudExpc3RlbmVyc1Jlc2l6ZSgpIHtcclxuICAgIHRoaXMucmVzaXphYmxlRWxlbWVudHMuZm9yRWFjaChlbGVtZW50ID0+IHtcclxuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLmJvdW5kUmVzaXplU3RhcnQpO1xyXG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLmJvdW5kUmVzaXplU3RhcnQpO1xyXG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuYm91bmRSZXNpemVJblByb2dyZXNzKTtcclxuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLmJvdW5kUmVzaXplSW5Qcm9ncmVzcyk7ICAgICAgXHJcbiAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRSZXNpemVFbmQpO1xyXG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5ib3VuZFJlc2l6ZUVuZCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgKiBjbG9zZSBhbGwgbGlzdGVuZXJzXHJcbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xyXG4gIGNsb3NlQWxsTGlzdGVuZXJzUmVzaXplKCkge1xyXG4gICAgdGhpcy5jbG9zZUVsZW1lbnRMaXN0ZW5lcnNSZXNpemUoKTtcclxuICAgIHRoaXMuY2xvc2VEb2N1bWVudExpc3RlbmVyc1Jlc2l6ZSgpO1xyXG4gIH1cclxuXHJcbiAvKiotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAqIHNldHVwIGFjdHVhbCByZXNpemUgc3RyYXRlZ3lcclxuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcbiAgc2V0dXBSZXNpemVTdHJhdGVneShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcclxuICAgIGlmKCAhZXZlbnQgKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIG9uIHdoaWNoIGVsZW1lbnQgcmVzaXplIHN0YXJ0ZWQgc28gd2Uga25vdyBpbiB3aGljaCBkaXJlY3Rpb24gdG8gcmVzaXplXHJcbiAgICBsZXQgcmVzaXplU3RyYXRlZ3k6c3RyaW5nID0gXCJzZVwiO1xyXG4gICAgY29uc3QgIHJlc2l6ZVNvdXJjZUVsZW0gPSBldmVudD8udGFyZ2V0O1xyXG5cclxuICAgIGlmKCByZXNpemVTb3VyY2VFbGVtICkge1xyXG4gICAgICBjb25zdCAgZm91bmRFbGVtID0gdGhpcy5yZXNpemFibGVFbGVtZW50cy5maW5kKCBpdGVtID0+IGl0ZW0gPT09IHJlc2l6ZVNvdXJjZUVsZW0gKTtcclxuICAgICAgaWYgKGZvdW5kRWxlbSAmJiBmb3VuZEVsZW0ucmVzaXplU3RyYXRlZ3kpIHtcclxuICAgICAgICByZXNpemVTdHJhdGVneSA9IGZvdW5kRWxlbT8ucmVzaXplU3RyYXRlZ3k7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFjdFJlc2l6ZVN0cmF0ZWd5ID0gIHJlc2l6ZVN0cmF0ZWd5O1xyXG4gIH1cclxufVxyXG4iXX0=
|