@libs-ui/components-draw-line 0.1.1-1
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 +57 -0
- package/draw-line.interface.d.ts +119 -0
- package/esm2022/draw-line.directive.mjs +672 -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 +380 -0
- package/esm2022/util/line-connect-bottom-left.until.mjs +147 -0
- package/fesm2022/libs-ui-components-draw-line.mjs +1571 -0
- package/fesm2022/libs-ui-components-draw-line.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/package.json +26 -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,380 @@
|
|
|
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') {
|
|
15
|
+
// điểm out luôn ở phía bên dưới
|
|
16
|
+
start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0) / 2;
|
|
17
|
+
start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
|
|
18
|
+
}
|
|
19
|
+
if (MoCanvasConnectNavigationNewElementUtil.START_MODE === 'bottom-left') {
|
|
20
|
+
// điểm out luôn ở phía bên dưới
|
|
21
|
+
start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0) / 2;
|
|
22
|
+
start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
|
|
23
|
+
}
|
|
24
|
+
const M_start = { x: start_x, y: start_y };
|
|
25
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start_x, elementNext.x, 'x');
|
|
26
|
+
switch (MoCanvasConnectNavigationNewElementUtil.START_MODE) {
|
|
27
|
+
case 'right-left':
|
|
28
|
+
if (directionX === 'left') {
|
|
29
|
+
this.lineConnectLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.lineConnectRight(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
33
|
+
break;
|
|
34
|
+
case 'bottom-top':
|
|
35
|
+
if (directionX === 'left') {
|
|
36
|
+
this.lineConnectLeftWithBottomStart(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.lineConnectRightWithBottomStart(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
40
|
+
break;
|
|
41
|
+
case 'bottom-left':
|
|
42
|
+
console.log(directionX);
|
|
43
|
+
if (directionX === 'left') {
|
|
44
|
+
MoCanvasConnectNavigationBottomLeftElementUtil.lineLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
MoCanvasConnectNavigationBottomLeftElementUtil.rightLeft(elementNext, M_start, curve, obstacleRect, separatedPoints);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
static lineConnectRight(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
|
|
52
|
+
const endPosition = {
|
|
53
|
+
x: (elementNext.x ?? 0) - lineCurve * 3,
|
|
54
|
+
y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2,
|
|
55
|
+
};
|
|
56
|
+
const endPositionX = cloneDeep(endPosition);
|
|
57
|
+
let separatedPointsCheckAndAvoidBlocks = [];
|
|
58
|
+
let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(start.x ?? 0, start.y ?? 0, lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
|
|
59
|
+
if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
|
|
60
|
+
path = '';
|
|
61
|
+
endPath = {
|
|
62
|
+
x: start.x,
|
|
63
|
+
y: start.y,
|
|
64
|
+
};
|
|
65
|
+
separatedPointsCheckAndAvoidBlocks = [];
|
|
66
|
+
}
|
|
67
|
+
separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
|
|
68
|
+
// 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
|
|
69
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
|
|
70
|
+
if (directionY === 'center') {
|
|
71
|
+
const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
|
|
72
|
+
separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
|
|
73
|
+
return {
|
|
74
|
+
dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
|
|
75
|
+
endPath: LEnd,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
let lineCurveSubY = lineCurve;
|
|
79
|
+
if (Math.abs((endPath.y ?? 0) - endPosition.y) < lineCurve * 2) {
|
|
80
|
+
lineCurveSubY = Math.abs((endPath.y ?? 0) - endPosition.y) / 2;
|
|
81
|
+
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
|
|
82
|
+
const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
|
|
83
|
+
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
|
|
84
|
+
const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`;
|
|
85
|
+
separatedPoints.push({ start: endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
|
|
86
|
+
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' });
|
|
87
|
+
const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
88
|
+
return {
|
|
89
|
+
dPath: `${path} ${pathQ1} ${pathQ2} ${lineClose}`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
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
|
|
93
|
+
const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
|
|
94
|
+
const endPositionY = cloneDeep(endPosition);
|
|
95
|
+
endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve);
|
|
96
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, separatedPoints);
|
|
97
|
+
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
|
|
98
|
+
const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`; // từ ngang sang thẳng phải có đường cong
|
|
99
|
+
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' });
|
|
100
|
+
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' });
|
|
101
|
+
const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
102
|
+
return {
|
|
103
|
+
dPath: `${path} ${pathQ1} ${straightLine.path} ${pathQ2} ${lineClose}`,
|
|
104
|
+
endPath: straightLine.endPath,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
static lineConnectLeft(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
|
|
108
|
+
const endPositionOrigin = {
|
|
109
|
+
x: (elementNext.x ?? 0) - lineCurve * 1.5,
|
|
110
|
+
y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2,
|
|
111
|
+
};
|
|
112
|
+
const endPosition = cloneDeep(endPositionOrigin);
|
|
113
|
+
const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
|
|
114
|
+
const endY = directionStartY === 'under' || directionStartY === 'center' ? (elementNext.y ?? 0) : (elementNext.y ?? 0) + (elementNext.height ?? 0);
|
|
115
|
+
endPosition.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, endY, lineCurve * 2);
|
|
116
|
+
const pathQ = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: (start.x ?? 0) + 10, y: start.y ?? 0 }, `right-${directionStartY === 'under' ? 'under' : 'above'}`, lineCurve, lineCurve);
|
|
117
|
+
const startQL = { lx: pathQ.x, ly: MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, pathQ.y ?? 0, (elementFrom.height ?? 0) / 2, true) };
|
|
118
|
+
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' });
|
|
119
|
+
separatedPoints.push({ start: { x: pathQ.x ?? 0, y: pathQ.y ?? 0 }, end: { x: startQL.lx ?? 0, y: startQL.ly }, mode: 'horizontal', id: '2' });
|
|
120
|
+
if (directionStartY === 'center') {
|
|
121
|
+
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
|
|
122
|
+
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' });
|
|
123
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
124
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
125
|
+
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
|
|
126
|
+
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' });
|
|
127
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
128
|
+
return {
|
|
129
|
+
dPath: ``,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startQL.lx ?? 0, startQL.ly ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
|
|
133
|
+
if (Math.abs((endPosition.x ?? 0) - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
134
|
+
endPosition.x = straightLine.endPath.x;
|
|
135
|
+
}
|
|
136
|
+
if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
|
|
137
|
+
let condition = true;
|
|
138
|
+
while (condition) {
|
|
139
|
+
const checkAndAvoidBlocksYLeft = separatedPoints.findIndex((item) => item.id === 'checkAndAvoidBlocksYLeft');
|
|
140
|
+
if (checkAndAvoidBlocksYLeft !== -1) {
|
|
141
|
+
separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
|
|
142
|
+
}
|
|
143
|
+
if (checkAndAvoidBlocksYLeft === -1) {
|
|
144
|
+
condition = false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
straightLine.path = '';
|
|
148
|
+
straightLine.endPath = {
|
|
149
|
+
x: startQL.lx ?? 0,
|
|
150
|
+
y: startQL.ly ?? 0,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (endPosition.x === straightLine.endPath.x) {
|
|
154
|
+
separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
155
|
+
this.closeLine({ x: endPositionOrigin.x ?? 0, y: endPositionOrigin.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1,
|
|
159
|
+
const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
|
|
160
|
+
const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
|
|
161
|
+
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
|
|
162
|
+
const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
|
|
163
|
+
if (elementBlockRoad && Math.abs(elementBlockRoadX - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
164
|
+
coordQ1.x1 = straightLine.endPath.x ?? 0;
|
|
165
|
+
coordQ1.y1 = straightLine.endPath.y ?? 0;
|
|
166
|
+
coordQ1.x = straightLine.endPath.x ?? 0;
|
|
167
|
+
coordQ1.y = straightLine.endPath.y ?? 0;
|
|
168
|
+
}
|
|
169
|
+
separatedPoints.push({ start: straightLine.endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
170
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
171
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
172
|
+
const directionNextY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPath.x, 'x');
|
|
173
|
+
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
|
|
174
|
+
separatedPoints.push({ start: endPath, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '6' });
|
|
175
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
176
|
+
return {
|
|
177
|
+
dPath: ``,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
static closeLine(start, end, lineCurve, elementNext, separatedPoints) {
|
|
181
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, end.y, 'y');
|
|
182
|
+
if (start.y === end.y) {
|
|
183
|
+
separatedPoints.push({ start, end: { x: elementNext.x ?? 0, y: end.y ?? 0 }, mode: 'horizontal', id: '7' });
|
|
184
|
+
return `L ${elementNext.x} ${end.y}`;
|
|
185
|
+
}
|
|
186
|
+
const line = { x: start.x, y: start.y };
|
|
187
|
+
const endPoint = {
|
|
188
|
+
x: elementNext.x,
|
|
189
|
+
y: end.y,
|
|
190
|
+
};
|
|
191
|
+
let pathQ1 = '';
|
|
192
|
+
if (Math.abs(start.y - end.y) > lineCurve) {
|
|
193
|
+
const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
|
|
194
|
+
line.y = toY;
|
|
195
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(line.x, elementNext.x, 'x');
|
|
196
|
+
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
|
|
197
|
+
let lineL = '';
|
|
198
|
+
if (coordQ1.y === end.y) {
|
|
199
|
+
lineL = `L ${endPoint.x} ${endPoint.y}`;
|
|
200
|
+
}
|
|
201
|
+
pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y} ${lineL}`; // từ ngang sang thẳng phải có đường cong
|
|
202
|
+
}
|
|
203
|
+
separatedPoints.push({ start, end: line, mode: 'horizontal', id: '8' });
|
|
204
|
+
separatedPoints.push({ start: line, end: endPoint, mode: 'vertical-single-curve', id: '9' });
|
|
205
|
+
return `L ${line.x} ${line.y} ${pathQ1}`;
|
|
206
|
+
}
|
|
207
|
+
static lineConnectLeftWithBottomStart(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
|
|
208
|
+
const endPositionOrigin = {
|
|
209
|
+
x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
|
|
210
|
+
y: (elementNext.y ?? 0) - lineCurve,
|
|
211
|
+
};
|
|
212
|
+
const endPosition = cloneDeep(endPositionOrigin);
|
|
213
|
+
const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
|
|
214
|
+
const endY = elementNext.y ?? 0;
|
|
215
|
+
console.log('directionStartY', directionStartY);
|
|
216
|
+
if (directionStartY === 'under') {
|
|
217
|
+
endPosition.y = endY - lineCurve * 3;
|
|
218
|
+
}
|
|
219
|
+
const startQL = { lx: start.x, ly: (start.y ?? 0) + lineCurve };
|
|
220
|
+
const line = {
|
|
221
|
+
start: { x: start.x ?? 0, y: start.y ?? 0 },
|
|
222
|
+
end: { x: startQL.lx ?? 0, y: startQL.ly ?? 0 },
|
|
223
|
+
};
|
|
224
|
+
const newEnd = { x: elementFrom.x - lineCurve * 2, y: line.end.y - lineCurve };
|
|
225
|
+
if (directionStartY === 'above') {
|
|
226
|
+
line.end = { x: (start.x ?? 0) - lineCurve, y: (start.y ?? 0) + lineCurve * 2 };
|
|
227
|
+
separatedPoints.push({ start: line.end, end: newEnd, mode: 'horizontal-single-curve', id: '1' });
|
|
228
|
+
}
|
|
229
|
+
separatedPoints.push({ start: line.start, end: line.end, mode: 'vertical-single-curve', id: '1' }); // line vẽ đi khỏi khối đầu tiên
|
|
230
|
+
const startNewLine = directionStartY === 'above' ? newEnd : line.end;
|
|
231
|
+
if (directionStartY === 'center') {
|
|
232
|
+
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
|
|
233
|
+
// từ ngang sang thẳng phải có đường cong
|
|
234
|
+
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' });
|
|
235
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
|
|
236
|
+
const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
|
|
237
|
+
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
|
|
238
|
+
// từ ngang sang thẳng phải có đường cong
|
|
239
|
+
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' });
|
|
240
|
+
this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
241
|
+
return {
|
|
242
|
+
dPath: ``,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// kiểm tra hướng thẳng đến end, nếu có khối thì tránh
|
|
246
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startNewLine.x ?? 0, startNewLine.y ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
|
|
247
|
+
const directionStartX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, endPositionOrigin.x, 'x');
|
|
248
|
+
if (directionStartX === 'center' && directionStartY === 'under') {
|
|
249
|
+
this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
250
|
+
return {
|
|
251
|
+
dPath: ``,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
|
|
255
|
+
let condition = true;
|
|
256
|
+
while (condition) {
|
|
257
|
+
const checkAndAvoidBlocksYLeft = separatedPoints.findIndex((item) => item.id === 'checkAndAvoidBlocksYLeft');
|
|
258
|
+
if (checkAndAvoidBlocksYLeft !== -1) {
|
|
259
|
+
separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
|
|
260
|
+
}
|
|
261
|
+
if (checkAndAvoidBlocksYLeft === -1) {
|
|
262
|
+
condition = false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
straightLine.path = '';
|
|
266
|
+
straightLine.endPath = {
|
|
267
|
+
x: startQL.lx ?? 0,
|
|
268
|
+
y: startQL.ly ?? 0,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
// kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1
|
|
272
|
+
const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
|
|
273
|
+
const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
|
|
274
|
+
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
|
|
275
|
+
const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
|
|
276
|
+
if (elementBlockRoad && Math.abs(elementBlockRoadX - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
|
|
277
|
+
coordQ1.x1 = straightLine.endPath.x ?? 0;
|
|
278
|
+
coordQ1.y1 = straightLine.endPath.y ?? 0;
|
|
279
|
+
coordQ1.x = straightLine.endPath.x ?? 0;
|
|
280
|
+
coordQ1.y = straightLine.endPath.y ?? 0;
|
|
281
|
+
}
|
|
282
|
+
// kiểm tra và vẽ hướng ngang
|
|
283
|
+
const directionXToEnd = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPositionOrigin.x, 'x');
|
|
284
|
+
endPosition.x = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionXToEnd, endPosition.x, lineCurve);
|
|
285
|
+
if (Math.abs((coordQ1.y ?? 0) - endPosition.y) <= lineCurve) {
|
|
286
|
+
endPosition.y -= lineCurve;
|
|
287
|
+
}
|
|
288
|
+
const pathHorizontal = [];
|
|
289
|
+
const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, pathHorizontal);
|
|
290
|
+
if (directionXToEnd === 'left' && endPath.x > (coordQ1.x ?? 0)) {
|
|
291
|
+
separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical', id: '6a ' + directionStartY });
|
|
292
|
+
this.closeLineWithLineTopBottom(endPositionOrigin, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
separatedPoints.push(...pathHorizontal);
|
|
296
|
+
separatedPoints.push({ start: straightLine.endPath, end: { x: coordQ1.x ?? 0 - 10, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
|
|
297
|
+
this.closeLineWithLineTopBottom({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
|
|
298
|
+
return {
|
|
299
|
+
dPath: ``,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
static closeLineWithLineTopBottom(start, end, lineCurve, elementNext, separatedPoints) {
|
|
303
|
+
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, end.x, 'x');
|
|
304
|
+
if (start.x === end.x) {
|
|
305
|
+
separatedPoints.push({ start, end: { x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2, y: elementNext.y ?? 0 }, mode: 'horizontal', id: '7' });
|
|
306
|
+
return `L ${elementNext.x} ${end.y}`;
|
|
307
|
+
}
|
|
308
|
+
const line = { x: start.x, y: start.y };
|
|
309
|
+
const endPoint = {
|
|
310
|
+
x: end.x,
|
|
311
|
+
y: elementNext.y,
|
|
312
|
+
};
|
|
313
|
+
const pathQ1 = '';
|
|
314
|
+
if (Math.abs(start.x - end.x) > lineCurve) {
|
|
315
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPoint.y, 'y');
|
|
316
|
+
const toX = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionX, end.x, lineCurve);
|
|
317
|
+
const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
|
|
318
|
+
line.x = toX;
|
|
319
|
+
line.y = toY;
|
|
320
|
+
separatedPoints.push({ start: start, end: line, mode: 'vertical-single-curve', id: '9' });
|
|
321
|
+
}
|
|
322
|
+
separatedPoints.push({ start: line, end: endPoint, mode: 'horizontal-single-curve', id: '9' });
|
|
323
|
+
return `L ${line.x} ${line.y} ${pathQ1}`;
|
|
324
|
+
}
|
|
325
|
+
static lineConnectRightWithBottomStart(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
|
|
326
|
+
const endPosition = {
|
|
327
|
+
x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
|
|
328
|
+
y: (elementNext.y ?? 0) - lineCurve,
|
|
329
|
+
};
|
|
330
|
+
// vẽ 1 đường thẳng từ điểm start ra ngoài đã
|
|
331
|
+
const end = { x: (start.x ?? 0) + 10, y: (start.y ?? 0) + 20 };
|
|
332
|
+
separatedPoints.push({ start: { x: start.x ?? 0, y: start.y ?? 0 }, end: end, mode: 'vertical-single-curve', id: '1' });
|
|
333
|
+
const endPositionX = cloneDeep(endPosition);
|
|
334
|
+
endPositionX.x -= 10;
|
|
335
|
+
let separatedPointsCheckAndAvoidBlocks = [];
|
|
336
|
+
let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(end.x ?? 0, end.y ?? 0, lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
|
|
337
|
+
if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
|
|
338
|
+
path = '';
|
|
339
|
+
endPath = {
|
|
340
|
+
x: start.x,
|
|
341
|
+
y: start.y,
|
|
342
|
+
};
|
|
343
|
+
separatedPointsCheckAndAvoidBlocks = [];
|
|
344
|
+
}
|
|
345
|
+
separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
|
|
346
|
+
// 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
|
|
347
|
+
const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
|
|
348
|
+
if (directionY === 'center') {
|
|
349
|
+
const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
|
|
350
|
+
separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
|
|
351
|
+
// đoạn này chưa oce
|
|
352
|
+
this.closeLineWithLineTopBottom(LEnd, endPosition, lineCurve, elementNext, separatedPoints);
|
|
353
|
+
return {
|
|
354
|
+
dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
|
|
355
|
+
endPath: LEnd,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
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
|
|
359
|
+
const endPositionY = cloneDeep(endPosition);
|
|
360
|
+
endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve) - 10;
|
|
361
|
+
// cần check khi đi thẳng lên có vướng khối nào không để tiến lên
|
|
362
|
+
const elementBlockRoadStraightLineY = MoCanvasCalculatorDirectionElementUtil.checkBlocksElementStraightY((endPath.x ?? 0) + 10, endPath.y ?? 0, endPositionY, obstacleRect);
|
|
363
|
+
if (elementBlockRoadStraightLineY) {
|
|
364
|
+
coordQ1.x = (elementBlockRoadStraightLineY.x ?? 0) + (elementBlockRoadStraightLineY.width ?? 0) + lineCurve;
|
|
365
|
+
}
|
|
366
|
+
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' });
|
|
367
|
+
let avoidBlocksYLine = [];
|
|
368
|
+
const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, avoidBlocksYLine);
|
|
369
|
+
if (directionY === 'under' && (coordQ1.y ?? 0) > endPositionY.y) {
|
|
370
|
+
avoidBlocksYLine = [];
|
|
371
|
+
straightLine.endPath = { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 };
|
|
372
|
+
}
|
|
373
|
+
separatedPoints.push(...avoidBlocksYLine);
|
|
374
|
+
this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
|
|
375
|
+
return {
|
|
376
|
+
dPath: ``,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdC1uYXZpZ2F0aW9uLW5ldy1lbGVtZW50LnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvZHJhdy1saW5lL3NyYy91dGlsL2Nvbm5lY3QtbmF2aWdhdGlvbi1uZXctZWxlbWVudC51dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsc0NBQXNDLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUM3RixPQUFPLEVBQUUsOENBQThDLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQU1sRyxNQUFNLE9BQU8sdUNBQXVDO0lBQ2xELE1BQU0sQ0FBQyxxQ0FBcUMsR0FBRyxFQUFFLENBQUM7SUFDbEQsTUFBTSxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUM7SUFFakMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFdBQWtCLEVBQUUsV0FBa0IsRUFBRSxZQUFxQixFQUFFLGVBQStCLEVBQUUsS0FBYTtRQUN2SSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFrQixFQUFFLFdBQWtCLEVBQUUsWUFBcUIsRUFBRSxlQUErQixFQUFFLEtBQWE7UUFDbEksSUFBSSxPQUFPLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUMvRixJQUFJLE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcs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UUFDckMsTUFBTSxZQUFZLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFdEwsSUFBSSxVQUFVLEtBQUssT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEUsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1lBQ3RCLFlBQVksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbEUsQ0FBQztRQUNELGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRTFKLE9BQU87WUFDTCxLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUM7SUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2xvbmVEZWVwIH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuaW1wb3J0IHsgSVBvaW50LCBJUG9pbnRzLCBJUmVjdCB9IGZyb20gJy4uL2RyYXctbGluZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbCB9IGZyb20gJy4vY2FsY3VsYXRvci1icmFuY2gudXRpbCc7XG5pbXBvcnQgeyBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbCB9IGZyb20gJy4vY2FsY3VsYXRvci1kaXJldGlvbi1lbGVtZW50LnVudGlsJztcbmltcG9ydCB7IE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25Cb3R0b21MZWZ0RWxlbWVudFV0aWwgfSBmcm9tICcuL2xpbmUtY29ubmVjdC1ib3R0b20tbGVmdC51bnRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBvc2l0aW9uWFkge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cbmV4cG9ydCBjbGFzcyBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwge1xuICBzdGF0aWMgRUxFTUVOVF9NQVJHSU5fQkVUV0VFTl9CUkFOQ0hfREVGQVVMVCA9IDMyO1xuICBzdGF0aWMgU1RBUlRfTU9ERSA9ICdyaWdodC1sZWZ0JztcblxuICBzdGF0aWMgc2V0WFlDb25uZWN0RWxlbWVudHMoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIHRoaXMuZHJhd0xpbmVDb25uZWN0KGVsZW1lbnRGcm9tLCBlbGVtZW50TmV4dCwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMsIGN1cnZlKTtcbiAgfVxuXG4gIHN0YXRpYyBkcmF3TGluZUNvbm5lY3QoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIGxldCBzdGFydF94ID0gKGVsZW1lbnRGcm9tLnggPz8gMCkgKyAoZWxlbWVudEZyb20ud2lkdGggPz8gMCk7IC8vIMSRaeG7g20gb3V0IGx1w7RuIOG7nyBwaMOtYSBiw6puIHBo4bqjaVxuICAgIGxldCBzdGFydF95ID0gKGVsZW1lbnRGcm9tLnkgPz8gMCkgKyAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApIC8gMjsgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gcGjhuqNpXG5cbiAgICBpZiAoTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLlNUQVJUX01PREUgPT09ICdib3R0b20tdG9wJykge1xuICAgICAgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gZMaw4bubaVxuICAgICAgc3RhcnRfeCA9IChlbGVtZW50RnJvbS54ID8/IDApICsgKGVsZW1lbnRGcm9tLndpZHRoID8/IDApIC8gMjtcbiAgICAgIHN0YXJ0X3kgPSAoZWxlbWVudEZyb20ueSA/PyAwKSArIChlbGVtZW50RnJvbS5oZWlnaHQgPz8gMCk7XG4gICAgfVxuICAgIGlmIChNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwuU1RBUlRfTU9ERSA9PT0gJ2JvdHRvbS1sZWZ0Jykge1xuICAgICAgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gZMaw4bubaVxuICAgICAgc3RhcnRfeCA9IChlbGVtZW50RnJvbS54ID8/IDApICsgKGVsZW1lbnRGcm9tLndpZHRoID8/IDApIC8gMjtcbiAgICAgIHN0YXJ0X3kgPSAoZWxlbWVudEZyb20ueSA/PyAwKSArIChlbGVtZW50RnJvbS5oZWlnaHQgPz8gMCk7XG4gICAgfVxuICAgIGNvbnN0IE1fc3RhcnQ6IElQb2ludCA9IHsgeDogc3RhcnRfeCwgeTogc3RhcnRfeSB9O1xuXG4gICAgY29uc3QgZGlyZWN0aW9uWCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0X3gsIGVsZW1lbnROZXh0LngsICd4Jyk7XG5cbiAgICBzd2l0Y2ggKE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbC5TVEFSVF9NT0RFKSB7XG4gICAgICBjYXNlICdyaWdodC1sZWZ0JzpcbiAgICAgICAgaWYgKGRpcmVjdGlvblggPT09ICdsZWZ0Jykge1xuICAgICAgICAgIHRoaXMubGluZUNvbm5lY3RMZWZ0KGVsZW1lbnROZXh0LCBlbGVtZW50RnJvbSwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpbmVDb25uZWN0UmlnaHQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdib3R0b20tdG9wJzpcbiAgICAgICAgaWYgKGRpcmVjdGlvblggPT09ICdsZWZ0Jykge1xuICAgICAgICAgIHRoaXMubGluZUNvbm5lY3RMZWZ0V2l0aEJvdHRvbVN0YXJ0KGVsZW1lbnROZXh0LCBlbGVtZW50RnJvbSwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpbmVDb25uZWN0UmlnaHRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgIGNvbnNvbGUubG9nKGRpcmVjdGlvblgpO1xuICAgICAgICBpZiAoZGlyZWN0aW9uWCA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbkJvdHRvbUxlZnRFbGVtZW50VXRpbC5saW5lTGVmdChlbGVtZW50TmV4dCwgZWxlbWVudEZyb20sIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbkJvdHRvbUxlZnRFbGVtZW50VXRpbC5yaWdodExlZnQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0UmlnaHQoZWxlbWVudE5leHQ6IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb24gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSAtIGxpbmVDdXJ2ZSAqIDMsXG4gICAgICB5OiAoZWxlbWVudE5leHQueSA/PyAwKSArIChlbGVtZW50TmV4dC5oZWlnaHQgPz8gMCkgLyAyLFxuICAgIH07XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgbGV0IHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3M6IEFycmF5PElQb2ludHM+ID0gW107XG4gICAgbGV0IHsgcGF0aCwgZW5kUGF0aCB9ID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2NrcyhzdGFydC54ID8/IDAsIHN0YXJ0LnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblgsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKHN0YXJ0LnggPz8gMCkgLSBlbmRQb3NpdGlvbi54KSA8IDEwKSB7XG4gICAgICBwYXRoID0gJyc7XG4gICAgICBlbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydC54LFxuICAgICAgICB5OiBzdGFydC55LFxuICAgICAgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2NrcyA9IFtdO1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5zcGxpY2Uoc2VwYXJhdGVkUG9pbnRzLmxlbmd0aCwgMCwgLi4uc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICAvLyBzYXUga2hpIMSRw6MgxJFpIG5nYW5nIHbDoCB0csOhbmggY8OhYyBraOG7kWksIHRp4bq/cCB0aGVvIGzDoCDEkWkgdGnhur9wIGjGsOG7m25nIGzDqm4geHXhu5FuZyDEkeG7gyB24buBIGto4buRaSBj4bqnbiBu4buRaSB04bubaSwgY+G6p24gY2hlY2sgeGVtIMSRaeG7g20gZW5kIFggbsOzIMSRYW5nIOG7nyBoxrDhu5tuZyBuw6BvXG4gICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb24ueSwgJ3knKTtcblxuICAgIGlmIChkaXJlY3Rpb25ZID09PSAnY2VudGVyJykge1xuICAgICAgY29uc3QgTEVuZCA9IHsgeDogZWxlbWVudE5leHQueCA/PyAwLCB5OiBlbmRQYXRoLnkgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiBMRW5kLCBtb2RlOiAnaG9yaXpvbnRhbCcsIGlkOiAnZicgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRQYXRoOiBgJHtwYXRofSBMICR7TEVuZC54fSAke0xFbmQueX1gLFxuICAgICAgICBlbmRQYXRoOiBMRW5kLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBsZXQgbGluZUN1cnZlU3ViWSA9IGxpbmVDdXJ2ZTtcblxuICAgIGlmIChNYXRoLmFicygoZW5kUGF0aC55ID8/IDApIC0gZW5kUG9zaXRpb24ueSkgPCBsaW5lQ3VydmUgKiAyKSB7XG4gICAgICBsaW5lQ3VydmVTdWJZID0gTWF0aC5hYnMoKGVuZFBhdGgueSA/PyAwKSAtIGVuZFBvc2l0aW9uLnkpIC8gMjtcblxuICAgICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlU3ViWSAqIDIsIGxpbmVDdXJ2ZVN1YlkpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuICAgICAgY29uc3QgcGF0aFExID0gYFEgJHtjb29yZFExLngxfSwke2Nvb3JkUTEueTF9ICR7Y29vcmRRMS54fSwke2Nvb3JkUTEueX1gOyAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgICBjb25zdCBjb29yZFEyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIGAke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ30tcmlnaHRgLCBsaW5lQ3VydmVTdWJZICogMiwgbGluZUN1cnZlU3ViWSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyB0aOG6s25nIHNhbmcgbmdhbmdcbiAgICAgIGNvbnN0IHBhdGhRMiA9IGBRICR7Y29vcmRRMi54MX0sJHtjb29yZFEyLnkxfSAke2Nvb3JkUTIueH0sJHtjb29yZFEyLnl9YDtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2cnIH0pO1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICdqJyB9KTtcbiAgICAgIGNvbnN0IGxpbmVDbG9zZSA9IHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYCR7cGF0aH0gJHtwYXRoUTF9ICR7cGF0aFEyfSAke2xpbmVDbG9zZX1gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBjb29yZFExID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGByaWdodC0ke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICBjb25zdCBwYXRoUTEgPSBgUSAke2Nvb3JkUTEueDF9LCR7Y29vcmRRMS55MX0gJHtjb29yZFExLnh9LCR7Y29vcmRRMS55fWA7IC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcbiAgICBjb25zdCBlbmRQb3NpdGlvblkgPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgZW5kUG9zaXRpb25ZLnkgPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25ZLCBlbmRQb3NpdGlvbi55LCBsaW5lQ3VydmUpO1xuXG4gICAgY29uc3Qgc3RyYWlnaHRMaW5lID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc1koY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uWSwgZGlyZWN0aW9uWSwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ30tcmlnaHRgLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyB0aOG6s25nIHNhbmcgbmdhbmdcbiAgICBjb25zdCBwYXRoUTIgPSBgUSAke2Nvb3JkUTIueDF9LCR7Y29vcmRRMi55MX0gJHtjb29yZFEyLnh9LCR7Y29vcmRRMi55fWA7IC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSB9LCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnZycgfSk7XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIHk6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnkgPz8gMCB9LCBlbmQ6IHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2onIH0pO1xuICAgIGNvbnN0IGxpbmVDbG9zZSA9IHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgJHtwYXRofSAke3BhdGhRMX0gJHtzdHJhaWdodExpbmUucGF0aH0gJHtwYXRoUTJ9ICR7bGluZUNsb3NlfWAsXG4gICAgICBlbmRQYXRoOiBzdHJhaWdodExpbmUuZW5kUGF0aCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbGluZUNvbm5lY3RMZWZ0KGVsZW1lbnROZXh0OiBJUmVjdCwgZWxlbWVudEZyb206IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb25PcmlnaW4gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSAtIGxpbmVDdXJ2ZSAqIDEuNSxcbiAgICAgIHk6IChlbGVtZW50TmV4dC55ID8/IDApICsgKGVsZW1lbnROZXh0LmhlaWdodCA/PyAwKSAvIDIsXG4gICAgfTtcblxuICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gY2xvbmVEZWVwKGVuZFBvc2l0aW9uT3JpZ2luKTtcbiAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdGFydC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuXG4gICAgY29uc3QgZW5kWSA9IGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyB8fCBkaXJlY3Rpb25TdGFydFkgPT09ICdjZW50ZXInID8gKGVsZW1lbnROZXh0LnkgPz8gMCkgOiAoZWxlbWVudE5leHQueSA/PyAwKSArIChlbGVtZW50TmV4dC5oZWlnaHQgPz8gMCk7XG5cbiAgICBlbmRQb3NpdGlvbi55ID0gTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uU3RhcnRZLCBlbmRZLCBsaW5lQ3VydmUgKiAyKTtcblxuICAgIGNvbnN0IHBhdGhRID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogKHN0YXJ0LnggPz8gMCkgKyAxMCwgeTogc3RhcnQueSA/PyAwIH0sIGByaWdodC0ke2RpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyA/ICd1bmRlcicgOiAnYWJvdmUnfWAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTtcbiAgICBjb25zdCBzdGFydFFMID0geyBseDogcGF0aFEueCwgbHk6IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblN0YXJ0WSwgcGF0aFEueSA/PyAwLCAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApIC8gMiwgdHJ1ZSkgfTtcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogc3RhcnQueCA/PyAwLCB5OiBzdGFydC55ID8/IDAgfSwgZW5kOiB7IHg6IHBhdGhRLnggPz8gMCwgeTogcGF0aFEueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBwYXRoUS54ID8/IDAsIHk6IHBhdGhRLnkgPz8gMCB9LCBlbmQ6IHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5IH0sIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICcyJyB9KTtcblxuICAgIGlmIChkaXJlY3Rpb25TdGFydFkgPT09ICdjZW50ZXInKSB7XG4gICAgICBjb25zdCBjb29yZFExID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5ID8/IDAgfSwgYGFib3ZlLWxlZnRgLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5IH0sIGVuZDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMycgfSk7XG5cbiAgICAgIGNvbnN0IGVuZFBhdGggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzTGVmdChjb29yZFExLnggPz8gMCwgY29vcmRRMS55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb24sIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcblxuICAgICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgbGVmdC0ke2RpcmVjdGlvblN0YXJ0WTIgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGVuZDogeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc0JyB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYGAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdChzdGFydFFMLmx4ID8/IDAsIHN0YXJ0UUwubHkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgZGlyZWN0aW9uU3RhcnRZLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKGVuZFBvc2l0aW9uLnggPz8gMCkgLSAoc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwKSkgPD0gbGluZUN1cnZlICogMikge1xuICAgICAgZW5kUG9zaXRpb24ueCA9IHN0cmFpZ2h0TGluZS5lbmRQYXRoLng7XG4gICAgfVxuXG4gICAgaWYgKChkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicgJiYgc3RhcnRRTC5seSA+IGVuZFBvc2l0aW9uLnkpIHx8IChkaXJlY3Rpb25TdGFydFkgPT09ICdhYm92ZScgJiYgc3RhcnRRTC5seSA8IGVuZFBvc2l0aW9uLnkpIHx8IHN0YXJ0UUwubHkgPT09IGVuZFBvc2l0aW9uLnkpIHtcbiAgICAgIGxldCBjb25kaXRpb24gPSB0cnVlO1xuXG4gICAgICB3aGlsZSAoY29uZGl0aW9uKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdCA9IHNlcGFyYXRlZFBvaW50cy5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0uaWQgPT09ICdjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQnKTtcblxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ICE9PSAtMSkge1xuICAgICAgICAgIHNlcGFyYXRlZFBvaW50cy5zcGxpY2UoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0LCAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID09PSAtMSkge1xuICAgICAgICAgIGNvbmRpdGlvbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0cmFpZ2h0TGluZS5wYXRoID0gJyc7XG4gICAgICBzdHJhaWdodExpbmUuZW5kUGF0aCA9IHtcbiAgICAgICAgeDogc3RhcnRRTC5seCA/PyAwLFxuICAgICAgICB5OiBzdGFydFFMLmx5ID8/IDAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChlbmRQb3NpdGlvbi54ID09PSBzdHJhaWdodExpbmUuZW5kUGF0aC54KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdHJhaWdodExpbmUuZW5kUGF0aCwgZW5kOiBlbmRQb3NpdGlvbk9yaWdpbiwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lKHsgeDogZW5kUG9zaXRpb25PcmlnaW4ueCA/PyAwLCB5OiBlbmRQb3NpdGlvbk9yaWdpbi55ID8/IDAgfSwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBraeG7g20gdHJhIG5nYXkga2hpIGN1YSBjw7Mgdsaw4bubbmcgYWkga2jDtG5nIHLhu5NpIGjhurVuZyB24bq9IFExLFxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKGVsZW1lbnRCbG9ja1JvYWRYIC0gKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCkpIDw9IGxpbmVDdXJ2ZSAqIDIpIHtcbiAgICAgIGNvb3JkUTEueDEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkxID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgICAgY29vcmRRMS54ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwO1xuICAgICAgY29vcmRRMS55ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzZhICcgKyBkaXJlY3Rpb25TdGFydFkgfSk7XG5cbiAgICBjb25zdCBlbmRQYXRoID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc0xlZnQoY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICBjb25zdCBkaXJlY3Rpb25OZXh0WSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGNvb3JkUTEueCA/PyAwLCBlbmRQYXRoLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25OZXh0WX0tJHtkaXJlY3Rpb25TdGFydFkyID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzYnIH0pO1xuXG4gICAgdGhpcy5jbG9zZUxpbmUoeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZFBhdGg6IGBgLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjbG9zZUxpbmUoc3RhcnQ6IElQb3NpdGlvblhZLCBlbmQ6IElQb3NpdGlvblhZLCBsaW5lQ3VydmU6IG51bWJlciwgZWxlbWVudE5leHQ6IElSZWN0LCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LnksIGVuZC55LCAneScpO1xuXG4gICAgaWYgKHN0YXJ0LnkgPT09IGVuZC55KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0LCBlbmQ6IHsgeDogZWxlbWVudE5leHQueCA/PyAwLCB5OiBlbmQueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICc3JyB9KTtcblxuICAgICAgcmV0dXJuIGBMICR7ZWxlbWVudE5leHQueH0gJHtlbmQueX1gO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbmUgPSB7IHg6IHN0YXJ0LngsIHk6IHN0YXJ0LnkgfTtcbiAgICBjb25zdCBlbmRQb2ludCA9IHtcbiAgICAgIHg6IGVsZW1lbnROZXh0LngsXG4gICAgICB5OiBlbmQueSxcbiAgICB9O1xuICAgIGxldCBwYXRoUTEgPSAnJztcblxuICAgIGlmIChNYXRoLmFicyhzdGFydC55IC0gZW5kLnkpID4gbGluZUN1cnZlKSB7XG4gICAgICBjb25zdCB0b1kgPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25ZLCBlbmQueSwgbGluZUN1cnZlKTtcblxuICAgICAgbGluZS55ID0gdG9ZO1xuXG4gICAgICBjb25zdCBkaXJlY3Rpb25YID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQobGluZS54LCBlbGVtZW50TmV4dC54LCAneCcpO1xuICAgICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGxpbmUueCA/PyAwLCB5OiBsaW5lLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9LSR7ZGlyZWN0aW9uWH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIGxldCBsaW5lTCA9ICcnO1xuXG4gICAgICBpZiAoY29vcmRRMS55ID09PSBlbmQueSkge1xuICAgICAgICBsaW5lTCA9IGBMICR7ZW5kUG9pbnQueH0gJHtlbmRQb2ludC55fWA7XG4gICAgICB9XG5cbiAgICAgIHBhdGhRMSA9IGBRICR7Y29vcmRRMS54MX0sJHtjb29yZFExLnkxfSAke2Nvb3JkUTEueH0sJHtjb29yZFExLnl9ICR7bGluZUx9YDsgLy8gdOG7qyBuZ2FuZyBzYW5nIHRo4bqzbmcgcGjhuqNpIGPDsyDEkcaw4budbmcgY29uZ1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQsIGVuZDogbGluZSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzgnIH0pO1xuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGxpbmUsIGVuZDogZW5kUG9pbnQsIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzknIH0pO1xuXG4gICAgcmV0dXJuIGBMICR7bGluZS54fSAke2xpbmUueX0gJHtwYXRoUTF9YDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0TGVmdFdpdGhCb3R0b21TdGFydChlbGVtZW50TmV4dDogSVJlY3QsIGVsZW1lbnRGcm9tOiBJUmVjdCwgc3RhcnQ6IElQb2ludCwgbGluZUN1cnZlOiBudW1iZXIsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPikge1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uT3JpZ2luID0ge1xuICAgICAgeDogKGVsZW1lbnROZXh0LnggPz8gMCkgKyAoZWxlbWVudE5leHQud2lkdGggPz8gMCkgLyAyLFxuICAgICAgeTogKGVsZW1lbnROZXh0LnkgPz8gMCkgLSBsaW5lQ3VydmUsXG4gICAgfTtcbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IGNsb25lRGVlcChlbmRQb3NpdGlvbk9yaWdpbik7XG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnQueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICBjb25zdCBlbmRZID0gZWxlbWVudE5leHQueSA/PyAwO1xuXG4gICAgY29uc29sZS5sb2coJ2RpcmVjdGlvblN0YXJ0WScsIGRpcmVjdGlvblN0YXJ0WSk7XG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJykge1xuICAgICAgZW5kUG9zaXRpb24ueSA9IGVuZFkgLSBsaW5lQ3VydmUgKiAzO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UUwgPSB7IGx4OiBzdGFydC54LCBseTogKHN0YXJ0LnkgPz8gMCkgKyBsaW5lQ3VydmUgfTtcbiAgICBjb25zdCBsaW5lID0ge1xuICAgICAgc3RhcnQ6IHsgeDogc3RhcnQueCA/PyAwLCB5OiBzdGFydC55ID8/IDAgfSxcbiAgICAgIGVuZDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgPz8gMCB9LFxuICAgIH07XG4gICAgY29uc3QgbmV3RW5kID0geyB4OiBlbGVtZW50RnJvbS54IC0gbGluZUN1cnZlICogMiwgeTogbGluZS5lbmQueSAtIGxpbmVDdXJ2ZSB9O1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJykge1xuICAgICAgbGluZS5lbmQgPSB7IHg6IChzdGFydC54ID8/IDApIC0gbGluZUN1cnZlLCB5OiAoc3RhcnQueSA/PyAwKSArIGxpbmVDdXJ2ZSAqIDIgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogbGluZS5lbmQsIGVuZDogbmV3RW5kLCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzEnIH0pO1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLnN0YXJ0LCBlbmQ6IGxpbmUuZW5kLCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICcxJyB9KTsgLy8gbGluZSB24bq9IMSRaSBraOG7j2kga2jhu5FpIMSR4bqndSB0acOqblxuICAgIGNvbnN0IHN0YXJ0TmV3TGluZSA9IGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJyA/IG5ld0VuZCA6IGxpbmUuZW5kO1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIGNvbnN0IGNvb3JkUTEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgPz8gMCB9LCBgYWJvdmUtbGVmdGAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTsgLy8gdMOtbmggxJFv4bqhbiBjb25nIHThu6sgxJHGsOG7nW5nIG5nYW5nIHNhbmcgxJHGsOG7nW5nIHRo4bqzbmdcblxuICAgICAgLy8gdOG7qyBuZ2FuZyBzYW5nIHRo4bqzbmcgcGjhuqNpIGPDsyDEkcaw4budbmcgY29uZ1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICczJyB9KTtcblxuICAgICAgY29uc3QgZW5kUGF0aCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NMZWZ0KGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuICAgICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICAgIGNvbnN0IGNvb3JkUTIgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBlbmRQYXRoLnggPz8gMCwgeTogZW5kUGF0aC55ID8/IDAgfSwgYGxlZnQtJHtkaXJlY3Rpb25TdGFydFkyID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgICAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBlbmQ6IHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNCcgfSk7XG4gICAgICB0aGlzLmNsb3NlTGluZSh7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGBgLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBraeG7g20gdHJhIGjGsOG7m25nIHRo4bqzbmcgxJHhur9uIGVuZCwgbuG6v3UgY8OzIGto4buRaSB0aMOsIHRyw6FuaFxuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdChzdGFydE5ld0xpbmUueCA/PyAwLCBzdGFydE5ld0xpbmUueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBkaXJlY3Rpb25TdGFydFksIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIGNvbnN0IGRpcmVjdGlvblN0YXJ0WCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LngsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG5cbiAgICBpZiAoZGlyZWN0aW9uU3RhcnRYID09PSAnY2VudGVyJyAmJiBkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicpIHtcbiAgICAgIHRoaXMuY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oeyB4OiBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIHk6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGBgLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyAmJiBzdGFydFFMLmx5ID4gZW5kUG9zaXRpb24ueSkgfHwgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJyAmJiBzdGFydFFMLmx5IDwgZW5kUG9zaXRpb24ueSkgfHwgc3RhcnRRTC5seSA9PT0gZW5kUG9zaXRpb24ueSkge1xuICAgICAgbGV0IGNvbmRpdGlvbiA9IHRydWU7XG5cbiAgICAgIHdoaWxlIChjb25kaXRpb24pIHtcbiAgICAgICAgY29uc3QgY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID0gc2VwYXJhdGVkUG9pbnRzLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS5pZCA9PT0gJ2NoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdCcpO1xuXG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgIT09IC0xKSB7XG4gICAgICAgICAgc2VwYXJhdGVkUG9pbnRzLnNwbGljZShjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgPT09IC0xKSB7XG4gICAgICAgICAgY29uZGl0aW9uID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RyYWlnaHRMaW5lLnBhdGggPSAnJztcbiAgICAgIHN0cmFpZ2h0TGluZS5lbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydFFMLmx4ID8/IDAsXG4gICAgICAgIHk6IHN0YXJ0UUwubHkgPz8gMCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8ga2nhu4NtIHRyYSBuZ2F5IGtoaSBjdWEgY8OzIHbGsOG7m25nIGFpIGtow7RuZyBy4buTaSBo4bq1bmcgduG6vSBRMVxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKGVsZW1lbnRCbG9ja1JvYWRYIC0gKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCkpIDw9IGxpbmVDdXJ2ZSAqIDIpIHtcbiAgICAgIGNvb3JkUTEueDEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkxID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgICAgY29vcmRRMS54ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwO1xuICAgICAgY29vcmRRMS55ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgIH1cblxuICAgIC8vIGtp4buDbSB0cmEgdsOgIHbhur0gaMaw4bubbmcgbmdhbmdcbiAgICBjb25zdCBkaXJlY3Rpb25YVG9FbmQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChjb29yZFExLnggPz8gMCwgZW5kUG9zaXRpb25PcmlnaW4ueCwgJ3gnKTtcblxuICAgIGVuZFBvc2l0aW9uLnggPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25YVG9FbmQsIGVuZFBvc2l0aW9uLngsIGxpbmVDdXJ2ZSk7XG4gICAgaWYgKE1hdGguYWJzKChjb29yZFExLnkgPz8gMCkgLSBlbmRQb3NpdGlvbi55KSA8PSBsaW5lQ3VydmUpIHtcbiAgICAgIGVuZFBvc2l0aW9uLnkgLT0gbGluZUN1cnZlO1xuICAgIH1cbiAgICBjb25zdCBwYXRoSG9yaXpvbnRhbDogSVBvaW50c1tdID0gW107XG4gICAgY29uc3QgZW5kUGF0aCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NMZWZ0KGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgb2JzdGFjbGVSZWN0LCBwYXRoSG9yaXpvbnRhbCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWFRvRW5kID09PSAnbGVmdCcgJiYgZW5kUGF0aC54ID4gKGNvb3JkUTEueCA/PyAwKSkge1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogc3RyYWlnaHRMaW5lLmVuZFBhdGgsIGVuZDogZW5kUG9zaXRpb25PcmlnaW4sIG1vZGU6ICd2ZXJ0aWNhbCcsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oZW5kUG9zaXRpb25PcmlnaW4sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goLi4ucGF0aEhvcml6b250YWwpO1xuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAgLSAxMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICB0aGlzLmNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgYCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oc3RhcnQ6IElQb3NpdGlvblhZLCBlbmQ6IElQb3NpdGlvblhZLCBsaW5lQ3VydmU6IG51bWJlciwgZWxlbWVudE5leHQ6IElSZWN0LCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZGlyZWN0aW9uWCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LngsIGVuZC54LCAneCcpO1xuXG4gICAgaWYgKHN0YXJ0LnggPT09IGVuZC54KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0LCBlbmQ6IHsgeDogKGVsZW1lbnROZXh0LnggPz8gMCkgKyAoZWxlbWVudE5leHQud2lkdGggPz8gMCkgLyAyLCB5OiBlbGVtZW50TmV4dC55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzcnIH0pO1xuXG4gICAgICByZXR1cm4gYEwgJHtlbGVtZW50TmV4dC54fSAke2VuZC55fWA7XG4gICAgfVxuXG4gICAgY29uc3QgbGluZSA9IHsgeDogc3RhcnQueCwgeTogc3RhcnQueSB9O1xuICAgIGNvbnN0IGVuZFBvaW50ID0ge1xuICAgICAgeDogZW5kLngsXG4gICAgICB5OiBlbGVtZW50TmV4dC55LFxuICAgIH07XG4gICAgY29uc3QgcGF0aFExID0gJyc7XG5cbiAgICBpZiAoTWF0aC5hYnMoc3RhcnQueCAtIGVuZC54KSA+IGxpbmVDdXJ2ZSkge1xuICAgICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LnksIGVuZFBvaW50LnksICd5Jyk7XG4gICAgICBjb25zdCB0b1ggPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25YLCBlbmQueCwgbGluZUN1cnZlKTtcbiAgICAgIGNvbnN0IHRvWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZC55LCBsaW5lQ3VydmUpO1xuXG4gICAgICBsaW5lLnggPSB0b1g7XG4gICAgICBsaW5lLnkgPSB0b1k7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdGFydCwgZW5kOiBsaW5lLCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc5JyB9KTtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLCBlbmQ6IGVuZFBvaW50LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzknIH0pO1xuXG4gICAgcmV0dXJuIGBMICR7bGluZS54fSAke2xpbmUueX0gJHtwYXRoUTF9YDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0UmlnaHRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQ6IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb24gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSArIChlbGVtZW50TmV4dC53aWR0aCA/PyAwKSAvIDIsXG4gICAgICB5OiAoZWxlbWVudE5leHQueSA/PyAwKSAtIGxpbmVDdXJ2ZSxcbiAgICB9O1xuXG4gICAgLy8gduG6vSAxIMSRxrDhu51uZyB0aOG6s25nIHThu6sgxJFp4buDbSBzdGFydCByYSBuZ2/DoGkgxJHDo1xuICAgIGNvbnN0IGVuZCA9IHsgeDogKHN0YXJ0LnggPz8gMCkgKyAxMCwgeTogKHN0YXJ0LnkgPz8gMCkgKyAyMCB9O1xuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdGFydC54ID8/IDAsIHk6IHN0YXJ0LnkgPz8gMCB9LCBlbmQ6IGVuZCwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgZW5kUG9zaXRpb25YLnggLT0gMTA7XG5cbiAgICBsZXQgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2NrczogQXJyYXk8SVBvaW50cz4gPSBbXTtcbiAgICBsZXQgeyBwYXRoLCBlbmRQYXRoIH0gPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzKGVuZC54ID8/IDAsIGVuZC55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb25YLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MpO1xuXG4gICAgaWYgKE1hdGguYWJzKChzdGFydC54ID8/IDApIC0gZW5kUG9zaXRpb24ueCkgPCAxMCkge1xuICAgICAgcGF0aCA9ICcnO1xuICAgICAgZW5kUGF0aCA9IHtcbiAgICAgICAgeDogc3RhcnQueCxcbiAgICAgICAgeTogc3RhcnQueSxcbiAgICAgIH07XG5cbiAgICAgIHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MgPSBbXTtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMuc3BsaWNlKHNlcGFyYXRlZFBvaW50cy5sZW5ndGgsIDAsIC4uLnNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MpO1xuXG4gICAgLy8gc2F1IGtoaSDEkcOjIMSRaSBuZ2FuZyB2w6AgdHLDoW5oIGPDoWMga2jhu5FpLCB0aeG6v3AgdGhlbyBsw6AgxJFpIHRp4bq/cCBoxrDhu5tuZyBsw6puIHh14buRbmcgxJHhu4MgduG7gSBraOG7kWkgY+G6p24gbuG7kWkgdOG7m2ksIGPhuqduIGNoZWNrIHhlbSDEkWnhu4NtIGVuZCBYIG7DsyDEkWFuZyDhu58gaMaw4bubbmcgbsOgb1xuICAgIGNvbnN0IGRpcmVjdGlvblkgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChlbmRQYXRoLnksIGVuZFBvc2l0aW9uLnksICd5Jyk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIGNvbnN0IExFbmQgPSB7IHg6IGVsZW1lbnROZXh0LnggPz8gMCwgeTogZW5kUGF0aC55IH07XG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGVuZFBhdGgsIGVuZDogTEVuZCwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJ2YnIH0pO1xuXG4gICAgICAvLyDEkW/huqFuIG7DoHkgY2jGsGEgb2NlXG4gICAgICB0aGlzLmNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKExFbmQsIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYCR7cGF0aH0gTCAke0xFbmQueH0gJHtMRW5kLnl9YCxcbiAgICAgICAgZW5kUGF0aDogTEVuZCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uWSA9IGNsb25lRGVlcChlbmRQb3NpdGlvbik7XG5cbiAgICBlbmRQb3NpdGlvblkueSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZFBvc2l0aW9uLnksIGxpbmVDdXJ2ZSkgLSAxMDtcblxuICAgIC8vIGPhuqduIGNoZWNrIGtoaSDEkWkgdGjhurNuZyBsw6puIGPDsyB2xrDhu5tuZyBraOG7kWkgbsOgbyBraMO0bmcgxJHhu4MgdGnhur9uIGzDqm5cbiAgICBjb25zdCBlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQmxvY2tzRWxlbWVudFN0cmFpZ2h0WSgoZW5kUGF0aC54ID8/IDApICsgMTAsIGVuZFBhdGgueSA/PyAwLCBlbmRQb3NpdGlvblksIG9ic3RhY2xlUmVjdCk7XG5cbiAgICBpZiAoZWxlbWVudEJsb2NrUm9hZFN0cmFpZ2h0TGluZVkpIHtcbiAgICAgIGNvb3JkUTEueCA9IChlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWS54ID8/IDApICsgKGVsZW1lbnRCbG9ja1JvYWRTdHJhaWdodExpbmVZLndpZHRoID8/IDApICsgbGluZUN1cnZlO1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2cnIH0pO1xuXG4gICAgbGV0IGF2b2lkQmxvY2tzWUxpbmU6IElQb2ludHNbXSA9IFtdO1xuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZKGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblksIGRpcmVjdGlvblksIG9ic3RhY2xlUmVjdCwgYXZvaWRCbG9ja3NZTGluZSk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWSA9PT0gJ3VuZGVyJyAmJiAoY29vcmRRMS55ID8/IDApID4gZW5kUG9zaXRpb25ZLnkpIHtcbiAgICAgIGF2b2lkQmxvY2tzWUxpbmUgPSBbXTtcbiAgICAgIHN0cmFpZ2h0TGluZS5lbmRQYXRoID0geyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfTtcbiAgICB9XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goLi4uYXZvaWRCbG9ja3NZTGluZSk7XG4gICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgYCxcbiAgICB9O1xuICB9XG59XG4iXX0=
|