@datagrok-libraries/bio 5.1.1 → 5.2.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.
@@ -1,677 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import * as grok from 'datagrok-api/grok';
11
- import * as ui from 'datagrok-api/ui';
12
- import * as DG from 'datagrok-api/dg';
13
- import wu from 'wu';
14
- import * as rxjs from 'rxjs';
15
- import { UnitsHandler } from '../utils/units-handler';
16
- import { getSplitter, monomerToShort, pickUpPalette, pickUpSeqCol } from '../utils/macromolecule';
17
- var PositionHeight;
18
- (function (PositionHeight) {
19
- PositionHeight["Entropy"] = "Entropy";
20
- PositionHeight["full"] = "100%";
21
- })(PositionHeight || (PositionHeight = {}));
22
- /**@param {MouseEvent} event
23
- * @param {number} r devicePixelRation
24
- * @return {DG.Point} canvas related cursor position
25
- */
26
- HTMLCanvasElement.prototype.getCursorPosition = function (event, r) {
27
- const rect = this.getBoundingClientRect();
28
- return new DG.Point((event.clientX - rect.left) * r, (event.clientY - rect.top) * r);
29
- };
30
- DG.Rect.prototype.contains = function (x, y) {
31
- return this.left <= x && x <= this.right && this.top <= y && y <= this.bottom;
32
- };
33
- export class PositionMonomerInfo {
34
- constructor(count = 0, bounds = new DG.Rect(0, 0, 0, 0)) {
35
- this.count = count;
36
- this.bounds = bounds;
37
- }
38
- }
39
- export class PositionInfo {
40
- /** freq = {}, rowCount = 0
41
- * @param {string} name Name of position ('111A', '111.1', etc)
42
- * @param {number} sumForHeightCalc Sum of all monomer counts for height calculation
43
- * @param {number} rowCount Count of elements in column
44
- * @param {string[]} freq frequency of monomers in position
45
- */
46
- constructor(name, freq = {}, rowCount = 0, sumForHeightCalc = 0) {
47
- this.name = name;
48
- this.freq = freq;
49
- this.rowCount = rowCount;
50
- this.sumForHeightCalc = sumForHeightCalc;
51
- }
52
- }
53
- export class WebLogo extends DG.JsViewer {
54
- constructor() {
55
- super();
56
- this.viewerId = -1;
57
- this.initialized = false;
58
- // private readonly colorScheme: ColorScheme = ColorSchemes[NucleotidesWebLogo.residuesSet];
59
- this.cp = null;
60
- this.axisHeight = 12;
61
- this.seqCol = null;
62
- this.splitter = null;
63
- // private maxLength: number = 100;
64
- this.positions = [];
65
- this.rowsMasked = 0;
66
- this.rowsNull = 0;
67
- this.visibleSlider = false;
68
- this.allowResize = true;
69
- this.turnOfResizeForOneSetValue = false;
70
- this.backgroundColor = 0xFFFFFFFF;
71
- this.positionMargin = 0;
72
- this.positionNames = [];
73
- this.startPosition = -1;
74
- this.endPosition = -1;
75
- this.viewSubs = [];
76
- this.viewerId = WebLogo.viewerCount;
77
- WebLogo.viewerCount += 1;
78
- this.textBaseline = 'top';
79
- this.unitsHandler = null;
80
- this.backgroundColor = this.int('backgroundColor', 0xFFFFFFFF);
81
- this._positionWidth = this.positionWidth = this.float('positionWidth', 16 /*,
82
- {editor: 'slider', min: 4, max: 64, postfix: 'px'}*/);
83
- this.minHeight = this.float('minHeight', 50 /*,
84
- {editor: 'slider', min: 25, max: 250, postfix: 'px'}*/);
85
- this.maxHeight = this.float('maxHeight', 100 /*,
86
- {editor: 'slider', min: 25, max: 500, postfix: 'px'}*/);
87
- this.skipEmptySequences = this.bool('skipEmptySequences', true);
88
- this.sequenceColumnName = this.string('sequenceColumnName', null);
89
- this.startPositionName = this.string('startPositionName', null);
90
- this.endPositionName = this.string('endPositionName', null);
91
- this.fixWidth = this.bool('fixWidth', false);
92
- this.verticalAlignment = this.string('verticalAlignment', 'middle', { choices: ['top', 'middle', 'bottom'] });
93
- this.horizontalAlignment = this.string('horizontalAlignment', 'center', { choices: ['left', 'center', 'right'] });
94
- this.fitArea = this.bool('fitArea', true);
95
- this.shrinkEmptyTail = this.bool('shrinkEmptyTail', true);
96
- this.skipEmptyPositions = this.bool('skipEmptyPositions', false);
97
- this.positionMarginState = this.string('positionMarginState', 'auto', { choices: ['auto', 'enable', 'off'] });
98
- let defaultValueForPositionMargin = 0;
99
- if (this.positionMarginState === 'auto') {
100
- defaultValueForPositionMargin = 4;
101
- }
102
- this.positionMargin = this.int('positionMargin', defaultValueForPositionMargin, { min: 0, max: 16 });
103
- this.positionHeight = this.string('positionHeight', PositionHeight.full, { choices: [PositionHeight.full, PositionHeight.Entropy] });
104
- const style = { style: 'barbell' };
105
- this.slider = ui.rangeSlider(0, 100, 0, 20, false, style);
106
- this.canvas = ui.canvas();
107
- this.canvas.style.width = '100%';
108
- }
109
- /** For startPosition equals to endPosition Length is 1 */
110
- get Length() {
111
- if (this.skipEmptyPositions) {
112
- return this.positions.length;
113
- }
114
- return this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0;
115
- }
116
- /** Calculate new position data basic on {@link positionMarginState} and {@link positionMargin} */
117
- get positionWidthWithMargin() {
118
- return this._positionWidth + this.positionMarginValue;
119
- }
120
- get positionMarginValue() {
121
- var _a;
122
- if ((this.positionMarginState === 'auto') && (((_a = this.unitsHandler) === null || _a === void 0 ? void 0 : _a.getAlphabetIsMultichar()) === true)) {
123
- return this.positionMargin;
124
- }
125
- if (this.positionMarginState === 'enable') {
126
- return this.positionMargin;
127
- }
128
- return 0;
129
- }
130
- /** Count of position rendered for calculations countOfRenderPositions */
131
- get countOfRenderPositions() {
132
- if (this.host == null) {
133
- return 0;
134
- }
135
- const r = window.devicePixelRatio;
136
- if (r > 1) {
137
- return this.canvasWidthWithRatio / this.positionWidthWithMargin;
138
- }
139
- else {
140
- return this.canvas.width / (this.positionWidthWithMargin * r);
141
- }
142
- }
143
- get canvasWidthWithRatio() {
144
- return this.canvas.width * window.devicePixelRatio;
145
- }
146
- /** Position of start rendering */
147
- get firstVisibleIndex() {
148
- return (this.visibleSlider) ? Math.floor(this.slider.min) : 0;
149
- }
150
- init() {
151
- if (this.initialized) {
152
- console.error('WebLogo second initialization!');
153
- return;
154
- }
155
- this.initialized = true;
156
- this.helpUrl = '/help/visualize/viewers/web-logo.md';
157
- this.msgHost = ui.div('No message');
158
- this.msgHost.style.display = 'none';
159
- this.canvas = ui.canvas();
160
- this.canvas.style.width = '100%';
161
- //this.slider.setShowHandles(false);
162
- this.slider.root.style.position = 'absolute';
163
- this.slider.root.style.zIndex = '999';
164
- this.slider.root.style.display = 'none';
165
- this.slider.root.style.height = '0.7em';
166
- this.visibleSlider = false;
167
- this.slider.onValuesChanged.subscribe(() => {
168
- if ((this.host == null)) {
169
- return;
170
- }
171
- /* Resize slider if we can resize do that */
172
- if ((this.allowResize) && (!this.turnOfResizeForOneSetValue) &&
173
- (this.visibleSlider)) {
174
- const countOfPositions = Math.ceil(this.slider.max - this.slider.min);
175
- const calculatedWidth = (this.canvas.width / countOfPositions) - this.positionMarginValue;
176
- // saving positionWidth value global (even if slider is not visible)
177
- this.positionWidth = calculatedWidth;
178
- this._positionWidth = calculatedWidth;
179
- }
180
- this.turnOfResizeForOneSetValue = false;
181
- this.render(true);
182
- });
183
- this.host = ui.div([this.msgHost, this.canvas]);
184
- this.host.style.justifyContent = 'center';
185
- this.host.style.alignItems = 'center';
186
- this.host.style.position = 'relative';
187
- this.host.style.setProperty('overflow', 'hidden', 'important');
188
- const getMonomer = (p) => {
189
- const calculatedX = p.x + this.firstVisibleIndex * this.positionWidthWithMargin;
190
- const jPos = Math.floor(p.x / this.positionWidthWithMargin + this.firstVisibleIndex);
191
- const position = this.positions[jPos];
192
- if (position === void 0)
193
- return [jPos, null, null];
194
- const monomer = Object.keys(position.freq)
195
- .find((m) => position.freq[m].bounds.contains(calculatedX, p.y));
196
- if (monomer === undefined)
197
- return [jPos, null, null];
198
- return [jPos, monomer, position.freq[monomer]];
199
- };
200
- const correctMonomerFilter = (iRow, monomer, jPos) => {
201
- const seq = this.seqCol.get(iRow);
202
- const seqM = seq ? this.splitter(seq)[this.startPosition + jPos] : null;
203
- return ((seqM === monomer) || (seqM === '' && monomer === '-')) && this.dataFrame.filter.get(iRow);
204
- };
205
- rxjs.fromEvent(this.canvas, 'mousemove').subscribe((e) => {
206
- const args = e;
207
- const r = window.devicePixelRatio;
208
- const cursorP = this.canvas.getCursorPosition(args, r);
209
- const [jPos, monomer] = getMonomer(cursorP);
210
- if (this.dataFrame && this.seqCol && this.splitter && monomer) {
211
- const rowCount = wu.count().take(this.dataFrame.rowCount).filter(function (iRow) {
212
- return correctMonomerFilter(iRow, monomer, jPos);
213
- }).reduce((count, iRow) => count + 1, 0);
214
- ui.tooltip.show(ui.div([ui.div(`${monomer}`), ui.div(`${rowCount} rows`)]), args.x + 16, args.y + 16);
215
- }
216
- else {
217
- ui.tooltip.hide();
218
- }
219
- });
220
- rxjs.fromEvent(this.canvas, 'mousedown').subscribe((e) => {
221
- const args = e;
222
- const r = window.devicePixelRatio;
223
- const [jPos, monomer] = getMonomer(this.canvas.getCursorPosition(args, r));
224
- // prevents deselect all rows if we miss monomer bounds
225
- if (this.dataFrame && this.seqCol && this.splitter && monomer) {
226
- this.dataFrame.selection.init(function (iRow) {
227
- return correctMonomerFilter(iRow, monomer, jPos);
228
- });
229
- }
230
- });
231
- rxjs.fromEvent(this.canvas, 'wheel').subscribe((e) => {
232
- if (!this.visibleSlider)
233
- return;
234
- const countOfScrollPositions = (e.deltaY / 100) * Math.max(Math.floor((this.countOfRenderPositions) / 2), 1);
235
- this.slider.scrollBy(this.slider.min + countOfScrollPositions);
236
- });
237
- this.viewSubs.push(ui.onSizeChanged(this.root).subscribe(this.rootOnSizeChanged.bind(this)));
238
- this.root.append(this.host);
239
- this.root.append(this.slider.root);
240
- this._calculate(window.devicePixelRatio);
241
- this.updateSlider();
242
- this.render(true);
243
- }
244
- /** Handler of changing size WebLogo */
245
- rootOnSizeChanged() {
246
- this._calculate(window.devicePixelRatio);
247
- this.updateSlider();
248
- this.render(true);
249
- }
250
- /** Assigns {@link seqCol} and {@link cp} based on {@link sequenceColumnName} and calls {@link render}().
251
- */
252
- updateSeqCol() {
253
- if (this.dataFrame) {
254
- this.seqCol = this.sequenceColumnName ? this.dataFrame.col(this.sequenceColumnName) : null;
255
- if (this.seqCol == null) {
256
- this.seqCol = pickUpSeqCol(this.dataFrame);
257
- this.sequenceColumnName = this.seqCol ? this.seqCol.name : null;
258
- }
259
- if (this.seqCol) {
260
- const units = this.seqCol.getTag(DG.TAGS.UNITS);
261
- const separator = this.seqCol.getTag("separator" /* TAGS.separator */);
262
- this.splitter = getSplitter(units, separator);
263
- this.unitsHandler = new UnitsHandler(this.seqCol);
264
- this.updatePositions();
265
- this.cp = pickUpPalette(this.seqCol);
266
- }
267
- else {
268
- this.splitter = null;
269
- this.positionNames = [];
270
- this.startPosition = -1;
271
- this.endPosition = -1;
272
- this.cp = null;
273
- }
274
- }
275
- this.render();
276
- }
277
- /** Updates {@link positionNames} and calculates {@link startPosition} and {@link endPosition}.
278
- */
279
- updatePositions() {
280
- if (!this.seqCol)
281
- return;
282
- let categories;
283
- if (this.shrinkEmptyTail) {
284
- const indices = this.dataFrame.filter.getSelectedIndexes();
285
- categories = Array.from(new Set(Array.from(Array(indices.length).keys()).map((i) => this.seqCol.get(indices[i]))));
286
- }
287
- else {
288
- categories = this.seqCol.categories;
289
- }
290
- const maxLength = categories.length > 0 ? Math.max(...categories.map((s) => s !== null ? this.splitter(s).length : 0)) : 0;
291
- // Get position names from data column tag 'positionNames'
292
- const positionNamesTxt = this.seqCol.getTag('positionNames');
293
- // Fallback if 'positionNames' tag is not provided
294
- this.positionNames = positionNamesTxt ? positionNamesTxt.split(', ').map((n) => n.trim()) :
295
- [...Array(maxLength).keys()].map((jPos) => `${jPos + 1}`);
296
- this.startPosition = (this.startPositionName && this.positionNames &&
297
- this.positionNames.includes(this.startPositionName)) ?
298
- this.positionNames.indexOf(this.startPositionName) : 0;
299
- this.endPosition = (this.endPositionName && this.positionNames &&
300
- this.positionNames.includes(this.endPositionName)) ?
301
- this.positionNames.indexOf(this.endPositionName) : (maxLength - 1);
302
- }
303
- get widthArea() {
304
- return this.Length * this.positionWidth / window.devicePixelRatio;
305
- }
306
- get heightArea() {
307
- return Math.min(this.maxHeight, Math.max(this.minHeight, this.root.clientHeight));
308
- }
309
- get xScale() {
310
- return (this.root.clientWidth - this.Length * this.positionMarginValue) / this.widthArea;
311
- }
312
- get yScale() {
313
- return this.root.clientHeight / this.heightArea;
314
- }
315
- checkIsHideSlider() {
316
- let showSliderWithFitArea = true;
317
- const minScale = Math.min(this.xScale, this.yScale);
318
- if (((minScale == this.xScale) || (minScale <= 1)) && (this.fitArea)) {
319
- showSliderWithFitArea = false;
320
- }
321
- return ((this.fixWidth || Math.ceil(this.canvas.width / this.positionWidthWithMargin) >= this.Length) || (showSliderWithFitArea));
322
- }
323
- setSliderVisibility(visible) {
324
- if (visible) {
325
- this.slider.root.style.display = 'inherit';
326
- this.visibleSlider = true;
327
- }
328
- else {
329
- this.slider.root.style.display = 'none';
330
- this.visibleSlider = false;
331
- }
332
- }
333
- /** Updates {@link slider}, needed to set slider options and to update slider position. */
334
- updateSlider() {
335
- if (this.checkIsHideSlider()) {
336
- this.setSliderVisibility(false);
337
- }
338
- else {
339
- this.setSliderVisibility(true);
340
- }
341
- if ((this.slider != null) && (this.canvas != null)) {
342
- let diffEndScrollAndSliderMin = Math.floor(this.slider.min + this.canvas.width / this.positionWidthWithMargin) - this.Length;
343
- diffEndScrollAndSliderMin = diffEndScrollAndSliderMin > 0 ? diffEndScrollAndSliderMin : 0;
344
- let newMin = Math.floor(this.slider.min - diffEndScrollAndSliderMin);
345
- let newMax = Math.floor(this.slider.min - diffEndScrollAndSliderMin) + Math.floor(this.canvas.width / this.positionWidthWithMargin);
346
- if (this.checkIsHideSlider()) {
347
- newMin = 0;
348
- newMax = this.Length - 1;
349
- }
350
- this.turnOfResizeForOneSetValue = true;
351
- this.slider.setValues(0, this.Length, newMin, newMax);
352
- }
353
- }
354
- /** Handler of property change events. */
355
- onPropertyChanged(property) {
356
- super.onPropertyChanged(property);
357
- switch (property.name) {
358
- case 'sequenceColumnName':
359
- this.updateSeqCol();
360
- break;
361
- case 'startPositionName':
362
- this.updateSeqCol();
363
- break;
364
- case 'endPositionName':
365
- this.updateSeqCol();
366
- break;
367
- case 'positionWidth':
368
- this._positionWidth = this.positionWidth;
369
- this.updateSlider();
370
- break;
371
- case 'fixWidth':
372
- this.updateSlider();
373
- break;
374
- case 'fitArea':
375
- this.updateSlider();
376
- break;
377
- case 'shrinkEmptyTail':
378
- this.updatePositions();
379
- break;
380
- case 'skipEmptyPositions':
381
- this.updatePositions();
382
- break;
383
- case 'positionMargin':
384
- this.updateSlider();
385
- break;
386
- }
387
- this.render(true);
388
- }
389
- /** Add filter handlers when table is a attached */
390
- onTableAttached() {
391
- super.onTableAttached();
392
- const dataFrameTxt = this.dataFrame ? 'data' : 'null';
393
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached( dataFrame = ${dataFrameTxt} ) start`);
394
- this.updateSeqCol();
395
- if (this.dataFrame !== void 0) {
396
- this.subs.push(this.dataFrame.selection.onChanged.subscribe((_) => this.render()));
397
- this.subs.push(this.dataFrame.filter.onChanged.subscribe((_) => {
398
- this.updatePositions();
399
- this.render();
400
- }));
401
- }
402
- this.init();
403
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached() end`);
404
- }
405
- /** Remove all handlers when table is a detach */
406
- detach() {
407
- const _super = Object.create(null, {
408
- detach: { get: () => super.detach }
409
- });
410
- return __awaiter(this, void 0, void 0, function* () {
411
- const dataFrameTxt = `${this.dataFrame ? 'data' : 'null'}`;
412
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached( dataFrame = ${dataFrameTxt} ) start`);
413
- _super.detach.call(this);
414
- this.viewSubs.forEach((sub) => sub.unsubscribe());
415
- this.host.remove();
416
- this.msgHost = undefined;
417
- this.host = undefined;
418
- this.initialized = false;
419
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached() end`);
420
- });
421
- }
422
- /** Helper function for rendering */
423
- _nullSequence(fillerResidue = 'X') {
424
- if (!this.skipEmptySequences)
425
- return new Array(this.Length).fill(fillerResidue).join('');
426
- return '';
427
- }
428
- /** Helper function for remove empty positions */
429
- // TODO: use this function in from core
430
- removeWhere(array, predicate) {
431
- let length = array.length;
432
- let updateIterator = 0;
433
- for (let deleteIterator = 0; deleteIterator < length; deleteIterator++) {
434
- if (!predicate(array[deleteIterator])) {
435
- array[updateIterator] = array[deleteIterator];
436
- updateIterator++;
437
- }
438
- }
439
- array.length = updateIterator;
440
- return array;
441
- }
442
- /** Function for removing empty positions */
443
- _removeEmptyPositions() {
444
- if (this.skipEmptyPositions) {
445
- this.removeWhere(this.positions, item => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.freq['-']) === null || _a === void 0 ? void 0 : _a.count) === item.rowCount; });
446
- }
447
- }
448
- _calculate(r) {
449
- if (!this.host || !this.seqCol || !this.dataFrame)
450
- return;
451
- this.unitsHandler = new UnitsHandler(this.seqCol);
452
- this.calcSize();
453
- this.positions = new Array(this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0);
454
- for (let jPos = 0; jPos < this.Length; jPos++) {
455
- const posName = this.positionNames[this.startPosition + jPos];
456
- this.positions[jPos] = new PositionInfo(posName);
457
- }
458
- // 2022-05-05 askalkin instructed to show WebLogo based on filter (not selection)
459
- const indices = this.dataFrame.filter.getSelectedIndexes();
460
- // const indices = this.dataFrame.selection.trueCount > 0 ? this.dataFrame.selection.getSelectedIndexes() :
461
- // this.dataFrame.filter.getSelectedIndexes();
462
- this.rowsMasked = indices.length;
463
- this.rowsNull = 0;
464
- for (const i of indices) {
465
- let s = (this.seqCol.get(i));
466
- if (!s) {
467
- s = this._nullSequence();
468
- ++this.rowsNull;
469
- }
470
- const seqM = this.splitter(s);
471
- for (let jPos = 0; jPos < this.Length; jPos++) {
472
- const pmInfo = this.positions[jPos].freq;
473
- const m = seqM[this.startPosition + jPos] || '-';
474
- if (!(m in pmInfo))
475
- pmInfo[m] = new PositionMonomerInfo();
476
- pmInfo[m].count++;
477
- }
478
- }
479
- //#region Polish freq counts
480
- for (let jPos = 0; jPos < this.Length; jPos++) {
481
- // delete this.positions[jPos].freq['-'];
482
- this.positions[jPos].rowCount = 0;
483
- for (const m in this.positions[jPos].freq)
484
- this.positions[jPos].rowCount += this.positions[jPos].freq[m].count;
485
- if (this.positionHeight == PositionHeight.Entropy) {
486
- this.positions[jPos].sumForHeightCalc = 0;
487
- for (const m in this.positions[jPos].freq) {
488
- const pn = this.positions[jPos].freq[m].count / this.positions[jPos].rowCount;
489
- this.positions[jPos].sumForHeightCalc += -pn * Math.log2(pn);
490
- }
491
- }
492
- }
493
- //#endregion
494
- this._removeEmptyPositions();
495
- const absoluteMaxHeight = this.canvas.height - this.axisHeight * r;
496
- //#region Calculate screen
497
- for (let jPos = 0; jPos < this.Length; jPos++) {
498
- const freq = this.positions[jPos].freq;
499
- const rowCount = this.positions[jPos].rowCount;
500
- const alphabetSize = this.getAlphabetSize();
501
- if ((this.positionHeight == PositionHeight.Entropy) && (alphabetSize == null)) {
502
- grok.shell.error('WebLogo: alphabet is undefined.');
503
- }
504
- const maxHeight = (this.positionHeight == PositionHeight.Entropy) ? (absoluteMaxHeight * (Math.log2(alphabetSize) - (this.positions[jPos].sumForHeightCalc)) / Math.log2(alphabetSize)) : absoluteMaxHeight;
505
- let y = this.axisHeight * r + (absoluteMaxHeight - maxHeight - 1);
506
- const entries = Object.entries(freq).sort((a, b) => {
507
- if (a[0] !== '-' && b[0] !== '-')
508
- return b[1].count - a[1].count;
509
- else if (a[0] === '-' && b[0] === '-')
510
- return 0;
511
- else if (a[0] === '-')
512
- return -1;
513
- else /* (b[0] === '-') */
514
- return +1;
515
- });
516
- for (const entry of entries) {
517
- const pmInfo = entry[1];
518
- // const m: string = entry[0];
519
- const h = maxHeight * pmInfo.count / rowCount;
520
- pmInfo.bounds = new DG.Rect(jPos * this.positionWidthWithMargin, y, this._positionWidth, h);
521
- y += h;
522
- }
523
- }
524
- //#endregion
525
- }
526
- /** Render WebLogo sensitive to changes in params of rendering
527
- *@param {boolean} recalc - indicates that need to recalculate data for rendering
528
- */
529
- render(recalc = true) {
530
- var _a;
531
- if (this.msgHost) {
532
- if (this.seqCol && !this.cp) {
533
- this.msgHost.innerText = `Unknown palette (column semType: '${this.seqCol.semType}').`;
534
- this.msgHost.style.display = '';
535
- }
536
- else {
537
- this.msgHost.style.display = 'none';
538
- }
539
- }
540
- if (!this.seqCol || !this.dataFrame || !this.cp || this.startPosition === -1 || this.endPosition === -1 || this.host == null || this.slider == null)
541
- return;
542
- const g = this.canvas.getContext('2d');
543
- if (!g)
544
- return;
545
- this.slider.root.style.width = `${this.host.clientWidth}px`;
546
- const r = window.devicePixelRatio;
547
- if (recalc)
548
- this._calculate(r);
549
- g.resetTransform();
550
- g.fillStyle = DG.Color.toHtml(this.backgroundColor);
551
- g.fillRect(0, 0, this.canvas.width, this.canvas.height);
552
- g.textBaseline = this.textBaseline;
553
- const maxCountOfRowsRendered = this.countOfRenderPositions + 1;
554
- const firstVisibleIndex = (this.visibleSlider) ? Math.floor(this.slider.min) : 0;
555
- const lastVisibleIndex = Math.min(this.Length, firstVisibleIndex + maxCountOfRowsRendered);
556
- //#region Plot positionNames
557
- const positionFontSize = 10 * r;
558
- g.resetTransform();
559
- g.fillStyle = 'black';
560
- g.textAlign = 'center';
561
- g.font = `${positionFontSize.toFixed(1)}px Roboto, Roboto Local, sans-serif`;
562
- const posNameMaxWidth = Math.max(...this.positions.map((pos) => g.measureText(pos.name).width));
563
- const hScale = posNameMaxWidth < (this._positionWidth - 2) ? 1 : (this._positionWidth - 2) / posNameMaxWidth;
564
- for (let jPos = this.firstVisibleIndex; jPos < lastVisibleIndex; jPos++) {
565
- const pos = this.positions[jPos];
566
- g.resetTransform();
567
- g.setTransform(hScale, 0, 0, 1, jPos * this.positionWidthWithMargin + this._positionWidth / 2 - this.positionWidthWithMargin * firstVisibleIndex, 0);
568
- g.fillText(pos.name, 0, 0);
569
- }
570
- //#endregion Plot positionNames
571
- const fontStyle = '16px Roboto, Roboto Local, sans-serif';
572
- // Hacks to scale uppercase characters to target rectangle
573
- const uppercaseLetterAscent = 0.25;
574
- const uppercaseLetterHeight = 12.2;
575
- for (let jPos = this.firstVisibleIndex; jPos < lastVisibleIndex; jPos++) {
576
- for (const [monomer, pmInfo] of Object.entries(this.positions[jPos].freq)) {
577
- if (monomer !== '-') {
578
- const monomerTxt = monomerToShort(monomer, 5);
579
- const b = pmInfo.bounds;
580
- const left = b.left - this.positionWidthWithMargin * this.firstVisibleIndex;
581
- g.resetTransform();
582
- g.strokeStyle = 'lightgray';
583
- g.lineWidth = 1;
584
- g.rect(left, b.top, b.width, b.height);
585
- g.fillStyle = (_a = this.cp.get(monomer)) !== null && _a !== void 0 ? _a : this.cp.get('other');
586
- g.textAlign = 'left';
587
- g.font = fontStyle;
588
- //g.fillRect(b.left, b.top, b.width, b.height);
589
- const mTm = g.measureText(monomerTxt);
590
- g.setTransform(b.width / mTm.width, 0, 0, b.height / uppercaseLetterHeight, left, b.top);
591
- g.fillText(monomerTxt, 0, -uppercaseLetterAscent);
592
- }
593
- }
594
- }
595
- }
596
- /** Calculate canvas size an positionWidth and updates properties */
597
- calcSize() {
598
- if (!this.host)
599
- return;
600
- const r = window.devicePixelRatio;
601
- let width = this.widthArea;
602
- let height = this.heightArea;
603
- if ((this.fitArea) && (!this.visibleSlider)) {
604
- const scale = Math.max(1, Math.min(this.xScale, this.yScale));
605
- width = width * scale;
606
- height = height * scale;
607
- this._positionWidth = this.positionWidth * scale;
608
- }
609
- width = this.Length * this.positionWidthWithMargin / r;
610
- this.canvas.width = this.root.clientWidth * r;
611
- this.canvas.style.width = `${this.root.clientWidth}px`;
612
- // const canvasHeight: number = width > this.root.clientWidth ? height - 8 : height;
613
- this.host.style.setProperty('height', `${height}px`);
614
- const canvasHeight = this.host.clientHeight;
615
- this.canvas.height = canvasHeight * r;
616
- // Adjust host and root width
617
- if (this.fixWidth) {
618
- // full width for canvas host and root
619
- this.root.style.width = this.host.style.width = `${width}px`;
620
- this.root.style.height = `${height}px`;
621
- this.root.style.overflow = 'hidden';
622
- this.host.style.setProperty('overflow-y', 'hidden', 'important');
623
- }
624
- else {
625
- // allow scroll canvas in root
626
- this.root.style.width = this.host.style.width = '100%';
627
- this.host.style.overflowX = 'auto!important';
628
- this.host.style.setProperty('text-align', this.horizontalAlignment);
629
- const sliderHeight = this.visibleSlider ? 10 : 0;
630
- // vertical alignment
631
- let hostTopMargin = 0;
632
- switch (this.verticalAlignment) {
633
- case 'top':
634
- hostTopMargin = 0;
635
- break;
636
- case 'middle':
637
- hostTopMargin = Math.max(0, (this.root.clientHeight - height) / 2);
638
- break;
639
- case 'bottom':
640
- hostTopMargin = Math.max(0, this.root.clientHeight - height - sliderHeight);
641
- break;
642
- }
643
- // horizontal alignment
644
- let hostLeftMargin = 0;
645
- switch (this.horizontalAlignment) {
646
- case 'left':
647
- hostLeftMargin = 0;
648
- break;
649
- case 'center':
650
- hostLeftMargin = Math.max(0, (this.root.clientWidth - width) / 2);
651
- break;
652
- case 'right':
653
- hostLeftMargin = Math.max(0, this.root.clientWidth - width);
654
- break;
655
- }
656
- this.host.style.setProperty('margin-top', `${hostTopMargin}px`, 'important');
657
- this.host.style.setProperty('margin-left', `${hostLeftMargin}px`, 'important');
658
- if (this.slider != null) {
659
- this.slider.root.style.setProperty('margin-top', `${hostTopMargin + canvasHeight}px`, 'important');
660
- }
661
- if (this.root.clientHeight <= height) {
662
- this.host.style.setProperty('height', `${this.root.clientHeight}px`);
663
- this.host.style.setProperty('overflow-y', null);
664
- }
665
- else {
666
- this.host.style.setProperty('overflow-y', 'hidden', 'important');
667
- }
668
- }
669
- }
670
- getAlphabetSize() {
671
- var _a, _b;
672
- return (_b = (_a = this.unitsHandler) === null || _a === void 0 ? void 0 : _a.getAlphabetSize()) !== null && _b !== void 0 ? _b : 0;
673
- }
674
- }
675
- WebLogo.residuesSet = 'nucleotides';
676
- WebLogo.viewerCount = -1;
677
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWxvZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWItbG9nby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV0QyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFJN0IsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBRXBELE9BQU8sRUFBQyxXQUFXLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQXFCLE1BQU0sd0JBQXdCLENBQUM7QUFRcEgsSUFBSyxjQUdKO0FBSEQsV0FBSyxjQUFjO0lBQ2pCLHFDQUFtQixDQUFBO0lBQ25CLCtCQUFhLENBQUE7QUFDZixDQUFDLEVBSEksY0FBYyxLQUFkLGNBQWMsUUFHbEI7QUFRRDs7O0dBR0c7QUFDSCxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsVUFBUyxLQUFpQixFQUFFLENBQVM7SUFDbkYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDMUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN2RixDQUFDLENBQUM7QUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsVUFBUyxDQUFTLEVBQUUsQ0FBUztJQUN4RCxPQUFPLElBQUksQ0FBQyxJQUFJLElBQUks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Q0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLEdBQUcsY0FBYyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDL0UsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRTtnQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsR0FBRyxhQUFhLEdBQUcsWUFBWSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDcEc7WUFFRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLE1BQU0sRUFBRTtnQkFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQztnQkFDckUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQzthQUNqRDtpQkFBTTtnQkFDTCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxXQUFXLENBQUMsQ0FBQzthQUNsRTtTQUNGO0lBQ0gsQ0FBQztJQUVNLGVBQWU7O1FBQ3BCLE9BQU8sTUFBQSxNQUFBLElBQUksQ0FBQyxZQUFZLDBDQUFFLGVBQWUsRUFBRSxtQ0FBSSxDQUFDLENBQUM7SUFDbkQsQ0FBQzs7QUF4dkJhLG1CQUFXLEdBQUcsYUFBYSxDQUFDO0FBQzNCLG1CQUFXLEdBQVcsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5pbXBvcnQgd3UgZnJvbSAnd3UnO1xuaW1wb3J0ICogYXMgcnhqcyBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtTZXFQYWxldHRlfSBmcm9tICcuLi9zZXEtcGFsZXR0ZXMnO1xuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtVbml0c0hhbmRsZXJ9IGZyb20gJy4uL3V0aWxzL3VuaXRzLWhhbmRsZXInO1xuaW1wb3J0IHtTbGlkZXJPcHRpb25zfSBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0IHtnZXRTcGxpdHRlciwgbW9ub21lclRvU2hvcnQsIHBpY2tVcFBhbGV0dGUsIHBpY2tVcFNlcUNvbCwgU3BsaXR0ZXJGdW5jLCBUQUdTfSBmcm9tICcuLi91dGlscy9tYWNyb21vbGVjdWxlJztcblxuZGVjbGFyZSBtb2R1bGUgJ2RhdGFncm9rLWFwaS9zcmMvZ3JpZCcge1xuICBpbnRlcmZhY2UgUmVjdCB7XG4gICAgY29udGFpbnMoeDogbnVtYmVyLCB5OiBudW1iZXIpOiBib29sZWFuO1xuICB9XG59XG5cbmVudW0gUG9zaXRpb25IZWlnaHQge1xuICBFbnRyb3B5ID0gJ0VudHJvcHknLFxuICBmdWxsID0gJzEwMCUnLFxufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBIVE1MQ2FudmFzRWxlbWVudCB7XG4gICAgZ2V0Q3Vyc29yUG9zaXRpb24oZXZlbnQ6IE1vdXNlRXZlbnQsIHI6IG51bWJlcik6IERHLlBvaW50O1xuICB9XG59XG5cbi8qKkBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSByIGRldmljZVBpeGVsUmF0aW9uXG4gKiBAcmV0dXJuIHtERy5Qb2ludH0gY2FudmFzIHJlbGF0ZWQgY3Vyc29yIHBvc2l0aW9uXG4gKi9cbkhUTUxDYW52YXNFbGVtZW50LnByb3RvdHlwZS5nZXRDdXJzb3JQb3NpdGlvbiA9IGZ1bmN0aW9uKGV2ZW50OiBNb3VzZUV2ZW50LCByOiBudW1iZXIpOiBERy5Qb2ludCB7XG4gIGNvbnN0IHJlY3QgPSB0aGlzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICByZXR1cm4gbmV3IERHLlBvaW50KChldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0KSAqIHIsIChldmVudC5jbGllbnRZIC0gcmVjdC50b3ApICogcik7XG59O1xuXG5ERy5SZWN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiB0aGlzLmxlZnQgPD0geCAmJiB4IDw9IHRoaXMucmlnaHQgJiYgdGhpcy50b3AgPD0geSAmJiB5IDw9IHRoaXMuYm90dG9tO1xufTtcblxuZXhwb3J0IGNsYXNzIFBvc2l0aW9uTW9ub21lckluZm8ge1xuICAvKiogU2VxdWVuY2VzIGNvdW50IHdpdGggbW9ub21lciBpbiBwb3NpdGlvbiAqL1xuICBjb3VudDogbnVtYmVyO1xuXG4gIC8qKiBSZW1lbWJlciBzY3JlZW4gY29vcmRzIHJlY3QgKi9cbiAgYm91bmRzOiBERy5SZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGNvdW50OiBudW1iZXIgPSAwLCBib3VuZHM6IERHLlJlY3QgPSBuZXcgREcuUmVjdCgwLCAwLCAwLCAwKSkge1xuICAgIHRoaXMuY291bnQgPSBjb3VudDtcbiAgICB0aGlzLmJvdW5kcyA9IGJvdW5kcztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUG9zaXRpb25JbmZvIHtcbiAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgZnJlcTogeyBbbTogc3RyaW5nXTogUG9zaXRpb25Nb25vbWVySW5mbyB9O1xuICByb3dDb3VudDogbnVtYmVyO1xuICBzdW1Gb3JIZWlnaHRDYWxjOiBudW1iZXI7XG5cbiAgLyoqIGZyZXEgPSB7fSwgcm93Q291bnQgPSAwXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5hbWUgb2YgcG9zaXRpb24gKCcxMTFBJywgJzExMS4xJywgZXRjKVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3VtRm9ySGVpZ2h0Q2FsYyBTdW0gb2YgYWxsIG1vbm9tZXIgY291bnRzIGZvciBoZWlnaHQgY2FsY3VsYXRpb25cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvd0NvdW50IENvdW50IG9mIGVsZW1lbnRzIGluIGNvbHVtblxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBmcmVxIGZyZXF1ZW5jeSBvZiBtb25vbWVycyBpbiBwb3NpdGlvblxuICAgKi9cbiAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCBmcmVxOiB7IFttOiBzdHJpbmddOiBQb3NpdGlvbk1vbm9tZXJJbmZvIH0gPSB7fSwgcm93Q291bnQ6IG51bWJlciA9IDAsIHN1bUZvckhlaWdodENhbGM6IG51bWJlciA9IDApIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuZnJlcSA9IGZyZXE7XG4gICAgdGhpcy5yb3dDb3VudCA9IHJvd0NvdW50O1xuICAgIHRoaXMuc3VtRm9ySGVpZ2h0Q2FsYyA9IHN1bUZvckhlaWdodENhbGM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYkxvZ28gZXh0ZW5kcyBERy5Kc1ZpZXdlciB7XG4gIHB1YmxpYyBzdGF0aWMgcmVzaWR1ZXNTZXQgPSAnbnVjbGVvdGlkZXMnO1xuICBwcml2YXRlIHN0YXRpYyB2aWV3ZXJDb3VudDogbnVtYmVyID0gLTE7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aWV3ZXJJZDogbnVtYmVyID0gLTE7XG4gIHByaXZhdGUgdW5pdHNIYW5kbGVyOiBVbml0c0hhbmRsZXIgfCBudWxsO1xuICBwcml2YXRlIGluaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gcHJpdmF0ZSByZWFkb25seSBjb2xvclNjaGVtZTogQ29sb3JTY2hlbWUgPSBDb2xvclNjaGVtZXNbTnVjbGVvdGlkZXNXZWJMb2dvLnJlc2lkdWVzU2V0XTtcbiAgcHJvdGVjdGVkIGNwOiBTZXFQYWxldHRlIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBob3N0PzogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgbXNnSG9zdD86IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XG4gIHByaXZhdGUgc2xpZGVyOiBERy5SYW5nZVNsaWRlcjtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXh0QmFzZWxpbmU6IENhbnZhc1RleHRCYXNlbGluZTtcblxuICBwcml2YXRlIGF4aXNIZWlnaHQ6IG51bWJlciA9IDEyO1xuXG4gIHByaXZhdGUgc2VxQ29sOiBERy5Db2x1bW48c3RyaW5nPiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNwbGl0dGVyOiBTcGxpdHRlckZ1bmMgfCBudWxsID0gbnVsbDtcbiAgLy8gcHJpdmF0ZSBtYXhMZW5ndGg6IG51bWJlciA9IDEwMDtcbiAgcHJpdmF0ZSBwb3NpdGlvbnM6IFBvc2l0aW9uSW5mb1tdID0gW107XG5cbiAgcHJpdmF0ZSByb3dzTWFza2VkOiBudW1iZXIgPSAwO1xuICBwcml2YXRlIHJvd3NOdWxsOiBudW1iZXIgPSAwO1xuICBwcml2YXRlIHZpc2libGVTbGlkZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBhbGxvd1Jlc2l6ZTogYm9vbGVhbiA9IHRydWU7XG4gIHByaXZhdGUgdHVybk9mUmVzaXplRm9yT25lU2V0VmFsdWU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBWaWV3ZXIncyBwcm9wZXJ0aWVzIChsaWtlbHkgdGhleSBzaG91bGQgYmUgcHVibGljIHNvIHRoYXQgdGhleSBjYW4gYmUgc2V0IG91dHNpZGUpXG4gIHByaXZhdGUgX3Bvc2l0aW9uV2lkdGg6IG51bWJlcjtcbiAgcHVibGljIHBvc2l0aW9uV2lkdGg6IG51bWJlcjtcbiAgcHVibGljIG1pbkhlaWdodDogbnVtYmVyO1xuICBwdWJsaWMgYmFja2dyb3VuZENvbG9yOiBudW1iZXIgPSAweEZGRkZGRkZGO1xuICBwdWJsaWMgbWF4SGVpZ2h0OiBudW1iZXI7XG4gIHB1YmxpYyBza2lwRW1wdHlTZXF1ZW5jZXM6IGJvb2xlYW47XG4gIHB1YmxpYyBzZXF1ZW5jZUNvbHVtbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHB1YmxpYyBwb3NpdGlvbk1hcmdpblN0YXRlOiBzdHJpbmc7XG4gIHB1YmxpYyBwb3NpdGlvbk1hcmdpbjogbnVtYmVyID0gMDtcbiAgcHVibGljIHN0YXJ0UG9zaXRpb25OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwdWJsaWMgZW5kUG9zaXRpb25OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBwdWJsaWMgZml4V2lkdGg6IGJvb2xlYW47XG4gIHB1YmxpYyB2ZXJ0aWNhbEFsaWdubWVudDogc3RyaW5nIHwgbnVsbDtcbiAgcHVibGljIGhvcml6b250YWxBbGlnbm1lbnQ6IHN0cmluZyB8IG51bGw7XG4gIHB1YmxpYyBmaXRBcmVhOiBib29sZWFuO1xuICBwdWJsaWMgc2hyaW5rRW1wdHlUYWlsOiBib29sZWFuO1xuICBwdWJsaWMgc2tpcEVtcHR5UG9zaXRpb25zOiBib29sZWFuO1xuICBwdWJsaWMgcG9zaXRpb25IZWlnaHQ6IHN0cmluZztcblxuICBwcml2YXRlIHBvc2l0aW9uTmFtZXM6IHN0cmluZ1tdID0gW107XG5cbiAgcHJpdmF0ZSBzdGFydFBvc2l0aW9uOiBudW1iZXIgPSAtMTtcblxuICBwcml2YXRlIGVuZFBvc2l0aW9uOiBudW1iZXIgPSAtMTtcblxuICAvKiogRm9yIHN0YXJ0UG9zaXRpb24gZXF1YWxzIHRvIGVuZFBvc2l0aW9uIExlbmd0aCBpcyAxICovXG4gIHByaXZhdGUgZ2V0IExlbmd0aCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnNraXBFbXB0eVBvc2l0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRQb3NpdGlvbiA8PSB0aGlzLmVuZFBvc2l0aW9uID8gdGhpcy5lbmRQb3NpdGlvbiAtIHRoaXMuc3RhcnRQb3NpdGlvbiArIDEgOiAwO1xuICB9XG5cbiAgLyoqIENhbGN1bGF0ZSBuZXcgcG9zaXRpb24gZGF0YSBiYXNpYyBvbiB7QGxpbmsgcG9zaXRpb25NYXJnaW5TdGF0ZX0gYW5kIHtAbGluayBwb3NpdGlvbk1hcmdpbn0gKi9cbiAgcHJpdmF0ZSBnZXQgcG9zaXRpb25XaWR0aFdpdGhNYXJnaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uV2lkdGggKyB0aGlzLnBvc2l0aW9uTWFyZ2luVmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGdldCBwb3NpdGlvbk1hcmdpblZhbHVlKCkge1xuICAgIGlmICgodGhpcy5wb3NpdGlvbk1hcmdpblN0YXRlID09PSAnYXV0bycpICYmICh0aGlzLnVuaXRzSGFuZGxlcj8uZ2V0QWxwaGFiZXRJc011bHRpY2hhcigpID09PSB0cnVlKSkge1xuICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb25NYXJnaW47XG4gICAgfVxuICAgIGlmICh0aGlzLnBvc2l0aW9uTWFyZ2luU3RhdGUgPT09ICdlbmFibGUnKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbk1hcmdpbjtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKiBDb3VudCBvZiBwb3NpdGlvbiByZW5kZXJlZCBmb3IgY2FsY3VsYXRpb25zIGNvdW50T2ZSZW5kZXJQb3NpdGlvbnMgKi9cbiAgcHJpdmF0ZSBnZXQgY291bnRPZlJlbmRlclBvc2l0aW9ucygpIHtcbiAgICBpZiAodGhpcy5ob3N0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCByID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gICAgaWYgKHIgPiAxKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYW52YXNXaWR0aFdpdGhSYXRpbyAvIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmNhbnZhcy53aWR0aCAvICh0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luICogcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgY2FudmFzV2lkdGhXaXRoUmF0aW8oKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLndpZHRoICogd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIH1cblxuXG4gIC8qKiBQb3NpdGlvbiBvZiBzdGFydCByZW5kZXJpbmcgKi9cbiAgcHJpdmF0ZSBnZXQgZmlyc3RWaXNpYmxlSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMudmlzaWJsZVNsaWRlcikgPyBNYXRoLmZsb29yKHRoaXMuc2xpZGVyLm1pbikgOiAwO1xuICB9XG5cbiAgcHJpdmF0ZSB2aWV3U3ViczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy52aWV3ZXJJZCA9IFdlYkxvZ28udmlld2VyQ291bnQ7XG4gICAgV2ViTG9nby52aWV3ZXJDb3VudCArPSAxO1xuXG4gICAgdGhpcy50ZXh0QmFzZWxpbmUgPSAndG9wJztcbiAgICB0aGlzLnVuaXRzSGFuZGxlciA9IG51bGw7XG5cbiAgICB0aGlzLmJhY2tncm91bmRDb2xvciA9IHRoaXMuaW50KCdiYWNrZ3JvdW5kQ29sb3InLCAweEZGRkZGRkZGKTtcbiAgICB0aGlzLl9wb3NpdGlvbldpZHRoID0gdGhpcy5wb3NpdGlvbldpZHRoID0gdGhpcy5mbG9hdCgncG9zaXRpb25XaWR0aCcsIDE2LyosXG4gICAgICB7ZWRpdG9yOiAnc2xpZGVyJywgbWluOiA0LCBtYXg6IDY0LCBwb3N0Zml4OiAncHgnfSovKTtcbiAgICB0aGlzLm1pbkhlaWdodCA9IHRoaXMuZmxvYXQoJ21pbkhlaWdodCcsIDUwLyosXG4gICAgICB7ZWRpdG9yOiAnc2xpZGVyJywgbWluOiAyNSwgbWF4OiAyNTAsIHBvc3RmaXg6ICdweCd9Ki8pO1xuICAgIHRoaXMubWF4SGVpZ2h0ID0gdGhpcy5mbG9hdCgnbWF4SGVpZ2h0JywgMTAwLyosXG4gICAgICB7ZWRpdG9yOiAnc2xpZGVyJywgbWluOiAyNSwgbWF4OiA1MDAsIHBvc3RmaXg6ICdweCd9Ki8pO1xuXG4gICAgdGhpcy5za2lwRW1wdHlTZXF1ZW5jZXMgPSB0aGlzLmJvb2woJ3NraXBFbXB0eVNlcXVlbmNlcycsIHRydWUpO1xuICAgIHRoaXMuc2VxdWVuY2VDb2x1bW5OYW1lID0gdGhpcy5zdHJpbmcoJ3NlcXVlbmNlQ29sdW1uTmFtZScsIG51bGwpO1xuXG4gICAgdGhpcy5zdGFydFBvc2l0aW9uTmFtZSA9IHRoaXMuc3RyaW5nKCdzdGFydFBvc2l0aW9uTmFtZScsIG51bGwpO1xuICAgIHRoaXMuZW5kUG9zaXRpb25OYW1lID0gdGhpcy5zdHJpbmcoJ2VuZFBvc2l0aW9uTmFtZScsIG51bGwpO1xuXG4gICAgdGhpcy5maXhXaWR0aCA9IHRoaXMuYm9vbCgnZml4V2lkdGgnLCBmYWxzZSk7XG5cbiAgICB0aGlzLnZlcnRpY2FsQWxpZ25tZW50ID0gdGhpcy5zdHJpbmcoJ3ZlcnRpY2FsQWxpZ25tZW50JywgJ21pZGRsZScsXG4gICAgICB7Y2hvaWNlczogWyd0b3AnLCAnbWlkZGxlJywgJ2JvdHRvbSddfSk7XG4gICAgdGhpcy5ob3Jpem9udGFsQWxpZ25tZW50ID0gdGhpcy5zdHJpbmcoJ2hvcml6b250YWxBbGlnbm1lbnQnLCAnY2VudGVyJyxcbiAgICAgIHtjaG9pY2VzOiBbJ2xlZnQnLCAnY2VudGVyJywgJ3JpZ2h0J119KTtcbiAgICB0aGlzLmZpdEFyZWEgPSB0aGlzLmJvb2woJ2ZpdEFyZWEnLCB0cnVlKTtcbiAgICB0aGlzLnNocmlua0VtcHR5VGFpbCA9IHRoaXMuYm9vbCgnc2hyaW5rRW1wdHlUYWlsJywgdHJ1ZSk7XG4gICAgdGhpcy5za2lwRW1wdHlQb3NpdGlvbnMgPSB0aGlzLmJvb2woJ3NraXBFbXB0eVBvc2l0aW9ucycsIGZhbHNlKTtcbiAgICB0aGlzLnBvc2l0aW9uTWFyZ2luU3RhdGUgPSB0aGlzLnN0cmluZygncG9zaXRpb25NYXJnaW5TdGF0ZScsICdhdXRvJyxcbiAgICAgIHtjaG9pY2VzOiBbJ2F1dG8nLCAnZW5hYmxlJywgJ29mZiddfSk7XG4gICAgbGV0IGRlZmF1bHRWYWx1ZUZvclBvc2l0aW9uTWFyZ2luID0gMDtcbiAgICBpZiAodGhpcy5wb3NpdGlvbk1hcmdpblN0YXRlID09PSAnYXV0bycpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZUZvclBvc2l0aW9uTWFyZ2luID0gNDtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbk1hcmdpbiA9IHRoaXMuaW50KCdwb3NpdGlvbk1hcmdpbicsIGRlZmF1bHRWYWx1ZUZvclBvc2l0aW9uTWFyZ2luLCB7bWluOiAwLCBtYXg6IDE2fSk7XG4gICAgdGhpcy5wb3NpdGlvbkhlaWdodCA9IHRoaXMuc3RyaW5nKCdwb3NpdGlvbkhlaWdodCcsIFBvc2l0aW9uSGVpZ2h0LmZ1bGwsIHtjaG9pY2VzOiBbUG9zaXRpb25IZWlnaHQuZnVsbCwgUG9zaXRpb25IZWlnaHQuRW50cm9weV19KTtcblxuICAgIGNvbnN0IHN0eWxlOiBTbGlkZXJPcHRpb25zID0ge3N0eWxlOiAnYmFyYmVsbCd9O1xuICAgIHRoaXMuc2xpZGVyID0gdWkucmFuZ2VTbGlkZXIoMCwgMTAwLCAwLCAyMCwgZmFsc2UsIHN0eWxlKTtcbiAgICB0aGlzLmNhbnZhcyA9IHVpLmNhbnZhcygpO1xuICAgIHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmluaXRpYWxpemVkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdXZWJMb2dvIHNlY29uZCBpbml0aWFsaXphdGlvbiEnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLmhlbHBVcmwgPSAnL2hlbHAvdmlzdWFsaXplL3ZpZXdlcnMvd2ViLWxvZ28ubWQnO1xuXG4gICAgdGhpcy5tc2dIb3N0ID0gdWkuZGl2KCdObyBtZXNzYWdlJyk7XG4gICAgdGhpcy5tc2dIb3N0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICB0aGlzLmNhbnZhcyA9IHVpLmNhbnZhcygpO1xuICAgIHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuXG4gICAgLy90aGlzLnNsaWRlci5zZXRTaG93SGFuZGxlcyhmYWxzZSk7XG4gICAgdGhpcy5zbGlkZXIucm9vdC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgdGhpcy5zbGlkZXIucm9vdC5zdHlsZS56SW5kZXggPSAnOTk5JztcbiAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgdGhpcy5zbGlkZXIucm9vdC5zdHlsZS5oZWlnaHQgPSAnMC43ZW0nO1xuXG4gICAgdGhpcy52aXNpYmxlU2xpZGVyID0gZmFsc2U7XG5cbiAgICB0aGlzLnNsaWRlci5vblZhbHVlc0NoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGlmICgodGhpcy5ob3N0ID09IG51bGwpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8qIFJlc2l6ZSBzbGlkZXIgaWYgd2UgY2FuIHJlc2l6ZSBkbyB0aGF0ICovXG4gICAgICBpZiAoKHRoaXMuYWxsb3dSZXNpemUpICYmICghdGhpcy50dXJuT2ZSZXNpemVGb3JPbmVTZXRWYWx1ZSkgJiZcbiAgICAgICAgKHRoaXMudmlzaWJsZVNsaWRlcikpIHtcbiAgICAgICAgY29uc3QgY291bnRPZlBvc2l0aW9ucyA9IE1hdGguY2VpbCh0aGlzLnNsaWRlci5tYXggLSB0aGlzLnNsaWRlci5taW4pO1xuICAgICAgICBjb25zdCBjYWxjdWxhdGVkV2lkdGggPSAodGhpcy5jYW52YXMud2lkdGggLyBjb3VudE9mUG9zaXRpb25zKSAtIHRoaXMucG9zaXRpb25NYXJnaW5WYWx1ZTtcbiAgICAgICAgLy8gc2F2aW5nIHBvc2l0aW9uV2lkdGggdmFsdWUgZ2xvYmFsIChldmVuIGlmIHNsaWRlciBpcyBub3QgdmlzaWJsZSlcbiAgICAgICAgdGhpcy5wb3NpdGlvbldpZHRoID0gY2FsY3VsYXRlZFdpZHRoO1xuICAgICAgICB0aGlzLl9wb3NpdGlvbldpZHRoID0gY2FsY3VsYXRlZFdpZHRoO1xuICAgICAgfVxuICAgICAgdGhpcy50dXJuT2ZSZXNpemVGb3JPbmVTZXRWYWx1ZSA9IGZhbHNlO1xuICAgICAgdGhpcy5yZW5kZXIodHJ1ZSk7XG4gICAgfSk7XG5cblxuICAgIHRoaXMuaG9zdCA9IHVpLmRpdihbdGhpcy5tc2dIb3N0LCB0aGlzLmNhbnZhc10pO1xuXG4gICAgdGhpcy5ob3N0LnN0eWxlLmp1c3RpZnlDb250ZW50ID0gJ2NlbnRlcic7XG4gICAgdGhpcy5ob3N0LnN0eWxlLmFsaWduSXRlbXMgPSAnY2VudGVyJztcbiAgICB0aGlzLmhvc3Quc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnb3ZlcmZsb3cnLCAnaGlkZGVuJywgJ2ltcG9ydGFudCcpO1xuXG4gICAgY29uc3QgZ2V0TW9ub21lciA9IChwOiBERy5Qb2ludCk6IFtudW1iZXIsIHN0cmluZyB8IG51bGwsIFBvc2l0aW9uTW9ub21lckluZm8gfCBudWxsXSA9PiB7XG4gICAgICBjb25zdCBjYWxjdWxhdGVkWCA9IHAueCArIHRoaXMuZmlyc3RWaXNpYmxlSW5kZXggKiB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luO1xuICAgICAgY29uc3QgalBvcyA9IE1hdGguZmxvb3IocC54IC8gdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiArIHRoaXMuZmlyc3RWaXNpYmxlSW5kZXgpO1xuICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLnBvc2l0aW9uc1tqUG9zXTtcblxuICAgICAgaWYgKHBvc2l0aW9uID09PSB2b2lkIDApXG4gICAgICAgIHJldHVybiBbalBvcywgbnVsbCwgbnVsbF07XG5cbiAgICAgIGNvbnN0IG1vbm9tZXI6IHN0cmluZyB8IHVuZGVmaW5lZCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uLmZyZXEpXG4gICAgICAgIC5maW5kKChtKSA9PiBwb3NpdGlvbi5mcmVxW21dLmJvdW5kcy5jb250YWlucyhjYWxjdWxhdGVkWCwgcC55KSk7XG4gICAgICBpZiAobW9ub21lciA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gW2pQb3MsIG51bGwsIG51bGxdO1xuXG4gICAgICByZXR1cm4gW2pQb3MsIG1vbm9tZXIsIHBvc2l0aW9uLmZyZXFbbW9ub21lcl1dO1xuICAgIH07XG5cbiAgICBjb25zdCBjb3JyZWN0TW9ub21lckZpbHRlciA9IChpUm93OiBudW1iZXIsIG1vbm9tZXI6IHN0cmluZywgalBvczogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBzZXEgPSB0aGlzLnNlcUNvbCEuZ2V0KGlSb3cpO1xuICAgICAgY29uc3Qgc2VxTSA9IHNlcSA/IHRoaXMuc3BsaXR0ZXIhKHNlcSlbdGhpcy5zdGFydFBvc2l0aW9uICsgalBvc10gOiBudWxsO1xuICAgICAgcmV0dXJuICgoc2VxTSA9PT0gbW9ub21lcikgfHwgKHNlcU0gPT09ICcnICYmIG1vbm9tZXIgPT09ICctJykpICYmIHRoaXMuZGF0YUZyYW1lLmZpbHRlci5nZXQoaVJvdyk7XG4gICAgfTtcblxuICAgIHJ4anMuZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMuY2FudmFzLCAnbW91c2Vtb3ZlJykuc3Vic2NyaWJlKChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBhcmdzID0gZSBhcyBNb3VzZUV2ZW50O1xuXG4gICAgICBjb25zdCByOiBudW1iZXIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICAgIGNvbnN0IGN1cnNvclA6IERHLlBvaW50ID0gdGhpcy5jYW52YXMuZ2V0Q3Vyc29yUG9zaXRpb24oYXJncywgcik7XG4gICAgICBjb25zdCBbalBvcywgbW9ub21lcl0gPSBnZXRNb25vbWVyKGN1cnNvclApO1xuICAgICAgaWYgKHRoaXMuZGF0YUZyYW1lICYmIHRoaXMuc2VxQ29sICYmIHRoaXMuc3BsaXR0ZXIgJiYgbW9ub21lcikge1xuICAgICAgICBjb25zdCByb3dDb3VudCA9IHd1LmNvdW50KCkudGFrZSh0aGlzLmRhdGFGcmFtZS5yb3dDb3VudCkuZmlsdGVyKGZ1bmN0aW9uKGlSb3cpIHtcbiAgICAgICAgICByZXR1cm4gY29ycmVjdE1vbm9tZXJGaWx0ZXIoaVJvdywgbW9ub21lciwgalBvcyk7XG4gICAgICAgIH0pLnJlZHVjZTxudW1iZXI+KChjb3VudCwgaVJvdykgPT4gY291bnQgKyAxLCAwKTtcbiAgICAgICAgdWkudG9vbHRpcC5zaG93KHVpLmRpdihbdWkuZGl2KGAke21vbm9tZXJ9YCksIHVpLmRpdihgJHtyb3dDb3VudH0gcm93c2ApXSksIGFyZ3MueCArIDE2LCBhcmdzLnkgKyAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1aS50b29sdGlwLmhpZGUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJ4anMuZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMuY2FudmFzLCAnbW91c2Vkb3duJykuc3Vic2NyaWJlKChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBhcmdzID0gZSBhcyBNb3VzZUV2ZW50O1xuICAgICAgY29uc3QgcjogbnVtYmVyID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gICAgICBjb25zdCBbalBvcywgbW9ub21lcl0gPSBnZXRNb25vbWVyKHRoaXMuY2FudmFzLmdldEN1cnNvclBvc2l0aW9uKGFyZ3MsIHIpKTtcblxuICAgICAgLy8gcHJldmVudHMgZGVzZWxlY3QgYWxsIHJvd3MgaWYgd2UgbWlzcyBtb25vbWVyIGJvdW5kc1xuICAgICAgaWYgKHRoaXMuZGF0YUZyYW1lICYmIHRoaXMuc2VxQ29sICYmIHRoaXMuc3BsaXR0ZXIgJiYgbW9ub21lcikge1xuICAgICAgICB0aGlzLmRhdGFGcmFtZS5zZWxlY3Rpb24uaW5pdChmdW5jdGlvbihpUm93KSB7XG4gICAgICAgICAgcmV0dXJuIGNvcnJlY3RNb25vbWVyRmlsdGVyKGlSb3csIG1vbm9tZXIsIGpQb3MpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJ4anMuZnJvbUV2ZW50PFdoZWVsRXZlbnQ+KHRoaXMuY2FudmFzLCAnd2hlZWwnKS5zdWJzY3JpYmUoKGU6IFdoZWVsRXZlbnQpID0+IHtcbiAgICAgIGlmICghdGhpcy52aXNpYmxlU2xpZGVyKVxuICAgICAgICByZXR1cm47XG4gICAgICBjb25zdCBjb3VudE9mU2Nyb2xsUG9zaXRpb25zID0gKGUuZGVsdGFZIC8gMTAwKSAqIE1hdGgubWF4KE1hdGguZmxvb3IoKHRoaXMuY291bnRPZlJlbmRlclBvc2l0aW9ucykgLyAyKSwgMSk7XG4gICAgICB0aGlzLnNsaWRlci5zY3JvbGxCeSh0aGlzLnNsaWRlci5taW4gKyBjb3VudE9mU2Nyb2xsUG9zaXRpb25zKTtcblxuICAgIH0pO1xuXG4gICAgdGhpcy52aWV3U3Vicy5wdXNoKHVpLm9uU2l6ZUNoYW5nZWQodGhpcy5yb290KS5zdWJzY3JpYmUodGhpcy5yb290T25TaXplQ2hhbmdlZC5iaW5kKHRoaXMpKSk7XG5cbiAgICB0aGlzLnJvb3QuYXBwZW5kKHRoaXMuaG9zdCk7XG4gICAgdGhpcy5yb290LmFwcGVuZCh0aGlzLnNsaWRlci5yb290KTtcblxuICAgIHRoaXMuX2NhbGN1bGF0ZSh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyk7XG4gICAgdGhpcy51cGRhdGVTbGlkZXIoKTtcbiAgICB0aGlzLnJlbmRlcih0cnVlKTtcbiAgfVxuXG4gIC8qKiBIYW5kbGVyIG9mIGNoYW5naW5nIHNpemUgV2ViTG9nbyAqL1xuICBwcml2YXRlIHJvb3RPblNpemVDaGFuZ2VkKCk6IHZvaWQge1xuICAgIHRoaXMuX2NhbGN1bGF0ZSh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyk7XG4gICAgdGhpcy51cGRhdGVTbGlkZXIoKTtcbiAgICB0aGlzLnJlbmRlcih0cnVlKTtcbiAgfVxuXG4gIC8qKiBBc3NpZ25zIHtAbGluayBzZXFDb2x9IGFuZCB7QGxpbmsgY3B9IGJhc2VkIG9uIHtAbGluayBzZXF1ZW5jZUNvbHVtbk5hbWV9IGFuZCBjYWxscyB7QGxpbmsgcmVuZGVyfSgpLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVTZXFDb2woKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YUZyYW1lKSB7XG4gICAgICB0aGlzLnNlcUNvbCA9IHRoaXMuc2VxdWVuY2VDb2x1bW5OYW1lID8gdGhpcy5kYXRhRnJhbWUuY29sKHRoaXMuc2VxdWVuY2VDb2x1bW5OYW1lKSA6IG51bGw7XG4gICAgICBpZiAodGhpcy5zZXFDb2wgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLnNlcUNvbCA9IHBpY2tVcFNlcUNvbCh0aGlzLmRhdGFGcmFtZSk7XG4gICAgICAgIHRoaXMuc2VxdWVuY2VDb2x1bW5OYW1lID0gdGhpcy5zZXFDb2wgPyB0aGlzLnNlcUNvbC5uYW1lIDogbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnNlcUNvbCkge1xuICAgICAgICBjb25zdCB1bml0czogc3RyaW5nID0gdGhpcy5zZXFDb2whLmdldFRhZyhERy5UQUdTLlVOSVRTKTtcbiAgICAgICAgY29uc3Qgc2VwYXJhdG9yOiBzdHJpbmcgPSB0aGlzLnNlcUNvbCEuZ2V0VGFnKFRBR1Muc2VwYXJhdG9yKTtcbiAgICAgICAgdGhpcy5zcGxpdHRlciA9IGdldFNwbGl0dGVyKHVuaXRzLCBzZXBhcmF0b3IpO1xuICAgICAgICB0aGlzLnVuaXRzSGFuZGxlciA9IG5ldyBVbml0c0hhbmRsZXIodGhpcy5zZXFDb2wpO1xuXG4gICAgICAgIHRoaXMudXBkYXRlUG9zaXRpb25zKCk7XG4gICAgICAgIHRoaXMuY3AgPSBwaWNrVXBQYWxldHRlKHRoaXMuc2VxQ29sKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3BsaXR0ZXIgPSBudWxsO1xuICAgICAgICB0aGlzLnBvc2l0aW9uTmFtZXMgPSBbXTtcbiAgICAgICAgdGhpcy5zdGFydFBvc2l0aW9uID0gLTE7XG4gICAgICAgIHRoaXMuZW5kUG9zaXRpb24gPSAtMTtcbiAgICAgICAgdGhpcy5jcCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKiogVXBkYXRlcyB7QGxpbmsgcG9zaXRpb25OYW1lc30gYW5kIGNhbGN1bGF0ZXMge0BsaW5rIHN0YXJ0UG9zaXRpb259IGFuZCB7QGxpbmsgZW5kUG9zaXRpb259LlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVQb3NpdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNlcUNvbClcbiAgICAgIHJldHVybjtcblxuICAgIGxldCBjYXRlZ29yaWVzOiAoc3RyaW5nIHwgbnVsbCkgW107XG4gICAgaWYgKHRoaXMuc2hyaW5rRW1wdHlUYWlsKSB7XG4gICAgICBjb25zdCBpbmRpY2VzOiBJbnQzMkFycmF5ID0gdGhpcy5kYXRhRnJhbWUuZmlsdGVyLmdldFNlbGVjdGVkSW5kZXhlcygpO1xuICAgICAgY2F0ZWdvcmllcyA9IEFycmF5LmZyb20obmV3IFNldChcbiAgICAgICAgQXJyYXkuZnJvbShBcnJheShpbmRpY2VzLmxlbmd0aCkua2V5cygpKS5tYXAoKGk6IG51bWJlcikgPT4gdGhpcy5zZXFDb2whLmdldChpbmRpY2VzW2ldKSkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2F0ZWdvcmllcyA9IHRoaXMuc2VxQ29sLmNhdGVnb3JpZXM7XG4gICAgfVxuICAgIGNvbnN0IG1heExlbmd0aCA9IGNhdGVnb3JpZXMubGVuZ3RoID4gMCA/IE1hdGgubWF4KC4uLmNhdGVnb3JpZXMubWFwKFxuICAgICAgKHMpID0+IHMgIT09IG51bGwgPyB0aGlzLnNwbGl0dGVyIShzKS5sZW5ndGggOiAwKSkgOiAwO1xuXG4gICAgLy8gR2V0IHBvc2l0aW9uIG5hbWVzIGZyb20gZGF0YSBjb2x1bW4gdGFnICdwb3NpdGlvbk5hbWVzJ1xuICAgIGNvbnN0IHBvc2l0aW9uTmFtZXNUeHQgPSB0aGlzLnNlcUNvbC5nZXRUYWcoJ3Bvc2l0aW9uTmFtZXMnKTtcbiAgICAvLyBGYWxsYmFjayBpZiAncG9zaXRpb25OYW1lcycgdGFnIGlzIG5vdCBwcm92aWRlZFxuICAgIHRoaXMucG9zaXRpb25OYW1lcyA9IHBvc2l0aW9uTmFtZXNUeHQgPyBwb3NpdGlvbk5hbWVzVHh0LnNwbGl0KCcsICcpLm1hcCgobikgPT4gbi50cmltKCkpIDpcbiAgICAgIFsuLi5BcnJheShtYXhMZW5ndGgpLmtleXMoKV0ubWFwKChqUG9zKSA9PiBgJHtqUG9zICsgMX1gKTtcblxuICAgIHRoaXMuc3RhcnRQb3NpdGlvbiA9ICh0aGlzLnN0YXJ0UG9zaXRpb25OYW1lICYmIHRoaXMucG9zaXRpb25OYW1lcyAmJlxuICAgICAgdGhpcy5wb3NpdGlvbk5hbWVzLmluY2x1ZGVzKHRoaXMuc3RhcnRQb3NpdGlvbk5hbWUpKSA/XG4gICAgICB0aGlzLnBvc2l0aW9uTmFtZXMuaW5kZXhPZih0aGlzLnN0YXJ0UG9zaXRpb25OYW1lKSA6IDA7XG4gICAgdGhpcy5lbmRQb3NpdGlvbiA9ICh0aGlzLmVuZFBvc2l0aW9uTmFtZSAmJiB0aGlzLnBvc2l0aW9uTmFtZXMgJiZcbiAgICAgIHRoaXMucG9zaXRpb25OYW1lcy5pbmNsdWRlcyh0aGlzLmVuZFBvc2l0aW9uTmFtZSkpID9cbiAgICAgIHRoaXMucG9zaXRpb25OYW1lcy5pbmRleE9mKHRoaXMuZW5kUG9zaXRpb25OYW1lKSA6IChtYXhMZW5ndGggLSAxKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHdpZHRoQXJlYSgpIHtcbiAgICByZXR1cm4gdGhpcy5MZW5ndGggKiB0aGlzLnBvc2l0aW9uV2lkdGggLyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGhlaWdodEFyZWEoKSB7XG4gICAgcmV0dXJuIE1hdGgubWluKHRoaXMubWF4SGVpZ2h0LCBNYXRoLm1heCh0aGlzLm1pbkhlaWdodCwgdGhpcy5yb290LmNsaWVudEhlaWdodCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgeFNjYWxlKCkge1xuICAgIHJldHVybiAodGhpcy5yb290LmNsaWVudFdpZHRoIC0gdGhpcy5MZW5ndGggKiB0aGlzLnBvc2l0aW9uTWFyZ2luVmFsdWUpIC8gdGhpcy53aWR0aEFyZWE7XG4gIH1cblxuICBwcml2YXRlIGdldCB5U2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdC5jbGllbnRIZWlnaHQgLyB0aGlzLmhlaWdodEFyZWE7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSXNIaWRlU2xpZGVyKCk6IGJvb2xlYW4ge1xuICAgIGxldCBzaG93U2xpZGVyV2l0aEZpdEFyZWEgPSB0cnVlO1xuICAgIGNvbnN0IG1pblNjYWxlID0gTWF0aC5taW4odGhpcy54U2NhbGUsIHRoaXMueVNjYWxlKTtcblxuICAgIGlmICgoKG1pblNjYWxlID09IHRoaXMueFNjYWxlKSB8fCAobWluU2NhbGUgPD0gMSkpICYmICh0aGlzLmZpdEFyZWEpKSB7XG4gICAgICBzaG93U2xpZGVyV2l0aEZpdEFyZWEgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuICgodGhpcy5maXhXaWR0aCB8fCBNYXRoLmNlaWwodGhpcy5jYW52YXMud2lkdGggLyB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luKSA+PSB0aGlzLkxlbmd0aCkgfHwgKHNob3dTbGlkZXJXaXRoRml0QXJlYSkpO1xuICB9XG5cbiAgc2V0U2xpZGVyVmlzaWJpbGl0eSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHZpc2libGUpIHtcbiAgICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuZGlzcGxheSA9ICdpbmhlcml0JztcbiAgICAgIHRoaXMudmlzaWJsZVNsaWRlciA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHRoaXMudmlzaWJsZVNsaWRlciA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHtAbGluayBzbGlkZXJ9LCBuZWVkZWQgdG8gc2V0IHNsaWRlciBvcHRpb25zIGFuZCB0byB1cGRhdGUgc2xpZGVyIHBvc2l0aW9uLiAqL1xuICBwcml2YXRlIHVwZGF0ZVNsaWRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGVja0lzSGlkZVNsaWRlcigpKSB7XG4gICAgICB0aGlzLnNldFNsaWRlclZpc2liaWxpdHkoZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFNsaWRlclZpc2liaWxpdHkodHJ1ZSk7XG4gICAgfVxuICAgIGlmICgodGhpcy5zbGlkZXIgIT0gbnVsbCkgJiYgKHRoaXMuY2FudmFzICE9IG51bGwpKSB7XG4gICAgICBsZXQgZGlmZkVuZFNjcm9sbEFuZFNsaWRlck1pbiA9IE1hdGguZmxvb3IodGhpcy5zbGlkZXIubWluICsgdGhpcy5jYW52YXMud2lkdGggLyB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luKSAtIHRoaXMuTGVuZ3RoO1xuICAgICAgZGlmZkVuZFNjcm9sbEFuZFNsaWRlck1pbiA9IGRpZmZFbmRTY3JvbGxBbmRTbGlkZXJNaW4gPiAwID8gZGlmZkVuZFNjcm9sbEFuZFNsaWRlck1pbiA6IDA7XG4gICAgICBsZXQgbmV3TWluID0gTWF0aC5mbG9vcih0aGlzLnNsaWRlci5taW4gLSBkaWZmRW5kU2Nyb2xsQW5kU2xpZGVyTWluKTtcbiAgICAgIGxldCBuZXdNYXggPSBNYXRoLmZsb29yKHRoaXMuc2xpZGVyLm1pbiAtIGRpZmZFbmRTY3JvbGxBbmRTbGlkZXJNaW4pICsgTWF0aC5mbG9vcih0aGlzLmNhbnZhcy53aWR0aCAvIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4pO1xuICAgICAgaWYgKHRoaXMuY2hlY2tJc0hpZGVTbGlkZXIoKSkge1xuICAgICAgICBuZXdNaW4gPSAwO1xuICAgICAgICBuZXdNYXggPSB0aGlzLkxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgICB0aGlzLnR1cm5PZlJlc2l6ZUZvck9uZVNldFZhbHVlID0gdHJ1ZTtcbiAgICAgIHRoaXMuc2xpZGVyLnNldFZhbHVlcygwLCB0aGlzLkxlbmd0aCxcbiAgICAgICAgbmV3TWluLCBuZXdNYXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBIYW5kbGVyIG9mIHByb3BlcnR5IGNoYW5nZSBldmVudHMuICovXG4gIHB1YmxpYyBvdmVycmlkZSBvblByb3BlcnR5Q2hhbmdlZChwcm9wZXJ0eTogREcuUHJvcGVydHkpOiB2b2lkIHtcbiAgICBzdXBlci5vblByb3BlcnR5Q2hhbmdlZChwcm9wZXJ0eSk7XG5cbiAgICBzd2l0Y2ggKHByb3BlcnR5Lm5hbWUpIHtcbiAgICBjYXNlICdzZXF1ZW5jZUNvbHVtbk5hbWUnOlxuICAgICAgdGhpcy51cGRhdGVTZXFDb2woKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3N0YXJ0UG9zaXRpb25OYW1lJzpcbiAgICAgIHRoaXMudXBkYXRlU2VxQ29sKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdlbmRQb3NpdGlvbk5hbWUnOlxuICAgICAgdGhpcy51cGRhdGVTZXFDb2woKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Bvc2l0aW9uV2lkdGgnOlxuICAgICAgdGhpcy5fcG9zaXRpb25XaWR0aCA9IHRoaXMucG9zaXRpb25XaWR0aDtcbiAgICAgIHRoaXMudXBkYXRlU2xpZGVyKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdmaXhXaWR0aCc6XG4gICAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZml0QXJlYSc6XG4gICAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2hyaW5rRW1wdHlUYWlsJzpcbiAgICAgIHRoaXMudXBkYXRlUG9zaXRpb25zKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdza2lwRW1wdHlQb3NpdGlvbnMnOlxuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbnMoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Bvc2l0aW9uTWFyZ2luJzpcbiAgICAgIHRoaXMudXBkYXRlU2xpZGVyKCk7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcih0cnVlKTtcbiAgfVxuXG4gIC8qKiBBZGQgZmlsdGVyIGhhbmRsZXJzIHdoZW4gdGFibGUgaXMgYSBhdHRhY2hlZCAgKi9cbiAgcHVibGljIG92ZXJyaWRlIG9uVGFibGVBdHRhY2hlZCgpIHtcbiAgICBzdXBlci5vblRhYmxlQXR0YWNoZWQoKTtcblxuICAgIGNvbnN0IGRhdGFGcmFtZVR4dDogc3RyaW5nID0gdGhpcy5kYXRhRnJhbWUgPyAnZGF0YScgOiAnbnVsbCc7XG4gICAgY29uc29sZS5kZWJ1ZyhgYmlvOiBXZWJMb2dvPCR7dGhpcy52aWV3ZXJJZH0+Lm9uVGFibGVBdHRhY2hlZCggZGF0YUZyYW1lID0gJHtkYXRhRnJhbWVUeHR9ICkgc3RhcnRgKTtcblxuICAgIHRoaXMudXBkYXRlU2VxQ29sKCk7XG5cbiAgICBpZiAodGhpcy5kYXRhRnJhbWUgIT09IHZvaWQgMCkge1xuICAgICAgdGhpcy5zdWJzLnB1c2godGhpcy5kYXRhRnJhbWUuc2VsZWN0aW9uLm9uQ2hhbmdlZC5zdWJzY3JpYmUoKF8pID0+IHRoaXMucmVuZGVyKCkpKTtcbiAgICAgIHRoaXMuc3Vicy5wdXNoKHRoaXMuZGF0YUZyYW1lLmZpbHRlci5vbkNoYW5nZWQuc3Vic2NyaWJlKChfKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlUG9zaXRpb25zKCk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgdGhpcy5pbml0KCk7XG4gICAgY29uc29sZS5kZWJ1ZyhgYmlvOiBXZWJMb2dvPCR7dGhpcy52aWV3ZXJJZH0+Lm9uVGFibGVBdHRhY2hlZCgpIGVuZGApO1xuICB9XG5cbiAgLyoqIFJlbW92ZSBhbGwgaGFuZGxlcnMgd2hlbiB0YWJsZSBpcyBhIGRldGFjaCAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGRldGFjaCgpIHtcbiAgICBjb25zdCBkYXRhRnJhbWVUeHQgPSBgJHt0aGlzLmRhdGFGcmFtZSA/ICdkYXRhJyA6ICdudWxsJ31gO1xuICAgIGNvbnNvbGUuZGVidWcoYGJpbzogV2ViTG9nbzwke3RoaXMudmlld2VySWR9Pi5vblRhYmxlQXR0YWNoZWQoIGRhdGFGcmFtZSA9ICR7ZGF0YUZyYW1lVHh0fSApIHN0YXJ0YCk7XG4gICAgc3VwZXIuZGV0YWNoKCk7XG5cbiAgICB0aGlzLnZpZXdTdWJzLmZvckVhY2goKHN1YikgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgIHRoaXMuaG9zdCEucmVtb3ZlKCk7XG4gICAgdGhpcy5tc2dIb3N0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaG9zdCA9IHVuZGVmaW5lZDtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBjb25zb2xlLmRlYnVnKGBiaW86IFdlYkxvZ288JHt0aGlzLnZpZXdlcklkfT4ub25UYWJsZUF0dGFjaGVkKCkgZW5kYCk7XG4gIH1cblxuICAvKiogSGVscGVyIGZ1bmN0aW9uIGZvciByZW5kZXJpbmcgKi9cbiAgcHJvdGVjdGVkIF9udWxsU2VxdWVuY2UoZmlsbGVyUmVzaWR1ZSA9ICdYJyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLnNraXBFbXB0eVNlcXVlbmNlcylcbiAgICAgIHJldHVybiBuZXcgQXJyYXkodGhpcy5MZW5ndGgpLmZpbGwoZmlsbGVyUmVzaWR1ZSkuam9pbignJyk7XG5cbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICAvKiogSGVscGVyIGZ1bmN0aW9uIGZvciByZW1vdmUgZW1wdHkgcG9zaXRpb25zICovXG4gIC8vIFRPRE86IHVzZSB0aGlzIGZ1bmN0aW9uIGluIGZyb20gY29yZVxuICBwcm90ZWN0ZWQgcmVtb3ZlV2hlcmUoYXJyYXk6IEFycmF5PGFueT4sIHByZWRpY2F0ZTogKFQ6IGFueSkgPT4gYm9vbGVhbik6IEFycmF5PGFueT4ge1xuICAgIGxldCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgbGV0IHVwZGF0ZUl0ZXJhdG9yID0gMDtcbiAgICBmb3IgKGxldCBkZWxldGVJdGVyYXRvciA9IDA7IGRlbGV0ZUl0ZXJhdG9yIDwgbGVuZ3RoOyBkZWxldGVJdGVyYXRvcisrKSB7XG4gICAgICBpZiAoIXByZWRpY2F0ZShhcnJheVtkZWxldGVJdGVyYXRvcl0pKSB7XG4gICAgICAgIGFycmF5W3VwZGF0ZUl0ZXJhdG9yXSA9IGFycmF5W2RlbGV0ZUl0ZXJhdG9yXTtcbiAgICAgICAgdXBkYXRlSXRlcmF0b3IrKztcbiAgICAgIH1cbiAgICB9XG4gICAgYXJyYXkubGVuZ3RoID0gdXBkYXRlSXRlcmF0b3I7XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cblxuICAvKiogRnVuY3Rpb24gZm9yIHJlbW92aW5nIGVtcHR5IHBvc2l0aW9ucyAqL1xuICBwcm90ZWN0ZWQgX3JlbW92ZUVtcHR5UG9zaXRpb25zKCkge1xuICAgIGlmICh0aGlzLnNraXBFbXB0eVBvc2l0aW9ucykge1xuICAgICAgdGhpcy5yZW1vdmVXaGVyZSh0aGlzLnBvc2l0aW9ucywgaXRlbSA9PiBpdGVtPy5mcmVxWyctJ10/LmNvdW50ID09PSBpdGVtLnJvd0NvdW50KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2NhbGN1bGF0ZShyOiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMuaG9zdCB8fCAhdGhpcy5zZXFDb2wgfHwgIXRoaXMuZGF0YUZyYW1lKVxuICAgICAgcmV0dXJuO1xuICAgIHRoaXMudW5pdHNIYW5kbGVyID0gbmV3IFVuaXRzSGFuZGxlcih0aGlzLnNlcUNvbCk7XG5cbiAgICB0aGlzLmNhbGNTaXplKCk7XG5cbiAgICB0aGlzLnBvc2l0aW9ucyA9IG5ldyBBcnJheSh0aGlzLnN0YXJ0UG9zaXRpb24gPD0gdGhpcy5lbmRQb3NpdGlvbiA/IHRoaXMuZW5kUG9zaXRpb24gLSB0aGlzLnN0YXJ0UG9zaXRpb24gKyAxIDogMCk7XG4gICAgZm9yIChsZXQgalBvcyA9IDA7IGpQb3MgPCB0aGlzLkxlbmd0aDsgalBvcysrKSB7XG4gICAgICBjb25zdCBwb3NOYW1lOiBzdHJpbmcgPSB0aGlzLnBvc2l0aW9uTmFtZXNbdGhpcy5zdGFydFBvc2l0aW9uICsgalBvc107XG4gICAgICB0aGlzLnBvc2l0aW9uc1tqUG9zXSA9IG5ldyBQb3NpdGlvbkluZm8ocG9zTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gMjAyMi0wNS0wNSBhc2thbGtpbiBpbnN0cnVjdGVkIHRvIHNob3cgV2ViTG9nbyBiYXNlZCBvbiBmaWx0ZXIgKG5vdCBzZWxlY3Rpb24pXG4gICAgY29uc3QgaW5kaWNlcyA9IHRoaXMuZGF0YUZyYW1lLmZpbHRlci5nZXRTZWxlY3RlZEluZGV4ZXMoKTtcbiAgICAvLyBjb25zdCBpbmRpY2VzID0gdGhpcy5kYXRhRnJhbWUuc2VsZWN0aW9uLnRydWVDb3VudCA+IDAgPyB0aGlzLmRhdGFGcmFtZS5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWRJbmRleGVzKCkgOlxuICAgIC8vICAgdGhpcy5kYXRhRnJhbWUuZmlsdGVyLmdldFNlbGVjdGVkSW5kZXhlcygpO1xuXG4gICAgdGhpcy5yb3dzTWFza2VkID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgdGhpcy5yb3dzTnVsbCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IGkgb2YgaW5kaWNlcykge1xuICAgICAgbGV0IHM6IHN0cmluZyA9IDxzdHJpbmc+KHRoaXMuc2VxQ29sLmdldChpKSk7XG5cbiAgICAgIGlmICghcykge1xuICAgICAgICBzID0gdGhpcy5fbnVsbFNlcXVlbmNlKCk7XG4gICAgICAgICsrdGhpcy5yb3dzTnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2VxTTogc3RyaW5nW10gPSB0aGlzLnNwbGl0dGVyIShzKTtcbiAgICAgIGZvciAobGV0IGpQb3MgPSAwOyBqUG9zIDwgdGhpcy5MZW5ndGg7IGpQb3MrKykge1xuICAgICAgICBjb25zdCBwbUluZm8gPSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxO1xuICAgICAgICBjb25zdCBtOiBzdHJpbmcgPSBzZXFNW3RoaXMuc3RhcnRQb3NpdGlvbiArIGpQb3NdIHx8ICctJztcbiAgICAgICAgaWYgKCEobSBpbiBwbUluZm8pKVxuICAgICAgICAgIHBtSW5mb1ttXSA9IG5ldyBQb3NpdGlvbk1vbm9tZXJJbmZvKCk7XG4gICAgICAgIHBtSW5mb1ttXS5jb3VudCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vI3JlZ2lvbiBQb2xpc2ggZnJlcSBjb3VudHNcbiAgICBmb3IgKGxldCBqUG9zID0gMDsgalBvcyA8IHRoaXMuTGVuZ3RoOyBqUG9zKyspIHtcbiAgICAgIC8vIGRlbGV0ZSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxWyctJ107XG5cbiAgICAgIHRoaXMucG9zaXRpb25zW2pQb3NdLnJvd0NvdW50ID0gMDtcbiAgICAgIGZvciAoY29uc3QgbSBpbiB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxKVxuICAgICAgICB0aGlzLnBvc2l0aW9uc1tqUG9zXS5yb3dDb3VudCArPSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxW21dLmNvdW50O1xuICAgICAgaWYgKHRoaXMucG9zaXRpb25IZWlnaHQgPT0gUG9zaXRpb25IZWlnaHQuRW50cm9weSkge1xuICAgICAgICB0aGlzLnBvc2l0aW9uc1tqUG9zXS5zdW1Gb3JIZWlnaHRDYWxjID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBtIGluIHRoaXMucG9zaXRpb25zW2pQb3NdLmZyZXEpIHtcbiAgICAgICAgICBjb25zdCBwbiA9IHRoaXMucG9zaXRpb25zW2pQb3NdLmZyZXFbbV0uY291bnQgLyB0aGlzLnBvc2l0aW9uc1tqUG9zXS5yb3dDb3VudDtcbiAgICAgICAgICB0aGlzLnBvc2l0aW9uc1tqUG9zXS5zdW1Gb3JIZWlnaHRDYWxjICs9IC1wbiAqIE1hdGgubG9nMihwbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8jZW5kcmVnaW9uXG4gICAgdGhpcy5fcmVtb3ZlRW1wdHlQb3NpdGlvbnMoKTtcblxuICAgIGNvbnN0IGFic29sdXRlTWF4SGVpZ2h0ID0gdGhpcy5jYW52YXMuaGVpZ2h0IC0gdGhpcy5heGlzSGVpZ2h0ICogcjtcblxuICAgIC8vI3JlZ2lvbiBDYWxjdWxhdGUgc2NyZWVuXG4gICAgZm9yIChsZXQgalBvcyA9IDA7IGpQb3MgPCB0aGlzLkxlbmd0aDsgalBvcysrKSB7XG4gICAgICBjb25zdCBmcmVxOiB7IFtjOiBzdHJpbmddOiBQb3NpdGlvbk1vbm9tZXJJbmZvIH0gPSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxO1xuICAgICAgY29uc3Qgcm93Q291bnQgPSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5yb3dDb3VudDtcbiAgICAgIGNvbnN0IGFscGhhYmV0U2l6ZSA9IHRoaXMuZ2V0QWxwaGFiZXRTaXplKCk7XG4gICAgICBpZiAoKHRoaXMucG9zaXRpb25IZWlnaHQgPT0gUG9zaXRpb25IZWlnaHQuRW50cm9weSkgJiYgKGFscGhhYmV0U2l6ZSA9PSBudWxsKSkge1xuICAgICAgICBncm9rLnNoZWxsLmVycm9yKCdXZWJMb2dvOiBhbHBoYWJldCBpcyB1bmRlZmluZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1heEhlaWdodCA9ICh0aGlzLnBvc2l0aW9uSGVpZ2h0ID09IFBvc2l0aW9uSGVpZ2h0LkVudHJvcHkpID8gKGFic29sdXRlTWF4SGVpZ2h0ICogKE1hdGgubG9nMihhbHBoYWJldFNpemUpIC0gKHRoaXMucG9zaXRpb25zW2pQb3NdLnN1bUZvckhlaWdodENhbGMpKSAvIE1hdGgubG9nMihhbHBoYWJldFNpemUpKSA6IGFic29sdXRlTWF4SGVpZ2h0O1xuXG4gICAgICBsZXQgeTogbnVtYmVyID0gdGhpcy5heGlzSGVpZ2h0ICogciArIChhYnNvbHV0ZU1heEhlaWdodCAtIG1heEhlaWdodCAtIDEpO1xuXG4gICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoZnJlcSkuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICBpZiAoYVswXSAhPT0gJy0nICYmIGJbMF0gIT09ICctJylcbiAgICAgICAgICByZXR1cm4gYlsxXS5jb3VudCAtIGFbMV0uY291bnQ7XG4gICAgICAgIGVsc2UgaWYgKGFbMF0gPT09ICctJyAmJiBiWzBdID09PSAnLScpXG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIGVsc2UgaWYgKGFbMF0gPT09ICctJylcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIGVsc2UgLyogKGJbMF0gPT09ICctJykgKi9cbiAgICAgICAgICByZXR1cm4gKzE7XG4gICAgICB9KTtcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBjb25zdCBwbUluZm86IFBvc2l0aW9uTW9ub21lckluZm8gPSBlbnRyeVsxXTtcbiAgICAgICAgLy8gY29uc3QgbTogc3RyaW5nID0gZW50cnlbMF07XG4gICAgICAgIGNvbnN0IGg6IG51bWJlciA9IG1heEhlaWdodCAqIHBtSW5mby5jb3VudCAvIHJvd0NvdW50O1xuXG4gICAgICAgIHBtSW5mby5ib3VuZHMgPSBuZXcgREcuUmVjdChqUG9zICogdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiwgeSwgdGhpcy5fcG9zaXRpb25XaWR0aCwgaCk7XG4gICAgICAgIHkgKz0gaDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8jZW5kcmVnaW9uXG5cbiAgfVxuXG4gIC8qKiBSZW5kZXIgV2ViTG9nbyBzZW5zaXRpdmUgdG8gY2hhbmdlcyBpbiBwYXJhbXMgb2YgcmVuZGVyaW5nXG4gICAqQHBhcmFtIHtib29sZWFufSByZWNhbGMgLSBpbmRpY2F0ZXMgdGhhdCBuZWVkIHRvIHJlY2FsY3VsYXRlIGRhdGEgZm9yIHJlbmRlcmluZ1xuICAgKi9cbiAgcmVuZGVyKHJlY2FsYyA9IHRydWUpIHtcbiAgICBpZiAodGhpcy5tc2dIb3N0KSB7XG4gICAgICBpZiAodGhpcy5zZXFDb2wgJiYgIXRoaXMuY3ApIHtcbiAgICAgICAgdGhpcy5tc2dIb3N0IS5pbm5lclRleHQgPSBgVW5rbm93biBwYWxldHRlIChjb2x1bW4gc2VtVHlwZTogJyR7dGhpcy5zZXFDb2wuc2VtVHlwZX0nKS5gO1xuICAgICAgICB0aGlzLm1zZ0hvc3QhLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubXNnSG9zdCEuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc2VxQ29sIHx8ICF0aGlzLmRhdGFGcmFtZSB8fCAhdGhpcy5jcCB8fCB0aGlzLnN0YXJ0UG9zaXRpb24gPT09IC0xIHx8IHRoaXMuZW5kUG9zaXRpb24gPT09IC0xIHx8IHRoaXMuaG9zdCA9PSBudWxsIHx8IHRoaXMuc2xpZGVyID09IG51bGwpXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCBnID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBpZiAoIWcpIHJldHVybjtcblxuICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUud2lkdGggPSBgJHt0aGlzLmhvc3QuY2xpZW50V2lkdGh9cHhgO1xuXG4gICAgY29uc3QgciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gICAgaWYgKHJlY2FsYylcbiAgICAgIHRoaXMuX2NhbGN1bGF0ZShyKTtcblxuICAgIGcucmVzZXRUcmFuc2Zvcm0oKTtcbiAgICBnLmZpbGxTdHlsZSA9IERHLkNvbG9yLnRvSHRtbCh0aGlzLmJhY2tncm91bmRDb2xvcik7XG4gICAgZy5maWxsUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcbiAgICBnLnRleHRCYXNlbGluZSA9IHRoaXMudGV4dEJhc2VsaW5lO1xuXG4gICAgY29uc3QgbWF4Q291bnRPZlJvd3NSZW5kZXJlZCA9IHRoaXMuY291bnRPZlJlbmRlclBvc2l0aW9ucyArIDE7XG4gICAgY29uc3QgZmlyc3RWaXNpYmxlSW5kZXggPSAodGhpcy52aXNpYmxlU2xpZGVyKSA/IE1hdGguZmxvb3IodGhpcy5zbGlkZXIubWluKSA6IDA7XG4gICAgY29uc3QgbGFzdFZpc2libGVJbmRleCA9IE1hdGgubWluKHRoaXMuTGVuZ3RoLCBmaXJzdFZpc2libGVJbmRleCArIG1heENvdW50T2ZSb3dzUmVuZGVyZWQpO1xuXG4gICAgLy8jcmVnaW9uIFBsb3QgcG9zaXRpb25OYW1lc1xuICAgIGNvbnN0IHBvc2l0aW9uRm9udFNpemUgPSAxMCAqIHI7XG4gICAgZy5yZXNldFRyYW5zZm9ybSgpO1xuICAgIGcuZmlsbFN0eWxlID0gJ2JsYWNrJztcbiAgICBnLnRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgIGcuZm9udCA9IGAke3Bvc2l0aW9uRm9udFNpemUudG9GaXhlZCgxKX1weCBSb2JvdG8sIFJvYm90byBMb2NhbCwgc2Fucy1zZXJpZmA7XG4gICAgY29uc3QgcG9zTmFtZU1heFdpZHRoID0gTWF0aC5tYXgoLi4udGhpcy5wb3NpdGlvbnMubWFwKChwb3MpID0+IGcubWVhc3VyZVRleHQocG9zLm5hbWUpLndpZHRoKSk7XG4gICAgY29uc3QgaFNjYWxlID0gcG9zTmFtZU1heFdpZHRoIDwgKHRoaXMuX3Bvc2l0aW9uV2lkdGggLSAyKSA/IDEgOiAodGhpcy5fcG9zaXRpb25XaWR0aCAtIDIpIC8gcG9zTmFtZU1heFdpZHRoO1xuXG4gICAgZm9yIChsZXQgalBvcyA9IHRoaXMuZmlyc3RWaXNpYmxlSW5kZXg7IGpQb3MgPCBsYXN0VmlzaWJsZUluZGV4OyBqUG9zKyspIHtcbiAgICAgIGNvbnN0IHBvczogUG9zaXRpb25JbmZvID0gdGhpcy5wb3NpdGlvbnNbalBvc107XG4gICAgICBnLnJlc2V0VHJhbnNmb3JtKCk7XG4gICAgICBnLnNldFRyYW5zZm9ybShcbiAgICAgICAgaFNjYWxlLCAwLCAwLCAxLFxuICAgICAgICBqUG9zICogdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiArIHRoaXMuX3Bvc2l0aW9uV2lkdGggLyAyIC0gdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiAqIGZpcnN0VmlzaWJsZUluZGV4LCAwKTtcbiAgICAgIGcuZmlsbFRleHQocG9zLm5hbWUsIDAsIDApO1xuICAgIH1cbiAgICAvLyNlbmRyZWdpb24gUGxvdCBwb3NpdGlvbk5hbWVzXG4gICAgY29uc3QgZm9udFN0eWxlID0gJzE2cHggUm9ib3RvLCBSb2JvdG8gTG9jYWwsIHNhbnMtc2VyaWYnO1xuICAgIC8vIEhhY2tzIHRvIHNjYWxlIHVwcGVyY2FzZSBjaGFyYWN0ZXJzIHRvIHRhcmdldCByZWN0YW5nbGVcbiAgICBjb25zdCB1cHBlcmNhc2VMZXR0ZXJBc2NlbnQgPSAwLjI1O1xuICAgIGNvbnN0IHVwcGVyY2FzZUxldHRlckhlaWdodCA9IDEyLjI7XG4gICAgZm9yIChsZXQgalBvcyA9IHRoaXMuZmlyc3RWaXNpYmxlSW5kZXg7IGpQb3MgPCBsYXN0VmlzaWJsZUluZGV4OyBqUG9zKyspIHtcbiAgICAgIGZvciAoY29uc3QgW21vbm9tZXIsIHBtSW5mb10gb2YgT2JqZWN0LmVudHJpZXModGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcSkpIHtcbiAgICAgICAgaWYgKG1vbm9tZXIgIT09ICctJykge1xuICAgICAgICAgIGNvbnN0IG1vbm9tZXJUeHQgPSBtb25vbWVyVG9TaG9ydChtb25vbWVyLCA1KTtcbiAgICAgICAgICBjb25zdCBiID0gcG1JbmZvLmJvdW5kcztcbiAgICAgICAgICBjb25zdCBsZWZ0ID0gYi5sZWZ0IC0gdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiAqIHRoaXMuZmlyc3RWaXNpYmxlSW5kZXg7XG5cbiAgICAgICAgICBnLnJlc2V0VHJhbnNmb3JtKCk7XG4gICAgICAgICAgZy5zdHJva2VTdHlsZSA9ICdsaWdodGdyYXknO1xuICAgICAgICAgIGcubGluZVdpZHRoID0gMTtcbiAgICAgICAgICBnLnJlY3QobGVmdCwgYi50b3AsIGIud2lkdGgsIGIuaGVpZ2h0KTtcbiAgICAgICAgICBnLmZpbGxTdHlsZSA9IHRoaXMuY3AuZ2V0KG1vbm9tZXIpID8/IHRoaXMuY3AuZ2V0KCdvdGhlcicpO1xuICAgICAgICAgIGcudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgIGcuZm9udCA9IGZvbnRTdHlsZTtcbiAgICAgICAgICAvL2cuZmlsbFJlY3QoYi5sZWZ0LCBiLnRvcCwgYi53aWR0aCwgYi5oZWlnaHQpO1xuICAgICAgICAgIGNvbnN0IG1UbTogVGV4dE1ldHJpY3MgPSBnLm1lYXN1cmVUZXh0KG1vbm9tZXJUeHQpO1xuXG4gICAgICAgICAgZy5zZXRUcmFuc2Zvcm0oXG4gICAgICAgICAgICBiLndpZHRoIC8gbVRtLndpZHRoLCAwLCAwLCBiLmhlaWdodCAvIHVwcGVyY2FzZUxldHRlckhlaWdodCxcbiAgICAgICAgICAgIGxlZnQsIGIudG9wKTtcbiAgICAgICAgICBnLmZpbGxUZXh0KG1vbm9tZXJUeHQsIDAsIC11cHBlcmNhc2VMZXR0ZXJBc2NlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIENhbGN1bGF0ZSBjYW52YXMgc2l6ZSBhbiBwb3NpdGlvbldpZHRoIGFuZCB1cGRhdGVzIHByb3BlcnRpZXMgKi9cbiAgcHJpdmF0ZSBjYWxjU2l6ZSgpIHtcbiAgICBpZiAoIXRoaXMuaG9zdClcbiAgICAgIHJldHVybjtcblxuICAgIGNvbnN0IHI6IG51bWJlciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXG4gICAgbGV0IHdpZHRoOiBudW1iZXIgPSB0aGlzLndpZHRoQXJlYTtcbiAgICBsZXQgaGVpZ2h0ID0gdGhpcy5oZWlnaHRBcmVhO1xuXG4gICAgaWYgKCh0aGlzLmZpdEFyZWEpICYmICghdGhpcy52aXNpYmxlU2xpZGVyKSkge1xuICAgICAgY29uc3Qgc2NhbGUgPSBNYXRoLm1heCgxLCBNYXRoLm1pbih0aGlzLnhTY2FsZSwgdGhpcy55U2NhbGUpKTtcbiAgICAgIHdpZHRoID0gd2lkdGggKiBzY2FsZTtcbiAgICAgIGhlaWdodCA9IGhlaWdodCAqIHNjYWxlO1xuICAgICAgdGhpcy5fcG9zaXRpb25XaWR0aCA9IHRoaXMucG9zaXRpb25XaWR0aCAqIHNjYWxlO1xuICAgIH1cblxuICAgIHdpZHRoID0gdGhpcy5MZW5ndGggKiB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luIC8gcjtcblxuICAgIHRoaXMuY2FudmFzLndpZHRoID0gdGhpcy5yb290LmNsaWVudFdpZHRoICogcjtcbiAgICB0aGlzLmNhbnZhcy5zdHlsZS53aWR0aCA9IGAke3RoaXMucm9vdC5jbGllbnRXaWR0aH1weGA7XG5cbiAgICAvLyBjb25zdCBjYW52YXNIZWlnaHQ6IG51bWJlciA9IHdpZHRoID4gdGhpcy5yb290LmNsaWVudFdpZHRoID8gaGVpZ2h0IC0gOCA6IGhlaWdodDtcbiAgICB0aGlzLmhvc3Quc3R5bGUuc2V0UHJvcGVydHkoJ2hlaWdodCcsIGAke2hlaWdodH1weGApO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodDogbnVtYmVyID0gdGhpcy5ob3N0LmNsaWVudEhlaWdodDtcbiAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSBjYW52YXNIZWlnaHQgKiByO1xuXG4gICAgLy8gQWRqdXN0IGhvc3QgYW5kIHJvb3Qgd2lkdGhcbiAgICBpZiAodGhpcy5maXhXaWR0aCkge1xuICAgICAgLy8gZnVsbCB3aWR0aCBmb3IgY2FudmFzIGhvc3QgYW5kIHJvb3RcbiAgICAgIHRoaXMucm9vdC5zdHlsZS53aWR0aCA9IHRoaXMuaG9zdC5zdHlsZS53aWR0aCA9IGAke3dpZHRofXB4YDtcbiAgICAgIHRoaXMucm9vdC5zdHlsZS5oZWlnaHQgPSBgJHtoZWlnaHR9cHhgO1xuICAgICAgdGhpcy5yb290LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgICB0aGlzLmhvc3Quc3R5bGUuc2V0UHJvcGVydHkoJ292ZXJmbG93LXknLCAnaGlkZGVuJywgJ2ltcG9ydGFudCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBhbGxvdyBzY3JvbGwgY2FudmFzIGluIHJvb3RcbiAgICAgIHRoaXMucm9vdC5zdHlsZS53aWR0aCA9IHRoaXMuaG9zdC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICAgIHRoaXMuaG9zdC5zdHlsZS5vdmVyZmxvd1ggPSAnYXV0byFpbXBvcnRhbnQnO1xuICAgICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCd0ZXh0LWFsaWduJywgdGhpcy5ob3Jpem9udGFsQWxpZ25tZW50KTtcblxuICAgICAgY29uc3Qgc2xpZGVySGVpZ2h0ID0gdGhpcy52aXNpYmxlU2xpZGVyID8gMTAgOiAwO1xuXG4gICAgICAvLyB2ZXJ0aWNhbCBhbGlnbm1lbnRcbiAgICAgIGxldCBob3N0VG9wTWFyZ2luID0gMDtcbiAgICAgIHN3aXRjaCAodGhpcy52ZXJ0aWNhbEFsaWdubWVudCkge1xuICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgaG9zdFRvcE1hcmdpbiA9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWlkZGxlJzpcbiAgICAgICAgaG9zdFRvcE1hcmdpbiA9IE1hdGgubWF4KDAsICh0aGlzLnJvb3QuY2xpZW50SGVpZ2h0IC0gaGVpZ2h0KSAvIDIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgIGhvc3RUb3BNYXJnaW4gPSBNYXRoLm1heCgwLCB0aGlzLnJvb3QuY2xpZW50SGVpZ2h0IC0gaGVpZ2h0IC0gc2xpZGVySGVpZ2h0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLyBob3Jpem9udGFsIGFsaWdubWVudFxuICAgICAgbGV0IGhvc3RMZWZ0TWFyZ2luID0gMDtcbiAgICAgIHN3aXRjaCAodGhpcy5ob3Jpem9udGFsQWxpZ25tZW50KSB7XG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgaG9zdExlZnRNYXJnaW4gPSAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgIGhvc3RMZWZ0TWFyZ2luID0gTWF0aC5tYXgoMCwgKHRoaXMucm9vdC5jbGllbnRXaWR0aCAtIHdpZHRoKSAvIDIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgaG9zdExlZnRNYXJnaW4gPSBNYXRoLm1heCgwLCB0aGlzLnJvb3QuY2xpZW50V2lkdGggLSB3aWR0aCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdtYXJnaW4tdG9wJywgYCR7aG9zdFRvcE1hcmdpbn1weGAsICdpbXBvcnRhbnQnKTtcbiAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnbWFyZ2luLWxlZnQnLCBgJHtob3N0TGVmdE1hcmdpbn1weGAsICdpbXBvcnRhbnQnKTtcbiAgICAgIGlmICh0aGlzLnNsaWRlciAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuc2V0UHJvcGVydHkoJ21hcmdpbi10b3AnLCBgJHtob3N0VG9wTWFyZ2luICsgY2FudmFzSGVpZ2h0fXB4YCwgJ2ltcG9ydGFudCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5yb290LmNsaWVudEhlaWdodCA8PSBoZWlnaHQpIHtcbiAgICAgICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdoZWlnaHQnLCBgJHt0aGlzLnJvb3QuY2xpZW50SGVpZ2h0fXB4YCk7XG4gICAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnb3ZlcmZsb3cteScsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdvdmVyZmxvdy15JywgJ2hpZGRlbicsICdpbXBvcnRhbnQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0QWxwaGFiZXRTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudW5pdHNIYW5kbGVyPy5nZXRBbHBoYWJldFNpemUoKSA/PyAwO1xuICB9XG59XG4iXX0=