@garrix82/reactgenie-lib 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.env.example +22 -0
  2. package/.github/workflows/publish.yml +20 -0
  3. package/LICENSE.txt +201 -0
  4. package/README.md +621 -0
  5. package/babel.config.js +29 -0
  6. package/dist/adapters/__tests__/expo-router-adapter.test.d.ts +1 -0
  7. package/dist/adapters/expo-router-adapter.d.ts +16 -0
  8. package/dist/adapters/expo-router-adapter.js +521 -0
  9. package/dist/adapters/navigation-adapter.d.ts +20 -0
  10. package/dist/adapters/navigation-adapter.js +137 -0
  11. package/dist/audio-visualizer.d.ts +14 -0
  12. package/dist/audio-visualizer.js +123 -0
  13. package/dist/current-selection.d.ts +27 -0
  14. package/dist/current-selection.js +94 -0
  15. package/dist/errors.d.ts +19 -0
  16. package/dist/errors.js +37 -0
  17. package/dist/genie/DateTime.d.ts +66 -0
  18. package/dist/genie/DateTime.js +399 -0
  19. package/dist/genie/TimeDelta.d.ts +35 -0
  20. package/dist/genie/TimeDelta.js +169 -0
  21. package/dist/genie-view-wrapper.d.ts +1 -0
  22. package/dist/genie-view-wrapper.js +377 -0
  23. package/dist/hooks/__tests__/useSpeechRecognition.test.d.ts +1 -0
  24. package/dist/hooks/useSpeechRecognition.d.ts +28 -0
  25. package/dist/hooks/useSpeechRecognition.js +118 -0
  26. package/dist/index.d.ts +30 -0
  27. package/dist/index.js +469 -0
  28. package/dist/logger.d.ts +23 -0
  29. package/dist/logger.js +597 -0
  30. package/dist/logger.remote.test.d.ts +0 -0
  31. package/dist/modality-provider-v2.d.ts +28 -0
  32. package/dist/modality-provider-v2.js +1321 -0
  33. package/dist/modality-provider.d.ts +22 -0
  34. package/dist/modality-provider.js +373 -0
  35. package/dist/native-visibility.d.ts +28 -0
  36. package/dist/native-visibility.js +50 -0
  37. package/dist/platform/VoiceRecognitionBar.d.ts +17 -0
  38. package/dist/platform/VoiceRecognitionBar.js +332 -0
  39. package/dist/platform/components.d.ts +32 -0
  40. package/dist/platform/components.js +351 -0
  41. package/dist/platform/events.d.ts +31 -0
  42. package/dist/platform/events.js +274 -0
  43. package/dist/platform/index.d.ts +3 -0
  44. package/dist/platform/index.js +39 -0
  45. package/dist/platform/types.d.ts +79 -0
  46. package/dist/platform/types.js +97 -0
  47. package/dist/react-decorators.d.ts +87 -0
  48. package/dist/react-decorators.js +368 -0
  49. package/dist/shared-store.d.ts +74 -0
  50. package/dist/shared-store.js +589 -0
  51. package/dist/speech-recognition/__tests__/speech-recognition-groq-transport.test.d.ts +1 -0
  52. package/dist/speech-recognition/__tests__/speech-recognition-native.test.d.ts +1 -0
  53. package/dist/speech-recognition/__tests__/speech-recognition-openai-native.test.d.ts +1 -0
  54. package/dist/speech-recognition/__tests__/speech-recognition-openai.test.d.ts +1 -0
  55. package/dist/speech-recognition/__tests__/speech-recognition-unified-import.test.d.ts +0 -0
  56. package/dist/speech-recognition/__tests__/speech-recognition-unified.test.d.ts +1 -0
  57. package/dist/speech-recognition/speech-recognition-groq.d.ts +21 -0
  58. package/dist/speech-recognition/speech-recognition-groq.js +409 -0
  59. package/dist/speech-recognition/speech-recognition-mlx.d.ts +15 -0
  60. package/dist/speech-recognition/speech-recognition-mlx.js +393 -0
  61. package/dist/speech-recognition/speech-recognition-native.d.ts +24 -0
  62. package/dist/speech-recognition/speech-recognition-native.js +632 -0
  63. package/dist/speech-recognition/speech-recognition-openai-native.d.ts +40 -0
  64. package/dist/speech-recognition/speech-recognition-openai-native.js +653 -0
  65. package/dist/speech-recognition/speech-recognition-openai.d.ts +39 -0
  66. package/dist/speech-recognition/speech-recognition-openai.js +718 -0
  67. package/dist/speech-recognition/speech-recognition-unified.d.ts +93 -0
  68. package/dist/speech-recognition/speech-recognition-unified.js +589 -0
  69. package/dist/speech-recognition/utils/groq-transcription.d.ts +41 -0
  70. package/dist/speech-recognition/utils/groq-transcription.js +382 -0
  71. package/dist/speech-recognition.d.ts +7 -0
  72. package/dist/speech-recognition.js +61 -0
  73. package/dist/voice-pipeline-telemetry.d.ts +26 -0
  74. package/dist/voice-pipeline-telemetry.js +15 -0
  75. package/garrix82-reactgenie-lib-1.3.0.tgz +0 -0
  76. package/metro/index.js +3 -0
  77. package/metro/with-genie-registry.js +47 -0
  78. package/package.json +111 -0
  79. package/scripts/dry-run.js +23 -0
  80. package/scripts/generate-genie-registry.js +278 -0
  81. package/scripts/log-file-test.js +51 -0
  82. package/scripts/parse.js +26 -0
  83. package/scripts/prompt.js +19 -0
  84. package/scripts/set-script.js +200 -0
  85. package/tsconfig.json +36 -0
@@ -0,0 +1,718 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.OpenAISpeechRecognizer = void 0;
7
+ exports.getOpenAISpeechCapabilities = getOpenAISpeechCapabilities;
8
+ exports.isOpenAISpeechAvailable = isOpenAISpeechAvailable;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _reactNative = require("react-native");
11
+ var _logger = _interopRequireDefault(require("../logger"));
12
+ var _groqTranscription = require("./utils/groq-transcription");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
16
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
17
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
18
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
19
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
20
+ const DEFAULT_REALTIME_MODEL = "gpt-4o-transcribe";
21
+ const DEFAULT_REALTIME_WEBRTC_URL = "https://api.openai.com/v1/realtime?intent=transcription";
22
+ const DATA_CHANNEL_OPEN_TIMEOUT_MS = 6000;
23
+ const SESSION_CACHE_RELEASE_DELAY_MS = 45_000;
24
+ const ENABLE_SESSION_CACHE = typeof process === "undefined" ? true : process.env.NODE_ENV !== "test";
25
+ const cachedWebRtcSession = {
26
+ pc: null,
27
+ dataChannel: null,
28
+ stream: null,
29
+ releaseTimer: null
30
+ };
31
+ function clearCachedReleaseTimer() {
32
+ if (!ENABLE_SESSION_CACHE) {
33
+ return;
34
+ }
35
+ if (cachedWebRtcSession.releaseTimer) {
36
+ clearTimeout(cachedWebRtcSession.releaseTimer);
37
+ cachedWebRtcSession.releaseTimer = null;
38
+ }
39
+ }
40
+ function closeWebRtcSessionResources(session) {
41
+ if (session.dataChannel) {
42
+ try {
43
+ session.dataChannel.close();
44
+ } catch (error) {
45
+ _logger.default.warn("[OpenAI SR] close data channel warning:", error);
46
+ }
47
+ }
48
+ if (session.pc) {
49
+ try {
50
+ session.pc.close();
51
+ } catch (error) {
52
+ _logger.default.warn("[OpenAI SR] close peer warning:", error);
53
+ }
54
+ }
55
+ if (session.stream) {
56
+ try {
57
+ session.stream.getTracks().forEach(track => track.stop());
58
+ } catch (error) {
59
+ _logger.default.warn("[OpenAI SR] stop stream warning:", error);
60
+ }
61
+ }
62
+ }
63
+ function scheduleCachedSessionRelease() {
64
+ if (!ENABLE_SESSION_CACHE) {
65
+ return;
66
+ }
67
+ clearCachedReleaseTimer();
68
+ cachedWebRtcSession.releaseTimer = setTimeout(() => {
69
+ closeWebRtcSessionResources(cachedWebRtcSession);
70
+ cachedWebRtcSession.pc = null;
71
+ cachedWebRtcSession.dataChannel = null;
72
+ cachedWebRtcSession.stream = null;
73
+ cachedWebRtcSession.releaseTimer = null;
74
+ }, SESSION_CACHE_RELEASE_DELAY_MS);
75
+ }
76
+ function hydrateFromSessionCache() {
77
+ if (!ENABLE_SESSION_CACHE) {
78
+ return {
79
+ pc: null,
80
+ dataChannel: null,
81
+ stream: null
82
+ };
83
+ }
84
+ return {
85
+ pc: cachedWebRtcSession.pc,
86
+ dataChannel: cachedWebRtcSession.dataChannel,
87
+ stream: cachedWebRtcSession.stream
88
+ };
89
+ }
90
+ function persistSessionCache(pc, dataChannel, stream) {
91
+ if (!ENABLE_SESSION_CACHE) {
92
+ return;
93
+ }
94
+ cachedWebRtcSession.pc = pc;
95
+ cachedWebRtcSession.dataChannel = dataChannel;
96
+ cachedWebRtcSession.stream = stream;
97
+ }
98
+ const OpenAISpeechRecognizer = ({
99
+ shouldListen,
100
+ speechStatusCallback,
101
+ speechResultCallback,
102
+ speechTranslationCallback,
103
+ speechReadyCallback,
104
+ clientSecret,
105
+ openaiTranscriptionSessionEndpoint,
106
+ openaiTranslationEndpoint,
107
+ openaiRealtimeWebRtcUrl = DEFAULT_REALTIME_WEBRTC_URL,
108
+ openaiRealtimeModel = DEFAULT_REALTIME_MODEL,
109
+ openaiTranslationModel = "gpt-4.1-mini",
110
+ openaiVadEnabled = true,
111
+ openaiAutoStopOnVadSilence = false,
112
+ openaiVadThreshold = 0.7,
113
+ openaiVadPrefixPaddingMs = 400,
114
+ openaiVadSilenceDurationMs = 1000,
115
+ openaiVadIdleTimeoutMs = 6000,
116
+ openaiPrewarmOnMount = false,
117
+ language = "en",
118
+ requestContextProvider,
119
+ onError
120
+ }) => {
121
+ const proxyAuthToken = clientSecret;
122
+ const [isRecording, setIsRecording] = (0, _react.useState)(false);
123
+ const [sessionRecoveryToken, setSessionRecoveryToken] = (0, _react.useState)(0);
124
+ const cachedSessionRef = (0, _react.useRef)(hydrateFromSessionCache());
125
+ const pcRef = (0, _react.useRef)(cachedSessionRef.current.pc);
126
+ const dataChannelRef = (0, _react.useRef)(cachedSessionRef.current.dataChannel);
127
+ const streamRef = (0, _react.useRef)(cachedSessionRef.current.stream);
128
+ const sessionInitRef = (0, _react.useRef)(null);
129
+ const finalTranscriptRef = (0, _react.useRef)("");
130
+ const interimTranscriptRef = (0, _react.useRef)("");
131
+ const stopInFlightRef = (0, _react.useRef)(false);
132
+ const finalizedRef = (0, _react.useRef)(false);
133
+ const awaitingCommitFinalRef = (0, _react.useRef)(false);
134
+ const commitFinalTimeoutRef = (0, _react.useRef)(null);
135
+ const didPrewarmRef = (0, _react.useRef)(false);
136
+ const isRecordingRef = (0, _react.useRef)(false);
137
+ const shouldListenRef = (0, _react.useRef)(shouldListen);
138
+ const openaiPrewarmOnMountRef = (0, _react.useRef)(openaiPrewarmOnMount);
139
+ const sessionRecoveryModeRef = (0, _react.useRef)(null);
140
+ const sessionRecoveryInFlightRef = (0, _react.useRef)(false);
141
+ const suppressedChannelErrorRef = (0, _react.useRef)(null);
142
+ const emitError = (0, _react.useCallback)(error => {
143
+ const err = error instanceof Error ? error : new Error(String(error));
144
+ _logger.default.error("[OpenAI SR] error:", err);
145
+ onError?.(err);
146
+ }, [onError]);
147
+ const resetTranscriptRefs = (0, _react.useCallback)(() => {
148
+ finalTranscriptRef.current = "";
149
+ interimTranscriptRef.current = "";
150
+ finalizedRef.current = false;
151
+ }, []);
152
+ const getBufferedTranscript = (0, _react.useCallback)(() => {
153
+ return (finalTranscriptRef.current || interimTranscriptRef.current).trim();
154
+ }, []);
155
+ const clearCommitFinalWait = (0, _react.useCallback)(() => {
156
+ awaitingCommitFinalRef.current = false;
157
+ if (commitFinalTimeoutRef.current) {
158
+ clearTimeout(commitFinalTimeoutRef.current);
159
+ commitFinalTimeoutRef.current = null;
160
+ }
161
+ }, []);
162
+ const notifyReady = (0, _react.useCallback)(ready => {
163
+ speechReadyCallback?.(ready);
164
+ }, [speechReadyCallback]);
165
+ const setAudioCaptureEnabled = (0, _react.useCallback)(enabled => {
166
+ const stream = streamRef.current;
167
+ if (!stream) {
168
+ return;
169
+ }
170
+ try {
171
+ const tracks = typeof stream.getAudioTracks === "function" ? stream.getAudioTracks() : typeof stream.getTracks === "function" ? stream.getTracks().filter(track => track?.kind === "audio") : [];
172
+ tracks.forEach(track => {
173
+ try {
174
+ track.enabled = enabled;
175
+ } catch (error) {
176
+ _logger.default.warn("[OpenAI SR] toggle audio track warning:", error);
177
+ }
178
+ });
179
+ } catch (error) {
180
+ _logger.default.warn("[OpenAI SR] enumerate audio tracks warning:", error);
181
+ }
182
+ }, []);
183
+ const clearRealtimeInputBuffer = (0, _react.useCallback)(reason => {
184
+ if (dataChannelRef.current?.readyState !== "open") {
185
+ return;
186
+ }
187
+ try {
188
+ dataChannelRef.current.send(JSON.stringify({
189
+ type: "input_audio_buffer.clear"
190
+ }));
191
+ _logger.default.debug(`[OpenAI SR] cleared input buffer (${reason})`);
192
+ } catch (error) {
193
+ _logger.default.warn("[OpenAI SR] clear input buffer warning:", error);
194
+ }
195
+ }, []);
196
+ const getRequestContextHeaders = (0, _react.useCallback)(() => {
197
+ const context = requestContextProvider?.();
198
+ if (!context) return {};
199
+ const headers = {};
200
+ if (context.threadId) {
201
+ headers["x-thread-id"] = String(context.threadId);
202
+ }
203
+ if (context.turnId) {
204
+ headers["x-turn-id"] = String(context.turnId);
205
+ }
206
+ if (context.sessionId !== undefined && context.sessionId !== null) {
207
+ headers["x-voice-session-id"] = String(context.sessionId);
208
+ }
209
+ if (context.sentryTrace) {
210
+ headers["sentry-trace"] = String(context.sentryTrace);
211
+ }
212
+ if (context.baggage) {
213
+ headers.baggage = String(context.baggage);
214
+ }
215
+ return headers;
216
+ }, [requestContextProvider]);
217
+ (0, _react.useEffect)(() => {
218
+ clearCachedReleaseTimer();
219
+ if (dataChannelRef.current?.readyState === "open") {
220
+ notifyReady(true);
221
+ }
222
+ }, [notifyReady]);
223
+ (0, _react.useEffect)(() => {
224
+ isRecordingRef.current = isRecording;
225
+ }, [isRecording]);
226
+ (0, _react.useEffect)(() => {
227
+ shouldListenRef.current = shouldListen;
228
+ }, [shouldListen]);
229
+ (0, _react.useEffect)(() => {
230
+ openaiPrewarmOnMountRef.current = openaiPrewarmOnMount;
231
+ }, [openaiPrewarmOnMount]);
232
+ const handleExpiredSession = (0, _react.useCallback)((channel, pc) => {
233
+ if (sessionRecoveryInFlightRef.current) {
234
+ return;
235
+ }
236
+ if (dataChannelRef.current !== channel) {
237
+ return;
238
+ }
239
+ sessionRecoveryInFlightRef.current = true;
240
+ suppressedChannelErrorRef.current = channel;
241
+ sessionRecoveryModeRef.current = shouldListenRef.current ? "listen" : openaiPrewarmOnMountRef.current ? "prewarm" : null;
242
+ clearCommitFinalWait();
243
+ resetTranscriptRefs();
244
+ setAudioCaptureEnabled(false);
245
+ sessionInitRef.current = null;
246
+ closeWebRtcSessionResources({
247
+ dataChannel: channel,
248
+ pc,
249
+ stream: streamRef.current
250
+ });
251
+ if (dataChannelRef.current === channel) {
252
+ dataChannelRef.current = null;
253
+ }
254
+ if (cachedWebRtcSession.dataChannel === channel) {
255
+ cachedWebRtcSession.dataChannel = null;
256
+ }
257
+ if (pcRef.current === pc) {
258
+ pcRef.current = null;
259
+ }
260
+ streamRef.current = null;
261
+ persistSessionCache(null, null, null);
262
+ setIsRecording(false);
263
+ notifyReady(false);
264
+ speechStatusCallback(false, "");
265
+ if (sessionRecoveryModeRef.current) {
266
+ setSessionRecoveryToken(value => value + 1);
267
+ } else {
268
+ sessionRecoveryInFlightRef.current = false;
269
+ suppressedChannelErrorRef.current = null;
270
+ }
271
+ }, [clearCommitFinalWait, notifyReady, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
272
+ const buildTurnDetection = (0, _react.useCallback)(() => {
273
+ if (!openaiVadEnabled) return null;
274
+ return {
275
+ type: "server_vad",
276
+ threshold: openaiVadThreshold,
277
+ prefix_padding_ms: openaiVadPrefixPaddingMs,
278
+ silence_duration_ms: openaiVadSilenceDurationMs
279
+ };
280
+ }, [openaiVadEnabled, openaiVadThreshold, openaiVadPrefixPaddingMs, openaiVadSilenceDurationMs]);
281
+ const waitForDataChannelOpen = (0, _react.useCallback)(async channel => {
282
+ const readState = () => String(channel.readyState);
283
+ if (readState() === "open") {
284
+ return;
285
+ }
286
+ const start = Date.now();
287
+ while (Date.now() - start < DATA_CHANNEL_OPEN_TIMEOUT_MS) {
288
+ if (readState() === "open") {
289
+ return;
290
+ }
291
+ await new Promise(resolve => setTimeout(resolve, 50));
292
+ }
293
+ throw new Error(`OpenAI realtime data channel did not open within ${DATA_CHANNEL_OPEN_TIMEOUT_MS}ms (state=${readState()})`);
294
+ }, []);
295
+ const translateToEnglish = (0, _react.useCallback)(async text => {
296
+ const input = text.trim();
297
+ if (!input || !openaiTranslationEndpoint) return "";
298
+ if (language.toLowerCase().startsWith("en")) return "";
299
+ const headers = _objectSpread({
300
+ "content-type": "application/json"
301
+ }, getRequestContextHeaders());
302
+ if (proxyAuthToken) {
303
+ headers.Authorization = `Bearer ${proxyAuthToken}`;
304
+ }
305
+ const response = await fetch(openaiTranslationEndpoint, {
306
+ method: "POST",
307
+ headers,
308
+ body: JSON.stringify({
309
+ text: input,
310
+ sourceLanguage: language,
311
+ model: openaiTranslationModel
312
+ })
313
+ });
314
+ if (!response.ok) {
315
+ const body = await response.text().catch(() => "");
316
+ throw new Error(`translation failed (${response.status}): ${body}`);
317
+ }
318
+ const payload = await response.json().catch(() => null);
319
+ const translated = typeof payload?.text === "string" ? payload.text.trim() : "";
320
+ if (translated) {
321
+ speechTranslationCallback?.(translated);
322
+ }
323
+ return translated;
324
+ }, [proxyAuthToken, language, getRequestContextHeaders, openaiTranslationEndpoint, openaiTranslationModel, speechTranslationCallback]);
325
+ const emitFinal = (0, _react.useCallback)(async () => {
326
+ if (finalizedRef.current) return;
327
+ finalizedRef.current = true;
328
+ const finalText = (finalTranscriptRef.current || interimTranscriptRef.current).trim();
329
+ let parseText = finalText;
330
+ try {
331
+ const translated = await translateToEnglish(finalText);
332
+ if (translated) {
333
+ parseText = translated;
334
+ }
335
+ } catch (error) {
336
+ _logger.default.warn("[OpenAI SR] translation failed:", error);
337
+ } finally {
338
+ speechStatusCallback(false, "");
339
+ if (parseText) {
340
+ speechResultCallback(parseText);
341
+ }
342
+ }
343
+ }, [speechResultCallback, speechStatusCallback, translateToEnglish]);
344
+ const finalizeAndReset = (0, _react.useCallback)(async () => {
345
+ clearCommitFinalWait();
346
+ await emitFinal();
347
+ resetTranscriptRefs();
348
+ }, [clearCommitFinalWait, emitFinal, resetTranscriptRefs]);
349
+ const handleRealtimeMessage = (0, _react.useCallback)(payload => {
350
+ const type = String(payload?.type || "");
351
+ const acceptsTranscript = isRecordingRef.current || awaitingCommitFinalRef.current;
352
+ if (!acceptsTranscript) {
353
+ return;
354
+ }
355
+ const shouldPublishInterim = isRecordingRef.current;
356
+ const delta = extractDeltaText(payload);
357
+ const completed = extractCompletedText(payload);
358
+ if (delta) {
359
+ interimTranscriptRef.current = (0, _groqTranscription.mergeTranscriptParts)(finalTranscriptRef.current, delta);
360
+ if (shouldPublishInterim) {
361
+ speechStatusCallback(true, interimTranscriptRef.current);
362
+ }
363
+ }
364
+ if (completed) {
365
+ finalTranscriptRef.current = (0, _groqTranscription.mergeTranscriptParts)(finalTranscriptRef.current, completed);
366
+ interimTranscriptRef.current = finalTranscriptRef.current;
367
+ if (shouldPublishInterim) {
368
+ speechStatusCallback(true, finalTranscriptRef.current);
369
+ }
370
+ }
371
+ const looksCompleted = !!completed || type.includes("completed");
372
+ if (awaitingCommitFinalRef.current && looksCompleted && getBufferedTranscript()) {
373
+ finalizeAndReset().catch(error => emitError(error));
374
+ return;
375
+ }
376
+ if (openaiAutoStopOnVadSilence && type === "input_audio_buffer.speech_stopped") {
377
+ const pauseTranscript = getBufferedTranscript();
378
+ speechStatusCallback(false, pauseTranscript);
379
+ }
380
+ }, [emitError, finalizeAndReset, getBufferedTranscript, openaiAutoStopOnVadSilence, speechStatusCallback]);
381
+ const startWebRtcSession = (0, _react.useCallback)(async token => {
382
+ clearCachedReleaseTimer();
383
+ if (typeof RTCPeerConnection === "undefined") {
384
+ throw new Error("RTCPeerConnection is unavailable on web runtime");
385
+ }
386
+ if (!navigator.mediaDevices?.getUserMedia) {
387
+ throw new Error("navigator.mediaDevices.getUserMedia is unavailable");
388
+ }
389
+ const stream = await navigator.mediaDevices.getUserMedia({
390
+ audio: {
391
+ echoCancellation: true,
392
+ noiseSuppression: true,
393
+ autoGainControl: true
394
+ }
395
+ });
396
+ streamRef.current = stream;
397
+ persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
398
+ setAudioCaptureEnabled(false);
399
+ const pc = new RTCPeerConnection();
400
+ pcRef.current = pc;
401
+ persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
402
+ stream.getTracks().forEach(track => pc.addTrack(track, stream));
403
+ const dataChannel = pc.createDataChannel("oai-events");
404
+ dataChannelRef.current = dataChannel;
405
+ persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
406
+ dataChannel.onopen = () => {
407
+ notifyReady(true);
408
+ };
409
+ dataChannel.onmessage = event => {
410
+ try {
411
+ const payload = JSON.parse(String(event.data || "{}"));
412
+ if (payload?.type === "error") {
413
+ const message = String(payload?.error?.message || "OpenAI realtime error");
414
+ if (isCommitBufferTooSmallError(message)) {
415
+ // Ignore commit buffer-too-small errors for low-latency fast-stop path.
416
+ return;
417
+ }
418
+ if (isSessionDurationLimitError(message)) {
419
+ handleExpiredSession(dataChannel, pc);
420
+ return;
421
+ }
422
+ throw new Error(message);
423
+ }
424
+ handleRealtimeMessage(payload);
425
+ } catch (error) {
426
+ emitError(error);
427
+ }
428
+ };
429
+ dataChannel.onerror = () => {
430
+ if (suppressedChannelErrorRef.current === dataChannel) {
431
+ return;
432
+ }
433
+ notifyReady(false);
434
+ emitError(new Error("OpenAI realtime data channel error"));
435
+ };
436
+ dataChannel.onclose = () => {
437
+ if (dataChannelRef.current === dataChannel) {
438
+ dataChannelRef.current = null;
439
+ }
440
+ if (cachedWebRtcSession.dataChannel === dataChannel) {
441
+ cachedWebRtcSession.dataChannel = null;
442
+ }
443
+ notifyReady(false);
444
+ };
445
+ const offer = await pc.createOffer();
446
+ await pc.setLocalDescription(offer);
447
+ const response = await fetch(openaiRealtimeWebRtcUrl, {
448
+ method: "POST",
449
+ headers: {
450
+ Authorization: `Bearer ${token}`,
451
+ "content-type": "application/sdp"
452
+ },
453
+ body: offer.sdp || ""
454
+ });
455
+ if (!response.ok) {
456
+ const body = await response.text().catch(() => "");
457
+ throw new Error(`webrtc negotiation failed (${response.status}): ${body}`);
458
+ }
459
+ const answerSdp = await response.text();
460
+ await pc.setRemoteDescription({
461
+ type: "answer",
462
+ sdp: answerSdp
463
+ });
464
+ await waitForDataChannelOpen(dataChannel);
465
+ }, [emitError, handleRealtimeMessage, notifyReady, openaiRealtimeWebRtcUrl, setAudioCaptureEnabled, waitForDataChannelOpen]);
466
+ const getEphemeralToken = (0, _react.useCallback)(async () => {
467
+ const headers = _objectSpread({
468
+ "content-type": "application/json"
469
+ }, getRequestContextHeaders());
470
+ if (proxyAuthToken) {
471
+ headers.Authorization = `Bearer ${proxyAuthToken}`;
472
+ }
473
+ const response = await fetch(openaiTranscriptionSessionEndpoint, {
474
+ method: "POST",
475
+ headers,
476
+ body: JSON.stringify({
477
+ input_audio_format: "pcm16",
478
+ input_audio_transcription: {
479
+ model: openaiRealtimeModel,
480
+ language
481
+ },
482
+ turn_detection: buildTurnDetection() || undefined
483
+ })
484
+ });
485
+ if (!response.ok) {
486
+ const body = await response.text().catch(() => "");
487
+ throw new Error(`transcription session request failed (${response.status}): ${body}`);
488
+ }
489
+ const payload = await response.json().catch(() => ({}));
490
+ const token = payload?.client_secret?.value || payload?.client_secret || payload?.value || "";
491
+ if (!token) {
492
+ throw new Error("No ephemeral token returned from transcription session endpoint");
493
+ }
494
+ return token;
495
+ }, [buildTurnDetection, getRequestContextHeaders, proxyAuthToken, language, openaiRealtimeModel, openaiTranscriptionSessionEndpoint]);
496
+ const hasReusableSession = (0, _react.useCallback)(() => {
497
+ return !!pcRef.current && !!streamRef.current && dataChannelRef.current?.readyState === "open";
498
+ }, []);
499
+ const ensureWebRtcSession = (0, _react.useCallback)(async () => {
500
+ if (hasReusableSession()) {
501
+ return;
502
+ }
503
+ if (sessionInitRef.current) {
504
+ await sessionInitRef.current;
505
+ return;
506
+ }
507
+ sessionInitRef.current = (async () => {
508
+ const token = await getEphemeralToken();
509
+ await startWebRtcSession(token);
510
+ })();
511
+ try {
512
+ await sessionInitRef.current;
513
+ } finally {
514
+ sessionInitRef.current = null;
515
+ }
516
+ }, [getEphemeralToken, hasReusableSession, startWebRtcSession]);
517
+ const cleanup = (0, _react.useCallback)(async () => {
518
+ sessionInitRef.current = null;
519
+ clearCachedReleaseTimer();
520
+ closeWebRtcSessionResources({
521
+ dataChannel: dataChannelRef.current,
522
+ pc: pcRef.current,
523
+ stream: streamRef.current
524
+ });
525
+ dataChannelRef.current = null;
526
+ pcRef.current = null;
527
+ streamRef.current = null;
528
+ persistSessionCache(null, null, null);
529
+ }, []);
530
+ (0, _react.useEffect)(() => {
531
+ if (sessionRecoveryToken === 0 || !sessionRecoveryModeRef.current) {
532
+ return;
533
+ }
534
+ let cancelled = false;
535
+ const recoveryMode = sessionRecoveryModeRef.current;
536
+ (async () => {
537
+ try {
538
+ await ensureWebRtcSession();
539
+ if (cancelled) {
540
+ return;
541
+ }
542
+ if (recoveryMode === "listen" && shouldListenRef.current) {
543
+ setAudioCaptureEnabled(true);
544
+ setIsRecording(true);
545
+ }
546
+ notifyReady(dataChannelRef.current?.readyState === "open");
547
+ } catch (error) {
548
+ if (cancelled) {
549
+ return;
550
+ }
551
+ emitError(error);
552
+ setAudioCaptureEnabled(false);
553
+ await cleanup();
554
+ setIsRecording(false);
555
+ notifyReady(false);
556
+ speechStatusCallback(false, "");
557
+ } finally {
558
+ if (cancelled) {
559
+ return;
560
+ }
561
+ sessionRecoveryModeRef.current = null;
562
+ sessionRecoveryInFlightRef.current = false;
563
+ suppressedChannelErrorRef.current = null;
564
+ }
565
+ })();
566
+ return () => {
567
+ cancelled = true;
568
+ };
569
+ }, [cleanup, emitError, ensureWebRtcSession, notifyReady, sessionRecoveryToken, setAudioCaptureEnabled, speechStatusCallback]);
570
+ const startRecording = (0, _react.useCallback)(async () => {
571
+ if (isRecording || stopInFlightRef.current || sessionRecoveryInFlightRef.current) {
572
+ return;
573
+ }
574
+ try {
575
+ clearCommitFinalWait();
576
+ notifyReady(false);
577
+ resetTranscriptRefs();
578
+ const reusingWarmSession = hasReusableSession();
579
+ await ensureWebRtcSession();
580
+ if (reusingWarmSession) {
581
+ clearRealtimeInputBuffer("start_recording");
582
+ }
583
+ if (!shouldListenRef.current) {
584
+ setAudioCaptureEnabled(false);
585
+ notifyReady(dataChannelRef.current?.readyState === "open");
586
+ return;
587
+ }
588
+ setAudioCaptureEnabled(true);
589
+ setIsRecording(true);
590
+ notifyReady(dataChannelRef.current?.readyState === "open");
591
+ } catch (error) {
592
+ emitError(error);
593
+ setAudioCaptureEnabled(false);
594
+ await cleanup();
595
+ setIsRecording(false);
596
+ notifyReady(false);
597
+ speechStatusCallback(false, "");
598
+ }
599
+ }, [cleanup, clearRealtimeInputBuffer, clearCommitFinalWait, ensureWebRtcSession, emitError, hasReusableSession, isRecording, notifyReady, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
600
+ const stopRecording = (0, _react.useCallback)(async () => {
601
+ if (!isRecording || stopInFlightRef.current) return;
602
+ stopInFlightRef.current = true;
603
+ setIsRecording(false);
604
+ setAudioCaptureEnabled(false);
605
+ notifyReady(false);
606
+ try {
607
+ if (dataChannelRef.current?.readyState === "open") {
608
+ dataChannelRef.current.send(JSON.stringify({
609
+ type: "input_audio_buffer.commit"
610
+ }));
611
+ }
612
+ const buffered = getBufferedTranscript();
613
+ if (buffered) {
614
+ await finalizeAndReset();
615
+ } else {
616
+ speechStatusCallback(false, "");
617
+ awaitingCommitFinalRef.current = true;
618
+ if (commitFinalTimeoutRef.current) {
619
+ clearTimeout(commitFinalTimeoutRef.current);
620
+ }
621
+ // Short fallback: if no post-commit transcript arrives, reset state and exit.
622
+ commitFinalTimeoutRef.current = setTimeout(() => {
623
+ if (!awaitingCommitFinalRef.current) return;
624
+ clearCommitFinalWait();
625
+ resetTranscriptRefs();
626
+ }, 1500);
627
+ }
628
+ } catch (error) {
629
+ emitError(error);
630
+ speechStatusCallback(false, "");
631
+ } finally {
632
+ stopInFlightRef.current = false;
633
+ notifyReady(false);
634
+ }
635
+ }, [emitError, finalizeAndReset, getBufferedTranscript, isRecording, notifyReady, clearCommitFinalWait, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
636
+ (0, _react.useEffect)(() => {
637
+ if (!openaiPrewarmOnMount || didPrewarmRef.current) {
638
+ return;
639
+ }
640
+ didPrewarmRef.current = true;
641
+ ensureWebRtcSession().then(() => {
642
+ notifyReady(true);
643
+ }).catch(error => {
644
+ emitError(error);
645
+ });
646
+ }, [emitError, ensureWebRtcSession, notifyReady, openaiPrewarmOnMount]);
647
+ (0, _react.useEffect)(() => {
648
+ if (shouldListen && !isRecording) {
649
+ startRecording();
650
+ } else if (!shouldListen && isRecording) {
651
+ stopRecording();
652
+ }
653
+ }, [isRecording, shouldListen, startRecording, stopRecording]);
654
+ (0, _react.useEffect)(() => {
655
+ return () => {
656
+ notifyReady(false);
657
+ clearCommitFinalWait();
658
+ setAudioCaptureEnabled(false);
659
+ if (ENABLE_SESSION_CACHE && openaiPrewarmOnMountRef.current && !isRecordingRef.current) {
660
+ scheduleCachedSessionRelease();
661
+ } else {
662
+ cleanup().catch(() => undefined);
663
+ }
664
+ };
665
+ }, [cleanup, notifyReady, clearCommitFinalWait, setAudioCaptureEnabled]);
666
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, null);
667
+ };
668
+ exports.OpenAISpeechRecognizer = OpenAISpeechRecognizer;
669
+ function extractDeltaText(payload) {
670
+ const type = String(payload?.type || "");
671
+ if (!type.includes("delta")) return "";
672
+ const candidates = [payload?.delta, payload?.text_delta, payload?.transcript_delta, payload?.item?.content?.[0]?.transcript];
673
+ for (const value of candidates) {
674
+ if (typeof value === "string" && value.trim()) return value.trim();
675
+ }
676
+ return "";
677
+ }
678
+ function extractCompletedText(payload) {
679
+ const type = String(payload?.type || "");
680
+ if (!type.includes("completed")) return "";
681
+ const candidates = [payload?.transcript, payload?.text, payload?.item?.content?.[0]?.transcript, payload?.item?.transcript];
682
+ for (const value of candidates) {
683
+ if (typeof value === "string" && value.trim()) return value.trim();
684
+ }
685
+ return "";
686
+ }
687
+ function extractItemId(payload) {
688
+ const candidates = [payload?.item_id, payload?.item?.id];
689
+ for (const value of candidates) {
690
+ if (typeof value === "string" && value.trim()) {
691
+ return value.trim();
692
+ }
693
+ }
694
+ return null;
695
+ }
696
+ function isCommitBufferTooSmallError(message) {
697
+ const normalized = message.toLowerCase();
698
+ return normalized.includes("input audio buffer") && normalized.includes("buffer too small");
699
+ }
700
+ function isSessionDurationLimitError(message) {
701
+ const normalized = message.toLowerCase();
702
+ return normalized.includes("session") && (normalized.includes("maximum duration") || normalized.includes("max duration"));
703
+ }
704
+ function isOpenAISpeechAvailable() {
705
+ if (_reactNative.Platform.OS !== "web") return false;
706
+ if (typeof window === "undefined") return false;
707
+ return typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia && typeof RTCPeerConnection !== "undefined";
708
+ }
709
+ function getOpenAISpeechCapabilities() {
710
+ return {
711
+ available: isOpenAISpeechAvailable(),
712
+ platform: _reactNative.Platform.OS,
713
+ supportsServerVAD: true,
714
+ transport: "webrtc"
715
+ };
716
+ }
717
+ var _default = exports.default = OpenAISpeechRecognizer;
718
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3ROYXRpdmUiLCJfbG9nZ2VyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9ncm9xVHJhbnNjcmlwdGlvbiIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJvIiwiaSIsImYiLCJfX3Byb3RvX18iLCJoYXMiLCJnZXQiLCJzZXQiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsIm93bktleXMiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJfdG9Qcm9wZXJ0eUtleSIsInZhbHVlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJfdG9QcmltaXRpdmUiLCJTeW1ib2wiLCJ0b1ByaW1pdGl2ZSIsIlR5cGVFcnJvciIsIlN0cmluZyIsIk51bWJlciIsIkRFRkFVTFRfUkVBTFRJTUVfTU9ERUwiLCJERUZBVUxUX1JFQUxUSU1FX1dFQlJUQ19VUkwiLCJEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TIiwiU0VTU0lPTl9DQUNIRV9SRUxFQVNFX0RFTEFZX01TIiwiRU5BQkxFX1NFU1NJT05fQ0FDSEUiLCJwcm9jZXNzIiwiZW52IiwiTk9ERV9FTlYiLCJjYWNoZWRXZWJSdGNTZXNzaW9uIiwicGMiLCJkYXRhQ2hhbm5lbCIsInN0cmVhbSIsInJlbGVhc2VUaW1lciIsImNsZWFyQ2FjaGVkUmVsZWFzZVRpbWVyIiwiY2xlYXJUaW1lb3V0IiwiY2xvc2VXZWJSdGNTZXNzaW9uUmVzb3VyY2VzIiwic2Vzc2lvbiIsImNsb3NlIiwiZXJyb3IiLCJsb2dnZXIiLCJ3YXJuIiwiZ2V0VHJhY2tzIiwidHJhY2siLCJzdG9wIiwic2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSIsInNldFRpbWVvdXQiLCJoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSIsInBlcnNpc3RTZXNzaW9uQ2FjaGUiLCJPcGVuQUlTcGVlY2hSZWNvZ25pemVyIiwic2hvdWxkTGlzdGVuIiwic3BlZWNoU3RhdHVzQ2FsbGJhY2siLCJzcGVlY2hSZXN1bHRDYWxsYmFjayIsInNwZWVjaFRyYW5zbGF0aW9uQ2FsbGJhY2siLCJzcGVlY2hSZWFkeUNhbGxiYWNrIiwiY2xpZW50U2VjcmV0Iiwib3BlbmFpVHJhbnNjcmlwdGlvblNlc3Npb25FbmRwb2ludCIsIm9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQiLCJvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybCIsIm9wZW5haVJlYWx0aW1lTW9kZWwiLCJvcGVuYWlUcmFuc2xhdGlvbk1vZGVsIiwib3BlbmFpVmFkRW5hYmxlZCIsIm9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlIiwib3BlbmFpVmFkVGhyZXNob2xkIiwib3BlbmFpVmFkUHJlZml4UGFkZGluZ01zIiwib3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMiLCJvcGVuYWlWYWRJZGxlVGltZW91dE1zIiwib3BlbmFpUHJld2FybU9uTW91bnQiLCJsYW5ndWFnZSIsInJlcXVlc3RDb250ZXh0UHJvdmlkZXIiLCJvbkVycm9yIiwicHJveHlBdXRoVG9rZW4iLCJpc1JlY29yZGluZyIsInNldElzUmVjb3JkaW5nIiwidXNlU3RhdGUiLCJzZXNzaW9uUmVjb3ZlcnlUb2tlbiIsInNldFNlc3Npb25SZWNvdmVyeVRva2VuIiwiY2FjaGVkU2Vzc2lvblJlZiIsInVzZVJlZiIsInBjUmVmIiwiY3VycmVudCIsImRhdGFDaGFubmVsUmVmIiwic3RyZWFtUmVmIiwic2Vzc2lvbkluaXRSZWYiLCJmaW5hbFRyYW5zY3JpcHRSZWYiLCJpbnRlcmltVHJhbnNjcmlwdFJlZiIsInN0b3BJbkZsaWdodFJlZiIsImZpbmFsaXplZFJlZiIsImF3YWl0aW5nQ29tbWl0RmluYWxSZWYiLCJjb21taXRGaW5hbFRpbWVvdXRSZWYiLCJkaWRQcmV3YXJtUmVmIiwiaXNSZWNvcmRpbmdSZWYiLCJzaG91bGRMaXN0ZW5SZWYiLCJvcGVuYWlQcmV3YXJtT25Nb3VudFJlZiIsInNlc3Npb25SZWNvdmVyeU1vZGVSZWYiLCJzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZiIsInN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYiLCJlbWl0RXJyb3IiLCJ1c2VDYWxsYmFjayIsImVyciIsIkVycm9yIiwicmVzZXRUcmFuc2NyaXB0UmVmcyIsImdldEJ1ZmZlcmVkVHJhbnNjcmlwdCIsInRyaW0iLCJjbGVhckNvbW1pdEZpbmFsV2FpdCIsIm5vdGlmeVJlYWR5IiwicmVhZHkiLCJzZXRBdWRpb0NhcHR1cmVFbmFibGVkIiwiZW5hYmxlZCIsInRyYWNrcyIsImdldEF1ZGlvVHJhY2tzIiwia2luZCIsImNsZWFyUmVhbHRpbWVJbnB1dEJ1ZmZlciIsInJlYXNvbiIsInJlYWR5U3RhdGUiLCJzZW5kIiwiSlNPTiIsInN0cmluZ2lmeSIsInR5cGUiLCJkZWJ1ZyIsImdldFJlcXVlc3RDb250ZXh0SGVhZGVycyIsImNvbnRleHQiLCJoZWFkZXJzIiwidGhyZWFkSWQiLCJ0dXJuSWQiLCJzZXNzaW9uSWQiLCJ1bmRlZmluZWQiLCJzZW50cnlUcmFjZSIsImJhZ2dhZ2UiLCJ1c2VFZmZlY3QiLCJoYW5kbGVFeHBpcmVkU2Vzc2lvbiIsImNoYW5uZWwiLCJidWlsZFR1cm5EZXRlY3Rpb24iLCJ0aHJlc2hvbGQiLCJwcmVmaXhfcGFkZGluZ19tcyIsInNpbGVuY2VfZHVyYXRpb25fbXMiLCJ3YWl0Rm9yRGF0YUNoYW5uZWxPcGVuIiwicmVhZFN0YXRlIiwic3RhcnQiLCJEYXRlIiwibm93IiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2xhdGVUb0VuZ2xpc2giLCJ0ZXh0IiwiaW5wdXQiLCJ0b0xvd2VyQ2FzZSIsInN0YXJ0c1dpdGgiLCJBdXRob3JpemF0aW9uIiwicmVzcG9uc2UiLCJmZXRjaCIsIm1ldGhvZCIsImJvZHkiLCJzb3VyY2VMYW5ndWFnZSIsIm1vZGVsIiwib2siLCJjYXRjaCIsInN0YXR1cyIsInBheWxvYWQiLCJqc29uIiwidHJhbnNsYXRlZCIsImVtaXRGaW5hbCIsImZpbmFsVGV4dCIsInBhcnNlVGV4dCIsImZpbmFsaXplQW5kUmVzZXQiLCJoYW5kbGVSZWFsdGltZU1lc3NhZ2UiLCJhY2NlcHRzVHJhbnNjcmlwdCIsInNob3VsZFB1Ymxpc2hJbnRlcmltIiwiZGVsdGEiLCJleHRyYWN0RGVsdGFUZXh0IiwiY29tcGxldGVkIiwiZXh0cmFjdENvbXBsZXRlZFRleHQiLCJtZXJnZVRyYW5zY3JpcHRQYXJ0cyIsImxvb2tzQ29tcGxldGVkIiwiaW5jbHVkZXMiLCJwYXVzZVRyYW5zY3JpcHQiLCJzdGFydFdlYlJ0Y1Nlc3Npb24iLCJ0b2tlbiIsIlJUQ1BlZXJDb25uZWN0aW9uIiwibmF2aWdhdG9yIiwibWVkaWFEZXZpY2VzIiwiZ2V0VXNlck1lZGlhIiwiYXVkaW8iLCJlY2hvQ2FuY2VsbGF0aW9uIiwibm9pc2VTdXBwcmVzc2lvbiIsImF1dG9HYWluQ29udHJvbCIsImFkZFRyYWNrIiwiY3JlYXRlRGF0YUNoYW5uZWwiLCJvbm9wZW4iLCJvbm1lc3NhZ2UiLCJldmVudCIsInBhcnNlIiwiZGF0YSIsIm1lc3NhZ2UiLCJpc0NvbW1pdEJ1ZmZlclRvb1NtYWxsRXJyb3IiLCJpc1Nlc3Npb25EdXJhdGlvbkxpbWl0RXJyb3IiLCJvbmVycm9yIiwib25jbG9zZSIsIm9mZmVyIiwiY3JlYXRlT2ZmZXIiLCJzZXRMb2NhbERlc2NyaXB0aW9uIiwic2RwIiwiYW5zd2VyU2RwIiwic2V0UmVtb3RlRGVzY3JpcHRpb24iLCJnZXRFcGhlbWVyYWxUb2tlbiIsImlucHV0X2F1ZGlvX2Zvcm1hdCIsImlucHV0X2F1ZGlvX3RyYW5zY3JpcHRpb24iLCJ0dXJuX2RldGVjdGlvbiIsImNsaWVudF9zZWNyZXQiLCJoYXNSZXVzYWJsZVNlc3Npb24iLCJlbnN1cmVXZWJSdGNTZXNzaW9uIiwiY2xlYW51cCIsImNhbmNlbGxlZCIsInJlY292ZXJ5TW9kZSIsInN0YXJ0UmVjb3JkaW5nIiwicmV1c2luZ1dhcm1TZXNzaW9uIiwic3RvcFJlY29yZGluZyIsImJ1ZmZlcmVkIiwidGhlbiIsImNyZWF0ZUVsZW1lbnQiLCJWaWV3IiwiZXhwb3J0cyIsImNhbmRpZGF0ZXMiLCJ0ZXh0X2RlbHRhIiwidHJhbnNjcmlwdF9kZWx0YSIsIml0ZW0iLCJjb250ZW50IiwidHJhbnNjcmlwdCIsImV4dHJhY3RJdGVtSWQiLCJpdGVtX2lkIiwiaWQiLCJub3JtYWxpemVkIiwiaXNPcGVuQUlTcGVlY2hBdmFpbGFibGUiLCJQbGF0Zm9ybSIsIk9TIiwid2luZG93IiwiZ2V0T3BlbkFJU3BlZWNoQ2FwYWJpbGl0aWVzIiwiYXZhaWxhYmxlIiwicGxhdGZvcm0iLCJzdXBwb3J0c1NlcnZlclZBRCIsInRyYW5zcG9ydCIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NwZWVjaC1yZWNvZ25pdGlvbi9zcGVlY2gtcmVjb2duaXRpb24tb3BlbmFpLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgUGxhdGZvcm0sIFZpZXcgfSBmcm9tIFwicmVhY3QtbmF0aXZlXCI7XG5pbXBvcnQgbG9nZ2VyIGZyb20gXCIuLi9sb2dnZXJcIjtcbmltcG9ydCB7IG1lcmdlVHJhbnNjcmlwdFBhcnRzIH0gZnJvbSBcIi4vdXRpbHMvZ3JvcS10cmFuc2NyaXB0aW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJU3BlZWNoUmVjb2duaXplclByb3BzIHtcbiAgc2hvdWxkTGlzdGVuOiBib29sZWFuO1xuICBzcGVlY2hTdGF0dXNDYWxsYmFjazogKHN0YXR1czogYm9vbGVhbiwgdHJhbnNjcmlwdDogc3RyaW5nKSA9PiB2b2lkO1xuICBzcGVlY2hSZXN1bHRDYWxsYmFjazogKHJlc3VsdDogc3RyaW5nKSA9PiB2b2lkO1xuICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrPzogKHRyYW5zbGF0aW9uOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHNwZWVjaFJlYWR5Q2FsbGJhY2s/OiAocmVhZHk6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIGNsaWVudFNlY3JldD86IHN0cmluZztcbiAgb3BlbmFpVHJhbnNjcmlwdGlvblNlc3Npb25FbmRwb2ludDogc3RyaW5nO1xuICBvcGVuYWlUcmFuc2xhdGlvbkVuZHBvaW50Pzogc3RyaW5nO1xuICBvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybD86IHN0cmluZztcbiAgb3BlbmFpUmVhbHRpbWVNb2RlbD86IFwiZ3B0LTRvLXRyYW5zY3JpYmVcIiB8IFwiZ3B0LTRvLW1pbmktdHJhbnNjcmliZVwiO1xuICBvcGVuYWlUcmFuc2xhdGlvbk1vZGVsPzogc3RyaW5nO1xuICBvcGVuYWlWYWRFbmFibGVkPzogYm9vbGVhbjtcbiAgb3BlbmFpQXV0b1N0b3BPblZhZFNpbGVuY2U/OiBib29sZWFuO1xuICBvcGVuYWlWYWRUaHJlc2hvbGQ/OiBudW1iZXI7XG4gIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcz86IG51bWJlcjtcbiAgb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXM/OiBudW1iZXI7XG4gIG9wZW5haVZhZElkbGVUaW1lb3V0TXM/OiBudW1iZXI7XG4gIG9wZW5haVByZXdhcm1Pbk1vdW50PzogYm9vbGVhbjtcbiAgbGFuZ3VhZ2U/OiBzdHJpbmc7XG4gIHJlcXVlc3RDb250ZXh0UHJvdmlkZXI/OiAoKSA9PlxuICAgIHwge1xuICAgICAgICB0aHJlYWRJZD86IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHR1cm5JZD86IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHNlc3Npb25JZD86IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG4gICAgICAgIHNlbnRyeVRyYWNlPzogc3RyaW5nIHwgbnVsbDtcbiAgICAgICAgYmFnZ2FnZT86IHN0cmluZyB8IG51bGw7XG4gICAgICB9XG4gICAgfCBudWxsXG4gICAgfCB1bmRlZmluZWQ7XG4gIG9uRXJyb3I/OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufVxuXG5jb25zdCBERUZBVUxUX1JFQUxUSU1FX01PREVMID0gXCJncHQtNG8tdHJhbnNjcmliZVwiO1xuY29uc3QgREVGQVVMVF9SRUFMVElNRV9XRUJSVENfVVJMID1cbiAgXCJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxL3JlYWx0aW1lP2ludGVudD10cmFuc2NyaXB0aW9uXCI7XG5jb25zdCBEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TID0gNjAwMDtcbmNvbnN0IFNFU1NJT05fQ0FDSEVfUkVMRUFTRV9ERUxBWV9NUyA9IDQ1XzAwMDtcbmNvbnN0IEVOQUJMRV9TRVNTSU9OX0NBQ0hFID1cbiAgdHlwZW9mIHByb2Nlc3MgPT09IFwidW5kZWZpbmVkXCIgPyB0cnVlIDogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwidGVzdFwiO1xuXG50eXBlIENhY2hlZFdlYlJ0Y1Nlc3Npb24gPSB7XG4gIHBjOiBSVENQZWVyQ29ubmVjdGlvbiB8IG51bGw7XG4gIGRhdGFDaGFubmVsOiBSVENEYXRhQ2hhbm5lbCB8IG51bGw7XG4gIHN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsO1xuICByZWxlYXNlVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbDtcbn07XG5cbmNvbnN0IGNhY2hlZFdlYlJ0Y1Nlc3Npb246IENhY2hlZFdlYlJ0Y1Nlc3Npb24gPSB7XG4gIHBjOiBudWxsLFxuICBkYXRhQ2hhbm5lbDogbnVsbCxcbiAgc3RyZWFtOiBudWxsLFxuICByZWxlYXNlVGltZXI6IG51bGwsXG59O1xuXG5mdW5jdGlvbiBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIpIHtcbiAgICBjbGVhclRpbWVvdXQoY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIpO1xuICAgIGNhY2hlZFdlYlJ0Y1Nlc3Npb24ucmVsZWFzZVRpbWVyID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoXG4gIHNlc3Npb246IFBpY2s8Q2FjaGVkV2ViUnRjU2Vzc2lvbiwgXCJwY1wiIHwgXCJkYXRhQ2hhbm5lbFwiIHwgXCJzdHJlYW1cIj5cbikge1xuICBpZiAoc2Vzc2lvbi5kYXRhQ2hhbm5lbCkge1xuICAgIHRyeSB7XG4gICAgICBzZXNzaW9uLmRhdGFDaGFubmVsLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gY2xvc2UgZGF0YSBjaGFubmVsIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc2Vzc2lvbi5wYykge1xuICAgIHRyeSB7XG4gICAgICBzZXNzaW9uLnBjLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gY2xvc2UgcGVlciB3YXJuaW5nOlwiLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNlc3Npb24uc3RyZWFtKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNlc3Npb24uc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB0cmFjay5zdG9wKCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihcIltPcGVuQUkgU1JdIHN0b3Agc3RyZWFtIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSgpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybjtcbiAgfVxuICBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpO1xuICBjYWNoZWRXZWJSdGNTZXNzaW9uLnJlbGVhc2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGNsb3NlV2ViUnRjU2Vzc2lvblJlc291cmNlcyhjYWNoZWRXZWJSdGNTZXNzaW9uKTtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLnBjID0gbnVsbDtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gbnVsbDtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLnN0cmVhbSA9IG51bGw7XG4gICAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIgPSBudWxsO1xuICB9LCBTRVNTSU9OX0NBQ0hFX1JFTEVBU0VfREVMQVlfTVMpO1xufVxuXG5mdW5jdGlvbiBoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSgpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybiB7XG4gICAgICBwYzogbnVsbCxcbiAgICAgIGRhdGFDaGFubmVsOiBudWxsLFxuICAgICAgc3RyZWFtOiBudWxsLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBwYzogY2FjaGVkV2ViUnRjU2Vzc2lvbi5wYyxcbiAgICBkYXRhQ2hhbm5lbDogY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCxcbiAgICBzdHJlYW06IGNhY2hlZFdlYlJ0Y1Nlc3Npb24uc3RyZWFtLFxuICB9O1xufVxuXG5mdW5jdGlvbiBwZXJzaXN0U2Vzc2lvbkNhY2hlKFxuICBwYzogUlRDUGVlckNvbm5lY3Rpb24gfCBudWxsLFxuICBkYXRhQ2hhbm5lbDogUlRDRGF0YUNoYW5uZWwgfCBudWxsLFxuICBzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbFxuKSB7XG4gIGlmICghRU5BQkxFX1NFU1NJT05fQ0FDSEUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5wYyA9IHBjO1xuICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gZGF0YUNoYW5uZWw7XG4gIGNhY2hlZFdlYlJ0Y1Nlc3Npb24uc3RyZWFtID0gc3RyZWFtO1xufVxuXG5leHBvcnQgY29uc3QgT3BlbkFJU3BlZWNoUmVjb2duaXplcjogUmVhY3QuRkM8T3BlbkFJU3BlZWNoUmVjb2duaXplclByb3BzPiA9ICh7XG4gIHNob3VsZExpc3RlbixcbiAgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssXG4gIHNwZWVjaFJlc3VsdENhbGxiYWNrLFxuICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrLFxuICBzcGVlY2hSZWFkeUNhbGxiYWNrLFxuICBjbGllbnRTZWNyZXQsXG4gIG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsXG4gIG9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQsXG4gIG9wZW5haVJlYWx0aW1lV2ViUnRjVXJsID0gREVGQVVMVF9SRUFMVElNRV9XRUJSVENfVVJMLFxuICBvcGVuYWlSZWFsdGltZU1vZGVsID0gREVGQVVMVF9SRUFMVElNRV9NT0RFTCxcbiAgb3BlbmFpVHJhbnNsYXRpb25Nb2RlbCA9IFwiZ3B0LTQuMS1taW5pXCIsXG4gIG9wZW5haVZhZEVuYWJsZWQgPSB0cnVlLFxuICBvcGVuYWlBdXRvU3RvcE9uVmFkU2lsZW5jZSA9IGZhbHNlLFxuICBvcGVuYWlWYWRUaHJlc2hvbGQgPSAwLjcsXG4gIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcyA9IDQwMCxcbiAgb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMgPSAxMDAwLFxuICBvcGVuYWlWYWRJZGxlVGltZW91dE1zID0gNjAwMCxcbiAgb3BlbmFpUHJld2FybU9uTW91bnQgPSBmYWxzZSxcbiAgbGFuZ3VhZ2UgPSBcImVuXCIsXG4gIHJlcXVlc3RDb250ZXh0UHJvdmlkZXIsXG4gIG9uRXJyb3IsXG59KSA9PiB7XG4gIGNvbnN0IHByb3h5QXV0aFRva2VuID0gY2xpZW50U2VjcmV0O1xuICBjb25zdCBbaXNSZWNvcmRpbmcsIHNldElzUmVjb3JkaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW3Nlc3Npb25SZWNvdmVyeVRva2VuLCBzZXRTZXNzaW9uUmVjb3ZlcnlUb2tlbl0gPSB1c2VTdGF0ZSgwKTtcbiAgY29uc3QgY2FjaGVkU2Vzc2lvblJlZiA9IHVzZVJlZihoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSgpKTtcbiAgY29uc3QgcGNSZWYgPSB1c2VSZWY8UlRDUGVlckNvbm5lY3Rpb24gfCBudWxsPihjYWNoZWRTZXNzaW9uUmVmLmN1cnJlbnQucGMpO1xuICBjb25zdCBkYXRhQ2hhbm5lbFJlZiA9IHVzZVJlZjxSVENEYXRhQ2hhbm5lbCB8IG51bGw+KFxuICAgIGNhY2hlZFNlc3Npb25SZWYuY3VycmVudC5kYXRhQ2hhbm5lbFxuICApO1xuICBjb25zdCBzdHJlYW1SZWYgPSB1c2VSZWY8TWVkaWFTdHJlYW0gfCBudWxsPihjYWNoZWRTZXNzaW9uUmVmLmN1cnJlbnQuc3RyZWFtKTtcbiAgY29uc3Qgc2Vzc2lvbkluaXRSZWYgPSB1c2VSZWY8UHJvbWlzZTx2b2lkPiB8IG51bGw+KG51bGwpO1xuICBjb25zdCBmaW5hbFRyYW5zY3JpcHRSZWYgPSB1c2VSZWYoXCJcIik7XG4gIGNvbnN0IGludGVyaW1UcmFuc2NyaXB0UmVmID0gdXNlUmVmKFwiXCIpO1xuICBjb25zdCBzdG9wSW5GbGlnaHRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBmaW5hbGl6ZWRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBhd2FpdGluZ0NvbW1pdEZpbmFsUmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY29tbWl0RmluYWxUaW1lb3V0UmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGRpZFByZXdhcm1SZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBpc1JlY29yZGluZ1JlZiA9IHVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IHNob3VsZExpc3RlblJlZiA9IHVzZVJlZihzaG91bGRMaXN0ZW4pO1xuICBjb25zdCBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZiA9IHVzZVJlZihvcGVuYWlQcmV3YXJtT25Nb3VudCk7XG4gIGNvbnN0IHNlc3Npb25SZWNvdmVyeU1vZGVSZWYgPSB1c2VSZWY8XCJsaXN0ZW5cIiB8IFwicHJld2FybVwiIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgY29uc3Qgc3VwcHJlc3NlZENoYW5uZWxFcnJvclJlZiA9IHVzZVJlZjxSVENEYXRhQ2hhbm5lbCB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IGVtaXRFcnJvciA9IHVzZUNhbGxiYWNrKFxuICAgIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgY29uc3QgZXJyID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xuICAgICAgbG9nZ2VyLmVycm9yKFwiW09wZW5BSSBTUl0gZXJyb3I6XCIsIGVycik7XG4gICAgICBvbkVycm9yPy4oZXJyKTtcbiAgICB9LFxuICAgIFtvbkVycm9yXVxuICApO1xuXG4gIGNvbnN0IHJlc2V0VHJhbnNjcmlwdFJlZnMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBcIlwiO1xuICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBcIlwiO1xuICAgIGZpbmFsaXplZFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gIH0sIFtdKTtcblxuICBjb25zdCBnZXRCdWZmZXJlZFRyYW5zY3JpcHQgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGZpbmFsVHJhbnNjcmlwdFJlZi5jdXJyZW50IHx8XG4gICAgICBpbnRlcmltVHJhbnNjcmlwdFJlZi5jdXJyZW50XG4gICAgKS50cmltKCk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBjbGVhckNvbW1pdEZpbmFsV2FpdCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBhd2FpdGluZ0NvbW1pdEZpbmFsUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICBpZiAoY29tbWl0RmluYWxUaW1lb3V0UmVmLmN1cnJlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dChjb21taXRGaW5hbFRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBjb21taXRGaW5hbFRpbWVvdXRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3Qgbm90aWZ5UmVhZHkgPSB1c2VDYWxsYmFjayhcbiAgICAocmVhZHk6IGJvb2xlYW4pID0+IHtcbiAgICAgIHNwZWVjaFJlYWR5Q2FsbGJhY2s/LihyZWFkeSk7XG4gICAgfSxcbiAgICBbc3BlZWNoUmVhZHlDYWxsYmFja11cbiAgKTtcblxuICBjb25zdCBzZXRBdWRpb0NhcHR1cmVFbmFibGVkID0gdXNlQ2FsbGJhY2soKGVuYWJsZWQ6IGJvb2xlYW4pID0+IHtcbiAgICBjb25zdCBzdHJlYW0gPSBzdHJlYW1SZWYuY3VycmVudDtcbiAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFja3MgPVxuICAgICAgICB0eXBlb2YgKHN0cmVhbSBhcyBhbnkpLmdldEF1ZGlvVHJhY2tzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IChzdHJlYW0gYXMgYW55KS5nZXRBdWRpb1RyYWNrcygpXG4gICAgICAgICAgOiB0eXBlb2YgKHN0cmVhbSBhcyBhbnkpLmdldFRyYWNrcyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IChzdHJlYW0gYXMgYW55KVxuICAgICAgICAgICAgICAgIC5nZXRUcmFja3MoKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoKHRyYWNrOiBhbnkpID0+IHRyYWNrPy5raW5kID09PSBcImF1ZGlvXCIpXG4gICAgICAgICAgICA6IFtdO1xuXG4gICAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IGFueSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gdG9nZ2xlIGF1ZGlvIHRyYWNrIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gZW51bWVyYXRlIGF1ZGlvIHRyYWNrcyB3YXJuaW5nOlwiLCBlcnJvcik7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3QgY2xlYXJSZWFsdGltZUlucHV0QnVmZmVyID0gdXNlQ2FsbGJhY2soKHJlYXNvbjogc3RyaW5nKSA9PiB7XG4gICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQ/LnJlYWR5U3RhdGUgIT09IFwib3BlblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHsgdHlwZTogXCJpbnB1dF9hdWRpb19idWZmZXIuY2xlYXJcIiB9KVxuICAgICAgKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW09wZW5BSSBTUl0gY2xlYXJlZCBpbnB1dCBidWZmZXIgKCR7cmVhc29ufSlgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oXCJbT3BlbkFJIFNSXSBjbGVhciBpbnB1dCBidWZmZXIgd2FybmluZzpcIiwgZXJyb3IpO1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IGdldFJlcXVlc3RDb250ZXh0SGVhZGVycyA9IHVzZUNhbGxiYWNrKCgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gcmVxdWVzdENvbnRleHRQcm92aWRlcj8uKCk7XG4gICAgaWYgKCFjb250ZXh0KSByZXR1cm4ge307XG5cbiAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgaWYgKGNvbnRleHQudGhyZWFkSWQpIHtcbiAgICAgIGhlYWRlcnNbXCJ4LXRocmVhZC1pZFwiXSA9IFN0cmluZyhjb250ZXh0LnRocmVhZElkKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQudHVybklkKSB7XG4gICAgICBoZWFkZXJzW1wieC10dXJuLWlkXCJdID0gU3RyaW5nKGNvbnRleHQudHVybklkKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQuc2Vzc2lvbklkICE9PSB1bmRlZmluZWQgJiYgY29udGV4dC5zZXNzaW9uSWQgIT09IG51bGwpIHtcbiAgICAgIGhlYWRlcnNbXCJ4LXZvaWNlLXNlc3Npb24taWRcIl0gPSBTdHJpbmcoY29udGV4dC5zZXNzaW9uSWQpO1xuICAgIH1cbiAgICBpZiAoY29udGV4dC5zZW50cnlUcmFjZSkge1xuICAgICAgaGVhZGVyc1tcInNlbnRyeS10cmFjZVwiXSA9IFN0cmluZyhjb250ZXh0LnNlbnRyeVRyYWNlKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQuYmFnZ2FnZSkge1xuICAgICAgaGVhZGVycy5iYWdnYWdlID0gU3RyaW5nKGNvbnRleHQuYmFnZ2FnZSk7XG4gICAgfVxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LCBbcmVxdWVzdENvbnRleHRQcm92aWRlcl0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY2xlYXJDYWNoZWRSZWxlYXNlVGltZXIoKTtcbiAgICBpZiAoZGF0YUNoYW5uZWxSZWYuY3VycmVudD8ucmVhZHlTdGF0ZSA9PT0gXCJvcGVuXCIpIHtcbiAgICAgIG5vdGlmeVJlYWR5KHRydWUpO1xuICAgIH1cbiAgfSwgW25vdGlmeVJlYWR5XSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpc1JlY29yZGluZ1JlZi5jdXJyZW50ID0gaXNSZWNvcmRpbmc7XG4gIH0sIFtpc1JlY29yZGluZ10pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgc2hvdWxkTGlzdGVuUmVmLmN1cnJlbnQgPSBzaG91bGRMaXN0ZW47XG4gIH0sIFtzaG91bGRMaXN0ZW5dKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIG9wZW5haVByZXdhcm1Pbk1vdW50UmVmLmN1cnJlbnQgPSBvcGVuYWlQcmV3YXJtT25Nb3VudDtcbiAgfSwgW29wZW5haVByZXdhcm1Pbk1vdW50XSk7XG5cbiAgY29uc3QgaGFuZGxlRXhwaXJlZFNlc3Npb24gPSB1c2VDYWxsYmFjayhcbiAgICAoY2hhbm5lbDogUlRDRGF0YUNoYW5uZWwsIHBjOiBSVENQZWVyQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgIT09IGNoYW5uZWwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9IGNoYW5uZWw7XG4gICAgICBzZXNzaW9uUmVjb3ZlcnlNb2RlUmVmLmN1cnJlbnQgPSBzaG91bGRMaXN0ZW5SZWYuY3VycmVudFxuICAgICAgICA/IFwibGlzdGVuXCJcbiAgICAgICAgOiBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZi5jdXJyZW50XG4gICAgICAgICAgPyBcInByZXdhcm1cIlxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICAgIHJlc2V0VHJhbnNjcmlwdFJlZnMoKTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgc2Vzc2lvbkluaXRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoe1xuICAgICAgICBkYXRhQ2hhbm5lbDogY2hhbm5lbCxcbiAgICAgICAgcGMsXG4gICAgICAgIHN0cmVhbTogc3RyZWFtUmVmLmN1cnJlbnQsXG4gICAgICB9KTtcblxuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgPT09IGNoYW5uZWwpIHtcbiAgICAgICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCA9PT0gY2hhbm5lbCkge1xuICAgICAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwY1JlZi5jdXJyZW50ID09PSBwYykge1xuICAgICAgICBwY1JlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHN0cmVhbVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIHBlcnNpc3RTZXNzaW9uQ2FjaGUobnVsbCwgbnVsbCwgbnVsbCk7XG5cbiAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcblxuICAgICAgaWYgKHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudCkge1xuICAgICAgICBzZXRTZXNzaW9uUmVjb3ZlcnlUb2tlbigodmFsdWUpID0+IHZhbHVlICsgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9XG4gICAgfSxcbiAgICBbXG4gICAgICBjbGVhckNvbW1pdEZpbmFsV2FpdCxcbiAgICAgIG5vdGlmeVJlYWR5LFxuICAgICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQsXG4gICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgYnVpbGRUdXJuRGV0ZWN0aW9uID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICghb3BlbmFpVmFkRW5hYmxlZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFwic2VydmVyX3ZhZFwiLFxuICAgICAgdGhyZXNob2xkOiBvcGVuYWlWYWRUaHJlc2hvbGQsXG4gICAgICBwcmVmaXhfcGFkZGluZ19tczogb3BlbmFpVmFkUHJlZml4UGFkZGluZ01zLFxuICAgICAgc2lsZW5jZV9kdXJhdGlvbl9tczogb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMsXG4gICAgfTtcbiAgfSwgW1xuICAgIG9wZW5haVZhZEVuYWJsZWQsXG4gICAgb3BlbmFpVmFkVGhyZXNob2xkLFxuICAgIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcyxcbiAgICBvcGVuYWlWYWRTaWxlbmNlRHVyYXRpb25NcyxcbiAgXSk7XG5cbiAgY29uc3Qgd2FpdEZvckRhdGFDaGFubmVsT3BlbiA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jIChjaGFubmVsOiBSVENEYXRhQ2hhbm5lbCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgY29uc3QgcmVhZFN0YXRlID0gKCkgPT4gU3RyaW5nKGNoYW5uZWwucmVhZHlTdGF0ZSk7XG4gICAgICBpZiAocmVhZFN0YXRlKCkgPT09IFwib3BlblwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnQgPCBEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TKSB7XG4gICAgICAgIGlmIChyZWFkU3RhdGUoKSA9PT0gXCJvcGVuXCIpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgNTApKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE9wZW5BSSByZWFsdGltZSBkYXRhIGNoYW5uZWwgZGlkIG5vdCBvcGVuIHdpdGhpbiAke0RBVEFfQ0hBTk5FTF9PUEVOX1RJTUVPVVRfTVN9bXMgKHN0YXRlPSR7cmVhZFN0YXRlKCl9KWBcbiAgICAgICk7XG4gICAgfSxcbiAgICBbXVxuICApO1xuXG4gIGNvbnN0IHRyYW5zbGF0ZVRvRW5nbGlzaCA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jICh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgY29uc3QgaW5wdXQgPSB0ZXh0LnRyaW0oKTtcbiAgICAgIGlmICghaW5wdXQgfHwgIW9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQpIHJldHVybiBcIlwiO1xuICAgICAgaWYgKGxhbmd1YWdlLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChcImVuXCIpKSByZXR1cm4gXCJcIjtcblxuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIC4uLmdldFJlcXVlc3RDb250ZXh0SGVhZGVycygpLFxuICAgICAgfTtcbiAgICAgIGlmIChwcm94eUF1dGhUb2tlbikge1xuICAgICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7cHJveHlBdXRoVG9rZW59YDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChvcGVuYWlUcmFuc2xhdGlvbkVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICB0ZXh0OiBpbnB1dCxcbiAgICAgICAgICBzb3VyY2VMYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICAgICAgbW9kZWw6IG9wZW5haVRyYW5zbGF0aW9uTW9kZWwsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKS5jYXRjaCgoKSA9PiBcIlwiKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmFuc2xhdGlvbiBmYWlsZWQgKCR7cmVzcG9uc2Uuc3RhdHVzfSk6ICR7Ym9keX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKS5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZWQgPVxuICAgICAgICB0eXBlb2YgcGF5bG9hZD8udGV4dCA9PT0gXCJzdHJpbmdcIiA/IHBheWxvYWQudGV4dC50cmltKCkgOiBcIlwiO1xuICAgICAgaWYgKHRyYW5zbGF0ZWQpIHtcbiAgICAgICAgc3BlZWNoVHJhbnNsYXRpb25DYWxsYmFjaz8uKHRyYW5zbGF0ZWQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZWQ7XG4gICAgfSxcbiAgICBbXG4gICAgICBwcm94eUF1dGhUb2tlbixcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgZ2V0UmVxdWVzdENvbnRleHRIZWFkZXJzLFxuICAgICAgb3BlbmFpVHJhbnNsYXRpb25FbmRwb2ludCxcbiAgICAgIG9wZW5haVRyYW5zbGF0aW9uTW9kZWwsXG4gICAgICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBlbWl0RmluYWwgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKGZpbmFsaXplZFJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgZmluYWxpemVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgY29uc3QgZmluYWxUZXh0ID0gKFxuICAgICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQgfHxcbiAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnRcbiAgICApLnRyaW0oKTtcblxuICAgIGxldCBwYXJzZVRleHQgPSBmaW5hbFRleHQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZWQgPSBhd2FpdCB0cmFuc2xhdGVUb0VuZ2xpc2goZmluYWxUZXh0KTtcbiAgICAgIGlmICh0cmFuc2xhdGVkKSB7XG4gICAgICAgIHBhcnNlVGV4dCA9IHRyYW5zbGF0ZWQ7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gdHJhbnNsYXRpb24gZmFpbGVkOlwiLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICAgIGlmIChwYXJzZVRleHQpIHtcbiAgICAgICAgc3BlZWNoUmVzdWx0Q2FsbGJhY2socGFyc2VUZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtzcGVlY2hSZXN1bHRDYWxsYmFjaywgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssIHRyYW5zbGF0ZVRvRW5nbGlzaF0pO1xuXG4gIGNvbnN0IGZpbmFsaXplQW5kUmVzZXQgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICBhd2FpdCBlbWl0RmluYWwoKTtcbiAgICByZXNldFRyYW5zY3JpcHRSZWZzKCk7XG4gIH0sIFtjbGVhckNvbW1pdEZpbmFsV2FpdCwgZW1pdEZpbmFsLCByZXNldFRyYW5zY3JpcHRSZWZzXSk7XG5cbiAgY29uc3QgaGFuZGxlUmVhbHRpbWVNZXNzYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHBheWxvYWQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgdHlwZSA9IFN0cmluZyhwYXlsb2FkPy50eXBlIHx8IFwiXCIpO1xuICAgICAgY29uc3QgYWNjZXB0c1RyYW5zY3JpcHQgPVxuICAgICAgICBpc1JlY29yZGluZ1JlZi5jdXJyZW50IHx8IGF3YWl0aW5nQ29tbWl0RmluYWxSZWYuY3VycmVudDtcbiAgICAgIGlmICghYWNjZXB0c1RyYW5zY3JpcHQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaG91bGRQdWJsaXNoSW50ZXJpbSA9IGlzUmVjb3JkaW5nUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBkZWx0YSA9IGV4dHJhY3REZWx0YVRleHQocGF5bG9hZCk7XG4gICAgICBjb25zdCBjb21wbGV0ZWQgPSBleHRyYWN0Q29tcGxldGVkVGV4dChwYXlsb2FkKTtcblxuICAgICAgaWYgKGRlbHRhKSB7XG4gICAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBtZXJnZVRyYW5zY3JpcHRQYXJ0cyhcbiAgICAgICAgICBmaW5hbFRyYW5zY3JpcHRSZWYuY3VycmVudCxcbiAgICAgICAgICBkZWx0YVxuICAgICAgICApO1xuICAgICAgICBpZiAoc2hvdWxkUHVibGlzaEludGVyaW0pIHtcbiAgICAgICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayh0cnVlLCBpbnRlcmltVHJhbnNjcmlwdFJlZi5jdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tcGxldGVkKSB7XG4gICAgICAgIGZpbmFsVHJhbnNjcmlwdFJlZi5jdXJyZW50ID0gbWVyZ2VUcmFuc2NyaXB0UGFydHMoXG4gICAgICAgICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQsXG4gICAgICAgICAgY29tcGxldGVkXG4gICAgICAgICk7XG4gICAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBmaW5hbFRyYW5zY3JpcHRSZWYuY3VycmVudDtcbiAgICAgICAgaWYgKHNob3VsZFB1Ymxpc2hJbnRlcmltKSB7XG4gICAgICAgICAgc3BlZWNoU3RhdHVzQ2FsbGJhY2sodHJ1ZSwgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxvb2tzQ29tcGxldGVkID0gISFjb21wbGV0ZWQgfHwgdHlwZS5pbmNsdWRlcyhcImNvbXBsZXRlZFwiKTtcbiAgICAgIGlmIChcbiAgICAgICAgYXdhaXRpbmdDb21taXRGaW5hbFJlZi5jdXJyZW50ICYmXG4gICAgICAgIGxvb2tzQ29tcGxldGVkICYmXG4gICAgICAgIGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCgpXG4gICAgICApIHtcbiAgICAgICAgZmluYWxpemVBbmRSZXNldCgpLmNhdGNoKChlcnJvcikgPT4gZW1pdEVycm9yKGVycm9yKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlICYmIHR5cGUgPT09IFwiaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkXCIpIHtcbiAgICAgICAgY29uc3QgcGF1c2VUcmFuc2NyaXB0ID0gZ2V0QnVmZmVyZWRUcmFuc2NyaXB0KCk7XG4gICAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBwYXVzZVRyYW5zY3JpcHQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgZW1pdEVycm9yLFxuICAgICAgZmluYWxpemVBbmRSZXNldCxcbiAgICAgIGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCxcbiAgICAgIG9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlLFxuICAgICAgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssXG4gICAgXVxuICApO1xuXG4gIGNvbnN0IHN0YXJ0V2ViUnRjU2Vzc2lvbiA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jICh0b2tlbjogc3RyaW5nKSA9PiB7XG4gICAgICBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpO1xuICAgICAgaWYgKHR5cGVvZiBSVENQZWVyQ29ubmVjdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSVENQZWVyQ29ubmVjdGlvbiBpcyB1bmF2YWlsYWJsZSBvbiB3ZWIgcnVudGltZVwiKTtcbiAgICAgIH1cbiAgICAgIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcz8uZ2V0VXNlck1lZGlhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhIGlzIHVuYXZhaWxhYmxlXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgZWNob0NhbmNlbGxhdGlvbjogdHJ1ZSxcbiAgICAgICAgICBub2lzZVN1cHByZXNzaW9uOiB0cnVlLFxuICAgICAgICAgIGF1dG9HYWluQ29udHJvbDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtUmVmLmN1cnJlbnQgPSBzdHJlYW07XG4gICAgICBwZXJzaXN0U2Vzc2lvbkNhY2hlKHBjUmVmLmN1cnJlbnQsIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsIHN0cmVhbVJlZi5jdXJyZW50KTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuXG4gICAgICBjb25zdCBwYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbigpO1xuICAgICAgcGNSZWYuY3VycmVudCA9IHBjO1xuICAgICAgcGVyc2lzdFNlc3Npb25DYWNoZShwY1JlZi5jdXJyZW50LCBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50LCBzdHJlYW1SZWYuY3VycmVudCk7XG4gICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHBjLmFkZFRyYWNrKHRyYWNrLCBzdHJlYW0pKTtcblxuICAgICAgY29uc3QgZGF0YUNoYW5uZWwgPSBwYy5jcmVhdGVEYXRhQ2hhbm5lbChcIm9haS1ldmVudHNcIik7XG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50ID0gZGF0YUNoYW5uZWw7XG4gICAgICBwZXJzaXN0U2Vzc2lvbkNhY2hlKHBjUmVmLmN1cnJlbnQsIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsIHN0cmVhbVJlZi5jdXJyZW50KTtcbiAgICAgIGRhdGFDaGFubmVsLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgbm90aWZ5UmVhZHkodHJ1ZSk7XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25tZXNzYWdlID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5wYXJzZShTdHJpbmcoZXZlbnQuZGF0YSB8fCBcInt9XCIpKTtcbiAgICAgICAgICBpZiAocGF5bG9hZD8udHlwZSA9PT0gXCJlcnJvclwiKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gU3RyaW5nKFxuICAgICAgICAgICAgICBwYXlsb2FkPy5lcnJvcj8ubWVzc2FnZSB8fCBcIk9wZW5BSSByZWFsdGltZSBlcnJvclwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGlzQ29tbWl0QnVmZmVyVG9vU21hbGxFcnJvcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgICAvLyBJZ25vcmUgY29tbWl0IGJ1ZmZlci10b28tc21hbGwgZXJyb3JzIGZvciBsb3ctbGF0ZW5jeSBmYXN0LXN0b3AgcGF0aC5cbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU2Vzc2lvbkR1cmF0aW9uTGltaXRFcnJvcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgICBoYW5kbGVFeHBpcmVkU2Vzc2lvbihkYXRhQ2hhbm5lbCwgcGMpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhbmRsZVJlYWx0aW1lTWVzc2FnZShwYXlsb2FkKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBlbWl0RXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgaWYgKHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9PT0gZGF0YUNoYW5uZWwpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgICBlbWl0RXJyb3IobmV3IEVycm9yKFwiT3BlbkFJIHJlYWx0aW1lIGRhdGEgY2hhbm5lbCBlcnJvclwiKSk7XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgPT09IGRhdGFDaGFubmVsKSB7XG4gICAgICAgICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhY2hlZFdlYlJ0Y1Nlc3Npb24uZGF0YUNoYW5uZWwgPT09IGRhdGFDaGFubmVsKSB7XG4gICAgICAgICAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgfTtcblxuICAgICAgY29uc3Qgb2ZmZXIgPSBhd2FpdCBwYy5jcmVhdGVPZmZlcigpO1xuICAgICAgYXdhaXQgcGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcik7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gob3BlbmFpUmVhbHRpbWVXZWJSdGNVcmwsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gLFxuICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vc2RwXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IG9mZmVyLnNkcCB8fCBcIlwiLFxuICAgICAgfSk7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXNwb25zZS50ZXh0KCkuY2F0Y2goKCkgPT4gXCJcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgd2VicnRjIG5lZ290aWF0aW9uIGZhaWxlZCAoJHtyZXNwb25zZS5zdGF0dXN9KTogJHtib2R5fWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhbnN3ZXJTZHAgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICBhd2FpdCBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6IFwiYW5zd2VyXCIsXG4gICAgICAgIHNkcDogYW5zd2VyU2RwLFxuICAgICAgfSBhcyBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0KTtcbiAgICAgIGF3YWl0IHdhaXRGb3JEYXRhQ2hhbm5lbE9wZW4oZGF0YUNoYW5uZWwpO1xuICAgIH0sXG4gICAgW1xuICAgICAgZW1pdEVycm9yLFxuICAgICAgaGFuZGxlUmVhbHRpbWVNZXNzYWdlLFxuICAgICAgbm90aWZ5UmVhZHksXG4gICAgICBvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybCxcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQsXG4gICAgICB3YWl0Rm9yRGF0YUNoYW5uZWxPcGVuLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBnZXRFcGhlbWVyYWxUb2tlbiA9IHVzZUNhbGxiYWNrKGFzeW5jICgpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIC4uLmdldFJlcXVlc3RDb250ZXh0SGVhZGVycygpLFxuICAgIH07XG4gICAgaWYgKHByb3h5QXV0aFRva2VuKSB7XG4gICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7cHJveHlBdXRoVG9rZW59YDtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsIHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBoZWFkZXJzLFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBpbnB1dF9hdWRpb19mb3JtYXQ6IFwicGNtMTZcIixcbiAgICAgICAgaW5wdXRfYXVkaW9fdHJhbnNjcmlwdGlvbjoge1xuICAgICAgICAgIG1vZGVsOiBvcGVuYWlSZWFsdGltZU1vZGVsLFxuICAgICAgICAgIGxhbmd1YWdlLFxuICAgICAgICB9LFxuICAgICAgICB0dXJuX2RldGVjdGlvbjogYnVpbGRUdXJuRGV0ZWN0aW9uKCkgfHwgdW5kZWZpbmVkLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpLmNhdGNoKCgpID0+IFwiXCIpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgdHJhbnNjcmlwdGlvbiBzZXNzaW9uIHJlcXVlc3QgZmFpbGVkICgke3Jlc3BvbnNlLnN0YXR1c30pOiAke2JvZHl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgcmVzcG9uc2UuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpO1xuICAgIGNvbnN0IHRva2VuID1cbiAgICAgIHBheWxvYWQ/LmNsaWVudF9zZWNyZXQ/LnZhbHVlIHx8XG4gICAgICBwYXlsb2FkPy5jbGllbnRfc2VjcmV0IHx8XG4gICAgICBwYXlsb2FkPy52YWx1ZSB8fFxuICAgICAgXCJcIjtcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTm8gZXBoZW1lcmFsIHRva2VuIHJldHVybmVkIGZyb20gdHJhbnNjcmlwdGlvbiBzZXNzaW9uIGVuZHBvaW50XCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9LCBbXG4gICAgYnVpbGRUdXJuRGV0ZWN0aW9uLFxuICAgIGdldFJlcXVlc3RDb250ZXh0SGVhZGVycyxcbiAgICBwcm94eUF1dGhUb2tlbixcbiAgICBsYW5ndWFnZSxcbiAgICBvcGVuYWlSZWFsdGltZU1vZGVsLFxuICAgIG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsXG4gIF0pO1xuXG4gIGNvbnN0IGhhc1JldXNhYmxlU2Vzc2lvbiA9IHVzZUNhbGxiYWNrKCgpOiBib29sZWFuID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgISFwY1JlZi5jdXJyZW50ICYmXG4gICAgICAhIXN0cmVhbVJlZi5jdXJyZW50ICYmXG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIlxuICAgICk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBlbnN1cmVXZWJSdGNTZXNzaW9uID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGlmIChoYXNSZXVzYWJsZVNlc3Npb24oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc2Vzc2lvbkluaXRSZWYuY3VycmVudCkge1xuICAgICAgYXdhaXQgc2Vzc2lvbkluaXRSZWYuY3VycmVudDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXNzaW9uSW5pdFJlZi5jdXJyZW50ID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgZ2V0RXBoZW1lcmFsVG9rZW4oKTtcbiAgICAgIGF3YWl0IHN0YXJ0V2ViUnRjU2Vzc2lvbih0b2tlbik7XG4gICAgfSkoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBzZXNzaW9uSW5pdFJlZi5jdXJyZW50O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXNzaW9uSW5pdFJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH0sIFtnZXRFcGhlbWVyYWxUb2tlbiwgaGFzUmV1c2FibGVTZXNzaW9uLCBzdGFydFdlYlJ0Y1Nlc3Npb25dKTtcblxuICBjb25zdCBjbGVhbnVwID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIHNlc3Npb25Jbml0UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIGNsZWFyQ2FjaGVkUmVsZWFzZVRpbWVyKCk7XG5cbiAgICBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoe1xuICAgICAgZGF0YUNoYW5uZWw6IGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsXG4gICAgICBwYzogcGNSZWYuY3VycmVudCxcbiAgICAgIHN0cmVhbTogc3RyZWFtUmVmLmN1cnJlbnQsXG4gICAgfSk7XG4gICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgcGNSZWYuY3VycmVudCA9IG51bGw7XG4gICAgc3RyZWFtUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIHBlcnNpc3RTZXNzaW9uQ2FjaGUobnVsbCwgbnVsbCwgbnVsbCk7XG4gIH0sIFtdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChzZXNzaW9uUmVjb3ZlcnlUb2tlbiA9PT0gMCB8fCAhc2Vzc2lvblJlY292ZXJ5TW9kZVJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGNhbmNlbGxlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHJlY292ZXJ5TW9kZSA9IHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudDtcblxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBlbnN1cmVXZWJSdGNTZXNzaW9uKCk7XG4gICAgICAgIGlmIChjYW5jZWxsZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVjb3ZlcnlNb2RlID09PSBcImxpc3RlblwiICYmIHNob3VsZExpc3RlblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZCh0cnVlKTtcbiAgICAgICAgICBzZXRJc1JlY29yZGluZyh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBub3RpZnlSZWFkeShkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVtaXRFcnJvcihlcnJvcik7XG4gICAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgICBhd2FpdCBjbGVhbnVwKCk7XG4gICAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayhmYWxzZSwgXCJcIik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgc3VwcHJlc3NlZENoYW5uZWxFcnJvclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNhbmNlbGxlZCA9IHRydWU7XG4gICAgfTtcbiAgfSwgW1xuICAgIGNsZWFudXAsXG4gICAgZW1pdEVycm9yLFxuICAgIGVuc3VyZVdlYlJ0Y1Nlc3Npb24sXG4gICAgbm90aWZ5UmVhZHksXG4gICAgc2Vzc2lvblJlY292ZXJ5VG9rZW4sXG4gICAgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZCxcbiAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayxcbiAgXSk7XG5cbiAgY29uc3Qgc3RhcnRSZWNvcmRpbmcgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKGlzUmVjb3JkaW5nIHx8IHN0b3BJbkZsaWdodFJlZi5jdXJyZW50IHx8IHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNsZWFyQ29tbWl0RmluYWxXYWl0KCk7XG4gICAgICBub3RpZnlSZWFkeShmYWxzZSk7XG4gICAgICByZXNldFRyYW5zY3JpcHRSZWZzKCk7XG4gICAgICBjb25zdCByZXVzaW5nV2FybVNlc3Npb24gPSBoYXNSZXVzYWJsZVNlc3Npb24oKTtcbiAgICAgIGF3YWl0IGVuc3VyZVdlYlJ0Y1Nlc3Npb24oKTtcbiAgICAgIGlmIChyZXVzaW5nV2FybVNlc3Npb24pIHtcbiAgICAgICAgY2xlYXJSZWFsdGltZUlucHV0QnVmZmVyKFwic3RhcnRfcmVjb3JkaW5nXCIpO1xuICAgICAgfVxuICAgICAgaWYgKCFzaG91bGRMaXN0ZW5SZWYuY3VycmVudCkge1xuICAgICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKGZhbHNlKTtcbiAgICAgICAgbm90aWZ5UmVhZHkoZGF0YUNoYW5uZWxSZWYuY3VycmVudD8ucmVhZHlTdGF0ZSA9PT0gXCJvcGVuXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKHRydWUpO1xuICAgICAgc2V0SXNSZWNvcmRpbmcodHJ1ZSk7XG4gICAgICBub3RpZnlSZWFkeShkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVtaXRFcnJvcihlcnJvcik7XG4gICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKGZhbHNlKTtcbiAgICAgIGF3YWl0IGNsZWFudXAoKTtcbiAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICB9XG4gIH0sIFtcbiAgICBjbGVhbnVwLFxuICAgIGNsZWFyUmVhbHRpbWVJbnB1dEJ1ZmZlcixcbiAgICBjbGVhckNvbW1pdEZpbmFsV2FpdCxcbiAgICBlbnN1cmVXZWJSdGNTZXNzaW9uLFxuICAgIGVtaXRFcnJvcixcbiAgICBoYXNSZXVzYWJsZVNlc3Npb24sXG4gICAgaXNSZWNvcmRpbmcsXG4gICAgbm90aWZ5UmVhZHksXG4gICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkLFxuICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrLFxuICBdKTtcblxuICBjb25zdCBzdG9wUmVjb3JkaW5nID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGlmICghaXNSZWNvcmRpbmcgfHwgc3RvcEluRmxpZ2h0UmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBzdG9wSW5GbGlnaHRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgc2V0SXNSZWNvcmRpbmcoZmFsc2UpO1xuICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICB0cnkge1xuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQ/LnJlYWR5U3RhdGUgPT09IFwib3BlblwiKSB7XG4gICAgICAgIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQuc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7IHR5cGU6IFwiaW5wdXRfYXVkaW9fYnVmZmVyLmNvbW1pdFwiIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCBidWZmZXJlZCA9IGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCgpO1xuICAgICAgaWYgKGJ1ZmZlcmVkKSB7XG4gICAgICAgIGF3YWl0IGZpbmFsaXplQW5kUmVzZXQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICAgICAgYXdhaXRpbmdDb21taXRGaW5hbFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgaWYgKGNvbW1pdEZpbmFsVGltZW91dFJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGNvbW1pdEZpbmFsVGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBTaG9ydCBmYWxsYmFjazogaWYgbm8gcG9zdC1jb21taXQgdHJhbnNjcmlwdCBhcnJpdmVzLCByZXNldCBzdGF0ZSBhbmQgZXhpdC5cbiAgICAgICAgY29tbWl0RmluYWxUaW1lb3V0UmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAoIWF3YWl0aW5nQ29tbWl0RmluYWxSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgICAgICAgIGNsZWFyQ29tbWl0RmluYWxXYWl0KCk7XG4gICAgICAgICAgcmVzZXRUcmFuc2NyaXB0UmVmcygpO1xuICAgICAgICB9LCAxNTAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZW1pdEVycm9yKGVycm9yKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc3RvcEluRmxpZ2h0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICB9XG4gIH0sIFtcbiAgICBlbWl0RXJyb3IsXG4gICAgZmluYWxpemVBbmRSZXNldCxcbiAgICBnZXRCdWZmZXJlZFRyYW5zY3JpcHQsXG4gICAgaXNSZWNvcmRpbmcsXG4gICAgbm90aWZ5UmVhZHksXG4gICAgY2xlYXJDb21taXRGaW5hbFdhaXQsXG4gICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkLFxuICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrLFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3BlbmFpUHJld2FybU9uTW91bnQgfHwgZGlkUHJld2FybVJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRpZFByZXdhcm1SZWYuY3VycmVudCA9IHRydWU7XG4gICAgZW5zdXJlV2ViUnRjU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG5vdGlmeVJlYWR5KHRydWUpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgZW1pdEVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICB9LCBbZW1pdEVycm9yLCBlbnN1cmVXZWJSdGNTZXNzaW9uLCBub3RpZnlSZWFkeSwgb3BlbmFpUHJld2FybU9uTW91bnRdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChzaG91bGRMaXN0ZW4gJiYgIWlzUmVjb3JkaW5nKSB7XG4gICAgICBzdGFydFJlY29yZGluZygpO1xuICAgIH0gZWxzZSBpZiAoIXNob3VsZExpc3RlbiAmJiBpc1JlY29yZGluZykge1xuICAgICAgc3RvcFJlY29yZGluZygpO1xuICAgIH1cbiAgfSwgW2lzUmVjb3JkaW5nLCBzaG91bGRMaXN0ZW4sIHN0YXJ0UmVjb3JkaW5nLCBzdG9wUmVjb3JkaW5nXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgaWYgKFxuICAgICAgICBFTkFCTEVfU0VTU0lPTl9DQUNIRSAmJlxuICAgICAgICBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZi5jdXJyZW50ICYmXG4gICAgICAgICFpc1JlY29yZGluZ1JlZi5jdXJyZW50XG4gICAgICApIHtcbiAgICAgICAgc2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYW51cCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2NsZWFudXAsIG5vdGlmeVJlYWR5LCBjbGVhckNvbW1pdEZpbmFsV2FpdCwgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZF0pO1xuXG4gIHJldHVybiA8VmlldyAvPjtcbn07XG5cbmZ1bmN0aW9uIGV4dHJhY3REZWx0YVRleHQocGF5bG9hZDogYW55KTogc3RyaW5nIHtcbiAgY29uc3QgdHlwZSA9IFN0cmluZyhwYXlsb2FkPy50eXBlIHx8IFwiXCIpO1xuICBpZiAoIXR5cGUuaW5jbHVkZXMoXCJkZWx0YVwiKSkgcmV0dXJuIFwiXCI7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBbXG4gICAgcGF5bG9hZD8uZGVsdGEsXG4gICAgcGF5bG9hZD8udGV4dF9kZWx0YSxcbiAgICBwYXlsb2FkPy50cmFuc2NyaXB0X2RlbHRhLFxuICAgIHBheWxvYWQ/Lml0ZW0/LmNvbnRlbnQ/LlswXT8udHJhbnNjcmlwdCxcbiAgXTtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkpIHJldHVybiB2YWx1ZS50cmltKCk7XG4gIH1cbiAgcmV0dXJuIFwiXCI7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RDb21wbGV0ZWRUZXh0KHBheWxvYWQ6IGFueSk6IHN0cmluZyB7XG4gIGNvbnN0IHR5cGUgPSBTdHJpbmcocGF5bG9hZD8udHlwZSB8fCBcIlwiKTtcbiAgaWYgKCF0eXBlLmluY2x1ZGVzKFwiY29tcGxldGVkXCIpKSByZXR1cm4gXCJcIjtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtcbiAgICBwYXlsb2FkPy50cmFuc2NyaXB0LFxuICAgIHBheWxvYWQ/LnRleHQsXG4gICAgcGF5bG9hZD8uaXRlbT8uY29udGVudD8uWzBdPy50cmFuc2NyaXB0LFxuICAgIHBheWxvYWQ/Lml0ZW0/LnRyYW5zY3JpcHQsXG4gIF07XG4gIGZvciAoY29uc3QgdmFsdWUgb2YgY2FuZGlkYXRlcykge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUudHJpbSgpKSByZXR1cm4gdmFsdWUudHJpbSgpO1xuICB9XG4gIHJldHVybiBcIlwiO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0SXRlbUlkKHBheWxvYWQ6IGFueSk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjYW5kaWRhdGVzID0gW3BheWxvYWQ/Lml0ZW1faWQsIHBheWxvYWQ/Lml0ZW0/LmlkXTtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50cmltKCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc0NvbW1pdEJ1ZmZlclRvb1NtYWxsRXJyb3IobWVzc2FnZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBtZXNzYWdlLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgbm9ybWFsaXplZC5pbmNsdWRlcyhcImlucHV0IGF1ZGlvIGJ1ZmZlclwiKSAmJlxuICAgIG5vcm1hbGl6ZWQuaW5jbHVkZXMoXCJidWZmZXIgdG9vIHNtYWxsXCIpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzU2Vzc2lvbkR1cmF0aW9uTGltaXRFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IG1lc3NhZ2UudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIChcbiAgICBub3JtYWxpemVkLmluY2x1ZGVzKFwic2Vzc2lvblwiKSAmJlxuICAgIChub3JtYWxpemVkLmluY2x1ZGVzKFwibWF4aW11bSBkdXJhdGlvblwiKSB8fFxuICAgICAgbm9ybWFsaXplZC5pbmNsdWRlcyhcIm1heCBkdXJhdGlvblwiKSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzT3BlbkFJU3BlZWNoQXZhaWxhYmxlKCk6IGJvb2xlYW4ge1xuICBpZiAoUGxhdGZvcm0uT1MgIT09IFwid2ViXCIpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgISFuYXZpZ2F0b3IubWVkaWFEZXZpY2VzPy5nZXRVc2VyTWVkaWEgJiZcbiAgICB0eXBlb2YgUlRDUGVlckNvbm5lY3Rpb24gIT09IFwidW5kZWZpbmVkXCJcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9wZW5BSVNwZWVjaENhcGFiaWxpdGllcygpIHtcbiAgcmV0dXJuIHtcbiAgICBhdmFpbGFibGU6IGlzT3BlbkFJU3BlZWNoQXZhaWxhYmxlKCksXG4gICAgcGxhdGZvcm06IFBsYXRmb3JtLk9TLFxuICAgIHN1cHBvcnRzU2VydmVyVkFEOiB0cnVlLFxuICAgIHRyYW5zcG9ydDogXCJ3ZWJydGNcIixcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgT3BlbkFJU3BlZWNoUmVjb2duaXplcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxJQUFBQSxNQUFBLEdBQUFDLHVC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QVM2SCxhQUFhQSxDQUFDdEUsT0FBWSxFQUFpQjtFQUNsRCxNQUFNZ0UsVUFBVSxHQUFHLENBQUNoRSxPQUFPLEVBQUV1RSxPQUFPLEVBQUV2RSxPQUFPLEVBQUVtRSxJQUFJLEVBQUVLLEVBQUUsQ0FBQztFQUN4RCxLQUFLLE1BQU0xTixLQUFLLElBQUlrTixVQUFVLEVBQUU7SUFDOUIsSUFBSSxPQUFPbE4sS0FBSyxLQUFLLFFBQVEsSUFBSUEsS0FBSyxDQUFDMkYsSUFBSSxDQUFDLENBQUMsRUFBRTtNQUM3QyxPQUFPM0YsS0FBSyxDQUFDMkYsSUFBSSxDQUFDLENBQUM7SUFDckI7RUFDRjtFQUNBLE9BQU8sSUFBSTtBQUNiO0FBRUEsU0FBUzJGLDJCQUEyQkEsQ0FBQ0QsT0FBZSxFQUFXO0VBQzdELE1BQU1zQyxVQUFVLEdBQUd0QyxPQUFPLENBQUMvQyxXQUFXLENBQUMsQ0FBQztFQUN4QyxPQUNFcUYsVUFBVSxDQUFDekQsUUFBUSxDQUFDLG9CQUFvQixDQUFDLElBQ3pDeUQsVUFBVSxDQUFDekQsUUFBUSxDQUFDLGtCQUFrQixDQUFDO0FBRTNDO0FBRUEsU0FBU3FCLDJCQUEyQkEsQ0FBQ0YsT0FBZSxFQUFXO0VBQzdELE1BQU1zQyxVQUFVLEdBQUd0QyxPQUFPLENBQUMvQyxXQUFXLENBQUMsQ0FBQztFQUN4QyxPQUNFcUYsVUFBVSxDQUFDekQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUM3QnlELFVBQVUsQ0FBQ3pELFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxJQUN0Q3lELFVBQVUsQ0FBQ3pELFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUUxQztBQUVPLFNBQVMwRCx1QkFBdUJBLENBQUEsRUFBWTtFQUNqRCxJQUFJQyxxQkFBUSxDQUFDQyxFQUFFLEtBQUssS0FBSyxFQUFFLE9BQU8sS0FBSztFQUN2QyxJQUFJLE9BQU9DLE1BQU0sS0FBSyxXQUFXLEVBQUUsT0FBTyxLQUFLO0VBQy9DLE9BQ0UsT0FBT3hELFNBQVMsS0FBSyxXQUFXLElBQ2hDLENBQUMsQ0FBQ0EsU0FBUyxDQUFDQyxZQUFZLEVBQUVDLFlBQVksSUFDdEMsT0FBT0gsaUJBQWlCLEtBQUssV0FBVztBQUU1QztBQUVPLFNBQVMwRCwyQkFBMkJBLENBQUEsRUFBRztFQUM1QyxPQUFPO0lBQ0xDLFNBQVMsRUFBRUwsdUJBQXVCLENBQUMsQ0FBQztJQUNwQ00sUUFBUSxFQUFFTCxxQkFBUSxDQUFDQyxFQUFFO0lBQ3JCSyxpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCQyxTQUFTLEVBQUU7RUFDYixDQUFDO0FBQ0g7QUFBQyxJQUFBQyxRQUFBLEdBQUFwQixPQUFBLENBQUFqUCxPQUFBLEdBRWNxRSxzQkFBc0IiLCJpZ25vcmVMaXN0IjpbXX0=