speechrecorderng 2.21.4 → 2.22.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 (111) hide show
  1. package/{esm2015/lib/action/action.js → esm2020/lib/action/action.mjs} +0 -0
  2. package/{esm2015/lib/audio/audio_display.js → esm2020/lib/audio/audio_display.mjs} +5 -5
  3. package/esm2020/lib/audio/audio_player.mjs +276 -0
  4. package/esm2020/lib/audio/capture/capture.mjs +547 -0
  5. package/{esm2015/lib/audio/context.js → esm2020/lib/audio/context.mjs} +0 -0
  6. package/esm2020/lib/audio/dsp/level_measure.mjs +351 -0
  7. package/{esm2015/lib/audio/format.js → esm2020/lib/audio/format.mjs} +0 -0
  8. package/{esm2015/lib/audio/impl/wavformat.js → esm2020/lib/audio/impl/wavformat.mjs} +0 -0
  9. package/{esm2015/lib/audio/impl/wavwriter.js → esm2020/lib/audio/impl/wavwriter.mjs} +0 -0
  10. package/{esm2015/lib/audio/io/stream.js → esm2020/lib/audio/io/stream.mjs} +0 -0
  11. package/{esm2015/lib/audio/persistor.js → esm2020/lib/audio/persistor.mjs} +0 -0
  12. package/{esm2015/lib/audio/playback/player.js → esm2020/lib/audio/playback/player.mjs} +0 -0
  13. package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +376 -0
  14. package/{esm2015/lib/audio/ui/audio_display_control.js → esm2020/lib/audio/ui/audio_display_control.mjs} +5 -5
  15. package/{esm2015/lib/audio/ui/audio_display_scroll_pane.js → esm2020/lib/audio/ui/audio_display_scroll_pane.mjs} +5 -5
  16. package/{esm2015/lib/audio/ui/audiosignal.js → esm2020/lib/audio/ui/audiosignal.mjs} +5 -5
  17. package/{esm2015/lib/audio/ui/common.js → esm2020/lib/audio/ui/common.mjs} +0 -0
  18. package/esm2020/lib/audio/ui/container.mjs +431 -0
  19. package/{esm2015/lib/audio/ui/livelevel.js → esm2020/lib/audio/ui/livelevel.mjs} +5 -5
  20. package/{esm2015/lib/audio/ui/scroll_pane_horizontal.js → esm2020/lib/audio/ui/scroll_pane_horizontal.mjs} +4 -4
  21. package/{esm2015/lib/audio/ui/sonagram.js → esm2020/lib/audio/ui/sonagram.mjs} +5 -5
  22. package/{esm2015/lib/dsp/utils.js → esm2020/lib/dsp/utils.mjs} +0 -0
  23. package/{esm2015/lib/io/BinaryWriter.js → esm2020/lib/io/BinaryWriter.mjs} +0 -0
  24. package/{esm2015/lib/io/stream.js → esm2020/lib/io/stream.mjs} +0 -0
  25. package/{esm2015/lib/math/2d/geometry.js → esm2020/lib/math/2d/geometry.mjs} +0 -0
  26. package/{esm2015/lib/math/complex.js → esm2020/lib/math/complex.mjs} +0 -0
  27. package/{esm2015/lib/math/dft.js → esm2020/lib/math/dft.mjs} +0 -0
  28. package/{esm2015/lib/math/utils.js → esm2020/lib/math/utils.mjs} +0 -0
  29. package/esm2020/lib/media/utils.mjs +14 -0
  30. package/esm2020/lib/net/uploader.mjs +246 -0
  31. package/{esm2015/lib/speechrecorder/project/project.js → esm2020/lib/speechrecorder/project/project.mjs} +0 -0
  32. package/{esm2015/lib/speechrecorder/project/project.service.js → esm2020/lib/speechrecorder/project/project.service.mjs} +4 -4
  33. package/esm2020/lib/speechrecorder/recording.mjs +54 -0
  34. package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +246 -0
  35. package/{esm2015/lib/speechrecorder/script/script.js → esm2020/lib/speechrecorder/script/script.mjs} +2 -2
  36. package/{esm2015/lib/speechrecorder/script/script.service.js → esm2020/lib/speechrecorder/script/script.service.mjs} +4 -4
  37. package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +1144 -0
  38. package/esm2020/lib/speechrecorder/session/controlpanel.mjs +449 -0
  39. package/{esm2015/lib/speechrecorder/session/item.js → esm2020/lib/speechrecorder/session/item.mjs} +1 -1
  40. package/{esm2015/lib/speechrecorder/session/progress.js → esm2020/lib/speechrecorder/session/progress.mjs} +5 -5
  41. package/{esm2015/lib/speechrecorder/session/prompting.js → esm2020/lib/speechrecorder/session/prompting.mjs} +21 -21
  42. package/esm2020/lib/speechrecorder/session/recorder_combi_pane.mjs +75 -0
  43. package/esm2020/lib/speechrecorder/session/recording_list.mjs +109 -0
  44. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +126 -0
  45. package/{esm2015/lib/speechrecorder/session/recordingfile/recording-file-navi.component.js → esm2020/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs} +5 -5
  46. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +168 -0
  47. package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +415 -0
  48. package/{esm2015/lib/speechrecorder/session/recordingfile/recording-file.js → esm2020/lib/speechrecorder/session/recordingfile/recording-file.mjs} +1 -1
  49. package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +251 -0
  50. package/{esm2015/lib/speechrecorder/session/session.js → esm2020/lib/speechrecorder/session/session.mjs} +0 -0
  51. package/{esm2015/lib/speechrecorder/session/session.service.js → esm2020/lib/speechrecorder/session/session.service.mjs} +4 -4
  52. package/{esm2015/lib/speechrecorder/session/session_finished_dialog.js → esm2020/lib/speechrecorder/session/session_finished_dialog.mjs} +4 -4
  53. package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +1274 -0
  54. package/{esm2015/lib/speechrecorder/session/warning_bar.js → esm2020/lib/speechrecorder/session/warning_bar.mjs} +5 -5
  55. package/{esm2015/lib/speechrecorder/spruploader.js → esm2020/lib/speechrecorder/spruploader.mjs} +4 -4
  56. package/{esm2015/lib/speechrecorder/startstopsignal/startstopsignal.js → esm2020/lib/speechrecorder/startstopsignal/startstopsignal.mjs} +0 -0
  57. package/{esm2015/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.js → esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs} +5 -5
  58. package/esm2020/lib/speechrecorderng.component.mjs +427 -0
  59. package/{esm2015/lib/speechrecorderng.module.js → esm2020/lib/speechrecorderng.module.mjs} +12 -11
  60. package/{esm2015/lib/spr.config.js → esm2020/lib/spr.config.mjs} +4 -4
  61. package/{esm2015/lib/spr.module.version.js → esm2020/lib/spr.module.version.mjs} +2 -2
  62. package/{esm2015/lib/ui/canvas_layer_comp.js → esm2020/lib/ui/canvas_layer_comp.mjs} +4 -4
  63. package/{esm2015/lib/ui/message_dialog.js → esm2020/lib/ui/message_dialog.mjs} +4 -4
  64. package/{esm2015/lib/ui/recordingitem_display.js → esm2020/lib/ui/recordingitem_display.mjs} +9 -9
  65. package/{esm2015/lib/utils/css_utils.js → esm2020/lib/utils/css_utils.mjs} +0 -0
  66. package/{esm2015/lib/utils/scrollIntoViewToBottom.js → esm2020/lib/utils/scrollIntoViewToBottom.mjs} +4 -4
  67. package/{esm2015/lib/utils/ua-parser.js → esm2020/lib/utils/ua-parser.mjs} +0 -0
  68. package/{esm2015/lib/utils/utils.js → esm2020/lib/utils/utils.mjs} +0 -0
  69. package/esm2020/public-api.mjs +31 -0
  70. package/{esm2015/speechrecorderng.js → esm2020/speechrecorderng.mjs} +0 -0
  71. package/fesm2015/speechrecorderng.mjs +11991 -0
  72. package/fesm2015/speechrecorderng.mjs.map +1 -0
  73. package/{fesm2015/speechrecorderng.js → fesm2020/speechrecorderng.mjs} +1863 -285
  74. package/fesm2020/speechrecorderng.mjs.map +1 -0
  75. package/lib/media/utils.d.ts +3 -0
  76. package/lib/net/uploader.d.ts +4 -2
  77. package/lib/speechrecorder/recording.d.ts +14 -3
  78. package/lib/speechrecorder/recordings/recordings.service.d.ts +12 -5
  79. package/lib/speechrecorder/session/audiorecorder.d.ts +150 -0
  80. package/lib/speechrecorder/session/controlpanel.d.ts +2 -1
  81. package/lib/speechrecorder/session/item.d.ts +2 -2
  82. package/lib/speechrecorder/session/recorder_combi_pane.d.ts +26 -0
  83. package/lib/speechrecorder/session/recording_list.d.ts +19 -0
  84. package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +6 -2
  85. package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +5 -4
  86. package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +2 -2
  87. package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +5 -3
  88. package/lib/speechrecorder/session/sessionmanager.d.ts +5 -5
  89. package/lib/speechrecorderng.module.d.ts +31 -28
  90. package/lib/spr.module.version.d.ts +1 -1
  91. package/package.json +33 -20
  92. package/public-api.d.ts +2 -1
  93. package/bundles/speechrecorderng.umd.js +0 -10146
  94. package/bundles/speechrecorderng.umd.js.map +0 -1
  95. package/esm2015/lib/audio/audio_player.js +0 -274
  96. package/esm2015/lib/audio/capture/capture.js +0 -544
  97. package/esm2015/lib/audio/dsp/level_measure.js +0 -356
  98. package/esm2015/lib/audio/ui/audio_canvas_layer_comp.js +0 -364
  99. package/esm2015/lib/audio/ui/container.js +0 -412
  100. package/esm2015/lib/net/uploader.js +0 -220
  101. package/esm2015/lib/speechrecorder/recording.js +0 -38
  102. package/esm2015/lib/speechrecorder/recordings/recordings.service.js +0 -173
  103. package/esm2015/lib/speechrecorder/session/controlpanel.js +0 -446
  104. package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-meta.component.js +0 -83
  105. package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.js +0 -163
  106. package/esm2015/lib/speechrecorder/session/recordingfile/recording-file-view.component.js +0 -386
  107. package/esm2015/lib/speechrecorder/session/recordingfile/recordingfile-service.js +0 -191
  108. package/esm2015/lib/speechrecorder/session/sessionmanager.js +0 -1271
  109. package/esm2015/lib/speechrecorderng.component.js +0 -423
  110. package/esm2015/public-api.js +0 -30
  111. package/fesm2015/speechrecorderng.js.map +0 -1
@@ -0,0 +1,351 @@
1
+ import { DSPUtils } from "../../dsp/utils";
2
+ import { Arrays, WorkerHelper } from "../../utils/utils";
3
+ export const MIN_DB_LEVEL = -40.0;
4
+ export class LevelInfo {
5
+ constructor(channelCount, startFrame = 0, frameLength = 0, minLinLevels, maxLinLevels) {
6
+ this.channelCount = channelCount;
7
+ this.startFrame = startFrame;
8
+ this.frameLength = frameLength;
9
+ this._minLinLevels = this.checkOrInitArray(minLinLevels);
10
+ this._maxLinLevels = this.checkOrInitArray(maxLinLevels);
11
+ }
12
+ get minLinLevels() {
13
+ return this._minLinLevels;
14
+ }
15
+ get maxLinLevels() {
16
+ return this._maxLinLevels;
17
+ }
18
+ checkOrInitArray(arr) {
19
+ if (arr) {
20
+ if (arr.length !== this.channelCount)
21
+ throw new Error("Level arrays must be equal to channel count " + this.channelCount);
22
+ return arr;
23
+ }
24
+ else {
25
+ return new Array(this.channelCount);
26
+ }
27
+ }
28
+ merge(levelInfo) {
29
+ if (levelInfo === null) {
30
+ return;
31
+ }
32
+ if (this.channelCount !== levelInfo.channelCount) {
33
+ throw new Error("Channel count of level info to merge must be equal. (" + this.channelCount + " != " + levelInfo.channelCount + ")");
34
+ }
35
+ let endFrame = this.startFrame + this.frameLength;
36
+ let mergeEndFrame = levelInfo.startFrame + levelInfo.frameLength;
37
+ if (levelInfo.startFrame < this.startFrame) {
38
+ this.startFrame = levelInfo.startFrame;
39
+ }
40
+ if (mergeEndFrame > endFrame) {
41
+ this.frameLength = mergeEndFrame - this.startFrame;
42
+ }
43
+ for (let ch = 0; ch < this.channelCount; ch++) {
44
+ if (levelInfo.minLinLevels[ch] < this.minLinLevels[ch]) {
45
+ this.minLinLevels[ch] = levelInfo.minLinLevels[ch];
46
+ }
47
+ if (levelInfo.maxLinLevels[ch] > this.maxLinLevels[ch]) {
48
+ this.maxLinLevels[ch] = levelInfo.maxLinLevels[ch];
49
+ }
50
+ }
51
+ }
52
+ levelsLin() {
53
+ let lvlsLin = new Array(this.channelCount);
54
+ for (let ch = 0; ch < this.channelCount; ch++) {
55
+ lvlsLin[ch] = Math.max(Math.abs(this.minLinLevels[ch]), Math.abs(this.maxLinLevels[ch]));
56
+ }
57
+ return lvlsLin;
58
+ }
59
+ powerLevelsDB() {
60
+ let lvlsDb = new Array(this.channelCount);
61
+ for (let ch = 0; ch < this.channelCount; ch++) {
62
+ lvlsDb[ch] = DSPUtils.toPowerLevelInDB(this.levelsLin()[ch]);
63
+ }
64
+ return lvlsDb;
65
+ }
66
+ powerLevelDB() {
67
+ let pLvlsDb = this.powerLevelsDB();
68
+ return Math.max(...pLvlsDb);
69
+ }
70
+ clone() {
71
+ return new LevelInfo(this.channelCount, this.startFrame, this.frameLength, Arrays.cloneNumberArray(this.minLinLevels), Arrays.cloneNumberArray(this.maxLinLevels));
72
+ }
73
+ }
74
+ export class LevelInfos {
75
+ constructor(bufferLevelInfos, peakLevelInfo) {
76
+ this.bufferLevelInfos = bufferLevelInfos;
77
+ this.peakLevelInfo = peakLevelInfo;
78
+ }
79
+ framesPerBuffer() {
80
+ if (this.bufferLevelInfos.length > 0) {
81
+ return this.bufferLevelInfos[0].frameLength;
82
+ }
83
+ return this.peakLevelInfo.frameLength / this.bufferLevelInfos.length;
84
+ }
85
+ }
86
+ export class PeakLevelInterceptor {
87
+ constructor(levelListener) {
88
+ this.levelListener = levelListener;
89
+ this._channelCount = 0;
90
+ this._peakDbLvl = MIN_DB_LEVEL;
91
+ }
92
+ get peakDbLvl() {
93
+ return this._peakDbLvl;
94
+ }
95
+ get channelCount() {
96
+ return this._channelCount;
97
+ }
98
+ set channelCount(value) {
99
+ this._channelCount = value;
100
+ if (this.levelListener) {
101
+ this.levelListener.channelCount = value;
102
+ }
103
+ }
104
+ update(levelInfo, peakLevelInfo) {
105
+ let peakDBVal = levelInfo.powerLevelDB();
106
+ if (this.peakDbLvl < peakDBVal) {
107
+ this._peakDbLvl = peakDBVal;
108
+ }
109
+ }
110
+ streamFinished() {
111
+ if (this.levelListener) {
112
+ this.levelListener.streamFinished();
113
+ }
114
+ }
115
+ reset() {
116
+ this._peakDbLvl = MIN_DB_LEVEL;
117
+ if (this.levelListener) {
118
+ this.levelListener.reset();
119
+ }
120
+ }
121
+ }
122
+ export class LevelMeasure {
123
+ constructor() {
124
+ this.worker = null;
125
+ this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
126
+ }
127
+ calcBufferLevelInfos(audioBuffer, bufferTimeLength) {
128
+ return new Promise((resolve) => {
129
+ let chs = audioBuffer.numberOfChannels;
130
+ let bufferFrameLength = Math.round(audioBuffer.sampleRate * bufferTimeLength);
131
+ let buffers = new Array(chs);
132
+ for (let ch = 0; ch < chs; ch++) {
133
+ let adCh = audioBuffer.getChannelData(ch);
134
+ let adChCopy = new Float32Array(adCh.length);
135
+ adChCopy.set(adCh);
136
+ buffers[ch] = adChCopy.buffer;
137
+ }
138
+ this.worker = new Worker(this.workerURL);
139
+ this.worker.onmessage = (me) => {
140
+ let linLevelArrs = new Array(chs);
141
+ for (let ch = 0; ch < chs; ch++) {
142
+ linLevelArrs[ch] = new Float32Array(me.data.linLevelBuffers[ch]);
143
+ }
144
+ let bufferCount = Math.ceil(me.data.frameLength / me.data.bufferFrameLength);
145
+ let framePos = 0;
146
+ let bufferLevelInfos = new Array();
147
+ let peakLevelInfo = new LevelInfo(chs);
148
+ for (let bi = 0; bi < bufferCount; bi++) {
149
+ let minLevels = new Array(chs);
150
+ let maxLevels = new Array(chs);
151
+ for (let ch = 0; ch < chs; ch++) {
152
+ let linLvlArrPos = bi * 2;
153
+ minLevels[ch] = linLevelArrs[ch][linLvlArrPos];
154
+ maxLevels[ch] = linLevelArrs[ch][linLvlArrPos + 1];
155
+ }
156
+ let bli = new LevelInfo(chs, framePos, me.data.bufferFrameLength, minLevels, maxLevels);
157
+ bufferLevelInfos.push(bli);
158
+ peakLevelInfo.merge(bli);
159
+ }
160
+ this.terminateWorker();
161
+ resolve(new LevelInfos(bufferLevelInfos, peakLevelInfo));
162
+ };
163
+ this.worker.postMessage({ bufferFrameLength: bufferFrameLength, audioData: buffers, chs: chs }, buffers);
164
+ });
165
+ }
166
+ terminateWorker() {
167
+ this.worker?.terminate();
168
+ }
169
+ /*
170
+ * Method used as worker code.
171
+ */
172
+ workerFunction() {
173
+ self.onmessage = function (msg) {
174
+ let chs = msg.data.chs;
175
+ let bufferFrameLength = msg.data.bufferFrameLength;
176
+ let audioData = new Array(chs);
177
+ let linLevels = new Array(chs);
178
+ for (let ch = 0; ch < chs; ch++) {
179
+ audioData[ch] = new Float32Array(msg.data.audioData[ch]);
180
+ }
181
+ let frameLength = audioData[0].length;
182
+ let bufferCount = Math.ceil(frameLength / bufferFrameLength);
183
+ for (let ch = 0; ch < chs; ch++) {
184
+ linLevels[ch] = new Float32Array(bufferCount * 2);
185
+ }
186
+ if (audioData && chs > 0) {
187
+ for (let ch = 0; ch < chs; ch++) {
188
+ let chData = audioData[ch];
189
+ for (let s = 0; s < frameLength; s++) {
190
+ let bi = Math.floor(s / bufferFrameLength);
191
+ let lvlArrPos = bi * 2;
192
+ //let bs = s % bufferFrameLength;
193
+ let chSample = chData[s];
194
+ if (chSample < linLevels[ch][lvlArrPos]) {
195
+ linLevels[ch][lvlArrPos] = chSample;
196
+ }
197
+ lvlArrPos++;
198
+ if (chSample > linLevels[ch][lvlArrPos]) {
199
+ linLevels[ch][lvlArrPos] = chSample;
200
+ }
201
+ }
202
+ }
203
+ const linLevelBufs = new Array(chs);
204
+ for (let ch = 0; ch < chs; ch++) {
205
+ linLevelBufs[ch] = linLevels[ch].buffer;
206
+ }
207
+ postMessage({ bufferFrameLength: bufferFrameLength, frameLength: frameLength, linLevelBuffers: linLevelBufs }, linLevelBufs);
208
+ }
209
+ };
210
+ }
211
+ }
212
+ export class StreamLevelMeasure {
213
+ constructor() {
214
+ this.currentLevelInfos = null;
215
+ this.peakLevelInfo = null;
216
+ this.worker = null;
217
+ this.channelCount = 0;
218
+ this.bufferIndex = 0;
219
+ this.frameCount = 0;
220
+ this.levelListener = null;
221
+ this.peakLevelListener = null;
222
+ this.peakLevelInDb = MIN_DB_LEVEL;
223
+ this.workerURL = WorkerHelper.buildWorkerBlobURL(this.workerFunction);
224
+ }
225
+ setFormat(channels, sampleRate) {
226
+ this.channelCount = channels;
227
+ this.currentLevelInfos = new LevelInfo(this.channelCount);
228
+ this.peakLevelInfo = new LevelInfo(this.channelCount);
229
+ this.worker = new Worker(this.workerURL);
230
+ this.worker.onmessage = (me) => {
231
+ let streamFinished = me.data.streamFinished;
232
+ if (streamFinished) {
233
+ if (this.levelListener) {
234
+ this.levelListener.streamFinished();
235
+ }
236
+ }
237
+ else {
238
+ let minLevels = new Array(this.channelCount);
239
+ let maxLevels = new Array(this.channelCount);
240
+ for (let ch = 0; ch < this.channelCount; ch++) {
241
+ let fls = new Float32Array(me.data.linLevelBuffers[ch]);
242
+ minLevels[ch] = fls[0];
243
+ maxLevels[ch] = fls[1];
244
+ }
245
+ let bi = new LevelInfo(this.channelCount, this.frameCount, me.data.fraemLength, minLevels, maxLevels);
246
+ this.updateLevels(bi);
247
+ }
248
+ };
249
+ }
250
+ nextStream() {
251
+ this.reset();
252
+ }
253
+ reset() {
254
+ this.currentLevelInfos = new LevelInfo(this.channelCount);
255
+ this.peakLevelInfo = new LevelInfo(this.channelCount);
256
+ if (this.levelListener) {
257
+ this.levelListener.reset();
258
+ this.levelListener.channelCount = this.channelCount;
259
+ }
260
+ if (this.peakLevelListener) {
261
+ this.peakLevelInDb = MIN_DB_LEVEL;
262
+ this.peakLevelListener(this.peakLevelInDb);
263
+ }
264
+ }
265
+ write(bufferData) {
266
+ let bufArrCopies = new Array(bufferData.length);
267
+ let buffers = new Array(bufferData.length);
268
+ for (let ch = 0; ch < bufferData.length; ch++) {
269
+ bufArrCopies[ch] = bufferData[ch].slice();
270
+ buffers[ch] = bufArrCopies[ch].buffer;
271
+ }
272
+ this.worker?.postMessage({
273
+ streamFinished: false,
274
+ audioData: buffers,
275
+ chs: this.channelCount,
276
+ bufferIndex: this.bufferIndex
277
+ }, buffers);
278
+ this.bufferIndex++;
279
+ return bufArrCopies[0].length;
280
+ }
281
+ flush() {
282
+ this.worker?.postMessage({ streamFinished: true });
283
+ }
284
+ close() {
285
+ this.worker?.terminate();
286
+ }
287
+ /*
288
+ * Method used as worker code.
289
+ */
290
+ workerFunction() {
291
+ self.onmessage = function (msg) {
292
+ let streamFinished = msg.data.streamFinished;
293
+ if (streamFinished) {
294
+ postMessage({ streamFinished: true });
295
+ }
296
+ else {
297
+ let chs = msg.data.chs;
298
+ let frameLength = null;
299
+ let audioData = new Array(chs);
300
+ let linLevels = new Array(chs);
301
+ for (let ch = 0; ch < chs; ch++) {
302
+ linLevels[ch] = new Float32Array(2);
303
+ audioData[ch] = new Float32Array(msg.data.audioData[ch]);
304
+ }
305
+ if (audioData) {
306
+ for (let ch = 0; ch < chs; ch++) {
307
+ let chData = audioData[ch];
308
+ if (frameLength === null) {
309
+ frameLength = chData.length;
310
+ }
311
+ for (let s = 0; s < frameLength; s++) {
312
+ let chSample = chData[s];
313
+ if (chSample < linLevels[ch][0]) {
314
+ linLevels[ch][0] = chSample;
315
+ }
316
+ if (chSample > linLevels[ch][1]) {
317
+ linLevels[ch][1] = chSample;
318
+ }
319
+ }
320
+ }
321
+ }
322
+ let linLevelBufs = new Array(chs);
323
+ for (let ch = 0; ch < chs; ch++) {
324
+ linLevelBufs[ch] = linLevels[ch].buffer;
325
+ }
326
+ postMessage({ streamFinished: false, frameLength: frameLength, linLevelBuffers: linLevelBufs }, linLevelBufs);
327
+ }
328
+ };
329
+ }
330
+ updateLevels(bufferLevelInfo) {
331
+ this.currentLevelInfos = bufferLevelInfo;
332
+ if (this.peakLevelInfo) {
333
+ this.peakLevelInfo.merge(bufferLevelInfo);
334
+ if (this.levelListener) {
335
+ this.levelListener.update(this.currentLevelInfos, this.peakLevelInfo.clone());
336
+ }
337
+ if (this.peakLevelListener) {
338
+ let peakDBVal = bufferLevelInfo.powerLevelDB();
339
+ if (this.peakLevelInDb < peakDBVal) {
340
+ this.peakLevelInDb = peakDBVal;
341
+ // the event comes from outside of an Angular zone
342
+ this.peakLevelListener(this.peakLevelInDb);
343
+ }
344
+ }
345
+ }
346
+ }
347
+ stop() {
348
+ this.worker?.terminate();
349
+ }
350
+ }
351
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGV2ZWxfbWVhc3VyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9kc3AvbGV2ZWxfbWVhc3VyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFekMsT0FBTyxFQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUV2RCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUM7QUFJbEMsTUFBTSxPQUFPLFNBQVM7SUFLcEIsWUFBNEIsWUFBb0IsRUFDN0IsYUFBcUIsQ0FBQyxFQUN0QixjQUFzQixDQUFDLEVBQzlCLFlBQTRCLEVBQzVCLFlBQTRCO1FBSlosaUJBQVksR0FBWixZQUFZLENBQVE7UUFDN0IsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUd4QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQUVPLGdCQUFnQixDQUFDLEdBQThCO1FBQ3JELElBQUksR0FBRyxFQUFFO1lBQ1AsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxZQUFZO2dCQUNsQyxNQUFPLElBQUksS0FBSyxDQUFDLDhDQUE4QyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2RixPQUFPLEdBQUcsQ0FBQztTQUNaO2FBQU07WUFDTCxPQUFPLElBQUksS0FBSyxDQUFTLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQTtTQUM1QztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsU0FBb0I7UUFDeEIsSUFBSSxTQUFTLEtBQUssSUFBSSxFQUFFO1lBQ3RCLE9BQU87U0FDUjtRQUNELElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxTQUFTLENBQUMsWUFBWSxFQUFFO1lBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLEdBQUcsU0FBUyxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsQ0FBQztTQUN0STtRQUVELElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNsRCxJQUFJLGFBQWEsR0FBRyxTQUFTLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxXQUFXLENBQUM7UUFFakUsSUFBSSxTQUFTLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDMUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO1NBQ3hDO1FBRUQsSUFBSSxhQUFhLEdBQUcsUUFBUSxFQUFFO1lBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7U0FDcEQ7UUFFRCxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUU3QyxJQUFJLFNBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDdEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3BEO1lBQ0QsSUFBSSxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQ3RELElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUNwRDtTQUNGO0lBQ0gsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBUyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbkQsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDN0MsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxRjtRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxhQUFhO1FBQ1gsSUFBSSxNQUFNLEdBQUcsSUFBSSxLQUFLLENBQVMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2xELEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsRUFBRSxFQUFFO1lBQzdDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDOUQ7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsWUFBWTtRQUNWLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFDbkgsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxVQUFVO0lBQ3JCLFlBQTRCLGdCQUFrQyxFQUFrQixhQUF3QjtRQUE1RSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQWtCLGtCQUFhLEdBQWIsYUFBYSxDQUFXO0lBQ3hHLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFDLENBQUMsRUFBQztZQUNoQyxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7U0FDN0M7UUFDRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxHQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFDckUsQ0FBQztDQUNGO0FBMEJELE1BQU0sT0FBTyxvQkFBb0I7SUFxQi9CLFlBQW9CLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBTnhDLGtCQUFhLEdBQVMsQ0FBQyxDQUFDO1FBRXhCLGVBQVUsR0FBRyxZQUFZLENBQUM7SUFJaUIsQ0FBQztJQXBCcEQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztJQUVELElBQUksWUFBWSxDQUFDLEtBQWE7UUFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBRyxJQUFJLENBQUMsYUFBYSxFQUFDO1lBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxHQUFDLEtBQUssQ0FBQztTQUN2QztJQUNILENBQUM7SUFVRCxNQUFNLENBQUMsU0FBb0IsRUFBRSxhQUF3QjtRQUNuRCxJQUFJLFNBQVMsR0FBRyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsRUFBRTtZQUM5QixJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztTQUM3QjtJQUNILENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBRyxJQUFJLENBQUMsYUFBYSxFQUFDO1lBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7U0FDckM7SUFDSCxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDO1FBQy9CLElBQUcsSUFBSSxDQUFDLGFBQWEsRUFBQztZQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQzVCO0lBQ0gsQ0FBQztDQUNGO0FBS0QsTUFBTSxPQUFPLFlBQVk7SUFLdkI7UUFGUSxXQUFNLEdBQWMsSUFBSSxDQUFDO1FBRy9CLElBQUksQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUN2RSxDQUFDO0lBRUQsb0JBQW9CLENBQUMsV0FBd0IsRUFBRSxnQkFBd0I7UUFDckUsT0FBTyxJQUFJLE9BQU8sQ0FBYSxDQUFDLE9BQU8sRUFBQyxFQUFFO1lBQ3hDLElBQUksR0FBRyxHQUFHLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQztZQUN2QyxJQUFJLGlCQUFpQixHQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFVBQVUsR0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzFFLElBQUksT0FBTyxHQUFHLElBQUksS0FBSyxDQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUU7Z0JBQy9CLElBQUksSUFBSSxHQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3hDLElBQUksUUFBUSxHQUFDLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDM0MsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbkIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7YUFDL0I7WUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUU3QixJQUFJLFlBQVksR0FBQyxJQUFJLEtBQUssQ0FBZSxHQUFHLENBQUMsQ0FBQztnQkFDOUMsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTtvQkFDL0IsWUFBWSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ2xFO2dCQUVELElBQUksV0FBVyxHQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUN6RSxJQUFJLFFBQVEsR0FBQyxDQUFDLENBQUM7Z0JBQ2YsSUFBSSxnQkFBZ0IsR0FBQyxJQUFJLEtBQUssRUFBYSxDQUFDO2dCQUM1QyxJQUFJLGFBQWEsR0FBQyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDckMsS0FBSSxJQUFJLEVBQUUsR0FBQyxDQUFDLEVBQUMsRUFBRSxHQUFDLFdBQVcsRUFBQyxFQUFFLEVBQUUsRUFBRTtvQkFDaEMsSUFBSSxTQUFTLEdBQUcsSUFBSSxLQUFLLENBQVMsR0FBRyxDQUFDLENBQUM7b0JBQ3ZDLElBQUksU0FBUyxHQUFHLElBQUksS0FBSyxDQUFTLEdBQUcsQ0FBQyxDQUFDO29CQUN2QyxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFO3dCQUMvQixJQUFJLFlBQVksR0FBQyxFQUFFLEdBQUMsQ0FBQyxDQUFDO3dCQUN0QixTQUFTLENBQUMsRUFBRSxDQUFDLEdBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUM3QyxTQUFTLENBQUMsRUFBRSxDQUFDLEdBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFlBQVksR0FBQyxDQUFDLENBQUMsQ0FBQztxQkFDaEQ7b0JBQ0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxTQUFTLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDeEYsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMzQixhQUFhLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUMxQjtnQkFDRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO1lBQzNELENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUMsaUJBQWlCLEVBQUMsaUJBQWlCLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFdkcsQ0FBQyxDQUFDLENBQUM7SUFFTCxDQUFDO0lBR08sZUFBZTtRQUNyQixJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBRTNCLENBQUM7SUFFRDs7T0FFRztJQUNILGNBQWM7UUFDWixJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsR0FBZ0I7WUFFekMsSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7WUFDdkIsSUFBSSxpQkFBaUIsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1lBRW5ELElBQUksU0FBUyxHQUFHLElBQUksS0FBSyxDQUFlLEdBQUcsQ0FBQyxDQUFDO1lBQzdDLElBQUksU0FBUyxHQUFHLElBQUksS0FBSyxDQUFlLEdBQUcsQ0FBQyxDQUFDO1lBRTdDLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUU7Z0JBQy9CLFNBQVMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQzFEO1lBQ0QsSUFBSSxXQUFXLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUN0QyxJQUFJLFdBQVcsR0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3pELEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUU7Z0JBQy9CLFNBQVMsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLFlBQVksQ0FBQyxXQUFXLEdBQUMsQ0FBQyxDQUFDLENBQUM7YUFDakQ7WUFDRCxJQUFJLFNBQVMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFO2dCQUN4QixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFO29CQUMvQixJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBRTNCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUU7d0JBQ3BDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLGlCQUFpQixDQUFDLENBQUM7d0JBQzNDLElBQUksU0FBUyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBQ3ZCLGlDQUFpQzt3QkFDakMsSUFBSSxRQUFRLEdBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUN2QixJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUU7NEJBQ3ZDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxRQUFRLENBQUM7eUJBQ3JDO3dCQUNELFNBQVMsRUFBRSxDQUFDO3dCQUNaLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFBRTs0QkFDdkMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLFFBQVEsQ0FBQzt5QkFDckM7cUJBQ0Y7aUJBQ0Y7Z0JBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQU0sR0FBRyxDQUFDLENBQUM7Z0JBQ3pDLEtBQUssSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUU7b0JBQy9CLFlBQVksQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDO2lCQUN6QztnQkFDRCxXQUFXLENBQUMsRUFBQyxpQkFBaUIsRUFBQyxpQkFBaUIsRUFBQyxXQUFXLEVBQUMsV0FBVyxFQUFDLGVBQWUsRUFBRSxZQUFZLEVBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQzthQUN4SDtRQUNILENBQUMsQ0FBQTtJQUNILENBQUM7Q0FDRjtBQUdELE1BQU0sT0FBTyxrQkFBa0I7SUFlN0I7UUFiQSxzQkFBaUIsR0FBaUIsSUFBSSxDQUFDO1FBQ3ZDLGtCQUFhLEdBQWlCLElBQUksQ0FBQztRQUczQixXQUFNLEdBQWMsSUFBSSxDQUFDO1FBQ3pCLGlCQUFZLEdBQVMsQ0FBQyxDQUFDO1FBQ3ZCLGdCQUFXLEdBQVcsQ0FBQyxDQUFDO1FBQ3hCLGVBQVUsR0FBVyxDQUFDLENBQUM7UUFFL0Isa0JBQWEsR0FBcUIsSUFBSSxDQUFDO1FBQ3ZDLHNCQUFpQixHQUFvQyxJQUFJLENBQUM7UUFDbEQsa0JBQWEsR0FBUSxZQUFZLENBQUM7UUFHeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO0lBQ3ZFLENBQUM7SUFFRCxTQUFTLENBQUMsUUFBZ0IsRUFBRSxVQUFrQjtRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQztRQUM3QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUU7WUFDN0IsSUFBSSxjQUFjLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDNUMsSUFBSSxjQUFjLEVBQUU7Z0JBQ2xCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtvQkFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQTtpQkFDcEM7YUFDRjtpQkFBTTtnQkFFTCxJQUFJLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBUyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ3JELElBQUksU0FBUyxHQUFHLElBQUksS0FBSyxDQUFTLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDckQsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxFQUFFLEVBQUU7b0JBQzdDLElBQUksR0FBRyxHQUFHLElBQUksWUFBWSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ3hELFNBQVMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZCLFNBQVMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3hCO2dCQUNELElBQUksRUFBRSxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ3RHLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDdkI7UUFDSCxDQUFDLENBQUE7SUFDSCxDQUFDO0lBR0QsVUFBVTtRQUNSLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFFTyxLQUFLO1FBQ1gsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0RCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1NBQ3JEO1FBQ0QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsSUFBSSxDQUFDLGFBQWEsR0FBQyxZQUFZLENBQUM7WUFDaEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUM1QztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBK0I7UUFDbkMsSUFBSSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQWUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlELElBQUksT0FBTyxHQUFHLElBQUksS0FBSyxDQUFNLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRCxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUM3QyxZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDO1NBQ3ZDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUM7WUFDdkIsY0FBYyxFQUFFLEtBQUs7WUFDckIsU0FBUyxFQUFFLE9BQU87WUFDbEIsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQ3RCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztTQUM5QixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ1osSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLE9BQU8sWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUMsY0FBYyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7SUFFbkQsQ0FBQztJQUVELEtBQUs7UUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNILGNBQWM7UUFDWixJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsR0FBZ0I7WUFDekMsSUFBSSxjQUFjLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDN0MsSUFBSSxjQUFjLEVBQUU7Z0JBQ2xCLFdBQVcsQ0FBQyxFQUFDLGNBQWMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO2FBQ3JDO2lCQUFNO2dCQUNMLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO2dCQUN2QixJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksU0FBUyxHQUFHLElBQUksS0FBSyxDQUFlLEdBQUcsQ0FBQyxDQUFDO2dCQUM3QyxJQUFJLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBZSxHQUFHLENBQUMsQ0FBQztnQkFDN0MsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTtvQkFDL0IsU0FBUyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNwQyxTQUFTLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztpQkFDMUQ7Z0JBRUQsSUFBSSxTQUFTLEVBQUU7b0JBQ2IsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTt3QkFDL0IsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUMzQixJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUU7NEJBQ3hCLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO3lCQUM3Qjt3QkFDRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFOzRCQUNwQyxJQUFJLFFBQVEsR0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3ZCLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQ0FDL0IsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQzs2QkFDN0I7NEJBQ0QsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dDQUMvQixTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDOzZCQUM3Qjt5QkFDRjtxQkFDRjtpQkFDRjtnQkFDRCxJQUFJLFlBQVksR0FBRyxJQUFJLEtBQUssQ0FBTSxHQUFHLENBQUMsQ0FBQztnQkFDdkMsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRTtvQkFDL0IsWUFBWSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUM7aUJBQ3pDO2dCQUNELFdBQVcsQ0FBQyxFQUFDLGNBQWMsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7YUFDN0c7UUFDSCxDQUFDLENBQUE7SUFDSCxDQUFDO0lBRUQsWUFBWSxDQUFDLGVBQTBCO1FBRXJDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxlQUFlLENBQUM7UUFDekMsSUFBRyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzFDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQzthQUMvRTtZQUNELElBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFDO2dCQUN4QixJQUFJLFNBQVMsR0FBRyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQy9DLElBQUksSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLEVBQUU7b0JBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO29CQUMvQixrREFBa0Q7b0JBQ2xELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7aUJBQzVDO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFHRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUMzQixDQUFDO0NBR0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RTUFV0aWxzfSBmcm9tIFwiLi4vLi4vZHNwL3V0aWxzXCI7XHJcbmltcG9ydCB7U2VxdWVuY2VBdWRpb0Zsb2F0MzJPdXRTdHJlYW19IGZyb20gXCIuLi9pby9zdHJlYW1cIjtcclxuaW1wb3J0IHtBcnJheXMsIFdvcmtlckhlbHBlcn0gZnJvbSBcIi4uLy4uL3V0aWxzL3V0aWxzXCI7XHJcblxyXG5leHBvcnQgY29uc3QgTUlOX0RCX0xFVkVMID0gLTQwLjA7XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBMZXZlbEluZm8ge1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IF9taW5MaW5MZXZlbHM6IEFycmF5PG51bWJlcj47XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TGluTGV2ZWxzOiBBcnJheTxudW1iZXI+O1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgY2hhbm5lbENvdW50OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgcHVibGljIHN0YXJ0RnJhbWU6IG51bWJlciA9IDAsXHJcbiAgICAgICAgICAgICAgcHVibGljIGZyYW1lTGVuZ3RoOiBudW1iZXIgPSAwLFxyXG4gICAgICAgICAgICAgIG1pbkxpbkxldmVscz86IEFycmF5PG51bWJlcj4sXHJcbiAgICAgICAgICAgICAgbWF4TGluTGV2ZWxzPzogQXJyYXk8bnVtYmVyPikge1xyXG4gICAgdGhpcy5fbWluTGluTGV2ZWxzID0gdGhpcy5jaGVja09ySW5pdEFycmF5KG1pbkxpbkxldmVscyk7XHJcbiAgICB0aGlzLl9tYXhMaW5MZXZlbHMgPSB0aGlzLmNoZWNrT3JJbml0QXJyYXkobWF4TGluTGV2ZWxzKTtcclxuICB9XHJcblxyXG4gIGdldCBtaW5MaW5MZXZlbHMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWluTGluTGV2ZWxzO1xyXG4gIH1cclxuXHJcbiAgZ2V0IG1heExpbkxldmVscygpIHtcclxuICAgIHJldHVybiB0aGlzLl9tYXhMaW5MZXZlbHM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNoZWNrT3JJbml0QXJyYXkoYXJyOiBBcnJheTxudW1iZXI+IHwgdW5kZWZpbmVkKTogQXJyYXk8bnVtYmVyPiB7XHJcbiAgICBpZiAoYXJyKSB7XHJcbiAgICAgIGlmIChhcnIubGVuZ3RoICE9PSB0aGlzLmNoYW5uZWxDb3VudClcclxuICAgICAgICB0aHJvdyAgbmV3IEVycm9yKFwiTGV2ZWwgYXJyYXlzIG11c3QgYmUgZXF1YWwgdG8gY2hhbm5lbCBjb3VudCBcIiArIHRoaXMuY2hhbm5lbENvdW50KTtcclxuICAgICAgcmV0dXJuIGFycjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG1lcmdlKGxldmVsSW5mbzogTGV2ZWxJbmZvKSB7XHJcbiAgICBpZiAobGV2ZWxJbmZvID09PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNoYW5uZWxDb3VudCAhPT0gbGV2ZWxJbmZvLmNoYW5uZWxDb3VudCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGFubmVsIGNvdW50IG9mIGxldmVsIGluZm8gdG8gbWVyZ2UgbXVzdCBiZSBlcXVhbC4gKFwiICsgdGhpcy5jaGFubmVsQ291bnQgKyBcIiAhPSBcIiArIGxldmVsSW5mby5jaGFubmVsQ291bnQgKyBcIilcIik7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGVuZEZyYW1lID0gdGhpcy5zdGFydEZyYW1lICsgdGhpcy5mcmFtZUxlbmd0aDtcclxuICAgIGxldCBtZXJnZUVuZEZyYW1lID0gbGV2ZWxJbmZvLnN0YXJ0RnJhbWUgKyBsZXZlbEluZm8uZnJhbWVMZW5ndGg7XHJcblxyXG4gICAgaWYgKGxldmVsSW5mby5zdGFydEZyYW1lIDwgdGhpcy5zdGFydEZyYW1lKSB7XHJcbiAgICAgIHRoaXMuc3RhcnRGcmFtZSA9IGxldmVsSW5mby5zdGFydEZyYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXJnZUVuZEZyYW1lID4gZW5kRnJhbWUpIHtcclxuICAgICAgdGhpcy5mcmFtZUxlbmd0aCA9IG1lcmdlRW5kRnJhbWUgLSB0aGlzLnN0YXJ0RnJhbWU7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcblxyXG4gICAgICBpZiAobGV2ZWxJbmZvLm1pbkxpbkxldmVsc1tjaF0gPCB0aGlzLm1pbkxpbkxldmVsc1tjaF0pIHtcclxuICAgICAgICB0aGlzLm1pbkxpbkxldmVsc1tjaF0gPSBsZXZlbEluZm8ubWluTGluTGV2ZWxzW2NoXTtcclxuICAgICAgfVxyXG4gICAgICBpZiAobGV2ZWxJbmZvLm1heExpbkxldmVsc1tjaF0gPiB0aGlzLm1heExpbkxldmVsc1tjaF0pIHtcclxuICAgICAgICB0aGlzLm1heExpbkxldmVsc1tjaF0gPSBsZXZlbEluZm8ubWF4TGluTGV2ZWxzW2NoXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbGV2ZWxzTGluKCk6IEFycmF5PG51bWJlcj4ge1xyXG4gICAgbGV0IGx2bHNMaW4gPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgbHZsc0xpbltjaF0gPSBNYXRoLm1heChNYXRoLmFicyh0aGlzLm1pbkxpbkxldmVsc1tjaF0pLCBNYXRoLmFicyh0aGlzLm1heExpbkxldmVsc1tjaF0pKTtcclxuICAgIH1cclxuICAgIHJldHVybiBsdmxzTGluO1xyXG4gIH1cclxuXHJcbiAgcG93ZXJMZXZlbHNEQigpOiBBcnJheTxudW1iZXI+IHtcclxuICAgIGxldCBsdmxzRGIgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgbHZsc0RiW2NoXSA9IERTUFV0aWxzLnRvUG93ZXJMZXZlbEluREIodGhpcy5sZXZlbHNMaW4oKVtjaF0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGx2bHNEYjtcclxuICB9XHJcblxyXG4gIHBvd2VyTGV2ZWxEQigpOiBudW1iZXIge1xyXG4gICAgbGV0IHBMdmxzRGIgPSB0aGlzLnBvd2VyTGV2ZWxzREIoKTtcclxuICAgIHJldHVybiBNYXRoLm1heCguLi5wTHZsc0RiKTtcclxuICB9XHJcblxyXG4gIGNsb25lKCk6IExldmVsSW5mbyB7XHJcbiAgICByZXR1cm4gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCwgdGhpcy5zdGFydEZyYW1lLCB0aGlzLmZyYW1lTGVuZ3RoLCBBcnJheXMuY2xvbmVOdW1iZXJBcnJheSh0aGlzLm1pbkxpbkxldmVscyksXHJcbiAgICAgIEFycmF5cy5jbG9uZU51bWJlckFycmF5KHRoaXMubWF4TGluTGV2ZWxzKSk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgTGV2ZWxJbmZvcyB7XHJcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IGJ1ZmZlckxldmVsSW5mb3M6IEFycmF5PExldmVsSW5mbz4sIHB1YmxpYyByZWFkb25seSBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pIHtcclxuICB9XHJcblxyXG4gIGZyYW1lc1BlckJ1ZmZlcigpOm51bWJlcntcclxuICAgIGlmKHRoaXMuYnVmZmVyTGV2ZWxJbmZvcy5sZW5ndGg+MCl7XHJcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlckxldmVsSW5mb3NbMF0uZnJhbWVMZW5ndGg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5wZWFrTGV2ZWxJbmZvLmZyYW1lTGVuZ3RoL3RoaXMuYnVmZmVyTGV2ZWxJbmZvcy5sZW5ndGg7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBMZXZlbExpc3RlbmVyIHtcclxuICBjaGFubmVsQ291bnQ6IG51bWJlcjtcclxuXHJcbiAgdXBkYXRlKGxldmVsSW5mbzogTGV2ZWxJbmZvLCBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pOiB2b2lkO1xyXG5cclxuICBzdHJlYW1GaW5pc2hlZCgpOiB2b2lkO1xyXG5cclxuICByZXNldCgpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFBlYWtMZXZlbExpc3RlbmVyIHtcclxuICB1cGRhdGUocGVha0xldmVsOm51bWJlcik6IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGVha0xldmVsTGlzdGVuZXIge1xyXG5cclxuICB1cGRhdGUobGV2ZWxJbmZvOiBMZXZlbEluZm8sIHBlYWtMZXZlbEluZm86IExldmVsSW5mbyk6IHZvaWQ7XHJcblxyXG4gIHN0cmVhbUZpbmlzaGVkKCk6IHZvaWQ7XHJcblxyXG4gIHJlc2V0KCk6IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBQZWFrTGV2ZWxJbnRlcmNlcHRvciBpbXBsZW1lbnRzIExldmVsTGlzdGVuZXJ7XHJcbiAgZ2V0IHBlYWtEYkx2bCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BlYWtEYkx2bDtcclxuICB9XHJcbiAgZ2V0IGNoYW5uZWxDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2NoYW5uZWxDb3VudDtcclxuICB9XHJcblxyXG4gIHNldCBjaGFubmVsQ291bnQodmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5fY2hhbm5lbENvdW50ID0gdmFsdWU7XHJcbiAgICBpZih0aGlzLmxldmVsTGlzdGVuZXIpe1xyXG4gICAgICB0aGlzLmxldmVsTGlzdGVuZXIuY2hhbm5lbENvdW50PXZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hhbm5lbENvdW50OiBudW1iZXI9MDtcclxuXHJcbiAgcHJpdmF0ZSBfcGVha0RiTHZsID0gTUlOX0RCX0xFVkVMO1xyXG5cclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbGV2ZWxMaXN0ZW5lcj86TGV2ZWxMaXN0ZW5lcikge31cclxuXHJcbiAgdXBkYXRlKGxldmVsSW5mbzogTGV2ZWxJbmZvLCBwZWFrTGV2ZWxJbmZvOiBMZXZlbEluZm8pOiB2b2lke1xyXG4gICAgbGV0IHBlYWtEQlZhbCA9IGxldmVsSW5mby5wb3dlckxldmVsREIoKTtcclxuICAgIGlmICh0aGlzLnBlYWtEYkx2bCA8IHBlYWtEQlZhbCkge1xyXG4gICAgICB0aGlzLl9wZWFrRGJMdmwgPSBwZWFrREJWYWw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdHJlYW1GaW5pc2hlZCgpOiB2b2lke1xyXG4gICAgaWYodGhpcy5sZXZlbExpc3RlbmVyKXtcclxuICAgICAgdGhpcy5sZXZlbExpc3RlbmVyLnN0cmVhbUZpbmlzaGVkKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXNldCgpOiB2b2lke1xyXG4gICAgdGhpcy5fcGVha0RiTHZsID0gTUlOX0RCX0xFVkVMO1xyXG4gICAgaWYodGhpcy5sZXZlbExpc3RlbmVyKXtcclxuICAgICAgdGhpcy5sZXZlbExpc3RlbmVyLnJlc2V0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5kZWNsYXJlIGZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2U6IGFueSwgdHJhbnNmZXI/OiBBcnJheTxhbnk+KTogdm9pZDtcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgTGV2ZWxNZWFzdXJlIHtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSB3b3JrZXJVUkw6IHN0cmluZztcclxuICBwcml2YXRlIHdvcmtlcjogV29ya2VyfG51bGw9bnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLndvcmtlclVSTCA9IFdvcmtlckhlbHBlci5idWlsZFdvcmtlckJsb2JVUkwodGhpcy53b3JrZXJGdW5jdGlvbilcclxuICB9XHJcblxyXG4gIGNhbGNCdWZmZXJMZXZlbEluZm9zKGF1ZGlvQnVmZmVyOiBBdWRpb0J1ZmZlciwgYnVmZmVyVGltZUxlbmd0aDogbnVtYmVyKTogUHJvbWlzZTxMZXZlbEluZm9zPiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TGV2ZWxJbmZvcz4oKHJlc29sdmUpPT57XHJcbiAgICAgIGxldCBjaHMgPSBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xyXG4gICAgICBsZXQgYnVmZmVyRnJhbWVMZW5ndGg9TWF0aC5yb3VuZChhdWRpb0J1ZmZlci5zYW1wbGVSYXRlKmJ1ZmZlclRpbWVMZW5ndGgpO1xyXG4gICAgICBsZXQgYnVmZmVycyA9IG5ldyBBcnJheTxhbnk+KGNocyk7XHJcbiAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICBsZXQgYWRDaD1hdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgbGV0IGFkQ2hDb3B5PW5ldyBGbG9hdDMyQXJyYXkoYWRDaC5sZW5ndGgpO1xyXG4gICAgICAgIGFkQ2hDb3B5LnNldChhZENoKTtcclxuICAgICAgICBidWZmZXJzW2NoXSA9IGFkQ2hDb3B5LmJ1ZmZlcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy53b3JrZXIgPSBuZXcgV29ya2VyKHRoaXMud29ya2VyVVJMKTtcclxuICAgICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcblxyXG4gICAgICAgIGxldCBsaW5MZXZlbEFycnM9bmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICBsaW5MZXZlbEFycnNbY2hdID0gbmV3IEZsb2F0MzJBcnJheShtZS5kYXRhLmxpbkxldmVsQnVmZmVyc1tjaF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGJ1ZmZlckNvdW50PU1hdGguY2VpbChtZS5kYXRhLmZyYW1lTGVuZ3RoL21lLmRhdGEuYnVmZmVyRnJhbWVMZW5ndGgpO1xyXG4gICAgICAgIGxldCBmcmFtZVBvcz0wO1xyXG4gICAgICAgIGxldCBidWZmZXJMZXZlbEluZm9zPW5ldyBBcnJheTxMZXZlbEluZm8+KCk7XHJcbiAgICAgICAgbGV0IHBlYWtMZXZlbEluZm89bmV3IExldmVsSW5mbyhjaHMpO1xyXG4gICAgICAgIGZvcihsZXQgYmk9MDtiaTxidWZmZXJDb3VudDtiaSsrKSB7XHJcbiAgICAgICAgICBsZXQgbWluTGV2ZWxzID0gbmV3IEFycmF5PG51bWJlcj4oY2hzKTtcclxuICAgICAgICAgIGxldCBtYXhMZXZlbHMgPSBuZXcgQXJyYXk8bnVtYmVyPihjaHMpO1xyXG4gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICBsZXQgbGluTHZsQXJyUG9zPWJpKjI7XHJcbiAgICAgICAgICAgIG1pbkxldmVsc1tjaF09bGluTGV2ZWxBcnJzW2NoXVtsaW5MdmxBcnJQb3NdO1xyXG4gICAgICAgICAgICBtYXhMZXZlbHNbY2hdPWxpbkxldmVsQXJyc1tjaF1bbGluTHZsQXJyUG9zKzFdO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGV0IGJsaSA9IG5ldyBMZXZlbEluZm8oY2hzLCBmcmFtZVBvcywgbWUuZGF0YS5idWZmZXJGcmFtZUxlbmd0aCwgbWluTGV2ZWxzLCBtYXhMZXZlbHMpO1xyXG4gICAgICAgICAgYnVmZmVyTGV2ZWxJbmZvcy5wdXNoKGJsaSk7XHJcbiAgICAgICAgICBwZWFrTGV2ZWxJbmZvLm1lcmdlKGJsaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudGVybWluYXRlV29ya2VyKCk7XHJcbiAgICAgICAgcmVzb2x2ZShuZXcgTGV2ZWxJbmZvcyhidWZmZXJMZXZlbEluZm9zLCBwZWFrTGV2ZWxJbmZvKSk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aGlzLndvcmtlci5wb3N0TWVzc2FnZSh7YnVmZmVyRnJhbWVMZW5ndGg6YnVmZmVyRnJhbWVMZW5ndGgsYXVkaW9EYXRhOiBidWZmZXJzLCBjaHM6IGNoc30sIGJ1ZmZlcnMpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIHRlcm1pbmF0ZVdvcmtlcigpIHtcclxuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcclxuXHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZzpNZXNzYWdlRXZlbnQpIHtcclxuXHJcbiAgICAgIGxldCBjaHMgPSBtc2cuZGF0YS5jaHM7XHJcbiAgICAgIGxldCBidWZmZXJGcmFtZUxlbmd0aCA9IG1zZy5kYXRhLmJ1ZmZlckZyYW1lTGVuZ3RoO1xyXG5cclxuICAgICAgbGV0IGF1ZGlvRGF0YSA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgICAgIGxldCBsaW5MZXZlbHMgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG5cclxuICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgIGF1ZGlvRGF0YVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KG1zZy5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBmcmFtZUxlbmd0aCA9IGF1ZGlvRGF0YVswXS5sZW5ndGg7XHJcbiAgICAgIGxldCBidWZmZXJDb3VudD1NYXRoLmNlaWwoZnJhbWVMZW5ndGgvYnVmZmVyRnJhbWVMZW5ndGgpO1xyXG4gICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgbGluTGV2ZWxzW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyQ291bnQqMik7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGF1ZGlvRGF0YSAmJiBjaHMgPiAwKSB7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgbGV0IGNoRGF0YSA9IGF1ZGlvRGF0YVtjaF07XHJcblxyXG4gICAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBmcmFtZUxlbmd0aDsgcysrKSB7XHJcbiAgICAgICAgICAgIGxldCBiaSA9IE1hdGguZmxvb3IocyAvIGJ1ZmZlckZyYW1lTGVuZ3RoKTtcclxuICAgICAgICAgICAgbGV0IGx2bEFyclBvcyA9IGJpICogMjtcclxuICAgICAgICAgICAgLy9sZXQgYnMgPSBzICUgYnVmZmVyRnJhbWVMZW5ndGg7XHJcbiAgICAgICAgICAgIGxldCBjaFNhbXBsZT1jaERhdGFbc107XHJcbiAgICAgICAgICAgIGlmIChjaFNhbXBsZSA8IGxpbkxldmVsc1tjaF1bbHZsQXJyUG9zXSkge1xyXG4gICAgICAgICAgICAgIGxpbkxldmVsc1tjaF1bbHZsQXJyUG9zXSA9IGNoU2FtcGxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGx2bEFyclBvcysrO1xyXG4gICAgICAgICAgICBpZiAoY2hTYW1wbGUgPiBsaW5MZXZlbHNbY2hdW2x2bEFyclBvc10pIHtcclxuICAgICAgICAgICAgICBsaW5MZXZlbHNbY2hdW2x2bEFyclBvc10gPSBjaFNhbXBsZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBsaW5MZXZlbEJ1ZnMgPSBuZXcgQXJyYXk8YW55PihjaHMpO1xyXG4gICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgIGxpbkxldmVsQnVmc1tjaF0gPSBsaW5MZXZlbHNbY2hdLmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe2J1ZmZlckZyYW1lTGVuZ3RoOmJ1ZmZlckZyYW1lTGVuZ3RoLGZyYW1lTGVuZ3RoOmZyYW1lTGVuZ3RoLGxpbkxldmVsQnVmZmVyczogbGluTGV2ZWxCdWZzfSwgbGluTGV2ZWxCdWZzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBTdHJlYW1MZXZlbE1lYXN1cmUgaW1wbGVtZW50cyBTZXF1ZW5jZUF1ZGlvRmxvYXQzMk91dFN0cmVhbSB7XHJcblxyXG4gIGN1cnJlbnRMZXZlbEluZm9zOiBMZXZlbEluZm98bnVsbD1udWxsO1xyXG4gIHBlYWtMZXZlbEluZm86IExldmVsSW5mb3xudWxsPW51bGw7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2VyVVJMOiBzdHJpbmc7XHJcbiAgcHJpdmF0ZSB3b3JrZXI6IFdvcmtlcnxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBjaGFubmVsQ291bnQ6IG51bWJlcj0wO1xyXG4gIHByaXZhdGUgYnVmZmVySW5kZXg6IG51bWJlciA9IDA7XHJcbiAgcHJpdmF0ZSBmcmFtZUNvdW50OiBudW1iZXIgPSAwO1xyXG5cclxuICBsZXZlbExpc3RlbmVyOiBMZXZlbExpc3RlbmVyfG51bGw9bnVsbDtcclxuICBwZWFrTGV2ZWxMaXN0ZW5lcjogKChwZWFrTHZsSW5EYjpudW1iZXIpPT52b2lkKXxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBwZWFrTGV2ZWxJbkRiOm51bWJlcj1NSU5fREJfTEVWRUw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgdGhpcy53b3JrZXJVUkwgPSBXb3JrZXJIZWxwZXIuYnVpbGRXb3JrZXJCbG9iVVJMKHRoaXMud29ya2VyRnVuY3Rpb24pXHJcbiAgfVxyXG5cclxuICBzZXRGb3JtYXQoY2hhbm5lbHM6IG51bWJlciwgc2FtcGxlUmF0ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxzO1xyXG4gICAgdGhpcy5jdXJyZW50TGV2ZWxJbmZvcyA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgdGhpcy5wZWFrTGV2ZWxJbmZvID0gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIodGhpcy53b3JrZXJVUkwpO1xyXG4gICAgdGhpcy53b3JrZXIub25tZXNzYWdlID0gKG1lKSA9PiB7XHJcbiAgICAgIGxldCBzdHJlYW1GaW5pc2hlZCA9IG1lLmRhdGEuc3RyZWFtRmluaXNoZWQ7XHJcbiAgICAgIGlmIChzdHJlYW1GaW5pc2hlZCkge1xyXG4gICAgICAgIGlmICh0aGlzLmxldmVsTGlzdGVuZXIpIHtcclxuICAgICAgICAgIHRoaXMubGV2ZWxMaXN0ZW5lci5zdHJlYW1GaW5pc2hlZCgpXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICBsZXQgbWluTGV2ZWxzID0gbmV3IEFycmF5PG51bWJlcj4odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgICAgIGxldCBtYXhMZXZlbHMgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcbiAgICAgICAgICBsZXQgZmxzID0gbmV3IEZsb2F0MzJBcnJheShtZS5kYXRhLmxpbkxldmVsQnVmZmVyc1tjaF0pO1xyXG4gICAgICAgICAgbWluTGV2ZWxzW2NoXSA9IGZsc1swXTtcclxuICAgICAgICAgIG1heExldmVsc1tjaF0gPSBmbHNbMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBiaSA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQsIHRoaXMuZnJhbWVDb3VudCwgbWUuZGF0YS5mcmFlbUxlbmd0aCwgbWluTGV2ZWxzLCBtYXhMZXZlbHMpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlTGV2ZWxzKGJpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIG5leHRTdHJlYW0oKSB7XHJcbiAgICB0aGlzLnJlc2V0KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0KCkge1xyXG4gICAgdGhpcy5jdXJyZW50TGV2ZWxJbmZvcyA9IG5ldyBMZXZlbEluZm8odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgdGhpcy5wZWFrTGV2ZWxJbmZvID0gbmV3IExldmVsSW5mbyh0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICBpZiAodGhpcy5sZXZlbExpc3RlbmVyKSB7XHJcbiAgICAgIHRoaXMubGV2ZWxMaXN0ZW5lci5yZXNldCgpO1xyXG4gICAgICB0aGlzLmxldmVsTGlzdGVuZXIuY2hhbm5lbENvdW50ID0gdGhpcy5jaGFubmVsQ291bnQ7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5wZWFrTGV2ZWxMaXN0ZW5lcikge1xyXG4gICAgICB0aGlzLnBlYWtMZXZlbEluRGI9TUlOX0RCX0xFVkVMO1xyXG4gICAgICB0aGlzLnBlYWtMZXZlbExpc3RlbmVyKHRoaXMucGVha0xldmVsSW5EYik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB3cml0ZShidWZmZXJEYXRhOiBBcnJheTxGbG9hdDMyQXJyYXk+KTogbnVtYmVyIHtcclxuICAgIGxldCBidWZBcnJDb3BpZXMgPSBuZXcgQXJyYXk8RmxvYXQzMkFycmF5PihidWZmZXJEYXRhLmxlbmd0aCk7XHJcbiAgICBsZXQgYnVmZmVycyA9IG5ldyBBcnJheTxhbnk+KGJ1ZmZlckRhdGEubGVuZ3RoKTtcclxuICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBidWZmZXJEYXRhLmxlbmd0aDsgY2grKykge1xyXG4gICAgICBidWZBcnJDb3BpZXNbY2hdID0gYnVmZmVyRGF0YVtjaF0uc2xpY2UoKTtcclxuICAgICAgYnVmZmVyc1tjaF0gPSBidWZBcnJDb3BpZXNbY2hdLmJ1ZmZlcjtcclxuICAgIH1cclxuICAgIHRoaXMud29ya2VyPy5wb3N0TWVzc2FnZSh7XHJcbiAgICAgIHN0cmVhbUZpbmlzaGVkOiBmYWxzZSxcclxuICAgICAgYXVkaW9EYXRhOiBidWZmZXJzLFxyXG4gICAgICBjaHM6IHRoaXMuY2hhbm5lbENvdW50LFxyXG4gICAgICBidWZmZXJJbmRleDogdGhpcy5idWZmZXJJbmRleFxyXG4gICAgfSwgYnVmZmVycyk7XHJcbiAgICB0aGlzLmJ1ZmZlckluZGV4Kys7XHJcbiAgICByZXR1cm4gYnVmQXJyQ29waWVzWzBdLmxlbmd0aDtcclxuICB9XHJcblxyXG4gIGZsdXNoKCkge1xyXG4gICAgdGhpcy53b3JrZXI/LnBvc3RNZXNzYWdlKHtzdHJlYW1GaW5pc2hlZDogdHJ1ZX0pO1xyXG5cclxuICB9XHJcblxyXG4gIGNsb3NlKCkge1xyXG4gICAgICB0aGlzLndvcmtlcj8udGVybWluYXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqICBNZXRob2QgdXNlZCBhcyB3b3JrZXIgY29kZS5cclxuICAgKi9cclxuICB3b3JrZXJGdW5jdGlvbigpIHtcclxuICAgIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZzpNZXNzYWdlRXZlbnQpIHtcclxuICAgICAgbGV0IHN0cmVhbUZpbmlzaGVkID0gbXNnLmRhdGEuc3RyZWFtRmluaXNoZWQ7XHJcbiAgICAgIGlmIChzdHJlYW1GaW5pc2hlZCkge1xyXG4gICAgICAgIHBvc3RNZXNzYWdlKHtzdHJlYW1GaW5pc2hlZDogdHJ1ZX0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBjaHMgPSBtc2cuZGF0YS5jaHM7XHJcbiAgICAgICAgbGV0IGZyYW1lTGVuZ3RoID0gbnVsbDtcclxuICAgICAgICBsZXQgYXVkaW9EYXRhID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBsZXQgbGluTGV2ZWxzID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICBsaW5MZXZlbHNbY2hdID0gbmV3IEZsb2F0MzJBcnJheSgyKTtcclxuICAgICAgICAgIGF1ZGlvRGF0YVtjaF0gPSBuZXcgRmxvYXQzMkFycmF5KG1zZy5kYXRhLmF1ZGlvRGF0YVtjaF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGF1ZGlvRGF0YSkge1xyXG4gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICBsZXQgY2hEYXRhID0gYXVkaW9EYXRhW2NoXTtcclxuICAgICAgICAgICAgaWYgKGZyYW1lTGVuZ3RoID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgZnJhbWVMZW5ndGggPSBjaERhdGEubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgZnJhbWVMZW5ndGg7IHMrKykge1xyXG4gICAgICAgICAgICAgIGxldCBjaFNhbXBsZT1jaERhdGFbc107XHJcbiAgICAgICAgICAgICAgaWYgKGNoU2FtcGxlIDwgbGluTGV2ZWxzW2NoXVswXSkge1xyXG4gICAgICAgICAgICAgICAgbGluTGV2ZWxzW2NoXVswXSA9IGNoU2FtcGxlO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZiAoY2hTYW1wbGUgPiBsaW5MZXZlbHNbY2hdWzFdKSB7XHJcbiAgICAgICAgICAgICAgICBsaW5MZXZlbHNbY2hdWzFdID0gY2hTYW1wbGU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBsaW5MZXZlbEJ1ZnMgPSBuZXcgQXJyYXk8YW55PihjaHMpO1xyXG4gICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcclxuICAgICAgICAgIGxpbkxldmVsQnVmc1tjaF0gPSBsaW5MZXZlbHNbY2hdLmJ1ZmZlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe3N0cmVhbUZpbmlzaGVkOiBmYWxzZSwgZnJhbWVMZW5ndGg6IGZyYW1lTGVuZ3RoLCBsaW5MZXZlbEJ1ZmZlcnM6IGxpbkxldmVsQnVmc30sIGxpbkxldmVsQnVmcyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHVwZGF0ZUxldmVscyhidWZmZXJMZXZlbEluZm86IExldmVsSW5mbykge1xyXG5cclxuICAgIHRoaXMuY3VycmVudExldmVsSW5mb3MgPSBidWZmZXJMZXZlbEluZm87XHJcbiAgICBpZih0aGlzLnBlYWtMZXZlbEluZm8pIHtcclxuICAgICAgdGhpcy5wZWFrTGV2ZWxJbmZvLm1lcmdlKGJ1ZmZlckxldmVsSW5mbyk7XHJcbiAgICAgIGlmICh0aGlzLmxldmVsTGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLmxldmVsTGlzdGVuZXIudXBkYXRlKHRoaXMuY3VycmVudExldmVsSW5mb3MsIHRoaXMucGVha0xldmVsSW5mby5jbG9uZSgpKTtcclxuICAgICAgfVxyXG4gICAgICBpZih0aGlzLnBlYWtMZXZlbExpc3RlbmVyKXtcclxuICAgICAgICBsZXQgcGVha0RCVmFsID0gYnVmZmVyTGV2ZWxJbmZvLnBvd2VyTGV2ZWxEQigpO1xyXG4gICAgICAgIGlmICh0aGlzLnBlYWtMZXZlbEluRGIgPCBwZWFrREJWYWwpIHtcclxuICAgICAgICAgIHRoaXMucGVha0xldmVsSW5EYiA9IHBlYWtEQlZhbDtcclxuICAgICAgICAgIC8vIHRoZSBldmVudCBjb21lcyBmcm9tIG91dHNpZGUgb2YgYW4gQW5ndWxhciB6b25lXHJcbiAgICAgICAgICB0aGlzLnBlYWtMZXZlbExpc3RlbmVyKHRoaXMucGVha0xldmVsSW5EYik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgc3RvcCgpIHtcclxuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcclxuICB9XHJcblxyXG5cclxufVxyXG4iXX0=