angular-toolbox 1.2.2 → 1.3.0
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/README.md +1 -1
- package/esm2022/lib/component/index.mjs +2 -1
- package/esm2022/lib/component/layout/border-layout/border-layout.component.mjs +125 -0
- package/esm2022/lib/component/layout/border-layout/util/border-layout-bounds-manager.mjs +211 -0
- package/esm2022/lib/component/layout/border-layout/util/border-layout-renderer.mjs +212 -0
- package/esm2022/lib/component/layout/border-layout/util/resize-method.mjs +9 -0
- package/esm2022/lib/component/layout/border-layout-container/border-layout-container.component.mjs +143 -0
- package/esm2022/lib/component/layout/index.mjs +3 -0
- package/esm2022/lib/core/impl/version/version.impl.mjs +3 -4
- package/esm2022/lib/model/business/ui/index.mjs +2 -1
- package/esm2022/lib/model/business/ui/layout/index.mjs +5 -0
- package/esm2022/lib/model/business/ui/layout/layout-constraints.mjs +9 -0
- package/esm2022/lib/model/business/ui/layout/layout-drag-event-type.enum.mjs +26 -0
- package/esm2022/lib/model/business/ui/layout/layout-drag.event.mjs +23 -0
- package/esm2022/lib/model/business/ui/layout/layout-region.mjs +35 -0
- package/esm2022/lib/model/business/ui/window/window-init.mjs +1 -1
- package/esm2022/lib/model/service/version/angular-toolbox-version.service.mjs +4 -4
- package/esm2022/lib/util/index.mjs +2 -1
- package/esm2022/lib/util/version.util.mjs +44 -0
- package/esm2022/lib/util/window/window-features-builder.mjs +13 -1
- package/fesm2022/angular-toolbox.mjs +2524 -1703
- package/fesm2022/angular-toolbox.mjs.map +1 -1
- package/lib/component/index.d.ts +1 -0
- package/lib/component/layout/border-layout/border-layout.component.d.ts +79 -0
- package/lib/component/layout/border-layout/util/border-layout-bounds-manager.d.ts +131 -0
- package/lib/component/layout/border-layout/util/border-layout-renderer.d.ts +87 -0
- package/lib/component/layout/border-layout/util/resize-method.d.ts +13 -0
- package/lib/component/layout/border-layout-container/border-layout-container.component.d.ts +104 -0
- package/lib/component/layout/index.d.ts +2 -0
- package/lib/model/business/ui/index.d.ts +1 -0
- package/lib/model/business/ui/layout/index.d.ts +4 -0
- package/lib/model/business/ui/layout/layout-constraints.d.ts +33 -0
- package/lib/model/business/ui/layout/layout-drag-event-type.enum.d.ts +24 -0
- package/lib/model/business/ui/layout/layout-drag.event.d.ts +32 -0
- package/lib/model/business/ui/layout/layout-region.d.ts +36 -0
- package/lib/model/business/ui/window/window-init.d.ts +5 -0
- package/lib/util/index.d.ts +1 -0
- package/lib/util/version.util.d.ts +30 -0
- package/lib/util/window/window-features-builder.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A library that provides useful tools for Angular apps development.
|
|
4
4
|
|
|
5
|
-
[]()
|
|
6
6
|
|
|
7
7
|
## License
|
|
8
8
|
|
|
@@ -6,4 +6,5 @@
|
|
|
6
6
|
* found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
|
|
7
7
|
*/
|
|
8
8
|
export * from './angular-toolbox-logo/angular-toolbox-logo.component';
|
|
9
|
-
|
|
9
|
+
export * from './layout';
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRvb2xib3gvc3JjL2xpYi9jb21wb25lbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsY0FBYyx1REFBdUQsQ0FBQztBQUN0RSxjQUFjLFVBQVUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBAbGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgUGFzY2FsIEVDSEVNQU5OLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKlxyXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxyXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vcGFzY2FsZWNoZW1hbm4uY29tL2FuZ3VsYXItdG9vbGJveC9yZXNvdXJjZXMvbGljZW5zZVxyXG4gKi9cclxuXHJcbmV4cG9ydCAqIGZyb20gJy4vYW5ndWxhci10b29sYm94LWxvZ28vYW5ndWxhci10b29sYm94LWxvZ28uY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9sYXlvdXQnO1xyXG4iXX0=
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Pascal ECHEMANN. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be found in
|
|
6
|
+
* the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
|
|
7
|
+
*/
|
|
8
|
+
import { Component, ContentChildren, ViewChild, HostListener, EventEmitter, Output } from '@angular/core';
|
|
9
|
+
import { BorderLayoutContainer } from '../border-layout-container/border-layout-container.component';
|
|
10
|
+
import { LayoutDragEventType } from '../../../model';
|
|
11
|
+
import { BorderLayoutRenderer } from './util/border-layout-renderer';
|
|
12
|
+
import { IdentifiableComponent } from '../../../core';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "../../../model";
|
|
15
|
+
/**
|
|
16
|
+
* A border layout lays out a container, arranging and resizing its components to fit in five regions: north, south, east, west, and center.
|
|
17
|
+
* Each region is defined by a `BorderLayoutContainer` instance, and is identified by a corresponding constant: `NORTH`, `SOUTH`, `EAST`, `WEST`, and `CENTER`.
|
|
18
|
+
*/
|
|
19
|
+
export class BorderLayout extends IdentifiableComponent {
|
|
20
|
+
/**
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
onResize() {
|
|
24
|
+
this.paint();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @private
|
|
28
|
+
*/
|
|
29
|
+
set __containers__(containers) {
|
|
30
|
+
this.renderer.addContainers(containers);
|
|
31
|
+
}
|
|
32
|
+
;
|
|
33
|
+
/**
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
constructor(subscribeSvc) {
|
|
37
|
+
super();
|
|
38
|
+
this.subscribeSvc = subscribeSvc;
|
|
39
|
+
/**
|
|
40
|
+
* Emits events each time the user starts dragging a region handle.
|
|
41
|
+
*/
|
|
42
|
+
this.dragStart = new EventEmitter(false);
|
|
43
|
+
/**
|
|
44
|
+
* Emits events each time the user stops dragging a region handle.
|
|
45
|
+
*/
|
|
46
|
+
this.dragStop = new EventEmitter(false);
|
|
47
|
+
/**
|
|
48
|
+
* Emits events each time the user is dragging a region handle.
|
|
49
|
+
*/
|
|
50
|
+
this.dragging = new EventEmitter(false);
|
|
51
|
+
this.renderer = new BorderLayoutRenderer(subscribeSvc);
|
|
52
|
+
subscribeSvc.register(this, this.renderer.userAction.subscribe((event) => {
|
|
53
|
+
event.layout = this;
|
|
54
|
+
if (event.type === LayoutDragEventType.DRAGGING) {
|
|
55
|
+
this.dragging.emit(event);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (event.type === LayoutDragEventType.DRAG_START) {
|
|
59
|
+
this.dragStart.emit(event);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.dragStop.emit(event);
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @private
|
|
67
|
+
* For test purpose only.
|
|
68
|
+
*/
|
|
69
|
+
getRenderer() {
|
|
70
|
+
return this.renderer;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
ngOnDestroy() {
|
|
76
|
+
this.subscribeSvc.clearAll(this);
|
|
77
|
+
this.renderer.destroy();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
ngAfterViewInit() {
|
|
83
|
+
this.renderer.setLayoutContainer(this.layoutContainer.nativeElement);
|
|
84
|
+
this.paint();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Forces the container to be redrawn.
|
|
88
|
+
*/
|
|
89
|
+
paint() {
|
|
90
|
+
this.renderer.paint();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Resizes the specified region.
|
|
94
|
+
*
|
|
95
|
+
* @param region The region to resize.
|
|
96
|
+
* @param size The new size of the region to resize.
|
|
97
|
+
*
|
|
98
|
+
* @returns `true` whether the specified region has been resized; `false` otherwise.
|
|
99
|
+
*/
|
|
100
|
+
resizeRegion(region, size) {
|
|
101
|
+
this.renderer.resizeRegion(region, size);
|
|
102
|
+
}
|
|
103
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: BorderLayout, deps: [{ token: i1.SubscriptionService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
104
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.3", type: BorderLayout, isStandalone: true, selector: "atx-border-layout", outputs: { dragStart: "dragStart", dragStop: "dragStop", dragging: "dragging" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "__containers__", predicate: BorderLayoutContainer }], viewQueries: [{ propertyName: "layoutContainer", first: true, predicate: ["atxLayoutContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<!--\n * LICENSE\n * Copyright Pascal ECHEMANN. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license\n-->\n\n<div #atxLayoutContainer class=\"atx-border-layout\">\n <ng-content></ng-content>\n</div>", styles: [".atx-border-layout{position:relative;height:100%;width:100%;-webkit-user-select:none;user-select:none;overflow:hidden}.atx-border-layout,.atx-border-layout *{box-sizing:border-box}.atx-border-layout .content{height:100%;width:100%;overflow:auto}.atx-border-layout .drag{position:absolute;border:2px solid black}:host ::ng-deep .atx-handle{position:absolute}:host ::ng-deep .atx-handle:hover,:host ::ng-deep .atx-handle.atx-handle-selected{background-color:var(--atx-handle-color, #469afa)}:host ::ng-deep .north{position:absolute;z-index:10;top:0;left:0;right:0}:host ::ng-deep .north .atx-handle{left:0;right:0;bottom:0;height:4px;cursor:ns-resize}:host ::ng-deep .west{position:absolute;z-index:5;left:0;height:unset!important}:host ::ng-deep .west .atx-handle{right:0;bottom:0;top:0;width:4px;cursor:ew-resize}:host ::ng-deep .east{position:absolute;z-index:5;right:0;height:unset!important}:host ::ng-deep .east .atx-handle{left:0;bottom:0;top:0;width:4px;cursor:ew-resize}:host ::ng-deep .south{position:absolute;z-index:10;bottom:0;left:0;right:0}:host ::ng-deep .south .atx-handle{left:0;right:0;top:0;height:4px;cursor:ns-resize}:host ::ng-deep .center{position:absolute}\n/**\n * @license\n * Copyright Pascal ECHEMANN. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be found in\n * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license\n */\n"] }); }
|
|
105
|
+
}
|
|
106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.3", ngImport: i0, type: BorderLayout, decorators: [{
|
|
107
|
+
type: Component,
|
|
108
|
+
args: [{ selector: 'atx-border-layout', standalone: true, template: "<!--\n * LICENSE\n * Copyright Pascal ECHEMANN. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license\n-->\n\n<div #atxLayoutContainer class=\"atx-border-layout\">\n <ng-content></ng-content>\n</div>", styles: [".atx-border-layout{position:relative;height:100%;width:100%;-webkit-user-select:none;user-select:none;overflow:hidden}.atx-border-layout,.atx-border-layout *{box-sizing:border-box}.atx-border-layout .content{height:100%;width:100%;overflow:auto}.atx-border-layout .drag{position:absolute;border:2px solid black}:host ::ng-deep .atx-handle{position:absolute}:host ::ng-deep .atx-handle:hover,:host ::ng-deep .atx-handle.atx-handle-selected{background-color:var(--atx-handle-color, #469afa)}:host ::ng-deep .north{position:absolute;z-index:10;top:0;left:0;right:0}:host ::ng-deep .north .atx-handle{left:0;right:0;bottom:0;height:4px;cursor:ns-resize}:host ::ng-deep .west{position:absolute;z-index:5;left:0;height:unset!important}:host ::ng-deep .west .atx-handle{right:0;bottom:0;top:0;width:4px;cursor:ew-resize}:host ::ng-deep .east{position:absolute;z-index:5;right:0;height:unset!important}:host ::ng-deep .east .atx-handle{left:0;bottom:0;top:0;width:4px;cursor:ew-resize}:host ::ng-deep .south{position:absolute;z-index:10;bottom:0;left:0;right:0}:host ::ng-deep .south .atx-handle{left:0;right:0;top:0;height:4px;cursor:ns-resize}:host ::ng-deep .center{position:absolute}\n/**\n * @license\n * Copyright Pascal ECHEMANN. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be found in\n * the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license\n */\n"] }]
|
|
109
|
+
}], ctorParameters: () => [{ type: i1.SubscriptionService }], propDecorators: { dragStart: [{
|
|
110
|
+
type: Output
|
|
111
|
+
}], dragStop: [{
|
|
112
|
+
type: Output
|
|
113
|
+
}], dragging: [{
|
|
114
|
+
type: Output
|
|
115
|
+
}], onResize: [{
|
|
116
|
+
type: HostListener,
|
|
117
|
+
args: ["window:resize"]
|
|
118
|
+
}], layoutContainer: [{
|
|
119
|
+
type: ViewChild,
|
|
120
|
+
args: ["atxLayoutContainer"]
|
|
121
|
+
}], __containers__: [{
|
|
122
|
+
type: ContentChildren,
|
|
123
|
+
args: [BorderLayoutContainer]
|
|
124
|
+
}] } });
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9yZGVyLWxheW91dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRvb2xib3gvc3JjL2xpYi9jb21wb25lbnQvbGF5b3V0L2JvcmRlci1sYXlvdXQvYm9yZGVyLWxheW91dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRvb2xib3gvc3JjL2xpYi9jb21wb25lbnQvbGF5b3V0L2JvcmRlci1sYXlvdXQvYm9yZGVyLWxheW91dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQWlCLFNBQVMsRUFBRSxlQUFlLEVBQXlCLFNBQVMsRUFBRSxZQUFZLEVBQWEsWUFBWSxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuSyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw4REFBOEQsQ0FBQztBQUNyRyxPQUFPLEVBQW1CLG1CQUFtQixFQUF1RCxNQUFNLGdCQUFnQixDQUFDO0FBQzNILE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBRXREOzs7R0FHRztBQU9ILE1BQU0sT0FBTyxZQUFhLFNBQVEscUJBQXFCO0lBb0JyRDs7T0FFRztJQUVLLFFBQVE7UUFDZCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZixDQUFDO0lBYUQ7O09BRUc7SUFDSCxJQUNZLGNBQWMsQ0FBQyxVQUE0QztRQUNyRSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQUEsQ0FBQztJQUVGOztPQUVHO0lBQ0gsWUFBb0IsWUFBaUM7UUFDbkQsS0FBSyxFQUFFLENBQUM7UUFEVSxpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFoRHJEOztXQUVHO1FBRWEsY0FBUyxHQUFrQyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVuRjs7V0FFRztRQUVhLGFBQVEsR0FBa0MsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFbEY7O1dBRUc7UUFFYSxhQUFRLEdBQWtDLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBa0NoRixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksb0JBQW9CLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkQsWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQXNCLEVBQUMsRUFBRTtZQUMzRCxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztZQUNwQixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzNCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSSxXQUFXO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZUFBZTtRQUNwQixJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSztRQUNWLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxZQUFZLENBQUMsTUFBdUMsRUFBRSxJQUFZO1FBQ3ZFLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLE1BQXNCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0QsQ0FBQzs4R0E5R1UsWUFBWTtrR0FBWixZQUFZLHFQQTBDTixxQkFBcUIsMktDbEV4Qyx5VkFVTTs7MkZEY08sWUFBWTtrQkFOeEIsU0FBUzsrQkFDRSxtQkFBbUIsY0FHakIsSUFBSTt3RkFRQSxTQUFTO3NCQUR4QixNQUFNO2dCQU9TLFFBQVE7c0JBRHZCLE1BQU07Z0JBT1MsUUFBUTtzQkFEdkIsTUFBTTtnQkFPQyxRQUFRO3NCQURmLFlBQVk7dUJBQUMsZUFBZTtnQkFTckIsZUFBZTtzQkFEdEIsU0FBUzt1QkFBQyxvQkFBb0I7Z0JBWW5CLGNBQWM7c0JBRHpCLGVBQWU7dUJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IFBhc2NhbCBFQ0hFTUFOTi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpblxuICogdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL3Bhc2NhbGVjaGVtYW5uLmNvbS9hbmd1bGFyLXRvb2xib3gvcmVzb3VyY2VzL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIENvbnRlbnRDaGlsZHJlbiwgT25EZXN0cm95LCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIEhvc3RMaXN0ZW5lciwgUXVlcnlMaXN0LCBFdmVudEVtaXR0ZXIsIG91dHB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCb3JkZXJMYXlvdXRDb250YWluZXIgfSBmcm9tICcuLi9ib3JkZXItbGF5b3V0LWNvbnRhaW5lci9ib3JkZXItbGF5b3V0LWNvbnRhaW5lci5jb21wb25lbnQnO1xuaW1wb3J0IHsgTGF5b3V0RHJhZ0V2ZW50LCBMYXlvdXREcmFnRXZlbnRUeXBlLCBMYXlvdXRSZWdpb24sIExheW91dFJlZ2lvblR5cGUsIFN1YnNjcmlwdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9tb2RlbCc7XG5pbXBvcnQgeyBCb3JkZXJMYXlvdXRSZW5kZXJlciB9IGZyb20gJy4vdXRpbC9ib3JkZXItbGF5b3V0LXJlbmRlcmVyJztcbmltcG9ydCB7IElkZW50aWZpYWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uL2NvcmUnO1xuXG4vKipcbiAqIEEgYm9yZGVyIGxheW91dCBsYXlzIG91dCBhIGNvbnRhaW5lciwgYXJyYW5naW5nIGFuZCByZXNpemluZyBpdHMgY29tcG9uZW50cyB0byBmaXQgaW4gZml2ZSByZWdpb25zOiBub3J0aCwgc291dGgsIGVhc3QsIHdlc3QsIGFuZCBjZW50ZXIuXG4gKiBFYWNoIHJlZ2lvbiBpcyBkZWZpbmVkIGJ5IGEgYEJvcmRlckxheW91dENvbnRhaW5lcmAgaW5zdGFuY2UsIGFuZCBpcyBpZGVudGlmaWVkIGJ5IGEgY29ycmVzcG9uZGluZyBjb25zdGFudDogYE5PUlRIYCwgYFNPVVRIYCwgYEVBU1RgLCBgV0VTVGAsIGFuZCBgQ0VOVEVSYC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXR4LWJvcmRlci1sYXlvdXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vYm9yZGVyLWxheW91dC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2JvcmRlci1sYXlvdXQuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBCb3JkZXJMYXlvdXQgZXh0ZW5kcyBJZGVudGlmaWFibGVDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBFbWl0cyBldmVudHMgZWFjaCB0aW1lIHRoZSB1c2VyIHN0YXJ0cyBkcmFnZ2luZyBhIHJlZ2lvbiBoYW5kbGUuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIHJlYWRvbmx5IGRyYWdTdGFydDogRXZlbnRFbWl0dGVyPExheW91dERyYWdFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKTtcblxuICAvKipcbiAgICogRW1pdHMgZXZlbnRzIGVhY2ggdGltZSB0aGUgdXNlciBzdG9wcyBkcmFnZ2luZyBhIHJlZ2lvbiBoYW5kbGUuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgcHVibGljIHJlYWRvbmx5IGRyYWdTdG9wOiBFdmVudEVtaXR0ZXI8TGF5b3V0RHJhZ0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuXG4gIC8qKlxuICAgKiBFbWl0cyBldmVudHMgZWFjaCB0aW1lIHRoZSB1c2VyIGlzIGRyYWdnaW5nIGEgcmVnaW9uIGhhbmRsZS5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgcmVhZG9ubHkgZHJhZ2dpbmc6IEV2ZW50RW1pdHRlcjxMYXlvdXREcmFnRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG4gIFxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6cmVzaXplXCIpXG4gIHByaXZhdGUgb25SZXNpemUoKTogdm9pZCB7XG4gICAgdGhpcy5wYWludCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBAVmlld0NoaWxkKFwiYXR4TGF5b3V0Q29udGFpbmVyXCIpXG4gIHByaXZhdGUgbGF5b3V0Q29udGFpbmVyITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHJlbmRlcmVyOiBCb3JkZXJMYXlvdXRSZW5kZXJlcjtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIEBDb250ZW50Q2hpbGRyZW4oQm9yZGVyTGF5b3V0Q29udGFpbmVyKVxuICBwcml2YXRlIHNldCBfX2NvbnRhaW5lcnNfXyhjb250YWluZXJzOiBRdWVyeUxpc3Q8Qm9yZGVyTGF5b3V0Q29udGFpbmVyPikge1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ29udGFpbmVycyhjb250YWluZXJzKTtcbiAgfTtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3Vic2NyaWJlU3ZjOiBTdWJzY3JpcHRpb25TZXJ2aWNlKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IEJvcmRlckxheW91dFJlbmRlcmVyKHN1YnNjcmliZVN2Yyk7XG4gICAgc3Vic2NyaWJlU3ZjLnJlZ2lzdGVyKHRoaXMsXG4gICAgICB0aGlzLnJlbmRlcmVyLnVzZXJBY3Rpb24uc3Vic2NyaWJlKChldmVudDogTGF5b3V0RHJhZ0V2ZW50KT0+IHtcbiAgICAgICAgZXZlbnQubGF5b3V0ID0gdGhpcztcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IExheW91dERyYWdFdmVudFR5cGUuRFJBR0dJTkcpIHtcbiAgICAgICAgICB0aGlzLmRyYWdnaW5nLmVtaXQoZXZlbnQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gTGF5b3V0RHJhZ0V2ZW50VHlwZS5EUkFHX1NUQVJUKSB7XG4gICAgICAgICAgdGhpcy5kcmFnU3RhcnQuZW1pdChldmVudCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZHJhZ1N0b3AuZW1pdChldmVudCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogRm9yIHRlc3QgcHVycG9zZSBvbmx5LlxuICAgKi9cbiAgcHVibGljIGdldFJlbmRlcmVyKCk6IEJvcmRlckxheW91dFJlbmRlcmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaWJlU3ZjLmNsZWFyQWxsKHRoaXMpO1xuICAgIHRoaXMucmVuZGVyZXIuZGVzdHJveSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIuc2V0TGF5b3V0Q29udGFpbmVyKHRoaXMubGF5b3V0Q29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHRoaXMucGFpbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JjZXMgdGhlIGNvbnRhaW5lciB0byBiZSByZWRyYXduLlxuICAgKi9cbiAgcHVibGljIHBhaW50KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIucGFpbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNpemVzIHRoZSBzcGVjaWZpZWQgcmVnaW9uLlxuICAgKiBcbiAgICogQHBhcmFtIHJlZ2lvbiBUaGUgcmVnaW9uIHRvIHJlc2l6ZS5cbiAgICogQHBhcmFtIHNpemUgVGhlIG5ldyBzaXplIG9mIHRoZSByZWdpb24gdG8gcmVzaXplLlxuICAgKiBcbiAgICogQHJldHVybnMgYHRydWVgIHdoZXRoZXIgdGhlIHNwZWNpZmllZCByZWdpb24gaGFzIGJlZW4gcmVzaXplZDsgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqL1xuICBwdWJsaWMgcmVzaXplUmVnaW9uKHJlZ2lvbjogTGF5b3V0UmVnaW9uIHwgTGF5b3V0UmVnaW9uVHlwZSwgc2l6ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5yZXNpemVSZWdpb24ocmVnaW9uIGFzIExheW91dFJlZ2lvbiwgc2l6ZSk7XG4gIH1cbn1cbiIsIjwhLS1cbiAqIExJQ0VOU0VcbiAqIENvcHlyaWdodCBQYXNjYWwgRUNIRU1BTk4uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9wYXNjYWxlY2hlbWFubi5jb20vYW5ndWxhci10b29sYm94L3Jlc291cmNlcy9saWNlbnNlXG4tLT5cblxuPGRpdiAjYXR4TGF5b3V0Q29udGFpbmVyIGNsYXNzPVwiYXR4LWJvcmRlci1sYXlvdXRcIj5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG48L2Rpdj4iXX0=
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Pascal ECHEMANN. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be found in
|
|
6
|
+
* the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
|
|
7
|
+
*/
|
|
8
|
+
import { LayoutRegion, } from '../../../../model';
|
|
9
|
+
/**
|
|
10
|
+
* @private
|
|
11
|
+
* A utility class that computes the size of all border layout containers.
|
|
12
|
+
*/
|
|
13
|
+
export class BorderLayoutBoundsManager {
|
|
14
|
+
constructor() {
|
|
15
|
+
/**
|
|
16
|
+
* @private
|
|
17
|
+
* The container top position when the user starts to drag the handle.
|
|
18
|
+
*/
|
|
19
|
+
this.topPos = 0;
|
|
20
|
+
/**
|
|
21
|
+
* @private
|
|
22
|
+
* The container left position when the user starts to drag the handle.
|
|
23
|
+
*/
|
|
24
|
+
this.leftPos = 0;
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
* The bounds of the center container.
|
|
28
|
+
*/
|
|
29
|
+
this.bounds = new DOMRect();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Makes this object elligible for garbage collection.
|
|
33
|
+
*/
|
|
34
|
+
destroy() {
|
|
35
|
+
this.bounds = null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns a rectangle that represents the bounds currently computed by this object.
|
|
39
|
+
*
|
|
40
|
+
* @returns The bounds currently computed by this object.
|
|
41
|
+
*/
|
|
42
|
+
getBounds() {
|
|
43
|
+
return this.bounds;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Sets the top-left hand corner position before each bounds computaion.
|
|
47
|
+
*
|
|
48
|
+
* @param x The x position of the main container, in pixels, before computaion.
|
|
49
|
+
* @param y The y position of the main container, in pixels, before computaion.
|
|
50
|
+
*/
|
|
51
|
+
setOrigin(x, y) {
|
|
52
|
+
this.leftPos = x;
|
|
53
|
+
this.topPos = y;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @private
|
|
57
|
+
* For test purpose only.
|
|
58
|
+
*/
|
|
59
|
+
getOrigin() {
|
|
60
|
+
return { x: this.leftPos, y: this.topPos };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Computes the size of a "north" container.
|
|
64
|
+
*
|
|
65
|
+
* @param event The mouse event that triggered the computation of the container size.
|
|
66
|
+
* @param width The width of the main container.
|
|
67
|
+
* @param height The height of the main container.
|
|
68
|
+
* @param minSize The minimum size of the container for which to compute the size.
|
|
69
|
+
* @param maxSize The maximum size of the container for which to compute the size.
|
|
70
|
+
*
|
|
71
|
+
* @returns The size of a "north" container.
|
|
72
|
+
*/
|
|
73
|
+
northResize(event, width, height, minSize, maxSize) {
|
|
74
|
+
const size = event.clientY - this.topPos;
|
|
75
|
+
if (maxSize && size > maxSize)
|
|
76
|
+
return this.setY(maxSize);
|
|
77
|
+
if (minSize && size < minSize)
|
|
78
|
+
return this.setY(minSize);
|
|
79
|
+
return this.setY(size);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
setY(y) {
|
|
85
|
+
this.bounds.y = y;
|
|
86
|
+
return y;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Computes the size of a "south" container.
|
|
90
|
+
*
|
|
91
|
+
* @param event The mouse event that triggered the computation of the container size.
|
|
92
|
+
* @param width The width of the main container.
|
|
93
|
+
* @param height The height of the main container.
|
|
94
|
+
* @param minSize The minimum size of the container for which to compute the size.
|
|
95
|
+
* @param maxSize The maximum size of the container for which to compute the size.
|
|
96
|
+
*
|
|
97
|
+
* @returns The size of a "south" container.
|
|
98
|
+
*/
|
|
99
|
+
southResize(event, width, height, minSize, maxSize) {
|
|
100
|
+
const size = height - (event.clientY - this.topPos);
|
|
101
|
+
if (maxSize && size > maxSize)
|
|
102
|
+
return this.setHeight(maxSize);
|
|
103
|
+
if (minSize && size < minSize)
|
|
104
|
+
return this.setHeight(minSize);
|
|
105
|
+
return this.setHeight(size);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
setHeight(height) {
|
|
111
|
+
this.bounds.height = height;
|
|
112
|
+
return height;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Computes the size of a "west" container.
|
|
116
|
+
*
|
|
117
|
+
* @param event The mouse event that triggered the computation of the container size.
|
|
118
|
+
* @param width The width of the main container.
|
|
119
|
+
* @param height The height of the main container.
|
|
120
|
+
* @param minSize The minimum size of the container for which to compute the size.
|
|
121
|
+
* @param maxSize The maximum size of the container for which to compute the size.
|
|
122
|
+
*
|
|
123
|
+
* @returns The size of a "west" container.
|
|
124
|
+
*/
|
|
125
|
+
westResize(event, width, height, minSize, maxSize) {
|
|
126
|
+
const size = event.clientX - this.leftPos;
|
|
127
|
+
if (maxSize && size > maxSize)
|
|
128
|
+
return this.setX(maxSize);
|
|
129
|
+
if (minSize && size < minSize)
|
|
130
|
+
return this.setX(minSize);
|
|
131
|
+
return this.setX(size);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* @private
|
|
135
|
+
*/
|
|
136
|
+
setX(x) {
|
|
137
|
+
this.bounds.x = x;
|
|
138
|
+
return x;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Computes the size of a "east" container.
|
|
142
|
+
*
|
|
143
|
+
* @param event The mouse event that triggered the computation of the container size.
|
|
144
|
+
* @param width The width of the main container.
|
|
145
|
+
* @param height The height of the main container.
|
|
146
|
+
* @param minSize The minimum size of the container for which to compute the size.
|
|
147
|
+
* @param maxSize The maximum size of the container for which to compute the size.
|
|
148
|
+
*
|
|
149
|
+
* @returns The size of a "east" container.
|
|
150
|
+
*/
|
|
151
|
+
eastResize(event, width, height, minSize, maxSize) {
|
|
152
|
+
const size = width - (event.clientX - this.leftPos);
|
|
153
|
+
if (maxSize && size > maxSize)
|
|
154
|
+
return this.setWidth(maxSize);
|
|
155
|
+
if (minSize && size < minSize)
|
|
156
|
+
return this.setWidth(minSize);
|
|
157
|
+
return this.setWidth(size);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
setWidth(width) {
|
|
163
|
+
this.bounds.width = width;
|
|
164
|
+
return width;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Invoked after each `BorderLayoutContainer` registration to initialize the center container bounds.
|
|
168
|
+
*
|
|
169
|
+
* @param container A `BorderLayoutContainer` instance added to the main container.
|
|
170
|
+
*/
|
|
171
|
+
initBounds(container) {
|
|
172
|
+
const r = container.constraints.region;
|
|
173
|
+
if (r === LayoutRegion.NORTH) {
|
|
174
|
+
this.bounds.y = container.getSize();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (r === LayoutRegion.SOUTH) {
|
|
178
|
+
this.bounds.height = container.getSize();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (r === LayoutRegion.WEST) {
|
|
182
|
+
this.bounds.x = container.getSize();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (r === LayoutRegion.EAST)
|
|
186
|
+
this.bounds.width = container.getSize();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Returns the method used to compute the size of a container, depending on the specified region.
|
|
190
|
+
*
|
|
191
|
+
* @param region The region associated with the container for which to compute the size.
|
|
192
|
+
*
|
|
193
|
+
* @returns The method used to compute the size of a container.
|
|
194
|
+
*/
|
|
195
|
+
getResizeMethod(region) {
|
|
196
|
+
let method = this.southResize;
|
|
197
|
+
switch (region) {
|
|
198
|
+
case LayoutRegion.NORTH:
|
|
199
|
+
method = this.northResize;
|
|
200
|
+
break;
|
|
201
|
+
case LayoutRegion.WEST:
|
|
202
|
+
method = this.westResize;
|
|
203
|
+
break;
|
|
204
|
+
case LayoutRegion.EAST:
|
|
205
|
+
method = this.eastResize;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
return method.bind(this);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9yZGVyLWxheW91dC1ib3VuZHMtbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdG9vbGJveC9zcmMvbGliL2NvbXBvbmVudC9sYXlvdXQvYm9yZGVyLWxheW91dC91dGlsL2JvcmRlci1sYXlvdXQtYm91bmRzLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBR0gsT0FBTyxFQUFlLFlBQVksR0FBRyxNQUFNLG1CQUFtQixDQUFDO0FBRy9EOzs7R0FHRztBQUNILE1BQU0sT0FBTyx5QkFBeUI7SUFBdEM7UUFFRTs7O1dBR0c7UUFDSyxXQUFNLEdBQVcsQ0FBQyxDQUFDO1FBRTNCOzs7V0FHRztRQUNLLFlBQU8sR0FBVyxDQUFDLENBQUM7UUFFNUI7OztXQUdHO1FBQ0ssV0FBTSxHQUFZLElBQUksT0FBTyxFQUFFLENBQUM7SUFtTDFDLENBQUM7SUFqTEM7O09BRUc7SUFDSSxPQUFPO1FBQ1osSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFXLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFNBQVMsQ0FBQyxDQUFTLEVBQUUsQ0FBUztRQUNuQyxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksU0FBUztRQUNkLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksV0FBVyxDQUFDLEtBQWlCLEVBQUUsS0FBYSxFQUFFLE1BQWMsRUFB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QUMsSUFBSTtnQkFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztnQkFBQyxNQUFNO1FBQzFELENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFRLENBQUM7SUFDbEMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IFBhc2NhbCBFQ0hFTUFOTi4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpblxuICogdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL3Bhc2NhbGVjaGVtYW5uLmNvbS9hbmd1bGFyLXRvb2xib3gvcmVzb3VyY2VzL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyBCb3JkZXJMYXlvdXRDb250YWluZXIgfSBmcm9tICcuLi8uLi9ib3JkZXItbGF5b3V0LWNvbnRhaW5lci9ib3JkZXItbGF5b3V0LWNvbnRhaW5lci5jb21wb25lbnQnO1xuaW1wb3J0IHsgRGVzdHJveWFibGUsIExheW91dFJlZ2lvbiwgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbCc7XG5pbXBvcnQgeyBSZXNpemVNZXRob2QgfSBmcm9tICcuL3Jlc2l6ZS1tZXRob2QnO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBIHV0aWxpdHkgY2xhc3MgdGhhdCBjb21wdXRlcyB0aGUgc2l6ZSBvZiBhbGwgYm9yZGVyIGxheW91dCBjb250YWluZXJzLlxuICovXG5leHBvcnQgY2xhc3MgQm9yZGVyTGF5b3V0Qm91bmRzTWFuYWdlciBpbXBsZW1lbnRzIERlc3Ryb3lhYmxlIHtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogVGhlIGNvbnRhaW5lciB0b3AgcG9zaXRpb24gd2hlbiB0aGUgdXNlciBzdGFydHMgdG8gZHJhZyB0aGUgaGFuZGxlLlxuICAgKi9cbiAgcHJpdmF0ZSB0b3BQb3M6IG51bWJlciA9IDA7XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIFRoZSBjb250YWluZXIgbGVmdCBwb3NpdGlvbiB3aGVuIHRoZSB1c2VyIHN0YXJ0cyB0byBkcmFnIHRoZSBoYW5kbGUuXG4gICAqL1xuICBwcml2YXRlIGxlZnRQb3M6IG51bWJlciA9IDA7XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIFRoZSBib3VuZHMgb2YgdGhlIGNlbnRlciBjb250YWluZXIuXG4gICAqL1xuICBwcml2YXRlIGJvdW5kczogRE9NUmVjdCA9IG5ldyBET01SZWN0KCk7XG5cbiAgLyoqXG4gICAqIE1ha2VzIHRoaXMgb2JqZWN0IGVsbGlnaWJsZSBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5ib3VuZHMgPSBudWxsIGFzIGFueTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgcmVjdGFuZ2xlIHRoYXQgcmVwcmVzZW50cyB0aGUgYm91bmRzIGN1cnJlbnRseSBjb21wdXRlZCBieSB0aGlzIG9iamVjdC5cbiAgICogXG4gICAqIEByZXR1cm5zIFRoZSBib3VuZHMgY3VycmVudGx5IGNvbXB1dGVkIGJ5IHRoaXMgb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIGdldEJvdW5kcygpOiBET01SZWN0IHtcbiAgICByZXR1cm4gdGhpcy5ib3VuZHM7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgdG9wLWxlZnQgaGFuZCBjb3JuZXIgcG9zaXRpb24gYmVmb3JlIGVhY2ggYm91bmRzIGNvbXB1dGFpb24uXG4gICAqIFxuICAgKiBAcGFyYW0geCBUaGUgeCBwb3NpdGlvbiBvZiB0aGUgbWFpbiBjb250YWluZXIsIGluIHBpeGVscywgYmVmb3JlIGNvbXB1dGFpb24uXG4gICAqIEBwYXJhbSB5IFRoZSB5IHBvc2l0aW9uIG9mIHRoZSBtYWluIGNvbnRhaW5lciwgaW4gcGl4ZWxzLCBiZWZvcmUgY29tcHV0YWlvbi5cbiAgICovXG4gIHB1YmxpYyBzZXRPcmlnaW4oeDogbnVtYmVyLCB5OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmxlZnRQb3MgPSB4O1xuICAgIHRoaXMudG9wUG9zID0geTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBGb3IgdGVzdCBwdXJwb3NlIG9ubHkuXG4gICAqL1xuICBwdWJsaWMgZ2V0T3JpZ2luKCk6IGFueSB7XG4gICAgcmV0dXJuIHsgeDogdGhpcy5sZWZ0UG9zLCB5OiB0aGlzLnRvcFBvcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIHRoZSBzaXplIG9mIGEgXCJub3J0aFwiIGNvbnRhaW5lci5cbiAgICogXG4gICAqIEBwYXJhbSBldmVudCBUaGUgbW91c2UgZXZlbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGNvbXB1dGF0aW9uIG9mIHRoZSBjb250YWluZXIgc2l6ZS5cbiAgICogQHBhcmFtIHdpZHRoIFRoZSB3aWR0aCBvZiB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqIEBwYXJhbSBoZWlnaHQgVGhlIGhlaWdodCBvZiB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqIEBwYXJhbSBtaW5TaXplIFRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIGNvbnRhaW5lciBmb3Igd2hpY2ggdG8gY29tcHV0ZSB0aGUgc2l6ZS5cbiAgICogQHBhcmFtIG1heFNpemUgVGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgY29udGFpbmVyIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBzaXplLlxuICAgKiBcbiAgICogQHJldHVybnMgVGhlIHNpemUgb2YgYSBcIm5vcnRoXCIgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIG5vcnRoUmVzaXplKGV2ZW50OiBNb3VzZUV2ZW50LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgbWluU2l6ZTogbnVtYmVyIHwgdW5kZWZpbmVkLCBtYXhTaXplOiBudW1iZXIgfCB1bmRlZmluZWQpOiBudW1iZXIge1xuICAgIGNvbnN0IHNpemU6IG51bWJlciA9IGV2ZW50LmNsaWVudFkgLSB0aGlzLnRvcFBvcztcbiAgICBpZiAobWF4U2l6ZSAmJiBzaXplID4gbWF4U2l6ZSkgcmV0dXJuIHRoaXMuc2V0WShtYXhTaXplKTtcbiAgICBpZiAobWluU2l6ZSAmJiBzaXplIDwgbWluU2l6ZSkgcmV0dXJuIHRoaXMuc2V0WShtaW5TaXplKTtcbiAgICByZXR1cm4gdGhpcy5zZXRZKHNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHNldFkoeTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICB0aGlzLmJvdW5kcy55ID0geTtcbiAgICByZXR1cm4geTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiBhIFwic291dGhcIiBjb250YWluZXIuXG4gICAqIFxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIG1vdXNlIGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBjb21wdXRhdGlvbiBvZiB0aGUgY29udGFpbmVyIHNpemUuXG4gICAqIEBwYXJhbSB3aWR0aCBUaGUgd2lkdGggb2YgdGhlIG1haW4gY29udGFpbmVyLlxuICAgKiBAcGFyYW0gaGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIG1haW4gY29udGFpbmVyLlxuICAgKiBAcGFyYW0gbWluU2l6ZSBUaGUgbWluaW11bSBzaXplIG9mIHRoZSBjb250YWluZXIgZm9yIHdoaWNoIHRvIGNvbXB1dGUgdGhlIHNpemUuXG4gICAqIEBwYXJhbSBtYXhTaXplIFRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIGNvbnRhaW5lciBmb3Igd2hpY2ggdG8gY29tcHV0ZSB0aGUgc2l6ZS5cbiAgICogXG4gICAqIEByZXR1cm5zIFRoZSBzaXplIG9mIGEgXCJzb3V0aFwiIGNvbnRhaW5lci5cbiAgICovXG4gIHB1YmxpYyBzb3V0aFJlc2l6ZShldmVudDogTW91c2VFdmVudCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIG1pblNpemU6IG51bWJlciB8IHVuZGVmaW5lZCwgbWF4U2l6ZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcbiAgICBjb25zdCBzaXplOiBudW1iZXIgPSBoZWlnaHQgLSAoZXZlbnQuY2xpZW50WSAtIHRoaXMudG9wUG9zKTtcbiAgICBpZiAobWF4U2l6ZSAmJiBzaXplID4gbWF4U2l6ZSkgcmV0dXJuIHRoaXMuc2V0SGVpZ2h0KG1heFNpemUpO1xuICAgIGlmIChtaW5TaXplICYmIHNpemUgPCBtaW5TaXplKSByZXR1cm4gdGhpcy5zZXRIZWlnaHQobWluU2l6ZSk7XG4gICAgcmV0dXJuIHRoaXMuc2V0SGVpZ2h0KHNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHNldEhlaWdodChoZWlnaHQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgdGhpcy5ib3VuZHMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHJldHVybiBoZWlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgdGhlIHNpemUgb2YgYSBcIndlc3RcIiBjb250YWluZXIuXG4gICAqIFxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIG1vdXNlIGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBjb21wdXRhdGlvbiBvZiB0aGUgY29udGFpbmVyIHNpemUuXG4gICAqIEBwYXJhbSB3aWR0aCBUaGUgd2lkdGggb2YgdGhlIG1haW4gY29udGFpbmVyLlxuICAgKiBAcGFyYW0gaGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIG1haW4gY29udGFpbmVyLlxuICAgKiBAcGFyYW0gbWluU2l6ZSBUaGUgbWluaW11bSBzaXplIG9mIHRoZSBjb250YWluZXIgZm9yIHdoaWNoIHRvIGNvbXB1dGUgdGhlIHNpemUuXG4gICAqIEBwYXJhbSBtYXhTaXplIFRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIGNvbnRhaW5lciBmb3Igd2hpY2ggdG8gY29tcHV0ZSB0aGUgc2l6ZS5cbiAgICogXG4gICAqIEByZXR1cm5zIFRoZSBzaXplIG9mIGEgXCJ3ZXN0XCIgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIHdlc3RSZXNpemUoZXZlbnQ6IE1vdXNlRXZlbnQsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBtaW5TaXplOiBudW1iZXIgfCB1bmRlZmluZWQsIG1heFNpemU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gICAgY29uc3Qgc2l6ZTogbnVtYmVyID0gZXZlbnQuY2xpZW50WCAtIHRoaXMubGVmdFBvcztcbiAgICBpZiAobWF4U2l6ZSAmJiBzaXplID4gbWF4U2l6ZSkgcmV0dXJuIHRoaXMuc2V0WChtYXhTaXplKTtcbiAgICBpZiAobWluU2l6ZSAmJiBzaXplIDwgbWluU2l6ZSkgcmV0dXJuIHRoaXMuc2V0WChtaW5TaXplKTtcbiAgICByZXR1cm4gdGhpcy5zZXRYKHNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHNldFgoeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICB0aGlzLmJvdW5kcy54ID0geDtcbiAgICByZXR1cm4geDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiBhIFwiZWFzdFwiIGNvbnRhaW5lci5cbiAgICogXG4gICAqIEBwYXJhbSBldmVudCBUaGUgbW91c2UgZXZlbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGNvbXB1dGF0aW9uIG9mIHRoZSBjb250YWluZXIgc2l6ZS5cbiAgICogQHBhcmFtIHdpZHRoIFRoZSB3aWR0aCBvZiB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqIEBwYXJhbSBoZWlnaHQgVGhlIGhlaWdodCBvZiB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqIEBwYXJhbSBtaW5TaXplIFRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIGNvbnRhaW5lciBmb3Igd2hpY2ggdG8gY29tcHV0ZSB0aGUgc2l6ZS5cbiAgICogQHBhcmFtIG1heFNpemUgVGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgY29udGFpbmVyIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBzaXplLlxuICAgKiBcbiAgICogQHJldHVybnMgVGhlIHNpemUgb2YgYSBcImVhc3RcIiBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgZWFzdFJlc2l6ZShldmVudDogTW91c2VFdmVudCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIG1pblNpemU6IG51bWJlciB8IHVuZGVmaW5lZCwgbWF4U2l6ZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcbiAgICBjb25zdCBzaXplOiBudW1iZXIgPSB3aWR0aCAtIChldmVudC5jbGllbnRYIC0gdGhpcy5sZWZ0UG9zKTtcbiAgICBpZiAobWF4U2l6ZSAmJiBzaXplID4gbWF4U2l6ZSkgcmV0dXJuIHRoaXMuc2V0V2lkdGgobWF4U2l6ZSk7XG4gICAgaWYgKG1pblNpemUgJiYgc2l6ZSA8IG1pblNpemUpIHJldHVybiB0aGlzLnNldFdpZHRoKG1pblNpemUpO1xuICAgIHJldHVybiB0aGlzLnNldFdpZHRoKHNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHNldFdpZHRoKHdpZHRoOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHRoaXMuYm91bmRzLndpZHRoID0gd2lkdGg7XG4gICAgcmV0dXJuIHdpZHRoO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgYWZ0ZXIgZWFjaCBgQm9yZGVyTGF5b3V0Q29udGFpbmVyYCByZWdpc3RyYXRpb24gdG8gaW5pdGlhbGl6ZSB0aGUgY2VudGVyIGNvbnRhaW5lciBib3VuZHMuXG4gICAqIFxuICAgKiBAcGFyYW0gY29udGFpbmVyIEEgYEJvcmRlckxheW91dENvbnRhaW5lcmAgaW5zdGFuY2UgYWRkZWQgdG8gdGhlIG1haW4gY29udGFpbmVyLiBcbiAgICovXG4gIHB1YmxpYyBpbml0Qm91bmRzKGNvbnRhaW5lcjogQm9yZGVyTGF5b3V0Q29udGFpbmVyKTogdm9pZCB7XG4gICAgY29uc3QgcjogTGF5b3V0UmVnaW9uID0gY29udGFpbmVyLmNvbnN0cmFpbnRzLnJlZ2lvbiBhcyBMYXlvdXRSZWdpb247XG4gICAgaWYgKHIgPT09IExheW91dFJlZ2lvbi5OT1JUSCkge1xuICAgICAgdGhpcy5ib3VuZHMueSA9IGNvbnRhaW5lci5nZXRTaXplKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyID09PSBMYXlvdXRSZWdpb24uU09VVEgpIHtcbiAgICAgIHRoaXMuYm91bmRzLmhlaWdodCA9IGNvbnRhaW5lci5nZXRTaXplKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyID09PSBMYXlvdXRSZWdpb24uV0VTVCkge1xuICAgICAgdGhpcy5ib3VuZHMueCA9IGNvbnRhaW5lci5nZXRTaXplKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyID09PSBMYXlvdXRSZWdpb24uRUFTVCkgdGhpcy5ib3VuZHMud2lkdGggPSBjb250YWluZXIuZ2V0U2l6ZSgpO1xuICB9XG4gIFxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbWV0aG9kIHVzZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiBhIGNvbnRhaW5lciwgZGVwZW5kaW5nIG9uIHRoZSBzcGVjaWZpZWQgcmVnaW9uLlxuICAgKiBcbiAgICogQHBhcmFtIHJlZ2lvbiBUaGUgcmVnaW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29udGFpbmVyIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBzaXplLlxuICAgKiBcbiAgICogQHJldHVybnMgVGhlIG1ldGhvZCB1c2VkIHRvIGNvbXB1dGUgdGhlIHNpemUgb2YgYSBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0UmVzaXplTWV0aG9kKHJlZ2lvbjogTGF5b3V0UmVnaW9uKTogUmVzaXplTWV0aG9kIHtcbiAgICBsZXQgbWV0aG9kOiBSZXNpemVNZXRob2QgPSB0aGlzLnNvdXRoUmVzaXplO1xuICAgIHN3aXRjaCAocmVnaW9uKSB7XG4gICAgICBjYXNlIExheW91dFJlZ2lvbi5OT1JUSDogbWV0aG9kID0gdGhpcy5ub3J0aFJlc2l6ZTsgYnJlYWs7XG4gICAgICBjYXNlIExheW91dFJlZ2lvbi5XRVNUOiBtZXRob2QgPSB0aGlzLndlc3RSZXNpemU7IGJyZWFrO1xuICAgICAgY2FzZSBMYXlvdXRSZWdpb24uRUFTVDogbWV0aG9kID0gdGhpcy5lYXN0UmVzaXplOyBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG1ldGhvZC5iaW5kKHRoaXMpIGFzIGFueTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Pascal ECHEMANN. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be found in
|
|
6
|
+
* the LICENSE file at https://pascalechemann.com/angular-toolbox/resources/license
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from '@angular/core';
|
|
9
|
+
import { EMPTY_STRING } from '../../../../util';
|
|
10
|
+
import { LayoutDragEvent, LayoutDragEventType, LayoutRegion } from '../../../../model';
|
|
11
|
+
import { IdentifiableComponent } from '../../../../core';
|
|
12
|
+
import { BorderLayoutBoundsManager } from './border-layout-bounds-manager';
|
|
13
|
+
/**
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
const MOUSEMOVE = "mousemove";
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
const MOUSEUP = "mouseup";
|
|
21
|
+
/**
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
const REGION_ERR_MSG = "A container with the same identifier has already been registered: ";
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
const LAYOUT_ERR_MSG = "No layout container has been registered.";
|
|
29
|
+
/**
|
|
30
|
+
* @private
|
|
31
|
+
* A controller object responsible for handling user actions on a `BorderLayout` container.
|
|
32
|
+
*/
|
|
33
|
+
export class BorderLayoutRenderer extends IdentifiableComponent {
|
|
34
|
+
/**
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
constructor(subscribeSvc) {
|
|
38
|
+
super();
|
|
39
|
+
this.subscribeSvc = subscribeSvc;
|
|
40
|
+
/**
|
|
41
|
+
* Emits events each time the user starts, or stops dragging handle.
|
|
42
|
+
*/
|
|
43
|
+
this.userAction = new EventEmitter(false);
|
|
44
|
+
/**
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
this.containerList = [];
|
|
48
|
+
this.boundsManager = new BorderLayoutBoundsManager();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Add the list `BorderLayoutContainer` objects associated with the main container to this controller.
|
|
52
|
+
*
|
|
53
|
+
* @param containers the list `BorderLayoutContainer` objects associated with the main container.
|
|
54
|
+
*/
|
|
55
|
+
addContainers(containers) {
|
|
56
|
+
let regionValidator = EMPTY_STRING;
|
|
57
|
+
containers.forEach(container => {
|
|
58
|
+
const constraints = container.constraints;
|
|
59
|
+
const r = constraints.region;
|
|
60
|
+
if (regionValidator.indexOf(r) !== -1)
|
|
61
|
+
throw new SyntaxError(REGION_ERR_MSG + r);
|
|
62
|
+
regionValidator += r;
|
|
63
|
+
if (constraints.resizable) {
|
|
64
|
+
this.subscribeSvc.register(this, container.resizeStart.subscribe(container => this.resizeEnter(container)));
|
|
65
|
+
}
|
|
66
|
+
this.boundsManager.initBounds(container);
|
|
67
|
+
if (r === LayoutRegion.NORTH || r === LayoutRegion.SOUTH)
|
|
68
|
+
return;
|
|
69
|
+
this.containerList.push(container);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
;
|
|
73
|
+
/**
|
|
74
|
+
* Sets the reference to the HTML container associated with the main container.
|
|
75
|
+
*
|
|
76
|
+
* @param lytContainer The reference to the HTML container associated with the main container.
|
|
77
|
+
*/
|
|
78
|
+
setLayoutContainer(lytContainer) {
|
|
79
|
+
this.lytContainerElm = lytContainer;
|
|
80
|
+
}
|
|
81
|
+
;
|
|
82
|
+
/**
|
|
83
|
+
* @private
|
|
84
|
+
* For test purpose only.
|
|
85
|
+
* Returns the reference to the internal `BorderLayoutBoundsManager` instance.
|
|
86
|
+
*/
|
|
87
|
+
getBoundsManager() {
|
|
88
|
+
return this.boundsManager;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Makes this object elligible for garbage collection.
|
|
92
|
+
*/
|
|
93
|
+
destroy() {
|
|
94
|
+
this.subscribeSvc.clearAll(this);
|
|
95
|
+
this.containerList.length = 0;
|
|
96
|
+
this.containerList = null;
|
|
97
|
+
this.lytContainerElm = null;
|
|
98
|
+
this.boundsManager.destroy();
|
|
99
|
+
this.boundsManager = null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Forces the layout of all `BorderLayoutContainer` objects associated with the main container.
|
|
103
|
+
*/
|
|
104
|
+
paint() {
|
|
105
|
+
this.checkLytContainer();
|
|
106
|
+
this.render(this.lytContainerElm.offsetWidth);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Resizes the specified region of the associated container.
|
|
110
|
+
*
|
|
111
|
+
* @param region The region to resize.
|
|
112
|
+
* @param size The new size of the region to resize.
|
|
113
|
+
*
|
|
114
|
+
* @returns `true` whether the specified region has been resized; `false` otherwise.
|
|
115
|
+
*/
|
|
116
|
+
resizeRegion(region, size) {
|
|
117
|
+
if (region === LayoutRegion.CENTER)
|
|
118
|
+
return false;
|
|
119
|
+
const container = this.containerList.find((c) => {
|
|
120
|
+
return c.constraints.region === region;
|
|
121
|
+
});
|
|
122
|
+
if (!container)
|
|
123
|
+
return false;
|
|
124
|
+
container.setSize(size);
|
|
125
|
+
this.boundsManager.initBounds(container);
|
|
126
|
+
this.paint();
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
resizeEnter(container) {
|
|
133
|
+
this.checkLytContainer();
|
|
134
|
+
const lytNativeElm = this.lytContainerElm;
|
|
135
|
+
const width = lytNativeElm.offsetWidth;
|
|
136
|
+
const height = lytNativeElm.offsetHeight;
|
|
137
|
+
const bounds = lytNativeElm.getBoundingClientRect();
|
|
138
|
+
const constraints = container.constraints;
|
|
139
|
+
const region = constraints.region;
|
|
140
|
+
const minSize = constraints.minSize;
|
|
141
|
+
const maxSize = constraints.maxSize;
|
|
142
|
+
let size = 0;
|
|
143
|
+
this.boundsManager.setOrigin(bounds.x, bounds.y);
|
|
144
|
+
let resizeMethod = this.boundsManager.getResizeMethod(region);
|
|
145
|
+
container.selected = true;
|
|
146
|
+
const onMoveHandler = (event) => {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
event.stopPropagation();
|
|
149
|
+
size = resizeMethod(event, width, height, minSize, maxSize);
|
|
150
|
+
container.setSize(size);
|
|
151
|
+
this.render(width);
|
|
152
|
+
this.fireEvent(container, LayoutDragEventType.DRAGGING);
|
|
153
|
+
};
|
|
154
|
+
const onStopHandler = (event) => {
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
event.stopPropagation();
|
|
157
|
+
lytNativeElm.removeEventListener(MOUSEMOVE, onMoveHandler);
|
|
158
|
+
lytNativeElm.removeEventListener(MOUSEUP, onStopHandler);
|
|
159
|
+
container.selected = false;
|
|
160
|
+
size = resizeMethod(event, width, height, minSize, maxSize);
|
|
161
|
+
container.setSize(size);
|
|
162
|
+
this.render(width);
|
|
163
|
+
this.fireEvent(container, LayoutDragEventType.DRAG_STOP);
|
|
164
|
+
};
|
|
165
|
+
lytNativeElm.addEventListener(MOUSEMOVE, onMoveHandler);
|
|
166
|
+
lytNativeElm.addEventListener(MOUSEUP, onStopHandler);
|
|
167
|
+
this.fireEvent(container, LayoutDragEventType.DRAG_START);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
fireEvent(target, type) {
|
|
173
|
+
const evt = new LayoutDragEvent(target, type);
|
|
174
|
+
this.userAction.emit(evt);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* @private
|
|
178
|
+
*/
|
|
179
|
+
render(width) {
|
|
180
|
+
const bounds = this.boundsManager.getBounds();
|
|
181
|
+
const top = bounds.top;
|
|
182
|
+
const bottom = bounds.bottom;
|
|
183
|
+
const left = bounds.left;
|
|
184
|
+
const right = bounds.right;
|
|
185
|
+
this.containerList.forEach((cont) => {
|
|
186
|
+
const r = cont.constraints.region;
|
|
187
|
+
if (r === LayoutRegion.WEST) {
|
|
188
|
+
cont.setTopPos(top);
|
|
189
|
+
cont.setRightPos(width - left);
|
|
190
|
+
cont.setBottomPos(bottom - top);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (r === LayoutRegion.CENTER) {
|
|
194
|
+
cont.setTopPos(top);
|
|
195
|
+
cont.setLeftPos(left);
|
|
196
|
+
cont.setRightPos(right - left);
|
|
197
|
+
cont.setBottomPos(bottom - top);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (r === LayoutRegion.EAST) {
|
|
201
|
+
cont.setTopPos(top);
|
|
202
|
+
cont.setLeftPos(width - (right - left));
|
|
203
|
+
cont.setBottomPos(bottom - top);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
checkLytContainer() {
|
|
208
|
+
if (!this.lytContainerElm)
|
|
209
|
+
throw new ReferenceError(LAYOUT_ERR_MSG);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9yZGVyLWxheW91dC1yZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdG9vbGJveC9zcmMvbGliL2NvbXBvbmVudC9sYXlvdXQvYm9yZGVyLWxheW91dC91dGlsL2JvcmRlci1sYXlvdXQtcmVuZGVyZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUV4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFrQyxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUF1QixNQUFNLG1CQUFtQixDQUFDO0FBQzVJLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRzNFOztHQUVHO0FBQ0gsTUFBTSxTQUFTLEdBQVEsV0FBVyxDQUFDO0FBRW5DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLEdBQVEsU0FBUyxDQUFDO0FBRS9COztHQUVHO0FBQ0gsTUFBTSxjQUFjLEdBQVcsb0VBQW9FLENBQUM7QUFFcEc7O0dBRUc7QUFDSCxNQUFNLGNBQWMsR0FBVywwQ0FBMEMsQ0FBQztBQUUxRTs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sb0JBQXFCLFNBQVEscUJBQXFCO0lBc0I3RDs7T0FFRztJQUNILFlBQW9CLFlBQWlDO1FBQ25ELEtBQUssRUFBRSxDQUFDO1FBRFUsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBdkJyRDs7V0FFRztRQUNhLGVBQVUsR0FBa0MsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFPcEY7O1dBRUc7UUFDSyxrQkFBYSxHQUE0QixFQUFFLENBQUM7UUFZbEQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJ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QVUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDbEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWU7WUFBRSxNQUFNLElBQUksY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBQYXNjYWwgRUNIRU1BTk4uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW5cbiAqIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9wYXNjYWxlY2hlbWFubi5jb20vYW5ndWxhci10b29sYm94L3Jlc291cmNlcy9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBRdWVyeUxpc3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJvcmRlckxheW91dENvbnRhaW5lciB9IGZyb20gJy4uLy4uL2JvcmRlci1sYXlvdXQtY29udGFpbmVyL2JvcmRlci1sYXlvdXQtY29udGFpbmVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBFTVBUWV9TVFJJTkcgfSBmcm9tICcuLi8uLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IERlc3Ryb3lhYmxlLCBMYXlvdXRDb25zdHJhaW50cywgTGF5b3V0RHJhZ0V2ZW50LCBMYXlvdXREcmFnRXZlbnRUeXBlLCBMYXlvdXRSZWdpb24sIFN1YnNjcmlwdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbCc7XG5pbXBvcnQgeyBJZGVudGlmaWFibGVDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlJztcbmltcG9ydCB7IEJvcmRlckxheW91dEJvdW5kc01hbmFnZXIgfSBmcm9tICcuL2JvcmRlci1sYXlvdXQtYm91bmRzLW1hbmFnZXInO1xuaW1wb3J0IHsgUmVzaXplTWV0aG9kIH0gZnJvbSAnLi9yZXNpemUtbWV0aG9kJztcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBNT1VTRU1PVkU6IGFueSA9IFwibW91c2Vtb3ZlXCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgTU9VU0VVUDogYW55ID0gXCJtb3VzZXVwXCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgUkVHSU9OX0VSUl9NU0c6IHN0cmluZyA9IFwiQSBjb250YWluZXIgd2l0aCB0aGUgc2FtZSBpZGVudGlmaWVyIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZDogXCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgTEFZT1VUX0VSUl9NU0c6IHN0cmluZyA9IFwiTm8gbGF5b3V0IGNvbnRhaW5lciBoYXMgYmVlbiByZWdpc3RlcmVkLlwiO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBBIGNvbnRyb2xsZXIgb2JqZWN0IHJlc3BvbnNpYmxlIGZvciBoYW5kbGluZyB1c2VyIGFjdGlvbnMgb24gYSBgQm9yZGVyTGF5b3V0YCBjb250YWluZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBCb3JkZXJMYXlvdXRSZW5kZXJlciBleHRlbmRzIElkZW50aWZpYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIERlc3Ryb3lhYmxlIHtcblxuICAvKipcbiAgICogRW1pdHMgZXZlbnRzIGVhY2ggdGltZSB0aGUgdXNlciBzdGFydHMsIG9yIHN0b3BzIGRyYWdnaW5nIGhhbmRsZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyQWN0aW9uOiBFdmVudEVtaXR0ZXI8TGF5b3V0RHJhZ0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBseXRDb250YWluZXJFbG0hOiBIVE1MRGl2RWxlbWVudDtcbiAgXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjb250YWluZXJMaXN0OiBCb3JkZXJMYXlvdXRDb250YWluZXJbXSA9IFtdO1xuICBcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGJvdW5kc01hbmFnZXI6IEJvcmRlckxheW91dEJvdW5kc01hbmFnZXI7IFxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzdWJzY3JpYmVTdmM6IFN1YnNjcmlwdGlvblNlcnZpY2UpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYm91bmRzTWFuYWdlciA9IG5ldyBCb3JkZXJMYXlvdXRCb3VuZHNNYW5hZ2VyKCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHRoZSBsaXN0IGBCb3JkZXJMYXlvdXRDb250YWluZXJgIG9iamVjdHMgYXNzb2NpYXRlZCB3aXRoIHRoZSBtYWluIGNvbnRhaW5lciB0byB0aGlzIGNvbnRyb2xsZXIuXG4gICAqIFxuICAgKiBAcGFyYW0gY29udGFpbmVycyB0aGUgbGlzdCBgQm9yZGVyTGF5b3V0Q29udGFpbmVyYCBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkQ29udGFpbmVycyhjb250YWluZXJzOiBRdWVyeUxpc3Q8Qm9yZGVyTGF5b3V0Q29udGFpbmVyPik6IHZvaWQge1xuICAgIGxldCByZWdpb25WYWxpZGF0b3I6IHN0cmluZyA9IEVNUFRZX1NUUklORztcbiAgICBjb250YWluZXJzLmZvckVhY2goY29udGFpbmVyID0+IHtcbiAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBMYXlvdXRDb25zdHJhaW50cyA9IGNvbnRhaW5lci5jb25zdHJhaW50cztcbiAgICAgIGNvbnN0IHI6IHN0cmluZyA9IGNvbnN0cmFpbnRzLnJlZ2lvbiBhcyBzdHJpbmc7XG4gICAgICBpZiAocmVnaW9uVmFsaWRhdG9yLmluZGV4T2YocikgIT09IC0xKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoUkVHSU9OX0VSUl9NU0cgKyByKTtcbiAgICAgIHJlZ2lvblZhbGlkYXRvciArPSByO1xuICAgICAgaWYgKGNvbnN0cmFpbnRzLnJlc2l6YWJsZSkge1xuICAgICAgICB0aGlzLnN1YnNjcmliZVN2Yy5yZWdpc3Rlcih0aGlzLFxuICAgICAgICAgIGNvbnRhaW5lci5yZXNpemVTdGFydC5zdWJzY3JpYmUoY29udGFpbmVyPT4gdGhpcy5yZXNpemVFbnRlcihjb250YWluZXIpKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhpcy5ib3VuZHNNYW5hZ2VyLmluaXRCb3VuZHMoY29udGFpbmVyKTtcbiAgICAgIGlmIChyID09PSBMYXlvdXRSZWdpb24uTk9SVEggfHwgciA9PT0gTGF5b3V0UmVnaW9uLlNPVVRIKSByZXR1cm47XG4gICAgICB0aGlzLmNvbnRhaW5lckxpc3QucHVzaChjb250YWluZXIpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSByZWZlcmVuY2UgdG8gdGhlIEhUTUwgY29udGFpbmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqIFxuICAgKiBAcGFyYW0gbHl0Q29udGFpbmVyIFRoZSByZWZlcmVuY2UgdG8gdGhlIEhUTUwgY29udGFpbmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgc2V0TGF5b3V0Q29udGFpbmVyKGx5dENvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQpOiB2b2lkIHtcbiAgICB0aGlzLmx5dENvbnRhaW5lckVsbSA9IGx5dENvbnRhaW5lcjtcbiAgfTtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogRm9yIHRlc3QgcHVycG9zZSBvbmx5LlxuICAgKiBSZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gdGhlIGludGVybmFsIGBCb3JkZXJMYXlvdXRCb3VuZHNNYW5hZ2VyYCBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyBnZXRCb3VuZHNNYW5hZ2VyKCk6IEJvcmRlckxheW91dEJvdW5kc01hbmFnZXIge1xuICAgIHJldHVybiB0aGlzLmJvdW5kc01hbmFnZXI7IFxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIHRoaXMgb2JqZWN0IGVsbGlnaWJsZSBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpYmVTdmMuY2xlYXJBbGwodGhpcyk7XG4gICAgdGhpcy5jb250YWluZXJMaXN0Lmxlbmd0aCA9IDA7XG4gICAgdGhpcy5jb250YWluZXJMaXN0ID0gbnVsbCBhcyBhbnk7XG4gICAgdGhpcy5seXRDb250YWluZXJFbG0gPSBudWxsIGFzIGFueTtcbiAgICB0aGlzLmJvdW5kc01hbmFnZXIuZGVzdHJveSgpO1xuICAgIHRoaXMuYm91bmRzTWFuYWdlciA9IG51bGwgYXMgYW55O1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmNlcyB0aGUgbGF5b3V0IG9mIGFsbCBgQm9yZGVyTGF5b3V0Q29udGFpbmVyYCBvYmplY3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFpbiBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgcGFpbnQoKTogdm9pZCB7XG4gICAgdGhpcy5jaGVja0x5dENvbnRhaW5lcigpO1xuICAgIHRoaXMucmVuZGVyKHRoaXMubHl0Q29udGFpbmVyRWxtLm9mZnNldFdpZHRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNpemVzIHRoZSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBhc3NvY2lhdGVkIGNvbnRhaW5lci5cbiAgICogXG4gICAqIEBwYXJhbSByZWdpb24gVGhlIHJlZ2lvbiB0byByZXNpemUuXG4gICAqIEBwYXJhbSBzaXplIFRoZSBuZXcgc2l6ZSBvZiB0aGUgcmVnaW9uIHRvIHJlc2l6ZS5cbiAgICogXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgcmVnaW9uIGhhcyBiZWVuIHJlc2l6ZWQ7IGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHVibGljIHJlc2l6ZVJlZ2lvbihyZWdpb246IExheW91dFJlZ2lvbiwgc2l6ZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHJlZ2lvbiA9PT0gTGF5b3V0UmVnaW9uLkNFTlRFUikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGNvbnRhaW5lcjogQm9yZGVyTGF5b3V0Q29udGFpbmVyIHwgdW5kZWZpbmVkID0gdGhpcy5jb250YWluZXJMaXN0LmZpbmQoKGM6IEJvcmRlckxheW91dENvbnRhaW5lcik9PiB7XG4gICAgICByZXR1cm4gYy5jb25zdHJhaW50cy5yZWdpb24gPT09IHJlZ2lvbjtcbiAgICB9KTtcbiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnRhaW5lci5zZXRTaXplKHNpemUpO1xuICAgIHRoaXMuYm91bmRzTWFuYWdlci5pbml0Qm91bmRzKGNvbnRhaW5lcik7XG4gICAgdGhpcy5wYWludCgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHJlc2l6ZUVudGVyKGNvbnRhaW5lcjogQm9yZGVyTGF5b3V0Q29udGFpbmVyKTogdm9pZCB7XG4gICAgdGhpcy5jaGVja0x5dENvbnRhaW5lcigpO1xuICAgIGNvbnN0IGx5dE5hdGl2ZUVsbTogSFRNTERpdkVsZW1lbnQgPSB0aGlzLmx5dENvbnRhaW5lckVsbTtcbiAgICBjb25zdCB3aWR0aDogbnVtYmVyID0gbHl0TmF0aXZlRWxtLm9mZnNldFdpZHRoO1xuICAgIGNvbnN0IGhlaWdodDogbnVtYmVyID0gbHl0TmF0aXZlRWxtLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBib3VuZHM6IERPTVJlY3QgPSBseXROYXRpdmVFbG0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgY29uc3RyYWludHM6IExheW91dENvbnN0cmFpbnRzID0gY29udGFpbmVyLmNvbnN0cmFpbnRzO1xuICAgIGNvbnN0IHJlZ2lvbjogTGF5b3V0UmVnaW9uID0gY29uc3RyYWludHMucmVnaW9uIGFzIExheW91dFJlZ2lvbjtcbiAgICBjb25zdCBtaW5TaXplOiBudW1iZXIgfCB1bmRlZmluZWQgPSBjb25zdHJhaW50cy5taW5TaXplO1xuICAgIGNvbnN0IG1heFNpemU6IG51bWJlciB8IHVuZGVmaW5lZCA9IGNvbnN0cmFpbnRzLm1heFNpemU7XG4gICAgbGV0IHNpemU6IG51bWJlciA9IDA7XG4gICAgdGhpcy5ib3VuZHNNYW5hZ2VyLnNldE9yaWdpbihib3VuZHMueCwgYm91bmRzLnkpO1xuICAgIGxldCByZXNpemVNZXRob2Q6IFJlc2l6ZU1ldGhvZCA9IHRoaXMuYm91bmRzTWFuYWdlci5nZXRSZXNpemVNZXRob2QocmVnaW9uKTtcbiAgICBjb250YWluZXIuc2VsZWN0ZWQgPSB0cnVlO1xuICAgIGNvbnN0IG9uTW92ZUhhbmRsZXIgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpPT4ge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgc2l6ZSA9IHJlc2l6ZU1ldGhvZChldmVudCwgd2lkdGgsIGhlaWdodCwgbWluU2l6ZSwgbWF4U2l6ZSk7XG4gICAgICBjb250YWluZXIuc2V0U2l6ZShzaXplKTtcbiAgICAgIHRoaXMucmVuZGVyKHdpZHRoKTtcbiAgICAgIHRoaXMuZmlyZUV2ZW50KGNvbnRhaW5lciwgTGF5b3V0RHJhZ0V2ZW50VHlwZS5EUkFHR0lORyk7XG4gICAgfTtcbiAgICBjb25zdCBvblN0b3BIYW5kbGVyID0gKGV2ZW50OiBNb3VzZUV2ZW50KT0+IHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGx5dE5hdGl2ZUVsbS5yZW1vdmVFdmVudExpc3RlbmVyKE1PVVNFTU9WRSwgb25Nb3ZlSGFuZGxlcik7XG4gICAgICBseXROYXRpdmVFbG0ucmVtb3ZlRXZlbnRMaXN0ZW5lcihNT1VTRVVQLCBvblN0b3BIYW5kbGVyKTtcbiAgICAgIGNvbnRhaW5lci5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgc2l6ZSA9IHJlc2l6ZU1ldGhvZChldmVudCwgd2lkdGgsIGhlaWdodCwgbWluU2l6ZSwgbWF4U2l6ZSk7XG4gICAgICBjb250YWluZXIuc2V0U2l6ZShzaXplKTtcbiAgICAgIHRoaXMucmVuZGVyKHdpZHRoKTtcbiAgICAgIHRoaXMuZmlyZUV2ZW50KGNvbnRhaW5lciwgTGF5b3V0RHJhZ0V2ZW50VHlwZS5EUkFHX1NUT1ApO1xuICAgIH07XG4gICAgbHl0TmF0aXZlRWxtLmFkZEV2ZW50TGlzdGVuZXIoTU9VU0VNT1ZFLCBvbk1vdmVIYW5kbGVyKTtcbiAgICBseXROYXRpdmVFbG0uYWRkRXZlbnRMaXN0ZW5lcihNT1VTRVVQLCBvblN0b3BIYW5kbGVyKTtcbiAgICB0aGlzLmZpcmVFdmVudChjb250YWluZXIsIExheW91dERyYWdFdmVudFR5cGUuRFJBR19TVEFSVCk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZmlyZUV2ZW50KHRhcmdldDogQm9yZGVyTGF5b3V0Q29udGFpbmVyLCB0eXBlOiBMYXlvdXREcmFnRXZlbnRUeXBlKTogdm9pZCB7XG4gICAgY29uc3QgZXZ0OiBMYXlvdXREcmFnRXZlbnQgPSBuZXcgTGF5b3V0RHJhZ0V2ZW50KHRhcmdldCwgdHlwZSk7XG4gICAgdGhpcy51c2VyQWN0aW9uLmVtaXQoZXZ0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXIod2lkdGg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGJvdW5kczogRE9NUmVjdCA9IHRoaXMuYm91bmRzTWFuYWdlci5nZXRCb3VuZHMoKTtcbiAgICBjb25zdCB0b3A6IG51bWJlciA9IGJvdW5kcy50b3A7XG4gICAgY29uc3QgYm90dG9tOiBudW1iZXIgPSBib3VuZHMuYm90dG9tO1xuICAgIGNvbnN0IGxlZnQ6IG51bWJlciA9IGJvdW5kcy5sZWZ0O1xuICAgIGNvbnN0IHJpZ2h0OiBudW1iZXIgPSBib3VuZHMucmlnaHQ7XG4gICAgdGhpcy5jb250YWluZXJMaXN0LmZvckVhY2goKGNvbnQ6IEJvcmRlckxheW91dENvbnRhaW5lcikgPT4ge1xuICAgICAgY29uc3QgcjogTGF5b3V0UmVnaW9uID0gY29udC5jb25zdHJhaW50cy5yZWdpb24gYXMgTGF5b3V0UmVnaW9uO1xuICAgICAgaWYgKHIgPT09IExheW91dFJlZ2lvbi5XRVNUKSB7XG4gICAgICAgIGNvbnQuc2V0VG9wUG9zKHRvcCk7XG4gICAgICAgIGNvbnQuc2V0UmlnaHRQb3Mod2lkdGggLSBsZWZ0KTtcbiAgICAgICAgY29udC5zZXRCb3R0b21Qb3MoYm90dG9tIC0gdG9wKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHIgPT09IExheW91dFJlZ2lvbi5DRU5URVIpIHtcbiAgICAgICAgY29udC5zZXRUb3BQb3ModG9wKTtcbiAgICAgICAgY29udC5zZXRMZWZ0UG9zKGxlZnQpO1xuICAgICAgICBjb250LnNldFJpZ2h0UG9zKHJpZ2h0IC0gbGVmdCk7XG4gICAgICAgIGNvbnQuc2V0Qm90dG9tUG9zKGJvdHRvbSAtIHRvcCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChyID09PSBMYXlvdXRSZWdpb24uRUFTVCkge1xuICAgICAgICBjb250LnNldFRvcFBvcyh0b3ApO1xuICAgICAgICBjb250LnNldExlZnRQb3Mod2lkdGggLSAocmlnaHQgLSBsZWZ0KSk7XG4gICAgICAgIGNvbnQuc2V0Qm90dG9tUG9zKGJvdHRvbSAtIHRvcCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrTHl0Q29udGFpbmVyKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5seXRDb250YWluZXJFbG0pIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihMQVlPVVRfRVJSX01TRyk7XG4gIH1cbn1cbiJdfQ==
|