tango-app-ui-store-builder 1.0.28 → 1.0.30
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/esm2022/lib/components/collection-update-ai/collection-update-ai.component.mjs +1486 -0
- package/esm2022/lib/components/manage-plano/popups/create-planogram/create-planogram.component.mjs +6 -9
- package/esm2022/lib/components/manage-store-plano/manage-store-plano.component.mjs +203 -76
- package/esm2022/lib/services/store-builder.service.mjs +10 -1
- package/esm2022/lib/tango-store-builder-routing.module.mjs +6 -1
- package/esm2022/lib/tango-store-builder.module.mjs +1 -4
- package/esm2022/lib/tango-store-plano.module.mjs +18 -20
- package/fesm2022/tango-app-ui-store-builder.mjs +2167 -561
- package/fesm2022/tango-app-ui-store-builder.mjs.map +1 -1
- package/lib/components/collection-update-ai/collection-update-ai.component.d.ts +82 -0
- package/lib/components/manage-plano/popups/create-planogram/create-planogram.component.d.ts +1 -0
- package/lib/components/manage-plano/rollout-table/rollout-table.component.d.ts +2 -2
- package/lib/components/manage-plano/verification-table/verification-table.component.d.ts +4 -4
- package/lib/components/manage-store-plano/manage-store-plano.component.d.ts +11 -2
- package/lib/services/store-builder.service.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1486 @@
|
|
|
1
|
+
import { Component, ViewChild } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
|
4
|
+
import { lastValueFrom, Subject, takeUntil } from 'rxjs';
|
|
5
|
+
import * as fabric from "fabric";
|
|
6
|
+
import { TitleCasePipe } from "@angular/common";
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/forms";
|
|
9
|
+
import * as i2 from "../../services/store-builder.service";
|
|
10
|
+
import * as i3 from "tango-app-ui-shared";
|
|
11
|
+
import * as i4 from "@angular/router";
|
|
12
|
+
import * as i5 from "@angular/common";
|
|
13
|
+
export class CollectionUpdateAiComponent {
|
|
14
|
+
fb;
|
|
15
|
+
apiService;
|
|
16
|
+
toastService;
|
|
17
|
+
route;
|
|
18
|
+
titleCase;
|
|
19
|
+
form;
|
|
20
|
+
loading = false;
|
|
21
|
+
beforeCanvasRef;
|
|
22
|
+
beforeCanvas;
|
|
23
|
+
beforeContainerRef;
|
|
24
|
+
afterCanvasRef;
|
|
25
|
+
afterCanvas;
|
|
26
|
+
afterContainerRef;
|
|
27
|
+
destroy$ = new Subject();
|
|
28
|
+
planoData;
|
|
29
|
+
floorData;
|
|
30
|
+
wallThickness = 30;
|
|
31
|
+
verticalMargin = (1.25 / 100) * this.toPixels(1524, "mm");
|
|
32
|
+
cdnUrl;
|
|
33
|
+
activeHighlight = null;
|
|
34
|
+
cancelHighlightBlink = false;
|
|
35
|
+
storeChips = [];
|
|
36
|
+
selectedStore;
|
|
37
|
+
selectedFixture;
|
|
38
|
+
constructor(fb, apiService, toastService, route, titleCase) {
|
|
39
|
+
this.fb = fb;
|
|
40
|
+
this.apiService = apiService;
|
|
41
|
+
this.toastService = toastService;
|
|
42
|
+
this.route = route;
|
|
43
|
+
this.titleCase = titleCase;
|
|
44
|
+
this.form = this.fb.group({
|
|
45
|
+
stores: ['', Validators.required],
|
|
46
|
+
updateType: ['vm', Validators.required],
|
|
47
|
+
selectionCriteria: ['', Validators.required],
|
|
48
|
+
updationCriteria: ['', Validators.required],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
ngAfterViewInit() {
|
|
52
|
+
this.route.queryParams
|
|
53
|
+
.pipe(takeUntil(this.destroy$))
|
|
54
|
+
.subscribe((params) => {
|
|
55
|
+
if (params?.planoId) {
|
|
56
|
+
this.getStoreFixtures(params?.planoId);
|
|
57
|
+
if (params?.floorId) {
|
|
58
|
+
this.floorData = { _id: params?.floorId };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
this.beforeCanvas = new fabric.Canvas(this.beforeCanvasRef?.nativeElement, {
|
|
63
|
+
selectionFullyContained: true,
|
|
64
|
+
perPixelTargetFind: true,
|
|
65
|
+
targetFindTolerance: 5,
|
|
66
|
+
});
|
|
67
|
+
this.afterCanvas = new fabric.Canvas(this.afterCanvasRef?.nativeElement, {
|
|
68
|
+
selectionFullyContained: true,
|
|
69
|
+
perPixelTargetFind: true,
|
|
70
|
+
targetFindTolerance: 5,
|
|
71
|
+
});
|
|
72
|
+
this.setupZoomHandlers(this.beforeCanvas);
|
|
73
|
+
this.setupZoomHandlers(this.afterCanvas);
|
|
74
|
+
}
|
|
75
|
+
setupZoomHandlers(canvas) {
|
|
76
|
+
canvas.on("mouse:wheel", (opt) => {
|
|
77
|
+
const e = opt.e;
|
|
78
|
+
if (e.ctrlKey || e.metaKey) {
|
|
79
|
+
const delta = e.deltaY;
|
|
80
|
+
let zoom = canvas.getZoom();
|
|
81
|
+
zoom *= 0.995 ** delta;
|
|
82
|
+
zoom = Math.max(0.2, Math.min(zoom, 3));
|
|
83
|
+
canvas.zoomToPoint({
|
|
84
|
+
x: e.offsetX,
|
|
85
|
+
y: e.offsetY,
|
|
86
|
+
}, zoom);
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
e.stopPropagation();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
let isDragging = false;
|
|
92
|
+
let lastPosX = 0;
|
|
93
|
+
let lastPosY = 0;
|
|
94
|
+
canvas.on("mouse:down", (opt) => {
|
|
95
|
+
if (!opt.target) {
|
|
96
|
+
isDragging = true;
|
|
97
|
+
canvas.selection = false;
|
|
98
|
+
const e = opt.e;
|
|
99
|
+
lastPosX = e.clientX;
|
|
100
|
+
lastPosY = e.clientY;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
canvas.on("mouse:move", (opt) => {
|
|
104
|
+
if (isDragging && canvas.viewportTransform) {
|
|
105
|
+
const e = opt.e;
|
|
106
|
+
const vpt = canvas.viewportTransform;
|
|
107
|
+
vpt[4] += e.clientX - lastPosX;
|
|
108
|
+
vpt[5] += e.clientY - lastPosY;
|
|
109
|
+
canvas.requestRenderAll();
|
|
110
|
+
lastPosX = e.clientX;
|
|
111
|
+
lastPosY = e.clientY;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
canvas.on("mouse:up", () => {
|
|
115
|
+
isDragging = false;
|
|
116
|
+
canvas.selection = true;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
updateAiResponseFixture(fixture) {
|
|
120
|
+
let matchFound = false;
|
|
121
|
+
for (let i = 0; i < this.floorData.layoutPolygon.length; i++) {
|
|
122
|
+
const element = this.floorData.layoutPolygon[i];
|
|
123
|
+
if (element.elementType === 'wall' && Array.isArray(element.fixtures)) {
|
|
124
|
+
for (let j = 0; j < element.fixtures.length; j++) {
|
|
125
|
+
const fx = element.fixtures[j];
|
|
126
|
+
if (fx._id === fixture._id) {
|
|
127
|
+
this.floorData.layoutPolygon[i].fixtures[j] = {
|
|
128
|
+
...fixture
|
|
129
|
+
};
|
|
130
|
+
matchFound = true;
|
|
131
|
+
this.selectedFixture = fixture;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (matchFound)
|
|
138
|
+
return;
|
|
139
|
+
for (let i = 0; i < this.floorData?.centerFixture.length; i++) {
|
|
140
|
+
const fx = this.floorData?.centerFixture[i];
|
|
141
|
+
if (fx._id === fixture._id) {
|
|
142
|
+
this.floorData.centerFixture[i] = {
|
|
143
|
+
...fixture
|
|
144
|
+
};
|
|
145
|
+
this.selectedFixture = fixture;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
submitPrompt() {
|
|
151
|
+
if (this.form.invalid) {
|
|
152
|
+
this.form.markAllAsTouched();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.loading = true;
|
|
156
|
+
const payload = {
|
|
157
|
+
...this.form.value,
|
|
158
|
+
stores: [this.selectedStore]
|
|
159
|
+
};
|
|
160
|
+
this.apiService.findFixtureAi(payload).subscribe({
|
|
161
|
+
next: (res) => {
|
|
162
|
+
this.loading = false;
|
|
163
|
+
if (res.code === 200) {
|
|
164
|
+
this.updateAiResponseFixture(res.data);
|
|
165
|
+
this.renderFloor(this.afterCanvas);
|
|
166
|
+
setTimeout(() => {
|
|
167
|
+
const actionFixture = this.afterCanvas
|
|
168
|
+
.getObjects()
|
|
169
|
+
.find((obj) => {
|
|
170
|
+
return obj.objType === "fixture" && obj.fixtureId === res.data._id;
|
|
171
|
+
});
|
|
172
|
+
if (!actionFixture)
|
|
173
|
+
return;
|
|
174
|
+
this.highlightFixture(this.afterCanvas, actionFixture, true);
|
|
175
|
+
}, 0);
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
error: () => {
|
|
179
|
+
this.loading = false;
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async getStoreFixtures(storeId) {
|
|
184
|
+
this.loading = true;
|
|
185
|
+
this.apiService
|
|
186
|
+
.getStoreFixtures({ id: [storeId] })
|
|
187
|
+
.pipe(takeUntil(this.destroy$))
|
|
188
|
+
.subscribe({
|
|
189
|
+
next: async (res) => {
|
|
190
|
+
if (!res?.data?.[0]?.floors?.length) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.planoData = structuredClone(res.data[0]);
|
|
194
|
+
this.floorData = structuredClone(res.data[0].floors[0]);
|
|
195
|
+
this.renderFloor(this.beforeCanvas);
|
|
196
|
+
this.renderFloor(this.afterCanvas);
|
|
197
|
+
this.loading = false;
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
this.resizeCanvas(this.beforeCanvas, this.beforeContainerRef);
|
|
200
|
+
this.fitCanvasToLayoutAnimated(this.beforeCanvas);
|
|
201
|
+
this.resizeCanvas(this.afterCanvas, this.afterContainerRef);
|
|
202
|
+
this.fitCanvasToLayoutAnimated(this.afterCanvas);
|
|
203
|
+
}, 300);
|
|
204
|
+
},
|
|
205
|
+
error: (err) => {
|
|
206
|
+
this.loading = false;
|
|
207
|
+
this.toastService.getErrorToast("Failed to fetch plano");
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
ngOnDestroy() {
|
|
212
|
+
this.destroy$.next(true);
|
|
213
|
+
this.destroy$.complete();
|
|
214
|
+
}
|
|
215
|
+
resizeCanvas(canvas, conteiner) {
|
|
216
|
+
const container = conteiner.nativeElement;
|
|
217
|
+
canvas.setDimensions({
|
|
218
|
+
width: container.clientWidth - 50,
|
|
219
|
+
height: container.clientHeight - 40,
|
|
220
|
+
});
|
|
221
|
+
canvas.requestRenderAll();
|
|
222
|
+
}
|
|
223
|
+
fitCanvasToLayoutAnimated(canvas) {
|
|
224
|
+
if (!canvas)
|
|
225
|
+
return;
|
|
226
|
+
const bounds = this.getFullLayoutBounds(canvas);
|
|
227
|
+
if (!bounds.width || !bounds.height)
|
|
228
|
+
return;
|
|
229
|
+
const canvasW = canvas.getWidth();
|
|
230
|
+
const canvasH = canvas.getHeight();
|
|
231
|
+
// Final zoom to fit (with padding)
|
|
232
|
+
const scaleX = canvasW / bounds.width;
|
|
233
|
+
const scaleY = canvasH / bounds.height;
|
|
234
|
+
const targetZoom = Math.min(scaleX, scaleY) * 0.9; // padding 10%
|
|
235
|
+
// Desired viewport offset to center layout
|
|
236
|
+
const targetVpt = [
|
|
237
|
+
...(canvas.viewportTransform || [1, 0, 0, 1, 0, 0]),
|
|
238
|
+
];
|
|
239
|
+
targetVpt[0] = targetZoom; // scaleX
|
|
240
|
+
targetVpt[3] = targetZoom; // scaleY
|
|
241
|
+
targetVpt[4] = canvasW / 2 - (bounds.left + bounds.width / 2) * targetZoom; // center X
|
|
242
|
+
targetVpt[5] = canvasH / 2 - (bounds.top + bounds.height / 2) * targetZoom; // center Y
|
|
243
|
+
// Current viewport (starting point of animation)
|
|
244
|
+
const startVpt = [...canvas.viewportTransform];
|
|
245
|
+
fabric.util.animate({
|
|
246
|
+
startValue: 0,
|
|
247
|
+
endValue: 1,
|
|
248
|
+
duration: 100,
|
|
249
|
+
easing: fabric.util.ease.easeOutCubic,
|
|
250
|
+
onChange: (value) => {
|
|
251
|
+
const vpt = canvas.viewportTransform;
|
|
252
|
+
// Interpolate matrix values
|
|
253
|
+
vpt[0] = startVpt[0] + (targetVpt[0] - startVpt[0]) * value;
|
|
254
|
+
vpt[3] = startVpt[3] + (targetVpt[3] - startVpt[3]) * value;
|
|
255
|
+
vpt[4] = startVpt[4] + (targetVpt[4] - startVpt[4]) * value;
|
|
256
|
+
vpt[5] = startVpt[5] + (targetVpt[5] - startVpt[5]) * value;
|
|
257
|
+
canvas.requestRenderAll();
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
getFullLayoutBounds(canvas) {
|
|
262
|
+
const objects = canvas.getObjects();
|
|
263
|
+
if (!objects.length)
|
|
264
|
+
return { left: 0, top: 0, width: 0, height: 0 };
|
|
265
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
266
|
+
for (const obj of objects) {
|
|
267
|
+
const rect = obj.getBoundingRect();
|
|
268
|
+
minX = Math.min(minX, rect.left);
|
|
269
|
+
minY = Math.min(minY, rect.top);
|
|
270
|
+
maxX = Math.max(maxX, rect.left + rect.width);
|
|
271
|
+
maxY = Math.max(maxY, rect.top + rect.height);
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
left: minX,
|
|
275
|
+
top: minY,
|
|
276
|
+
width: maxX - minX,
|
|
277
|
+
height: maxY - minY,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
renderFloor(canvas) {
|
|
281
|
+
this.drawInitialContent(canvas);
|
|
282
|
+
}
|
|
283
|
+
async drawInitialContent(canvas) {
|
|
284
|
+
canvas.clear();
|
|
285
|
+
await this.drawLayoutElements(canvas);
|
|
286
|
+
// this.drawBg();
|
|
287
|
+
}
|
|
288
|
+
async drawLayoutElements(canvas) {
|
|
289
|
+
for (let index = 0; index < this.floorData.layoutPolygon.length; index++) {
|
|
290
|
+
const element = this.floorData.layoutPolygon[index];
|
|
291
|
+
let wall;
|
|
292
|
+
element.relativePosition ??= {
|
|
293
|
+
x: 0,
|
|
294
|
+
y: 0,
|
|
295
|
+
unit: "ft",
|
|
296
|
+
};
|
|
297
|
+
const x = this.toPixels(element.relativePosition.x, element.unit);
|
|
298
|
+
const y = this.toPixels(element.relativePosition.y, element.unit);
|
|
299
|
+
if (element.elementType === "wall") {
|
|
300
|
+
const height = this.wallThickness;
|
|
301
|
+
const width = this.toPixels(element.distance, element.unit);
|
|
302
|
+
wall = await this.drawWall(canvas, x, y, height, width, element);
|
|
303
|
+
}
|
|
304
|
+
else if (element.elementType === "entrance") {
|
|
305
|
+
const arrowWidth = 80;
|
|
306
|
+
const arrowHeight = 75;
|
|
307
|
+
const arrowBase = 40;
|
|
308
|
+
this.drawEntrance(canvas, x, y, arrowWidth, arrowHeight, arrowBase, element);
|
|
309
|
+
}
|
|
310
|
+
if (element.elementType === "wall") {
|
|
311
|
+
const fixtureGroups = [];
|
|
312
|
+
for (let j = 0; j < element?.fixtures?.length; j++) {
|
|
313
|
+
const fixture = element.fixtures[j];
|
|
314
|
+
const x = this.toPixels(fixture.relativePosition.x, fixture.relativePosition.unit);
|
|
315
|
+
const y = this.toPixels(fixture.relativePosition.y, fixture.relativePosition.unit);
|
|
316
|
+
const fixtureHeight = this.toPixels(fixture.fixtureStaticLength.value, fixture.fixtureStaticLength.unit);
|
|
317
|
+
const fixtureWidth = this.toPixels(fixture.fixtureStaticWidth.value, fixture.fixtureStaticWidth.unit);
|
|
318
|
+
const fixtureObj = await this.drawFixture(canvas, x, y, fixtureHeight, fixtureWidth, fixture);
|
|
319
|
+
fixtureGroups.push(fixtureObj);
|
|
320
|
+
}
|
|
321
|
+
if (element.isLocked && wall) {
|
|
322
|
+
canvas.remove(wall);
|
|
323
|
+
fixtureGroups.forEach((f) => canvas.remove(f));
|
|
324
|
+
const combinedGroup = new fabric.Group([wall, ...fixtureGroups], {
|
|
325
|
+
hasControls: true,
|
|
326
|
+
selectable: true,
|
|
327
|
+
subTargetCheck: true,
|
|
328
|
+
});
|
|
329
|
+
combinedGroup.set({ isLocked: true });
|
|
330
|
+
canvas.add(combinedGroup);
|
|
331
|
+
}
|
|
332
|
+
for (let j = 0; j < element?.otherElements?.length; j++) {
|
|
333
|
+
const otherElement = element.otherElements[j];
|
|
334
|
+
const x = this.toPixels(otherElement.relativePosition.x, "ft");
|
|
335
|
+
const y = this.toPixels(otherElement.relativePosition.y, "ft");
|
|
336
|
+
const a = otherElement.relativePosition.angle;
|
|
337
|
+
const h = this.toPixels(otherElement.fixtureStaticLength.value, otherElement.fixtureStaticLength.unit);
|
|
338
|
+
const w = this.toPixels(otherElement.fixtureStaticWidth.value, otherElement.fixtureStaticWidth.unit);
|
|
339
|
+
const fixtureObj = this.drawOtherElementsWithLabel(canvas, x, y, a, w, h, otherElement);
|
|
340
|
+
// elementsGroup.push(fixtureObj as fabric.Group);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
for (let i = 0; i < this.floorData?.centerFixture?.length; i++) {
|
|
345
|
+
const fixture = this.floorData.centerFixture[i];
|
|
346
|
+
const x = this.toPixels(fixture.relativePosition.x, fixture.relativePosition.unit);
|
|
347
|
+
const y = this.toPixels(fixture.relativePosition.y, fixture.relativePosition.unit);
|
|
348
|
+
const fixtureHeight = this.toPixels(fixture.fixtureStaticLength.value, fixture.fixtureStaticLength.unit);
|
|
349
|
+
const fixtureWidth = this.toPixels(fixture.fixtureStaticWidth.value, fixture.fixtureStaticWidth.unit);
|
|
350
|
+
await this.drawFixture(canvas, x, y, fixtureHeight, fixtureWidth, fixture);
|
|
351
|
+
}
|
|
352
|
+
for (let j = 0; j < this.floorData?.otherElements?.length; j++) {
|
|
353
|
+
const otherElement = this.floorData.otherElements[j];
|
|
354
|
+
const x = this.toPixels(otherElement.relativePosition.x, "ft");
|
|
355
|
+
const y = this.toPixels(otherElement.relativePosition.y, "ft");
|
|
356
|
+
const a = otherElement.relativePosition.angle;
|
|
357
|
+
const h = this.toPixels(otherElement.fixtureStaticLength.value, otherElement.fixtureStaticLength.unit);
|
|
358
|
+
const w = this.toPixels(otherElement.fixtureStaticWidth.value, otherElement.fixtureStaticWidth.unit);
|
|
359
|
+
const fixtureObj = this.drawOtherElementsWithLabel(canvas, x, y, a, w, h, otherElement);
|
|
360
|
+
}
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
toPixels(value, unit, dpi = 2.8) {
|
|
364
|
+
let pixels;
|
|
365
|
+
if (unit === "mm") {
|
|
366
|
+
pixels = (value / 25.4) * dpi;
|
|
367
|
+
}
|
|
368
|
+
else if (unit === "ft") {
|
|
369
|
+
pixels = value * 12 * dpi;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
throw new Error("Unsupported unit. Use 'mm' or 'ft'.");
|
|
373
|
+
}
|
|
374
|
+
return Number(pixels.toFixed(4));
|
|
375
|
+
}
|
|
376
|
+
async drawWall(canvas, x, y, height, width, elementData) {
|
|
377
|
+
const radius = 5;
|
|
378
|
+
const fillColor = "#F6FCFF";
|
|
379
|
+
const strokeColor = "#D0D5DD";
|
|
380
|
+
const labelColor = "#009BF3";
|
|
381
|
+
let text = `${this.titleCase.transform(elementData.elementType)} ${elementData.elementNumber}`;
|
|
382
|
+
const wall = new fabric.Rect({
|
|
383
|
+
left: 0,
|
|
384
|
+
top: 0,
|
|
385
|
+
width,
|
|
386
|
+
height,
|
|
387
|
+
rx: radius,
|
|
388
|
+
ry: radius,
|
|
389
|
+
fill: fillColor,
|
|
390
|
+
stroke: strokeColor,
|
|
391
|
+
strokeWidth: 0.27,
|
|
392
|
+
selectable: false,
|
|
393
|
+
strokeUniform: true,
|
|
394
|
+
});
|
|
395
|
+
const centerX = width / 2;
|
|
396
|
+
const centerY = height / 2;
|
|
397
|
+
const isVertical = height > width;
|
|
398
|
+
const label = new fabric.FabricText(text, {
|
|
399
|
+
left: centerX,
|
|
400
|
+
top: centerY,
|
|
401
|
+
fontSize: 10,
|
|
402
|
+
fontFamily: "Inter",
|
|
403
|
+
fontWeight: "500",
|
|
404
|
+
fill: labelColor,
|
|
405
|
+
originX: "center",
|
|
406
|
+
originY: "center",
|
|
407
|
+
angle: isVertical ? -90 : 0,
|
|
408
|
+
selectable: false,
|
|
409
|
+
});
|
|
410
|
+
const arrowHead = 5;
|
|
411
|
+
const elements = [wall, label];
|
|
412
|
+
if (isVertical) {
|
|
413
|
+
const textWidth = label.width || 0;
|
|
414
|
+
const topArrowY = 5;
|
|
415
|
+
const topArrowEndY = centerY - textWidth / 2 - 5;
|
|
416
|
+
if (topArrowEndY > topArrowY + arrowHead) {
|
|
417
|
+
elements.push(new fabric.Line([centerX, topArrowY, centerX, topArrowEndY], {
|
|
418
|
+
stroke: labelColor,
|
|
419
|
+
strokeWidth: 1,
|
|
420
|
+
selectable: false,
|
|
421
|
+
}), new fabric.Triangle({
|
|
422
|
+
left: centerX,
|
|
423
|
+
top: topArrowY,
|
|
424
|
+
width: arrowHead,
|
|
425
|
+
height: arrowHead,
|
|
426
|
+
angle: 0,
|
|
427
|
+
fill: labelColor,
|
|
428
|
+
originX: "center",
|
|
429
|
+
originY: "bottom",
|
|
430
|
+
selectable: false,
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
const bottomArrowStartY = centerY + textWidth / 2 + 5;
|
|
434
|
+
const bottomArrowEndY = height - 5;
|
|
435
|
+
if (bottomArrowEndY > bottomArrowStartY + arrowHead) {
|
|
436
|
+
elements.push(new fabric.Line([centerX, bottomArrowStartY, centerX, bottomArrowEndY], {
|
|
437
|
+
stroke: labelColor,
|
|
438
|
+
strokeWidth: 1,
|
|
439
|
+
selectable: false,
|
|
440
|
+
}), new fabric.Triangle({
|
|
441
|
+
left: centerX,
|
|
442
|
+
top: bottomArrowEndY,
|
|
443
|
+
width: arrowHead,
|
|
444
|
+
height: arrowHead,
|
|
445
|
+
angle: 180,
|
|
446
|
+
fill: labelColor,
|
|
447
|
+
originX: "center",
|
|
448
|
+
originY: "top",
|
|
449
|
+
selectable: false,
|
|
450
|
+
}));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const textWidth = label.width || 0;
|
|
455
|
+
const leftArrowStartX = 5;
|
|
456
|
+
const leftArrowEndX = centerX - textWidth / 2 - 5;
|
|
457
|
+
if (leftArrowEndX > leftArrowStartX + arrowHead) {
|
|
458
|
+
elements.push(new fabric.Line([leftArrowStartX, centerY, leftArrowEndX, centerY], {
|
|
459
|
+
stroke: labelColor,
|
|
460
|
+
strokeWidth: 1,
|
|
461
|
+
selectable: false,
|
|
462
|
+
}), new fabric.Triangle({
|
|
463
|
+
left: leftArrowStartX,
|
|
464
|
+
top: centerY,
|
|
465
|
+
width: arrowHead,
|
|
466
|
+
height: arrowHead,
|
|
467
|
+
angle: -90,
|
|
468
|
+
fill: labelColor,
|
|
469
|
+
originX: "center",
|
|
470
|
+
originY: "center",
|
|
471
|
+
selectable: false,
|
|
472
|
+
}));
|
|
473
|
+
}
|
|
474
|
+
const rightArrowStartX = centerX + textWidth / 2 + 5;
|
|
475
|
+
const rightArrowEndX = width - 5;
|
|
476
|
+
if (rightArrowEndX > rightArrowStartX + arrowHead) {
|
|
477
|
+
elements.push(new fabric.Line([rightArrowStartX, centerY, rightArrowEndX, centerY], {
|
|
478
|
+
stroke: labelColor,
|
|
479
|
+
strokeWidth: 1,
|
|
480
|
+
selectable: false,
|
|
481
|
+
}), new fabric.Triangle({
|
|
482
|
+
left: rightArrowEndX,
|
|
483
|
+
top: centerY,
|
|
484
|
+
width: arrowHead,
|
|
485
|
+
height: arrowHead,
|
|
486
|
+
angle: 90,
|
|
487
|
+
fill: labelColor,
|
|
488
|
+
originX: "center",
|
|
489
|
+
originY: "center",
|
|
490
|
+
selectable: false,
|
|
491
|
+
}));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
const group = new fabric.Group(elements, {
|
|
495
|
+
left: x,
|
|
496
|
+
top: y,
|
|
497
|
+
hasControls: true,
|
|
498
|
+
lockScalingX: isVertical,
|
|
499
|
+
lockScalingY: !isVertical,
|
|
500
|
+
// lockRotation: true,
|
|
501
|
+
evented: true,
|
|
502
|
+
hoverCursor: "pointer",
|
|
503
|
+
angle: elementData.angle,
|
|
504
|
+
subTargetCheck: true,
|
|
505
|
+
});
|
|
506
|
+
group.objType = elementData.elementType;
|
|
507
|
+
group.data = elementData;
|
|
508
|
+
canvas.add(group);
|
|
509
|
+
// If newly added, focus it once
|
|
510
|
+
if (elementData?.newAdded) {
|
|
511
|
+
try {
|
|
512
|
+
canvas.setActiveObject(group);
|
|
513
|
+
canvas.requestRenderAll();
|
|
514
|
+
}
|
|
515
|
+
catch { }
|
|
516
|
+
delete elementData.newAdded;
|
|
517
|
+
}
|
|
518
|
+
return group;
|
|
519
|
+
}
|
|
520
|
+
drawEntrance(canvas, x, y, width, height, arrowWidth, elementData) {
|
|
521
|
+
const bodyWidth = width - arrowWidth;
|
|
522
|
+
const pathData = [
|
|
523
|
+
`M 0 0`,
|
|
524
|
+
`L ${bodyWidth} 0`,
|
|
525
|
+
`L ${bodyWidth} ${-height / 2}`,
|
|
526
|
+
`L ${width} ${height / 2}`,
|
|
527
|
+
`L ${bodyWidth} ${height + height / 2}`,
|
|
528
|
+
`L ${bodyWidth} ${height}`,
|
|
529
|
+
`L 0 ${height}`,
|
|
530
|
+
`Z`,
|
|
531
|
+
].join(" ");
|
|
532
|
+
const arrow = new fabric.Path(pathData, {
|
|
533
|
+
fill: "#03A9F4",
|
|
534
|
+
selectable: false,
|
|
535
|
+
evented: false,
|
|
536
|
+
});
|
|
537
|
+
const maxTextHeight = height - 6;
|
|
538
|
+
const text = new fabric.Text("Entrance", {
|
|
539
|
+
fontFamily: "Arial",
|
|
540
|
+
fontWeight: "bold",
|
|
541
|
+
fill: "white",
|
|
542
|
+
angle: -90,
|
|
543
|
+
originX: "center",
|
|
544
|
+
originY: "center",
|
|
545
|
+
left: 15,
|
|
546
|
+
top: height / 2,
|
|
547
|
+
fontSize: 20,
|
|
548
|
+
selectable: false,
|
|
549
|
+
evented: false,
|
|
550
|
+
});
|
|
551
|
+
const textBounds = text.getBoundingRect();
|
|
552
|
+
if (textBounds.height > maxTextHeight) {
|
|
553
|
+
const scale = maxTextHeight / textBounds.height;
|
|
554
|
+
text.set("fontSize", text.fontSize * scale);
|
|
555
|
+
}
|
|
556
|
+
const group = new fabric.Group([arrow, text], {
|
|
557
|
+
left: x,
|
|
558
|
+
top: y,
|
|
559
|
+
lockScalingX: true,
|
|
560
|
+
lockScalingY: true,
|
|
561
|
+
lockScalingFlip: true,
|
|
562
|
+
angle: elementData.angle,
|
|
563
|
+
});
|
|
564
|
+
group.objType = elementData.elementType;
|
|
565
|
+
group.data = elementData;
|
|
566
|
+
canvas.add(group);
|
|
567
|
+
}
|
|
568
|
+
async drawFixture(canvas, x, y, height, width, fixtureData) {
|
|
569
|
+
let fixtureColor;
|
|
570
|
+
// if (["fixture", "fixture-redo"].includes(this.publishingState)) {
|
|
571
|
+
// fixtureColor = {
|
|
572
|
+
// primary:
|
|
573
|
+
// fixtureData.status == "" && fixtureData.taskStatus == "submit"
|
|
574
|
+
// ? "#a5a6a8"
|
|
575
|
+
// : fixtureData.status == "agree"
|
|
576
|
+
// ? "#6CE9A6"
|
|
577
|
+
// : "#51C1FF",
|
|
578
|
+
// fill:
|
|
579
|
+
// fixtureData.status == "" && fixtureData.taskStatus == "submit"
|
|
580
|
+
// ? "#f3f4f8"
|
|
581
|
+
// : fixtureData.status == "agree"
|
|
582
|
+
// ? "#6CE9A6"
|
|
583
|
+
// : "#EAF8FF",
|
|
584
|
+
// vmFill:
|
|
585
|
+
// fixtureData.status == "" && fixtureData.taskStatus == "submit"
|
|
586
|
+
// ? "#a5a6a8"
|
|
587
|
+
// : "#6938EF",
|
|
588
|
+
// };
|
|
589
|
+
// }
|
|
590
|
+
if (fixtureData.fixtureName === "space")
|
|
591
|
+
return;
|
|
592
|
+
const radius = 5;
|
|
593
|
+
const mainContainer = new fabric.Rect({
|
|
594
|
+
left: x,
|
|
595
|
+
top: y,
|
|
596
|
+
width: width,
|
|
597
|
+
height: height,
|
|
598
|
+
rx: radius,
|
|
599
|
+
ry: radius,
|
|
600
|
+
stroke: fixtureColor?.primary ?? "#51C1FF",
|
|
601
|
+
strokeWidth: 0.27,
|
|
602
|
+
fill: "white",
|
|
603
|
+
});
|
|
604
|
+
const topWidth = width / 1.05;
|
|
605
|
+
const topHeight = (15 / 100) * height;
|
|
606
|
+
const topX = x + (width - topWidth) / 2;
|
|
607
|
+
const topY = y + this.verticalMargin;
|
|
608
|
+
const topContainer = new fabric.Rect({
|
|
609
|
+
left: topX,
|
|
610
|
+
top: topY,
|
|
611
|
+
width: topWidth,
|
|
612
|
+
height: topHeight,
|
|
613
|
+
rx: radius,
|
|
614
|
+
ry: radius,
|
|
615
|
+
stroke: fixtureColor?.primary ?? "#51C1FF",
|
|
616
|
+
strokeWidth: 0.27,
|
|
617
|
+
fill: "white",
|
|
618
|
+
});
|
|
619
|
+
const innerBoxHeight = topHeight / 2;
|
|
620
|
+
const innerTopBox = new fabric.Path(`M ${topX + radius} ${topY}
|
|
621
|
+
L ${topX + topWidth - radius} ${topY}
|
|
622
|
+
Q ${topX + topWidth} ${topY} ${topX + topWidth} ${topY + radius}
|
|
623
|
+
L ${topX + topWidth} ${topY + innerBoxHeight}
|
|
624
|
+
L ${topX} ${topY + innerBoxHeight}
|
|
625
|
+
L ${topX} ${topY + radius}
|
|
626
|
+
Q ${topX} ${topY} ${topX + radius} ${topY} Z`, {
|
|
627
|
+
stroke: fixtureColor?.primary ?? "#51C1FF",
|
|
628
|
+
strokeWidth: 0.27,
|
|
629
|
+
fill: "transparent",
|
|
630
|
+
});
|
|
631
|
+
const topText = new fabric.Textbox(`Fixture ${fixtureData.associatedElementFixtureNumber
|
|
632
|
+
? fixtureData.associatedElementFixtureNumber +
|
|
633
|
+
(fixtureData?.fixtureNumber
|
|
634
|
+
? " - FX-" + fixtureData.fixtureNumber
|
|
635
|
+
: "")
|
|
636
|
+
: "new"}`, {
|
|
637
|
+
left: topX + topWidth / 2,
|
|
638
|
+
top: topY + innerBoxHeight / 2,
|
|
639
|
+
fontSize: 5,
|
|
640
|
+
fontFamily: "Inter",
|
|
641
|
+
fontWeight: "500",
|
|
642
|
+
fill: "#101828",
|
|
643
|
+
originX: "center",
|
|
644
|
+
originY: "center",
|
|
645
|
+
width: topWidth,
|
|
646
|
+
height: innerBoxHeight,
|
|
647
|
+
textAlign: "center",
|
|
648
|
+
});
|
|
649
|
+
const secondBoxY = topY + innerBoxHeight;
|
|
650
|
+
const innerBottomBox = new fabric.Path(`M ${topX} ${secondBoxY}
|
|
651
|
+
L ${topX + topWidth} ${secondBoxY}
|
|
652
|
+
L ${topX + topWidth} ${secondBoxY + innerBoxHeight - radius}
|
|
653
|
+
Q ${topX + topWidth} ${secondBoxY + innerBoxHeight} ${topX + topWidth - radius} ${secondBoxY + innerBoxHeight}
|
|
654
|
+
L ${topX + radius} ${secondBoxY + innerBoxHeight}
|
|
655
|
+
Q ${topX} ${secondBoxY + innerBoxHeight} ${topX} ${secondBoxY + innerBoxHeight - radius}
|
|
656
|
+
L ${topX} ${secondBoxY} Z`, {
|
|
657
|
+
fill: "#344054",
|
|
658
|
+
stroke: fixtureColor?.primary ?? "#51C1FF",
|
|
659
|
+
strokeWidth: 0.27,
|
|
660
|
+
});
|
|
661
|
+
let fontSize = 5;
|
|
662
|
+
let bottomText;
|
|
663
|
+
const textContent = `${fixtureData?.fixtureName} - ${fixtureData?.fixtureWidth.value} ${fixtureData?.fixtureWidth.unit}`;
|
|
664
|
+
const createBottomText = (fs) => new fabric.Textbox(textContent, {
|
|
665
|
+
left: topX + topWidth / 2,
|
|
666
|
+
top: secondBoxY + innerBoxHeight / 2,
|
|
667
|
+
fontSize: fs,
|
|
668
|
+
fontFamily: "Inter",
|
|
669
|
+
fontWeight: "500",
|
|
670
|
+
fill: "#FFFFFF",
|
|
671
|
+
originX: "center",
|
|
672
|
+
originY: "center",
|
|
673
|
+
textAlign: "center",
|
|
674
|
+
width: topWidth,
|
|
675
|
+
});
|
|
676
|
+
do {
|
|
677
|
+
bottomText = createBottomText(fontSize);
|
|
678
|
+
fontSize -= 0.5;
|
|
679
|
+
} while (bottomText.height > innerBoxHeight && fontSize > 2);
|
|
680
|
+
const midWidth = width / 1.05;
|
|
681
|
+
const midHeight = (77 / 100) * height;
|
|
682
|
+
const midX = x + (width - midWidth) / 2;
|
|
683
|
+
const midY = topY + topHeight + this.verticalMargin;
|
|
684
|
+
const midContainer = new fabric.Rect({
|
|
685
|
+
left: midX,
|
|
686
|
+
top: midY,
|
|
687
|
+
width: midWidth,
|
|
688
|
+
height: midHeight,
|
|
689
|
+
rx: radius,
|
|
690
|
+
ry: radius,
|
|
691
|
+
stroke: fixtureColor?.primary ?? "#51C1FF",
|
|
692
|
+
strokeWidth: 0.27,
|
|
693
|
+
fill: "white",
|
|
694
|
+
});
|
|
695
|
+
const shelfCount = fixtureData.shelfConfig?.length;
|
|
696
|
+
const boxHeight = midHeight / (shelfCount + 2);
|
|
697
|
+
const firstBoxY = midY;
|
|
698
|
+
const firstBox = new fabric.Path(`M ${midX + radius} ${firstBoxY}
|
|
699
|
+
L ${midX + midWidth - radius} ${firstBoxY}
|
|
700
|
+
Q ${midX + midWidth} ${firstBoxY} ${midX + midWidth} ${firstBoxY + radius}
|
|
701
|
+
L ${midX + midWidth} ${firstBoxY + boxHeight}
|
|
702
|
+
L ${midX} ${firstBoxY + boxHeight}
|
|
703
|
+
L ${midX} ${firstBoxY + radius}
|
|
704
|
+
Q ${midX} ${firstBoxY} ${midX + radius} ${firstBoxY} Z`, {
|
|
705
|
+
fill: fixtureColor?.fill
|
|
706
|
+
? fixtureColor?.fill
|
|
707
|
+
: fixtureData.issue
|
|
708
|
+
? "#D92D20"
|
|
709
|
+
: "#EAF8FF",
|
|
710
|
+
stroke: fixtureColor?.primary
|
|
711
|
+
? fixtureColor?.primary
|
|
712
|
+
: fixtureData.issue
|
|
713
|
+
? "#D92D20"
|
|
714
|
+
: "#6BCAFF",
|
|
715
|
+
strokeWidth: 0.27,
|
|
716
|
+
});
|
|
717
|
+
const firstBoxText = new fabric.Textbox(`${fixtureData?.header?.label ? fixtureData.header.label : ""}`, {
|
|
718
|
+
left: midX + midWidth / 2,
|
|
719
|
+
top: firstBoxY + boxHeight / 2,
|
|
720
|
+
fontSize: 7,
|
|
721
|
+
fontFamily: "Inter",
|
|
722
|
+
fontWeight: "600",
|
|
723
|
+
fill: fixtureData.issue ? "#fff" : "#101828",
|
|
724
|
+
originX: "center",
|
|
725
|
+
originY: "center",
|
|
726
|
+
width: midWidth,
|
|
727
|
+
height: boxHeight,
|
|
728
|
+
textAlign: "center",
|
|
729
|
+
});
|
|
730
|
+
const shelves = [];
|
|
731
|
+
const shelfHeight = midHeight - 2 * boxHeight;
|
|
732
|
+
if (fixtureData.productResolutionLevel === "L1") {
|
|
733
|
+
const boxY = firstBoxY + boxHeight;
|
|
734
|
+
const shelf = new fabric.Rect({
|
|
735
|
+
left: midX,
|
|
736
|
+
top: boxY,
|
|
737
|
+
width: midWidth,
|
|
738
|
+
height: shelfHeight,
|
|
739
|
+
// stroke: '#51C1FF',
|
|
740
|
+
stroke: fixtureColor?.primary
|
|
741
|
+
? fixtureColor?.primary
|
|
742
|
+
: fixtureData.issue
|
|
743
|
+
? "#D92D20"
|
|
744
|
+
: "#51C1FF",
|
|
745
|
+
strokeWidth: 0.27,
|
|
746
|
+
fill: "white",
|
|
747
|
+
});
|
|
748
|
+
const text = fixtureData?.productBrandName?.join(" + ") || "";
|
|
749
|
+
// Wrap text within fixture width and shrink to fit vertical space
|
|
750
|
+
const maxTextWidth = midWidth * 0.9;
|
|
751
|
+
const maxTextHeight = shelfHeight * 0.8;
|
|
752
|
+
let fontSizeL1 = 6;
|
|
753
|
+
const createWrappedTextbox = (fs) => new fabric.Textbox(text, {
|
|
754
|
+
left: midX + midWidth / 2,
|
|
755
|
+
top: boxY + shelfHeight / 2,
|
|
756
|
+
originX: "center",
|
|
757
|
+
originY: "center",
|
|
758
|
+
width: maxTextWidth,
|
|
759
|
+
fontSize: fs,
|
|
760
|
+
fontFamily: "Inter",
|
|
761
|
+
fontWeight: "500",
|
|
762
|
+
textAlign: "center",
|
|
763
|
+
fill: "#333",
|
|
764
|
+
selectable: false,
|
|
765
|
+
evented: false,
|
|
766
|
+
});
|
|
767
|
+
let wrappedText = createWrappedTextbox(fontSizeL1);
|
|
768
|
+
while (wrappedText.height > maxTextHeight && fontSizeL1 > 2) {
|
|
769
|
+
fontSizeL1 -= 0.5;
|
|
770
|
+
wrappedText = createWrappedTextbox(fontSizeL1);
|
|
771
|
+
}
|
|
772
|
+
const padding = 2;
|
|
773
|
+
const background = new fabric.Rect({
|
|
774
|
+
left: midX + midWidth / 2,
|
|
775
|
+
top: boxY + shelfHeight / 2,
|
|
776
|
+
originX: "center",
|
|
777
|
+
originY: "center",
|
|
778
|
+
width: Math.min(maxTextWidth, wrappedText.width) + padding,
|
|
779
|
+
height: wrappedText.getScaledHeight() + 2,
|
|
780
|
+
fill: "rgba(255, 255, 255, 0.5)",
|
|
781
|
+
selectable: false,
|
|
782
|
+
evented: false,
|
|
783
|
+
rx: 1,
|
|
784
|
+
ry: 1,
|
|
785
|
+
});
|
|
786
|
+
shelves.push(shelf, background, wrappedText);
|
|
787
|
+
}
|
|
788
|
+
else if (fixtureData.productResolutionLevel === "L2") {
|
|
789
|
+
for (let i = 0; i < shelfCount; i++) {
|
|
790
|
+
const boxY = firstBoxY + boxHeight * (i + 1);
|
|
791
|
+
const shelf = new fabric.Rect({
|
|
792
|
+
left: midX,
|
|
793
|
+
top: boxY,
|
|
794
|
+
width: midWidth,
|
|
795
|
+
height: boxHeight,
|
|
796
|
+
stroke: fixtureColor?.primary
|
|
797
|
+
? fixtureColor?.primary
|
|
798
|
+
: fixtureData.issue
|
|
799
|
+
? "#D92D20"
|
|
800
|
+
: "#51C1FF",
|
|
801
|
+
strokeWidth: 0.27,
|
|
802
|
+
fill: "white",
|
|
803
|
+
});
|
|
804
|
+
shelves.push(shelf);
|
|
805
|
+
if (fixtureData.shelfConfig?.[i].shelfType === "tray") {
|
|
806
|
+
const trayRows = fixtureData.shelfConfig?.[i].trayRows || 1;
|
|
807
|
+
const rowSpacing = boxHeight / trayRows;
|
|
808
|
+
for (let r = 1; r < trayRows; r++) {
|
|
809
|
+
const lineY = boxY + r * rowSpacing;
|
|
810
|
+
const trayLine = new fabric.Line([midX, lineY, midX + midWidth, lineY], {
|
|
811
|
+
stroke: "#999",
|
|
812
|
+
strokeWidth: 0.2,
|
|
813
|
+
selectable: false,
|
|
814
|
+
evented: false,
|
|
815
|
+
});
|
|
816
|
+
shelves.push(trayLine);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
const text = fixtureData.shelfConfig?.[i].productBrandName?.join(" + ") || "";
|
|
820
|
+
// L2: Single-line ellipsis against full shelf width
|
|
821
|
+
const horizontalPadding = 6;
|
|
822
|
+
const maxTextWidth = Math.max(0, midWidth - horizontalPadding);
|
|
823
|
+
const maxTextHeight = boxHeight * 0.8;
|
|
824
|
+
const baseFontSize = 5;
|
|
825
|
+
const measure = (t) => new fabric.Text(t, {
|
|
826
|
+
fontSize: baseFontSize,
|
|
827
|
+
fontFamily: "Inter",
|
|
828
|
+
fontWeight: "500",
|
|
829
|
+
});
|
|
830
|
+
let displayText = text;
|
|
831
|
+
let measured = measure(displayText);
|
|
832
|
+
if ((measured.width ?? 0) > maxTextWidth) {
|
|
833
|
+
const ellipsis = "...";
|
|
834
|
+
let leftIdx = 0;
|
|
835
|
+
let rightIdx = text.length;
|
|
836
|
+
while (leftIdx < rightIdx) {
|
|
837
|
+
const midIdx = Math.floor((leftIdx + rightIdx) / 2);
|
|
838
|
+
const candidate = text.slice(0, midIdx) + ellipsis;
|
|
839
|
+
measured = measure(candidate);
|
|
840
|
+
if ((measured.width ?? 0) > maxTextWidth) {
|
|
841
|
+
rightIdx = midIdx;
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
leftIdx = midIdx + 1;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
displayText = text.slice(0, Math.max(0, leftIdx - 1)) + ellipsis;
|
|
848
|
+
measured = measure(displayText);
|
|
849
|
+
}
|
|
850
|
+
const background = new fabric.Rect({
|
|
851
|
+
left: midX + midWidth / 2,
|
|
852
|
+
top: boxY + boxHeight / 2,
|
|
853
|
+
originX: "center",
|
|
854
|
+
originY: "center",
|
|
855
|
+
width: midWidth,
|
|
856
|
+
height: Math.min(maxTextHeight, measured.height ?? 10) + 2,
|
|
857
|
+
fill: "rgba(255, 255, 255, 0.5)",
|
|
858
|
+
selectable: false,
|
|
859
|
+
evented: false,
|
|
860
|
+
rx: 1,
|
|
861
|
+
ry: 1,
|
|
862
|
+
});
|
|
863
|
+
const finalText = new fabric.Text(displayText, {
|
|
864
|
+
left: midX + midWidth / 2,
|
|
865
|
+
top: boxY + boxHeight / 2,
|
|
866
|
+
originX: "center",
|
|
867
|
+
originY: "center",
|
|
868
|
+
fontSize: baseFontSize,
|
|
869
|
+
fontFamily: "Inter",
|
|
870
|
+
fontWeight: "500",
|
|
871
|
+
fill: "#333",
|
|
872
|
+
selectable: false,
|
|
873
|
+
evented: false,
|
|
874
|
+
});
|
|
875
|
+
shelves.push(background, finalText);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
else if (fixtureData.productResolutionLevel === "L3") {
|
|
879
|
+
const sequentialGroups = [];
|
|
880
|
+
let previousZone = null;
|
|
881
|
+
for (const shelf of fixtureData.shelfConfig) {
|
|
882
|
+
const zone = shelf.zone || "Unknown";
|
|
883
|
+
if (zone !== previousZone) {
|
|
884
|
+
sequentialGroups.push({ zone, shelves: [shelf] });
|
|
885
|
+
previousZone = zone;
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
sequentialGroups[sequentialGroups.length - 1].shelves.push(shelf);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
let currentShelfIndex = 0;
|
|
892
|
+
for (const group of sequentialGroups) {
|
|
893
|
+
const { zone, shelves: shelvesInGroup } = group;
|
|
894
|
+
const groupStartIndex = currentShelfIndex;
|
|
895
|
+
const groupLength = shelvesInGroup.length;
|
|
896
|
+
const groupTopY = firstBoxY + boxHeight * (groupStartIndex + 1);
|
|
897
|
+
const groupBottomY = groupTopY + boxHeight * groupLength;
|
|
898
|
+
for (let j = 0; j < shelvesInGroup.length; j++) {
|
|
899
|
+
const shelfData = shelvesInGroup[j];
|
|
900
|
+
const boxY = firstBoxY + boxHeight * (currentShelfIndex + 1);
|
|
901
|
+
const shelfRect = new fabric.Rect({
|
|
902
|
+
left: midX,
|
|
903
|
+
top: boxY,
|
|
904
|
+
width: midWidth,
|
|
905
|
+
height: boxHeight,
|
|
906
|
+
stroke: fixtureColor?.primary
|
|
907
|
+
? fixtureColor?.primary
|
|
908
|
+
: fixtureData.issue
|
|
909
|
+
? "#D92D20"
|
|
910
|
+
: "#51C1FF",
|
|
911
|
+
strokeWidth: 0.27,
|
|
912
|
+
fill: "white",
|
|
913
|
+
});
|
|
914
|
+
shelves.push(shelfRect);
|
|
915
|
+
if (shelfData.shelfType === "tray") {
|
|
916
|
+
const trayRows = shelfData.trayRows || 0;
|
|
917
|
+
const productPerShelf = shelfData.productPerShelf || 0;
|
|
918
|
+
const rowSpacing = boxHeight / trayRows;
|
|
919
|
+
const columnSpacing = midWidth / productPerShelf;
|
|
920
|
+
for (let r = 1; r < trayRows; r++) {
|
|
921
|
+
const lineY = boxY + r * rowSpacing;
|
|
922
|
+
const trayLine = new fabric.Line([midX, lineY, midX + midWidth, lineY], {
|
|
923
|
+
stroke: "#999",
|
|
924
|
+
strokeWidth: 0.2,
|
|
925
|
+
selectable: false,
|
|
926
|
+
evented: false,
|
|
927
|
+
});
|
|
928
|
+
shelves.push(trayLine);
|
|
929
|
+
}
|
|
930
|
+
for (let c = 1; c < productPerShelf; c++) {
|
|
931
|
+
const lineX = midX + c * columnSpacing;
|
|
932
|
+
const verticalLine = new fabric.Line([lineX, boxY, lineX, boxY + boxHeight], {
|
|
933
|
+
stroke: "#999",
|
|
934
|
+
strokeWidth: 0.2,
|
|
935
|
+
selectable: false,
|
|
936
|
+
evented: false,
|
|
937
|
+
});
|
|
938
|
+
shelves.push(verticalLine);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
currentShelfIndex++;
|
|
942
|
+
}
|
|
943
|
+
const groupBottomLine = new fabric.Line([midX, groupBottomY, midX + midWidth, groupBottomY], {
|
|
944
|
+
stroke: fixtureColor?.primary
|
|
945
|
+
? fixtureColor?.primary
|
|
946
|
+
: fixtureData.issue
|
|
947
|
+
? "#D92D20"
|
|
948
|
+
: "#51C1FF",
|
|
949
|
+
strokeWidth: 1,
|
|
950
|
+
selectable: false,
|
|
951
|
+
evented: false,
|
|
952
|
+
});
|
|
953
|
+
shelves.push(groupBottomLine);
|
|
954
|
+
if (fixtureData.fixtureType === "wall") {
|
|
955
|
+
const labelPadding = 2;
|
|
956
|
+
const labelText = new fabric.Textbox(zone, {
|
|
957
|
+
left: midX + midWidth - labelPadding,
|
|
958
|
+
top: groupBottomY,
|
|
959
|
+
fontSize: 5,
|
|
960
|
+
fontFamily: "Inter",
|
|
961
|
+
fontWeight: "600",
|
|
962
|
+
fill: "#707070",
|
|
963
|
+
originX: "right",
|
|
964
|
+
originY: "bottom",
|
|
965
|
+
width: midWidth / 2,
|
|
966
|
+
textAlign: "right",
|
|
967
|
+
});
|
|
968
|
+
shelves.push(labelText);
|
|
969
|
+
}
|
|
970
|
+
const groupCenterX = midX + midWidth / 2;
|
|
971
|
+
const groupCenterY = groupTopY + (groupBottomY - groupTopY) / 2;
|
|
972
|
+
const sectionBrands = new Set();
|
|
973
|
+
shelvesInGroup?.forEach((shelf) => {
|
|
974
|
+
shelf.productBrandName?.forEach((brand) => {
|
|
975
|
+
sectionBrands.add(brand);
|
|
976
|
+
});
|
|
977
|
+
});
|
|
978
|
+
if ([...sectionBrands].length) {
|
|
979
|
+
const text = [...sectionBrands].join(" + ");
|
|
980
|
+
const padding = 2;
|
|
981
|
+
const maxTextWidth = midWidth;
|
|
982
|
+
const rectWidth = midWidth * 0.9;
|
|
983
|
+
const maxTextHeight = 20;
|
|
984
|
+
let fontSize = 6;
|
|
985
|
+
let wrappedText;
|
|
986
|
+
const createTextbox = (fs) => {
|
|
987
|
+
return new fabric.Textbox(text, {
|
|
988
|
+
fontSize: fs,
|
|
989
|
+
fontFamily: "Inter",
|
|
990
|
+
fontWeight: "400",
|
|
991
|
+
width: maxTextWidth,
|
|
992
|
+
textAlign: "center",
|
|
993
|
+
originX: "center",
|
|
994
|
+
originY: "center",
|
|
995
|
+
fill: "#101828",
|
|
996
|
+
selectable: false,
|
|
997
|
+
evented: false,
|
|
998
|
+
left: groupCenterX,
|
|
999
|
+
top: groupCenterY,
|
|
1000
|
+
});
|
|
1001
|
+
};
|
|
1002
|
+
do {
|
|
1003
|
+
wrappedText = createTextbox(fontSize);
|
|
1004
|
+
fontSize -= 0.5;
|
|
1005
|
+
} while (wrappedText.height > maxTextHeight && fontSize > 2);
|
|
1006
|
+
const rectHeight = wrappedText.getScaledHeight() + padding;
|
|
1007
|
+
const groupCenterText = new fabric.Rect({
|
|
1008
|
+
left: groupCenterX,
|
|
1009
|
+
top: groupCenterY,
|
|
1010
|
+
originX: "center",
|
|
1011
|
+
originY: "center",
|
|
1012
|
+
width: rectWidth,
|
|
1013
|
+
height: rectHeight,
|
|
1014
|
+
fill: "rgba(255, 255, 255, 0.5)",
|
|
1015
|
+
selectable: false,
|
|
1016
|
+
evented: false,
|
|
1017
|
+
rx: 1,
|
|
1018
|
+
ry: 1,
|
|
1019
|
+
});
|
|
1020
|
+
shelves.push(groupCenterText, wrappedText);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
if (fixtureData?.vmConfig?.length) {
|
|
1025
|
+
for (let i = 0; i < fixtureData.vmConfig.length; i++) {
|
|
1026
|
+
const vm = fixtureData.vmConfig[i];
|
|
1027
|
+
const startIndex = vm.startYPosition - 1;
|
|
1028
|
+
const endIndex = vm.endYPosition - 1;
|
|
1029
|
+
const shelfTopY = firstBoxY + boxHeight * (startIndex + 1);
|
|
1030
|
+
const shelfHeightSpan = boxHeight * (endIndex - startIndex + 1);
|
|
1031
|
+
let vmHeightPx = shelfHeightSpan;
|
|
1032
|
+
let y = shelfTopY;
|
|
1033
|
+
if (vm.yZone && vm.yZone !== "stretch") {
|
|
1034
|
+
vmHeightPx = shelfHeightSpan / 3;
|
|
1035
|
+
switch (vm.yZone) {
|
|
1036
|
+
case "top":
|
|
1037
|
+
y = shelfTopY;
|
|
1038
|
+
break;
|
|
1039
|
+
case "middle":
|
|
1040
|
+
y = shelfTopY + vmHeightPx;
|
|
1041
|
+
break;
|
|
1042
|
+
case "bottom":
|
|
1043
|
+
y = shelfTopY + 2 * vmHeightPx;
|
|
1044
|
+
break;
|
|
1045
|
+
default:
|
|
1046
|
+
y = shelfTopY;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
let x = midX;
|
|
1050
|
+
let width = midWidth;
|
|
1051
|
+
if (!vm.xZone || vm.xZone === "stretch") {
|
|
1052
|
+
width = midWidth;
|
|
1053
|
+
x = midX;
|
|
1054
|
+
}
|
|
1055
|
+
else {
|
|
1056
|
+
const sectionWidth = midWidth / 3;
|
|
1057
|
+
switch (vm.xZone) {
|
|
1058
|
+
case "left":
|
|
1059
|
+
width = sectionWidth;
|
|
1060
|
+
x = midX;
|
|
1061
|
+
break;
|
|
1062
|
+
case "middle":
|
|
1063
|
+
width = sectionWidth;
|
|
1064
|
+
x = midX + sectionWidth;
|
|
1065
|
+
break;
|
|
1066
|
+
case "right":
|
|
1067
|
+
width = sectionWidth;
|
|
1068
|
+
x = midX + 2 * sectionWidth;
|
|
1069
|
+
break;
|
|
1070
|
+
default:
|
|
1071
|
+
width = midWidth;
|
|
1072
|
+
x = midX;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (vm.vmImageUrl) {
|
|
1076
|
+
try {
|
|
1077
|
+
const vmImage = await fabric.FabricImage.fromURL(`${this.cdnUrl}${vm.vmImageUrl}?v=${Date.now()}`, {
|
|
1078
|
+
crossOrigin: "anonymous",
|
|
1079
|
+
});
|
|
1080
|
+
vmImage.set({
|
|
1081
|
+
left: x + width / 2,
|
|
1082
|
+
top: y + vmHeightPx / 2,
|
|
1083
|
+
originX: "center",
|
|
1084
|
+
originY: "center",
|
|
1085
|
+
scaleX: width / vmImage.width,
|
|
1086
|
+
scaleY: vmHeightPx / vmImage.height,
|
|
1087
|
+
selectable: false,
|
|
1088
|
+
evented: false,
|
|
1089
|
+
});
|
|
1090
|
+
shelves.push(vmImage);
|
|
1091
|
+
}
|
|
1092
|
+
catch (err) {
|
|
1093
|
+
console.error(`Error loading image for VM: ${vm.vmImageUrl}`, err);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
const vmBox = new fabric.Rect({
|
|
1098
|
+
left: x,
|
|
1099
|
+
top: y,
|
|
1100
|
+
width,
|
|
1101
|
+
height: vmHeightPx,
|
|
1102
|
+
fill: fixtureColor?.vmFill ?? "#6938EF",
|
|
1103
|
+
selectable: false,
|
|
1104
|
+
evented: false,
|
|
1105
|
+
});
|
|
1106
|
+
let fontSize = 5;
|
|
1107
|
+
let vmText;
|
|
1108
|
+
const createVmText = (fs) => new fabric.Textbox(vm.vmName || "", {
|
|
1109
|
+
left: x + width / 2,
|
|
1110
|
+
top: y + vmHeightPx / 2,
|
|
1111
|
+
originX: "center",
|
|
1112
|
+
originY: "center",
|
|
1113
|
+
fontSize: fs,
|
|
1114
|
+
fontFamily: "Inter",
|
|
1115
|
+
fontWeight: "600",
|
|
1116
|
+
fill: "white",
|
|
1117
|
+
textAlign: "center",
|
|
1118
|
+
width: width,
|
|
1119
|
+
selectable: false,
|
|
1120
|
+
evented: false,
|
|
1121
|
+
});
|
|
1122
|
+
do {
|
|
1123
|
+
vmText = createVmText(fontSize);
|
|
1124
|
+
fontSize -= 0.5;
|
|
1125
|
+
} while (vmText.height > vmHeightPx && fontSize > 2);
|
|
1126
|
+
shelves.push(vmBox, vmText);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const lastBoxY = firstBoxY + boxHeight * (shelfCount + 1);
|
|
1131
|
+
const lastBox = new fabric.Path(`M ${midX} ${lastBoxY}
|
|
1132
|
+
L ${midX + midWidth} ${lastBoxY}
|
|
1133
|
+
L ${midX + midWidth} ${lastBoxY + boxHeight - radius}
|
|
1134
|
+
Q ${midX + midWidth} ${lastBoxY + boxHeight} ${midX + midWidth - radius} ${lastBoxY + boxHeight}
|
|
1135
|
+
L ${midX + radius} ${lastBoxY + boxHeight}
|
|
1136
|
+
Q ${midX} ${lastBoxY + boxHeight} ${midX} ${lastBoxY + boxHeight - radius}
|
|
1137
|
+
L ${midX} ${lastBoxY} Z`, {
|
|
1138
|
+
fill: fixtureColor?.fill
|
|
1139
|
+
? fixtureColor?.fill
|
|
1140
|
+
: fixtureData.issue
|
|
1141
|
+
? "#FEE4E2"
|
|
1142
|
+
: "#EAF8FF",
|
|
1143
|
+
stroke: fixtureColor?.primary
|
|
1144
|
+
? fixtureColor?.primary
|
|
1145
|
+
: fixtureData.issue
|
|
1146
|
+
? "#D92D20"
|
|
1147
|
+
: "#6BCAFF",
|
|
1148
|
+
strokeWidth: 0.27,
|
|
1149
|
+
});
|
|
1150
|
+
const lastBoxText = new fabric.Textbox(`${fixtureData?.footer?.label ? fixtureData.footer.label : ""}`, {
|
|
1151
|
+
left: midX + midWidth / 2,
|
|
1152
|
+
top: lastBoxY + boxHeight / 2,
|
|
1153
|
+
fontSize: 5,
|
|
1154
|
+
fontFamily: "Inter",
|
|
1155
|
+
fontWeight: "600",
|
|
1156
|
+
fill: "#101828",
|
|
1157
|
+
originX: "center",
|
|
1158
|
+
originY: "center",
|
|
1159
|
+
textAlign: "center",
|
|
1160
|
+
width: midWidth,
|
|
1161
|
+
heigth: boxHeight,
|
|
1162
|
+
});
|
|
1163
|
+
const bottomWidth = width / 1.05;
|
|
1164
|
+
const bottomHeight = (3 / 100) * height;
|
|
1165
|
+
const bottomX = x + (width - bottomWidth) / 2;
|
|
1166
|
+
const bottomY = midY + midHeight + this.verticalMargin;
|
|
1167
|
+
const bottomContainer = new fabric.Rect({
|
|
1168
|
+
left: bottomX,
|
|
1169
|
+
top: bottomY,
|
|
1170
|
+
width: bottomWidth,
|
|
1171
|
+
height: bottomHeight,
|
|
1172
|
+
rx: radius,
|
|
1173
|
+
ry: radius,
|
|
1174
|
+
stroke: "transparent",
|
|
1175
|
+
fill: "transparent",
|
|
1176
|
+
});
|
|
1177
|
+
const bottomTextContent = new fabric.Textbox(`Shelves - ${fixtureData.shelfConfig?.length} . Products - ${fixtureData.fixtureCapacity} . VM - ${fixtureData.vmConfig?.length}`, {
|
|
1178
|
+
left: bottomX + bottomWidth / 2,
|
|
1179
|
+
top: bottomY + bottomHeight / 2,
|
|
1180
|
+
fontSize: 5,
|
|
1181
|
+
fontFamily: "Inter",
|
|
1182
|
+
fontWeight: "500",
|
|
1183
|
+
fill: "#333",
|
|
1184
|
+
originX: "center",
|
|
1185
|
+
originY: "center",
|
|
1186
|
+
textAlign: "center",
|
|
1187
|
+
width: bottomWidth,
|
|
1188
|
+
height: bottomHeight,
|
|
1189
|
+
});
|
|
1190
|
+
const fixtureGroup = new fabric.Group([
|
|
1191
|
+
mainContainer,
|
|
1192
|
+
topContainer,
|
|
1193
|
+
innerTopBox,
|
|
1194
|
+
topText,
|
|
1195
|
+
innerBottomBox,
|
|
1196
|
+
bottomText,
|
|
1197
|
+
midContainer,
|
|
1198
|
+
firstBox,
|
|
1199
|
+
firstBoxText,
|
|
1200
|
+
...shelves,
|
|
1201
|
+
lastBox,
|
|
1202
|
+
lastBoxText,
|
|
1203
|
+
bottomContainer,
|
|
1204
|
+
bottomTextContent,
|
|
1205
|
+
], {
|
|
1206
|
+
left: x,
|
|
1207
|
+
top: y,
|
|
1208
|
+
evented: true,
|
|
1209
|
+
hoverCursor: "pointer",
|
|
1210
|
+
lockScalingX: true,
|
|
1211
|
+
lockScalingY: true,
|
|
1212
|
+
subTargetCheck: true,
|
|
1213
|
+
// hasControls: fixtureData.fixtureType === "floor",
|
|
1214
|
+
// lockRotation: fixtureData.fixtureType !== "floor",
|
|
1215
|
+
// lockMovementX: currentFixtureInfo?.wallDirection === 'up' || currentFixtureInfo?.wallDirection === 'down',
|
|
1216
|
+
// lockMovementY: currentFixtureInfo?.wallDirection === 'right' || currentFixtureInfo?.wallDirection === 'left',
|
|
1217
|
+
angle: fixtureData.relativePosition?.angle ?? 0,
|
|
1218
|
+
});
|
|
1219
|
+
fixtureGroup.fixtureType = fixtureData.fixtureType;
|
|
1220
|
+
fixtureGroup.wallIndex = fixtureData.associatedElementNumber;
|
|
1221
|
+
fixtureGroup.fixtureIndex = fixtureData.associatedElementFixtureNumber;
|
|
1222
|
+
fixtureGroup.fixtureId = fixtureData._id;
|
|
1223
|
+
fixtureGroup.issue = fixtureData.issue;
|
|
1224
|
+
fixtureGroup.issueData = fixtureData.issueData;
|
|
1225
|
+
fixtureGroup.taskType = fixtureData.taskType;
|
|
1226
|
+
fixtureGroup.vmConfig = fixtureData.vmConfig;
|
|
1227
|
+
fixtureGroup.objType = "fixture";
|
|
1228
|
+
canvas.add(fixtureGroup);
|
|
1229
|
+
// If newly added, focus it once
|
|
1230
|
+
if (fixtureData?.newAdded) {
|
|
1231
|
+
try {
|
|
1232
|
+
canvas.setActiveObject(fixtureGroup);
|
|
1233
|
+
canvas.requestRenderAll();
|
|
1234
|
+
}
|
|
1235
|
+
catch { }
|
|
1236
|
+
delete fixtureData.newAdded;
|
|
1237
|
+
}
|
|
1238
|
+
return fixtureGroup;
|
|
1239
|
+
}
|
|
1240
|
+
drawOtherElementsWithLabel(canvas, x, y, a, width, height, element) {
|
|
1241
|
+
const rect = new fabric.Rect({
|
|
1242
|
+
width,
|
|
1243
|
+
height,
|
|
1244
|
+
rx: 2,
|
|
1245
|
+
ry: 2,
|
|
1246
|
+
fill: "#DAF1FF",
|
|
1247
|
+
stroke: "#6BCAFF",
|
|
1248
|
+
strokeWidth: 2,
|
|
1249
|
+
originX: "center",
|
|
1250
|
+
originY: "center",
|
|
1251
|
+
});
|
|
1252
|
+
const text = new fabric.Textbox(element.fixtureName, {
|
|
1253
|
+
width: width - 8,
|
|
1254
|
+
fontSize: 14,
|
|
1255
|
+
fontFamily: "Inter",
|
|
1256
|
+
fontWeight: "500",
|
|
1257
|
+
fill: "#101828",
|
|
1258
|
+
originX: "center",
|
|
1259
|
+
originY: "center",
|
|
1260
|
+
textAlign: "center",
|
|
1261
|
+
editable: false,
|
|
1262
|
+
splitByGrapheme: true,
|
|
1263
|
+
});
|
|
1264
|
+
const textBounds = text.getBoundingRect();
|
|
1265
|
+
if (textBounds.height > height - 8) {
|
|
1266
|
+
const scale = (height - 8) / textBounds.height;
|
|
1267
|
+
text.set("fontSize", text.fontSize * scale);
|
|
1268
|
+
}
|
|
1269
|
+
const group = new fabric.Group([rect, text], {
|
|
1270
|
+
left: x,
|
|
1271
|
+
top: y,
|
|
1272
|
+
angle: a,
|
|
1273
|
+
originX: "center",
|
|
1274
|
+
originY: "center",
|
|
1275
|
+
});
|
|
1276
|
+
group.objType = "others";
|
|
1277
|
+
group.data = element;
|
|
1278
|
+
canvas.add(group);
|
|
1279
|
+
if (element?.newAdded) {
|
|
1280
|
+
try {
|
|
1281
|
+
canvas.setActiveObject(group);
|
|
1282
|
+
canvas.requestRenderAll();
|
|
1283
|
+
}
|
|
1284
|
+
catch { }
|
|
1285
|
+
delete element.newAdded;
|
|
1286
|
+
}
|
|
1287
|
+
return group;
|
|
1288
|
+
}
|
|
1289
|
+
highlightFixture(canvas, group, blink = false) {
|
|
1290
|
+
this.removeHighlight(canvas);
|
|
1291
|
+
this.cancelHighlightBlink = false;
|
|
1292
|
+
const center = group.getCenterPoint();
|
|
1293
|
+
const realWidth = group.width * group.scaleX;
|
|
1294
|
+
const realHeight = group.height * group.scaleY;
|
|
1295
|
+
const rect = new fabric.Rect({
|
|
1296
|
+
left: center.x,
|
|
1297
|
+
top: center.y,
|
|
1298
|
+
width: realWidth + 8,
|
|
1299
|
+
height: realHeight + 8,
|
|
1300
|
+
rx: 5,
|
|
1301
|
+
ry: 5,
|
|
1302
|
+
stroke: "#00aaff",
|
|
1303
|
+
strokeWidth: 3,
|
|
1304
|
+
fill: "transparent",
|
|
1305
|
+
selectable: false,
|
|
1306
|
+
evented: false,
|
|
1307
|
+
originX: "center",
|
|
1308
|
+
originY: "center",
|
|
1309
|
+
angle: group.angle || 0,
|
|
1310
|
+
opacity: blink ? 0 : 1,
|
|
1311
|
+
});
|
|
1312
|
+
rect.data = { type: "fixture-highlight" };
|
|
1313
|
+
canvas.add(rect);
|
|
1314
|
+
canvas.moveObjectTo(rect, canvas.getObjects().length - 1);
|
|
1315
|
+
canvas.requestRenderAll();
|
|
1316
|
+
this.activeHighlight = rect;
|
|
1317
|
+
// --- No blinking needed ---
|
|
1318
|
+
if (!blink)
|
|
1319
|
+
return;
|
|
1320
|
+
let cycles = 0;
|
|
1321
|
+
const blinkOnce = () => {
|
|
1322
|
+
if (this.cancelHighlightBlink) {
|
|
1323
|
+
this.removeHighlight(canvas);
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
rect.animate({ opacity: 1 }, {
|
|
1327
|
+
duration: 200,
|
|
1328
|
+
onChange: () => canvas.requestRenderAll(),
|
|
1329
|
+
onComplete: () => {
|
|
1330
|
+
if (this.cancelHighlightBlink) {
|
|
1331
|
+
this.removeHighlight(canvas);
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
rect.animate({ opacity: 0 }, {
|
|
1335
|
+
duration: 200,
|
|
1336
|
+
onChange: () => canvas.requestRenderAll(),
|
|
1337
|
+
onComplete: () => {
|
|
1338
|
+
if (this.cancelHighlightBlink) {
|
|
1339
|
+
this.removeHighlight(canvas);
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
cycles++;
|
|
1343
|
+
if (cycles < 20) {
|
|
1344
|
+
blinkOnce();
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
if (!this.cancelHighlightBlink) {
|
|
1348
|
+
rect.set({ opacity: 1 });
|
|
1349
|
+
canvas.requestRenderAll();
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1353
|
+
});
|
|
1354
|
+
},
|
|
1355
|
+
});
|
|
1356
|
+
};
|
|
1357
|
+
blinkOnce();
|
|
1358
|
+
}
|
|
1359
|
+
removeHighlight(canvas) {
|
|
1360
|
+
this.cancelHighlightBlink = true;
|
|
1361
|
+
canvas.getObjects().forEach((obj) => {
|
|
1362
|
+
if (obj.data?.type === "fixture-highlight") {
|
|
1363
|
+
canvas.remove(obj);
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1366
|
+
this.activeHighlight = null;
|
|
1367
|
+
canvas.requestRenderAll();
|
|
1368
|
+
}
|
|
1369
|
+
async applyStores() {
|
|
1370
|
+
const value = this.form.value.stores;
|
|
1371
|
+
if (!value)
|
|
1372
|
+
return;
|
|
1373
|
+
const codes = value
|
|
1374
|
+
.split(',')
|
|
1375
|
+
.map((s) => s.trim().toUpperCase())
|
|
1376
|
+
.filter(Boolean);
|
|
1377
|
+
const response = await lastValueFrom(this.apiService.getPlanoId({ stores: codes }));
|
|
1378
|
+
const data = Array.isArray(response.data) ? response.data : [];
|
|
1379
|
+
const foundStoreSet = new Set(data.map((store) => store.storeName.toUpperCase()));
|
|
1380
|
+
const foundChips = data.map((store) => ({
|
|
1381
|
+
storeCode: store.storeName,
|
|
1382
|
+
status: 'pending',
|
|
1383
|
+
planoId: store._id
|
|
1384
|
+
}));
|
|
1385
|
+
const notFoundChips = codes
|
|
1386
|
+
.filter((code) => !foundStoreSet.has(code))
|
|
1387
|
+
.map((code) => ({
|
|
1388
|
+
storeCode: code,
|
|
1389
|
+
status: 'not_found'
|
|
1390
|
+
}));
|
|
1391
|
+
this.storeChips = [...foundChips, ...notFoundChips];
|
|
1392
|
+
const activeChip = this.storeChips.find((chip) => chip.status === 'pending');
|
|
1393
|
+
this.selectedStore = activeChip?.storeCode;
|
|
1394
|
+
this.getStoreFixtures(activeChip.planoId);
|
|
1395
|
+
}
|
|
1396
|
+
delay(ms) {
|
|
1397
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
1398
|
+
}
|
|
1399
|
+
async autoApprove() {
|
|
1400
|
+
for (let i = 0; i < this.storeChips.length; i++) {
|
|
1401
|
+
const { storeCode, status, planoId } = this.storeChips[i];
|
|
1402
|
+
if (status === 'not_found')
|
|
1403
|
+
continue;
|
|
1404
|
+
const planoRes = await lastValueFrom(this.apiService.getStoreFixtures({ id: [planoId] }));
|
|
1405
|
+
if (!planoRes?.data?.[0]?.floors?.length) {
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
this.planoData = structuredClone(planoRes.data[0]);
|
|
1409
|
+
this.floorData = structuredClone(planoRes.data[0].floors[0]);
|
|
1410
|
+
this.renderFloor(this.beforeCanvas);
|
|
1411
|
+
this.renderFloor(this.afterCanvas);
|
|
1412
|
+
this.loading = false;
|
|
1413
|
+
setTimeout(() => {
|
|
1414
|
+
this.resizeCanvas(this.beforeCanvas, this.beforeContainerRef);
|
|
1415
|
+
this.fitCanvasToLayoutAnimated(this.beforeCanvas);
|
|
1416
|
+
this.resizeCanvas(this.afterCanvas, this.afterContainerRef);
|
|
1417
|
+
this.fitCanvasToLayoutAnimated(this.afterCanvas);
|
|
1418
|
+
}, 100);
|
|
1419
|
+
const payload = {
|
|
1420
|
+
...this.form.value,
|
|
1421
|
+
stores: [storeCode]
|
|
1422
|
+
};
|
|
1423
|
+
const aiRes = await lastValueFrom(this.apiService.findFixtureAi(payload));
|
|
1424
|
+
if (aiRes.code === 200) {
|
|
1425
|
+
this.updateAiResponseFixture(aiRes.data);
|
|
1426
|
+
this.renderFloor(this.afterCanvas);
|
|
1427
|
+
setTimeout(() => {
|
|
1428
|
+
const actionFixture = this.afterCanvas
|
|
1429
|
+
.getObjects()
|
|
1430
|
+
.find((obj) => {
|
|
1431
|
+
return obj.objType === "fixture" && obj.fixtureId === aiRes.data._id;
|
|
1432
|
+
});
|
|
1433
|
+
if (!actionFixture)
|
|
1434
|
+
return;
|
|
1435
|
+
this.highlightFixture(this.afterCanvas, actionFixture, true);
|
|
1436
|
+
}, 0);
|
|
1437
|
+
}
|
|
1438
|
+
const updatePayload = {
|
|
1439
|
+
fixtures: [this.selectedFixture]
|
|
1440
|
+
};
|
|
1441
|
+
await lastValueFrom(this.apiService.updateFixtureData(updatePayload));
|
|
1442
|
+
this.storeChips[i].status = 'approved';
|
|
1443
|
+
const activeChip = this.storeChips.find((chip) => chip.status === 'pending');
|
|
1444
|
+
this.selectedStore = activeChip?.storeCode;
|
|
1445
|
+
await this.delay(3000);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
approveStore() {
|
|
1449
|
+
const payload = {
|
|
1450
|
+
fixtures: [this.selectedFixture]
|
|
1451
|
+
};
|
|
1452
|
+
this.apiService.updateFixtureData(payload).subscribe({
|
|
1453
|
+
next: (res) => {
|
|
1454
|
+
if (res.code === 200) {
|
|
1455
|
+
this.storeChips.find((chip) => chip.storeCode === this.selectedStore).status = 'approved';
|
|
1456
|
+
const nextChip = this.storeChips.find((chip) => chip.status === 'pending');
|
|
1457
|
+
this.selectedStore = nextChip?.storeCode;
|
|
1458
|
+
this.getStoreFixtures(nextChip.planoId);
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
selectStore(chip) {
|
|
1464
|
+
this.selectedStore = chip.storeCode;
|
|
1465
|
+
this.getStoreFixtures(chip.planoId);
|
|
1466
|
+
}
|
|
1467
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CollectionUpdateAiComponent, deps: [{ token: i1.FormBuilder }, { token: i2.StoreBuilderService }, { token: i3.ToastService }, { token: i4.ActivatedRoute }, { token: i5.TitleCasePipe }], target: i0.ɵɵFactoryTarget.Component });
|
|
1468
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CollectionUpdateAiComponent, isStandalone: true, selector: "lib-collection-update-ai", providers: [TitleCasePipe], viewQueries: [{ propertyName: "beforeCanvasRef", first: true, predicate: ["beforeCanvas"], descendants: true }, { propertyName: "beforeContainerRef", first: true, predicate: ["beforeCanvasContainer"], descendants: true }, { propertyName: "afterCanvasRef", first: true, predicate: ["afterCanvas"], descendants: true }, { propertyName: "afterContainerRef", first: true, predicate: ["afterCanvasContainer"], descendants: true }], ngImport: i0, template: "<form class=\"ai-container\" [formGroup]=\"form\" (ngSubmit)=\"submitPrompt()\">\r\n\r\n <!-- ================= Applicable Stores ================= -->\r\n <div class=\"field\">\r\n <label>Applicable Stores</label>\r\n\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"stores\" placeholder=\"e.g. LKST345, LKST346\" />\r\n\r\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"applyStores()\">\r\n Apply\r\n </button>\r\n </div>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.stores.touched && form.controls.stores.invalid\">\r\n Applicable stores is required\r\n </span>\r\n </div>\r\n\r\n <!-- ================= Store Chips ================= -->\r\n <div class=\"store-chips\" *ngIf=\"storeChips.length\">\r\n <div (click)=\"selectStore(chip)\" class=\"store-chip\" *ngFor=\"let chip of storeChips\" [ngClass]=\"[\r\n chip.status,\r\n chip.storeCode === selectedStore ? 'active' : ''\r\n ]\">\r\n {{ chip.storeCode }}\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- ================= Update Type ================= -->\r\n <div class=\"field\">\r\n <label>Update Type</label>\r\n\r\n <div class=\"radio-group\">\r\n <label class=\"radio-option\">\r\n <input type=\"radio\" formControlName=\"updateType\" value=\"vm\" />\r\n VM\r\n </label>\r\n\r\n <label class=\"radio-option\">\r\n <input type=\"radio\" formControlName=\"updateType\" value=\"pid\" />\r\n PID\r\n </label>\r\n </div>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.updateType.touched && form.controls.updateType.invalid\">\r\n Update type is required\r\n </span>\r\n </div>\r\n\r\n <!-- ================= AI Prompt ================= -->\r\n <div class=\"field\">\r\n <label>AI Prompt</label>\r\n\r\n <div class=\"row\">\r\n\r\n <!-- Selection Criteria -->\r\n <div class=\"col-md-6\">\r\n <div class=\"form-group\">\r\n <label class=\"small fw-semibold\">Selection Criteria</label>\r\n\r\n <textarea rows=\"3\" class=\"form-control\" formControlName=\"selectionCriteria\"\r\n placeholder=\"e.g. Select premium shades on wall fixtures\"></textarea>\r\n\r\n <span class=\"error\"\r\n *ngIf=\"form.controls.selectionCriteria.touched && form.controls.selectionCriteria.invalid\">\r\n Selection criteria is required\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Updation Criteria -->\r\n <div class=\"col-md-6\">\r\n <div class=\"form-group\">\r\n <label class=\"small fw-semibold\">Updation Criteria</label>\r\n\r\n <textarea rows=\"3\" class=\"form-control\" formControlName=\"updationCriteria\"\r\n placeholder=\"e.g. Move selected fixtures to mid shelves\"></textarea>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.updationCriteria.touched && form.controls.updationCriteria.invalid\">\r\n Updation criteria is required\r\n </span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- ================= Submit ================= -->\r\n <div class=\"d-flex justify-content-end mt-3\">\r\n <button type=\"submit\" class=\"submit-btn\" [disabled]=\"loading\">\r\n {{ loading ? 'Thinking\u2026' : 'Submit' }}\r\n </button>\r\n </div>\r\n\r\n <!-- ================= Canvases ================= -->\r\n <div class=\"canvas-grid mt-4\">\r\n\r\n <div class=\"canvas-box\" #beforeCanvasContainer>\r\n <div class=\"canvas-title\">Before Update</div>\r\n <canvas #beforeCanvas></canvas>\r\n </div>\r\n\r\n <div class=\"canvas-box\" #afterCanvasContainer>\r\n <div class=\"canvas-title\">After Update</div>\r\n <canvas #afterCanvas></canvas>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <!-- ================= Auto Approve ================= -->\r\n <button (click)=\"autoApprove()\" type=\"button\" class=\"btn btn-warning me-3\">\r\n \u26A0 Auto Approve\r\n </button>\r\n\r\n <!-- ================= Approve Changes ================= -->\r\n <button type=\"button\" class=\"btn btn-success\" (click)=\"approveStore()\" [disabled]=\"form.invalid\">\r\n \u2714 Approve Changes\r\n </button>\r\n </div>\r\n\r\n\r\n</form>", styles: ["@charset \"UTF-8\";.ai-container{display:flex;flex-direction:column;gap:16px;height:100%}.field{display:flex;flex-direction:column;gap:6px}.field label{font-size:13px;font-weight:600;color:#374151}.field input,.field textarea{padding:10px;font-size:14px;border-radius:6px;border:1px solid #d1d5db}.error{font-size:12px;color:#dc2626}.submit-btn{width:140px;padding:10px;background:#2563eb;color:#fff;border:none;border-radius:6px;cursor:pointer}.submit-btn:disabled{background:#9ca3af}.canvas-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.canvas-box{border:1px solid #e5e7eb;border-radius:8px;padding:8px;background:#f9fafb;display:flex;flex-direction:column;align-items:center;height:70dvh}.canvas-title{font-size:14px;font-weight:600;margin-bottom:8px}canvas{background:#fff;border-radius:4px}.approve-bar{display:flex;justify-content:flex-end;margin-top:auto}.approve-btn{padding:12px 20px;background:#16a34a;color:#fff;border:none;border-radius:6px;font-size:14px;cursor:pointer}.approve-btn:disabled{background:#9ca3af}.radio-group{display:flex;gap:20px;margin-top:6px}.radio-option{display:flex;align-items:center;gap:6px;cursor:pointer}.store-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}.store-chip{padding:6px 12px;border-radius:14px;font-size:13px;font-weight:600;color:#fff;cursor:pointer}.store-chip.pending{background-color:#6c757d}.store-chip.approved{background-color:#198754}.store-chip.skipped{background-color:#0d6efd}.store-chip.not_found{background-color:#dc3545}.store-chip.active{animation:chip-pulse 1.4s infinite ease-in-out;z-index:2}.store-chip.active:after{content:\"\";position:absolute;inset:-3px;border-radius:16px;border:2px solid #20c997;box-shadow:0 0 6px #20c997b3,0 0 12px #20c99766;animation:ring-pulse 1.4s infinite ease-in-out;pointer-events:none}@keyframes chip-pulse{0%{transform:scale(1)}50%{transform:scale(1.025)}to{transform:scale(1)}}@keyframes ring-pulse{0%{opacity:.4}50%{opacity:.9}to{opacity:.4}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
1469
|
+
}
|
|
1470
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CollectionUpdateAiComponent, decorators: [{
|
|
1471
|
+
type: Component,
|
|
1472
|
+
args: [{ selector: 'lib-collection-update-ai', standalone: true, imports: [CommonModule, ReactiveFormsModule], providers: [TitleCasePipe], template: "<form class=\"ai-container\" [formGroup]=\"form\" (ngSubmit)=\"submitPrompt()\">\r\n\r\n <!-- ================= Applicable Stores ================= -->\r\n <div class=\"field\">\r\n <label>Applicable Stores</label>\r\n\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"stores\" placeholder=\"e.g. LKST345, LKST346\" />\r\n\r\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"applyStores()\">\r\n Apply\r\n </button>\r\n </div>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.stores.touched && form.controls.stores.invalid\">\r\n Applicable stores is required\r\n </span>\r\n </div>\r\n\r\n <!-- ================= Store Chips ================= -->\r\n <div class=\"store-chips\" *ngIf=\"storeChips.length\">\r\n <div (click)=\"selectStore(chip)\" class=\"store-chip\" *ngFor=\"let chip of storeChips\" [ngClass]=\"[\r\n chip.status,\r\n chip.storeCode === selectedStore ? 'active' : ''\r\n ]\">\r\n {{ chip.storeCode }}\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- ================= Update Type ================= -->\r\n <div class=\"field\">\r\n <label>Update Type</label>\r\n\r\n <div class=\"radio-group\">\r\n <label class=\"radio-option\">\r\n <input type=\"radio\" formControlName=\"updateType\" value=\"vm\" />\r\n VM\r\n </label>\r\n\r\n <label class=\"radio-option\">\r\n <input type=\"radio\" formControlName=\"updateType\" value=\"pid\" />\r\n PID\r\n </label>\r\n </div>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.updateType.touched && form.controls.updateType.invalid\">\r\n Update type is required\r\n </span>\r\n </div>\r\n\r\n <!-- ================= AI Prompt ================= -->\r\n <div class=\"field\">\r\n <label>AI Prompt</label>\r\n\r\n <div class=\"row\">\r\n\r\n <!-- Selection Criteria -->\r\n <div class=\"col-md-6\">\r\n <div class=\"form-group\">\r\n <label class=\"small fw-semibold\">Selection Criteria</label>\r\n\r\n <textarea rows=\"3\" class=\"form-control\" formControlName=\"selectionCriteria\"\r\n placeholder=\"e.g. Select premium shades on wall fixtures\"></textarea>\r\n\r\n <span class=\"error\"\r\n *ngIf=\"form.controls.selectionCriteria.touched && form.controls.selectionCriteria.invalid\">\r\n Selection criteria is required\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Updation Criteria -->\r\n <div class=\"col-md-6\">\r\n <div class=\"form-group\">\r\n <label class=\"small fw-semibold\">Updation Criteria</label>\r\n\r\n <textarea rows=\"3\" class=\"form-control\" formControlName=\"updationCriteria\"\r\n placeholder=\"e.g. Move selected fixtures to mid shelves\"></textarea>\r\n\r\n <span class=\"error\" *ngIf=\"form.controls.updationCriteria.touched && form.controls.updationCriteria.invalid\">\r\n Updation criteria is required\r\n </span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- ================= Submit ================= -->\r\n <div class=\"d-flex justify-content-end mt-3\">\r\n <button type=\"submit\" class=\"submit-btn\" [disabled]=\"loading\">\r\n {{ loading ? 'Thinking\u2026' : 'Submit' }}\r\n </button>\r\n </div>\r\n\r\n <!-- ================= Canvases ================= -->\r\n <div class=\"canvas-grid mt-4\">\r\n\r\n <div class=\"canvas-box\" #beforeCanvasContainer>\r\n <div class=\"canvas-title\">Before Update</div>\r\n <canvas #beforeCanvas></canvas>\r\n </div>\r\n\r\n <div class=\"canvas-box\" #afterCanvasContainer>\r\n <div class=\"canvas-title\">After Update</div>\r\n <canvas #afterCanvas></canvas>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <!-- ================= Auto Approve ================= -->\r\n <button (click)=\"autoApprove()\" type=\"button\" class=\"btn btn-warning me-3\">\r\n \u26A0 Auto Approve\r\n </button>\r\n\r\n <!-- ================= Approve Changes ================= -->\r\n <button type=\"button\" class=\"btn btn-success\" (click)=\"approveStore()\" [disabled]=\"form.invalid\">\r\n \u2714 Approve Changes\r\n </button>\r\n </div>\r\n\r\n\r\n</form>", styles: ["@charset \"UTF-8\";.ai-container{display:flex;flex-direction:column;gap:16px;height:100%}.field{display:flex;flex-direction:column;gap:6px}.field label{font-size:13px;font-weight:600;color:#374151}.field input,.field textarea{padding:10px;font-size:14px;border-radius:6px;border:1px solid #d1d5db}.error{font-size:12px;color:#dc2626}.submit-btn{width:140px;padding:10px;background:#2563eb;color:#fff;border:none;border-radius:6px;cursor:pointer}.submit-btn:disabled{background:#9ca3af}.canvas-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.canvas-box{border:1px solid #e5e7eb;border-radius:8px;padding:8px;background:#f9fafb;display:flex;flex-direction:column;align-items:center;height:70dvh}.canvas-title{font-size:14px;font-weight:600;margin-bottom:8px}canvas{background:#fff;border-radius:4px}.approve-bar{display:flex;justify-content:flex-end;margin-top:auto}.approve-btn{padding:12px 20px;background:#16a34a;color:#fff;border:none;border-radius:6px;font-size:14px;cursor:pointer}.approve-btn:disabled{background:#9ca3af}.radio-group{display:flex;gap:20px;margin-top:6px}.radio-option{display:flex;align-items:center;gap:6px;cursor:pointer}.store-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}.store-chip{padding:6px 12px;border-radius:14px;font-size:13px;font-weight:600;color:#fff;cursor:pointer}.store-chip.pending{background-color:#6c757d}.store-chip.approved{background-color:#198754}.store-chip.skipped{background-color:#0d6efd}.store-chip.not_found{background-color:#dc3545}.store-chip.active{animation:chip-pulse 1.4s infinite ease-in-out;z-index:2}.store-chip.active:after{content:\"\";position:absolute;inset:-3px;border-radius:16px;border:2px solid #20c997;box-shadow:0 0 6px #20c997b3,0 0 12px #20c99766;animation:ring-pulse 1.4s infinite ease-in-out;pointer-events:none}@keyframes chip-pulse{0%{transform:scale(1)}50%{transform:scale(1.025)}to{transform:scale(1)}}@keyframes ring-pulse{0%{opacity:.4}50%{opacity:.9}to{opacity:.4}}\n"] }]
|
|
1473
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.StoreBuilderService }, { type: i3.ToastService }, { type: i4.ActivatedRoute }, { type: i5.TitleCasePipe }], propDecorators: { beforeCanvasRef: [{
|
|
1474
|
+
type: ViewChild,
|
|
1475
|
+
args: ['beforeCanvas']
|
|
1476
|
+
}], beforeContainerRef: [{
|
|
1477
|
+
type: ViewChild,
|
|
1478
|
+
args: ["beforeCanvasContainer"]
|
|
1479
|
+
}], afterCanvasRef: [{
|
|
1480
|
+
type: ViewChild,
|
|
1481
|
+
args: ['afterCanvas']
|
|
1482
|
+
}], afterContainerRef: [{
|
|
1483
|
+
type: ViewChild,
|
|
1484
|
+
args: ["afterCanvasContainer"]
|
|
1485
|
+
}] } });
|
|
1486
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi11cGRhdGUtYWkuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvY29sbGVjdGlvbi11cGRhdGUtYWkvY29sbGVjdGlvbi11cGRhdGUtYWkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvY29sbGVjdGlvbi11cGRhdGUtYWkvY29sbGVjdGlvbi11cGRhdGUtYWkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQXdDLE1BQU0sZUFBZSxDQUFDO0FBQzNGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsbUJBQW1CLEVBQTBCLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUd6RCxPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUVqQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7Ozs7QUFrQmhELE1BQU0sT0FBTywyQkFBMkI7SUEwQmxCO0lBQ1Y7SUFDQTtJQUNBO0lBQ0E7SUE1QlYsSUFBSSxDQUFZO0lBQ2hCLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFVyxlQUFlLENBQWlDO0lBQzNFLFlBQVksQ0FBaUI7SUFDTyxrQkFBa0IsQ0FBOEI7SUFDMUQsY0FBYyxDQUFpQztJQUN6RSxXQUFXLENBQWlCO0lBQ08saUJBQWlCLENBQThCO0lBQ2xGLFFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ3pCLFNBQVMsQ0FBTTtJ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QUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFBO1FBQ25DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDckMsQ0FBQzt3R0F0M0RVLDJCQUEyQjs0RkFBM0IsMkJBQTJCLHVFQUgzQixDQUFDLGFBQWEsQ0FBQyxxY0N2QjVCLHkxSUE0SE8sNitERHRHSyxZQUFZLDZWQUFFLG1CQUFtQjs7NEZBSWhDLDJCQUEyQjtrQkFUdkMsU0FBUzsrQkFDRSwwQkFBMEIsY0FHeEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixDQUFDLGFBQ2pDLENBQUMsYUFBYSxDQUFDO3NNQVFDLGVBQWU7c0JBQXpDLFNBQVM7dUJBQUMsY0FBYztnQkFFVyxrQkFBa0I7c0JBQXJELFNBQVM7dUJBQUMsdUJBQXVCO2dCQUNSLGNBQWM7c0JBQXZDLFNBQVM7dUJBQUMsYUFBYTtnQkFFVyxpQkFBaUI7c0JBQW5ELFNBQVM7dUJBQUMsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBSZWFjdGl2ZUZvcm1zTW9kdWxlLCBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBsYXN0VmFsdWVGcm9tLCBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgU3RvcmVCdWlsZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3N0b3JlLWJ1aWxkZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFRvYXN0U2VydmljZSB9IGZyb20gJ3RhbmdvLWFwcC11aS1zaGFyZWQnO1xyXG5pbXBvcnQgKiBhcyBmYWJyaWMgZnJvbSBcImZhYnJpY1wiO1xyXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IFRpdGxlQ2FzZVBpcGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XHJcblxyXG50eXBlIFN0b3JlU3RhdHVzID0gJ3BlbmRpbmcnIHwgJ2FwcHJvdmVkJyB8ICdza2lwcGVkJyB8ICdub3RfZm91bmQnO1xyXG5cclxuaW50ZXJmYWNlIFN0b3JlQ2hpcCB7XHJcbiAgc3RvcmVDb2RlOiBzdHJpbmc7XHJcbiAgcGxhbm9JZDogc3RyaW5nO1xyXG4gIHN0YXR1czogU3RvcmVTdGF0dXM7XHJcbn1cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItY29sbGVjdGlvbi11cGRhdGUtYWknLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9jb2xsZWN0aW9uLXVwZGF0ZS1haS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2NvbGxlY3Rpb24tdXBkYXRlLWFpLmNvbXBvbmVudC5zY3NzJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGVdLFxyXG4gIHByb3ZpZGVyczogW1RpdGxlQ2FzZVBpcGVdLFxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIENvbGxlY3Rpb25VcGRhdGVBaUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB7XHJcblxyXG4gIGZvcm06IEZvcm1Hcm91cDtcclxuICBsb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2JlZm9yZUNhbnZhcycpIGJlZm9yZUNhbnZhc1JlZiE6IEVsZW1lbnRSZWY8SFRNTENhbnZhc0VsZW1lbnQ+O1xyXG4gIGJlZm9yZUNhbnZhcyE6IGZhYnJpYy5DYW52YXM7XHJcbiAgQFZpZXdDaGlsZChcImJlZm9yZUNhbnZhc0NvbnRhaW5lclwiKSBiZWZvcmVDb250YWluZXJSZWYhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdhZnRlckNhbnZhcycpIGFmdGVyQ2FudmFzUmVmITogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XHJcbiAgYWZ0ZXJDYW52YXMhOiBmYWJyaWMuQ2FudmFzO1xyXG4gIEBWaWV3Q2hpbGQoXCJhZnRlckNhbnZhc0NvbnRhaW5lclwiKSBhZnRlckNvbnRhaW5lclJlZiE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xyXG4gIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcclxuICBwbGFub0RhdGE6IGFueTtcclxuICBmbG9vckRhdGE6IGFueTtcclxuICB3YWxsVGhpY2tuZXNzID0gMzA7XHJcbiAgdmVydGljYWxNYXJnaW4gPSAoMS4yNSAvIDEwMCkgKiB0aGlzLnRvUGl4ZWxzKDE1MjQsIFwibW1cIik7XHJcbiAgY2RuVXJsOiBzdHJpbmc7XHJcbiAgYWN0aXZlSGlnaGxpZ2h0OiBmYWJyaWMuUmVjdCB8IG51bGwgPSBudWxsO1xyXG4gIGNhbmNlbEhpZ2hsaWdodEJsaW5rID0gZmFsc2U7XHJcbiAgc3RvcmVDaGlwczogU3RvcmVDaGlwW10gPSBbXTtcclxuICBzZWxlY3RlZFN0b3JlPzogc3RyaW5nO1xyXG4gIHNlbGVjdGVkRml4dHVyZTogYW55XHJcblxyXG5cclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBhcGlTZXJ2aWNlOiBTdG9yZUJ1aWxkZXJTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB0b2FzdFNlcnZpY2U6IFRvYXN0U2VydmljZSxcclxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHJpdmF0ZSB0aXRsZUNhc2U6IFRpdGxlQ2FzZVBpcGUsXHJcblxyXG4gICkge1xyXG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XHJcbiAgICAgIHN0b3JlczogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgICAgdXBkYXRlVHlwZTogWyd2bScsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxyXG4gICAgICBzZWxlY3Rpb25Dcml0ZXJpYTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgICAgdXBkYXRpb25Dcml0ZXJpYTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5yb3V0ZS5xdWVyeVBhcmFtc1xyXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKHBhcmFtcykgPT4ge1xyXG4gICAgICAgIGlmIChwYXJhbXM/LnBsYW5vSWQpIHtcclxuICAgICAgICAgIHRoaXMuZ2V0U3RvcmVGaXh0dXJlcyhwYXJhbXM/LnBsYW5vSWQpO1xyXG4gICAgICAgICAgaWYgKHBhcmFtcz8uZmxvb3JJZCkge1xyXG4gICAgICAgICAgICB0aGlzLmZsb29yRGF0YSA9IHsgX2lkOiBwYXJhbXM/LmZsb29ySWQgfTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYmVmb3JlQ2FudmFzID0gbmV3IGZhYnJpYy5DYW52YXModGhpcy5iZWZvcmVDYW52YXNSZWY/Lm5hdGl2ZUVsZW1lbnQsIHtcclxuICAgICAgc2VsZWN0aW9uRnVsbHlDb250YWluZWQ6IHRydWUsXHJcbiAgICAgIHBlclBpeGVsVGFyZ2V0RmluZDogdHJ1ZSxcclxuICAgICAgdGFyZ2V0RmluZFRvbGVyYW5jZTogNSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWZ0ZXJDYW52YXMgPSBuZXcgZmFicmljLkNhbnZhcyh0aGlzLmFmdGVyQ2FudmFzUmVmPy5uYXRpdmVFbGVtZW50LCB7XHJcbiAgICAgIHNlbGVjdGlvbkZ1bGx5Q29udGFpbmVkOiB0cnVlLFxyXG4gICAgICBwZXJQaXhlbFRhcmdldEZpbmQ6IHRydWUsXHJcbiAgICAgIHRhcmdldEZpbmRUb2xlcmFuY2U6IDUsXHJcbiAgICB9KTtcclxuXHJcblxyXG4gICAgdGhpcy5zZXR1cFpvb21IYW5kbGVycyh0aGlzLmJlZm9yZUNhbnZhcyk7XHJcbiAgICB0aGlzLnNldHVwWm9vbUhhbmRsZXJzKHRoaXMuYWZ0ZXJDYW52YXMpO1xyXG5cclxuICB9XHJcblxyXG4gIHNldHVwWm9vbUhhbmRsZXJzKGNhbnZhczogZmFicmljLkNhbnZhcyk6IHZvaWQge1xyXG4gICAgY2FudmFzLm9uKFwibW91c2U6d2hlZWxcIiwgKG9wdDogZmFicmljLlRFdmVudDxXaGVlbEV2ZW50PikgPT4ge1xyXG4gICAgICBjb25zdCBlID0gb3B0LmU7XHJcblxyXG4gICAgICBpZiAoZS5jdHJsS2V5IHx8IGUubWV0YUtleSkge1xyXG4gICAgICAgIGNvbnN0IGRlbHRhID0gZS5kZWx0YVk7XHJcbiAgICAgICAgbGV0IHpvb20gPSBjYW52YXMuZ2V0Wm9vbSgpO1xyXG4gICAgICAgIHpvb20gKj0gMC45OTUgKiogZGVsdGE7XHJcblxyXG4gICAgICAgIHpvb20gPSBNYXRoLm1heCgwLjIsIE1hdGgubWluKHpvb20sIDMpKTtcclxuXHJcbiAgICAgICAgY2FudmFzLnpvb21Ub1BvaW50KFxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICB4OiBlLm9mZnNldFgsXHJcbiAgICAgICAgICAgIHk6IGUub2Zmc2V0WSxcclxuICAgICAgICAgIH0gYXMgZmFicmljLlBvaW50LFxyXG4gICAgICAgICAgem9vbVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBsZXQgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgbGV0IGxhc3RQb3NYID0gMDtcclxuICAgIGxldCBsYXN0UG9zWSA9IDA7XHJcblxyXG4gICAgY2FudmFzLm9uKFwibW91c2U6ZG93blwiLCAob3B0OiBhbnkpID0+IHtcclxuICAgICAgaWYgKCFvcHQudGFyZ2V0KSB7XHJcbiAgICAgICAgaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgY2FudmFzLnNlbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgIGNvbnN0IGUgPSBvcHQuZTtcclxuICAgICAgICBsYXN0UG9zWCA9IGUuY2xpZW50WDtcclxuICAgICAgICBsYXN0UG9zWSA9IGUuY2xpZW50WTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY2FudmFzLm9uKFwibW91c2U6bW92ZVwiLCAob3B0OiBhbnkpID0+IHtcclxuICAgICAgaWYgKGlzRHJhZ2dpbmcgJiYgY2FudmFzLnZpZXdwb3J0VHJhbnNmb3JtKSB7XHJcbiAgICAgICAgY29uc3QgZSA9IG9wdC5lO1xyXG4gICAgICAgIGNvbnN0IHZwdCA9IGNhbnZhcy52aWV3cG9ydFRyYW5zZm9ybTtcclxuICAgICAgICB2cHRbNF0gKz0gZS5jbGllbnRYIC0gbGFzdFBvc1g7XHJcbiAgICAgICAgdnB0WzVdICs9IGUuY2xpZW50WSAtIGxhc3RQb3NZO1xyXG4gICAgICAgIGNhbnZhcy5yZXF1ZXN0UmVuZGVyQWxsKCk7XHJcbiAgICAgICAgbGFzdFBvc1ggPSBlLmNsaWVudFg7XHJcbiAgICAgICAgbGFzdFBvc1kgPSBlLmNsaWVudFk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGNhbnZhcy5vbihcIm1vdXNlOnVwXCIsICgpID0+IHtcclxuICAgICAgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgICBjYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlQWlSZXNwb25zZUZpeHR1cmUoZml4dHVyZTogYW55KSB7XHJcbiAgICBsZXQgbWF0Y2hGb3VuZCA9IGZhbHNlXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmxvb3JEYXRhLmxheW91dFBvbHlnb24ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZmxvb3JEYXRhLmxheW91dFBvbHlnb25baV07XHJcblxyXG4gICAgICBpZiAoZWxlbWVudC5lbGVtZW50VHlwZSA9PT0gJ3dhbGwnICYmIEFycmF5LmlzQXJyYXkoZWxlbWVudC5maXh0dXJlcykpIHtcclxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsZW1lbnQuZml4dHVyZXMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgIGNvbnN0IGZ4ID0gZWxlbWVudC5maXh0dXJlc1tqXTtcclxuXHJcbiAgICAgICAgICBpZiAoZnguX2lkID09PSBmaXh0dXJlLl9pZCkge1xyXG4gICAgICAgICAgICB0aGlzLmZsb29yRGF0YS5sYXlvdXRQb2x5Z29uW2ldLmZpeHR1cmVzW2pdID0ge1xyXG4gICAgICAgICAgICAgIC4uLmZpeHR1cmVcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgbWF0Y2hGb3VuZCA9IHRydWVcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEZpeHR1cmUgPSBmaXh0dXJlXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChtYXRjaEZvdW5kKSByZXR1cm47XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmZsb29yRGF0YT8uY2VudGVyRml4dHVyZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBmeCA9IHRoaXMuZmxvb3JEYXRhPy5jZW50ZXJGaXh0dXJlW2ldO1xyXG5cclxuICAgICAgaWYgKGZ4Ll9pZCA9PT0gZml4dHVyZS5faWQpIHtcclxuICAgICAgICB0aGlzLmZsb29yRGF0YS5jZW50ZXJGaXh0dXJlW2ldID0ge1xyXG4gICAgICAgICAgLi4uZml4dHVyZVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlbGVjdGVkRml4dHVyZSA9IGZpeHR1cmVcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgfVxyXG5cclxuICBzdWJtaXRQcm9tcHQoKSB7XHJcbiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcclxuICAgICAgdGhpcy5mb3JtLm1hcmtBbGxBc1RvdWNoZWQoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcclxuICAgICAgLi4udGhpcy5mb3JtLnZhbHVlLFxyXG4gICAgICBzdG9yZXM6IFt0aGlzLnNlbGVjdGVkU3RvcmVdXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuYXBpU2VydmljZS5maW5kRml4dHVyZUFpKHBheWxvYWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAocmVzLmNvZGUgPT09IDIwMCkge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVBaVJlc3BvbnNlRml4dHVyZShyZXMuZGF0YSlcclxuICAgICAgICAgIHRoaXMucmVuZGVyRmxvb3IodGhpcy5hZnRlckNhbnZhcylcclxuXHJcblxyXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbkZpeHR1cmUgPSB0aGlzLmFmdGVyQ2FudmFzXHJcbiAgICAgICAgICAgICAgLmdldE9iamVjdHMoKVxyXG4gICAgICAgICAgICAgIC5maW5kKFxyXG4gICAgICAgICAgICAgICAgKG9iajogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiBvYmoub2JqVHlwZSA9PT0gXCJmaXh0dXJlXCIgJiYgb2JqLmZpeHR1cmVJZCA9PT0gcmVzLmRhdGEuX2lkXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgKSBhcyBmYWJyaWMuR3JvdXAgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWFjdGlvbkZpeHR1cmUpIHJldHVybjtcclxuICAgICAgICAgICAgdGhpcy5oaWdobGlnaHRGaXh0dXJlKHRoaXMuYWZ0ZXJDYW52YXMsIGFjdGlvbkZpeHR1cmUsIHRydWUpO1xyXG4gICAgICAgICAgfSwgMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgYXN5bmMgZ2V0U3RvcmVGaXh0dXJlcyhzdG9yZUlkOiBzdHJpbmcpIHtcclxuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XHJcbiAgICB0aGlzLmFwaVNlcnZpY2VcclxuICAgICAgLmdldFN0b3JlRml4dHVyZXMoeyBpZDogW3N0b3JlSWRdIH0pXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcclxuICAgICAgLnN1YnNjcmliZSh7XHJcbiAgICAgICAgbmV4dDogYXN5bmMgKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIXJlcz8uZGF0YT8uWzBdPy5mbG9vcnM/Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgdGhpcy5wbGFub0RhdGEgPSBzdHJ1Y3R1cmVkQ2xvbmUocmVzLmRhdGFbMF0pO1xyXG5cclxuICAgICAgICAgIHRoaXMuZmxvb3JEYXRhID0gc3RydWN0dXJlZENsb25lKHJlcy5kYXRhWzBdLmZsb29yc1swXSk7XHJcblxyXG4gICAgICAgICAgdGhpcy5yZW5kZXJGbG9vcih0aGlzLmJlZm9yZUNhbnZhcyk7XHJcbiAgICAgICAgICB0aGlzLnJlbmRlckZsb29yKHRoaXMuYWZ0ZXJDYW52YXMpO1xyXG5cclxuICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucmVzaXplQ2FudmFzKHRoaXMuYmVmb3JlQ2FudmFzLCB0aGlzLmJlZm9yZUNvbnRhaW5lclJlZik7XHJcbiAgICAgICAgICAgIHRoaXMuZml0Q2FudmFzVG9MYXlvdXRBbmltYXRlZCh0aGlzLmJlZm9yZUNhbnZhcyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZUNhbnZhcyh0aGlzLmFmdGVyQ2FudmFzLCB0aGlzLmFmdGVyQ29udGFpbmVyUmVmKTtcclxuICAgICAgICAgICAgdGhpcy5maXRDYW52YXNUb0xheW91dEFuaW1hdGVkKHRoaXMuYWZ0ZXJDYW52YXMpO1xyXG4gICAgICAgICAgfSwgMzAwKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcclxuICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy50b2FzdFNlcnZpY2UuZ2V0RXJyb3JUb2FzdChcIkZhaWxlZCB0byBmZXRjaCBwbGFub1wiKTtcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xyXG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcmVzaXplQ2FudmFzKGNhbnZhczogZmFicmljLkNhbnZhcywgY29udGVpbmVyOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pik6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gY29udGVpbmVyLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBjYW52YXMuc2V0RGltZW5zaW9ucyh7XHJcbiAgICAgIHdpZHRoOiBjb250YWluZXIuY2xpZW50V2lkdGggLSA1MCxcclxuXHJcbiAgICAgIGhlaWdodDogY29udGFpbmVyLmNsaWVudEhlaWdodCAtIDQwLFxyXG4gICAgfSk7XHJcbiAgICBjYW52YXMucmVxdWVzdFJlbmRlckFsbCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmaXRDYW52YXNUb0xheW91dEFuaW1hdGVkKGNhbnZhczogZmFicmljLkNhbnZhcykge1xyXG4gICAgaWYgKCFjYW52YXMpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLmdldEZ1bGxMYXlvdXRCb3VuZHMoY2FudmFzKTtcclxuICAgIGlmICghYm91bmRzLndpZHRoIHx8ICFib3VuZHMuaGVpZ2h0KSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgY2FudmFzVyA9IGNhbnZhcy5nZXRXaWR0aCgpO1xyXG4gICAgY29uc3QgY2FudmFzSCA9IGNhbnZhcy5nZXRIZWlnaHQoKTtcclxuXHJcbiAgICAvLyBGaW5hbCB6b29tIHRvIGZpdCAod2l0aCBwYWRkaW5nKVxyXG4gICAgY29uc3Qgc2NhbGVYID0gY2FudmFzVyAvIGJvdW5kcy53aWR0aDtcclxuICAgIGNvbnN0IHNjYWxlWSA9IGNhbnZhc0ggLyBib3VuZHMuaGVpZ2h0O1xyXG4gICAgY29uc3QgdGFyZ2V0Wm9vbSA9IE1hdGgubWluKHNjYWxlWCwgc2NhbGVZKSAqIDAuOTsgLy8gcGFkZGluZyAxMCVcclxuXHJcbiAgICAvLyBEZXNpcmVkIHZpZXdwb3J0IG9mZnNldCB0byBjZW50ZXIgbGF5b3V0XHJcbiAgICBjb25zdCB0YXJnZXRWcHQgPSBbXHJcbiAgICAgIC4uLihjYW52YXMudmlld3BvcnRUcmFuc2Zvcm0gfHwgWzEsIDAsIDAsIDEsIDAsIDBdKSxcclxuICAgIF0gYXMgZmFicmljLlRNYXQyRDtcclxuXHJcbiAgICB0YXJnZXRWcHRbMF0gPSB0YXJnZXRab29tOyAvLyBzY2FsZVhcclxuICAgIHRhcmdldFZwdFszXSA9IHRhcmdldFpvb207IC8vIHNjYWxlWVxyXG5cclxuICAgIHRhcmdldFZwdFs0XSA9IGNhbnZhc1cgLyAyIC0gKGJvdW5kcy5sZWZ0ICsgYm91bmRzLndpZHRoIC8gMikgKiB0YXJnZXRab29tOyAvLyBjZW50ZXIgWFxyXG4gICAgdGFyZ2V0VnB0WzVdID0gY2FudmFzSCAvIDIgLSAoYm91bmRzLnRvcCArIGJvdW5kcy5oZWlnaHQgLyAyKSAqIHRhcmdldFpvb207IC8vIGNlbnRlciBZXHJcblxyXG4gICAgLy8gQ3VycmVudCB2aWV3cG9ydCAoc3RhcnRpbmcgcG9pbnQgb2YgYW5pbWF0aW9uKVxyXG4gICAgY29uc3Qgc3RhcnRWcHQgPSBbLi4uY2FudmFzLnZpZXdwb3J0VHJhbnNmb3JtIV0gYXMgZmFicmljLlRNYXQyRDtcclxuXHJcbiAgICBmYWJyaWMudXRpbC5hbmltYXRlKHtcclxuICAgICAgc3RhcnRWYWx1ZTogMCxcclxuICAgICAgZW5kVmFsdWU6IDEsXHJcbiAgICAgIGR1cmF0aW9uOiAxMDAsXHJcbiAgICAgIGVhc2luZzogZmFicmljLnV0aWwuZWFzZS5lYXNlT3V0Q3ViaWMsXHJcbiAgICAgIG9uQ2hhbmdlOiAodmFsdWU6IG51bWJlcikgPT4ge1xyXG4gICAgICAgIGNvbnN0IHZwdCA9IGNhbnZhcy52aWV3cG9ydFRyYW5zZm9ybSE7XHJcblxyXG4gICAgICAgIC8vIEludGVycG9sYXRlIG1hdHJpeCB2YWx1ZXNcclxuICAgICAgICB2cHRbMF0gPSBzdGFydFZwdFswXSArICh0YXJnZXRWcHRbMF0gLSBzdGFydFZwdFswXSkgKiB2YWx1ZTtcclxuICAgICAgICB2cHRbM10gPSBzdGFydFZwdFszXSArICh0YXJnZXRWcHRbM10gLSBzdGFydFZwdFszXSkgKiB2YWx1ZTtcclxuICAgICAgICB2cHRbNF0gPSBzdGFydFZwdFs0XSArICh0YXJnZXRWcHRbNF0gLSBzdGFydFZwdFs0XSkgKiB2YWx1ZTtcclxuICAgICAgICB2cHRbNV0gPSBzdGFydFZwdFs1XSArICh0YXJnZXRWcHRbNV0gLSBzdGFydFZwdFs1XSkgKiB2YWx1ZTtcclxuXHJcbiAgICAgICAgY2FudmFzLnJlcXVlc3RSZW5kZXJBbGwoKTtcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRGdWxsTGF5b3V0Qm91bmRzKGNhbnZhczogZmFicmljLkNhbnZhcykge1xyXG4gICAgY29uc3Qgb2JqZWN0cyA9IGNhbnZhcy5nZXRPYmplY3RzKCk7XHJcbiAgICBpZiAoIW9iamVjdHMubGVuZ3RoKSByZXR1cm4geyBsZWZ0OiAwLCB0b3A6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDAgfTtcclxuXHJcbiAgICBsZXQgbWluWCA9IEluZmluaXR5LFxyXG4gICAgICBtaW5ZID0gSW5maW5pdHksXHJcbiAgICAgIG1heFggPSAtSW5maW5pdHksXHJcbiAgICAgIG1heFkgPSAtSW5maW5pdHk7XHJcblxyXG4gICAgZm9yIChjb25zdCBvYmogb2Ygb2JqZWN0cykge1xyXG4gICAgICBjb25zdCByZWN0ID0gb2JqLmdldEJvdW5kaW5nUmVjdCgpO1xyXG4gICAgICBtaW5YID0gTWF0aC5taW4obWluWCwgcmVjdC5sZWZ0KTtcclxuICAgICAgbWluWSA9IE1hdGgubWluKG1pblksIHJlY3QudG9wKTtcclxuICAgICAgbWF4WCA9IE1hdGgubWF4KG1heFgsIHJlY3QubGVmdCArIHJlY3Qud2lkdGgpO1xyXG4gICAgICBtYXhZID0gTWF0aC5tYXgobWF4WSwgcmVjdC50b3AgKyByZWN0LmhlaWdodCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbGVmdDogbWluWCxcclxuICAgICAgdG9wOiBtaW5ZLFxyXG4gICAgICB3aWR0aDogbWF4WCAtIG1pblgsXHJcbiAgICAgIGhlaWdodDogbWF4WSAtIG1pblksXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcmVuZGVyRmxvb3IoY2FudmFzOiBmYWJyaWMuQ2FudmFzKSB7XHJcbiAgICB0aGlzLmRyYXdJbml0aWFsQ29udGVudChjYW52YXMpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgZHJhd0luaXRpYWxDb250ZW50KGNhbnZhczogZmFicmljLkNhbnZhcyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY2FudmFzLmNsZWFyKCk7XHJcbiAgICBhd2FpdCB0aGlzLmRyYXdMYXlvdXRFbGVtZW50cyhjYW52YXMpO1xyXG4gICAgLy8gdGhpcy5kcmF3QmcoKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRyYXdMYXlvdXRFbGVtZW50cyhjYW52YXM6IGZhYnJpYy5DYW52YXMpIHtcclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLmZsb29yRGF0YS5sYXlvdXRQb2x5Z29uLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5mbG9vckRhdGEubGF5b3V0UG9seWdvbltpbmRleF07XHJcblxyXG4gICAgICBsZXQgd2FsbDtcclxuXHJcbiAgICAgIGVsZW1lbnQucmVsYXRpdmVQb3NpdGlvbiA/Pz0ge1xyXG4gICAgICAgIHg6IDAsXHJcbiAgICAgICAgeTogMCxcclxuICAgICAgICB1bml0OiBcImZ0XCIsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB4ID0gdGhpcy50b1BpeGVscyhlbGVtZW50LnJlbGF0aXZlUG9zaXRpb24ueCwgZWxlbWVudC51bml0KTtcclxuICAgICAgY29uc3QgeSA9IHRoaXMudG9QaXhlbHMoZWxlbWVudC5yZWxhdGl2ZVBvc2l0aW9uLnksIGVsZW1lbnQudW5pdCk7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudC5lbGVtZW50VHlwZSA9PT0gXCJ3YWxsXCIpIHtcclxuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLndhbGxUaGlja25lc3M7XHJcbiAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLnRvUGl4ZWxzKGVsZW1lbnQuZGlzdGFuY2UsIGVsZW1lbnQudW5pdCk7XHJcbiAgICAgICAgd2FsbCA9IGF3YWl0IHRoaXMuZHJhd1dhbGwoY2FudmFzLCB4LCB5LCBoZWlnaHQsIHdpZHRoLCBlbGVtZW50KTtcclxuICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmVsZW1lbnRUeXBlID09PSBcImVudHJhbmNlXCIpIHtcclxuICAgICAgICBjb25zdCBhcnJvd1dpZHRoID0gODA7XHJcbiAgICAgICAgY29uc3QgYXJyb3dIZWlnaHQgPSA3NTtcclxuICAgICAgICBjb25zdCBhcnJvd0Jhc2UgPSA0MDtcclxuICAgICAgICB0aGlzLmRyYXdFbnRyYW5jZShcclxuICAgICAgICAgIGNhbnZhcyxcclxuICAgICAgICAgIHgsXHJcbiAgICAgICAgICB5LFxyXG4gICAgICAgICAgYXJyb3dXaWR0aCxcclxuICAgICAgICAgIGFycm93SGVpZ2h0LFxyXG4gICAgICAgICAgYXJyb3dCYXNlLFxyXG4gICAgICAgICAgZWxlbWVudFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlbGVtZW50LmVsZW1lbnRUeXBlID09PSBcIndhbGxcIikge1xyXG4gICAgICAgIGNvbnN0IGZpeHR1cmVHcm91cHM6IGZhYnJpYy5Hcm91cFtdID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZWxlbWVudD8uZml4dHVyZXM/Lmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICBjb25zdCBmaXh0dXJlID0gZWxlbWVudC5maXh0dXJlc1tqXTtcclxuICAgICAgICAgIGNvbnN0IHggPSB0aGlzLnRvUGl4ZWxzKFxyXG4gICAgICAgICAgICBmaXh0dXJlLnJlbGF0aXZlUG9zaXRpb24ueCxcclxuICAgICAgICAgICAgZml4dHVyZS5yZWxhdGl2ZVBvc2l0aW9uLnVuaXRcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBjb25zdCB5ID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICAgICAgZml4dHVyZS5yZWxhdGl2ZVBvc2l0aW9uLnksXHJcbiAgICAgICAgICAgIGZpeHR1cmUucmVsYXRpdmVQb3NpdGlvbi51bml0XHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgY29uc3QgZml4dHVyZUhlaWdodCA9IHRoaXMudG9QaXhlbHMoXHJcbiAgICAgICAgICAgIGZpeHR1cmUuZml4dHVyZVN0YXRpY0xlbmd0aC52YWx1ZSxcclxuICAgICAgICAgICAgZml4dHVyZS5maXh0dXJlU3RhdGljTGVuZ3RoLnVuaXRcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBjb25zdCBmaXh0dXJlV2lkdGggPSB0aGlzLnRvUGl4ZWxzKFxyXG4gICAgICAgICAgICBmaXh0dXJlLmZpeHR1cmVTdGF0aWNXaWR0aC52YWx1ZSxcclxuICAgICAgICAgICAgZml4dHVyZS5maXh0dXJlU3RhdGljV2lkdGgudW5pdFxyXG4gICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICBjb25zdCBmaXh0dXJlT2JqID0gYXdhaXQgdGhpcy5kcmF3Rml4dHVyZShcclxuICAgICAgICAgICAgY2FudmFzLFxyXG4gICAgICAgICAgICB4LFxyXG4gICAgICAgICAgICB5LFxyXG4gICAgICAgICAgICBmaXh0dXJlSGVpZ2h0LFxyXG4gICAgICAgICAgICBmaXh0dXJlV2lkdGgsXHJcbiAgICAgICAgICAgIGZpeHR1cmVcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBmaXh0dXJlR3JvdXBzLnB1c2goZml4dHVyZU9iaiBhcyBmYWJyaWMuR3JvdXApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVsZW1lbnQuaXNMb2NrZWQgJiYgd2FsbCkge1xyXG4gICAgICAgICAgY2FudmFzLnJlbW92ZSh3YWxsKTtcclxuICAgICAgICAgIGZpeHR1cmVHcm91cHMuZm9yRWFjaCgoZikgPT4gY2FudmFzLnJlbW92ZShmKSk7XHJcblxyXG4gICAgICAgICAgY29uc3QgY29tYmluZWRHcm91cCA9IG5ldyBmYWJyaWMuR3JvdXAoW3dhbGwsIC4uLmZpeHR1cmVHcm91cHNdLCB7XHJcbiAgICAgICAgICAgIGhhc0NvbnRyb2xzOiB0cnVlLFxyXG4gICAgICAgICAgICBzZWxlY3RhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBzdWJUYXJnZXRDaGVjazogdHJ1ZSxcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIGNvbWJpbmVkR3JvdXAuc2V0KHsgaXNMb2NrZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICBjYW52YXMuYWRkKGNvbWJpbmVkR3JvdXApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBlbGVtZW50Py5vdGhlckVsZW1lbnRzPy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgY29uc3Qgb3RoZXJFbGVtZW50ID0gZWxlbWVudC5vdGhlckVsZW1lbnRzW2pdO1xyXG4gICAgICAgICAgY29uc3QgeCA9IHRoaXMudG9QaXhlbHMob3RoZXJFbGVtZW50LnJlbGF0aXZlUG9zaXRpb24ueCwgXCJmdFwiKTtcclxuICAgICAgICAgIGNvbnN0IHkgPSB0aGlzLnRvUGl4ZWxzKG90aGVyRWxlbWVudC5yZWxhdGl2ZVBvc2l0aW9uLnksIFwiZnRcIik7XHJcbiAgICAgICAgICBjb25zdCBhID0gb3RoZXJFbGVtZW50LnJlbGF0aXZlUG9zaXRpb24uYW5nbGU7XHJcbiAgICAgICAgICBjb25zdCBoID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICAgICAgb3RoZXJFbGVtZW50LmZpeHR1cmVTdGF0aWNMZW5ndGgudmFsdWUsXHJcbiAgICAgICAgICAgIG90aGVyRWxlbWVudC5maXh0dXJlU3RhdGljTGVuZ3RoLnVuaXRcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBjb25zdCB3ID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICAgICAgb3RoZXJFbGVtZW50LmZpeHR1cmVTdGF0aWNXaWR0aC52YWx1ZSxcclxuICAgICAgICAgICAgb3RoZXJFbGVtZW50LmZpeHR1cmVTdGF0aWNXaWR0aC51bml0XHJcbiAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgIGNvbnN0IGZpeHR1cmVPYmogPSB0aGlzLmRyYXdPdGhlckVsZW1lbnRzV2l0aExhYmVsKFxyXG4gICAgICAgICAgICBjYW52YXMsXHJcbiAgICAgICAgICAgIHgsXHJcbiAgICAgICAgICAgIHksXHJcbiAgICAgICAgICAgIGEsXHJcbiAgICAgICAgICAgIHcsXHJcbiAgICAgICAgICAgIGgsXHJcbiAgICAgICAgICAgIG90aGVyRWxlbWVudFxyXG4gICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAvLyBlbGVtZW50c0dyb3VwLnB1c2goZml4dHVyZU9iaiBhcyBmYWJyaWMuR3JvdXApO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5mbG9vckRhdGE/LmNlbnRlckZpeHR1cmU/Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGZpeHR1cmUgPSB0aGlzLmZsb29yRGF0YS5jZW50ZXJGaXh0dXJlW2ldO1xyXG4gICAgICBjb25zdCB4ID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICBmaXh0dXJlLnJlbGF0aXZlUG9zaXRpb24ueCxcclxuICAgICAgICBmaXh0dXJlLnJlbGF0aXZlUG9zaXRpb24udW5pdFxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCB5ID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICBmaXh0dXJlLnJlbGF0aXZlUG9zaXRpb24ueSxcclxuICAgICAgICBmaXh0dXJlLnJlbGF0aXZlUG9zaXRpb24udW5pdFxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBmaXh0dXJlSGVpZ2h0ID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICBmaXh0dXJlLmZpeHR1cmVTdGF0aWNMZW5ndGgudmFsdWUsXHJcbiAgICAgICAgZml4dHVyZS5maXh0dXJlU3RhdGljTGVuZ3RoLnVuaXRcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgZml4dHVyZVdpZHRoID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICBmaXh0dXJlLmZpeHR1cmVTdGF0aWNXaWR0aC52YWx1ZSxcclxuICAgICAgICBmaXh0dXJlLmZpeHR1cmVTdGF0aWNXaWR0aC51bml0XHJcbiAgICAgICk7XHJcbiAgICAgIGF3YWl0IHRoaXMuZHJhd0ZpeHR1cmUoXHJcbiAgICAgICAgY2FudmFzLFxyXG4gICAgICAgIHgsXHJcbiAgICAgICAgeSxcclxuICAgICAgICBmaXh0dXJlSGVpZ2h0LFxyXG4gICAgICAgIGZpeHR1cmVXaWR0aCxcclxuICAgICAgICBmaXh0dXJlXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmZsb29yRGF0YT8ub3RoZXJFbGVtZW50cz8ubGVuZ3RoOyBqKyspIHtcclxuICAgICAgY29uc3Qgb3RoZXJFbGVtZW50ID0gdGhpcy5mbG9vckRhdGEub3RoZXJFbGVtZW50c1tqXTtcclxuICAgICAgY29uc3QgeCA9IHRoaXMudG9QaXhlbHMob3RoZXJFbGVtZW50LnJlbGF0aXZlUG9zaXRpb24ueCwgXCJmdFwiKTtcclxuICAgICAgY29uc3QgeSA9IHRoaXMudG9QaXhlbHMob3RoZXJFbGVtZW50LnJlbGF0aXZlUG9zaXRpb24ueSwgXCJmdFwiKTtcclxuICAgICAgY29uc3QgYSA9IG90aGVyRWxlbWVudC5yZWxhdGl2ZVBvc2l0aW9uLmFuZ2xlO1xyXG4gICAgICBjb25zdCBoID0gdGhpcy50b1BpeGVscyhcclxuICAgICAgICBvdGhlckVsZW1lbnQuZml4dHVyZVN0YXRpY0xlbmd0aC52YWx1ZSxcclxuICAgICAgICBvdGhlckVsZW1lbnQuZml4dHVyZVN0YXRpY0xlbmd0aC51bml0XHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHcgPSB0aGlzLnRvUGl4ZWxzKFxyXG4gICAgICAgIG90aGVyRWxlbWVudC5maXh0dXJlU3RhdGljV2lkdGgudmFsdWUsXHJcbiAgICAgICAgb3RoZXJFbGVtZW50LmZpeHR1cmVTdGF0aWNXaWR0aC51bml0XHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb25zdCBmaXh0dXJlT2JqID0gdGhpcy5kcmF3T3RoZXJFbGVtZW50c1dpdGhMYWJlbChcclxuICAgICAgICBjYW52YXMsXHJcbiAgICAgICAgeCxcclxuICAgICAgICB5LFxyXG4gICAgICAgIGEsXHJcbiAgICAgICAgdyxcclxuICAgICAgICBoLFxyXG4gICAgICAgIG90aGVyRWxlbWVudFxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcblxyXG4gIHRvUGl4ZWxzKHZhbHVlOiBudW1iZXIsIHVuaXQ6IHN0cmluZywgZHBpID0gMi44KSB7XHJcbiAgICBsZXQgcGl4ZWxzOiBudW1iZXI7XHJcblxyXG4gICAgaWYgKHVuaXQgPT09IFwibW1cIikge1xyXG4gICAgICBwaXhlbHMgPSAodmFsdWUgLyAyNS40KSAqIGRwaTtcclxuICAgIH0gZWxzZSBpZiAodW5pdCA9PT0gXCJmdFwiKSB7XHJcbiAgICAgIHBpeGVscyA9IHZhbHVlICogMTIgKiBkcGk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCB1bml0LiBVc2UgJ21tJyBvciAnZnQnLlwiKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gTnVtYmVyKHBpeGVscy50b0ZpeGVkKDQpKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRyYXdXYWxsKFxyXG4gICAgY2FudmFzOiBmYWJyaWMuQ2FudmFzLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgaGVpZ2h0OiBudW1iZXIsXHJcbiAgICB3aWR0aDogbnVtYmVyLFxyXG4gICAgZWxlbWVudERhdGE6IGFueVxyXG4gICkge1xyXG4gICAgY29uc3QgcmFkaXVzID0gNTtcclxuICAgIGNvbnN0IGZpbGxDb2xvciA9IFwiI0Y2RkNGRlwiO1xyXG4gICAgY29uc3Qgc3Ryb2tlQ29sb3IgPSBcIiNEMEQ1RERcIjtcclxuICAgIGNvbnN0IGxhYmVsQ29sb3IgPSBcIiMwMDlCRjNcIjtcclxuICAgIGxldCB0ZXh0ID0gYCR7dGhpcy50aXRsZUNhc2UudHJhbnNmb3JtKGVsZW1lbnREYXRhLmVsZW1lbnRUeXBlKX0gJHtlbGVtZW50RGF0YS5lbGVtZW50TnVtYmVyXHJcbiAgICAgIH1gO1xyXG5cclxuICAgIGNvbnN0IHdhbGwgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICBsZWZ0OiAwLFxyXG4gICAgICB0b3A6IDAsXHJcbiAgICAgIHdpZHRoLFxyXG4gICAgICBoZWlnaHQsXHJcbiAgICAgIHJ4OiByYWRpdXMsXHJcbiAgICAgIHJ5OiByYWRpdXMsXHJcbiAgICAgIGZpbGw6IGZpbGxDb2xvcixcclxuICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcclxuICAgICAgc3Ryb2tlV2lkdGg6IDAuMjcsXHJcbiAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICBzdHJva2VVbmlmb3JtOiB0cnVlLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgY2VudGVyWCA9IHdpZHRoIC8gMjtcclxuICAgIGNvbnN0IGNlbnRlclkgPSBoZWlnaHQgLyAyO1xyXG4gICAgY29uc3QgaXNWZXJ0aWNhbCA9IGhlaWdodCA+IHdpZHRoO1xyXG5cclxuICAgIGNvbnN0IGxhYmVsID0gbmV3IGZhYnJpYy5GYWJyaWNUZXh0KHRleHQsIHtcclxuICAgICAgbGVmdDogY2VudGVyWCxcclxuICAgICAgdG9wOiBjZW50ZXJZLFxyXG4gICAgICBmb250U2l6ZTogMTAsXHJcbiAgICAgIGZvbnRGYW1pbHk6IFwiSW50ZXJcIixcclxuICAgICAgZm9udFdlaWdodDogXCI1MDBcIixcclxuICAgICAgZmlsbDogbGFiZWxDb2xvcixcclxuICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgb3JpZ2luWTogXCJjZW50ZXJcIixcclxuICAgICAgYW5nbGU6IGlzVmVydGljYWwgPyAtOTAgOiAwLFxyXG4gICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGFycm93SGVhZCA9IDU7XHJcbiAgICBjb25zdCBlbGVtZW50czogZmFicmljLk9iamVjdFtdID0gW3dhbGwsIGxhYmVsXTtcclxuXHJcbiAgICBpZiAoaXNWZXJ0aWNhbCkge1xyXG4gICAgICBjb25zdCB0ZXh0V2lkdGggPSBsYWJlbC53aWR0aCB8fCAwO1xyXG4gICAgICBjb25zdCB0b3BBcnJvd1kgPSA1O1xyXG4gICAgICBjb25zdCB0b3BBcnJvd0VuZFkgPSBjZW50ZXJZIC0gdGV4dFdpZHRoIC8gMiAtIDU7XHJcblxyXG4gICAgICBpZiAodG9wQXJyb3dFbmRZID4gdG9wQXJyb3dZICsgYXJyb3dIZWFkKSB7XHJcbiAgICAgICAgZWxlbWVudHMucHVzaChcclxuICAgICAgICAgIG5ldyBmYWJyaWMuTGluZShbY2VudGVyWCwgdG9wQXJyb3dZLCBjZW50ZXJYLCB0b3BBcnJvd0VuZFldLCB7XHJcbiAgICAgICAgICAgIHN0cm9rZTogbGFiZWxDb2xvcixcclxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXHJcbiAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgICBuZXcgZmFicmljLlRyaWFuZ2xlKHtcclxuICAgICAgICAgICAgbGVmdDogY2VudGVyWCxcclxuICAgICAgICAgICAgdG9wOiB0b3BBcnJvd1ksXHJcbiAgICAgICAgICAgIHdpZHRoOiBhcnJvd0hlYWQsXHJcbiAgICAgICAgICAgIGhlaWdodDogYXJyb3dIZWFkLFxyXG4gICAgICAgICAgICBhbmdsZTogMCxcclxuICAgICAgICAgICAgZmlsbDogbGFiZWxDb2xvcixcclxuICAgICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgICAgb3JpZ2luWTogXCJib3R0b21cIixcclxuICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGJvdHRvbUFycm93U3RhcnRZID0gY2VudGVyWSArIHRleHRXaWR0aCAvIDIgKyA1O1xyXG4gICAgICBjb25zdCBib3R0b21BcnJvd0VuZFkgPSBoZWlnaHQgLSA1O1xyXG5cclxuICAgICAgaWYgKGJvdHRvbUFycm93RW5kWSA+IGJvdHRvbUFycm93U3RhcnRZICsgYXJyb3dIZWFkKSB7XHJcbiAgICAgICAgZWxlbWVudHMucHVzaChcclxuICAgICAgICAgIG5ldyBmYWJyaWMuTGluZShcclxuICAgICAgICAgICAgW2NlbnRlclgsIGJvdHRvbUFycm93U3RhcnRZLCBjZW50ZXJYLCBib3R0b21BcnJvd0VuZFldLFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgc3Ryb2tlOiBsYWJlbENvbG9yLFxyXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxyXG4gICAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgbmV3IGZhYnJpYy5UcmlhbmdsZSh7XHJcbiAgICAgICAgICAgIGxlZnQ6IGNlbnRlclgsXHJcbiAgICAgICAgICAgIHRvcDogYm90dG9tQXJyb3dFbmRZLFxyXG4gICAgICAgICAgICB3aWR0aDogYXJyb3dIZWFkLFxyXG4gICAgICAgICAgICBoZWlnaHQ6IGFycm93SGVhZCxcclxuICAgICAgICAgICAgYW5nbGU6IDE4MCxcclxuICAgICAgICAgICAgZmlsbDogbGFiZWxDb2xvcixcclxuICAgICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgICAgb3JpZ2luWTogXCJ0b3BcIixcclxuICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IHRleHRXaWR0aCA9IGxhYmVsLndpZHRoIHx8IDA7XHJcbiAgICAgIGNvbnN0IGxlZnRBcnJvd1N0YXJ0WCA9IDU7XHJcbiAgICAgIGNvbnN0IGxlZnRBcnJvd0VuZFggPSBjZW50ZXJYIC0gdGV4dFdpZHRoIC8gMiAtIDU7XHJcblxyXG4gICAgICBpZiAobGVmdEFycm93RW5kWCA+IGxlZnRBcnJvd1N0YXJ0WCArIGFycm93SGVhZCkge1xyXG4gICAgICAgIGVsZW1lbnRzLnB1c2goXHJcbiAgICAgICAgICBuZXcgZmFicmljLkxpbmUoW2xlZnRBcnJvd1N0YXJ0WCwgY2VudGVyWSwgbGVmdEFycm93RW5kWCwgY2VudGVyWV0sIHtcclxuICAgICAgICAgICAgc3Ryb2tlOiBsYWJlbENvbG9yLFxyXG4gICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcclxuICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICAgIG5ldyBmYWJyaWMuVHJpYW5nbGUoe1xyXG4gICAgICAgICAgICBsZWZ0OiBsZWZ0QXJyb3dTdGFydFgsXHJcbiAgICAgICAgICAgIHRvcDogY2VudGVyWSxcclxuICAgICAgICAgICAgd2lkdGg6IGFycm93SGVhZCxcclxuICAgICAgICAgICAgaGVpZ2h0OiBhcnJvd0hlYWQsXHJcbiAgICAgICAgICAgIGFuZ2xlOiAtOTAsXHJcbiAgICAgICAgICAgIGZpbGw6IGxhYmVsQ29sb3IsXHJcbiAgICAgICAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCByaWdodEFycm93U3RhcnRYID0gY2VudGVyWCArIHRleHRXaWR0aCAvIDIgKyA1O1xyXG4gICAgICBjb25zdCByaWdodEFycm93RW5kWCA9IHdpZHRoIC0gNTtcclxuXHJcbiAgICAgIGlmIChyaWdodEFycm93RW5kWCA+IHJpZ2h0QXJyb3dTdGFydFggKyBhcnJvd0hlYWQpIHtcclxuICAgICAgICBlbGVtZW50cy5wdXNoKFxyXG4gICAgICAgICAgbmV3IGZhYnJpYy5MaW5lKFxyXG4gICAgICAgICAgICBbcmlnaHRBcnJvd1N0YXJ0WCwgY2VudGVyWSwgcmlnaHRBcnJvd0VuZFgsIGNlbnRlclldLFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgc3Ryb2tlOiBsYWJlbENvbG9yLFxyXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxyXG4gICAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgbmV3IGZhYnJpYy5UcmlhbmdsZSh7XHJcbiAgICAgICAgICAgIGxlZnQ6IHJpZ2h0QXJyb3dFbmRYLFxyXG4gICAgICAgICAgICB0b3A6IGNlbnRlclksXHJcbiAgICAgICAgICAgIHdpZHRoOiBhcnJvd0hlYWQsXHJcbiAgICAgICAgICAgIGhlaWdodDogYXJyb3dIZWFkLFxyXG4gICAgICAgICAgICBhbmdsZTogOTAsXHJcbiAgICAgICAgICAgIGZpbGw6IGxhYmVsQ29sb3IsXHJcbiAgICAgICAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGNvbnN0IGdyb3VwID0gbmV3IGZhYnJpYy5Hcm91cChlbGVtZW50cywge1xyXG4gICAgICBsZWZ0OiB4LFxyXG4gICAgICB0b3A6IHksXHJcbiAgICAgIGhhc0NvbnRyb2xzOiB0cnVlLFxyXG4gICAgICBsb2NrU2NhbGluZ1g6IGlzVmVydGljYWwsXHJcbiAgICAgIGxvY2tTY2FsaW5nWTogIWlzVmVydGljYWwsXHJcbiAgICAgIC8vIGxvY2tSb3RhdGlvbjogdHJ1ZSxcclxuICAgICAgZXZlbnRlZDogdHJ1ZSxcclxuICAgICAgaG92ZXJDdXJzb3I6IFwicG9pbnRlclwiLFxyXG4gICAgICBhbmdsZTogZWxlbWVudERhdGEuYW5nbGUsXHJcbiAgICAgIHN1YlRhcmdldENoZWNrOiB0cnVlLFxyXG4gICAgfSkgYXMgZmFicmljLkdyb3VwICYge1xyXG4gICAgICBvYmpUeXBlOiBzdHJpbmc7XHJcbiAgICAgIGRhdGE6IGFueTtcclxuICAgIH07XHJcblxyXG4gICAgZ3JvdXAub2JqVHlwZSA9IGVsZW1lbnREYXRhLmVsZW1lbnRUeXBlO1xyXG4gICAgZ3JvdXAuZGF0YSA9IGVsZW1lbnREYXRhO1xyXG5cclxuXHJcbiAgICBjYW52YXMuYWRkKGdyb3VwKTtcclxuXHJcbiAgICAvLyBJZiBuZXdseSBhZGRlZCwgZm9jdXMgaXQgb25jZVxyXG4gICAgaWYgKChlbGVtZW50RGF0YSBhcyBhbnkpPy5uZXdBZGRlZCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNhbnZhcy5zZXRBY3RpdmVPYmplY3QoZ3JvdXApO1xyXG4gICAgICAgIGNhbnZhcy5yZXF1ZXN0UmVuZGVyQWxsKCk7XHJcbiAgICAgIH0gY2F0Y2ggeyB9XHJcbiAgICAgIGRlbGV0ZSAoZWxlbWVudERhdGEgYXMgYW55KS5uZXdBZGRlZDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZ3JvdXA7XHJcbiAgfVxyXG5cclxuICBkcmF3RW50cmFuY2UoXHJcbiAgICBjYW52YXM6IGZhYnJpYy5DYW52YXMsXHJcbiAgICB4OiBudW1iZXIsXHJcbiAgICB5OiBudW1iZXIsXHJcbiAgICB3aWR0aDogbnVtYmVyLFxyXG4gICAgaGVpZ2h0OiBudW1iZXIsXHJcbiAgICBhcnJvd1dpZHRoOiBudW1iZXIsXHJcbiAgICBlbGVtZW50RGF0YTogYW55XHJcbiAgKSB7XHJcbiAgICBjb25zdCBib2R5V2lkdGggPSB3aWR0aCAtIGFycm93V2lkdGg7XHJcblxyXG4gICAgY29uc3QgcGF0aERhdGEgPSBbXHJcbiAgICAgIGBNIDAgMGAsXHJcbiAgICAgIGBMICR7Ym9keVdpZHRofSAwYCxcclxuICAgICAgYEwgJHtib2R5V2lkdGh9ICR7LWhlaWdodCAvIDJ9YCxcclxuICAgICAgYEwgJHt3aWR0aH0gJHtoZWlnaHQgLyAyfWAsXHJcbiAgICAgIGBMICR7Ym9keVdpZHRofSAke2hlaWdodCArIGhlaWdodCAvIDJ9YCxcclxuICAgICAgYEwgJHtib2R5V2lkdGh9ICR7aGVpZ2h0fWAsXHJcbiAgICAgIGBMIDAgJHtoZWlnaHR9YCxcclxuICAgICAgYFpgLFxyXG4gICAgXS5qb2luKFwiIFwiKTtcclxuXHJcbiAgICBjb25zdCBhcnJvdyA9IG5ldyBmYWJyaWMuUGF0aChwYXRoRGF0YSwge1xyXG4gICAgICBmaWxsOiBcIiMwM0E5RjRcIixcclxuICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgIGV2ZW50ZWQ6IGZhbHNlLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgbWF4VGV4dEhlaWdodCA9IGhlaWdodCAtIDY7XHJcbiAgICBjb25zdCB0ZXh0ID0gbmV3IGZhYnJpYy5UZXh0KFwiRW50cmFuY2VcIiwge1xyXG4gICAgICBmb250RmFtaWx5OiBcIkFyaWFsXCIsXHJcbiAgICAgIGZvbnRXZWlnaHQ6IFwiYm9sZFwiLFxyXG4gICAgICBmaWxsOiBcIndoaXRlXCIsXHJcbiAgICAgIGFuZ2xlOiAtOTAsXHJcbiAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgIGxlZnQ6IDE1LFxyXG4gICAgICB0b3A6IGhlaWdodCAvIDIsXHJcbiAgICAgIGZvbnRTaXplOiAyMCxcclxuICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgIGV2ZW50ZWQ6IGZhbHNlLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgdGV4dEJvdW5kcyA9IHRleHQuZ2V0Qm91bmRpbmdSZWN0KCk7XHJcbiAgICBpZiAodGV4dEJvdW5kcy5oZWlnaHQgPiBtYXhUZXh0SGVpZ2h0KSB7XHJcbiAgICAgIGNvbnN0IHNjYWxlID0gbWF4VGV4dEhlaWdodCAvIHRleHRCb3VuZHMuaGVpZ2h0O1xyXG4gICAgICB0ZXh0LnNldChcImZvbnRTaXplXCIsIHRleHQuZm9udFNpemUhICogc2NhbGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGdyb3VwID0gbmV3IGZhYnJpYy5Hcm91cChbYXJyb3csIHRleHRdLCB7XHJcbiAgICAgIGxlZnQ6IHgsXHJcbiAgICAgIHRvcDogeSxcclxuICAgICAgbG9ja1NjYWxpbmdYOiB0cnVlLFxyXG4gICAgICBsb2NrU2NhbGluZ1k6IHRydWUsXHJcbiAgICAgIGxvY2tTY2FsaW5nRmxpcDogdHJ1ZSxcclxuICAgICAgYW5nbGU6IGVsZW1lbnREYXRhLmFuZ2xlLFxyXG4gICAgfSkgYXMgZmFicmljLkdyb3VwICYge1xyXG4gICAgICBvYmpUeXBlOiBzdHJpbmc7XHJcbiAgICAgIGRhdGE6IGFueTtcclxuICAgIH07XHJcblxyXG4gICAgZ3JvdXAub2JqVHlwZSA9IGVsZW1lbnREYXRhLmVsZW1lbnRUeXBlO1xyXG4gICAgZ3JvdXAuZGF0YSA9IGVsZW1lbnREYXRhO1xyXG5cclxuICAgIGNhbnZhcy5hZGQoZ3JvdXApO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgZHJhd0ZpeHR1cmUoXHJcbiAgICBjYW52YXM6IGZhYnJpYy5DYW52YXMsXHJcbiAgICB4OiBudW1iZXIsXHJcbiAgICB5OiBudW1iZXIsXHJcbiAgICBoZWlnaHQ6IG51bWJlcixcclxuICAgIHdpZHRoOiBudW1iZXIsXHJcbiAgICBmaXh0dXJlRGF0YTogYW55XHJcbiAgKSB7XHJcbiAgICBsZXQgZml4dHVyZUNvbG9yOiBhbnk7XHJcbiAgICAvLyBpZiAoW1wiZml4dHVyZVwiLCBcImZpeHR1cmUtcmVkb1wiXS5pbmNsdWRlcyh0aGlzLnB1Ymxpc2hpbmdTdGF0ZSkpIHtcclxuICAgIC8vICAgZml4dHVyZUNvbG9yID0ge1xyXG4gICAgLy8gICAgIHByaW1hcnk6XHJcbiAgICAvLyAgICAgICBmaXh0dXJlRGF0YS5zdGF0dXMgPT0gXCJcIiAmJiBmaXh0dXJlRGF0YS50YXNrU3RhdHVzID09IFwic3VibWl0XCJcclxuICAgIC8vICAgICAgICAgPyBcIiNhNWE2YThcIlxyXG4gICAgLy8gICAgICAgICA6IGZpeHR1cmVEYXRhLnN0YXR1cyA9PSBcImFncmVlXCJcclxuICAgIC8vICAgICAgICAgPyBcIiM2Q0U5QTZcIlxyXG4gICAgLy8gICAgICAgICA6IFwiIzUxQzFGRlwiLFxyXG4gICAgLy8gICAgIGZpbGw6XHJcbiAgICAvLyAgICAgICBmaXh0dXJlRGF0YS5zdGF0dXMgPT0gXCJcIiAmJiBmaXh0dXJlRGF0YS50YXNrU3RhdHVzID09IFwic3VibWl0XCJcclxuICAgIC8vICAgICAgICAgPyBcIiNmM2Y0ZjhcIlxyXG4gICAgLy8gICAgICAgICA6IGZpeHR1cmVEYXRhLnN0YXR1cyA9PSBcImFncmVlXCJcclxuICAgIC8vICAgICAgICAgPyBcIiM2Q0U5QTZcIlxyXG4gICAgLy8gICAgICAgICA6IFwiI0VBRjhGRlwiLFxyXG4gICAgLy8gICAgIHZtRmlsbDpcclxuICAgIC8vICAgICAgIGZpeHR1cmVEYXRhLnN0YXR1cyA9PSBcIlwiICYmIGZpeHR1cmVEYXRhLnRhc2tTdGF0dXMgPT0gXCJzdWJtaXRcIlxyXG4gICAgLy8gICAgICAgICA/IFwiI2E1YTZhOFwiXHJcbiAgICAvLyAgICAgICAgIDogXCIjNjkzOEVGXCIsXHJcbiAgICAvLyAgIH07XHJcbiAgICAvLyB9XHJcbiAgICBpZiAoZml4dHVyZURhdGEuZml4dHVyZU5hbWUgPT09IFwic3BhY2VcIikgcmV0dXJuO1xyXG4gICAgY29uc3QgcmFkaXVzID0gNTtcclxuICAgIGNvbnN0IG1haW5Db250YWluZXIgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICBsZWZ0OiB4LFxyXG4gICAgICB0b3A6IHksXHJcbiAgICAgIHdpZHRoOiB3aWR0aCxcclxuICAgICAgaGVpZ2h0OiBoZWlnaHQsXHJcbiAgICAgIHJ4OiByYWRpdXMsXHJcbiAgICAgIHJ5OiByYWRpdXMsXHJcbiAgICAgIHN0cm9rZTogZml4dHVyZUNvbG9yPy5wcmltYXJ5ID8/IFwiIzUxQzFGRlwiLFxyXG4gICAgICBzdHJva2VXaWR0aDogMC4yNyxcclxuICAgICAgZmlsbDogXCJ3aGl0ZVwiLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgdG9wV2lkdGggPSB3aWR0aCAvIDEuMDU7XHJcbiAgICBjb25zdCB0b3BIZWlnaHQgPSAoMTUgLyAxMDApICogaGVpZ2h0O1xyXG4gICAgY29uc3QgdG9wWCA9IHggKyAod2lkdGggLSB0b3BXaWR0aCkgLyAyO1xyXG4gICAgY29uc3QgdG9wWSA9IHkgKyB0aGlzLnZlcnRpY2FsTWFyZ2luO1xyXG5cclxuICAgIGNvbnN0IHRvcENvbnRhaW5lciA9IG5ldyBmYWJyaWMuUmVjdCh7XHJcbiAgICAgIGxlZnQ6IHRvcFgsXHJcbiAgICAgIHRvcDogdG9wWSxcclxuICAgICAgd2lkdGg6IHRvcFdpZHRoLFxyXG4gICAgICBoZWlnaHQ6IHRvcEhlaWdodCxcclxuICAgICAgcng6IHJhZGl1cyxcclxuICAgICAgcnk6IHJhZGl1cyxcclxuICAgICAgc3Ryb2tlOiBmaXh0dXJlQ29sb3I/LnByaW1hcnkgPz8gXCIjNTFDMUZGXCIsXHJcbiAgICAgIHN0cm9rZVdpZHRoOiAwLjI3LFxyXG4gICAgICBmaWxsOiBcIndoaXRlXCIsXHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCBpbm5lckJveEhlaWdodCA9IHRvcEhlaWdodCAvIDI7XHJcbiAgICBjb25zdCBpbm5lclRvcEJveCA9IG5ldyBmYWJyaWMuUGF0aChcclxuICAgICAgYE0gJHt0b3BYICsgcmFkaXVzfSAke3RvcFl9IFxyXG4gICAgICAgICAgICAgIEwgJHt0b3BYICsgdG9wV2lkdGggLSByYWRpdXN9ICR7dG9wWX0gXHJcbiAgICAgICAgICAgICAgUSAke3RvcFggKyB0b3BXaWR0aH0gJHt0b3BZfSAke3RvcFggKyB0b3BXaWR0aH0gJHt0b3BZICsgcmFkaXVzfSBcclxuICAgICAgICAgICAgICBMICR7dG9wWCArIHRvcFdpZHRofSAke3RvcFkgKyBpbm5lckJveEhlaWdodH0gXHJcbiAgICAgICAgICAgICAgTCAke3RvcFh9ICR7dG9wWSArIGlubmVyQm94SGVpZ2h0fSBcclxuICAgICAgICAgICAgICBMICR7dG9wWH0gJHt0b3BZICsgcmFkaXVzfSBcclxuICAgICAgICAgICAgICBRICR7dG9wWH0gJHt0b3BZfSAke3RvcFggKyByYWRpdXN9ICR7dG9wWX0gWmAsXHJcbiAgICAgIHtcclxuICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeSA/PyBcIiM1MUMxRkZcIixcclxuICAgICAgICBzdHJva2VXaWR0aDogMC4yNyxcclxuICAgICAgICBmaWxsOiBcInRyYW5zcGFyZW50XCIsXHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgdG9wVGV4dCA9IG5ldyBmYWJyaWMuVGV4dGJveChcclxuICAgICAgYEZpeHR1cmUgJHtmaXh0dXJlRGF0YS5hc3NvY2lhdGVkRWxlbWVudEZpeHR1cmVOdW1iZXJcclxuICAgICAgICA/IGZpeHR1cmVEYXRhLmFzc29jaWF0ZWRFbGVtZW50Rml4dHVyZU51bWJlciArXHJcbiAgICAgICAgKGZpeHR1cmVEYXRhPy5maXh0dXJlTnVtYmVyXHJcbiAgICAgICAgICA/IFwiIC0gRlgtXCIgKyBmaXh0dXJlRGF0YS5maXh0dXJlTnVtYmVyXHJcbiAgICAgICAgICA6IFwiXCIpXHJcbiAgICAgICAgOiBcIm5ld1wiXHJcbiAgICAgIH1gLFxyXG4gICAgICB7XHJcbiAgICAgICAgbGVmdDogdG9wWCArIHRvcFdpZHRoIC8gMixcclxuICAgICAgICB0b3A6IHRvcFkgKyBpbm5lckJveEhlaWdodCAvIDIsXHJcbiAgICAgICAgZm9udFNpemU6IDUsXHJcbiAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgIGZvbnRXZWlnaHQ6IFwiNTAwXCIsXHJcbiAgICAgICAgZmlsbDogXCIjMTAxODI4XCIsXHJcbiAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgIHdpZHRoOiB0b3BXaWR0aCxcclxuICAgICAgICBoZWlnaHQ6IGlubmVyQm94SGVpZ2h0LFxyXG4gICAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBzZWNvbmRCb3hZID0gdG9wWSArIGlubmVyQm94SGVpZ2h0O1xyXG5cclxuICAgIGNvbnN0IGlubmVyQm90dG9tQm94ID0gbmV3IGZhYnJpYy5QYXRoKFxyXG4gICAgICBgTSAke3RvcFh9ICR7c2Vjb25kQm94WX0gXHJcbiAgICAgICAgICBMICR7dG9wWCArIHRvcFdpZHRofSAke3NlY29uZEJveFl9IFxyXG4gICAgICAgICAgTCAke3RvcFggKyB0b3BXaWR0aH0gJHtzZWNvbmRCb3hZICsgaW5uZXJCb3hIZWlnaHQgLSByYWRpdXN9IFxyXG4gICAgICAgICAgUSAke3RvcFggKyB0b3BXaWR0aH0gJHtzZWNvbmRCb3hZICsgaW5uZXJCb3hIZWlnaHR9ICR7dG9wWCArIHRvcFdpZHRoIC0gcmFkaXVzXHJcbiAgICAgIH0gJHtzZWNvbmRCb3hZICsgaW5uZXJCb3hIZWlnaHR9IFxyXG4gICAgICAgICAgTCAke3RvcFggKyByYWRpdXN9ICR7c2Vjb25kQm94WSArIGlubmVyQm94SGVpZ2h0fSBcclxuICAgICAgICAgIFEgJHt0b3BYfSAke3NlY29uZEJveFkgKyBpbm5lckJveEhlaWdodH0gJHt0b3BYfSAke3NlY29uZEJveFkgKyBpbm5lckJveEhlaWdodCAtIHJhZGl1c1xyXG4gICAgICB9IFxyXG4gICAgICAgICAgTCAke3RvcFh9ICR7c2Vjb25kQm94WX0gWmAsXHJcbiAgICAgIHtcclxuICAgICAgICBmaWxsOiBcIiMzNDQwNTRcIixcclxuICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeSA/PyBcIiM1MUMxRkZcIixcclxuICAgICAgICBzdHJva2VXaWR0aDogMC4yNyxcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICBsZXQgZm9udFNpemUgPSA1O1xyXG4gICAgbGV0IGJvdHRvbVRleHQ7XHJcblxyXG4gICAgY29uc3QgdGV4dENvbnRlbnQgPSBgJHtmaXh0dXJlRGF0YT8uZml4dHVyZU5hbWV9IC0gJHtmaXh0dXJlRGF0YT8uZml4dHVyZVdpZHRoLnZhbHVlfSAke2ZpeHR1cmVEYXRhPy5maXh0dXJlV2lkdGgudW5pdH1gO1xyXG5cclxuICAgIGNvbnN0IGNyZWF0ZUJvdHRvbVRleHQgPSAoZnM6IGFueSkgPT5cclxuICAgICAgbmV3IGZhYnJpYy5UZXh0Ym94KHRleHRDb250ZW50LCB7XHJcbiAgICAgICAgbGVmdDogdG9wWCArIHRvcFdpZHRoIC8gMixcclxuICAgICAgICB0b3A6IHNlY29uZEJveFkgKyBpbm5lckJveEhlaWdodCAvIDIsXHJcbiAgICAgICAgZm9udFNpemU6IGZzLFxyXG4gICAgICAgIGZvbnRGYW1pbHk6IFwiSW50ZXJcIixcclxuICAgICAgICBmb250V2VpZ2h0OiBcIjUwMFwiLFxyXG4gICAgICAgIGZpbGw6IFwiI0ZGRkZGRlwiLFxyXG4gICAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgb3JpZ2luWTogXCJjZW50ZXJcIixcclxuICAgICAgICB0ZXh0QWxpZ246IFwiY2VudGVyXCIsXHJcbiAgICAgICAgd2lkdGg6IHRvcFdpZHRoLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICBkbyB7XHJcbiAgICAgIGJvdHRvbVRleHQgPSBjcmVhdGVCb3R0b21UZXh0KGZvbnRTaXplKTtcclxuICAgICAgZm9udFNpemUgLT0gMC41O1xyXG4gICAgfSB3aGlsZSAoYm90dG9tVGV4dC5oZWlnaHQgPiBpbm5lckJveEhlaWdodCAmJiBmb250U2l6ZSA+IDIpO1xyXG5cclxuICAgIGNvbnN0IG1pZFdpZHRoID0gd2lkdGggLyAxLjA1O1xyXG4gICAgY29uc3QgbWlkSGVpZ2h0ID0gKDc3IC8gMTAwKSAqIGhlaWdodDtcclxuICAgIGNvbnN0IG1pZFggPSB4ICsgKHdpZHRoIC0gbWlkV2lkdGgpIC8gMjtcclxuICAgIGNvbnN0IG1pZFkgPSB0b3BZICsgdG9wSGVpZ2h0ICsgdGhpcy52ZXJ0aWNhbE1hcmdpbjtcclxuXHJcbiAgICBjb25zdCBtaWRDb250YWluZXIgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICBsZWZ0OiBtaWRYLFxyXG4gICAgICB0b3A6IG1pZFksXHJcbiAgICAgIHdpZHRoOiBtaWRXaWR0aCxcclxuICAgICAgaGVpZ2h0OiBtaWRIZWlnaHQsXHJcbiAgICAgIHJ4OiByYWRpdXMsXHJcbiAgICAgIHJ5OiByYWRpdXMsXHJcbiAgICAgIHN0cm9rZTogZml4dHVyZUNvbG9yPy5wcmltYXJ5ID8/IFwiIzUxQzFGRlwiLFxyXG4gICAgICBzdHJva2VXaWR0aDogMC4yNyxcclxuICAgICAgZmlsbDogXCJ3aGl0ZVwiLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3Qgc2hlbGZDb3VudCA9IGZpeHR1cmVEYXRhLnNoZWxmQ29uZmlnPy5sZW5ndGg7XHJcbiAgICBjb25zdCBib3hIZWlnaHQgPSBtaWRIZWlnaHQgLyAoc2hlbGZDb3VudCArIDIpO1xyXG4gICAgY29uc3QgZmlyc3RCb3hZID0gbWlkWTtcclxuXHJcbiAgICBjb25zdCBmaXJzdEJveCA9IG5ldyBmYWJyaWMuUGF0aChcclxuICAgICAgYE0gJHttaWRYICsgcmFkaXVzfSAke2ZpcnN0Qm94WX0gXHJcbiAgICAgICAgICAgICAgTCAke21pZFggKyBtaWRXaWR0aCAtIHJhZGl1c30gJHtmaXJzdEJveFl9IFxyXG4gICAgICAgICAgICAgIFEgJHttaWRYICsgbWlkV2lkdGh9ICR7Zmlyc3RCb3hZfSAke21pZFggKyBtaWRXaWR0aH0gJHtmaXJzdEJveFkgKyByYWRpdXNcclxuICAgICAgfSBcclxuICAgICAgICAgICAgICBMICR7bWlkWCArIG1pZFdpZHRofSAke2ZpcnN0Qm94WSArIGJveEhlaWdodH0gXHJcbiAgICAgICAgICAgICAgTCAke21pZFh9ICR7Zmlyc3RCb3hZICsgYm94SGVpZ2h0fSBcclxuICAgICAgICAgICAgICBMICR7bWlkWH0gJHtmaXJzdEJveFkgKyByYWRpdXN9IFxyXG4gICAgICAgICAgICAgIFEgJHttaWRYfSAke2ZpcnN0Qm94WX0gJHttaWRYICsgcmFkaXVzfSAke2ZpcnN0Qm94WX0gWmAsXHJcbiAgICAgIHtcclxuICAgICAgICBmaWxsOiBmaXh0dXJlQ29sb3I/LmZpbGxcclxuICAgICAgICAgID8gZml4dHVyZUNvbG9yPy5maWxsXHJcbiAgICAgICAgICA6IGZpeHR1cmVEYXRhLmlzc3VlXHJcbiAgICAgICAgICAgID8gXCIjRDkyRDIwXCJcclxuICAgICAgICAgICAgOiBcIiNFQUY4RkZcIixcclxuICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeVxyXG4gICAgICAgICAgPyBmaXh0dXJlQ29sb3I/LnByaW1hcnlcclxuICAgICAgICAgIDogZml4dHVyZURhdGEuaXNzdWVcclxuICAgICAgICAgICAgPyBcIiNEOTJEMjBcIlxyXG4gICAgICAgICAgICA6IFwiIzZCQ0FGRlwiLFxyXG4gICAgICAgIHN0cm9rZVdpZHRoOiAwLjI3LFxyXG4gICAgICB9XHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGZpcnN0Qm94VGV4dCA9IG5ldyBmYWJyaWMuVGV4dGJveChcclxuICAgICAgYCR7Zml4dHVyZURhdGE/LmhlYWRlcj8ubGFiZWwgPyBmaXh0dXJlRGF0YS5oZWFkZXIubGFiZWwgOiBcIlwifWAsXHJcbiAgICAgIHtcclxuICAgICAgICBsZWZ0OiBtaWRYICsgbWlkV2lkdGggLyAyLFxyXG4gICAgICAgIHRvcDogZmlyc3RCb3hZICsgYm94SGVpZ2h0IC8gMixcclxuICAgICAgICBmb250U2l6ZTogNyxcclxuICAgICAgICBmb250RmFtaWx5OiBcIkludGVyXCIsXHJcbiAgICAgICAgZm9udFdlaWdodDogXCI2MDBcIixcclxuICAgICAgICBmaWxsOiBmaXh0dXJlRGF0YS5pc3N1ZSA/IFwiI2ZmZlwiIDogXCIjMTAxODI4XCIsXHJcbiAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgIHdpZHRoOiBtaWRXaWR0aCxcclxuICAgICAgICBoZWlnaHQ6IGJveEhlaWdodCxcclxuICAgICAgICB0ZXh0QWxpZ246IFwiY2VudGVyXCIsXHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG4gICAgY29uc3Qgc2hlbHZlcyA9IFtdO1xyXG4gICAgY29uc3Qgc2hlbGZIZWlnaHQgPSBtaWRIZWlnaHQgLSAyICogYm94SGVpZ2h0O1xyXG5cclxuICAgIGlmIChmaXh0dXJlRGF0YS5wcm9kdWN0UmVzb2x1dGlvbkxldmVsID09PSBcIkwxXCIpIHtcclxuICAgICAgY29uc3QgYm94WSA9IGZpcnN0Qm94WSArIGJveEhlaWdodDtcclxuXHJcbiAgICAgIGNvbnN0IHNoZWxmID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICBsZWZ0OiBtaWRYLFxyXG4gICAgICAgIHRvcDogYm94WSxcclxuICAgICAgICB3aWR0aDogbWlkV2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0OiBzaGVsZkhlaWdodCxcclxuICAgICAgICAvLyBzdHJva2U6ICcjNTFDMUZGJyxcclxuICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeVxyXG4gICAgICAgICAgPyBmaXh0dXJlQ29sb3I/LnByaW1hcnlcclxuICAgICAgICAgIDogZml4dHVyZURhdGEuaXNzdWVcclxuICAgICAgICAgICAgPyBcIiNEOTJEMjBcIlxyXG4gICAgICAgICAgICA6IFwiIzUxQzFGRlwiLFxyXG4gICAgICAgIHN0cm9rZVdpZHRoOiAwLjI3LFxyXG4gICAgICAgIGZpbGw6IFwid2hpdGVcIixcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCB0ZXh0ID0gZml4dHVyZURhdGE/LnByb2R1Y3RCcmFuZE5hbWU/LmpvaW4oXCIgKyBcIikgfHwgXCJcIjtcclxuXHJcbiAgICAgIC8vIFdyYXAgdGV4dCB3aXRoaW4gZml4dHVyZSB3aWR0aCBhbmQgc2hyaW5rIHRvIGZpdCB2ZXJ0aWNhbCBzcGFjZVxyXG4gICAgICBjb25zdCBtYXhUZXh0V2lkdGggPSBtaWRXaWR0aCAqIDAuOTtcclxuICAgICAgY29uc3QgbWF4VGV4dEhlaWdodCA9IHNoZWxmSGVpZ2h0ICogMC44O1xyXG4gICAgICBsZXQgZm9udFNpemVMMSA9IDY7XHJcblxyXG4gICAgICBjb25zdCBjcmVhdGVXcmFwcGVkVGV4dGJveCA9IChmczogbnVtYmVyKSA9PlxyXG4gICAgICAgIG5ldyBmYWJyaWMuVGV4dGJveCh0ZXh0LCB7XHJcbiAgICAgICAgICBsZWZ0OiBtaWRYICsgbWlkV2lkdGggLyAyLFxyXG4gICAgICAgICAgdG9wOiBib3hZICsgc2hlbGZIZWlnaHQgLyAyLFxyXG4gICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICB3aWR0aDogbWF4VGV4dFdpZHRoLFxyXG4gICAgICAgICAgZm9udFNpemU6IGZzLFxyXG4gICAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgICAgZm9udFdlaWdodDogXCI1MDBcIixcclxuICAgICAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgICAgIGZpbGw6IFwiIzMzM1wiLFxyXG4gICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgIGxldCB3cmFwcGVkVGV4dCA9IGNyZWF0ZVdyYXBwZWRUZXh0Ym94KGZvbnRTaXplTDEpO1xyXG4gICAgICB3aGlsZSAod3JhcHBlZFRleHQuaGVpZ2h0ID4gbWF4VGV4dEhlaWdodCAmJiBmb250U2l6ZUwxID4gMikge1xyXG4gICAgICAgIGZvbnRTaXplTDEgLT0gMC41O1xyXG4gICAgICAgIHdyYXBwZWRUZXh0ID0gY3JlYXRlV3JhcHBlZFRleHRib3goZm9udFNpemVMMSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHBhZGRpbmcgPSAyO1xyXG4gICAgICBjb25zdCBiYWNrZ3JvdW5kID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICBsZWZ0OiBtaWRYICsgbWlkV2lkdGggLyAyLFxyXG4gICAgICAgIHRvcDogYm94WSArIHNoZWxmSGVpZ2h0IC8gMixcclxuICAgICAgICBvcmlnaW5YOiBcImNlbnRlclwiLFxyXG4gICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgd2lkdGg6IE1hdGgubWluKG1heFRleHRXaWR0aCwgd3JhcHBlZFRleHQud2lkdGghKSArIHBhZGRpbmcsXHJcbiAgICAgICAgaGVpZ2h0OiB3cmFwcGVkVGV4dC5nZXRTY2FsZWRIZWlnaHQoKSArIDIsXHJcbiAgICAgICAgZmlsbDogXCJyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSlcIixcclxuICAgICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcclxuICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICByeDogMSxcclxuICAgICAgICByeTogMSxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBzaGVsdmVzLnB1c2goc2hlbGYsIGJhY2tncm91bmQsIHdyYXBwZWRUZXh0KTtcclxuICAgIH0gZWxzZSBpZiAoZml4dHVyZURhdGEucHJvZHVjdFJlc29sdXRpb25MZXZlbCA9PT0gXCJMMlwiKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2hlbGZDb3VudDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3QgYm94WSA9IGZpcnN0Qm94WSArIGJveEhlaWdodCAqIChpICsgMSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHNoZWxmID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICAgIGxlZnQ6IG1pZFgsXHJcbiAgICAgICAgICB0b3A6IGJveFksXHJcbiAgICAgICAgICB3aWR0aDogbWlkV2lkdGgsXHJcbiAgICAgICAgICBoZWlnaHQ6IGJveEhlaWdodCxcclxuICAgICAgICAgIHN0cm9rZTogZml4dHVyZUNvbG9yPy5wcmltYXJ5XHJcbiAgICAgICAgICAgID8gZml4dHVyZUNvbG9yPy5wcmltYXJ5XHJcbiAgICAgICAgICAgIDogZml4dHVyZURhdGEuaXNzdWVcclxuICAgICAgICAgICAgICA/IFwiI0Q5MkQyMFwiXHJcbiAgICAgICAgICAgICAgOiBcIiM1MUMxRkZcIixcclxuICAgICAgICAgIHN0cm9rZVdpZHRoOiAwLjI3LFxyXG4gICAgICAgICAgZmlsbDogXCJ3aGl0ZVwiLFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBzaGVsdmVzLnB1c2goc2hlbGYpO1xyXG5cclxuICAgICAgICBpZiAoZml4dHVyZURhdGEuc2hlbGZDb25maWc/LltpXS5zaGVsZlR5cGUgPT09IFwidHJheVwiKSB7XHJcbiAgICAgICAgICBjb25zdCB0cmF5Um93cyA9IGZpeHR1cmVEYXRhLnNoZWxmQ29uZmlnPy5baV0udHJheVJvd3MgfHwgMTtcclxuICAgICAgICAgIGNvbnN0IHJvd1NwYWNpbmcgPSBib3hIZWlnaHQgLyB0cmF5Um93cztcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCByID0gMTsgciA8IHRyYXlSb3dzOyByKyspIHtcclxuICAgICAgICAgICAgY29uc3QgbGluZVkgPSBib3hZICsgciAqIHJvd1NwYWNpbmc7XHJcblxyXG4gICAgICAgICAgICBjb25zdCB0cmF5TGluZSA9IG5ldyBmYWJyaWMuTGluZShcclxuICAgICAgICAgICAgICBbbWlkWCwgbGluZVksIG1pZFggKyBtaWRXaWR0aCwgbGluZVldLFxyXG4gICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHN0cm9rZTogXCIjOTk5XCIsXHJcbiAgICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMC4yLFxyXG4gICAgICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBzaGVsdmVzLnB1c2godHJheUxpbmUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGV4dCA9XHJcbiAgICAgICAgICBmaXh0dXJlRGF0YS5zaGVsZkNvbmZpZz8uW2ldLnByb2R1Y3RCcmFuZE5hbWU/LmpvaW4oXCIgKyBcIikgfHwgXCJcIjtcclxuXHJcbiAgICAgICAgLy8gTDI6IFNpbmdsZS1saW5lIGVsbGlwc2lzIGFnYWluc3QgZnVsbCBzaGVsZiB3aWR0aFxyXG4gICAgICAgIGNvbnN0IGhvcml6b250YWxQYWRkaW5nID0gNjtcclxuICAgICAgICBjb25zdCBtYXhUZXh0V2lkdGggPSBNYXRoLm1heCgwLCBtaWRXaWR0aCAtIGhvcml6b250YWxQYWRkaW5nKTtcclxuICAgICAgICBjb25zdCBtYXhUZXh0SGVpZ2h0ID0gYm94SGVpZ2h0ICogMC44O1xyXG4gICAgICAgIGNvbnN0IGJhc2VGb250U2l6ZSA9IDU7XHJcblxyXG4gICAgICAgIGNvbnN0IG1lYXN1cmUgPSAodDogc3RyaW5nKSA9PlxyXG4gICAgICAgICAgbmV3IGZhYnJpYy5UZXh0KHQsIHtcclxuICAgICAgICAgICAgZm9udFNpemU6IGJhc2VGb250U2l6ZSxcclxuICAgICAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgICAgICBmb250V2VpZ2h0OiBcIjUwMFwiLFxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGxldCBkaXNwbGF5VGV4dCA9IHRleHQ7XHJcbiAgICAgICAgbGV0IG1lYXN1cmVkID0gbWVhc3VyZShkaXNwbGF5VGV4dCk7XHJcblxyXG4gICAgICAgIGlmICgobWVhc3VyZWQud2lkdGggPz8gMCkgPiBtYXhUZXh0V2lkdGgpIHtcclxuICAgICAgICAgIGNvbnN0IGVsbGlwc2lzID0gXCIuLi5cIjtcclxuICAgICAgICAgIGxldCBsZWZ0SWR4ID0gMDtcclxuICAgICAgICAgIGxldCByaWdodElkeCA9IHRleHQubGVuZ3RoO1xyXG5cclxuICAgICAgICAgIHdoaWxlIChsZWZ0SWR4IDwgcmlnaHRJZHgpIHtcclxuICAgICAgICAgICAgY29uc3QgbWlkSWR4ID0gTWF0aC5mbG9vcigobGVmdElkeCArIHJpZ2h0SWR4KSAvIDIpO1xyXG4gICAgICAgICAgICBjb25zdCBjYW5kaWRhdGUgPSB0ZXh0LnNsaWNlKDAsIG1pZElkeCkgKyBlbGxpcHNpcztcclxuICAgICAgICAgICAgbWVhc3VyZWQgPSBtZWFzdXJlKGNhbmRpZGF0ZSk7XHJcbiAgICAgICAgICAgIGlmICgobWVhc3VyZWQud2lkdGggPz8gMCkgPiBtYXhUZXh0V2lkdGgpIHtcclxuICAgICAgICAgICAgICByaWdodElkeCA9IG1pZElkeDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBsZWZ0SWR4ID0gbWlkSWR4ICsgMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZGlzcGxheVRleHQgPSB0ZXh0LnNsaWNlKDAsIE1hdGgubWF4KDAsIGxlZnRJZHggLSAxKSkgKyBlbGxpcHNpcztcclxuICAgICAgICAgIG1lYXN1cmVkID0gbWVhc3VyZShkaXNwbGF5VGV4dCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBiYWNrZ3JvdW5kID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICAgIGxlZnQ6IG1pZFggKyBtaWRXaWR0aCAvIDIsXHJcbiAgICAgICAgICB0b3A6IGJveFkgKyBib3hIZWlnaHQgLyAyLFxyXG4gICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICB3aWR0aDogbWlkV2lkdGgsXHJcbiAgICAgICAgICBoZWlnaHQ6IE1hdGgubWluKG1heFRleHRIZWlnaHQsIG1lYXN1cmVkLmhlaWdodCA/PyAxMCkgKyAyLFxyXG4gICAgICAgICAgZmlsbDogXCJyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSlcIixcclxuICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgZXZlbnRlZDogZmFsc2UsXHJcbiAgICAgICAgICByeDogMSxcclxuICAgICAgICAgIHJ5OiAxLFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBjb25zdCBmaW5hbFRleHQgPSBuZXcgZmFicmljLlRleHQoZGlzcGxheVRleHQsIHtcclxuICAgICAgICAgIGxlZnQ6IG1pZFggKyBtaWRXaWR0aCAvIDIsXHJcbiAgICAgICAgICB0b3A6IGJveFkgKyBib3hIZWlnaHQgLyAyLFxyXG4gICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICBmb250U2l6ZTogYmFzZUZvbnRTaXplLFxyXG4gICAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgICAgZm9udFdlaWdodDogXCI1MDBcIixcclxuICAgICAgICAgIGZpbGw6IFwiIzMzM1wiLFxyXG4gICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2hlbHZlcy5wdXNoKGJhY2tncm91bmQsIGZpbmFsVGV4dCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoZml4dHVyZURhdGEucHJvZHVjdFJlc29sdXRpb25MZXZlbCA9PT0gXCJMM1wiKSB7XHJcbiAgICAgIGNvbnN0IHNlcXVlbnRpYWxHcm91cHM6IHsgem9uZTogc3RyaW5nOyBzaGVsdmVzOiBhbnlbXSB9W10gPSBbXTtcclxuXHJcbiAgICAgIGxldCBwcmV2aW91c1pvbmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG5cclxuICAgICAgZm9yIChjb25zdCBzaGVsZiBvZiBmaXh0dXJlRGF0YS5zaGVsZkNvbmZpZykge1xyXG4gICAgICAgIGNvbnN0IHpvbmUgPSBzaGVsZi56b25lIHx8IFwiVW5rbm93blwiO1xyXG4gICAgICAgIGlmICh6b25lICE9PSBwcmV2aW91c1pvbmUpIHtcclxuICAgICAgICAgIHNlcXVlbnRpYWxHcm91cHMucHVzaCh7IHpvbmUsIHNoZWx2ZXM6IFtzaGVsZl0gfSk7XHJcbiAgICAgICAgICBwcmV2aW91c1pvbmUgPSB6b25lO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzZXF1ZW50aWFsR3JvdXBzW3NlcXVlbnRpYWxHcm91cHMubGVuZ3RoIC0gMV0uc2hlbHZlcy5wdXNoKHNoZWxmKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBjdXJyZW50U2hlbGZJbmRleCA9IDA7XHJcblxyXG4gICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIHNlcXVlbnRpYWxHcm91cHMpIHtcclxuICAgICAgICBjb25zdCB7IHpvbmUsIHNoZWx2ZXM6IHNoZWx2ZXNJbkdyb3VwIH0gPSBncm91cDtcclxuXHJcbiAgICAgICAgY29uc3QgZ3JvdXBTdGFydEluZGV4ID0gY3VycmVudFNoZWxmSW5kZXg7XHJcbiAgICAgICAgY29uc3QgZ3JvdXBMZW5ndGggPSBzaGVsdmVzSW5Hcm91cC5sZW5ndGg7XHJcblxyXG4gICAgICAgIGNvbnN0IGdyb3VwVG9wWSA9IGZpcnN0Qm94WSArIGJveEhlaWdodCAqIChncm91cFN0YXJ0SW5kZXggKyAxKTtcclxuICAgICAgICBjb25zdCBncm91cEJvdHRvbVkgPSBncm91cFRvcFkgKyBib3hIZWlnaHQgKiBncm91cExlbmd0aDtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzaGVsdmVzSW5Hcm91cC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgY29uc3Qgc2hlbGZEYXRhID0gc2hlbHZlc0luR3JvdXBbal07XHJcbiAgICAgICAgICBjb25zdCBib3hZID0gZmlyc3RCb3hZICsgYm94SGVpZ2h0ICogKGN1cnJlbnRTaGVsZkluZGV4ICsgMSk7XHJcblxyXG4gICAgICAgICAgY29uc3Qgc2hlbGZSZWN0ID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICAgICAgbGVmdDogbWlkWCxcclxuICAgICAgICAgICAgdG9wOiBib3hZLFxyXG4gICAgICAgICAgICB3aWR0aDogbWlkV2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogYm94SGVpZ2h0LFxyXG4gICAgICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeVxyXG4gICAgICAgICAgICAgID8gZml4dHVyZUNvbG9yPy5wcmltYXJ5XHJcbiAgICAgICAgICAgICAgOiBmaXh0dXJlRGF0YS5pc3N1ZVxyXG4gICAgICAgICAgICAgICAgPyBcIiNEOTJEMjBcIlxyXG4gICAgICAgICAgICAgICAgOiBcIiM1MUMxRkZcIixcclxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDAuMjcsXHJcbiAgICAgICAgICAgIGZpbGw6IFwid2hpdGVcIixcclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIHNoZWx2ZXMucHVzaChzaGVsZlJlY3QpO1xyXG5cclxuICAgICAgICAgIGlmIChzaGVsZkRhdGEuc2hlbGZUeXBlID09PSBcInRyYXlcIikge1xyXG4gICAgICAgICAgICBjb25zdCB0cmF5Um93cyA9IHNoZWxmRGF0YS50cmF5Um93cyB8fCAwO1xyXG4gICAgICAgICAgICBjb25zdCBwcm9kdWN0UGVyU2hlbGYgPSBzaGVsZkRhdGEucHJvZHVjdFBlclNoZWxmIHx8IDA7XHJcblxyXG4gICAgICAgICAgICBjb25zdCByb3dTcGFjaW5nID0gYm94SGVpZ2h0IC8gdHJheVJvd3M7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtblNwYWNpbmcgPSBtaWRXaWR0aCAvIHByb2R1Y3RQZXJTaGVsZjtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IHIgPSAxOyByIDwgdHJheVJvd3M7IHIrKykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGxpbmVZID0gYm94WSArIHIgKiByb3dTcGFjaW5nO1xyXG5cclxuICAgICAgICAgICAgICBjb25zdCB0cmF5TGluZSA9IG5ldyBmYWJyaWMuTGluZShcclxuICAgICAgICAgICAgICAgIFttaWRYLCBsaW5lWSwgbWlkWCArIG1pZFdpZHRoLCBsaW5lWV0sXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgIHN0cm9rZTogXCIjOTk5XCIsXHJcbiAgICAgICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAwLjIsXHJcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICBzaGVsdmVzLnB1c2godHJheUxpbmUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBjID0gMTsgYyA8IHByb2R1Y3RQZXJTaGVsZjsgYysrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgbGluZVggPSBtaWRYICsgYyAqIGNvbHVtblNwYWNpbmc7XHJcblxyXG4gICAgICAgICAgICAgIGNvbnN0IHZlcnRpY2FsTGluZSA9IG5ldyBmYWJyaWMuTGluZShcclxuICAgICAgICAgICAgICAgIFtsaW5lWCwgYm94WSwgbGluZVgsIGJveFkgKyBib3hIZWlnaHRdLFxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICBzdHJva2U6IFwiIzk5OVwiLFxyXG4gICAgICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMC4yLFxyXG4gICAgICAgICAgICAgICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgZXZlbnRlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgc2hlbHZlcy5wdXNoKHZlcnRpY2FsTGluZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBjdXJyZW50U2hlbGZJbmRleCsrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZ3JvdXBCb3R0b21MaW5lID0gbmV3IGZhYnJpYy5MaW5lKFxyXG4gICAgICAgICAgW21pZFgsIGdyb3VwQm90dG9tWSwgbWlkWCArIG1pZFdpZHRoLCBncm91cEJvdHRvbVldLFxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeVxyXG4gICAgICAgICAgICAgID8gZml4dHVyZUNvbG9yPy5wcmltYXJ5XHJcbiAgICAgICAgICAgICAgOiBmaXh0dXJlRGF0YS5pc3N1ZVxyXG4gICAgICAgICAgICAgICAgPyBcIiNEOTJEMjBcIlxyXG4gICAgICAgICAgICAgICAgOiBcIiM1MUMxRkZcIixcclxuICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXHJcbiAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBzaGVsdmVzLnB1c2goZ3JvdXBCb3R0b21MaW5lKTtcclxuXHJcbiAgICAgICAgaWYgKGZpeHR1cmVEYXRhLmZpeHR1cmVUeXBlID09PSBcIndhbGxcIikge1xyXG4gICAgICAgICAgY29uc3QgbGFiZWxQYWRkaW5nID0gMjtcclxuICAgICAgICAgIGNvbnN0IGxhYmVsVGV4dCA9IG5ldyBmYWJyaWMuVGV4dGJveCh6b25lLCB7XHJcbiAgICAgICAgICAgIGxlZnQ6IG1pZFggKyBtaWRXaWR0aCAtIGxhYmVsUGFkZGluZyxcclxuICAgICAgICAgICAgdG9wOiBncm91cEJvdHRvbVksXHJcbiAgICAgICAgICAgIGZvbnRTaXplOiA1LFxyXG4gICAgICAgICAgICBmb250RmFtaWx5OiBcIkludGVyXCIsXHJcbiAgICAgICAgICAgIGZvbnRXZWlnaHQ6IFwiNjAwXCIsXHJcbiAgICAgICAgICAgIGZpbGw6IFwiIzcwNzA3MFwiLFxyXG4gICAgICAgICAgICBvcmlnaW5YOiBcInJpZ2h0XCIsXHJcbiAgICAgICAgICAgIG9yaWdpblk6IFwiYm90dG9tXCIsXHJcbiAgICAgICAgICAgIHdpZHRoOiBtaWRXaWR0aCAvIDIsXHJcbiAgICAgICAgICAgIHRleHRBbGlnbjogXCJyaWdodFwiLFxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgc2hlbHZlcy5wdXNoKGxhYmVsVGV4dCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBncm91cENlbnRlclggPSBtaWRYICsgbWlkV2lkdGggLyAyO1xyXG4gICAgICAgIGNvbnN0IGdyb3VwQ2VudGVyWSA9IGdyb3VwVG9wWSArIChncm91cEJvdHRvbVkgLSBncm91cFRvcFkpIC8gMjtcclxuXHJcbiAgICAgICAgY29uc3Qgc2VjdGlvbkJyYW5kcyA9IG5ldyBTZXQoKTtcclxuXHJcbiAgICAgICAgc2hlbHZlc0luR3JvdXA/LmZvckVhY2goKHNoZWxmKSA9PiB7XHJcbiAgICAgICAgICBzaGVsZi5wcm9kdWN0QnJhbmROYW1lPy5mb3JFYWNoKChicmFuZDogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICAgIHNlY3Rpb25CcmFuZHMuYWRkKGJyYW5kKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoWy4uLnNlY3Rpb25CcmFuZHNdLmxlbmd0aCkge1xyXG4gICAgICAgICAgY29uc3QgdGV4dCA9IFsuLi5zZWN0aW9uQnJhbmRzXS5qb2luKFwiICsgXCIpO1xyXG4gICAgICAgICAgY29uc3QgcGFkZGluZyA9IDI7XHJcbiAgICAgICAgICBjb25zdCBtYXhUZXh0V2lkdGggPSBtaWRXaWR0aDtcclxuICAgICAgICAgIGNvbnN0IHJlY3RXaWR0aCA9IG1pZFdpZHRoICogMC45O1xyXG4gICAgICAgICAgY29uc3QgbWF4VGV4dEhlaWdodCA9IDIwO1xyXG5cclxuICAgICAgICAgIGxldCBmb250U2l6ZSA9IDY7XHJcbiAgICAgICAgICBsZXQgd3JhcHBlZFRleHQ7XHJcblxyXG4gICAgICAgICAgY29uc3QgY3JlYXRlVGV4dGJveCA9IChmczogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgZmFicmljLlRleHRib3godGV4dCwge1xyXG4gICAgICAgICAgICAgIGZvbnRTaXplOiBmcyxcclxuICAgICAgICAgICAgICBmb250RmFtaWx5OiBcIkludGVyXCIsXHJcbiAgICAgICAgICAgICAgZm9udFdlaWdodDogXCI0MDBcIixcclxuICAgICAgICAgICAgICB3aWR0aDogbWF4VGV4dFdpZHRoLFxyXG4gICAgICAgICAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgICAgICAgICBvcmlnaW5YOiBcImNlbnRlclwiLFxyXG4gICAgICAgICAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgICAgZmlsbDogXCIjMTAxODI4XCIsXHJcbiAgICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgZXZlbnRlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgbGVmdDogZ3JvdXBDZW50ZXJYLFxyXG4gICAgICAgICAgICAgIHRvcDogZ3JvdXBDZW50ZXJZLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICB3cmFwcGVkVGV4dCA9IGNyZWF0ZVRleHRib3goZm9udFNpemUpO1xyXG4gICAgICAgICAgICBmb250U2l6ZSAtPSAwLjU7XHJcbiAgICAgICAgICB9IHdoaWxlICh3cmFwcGVkVGV4dC5oZWlnaHQgPiBtYXhUZXh0SGVpZ2h0ICYmIGZvbnRTaXplID4gMik7XHJcblxyXG4gICAgICAgICAgY29uc3QgcmVjdEhlaWdodCA9IHdyYXBwZWRUZXh0LmdldFNjYWxlZEhlaWdodCgpICsgcGFkZGluZztcclxuXHJcbiAgICAgICAgICBjb25zdCBncm91cENlbnRlclRleHQgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICAgICAgICBsZWZ0OiBncm91cENlbnRlclgsXHJcbiAgICAgICAgICAgIHRvcDogZ3JvdXBDZW50ZXJZLFxyXG4gICAgICAgICAgICBvcmlnaW5YOiBcImNlbnRlclwiLFxyXG4gICAgICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgICAgICB3aWR0aDogcmVjdFdpZHRoLFxyXG4gICAgICAgICAgICBoZWlnaHQ6IHJlY3RIZWlnaHQsXHJcbiAgICAgICAgICAgIGZpbGw6IFwicmdiYSgyNTUsIDI1NSwgMjU1LCAwLjUpXCIsXHJcbiAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgcng6IDEsXHJcbiAgICAgICAgICAgIHJ5OiAxLFxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgc2hlbHZlcy5wdXNoKGdyb3VwQ2VudGVyVGV4dCwgd3JhcHBlZFRleHQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChmaXh0dXJlRGF0YT8udm1Db25maWc/Lmxlbmd0aCkge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpeHR1cmVEYXRhLnZtQ29uZmlnLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgY29uc3Qgdm0gPSBmaXh0dXJlRGF0YS52bUNvbmZpZ1tpXTtcclxuXHJcbiAgICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IHZtLnN0YXJ0WVBvc2l0aW9uIC0gMTtcclxuICAgICAgICBjb25zdCBlbmRJbmRleCA9IHZtLmVuZFlQb3NpdGlvbiAtIDE7XHJcblxyXG4gICAgICAgIGNvbnN0IHNoZWxmVG9wWSA9IGZpcnN0Qm94WSArIGJveEhlaWdodCAqIChzdGFydEluZGV4ICsgMSk7XHJcbiAgICAgICAgY29uc3Qgc2hlbGZIZWlnaHRTcGFuID0gYm94SGVpZ2h0ICogKGVuZEluZGV4IC0gc3RhcnRJbmRleCArIDEpO1xyXG5cclxuICAgICAgICBsZXQgdm1IZWlnaHRQeDogbnVtYmVyID0gc2hlbGZIZWlnaHRTcGFuO1xyXG4gICAgICAgIGxldCB5OiBudW1iZXIgPSBzaGVsZlRvcFk7XHJcblxyXG4gICAgICAgIGlmICh2bS55Wm9uZSAmJiB2bS55Wm9uZSAhPT0gXCJzdHJldGNoXCIpIHtcclxuICAgICAgICAgIHZtSGVpZ2h0UHggPSBzaGVsZkhlaWdodFNwYW4gLyAzO1xyXG5cclxuICAgICAgICAgIHN3aXRjaCAodm0ueVpvbmUpIHtcclxuICAgICAgICAgICAgY2FzZSBcInRvcFwiOlxyXG4gICAgICAgICAgICAgIHkgPSBzaGVsZlRvcFk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgXCJtaWRkbGVcIjpcclxuICAgICAgICAgICAgICB5ID0gc2hlbGZUb3BZICsgdm1IZWlnaHRQeDtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBcImJvdHRvbVwiOlxyXG4gICAgICAgICAgICAgIHkgPSBzaGVsZlRvcFkgKyAyICogdm1IZWlnaHRQeDtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICB5ID0gc2hlbGZUb3BZO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHggPSBtaWRYO1xyXG4gICAgICAgIGxldCB3aWR0aCA9IG1pZFdpZHRoO1xyXG5cclxuICAgICAgICBpZiAoIXZtLnhab25lIHx8IHZtLnhab25lID09PSBcInN0cmV0Y2hcIikge1xyXG4gICAgICAgICAgd2lkdGggPSBtaWRXaWR0aDtcclxuICAgICAgICAgIHggPSBtaWRYO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25zdCBzZWN0aW9uV2lkdGggPSBtaWRXaWR0aCAvIDM7XHJcbiAgICAgICAgICBzd2l0Y2ggKHZtLnhab25lKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJsZWZ0XCI6XHJcbiAgICAgICAgICAgICAgd2lkdGggPSBzZWN0aW9uV2lkdGg7XHJcbiAgICAgICAgICAgICAgeCA9IG1pZFg7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgXCJtaWRkbGVcIjpcclxuICAgICAgICAgICAgICB3aWR0aCA9IHNlY3Rpb25XaWR0aDtcclxuICAgICAgICAgICAgICB4ID0gbWlkWCArIHNlY3Rpb25XaWR0aDtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBcInJpZ2h0XCI6XHJcbiAgICAgICAgICAgICAgd2lkdGggPSBzZWN0aW9uV2lkdGg7XHJcbiAgICAgICAgICAgICAgeCA9IG1pZFggKyAyICogc2VjdGlvbldpZHRoO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgIHdpZHRoID0gbWlkV2lkdGg7XHJcbiAgICAgICAgICAgICAgeCA9IG1pZFg7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodm0udm1JbWFnZVVybCkge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgY29uc3Qgdm1JbWFnZTogYW55ID0gYXdhaXQgZmFicmljLkZhYnJpY0ltYWdlLmZyb21VUkwoXHJcbiAgICAgICAgICAgICAgYCR7dGhpcy5jZG5Vcmx9JHt2bS52bUltYWdlVXJsfT92PSR7RGF0ZS5ub3coKX1gLFxyXG4gICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGNyb3NzT3JpZ2luOiBcImFub255bW91c1wiLFxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgIHZtSW1hZ2Uuc2V0KHtcclxuICAgICAgICAgICAgICBsZWZ0OiB4ICsgd2lkdGggLyAyLFxyXG4gICAgICAgICAgICAgIHRvcDogeSArIHZtSGVpZ2h0UHggLyAyLFxyXG4gICAgICAgICAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgICAgICAgICAgb3JpZ2luWTogXCJjZW50ZXJcIixcclxuICAgICAgICAgICAgICBzY2FsZVg6IHdpZHRoIC8gdm1JbWFnZS53aWR0aCEsXHJcbiAgICAgICAgICAgICAgc2NhbGVZOiB2bUhlaWdodFB4IC8gdm1JbWFnZS5oZWlnaHQhLFxyXG4gICAgICAgICAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgIGV2ZW50ZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHNoZWx2ZXMucHVzaCh2bUltYWdlKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBsb2FkaW5nIGltYWdlIGZvciBWTTogJHt2bS52bUltYWdlVXJsfWAsIGVycik7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnN0IHZtQm94ID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgICAgICAgbGVmdDogeCxcclxuICAgICAgICAgICAgdG9wOiB5LFxyXG4gICAgICAgICAgICB3aWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0OiB2bUhlaWdodFB4LFxyXG4gICAgICAgICAgICBmaWxsOiBmaXh0dXJlQ29sb3I/LnZtRmlsbCA/PyBcIiM2OTM4RUZcIixcclxuICAgICAgICAgICAgc2VsZWN0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgIGV2ZW50ZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgbGV0IGZvbnRTaXplID0gNTtcclxuICAgICAgICAgIGxldCB2bVRleHQ7XHJcblxyXG4gICAgICAgICAgY29uc3QgY3JlYXRlVm1UZXh0ID0gKGZzOiBudW1iZXIpID0+XHJcbiAgICAgICAgICAgIG5ldyBmYWJyaWMuVGV4dGJveCh2bS52bU5hbWUgfHwgXCJcIiwge1xyXG4gICAgICAgICAgICAgIGxlZnQ6IHggKyB3aWR0aCAvIDIsXHJcbiAgICAgICAgICAgICAgdG9wOiB5ICsgdm1IZWlnaHRQeCAvIDIsXHJcbiAgICAgICAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgICAgICAgIGZvbnRTaXplOiBmcyxcclxuICAgICAgICAgICAgICBmb250RmFtaWx5OiBcIkludGVyXCIsXHJcbiAgICAgICAgICAgICAgZm9udFdlaWdodDogXCI2MDBcIixcclxuICAgICAgICAgICAgICBmaWxsOiBcIndoaXRlXCIsXHJcbiAgICAgICAgICAgICAgdGV4dEFsaWduOiBcImNlbnRlclwiLFxyXG4gICAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcclxuICAgICAgICAgICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICB2bVRleHQgPSBjcmVhdGVWbVRleHQoZm9udFNpemUpO1xyXG4gICAgICAgICAgICBmb250U2l6ZSAtPSAwLjU7XHJcbiAgICAgICAgICB9IHdoaWxlICh2bVRleHQuaGVpZ2h0ID4gdm1IZWlnaHRQeCAmJiBmb250U2l6ZSA+IDIpO1xyXG5cclxuICAgICAgICAgIHNoZWx2ZXMucHVzaCh2bUJveCwgdm1UZXh0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsYXN0Qm94WSA9IGZpcnN0Qm94WSArIGJveEhlaWdodCAqIChzaGVsZkNvdW50ICsgMSk7XHJcbiAgICBjb25zdCBsYXN0Qm94ID0gbmV3IGZhYnJpYy5QYXRoKFxyXG4gICAgICBgTSAke21pZFh9ICR7bGFzdEJveFl9IFxyXG4gICAgICAgICAgICAgIEwgJHttaWRYICsgbWlkV2lkdGh9ICR7bGFzdEJveFl9IFxyXG4gICAgICAgICAgICAgIEwgJHttaWRYICsgbWlkV2lkdGh9ICR7bGFzdEJveFkgKyBib3hIZWlnaHQgLSByYWRpdXN9IFxyXG4gICAgICAgICAgICAgIFEgJHttaWRYICsgbWlkV2lkdGh9ICR7bGFzdEJveFkgKyBib3hIZWlnaHR9ICR7bWlkWCArIG1pZFdpZHRoIC0gcmFkaXVzXHJcbiAgICAgIH0gJHtsYXN0Qm94WSArIGJveEhlaWdodH0gXHJcbiAgICAgICAgICAgICAgTCAke21pZFggKyByYWRpdXN9ICR7bGFzdEJveFkgKyBib3hIZWlnaHR9IFxyXG4gICAgICAgICAgICAgIFEgJHttaWRYfSAke2xhc3RCb3hZICsgYm94SGVpZ2h0fSAke21pZFh9ICR7bGFzdEJveFkgKyBib3hIZWlnaHQgLSByYWRpdXNcclxuICAgICAgfSBcclxuICAgICAgICAgICAgICBMICR7bWlkWH0gJHtsYXN0Qm94WX0gWmAsXHJcbiAgICAgIHtcclxuICAgICAgICBmaWxsOiBmaXh0dXJlQ29sb3I/LmZpbGxcclxuICAgICAgICAgID8gZml4dHVyZUNvbG9yPy5maWxsXHJcbiAgICAgICAgICA6IGZpeHR1cmVEYXRhLmlzc3VlXHJcbiAgICAgICAgICAgID8gXCIjRkVFNEUyXCJcclxuICAgICAgICAgICAgOiBcIiNFQUY4RkZcIixcclxuICAgICAgICBzdHJva2U6IGZpeHR1cmVDb2xvcj8ucHJpbWFyeVxyXG4gICAgICAgICAgPyBmaXh0dXJlQ29sb3I/LnByaW1hcnlcclxuICAgICAgICAgIDogZml4dHVyZURhdGEuaXNzdWVcclxuICAgICAgICAgICAgPyBcIiNEOTJEMjBcIlxyXG4gICAgICAgICAgICA6IFwiIzZCQ0FGRlwiLFxyXG4gICAgICAgIHN0cm9rZVdpZHRoOiAwLjI3LFxyXG4gICAgICB9XHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGxhc3RCb3hUZXh0ID0gbmV3IGZhYnJpYy5UZXh0Ym94KFxyXG4gICAgICBgJHtmaXh0dXJlRGF0YT8uZm9vdGVyPy5sYWJlbCA/IGZpeHR1cmVEYXRhLmZvb3Rlci5sYWJlbCA6IFwiXCJ9YCxcclxuICAgICAge1xyXG4gICAgICAgIGxlZnQ6IG1pZFggKyBtaWRXaWR0aCAvIDIsXHJcbiAgICAgICAgdG9wOiBsYXN0Qm94WSArIGJveEhlaWdodCAvIDIsXHJcbiAgICAgICAgZm9udFNpemU6IDUsXHJcbiAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgIGZvbnRXZWlnaHQ6IFwiNjAwXCIsXHJcbiAgICAgICAgZmlsbDogXCIjMTAxODI4XCIsXHJcbiAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgICB3aWR0aDogbWlkV2lkdGgsXHJcbiAgICAgICAgaGVpZ3RoOiBib3hIZWlnaHQsXHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgYm90dG9tV2lkdGggPSB3aWR0aCAvIDEuMDU7XHJcbiAgICBjb25zdCBib3R0b21IZWlnaHQgPSAoMyAvIDEwMCkgKiBoZWlnaHQ7XHJcbiAgICBjb25zdCBib3R0b21YID0geCArICh3aWR0aCAtIGJvdHRvbVdpZHRoKSAvIDI7XHJcbiAgICBjb25zdCBib3R0b21ZID0gbWlkWSArIG1pZEhlaWdodCArIHRoaXMudmVydGljYWxNYXJnaW47XHJcblxyXG4gICAgY29uc3QgYm90dG9tQ29udGFpbmVyID0gbmV3IGZhYnJpYy5SZWN0KHtcclxuICAgICAgbGVmdDogYm90dG9tWCxcclxuICAgICAgdG9wOiBib3R0b21ZLFxyXG4gICAgICB3aWR0aDogYm90dG9tV2lkdGgsXHJcbiAgICAgIGhlaWdodDogYm90dG9tSGVpZ2h0LFxyXG4gICAgICByeDogcmFkaXVzLFxyXG4gICAgICByeTogcmFkaXVzLFxyXG4gICAgICBzdHJva2U6IFwidHJhbnNwYXJlbnRcIixcclxuICAgICAgZmlsbDogXCJ0cmFuc3BhcmVudFwiLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgYm90dG9tVGV4dENvbnRlbnQgPSBuZXcgZmFicmljLlRleHRib3goXHJcbiAgICAgIGBTaGVsdmVzIC0gJHtmaXh0dXJlRGF0YS5zaGVsZkNvbmZpZz8ubGVuZ3RofSAuIFByb2R1Y3RzIC0gICR7Zml4dHVyZURhdGEuZml4dHVyZUNhcGFjaXR5fSAuIFZNIC0gJHtmaXh0dXJlRGF0YS52bUNvbmZpZz8ubGVuZ3RofWAsXHJcbiAgICAgIHtcclxuICAgICAgICBsZWZ0OiBib3R0b21YICsgYm90dG9tV2lkdGggLyAyLFxyXG4gICAgICAgIHRvcDogYm90dG9tWSArIGJvdHRvbUhlaWdodCAvIDIsXHJcbiAgICAgICAgZm9udFNpemU6IDUsXHJcbiAgICAgICAgZm9udEZhbWlseTogXCJJbnRlclwiLFxyXG4gICAgICAgIGZvbnRXZWlnaHQ6IFwiNTAwXCIsXHJcbiAgICAgICAgZmlsbDogXCIjMzMzXCIsXHJcbiAgICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgICB3aWR0aDogYm90dG9tV2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0OiBib3R0b21IZWlnaHQsXHJcbiAgICAgIH1cclxuICAgICk7XHJcblxyXG5cclxuICAgIGNvbnN0IGZpeHR1cmVHcm91cCA9IG5ldyBmYWJyaWMuR3JvdXAoXHJcbiAgICAgIFtcclxuICAgICAgICBtYWluQ29udGFpbmVyLFxyXG4gICAgICAgIHRvcENvbnRhaW5lcixcclxuICAgICAgICBpbm5lclRvcEJveCxcclxuICAgICAgICB0b3BUZXh0LFxyXG4gICAgICAgIGlubmVyQm90dG9tQm94LFxyXG4gICAgICAgIGJvdHRvbVRleHQsXHJcbiAgICAgICAgbWlkQ29udGFpbmVyLFxyXG4gICAgICAgIGZpcnN0Qm94LFxyXG4gICAgICAgIGZpcnN0Qm94VGV4dCxcclxuICAgICAgICAuLi5zaGVsdmVzLFxyXG4gICAgICAgIGxhc3RCb3gsXHJcbiAgICAgICAgbGFzdEJveFRleHQsXHJcbiAgICAgICAgYm90dG9tQ29udGFpbmVyLFxyXG4gICAgICAgIGJvdHRvbVRleHRDb250ZW50LFxyXG4gICAgICBdLFxyXG4gICAgICB7XHJcbiAgICAgICAgbGVmdDogeCxcclxuICAgICAgICB0b3A6IHksXHJcbiAgICAgICAgZXZlbnRlZDogdHJ1ZSxcclxuICAgICAgICBob3ZlckN1cnNvcjogXCJwb2ludGVyXCIsXHJcbiAgICAgICAgbG9ja1NjYWxpbmdYOiB0cnVlLFxyXG4gICAgICAgIGxvY2tTY2FsaW5nWTogdHJ1ZSxcclxuICAgICAgICBzdWJUYXJnZXRDaGVjazogdHJ1ZSxcclxuICAgICAgICAvLyBoYXNDb250cm9sczogZml4dHVyZURhdGEuZml4dHVyZVR5cGUgPT09IFwiZmxvb3JcIixcclxuICAgICAgICAvLyBsb2NrUm90YXRpb246IGZpeHR1cmVEYXRhLmZpeHR1cmVUeXBlICE9PSBcImZsb29yXCIsXHJcbiAgICAgICAgLy8gbG9ja01vdmVtZW50WDogY3VycmVudEZpeHR1cmVJbmZvPy53YWxsRGlyZWN0aW9uID09PSAndXAnIHx8IGN1cnJlbnRGaXh0dXJlSW5mbz8ud2FsbERpcmVjdGlvbiA9PT0gJ2Rvd24nLFxyXG4gICAgICAgIC8vIGxvY2tNb3ZlbWVudFk6IGN1cnJlbnRGaXh0dXJlSW5mbz8ud2FsbERpcmVjdGlvbiA9PT0gJ3JpZ2h0JyB8fCBjdXJyZW50Rml4dHVyZUluZm8/LndhbGxEaXJlY3Rpb24gPT09ICdsZWZ0JyxcclxuICAgICAgICBhbmdsZTogZml4dHVyZURhdGEucmVsYXRpdmVQb3NpdGlvbj8uYW5nbGUgPz8gMCxcclxuICAgICAgfVxyXG4gICAgKSBhcyBmYWJyaWMuR3JvdXAgJiB7XHJcbiAgICAgIHdhbGxJbmRleDogbnVtYmVyO1xyXG4gICAgICBmaXh0dXJlSW5kZXg6IG51bWJlcjtcclxuICAgICAgZml4dHVyZUlkOiBzdHJpbmc7XHJcbiAgICAgIGZpeHR1cmVUeXBlOiBcIndhbGxcIiB8IFwiZmxvb3JcIjtcclxuICAgICAgaXNzdWU6IGJvb2xlYW47XHJcbiAgICAgIGlzc3VlRGF0YTogYW55O1xyXG4gICAgICB0YXNrVHlwZTogc3RyaW5nO1xyXG4gICAgICB2bUNvbmZpZzogW107XHJcbiAgICAgIG9ialR5cGU6IHN0cmluZztcclxuICAgIH07XHJcblxyXG5cclxuXHJcbiAgICBmaXh0dXJlR3JvdXAuZml4dHVyZVR5cGUgPSBmaXh0dXJlRGF0YS5maXh0dXJlVHlwZTtcclxuICAgIGZpeHR1cmVHcm91cC53YWxsSW5kZXggPSBmaXh0dXJlRGF0YS5hc3NvY2lhdGVkRWxlbWVudE51bWJlcjtcclxuICAgIGZpeHR1cmVHcm91cC5maXh0dXJlSW5kZXggPSBmaXh0dXJlRGF0YS5hc3NvY2lhdGVkRWxlbWVudEZpeHR1cmVOdW1iZXI7XHJcbiAgICBmaXh0dXJlR3JvdXAuZml4dHVyZUlkID0gZml4dHVyZURhdGEuX2lkO1xyXG4gICAgZml4dHVyZUdyb3VwLmlzc3VlID0gZml4dHVyZURhdGEuaXNzdWU7XHJcbiAgICBmaXh0dXJlR3JvdXAuaXNzdWVEYXRhID0gZml4dHVyZURhdGEuaXNzdWVEYXRhO1xyXG4gICAgZml4dHVyZUdyb3VwLnRhc2tUeXBlID0gZml4dHVyZURhdGEudGFza1R5cGU7XHJcbiAgICBmaXh0dXJlR3JvdXAudm1Db25maWcgPSBmaXh0dXJlRGF0YS52bUNvbmZpZztcclxuICAgIGZpeHR1cmVHcm91cC5vYmpUeXBlID0gXCJmaXh0dXJlXCI7XHJcblxyXG5cclxuICAgIGNhbnZhcy5hZGQoZml4dHVyZUdyb3VwKTtcclxuXHJcbiAgICAvLyBJZiBuZXdseSBhZGRlZCwgZm9jdXMgaXQgb25jZVxyXG4gICAgaWYgKChmaXh0dXJlRGF0YSBhcyBhbnkpPy5uZXdBZGRlZCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNhbnZhcy5zZXRBY3RpdmVPYmplY3QoZml4dHVyZUdyb3VwKTtcclxuICAgICAgICBjYW52YXMucmVxdWVzdFJlbmRlckFsbCgpO1xyXG4gICAgICB9IGNhdGNoIHsgfVxyXG4gICAgICBkZWxldGUgKGZpeHR1cmVEYXRhIGFzIGFueSkubmV3QWRkZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZpeHR1cmVHcm91cDtcclxuICB9XHJcblxyXG4gIGRyYXdPdGhlckVsZW1lbnRzV2l0aExhYmVsKFxyXG4gICAgY2FudmFzOiBmYWJyaWMuQ2FudmFzLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgYTogbnVtYmVyLFxyXG4gICAgd2lkdGg6IG51bWJlcixcclxuICAgIGhlaWdodDogbnVtYmVyLFxyXG4gICAgZWxlbWVudDogYW55XHJcbiAgKTogZmFicmljLkdyb3VwIHtcclxuICAgIGNvbnN0IHJlY3QgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICB3aWR0aCxcclxuICAgICAgaGVpZ2h0LFxyXG4gICAgICByeDogMixcclxuICAgICAgcnk6IDIsXHJcbiAgICAgIGZpbGw6IFwiI0RBRjFGRlwiLFxyXG4gICAgICBzdHJva2U6IFwiIzZCQ0FGRlwiLFxyXG4gICAgICBzdHJva2VXaWR0aDogMixcclxuICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgb3JpZ2luWTogXCJjZW50ZXJcIixcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IHRleHQgPSBuZXcgZmFicmljLlRleHRib3goZWxlbWVudC5maXh0dXJlTmFtZSwge1xyXG4gICAgICB3aWR0aDogd2lkdGggLSA4LFxyXG4gICAgICBmb250U2l6ZTogMTQsXHJcbiAgICAgIGZvbnRGYW1pbHk6IFwiSW50ZXJcIixcclxuICAgICAgZm9udFdlaWdodDogXCI1MDBcIixcclxuICAgICAgZmlsbDogXCIjMTAxODI4XCIsXHJcbiAgICAgIG9yaWdpblg6IFwiY2VudGVyXCIsXHJcbiAgICAgIG9yaWdpblk6IFwiY2VudGVyXCIsXHJcbiAgICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcclxuICAgICAgZWRpdGFibGU6IGZhbHNlLFxyXG4gICAgICBzcGxpdEJ5R3JhcGhlbWU6IHRydWUsXHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCB0ZXh0Qm91bmRzID0gdGV4dC5nZXRCb3VuZGluZ1JlY3QoKTtcclxuXHJcbiAgICBpZiAodGV4dEJvdW5kcy5oZWlnaHQgPiBoZWlnaHQgLSA4KSB7XHJcbiAgICAgIGNvbnN0IHNjYWxlID0gKGhlaWdodCAtIDgpIC8gdGV4dEJvdW5kcy5oZWlnaHQ7XHJcbiAgICAgIHRleHQuc2V0KFwiZm9udFNpemVcIiwgdGV4dC5mb250U2l6ZSEgKiBzY2FsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZ3JvdXAgPSBuZXcgZmFicmljLkdyb3VwKFtyZWN0LCB0ZXh0XSwge1xyXG4gICAgICBsZWZ0OiB4LFxyXG4gICAgICB0b3A6IHksXHJcbiAgICAgIGFuZ2xlOiBhLFxyXG4gICAgICBvcmlnaW5YOiBcImNlbnRlclwiLFxyXG4gICAgICBvcmlnaW5ZOiBcImNlbnRlclwiLFxyXG4gICAgfSkgYXMgZmFicmljLkdyb3VwICYge1xyXG4gICAgICBvYmpUeXBlOiBzdHJpbmc7XHJcbiAgICAgIGRhdGE6IGFueTtcclxuICAgIH07XHJcblxyXG4gICAgZ3JvdXAub2JqVHlwZSA9IFwib3RoZXJzXCI7XHJcbiAgICBncm91cC5kYXRhID0gZWxlbWVudDtcclxuXHJcbiAgICBjYW52YXMuYWRkKGdyb3VwKTtcclxuXHJcbiAgICBpZiAoKGVsZW1lbnQgYXMgYW55KT8ubmV3QWRkZWQpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjYW52YXMuc2V0QWN0aXZlT2JqZWN0KGdyb3VwKTtcclxuICAgICAgICBjYW52YXMucmVxdWVzdFJlbmRlckFsbCgpO1xyXG4gICAgICB9IGNhdGNoIHsgfVxyXG4gICAgICBkZWxldGUgKGVsZW1lbnQgYXMgYW55KS5uZXdBZGRlZDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZ3JvdXA7XHJcbiAgfVxyXG5cclxuXHJcbiAgaGlnaGxpZ2h0Rml4dHVyZShjYW52YXM6IGZhYnJpYy5DYW52YXMsIGdyb3VwOiBhbnksIGJsaW5rOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIHRoaXMucmVtb3ZlSGlnaGxpZ2h0KGNhbnZhcyk7XHJcbiAgICB0aGlzLmNhbmNlbEhpZ2hsaWdodEJsaW5rID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3QgY2VudGVyID0gZ3JvdXAuZ2V0Q2VudGVyUG9pbnQoKTtcclxuXHJcbiAgICBjb25zdCByZWFsV2lkdGggPSBncm91cC53aWR0aCEgKiBncm91cC5zY2FsZVghO1xyXG4gICAgY29uc3QgcmVhbEhlaWdodCA9IGdyb3VwLmhlaWdodCEgKiBncm91cC5zY2FsZVkhO1xyXG5cclxuICAgIGNvbnN0IHJlY3QgPSBuZXcgZmFicmljLlJlY3Qoe1xyXG4gICAgICBsZWZ0OiBjZW50ZXIueCxcclxuICAgICAgdG9wOiBjZW50ZXIueSxcclxuICAgICAgd2lkdGg6IHJlYWxXaWR0aCArIDgsIC8vIGNvbnNpc3RlbnQgcGFkZGluZ1xyXG4gICAgICBoZWlnaHQ6IHJlYWxIZWlnaHQgKyA4LFxyXG4gICAgICByeDogNSxcclxuICAgICAgcnk6IDUsXHJcbiAgICAgIHN0cm9rZTogXCIjMDBhYWZmXCIsXHJcbiAgICAgIHN0cm9rZVdpZHRoOiAzLFxyXG4gICAgICBmaWxsOiBcInRyYW5zcGFyZW50XCIsXHJcbiAgICAgIHNlbGVjdGFibGU6IGZhbHNlLFxyXG4gICAgICBldmVudGVkOiBmYWxzZSxcclxuICAgICAgb3JpZ2luWDogXCJjZW50ZXJcIixcclxuICAgICAgb3JpZ2luWTogXCJjZW50ZXJcIixcclxuICAgICAgYW5nbGU6IGdyb3VwLmFuZ2xlIHx8IDAsXHJcbiAgICAgIG9wYWNpdHk6IGJsaW5rID8gMCA6IDEsXHJcbiAgICB9KTtcclxuXHJcbiAgICAocmVjdCBhcyBhbnkpLmRhdGEgPSB7IHR5cGU6IFwiZml4dHVyZS1oaWdobGlnaHRcIiB9O1xyXG5cclxuICAgIGNhbnZhcy5hZGQocmVjdCk7XHJcbiAgICBjYW52YXMubW92ZU9iamVjdFRvKHJlY3QsIGNhbnZhcy5nZXRPYmplY3RzKCkubGVuZ3RoIC0gMSk7XHJcbiAgICBjYW52YXMucmVxdWVzdFJlbmRlckFsbCgpO1xyXG5cclxuICAgIHRoaXMuYWN0aXZlSGlnaGxpZ2h0ID0gcmVjdDtcclxuXHJcbiAgICAvLyAtLS0gTm8gYmxpbmtpbmcgbmVlZGVkIC0tLVxyXG4gICAgaWYgKCFibGluaykgcmV0dXJuO1xyXG5cclxuICAgIGxldCBjeWNsZXMgPSAwO1xyXG5cclxuICAgIGNvbnN0IGJsaW5rT25jZSA9ICgpID0+IHtcclxuICAgICAgaWYgKHRoaXMuY2FuY2VsSGlnaGxpZ2h0QmxpbmspIHtcclxuICAgICAgICB0aGlzLnJlbW92ZUhpZ2hsaWdodChjYW52YXMpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmVjdC5hbmltYXRlKFxyXG4gICAgICAgIHsgb3BhY2l0eTogMSB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGR1cmF0aW9uOiAyMDAsXHJcbiAgICAgICAgICBvbkNoYW5nZTogKCkgPT4gY2FudmFzLnJlcXVlc3RSZW5kZXJBbGwoKSxcclxuICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY2FuY2VsSGlnaGxpZ2h0QmxpbmspIHtcclxuICAgICAgICAgICAgICB0aGlzLnJlbW92ZUhpZ2hsaWdodChjYW52YXMpO1xyXG4gICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVjdC5hbmltYXRlKFxyXG4gICAgICAgICAgICAgIHsgb3BhY2l0eTogMCB9LFxyXG4gICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAyMDAsXHJcbiAgICAgICAgICAgICAgICBvbkNoYW5nZTogKCkgPT4gY2FudmFzLnJlcXVlc3RSZW5kZXJBbGwoKSxcclxuICAgICAgICAgICAgICAgIG9uQ29tcGxldGU6ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY2FuY2VsSGlnaGxpZ2h0QmxpbmspIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUhpZ2hsaWdodChjYW52YXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgY3ljbGVzKys7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChjeWNsZXMgPCAyMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJsaW5rT25jZSgpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5jYW5jZWxIaWdobGlnaHRCbGluaykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgcmVjdC5zZXQoeyBvcGFjaXR5OiAxIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgY2FudmFzLnJlcXVlc3RSZW5kZXJBbGwoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9O1xyXG5cclxuICAgIGJsaW5rT25jZSgpO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlSGlnaGxpZ2h0KGNhbnZhczogZmFicmljLkNhbnZhcywpIHtcclxuICAgIHRoaXMuY2FuY2VsSGlnaGxpZ2h0QmxpbmsgPSB0cnVlO1xyXG5cclxuICAgIGNhbnZhcy5nZXRPYmplY3RzKCkuZm9yRWFjaCgob2JqKSA9PiB7XHJcbiAgICAgIGlmICgob2JqIGFzIGFueSkuZGF0YT8udHlwZSA9PT0gXCJmaXh0dXJlLWhpZ2hsaWdodFwiKSB7XHJcbiAgICAgICAgY2FudmFzLnJlbW92ZShvYmopO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFjdGl2ZUhpZ2hsaWdodCA9IG51bGw7XHJcbiAgICBjYW52YXMucmVxdWVzdFJlbmRlckFsbCgpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgYXBwbHlTdG9yZXMoKSB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZm9ybS52YWx1ZS5zdG9yZXM7XHJcbiAgICBpZiAoIXZhbHVlKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgY29kZXMgPSB2YWx1ZVxyXG4gICAgICAuc3BsaXQoJywnKVxyXG4gICAgICAubWFwKChzOiBzdHJpbmcpID0+IHMudHJpbSgpLnRvVXBwZXJDYXNlKCkpXHJcbiAgICAgIC5maWx0ZXIoQm9vbGVhbik7XHJcblxyXG4gICAgY29uc3QgcmVzcG9uc2U6IGFueSA9IGF3YWl0IGxhc3RWYWx1ZUZyb20oXHJcbiAgICAgIHRoaXMuYXBpU2VydmljZS5nZXRQbGFub0lkKHsgc3RvcmVzOiBjb2RlcyB9KVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBkYXRhID0gQXJyYXkuaXNBcnJheShyZXNwb25zZS5kYXRhKSA/IHJlc3BvbnNlLmRhdGEgOiBbXTtcclxuXHJcbiAgICBjb25zdCBmb3VuZFN0b3JlU2V0ID0gbmV3IFNldChcclxuICAgICAgZGF0YS5tYXAoKHN0b3JlOiBhbnkpID0+IHN0b3JlLnN0b3JlTmFtZS50b1VwcGVyQ2FzZSgpKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBmb3VuZENoaXBzID0gZGF0YS5tYXAoKHN0b3JlOiBhbnkpID0+ICh7XHJcbiAgICAgIHN0b3JlQ29kZTogc3RvcmUuc3RvcmVOYW1lLFxyXG4gICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcclxuICAgICAgcGxhbm9JZDogc3RvcmUuX2lkXHJcbiAgICB9KSk7XHJcblxyXG4gICAgY29uc3Qgbm90Rm91bmRDaGlwcyA9IGNvZGVzXHJcbiAgICAgIC5maWx0ZXIoKGNvZGU6IHN0cmluZykgPT4gIWZvdW5kU3RvcmVTZXQuaGFzKGNvZGUpKVxyXG4gICAgICAubWFwKChjb2RlOiBzdHJpbmcpID0+ICh7XHJcbiAgICAgICAgc3RvcmVDb2RlOiBjb2RlLFxyXG4gICAgICAgIHN0YXR1czogJ25vdF9mb3VuZCdcclxuICAgICAgfSkpO1xyXG5cclxuICAgIHRoaXMuc3RvcmVDaGlwcyA9IFsuLi5mb3VuZENoaXBzLCAuLi5ub3RGb3VuZENoaXBzXTtcclxuICAgIGNvbnN0IGFjdGl2ZUNoaXAgPSB0aGlzLnN0b3JlQ2hpcHMuZmluZCgoY2hpcCkgPT4gY2hpcC5zdGF0dXMgPT09ICdwZW5kaW5nJylcclxuICAgIHRoaXMuc2VsZWN0ZWRTdG9yZSA9IGFjdGl2ZUNoaXA/LnN0b3JlQ29kZVxyXG4gICAgdGhpcy5nZXRTdG9yZUZpeHR1cmVzKGFjdGl2ZUNoaXAhLnBsYW5vSWQpXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGF1dG9BcHByb3ZlKCkge1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN0b3JlQ2hpcHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgY29uc3QgeyBzdG9yZUNvZGUsIHN0YXR1cywgcGxhbm9JZCB9ID0gdGhpcy5zdG9yZUNoaXBzW2ldO1xyXG4gICAgICBpZiAoc3RhdHVzID09PSAnbm90X2ZvdW5kJykgY29udGludWU7XHJcblxyXG4gICAgICBjb25zdCBwbGFub1JlczogYW55ID0gYXdhaXQgbGFzdFZhbHVlRnJvbSh0aGlzLmFwaVNlcnZpY2UuZ2V0U3RvcmVGaXh0dXJlcyh7IGlkOiBbcGxhbm9JZF0gfSkpXHJcblxyXG4gICAgICBpZiAoIXBsYW5vUmVzPy5kYXRhPy5bMF0/LmZsb29ycz8ubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnBsYW5vRGF0YSA9IHN0cnVjdHVyZWRDbG9uZShwbGFub1Jlcy5kYXRhWzBdKTtcclxuXHJcbiAgICAgIHRoaXMuZmxvb3JEYXRhID0gc3RydWN0dXJlZENsb25lKHBsYW5vUmVzLmRhdGFbMF0uZmxvb3JzWzBdKTtcclxuXHJcbiAgICAgIHRoaXMucmVuZGVyRmxvb3IodGhpcy5iZWZvcmVDYW52YXMpO1xyXG4gICAgICB0aGlzLnJlbmRlckZsb29yKHRoaXMuYWZ0ZXJDYW52YXMpO1xyXG5cclxuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMucmVzaXplQ2FudmFzKHRoaXMuYmVmb3JlQ2FudmFzLCB0aGlzLmJlZm9yZUNvbnRhaW5lclJlZik7XHJcbiAgICAgICAgdGhpcy5maXRDYW52YXNUb0xheW91dEFuaW1hdGVkKHRoaXMuYmVmb3JlQ2FudmFzKTtcclxuXHJcbiAgICAgICAgdGhpcy5yZXNpemVDYW52YXModGhpcy5hZnRlckNhbnZhcywgdGhpcy5hZnRlckNvbnRhaW5lclJlZik7XHJcbiAgICAgICAgdGhpcy5maXRDYW52YXNUb0xheW91dEFuaW1hdGVkKHRoaXMuYWZ0ZXJDYW52YXMpO1xyXG4gICAgICB9LCAxMDApO1xyXG5cclxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcclxuICAgICAgICAuLi50aGlzLmZvcm0udmFsdWUsXHJcbiAgICAgICAgc3RvcmVzOiBbc3RvcmVDb2RlXVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgYWlSZXM6IGFueSA9IGF3YWl0IGxhc3RWYWx1ZUZyb20odGhpcy5hcGlTZXJ2aWNlLmZpbmRGaXh0dXJlQWkocGF5bG9hZCkpXHJcblxyXG4gICAgICBpZiAoYWlSZXMuY29kZSA9PT0gMjAwKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVBaVJlc3BvbnNlRml4dHVyZShhaVJlcy5kYXRhKVxyXG4gICAgICAgIHRoaXMucmVuZGVyRmxvb3IodGhpcy5hZnRlckNhbnZhcylcclxuXHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgYWN0aW9uRml4dHVyZSA9IHRoaXMuYWZ0ZXJDYW52YXNcclxuICAgICAgICAgICAgLmdldE9iamVjdHMoKVxyXG4gICAgICAgICAgICAuZmluZChcclxuICAgICAgICAgICAgICAob2JqOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvYmoub2JqVHlwZSA9PT0gXCJmaXh0dXJlXCIgJiYgb2JqLmZpeHR1cmVJZCA9PT0gYWlSZXMuZGF0YS5faWRcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICkgYXMgZmFicmljLkdyb3VwIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgIGlmICghYWN0aW9uRml4dHVyZSkgcmV0dXJuO1xyXG4gICAgICAgICAgdGhpcy5oaWdobGlnaHRGaXh0dXJlKHRoaXMuYWZ0ZXJDYW52YXMsIGFjdGlvbkZpeHR1cmUsIHRydWUpO1xyXG4gICAgICAgIH0sIDApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVQYXlsb2FkID0ge1xyXG4gICAgICAgIGZpeHR1cmVzOiBbdGhpcy5zZWxlY3RlZEZpeHR1cmVdXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGF3YWl0IGxhc3RWYWx1ZUZyb20odGhpcy5hcGlTZXJ2aWNlLnVwZGF0ZUZpeHR1cmVEYXRhKHVwZGF0ZVBheWxvYWQpKVxyXG4gICAgICB0aGlzLnN0b3JlQ2hpcHNbaV0uc3RhdHVzID0gJ2FwcHJvdmVkJ1xyXG4gICAgICBjb25zdCBhY3RpdmVDaGlwID0gdGhpcy5zdG9yZUNoaXBzLmZpbmQoKGNoaXApID0+IGNoaXAuc3RhdHVzID09PSAncGVuZGluZycpXHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRTdG9yZSA9IGFjdGl2ZUNoaXA/LnN0b3JlQ29kZVxyXG5cclxuICAgICAgYXdhaXQgdGhpcy5kZWxheSgzMDAwKTtcclxuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhcHByb3ZlU3RvcmUoKSB7XHJcbiAgICBjb25zdCBwYXlsb2FkID0ge1xyXG4gICAgICBmaXh0dXJlczogW3RoaXMuc2VsZWN0ZWRGaXh0dXJlXVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuYXBpU2VydmljZS51cGRhdGVGaXh0dXJlRGF0YShwYXlsb2FkKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAocmVzLmNvZGUgPT09IDIwMCkge1xyXG4gICAgICAgICAgdGhpcy5zdG9yZUNoaXBzLmZpbmQoKGNoaXApID0+IGNoaXAuc3RvcmVDb2RlID09PSB0aGlzLnNlbGVjdGVkU3RvcmUpIS5zdGF0dXMgPSAnYXBwcm92ZWQnXHJcbiAgICAgICAgICBjb25zdCBuZXh0Q2hpcCA9IHRoaXMuc3RvcmVDaGlwcy5maW5kKChjaGlwKSA9PiBjaGlwLnN0YXR1cyA9PT0gJ3BlbmRpbmcnKVxyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gbmV4dENoaXA/LnN0b3JlQ29kZVxyXG4gICAgICAgICAgdGhpcy5nZXRTdG9yZUZpeHR1cmVzKG5leHRDaGlwIS5wbGFub0lkKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIHNlbGVjdFN0b3JlKGNoaXA6IFN0b3JlQ2hpcCkge1xyXG4gICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gY2hpcC5zdG9yZUNvZGVcclxuICAgIHRoaXMuZ2V0U3RvcmVGaXh0dXJlcyhjaGlwLnBsYW5vSWQpXHJcbiAgfVxyXG59XHJcbiIsIjxmb3JtIGNsYXNzPVwiYWktY29udGFpbmVyXCIgW2Zvcm1Hcm91cF09XCJmb3JtXCIgKG5nU3VibWl0KT1cInN1Ym1pdFByb21wdCgpXCI+XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT0gQXBwbGljYWJsZSBTdG9yZXMgPT09PT09PT09PT09PT09PT0gLS0+XHJcbiAgPGRpdiBjbGFzcz1cImZpZWxkXCI+XHJcbiAgICA8bGFiZWw+QXBwbGljYWJsZSBTdG9yZXM8L2xhYmVsPlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTIgYWxpZ24taXRlbXMtY2VudGVyXCI+XHJcbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwic3RvcmVzXCIgcGxhY2Vob2xkZXI9XCJlLmcuIExLU1QzNDUsIExLU1QzNDZcIiAvPlxyXG5cclxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmVcIiAoY2xpY2spPVwiYXBwbHlTdG9yZXMoKVwiPlxyXG4gICAgICAgIEFwcGx5XHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPHNwYW4gY2xhc3M9XCJlcnJvclwiICpuZ0lmPVwiZm9ybS5jb250cm9scy5zdG9yZXMudG91Y2hlZCAmJiBmb3JtLmNvbnRyb2xzLnN0b3Jlcy5pbnZhbGlkXCI+XHJcbiAgICAgIEFwcGxpY2FibGUgc3RvcmVzIGlzIHJlcXVpcmVkXHJcbiAgICA8L3NwYW4+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT0gU3RvcmUgQ2hpcHMgPT09PT09PT09PT09PT09PT0gLS0+XHJcbiAgPGRpdiBjbGFzcz1cInN0b3JlLWNoaXBzXCIgKm5nSWY9XCJzdG9yZUNoaXBzLmxlbmd0aFwiPlxyXG4gICAgPGRpdiAoY2xpY2spPVwic2VsZWN0U3RvcmUoY2hpcClcIiBjbGFzcz1cInN0b3JlLWNoaXBcIiAqbmdGb3I9XCJsZXQgY2hpcCBvZiBzdG9yZUNoaXBzXCIgW25nQ2xhc3NdPVwiW1xyXG4gICAgICBjaGlwLnN0YXR1cyxcclxuICAgICAgY2hpcC5zdG9yZUNvZGUgPT09IHNlbGVjdGVkU3RvcmUgPyAnYWN0aXZlJyA6ICcnXHJcbiAgICBdXCI+XHJcbiAgICAgIHt7IGNoaXAuc3RvcmVDb2RlIH19XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT0gVXBkYXRlIFR5cGUgPT09PT09PT09PT09PT09PT0gLS0+XHJcbiAgPGRpdiBjbGFzcz1cImZpZWxkXCI+XHJcbiAgICA8bGFiZWw+VXBkYXRlIFR5cGU8L2xhYmVsPlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJyYWRpby1ncm91cFwiPlxyXG4gICAgICA8bGFiZWwgY2xhc3M9XCJyYWRpby1vcHRpb25cIj5cclxuICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgZm9ybUNvbnRyb2xOYW1lPVwidXBkYXRlVHlwZVwiIHZhbHVlPVwidm1cIiAvPlxyXG4gICAgICAgIFZNXHJcbiAgICAgIDwvbGFiZWw+XHJcblxyXG4gICAgICA8bGFiZWwgY2xhc3M9XCJyYWRpby1vcHRpb25cIj5cclxuICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgZm9ybUNvbnRyb2xOYW1lPVwidXBkYXRlVHlwZVwiIHZhbHVlPVwicGlkXCIgLz5cclxuICAgICAgICBQSURcclxuICAgICAgPC9sYWJlbD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxzcGFuIGNsYXNzPVwiZXJyb3JcIiAqbmdJZj1cImZvcm0uY29udHJvbHMudXBkYXRlVHlwZS50b3VjaGVkICYmIGZvcm0uY29udHJvbHMudXBkYXRlVHlwZS5pbnZhbGlkXCI+XHJcbiAgICAgIFVwZGF0ZSB0eXBlIGlzIHJlcXVpcmVkXHJcbiAgICA8L3NwYW4+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT0gQUkgUHJvbXB0ID09PT09PT09PT09PT09PT09IC0tPlxyXG4gIDxkaXYgY2xhc3M9XCJmaWVsZFwiPlxyXG4gICAgPGxhYmVsPkFJIFByb21wdDwvbGFiZWw+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cInJvd1wiPlxyXG5cclxuICAgICAgPCEtLSBTZWxlY3Rpb24gQ3JpdGVyaWEgLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XHJcbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJzbWFsbCBmdy1zZW1pYm9sZFwiPlNlbGVjdGlvbiBDcml0ZXJpYTwvbGFiZWw+XHJcblxyXG4gICAgICAgICAgPHRleHRhcmVhIHJvd3M9XCIzXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJzZWxlY3Rpb25Dcml0ZXJpYVwiXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBTZWxlY3QgcHJlbWl1bSBzaGFkZXMgb24gd2FsbCBmaXh0dXJlc1wiPjwvdGV4dGFyZWE+XHJcblxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJlcnJvclwiXHJcbiAgICAgICAgICAgICpuZ0lmPVwiZm9ybS5jb250cm9scy5zZWxlY3Rpb25Dcml0ZXJpYS50b3VjaGVkICYmIGZvcm0uY29udHJvbHMuc2VsZWN0aW9uQ3JpdGVyaWEuaW52YWxpZFwiPlxyXG4gICAgICAgICAgICBTZWxlY3Rpb24gY3JpdGVyaWEgaXMgcmVxdWlyZWRcclxuICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8IS0tIFVwZGF0aW9uIENyaXRlcmlhIC0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxyXG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwic21hbGwgZnctc2VtaWJvbGRcIj5VcGRhdGlvbiBDcml0ZXJpYTwvbGFiZWw+XHJcblxyXG4gICAgICAgICAgPHRleHRhcmVhIHJvd3M9XCIzXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJ1cGRhdGlvbkNyaXRlcmlhXCJcclxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIE1vdmUgc2VsZWN0ZWQgZml4dHVyZXMgdG8gbWlkIHNoZWx2ZXNcIj48L3RleHRhcmVhPlxyXG5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3JcIiAqbmdJZj1cImZvcm0uY29udHJvbHMudXBkYXRpb25Dcml0ZXJpYS50b3VjaGVkICYmIGZvcm0uY29udHJvbHMudXBkYXRpb25Dcml0ZXJpYS5pbnZhbGlkXCI+XHJcbiAgICAgICAgICAgIFVwZGF0aW9uIGNyaXRlcmlhIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuICA8IS0tID09PT09PT09PT09PT09PT09IFN1Ym1pdCA9PT09PT09PT09PT09PT09PSAtLT5cclxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1lbmQgbXQtM1wiPlxyXG4gICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJzdWJtaXQtYnRuXCIgW2Rpc2FibGVkXT1cImxvYWRpbmdcIj5cclxuICAgICAge3sgbG9hZGluZyA/ICdUaGlua2luZ+KApicgOiAnU3VibWl0JyB9fVxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gPT09PT09PT09PT09PT09PT0gQ2FudmFzZXMgPT09PT09PT09PT09PT09PT0gLS0+XHJcbiAgPGRpdiBjbGFzcz1cImNhbnZhcy1ncmlkIG10LTRcIj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWJveFwiICNiZWZvcmVDYW52YXNDb250YWluZXI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtdGl0bGVcIj5CZWZvcmUgVXBkYXRlPC9kaXY+XHJcbiAgICAgIDxjYW52YXMgI2JlZm9yZUNhbnZhcz48L2NhbnZhcz5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtYm94XCIgI2FmdGVyQ2FudmFzQ29udGFpbmVyPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLXRpdGxlXCI+QWZ0ZXIgVXBkYXRlPC9kaXY+XHJcbiAgICAgIDxjYW52YXMgI2FmdGVyQ2FudmFzPjwvY2FudmFzPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XHJcbiAgICA8IS0tID09PT09PT09PT09PT09PT09IEF1dG8gQXBwcm92ZSA9PT09PT09PT09PT09PT09PSAtLT5cclxuICAgIDxidXR0b24gKGNsaWNrKT1cImF1dG9BcHByb3ZlKClcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXdhcm5pbmcgbWUtM1wiPlxyXG4gICAgICDimqAgQXV0byBBcHByb3ZlXHJcbiAgICA8L2J1dHRvbj5cclxuXHJcbiAgICA8IS0tID09PT09PT09PT09PT09PT09IEFwcHJvdmUgQ2hhbmdlcyA9PT09PT09PT09PT09PT09PSAtLT5cclxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgKGNsaWNrKT1cImFwcHJvdmVTdG9yZSgpXCIgW2Rpc2FibGVkXT1cImZvcm0uaW52YWxpZFwiPlxyXG4gICAgICDinJQgQXBwcm92ZSBDaGFuZ2VzXHJcbiAgICA8L2J1dHRvbj5cclxuICA8L2Rpdj5cclxuXHJcblxyXG48L2Zvcm0+Il19
|