speechrecorderng 2.22.4 → 2.22.5
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/esm2020/lib/speechrecorder/session/audiorecorder.mjs +12 -272
- package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +283 -0
- package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +7 -277
- package/esm2020/lib/spr.module.version.mjs +2 -2
- package/fesm2015/speechrecorderng.mjs +5049 -5295
- package/fesm2015/speechrecorderng.mjs.map +1 -1
- package/fesm2020/speechrecorderng.mjs +5014 -5260
- package/fesm2020/speechrecorderng.mjs.map +1 -1
- package/lib/speechrecorder/session/audiorecorder.d.ts +5 -46
- package/lib/speechrecorder/session/basicrecorder.d.ts +57 -0
- package/lib/speechrecorder/session/sessionmanager.d.ts +4 -48
- package/lib/spr.module.version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { TransportActions } from "./controlpanel";
|
|
2
|
+
import { Browser, UserAgentBuilder } from "../../utils/ua-parser";
|
|
3
|
+
import { MessageDialog } from "../../ui/message_dialog";
|
|
4
|
+
import { LevelMeasure, StreamLevelMeasure } from "../../audio/dsp/level_measure";
|
|
5
|
+
import { Action } from "../../action/action";
|
|
6
|
+
import { MIN_DB_LEVEL } from "../../ui/recordingitem_display";
|
|
7
|
+
export const FORCE_REQUEST_AUDIO_PERMISSIONS = false;
|
|
8
|
+
export const RECFILE_API_CTX = 'recfile';
|
|
9
|
+
export const MAX_RECORDING_TIME_MS = 1000 * 60 * 60 * 60; // 1 hour
|
|
10
|
+
export const LEVEL_BAR_INTERVALL_SECONDS = 0.1; // 100ms
|
|
11
|
+
export class BasicRecorder {
|
|
12
|
+
constructor(dialog, sessionService) {
|
|
13
|
+
this.dialog = dialog;
|
|
14
|
+
this.sessionService = sessionService;
|
|
15
|
+
this.statusMsg = '';
|
|
16
|
+
this.statusWaiting = false;
|
|
17
|
+
this.readonly = false;
|
|
18
|
+
this.processingRecording = false;
|
|
19
|
+
this.ac = null;
|
|
20
|
+
this._selectedDeviceId = undefined;
|
|
21
|
+
this._channelCount = 2;
|
|
22
|
+
this._session = null;
|
|
23
|
+
this.uploadProgress = 100;
|
|
24
|
+
this.uploadStatus = 'ok';
|
|
25
|
+
this.audioSignalCollapsed = true;
|
|
26
|
+
this.peakLevelInDb = MIN_DB_LEVEL;
|
|
27
|
+
this.displayLevelInfos = null;
|
|
28
|
+
this.displayAudioClip = null;
|
|
29
|
+
this.audioFetchSubscription = null;
|
|
30
|
+
this.destroyed = false;
|
|
31
|
+
this.navigationDisabled = true;
|
|
32
|
+
this.userAgent = UserAgentBuilder.userAgent();
|
|
33
|
+
console.debug("Detected platform: " + this.userAgent.detectedPlatform);
|
|
34
|
+
console.debug("Detected browser: " + this.userAgent.detectedBrowser);
|
|
35
|
+
this.transportActions = new TransportActions();
|
|
36
|
+
this.playStartAction = new Action('Play');
|
|
37
|
+
this.levelMeasure = new LevelMeasure();
|
|
38
|
+
this.streamLevelMeasure = new StreamLevelMeasure();
|
|
39
|
+
this.selCaptureDeviceId = null;
|
|
40
|
+
}
|
|
41
|
+
set audioDevices(audioDevices) {
|
|
42
|
+
this._audioDevices = audioDevices;
|
|
43
|
+
}
|
|
44
|
+
set autoGainControlConfigs(autoGainControlConfigs) {
|
|
45
|
+
this._autoGainControlConfigs = autoGainControlConfigs;
|
|
46
|
+
}
|
|
47
|
+
set channelCount(channelCount) {
|
|
48
|
+
this._channelCount = channelCount;
|
|
49
|
+
}
|
|
50
|
+
set session(session) {
|
|
51
|
+
this._session = session;
|
|
52
|
+
}
|
|
53
|
+
get session() {
|
|
54
|
+
return this._session;
|
|
55
|
+
}
|
|
56
|
+
enableStartUserGesture() {
|
|
57
|
+
this.statusAlertType = 'info';
|
|
58
|
+
this.statusMsg = 'Ready.';
|
|
59
|
+
}
|
|
60
|
+
start() {
|
|
61
|
+
this.statusAlertType = 'info';
|
|
62
|
+
this.statusMsg = 'Starting session...';
|
|
63
|
+
this.statusWaiting = false;
|
|
64
|
+
if (this._session) {
|
|
65
|
+
if (this._session.sealed) {
|
|
66
|
+
this.readonly = true;
|
|
67
|
+
this.statusMsg = 'Session sealed!';
|
|
68
|
+
//let dialogRef = this.dialog.open(SessionSealedDialog, {});
|
|
69
|
+
this.dialog.open(MessageDialog, {
|
|
70
|
+
data: {
|
|
71
|
+
type: 'error',
|
|
72
|
+
title: 'Error',
|
|
73
|
+
msg: "This session is sealed. Recordings cannot be added anymore.",
|
|
74
|
+
advise: 'Please ask your experimenter what to do (e.g start a new session).',
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
let body = {};
|
|
80
|
+
if (this._session.status === "CREATED") {
|
|
81
|
+
this._session.status = "LOADED";
|
|
82
|
+
body.status = this._session.status;
|
|
83
|
+
if (!this._session.loadedDate) {
|
|
84
|
+
this._session.loadedDate = new Date();
|
|
85
|
+
body.loadedDate = this._session.loadedDate;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this._session.restartedDate = new Date();
|
|
90
|
+
body.restartedDate = this._session.restartedDate;
|
|
91
|
+
}
|
|
92
|
+
this.sessionService.patchSessionObserver(this._session, body).subscribe();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Check browser compatibility
|
|
96
|
+
if (this.userAgent.detectedBrowser === Browser.Safari && this._channelCount > 1) {
|
|
97
|
+
let eMsg = "Error: Safari browser does not support stereo recordings.";
|
|
98
|
+
console.error(eMsg);
|
|
99
|
+
this.dialog.open(MessageDialog, {
|
|
100
|
+
data: {
|
|
101
|
+
type: 'error',
|
|
102
|
+
title: 'Browser not supported',
|
|
103
|
+
msg: eMsg,
|
|
104
|
+
advice: "Please use a supported browser, e.g. Mozilla Firefox."
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//console.log("Session ID: "+this._session.session+ " status: "+this._session.status)
|
|
109
|
+
this._selectedDeviceId = undefined;
|
|
110
|
+
if (!this.readonly && this.ac && (FORCE_REQUEST_AUDIO_PERMISSIONS || (this._audioDevices && this._audioDevices.length > 0))) {
|
|
111
|
+
this.statusMsg = 'Requesting audio permissions...';
|
|
112
|
+
this.statusAlertType = 'info';
|
|
113
|
+
this.ac.deviceInfos((mdis) => {
|
|
114
|
+
let audioCaptureDeviceAvail = false;
|
|
115
|
+
let audioPlayDeviceAvail = false;
|
|
116
|
+
if (mdis) {
|
|
117
|
+
if (this.ac) {
|
|
118
|
+
this.ac.printDevices(mdis);
|
|
119
|
+
}
|
|
120
|
+
if (mdis.length > 0) {
|
|
121
|
+
for (let mdii = 0; mdii < mdis.length; mdii++) {
|
|
122
|
+
let mdi = mdis[mdii];
|
|
123
|
+
let kind = mdi.kind;
|
|
124
|
+
if (kind === "audioinput") {
|
|
125
|
+
audioCaptureDeviceAvail = true;
|
|
126
|
+
}
|
|
127
|
+
else if (kind === "audiooutput") {
|
|
128
|
+
audioPlayDeviceAvail = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (this._session && this._session.type !== 'TEST_DEF_A' && this._audioDevices && this._audioDevices.length > 0) {
|
|
133
|
+
let fdi = null;
|
|
134
|
+
for (let adI = 0; adI < this._audioDevices.length; adI++) {
|
|
135
|
+
let ad = this._audioDevices[adI];
|
|
136
|
+
if (ad.playback) {
|
|
137
|
+
// project audio device config for playback device
|
|
138
|
+
// not used for now
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
for (let mdii = 0; mdii < mdis.length; mdii++) {
|
|
142
|
+
let mdi = mdis[mdii];
|
|
143
|
+
let kind = mdi.kind;
|
|
144
|
+
if (kind === "audioinput") {
|
|
145
|
+
audioCaptureDeviceAvail = true;
|
|
146
|
+
}
|
|
147
|
+
else if (kind === "audiooutput") {
|
|
148
|
+
audioPlayDeviceAvail = true;
|
|
149
|
+
}
|
|
150
|
+
if (ad.regex) {
|
|
151
|
+
//console.log("Match?: \'"+mdi.label+"\' \'"+ad.name+"\'");
|
|
152
|
+
if (mdi.label.match(ad.name)) {
|
|
153
|
+
fdi = mdi;
|
|
154
|
+
//console.log("Match!");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
if (mdi.label.trim() === ad.name.trim()) {
|
|
159
|
+
fdi = mdi;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (fdi) {
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (fdi) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (fdi) {
|
|
171
|
+
// matching device found
|
|
172
|
+
// Not able to open device here since Chrome 71
|
|
173
|
+
// Chrome 71 requires a user gesture before the AudioContext can be resumed
|
|
174
|
+
// sessionmanager.ts:712 Open session with default audio device for 1 channels
|
|
175
|
+
// capture.ts:128 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
|
|
176
|
+
// push../projects/speechrecorderng/src/lib/audio/capture/capture.ts.AudioCapture.open @ capture.ts:128
|
|
177
|
+
//this.ac.open(this._channelCount, fdi.deviceId);
|
|
178
|
+
console.info("Set selected audio device: \'" + fdi.label + "\' Id: \'" + fdi.deviceId + "\'");
|
|
179
|
+
this._selectedDeviceId = fdi.deviceId;
|
|
180
|
+
this.enableStartUserGesture();
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// device not found
|
|
184
|
+
this.statusMsg = 'ERROR: Required audio device not available!';
|
|
185
|
+
this.statusAlertType = 'error';
|
|
186
|
+
this.readonly = true;
|
|
187
|
+
this.dialog.open(MessageDialog, {
|
|
188
|
+
data: {
|
|
189
|
+
type: 'error',
|
|
190
|
+
title: 'Required audio device',
|
|
191
|
+
msg: "Required audio device not found",
|
|
192
|
+
advice: "Please connect a suitable audio device for this project and retry (press the browser reload button)."
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (!audioCaptureDeviceAvail && !audioPlayDeviceAvail) {
|
|
199
|
+
// no device found
|
|
200
|
+
this.statusMsg = 'ERROR: No audio device available!';
|
|
201
|
+
this.statusAlertType = 'warn';
|
|
202
|
+
//this.readonly = true;
|
|
203
|
+
this.dialog.open(MessageDialog, {
|
|
204
|
+
data: {
|
|
205
|
+
type: 'warn',
|
|
206
|
+
title: 'No audio device',
|
|
207
|
+
msg: "No audio device found",
|
|
208
|
+
advice: "Please connect an audio device and retry (press the browser reload button) or try to continue anyway."
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
if (!this.readonly && !audioCaptureDeviceAvail) {
|
|
214
|
+
// no device found
|
|
215
|
+
this.statusMsg = 'WARNING: No audio capture device available!';
|
|
216
|
+
this.statusAlertType = 'warning';
|
|
217
|
+
//this.readonly = true;
|
|
218
|
+
this.dialog.open(MessageDialog, {
|
|
219
|
+
data: {
|
|
220
|
+
type: 'warning',
|
|
221
|
+
title: 'No audio capture device',
|
|
222
|
+
msg: "No audio capture device found",
|
|
223
|
+
advice: "Please connect an audio capture device and retry (press the browser reload button) or try to continue anyway."
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
// Safari does not list playback devices
|
|
228
|
+
if (!audioPlayDeviceAvail) {
|
|
229
|
+
// Firefox does not enumerate audiooutput devices
|
|
230
|
+
// Do not show this warning, because it would always appear on Firefox
|
|
231
|
+
// When https://bugzilla.mozilla.org/show_bug.cgi?id=1498512 is fixed the warning can be enabled for Firefox as well
|
|
232
|
+
// It is already implemneted but kept behind a preference setting https://bugzilla.mozilla.org/show_bug.cgi?id=1152401
|
|
233
|
+
// Output devices are listed if about:config media.setsinkid.enabled=true
|
|
234
|
+
// but default setting is false
|
|
235
|
+
// Same problem with Safari
|
|
236
|
+
if (!(this.userAgent.detectedBrowser === Browser.Safari || this.userAgent.detectedBrowser === Browser.Firefox)) {
|
|
237
|
+
// no device found
|
|
238
|
+
this.statusMsg = 'WARNING: No audio playback device available!';
|
|
239
|
+
this.statusAlertType = 'warn';
|
|
240
|
+
//this.readonly = true;
|
|
241
|
+
this.dialog.open(MessageDialog, {
|
|
242
|
+
data: {
|
|
243
|
+
type: 'warn',
|
|
244
|
+
title: 'No audio playback device',
|
|
245
|
+
msg: "No audio playback device found",
|
|
246
|
+
advice: "Please connect an audio playback device and retry (press the browser reload button) or try to continue anyway."
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Not able to open device here since Chrome 71
|
|
253
|
+
// Chrome 71 requires a user gesture before the AudioContext can be resumed
|
|
254
|
+
// sessionmanager.ts:712 Open session with default audio device for 1 channels
|
|
255
|
+
// capture.ts:128 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
|
|
256
|
+
// push../projects/speechrecorderng/src/lib/audio/capture/capture.ts.AudioCapture.open @ capture.ts:128
|
|
257
|
+
//console.log("Open session with default audio device for "+this._channelCount+" channels");
|
|
258
|
+
//this.ac.open(this._channelCount);
|
|
259
|
+
// enable start gesture anyway
|
|
260
|
+
this.enableStartUserGesture();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
closed() {
|
|
267
|
+
this.statusAlertType = 'info';
|
|
268
|
+
this.statusMsg = 'Session closed.';
|
|
269
|
+
}
|
|
270
|
+
error(msg = 'An unknown error occured during recording.', advice = 'Please retry.') {
|
|
271
|
+
this.statusMsg = 'ERROR: Recording.';
|
|
272
|
+
this.statusAlertType = 'error';
|
|
273
|
+
this.dialog.open(MessageDialog, {
|
|
274
|
+
data: {
|
|
275
|
+
type: 'error',
|
|
276
|
+
title: 'Recording error',
|
|
277
|
+
msg: msg,
|
|
278
|
+
advice: advice
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzaWNyZWNvcmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9zcGVlY2hyZWNvcmRlci9zZXNzaW9uL2Jhc2ljcmVjb3JkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFDLE9BQU8sRUFBYSxnQkFBZ0IsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBRTNFLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUt0RCxPQUFPLEVBQWEsWUFBWSxFQUFFLGtCQUFrQixFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFJM0YsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU1RCxNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBQyxLQUFLLENBQUM7QUFDbkQsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLFNBQVMsQ0FBQztBQUN6QyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxTQUFTO0FBRW5FLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLEdBQUcsQ0FBQyxDQUFFLFFBQVE7QUFFekQsTUFBTSxPQUFPLGFBQWE7SUFvQ3hCLFlBQXFCLE1BQWlCLEVBQVcsY0FBNkI7UUFBekQsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUFXLG1CQUFjLEdBQWQsY0FBYyxDQUFlO1FBbEM5RSxjQUFTLEdBQVMsRUFBRSxDQUFDO1FBRXJCLGtCQUFhLEdBQVUsS0FBSyxDQUFDO1FBQzdCLGFBQVEsR0FBQyxLQUFLLENBQUM7UUFDZix3QkFBbUIsR0FBQyxLQUFLLENBQUM7UUFD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O29DQUV2QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7d0NBQzlCLElBQUksRUFBRTs0Q0FDSixJQUFJLEVBQUUsTUFBTTs0Q0FDWixLQUFLLEVBQUUsMEJBQTBCOzRDQUNqQyxHQUFHLEVBQUUsZ0NBQWdDOzRDQUNyQyxNQUFNLEVBQUUsZ0hBQWdIO3lDQUN6SDtxQ0FDRixDQUFDLENBQUE7aUNBQ0g7NkJBQ0Y7eUJBQ0Y7d0JBRUQsK0NBQStDO3dCQUMvQywyRUFBMkU7d0JBQzNFLDhFQUE4RTt3QkFDOUUsb0pBQW9KO3dCQUNwSix1R0FBdUc7d0JBQ3ZHLDRGQUE0Rjt3QkFDNUYsbUNBQW1DO3dCQUVuQyw4QkFBOEI7d0JBQzlCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFBO3FCQUM5QjtpQkFDRjtZQUVILENBQUMsQ0FBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDO1FBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUM7SUFDckMsQ0FBQztJQUVELEtBQUssQ0FBQyxHQUFHLEdBQUMsNENBQTRDLEVBQUMsU0FBYyxlQUFlO1FBQ2xGLElBQUksQ0FBQyxTQUFTLEdBQUcsbUJBQW1CLENBQUM7UUFDckMsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQzlCLElBQUksRUFBRTtnQkFDSixJQUFJLEVBQUUsT0FBTztnQkFDYixLQUFLLEVBQUUsaUJBQWlCO2dCQUN4QixHQUFHLEVBQUUsR0FBRztnQkFDUixNQUFNLEVBQUUsTUFBTTthQUNmO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUVGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtUcmFuc3BvcnRBY3Rpb25zfSBmcm9tIFwiLi9jb250cm9scGFuZWxcIjtcclxuaW1wb3J0IHtCcm93c2VyLCBVc2VyQWdlbnQsIFVzZXJBZ2VudEJ1aWxkZXJ9IGZyb20gXCIuLi8uLi91dGlscy91YS1wYXJzZXJcIjtcclxuaW1wb3J0IHtNYXREaWFsb2d9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2dcIjtcclxuaW1wb3J0IHtNZXNzYWdlRGlhbG9nfSBmcm9tIFwiLi4vLi4vdWkvbWVzc2FnZV9kaWFsb2dcIjtcclxuaW1wb3J0IHtTZXNzaW9ufSBmcm9tIFwiLi9zZXNzaW9uXCI7XHJcbmltcG9ydCB7U2Vzc2lvblNlcnZpY2V9IGZyb20gXCIuL3Nlc3Npb24uc2VydmljZVwiO1xyXG5pbXBvcnQge0F1ZGlvQ2FwdHVyZX0gZnJvbSBcIi4uLy4uL2F1ZGlvL2NhcHR1cmUvY2FwdHVyZVwiO1xyXG5pbXBvcnQge0F1ZGlvRGV2aWNlLCBBdXRvR2FpbkNvbnRyb2xDb25maWd9IGZyb20gXCIuLi9wcm9qZWN0L3Byb2plY3RcIjtcclxuaW1wb3J0IHtMZXZlbEluZm9zLCBMZXZlbE1lYXN1cmUsIFN0cmVhbUxldmVsTWVhc3VyZX0gZnJvbSBcIi4uLy4uL2F1ZGlvL2RzcC9sZXZlbF9tZWFzdXJlXCI7XHJcbmltcG9ydCB7QXVkaW9QbGF5ZXJ9IGZyb20gXCIuLi8uLi9hdWRpby9wbGF5YmFjay9wbGF5ZXJcIjtcclxuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7QXVkaW9DbGlwfSBmcm9tIFwiLi4vLi4vYXVkaW8vcGVyc2lzdG9yXCI7XHJcbmltcG9ydCB7QWN0aW9ufSBmcm9tIFwiLi4vLi4vYWN0aW9uL2FjdGlvblwiO1xyXG5pbXBvcnQge01JTl9EQl9MRVZFTH0gZnJvbSBcIi4uLy4uL3VpL3JlY29yZGluZ2l0ZW1fZGlzcGxheVwiO1xyXG5cclxuZXhwb3J0IGNvbnN0IEZPUkNFX1JFUVVFU1RfQVVESU9fUEVSTUlTU0lPTlM9ZmFsc2U7XHJcbmV4cG9ydCBjb25zdCBSRUNGSUxFX0FQSV9DVFggPSAncmVjZmlsZSc7XHJcbmV4cG9ydCBjb25zdCBNQVhfUkVDT1JESU5HX1RJTUVfTVMgPSAxMDAwICogNjAgKiA2MCAqIDYwOyAvLyAxIGhvdXJcclxuXHJcbmV4cG9ydCBjb25zdCBMRVZFTF9CQVJfSU5URVJWQUxMX1NFQ09ORFMgPSAwLjE7ICAvLyAxMDBtc1xyXG5cclxuZXhwb3J0IGNsYXNzIEJhc2ljUmVjb3JkZXIge1xyXG4gIHByb3RlY3RlZCB1c2VyQWdlbnQ6VXNlckFnZW50O1xyXG4gIHN0YXR1c01zZzogc3RyaW5nPScnO1xyXG4gIHN0YXR1c0FsZXJ0VHlwZSE6IHN0cmluZztcclxuICBzdGF0dXNXYWl0aW5nOiBib29sZWFuPWZhbHNlO1xyXG4gIHJlYWRvbmx5PWZhbHNlO1xyXG4gIHByb2Nlc3NpbmdSZWNvcmRpbmc9ZmFsc2U7XHJcbiAgYWM6IEF1ZGlvQ2FwdHVyZXxudWxsPW51bGw7XHJcbiAgLy8gUHJvcGVydHkgYXVkaW9EZXZpY2VzIGZyb20gcHJvamVjdCBjb25maWc6IGxpc3Qgb2YgbmFtZXMgb2YgYWxsb3dlZCBhdWRpbyBkZXZpY2VzLlxyXG4gIHByb3RlY3RlZCBfYXVkaW9EZXZpY2VzOiBBcnJheTxBdWRpb0RldmljZT4gfCBudWxsfCB1bmRlZmluZWQ7XHJcbiAgcHJvdGVjdGVkIF9zZWxlY3RlZERldmljZUlkOnN0cmluZ3x1bmRlZmluZWQ9dW5kZWZpbmVkO1xyXG4gIHByb3RlY3RlZCBzZWxDYXB0dXJlRGV2aWNlSWQ6IENvbnN0cmFpbkRPTVN0cmluZyB8IG51bGw7XHJcbiAgcHJvdGVjdGVkIF9jaGFubmVsQ291bnQgPSAyO1xyXG4gIHByb3RlY3RlZCBfYXV0b0dhaW5Db250cm9sQ29uZmlnczogQXJyYXk8QXV0b0dhaW5Db250cm9sQ29uZmlnPiB8IG51bGx8IHVuZGVmaW5lZDtcclxuXHJcbiAgX3Nlc3Npb246IFNlc3Npb258bnVsbD1udWxsO1xyXG5cclxuICB0cmFuc3BvcnRBY3Rpb25zOiBUcmFuc3BvcnRBY3Rpb25zO1xyXG4gIHBsYXlTdGFydEFjdGlvbjogQWN0aW9uPHZvaWQ+O1xyXG5cclxuICB1cGxvYWRQcm9ncmVzczogbnVtYmVyID0gMTAwO1xyXG4gIHVwbG9hZFN0YXR1czogc3RyaW5nID0gJ29rJ1xyXG4gIGF1ZGlvU2lnbmFsQ29sbGFwc2VkID0gdHJ1ZTtcclxuXHJcbiAgcHJvdGVjdGVkIHN0cmVhbUxldmVsTWVhc3VyZTogU3RyZWFtTGV2ZWxNZWFzdXJlO1xyXG4gIHByb3RlY3RlZCBsZXZlbE1lYXN1cmU6IExldmVsTWVhc3VyZTtcclxuICBwZWFrTGV2ZWxJbkRiOm51bWJlcj1NSU5fREJfTEVWRUw7XHJcbiAgZGlzcGxheUxldmVsSW5mb3M6IExldmVsSW5mb3MgfCBudWxsPW51bGw7XHJcbiAgcHJvdGVjdGVkIF9jb250cm9sQXVkaW9QbGF5ZXIhOiBBdWRpb1BsYXllcjtcclxuICBkaXNwbGF5QXVkaW9DbGlwOiBBdWRpb0NsaXAgfCBudWxsPW51bGw7XHJcbiAgcHJvdGVjdGVkIGF1ZGlvRmV0Y2hTdWJzY3JpcHRpb246U3Vic2NyaXB0aW9ufG51bGw9bnVsbDtcclxuXHJcbiAgcHJvdGVjdGVkIGRlc3Ryb3llZD1mYWxzZTtcclxuXHJcbiAgcHJvdGVjdGVkIG5hdmlnYXRpb25EaXNhYmxlZD10cnVlO1xyXG5cclxuICBjb25zdHJ1Y3RvciggIHB1YmxpYyBkaWFsb2c6IE1hdERpYWxvZyxwcm90ZWN0ZWQgc2Vzc2lvblNlcnZpY2U6U2Vzc2lvblNlcnZpY2UpIHtcclxuICAgIHRoaXMudXNlckFnZW50PVVzZXJBZ2VudEJ1aWxkZXIudXNlckFnZW50KCk7XHJcbiAgICBjb25zb2xlLmRlYnVnKFwiRGV0ZWN0ZWQgcGxhdGZvcm06IFwiK3RoaXMudXNlckFnZW50LmRldGVjdGVkUGxhdGZvcm0pO1xyXG4gICAgY29uc29sZS5kZWJ1ZyhcIkRldGVjdGVkIGJyb3dzZXI6IFwiK3RoaXMudXNlckFnZW50LmRldGVjdGVkQnJvd3Nlcik7XHJcbiAgICB0aGlzLnRyYW5zcG9ydEFjdGlvbnMgPSBuZXcgVHJhbnNwb3J0QWN0aW9ucygpO1xyXG4gICAgdGhpcy5wbGF5U3RhcnRBY3Rpb24gPSBuZXcgQWN0aW9uKCdQbGF5Jyk7XHJcbiAgICB0aGlzLmxldmVsTWVhc3VyZSA9IG5ldyBMZXZlbE1lYXN1cmUoKTtcclxuICAgIHRoaXMuc3RyZWFtTGV2ZWxNZWFzdXJlID0gbmV3IFN0cmVhbUxldmVsTWVhc3VyZSgpO1xyXG4gICAgdGhpcy5zZWxDYXB0dXJlRGV2aWNlSWQgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgc2V0IGF1ZGlvRGV2aWNlcyhhdWRpb0RldmljZXM6IEFycmF5PEF1ZGlvRGV2aWNlPiB8IG51bGwgfCB1bmRlZmluZWQpIHtcclxuICAgIHRoaXMuX2F1ZGlvRGV2aWNlcyA9IGF1ZGlvRGV2aWNlcztcclxuICB9XHJcblxyXG4gIHNldCBhdXRvR2FpbkNvbnRyb2xDb25maWdzKGF1dG9HYWluQ29udHJvbENvbmZpZ3M6IEFycmF5PEF1dG9HYWluQ29udHJvbENvbmZpZz58bnVsbHx1bmRlZmluZWQpe1xyXG4gICAgdGhpcy5fYXV0b0dhaW5Db250cm9sQ29uZmlncz1hdXRvR2FpbkNvbnRyb2xDb25maWdzO1xyXG4gIH1cclxuXHJcbiAgc2V0IGNoYW5uZWxDb3VudChjaGFubmVsQ291bnQ6IG51bWJlcikge1xyXG4gICAgdGhpcy5fY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xyXG4gIH1cclxuXHJcbiAgc2V0IHNlc3Npb24oc2Vzc2lvbjogU2Vzc2lvbnxudWxsKSB7XHJcbiAgICB0aGlzLl9zZXNzaW9uID0gc2Vzc2lvbjtcclxuICB9XHJcblxyXG4gIGdldCBzZXNzaW9uKCk6U2Vzc2lvbnxudWxse1xyXG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb247XHJcbiAgfVxyXG5cclxuICBlbmFibGVTdGFydFVzZXJHZXN0dXJlKCkge1xyXG4gICAgdGhpcy5zdGF0dXNBbGVydFR5cGUgPSAnaW5mbyc7XHJcbiAgICB0aGlzLnN0YXR1c01zZyA9ICdSZWFkeS4nO1xyXG4gIH1cclxuXHJcbiAgc3RhcnQoKSB7XHJcbiAgICB0aGlzLnN0YXR1c0FsZXJ0VHlwZSA9ICdpbmZvJztcclxuICAgIHRoaXMuc3RhdHVzTXNnID0gJ1N0YXJ0aW5nIHNlc3Npb24uLi4nO1xyXG4gICAgdGhpcy5zdGF0dXNXYWl0aW5nPWZhbHNlO1xyXG4gICAgaWYodGhpcy5fc2Vzc2lvbikge1xyXG4gICAgICBpZiAodGhpcy5fc2Vzc2lvbi5zZWFsZWQpIHtcclxuICAgICAgICB0aGlzLnJlYWRvbmx5ID0gdHJ1ZVxyXG4gICAgICAgIHRoaXMuc3RhdHVzTXNnID0gJ1Nlc3Npb24gc2VhbGVkISc7XHJcbiAgICAgICAgLy9sZXQgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihTZXNzaW9uU2VhbGVkRGlhbG9nLCB7fSk7XHJcbiAgICAgICAgdGhpcy5kaWFsb2cub3BlbihNZXNzYWdlRGlhbG9nLCB7XHJcbiAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXHJcbiAgICAgICAgICAgIHRpdGxlOiAnRXJyb3InLFxyXG4gICAgICAgICAgICBtc2c6IFwiVGhpcyBzZXNzaW9uIGlzIHNlYWxlZC4gUmVjb3JkaW5ncyBjYW5ub3QgYmUgYWRkZWQgYW55bW9yZS5cIixcclxuICAgICAgICAgICAgYWR2aXNlOiAnUGxlYXNlIGFzayB5b3VyIGV4cGVyaW1lbnRlciB3aGF0IHRvIGRvIChlLmcgc3RhcnQgYSBuZXcgc2Vzc2lvbikuJyxcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZXQgYm9keTogYW55ID0ge307XHJcbiAgICAgICAgaWYgKHRoaXMuX3Nlc3Npb24uc3RhdHVzID09PSBcIkNSRUFURURcIikge1xyXG4gICAgICAgICAgdGhpcy5fc2Vzc2lvbi5zdGF0dXMgPSBcIkxPQURFRFwiO1xyXG4gICAgICAgICAgYm9keS5zdGF0dXMgPSB0aGlzLl9zZXNzaW9uLnN0YXR1cztcclxuICAgICAgICAgIGlmICghdGhpcy5fc2Vzc2lvbi5sb2FkZWREYXRlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3Nlc3Npb24ubG9hZGVkRGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgIGJvZHkubG9hZGVkRGF0ZSA9IHRoaXMuX3Nlc3Npb24ubG9hZGVkRGF0ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5fc2Vzc2lvbi5yZXN0YXJ0ZWREYXRlID0gbmV3IERhdGUoKTtcclxuICAgICAgICAgIGJvZHkucmVzdGFydGVkRGF0ZSA9IHRoaXMuX3Nlc3Npb24ucmVzdGFydGVkRGF0ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZXNzaW9uU2VydmljZS5wYXRjaFNlc3Npb25PYnNlcnZlcih0aGlzLl9zZXNzaW9uLCBib2R5KS5zdWJzY3JpYmUoKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgYnJvd3NlciBjb21wYXRpYmlsaXR5XHJcbiAgICBpZih0aGlzLnVzZXJBZ2VudC5kZXRlY3RlZEJyb3dzZXI9PT1Ccm93c2VyLlNhZmFyaSAmJiB0aGlzLl9jaGFubmVsQ291bnQ+MSl7XHJcbiAgICAgIGxldCBlTXNnPVwiRXJyb3I6IFNhZmFyaSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgc3RlcmVvIHJlY29yZGluZ3MuXCI7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoZU1zZyk7XHJcbiAgICAgIHRoaXMuZGlhbG9nLm9wZW4oTWVzc2FnZURpYWxvZywge1xyXG4gICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgIHR5cGU6ICdlcnJvcicsXHJcbiAgICAgICAgICB0aXRsZTogJ0Jyb3dzZXIgbm90IHN1cHBvcnRlZCcsXHJcbiAgICAgICAgICBtc2c6IGVNc2csXHJcbiAgICAgICAgICBhZHZpY2U6IFwiUGxlYXNlIHVzZSBhIHN1cHBvcnRlZCBicm93c2VyLCBlLmcuIE1vemlsbGEgRmlyZWZveC5cIlxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICAvL2NvbnNvbGUubG9nKFwiU2Vzc2lvbiBJRDogXCIrdGhpcy5fc2Vzc2lvbi5zZXNzaW9uKyBcIiBzdGF0dXM6IFwiK3RoaXMuX3Nlc3Npb24uc3RhdHVzKVxyXG4gICAgdGhpcy5fc2VsZWN0ZWREZXZpY2VJZD11bmRlZmluZWQ7XHJcblxyXG4gICAgaWYgKCF0aGlzLnJlYWRvbmx5ICYmIHRoaXMuYWMgJiYgKEZPUkNFX1JFUVVFU1RfQVVESU9fUEVSTUlTU0lPTlMgfHwgKHRoaXMuX2F1ZGlvRGV2aWNlcyAmJiB0aGlzLl9hdWRpb0RldmljZXMubGVuZ3RoID4gMCkpKSB7XHJcbiAgICAgIHRoaXMuc3RhdHVzTXNnID0gJ1JlcXVlc3RpbmcgYXVkaW8gcGVybWlzc2lvbnMuLi4nO1xyXG4gICAgICB0aGlzLnN0YXR1c0FsZXJ0VHlwZSA9ICdpbmZvJztcclxuXHJcbiAgICAgIHRoaXMuYWMuZGV2aWNlSW5mb3MoKG1kaXMpID0+IHtcclxuICAgICAgICBsZXQgYXVkaW9DYXB0dXJlRGV2aWNlQXZhaWw6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgICAgICBsZXQgYXVkaW9QbGF5RGV2aWNlQXZhaWw6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgICAgICBpZiAobWRpcykge1xyXG4gICAgICAgICAgaWYodGhpcy5hYykge1xyXG4gICAgICAgICAgICB0aGlzLmFjLnByaW50RGV2aWNlcyhtZGlzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChtZGlzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgbWRpaSA9IDA7IG1kaWkgPCBtZGlzLmxlbmd0aDsgbWRpaSsrKSB7XHJcbiAgICAgICAgICAgICAgbGV0IG1kaSA9IG1kaXNbbWRpaV07XHJcbiAgICAgICAgICAgICAgbGV0IGtpbmQ9bWRpLmtpbmQ7XHJcbiAgICAgICAgICAgICAgaWYoa2luZCA9PT0gXCJhdWRpb2lucHV0XCIpe1xyXG4gICAgICAgICAgICAgICAgYXVkaW9DYXB0dXJlRGV2aWNlQXZhaWw9dHJ1ZTtcclxuICAgICAgICAgICAgICB9ZWxzZSBpZihraW5kPT09IFwiYXVkaW9vdXRwdXRcIil7XHJcbiAgICAgICAgICAgICAgICBhdWRpb1BsYXlEZXZpY2VBdmFpbD10cnVlO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICh0aGlzLl9zZXNzaW9uICYmIHRoaXMuX3Nlc3Npb24udHlwZSAhPT0gJ1RFU1RfREVGX0EnICYmIHRoaXMuX2F1ZGlvRGV2aWNlcyAmJiB0aGlzLl9hdWRpb0RldmljZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgZmRpOiBNZWRpYURldmljZUluZm8gfCBudWxsID0gbnVsbDtcclxuICAgICAgICAgICAgZm9yIChsZXQgYWRJID0gMDsgYWRJIDwgdGhpcy5fYXVkaW9EZXZpY2VzLmxlbmd0aDsgYWRJKyspIHtcclxuICAgICAgICAgICAgICBsZXQgYWQgPSB0aGlzLl9hdWRpb0RldmljZXNbYWRJXTtcclxuICAgICAgICAgICAgICBpZiAoYWQucGxheWJhY2spIHtcclxuICAgICAgICAgICAgICAgIC8vIHByb2plY3QgYXVkaW8gZGV2aWNlIGNvbmZpZyBmb3IgcGxheWJhY2sgZGV2aWNlXHJcbiAgICAgICAgICAgICAgICAvLyBub3QgdXNlZCBmb3Igbm93XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgZm9yIChsZXQgbWRpaSA9IDA7IG1kaWkgPCBtZGlzLmxlbmd0aDsgbWRpaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgbWRpID0gbWRpc1ttZGlpXTtcclxuICAgICAgICAgICAgICAgIGxldCBraW5kPW1kaS5raW5kO1xyXG4gICAgICAgICAgICAgICAgaWYoa2luZCA9PT0gXCJhdWRpb2lucHV0XCIpe1xyXG4gICAgICAgICAgICAgICAgICBhdWRpb0NhcHR1cmVEZXZpY2VBdmFpbD10cnVlO1xyXG4gICAgICAgICAgICAgICAgfWVsc2UgaWYoa2luZD09PSBcImF1ZGlvb3V0cHV0XCIpe1xyXG4gICAgICAgICAgICAgICAgICBhdWRpb1BsYXlEZXZpY2VBdmFpbD10cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGFkLnJlZ2V4KSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJNYXRjaD86IFxcJ1wiK21kaS5sYWJlbCtcIlxcJyBcXCdcIithZC5uYW1lK1wiXFwnXCIpO1xyXG4gICAgICAgICAgICAgICAgICBpZiAobWRpLmxhYmVsLm1hdGNoKGFkLm5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmRpID0gbWRpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJNYXRjaCFcIik7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChtZGkubGFiZWwudHJpbSgpID09PSBhZC5uYW1lLnRyaW0oKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZkaSA9IG1kaTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGZkaSkge1xyXG4gICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgaWYgKGZkaSkge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZmRpKSB7XHJcbiAgICAgICAgICAgICAgLy8gbWF0Y2hpbmcgZGV2aWNlIGZvdW5kXHJcblxyXG4gICAgICAgICAgICAgIC8vIE5vdCBhYmxlIHRvIG9wZW4gZGV2aWNlIGhlcmUgc2luY2UgQ2hyb21lIDcxXHJcbiAgICAgICAgICAgICAgLy8gQ2hyb21lIDcxIHJlcXVpcmVzIGEgdXNlciBnZXN0dXJlIGJlZm9yZSB0aGUgQXVkaW9Db250ZXh0IGNhbiBiZSByZXN1bWVkXHJcbiAgICAgICAgICAgICAgLy8gc2Vzc2lvbm1hbmFnZXIudHM6NzEyIE9wZW4gc2Vzc2lvbiB3aXRoIGRlZmF1bHQgYXVkaW8gZGV2aWNlIGZvciAxIGNoYW5uZWxzXHJcbiAgICAgICAgICAgICAgLy8gY2FwdHVyZS50czoxMjggVGhlIEF1ZGlvQ29udGV4dCB3YXMgbm90IGFsbG93ZWQgdG8gc3RhcnQuIEl0IG11c3QgYmUgcmVzdW1lZCAob3IgY3JlYXRlZCkgYWZ0ZXIgYSB1c2VyIGdlc3R1cmUgb24gdGhlIHBhZ2UuIGh0dHBzOi8vZ29vLmdsLzdLN1dMdVxyXG4gICAgICAgICAgICAgIC8vIHB1c2guLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vY2FwdHVyZS9jYXB0dXJlLnRzLkF1ZGlvQ2FwdHVyZS5vcGVuIEAgY2FwdHVyZS50czoxMjhcclxuXHJcbiAgICAgICAgICAgICAgLy90aGlzLmFjLm9wZW4odGhpcy5fY2hhbm5lbENvdW50LCBmZGkuZGV2aWNlSWQpO1xyXG4gICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhcIlNldCBzZWxlY3RlZCBhdWRpbyBkZXZpY2U6IFxcJ1wiICsgZmRpLmxhYmVsICsgXCJcXCcgSWQ6IFxcJ1wiICsgZmRpLmRldmljZUlkICsgXCJcXCdcIik7XHJcbiAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWREZXZpY2VJZCA9IGZkaS5kZXZpY2VJZDtcclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5lbmFibGVTdGFydFVzZXJHZXN0dXJlKClcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvLyBkZXZpY2Ugbm90IGZvdW5kXHJcbiAgICAgICAgICAgICAgdGhpcy5zdGF0dXNNc2cgPSAnRVJST1I6IFJlcXVpcmVkIGF1ZGlvIGRldmljZSBub3QgYXZhaWxhYmxlISc7XHJcbiAgICAgICAgICAgICAgdGhpcy5zdGF0dXNBbGVydFR5cGUgPSAnZXJyb3InO1xyXG4gICAgICAgICAgICAgIHRoaXMucmVhZG9ubHkgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKE1lc3NhZ2VEaWFsb2csIHtcclxuICAgICAgICAgICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgICAgICAgICAgdHlwZTogJ2Vycm9yJyxcclxuICAgICAgICAgICAgICAgICAgdGl0bGU6ICdSZXF1aXJlZCBhdWRpbyBkZXZpY2UnLFxyXG4gICAgICAgICAgICAgICAgICBtc2c6IFwiUmVxdWlyZWQgYXVkaW8gZGV2aWNlIG5vdCBmb3VuZFwiLFxyXG4gICAgICAgICAgICAgICAgICBhZHZpY2U6IFwiUGxlYXNlIGNvbm5lY3QgYSBzdWl0YWJsZSBhdWRpbyBkZXZpY2UgZm9yIHRoaXMgcHJvamVjdCBhbmQgcmV0cnkgKHByZXNzIHRoZSBicm93c2VyIHJlbG9hZCBidXR0b24pLlwiXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIGlmKCFhdWRpb0NhcHR1cmVEZXZpY2VBdmFpbCAmJiAhYXVkaW9QbGF5RGV2aWNlQXZhaWwpe1xyXG4gICAgICAgICAgICAgIC8vIG5vIGRldmljZSBmb3VuZFxyXG4gICAgICAgICAgICAgIHRoaXMuc3RhdHVzTXNnID0gJ0VSUk9SOiBObyBhdWRpbyBkZXZpY2UgYXZhaWxhYmxlISc7XHJcbiAgICAgICAgICAgICAgdGhpcy5zdGF0dXNBbGVydFR5cGUgPSAnd2Fybic7XHJcbiAgICAgICAgICAgICAgLy90aGlzLnJlYWRvbmx5ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5kaWFsb2cub3BlbihNZXNzYWdlRGlhbG9nLCB7XHJcbiAgICAgICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICd3YXJuJyxcclxuICAgICAgICAgICAgICAgICAgdGl0bGU6ICdObyBhdWRpbyBkZXZpY2UnLFxyXG4gICAgICAgICAgICAgICAgICBtc2c6IFwiTm8gYXVkaW8gZGV2aWNlIGZvdW5kXCIsXHJcbiAgICAgICAgICAgICAgICAgIGFkdmljZTogXCJQbGVhc2UgY29ubmVjdCBhbiBhdWRpbyBkZXZpY2UgYW5kIHJldHJ5IChwcmVzcyB0aGUgYnJvd3NlciByZWxvYWQgYnV0dG9uKSBvciB0cnkgdG8gY29udGludWUgYW55d2F5LlwiXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfWVsc2Uge1xyXG4gICAgICAgICAgICAgIGlmICghdGhpcy5yZWFkb25seSAmJiAhYXVkaW9DYXB0dXJlRGV2aWNlQXZhaWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIG5vIGRldmljZSBmb3VuZFxyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXNNc2cgPSAnV0FSTklORzogTm8gYXVkaW8gY2FwdHVyZSBkZXZpY2UgYXZhaWxhYmxlISc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c0FsZXJ0VHlwZSA9ICd3YXJuaW5nJztcclxuICAgICAgICAgICAgICAgIC8vdGhpcy5yZWFkb25seSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5kaWFsb2cub3BlbihNZXNzYWdlRGlhbG9nLCB7XHJcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnd2FybmluZycsXHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdObyBhdWRpbyBjYXB0dXJlIGRldmljZScsXHJcbiAgICAgICAgICAgICAgICAgICAgbXNnOiBcIk5vIGF1ZGlvIGNhcHR1cmUgZGV2aWNlIGZvdW5kXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgYWR2aWNlOiBcIlBsZWFzZSBjb25uZWN0IGFuIGF1ZGlvIGNhcHR1cmUgZGV2aWNlIGFuZCByZXRyeSAocHJlc3MgdGhlIGJyb3dzZXIgcmVsb2FkIGJ1dHRvbikgb3IgdHJ5IHRvIGNvbnRpbnVlIGFueXdheS5cIlxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgbGlzdCBwbGF5YmFjayBkZXZpY2VzXHJcbiAgICAgICAgICAgICAgaWYgKCFhdWRpb1BsYXlEZXZpY2VBdmFpbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCBkb2VzIG5vdCBlbnVtZXJhdGUgYXVkaW9vdXRwdXQgZGV2aWNlc1xyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IHNob3cgdGhpcyB3YXJuaW5nLCBiZWNhdXNlIGl0IHdvdWxkIGFsd2F5cyBhcHBlYXIgb24gRmlyZWZveFxyXG4gICAgICAgICAgICAgICAgLy8gV2hlbiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDk4NTEyIGlzIGZpeGVkIHRoZSB3YXJuaW5nIGNhbiBiZSBlbmFibGVkIGZvciBGaXJlZm94IGFzIHdlbGxcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJdCBpcyBhbHJlYWR5IGltcGxlbW5ldGVkIGJ1dCBrZXB0IGJlaGluZCBhIHByZWZlcmVuY2Ugc2V0dGluZyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xMTUyNDAxXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vIE91dHB1dCBkZXZpY2VzIGFyZSBsaXN0ZWQgaWYgYWJvdXQ6Y29uZmlnIG1lZGlhLnNldHNpbmtpZC5lbmFibGVkPXRydWVcclxuICAgICAgICAgICAgICAgIC8vIGJ1dCBkZWZhdWx0IHNldHRpbmcgaXMgZmFsc2VcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2FtZSBwcm9ibGVtIHdpdGggU2FmYXJpXHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCEodGhpcy51c2VyQWdlbnQuZGV0ZWN0ZWRCcm93c2VyPT09QnJvd3Nlci5TYWZhcmkgfHwgdGhpcy51c2VyQWdlbnQuZGV0ZWN0ZWRCcm93c2VyPT09QnJvd3Nlci5GaXJlZm94KSkge1xyXG4gICAgICAgICAgICAgICAgICAvLyBubyBkZXZpY2UgZm91bmRcclxuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0dXNNc2cgPSAnV0FSTklORzogTm8gYXVkaW8gcGxheWJhY2sgZGV2aWNlIGF2YWlsYWJsZSEnO1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c0FsZXJ0VHlwZSA9ICd3YXJuJztcclxuICAgICAgICAgICAgICAgICAgLy90aGlzLnJlYWRvbmx5ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oTWVzc2FnZURpYWxvZywge1xyXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd3YXJuJyxcclxuICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnTm8gYXVkaW8gcGxheWJhY2sgZGV2aWNlJyxcclxuICAgICAgICAgICAgICAgICAgICAgIG1zZzogXCJObyBhdWRpbyBwbGF5YmFjayBkZXZpY2UgZm91bmRcIixcclxuICAgICAgICAgICAgICAgICAgICAgIGFkdmljZTogXCJQbGVhc2UgY29ubmVjdCBhbiBhdWRpbyBwbGF5YmFjayBkZXZpY2UgYW5kIHJldHJ5IChwcmVzcyB0aGUgYnJvd3NlciByZWxvYWQgYnV0dG9uKSBvciB0cnkgdG8gY29udGludWUgYW55d2F5LlwiXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gTm90IGFibGUgdG8gb3BlbiBkZXZpY2UgaGVyZSBzaW5jZSBDaHJvbWUgNzFcclxuICAgICAgICAgICAgLy8gQ2hyb21lIDcxIHJlcXVpcmVzIGEgdXNlciBnZXN0dXJlIGJlZm9yZSB0aGUgQXVkaW9Db250ZXh0IGNhbiBiZSByZXN1bWVkXHJcbiAgICAgICAgICAgIC8vIHNlc3Npb25tYW5hZ2VyLnRzOjcxMiBPcGVuIHNlc3Npb24gd2l0aCBkZWZhdWx0IGF1ZGlvIGRldmljZSBmb3IgMSBjaGFubmVsc1xyXG4gICAgICAgICAgICAvLyBjYXB0dXJlLnRzOjEyOCBUaGUgQXVkaW9Db250ZXh0IHdhcyBub3QgYWxsb3dlZCB0byBzdGFydC4gSXQgbXVzdCBiZSByZXN1bWVkIChvciBjcmVhdGVkKSBhZnRlciBhIHVzZXIgZ2VzdHVyZSBvbiB0aGUgcGFnZS4gaHR0cHM6Ly9nb28uZ2wvN0s3V0x1XHJcbiAgICAgICAgICAgIC8vIHB1c2guLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vY2FwdHVyZS9jYXB0dXJlLnRzLkF1ZGlvQ2FwdHVyZS5vcGVuIEAgY2FwdHVyZS50czoxMjhcclxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIk9wZW4gc2Vzc2lvbiB3aXRoIGRlZmF1bHQgYXVkaW8gZGV2aWNlIGZvciBcIit0aGlzLl9jaGFubmVsQ291bnQrXCIgY2hhbm5lbHNcIik7XHJcbiAgICAgICAgICAgIC8vdGhpcy5hYy5vcGVuKHRoaXMuX2NoYW5uZWxDb3VudCk7XHJcblxyXG4gICAgICAgICAgICAvLyBlbmFibGUgc3RhcnQgZ2VzdHVyZSBhbnl3YXlcclxuICAgICAgICAgICAgdGhpcy5lbmFibGVTdGFydFVzZXJHZXN0dXJlKClcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNsb3NlZCgpIHtcclxuICAgIHRoaXMuc3RhdHVzQWxlcnRUeXBlID0gJ2luZm8nO1xyXG4gICAgdGhpcy5zdGF0dXNNc2cgPSAnU2Vzc2lvbiBjbG9zZWQuJztcclxuICB9XHJcblxyXG4gIGVycm9yKG1zZz0nQW4gdW5rbm93biBlcnJvciBvY2N1cmVkIGR1cmluZyByZWNvcmRpbmcuJyxhZHZpY2U6c3RyaW5nPSdQbGVhc2UgcmV0cnkuJykge1xyXG4gICAgdGhpcy5zdGF0dXNNc2cgPSAnRVJST1I6IFJlY29yZGluZy4nO1xyXG4gICAgdGhpcy5zdGF0dXNBbGVydFR5cGUgPSAnZXJyb3InO1xyXG4gICAgdGhpcy5kaWFsb2cub3BlbihNZXNzYWdlRGlhbG9nLCB7XHJcbiAgICAgIGRhdGE6IHtcclxuICAgICAgICB0eXBlOiAnZXJyb3InLFxyXG4gICAgICAgIHRpdGxlOiAnUmVjb3JkaW5nIGVycm9yJyxcclxuICAgICAgICBtc2c6IG1zZyxcclxuICAgICAgICBhZHZpY2U6IGFkdmljZVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==
|