@limble/limble-tree 0.12.4 → 0.13.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 +149 -149
- package/{esm2015/lib/classes/Branch.js → esm2020/lib/classes/Branch.mjs} +1 -1
- package/{esm2015/lib/classes/DropZone.js → esm2020/lib/classes/DropZone.mjs} +1 -1
- package/{esm2015/lib/classes/DropZoneLocation.js → esm2020/lib/classes/DropZoneLocation.mjs} +1 -1
- package/{esm2015/lib/custom-event-bindings/dragleave-no-change-detect.directive.js → esm2020/lib/custom-event-bindings/dragleave-no-change-detect.directive.mjs} +0 -0
- package/{esm2015/lib/custom-event-bindings/dragover-no-change-detect.directive.js → esm2020/lib/custom-event-bindings/dragover-no-change-detect.directive.mjs} +1 -1
- package/esm2020/lib/drop-zone/drop-zone.component.mjs +75 -0
- package/esm2020/lib/limble-tree-branch/limble-tree-branch.component.mjs +110 -0
- package/esm2020/lib/limble-tree-node/limble-tree-node.component.mjs +467 -0
- package/{esm2015/lib/limble-tree-placeholder/limble-tree-placeholder.component.js → esm2020/lib/limble-tree-placeholder/limble-tree-placeholder.component.mjs} +3 -8
- package/esm2020/lib/limble-tree-root/drop-zone.service.mjs +376 -0
- package/esm2020/lib/limble-tree-root/limble-tree-root.component.mjs +172 -0
- package/{esm2015/lib/limble-tree-root/tree-construction-status.service.js → esm2020/lib/limble-tree-root/tree-construction-status.service.mjs} +1 -1
- package/esm2020/lib/limble-tree-root/tree.service.mjs +297 -0
- package/{esm2015/lib/limble-tree.module.js → esm2020/lib/limble-tree.module.mjs} +5 -5
- package/{esm2015/lib/singletons/component-creator.service.js → esm2020/lib/singletons/component-creator.service.mjs} +1 -1
- package/esm2020/lib/singletons/drag-state.service.mjs +63 -0
- package/esm2020/lib/singletons/global-events.service.mjs +136 -0
- package/{esm2015/lib/util.js → esm2020/lib/util.mjs} +1 -1
- package/{esm2015/limble-limble-tree.js → esm2020/limble-limble-tree.mjs} +0 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +1 -1
- package/fesm2015/limble-limble-tree.mjs +2256 -0
- package/fesm2015/limble-limble-tree.mjs.map +1 -0
- package/{fesm2015/limble-limble-tree.js → fesm2020/limble-limble-tree.mjs} +89 -136
- package/fesm2020/limble-limble-tree.mjs.map +1 -0
- package/{limble-limble-tree.d.ts → index.d.ts} +0 -0
- package/lib/custom-event-bindings/dragleave-no-change-detect.directive.d.ts +1 -1
- package/lib/custom-event-bindings/dragover-no-change-detect.directive.d.ts +1 -1
- package/lib/drop-zone/drop-zone.component.d.ts +1 -1
- package/lib/limble-tree-branch/limble-tree-branch.component.d.ts +1 -1
- package/lib/limble-tree-node/limble-tree-node.component.d.ts +1 -1
- package/lib/limble-tree-placeholder/limble-tree-placeholder.component.d.ts +1 -1
- package/lib/limble-tree-root/limble-tree-root.component.d.ts +1 -1
- package/package.json +22 -9
- package/bundles/limble-limble-tree.umd.js +0 -2910
- package/bundles/limble-limble-tree.umd.js.map +0 -1
- package/esm2015/lib/drop-zone/drop-zone.component.js +0 -81
- package/esm2015/lib/limble-tree-branch/limble-tree-branch.component.js +0 -116
- package/esm2015/lib/limble-tree-node/limble-tree-node.component.js +0 -484
- package/esm2015/lib/limble-tree-root/drop-zone.service.js +0 -377
- package/esm2015/lib/limble-tree-root/limble-tree-root.component.js +0 -178
- package/esm2015/lib/limble-tree-root/tree.service.js +0 -301
- package/esm2015/lib/singletons/drag-state.service.js +0 -64
- package/esm2015/lib/singletons/global-events.service.js +0 -137
- package/fesm2015/limble-limble-tree.js.map +0 -1
|
@@ -1,484 +0,0 @@
|
|
|
1
|
-
import { Component, ElementRef, Input, ViewChild, ViewContainerRef } from "@angular/core";
|
|
2
|
-
import { arraysAreEqual, isDraggingAllowed, isNestingAllowed, suddenTreeExit } from "../util";
|
|
3
|
-
import { filter, first, skip, skipUntil } from "rxjs/operators";
|
|
4
|
-
import { DropZone } from "../classes/DropZone";
|
|
5
|
-
import { fromEvent, merge } from "rxjs";
|
|
6
|
-
import { LimbleTreeBranchComponent } from "../limble-tree-branch/limble-tree-branch.component";
|
|
7
|
-
import * as i0 from "@angular/core";
|
|
8
|
-
import * as i1 from "../singletons/component-creator.service";
|
|
9
|
-
import * as i2 from "../singletons/drag-state.service";
|
|
10
|
-
import * as i3 from "../limble-tree-root/drop-zone.service";
|
|
11
|
-
import * as i4 from "../limble-tree-root/tree.service";
|
|
12
|
-
import * as i5 from "../singletons/global-events.service";
|
|
13
|
-
import * as i6 from "../limble-tree-root/tree-construction-status.service";
|
|
14
|
-
const _c0 = ["nodeHost"];
|
|
15
|
-
const _c1 = ["draggableDiv"];
|
|
16
|
-
const _c2 = ["nodeHostContainer"];
|
|
17
|
-
const _c3 = ["innerBranch"];
|
|
18
|
-
function LimbleTreeNodeComponent_drop_zone_0_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
-
i0.ɵɵelement(0, "drop-zone", 7);
|
|
20
|
-
} if (rf & 2) {
|
|
21
|
-
const ctx_r0 = i0.ɵɵnextContext();
|
|
22
|
-
i0.ɵɵproperty("dropZone", ctx_r0.dropZoneAbove);
|
|
23
|
-
} }
|
|
24
|
-
function LimbleTreeNodeComponent_ng_template_5_Template(rf, ctx) { }
|
|
25
|
-
function LimbleTreeNodeComponent_limble_tree_branch_7_Template(rf, ctx) { if (rf & 1) {
|
|
26
|
-
i0.ɵɵelement(0, "limble-tree-branch", 8, 9);
|
|
27
|
-
} if (rf & 2) {
|
|
28
|
-
const ctx_r5 = i0.ɵɵnextContext();
|
|
29
|
-
i0.ɵɵproperty("branch", ctx_r5.branch);
|
|
30
|
-
} }
|
|
31
|
-
function LimbleTreeNodeComponent_drop_zone_8_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
-
i0.ɵɵelement(0, "drop-zone", 7);
|
|
33
|
-
} if (rf & 2) {
|
|
34
|
-
const ctx_r6 = i0.ɵɵnextContext();
|
|
35
|
-
i0.ɵɵproperty("dropZone", ctx_r6.dropZoneBelow);
|
|
36
|
-
} }
|
|
37
|
-
export class LimbleTreeNodeComponent {
|
|
38
|
-
constructor(componentCreatorService, changeDetectorRef, dragStateService, dropZoneService, treeService, globalEventsService, ngZone, treeConstructionStatus) {
|
|
39
|
-
this.componentCreatorService = componentCreatorService;
|
|
40
|
-
this.changeDetectorRef = changeDetectorRef;
|
|
41
|
-
this.dragStateService = dragStateService;
|
|
42
|
-
this.dropZoneService = dropZoneService;
|
|
43
|
-
this.treeService = treeService;
|
|
44
|
-
this.globalEventsService = globalEventsService;
|
|
45
|
-
this.ngZone = ngZone;
|
|
46
|
-
this.treeConstructionStatus = treeConstructionStatus;
|
|
47
|
-
this.treeConstructionStatus.constructing();
|
|
48
|
-
if (this.treeService.treeOptions !== undefined &&
|
|
49
|
-
this.treeService.treeOptions.listMode !== true) {
|
|
50
|
-
this.renderInnerBranch = true;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
this.renderInnerBranch = false;
|
|
54
|
-
}
|
|
55
|
-
this.renderDropZoneBelow = false;
|
|
56
|
-
this.renderDropZoneAbove = false;
|
|
57
|
-
this.treeChangeSubscription = this.treeService.changes$
|
|
58
|
-
.pipe(
|
|
59
|
-
//The first one is the initial tree render, which we can ignore
|
|
60
|
-
skip(1))
|
|
61
|
-
.subscribe(() => {
|
|
62
|
-
this.treeChangeHandler();
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
treeChangeHandler() {
|
|
66
|
-
if (this.branch !== undefined &&
|
|
67
|
-
this.currentBranchCoordinates !== undefined &&
|
|
68
|
-
!arraysAreEqual(this.branch.getCoordinates(), this.currentBranchCoordinates)) {
|
|
69
|
-
this.updateDropZones();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
ngOnInit() {
|
|
73
|
-
var _a, _b, _c;
|
|
74
|
-
if (((_a = this.treeService.treeOptions) === null || _a === void 0 ? void 0 : _a.allowDragging) === false) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const parent = (_b = this.branch) === null || _b === void 0 ? void 0 : _b.getParent();
|
|
78
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.data) !== null) {
|
|
79
|
-
const parentData = parent === null || parent === void 0 ? void 0 : parent.data;
|
|
80
|
-
if (!isNestingAllowed(this.treeService.treeOptions, parentData)) {
|
|
81
|
-
this.renderInnerBranch = false;
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
this.registerDropZones();
|
|
86
|
-
this.currentBranchCoordinates = (_c = this.branch) === null || _c === void 0 ? void 0 : _c.getCoordinates();
|
|
87
|
-
this.ngZone.runOutsideAngular(() => {
|
|
88
|
-
if (this.dropZoneAbove === undefined ||
|
|
89
|
-
this.dropZoneBelow === undefined) {
|
|
90
|
-
throw new Error("Zones not registered");
|
|
91
|
-
}
|
|
92
|
-
merge(this.dropZoneAbove.getCommChannel(), this.dropZoneBelow.getCommChannel())
|
|
93
|
-
.pipe(filter((message) => message === "checkRendered"))
|
|
94
|
-
.subscribe(() => {
|
|
95
|
-
if (this.dropZoneAbove === undefined ||
|
|
96
|
-
this.dropZoneBelow === undefined ||
|
|
97
|
-
this.branch === undefined) {
|
|
98
|
-
throw new Error("Zones not registered");
|
|
99
|
-
}
|
|
100
|
-
this.renderDropZoneAbove = this.dropZoneAbove.isRendered();
|
|
101
|
-
this.renderDropZoneBelow = this.dropZoneBelow.isRendered();
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
ngAfterViewInit() {
|
|
106
|
-
this.renderNode();
|
|
107
|
-
this.setDropZoneHosts();
|
|
108
|
-
this.checkForHandle();
|
|
109
|
-
this.treeConstructionStatus.doneConstructing();
|
|
110
|
-
this.changeDetectorRef.detectChanges();
|
|
111
|
-
}
|
|
112
|
-
ngOnDestroy() {
|
|
113
|
-
this.treeChangeSubscription.unsubscribe();
|
|
114
|
-
if (this.dropZoneAbove !== undefined) {
|
|
115
|
-
this.dropZoneService.removeDropZone(this.dropZoneAbove);
|
|
116
|
-
}
|
|
117
|
-
if (this.dropZoneBelow !== undefined) {
|
|
118
|
-
this.dropZoneService.removeDropZone(this.dropZoneBelow);
|
|
119
|
-
}
|
|
120
|
-
this.treeService.cleanupSignal$.next(true);
|
|
121
|
-
}
|
|
122
|
-
dragstartHandler(event) {
|
|
123
|
-
var _a;
|
|
124
|
-
event.stopPropagation();
|
|
125
|
-
if (event.dataTransfer === null ||
|
|
126
|
-
this.branch === undefined ||
|
|
127
|
-
this.parentHost === undefined) {
|
|
128
|
-
throw new Error("failed to run dragstartHandler");
|
|
129
|
-
}
|
|
130
|
-
const draggedElement = event.target;
|
|
131
|
-
if (((_a = draggedElement.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) !== "LIMBLE-TREE-NODE") {
|
|
132
|
-
//Don't drag stuff that isn't part of the tree
|
|
133
|
-
event.preventDefault();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
event.dataTransfer.effectAllowed = "move";
|
|
137
|
-
this.dragStateService.dragging(this.branch, this.parentHost);
|
|
138
|
-
const treeElement = draggedElement.closest("limble-tree-root");
|
|
139
|
-
if (treeElement === null) {
|
|
140
|
-
throw new Error("could not get root of tree");
|
|
141
|
-
}
|
|
142
|
-
this.ngZone.runOutsideAngular(() => {
|
|
143
|
-
//We have to use a setTimeout due to a bug in chrome: https://stackoverflow.com/a/20733870/8796651
|
|
144
|
-
setTimeout(() => {
|
|
145
|
-
var _a, _b;
|
|
146
|
-
draggedElement.classList.add("dragging");
|
|
147
|
-
if (((_a = this.treeService.treeData) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
|
|
148
|
-
((_b = this.branch) === null || _b === void 0 ? void 0 : _b.getCoordinates().length) === 1) {
|
|
149
|
-
//We are dragging the only element in the tree, so we have to use the placeholder system
|
|
150
|
-
this.treeService.placeholder$.next(true);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
//We use this weird subscription/timeout combo in order to avoid a strange bug where the dragleave event
|
|
154
|
-
//does not fire if the user drags out of the tree too quickly. This issue would make the drop zone
|
|
155
|
-
//remain in the UI, potentially causing drop zones to appear in multiple trees at a time. This subscription
|
|
156
|
-
//waits for the dragover event on the tree to fire before rendering any drop zones. If the dragover
|
|
157
|
-
//event does not fire within a half second, we know the mouse left the tree too quickly, and we won't
|
|
158
|
-
//render the drop zone at all.
|
|
159
|
-
const dragSubscription = fromEvent(treeElement, "dragover")
|
|
160
|
-
.pipe(first())
|
|
161
|
-
.subscribe((dragoverEvent) => {
|
|
162
|
-
dragoverEvent.stopPropagation();
|
|
163
|
-
if (this.branch === undefined) {
|
|
164
|
-
throw new Error("Could not show surrounding drop zones");
|
|
165
|
-
}
|
|
166
|
-
const parent = this.branch.getParent();
|
|
167
|
-
let parentData;
|
|
168
|
-
let parentNestingAllowed = true;
|
|
169
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.data) !== null) {
|
|
170
|
-
parentData = parent === null || parent === void 0 ? void 0 : parent.data;
|
|
171
|
-
parentNestingAllowed = isNestingAllowed(this.treeService.treeOptions, parentData);
|
|
172
|
-
}
|
|
173
|
-
if (this.dropZoneAbove !== undefined && parentNestingAllowed) {
|
|
174
|
-
this.dropZoneService.showDropZoneFamily(this.dropZoneAbove, {
|
|
175
|
-
joinFamilies: true
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
setTimeout(() => {
|
|
180
|
-
if (!dragSubscription.closed) {
|
|
181
|
-
dragSubscription.unsubscribe();
|
|
182
|
-
}
|
|
183
|
-
}, 500);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
dragendHandler(event) {
|
|
187
|
-
var _a, _b;
|
|
188
|
-
event === null || event === void 0 ? void 0 : event.stopPropagation();
|
|
189
|
-
if (this.draggableDiv === undefined) {
|
|
190
|
-
throw new Error("could not get draggable div");
|
|
191
|
-
}
|
|
192
|
-
this.draggableDiv.nativeElement.classList.remove("dragging");
|
|
193
|
-
if (this.dragStateService.getState() === "captured") {
|
|
194
|
-
if (this.treeService.captured === false) {
|
|
195
|
-
//Dropped in a different tree. Remove the one in this tree
|
|
196
|
-
if (this.branch === undefined) {
|
|
197
|
-
throw new Error("could not get branch in dragendHandler");
|
|
198
|
-
}
|
|
199
|
-
this.treeService.cleanupSignal$.next(true);
|
|
200
|
-
this.treeService.captured = false;
|
|
201
|
-
}
|
|
202
|
-
this.dragStateService.release();
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
//Wasn't dropped into a valid tree, so reset for next drag and
|
|
206
|
-
//don't do anything else.
|
|
207
|
-
this.dragStateService.release();
|
|
208
|
-
this.dropZoneService.clearVisibleZones();
|
|
209
|
-
this.dropZoneService.restoreFamilies();
|
|
210
|
-
if (((_a = this.treeService.treeData) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
|
|
211
|
-
((_b = this.branch) === null || _b === void 0 ? void 0 : _b.getCoordinates().length) === 1) {
|
|
212
|
-
//We were dragging the only element in the tree, so we have to
|
|
213
|
-
//remove the placeholder that we added in the dragstart
|
|
214
|
-
this.treeService.placeholder$.next(false);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
dragoverHandler(event) {
|
|
219
|
-
var _a, _b, _c;
|
|
220
|
-
if (this.globalEventsService.scrolling === true) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
if (this.branch === undefined) {
|
|
224
|
-
throw new Error("Can't get current branch during dragover event");
|
|
225
|
-
}
|
|
226
|
-
const data = this.dragStateService.getData();
|
|
227
|
-
if (data === undefined) {
|
|
228
|
-
//They might be dragging something that isn't a node. Just ignore it.
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
const sourceBranch = data.branch;
|
|
232
|
-
//If trying to drop on self, return.
|
|
233
|
-
if (sourceBranch === this.branch ||
|
|
234
|
-
this.branch.getAncestors().includes(sourceBranch)) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const target = event.currentTarget.closest(".node-host-container");
|
|
238
|
-
if (!(target instanceof HTMLElement)) {
|
|
239
|
-
throw new Error("Failed to find node host container while dragging");
|
|
240
|
-
}
|
|
241
|
-
let topLine;
|
|
242
|
-
let bottomLine;
|
|
243
|
-
if (((_a = this.innerBranch) === null || _a === void 0 ? void 0 : _a.renderDropZoneInside) === false) {
|
|
244
|
-
topLine = target.offsetHeight / 2 - 6;
|
|
245
|
-
bottomLine = topLine;
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
topLine = target.offsetHeight / 3 - 3; //an imaginary line 1/3 of the way down from the top of the element;
|
|
249
|
-
bottomLine = topLine * 2; //an imaginary line 1/3 of the way up from the bottom of the element;
|
|
250
|
-
}
|
|
251
|
-
const parent = this.branch.getParent();
|
|
252
|
-
let parentData;
|
|
253
|
-
let parentNestingAllowed = true;
|
|
254
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.data) !== null) {
|
|
255
|
-
parentData = parent === null || parent === void 0 ? void 0 : parent.data;
|
|
256
|
-
parentNestingAllowed = isNestingAllowed(this.treeService.treeOptions, parentData);
|
|
257
|
-
}
|
|
258
|
-
/** The y-coordinates of the mouse in relation to the node it is hovering over */
|
|
259
|
-
const offsetY = event.clientY - target.getBoundingClientRect().top;
|
|
260
|
-
const activeDropZone = this.dropZoneService.getActiveDropZone();
|
|
261
|
-
if (offsetY < topLine &&
|
|
262
|
-
this.dropZoneAbove !== undefined &&
|
|
263
|
-
parentNestingAllowed &&
|
|
264
|
-
(activeDropZone === null ||
|
|
265
|
-
!DropZone.dropZoneLocationsAreEqual(activeDropZone, this.dropZoneAbove))) {
|
|
266
|
-
const index = this.branch.getIndex();
|
|
267
|
-
if (index === undefined || index === null) {
|
|
268
|
-
throw new Error("can't get branch index");
|
|
269
|
-
}
|
|
270
|
-
this.dropZoneService.showDropZoneFamily(this.dropZoneAbove, {
|
|
271
|
-
activateLowestInsteadOfFounder: true
|
|
272
|
-
});
|
|
273
|
-
if (suddenTreeExit(event)) {
|
|
274
|
-
this.dropZoneService.clearVisibleZones();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
else if (offsetY < bottomLine &&
|
|
278
|
-
offsetY > topLine &&
|
|
279
|
-
((_b = this.innerBranch) === null || _b === void 0 ? void 0 : _b.renderDropZoneInside) === true &&
|
|
280
|
-
((_c = this.innerBranch) === null || _c === void 0 ? void 0 : _c.dropZoneInside) !== undefined &&
|
|
281
|
-
(activeDropZone === null ||
|
|
282
|
-
!DropZone.dropZoneLocationsAreEqual(activeDropZone, this.innerBranch.dropZoneInside))) {
|
|
283
|
-
this.dropZoneService.showDropZoneFamily(this.innerBranch.dropZoneInside);
|
|
284
|
-
if (suddenTreeExit(event)) {
|
|
285
|
-
this.dropZoneService.clearVisibleZones();
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
else if (offsetY >= bottomLine &&
|
|
289
|
-
this.dropZoneBelow !== undefined &&
|
|
290
|
-
parentNestingAllowed &&
|
|
291
|
-
(activeDropZone === null ||
|
|
292
|
-
!DropZone.dropZoneLocationsAreEqual(activeDropZone, this.dropZoneBelow)) &&
|
|
293
|
-
this.branch.getChildren().length === 0) {
|
|
294
|
-
const index = this.branch.getIndex();
|
|
295
|
-
if (index === undefined || index === null) {
|
|
296
|
-
throw new Error("can't get branch index");
|
|
297
|
-
}
|
|
298
|
-
this.dropZoneService.showDropZoneFamily(this.dropZoneBelow);
|
|
299
|
-
if (suddenTreeExit(event)) {
|
|
300
|
-
this.dropZoneService.clearVisibleZones();
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
renderNode() {
|
|
305
|
-
var _a;
|
|
306
|
-
if (this.nodeHost === undefined || this.branch === undefined) {
|
|
307
|
-
throw new Error("Failed to render tree node");
|
|
308
|
-
}
|
|
309
|
-
let component = this.branch.data.component;
|
|
310
|
-
if (component === undefined) {
|
|
311
|
-
component = (_a = this.treeService.treeOptions) === null || _a === void 0 ? void 0 : _a.defaultComponent;
|
|
312
|
-
}
|
|
313
|
-
if (component === undefined) {
|
|
314
|
-
throw new Error("limbleTree requires a component to render");
|
|
315
|
-
}
|
|
316
|
-
const componentRef = this.componentCreatorService.appendComponent(component.class, this.nodeHost);
|
|
317
|
-
componentRef.instance.nodeData = this.branch.data;
|
|
318
|
-
for (const binding in component.bindings) {
|
|
319
|
-
componentRef.instance[binding] = component.bindings[binding];
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
registerDropZones() {
|
|
323
|
-
this.addDropZoneAbove();
|
|
324
|
-
this.addDropZoneBelow();
|
|
325
|
-
}
|
|
326
|
-
addDropZoneAbove() {
|
|
327
|
-
var _a;
|
|
328
|
-
if (this.branch === undefined) {
|
|
329
|
-
throw new Error("failed to register drop zone above");
|
|
330
|
-
}
|
|
331
|
-
const parent = this.branch.getParent();
|
|
332
|
-
const currentCoordinates = this.branch.getCoordinates();
|
|
333
|
-
const index = currentCoordinates[currentCoordinates.length - 1];
|
|
334
|
-
this.dropZoneAbove = new DropZone([...((_a = parent === null || parent === void 0 ? void 0 : parent.getCoordinates()) !== null && _a !== void 0 ? _a : [])], index);
|
|
335
|
-
this.dropZoneService.addDropZone(this.dropZoneAbove);
|
|
336
|
-
}
|
|
337
|
-
addDropZoneBelow() {
|
|
338
|
-
var _a;
|
|
339
|
-
if (this.branch === undefined) {
|
|
340
|
-
throw new Error("failed to register drop zone below");
|
|
341
|
-
}
|
|
342
|
-
const parent = this.branch.getParent();
|
|
343
|
-
const currentCoordinates = this.branch.getCoordinates();
|
|
344
|
-
const index = currentCoordinates[currentCoordinates.length - 1];
|
|
345
|
-
this.dropZoneBelow = new DropZone([...((_a = parent === null || parent === void 0 ? void 0 : parent.getCoordinates()) !== null && _a !== void 0 ? _a : [])], index + 1);
|
|
346
|
-
this.dropZoneService.addDropZone(this.dropZoneBelow);
|
|
347
|
-
}
|
|
348
|
-
updateDropZones() {
|
|
349
|
-
var _a;
|
|
350
|
-
this.currentBranchCoordinates = (_a = this.branch) === null || _a === void 0 ? void 0 : _a.getCoordinates();
|
|
351
|
-
this.updateDropZoneAbove();
|
|
352
|
-
this.updateDropZoneBelow();
|
|
353
|
-
this.updateDropZoneInside();
|
|
354
|
-
this.setDropZoneHosts();
|
|
355
|
-
}
|
|
356
|
-
updateDropZoneAbove() {
|
|
357
|
-
var _a;
|
|
358
|
-
if (this.branch === undefined || this.dropZoneAbove === undefined) {
|
|
359
|
-
throw new Error("failed to update drop zone above");
|
|
360
|
-
}
|
|
361
|
-
const parent = this.branch.getParent();
|
|
362
|
-
const currentCoordinates = this.branch.getCoordinates();
|
|
363
|
-
const index = currentCoordinates[currentCoordinates.length - 1];
|
|
364
|
-
const location = this.dropZoneAbove.getLocation();
|
|
365
|
-
location.setParentCoordinates([...((_a = parent === null || parent === void 0 ? void 0 : parent.getCoordinates()) !== null && _a !== void 0 ? _a : [])]);
|
|
366
|
-
location.setInsertIndex(index);
|
|
367
|
-
}
|
|
368
|
-
updateDropZoneBelow() {
|
|
369
|
-
var _a;
|
|
370
|
-
if (this.branch === undefined || this.dropZoneBelow === undefined) {
|
|
371
|
-
throw new Error("failed to update drop zone below");
|
|
372
|
-
}
|
|
373
|
-
const parent = this.branch.getParent();
|
|
374
|
-
const currentCoordinates = this.branch.getCoordinates();
|
|
375
|
-
const index = currentCoordinates[currentCoordinates.length - 1];
|
|
376
|
-
const location = this.dropZoneBelow.getLocation();
|
|
377
|
-
location.setParentCoordinates([...((_a = parent === null || parent === void 0 ? void 0 : parent.getCoordinates()) !== null && _a !== void 0 ? _a : [])]);
|
|
378
|
-
location.setInsertIndex(index + 1);
|
|
379
|
-
}
|
|
380
|
-
updateDropZoneInside() {
|
|
381
|
-
var _a;
|
|
382
|
-
if (((_a = this.innerBranch) === null || _a === void 0 ? void 0 : _a.dropZoneInside) === undefined) {
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
if (this.branch === undefined) {
|
|
386
|
-
throw new Error("failed to update drop zone inside");
|
|
387
|
-
}
|
|
388
|
-
const location = this.innerBranch.dropZoneInside.getLocation();
|
|
389
|
-
location.setParentCoordinates([...this.branch.getCoordinates()]);
|
|
390
|
-
}
|
|
391
|
-
setDropZoneHosts() {
|
|
392
|
-
if (this.dropZoneAbove === undefined ||
|
|
393
|
-
this.dropZoneBelow === undefined) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
this.dropZoneAbove.setHost(this.parentHost);
|
|
397
|
-
this.dropZoneBelow.setHost(this.parentHost);
|
|
398
|
-
}
|
|
399
|
-
checkForHandle() {
|
|
400
|
-
var _a;
|
|
401
|
-
if (this.nodeHostContainer === undefined ||
|
|
402
|
-
this.draggableDiv === undefined) {
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
const nodeHostContainerElement = this.nodeHostContainer.nativeElement;
|
|
406
|
-
const handle = nodeHostContainerElement.querySelector(".limble-tree-handle");
|
|
407
|
-
const draggableDivElement = this.draggableDiv.nativeElement;
|
|
408
|
-
if (!isDraggingAllowed(this.treeService.treeOptions, (_a = this.branch) === null || _a === void 0 ? void 0 : _a.data)) {
|
|
409
|
-
draggableDivElement.setAttribute("draggable", "false");
|
|
410
|
-
}
|
|
411
|
-
else if (handle === null) {
|
|
412
|
-
draggableDivElement.setAttribute("draggable", "true");
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
handle.addEventListener("mousedown", () => {
|
|
416
|
-
draggableDivElement.setAttribute("draggable", "true");
|
|
417
|
-
//For some reason mouseup doesn't fire after a drag, so we use this observable sequence instead.
|
|
418
|
-
const dragging = this.dragStateService.state$.pipe(filter((state) => state === "dragging"), first());
|
|
419
|
-
this.dragStateService.state$
|
|
420
|
-
.pipe(skipUntil(dragging), filter((state) => state === "idle"), first())
|
|
421
|
-
.subscribe(() => {
|
|
422
|
-
draggableDivElement.setAttribute("draggable", "false");
|
|
423
|
-
});
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
LimbleTreeNodeComponent.ɵfac = function LimbleTreeNodeComponent_Factory(t) { return new (t || LimbleTreeNodeComponent)(i0.ɵɵdirectiveInject(i1.ComponentCreatorService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i2.DragStateService), i0.ɵɵdirectiveInject(i3.DropZoneService), i0.ɵɵdirectiveInject(i4.TreeService), i0.ɵɵdirectiveInject(i5.GlobalEventsService), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i6.TreeConstructionStatus)); };
|
|
429
|
-
LimbleTreeNodeComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LimbleTreeNodeComponent, selectors: [["limble-tree-node"]], viewQuery: function LimbleTreeNodeComponent_Query(rf, ctx) { if (rf & 1) {
|
|
430
|
-
i0.ɵɵviewQuery(_c0, 5, ViewContainerRef);
|
|
431
|
-
i0.ɵɵviewQuery(_c1, 5, ElementRef);
|
|
432
|
-
i0.ɵɵviewQuery(_c2, 5, ElementRef);
|
|
433
|
-
i0.ɵɵviewQuery(_c3, 5, LimbleTreeBranchComponent);
|
|
434
|
-
} if (rf & 2) {
|
|
435
|
-
let _t;
|
|
436
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.nodeHost = _t.first);
|
|
437
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.draggableDiv = _t.first);
|
|
438
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.nodeHostContainer = _t.first);
|
|
439
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.innerBranch = _t.first);
|
|
440
|
-
} }, inputs: { branch: "branch", parentHost: "parentHost" }, decls: 9, vars: 4, consts: [[3, "dropZone", 4, "ngIf"], [1, "limble-parent-container", 3, "dragstart", "dragend"], ["draggableDiv", ""], [1, "node-host-container", 3, "dragoverEventThrottle", "dragoverNoChangeDetect"], ["nodeHostContainer", ""], ["nodeHost", ""], [3, "branch", 4, "ngIf"], [3, "dropZone"], [3, "branch"], ["innerBranch", ""]], template: function LimbleTreeNodeComponent_Template(rf, ctx) { if (rf & 1) {
|
|
441
|
-
i0.ɵɵtemplate(0, LimbleTreeNodeComponent_drop_zone_0_Template, 1, 1, "drop-zone", 0);
|
|
442
|
-
i0.ɵɵelementStart(1, "div", 1, 2);
|
|
443
|
-
i0.ɵɵlistener("dragstart", function LimbleTreeNodeComponent_Template_div_dragstart_1_listener($event) { return ctx.dragstartHandler($event); })("dragend", function LimbleTreeNodeComponent_Template_div_dragend_1_listener($event) { return ctx.dragendHandler($event); });
|
|
444
|
-
i0.ɵɵelementStart(3, "div", 3, 4);
|
|
445
|
-
i0.ɵɵlistener("dragoverNoChangeDetect", function LimbleTreeNodeComponent_Template_div_dragoverNoChangeDetect_3_listener($event) { return ctx.dragoverHandler($event); });
|
|
446
|
-
i0.ɵɵtemplate(5, LimbleTreeNodeComponent_ng_template_5_Template, 0, 0, "ng-template", null, 5, i0.ɵɵtemplateRefExtractor);
|
|
447
|
-
i0.ɵɵelementEnd();
|
|
448
|
-
i0.ɵɵtemplate(7, LimbleTreeNodeComponent_limble_tree_branch_7_Template, 2, 1, "limble-tree-branch", 6);
|
|
449
|
-
i0.ɵɵelementEnd();
|
|
450
|
-
i0.ɵɵtemplate(8, LimbleTreeNodeComponent_drop_zone_8_Template, 1, 1, "drop-zone", 0);
|
|
451
|
-
} if (rf & 2) {
|
|
452
|
-
i0.ɵɵproperty("ngIf", ctx.renderDropZoneAbove === true);
|
|
453
|
-
i0.ɵɵadvance(3);
|
|
454
|
-
i0.ɵɵproperty("dragoverEventThrottle", 10);
|
|
455
|
-
i0.ɵɵadvance(4);
|
|
456
|
-
i0.ɵɵproperty("ngIf", ctx.branch !== undefined && ctx.renderInnerBranch === true);
|
|
457
|
-
i0.ɵɵadvance(1);
|
|
458
|
-
i0.ɵɵproperty("ngIf", ctx.renderDropZoneBelow === true);
|
|
459
|
-
} }, styles: [".dragging[_ngcontent-%COMP%]{position:absolute;transition:transform .01s;transform:translate(-9999px)}"] });
|
|
460
|
-
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LimbleTreeNodeComponent, [{
|
|
461
|
-
type: Component,
|
|
462
|
-
args: [{
|
|
463
|
-
selector: "limble-tree-node",
|
|
464
|
-
templateUrl: "./limble-tree-node.component.html",
|
|
465
|
-
styleUrls: ["./limble-tree-node.component.scss"]
|
|
466
|
-
}]
|
|
467
|
-
}], function () { return [{ type: i1.ComponentCreatorService }, { type: i0.ChangeDetectorRef }, { type: i2.DragStateService }, { type: i3.DropZoneService }, { type: i4.TreeService }, { type: i5.GlobalEventsService }, { type: i0.NgZone }, { type: i6.TreeConstructionStatus }]; }, { branch: [{
|
|
468
|
-
type: Input
|
|
469
|
-
}], nodeHost: [{
|
|
470
|
-
type: ViewChild,
|
|
471
|
-
args: ["nodeHost", { read: ViewContainerRef }]
|
|
472
|
-
}], draggableDiv: [{
|
|
473
|
-
type: ViewChild,
|
|
474
|
-
args: ["draggableDiv", { read: ElementRef }]
|
|
475
|
-
}], nodeHostContainer: [{
|
|
476
|
-
type: ViewChild,
|
|
477
|
-
args: ["nodeHostContainer", { read: ElementRef }]
|
|
478
|
-
}], parentHost: [{
|
|
479
|
-
type: Input
|
|
480
|
-
}], innerBranch: [{
|
|
481
|
-
type: ViewChild,
|
|
482
|
-
args: ["innerBranch", { read: LimbleTreeBranchComponent }]
|
|
483
|
-
}] }); })();
|
|
484
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltYmxlLXRyZWUtbm9kZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLW5vZGUvbGltYmxlLXRyZWUtbm9kZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2xpbWJsZS10cmVlLW5vZGUvbGltYmxlLXRyZWUtbm9kZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0osU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBSUwsU0FBUyxFQUNULGdCQUFnQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQU12QixPQUFPLEVBQ0osY0FBYyxFQUNkLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsY0FBYyxFQUNoQixNQUFNLFNBQVMsQ0FBQztBQUNqQixPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQzs7Ozs7Ozs7Ozs7OztJQzNCL0YsK0JBR2E7OztJQURWLCtDQUEwQjs7OztJQWdCMUIsMkNBSXNCOzs7SUFGbkIsc0NBQWlCOzs7SUFJdkIsK0JBR2E7OztJQURWLCtDQUEwQjs7QURTN0IsTUFBTSxPQUFPLHVCQUF1QjtJQXVCakMsWUFDb0IsdUJBQWdELEVBQ2hELGlCQUFvQyxFQUNwQyxnQkFBa0MsRUFDbEMsZUFBZ0MsRUFDaEMsV0FBd0IsRUFDeEIsbUJBQXdDLEVBQ3hDLE1BQWMsRUFDZCxzQkFBOEM7UUFQOUMs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SUFBQyw4RkFDM0IsMEJBQXNCLElBREs7UUFLdEMsaUNBS0M7UUFIRSx5SUFBMEIsMkJBQXVCLElBQUM7UUFJbEQseUhBQXFDO1FBQ3hDLGlCQUFNO1FBQ04sc0dBSXNCO1FBQ3pCLGlCQUFNO1FBQ04sb0ZBR2E7O1FBMUJULHVEQUFrQztRQVloQyxlQUE0QjtRQUE1QiwwQ0FBNEI7UUFNM0IsZUFBd0Q7UUFBeEQsaUZBQXdEO1FBTTNELGVBQWtDO1FBQWxDLHVEQUFrQzs7dUZEVXpCLHVCQUF1QjtjQUxuQyxTQUFTO2VBQUM7Z0JBQ1IsUUFBUSxFQUFFLGtCQUFrQjtnQkFDNUIsV0FBVyxFQUFFLG1DQUFtQztnQkFDaEQsU0FBUyxFQUFFLENBQUMsbUNBQW1DLENBQUM7YUFDbEQ7NlJBSVcsTUFBTTtrQkFBZCxLQUFLO1lBQ3FELFFBQVE7a0JBQWxFLFNBQVM7bUJBQUMsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1lBUVEsWUFBWTtrQkFBcEUsU0FBUzttQkFBQyxjQUFjLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBSXZDLGlCQUFpQjtrQkFEeEIsU0FBUzttQkFBQyxtQkFBbUIsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUU7WUFJM0MsVUFBVTtrQkFBbEIsS0FBSztZQUVFLFdBQVc7a0JBRGxCLFNBQVM7bUJBQUMsYUFBYSxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgIENvbXBvbmVudCxcclxuICAgRWxlbWVudFJlZixcclxuICAgSW5wdXQsXHJcbiAgIE5nWm9uZSxcclxuICAgT25EZXN0cm95LFxyXG4gICBPbkluaXQsXHJcbiAgIFZpZXdDaGlsZCxcclxuICAgVmlld0NvbnRhaW5lclJlZlxyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IENvbXBvbmVudENyZWF0b3JTZXJ2aWNlIH0gZnJvbSBcIi4uL3NpbmdsZXRvbnMvY29tcG9uZW50LWNyZWF0b3Iuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcm9wWm9uZVNlcnZpY2UgfSBmcm9tIFwiLi4vbGltYmxlLXRyZWUtcm9vdC9kcm9wLXpvbmUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcmFnU3RhdGVTZXJ2aWNlIH0gZnJvbSBcIi4uL3NpbmdsZXRvbnMvZHJhZy1zdGF0ZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IExpbWJsZVRyZWVOb2RlLCBUcmVlU2VydmljZSB9IGZyb20gXCIuLi9saW1ibGUtdHJlZS1yb290L3RyZWUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBCcmFuY2gsIEJyYW5jaENvb3JkaW5hdGVzIH0gZnJvbSBcIi4uL2NsYXNzZXMvQnJhbmNoXCI7XHJcbmltcG9ydCB7XHJcbiAgIGFycmF5c0FyZUVxdWFsLFxyXG4gICBpc0RyYWdnaW5nQWxsb3dlZCxcclxuICAgaXNOZXN0aW5nQWxsb3dlZCxcclxuICAgc3VkZGVuVHJlZUV4aXRcclxufSBmcm9tIFwiLi4vdXRpbFwiO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIGZpcnN0LCBza2lwLCBza2lwVW50aWwgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcclxuaW1wb3J0IHsgR2xvYmFsRXZlbnRzU2VydmljZSB9IGZyb20gXCIuLi9zaW5nbGV0b25zL2dsb2JhbC1ldmVudHMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBEcm9wWm9uZSB9IGZyb20gXCIuLi9jbGFzc2VzL0Ryb3Bab25lXCI7XHJcbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IExpbWJsZVRyZWVCcmFuY2hDb21wb25lbnQgfSBmcm9tIFwiLi4vbGltYmxlLXRyZWUtYnJhbmNoL2xpbWJsZS10cmVlLWJyYW5jaC5jb21wb25lbnRcIjtcclxuaW1wb3J0IHsgVHJlZUNvbnN0cnVjdGlvblN0YXR1cyB9IGZyb20gXCIuLi9saW1ibGUtdHJlZS1yb290L3RyZWUtY29uc3RydWN0aW9uLXN0YXR1cy5zZXJ2aWNlXCI7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgc2VsZWN0b3I6IFwibGltYmxlLXRyZWUtbm9kZVwiLFxyXG4gICB0ZW1wbGF0ZVVybDogXCIuL2xpbWJsZS10cmVlLW5vZGUuY29tcG9uZW50Lmh0bWxcIixcclxuICAgc3R5bGVVcmxzOiBbXCIuL2xpbWJsZS10cmVlLW5vZGUuY29tcG9uZW50LnNjc3NcIl1cclxufSlcclxuZXhwb3J0IGNsYXNzIExpbWJsZVRyZWVOb2RlQ29tcG9uZW50XHJcbiAgIGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3lcclxue1xyXG4gICBASW5wdXQoKSBicmFuY2g6IEJyYW5jaDxhbnk+IHwgdW5kZWZpbmVkO1xyXG4gICBAVmlld0NoaWxkKFwibm9kZUhvc3RcIiwgeyByZWFkOiBWaWV3Q29udGFpbmVyUmVmIH0pIHByaXZhdGUgbm9kZUhvc3Q6XHJcbiAgICAgIHwgVmlld0NvbnRhaW5lclJlZlxyXG4gICAgICB8IHVuZGVmaW5lZDtcclxuICAgcHVibGljIGRyb3Bab25lQWJvdmU6IERyb3Bab25lIHwgdW5kZWZpbmVkO1xyXG4gICBwdWJsaWMgcmVuZGVyRHJvcFpvbmVBYm92ZTogYm9vbGVhbjtcclxuICAgcHVibGljIGRyb3Bab25lQmVsb3c6IERyb3Bab25lIHwgdW5kZWZpbmVkO1xyXG4gICBwdWJsaWMgcmVuZGVyRHJvcFpvbmVCZWxvdzogYm9vbGVhbjtcclxuICAgcHVibGljIHJlbmRlcklubmVyQnJhbmNoOiBCb29sZWFuO1xyXG4gICBAVmlld0NoaWxkKFwiZHJhZ2dhYmxlRGl2XCIsIHsgcmVhZDogRWxlbWVudFJlZiB9KSBwcml2YXRlIGRyYWdnYWJsZURpdjpcclxuICAgICAgfCBFbGVtZW50UmVmPEhUTUxFbGVtZW50PlxyXG4gICAgICB8IHVuZGVmaW5lZDtcclxuICAgQFZpZXdDaGlsZChcIm5vZGVIb3N0Q29udGFpbmVyXCIsIHsgcmVhZDogRWxlbWVudFJlZiB9KVxyXG4gICBwcml2YXRlIG5vZGVIb3N0Q29udGFpbmVyOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IHVuZGVmaW5lZDtcclxuICAgcHJpdmF0ZSBjdXJyZW50QnJhbmNoQ29vcmRpbmF0ZXM6IEJyYW5jaENvb3JkaW5hdGVzIHwgdW5kZWZpbmVkO1xyXG4gICBwcml2YXRlIHJlYWRvbmx5IHRyZWVDaGFuZ2VTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICAgQElucHV0KCkgcGFyZW50SG9zdDogVmlld0NvbnRhaW5lclJlZiB8IHVuZGVmaW5lZDtcclxuICAgQFZpZXdDaGlsZChcImlubmVyQnJhbmNoXCIsIHsgcmVhZDogTGltYmxlVHJlZUJyYW5jaENvbXBvbmVudCB9KVxyXG4gICBwcml2YXRlIGlubmVyQnJhbmNoOiBMaW1ibGVUcmVlQnJhbmNoQ29tcG9uZW50IHwgdW5kZWZpbmVkO1xyXG5cclxuICAgY29uc3RydWN0b3IoXHJcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgY29tcG9uZW50Q3JlYXRvclNlcnZpY2U6IENvbXBvbmVudENyZWF0b3JTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBkcmFnU3RhdGVTZXJ2aWNlOiBEcmFnU3RhdGVTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGRyb3Bab25lU2VydmljZTogRHJvcFpvbmVTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVTZXJ2aWNlOiBUcmVlU2VydmljZSxcclxuICAgICAgcHJpdmF0ZSByZWFkb25seSBnbG9iYWxFdmVudHNTZXJ2aWNlOiBHbG9iYWxFdmVudHNTZXJ2aWNlLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxyXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IHRyZWVDb25zdHJ1Y3Rpb25TdGF0dXM6IFRyZWVDb25zdHJ1Y3Rpb25TdGF0dXNcclxuICAgKSB7XHJcbiAgICAgIHRoaXMudHJlZUNvbnN0cnVjdGlvblN0YXR1cy5jb25zdHJ1Y3RpbmcoKTtcclxuICAgICAgaWYgKFxyXG4gICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLnRyZWVPcHRpb25zICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgICAgdGhpcy50cmVlU2VydmljZS50cmVlT3B0aW9ucy5saXN0TW9kZSAhPT0gdHJ1ZVxyXG4gICAgICApIHtcclxuICAgICAgICAgdGhpcy5yZW5kZXJJbm5lckJyYW5jaCA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIHRoaXMucmVuZGVySW5uZXJCcmFuY2ggPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnJlbmRlckRyb3Bab25lQmVsb3cgPSBmYWxzZTtcclxuICAgICAgdGhpcy5yZW5kZXJEcm9wWm9uZUFib3ZlID0gZmFsc2U7XHJcbiAgICAgIHRoaXMudHJlZUNoYW5nZVN1YnNjcmlwdGlvbiA9IHRoaXMudHJlZVNlcnZpY2UuY2hhbmdlcyRcclxuICAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgIC8vVGhlIGZpcnN0IG9uZSBpcyB0aGUgaW5pdGlhbCB0cmVlIHJlbmRlciwgd2hpY2ggd2UgY2FuIGlnbm9yZVxyXG4gICAgICAgICAgICBza2lwKDEpXHJcbiAgICAgICAgIClcclxuICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudHJlZUNoYW5nZUhhbmRsZXIoKTtcclxuICAgICAgICAgfSk7XHJcbiAgIH1cclxuXHJcbiAgIHByaXZhdGUgdHJlZUNoYW5nZUhhbmRsZXIoKSB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICAgdGhpcy5icmFuY2ggIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICB0aGlzLmN1cnJlbnRCcmFuY2hDb29yZGluYXRlcyAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgICFhcnJheXNBcmVFcXVhbChcclxuICAgICAgICAgICAgdGhpcy5icmFuY2guZ2V0Q29vcmRpbmF0ZXMoKSxcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50QnJhbmNoQ29vcmRpbmF0ZXNcclxuICAgICAgICAgKVxyXG4gICAgICApIHtcclxuICAgICAgICAgdGhpcy51cGRhdGVEcm9wWm9uZXMoKTtcclxuICAgICAgfVxyXG4gICB9XHJcblxyXG4gICBuZ09uSW5pdCgpIHtcclxuICAgICAgaWYgKHRoaXMudHJlZVNlcnZpY2UudHJlZU9wdGlvbnM/LmFsbG93RHJhZ2dpbmcgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLmJyYW5jaD8uZ2V0UGFyZW50KCk7XHJcbiAgICAgIGlmIChwYXJlbnQ/LmRhdGEgIT09IG51bGwpIHtcclxuICAgICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHBhcmVudD8uZGF0YSBhcyBMaW1ibGVUcmVlTm9kZTtcclxuICAgICAgICAgaWYgKCFpc05lc3RpbmdBbGxvd2VkKHRoaXMudHJlZVNlcnZpY2UudHJlZU9wdGlvbnMsIHBhcmVudERhdGEpKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVySW5uZXJCcmFuY2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5yZWdpc3RlckRyb3Bab25lcygpO1xyXG4gICAgICB0aGlzLmN1cnJlbnRCcmFuY2hDb29yZGluYXRlcyA9IHRoaXMuYnJhbmNoPy5nZXRDb29yZGluYXRlcygpO1xyXG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgdGhpcy5kcm9wWm9uZUFib3ZlID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgdGhpcy5kcm9wWm9uZUJlbG93ID09PSB1bmRlZmluZWRcclxuICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlpvbmVzIG5vdCByZWdpc3RlcmVkXCIpO1xyXG4gICAgICAgICB9XHJcbiAgICAgICAgIG1lcmdlKFxyXG4gICAgICAgICAgICB0aGlzLmRyb3Bab25lQWJvdmUuZ2V0Q29tbUNoYW5uZWwoKSxcclxuICAgICAgICAgICAgdGhpcy5kcm9wWm9uZUJlbG93LmdldENvbW1DaGFubmVsKClcclxuICAgICAgICAgKVxyXG4gICAgICAgICAgICAucGlwZShmaWx0ZXIoKG1lc3NhZ2UpID0+IG1lc3NhZ2UgPT09IFwiY2hlY2tSZW5kZXJlZFwiKSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wWm9uZUFib3ZlID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wWm9uZUJlbG93ID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgdGhpcy5icmFuY2ggPT09IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiWm9uZXMgbm90IHJlZ2lzdGVyZWRcIik7XHJcbiAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJEcm9wWm9uZUFib3ZlID0gdGhpcy5kcm9wWm9uZUFib3ZlLmlzUmVuZGVyZWQoKTtcclxuICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJEcm9wWm9uZUJlbG93ID0gdGhpcy5kcm9wWm9uZUJlbG93LmlzUmVuZGVyZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICB9XHJcblxyXG4gICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyTm9kZSgpO1xyXG4gICAgICB0aGlzLnNldERyb3Bab25lSG9zdHMoKTtcclxuICAgICAgdGhpcy5jaGVja0ZvckhhbmRsZSgpO1xyXG4gICAgICB0aGlzLnRyZWVDb25zdHJ1Y3Rpb25TdGF0dXMuZG9uZUNvbnN0cnVjdGluZygpO1xyXG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcclxuICAgfVxyXG5cclxuICAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgIHRoaXMudHJlZUNoYW5nZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICBpZiAodGhpcy5kcm9wWm9uZUFib3ZlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2UucmVtb3ZlRHJvcFpvbmUodGhpcy5kcm9wWm9uZUFib3ZlKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5kcm9wWm9uZUJlbG93ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2UucmVtb3ZlRHJvcFpvbmUodGhpcy5kcm9wWm9uZUJlbG93KTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnRyZWVTZXJ2aWNlLmNsZWFudXBTaWduYWwkLm5leHQodHJ1ZSk7XHJcbiAgIH1cclxuXHJcbiAgIHB1YmxpYyBkcmFnc3RhcnRIYW5kbGVyKGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIGlmIChcclxuICAgICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyID09PSBudWxsIHx8XHJcbiAgICAgICAgIHRoaXMuYnJhbmNoID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgdGhpcy5wYXJlbnRIb3N0ID09PSB1bmRlZmluZWRcclxuICAgICAgKSB7XHJcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImZhaWxlZCB0byBydW4gZHJhZ3N0YXJ0SGFuZGxlclwiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBkcmFnZ2VkRWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgaWYgKGRyYWdnZWRFbGVtZW50LnBhcmVudEVsZW1lbnQ/LnRhZ05hbWUgIT09IFwiTElNQkxFLVRSRUUtTk9ERVwiKSB7XHJcbiAgICAgICAgIC8vRG9uJ3QgZHJhZyBzdHVmZiB0aGF0IGlzbid0IHBhcnQgb2YgdGhlIHRyZWVcclxuICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gXCJtb3ZlXCI7XHJcbiAgICAgIHRoaXMuZHJhZ1N0YXRlU2VydmljZS5kcmFnZ2luZyh0aGlzLmJyYW5jaCwgdGhpcy5wYXJlbnRIb3N0KTtcclxuICAgICAgY29uc3QgdHJlZUVsZW1lbnQgPSBkcmFnZ2VkRWxlbWVudC5jbG9zZXN0KFwibGltYmxlLXRyZWUtcm9vdFwiKTtcclxuICAgICAgaWYgKHRyZWVFbGVtZW50ID09PSBudWxsKSB7XHJcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImNvdWxkIG5vdCBnZXQgcm9vdCBvZiB0cmVlXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgICAgLy9XZSBoYXZlIHRvIHVzZSBhIHNldFRpbWVvdXQgZHVlIHRvIGEgYnVnIGluIGNocm9tZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwNzMzODcwLzg3OTY2NTFcclxuICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGRyYWdnZWRFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJkcmFnZ2luZ1wiKTtcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLnRyZWVEYXRhPy5sZW5ndGggPT09IDEgJiZcclxuICAgICAgICAgICAgICAgdGhpcy5icmFuY2g/LmdldENvb3JkaW5hdGVzKCkubGVuZ3RoID09PSAxXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAvL1dlIGFyZSBkcmFnZ2luZyB0aGUgb25seSBlbGVtZW50IGluIHRoZSB0cmVlLCBzbyB3ZSBoYXZlIHRvIHVzZSB0aGUgcGxhY2Vob2xkZXIgc3lzdGVtXHJcbiAgICAgICAgICAgICAgIHRoaXMudHJlZVNlcnZpY2UucGxhY2Vob2xkZXIkLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgfSk7XHJcbiAgICAgICAgIC8vV2UgdXNlIHRoaXMgd2VpcmQgc3Vic2NyaXB0aW9uL3RpbWVvdXQgY29tYm8gaW4gb3JkZXIgdG8gYXZvaWQgYSBzdHJhbmdlIGJ1ZyB3aGVyZSB0aGUgZHJhZ2xlYXZlIGV2ZW50XHJcbiAgICAgICAgIC8vZG9lcyBub3QgZmlyZSBpZiB0aGUgdXNlciBkcmFncyBvdXQgb2YgdGhlIHRyZWUgdG9vIHF1aWNrbHkuIFRoaXMgaXNzdWUgd291bGQgbWFrZSB0aGUgZHJvcCB6b25lXHJcbiAgICAgICAgIC8vcmVtYWluIGluIHRoZSBVSSwgcG90ZW50aWFsbHkgY2F1c2luZyBkcm9wIHpvbmVzIHRvIGFwcGVhciBpbiBtdWx0aXBsZSB0cmVlcyBhdCBhIHRpbWUuIFRoaXMgc3Vic2NyaXB0aW9uXHJcbiAgICAgICAgIC8vd2FpdHMgZm9yIHRoZSBkcmFnb3ZlciBldmVudCBvbiB0aGUgdHJlZSB0byBmaXJlIGJlZm9yZSByZW5kZXJpbmcgYW55IGRyb3Agem9uZXMuIElmIHRoZSBkcmFnb3ZlclxyXG4gICAgICAgICAvL2V2ZW50IGRvZXMgbm90IGZpcmUgd2l0aGluIGEgaGFsZiBzZWNvbmQsIHdlIGtub3cgdGhlIG1vdXNlIGxlZnQgdGhlIHRyZWUgdG9vIHF1aWNrbHksIGFuZCB3ZSB3b24ndFxyXG4gICAgICAgICAvL3JlbmRlciB0aGUgZHJvcCB6b25lIGF0IGFsbC5cclxuICAgICAgICAgY29uc3QgZHJhZ1N1YnNjcmlwdGlvbiA9IGZyb21FdmVudCh0cmVlRWxlbWVudCwgXCJkcmFnb3ZlclwiKVxyXG4gICAgICAgICAgICAucGlwZShmaXJzdCgpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChkcmFnb3ZlckV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgIGRyYWdvdmVyRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgIGlmICh0aGlzLmJyYW5jaCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBzaG93IHN1cnJvdW5kaW5nIGRyb3Agem9uZXNcIik7XHJcbiAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5icmFuY2guZ2V0UGFyZW50KCk7XHJcbiAgICAgICAgICAgICAgIGxldCBwYXJlbnREYXRhOiBMaW1ibGVUcmVlTm9kZTtcclxuICAgICAgICAgICAgICAgbGV0IHBhcmVudE5lc3RpbmdBbGxvd2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgaWYgKHBhcmVudD8uZGF0YSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICBwYXJlbnREYXRhID0gcGFyZW50Py5kYXRhIGFzIExpbWJsZVRyZWVOb2RlO1xyXG4gICAgICAgICAgICAgICAgICBwYXJlbnROZXN0aW5nQWxsb3dlZCA9IGlzTmVzdGluZ0FsbG93ZWQoXHJcbiAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJlZVNlcnZpY2UudHJlZU9wdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgIHBhcmVudERhdGFcclxuICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICBpZiAodGhpcy5kcm9wWm9uZUFib3ZlICE9PSB1bmRlZmluZWQgJiYgcGFyZW50TmVzdGluZ0FsbG93ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2Uuc2hvd0Ryb3Bab25lRmFtaWx5KHRoaXMuZHJvcFpvbmVBYm92ZSwge1xyXG4gICAgICAgICAgICAgICAgICAgICBqb2luRmFtaWxpZXM6IHRydWVcclxuICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWRyYWdTdWJzY3JpcHRpb24uY2xvc2VkKSB7XHJcbiAgICAgICAgICAgICAgIGRyYWdTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICB9LCA1MDApO1xyXG4gICAgICB9KTtcclxuICAgfVxyXG5cclxuICAgcHVibGljIGRyYWdlbmRIYW5kbGVyKGV2ZW50PzogRHJhZ0V2ZW50KTogdm9pZCB7XHJcbiAgICAgIGV2ZW50Py5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlRGl2ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY291bGQgbm90IGdldCBkcmFnZ2FibGUgZGl2XCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZHJhZ2dhYmxlRGl2Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcImRyYWdnaW5nXCIpO1xyXG4gICAgICBpZiAodGhpcy5kcmFnU3RhdGVTZXJ2aWNlLmdldFN0YXRlKCkgPT09IFwiY2FwdHVyZWRcIikge1xyXG4gICAgICAgICBpZiAodGhpcy50cmVlU2VydmljZS5jYXB0dXJlZCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgLy9Ecm9wcGVkIGluIGEgZGlmZmVyZW50IHRyZWUuIFJlbW92ZSB0aGUgb25lIGluIHRoaXMgdHJlZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5icmFuY2ggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjb3VsZCBub3QgZ2V0IGJyYW5jaCBpbiBkcmFnZW5kSGFuZGxlclwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLmNsZWFudXBTaWduYWwkLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMudHJlZVNlcnZpY2UuY2FwdHVyZWQgPSBmYWxzZTtcclxuICAgICAgICAgfVxyXG4gICAgICAgICB0aGlzLmRyYWdTdGF0ZVNlcnZpY2UucmVsZWFzZSgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAvL1dhc24ndCBkcm9wcGVkIGludG8gYSB2YWxpZCB0cmVlLCBzbyByZXNldCBmb3IgbmV4dCBkcmFnIGFuZFxyXG4gICAgICAgICAvL2Rvbid0IGRvIGFueXRoaW5nIGVsc2UuXHJcbiAgICAgICAgIHRoaXMuZHJhZ1N0YXRlU2VydmljZS5yZWxlYXNlKCk7XHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmNsZWFyVmlzaWJsZVpvbmVzKCk7XHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLnJlc3RvcmVGYW1pbGllcygpO1xyXG4gICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgIHRoaXMudHJlZVNlcnZpY2UudHJlZURhdGE/Lmxlbmd0aCA9PT0gMSAmJlxyXG4gICAgICAgICAgICB0aGlzLmJyYW5jaD8uZ2V0Q29vcmRpbmF0ZXMoKS5sZW5ndGggPT09IDFcclxuICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIC8vV2Ugd2VyZSBkcmFnZ2luZyB0aGUgb25seSBlbGVtZW50IGluIHRoZSB0cmVlLCBzbyB3ZSBoYXZlIHRvXHJcbiAgICAgICAgICAgIC8vcmVtb3ZlIHRoZSBwbGFjZWhvbGRlciB0aGF0IHdlIGFkZGVkIGluIHRoZSBkcmFnc3RhcnRcclxuICAgICAgICAgICAgdGhpcy50cmVlU2VydmljZS5wbGFjZWhvbGRlciQubmV4dChmYWxzZSk7XHJcbiAgICAgICAgIH1cclxuICAgICAgfVxyXG4gICB9XHJcblxyXG4gICBwdWJsaWMgZHJhZ292ZXJIYW5kbGVyKGV2ZW50OiBEcmFnRXZlbnQpIHtcclxuICAgICAgaWYgKHRoaXMuZ2xvYmFsRXZlbnRzU2VydmljZS5zY3JvbGxpbmcgPT09IHRydWUpIHtcclxuICAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmJyYW5jaCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGdldCBjdXJyZW50IGJyYW5jaCBkdXJpbmcgZHJhZ292ZXIgZXZlbnRcIik7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZHJhZ1N0YXRlU2VydmljZS5nZXREYXRhKCk7XHJcbiAgICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgLy9UaGV5IG1pZ2h0IGJlIGRyYWdnaW5nIHNvbWV0aGluZyB0aGF0IGlzbid0IGEgbm9kZS4gSnVzdCBpZ25vcmUgaXQuXHJcbiAgICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBzb3VyY2VCcmFuY2ggPSBkYXRhLmJyYW5jaDtcclxuICAgICAgLy9JZiB0cnlpbmcgdG8gZHJvcCBvbiBzZWxmLCByZXR1cm4uXHJcbiAgICAgIGlmIChcclxuICAgICAgICAgc291cmNlQnJhbmNoID09PSB0aGlzLmJyYW5jaCB8fFxyXG4gICAgICAgICB0aGlzLmJyYW5jaC5nZXRBbmNlc3RvcnMoKS5pbmNsdWRlcyhzb3VyY2VCcmFuY2gpXHJcbiAgICAgICkge1xyXG4gICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgdGFyZ2V0ID0gKGV2ZW50LmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoXHJcbiAgICAgICAgIFwiLm5vZGUtaG9zdC1jb250YWluZXJcIlxyXG4gICAgICApO1xyXG4gICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmFpbGVkIHRvIGZpbmQgbm9kZSBob3N0IGNvbnRhaW5lciB3aGlsZSBkcmFnZ2luZ1wiKTtcclxuICAgICAgfVxyXG4gICAgICBsZXQgdG9wTGluZTogbnVtYmVyO1xyXG4gICAgICBsZXQgYm90dG9tTGluZTogbnVtYmVyO1xyXG4gICAgICBpZiAodGhpcy5pbm5lckJyYW5jaD8ucmVuZGVyRHJvcFpvbmVJbnNpZGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgIHRvcExpbmUgPSB0YXJnZXQub2Zmc2V0SGVpZ2h0IC8gMiAtIDY7XHJcbiAgICAgICAgIGJvdHRvbUxpbmUgPSB0b3BMaW5lO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgICB0b3BMaW5lID0gdGFyZ2V0Lm9mZnNldEhlaWdodCAvIDMgLSAzOyAvL2FuIGltYWdpbmFyeSBsaW5lIDEvMyBvZiB0aGUgd2F5IGRvd24gZnJvbSB0aGUgdG9wIG9mIHRoZSBlbGVtZW50O1xyXG4gICAgICAgICBib3R0b21MaW5lID0gdG9wTGluZSAqIDI7IC8vYW4gaW1hZ2luYXJ5IGxpbmUgMS8zIG9mIHRoZSB3YXkgdXAgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSBlbGVtZW50O1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuYnJhbmNoLmdldFBhcmVudCgpO1xyXG4gICAgICBsZXQgcGFyZW50RGF0YTogTGltYmxlVHJlZU5vZGU7XHJcbiAgICAgIGxldCBwYXJlbnROZXN0aW5nQWxsb3dlZCA9IHRydWU7XHJcbiAgICAgIGlmIChwYXJlbnQ/LmRhdGEgIT09IG51bGwpIHtcclxuICAgICAgICAgcGFyZW50RGF0YSA9IHBhcmVudD8uZGF0YSBhcyBMaW1ibGVUcmVlTm9kZTtcclxuICAgICAgICAgcGFyZW50TmVzdGluZ0FsbG93ZWQgPSBpc05lc3RpbmdBbGxvd2VkKFxyXG4gICAgICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLnRyZWVPcHRpb25zLFxyXG4gICAgICAgICAgICBwYXJlbnREYXRhXHJcbiAgICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgICAgLyoqIFRoZSB5LWNvb3JkaW5hdGVzIG9mIHRoZSBtb3VzZSBpbiByZWxhdGlvbiB0byB0aGUgbm9kZSBpdCBpcyBob3ZlcmluZyBvdmVyICovXHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSBldmVudC5jbGllbnRZIC0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcclxuICAgICAgY29uc3QgYWN0aXZlRHJvcFpvbmUgPSB0aGlzLmRyb3Bab25lU2VydmljZS5nZXRBY3RpdmVEcm9wWm9uZSgpO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIG9mZnNldFkgPCB0b3BMaW5lICYmXHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVBYm92ZSAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgIHBhcmVudE5lc3RpbmdBbGxvd2VkICYmXHJcbiAgICAgICAgIChhY3RpdmVEcm9wWm9uZSA9PT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAhRHJvcFpvbmUuZHJvcFpvbmVMb2NhdGlvbnNBcmVFcXVhbChcclxuICAgICAgICAgICAgICAgYWN0aXZlRHJvcFpvbmUsXHJcbiAgICAgICAgICAgICAgIHRoaXMuZHJvcFpvbmVBYm92ZVxyXG4gICAgICAgICAgICApKVxyXG4gICAgICApIHtcclxuICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmJyYW5jaC5nZXRJbmRleCgpO1xyXG4gICAgICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCB8fCBpbmRleCA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYW4ndCBnZXQgYnJhbmNoIGluZGV4XCIpO1xyXG4gICAgICAgICB9XHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLnNob3dEcm9wWm9uZUZhbWlseSh0aGlzLmRyb3Bab25lQWJvdmUsIHtcclxuICAgICAgICAgICAgYWN0aXZhdGVMb3dlc3RJbnN0ZWFkT2ZGb3VuZGVyOiB0cnVlXHJcbiAgICAgICAgIH0pO1xyXG4gICAgICAgICBpZiAoc3VkZGVuVHJlZUV4aXQoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmNsZWFyVmlzaWJsZVpvbmVzKCk7XHJcbiAgICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgb2Zmc2V0WSA8IGJvdHRvbUxpbmUgJiZcclxuICAgICAgICAgb2Zmc2V0WSA+IHRvcExpbmUgJiZcclxuICAgICAgICAgdGhpcy5pbm5lckJyYW5jaD8ucmVuZGVyRHJvcFpvbmVJbnNpZGUgPT09IHRydWUgJiZcclxuICAgICAgICAgdGhpcy5pbm5lckJyYW5jaD8uZHJvcFpvbmVJbnNpZGUgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICAoYWN0aXZlRHJvcFpvbmUgPT09IG51bGwgfHxcclxuICAgICAgICAgICAgIURyb3Bab25lLmRyb3Bab25lTG9jYXRpb25zQXJlRXF1YWwoXHJcbiAgICAgICAgICAgICAgIGFjdGl2ZURyb3Bab25lLFxyXG4gICAgICAgICAgICAgICB0aGlzLmlubmVyQnJhbmNoLmRyb3Bab25lSW5zaWRlXHJcbiAgICAgICAgICAgICkpXHJcbiAgICAgICkge1xyXG4gICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5zaG93RHJvcFpvbmVGYW1pbHkoXHJcbiAgICAgICAgICAgIHRoaXMuaW5uZXJCcmFuY2guZHJvcFpvbmVJbnNpZGVcclxuICAgICAgICAgKTtcclxuICAgICAgICAgaWYgKHN1ZGRlblRyZWVFeGl0KGV2ZW50KSkge1xyXG4gICAgICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5jbGVhclZpc2libGVab25lcygpO1xyXG4gICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgIG9mZnNldFkgPj0gYm90dG9tTGluZSAmJlxyXG4gICAgICAgICB0aGlzLmRyb3Bab25lQmVsb3cgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICBwYXJlbnROZXN0aW5nQWxsb3dlZCAmJlxyXG4gICAgICAgICAoYWN0aXZlRHJvcFpvbmUgPT09IG51bGwgfHxcclxuICAgICAgICAgICAgIURyb3Bab25lLmRyb3Bab25lTG9jYXRpb25zQXJlRXF1YWwoXHJcbiAgICAgICAgICAgICAgIGFjdGl2ZURyb3Bab25lLFxyXG4gICAgICAgICAgICAgICB0aGlzLmRyb3Bab25lQmVsb3dcclxuICAgICAgICAgICAgKSkgJiZcclxuICAgICAgICAgdGhpcy5icmFuY2guZ2V0Q2hpbGRyZW4oKS5sZW5ndGggPT09IDBcclxuICAgICAgKSB7XHJcbiAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5icmFuY2guZ2V0SW5kZXgoKTtcclxuICAgICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQgfHwgaW5kZXggPT09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2FuJ3QgZ2V0IGJyYW5jaCBpbmRleFwiKTtcclxuICAgICAgICAgfVxyXG4gICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5zaG93RHJvcFpvbmVGYW1pbHkodGhpcy5kcm9wWm9uZUJlbG93KTtcclxuICAgICAgICAgaWYgKHN1ZGRlblRyZWVFeGl0KGV2ZW50KSkge1xyXG4gICAgICAgICAgICB0aGlzLmRyb3Bab25lU2VydmljZS5jbGVhclZpc2libGVab25lcygpO1xyXG4gICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSByZW5kZXJOb2RlKCkge1xyXG4gICAgICBpZiAodGhpcy5ub2RlSG9zdCA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuYnJhbmNoID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmFpbGVkIHRvIHJlbmRlciB0cmVlIG5vZGVcIik7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IGNvbXBvbmVudCA9IHRoaXMuYnJhbmNoLmRhdGEuY29tcG9uZW50O1xyXG4gICAgICBpZiAoY29tcG9uZW50ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgY29tcG9uZW50ID0gdGhpcy50cmVlU2VydmljZS50cmVlT3B0aW9ucz8uZGVmYXVsdENvbXBvbmVudDtcclxuICAgICAgfVxyXG4gICAgICBpZiAoY29tcG9uZW50ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibGltYmxlVHJlZSByZXF1aXJlcyBhIGNvbXBvbmVudCB0byByZW5kZXJcIik7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgY29tcG9uZW50UmVmID0gdGhpcy5jb21wb25lbnRDcmVhdG9yU2VydmljZS5hcHBlbmRDb21wb25lbnQ8YW55PihcclxuICAgICAgICAgY29tcG9uZW50LmNsYXNzLFxyXG4gICAgICAgICB0aGlzLm5vZGVIb3N0XHJcbiAgICAgICk7XHJcbiAgICAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5ub2RlRGF0YSA9IHRoaXMuYnJhbmNoLmRhdGE7XHJcbiAgICAgIGZvciAoY29uc3QgYmluZGluZyBpbiBjb21wb25lbnQuYmluZGluZ3MpIHtcclxuICAgICAgICAgY29tcG9uZW50UmVmLmluc3RhbmNlW2JpbmRpbmddID0gY29tcG9uZW50LmJpbmRpbmdzW2JpbmRpbmddO1xyXG4gICAgICB9XHJcbiAgIH1cclxuXHJcbiAgIHByaXZhdGUgcmVnaXN0ZXJEcm9wWm9uZXMoKTogdm9pZCB7XHJcbiAgICAgIHRoaXMuYWRkRHJvcFpvbmVBYm92ZSgpO1xyXG4gICAgICB0aGlzLmFkZERyb3Bab25lQmVsb3coKTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSBhZGREcm9wWm9uZUFib3ZlKCk6IHZvaWQge1xyXG4gICAgICBpZiAodGhpcy5icmFuY2ggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmYWlsZWQgdG8gcmVnaXN0ZXIgZHJvcCB6b25lIGFib3ZlXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuYnJhbmNoLmdldFBhcmVudCgpO1xyXG4gICAgICBjb25zdCBjdXJyZW50Q29vcmRpbmF0ZXMgPSB0aGlzLmJyYW5jaC5nZXRDb29yZGluYXRlcygpO1xyXG4gICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRDb29yZGluYXRlc1tjdXJyZW50Q29vcmRpbmF0ZXMubGVuZ3RoIC0gMV07XHJcbiAgICAgIHRoaXMuZHJvcFpvbmVBYm92ZSA9IG5ldyBEcm9wWm9uZShcclxuICAgICAgICAgWy4uLihwYXJlbnQ/LmdldENvb3JkaW5hdGVzKCkgPz8gW10pXSxcclxuICAgICAgICAgaW5kZXhcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5kcm9wWm9uZVNlcnZpY2UuYWRkRHJvcFpvbmUodGhpcy5kcm9wWm9uZUFib3ZlKTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSBhZGREcm9wWm9uZUJlbG93KCk6IHZvaWQge1xyXG4gICAgICBpZiAodGhpcy5icmFuY2ggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmYWlsZWQgdG8gcmVnaXN0ZXIgZHJvcCB6b25lIGJlbG93XCIpO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuYnJhbmNoLmdldFBhcmVudCgpO1xyXG4gICAgICBjb25zdCBjdXJyZW50Q29vcmRpbmF0ZXMgPSB0aGlzLmJyYW5jaC5nZXRDb29yZGluYXRlcygpO1xyXG4gICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRDb29yZGluYXRlc1tjdXJyZW50Q29vcmRpbmF0ZXMubGVuZ3RoIC0gMV07XHJcbiAgICAgIHRoaXMuZHJvcFpvbmVCZWxvdyA9IG5ldyBEcm9wWm9uZShcclxuICAgICAgICAgWy4uLihwYXJlbnQ/LmdldENvb3JkaW5hdGVzKCkgPz8gW10pXSxcclxuICAgICAgICAgaW5kZXggKyAxXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuZHJvcFpvbmVTZXJ2aWNlLmFkZERyb3Bab25lKHRoaXMuZHJvcFpvbmVCZWxvdyk7XHJcbiAgIH1cclxuXHJcbiAgIHByaXZhdGUgdXBkYXRlRHJvcFpvbmVzKCk6IHZvaWQge1xyXG4gICAgICB0aGlzLmN1cnJlbnRCcmFuY2hDb29yZGluYXRlcyA9IHRoaXMuYnJhbmNoPy5nZXRDb29yZGluYXRlcygpO1xyXG4gICAgICB0aGlzLnVwZGF0ZURyb3Bab25lQWJvdmUoKTtcclxuICAgICAgdGhpcy51cGRhdGVEcm9wWm9uZUJlbG93KCk7XHJcbiAgICAgIHRoaXMudXBkYXRlRHJvcFpvbmVJbnNpZGUoKTtcclxuICAgICAgdGhpcy5zZXREcm9wWm9uZUhvc3RzKCk7XHJcbiAgIH1cclxuXHJcbiAgIHByaXZhdGUgdXBkYXRlRHJvcFpvbmVBYm92ZSgpOiB2b2lkIHtcclxuICAgICAgaWYgKHRoaXMuYnJhbmNoID09PSB1bmRlZmluZWQgfHwgdGhpcy5kcm9wWm9uZUFib3ZlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmFpbGVkIHRvIHVwZGF0ZSBkcm9wIHpvbmUgYWJvdmVcIik7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5icmFuY2guZ2V0UGFyZW50KCk7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRDb29yZGluYXRlcyA9IHRoaXMuYnJhbmNoLmdldENvb3JkaW5hdGVzKCk7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gY3VycmVudENvb3JkaW5hdGVzW2N1cnJlbnRDb29yZGluYXRlcy5sZW5ndGggLSAxXTtcclxuICAgICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmRyb3Bab25lQWJvdmUuZ2V0TG9jYXRpb24oKTtcclxuICAgICAgbG9jYXRpb24uc2V0UGFyZW50Q29vcmRpbmF0ZXMoWy4uLihwYXJlbnQ/LmdldENvb3JkaW5hdGVzKCkgPz8gW10pXSk7XHJcbiAgICAgIGxvY2F0aW9uLnNldEluc2VydEluZGV4KGluZGV4KTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSB1cGRhdGVEcm9wWm9uZUJlbG93KCk6IHZvaWQge1xyXG4gICAgICBpZiAodGhpcy5icmFuY2ggPT09IHVuZGVmaW5lZCB8fCB0aGlzLmRyb3Bab25lQmVsb3cgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJmYWlsZWQgdG8gdXBkYXRlIGRyb3Agem9uZSBiZWxvd1wiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLmJyYW5jaC5nZXRQYXJlbnQoKTtcclxuICAgICAgY29uc3QgY3VycmVudENvb3JkaW5hdGVzID0gdGhpcy5icmFuY2guZ2V0Q29vcmRpbmF0ZXMoKTtcclxuICAgICAgY29uc3QgaW5kZXggPSBjdXJyZW50Q29vcmRpbmF0ZXNbY3VycmVudENvb3JkaW5hdGVzLmxlbmd0aCAtIDFdO1xyXG4gICAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMuZHJvcFpvbmVCZWxvdy5nZXRMb2NhdGlvbigpO1xyXG4gICAgICBsb2NhdGlvbi5zZXRQYXJlbnRDb29yZGluYXRlcyhbLi4uKHBhcmVudD8uZ2V0Q29vcmRpbmF0ZXMoKSA/PyBbXSldKTtcclxuICAgICAgbG9jYXRpb24uc2V0SW5zZXJ0SW5kZXgoaW5kZXggKyAxKTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSB1cGRhdGVEcm9wWm9uZUluc2lkZSgpOiB2b2lkIHtcclxuICAgICAgaWYgKHRoaXMuaW5uZXJCcmFuY2g/LmRyb3Bab25lSW5zaWRlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmJyYW5jaCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImZhaWxlZCB0byB1cGRhdGUgZHJvcCB6b25lIGluc2lkZVwiKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMuaW5uZXJCcmFuY2guZHJvcFpvbmVJbnNpZGUuZ2V0TG9jYXRpb24oKTtcclxuICAgICAgbG9jYXRpb24uc2V0UGFyZW50Q29vcmRpbmF0ZXMoWy4uLnRoaXMuYnJhbmNoLmdldENvb3JkaW5hdGVzKCldKTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSBzZXREcm9wWm9uZUhvc3RzKCkge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVBYm92ZSA9PT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgIHRoaXMuZHJvcFpvbmVCZWxvdyA9PT0gdW5kZWZpbmVkXHJcbiAgICAgICkge1xyXG4gICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5kcm9wWm9uZUFib3ZlLnNldEhvc3QodGhpcy5wYXJlbnRIb3N0KTtcclxuICAgICAgdGhpcy5kcm9wWm9uZUJlbG93LnNldEhvc3QodGhpcy5wYXJlbnRIb3N0KTtcclxuICAgfVxyXG5cclxuICAgcHJpdmF0ZSBjaGVja0ZvckhhbmRsZSgpOiB2b2lkIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgICB0aGlzLm5vZGVIb3N0Q29udGFpbmVyID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgdGhpcy5kcmFnZ2FibGVEaXYgPT09IHVuZGVmaW5lZFxyXG4gICAgICApIHtcclxuICAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IG5vZGVIb3N0Q29udGFpbmVyRWxlbWVudCA9IHRoaXMubm9kZUhvc3RDb250YWluZXIubmF0aXZlRWxlbWVudDtcclxuICAgICAgY29uc3QgaGFuZGxlID0gbm9kZUhvc3RDb250YWluZXJFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgIFwiLmxpbWJsZS10cmVlLWhhbmRsZVwiXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IGRyYWdnYWJsZURpdkVsZW1lbnQgPSB0aGlzLmRyYWdnYWJsZURpdi5uYXRpdmVFbGVtZW50O1xyXG4gICAgICBpZiAoIWlzRHJhZ2dpbmdBbGxvd2VkKHRoaXMudHJlZVNlcnZpY2UudHJlZU9wdGlvbnMsIHRoaXMuYnJhbmNoPy5kYXRhKSkge1xyXG4gICAgICAgICBkcmFnZ2FibGVEaXZFbGVtZW50LnNldEF0dHJpYnV0ZShcImRyYWdnYWJsZVwiLCBcImZhbHNlXCIpO1xyXG4gICAgICB9IGVsc2UgaWYgKGhhbmRsZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICBkcmFnZ2FibGVEaXZFbGVtZW50LnNldEF0dHJpYnV0ZShcImRyYWdnYWJsZVwiLCBcInRydWVcIik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsICgpID0+IHtcclxuICAgICAgICAgICAgZHJhZ2dhYmxlRGl2RWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIiwgXCJ0cnVlXCIpO1xyXG4gICAgICAgICAgICAvL0ZvciBzb21lIHJlYXNvbiBtb3VzZXVwIGRvZXNuJ3QgZmlyZSBhZnRlciBhIGRyYWcsIHNvIHdlIHVzZSB0aGlzIG9ic2VydmFibGUgc2VxdWVuY2UgaW5zdGVhZC5cclxuICAgICAgICAgICAgY29uc3QgZHJhZ2dpbmcgPSB0aGlzLmRyYWdTdGF0ZVNlcnZpY2Uuc3RhdGUkLnBpcGUoXHJcbiAgICAgICAgICAgICAgIGZpbHRlcigoc3RhdGUpID0+IHN0YXRlID09PSBcImRyYWdnaW5nXCIpLFxyXG4gICAgICAgICAgICAgICBmaXJzdCgpXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlU2VydmljZS5zdGF0ZSRcclxuICAgICAgICAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgIHNraXBVbnRpbChkcmFnZ2luZyksXHJcbiAgICAgICAgICAgICAgICAgIGZpbHRlcigoc3RhdGUpID0+IHN0YXRlID09PSBcImlkbGVcIiksXHJcbiAgICAgICAgICAgICAgICAgIGZpcnN0KClcclxuICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlRGl2RWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIiwgXCJmYWxzZVwiKTtcclxuICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgIH1cclxufVxyXG4iLCI8ZHJvcC16b25lXHJcbiAgICpuZ0lmPVwicmVuZGVyRHJvcFpvbmVBYm92ZSA9PT0gdHJ1ZVwiXHJcbiAgIFtkcm9wWm9uZV09XCJkcm9wWm9uZUFib3ZlXCJcclxuPjwvZHJvcC16b25lPlxyXG48ZGl2XHJcbiAgIChkcmFnc3RhcnQpPVwiZHJhZ3N0YXJ0SGFuZGxlcigkZXZlbnQpXCJcclxuICAgKGRyYWdlbmQpPVwiZHJhZ2VuZEhhbmRsZXIoJGV2ZW50KVwiXHJcbiAgIGNsYXNzPVwibGltYmxlLXBhcmVudC1jb250YWluZXJcIlxyXG4gICAjZHJhZ2dhYmxlRGl2XHJcbj5cclxuICAgPGRpdlxyXG4gICAgICBjbGFzcz1cIm5vZGUtaG9zdC1jb250YWluZXJcIlxyXG4gICAgICAoZHJhZ292ZXJOb0NoYW5nZURldGVjdCk9XCJkcmFnb3ZlckhhbmRsZXIoJGV2ZW50KVwiXHJcbiAgICAgIFtkcmFnb3ZlckV2ZW50VGhyb3R0bGVdPVwiMTBcIlxyXG4gICAgICAjbm9kZUhvc3RDb250YWluZXJcclxuICAgPlxyXG4gICAgICA8bmctdGVtcGxhdGUgI25vZGVIb3N0PjwvbmctdGVtcGxhdGU+XHJcbiAgIDwvZGl2PlxyXG4gICA8bGltYmxlLXRyZWUtYnJhbmNoXHJcbiAgICAgICpuZ0lmPVwiYnJhbmNoICE9PSB1bmRlZmluZWQgJiYgcmVuZGVySW5uZXJCcmFuY2ggPT09IHRydWVcIlxyXG4gICAgICBbYnJhbmNoXT1cImJyYW5jaFwiXHJcbiAgICAgICNpbm5lckJyYW5jaFxyXG4gICA+PC9saW1ibGUtdHJlZS1icmFuY2g+XHJcbjwvZGl2PlxyXG48ZHJvcC16b25lXHJcbiAgICpuZ0lmPVwicmVuZGVyRHJvcFpvbmVCZWxvdyA9PT0gdHJ1ZVwiXHJcbiAgIFtkcm9wWm9uZV09XCJkcm9wWm9uZUJlbG93XCJcclxuPjwvZHJvcC16b25lPlxyXG4iXX0=
|