@libs-ui/components-draw-line 0.2.10-6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/draw-line.directive.d.ts +56 -0
- package/draw-line.interface.d.ts +119 -0
- package/esm2022/draw-line.directive.mjs +650 -0
- package/esm2022/draw-line.interface.mjs +2 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/libs-ui-components-draw-line.mjs +5 -0
- package/esm2022/util/calculator-branch.util.mjs +27 -0
- package/esm2022/util/calculator-diretion-element.until.mjs +350 -0
- package/esm2022/util/connect-navigation-new-element.util.mjs +378 -0
- package/esm2022/util/line-connect-bottom-left.until.mjs +147 -0
- package/fesm2022/libs-ui-components-draw-line.mjs +1547 -0
- package/fesm2022/libs-ui-components-draw-line.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/package.json +25 -0
- package/util/calculator-branch.util.d.ts +9 -0
- package/util/calculator-diretion-element.until.d.ts +64 -0
- package/util/connect-navigation-new-element.util.d.ts +17 -0
- package/util/line-connect-bottom-left.until.d.ts +5 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { cloneDeep } from "@libs-ui/utils";
|
|
2
|
+
import { MoCanvasCalculatorBranchUtil } from "./calculator-branch.util";
|
|
3
|
+
import { MoCanvasCalculatorDirectionElementUtil } from "./calculator-diretion-element.until";
|
|
4
|
+
import { MoCanvasConnectNavigationBottomLeftElementUtil } from "./line-connect-bottom-left.until";
|
|
5
|
+
export class MoCanvasConnectNavigationNewElementUtil {
|
|
6
|
+
static ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT = 32;
|
|
7
|
+
static START_MODE = 'right-left';
|
|
8
|
+
static setXYConnectElements(elementFrom, elementNext, obstacleRect, separatedPoints, curve) {
|
|
9
|
+
this.drawLineConnect(elementFrom, elementNext, obstacleRect, separatedPoints, curve);
|
|
10
|
+
}
|
|
11
|
+
static drawLineConnect(elementFrom, elementNext, obstacleRect, separatedPoints, curve) {
|
|
12
|
+
let start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0); // điểm out luôn ở phía bên phải
|
|
13
|
+
let start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0) / 2; // điểm out luôn ở phía bên phải
|
|
14
|
+
if (MoCanvasConnectNavigationNewElementUtil.START_MODE === 'bottom-top') { // điểm out luôn ở phía bên dưới
|
|
15
|
+
start_x = (elementFrom.x ?? 0) + ((elementFrom.width ?? 0) / 2);
|
|
16
|
+
start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
|
|
17
|
+
}
|
|
18
|
+
if (MoCanvasConnectNavigationNewElementUtil.START_MODE === 'bottom-left') { // điểm out luôn ở phía bên dưới
|
|
19
|
+
start_x = (elementFrom.x ?? 0) + ((elementFrom.width ?? 0) / 2);
|
|
20
|
+
start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
|
|
21
|
+
}
|
|
22
|
+
const M_start = { x: start_x, y: start_y };
|
|
23
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start_x, elementNext.x, 'x');
|
|
24
|
+
switch (MoCanvasConnectNavigationNewElementUtil.START_MODE) {
|
|
25
|
+
case 'right-left':
|
|
26
|
+
if (directionX === 'left') {
|
|
27
|
+
this.lineConnectLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.lineConnectRight(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
31
|
+
break;
|
|
32
|
+
case 'bottom-top':
|
|
33
|
+
if (directionX === 'left') {
|
|
34
|
+
this.lineConnectLeftWithBottomStart(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.lineConnectRightWithBottomStart(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
38
|
+
break;
|
|
39
|
+
case 'bottom-left':
|
|
40
|
+
console.log(directionX);
|
|
41
|
+
if (directionX === 'left') {
|
|
42
|
+
MoCanvasConnectNavigationBottomLeftElementUtil.lineLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
MoCanvasConnectNavigationBottomLeftElementUtil.rightLeft(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
static lineConnectRight(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
|
|
50
|
+
const endPosition = {
|
|
51
|
+
x: (elementNext.x ?? 0) - (lineCurve * 3),
|
|
52
|
+
y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2
|
|
53
|
+
};
|
|
54
|
+
const endPositionX = cloneDeep(endPosition);
|
|
55
|
+
let separatedPointsCheckAndAvoidBlocks = [];
|
|
56
|
+
let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(start.x ?? 0, start.y ?? 0, lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
|
|
57
|
+
if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
|
|
58
|
+
path = '';
|
|
59
|
+
endPath = {
|
|
60
|
+
x: start.x,
|
|
61
|
+
y: start.y
|
|
62
|
+
};
|
|
63
|
+
separatedPointsCheckAndAvoidBlocks = [];
|
|
64
|
+
}
|
|
65
|
+
separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
|
|
66
|
+
// sau khi đã đi ngang và tránh các khối, tiếp theo là đi tiếp hướng lên xuống để về khối cần nối tới, cần check xem điểm end X nó đang ở hướng nào
|
|
67
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
|
|
68
|
+
if (directionY === 'center') {
|
|
69
|
+
const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
|
|
70
|
+
separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
|
|
71
|
+
return {
|
|
72
|
+
dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
|
|
73
|
+
endPath: LEnd
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
let lineCurveSubY = lineCurve;
|
|
77
|
+
if (Math.abs((endPath.y ?? 0) - endPosition.y) < lineCurve * 2) {
|
|
78
|
+
lineCurveSubY = Math.abs((endPath.y ?? 0) - endPosition.y) / 2;
|
|
79
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
80
|
+
const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
|
|
81
|
+
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-right`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường thẳng sang ngang
|
|
82
|
+
const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`;
|
|
83
|
+
separatedPoints.push({ start: endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
|
|
84
|
+
separatedPoints.push({ start: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'vertical-single-curve', id: 'j' });
|
|
85
|
+
const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
86
|
+
return {
|
|
87
|
+
dPath: `${path} ${pathQ1} ${pathQ2} ${lineClose}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
91
|
+
const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
|
|
92
|
+
const endPositionY = cloneDeep(endPosition);
|
|
93
|
+
endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve);
|
|
94
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, separatedPoints);
|
|
95
|
+
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-right`, lineCurve, lineCurve); // tính đoạn cong từ đường thẳng sang ngang
|
|
96
|
+
const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`; // từ ngang sang thẳng phải có đường cong
|
|
97
|
+
separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
|
|
98
|
+
separatedPoints.push({ start: { x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'vertical-single-curve', id: 'j' });
|
|
99
|
+
const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
100
|
+
return {
|
|
101
|
+
dPath: `${path} ${pathQ1} ${straightLine.path} ${pathQ2} ${lineClose}`,
|
|
102
|
+
endPath: straightLine.endPath
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
static lineConnectLeft(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
|
|
106
|
+
const endPositionOrigin = {
|
|
107
|
+
x: (elementNext.x ?? 0) - (lineCurve * 1.5),
|
|
108
|
+
y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2
|
|
109
|
+
};
|
|
110
|
+
const endPosition = cloneDeep(endPositionOrigin);
|
|
111
|
+
const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
|
|
112
|
+
const endY = (directionStartY === 'under' || directionStartY === 'center') ? (elementNext.y ?? 0) : (elementNext.y ?? 0) + (elementNext.height ?? 0);
|
|
113
|
+
endPosition.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, endY, (lineCurve * 2));
|
|
114
|
+
const pathQ = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: (start.x ?? 0) + 10, y: start.y ?? 0 }, `right-${directionStartY === 'under' ? 'under' : 'above'}`, lineCurve, lineCurve);
|
|
115
|
+
const startQL = { lx: pathQ.x, ly: MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, (pathQ.y ?? 0), ((elementFrom.height ?? 0) / 2), true) };
|
|
116
|
+
separatedPoints.push({ start: { x: (start.x ?? 0), y: start.y ?? 0 }, end: { x: pathQ.x ?? 0, y: pathQ.y ?? 0 }, mode: 'horizontal-single-curve', id: '1' });
|
|
117
|
+
separatedPoints.push({ start: { x: pathQ.x ?? 0, y: pathQ.y ?? 0 }, end: { x: startQL.lx ?? 0, y: startQL.ly }, mode: 'horizontal', id: '2' });
|
|
118
|
+
if (directionStartY === 'center') {
|
|
119
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: startQL.lx ?? 0, y: startQL.ly ?? 0 }, `above-left`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
120
|
+
separatedPoints.push({ start: { x: startQL.lx ?? 0, y: startQL.ly }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '3' });
|
|
121
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
122
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
123
|
+
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `left-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
124
|
+
separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '4' });
|
|
125
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
126
|
+
return {
|
|
127
|
+
dPath: ``,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startQL.lx ?? 0, startQL.ly ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
|
|
131
|
+
if (Math.abs((endPosition.x ?? 0) - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
132
|
+
endPosition.x = straightLine.endPath.x;
|
|
133
|
+
}
|
|
134
|
+
if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
|
|
135
|
+
let condition = true;
|
|
136
|
+
while (condition) {
|
|
137
|
+
const checkAndAvoidBlocksYLeft = separatedPoints.findIndex(item => item.id === "checkAndAvoidBlocksYLeft");
|
|
138
|
+
if (checkAndAvoidBlocksYLeft !== -1) {
|
|
139
|
+
separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
|
|
140
|
+
}
|
|
141
|
+
if (checkAndAvoidBlocksYLeft === -1) {
|
|
142
|
+
condition = false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
straightLine.path = '';
|
|
146
|
+
straightLine.endPath = {
|
|
147
|
+
x: startQL.lx ?? 0,
|
|
148
|
+
y: startQL.ly ?? 0
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (endPosition.x === straightLine.endPath.x) {
|
|
152
|
+
separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
153
|
+
this.closeLine({ x: endPositionOrigin.x ?? 0, y: endPositionOrigin.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1,
|
|
157
|
+
const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
|
|
158
|
+
const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
|
|
159
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionStartY}-${directionNextX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
160
|
+
const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
|
|
161
|
+
if (elementBlockRoad && Math.abs((elementBlockRoadX) - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
162
|
+
coordQ1.x1 = straightLine.endPath.x ?? 0;
|
|
163
|
+
coordQ1.y1 = straightLine.endPath.y ?? 0;
|
|
164
|
+
coordQ1.x = straightLine.endPath.x ?? 0;
|
|
165
|
+
coordQ1.y = straightLine.endPath.y ?? 0;
|
|
166
|
+
}
|
|
167
|
+
separatedPoints.push({ start: straightLine.endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
168
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
169
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
170
|
+
const directionNextY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPath.x, 'x');
|
|
171
|
+
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `${directionNextY}-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
172
|
+
separatedPoints.push({ start: endPath, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '6' });
|
|
173
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
174
|
+
return {
|
|
175
|
+
dPath: ``,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
static closeLine(start, end, lineCurve, elementNext, separatedPoints) {
|
|
179
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, end.y, 'y');
|
|
180
|
+
if (start.y === end.y) {
|
|
181
|
+
separatedPoints.push({ start, end: { x: elementNext.x ?? 0, y: end.y ?? 0 }, mode: 'horizontal', id: '7' });
|
|
182
|
+
return `L ${elementNext.x} ${end.y}`;
|
|
183
|
+
}
|
|
184
|
+
const line = { x: start.x, y: start.y };
|
|
185
|
+
const endPoint = {
|
|
186
|
+
x: elementNext.x,
|
|
187
|
+
y: end.y
|
|
188
|
+
};
|
|
189
|
+
let pathQ1 = '';
|
|
190
|
+
if (Math.abs(start.y - end.y) > lineCurve) {
|
|
191
|
+
const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
|
|
192
|
+
line.y = toY;
|
|
193
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(line.x, elementNext.x, 'x');
|
|
194
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: line.x ?? 0, y: line.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-${directionX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
195
|
+
let lineL = '';
|
|
196
|
+
if (coordQ1.y === end.y) {
|
|
197
|
+
lineL = `L ${endPoint.x} ${endPoint.y}`;
|
|
198
|
+
}
|
|
199
|
+
pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y} ${lineL}`; // từ ngang sang thẳng phải có đường cong
|
|
200
|
+
}
|
|
201
|
+
separatedPoints.push({ start, end: line, mode: 'horizontal', id: '8' });
|
|
202
|
+
separatedPoints.push({ start: line, end: endPoint, mode: 'vertical-single-curve', id: '9' });
|
|
203
|
+
return `L ${line.x} ${line.y} ${pathQ1}`;
|
|
204
|
+
}
|
|
205
|
+
static lineConnectLeftWithBottomStart(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
|
|
206
|
+
const endPositionOrigin = {
|
|
207
|
+
x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
|
|
208
|
+
y: (elementNext.y ?? 0) - (lineCurve)
|
|
209
|
+
};
|
|
210
|
+
const endPosition = cloneDeep(endPositionOrigin);
|
|
211
|
+
const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
|
|
212
|
+
const endY = (elementNext.y ?? 0);
|
|
213
|
+
console.log('directionStartY', directionStartY);
|
|
214
|
+
if (directionStartY === 'under') {
|
|
215
|
+
endPosition.y = endY - (lineCurve * 3);
|
|
216
|
+
}
|
|
217
|
+
const startQL = { lx: start.x, ly: (start.y ?? 0) + lineCurve };
|
|
218
|
+
const line = {
|
|
219
|
+
start: { x: (start.x ?? 0), y: start.y ?? 0 },
|
|
220
|
+
end: { x: startQL.lx ?? 0, y: startQL.ly ?? 0 }
|
|
221
|
+
};
|
|
222
|
+
const newEnd = { x: elementFrom.x - (lineCurve * 2), y: line.end.y - lineCurve };
|
|
223
|
+
if (directionStartY === 'above') {
|
|
224
|
+
line.end = { x: (start.x ?? 0) - lineCurve, y: (start.y ?? 0) + (lineCurve * 2) };
|
|
225
|
+
separatedPoints.push({ start: line.end, end: newEnd, mode: 'horizontal-single-curve', id: '1' });
|
|
226
|
+
}
|
|
227
|
+
separatedPoints.push({ start: line.start, end: line.end, mode: 'vertical-single-curve', id: '1' }); // line vẽ đi khỏi khối đầu tiên
|
|
228
|
+
const startNewLine = directionStartY === 'above' ? newEnd : line.end;
|
|
229
|
+
if (directionStartY === 'center') {
|
|
230
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: startQL.lx ?? 0, y: startQL.ly ?? 0 }, `above-left`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
231
|
+
// từ ngang sang thẳng phải có đường cong
|
|
232
|
+
separatedPoints.push({ start: { x: startQL.lx ?? 0, y: startQL.ly }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '3' });
|
|
233
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
234
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
235
|
+
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `left-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
236
|
+
// từ ngang sang thẳng phải có đường cong
|
|
237
|
+
separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '4' });
|
|
238
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
239
|
+
return {
|
|
240
|
+
dPath: ``,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
// kiểm tra hướng thẳng đến end, nếu có khối thì tránh
|
|
244
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startNewLine.x ?? 0, startNewLine.y ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
|
|
245
|
+
const directionStartX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, endPositionOrigin.x, 'x');
|
|
246
|
+
if (directionStartX === 'center' && directionStartY === 'under') {
|
|
247
|
+
this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
248
|
+
return {
|
|
249
|
+
dPath: ``
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
|
|
253
|
+
let condition = true;
|
|
254
|
+
while (condition) {
|
|
255
|
+
const checkAndAvoidBlocksYLeft = separatedPoints.findIndex(item => item.id === "checkAndAvoidBlocksYLeft");
|
|
256
|
+
if (checkAndAvoidBlocksYLeft !== -1) {
|
|
257
|
+
separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
|
|
258
|
+
}
|
|
259
|
+
if (checkAndAvoidBlocksYLeft === -1) {
|
|
260
|
+
condition = false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
straightLine.path = '';
|
|
264
|
+
straightLine.endPath = {
|
|
265
|
+
x: startQL.lx ?? 0,
|
|
266
|
+
y: startQL.ly ?? 0
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1
|
|
270
|
+
const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
|
|
271
|
+
const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
|
|
272
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionStartY}-${directionNextX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
273
|
+
const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
|
|
274
|
+
if (elementBlockRoad && Math.abs((elementBlockRoadX) - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
275
|
+
coordQ1.x1 = straightLine.endPath.x ?? 0;
|
|
276
|
+
coordQ1.y1 = straightLine.endPath.y ?? 0;
|
|
277
|
+
coordQ1.x = straightLine.endPath.x ?? 0;
|
|
278
|
+
coordQ1.y = straightLine.endPath.y ?? 0;
|
|
279
|
+
}
|
|
280
|
+
// kiểm tra và vẽ hướng ngang
|
|
281
|
+
const directionXToEnd = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPositionOrigin.x, 'x');
|
|
282
|
+
endPosition.x = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionXToEnd, endPosition.x, lineCurve);
|
|
283
|
+
if (Math.abs((coordQ1.y ?? 0) - endPosition.y) <= lineCurve) {
|
|
284
|
+
endPosition.y -= lineCurve;
|
|
285
|
+
}
|
|
286
|
+
const pathHorizontal = [];
|
|
287
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, pathHorizontal);
|
|
288
|
+
if (directionXToEnd === 'left' && endPath.x > (coordQ1.x ?? 0)) {
|
|
289
|
+
separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical', id: '6a ' + directionStartY });
|
|
290
|
+
this.closeLineWithLineTopBottom(endPositionOrigin, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
separatedPoints.push(...pathHorizontal);
|
|
294
|
+
separatedPoints.push({ start: straightLine.endPath, end: { x: (coordQ1.x ?? 0 - 10), y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
295
|
+
this.closeLineWithLineTopBottom({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
296
|
+
return {
|
|
297
|
+
dPath: ``,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
static closeLineWithLineTopBottom(start, end, lineCurve, elementNext, separatedPoints) {
|
|
301
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, end.x, 'x');
|
|
302
|
+
if (start.x === end.x) {
|
|
303
|
+
separatedPoints.push({ start, end: { x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2, y: elementNext.y ?? 0 }, mode: 'horizontal', id: '7' });
|
|
304
|
+
return `L ${elementNext.x} ${end.y}`;
|
|
305
|
+
}
|
|
306
|
+
const line = { x: start.x, y: start.y };
|
|
307
|
+
const endPoint = {
|
|
308
|
+
x: end.x,
|
|
309
|
+
y: elementNext.y
|
|
310
|
+
};
|
|
311
|
+
const pathQ1 = '';
|
|
312
|
+
if (Math.abs(start.x - end.x) > lineCurve) {
|
|
313
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPoint.y, 'y');
|
|
314
|
+
const toX = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionX, end.x, lineCurve);
|
|
315
|
+
const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
|
|
316
|
+
line.x = toX;
|
|
317
|
+
line.y = toY;
|
|
318
|
+
separatedPoints.push({ start: start, end: line, mode: 'vertical-single-curve', id: '9' });
|
|
319
|
+
}
|
|
320
|
+
separatedPoints.push({ start: line, end: endPoint, mode: 'horizontal-single-curve', id: '9' });
|
|
321
|
+
return `L ${line.x} ${line.y} ${pathQ1}`;
|
|
322
|
+
}
|
|
323
|
+
static lineConnectRightWithBottomStart(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
|
|
324
|
+
const endPosition = {
|
|
325
|
+
x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
|
|
326
|
+
y: (elementNext.y ?? 0) - (lineCurve)
|
|
327
|
+
};
|
|
328
|
+
// vẽ 1 đường thẳng từ điểm start ra ngoài đã
|
|
329
|
+
const end = { x: (start.x ?? 0) + 10, y: (start.y ?? 0) + 20 };
|
|
330
|
+
separatedPoints.push({ start: { x: (start.x ?? 0), y: start.y ?? 0 }, end: end, mode: 'vertical-single-curve', id: '1' });
|
|
331
|
+
const endPositionX = cloneDeep(endPosition);
|
|
332
|
+
endPositionX.x -= 10;
|
|
333
|
+
let separatedPointsCheckAndAvoidBlocks = [];
|
|
334
|
+
let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(end.x ?? 0, (end.y ?? 0), lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
|
|
335
|
+
if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
|
|
336
|
+
path = '';
|
|
337
|
+
endPath = {
|
|
338
|
+
x: start.x,
|
|
339
|
+
y: start.y
|
|
340
|
+
};
|
|
341
|
+
separatedPointsCheckAndAvoidBlocks = [];
|
|
342
|
+
}
|
|
343
|
+
separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
|
|
344
|
+
// sau khi đã đi ngang và tránh các khối, tiếp theo là đi tiếp hướng lên xuống để về khối cần nối tới, cần check xem điểm end X nó đang ở hướng nào
|
|
345
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
|
|
346
|
+
if (directionY === 'center') {
|
|
347
|
+
const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
|
|
348
|
+
separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
|
|
349
|
+
// đoạn này chưa oce
|
|
350
|
+
this.closeLineWithLineTopBottom(LEnd, endPosition, lineCurve, elementNext, separatedPoints);
|
|
351
|
+
return {
|
|
352
|
+
dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
|
|
353
|
+
endPath: LEnd
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
357
|
+
const endPositionY = cloneDeep(endPosition);
|
|
358
|
+
endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve) - 10;
|
|
359
|
+
// cần check khi đi thẳng lên có vướng khối nào không để tiến lên
|
|
360
|
+
const elementBlockRoadStraightLineY = MoCanvasCalculatorDirectionElementUtil.checkBlocksElementStraightY((endPath.x ?? 0) + 10, endPath.y ?? 0, endPositionY, obstacleRect);
|
|
361
|
+
if (elementBlockRoadStraightLineY) {
|
|
362
|
+
coordQ1.x = (elementBlockRoadStraightLineY.x ?? 0) + (elementBlockRoadStraightLineY.width ?? 0) + lineCurve;
|
|
363
|
+
}
|
|
364
|
+
separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y }, end: { x: coordQ1.x ?? 0, y: (coordQ1.y ?? 0) }, mode: 'horizontal-single-curve', id: 'g' });
|
|
365
|
+
let avoidBlocksYLine = [];
|
|
366
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, avoidBlocksYLine);
|
|
367
|
+
if (directionY === 'under' && (coordQ1.y ?? 0) > endPositionY.y) {
|
|
368
|
+
avoidBlocksYLine = [];
|
|
369
|
+
straightLine.endPath = { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 };
|
|
370
|
+
}
|
|
371
|
+
separatedPoints.push(...avoidBlocksYLine);
|
|
372
|
+
this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
373
|
+
return {
|
|
374
|
+
dPath: ``,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdC1uYXZpZ2F0aW9uLW5ldy1lbGVtZW50LnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvZHJhdy1saW5lL3NyYy91dGlsL2Nvbm5lY3QtbmF2aWdhdGlvbi1uZXctZWxlbWVudC51dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsc0NBQXNDLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUM3RixPQUFPLEVBQUUsOENBQThDLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUdsRyxNQUFNLE9BQU8sdUNBQXVDO0lBQ2xELE1BQU0sQ0FBQyxxQ0FBcUMsR0FBRyxFQUFFLENBQUM7SUFDbEQsTUFBTSxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUM7SUFFakMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFdBQWtCLEVBQUUsV0FBa0IsRUFBRSxZQUFxQixFQUFFLGVBQStCLEVBQUUsS0FBYTtRQUN2SSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFrQixFQUFFLFdBQWtCLEVBQUUsWUFBcUIsRUFBRSxlQUErQixFQUFFLEtBQWE7UUFDbEksSUFBSSxPQUFPLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUMvRixJQUFJLE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcs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Q0FBQyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUVyTCxNQUFNLE9BQU8sR0FBRyxzQ0FBc0MsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLFVBQVUsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsMkNBQTJDO1FBQzlQLE1BQU0sTUFBTSxHQUFHLEtBQUssT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMseUNBQXlDO1FBRW5ILGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzlKLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FB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QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gXCJAbGlicy11aS91dGlsc1wiO1xuaW1wb3J0IHsgSVBvaW50LCBJUG9pbnRzLCBJUmVjdCB9IGZyb20gXCIuLi9kcmF3LWxpbmUuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsIH0gZnJvbSBcIi4vY2FsY3VsYXRvci1icmFuY2gudXRpbFwiO1xuaW1wb3J0IHsgTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwgfSBmcm9tIFwiLi9jYWxjdWxhdG9yLWRpcmV0aW9uLWVsZW1lbnQudW50aWxcIjtcbmltcG9ydCB7IE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25Cb3R0b21MZWZ0RWxlbWVudFV0aWwgfSBmcm9tIFwiLi9saW5lLWNvbm5lY3QtYm90dG9tLWxlZnQudW50aWxcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJUG9zaXRpb25YWSB7IHg6IG51bWJlciwgeTogbnVtYmVyIH1cbmV4cG9ydCBjbGFzcyBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwge1xuICBzdGF0aWMgRUxFTUVOVF9NQVJHSU5fQkVUV0VFTl9CUkFOQ0hfREVGQVVMVCA9IDMyO1xuICBzdGF0aWMgU1RBUlRfTU9ERSA9ICdyaWdodC1sZWZ0JztcblxuICBzdGF0aWMgc2V0WFlDb25uZWN0RWxlbWVudHMoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIHRoaXMuZHJhd0xpbmVDb25uZWN0KGVsZW1lbnRGcm9tLCBlbGVtZW50TmV4dCwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMsIGN1cnZlKTtcbiAgfVxuXG4gIHN0YXRpYyBkcmF3TGluZUNvbm5lY3QoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIGxldCBzdGFydF94ID0gKGVsZW1lbnRGcm9tLnggPz8gMCkgKyAoZWxlbWVudEZyb20ud2lkdGggPz8gMCk7IC8vIMSRaeG7g20gb3V0IGx1w7RuIOG7nyBwaMOtYSBiw6puIHBo4bqjaVxuICAgIGxldCBzdGFydF95ID0gKGVsZW1lbnRGcm9tLnkgPz8gMCkgKyAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApIC8gMjsgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gcGjhuqNpXG5cbiAgICBpZiAoTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLlNUQVJUX01PREUgPT09ICdib3R0b20tdG9wJykgeyAvLyDEkWnhu4NtIG91dCBsdcO0biDhu58gcGjDrWEgYsOqbiBkxrDhu5tpXG4gICAgICBzdGFydF94ID0gKGVsZW1lbnRGcm9tLnggPz8gMCkgKyAoKGVsZW1lbnRGcm9tLndpZHRoID8/IDApIC8gMik7XG4gICAgICBzdGFydF95ID0gKGVsZW1lbnRGcm9tLnkgPz8gMCkgKyAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApO1xuICAgIH1cbiAgICBpZiAoTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLlNUQVJUX01PREUgPT09ICdib3R0b20tbGVmdCcpIHsgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gZMaw4bubaVxuICAgICAgc3RhcnRfeCA9IChlbGVtZW50RnJvbS54ID8/IDApICsgKChlbGVtZW50RnJvbS53aWR0aCA/PyAwKSAvIDIpO1xuICAgICAgc3RhcnRfeSA9IChlbGVtZW50RnJvbS55ID8/IDApICsgKGVsZW1lbnRGcm9tLmhlaWdodCA/PyAwKTtcbiAgICB9XG4gICAgY29uc3QgTV9zdGFydDogSVBvaW50ID0geyB4OiBzdGFydF94LCB5OiBzdGFydF95IH07XG5cbiAgICBjb25zdCBkaXJlY3Rpb25YID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnRfeCwgZWxlbWVudE5leHQueCwgJ3gnKTtcblxuICAgIHN3aXRjaCAoTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLlNUQVJUX01PREUpIHtcbiAgICAgIGNhc2UgJ3JpZ2h0LWxlZnQnOlxuICAgICAgICBpZiAoZGlyZWN0aW9uWCA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgdGhpcy5saW5lQ29ubmVjdExlZnQoZWxlbWVudE5leHQsIGVsZW1lbnRGcm9tLCBNX3N0YXJ0LCBjdXJ2ZSwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGluZUNvbm5lY3RSaWdodChlbGVtZW50TmV4dCwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2JvdHRvbS10b3AnOlxuICAgICAgICBpZiAoZGlyZWN0aW9uWCA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgdGhpcy5saW5lQ29ubmVjdExlZnRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQsIGVsZW1lbnRGcm9tLCBNX3N0YXJ0LCBjdXJ2ZSwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGluZUNvbm5lY3RSaWdodFdpdGhCb3R0b21TdGFydChlbGVtZW50TmV4dCwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2JvdHRvbS1sZWZ0JzpcbiAgICAgICAgY29uc29sZS5sb2coZGlyZWN0aW9uWCk7XG4gICAgICAgIGlmIChkaXJlY3Rpb25YID09PSAnbGVmdCcpIHtcbiAgICAgICAgICBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uQm90dG9tTGVmdEVsZW1lbnRVdGlsLmxpbmVMZWZ0KGVsZW1lbnROZXh0LCBlbGVtZW50RnJvbSwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uQm90dG9tTGVmdEVsZW1lbnRVdGlsLnJpZ2h0TGVmdChlbGVtZW50TmV4dCwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbGluZUNvbm5lY3RSaWdodChlbGVtZW50TmV4dDogSVJlY3QsIHN0YXJ0OiBJUG9pbnQsIGxpbmVDdXJ2ZTogbnVtYmVyLCBvYnN0YWNsZVJlY3Q6IElSZWN0W10sIHNlcGFyYXRlZFBvaW50czogQXJyYXk8SVBvaW50cz4pIHtcbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IHtcbiAgICAgIHg6IChlbGVtZW50TmV4dC54ID8/IDApIC0gKGxpbmVDdXJ2ZSAqIDMpLFxuICAgICAgeTogKGVsZW1lbnROZXh0LnkgPz8gMCkgKyAoZWxlbWVudE5leHQuaGVpZ2h0ID8/IDApIC8gMlxuICAgIH07XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgbGV0IHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3M6IEFycmF5PElQb2ludHM+ID0gW107XG4gICAgbGV0IHsgcGF0aCwgZW5kUGF0aCB9ID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2NrcyhzdGFydC54ID8/IDAsIHN0YXJ0LnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblgsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKHN0YXJ0LnggPz8gMCkgLSBlbmRQb3NpdGlvbi54KSA8IDEwKSB7XG4gICAgICBwYXRoID0gJyc7XG4gICAgICBlbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydC54LFxuICAgICAgICB5OiBzdGFydC55XG4gICAgICB9O1xuXG4gICAgICBzZXBhcmF0ZWRQb2ludHNDaGVja0FuZEF2b2lkQmxvY2tzID0gW107XG4gICAgfVxuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnNwbGljZShzZXBhcmF0ZWRQb2ludHMubGVuZ3RoLCAwLCAuLi5zZXBhcmF0ZWRQb2ludHNDaGVja0FuZEF2b2lkQmxvY2tzKTtcblxuICAgIC8vIHNhdSBraGkgxJHDoyDEkWkgbmdhbmcgdsOgIHRyw6FuaCBjw6FjIGto4buRaSwgdGnhur9wIHRoZW8gbMOgIMSRaSB0aeG6v3AgaMaw4bubbmcgbMOqbiB4deG7kW5nIMSR4buDIHbhu4Ega2jhu5FpIGPhuqduIG7hu5FpIHThu5tpLCBj4bqnbiBjaGVjayB4ZW0gxJFp4buDbSBlbmQgWCBuw7MgxJFhbmcg4bufIGjGsOG7m25nIG7DoG9cbiAgICBjb25zdCBkaXJlY3Rpb25ZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoZW5kUGF0aC55LCBlbmRQb3NpdGlvbi55LCAneScpO1xuXG4gICAgaWYgKGRpcmVjdGlvblkgPT09ICdjZW50ZXInKSB7XG4gICAgICBjb25zdCBMRW5kID0geyB4OiBlbGVtZW50TmV4dC54ID8/IDAsIHk6IGVuZFBhdGgueSB9O1xuXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBlbmRQYXRoLCBlbmQ6IExFbmQsIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICdmJyB9KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGAke3BhdGh9IEwgJHtMRW5kLnh9ICR7TEVuZC55fWAsXG4gICAgICAgIGVuZFBhdGg6IExFbmRcbiAgICAgIH07XG4gICAgfVxuXG4gICAgbGV0IGxpbmVDdXJ2ZVN1YlkgPSBsaW5lQ3VydmU7XG5cbiAgICBpZiAoTWF0aC5hYnMoKGVuZFBhdGgueSA/PyAwKSAtIGVuZFBvc2l0aW9uLnkpIDwgbGluZUN1cnZlICogMikge1xuICAgICAgbGluZUN1cnZlU3ViWSA9IE1hdGguYWJzKChlbmRQYXRoLnkgPz8gMCkgLSBlbmRQb3NpdGlvbi55KSAvIDI7XG5cbiAgICAgIGNvbnN0IGNvb3JkUTEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBlbmRQYXRoLnggPz8gMCwgeTogZW5kUGF0aC55ID8/IDAgfSwgYHJpZ2h0LSR7ZGlyZWN0aW9uWSA9PT0gJ2Fib3ZlJyA/ICdhYm92ZScgOiAndW5kZXInfWAsIGxpbmVDdXJ2ZVN1YlkgKiAyLCBsaW5lQ3VydmVTdWJZKTsgLy8gdMOtbmggxJFv4bqhbiBjb25nIHThu6sgxJHGsOG7nW5nIG5nYW5nIHNhbmcgxJHGsOG7nW5nIHRo4bqzbmdcbiAgICAgIGNvbnN0IHBhdGhRMSA9IGBRICR7Y29vcmRRMS54MX0sJHtjb29yZFExLnkxfSAke2Nvb3JkUTEueH0sJHtjb29yZFExLnl9YDsgLy8gdOG7qyBuZ2FuZyBzYW5nIHRo4bqzbmcgcGjhuqNpIGPDsyDEkcaw4budbmcgY29uZ1xuICAgICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9LXJpZ2h0YCwgbGluZUN1cnZlU3ViWSAqIDIsIGxpbmVDdXJ2ZVN1YlkpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgdGjhurNuZyBzYW5nIG5nYW5nXG4gICAgICBjb25zdCBwYXRoUTIgPSBgUSAke2Nvb3JkUTIueDF9LCR7Y29vcmRRMi55MX0gJHtjb29yZFEyLnh9LCR7Y29vcmRRMi55fWA7XG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGVuZFBhdGgsIGVuZDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwtc2luZ2xlLWN1cnZlJywgaWQ6ICdnJyB9KTtcbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIGVuZDogeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnaicgfSk7XG4gICAgICBjb25zdCBsaW5lQ2xvc2UgPSB0aGlzLmNsb3NlTGluZSh7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBlbmRQb3NpdGlvbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGAke3BhdGh9ICR7cGF0aFExfSAke3BhdGhRMn0gJHtsaW5lQ2xvc2V9YCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgY29uc3QgcGF0aFExID0gYFEgJHtjb29yZFExLngxfSwke2Nvb3JkUTEueTF9ICR7Y29vcmRRMS54fSwke2Nvb3JkUTEueX1gOyAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgY29uc3QgZW5kUG9zaXRpb25ZID0gY2xvbmVEZWVwKGVuZFBvc2l0aW9uKTtcblxuICAgIGVuZFBvc2l0aW9uWS55ID0gTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uWSwgZW5kUG9zaXRpb24ueSwgbGluZUN1cnZlKTtcblxuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZKGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblksIGRpcmVjdGlvblksIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIGNvbnN0IGNvb3JkUTIgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIHk6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9LXJpZ2h0YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgdGjhurNuZyBzYW5nIG5nYW5nXG4gICAgY29uc3QgcGF0aFEyID0gYFEgJHtjb29yZFEyLngxfSwke2Nvb3JkUTIueTF9ICR7Y29vcmRRMi54fSwke2Nvb3JkUTIueX1gOyAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2cnIH0pO1xuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwLCB5OiBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDAgfSwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICdqJyB9KTtcbiAgICBjb25zdCBsaW5lQ2xvc2UgPSB0aGlzLmNsb3NlTGluZSh7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBlbmRQb3NpdGlvbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkUGF0aDogYCR7cGF0aH0gJHtwYXRoUTF9ICR7c3RyYWlnaHRMaW5lLnBhdGh9ICR7cGF0aFEyfSAke2xpbmVDbG9zZX1gLFxuICAgICAgZW5kUGF0aDogc3RyYWlnaHRMaW5lLmVuZFBhdGhcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbGluZUNvbm5lY3RMZWZ0KGVsZW1lbnROZXh0OiBJUmVjdCwgZWxlbWVudEZyb206IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb25PcmlnaW4gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSAtIChsaW5lQ3VydmUgKiAxLjUpLFxuICAgICAgeTogKGVsZW1lbnROZXh0LnkgPz8gMCkgKyAoZWxlbWVudE5leHQuaGVpZ2h0ID8/IDApIC8gMlxuICAgIH07XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IGNsb25lRGVlcChlbmRQb3NpdGlvbk9yaWdpbik7XG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnQueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcblxuICAgIGNvbnN0IGVuZFkgPSAoZGlyZWN0aW9uU3RhcnRZID09PSAndW5kZXInIHx8IGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2NlbnRlcicpID8gKGVsZW1lbnROZXh0LnkgPz8gMCkgOiAoZWxlbWVudE5leHQueSA/PyAwKSArIChlbGVtZW50TmV4dC5oZWlnaHQgPz8gMCk7XG5cbiAgICBlbmRQb3NpdGlvbi55ID0gTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uU3RhcnRZLCBlbmRZLCAobGluZUN1cnZlICogMikpO1xuXG4gICAgY29uc3QgcGF0aFEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiAoc3RhcnQueCA/PyAwKSArIDEwLCB5OiBzdGFydC55ID8/IDAgfSwgYHJpZ2h0LSR7ZGlyZWN0aW9uU3RhcnRZID09PSAndW5kZXInID8gJ3VuZGVyJyA6ICdhYm92ZSd9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpO1xuICAgIGNvbnN0IHN0YXJ0UUwgPSB7IGx4OiBwYXRoUS54LCBseTogTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uU3RhcnRZLCAocGF0aFEueSA/PyAwKSwgKChlbGVtZW50RnJvbS5oZWlnaHQgPz8gMCkgLyAyKSwgdHJ1ZSkgfTtcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogKHN0YXJ0LnggPz8gMCksIHk6IHN0YXJ0LnkgPz8gMCB9LCBlbmQ6IHsgeDogcGF0aFEueCA/PyAwLCB5OiBwYXRoUS55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwtc2luZ2xlLWN1cnZlJywgaWQ6ICcxJyB9KTtcbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IHBhdGhRLnggPz8gMCwgeTogcGF0aFEueSA/PyAwIH0sIGVuZDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgfSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzInIH0pO1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIGNvbnN0IGNvb3JkUTEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgPz8gMCB9LCBgYWJvdmUtbGVmdGAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTsgLy8gdMOtbmggxJFv4bqhbiBjb25nIHThu6sgxJHGsOG7nW5nIG5nYW5nIHNhbmcgxJHGsOG7nW5nIHRo4bqzbmdcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICczJyB9KTtcblxuICAgICAgY29uc3QgZW5kUGF0aCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NMZWZ0KGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoZW5kUGF0aC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuXG4gICAgICBjb25zdCBjb29yZFEyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGBsZWZ0LSR7ZGlyZWN0aW9uU3RhcnRZMiA9PT0gJ2Fib3ZlJyA/ICdhYm92ZScgOiAndW5kZXInfWAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTsgLy8gdMOtbmggxJFv4bqhbiBjb25nIHThu6sgxJHGsOG7nW5nIG5nYW5nIHNhbmcgxJHGsOG7nW5nIHRo4bqzbmdcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBlbmRQYXRoLnggPz8gMCwgeTogZW5kUGF0aC55ID8/IDAgfSwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzQnIH0pO1xuICAgICAgdGhpcy5jbG9zZUxpbmUoeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRQYXRoOiBgYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyYWlnaHRMaW5lID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0KHN0YXJ0UUwubHggPz8gMCwgc3RhcnRRTC5seSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBkaXJlY3Rpb25TdGFydFksIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIGlmIChNYXRoLmFicygoZW5kUG9zaXRpb24ueCA/PyAwKSAtIChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDApKSA8PSBsaW5lQ3VydmUgKiAyKSB7XG4gICAgICBlbmRQb3NpdGlvbi54ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueDtcbiAgICB9XG5cbiAgICBpZiAoKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyAmJiBzdGFydFFMLmx5ID4gZW5kUG9zaXRpb24ueSkgfHwgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJyAmJiBzdGFydFFMLmx5IDwgZW5kUG9zaXRpb24ueSkgfHwgc3RhcnRRTC5seSA9PT0gZW5kUG9zaXRpb24ueSkge1xuICAgICAgbGV0IGNvbmRpdGlvbiA9IHRydWU7XG5cbiAgICAgIHdoaWxlIChjb25kaXRpb24pIHtcbiAgICAgICAgY29uc3QgY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID0gc2VwYXJhdGVkUG9pbnRzLmZpbmRJbmRleChpdGVtID0+IGl0ZW0uaWQgPT09IFwiY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0XCIpO1xuXG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgIT09IC0xKSB7XG4gICAgICAgICAgc2VwYXJhdGVkUG9pbnRzLnNwbGljZShjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgPT09IC0xKSB7XG4gICAgICAgICAgY29uZGl0aW9uID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RyYWlnaHRMaW5lLnBhdGggPSAnJztcbiAgICAgIHN0cmFpZ2h0TGluZS5lbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydFFMLmx4ID8/IDAsXG4gICAgICAgIHk6IHN0YXJ0UUwubHkgPz8gMFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoZW5kUG9zaXRpb24ueCA9PT0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueCkge1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogc3RyYWlnaHRMaW5lLmVuZFBhdGgsIGVuZDogZW5kUG9zaXRpb25PcmlnaW4sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzZhICcgKyBkaXJlY3Rpb25TdGFydFkgfSk7XG4gICAgICB0aGlzLmNsb3NlTGluZSh7IHg6IGVuZFBvc2l0aW9uT3JpZ2luLnggPz8gMCwgeTogZW5kUG9zaXRpb25PcmlnaW4ueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICAvLyBraeG7g20gdHJhIG5nYXkga2hpIGN1YSBjw7Mgdsaw4bubbmcgYWkga2jDtG5nIHLhu5NpIGjhurVuZyB24bq9IFExLFxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKChlbGVtZW50QmxvY2tSb2FkWCkgLSAoc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwKSkgPD0gbGluZUN1cnZlICogMikge1xuICAgICAgY29vcmRRMS54MSA9IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMDtcbiAgICAgIGNvb3JkUTEueTEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDA7XG4gICAgICBjb29yZFExLnggPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkgPSBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDA7XG4gICAgfVxuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogc3RyYWlnaHRMaW5lLmVuZFBhdGgsIGVuZDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcblxuICAgIGNvbnN0IGVuZFBhdGggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzTGVmdChjb29yZFExLnggPz8gMCwgY29vcmRRMS55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb24sIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcbiAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoZW5kUGF0aC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuICAgIGNvbnN0IGRpcmVjdGlvbk5leHRZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoY29vcmRRMS54ID8/IDAsIGVuZFBhdGgueCwgJ3gnKTtcbiAgICBjb25zdCBjb29yZFEyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvbk5leHRZfS0ke2RpcmVjdGlvblN0YXJ0WTIgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBlbmRQYXRoLCBlbmQ6IHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNicgfSk7XG5cbiAgICB0aGlzLmNsb3NlTGluZSh7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkUGF0aDogYGAsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNsb3NlTGluZShzdGFydDogSVBvc2l0aW9uWFksIGVuZDogSVBvc2l0aW9uWFksIGxpbmVDdXJ2ZTogbnVtYmVyLCBlbGVtZW50TmV4dDogSVJlY3QsIHNlcGFyYXRlZFBvaW50czogQXJyYXk8SVBvaW50cz4pIHtcbiAgICBjb25zdCBkaXJlY3Rpb25ZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnQueSwgZW5kLnksICd5Jyk7XG5cbiAgICBpZiAoc3RhcnQueSA9PT0gZW5kLnkpIHtcbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQsIGVuZDogeyB4OiBlbGVtZW50TmV4dC54ID8/IDAsIHk6IGVuZC55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzcnIH0pO1xuXG4gICAgICByZXR1cm4gYEwgJHtlbGVtZW50TmV4dC54fSAke2VuZC55fWA7XG4gICAgfVxuXG4gICAgY29uc3QgbGluZSA9IHsgeDogc3RhcnQueCwgeTogc3RhcnQueSB9O1xuICAgIGNvbnN0IGVuZFBvaW50ID0ge1xuICAgICAgeDogZWxlbWVudE5leHQueCxcbiAgICAgIHk6IGVuZC55XG4gICAgfTtcbiAgICBsZXQgcGF0aFExID0gJyc7XG5cbiAgICBpZiAoTWF0aC5hYnMoc3RhcnQueSAtIGVuZC55KSA+IGxpbmVDdXJ2ZSkge1xuICAgICAgY29uc3QgdG9ZID0gTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uWSwgZW5kLnksIGxpbmVDdXJ2ZSk7XG5cbiAgICAgIGxpbmUueSA9IHRvWTtcblxuICAgICAgY29uc3QgZGlyZWN0aW9uWCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGxpbmUueCwgZWxlbWVudE5leHQueCwgJ3gnKTtcbiAgICAgIGNvbnN0IGNvb3JkUTEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBsaW5lLnggPz8gMCwgeTogbGluZS55ID8/IDAgfSwgYCR7ZGlyZWN0aW9uWSA9PT0gJ2Fib3ZlJyA/ICdhYm92ZScgOiAndW5kZXInfS0ke2RpcmVjdGlvblh9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgICBsZXQgbGluZUwgPSAnJztcblxuICAgICAgaWYgKGNvb3JkUTEueSA9PT0gZW5kLnkpIHtcbiAgICAgICAgbGluZUwgPSBgTCAke2VuZFBvaW50Lnh9ICR7ZW5kUG9pbnQueX1gO1xuICAgICAgfVxuXG4gICAgICBwYXRoUTEgPSBgUSAke2Nvb3JkUTEueDF9LCR7Y29vcmRRMS55MX0gJHtjb29yZFExLnh9LCR7Y29vcmRRMS55fSAke2xpbmVMfWA7IC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0LCBlbmQ6IGxpbmUsIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICc4JyB9KTtcbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLCBlbmQ6IGVuZFBvaW50LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc5JyB9KTtcblxuICAgIHJldHVybiBgTCAke2xpbmUueH0gJHtsaW5lLnl9ICR7cGF0aFExfWA7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBsaW5lQ29ubmVjdExlZnRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQ6IElSZWN0LCBlbGVtZW50RnJvbTogSVJlY3QsIHN0YXJ0OiBJUG9pbnQsIGxpbmVDdXJ2ZTogbnVtYmVyLCBvYnN0YWNsZVJlY3Q6IElSZWN0W10sIHNlcGFyYXRlZFBvaW50czogQXJyYXk8SVBvaW50cz4pIHtcbiAgICBjb25zdCBlbmRQb3NpdGlvbk9yaWdpbiA9IHtcbiAgICAgIHg6IChlbGVtZW50TmV4dC54ID8/IDApICsgKGVsZW1lbnROZXh0LndpZHRoID8/IDApIC8gMixcbiAgICAgIHk6IChlbGVtZW50TmV4dC55ID8/IDApIC0gKGxpbmVDdXJ2ZSlcbiAgICB9O1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gY2xvbmVEZWVwKGVuZFBvc2l0aW9uT3JpZ2luKTtcbiAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdGFydC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuICAgIGNvbnN0IGVuZFkgPSAoZWxlbWVudE5leHQueSA/PyAwKTtcblxuICAgIGNvbnNvbGUubG9nKCdkaXJlY3Rpb25TdGFydFknLCBkaXJlY3Rpb25TdGFydFkpO1xuICAgIGlmIChkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicpIHtcbiAgICAgIGVuZFBvc2l0aW9uLnkgPSBlbmRZIC0gKGxpbmVDdXJ2ZSAqIDMpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UUwgPSB7IGx4OiBzdGFydC54LCBseTogKHN0YXJ0LnkgPz8gMCkgKyBsaW5lQ3VydmUgfTtcbiAgICBjb25zdCBsaW5lID0ge1xuICAgICAgc3RhcnQ6IHsgeDogKHN0YXJ0LnggPz8gMCksIHk6IHN0YXJ0LnkgPz8gMCB9LFxuICAgICAgZW5kOiB7IHg6IHN0YXJ0UUwubHggPz8gMCwgeTogc3RhcnRRTC5seSA/PyAwIH1cbiAgICB9O1xuICAgIGNvbnN0IG5ld0VuZCA9IHsgeDogZWxlbWVudEZyb20ueCAtIChsaW5lQ3VydmUgKiAyKSwgeTogbGluZS5lbmQueSAtIGxpbmVDdXJ2ZSB9O1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJykge1xuICAgICAgbGluZS5lbmQgPSB7IHg6IChzdGFydC54ID8/IDApIC0gbGluZUN1cnZlLCB5OiAoc3RhcnQueSA/PyAwKSArIChsaW5lQ3VydmUgKiAyKSB9O1xuXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLmVuZCwgZW5kOiBuZXdFbmQsIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG4gICAgfVxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGxpbmUuc3RhcnQsIGVuZDogbGluZS5lbmQsIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzEnIH0pOyAvLyBsaW5lIHbhur0gxJFpIGto4buPaSBraOG7kWkgxJHhuqd1IHRpw6puXG4gICAgY29uc3Qgc3RhcnROZXdMaW5lID0gZGlyZWN0aW9uU3RhcnRZID09PSAnYWJvdmUnID8gbmV3RW5kIDogbGluZS5lbmQ7XG5cbiAgICBpZiAoZGlyZWN0aW9uU3RhcnRZID09PSAnY2VudGVyJykge1xuICAgICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0YXJ0UUwubHggPz8gMCwgeTogc3RhcnRRTC5seSA/PyAwIH0sIGBhYm92ZS1sZWZ0YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgICAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IHN0YXJ0UUwubHggPz8gMCwgeTogc3RhcnRRTC5seSB9LCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzMnIH0pO1xuXG4gICAgICBjb25zdCBlbmRQYXRoID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc0xlZnQoY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoZW5kUGF0aC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuICAgICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgbGVmdC0ke2RpcmVjdGlvblN0YXJ0WTIgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGVuZDogeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc0JyB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYGAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIGtp4buDbSB0cmEgaMaw4bubbmcgdGjhurNuZyDEkeG6v24gZW5kLCBu4bq/dSBjw7Mga2jhu5FpIHRow6wgdHLDoW5oXG4gICAgY29uc3Qgc3RyYWlnaHRMaW5lID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0KHN0YXJ0TmV3TGluZS54ID8/IDAsIHN0YXJ0TmV3TGluZS55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb24sIGRpcmVjdGlvblN0YXJ0WSwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRYID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnQueCwgZW5kUG9zaXRpb25PcmlnaW4ueCwgJ3gnKTtcblxuICAgIGlmIChkaXJlY3Rpb25TdGFydFggPT09ICdjZW50ZXInICYmIGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJykge1xuICAgICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYGBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKChkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicgJiYgc3RhcnRRTC5seSA+IGVuZFBvc2l0aW9uLnkpIHx8IChkaXJlY3Rpb25TdGFydFkgPT09ICdhYm92ZScgJiYgc3RhcnRRTC5seSA8IGVuZFBvc2l0aW9uLnkpIHx8IHN0YXJ0UUwubHkgPT09IGVuZFBvc2l0aW9uLnkpIHtcbiAgICAgIGxldCBjb25kaXRpb24gPSB0cnVlO1xuXG4gICAgICB3aGlsZSAoY29uZGl0aW9uKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdCA9IHNlcGFyYXRlZFBvaW50cy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtLmlkID09PSBcImNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdFwiKTtcblxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ICE9PSAtMSkge1xuICAgICAgICAgIHNlcGFyYXRlZFBvaW50cy5zcGxpY2UoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0LCAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID09PSAtMSkge1xuICAgICAgICAgIGNvbmRpdGlvbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0cmFpZ2h0TGluZS5wYXRoID0gJyc7XG4gICAgICBzdHJhaWdodExpbmUuZW5kUGF0aCA9IHtcbiAgICAgICAgeDogc3RhcnRRTC5seCA/PyAwLFxuICAgICAgICB5OiBzdGFydFFMLmx5ID8/IDBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8ga2nhu4NtIHRyYSBuZ2F5IGtoaSBjdWEgY8OzIHbGsOG7m25nIGFpIGtow7RuZyBy4buTaSBo4bq1bmcgduG6vSBRMVxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKChlbGVtZW50QmxvY2tSb2FkWCkgLSAoc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwKSkgPD0gbGluZUN1cnZlICogMikge1xuICAgICAgY29vcmRRMS54MSA9IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMDtcbiAgICAgIGNvb3JkUTEueTEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDA7XG4gICAgICBjb29yZFExLnggPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkgPSBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDA7XG4gICAgfVxuXG4gICAgLy8ga2nhu4NtIHRyYSB2w6AgduG6vSBoxrDhu5tuZyBuZ2FuZ1xuICAgIGNvbnN0IGRpcmVjdGlvblhUb0VuZCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGNvb3JkUTEueCA/PyAwLCBlbmRQb3NpdGlvbk9yaWdpbi54LCAneCcpO1xuXG4gICAgZW5kUG9zaXRpb24ueCA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblhUb0VuZCwgZW5kUG9zaXRpb24ueCwgbGluZUN1cnZlKTtcbiAgICBpZiAoTWF0aC5hYnMoKGNvb3JkUTEueSA/PyAwKSAtIGVuZFBvc2l0aW9uLnkpIDw9IGxpbmVDdXJ2ZSkge1xuICAgICAgZW5kUG9zaXRpb24ueSAtPSBsaW5lQ3VydmU7XG4gICAgfVxuICAgIGNvbnN0IHBhdGhIb3Jpem9udGFsOiBJUG9pbnRzW10gPSBbXTtcbiAgICBjb25zdCBlbmRQYXRoID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc0xlZnQoY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBvYnN0YWNsZVJlY3QsIHBhdGhIb3Jpem9udGFsKTtcblxuICAgIGlmIChkaXJlY3Rpb25YVG9FbmQgPT09ICdsZWZ0JyAmJiBlbmRQYXRoLnggPiAoY29vcmRRMS54ID8/IDApKSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdHJhaWdodExpbmUuZW5kUGF0aCwgZW5kOiBlbmRQb3NpdGlvbk9yaWdpbiwgbW9kZTogJ3ZlcnRpY2FsJywgaWQ6ICc2YSAnICsgZGlyZWN0aW9uU3RhcnRZIH0pO1xuICAgICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbShlbmRQb3NpdGlvbk9yaWdpbiwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCguLi5wYXRoSG9yaXpvbnRhbCk7XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogc3RyYWlnaHRMaW5lLmVuZFBhdGgsIGVuZDogeyB4OiAoY29vcmRRMS54ID8/IDAgLSAxMCksIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzZhICcgKyBkaXJlY3Rpb25TdGFydFkgfSk7XG4gICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkUGF0aDogYGAsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKHN0YXJ0OiBJUG9zaXRpb25YWSwgZW5kOiBJUG9zaXRpb25YWSwgbGluZUN1cnZlOiBudW1iZXIsIGVsZW1lbnROZXh0OiBJUmVjdCwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPikge1xuICAgIGNvbnN0IGRpcmVjdGlvblggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdGFydC54LCBlbmQueCwgJ3gnKTtcblxuICAgIGlmIChzdGFydC54ID09PSBlbmQueCkge1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydCwgZW5kOiB7IHg6IChlbGVtZW50TmV4dC54ID8/IDApICsgKGVsZW1lbnROZXh0LndpZHRoID8/IDApIC8gMiwgeTogZWxlbWVudE5leHQueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICc3JyB9KTtcblxuICAgICAgcmV0dXJuIGBMICR7ZWxlbWVudE5leHQueH0gJHtlbmQueX1gO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbmUgPSB7IHg6IHN0YXJ0LngsIHk6IHN0YXJ0LnkgfTtcbiAgICBjb25zdCBlbmRQb2ludCA9IHtcbiAgICAgIHg6IGVuZC54LFxuICAgICAgeTogZWxlbWVudE5leHQueVxuICAgIH07XG4gICAgY29uc3QgcGF0aFExID0gJyc7XG5cbiAgICBpZiAoTWF0aC5hYnMoc3RhcnQueCAtIGVuZC54KSA+IGxpbmVDdXJ2ZSkge1xuICAgICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LnksIGVuZFBvaW50LnksICd5Jyk7XG4gICAgICBjb25zdCB0b1ggPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25YLCBlbmQueCwgbGluZUN1cnZlKTtcbiAgICAgIGNvbnN0IHRvWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZC55LCBsaW5lQ3VydmUpO1xuXG4gICAgICBsaW5lLnggPSB0b1g7XG4gICAgICBsaW5lLnkgPSB0b1k7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdGFydCwgZW5kOiBsaW5lLCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc5JyB9KTtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLCBlbmQ6IGVuZFBvaW50LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzknIH0pO1xuXG4gICAgcmV0dXJuIGBMICR7bGluZS54fSAke2xpbmUueX0gJHtwYXRoUTF9YDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0UmlnaHRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQ6IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb24gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSArIChlbGVtZW50TmV4dC53aWR0aCA/PyAwKSAvIDIsXG4gICAgICB5OiAoZWxlbWVudE5leHQueSA/PyAwKSAtIChsaW5lQ3VydmUpXG4gICAgfTtcblxuICAgIC8vIHbhur0gMSDEkcaw4budbmcgdGjhurNuZyB04burIMSRaeG7g20gc3RhcnQgcmEgbmdvw6BpIMSRw6NcbiAgICBjb25zdCBlbmQgPSB7IHg6IChzdGFydC54ID8/IDApICsgMTAsIHk6IChzdGFydC55ID8/IDApICsgMjAgfTtcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogKHN0YXJ0LnggPz8gMCksIHk6IHN0YXJ0LnkgPz8gMCB9LCBlbmQ6IGVuZCwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgZW5kUG9zaXRpb25YLnggLT0gMTA7XG5cbiAgICBsZXQgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2NrczogQXJyYXk8SVBvaW50cz4gPSBbXTtcbiAgICBsZXQgeyBwYXRoLCBlbmRQYXRoIH0gPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzKGVuZC54ID8/IDAsIChlbmQueSA/PyAwKSwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblgsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKHN0YXJ0LnggPz8gMCkgLSBlbmRQb3NpdGlvbi54KSA8IDEwKSB7XG4gICAgICBwYXRoID0gJyc7XG4gICAgICBlbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydC54LFxuICAgICAgICB5OiBzdGFydC55XG4gICAgICB9O1xuXG4gICAgICBzZXBhcmF0ZWRQb2ludHNDaGVja0FuZEF2b2lkQmxvY2tzID0gW107XG4gICAgfVxuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnNwbGljZShzZXBhcmF0ZWRQb2ludHMubGVuZ3RoLCAwLCAuLi5zZXBhcmF0ZWRQb2ludHNDaGVja0FuZEF2b2lkQmxvY2tzKTtcblxuICAgIC8vIHNhdSBraGkgxJHDoyDEkWkgbmdhbmcgdsOgIHRyw6FuaCBjw6FjIGto4buRaSwgdGnhur9wIHRoZW8gbMOgIMSRaSB0aeG6v3AgaMaw4bubbmcgbMOqbiB4deG7kW5nIMSR4buDIHbhu4Ega2jhu5FpIGPhuqduIG7hu5FpIHThu5tpLCBj4bqnbiBjaGVjayB4ZW0gxJFp4buDbSBlbmQgWCBuw7MgxJFhbmcg4bufIGjGsOG7m25nIG7DoG9cbiAgICBjb25zdCBkaXJlY3Rpb25ZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoZW5kUGF0aC55LCBlbmRQb3NpdGlvbi55LCAneScpO1xuXG4gICAgaWYgKGRpcmVjdGlvblkgPT09ICdjZW50ZXInKSB7XG4gICAgICBjb25zdCBMRW5kID0geyB4OiBlbGVtZW50TmV4dC54ID8/IDAsIHk6IGVuZFBhdGgueSB9O1xuXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBlbmRQYXRoLCBlbmQ6IExFbmQsIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICdmJyB9KTtcblxuICAgICAgLy8gxJFv4bqhbiBuw6B5IGNoxrBhIG9jZVxuICAgICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbShMRW5kLCBlbmRQb3NpdGlvbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGAke3BhdGh9IEwgJHtMRW5kLnh9ICR7TEVuZC55fWAsXG4gICAgICAgIGVuZFBhdGg6IExFbmRcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uWSA9IGNsb25lRGVlcChlbmRQb3NpdGlvbik7XG5cbiAgICBlbmRQb3NpdGlvblkueSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZFBvc2l0aW9uLnksIGxpbmVDdXJ2ZSkgLSAxMDtcblxuICAgIC8vIGPhuqduIGNoZWNrIGtoaSDEkWkgdGjhurNuZyBsw6puIGPDsyB2xrDhu5tuZyBraOG7kWkgbsOgbyBraMO0bmcgxJHhu4MgdGnhur9uIGzDqm5cbiAgICBjb25zdCBlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQmxvY2tzRWxlbWVudFN0cmFpZ2h0WSgoZW5kUGF0aC54ID8/IDApICsgMTAsIGVuZFBhdGgueSA/PyAwLCBlbmRQb3NpdGlvblksIG9ic3RhY2xlUmVjdCk7XG5cbiAgICBpZiAoZWxlbWVudEJsb2NrUm9hZFN0cmFpZ2h0TGluZVkpIHtcbiAgICAgIGNvb3JkUTEueCA9IChlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWS54ID8/IDApICsgKGVsZW1lbnRCbG9ja1JvYWRTdHJhaWdodExpbmVZLndpZHRoID8/IDApICsgbGluZUN1cnZlO1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiAoY29vcmRRMS55ID8/IDApIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnZycgfSk7XG5cbiAgICBsZXQgYXZvaWRCbG9ja3NZTGluZTogSVBvaW50c1tdID0gW107XG4gICAgY29uc3Qgc3RyYWlnaHRMaW5lID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc1koY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uWSwgZGlyZWN0aW9uWSwgb2JzdGFjbGVSZWN0LCBhdm9pZEJsb2Nrc1lMaW5lKTtcblxuICAgIGlmIChkaXJlY3Rpb25ZID09PSAndW5kZXInICYmIChjb29yZFExLnkgPz8gMCkgPiBlbmRQb3NpdGlvblkueSkge1xuICAgICAgYXZvaWRCbG9ja3NZTGluZSA9IFtdO1xuICAgICAgc3RyYWlnaHRMaW5lLmVuZFBhdGggPSB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9O1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCguLi5hdm9pZEJsb2Nrc1lMaW5lKTtcbiAgICB0aGlzLmNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKHsgeDogc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwLCB5OiBzdHJhaWdodExpbmUuZW5kUGF0aC55ID8/IDAgfSwgZW5kUG9zaXRpb24sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZFBhdGg6IGBgLFxuICAgIH07XG4gIH1cbn0iXX0=
|