speechrecorderng 3.4.5 → 3.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/esm2020/lib/audio/audio_player.mjs +13 -26
- package/esm2020/lib/audio/capture/capture.mjs +244 -207
- package/esm2020/lib/audio/context.mjs +64 -2
- package/esm2020/lib/audio/net_audio_buffer.mjs +5 -9
- package/esm2020/lib/audio/playback/player.mjs +137 -96
- package/esm2020/lib/audio/ui/audio_display_control.mjs +1 -1
- package/esm2020/lib/speechrecorder/project/project.mjs +1 -1
- package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +9 -8
- package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +38 -37
- package/esm2020/lib/speechrecorder/script/script.mjs +1 -1
- package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +28 -77
- package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +9 -2
- package/esm2020/lib/speechrecorder/session/controlpanel.mjs +14 -7
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +3 -3
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +1 -1
- package/esm2020/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +44 -47
- package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +11 -11
- package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +137 -88
- package/esm2020/lib/speechrecorderng.component.mjs +9 -15
- package/esm2020/lib/spr.module.version.mjs +2 -2
- package/fesm2015/speechrecorderng.mjs +767 -635
- package/fesm2015/speechrecorderng.mjs.map +1 -1
- package/fesm2020/speechrecorderng.mjs +764 -635
- package/fesm2020/speechrecorderng.mjs.map +1 -1
- package/lib/audio/audio_player.d.ts +0 -1
- package/lib/audio/capture/capture.d.ts +5 -4
- package/lib/audio/context.d.ts +2 -0
- package/lib/audio/net_audio_buffer.d.ts +2 -4
- package/lib/audio/playback/player.d.ts +3 -2
- package/lib/speechrecorder/project/project.d.ts +1 -0
- package/lib/speechrecorder/recordings/basic_recording.service.d.ts +2 -2
- package/lib/speechrecorder/recordings/recordings.service.d.ts +8 -8
- package/lib/speechrecorder/script/script.d.ts +1 -0
- package/lib/speechrecorder/session/basicrecorder.d.ts +3 -0
- package/lib/speechrecorder/session/controlpanel.d.ts +2 -0
- package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +1 -0
- package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +2 -2
- package/lib/speechrecorder/session/sessionmanager.d.ts +8 -1
- package/lib/spr.module.version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { AudioStorageType, Platform as CfgPlatform } from "../../speechrecorder/
|
|
|
3
3
|
import { ArrayAudioBuffer } from "../array_audio_buffer";
|
|
4
4
|
import { UUID } from "../../utils/utils";
|
|
5
5
|
import { IndexedDbAudioBuffer } from "../inddb_audio_buffer";
|
|
6
|
+
import { AudioContextProvider } from "../context";
|
|
6
7
|
export const CHROME_ACTIVATE_ECHO_CANCELLATION_WITH_AGC = false;
|
|
7
8
|
const DEBUG_TRACE_LEVEL = 0;
|
|
8
9
|
// Dirty way to load this module
|
|
@@ -82,8 +83,10 @@ const awpStr = "class AudioCaptureInterceptorProcessor extends AudioWorkletProce
|
|
|
82
83
|
"\n" +
|
|
83
84
|
"registerProcessor('capture-interceptor',AudioCaptureInterceptorProcessor);\n";
|
|
84
85
|
export class AudioCapture {
|
|
85
|
-
|
|
86
|
+
//private context:AudioContext|null=null;
|
|
87
|
+
constructor() {
|
|
86
88
|
this._maxAutoNetMemStoreSamples = AudioCapture.DEFAULT_MAX_NET_AUTO_MEM_STORE_SAMPLES;
|
|
89
|
+
this.context = null;
|
|
87
90
|
this._recUUID = null;
|
|
88
91
|
this.agcStatus = null;
|
|
89
92
|
this.bufferingNode = null;
|
|
@@ -98,13 +101,7 @@ export class AudioCapture {
|
|
|
98
101
|
this.persisted = true;
|
|
99
102
|
this.persistError = null;
|
|
100
103
|
this.inddbAudioBuffer = null;
|
|
101
|
-
this.context = context;
|
|
102
104
|
this.n = navigator;
|
|
103
|
-
this.context.addEventListener('statechange', () => {
|
|
104
|
-
if (this.context.state !== 'running') {
|
|
105
|
-
this.close();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
105
|
}
|
|
109
106
|
get maxAutoNetMemStoreSamples() {
|
|
110
107
|
return this._maxAutoNetMemStoreSamples;
|
|
@@ -133,6 +130,19 @@ export class AudioCapture {
|
|
|
133
130
|
get opened() {
|
|
134
131
|
return this._opened;
|
|
135
132
|
}
|
|
133
|
+
_audioContext() {
|
|
134
|
+
if (!this.context) {
|
|
135
|
+
this.context = AudioContextProvider.audioContextInstance();
|
|
136
|
+
if (this.context) {
|
|
137
|
+
this.context.addEventListener('statechange', () => {
|
|
138
|
+
if (this.context && this.context.state !== 'running') {
|
|
139
|
+
this.close();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return this.context;
|
|
145
|
+
}
|
|
136
146
|
initData() {
|
|
137
147
|
if (!this._recUUID) {
|
|
138
148
|
this._recUUID = UUID.generate();
|
|
@@ -247,119 +257,137 @@ export class AudioCapture {
|
|
|
247
257
|
}
|
|
248
258
|
}
|
|
249
259
|
addCaptureInterceptor() {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.listener
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
let chunk = new Array(chs);
|
|
272
|
-
const samples = this.framesRecorded * chs;
|
|
273
|
-
if ((AudioStorageType.MEM_ENTIRE_AUTO_NET_CHUNKED === this.audioStorageType || AudioStorageType.MEM_CHUNKED_AUTO_NET_CHUNKED === this.audioStorageType) && this.data && samples > this._maxAutoNetMemStoreSamples) {
|
|
274
|
-
this.data = null;
|
|
275
|
-
}
|
|
276
|
-
//console.debug("Data initialized: "+(this.data!=null));
|
|
277
|
-
for (let ch = 0; ch < chs; ch++) {
|
|
278
|
-
//console.debug("Data ch initialized: "+(this.data !=null && this.data[ch] !=null));
|
|
279
|
-
if (ch < this.channelCount) {
|
|
280
|
-
if (dt.data[ch]) {
|
|
281
|
-
let fa = new Float32Array(dt.data[ch]);
|
|
282
|
-
if (this.data && this.data[ch]) {
|
|
283
|
-
this.data[ch].push(fa);
|
|
284
|
-
}
|
|
285
|
-
chunk[ch] = fa;
|
|
286
|
-
// Use samples of channel 0 to count frames (samples)
|
|
287
|
-
if (ch == 0) {
|
|
288
|
-
this.framesRecorded += fa.length;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
260
|
+
if (this.context) {
|
|
261
|
+
const awn = new AudioWorkletNode(this.context, 'capture-interceptor');
|
|
262
|
+
awn.onprocessorerror = (ev) => {
|
|
263
|
+
let msg = 'Unknwon error';
|
|
264
|
+
if (ev instanceof ErrorEvent) {
|
|
265
|
+
msg = ev.message;
|
|
266
|
+
}
|
|
267
|
+
console.error("Capture audio worklet error: " + msg);
|
|
268
|
+
if (this.listener) {
|
|
269
|
+
this.listener.error(msg);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
let awnPt = awn.port;
|
|
273
|
+
if (awnPt) {
|
|
274
|
+
awnPt.onmessage = (ev) => {
|
|
275
|
+
if (this.capturing) {
|
|
276
|
+
let dt = ev.data;
|
|
277
|
+
let chs = dt.chs;
|
|
278
|
+
let adaLen = dt.data.length;
|
|
279
|
+
if (DEBUG_TRACE_LEVEL > 8) {
|
|
280
|
+
console.debug('Received data from worklet: ' + chs + ' ' + dt.len + ' Data chs: ' + adaLen);
|
|
291
281
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
this.
|
|
296
|
-
// // Random test error:
|
|
297
|
-
// if(Math.random()>0.98) {
|
|
298
|
-
// throw new Error('Test');
|
|
299
|
-
// }
|
|
282
|
+
let chunk = new Array(chs);
|
|
283
|
+
const samples = this.framesRecorded * chs;
|
|
284
|
+
if ((AudioStorageType.MEM_ENTIRE_AUTO_NET_CHUNKED === this.audioStorageType || AudioStorageType.MEM_CHUNKED_AUTO_NET_CHUNKED === this.audioStorageType) && this.data && samples > this._maxAutoNetMemStoreSamples) {
|
|
285
|
+
this.data = null;
|
|
300
286
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
287
|
+
//console.debug("Data initialized: "+(this.data!=null));
|
|
288
|
+
for (let ch = 0; ch < chs; ch++) {
|
|
289
|
+
//console.debug("Data ch initialized: "+(this.data !=null && this.data[ch] !=null));
|
|
290
|
+
if (ch < this.channelCount) {
|
|
291
|
+
if (dt.data[ch]) {
|
|
292
|
+
let fa = new Float32Array(dt.data[ch]);
|
|
293
|
+
if (this.data && this.data[ch]) {
|
|
294
|
+
this.data[ch].push(fa);
|
|
295
|
+
}
|
|
296
|
+
chunk[ch] = fa;
|
|
297
|
+
// Use samples of channel 0 to count frames (samples)
|
|
298
|
+
if (ch == 0) {
|
|
299
|
+
this.framesRecorded += fa.length;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
307
302
|
}
|
|
308
|
-
|
|
303
|
+
}
|
|
304
|
+
if (this.audioOutStream) {
|
|
309
305
|
try {
|
|
310
|
-
this.
|
|
306
|
+
this.audioOutStream.write(chunk);
|
|
307
|
+
// // Random test error:
|
|
308
|
+
// if(Math.random()>0.98) {
|
|
309
|
+
// throw new Error('Test');
|
|
310
|
+
// }
|
|
311
311
|
}
|
|
312
|
-
catch (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
finally {
|
|
316
|
-
if (this.listener) {
|
|
317
|
-
let errExpl = '';
|
|
318
|
-
if (err instanceof DOMException) {
|
|
319
|
-
errExpl = ': ' + err.name + ': ' + err.message;
|
|
320
|
-
}
|
|
321
|
-
this.listener.error("Could not handle recorded audio data" + errExpl, "Please try to record again.");
|
|
312
|
+
catch (err) {
|
|
313
|
+
if (err instanceof Error) {
|
|
314
|
+
this.persistError = err;
|
|
322
315
|
}
|
|
323
316
|
else {
|
|
324
|
-
this.
|
|
317
|
+
this.persistError = new Error('Error handling recorded audio data');
|
|
318
|
+
}
|
|
319
|
+
console.error("Capture error: " + err);
|
|
320
|
+
try {
|
|
321
|
+
this.stop();
|
|
322
|
+
}
|
|
323
|
+
catch (err2) {
|
|
324
|
+
console.error("Capture next error (ignored): " + err2);
|
|
325
|
+
}
|
|
326
|
+
finally {
|
|
327
|
+
if (this.listener) {
|
|
328
|
+
let errExpl = '';
|
|
329
|
+
if (err instanceof DOMException) {
|
|
330
|
+
errExpl = ': ' + err.name + ': ' + err.message;
|
|
331
|
+
}
|
|
332
|
+
this.listener.error("Could not handle recorded audio data" + errExpl, "Please try to record again.");
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.close();
|
|
336
|
+
}
|
|
325
337
|
}
|
|
326
338
|
}
|
|
327
339
|
}
|
|
340
|
+
if (AudioStorageType.DB_CHUNKED === this._audioStorageType && this._persistentAudioStorageTarget) {
|
|
341
|
+
this.store();
|
|
342
|
+
}
|
|
328
343
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
this._opened = true;
|
|
343
|
-
if (this.listener) {
|
|
344
|
-
this.listener.opened();
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
// Tried to fix that Safari does not record the second channel
|
|
347
|
+
// Does not help
|
|
348
|
+
//awn.channelCount=this.channelCount;
|
|
349
|
+
//awn.channelCountMode='explicit';
|
|
350
|
+
//console.debug('Channel count explicitly set to '+this.channelCount);
|
|
351
|
+
this.bufferingNode = awn;
|
|
352
|
+
//this.bufferingNode.channelCount=this.channelCount;
|
|
353
|
+
this._opened = true;
|
|
354
|
+
if (this.listener) {
|
|
355
|
+
this.listener.opened();
|
|
356
|
+
}
|
|
345
357
|
}
|
|
346
358
|
}
|
|
347
|
-
open(channelCount, selDeviceId, autoGainControlConfigs) {
|
|
359
|
+
open(channelCount, selDeviceId, autoGainControlConfigs, allowEchoCancellation) {
|
|
348
360
|
//console.debug("Capture open: ctx state: "+this.context.state);
|
|
349
|
-
|
|
361
|
+
this.context = this._audioContext();
|
|
362
|
+
if (!this.context) {
|
|
363
|
+
throw new Error("Could not get audio context!");
|
|
364
|
+
}
|
|
365
|
+
if (this.context.state === 'suspended') {
|
|
350
366
|
//console.debug("Capture open: Resume context");
|
|
351
367
|
this.context.resume().then(() => {
|
|
352
368
|
//console.debug("Capture open (ctx resumed): ctx state: "+this.context.state);
|
|
353
|
-
this._open(channelCount, selDeviceId, autoGainControlConfigs);
|
|
369
|
+
this._open(channelCount, selDeviceId, autoGainControlConfigs, allowEchoCancellation);
|
|
370
|
+
}).catch((err) => {
|
|
371
|
+
console.error(err.message);
|
|
372
|
+
throw err;
|
|
354
373
|
});
|
|
355
374
|
}
|
|
375
|
+
else if (this.context.state === 'closed') {
|
|
376
|
+
const msg = 'Error on start capture: The audio context is already closed.';
|
|
377
|
+
console.error(msg);
|
|
378
|
+
throw new Error(msg);
|
|
379
|
+
}
|
|
356
380
|
else {
|
|
357
|
-
this._open(channelCount, selDeviceId, autoGainControlConfigs);
|
|
381
|
+
this._open(channelCount, selDeviceId, autoGainControlConfigs, allowEchoCancellation);
|
|
358
382
|
}
|
|
359
383
|
}
|
|
360
|
-
_open(channelCount, selDeviceId, autoGainControlConfigs) {
|
|
384
|
+
_open(channelCount, selDeviceId, autoGainControlConfigs, allowEchoCancellation) {
|
|
361
385
|
this.channelCount = channelCount;
|
|
362
386
|
this.framesRecorded = 0;
|
|
387
|
+
this.context = this._audioContext();
|
|
388
|
+
if (!this.context) {
|
|
389
|
+
throw new Error("Could not get audio context!");
|
|
390
|
+
}
|
|
363
391
|
//var msc = new AudioStreamConstr();
|
|
364
392
|
// var msc={};
|
|
365
393
|
//msc.video = false;
|
|
@@ -467,7 +495,7 @@ export class AudioCapture {
|
|
|
467
495
|
audio: {
|
|
468
496
|
deviceId: selDeviceId,
|
|
469
497
|
channelCount: channelCount,
|
|
470
|
-
|
|
498
|
+
echoCancellation: allowEchoCancellation ? undefined : false
|
|
471
499
|
},
|
|
472
500
|
video: false,
|
|
473
501
|
};
|
|
@@ -478,106 +506,109 @@ export class AudioCapture {
|
|
|
478
506
|
console.debug("Audio capture, AGC: " + this.agcStatus);
|
|
479
507
|
let ump = navigator.mediaDevices.getUserMedia(msc);
|
|
480
508
|
ump.then((s) => {
|
|
481
|
-
this.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
let
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
509
|
+
if (this.context) {
|
|
510
|
+
this.stream = s;
|
|
511
|
+
let aTracks = s.getAudioTracks();
|
|
512
|
+
for (let i = 0; i < aTracks.length; i++) {
|
|
513
|
+
let aTrack = aTracks[i];
|
|
514
|
+
console.info("Track audio info: id: " + aTrack.id + " kind: " + aTrack.kind + " label: \"" + aTrack.label + "\"");
|
|
515
|
+
let mtrSts = aTrack.getSettings();
|
|
516
|
+
// Typescript lib.dom.ts MediaTrackSettings.channelCount is missing
|
|
517
|
+
// https://github.com/mdn/browser-compat-data/blob/5493d8f937e05b2ddbd41b99f5bdfad4a1f2ed85/api/MediaTrackSettings.json
|
|
518
|
+
//@ts-ignore
|
|
519
|
+
console.info("Track audio settings: Ch cnt: " + mtrSts.channelCount + ", AGC: " + mtrSts.autoGainControl + ", Echo cancell.: " + mtrSts.echoCancellation);
|
|
520
|
+
if (mtrSts.autoGainControl) {
|
|
521
|
+
this.agcStatus = mtrSts.autoGainControl;
|
|
522
|
+
}
|
|
523
|
+
console.debug("Echo cancellation: " + mtrSts.echoCancellation);
|
|
493
524
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
console.info("Track video info: id: " + vTrack.id + " kind: " + vTrack.kind + " label: " + vTrack.label);
|
|
499
|
-
}
|
|
500
|
-
this.mediaStream = this.context.createMediaStreamSource(s);
|
|
501
|
-
// stream channel count ( is always 2 !)
|
|
502
|
-
let streamChannelCount = this.mediaStream.channelCount;
|
|
503
|
-
console.info("Stream channel count: " + streamChannelCount);
|
|
504
|
-
// is not set!!
|
|
505
|
-
//this.currentSampleRate = this.mediaStream.sampleRate;
|
|
506
|
-
this.currentSampleRate = this.context.sampleRate;
|
|
507
|
-
console.info("Source audio node: channels: " + streamChannelCount + " samplerate: " + this.currentSampleRate);
|
|
508
|
-
if (this.audioOutStream) {
|
|
509
|
-
this.audioOutStream.setFormat(this.channelCount, this.currentSampleRate);
|
|
510
|
-
}
|
|
511
|
-
// W3C -> new name is createScriptProcessor
|
|
512
|
-
//
|
|
513
|
-
// Again deprecated, but AudioWorker not yet implemented in stable releases (June 2016)
|
|
514
|
-
// AudioWorker is now AudioWorkletProcessor ... (May 2017)
|
|
515
|
-
// Update 12-2020:
|
|
516
|
-
// The ScriptProcessorNode Interface - DEPRECATED
|
|
517
|
-
// Update 06-2021
|
|
518
|
-
// AudioWorkletProcessor is here to stay. Web Audio API has now Recommendation status !
|
|
519
|
-
if (this.context.audioWorklet) {
|
|
520
|
-
//const workletFileName = ('file-loader!./interceptor_worklet.js');
|
|
521
|
-
//const workletFileName = 'http://localhost:4200/assets/interceptor_worklet.js';
|
|
522
|
-
//console.log(awpStr);
|
|
523
|
-
if (AudioCapture.captureInterceptorModuleRegistered) {
|
|
524
|
-
// Required capture interceptor module already registered
|
|
525
|
-
this.addCaptureInterceptor();
|
|
525
|
+
let vTracks = s.getVideoTracks();
|
|
526
|
+
for (let i = 0; i < vTracks.length; i++) {
|
|
527
|
+
let vTrack = vTracks[i];
|
|
528
|
+
console.info("Track video info: id: " + vTrack.id + " kind: " + vTrack.kind + " label: " + vTrack.label);
|
|
526
529
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
530
|
+
this.mediaStream = this.context.createMediaStreamSource(s);
|
|
531
|
+
// stream channel count ( is always 2 !)
|
|
532
|
+
let streamChannelCount = this.mediaStream.channelCount;
|
|
533
|
+
console.info("Stream channel count: " + streamChannelCount);
|
|
534
|
+
// is not set!!
|
|
535
|
+
//this.currentSampleRate = this.mediaStream.sampleRate;
|
|
536
|
+
this.currentSampleRate = this.context.sampleRate;
|
|
537
|
+
console.info("Source audio node: channels: " + streamChannelCount + " samplerate: " + this.currentSampleRate);
|
|
538
|
+
if (this.audioOutStream) {
|
|
539
|
+
this.audioOutStream.setFormat(this.channelCount, this.currentSampleRate);
|
|
540
|
+
}
|
|
541
|
+
// W3C -> new name is createScriptProcessor
|
|
542
|
+
//
|
|
543
|
+
// Again deprecated, but AudioWorker not yet implemented in stable releases (June 2016)
|
|
544
|
+
// AudioWorker is now AudioWorkletProcessor ... (May 2017)
|
|
545
|
+
// Update 12-2020:
|
|
546
|
+
// The ScriptProcessorNode Interface - DEPRECATED
|
|
547
|
+
// Update 06-2021
|
|
548
|
+
// AudioWorkletProcessor is here to stay. Web Audio API has now Recommendation status !
|
|
549
|
+
if (this.context.audioWorklet) {
|
|
550
|
+
//const workletFileName = ('file-loader!./interceptor_worklet.js');
|
|
551
|
+
//const workletFileName = 'http://localhost:4200/assets/interceptor_worklet.js';
|
|
552
|
+
//console.log(awpStr);
|
|
553
|
+
if (AudioCapture.captureInterceptorModuleRegistered) {
|
|
554
|
+
// Required capture interceptor module already registered
|
|
533
555
|
this.addCaptureInterceptor();
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
// Register capture interceptor module
|
|
559
|
+
let audioWorkletModuleBlob = new Blob([awpStr], { type: 'text/javascript' });
|
|
560
|
+
let audioWorkletModuleBlobUrl = window.URL.createObjectURL(audioWorkletModuleBlob);
|
|
561
|
+
this.context.audioWorklet.addModule(audioWorkletModuleBlobUrl).then(() => {
|
|
562
|
+
AudioCapture.captureInterceptorModuleRegistered = true;
|
|
563
|
+
this.addCaptureInterceptor();
|
|
564
|
+
}).catch((error) => {
|
|
565
|
+
console.log('Could not add module ' + error);
|
|
566
|
+
});
|
|
567
|
+
}
|
|
537
568
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
569
|
+
else if (this.context.createScriptProcessor) {
|
|
570
|
+
// The ScriptProcessorNode Interface - DEPRECATED Only as fallback
|
|
571
|
+
// TODO should we use streamChannelCount or channelCount here ?
|
|
572
|
+
let scriptProcessorNode = this.context.createScriptProcessor(AudioCapture.BUFFER_SIZE, streamChannelCount, streamChannelCount);
|
|
573
|
+
this.bufferingNode = scriptProcessorNode;
|
|
574
|
+
let c = 0;
|
|
575
|
+
if (scriptProcessorNode.onaudioprocess) {
|
|
576
|
+
scriptProcessorNode.onaudioprocess = (e) => {
|
|
577
|
+
if (this.capturing) {
|
|
578
|
+
let inBuffer = e.inputBuffer;
|
|
579
|
+
// only process requested count of channels
|
|
580
|
+
let currentBuffers = new Array(channelCount);
|
|
581
|
+
for (let ch = 0; ch < channelCount; ch++) {
|
|
582
|
+
let chSamples = inBuffer.getChannelData(ch);
|
|
583
|
+
let chSamplesCopy = chSamples.slice(0);
|
|
584
|
+
currentBuffers[ch] = chSamplesCopy.slice(0);
|
|
585
|
+
if (this.data) {
|
|
586
|
+
this.data[ch].push(chSamplesCopy);
|
|
587
|
+
}
|
|
588
|
+
if (DEBUG_TRACE_LEVEL > 8) {
|
|
589
|
+
console.debug("Process " + chSamplesCopy.length + " samples.");
|
|
590
|
+
}
|
|
591
|
+
this.framesRecorded += chSamplesCopy.length;
|
|
557
592
|
}
|
|
558
|
-
|
|
559
|
-
|
|
593
|
+
c++;
|
|
594
|
+
if (this.audioOutStream) {
|
|
595
|
+
this.audioOutStream.write(currentBuffers);
|
|
560
596
|
}
|
|
561
|
-
this.framesRecorded += chSamplesCopy.length;
|
|
562
|
-
}
|
|
563
|
-
c++;
|
|
564
|
-
if (this.audioOutStream) {
|
|
565
|
-
this.audioOutStream.write(currentBuffers);
|
|
566
597
|
}
|
|
598
|
+
};
|
|
599
|
+
this._opened = true;
|
|
600
|
+
if (this.listener) {
|
|
601
|
+
this.listener.opened();
|
|
567
602
|
}
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
this.listener.opened();
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
this.listener.error('Browser does not support audio processing (ScriptProcessor.onaudioprocess method not found)!');
|
|
572
606
|
}
|
|
573
607
|
}
|
|
574
608
|
else {
|
|
575
|
-
this.listener.error('Browser does not support audio processing (
|
|
609
|
+
this.listener.error('Browser does not support audio processing (neither AudioWorkletProcessor nor ScriptProcessor)!');
|
|
576
610
|
}
|
|
577
611
|
}
|
|
578
|
-
else {
|
|
579
|
-
this.listener.error('Browser does not support audio processing (neither AudioWorkletProcessor nor ScriptProcessor)!');
|
|
580
|
-
}
|
|
581
612
|
}, (e) => {
|
|
582
613
|
console.error(e + " Error name: " + e.name);
|
|
583
614
|
if (this.listener) {
|
|
@@ -598,36 +629,42 @@ export class AudioCapture {
|
|
|
598
629
|
});
|
|
599
630
|
}
|
|
600
631
|
_start() {
|
|
601
|
-
this.
|
|
602
|
-
|
|
603
|
-
this.audioOutStream
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
this.listener
|
|
632
|
+
if (this.context) {
|
|
633
|
+
this.initData();
|
|
634
|
+
if (this.audioOutStream) {
|
|
635
|
+
this.audioOutStream.nextStream();
|
|
636
|
+
}
|
|
637
|
+
this.capturing = true;
|
|
638
|
+
if (this.bufferingNode) {
|
|
639
|
+
this.mediaStream.connect(this.bufferingNode);
|
|
640
|
+
this.bufferingNode.connect(this.context.destination);
|
|
641
|
+
}
|
|
642
|
+
if (this.listener) {
|
|
643
|
+
this.listener.started();
|
|
644
|
+
}
|
|
612
645
|
}
|
|
613
646
|
}
|
|
614
647
|
start() {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
}
|
|
619
|
-
else {
|
|
620
|
-
console.debug("Capture start: audio context not running, state: " + aSt + ", resuming...");
|
|
621
|
-
this.context.resume().then(() => {
|
|
622
|
-
console.debug("Capture start: audio context resumed, starting...");
|
|
648
|
+
if (this.context) {
|
|
649
|
+
const aSt = this.context.state;
|
|
650
|
+
if (aSt === 'running') {
|
|
623
651
|
this._start();
|
|
624
|
-
}
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
console.debug("Capture start: audio context not running, state: " + aSt + ", resuming...");
|
|
655
|
+
this.context.resume().then(() => {
|
|
656
|
+
console.debug("Capture start: audio context resumed, starting...");
|
|
657
|
+
this._start();
|
|
658
|
+
});
|
|
659
|
+
}
|
|
625
660
|
}
|
|
626
661
|
}
|
|
627
662
|
stop() {
|
|
628
663
|
if (this.disconnectStreams && this.bufferingNode) {
|
|
629
664
|
this.mediaStream.disconnect(this.bufferingNode);
|
|
630
|
-
|
|
665
|
+
if (this.context) {
|
|
666
|
+
this.bufferingNode.disconnect(this.context.destination);
|
|
667
|
+
}
|
|
631
668
|
}
|
|
632
669
|
try {
|
|
633
670
|
if (this.audioOutStream) {
|
|
@@ -750,7 +787,7 @@ export class AudioCapture {
|
|
|
750
787
|
}
|
|
751
788
|
audioBuffer() {
|
|
752
789
|
let ab = null;
|
|
753
|
-
if (this.data) {
|
|
790
|
+
if (this.context && this.data) {
|
|
754
791
|
let frameLen = 0;
|
|
755
792
|
let ch0Data = this.data[0];
|
|
756
793
|
for (let ch0Chk of ch0Data) {
|
|
@@ -815,4 +852,4 @@ export class AudioCapture {
|
|
|
815
852
|
AudioCapture.BUFFER_SIZE = 8192;
|
|
816
853
|
AudioCapture.DEFAULT_MAX_NET_AUTO_MEM_STORE_SAMPLES = 2880000 * 5; // Default 5 minute at 48kHz
|
|
817
854
|
AudioCapture.captureInterceptorModuleRegistered = false;
|
|
818
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwdHVyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9jYXB0dXJlL2NhcHR1cmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQXlCLFFBQVEsSUFBSSxXQUFXLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUN0SCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxFQUFDLG9CQUFvQixFQUErQixNQUFNLHVCQUF1QixDQUFDO0FBR3pGLE1BQU0sQ0FBQyxNQUFNLDBDQUEwQyxHQUFDLEtBQUssQ0FBQztBQUU5RCxNQUFNLGlCQUFpQixHQUFDLENBQUMsQ0FBQztBQUUxQixnQ0FBZ0M7QUFDaEMsd0RBQXdEO0FBQ3hELE1BQU0sTUFBTSxHQUFDLHlFQUF5RTtJQUNsRixJQUFJO0lBQ0osMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QixxRUFBcUU7SUFDckUsb0JBQW9CO0lBQ3BCLG9CQUFvQjtJQUNwQix5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLG9CQUFvQjtJQUNwQixJQUFJO0lBQ0osU0FBUztJQUNULElBQUk7SUFDSixhQUFhO0lBQ2IsaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixvQkFBb0I7SUFDcEIsUUFBUTtJQUNSLElBQUk7SUFDSixxQ0FBcUM7SUFDckMsNEJBQTRCO0lBQzVCLHdCQUF3QjtJQUN4Qiw2QkFBNkI7SUFDN0IsMEJBQTBCO0lBQzFCLG9DQUFvQztJQUNwQywwQ0FBMEM7SUFDMUMsb0NBQW9DO0lBQ3BDLHlDQUF5QztJQUN6QywyQ0FBMkM7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LEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDcEIsR0FBRyxJQUFJLE1BQU0sQ0FBQztpQkFDZjthQUNGO1NBQ0Y7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxnQkFBZ0I7UUFDWixJQUFJLEtBQUssR0FBdUIsSUFBSSxDQUFDO1FBQ3JDLElBQUcsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNaLEtBQUssR0FBQyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNsRjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxxQkFBcUI7UUFDbkIsSUFBRyxJQUFJLENBQUMsWUFBWSxFQUFDO1lBQ25CLE9BQU8sSUFBSSxDQUFDO1NBQ2I7YUFBSztZQUNKLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1NBQzlCO0lBQ0gsQ0FBQzs7QUE1dkJNLHdCQUFXLEdBQVcsSUFBSSxDQUFDO0FBQ1YsbURBQXNDLEdBQVEsT0FBTyxHQUFDLENBQUMsQ0FBQyxDQUFDLDRCQUE0QjtBQUU5RiwrQ0FBa0MsR0FBQyxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1NlcXVlbmNlQXVkaW9GbG9hdDMyT3V0U3RyZWFtfSBmcm9tIFwiLi4vaW8vc3RyZWFtXCI7XHJcbmltcG9ydCB7QnJvd3NlciwgUGxhdGZvcm0sIFVzZXJBZ2VudEJ1aWxkZXJ9IGZyb20gXCIuLi8uLi91dGlscy91YS1wYXJzZXJcIjtcclxuXHJcbmltcG9ydCB7QXVkaW9TdG9yYWdlVHlwZSwgQXV0b0dhaW5Db250cm9sQ29uZmlnLCBQbGF0Zm9ybSBhcyBDZmdQbGF0Zm9ybX0gZnJvbSBcIi4uLy4uL3NwZWVjaHJlY29yZGVyL3Byb2plY3QvcHJvamVjdFwiO1xyXG5pbXBvcnQge0FycmF5QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJcIjtcclxuaW1wb3J0IHtVVUlEfSBmcm9tIFwiLi4vLi4vdXRpbHMvdXRpbHNcIjtcclxuaW1wb3J0IHtJbmRleGVkRGJBdWRpb0J1ZmZlciwgUGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldH0gZnJvbSBcIi4uL2luZGRiX2F1ZGlvX2J1ZmZlclwiO1xyXG5cclxuXHJcbmV4cG9ydCBjb25zdCBDSFJPTUVfQUNUSVZBVEVfRUNIT19DQU5DRUxMQVRJT05fV0lUSF9BR0M9ZmFsc2U7XHJcblxyXG5jb25zdCBERUJVR19UUkFDRV9MRVZFTD0wO1xyXG5cclxuLy8gRGlydHkgd2F5IHRvIGxvYWQgdGhpcyBtb2R1bGVcclxuLy8gQ29weSBjb250ZW50IG9mIGludGVyY2VwdG9yX3dvcmtsZXQuanMgdG8gdGhpcyBzdHJpbmdcclxuY29uc3QgYXdwU3RyPVwiY2xhc3MgQXVkaW9DYXB0dXJlSW50ZXJjZXB0b3JQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICBCVUZGRVJfUVVBTlRVTVM9NjQ7XFxuXCIgK1xyXG4gICAgXCIgICAgUVVBTlRVTV9GUkFNRV9MRU49MTI4O1xcblwiICtcclxuICAgIFwiICAgIEJVRkZFUl9GUkFNRV9MRU49dGhpcy5RVUFOVFVNX0ZSQU1FX0xFTip0aGlzLkJVRkZFUl9RVUFOVFVNUztcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXI9bnVsbDtcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXJQb3M9MDtcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXJQb3NCeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgIGNvbnN0cnVjdG9yKCkge1xcblwiICtcclxuICAgIFwiICAgICAgICBzdXBlcigpO1xcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgfVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgcHJvY2VzcyhcXG5cIiArXHJcbiAgICBcIiAgICAgIGlucHV0cyxcXG5cIiArXHJcbiAgICBcIiAgICAgIG91dHB1dHMsXFxuXCIgK1xyXG4gICAgXCIgICAgICBwYXJhbWV0ZXJzXFxuXCIgK1xyXG4gICAgXCIgICl7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICAgbGV0IGlucHV0c0NudD1pbnB1dHMubGVuZ3RoO1xcblwiICtcclxuICAgIFwiICAgICBsZXQgY2hhbm5lbENvdW50PTA7XFxuXCIgK1xyXG4gICAgXCIgICAgIGxldCBpbnB1dExlbj0wO1xcblwiICtcclxuICAgIFwiICAgICBsZXQgaW5wdXRMZW5CeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgICBpZihpbnB1dHNDbnQ+MCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgbGV0IGlucHV0MCA9IGlucHV0c1swXTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIGNoYW5uZWxDb3VudCA9IGlucHV0MC5sZW5ndGg7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICBpZiAoY2hhbm5lbENvdW50ID4gMCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGxldCBpbnB1dDBjaDA9aW5wdXQwWzBdO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGlucHV0TGVuPWlucHV0MGNoMC5sZW5ndGg7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgaW5wdXRMZW5CeXRlcz1pbnB1dDBjaDAuYnVmZmVyLmxlbmd0aDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgICBpZiAoIXRoaXMuYnVmZmVyIHx8IHRoaXMuYnVmZmVyLmxlbmd0aCA8IGNoYW5uZWxDb3VudCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXkoY2hhbm5lbENvdW50KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIHRoaXMuYnVmZmVyUG9zID0gMFxcblwiICtcclxuICAgIFwiICAgICAgICAgZm9yIChsZXQgYmNoID0gMDsgYmNoIDwgY2hhbm5lbENvdW50OyBiY2grKykge1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIHRoaXMuYnVmZmVyW2JjaF0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuQlVGRkVSX0ZSQU1FX0xFTik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgdGhpcy5idWZmZXJQb3MgPSAwO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIHRoaXMuYnVmZmVyUG9zQnl0ZXM9MDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgICBsZXQgYnVmQXZhaWwgPSB0aGlzLkJVRkZFUl9GUkFNRV9MRU4gLSB0aGlzLmJ1ZmZlclBvcztcXG5cIiArXHJcbiAgICBcIiAgICAgLy8gY2hlY2sgaWYgYnVmZmVyIGhhcyB0byBiZSB0cmFuc2ZlcnJlZFxcblwiICtcclxuICAgIFwiICAgICBpZiAoaW5wdXRMZW4gPiBidWZBdmFpbCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgbGV0IGFkYT1uZXcgQXJyYXkoY2hhbm5lbENvdW50KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaGFubmVsQ291bnQ7IGNoKyspIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBhZGFbY2hdPXRoaXMuYnVmZmVyW2NoXS5idWZmZXIuc2xpY2UoMCk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGRhdGE6IGFkYSxcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBjaHM6IGNoYW5uZWxDb3VudCxcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBsZW46IHRoaXMuYnVmZmVyUG9zXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB9LCBhZGEpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgLy8gYnVmZmVyIHRyYW5zZmVycmVkLCByZXNldFxcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3MgPSAwO1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3NCeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgICB9XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICAgZm9yKGxldCBpaT0wO2lpPGlucHV0c0NudDtpaSsrKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hhbm5lbENvdW50OyBjaCsrKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgLy8gTXV0ZSBvdXRwdXRzXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgLy9vdXRwdXRzW2lpXVtjaF0uZmlsbCgwKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBsZXQgY2hTYW1wbGVzID0gaW5wdXRzW2lpXVtjaF07XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgdGhpcy5idWZmZXJbY2hdLnNldChjaFNhbXBsZXMsdGhpcy5idWZmZXJQb3MpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgfVxcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3MrPWlucHV0TGVuO1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3NCeXRlcys9aW5wdXRMZW5CeXRlcztcXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgIFxcblwiICtcclxuICAgIFwiICAgICByZXR1cm4gdHJ1ZTtcXG5cIiArXHJcbiAgICBcIiAgfVxcblwiICtcclxuICAgIFwifVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCJyZWdpc3RlclByb2Nlc3NvcignY2FwdHVyZS1pbnRlcmNlcHRvcicsQXVkaW9DYXB0dXJlSW50ZXJjZXB0b3JQcm9jZXNzb3IpO1xcblwiO1xyXG5cclxuXHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBBdWRpb0NhcHR1cmVMaXN0ZW5lciB7XHJcbiAgb3BlbmVkKCk6IHZvaWQ7XHJcblxyXG4gIHN0YXJ0ZWQoKTogdm9pZDtcclxuXHJcbiAgc3RvcHBlZCgpOiB2b2lkO1xyXG5cclxuICBjbG9zZWQoKTogdm9pZDtcclxuXHJcbiAgZXJyb3IobXNnPzpzdHJpbmcsYWR2aWNlPzpzdHJpbmcpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQXVkaW9DYXB0dXJlIHtcclxuXHJcbiAgZ2V0IG1heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9tYXhBdXRvTmV0TWVtU3RvcmVTYW1wbGVzO1xyXG4gIH1cclxuXHJcbiAgc2V0IG1heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXModmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5fbWF4QXV0b05ldE1lbVN0b3JlU2FtcGxlcyA9IHZhbHVlO1xyXG4gIH1cclxuICBzZXQgcmVjVVVJRCh2YWx1ZTogc3RyaW5nfG51bGwpIHtcclxuICAgIHRoaXMuX3JlY1VVSUQgPSB2YWx1ZTtcclxuICB9XHJcbiAgZ2V0IHJlY1VVSUQoKTogc3RyaW5nIHxudWxse1xyXG4gICAgcmV0dXJuIHRoaXMuX3JlY1VVSUQ7XHJcbiAgfVxyXG4gIGdldCBhdWRpb1N0b3JhZ2VUeXBlKCk6IEF1ZGlvU3RvcmFnZVR5cGUge1xyXG4gICAgcmV0dXJuIHRoaXMuX2F1ZGlvU3RvcmFnZVR5cGU7XHJcbiAgfVxyXG5cclxuICBzZXQgYXVkaW9TdG9yYWdlVHlwZSh2YWx1ZTogQXVkaW9TdG9yYWdlVHlwZSkge1xyXG4gICAgdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSA9IHZhbHVlO1xyXG4gIH1cclxuICBnZXQgcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCgpOiBQZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0IHwgbnVsbCB7XHJcbiAgICByZXR1cm4gdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldDtcclxuICB9XHJcblxyXG4gIHNldCBwZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0KHZhbHVlOiBQZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0IHwgbnVsbCkge1xyXG4gICAgdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgZ2V0IG9wZW5lZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9vcGVuZWQ7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgQlVGRkVSX1NJWkU6IG51bWJlciA9IDgxOTI7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9NQVhfTkVUX0FVVE9fTUVNX1NUT1JFX1NBTVBMRVM6bnVtYmVyPTI4ODAwMDAqNTsgLy8gRGVmYXVsdCA1IG1pbnV0ZSBhdCA0OGtIelxyXG4gIHByaXZhdGUgX21heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXM6bnVtYmVyPUF1ZGlvQ2FwdHVyZS5ERUZBVUxUX01BWF9ORVRfQVVUT19NRU1fU1RPUkVfU0FNUExFUztcclxuICBwcml2YXRlIHN0YXRpYyBjYXB0dXJlSW50ZXJjZXB0b3JNb2R1bGVSZWdpc3RlcmVkPWZhbHNlO1xyXG4gIGNvbnRleHQ6IEF1ZGlvQ29udGV4dDtcclxuICBzdHJlYW0hOiBNZWRpYVN0cmVhbTtcclxuICBjaGFubmVsQ291bnQhOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBfcmVjVVVJRDpzdHJpbmd8bnVsbD1udWxsO1xyXG4gIG1lZGlhU3RyZWFtOiBhbnk7XHJcbiAgYWdjU3RhdHVzOmJvb2xlYW58bnVsbD1udWxsO1xyXG4gIGJ1ZmZlcmluZ05vZGU6IEF1ZGlvTm9kZXxudWxsPW51bGw7XHJcbiAgbGlzdGVuZXIhOiBBdWRpb0NhcHR1cmVMaXN0ZW5lcjtcclxuICBkYXRhOiBBcnJheTxBcnJheTxGbG9hdDMyQXJyYXk+PnxudWxsPW51bGw7XHJcbiAgY3VycmVudFNhbXBsZVJhdGUhOiBudW1iZXI7XHJcbiAgbjogTmF2aWdhdG9yO1xyXG4gIGF1ZGlvT3V0U3RyZWFtOiBTZXF1ZW5jZUF1ZGlvRmxvYXQzMk91dFN0cmVhbSB8IG51bGw9bnVsbDtcclxuICBwcml2YXRlIGRpc2Nvbm5lY3RTdHJlYW1zID0gdHJ1ZTtcclxuICBwcml2YXRlIF9vcGVuZWQ9ZmFsc2U7XHJcbiAgcHJpdmF0ZSBjYXB0dXJpbmcgPSBmYWxzZTtcclxuXHJcbiAgZnJhbWVzUmVjb3JkZWQ6IG51bWJlcj0wO1xyXG5cclxuICBwcml2YXRlIF9hdWRpb1N0b3JhZ2VUeXBlOkF1ZGlvU3RvcmFnZVR5cGU9QXVkaW9TdG9yYWdlVHlwZS5NRU1fRU5USVJFO1xyXG4gIHByaXZhdGUgX3BlcnNpc3RlbnRBdWRpb1N0b3JhZ2VUYXJnZXQ6UGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldHxudWxsPW51bGw7XHJcblxyXG4gIHByaXZhdGUgcGVyc2lzdGVkPXRydWU7XHJcbiAgcHJpdmF0ZSBwZXJzaXN0RXJyb3I6RXJyb3J8bnVsbD1udWxsO1xyXG4gIHByaXZhdGUgaW5kZGJBdWRpb0J1ZmZlcjpJbmRleGVkRGJBdWRpb0J1ZmZlcnxudWxsPW51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEF1ZGlvQ29udGV4dCkge1xyXG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcclxuICAgIHRoaXMubiA9IG5hdmlnYXRvcjtcclxuICAgIHRoaXMuY29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsICgpID0+IHtcclxuICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ3J1bm5pbmcnKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdERhdGEoKSB7XHJcbiAgICBpZighdGhpcy5fcmVjVVVJRCkge1xyXG4gICAgICB0aGlzLl9yZWNVVUlEID0gVVVJRC5nZW5lcmF0ZSgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5wZXJzaXN0RXJyb3I9bnVsbDtcclxuICAgIC8vY29uc29sZS5kZWJ1ZyhcIkF1ZGlvIGNhcHR1cmUgaW5pdGlhbGl6ZSBzdG9yYWdlIGZvciB0eXBlOiBcIit0aGlzLl9hdWRpb1N0b3JhZ2VUeXBlKTtcclxuICAgIGlmKEF1ZGlvU3RvcmFnZVR5cGUuREJfQ0hVTktFRCA9PT0gdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSAmJiB0aGlzLl9wZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0ICYmIHRoaXMuX3JlY1VVSUQpIHtcclxuICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ3JlYXRlIGluZGV4ZWQgZGIgYXVkaW8gYnVmZmVyLlwiKTtcclxuICAgICAgdGhpcy5pbmRkYkF1ZGlvQnVmZmVyID0gbmV3IEluZGV4ZWREYkF1ZGlvQnVmZmVyKHRoaXMuX3BlcnNpc3RlbnRBdWRpb1N0b3JhZ2VUYXJnZXQsIHRoaXMuY2hhbm5lbENvdW50LHRoaXMuY3VycmVudFNhbXBsZVJhdGUsQXVkaW9DYXB0dXJlLkJVRkZFUl9TSVpFLDAsdGhpcy5fcmVjVVVJRClcclxuICAgIH1cclxuICAgIGlmKCEoQXVkaW9TdG9yYWdlVHlwZS5ORVRfQ0hVTktFRCA9PT0gdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSkpIHtcclxuICAgICAgLy8gSW5pdGlhbGl6ZSBhdWRpbyBkYXRhIGFycmF5IGV4Y2VwdCBmb3IgbmV0IGF1ZGlvIGJ1ZmZlciBtb2RlXHJcbiAgICAgIHRoaXMuZGF0YSA9IG5ldyBBcnJheTxBcnJheTxGbG9hdDMyQXJyYXk+PigpO1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hhbm5lbENvdW50OyBpKyspIHtcclxuICAgICAgICB0aGlzLmRhdGEucHVzaChuZXcgQXJyYXk8RmxvYXQzMkFycmF5PigpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5mcmFtZXNSZWNvcmRlZCA9IDA7XHJcbiAgfVxyXG5cclxuICBsaXN0RGV2aWNlcygpIHtcclxuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oKGw6IE1lZGlhRGV2aWNlSW5mb1tdKSA9PiB0aGlzLnByaW50RGV2aWNlcyhsKSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGR1bW15U2Vzc2lvbigpOlByb21pc2U8TWVkaWFTdHJlYW0+e1xyXG4gICAgLy8gd29ya2Fyb3VuZCB0byByZXF1ZXN0IHBlcm1pc3Npb25zOlxyXG4gICAgLy8gU3RhcnQgYSBkdW1teSBzZXNzaW9uXHJcbiAgICBsZXQgbWVkaWFTdHJDbnN0cnMgPSA8TWVkaWFTdHJlYW1Db25zdHJhaW50cz57YXVkaW86XHJcbiAgICAgICAge2VjaG9DYW5jZWxhdGlvbjogZmFsc2V9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKG1lZGlhU3RyQ25zdHJzKTtcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgcHJpdmF0ZSBzdG9wQWxsU2Vzc2lvblRyYWNrcyhtZWRpYVN0cmVhbTpNZWRpYVN0cmVhbSl7XHJcbiAgICAgIGxldCBhdHMgPSBtZWRpYVN0cmVhbS5nZXRUcmFja3MoKTtcclxuICAgICAgZm9yIChsZXQgYXRJZHggPSAwOyBhdElkeCA8IGF0cy5sZW5ndGg7IGF0SWR4KyspIHtcclxuICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdG9wIGR1bW15IHNlc3Npb24gdHJhY2s6ICNcIiArIGF0SWR4KVxyXG4gICAgICAgIGF0c1thdElkeF0uc3RvcCgpO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICBkZXZpY2VJbmZvcyhjYjogKGRldmljZUluZm9zOiBNZWRpYURldmljZUluZm9bXSB8IG51bGwpID0+IGFueSwgcmV0cnkgPSB0cnVlLGR1bW15U3RyZWFtPzpNZWRpYVN0cmVhbSkge1xyXG5cclxuICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oKGw6IE1lZGlhRGV2aWNlSW5mb1tdKSA9PiB7XHJcbiAgICAgIGxldCBsYWJlbHNBdmFpbGFibGUgPSBmYWxzZTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IGRpID0gbFtpXTtcclxuICAgICAgICBpZiAoZGkubGFiZWwpIHtcclxuICAgICAgICAgIGxhYmVsc0F2YWlsYWJsZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmICghbGFiZWxzQXZhaWxhYmxlKSB7XHJcbiAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiTWVkaWEgZGV2aWNlIGVudW1lcmF0aW9uOiBObyBsYWJlbHMuXCIpXHJcbiAgICAgICAgaWYgKHJldHJ5KSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlN0YXJ0aW5nIGR1bW15IHNlc3Npb24gdG8gcmVxdWVzdCBhdWRpbyBwZXJtaXNzaW9ucy4uLlwiKVxyXG5cclxuICAgICAgICAgICAgdGhpcy5kdW1teVNlc3Npb24oKS50aGVuKChzOiBNZWRpYVN0cmVhbSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBhbmQgc3RvcCBpdCBpbW1lZGlhdGVseVxyXG5cclxuICAgICAgICAgICAgaWYocykge1xyXG4gICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkdvdCBkdW1teSBzZXNzaW9uIHN0cmVhbTogXCIgKyBzICsgXCIgLlwiKVxyXG4gICAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJObyBkdW1teSBzdHJlYW1cIilcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyByZXRyeSAob25seSBvbmNlKVxyXG4gICAgICAgICAgICB0aGlzLmRldmljZUluZm9zKGNiLCBmYWxzZSxzKTtcclxuICAgICAgICAgIH0scmVhc29uID0+IHtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiRHVtbXkgc2Vzc2lvbiByZWplY3RlZC5cIilcclxuICAgICAgICAgICAgLy8gVE9ETyBlcnJvciBjYWxsYmFja1xyXG4gICAgICAgICAgICBjYihudWxsKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjYihudWxsKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gc3VjY2Vzc1xyXG4gICAgICAgIGNiKGwpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmKGR1bW15U3RyZWFtKXtcclxuICAgICAgICB0aGlzLnN0b3BBbGxTZXNzaW9uVHJhY2tzKGR1bW15U3RyZWFtKTtcclxuICAgICAgfVxyXG4gICAgfSwocmVhc29uKT0+IHtcclxuICAgICAgLy9yZWplY3RlZFxyXG4gICAgICAvL2NvbnNvbGUuZGVidWcoXCJNZWRpYSBkZXZpY2UgZW51bWVyYXRpb24gcmVqZWN0ZWQuXCIpXHJcbiAgICAgIGlmIChyZXRyeSkge1xyXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlN0YXJ0aW5nIGR1bW15IHNlc3Npb24gdG8gcmVxdWVzdCBhdWRpbyBwZXJtaXNzaW9ucy4uLlwiKVxyXG4gICAgICAgIHRoaXMuZHVtbXlTZXNzaW9uKCkudGhlbigoczogTWVkaWFTdHJlYW0pID0+IHtcclxuICAgICAgICAgIC8vIGFuZCBzdG9wIGl0IGltbWVkaWF0ZWx5XHJcbiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJEdW1teSBzZXNzaW9uLlwiKVxyXG4gICAgICAgICAgaWYocykge1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJHb3QgZHVtbXkgc2Vzc2lvbiBzdHJlYW06IFwiICsgcyArIFwiIC5cIilcclxuICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJObyBkdW1teSBzdHJlYW1cIilcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIHJldHJ5IChvbmx5IG9uY2UpXHJcbiAgICAgICAgICB0aGlzLmRldmljZUluZm9zKGNiLCBmYWxzZSxzKTtcclxuICAgICAgICB9LCByZWFzb24gPT4ge1xyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiRHVtbXkgc2Vzc2lvbiByZWplY3RlZC5cIilcclxuICAgICAgICAgIC8vIFRPRE8gZXJyb3IgY2FsbGJhY2tcclxuICAgICAgICAgIGNiKG51bGwpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNiKG51bGwpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmKGR1bW15U3RyZWFtKXtcclxuICAgICAgICB0aGlzLnN0b3BBbGxTZXNzaW9uVHJhY2tzKGR1bW15U3RyZWFtKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG5cclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgcHJpbnREZXZpY2VzKGw6IE1lZGlhRGV2aWNlSW5mb1tdKTogdm9pZCB7XHJcbiAgICAvL2xldCBzZWxEZXZpY2VJZCA9ICdfX19kdW1teV9fXyc7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGwubGVuZ3RoOyBpKyspIHtcclxuICAgICAgbGV0IGRpID0gbFtpXTtcclxuICAgICAgY29uc29sZS5sb2coXCJBdWRpbyBkZXZpY2U6IElkOiBcIiArIGRpLmRldmljZUlkICsgXCIgZ3JvdXBJZDogXCIgKyBkaS5ncm91cElkICsgXCIgbGFiZWw6IFwiICsgZGkubGFiZWwgKyBcIiBraW5kOiBcIiArIGRpLmtpbmQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYWRkQ2FwdHVyZUludGVyY2VwdG9yKCkge1xyXG4gICAgY29uc3QgYXduID0gbmV3IEF1ZGlvV29ya2xldE5vZGUodGhpcy5jb250ZXh0LCAnY2FwdHVyZS1pbnRlcmNlcHRvcicpO1xyXG4gICAgYXduLm9ucHJvY2Vzc29yZXJyb3IgPSAoZXY6IEV2ZW50KSA9PiB7XHJcbiAgICAgIGxldCBtc2cgPSAnVW5rbndvbiBlcnJvcic7XHJcbiAgICAgIGlmIChldiBpbnN0YW5jZW9mIEVycm9yRXZlbnQpIHtcclxuICAgICAgICBtc2cgPSBldi5tZXNzYWdlO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJDYXB0dXJlIGF1ZGlvIHdvcmtsZXQgZXJyb3I6IFwiICsgbXNnKTtcclxuICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVyLmVycm9yKG1zZyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGxldCBhd25QdCA9IGF3bi5wb3J0O1xyXG4gICAgaWYgKGF3blB0KSB7XHJcbiAgICAgIGF3blB0Lm9ubWVzc2FnZSA9IChldjogTWVzc2FnZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2FwdHVyaW5nKSB7XHJcbiAgICAgICAgICBsZXQgZHQgPSBldi5kYXRhO1xyXG4gICAgICAgICAgbGV0IGNocyA9IGR0LmNocztcclxuICAgICAgICAgIGxldCBhZGFMZW4gPSBkdC5kYXRhLmxlbmd0aDtcclxuICAgICAgICAgIGlmIChERUJVR19UUkFDRV9MRVZFTCA+IDgpIHtcclxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZygnUmVjZWl2ZWQgZGF0YSBmcm9tIHdvcmtsZXQ6ICcgKyBjaHMgKyAnICcgKyBkdC5sZW4gKyAnIERhdGEgY2hzOiAnICsgYWRhTGVuKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGxldCBjaHVuayA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgICAgICAgICBjb25zdCBzYW1wbGVzID0gdGhpcy5mcmFtZXNSZWNvcmRlZCAqIGNocztcclxuICAgICAgICAgIGlmICgoQXVkaW9TdG9yYWdlVHlwZS5NRU1fRU5USVJFX0FVVE9fTkVUX0NIVU5LRUQgPT09IHRoaXMuYXVkaW9TdG9yYWdlVHlwZSB8fCBBdWRpb1N0b3JhZ2VUeXBlLk1FTV9DSFVOS0VEX0FVVE9fTkVUX0NIVU5LRUQgPT09IHRoaXMuYXVkaW9TdG9yYWdlVHlwZSkgJiYgdGhpcy5kYXRhICYmIHNhbXBsZXMgPiB0aGlzLl9tYXhBdXRvTmV0TWVtU3RvcmVTYW1wbGVzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IG51bGw7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiRGF0YSBpbml0aWFsaXplZDogXCIrKHRoaXMuZGF0YSE9bnVsbCkpO1xyXG4gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IGNoczsgY2grKykge1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJEYXRhIGNoIGluaXRpYWxpemVkOiBcIisodGhpcy5kYXRhICE9bnVsbCAmJiB0aGlzLmRhdGFbY2hdICE9bnVsbCkpO1xyXG4gICAgICAgICAgICBpZiAoY2ggPCB0aGlzLmNoYW5uZWxDb3VudCkge1xyXG4gICAgICAgICAgICAgIGlmIChkdC5kYXRhW2NoXSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGZhID0gbmV3IEZsb2F0MzJBcnJheShkdC5kYXRhW2NoXSk7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YVtjaF0pIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhW2NoXS5wdXNoKGZhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNodW5rW2NoXSA9IGZhO1xyXG4gICAgICAgICAgICAgICAgLy8gVXNlIHNhbXBsZXMgb2YgY2hhbm5lbCAwIHRvIGNvdW50IGZyYW1lcyAoc2FtcGxlcylcclxuICAgICAgICAgICAgICAgIGlmIChjaCA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVzUmVjb3JkZWQgKz0gZmEubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHRoaXMuYXVkaW9PdXRTdHJlYW0pIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICB0aGlzLmF1ZGlvT3V0U3RyZWFtLndyaXRlKGNodW5rKTtcclxuICAgICAgICAgICAgICAvLyAvLyBSYW5kb20gdGVzdCBlcnJvcjpcclxuICAgICAgICAgICAgICAvLyBpZihNYXRoLnJhbmRvbSgpPjAuOTgpIHtcclxuICAgICAgICAgICAgICAvLyAgIHRocm93IG5ldyBFcnJvcignVGVzdCcpO1xyXG4gICAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RFcnJvciA9IGVycjtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wZXJzaXN0RXJyb3IgPSBuZXcgRXJyb3IoJ0Vycm9yIGhhbmRsaW5nIHJlY29yZGVkIGF1ZGlvIGRhdGEnKTtcclxuICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDYXB0dXJlIGVycm9yOiBcIiArIGVycik7XHJcbiAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycjIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDYXB0dXJlIG5leHQgZXJyb3IgKGlnbm9yZWQpOiBcIiArIGVycjIpO1xyXG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICBsZXQgZXJyRXhwbCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRE9NRXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyRXhwbCA9ICc6ICcgKyBlcnIubmFtZSArICc6ICcgKyBlcnIubWVzc2FnZTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmVycm9yKFwiQ291bGQgbm90IGhhbmRsZSByZWNvcmRlZCBhdWRpbyBkYXRhXCIgKyBlcnJFeHBsLCBcIlBsZWFzZSB0cnkgdG8gcmVjb3JkIGFnYWluLlwiKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChBdWRpb1N0b3JhZ2VUeXBlLkRCX0NIVU5LRUQgPT09IHRoaXMuX2F1ZGlvU3RvcmFnZVR5cGUgJiYgdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCkge1xyXG4gICAgICAgICAgICB0aGlzLnN0b3JlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gICAgLy8gVHJpZWQgdG8gZml4IHRoYXQgU2FmYXJpIGRvZXMgbm90IHJlY29yZCB0aGUgc2Vjb25kIGNoYW5uZWxcclxuICAgIC8vIERvZXMgbm90IGhlbHBcclxuICAgIC8vYXduLmNoYW5uZWxDb3VudD10aGlzLmNoYW5uZWxDb3VudDtcclxuICAgIC8vYXduLmNoYW5uZWxDb3VudE1vZGU9J2V4cGxpY2l0JztcclxuICAgIC8vY29uc29sZS5kZWJ1ZygnQ2hhbm5lbCBjb3VudCBleHBsaWNpdGx5IHNldCB0byAnK3RoaXMuY2hhbm5lbENvdW50KTtcclxuXHJcbiAgICB0aGlzLmJ1ZmZlcmluZ05vZGUgPSBhd247XHJcbiAgICAvL3RoaXMuYnVmZmVyaW5nTm9kZS5jaGFubmVsQ291bnQ9dGhpcy5jaGFubmVsQ291bnQ7XHJcbiAgICB0aGlzLl9vcGVuZWQgPSB0cnVlO1xyXG4gICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgdGhpcy5saXN0ZW5lci5vcGVuZWQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9wZW4oY2hhbm5lbENvdW50OiBudW1iZXIsIHNlbERldmljZUlkPzogQ29uc3RyYWluRE9NU3RyaW5nfHVuZGVmaW5lZCxhdXRvR2FpbkNvbnRyb2xDb25maWdzPzpBcnJheTxBdXRvR2FpbkNvbnRyb2xDb25maWc+fG51bGx8dW5kZWZpbmVkKXtcclxuICAgIC8vY29uc29sZS5kZWJ1ZyhcIkNhcHR1cmUgb3BlbjogY3R4IHN0YXRlOiBcIit0aGlzLmNvbnRleHQuc3RhdGUpO1xyXG4gICAgaWYodGhpcy5jb250ZXh0LnN0YXRlIT09J3J1bm5pbmcnKXtcclxuICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQ2FwdHVyZSBvcGVuOiBSZXN1bWUgY29udGV4dFwiKTtcclxuICAgICAgdGhpcy5jb250ZXh0LnJlc3VtZSgpLnRoZW4oKCk9PntcclxuICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJDYXB0dXJlIG9wZW4gKGN0eCByZXN1bWVkKTogY3R4IHN0YXRlOiBcIit0aGlzLmNvbnRleHQuc3RhdGUpO1xyXG4gICAgICAgIHRoaXMuX29wZW4oY2hhbm5lbENvdW50LCBzZWxEZXZpY2VJZCwgYXV0b0dhaW5Db250cm9sQ29uZmlncyk7XHJcbiAgICAgIH0pXHJcbiAgICB9ZWxzZXtcclxuICAgICAgdGhpcy5fb3BlbihjaGFubmVsQ291bnQsIHNlbERldmljZUlkLCBhdXRvR2FpbkNvbnRyb2xDb25maWdzKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBfb3BlbihjaGFubmVsQ291bnQ6IG51bWJlciwgc2VsRGV2aWNlSWQ/OiBDb25zdHJhaW5ET01TdHJpbmd8dW5kZWZpbmVkLGF1dG9HYWluQ29udHJvbENvbmZpZ3M/OkFycmF5PEF1dG9HYWluQ29udHJvbENvbmZpZz58bnVsbHx1bmRlZmluZWQpIHtcclxuICAgIHRoaXMuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xyXG4gICAgdGhpcy5mcmFtZXNSZWNvcmRlZCA9IDA7XHJcblxyXG5cclxuICAgIC8vdmFyIG1zYyA9IG5ldyBBdWRpb1N0cmVhbUNvbnN0cigpO1xyXG4gICAgLy8gdmFyIG1zYz17fTtcclxuICAgIC8vbXNjLnZpZGVvID0gZmFsc2U7XHJcbiAgICAvL21zYy5hdWRpbyA9IHRydWU7XHJcblxyXG4gICAgLy8gQ2hyb21lIGFuZCBGaXJlZm94IHN0ZXJlbyBjaGFubmVscyBhcmUgaWRlbnRpY2FsICEhXHJcbiAgICAvLyBBbmQgZXZlbiB3b3JzZTogVGhlIGRhdGEgY29taW5nIGZyb20gdGhlIHNvdXJjZSBpcyBhbHJlYWR5IHByZXByb2Nlc3NlZCBvbiBGRiBhbmQgQ2hyb21lLiBJdCBjb250YWlucyBEU1AgYXJ0aWZhY3RzISFcclxuXHJcbiAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zODc3MzdcclxuICAgIC8vIFRoZSB3b3JrYXJvdW5kIHRvIHNldCB0aGVzZSBjb25zdHJhaW50cyBkb2VzIF9OT1RfIGhlbHA6XHJcbiAgICAvL3ZhciBtc2M9e2F1ZGlvOiB7ZWNob0NhbmNlbGxhdGlvbjogZmFsc2UsY2hhbm5lbENvdW50OiAyLCBnb29nQXVkaW9NaXJyb3Jpbmc6IGZhbHNlfSx2aWRlbzogZmFsc2V9O1xyXG5cclxuICAgIC8vIFNhZmFyaSBhdCBsZWFzdCB2ZXJzaW9uIDExOiBTdXBwb3J0IGZvciBtZWRpYSBzdHJlYW1zXHJcbiAgICAvLyBUT0RPIHRlc3QgaWYgaW5wdXQgaXMgdW5wcm9jZXNzZWRcclxuXHJcbiAgICBsZXQgbXNjOk1lZGlhU3RyZWFtQ29uc3RyYWludHM7XHJcbiAgICBjb25zb2xlLmluZm8oJ1VzZXIgYWdlbnQ6ICcrbmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcblxyXG5cclxuICAgICAgbGV0IHVhPVVzZXJBZ2VudEJ1aWxkZXIudXNlckFnZW50KCk7XHJcblxyXG4gICAgICAvLyB1YS5jb21wb25lbnRzLmZvckVhY2goKGMpPT57XHJcbiAgICAgIC8vICAgY29uc29sZS5pbmZvKFwiVUFfQ29tcDogXCIrYy50b1N0cmluZygpKTtcclxuICAgICAgLy8gfSlcclxuXHJcbiAgICAgbGV0IGFnY0NmZzpBdXRvR2FpbkNvbnRyb2xDb25maWd8bnVsbD1udWxsO1xyXG5cclxuICAgIGxldCBhdXRvR2FpbkNvbnRyb2w9ZmFsc2U7XHJcbiAgICBsZXQgY2hyb21lRWNob0NhbmNlbGxhdGlvbj1mYWxzZTtcclxuICAgIGlmKGF1dG9HYWluQ29udHJvbENvbmZpZ3Mpe1xyXG4gICAgICBmb3IobGV0IGFnY2Mgb2YgYXV0b0dhaW5Db250cm9sQ29uZmlncyl7XHJcbiAgICAgICAgaWYoYWdjYy5wbGF0Zm9ybT09PUNmZ1BsYXRmb3JtLkFuZHJvaWQgJiYgdWEuZGV0ZWN0ZWRQbGF0Zm9ybT09PVBsYXRmb3JtLkFuZHJvaWQpe1xyXG4gICAgICAgICAgICBhZ2NDZmc9YWdjYztcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGFnY2MucGxhdGZvcm09PT1DZmdQbGF0Zm9ybS5XaW5kb3dzICYmIHVhLmRldGVjdGVkUGxhdGZvcm09PT1QbGF0Zm9ybS5XaW5kb3dzKXtcclxuICAgICAgICAgIGFnY0NmZz1hZ2NjO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmKGFnY0NmZyl7XHJcbiAgICAgICAgLy8gVE9ETyB1c2UgRVhBQ1QvSURFQUwgY29uc3RyYWludFxyXG4gICAgICAgIGF1dG9HYWluQ29udHJvbD1hZ2NDZmcudmFsdWU7XHJcbiAgICAgICAgaWYoQ0hST01FX0FDVElWQVRFX0VDSE9fQ0FOQ0VMTEFUSU9OX1dJVEhfQUdDKXtcclxuICAgICAgICAgIGNocm9tZUVjaG9DYW5jZWxsYXRpb249YWdjQ2ZnLnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBUT0RPIHF1ZXJ5IHJlYWwgQUdDIHN0YXR1c1xyXG4gICAgICAgIHRoaXMuYWdjU3RhdHVzPWFnY0NmZy52YWx1ZTtcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgdGhpcy5hZ2NTdGF0dXM9ZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBkZWZhdWx0XHJcbiAgICBtc2MgPSB7XHJcbiAgICAgIGF1ZGlvOiB7XHJcbiAgICAgICAgZGV2aWNlSWQ6IHNlbERldmljZUlkLFxyXG4gICAgICAgIGVjaG9DYW5jZWxsYXRpb246IGZhbHNlLFxyXG4gICAgICAgIGNoYW5uZWxDb3VudDogY2hhbm5lbENvdW50LFxyXG4gICAgICAgIGF1dG9HYWluQ29udHJvbDogYXV0b0dhaW5Db250cm9sXHJcbiAgICAgIH0sXHJcbiAgICAgIHZpZGVvOiBmYWxzZVxyXG4gICAgfTtcclxuXHJcbiAgICBpZiAodWEuZGV0ZWN0ZWRCcm93c2VyPT09QnJvd3Nlci5FZGdlKSB7XHJcblxyXG4gICAgICAvLyBNaWNyb3NvZnQgRWRnZSBzZW5kcyB1bm1vZGlmaWVkIGF1ZGlvXHJcbiAgICAgIC8vIFRoZSBjb25zdHJhaW50IGNhbiBmb2xsb3cgdGhlIHNwZWNpZmljYXRpb25cclxuICAgICAgY29uc29sZS5pbmZvKFwiU2V0dGluZyBtZWRpYSB0cmFjayBjb25zdHJhaW50cyBmb3IgTWljcm9zb2Z0IEVkZ2UuXCIpO1xyXG4gICAgICBtc2MgPSB7XHJcbiAgICAgICAgYXVkaW86IHtcclxuICAgICAgICAgIGRldmljZUlkOiBzZWxEZXZpY2VJZCxcclxuICAgICAgICAgIGVjaG9DYW5jZWxsYXRpb246IGZhbHNlLFxyXG4gICAgICAgICAgY2hhbm5lbENvdW50OiBjaGFubmVsQ291bnQsXHJcbiAgICAgICAgICBhdXRvR2FpbkNvbnRyb2w6IGF1dG9HYWluQ29udHJvbFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdmlkZW86IGZhbHNlXHJcbiAgICAgIH07XHJcbiAgICB9IGVsc2UgaWYgKHVhLmRldGVjdGVkQnJvd3Nlcj09PUJyb3dzZXIuQ2hyb21lKSB7XHJcbiAgICAgIC8vIEdvb2dsZSBDaHJvbWU6IHdlIG5lZWQgdG8gc3dpdGNoIG9mIGVhY2ggb2YgdGhlIHByZXByb2Nlc3NpbmcgdW5pdHMgaW5jbHVkaW5nIHRoZVxyXG4gICAgICBjb25zb2xlLmluZm8oXCJTZXR0aW5nIG1lZGlhIHRyYWNrIGNvbnN0cmFpbnRzIGZvciBHb29nbGUgQ2hyb21lLlwiKTtcclxuXHJcbiAgICAgIC8vIENocm9tZSA2MCAtPiA2MSBjaGFuZ2VkXHJcbiAgICAgIC8vIGl0IHdvcmtzIG5vdyB3aXRob3V0IG1hbmRhdG9yeS9vcHRpb25hbCBzdWItb2JqZWN0c1xyXG5cclxuXHJcbiAgICAgIC8vIFJlcXVpcmVzIGF0IGxlYXN0IENocm9tZSA2MVxyXG4gICAgICBtc2MgPSB7XHJcbiAgICAgICAgYXVkaW86IHtcclxuICAgICAgICAgIGRldmljZUlkOiBzZWxEZXZpY2VJZCxcclxuICAgICAgICAgIGNoYW5uZWxDb3VudDogY2hhbm5lbENvdW50LFxyXG4gICAgICAgICAgZWNob0NhbmNlbGxhdGlvbjoge2V4YWN0OmNocm9tZUVjaG9DYW5jZWxsYXRpb259LFxyXG4gICAgICAgICAgYXV0b0dhaW5Db250cm9sOiB7ZXhhY3Q6YXV0b0dhaW5Db250cm9sfSxcclxuICAgICAgICAgIHNhbXBsZVNpemU6e21pbjogMTZ9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdmlkZW86IGZhbHNlLFxyXG4gICAgICB9XHJcblxyXG4gICAgfSBlbHNlIGlmICh1YS5kZXRlY3RlZEJyb3dzZXI9PT1Ccm93c2VyLkZpcmVmb3gpIHtcclxuICAgICAgY29uc29sZS5pbmZvKFwiU2V0dGluZyBtZWRpYSB0cmFjayBjb25zdHJhaW50cyBmb3IgTW96aWxsYSBGaXJlZm94LlwiKTtcclxuICAgICAgLy8gRmlyZWZveFxyXG4gICAgICBtc2MgPSB7XHJcbiAgICAgICAgYXVkaW86IHtcclxuICAgICAgICAgICAgZGV2aWNlSWQ6IHNlbERldmljZUlkLFxyXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IGNoYW5uZWxDb3VudCxcclxuICAgICAgICAgIGVjaG9DYW5jZWxsYXRpb246IGZhbHNlLFxyXG4gICAgICAgICAgICBhdXRvR2FpbkNvbnRyb2w6IGF1dG9HYWluQ29udHJvbCxcclxuICAgICAgICAgIG5vaXNlU3VwcHJlc3Npb246IGZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB2aWRlbzogZmFsc2UsXHJcbiAgICAgIH1cclxuXHJcbiAgICB9IGVsc2UgaWYgKHVhLmRldGVjdGVkQnJvd3Nlcj09PUJyb3dzZXIuU2FmYXJpKSB7XHJcbiAgICAgIGNvbnNvbGUuaW5mbyhcIlNldHRpbmcgbWVkaWEgdHJhY2sgY29uc3RyYWludHMgZm9yIFNhZmFyaSBicm93c2VyLlwiKVxyXG4gICAgICAvL2NvbnNvbGUuaW5mbyhcIkFwcGx5IHdvcmthcm91bmQgZm9yIFNhZmFyaTogQXZvaWQgZGlzY29ubmVjdCBvZiBzdHJlYW1zLlwiKTtcclxuXHJcbiAgICAgIHRoaXMuZGlzY29ubmVjdFN0cmVhbXMgPSB0cnVlO1xyXG4gICAgICBtc2MgPSB7XHJcbiAgICAgICAgYXVkaW86IHtcclxuICAgICAgICAgIGRldmljZUlkOiBzZWxEZXZpY2VJZCxcclxuICAgICAgICAgIGNoYW5uZWxDb3VudDogY2hhbm5lbENvdW50LFxyXG4gICAgICAgICAgLy9lY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdmlkZW86IGZhbHNlLFxyXG4gICAgICB9XHJcblxyXG4gICAgfSBlbHNlIHtcclxuXHJcbiAgICAgIC8vIFRPRE8gZGVmYXVsdCBjb25zdHJhaW50cyBvciBlcnJvciBCcm93c2VyIG5vdCBzdXBwb3J0ZWRcclxuICAgIH1cclxuXHJcblxyXG5cclxuICAgIGNvbnNvbGUuZGVidWcoXCJBdWRpbyBjYXB0dXJlLCBBR0M6IFwiK3RoaXMuYWdjU3RhdHVzKVxyXG5cclxuICAgIGxldCB1bXAgPSBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShtc2MpO1xyXG4gICAgdW1wLnRoZW4oKHMpID0+IHtcclxuICAgICAgICB0aGlzLnN0cmVhbSA9IHM7XHJcblxyXG4gICAgICAgIGxldCBhVHJhY2tzID0gcy5nZXRBdWRpb1RyYWNrcygpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFUcmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIGxldCBhVHJhY2sgPSBhVHJhY2tzW2ldO1xyXG5cclxuICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlRyYWNrIGF1ZGlvIGluZm86IGlkOiBcIiArIGFUcmFjay5pZCArIFwiIGtpbmQ6IFwiICsgYVRyYWNrLmtpbmQgKyBcIiBsYWJlbDogXFxcIlwiICsgYVRyYWNrLmxhYmVsICsgXCJcXFwiXCIpO1xyXG4gICAgICAgICAgbGV0IG10clN0cz1hVHJhY2suZ2V0U2V0dGluZ3MoKTtcclxuXHJcbiAgICAgICAgICAvLyBUeXBlc2NyaXB0IGxpYi5kb20udHMgTWVkaWFUcmFja1NldHRpbmdzLmNoYW5uZWxDb3VudCBpcyBtaXNzaW5nXHJcbiAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWRuL2Jyb3dzZXItY29tcGF0LWRhdGEvYmxvYi81NDkzZDhmOTM3ZTA1YjJkZGJkNDFiOTlmNWJkZmFkNGExZjJlZDg1L2FwaS9NZWRpYVRyYWNrU2V0dGluZ3MuanNvblxyXG4gICAgICAgICAgLy9AdHMtaWdub3JlXHJcbiAgICAgICAgICBjb25zb2xlLmluZm8oXCJUcmFjayBhdWRpbyBzZXR0aW5nczogQ2ggY250OiBcIittdHJTdHMuY2hhbm5lbENvdW50K1wiLCBBR0M6IFwiK210clN0cy5hdXRvR2FpbkNvbnRyb2wrXCIsIEVjaG8gY2FuY2VsbC46IFwiK210clN0cy5lY2hvQ2FuY2VsbGF0aW9uKTtcclxuICAgICAgICAgIGlmKG10clN0cy5hdXRvR2FpbkNvbnRyb2wpe1xyXG4gICAgICAgICAgICB0aGlzLmFnY1N0YXR1cz1tdHJTdHMuYXV0b0dhaW5Db250cm9sO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHZUcmFja3MgPSBzLmdldFZpZGVvVHJhY2tzKCk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2VHJhY2tzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICBsZXQgdlRyYWNrID0gdlRyYWNrc1tpXTtcclxuICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlRyYWNrIHZpZGVvIGluZm86IGlkOiBcIiArIHZUcmFjay5pZCArIFwiIGtpbmQ6IFwiICsgdlRyYWNrLmtpbmQgKyBcIiBsYWJlbDogXCIgKyB2VHJhY2subGFiZWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gdGhpcy5jb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHMpO1xyXG4gICAgICAgIC8vIHN0cmVhbSBjaGFubmVsIGNvdW50ICggaXMgYWx3YXlzIDIgISlcclxuICAgICAgICBsZXQgc3RyZWFtQ2hhbm5lbENvdW50OiBudW1iZXIgPSB0aGlzLm1lZGlhU3RyZWFtLmNoYW5uZWxDb3VudDtcclxuICAgICAgICBjb25zb2xlLmluZm8oXCJTdHJlYW0gY2hhbm5lbCBjb3VudDogXCIrc3RyZWFtQ2hhbm5lbENvdW50KTtcclxuICAgICAgICAvLyBpcyBub3Qgc2V0ISFcclxuICAgICAgICAvL3RoaXMuY3VycmVudFNhbXBsZVJhdGUgPSB0aGlzLm1lZGlhU3RyZWFtLnNhbXBsZVJhdGU7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSA9IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xyXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlNvdXJjZSBhdWRpbyBub2RlOiBjaGFubmVsczogXCIgKyBzdHJlYW1DaGFubmVsQ291bnQgKyBcIiBzYW1wbGVyYXRlOiBcIiArIHRoaXMuY3VycmVudFNhbXBsZVJhdGUpO1xyXG4gICAgICAgIGlmICh0aGlzLmF1ZGlvT3V0U3RyZWFtKSB7XHJcbiAgICAgICAgICB0aGlzLmF1ZGlvT3V0U3RyZWFtLnNldEZvcm1hdCh0aGlzLmNoYW5uZWxDb3VudCwgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFczQyAgLT4gbmV3IG5hbWUgaXMgY3JlYXRlU2NyaXB0UHJvY2Vzc29yXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBBZ2FpbiBkZXByZWNhdGVkLCBidXQgQXVkaW9Xb3JrZXIgbm90IHlldCBpbXBsZW1lbnRlZCBpbiBzdGFibGUgcmVsZWFzZXMgKEp1bmUgMjAxNilcclxuICAgICAgICAvLyBBdWRpb1dvcmtlciBpcyBub3cgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIC4uLiAoTWF5IDIwMTcpXHJcblxyXG4gICAgICAvLyBVcGRhdGUgMTItMjAyMDpcclxuICAgICAgIC8vIFRoZSBTY3JpcHRQcm9jZXNzb3JOb2RlIEludGVyZmFjZSAtIERFUFJFQ0FURURcclxuXHJcbiAgICAgIC8vIFVwZGF0ZSAwNi0yMDIxXHJcbiAgICAgIC8vICBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgaXMgaGVyZSB0byBzdGF5LiBXZWIgQXVkaW8gQVBJIGhhcyBub3cgUmVjb21tZW5kYXRpb24gc3RhdHVzICFcclxuXHJcbiAgICAgICAgICBpZih0aGlzLmNvbnRleHQuYXVkaW9Xb3JrbGV0KXtcclxuICAgICAgICAgICAgLy9jb25zdCB3b3JrbGV0RmlsZU5hbWUgPSAoJ2ZpbGUtbG9hZGVyIS4vaW50ZXJjZXB0b3Jfd29ya2xldC5qcycpO1xyXG4gICAgICAgICAgICAvL2NvbnN0IHdvcmtsZXRGaWxlTmFtZSA9ICdodHRwOi8vbG9jYWxob3N0OjQyMDAvYXNzZXRzL2ludGVyY2VwdG9yX3dvcmtsZXQuanMnO1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKGF3cFN0cik7XHJcbiAgICAgICAgICAgIGlmKEF1ZGlvQ2FwdHVyZS5jYXB0dXJlSW50ZXJjZXB0b3JNb2R1bGVSZWdpc3RlcmVkKSB7XHJcbiAgICAgICAgICAgICAgLy8gUmVxdWlyZWQgY2FwdHVyZSBpbnRlcmNlcHRvciBtb2R1bGUgYWxyZWFkeSByZWdpc3RlcmVkXHJcbiAgICAgICAgICAgICAgdGhpcy5hZGRDYXB0dXJlSW50ZXJjZXB0b3IoKTtcclxuICAgICAgICAgICAgfWVsc2V7XHJcblxyXG4gICAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGNhcHR1cmUgaW50ZXJjZXB0b3IgbW9kdWxlXHJcbiAgICAgICAgICAgICAgbGV0IGF1ZGlvV29ya2xldE1vZHVsZUJsb2IgPSBuZXcgQmxvYihbYXdwU3RyXSwge3R5cGU6ICd0ZXh0L2phdmFzY3JpcHQnfSk7XHJcblxyXG4gICAgICAgICAgICAgIGxldCBhdWRpb1dvcmtsZXRNb2R1bGVCbG9iVXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYik7XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKGF1ZGlvV29ya2xldE1vZHVsZUJsb2JVcmwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICBBdWRpb0NhcHR1cmUuY2FwdHVyZUludGVyY2VwdG9yTW9kdWxlUmVnaXN0ZXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQ2FwdHVyZUludGVyY2VwdG9yKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgKS5jYXRjaCgoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0NvdWxkIG5vdCBhZGQgbW9kdWxlICcgKyBlcnJvcik7XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1lbHNlIGlmKHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IpIHtcclxuICAgICAgICAgICAgLy8gVGhlIFNjcmlwdFByb2Nlc3Nvck5vZGUgSW50ZXJmYWNlIC0gREVQUkVDQVRFRCBPbmx5IGFzIGZhbGxiYWNrXHJcbiAgICAgICAgICAgIC8vIFRPRE8gc2hvdWxkIHdlIHVzZSBzdHJlYW1DaGFubmVsQ291bnQgb3IgY2hhbm5lbENvdW50IGhlcmUgP1xyXG4gICAgICAgICAgICBsZXQgc2NyaXB0UHJvY2Vzc29yTm9kZT0gdGhpcy5jb250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcihBdWRpb0NhcHR1cmUuQlVGRkVSX1NJWkUsIHN0cmVhbUNoYW5uZWxDb3VudCwgc3RyZWFtQ2hhbm5lbENvdW50KTtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXJpbmdOb2RlPXNjcmlwdFByb2Nlc3Nvck5vZGU7XHJcbiAgICAgICAgICAgIGxldCBjID0gMDtcclxuICAgICAgICAgICAgaWYoc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2Vzcyl7XHJcbiAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IChlOiBBdWRpb1Byb2Nlc3NpbmdFdmVudCkgPT4ge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmluZykge1xyXG4gICAgICAgICAgICAgICAgICBsZXQgaW5CdWZmZXIgPSBlLmlucHV0QnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgICAvLyBvbmx5IHByb2Nlc3MgcmVxdWVzdGVkIGNvdW50IG9mIGNoYW5uZWxzXHJcbiAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50QnVmZmVycyA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoOiBudW1iZXIgPSAwOyBjaCA8IGNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjaFNhbXBsZXMgPSBpbkJ1ZmZlci5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNoU2FtcGxlc0NvcHkgPSBjaFNhbXBsZXMuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudEJ1ZmZlcnNbY2hdID0gY2hTYW1wbGVzQ29weS5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YVtjaF0ucHVzaChjaFNhbXBsZXNDb3B5KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYoREVCVUdfVFJBQ0VfTEVWRUw+OCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiUHJvY2VzcyBcIitjaFNhbXBsZXNDb3B5Lmxlbmd0aCtcIiBzYW1wbGVzLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mcmFtZXNSZWNvcmRlZCArPSBjaFNhbXBsZXNDb3B5Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBjKys7XHJcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmF1ZGlvT3V0U3RyZWFtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hdWRpb091dFN0cmVhbS53cml0ZShjdXJyZW50QnVmZmVycyk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgIHRoaXMuX29wZW5lZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIub3BlbmVkKCk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmVycm9yKCdCcm93c2VyIGRvZXMgbm90IHN1cHBvcnQgYXVkaW8gcHJvY2Vzc2luZyAoU2NyaXB0UHJvY2Vzc29yLm9uYXVkaW9wcm9jZXNzIG1ldGhvZCBub3QgZm91bmQpIScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5lcnJvcignQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGF1ZGlvIHByb2Nlc3NpbmcgKG5laXRoZXIgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIG5vciBTY3JpcHRQcm9jZXNzb3IpIScpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sIChlKSA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUgKyBcIiBFcnJvciBuYW1lOiBcIiArZS5uYW1lKTtcclxuICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIGlmKCdOb3RBbGxvd2VkRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ05vdCBhbGxvd2VkIHRvIHVzZSB5b3VyIG1pY3JvcGhvbmUuJywnUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IG1pY3JvcGhvbmUgYWNjZXNzIGlzIGFsbG93ZWQgZm9yIHRoaXMgd2ViIHBhZ2UgYW5kIHJlbG9hZCB0aGUgcGFnZS4nKTtcclxuICAgICAgICAgICAgfWVsc2UgaWYoJ05vdFJlYWRhYmxlRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ0NvdWxkIG5vdCByZWFkIGZyb20geW91ciBhdWRpbyBkZXZpY2UuJywnUGxlYXNlIG1ha2Ugc3VyZSB5b3VyIGF1ZGlvIGRldmljZSBpcyB3b3JraW5nLicpO1xyXG4gICAgICAgICAgICB9ZWxzZSBpZignT3ZlcmNvbnN0cmFpbmVkRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIGxldCBlTXNnPWUubXNnP2UubXNnOidPdmVyY29uc3RyYWluZWQgbWVkaWEgZGV2aWNlIHJlcXVlc3QgZXJyb3IuJztcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmVycm9yKGVNc2cpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIClcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3N0YXJ0KCl7XHJcbiAgICB0aGlzLmluaXREYXRhKCk7XHJcbiAgICBpZiAodGhpcy5hdWRpb091dFN0cmVhbSkge1xyXG4gICAgICB0aGlzLmF1ZGlvT3V0U3RyZWFtLm5leHRTdHJlYW0oKVxyXG4gICAgfVxyXG4gICAgdGhpcy5jYXB0dXJpbmcgPSB0cnVlO1xyXG4gICAgaWYodGhpcy5idWZmZXJpbmdOb2RlKSB7XHJcbiAgICAgIHRoaXMubWVkaWFTdHJlYW0uY29ubmVjdCh0aGlzLmJ1ZmZlcmluZ05vZGUpO1xyXG4gICAgICB0aGlzLmJ1ZmZlcmluZ05vZGUuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMubGlzdGVuZXIpIHtcclxuICAgICAgdGhpcy5saXN0ZW5lci5zdGFydGVkKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdGFydCgpIHtcclxuICAgIGNvbnN0IGFTdD10aGlzLmNvbnRleHQuc3RhdGU7XHJcbiAgICBpZihhU3Q9PT0ncnVubmluZycpIHtcclxuICAgICAgdGhpcy5fc3RhcnQoKTtcclxuICAgIH1lbHNle1xyXG4gICAgICBjb25zb2xlLmRlYnVnKFwiQ2FwdHVyZSBzdGFydDogYXVkaW8gY29udGV4dCBub3QgcnVubmluZywgc3RhdGU6IFwiK2FTdCtcIiwgcmVzdW1pbmcuLi5cIik7XHJcbiAgICAgIHRoaXMuY29udGV4dC5yZXN1bWUoKS50aGVuKCgpPT57XHJcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkNhcHR1cmUgc3RhcnQ6IGF1ZGlvIGNvbnRleHQgcmVzdW1lZCwgc3RhcnRpbmcuLi5cIik7XHJcbiAgICAgICAgdGhpcy5fc3RhcnQoKTtcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN0b3AoKSB7XHJcblxyXG4gICAgaWYgKHRoaXMuZGlzY29ubmVjdFN0cmVhbXMgJiYgdGhpcy5idWZmZXJpbmdOb2RlKSB7XHJcbiAgICAgIHRoaXMubWVkaWFTdHJlYW0uZGlzY29ubmVjdCh0aGlzLmJ1ZmZlcmluZ05vZGUpO1xyXG4gICAgICB0aGlzLmJ1ZmZlcmluZ05vZGUuZGlzY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGlmICh0aGlzLmF1ZGlvT3V0U3RyZWFtKSB7XHJcbiAgICAgICAgdGhpcy5hdWRpb091dFN0cmVhbS5mbHVzaCgpO1xyXG4gICAgICB9XHJcbiAgICB9Y2F0Y2goZXJyKXtcclxuICAgICAgY29uc29sZS5lcnJvcihcIkNvdWxkIG5vdCBmbHVzaCBjYXB0dXJlIHN0cmVhbS5cIik7XHJcbiAgICAgdGhyb3cgZXJyO1xyXG4gICAgfWZpbmFsbHkge1xyXG4gICAgICB0aGlzLmNhcHR1cmluZyA9IGZhbHNlO1xyXG4gICAgICBpZiAodGhpcy5pbmRkYkF1ZGlvQnVmZmVyICYmIHRoaXMucGVyc2lzdEVycm9yKSB7XHJcbiAgICAgICAgLy8gRGVsZXRlIGludmFsaWQgcGVyc2lzdGVudCBhdWRpbyBkYXRhIGFuZCBob3BlIHRoYXQgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IHVwbG9hZGVkIHRvIHRoZSBzZXJ2ZXJcclxuICAgICAgICB0aGlzLmluZGRiQXVkaW9CdWZmZXIucmVsZWFzZUF1ZGlvRGF0YSgpO1xyXG4gICAgICAgIHRoaXMuaW5kZGJBdWRpb0J1ZmZlciA9IG51bGw7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMubGlzdGVuZXIgJiYgKHRoaXMucGVyc2lzdEVycm9yIHx8IHRoaXMucGVyc2lzdGVkKSkge1xyXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlN0b3BwZWQgYnkgc3RvcCgpIG1ldGhvZCBjYWxsXCIpO1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXIuc3RvcHBlZCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgc3RvcmUoKXtcclxuICAgLy8gaWYodGhpcy5kYiAmJiB0aGlzLnJlY1VVSUQpe1xyXG4gICAvLyAgICBsZXQgdHI9IHRoaXMuZGIudHJhbnNhY3Rpb24oU3ByRGIuUkVDT1JESU5HX0ZJTEVfQ0hVTktTX09CSkVDVF9TVE9SRV9OQU1FLCAncmVhZHdyaXRlJyk7XHJcbiAgIC8vICAgIGxldCByZWNGaWxlT2JqU3RvcmUgPSB0ci5vYmplY3RTdG9yZShTcHJEYi5SRUNPUkRJTkdfRklMRV9DSFVOS1NfT0JKRUNUX1NUT1JFX05BTUUpO1xyXG4gICAvL1xyXG4gICAvLyAgICAgIHRyeSB7XHJcbiAgIC8vICAgICAgICBsZXQgY2gwRGF0YT10aGlzLmRhdGFbMF07XHJcbiAgIC8vICAgICAgICBsZXQgZGF0YUNoa0NudD1jaDBEYXRhLmxlbmd0aDtcclxuICAgLy8gICAgICAgICAgbGV0IHBvcyA9IDA7XHJcbiAgIC8vICAgICAgICAgIGZvciAobGV0IGNoQ2tJZHggPSAwOyBjaENrSWR4IDwgZGF0YUNoa0NudDsgY2hDa0lkeCsrKSB7XHJcbiAgIC8vICAgICAgICAgICAgbGV0IGJ1Zkxlbj0wO1xyXG4gICAvLyAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCB0aGlzLmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAvLyAgICAgICAgICAgICAgbGV0IGNoQ2hrID0gdGhpcy5kYXRhW2NoXVtjaENrSWR4XTtcclxuICAgLy8gICAgICAgICAgICAgIGJ1ZkxlbiA9IGNoQ2hrLmxlbmd0aDtcclxuICAgLy8gICAgICAgICAgICAgIC8vbGV0IGNhY2hlSWQgPSB1dWlkICsgJ18nICsgY2ggKyAnXycgKyBjaENrSWR4O1xyXG4gICAvLyAgICAgICAgICAgICAgbGV0IGNoa0RiSWQgPSBbdGhpcy5yZWNVVUlELCB0aGlzLmluZERiQ2hrSWR4ICsgY2hDa0lkeCwgY2hdO1xyXG4gICAvLyAgICAgICAgICAgICAgbGV0IGNyID0gcmVjRmlsZU9ialN0b3JlLmFkZChjaENoaywgY2hrRGJJZCk7XHJcbiAgIC8vICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJBZGRlZDogXCIrY2grXCIgXCIrKHRoaXMuaW5kRGJDaGtJZHgrY2hDa0lkeCkpO1xyXG4gICAvLyAgICAgICAgICAgICAgY3Iub25zdWNjZXNzPSgpPT57XHJcbiAgIC8vICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlN0b3JlZCBhdWRpbyBkYXRhIHRvIGluZGV4ZWQgZGJcIik7XHJcbiAgIC8vICAgICAgICAgICAgICB9XHJcbiAgIC8vICAgICAgICAgICAgICBjci5vbmVycm9yPSgpPT57XHJcbiAgIC8vICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzdG9yaW5nIGF1ZGlvIGRhdGEgdG8gaW5kZXhlZCBkYlwiKTtcclxuICAgLy8gICAgICAgICAgICAgIH1cclxuICAgLy8gICAgICAgICAgICB9XHJcbiAgIC8vICAgICAgICAgICAgcG9zICs9IGJ1ZkxlbjtcclxuICAgLy8gICAgICAgIH1cclxuICAgLy8gICAgICAgIHRoaXMuaW5kRGJDaGtJZHgrPWRhdGFDaGtDbnQ7XHJcbiAgIC8vXHJcbiAgIC8vICAgICAgICB0ci5vbmVycm9yID0gKGVycikgPT4ge1xyXG4gICAvLyAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gY2FjaGUgYXVkaW8gZGF0YSB0byBpbmRleGVkIGRiOiAnICsgZXJyKVxyXG4gICAvLyAgICAgICAgfVxyXG4gICAvLyAgICAgICAgdHIub25jb21wbGV0ZSA9ICgpID0+IHtcclxuICAgLy8gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdUcmFuc2ZlcnJlZCBjYXB0dXJlIGF1ZGlvIGRhdGEgdG8gaW5kZXhlZCBkYiwgZGVsZXRpbmcgb3JpZ2luYWwgZGF0YSBmcm9tIG1lbW9yeS4uLicpO1xyXG4gICAvL1xyXG4gICAvLyAgICAgICAgICAvLy8gQXVkaW8gZGF0YSBzYXZlZCB0byBpbmRleCBkYiBkZWxldGUgZnJvbSBpbiBtZW1vcnkgZGF0YSBhcnJheVxyXG4gICAvLyAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgLy8gICAgICAgICAgIHRoaXMuZGF0YVtjaF0uc3BsaWNlKDApO1xyXG4gICAvLyAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlNwbGljZWQvcmVtb3ZlZCBjaDogXCIrY2gpO1xyXG4gICAvLyAgICAgICAgICB9XHJcbiAgIC8vXHJcbiAgIC8vICAgICAgICAgIHRoaXMucGVyc2lzdGVkPXRydWU7XHJcbiAgIC8vICAgICAgICAgIGlmKHRoaXMubGlzdGVuZXIgJiYgIXRoaXMuY2FwdHVyaW5nKXtcclxuICAgLy8gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdG9wcGVkIGJ5IGluZGV4ZWQgZGIgaG9va1wiKTtcclxuICAgLy8gICAgICAgICAgICB0aGlzLmxpc3RlbmVyLnN0b3BwZWQoKTtcclxuICAgLy8gICAgICAgICAgfVxyXG4gICAvLyAgICAgICAgfVxyXG4gICAvLyAgICAgICAgLy8gQ29tbWl0IGNodW5rc1xyXG4gICAvLyAgICAgICAgdGhpcy5wZXJzaXN0ZWQ9ZmFsc2U7XHJcbiAgIC8vICAgICAgICB0ci5jb21taXQoKTtcclxuICAgLy8gICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgLy8gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RyYW5zZmVyIGNhcHR1cmUgYXVkaW8gZGF0YSBlcnJvcjogJytlcnIpO1xyXG4gICAvLyAgICAgIH1cclxuICAgLy8gICAgfVxyXG5cclxuICAgIC8vIGlmKCF0aGlzLmluZGRiQXVkaW9CdWZmZXIgJiYgdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCAmJiB0aGlzLnJlY1VVSUQpIHtcclxuICAgIC8vICAgdGhpcy5pbmRkYkF1ZGlvQnVmZmVyID0gbmV3IEluZGV4ZWREYkF1ZGlvQnVmZmVyKHRoaXMuX3BlcnNpc3RlbnRBdWRpb1N0b3JhZ2VUYXJnZXQsIHRoaXMuY2hhbm5lbENvdW50LHRoaXMuY3VycmVudFNhbXBsZVJhdGUsQXVkaW9DYXB0dXJlLkJVRkZFUl9TSVpFLDAsdGhpcy5yZWNVVUlEKVxyXG4gICAgLy8gfVxyXG4gICAgaWYodGhpcy5pbmRkYkF1ZGlvQnVmZmVyICYmIHRoaXMuZGF0YSl7XHJcblxyXG4gICAgICAvLyBUcnkgdG8gYXBwZW5kIHRvXHJcbiAgICAgIHRoaXMuaW5kZGJBdWRpb0J1ZmZlci5hcHBlbmRSYXdBdWRpb0RhdGEodGhpcy5kYXRhKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoJ1RyYW5zZmVycmVkIGNhcHR1cmUgYXVkaW8gZGF0YSB0byBpbmRleGVkIGRiLCBkZWxldGluZyBvcmlnaW5hbCBkYXRhIGZyb20gbWVtb3J5Li4uJyk7XHJcblxyXG4gICAgICAgICAgLy8vIEF1ZGlvIGRhdGEgc2F2ZWQgdG8gaW5kZXggZGIgZGVsZXRlIGZyb20gaW4gbWVtb3J5IGRhdGEgYXJyYXlcclxuICAgICAgICAgIGlmKHRoaXMuZGF0YSkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgICAgICAgICB0aGlzLmRhdGFbY2hdLnNwbGljZSgwKTtcclxuICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTcGxpY2VkL3JlbW92ZWQgY2g6IFwiK2NoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy5wZXJzaXN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgaWYgKHRoaXMubGlzdGVuZXIgJiYgIXRoaXMuY2FwdHVyaW5nKSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIlN0b3BwZWQgYnkgaW5kZXhlZCBkYiBob29rXCIpO1xyXG4gICAgICAgICAgICB0aGlzLmxpc3RlbmVyLnN0b3BwZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LGVycm9yOihlcnIpPT57XHJcbiAgICAgICAgICAvLyBPbmx5IGxvZyB0aGUgZmlyc3QgZXJyb3JcclxuICAgICAgICAgIGlmKCF0aGlzLnBlcnNpc3RFcnJvcikge1xyXG4gICAgICAgICAgICB0aGlzLnBlcnNpc3RFcnJvciA9IGVycjtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHBlcnNpc3RpbmcgYXVkaW8gZGF0YTogXCIgKyBlcnIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMucGVyc2lzdGVkPWZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIGNsb3NlKCkge1xyXG4gICAgaWYodGhpcy5tZWRpYVN0cmVhbSkge1xyXG4gICAgICB0aGlzLm1lZGlhU3RyZWFtLmRpc2Nvbm5lY3QoKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnN0cmVhbSkge1xyXG4gICAgICBjb25zdCBtdHMgPSB0aGlzLnN0cmVhbS5nZXRUcmFja3MoKTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBtdHNbaV0uc3RvcCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLl9vcGVuZWQ9ZmFsc2U7XHJcbiAgfVxyXG5cclxuICBhdWRpb0J1ZmZlcigpOiBBdWRpb0J1ZmZlciB8bnVsbHtcclxuICAgIGxldCBhYjogQXVkaW9CdWZmZXJ8bnVsbD1udWxsO1xyXG4gICAgaWYodGhpcy5kYXRhKSB7XHJcbiAgICAgIGxldCBmcmFtZUxlbjogbnVtYmVyID0gMDtcclxuXHJcbiAgICAgIGxldCBjaDBEYXRhID0gdGhpcy5kYXRhWzBdO1xyXG5cclxuICAgICAgZm9yIChsZXQgY2gwQ2hrIG9mIGNoMERhdGEpIHtcclxuICAgICAgICBmcmFtZUxlbiArPSBjaDBDaGsubGVuZ3RoO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGFiID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJ1ZmZlcih0aGlzLmNoYW5uZWxDb3VudCwgZnJhbWVMZW4sIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcclxuICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIERPTUV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgaWYgKGVyci5uYW1lID09PSAnTm90U3VwcG9ydGVkRXJyb3InKSB7XHJcbiAgICAgICAgICAgIGlmIChmcmFtZUxlbiA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgLy8gRW1wdHkgYnVmZmVycyBhcmUgbm90IHN1cHBvcnRlZCBieSBDaHJvbWl1bVxyXG4gICAgICAgICAgICAgIC8vIENyZWF0ZSBkdW1teSBidWZmZXIgd2l0aCBvbmUgc2FtcGxlXHJcbiAgICAgICAgICAgICAgYWIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyKHRoaXMuY2hhbm5lbENvdW50LCAxLCB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSB7XHJcbiAgICAgICAgICAvLyBPdXQgb2YgbWVtb3J5XHJcbiAgICAgICAgICAvLyBUT0RPIFdoYXQgdG8gZG8gPz9cclxuICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgICBsZXQgY2hEID0gYWIuZ2V0Q2hhbm5lbERhdGEoY2gpO1xyXG4gICAgICAgIGxldCBwb3MgPSAwO1xyXG4gICAgICAgIGZvciAobGV0IGNoQ2hrIG9mIHRoaXMuZGF0YVtjaF0pIHtcclxuICAgICAgICAgIGxldCBidWZMZW4gPSBjaENoay5sZW5ndGg7XHJcbiAgICAgICAgICBjaEQuc2V0KGNoQ2hrLCBwb3MpO1xyXG4gICAgICAgICAgcG9zICs9IGJ1ZkxlbjtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBhYjtcclxuICB9XHJcblxyXG4gIGF1ZGlvQnVmZmVyQXJyYXkoKTpBcnJheUF1ZGlvQnVmZmVyfG51bGx7XHJcbiAgICAgIGxldCBhcnJBYjpBcnJheUF1ZGlvQnVmZmVyfG51bGw9bnVsbDtcclxuICAgICAgaWYodGhpcy5kYXRhKSB7XHJcbiAgICAgICAgYXJyQWI9bmV3IEFycmF5QXVkaW9CdWZmZXIodGhpcy5jaGFubmVsQ291bnQsIHRoaXMuY3VycmVudFNhbXBsZVJhdGUsIHRoaXMuZGF0YSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGFyckFiO1xyXG4gIH1cclxuXHJcbiAgaW5kZGJBdWRpb0J1ZmZlckFycmF5KCk6SW5kZXhlZERiQXVkaW9CdWZmZXJ8bnVsbHtcclxuICAgIGlmKHRoaXMucGVyc2lzdEVycm9yKXtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9ZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmluZGRiQXVkaW9CdWZmZXI7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbn1cclxuXHJcbiJdfQ==
|
|
855
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwdHVyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9jYXB0dXJlL2NhcHR1cmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQXlCLFFBQVEsSUFBSSxXQUFXLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUN0SCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxFQUFDLG9CQUFvQixFQUErQixNQUFNLHVCQUF1QixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUdoRCxNQUFNLENBQUMsTUFBTSwwQ0FBMEMsR0FBQyxLQUFLLENBQUM7QUFFOUQsTUFBTSxpQkFBaUIsR0FBQyxDQUFDLENBQUM7QUFFMUIsZ0NBQWdDO0FBQ2hDLHdEQUF3RDtBQUN4RCxNQUFNLE1BQU0sR0FBQyx5RUFBeUU7SUFDbEYsSUFBSTtJQUNKLDJCQUEyQjtJQUMzQiw4QkFBOEI7SUFDOUIscUVBQXFFO0lBQ3JFLG9CQUFvQjtJQUNwQixvQkFBb0I7SUFDcEIseUJBQXlCO0lBQ3pCLHVCQUF1QjtJQUN2QixvQkFBb0I7SUFDcEIsSUFBSTtJQUNKLFNBQVM7SUFDVCxJQUFJO0lBQ0osYUFBYTtJQUNiLGlCQUFpQjtJQUNqQixrQkFBa0I7SUFDbEIsb0JBQW9CO0lBQ3BCLFFBQVE7SUFDUixJQUFJO0lBQ0oscUNBQXFDO0lBQ3JDLDRCQUE0QjtJQUM1Qix3QkFBd0I7SUFDeEIsNkJBQTZCO0lBQzdCLDBCQUEwQjtJQUMxQixvQ0FBb0M7SUFDcEMsMENB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T3V0U3RyZWFtfSBmcm9tIFwiLi4vaW8vc3RyZWFtXCI7XHJcbmltcG9ydCB7QnJvd3NlciwgUGxhdGZvcm0sIFVzZXJBZ2VudEJ1aWxkZXJ9IGZyb20gXCIuLi8uLi91dGlscy91YS1wYXJzZXJcIjtcclxuXHJcbmltcG9ydCB7QXVkaW9TdG9yYWdlVHlwZSwgQXV0b0dhaW5Db250cm9sQ29uZmlnLCBQbGF0Zm9ybSBhcyBDZmdQbGF0Zm9ybX0gZnJvbSBcIi4uLy4uL3NwZWVjaHJlY29yZGVyL3Byb2plY3QvcHJvamVjdFwiO1xyXG5pbXBvcnQge0FycmF5QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJcIjtcclxuaW1wb3J0IHtVVUlEfSBmcm9tIFwiLi4vLi4vdXRpbHMvdXRpbHNcIjtcclxuaW1wb3J0IHtJbmRleGVkRGJBdWRpb0J1ZmZlciwgUGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldH0gZnJvbSBcIi4uL2luZGRiX2F1ZGlvX2J1ZmZlclwiO1xyXG5pbXBvcnQge0F1ZGlvQ29udGV4dFByb3ZpZGVyfSBmcm9tIFwiLi4vY29udGV4dFwiO1xyXG5cclxuXHJcbmV4cG9ydCBjb25zdCBDSFJPTUVfQUNUSVZBVEVfRUNIT19DQU5DRUxMQVRJT05fV0lUSF9BR0M9ZmFsc2U7XHJcblxyXG5jb25zdCBERUJVR19UUkFDRV9MRVZFTD0wO1xyXG5cclxuLy8gRGlydHkgd2F5IHRvIGxvYWQgdGhpcyBtb2R1bGVcclxuLy8gQ29weSBjb250ZW50IG9mIGludGVyY2VwdG9yX3dvcmtsZXQuanMgdG8gdGhpcyBzdHJpbmdcclxuY29uc3QgYXdwU3RyPVwiY2xhc3MgQXVkaW9DYXB0dXJlSW50ZXJjZXB0b3JQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICBCVUZGRVJfUVVBTlRVTVM9NjQ7XFxuXCIgK1xyXG4gICAgXCIgICAgUVVBTlRVTV9GUkFNRV9MRU49MTI4O1xcblwiICtcclxuICAgIFwiICAgIEJVRkZFUl9GUkFNRV9MRU49dGhpcy5RVUFOVFVNX0ZSQU1FX0xFTip0aGlzLkJVRkZFUl9RVUFOVFVNUztcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXI9bnVsbDtcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXJQb3M9MDtcXG5cIiArXHJcbiAgICBcIiAgICBidWZmZXJQb3NCeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgIGNvbnN0cnVjdG9yKCkge1xcblwiICtcclxuICAgIFwiICAgICAgICBzdXBlcigpO1xcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgICAgfVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCIgcHJvY2VzcyhcXG5cIiArXHJcbiAgICBcIiAgICAgIGlucHV0cyxcXG5cIiArXHJcbiAgICBcIiAgICAgIG91dHB1dHMsXFxuXCIgK1xyXG4gICAgXCIgICAgICBwYXJhbWV0ZXJzXFxuXCIgK1xyXG4gICAgXCIgICl7XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICAgbGV0IGlucHV0c0NudD1pbnB1dHMubGVuZ3RoO1xcblwiICtcclxuICAgIFwiICAgICBsZXQgY2hhbm5lbENvdW50PTA7XFxuXCIgK1xyXG4gICAgXCIgICAgIGxldCBpbnB1dExlbj0wO1xcblwiICtcclxuICAgIFwiICAgICBsZXQgaW5wdXRMZW5CeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgICBpZihpbnB1dHNDbnQ+MCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgbGV0IGlucHV0MCA9IGlucHV0c1swXTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIGNoYW5uZWxDb3VudCA9IGlucHV0MC5sZW5ndGg7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICBpZiAoY2hhbm5lbENvdW50ID4gMCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGxldCBpbnB1dDBjaDA9aW5wdXQwWzBdO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGlucHV0TGVuPWlucHV0MGNoMC5sZW5ndGg7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgaW5wdXRMZW5CeXRlcz1pbnB1dDBjaDAuYnVmZmVyLmxlbmd0aDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgICBpZiAoIXRoaXMuYnVmZmVyIHx8IHRoaXMuYnVmZmVyLmxlbmd0aCA8IGNoYW5uZWxDb3VudCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgQXJyYXkoY2hhbm5lbENvdW50KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIHRoaXMuYnVmZmVyUG9zID0gMFxcblwiICtcclxuICAgIFwiICAgICAgICAgZm9yIChsZXQgYmNoID0gMDsgYmNoIDwgY2hhbm5lbENvdW50OyBiY2grKykge1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIHRoaXMuYnVmZmVyW2JjaF0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuQlVGRkVSX0ZSQU1FX0xFTik7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgdGhpcy5idWZmZXJQb3MgPSAwO1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIHRoaXMuYnVmZmVyUG9zQnl0ZXM9MDtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIH1cXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgICBsZXQgYnVmQXZhaWwgPSB0aGlzLkJVRkZFUl9GUkFNRV9MRU4gLSB0aGlzLmJ1ZmZlclBvcztcXG5cIiArXHJcbiAgICBcIiAgICAgLy8gY2hlY2sgaWYgYnVmZmVyIGhhcyB0byBiZSB0cmFuc2ZlcnJlZFxcblwiICtcclxuICAgIFwiICAgICBpZiAoaW5wdXRMZW4gPiBidWZBdmFpbCkge1xcblwiICtcclxuICAgIFwiICAgICAgICAgbGV0IGFkYT1uZXcgQXJyYXkoY2hhbm5lbENvdW50KTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaGFubmVsQ291bnQ7IGNoKyspIHtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBhZGFbY2hdPXRoaXMuYnVmZmVyW2NoXS5idWZmZXIuc2xpY2UoMCk7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB9XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe1xcblwiICtcclxuICAgIFwiICAgICAgICAgICAgIGRhdGE6IGFkYSxcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBjaHM6IGNoYW5uZWxDb3VudCxcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBsZW46IHRoaXMuYnVmZmVyUG9zXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICB9LCBhZGEpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgLy8gYnVmZmVyIHRyYW5zZmVycmVkLCByZXNldFxcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3MgPSAwO1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3NCeXRlcz0wO1xcblwiICtcclxuICAgIFwiICAgICB9XFxuXCIgK1xyXG4gICAgXCJcXG5cIiArXHJcbiAgICBcIiAgICAgZm9yKGxldCBpaT0wO2lpPGlucHV0c0NudDtpaSsrKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hhbm5lbENvdW50OyBjaCsrKSB7XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgLy8gTXV0ZSBvdXRwdXRzXFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgLy9vdXRwdXRzW2lpXVtjaF0uZmlsbCgwKTtcXG5cIiArXHJcbiAgICBcIiAgICAgICAgICAgICBsZXQgY2hTYW1wbGVzID0gaW5wdXRzW2lpXVtjaF07XFxuXCIgK1xyXG4gICAgXCIgICAgICAgICAgICAgdGhpcy5idWZmZXJbY2hdLnNldChjaFNhbXBsZXMsdGhpcy5idWZmZXJQb3MpO1xcblwiICtcclxuICAgIFwiICAgICAgICAgfVxcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3MrPWlucHV0TGVuO1xcblwiICtcclxuICAgIFwiICAgICAgICAgdGhpcy5idWZmZXJQb3NCeXRlcys9aW5wdXRMZW5CeXRlcztcXG5cIiArXHJcbiAgICBcIiAgICAgfVxcblwiICtcclxuICAgIFwiICAgIFxcblwiICtcclxuICAgIFwiICAgICByZXR1cm4gdHJ1ZTtcXG5cIiArXHJcbiAgICBcIiAgfVxcblwiICtcclxuICAgIFwifVxcblwiICtcclxuICAgIFwiXFxuXCIgK1xyXG4gICAgXCJyZWdpc3RlclByb2Nlc3NvcignY2FwdHVyZS1pbnRlcmNlcHRvcicsQXVkaW9DYXB0dXJlSW50ZXJjZXB0b3JQcm9jZXNzb3IpO1xcblwiO1xyXG5cclxuXHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBBdWRpb0NhcHR1cmVMaXN0ZW5lciB7XHJcbiAgb3BlbmVkKCk6IHZvaWQ7XHJcblxyXG4gIHN0YXJ0ZWQoKTogdm9pZDtcclxuXHJcbiAgc3RvcHBlZCgpOiB2b2lkO1xyXG5cclxuICBjbG9zZWQoKTogdm9pZDtcclxuXHJcbiAgZXJyb3IobXNnPzpzdHJpbmcsYWR2aWNlPzpzdHJpbmcpOiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQXVkaW9DYXB0dXJlIHtcclxuXHJcbiAgZ2V0IG1heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9tYXhBdXRvTmV0TWVtU3RvcmVTYW1wbGVzO1xyXG4gIH1cclxuXHJcbiAgc2V0IG1heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXModmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5fbWF4QXV0b05ldE1lbVN0b3JlU2FtcGxlcyA9IHZhbHVlO1xyXG4gIH1cclxuICBzZXQgcmVjVVVJRCh2YWx1ZTogc3RyaW5nfG51bGwpIHtcclxuICAgIHRoaXMuX3JlY1VVSUQgPSB2YWx1ZTtcclxuICB9XHJcbiAgZ2V0IHJlY1VVSUQoKTogc3RyaW5nIHxudWxse1xyXG4gICAgcmV0dXJuIHRoaXMuX3JlY1VVSUQ7XHJcbiAgfVxyXG4gIGdldCBhdWRpb1N0b3JhZ2VUeXBlKCk6IEF1ZGlvU3RvcmFnZVR5cGUge1xyXG4gICAgcmV0dXJuIHRoaXMuX2F1ZGlvU3RvcmFnZVR5cGU7XHJcbiAgfVxyXG5cclxuICBzZXQgYXVkaW9TdG9yYWdlVHlwZSh2YWx1ZTogQXVkaW9TdG9yYWdlVHlwZSkge1xyXG4gICAgdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSA9IHZhbHVlO1xyXG4gIH1cclxuICBnZXQgcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCgpOiBQZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0IHwgbnVsbCB7XHJcbiAgICByZXR1cm4gdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldDtcclxuICB9XHJcblxyXG4gIHNldCBwZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0KHZhbHVlOiBQZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0IHwgbnVsbCkge1xyXG4gICAgdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCA9IHZhbHVlO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldCBvcGVuZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fb3BlbmVkO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIEJVRkZFUl9TSVpFOiBudW1iZXIgPSA4MTkyO1xyXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfTUFYX05FVF9BVVRPX01FTV9TVE9SRV9TQU1QTEVTOm51bWJlcj0yODgwMDAwKjU7IC8vIERlZmF1bHQgNSBtaW51dGUgYXQgNDhrSHpcclxuICBwcml2YXRlIF9tYXhBdXRvTmV0TWVtU3RvcmVTYW1wbGVzOm51bWJlcj1BdWRpb0NhcHR1cmUuREVGQVVMVF9NQVhfTkVUX0FVVE9fTUVNX1NUT1JFX1NBTVBMRVM7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgY2FwdHVyZUludGVyY2VwdG9yTW9kdWxlUmVnaXN0ZXJlZD1mYWxzZTtcclxuICBjb250ZXh0OiBBdWRpb0NvbnRleHR8bnVsbD1udWxsO1xyXG4gIHN0cmVhbSE6IE1lZGlhU3RyZWFtO1xyXG4gIGNoYW5uZWxDb3VudCE6IG51bWJlcjtcclxuICBwcml2YXRlIF9yZWNVVUlEOnN0cmluZ3xudWxsPW51bGw7XHJcbiAgbWVkaWFTdHJlYW06IGFueTtcclxuICBhZ2NTdGF0dXM6Ym9vbGVhbnxudWxsPW51bGw7XHJcbiAgYnVmZmVyaW5nTm9kZTogQXVkaW9Ob2RlfG51bGw9bnVsbDtcclxuICBsaXN0ZW5lciE6IEF1ZGlvQ2FwdHVyZUxpc3RlbmVyO1xyXG4gIGRhdGE6IEFycmF5PEFycmF5PEZsb2F0MzJBcnJheT4+fG51bGw9bnVsbDtcclxuICBjdXJyZW50U2FtcGxlUmF0ZSE6IG51bWJlcjtcclxuICBuOiBOYXZpZ2F0b3I7XHJcbiAgYXVkaW9PdXRTdHJlYW06IFNlcXVlbmNlQXVkaW9GbG9hdDMyT3V0U3RyZWFtIHwgbnVsbD1udWxsO1xyXG4gIHByaXZhdGUgZGlzY29ubmVjdFN0cmVhbXMgPSB0cnVlO1xyXG4gIHByaXZhdGUgX29wZW5lZD1mYWxzZTtcclxuICBwcml2YXRlIGNhcHR1cmluZyA9IGZhbHNlO1xyXG5cclxuICBmcmFtZXNSZWNvcmRlZDogbnVtYmVyPTA7XHJcblxyXG4gIHByaXZhdGUgX2F1ZGlvU3RvcmFnZVR5cGU6QXVkaW9TdG9yYWdlVHlwZT1BdWRpb1N0b3JhZ2VUeXBlLk1FTV9FTlRJUkU7XHJcbiAgcHJpdmF0ZSBfcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldDpQZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0fG51bGw9bnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBwZXJzaXN0ZWQ9dHJ1ZTtcclxuICBwcml2YXRlIHBlcnNpc3RFcnJvcjpFcnJvcnxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBpbmRkYkF1ZGlvQnVmZmVyOkluZGV4ZWREYkF1ZGlvQnVmZmVyfG51bGw9bnVsbDtcclxuXHJcbiAgLy9wcml2YXRlIGNvbnRleHQ6QXVkaW9Db250ZXh0fG51bGw9bnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLm4gPSBuYXZpZ2F0b3I7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9hdWRpb0NvbnRleHQoKTpBdWRpb0NvbnRleHR8bnVsbHtcclxuICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICB0aGlzLmNvbnRleHQ9QXVkaW9Db250ZXh0UHJvdmlkZXIuYXVkaW9Db250ZXh0SW5zdGFuY2UoKTtcclxuICAgICAgaWYodGhpcy5jb250ZXh0KSB7XHJcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICAgICAgaWYgKHRoaXMuY29udGV4dCAmJiB0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdydW5uaW5nJykge1xyXG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNvbnRleHQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXREYXRhKCkge1xyXG4gICAgaWYoIXRoaXMuX3JlY1VVSUQpIHtcclxuICAgICAgdGhpcy5fcmVjVVVJRCA9IFVVSUQuZ2VuZXJhdGUoKTtcclxuICAgIH1cclxuICAgIHRoaXMucGVyc2lzdEVycm9yPW51bGw7XHJcbiAgICAvL2NvbnNvbGUuZGVidWcoXCJBdWRpbyBjYXB0dXJlIGluaXRpYWxpemUgc3RvcmFnZSBmb3IgdHlwZTogXCIrdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSk7XHJcbiAgICBpZihBdWRpb1N0b3JhZ2VUeXBlLkRCX0NIVU5LRUQgPT09IHRoaXMuX2F1ZGlvU3RvcmFnZVR5cGUgJiYgdGhpcy5fcGVyc2lzdGVudEF1ZGlvU3RvcmFnZVRhcmdldCAmJiB0aGlzLl9yZWNVVUlEKSB7XHJcbiAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkNyZWF0ZSBpbmRleGVkIGRiIGF1ZGlvIGJ1ZmZlci5cIik7XHJcbiAgICAgIHRoaXMuaW5kZGJBdWRpb0J1ZmZlciA9IG5ldyBJbmRleGVkRGJBdWRpb0J1ZmZlcih0aGlzLl9wZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0LCB0aGlzLmNoYW5uZWxDb3VudCx0aGlzLmN1cnJlbnRTYW1wbGVSYXRlLEF1ZGlvQ2FwdHVyZS5CVUZGRVJfU0laRSwwLHRoaXMuX3JlY1VVSUQpXHJcbiAgICB9XHJcbiAgICBpZighKEF1ZGlvU3RvcmFnZVR5cGUuTkVUX0NIVU5LRUQgPT09IHRoaXMuX2F1ZGlvU3RvcmFnZVR5cGUpKSB7XHJcbiAgICAgIC8vIEluaXRpYWxpemUgYXVkaW8gZGF0YSBhcnJheSBleGNlcHQgZm9yIG5ldCBhdWRpbyBidWZmZXIgbW9kZVxyXG4gICAgICB0aGlzLmRhdGEgPSBuZXcgQXJyYXk8QXJyYXk8RmxvYXQzMkFycmF5Pj4oKTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoYW5uZWxDb3VudDsgaSsrKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhLnB1c2gobmV3IEFycmF5PEZsb2F0MzJBcnJheT4oKSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuZnJhbWVzUmVjb3JkZWQgPSAwO1xyXG4gIH1cclxuXHJcbiAgbGlzdERldmljZXMoKSB7XHJcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChsOiBNZWRpYURldmljZUluZm9bXSkgPT4gdGhpcy5wcmludERldmljZXMobCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkdW1teVNlc3Npb24oKTpQcm9taXNlPE1lZGlhU3RyZWFtPntcclxuICAgIC8vIHdvcmthcm91bmQgdG8gcmVxdWVzdCBwZXJtaXNzaW9uczpcclxuICAgIC8vIFN0YXJ0IGEgZHVtbXkgc2Vzc2lvblxyXG4gICAgbGV0IG1lZGlhU3RyQ25zdHJzID0gPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+e2F1ZGlvOlxyXG4gICAgICAgIHtlY2hvQ2FuY2VsYXRpb246IGZhbHNlfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShtZWRpYVN0ckNuc3Rycyk7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgc3RvcEFsbFNlc3Npb25UcmFja3MobWVkaWFTdHJlYW06TWVkaWFTdHJlYW0pe1xyXG4gICAgICBsZXQgYXRzID0gbWVkaWFTdHJlYW0uZ2V0VHJhY2tzKCk7XHJcbiAgICAgIGZvciAobGV0IGF0SWR4ID0gMDsgYXRJZHggPCBhdHMubGVuZ3RoOyBhdElkeCsrKSB7XHJcbiAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiU3RvcCBkdW1teSBzZXNzaW9uIHRyYWNrOiAjXCIgKyBhdElkeClcclxuICAgICAgICBhdHNbYXRJZHhdLnN0b3AoKTtcclxuICAgICAgfVxyXG4gIH1cclxuXHJcbiAgZGV2aWNlSW5mb3MoY2I6IChkZXZpY2VJbmZvczogTWVkaWFEZXZpY2VJbmZvW10gfCBudWxsKSA9PiBhbnksIHJldHJ5ID0gdHJ1ZSxkdW1teVN0cmVhbT86TWVkaWFTdHJlYW0pIHtcclxuXHJcbiAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChsOiBNZWRpYURldmljZUluZm9bXSkgPT4ge1xyXG4gICAgICBsZXQgbGFiZWxzQXZhaWxhYmxlID0gZmFsc2U7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBkaSA9IGxbaV07XHJcbiAgICAgICAgaWYgKGRpLmxhYmVsKSB7XHJcbiAgICAgICAgICBsYWJlbHNBdmFpbGFibGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBpZiAoIWxhYmVsc0F2YWlsYWJsZSkge1xyXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIk1lZGlhIGRldmljZSBlbnVtZXJhdGlvbjogTm8gbGFiZWxzLlwiKVxyXG4gICAgICAgIGlmIChyZXRyeSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmluZm8oXCJTdGFydGluZyBkdW1teSBzZXNzaW9uIHRvIHJlcXVlc3QgYXVkaW8gcGVybWlzc2lvbnMuLi5cIilcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZHVtbXlTZXNzaW9uKCkudGhlbigoczogTWVkaWFTdHJlYW0pID0+IHtcclxuICAgICAgICAgICAgLy8gYW5kIHN0b3AgaXQgaW1tZWRpYXRlbHlcclxuXHJcbiAgICAgICAgICAgIGlmKHMpIHtcclxuICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJHb3QgZHVtbXkgc2Vzc2lvbiBzdHJlYW06IFwiICsgcyArIFwiIC5cIilcclxuICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiTm8gZHVtbXkgc3RyZWFtXCIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcmV0cnkgKG9ubHkgb25jZSlcclxuICAgICAgICAgICAgdGhpcy5kZXZpY2VJbmZvcyhjYiwgZmFsc2Uscyk7XHJcbiAgICAgICAgICB9LHJlYXNvbiA9PiB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkR1bW15IHNlc3Npb24gcmVqZWN0ZWQuXCIpXHJcbiAgICAgICAgICAgIC8vIFRPRE8gZXJyb3IgY2FsbGJhY2tcclxuICAgICAgICAgICAgY2IobnVsbCk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY2IobnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIHN1Y2Nlc3NcclxuICAgICAgICBjYihsKTtcclxuICAgICAgfVxyXG4gICAgICBpZihkdW1teVN0cmVhbSl7XHJcbiAgICAgICAgdGhpcy5zdG9wQWxsU2Vzc2lvblRyYWNrcyhkdW1teVN0cmVhbSk7XHJcbiAgICAgIH1cclxuICAgIH0sKHJlYXNvbik9PiB7XHJcbiAgICAgIC8vcmVqZWN0ZWRcclxuICAgICAgLy9jb25zb2xlLmRlYnVnKFwiTWVkaWEgZGV2aWNlIGVudW1lcmF0aW9uIHJlamVjdGVkLlwiKVxyXG4gICAgICBpZiAocmV0cnkpIHtcclxuICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdGFydGluZyBkdW1teSBzZXNzaW9uIHRvIHJlcXVlc3QgYXVkaW8gcGVybWlzc2lvbnMuLi5cIilcclxuICAgICAgICB0aGlzLmR1bW15U2Vzc2lvbigpLnRoZW4oKHM6IE1lZGlhU3RyZWFtKSA9PiB7XHJcbiAgICAgICAgICAvLyBhbmQgc3RvcCBpdCBpbW1lZGlhdGVseVxyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiRHVtbXkgc2Vzc2lvbi5cIilcclxuICAgICAgICAgIGlmKHMpIHtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiR290IGR1bW15IHNlc3Npb24gc3RyZWFtOiBcIiArIHMgKyBcIiAuXCIpXHJcbiAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiTm8gZHVtbXkgc3RyZWFtXCIpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvLyByZXRyeSAob25seSBvbmNlKVxyXG4gICAgICAgICAgdGhpcy5kZXZpY2VJbmZvcyhjYiwgZmFsc2Uscyk7XHJcbiAgICAgICAgfSwgcmVhc29uID0+IHtcclxuICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkR1bW15IHNlc3Npb24gcmVqZWN0ZWQuXCIpXHJcbiAgICAgICAgICAvLyBUT0RPIGVycm9yIGNhbGxiYWNrXHJcbiAgICAgICAgICBjYihudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjYihudWxsKTtcclxuICAgICAgfVxyXG4gICAgICBpZihkdW1teVN0cmVhbSl7XHJcbiAgICAgICAgdGhpcy5zdG9wQWxsU2Vzc2lvblRyYWNrcyhkdW1teVN0cmVhbSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIHByaW50RGV2aWNlcyhsOiBNZWRpYURldmljZUluZm9bXSk6IHZvaWQge1xyXG4gICAgLy9sZXQgc2VsRGV2aWNlSWQgPSAnX19fZHVtbXlfX18nO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGxldCBkaSA9IGxbaV07XHJcbiAgICAgIGNvbnNvbGUubG9nKFwiQXVkaW8gZGV2aWNlOiBJZDogXCIgKyBkaS5kZXZpY2VJZCArIFwiIGdyb3VwSWQ6IFwiICsgZGkuZ3JvdXBJZCArIFwiIGxhYmVsOiBcIiArIGRpLmxhYmVsICsgXCIga2luZDogXCIgKyBkaS5raW5kKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFkZENhcHR1cmVJbnRlcmNlcHRvcigpIHtcclxuICAgIGlmICh0aGlzLmNvbnRleHQpIHtcclxuXHJcbiAgICBjb25zdCBhd24gPSBuZXcgQXVkaW9Xb3JrbGV0Tm9kZSh0aGlzLmNvbnRleHQsICdjYXB0dXJlLWludGVyY2VwdG9yJyk7XHJcbiAgICBhd24ub25wcm9jZXNzb3JlcnJvciA9IChldjogRXZlbnQpID0+IHtcclxuICAgICAgbGV0IG1zZyA9ICdVbmtud29uIGVycm9yJztcclxuICAgICAgaWYgKGV2IGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAgIG1zZyA9IGV2Lm1lc3NhZ2U7XHJcbiAgICAgIH1cclxuICAgICAgY29uc29sZS5lcnJvcihcIkNhcHR1cmUgYXVkaW8gd29ya2xldCBlcnJvcjogXCIgKyBtc2cpO1xyXG4gICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IobXNnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgbGV0IGF3blB0ID0gYXduLnBvcnQ7XHJcbiAgICBpZiAoYXduUHQpIHtcclxuICAgICAgYXduUHQub25tZXNzYWdlID0gKGV2OiBNZXNzYWdlRXZlbnQpID0+IHtcclxuICAgICAgICBpZiAodGhpcy5jYXB0dXJpbmcpIHtcclxuICAgICAgICAgIGxldCBkdCA9IGV2LmRhdGE7XHJcbiAgICAgICAgICBsZXQgY2hzID0gZHQuY2hzO1xyXG4gICAgICAgICAgbGV0IGFkYUxlbiA9IGR0LmRhdGEubGVuZ3RoO1xyXG4gICAgICAgICAgaWYgKERFQlVHX1RSQUNFX0xFVkVMID4gOCkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnKCdSZWNlaXZlZCBkYXRhIGZyb20gd29ya2xldDogJyArIGNocyArICcgJyArIGR0LmxlbiArICcgRGF0YSBjaHM6ICcgKyBhZGFMZW4pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGV0IGNodW5rID0gbmV3IEFycmF5PEZsb2F0MzJBcnJheT4oY2hzKTtcclxuICAgICAgICAgIGNvbnN0IHNhbXBsZXMgPSB0aGlzLmZyYW1lc1JlY29yZGVkICogY2hzO1xyXG4gICAgICAgICAgaWYgKChBdWRpb1N0b3JhZ2VUeXBlLk1FTV9FTlRJUkVfQVVUT19ORVRfQ0hVTktFRCA9PT0gdGhpcy5hdWRpb1N0b3JhZ2VUeXBlIHx8IEF1ZGlvU3RvcmFnZVR5cGUuTUVNX0NIVU5LRURfQVVUT19ORVRfQ0hVTktFRCA9PT0gdGhpcy5hdWRpb1N0b3JhZ2VUeXBlKSAmJiB0aGlzLmRhdGEgJiYgc2FtcGxlcyA+IHRoaXMuX21heEF1dG9OZXRNZW1TdG9yZVNhbXBsZXMpIHtcclxuICAgICAgICAgICAgdGhpcy5kYXRhID0gbnVsbDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJEYXRhIGluaXRpYWxpemVkOiBcIisodGhpcy5kYXRhIT1udWxsKSk7XHJcbiAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgY2hzOyBjaCsrKSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkRhdGEgY2ggaW5pdGlhbGl6ZWQ6IFwiKyh0aGlzLmRhdGEgIT1udWxsICYmIHRoaXMuZGF0YVtjaF0gIT1udWxsKSk7XHJcbiAgICAgICAgICAgIGlmIChjaCA8IHRoaXMuY2hhbm5lbENvdW50KSB7XHJcbiAgICAgICAgICAgICAgaWYgKGR0LmRhdGFbY2hdKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgZmEgPSBuZXcgRmxvYXQzMkFycmF5KGR0LmRhdGFbY2hdKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhW2NoXSkge1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLmRhdGFbY2hdLnB1c2goZmEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2h1bmtbY2hdID0gZmE7XHJcbiAgICAgICAgICAgICAgICAvLyBVc2Ugc2FtcGxlcyBvZiBjaGFubmVsIDAgdG8gY291bnQgZnJhbWVzIChzYW1wbGVzKVxyXG4gICAgICAgICAgICAgICAgaWYgKGNoID09IDApIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5mcmFtZXNSZWNvcmRlZCArPSBmYS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAodGhpcy5hdWRpb091dFN0cmVhbSkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgIHRoaXMuYXVkaW9PdXRTdHJlYW0ud3JpdGUoY2h1bmspO1xyXG4gICAgICAgICAgICAgIC8vIC8vIFJhbmRvbSB0ZXN0IGVycm9yOlxyXG4gICAgICAgICAgICAgIC8vIGlmKE1hdGgucmFuZG9tKCk+MC45OCkge1xyXG4gICAgICAgICAgICAgIC8vICAgdGhyb3cgbmV3IEVycm9yKCdUZXN0Jyk7XHJcbiAgICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucGVyc2lzdEVycm9yID0gZXJyO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RFcnJvciA9IG5ldyBFcnJvcignRXJyb3IgaGFuZGxpbmcgcmVjb3JkZWQgYXVkaW8gZGF0YScpO1xyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkNhcHR1cmUgZXJyb3I6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9wKCk7XHJcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyMikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkNhcHR1cmUgbmV4dCBlcnJvciAoaWdub3JlZCk6IFwiICsgZXJyMik7XHJcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgIGxldCBlcnJFeHBsID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBET01FeGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJFeHBsID0gJzogJyArIGVyci5uYW1lICsgJzogJyArIGVyci5tZXNzYWdlO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoXCJDb3VsZCBub3QgaGFuZGxlIHJlY29yZGVkIGF1ZGlvIGRhdGFcIiArIGVyckV4cGwsIFwiUGxlYXNlIHRyeSB0byByZWNvcmQgYWdhaW4uXCIpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKEF1ZGlvU3RvcmFnZVR5cGUuREJfQ0hVTktFRCA9PT0gdGhpcy5fYXVkaW9TdG9yYWdlVHlwZSAmJiB0aGlzLl9wZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RvcmUoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgICAvLyBUcmllZCB0byBmaXggdGhhdCBTYWZhcmkgZG9lcyBub3QgcmVjb3JkIHRoZSBzZWNvbmQgY2hhbm5lbFxyXG4gICAgLy8gRG9lcyBub3QgaGVscFxyXG4gICAgLy9hd24uY2hhbm5lbENvdW50PXRoaXMuY2hhbm5lbENvdW50O1xyXG4gICAgLy9hd24uY2hhbm5lbENvdW50TW9kZT0nZXhwbGljaXQnO1xyXG4gICAgLy9jb25zb2xlLmRlYnVnKCdDaGFubmVsIGNvdW50IGV4cGxpY2l0bHkgc2V0IHRvICcrdGhpcy5jaGFubmVsQ291bnQpO1xyXG5cclxuICAgIHRoaXMuYnVmZmVyaW5nTm9kZSA9IGF3bjtcclxuICAgIC8vdGhpcy5idWZmZXJpbmdOb2RlLmNoYW5uZWxDb3VudD10aGlzLmNoYW5uZWxDb3VudDtcclxuICAgIHRoaXMuX29wZW5lZCA9IHRydWU7XHJcbiAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyLm9wZW5lZCgpO1xyXG4gICAgfVxyXG4gIH1cclxuICB9XHJcblxyXG4gIG9wZW4oY2hhbm5lbENvdW50OiBudW1iZXIsIHNlbERldmljZUlkPzogQ29uc3RyYWluRE9NU3RyaW5nfHVuZGVmaW5lZCxhdXRvR2FpbkNvbnRyb2xDb25maWdzPzpBcnJheTxBdXRvR2FpbkNvbnRyb2xDb25maWc+fG51bGx8dW5kZWZpbmVkLGFsbG93RWNob0NhbmNlbGxhdGlvbj86Ym9vbGVhbil7XHJcbiAgICAvL2NvbnNvbGUuZGVidWcoXCJDYXB0dXJlIG9wZW46IGN0eCBzdGF0ZTogXCIrdGhpcy5jb250ZXh0LnN0YXRlKTtcclxuICAgIHRoaXMuY29udGV4dD10aGlzLl9hdWRpb0NvbnRleHQoKTtcclxuICAgIGlmKCF0aGlzLmNvbnRleHQpe1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZ2V0IGF1ZGlvIGNvbnRleHQhXCIpO1xyXG4gICAgfVxyXG4gICAgaWYodGhpcy5jb250ZXh0LnN0YXRlPT09J3N1c3BlbmRlZCcpe1xyXG4gICAgICAvL2NvbnNvbGUuZGVidWcoXCJDYXB0dXJlIG9wZW46IFJlc3VtZSBjb250ZXh0XCIpO1xyXG4gICAgICB0aGlzLmNvbnRleHQucmVzdW1lKCkudGhlbigoKT0+e1xyXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkNhcHR1cmUgb3BlbiAoY3R4IHJlc3VtZWQpOiBjdHggc3RhdGU6IFwiK3RoaXMuY29udGV4dC5zdGF0ZSk7XHJcbiAgICAgICAgdGhpcy5fb3BlbihjaGFubmVsQ291bnQsIHNlbERldmljZUlkLCBhdXRvR2FpbkNvbnRyb2xDb25maWdzLGFsbG93RWNob0NhbmNlbGxhdGlvbik7XHJcbiAgICAgIH0pLmNhdGNoKChlcnIpPT57XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICB9KVxyXG4gICAgfWVsc2UgaWYodGhpcy5jb250ZXh0LnN0YXRlPT09J2Nsb3NlZCcpIHtcclxuICAgICAgICBjb25zdCBtc2c9J0Vycm9yIG9uIHN0YXJ0IGNhcHR1cmU6IFRoZSBhdWRpbyBjb250ZXh0IGlzIGFscmVhZHkgY2xvc2VkLic7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgfWVsc2Uge1xyXG4gICAgICB0aGlzLl9vcGVuKGNoYW5uZWxDb3VudCwgc2VsRGV2aWNlSWQsIGF1dG9HYWluQ29udHJvbENvbmZpZ3MsYWxsb3dFY2hvQ2FuY2VsbGF0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBfb3BlbihjaGFubmVsQ291bnQ6IG51bWJlciwgc2VsRGV2aWNlSWQ/OiBDb25zdHJhaW5ET01TdHJpbmd8dW5kZWZpbmVkLGF1dG9HYWluQ29udHJvbENvbmZpZ3M/OkFycmF5PEF1dG9HYWluQ29udHJvbENvbmZpZz58bnVsbHx1bmRlZmluZWQsYWxsb3dFY2hvQ2FuY2VsbGF0aW9uPzpib29sZWFuKSB7XHJcbiAgICB0aGlzLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcclxuICAgIHRoaXMuZnJhbWVzUmVjb3JkZWQgPSAwO1xyXG5cclxuICAgIHRoaXMuY29udGV4dD10aGlzLl9hdWRpb0NvbnRleHQoKTtcclxuXHJcbiAgICBpZighdGhpcy5jb250ZXh0KXtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGdldCBhdWRpbyBjb250ZXh0IVwiKTtcclxuICAgIH1cclxuXHJcbiAgICAvL3ZhciBtc2MgPSBuZXcgQXVkaW9TdHJlYW1Db25zdHIoKTtcclxuICAgIC8vIHZhciBtc2M9e307XHJcbiAgICAvL21zYy52aWRlbyA9IGZhbHNlO1xyXG4gICAgLy9tc2MuYXVkaW8gPSB0cnVlO1xyXG5cclxuICAgIC8vIENocm9tZSBhbmQgRmlyZWZveCBzdGVyZW8gY2hhbm5lbHMgYXJlIGlkZW50aWNhbCAhIVxyXG4gICAgLy8gQW5kIGV2ZW4gd29yc2U6IFRoZSBkYXRhIGNvbWluZyBmcm9tIHRoZSBzb3VyY2UgaXMgYWxyZWFkeSBwcmVwcm9jZXNzZWQgb24gRkYgYW5kIENocm9tZS4gSXQgY29udGFpbnMgRFNQIGFydGlmYWN0cyEhXHJcblxyXG4gICAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzg3NzM3XHJcbiAgICAvLyBUaGUgd29ya2Fyb3VuZCB0byBzZXQgdGhlc2UgY29uc3RyYWludHMgZG9lcyBfTk9UXyBoZWxwOlxyXG4gICAgLy92YXIgbXNjPXthdWRpbzoge2VjaG9DYW5jZWxsYXRpb246IGZhbHNlLGNoYW5uZWxDb3VudDogMiwgZ29vZ0F1ZGlvTWlycm9yaW5nOiBmYWxzZX0sdmlkZW86IGZhbHNlfTtcclxuXHJcbiAgICAvLyBTYWZhcmkgYXQgbGVhc3QgdmVyc2lvbiAxMTogU3VwcG9ydCBmb3IgbWVkaWEgc3RyZWFtc1xyXG4gICAgLy8gVE9ETyB0ZXN0IGlmIGlucHV0IGlzIHVucHJvY2Vzc2VkXHJcblxyXG4gICAgbGV0IG1zYzpNZWRpYVN0cmVhbUNvbnN0cmFpbnRzO1xyXG4gICAgY29uc29sZS5pbmZvKCdVc2VyIGFnZW50OiAnK25hdmlnYXRvci51c2VyQWdlbnQpO1xyXG5cclxuXHJcbiAgICAgIGxldCB1YT1Vc2VyQWdlbnRCdWlsZGVyLnVzZXJBZ2VudCgpO1xyXG5cclxuICAgICAgLy8gdWEuY29tcG9uZW50cy5mb3JFYWNoKChjKT0+e1xyXG4gICAgICAvLyAgIGNvbnNvbGUuaW5mbyhcIlVBX0NvbXA6IFwiK2MudG9TdHJpbmcoKSk7XHJcbiAgICAgIC8vIH0pXHJcblxyXG4gICAgIGxldCBhZ2NDZmc6QXV0b0dhaW5Db250cm9sQ29uZmlnfG51bGw9bnVsbDtcclxuXHJcbiAgICBsZXQgYXV0b0dhaW5Db250cm9sPWZhbHNlO1xyXG4gICAgbGV0IGNocm9tZUVjaG9DYW5jZWxsYXRpb249ZmFsc2U7XHJcbiAgICBpZihhdXRvR2FpbkNvbnRyb2xDb25maWdzKXtcclxuICAgICAgZm9yKGxldCBhZ2NjIG9mIGF1dG9HYWluQ29udHJvbENvbmZpZ3Mpe1xyXG4gICAgICAgIGlmKGFnY2MucGxhdGZvcm09PT1DZmdQbGF0Zm9ybS5BbmRyb2lkICYmIHVhLmRldGVjdGVkUGxhdGZvcm09PT1QbGF0Zm9ybS5BbmRyb2lkKXtcclxuICAgICAgICAgICAgYWdjQ2ZnPWFnY2M7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZihhZ2NjLnBsYXRmb3JtPT09Q2ZnUGxhdGZvcm0uV2luZG93cyAmJiB1YS5kZXRlY3RlZFBsYXRmb3JtPT09UGxhdGZvcm0uV2luZG93cyl7XHJcbiAgICAgICAgICBhZ2NDZmc9YWdjYztcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBpZihhZ2NDZmcpe1xyXG4gICAgICAgIC8vIFRPRE8gdXNlIEVYQUNUL0lERUFMIGNvbnN0cmFpbnRcclxuICAgICAgICBhdXRvR2FpbkNvbnRyb2w9YWdjQ2ZnLnZhbHVlO1xyXG4gICAgICAgIGlmKENIUk9NRV9BQ1RJVkFURV9FQ0hPX0NBTkNFTExBVElPTl9XSVRIX0FHQyl7XHJcbiAgICAgICAgICBjaHJvbWVFY2hvQ2FuY2VsbGF0aW9uPWFnY0NmZy52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVE9ETyBxdWVyeSByZWFsIEFHQyBzdGF0dXNcclxuICAgICAgICB0aGlzLmFnY1N0YXR1cz1hZ2NDZmcudmFsdWU7XHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgIHRoaXMuYWdjU3RhdHVzPWZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZGVmYXVsdFxyXG4gICAgbXNjID0ge1xyXG4gICAgICBhdWRpbzoge1xyXG4gICAgICAgIGRldmljZUlkOiBzZWxEZXZpY2VJZCxcclxuICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcclxuICAgICAgICBjaGFubmVsQ291bnQ6IGNoYW5uZWxDb3VudCxcclxuICAgICAgICBhdXRvR2FpbkNvbnRyb2w6IGF1dG9HYWluQ29udHJvbFxyXG4gICAgICB9LFxyXG4gICAgICB2aWRlbzogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHVhLmRldGVjdGVkQnJvd3Nlcj09PUJyb3dzZXIuRWRnZSkge1xyXG5cclxuICAgICAgLy8gTWljcm9zb2Z0IEVkZ2Ugc2VuZHMgdW5tb2RpZmllZCBhdWRpb1xyXG4gICAgICAvLyBUaGUgY29uc3RyYWludCBjYW4gZm9sbG93IHRoZSBzcGVjaWZpY2F0aW9uXHJcbiAgICAgIGNvbnNvbGUuaW5mbyhcIlNldHRpbmcgbWVkaWEgdHJhY2sgY29uc3RyYWludHMgZm9yIE1pY3Jvc29mdCBFZGdlLlwiKTtcclxuICAgICAgbXNjID0ge1xyXG4gICAgICAgIGF1ZGlvOiB7XHJcbiAgICAgICAgICBkZXZpY2VJZDogc2VsRGV2aWNlSWQsXHJcbiAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcclxuICAgICAgICAgIGNoYW5uZWxDb3VudDogY2hhbm5lbENvdW50LFxyXG4gICAgICAgICAgYXV0b0dhaW5Db250cm9sOiBhdXRvR2FpbkNvbnRyb2xcclxuICAgICAgICB9LFxyXG4gICAgICAgIHZpZGVvOiBmYWxzZVxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIGlmICh1YS5kZXRlY3RlZEJyb3dzZXI9PT1Ccm93c2VyLkNocm9tZSkge1xyXG4gICAgICAvLyBHb29nbGUgQ2hyb21lOiB3ZSBuZWVkIHRvIHN3aXRjaCBvZiBlYWNoIG9mIHRoZSBwcmVwcm9jZXNzaW5nIHVuaXRzIGluY2x1ZGluZyB0aGVcclxuICAgICAgY29uc29sZS5pbmZvKFwiU2V0dGluZyBtZWRpYSB0cmFjayBjb25zdHJhaW50cyBmb3IgR29vZ2xlIENocm9tZS5cIik7XHJcblxyXG4gICAgICAvLyBDaHJvbWUgNjAgLT4gNjEgY2hhbmdlZFxyXG4gICAgICAvLyBpdCB3b3JrcyBub3cgd2l0aG91dCBtYW5kYXRvcnkvb3B0aW9uYWwgc3ViLW9iamVjdHNcclxuXHJcblxyXG4gICAgICAvLyBSZXF1aXJlcyBhdCBsZWFzdCBDaHJvbWUgNjFcclxuICAgICAgbXNjID0ge1xyXG4gICAgICAgIGF1ZGlvOiB7XHJcbiAgICAgICAgICBkZXZpY2VJZDogc2VsRGV2aWNlSWQsXHJcbiAgICAgICAgICBjaGFubmVsQ291bnQ6IGNoYW5uZWxDb3VudCxcclxuICAgICAgICAgIGVjaG9DYW5jZWxsYXRpb246IHtleGFjdDpjaHJvbWVFY2hvQ2FuY2VsbGF0aW9ufSxcclxuICAgICAgICAgIGF1dG9HYWluQ29udHJvbDoge2V4YWN0OmF1dG9HYWluQ29udHJvbH0sXHJcbiAgICAgICAgICBzYW1wbGVTaXplOnttaW46IDE2fSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHZpZGVvOiBmYWxzZSxcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSBpZiAodWEuZGV0ZWN0ZWRCcm93c2VyPT09QnJvd3Nlci5GaXJlZm94KSB7XHJcbiAgICAgIGNvbnNvbGUuaW5mbyhcIlNldHRpbmcgbWVkaWEgdHJhY2sgY29uc3RyYWludHMgZm9yIE1vemlsbGEgRmlyZWZveC5cIik7XHJcbiAgICAgIC8vIEZpcmVmb3hcclxuICAgICAgbXNjID0ge1xyXG4gICAgICAgIGF1ZGlvOiB7XHJcbiAgICAgICAgICAgIGRldmljZUlkOiBzZWxEZXZpY2VJZCxcclxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBjaGFubmVsQ291bnQsXHJcbiAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcclxuICAgICAgICAgICAgYXV0b0dhaW5Db250cm9sOiBhdXRvR2FpbkNvbnRyb2wsXHJcbiAgICAgICAgICBub2lzZVN1cHByZXNzaW9uOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdmlkZW86IGZhbHNlLFxyXG4gICAgICB9XHJcblxyXG4gICAgfSBlbHNlIGlmICh1YS5kZXRlY3RlZEJyb3dzZXI9PT1Ccm93c2VyLlNhZmFyaSkge1xyXG4gICAgICBjb25zb2xlLmluZm8oXCJTZXR0aW5nIG1lZGlhIHRyYWNrIGNvbnN0cmFpbnRzIGZvciBTYWZhcmkgYnJvd3Nlci5cIilcclxuICAgICAgLy9jb25zb2xlLmluZm8oXCJBcHBseSB3b3JrYXJvdW5kIGZvciBTYWZhcmk6IEF2b2lkIGRpc2Nvbm5lY3Qgb2Ygc3RyZWFtcy5cIik7XHJcblxyXG4gICAgICB0aGlzLmRpc2Nvbm5lY3RTdHJlYW1zID0gdHJ1ZTtcclxuXHJcbiAgICAgIG1zYyA9IHtcclxuICAgICAgICBhdWRpbzoge1xyXG4gICAgICAgICAgZGV2aWNlSWQ6IHNlbERldmljZUlkLFxyXG4gICAgICAgICAgY2hhbm5lbENvdW50OiBjaGFubmVsQ291bnQsXHJcbiAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBhbGxvd0VjaG9DYW5jZWxsYXRpb24/dW5kZWZpbmVkOmZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB2aWRlbzogZmFsc2UsXHJcbiAgICAgIH1cclxuXHJcbiAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgLy8gVE9ETyBkZWZhdWx0IGNvbnN0cmFpbnRzIG9yIGVycm9yIEJyb3dzZXIgbm90IHN1cHBvcnRlZFxyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgY29uc29sZS5kZWJ1ZyhcIkF1ZGlvIGNhcHR1cmUsIEFHQzogXCIrdGhpcy5hZ2NTdGF0dXMpXHJcblxyXG4gICAgbGV0IHVtcCA9IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKG1zYyk7XHJcbiAgICB1bXAudGhlbigocykgPT4ge1xyXG5cclxuICAgICAgaWYgKHRoaXMuY29udGV4dCkge1xyXG4gICAgICB0aGlzLnN0cmVhbSA9IHM7XHJcblxyXG4gICAgICBsZXQgYVRyYWNrcyA9IHMuZ2V0QXVkaW9UcmFja3MoKTtcclxuXHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYVRyYWNrcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBhVHJhY2sgPSBhVHJhY2tzW2ldO1xyXG5cclxuICAgICAgICBjb25zb2xlLmluZm8oXCJUcmFjayBhdWRpbyBpbmZvOiBpZDogXCIgKyBhVHJhY2suaWQgKyBcIiBraW5kOiBcIiArIGFUcmFjay5raW5kICsgXCIgbGFiZWw6IFxcXCJcIiArIGFUcmFjay5sYWJlbCArIFwiXFxcIlwiKTtcclxuICAgICAgICBsZXQgbXRyU3RzID0gYVRyYWNrLmdldFNldHRpbmdzKCk7XHJcblxyXG4gICAgICAgIC8vIFR5cGVzY3JpcHQgbGliLmRvbS50cyBNZWRpYVRyYWNrU2V0dGluZ3MuY2hhbm5lbENvdW50IGlzIG1pc3NpbmdcclxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWRuL2Jyb3dzZXItY29tcGF0LWRhdGEvYmxvYi81NDkzZDhmOTM3ZTA1YjJkZGJkNDFiOTlmNWJkZmFkNGExZjJlZDg1L2FwaS9NZWRpYVRyYWNrU2V0dGluZ3MuanNvblxyXG4gICAgICAgIC8vQHRzLWlnbm9yZVxyXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlRyYWNrIGF1ZGlvIHNldHRpbmdzOiBDaCBjbnQ6IFwiICsgbXRyU3RzLmNoYW5uZWxDb3VudCArIFwiLCBBR0M6IFwiICsgbXRyU3RzLmF1dG9HYWluQ29udHJvbCArIFwiLCBFY2hvIGNhbmNlbGwuOiBcIiArIG10clN0cy5lY2hvQ2FuY2VsbGF0aW9uKTtcclxuICAgICAgICBpZiAobXRyU3RzLmF1dG9HYWluQ29udHJvbCkge1xyXG4gICAgICAgICAgdGhpcy5hZ2NTdGF0dXMgPSBtdHJTdHMuYXV0b0dhaW5Db250cm9sO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkVjaG8gY2FuY2VsbGF0aW9uOiBcIittdHJTdHMuZWNob0NhbmNlbGxhdGlvbik7XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgICBsZXQgdlRyYWNrcyA9IHMuZ2V0VmlkZW9UcmFja3MoKTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2VHJhY2tzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IHZUcmFjayA9IHZUcmFja3NbaV07XHJcbiAgICAgICAgY29uc29sZS5pbmZvKFwiVHJhY2sgdmlkZW8gaW5mbzogaWQ6IFwiICsgdlRyYWNrLmlkICsgXCIga2luZDogXCIgKyB2VHJhY2sua2luZCArIFwiIGxhYmVsOiBcIiArIHZUcmFjay5sYWJlbCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzKTtcclxuICAgICAgLy8gc3RyZWFtIGNoYW5uZWwgY291bnQgKCBpcyBhbHdheXMgMiAhKVxyXG4gICAgICBsZXQgc3RyZWFtQ2hhbm5lbENvdW50OiBudW1iZXIgPSB0aGlzLm1lZGlhU3RyZWFtLmNoYW5uZWxDb3VudDtcclxuICAgICAgY29uc29sZS5pbmZvKFwiU3RyZWFtIGNoYW5uZWwgY291bnQ6IFwiICsgc3RyZWFtQ2hhbm5lbENvdW50KTtcclxuICAgICAgLy8gaXMgbm90IHNldCEhXHJcbiAgICAgIC8vdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSA9IHRoaXMubWVkaWFTdHJlYW0uc2FtcGxlUmF0ZTtcclxuICAgICAgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSA9IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xyXG4gICAgICBjb25zb2xlLmluZm8oXCJTb3VyY2UgYXVkaW8gbm9kZTogY2hhbm5lbHM6IFwiICsgc3RyZWFtQ2hhbm5lbENvdW50ICsgXCIgc2FtcGxlcmF0ZTogXCIgKyB0aGlzLmN1cnJlbnRTYW1wbGVSYXRlKTtcclxuICAgICAgaWYgKHRoaXMuYXVkaW9PdXRTdHJlYW0pIHtcclxuICAgICAgICB0aGlzLmF1ZGlvT3V0U3RyZWFtLnNldEZvcm1hdCh0aGlzLmNoYW5uZWxDb3VudCwgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSk7XHJcbiAgICAgIH1cclxuICAgICAgLy8gVzNDICAtPiBuZXcgbmFtZSBpcyBjcmVhdGVTY3JpcHRQcm9jZXNzb3JcclxuICAgICAgLy9cclxuICAgICAgLy8gQWdhaW4gZGVwcmVjYXRlZCwgYnV0IEF1ZGlvV29ya2VyIG5vdCB5ZXQgaW1wbGVtZW50ZWQgaW4gc3RhYmxlIHJlbGVhc2VzIChKdW5lIDIwMTYpXHJcbiAgICAgIC8vIEF1ZGlvV29ya2VyIGlzIG5vdyBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgLi4uIChNYXkgMjAxNylcclxuXHJcbiAgICAgIC8vIFVwZGF0ZSAxMi0yMDIwOlxyXG4gICAgICAvLyBUaGUgU2NyaXB0UHJvY2Vzc29yTm9kZSBJbnRlcmZhY2UgLSBERVBSRUNBVEVEXHJcblxyXG4gICAgICAvLyBVcGRhdGUgMDYtMjAyMVxyXG4gICAgICAvLyAgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGlzIGhlcmUgdG8gc3RheS4gV2ViIEF1ZGlvIEFQSSBoYXMgbm93IFJlY29tbWVuZGF0aW9uIHN0YXR1cyAhXHJcblxyXG4gICAgICBpZiAodGhpcy5jb250ZXh0LmF1ZGlvV29ya2xldCkge1xyXG4gICAgICAgIC8vY29uc3Qgd29ya2xldEZpbGVOYW1lID0gKCdmaWxlLWxvYWRlciEuL2ludGVyY2VwdG9yX3dvcmtsZXQuanMnKTtcclxuICAgICAgICAvL2NvbnN0IHdvcmtsZXRGaWxlTmFtZSA9ICdodHRwOi8vbG9jYWxob3N0OjQyMDAvYXNzZXRzL2ludGVyY2VwdG9yX3dvcmtsZXQuanMnO1xyXG4gICAgICAgIC8vY29uc29sZS5sb2coYXdwU3RyKTtcclxuICAgICAgICBpZiAoQXVkaW9DYXB0dXJlLmNhcHR1cmVJbnRlcmNlcHRvck1vZHVsZVJlZ2lzdGVyZWQpIHtcclxuICAgICAgICAgIC8vIFJlcXVpcmVkIGNhcHR1cmUgaW50ZXJjZXB0b3IgbW9kdWxlIGFscmVhZHkgcmVnaXN0ZXJlZFxyXG4gICAgICAgICAgdGhpcy5hZGRDYXB0dXJlSW50ZXJjZXB0b3IoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgIC8vIFJlZ2lzdGVyIGNhcHR1cmUgaW50ZXJjZXB0b3IgbW9kdWxlXHJcbiAgICAgICAgICBsZXQgYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYiA9IG5ldyBCbG9iKFthd3BTdHJdLCB7dHlwZTogJ3RleHQvamF2YXNjcmlwdCd9KTtcclxuXHJcbiAgICAgICAgICBsZXQgYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYlVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGF1ZGlvV29ya2xldE1vZHVsZUJsb2IpO1xyXG5cclxuICAgICAgICAgIHRoaXMuY29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKGF1ZGlvV29ya2xldE1vZHVsZUJsb2JVcmwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgQXVkaW9DYXB0dXJlLmNhcHR1cmVJbnRlcmNlcHRvck1vZHVsZVJlZ2lzdGVyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDYXB0dXJlSW50ZXJjZXB0b3IoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICApLmNhdGNoKChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb3VsZCBub3QgYWRkIG1vZHVsZSAnICsgZXJyb3IpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IpIHtcclxuICAgICAgICAvLyBUaGUgU2NyaXB0UHJvY2Vzc29yTm9kZSBJbnRlcmZhY2UgLSBERVBSRUNBVEVEIE9ubHkgYXMgZmFsbGJhY2tcclxuICAgICAgICAvLyBUT0RPIHNob3VsZCB3ZSB1c2Ugc3RyZWFtQ2hhbm5lbENvdW50IG9yIGNoYW5uZWxDb3VudCBoZXJlID9cclxuICAgICAgICBsZXQgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoQXVkaW9DYXB0dXJlLkJVRkZFUl9TSVpFLCBzdHJlYW1DaGFubmVsQ291bnQsIHN0cmVhbUNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgdGhpcy5idWZmZXJpbmdOb2RlID0gc2NyaXB0UHJvY2Vzc29yTm9kZTtcclxuICAgICAgICBsZXQgYyA9IDA7XHJcbiAgICAgICAgaWYgKHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MpIHtcclxuICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoZTogQXVkaW9Qcm9jZXNzaW5nRXZlbnQpID0+IHtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNhcHR1cmluZykge1xyXG4gICAgICAgICAgICAgIGxldCBpbkJ1ZmZlciA9IGUuaW5wdXRCdWZmZXI7XHJcbiAgICAgICAgICAgICAgLy8gb25seSBwcm9jZXNzIHJlcXVlc3RlZCBjb3VudCBvZiBjaGFubmVsc1xyXG4gICAgICAgICAgICAgIGxldCBjdXJyZW50QnVmZmVycyA9IG5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgICAgICAgZm9yIChsZXQgY2g6IG51bWJlciA9IDA7IGNoIDwgY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2hTYW1wbGVzID0gaW5CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2gpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGNoU2FtcGxlc0NvcHkgPSBjaFNhbXBsZXMuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50QnVmZmVyc1tjaF0gPSBjaFNhbXBsZXNDb3B5LnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLmRhdGFbY2hdLnB1c2goY2hTYW1wbGVzQ29weSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoREVCVUdfVFJBQ0VfTEVWRUwgPiA4KSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoXCJQcm9jZXNzIFwiICsgY2hTYW1wbGVzQ29weS5sZW5ndGggKyBcIiBzYW1wbGVzLlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVzUmVjb3JkZWQgKz0gY2hTYW1wbGVzQ29weS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGMrKztcclxuICAgICAgICAgICAgICBpZiAodGhpcy5hdWRpb091dFN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb091dFN0cmVhbS53cml0ZShjdXJyZW50QnVmZmVycyk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgICAgdGhpcy5fb3BlbmVkID0gdHJ1ZTtcclxuICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXIub3BlbmVkKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ0Jyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBhdWRpbyBwcm9jZXNzaW5nIChTY3JpcHRQcm9jZXNzb3Iub25hdWRpb3Byb2Nlc3MgbWV0aG9kIG5vdCBmb3VuZCkhJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ0Jyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBhdWRpbyBwcm9jZXNzaW5nIChuZWl0aGVyIEF1ZGlvV29ya2xldFByb2Nlc3NvciBub3IgU2NyaXB0UHJvY2Vzc29yKSEnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgICAgIH0sIChlKSA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUgKyBcIiBFcnJvciBuYW1lOiBcIiArZS5uYW1lKTtcclxuICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIGlmKCdOb3RBbGxvd2VkRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ05vdCBhbGxvd2VkIHRvIHVzZSB5b3VyIG1pY3JvcGhvbmUuJywnUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IG1pY3JvcGhvbmUgYWNjZXNzIGlzIGFsbG93ZWQgZm9yIHRoaXMgd2ViIHBhZ2UgYW5kIHJlbG9hZCB0aGUgcGFnZS4nKTtcclxuICAgICAgICAgICAgfWVsc2UgaWYoJ05vdFJlYWRhYmxlRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoJ0NvdWxkIG5vdCByZWFkIGZyb20geW91ciBhdWRpbyBkZXZpY2UuJywnUGxlYXNlIG1ha2Ugc3VyZSB5b3VyIGF1ZGlvIGRldmljZSBpcyB3b3JraW5nLicpO1xyXG4gICAgICAgICAgICB9ZWxzZSBpZignT3ZlcmNvbnN0cmFpbmVkRXJyb3InID09PSBlLm5hbWUpe1xyXG4gICAgICAgICAgICAgIGxldCBlTXNnPWUubXNnP2UubXNnOidPdmVyY29uc3RyYWluZWQgbWVkaWEgZGV2aWNlIHJlcXVlc3QgZXJyb3IuJztcclxuICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVyLmVycm9yKGVNc2cpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMubGlzdGVuZXIuZXJyb3IoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIClcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3N0YXJ0KCl7XHJcbiAgICBpZih0aGlzLmNvbnRleHQpIHtcclxuICAgICAgdGhpcy5pbml0RGF0YSgpO1xyXG4gICAgICBpZiAodGhpcy5hdWRpb091dFN0cmVhbSkge1xyXG4gICAgICAgIHRoaXMuYXVkaW9PdXRTdHJlYW0ubmV4dFN0cmVhbSgpXHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jYXB0dXJpbmcgPSB0cnVlO1xyXG4gICAgICBpZiAodGhpcy5idWZmZXJpbmdOb2RlKSB7XHJcbiAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5jb25uZWN0KHRoaXMuYnVmZmVyaW5nTm9kZSk7XHJcbiAgICAgICAgdGhpcy5idWZmZXJpbmdOb2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5saXN0ZW5lcikge1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXIuc3RhcnRlZCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdGFydCgpIHtcclxuICAgIGlmKHRoaXMuY29udGV4dCkge1xyXG4gICAgICBjb25zdCBhU3QgPSB0aGlzLmNvbnRleHQuc3RhdGU7XHJcbiAgICAgIGlmIChhU3QgPT09ICdydW5uaW5nJykge1xyXG4gICAgICAgIHRoaXMuX3N0YXJ0KCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkNhcHR1cmUgc3RhcnQ6IGF1ZGlvIGNvbnRleHQgbm90IHJ1bm5pbmcsIHN0YXRlOiBcIiArIGFTdCArIFwiLCByZXN1bWluZy4uLlwiKTtcclxuICAgICAgICB0aGlzLmNvbnRleHQucmVzdW1lKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiQ2FwdHVyZSBzdGFydDogYXVkaW8gY29udGV4dCByZXN1bWVkLCBzdGFydGluZy4uLlwiKTtcclxuICAgICAgICAgIHRoaXMuX3N0YXJ0KCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc3RvcCgpIHtcclxuXHJcbiAgICBpZiAodGhpcy5kaXNjb25uZWN0U3RyZWFtcyAmJiB0aGlzLmJ1ZmZlcmluZ05vZGUpIHtcclxuICAgICAgdGhpcy5tZWRpYVN0cmVhbS5kaXNjb25uZWN0KHRoaXMuYnVmZmVyaW5nTm9kZSk7XHJcbiAgICAgIGlmKHRoaXMuY29udGV4dCkge1xyXG4gICAgICAgIHRoaXMuYnVmZmVyaW5nTm9kZS5kaXNjb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBpZiAodGhpcy5hdWRpb091dFN0cmVhbSkge1xyXG4gICAgICAgIHRoaXMuYXVkaW9PdXRTdHJlYW0uZmx1c2goKTtcclxuICAgICAgfVxyXG4gICAgfWNhdGNoKGVycil7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJDb3VsZCBub3QgZmx1c2ggY2FwdHVyZSBzdHJlYW0uXCIpO1xyXG4gICAgIHRocm93IGVycjtcclxuICAgIH1maW5hbGx5IHtcclxuICAgICAgdGhpcy5jYXB0dXJpbmcgPSBmYWxzZTtcclxuICAgICAgaWYgKHRoaXMuaW5kZGJBdWRpb0J1ZmZlciAmJiB0aGlzLnBlcnNpc3RFcnJvcikge1xyXG4gICAgICAgIC8vIERlbGV0ZSBpbnZhbGlkIHBlcnNpc3RlbnQgYXVkaW8gZGF0YSBhbmQgaG9wZSB0aGF0IGl0IHdpbGwgYmUgY29tcGxldGVseSB1cGxvYWRlZCB0byB0aGUgc2VydmVyXHJcbiAgICAgICAgdGhpcy5pbmRkYkF1ZGlvQnVmZmVyLnJlbGVhc2VBdWRpb0RhdGEoKTtcclxuICAgICAgICB0aGlzLmluZGRiQXVkaW9CdWZmZXIgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmxpc3RlbmVyICYmICh0aGlzLnBlcnNpc3RFcnJvciB8fCB0aGlzLnBlcnNpc3RlZCkpIHtcclxuICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdG9wcGVkIGJ5IHN0b3AoKSBtZXRob2QgY2FsbFwiKTtcclxuICAgICAgICB0aGlzLmxpc3RlbmVyLnN0b3BwZWQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHN0b3JlKCl7XHJcbiAgIC8vIGlmKHRoaXMuZGIgJiYgdGhpcy5yZWNVVUlEKXtcclxuICAgLy8gICAgbGV0IHRyPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFNwckRiLlJFQ09SRElOR19GSUxFX0NIVU5LU19PQkpFQ1RfU1RPUkVfTkFNRSwgJ3JlYWR3cml0ZScpO1xyXG4gICAvLyAgICBsZXQgcmVjRmlsZU9ialN0b3JlID0gdHIub2JqZWN0U3RvcmUoU3ByRGIuUkVDT1JESU5HX0ZJTEVfQ0hVTktTX09CSkVDVF9TVE9SRV9OQU1FKTtcclxuICAgLy9cclxuICAgLy8gICAgICB0cnkge1xyXG4gICAvLyAgICAgICAgbGV0IGNoMERhdGE9dGhpcy5kYXRhWzBdO1xyXG4gICAvLyAgICAgICAgbGV0IGRhdGFDaGtDbnQ9Y2gwRGF0YS5sZW5ndGg7XHJcbiAgIC8vICAgICAgICAgIGxldCBwb3MgPSAwO1xyXG4gICAvLyAgICAgICAgICBmb3IgKGxldCBjaENrSWR4ID0gMDsgY2hDa0lkeCA8IGRhdGFDaGtDbnQ7IGNoQ2tJZHgrKykge1xyXG4gICAvLyAgICAgICAgICAgIGxldCBidWZMZW49MDtcclxuICAgLy8gICAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgLy8gICAgICAgICAgICAgIGxldCBjaENoayA9IHRoaXMuZGF0YVtjaF1bY2hDa0lkeF07XHJcbiAgIC8vICAgICAgICAgICAgICBidWZMZW4gPSBjaENoay5sZW5ndGg7XHJcbiAgIC8vICAgICAgICAgICAgICAvL2xldCBjYWNoZUlkID0gdXVpZCArICdfJyArIGNoICsgJ18nICsgY2hDa0lkeDtcclxuICAgLy8gICAgICAgICAgICAgIGxldCBjaGtEYklkID0gW3RoaXMucmVjVVVJRCwgdGhpcy5pbmREYkNoa0lkeCArIGNoQ2tJZHgsIGNoXTtcclxuICAgLy8gICAgICAgICAgICAgIGxldCBjciA9IHJlY0ZpbGVPYmpTdG9yZS5hZGQoY2hDaGssIGNoa0RiSWQpO1xyXG4gICAvLyAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQWRkZWQ6IFwiK2NoK1wiIFwiKyh0aGlzLmluZERiQ2hrSWR4K2NoQ2tJZHgpKTtcclxuICAgLy8gICAgICAgICAgICAgIGNyLm9uc3VjY2Vzcz0oKT0+e1xyXG4gICAvLyAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdG9yZWQgYXVkaW8gZGF0YSB0byBpbmRleGVkIGRiXCIpO1xyXG4gICAvLyAgICAgICAgICAgICAgfVxyXG4gICAvLyAgICAgICAgICAgICAgY3Iub25lcnJvcj0oKT0+e1xyXG4gICAvLyAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc3RvcmluZyBhdWRpbyBkYXRhIHRvIGluZGV4ZWQgZGJcIik7XHJcbiAgIC8vICAgICAgICAgICAgICB9XHJcbiAgIC8vICAgICAgICAgICAgfVxyXG4gICAvLyAgICAgICAgICAgIHBvcyArPSBidWZMZW47XHJcbiAgIC8vICAgICAgICB9XHJcbiAgIC8vICAgICAgICB0aGlzLmluZERiQ2hrSWR4Kz1kYXRhQ2hrQ250O1xyXG4gICAvL1xyXG4gICAvLyAgICAgICAgdHIub25lcnJvciA9IChlcnIpID0+IHtcclxuICAgLy8gICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGNhY2hlIGF1ZGlvIGRhdGEgdG8gaW5kZXhlZCBkYjogJyArIGVycilcclxuICAgLy8gICAgICAgIH1cclxuICAgLy8gICAgICAgIHRyLm9uY29tcGxldGUgPSAoKSA9PiB7XHJcbiAgIC8vICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZygnVHJhbnNmZXJyZWQgY2FwdHVyZSBhdWRpbyBkYXRhIHRvIGluZGV4ZWQgZGIsIGRlbGV0aW5nIG9yaWdpbmFsIGRhdGEgZnJvbSBtZW1vcnkuLi4nKTtcclxuICAgLy9cclxuICAgLy8gICAgICAgICAgLy8vIEF1ZGlvIGRhdGEgc2F2ZWQgdG8gaW5kZXggZGIgZGVsZXRlIGZyb20gaW4gbWVtb3J5IGRhdGEgYXJyYXlcclxuICAgLy8gICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcbiAgIC8vICAgICAgICAgICB0aGlzLmRhdGFbY2hdLnNwbGljZSgwKTtcclxuICAgLy8gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTcGxpY2VkL3JlbW92ZWQgY2g6IFwiK2NoKTtcclxuICAgLy8gICAgICAgICAgfVxyXG4gICAvL1xyXG4gICAvLyAgICAgICAgICB0aGlzLnBlcnNpc3RlZD10cnVlO1xyXG4gICAvLyAgICAgICAgICBpZih0aGlzLmxpc3RlbmVyICYmICF0aGlzLmNhcHR1cmluZyl7XHJcbiAgIC8vICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiU3RvcHBlZCBieSBpbmRleGVkIGRiIGhvb2tcIik7XHJcbiAgIC8vICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5zdG9wcGVkKCk7XHJcbiAgIC8vICAgICAgICAgIH1cclxuICAgLy8gICAgICAgIH1cclxuICAgLy8gICAgICAgIC8vIENvbW1pdCBjaHVua3NcclxuICAgLy8gICAgICAgIHRoaXMucGVyc2lzdGVkPWZhbHNlO1xyXG4gICAvLyAgICAgICAgdHIuY29tbWl0KCk7XHJcbiAgIC8vICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgIC8vICAgICAgICBjb25zb2xlLmVycm9yKCdUcmFuc2ZlciBjYXB0dXJlIGF1ZGlvIGRhdGEgZXJyb3I6ICcrZXJyKTtcclxuICAgLy8gICAgICB9XHJcbiAgIC8vICAgIH1cclxuXHJcbiAgICAvLyBpZighdGhpcy5pbmRkYkF1ZGlvQnVmZmVyICYmIHRoaXMuX3BlcnNpc3RlbnRBdWRpb1N0b3JhZ2VUYXJnZXQgJiYgdGhpcy5yZWNVVUlEKSB7XHJcbiAgICAvLyAgIHRoaXMuaW5kZGJBdWRpb0J1ZmZlciA9IG5ldyBJbmRleGVkRGJBdWRpb0J1ZmZlcih0aGlzLl9wZXJzaXN0ZW50QXVkaW9TdG9yYWdlVGFyZ2V0LCB0aGlzLmNoYW5uZWxDb3VudCx0aGlzLmN1cnJlbnRTYW1wbGVSYXRlLEF1ZGlvQ2FwdHVyZS5CVUZGRVJfU0laRSwwLHRoaXMucmVjVVVJRClcclxuICAgIC8vIH1cclxuICAgIGlmKHRoaXMuaW5kZGJBdWRpb0J1ZmZlciAmJiB0aGlzLmRhdGEpe1xyXG5cclxuICAgICAgLy8gVHJ5IHRvIGFwcGVuZCB0b1xyXG4gICAgICB0aGlzLmluZGRiQXVkaW9CdWZmZXIuYXBwZW5kUmF3QXVkaW9EYXRhKHRoaXMuZGF0YSkuc3Vic2NyaWJlKHtcclxuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdUcmFuc2ZlcnJlZCBjYXB0dXJlIGF1ZGlvIGRhdGEgdG8gaW5kZXhlZCBkYiwgZGVsZXRpbmcgb3JpZ2luYWwgZGF0YSBmcm9tIG1lbW9yeS4uLicpO1xyXG5cclxuICAgICAgICAgIC8vLyBBdWRpbyBkYXRhIHNhdmVkIHRvIGluZGV4IGRiIGRlbGV0ZSBmcm9tIGluIG1lbW9yeSBkYXRhIGFycmF5XHJcbiAgICAgICAgICBpZih0aGlzLmRhdGEpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgY2ggPSAwOyBjaCA8IHRoaXMuY2hhbm5lbENvdW50OyBjaCsrKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5kYXRhW2NoXS5zcGxpY2UoMCk7XHJcbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiU3BsaWNlZC9yZW1vdmVkIGNoOiBcIitjaCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMucGVyc2lzdGVkID0gdHJ1ZTtcclxuICAgICAgICAgIGlmICh0aGlzLmxpc3RlbmVyICYmICF0aGlzLmNhcHR1cmluZykge1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJTdG9wcGVkIGJ5IGluZGV4ZWQgZGIgaG9va1wiKTtcclxuICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5zdG9wcGVkKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxlcnJvcjooZXJyKT0+e1xyXG4gICAgICAgICAgLy8gT25seSBsb2cgdGhlIGZpcnN0IGVycm9yXHJcbiAgICAgICAgICBpZighdGhpcy5wZXJzaXN0RXJyb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5wZXJzaXN0RXJyb3IgPSBlcnI7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBwZXJzaXN0aW5nIGF1ZGlvIGRhdGE6IFwiICsgZXJyKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLnBlcnNpc3RlZD1mYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBjbG9zZSgpIHtcclxuICAgIGlmKHRoaXMubWVkaWFTdHJlYW0pIHtcclxuICAgICAgdGhpcy5tZWRpYVN0cmVhbS5kaXNjb25uZWN0KCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5zdHJlYW0pIHtcclxuICAgICAgY29uc3QgbXRzID0gdGhpcy5zdHJlYW0uZ2V0VHJhY2tzKCk7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbXRzW2ldLnN0b3AoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5fb3BlbmVkPWZhbHNlO1xyXG4gIH1cclxuXHJcbiAgYXVkaW9CdWZmZXIoKTogQXVkaW9CdWZmZXIgfG51bGx7XHJcbiAgICBsZXQgYWI6IEF1ZGlvQnVmZmVyfG51bGw9bnVsbDtcclxuICAgIGlmKHRoaXMuY29udGV4dCAmJiB0aGlzLmRhdGEpIHtcclxuICAgICAgbGV0IGZyYW1lTGVuOiBudW1iZXIgPSAwO1xyXG5cclxuICAgICAgbGV0IGNoMERhdGEgPSB0aGlzLmRhdGFbMF07XHJcblxyXG4gICAgICBmb3IgKGxldCBjaDBDaGsgb2YgY2gwRGF0YSkge1xyXG4gICAgICAgIGZyYW1lTGVuICs9IGNoMENoay5sZW5ndGg7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgYWIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyKHRoaXMuY2hhbm5lbENvdW50LCBmcmFtZUxlbiwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xyXG4gICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRE9NRXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdOb3RTdXBwb3J0ZWRFcnJvcicpIHtcclxuICAgICAgICAgICAgaWYgKGZyYW1lTGVuID09IDApIHtcclxuICAgICAgICAgICAgICAvLyBFbXB0eSBidWZmZXJzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IENocm9taXVtXHJcbiAgICAgICAgICAgICAgLy8gQ3JlYXRlIGR1bW15IGJ1ZmZlciB3aXRoIG9uZSBzYW1wbGVcclxuICAgICAgICAgICAgICBhYiA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXIodGhpcy5jaGFubmVsQ291bnQsIDEsIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGVyciBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpIHtcclxuICAgICAgICAgIC8vIE91dCBvZiBtZW1vcnlcclxuICAgICAgICAgIC8vIFRPRE8gV2hhdCB0byBkbyA/P1xyXG4gICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCB0aGlzLmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgIGxldCBjaEQgPSBhYi5nZXRDaGFubmVsRGF0YShjaCk7XHJcbiAgICAgICAgbGV0IHBvcyA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgY2hDaGsgb2YgdGhpcy5kYXRhW2NoXSkge1xyXG4gICAgICAgICAgbGV0IGJ1ZkxlbiA9IGNoQ2hrLmxlbmd0aDtcclxuICAgICAgICAgIGNoRC5zZXQoY2hDaGssIHBvcyk7XHJcbiAgICAgICAgICBwb3MgKz0gYnVmTGVuO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFiO1xyXG4gIH1cclxuXHJcbiAgYXVkaW9CdWZmZXJBcnJheSgpOkFycmF5QXVkaW9CdWZmZXJ8bnVsbHtcclxuICAgICAgbGV0IGFyckFiOkFycmF5QXVkaW9CdWZmZXJ8bnVsbD1udWxsO1xyXG4gICAgICBpZih0aGlzLmRhdGEpIHtcclxuICAgICAgICBhcnJBYj1uZXcgQXJyYXlBdWRpb0J1ZmZlcih0aGlzLmNoYW5uZWxDb3VudCwgdGhpcy5jdXJyZW50U2FtcGxlUmF0ZSwgdGhpcy5kYXRhKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gYXJyQWI7XHJcbiAgfVxyXG5cclxuICBpbmRkYkF1ZGlvQnVmZmVyQXJyYXkoKTpJbmRleGVkRGJBdWRpb0J1ZmZlcnxudWxse1xyXG4gICAgaWYodGhpcy5wZXJzaXN0RXJyb3Ipe1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1lbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaW5kZGJBdWRpb0J1ZmZlcjtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxufVxyXG5cclxuIl19
|