@libs-ui/services-diagram-draw 0.2.356-37
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 +279 -0
- package/canvas.service.d.ts +42 -0
- package/diagram-draw.service.d.ts +91 -0
- package/direction.service.d.ts +43 -0
- package/esm2022/canvas.service.mjs +628 -0
- package/esm2022/diagram-draw.service.mjs +711 -0
- package/esm2022/direction.service.mjs +255 -0
- package/esm2022/index.mjs +6 -0
- package/esm2022/interfaces/canvas.interface.mjs +2 -0
- package/esm2022/interfaces/coordinates.interface.mjs +2 -0
- package/esm2022/interfaces/diagram.interface.mjs +2 -0
- package/esm2022/libs-ui-services-diagram-draw.mjs +5 -0
- package/esm2022/utils/calculator-branch.util.mjs +187 -0
- package/esm2022/utils/calculator-element.util.mjs +335 -0
- package/esm2022/utils/canvas.util.mjs +176 -0
- package/esm2022/utils/diagram.util.mjs +54 -0
- package/esm2022/utils/direction.util.mjs +103 -0
- package/esm2022/utils/horizontal/calculator-branch.util.mjs +243 -0
- package/esm2022/utils/horizontal/calculator-coordinates.util.mjs +315 -0
- package/fesm2022/libs-ui-services-diagram-draw.mjs +2982 -0
- package/fesm2022/libs-ui-services-diagram-draw.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/interfaces/canvas.interface.d.ts +21 -0
- package/interfaces/coordinates.interface.d.ts +40 -0
- package/interfaces/diagram.interface.d.ts +109 -0
- package/package.json +27 -0
- package/utils/calculator-branch.util.d.ts +16 -0
- package/utils/calculator-element.util.d.ts +24 -0
- package/utils/canvas.util.d.ts +21 -0
- package/utils/diagram.util.d.ts +6 -0
- package/utils/direction.util.d.ts +6 -0
- package/utils/horizontal/calculator-branch.util.d.ts +67 -0
- package/utils/horizontal/calculator-coordinates.util.d.ts +42 -0
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
import { Injectable, signal } from '@angular/core';
|
|
2
|
+
import { setStylesElement } from '@libs-ui/utils';
|
|
3
|
+
import { MoLibDiagramCalculatorCoordinatesUtil } from './utils/calculator-element.util';
|
|
4
|
+
import { applyElementStyle, setAttributeSvgAndAppend } from './utils/diagram.util';
|
|
5
|
+
import { MoLibDiagramHorizontalCalculatorCoordinatesUtil } from './utils/horizontal/calculator-coordinates.util';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
const canvasConfig = signal({
|
|
8
|
+
ELEMENT_WIDTH_DEFAULT_BRANCH_WHEN_NOT_ELEMENT: 60,
|
|
9
|
+
ELEMENT_MARGIN_DEFAULT: 60,
|
|
10
|
+
ELEMENT_MARGIN_DEFAULT_BRANCH: 16,
|
|
11
|
+
ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT: 60,
|
|
12
|
+
DEFAULT_BRANCH_WHEN_NO_ELEMENT: 100,
|
|
13
|
+
ELEMENT_HEIGHT_CURVE: 10,
|
|
14
|
+
ELEMENT_SVG_STROKE_COLOR: '9ca2ad',
|
|
15
|
+
ELEMENT_SVG_STROKE_WIDTH: '1',
|
|
16
|
+
ELEMENT_MARGIN_DEFAULT_BRANCH_TO_ELEMENT_FIRST: 78,
|
|
17
|
+
DISTANCE_TO_WAIT: 30,
|
|
18
|
+
WAIT_TO_ELEMENT: 50,
|
|
19
|
+
ELEMENT_WAIT_DEFAULT: 28,
|
|
20
|
+
DISTANCE_WAIT_TO_NEXT_LINE: 4,
|
|
21
|
+
TYPE_ELEMENT_EXIT: 'EXIT',
|
|
22
|
+
TYPE_ELEMENT_WORKFLOW: 'WORKFLOW',
|
|
23
|
+
WIDTH_ELEMENT_DEFAULT: 165,
|
|
24
|
+
HEIGHT_ELEMENT_DEFAULT: 48,
|
|
25
|
+
ADD_ICON_DIAMETER: 24,
|
|
26
|
+
});
|
|
27
|
+
export const canvasConfigReadonly = canvasConfig.asReadonly();
|
|
28
|
+
export const storeDataDefault = {
|
|
29
|
+
positionMaxLeft: 0,
|
|
30
|
+
positionMaxTop: 0,
|
|
31
|
+
widthHeightSvgCanvas: { heightSvg: window.innerHeight, widthSvg: window.innerWidth },
|
|
32
|
+
};
|
|
33
|
+
export class LibsUiDiagramDrawService {
|
|
34
|
+
configCanvas = signal(undefined);
|
|
35
|
+
orientation = signal('vertical');
|
|
36
|
+
elementSvg = signal(undefined);
|
|
37
|
+
attributeSvgD = signal('');
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
componentRefs = signal([]);
|
|
40
|
+
// Virtualization Tracking
|
|
41
|
+
virtualViewport;
|
|
42
|
+
virtualFlatElements = [];
|
|
43
|
+
virtualFlatBranches = [];
|
|
44
|
+
virtualNodesMap = new Map();
|
|
45
|
+
updateViewport(vp) {
|
|
46
|
+
this.virtualViewport = vp;
|
|
47
|
+
if (this.configCanvas()?.useVirtualizationTemplate) {
|
|
48
|
+
this.applyVirtualizationDiff();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
set setConfig(config) {
|
|
52
|
+
this.configCanvas.set(config);
|
|
53
|
+
}
|
|
54
|
+
set setConfigCanvas(config) {
|
|
55
|
+
if (!config) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
canvasConfig.update((current) => ({ ...current, ...config }));
|
|
59
|
+
}
|
|
60
|
+
configXYElements(elements, updateSVG, positionX) {
|
|
61
|
+
const storeData = this.configCanvas()?.storeDataDefine ?? storeDataDefault;
|
|
62
|
+
const maxLeftOrigin = storeData.positionMaxLeft;
|
|
63
|
+
const maxTopOrigin = storeData.positionMaxTop ?? 0;
|
|
64
|
+
if (this.orientation() === 'horizontal') {
|
|
65
|
+
MoLibDiagramHorizontalCalculatorCoordinatesUtil.setXYElements(elements, storeData, positionX);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
MoLibDiagramCalculatorCoordinatesUtil.setXYElements(elements, storeData, positionX);
|
|
69
|
+
}
|
|
70
|
+
const maxLeftNew = storeData.positionMaxLeft;
|
|
71
|
+
const maxTopNew = storeData.positionMaxTop ?? 0;
|
|
72
|
+
if (!this.elementSvg()) {
|
|
73
|
+
this.elementSvg.set(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
|
|
74
|
+
}
|
|
75
|
+
if (!updateSVG && this.configCanvas()?.svgContainer && this.elementSvg()) {
|
|
76
|
+
setAttributeSvgAndAppend(this.configCanvas()?.svgContainer, this.elementSvg(), '');
|
|
77
|
+
}
|
|
78
|
+
if (this.orientation() === 'horizontal' && maxTopOrigin !== maxTopNew) {
|
|
79
|
+
this.updatePositionElements(maxTopNew, elements, storeData);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (this.orientation() === 'vertical' && maxLeftOrigin !== maxLeftNew) {
|
|
83
|
+
this.updatePositionElements(maxLeftNew, elements, storeData);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (this.elementSvg()) {
|
|
87
|
+
this.attributeSvgD.set('');
|
|
88
|
+
this.buildSvgElement(elements);
|
|
89
|
+
this.elementSvg()?.setAttribute('d', this.attributeSvgD());
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
updatePositionElements(positionOffset, elements, config) {
|
|
93
|
+
if (positionOffset && positionOffset < 0) {
|
|
94
|
+
positionOffset = positionOffset * -1 + 200; // 100 là khoảng cách cách biên
|
|
95
|
+
}
|
|
96
|
+
if (this.orientation() === 'horizontal') {
|
|
97
|
+
MoLibDiagramHorizontalCalculatorCoordinatesUtil.setXYElements(elements, { ...config, updateSVG: true }, positionOffset);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
MoLibDiagramCalculatorCoordinatesUtil.setXYElements(elements, { ...config, updateSVG: true }, positionOffset);
|
|
101
|
+
}
|
|
102
|
+
if (!this.elementSvg()) {
|
|
103
|
+
this.elementSvg.set(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
|
|
104
|
+
}
|
|
105
|
+
if (this.elementSvg()) {
|
|
106
|
+
this.attributeSvgD.set('');
|
|
107
|
+
this.buildSvgElement(elements);
|
|
108
|
+
this.elementSvg()?.setAttribute('d', this.attributeSvgD());
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
buildSvgElement(elements) {
|
|
112
|
+
elements.forEach((currentElement) => {
|
|
113
|
+
if (currentElement.attributeSvgD) {
|
|
114
|
+
this.attributeSvgD.update((prev) => `${prev ?? ''} ${currentElement.attributeSvgD}`);
|
|
115
|
+
}
|
|
116
|
+
if (currentElement.nodeOtherConfig?.attributeSvgD) {
|
|
117
|
+
this.attributeSvgD.update((prev) => `${prev ?? ''} ${currentElement.nodeOtherConfig?.attributeSvgD}`);
|
|
118
|
+
}
|
|
119
|
+
if (!currentElement.branches || !currentElement.branches.length) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
currentElement.branches.forEach((branch) => {
|
|
123
|
+
if (branch.attributeSvgD) {
|
|
124
|
+
this.attributeSvgD.update((prev) => `${prev ?? ''} ${branch.attributeSvgD}`);
|
|
125
|
+
}
|
|
126
|
+
if (branch.nodeOtherConfig?.attributeSvgD) {
|
|
127
|
+
this.attributeSvgD.update((prev) => `${prev ?? ''} ${branch.nodeOtherConfig?.attributeSvgD}`);
|
|
128
|
+
}
|
|
129
|
+
if (!branch.elements.length) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.buildSvgElement(branch.elements);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Render tất cả nodes từ elements array
|
|
138
|
+
*/
|
|
139
|
+
renderNodes(elements) {
|
|
140
|
+
if (this.configCanvas()?.useVirtualizationTemplate) {
|
|
141
|
+
this.extractVirtualElements(elements);
|
|
142
|
+
this.applyVirtualizationDiff();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.clearNodes();
|
|
146
|
+
this.renderElementsRecursively(elements, true, undefined);
|
|
147
|
+
this.renderBranchLabels(elements);
|
|
148
|
+
}
|
|
149
|
+
extractVirtualElements(elements) {
|
|
150
|
+
this.virtualFlatElements = [];
|
|
151
|
+
this.virtualFlatBranches = [];
|
|
152
|
+
const scan = (list, branch, isFirstLevel = true) => {
|
|
153
|
+
list.forEach((el, index) => {
|
|
154
|
+
const shouldShowArrow = !(isFirstLevel && index === 0);
|
|
155
|
+
this.virtualFlatElements.push({ element: el, branch, isOtherConfig: false, shouldShowArrow, parentId: el.id });
|
|
156
|
+
if (el.nodeOtherConfig)
|
|
157
|
+
this.virtualFlatElements.push({ element: el.nodeOtherConfig, branch, isOtherConfig: true, shouldShowArrow: false, parentId: el.id });
|
|
158
|
+
if (el.branches) {
|
|
159
|
+
el.branches.forEach((b, bIndex) => {
|
|
160
|
+
if (!b.label)
|
|
161
|
+
b.label = `Nhánh ${bIndex + 1}`;
|
|
162
|
+
this.virtualFlatBranches.push(b);
|
|
163
|
+
if (b.elements)
|
|
164
|
+
scan(b.elements, b, false);
|
|
165
|
+
if (b.nodeOtherConfig)
|
|
166
|
+
this.virtualFlatElements.push({ element: b.nodeOtherConfig, branch: b, isOtherConfig: true, shouldShowArrow: false, parentId: 'branch_' + bIndex + '_' + el.id });
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
scan(elements, undefined, true);
|
|
172
|
+
}
|
|
173
|
+
applyVirtualizationDiff() {
|
|
174
|
+
const vp = this.virtualViewport;
|
|
175
|
+
if (!vp)
|
|
176
|
+
return;
|
|
177
|
+
const config = this.configCanvas();
|
|
178
|
+
const container = config?.nodesContainer?.nativeElement;
|
|
179
|
+
if (!container || !config)
|
|
180
|
+
return;
|
|
181
|
+
const buffer = 300;
|
|
182
|
+
const visibleIds = new Set();
|
|
183
|
+
this.virtualFlatElements.forEach((item) => {
|
|
184
|
+
const el = item.element;
|
|
185
|
+
if (el.translateX === undefined || el.translateY === undefined)
|
|
186
|
+
return;
|
|
187
|
+
if (el.translateX + (el.specific_width || 165) < vp.x - buffer || el.translateX > vp.x + vp.width + buffer || el.translateY + (el.specific_height || 48) < vp.y - buffer || el.translateY > vp.y + vp.height + buffer)
|
|
188
|
+
return;
|
|
189
|
+
const id = String(item.parentId) + (item.isOtherConfig ? '_other' : '');
|
|
190
|
+
visibleIds.add(id);
|
|
191
|
+
if (!this.virtualNodesMap.has(id)) {
|
|
192
|
+
const componentType = item.isOtherConfig ? config.nodeOtherConfigComponentType : config.nodeComponentType;
|
|
193
|
+
if (componentType && config.viewContainerRef) {
|
|
194
|
+
const ref = config.viewContainerRef.createComponent(componentType);
|
|
195
|
+
ref.setInput('element', el);
|
|
196
|
+
if (item.branch)
|
|
197
|
+
ref.setInput('branch', item.branch);
|
|
198
|
+
ref.setInput('orientation', this.orientation());
|
|
199
|
+
const domEl = ref.location.nativeElement;
|
|
200
|
+
domEl.classList.add('diagram-node-dynamic');
|
|
201
|
+
applyElementStyle(domEl, el);
|
|
202
|
+
container.appendChild(domEl);
|
|
203
|
+
let arrow;
|
|
204
|
+
if (item.shouldShowArrow && !item.isOtherConfig) {
|
|
205
|
+
arrow = this.createArrowIndicator(el, container);
|
|
206
|
+
}
|
|
207
|
+
this.virtualNodesMap.set(id, { component: ref, arrow });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
const cache = this.virtualNodesMap.get(id);
|
|
212
|
+
if (cache) {
|
|
213
|
+
if (cache.component)
|
|
214
|
+
applyElementStyle(cache.component.location.nativeElement, el);
|
|
215
|
+
if (cache.arrow) {
|
|
216
|
+
const arrowSize = 16;
|
|
217
|
+
const nodeWidth = el.specific_width ?? 165;
|
|
218
|
+
const nodeHeight = el.specific_height ?? 48;
|
|
219
|
+
if (this.orientation() === 'horizontal') {
|
|
220
|
+
cache.arrow.innerHTML = `
|
|
221
|
+
<svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
222
|
+
<path d="M8 4L16 8L8 12Z" fill="#9ca3af"/>
|
|
223
|
+
</svg>
|
|
224
|
+
`;
|
|
225
|
+
cache.arrow.style.left = `${el.translateX - arrowSize}px`;
|
|
226
|
+
cache.arrow.style.top = `${el.translateY + nodeHeight / 2 - arrowSize / 2}px`;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
cache.arrow.innerHTML = `
|
|
230
|
+
<svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
231
|
+
<path d="M8 16L4 12H12L8 16Z" fill="#9ca3af"/>
|
|
232
|
+
</svg>
|
|
233
|
+
`;
|
|
234
|
+
cache.arrow.style.left = `${el.translateX + nodeWidth / 2 - arrowSize / 2}px`;
|
|
235
|
+
cache.arrow.style.top = `${el.translateY - arrowSize}px`;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
this.virtualFlatBranches.forEach((branch, index) => {
|
|
242
|
+
const x = branch.specific_start_branch_x;
|
|
243
|
+
const y = branch.specific_start_branch_y;
|
|
244
|
+
if (x === undefined || y === undefined)
|
|
245
|
+
return;
|
|
246
|
+
if (x < vp.x - buffer || x > vp.x + vp.width + buffer || y < vp.y - buffer || y > vp.y + vp.height + buffer)
|
|
247
|
+
return;
|
|
248
|
+
const id = 'branch_' + index + '_' + Math.round(x) + '_' + Math.round(y);
|
|
249
|
+
visibleIds.add(id);
|
|
250
|
+
if (!this.virtualNodesMap.has(id)) {
|
|
251
|
+
const labelDiv = this.createBranchLabel(branch);
|
|
252
|
+
if (labelDiv)
|
|
253
|
+
this.virtualNodesMap.set(id, { label: labelDiv });
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
const cache = this.virtualNodesMap.get(id);
|
|
257
|
+
if (cache?.label) {
|
|
258
|
+
const labelDiv = cache.label;
|
|
259
|
+
const labelRect = labelDiv.getBoundingClientRect();
|
|
260
|
+
const labelW = labelRect.width || labelDiv.offsetWidth;
|
|
261
|
+
const labelH = labelRect.height || labelDiv.offsetHeight;
|
|
262
|
+
if (this.orientation() === 'vertical') {
|
|
263
|
+
labelDiv.style.left = `${x - labelW / 2 - 4}px`;
|
|
264
|
+
labelDiv.style.top = `${y - labelH / 2 + 4}px`;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
labelDiv.style.left = `${x + 4}px`;
|
|
268
|
+
labelDiv.style.top = `${y - labelH / 2}px`; // center over wire
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
Array.from(this.virtualNodesMap.entries()).forEach(([id, cache]) => {
|
|
274
|
+
if (!visibleIds.has(id)) {
|
|
275
|
+
cache.component?.destroy();
|
|
276
|
+
cache.arrow?.remove();
|
|
277
|
+
cache.label?.remove();
|
|
278
|
+
this.virtualNodesMap.delete(id);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Render elements và branches một cách đệ quy
|
|
284
|
+
*/
|
|
285
|
+
renderElementsRecursively(elements, isFirstLevel = true, branch) {
|
|
286
|
+
elements.forEach((element, index) => {
|
|
287
|
+
if (element.translateX !== undefined && element.translateY !== undefined) {
|
|
288
|
+
// Main node: có arrow nếu không phải element đầu tiên của level đầu
|
|
289
|
+
const shouldShowArrow = !(isFirstLevel && index === 0);
|
|
290
|
+
this.createNode(element, branch, shouldShowArrow, false);
|
|
291
|
+
}
|
|
292
|
+
// Render nodeOtherConfig nếu có (nodes phụ) - KHÔNG có arrow
|
|
293
|
+
if (element.nodeOtherConfig && element.nodeOtherConfig.translateX !== undefined && element.nodeOtherConfig.translateY !== undefined) {
|
|
294
|
+
this.createNode(element.nodeOtherConfig, branch, false, true);
|
|
295
|
+
}
|
|
296
|
+
// Render branches nếu có
|
|
297
|
+
if (element.branches && element.branches.length > 0) {
|
|
298
|
+
element.branches.forEach((branch) => {
|
|
299
|
+
if (branch.elements && branch.elements.length > 0) {
|
|
300
|
+
this.renderElementsRecursively(branch.elements, false, branch);
|
|
301
|
+
}
|
|
302
|
+
if (branch.nodeOtherConfig && branch.nodeOtherConfig.translateX !== undefined && branch.nodeOtherConfig.translateY !== undefined) {
|
|
303
|
+
this.createNode(branch.nodeOtherConfig, branch, false, true);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Tạo một node component động
|
|
311
|
+
*/
|
|
312
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
313
|
+
createNode(element, branch, shouldShowArrow, isNodeOtherConfig) {
|
|
314
|
+
const config = this.configCanvas();
|
|
315
|
+
if (!config?.viewContainerRef) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (config.useVirtualizationTemplate) {
|
|
319
|
+
if (config.nodesContainer?.nativeElement) {
|
|
320
|
+
if (shouldShowArrow && !isNodeOtherConfig) {
|
|
321
|
+
this.createArrowIndicator(element, config.nodesContainer.nativeElement);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const componentType = isNodeOtherConfig ? config.nodeOtherConfigComponentType : config.nodeComponentType;
|
|
327
|
+
if (!componentType) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const componentRef = config.viewContainerRef.createComponent(componentType);
|
|
331
|
+
const el = componentRef.location.nativeElement;
|
|
332
|
+
componentRef.setInput('element', element);
|
|
333
|
+
if (branch) {
|
|
334
|
+
componentRef.setInput('branch', branch);
|
|
335
|
+
}
|
|
336
|
+
componentRef.setInput('orientation', this.orientation());
|
|
337
|
+
el.classList.add('diagram-node-dynamic');
|
|
338
|
+
applyElementStyle(el, element);
|
|
339
|
+
if (config.nodesContainer?.nativeElement) {
|
|
340
|
+
config.nodesContainer.nativeElement.appendChild(el);
|
|
341
|
+
if (shouldShowArrow && !isNodeOtherConfig) {
|
|
342
|
+
this.createArrowIndicator(element, config.nodesContainer.nativeElement);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
this.componentRefs.update((refs) => [...refs, componentRef]); // Lưu reference để cleanup sau
|
|
346
|
+
return componentRef;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Clear tất cả nodes đã tạo
|
|
350
|
+
*/
|
|
351
|
+
clearNodes() {
|
|
352
|
+
this.componentRefs().forEach((ref) => {
|
|
353
|
+
ref.destroy();
|
|
354
|
+
});
|
|
355
|
+
this.componentRefs.set([]);
|
|
356
|
+
Array.from(this.virtualNodesMap.values()).forEach((cache) => {
|
|
357
|
+
cache.component?.destroy();
|
|
358
|
+
cache.arrow?.remove();
|
|
359
|
+
cache.label?.remove();
|
|
360
|
+
});
|
|
361
|
+
this.virtualNodesMap.clear();
|
|
362
|
+
const config = this.configCanvas();
|
|
363
|
+
const nodesContainer = config?.nodesContainer?.nativeElement;
|
|
364
|
+
if (nodesContainer) {
|
|
365
|
+
if (!config?.useVirtualizationTemplate) {
|
|
366
|
+
const dynamicNodes = nodesContainer.querySelectorAll('.diagram-node-dynamic');
|
|
367
|
+
dynamicNodes.forEach((node) => node.remove());
|
|
368
|
+
}
|
|
369
|
+
const labels = nodesContainer.querySelectorAll('.branch-label');
|
|
370
|
+
labels.forEach((label) => label.remove());
|
|
371
|
+
const arrows = nodesContainer.querySelectorAll('.node-arrow-indicator');
|
|
372
|
+
arrows.forEach((arrow) => arrow.remove());
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Tạo mũi tên indicator chỉ hướng vào node.
|
|
377
|
+
* - vertical: mũi tên ▼ phía TRÊN node (luồng trên → xuống)
|
|
378
|
+
* - horizontal: mũi tên ► phía TRÁI node (luồng trái → phải)
|
|
379
|
+
*/
|
|
380
|
+
createArrowIndicator(element, container) {
|
|
381
|
+
if (element.translateX === undefined || element.translateY === undefined) {
|
|
382
|
+
return undefined;
|
|
383
|
+
}
|
|
384
|
+
const arrow = document.createElement('div');
|
|
385
|
+
arrow.className = 'node-arrow-indicator';
|
|
386
|
+
arrow.style.position = 'absolute';
|
|
387
|
+
arrow.style.zIndex = '1';
|
|
388
|
+
arrow.style.pointerEvents = 'none';
|
|
389
|
+
const arrowSize = 16;
|
|
390
|
+
const nodeWidth = element.specific_width ?? 0;
|
|
391
|
+
const nodeHeight = element.specific_height ?? 0;
|
|
392
|
+
if (this.orientation() === 'horizontal') {
|
|
393
|
+
// Mũi tên ► ở bên TRÁI node, căn giữa theo chiều cao
|
|
394
|
+
arrow.innerHTML = `
|
|
395
|
+
<svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
396
|
+
<path d="M8 4L16 8L8 12Z" fill="#9ca3af"/>
|
|
397
|
+
</svg>
|
|
398
|
+
`;
|
|
399
|
+
arrow.style.left = `${element.translateX - arrowSize}px`;
|
|
400
|
+
arrow.style.top = `${element.translateY + nodeHeight / 2 - arrowSize / 2}px`;
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
// Mũi tên ▼ ở phía TRÊN node, căn giữa theo chiều rộng
|
|
404
|
+
arrow.innerHTML = `
|
|
405
|
+
<svg width="${arrowSize}" height="${arrowSize}" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
406
|
+
<path d="M8 16L4 12H12L8 16Z" fill="#9ca3af"/>
|
|
407
|
+
</svg>
|
|
408
|
+
`;
|
|
409
|
+
arrow.style.left = `${element.translateX + nodeWidth / 2 - arrowSize / 2}px`;
|
|
410
|
+
arrow.style.top = `${element.translateY - arrowSize}px`;
|
|
411
|
+
}
|
|
412
|
+
container.appendChild(arrow);
|
|
413
|
+
return arrow;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Render branch labels (text annotations on branches)
|
|
417
|
+
*/
|
|
418
|
+
renderBranchLabels(elements) {
|
|
419
|
+
const svgContainer = this.configCanvas()?.svgContainer?.nativeElement;
|
|
420
|
+
if (!svgContainer) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
elements.forEach((element) => {
|
|
424
|
+
if (element.branches && element.branches.length > 0) {
|
|
425
|
+
element.branches.forEach((branch, index) => {
|
|
426
|
+
if (branch.specific_start_branch_x !== undefined && branch.specific_start_branch_y !== undefined) {
|
|
427
|
+
if (!branch.label) {
|
|
428
|
+
branch.label = `Nhánh ${index + 1}`;
|
|
429
|
+
}
|
|
430
|
+
this.createBranchLabel(branch);
|
|
431
|
+
}
|
|
432
|
+
if (branch.elements && branch.elements.length > 0) {
|
|
433
|
+
this.renderBranchLabels(branch.elements);
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
createBranchLabel(branch) {
|
|
440
|
+
const config = this.configCanvas();
|
|
441
|
+
const container = config?.nodesContainer?.nativeElement;
|
|
442
|
+
if (!container) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
const labelDiv = document.createElement('div');
|
|
446
|
+
labelDiv.className = 'branch-label';
|
|
447
|
+
labelDiv.textContent = branch.label || '';
|
|
448
|
+
labelDiv.style.position = 'absolute';
|
|
449
|
+
labelDiv.style.padding = '2px 7px';
|
|
450
|
+
labelDiv.style.borderRadius = '10px';
|
|
451
|
+
labelDiv.style.backgroundColor = branch.labelBgColor || '#f3f4f6';
|
|
452
|
+
labelDiv.style.fontSize = '11px';
|
|
453
|
+
labelDiv.style.fontFamily = 'system-ui, -apple-system, sans-serif';
|
|
454
|
+
labelDiv.style.color = '#374151';
|
|
455
|
+
labelDiv.style.whiteSpace = 'nowrap';
|
|
456
|
+
labelDiv.style.zIndex = '2';
|
|
457
|
+
labelDiv.style.pointerEvents = 'none';
|
|
458
|
+
container.appendChild(labelDiv);
|
|
459
|
+
const startX = branch.specific_start_branch_x ?? 0;
|
|
460
|
+
const startY = branch.specific_start_branch_y ?? 0;
|
|
461
|
+
const labelW = labelDiv.offsetWidth;
|
|
462
|
+
const labelH = labelDiv.offsetHeight || 18;
|
|
463
|
+
if (this.orientation() === 'horizontal') {
|
|
464
|
+
/**
|
|
465
|
+
* Horizontal: label nằm TRÊN đường line nằm ngang.
|
|
466
|
+
* specific_start_branch = điểm bắt đầu đoạn thẳng ngang đến element.
|
|
467
|
+
* Đặt label tịnh tiến sang phải 8px từ ngoặt nhánh, và căn giữa dây.
|
|
468
|
+
*/
|
|
469
|
+
labelDiv.style.left = `${startX + 4}px`;
|
|
470
|
+
labelDiv.style.top = `${startY - labelH / 2}px`;
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
/**
|
|
474
|
+
* Vertical: label nằm BÊN TRÁI đường ngang, căn giữa theo Y.
|
|
475
|
+
* specific_start_branch = điểm đầu đoạn thẳng đến element (sau curve).
|
|
476
|
+
*/
|
|
477
|
+
labelDiv.style.left = `${startX - labelW / 2 - 4}px`;
|
|
478
|
+
labelDiv.style.top = `${startY - labelH / 2 + 4}px`;
|
|
479
|
+
}
|
|
480
|
+
return labelDiv;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Render dấu "+" tại mỗi vị trí có thể thả element từ sidebar.
|
|
484
|
+
* Service tự tạo DOM elements và inject vào nodesContainer.
|
|
485
|
+
* @param flatElements Danh sách flat elements đã tính toán vị trí
|
|
486
|
+
* @param onDrop Callback khi người dùng thả element vào một "+"
|
|
487
|
+
* @param canDropFn (tùy chọn) Function kiểm tra điều kiện hiển thị drop zone.
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
renderDropZones(flatElements, onDrop, canDropFn, ruleConnectableElements) {
|
|
491
|
+
this.clearDropZones();
|
|
492
|
+
const container = this.configCanvas()?.nodesContainer?.nativeElement;
|
|
493
|
+
if (!container)
|
|
494
|
+
return;
|
|
495
|
+
flatElements.forEach((el) => {
|
|
496
|
+
if (el.code === canvasConfigReadonly().TYPE_ELEMENT_EXIT)
|
|
497
|
+
return;
|
|
498
|
+
if (el.element_type === canvasConfigReadonly().TYPE_ELEMENT_WORKFLOW) {
|
|
499
|
+
el.branches?.forEach((branch) => {
|
|
500
|
+
if (canDropFn(undefined, el, branch, ruleConnectableElements))
|
|
501
|
+
return;
|
|
502
|
+
const top = this.orientation() === 'horizontal' ? this.calcDropZoneTopBranchH(el, branch) : this.calcDropZoneTopBranch(el, branch);
|
|
503
|
+
const left = this.orientation() === 'horizontal' ? this.calcDropZoneLeftBranchH(el, branch) : this.calcDropZoneLeftBranch(el, branch);
|
|
504
|
+
this.createDropZoneEl(container, top, left, el, branch, onDrop);
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
if (!canDropFn(undefined, el, undefined, ruleConnectableElements))
|
|
509
|
+
return;
|
|
510
|
+
const top = this.orientation() === 'horizontal' ? this.calcDropZoneTopNodeH(el) : this.calcDropZoneTopNode(el);
|
|
511
|
+
const left = this.orientation() === 'horizontal' ? this.calcDropZoneLeftNodeH(el) : this.calcDropZoneLeftNode(el);
|
|
512
|
+
this.createDropZoneEl(container, top, left, el, undefined, onDrop);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
/** Xóa tất cả drop zone "+" khỏi DOM */
|
|
517
|
+
clearDropZones() {
|
|
518
|
+
const container = this.configCanvas()?.nodesContainer?.nativeElement;
|
|
519
|
+
if (!container)
|
|
520
|
+
return;
|
|
521
|
+
container.querySelectorAll('.diagram-drop-zone').forEach((el) => el.remove());
|
|
522
|
+
}
|
|
523
|
+
createDropZoneEl(container, top, left, element, branch, onDrop) {
|
|
524
|
+
const indicatorStyle = this.configCanvas()?.dropZoneStyle;
|
|
525
|
+
const RECT_W = element.specific_width ?? canvasConfigReadonly().WIDTH_ELEMENT_DEFAULT;
|
|
526
|
+
const RECT_H = element.specific_height ?? canvasConfigReadonly().HEIGHT_ELEMENT_DEFAULT;
|
|
527
|
+
// Tâm của nút tròn
|
|
528
|
+
const centerX = left + canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
529
|
+
const centerY = top + canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
530
|
+
// Hit zone vô hình: rộng hơn rectangle một khoản padding để bắt drag sớm hơn
|
|
531
|
+
const HIT_PAD = 20;
|
|
532
|
+
const HIT_W = RECT_W + HIT_PAD * 2;
|
|
533
|
+
const HIT_H = RECT_H + HIT_PAD * 2;
|
|
534
|
+
const hitLeft = centerX - HIT_W / 2;
|
|
535
|
+
const hitTop = centerY - HIT_H / 2;
|
|
536
|
+
// ── Hit zone (wrapper vô hình, vùng nhận drag rộng) ─────────────────
|
|
537
|
+
const hitZone = document.createElement('div');
|
|
538
|
+
hitZone.className = 'diagram-drop-zone';
|
|
539
|
+
hitZone.style.cssText = `
|
|
540
|
+
position: absolute;
|
|
541
|
+
top: ${hitTop}px;
|
|
542
|
+
left: ${hitLeft}px;
|
|
543
|
+
z-index: 9;
|
|
544
|
+
width: ${HIT_W}px;
|
|
545
|
+
height: ${HIT_H}px;
|
|
546
|
+
cursor: pointer;
|
|
547
|
+
`;
|
|
548
|
+
// ── Indicator (con bên trong, phần hiển thị) ─────────────────────────
|
|
549
|
+
const indicator = document.createElement('div');
|
|
550
|
+
indicator.style.pointerEvents = 'none'; // tránh tranh chấp event với hitZone
|
|
551
|
+
// Vị trí dot trong hitZone (căn giữa hitZone)
|
|
552
|
+
const dotOffsetLeft = HIT_W / 2 - canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
553
|
+
const dotOffsetTop = HIT_H / 2 - canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
554
|
+
// Vị trí rectangle trong hitZone (căn giữa hitZone)
|
|
555
|
+
const rectOffsetLeft = HIT_PAD;
|
|
556
|
+
const rectOffsetTop = HIT_H / 2 - RECT_H / 2;
|
|
557
|
+
const applyDotStyle = () => {
|
|
558
|
+
const s = indicatorStyle;
|
|
559
|
+
const size = canvasConfigReadonly().ADD_ICON_DIAMETER;
|
|
560
|
+
const bg = s?.backgroundColor ?? '#3b82f6';
|
|
561
|
+
const iconColor = s?.iconColor ?? '#ffffff';
|
|
562
|
+
const opacity = s?.opacity ?? 0.95;
|
|
563
|
+
const borderRadius = s?.borderRadius ?? '50%';
|
|
564
|
+
setStylesElement(indicator, {
|
|
565
|
+
position: 'absolute',
|
|
566
|
+
top: `${dotOffsetTop}px`,
|
|
567
|
+
left: `${dotOffsetLeft}px`,
|
|
568
|
+
width: `${size}px`,
|
|
569
|
+
height: `${size}px`,
|
|
570
|
+
pointerEvents: 'none',
|
|
571
|
+
display: 'flex',
|
|
572
|
+
alignItems: 'center',
|
|
573
|
+
justifyContent: 'center',
|
|
574
|
+
transition: 'opacity 0.15s ease',
|
|
575
|
+
border: 'none',
|
|
576
|
+
});
|
|
577
|
+
if (s?.renderIndicator) {
|
|
578
|
+
indicator.innerHTML = s.renderIndicator(size);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
indicator.innerHTML = `
|
|
582
|
+
<div style="
|
|
583
|
+
width: ${size}px;
|
|
584
|
+
height: ${size}px;
|
|
585
|
+
background-color: ${bg};
|
|
586
|
+
border-radius: ${borderRadius};
|
|
587
|
+
opacity: ${opacity};
|
|
588
|
+
display: flex;
|
|
589
|
+
align-items: center;
|
|
590
|
+
justify-content: center;
|
|
591
|
+
pointer-events: none;
|
|
592
|
+
"><i class="libs-ui-icon-add before:text-[${iconColor}]"></i></div>
|
|
593
|
+
`;
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
const applyRectStyle = () => {
|
|
597
|
+
const s = indicatorStyle;
|
|
598
|
+
const hoverBg = s?.hoverBackgroundColor ?? '#eef4ff';
|
|
599
|
+
const hoverBorder = s?.hoverBorderColor ?? 'rgba(59, 130, 246, 0.7)';
|
|
600
|
+
const hoverBorderStyle = s?.hoverBorderStyle ?? 'dashed';
|
|
601
|
+
const hoverRadius = s?.hoverBorderRadius ?? 10;
|
|
602
|
+
setStylesElement(indicator, {
|
|
603
|
+
top: `${rectOffsetTop}px`,
|
|
604
|
+
left: `${rectOffsetLeft}px`,
|
|
605
|
+
width: `${RECT_W}px`,
|
|
606
|
+
height: `${RECT_H}px`,
|
|
607
|
+
borderRadius: `${hoverRadius}px`,
|
|
608
|
+
backgroundColor: hoverBg,
|
|
609
|
+
border: `2px ${hoverBorderStyle} ${hoverBorder}`,
|
|
610
|
+
transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
611
|
+
});
|
|
612
|
+
// Nếu có hàm render động cho trạng thái hover — gọi nó
|
|
613
|
+
indicator.innerHTML = s?.renderHoverIndicator ? s.renderHoverIndicator() : '';
|
|
614
|
+
};
|
|
615
|
+
applyDotStyle();
|
|
616
|
+
hitZone.appendChild(indicator);
|
|
617
|
+
hitZone.addEventListener('dragenter', (e) => {
|
|
618
|
+
e.preventDefault();
|
|
619
|
+
applyRectStyle();
|
|
620
|
+
});
|
|
621
|
+
hitZone.addEventListener('dragover', (e) => {
|
|
622
|
+
e.preventDefault();
|
|
623
|
+
if (e.dataTransfer)
|
|
624
|
+
e.dataTransfer.dropEffect = 'copy';
|
|
625
|
+
});
|
|
626
|
+
hitZone.addEventListener('dragleave', (e) => {
|
|
627
|
+
if (!hitZone.contains(e.relatedTarget)) {
|
|
628
|
+
applyDotStyle();
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
hitZone.addEventListener('drop', (e) => {
|
|
632
|
+
e.preventDefault();
|
|
633
|
+
e.stopPropagation();
|
|
634
|
+
const raw = e.dataTransfer?.getData('application/json') ?? '';
|
|
635
|
+
onDrop(element, branch, raw);
|
|
636
|
+
});
|
|
637
|
+
container.appendChild(hitZone);
|
|
638
|
+
}
|
|
639
|
+
// ── Vertical drop zone helpers (existing) ───────────────────────────────────
|
|
640
|
+
calcDropZoneTopBranch(el, branch) {
|
|
641
|
+
const oc = branch.nodeOtherConfig;
|
|
642
|
+
if (oc)
|
|
643
|
+
return (oc.specific_y ?? 0) + (oc.specific_height ?? canvasConfigReadonly().ELEMENT_WAIT_DEFAULT) + 10;
|
|
644
|
+
return (branch.specific_start_branch_y ?? 0) + 30;
|
|
645
|
+
}
|
|
646
|
+
calcDropZoneLeftBranch(el, branch) {
|
|
647
|
+
const firstEl = branch.elements?.[0];
|
|
648
|
+
if (firstEl?.translateX !== undefined)
|
|
649
|
+
return firstEl.translateX + (firstEl.specific_width ?? canvasConfigReadonly().WIDTH_ELEMENT_DEFAULT) / 2 - canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
650
|
+
return (el.translateX ?? 0) + (el.specific_width ?? canvasConfigReadonly().WIDTH_ELEMENT_DEFAULT) / 2 - canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
651
|
+
}
|
|
652
|
+
calcDropZoneTopNode(el) {
|
|
653
|
+
const oc = el.nodeOtherConfig;
|
|
654
|
+
if (oc)
|
|
655
|
+
return (oc.specific_y ?? 0) + (oc.specific_height ?? canvasConfigReadonly().ELEMENT_WAIT_DEFAULT) + 10;
|
|
656
|
+
return (el.translateY ?? 0) + (el.specific_height ?? canvasConfigReadonly().HEIGHT_ELEMENT_DEFAULT) + 10;
|
|
657
|
+
}
|
|
658
|
+
calcDropZoneLeftNode(el) {
|
|
659
|
+
return (el.translateX ?? 0) + (el.specific_width ?? canvasConfigReadonly().WIDTH_ELEMENT_DEFAULT) / 2 - canvasConfigReadonly().ADD_ICON_DIAMETER / 2;
|
|
660
|
+
}
|
|
661
|
+
// ── Horizontal drop zone helpers ─────────────────────────────────────────────
|
|
662
|
+
/**
|
|
663
|
+
* Horizontal node: "+" nằm giữa đường line nối 2 node — căn giữa Y của element.
|
|
664
|
+
*/
|
|
665
|
+
calcDropZoneTopNodeH(el) {
|
|
666
|
+
const D = canvasConfigReadonly().ADD_ICON_DIAMETER;
|
|
667
|
+
const centerY = (el.translateY ?? 0) + (el.specific_height ?? canvasConfigReadonly().HEIGHT_ELEMENT_DEFAULT) / 2;
|
|
668
|
+
return centerY - D / 2;
|
|
669
|
+
}
|
|
670
|
+
calcDropZoneLeftNodeH(el) {
|
|
671
|
+
const D = canvasConfigReadonly().ADD_ICON_DIAMETER;
|
|
672
|
+
const M = canvasConfigReadonly().ELEMENT_MARGIN_DEFAULT;
|
|
673
|
+
const oc = el.nodeOtherConfig;
|
|
674
|
+
if (oc) {
|
|
675
|
+
const right = (oc.specific_x ?? 0) + (oc.specific_width ?? canvasConfigReadonly().ELEMENT_WAIT_DEFAULT);
|
|
676
|
+
return right + M / 2 - D / 2;
|
|
677
|
+
}
|
|
678
|
+
const right = (el.translateX ?? 0) + (el.specific_width ?? canvasConfigReadonly().WIDTH_ELEMENT_DEFAULT);
|
|
679
|
+
// Midpoint của khoảng trống giữa node và node tiếp theo (gap = ELEMENT_MARGIN_DEFAULT)
|
|
680
|
+
return right + M / 2 - D / 2;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Horizontal branch: "+" nằm căn giữa Y của branch line, sau phần tử cuối trong nhánh.
|
|
684
|
+
*/
|
|
685
|
+
calcDropZoneTopBranchH(el, branch) {
|
|
686
|
+
const D = canvasConfigReadonly().ADD_ICON_DIAMETER;
|
|
687
|
+
// specific_start_branch_y = tâm Y của đường nhánh
|
|
688
|
+
const centerY = branch.specific_start_branch_y ?? 0;
|
|
689
|
+
return centerY - D / 2;
|
|
690
|
+
}
|
|
691
|
+
calcDropZoneLeftBranchH(el, branch) {
|
|
692
|
+
const D = canvasConfigReadonly().ADD_ICON_DIAMETER;
|
|
693
|
+
const M = canvasConfigReadonly().ELEMENT_MARGIN_DEFAULT;
|
|
694
|
+
// Sau nodeOtherConfig của nhánh (cổ nhánh)
|
|
695
|
+
const oc = branch.nodeOtherConfig;
|
|
696
|
+
if (oc?.specific_x !== undefined) {
|
|
697
|
+
return (oc.specific_x ?? 0) + (oc.specific_width ?? canvasConfigReadonly().ELEMENT_WAIT_DEFAULT) + M / 2 - D / 2;
|
|
698
|
+
}
|
|
699
|
+
// Nếu nhánh không có nodeOtherConfig: đặt sau điểm rẽ nhánh
|
|
700
|
+
return (branch.specific_start_branch_x ?? 0) + M / 2 - D / 2;
|
|
701
|
+
}
|
|
702
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDiagramDrawService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
703
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDiagramDrawService, providedIn: 'root' });
|
|
704
|
+
}
|
|
705
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDiagramDrawService, decorators: [{
|
|
706
|
+
type: Injectable,
|
|
707
|
+
args: [{
|
|
708
|
+
providedIn: 'root',
|
|
709
|
+
}]
|
|
710
|
+
}] });
|
|
711
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ3JhbS1kcmF3LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL3NlcnZpY2VzL2RpYWdyYW0tZHJhdy9zcmMvZGlhZ3JhbS1kcmF3LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFnQixVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSWxELE9BQU8sRUFBRSxxQ0FBcUMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25GLE9BQU8sRUFBRSwrQ0FBK0MsRUFBRSxNQUFNLGdEQUFnRCxDQUFDOztBQUVqSCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQWdCO0lBQ3pDLDZDQUE2QyxFQUFFLEVBQUU7SUFDakQsc0JBQXNCLEVBQUUsRUFBRTtJQUMxQiw2QkFBNkIsRUFBRSxFQUFFO0lBQ2pDLHFDQUFxQyxFQUFFLEVBQUU7SUFDekMsOEJBQThCLEVBQUUsR0FBRztJQUNuQyxvQkFBb0IsRUFBRSxFQUFFO0lBQ3hCLHdCQUF3QixFQUFFLFFBQVE7SUFDbEMsd0JBQXdCLEVBQUUsR0FBRztJQUM3Qiw4Q0FBOEMsRUFBRSxFQUFFO0lBRWxELGdCQUFnQixFQUFFLEVBQUU7SUFDcEIsZUFBZSxFQUFFLEVBQUU7SUFDbkIsb0JBQW9CLEVBQUUsRUFBRTtJQUN4QiwwQkFBMEIsRUFBRSxDQUFDO0lBRTdCLGlCQUFpQixFQUFFLE1BQU07SUFDekIscUJBQXFCLEVBQUUsVUFBVTtJQUNqQyxxQkFBcUIsRUFBRSxHQUFHO0lBQzFCLHNCQUFzQixFQUFFLEVBQUU7SUFFMUIsaUJBQWlCLEVBQUUsRUFBRTtDQUN0QixDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxvQkFB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ZSxDQUFDO1FBQ2xDLElBQUksRUFBRSxFQUFFLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxjQUFjLElBQUksb0JBQW9CLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuSCxDQUFDO1FBQ0QsNERBQTREO1FBQzVELE9BQU8sQ0FBQyxNQUFNLENBQUMsdUJBQXVCLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9ELENBQUM7d0dBMXVCVSx3QkFBd0I7NEdBQXhCLHdCQUF3QixjQUZ2QixNQUFNOzs0RkFFUCx3QkFBd0I7a0JBSHBDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHNldFN0eWxlc0VsZW1lbnQgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBJUnVsZUNvbm5lY3RhYmxlLCBURHJvcFpvbmVDYW5Ecm9wRm4gfSBmcm9tICcuL2ludGVyZmFjZXMvY2FudmFzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJRGF0YURpYWdyYW1Db25maWdTdmcgfSBmcm9tICcuL2ludGVyZmFjZXMvY29vcmRpbmF0ZXMuaW50ZXJmYWNlJztcbmltcG9ydCB7IElDYW52YXNDb25maWcsIElDb25maWcsIElEaWFncmFtRWxlbWVudCwgSURpYWdyYW1FbGVtZW50QnJhbmNoLCBJRHJvcFpvbmVJbmRpY2F0b3JTdHlsZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9kaWFncmFtLmludGVyZmFjZSc7XG5pbXBvcnQgeyBNb0xpYkRpYWdyYW1DYWxjdWxhdG9yQ29vcmRpbmF0ZXNVdGlsIH0gZnJvbSAnLi91dGlscy9jYWxjdWxhdG9yLWVsZW1lbnQudXRpbCc7XG5pbXBvcnQgeyBhcHBseUVsZW1lbnRTdHlsZSwgc2V0QXR0cmlidXRlU3ZnQW5kQXBwZW5kIH0gZnJvbSAnLi91dGlscy9kaWFncmFtLnV0aWwnO1xuaW1wb3J0IHsgTW9MaWJEaWFncmFtSG9yaXpvbnRhbENhbGN1bGF0b3JDb29yZGluYXRlc1V0aWwgfSBmcm9tICcuL3V0aWxzL2hvcml6b250YWwvY2FsY3VsYXRvci1jb29yZGluYXRlcy51dGlsJztcblxuY29uc3QgY2FudmFzQ29uZmlnID0gc2lnbmFsPElDYW52YXNDb25maWc+KHtcbiAgRUxFTUVOVF9XSURUSF9ERUZBVUxUX0JSQU5DSF9XSEVOX05PVF9FTEVNRU5UOiA2MCxcbiAgRUxFTUVOVF9NQVJHSU5fREVGQVVMVDogNjAsXG4gIEVMRU1FTlRfTUFSR0lOX0RFRkFVTFRfQlJBTkNIOiAxNixcbiAgRUxFTUVOVF9NQVJHSU5fQkVUV0VFTl9CUkFOQ0hfREVGQVVMVDogNjAsXG4gIERFRkFVTFRfQlJBTkNIX1dIRU5fTk9fRUxFTUVOVDogMTAwLFxuICBFTEVNRU5UX0hFSUdIVF9DVVJWRTogMTAsXG4gIEVMRU1FTlRfU1ZHX1NUUk9LRV9DT0xPUjogJzljYTJhZCcsXG4gIEVMRU1FTlRfU1ZHX1NUUk9LRV9XSURUSDogJzEnLFxuICBFTEVNRU5UX01BUkdJTl9ERUZBVUxUX0JSQU5DSF9UT19FTEVNRU5UX0ZJUlNUOiA3OCxcblxuICBESVNUQU5DRV9UT19XQUlUOiAzMCxcbiAgV0FJVF9UT19FTEVNRU5UOiA1MCxcbiAgRUxFTUVOVF9XQUlUX0RFRkFVTFQ6IDI4LFxuICBESVNUQU5DRV9XQUlUX1RPX05FWFRfTElORTogNCxcblxuICBUWVBFX0VMRU1FTlRfRVhJVDogJ0VYSVQnLFxuICBUWVBFX0VMRU1FTlRfV09SS0ZMT1c6ICdXT1JLRkxPVycsXG4gIFdJRFRIX0VMRU1FTlRfREVGQVVMVDogMTY1LFxuICBIRUlHSFRfRUxFTUVOVF9ERUZBVUxUOiA0OCxcblxuICBBRERfSUNPTl9ESUFNRVRFUjogMjQsXG59KTtcblxuZXhwb3J0IGNvbnN0IGNhbnZhc0NvbmZpZ1JlYWRvbmx5ID0gY2FudmFzQ29uZmlnLmFzUmVhZG9ubHkoKTtcbmV4cG9ydCBjb25zdCBzdG9yZURhdGFEZWZhdWx0ID0ge1xuICBwb3NpdGlvbk1heExlZnQ6IDAsXG4gIHBvc2l0aW9uTWF4VG9wOiAwLFxuICB3aWR0aEhlaWdodFN2Z0NhbnZhczogeyBoZWlnaHRTdmc6IHdpbmRvdy5pbm5lckhlaWdodCwgd2lkdGhTdmc6IHdpbmRvdy5pbm5lcldpZHRoIH0sXG59O1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaURpYWdyYW1EcmF3U2VydmljZSB7XG4gIHByaXZhdGUgY29uZmlnQ2FudmFzID0gc2lnbmFsPElDb25maWcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHJlYWRvbmx5IG9yaWVudGF0aW9uID0gc2lnbmFsPCd2ZXJ0aWNhbCcgfCAnaG9yaXpvbnRhbCc+KCd2ZXJ0aWNhbCcpO1xuICBwcml2YXRlIGVsZW1lbnRTdmcgPSBzaWduYWw8U1ZHUGF0aEVsZW1lbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgYXR0cmlidXRlU3ZnRCA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBjb21wb25lbnRSZWZzID0gc2lnbmFsPENvbXBvbmVudFJlZjxhbnk+W10+KFtdKTtcblxuICAvLyBWaXJ0dWFsaXphdGlvbiBUcmFja2luZ1xuICBwcml2YXRlIHZpcnR1YWxWaWV3cG9ydD86IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG4gIHByaXZhdGUgdmlydHVhbEZsYXRFbGVtZW50czogeyBlbGVtZW50OiBJRGlhZ3JhbUVsZW1lbnQ7IGJyYW5jaD86IElEaWFncmFtRWxlbWVudEJyYW5jaDsgc2hvdWxkU2hvd0Fycm93OiBib29sZWFuOyBpc090aGVyQ29uZmlnOiBib29sZWFuOyBwYXJlbnRJZD86IHN0cmluZyB8IG51bWJlciB9W10gPSBbXTtcbiAgcHJpdmF0ZSB2aXJ0dWFsRmxhdEJyYW5jaGVzOiBJRGlhZ3JhbUVsZW1lbnRCcmFuY2hbXSA9IFtdO1xuICBwcml2YXRlIHZpcnR1YWxOb2Rlc01hcCA9IG5ldyBNYXA8c3RyaW5nLCB7IGNvbXBvbmVudD86IENvbXBvbmVudFJlZjxhbnk+OyBhcnJvdz86IEhUTUxFbGVtZW50OyBsYWJlbD86IEhUTUxFbGVtZW50IH0+KCk7XG5cbiAgcHVibGljIHVwZGF0ZVZpZXdwb3J0KHZwOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9KSB7XG4gICAgdGhpcy52aXJ0dWFsVmlld3BvcnQgPSB2cDtcbiAgICBpZiAodGhpcy5jb25maWdDYW52YXMoKT8udXNlVmlydHVhbGl6YXRpb25UZW1wbGF0ZSkge1xuICAgICAgdGhpcy5hcHBseVZpcnR1YWxpemF0aW9uRGlmZigpO1xuICAgIH1cbiAgfVxuXG4gIHNldCBzZXRDb25maWcoY29uZmlnOiBJQ29uZmlnKSB7XG4gICAgdGhpcy5jb25maWdDYW52YXMuc2V0KGNvbmZpZyk7XG4gIH1cblxuICBzZXQgc2V0Q29uZmlnQ2FudmFzKGNvbmZpZzogUGFydGlhbDxJQ2FudmFzQ29uZmlnPikge1xuICAgIGlmICghY29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2FudmFzQ29uZmlnLnVwZGF0ZSgoY3VycmVudCkgPT4gKHsgLi4uY3VycmVudCwgLi4uY29uZmlnIH0pKTtcbiAgfVxuXG4gIGNvbmZpZ1hZRWxlbWVudHMoZWxlbWVudHM6IEFycmF5PElEaWFncmFtRWxlbWVudD4sIHVwZGF0ZVNWRz86IGJvb2xlYW4sIHBvc2l0aW9uWD86IG51bWJlcikge1xuICAgIGNvbnN0IHN0b3JlRGF0YSA9IHRoaXMuY29uZmlnQ2FudmFzKCk/LnN0b3JlRGF0YURlZmluZSA/PyBzdG9yZURhdGFEZWZhdWx0O1xuICAgIGNvbnN0IG1heExlZnRPcmlnaW4gPSBzdG9yZURhdGEucG9zaXRpb25NYXhMZWZ0O1xuICAgIGNvbnN0IG1heFRvcE9yaWdpbiA9IHN0b3JlRGF0YS5wb3NpdGlvbk1heFRvcCA/PyAwO1xuXG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24oKSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBNb0xpYkRpYWdyYW1Ib3Jpem9udGFsQ2FsY3VsYXRvckNvb3JkaW5hdGVzVXRpbC5zZXRYWUVsZW1lbnRzKGVsZW1lbnRzLCBzdG9yZURhdGEsIHBvc2l0aW9uWCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIE1vTGliRGlhZ3JhbUNhbGN1bGF0b3JDb29yZGluYXRlc1V0aWwuc2V0WFlFbGVtZW50cyhlbGVtZW50cywgc3RvcmVEYXRhLCBwb3NpdGlvblgpO1xuICAgIH1cblxuICAgIGNvbnN0IG1heExlZnROZXcgPSBzdG9yZURhdGEucG9zaXRpb25NYXhMZWZ0O1xuICAgIGNvbnN0IG1heFRvcE5ldyA9IHN0b3JlRGF0YS5wb3NpdGlvbk1heFRvcCA/PyAwO1xuXG4gICAgaWYgKCF0aGlzLmVsZW1lbnRTdmcoKSkge1xuICAgICAgdGhpcy5lbGVtZW50U3ZnLnNldChkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgJ3BhdGgnKSk7XG4gICAgfVxuXG4gICAgaWYgKCF1cGRhdGVTVkcgJiYgdGhpcy5jb25maWdDYW52YXMoKT8uc3ZnQ29udGFpbmVyICYmIHRoaXMuZWxlbWVudFN2ZygpKSB7XG4gICAgICBzZXRBdHRyaWJ1dGVTdmdBbmRBcHBlbmQodGhpcy5jb25maWdDYW52YXMoKT8uc3ZnQ29udGFpbmVyLCB0aGlzLmVsZW1lbnRTdmcoKSwgJycpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uKCkgPT09ICdob3Jpem9udGFsJyAmJiBtYXhUb3BPcmlnaW4gIT09IG1heFRvcE5ldykge1xuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbkVsZW1lbnRzKG1heFRvcE5ldywgZWxlbWVudHMsIHN0b3JlRGF0YSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uKCkgPT09ICd2ZXJ0aWNhbCcgJiYgbWF4TGVmdE9yaWdpbiAhPT0gbWF4TGVmdE5ldykge1xuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbkVsZW1lbnRzKG1heExlZnROZXcsIGVsZW1lbnRzLCBzdG9yZURhdGEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmVsZW1lbnRTdmcoKSkge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVTdmdELnNldCgnJyk7XG4gICAgICB0aGlzLmJ1aWxkU3ZnRWxlbWVudChlbGVtZW50cyk7XG4gICAgICB0aGlzLmVsZW1lbnRTdmcoKT8uc2V0QXR0cmlidXRlKCdkJywgdGhpcy5hdHRyaWJ1dGVTdmdEKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9zaXRpb25FbGVtZW50cyhwb3NpdGlvbk9mZnNldDogbnVtYmVyLCBlbGVtZW50czogQXJyYXk8SURpYWdyYW1FbGVtZW50PiwgY29uZmlnOiBJRGF0YURpYWdyYW1Db25maWdTdmcpIHtcbiAgICBpZiAocG9zaXRpb25PZmZzZXQgJiYgcG9zaXRpb25PZmZzZXQgPCAwKSB7XG4gICAgICBwb3NpdGlvbk9mZnNldCA9IHBvc2l0aW9uT2Zmc2V0ICogLTEgKyAyMDA7IC8vIDEwMCBsw6Aga2hv4bqjbmcgY8OhY2ggY8OhY2ggYmnDqm5cbiAgICB9XG4gICAgaWYgKHRoaXMub3JpZW50YXRpb24oKSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBNb0xpYkRpYWdyYW1Ib3Jpem9udGFsQ2FsY3VsYXRvckNvb3JkaW5hdGVzVXRpbC5zZXRYWUVsZW1lbnRzKGVsZW1lbnRzLCB7IC4uLmNvbmZpZywgdXBkYXRlU1ZHOiB0cnVlIH0sIHBvc2l0aW9uT2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgTW9MaWJEaWFncmFtQ2FsY3VsYXRvckNvb3JkaW5hdGVzVXRpbC5zZXRYWUVsZW1lbnRzKGVsZW1lbnRzLCB7IC4uLmNvbmZpZywgdXBkYXRlU1ZHOiB0cnVlIH0sIHBvc2l0aW9uT2Zmc2V0KTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmVsZW1lbnRTdmcoKSkge1xuICAgICAgdGhpcy5lbGVtZW50U3ZnLnNldChkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgJ3BhdGgnKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmVsZW1lbnRTdmcoKSkge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVTdmdELnNldCgnJyk7XG4gICAgICB0aGlzLmJ1aWxkU3ZnRWxlbWVudChlbGVtZW50cyk7XG4gICAgICB0aGlzLmVsZW1lbnRTdmcoKT8uc2V0QXR0cmlidXRlKCdkJywgdGhpcy5hdHRyaWJ1dGVTdmdEKCkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTdmdFbGVtZW50KGVsZW1lbnRzOiBBcnJheTxJRGlhZ3JhbUVsZW1lbnQ+KSB7XG4gICAgZWxlbWVudHMuZm9yRWFjaCgoY3VycmVudEVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChjdXJyZW50RWxlbWVudC5hdHRyaWJ1dGVTdmdEKSB7XG4gICAgICAgIHRoaXMuYXR0cmlidXRlU3ZnRC51cGRhdGUoKHByZXYpID0+IGAke3ByZXYgPz8gJyd9ICR7Y3VycmVudEVsZW1lbnQuYXR0cmlidXRlU3ZnRH1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50RWxlbWVudC5ub2RlT3RoZXJDb25maWc/LmF0dHJpYnV0ZVN2Z0QpIHtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVTdmdELnVwZGF0ZSgocHJldikgPT4gYCR7cHJldiA/PyAnJ30gJHtjdXJyZW50RWxlbWVudC5ub2RlT3RoZXJDb25maWc/LmF0dHJpYnV0ZVN2Z0R9YCk7XG4gICAgICB9XG4gICAgICBpZiAoIWN1cnJlbnRFbGVtZW50LmJyYW5jaGVzIHx8ICFjdXJyZW50RWxlbWVudC5icmFuY2hlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50RWxlbWVudC5icmFuY2hlcy5mb3JFYWNoKChicmFuY2gpID0+IHtcbiAgICAgICAgaWYgKGJyYW5jaC5hdHRyaWJ1dGVTdmdEKSB7XG4gICAgICAgICAgdGhpcy5hdHRyaWJ1dGVTdmdELnVwZGF0ZSgocHJldikgPT4gYCR7cHJldiA/PyAnJ30gJHticmFuY2guYXR0cmlidXRlU3ZnRH1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnJhbmNoLm5vZGVPdGhlckNvbmZpZz8uYXR0cmlidXRlU3ZnRCkge1xuICAgICAgICAgIHRoaXMuYXR0cmlidXRlU3ZnRC51cGRhdGUoKHByZXYpID0+IGAke3ByZXYgPz8gJyd9ICR7YnJhbmNoLm5vZGVPdGhlckNvbmZpZz8uYXR0cmlidXRlU3ZnRH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghYnJhbmNoLmVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYnVpbGRTdmdFbGVtZW50KGJyYW5jaC5lbGVtZW50cyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgdOG6pXQgY+G6oyBub2RlcyB04burIGVsZW1lbnRzIGFycmF5XG4gICAqL1xuICByZW5kZXJOb2RlcyhlbGVtZW50czogQXJyYXk8SURpYWdyYW1FbGVtZW50Pikge1xuICAgIGlmICh0aGlzLmNvbmZpZ0NhbnZhcygpPy51c2VWaXJ0dWFsaXphdGlvblRlbXBsYXRlKSB7XG4gICAgICB0aGlzLmV4dHJhY3RWaXJ0dWFsRWxlbWVudHMoZWxlbWVudHMpO1xuICAgICAgdGhpcy5hcHBseVZpcnR1YWxpemF0aW9uRGlmZigpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2xlYXJOb2RlcygpO1xuICAgIHRoaXMucmVuZGVyRWxlbWVudHNSZWN1cnNpdmVseShlbGVtZW50cywgdHJ1ZSwgdW5kZWZpbmVkKTtcbiAgICB0aGlzLnJlbmRlckJyYW5jaExhYmVscyhlbGVtZW50cyk7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RWaXJ0dWFsRWxlbWVudHMoZWxlbWVudHM6IElEaWFncmFtRWxlbWVudFtdKSB7XG4gICAgdGhpcy52aXJ0dWFsRmxhdEVsZW1lbnRzID0gW107XG4gICAgdGhpcy52aXJ0dWFsRmxhdEJyYW5jaGVzID0gW107XG4gICAgY29uc3Qgc2NhbiA9IChsaXN0OiBJRGlhZ3JhbUVsZW1lbnRbXSwgYnJhbmNoPzogSURpYWdyYW1FbGVtZW50QnJhbmNoLCBpc0ZpcnN0TGV2ZWwgPSB0cnVlKSA9PiB7XG4gICAgICBsaXN0LmZvckVhY2goKGVsLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBzaG91bGRTaG93QXJyb3cgPSAhKGlzRmlyc3RMZXZlbCAmJiBpbmRleCA9PT0gMCk7XG4gICAgICAgIHRoaXMudmlydHVhbEZsYXRFbGVtZW50cy5wdXNoKHsgZWxlbWVudDogZWwsIGJyYW5jaCwgaXNPdGhlckNvbmZpZzogZmFsc2UsIHNob3VsZFNob3dBcnJvdywgcGFyZW50SWQ6IGVsLmlkIH0pO1xuICAgICAgICBpZiAoZWwubm9kZU90aGVyQ29uZmlnKSB0aGlzLnZpcnR1YWxGbGF0RWxlbWVudHMucHVzaCh7IGVsZW1lbnQ6IGVsLm5vZGVPdGhlckNvbmZpZywgYnJhbmNoLCBpc090aGVyQ29uZmlnOiB0cnVlLCBzaG91bGRTaG93QXJyb3c6IGZhbHNlLCBwYXJlbnRJZDogZWwuaWQgfSk7XG4gICAgICAgIGlmIChlbC5icmFuY2hlcykge1xuICAgICAgICAgIGVsLmJyYW5jaGVzLmZvckVhY2goKGIsIGJJbmRleCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFiLmxhYmVsKSBiLmxhYmVsID0gYE5ow6FuaCAke2JJbmRleCArIDF9YDtcbiAgICAgICAgICAgIHRoaXMudmlydHVhbEZsYXRCcmFuY2hlcy5wdXNoKGIpO1xuICAgICAgICAgICAgaWYgKGIuZWxlbWVudHMpIHNjYW4oYi5lbGVtZW50cyBhcyBJRGlhZ3JhbUVsZW1lbnRbXSwgYiwgZmFsc2UpO1xuICAgICAgICAgICAgaWYgKGIubm9kZU90aGVyQ29uZmlnKSB0aGlzLnZpcnR1YWxGbGF0RWxlbWVudHMucHVzaCh7IGVsZW1lbnQ6IGIubm9kZU90aGVyQ29uZmlnLCBicmFuY2g6IGIsIGlzT3RoZXJDb25maWc6IHRydWUsIHNob3VsZFNob3dBcnJvdzogZmFsc2UsIHBhcmVudElkOiAnYnJhbmNoXycgKyBiSW5kZXggKyAnXycgKyBlbC5pZCB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcbiAgICBzY2FuKGVsZW1lbnRzLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVZpcnR1YWxpemF0aW9uRGlmZigpIHtcbiAgICBjb25zdCB2cCA9IHRoaXMudmlydHVhbFZpZXdwb3J0O1xuICAgIGlmICghdnApIHJldHVybjtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZ0NhbnZhcygpO1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGNvbmZpZz8ubm9kZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFjb250YWluZXIgfHwgIWNvbmZpZykgcmV0dXJuO1xuXG4gICAgY29uc3QgYnVmZmVyID0gMzAwO1xuICAgIGNvbnN0IHZpc2libGVJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIHRoaXMudmlydHVhbEZsYXRFbGVtZW50cy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IGl0ZW0uZWxlbWVudDtcbiAgICAgIGlmIChlbC50cmFuc2xhdGVYID09PSB1bmRlZmluZWQgfHwgZWwudHJhbnNsYXRlWSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICBpZiAoZWwudHJhbnNsYXRlWCArIChlbC5zcGVjaWZpY193aWR0aCB8fCAxNjUpIDwgdnAueCAtIGJ1ZmZlciB8fCBlbC50cmFuc2xhdGVYID4gdnAueCArIHZwLndpZHRoICsgYnVmZmVyIHx8IGVsLnRyYW5zbGF0ZVkgKyAoZWwuc3BlY2lmaWNfaGVpZ2h0IHx8IDQ4KSA8IHZwLnkgLSBidWZmZXIgfHwgZWwudHJhbnNsYXRlWSA+IHZwLnkgKyB2cC5oZWlnaHQgKyBidWZmZXIpIHJldHVybjtcblxuICAgICAgY29uc3QgaWQgPSBTdHJpbmcoaXRlbS5wYXJlbnRJZCkgKyAoaXRlbS5pc090aGVyQ29uZmlnID8gJ19vdGhlcicgOiAnJyk7XG4gICAgICB2aXNpYmxlSWRzLmFkZChpZCk7XG5cbiAgICAgIGlmICghdGhpcy52aXJ0dWFsTm9kZXNNYXAuaGFzKGlkKSkge1xuICAgICAgICBjb25zdCBjb21wb25lbnRUeXBlID0gaXRlbS5pc090aGVyQ29uZmlnID8gY29uZmlnLm5vZGVPdGhlckNvbmZpZ0NvbXBvbmVudFR5cGUgOiBjb25maWcubm9kZUNvbXBvbmVudFR5cGU7XG4gICAgICAgIGlmIChjb21wb25lbnRUeXBlICYmIGNvbmZpZy52aWV3Q29udGFpbmVyUmVmKSB7XG4gICAgICAgICAgY29uc3QgcmVmID0gY29uZmlnLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudFR5cGUpO1xuICAgICAgICAgIHJlZi5zZXRJbnB1dCgnZWxlbWVudCcsIGVsKTtcbiAgICAgICAgICBpZiAoaXRlbS5icmFuY2gpIHJlZi5zZXRJbnB1dCgnYnJhbmNoJywgaXRlbS5icmFuY2gpO1xuICAgICAgICAgIHJlZi5zZXRJbnB1dCgnb3JpZW50YXRpb24nLCB0aGlzLm9yaWVudGF0aW9uKCkpO1xuXG4gICAgICAgICAgY29uc3QgZG9tRWwgPSByZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICBkb21FbC5jbGFzc0xpc3QuYWRkKCdkaWFncmFtLW5vZGUtZHluYW1pYycpO1xuICAgICAgICAgIGFwcGx5RWxlbWVudFN0eWxlKGRvbUVsLCBlbCk7XG4gICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGRvbUVsKTtcblxuICAgICAgICAgIGxldCBhcnJvdzogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKGl0ZW0uc2hvdWxkU2hvd0Fycm93ICYmICFpdGVtLmlzT3RoZXJDb25maWcpIHtcbiAgICAgICAgICAgIGFycm93ID0gdGhpcy5jcmVhdGVBcnJvd0luZGljYXRvcihlbCwgY29udGFpbmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy52aXJ0dWFsTm9kZXNNYXAuc2V0KGlkLCB7IGNvbXBvbmVudDogcmVmLCBhcnJvdyB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2FjaGUgPSB0aGlzLnZpcnR1YWxOb2Rlc01hcC5nZXQoaWQpO1xuICAgICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgICBpZiAoY2FjaGUuY29tcG9uZW50KSBhcHBseUVsZW1lbnRTdHlsZShjYWNoZS5jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgZWwpO1xuICAgICAgICAgIGlmIChjYWNoZS5hcnJvdykge1xuICAgICAgICAgICAgY29uc3QgYXJyb3dTaXplID0gMTY7XG4gICAgICAgICAgICBjb25zdCBub2RlV2lkdGggPSBlbC5zcGVjaWZpY193aWR0aCA/PyAxNjU7XG4gICAgICAgICAgICBjb25zdCBub2RlSGVpZ2h0ID0gZWwuc3BlY2lmaWNfaGVpZ2h0ID8/IDQ4O1xuICAgICAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24oKSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgICAgIGNhY2hlLmFycm93LmlubmVySFRNTCA9IGBcbiAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIiR7YXJyb3dTaXplfVwiIGhlaWdodD1cIiR7YXJyb3dTaXplfVwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTggNEwxNiA4TDggMTJaXCIgZmlsbD1cIiM5Y2EzYWZcIi8+XG4gICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICAgICAgY2FjaGUuYXJyb3cuc3R5bGUubGVmdCA9IGAke2VsLnRyYW5zbGF0ZVggLSBhcnJvd1NpemV9cHhgO1xuICAgICAgICAgICAgICBjYWNoZS5hcnJvdy5zdHlsZS50b3AgPSBgJHtlbC50cmFuc2xhdGVZICsgbm9kZUhlaWdodCAvIDIgLSBhcnJvd1NpemUgLyAyfXB4YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNhY2hlLmFycm93LmlubmVySFRNTCA9IGBcbiAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIiR7YXJyb3dTaXplfVwiIGhlaWdodD1cIiR7YXJyb3dTaXplfVwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTggMTZMNCAxMkgxMkw4IDE2WlwiIGZpbGw9XCIjOWNhM2FmXCIvPlxuICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgIGA7XG4gICAgICAgICAgICAgIGNhY2hlLmFycm93LnN0eWxlLmxlZnQgPSBgJHtlbC50cmFuc2xhdGVYICsgbm9kZVdpZHRoIC8gMiAtIGFycm93U2l6ZSAvIDJ9cHhgO1xuICAgICAgICAgICAgICBjYWNoZS5hcnJvdy5zdHlsZS50b3AgPSBgJHtlbC50cmFuc2xhdGVZIC0gYXJyb3dTaXplfXB4YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMudmlydHVhbEZsYXRCcmFuY2hlcy5mb3JFYWNoKChicmFuY2gsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCB4ID0gYnJhbmNoLnNwZWNpZmljX3N0YXJ0X2JyYW5jaF94O1xuICAgICAgY29uc3QgeSA9IGJyYW5jaC5zcGVjaWZpY19zdGFydF9icmFuY2hfeTtcbiAgICAgIGlmICh4ID09PSB1bmRlZmluZWQgfHwgeSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICBpZiAoeCA8IHZwLnggLSBidWZmZXIgfHwgeCA+IHZwLnggKyB2cC53aWR0aCArIGJ1ZmZlciB8fCB5IDwgdnAueSAtIGJ1ZmZlciB8fCB5ID4gdnAueSArIHZwLmhlaWdodCArIGJ1ZmZlcikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBpZCA9ICdicmFuY2hfJyArIGluZGV4ICsgJ18nICsgTWF0aC5yb3VuZCh4KSArICdfJyArIE1hdGgucm91bmQoeSk7XG4gICAgICB2aXNpYmxlSWRzLmFkZChpZCk7XG5cbiAgICAgIGlmICghdGhpcy52aXJ0dWFsTm9kZXNNYXAuaGFzKGlkKSkge1xuICAgICAgICBjb25zdCBsYWJlbERpdiA9IHRoaXMuY3JlYXRlQnJhbmNoTGFiZWwoYnJhbmNoKTtcbiAgICAgICAgaWYgKGxhYmVsRGl2KSB0aGlzLnZpcnR1YWxOb2Rlc01hcC5zZXQoaWQsIHsgbGFiZWw6IGxhYmVsRGl2IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY2FjaGUgPSB0aGlzLnZpcnR1YWxOb2Rlc01hcC5nZXQoaWQpO1xuICAgICAgICBpZiAoY2FjaGU/LmxhYmVsKSB7XG4gICAgICAgICAgY29uc3QgbGFiZWxEaXYgPSBjYWNoZS5sYWJlbDtcbiAgICAgICAgICBjb25zdCBsYWJlbFJlY3QgPSBsYWJlbERpdi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICBjb25zdCBsYWJlbFcgPSBsYWJlbFJlY3Qud2lkdGggfHwgbGFiZWxEaXYub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgY29uc3QgbGFiZWxIID0gbGFiZWxSZWN0LmhlaWdodCB8fCBsYWJlbERpdi5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24oKSA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICAgICAgbGFiZWxEaXYuc3R5bGUubGVmdCA9IGAke3ggLSBsYWJlbFcgLyAyIC0gNH1weGA7XG4gICAgICAgICAgICBsYWJlbERpdi5zdHlsZS50b3AgPSBgJHt5IC0gbGFiZWxIIC8gMiArIDR9cHhgO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsYWJlbERpdi5zdHlsZS5sZWZ0ID0gYCR7eCArIDR9cHhgO1xuICAgICAgICAgICAgbGFiZWxEaXYuc3R5bGUudG9wID0gYCR7eSAtIGxhYmVsSCAvIDJ9cHhgOyAvLyBjZW50ZXIgb3ZlciB3aXJlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBBcnJheS5mcm9tKHRoaXMudmlydHVhbE5vZGVzTWFwLmVudHJpZXMoKSkuZm9yRWFjaCgoW2lkLCBjYWNoZV0pID0+IHtcbiAgICAgIGlmICghdmlzaWJsZUlkcy5oYXMoaWQpKSB7XG4gICAgICAgIGNhY2hlLmNvbXBvbmVudD8uZGVzdHJveSgpO1xuICAgICAgICBjYWNoZS5hcnJvdz8ucmVtb3ZlKCk7XG4gICAgICAgIGNhY2hlLmxhYmVsPy5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy52aXJ0dWFsTm9kZXNNYXAuZGVsZXRlKGlkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgZWxlbWVudHMgdsOgIGJyYW5jaGVzIG3hu5l0IGPDoWNoIMSR4buHIHF1eVxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJFbGVtZW50c1JlY3Vyc2l2ZWx5KGVsZW1lbnRzOiBBcnJheTxJRGlhZ3JhbUVsZW1lbnQ+LCBpc0ZpcnN0TGV2ZWwgPSB0cnVlLCBicmFuY2g/OiBJRGlhZ3JhbUVsZW1lbnRCcmFuY2gpIHtcbiAgICBlbGVtZW50cy5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGVsZW1lbnQudHJhbnNsYXRlWCAhPT0gdW5kZWZpbmVkICYmIGVsZW1lbnQudHJhbnNsYXRlWSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIE1haW4gbm9kZTogY8OzIGFycm93IG7hur91IGtow7RuZyBwaOG6o2kgZWxlbWVudCDEkeG6p3UgdGnDqm4gY+G7p2EgbGV2ZWwgxJHhuqd1XG4gICAgICAgIGNvbnN0IHNob3VsZFNob3dBcnJvdyA9ICEoaXNGaXJzdExldmVsICYmIGluZGV4ID09PSAwKTtcbiAgICAgICAgdGhpcy5jcmVhdGVOb2RlKGVsZW1lbnQsIGJyYW5jaCwgc2hvdWxkU2hvd0Fycm93LCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbmRlciBub2RlT3RoZXJDb25maWcgbuG6v3UgY8OzIChub2RlcyBwaOG7pSkgLSBLSMOUTkcgY8OzIGFycm93XG4gICAgICBpZiAoZWxlbWVudC5ub2RlT3RoZXJDb25maWcgJiYgZWxlbWVudC5ub2RlT3RoZXJDb25maWcudHJhbnNsYXRlWCAhPT0gdW5kZWZpbmVkICYmIGVsZW1lbnQubm9kZU90aGVyQ29uZmlnLnRyYW5zbGF0ZVkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmNyZWF0ZU5vZGUoZWxlbWVudC5ub2RlT3RoZXJDb25maWcsIGJyYW5jaCwgZmFsc2UsIHRydWUpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZW5kZXIgYnJhbmNoZXMgbuG6v3UgY8OzXG4gICAgICBpZiAoZWxlbWVudC5icmFuY2hlcyAmJiBlbGVtZW50LmJyYW5jaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZWxlbWVudC5icmFuY2hlcy5mb3JFYWNoKChicmFuY2gpID0+IHtcbiAgICAgICAgICBpZiAoYnJhbmNoLmVsZW1lbnRzICYmIGJyYW5jaC5lbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlckVsZW1lbnRzUmVjdXJzaXZlbHkoYnJhbmNoLmVsZW1lbnRzLCBmYWxzZSwgYnJhbmNoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGJyYW5jaC5ub2RlT3RoZXJDb25maWcgJiYgYnJhbmNoLm5vZGVPdGhlckNvbmZpZy50cmFuc2xhdGVYICE9PSB1bmRlZmluZWQgJiYgYnJhbmNoLm5vZGVPdGhlckNvbmZpZy50cmFuc2xhdGVZICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlTm9kZShicmFuY2gubm9kZU90aGVyQ29uZmlnLCBicmFuY2gsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFThuqFvIG3hu5l0IG5vZGUgY29tcG9uZW50IMSR4buZbmdcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHByaXZhdGUgY3JlYXRlTm9kZShlbGVtZW50OiBJRGlhZ3JhbUVsZW1lbnQsIGJyYW5jaDogSURpYWdyYW1FbGVtZW50QnJhbmNoIHwgdW5kZWZpbmVkLCBzaG91bGRTaG93QXJyb3c6IGJvb2xlYW4sIGlzTm9kZU90aGVyQ29uZmlnOiBib29sZWFuKTogQ29tcG9uZW50UmVmPGFueT4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnQ2FudmFzKCk7XG4gICAgaWYgKCFjb25maWc/LnZpZXdDb250YWluZXJSZWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLnVzZVZpcnR1YWxpemF0aW9uVGVtcGxhdGUpIHtcbiAgICAgIGlmIChjb25maWcubm9kZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHNob3VsZFNob3dBcnJvdyAmJiAhaXNOb2RlT3RoZXJDb25maWcpIHtcbiAgICAgICAgICB0aGlzLmNyZWF0ZUFycm93SW5kaWNhdG9yKGVsZW1lbnQsIGNvbmZpZy5ub2Rlc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbXBvbmVudFR5cGUgPSBpc05vZGVPdGhlckNvbmZpZyA/IGNvbmZpZy5ub2RlT3RoZXJDb25maWdDb21wb25lbnRUeXBlIDogY29uZmlnLm5vZGVDb21wb25lbnRUeXBlO1xuXG4gICAgaWYgKCFjb21wb25lbnRUeXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29tcG9uZW50UmVmID0gY29uZmlnLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudFR5cGUpO1xuICAgIGNvbnN0IGVsID0gY29tcG9uZW50UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBjb21wb25lbnRSZWYuc2V0SW5wdXQoJ2VsZW1lbnQnLCBlbGVtZW50KTtcbiAgICBpZiAoYnJhbmNoKSB7XG4gICAgICBjb21wb25lbnRSZWYuc2V0SW5wdXQoJ2JyYW5jaCcsIGJyYW5jaCk7XG4gICAgfVxuICAgIGNvbXBvbmVudFJlZi5zZXRJbnB1dCgnb3JpZW50YXRpb24nLCB0aGlzLm9yaWVudGF0aW9uKCkpO1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2RpYWdyYW0tbm9kZS1keW5hbWljJyk7XG5cbiAgICBhcHBseUVsZW1lbnRTdHlsZShlbCwgZWxlbWVudCk7XG5cbiAgICBpZiAoY29uZmlnLm5vZGVzQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBjb25maWcubm9kZXNDb250YWluZXIubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZChlbCk7XG5cbiAgICAgIGlmIChzaG91bGRTaG93QXJyb3cgJiYgIWlzTm9kZU90aGVyQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlQXJyb3dJbmRpY2F0b3IoZWxlbWVudCwgY29uZmlnLm5vZGVzQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY29tcG9uZW50UmVmcy51cGRhdGUoKHJlZnMpID0+IFsuLi5yZWZzLCBjb21wb25lbnRSZWZdKTsgLy8gTMawdSByZWZlcmVuY2UgxJHhu4MgY2xlYW51cCBzYXVcblxuICAgIHJldHVybiBjb21wb25lbnRSZWY7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgdOG6pXQgY+G6oyBub2RlcyDEkcOjIHThuqFvXG4gICAqL1xuICBjbGVhck5vZGVzKCkge1xuICAgIHRoaXMuY29tcG9uZW50UmVmcygpLmZvckVhY2goKHJlZikgPT4ge1xuICAgICAgcmVmLmRlc3Ryb3koKTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbXBvbmVudFJlZnMuc2V0KFtdKTtcblxuICAgIEFycmF5LmZyb20odGhpcy52aXJ0dWFsTm9kZXNNYXAudmFsdWVzKCkpLmZvckVhY2goKGNhY2hlKSA9PiB7XG4gICAgICBjYWNoZS5jb21wb25lbnQ/LmRlc3Ryb3koKTtcbiAgICAgIGNhY2hlLmFycm93Py5yZW1vdmUoKTtcbiAgICAgIGNhY2hlLmxhYmVsPy5yZW1vdmUoKTtcbiAgICB9KTtcbiAgICB0aGlzLnZpcnR1YWxOb2Rlc01hcC5jbGVhcigpO1xuXG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWdDYW52YXMoKTtcbiAgICBjb25zdCBub2Rlc0NvbnRhaW5lciA9IGNvbmZpZz8ubm9kZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKG5vZGVzQ29udGFpbmVyKSB7XG4gICAgICBpZiAoIWNvbmZpZz8udXNlVmlydHVhbGl6YXRpb25UZW1wbGF0ZSkge1xuICAgICAgICBjb25zdCBkeW5hbWljTm9kZXMgPSBub2Rlc0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZGlhZ3JhbS1ub2RlLWR5bmFtaWMnKTtcbiAgICAgICAgZHluYW1pY05vZGVzLmZvckVhY2goKG5vZGU6IEVsZW1lbnQpID0+IG5vZGUucmVtb3ZlKCkpO1xuICAgICAgfVxuICAgICAgY29uc3QgbGFiZWxzID0gbm9kZXNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLmJyYW5jaC1sYWJlbCcpO1xuICAgICAgbGFiZWxzLmZvckVhY2goKGxhYmVsOiBFbGVtZW50KSA9PiBsYWJlbC5yZW1vdmUoKSk7XG4gICAgICBjb25zdCBhcnJvd3MgPSBub2Rlc0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcubm9kZS1hcnJvdy1pbmRpY2F0b3InKTtcbiAgICAgIGFycm93cy5mb3JFYWNoKChhcnJvdzogRWxlbWVudCkgPT4gYXJyb3cucmVtb3ZlKCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBU4bqhbyBtxalpIHTDqm4gaW5kaWNhdG9yIGNo4buJIGjGsOG7m25nIHbDoG8gbm9kZS5cbiAgICogLSB2ZXJ0aWNhbDogICBtxalpIHTDqm4g4pa8IHBow61hIFRSw4pOIG5vZGUgIChsdeG7k25nIHRyw6puIOKGkiB4deG7kW5nKVxuICAgKiAtIGhvcml6b250YWw6IG3FqWkgdMOqbiDilrogcGjDrWEgVFLDgUkgbm9kZSAgKGx14buTbmcgdHLDoWkg4oaSIHBo4bqjaSlcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQXJyb3dJbmRpY2F0b3IoZWxlbWVudDogSURpYWdyYW1FbGVtZW50LCBjb250YWluZXI6IEhUTUxFbGVtZW50LCApOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGVsZW1lbnQudHJhbnNsYXRlWCA9PT0gdW5kZWZpbmVkIHx8IGVsZW1lbnQudHJhbnNsYXRlWSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGFycm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgYXJyb3cuY2xhc3NOYW1lID0gJ25vZGUtYXJyb3ctaW5kaWNhdG9yJztcbiAgICBhcnJvdy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgYXJyb3cuc3R5bGUuekluZGV4ID0gJzEnO1xuICAgIGFycm93LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG5cbiAgICBjb25zdCBhcnJvd1NpemUgPSAxNjtcbiAgICBjb25zdCBub2RlV2lkdGggPSBlbGVtZW50LnNwZWNpZmljX3dpZHRoID8/IDA7XG4gICAgY29uc3Qgbm9kZUhlaWdodCA9IGVsZW1lbnQuc3BlY2lmaWNfaGVpZ2h0ID8/IDA7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbigpID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIC8vIE3FqWkgdMOqbiDilrog4bufIGLDqm4gVFLDgUkgbm9kZSwgY8SDbiBnaeG7r2EgdGhlbyBjaGnhu4F1IGNhb1xuICAgICAgYXJyb3cuaW5uZXJIVE1MID0gYFxuICAgICAgICA8c3ZnIHdpZHRoPVwiJHthcnJvd1NpemV9XCIgaGVpZ2h0PVwiJHthcnJvd1NpemV9XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgIDxwYXRoIGQ9XCJNOCA0TDE2IDhMOCAxMlpcIiBmaWxsPVwiIzljYTNhZlwiLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICBgO1xuICAgICAgYXJyb3cuc3R5bGUubGVmdCA9IGAke2VsZW1lbnQudHJhbnNsYXRlWCAtIGFycm93U2l6ZX1weGA7XG4gICAgICBhcnJvdy5zdHlsZS50b3AgPSBgJHtlbGVtZW50LnRyYW5zbGF0ZVkgKyBub2RlSGVpZ2h0IC8gMiAtIGFycm93U2l6ZSAvIDJ9cHhgO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBNxalpIHTDqm4g4pa8IOG7nyBwaMOtYSBUUsOKTiBub2RlLCBjxINuIGdp4buvYSB0aGVvIGNoaeG7gXUgcuG7mW5nXG4gICAgICBhcnJvdy5pbm5lckhUTUwgPSBgXG4gICAgICAgIDxzdmcgd2lkdGg9XCIke2Fycm93U2l6ZX1cIiBoZWlnaHQ9XCIke2Fycm93U2l6ZX1cIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGggZD1cIk04IDE2TDQgMTJIMTJMOCAxNlpcIiBmaWxsPVwiIzljYTNhZlwiLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICBgO1xuICAgICAgYXJyb3cuc3R5bGUubGVmdCA9IGAke2VsZW1lbnQudHJhbnNsYXRlWCArIG5vZGVXaWR0aCAvIDIgLSBhcnJvd1NpemUgLyAyfXB4YDtcbiAgICAgIGFycm93LnN0eWxlLnRvcCA9IGAke2VsZW1lbnQudHJhbnNsYXRlWSAtIGFycm93U2l6ZX1weGA7XG4gICAgfVxuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGFycm93KTtcbiAgICByZXR1cm4gYXJyb3c7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIGJyYW5jaCBsYWJlbHMgKHRleHQgYW5ub3RhdGlvbnMgb24gYnJhbmNoZXMpXG4gICAqL1xuICBwcml2YXRlIHJlbmRlckJyYW5jaExhYmVscyhlbGVtZW50czogQXJyYXk8SURpYWdyYW1FbGVtZW50PiwgKSB7XG4gICAgY29uc3Qgc3ZnQ29udGFpbmVyID0gdGhpcy5jb25maWdDYW52YXMoKT8uc3ZnQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghc3ZnQ29udGFpbmVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGVsZW1lbnQuYnJhbmNoZXMgJiYgZWxlbWVudC5icmFuY2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVsZW1lbnQuYnJhbmNoZXMuZm9yRWFjaCgoYnJhbmNoLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGlmIChicmFuY2guc3BlY2lmaWNfc3RhcnRfYnJhbmNoX3ggIT09IHVuZGVmaW5lZCAmJiBicmFuY2guc3BlY2lmaWNfc3RhcnRfYnJhbmNoX3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKCFicmFuY2gubGFiZWwpIHtcbiAgICAgICAgICAgICAgYnJhbmNoLmxhYmVsID0gYE5ow6FuaCAke2luZGV4ICsgMX1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jcmVhdGVCcmFuY2hMYWJlbChicmFuY2gpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChicmFuY2guZWxlbWVudHMgJiYgYnJhbmNoLmVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyQnJhbmNoTGFiZWxzKGJyYW5jaC5lbGVtZW50cyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQnJhbmNoTGFiZWwoYnJhbmNoOiBJRGlhZ3JhbUVsZW1lbnRCcmFuY2gsICk6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZ0NhbnZhcygpO1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGNvbmZpZz8ubm9kZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWxEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBsYWJlbERpdi5jbGFzc05hbWUgPSAnYnJhbmNoLWxhYmVsJztcbiAgICBsYWJlbERpdi50ZXh0Q29udGVudCA9IGJyYW5jaC5sYWJlbCB8fCAnJztcblxuICAgIGxhYmVsRGl2LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBsYWJlbERpdi5zdHlsZS5wYWRkaW5nID0gJzJweCA3cHgnO1xuICAgIGxhYmVsRGl2LnN0eWxlLmJvcmRlclJhZGl1cyA9ICcxMHB4JztcbiAgICBsYWJlbERpdi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBicmFuY2gubGFiZWxCZ0NvbG9yIHx8ICcjZjNmNGY2JztcbiAgICBsYWJlbERpdi5zdHlsZS5mb250U2l6ZSA9ICcxMXB4JztcbiAgICBsYWJlbERpdi5zdHlsZS5mb250RmFtaWx5ID0gJ3N5c3RlbS11aSwgLWFwcGxlLXN5c3RlbSwgc2Fucy1zZXJpZic7XG4gICAgbGFiZWxEaXYuc3R5bGUuY29sb3IgPSAnIzM3NDE1MSc7XG4gICAgbGFiZWxEaXYuc3R5bGUud2hpdGVTcGFjZSA9ICdub3dyYXAnO1xuICAgIGxhYmVsRGl2LnN0eWxlLnpJbmRleCA9ICcyJztcbiAgICBsYWJlbERpdi5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsRGl2KTtcblxuICAgIGNvbnN0IHN0YXJ0WCA9IGJyYW5jaC5zcGVjaWZpY19zdGFydF9icmFuY2hfeCA/PyAwO1xuICAgIGNvbnN0IHN0YXJ0WSA9IGJyYW5jaC5zcGVjaWZpY19zdGFydF9icmFuY2hfeSA/PyAwO1xuICAgIGNvbnN0IGxhYmVsVyA9IGxhYmVsRGl2Lm9mZnNldFdpZHRoO1xuICAgIGNvbnN0IGxhYmVsSCA9IGxhYmVsRGl2Lm9mZnNldEhlaWdodCB8fCAxODtcblxuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uKCkgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgLyoqXG4gICAgICAgKiBIb3Jpem9udGFsOiBsYWJlbCBu4bqxbSBUUsOKTiDEkcaw4budbmcgbGluZSBu4bqxbSBuZ2FuZy5cbiAgICAgICAqIHNwZWNpZmljX3N0YXJ0X2JyYW5jaCA9IMSRaeG7g20gYuG6r3QgxJHhuqd1IMSRb+G6oW4gdGjhurNuZyBuZ2FuZyDEkeG6v24gZWxlbWVudC5cbiAgICAgICAqIMSQ4bq3dCBsYWJlbCB04buLbmggdGnhur9uIHNhbmcgcGjhuqNpIDhweCB04burIG5nb+G6t3QgbmjDoW5oLCB2w6AgY8SDbiBnaeG7r2EgZMOieS5cbiAgICAgICAqL1xuICAgICAgbGFiZWxEaXYuc3R5bGUubGVmdCA9IGAke3N0YXJ0WCArIDR9cHhgO1xuICAgICAgbGFiZWxEaXYuc3R5bGUudG9wID0gYCR7c3RhcnRZIC0gbGFiZWxIIC8gMn1weGA7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qKlxuICAgICAgICogVmVydGljYWw6IGxhYmVsIG7hurFtIELDik4gVFLDgUkgxJHGsOG7nW5nIG5nYW5nLCBjxINuIGdp4buvYSB0aGVvIFkuXG4gICAgICAgKiBzcGVjaWZpY19zdGFydF9icmFuY2ggPSDEkWnhu4NtIMSR4bqndSDEkW/huqFuIHRo4bqzbmcgxJHhur9uIGVsZW1lbnQgKHNhdSBjdXJ2ZSkuXG4gICAgICAgKi9cbiAgICAgIGxhYmVsRGl2LnN0eWxlLmxlZnQgPSBgJHtzdGFydFggLSBsYWJlbFcgLyAyIC0gNH1weGA7XG4gICAgICBsYWJlbERpdi5zdHlsZS50b3AgPSBgJHtzdGFydFkgLSBsYWJlbEggLyAyICsgNH1weGA7XG4gICAgfVxuICAgIHJldHVybiBsYWJlbERpdjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgZOG6pXUgXCIrXCIgdOG6oWkgbeG7l2kgduG7iyB0csOtIGPDsyB0aOG7gyB0aOG6oyBlbGVtZW50IHThu6sgc2lkZWJhci5cbiAgICogU2VydmljZSB04buxIHThuqFvIERPTSBlbGVtZW50cyB2w6AgaW5qZWN0IHbDoG8gbm9kZXNDb250YWluZXIuXG4gICAqIEBwYXJhbSBmbGF0RWxlbWVudHMgRGFuaCBzw6FjaCBmbGF0IGVsZW1lbnRzIMSRw6MgdMOtbmggdG/DoW4gduG7iyB0csOtXG4gICAqIEBwYXJhbSBvbkRyb3AgQ2FsbGJhY2sga2hpIG5nxrDhu51pIGTDuW5nIHRo4bqjIGVsZW1lbnQgdsOgbyBt4buZdCBcIitcIlxuICAgKiBAcGFyYW0gY2FuRHJvcEZuICh0w7l5IGNo4buNbikgRnVuY3Rpb24ga2nhu4NtIHRyYSDEkWnhu4F1IGtp4buHbiBoaeG7g24gdGjhu4sgZHJvcCB6b25lLlxuICAgKiBgYGBcbiAgICovXG4gIHJlbmRlckRyb3Bab25lcyhcbiAgICBmbGF0RWxlbWVudHM6IElEaWFncmFtRWxlbWVudFtdLFxuICAgIG9uRHJvcDogKGVsZW1lbnQ6IElEaWFncmFtRWxlbWVudCwgYnJhbmNoOiBJRGlhZ3JhbUVsZW1lbnRCcmFuY2ggfCB1bmRlZmluZWQsIGRyYWdEYXRhOiBzdHJpbmcpID0+IHZvaWQsXG4gICAgY2FuRHJvcEZuOiBURHJvcFpvbmVDYW5Ecm9wRm4sXG4gICAgcnVsZUNvbm5lY3RhYmxlRWxlbWVudHM6IEFycmF5PElSdWxlQ29ubmVjdGFibGU+XG4gICk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJEcm9wWm9uZXMoKTtcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbmZpZ0NhbnZhcygpPy5ub2Rlc0NvbnRhaW5lcj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuO1xuXG4gICAgZmxhdEVsZW1lbnRzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBpZiAoZWwuY29kZSA9PT0gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5UWVBFX0VMRU1FTlRfRVhJVCkgcmV0dXJuO1xuXG4gICAgICBpZiAoZWwuZWxlbWVudF90eXBlID09PSBjYW52YXNDb25maWdSZWFkb25seSgpLlRZUEVfRUxFTUVOVF9XT1JLRkxPVykge1xuICAgICAgICBlbC5icmFuY2hlcz8uZm9yRWFjaCgoYnJhbmNoKSA9PiB7XG4gICAgICAgICAgaWYgKGNhbkRyb3BGbih1bmRlZmluZWQsIGVsLCBicmFuY2gsIHJ1bGVDb25uZWN0YWJsZUVsZW1lbnRzKSkgcmV0dXJuO1xuXG4gICAgICAgICAgY29uc3QgdG9wID0gdGhpcy5vcmllbnRhdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLmNhbGNEcm9wWm9uZVRvcEJyYW5jaEgoZWwsIGJyYW5jaCkgOiB0aGlzLmNhbGNEcm9wWm9uZVRvcEJyYW5jaChlbCwgYnJhbmNoKTtcbiAgICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy5vcmllbnRhdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLmNhbGNEcm9wWm9uZUxlZnRCcmFuY2hIKGVsLCBicmFuY2gpIDogdGhpcy5jYWxjRHJvcFpvbmVMZWZ0QnJhbmNoKGVsLCBicmFuY2gpO1xuICAgICAgICAgIHRoaXMuY3JlYXRlRHJvcFpvbmVFbChjb250YWluZXIsIHRvcCwgbGVmdCwgZWwsIGJyYW5jaCwgb25Ecm9wKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIWNhbkRyb3BGbih1bmRlZmluZWQsIGVsLCB1bmRlZmluZWQsIHJ1bGVDb25uZWN0YWJsZUVsZW1lbnRzKSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHRvcCA9IHRoaXMub3JpZW50YXRpb24oKSA9PT0gJ2hvcml6b250YWwnID8gdGhpcy5jYWxjRHJvcFpvbmVUb3BOb2RlSChlbCkgOiB0aGlzLmNhbGNEcm9wWm9uZVRvcE5vZGUoZWwpO1xuICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy5vcmllbnRhdGlvbigpID09PSAnaG9yaXpvbnRhbCcgPyB0aGlzLmNhbGNEcm9wWm9uZUxlZnROb2RlSChlbCkgOiB0aGlzLmNhbGNEcm9wWm9uZUxlZnROb2RlKGVsKTtcbiAgICAgICAgdGhpcy5jcmVhdGVEcm9wWm9uZUVsKGNvbnRhaW5lciwgdG9wLCBsZWZ0LCBlbCwgdW5kZWZpbmVkLCBvbkRyb3ApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFjDs2EgdOG6pXQgY+G6oyBkcm9wIHpvbmUgXCIrXCIga2jhu49pIERPTSAqL1xuICBjbGVhckRyb3Bab25lcygpOiB2b2lkIHtcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbmZpZ0NhbnZhcygpPy5ub2Rlc0NvbnRhaW5lcj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIWNvbnRhaW5lcikgcmV0dXJuO1xuICAgIGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZGlhZ3JhbS1kcm9wLXpvbmUnKS5mb3JFYWNoKChlbCkgPT4gZWwucmVtb3ZlKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEcm9wWm9uZUVsKFxuICAgIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsXG4gICAgdG9wOiBudW1iZXIsXG4gICAgbGVmdDogbnVtYmVyLFxuICAgIGVsZW1lbnQ6IElEaWFncmFtRWxlbWVudCxcbiAgICBicmFuY2g6IElEaWFncmFtRWxlbWVudEJyYW5jaCB8IHVuZGVmaW5lZCxcbiAgICBvbkRyb3A6IChlbGVtZW50OiBJRGlhZ3JhbUVsZW1lbnQsIGJyYW5jaDogSURpYWdyYW1FbGVtZW50QnJhbmNoIHwgdW5kZWZpbmVkLCBkcmFnRGF0YTogc3RyaW5nKSA9PiB2b2lkXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGluZGljYXRvclN0eWxlOiBJRHJvcFpvbmVJbmRpY2F0b3JTdHlsZSB8IHVuZGVmaW5lZCA9IHRoaXMuY29uZmlnQ2FudmFzKCk/LmRyb3Bab25lU3R5bGU7XG4gICAgY29uc3QgUkVDVF9XID0gZWxlbWVudC5zcGVjaWZpY193aWR0aCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLldJRFRIX0VMRU1FTlRfREVGQVVMVDtcbiAgICBjb25zdCBSRUNUX0ggPSBlbGVtZW50LnNwZWNpZmljX2hlaWdodCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLkhFSUdIVF9FTEVNRU5UX0RFRkFVTFQ7XG5cbiAgICAvLyBUw6JtIGPhu6dhIG7DunQgdHLDsm5cbiAgICBjb25zdCBjZW50ZXJYID0gbGVmdCArIGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVIgLyAyO1xuICAgIGNvbnN0IGNlbnRlclkgPSB0b3AgKyBjYW52YXNDb25maWdSZWFkb25seSgpLkFERF9JQ09OX0RJQU1FVEVSIC8gMjtcblxuICAgIC8vIEhpdCB6b25lIHbDtCBow6xuaDogcuG7mW5nIGjGoW4gcmVjdGFuZ2xlIG3hu5l0IGtob+G6o24gcGFkZGluZyDEkeG7gyBi4bqvdCBkcmFnIHPhu5ttIGjGoW5cbiAgICBjb25zdCBISVRfUEFEID0gMjA7XG4gICAgY29uc3QgSElUX1cgPSBSRUNUX1cgKyBISVRfUEFEICogMjtcbiAgICBjb25zdCBISVRfSCA9IFJFQ1RfSCArIEhJVF9QQUQgKiAyO1xuICAgIGNvbnN0IGhpdExlZnQgPSBjZW50ZXJYIC0gSElUX1cgLyAyO1xuICAgIGNvbnN0IGhpdFRvcCA9IGNlbnRlclkgLSBISVRfSCAvIDI7XG5cbiAgICAvLyDilIDilIAgSGl0IHpvbmUgKHdyYXBwZXIgdsO0IGjDrG5oLCB2w7luZyBuaOG6rW4gZHJhZyBy4buZbmcpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIGNvbnN0IGhpdFpvbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBoaXRab25lLmNsYXNzTmFtZSA9ICdkaWFncmFtLWRyb3Atem9uZSc7XG4gICAgaGl0Wm9uZS5zdHlsZS5jc3NUZXh0ID0gYFxuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgdG9wOiAke2hpdFRvcH1weDtcbiAgICAgIGxlZnQ6ICR7aGl0TGVmdH1weDtcbiAgICAgIHotaW5kZXg6IDk7XG4gICAgICB3aWR0aDogJHtISVRfV31weDtcbiAgICAgIGhlaWdodDogJHtISVRfSH1weDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBgO1xuXG4gICAgLy8g4pSA4pSAIEluZGljYXRvciAoY29uIGLDqm4gdHJvbmcsIHBo4bqnbiBoaeG7g24gdGjhu4spIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgIGNvbnN0IGluZGljYXRvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGluZGljYXRvci5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnOyAvLyB0csOhbmggdHJhbmggY2jhuqVwIGV2ZW50IHbhu5tpIGhpdFpvbmVcblxuICAgIC8vIFbhu4sgdHLDrSBkb3QgdHJvbmcgaGl0Wm9uZSAoY8SDbiBnaeG7r2EgaGl0Wm9uZSlcbiAgICBjb25zdCBkb3RPZmZzZXRMZWZ0ID0gSElUX1cgLyAyIC0gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5BRERfSUNPTl9ESUFNRVRFUiAvIDI7XG4gICAgY29uc3QgZG90T2Zmc2V0VG9wID0gSElUX0ggLyAyIC0gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5BRERfSUNPTl9ESUFNRVRFUiAvIDI7XG5cbiAgICAvLyBW4buLIHRyw60gcmVjdGFuZ2xlIHRyb25nIGhpdFpvbmUgKGPEg24gZ2nhu69hIGhpdFpvbmUpXG4gICAgY29uc3QgcmVjdE9mZnNldExlZnQgPSBISVRfUEFEO1xuICAgIGNvbnN0IHJlY3RPZmZzZXRUb3AgPSBISVRfSCAvIDIgLSBSRUNUX0ggLyAyO1xuXG4gICAgY29uc3QgYXBwbHlEb3RTdHlsZSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHMgPSBpbmRpY2F0b3JTdHlsZTtcbiAgICAgIGNvbnN0IHNpemUgPSBjYW52YXNDb25maWdSZWFkb25seSgpLkFERF9JQ09OX0RJQU1FVEVSO1xuICAgICAgY29uc3QgYmcgPSBzPy5iYWNrZ3JvdW5kQ29sb3IgPz8gJyMzYjgyZjYnO1xuICAgICAgY29uc3QgaWNvbkNvbG9yID0gcz8uaWNvbkNvbG9yID8/ICcjZmZmZmZmJztcbiAgICAgIGNvbnN0IG9wYWNpdHkgPSBzPy5vcGFjaXR5ID8/IDAuOTU7XG4gICAgICBjb25zdCBib3JkZXJSYWRpdXMgPSBzPy5ib3JkZXJSYWRpdXMgPz8gJzUwJSc7XG5cbiAgICAgIHNldFN0eWxlc0VsZW1lbnQoaW5kaWNhdG9yLCB7XG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICB0b3A6IGAke2RvdE9mZnNldFRvcH1weGAsXG4gICAgICAgIGxlZnQ6IGAke2RvdE9mZnNldExlZnR9cHhgLFxuICAgICAgICB3aWR0aDogYCR7c2l6ZX1weGAsXG4gICAgICAgIGhlaWdodDogYCR7c2l6ZX1weGAsXG4gICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInLFxuICAgICAgICB0cmFuc2l0aW9uOiAnb3BhY2l0eSAwLjE1cyBlYXNlJyxcbiAgICAgICAgYm9yZGVyOiAnbm9uZScsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHM/LnJlbmRlckluZGljYXRvcikge1xuICAgICAgICBpbmRpY2F0b3IuaW5uZXJIVE1MID0gcy5yZW5kZXJJbmRpY2F0b3Ioc2l6ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmRpY2F0b3IuaW5uZXJIVE1MID0gYFxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJcbiAgICAgICAgICAgIHdpZHRoOiAke3NpemV9cHg7XG4gICAgICAgICAgICBoZWlnaHQ6ICR7c2l6ZX1weDtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICR7Ymd9O1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogJHtib3JkZXJSYWRpdXN9O1xuICAgICAgICAgICAgb3BhY2l0eTogJHtvcGFjaXR5fTtcbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgICAgICBcIj48aSBjbGFzcz1cImxpYnMtdWktaWNvbi1hZGQgYmVmb3JlOnRleHQtWyR7aWNvbkNvbG9yfV1cIj48L2k+PC9kaXY+XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGFwcGx5UmVjdFN0eWxlID0gKCkgPT4ge1xuICAgICAgY29uc3QgcyA9IGluZGljYXRvclN0eWxlO1xuICAgICAgY29uc3QgaG92ZXJCZyA9IHM/LmhvdmVyQmFja2dyb3VuZENvbG9yID8/ICcjZWVmNGZmJztcbiAgICAgIGNvbnN0IGhvdmVyQm9yZGVyID0gcz8uaG92ZXJCb3JkZXJDb2xvciA/PyAncmdiYSg1OSwgMTMwLCAyNDYsIDAuNyknO1xuICAgICAgY29uc3QgaG92ZXJCb3JkZXJTdHlsZSA9IHM/LmhvdmVyQm9yZGVyU3R5bGUgPz8gJ2Rhc2hlZCc7XG4gICAgICBjb25zdCBob3ZlclJhZGl1cyA9IHM/LmhvdmVyQm9yZGVyUmFkaXVzID8/IDEwO1xuXG4gICAgICBzZXRTdHlsZXNFbGVtZW50KGluZGljYXRvciwge1xuICAgICAgICB0b3A6IGAke3JlY3RPZmZzZXRUb3B9cHhgLFxuICAgICAgICBsZWZ0OiBgJHtyZWN0T2Zmc2V0TGVmdH1weGAsXG4gICAgICAgIHdpZHRoOiBgJHtSRUNUX1d9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke1JFQ1RfSH1weGAsXG4gICAgICAgIGJvcmRlclJhZGl1czogYCR7aG92ZXJSYWRpdXN9cHhgLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGhvdmVyQmcsXG4gICAgICAgIGJvcmRlcjogYDJweCAke2hvdmVyQm9yZGVyU3R5bGV9ICR7aG92ZXJCb3JkZXJ9YCxcbiAgICAgICAgdHJhbnNpdGlvbjogJ2FsbCAwLjJzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSknLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE7hur91IGPDsyBow6BtIHJlbmRlciDEkeG7mW5nIGNobyB0cuG6oW5nIHRow6FpIGhvdmVyIOKAlCBn4buNaSBuw7NcbiAgICAgIGluZGljYXRvci5pbm5lckhUTUwgPSBzPy5yZW5kZXJIb3ZlckluZGljYXRvciA/IHMucmVuZGVySG92ZXJJbmRpY2F0b3IoKSA6ICcnO1xuICAgIH07XG5cbiAgICBhcHBseURvdFN0eWxlKCk7XG4gICAgaGl0Wm9uZS5hcHBlbmRDaGlsZChpbmRpY2F0b3IpO1xuXG4gICAgaGl0Wm9uZS5hZGRFdmVudExpc3RlbmVyKCdkcmFnZW50ZXInLCAoZTogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBhcHBseVJlY3RTdHlsZSgpO1xuICAgIH0pO1xuXG4gICAgaGl0Wm9uZS5hZGRFdmVudExpc3RlbmVyKCdkcmFnb3ZlcicsIChlOiBEcmFnRXZlbnQpID0+IHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGlmIChlLmRhdGFUcmFuc2ZlcikgZS5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdjb3B5JztcbiAgICB9KTtcblxuICAgIGhpdFpvbmUuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ2xlYXZlJywgKGU6IERyYWdFdmVudCkgPT4ge1xuICAgICAgaWYgKCFoaXRab25lLmNvbnRhaW5zKGUucmVsYXRlZFRhcmdldCBhcyBOb2RlKSkge1xuICAgICAgICBhcHBseURvdFN0eWxlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBoaXRab25lLmFkZEV2ZW50TGlzdGVuZXIoJ2Ryb3AnLCAoZTogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgY29uc3QgcmF3ID0gZS5kYXRhVHJhbnNmZXI/LmdldERhdGEoJ2FwcGxpY2F0aW9uL2pzb24nKSA/PyAnJztcbiAgICAgIG9uRHJvcChlbGVtZW50LCBicmFuY2gsIHJhdyk7XG4gICAgfSk7XG5cbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoaGl0Wm9uZSk7XG4gIH1cblxuICAvLyDilIDilIAgVmVydGljYWwgZHJvcCB6b25lIGhlbHBlcnMgKGV4aXN0aW5nKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVUb3BCcmFuY2goZWw6IElEaWFncmFtRWxlbWVudCwgYnJhbmNoOiBJRGlhZ3JhbUVsZW1lbnRCcmFuY2gpOiBudW1iZXIge1xuICAgIGNvbnN0IG9jID0gYnJhbmNoLm5vZGVPdGhlckNvbmZpZztcbiAgICBpZiAob2MpIHJldHVybiAob2Muc3BlY2lmaWNfeSA/PyAwKSArIChvYy5zcGVjaWZpY19oZWlnaHQgPz8gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5FTEVNRU5UX1dBSVRfREVGQVVMVCkgKyAxMDtcbiAgICByZXR1cm4gKGJyYW5jaC5zcGVjaWZpY19zdGFydF9icmFuY2hfeSA/PyAwKSArIDMwO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVMZWZ0QnJhbmNoKGVsOiBJRGlhZ3JhbUVsZW1lbnQsIGJyYW5jaDogSURpYWdyYW1FbGVtZW50QnJhbmNoKTogbnVtYmVyIHtcbiAgICBjb25zdCBmaXJzdEVsID0gYnJhbmNoLmVsZW1lbnRzPy5bMF07XG4gICAgaWYgKGZpcnN0RWw/LnRyYW5zbGF0ZVggIT09IHVuZGVmaW5lZCkgcmV0dXJuIGZpcnN0RWwudHJhbnNsYXRlWCArIChmaXJzdEVsLnNwZWNpZmljX3dpZHRoID8/IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuV0lEVEhfRUxFTUVOVF9ERUZBVUxUKSAvIDIgLSBjYW52YXNDb25maWdSZWFkb25seSgpLkFERF9JQ09OX0RJQU1FVEVSIC8gMjtcbiAgICByZXR1cm4gKGVsLnRyYW5zbGF0ZVggPz8gMCkgKyAoZWwuc3BlY2lmaWNfd2lkdGggPz8gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5XSURUSF9FTEVNRU5UX0RFRkFVTFQpIC8gMiAtIGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVIgLyAyO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVUb3BOb2RlKGVsOiBJRGlhZ3JhbUVsZW1lbnQpOiBudW1iZXIge1xuICAgIGNvbnN0IG9jID0gZWwubm9kZU90aGVyQ29uZmlnO1xuICAgIGlmIChvYykgcmV0dXJuIChvYy5zcGVjaWZpY195ID8/IDApICsgKG9jLnNwZWNpZmljX2hlaWdodCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLkVMRU1FTlRfV0FJVF9ERUZBVUxUKSArIDEwO1xuICAgIHJldHVybiAoZWwudHJhbnNsYXRlWSA/PyAwKSArIChlbC5zcGVjaWZpY19oZWlnaHQgPz8gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5IRUlHSFRfRUxFTUVOVF9ERUZBVUxUKSArIDEwO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVMZWZ0Tm9kZShlbDogSURpYWdyYW1FbGVtZW50KTogbnVtYmVyIHtcbiAgICByZXR1cm4gKGVsLnRyYW5zbGF0ZVggPz8gMCkgKyAoZWwuc3BlY2lmaWNfd2lkdGggPz8gY2FudmFzQ29uZmlnUmVhZG9ubHkoKS5XSURUSF9FTEVNRU5UX0RFRkFVTFQpIC8gMiAtIGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVIgLyAyO1xuICB9XG5cbiAgLy8g4pSA4pSAIEhvcml6b250YWwgZHJvcCB6b25lIGhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8qKlxuICAgKiBIb3Jpem9udGFsIG5vZGU6IFwiK1wiIG7hurFtIGdp4buvYSDEkcaw4budbmcgbGluZSBu4buRaSAyIG5vZGUg4oCUIGPEg24gZ2nhu69hIFkgY+G7p2EgZWxlbWVudC5cbiAgICovXG4gIHByaXZhdGUgY2FsY0Ryb3Bab25lVG9wTm9kZUgoZWw6IElEaWFncmFtRWxlbWVudCk6IG51bWJlciB7XG4gICAgY29uc3QgRCA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVI7XG4gICAgY29uc3QgY2VudGVyWSA9IChlbC50cmFuc2xhdGVZID8/IDApICsgKGVsLnNwZWNpZmljX2hlaWdodCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLkhFSUdIVF9FTEVNRU5UX0RFRkFVTFQpIC8gMjtcbiAgICByZXR1cm4gY2VudGVyWSAtIEQgLyAyO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVMZWZ0Tm9kZUgoZWw6IElEaWFncmFtRWxlbWVudCk6IG51bWJlciB7XG4gICAgY29uc3QgRCA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVI7XG4gICAgY29uc3QgTSA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuRUxFTUVOVF9NQVJHSU5fREVGQVVMVDtcbiAgICBjb25zdCBvYyA9IGVsLm5vZGVPdGhlckNvbmZpZztcblxuICAgIGlmIChvYykge1xuICAgICAgY29uc3QgcmlnaHQgPSAob2Muc3BlY2lmaWNfeCA/PyAwKSArIChvYy5zcGVjaWZpY193aWR0aCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLkVMRU1FTlRfV0FJVF9ERUZBVUxUKTtcbiAgICAgIHJldHVybiByaWdodCArIE0gLyAyIC0gRCAvIDI7XG4gICAgfVxuXG4gICAgY29uc3QgcmlnaHQgPSAoZWwudHJhbnNsYXRlWCA/PyAwKSArIChlbC5zcGVjaWZpY193aWR0aCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLldJRFRIX0VMRU1FTlRfREVGQVVMVCk7XG4gICAgLy8gTWlkcG9pbnQgY+G7p2Ega2hv4bqjbmcgdHLhu5FuZyBnaeG7r2Egbm9kZSB2w6Agbm9kZSB0aeG6v3AgdGhlbyAoZ2FwID0gRUxFTUVOVF9NQVJHSU5fREVGQVVMVClcbiAgICByZXR1cm4gcmlnaHQgKyBNIC8gMiAtIEQgLyAyO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvcml6b250YWwgYnJhbmNoOiBcIitcIiBu4bqxbSBjxINuIGdp4buvYSBZIGPhu6dhIGJyYW5jaCBsaW5lLCBzYXUgcGjhuqduIHThu60gY3Xhu5FpIHRyb25nIG5ow6FuaC5cbiAgICovXG4gIHByaXZhdGUgY2FsY0Ryb3Bab25lVG9wQnJhbmNoSChlbDogSURpYWdyYW1FbGVtZW50LCBicmFuY2g6IElEaWFncmFtRWxlbWVudEJyYW5jaCk6IG51bWJlciB7XG4gICAgY29uc3QgRCA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVI7XG4gICAgLy8gc3BlY2lmaWNfc3RhcnRfYnJhbmNoX3kgPSB0w6JtIFkgY+G7p2EgxJHGsOG7nW5nIG5ow6FuaFxuICAgIGNvbnN0IGNlbnRlclkgPSBicmFuY2guc3BlY2lmaWNfc3RhcnRfYnJhbmNoX3kgPz8gMDtcbiAgICByZXR1cm4gY2VudGVyWSAtIEQgLyAyO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjRHJvcFpvbmVMZWZ0QnJhbmNoSChlbDogSURpYWdyYW1FbGVtZW50LCBicmFuY2g6IElEaWFncmFtRWxlbWVudEJyYW5jaCk6IG51bWJlciB7XG4gICAgY29uc3QgRCA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuQUREX0lDT05fRElBTUVURVI7XG4gICAgY29uc3QgTSA9IGNhbnZhc0NvbmZpZ1JlYWRvbmx5KCkuRUxFTUVOVF9NQVJHSU5fREVGQVVMVDtcblxuICAgIC8vIFNhdSBub2RlT3RoZXJDb25maWcgY+G7p2EgbmjDoW5oIChj4buVIG5ow6FuaClcbiAgICBjb25zdCBvYyA9IGJyYW5jaC5ub2RlT3RoZXJDb25maWc7XG4gICAgaWYgKG9jPy5zcGVjaWZpY194ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAob2Muc3BlY2lmaWNfeCA/PyAwKSArIChvYy5zcGVjaWZpY193aWR0aCA/PyBjYW52YXNDb25maWdSZWFkb25seSgpLkVMRU1FTlRfV0FJVF9ERUZBVUxUKSArIE0gLyAyIC0gRCAvIDI7XG4gICAgfVxuICAgIC8vIE7hur91IG5ow6FuaCBraMO0bmcgY8OzIG5vZGVPdGhlckNvbmZpZzogxJHhurd0IHNhdSDEkWnhu4NtIHLhur0gbmjDoW5oXG4gICAgcmV0dXJuIChicmFuY2guc3BlY2lmaWNfc3RhcnRfYnJhbmNoX3ggPz8gMCkgKyBNIC8gMiAtIEQgLyAyO1xuICB9XG59XG4iXX0=
|