@plait/core 0.24.0-next.9 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/board/board.component.d.ts +1 -1
  2. package/constants/selection.d.ts +1 -0
  3. package/core/children/children.component.d.ts +3 -3
  4. package/core/element/element.component.d.ts +1 -1
  5. package/esm2022/board/board.component.mjs +9 -7
  6. package/esm2022/constants/resize.mjs +1 -1
  7. package/esm2022/constants/selection.mjs +2 -1
  8. package/esm2022/core/children/children.component.mjs +11 -9
  9. package/esm2022/core/element/context.mjs +1 -1
  10. package/esm2022/core/element/element.component.mjs +4 -3
  11. package/esm2022/interfaces/board.mjs +1 -1
  12. package/esm2022/interfaces/direction.mjs +8 -0
  13. package/esm2022/interfaces/index.mjs +2 -1
  14. package/esm2022/interfaces/plugin-key.mjs +1 -1
  15. package/esm2022/interfaces/point.mjs +1 -1
  16. package/esm2022/interfaces/rectangle-client.mjs +4 -1
  17. package/esm2022/interfaces/viewport.mjs +2 -2
  18. package/esm2022/plugins/create-board.mjs +10 -9
  19. package/esm2022/plugins/with-hotkey.mjs +5 -3
  20. package/esm2022/plugins/with-moving.mjs +17 -4
  21. package/esm2022/plugins/with-options.mjs +1 -1
  22. package/esm2022/plugins/with-selection.mjs +37 -25
  23. package/esm2022/public-api.mjs +1 -2
  24. package/esm2022/testing/core/fake-weak-map.mjs +2 -2
  25. package/esm2022/testing/core/index.mjs +1 -1
  26. package/esm2022/testing/fake-events/event-objects.mjs +1 -1
  27. package/esm2022/testing/fake-events/index.mjs +1 -1
  28. package/esm2022/testing/index.mjs +1 -1
  29. package/esm2022/testing/test-element.mjs +1 -1
  30. package/esm2022/transforms/element.mjs +4 -4
  31. package/esm2022/transforms/selection.mjs +16 -6
  32. package/esm2022/utils/board.mjs +1 -1
  33. package/esm2022/utils/draw/rectangle.mjs +1 -1
  34. package/esm2022/utils/element.mjs +3 -3
  35. package/esm2022/utils/reaction-manager.mjs +370 -0
  36. package/esm2022/utils/to-image.mjs +106 -34
  37. package/esm2022/utils/tree.mjs +2 -2
  38. package/esm2022/utils/weak-maps.mjs +1 -1
  39. package/fesm2022/plait-core.mjs +729 -254
  40. package/fesm2022/plait-core.mjs.map +1 -1
  41. package/interfaces/board.d.ts +2 -1
  42. package/interfaces/direction.d.ts +7 -0
  43. package/interfaces/index.d.ts +1 -0
  44. package/interfaces/rectangle-client.d.ts +6 -0
  45. package/package.json +3 -2
  46. package/plugins/with-selection.d.ts +5 -1
  47. package/public-api.d.ts +0 -1
  48. package/styles/styles.scss +1 -1
  49. package/testing/core/fake-weak-map.d.ts +2 -2
  50. package/transforms/element.d.ts +2 -2
  51. package/transforms/selection.d.ts +2 -2
  52. package/utils/reaction-manager.d.ts +41 -0
  53. package/utils/to-image.d.ts +11 -0
  54. package/utils/tree.d.ts +2 -2
  55. package/utils/weak-maps.d.ts +4 -1
  56. package/esm2022/plait.module.mjs +0 -21
  57. package/plait.module.d.ts +0 -10
@@ -0,0 +1,370 @@
1
+ import { PlaitBoard } from '../interfaces/board';
2
+ import { createG } from './dom/common';
3
+ import { RectangleClient, SELECTION_BORDER_COLOR } from '../interfaces';
4
+ import { depthFirstRecursion } from './tree';
5
+ const ALIGN_TOLERANCE = 2;
6
+ export class AlignReaction {
7
+ constructor(board, activeElements, activeRectangle) {
8
+ this.board = board;
9
+ this.activeElements = activeElements;
10
+ this.activeRectangle = activeRectangle;
11
+ this.alignRectangles = this.getAlignRectangle();
12
+ }
13
+ getAlignRectangle() {
14
+ const result = [];
15
+ depthFirstRecursion(this.board, node => {
16
+ if (PlaitBoard.isBoard(node) || this.activeElements.some(element => node.id === element.id) || !this.board.isAlign(node)) {
17
+ return;
18
+ }
19
+ const rectangle = this.board.getRectangle(node);
20
+ rectangle && result.push(rectangle);
21
+ }, node => {
22
+ if (node && (PlaitBoard.isBoard(node) || this.board.isRecursion(node))) {
23
+ return true;
24
+ }
25
+ else {
26
+ return false;
27
+ }
28
+ }, true);
29
+ return result;
30
+ }
31
+ handleAlign() {
32
+ const alignRectangles = this.getAlignRectangle();
33
+ const g = createG();
34
+ let alignLines = [];
35
+ const offset = 12;
36
+ let deltaX = 0;
37
+ let deltaY = 0;
38
+ let isCorrectX = false;
39
+ let isCorrectY = false;
40
+ for (let alignRectangle of alignRectangles) {
41
+ const closestDistances = this.calculateClosestDistances(this.activeRectangle, alignRectangle);
42
+ let canDrawHorizontal = false;
43
+ if (!isCorrectX && closestDistances.absXDistance < ALIGN_TOLERANCE) {
44
+ deltaX = closestDistances.xDistance;
45
+ this.activeRectangle.x -= deltaX;
46
+ isCorrectX = true;
47
+ canDrawHorizontal = true;
48
+ }
49
+ if (closestDistances.absXDistance === 0) {
50
+ canDrawHorizontal = true;
51
+ }
52
+ if (canDrawHorizontal) {
53
+ const verticalY = [
54
+ alignRectangle.y,
55
+ alignRectangle.y + alignRectangle.height,
56
+ this.activeRectangle.y,
57
+ this.activeRectangle.y + this.activeRectangle.height
58
+ ];
59
+ const lineTopY = Math.min(...verticalY) - offset;
60
+ const lineBottomY = Math.max(...verticalY) + offset;
61
+ const leftLine = [this.activeRectangle.x, lineTopY, this.activeRectangle.x, lineBottomY];
62
+ const middleLine = [
63
+ this.activeRectangle.x + this.activeRectangle.width / 2,
64
+ lineTopY,
65
+ this.activeRectangle.x + this.activeRectangle.width / 2,
66
+ lineBottomY
67
+ ];
68
+ const rightLine = [
69
+ this.activeRectangle.x + this.activeRectangle.width,
70
+ lineTopY,
71
+ this.activeRectangle.x + this.activeRectangle.width,
72
+ lineBottomY
73
+ ];
74
+ const shouldDrawLeftLine = closestDistances.indexX === 0 ||
75
+ closestDistances.indexX === 1 ||
76
+ (closestDistances.indexX === 2 && this.activeRectangle.width === alignRectangle.width);
77
+ if (shouldDrawLeftLine && !alignLines[0]) {
78
+ alignLines[0] = leftLine;
79
+ }
80
+ const shouldDrawRightLine = closestDistances.indexX === 2 ||
81
+ closestDistances.indexX === 3 ||
82
+ (closestDistances.indexX === 0 && this.activeRectangle.width === alignRectangle.width);
83
+ if (shouldDrawRightLine && !alignLines[2]) {
84
+ alignLines[2] = rightLine;
85
+ }
86
+ const shouldDrawMiddleLine = closestDistances.indexX === 4 || (!shouldDrawLeftLine && !shouldDrawRightLine);
87
+ if (shouldDrawMiddleLine && !alignLines[1]) {
88
+ alignLines[1] = middleLine;
89
+ }
90
+ isCorrectX = true;
91
+ }
92
+ let canDrawVertical = false;
93
+ if (!isCorrectY && closestDistances.absYDistance < ALIGN_TOLERANCE) {
94
+ deltaY = closestDistances.yDistance;
95
+ this.activeRectangle.y -= deltaY;
96
+ isCorrectY = true;
97
+ canDrawVertical = true;
98
+ }
99
+ if (closestDistances.absYDistance === 0) {
100
+ canDrawVertical = true;
101
+ }
102
+ if (canDrawVertical) {
103
+ const horizontalX = [
104
+ alignRectangle.x,
105
+ alignRectangle.x + alignRectangle.width,
106
+ this.activeRectangle.x,
107
+ this.activeRectangle.x + this.activeRectangle.width
108
+ ];
109
+ const lineLeftX = Math.min(...horizontalX) - offset;
110
+ const lineRightX = Math.max(...horizontalX) + offset;
111
+ const topLine = [lineLeftX, this.activeRectangle.y, lineRightX, this.activeRectangle.y];
112
+ const horizontalMiddleLine = [
113
+ lineLeftX,
114
+ this.activeRectangle.y + this.activeRectangle.height / 2,
115
+ lineRightX,
116
+ this.activeRectangle.y + this.activeRectangle.height / 2
117
+ ];
118
+ const bottomLine = [
119
+ lineLeftX,
120
+ this.activeRectangle.y + this.activeRectangle.height,
121
+ lineRightX,
122
+ this.activeRectangle.y + this.activeRectangle.height
123
+ ];
124
+ const shouldDrawTopLine = closestDistances.indexY === 0 ||
125
+ closestDistances.indexY === 1 ||
126
+ (closestDistances.indexY === 2 && this.activeRectangle.height === alignRectangle.height);
127
+ if (shouldDrawTopLine && !alignLines[3]) {
128
+ alignLines[3] = topLine;
129
+ }
130
+ const shouldDrawBottomLine = closestDistances.indexY === 2 ||
131
+ closestDistances.indexY === 3 ||
132
+ (closestDistances.indexY === 0 && this.activeRectangle.width === alignRectangle.width);
133
+ if (shouldDrawBottomLine && !alignLines[5]) {
134
+ alignLines[5] = bottomLine;
135
+ }
136
+ const shouldDrawMiddleLine = closestDistances.indexY === 4 || (!shouldDrawTopLine && !shouldDrawBottomLine);
137
+ if (shouldDrawMiddleLine && !alignLines[4]) {
138
+ alignLines[4] = horizontalMiddleLine;
139
+ }
140
+ }
141
+ }
142
+ const alignDeltaX = deltaX;
143
+ const alignDeltaY = deltaY;
144
+ this.activeRectangle.x += deltaX;
145
+ const distributeHorizontalResult = this.alignDistribute(alignRectangles, true);
146
+ const distributeVerticalResult = this.alignDistribute(alignRectangles, false);
147
+ const distributeLines = [...distributeHorizontalResult.distributeLines, ...distributeVerticalResult.distributeLines];
148
+ if (distributeHorizontalResult.delta) {
149
+ deltaX = distributeHorizontalResult.delta;
150
+ if (alignDeltaX !== deltaX) {
151
+ alignLines[0] = [];
152
+ alignLines[1] = [];
153
+ alignLines[2] = [];
154
+ }
155
+ }
156
+ if (distributeVerticalResult.delta) {
157
+ deltaY = distributeVerticalResult.delta;
158
+ if (alignDeltaY !== deltaY) {
159
+ alignLines[3] = [];
160
+ alignLines[4] = [];
161
+ alignLines[5] = [];
162
+ }
163
+ }
164
+ if (alignLines.length) {
165
+ this.drawAlignLines(alignLines, g);
166
+ }
167
+ if (distributeLines.length) {
168
+ this.drawDistributeLines(distributeLines, g);
169
+ }
170
+ return { deltaX, deltaY, g };
171
+ }
172
+ calculateClosestDistances(activeRectangle, alignRectangle) {
173
+ const activeRectangleCenter = [activeRectangle.x + activeRectangle.width / 2, activeRectangle.y + activeRectangle.height / 2];
174
+ const alignRectangleCenter = [alignRectangle.x + alignRectangle.width / 2, alignRectangle.y + alignRectangle.height / 2];
175
+ const centerXDistance = activeRectangleCenter[0] - alignRectangleCenter[0];
176
+ const centerYDistance = activeRectangleCenter[1] - alignRectangleCenter[1];
177
+ const leftToLeft = activeRectangle.x - alignRectangle.x;
178
+ const leftToRight = activeRectangle.x - (alignRectangle.x + alignRectangle.width);
179
+ const rightToRight = activeRectangle.x + activeRectangle.width - (alignRectangle.x + alignRectangle.width);
180
+ const rightToLeft = activeRectangle.x + activeRectangle.width - alignRectangle.x;
181
+ const topToTop = activeRectangle.y - alignRectangle.y;
182
+ const topToBottom = activeRectangle.y - (alignRectangle.y + alignRectangle.height);
183
+ const bottomToTop = activeRectangle.y + activeRectangle.height - alignRectangle.y;
184
+ const bottomToBottom = activeRectangle.y + activeRectangle.height - (alignRectangle.y + alignRectangle.height);
185
+ const xDistances = [leftToLeft, leftToRight, rightToRight, rightToLeft, centerXDistance];
186
+ const yDistances = [topToTop, topToBottom, bottomToBottom, bottomToTop, centerYDistance];
187
+ const xDistancesAbs = xDistances.map(distance => Math.abs(distance));
188
+ const yDistancesAbs = yDistances.map(distance => Math.abs(distance));
189
+ const indexX = xDistancesAbs.indexOf(Math.min(...xDistancesAbs));
190
+ const indexY = yDistancesAbs.indexOf(Math.min(...yDistancesAbs));
191
+ return {
192
+ absXDistance: xDistancesAbs[indexX],
193
+ xDistance: xDistances[indexX],
194
+ absYDistance: yDistancesAbs[indexY],
195
+ yDistance: yDistances[indexY],
196
+ indexX,
197
+ indexY
198
+ };
199
+ }
200
+ alignDistribute(alignRectangles, isHorizontal) {
201
+ let distributeLines = [];
202
+ let delta = 0;
203
+ let rectangles = [];
204
+ const axis = isHorizontal ? 'x' : 'y';
205
+ const side = isHorizontal ? 'width' : 'height';
206
+ const activeRectangleCenter = this.activeRectangle[axis] + this.activeRectangle[side] / 2;
207
+ alignRectangles.forEach(rec => {
208
+ const isCross = isHorizontal ? isHorizontalCross(rec, this.activeRectangle) : isVerticalCross(rec, this.activeRectangle);
209
+ if (isCross && !RectangleClient.isHit(rec, this.activeRectangle)) {
210
+ rectangles.push(rec);
211
+ }
212
+ });
213
+ rectangles = [...rectangles, this.activeRectangle].sort((a, b) => a[axis] - b[axis]);
214
+ const refArray = [];
215
+ let distributeDistance = 0;
216
+ let beforeIndex = undefined;
217
+ let afterIndex = undefined;
218
+ for (let i = 0; i < rectangles.length; i++) {
219
+ for (let j = i + 1; j < rectangles.length; j++) {
220
+ const before = rectangles[i];
221
+ const after = rectangles[j];
222
+ const distance = after[axis] - (before[axis] + before[side]);
223
+ let dif = Infinity;
224
+ if (refArray[i]?.after) {
225
+ refArray[i].after.push({ distance, index: j });
226
+ }
227
+ else {
228
+ refArray[i] = { ...refArray[i], after: [{ distance, index: j }] };
229
+ }
230
+ if (refArray[j]?.before) {
231
+ refArray[j].before.push({ distance, index: i });
232
+ }
233
+ else {
234
+ refArray[j] = { ...refArray[j], before: [{ distance, index: i }] };
235
+ }
236
+ //middle
237
+ let _center = (before[axis] + before[side] + after[axis]) / 2;
238
+ dif = Math.abs(activeRectangleCenter - _center);
239
+ if (dif < ALIGN_TOLERANCE) {
240
+ distributeDistance = (after[axis] - (before[axis] + before[side]) - this.activeRectangle[side]) / 2;
241
+ delta = activeRectangleCenter - _center;
242
+ beforeIndex = i;
243
+ afterIndex = j;
244
+ }
245
+ //after
246
+ const distanceRight = after[axis] - (before[axis] + before[side]);
247
+ _center = after[axis] + after[side] + distanceRight + this.activeRectangle[side] / 2;
248
+ dif = Math.abs(activeRectangleCenter - _center);
249
+ if (!distributeDistance && dif < ALIGN_TOLERANCE) {
250
+ distributeDistance = distanceRight;
251
+ beforeIndex = j;
252
+ delta = activeRectangleCenter - _center;
253
+ }
254
+ //before
255
+ const distanceBefore = after[axis] - (before[axis] + before[side]);
256
+ _center = before[axis] - distanceBefore - this.activeRectangle[side] / 2;
257
+ dif = Math.abs(activeRectangleCenter - _center);
258
+ if (!distributeDistance && dif < ALIGN_TOLERANCE) {
259
+ distributeDistance = distanceBefore;
260
+ afterIndex = i;
261
+ delta = activeRectangleCenter - _center;
262
+ }
263
+ }
264
+ }
265
+ const activeIndex = rectangles.indexOf(this.activeRectangle);
266
+ let beforeIndexes = [];
267
+ let afterIndexes = [];
268
+ if (beforeIndex !== undefined) {
269
+ beforeIndexes.push(beforeIndex);
270
+ findRectangle(distributeDistance, refArray[beforeIndex], 'before', beforeIndexes);
271
+ }
272
+ if (afterIndex !== undefined) {
273
+ afterIndexes.push(afterIndex);
274
+ findRectangle(distributeDistance, refArray[afterIndex], 'after', afterIndexes);
275
+ }
276
+ if (beforeIndexes.length || afterIndexes.length) {
277
+ const indexArr = [...beforeIndexes.reverse(), activeIndex, ...afterIndexes];
278
+ this.activeRectangle[axis] -= delta;
279
+ for (let i = 1; i < indexArr.length; i++) {
280
+ distributeLines.push(getLinePoints(rectangles[indexArr[i - 1]], rectangles[indexArr[i]]));
281
+ }
282
+ }
283
+ function findRectangle(distance, ref, direction, rectangleIndexes) {
284
+ const arr = ref[direction];
285
+ const index = refArray.indexOf(ref);
286
+ if ((index === 0 && direction === 'before') || (index === refArray.length - 1 && direction === 'after'))
287
+ return;
288
+ for (let i = 0; i < arr.length; i++) {
289
+ if (Math.abs(arr[i].distance - distance) < 0.1) {
290
+ rectangleIndexes.push(arr[i].index);
291
+ findRectangle(distance, refArray[arr[i].index], direction, rectangleIndexes);
292
+ return;
293
+ }
294
+ }
295
+ }
296
+ function getLinePoints(beforeRectangle, afterRectangle) {
297
+ const oppositeAxis = axis === 'x' ? 'y' : 'x';
298
+ const oppositeSide = side === 'width' ? 'height' : 'width';
299
+ const align = [
300
+ beforeRectangle[oppositeAxis],
301
+ beforeRectangle[oppositeAxis] + beforeRectangle[oppositeSide],
302
+ afterRectangle[oppositeAxis],
303
+ afterRectangle[oppositeAxis] + afterRectangle[oppositeSide]
304
+ ];
305
+ const sortArr = align.sort((a, b) => a - b);
306
+ const average = (sortArr[1] + sortArr[2]) / 2;
307
+ const offset = 3;
308
+ return isHorizontal
309
+ ? [
310
+ [beforeRectangle.x + beforeRectangle.width + offset, average],
311
+ [afterRectangle.x - offset, average]
312
+ ]
313
+ : [
314
+ [average, beforeRectangle.y + beforeRectangle.height + offset],
315
+ [average, afterRectangle.y - offset]
316
+ ];
317
+ }
318
+ return { delta, distributeLines };
319
+ }
320
+ drawAlignLines(lines, g) {
321
+ lines.forEach(points => {
322
+ if (!points.length)
323
+ return;
324
+ const xAlign = PlaitBoard.getRoughSVG(this.board).line(points[0], points[1], points[2], points[3], {
325
+ stroke: SELECTION_BORDER_COLOR,
326
+ strokeWidth: 1,
327
+ strokeLineDash: [4, 4]
328
+ });
329
+ g.appendChild(xAlign);
330
+ });
331
+ }
332
+ drawDistributeLines(lines, g) {
333
+ lines.forEach(line => {
334
+ if (!line.length)
335
+ return;
336
+ let isHorizontal = line[0][1] === line[1][1];
337
+ const yAlign = PlaitBoard.getRoughSVG(this.board).line(line[0][0], line[0][1], line[1][0], line[1][1], {
338
+ stroke: SELECTION_BORDER_COLOR,
339
+ strokeWidth: 1
340
+ });
341
+ g.appendChild(yAlign);
342
+ line.forEach(point => {
343
+ const barPoint = getBarPoint(point, isHorizontal);
344
+ const bar = PlaitBoard.getRoughSVG(this.board).line(barPoint[0][0], barPoint[0][1], barPoint[1][0], barPoint[1][1], {
345
+ stroke: SELECTION_BORDER_COLOR,
346
+ strokeWidth: 1
347
+ });
348
+ g.appendChild(bar);
349
+ });
350
+ });
351
+ }
352
+ }
353
+ function isHorizontalCross(rectangle, other) {
354
+ return !(rectangle.y + rectangle.height < other.y || rectangle.y > other.y + other.height);
355
+ }
356
+ function isVerticalCross(rectangle, other) {
357
+ return !(rectangle.x + rectangle.width < other.x || rectangle.x > other.x + other.width);
358
+ }
359
+ function getBarPoint(point, isHorizontal) {
360
+ return isHorizontal
361
+ ? [
362
+ [point[0], point[1] - 4],
363
+ [point[0], point[1] + 4]
364
+ ]
365
+ : [
366
+ [point[0] - 4, point[1]],
367
+ [point[0] + 4, point[1]]
368
+ ];
369
+ }
370
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3Rpb24tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3V0aWxzL3JlYWN0aW9uLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHdkMsT0FBTyxFQUFTLGVBQWUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFhN0MsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBRTFCLE1BQU0sT0FBTyxhQUFhO0lBR3RCLFlBQW9CLEtBQWlCLEVBQVUsY0FBOEIsRUFBVSxlQUFnQztRQUFuRyxVQUFLLEdBQUwsS0FBSyxDQUFZO1FBQVUsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ25ILElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDcEQsQ0FBQztJQUVELGlCQUFpQjtRQUNiLE1BQU0sTUFBTSxHQUFzQixFQUFFLENBQUM7UUFDckMsbUJBQW1CLENBQ2YsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsRUFBRTtZQUNILElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3RILE9BQU87YUFDVjtZQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hELFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsRUFDRCxJQUFJLENBQUMsRUFBRTtZQUNILElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO2dCQUNwRSxPQUFPLElBQUksQ0FBQzthQUNmO2lCQUFNO2dCQUNILE9BQU8sS0FBSyxDQUFDO2FBQ2hCO1FBQ0wsQ0FBQyxFQUNELElBQUksQ0FDUCxDQUFDO1FBQ0YsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQUVELFdBQVc7UUFDUCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNqRCxNQUFNLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztRQUNwQixJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFFcEIsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFFdkIsS0FBSyxJQUFJLGNBQWMsSUFBSSxlQUFlLEVBQUU7WUFDeEMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUM5RixJQUFJLGlCQUFpQixHQUFHLEtBQUssQ0FBQztZQUM5QixJQUFJLENBQUMsVUFBVSxJQUFJLGdCQUFnQixDQUFDLFlBQVksR0FBRyxlQUFlLEVBQUU7Z0JBQ2hFLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQztnQkFDakMsVUFBVSxHQUFHLElBQUksQ0FBQztnQkFDbEIsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO2FBQzVCO1lBRUQsSUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUNyQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7YUFDNUI7WUFFRCxJQUFJLGlCQUFpQixFQUFFO2dCQUNuQixNQUFNLFNBQVMsR0FBRztvQkFDZCxjQUFjLENBQUMsQ0FBQztvQkFDaEIsY0FBYyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTTtvQkFDeEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO29CQUN0QixJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU07aUJBQ3ZELENBQUM7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDakQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDcEQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQ3pGLE1BQU0sVUFBVSxHQUFHO29CQUNmLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxHQUFHLENBQUM7b0JBQ3ZELFFBQVE7b0JBQ1IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQztvQkFDdkQsV0FBVztpQkFDZCxDQUFDO2dCQUNGLE1BQU0sU0FBUyxHQUFHO29CQUNkLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSztvQkFDbkQsUUFBUTtvQkFDUixJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUs7b0JBQ25ELFdBQVc7aUJBQ2QsQ0FBQztnQkFFRixNQUFNLGtCQUFrQixHQUNwQixnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDN0IsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7b0JBQzdCLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssS0FBSyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzNGLElBQUksa0JBQWtCLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3RDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUM7aUJBQzVCO2dCQUVELE1BQU0sbUJBQW1CLEdBQ3JCLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDO29CQUM3QixnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDN0IsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxLQUFLLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDM0YsSUFBSSxtQkFBbUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDdkMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztpQkFDN0I7Z0JBRUQsTUFBTSxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7Z0JBQzVHLElBQUksb0JBQW9CLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3hDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUM7aUJBQzlCO2dCQUVELFVBQVUsR0FBRyxJQUFJLENBQUM7YUFDckI7WUFFRCxJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDNUIsSUFBSSxDQUFDLFVBQVUsSUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLEdBQUcsZUFBZSxFQUFFO2dCQUNoRSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUM7Z0JBQ2pDLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ2xCLGVBQWUsR0FBRyxJQUFJLENBQUM7YUFDMUI7WUFDRCxJQUFJLGdCQUFnQixDQUFDLFlBQVksS0FBSyxDQUFDLEVBQUU7Z0JBQ3JDLGVBQWUsR0FBRyxJQUFJLENBQUM7YUFDMUI7WUFDRCxJQUFJLGVBQWUsRUFBRTtnQkFDakIsTUFBTSxXQUFXLEdBQUc7b0JBQ2hCLGNBQWMsQ0FBQyxDQUFDO29CQUNoQixjQUFjLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxLQUFLO29CQUN2QyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ3RCLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSztpQkFDdEQsQ0FBQztnQkFDRixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNwRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDO2dCQUNyRCxNQUFNLE9BQU8sR0FBRyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEYsTUFBTSxvQkFBb0IsR0FBRztvQkFDekIsU0FBUztvQkFDVCxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDO29CQUN4RCxVQUFVO29CQUNWLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUM7aUJBQzNELENBQUM7Z0JBQ0YsTUFBTSxVQUFVLEdBQUc7b0JBQ2YsU0FBUztvQkFDVCxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU07b0JBQ3BELFVBQVU7b0JBQ1YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNO2lCQUN2RCxDQUFDO2dCQUVGLE1BQU0saUJBQWlCLEdBQ25CLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDO29CQUM3QixnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDN0IsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxLQUFLLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDN0YsSUFBSSxpQkFBaUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDckMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztpQkFDM0I7Z0JBRUQsTUFBTSxvQkFBb0IsR0FDdEIsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7b0JBQzdCLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDO29CQUM3QixDQUFDLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEtBQUssY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMzRixJQUFJLG9CQUFvQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUN4QyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDO2lCQUM5QjtnQkFFRCxNQUFNLG9CQUFvQixHQUFHLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLGlCQUFpQixJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztnQkFDNUcsSUFBSSxvQkFBb0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDeEMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDO2lCQUN4QzthQUNKO1NBQ0o7UUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUM7UUFDM0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDO1FBRTNCLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQztRQUNqQyxNQUFNLDBCQUEwQixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9FLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUUsTUFBTSxlQUFlLEdBQWMsQ0FBQyxHQUFHLDBCQUEwQixDQUFDLGVBQWUsRUFBRSxHQUFHLHdCQUF3QixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2hJLElBQUksMEJBQTBCLENBQUMsS0FBSyxFQUFFO1lBQ2xDLE1BQU0sR0FBRywwQkFBMEIsQ0FBQyxLQUFLLENBQUM7WUFDMUMsSUFBSSxXQUFXLEtBQUssTUFBTSxFQUFFO2dCQUN4QixVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNuQixVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUNuQixVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQ3RCO1NBQ0o7UUFFRCxJQUFJLHdCQUF3QixDQUFDLEtBQUssRUFBRTtZQUNoQyxNQUFNLEdBQUcsd0JBQXdCLENBQUMsS0FBSyxDQUFDO1lBQ3hDLElBQUksV0FBVyxLQUFLLE1BQU0sRUFBRTtnQkFDeEIsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDbkIsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDbkIsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUN0QjtTQUNKO1FBRUQsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFO1lBQ25CLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3RDO1FBRUQsSUFBSSxlQUFlLENBQUMsTUFBTSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDaEQ7UUFFRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQseUJBQXlCLENBQUMsZUFBZ0MsRUFBRSxjQUErQjtRQUN2RixNQUFNLHFCQUFxQixHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDOUgsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsY0FBYyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXpILE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTNFLE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQyxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEYsTUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsS0FBSyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0csTUFBTSxXQUFXLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFFakYsTUFBTSxRQUFRLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRixNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUNsRixNQUFNLGNBQWMsR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUvRyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN6RixNQUFNLFVBQVUsR0FBRyxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUV6RixNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFckUsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUNqRSxNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBRWpFLE9BQU87WUFDSCxZQUFZLEVBQUUsYUFBYSxDQUFDLE1BQU0sQ0FBQztZQUNuQyxTQUFTLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUM3QixZQUFZLEVBQUUsYUFBYSxDQUFDLE1BQU0sQ0FBQztZQUNuQyxTQUFTLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUM3QixNQUFNO1lBQ04sTUFBTTtTQUNULENBQUM7SUFDTixDQUFDO0lBRUQsZUFBZSxDQUFDLGVBQWtDLEVBQUUsWUFBcUI7UUFDckUsSUFBSSxlQUFlLEdBQVUsRUFBRSxDQUFDO1FBQ2hDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLElBQUksVUFBVSxHQUFzQixFQUFFLENBQUM7UUFDdkMsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN0QyxNQUFNLElBQUksR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1FBRS9DLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxRixlQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQzFCLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDekgsSUFBSSxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQzlELFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILFVBQVUsR0FBRyxDQUFDLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFckYsTUFBTSxRQUFRLEdBQW9CLEVBQUUsQ0FBQztRQUNyQyxJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztRQUMzQixJQUFJLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBRTNCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3hDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUMsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3QixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzVCLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDN0QsSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDO2dCQUNuQixJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUU7b0JBQ3BCLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUNsRDtxQkFBTTtvQkFDSCxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO2lCQUNyRTtnQkFFRCxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUU7b0JBQ3JCLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUNuRDtxQkFBTTtvQkFDSCxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO2lCQUN0RTtnQkFFRCxRQUFRO2dCQUNSLElBQUksT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzlELEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLEdBQUcsR0FBRyxlQUFlLEVBQUU7b0JBQ3ZCLGtCQUFrQixHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3BHLEtBQUssR0FBRyxxQkFBcUIsR0FBRyxPQUFPLENBQUM7b0JBQ3hDLFdBQVcsR0FBRyxDQUFDLENBQUM7b0JBQ2hCLFVBQVUsR0FBRyxDQUFDLENBQUM7aUJBQ2xCO2dCQUVELE9BQU87Z0JBQ1AsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JGLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsa0JBQWtCLElBQUksR0FBRyxHQUFHLGVBQWUsRUFBRTtvQkFDOUMsa0JBQWtCLEdBQUcsYUFBYSxDQUFDO29CQUNuQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO29CQUNoQixLQUFLLEdBQUcscUJBQXFCLEdBQUcsT0FBTyxDQUFDO2lCQUMzQztnQkFFRCxRQUFRO2dCQUNSLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDbkUsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3pFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxDQUFDO2dCQUVoRCxJQUFJLENBQUMsa0JBQWtCLElBQUksR0FBRyxHQUFHLGVBQWUsRUFBRTtvQkFDOUMsa0JBQWtCLEdBQUcsY0FBYyxDQUFDO29CQUNwQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO29CQUNmLEtBQUssR0FBRyxxQkFBcUIsR0FBRyxPQUFPLENBQUM7aUJBQzNDO2FBQ0o7U0FDSjtRQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzdELElBQUksYUFBYSxHQUFhLEVBQUUsQ0FBQztRQUNqQyxJQUFJLFlBQVksR0FBYSxFQUFFLENBQUM7UUFDaEMsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFO1lBQzNCLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDaEMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUM7U0FDckY7UUFFRCxJQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUU7WUFDMUIsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM5QixhQUFhLENBQUMsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztTQUNsRjtRQUVELElBQUksYUFBYSxDQUFDLE1BQU0sSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFO1lBQzdDLE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxhQUFhLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLEdBQUcsWUFBWSxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUM7WUFDcEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3RDLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUM3RjtTQUNKO1FBRUQsU0FBUyxhQUFhLENBQUMsUUFBZ0IsRUFBRSxHQUFrQixFQUFFLFNBQWlCLEVBQUUsZ0JBQTBCO1lBQ3RHLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxTQUFnQyxDQUFDLENBQUM7WUFDbEQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsS0FBSyxLQUFLLENBQUMsSUFBSSxTQUFTLEtBQUssUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksU0FBUyxLQUFLLE9BQU8sQ0FBQztnQkFBRSxPQUFPO1lBQ2hILEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUNqQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxHQUFHLEVBQUU7b0JBQzVDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztvQkFDN0UsT0FBTztpQkFDVjthQUNKO1FBQ0wsQ0FBQztRQUVELFNBQVMsYUFBYSxDQUFDLGVBQWdDLEVBQUUsY0FBK0I7WUFDcEYsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDOUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDM0QsTUFBTSxLQUFLLEdBQUc7Z0JBQ1YsZUFBZSxDQUFDLFlBQVksQ0FBQztnQkFDN0IsZUFBZSxDQUFDLFlBQVksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxZQUFZLENBQUM7Z0JBQzdELGNBQWMsQ0FBQyxZQUFZLENBQUM7Z0JBQzVCLGNBQWMsQ0FBQyxZQUFZLENBQUMsR0FBRyxjQUFjLENBQUMsWUFBWSxDQUFDO2FBQzlELENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDakIsT0FBTyxZQUFZO2dCQUNmLENBQUMsQ0FBQztvQkFDSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLEtBQUssR0FBRyxNQUFNLEVBQUUsT0FBTyxDQUFDO29CQUM3RCxDQUFDLGNBQWMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxFQUFFLE9BQU8sQ0FBQztpQkFDdkM7Z0JBQ0gsQ0FBQyxDQUFDO29CQUNJLENBQUMsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7b0JBQzlELENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO2lCQUN2QyxDQUFDO1FBQ1osQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFpQixFQUFFLENBQWM7UUFDNUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07Z0JBQUUsT0FBTztZQUMzQixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUMvRixNQUFNLEVBQUUsc0JBQXNCO2dCQUM5QixXQUFXLEVBQUUsQ0FBQztnQkFDZCxjQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3pCLENBQUMsQ0FBQztZQUNILENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsS0FBZ0IsRUFBRSxDQUFjO1FBQ2hELEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDakIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO2dCQUFFLE9BQU87WUFDekIsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNuRyxNQUFNLEVBQUUsc0JBQXNCO2dCQUM5QixXQUFXLEVBQUUsQ0FBQzthQUNqQixDQUFDLENBQUM7WUFDSCxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXRCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ2pCLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ2xELE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2hILE1BQU0sRUFBRSxzQkFBc0I7b0JBQzlCLFdBQVcsRUFBRSxDQUFDO2lCQUNqQixDQUFDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2QixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztDQUNKO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxTQUEwQixFQUFFLEtBQXNCO0lBQ3pFLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0YsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLFNBQTBCLEVBQUUsS0FBc0I7SUFDdkUsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3RixDQUFDO0FBQ0QsU0FBUyxXQUFXLENBQUMsS0FBWSxFQUFFLFlBQXFCO0lBQ3BELE9BQU8sWUFBWTtRQUNmLENBQUMsQ0FBQztZQUNJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUMzQjtRQUNILENBQUMsQ0FBQztZQUNJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMzQixDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBsYWl0Qm9hcmQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2JvYXJkJztcbmltcG9ydCB7IGNyZWF0ZUcgfSBmcm9tICcuL2RvbS9jb21tb24nO1xuaW1wb3J0IHsgUGxhaXRFbGVtZW50IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9lbGVtZW50JztcbmltcG9ydCB7IEFuY2VzdG9yIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7IFBvaW50LCBSZWN0YW5nbGVDbGllbnQsIFNFTEVDVElPTl9CT1JERVJfQ09MT1IgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IGRlcHRoRmlyc3RSZWN1cnNpb24gfSBmcm9tICcuL3RyZWUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFsaWduUmVmIHtcbiAgICBkZWx0YVg6IG51bWJlcjtcbiAgICBkZWx0YVk6IG51bWJlcjtcbiAgICBnOiBTVkdHRWxlbWVudDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaXN0cmlidXRlUmVmIHtcbiAgICBiZWZvcmU6IHsgZGlzdGFuY2U6IG51bWJlcjsgaW5kZXg6IG51bWJlciB9W107XG4gICAgYWZ0ZXI6IHsgZGlzdGFuY2U6IG51bWJlcjsgaW5kZXg6IG51bWJlciB9W107XG59XG5cbmNvbnN0IEFMSUdOX1RPTEVSQU5DRSA9IDI7XG5cbmV4cG9ydCBjbGFzcyBBbGlnblJlYWN0aW9uIHtcbiAgICBhbGlnblJlY3RhbmdsZXM6IFJlY3RhbmdsZUNsaWVudFtdO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBib2FyZDogUGxhaXRCb2FyZCwgcHJpdmF0ZSBhY3RpdmVFbGVtZW50czogUGxhaXRFbGVtZW50W10sIHByaXZhdGUgYWN0aXZlUmVjdGFuZ2xlOiBSZWN0YW5nbGVDbGllbnQpIHtcbiAgICAgICAgdGhpcy5hbGlnblJlY3RhbmdsZXMgPSB0aGlzLmdldEFsaWduUmVjdGFuZ2xlKCk7XG4gICAgfVxuXG4gICAgZ2V0QWxpZ25SZWN0YW5nbGUoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogUmVjdGFuZ2xlQ2xpZW50W10gPSBbXTtcbiAgICAgICAgZGVwdGhGaXJzdFJlY3Vyc2lvbjxBbmNlc3Rvcj4oXG4gICAgICAgICAgICB0aGlzLmJvYXJkLFxuICAgICAgICAgICAgbm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKFBsYWl0Qm9hcmQuaXNCb2FyZChub2RlKSB8fCB0aGlzLmFjdGl2ZUVsZW1lbnRzLnNvbWUoZWxlbWVudCA9PiBub2RlLmlkID09PSBlbGVtZW50LmlkKSB8fCAhdGhpcy5ib2FyZC5pc0FsaWduKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgcmVjdGFuZ2xlID0gdGhpcy5ib2FyZC5nZXRSZWN0YW5nbGUobm9kZSk7XG4gICAgICAgICAgICAgICAgcmVjdGFuZ2xlICYmIHJlc3VsdC5wdXNoKHJlY3RhbmdsZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUgJiYgKFBsYWl0Qm9hcmQuaXNCb2FyZChub2RlKSB8fCB0aGlzLmJvYXJkLmlzUmVjdXJzaW9uKG5vZGUpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBoYW5kbGVBbGlnbigpOiBBbGlnblJlZiB7XG4gICAgICAgIGNvbnN0IGFsaWduUmVjdGFuZ2xlcyA9IHRoaXMuZ2V0QWxpZ25SZWN0YW5nbGUoKTtcbiAgICAgICAgY29uc3QgZyA9IGNyZWF0ZUcoKTtcbiAgICAgICAgbGV0IGFsaWduTGluZXMgPSBbXTtcblxuICAgICAgICBjb25zdCBvZmZzZXQgPSAxMjtcbiAgICAgICAgbGV0IGRlbHRhWCA9IDA7XG4gICAgICAgIGxldCBkZWx0YVkgPSAwO1xuICAgICAgICBsZXQgaXNDb3JyZWN0WCA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNDb3JyZWN0WSA9IGZhbHNlO1xuXG4gICAgICAgIGZvciAobGV0IGFsaWduUmVjdGFuZ2xlIG9mIGFsaWduUmVjdGFuZ2xlcykge1xuICAgICAgICAgICAgY29uc3QgY2xvc2VzdERpc3RhbmNlcyA9IHRoaXMuY2FsY3VsYXRlQ2xvc2VzdERpc3RhbmNlcyh0aGlzLmFjdGl2ZVJlY3RhbmdsZSwgYWxpZ25SZWN0YW5nbGUpO1xuICAgICAgICAgICAgbGV0IGNhbkRyYXdIb3Jpem9udGFsID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIWlzQ29ycmVjdFggJiYgY2xvc2VzdERpc3RhbmNlcy5hYnNYRGlzdGFuY2UgPCBBTElHTl9UT0xFUkFOQ0UpIHtcbiAgICAgICAgICAgICAgICBkZWx0YVggPSBjbG9zZXN0RGlzdGFuY2VzLnhEaXN0YW5jZTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS54IC09IGRlbHRhWDtcbiAgICAgICAgICAgICAgICBpc0NvcnJlY3RYID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjYW5EcmF3SG9yaXpvbnRhbCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjbG9zZXN0RGlzdGFuY2VzLmFic1hEaXN0YW5jZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNhbkRyYXdIb3Jpem9udGFsID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNhbkRyYXdIb3Jpem9udGFsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmVydGljYWxZID0gW1xuICAgICAgICAgICAgICAgICAgICBhbGlnblJlY3RhbmdsZS55LFxuICAgICAgICAgICAgICAgICAgICBhbGlnblJlY3RhbmdsZS55ICsgYWxpZ25SZWN0YW5nbGUuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55ICsgdGhpcy5hY3RpdmVSZWN0YW5nbGUuaGVpZ2h0XG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lVG9wWSA9IE1hdGgubWluKC4uLnZlcnRpY2FsWSkgLSBvZmZzZXQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbGluZUJvdHRvbVkgPSBNYXRoLm1heCguLi52ZXJ0aWNhbFkpICsgb2Zmc2V0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlZnRMaW5lID0gW3RoaXMuYWN0aXZlUmVjdGFuZ2xlLngsIGxpbmVUb3BZLCB0aGlzLmFjdGl2ZVJlY3RhbmdsZS54LCBsaW5lQm90dG9tWV07XG4gICAgICAgICAgICAgICAgY29uc3QgbWlkZGxlTGluZSA9IFtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVSZWN0YW5nbGUueCArIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLndpZHRoIC8gMixcbiAgICAgICAgICAgICAgICAgICAgbGluZVRvcFksXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLnggKyB0aGlzLmFjdGl2ZVJlY3RhbmdsZS53aWR0aCAvIDIsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVCb3R0b21ZXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBjb25zdCByaWdodExpbmUgPSBbXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLnggKyB0aGlzLmFjdGl2ZVJlY3RhbmdsZS53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbGluZVRvcFksXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLnggKyB0aGlzLmFjdGl2ZVJlY3RhbmdsZS53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgbGluZUJvdHRvbVlcbiAgICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkRHJhd0xlZnRMaW5lID1cbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdERpc3RhbmNlcy5pbmRleFggPT09IDAgfHxcbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdERpc3RhbmNlcy5pbmRleFggPT09IDEgfHxcbiAgICAgICAgICAgICAgICAgICAgKGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhYID09PSAyICYmIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLndpZHRoID09PSBhbGlnblJlY3RhbmdsZS53aWR0aCk7XG4gICAgICAgICAgICAgICAgaWYgKHNob3VsZERyYXdMZWZ0TGluZSAmJiAhYWxpZ25MaW5lc1swXSkge1xuICAgICAgICAgICAgICAgICAgICBhbGlnbkxpbmVzWzBdID0gbGVmdExpbmU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkRHJhd1JpZ2h0TGluZSA9XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhYID09PSAyIHx8XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhYID09PSAzIHx8XG4gICAgICAgICAgICAgICAgICAgIChjbG9zZXN0RGlzdGFuY2VzLmluZGV4WCA9PT0gMCAmJiB0aGlzLmFjdGl2ZVJlY3RhbmdsZS53aWR0aCA9PT0gYWxpZ25SZWN0YW5nbGUud2lkdGgpO1xuICAgICAgICAgICAgICAgIGlmIChzaG91bGREcmF3UmlnaHRMaW5lICYmICFhbGlnbkxpbmVzWzJdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduTGluZXNbMl0gPSByaWdodExpbmU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkRHJhd01pZGRsZUxpbmUgPSBjbG9zZXN0RGlzdGFuY2VzLmluZGV4WCA9PT0gNCB8fCAoIXNob3VsZERyYXdMZWZ0TGluZSAmJiAhc2hvdWxkRHJhd1JpZ2h0TGluZSk7XG4gICAgICAgICAgICAgICAgaWYgKHNob3VsZERyYXdNaWRkbGVMaW5lICYmICFhbGlnbkxpbmVzWzFdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduTGluZXNbMV0gPSBtaWRkbGVMaW5lO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlzQ29ycmVjdFggPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgY2FuRHJhd1ZlcnRpY2FsID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIWlzQ29ycmVjdFkgJiYgY2xvc2VzdERpc3RhbmNlcy5hYnNZRGlzdGFuY2UgPCBBTElHTl9UT0xFUkFOQ0UpIHtcbiAgICAgICAgICAgICAgICBkZWx0YVkgPSBjbG9zZXN0RGlzdGFuY2VzLnlEaXN0YW5jZTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55IC09IGRlbHRhWTtcbiAgICAgICAgICAgICAgICBpc0NvcnJlY3RZID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjYW5EcmF3VmVydGljYWwgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNsb3Nlc3REaXN0YW5jZXMuYWJzWURpc3RhbmNlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY2FuRHJhd1ZlcnRpY2FsID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYW5EcmF3VmVydGljYWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBob3Jpem9udGFsWCA9IFtcbiAgICAgICAgICAgICAgICAgICAgYWxpZ25SZWN0YW5nbGUueCxcbiAgICAgICAgICAgICAgICAgICAgYWxpZ25SZWN0YW5nbGUueCArIGFsaWduUmVjdGFuZ2xlLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS54LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS54ICsgdGhpcy5hY3RpdmVSZWN0YW5nbGUud2lkdGhcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVMZWZ0WCA9IE1hdGgubWluKC4uLmhvcml6b250YWxYKSAtIG9mZnNldDtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lUmlnaHRYID0gTWF0aC5tYXgoLi4uaG9yaXpvbnRhbFgpICsgb2Zmc2V0O1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvcExpbmUgPSBbbGluZUxlZnRYLCB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55LCBsaW5lUmlnaHRYLCB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55XTtcbiAgICAgICAgICAgICAgICBjb25zdCBob3Jpem9udGFsTWlkZGxlTGluZSA9IFtcbiAgICAgICAgICAgICAgICAgICAgbGluZUxlZnRYLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVJlY3RhbmdsZS55ICsgdGhpcy5hY3RpdmVSZWN0YW5nbGUuaGVpZ2h0IC8gMixcbiAgICAgICAgICAgICAgICAgICAgbGluZVJpZ2h0WCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVSZWN0YW5nbGUueSArIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLmhlaWdodCAvIDJcbiAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvdHRvbUxpbmUgPSBbXG4gICAgICAgICAgICAgICAgICAgIGxpbmVMZWZ0WCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVSZWN0YW5nbGUueSArIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLmhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgbGluZVJpZ2h0WCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVSZWN0YW5nbGUueSArIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLmhlaWdodFxuICAgICAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzaG91bGREcmF3VG9wTGluZSA9XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhZID09PSAwIHx8XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhZID09PSAxIHx8XG4gICAgICAgICAgICAgICAgICAgIChjbG9zZXN0RGlzdGFuY2VzLmluZGV4WSA9PT0gMiAmJiB0aGlzLmFjdGl2ZVJlY3RhbmdsZS5oZWlnaHQgPT09IGFsaWduUmVjdGFuZ2xlLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgaWYgKHNob3VsZERyYXdUb3BMaW5lICYmICFhbGlnbkxpbmVzWzNdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduTGluZXNbM10gPSB0b3BMaW5lO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZERyYXdCb3R0b21MaW5lID1cbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdERpc3RhbmNlcy5pbmRleFkgPT09IDIgfHxcbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdERpc3RhbmNlcy5pbmRleFkgPT09IDMgfHxcbiAgICAgICAgICAgICAgICAgICAgKGNsb3Nlc3REaXN0YW5jZXMuaW5kZXhZID09PSAwICYmIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLndpZHRoID09PSBhbGlnblJlY3RhbmdsZS53aWR0aCk7XG4gICAgICAgICAgICAgICAgaWYgKHNob3VsZERyYXdCb3R0b21MaW5lICYmICFhbGlnbkxpbmVzWzVdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduTGluZXNbNV0gPSBib3R0b21MaW5lO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZERyYXdNaWRkbGVMaW5lID0gY2xvc2VzdERpc3RhbmNlcy5pbmRleFkgPT09IDQgfHwgKCFzaG91bGREcmF3VG9wTGluZSAmJiAhc2hvdWxkRHJhd0JvdHRvbUxpbmUpO1xuICAgICAgICAgICAgICAgIGlmIChzaG91bGREcmF3TWlkZGxlTGluZSAmJiAhYWxpZ25MaW5lc1s0XSkge1xuICAgICAgICAgICAgICAgICAgICBhbGlnbkxpbmVzWzRdID0gaG9yaXpvbnRhbE1pZGRsZUxpbmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYWxpZ25EZWx0YVggPSBkZWx0YVg7XG4gICAgICAgIGNvbnN0IGFsaWduRGVsdGFZID0gZGVsdGFZO1xuXG4gICAgICAgIHRoaXMuYWN0aXZlUmVjdGFuZ2xlLnggKz0gZGVsdGFYO1xuICAgICAgICBjb25zdCBkaXN0cmlidXRlSG9yaXpvbnRhbFJlc3VsdCA9IHRoaXMuYWxpZ25EaXN0cmlidXRlKGFsaWduUmVjdGFuZ2xlcywgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IGRpc3RyaWJ1dGVWZXJ0aWNhbFJlc3VsdCA9IHRoaXMuYWxpZ25EaXN0cmlidXRlKGFsaWduUmVjdGFuZ2xlcywgZmFsc2UpO1xuICAgICAgICBjb25zdCBkaXN0cmlidXRlTGluZXM6IFBvaW50W11bXSA9IFsuLi5kaXN0cmlidXRlSG9yaXpvbnRhbFJlc3VsdC5kaXN0cmlidXRlTGluZXMsIC4uLmRpc3RyaWJ1dGVWZXJ0aWNhbFJlc3VsdC5kaXN0cmlidXRlTGluZXNdO1xuICAgICAgICBpZiAoZGlzdHJpYnV0ZUhvcml6b250YWxSZXN1bHQuZGVsdGEpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGRpc3RyaWJ1dGVIb3Jpem9udGFsUmVzdWx0LmRlbHRhO1xuICAgICAgICAgICAgaWYgKGFsaWduRGVsdGFYICE9PSBkZWx0YVgpIHtcbiAgICAgICAgICAgICAgICBhbGlnbkxpbmVzWzBdID0gW107XG4gICAgICAgICAgICAgICAgYWxpZ25MaW5lc1sxXSA9IFtdO1xuICAgICAgICAgICAgICAgIGFsaWduTGluZXNbMl0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXN0cmlidXRlVmVydGljYWxSZXN1bHQuZGVsdGEpIHtcbiAgICAgICAgICAgIGRlbHRhWSA9IGRpc3RyaWJ1dGVWZXJ0aWNhbFJlc3VsdC5kZWx0YTtcbiAgICAgICAgICAgIGlmIChhbGlnbkRlbHRhWSAhPT0gZGVsdGFZKSB7XG4gICAgICAgICAgICAgICAgYWxpZ25MaW5lc1szXSA9IFtdO1xuICAgICAgICAgICAgICAgIGFsaWduTGluZXNbNF0gPSBbXTtcbiAgICAgICAgICAgICAgICBhbGlnbkxpbmVzWzVdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWxpZ25MaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0FsaWduTGluZXMoYWxpZ25MaW5lcywgZyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGlzdHJpYnV0ZUxpbmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5kcmF3RGlzdHJpYnV0ZUxpbmVzKGRpc3RyaWJ1dGVMaW5lcywgZyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBkZWx0YVgsIGRlbHRhWSwgZyB9O1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZUNsb3Nlc3REaXN0YW5jZXMoYWN0aXZlUmVjdGFuZ2xlOiBSZWN0YW5nbGVDbGllbnQsIGFsaWduUmVjdGFuZ2xlOiBSZWN0YW5nbGVDbGllbnQpIHtcbiAgICAgICAgY29uc3QgYWN0aXZlUmVjdGFuZ2xlQ2VudGVyID0gW2FjdGl2ZVJlY3RhbmdsZS54ICsgYWN0aXZlUmVjdGFuZ2xlLndpZHRoIC8gMiwgYWN0aXZlUmVjdGFuZ2xlLnkgKyBhY3RpdmVSZWN0YW5nbGUuaGVpZ2h0IC8gMl07XG4gICAgICAgIGNvbnN0IGFsaWduUmVjdGFuZ2xlQ2VudGVyID0gW2FsaWduUmVjdGFuZ2xlLnggKyBhbGlnblJlY3RhbmdsZS53aWR0aCAvIDIsIGFsaWduUmVjdGFuZ2xlLnkgKyBhbGlnblJlY3RhbmdsZS5oZWlnaHQgLyAyXTtcblxuICAgICAgICBjb25zdCBjZW50ZXJYRGlzdGFuY2UgPSBhY3RpdmVSZWN0YW5nbGVDZW50ZXJbMF0gLSBhbGlnblJlY3RhbmdsZUNlbnRlclswXTtcbiAgICAgICAgY29uc3QgY2VudGVyWURpc3RhbmNlID0gYWN0aXZlUmVjdGFuZ2xlQ2VudGVyWzFdIC0gYWxpZ25SZWN0YW5nbGVDZW50ZXJbMV07XG5cbiAgICAgICAgY29uc3QgbGVmdFRvTGVmdCA9IGFjdGl2ZVJlY3RhbmdsZS54IC0gYWxpZ25SZWN0YW5nbGUueDtcbiAgICAgICAgY29uc3QgbGVmdFRvUmlnaHQgPSBhY3RpdmVSZWN0YW5nbGUueCAtIChhbGlnblJlY3RhbmdsZS54ICsgYWxpZ25SZWN0YW5nbGUud2lkdGgpO1xuICAgICAgICBjb25zdCByaWdodFRvUmlnaHQgPSBhY3RpdmVSZWN0YW5nbGUueCArIGFjdGl2ZVJlY3RhbmdsZS53aWR0aCAtIChhbGlnblJlY3RhbmdsZS54ICsgYWxpZ25SZWN0YW5nbGUud2lkdGgpO1xuICAgICAgICBjb25zdCByaWdodFRvTGVmdCA9IGFjdGl2ZVJlY3RhbmdsZS54ICsgYWN0aXZlUmVjdGFuZ2xlLndpZHRoIC0gYWxpZ25SZWN0YW5nbGUueDtcblxuICAgICAgICBjb25zdCB0b3BUb1RvcCA9IGFjdGl2ZVJlY3RhbmdsZS55IC0gYWxpZ25SZWN0YW5nbGUueTtcbiAgICAgICAgY29uc3QgdG9wVG9Cb3R0b20gPSBhY3RpdmVSZWN0YW5nbGUueSAtIChhbGlnblJlY3RhbmdsZS55ICsgYWxpZ25SZWN0YW5nbGUuaGVpZ2h0KTtcbiAgICAgICAgY29uc3QgYm90dG9tVG9Ub3AgPSBhY3RpdmVSZWN0YW5nbGUueSArIGFjdGl2ZVJlY3RhbmdsZS5oZWlnaHQgLSBhbGlnblJlY3RhbmdsZS55O1xuICAgICAgICBjb25zdCBib3R0b21Ub0JvdHRvbSA9IGFjdGl2ZVJlY3RhbmdsZS55ICsgYWN0aXZlUmVjdGFuZ2xlLmhlaWdodCAtIChhbGlnblJlY3RhbmdsZS55ICsgYWxpZ25SZWN0YW5nbGUuaGVpZ2h0KTtcblxuICAgICAgICBjb25zdCB4RGlzdGFuY2VzID0gW2xlZnRUb0xlZnQsIGxlZnRUb1JpZ2h0LCByaWdodFRvUmlnaHQsIHJpZ2h0VG9MZWZ0LCBjZW50ZXJYRGlzdGFuY2VdO1xuICAgICAgICBjb25zdCB5RGlzdGFuY2VzID0gW3RvcFRvVG9wLCB0b3BUb0JvdHRvbSwgYm90dG9tVG9Cb3R0b20sIGJvdHRvbVRvVG9wLCBjZW50ZXJZRGlzdGFuY2VdO1xuXG4gICAgICAgIGNvbnN0IHhEaXN0YW5jZXNBYnMgPSB4RGlzdGFuY2VzLm1hcChkaXN0YW5jZSA9PiBNYXRoLmFicyhkaXN0YW5jZSkpO1xuICAgICAgICBjb25zdCB5RGlzdGFuY2VzQWJzID0geURpc3RhbmNlcy5tYXAoZGlzdGFuY2UgPT4gTWF0aC5hYnMoZGlzdGFuY2UpKTtcblxuICAgICAgICBjb25zdCBpbmRleFggPSB4RGlzdGFuY2VzQWJzLmluZGV4T2YoTWF0aC5taW4oLi4ueERpc3RhbmNlc0FicykpO1xuICAgICAgICBjb25zdCBpbmRleFkgPSB5RGlzdGFuY2VzQWJzLmluZGV4T2YoTWF0aC5taW4oLi4ueURpc3RhbmNlc0FicykpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhYnNYRGlzdGFuY2U6IHhEaXN0YW5jZXNBYnNbaW5kZXhYXSxcbiAgICAgICAgICAgIHhEaXN0YW5jZTogeERpc3RhbmNlc1tpbmRleFhdLFxuICAgICAgICAgICAgYWJzWURpc3RhbmNlOiB5RGlzdGFuY2VzQWJzW2luZGV4WV0sXG4gICAgICAgICAgICB5RGlzdGFuY2U6IHlEaXN0YW5jZXNbaW5kZXhZXSxcbiAgICAgICAgICAgIGluZGV4WCxcbiAgICAgICAgICAgIGluZGV4WVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFsaWduRGlzdHJpYnV0ZShhbGlnblJlY3RhbmdsZXM6IFJlY3RhbmdsZUNsaWVudFtdLCBpc0hvcml6b250YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgbGV0IGRpc3RyaWJ1dGVMaW5lczogYW55W10gPSBbXTtcbiAgICAgICAgbGV0IGRlbHRhID0gMDtcbiAgICAgICAgbGV0IHJlY3RhbmdsZXM6IFJlY3RhbmdsZUNsaWVudFtdID0gW107XG4gICAgICAgIGNvbnN0IGF4aXMgPSBpc0hvcml6b250YWwgPyAneCcgOiAneSc7XG4gICAgICAgIGNvbnN0IHNpZGUgPSBpc0hvcml6b250YWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG5cbiAgICAgICAgY29uc3QgYWN0aXZlUmVjdGFuZ2xlQ2VudGVyID0gdGhpcy5hY3RpdmVSZWN0YW5nbGVbYXhpc10gKyB0aGlzLmFjdGl2ZVJlY3RhbmdsZVtzaWRlXSAvIDI7XG4gICAgICAgIGFsaWduUmVjdGFuZ2xlcy5mb3JFYWNoKHJlYyA9PiB7XG4gICAgICAgICAgICBjb25zdCBpc0Nyb3NzID0gaXNIb3Jpem9udGFsID8gaXNIb3Jpem9udGFsQ3Jvc3MocmVjLCB0aGlzLmFjdGl2ZVJlY3RhbmdsZSkgOiBpc1ZlcnRpY2FsQ3Jvc3MocmVjLCB0aGlzLmFjdGl2ZVJlY3RhbmdsZSk7XG4gICAgICAgICAgICBpZiAoaXNDcm9zcyAmJiAhUmVjdGFuZ2xlQ2xpZW50LmlzSGl0KHJlYywgdGhpcy5hY3RpdmVSZWN0YW5nbGUpKSB7XG4gICAgICAgICAgICAgICAgcmVjdGFuZ2xlcy5wdXNoKHJlYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZWN0YW5nbGVzID0gWy4uLnJlY3RhbmdsZXMsIHRoaXMuYWN0aXZlUmVjdGFuZ2xlXS5zb3J0KChhLCBiKSA9PiBhW2F4aXNdIC0gYltheGlzXSk7XG5cbiAgICAgICAgY29uc3QgcmVmQXJyYXk6IERpc3RyaWJ1dGVSZWZbXSA9IFtdO1xuICAgICAgICBsZXQgZGlzdHJpYnV0ZURpc3RhbmNlID0gMDtcbiAgICAgICAgbGV0IGJlZm9yZUluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgYWZ0ZXJJbmRleCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RhbmdsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJlY3RhbmdsZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmUgPSByZWN0YW5nbGVzW2ldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFmdGVyID0gcmVjdGFuZ2xlc1tqXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGFmdGVyW2F4aXNdIC0gKGJlZm9yZVtheGlzXSArIGJlZm9yZVtzaWRlXSk7XG4gICAgICAgICAgICAgICAgbGV0IGRpZiA9IEluZmluaXR5O1xuICAgICAgICAgICAgICAgIGlmIChyZWZBcnJheVtpXT8uYWZ0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmQXJyYXlbaV0uYWZ0ZXIucHVzaCh7IGRpc3RhbmNlLCBpbmRleDogaiB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWZBcnJheVtpXSA9IHsgLi4ucmVmQXJyYXlbaV0sIGFmdGVyOiBbeyBkaXN0YW5jZSwgaW5kZXg6IGogfV0gfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmVmQXJyYXlbal0/LmJlZm9yZSkge1xuICAgICAgICAgICAgICAgICAgICByZWZBcnJheVtqXS5iZWZvcmUucHVzaCh7IGRpc3RhbmNlLCBpbmRleDogaSB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWZBcnJheVtqXSA9IHsgLi4ucmVmQXJyYXlbal0sIGJlZm9yZTogW3sgZGlzdGFuY2UsIGluZGV4OiBpIH1dIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy9taWRkbGVcbiAgICAgICAgICAgICAgICBsZXQgX2NlbnRlciA9IChiZWZvcmVbYXhpc10gKyBiZWZvcmVbc2lkZV0gKyBhZnRlcltheGlzXSkgLyAyO1xuICAgICAgICAgICAgICAgIGRpZiA9IE1hdGguYWJzKGFjdGl2ZVJlY3RhbmdsZUNlbnRlciAtIF9jZW50ZXIpO1xuICAgICAgICAgICAgICAgIGlmIChkaWYgPCBBTElHTl9UT0xFUkFOQ0UpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzdHJpYnV0ZURpc3RhbmNlID0gKGFmdGVyW2F4aXNdIC0gKGJlZm9yZVtheGlzXSArIGJlZm9yZVtzaWRlXSkgLSB0aGlzLmFjdGl2ZVJlY3RhbmdsZVtzaWRlXSkgLyAyO1xuICAgICAgICAgICAgICAgICAgICBkZWx0YSA9IGFjdGl2ZVJlY3RhbmdsZUNlbnRlciAtIF9jZW50ZXI7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZUluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgYWZ0ZXJJbmRleCA9IGo7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy9hZnRlclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlUmlnaHQgPSBhZnRlcltheGlzXSAtIChiZWZvcmVbYXhpc10gKyBiZWZvcmVbc2lkZV0pO1xuICAgICAgICAgICAgICAgIF9jZW50ZXIgPSBhZnRlcltheGlzXSArIGFmdGVyW3NpZGVdICsgZGlzdGFuY2VSaWdodCArIHRoaXMuYWN0aXZlUmVjdGFuZ2xlW3NpZGVdIC8gMjtcbiAgICAgICAgICAgICAgICBkaWYgPSBNYXRoLmFicyhhY3RpdmVSZWN0YW5nbGVDZW50ZXIgLSBfY2VudGVyKTtcbiAgICAgICAgICAgICAgICBpZiAoIWRpc3RyaWJ1dGVEaXN0YW5jZSAmJiBkaWYgPCBBTElHTl9UT0xFUkFOQ0UpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzdHJpYnV0ZURpc3RhbmNlID0gZGlzdGFuY2VSaWdodDtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlSW5kZXggPSBqO1xuICAgICAgICAgICAgICAgICAgICBkZWx0YSA9IGFjdGl2ZVJlY3RhbmdsZUNlbnRlciAtIF9jZW50ZXI7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy9iZWZvcmVcbiAgICAgICAgICAgICAgICBjb25zdCBkaXN0YW5jZUJlZm9yZSA9IGFmdGVyW2F4aXNdIC0gKGJlZm9yZVtheGlzXSArIGJlZm9yZVtzaWRlXSk7XG4gICAgICAgICAgICAgICAgX2NlbnRlciA9IGJlZm9yZVtheGlzXSAtIGRpc3RhbmNlQmVmb3JlIC0gdGhpcy5hY3RpdmVSZWN0YW5nbGVbc2lkZV0gLyAyO1xuICAgICAgICAgICAgICAgIGRpZiA9IE1hdGguYWJzKGFjdGl2ZVJlY3RhbmdsZUNlbnRlciAtIF9jZW50ZXIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFkaXN0cmlidXRlRGlzdGFuY2UgJiYgZGlmIDwgQUxJR05fVE9MRVJBTkNFKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3RyaWJ1dGVEaXN0YW5jZSA9IGRpc3RhbmNlQmVmb3JlO1xuICAgICAgICAgICAgICAgICAgICBhZnRlckluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgZGVsdGEgPSBhY3RpdmVSZWN0YW5nbGVDZW50ZXIgLSBfY2VudGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gcmVjdGFuZ2xlcy5pbmRleE9mKHRoaXMuYWN0aXZlUmVjdGFuZ2xlKTtcbiAgICAgICAgbGV0IGJlZm9yZUluZGV4ZXM6IG51bWJlcltdID0gW107XG4gICAgICAgIGxldCBhZnRlckluZGV4ZXM6IG51bWJlcltdID0gW107XG4gICAgICAgIGlmIChiZWZvcmVJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBiZWZvcmVJbmRleGVzLnB1c2goYmVmb3JlSW5kZXgpO1xuICAgICAgICAgICAgZmluZFJlY3RhbmdsZShkaXN0cmlidXRlRGlzdGFuY2UsIHJlZkFycmF5W2JlZm9yZUluZGV4XSwgJ2JlZm9yZScsIGJlZm9yZUluZGV4ZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFmdGVySW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYWZ0ZXJJbmRleGVzLnB1c2goYWZ0ZXJJbmRleCk7XG4gICAgICAgICAgICBmaW5kUmVjdGFuZ2xlKGRpc3RyaWJ1dGVEaXN0YW5jZSwgcmVmQXJyYXlbYWZ0ZXJJbmRleF0sICdhZnRlcicsIGFmdGVySW5kZXhlcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmVmb3JlSW5kZXhlcy5sZW5ndGggfHwgYWZ0ZXJJbmRleGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgaW5kZXhBcnIgPSBbLi4uYmVmb3JlSW5kZXhlcy5yZXZlcnNlKCksIGFjdGl2ZUluZGV4LCAuLi5hZnRlckluZGV4ZXNdO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVSZWN0YW5nbGVbYXhpc10gLT0gZGVsdGE7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGluZGV4QXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZGlzdHJpYnV0ZUxpbmVzLnB1c2goZ2V0TGluZVBvaW50cyhyZWN0YW5nbGVzW2luZGV4QXJyW2kgLSAxXV0sIHJlY3RhbmdsZXNbaW5kZXhBcnJbaV1dKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBmaW5kUmVjdGFuZ2xlKGRpc3RhbmNlOiBudW1iZXIsIHJlZjogRGlzdHJpYnV0ZVJlZiwgZGlyZWN0aW9uOiBzdHJpbmcsIHJlY3RhbmdsZUluZGV4ZXM6IG51bWJlcltdKSB7XG4gICAgICAgICAgICBjb25zdCBhcnIgPSByZWZbZGlyZWN0aW9uIGFzIGtleW9mIERpc3RyaWJ1dGVSZWZdO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSByZWZBcnJheS5pbmRleE9mKHJlZik7XG4gICAgICAgICAgICBpZiAoKGluZGV4ID09PSAwICYmIGRpcmVjdGlvbiA9PT0gJ2JlZm9yZScpIHx8IChpbmRleCA9PT0gcmVmQXJyYXkubGVuZ3RoIC0gMSAmJiBkaXJlY3Rpb24gPT09ICdhZnRlcicpKSByZXR1cm47XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChNYXRoLmFicyhhcnJbaV0uZGlzdGFuY2UgLSBkaXN0YW5jZSkgPCAwLjEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlSW5kZXhlcy5wdXNoKGFycltpXS5pbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGZpbmRSZWN0YW5nbGUoZGlzdGFuY2UsIHJlZkFycmF5W2FycltpXS5pbmRleF0sIGRpcmVjdGlvbiwgcmVjdGFuZ2xlSW5kZXhlcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBnZXRMaW5lUG9pbnRzKGJlZm9yZVJlY3RhbmdsZTogUmVjdGFuZ2xlQ2xpZW50LCBhZnRlclJlY3RhbmdsZTogUmVjdGFuZ2xlQ2xpZW50KSB7XG4gICAgICAgICAgICBjb25zdCBvcHBvc2l0ZUF4aXMgPSBheGlzID09PSAneCcgPyAneScgOiAneCc7XG4gICAgICAgICAgICBjb25zdCBvcHBvc2l0ZVNpZGUgPSBzaWRlID09PSAnd2lkdGgnID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgICAgICAgICAgY29uc3QgYWxpZ24gPSBbXG4gICAgICAgICAgICAgICAgYmVmb3JlUmVjdGFuZ2xlW29wcG9zaXRlQXhpc10sXG4gICAgICAgICAgICAgICAgYmVmb3JlUmVjdGFuZ2xlW29wcG9zaXRlQXhpc10gKyBiZWZvcmVSZWN0YW5nbGVbb3Bwb3NpdGVTaWRlXSxcbiAgICAgICAgICAgICAgICBhZnRlclJlY3RhbmdsZVtvcHBvc2l0ZUF4aXNdLFxuICAgICAgICAgICAgICAgIGFmdGVyUmVjdGFuZ2xlW29wcG9zaXRlQXhpc10gKyBhZnRlclJlY3RhbmdsZVtvcHBvc2l0ZVNpZGVdXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgY29uc3Qgc29ydEFyciA9IGFsaWduLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgICAgICAgICAgIGNvbnN0IGF2ZXJhZ2UgPSAoc29ydEFyclsxXSArIHNvcnRBcnJbMl0pIC8gMjtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IDM7XG4gICAgICAgICAgICByZXR1cm4gaXNIb3Jpem9udGFsXG4gICAgICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgICAgICAgW2JlZm9yZVJlY3RhbmdsZS54ICsgYmVmb3JlUmVjdGFuZ2xlLndpZHRoICsgb2Zmc2V0LCBhdmVyYWdlXSxcbiAgICAgICAgICAgICAgICAgICAgICBbYWZ0ZXJSZWN0YW5nbGUueCAtIG9mZnNldCwgYXZlcmFnZV1cbiAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICA6IFtcbiAgICAgICAgICAgICAgICAgICAgICBbYXZlcmFnZSwgYmVmb3JlUmVjdGFuZ2xlLnkgKyBiZWZvcmVSZWN0YW5nbGUuaGVpZ2h0ICsgb2Zmc2V0XSxcbiAgICAgICAgICAgICAgICAgICAgICBbYXZlcmFnZSwgYWZ0ZXJSZWN0YW5nbGUueSAtIG9mZnNldF1cbiAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgZGVsdGEsIGRpc3RyaWJ1dGVMaW5lcyB9O1xuICAgIH1cblxuICAgIGRyYXdBbGlnbkxpbmVzKGxpbmVzOiBudW1iZXJbXVtdLCBnOiBTVkdHRWxlbWVudCkge1xuICAgICAgICBsaW5lcy5mb3JFYWNoKHBvaW50cyA9PiB7XG4gICAgICAgICAgICBpZiAoIXBvaW50cy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IHhBbGlnbiA9IFBsYWl0Qm9hcmQuZ2V0Um91Z2hTVkcodGhpcy5ib2FyZCkubGluZShwb2ludHNbMF0sIHBvaW50c1sxXSwgcG9pbnRzWzJdLCBwb2ludHNbM10sIHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IFNFTEVDVElPTl9CT1JERVJfQ09MT1IsXG4gICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgICAgICAgc3Ryb2tlTGluZURhc2g6IFs0LCA0XVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBnLmFwcGVuZENoaWxkKHhBbGlnbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGRyYXdEaXN0cmlidXRlTGluZXMobGluZXM6IFBvaW50W11bXSwgZzogU1ZHR0VsZW1lbnQpIHtcbiAgICAgICAgbGluZXMuZm9yRWFjaChsaW5lID0+IHtcbiAgICAgICAgICAgIGlmICghbGluZS5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIGxldCBpc0hvcml6b250YWwgPSBsaW5lWzBdWzFdID09PSBsaW5lWzFdWzFdO1xuICAgICAgICAgICAgY29uc3QgeUFsaWduID0gUGxhaXRCb2FyZC5nZXRSb3VnaFNWRyh0aGlzLmJvYXJkKS5saW5lKGxpbmVbMF1bMF0sIGxpbmVbMF1bMV0sIGxpbmVbMV1bMF0sIGxpbmVbMV1bMV0sIHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IFNFTEVDVElPTl9CT1JERVJfQ09MT1IsXG4gICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDFcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZy5hcHBlbmRDaGlsZCh5QWxpZ24pO1xuXG4gICAgICAgICAgICBsaW5lLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhclBvaW50ID0gZ2V0QmFyUG9pbnQocG9pbnQsIGlzSG9yaXpvbnRhbCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYmFyID0gUGxhaXRCb2FyZC5nZXRSb3VnaFNWRyh0aGlzLmJvYXJkKS5saW5lKGJhclBvaW50WzBdWzBdLCBiYXJQb2ludFswXVsxXSwgYmFyUG9pbnRbMV1bMF0sIGJhclBvaW50WzFdWzFdLCB7XG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogU0VMRUNUSU9OX0JPUkRFUl9DT0xPUixcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBnLmFwcGVuZENoaWxkKGJhcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0hvcml6b250YWxDcm9zcyhyZWN0YW5nbGU6IFJlY3RhbmdsZUNsaWVudCwgb3RoZXI6IFJlY3RhbmdsZUNsaWVudCkge1xuICAgIHJldHVybiAhKHJlY3RhbmdsZS55ICsgcmVjdGFuZ2xlLmhlaWdodCA8IG90aGVyLnkgfHwgcmVjdGFuZ2xlLnkgPiBvdGhlci55ICsgb3RoZXIuaGVpZ2h0KTtcbn1cblxuZnVuY3Rpb24gaXNWZXJ0aWNhbENyb3NzKHJlY3RhbmdsZTogUmVjdGFuZ2xlQ2xpZW50LCBvdGhlcjogUmVjdGFuZ2xlQ2xpZW50KSB7XG4gICAgcmV0dXJuICEocmVjdGFuZ2xlLnggKyByZWN0YW5nbGUud2lkdGggPCBvdGhlci54IHx8IHJlY3RhbmdsZS54ID4gb3RoZXIueCArIG90aGVyLndpZHRoKTtcbn1cbmZ1bmN0aW9uIGdldEJhclBvaW50KHBvaW50OiBQb2ludCwgaXNIb3Jpem9udGFsOiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGlzSG9yaXpvbnRhbFxuICAgICAgICA/IFtcbiAgICAgICAgICAgICAgW3BvaW50WzBdLCBwb2ludFsxXSAtIDRdLFxuICAgICAgICAgICAgICBbcG9pbnRbMF0sIHBvaW50WzFdICsgNF1cbiAgICAgICAgICBdXG4gICAgICAgIDogW1xuICAgICAgICAgICAgICBbcG9pbnRbMF0gLSA0LCBwb2ludFsxXV0sXG4gICAgICAgICAgICAgIFtwb2ludFswXSArIDQsIHBvaW50WzFdXVxuICAgICAgICAgIF07XG59XG4iXX0=