@datagrok-libraries/statistics 1.9.2 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/styles.css +229 -0
- package/package.json +3 -2
- package/src/fit/const.d.ts +58 -0
- package/src/fit/const.d.ts.map +1 -0
- package/src/fit/const.js +63 -0
- package/src/fit/fit-data.d.ts.map +1 -1
- package/src/fit/fit-data.js +37 -5
- package/src/fit/new-fit-API.d.ts +6 -0
- package/src/fit/new-fit-API.d.ts.map +1 -1
- package/src/fit/new-fit-API.js +2 -8
- package/src/mpo/dialogs/desirability-mode-dialog.d.ts +14 -0
- package/src/mpo/dialogs/desirability-mode-dialog.d.ts.map +1 -0
- package/src/mpo/dialogs/desirability-mode-dialog.js +198 -0
- package/src/mpo/editors/desirability-editor-factory.d.ts +15 -0
- package/src/mpo/editors/desirability-editor-factory.d.ts.map +1 -0
- package/src/mpo/editors/desirability-editor-factory.js +11 -0
- package/src/mpo/editors/mpo-categorical-editor.d.ts +24 -0
- package/src/mpo/editors/mpo-categorical-editor.d.ts.map +1 -0
- package/src/mpo/editors/mpo-categorical-editor.js +113 -0
- package/src/mpo/editors/mpo-line-editor.d.ts +46 -0
- package/src/mpo/editors/mpo-line-editor.d.ts.map +1 -0
- package/src/mpo/editors/mpo-line-editor.js +583 -0
- package/src/mpo/mpo-profile-editor.d.ts +42 -6
- package/src/mpo/mpo-profile-editor.d.ts.map +1 -1
- package/src/mpo/mpo-profile-editor.js +368 -59
- package/src/mpo/mpo.d.ts +53 -3
- package/src/mpo/mpo.d.ts.map +1 -1
- package/src/mpo/mpo.js +92 -16
- package/src/mpo/utils.d.ts +6 -0
- package/src/mpo/utils.d.ts.map +1 -0
- package/src/mpo/utils.js +17 -0
- package/src/mpo/mpo-line-editor.d.ts +0 -10
- package/src/mpo/mpo-line-editor.d.ts.map +0 -1
- package/src/mpo/mpo-line-editor.js +0 -258
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
import * as DG from 'datagrok-api/dg';
|
|
5
|
+
import { Subject } from 'rxjs';
|
|
6
|
+
let _konva;
|
|
7
|
+
async function getKonva() {
|
|
8
|
+
if (!_konva)
|
|
9
|
+
_konva = (await import('konva')).default;
|
|
10
|
+
return _konva;
|
|
11
|
+
}
|
|
12
|
+
// Constants for the editor layout
|
|
13
|
+
const EDITOR_PADDING = { top: 10, right: 10, bottom: 20, left: 30 };
|
|
14
|
+
const POINT_RADIUS = 3;
|
|
15
|
+
const COLORS = {
|
|
16
|
+
line: DG.Color.toHtml(DG.Color.filteredRows),
|
|
17
|
+
handle: DG.Color.toHtml(DG.Color.selectedRows),
|
|
18
|
+
barFill: DG.Color.toHtml(DG.Color.histogramBar),
|
|
19
|
+
barStroke: DG.Color.toHtml(DG.Color.lightGray),
|
|
20
|
+
};
|
|
21
|
+
class CoordMapper {
|
|
22
|
+
constructor(minX, maxX, width, height) {
|
|
23
|
+
this.minX = minX;
|
|
24
|
+
this.maxX = maxX;
|
|
25
|
+
this.width = width;
|
|
26
|
+
this.height = height;
|
|
27
|
+
this.plotWidth = width - EDITOR_PADDING.left - EDITOR_PADDING.right;
|
|
28
|
+
this.plotHeight = height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
|
|
29
|
+
this.scaleX = (this.maxX - this.minX === 0) ? 1 : this.plotWidth / (this.maxX - this.minX);
|
|
30
|
+
this.scaleY = this.plotHeight;
|
|
31
|
+
}
|
|
32
|
+
toCanvasCoords(p) {
|
|
33
|
+
const canvasX = EDITOR_PADDING.left + (p[0] - this.minX) * this.scaleX;
|
|
34
|
+
const canvasY = EDITOR_PADDING.top + this.plotHeight - (p[1] * this.scaleY);
|
|
35
|
+
return { x: canvasX, y: canvasY };
|
|
36
|
+
}
|
|
37
|
+
toDataCoords(canvasX, canvasY) {
|
|
38
|
+
let dataX = this.minX + (canvasX - EDITOR_PADDING.left) / this.scaleX;
|
|
39
|
+
let dataY = (EDITOR_PADDING.top + this.plotHeight - canvasY) / this.scaleY;
|
|
40
|
+
dataX = Math.max(this.minX, Math.min(this.maxX, dataX));
|
|
41
|
+
dataY = Math.max(0, Math.min(1, dataY));
|
|
42
|
+
return { x: dataX, y: dataY };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class MpoDesirabilityLineEditor {
|
|
46
|
+
constructor(prop, width, height) {
|
|
47
|
+
this.root = ui.div();
|
|
48
|
+
this.onChanged = new Subject();
|
|
49
|
+
this.supportsModeDialog = true;
|
|
50
|
+
// Flag to prevent touchpad right-click from adding a new point
|
|
51
|
+
this.ignoreNextClick = false;
|
|
52
|
+
this.dragScaleX = 0;
|
|
53
|
+
this.dragScaleY = 0;
|
|
54
|
+
this._prop = prop;
|
|
55
|
+
this._width = width;
|
|
56
|
+
this._height = height;
|
|
57
|
+
this.ensureDefaultLine();
|
|
58
|
+
this.root.style.width = `${width}px`;
|
|
59
|
+
this.root.style.height = `${height}px`;
|
|
60
|
+
this.root.style.position = 'relative';
|
|
61
|
+
requestAnimationFrame(() => this.initKonva(width, height));
|
|
62
|
+
}
|
|
63
|
+
ensureDefaultLine() {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
if (this._prop.line.length > 0)
|
|
66
|
+
return;
|
|
67
|
+
const min = (_a = this._prop.min) !== null && _a !== void 0 ? _a : 0;
|
|
68
|
+
const max = (_b = this._prop.max) !== null && _b !== void 0 ? _b : 1;
|
|
69
|
+
this._prop.line = [[min, 0.5], [max, 0.5]];
|
|
70
|
+
}
|
|
71
|
+
updateDragScales() {
|
|
72
|
+
const plotWidth = this._width - EDITOR_PADDING.left - EDITOR_PADDING.right;
|
|
73
|
+
const plotHeight = this._height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
|
|
74
|
+
this.dragScaleX = (this.getMaxX() - this.getMinX()) / plotWidth;
|
|
75
|
+
this.dragScaleY = 1 / plotHeight;
|
|
76
|
+
}
|
|
77
|
+
isInPlotArea(pos, width, height) {
|
|
78
|
+
return (pos.x >= EDITOR_PADDING.left &&
|
|
79
|
+
pos.x <= width - EDITOR_PADDING.right &&
|
|
80
|
+
pos.y >= EDITOR_PADDING.top &&
|
|
81
|
+
pos.y <= height - EDITOR_PADDING.bottom);
|
|
82
|
+
}
|
|
83
|
+
async initKonva(width, height) {
|
|
84
|
+
var _a;
|
|
85
|
+
if (!this.root.parentElement) {
|
|
86
|
+
console.warn('Konva container not attached to DOM yet.');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const Konva = await getKonva();
|
|
90
|
+
this.barsLayer = new Konva.Layer();
|
|
91
|
+
this.stage = new Konva.Stage({
|
|
92
|
+
container: this.root,
|
|
93
|
+
width,
|
|
94
|
+
height,
|
|
95
|
+
});
|
|
96
|
+
this.stage.add(this.barsLayer);
|
|
97
|
+
this.layer = new Konva.Layer();
|
|
98
|
+
this.stage.add(this.layer);
|
|
99
|
+
const minX = this.getMinX();
|
|
100
|
+
const maxX = this.getMaxX();
|
|
101
|
+
// --- Draw Axes ---
|
|
102
|
+
this.drawAxes(minX, maxX, width, height);
|
|
103
|
+
// --- Draw Line and Points ---
|
|
104
|
+
this.konvaLine = new Konva.Line({
|
|
105
|
+
points: [],
|
|
106
|
+
stroke: COLORS.line,
|
|
107
|
+
strokeWidth: 2,
|
|
108
|
+
lineCap: 'round',
|
|
109
|
+
lineJoin: 'round',
|
|
110
|
+
});
|
|
111
|
+
this.layer.add(this.konvaLine);
|
|
112
|
+
this.pointsGroup = new Konva.Group();
|
|
113
|
+
this.layer.add(this.pointsGroup);
|
|
114
|
+
// --- Redraw Function ---
|
|
115
|
+
this.redrawFn = (notify = true) => {
|
|
116
|
+
const minX = this.getMinX();
|
|
117
|
+
const maxX = this.getMaxX();
|
|
118
|
+
if (this._prop.mode === 'freeform' && this._prop.freeformLine)
|
|
119
|
+
this._prop.line = this._prop.freeformLine;
|
|
120
|
+
if (this._prop.mode !== 'freeform') {
|
|
121
|
+
if (!this._prop.freeformLine)
|
|
122
|
+
this._prop.freeformLine = [...this._prop.line];
|
|
123
|
+
this._prop.line = this.computeLine();
|
|
124
|
+
}
|
|
125
|
+
this.pointsGroup.destroyChildren();
|
|
126
|
+
const konvaPoints = [];
|
|
127
|
+
const mapper = new CoordMapper(minX, maxX, width, height);
|
|
128
|
+
const sortedIndices = [...this._prop.line.keys()]
|
|
129
|
+
.sort((a, b) => this._prop.line[a][0] - this._prop.line[b][0]);
|
|
130
|
+
const sortedLine = sortedIndices.map((idx) => this._prop.line[idx]);
|
|
131
|
+
sortedLine.forEach((p, index) => {
|
|
132
|
+
const coords = mapper.toCanvasCoords([p[0], p[1]]);
|
|
133
|
+
konvaPoints.push(coords.x, coords.y);
|
|
134
|
+
if (this._prop.mode !== 'freeform')
|
|
135
|
+
return;
|
|
136
|
+
const pointCircle = new Konva.Circle({
|
|
137
|
+
x: coords.x,
|
|
138
|
+
y: coords.y,
|
|
139
|
+
radius: POINT_RADIUS,
|
|
140
|
+
fill: 'white',
|
|
141
|
+
stroke: COLORS.line,
|
|
142
|
+
strokeWidth: 1,
|
|
143
|
+
draggable: true,
|
|
144
|
+
hitStrokeWidth: 5,
|
|
145
|
+
});
|
|
146
|
+
// Store index directly on the node for easy access
|
|
147
|
+
pointCircle.setAttr('_dataIndex', sortedIndices[index]);
|
|
148
|
+
pointCircle.on('dragmove', (evt) => {
|
|
149
|
+
const circle = evt.target;
|
|
150
|
+
const pos = circle.position();
|
|
151
|
+
const dataIndex = circle.getAttr('_dataIndex');
|
|
152
|
+
const sortedPos = sortedIndices.indexOf(dataIndex);
|
|
153
|
+
// Constrain dragging horizontally between neighbors (or bounds)
|
|
154
|
+
const prevX = sortedPos > 0 ? this._prop.line[sortedIndices[sortedPos - 1]][0] : minX;
|
|
155
|
+
const nextX = sortedPos < sortedIndices.length - 1 ?
|
|
156
|
+
this._prop.line[sortedIndices[sortedPos + 1]][0] :
|
|
157
|
+
maxX;
|
|
158
|
+
// Add a small buffer to avoid points overlapping exactly
|
|
159
|
+
const buffer = (maxX - minX === 0) ? 0 : 0.001 * (maxX - minX); // Avoid NaN if minX === maxX
|
|
160
|
+
const minCanvasX = mapper.toCanvasCoords([prevX + (sortedPos > 0 ? buffer : 0), 0]).x;
|
|
161
|
+
const maxCanvasX = mapper.toCanvasCoords([nextX - (sortedPos < sortedIndices.length - 1 ? buffer : 0), 0]).x;
|
|
162
|
+
pos.x = Math.max(minCanvasX, Math.min(maxCanvasX, pos.x));
|
|
163
|
+
const plotTop = EDITOR_PADDING.top;
|
|
164
|
+
const plotBottom = height - EDITOR_PADDING.bottom;
|
|
165
|
+
pos.y = Math.max(plotTop, Math.min(plotBottom, pos.y));
|
|
166
|
+
circle.position(pos);
|
|
167
|
+
const dataCoords = mapper.toDataCoords(pos.x, pos.y);
|
|
168
|
+
this._prop.line[dataIndex][0] = dataCoords.x;
|
|
169
|
+
this._prop.line[dataIndex][1] = dataCoords.y;
|
|
170
|
+
const currentKonvaPoints = this._prop.line.map((pData, idx) => {
|
|
171
|
+
// Use dragged circle position directly for the point being dragged
|
|
172
|
+
if (idx === dataIndex)
|
|
173
|
+
return [pos.x, pos.y];
|
|
174
|
+
else {
|
|
175
|
+
const c = mapper.toCanvasCoords([pData[0], pData[1]]);
|
|
176
|
+
return [c.x, c.y];
|
|
177
|
+
}
|
|
178
|
+
}).flat();
|
|
179
|
+
this.konvaLine.points(currentKonvaPoints);
|
|
180
|
+
this.layer.batchDraw();
|
|
181
|
+
});
|
|
182
|
+
pointCircle.on('dragend', () => {
|
|
183
|
+
var _a;
|
|
184
|
+
this._prop.line.sort((a, b) => a[0] - b[0]);
|
|
185
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
186
|
+
});
|
|
187
|
+
pointCircle.on('contextmenu', (evt) => {
|
|
188
|
+
var _a;
|
|
189
|
+
evt.evt.preventDefault();
|
|
190
|
+
if (this._prop.line.length <= 2) {
|
|
191
|
+
grok.shell.warning('Cannot remove points, minimum of 2 required.');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
this.ignoreNextClick = true;
|
|
195
|
+
const circle = evt.target;
|
|
196
|
+
const dataIndex = circle.getAttr('_dataIndex');
|
|
197
|
+
if (dataIndex >= 0) {
|
|
198
|
+
if (this._prop.min == null)
|
|
199
|
+
this._prop.min = this.getMinX();
|
|
200
|
+
if (this._prop.max == null)
|
|
201
|
+
this._prop.max = this.getMaxX();
|
|
202
|
+
this._prop.line.splice(dataIndex, 1);
|
|
203
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
pointCircle.on('mouseenter', (evt) => {
|
|
207
|
+
this.stage.container().style.cursor = 'pointer';
|
|
208
|
+
const circle = evt.target;
|
|
209
|
+
const pos = circle.position();
|
|
210
|
+
const dataCoords = mapper.toDataCoords(pos.x, pos.y);
|
|
211
|
+
const tooltipText = `X: ${dataCoords.x.toFixed(2)}, Y: ${dataCoords.y.toFixed(2)}<br><br>Drag to move, double-click to edit, right-click to delete`;
|
|
212
|
+
ui.tooltip.show(tooltipText, evt.evt.clientX, evt.evt.clientY);
|
|
213
|
+
});
|
|
214
|
+
pointCircle.on('mouseleave', () => {
|
|
215
|
+
this.stage.container().style.cursor = 'default';
|
|
216
|
+
ui.tooltip.hide();
|
|
217
|
+
});
|
|
218
|
+
pointCircle.on('dblclick dbltap', (evt) => {
|
|
219
|
+
this.ignoreNextClick = true;
|
|
220
|
+
ui.tooltip.hide();
|
|
221
|
+
const dataIndex = evt.target.getAttr('_dataIndex');
|
|
222
|
+
this.showPointEditor(dataIndex, evt.evt.clientX, evt.evt.clientY);
|
|
223
|
+
});
|
|
224
|
+
this.pointsGroup.add(pointCircle);
|
|
225
|
+
});
|
|
226
|
+
this.konvaLine.points(konvaPoints);
|
|
227
|
+
this.layer.batchDraw();
|
|
228
|
+
// --- Add special handle (Gaussian peak / Sigmoid inflection) ---
|
|
229
|
+
this.addSpecialHandle(width, height);
|
|
230
|
+
if (notify)
|
|
231
|
+
this.onChanged.next(this._prop.line);
|
|
232
|
+
};
|
|
233
|
+
// --- Left-click to Add Point ---
|
|
234
|
+
this.stage.on('click tap', (evt) => {
|
|
235
|
+
var _a, _b;
|
|
236
|
+
if (this.ignoreNextClick) {
|
|
237
|
+
this.ignoreNextClick = false;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (evt.target instanceof Konva.Circle || evt.evt.button !== 0)
|
|
241
|
+
return;
|
|
242
|
+
const pos = (_a = this.stage) === null || _a === void 0 ? void 0 : _a.getPointerPosition();
|
|
243
|
+
if (!pos)
|
|
244
|
+
return;
|
|
245
|
+
const minX = this.getMinX();
|
|
246
|
+
const maxX = this.getMaxX();
|
|
247
|
+
if (!this.isInPlotArea(pos, this.stage.width(), this.stage.height()))
|
|
248
|
+
return;
|
|
249
|
+
const mapper = new CoordMapper(minX, maxX, this.stage.width(), this.stage.height());
|
|
250
|
+
const dataCoords = mapper.toDataCoords(pos.x, pos.y);
|
|
251
|
+
this._prop.line.push([dataCoords.x, dataCoords.y]);
|
|
252
|
+
this._prop.line.sort((a, b) => a[0] - b[0]);
|
|
253
|
+
(_b = this.redrawFn) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
254
|
+
});
|
|
255
|
+
// Cursor change
|
|
256
|
+
this.stage.on('mousemove', (evt) => {
|
|
257
|
+
if (!this.stage)
|
|
258
|
+
return;
|
|
259
|
+
const pos = this.stage.getPointerPosition();
|
|
260
|
+
if (!pos)
|
|
261
|
+
return;
|
|
262
|
+
if (this._prop.mode !== 'freeform') {
|
|
263
|
+
if (this.isInPlotArea(pos, width, height))
|
|
264
|
+
this.stage.container().style.cursor = 'grab';
|
|
265
|
+
else
|
|
266
|
+
this.stage.container().style.cursor = 'default';
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
this.stage.on('mouseout', () => ui.tooltip.hide());
|
|
270
|
+
// Enable curve drag (smooth)
|
|
271
|
+
this.enableCurveDrag(width, height);
|
|
272
|
+
this.updateDragScales();
|
|
273
|
+
// Initial draw
|
|
274
|
+
if (this.pendingBarValues) {
|
|
275
|
+
this.drawBars(this.pendingBarValues);
|
|
276
|
+
this.pendingBarValues = undefined;
|
|
277
|
+
}
|
|
278
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this, false);
|
|
279
|
+
}
|
|
280
|
+
get line() {
|
|
281
|
+
return this._prop.line;
|
|
282
|
+
}
|
|
283
|
+
computeLine() {
|
|
284
|
+
var _a, _b, _c, _d;
|
|
285
|
+
var _e, _f, _g, _h;
|
|
286
|
+
if (this._prop.mode === 'freeform')
|
|
287
|
+
return this._prop.line;
|
|
288
|
+
const minX = this.getMinX();
|
|
289
|
+
const maxX = this.getMaxX();
|
|
290
|
+
const n = 60;
|
|
291
|
+
const line = [];
|
|
292
|
+
for (let i = 0; i <= n; i++) {
|
|
293
|
+
const x = minX + (maxX - minX) * (i / n);
|
|
294
|
+
let y = 0;
|
|
295
|
+
if (this._prop.mode === 'gaussian') {
|
|
296
|
+
(_a = (_e = this._prop).mean) !== null && _a !== void 0 ? _a : (_e.mean = (minX + maxX) / 2);
|
|
297
|
+
(_b = (_f = this._prop).sigma) !== null && _b !== void 0 ? _b : (_f.sigma = (maxX - minX) / 6);
|
|
298
|
+
const mean = this._prop.mean;
|
|
299
|
+
const sigma = this._prop.sigma;
|
|
300
|
+
const z = (x - mean) / sigma;
|
|
301
|
+
y = Math.exp(-0.5 * z * z);
|
|
302
|
+
}
|
|
303
|
+
if (this._prop.mode === 'sigmoid') {
|
|
304
|
+
(_c = (_g = this._prop).x0) !== null && _c !== void 0 ? _c : (_g.x0 = (minX + maxX) / 2);
|
|
305
|
+
(_d = (_h = this._prop).k) !== null && _d !== void 0 ? _d : (_h.k = 10);
|
|
306
|
+
const x0 = this._prop.x0;
|
|
307
|
+
const k = this._prop.k;
|
|
308
|
+
y = 1 / (1 + Math.exp(-k * (x - x0)));
|
|
309
|
+
}
|
|
310
|
+
line.push([x, y]);
|
|
311
|
+
}
|
|
312
|
+
return line;
|
|
313
|
+
}
|
|
314
|
+
drawAxes(minX, maxX, width, height) {
|
|
315
|
+
const axisColor = getComputedStyle(document.documentElement).getPropertyValue('--grey-2').trim() || '#DBDCDF';
|
|
316
|
+
this.layer.add(new _konva.Line({
|
|
317
|
+
points: [EDITOR_PADDING.left, height - EDITOR_PADDING.bottom, width - EDITOR_PADDING.right, height - EDITOR_PADDING.bottom],
|
|
318
|
+
stroke: axisColor,
|
|
319
|
+
strokeWidth: 1,
|
|
320
|
+
}), new _konva.Line({
|
|
321
|
+
points: [EDITOR_PADDING.left, EDITOR_PADDING.top, EDITOR_PADDING.left, height - EDITOR_PADDING.bottom],
|
|
322
|
+
stroke: axisColor,
|
|
323
|
+
strokeWidth: 1,
|
|
324
|
+
}), new _konva.Text({ x: EDITOR_PADDING.left, y: height - EDITOR_PADDING.bottom + 3, text: minX.toFixed(1), fontSize: 9, fill: 'grey' }), new _konva.Text({ x: width - EDITOR_PADDING.right - 15, y: height - EDITOR_PADDING.bottom + 3, text: maxX.toFixed(1), fontSize: 9, fill: 'grey' }));
|
|
325
|
+
}
|
|
326
|
+
getMinX() {
|
|
327
|
+
var _a, _b;
|
|
328
|
+
return (_b = (_a = this._prop.min) !== null && _a !== void 0 ? _a : Math.min(...this._prop.line.map((p) => p[0]))) !== null && _b !== void 0 ? _b : 0;
|
|
329
|
+
}
|
|
330
|
+
getMaxX() {
|
|
331
|
+
var _a, _b;
|
|
332
|
+
return (_b = (_a = this._prop.max) !== null && _a !== void 0 ? _a : Math.max(...this._prop.line.map((p) => p[0]))) !== null && _b !== void 0 ? _b : 1;
|
|
333
|
+
}
|
|
334
|
+
getDefaultMean() {
|
|
335
|
+
return (this.getMinX() + this.getMaxX()) / 2;
|
|
336
|
+
}
|
|
337
|
+
getDefaultSigma() {
|
|
338
|
+
return Math.max(0.01, (this.getMaxX() - this.getMinX()) / 6);
|
|
339
|
+
}
|
|
340
|
+
getDefaultX0() {
|
|
341
|
+
return (this.getMinX() + this.getMaxX()) / 2;
|
|
342
|
+
}
|
|
343
|
+
getDefaultK() {
|
|
344
|
+
return 10;
|
|
345
|
+
}
|
|
346
|
+
redrawAll(notify = true) {
|
|
347
|
+
if (!this.stage || !this.layer || !this.redrawFn)
|
|
348
|
+
return;
|
|
349
|
+
const width = this.stage.width();
|
|
350
|
+
const height = this.stage.height();
|
|
351
|
+
const minX = this.getMinX();
|
|
352
|
+
const maxX = this.getMaxX();
|
|
353
|
+
this.layer.destroyChildren();
|
|
354
|
+
this.drawAxes(minX, maxX, width, height);
|
|
355
|
+
this.layer.add(this.konvaLine, this.pointsGroup);
|
|
356
|
+
this.redrawFn(notify);
|
|
357
|
+
if (this.barValues)
|
|
358
|
+
this.drawBars();
|
|
359
|
+
}
|
|
360
|
+
drawBars(values) {
|
|
361
|
+
var _a;
|
|
362
|
+
if (values)
|
|
363
|
+
this.barValues = values;
|
|
364
|
+
if (!this.barsLayer) {
|
|
365
|
+
this.pendingBarValues = values;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
this.barsLayer.destroyChildren();
|
|
369
|
+
if (!this.barValues || this.barValues.length === 0)
|
|
370
|
+
return;
|
|
371
|
+
const stage = this.barsLayer.getStage();
|
|
372
|
+
if (!stage) {
|
|
373
|
+
this.pendingBarValues = values;
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const width = stage.width();
|
|
377
|
+
const height = stage.height();
|
|
378
|
+
const minX = this.getMinX();
|
|
379
|
+
const maxX = this.getMaxX();
|
|
380
|
+
if (maxX === minX)
|
|
381
|
+
return;
|
|
382
|
+
const numBins = 20;
|
|
383
|
+
const plotWidth = width - EDITOR_PADDING.left - EDITOR_PADDING.right;
|
|
384
|
+
const plotHeight = height - EDITOR_PADDING.top - EDITOR_PADDING.bottom;
|
|
385
|
+
const binWidth = Math.max(1e-9, (maxX - minX) / numBins);
|
|
386
|
+
const bins = new Array(numBins).fill(0);
|
|
387
|
+
((_a = this.barValues) !== null && _a !== void 0 ? _a : []).forEach((v) => {
|
|
388
|
+
const idx = Math.min(Math.floor((v - minX) / binWidth), numBins - 1);
|
|
389
|
+
bins[idx]++;
|
|
390
|
+
});
|
|
391
|
+
const maxCount = Math.max(...bins) || 1;
|
|
392
|
+
bins.forEach((count, i) => {
|
|
393
|
+
const barX = EDITOR_PADDING.left + (i * binWidth / (maxX - minX)) * plotWidth;
|
|
394
|
+
const barW = (binWidth / (maxX - minX)) * plotWidth - 1;
|
|
395
|
+
const barH = (count / maxCount) * plotHeight;
|
|
396
|
+
const rect = new _konva.Rect({
|
|
397
|
+
x: barX,
|
|
398
|
+
y: EDITOR_PADDING.top + plotHeight - barH,
|
|
399
|
+
width: barW,
|
|
400
|
+
height: barH,
|
|
401
|
+
fill: COLORS.barFill,
|
|
402
|
+
opacity: 0.25,
|
|
403
|
+
stroke: COLORS.barStroke,
|
|
404
|
+
strokeWidth: 0.5,
|
|
405
|
+
});
|
|
406
|
+
this.barsLayer.add(rect);
|
|
407
|
+
});
|
|
408
|
+
this.barsLayer.batchDraw();
|
|
409
|
+
}
|
|
410
|
+
enableCurveDrag(width, height) {
|
|
411
|
+
if (!this.stage)
|
|
412
|
+
return;
|
|
413
|
+
let dragging = false;
|
|
414
|
+
let startPointer = null;
|
|
415
|
+
let startMean = 0;
|
|
416
|
+
let startSigma = 0;
|
|
417
|
+
let startX0 = 0;
|
|
418
|
+
let startK = 0;
|
|
419
|
+
this.stage.on('mousedown touchstart', (evt) => {
|
|
420
|
+
var _a, _b, _c, _d;
|
|
421
|
+
if (this._prop.mode === 'freeform')
|
|
422
|
+
return;
|
|
423
|
+
if (!evt.evt)
|
|
424
|
+
return;
|
|
425
|
+
const pos = this.stage.getPointerPosition();
|
|
426
|
+
if (!pos)
|
|
427
|
+
return;
|
|
428
|
+
if (!this.isInPlotArea(pos, width, height))
|
|
429
|
+
return;
|
|
430
|
+
dragging = true;
|
|
431
|
+
startPointer = pos;
|
|
432
|
+
startMean = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (this.getMinX() + this.getMaxX()) / 2;
|
|
433
|
+
startSigma = (_b = this._prop.sigma) !== null && _b !== void 0 ? _b : (this.getMaxX() - this.getMinX()) / 6;
|
|
434
|
+
startX0 = (_c = this._prop.x0) !== null && _c !== void 0 ? _c : (this.getMinX() + this.getMaxX()) / 2;
|
|
435
|
+
startK = (_d = this._prop.k) !== null && _d !== void 0 ? _d : 10;
|
|
436
|
+
this.stage.container().style.cursor = 'grabbing';
|
|
437
|
+
});
|
|
438
|
+
this.stage.on('mousemove touchmove', (evt) => {
|
|
439
|
+
var _a, _b;
|
|
440
|
+
if (!dragging || !startPointer)
|
|
441
|
+
return;
|
|
442
|
+
const pos = this.stage.getPointerPosition();
|
|
443
|
+
if (!pos)
|
|
444
|
+
return;
|
|
445
|
+
const dx = pos.x - startPointer.x;
|
|
446
|
+
const dy = pos.y - startPointer.y;
|
|
447
|
+
if (this._prop.mode === 'gaussian') {
|
|
448
|
+
this._prop.mean = startMean + dx * this.dragScaleX;
|
|
449
|
+
this._prop.sigma = Math.max(0.01, startSigma + (-dy) * this.dragScaleY * (this.getMaxX() - this.getMinX()));
|
|
450
|
+
}
|
|
451
|
+
if (this._prop.mode === 'sigmoid') {
|
|
452
|
+
this._prop.x0 = startX0 + dx * this.dragScaleX;
|
|
453
|
+
this._prop.k = Math.max(0.1, startK + (-dy) * this.dragScaleY * 50);
|
|
454
|
+
}
|
|
455
|
+
this._prop.line = this.computeLine();
|
|
456
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
457
|
+
(_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
|
|
458
|
+
});
|
|
459
|
+
this.stage.on('mouseup touchend', () => {
|
|
460
|
+
dragging = false;
|
|
461
|
+
startPointer = null;
|
|
462
|
+
this.stage.container().style.cursor = 'default';
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
addSpecialHandle(width, height) {
|
|
466
|
+
var _a, _b;
|
|
467
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
468
|
+
if (this._prop.mode === 'freeform')
|
|
469
|
+
return;
|
|
470
|
+
const minX = this.getMinX();
|
|
471
|
+
const maxX = this.getMaxX();
|
|
472
|
+
const mapper = new CoordMapper(minX, maxX, width, height);
|
|
473
|
+
let x = (minX + maxX) / 2;
|
|
474
|
+
let y = 0.5;
|
|
475
|
+
if (this._prop.mode === 'gaussian') {
|
|
476
|
+
x = (_a = this._prop.mean) !== null && _a !== void 0 ? _a : (minX + maxX) / 2;
|
|
477
|
+
y = 1;
|
|
478
|
+
}
|
|
479
|
+
else if (this._prop.mode === 'sigmoid') {
|
|
480
|
+
x = (_b = this._prop.x0) !== null && _b !== void 0 ? _b : (minX + maxX) / 2;
|
|
481
|
+
y = 0.5;
|
|
482
|
+
}
|
|
483
|
+
const coords = mapper.toCanvasCoords([x, y]);
|
|
484
|
+
if (!this.specialHandle) {
|
|
485
|
+
this.specialHandle = new _konva.Circle({
|
|
486
|
+
x: coords.x,
|
|
487
|
+
y: coords.y,
|
|
488
|
+
radius: 7,
|
|
489
|
+
fill: COLORS.handle,
|
|
490
|
+
draggable: true,
|
|
491
|
+
hitStrokeWidth: 15,
|
|
492
|
+
});
|
|
493
|
+
this.specialHandle.on('dragmove', (evt) => {
|
|
494
|
+
var _a, _b;
|
|
495
|
+
const pos = evt.target.position();
|
|
496
|
+
const data = mapper.toDataCoords(pos.x, pos.y);
|
|
497
|
+
if (this._prop.mode === 'gaussian') {
|
|
498
|
+
this._prop.mean = data.x;
|
|
499
|
+
this._prop.sigma = Math.max(0.01, Math.abs(data.y - 1));
|
|
500
|
+
}
|
|
501
|
+
else if (this._prop.mode === 'sigmoid') {
|
|
502
|
+
this._prop.x0 = data.x;
|
|
503
|
+
this._prop.k = clamp(Math.abs(data.y - 0.5) * 30, 0.1, 30);
|
|
504
|
+
}
|
|
505
|
+
this._prop.line = this.computeLine();
|
|
506
|
+
(_a = this.redrawFn) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
507
|
+
(_b = this.onParamsChanged) === null || _b === void 0 ? void 0 : _b.call(this, this._prop);
|
|
508
|
+
});
|
|
509
|
+
this.layer.add(this.specialHandle);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
if (!this.specialHandle.getLayer())
|
|
513
|
+
this.layer.add(this.specialHandle);
|
|
514
|
+
this.specialHandle.position(coords);
|
|
515
|
+
}
|
|
516
|
+
this.layer.batchDraw();
|
|
517
|
+
}
|
|
518
|
+
showPointEditor(dataIndex, clientX, clientY) {
|
|
519
|
+
const point = this._prop.line[dataIndex];
|
|
520
|
+
const xInput = ui.input.float('X', { value: point[0], min: this.getMinX(), max: this.getMaxX(), format: '#0.00', step: 0.01 });
|
|
521
|
+
const yInput = ui.input.float('Y', { value: point[1], min: 0, max: 1, format: '#0.00', step: 0.01 });
|
|
522
|
+
const close = () => {
|
|
523
|
+
content.removeEventListener('keydown', onKey);
|
|
524
|
+
popup.remove();
|
|
525
|
+
};
|
|
526
|
+
const apply = () => {
|
|
527
|
+
const x = xInput.value;
|
|
528
|
+
const y = yInput.value;
|
|
529
|
+
if (x == null || y == null || isNaN(x) || isNaN(y))
|
|
530
|
+
return;
|
|
531
|
+
this._prop.line[dataIndex] = [x, y];
|
|
532
|
+
this.redrawAll();
|
|
533
|
+
};
|
|
534
|
+
const onKey = (e) => {
|
|
535
|
+
if (e.key === 'Enter') {
|
|
536
|
+
apply();
|
|
537
|
+
close();
|
|
538
|
+
}
|
|
539
|
+
if (e.key === 'Escape')
|
|
540
|
+
close();
|
|
541
|
+
};
|
|
542
|
+
const content = ui.inputs([xInput, yInput]);
|
|
543
|
+
content.style.overflow = 'hidden';
|
|
544
|
+
content.addEventListener('keydown', onKey);
|
|
545
|
+
const rootRect = this.root.getBoundingClientRect();
|
|
546
|
+
const popup = ui.showPopup(content, this.root, { dx: clientX - rootRect.left, dy: clientY - rootRect.bottom, smart: false });
|
|
547
|
+
}
|
|
548
|
+
setRange(min, max) {
|
|
549
|
+
const oldMin = this.getMinX();
|
|
550
|
+
const oldMax = this.getMaxX();
|
|
551
|
+
const oldRange = oldMax - oldMin;
|
|
552
|
+
const newRange = max - min;
|
|
553
|
+
if (oldRange !== 0 && newRange !== 0) {
|
|
554
|
+
const scale = newRange / oldRange;
|
|
555
|
+
const remap = (x) => min + (x - oldMin) * scale;
|
|
556
|
+
if (this._prop.mean != null)
|
|
557
|
+
this._prop.mean = remap(this._prop.mean);
|
|
558
|
+
if (this._prop.sigma != null)
|
|
559
|
+
this._prop.sigma *= scale;
|
|
560
|
+
if (this._prop.x0 != null)
|
|
561
|
+
this._prop.x0 = remap(this._prop.x0);
|
|
562
|
+
if (this._prop.k != null)
|
|
563
|
+
this._prop.k /= scale;
|
|
564
|
+
for (const p of this._prop.line)
|
|
565
|
+
p[0] = remap(p[0]);
|
|
566
|
+
if (this._prop.freeformLine) {
|
|
567
|
+
for (const p of this._prop.freeformLine)
|
|
568
|
+
p[0] = remap(p[0]);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
this._prop.min = min;
|
|
572
|
+
this._prop.max = max;
|
|
573
|
+
this.updateDragScales();
|
|
574
|
+
this.redrawAll(false);
|
|
575
|
+
}
|
|
576
|
+
setColumn(col) {
|
|
577
|
+
if (!col)
|
|
578
|
+
return;
|
|
579
|
+
const values = col.toList();
|
|
580
|
+
this.drawBars(values);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXBvLWxpbmUtZWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibXBvLWxpbmUtZWRpdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEtBQUssSUFBSSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUl0QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRTdCLElBQUksTUFBZ0MsQ0FBQztBQUVyQyxLQUFLLFVBQVUsUUFBUTtJQUNyQixJQUFJLENBQUMsTUFBTTtRQUNULE1BQU0sR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQzNDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFJRCxrQ0FBa0M7QUFDbEMsTUFBTSxjQUFjLEdBQUcsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUM7QUFDbEUsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBRXZCLE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO0lBQzVDLE1BQU0sRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUM5QyxPQUFPLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7SUFDL0MsU0FBUyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxL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R0FBRyxHQUFHLENBQUM7UUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELFNBQVMsQ0FBQyxHQUFxQjtRQUM3QixJQUFJLENBQUMsR0FBRztZQUNOLE9BQU87UUFFVCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5pbXBvcnQgdHlwZSBLb252YSBmcm9tICdrb252YSc7XG5pbXBvcnQge0Rlc2lyYWJpbGl0eUxpbmUsIE51bWVyaWNhbERlc2lyYWJpbGl0eX0gZnJvbSAnLi4vbXBvJztcbmltcG9ydCB7U3ViamVjdH0gZnJvbSAncnhqcyc7XG5cbmxldCBfa29udmE6IHR5cGVvZiBLb252YSB8IHVuZGVmaW5lZDtcblxuYXN5bmMgZnVuY3Rpb24gZ2V0S29udmEoKTogUHJvbWlzZTx0eXBlb2YgS29udmE+IHtcbiAgaWYgKCFfa29udmEpXG4gICAgX2tvbnZhID0gKGF3YWl0IGltcG9ydCgna29udmEnKSkuZGVmYXVsdDtcbiAgcmV0dXJuIF9rb252YTtcbn1cblxudHlwZSBQb2ludCA9IFtudW1iZXIsIG51bWJlcl07XG5cbi8vIENvbnN0YW50cyBmb3IgdGhlIGVkaXRvciBsYXlvdXRcbmNvbnN0IEVESVRPUl9QQURESU5HID0ge3RvcDogMTAsIHJpZ2h0OiAxMCwgYm90dG9tOiAyMCwgbGVmdDogMzB9O1xuY29uc3QgUE9JTlRfUkFESVVTID0gMztcblxuY29uc3QgQ09MT1JTID0ge1xuICBsaW5lOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3IuZmlsdGVyZWRSb3dzKSxcbiAgaGFuZGxlOiBERy5Db2xvci50b0h0bWwoREcuQ29sb3Iuc2VsZWN0ZWRSb3dzKSxcbiAgYmFyRmlsbDogREcuQ29sb3IudG9IdG1sKERHLkNvbG9yLmhpc3RvZ3JhbUJhciksXG4gIGJhclN0cm9rZTogREcuQ29sb3IudG9IdG1sKERHLkNvbG9yLmxpZ2h0R3JheSksXG59O1xuXG5jbGFzcyBDb29yZE1hcHBlciB7XG4gIHByaXZhdGUgcGxvdFdpZHRoOiBudW1iZXI7XG4gIHByaXZhdGUgcGxvdEhlaWdodDogbnVtYmVyO1xuICBwcml2YXRlIHNjYWxlWDogbnVtYmVyO1xuICBwcml2YXRlIHNjYWxlWTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbWluWDogbnVtYmVyLFxuICAgIHByaXZhdGUgbWF4WDogbnVtYmVyLFxuICAgIHByaXZhdGUgd2lkdGg6IG51bWJlcixcbiAgICBwcml2YXRlIGhlaWdodDogbnVtYmVyLFxuICApIHtcbiAgICB0aGlzLnBsb3RXaWR0aCA9IHdpZHRoIC0gRURJVE9SX1BBRERJTkcubGVmdCAtIEVESVRPUl9QQURESU5HLnJpZ2h0O1xuICAgIHRoaXMucGxvdEhlaWdodCA9IGhlaWdodCAtIEVESVRPUl9QQURESU5HLnRvcCAtIEVESVRPUl9QQURESU5HLmJvdHRvbTtcbiAgICB0aGlzLnNjYWxlWCA9ICh0aGlzLm1heFggLSB0aGlzLm1pblggPT09IDApID8gMSA6IHRoaXMucGxvdFdpZHRoIC8gKHRoaXMubWF4WCAtIHRoaXMubWluWCk7XG4gICAgdGhpcy5zY2FsZVkgPSB0aGlzLnBsb3RIZWlnaHQ7XG4gIH1cblxuICB0b0NhbnZhc0Nvb3JkcyhwOiBQb2ludCk6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0ge1xuICAgIGNvbnN0IGNhbnZhc1ggPSBFRElUT1JfUEFERElORy5sZWZ0ICsgKHBbMF0gLSB0aGlzLm1pblgpICogdGhpcy5zY2FsZVg7XG4gICAgY29uc3QgY2FudmFzWSA9IEVESVRPUl9QQURESU5HLnRvcCArIHRoaXMucGxvdEhlaWdodCAtIChwWzFdICogdGhpcy5zY2FsZVkpO1xuXG4gICAgcmV0dXJuIHt4OiBjYW52YXNYLCB5OiBjYW52YXNZfTtcbiAgfVxuXG4gIHRvRGF0YUNvb3JkcyhjYW52YXNYOiBudW1iZXIsIGNhbnZhc1k6IG51bWJlcik6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0ge1xuICAgIGxldCBkYXRhWCA9IHRoaXMubWluWCArIChjYW52YXNYIC0gRURJVE9SX1BBRERJTkcubGVmdCkgLyB0aGlzLnNjYWxlWDtcbiAgICBsZXQgZGF0YVkgPSAoRURJVE9SX1BBRERJTkcudG9wICsgdGhpcy5wbG90SGVpZ2h0IC0gY2FudmFzWSkgLyB0aGlzLnNjYWxlWTtcblxuICAgIGRhdGFYID0gTWF0aC5tYXgodGhpcy5taW5YLCBNYXRoLm1pbih0aGlzLm1heFgsIGRhdGFYKSk7XG4gICAgZGF0YVkgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBkYXRhWSkpO1xuXG4gICAgcmV0dXJuIHt4OiBkYXRhWCwgeTogZGF0YVl9O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNcG9EZXNpcmFiaWxpdHlMaW5lRWRpdG9yIHtcbiAgcm9vdCA9IHVpLmRpdigpO1xuICBvbkNoYW5nZWQgPSBuZXcgU3ViamVjdDxEZXNpcmFiaWxpdHlMaW5lPigpO1xuICBzdXBwb3J0c01vZGVEaWFsb2c6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIHByaXZhdGUgX3Byb3A6IE51bWVyaWNhbERlc2lyYWJpbGl0eTtcbiAgcHJpdmF0ZSBiYXJzTGF5ZXI/OiBLb252YS5MYXllcjtcbiAgcHJpdmF0ZSBwZW5kaW5nQmFyVmFsdWVzPzogbnVtYmVyW107XG5cbiAgcHJpdmF0ZSBzdGFnZT86IEtvbnZhLlN0YWdlO1xuICBwcml2YXRlIGxheWVyPzogS29udmEuTGF5ZXI7XG5cbiAgcHJpdmF0ZSBrb252YUxpbmU/OiBLb252YS5MaW5lO1xuICBwcml2YXRlIHBvaW50c0dyb3VwPzogS29udmEuR3JvdXA7XG4gIHByaXZhdGUgYmFyVmFsdWVzPzogbnVtYmVyW107XG5cbiAgcHJpdmF0ZSByZWRyYXdGbiE6IChub3RpZnk/OiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgc3BlY2lhbEhhbmRsZT86IEtvbnZhLkNpcmNsZTtcbiAgb25QYXJhbXNDaGFuZ2VkPzogKHByb3A6IE51bWVyaWNhbERlc2lyYWJpbGl0eSkgPT4gdm9pZDtcblxuICAvLyBGbGFnIHRvIHByZXZlbnQgdG91Y2hwYWQgcmlnaHQtY2xpY2sgZnJvbSBhZGRpbmcgYSBuZXcgcG9pbnRcbiAgcHJpdmF0ZSBpZ25vcmVOZXh0Q2xpY2sgPSBmYWxzZTtcbiAgcHJpdmF0ZSBkcmFnU2NhbGVYID0gMDtcbiAgcHJpdmF0ZSBkcmFnU2NhbGVZID0gMDtcbiAgcHJpdmF0ZSBfd2lkdGg6IG51bWJlcjtcbiAgcHJpdmF0ZSBfaGVpZ2h0OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocHJvcDogTnVtZXJpY2FsRGVzaXJhYmlsaXR5LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHRoaXMuX3Byb3AgPSBwcm9wO1xuICAgIHRoaXMuX3dpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5faGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMuZW5zdXJlRGVmYXVsdExpbmUoKTtcbiAgICB0aGlzLnJvb3Quc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgdGhpcy5yb290LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgdGhpcy5yb290LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcblxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmluaXRLb252YSh3aWR0aCwgaGVpZ2h0KSk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZURlZmF1bHRMaW5lKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wcm9wLmxpbmUubGVuZ3RoID4gMClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG1pbiA9IHRoaXMuX3Byb3AubWluID8/IDA7XG4gICAgY29uc3QgbWF4ID0gdGhpcy5fcHJvcC5tYXggPz8gMTtcbiAgICB0aGlzLl9wcm9wLmxpbmUgPSBbW21pbiwgMC41XSwgW21heCwgMC41XV07XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURyYWdTY2FsZXMoKTogdm9pZCB7XG4gICAgY29uc3QgcGxvdFdpZHRoID0gdGhpcy5fd2lkdGggLSBFRElUT1JfUEFERElORy5sZWZ0IC0gRURJVE9SX1BBRERJTkcucmlnaHQ7XG4gICAgY29uc3QgcGxvdEhlaWdodCA9IHRoaXMuX2hlaWdodCAtIEVESVRPUl9QQURESU5HLnRvcCAtIEVESVRPUl9QQURESU5HLmJvdHRvbTtcbiAgICB0aGlzLmRyYWdTY2FsZVggPSAodGhpcy5nZXRNYXhYKCkgLSB0aGlzLmdldE1pblgoKSkgLyBwbG90V2lkdGg7XG4gICAgdGhpcy5kcmFnU2NhbGVZID0gMSAvIHBsb3RIZWlnaHQ7XG4gIH1cblxuICBwcml2YXRlIGlzSW5QbG90QXJlYShwb3M6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHBvcy54ID49IEVESVRPUl9QQURESU5HLmxlZnQgJiZcbiAgICAgIHBvcy54IDw9IHdpZHRoIC0gRURJVE9SX1BBRERJTkcucmlnaHQgJiZcbiAgICAgIHBvcy55ID49IEVESVRPUl9QQURESU5HLnRvcCAmJlxuICAgICAgcG9zLnkgPD0gaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdEtvbnZhKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnJvb3QucGFyZW50RWxlbWVudCkge1xuICAgICAgY29uc29sZS53YXJuKCdLb252YSBjb250YWluZXIgbm90IGF0dGFjaGVkIHRvIERPTSB5ZXQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgS29udmEgPSBhd2FpdCBnZXRLb252YSgpO1xuICAgIHRoaXMuYmFyc0xheWVyID0gbmV3IEtvbnZhLkxheWVyKCk7XG5cbiAgICB0aGlzLnN0YWdlID0gbmV3IEtvbnZhLlN0YWdlKHtcbiAgICAgIGNvbnRhaW5lcjogdGhpcy5yb290LFxuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWdlLmFkZCh0aGlzLmJhcnNMYXllcik7XG4gICAgdGhpcy5sYXllciA9IG5ldyBLb252YS5MYXllcigpO1xuICAgIHRoaXMuc3RhZ2UuYWRkKHRoaXMubGF5ZXIpO1xuXG4gICAgY29uc3QgbWluWCA9IHRoaXMuZ2V0TWluWCgpO1xuICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgIC8vIC0tLSBEcmF3IEF4ZXMgLS0tXG4gICAgdGhpcy5kcmF3QXhlcyhtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIC8vIC0tLSBEcmF3IExpbmUgYW5kIFBvaW50cyAtLS1cbiAgICB0aGlzLmtvbnZhTGluZSA9IG5ldyBLb252YS5MaW5lKHtcbiAgICAgIHBvaW50czogW10sXG4gICAgICBzdHJva2U6IENPTE9SUy5saW5lLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBsaW5lQ2FwOiAncm91bmQnLFxuICAgICAgbGluZUpvaW46ICdyb3VuZCcsXG4gICAgfSk7XG4gICAgdGhpcy5sYXllci5hZGQodGhpcy5rb252YUxpbmUpO1xuXG4gICAgdGhpcy5wb2ludHNHcm91cCA9IG5ldyBLb252YS5Hcm91cCgpO1xuICAgIHRoaXMubGF5ZXIuYWRkKHRoaXMucG9pbnRzR3JvdXApO1xuXG4gICAgLy8gLS0tIFJlZHJhdyBGdW5jdGlvbiAtLS1cbiAgICB0aGlzLnJlZHJhd0ZuID0gKG5vdGlmeTogYm9vbGVhbiA9IHRydWUpID0+IHtcbiAgICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJyAmJiB0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSlcbiAgICAgICAgdGhpcy5fcHJvcC5saW5lID0gdGhpcy5fcHJvcC5mcmVlZm9ybUxpbmU7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgIT09ICdmcmVlZm9ybScpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSlcbiAgICAgICAgICB0aGlzLl9wcm9wLmZyZWVmb3JtTGluZSA9IFsuLi50aGlzLl9wcm9wLmxpbmVdO1xuICAgICAgICB0aGlzLl9wcm9wLmxpbmUgPSB0aGlzLmNvbXB1dGVMaW5lKCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucG9pbnRzR3JvdXAhLmRlc3Ryb3lDaGlsZHJlbigpO1xuICAgICAgY29uc3Qga29udmFQb2ludHM6IG51bWJlcltdID0gW107XG5cbiAgICAgIGNvbnN0IG1hcHBlciA9IG5ldyBDb29yZE1hcHBlcihtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGNvbnN0IHNvcnRlZEluZGljZXMgPSBbLi4udGhpcy5fcHJvcC5saW5lLmtleXMoKV1cbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IHRoaXMuX3Byb3AubGluZVthXVswXSAtIHRoaXMuX3Byb3AubGluZVtiXVswXSk7XG4gICAgICBjb25zdCBzb3J0ZWRMaW5lID0gc29ydGVkSW5kaWNlcy5tYXAoKGlkeCkgPT4gdGhpcy5fcHJvcC5saW5lW2lkeF0pO1xuXG4gICAgICBzb3J0ZWRMaW5lLmZvckVhY2goKHAsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNvb3JkcyA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcFswXSwgcFsxXV0pO1xuICAgICAgICBrb252YVBvaW50cy5wdXNoKGNvb3Jkcy54LCBjb29yZHMueSk7XG5cbiAgICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSAhPT0gJ2ZyZWVmb3JtJylcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcG9pbnRDaXJjbGUgPSBuZXcgS29udmEuQ2lyY2xlKHtcbiAgICAgICAgICB4OiBjb29yZHMueCxcbiAgICAgICAgICB5OiBjb29yZHMueSxcbiAgICAgICAgICByYWRpdXM6IFBPSU5UX1JBRElVUyxcbiAgICAgICAgICBmaWxsOiAnd2hpdGUnLFxuICAgICAgICAgIHN0cm9rZTogQ09MT1JTLmxpbmUsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgZHJhZ2dhYmxlOiB0cnVlLFxuICAgICAgICAgIGhpdFN0cm9rZVdpZHRoOiA1LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdG9yZSBpbmRleCBkaXJlY3RseSBvbiB0aGUgbm9kZSBmb3IgZWFzeSBhY2Nlc3NcbiAgICAgICAgcG9pbnRDaXJjbGUuc2V0QXR0cignX2RhdGFJbmRleCcsIHNvcnRlZEluZGljZXNbaW5kZXhdKTtcblxuICAgICAgICBwb2ludENpcmNsZS5vbignZHJhZ21vdmUnLCAoZXZ0KSA9PiB7XG4gICAgICAgICAgY29uc3QgY2lyY2xlID0gZXZ0LnRhcmdldCBhcyBLb252YS5DaXJjbGU7XG4gICAgICAgICAgY29uc3QgcG9zID0gY2lyY2xlLnBvc2l0aW9uKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gY2lyY2xlLmdldEF0dHIoJ19kYXRhSW5kZXgnKTtcbiAgICAgICAgICBjb25zdCBzb3J0ZWRQb3MgPSBzb3J0ZWRJbmRpY2VzLmluZGV4T2YoZGF0YUluZGV4KTtcblxuICAgICAgICAgIC8vIENvbnN0cmFpbiBkcmFnZ2luZyBob3Jpem9udGFsbHkgYmV0d2VlbiBuZWlnaGJvcnMgKG9yIGJvdW5kcylcbiAgICAgICAgICBjb25zdCBwcmV2WCA9IHNvcnRlZFBvcyA+IDAgPyB0aGlzLl9wcm9wLmxpbmVbc29ydGVkSW5kaWNlc1tzb3J0ZWRQb3MgLSAxXV1bMF0gOiBtaW5YO1xuICAgICAgICAgIGNvbnN0IG5leHRYID0gc29ydGVkUG9zIDwgc29ydGVkSW5kaWNlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtzb3J0ZWRJbmRpY2VzW3NvcnRlZFBvcyArIDFdXVswXSA6XG4gICAgICAgICAgICBtYXhYO1xuXG4gICAgICAgICAgLy8gQWRkIGEgc21hbGwgYnVmZmVyIHRvIGF2b2lkIHBvaW50cyBvdmVybGFwcGluZyBleGFjdGx5XG4gICAgICAgICAgY29uc3QgYnVmZmVyID0gKG1heFggLSBtaW5YID09PSAwKSA/IDAgOiAwLjAwMSAqIChtYXhYIC0gbWluWCk7IC8vIEF2b2lkIE5hTiBpZiBtaW5YID09PSBtYXhYXG4gICAgICAgICAgY29uc3QgbWluQ2FudmFzWCA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcHJldlggKyAoc29ydGVkUG9zID4gMCA/IGJ1ZmZlciA6IDApLCAwXSkueDtcbiAgICAgICAgICBjb25zdCBtYXhDYW52YXNYID0gbWFwcGVyLnRvQ2FudmFzQ29vcmRzKFtuZXh0WCAtIChzb3J0ZWRQb3MgPCBzb3J0ZWRJbmRpY2VzLmxlbmd0aCAtIDEgPyBidWZmZXIgOiAwKSwgMF0pLng7XG5cbiAgICAgICAgICBwb3MueCA9IE1hdGgubWF4KG1pbkNhbnZhc1gsIE1hdGgubWluKG1heENhbnZhc1gsIHBvcy54KSk7XG5cbiAgICAgICAgICBjb25zdCBwbG90VG9wID0gRURJVE9SX1BBRERJTkcudG9wO1xuICAgICAgICAgIGNvbnN0IHBsb3RCb3R0b20gPSBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b207XG4gICAgICAgICAgcG9zLnkgPSBNYXRoLm1heChwbG90VG9wLCBNYXRoLm1pbihwbG90Qm90dG9tLCBwb3MueSkpO1xuXG4gICAgICAgICAgY2lyY2xlLnBvc2l0aW9uKHBvcyk7XG5cbiAgICAgICAgICBjb25zdCBkYXRhQ29vcmRzID0gbWFwcGVyLnRvRGF0YUNvb3Jkcyhwb3MueCwgcG9zLnkpO1xuICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtkYXRhSW5kZXhdWzBdID0gZGF0YUNvb3Jkcy54O1xuICAgICAgICAgIHRoaXMuX3Byb3AubGluZVtkYXRhSW5kZXhdWzFdID0gZGF0YUNvb3Jkcy55O1xuXG4gICAgICAgICAgY29uc3QgY3VycmVudEtvbnZhUG9pbnRzID0gdGhpcy5fcHJvcC5saW5lLm1hcCgocERhdGEsIGlkeCkgPT4ge1xuICAgICAgICAgICAgLy8gVXNlIGRyYWdnZWQgY2lyY2xlIHBvc2l0aW9uIGRpcmVjdGx5IGZvciB0aGUgcG9pbnQgYmVpbmcgZHJhZ2dlZFxuICAgICAgICAgICAgaWYgKGlkeCA9PT0gZGF0YUluZGV4KVxuICAgICAgICAgICAgICByZXR1cm4gW3Bvcy54LCBwb3MueV07XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc3QgYyA9IG1hcHBlci50b0NhbnZhc0Nvb3JkcyhbcERhdGFbMF0sIHBEYXRhWzFdXSk7XG4gICAgICAgICAgICAgIHJldHVybiBbYy54LCBjLnldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLmZsYXQoKTtcblxuICAgICAgICAgIHRoaXMua29udmFMaW5lIS5wb2ludHMoY3VycmVudEtvbnZhUG9pbnRzKTtcbiAgICAgICAgICB0aGlzLmxheWVyIS5iYXRjaERyYXcoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2RyYWdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fcHJvcC5saW5lLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKTtcbiAgICAgICAgICB0aGlzLnJlZHJhd0ZuPy4oKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2NvbnRleHRtZW51JywgKGV2dCkgPT4ge1xuICAgICAgICAgIGV2dC5ldnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBpZiAodGhpcy5fcHJvcC5saW5lLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICBncm9rLnNoZWxsLndhcm5pbmcoJ0Nhbm5vdCByZW1vdmUgcG9pbnRzLCBtaW5pbXVtIG9mIDIgcmVxdWlyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5pZ25vcmVOZXh0Q2xpY2sgPSB0cnVlO1xuICAgICAgICAgIGNvbnN0IGNpcmNsZSA9IGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlO1xuICAgICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGNpcmNsZS5nZXRBdHRyKCdfZGF0YUluZGV4JykgYXMgbnVtYmVyO1xuXG4gICAgICAgICAgaWYgKGRhdGFJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fcHJvcC5taW4gPT0gbnVsbClcbiAgICAgICAgICAgICAgdGhpcy5fcHJvcC5taW4gPSB0aGlzLmdldE1pblgoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9wcm9wLm1heCA9PSBudWxsKVxuICAgICAgICAgICAgICB0aGlzLl9wcm9wLm1heCA9IHRoaXMuZ2V0TWF4WCgpO1xuICAgICAgICAgICAgdGhpcy5fcHJvcC5saW5lLnNwbGljZShkYXRhSW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5yZWRyYXdGbj8uKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBwb2ludENpcmNsZS5vbignbW91c2VlbnRlcicsIChldnQpID0+IHtcbiAgICAgICAgICB0aGlzLnN0YWdlIS5jb250YWluZXIoKS5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgICAgICAgY29uc3QgY2lyY2xlID0gZXZ0LnRhcmdldCBhcyBLb252YS5DaXJjbGU7XG4gICAgICAgICAgY29uc3QgcG9zID0gY2lyY2xlLnBvc2l0aW9uKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUNvb3JkcyA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcbiAgICAgICAgICBjb25zdCB0b29sdGlwVGV4dCA9IGBYOiAke2RhdGFDb29yZHMueC50b0ZpeGVkKDIpfSwgWTogJHtkYXRhQ29vcmRzLnkudG9GaXhlZCgyKX08YnI+PGJyPkRyYWcgdG8gbW92ZSwgZG91YmxlLWNsaWNrIHRvIGVkaXQsIHJpZ2h0LWNsaWNrIHRvIGRlbGV0ZWA7XG4gICAgICAgICAgdWkudG9vbHRpcC5zaG93KHRvb2x0aXBUZXh0LCBldnQuZXZ0LmNsaWVudFgsIGV2dC5ldnQuY2xpZW50WSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHBvaW50Q2lyY2xlLm9uKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICAgICAgICB1aS50b29sdGlwLmhpZGUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcG9pbnRDaXJjbGUub24oJ2RibGNsaWNrIGRibHRhcCcsIChldnQpID0+IHtcbiAgICAgICAgICB0aGlzLmlnbm9yZU5leHRDbGljayA9IHRydWU7XG4gICAgICAgICAgdWkudG9vbHRpcC5oaWRlKCk7XG4gICAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gKGV2dC50YXJnZXQgYXMgS29udmEuQ2lyY2xlKS5nZXRBdHRyKCdfZGF0YUluZGV4JykgYXMgbnVtYmVyO1xuICAgICAgICAgIHRoaXMuc2hvd1BvaW50RWRpdG9yKGRhdGFJbmRleCwgZXZ0LmV2dC5jbGllbnRYLCBldnQuZXZ0LmNsaWVudFkpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnBvaW50c0dyb3VwIS5hZGQocG9pbnRDaXJjbGUpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMua29udmFMaW5lIS5wb2ludHMoa29udmFQb2ludHMpO1xuICAgICAgdGhpcy5sYXllciEuYmF0Y2hEcmF3KCk7XG5cbiAgICAgIC8vIC0tLSBBZGQgc3BlY2lhbCBoYW5kbGUgKEdhdXNzaWFuIHBlYWsgLyBTaWdtb2lkIGluZmxlY3Rpb24pIC0tLVxuICAgICAgdGhpcy5hZGRTcGVjaWFsSGFuZGxlKHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgICBpZiAobm90aWZ5KVxuICAgICAgICB0aGlzLm9uQ2hhbmdlZC5uZXh0KHRoaXMuX3Byb3AubGluZSk7XG4gICAgfTtcblxuICAgIC8vIC0tLSBMZWZ0LWNsaWNrIHRvIEFkZCBQb2ludCAtLS1cbiAgICB0aGlzLnN0YWdlLm9uKCdjbGljayB0YXAnLCAoZXZ0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pZ25vcmVOZXh0Q2xpY2spIHtcbiAgICAgICAgdGhpcy5pZ25vcmVOZXh0Q2xpY2sgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZ0LnRhcmdldCBpbnN0YW5jZW9mIEtvbnZhLkNpcmNsZSB8fCBldnQuZXZ0LmJ1dHRvbiAhPT0gMClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlPy5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICAgIGNvbnN0IG1heFggPSB0aGlzLmdldE1heFgoKTtcblxuICAgICAgaWYgKCF0aGlzLmlzSW5QbG90QXJlYShwb3MsIHRoaXMuc3RhZ2UhLndpZHRoKCksIHRoaXMuc3RhZ2UhLmhlaWdodCgpKSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBtYXBwZXIgPSBuZXcgQ29vcmRNYXBwZXIobWluWCwgbWF4WCwgdGhpcy5zdGFnZSEud2lkdGgoKSwgdGhpcy5zdGFnZSEuaGVpZ2h0KCkpO1xuICAgICAgY29uc3QgZGF0YUNvb3JkcyA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcblxuICAgICAgdGhpcy5fcHJvcC5saW5lLnB1c2goW2RhdGFDb29yZHMueCwgZGF0YUNvb3Jkcy55XSk7XG4gICAgICB0aGlzLl9wcm9wLmxpbmUuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuICAgICAgdGhpcy5yZWRyYXdGbj8uKCk7XG4gICAgfSk7XG5cbiAgICAvLyBDdXJzb3IgY2hhbmdlXG4gICAgdGhpcy5zdGFnZS5vbignbW91c2Vtb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnN0YWdlKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlLmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSAhPT0gJ2ZyZWVmb3JtJykge1xuICAgICAgICBpZiAodGhpcy5pc0luUGxvdEFyZWEocG9zLCB3aWR0aCwgaGVpZ2h0KSlcbiAgICAgICAgICB0aGlzLnN0YWdlLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdncmFiJztcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRoaXMuc3RhZ2UuY29udGFpbmVyKCkuc3R5bGUuY3Vyc29yID0gJ2RlZmF1bHQnO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5zdGFnZS5vbignbW91c2VvdXQnLCAoKSA9PiB1aS50b29sdGlwLmhpZGUoKSk7XG5cbiAgICAvLyBFbmFibGUgY3VydmUgZHJhZyAoc21vb3RoKVxuICAgIHRoaXMuZW5hYmxlQ3VydmVEcmFnKHdpZHRoLCBoZWlnaHQpO1xuICAgIHRoaXMudXBkYXRlRHJhZ1NjYWxlcygpO1xuXG4gICAgLy8gSW5pdGlhbCBkcmF3XG4gICAgaWYgKHRoaXMucGVuZGluZ0JhclZhbHVlcykge1xuICAgICAgdGhpcy5kcmF3QmFycyh0aGlzLnBlbmRpbmdCYXJWYWx1ZXMpO1xuICAgICAgdGhpcy5wZW5kaW5nQmFyVmFsdWVzID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnJlZHJhd0ZuPy4oZmFsc2UpO1xuICB9XG5cbiAgZ2V0IGxpbmUoKTogRGVzaXJhYmlsaXR5TGluZSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb3AubGluZTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUxpbmUoKTogRGVzaXJhYmlsaXR5TGluZSB7XG4gICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJylcbiAgICAgIHJldHVybiB0aGlzLl9wcm9wLmxpbmU7XG5cbiAgICBjb25zdCBtaW5YID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3QgbWF4WCA9IHRoaXMuZ2V0TWF4WCgpO1xuICAgIGNvbnN0IG4gPSA2MDtcbiAgICBjb25zdCBsaW5lOiBEZXNpcmFiaWxpdHlMaW5lID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBuOyBpKyspIHtcbiAgICAgIGNvbnN0IHggPSBtaW5YICsgKG1heFggLSBtaW5YKSAqIChpIC8gbik7XG4gICAgICBsZXQgeSA9IDA7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdnYXVzc2lhbicpIHtcbiAgICAgICAgdGhpcy5fcHJvcC5tZWFuID8/PSAobWluWCArIG1heFgpIC8gMjtcbiAgICAgICAgdGhpcy5fcHJvcC5zaWdtYSA/Pz0gKG1heFggLSBtaW5YKSAvIDY7XG4gICAgICAgIGNvbnN0IG1lYW4gPSB0aGlzLl9wcm9wLm1lYW47XG4gICAgICAgIGNvbnN0IHNpZ21hID0gdGhpcy5fcHJvcC5zaWdtYTtcbiAgICAgICAgY29uc3QgeiA9ICh4IC0gbWVhbikgLyBzaWdtYTtcbiAgICAgICAgeSA9IE1hdGguZXhwKC0wLjUgKiB6ICogeik7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdzaWdtb2lkJykge1xuICAgICAgICB0aGlzLl9wcm9wLngwID8/PSAobWluWCArIG1heFgpIC8gMjtcbiAgICAgICAgdGhpcy5fcHJvcC5rID8/PSAxMDtcbiAgICAgICAgY29uc3QgeDAgPSB0aGlzLl9wcm9wLngwO1xuICAgICAgICBjb25zdCBrID0gdGhpcy5fcHJvcC5rO1xuICAgICAgICB5ID0gMSAvICgxICsgTWF0aC5leHAoLWsgKiAoeCAtIHgwKSkpO1xuICAgICAgfVxuXG4gICAgICBsaW5lLnB1c2goW3gsIHldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0F4ZXMobWluWDogbnVtYmVyLCBtYXhYOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgY29uc3QgYXhpc0NvbG9yID0gZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJy0tZ3JleS0yJykudHJpbSgpIHx8ICcjREJEQ0RGJztcbiAgICB0aGlzLmxheWVyIS5hZGQoXG4gICAgICBuZXcgX2tvbnZhIS5MaW5lKHtcbiAgICAgICAgcG9pbnRzOiBbRURJVE9SX1BBRERJTkcubGVmdCwgaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tLCB3aWR0aCAtIEVESVRPUl9QQURESU5HLnJpZ2h0LCBoZWlnaHQgLSBFRElUT1JfUEFERElORy5ib3R0b21dLFxuICAgICAgICBzdHJva2U6IGF4aXNDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICB9KSxcbiAgICAgIG5ldyBfa29udmEhLkxpbmUoe1xuICAgICAgICBwb2ludHM6IFtFRElUT1JfUEFERElORy5sZWZ0LCBFRElUT1JfUEFERElORy50b3AsIEVESVRPUl9QQURESU5HLmxlZnQsIGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbV0sXG4gICAgICAgIHN0cm9rZTogYXhpc0NvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgIH0pLFxuICAgICAgbmV3IF9rb252YSEuVGV4dCh7eDogRURJVE9SX1BBRERJTkcubGVmdCwgeTogaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcuYm90dG9tICsgMywgdGV4dDogbWluWC50b0ZpeGVkKDEpLCBmb250U2l6ZTogOSwgZmlsbDogJ2dyZXknfSksXG4gICAgICBuZXcgX2tvbnZhIS5UZXh0KHt4OiB3aWR0aCAtIEVESVRPUl9QQURESU5HLnJpZ2h0IC0gMTUsIHk6IGhlaWdodCAtIEVESVRPUl9QQURESU5HLmJvdHRvbSArIDMsIHRleHQ6IG1heFgudG9GaXhlZCgxKSwgZm9udFNpemU6IDksIGZpbGw6ICdncmV5J30pLFxuICAgICk7XG4gIH1cblxuICBnZXRNaW5YKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb3AubWluID8/IE1hdGgubWluKC4uLnRoaXMuX3Byb3AubGluZS5tYXAoKHApID0+IHBbMF0pKSA/PyAwO1xuICB9XG5cbiAgZ2V0TWF4WCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9wcm9wLm1heCA/PyBNYXRoLm1heCguLi50aGlzLl9wcm9wLmxpbmUubWFwKChwKSA9PiBwWzBdKSkgPz8gMTtcbiAgfVxuXG4gIGdldERlZmF1bHRNZWFuKCk6IG51bWJlciB7XG4gICAgcmV0dXJuICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gIH1cblxuICBnZXREZWZhdWx0U2lnbWEoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMC4wMSwgKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gNik7XG4gIH1cblxuICBnZXREZWZhdWx0WDAoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMuZ2V0TWluWCgpICsgdGhpcy5nZXRNYXhYKCkpIC8gMjtcbiAgfVxuXG4gIGdldERlZmF1bHRLKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDEwO1xuICB9XG5cbiAgcmVkcmF3QWxsKG5vdGlmeTogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3RhZ2UgfHwgIXRoaXMubGF5ZXIgfHwgIXRoaXMucmVkcmF3Rm4pXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuc3RhZ2Uud2lkdGgoKTtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN0YWdlLmhlaWdodCgpO1xuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICB0aGlzLmxheWVyLmRlc3Ryb3lDaGlsZHJlbigpO1xuXG4gICAgdGhpcy5kcmF3QXhlcyhtaW5YLCBtYXhYLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIHRoaXMubGF5ZXIuYWRkKHRoaXMua29udmFMaW5lISwgdGhpcy5wb2ludHNHcm91cCEpO1xuXG4gICAgdGhpcy5yZWRyYXdGbihub3RpZnkpO1xuXG4gICAgaWYgKHRoaXMuYmFyVmFsdWVzKVxuICAgICAgdGhpcy5kcmF3QmFycygpO1xuICB9XG5cbiAgZHJhd0JhcnModmFsdWVzPzogbnVtYmVyW10pIHtcbiAgICBpZiAodmFsdWVzKVxuICAgICAgdGhpcy5iYXJWYWx1ZXMgPSB2YWx1ZXM7XG5cbiAgICBpZiAoIXRoaXMuYmFyc0xheWVyKSB7XG4gICAgICB0aGlzLnBlbmRpbmdCYXJWYWx1ZXMgPSB2YWx1ZXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYmFyc0xheWVyLmRlc3Ryb3lDaGlsZHJlbigpO1xuXG4gICAgaWYgKCF0aGlzLmJhclZhbHVlcyB8fCB0aGlzLmJhclZhbHVlcy5sZW5ndGggPT09IDApXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCBzdGFnZSA9IHRoaXMuYmFyc0xheWVyLmdldFN0YWdlKCk7XG4gICAgaWYgKCFzdGFnZSkge1xuICAgICAgdGhpcy5wZW5kaW5nQmFyVmFsdWVzID0gdmFsdWVzO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdpZHRoID0gc3RhZ2Uud2lkdGgoKTtcbiAgICBjb25zdCBoZWlnaHQgPSBzdGFnZS5oZWlnaHQoKTtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG5cbiAgICBpZiAobWF4WCA9PT0gbWluWClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG51bUJpbnMgPSAyMDtcbiAgICBjb25zdCBwbG90V2lkdGggPSB3aWR0aCAtIEVESVRPUl9QQURESU5HLmxlZnQgLSBFRElUT1JfUEFERElORy5yaWdodDtcbiAgICBjb25zdCBwbG90SGVpZ2h0ID0gaGVpZ2h0IC0gRURJVE9SX1BBRERJTkcudG9wIC0gRURJVE9SX1BBRERJTkcuYm90dG9tO1xuXG4gICAgY29uc3QgYmluV2lkdGggPSBNYXRoLm1heCgxZS05LCAobWF4WCAtIG1pblgpIC8gbnVtQmlucyk7XG4gICAgY29uc3QgYmlucyA9IG5ldyBBcnJheShudW1CaW5zKS5maWxsKDApO1xuXG4gICAgKHRoaXMuYmFyVmFsdWVzID8/IFtdKS5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICBjb25zdCBpZHggPSBNYXRoLm1pbihNYXRoLmZsb29yKCh2IC0gbWluWCkgLyBiaW5XaWR0aCksIG51bUJpbnMgLSAxKTtcbiAgICAgIGJpbnNbaWR4XSsrO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbWF4Q291bnQgPSBNYXRoLm1heCguLi5iaW5zKSB8fCAxO1xuXG4gICAgYmlucy5mb3JFYWNoKChjb3VudCwgaSkgPT4ge1xuICAgICAgY29uc3QgYmFyWCA9IEVESVRPUl9QQURESU5HLmxlZnQgKyAoaSAqIGJpbldpZHRoIC8gKG1heFggLSBtaW5YKSkgKiBwbG90V2lkdGg7XG4gICAgICBjb25zdCBiYXJXID0gKGJpbldpZHRoIC8gKG1heFggLSBtaW5YKSkgKiBwbG90V2lkdGggLSAxO1xuICAgICAgY29uc3QgYmFySCA9IChjb3VudCAvIG1heENvdW50KSAqIHBsb3RIZWlnaHQ7XG5cbiAgICAgIGNvbnN0IHJlY3QgPSBuZXcgX2tvbnZhIS5SZWN0KHtcbiAgICAgICAgeDogYmFyWCxcbiAgICAgICAgeTogRURJVE9SX1BBRERJTkcudG9wICsgcGxvdEhlaWdodCAtIGJhckgsXG4gICAgICAgIHdpZHRoOiBiYXJXLFxuICAgICAgICBoZWlnaHQ6IGJhckgsXG4gICAgICAgIGZpbGw6IENPTE9SUy5iYXJGaWxsLFxuICAgICAgICBvcGFjaXR5OiAwLjI1LFxuICAgICAgICBzdHJva2U6IENPTE9SUy5iYXJTdHJva2UsXG4gICAgICAgIHN0cm9rZVdpZHRoOiAwLjUsXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5iYXJzTGF5ZXIhLmFkZChyZWN0KTtcbiAgICB9KTtcblxuICAgIHRoaXMuYmFyc0xheWVyIS5iYXRjaERyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5hYmxlQ3VydmVEcmFnKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLnN0YWdlKVxuICAgICAgcmV0dXJuO1xuXG4gICAgbGV0IGRyYWdnaW5nID0gZmFsc2U7XG4gICAgbGV0IHN0YXJ0UG9pbnRlcjoge3g6IG51bWJlciwgeTogbnVtYmVyfSB8IG51bGwgPSBudWxsO1xuICAgIGxldCBzdGFydE1lYW4gPSAwO1xuICAgIGxldCBzdGFydFNpZ21hID0gMDtcbiAgICBsZXQgc3RhcnRYMCA9IDA7XG4gICAgbGV0IHN0YXJ0SyA9IDA7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZWRvd24gdG91Y2hzdGFydCcsIChldnQpID0+IHtcbiAgICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdmcmVlZm9ybScpXG4gICAgICAgIHJldHVybjtcbiAgICAgIGlmICghZXZ0LmV2dClcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3MgPSB0aGlzLnN0YWdlIS5nZXRQb2ludGVyUG9zaXRpb24oKTtcbiAgICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGlmICghdGhpcy5pc0luUGxvdEFyZWEocG9zLCB3aWR0aCwgaGVpZ2h0KSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBkcmFnZ2luZyA9IHRydWU7XG4gICAgICBzdGFydFBvaW50ZXIgPSBwb3M7XG5cbiAgICAgIHN0YXJ0TWVhbiA9IHRoaXMuX3Byb3AubWVhbiA/PyAodGhpcy5nZXRNaW5YKCkgKyB0aGlzLmdldE1heFgoKSkgLyAyO1xuICAgICAgc3RhcnRTaWdtYSA9IHRoaXMuX3Byb3Auc2lnbWEgPz8gKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpIC8gNjtcbiAgICAgIHN0YXJ0WDAgPSB0aGlzLl9wcm9wLngwID8/ICh0aGlzLmdldE1pblgoKSArIHRoaXMuZ2V0TWF4WCgpKSAvIDI7XG4gICAgICBzdGFydEsgPSB0aGlzLl9wcm9wLmsgPz8gMTA7XG5cbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0YWdlLm9uKCdtb3VzZW1vdmUgdG91Y2htb3ZlJywgKGV2dCkgPT4ge1xuICAgICAgaWYgKCFkcmFnZ2luZyB8fCAhc3RhcnRQb2ludGVyKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuc3RhZ2UhLmdldFBvaW50ZXJQb3NpdGlvbigpO1xuICAgICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgY29uc3QgZHggPSBwb3MueCAtIHN0YXJ0UG9pbnRlci54O1xuICAgICAgY29uc3QgZHkgPSBwb3MueSAtIHN0YXJ0UG9pbnRlci55O1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgIHRoaXMuX3Byb3AubWVhbiA9IHN0YXJ0TWVhbiArIGR4ICogdGhpcy5kcmFnU2NhbGVYO1xuICAgICAgICB0aGlzLl9wcm9wLnNpZ21hID0gTWF0aC5tYXgoMC4wMSwgc3RhcnRTaWdtYSArICgtZHkpICogdGhpcy5kcmFnU2NhbGVZICogKHRoaXMuZ2V0TWF4WCgpIC0gdGhpcy5nZXRNaW5YKCkpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICAgIHRoaXMuX3Byb3AueDAgPSBzdGFydFgwICsgZHggKiB0aGlzLmRyYWdTY2FsZVg7XG4gICAgICAgIHRoaXMuX3Byb3AuayA9IE1hdGgubWF4KDAuMSwgc3RhcnRLICsgKC1keSkgKiB0aGlzLmRyYWdTY2FsZVkgKiA1MCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3Byb3AubGluZSA9IHRoaXMuY29tcHV0ZUxpbmUoKTtcbiAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgdGhpcy5vblBhcmFtc0NoYW5nZWQ/Lih0aGlzLl9wcm9wKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhZ2Uub24oJ21vdXNldXAgdG91Y2hlbmQnLCAoKSA9PiB7XG4gICAgICBkcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgc3RhcnRQb2ludGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc3RhZ2UhLmNvbnRhaW5lcigpLnN0eWxlLmN1cnNvciA9ICdkZWZhdWx0JztcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkU3BlY2lhbEhhbmRsZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIGNvbnN0IGNsYW1wID0gKHY6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSA9PiBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgdikpO1xuXG4gICAgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ2ZyZWVmb3JtJylcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IG1pblggPSB0aGlzLmdldE1pblgoKTtcbiAgICBjb25zdCBtYXhYID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3QgbWFwcGVyID0gbmV3IENvb3JkTWFwcGVyKG1pblgsIG1heFgsIHdpZHRoLCBoZWlnaHQpO1xuXG4gICAgbGV0IHggPSAobWluWCArIG1heFgpIC8gMjtcbiAgICBsZXQgeSA9IDAuNTtcblxuICAgIGlmICh0aGlzLl9wcm9wLm1vZGUgPT09ICdnYXVzc2lhbicpIHtcbiAgICAgIHggPSB0aGlzLl9wcm9wLm1lYW4gPz8gKG1pblggKyBtYXhYKSAvIDI7XG4gICAgICB5ID0gMTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3Byb3AubW9kZSA9PT0gJ3NpZ21vaWQnKSB7XG4gICAgICB4ID0gdGhpcy5fcHJvcC54MCA/PyAobWluWCArIG1heFgpIC8gMjtcbiAgICAgIHkgPSAwLjU7XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRzID0gbWFwcGVyLnRvQ2FudmFzQ29vcmRzKFt4LCB5XSk7XG5cbiAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZSkge1xuICAgICAgdGhpcy5zcGVjaWFsSGFuZGxlID0gbmV3IF9rb252YSEuQ2lyY2xlKHtcbiAgICAgICAgeDogY29vcmRzLngsXG4gICAgICAgIHk6IGNvb3Jkcy55LFxuICAgICAgICByYWRpdXM6IDcsXG4gICAgICAgIGZpbGw6IENPTE9SUy5oYW5kbGUsXG4gICAgICAgIGRyYWdnYWJsZTogdHJ1ZSxcbiAgICAgICAgaGl0U3Ryb2tlV2lkdGg6IDE1LFxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5vbignZHJhZ21vdmUnLCAoZXZ0KSA9PiB7XG4gICAgICAgIGNvbnN0IHBvcyA9IGV2dC50YXJnZXQucG9zaXRpb24oKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG1hcHBlci50b0RhdGFDb29yZHMocG9zLngsIHBvcy55KTtcblxuICAgICAgICBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnZ2F1c3NpYW4nKSB7XG4gICAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgPSBNYXRoLm1heCgwLjAxLCBNYXRoLmFicyhkYXRhLnkgLSAxKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fcHJvcC5tb2RlID09PSAnc2lnbW9pZCcpIHtcbiAgICAgICAgICB0aGlzLl9wcm9wLngwID0gZGF0YS54O1xuICAgICAgICAgIHRoaXMuX3Byb3AuayA9IGNsYW1wKE1hdGguYWJzKGRhdGEueSAtIDAuNSkgKiAzMCwgMC4xLCAzMCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcm9wLmxpbmUgPSB0aGlzLmNvbXB1dGVMaW5lKCk7XG4gICAgICAgIHRoaXMucmVkcmF3Rm4/LigpO1xuICAgICAgICB0aGlzLm9uUGFyYW1zQ2hhbmdlZD8uKHRoaXMuX3Byb3ApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMubGF5ZXIhLmFkZCh0aGlzLnNwZWNpYWxIYW5kbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuc3BlY2lhbEhhbmRsZS5nZXRMYXllcigpKVxuICAgICAgICB0aGlzLmxheWVyIS5hZGQodGhpcy5zcGVjaWFsSGFuZGxlKTtcbiAgICAgIHRoaXMuc3BlY2lhbEhhbmRsZS5wb3NpdGlvbihjb29yZHMpO1xuICAgIH1cbiAgICB0aGlzLmxheWVyIS5iYXRjaERyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1BvaW50RWRpdG9yKGRhdGFJbmRleDogbnVtYmVyLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHBvaW50ID0gdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF07XG4gICAgY29uc3QgeElucHV0ID0gdWkuaW5wdXQuZmxvYXQoJ1gnLCB7dmFsdWU6IHBvaW50WzBdLCBtaW46IHRoaXMuZ2V0TWluWCgpLCBtYXg6IHRoaXMuZ2V0TWF4WCgpLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcbiAgICBjb25zdCB5SW5wdXQgPSB1aS5pbnB1dC5mbG9hdCgnWScsIHt2YWx1ZTogcG9pbnRbMV0sIG1pbjogMCwgbWF4OiAxLCBmb3JtYXQ6ICcjMC4wMCcsIHN0ZXA6IDAuMDF9KTtcblxuICAgIGNvbnN0IGNsb3NlID0gKCkgPT4ge1xuICAgICAgY29udGVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpO1xuICAgICAgcG9wdXAucmVtb3ZlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGFwcGx5ID0gKCkgPT4ge1xuICAgICAgY29uc3QgeCA9IHhJbnB1dC52YWx1ZTtcbiAgICAgIGNvbnN0IHkgPSB5SW5wdXQudmFsdWU7XG4gICAgICBpZiAoeCA9PSBudWxsIHx8IHkgPT0gbnVsbCB8fCBpc05hTih4KSB8fCBpc05hTih5KSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fcHJvcC5saW5lW2RhdGFJbmRleF0gPSBbeCwgeV07XG4gICAgICB0aGlzLnJlZHJhd0FsbCgpO1xuICAgIH07XG5cbiAgICBjb25zdCBvbktleSA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgYXBwbHkoKTtcbiAgICAgICAgY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpXG4gICAgICAgIGNsb3NlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB1aS5pbnB1dHMoW3hJbnB1dCwgeUlucHV0XSk7XG4gICAgY29udGVudC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIGNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KTtcblxuICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5yb290LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHBvcHVwID0gdWkuc2hvd1BvcHVwKGNvbnRlbnQsIHRoaXMucm9vdCwge2R4OiBjbGllbnRYIC0gcm9vdFJlY3QubGVmdCwgZHk6IGNsaWVudFkgLSByb290UmVjdC5ib3R0b20sIHNtYXJ0OiBmYWxzZX0pO1xuICB9XG5cbiAgc2V0UmFuZ2UobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgb2xkTWluID0gdGhpcy5nZXRNaW5YKCk7XG4gICAgY29uc3Qgb2xkTWF4ID0gdGhpcy5nZXRNYXhYKCk7XG4gICAgY29uc3Qgb2xkUmFuZ2UgPSBvbGRNYXggLSBvbGRNaW47XG4gICAgY29uc3QgbmV3UmFuZ2UgPSBtYXggLSBtaW47XG5cbiAgICBpZiAob2xkUmFuZ2UgIT09IDAgJiYgbmV3UmFuZ2UgIT09IDApIHtcbiAgICAgIGNvbnN0IHNjYWxlID0gbmV3UmFuZ2UgLyBvbGRSYW5nZTtcbiAgICAgIGNvbnN0IHJlbWFwID0gKHg6IG51bWJlcikgPT4gbWluICsgKHggLSBvbGRNaW4pICogc2NhbGU7XG5cbiAgICAgIGlmICh0aGlzLl9wcm9wLm1lYW4gIT0gbnVsbClcbiAgICAgICAgdGhpcy5fcHJvcC5tZWFuID0gcmVtYXAodGhpcy5fcHJvcC5tZWFuKTtcbiAgICAgIGlmICh0aGlzLl9wcm9wLnNpZ21hICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3Auc2lnbWEgKj0gc2NhbGU7XG4gICAgICBpZiAodGhpcy5fcHJvcC54MCAhPSBudWxsKVxuICAgICAgICB0aGlzLl9wcm9wLngwID0gcmVtYXAodGhpcy5fcHJvcC54MCk7XG4gICAgICBpZiAodGhpcy5fcHJvcC5rICE9IG51bGwpXG4gICAgICAgIHRoaXMuX3Byb3AuayAvPSBzY2FsZTtcblxuICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AubGluZSlcbiAgICAgICAgcFswXSA9IHJlbWFwKHBbMF0pO1xuXG4gICAgICBpZiAodGhpcy5fcHJvcC5mcmVlZm9ybUxpbmUpIHtcbiAgICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMuX3Byb3AuZnJlZWZvcm1MaW5lKVxuICAgICAgICAgIHBbMF0gPSByZW1hcChwWzBdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9wcm9wLm1pbiA9IG1pbjtcbiAgICB0aGlzLl9wcm9wLm1heCA9IG1heDtcbiAgICB0aGlzLnVwZGF0ZURyYWdTY2FsZXMoKTtcbiAgICB0aGlzLnJlZHJhd0FsbChmYWxzZSk7XG4gIH1cblxuICBzZXRDb2x1bW4oY29sOiBERy5Db2x1bW4gfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKCFjb2wpXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCB2YWx1ZXMgPSBjb2wudG9MaXN0KCk7XG4gICAgdGhpcy5kcmF3QmFycyh2YWx1ZXMpO1xuICB9XG59XG4iXX0=
|