@libs-ui/components-draw-line 0.2.61
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 +3 -0
- package/draw-line.directive.d.ts +54 -0
- package/draw-line.interface.d.ts +119 -0
- package/esm2022/draw-line.directive.mjs +595 -0
- package/esm2022/draw-line.interface.mjs +2 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/libs-ui-components-draw-line.mjs +5 -0
- package/esm2022/util/calculator-branch.util.mjs +27 -0
- package/esm2022/util/calculator-diretion-element.until.mjs +339 -0
- package/esm2022/util/connect-navigation-new-element.util.mjs +381 -0
- package/esm2022/util/line-connect-bottom-left.until.mjs +155 -0
- package/fesm2022/libs-ui-components-draw-line.mjs +1493 -0
- package/fesm2022/libs-ui-components-draw-line.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/package.json +25 -0
- package/util/calculator-branch.util.d.ts +9 -0
- package/util/calculator-diretion-element.until.d.ts +60 -0
- package/util/connect-navigation-new-element.util.d.ts +17 -0
- package/util/line-connect-bottom-left.until.d.ts +5 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, Input, NgZone, Output, inject } from "@angular/core";
|
|
2
|
+
import { checkMouseOverInContainer, cloneDeep, get } from "@libs-ui/utils";
|
|
3
|
+
import { Subject, fromEvent, mergeMap, startWith, takeUntil, tap } from "rxjs";
|
|
4
|
+
import { MoCanvasConnectNavigationNewElementUtil } from "./util/connect-navigation-new-element.util";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class LibsUiComponentsDrawLineDirective {
|
|
7
|
+
cdr = inject(ChangeDetectorRef);
|
|
8
|
+
zone = inject(NgZone);
|
|
9
|
+
elementRef = inject(ElementRef);
|
|
10
|
+
intervalScrollToElement;
|
|
11
|
+
dataDraw = [];
|
|
12
|
+
dataReachablePointRange = [];
|
|
13
|
+
onDrawLineEnd = new Subject();
|
|
14
|
+
onDestroy = new Subject();
|
|
15
|
+
viewBoxConfig;
|
|
16
|
+
svgElement;
|
|
17
|
+
drawRectDebug;
|
|
18
|
+
outDrawLineFunctionControl = new EventEmitter();
|
|
19
|
+
outConnected = new EventEmitter();
|
|
20
|
+
ngAfterViewInit() {
|
|
21
|
+
this.svgElement = this.svgElement || document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
22
|
+
this.elementRef.nativeElement.append(this.svgElement);
|
|
23
|
+
this.outDrawLineFunctionControl.emit({
|
|
24
|
+
setData: this.setData.bind(this),
|
|
25
|
+
setReachablePointRange: this.setReachablePointRange.bind(this),
|
|
26
|
+
removeLine: this.removeLine.bind(this),
|
|
27
|
+
removeReachablePointRange: this.removeReachablePointRange.bind(this),
|
|
28
|
+
updateViewBox: this.updateViewBox.bind(this)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
setData(data) {
|
|
32
|
+
const newData = [];
|
|
33
|
+
data.forEach(item => {
|
|
34
|
+
if (this.dataDraw.find(dataDraw => dataDraw.id === item.id && item.points.start.x === dataDraw.points.start.x && item.points.start.y === dataDraw.points.start.y && item.points.end.x === dataDraw.points.end.x && item.points.end.y === dataDraw.points.end.y)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const itemClone = cloneDeep(item);
|
|
38
|
+
itemClone.ref = item;
|
|
39
|
+
newData.push(itemClone);
|
|
40
|
+
});
|
|
41
|
+
this.dataDraw.push(...newData);
|
|
42
|
+
this.startProcessDataRow(newData);
|
|
43
|
+
}
|
|
44
|
+
setReachablePointRange(data) {
|
|
45
|
+
const newData = [];
|
|
46
|
+
data.forEach(item => {
|
|
47
|
+
if (this.dataReachablePointRange.find(dataDraw => dataDraw.id === item.id || item.x === dataDraw.x && item.y === dataDraw.y)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const itemClone = cloneDeep(item);
|
|
51
|
+
itemClone.ref = item;
|
|
52
|
+
newData.push(itemClone);
|
|
53
|
+
});
|
|
54
|
+
this.dataReachablePointRange.push(...newData);
|
|
55
|
+
this.startProcessDataReachablePointRange(newData);
|
|
56
|
+
}
|
|
57
|
+
removeLine(id, points) {
|
|
58
|
+
const dataDrawById = this.dataDraw.filter(item => item.id === id);
|
|
59
|
+
if (!dataDrawById?.length) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const removeByItem = (item) => {
|
|
63
|
+
this.removeElementOfPoints(item.points);
|
|
64
|
+
item.points.separatedPoints?.forEach(separatedPoints => this.removeElementOfPoints(separatedPoints));
|
|
65
|
+
};
|
|
66
|
+
if (!points?.length) {
|
|
67
|
+
dataDrawById.forEach(item => removeByItem(item));
|
|
68
|
+
this.dataDraw = this.dataDraw.filter(item => item.id !== id);
|
|
69
|
+
this.updateViewBox();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
points.forEach(point => {
|
|
73
|
+
const dataDrawRemoveByPoint = dataDrawById.find(item => item.points.start.x === point.start.x && item.points.start.y === point.start.y && item.points.end.x === point.end.x && item.points.end.y === point.end.y);
|
|
74
|
+
if (dataDrawRemoveByPoint) {
|
|
75
|
+
dataDrawRemoveByPoint.isRemove = true;
|
|
76
|
+
removeByItem(dataDrawRemoveByPoint);
|
|
77
|
+
this.dataDraw = this.dataDraw.filter(item => item.id !== id && !item.isRemove);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
this.updateViewBox();
|
|
81
|
+
}
|
|
82
|
+
removeReachablePointRange(ids) {
|
|
83
|
+
this.clearRect();
|
|
84
|
+
if (!ids.length) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
ids.forEach(id => {
|
|
88
|
+
const itemRemove = this.dataReachablePointRange?.find(item => item.id === id);
|
|
89
|
+
if (!itemRemove) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
itemRemove.onDestroyEvent?.next();
|
|
93
|
+
itemRemove.element?.remove();
|
|
94
|
+
this.dataReachablePointRange = this.dataReachablePointRange?.filter(item => item.id !== id);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
startProcessDataRow(dataDraw) {
|
|
98
|
+
this.zone.runOutsideAngular(() => {
|
|
99
|
+
dataDraw.forEach(item => {
|
|
100
|
+
const { pathElement, arrowElement, circleStartElement, circleEndElement } = this.createPathAndArrowElement(item.id);
|
|
101
|
+
item.points.obstacleRect?.forEach(data => this.addRect('rect', data));
|
|
102
|
+
item.points.pathElement = pathElement;
|
|
103
|
+
item.points.arrowElement = arrowElement;
|
|
104
|
+
if (item.startCircle) {
|
|
105
|
+
item.points.circleStartElement = circleStartElement;
|
|
106
|
+
this.svgElement.append(circleStartElement);
|
|
107
|
+
}
|
|
108
|
+
if (item.endCircle) {
|
|
109
|
+
item.points.circleEndElement = circleEndElement;
|
|
110
|
+
this.svgElement.append(circleEndElement);
|
|
111
|
+
}
|
|
112
|
+
item.points.onDestroyEvent = new Subject();
|
|
113
|
+
this.drawLine(item);
|
|
114
|
+
});
|
|
115
|
+
this.updateViewBox();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
startProcessDataReachablePointRange(data) {
|
|
119
|
+
this.zone.runOutsideAngular(() => {
|
|
120
|
+
data.forEach(item => {
|
|
121
|
+
item.onDestroyEvent = new Subject();
|
|
122
|
+
item.element = this.createPathAndArrowElement(item.id).circleEndElement;
|
|
123
|
+
this.svgElement.append(item.element);
|
|
124
|
+
this.updateAttributeCircle(item.element, item.id, item, item.style);
|
|
125
|
+
this.onDrawLineEnd.pipe(takeUntil(item.onDestroyEvent), takeUntil(this.onDestroy)).subscribe(eventData => {
|
|
126
|
+
const { dataLine, event } = eventData;
|
|
127
|
+
if (!checkMouseOverInContainer(event, item.element) || !dataLine.ref || !item.ref) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
item.idConnected = eventData.dataLine.id;
|
|
131
|
+
eventData.dataLine.idConnected = item.id;
|
|
132
|
+
this.outConnected.emit({
|
|
133
|
+
dataLine: dataLine.ref,
|
|
134
|
+
dataReachablePointRange: item.ref
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
this.updateViewBox();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
removeElementOfPoints(points) {
|
|
142
|
+
this.zone.runOutsideAngular(() => {
|
|
143
|
+
points.onDestroyEvent?.next();
|
|
144
|
+
points.onDestroyEvent?.complete();
|
|
145
|
+
points?.pathElement?.remove();
|
|
146
|
+
points?.arrowElement?.remove();
|
|
147
|
+
points?.circleStartElement?.remove();
|
|
148
|
+
points.circleEndElement?.remove();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
drawLine(data) {
|
|
152
|
+
this.zone.runOutsideAngular(() => {
|
|
153
|
+
const { points, mode } = data;
|
|
154
|
+
let { curve } = data?.lineStyle || {};
|
|
155
|
+
if (mode !== 'quart-in') {
|
|
156
|
+
curve = curve ?? 10;
|
|
157
|
+
}
|
|
158
|
+
const preLengthSeparatedPoints = points.separatedPoints?.length;
|
|
159
|
+
points.separatedPoints?.forEach(separatedPoints => this.removeElementOfPoints(separatedPoints));
|
|
160
|
+
points.separatedPoints = [];
|
|
161
|
+
MoCanvasConnectNavigationNewElementUtil.START_MODE = 'right-left';
|
|
162
|
+
if (data.startEndMode) {
|
|
163
|
+
MoCanvasConnectNavigationNewElementUtil.START_MODE = data.startEndMode;
|
|
164
|
+
}
|
|
165
|
+
this.calculatorSeparatedPoints(data.id, points, curve || 10, points.separatedPoints, points.obstacleRect || []);
|
|
166
|
+
if (!preLengthSeparatedPoints && points.separatedPoints.length) {
|
|
167
|
+
this.removeElementOfPoints(points);
|
|
168
|
+
const { pathElement, arrowElement } = this.createPathAndArrowElement(data.id);
|
|
169
|
+
points.pathElement = pathElement;
|
|
170
|
+
points.arrowElement = arrowElement;
|
|
171
|
+
points.initialized = false;
|
|
172
|
+
}
|
|
173
|
+
if (!points.separatedPoints?.length) {
|
|
174
|
+
this.buildPathAndDraw(data, points, mode);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
points.separatedPoints.forEach(separatedPoints => {
|
|
178
|
+
this.buildPathAndDraw(data, separatedPoints, separatedPoints.mode || mode);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
updateViewBox(viewBoxConfig) {
|
|
183
|
+
if (viewBoxConfig) {
|
|
184
|
+
this.viewBoxConfig = viewBoxConfig;
|
|
185
|
+
}
|
|
186
|
+
const xPoints = new Set([0]);
|
|
187
|
+
const yPoints = new Set([0]);
|
|
188
|
+
const addPoints = (points) => {
|
|
189
|
+
xPoints.add(points.start.x);
|
|
190
|
+
xPoints.add(points.end.x);
|
|
191
|
+
yPoints.add(points.start.y);
|
|
192
|
+
yPoints.add(points.end.y);
|
|
193
|
+
};
|
|
194
|
+
this.dataDraw?.forEach(item => {
|
|
195
|
+
const points = item.points;
|
|
196
|
+
addPoints(points);
|
|
197
|
+
points.separatedPoints?.forEach(separatedPoints => addPoints(separatedPoints));
|
|
198
|
+
points.obstacleRect?.forEach(obstacleRect => {
|
|
199
|
+
addPoints({
|
|
200
|
+
start: { x: obstacleRect.x - (obstacleRect.gapXObstacleRect || 8), y: obstacleRect.y - (obstacleRect.gapYObstacleRect || 8) },
|
|
201
|
+
end: { x: obstacleRect.x + obstacleRect.width + (obstacleRect.gapXObstacleRect || 8) * 2, y: obstacleRect.y + obstacleRect.height + (obstacleRect.gapYObstacleRect || 8) * 2 }
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
const xMax = this.viewBoxConfig?.width ?? (xPoints.size ? Math.max(...xPoints) : 0) + 14;
|
|
206
|
+
const yMax = this.viewBoxConfig?.height ?? (yPoints.size ? Math.max(...yPoints) : 0) + 14;
|
|
207
|
+
if (!this.viewBoxConfig?.ignoreViewBox) {
|
|
208
|
+
const rectSvgElement = this.svgElement.getBoundingClientRect();
|
|
209
|
+
this.svgElement?.setAttribute('viewBox', `${this.viewBoxConfig?.minX ?? rectSvgElement.x} ${this.viewBoxConfig?.minY ?? rectSvgElement.y} ${xMax} ${yMax}`);
|
|
210
|
+
}
|
|
211
|
+
this.svgElement?.setAttribute('width', `${xMax ?? 0}`);
|
|
212
|
+
this.svgElement?.setAttribute('height', `${yMax ?? 0}`);
|
|
213
|
+
}
|
|
214
|
+
isPointInsideSquare(point, square) {
|
|
215
|
+
const { x, y } = point;
|
|
216
|
+
const { x: squareX, y: squareY, width, height } = square;
|
|
217
|
+
return x >= squareX && x <= squareX + width && y >= squareY && y <= squareY + height;
|
|
218
|
+
}
|
|
219
|
+
calculatorSeparatedPoints(name, points, curve, separatedPoints, obstacleRects) {
|
|
220
|
+
if (!obstacleRects.length) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const elementStart = obstacleRects.find(item => this.isPointInsideSquare(points.start, item));
|
|
224
|
+
const elementEnd = obstacleRects.find(item => this.isPointInsideSquare(points.end, item));
|
|
225
|
+
if (this.viewBoxConfig?.marginBetweenElement) {
|
|
226
|
+
MoCanvasConnectNavigationNewElementUtil.ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT = this.viewBoxConfig?.marginBetweenElement ?? 32;
|
|
227
|
+
}
|
|
228
|
+
MoCanvasConnectNavigationNewElementUtil.setXYConnectElements(elementStart ?? { ...points.start, width: 1, height: 1 }, elementEnd ?? { ...points.end, width: 1, height: 1 }, obstacleRects, separatedPoints, curve);
|
|
229
|
+
separatedPoints?.forEach(item => {
|
|
230
|
+
item.pathElement = this.createPathAndArrowElement(name).pathElement;
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
buildPathAndDraw(data, points, mode) {
|
|
234
|
+
let dPath = {};
|
|
235
|
+
const styleConfig = {
|
|
236
|
+
stroke: data.lineStyle?.stroke ?? '#9CA2AD',
|
|
237
|
+
strokeDasharray: data.lineStyle?.strokeDasharray,
|
|
238
|
+
strokeWidth: data.lineStyle?.strokeWidth ?? '1px',
|
|
239
|
+
fill: data.lineStyle?.fill ?? 'none',
|
|
240
|
+
curve: data.lineStyle?.curve ?? 10,
|
|
241
|
+
distancePoint: data.lineStyle?.distancePoint ?? 10
|
|
242
|
+
};
|
|
243
|
+
points.pathElement?.setAttribute('stroke', styleConfig.stroke);
|
|
244
|
+
points.pathElement?.setAttribute('fill', styleConfig.fill);
|
|
245
|
+
points.pathElement?.setAttribute('stroke-width', styleConfig.strokeWidth);
|
|
246
|
+
if (styleConfig.strokeDasharray) {
|
|
247
|
+
points.pathElement?.setAttribute('stroke-dasharray', styleConfig.strokeDasharray);
|
|
248
|
+
}
|
|
249
|
+
let { curve, distancePoint } = styleConfig;
|
|
250
|
+
mode = mode || "quart-in";
|
|
251
|
+
if (mode !== 'quart-in') {
|
|
252
|
+
curve = curve ?? 10;
|
|
253
|
+
distancePoint = distancePoint ?? 10;
|
|
254
|
+
}
|
|
255
|
+
if (mode === 'quart-in' || points.start.x === points.end.x || points.start.y === points.end.y) {
|
|
256
|
+
this.drawBalancedCurve(dPath, points);
|
|
257
|
+
if (mode === 'quart-in') {
|
|
258
|
+
dPath = {};
|
|
259
|
+
this.drawBendBothEndsCurve(dPath, points);
|
|
260
|
+
}
|
|
261
|
+
points.pathElement?.setAttribute('d', this.builDAttributeToString(dPath));
|
|
262
|
+
this.drawRectAndInitEvent(data, mode);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const result = this.calculatorDistancePointAndCurve(points, distancePoint, curve, mode);
|
|
266
|
+
distancePoint = result.distancePoint;
|
|
267
|
+
curve = result.curve;
|
|
268
|
+
this.buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint || 0, curve || 0, mode);
|
|
269
|
+
this.buildDAttributeByPointEndModeVertical(dPath, points, distancePoint || 0, curve || 0, mode);
|
|
270
|
+
points.pathElement?.setAttribute('d', this.builDAttributeToString(dPath));
|
|
271
|
+
this.drawRectAndInitEvent(data, mode);
|
|
272
|
+
}
|
|
273
|
+
calculatorDistancePointAndCurve(points, distancePoint, curve, mode) {
|
|
274
|
+
if ((!mode.includes('vertical') && !mode.includes('horizontal'))) {
|
|
275
|
+
return { curve, distancePoint };
|
|
276
|
+
}
|
|
277
|
+
const gapX = Math.abs(points.start.x - points.end.x);
|
|
278
|
+
const gapY = Math.abs(points.start.y - points.end.y);
|
|
279
|
+
const multiplierCurve = mode.includes('horizontal') ? 1 : 2;
|
|
280
|
+
const multiplierDistance = mode.includes('horizontal') ? 2 : 1;
|
|
281
|
+
if (!mode.includes('single-curve')) {
|
|
282
|
+
if (gapX < distancePoint * multiplierDistance + curve * multiplierCurve) {
|
|
283
|
+
distancePoint = curve = gapX / 3;
|
|
284
|
+
}
|
|
285
|
+
if (gapY < distancePoint * multiplierDistance + curve * multiplierCurve) {
|
|
286
|
+
distancePoint = curve = gapY / 3;
|
|
287
|
+
}
|
|
288
|
+
return { curve, distancePoint };
|
|
289
|
+
}
|
|
290
|
+
const minGap = Math.min(gapX, gapY);
|
|
291
|
+
if (minGap < distancePoint) {
|
|
292
|
+
distancePoint = minGap;
|
|
293
|
+
}
|
|
294
|
+
if (minGap < curve) {
|
|
295
|
+
curve = minGap;
|
|
296
|
+
}
|
|
297
|
+
return { curve, distancePoint };
|
|
298
|
+
}
|
|
299
|
+
drawRectAndInitEvent(data, mode) {
|
|
300
|
+
const points = data.points;
|
|
301
|
+
this.updateStyleArrow(points, mode, data);
|
|
302
|
+
if (data.startCircle && points.circleStartElement) {
|
|
303
|
+
this.updateAttributeCircle(points.circleStartElement, data.id, points.start, data.startCircleStyle);
|
|
304
|
+
}
|
|
305
|
+
if (data.endCircle && points.circleEndElement) {
|
|
306
|
+
this.updateAttributeCircle(points.circleEndElement, data.id, points.end, data.endCircleStyle);
|
|
307
|
+
}
|
|
308
|
+
this.initEvent(data);
|
|
309
|
+
}
|
|
310
|
+
drawBalancedCurve(dPath, points) {
|
|
311
|
+
dPath.M = { x: points.start.x, y: points.start.y };
|
|
312
|
+
dPath.Q = [{ x: points.start.x + (points.end.x - points.start.x) / 4, y: points.start.y + (points.end.y - points.start.y) / 2 }, { x: points.start.x + (points.end.x - points.start.x) / 2, y: points.start.y + (points.end.y - points.start.y) / 2 }];
|
|
313
|
+
dPath.Q2 = [{ x: points.end.x - (points.end.x - points.start.x) / 4, y: points.start.y + (points.end.y - points.start.y) / 2 }, { x: points.end.x, y: points.end.y }];
|
|
314
|
+
}
|
|
315
|
+
drawBendBothEndsCurve(dPath, points) {
|
|
316
|
+
const pointXCurve = (points.start.x + points.end.x) * 0.5;
|
|
317
|
+
const pointControl1 = { x: pointXCurve, y: points.start.y };
|
|
318
|
+
const pointControl2 = { x: pointXCurve, y: points.end.y };
|
|
319
|
+
dPath.M = { x: points.start.x, y: points.start.y };
|
|
320
|
+
dPath.C = [{ x: pointControl1.x, y: pointControl1.y }, { x: pointControl2.x, y: pointControl2.y }, { x: points.end.x, y: points.end.y }];
|
|
321
|
+
}
|
|
322
|
+
buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint, curve, mode) {
|
|
323
|
+
if (!mode.includes('horizontal')) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const multiplierX = points.start.x < points.end.x ? -1 : 1;
|
|
327
|
+
const multiplierY = points.start.y < points.end.y ? 1 : -1;
|
|
328
|
+
const reverseMultiplier = -1;
|
|
329
|
+
dPath.M = { x: points.start.x, y: points.start.y };
|
|
330
|
+
dPath.L = { x: points.end.x + ((distancePoint * 2 + curve) * multiplierX), y: points.start.y };
|
|
331
|
+
if (mode.includes('horizontal-single')) {
|
|
332
|
+
dPath.L.x = points.end.x + (curve * multiplierX);
|
|
333
|
+
}
|
|
334
|
+
dPath.Q = [{ x: dPath.L.x + (curve * multiplierX * reverseMultiplier), y: points.start.y }, { x: dPath.L.x + (curve * multiplierX * reverseMultiplier), y: points.start.y + (curve * multiplierY) }];
|
|
335
|
+
dPath.L2 = { x: dPath.Q[1].x, y: points.end.y + (curve * multiplierY * reverseMultiplier) };
|
|
336
|
+
if (mode.includes('horizontal-single')) {
|
|
337
|
+
dPath.L2 = points.end;
|
|
338
|
+
}
|
|
339
|
+
if (mode === 'horizontal') {
|
|
340
|
+
dPath.Q2 = [{ x: dPath.L2.x, y: points.end.y }, { x: dPath.L2.x + (distancePoint * multiplierX * reverseMultiplier), y: points.end.y }];
|
|
341
|
+
dPath.L3 = { x: points.end.x, y: points.end.y };
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
buildDAttributeByPointEndModeVertical(dPath, points, distancePoint, curve, mode) {
|
|
345
|
+
if (!mode.includes('vertical')) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const multiplierX = points.start.x < points.end.x ? -1 : 1;
|
|
349
|
+
const multiplierY = points.start.y < points.end.y ? 1 : -1;
|
|
350
|
+
const reverseMultiplier = -1;
|
|
351
|
+
dPath.M = points.start;
|
|
352
|
+
dPath.L = { x: points.start.x, y: points.start.y + (distancePoint * multiplierY) };
|
|
353
|
+
if (mode.includes('vertical-single')) {
|
|
354
|
+
dPath.L.y = points.end.y + (distancePoint * multiplierY * reverseMultiplier);
|
|
355
|
+
}
|
|
356
|
+
dPath.Q = [{ x: dPath.L.x, y: dPath.L.y + (curve * multiplierY) }, { x: dPath.L.x + (curve * multiplierX * reverseMultiplier), y: dPath.L.y + (curve * multiplierY) }];
|
|
357
|
+
dPath.L2 = { x: points.end.x + ((curve * 2) * multiplierX), y: dPath.Q[1].y };
|
|
358
|
+
if (mode.includes('vertical-single')) {
|
|
359
|
+
dPath.L2 = points.end;
|
|
360
|
+
}
|
|
361
|
+
if (mode === 'vertical') {
|
|
362
|
+
dPath.Q2 = [{ x: points.end.x, y: dPath.L2.y }, { x: points.end.x, y: dPath.L2.y + (curve * multiplierY) }];
|
|
363
|
+
dPath.L3 = { x: points.end.x, y: points.end.y };
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
builDAttributeToString(dAttribute) {
|
|
367
|
+
let dString = '';
|
|
368
|
+
Object.keys(dAttribute).forEach(key => {
|
|
369
|
+
const data = get(dAttribute, key);
|
|
370
|
+
if (Array.isArray(data)) {
|
|
371
|
+
const [point1, point2, point3] = data;
|
|
372
|
+
dString = `${dString}${key.replace(/\d/g, '')}${point1.x},${point1.y} ${point2.x},${point2.y}${point3 ? ' ' + point3.x + ',' + point3.y : ''}
|
|
373
|
+
`;
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
dString = `${dString}${key.replace(/\d/g, '')}${data.x},${data.y}
|
|
377
|
+
`;
|
|
378
|
+
});
|
|
379
|
+
return dString;
|
|
380
|
+
}
|
|
381
|
+
updateStyleArrow(points, mode, data) {
|
|
382
|
+
if (!points.arrowElement || data.ignoreDrawArrow) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const styleConfig = {
|
|
386
|
+
fill: data.arrowStyle?.fill ?? '#9CA2AD',
|
|
387
|
+
stroke: data.arrowStyle?.stroke ?? 'none',
|
|
388
|
+
strokeWidth: data.arrowStyle?.strokeWidth ?? '0',
|
|
389
|
+
width: data.arrowStyle?.width ?? 6,
|
|
390
|
+
height: data.arrowStyle?.height ?? 8
|
|
391
|
+
};
|
|
392
|
+
const pointEnd = cloneDeep(points.end);
|
|
393
|
+
const arrowElement = points.arrowElement;
|
|
394
|
+
const direction = data.arrowDirection || this.getDirection(points, mode);
|
|
395
|
+
switch (direction) {
|
|
396
|
+
case 'right':
|
|
397
|
+
if (mode.includes('horizontal') || mode.includes('vertical')) {
|
|
398
|
+
pointEnd.x -= styleConfig.height;
|
|
399
|
+
}
|
|
400
|
+
arrowElement?.setAttribute('points', `${pointEnd.x},${pointEnd.y - styleConfig.width} ${pointEnd.x + styleConfig.height},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.width} `);
|
|
401
|
+
break;
|
|
402
|
+
case 'left':
|
|
403
|
+
if (mode.includes('horizontal') || mode.includes('vertical')) {
|
|
404
|
+
pointEnd.x += styleConfig.height;
|
|
405
|
+
}
|
|
406
|
+
arrowElement?.setAttribute('points', `${pointEnd.x},${pointEnd.y - styleConfig.width} ${pointEnd.x - styleConfig.height},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.width} `);
|
|
407
|
+
break;
|
|
408
|
+
case 'top':
|
|
409
|
+
if (mode.includes('horizontal') || mode.includes('vertical')) {
|
|
410
|
+
pointEnd.y += styleConfig.height;
|
|
411
|
+
}
|
|
412
|
+
arrowElement?.setAttribute('points', `${pointEnd.x - styleConfig.width},${pointEnd.y} ${pointEnd.x},${pointEnd.y - styleConfig.height} ${pointEnd.x + styleConfig.width},${pointEnd.y} `);
|
|
413
|
+
break;
|
|
414
|
+
case 'bottom':
|
|
415
|
+
if (mode.includes('horizontal') || mode.includes('vertical')) {
|
|
416
|
+
pointEnd.y -= styleConfig.height;
|
|
417
|
+
}
|
|
418
|
+
arrowElement?.setAttribute('points', `${pointEnd.x - styleConfig.width},${pointEnd.y} ${pointEnd.x},${pointEnd.y + styleConfig.height} ${pointEnd.x + styleConfig.width},${pointEnd.y} `);
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
arrowElement?.setAttribute('fill', styleConfig.fill);
|
|
422
|
+
arrowElement?.setAttribute('stroke', styleConfig.stroke);
|
|
423
|
+
arrowElement?.setAttribute('stroke-width', styleConfig.strokeWidth);
|
|
424
|
+
}
|
|
425
|
+
updateAttributeCircle(circleElement, name, point, circleStyle) {
|
|
426
|
+
circleElement.setAttribute('name', name);
|
|
427
|
+
circleElement.setAttribute('cx', `${point.x}`);
|
|
428
|
+
circleElement.setAttribute('cy', `${point.y}`);
|
|
429
|
+
circleElement.setAttribute('r', `${circleStyle?.r ?? 2}`);
|
|
430
|
+
circleElement.setAttribute('fill', `${circleStyle?.fill ?? 'green'}`);
|
|
431
|
+
circleElement.setAttribute('stroke', `${circleStyle?.stroke ?? '#9CA2AD'}`);
|
|
432
|
+
circleElement.setAttribute('stroke-width', `${circleStyle?.strokeWidth ?? '1px'}`);
|
|
433
|
+
return circleElement;
|
|
434
|
+
}
|
|
435
|
+
getDirection(points, mode) {
|
|
436
|
+
let pointStart = { ...points.start };
|
|
437
|
+
if (points.separatedPoints) {
|
|
438
|
+
const lineToEnd = points.separatedPoints.find(item => item.end.x === points.end.x && item.end.y === points.end.y);
|
|
439
|
+
if (lineToEnd) {
|
|
440
|
+
pointStart = lineToEnd.start;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const modeHorizontal = pointStart.x < points.end.x ? 'right' : 'left';
|
|
444
|
+
const modeVertical = pointStart.y < points.end.y ? 'bottom' : 'top';
|
|
445
|
+
if (Math.abs(points.end.x - pointStart.x) > Math.abs(points.end.y - pointStart.y)) {
|
|
446
|
+
return modeHorizontal;
|
|
447
|
+
}
|
|
448
|
+
return modeVertical;
|
|
449
|
+
}
|
|
450
|
+
initEvent(data) {
|
|
451
|
+
const points = data.points;
|
|
452
|
+
let preEvent = undefined;
|
|
453
|
+
if ((!points.arrowElement && !points.circleEndElement) || !points.onDestroyEvent || points.initialized) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
points.initialized = true;
|
|
457
|
+
const stopEventMouse = (mouseEvent) => {
|
|
458
|
+
mouseEvent.preventDefault();
|
|
459
|
+
mouseEvent.stopPropagation();
|
|
460
|
+
};
|
|
461
|
+
const documentMouseUp = fromEvent(document, 'mouseup')
|
|
462
|
+
.pipe(tap((eventMouseUp) => {
|
|
463
|
+
stopEventMouse(eventMouseUp);
|
|
464
|
+
if (preEvent) {
|
|
465
|
+
preEvent = undefined;
|
|
466
|
+
this.onDrawLineEnd.next({ dataLine: data, event: eventMouseUp });
|
|
467
|
+
}
|
|
468
|
+
}), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy));
|
|
469
|
+
const documentMouseMove = fromEvent(document, 'mousemove').pipe(tap((eventMousemove) => stopEventMouse(eventMousemove)), takeUntil((documentMouseUp)), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy));
|
|
470
|
+
const handlerDrag = (dragMouseEvent) => {
|
|
471
|
+
if (!preEvent) {
|
|
472
|
+
preEvent = dragMouseEvent;
|
|
473
|
+
}
|
|
474
|
+
const pointEnd = cloneDeep(points.end);
|
|
475
|
+
const movementX = dragMouseEvent.clientX - preEvent.clientX;
|
|
476
|
+
const movementY = dragMouseEvent.clientY - preEvent.clientY;
|
|
477
|
+
preEvent = dragMouseEvent;
|
|
478
|
+
pointEnd.x += movementX;
|
|
479
|
+
pointEnd.y += movementY;
|
|
480
|
+
if (data.points?.obstacleRect?.length && data.points?.obstacleRect.some(obstacleRect => this.checkPointIncludeRect(pointEnd, obstacleRect))) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
points.end.x = pointEnd.x;
|
|
484
|
+
points.end.y = pointEnd.y;
|
|
485
|
+
this.drawLine(data);
|
|
486
|
+
this.updateViewBox();
|
|
487
|
+
};
|
|
488
|
+
if (points.arrowElement) {
|
|
489
|
+
const elementMouseDownArrow = fromEvent(points.arrowElement, 'mousedown').pipe(tap(eventMousedown => {
|
|
490
|
+
stopEventMouse(eventMousedown);
|
|
491
|
+
}), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy));
|
|
492
|
+
const dragArrow = elementMouseDownArrow.pipe(mergeMap((mouseEvent) => documentMouseMove.pipe(startWith((mouseEvent)))));
|
|
493
|
+
dragArrow.pipe(tap(handlerDrag), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy)).subscribe();
|
|
494
|
+
}
|
|
495
|
+
if (points.circleEndElement) {
|
|
496
|
+
const elementMouseDownCircle = fromEvent(points.circleEndElement, 'mousedown').pipe(tap(eventMousedown => {
|
|
497
|
+
stopEventMouse(eventMousedown);
|
|
498
|
+
}), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy));
|
|
499
|
+
const dragCircle = elementMouseDownCircle.pipe(mergeMap((mouseEvent) => documentMouseMove.pipe(startWith((mouseEvent)))));
|
|
500
|
+
dragCircle.pipe(tap(handlerDrag), takeUntil(points.onDestroyEvent), takeUntil(this.onDestroy)).subscribe();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
checkPointIncludeRect(point, obstacleRect) {
|
|
504
|
+
const gapDefault = 8;
|
|
505
|
+
obstacleRect = {
|
|
506
|
+
x: obstacleRect.x - (obstacleRect.gapXObstacleRect || gapDefault),
|
|
507
|
+
y: obstacleRect.y - (obstacleRect.gapYObstacleRect || gapDefault),
|
|
508
|
+
width: obstacleRect.width + (obstacleRect.gapXObstacleRect || gapDefault) * 2,
|
|
509
|
+
height: obstacleRect.height + (obstacleRect.gapYObstacleRect || gapDefault) * 2
|
|
510
|
+
};
|
|
511
|
+
if ((obstacleRect.x <= point.x && point.x <= obstacleRect.x + obstacleRect.width) && (obstacleRect.y <= point.y && point.y <= obstacleRect.y + obstacleRect.height)) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
createPathAndArrowElement(name) {
|
|
517
|
+
const pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
518
|
+
const arrowElement = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
|
|
519
|
+
const circleStartElement = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
520
|
+
const circleEndElement = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
521
|
+
pathElement.setAttribute('name', name);
|
|
522
|
+
arrowElement.setAttribute('name', name);
|
|
523
|
+
this.svgElement.append(pathElement);
|
|
524
|
+
this.svgElement.append(arrowElement);
|
|
525
|
+
return { pathElement, arrowElement, circleStartElement, circleEndElement };
|
|
526
|
+
}
|
|
527
|
+
addCircle(name, point) {
|
|
528
|
+
if (!this.drawRectDebug) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
532
|
+
circle.setAttribute('name', name);
|
|
533
|
+
circle.setAttribute('cx', `${point.x}`);
|
|
534
|
+
circle.setAttribute('cy', `${point.y}`);
|
|
535
|
+
circle.setAttribute('r', '2');
|
|
536
|
+
circle.setAttribute('style', 'fill: none; stroke: blue; stroke-width: 1px;');
|
|
537
|
+
this.svgElement.appendChild(circle);
|
|
538
|
+
}
|
|
539
|
+
clearCircle() {
|
|
540
|
+
if (!this.drawRectDebug) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
Array.from(this.svgElement.getElementsByTagName('circle'))?.forEach(item => item.remove());
|
|
544
|
+
}
|
|
545
|
+
addRect(name, rect) {
|
|
546
|
+
if (!this.drawRectDebug) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
550
|
+
const textElement = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
551
|
+
rectElement.setAttribute('name', name);
|
|
552
|
+
rectElement.setAttribute('x', `${rect.x}`);
|
|
553
|
+
rectElement.setAttribute('y', `${rect.y}`);
|
|
554
|
+
rectElement.setAttribute('width', `${rect.width}`);
|
|
555
|
+
rectElement.setAttribute('height', `${rect.height}`);
|
|
556
|
+
rectElement.setAttribute('style', 'fill: blue; stroke: blue;');
|
|
557
|
+
this.svgElement.appendChild(rectElement);
|
|
558
|
+
textElement.setAttribute('x', `${rect.x}`);
|
|
559
|
+
textElement.setAttribute('y', `${rect.y}`);
|
|
560
|
+
textElement.textContent = rect.id ?? '';
|
|
561
|
+
this.svgElement.appendChild(textElement);
|
|
562
|
+
}
|
|
563
|
+
clearRect() {
|
|
564
|
+
if (!this.drawRectDebug) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
Array.from(this.svgElement.getElementsByTagName('rect'))?.forEach(item => item.remove());
|
|
568
|
+
Array.from(this.svgElement.getElementsByTagName('text'))?.forEach(item => item.remove());
|
|
569
|
+
}
|
|
570
|
+
ngOnDestroy() {
|
|
571
|
+
this.onDestroy.next();
|
|
572
|
+
this.onDestroy.complete();
|
|
573
|
+
}
|
|
574
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsDrawLineDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
575
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: LibsUiComponentsDrawLineDirective, isStandalone: true, selector: "[LibsUiComponentsDrawLineDirective]", inputs: { viewBoxConfig: "viewBoxConfig", svgElement: "svgElement", drawRectDebug: "drawRectDebug" }, outputs: { outDrawLineFunctionControl: "outDrawLineFunctionControl", outConnected: "outConnected" }, ngImport: i0 });
|
|
576
|
+
}
|
|
577
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsDrawLineDirective, decorators: [{
|
|
578
|
+
type: Directive,
|
|
579
|
+
args: [{
|
|
580
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
581
|
+
selector: "[LibsUiComponentsDrawLineDirective]",
|
|
582
|
+
standalone: true,
|
|
583
|
+
}]
|
|
584
|
+
}], propDecorators: { viewBoxConfig: [{
|
|
585
|
+
type: Input
|
|
586
|
+
}], svgElement: [{
|
|
587
|
+
type: Input
|
|
588
|
+
}], drawRectDebug: [{
|
|
589
|
+
type: Input
|
|
590
|
+
}], outDrawLineFunctionControl: [{
|
|
591
|
+
type: Output
|
|
592
|
+
}], outConnected: [{
|
|
593
|
+
type: Output
|
|
594
|
+
}] } });
|
|
595
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhdy1saW5lLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9kcmF3LWxpbmUvc3JjL2RyYXctbGluZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFhLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEosT0FBTyxFQUFFLHlCQUF5QixFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRSxPQUFPLEVBQWMsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFM0YsT0FBTyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sNENBQTRDLENBQUM7O0FBT3JHLE1BQU0sT0FBTyxpQ0FBaUM7SUFDbEMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2hDLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdEIsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoQyx1QkFBdUIsQ0FBVTtJQUNuQyxRQUFRLEdBQThCLEVBQUUsQ0FBQztJQUN6Qyx1QkFBdUIsR0FBZ0MsRUFBRSxDQUFDO0lBQzFELGFBQWEsR0FHaEIsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUNYLFNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBRS9CLGFBQWEsQ0FBa0I7SUFDL0IsVUFBVSxDQUFpQjtJQUMzQixhQUFhLENBQVc7SUFFdkIsMEJBQTBCLEdBQTZDLElBQUksWUFBWSxFQUFFLENBQUM7SUFDMUYsWUFBWSxHQUFrRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBRzNJLGVBQWU7UUFDYixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUM7WUFDbkMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUM5RCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3RDLHlCQUF5QixFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3BFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDN0MsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLE9BQU8sQ0FBQyxJQUErQjtRQUM3QyxNQUFNLE9BQU8sR0FBOEIsRUFBRSxDQUFDO1FBRTlDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbEIsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDaFEsT0FBTztZQUNULENBQUM7WUFDRCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEMsU0FBUyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7WUFDckIsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFHRCxzQkFBc0IsQ0FBQyxJQUFpQztRQUN0RCxNQUFNLE9BQU8sR0FBZ0MsRUFBRSxDQUFDO1FBRWhELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbEIsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM3SCxPQUFPO1lBQ1QsQ0FBQztZQUNELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUVsQyxTQUFTLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQztZQUNyQixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU8sVUFBVSxDQUFDLEVBQVUsRUFBRSxNQUF1QjtRQUNwRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFbEUsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUMxQixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBd0IsRUFBRSxFQUFFO1lBQ2hELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFFdkcsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUNwQixZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDakQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBRXJCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNyQixNQUFNLHFCQUFxQixHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVsTixJQUFJLHFCQUFxQixFQUFFLENBQUM7Z0JBQzFCLHFCQUFxQixDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7Z0JBQ3RDLFlBQVksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakYsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBRXZCLENBQUM7SUFFTyx5QkFBeUIsQ0FBQyxHQUFrQjtRQUNsRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixPQUFPO1FBQ1QsQ0FBQztRQUVELEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDZixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUU5RSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU87WUFDVCxDQUFDO1lBQ0QsVUFBVSxDQUFDLGNBQWMsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUNsQyxVQUFVLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5RixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxRQUFtQztRQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUMvQixRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUN0QixNQUFNLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRXBILElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO2dCQUN4QyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztvQkFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztnQkFDN0MsQ0FBQztnQkFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztvQkFDaEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDM0MsQ0FBQztnQkFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNPLG1DQUFtQyxDQUFDLElBQWlDO1FBQzNFLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGdCQUFnQixDQUFDO2dCQUN4RSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUN2RyxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxHQUFHLFNBQVMsQ0FBQztvQkFFdEMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBaUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDNUcsT0FBTztvQkFDVCxDQUFDO29CQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7b0JBQ3pDLFNBQVMsQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3pDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO3dCQUNyQixRQUFRLEVBQUUsUUFBUSxDQUFDLEdBQUc7d0JBQ3RCLHVCQUF1QixFQUFFLElBQUksQ0FBQyxHQUFHO3FCQUNsQyxDQUFDLENBQUM7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxxQkFBcUIsQ0FBQyxNQUFlO1FBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDOUIsTUFBTSxDQUFDLGNBQWMsRUFBRSxRQUFRLEVBQUUsQ0FBQztZQUNsQyxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQzlCLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDL0IsTUFBTSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxRQUFRLENBQUMsSUFBd0I7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDL0IsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7WUFDOUIsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUksRUFBRSxTQUFTLElBQUksRUFBRSxDQUFDO1lBRXRDLElBQUksSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUN4QixLQUFLLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN0QixDQUFDO1lBQ0QsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQztZQUVoRSxNQUFNLENBQUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ2hHLE1BQU0sQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1lBQzVCLHVDQUF1QyxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUM7WUFDbEUsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RCLHVDQUF1QyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQ3pFLENBQUM7WUFDRCxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUUsRUFBRSxNQUFNLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7WUFDaEgsSUFBSSxDQUFDLHdCQUF3QixJQUFJLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQy9ELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDbkMsTUFBTSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUU5RSxNQUFNLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztnQkFDakMsTUFBTSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1lBQzdCLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxNQUFNLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRTFDLE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLGVBQWUsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxhQUFhLENBQUMsYUFBOEI7UUFDbEQsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQWdCLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBZ0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTFDLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBZSxFQUFFLEVBQUU7WUFDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzVCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7WUFFM0IsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xCLE1BQU0sQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDL0UsTUFBTSxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQzFDLFNBQVMsQ0FBQztvQkFDUixLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsRUFBRTtvQkFDN0gsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLEtBQUssR0FBRyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7aUJBQy9LLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3pGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFMUYsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLENBQUM7WUFDdkMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBRS9ELElBQUksQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxJQUFJLGNBQWMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLElBQUksY0FBYyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM5SixDQUFDO1FBQ0QsSUFBSSxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVPLG1CQUFtQixDQUFDLEtBQWEsRUFBRSxNQUFhO1FBQ3RELE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUV6RCxPQUFPLENBQUMsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLE9BQU8sR0FBRyxLQUFLLElBQUksQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQztJQUN2RixDQUFDO0lBRU8seUJBQXlCLENBQUMsSUFBWSxFQUFFLE1BQWUsRUFBRSxLQUFhLEVBQUUsZUFBK0IsRUFBRSxhQUEyQjtRQUMxSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzFCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDOUYsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFMUYsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLG9CQUFvQixFQUFFLENBQUM7WUFDN0MsdUNBQXVDLENBQUMscUNBQXFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxvQkFBb0IsSUFBSSxFQUFFLENBQUM7UUFDakksQ0FBQztRQUNELHVDQUF1QyxDQUFDLG9CQUFvQixDQUFDLFlBQVksSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwTixlQUFlLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzlCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUN0RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxJQUF3QixFQUFFLE1BQWUsRUFBRSxJQUFnQjtRQUNsRixJQUFJLEtBQUssR0FBRyxFQUF1QixDQUFDO1FBQ3BDLE1BQU0sV0FBVyxHQUFHO1lBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sSUFBSSxTQUFTO1lBQzNDLGVBQWUsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLGVBQWU7WUFDaEQsV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsV0FBVyxJQUFJLEtBQUs7WUFDakQsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxJQUFJLE1BQU07WUFDcEMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbEMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxJQUFJLEVBQUU7U0FDbkQsQ0FBQztRQUVGLE1BQU0sQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRCxNQUFNLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFFLElBQUksV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNwRixDQUFDO1FBQ0QsSUFBSSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsR0FBRyxXQUFXLENBQUM7UUFFM0MsSUFBSSxHQUFHLElBQUksSUFBSSxVQUFVLENBQUM7UUFDMUIsSUFBSSxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDeEIsS0FBSyxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDcEIsYUFBYSxHQUFHLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDdEMsQ0FBQztRQUNELElBQUksSUFBSSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzlGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFdEMsSUFBSSxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3hCLEtBQUssR0FBRyxFQUF1QixDQUFDO2dCQUNoQyxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLENBQUM7WUFDRCxNQUFNLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDMUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUV0QyxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV4RixhQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQztRQUNyQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUVyQixJQUFJLENBQUMsdUNBQXVDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbEcsSUFBSSxDQUFDLHFDQUFxQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsYUFBYSxJQUFJLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFTywrQkFBK0IsQ0FBQyxNQUFlLEVBQUUsYUFBcUIsRUFBRSxLQUFhLEVBQUUsSUFBZTtRQUM1RyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDakUsT0FBTyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsQ0FBQztRQUNsQyxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDbkMsSUFBSSxJQUFJLEdBQUcsYUFBYSxHQUFHLGtCQUFrQixHQUFHLEtBQUssR0FBRyxlQUFlLEVBQUUsQ0FBQztnQkFDeEUsYUFBYSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1lBQ25DLENBQUM7WUFDRCxJQUFJLElBQUksR0FBRyxhQUFhLEdBQUcsa0JBQWtCLEdBQUcsS0FBSyxHQUFHLGVBQWUsRUFBRSxDQUFDO2dCQUN4RSxhQUFhLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUVELE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLENBQUM7UUFDbEMsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXBDLElBQUksTUFBTSxHQUFHLGFBQWEsRUFBRSxDQUFDO1lBQzNCLGFBQWEsR0FBRyxNQUFNLENBQUM7UUFDekIsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLEtBQUssRUFBRSxDQUFDO1lBQ25CLEtBQUssR0FBRyxNQUFNLENBQUM7UUFDakIsQ0FBQztRQUVELE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVPLG9CQUFvQixDQUFDLElBQXdCLEVBQUUsSUFBZTtRQUNwRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRTNCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN0RyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBd0IsRUFBRSxNQUFlO1FBQ2pFLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDbkQsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2UCxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEssQ0FBQztJQUVPLHFCQUFxQixDQUFDLEtBQXdCLEVBQUUsTUFBZTtRQUNyRSxNQUFNLFdBQVcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQzFELE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM1RCxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFFMUQsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNuRCxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMs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Q3hCLE9BQU87UUFDVCxDQUFDO1FBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDekYsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQzt3R0F2ckJVLGlDQUFpQzs0RkFBakMsaUNBQWlDOzs0RkFBakMsaUNBQWlDO2tCQUw3QyxTQUFTO21CQUFDO29CQUNULDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLHFDQUFxQztvQkFDL0MsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzhCQWNVLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUVJLDBCQUEwQjtzQkFBbkMsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIE91dHB1dCwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IGNoZWNrTW91c2VPdmVySW5Db250YWluZXIsIGNsb25lRGVlcCwgZ2V0IH0gZnJvbSBcIkBsaWJzLXVpL3V0aWxzXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBmcm9tRXZlbnQsIG1lcmdlTWFwLCBzdGFydFdpdGgsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IElBdHRyaWJ1dGVET25QYXRoLCBJQ2lyY2xlU3R5bGUsIElEcmF3TGluZURhdGFJbnB1dCwgSU1vRHJhd0xpbmVGdW5jdGlvbkNvbnRyb2wsIElQb2ludCwgSVBvaW50cywgSVJlYWNoYWJsZVBvaW50UmFuZ2UsIElSZWN0LCBJVmlld0JveENvbmZpZywgVFlQRV9ESVJFQ1RJT04sIFRZUEVfTU9ERSB9IGZyb20gXCIuL2RyYXctbGluZS5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbCB9IGZyb20gXCIuL3V0aWwvY29ubmVjdC1uYXZpZ2F0aW9uLW5ldy1lbGVtZW50LnV0aWxcIjtcblxuQERpcmVjdGl2ZSh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gIHNlbGVjdG9yOiBcIltMaWJzVWlDb21wb25lbnRzRHJhd0xpbmVEaXJlY3RpdmVdXCIsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaUNvbXBvbmVudHNEcmF3TGluZURpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByb3RlY3RlZCBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuICBwcm90ZWN0ZWQgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuICBwcm90ZWN0ZWQgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJvdGVjdGVkIGludGVydmFsU2Nyb2xsVG9FbGVtZW50PzogbnVtYmVyO1xuICBwcml2YXRlIGRhdGFEcmF3OiBBcnJheTxJRHJhd0xpbmVEYXRhSW5wdXQ+ID0gW107XG4gIHByaXZhdGUgZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2U6IEFycmF5PElSZWFjaGFibGVQb2ludFJhbmdlPiA9IFtdO1xuICBwcml2YXRlIG9uRHJhd0xpbmVFbmQ6IFN1YmplY3Q8e1xuICAgIGRhdGFMaW5lOiBJRHJhd0xpbmVEYXRhSW5wdXQsXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnRcbiAgfT4gPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIG9uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgQElucHV0KCkgdmlld0JveENvbmZpZz86IElWaWV3Qm94Q29uZmlnO1xuICBASW5wdXQoKSBzdmdFbGVtZW50ITogU1ZHU1ZHRWxlbWVudDtcbiAgQElucHV0KCkgZHJhd1JlY3REZWJ1Zz86IGJvb2xlYW47XG5cbiAgQE91dHB1dCgpIG91dERyYXdMaW5lRnVuY3Rpb25Db250cm9sOiBFdmVudEVtaXR0ZXI8SU1vRHJhd0xpbmVGdW5jdGlvbkNvbnRyb2w+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb3V0Q29ubmVjdGVkOiBFdmVudEVtaXR0ZXI8eyBkYXRhTGluZTogSURyYXdMaW5lRGF0YUlucHV0LCBkYXRhUmVhY2hhYmxlUG9pbnRSYW5nZTogSVJlYWNoYWJsZVBvaW50UmFuZ2UgfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdmdFbGVtZW50ID0gdGhpcy5zdmdFbGVtZW50IHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwic3ZnXCIpO1xuICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmFwcGVuZCh0aGlzLnN2Z0VsZW1lbnQpO1xuICAgIHRoaXMub3V0RHJhd0xpbmVGdW5jdGlvbkNvbnRyb2wuZW1pdCh7XG4gICAgICBzZXREYXRhOiB0aGlzLnNldERhdGEuYmluZCh0aGlzKSxcbiAgICAgIHNldFJlYWNoYWJsZVBvaW50UmFuZ2U6IHRoaXMuc2V0UmVhY2hhYmxlUG9pbnRSYW5nZS5iaW5kKHRoaXMpLFxuICAgICAgcmVtb3ZlTGluZTogdGhpcy5yZW1vdmVMaW5lLmJpbmQodGhpcyksXG4gICAgICByZW1vdmVSZWFjaGFibGVQb2ludFJhbmdlOiB0aGlzLnJlbW92ZVJlYWNoYWJsZVBvaW50UmFuZ2UuYmluZCh0aGlzKSxcbiAgICAgIHVwZGF0ZVZpZXdCb3g6IHRoaXMudXBkYXRlVmlld0JveC5iaW5kKHRoaXMpXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldERhdGEoZGF0YTogQXJyYXk8SURyYXdMaW5lRGF0YUlucHV0Pikge1xuICAgIGNvbnN0IG5ld0RhdGE6IEFycmF5PElEcmF3TGluZURhdGFJbnB1dD4gPSBbXTtcblxuICAgIGRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGlmICh0aGlzLmRhdGFEcmF3LmZpbmQoZGF0YURyYXcgPT4gZGF0YURyYXcuaWQgPT09IGl0ZW0uaWQgJiYgaXRlbS5wb2ludHMuc3RhcnQueCA9PT0gZGF0YURyYXcucG9pbnRzLnN0YXJ0LnggJiYgaXRlbS5wb2ludHMuc3RhcnQueSA9PT0gZGF0YURyYXcucG9pbnRzLnN0YXJ0LnkgJiYgaXRlbS5wb2ludHMuZW5kLnggPT09IGRhdGFEcmF3LnBvaW50cy5lbmQueCAmJiBpdGVtLnBvaW50cy5lbmQueSA9PT0gZGF0YURyYXcucG9pbnRzLmVuZC55KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBpdGVtQ2xvbmUgPSBjbG9uZURlZXAoaXRlbSk7XG5cbiAgICAgIGl0ZW1DbG9uZS5yZWYgPSBpdGVtO1xuICAgICAgbmV3RGF0YS5wdXNoKGl0ZW1DbG9uZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRhdGFEcmF3LnB1c2goLi4ubmV3RGF0YSk7XG4gICAgdGhpcy5zdGFydFByb2Nlc3NEYXRhUm93KG5ld0RhdGEpO1xuICB9XG5cblxuICBzZXRSZWFjaGFibGVQb2ludFJhbmdlKGRhdGE6IEFycmF5PElSZWFjaGFibGVQb2ludFJhbmdlPikge1xuICAgIGNvbnN0IG5ld0RhdGE6IEFycmF5PElSZWFjaGFibGVQb2ludFJhbmdlPiA9IFtdO1xuXG4gICAgZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaWYgKHRoaXMuZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2UuZmluZChkYXRhRHJhdyA9PiBkYXRhRHJhdy5pZCA9PT0gaXRlbS5pZCB8fCBpdGVtLnggPT09IGRhdGFEcmF3LnggJiYgaXRlbS55ID09PSBkYXRhRHJhdy55KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBpdGVtQ2xvbmUgPSBjbG9uZURlZXAoaXRlbSk7XG5cbiAgICAgIGl0ZW1DbG9uZS5yZWYgPSBpdGVtO1xuICAgICAgbmV3RGF0YS5wdXNoKGl0ZW1DbG9uZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRhdGFSZWFjaGFibGVQb2ludFJhbmdlLnB1c2goLi4ubmV3RGF0YSk7XG4gICAgdGhpcy5zdGFydFByb2Nlc3NEYXRhUmVhY2hhYmxlUG9pbnRSYW5nZShuZXdEYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTGluZShpZDogc3RyaW5nLCBwb2ludHM/OiBBcnJheTxJUG9pbnRzPikge1xuICAgIGNvbnN0IGRhdGFEcmF3QnlJZCA9IHRoaXMuZGF0YURyYXcuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pZCA9PT0gaWQpO1xuXG4gICAgaWYgKCFkYXRhRHJhd0J5SWQ/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbW92ZUJ5SXRlbSA9IChpdGVtOiBJRHJhd0xpbmVEYXRhSW5wdXQpID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlRWxlbWVudE9mUG9pbnRzKGl0ZW0ucG9pbnRzKTtcbiAgICAgIGl0ZW0ucG9pbnRzLnNlcGFyYXRlZFBvaW50cz8uZm9yRWFjaChzZXBhcmF0ZWRQb2ludHMgPT4gdGhpcy5yZW1vdmVFbGVtZW50T2ZQb2ludHMoc2VwYXJhdGVkUG9pbnRzKSk7XG5cbiAgICB9O1xuXG4gICAgaWYgKCFwb2ludHM/Lmxlbmd0aCkge1xuICAgICAgZGF0YURyYXdCeUlkLmZvckVhY2goaXRlbSA9PiByZW1vdmVCeUl0ZW0oaXRlbSkpO1xuICAgICAgdGhpcy5kYXRhRHJhdyA9IHRoaXMuZGF0YURyYXcuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pZCAhPT0gaWQpO1xuICAgICAgdGhpcy51cGRhdGVWaWV3Qm94KCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwb2ludHMuZm9yRWFjaChwb2ludCA9PiB7XG4gICAgICBjb25zdCBkYXRhRHJhd1JlbW92ZUJ5UG9pbnQgPSBkYXRhRHJhd0J5SWQuZmluZChpdGVtID0+IGl0ZW0ucG9pbnRzLnN0YXJ0LnggPT09IHBvaW50LnN0YXJ0LnggJiYgaXRlbS5wb2ludHMuc3RhcnQueSA9PT0gcG9pbnQuc3RhcnQueSAmJiBpdGVtLnBvaW50cy5lbmQueCA9PT0gcG9pbnQuZW5kLnggJiYgaXRlbS5wb2ludHMuZW5kLnkgPT09IHBvaW50LmVuZC55KTtcblxuICAgICAgaWYgKGRhdGFEcmF3UmVtb3ZlQnlQb2ludCkge1xuICAgICAgICBkYXRhRHJhd1JlbW92ZUJ5UG9pbnQuaXNSZW1vdmUgPSB0cnVlO1xuICAgICAgICByZW1vdmVCeUl0ZW0oZGF0YURyYXdSZW1vdmVCeVBvaW50KTtcbiAgICAgICAgdGhpcy5kYXRhRHJhdyA9IHRoaXMuZGF0YURyYXcuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pZCAhPT0gaWQgJiYgIWl0ZW0uaXNSZW1vdmUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMudXBkYXRlVmlld0JveCgpO1xuXG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVJlYWNoYWJsZVBvaW50UmFuZ2UoaWRzOiBBcnJheTxzdHJpbmc+KSB7XG4gICAgdGhpcy5jbGVhclJlY3QoKTtcbiAgICBpZiAoIWlkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZHMuZm9yRWFjaChpZCA9PiB7XG4gICAgICBjb25zdCBpdGVtUmVtb3ZlID0gdGhpcy5kYXRhUmVhY2hhYmxlUG9pbnRSYW5nZT8uZmluZChpdGVtID0+IGl0ZW0uaWQgPT09IGlkKTtcblxuICAgICAgaWYgKCFpdGVtUmVtb3ZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGl0ZW1SZW1vdmUub25EZXN0cm95RXZlbnQ/Lm5leHQoKTtcbiAgICAgIGl0ZW1SZW1vdmUuZWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICB0aGlzLmRhdGFSZWFjaGFibGVQb2ludFJhbmdlID0gdGhpcy5kYXRhUmVhY2hhYmxlUG9pbnRSYW5nZT8uZmlsdGVyKGl0ZW0gPT4gaXRlbS5pZCAhPT0gaWQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydFByb2Nlc3NEYXRhUm93KGRhdGFEcmF3OiBBcnJheTxJRHJhd0xpbmVEYXRhSW5wdXQ+KSB7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGRhdGFEcmF3LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGNvbnN0IHsgcGF0aEVsZW1lbnQsIGFycm93RWxlbWVudCwgY2lyY2xlU3RhcnRFbGVtZW50LCBjaXJjbGVFbmRFbGVtZW50IH0gPSB0aGlzLmNyZWF0ZVBhdGhBbmRBcnJvd0VsZW1lbnQoaXRlbS5pZCk7XG5cbiAgICAgICAgaXRlbS5wb2ludHMub2JzdGFjbGVSZWN0Py5mb3JFYWNoKGRhdGEgPT4gdGhpcy5hZGRSZWN0KCdyZWN0JywgZGF0YSkpO1xuICAgICAgICBpdGVtLnBvaW50cy5wYXRoRWxlbWVudCA9IHBhdGhFbGVtZW50O1xuICAgICAgICBpdGVtLnBvaW50cy5hcnJvd0VsZW1lbnQgPSBhcnJvd0VsZW1lbnQ7XG4gICAgICAgIGlmIChpdGVtLnN0YXJ0Q2lyY2xlKSB7XG4gICAgICAgICAgaXRlbS5wb2ludHMuY2lyY2xlU3RhcnRFbGVtZW50ID0gY2lyY2xlU3RhcnRFbGVtZW50O1xuICAgICAgICAgIHRoaXMuc3ZnRWxlbWVudC5hcHBlbmQoY2lyY2xlU3RhcnRFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5lbmRDaXJjbGUpIHtcbiAgICAgICAgICBpdGVtLnBvaW50cy5jaXJjbGVFbmRFbGVtZW50ID0gY2lyY2xlRW5kRWxlbWVudDtcbiAgICAgICAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKGNpcmNsZUVuZEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGl0ZW0ucG9pbnRzLm9uRGVzdHJveUV2ZW50ID0gbmV3IFN1YmplY3QoKTtcbiAgICAgICAgdGhpcy5kcmF3TGluZShpdGVtKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy51cGRhdGVWaWV3Qm94KCk7XG4gICAgfSk7XG4gIH1cbiAgcHJpdmF0ZSBzdGFydFByb2Nlc3NEYXRhUmVhY2hhYmxlUG9pbnRSYW5nZShkYXRhOiBBcnJheTxJUmVhY2hhYmxlUG9pbnRSYW5nZT4pIHtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICBpdGVtLm9uRGVzdHJveUV2ZW50ID0gbmV3IFN1YmplY3QoKTtcbiAgICAgICAgaXRlbS5lbGVtZW50ID0gdGhpcy5jcmVhdGVQYXRoQW5kQXJyb3dFbGVtZW50KGl0ZW0uaWQpLmNpcmNsZUVuZEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3ZnRWxlbWVudC5hcHBlbmQoaXRlbS5lbGVtZW50KTtcbiAgICAgICAgdGhpcy51cGRhdGVBdHRyaWJ1dGVDaXJjbGUoaXRlbS5lbGVtZW50LCBpdGVtLmlkLCBpdGVtLCBpdGVtLnN0eWxlKTtcbiAgICAgICAgdGhpcy5vbkRyYXdMaW5lRW5kLnBpcGUodGFrZVVudGlsKGl0ZW0ub25EZXN0cm95RXZlbnQpLCB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpKS5zdWJzY3JpYmUoZXZlbnREYXRhID0+IHtcbiAgICAgICAgICBjb25zdCB7IGRhdGFMaW5lLCBldmVudCB9ID0gZXZlbnREYXRhO1xuXG4gICAgICAgICAgaWYgKCFjaGVja01vdXNlT3ZlckluQ29udGFpbmVyKGV2ZW50LCBpdGVtLmVsZW1lbnQgYXMgdW5rbm93biBhcyBIVE1MRWxlbWVudCkgfHwgIWRhdGFMaW5lLnJlZiB8fCAhaXRlbS5yZWYpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpdGVtLmlkQ29ubmVjdGVkID0gZXZlbnREYXRhLmRhdGFMaW5lLmlkO1xuICAgICAgICAgIGV2ZW50RGF0YS5kYXRhTGluZS5pZENvbm5lY3RlZCA9IGl0ZW0uaWQ7XG4gICAgICAgICAgdGhpcy5vdXRDb25uZWN0ZWQuZW1pdCh7XG4gICAgICAgICAgICBkYXRhTGluZTogZGF0YUxpbmUucmVmLFxuICAgICAgICAgICAgZGF0YVJlYWNoYWJsZVBvaW50UmFuZ2U6IGl0ZW0ucmVmXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnVwZGF0ZVZpZXdCb3goKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlRWxlbWVudE9mUG9pbnRzKHBvaW50czogSVBvaW50cykge1xuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBwb2ludHMub25EZXN0cm95RXZlbnQ/Lm5leHQoKTtcbiAgICAgIHBvaW50cy5vbkRlc3Ryb3lFdmVudD8uY29tcGxldGUoKTtcbiAgICAgIHBvaW50cz8ucGF0aEVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgcG9pbnRzPy5hcnJvd0VsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgcG9pbnRzPy5jaXJjbGVTdGFydEVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgcG9pbnRzLmNpcmNsZUVuZEVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmF3TGluZShkYXRhOiBJRHJhd0xpbmVEYXRhSW5wdXQpIHtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgeyBwb2ludHMsIG1vZGUgfSA9IGRhdGE7XG4gICAgICBsZXQgeyBjdXJ2ZSB9ID0gZGF0YT8ubGluZVN0eWxlIHx8IHt9O1xuXG4gICAgICBpZiAobW9kZSAhPT0gJ3F1YXJ0LWluJykge1xuICAgICAgICBjdXJ2ZSA9IGN1cnZlID8/IDEwO1xuICAgICAgfVxuICAgICAgY29uc3QgcHJlTGVuZ3RoU2VwYXJhdGVkUG9pbnRzID0gcG9pbnRzLnNlcGFyYXRlZFBvaW50cz8ubGVuZ3RoO1xuXG4gICAgICBwb2ludHMuc2VwYXJhdGVkUG9pbnRzPy5mb3JFYWNoKHNlcGFyYXRlZFBvaW50cyA9PiB0aGlzLnJlbW92ZUVsZW1lbnRPZlBvaW50cyhzZXBhcmF0ZWRQb2ludHMpKTtcbiAgICAgIHBvaW50cy5zZXBhcmF0ZWRQb2ludHMgPSBbXTtcbiAgICAgIE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbC5TVEFSVF9NT0RFID0gJ3JpZ2h0LWxlZnQnO1xuICAgICAgaWYgKGRhdGEuc3RhcnRFbmRNb2RlKSB7XG4gICAgICAgIE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbC5TVEFSVF9NT0RFID0gZGF0YS5zdGFydEVuZE1vZGU7XG4gICAgICB9XG4gICAgICB0aGlzLmNhbGN1bGF0b3JTZXBhcmF0ZWRQb2ludHMoZGF0YS5pZCwgcG9pbnRzLCBjdXJ2ZSB8fCAxMCwgcG9pbnRzLnNlcGFyYXRlZFBvaW50cywgcG9pbnRzLm9ic3RhY2xlUmVjdCB8fCBbXSk7XG4gICAgICBpZiAoIXByZUxlbmd0aFNlcGFyYXRlZFBvaW50cyAmJiBwb2ludHMuc2VwYXJhdGVkUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnJlbW92ZUVsZW1lbnRPZlBvaW50cyhwb2ludHMpO1xuICAgICAgICBjb25zdCB7IHBhdGhFbGVtZW50LCBhcnJvd0VsZW1lbnQgfSA9IHRoaXMuY3JlYXRlUGF0aEFuZEFycm93RWxlbWVudChkYXRhLmlkKTtcblxuICAgICAgICBwb2ludHMucGF0aEVsZW1lbnQgPSBwYXRoRWxlbWVudDtcbiAgICAgICAgcG9pbnRzLmFycm93RWxlbWVudCA9IGFycm93RWxlbWVudDtcbiAgICAgICAgcG9pbnRzLmluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIXBvaW50cy5zZXBhcmF0ZWRQb2ludHM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmJ1aWxkUGF0aEFuZERyYXcoZGF0YSwgcG9pbnRzLCBtb2RlKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBvaW50cy5zZXBhcmF0ZWRQb2ludHMuZm9yRWFjaChzZXBhcmF0ZWRQb2ludHMgPT4ge1xuICAgICAgICB0aGlzLmJ1aWxkUGF0aEFuZERyYXcoZGF0YSwgc2VwYXJhdGVkUG9pbnRzLCBzZXBhcmF0ZWRQb2ludHMubW9kZSB8fCBtb2RlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVWaWV3Qm94KHZpZXdCb3hDb25maWc/OiBJVmlld0JveENvbmZpZykge1xuICAgIGlmICh2aWV3Qm94Q29uZmlnKSB7XG4gICAgICB0aGlzLnZpZXdCb3hDb25maWcgPSB2aWV3Qm94Q29uZmlnO1xuICAgIH1cbiAgICBjb25zdCB4UG9pbnRzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQoWzBdKTtcbiAgICBjb25zdCB5UG9pbnRzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQoWzBdKTtcblxuICAgIGNvbnN0IGFkZFBvaW50cyA9IChwb2ludHM6IElQb2ludHMpID0+IHtcbiAgICAgIHhQb2ludHMuYWRkKHBvaW50cy5zdGFydC54KTtcbiAgICAgIHhQb2ludHMuYWRkKHBvaW50cy5lbmQueCk7XG4gICAgICB5UG9pbnRzLmFkZChwb2ludHMuc3RhcnQueSk7XG4gICAgICB5UG9pbnRzLmFkZChwb2ludHMuZW5kLnkpO1xuICAgIH07XG5cbiAgICB0aGlzLmRhdGFEcmF3Py5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgY29uc3QgcG9pbnRzID0gaXRlbS5wb2ludHM7XG5cbiAgICAgIGFkZFBvaW50cyhwb2ludHMpO1xuICAgICAgcG9pbnRzLnNlcGFyYXRlZFBvaW50cz8uZm9yRWFjaChzZXBhcmF0ZWRQb2ludHMgPT4gYWRkUG9pbnRzKHNlcGFyYXRlZFBvaW50cykpO1xuICAgICAgcG9pbnRzLm9ic3RhY2xlUmVjdD8uZm9yRWFjaChvYnN0YWNsZVJlY3QgPT4ge1xuICAgICAgICBhZGRQb2ludHMoe1xuICAgICAgICAgIHN0YXJ0OiB7IHg6IG9ic3RhY2xlUmVjdC54IC0gKG9ic3RhY2xlUmVjdC5nYXBYT2JzdGFjbGVSZWN0IHx8IDgpLCB5OiBvYnN0YWNsZVJlY3QueSAtIChvYnN0YWNsZVJlY3QuZ2FwWU9ic3RhY2xlUmVjdCB8fCA4KSB9LFxuICAgICAgICAgIGVuZDogeyB4OiBvYnN0YWNsZVJlY3QueCArIG9ic3RhY2xlUmVjdC53aWR0aCArIChvYnN0YWNsZVJlY3QuZ2FwWE9ic3RhY2xlUmVjdCB8fCA4KSAqIDIsIHk6IG9ic3RhY2xlUmVjdC55ICsgb2JzdGFjbGVSZWN0LmhlaWdodCArIChvYnN0YWNsZVJlY3QuZ2FwWU9ic3RhY2xlUmVjdCB8fCA4KSAqIDIgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgeE1heCA9IHRoaXMudmlld0JveENvbmZpZz8ud2lkdGggPz8gKHhQb2ludHMuc2l6ZSA/IE1hdGgubWF4KC4uLnhQb2ludHMpIDogMCkgKyAxNDtcbiAgICBjb25zdCB5TWF4ID0gdGhpcy52aWV3Qm94Q29uZmlnPy5oZWlnaHQgPz8gKHlQb2ludHMuc2l6ZSA/IE1hdGgubWF4KC4uLnlQb2ludHMpIDogMCkgKyAxNDtcblxuICAgIGlmICghdGhpcy52aWV3Qm94Q29uZmlnPy5pZ25vcmVWaWV3Qm94KSB7XG4gICAgICBjb25zdCByZWN0U3ZnRWxlbWVudCA9IHRoaXMuc3ZnRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgdGhpcy5zdmdFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnLCBgJHt0aGlzLnZpZXdCb3hDb25maWc/Lm1pblggPz8gcmVjdFN2Z0VsZW1lbnQueH0gJHt0aGlzLnZpZXdCb3hDb25maWc/Lm1pblkgPz8gcmVjdFN2Z0VsZW1lbnQueX0gJHt4TWF4fSAke3lNYXh9YCk7XG4gICAgfVxuICAgIHRoaXMuc3ZnRWxlbWVudD8uc2V0QXR0cmlidXRlKCd3aWR0aCcsIGAke3hNYXggPz8gMH1gKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7eU1heCA/PyAwfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BvaW50SW5zaWRlU3F1YXJlKHBvaW50OiBJUG9pbnQsIHNxdWFyZTogSVJlY3QpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHgsIHkgfSA9IHBvaW50O1xuICAgIGNvbnN0IHsgeDogc3F1YXJlWCwgeTogc3F1YXJlWSwgd2lkdGgsIGhlaWdodCB9ID0gc3F1YXJlO1xuXG4gICAgcmV0dXJuIHggPj0gc3F1YXJlWCAmJiB4IDw9IHNxdWFyZVggKyB3aWR0aCAmJiB5ID49IHNxdWFyZVkgJiYgeSA8PSBzcXVhcmVZICsgaGVpZ2h0O1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdG9yU2VwYXJhdGVkUG9pbnRzKG5hbWU6IHN0cmluZywgcG9pbnRzOiBJUG9pbnRzLCBjdXJ2ZTogbnVtYmVyLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+LCBvYnN0YWNsZVJlY3RzOiBBcnJheTxJUmVjdD4pIHtcbiAgICBpZiAoIW9ic3RhY2xlUmVjdHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudFN0YXJ0ID0gb2JzdGFjbGVSZWN0cy5maW5kKGl0ZW0gPT4gdGhpcy5pc1BvaW50SW5zaWRlU3F1YXJlKHBvaW50cy5zdGFydCwgaXRlbSkpO1xuICAgIGNvbnN0IGVsZW1lbnRFbmQgPSBvYnN0YWNsZVJlY3RzLmZpbmQoaXRlbSA9PiB0aGlzLmlzUG9pbnRJbnNpZGVTcXVhcmUocG9pbnRzLmVuZCwgaXRlbSkpO1xuXG4gICAgaWYgKHRoaXMudmlld0JveENvbmZpZz8ubWFyZ2luQmV0d2VlbkVsZW1lbnQpIHtcbiAgICAgIE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbC5FTEVNRU5UX01BUkdJTl9CRVRXRUVOX0JSQU5DSF9ERUZBVUxUID0gdGhpcy52aWV3Qm94Q29uZmlnPy5tYXJnaW5CZXR3ZWVuRWxlbWVudCA/PyAzMjtcbiAgICB9XG4gICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLnNldFhZQ29ubmVjdEVsZW1lbnRzKGVsZW1lbnRTdGFydCA/PyB7IC4uLnBvaW50cy5zdGFydCwgd2lkdGg6IDEsIGhlaWdodDogMSB9LCBlbGVtZW50RW5kID8/IHsgLi4ucG9pbnRzLmVuZCwgd2lkdGg6IDEsIGhlaWdodDogMSB9LCBvYnN0YWNsZVJlY3RzLCBzZXBhcmF0ZWRQb2ludHMsIGN1cnZlKTtcbiAgICBzZXBhcmF0ZWRQb2ludHM/LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtLnBhdGhFbGVtZW50ID0gdGhpcy5jcmVhdGVQYXRoQW5kQXJyb3dFbGVtZW50KG5hbWUpLnBhdGhFbGVtZW50O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFBhdGhBbmREcmF3KGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCwgcG9pbnRzOiBJUG9pbnRzLCBtb2RlPzogVFlQRV9NT0RFKSB7XG4gICAgbGV0IGRQYXRoID0ge30gYXMgSUF0dHJpYnV0ZURPblBhdGg7XG4gICAgY29uc3Qgc3R5bGVDb25maWcgPSB7XG4gICAgICBzdHJva2U6IGRhdGEubGluZVN0eWxlPy5zdHJva2UgPz8gJyM5Q0EyQUQnLFxuICAgICAgc3Ryb2tlRGFzaGFycmF5OiBkYXRhLmxpbmVTdHlsZT8uc3Ryb2tlRGFzaGFycmF5LFxuICAgICAgc3Ryb2tlV2lkdGg6IGRhdGEubGluZVN0eWxlPy5zdHJva2VXaWR0aCA/PyAnMXB4JyxcbiAgICAgIGZpbGw6IGRhdGEubGluZVN0eWxlPy5maWxsID8/ICdub25lJyxcbiAgICAgIGN1cnZlOiBkYXRhLmxpbmVTdHlsZT8uY3VydmUgPz8gMTAsXG4gICAgICBkaXN0YW5jZVBvaW50OiBkYXRhLmxpbmVTdHlsZT8uZGlzdGFuY2VQb2ludCA/PyAxMFxuICAgIH07XG5cbiAgICBwb2ludHMucGF0aEVsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgc3R5bGVDb25maWcuc3Ryb2tlKTtcbiAgICBwb2ludHMucGF0aEVsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnZmlsbCcsIHN0eWxlQ29uZmlnLmZpbGwpO1xuICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBzdHlsZUNvbmZpZy5zdHJva2VXaWR0aCk7XG4gICAgaWYgKHN0eWxlQ29uZmlnLnN0cm9rZURhc2hhcnJheSkge1xuICAgICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS1kYXNoYXJyYXknLCBzdHlsZUNvbmZpZy5zdHJva2VEYXNoYXJyYXkpO1xuICAgIH1cbiAgICBsZXQgeyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9ID0gc3R5bGVDb25maWc7XG5cbiAgICBtb2RlID0gbW9kZSB8fCBcInF1YXJ0LWluXCI7XG4gICAgaWYgKG1vZGUgIT09ICdxdWFydC1pbicpIHtcbiAgICAgIGN1cnZlID0gY3VydmUgPz8gMTA7XG4gICAgICBkaXN0YW5jZVBvaW50ID0gZGlzdGFuY2VQb2ludCA/PyAxMDtcbiAgICB9XG4gICAgaWYgKG1vZGUgPT09ICdxdWFydC1pbicgfHwgcG9pbnRzLnN0YXJ0LnggPT09IHBvaW50cy5lbmQueCB8fCBwb2ludHMuc3RhcnQueSA9PT0gcG9pbnRzLmVuZC55KSB7XG4gICAgICB0aGlzLmRyYXdCYWxhbmNlZEN1cnZlKGRQYXRoLCBwb2ludHMpO1xuXG4gICAgICBpZiAobW9kZSA9PT0gJ3F1YXJ0LWluJykge1xuICAgICAgICBkUGF0aCA9IHt9IGFzIElBdHRyaWJ1dGVET25QYXRoO1xuICAgICAgICB0aGlzLmRyYXdCZW5kQm90aEVuZHNDdXJ2ZShkUGF0aCwgcG9pbnRzKTtcbiAgICAgIH1cbiAgICAgIHBvaW50cy5wYXRoRWxlbWVudD8uc2V0QXR0cmlidXRlKCdkJywgdGhpcy5idWlsREF0dHJpYnV0ZVRvU3RyaW5nKGRQYXRoKSk7XG4gICAgICB0aGlzLmRyYXdSZWN0QW5kSW5pdEV2ZW50KGRhdGEsIG1vZGUpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY2FsY3VsYXRvckRpc3RhbmNlUG9pbnRBbmRDdXJ2ZShwb2ludHMsIGRpc3RhbmNlUG9pbnQsIGN1cnZlLCBtb2RlKTtcblxuICAgIGRpc3RhbmNlUG9pbnQgPSByZXN1bHQuZGlzdGFuY2VQb2ludDtcbiAgICBjdXJ2ZSA9IHJlc3VsdC5jdXJ2ZTtcblxuICAgIHRoaXMuYnVpbGREQXR0cmlidXRlQnlQb2ludEVuZE1vZGVIb3Jpem9udGFsKGRQYXRoLCBwb2ludHMsIGRpc3RhbmNlUG9pbnQgfHwgMCwgY3VydmUgfHwgMCwgbW9kZSk7XG4gICAgdGhpcy5idWlsZERBdHRyaWJ1dGVCeVBvaW50RW5kTW9kZVZlcnRpY2FsKGRQYXRoLCBwb2ludHMsIGRpc3RhbmNlUG9pbnQgfHwgMCwgY3VydmUgfHwgMCwgbW9kZSk7XG4gICAgcG9pbnRzLnBhdGhFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmJ1aWxEQXR0cmlidXRlVG9TdHJpbmcoZFBhdGgpKTtcbiAgICB0aGlzLmRyYXdSZWN0QW5kSW5pdEV2ZW50KGRhdGEsIG1vZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdG9yRGlzdGFuY2VQb2ludEFuZEN1cnZlKHBvaW50czogSVBvaW50cywgZGlzdGFuY2VQb2ludDogbnVtYmVyLCBjdXJ2ZTogbnVtYmVyLCBtb2RlOiBUWVBFX01PREUpIHtcbiAgICBpZiAoKCFtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbCcpICYmICFtb2RlLmluY2x1ZGVzKCdob3Jpem9udGFsJykpKSB7XG4gICAgICByZXR1cm4geyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9O1xuICAgIH1cbiAgICBjb25zdCBnYXBYID0gTWF0aC5hYnMocG9pbnRzLnN0YXJ0LnggLSBwb2ludHMuZW5kLngpO1xuICAgIGNvbnN0IGdhcFkgPSBNYXRoLmFicyhwb2ludHMuc3RhcnQueSAtIHBvaW50cy5lbmQueSk7XG4gICAgY29uc3QgbXVsdGlwbGllckN1cnZlID0gbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpID8gMSA6IDI7XG4gICAgY29uc3QgbXVsdGlwbGllckRpc3RhbmNlID0gbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpID8gMiA6IDE7XG5cbiAgICBpZiAoIW1vZGUuaW5jbHVkZXMoJ3NpbmdsZS1jdXJ2ZScpKSB7XG4gICAgICBpZiAoZ2FwWCA8IGRpc3RhbmNlUG9pbnQgKiBtdWx0aXBsaWVyRGlzdGFuY2UgKyBjdXJ2ZSAqIG11bHRpcGxpZXJDdXJ2ZSkge1xuICAgICAgICBkaXN0YW5jZVBvaW50ID0gY3VydmUgPSBnYXBYIC8gMztcbiAgICAgIH1cbiAgICAgIGlmIChnYXBZIDwgZGlzdGFuY2VQb2ludCAqIG11bHRpcGxpZXJEaXN0YW5jZSArIGN1cnZlICogbXVsdGlwbGllckN1cnZlKSB7XG4gICAgICAgIGRpc3RhbmNlUG9pbnQgPSBjdXJ2ZSA9IGdhcFkgLyAzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBjdXJ2ZSwgZGlzdGFuY2VQb2ludCB9O1xuICAgIH1cbiAgICBjb25zdCBtaW5HYXAgPSBNYXRoLm1pbihnYXBYLCBnYXBZKTtcblxuICAgIGlmIChtaW5HYXAgPCBkaXN0YW5jZVBvaW50KSB7XG4gICAgICBkaXN0YW5jZVBvaW50ID0gbWluR2FwO1xuICAgIH1cbiAgICBpZiAobWluR2FwIDwgY3VydmUpIHtcbiAgICAgIGN1cnZlID0gbWluR2FwO1xuICAgIH1cblxuICAgIHJldHVybiB7IGN1cnZlLCBkaXN0YW5jZVBvaW50IH07XG4gIH1cblxuICBwcml2YXRlIGRyYXdSZWN0QW5kSW5pdEV2ZW50KGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCwgbW9kZTogVFlQRV9NT0RFKSB7XG4gICAgY29uc3QgcG9pbnRzID0gZGF0YS5wb2ludHM7XG5cbiAgICB0aGlzLnVwZGF0ZVN0eWxlQXJyb3cocG9pbnRzLCBtb2RlLCBkYXRhKTtcbiAgICBpZiAoZGF0YS5zdGFydENpcmNsZSAmJiBwb2ludHMuY2lyY2xlU3RhcnRFbGVtZW50KSB7XG4gICAgICB0aGlzLnVwZGF0ZUF0dHJpYnV0ZUNpcmNsZShwb2ludHMuY2lyY2xlU3RhcnRFbGVtZW50LCBkYXRhLmlkLCBwb2ludHMuc3RhcnQsIGRhdGEuc3RhcnRDaXJjbGVTdHlsZSk7XG4gICAgfVxuICAgIGlmIChkYXRhLmVuZENpcmNsZSAmJiBwb2ludHMuY2lyY2xlRW5kRWxlbWVudCkge1xuICAgICAgdGhpcy51cGRhdGVBdHRyaWJ1dGVDaXJjbGUocG9pbnRzLmNpcmNsZUVuZEVsZW1lbnQsIGRhdGEuaWQsIHBvaW50cy5lbmQsIGRhdGEuZW5kQ2lyY2xlU3R5bGUpO1xuICAgIH1cbiAgICB0aGlzLmluaXRFdmVudChkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0JhbGFuY2VkQ3VydmUoZFBhdGg6IElBdHRyaWJ1dGVET25QYXRoLCBwb2ludHM6IElQb2ludHMpIHtcbiAgICBkUGF0aC5NID0geyB4OiBwb2ludHMuc3RhcnQueCwgeTogcG9pbnRzLnN0YXJ0LnkgfTtcbiAgICBkUGF0aC5RID0gW3sgeDogcG9pbnRzLnN0YXJ0LnggKyAocG9pbnRzLmVuZC54IC0gcG9pbnRzLnN0YXJ0LngpIC8gNCwgeTogcG9pbnRzLnN0YXJ0LnkgKyAocG9pbnRzLmVuZC55IC0gcG9pbnRzLnN0YXJ0LnkpIC8gMiB9LCB7IHg6IHBvaW50cy5zdGFydC54ICsgKHBvaW50cy5lbmQueCAtIHBvaW50cy5zdGFydC54KSAvIDIsIHk6IHBvaW50cy5zdGFydC55ICsgKHBvaW50cy5lbmQueSAtIHBvaW50cy5zdGFydC55KSAvIDIgfV07XG4gICAgZFBhdGguUTIgPSBbeyB4OiBwb2ludHMuZW5kLnggLSAocG9pbnRzLmVuZC54IC0gcG9pbnRzLnN0YXJ0LngpIC8gNCwgeTogcG9pbnRzLnN0YXJ0LnkgKyAocG9pbnRzLmVuZC55IC0gcG9pbnRzLnN0YXJ0LnkpIC8gMiB9LCB7IHg6IHBvaW50cy5lbmQueCwgeTogcG9pbnRzLmVuZC55IH1dO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmF3QmVuZEJvdGhFbmRzQ3VydmUoZFBhdGg6IElBdHRyaWJ1dGVET25QYXRoLCBwb2ludHM6IElQb2ludHMpIHtcbiAgICBjb25zdCBwb2ludFhDdXJ2ZSA9IChwb2ludHMuc3RhcnQueCArIHBvaW50cy5lbmQueCkgKiAwLjU7XG4gICAgY29uc3QgcG9pbnRDb250cm9sMSA9IHsgeDogcG9pbnRYQ3VydmUsIHk6IHBvaW50cy5zdGFydC55IH07XG4gICAgY29uc3QgcG9pbnRDb250cm9sMiA9IHsgeDogcG9pbnRYQ3VydmUsIHk6IHBvaW50cy5lbmQueSB9O1xuXG4gICAgZFBhdGguTSA9IHsgeDogcG9pbnRzLnN0YXJ0LngsIHk6IHBvaW50cy5zdGFydC55IH07XG4gICAgZFBhdGguQyA9IFt7IHg6IHBvaW50Q29udHJvbDEueCwgeTogcG9pbnRDb250cm9sMS55IH0sIHsgeDogcG9pbnRDb250cm9sMi54LCB5OiBwb2ludENvbnRyb2wyLnkgfSwgeyB4OiBwb2ludHMuZW5kLngsIHk6IHBvaW50cy5lbmQueSB9XTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGREQXR0cmlidXRlQnlQb2ludEVuZE1vZGVIb3Jpem9udGFsKGRQYXRoOiBJQXR0cmlidXRlRE9uUGF0aCwgcG9pbnRzOiBJUG9pbnRzLCBkaXN0YW5jZVBvaW50OiBudW1iZXIsIGN1cnZlOiBudW1iZXIsIG1vZGU6IFRZUEVfTU9ERSkge1xuICAgIGlmICghbW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbCcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG11bHRpcGxpZXJYID0gcG9pbnRzLnN0YXJ0LnggPCBwb2ludHMuZW5kLnggPyAtMSA6IDE7XG4gICAgY29uc3QgbXVsdGlwbGllclkgPSBwb2ludHMuc3RhcnQueSA8IHBvaW50cy5lbmQueSA/IDEgOiAtMTtcbiAgICBjb25zdCByZXZlcnNlTXVsdGlwbGllciA9IC0xO1xuXG4gICAgZFBhdGguTSA9IHsgeDogcG9pbnRzLnN0YXJ0LngsIHk6IHBvaW50cy5zdGFydC55IH07XG4gICAgZFBhdGguTCA9IHsgeDogcG9pbnRzLmVuZC54ICsgKChkaXN0YW5jZVBvaW50ICogMiArIGN1cnZlKSAqIG11bHRpcGxpZXJYKSwgeTogcG9pbnRzLnN0YXJ0LnkgfTtcbiAgICBpZiAobW9kZS5pbmNsdWRlcygnaG9yaXpvbnRhbC1zaW5nbGUnKSkge1xuICAgICAgZFBhdGguTC54ID0gcG9pbnRzLmVuZC54ICsgKGN1cnZlICogbXVsdGlwbGllclgpO1xuICAgIH1cbiAgICBkUGF0aC5RID0gW3sgeDogZFBhdGguTC54ICsgKGN1cnZlICogbXVsdGlwbGllclggKiByZXZlcnNlTXVsdGlwbGllciksIHk6IHBvaW50cy5zdGFydC55IH0sIHsgeDogZFBhdGguTC54ICsgKGN1cnZlICogbXVsdGlwbGllclggKiByZXZlcnNlTXVsdGlwbGllciksIHk6IHBvaW50cy5zdGFydC55ICsgKGN1cnZlICogbXVsdGlwbGllclkpIH1dO1xuICAgIGRQYXRoLkwyID0geyB4OiBkUGF0aC5RWzFdLngsIHk6IHBvaW50cy5lbmQueSArIChjdXJ2ZSAqIG11bHRpcGxpZXJZICogcmV2ZXJzZU11bHRpcGxpZXIpIH07XG4gICAgaWYgKG1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwtc2luZ2xlJykpIHtcbiAgICAgIGRQYXRoLkwyID0gcG9pbnRzLmVuZDtcbiAgICB9XG4gICAgaWYgKG1vZGUgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgZFBhdGguUTIgPSBbeyB4OiBkUGF0aC5MMi54LCB5OiBwb2ludHMuZW5kLnkgfSwgeyB4OiBkUGF0aC5MMi54ICsgKGRpc3RhbmNlUG9pbnQgKiBtdWx0aXBsaWVyWCAqIHJldmVyc2VNdWx0aXBsaWVyKSwgeTogcG9pbnRzLmVuZC55IH1dO1xuICAgICAgZFBhdGguTDMgPSB7IHg6IHBvaW50cy5lbmQueCwgeTogcG9pbnRzLmVuZC55IH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBidWlsZERBdHRyaWJ1dGVCeVBvaW50RW5kTW9kZVZlcnRpY2FsKGRQYXRoOiBJQXR0cmlidXRlRE9uUGF0aCwgcG9pbnRzOiBJUG9pbnRzLCBkaXN0YW5jZVBvaW50OiBudW1iZXIsIGN1cnZlOiBudW1iZXIsIG1vZGU6IFRZUEVfTU9ERSkge1xuICAgIGlmICghbW9kZS5pbmNsdWRlcygndmVydGljYWwnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtdWx0aXBsaWVyWCA9IHBvaW50cy5zdGFydC54IDwgcG9pbnRzLmVuZC54ID8gLTEgOiAxO1xuICAgIGNvbnN0IG11bHRpcGxpZXJZID0gcG9pbnRzLnN0YXJ0LnkgPCBwb2ludHMuZW5kLnkgPyAxIDogLTE7XG4gICAgY29uc3QgcmV2ZXJzZU11bHRpcGxpZXIgPSAtMTtcblxuICAgIGRQYXRoLk0gPSBwb2ludHMuc3RhcnQ7XG4gICAgZFBhdGguTCA9IHsgeDogcG9pbnRzLnN0YXJ0LngsIHk6IHBvaW50cy5zdGFydC55ICsgKGRpc3RhbmNlUG9pbnQgKiBtdWx0aXBsaWVyWSkgfTtcbiAgICBpZiAobW9kZS5pbmNsdWRlcygndmVydGljYWwtc2luZ2xlJykpIHtcbiAgICAgIGRQYXRoLkwueSA9IHBvaW50cy5lbmQueSArIChkaXN0YW5jZVBvaW50ICogbXVsdGlwbGllclkgKiByZXZlcnNlTXVsdGlwbGllcik7XG4gICAgfVxuICAgIGRQYXRoLlEgPSBbeyB4OiBkUGF0aC5MLngsIHk6IGRQYXRoLkwueSArIChjdXJ2ZSAqIG11bHRpcGxpZXJZKSB9LCB7IHg6IGRQYXRoLkwueCArIChjdXJ2ZSAqIG11bHRpcGxpZXJYICogcmV2ZXJzZU11bHRpcGxpZXIpLCB5OiBkUGF0aC5MLnkgKyAoY3VydmUgKiBtdWx0aXBsaWVyWSkgfV07XG4gICAgZFBhdGguTDIgPSB7IHg6IHBvaW50cy5lbmQueCArICgoY3VydmUgKiAyKSAqIG11bHRpcGxpZXJYKSwgeTogZFBhdGguUVsxXS55IH07XG4gICAgaWYgKG1vZGUuaW5jbHVkZXMoJ3ZlcnRpY2FsLXNpbmdsZScpKSB7XG4gICAgICBkUGF0aC5MMiA9IHBvaW50cy5lbmQ7XG4gICAgfVxuICAgIGlmIChtb2RlID09PSAndmVydGljYWwnKSB7XG4gICAgICBkUGF0aC5RMiA9IFt7IHg6IHBvaW50cy5lbmQueCwgeTogZFBhdGguTDIueSB9LCB7IHg6IHBvaW50cy5lbmQueCwgeTogZFBhdGguTDIueSArIChjdXJ2ZSAqIG11bHRpcGxpZXJZKSB9XTtcbiAgICAgIGRQYXRoLkwzID0geyB4OiBwb2ludHMuZW5kLngsIHk6IHBvaW50cy5lbmQueSB9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYnVpbERBdHRyaWJ1dGVUb1N0cmluZyhkQXR0cmlidXRlOiBJQXR0cmlidXRlRE9uUGF0aCk6IHN0cmluZyB7XG4gICAgbGV0IGRTdHJpbmcgPSAnJztcblxuICAgIE9iamVjdC5rZXlzKGRBdHRyaWJ1dGUpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBnZXQoZEF0dHJpYnV0ZSwga2V5KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgY29uc3QgW3BvaW50MSwgcG9pbnQyLCBwb2ludDNdID0gZGF0YTtcblxuICAgICAgICBkU3RyaW5nID0gYCR7ZFN0cmluZ30ke2tleS5yZXBsYWNlKC9cXGQvZywgJycpfSR7cG9pbnQxLnh9LCR7cG9pbnQxLnl9ICR7cG9pbnQyLnh9LCR7cG9pbnQyLnl9JHtwb2ludDMgPyAnICcgKyBwb2ludDMueCArICcsJyArIHBvaW50My55IDogJyd9XG4gICAgICAgIGA7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZFN0cmluZyA9IGAke2RTdHJpbmd9JHtrZXkucmVwbGFjZSgvXFxkL2csICcnKX0ke2RhdGEueH0sJHtkYXRhLnl9XG4gICAgICBgO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRTdHJpbmc7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVN0eWxlQXJyb3cocG9pbnRzOiBJUG9pbnRzLCBtb2RlOiBUWVBFX01PREUsIGRhdGE6IElEcmF3TGluZURhdGFJbnB1dCkge1xuICAgIGlmICghcG9pbnRzLmFycm93RWxlbWVudCB8fCBkYXRhLmlnbm9yZURyYXdBcnJvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdHlsZUNvbmZpZyA9IHtcbiAgICAgIGZpbGw6IGRhdGEuYXJyb3dTdHlsZT8uZmlsbCA/PyAnIzlDQTJBRCcsXG4gICAgICBzdHJva2U6IGRhdGEuYXJyb3dTdHlsZT8uc3Ryb2tlID8/ICdub25lJyxcbiAgICAgIHN0cm9rZVdpZHRoOiBkYXRhLmFycm93U3R5bGU/LnN0cm9rZVdpZHRoID8/ICcwJyxcbiAgICAgIHdpZHRoOiBkYXRhLmFycm93U3R5bGU/LndpZHRoID8/IDYsXG4gICAgICBoZWlnaHQ6IGRhdGEuYXJyb3dTdHlsZT8uaGVpZ2h0ID8/IDhcbiAgICB9O1xuICAgIGNvbnN0IHBvaW50RW5kID0gY2xvbmVEZWVwKHBvaW50cy5lbmQpO1xuICAgIGNvbnN0IGFycm93RWxlbWVudCA9IHBvaW50cy5hcnJvd0VsZW1lbnQ7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gZGF0YS5hcnJvd0RpcmVjdGlvbiB8fCB0aGlzLmdldERpcmVjdGlvbihwb2ludHMsIG1vZGUpO1xuXG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgaWYgKG1vZGUuaW5jbHVkZXMoJ2hvcml6b250YWwnKSB8fCBtb2RlLmluY2x1ZGVzKCd2ZXJ0aWNhbCcpKSB7XG4gICAgICAgICAgcG9pbnRFbmQueCAtPSBzdHlsZUNvbmZpZy5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgYXJyb3dFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ3BvaW50cycsIGAke3BvaW50RW5kLnh9LCR7cG9pbnRFbmQueSAtIHN0eWxlQ29uZmlnLndpZHRofSAgJHtwb2ludEVuZC54ICsgc3R5bGVDb25maWcuaGVpZ2h0fSwke3BvaW50RW5kLnl9ICR7cG9pbnRFbmQueH0sJHtwb2ludEVuZC55ICsgc3R5bGVDb25maWcud2lkdGh9IGApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIGlmIChtb2RlLmluY2x1ZGVzKCdob3Jpem9udGFsJykgfHwgbW9kZS5pbmNsdWRlcygndmVydGljYWwnKSkge1xuICAgICAgICAgIHBvaW50RW5kLnggKz0gc3R5bGVDb25maWcuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGFycm93RWxlbWVudD8uc2V0QXR0cmlidXRlKCdwb2ludHMnLCBgJHtwb2ludEVuZC54fSwke3BvaW50RW5kLnkgLSBzdHlsZUNvbmZpZy53aWR0aH0gICR7cG9pbnRFbmQueCAtIHN0eWxlQ29uZmlnLmhlaWdodH0sJHtwb2ludEVuZC55fSAke3BvaW50RW5kLnh9LCR7cG9pbnRFbmQueSArIHN0eWxlQ29uZmlnLndpZHRofSBgKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgIGlmIChtb2RlLmluY2x1ZGVzKCdob3Jpem9udGFsJykgfHwgbW9kZS5pbmNsdWRlcygndmVydGljYWwnKSkge1xuICAgICAgICAgIHBvaW50RW5kLnkgKz0gc3R5bGVDb25maWcuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGFycm93RWxlbWVudD8uc2V0QXR0cmlidXRlKCdwb2ludHMnLCBgJHtwb2ludEVuZC54IC0gc3R5bGVDb25maWcud2lkdGh9LCR7cG9pbnRFbmQueX0gICR7cG9pbnRFbmQueH0sJHtwb2ludEVuZC55IC0gc3R5bGVDb25maWcuaGVpZ2h0fSAke3BvaW50RW5kLnggKyBzdHlsZUNvbmZpZy53aWR0aH0sJHtwb2ludEVuZC55fSBgKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgIGlmIChtb2RlLmluY2x1ZGVzKCdob3Jpem9udGFsJykgfHwgbW9kZS5pbmNsdWRlcygndmVydGljYWwnKSkge1xuICAgICAgICAgIHBvaW50RW5kLnkgLT0gc3R5bGVDb25maWcuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGFycm93RWxlbWVudD8uc2V0QXR0cmlidXRlKCdwb2ludHMnLCBgJHtwb2ludEVuZC54IC0gc3R5bGVDb25maWcud2lkdGh9LCR7cG9pbnRFbmQueX0gICR7cG9pbnRFbmQueH0sJHtwb2ludEVuZC55ICsgc3R5bGVDb25maWcuaGVpZ2h0fSAke3BvaW50RW5kLnggKyBzdHlsZUNvbmZpZy53aWR0aH0sJHtwb2ludEVuZC55fSBgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgYXJyb3dFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCBzdHlsZUNvbmZpZy5maWxsKTtcbiAgICBhcnJvd0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgc3R5bGVDb25maWcuc3Ryb2tlKTtcbiAgICBhcnJvd0VsZW1lbnQ/LnNldEF0dHJpYnV0ZSgnc3Ryb2tlLXdpZHRoJywgc3R5bGVDb25maWcuc3Ryb2tlV2lkdGgpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVBdHRyaWJ1dGVDaXJjbGUoY2lyY2xlRWxlbWVudDogU1ZHQ2lyY2xlRWxlbWVudCwgbmFtZTogc3RyaW5nLCBwb2ludDogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LCBjaXJjbGVTdHlsZT86IElDaXJjbGVTdHlsZSkge1xuICAgIGNpcmNsZUVsZW1lbnQuc2V0QXR0cmlidXRlKCduYW1lJywgbmFtZSk7XG4gICAgY2lyY2xlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N4JywgYCR7cG9pbnQueH1gKTtcbiAgICBjaXJjbGVFbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCBgJHtwb2ludC55fWApO1xuICAgIGNpcmNsZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdyJywgYCR7Y2lyY2xlU3R5bGU/LnIgPz8gMn1gKTtcbiAgICBjaXJjbGVFbGVtZW50LnNldEF0dHJpYnV0ZSgnZmlsbCcsIGAke2NpcmNsZVN0eWxlPy5maWxsID8/ICdncmVlbid9YCk7XG4gICAgY2lyY2xlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIGAke2NpcmNsZVN0eWxlPy5zdHJva2UgPz8gJyM5Q0EyQUQnfWApO1xuICAgIGNpcmNsZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCBgJHtjaXJjbGVTdHlsZT8uc3Ryb2tlV2lkdGggPz8gJzFweCd9YCk7XG5cbiAgICByZXR1cm4gY2lyY2xlRWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGlyZWN0aW9uKHBvaW50czogSVBvaW50cywgbW9kZTogVFlQRV9NT0RFKTogVFlQRV9ESVJFQ1RJT04ge1xuICAgIGxldCBwb2ludFN0YXJ0ID0geyAuLi5wb2ludHMuc3RhcnQgfTtcblxuICAgIGlmIChwb2ludHMuc2VwYXJhdGVkUG9pbnRzKSB7XG4gICAgICBjb25zdCBsaW5lVG9FbmQgPSBwb2ludHMuc2VwYXJhdGVkUG9pbnRzLmZpbmQoaXRlbSA9PiBpdGVtLmVuZC54ID09PSBwb2ludHMuZW5kLnggJiYgaXRlbS5lbmQueSA9PT0gcG9pbnRzLmVuZC55KVxuICAgICAgaWYgKGxpbmVUb0VuZCkge1xuICAgICAgICBwb2ludFN0YXJ0ID0gbGluZVRvRW5kLnN0YXJ0O1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBtb2RlSG9yaXpvbnRhbCA9IHBvaW50U3RhcnQueCA8IHBvaW50cy5lbmQueCA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgY29uc3QgbW9kZVZlcnRpY2FsID0gcG9pbnRTdGFydC55IDwgcG9pbnRzLmVuZC55ID8gJ2JvdHRvbScgOiAndG9wJztcblxuICAgIGlmIChNYXRoLmFicyhwb2ludHMuZW5kLnggLSBwb2ludFN0YXJ0LngpID4gTWF0aC5hYnMocG9pbnRzLmVuZC55IC0gcG9pbnRTdGFydC55KSkge1xuICAgICAgcmV0dXJuIG1vZGVIb3Jpem9udGFsO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlVmVydGljYWw7XG4gIH1cblxuICBwcml2YXRlIGluaXRFdmVudChkYXRhOiBJRHJhd0xpbmVEYXRhSW5wdXQpIHtcbiAgICBjb25zdCBwb2ludHM6IElQb2ludHMgPSBkYXRhLnBvaW50cztcbiAgICBsZXQgcHJlRXZlbnQ6IE1vdXNlRXZlbnQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoKCFwb2ludHMuYXJyb3dFbGVtZW50ICYmICFwb2ludHMuY2lyY2xlRW5kRWxlbWVudCkgfHwgIXBvaW50cy5vbkRlc3Ryb3lFdmVudCB8fCBwb2ludHMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwb2ludHMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIGNvbnN0IHN0b3BFdmVudE1vdXNlID0gKG1vdXNlRXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIG1vdXNlRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIG1vdXNlRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfTtcbiAgICBjb25zdCBkb2N1bWVudE1vdXNlVXAgPSBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZG9jdW1lbnQsICdtb3VzZXVwJylcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKGV2ZW50TW91c2VVcCkgPT4ge1xuICAgICAgICAgIHN0b3BFdmVudE1vdXNlKGV2ZW50TW91c2VVcCk7XG4gICAgICAgICAgaWYgKHByZUV2ZW50KSB7XG4gICAgICAgICAgICBwcmVFdmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMub25EcmF3TGluZUVuZC5uZXh0KHsgZGF0YUxpbmU6IGRhdGEsIGV2ZW50OiBldmVudE1vdXNlVXAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsKHBvaW50cy5vbkRlc3Ryb3lFdmVudCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSlcbiAgICAgICk7XG4gICAgY29uc3QgZG9jdW1lbnRNb3VzZU1vdmUgPSBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZG9jdW1lbnQsICdtb3VzZW1vdmUnKS5waXBlKHRhcCgoZXZlbnRNb3VzZW1vdmUpID0+IHN0b3BFdmVudE1vdXNlKGV2ZW50TW91c2Vtb3ZlKSksIHRha2VVbnRpbCgoZG9jdW1lbnRNb3VzZVVwKSksIHRha2VVbnRpbChwb2ludHMub25EZXN0cm95RXZlbnQpLCB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpKTtcbiAgICBjb25zdCBoYW5kbGVyRHJhZyA9IChkcmFnTW91c2VFdmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgaWYgKCFwcmVFdmVudCkge1xuICAgICAgICBwcmVFdmVudCA9IGRyYWdNb3VzZUV2ZW50O1xuICAgICAgfVxuICAgICAgY29uc3QgcG9pbnRFbmQgPSBjbG9uZURlZXAocG9pbnRzLmVuZCk7XG5cbiAgICAgIGNvbnN0IG1vdmVtZW50WCA9IGRyYWdNb3VzZUV2ZW50LmNsaWVudFggLSBwcmVFdmVudC5jbGllbnRYO1xuICAgICAgY29uc3QgbW92ZW1lbnRZID0gZHJhZ01vdXNlRXZlbnQuY2xpZW50WSAtIHByZUV2ZW50LmNsaWVudFk7XG5cbiAgICAgIHByZUV2ZW50ID0gZHJhZ01vdXNlRXZlbnQ7XG4gICAgICBwb2ludEVuZC54ICs9IG1vdmVtZW50WDtcbiAgICAgIHBvaW50RW5kLnkgKz0gbW92ZW1lbnRZO1xuICAgICAgaWYgKGRhdGEucG9pbnRzPy5vYnN0YWNsZVJlY3Q/Lmxlbmd0aCAmJiBkYXRhLnBvaW50cz8ub2JzdGFjbGVSZWN0LnNvbWUob2JzdGFjbGVSZWN0ID0+IHRoaXMuY2hlY2tQb2ludEluY2x1ZGVSZWN0KHBvaW50RW5kLCBvYnN0YWNsZVJlY3QpKSkge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHBvaW50cy5lbmQueCA9IHBvaW50RW5kLng7XG4gICAgICBwb2ludHMuZW5kLnkgPSBwb2ludEVuZC55O1xuICAgICAgdGhpcy5kcmF3TGluZShkYXRhKTtcbiAgICAgIHRoaXMudXBkYXRlVmlld0JveCgpO1xuICAgIH07XG5cbiAgICBpZiAocG9pbnRzLmFycm93RWxlbWVudCkge1xuICAgICAgY29uc3QgZWxlbWVudE1vdXNlRG93bkFycm93ID0gZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHBvaW50cy5hcnJvd0VsZW1lbnQsICdtb3VzZWRvd24nKS5waXBlKFxuICAgICAgICB0YXAoZXZlbnRNb3VzZWRvd24gPT4ge1xuICAgICAgICAgIHN0b3BFdmVudE1vdXNlKGV2ZW50TW91c2Vkb3duKTtcblxuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsKHBvaW50cy5vbkRlc3Ryb3lFdmVudCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSlcbiAgICAgICk7XG4gICAgICBjb25zdCBkcmFnQXJyb3cgPSBlbGVtZW50TW91c2VEb3duQXJyb3cucGlwZShtZXJnZU1hcCgobW91c2VFdmVudDogTW91c2VFdmVudCkgPT4gZG9jdW1lbnRNb3VzZU1vdmUucGlwZShzdGFydFdpdGgoKG1vdXNlRXZlbnQpKSkpKSBhcyBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+O1xuXG4gICAgICBkcmFnQXJyb3cucGlwZSh0YXAoaGFuZGxlckRyYWcpLCB0YWtlVW50aWwocG9pbnRzLm9uRGVzdHJveUV2ZW50KSwgdGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgaWYgKHBvaW50cy5jaXJjbGVFbmRFbGVtZW50KSB7XG4gICAgICBjb25zdCBlbGVtZW50TW91c2VEb3duQ2lyY2xlID0gZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHBvaW50cy5jaXJjbGVFbmRFbGVtZW50LCAnbW91c2Vkb3duJykucGlwZShcbiAgICAgICAgdGFwKGV2ZW50TW91c2Vkb3duID0+IHtcbiAgICAgICAgICBzdG9wRXZlbnRNb3VzZShldmVudE1vdXNlZG93bik7XG5cbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbChwb2ludHMub25EZXN0cm95RXZlbnQpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpXG4gICAgICApO1xuICAgICAgY29uc3QgZHJhZ0NpcmNsZSA9IGVsZW1lbnRNb3VzZURvd25DaXJjbGUucGlwZShtZXJnZU1hcCgobW91c2VFdmVudDogTW91c2VFdmVudCkgPT4gZG9jdW1lbnRNb3VzZU1vdmUucGlwZShzdGFydFdpdGgoKG1vdXNlRXZlbnQpKSkpKSBhcyBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+O1xuXG4gICAgICBkcmFnQ2lyY2xlLnBpcGUodGFwKGhhbmRsZXJEcmFnKSwgdGFrZVVudGlsKHBvaW50cy5vbkRlc3Ryb3lFdmVudCksIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpLnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tQb2ludEluY2x1ZGVSZWN0KHBvaW50OiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0sIG9ic3RhY2xlUmVjdDogSVJlY3QpOiBib29sZWFuIHtcbiAgICBjb25zdCBnYXBEZWZhdWx0ID0gODtcblxuICAgIG9ic3RhY2xlUmVjdCA9IHtcbiAgICAgIHg6IG9ic3RhY2xlUmVjdC54IC0gKG9ic3RhY2xlUmVjdC5nYXBYT2JzdGFjbGVSZWN0IHx8IGdhcERlZmF1bHQpLFxuICAgICAgeTogb2JzdGFjbGVSZWN0LnkgLSAob2JzdGFjbGVSZWN0LmdhcFlPYnN0YWNsZVJlY3QgfHwgZ2FwRGVmYXVsdCksXG4gICAgICB3aWR0aDogb2JzdGFjbGVSZWN0LndpZHRoICsgKG9ic3RhY2xlUmVjdC5nYXBYT2JzdGFjbGVSZWN0IHx8IGdhcERlZmF1bHQpICogMixcbiAgICAgIGhlaWdodDogb2JzdGFjbGVSZWN0LmhlaWdodCArIChvYnN0YWNsZVJlY3QuZ2FwWU9ic3RhY2xlUmVjdCB8fCBnYXBEZWZhdWx0KSAqIDJcbiAgICB9O1xuICAgIGlmICgob2JzdGFjbGVSZWN0LnggPD0gcG9pbnQueCAmJiBwb2ludC54IDw9IG9ic3RhY2xlUmVjdC54ICsgb2JzdGFjbGVSZWN0LndpZHRoKSAmJiAob2JzdGFjbGVSZWN0LnkgPD0gcG9pbnQueSAmJiBwb2ludC55IDw9IG9ic3RhY2xlUmVjdC55ICsgb2JzdGFjbGVSZWN0LmhlaWdodCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlUGF0aEFuZEFycm93RWxlbWVudChuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwYXRoRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwicGF0aFwiKTtcbiAgICBjb25zdCBhcnJvd0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcInBvbHlsaW5lXCIpO1xuICAgIGNvbnN0IGNpcmNsZVN0YXJ0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiY2lyY2xlXCIpO1xuICAgIGNvbnN0IGNpcmNsZUVuZEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImNpcmNsZVwiKTtcblxuICAgIHBhdGhFbGVtZW50LnNldEF0dHJpYnV0ZSgnbmFtZScsIG5hbWUpO1xuICAgIGFycm93RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBuYW1lKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKHBhdGhFbGVtZW50KTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kKGFycm93RWxlbWVudCk7XG5cbiAgICByZXR1cm4geyBwYXRoRWxlbWVudCwgYXJyb3dFbGVtZW50LCBjaXJjbGVTdGFydEVsZW1lbnQsIGNpcmNsZUVuZEVsZW1lbnQgfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2lyY2xlKG5hbWU6IHN0cmluZywgcG9pbnQ6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfSkge1xuICAgIGlmICghdGhpcy5kcmF3UmVjdERlYnVnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNpcmNsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiY2lyY2xlXCIpO1xuXG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZSgnbmFtZScsIG5hbWUpO1xuICAgIGNpcmNsZS5zZXRBdHRyaWJ1dGUoJ2N4JywgYCR7cG9pbnQueH1gKTtcbiAgICBjaXJjbGUuc2V0QXR0cmlidXRlKCdjeScsIGAke3BvaW50Lnl9YCk7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZSgncicsICcyJyk7XG4gICAgY2lyY2xlLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnZmlsbDogbm9uZTsgc3Ryb2tlOiBibHVlOyBzdHJva2Utd2lkdGg6IDFweDsnKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQoY2lyY2xlKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJDaXJjbGUoKSB7XG4gICAgaWYgKCF0aGlzLmRyYXdSZWN0RGVidWcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgQXJyYXkuZnJvbSh0aGlzLnN2Z0VsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2NpcmNsZScpKT8uZm9yRWFjaChpdGVtID0+IGl0ZW0ucmVtb3ZlKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRSZWN0KG5hbWU6IHN0cmluZywgcmVjdDogSVJlY3QpIHtcbiAgICBpZiAoIXRoaXMuZHJhd1JlY3REZWJ1Zykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZWN0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwicmVjdFwiKTtcbiAgICBjb25zdCB0ZXh0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwidGV4dFwiKTtcblxuICAgIHJlY3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnbmFtZScsIG5hbWUpO1xuICAgIHJlY3RFbGVtZW50LnNldEF0dHJpYnV0ZSgneCcsIGAke3JlY3QueH1gKTtcbiAgICByZWN0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3knLCBgJHtyZWN0Lnl9YCk7XG4gICAgcmVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKCd3aWR0aCcsIGAke3JlY3Qud2lkdGh9YCk7XG4gICAgcmVjdEVsZW1lbnQuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBgJHtyZWN0LmhlaWdodH1gKTtcbiAgICByZWN0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJ2ZpbGw6IGJsdWU7IHN0cm9rZTogYmx1ZTsnKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQocmVjdEVsZW1lbnQpO1xuXG4gICAgdGV4dEVsZW1lbnQuc2V0QXR0cmlidXRlKCd4JywgYCR7cmVjdC54fWApO1xuICAgIHRleHRFbGVtZW50LnNldEF0dHJpYnV0ZSgneScsIGAke3JlY3QueX1gKTtcbiAgICB0ZXh0RWxlbWVudC50ZXh0Q29udGVudCA9IHJlY3QuaWQgPz8gJyc7XG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRleHRFbGVtZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJSZWN0KCkge1xuICAgIGlmICghdGhpcy5kcmF3UmVjdERlYnVnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIEFycmF5LmZyb20odGhpcy5zdmdFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdyZWN0JykpPy5mb3JFYWNoKGl0ZW0gPT4gaXRlbS5yZW1vdmUoKSk7XG4gICAgQXJyYXkuZnJvbSh0aGlzLnN2Z0VsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RleHQnKSk/LmZvckVhY2goaXRlbSA9PiBpdGVtLnJlbW92ZSgpKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub25EZXN0cm95Lm5leHQoKTtcbiAgICB0aGlzLm9uRGVzdHJveS5jb21wbGV0ZSgpO1xuICB9XG59XG4iXX0=
|