speechrecorderng 3.10.13 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/speechrecorderng.mjs +204 -201
  3. package/fesm2022/speechrecorderng.mjs.map +1 -1
  4. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +2 -2
  5. package/lib/spr.module.version.d.ts +1 -1
  6. package/lib/ui/canvas_layer_comp.d.ts +1 -1
  7. package/lib/ui/responsive_component.d.ts +1 -1
  8. package/package.json +13 -15
  9. package/esm2022/lib/action/action.mjs +0 -73
  10. package/esm2022/lib/audio/array_audio_buffer.mjs +0 -164
  11. package/esm2022/lib/audio/array_audio_buffer_input_stream.mjs +0 -86
  12. package/esm2022/lib/audio/array_audio_buffer_random_access_stream.mjs +0 -16
  13. package/esm2022/lib/audio/audio_data_holder.mjs +0 -264
  14. package/esm2022/lib/audio/audio_display.mjs +0 -118
  15. package/esm2022/lib/audio/audio_player.mjs +0 -238
  16. package/esm2022/lib/audio/capture/capture.mjs +0 -855
  17. package/esm2022/lib/audio/context.mjs +0 -79
  18. package/esm2022/lib/audio/dsp/level_measure.mjs +0 -517
  19. package/esm2022/lib/audio/format.mjs +0 -20
  20. package/esm2022/lib/audio/impl/wavformat.mjs +0 -7
  21. package/esm2022/lib/audio/impl/wavreader.mjs +0 -144
  22. package/esm2022/lib/audio/impl/wavwriter.mjs +0 -191
  23. package/esm2022/lib/audio/inddb_audio_buffer.mjs +0 -508
  24. package/esm2022/lib/audio/io/stream.mjs +0 -59
  25. package/esm2022/lib/audio/net_audio_buffer.mjs +0 -293
  26. package/esm2022/lib/audio/persistor.mjs +0 -81
  27. package/esm2022/lib/audio/playback/array_audio_buffer_source_node.mjs +0 -126
  28. package/esm2022/lib/audio/playback/audio_source_node.mjs +0 -18
  29. package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
  30. package/esm2022/lib/audio/playback/inddb_audio_buffer_source_node.mjs +0 -167
  31. package/esm2022/lib/audio/playback/net_audio_buffer_source_node.mjs +0 -218
  32. package/esm2022/lib/audio/playback/player.mjs +0 -402
  33. package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
  34. package/esm2022/lib/audio/ui/audio_display_control.mjs +0 -150
  35. package/esm2022/lib/audio/ui/audio_display_scroll_pane.mjs +0 -146
  36. package/esm2022/lib/audio/ui/audiosignal.mjs +0 -533
  37. package/esm2022/lib/audio/ui/common.mjs +0 -19
  38. package/esm2022/lib/audio/ui/container.mjs +0 -414
  39. package/esm2022/lib/audio/ui/livelevel.mjs +0 -361
  40. package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
  41. package/esm2022/lib/audio/ui/sonagram.mjs +0 -900
  42. package/esm2022/lib/db/inddb.mjs +0 -120
  43. package/esm2022/lib/dsp/utils.mjs +0 -48
  44. package/esm2022/lib/environment/environment.defaults.mjs +0 -9
  45. package/esm2022/lib/io/BinaryReader.mjs +0 -93
  46. package/esm2022/lib/io/BinaryWriter.mjs +0 -80
  47. package/esm2022/lib/io/stream.mjs +0 -259
  48. package/esm2022/lib/math/2d/geometry.mjs +0 -28
  49. package/esm2022/lib/math/complex.mjs +0 -58
  50. package/esm2022/lib/math/dft.mjs +0 -196
  51. package/esm2022/lib/media/utils.mjs +0 -14
  52. package/esm2022/lib/net/uploader.mjs +0 -367
  53. package/esm2022/lib/recorder_component.mjs +0 -65
  54. package/esm2022/lib/speechrecorder/project/project.mjs +0 -54
  55. package/esm2022/lib/speechrecorder/project/project.service.mjs +0 -64
  56. package/esm2022/lib/speechrecorder/recording.mjs +0 -124
  57. package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -221
  58. package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
  59. package/esm2022/lib/speechrecorder/script/script.mjs +0 -114
  60. package/esm2022/lib/speechrecorder/script/script.service.mjs +0 -47
  61. package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
  62. package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +0 -676
  63. package/esm2022/lib/speechrecorder/session/controlpanel.mjs +0 -416
  64. package/esm2022/lib/speechrecorder/session/item.mjs +0 -30
  65. package/esm2022/lib/speechrecorder/session/progress.mjs +0 -135
  66. package/esm2022/lib/speechrecorder/session/prompting.mjs +0 -639
  67. package/esm2022/lib/speechrecorder/session/recorder_combi_pane.mjs +0 -88
  68. package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
  69. package/esm2022/lib/speechrecorder/session/recording_list.mjs +0 -188
  70. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +0 -128
  71. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +0 -114
  72. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +0 -146
  73. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +0 -424
  74. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file.mjs +0 -68
  75. package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
  76. package/esm2022/lib/speechrecorder/session/session.mjs +0 -2
  77. package/esm2022/lib/speechrecorder/session/session.service.mjs +0 -69
  78. package/esm2022/lib/speechrecorder/session/session_finished_dialog.mjs +0 -46
  79. package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +0 -1385
  80. package/esm2022/lib/speechrecorder/session/warning_bar.mjs +0 -33
  81. package/esm2022/lib/speechrecorder/spruploader.mjs +0 -22
  82. package/esm2022/lib/speechrecorder/startstopsignal/startstopsignal.mjs +0 -2
  83. package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
  84. package/esm2022/lib/speechrecorderng.component.mjs +0 -392
  85. package/esm2022/lib/speechrecorderng.module.mjs +0 -97
  86. package/esm2022/lib/spr.config.mjs +0 -27
  87. package/esm2022/lib/spr.module.version.mjs +0 -2
  88. package/esm2022/lib/ui/canvas_layer_comp.mjs +0 -38
  89. package/esm2022/lib/ui/intersection-observer.directive.mjs +0 -32
  90. package/esm2022/lib/ui/message_dialog.mjs +0 -51
  91. package/esm2022/lib/ui/recordingitem_display.mjs +0 -253
  92. package/esm2022/lib/ui/responsive_component.mjs +0 -24
  93. package/esm2022/lib/utils/scrollIntoViewToBottom.mjs +0 -23
  94. package/esm2022/lib/utils/ua-parser.mjs +0 -190
  95. package/esm2022/lib/utils/utils.mjs +0 -132
  96. package/esm2022/lib/utils/wake_lock.mjs +0 -114
  97. package/esm2022/lib/utils/wake_lock_media.mjs +0 -2
  98. package/esm2022/public-api.mjs +0 -35
  99. package/esm2022/speechrecorderng.mjs +0 -5
@@ -1,900 +0,0 @@
1
- import { DFTFloat32 } from '../../math/dft';
2
- import { Point } from './common';
3
- import { Component, ViewChild } from "@angular/core";
4
- import { AudioCanvasLayerComponent } from "./audio_canvas_layer_comp";
5
- import { WorkerHelper } from "../../utils/utils";
6
- import { AudioBufferSource } from "../audio_data_holder";
7
- import * as i0 from "@angular/core";
8
- const DEFAULT_DFT_SIZE = 1024;
9
- export class Sonagram extends AudioCanvasLayerComponent {
10
- constructor(ref) {
11
- super();
12
- this.ref = ref;
13
- this._playFramePosition = null;
14
- this.raAsSubsc = null;
15
- this.dftSize = DEFAULT_DFT_SIZE;
16
- this.worker = null;
17
- this._audioDataHolder = null;
18
- this.markers = new Array();
19
- this.dft = new DFTFloat32(this.dftSize);
20
- this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
21
- this._bgColor = null;
22
- this._selectColor = 'rgba(255,255,0,0.1)';
23
- }
24
- ngAfterViewInit() {
25
- this.ce = this.ref.nativeElement;
26
- this.sonagramCanvas = this.sonagramCanvasRef.nativeElement;
27
- this.sonagramCanvas.style.zIndex = '1';
28
- this.bgCanvas = this.bgCanvasRef.nativeElement;
29
- this.bgCanvas.style.zIndex = '2';
30
- this.cursorCanvas = this.cursorCanvasRef.nativeElement;
31
- this.cursorCanvas.style.zIndex = '4';
32
- this.markerCanvas = this.markerCanvasRef.nativeElement;
33
- this.markerCanvas.style.zIndex = '3';
34
- this.canvasLayers[0] = this.sonagramCanvas;
35
- this.canvasLayers[1] = this.bgCanvas;
36
- this.canvasLayers[2] = this.cursorCanvas;
37
- this.canvasLayers[3] = this.markerCanvas;
38
- }
39
- get playFramePosition() {
40
- return this._playFramePosition;
41
- }
42
- set playFramePosition(playFramePosition) {
43
- this._playFramePosition = playFramePosition;
44
- // this.redraw();
45
- this.drawPlayPosition();
46
- }
47
- canvasMousePos(c, e) {
48
- const cr = c.getBoundingClientRect();
49
- const x = e.x - cr.left;
50
- const y = e.y - cr.top;
51
- return new Point(x, y);
52
- }
53
- drawStateText(stateText) {
54
- if (stateText) {
55
- const g = this.sonagramCanvas.getContext("2d");
56
- const w = this.sonagramCanvas.width;
57
- const h = this.sonagramCanvas.height;
58
- if (g && w && h) {
59
- g.strokeStyle = 'black';
60
- g.fillStyle = 'black';
61
- g.font = '20px sans-serif';
62
- g.fillText(stateText, 10, 25);
63
- }
64
- }
65
- }
66
- drawCursorPosition(e, show) {
67
- if (this.cursorCanvas) {
68
- const w = this.cursorCanvas.width;
69
- const h = this.cursorCanvas.height;
70
- const g = this.cursorCanvas.getContext('2d');
71
- if (g) {
72
- g.clearRect(0, 0, w, h);
73
- if (show) {
74
- //const pp = this.canvasMousePos(this.cursorCanvas, e);
75
- let xViewPortPixelpos = e.offsetX;
76
- g.fillStyle = 'yellow';
77
- g.strokeStyle = 'yellow';
78
- g.beginPath();
79
- g.moveTo(xViewPortPixelpos, 0);
80
- g.lineTo(xViewPortPixelpos, h);
81
- g.closePath();
82
- g.stroke();
83
- if (this._audioDataHolder) {
84
- let framePosRound = this.viewPortXPixelToFramePosition(xViewPortPixelpos);
85
- if (framePosRound != null) {
86
- g.font = '14px sans-serif';
87
- g.fillStyle = 'yellow';
88
- g.fillText(framePosRound.toString(), xViewPortPixelpos + 2, 50);
89
- }
90
- }
91
- }
92
- }
93
- }
94
- }
95
- drawPlayPosition() {
96
- if (this.markerCanvas) {
97
- const w = this.markerCanvas.width;
98
- const h = this.markerCanvas.height;
99
- const g = this.markerCanvas.getContext("2d");
100
- if (g) {
101
- g.clearRect(0, 0, w, h);
102
- if (this._playFramePosition != null) {
103
- let pixelPos = this.frameToViewPortXPixelPosition(this._playFramePosition);
104
- if (pixelPos) {
105
- g.fillStyle = 'red';
106
- g.strokeStyle = 'red';
107
- g.beginPath();
108
- g.moveTo(pixelPos, 0);
109
- g.lineTo(pixelPos, h);
110
- g.closePath();
111
- g.stroke();
112
- }
113
- }
114
- }
115
- }
116
- }
117
- /*
118
- * Method used as worker code.
119
- */
120
- workerFunction() {
121
- // Redefine some DSP classes for worker function
122
- // See e.g. audio.math.Complex
123
- class Complex {
124
- static fromPolarForm(magnitude, argument) {
125
- const r = Math.cos(argument) * magnitude;
126
- const i = Math.sin(argument) * magnitude;
127
- return new Complex(r, i);
128
- }
129
- constructor(real, img) {
130
- this.real = real;
131
- this.img = img;
132
- }
133
- magnitude() {
134
- return Math.sqrt((this.real * this.real) + (this.img * this.img));
135
- }
136
- argument() {
137
- return Math.atan2(this.img, this.real);
138
- }
139
- add(addC) {
140
- return new Complex(this.real + addC.real, this.img + addC.img);
141
- }
142
- sub(subC) {
143
- return new Complex(this.real - subC.real, this.img - subC.img);
144
- }
145
- mult(multC) {
146
- const multR = (this.real * multC.real) - (this.img * multC.img);
147
- const multI = (this.real * multC.img) + (multC.real * this.img);
148
- return new Complex(multR, multI);
149
- }
150
- multReal(multF) {
151
- return new Complex(this.real * multF, this.img * multF);
152
- }
153
- div(divisor) {
154
- const divReal = divisor.real;
155
- const divImg = divisor.img;
156
- const div = (divReal * divReal) + (divImg * divImg);
157
- const divisionReal = ((this.real * divReal) + (this.img * divImg)) / div;
158
- const divisionImg = ((divReal * this.img) - (this.real * divImg)) / div;
159
- return new Complex(divisionReal, divisionImg);
160
- }
161
- divReal(divisor) {
162
- const div = divisor * divisor;
163
- const divsionReal = (this.real * divisor) / div;
164
- const divsionImg = (divisor * this.img) / div;
165
- return new Complex(divsionReal, divsionImg);
166
- }
167
- conjugate() {
168
- return new Complex(this.real, -this.img);
169
- }
170
- equals(c) {
171
- if (c === null) {
172
- return false;
173
- }
174
- return (this.real === c.real && this.img === c.img);
175
- }
176
- toString() {
177
- return 'Real: ' + this.real + ', Img: ' + this.img;
178
- }
179
- }
180
- class DFTFloat32 {
181
- constructor(n) {
182
- this.n = n;
183
- this.m = Math.log(n) / Math.log(2);
184
- // if(n != (1 << m))throw new RuntimeException("length N must be power of 2");
185
- // lookup tables
186
- this.cosLookup = new Float32Array(n / 2);
187
- this.sinLookup = new Float32Array(n / 2);
188
- for (let i = 0; i < n / 2; i++) {
189
- const arc = (-2 * Math.PI * i) / n;
190
- this.cosLookup[i] = Math.cos(arc);
191
- this.sinLookup[i] = Math.sin(arc);
192
- }
193
- }
194
- processReal(srcBuf) {
195
- const x = srcBuf.slice();
196
- const y = new Float32Array(srcBuf.length);
197
- for (let yi = 0; yi < y.length; yi++) {
198
- y[yi] = 0.0;
199
- }
200
- this.fftCooleyTukey(x, y);
201
- const rc = new Array(x.length);
202
- for (let i = 0; i < x.length; i++) {
203
- rc[i] = new Complex(x[i], y[i]);
204
- }
205
- return rc;
206
- }
207
- processRealMagnitude(srcBuf) {
208
- const x = srcBuf.slice();
209
- const y = new Float32Array(srcBuf.length);
210
- for (let yi = 0; yi < y.length; yi++) {
211
- y[yi] = 0.0;
212
- }
213
- this.fftCooleyTukey(x, y);
214
- const rc = new Float32Array(x.length);
215
- for (let i = 0; i < x.length; i++) {
216
- const rcc = new Complex(x[i], y[i]);
217
- rc[i] = rcc.magnitude();
218
- }
219
- return rc;
220
- }
221
- fftCooleyTukey(real, img) {
222
- let i;
223
- let j = 0;
224
- let k;
225
- let n1;
226
- let n2 = this.n / 2;
227
- let a;
228
- let c;
229
- let s;
230
- let t1;
231
- let t2;
232
- for (i = 1; i < this.n - 1; i++) {
233
- n1 = n2;
234
- while (j >= n1) {
235
- j = j - n1;
236
- n1 = n1 / 2;
237
- }
238
- j = j + n1;
239
- if (i < j) {
240
- t1 = real[i];
241
- real[i] = real[j];
242
- real[j] = t1;
243
- t1 = img[i];
244
- img[i] = img[j];
245
- img[j] = t1;
246
- }
247
- }
248
- n1 = 0;
249
- n2 = 1;
250
- for (i = 0; i < this.m; i++) {
251
- n1 = n2;
252
- n2 = n2 + n2;
253
- a = 0;
254
- for (j = 0; j < n1; j++) {
255
- c = this.cosLookup[a];
256
- s = this.sinLookup[a];
257
- a += (1 << (this.m - i - 1));
258
- for (k = j; k < this.n; k = k + n2) {
259
- t1 = c * real[k + n1] - s * img[k + n1];
260
- t2 = s * real[k + n1] + c * img[k + n1];
261
- real[k + n1] = real[k] - t1;
262
- img[k + n1] = img[k] - t2;
263
- real[k] = real[k] + t1;
264
- img[k] = img[k] + t2;
265
- }
266
- }
267
- }
268
- }
269
- process(t) {
270
- const reals = new Float32Array(this.n);
271
- const imgs = new Float32Array(this.n);
272
- const trans = new Array(this.n);
273
- for (let i = 0; i < this.n; i++) {
274
- reals[i] = t[i].real;
275
- imgs[i] = t[i].img;
276
- }
277
- this.fftCooleyTukey(reals, imgs);
278
- for (let i = 0; i < this.n; i++) {
279
- trans[i] = new Complex(reals[i], imgs[i]);
280
- }
281
- return trans;
282
- }
283
- }
284
- class GaussianWindow {
285
- static { this.DEFAULT_SIGMA = 0.3; }
286
- constructor(size, sigma = GaussianWindow.DEFAULT_SIGMA) {
287
- this.buf = new Float32Array(size);
288
- const center = (size - 1) / 2;
289
- for (let i = 0; i < size; i++) {
290
- const quot = (i - center) / (sigma * center);
291
- const exp = -0.5 * quot * quot;
292
- this.buf[i] = Math.exp(exp);
293
- }
294
- }
295
- getScale(i) {
296
- return this.buf[i];
297
- }
298
- }
299
- self.onmessage = function (msg) {
300
- //console.debug("Sonagram render thread");
301
- let l = msg.data.l;
302
- let w = msg.data.w;
303
- let h = msg.data.h;
304
- let vw = msg.data.vw;
305
- let chs = msg.data.chs;
306
- let audioDataOffset = 0;
307
- let adOffset = msg.data.audioDataOffset;
308
- if (adOffset) {
309
- audioDataOffset = adOffset;
310
- }
311
- let maxPsd = null;
312
- if (msg.data.maxPsd !== undefined) {
313
- maxPsd = msg.data.maxPsd;
314
- }
315
- let audioData = new Array(chs);
316
- for (let ch = 0; ch < chs; ch++) {
317
- audioData[ch] = new Float32Array(msg.data['audioData'][ch]);
318
- }
319
- let frameLength = msg.data.frameLength;
320
- let dftSize = msg.data.dftSize;
321
- let dftBands = dftSize / 2;
322
- let dft = new DFTFloat32(dftSize);
323
- let wf = new GaussianWindow(dftSize);
324
- let arrSize = w * h * 4;
325
- if (arrSize < 0) {
326
- arrSize = 0;
327
- }
328
- let imgData = new Uint8ClampedArray(arrSize);
329
- //console.log("Render method:");
330
- //console.debug("Created imgData arrSize: "+arrSize+" ", w, "x", h);
331
- let calcMaxPsd = -Infinity;
332
- if (arrSize > 0) {
333
- let chH = Math.round(h / chs);
334
- let framesPerPixel = frameLength / vw;
335
- //console.debug("Render: ", w, "x", h);
336
- let b = new Float32Array(dftSize);
337
- let sona = new Array(chs);
338
- for (let ch = 0; ch < chs; ch++) {
339
- let chDataLen = audioData[ch].length;
340
- // initialize DFT array buffer
341
- sona[ch] = new Array(w);
342
- let framePos = 0;
343
- for (let pii = 0; pii < w; pii++) {
344
- let virtPii = l + pii;
345
- // Position of sample data frame is pixel position mapped to audio frame position.
346
- // Then "center" the frame by shifting left by half the DFT size (=dftBands)
347
- framePos = Math.round((virtPii * framesPerPixel) - dftBands);
348
- // fill DFT buffer with windowed sample values
349
- for (let i = 0; i < dftSize; i++) {
350
- let samplePos = framePos + i;
351
- // initialize for negative sample positions and out of bounds positions
352
- let chDat = 0;
353
- // Set audio sample if available
354
- let adp = samplePos - audioDataOffset;
355
- if (adp >= 0 && adp < chDataLen) {
356
- chDat = audioData[ch][adp];
357
- //console.debug("Audio data: "+chDat);
358
- }
359
- else {
360
- //console.debug("Sample buf pos oob: adp: "+adp+", chDataLen: "+chDataLen+", samplePos: "+samplePos+", i: "+i);
361
- }
362
- // apply Window
363
- b[i] = chDat * wf.getScale(i);
364
- }
365
- // Calc DFT magnitudes
366
- let spectr = dft.processRealMagnitude(b);
367
- // Get maximum value of spectral energy
368
- for (let s = 0; s < dftBands; s++) {
369
- let psd = (2 * Math.pow(spectr[s], 2)) / dftBands;
370
- if (psd > calcMaxPsd) {
371
- calcMaxPsd = psd;
372
- }
373
- }
374
- // Set render model data for this pixel
375
- sona[ch][pii] = spectr;
376
- }
377
- }
378
- if (!msg.data.norender) {
379
- if (!maxPsd) {
380
- maxPsd = calcMaxPsd;
381
- }
382
- for (let ch = 0; ch < chs; ch++) {
383
- for (let pii = 0; pii < w; pii++) {
384
- let allBlack = true;
385
- for (let y = 0; y < chH; y++) {
386
- let freqIdx = Math.round(y * dftBands / chH);
387
- // calculate the one-sided power spectral density PSD (f, t) in Pa2/Hz
388
- // PSD(f) proportional to 2|X(f)|2 / (t2 - t1)
389
- let val = sona[ch][pii][freqIdx];
390
- let psd = (2 * Math.pow(val, 2)) / dftBands;
391
- // Calculate logarithmic value
392
- //let psdLog = ips.dsp.DSPUtils.toLevelInDB(psd / maxPsd);
393
- let linearLevel = psd / maxPsd;
394
- let psdLog = 10 * Math.log(linearLevel) / Math.log(10);
395
- // Fixed dynamic Range value of 70dB for now
396
- let dynRangeInDb = 70;
397
- let scaledVal = (psdLog + dynRangeInDb) / dynRangeInDb;
398
- // are the following checks necessary for clamped array ?
399
- if (scaledVal > 1.0)
400
- scaledVal = 1;
401
- if (scaledVal < 0.0) {
402
- scaledVal = 0;
403
- }
404
- let rgbVal = Math.round(255 * scaledVal);
405
- if (rgbVal < 0) {
406
- // System.out.println("Neg RGB val: "+rgbVal);
407
- rgbVal = 0;
408
- }
409
- if (rgbVal > 255) {
410
- rgbVal = 255;
411
- }
412
- rgbVal = 255 - rgbVal;
413
- if (rgbVal > 0) {
414
- allBlack = false;
415
- }
416
- let py = chH - y;
417
- let dataPos = ((((ch * chH) + py) * w) + pii) * 4;
418
- imgData[dataPos + 0] = rgbVal; //R
419
- imgData[dataPos + 1] = rgbVal; //G
420
- imgData[dataPos + 2] = rgbVal; //B
421
- imgData[dataPos + 3] = 255; //A (alpha: fully opaque)
422
- //console.debug("Rendered: py: "+py+", rgbval: "+rgbVal);
423
- // example 1x1, 2chs
424
- // ch0x0y0R,ch0x0y0G,ch0x0y0B,ch0x0y0A,
425
- // ch0x1y0R,ch0x1y0G,ch0x1y0B,ch0x1y0A,
426
- // ch0x0y0R,ch0x0y0G,ch0x0y0B,ch0x0y0A,
427
- // ch0x1y1R,ch0x1y1G,ch0x1y1B,ch0x1y1A,
428
- // ch1x0y0R,ch1x0y0G,ch1x0y0B,ch1x0y0A,
429
- // ch1x1y0R,ch1x1y0G,ch1x1y0B,ch1x1y0A,
430
- // ch1x0y0R,ch1x0y0G,ch1x0y0B,ch1x0y0A,
431
- // ch1x1y1R,ch1x1y1G,ch1x1y1B,ch1x1y1A
432
- }
433
- // if (allBlack) {
434
- // console.log("Black: ", pii, " ", ch);
435
- // }
436
- }
437
- }
438
- }
439
- }
440
- //console.debug("Render thread post message imgData: "+imgData.length)
441
- postMessage({ imgData: imgData, l: l, w: msg.data.w, h: msg.data.h, vw: vw, maxPsd: calcMaxPsd, terminate: msg.data.terminate }, [imgData.buffer]);
442
- };
443
- }
444
- startDraw(clear = true) {
445
- if (clear) {
446
- if (this.bounds) {
447
- this.sonagramCanvas.style.left = Math.round(this.bounds.position.left).toString() + 'px';
448
- let intW = Math.round(this.bounds.dimension.width);
449
- let intH = Math.round(this.bounds.dimension.height);
450
- this.sonagramCanvas.width = intW;
451
- this.sonagramCanvas.height = intH;
452
- let g = this.sonagramCanvas.getContext("2d");
453
- if (g) {
454
- //g.clearRect(0, 0,w, h);
455
- g.fillStyle = "white";
456
- g.fillRect(0, 0, intW, intH);
457
- }
458
- }
459
- }
460
- this.startRender();
461
- this.drawCursorLayer();
462
- }
463
- startRender() {
464
- //console.debug("Sonagram start render...");
465
- if (this.worker) {
466
- this.worker.terminate();
467
- this.worker = null;
468
- }
469
- if (this.raAsSubsc) {
470
- this.raAsSubsc.unsubscribe();
471
- }
472
- if (this._audioDataHolder) {
473
- this._audioDataHolder.addOnReadyListener(() => {
474
- if (this._audioDataHolder && this.bounds && this.bounds.dimension) {
475
- let w = Math.round(this.bounds.dimension.width);
476
- let h = Math.round(this.bounds.dimension.height);
477
- let vw = Math.round(this.virtualDimension.width);
478
- if (w > 0 && h > 0 && vw > 0) {
479
- this.worker = new Worker(this.workerURL);
480
- //this.wo = new Worker('./worker/sonagram.worker', { type: `module` });
481
- let chs = this._audioDataHolder.numberOfChannels;
482
- let vw = Math.round(this.virtualDimension.width);
483
- let frameLength = this._audioDataHolder.frameLen;
484
- let framesPerPixel = Math.ceil(frameLength / vw);
485
- let leftPos = Math.round(this.bounds.position.left);
486
- let renderPos = leftPos;
487
- let raAs = this._audioDataHolder.randomAccessAudioStream();
488
- let audioBuffer = null;
489
- let audioSource = this._audioDataHolder.audioSource;
490
- if (audioSource instanceof AudioBufferSource) {
491
- audioBuffer = audioSource.audioBuffer;
492
- }
493
- //let arrayAudioBuffer=this._audioDataHolder.arrayBuffer;
494
- let arrAbBuf;
495
- let ada = new Array(chs);
496
- // for(let ch=0;ch<chs;ch++) {
497
- // ada[ch] = new Float32Array(this.dftSize);
498
- // }
499
- let imgData;
500
- let maxPsd = -Infinity;
501
- let norender = true;
502
- if (this.worker) {
503
- this.worker.onmessage = (me) => {
504
- if (true === me.data.terminate) {
505
- let drawImgData;
506
- if (imgData) {
507
- drawImgData = imgData;
508
- }
509
- else {
510
- drawImgData = me.data.imgData;
511
- }
512
- this.drawRendered(w, h, drawImgData);
513
- if (this.worker) {
514
- this.worker.terminate();
515
- }
516
- this.worker = null;
517
- raAs.close();
518
- }
519
- else {
520
- // set rendered vertical values of one pixel of timescale
521
- //let dataPos = renderPos * h * 4;
522
- if (norender) {
523
- if (me.data.maxPsd > maxPsd) {
524
- maxPsd = me.data.maxPsd;
525
- //console.debug("new maxPsd: "+maxPsd);
526
- }
527
- }
528
- else {
529
- let chH = Math.round(h / chs);
530
- let idp = me.data.l - leftPos;
531
- for (let ch = 0; ch < chs; ch++) {
532
- for (let y = 0; y < chH; y++) {
533
- let py = chH - y;
534
- let dataPos = ((((ch * chH) + py) * w) + idp) * 4;
535
- let mePos = ((ch * chH) + py) * 4;
536
- //let lastPos = dataPos + me.data.imgData.length;
537
- //if (lastPos < imgData.length) {
538
- // set one pixel
539
- imgData[dataPos] = me.data.imgData[mePos];
540
- imgData[dataPos + 1] = me.data.imgData[mePos + 1];
541
- imgData[dataPos + 2] = me.data.imgData[mePos + 2];
542
- imgData[dataPos + 3] = me.data.imgData[mePos + 3];
543
- //} else {
544
- //console.error("Out of range: " + dataPos + "+" + me.data.imgData.length + ">=" + imgData.length);
545
- // }
546
- }
547
- }
548
- }
549
- if (this._audioDataHolder && arrAbBuf && this.worker) {
550
- // proceed with next pixel
551
- renderPos++;
552
- //console.debug("Render pos: "+renderPos);
553
- let terminate = false;
554
- let windowEnd = renderPos >= leftPos + w;
555
- if (windowEnd) {
556
- if (norender) {
557
- // phase two: rendering
558
- norender = false;
559
- // start from beginning
560
- renderPos = leftPos;
561
- //console.debug("now rendering: maxPsd: "+maxPsd);
562
- }
563
- else {
564
- // terminate render phase
565
- terminate = true;
566
- }
567
- }
568
- let leftFramePos = Math.floor(frameLength * renderPos / vw) - this.dftSize / 2;
569
- if (leftFramePos < 0) {
570
- leftFramePos = 0;
571
- }
572
- //let ada = new Array<ArrayBuffer>(chs);
573
- //console.debug("Render pos: "+renderPos+" leftFramePos: "+leftFramePos);
574
- if (!terminate) {
575
- if (this._audioDataHolder) {
576
- //let read = this._audioDataHolder.frames(leftFramePos, this.dftSize, arrAbBuf);
577
- this.raAsSubsc = raAs.framesObs(leftFramePos, this.dftSize, arrAbBuf).subscribe({
578
- next: (read) => {
579
- if (arrAbBuf && this.worker) {
580
- if (read < this.dftSize) {
581
- // zero padding
582
- for (let ch = 0; ch < chs; ch++) {
583
- for (let zp = read; zp < this.dftSize; zp++) {
584
- arrAbBuf[ch][zp] = 0;
585
- }
586
- }
587
- }
588
- for (let ch = 0; ch < chs; ch++) {
589
- // Need a copy here for the worker, otherwise this.audioData is not accessible after posting to the worker
590
- //ada[ch] = arrAbBuf[ch].buffer.slice(0);
591
- const arrAbBufCh = arrAbBuf[ch];
592
- const adLen = arrAbBufCh.buffer.byteLength;
593
- if (!ada[ch] || ada[ch].byteLength !== adLen) {
594
- ada[ch] = new ArrayBuffer(adLen);
595
- }
596
- let fAdaCh = new Float32Array(ada[ch]);
597
- fAdaCh.set(arrAbBuf[ch]);
598
- }
599
- this.worker.postMessage({
600
- audioData: ada,
601
- audioDataOffset: leftFramePos,
602
- l: renderPos,
603
- w: me.data.w,
604
- h: h,
605
- vw: vw,
606
- chs: chs,
607
- frameLength: frameLength,
608
- dftSize: this.dftSize,
609
- maxPsd: maxPsd,
610
- norender: norender,
611
- terminate: terminate
612
- }, ada);
613
- }
614
- },
615
- error: (err) => {
616
- console.error("Sonagram: Error reading audio data: " + err);
617
- }
618
- });
619
- }
620
- }
621
- else {
622
- for (let ch = 0; ch < chs; ch++) {
623
- ada[ch] = new ArrayBuffer(0);
624
- }
625
- this.worker.postMessage({
626
- audioData: ada,
627
- audioDataOffset: leftFramePos,
628
- l: renderPos,
629
- w: me.data.w,
630
- h: h,
631
- vw: vw,
632
- chs: chs,
633
- frameLength: frameLength,
634
- dftSize: this.dftSize,
635
- maxPsd: maxPsd,
636
- norender: norender,
637
- terminate: terminate
638
- }, ada);
639
- }
640
- }
641
- }
642
- };
643
- }
644
- if (audioBuffer && audioBuffer.length * audioBuffer.numberOfChannels < AudioCanvasLayerComponent.ENABLE_STREAMING_NUMBER_OF_SAMPLES_THRESHOLD) {
645
- let ada = new Array(chs);
646
- for (let ch = 0; ch < chs; ch++) {
647
- // Need a copy here for the worker, otherwise this.audioData is not accessible after posting to the worker
648
- ada[ch] = audioBuffer.getChannelData(ch).buffer.slice(0);
649
- }
650
- //let start = Date.now();
651
- if (this.markerCanvas) {
652
- let g = this.markerCanvas.getContext("2d");
653
- if (g) {
654
- g.fillText("Rendering...", 10, 20);
655
- }
656
- }
657
- this.worker.postMessage({
658
- audioData: ada,
659
- l: leftPos,
660
- w: w,
661
- h: h,
662
- vw: Math.round(this.virtualDimension.width),
663
- chs: chs,
664
- frameLength: frameLength,
665
- dftSize: this.dftSize,
666
- terminate: true
667
- }, ada);
668
- }
669
- else {
670
- if (w > 0) {
671
- if (framesPerPixel > 0) {
672
- let arrSize = w * h * 4;
673
- if (arrSize < 0) {
674
- arrSize = 0;
675
- }
676
- imgData = new Uint8ClampedArray(arrSize);
677
- let rw = 1;
678
- arrAbBuf = new Array(chs);
679
- for (let ch = 0; ch < chs; ch++) {
680
- arrAbBuf[ch] = new Float32Array(this.dftSize);
681
- }
682
- let leftFramePos = Math.floor(frameLength * renderPos / vw) - this.dftSize / 2;
683
- let framesToRead = this.dftSize;
684
- if (leftFramePos < 0) {
685
- leftFramePos = 0;
686
- }
687
- this.drawStateText('Loading/Rendering...');
688
- this.raAsSubsc = raAs.framesObs(leftFramePos, framesToRead, arrAbBuf).subscribe({
689
- next: (read) => {
690
- if (arrAbBuf && this.worker) {
691
- if (read < this.dftSize) {
692
- // zero padding
693
- for (let ch = 0; ch < chs; ch++) {
694
- for (let zp = read; zp < this.dftSize; zp++) {
695
- arrAbBuf[ch][zp] = 0;
696
- }
697
- }
698
- }
699
- for (let ch = 0; ch < chs; ch++) {
700
- const arrAbBufCh = arrAbBuf[ch];
701
- const adLen = arrAbBufCh.buffer.byteLength;
702
- if (!ada[ch] || ada[ch].byteLength !== adLen) {
703
- ada[ch] = new ArrayBuffer(adLen);
704
- }
705
- let fAdaCh = new Float32Array(ada[ch]);
706
- fAdaCh.set(arrAbBuf[ch]);
707
- }
708
- this.worker.postMessage({
709
- l: renderPos,
710
- w: rw,
711
- h: h,
712
- vw: vw,
713
- chs: chs,
714
- frameLength: frameLength,
715
- audioData: ada,
716
- audioDataOffset: leftFramePos,
717
- dftSize: this.dftSize,
718
- norender: norender,
719
- terminate: false
720
- }, ada);
721
- }
722
- },
723
- error: (err) => {
724
- console.error("Sonagram: Error reading audio data: " + err);
725
- }
726
- });
727
- }
728
- }
729
- }
730
- }
731
- }
732
- });
733
- }
734
- else {
735
- if (this.bounds && this.bounds.dimension) {
736
- let w = Math.round(this.bounds.dimension.width);
737
- let h = Math.round(this.bounds.dimension.height);
738
- let g = this.sonagramCanvas.getContext("2d");
739
- if (g) {
740
- g.clearRect(0, 0, w, h);
741
- }
742
- }
743
- }
744
- }
745
- drawRendered(w, h, imgData) {
746
- if (this.sonagramCanvas) {
747
- this.sonagramCanvas.width = w;
748
- this.sonagramCanvas.height = h;
749
- let g = this.sonagramCanvas.getContext("2d");
750
- if (g) {
751
- if (w > 0 && h > 0) {
752
- let gImgData = g.createImageData(w, h);
753
- gImgData.data.set(imgData);
754
- g.putImageData(gImgData, 0, 0);
755
- }
756
- }
757
- }
758
- this.drawBg();
759
- this.drawPlayPosition();
760
- }
761
- // // synchronous draw (not used anymore)
762
- // redraw() {
763
- //
764
- // let g = this.sonagramCanvas.getContext("2d");
765
- //
766
- // let w = this.sonagramCanvas.width;
767
- // let h = this.sonagramCanvas.height;
768
- // if (g) {
769
- // g.clearRect(0, 0, w, h);
770
- // g.fillStyle = "white";
771
- // g.fillRect(0, 0, w, h);
772
- // if (this._audioDataHolder) {
773
- // let spectSize = Math.floor(this.dftSize / 2)
774
- // let chs = this._audioDataHolder.numberOfChannels;
775
- // let chH = h / chs;
776
- //
777
- // let frameLength = this._audioDataHolder.frameLen;
778
- //
779
- // let framesPerPixel = frameLength / w;
780
- // let y = 0;
781
- // let audioBuffer:AudioBuffer|null=null;
782
- // let audioSource=this._audioDataHolder.audioSource;
783
- // if(audioSource instanceof AudioBufferSource){
784
- // audioBuffer=audioSource.audioBuffer;
785
- // }
786
- //
787
- // if(audioBuffer) {
788
- // let b = new Float32Array(this.dftSize)
789
- //
790
- // let sona = new Array<Array<Float32Array>>(chs);
791
- // let max = 0;
792
- // let maxPsd = -Infinity;
793
- // for (let ch = 0; ch < chs; ch++) {
794
- // let x = 0;
795
- // sona[ch] = new Array<Float32Array>(w);
796
- //
797
- // let chData = audioBuffer.getChannelData(ch);
798
- // // TODO center buffer
799
- //
800
- // let framePos = 0;
801
- // for (let pii = 0; pii < w; pii++) {
802
- // framePos = Math.round(pii * framesPerPixel);
803
- // // calculate DFT at pixel position
804
- // for (let i = 0; i < this.dftSize; i++) {
805
- // let chDat = chData[framePos + i];
806
- // b[i] = chDat;
807
- // }
808
- // let spectr = this.dft.processRealMagnitude(b);
809
- // sona[ch][pii] = spectr;
810
- // // @ts-ignore
811
- // let pMax = Math.max.apply(null, spectr);
812
- // if (pMax > max) {
813
- // max = pMax;
814
- // }
815
- //
816
- // for (let s = 0; s < spectSize; s++) {
817
- // let psd = (2 * Math.pow(spectr[s], 2)) / spectSize;
818
- // if (psd > maxPsd) {
819
- // maxPsd = psd;
820
- // }
821
- // }
822
- // }
823
- // }
824
- // //console.log("max: ", max);
825
- // maxPsd = (2 * Math.pow(max, 2)) / spectSize;
826
- // for (let ch = 0; ch < chs; ch++) {
827
- //
828
- // let framePos = 0;
829
- // for (let pii = 0; pii < w; pii++) {
830
- // framePos = pii * framesPerPixel;
831
- //
832
- // for (let y = 0; y < h; y++) {
833
- // let freqIdx = Math.round(y * spectSize / h);
834
- //
835
- // // calculate the one sided power spectral density PSD (f, t) in Pa2/Hz
836
- // // PSD(f) proportional to 2|X(f)|2 / (t2 - t1)
837
- // let val = sona[ch][pii][freqIdx];
838
- // let psd = (2 * Math.pow(val, 2)) / spectSize;
839
- //
840
- // // Calculate logarithmic
841
- // let psdLog = DSPUtils.toLevelInDB(psd / maxPsd);
842
- // let dynRangeInDb = 70;
843
- // let scaledVal = (psdLog + dynRangeInDb) / dynRangeInDb;
844
- //
845
- // if (scaledVal > 1)
846
- // scaledVal = 1;
847
- // if (scaledVal < 0) {
848
- // scaledVal = 0;
849
- // }
850
- // let rgbVal = (255 * scaledVal);
851
- // if (rgbVal < 0) {
852
- // // System.out.println("Neg RGB val: "+rgbVal);
853
- // rgbVal = 0;
854
- // }
855
- // if (rgbVal > 255) {
856
- // rgbVal = 255;
857
- // }
858
- // rgbVal = 255 - rgbVal;
859
- // let colorStr = CSSUtils.toColorString(rgbVal, rgbVal, rgbVal);
860
- // g.fillStyle = colorStr;
861
- // g.fillRect(pii, chH - y, 1, 1);
862
- // }
863
- // }
864
- // }
865
- // this.drawPlayPosition();
866
- // }else{
867
- // throw Error("Redraw only supported with audio buffer.")
868
- // }
869
- // }
870
- // }
871
- // }
872
- //
873
- setData(audioData) {
874
- this._audioDataHolder = audioData;
875
- this.playFramePosition = 0;
876
- }
877
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Sonagram, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
878
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: Sonagram, selector: "audio-sonagram", viewQueries: [{ propertyName: "sonagramCanvasRef", first: true, predicate: ["sonagram"], descendants: true, static: true }, { propertyName: "markerCanvasRef", first: true, predicate: ["marker"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
879
- <canvas #sonagram height="10"></canvas>
880
- <canvas #bg height="10"></canvas>
881
- <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
882
- (mouseleave)="updateCursorCanvas($event, false)"></canvas>
883
- <canvas #marker height="10"></canvas>`, isInline: true, styles: [":host{min-height:0px}\n", "canvas{top:0;left:0;width:0;height:0;min-height:0px;position:absolute}\n"] }); }
884
- }
885
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Sonagram, decorators: [{
886
- type: Component,
887
- args: [{ selector: 'audio-sonagram', template: `
888
- <canvas #sonagram height="10"></canvas>
889
- <canvas #bg height="10"></canvas>
890
- <canvas #cursor height="10" (mousedown)="selectionStart($event)" (mouseover)="updateCursorCanvas($event)" (mousemove)="updateCursorCanvas($event)"
891
- (mouseleave)="updateCursorCanvas($event, false)"></canvas>
892
- <canvas #marker height="10"></canvas>`, styles: [":host{min-height:0px}\n", "canvas{top:0;left:0;width:0;height:0;min-height:0px;position:absolute}\n"] }]
893
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { sonagramCanvasRef: [{
894
- type: ViewChild,
895
- args: ['sonagram', { static: true }]
896
- }], markerCanvasRef: [{
897
- type: ViewChild,
898
- args: ['marker', { static: true }]
899
- }] } });
900
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYWdyYW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vdWkvc29uYWdyYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBUyxLQUFLLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDdkMsT0FBTyxFQUFDLFNBQVMsRUFBYyxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDcEUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxpQkFBaUIsRUFBa0IsTUFBTSxzQkFBc0IsQ0FBQzs7QUFLeEUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7QUF3QjlCLE1BQU0sT0FBTyxRQUFTLFNBQVEseUJBQXlCO0lBb0JuRCxZQUFvQixHQUFlO1FBQy9CLEtBQUssRUFBRSxDQUFDO1FBRFEsUUFBRyxHQUFILEdBQUcsQ0FBWTtRQVIzQix1QkFBa0IsR0FBYyxJQUFJLENBQUM7UUFJckMsY0FBUyxHQUFtQixJQUFJLENBQUM7UUFFakMsWUFBTyxHQUFHLGdCQUFnQixDQUFDO1FBSS9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ25CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO1FBQ25DLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXhDLElBQUksQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FB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Ozs4Q0FLZ0M7K0VBc0JELGlCQUFpQjtzQkFBekQsU0FBUzt1QkFBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUVBLGVBQWU7c0JBQXJELFNBQVM7dUJBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7REZURmxvYXQzMn0gZnJvbSAnLi4vLi4vbWF0aC9kZnQnO1xyXG5pbXBvcnQge01hcmtlciwgUG9pbnR9IGZyb20gJy4vY29tbW9uJztcclxuaW1wb3J0IHtDb21wb25lbnQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHtBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge1dvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcbmltcG9ydCB7QXVkaW9CdWZmZXJTb3VyY2UsIEF1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xyXG5cclxuZGVjbGFyZSBmdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlOiBhbnksIHRyYW5zZmVyOiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcbmNvbnN0IERFRkFVTFRfREZUX1NJWkUgPSAxMDI0O1xyXG5cclxuQENvbXBvbmVudCh7XHJcblxyXG4gICAgc2VsZWN0b3I6ICdhdWRpby1zb25hZ3JhbScsXHJcbiAgICB0ZW1wbGF0ZTogYFxyXG4gICAgICAgIDxjYW52YXMgI3NvbmFncmFtIGhlaWdodD1cIjEwXCI+PC9jYW52YXM+XHJcbiAgICAgICAgPGNhbnZhcyAjYmcgaGVpZ2h0PVwiMTBcIj48L2NhbnZhcz5cclxuICAgICAgICA8Y2FudmFzICNjdXJzb3IgaGVpZ2h0PVwiMTBcIiAobW91c2Vkb3duKT1cInNlbGVjdGlvblN0YXJ0KCRldmVudClcIiAobW91c2VvdmVyKT1cInVwZGF0ZUN1cnNvckNhbnZhcygkZXZlbnQpXCIgKG1vdXNlbW92ZSk9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJ1cGRhdGVDdXJzb3JDYW52YXMoJGV2ZW50LCBmYWxzZSlcIj48L2NhbnZhcz5cclxuICAgICAgICA8Y2FudmFzICNtYXJrZXIgaGVpZ2h0PVwiMTBcIj48L2NhbnZhcz5gLFxyXG5cclxuICAgIHN0eWxlczogW2A6aG9zdHtcclxuICAgICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgfWAsYGNhbnZhcyB7XHJcbiAgICAgICAgdG9wOiAwO1xyXG4gICAgICAgIGxlZnQ6IDA7XHJcbiAgICAgICAgd2lkdGg6IDA7XHJcbiAgICAgICAgaGVpZ2h0OiAwO1xyXG4gICAgICBtaW4taGVpZ2h0OiAwcHg7XHJcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgfWBdXHJcblxyXG59KVxyXG5leHBvcnQgY2xhc3MgU29uYWdyYW0gZXh0ZW5kcyBBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50IHtcclxuXHJcbiAgICBkZnQ6IERGVEZsb2F0MzI7XHJcbiAgICBuOiBhbnk7XHJcbiAgICBjZSE6IEhUTUxEaXZFbGVtZW50O1xyXG4gICAgc29uYWdyYW1DYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuICAgIC8vY3Vyc29yQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuICAgIG1hcmtlckNhbnZhcyE6IEhUTUxDYW52YXNFbGVtZW50O1xyXG4gICAgQFZpZXdDaGlsZCgnc29uYWdyYW0nLCB7IHN0YXRpYzogdHJ1ZSB9KSBzb25hZ3JhbUNhbnZhc1JlZiE6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgnbWFya2VyJywgeyBzdGF0aWM6IHRydWUgfSkgbWFya2VyQ2FudmFzUmVmITogRWxlbWVudFJlZjtcclxuICAgIG1hcmtlcnM6IEFycmF5PE1hcmtlcj47XHJcbiAgICBwcml2YXRlIF9wbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICBwcml2YXRlIHdvcmtlcjogV29ya2VyIHwgbnVsbDtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcbiAgICBwcml2YXRlIHJhQXNTdWJzYzpTdWJzY3JpcHRpb258bnVsbD1udWxsO1xyXG5cclxuICAgIHByaXZhdGUgZGZ0U2l6ZSA9IERFRkFVTFRfREZUX1NJWkU7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMud29ya2VyID0gbnVsbDtcclxuICAgICAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBudWxsO1xyXG4gICAgICAgIHRoaXMubWFya2VycyA9IG5ldyBBcnJheTxNYXJrZXI+KCk7XHJcbiAgICAgICAgdGhpcy5kZnQgPSBuZXcgREZURmxvYXQzMih0aGlzLmRmdFNpemUpO1xyXG5cclxuICAgICAgICB0aGlzLndvcmtlclVSTCA9IFdvcmtlckhlbHBlci5idWlsZFdvcmtlckJsb2JVUkwodGhpcy53b3JrZXJGdW5jdGlvbilcclxuICAgICAgIHRoaXMuX2JnQ29sb3I9bnVsbDtcclxuICAgICAgIHRoaXMuX3NlbGVjdENvbG9yPSdyZ2JhKDI1NSwyNTUsMCwwLjEpJ1xyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuXHJcbiAgICAgICAgdGhpcy5jZSA9IHRoaXMucmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5zb25hZ3JhbUNhbnZhcyA9IHRoaXMuc29uYWdyYW1DYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgICAgICB0aGlzLnNvbmFncmFtQ2FudmFzLnN0eWxlLnpJbmRleCA9ICcxJztcclxuICAgICAgdGhpcy5iZ0NhbnZhcyA9IHRoaXMuYmdDYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgICAgdGhpcy5iZ0NhbnZhcy5zdHlsZS56SW5kZXggPSAnMic7XHJcbiAgICAgICAgdGhpcy5jdXJzb3JDYW52YXMgPSB0aGlzLmN1cnNvckNhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIHRoaXMuY3Vyc29yQ2FudmFzLnN0eWxlLnpJbmRleCA9ICc0JztcclxuICAgICAgICB0aGlzLm1hcmtlckNhbnZhcyA9IHRoaXMubWFya2VyQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5tYXJrZXJDYW52YXMuc3R5bGUuekluZGV4ID0gJzMnO1xyXG5cclxuICAgICAgICB0aGlzLmNhbnZhc0xheWVyc1swXSA9IHRoaXMuc29uYWdyYW1DYW52YXM7XHJcbiAgICAgIHRoaXMuY2FudmFzTGF5ZXJzWzFdID0gdGhpcy5iZ0NhbnZhcztcclxuICAgICAgdGhpcy5jYW52YXNMYXllcnNbMl0gPSB0aGlzLmN1cnNvckNhbnZhcztcclxuICAgICAgICB0aGlzLmNhbnZhc0xheWVyc1szXSA9IHRoaXMubWFya2VyQ2FudmFzO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcGxheUZyYW1lUG9zaXRpb24oKTogbnVtYmVyfG51bGwge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgcGxheUZyYW1lUG9zaXRpb24ocGxheUZyYW1lUG9zaXRpb246IG51bWJlcnxudWxsKSB7XHJcbiAgICAgICAgdGhpcy5fcGxheUZyYW1lUG9zaXRpb24gPSBwbGF5RnJhbWVQb3NpdGlvbjtcclxuICAgICAgICAvLyB0aGlzLnJlZHJhdygpO1xyXG4gICAgICAgIHRoaXMuZHJhd1BsYXlQb3NpdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY2FudmFzTW91c2VQb3MoYzogSFRNTENhbnZhc0VsZW1lbnQsIGU6IE1vdXNlRXZlbnQpOiBQb2ludCB7XHJcbiAgICAgICAgY29uc3QgY3IgPSBjLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgICAgICBjb25zdCB4ID0gZS54IC0gY3IubGVmdDtcclxuICAgICAgICBjb25zdCB5ID0gZS55IC0gY3IudG9wO1xyXG4gICAgICAgIHJldHVybiBuZXcgUG9pbnQoeCx5KTtcclxuICAgIH1cclxuXHJcbiAgZHJhd1N0YXRlVGV4dChzdGF0ZVRleHQ6c3RyaW5nKSB7XHJcbiAgICAgICAgaWYoc3RhdGVUZXh0KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGcgPSB0aGlzLnNvbmFncmFtQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICAgICAgY29uc3QgdyA9IHRoaXMuc29uYWdyYW1DYW52YXMud2lkdGg7XHJcbiAgICAgICAgICAgIGNvbnN0IGggPSB0aGlzLnNvbmFncmFtQ2FudmFzLmhlaWdodDtcclxuICAgICAgICAgICAgaWYgKGcgJiYgdyAmJiBoKSB7XHJcbiAgICAgICAgICAgICAgICBnLnN0cm9rZVN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgICAgICAgICAgIGcuZm9udCA9ICcyMHB4IHNhbnMtc2VyaWYnO1xyXG4gICAgICAgICAgICAgICAgZy5maWxsVGV4dChzdGF0ZVRleHQsIDEwLCAyNSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgfVxyXG5cclxuICBkcmF3Q3Vyc29yUG9zaXRpb24oZTogTW91c2VFdmVudCwgc2hvdzogYm9vbGVhbikge1xyXG5cclxuICAgIGlmICh0aGlzLmN1cnNvckNhbnZhcykge1xyXG4gICAgICBjb25zdCB3ID0gdGhpcy5jdXJzb3JDYW52YXMud2lkdGg7XHJcbiAgICAgIGNvbnN0IGggPSB0aGlzLmN1cnNvckNhbnZhcy5oZWlnaHQ7XHJcbiAgICAgIGNvbnN0IGcgPSB0aGlzLmN1cnNvckNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgICBpZiAoZykge1xyXG4gICAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICAgIGlmIChzaG93KSB7XHJcbiAgICAgICAgICAvL2NvbnN0IHBwID0gdGhpcy5jYW52YXNNb3VzZVBvcyh0aGlzLmN1cnNvckNhbnZhcywgZSk7XHJcbiAgICAgICAgICBsZXQgeFZpZXdQb3J0UGl4ZWxwb3MgPSBlLm9mZnNldFg7XHJcblxyXG4gICAgICAgICAgZy5maWxsU3R5bGUgPSAneWVsbG93JztcclxuICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAneWVsbG93JztcclxuICAgICAgICAgIGcuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgICBnLm1vdmVUbyh4Vmlld1BvcnRQaXhlbHBvcywgMCk7XHJcbiAgICAgICAgICBnLmxpbmVUbyh4Vmlld1BvcnRQaXhlbHBvcywgaCk7XHJcbiAgICAgICAgICBnLmNsb3NlUGF0aCgpO1xyXG5cclxuICAgICAgICAgIGcuc3Ryb2tlKCk7XHJcblxyXG4gICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvRGF0YUhvbGRlcikge1xyXG5cclxuICAgICAgICAgICAgbGV0IGZyYW1lUG9zUm91bmQgPSB0aGlzLnZpZXdQb3J0WFBpeGVsVG9GcmFtZVBvc2l0aW9uKHhWaWV3UG9ydFBpeGVscG9zKTtcclxuICAgICAgICAgICAgaWYoZnJhbWVQb3NSb3VuZCE9bnVsbCkge1xyXG4gICAgICAgICAgICAgIGcuZm9udCA9ICcxNHB4IHNhbnMtc2VyaWYnO1xyXG4gICAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gJ3llbGxvdyc7XHJcbiAgICAgICAgICAgICAgZy5maWxsVGV4dChmcmFtZVBvc1JvdW5kLnRvU3RyaW5nKCksIHhWaWV3UG9ydFBpeGVscG9zICsgMiwgNTApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAgIGRyYXdQbGF5UG9zaXRpb24oKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubWFya2VyQ2FudmFzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHcgPSB0aGlzLm1hcmtlckNhbnZhcy53aWR0aDtcclxuICAgICAgICAgICAgY29uc3QgaCA9IHRoaXMubWFya2VyQ2FudmFzLmhlaWdodDtcclxuICAgICAgICAgICAgY29uc3QgZyA9IHRoaXMubWFya2VyQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICAgICAgaWYgKGcpIHtcclxuICAgICAgICAgICAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICAgICAgICAgICAgaWYodGhpcy5fcGxheUZyYW1lUG9zaXRpb24hPW51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcGl4ZWxQb3MgPSB0aGlzLmZyYW1lVG9WaWV3UG9ydFhQaXhlbFBvc2l0aW9uKHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGl4ZWxQb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZy5maWxsU3R5bGUgPSAncmVkJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZy5zdHJva2VTdHlsZSA9ICdyZWQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnLmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBnLm1vdmVUbyhwaXhlbFBvcywgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGcubGluZVRvKHBpeGVsUG9zLCBoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZy5jbG9zZVBhdGgoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZy5zdHJva2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLypcclxuICAgICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgICAqL1xyXG4gICAgd29ya2VyRnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIFJlZGVmaW5lIHNvbWUgRFNQIGNsYXNzZXMgZm9yIHdvcmtlciBmdW5jdGlvblxyXG4gICAgICAgIC8vIFNlZSBlLmcuIGF1ZGlvLm1hdGguQ29tcGxleFxyXG4gICAgICAgIGNsYXNzIENvbXBsZXgge1xyXG5cclxuICAgICAgICAgICAgcmVhbDogbnVtYmVyO1xyXG4gICAgICAgICAgICBpbWc6IG51bWJlcjtcclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBzdGF0aWMgZnJvbVBvbGFyRm9ybShtYWduaXR1ZGU6IG51bWJlciwgYXJndW1lbnQ6IG51bWJlcik6IENvbXBsZXgge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgciA9IE1hdGguY29zKGFyZ3VtZW50KSAqIG1hZ25pdHVkZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGkgPSBNYXRoLnNpbihhcmd1bWVudCkgKiBtYWduaXR1ZGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBsZXgociwgaSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKHJlYWw6IG51bWJlciwgaW1nOiBudW1iZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVhbCA9IHJlYWw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmltZyA9IGltZztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcHVibGljIG1hZ25pdHVkZSgpOiBudW1iZXIge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguc3FydCgodGhpcy5yZWFsICogdGhpcy5yZWFsKSArICh0aGlzLmltZyAqIHRoaXMuaW1nKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBhcmd1bWVudCgpOiBudW1iZXIge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIodGhpcy5pbWcsIHRoaXMucmVhbCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBhZGQoYWRkQzogQ29tcGxleCk6IENvbXBsZXgge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV4KHRoaXMucmVhbCArIGFkZEMucmVhbCwgdGhpcy5pbWcgKyBhZGRDLmltZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBzdWIoc3ViQzogQ29tcGxleCk6IENvbXBsZXgge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV4KHRoaXMucmVhbCAtIHN1YkMucmVhbCwgdGhpcy5pbWcgLSBzdWJDLmltZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBtdWx0KG11bHRDOiBDb21wbGV4KTogQ29tcGxleCB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtdWx0UiA9ICh0aGlzLnJlYWwgKiBtdWx0Qy5yZWFsKSAtICh0aGlzLmltZyAqIG11bHRDLmltZyk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtdWx0SSA9ICh0aGlzLnJlYWwgKiBtdWx0Qy5pbWcpICsgKG11bHRDLnJlYWwgKiB0aGlzLmltZyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBsZXgobXVsdFIsIG11bHRJKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcHVibGljIG11bHRSZWFsKG11bHRGOiBudW1iZXIpOiBDb21wbGV4IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcGxleCh0aGlzLnJlYWwgKiBtdWx0RiwgdGhpcy5pbWcgKiBtdWx0Rik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBkaXYoZGl2aXNvcjogQ29tcGxleCk6IENvbXBsZXgge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGl2UmVhbCA9IGRpdmlzb3IucmVhbDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpdkltZyA9IGRpdmlzb3IuaW1nO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGl2ID0gKGRpdlJlYWwgKiBkaXZSZWFsKSArIChkaXZJbWcgKiBkaXZJbWcpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGl2aXNpb25SZWFsID0gKCh0aGlzLnJlYWwgKiBkaXZSZWFsKSArICh0aGlzLmltZyAqIGRpdkltZykpIC8gZGl2O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGl2aXNpb25JbWcgPSAoKGRpdlJlYWwgKiB0aGlzLmltZykgLSAodGhpcy5yZWFsICogZGl2SW1nKSkgLyBkaXY7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV4KGRpdmlzaW9uUmVhbCwgZGl2aXNpb25JbWcpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBwdWJsaWMgZGl2UmVhbChkaXZpc29yOiBudW1iZXIpOiBDb21wbGV4IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRpdmlzb3IgKiBkaXZpc29yO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGl2c2lvblJlYWwgPSAodGhpcy5yZWFsICogZGl2aXNvcikgLyBkaXY7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkaXZzaW9uSW1nID0gKGRpdmlzb3IgKiB0aGlzLmltZykgLyBkaXY7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV4KGRpdnNpb25SZWFsLCBkaXZzaW9uSW1nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcHVibGljIGNvbmp1Z2F0ZSgpOiBDb21wbGV4IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcGxleCh0aGlzLnJlYWwsIC10aGlzLmltZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBlcXVhbHMoYzogQ29tcGxleCk6IGJvb2xlYW4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGMgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMucmVhbCA9PT0gYy5yZWFsICYmIHRoaXMuaW1nID09PSBjLmltZyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdSZWFsOiAnICsgdGhpcy5yZWFsICsgJywgSW1nOiAnICsgdGhpcy5pbWc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNsYXNzIERGVEZsb2F0MzIge1xyXG5cclxuICAgICAgICAgICAgcHJpdmF0ZSByZWFkb25seSBuOiBudW1iZXI7XHJcbiAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgbTogbnVtYmVyO1xyXG5cclxuICAgICAgICAgICAgcHJpdmF0ZSByZWFkb25seSBjb3NMb29rdXA6IEZsb2F0MzJBcnJheTtcclxuICAgICAgICAgICAgcHJpdmF0ZSByZWFkb25seSBzaW5Mb29rdXA6IEZsb2F0MzJBcnJheTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKG46IG51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5uID0gbjtcclxuICAgICAgICAgICAgICAgIHRoaXMubSA9IE1hdGgubG9nKG4pIC8gTWF0aC5sb2coMik7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gaWYobiAhPSAoMSA8PCBtKSl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihcImxlbmd0aCBOIG11c3QgYmUgcG93ZXIgb2YgMlwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBsb29rdXAgdGFibGVzXHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvc0xvb2t1cCA9IG5ldyBGbG9hdDMyQXJyYXkobiAvIDIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaW5Mb29rdXAgPSBuZXcgRmxvYXQzMkFycmF5KG4gLyAyKTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4gLyAyOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcmMgPSAoLTIgKiBNYXRoLlBJICogaSkgLyBuO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29zTG9va3VwW2ldID0gTWF0aC5jb3MoYXJjKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNpbkxvb2t1cFtpXSA9IE1hdGguc2luKGFyYyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHB1YmxpYyBwcm9jZXNzUmVhbChzcmNCdWY6IEZsb2F0MzJBcnJheSk6IEFycmF5PENvbXBsZXg+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHggPSBzcmNCdWYuc2xpY2UoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHkgPSBuZXcgRmxvYXQzMkFycmF5KHNyY0J1Zi5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgeWkgPSAwOyB5aSA8IHkubGVuZ3RoOyB5aSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeVt5aV0gPSAwLjA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZmdENvb2xleVR1a2V5KHgsIHkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmMgPSBuZXcgQXJyYXk8Q29tcGxleD4oeC5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmNbaV0gPSBuZXcgQ29tcGxleCh4W2ldLCB5W2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiByYztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcHVibGljIHByb2Nlc3NSZWFsTWFnbml0dWRlKHNyY0J1ZjogRmxvYXQzMkFycmF5KTogRmxvYXQzMkFycmF5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHggPSBzcmNCdWYuc2xpY2UoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHkgPSBuZXcgRmxvYXQzMkFycmF5KHNyY0J1Zi5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgeWkgPSAwOyB5aSA8IHkubGVuZ3RoOyB5aSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeVt5aV0gPSAwLjA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZmdENvb2xleVR1a2V5KHgsIHkpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmMgPSBuZXcgRmxvYXQzMkFycmF5KHgubGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJjYyA9IG5ldyBDb21wbGV4KHhbaV0sIHlbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJjW2ldID0gcmNjLm1hZ25pdHVkZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJjO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBwdWJsaWMgZmZ0Q29vbGV5VHVrZXkocmVhbDogRmxvYXQzMkFycmF5LCBpbWc6IEZsb2F0MzJBcnJheSk6IHZvaWQge1xyXG4gICAgICAgICAgICAgICAgbGV0IGk6IG51bWJlcjtcclxuICAgICAgICAgICAgICAgIGxldCBqID0gMDtcclxuICAgICAgICAgICAgICAgIGxldCBrOiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBsZXQgbjE6IG51bWJlcjtcclxuICAgICAgICAgICAgICAgIGxldCBuMjogbnVtYmVyID0gdGhpcy5uIC8gMjtcclxuICAgICAgICAgICAgICAgIGxldCBhOiBudW1iZXI7XHJcbiAgICAgICAgICAgICAgICBsZXQgYzogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgbGV0IHM6IG51bWJlcjtcclxuICAgICAgICAgICAgICAgIGxldCB0MTogbnVtYmVyO1xyXG4gICAgICAgICAgICAgICAgbGV0IHQyOiBudW1iZXI7XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHRoaXMubiAtIDE7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIG4xID0gbjI7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPj0gbjEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGogLSBuMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbjEgPSBuMSAvIDI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGogPSBqICsgbjE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpIDwgaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0MSA9IHJlYWxbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxbaV0gPSByZWFsW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFsW2pdID0gdDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHQxID0gaW1nW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbWdbaV0gPSBpbWdbal07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1tqXSA9IHQxO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBuMSA9IDA7XHJcbiAgICAgICAgICAgICAgICBuMiA9IDE7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5tOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBuMSA9IG4yO1xyXG4gICAgICAgICAgICAgICAgICAgIG4yID0gbjIgKyBuMjtcclxuICAgICAgICAgICAgICAgICAgICBhID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbjE7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjID0gdGhpcy5jb3NMb29rdXBbYV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSB0aGlzLnNpbkxvb2t1cFthXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYSArPSAoMSA8PCAodGhpcy5tIC0gaSAtIDEpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoayA9IGo7IGsgPCB0aGlzLm47IGsgPSBrICsgbjIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQxID0gYyAqIHJlYWxbayArIG4xXSAtIHMgKiBpbWdbayArIG4xXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQyID0gcyAqIHJlYWxbayArIG4xXSArIGMgKiBpbWdbayArIG4xXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxbayArIG4xXSA9IHJlYWxba10gLSB0MTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltZ1trICsgbjFdID0gaW1nW2tdIC0gdDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFsW2tdID0gcmVhbFtrXSArIHQxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nW2tdID0gaW1nW2tdICsgdDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICBwdWJsaWMgcHJvY2Vzcyh0OiBBcnJheTxDb21wbGV4Pik6IEFycmF5PENvbXBsZXg+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWxzOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMubik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbWdzOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMubik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0cmFuczogQXJyYXk8Q29tcGxleD4gPSBuZXcgQXJyYXk8Q29tcGxleD4odGhpcy5uKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICByZWFsc1tpXSA9IHRbaV0ucmVhbDtcclxuICAgICAgICAgICAgICAgICAgICBpbWdzW2ldID0gdFtpXS5pbWc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZmdENvb2xleVR1a2V5KHJlYWxzLCBpbWdzKTtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc1tpXSA9IG5ldyBDb21wbGV4KHJlYWxzW2ldLCBpbWdzW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0cmFucztcclxuXHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW50ZXJmYWNlIFdpbmRvd0Z1bmN0aW9uIHtcclxuICAgICAgICAgICAgZ2V0U2NhbGUoaTogbnVtYmVyKTogbnVtYmVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY2xhc3MgR2F1c3NpYW5XaW5kb3cgaW1wbGVtZW50cyBXaW5kb3dGdW5jdGlvbiB7XHJcblxyXG4gICAgICAgICAgICBwdWJsaWMgc3RhdGljIERFRkFVTFRfU0lHTUEgPSAwLjM7XHJcbiAgICAgICAgICAgIC8vIEdhdXNzaWFuIHdpbmRvdyBmdW5jdGlvbixcclxuICAgICAgICAgICAgLy8gaHR0cDovL3JlZmVyZW5jZS53b2xmcmFtLmNvbS9sYW5ndWFnZS9yZWYvR2F1c3NpYW5XaW5kb3cuaHRtbFxyXG4gICAgICAgICAgICAvLyB2YWw9ZXhwKC01MCp4KngvOSkgPT4gc2lnbWE9MC4zXHJcblxyXG4gICAgICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGJ1ZjogRmxvYXQzMkFycmF5O1xyXG5cclxuICAgICAgICAgICAgY29uc3RydWN0b3Ioc2l6ZTogbnVtYmVyLCBzaWdtYTogbnVtYmVyID0gR2F1c3NpYW5XaW5kb3cuREVGQVVMVF9TSUdNQSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWYgPSBuZXcgRmxvYXQzMkFycmF5KHNpemUpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VudGVyID0gKHNpemUgLSAxKSAvIDI7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1b3QgPSAoaSAtIGNlbnRlcikgLyAoc2lnbWEgKiBjZW50ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cCA9IC0wLjUgKiBxdW90ICogcXVvdDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZltpXSA9IE1hdGguZXhwKGV4cCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGdldFNjYWxlKGk6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5idWZbaV07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChtc2c6TWVzc2FnZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlNvbmFncmFtIHJlbmRlciB0aHJlYWRcIik7XHJcbiAgICAgICAgICAgIGxldCBsID0gbXNnLmRhdGEubDtcclxuICAgICAgICAgICAgbGV0IHcgPSBtc2cuZGF0YS53O1xyXG4gICAgICAgICAgICBsZXQgaCA9IG1zZy5kYXRhLmg7XHJcbiAgICAgICAgICAgIGxldCB2dyA9IG1zZy5kYXRhLnZ3O1xyXG4gICAgICAgICAgICBsZXQgY2hzID0gbXNnLmRhdGEuY2hzO1xyXG4gICAgICAgICAgICBsZXQgYXVkaW9EYXRhT2Zmc2V0PTA7XHJcbiAgICAgICAgICAgIGxldCBhZE9mZnNldD1tc2cuZGF0YS5hdWRpb0RhdGFPZmZzZXQ7XHJcbiAgICAgICAgICAgIGlmKGFkT2Zmc2V0KXtcclxuICAgICAgICAgICAgICBhdWRpb0RhdGFPZmZzZXQ9YWRPZmZzZXQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICBsZXQgbWF4UHNkID0gbnVsbDtcclxuICAgICAgICAgICAgaWYobXNnLmRhdGEubWF4UHNkIT09dW5kZWZpbmVkKXtcclxuICAgICAgICAgICAgICBtYXhQc2Q9bXNnLmRhdGEubWF4UHNkO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgYXVkaW9EYXRhID0gbmV3IEFycmF5KGNocyk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgIGF1ZGlvRGF0YVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KG1zZy5kYXRhWydhdWRpb0RhdGEnXVtjaF0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgZnJhbWVMZW5ndGggPSBtc2cuZGF0YS5mcmFtZUxlbmd0aDtcclxuICAgICAgICAgICAgbGV0IGRmdFNpemUgPSBtc2cuZGF0YS5kZnRTaXplO1xyXG5cclxuICAgICAgICAgICAgbGV0IGRmdEJhbmRzID0gZGZ0U2l6ZSAvIDI7XHJcbiAgICAgICAgICAgIGxldCBkZnQgPSBuZXcgREZURmxvYXQzMihkZnRTaXplKTtcclxuICAgICAgICAgICAgbGV0IHdmID0gbmV3IEdhdXNzaWFuV2luZG93KGRmdFNpemUpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGFyclNpemU9dypoKjQ7XHJcbiAgICAgICAgICAgIGlmKGFyclNpemU8MCl7XHJcbiAgICAgICAgICAgICAgICBhcnJTaXplPTBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgaW1nRGF0YSA9IG5ldyBVaW50OENsYW1wZWRBcnJheShhcnJTaXplKTtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIlJlbmRlciBtZXRob2Q6XCIpO1xyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ3JlYXRlZCBpbWdEYXRhIGFyclNpemU6IFwiK2FyclNpemUrXCIgXCIsIHcsIFwieFwiLCBoKTtcclxuICAgICAgICAgIGxldCBjYWxjTWF4UHNkPS1JbmZpbml0eTtcclxuICAgICAgICAgICAgaWYgKGFyclNpemU+MCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBjaEggPSBNYXRoLnJvdW5kKGggLyBjaHMpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB2dztcclxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlJlbmRlcjogXCIsIHcsIFwieFwiLCBoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgYiA9IG5ldyBGbG9hdDMyQXJyYXkoZGZ0U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgc29uYSA9IG5ldyBBcnJheShjaHMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNoRGF0YUxlbj1hdWRpb0RhdGFbY2hdLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbml0aWFsaXplIERGVCBhcnJheSBidWZmZXJcclxuICAgICAgICAgICAgICAgICAgICBzb25hW2NoXSA9IG5ldyBBcnJheSh3KTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2aXJ0UGlpID0gbCArIHBpaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUG9zaXRpb24gb2Ygc2FtcGxlIGRhdGEgZnJhbWUgaXMgcGl4ZWwgcG9zaXRpb24gbWFwcGVkIHRvIGF1ZGlvIGZyYW1lIHBvc2l0aW9uLlxyXG4gICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZW4gXCJjZW50ZXJcIiB0aGUgZnJhbWUgYnkgc2hpZnRpbmcgbGVmdCBieSBoYWxmIHRoZSBERlQgc2l6ZSAoPWRmdEJhbmRzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVBvcyA9IE1hdGgucm91bmQoKHZpcnRQaWkgKiBmcmFtZXNQZXJQaXhlbCktZGZ0QmFuZHMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIERGVCBidWZmZXIgd2l0aCB3aW5kb3dlZCBzYW1wbGUgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGZ0U2l6ZTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgc2FtcGxlUG9zPWZyYW1lUG9zICsgaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluaXRpYWxpemUgZm9yIG5lZ2F0aXZlIHNhbXBsZSBwb3NpdGlvbnMgYW5kIG91dCBvZiBib3VuZHMgcG9zaXRpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2hEYXQ9MDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgYXVkaW8gc2FtcGxlIGlmIGF2YWlsYWJsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFkcD1zYW1wbGVQb3MtYXVkaW9EYXRhT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoYWRwPj0wICYmIGFkcCA8IGNoRGF0YUxlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaERhdCA9IGF1ZGlvRGF0YVtjaF1bYWRwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQXVkaW8gZGF0YTogXCIrY2hEYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlNhbXBsZSBidWYgcG9zIG9vYjogYWRwOiBcIithZHArXCIsIGNoRGF0YUxlbjogXCIrY2hEYXRhTGVuK1wiLCBzYW1wbGVQb3M6IFwiK3NhbXBsZVBvcytcIiwgaTogXCIraSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwbHkgV2luZG93XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiW2ldID0gY2hEYXQgKiB3Zi5nZXRTY2FsZShpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYWxjIERGVCBtYWduaXR1ZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzcGVjdHIgPSBkZnQucHJvY2Vzc1JlYWxNYWduaXR1ZGUoYik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgbWF4aW11bSB2YWx1ZSBvZiBzcGVjdHJhbCBlbmVyZ3lcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBkZnRCYW5kczsgcysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcHNkID0gKDIgKiBNYXRoLnBvdyhzcGVjdHJbc10sIDIpKSAvIGRmdEJhbmRzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBzZCA+IGNhbGNNYXhQc2QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxjTWF4UHNkID0gcHNkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCByZW5kZXIgbW9kZWwgZGF0YSBmb3IgdGhpcyBwaXhlbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzb25hW2NoXVtwaWldID0gc3BlY3RyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZighbXNnLmRhdGEubm9yZW5kZXIpIHtcclxuICAgICAgICAgICAgICAgICAgaWYoIW1heFBzZCl7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF4UHNkPWNhbGNNYXhQc2Q7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgIGZvciAobGV0IHBpaSA9IDA7IHBpaSA8IHc7IHBpaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGFsbEJsYWNrID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IGNoSDsgeSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBsZXQgZnJlcUlkeCA9IE1hdGgucm91bmQoeSAqIGRmdEJhbmRzIC8gY2hIKTtcclxuICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgb25lLXNpZGVkIHBvd2VyIHNwZWN0cmFsIGRlbnNpdHkgUFNEIChmLCB0KSBpbiBQYTIvSHpcclxuICAgICAgICAgICAgICAgICAgICAgIC8vIFBTRChmKSBwcm9wb3J0aW9uYWwgdG8gMnxYKGYpfDIgLyAodDIgLSB0MSlcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCB2YWwgPSBzb25hW2NoXVtwaWldW2ZyZXFJZHhdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IHBzZCA9ICgyICogTWF0aC5wb3codmFsLCAyKSkgLyBkZnRCYW5kcztcclxuICAgICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBsb2dhcml0aG1pYyB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgLy9sZXQgcHNkTG9nID0gaXBzLmRzcC5EU1BVdGlscy50b0xldmVsSW5EQihwc2QgLyBtYXhQc2QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGxpbmVhckxldmVsID0gcHNkIC8gbWF4UHNkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IHBzZExvZyA9IDEwICogTWF0aC5sb2cobGluZWFyTGV2ZWwpIC8gTWF0aC5sb2coMTApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gRml4ZWQgZHluYW1pYyBSYW5nZSB2YWx1ZSBvZiA3MGRCIGZvciBub3dcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCBkeW5SYW5nZUluRGIgPSA3MDtcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCBzY2FsZWRWYWwgPSAocHNkTG9nICsgZHluUmFuZ2VJbkRiKSAvIGR5blJhbmdlSW5EYjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyBhcmUgdGhlIGZvbGxvd2luZyBjaGVja3MgbmVjZXNzYXJ5IGZvciBjbGFtcGVkIGFycmF5ID9cclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2FsZWRWYWwgPiAxLjApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlZFZhbCA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NhbGVkVmFsIDwgMC4wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlZFZhbCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICBsZXQgcmdiVmFsID0gTWF0aC5yb3VuZCgyNTUgKiBzY2FsZWRWYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHJnYlZhbCA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9cdFx0XHRcdFx0XHRcdFN5c3RlbS5vdXQucHJpbnRsbihcIk5lZyBSR0IgdmFsOiBcIityZ2JWYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZ2JWYWwgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHJnYlZhbCA+IDI1NSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZ2JWYWwgPSAyNTU7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICByZ2JWYWwgPSAyNTUgLSByZ2JWYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAocmdiVmFsID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbGxCbGFjayA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IHB5ID0gY2hIIC0geTtcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCBkYXRhUG9zID0gKCgoKGNoICogY2hIKSArIHB5KSAqIHcpICsgcGlpKSAqIDQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpbWdEYXRhW2RhdGFQb3MgKyAwXSA9IHJnYlZhbDsgLy9SXHJcbiAgICAgICAgICAgICAgICAgICAgICBpbWdEYXRhW2RhdGFQb3MgKyAxXSA9IHJnYlZhbDsgLy9HXHJcbiAgICAgICAgICAgICAgICAgICAgICBpbWdEYXRhW2RhdGFQb3MgKyAyXSA9IHJnYlZhbDsgLy9CXHJcbiAgICAgICAgICAgICAgICAgICAgICBpbWdEYXRhW2RhdGFQb3MgKyAzXSA9IDI1NTsgLy9BIChhbHBoYTogZnVsbHkgb3BhcXVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiUmVuZGVyZWQ6IHB5OiBcIitweStcIiwgcmdidmFsOiBcIityZ2JWYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZXhhbXBsZSAxeDEsIDJjaHNcclxuICAgICAgICAgICAgICAgICAgICAgIC8vICBjaDB4MHkwUixjaDB4MHkwRyxjaDB4MHkwQixjaDB4MHkwQSxcclxuICAgICAgICAgICAgICAgICAgICAgIC8vICBjaDB4MXkwUixjaDB4MXkwRyxjaDB4MXkwQixjaDB4MXkwQSxcclxuICAgICAgICAgICAgICAgICAgICAgIC8vICBjaDB4MHkwUixjaDB4MHkwRyxjaDB4MHkwQixjaDB4MHkwQSxcclxuICAgICAgICAgICAgICAgICAgICAgIC8vICBjaDB4MXkxUixjaDB4MXkxRyxjaDB4MXkxQixjaDB4MXkxQSxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyAgY2gxeDB5MFIsY2gxeDB5MEcsY2gxeDB5MEIsY2gxeDB5MEEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyAgY2gxeDF5MFIsY2gxeDF5MEcsY2gxeDF5MEIsY2gxeDF5MEEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyAgY2gxeDB5MFIsY2gxeDB5MEcsY2gxeDB5MEIsY2gxeDB5MEEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyAgY2gxeDF5MVIsY2gxeDF5MUcsY2gxeDF5MUIsY2gxeDF5MUFcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgKGFsbEJsYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICBjb25zb2xlLmxvZyhcIkJsYWNrOiBcIiwgcGlpLCBcIiBcIiwgY2gpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlJlbmRlciB0aHJlYWQgcG9zdCBtZXNzYWdlIGltZ0RhdGE6IFwiK2ltZ0RhdGEubGVuZ3RoKVxyXG4gICAgICAgICAgICBwb3N0TWVzc2FnZSh7aW1nRGF0YTogaW1nRGF0YSwgbDogbCwgdzogbXNnLmRhdGEudywgaDogbXNnLmRhdGEuaCwgdnc6IHZ3LG1heFBzZDpjYWxjTWF4UHNkLHRlcm1pbmF0ZTptc2cuZGF0YS50ZXJtaW5hdGV9LCBbaW1nRGF0YS5idWZmZXJdKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnREcmF3KGNsZWFyID0gdHJ1ZSkge1xyXG4gICAgICAgIGlmIChjbGVhcikge1xyXG4gICAgICAgICAgICBpZih0aGlzLmJvdW5kcykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zb25hZ3JhbUNhbnZhcy5zdHlsZS5sZWZ0ID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5wb3NpdGlvbi5sZWZ0KS50b1N0cmluZygpICsgJ3B4JztcclxuICAgICAgICAgICAgICAgIGxldCBpbnRXID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpXHJcbiAgICAgICAgICAgICAgICBsZXQgaW50SCA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLmhlaWdodClcclxuICAgICAgICAgICAgICAgIHRoaXMuc29uYWdyYW1DYW52YXMud2lkdGggPSBpbnRXO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zb25hZ3JhbUNhbnZhcy5oZWlnaHQgPSBpbnRIO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBnID0gdGhpcy5zb25hZ3JhbUNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAoZykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZy5jbGVhclJlY3QoMCwgMCx3LCBoKTtcclxuICAgICAgICAgICAgICAgICAgICBnLmZpbGxTdHlsZSA9IFwid2hpdGVcIjtcclxuICAgICAgICAgICAgICAgICAgICBnLmZpbGxSZWN0KDAsIDAsIGludFcsIGludEgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc3RhcnRSZW5kZXIoKTtcclxuICAgICAgICB0aGlzLmRyYXdDdXJzb3JMYXllcigpXHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGFydFJlbmRlcigpIHtcclxuICAgICAgLy9jb25zb2xlLmRlYnVnKFwiU29uYWdyYW0gc3RhcnQgcmVuZGVyLi4uXCIpO1xyXG4gICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICB0aGlzLndvcmtlci50ZXJtaW5hdGUoKTtcclxuICAgICAgICAgICAgdGhpcy53b3JrZXIgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgaWYodGhpcy5yYUFzU3Vic2Mpe1xyXG4gICAgICAgIHRoaXMucmFBc1N1YnNjLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuX2F1ZGlvRGF0YUhvbGRlcikge1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5hZGRPblJlYWR5TGlzdGVuZXIoKCk9PiB7XHJcbiAgICAgICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyICYmIHRoaXMuYm91bmRzICYmIHRoaXMuYm91bmRzLmRpbWVuc2lvbikge1xyXG4gICAgICAgICAgICBsZXQgdyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMuZGltZW5zaW9uLndpZHRoKTtcclxuICAgICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgICBsZXQgdncgPSBNYXRoLnJvdW5kKHRoaXMudmlydHVhbERpbWVuc2lvbi53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICBpZiAodyA+IDAgJiYgaCA+IDAgJiYgdncgPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMud29ya2VyID0gbmV3IFdvcmtlcih0aGlzLndvcmtlclVSTCk7XHJcbiAgICAgICAgICAgICAgLy90aGlzLndvID0gbmV3IFdvcmtlcignLi93b3JrZXIvc29uYWdyYW0ud29ya2VyJywgeyB0eXBlOiBgbW9kdWxlYCB9KTtcclxuXHJcbiAgICAgICAgICAgICAgbGV0IGNocyA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gICAgICAgICAgICAgIGxldCB2dyA9IE1hdGgucm91bmQodGhpcy52aXJ0dWFsRGltZW5zaW9uLndpZHRoKTtcclxuXHJcbiAgICAgICAgICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gdGhpcy5fYXVkaW9EYXRhSG9sZGVyLmZyYW1lTGVuO1xyXG4gICAgICAgICAgICAgIGxldCBmcmFtZXNQZXJQaXhlbCA9IE1hdGguY2VpbChmcmFtZUxlbmd0aCAvIHZ3KTtcclxuICAgICAgICAgICAgICBsZXQgbGVmdFBvcyA9IE1hdGgucm91bmQodGhpcy5ib3VuZHMucG9zaXRpb24ubGVmdCk7XHJcbiAgICAgICAgICAgICAgbGV0IHJlbmRlclBvcyA9IGxlZnRQb3M7XHJcbiAgICAgICAgICAgICAgbGV0IHJhQXMgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIucmFuZG9tQWNjZXNzQXVkaW9TdHJlYW0oKTtcclxuXHJcbiAgICAgICAgICAgICAgbGV0IGF1ZGlvQnVmZmVyOiBBdWRpb0J1ZmZlciB8IG51bGwgPSBudWxsO1xyXG4gICAgICAgICAgICAgIGxldCBhdWRpb1NvdXJjZSA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5hdWRpb1NvdXJjZTtcclxuICAgICAgICAgICAgICBpZiAoYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXIgPSBhdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgLy9sZXQgYXJyYXlBdWRpb0J1ZmZlcj10aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXJyYXlCdWZmZXI7XHJcbiAgICAgICAgICAgICAgbGV0IGFyckFiQnVmOiBGbG9hdDMyQXJyYXlbXSB8IG51bGw7XHJcbiAgICAgICAgICAgICAgbGV0IGFkYSA9IG5ldyBBcnJheTxBcnJheUJ1ZmZlcj4oY2hzKTtcclxuICAgICAgICAgICAgICAvLyBmb3IobGV0IGNoPTA7Y2g8Y2hzO2NoKyspIHtcclxuICAgICAgICAgICAgICAvLyAgIGFkYVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZGZ0U2l6ZSk7XHJcbiAgICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICAgIGxldCBpbWdEYXRhOiBVaW50OENsYW1wZWRBcnJheTtcclxuICAgICAgICAgICAgICBsZXQgbWF4UHNkID0gLUluZmluaXR5O1xyXG4gICAgICAgICAgICAgIGxldCBub3JlbmRlciA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGlmICh0cnVlID09PSBtZS5kYXRhLnRlcm1pbmF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBkcmF3SW1nRGF0YTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW1nRGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgZHJhd0ltZ0RhdGEgPSBpbWdEYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBkcmF3SW1nRGF0YSA9IG1lLmRhdGEuaW1nRGF0YTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3UmVuZGVyZWQodywgaCwgZHJhd0ltZ0RhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy53b3JrZXIudGVybWluYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud29ya2VyID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICByYUFzLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCByZW5kZXJlZCB2ZXJ0aWNhbCB2YWx1ZXMgb2Ygb25lIHBpeGVsIG9mIHRpbWVzY2FsZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vbGV0IGRhdGFQb3MgPSByZW5kZXJQb3MgKiBoICogNDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9yZW5kZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChtZS5kYXRhLm1heFBzZCA+IG1heFBzZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhQc2QgPSBtZS5kYXRhLm1heFBzZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwibmV3IG1heFBzZDogXCIrbWF4UHNkKTtcclxuICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGNoSCA9IE1hdGgucm91bmQoaCAvIGNocyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICBsZXQgaWRwID0gbWUuZGF0YS5sIC0gbGVmdFBvcztcclxuICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBjaEg7IHkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBweSA9IGNoSCAtIHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRhdGFQb3MgPSAoKCgoY2ggKiBjaEgpICsgcHkpICogdykgKyBpZHApICogNDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWVQb3MgPSAoKGNoICogY2hIKSArIHB5KSAqIDQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sZXQgbGFzdFBvcyA9IGRhdGFQb3MgKyBtZS5kYXRhLmltZ0RhdGEubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgKGxhc3RQb3MgPCBpbWdEYXRhLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBvbmUgcGl4ZWxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nRGF0YVtkYXRhUG9zXSA9IG1lLmRhdGEuaW1nRGF0YVttZVBvc107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaW1nRGF0YVtkYXRhUG9zICsgMV0gPSBtZS5kYXRhLmltZ0RhdGFbbWVQb3MgKyAxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBpbWdEYXRhW2RhdGFQb3MgKyAyXSA9IG1lLmRhdGEuaW1nRGF0YVttZVBvcyArIDJdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGltZ0RhdGFbZGF0YVBvcyArIDNdID0gbWUuZGF0YS5pbWdEYXRhW21lUG9zICsgM107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy99IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5lcnJvcihcIk91dCBvZiByYW5nZTogXCIgKyBkYXRhUG9zICsgXCIrXCIgKyBtZS5kYXRhLmltZ0RhdGEubGVuZ3RoICsgXCI+PVwiICsgaW1nRGF0YS5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyICYmIGFyckFiQnVmICYmIHRoaXMud29ya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBwaXhlbFxyXG4gICAgICAgICAgICAgICAgICAgICAgcmVuZGVyUG9zKys7XHJcbiAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJSZW5kZXIgcG9zOiBcIityZW5kZXJQb3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGxldCB0ZXJtaW5hdGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCB3aW5kb3dFbmQgPSByZW5kZXJQb3MgPj0gbGVmdFBvcyArIHc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHdpbmRvd0VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9yZW5kZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwaGFzZSB0d286IHJlbmRlcmluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5vcmVuZGVyID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgZnJvbSBiZWdpbm5pbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJQb3MgPSBsZWZ0UG9zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIm5vdyByZW5kZXJpbmc6IG1heFBzZDogXCIrbWF4UHNkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0ZXJtaW5hdGUgcmVuZGVyIHBoYXNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybWluYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGxldCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpIC0gdGhpcy5kZnRTaXplIC8gMjtcclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChsZWZ0RnJhbWVQb3MgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnRGcmFtZVBvcyA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAvL2xldCBhZGEgPSBuZXcgQXJyYXk8QXJyYXlCdWZmZXI+KGNocyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiUmVuZGVyIHBvczogXCIrcmVuZGVyUG9zK1wiIGxlZnRGcmFtZVBvczogXCIrbGVmdEZyYW1lUG9zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlcm1pbmF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9EYXRhSG9sZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sZXQgcmVhZCA9IHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5mcmFtZXMobGVmdEZyYW1lUG9zLCB0aGlzLmRmdFNpemUsIGFyckFiQnVmKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhQXNTdWJzYyA9IHJhQXMuZnJhbWVzT2JzKGxlZnRGcmFtZVBvcywgdGhpcy5kZnRTaXplLCBhcnJBYkJ1Zikuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0OiAocmVhZCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcnJBYkJ1ZiAmJiB0aGlzLndvcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWQgPCB0aGlzLmRmdFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gemVybyBwYWRkaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB6cCA9IHJlYWQ7IHpwIDwgdGhpcy5kZnRTaXplOyB6cCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJBYkJ1ZltjaF1benBdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCBhIGNvcHkgaGVyZSBmb3IgdGhlIHdvcmtlciwgb3RoZXJ3aXNlIHRoaXMuYXVkaW9EYXRhIGlzIG5vdCBhY2Nlc3NpYmxlIGFmdGVyIHBvc3RpbmcgdG8gdGhlIHdvcmtlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FkYVtjaF0gPSBhcnJBYkJ1ZltjaF0uYnVmZmVyLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcnJBYkJ1ZkNoID0gYXJyQWJCdWZbY2hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZExlbiA9IGFyckFiQnVmQ2guYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWRhW2NoXSB8fCBhZGFbY2hdLmJ5dGVMZW5ndGggIT09IGFkTGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRhW2NoXSA9IG5ldyBBcnJheUJ1ZmZlcihhZExlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZBZGFDaCA9IG5ldyBGbG9hdDMyQXJyYXkoYWRhW2NoXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZBZGFDaC5zZXQoYXJyQWJCdWZbY2hdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGF0YTogYWRhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RhdGFPZmZzZXQ6IGxlZnRGcmFtZVBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbDogcmVuZGVyUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBtZS5kYXRhLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hzOiBjaHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoOiBmcmFtZUxlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZ0U2l6ZTogdGhpcy5kZnRTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhQc2Q6IG1heFBzZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9yZW5kZXI6IG5vcmVuZGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGU6IHRlcm1pbmF0ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgYWRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlNvbmFncmFtOiBFcnJvciByZWFkaW5nIGF1ZGlvIGRhdGE6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYWRhW2NoXSA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZGEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBsZWZ0RnJhbWVQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbDogcmVuZGVyUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHc6IG1lLmRhdGEudyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHZ3OiB2dyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjaHM6IGNocyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZUxlbmd0aDogZnJhbWVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGZ0U2l6ZTogdGhpcy5kZnRTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1heFBzZDogbWF4UHNkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5vcmVuZGVyOiBub3JlbmRlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGU6IHRlcm1pbmF0ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBhZGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIgJiYgYXVkaW9CdWZmZXIubGVuZ3RoICogYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscyA8IEF1ZGlvQ2FudmFzTGF5ZXJDb21wb25lbnQuRU5BQkxFX1NUUkVBTUlOR19OVU1CRVJfT0ZfU0FNUExFU19USFJFU0hPTEQpIHtcclxuICAgICAgICAgICAgICAgIGxldCBhZGEgPSBuZXcgQXJyYXk8QXJyYXlCdWZmZXI+KGNocyk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vIE5lZWQgYSBjb3B5IGhlcmUgZm9yIHRoZSB3b3JrZXIsIG90aGVyd2lzZSB0aGlzLmF1ZGlvRGF0YSBpcyBub3QgYWNjZXNzaWJsZSBhZnRlciBwb3N0aW5nIHRvIHRoZSB3b3JrZXJcclxuICAgICAgICAgICAgICAgICAgYWRhW2NoXSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoKS5idWZmZXIuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvL2xldCBzdGFydCA9IERhdGUubm93KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWFya2VyQ2FudmFzKSB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBnID0gdGhpcy5tYXJrZXJDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgICAgICAgICAgICAgICBpZiAoZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGcuZmlsbFRleHQoXCJSZW5kZXJpbmcuLi5cIiwgMTAsIDIwKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiBhZGEsXHJcbiAgICAgICAgICAgICAgICAgIGw6IGxlZnRQb3MsXHJcbiAgICAgICAgICAgICAgICAgIHc6IHcsXHJcbiAgICAgICAgICAgICAgICAgIGg6IGgsXHJcbiAgICAgICAgICAgICAgICAgIHZ3OiBNYXRoLnJvdW5kKHRoaXMudmlydHVhbERpbWVuc2lvbi53aWR0aCksXHJcbiAgICAgICAgICAgICAgICAgIGNoczogY2hzLFxyXG4gICAgICAgICAgICAgICAgICBmcmFtZUxlbmd0aDogZnJhbWVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgIGRmdFNpemU6IHRoaXMuZGZ0U2l6ZSxcclxuICAgICAgICAgICAgICAgICAgdGVybWluYXRlOiB0cnVlXHJcbiAgICAgICAgICAgICAgICB9LCBhZGEpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodyA+IDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgIGlmIChmcmFtZXNQZXJQaXhlbCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYXJyU2l6ZSA9IHcgKiBoICogNDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJyU2l6ZSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFyclNpemUgPSAwXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGltZ0RhdGEgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoYXJyU2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJ3ID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBhcnJBYkJ1ZiA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGFyckFiQnVmW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5kZnRTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBsZWZ0RnJhbWVQb3MgPSBNYXRoLmZsb29yKGZyYW1lTGVuZ3RoICogcmVuZGVyUG9zIC8gdncpIC0gdGhpcy5kZnRTaXplIC8gMjtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZnJhbWVzVG9SZWFkID0gdGhpcy5kZnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsZWZ0RnJhbWVQb3MgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBsZWZ0RnJhbWVQb3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYXdTdGF0ZVRleHQoJ0xvYWRpbmcvUmVuZGVyaW5nLi4uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yYUFzU3Vic2MgPSByYUFzLmZyYW1lc09icyhsZWZ0RnJhbWVQb3MsIGZyYW1lc1RvUmVhZCwgYXJyQWJCdWYpLnN1YnNjcmliZShcclxuICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dDogKHJlYWQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyQWJCdWYgJiYgdGhpcy53b3JrZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWFkIDwgdGhpcy5kZnRTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHplcm8gcGFkZGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgenAgPSByZWFkOyB6cCA8IHRoaXMuZGZ0U2l6ZTsgenArKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyQWJCdWZbY2hdW3pwXSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFyckFiQnVmQ2ggPSBhcnJBYkJ1ZltjaF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFkTGVuID0gYXJyQWJCdWZDaC5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGFbY2hdIHx8IGFkYVtjaF0uYnl0ZUxlbmd0aCAhPT0gYWRMZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGFbY2hdID0gbmV3IEFycmF5QnVmZmVyKGFkTGVuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZkFkYUNoID0gbmV3IEZsb2F0MzJBcnJheShhZGFbY2hdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZkFkYUNoLnNldChhcnJBYkJ1ZltjaF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud29ya2VyLnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbDogcmVuZGVyUG9zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBydyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnc6IHZ3LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHM6IGNocyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RhdGE6IGFkYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhT2Zmc2V0OiBsZWZ0RnJhbWVQb3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmdFNpemU6IHRoaXMuZGZ0U2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9yZW5kZXI6IG5vcmVuZGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGU6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBhZGEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiU29uYWdyYW06IEVycm9yIHJlYWRpbmcgYXVkaW8gZGF0YTogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmJvdW5kcyAmJiB0aGlzLmJvdW5kcy5kaW1lbnNpb24pIHtcclxuICAgICAgICAgIGxldCB3ID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgICAgICAgbGV0IGggPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLmRpbWVuc2lvbi5oZWlnaHQpO1xyXG4gICAgICAgICAgbGV0IGcgPSB0aGlzLnNvbmFncmFtQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICAgIGlmIChnKSB7XHJcbiAgICAgICAgICAgIGcuY2xlYXJSZWN0KDAsIDAsIHcsIGgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGRyYXdSZW5kZXJlZCh3Om51bWJlcixoOm51bWJlcixpbWdEYXRhOlVpbnQ4Q2xhbXBlZEFycmF5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc29uYWdyYW1DYW52YXMpIHtcclxuICAgICAgICAgICAgdGhpcy5zb25hZ3JhbUNhbnZhcy53aWR0aCA9IHc7XHJcbiAgICAgICAgICAgIHRoaXMuc29uYWdyYW1DYW52YXMuaGVpZ2h0ID0gaDtcclxuICAgICAgICAgICAgbGV0IGcgPSB0aGlzLnNvbmFncmFtQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuICAgICAgICAgICAgaWYgKGcpIHtcclxuICAgICAgICAgICAgICAgIGlmICh3ID4gMCAmJiBoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBnSW1nRGF0YSA9IGcuY3JlYXRlSW1hZ2VEYXRhKHcsIGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGdJbWdEYXRhLmRhdGEuc2V0KGltZ0RhdGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGcucHV0SW1hZ2VEYXRhKGdJbWdEYXRhLCAwLCAwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmRyYXdCZygpO1xyXG4gICAgICAgIHRoaXMuZHJhd1BsYXlQb3NpdGlvbigpO1xyXG4gICAgfVxyXG5cclxuLy8gICAgIC8vIHN5bmNocm9ub3VzIGRyYXcgKG5vdCB1c2VkIGFueW1vcmUpXHJcbi8vICAgcmVkcmF3KCkge1xyXG4vL1xyXG4vLyAgICAgbGV0IGcgPSB0aGlzLnNvbmFncmFtQ2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuLy9cclxuLy8gICAgIGxldCB3ID0gdGhpcy5zb25hZ3JhbUNhbnZhcy53aWR0aDtcclxuLy8gICAgIGxldCBoID0gdGhpcy5zb25hZ3JhbUNhbnZhcy5oZWlnaHQ7XHJcbi8vICAgICBpZiAoZykge1xyXG4vLyAgICAgICBnLmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcclxuLy8gICAgICAgZy5maWxsU3R5bGUgPSBcIndoaXRlXCI7XHJcbi8vICAgICAgIGcuZmlsbFJlY3QoMCwgMCwgdywgaCk7XHJcbi8vICAgICAgIGlmICh0aGlzLl9hdWRpb0RhdGFIb2xkZXIpIHtcclxuLy8gICAgICAgICBsZXQgc3BlY3RTaXplID0gTWF0aC5mbG9vcih0aGlzLmRmdFNpemUgLyAyKVxyXG4vLyAgICAgICAgIGxldCBjaHMgPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIubnVtYmVyT2ZDaGFubmVscztcclxuLy8gICAgICAgICBsZXQgY2hIID0gaCAvIGNocztcclxuLy9cclxuLy8gICAgICAgICBsZXQgZnJhbWVMZW5ndGggPSB0aGlzLl9hdWRpb0RhdGFIb2xkZXIuZnJhbWVMZW47XHJcbi8vXHJcbi8vICAgICAgICAgbGV0IGZyYW1lc1BlclBpeGVsID0gZnJhbWVMZW5ndGggLyB3O1xyXG4vLyAgICAgICAgIGxldCB5ID0gMDtcclxuLy8gICAgICAgICBsZXQgYXVkaW9CdWZmZXI6QXVkaW9CdWZmZXJ8bnVsbD1udWxsO1xyXG4vLyAgICAgICAgIGxldCBhdWRpb1NvdXJjZT10aGlzLl9hdWRpb0RhdGFIb2xkZXIuYXVkaW9Tb3VyY2U7XHJcbi8vICAgICAgICAgaWYoYXVkaW9Tb3VyY2UgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlclNvdXJjZSl7XHJcbi8vICAgICAgICAgICBhdWRpb0J1ZmZlcj1hdWRpb1NvdXJjZS5hdWRpb0J1ZmZlcjtcclxuLy8gICAgICAgICB9XHJcbi8vXHJcbi8vICAgICAgICAgaWYoYXVkaW9CdWZmZXIpIHtcclxuLy8gICAgICAgICAgIGxldCBiID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmRmdFNpemUpXHJcbi8vXHJcbi8vICAgICAgICAgICBsZXQgc29uYSA9IG5ldyBBcnJheTxBcnJheTxGbG9hdDMyQXJyYXk+PihjaHMpO1xyXG4vLyAgICAgICAgICAgbGV0IG1heCA9IDA7XHJcbi8vICAgICAgICAgICBsZXQgbWF4UHNkID0gLUluZmluaXR5O1xyXG4vLyAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4vLyAgICAgICAgICAgICBsZXQgeCA9IDA7XHJcbi8vICAgICAgICAgICAgIHNvbmFbY2hdID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4odyk7XHJcbi8vXHJcbi8vICAgICAgICAgICAgIGxldCBjaERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbi8vICAgICAgICAgICAgIC8vIFRPRE8gY2VudGVyIGJ1ZmZlclxyXG4vL1xyXG4vLyAgICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4vLyAgICAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4vLyAgICAgICAgICAgICAgIGZyYW1lUG9zID0gTWF0aC5yb3VuZChwaWkgKiBmcmFtZXNQZXJQaXhlbCk7XHJcbi8vICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIERGVCBhdCBwaXhlbCBwb3NpdGlvblxyXG4vLyAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kZnRTaXplOyBpKyspIHtcclxuLy8gICAgICAgICAgICAgICAgIGxldCBjaERhdCA9IGNoRGF0YVtmcmFtZVBvcyArIGldO1xyXG4vLyAgICAgICAgICAgICAgICAgYltpXSA9IGNoRGF0O1xyXG4vLyAgICAgICAgICAgICAgIH1cclxuLy8gICAgICAgICAgICAgICBsZXQgc3BlY3RyID0gdGhpcy5kZnQucHJvY2Vzc1JlYWxNYWduaXR1ZGUoYik7XHJcbi8vICAgICAgICAgICAgICAgc29uYVtjaF1bcGlpXSA9IHNwZWN0cjtcclxuLy8gICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXHJcbi8vICAgICAgICAgICAgICAgbGV0IHBNYXggPSBNYXRoLm1heC5hcHBseShudWxsLCBzcGVjdHIpO1xyXG4vLyAgICAgICAgICAgICAgIGlmIChwTWF4ID4gbWF4KSB7XHJcbi8vICAgICAgICAgICAgICAgICBtYXggPSBwTWF4O1xyXG4vLyAgICAgICAgICAgICAgIH1cclxuLy9cclxuLy8gICAgICAgICAgICAgICBmb3IgKGxldCBzID0gMDsgcyA8IHNwZWN0U2l6ZTsgcysrKSB7XHJcbi8vICAgICAgICAgICAgICAgICBsZXQgcHNkID0gKDIgKiBNYXRoLnBvdyhzcGVjdHJbc10sIDIpKSAvIHNwZWN0U2l6ZTtcclxuLy8gICAgICAgICAgICAgICAgIGlmIChwc2QgPiBtYXhQc2QpIHtcclxuLy8gICAgICAgICAgICAgICAgICAgbWF4UHNkID0gcHNkO1xyXG4vLyAgICAgICAgICAgICAgICAgfVxyXG4vLyAgICAgICAgICAgICAgIH1cclxuLy8gICAgICAgICAgICAgfVxyXG4vLyAgICAgICAgICAgfVxyXG4vLyAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIm1heDogXCIsIG1heCk7XHJcbi8vICAgICAgICAgICBtYXhQc2QgPSAoMiAqIE1hdGgucG93KG1heCwgMikpIC8gc3BlY3RTaXplO1xyXG4vLyAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4vL1xyXG4vLyAgICAgICAgICAgICBsZXQgZnJhbWVQb3MgPSAwO1xyXG4vLyAgICAgICAgICAgICBmb3IgKGxldCBwaWkgPSAwOyBwaWkgPCB3OyBwaWkrKykge1xyXG4vLyAgICAgICAgICAgICAgIGZyYW1lUG9zID0gcGlpICogZnJhbWVzUGVyUGl4ZWw7XHJcbi8vXHJcbi8vICAgICAgICAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBoOyB5KyspIHtcclxuLy8gICAgICAgICAgICAgICAgIGxldCBmcmVxSWR4ID0gTWF0aC5yb3VuZCh5ICogc3BlY3RTaXplIC8gaCk7XHJcbi8vXHJcbi8vICAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIG9uZSBzaWRlZCBwb3dlciBzcGVjdHJhbCBkZW5zaXR5IFBTRCAoZiwgdCkgaW4gUGEyL0h6XHJcbi8vICAgICAgICAgICAgICAgICAvLyBQU0QoZikgcHJvcG9ydGlvbmFsIHRvIDJ8WChmKXwyIC8gKHQyIC0gdDEpXHJcbi8vICAgICAgICAgICAgICAgICBsZXQgdmFsID0gc29uYVtjaF1bcGlpXVtmcmVxSWR4XTtcclxuLy8gICAgICAgICAgICAgICAgIGxldCBwc2QgPSAoMiAqIE1hdGgucG93KHZhbCwgMikpIC8gc3BlY3RTaXplO1xyXG4vL1xyXG4vLyAgICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIGxvZ2FyaXRobWljXHJcbi8vICAgICAgICAgICAgICAgICBsZXQgcHNkTG9nID0gRFNQVXRpbHMudG9MZXZlbEluREIocHNkIC8gbWF4UHNkKTtcclxuLy8gICAgICAgICAgICAgICAgIGxldCBkeW5SYW5nZUluRGIgPSA3MDtcclxuLy8gICAgICAgICAgICAgICAgIGxldCBzY2FsZWRWYWwgPSAocHNkTG9nICsgZHluUmFuZ2VJbkRiKSAvIGR5blJhbmdlSW5EYjtcclxuLy9cclxuLy8gICAgICAgICAgICAgICAgIGlmIChzY2FsZWRWYWwgPiAxKVxyXG4vLyAgICAgICAgICAgICAgICAgICBzY2FsZWRWYWwgPSAxO1xyXG4vLyAgICAgICAgICAgICAgICAgaWYgKHNjYWxlZFZhbCA8IDApIHtcclxuLy8gICAgICAgICAgICAgICAgICAgc2NhbGVkVmFsID0gMDtcclxuLy8gICAgICAgICAgICAgICAgIH1cclxuLy8gICAgICAgICAgICAgICAgIGxldCByZ2JWYWwgPSAoMjU1ICogc2NhbGVkVmFsKTtcclxuLy8gICAgICAgICAgICAgICAgIGlmIChyZ2JWYWwgPCAwKSB7XHJcbi8vIC8vXHRcdFx0XHRcdFx0XHRTeXN0ZW0ub3V0LnByaW50bG4oXCJOZWcgUkdCIHZhbDogXCIrcmdiVmFsKTtcclxuLy8gICAgICAgICAgICAgICAgICAgcmdiVmFsID0gMDtcclxuLy8gICAgICAgICAgICAgICAgIH1cclxuLy8gICAgICAgICAgICAgICAgIGlmIChyZ2JWYWwgPiAyNTUpIHtcclxuLy8gICAgICAgICAgICAgICAgICAgcmdiVmFsID0gMjU1O1xyXG4vLyAgICAgICAgICAgICAgICAgfVxyXG4vLyAgICAgICAgICAgICAgICAgcmdiVmFsID0gMjU1IC0gcmdiVmFsO1xyXG4vLyAgICAgICAgICAgICAgICAgbGV0IGNvbG9yU3RyID0gQ1NTVXRpbHMudG9Db2xvclN0cmluZyhyZ2JWYWwsIHJnYlZhbCwgcmdiVmFsKTtcclxuLy8gICAgICAgICAgICAgICAgIGcuZmlsbFN0eWxlID0gY29sb3JTdHI7XHJcbi8vICAgICAgICAgICAgICAgICBnLmZpbGxSZWN0KHBpaSwgY2hIIC0geSwgMSwgMSk7XHJcbi8vICAgICAgICAgICAgICAgfVxyXG4vLyAgICAgICAgICAgICB9XHJcbi8vICAgICAgICAgICB9XHJcbi8vICAgICAgICAgICB0aGlzLmRyYXdQbGF5UG9zaXRpb24oKTtcclxuLy8gICAgICAgICB9ZWxzZXtcclxuLy8gICAgICAgICAgIHRocm93IEVycm9yKFwiUmVkcmF3IG9ubHkgc3VwcG9ydGVkIHdpdGggYXVkaW8gYnVmZmVyLlwiKVxyXG4vLyAgICAgICAgIH1cclxuLy8gICAgICAgfVxyXG4vLyAgICAgfVxyXG4vLyAgIH1cclxuLy9cclxuXHJcbiAgICBzZXREYXRhKGF1ZGlvRGF0YTogQXVkaW9EYXRhSG9sZGVyIHwgbnVsbCkge1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvRGF0YUhvbGRlciA9IGF1ZGlvRGF0YTtcclxuICAgICAgICB0aGlzLnBsYXlGcmFtZVBvc2l0aW9uID0gMDtcclxuICAgIH1cclxuXHJcbn1cclxuXHJcbiJdfQ==