@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,1321 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.ModalityProvider = exports.GenieInterpreter = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactRedux = require("react-redux");
9
+ var _reactNative = require("react-native");
10
+ var _native = require("@react-navigation/native");
11
+ var _stack = require("@react-navigation/stack");
12
+ var _vectorIcons = require("@expo/vector-icons");
13
+ var _sonnerNative = require("sonner-native");
14
+ var _navigationAdapter = require("./adapters/navigation-adapter");
15
+ var _reactgenieDsl = require("@garrix82/reactgenie-dsl");
16
+ var _reactDecorators = require("./react-decorators");
17
+ var _sharedStore = require("./shared-store");
18
+ var _speechRecognitionUnified = require("./speech-recognition/speech-recognition-unified");
19
+ var _useSpeechRecognition = require("./hooks/useSpeechRecognition");
20
+ var _VoiceRecognitionBar = require("./platform/VoiceRecognitionBar");
21
+ var _platform = require("./platform");
22
+ var _logger = _interopRequireWildcard(require("./logger"));
23
+ var _voicePipelineTelemetry = require("./voice-pipeline-telemetry");
24
+ 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); }
25
+ 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; }
26
+ 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; }
27
+ 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; }
28
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
29
+ 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); } /**
30
+ * Platform-independent Modality Provider
31
+ * Provides voice recognition, navigation, and multimodal interaction
32
+ * Fully type-safe and works on Web, iOS, and Android
33
+ */ // Platform abstraction imports
34
+ // ============================================================================
35
+ // Types
36
+ // ============================================================================
37
+
38
+ const SPEECH_MINIMAL_TEXT_LIMIT = 120;
39
+ const VOICE_UI_OCCLUSION_TEST_ID = 'reactgenie-voice-ui-occlusion';
40
+ const truncateText = (value, maxLength) => {
41
+ if (value.length <= maxLength) {
42
+ return value;
43
+ }
44
+ return `${value.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
45
+ };
46
+
47
+ // ============================================================================
48
+ // Language helpers
49
+ // ============================================================================
50
+
51
+ const normalizeLanguageTag = lang => {
52
+ const normalized = (lang || "en").trim().toLowerCase();
53
+ return normalized.length > 0 ? normalized : "en";
54
+ };
55
+ const isNoCommandParseError = error => {
56
+ if (!(error instanceof Error)) return false;
57
+ const message = (error.message || "").toLowerCase();
58
+ return message.includes("missing command") || message.includes("structured output missing command");
59
+ };
60
+ const DEICTIC_REFERENCE_PATTERN = /\b(this|it|current|selected|that)\b/i;
61
+ const isDeicticReferenceUtterance = utterance => DEICTIC_REFERENCE_PATTERN.test(utterance);
62
+ const pointToRectDistanceSq = (pointX, pointY, rect) => {
63
+ const closestX = Math.max(rect.x, Math.min(pointX, rect.x + rect.width));
64
+ const closestY = Math.max(rect.y, Math.min(pointY, rect.y + rect.height));
65
+ return Math.pow(pointX - closestX, 2) + Math.pow(pointY - closestY, 2);
66
+ };
67
+ const pointInRect = (pointX, pointY, rect) => pointX >= rect.x && pointX <= rect.x + rect.width && pointY >= rect.y && pointY <= rect.y + rect.height;
68
+ const rectFromDomBounds = rect => ({
69
+ x: rect.left,
70
+ y: rect.top,
71
+ width: rect.width,
72
+ height: rect.height
73
+ });
74
+ const getWebVoiceUiOcclusionRect = element => {
75
+ const rect = element.getBoundingClientRect();
76
+ if (rect.width > 0 && rect.height > 0) {
77
+ return rectFromDomBounds(rect);
78
+ }
79
+ let minLeft = Number.POSITIVE_INFINITY;
80
+ let minTop = Number.POSITIVE_INFINITY;
81
+ let maxRight = Number.NEGATIVE_INFINITY;
82
+ let maxBottom = Number.NEGATIVE_INFINITY;
83
+ for (const descendant of Array.from(element.querySelectorAll("*"))) {
84
+ const descendantRect = descendant.getBoundingClientRect();
85
+ if (descendantRect.width <= 0 || descendantRect.height <= 0) {
86
+ continue;
87
+ }
88
+ minLeft = Math.min(minLeft, descendantRect.left);
89
+ minTop = Math.min(minTop, descendantRect.top);
90
+ maxRight = Math.max(maxRight, descendantRect.right);
91
+ maxBottom = Math.max(maxBottom, descendantRect.bottom);
92
+ }
93
+ if (!Number.isFinite(minLeft) || !Number.isFinite(minTop) || !Number.isFinite(maxRight) || !Number.isFinite(maxBottom)) {
94
+ return undefined;
95
+ }
96
+ return {
97
+ x: minLeft,
98
+ y: minTop,
99
+ width: maxRight - minLeft,
100
+ height: maxBottom - minTop
101
+ };
102
+ };
103
+ const resolveTapClassName = (interfaces, tap) => {
104
+ if (!tap || interfaces.length === 0) {
105
+ return undefined;
106
+ }
107
+ let nearest = interfaces[0];
108
+ let nearestDistance = pointToRectDistanceSq(tap.x, tap.y, nearest.rect);
109
+ for (let index = 1; index < interfaces.length; index += 1) {
110
+ const candidate = interfaces[index];
111
+ const distance = pointToRectDistanceSq(tap.x, tap.y, candidate.rect);
112
+ if (distance < nearestDistance) {
113
+ nearest = candidate;
114
+ nearestDistance = distance;
115
+ }
116
+ }
117
+ return nearest?.className;
118
+ };
119
+ const applyRuntimeUiContext = (interpreter, context) => {
120
+ const maybeRuntimeContextSetter = interpreter;
121
+ maybeRuntimeContextSetter.setRuntimeContext?.(context);
122
+ };
123
+ class VisibilityTransitionError extends Error {
124
+ constructor(message) {
125
+ super(message);
126
+ this.name = 'VisibilityTransitionError';
127
+ }
128
+ }
129
+ const waitForMs = ms => new Promise(resolve => {
130
+ setTimeout(resolve, ms);
131
+ });
132
+ const waitForStableInterfaceSnapshot = async (timeoutMs = 450, pollIntervalMs = 16) => {
133
+ const deadline = Date.now() + timeoutMs;
134
+ let snapshot = (0, _reactDecorators.RetrieveInterfacesSnapshot)();
135
+ while (snapshot.visibilityState === "transition_unstable" && Date.now() < deadline) {
136
+ await waitForMs(pollIntervalMs);
137
+ snapshot = (0, _reactDecorators.RetrieveInterfacesSnapshot)();
138
+ }
139
+ return snapshot;
140
+ };
141
+ const recordInterpreterTurn = (interpreter, record) => {
142
+ const maybeTurnRecorder = interpreter;
143
+ if (typeof maybeTurnRecorder.recordTurn === "function") {
144
+ maybeTurnRecorder.recordTurn(record);
145
+ return;
146
+ }
147
+ maybeTurnRecorder.recordInteraction?.(record);
148
+ };
149
+
150
+ // ============================================================================
151
+ // Navigation Setup
152
+ // ============================================================================
153
+
154
+ const Stack = (0, _stack.createStackNavigator)();
155
+ let GenieInterpreter = exports.GenieInterpreter = void 0;
156
+ const cardStyle = {
157
+ presentation: 'card',
158
+ headerStyleInterpolator: _stack.HeaderStyleInterpolators.forUIKit,
159
+ cardStyleInterpolator: _stack.CardStyleInterpolators.forHorizontalIOS
160
+ };
161
+
162
+ /**
163
+ * Default screen wrapper - renders children with hidden header
164
+ */
165
+ const DefaultScreen = children => ({
166
+ navigation
167
+ }) => {
168
+ (0, _react.useEffect)(() => {
169
+ navigation.setOptions({
170
+ headerShown: false
171
+ });
172
+ }, [navigation]);
173
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
174
+ };
175
+
176
+ /**
177
+ * Object interface screen wrapper - renders genie objects with navigation
178
+ */
179
+ const ObjectInterfaceScreen = genieInterfaceStoreElement => ({
180
+ route,
181
+ navigation
182
+ }) => {
183
+ const params = route?.params || {};
184
+ const title = genieInterfaceStoreElement.title(params);
185
+ (0, _react.useEffect)(() => {
186
+ navigation.setOptions({
187
+ headerShown: true,
188
+ title: title
189
+ });
190
+ }, [navigation, title]);
191
+ return /*#__PURE__*/_react.default.createElement(genieInterfaceStoreElement.function, params);
192
+ };
193
+
194
+ // ============================================================================
195
+ // Main Component
196
+ // ============================================================================
197
+
198
+ const ModalityProvider = ({
199
+ examples: propsExamples,
200
+ clientSecret,
201
+ apiBaseUrl,
202
+ parserConfig,
203
+ speechConfig,
204
+ loggerConfig,
205
+ speechLanguage,
206
+ langsmithConfig,
207
+ displayTranscript = false,
208
+ extraPrompt = '',
209
+ children,
210
+ VoiceUIComponent = _VoiceRecognitionBar.VoiceRecognitionBar,
211
+ showFloatingMicButton = true,
212
+ voicePlaceholder
213
+ }) => {
214
+ const resolvedProxyBaseUrl = apiBaseUrl;
215
+
216
+ // ========== Speech Recognition Hook ==========
217
+ const speechRecognition = (0, _useSpeechRecognition.useSpeechRecognition)();
218
+ (0, _react.useEffect)(() => {
219
+ if (loggerConfig) {
220
+ (0, _logger.configureLogger)(loggerConfig);
221
+ }
222
+ }, [loggerConfig]);
223
+
224
+ // ========== Legacy State (for backward compatibility) ==========
225
+ const [isPressed, setIsPressed] = (0, _react.useState)(false);
226
+ const [isOpenAISpeechReady, setIsOpenAISpeechReady] = (0, _react.useState)(true);
227
+
228
+ // ========== Selectors ==========
229
+ const examples = (0, _sharedStore.useGenieSelector)(() => {
230
+ const sharedExamples = _reactgenieDsl.sharedState['__EXAMPLES__'] || [];
231
+ if (propsExamples === undefined) {
232
+ return sharedExamples;
233
+ } else {
234
+ return [...propsExamples, ...sharedExamples];
235
+ }
236
+ });
237
+ const navState = (0, _reactRedux.useSelector)(state => state.navState);
238
+ const navStack = (0, _reactRedux.useSelector)(state => state.navStack);
239
+ const voiceMessage = (0, _reactRedux.useSelector)(state => state.message);
240
+ const resolvedSpeechLanguage = normalizeLanguageTag(speechLanguage);
241
+ const resolvedSpeechConfig = (0, _react.useMemo)(() => (0, _speechRecognitionUnified.getSpeechRecognitionConfig)(speechConfig), [speechConfig]);
242
+ const langsmithApiKey = langsmithConfig?.apiKey;
243
+ const langsmithProject = langsmithConfig?.project;
244
+ const langsmithEndpoint = langsmithConfig?.endpoint;
245
+ const isOpenAIAutoStopEnabled = resolvedSpeechConfig.provider === "openai" && !!resolvedSpeechConfig.openai?.autoStopOnVadSilence;
246
+ const isOpenAIProvider = resolvedSpeechConfig.provider === "openai";
247
+
248
+ // ========== Refs ==========
249
+ const navigationRef = (0, _native.useNavigationContainerRef)();
250
+ const lastTranscriptRef = _react.default.useRef('');
251
+ const latestTranscriptRef = _react.default.useRef('');
252
+ const latestTranslationRef = _react.default.useRef('');
253
+ const isProcessingTranscriptRef = _react.default.useRef(false);
254
+ const activeSessionIdRef = _react.default.useRef(0);
255
+ const finalizedSessionIdRef = _react.default.useRef(-1);
256
+ const activeThreadIdRef = _react.default.useRef(null);
257
+ const activeTurnIdRef = _react.default.useRef(null);
258
+ const acceptingSpeechInputRef = _react.default.useRef(false);
259
+ const awaitingLateFinalAfterPauseRef = _react.default.useRef(false);
260
+ const lateFinalFallbackTimerRef = _react.default.useRef(null);
261
+ const speechResponseTimeoutRef = _react.default.useRef(null);
262
+ const activeVoicePipelineRef = _react.default.useRef(null);
263
+ const activeListeningStageRef = _react.default.useRef(null);
264
+ const activeProcessingStageRef = _react.default.useRef(null);
265
+ const displayOutcomeRef = _react.default.useRef('not_applicable');
266
+ const navStackRef = _react.default.useRef(0);
267
+ const webSpeechUtteranceRef = _react.default.useRef(null);
268
+ const touchStartPointRef = _react.default.useRef(null);
269
+ const blockedOverlayTapRef = _react.default.useRef(false);
270
+ const handleMicrophonePressRef = _react.default.useRef(null);
271
+ const voiceUiLayoutRectRef = _react.default.useRef(null);
272
+ (0, _react.useEffect)(() => {
273
+ navStackRef.current = navStack;
274
+ }, [navStack]);
275
+ (0, _react.useEffect)(() => {
276
+ if (!isOpenAIProvider) {
277
+ setIsOpenAISpeechReady(true);
278
+ }
279
+ }, [isOpenAIProvider]);
280
+ const resolvedParserConfig = (0, _react.useMemo)(() => ({
281
+ provider: parserConfig?.provider,
282
+ groq: _objectSpread(_objectSpread({}, parserConfig?.groq || {}), {}, {
283
+ baseUrl: parserConfig?.groq?.baseUrl || resolvedProxyBaseUrl
284
+ }),
285
+ openai: _objectSpread(_objectSpread({}, parserConfig?.openai || {}), {}, {
286
+ baseUrl: parserConfig?.openai?.baseUrl || resolvedProxyBaseUrl
287
+ })
288
+ }), [parserConfig, resolvedProxyBaseUrl]);
289
+
290
+ // ========== Initialize Genie Interpreter ==========
291
+ exports.GenieInterpreter = GenieInterpreter = (0, _react.useMemo)(() => {
292
+ const descriptors = [];
293
+ for (const key in _reactDecorators.AllGenieObjects) {
294
+ descriptors.push(_reactDecorators.AllGenieObjects[key].ClassDescriptor);
295
+ }
296
+ return new _reactgenieDsl.NlInterpreter(descriptors, clientSecret, undefined, examples, extraPrompt, {
297
+ parser: resolvedParserConfig,
298
+ monitoring: {
299
+ langsmithApiKey,
300
+ langsmithProject,
301
+ langsmithEndpoint
302
+ }
303
+ });
304
+ }, [clientSecret, examples, extraPrompt, resolvedParserConfig, langsmithApiKey, langsmithProject, langsmithEndpoint]);
305
+
306
+ // ========== UI List (Navigation Screens) ==========
307
+ const uiList = (0, _react.useMemo)(() => {
308
+ const allInterfaces = _reactDecorators.AllGenieObjectInterfaces.allInterfaces();
309
+ return Object.keys(allInterfaces).map(key => {
310
+ const interfaceStoreElement = allInterfaces[key];
311
+ return /*#__PURE__*/_react.default.createElement(Stack.Screen, {
312
+ name: key,
313
+ component: ObjectInterfaceScreen(interfaceStoreElement),
314
+ options: cardStyle
315
+ });
316
+ });
317
+ }, []);
318
+
319
+ // ========== GUI Structure ==========
320
+ const gui = (0, _react.useMemo)(() => {
321
+ // If using expo-router, skip NavigationContainer (it's provided by expo-router)
322
+ if ((0, _navigationAdapter.isExpoRouter)()) {
323
+ // In expo-router, components are rendered directly without NavigationContainer
324
+ // The navigation structure is file-based
325
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
326
+ }
327
+
328
+ // Traditional react-navigation setup
329
+ return (
330
+ /*#__PURE__*/
331
+ // @ts-expect-error - React Navigation v7 types are overly strict with React 19; children are properly provided below
332
+ _react.default.createElement(_native.NavigationContainer, {
333
+ ref: navigationRef
334
+ }, /*#__PURE__*/_react.default.createElement(Stack.Navigator, {
335
+ initialRouteName: "Default GUI"
336
+ }, /*#__PURE__*/_react.default.createElement(Stack.Screen, {
337
+ name: "Default GUI",
338
+ component: DefaultScreen(children),
339
+ options: cardStyle
340
+ }), uiList))
341
+ );
342
+ }, [navigationRef, uiList, children]);
343
+
344
+ // ========== Effects ==========
345
+
346
+ // Handle navigation state changes
347
+ (0, _react.useEffect)(() => {
348
+ // console.log('nav state changed', navState);
349
+ if (navState.objectViewClassName !== null) {
350
+ if ((0, _navigationAdapter.isExpoRouter)()) {
351
+ // For expo-router, use dynamic routing
352
+ // This requires expo-router to be set up with dynamic routes
353
+ _logger.default.warn('expo-router navigation requires manual route setup');
354
+ // User needs to create dynamic routes in their app directory
355
+ } else if (navigationRef.isReady()) {
356
+ // Traditional navigation
357
+ navigationRef.dispatch(_native.StackActions.push(navState.objectViewClassName, navState.objectConstructorParams));
358
+ }
359
+ }
360
+ }, [navStack, navState, navigationRef]);
361
+ const listenerState = speechRecognition.state === _useSpeechRecognition.SpeechState.Listening ? _platform.ListenerState.Listening : speechRecognition.state === _useSpeechRecognition.SpeechState.Processing ? _platform.ListenerState.Processing : _platform.ListenerState.Idle;
362
+ const isConnecting = isOpenAIProvider && speechRecognition.state === _useSpeechRecognition.SpeechState.Listening && !speechRecognition.isProcessing && !isOpenAISpeechReady;
363
+ const isListeningForUi = speechRecognition.state === _useSpeechRecognition.SpeechState.Listening && !isConnecting;
364
+ const setSelectionBlockedRects = (0, _react.useCallback)(rects => {
365
+ _reactDecorators.CurrentSelectionBlockedRects.splice(0, _reactDecorators.CurrentSelectionBlockedRects.length);
366
+ rects.forEach(rect => {
367
+ if (rect.width <= 0 || rect.height <= 0) {
368
+ return;
369
+ }
370
+ _reactDecorators.CurrentSelectionBlockedRects.push(rect);
371
+ });
372
+ }, []);
373
+ const pointIsInBlockedSelectionRect = (0, _react.useCallback)((x, y) => {
374
+ for (const rect of _reactDecorators.CurrentSelectionBlockedRects) {
375
+ if (pointInRect(x, y, rect)) {
376
+ return true;
377
+ }
378
+ }
379
+ return false;
380
+ }, []);
381
+ const getLatestUnblockedTap = (0, _react.useCallback)(() => {
382
+ const taps = _reactDecorators.ClickPoints ?? [];
383
+ for (let index = taps.length - 1; index >= 0; index -= 1) {
384
+ const tap = taps[index];
385
+ if (!pointIsInBlockedSelectionRect(tap.x, tap.y)) {
386
+ return tap;
387
+ }
388
+ }
389
+ return undefined;
390
+ }, [pointIsInBlockedSelectionRect]);
391
+ const updateVoiceUiBlockedRects = (0, _react.useCallback)(fallbackRect => {
392
+ const applyRect = rect => {
393
+ if (!rect || rect.width <= 0 || rect.height <= 0) {
394
+ setSelectionBlockedRects([]);
395
+ return;
396
+ }
397
+ setSelectionBlockedRects([rect]);
398
+ };
399
+ if (_reactNative.Platform.OS === 'web' && typeof document !== 'undefined') {
400
+ const element = document.querySelector(`[data-testid="${VOICE_UI_OCCLUSION_TEST_ID}"]`);
401
+ if (element) {
402
+ applyRect(getWebVoiceUiOcclusionRect(element));
403
+ return;
404
+ }
405
+ }
406
+ applyRect(fallbackRect ?? voiceUiLayoutRectRef.current ?? undefined);
407
+ }, [setSelectionBlockedRects]);
408
+ const handleVoiceUiLayout = (0, _react.useCallback)(event => {
409
+ const {
410
+ x,
411
+ y,
412
+ width,
413
+ height
414
+ } = event.nativeEvent.layout;
415
+ const layoutRect = {
416
+ x,
417
+ y,
418
+ width,
419
+ height
420
+ };
421
+ voiceUiLayoutRectRef.current = layoutRect;
422
+ updateVoiceUiBlockedRects(layoutRect);
423
+ }, [updateVoiceUiBlockedRects]);
424
+ (0, _react.useEffect)(() => {
425
+ const voiceUiVisible = isListeningForUi || speechRecognition.isProcessing || isConnecting || displayTranscript && (speechRecognition.interimTranscript.trim().length > 0 || speechRecognition.transcript.trim().length > 0);
426
+ if (!voiceUiVisible) {
427
+ setSelectionBlockedRects([]);
428
+ return;
429
+ }
430
+ const rafId = requestAnimationFrame(() => {
431
+ updateVoiceUiBlockedRects();
432
+ });
433
+ return () => {
434
+ cancelAnimationFrame(rafId);
435
+ };
436
+ }, [displayTranscript, isConnecting, isListeningForUi, setSelectionBlockedRects, speechRecognition.interimTranscript, speechRecognition.isProcessing, speechRecognition.transcript, updateVoiceUiBlockedRects]);
437
+ (0, _react.useEffect)(() => {
438
+ return () => {
439
+ setSelectionBlockedRects([]);
440
+ };
441
+ }, [setSelectionBlockedRects]);
442
+
443
+ // Handle voice message toast notifications
444
+ (0, _react.useEffect)(() => {
445
+ const toastMessage = voiceMessage?.fullText?.trim() || voiceMessage?.message?.trim() || voiceMessage?.minimalText?.trim();
446
+ if (!toastMessage) {
447
+ return;
448
+ }
449
+ const toastMessageKey = `${voiceMessage?.type ?? 'info'}|${voiceMessage?.origin ?? ''}|${toastMessage}`;
450
+ const clearVoiceMessage = () => {
451
+ (0, _reactgenieDsl.genieDispatch)(() => {
452
+ const reactGenieState = _reactgenieDsl.sharedState;
453
+ const currentMessage = reactGenieState.message;
454
+ const currentToastMessage = currentMessage?.fullText?.trim() || currentMessage?.message?.trim() || currentMessage?.minimalText?.trim() || '';
455
+ const currentMessageKey = `${currentMessage?.type ?? 'info'}|${currentMessage?.origin ?? ''}|${currentToastMessage}`;
456
+ if (currentMessageKey !== toastMessageKey) {
457
+ return;
458
+ }
459
+ reactGenieState.message = {
460
+ minimalText: '',
461
+ fullText: '',
462
+ message: '',
463
+ type: 'info',
464
+ shouldSpeak: false,
465
+ origin: 'system'
466
+ };
467
+ });
468
+ };
469
+ const toastOptions = {
470
+ onAutoClose: clearVoiceMessage,
471
+ onDismiss: clearVoiceMessage
472
+ };
473
+ switch (voiceMessage.type) {
474
+ case 'error':
475
+ _sonnerNative.toast.error(toastMessage, toastOptions);
476
+ break;
477
+ case 'success':
478
+ _sonnerNative.toast.success(toastMessage, toastOptions);
479
+ break;
480
+ case 'warning':
481
+ case 'info':
482
+ default:
483
+ (0, _sonnerNative.toast)(toastMessage, toastOptions);
484
+ break;
485
+ }
486
+ }, [voiceMessage]);
487
+ const clearLateFinalFallback = (0, _react.useCallback)(() => {
488
+ awaitingLateFinalAfterPauseRef.current = false;
489
+ if (lateFinalFallbackTimerRef.current) {
490
+ clearTimeout(lateFinalFallbackTimerRef.current);
491
+ lateFinalFallbackTimerRef.current = null;
492
+ }
493
+ }, []);
494
+ const finishListeningStage = (0, _react.useCallback)((status, context) => {
495
+ const stage = activeListeningStageRef.current;
496
+ if (!stage) return;
497
+ try {
498
+ stage.finish?.(status, _objectSpread({
499
+ session_id: activeSessionIdRef.current,
500
+ thread_id: activeThreadIdRef.current,
501
+ turn_id: activeTurnIdRef.current
502
+ }, context || {}));
503
+ } catch {
504
+ // noop
505
+ }
506
+ activeListeningStageRef.current = null;
507
+ }, []);
508
+ const clearSpeechResponseTimeout = (0, _react.useCallback)(() => {
509
+ if (speechResponseTimeoutRef.current) {
510
+ clearTimeout(speechResponseTimeoutRef.current);
511
+ speechResponseTimeoutRef.current = null;
512
+ }
513
+ }, []);
514
+ const getProcessingStageStatus = (0, _react.useCallback)(outcome => {
515
+ if (outcome === 'speech_response_sent') return 'ok';
516
+ if (outcome === 'error') return 'error';
517
+ return 'cancelled';
518
+ }, []);
519
+ const finishProcessingStage = (0, _react.useCallback)((status, context) => {
520
+ const stage = activeProcessingStageRef.current;
521
+ if (!stage) return;
522
+ try {
523
+ stage.finish?.(status, _objectSpread({
524
+ session_id: activeSessionIdRef.current,
525
+ thread_id: activeThreadIdRef.current,
526
+ turn_id: activeTurnIdRef.current,
527
+ latency_scope: 'post_stop_processing',
528
+ 'voice.latency_scope': 'post_stop_processing'
529
+ }, context || {}));
530
+ } catch {
531
+ // noop
532
+ }
533
+ activeProcessingStageRef.current = null;
534
+ }, []);
535
+ const finishVoicePipeline = (0, _react.useCallback)((outcome, context) => {
536
+ clearSpeechResponseTimeout();
537
+ const pipeline = activeVoicePipelineRef.current;
538
+ finishProcessingStage(getProcessingStageStatus(outcome), _objectSpread({
539
+ outcome,
540
+ processing_outcome: outcome,
541
+ 'voice.processing_outcome': outcome
542
+ }, context || {}));
543
+ if (!pipeline) return;
544
+ try {
545
+ pipeline.finish?.(outcome, _objectSpread({
546
+ session_id: activeSessionIdRef.current,
547
+ thread_id: activeThreadIdRef.current,
548
+ turn_id: activeTurnIdRef.current,
549
+ display_outcome: displayOutcomeRef.current
550
+ }, context || {}));
551
+ } catch {
552
+ // noop
553
+ }
554
+ activeVoicePipelineRef.current = null;
555
+ activeListeningStageRef.current = null;
556
+ activeProcessingStageRef.current = null;
557
+ displayOutcomeRef.current = 'not_applicable';
558
+ activeThreadIdRef.current = null;
559
+ activeTurnIdRef.current = null;
560
+ }, [clearSpeechResponseTimeout, finishProcessingStage, getProcessingStageStatus]);
561
+ const speakVoiceResponse = (0, _react.useCallback)(async text => {
562
+ if (!text) {
563
+ return;
564
+ }
565
+ const normalizedText = truncateText(text, SPEECH_MINIMAL_TEXT_LIMIT);
566
+ if (!normalizedText.trim()) {
567
+ return;
568
+ }
569
+ const pipeline = activeVoicePipelineRef.current;
570
+ const speechStage = pipeline?.startStage?.('speech.respond', {
571
+ session_id: activeSessionIdRef.current,
572
+ thread_id: activeThreadIdRef.current,
573
+ turn_id: activeTurnIdRef.current,
574
+ text_length: normalizedText.length
575
+ }) || null;
576
+ const finishSpeechStage = (status, context) => {
577
+ try {
578
+ speechStage?.finish?.(status, _objectSpread({
579
+ text_length: normalizedText.length
580
+ }, context || {}));
581
+ } catch {
582
+ // noop
583
+ }
584
+ };
585
+ if (_reactNative.Platform.OS === 'web') {
586
+ const speechSynthesisApi = globalThis?.speechSynthesis;
587
+ const utteranceConstructor = globalThis?.SpeechSynthesisUtterance;
588
+ if (!speechSynthesisApi || !utteranceConstructor) {
589
+ finishSpeechStage('error', {
590
+ reason: 'speech_api_unavailable',
591
+ platform: 'web'
592
+ });
593
+ if (pipeline) {
594
+ finishVoicePipeline('error', {
595
+ reason: 'speech_api_unavailable',
596
+ platform: 'web'
597
+ });
598
+ }
599
+ return;
600
+ }
601
+ if (webSpeechUtteranceRef.current) {
602
+ speechSynthesisApi.cancel();
603
+ webSpeechUtteranceRef.current = null;
604
+ }
605
+ const utterance = new utteranceConstructor(normalizedText);
606
+ webSpeechUtteranceRef.current = utterance;
607
+ speechSynthesisApi.speak(utterance);
608
+ finishSpeechStage('ok', {
609
+ platform: 'web'
610
+ });
611
+ if (pipeline) {
612
+ finishVoicePipeline('speech_response_sent', {
613
+ platform: 'web',
614
+ speech_text_length: normalizedText.length
615
+ });
616
+ }
617
+ return;
618
+ }
619
+ try {
620
+ const speechModule = await Promise.resolve().then(() => _interopRequireWildcard(require('expo-speech')));
621
+ speechModule.stop();
622
+ speechModule.speak(normalizedText);
623
+ finishSpeechStage('ok', {
624
+ platform: 'native'
625
+ });
626
+ if (pipeline) {
627
+ finishVoicePipeline('speech_response_sent', {
628
+ platform: 'native',
629
+ speech_text_length: normalizedText.length
630
+ });
631
+ }
632
+ } catch (error) {
633
+ finishSpeechStage('error', {
634
+ platform: 'native',
635
+ reason: 'speech_module_error'
636
+ });
637
+ if (pipeline) {
638
+ finishVoicePipeline('error', {
639
+ platform: 'native',
640
+ reason: 'speech_module_error'
641
+ });
642
+ }
643
+ _logger.default.warn('Unable to play speech response', error);
644
+ }
645
+ }, [finishVoicePipeline]);
646
+ (0, _react.useEffect)(() => {
647
+ const minimalText = voiceMessage?.minimalText?.trim() || voiceMessage?.message?.trim() || '';
648
+ if (!minimalText) {
649
+ return;
650
+ }
651
+ if (voiceMessage?.origin !== 'voice' || !voiceMessage?.shouldSpeak) {
652
+ return;
653
+ }
654
+ void speakVoiceResponse(minimalText);
655
+ }, [voiceMessage, speakVoiceResponse]);
656
+ const armSpeechResponseTimeout = (0, _react.useCallback)(reason => {
657
+ clearSpeechResponseTimeout();
658
+ speechResponseTimeoutRef.current = setTimeout(() => {
659
+ finishVoicePipeline('speech_response_timeout', {
660
+ reason
661
+ });
662
+ }, 5000);
663
+ }, [clearSpeechResponseTimeout, finishVoicePipeline]);
664
+ (0, _react.useEffect)(() => {
665
+ return () => {
666
+ if (lateFinalFallbackTimerRef.current) {
667
+ clearTimeout(lateFinalFallbackTimerRef.current);
668
+ lateFinalFallbackTimerRef.current = null;
669
+ }
670
+ clearSpeechResponseTimeout();
671
+ finishVoicePipeline('aborted', {
672
+ reason: 'provider_unmounted'
673
+ });
674
+ const speechSynthesisApi = globalThis?.speechSynthesis;
675
+ if (speechSynthesisApi) {
676
+ speechSynthesisApi.cancel();
677
+ }
678
+ };
679
+ }, [clearSpeechResponseTimeout, finishVoicePipeline]);
680
+ const beginLateFinalFallback = (0, _react.useCallback)(reason => {
681
+ awaitingLateFinalAfterPauseRef.current = true;
682
+ if (lateFinalFallbackTimerRef.current) {
683
+ clearTimeout(lateFinalFallbackTimerRef.current);
684
+ }
685
+ lateFinalFallbackTimerRef.current = setTimeout(() => {
686
+ lateFinalFallbackTimerRef.current = null;
687
+ if (!awaitingLateFinalAfterPauseRef.current) {
688
+ return;
689
+ }
690
+ if (latestTranscriptRef.current.trim() !== '') {
691
+ return;
692
+ }
693
+ awaitingLateFinalAfterPauseRef.current = false;
694
+ acceptingSpeechInputRef.current = false;
695
+ finishListeningStage('cancelled', {
696
+ reason: 'late_final_missing'
697
+ });
698
+ finishVoicePipeline('aborted', {
699
+ reason: 'late_final_missing'
700
+ });
701
+ _logger.default.info(`[Voice] ${reason}; no late final transcript; stop finalized`);
702
+ }, 350);
703
+ _logger.default.info(`[Voice] ${reason}; waiting briefly for late final`);
704
+ }, [finishListeningStage, finishVoicePipeline]);
705
+
706
+ // Parse transcript once recording finishes
707
+ const processTranscript = (0, _react.useCallback)(async (sessionId, text) => {
708
+ const noCommandMessage = "No command to run.";
709
+ const navigationSettlingMessage = "Navigation is still settling. Please try again in a moment.";
710
+ const trimmed = text.trim();
711
+ if (trimmed === '' || isProcessingTranscriptRef.current || sessionId !== activeSessionIdRef.current || finalizedSessionIdRef.current === sessionId) {
712
+ if (trimmed === '') {
713
+ latestTranscriptRef.current = '';
714
+ }
715
+ return;
716
+ }
717
+ finishListeningStage('ok', {
718
+ reason: 'transcript_processing_started'
719
+ });
720
+ isProcessingTranscriptRef.current = true;
721
+ finalizedSessionIdRef.current = sessionId;
722
+ acceptingSpeechInputRef.current = false;
723
+ clearLateFinalFallback();
724
+ lastTranscriptRef.current = trimmed;
725
+ speechRecognition.stopListening();
726
+ speechRecognition.setProcessing(true);
727
+ _logger.default.info('Listener state set to Processing');
728
+ _logger.default.info(`Final transcript received: ${trimmed}`);
729
+ activeVoicePipelineRef.current?.annotate?.({
730
+ session_id: activeSessionIdRef.current,
731
+ thread_id: activeThreadIdRef.current,
732
+ turn_id: activeTurnIdRef.current,
733
+ final_transcript_length: trimmed.length
734
+ });
735
+ activeProcessingStageRef.current = activeVoicePipelineRef.current?.startStage?.('voice.processing', {
736
+ session_id: activeSessionIdRef.current,
737
+ thread_id: activeThreadIdRef.current,
738
+ turn_id: activeTurnIdRef.current,
739
+ latency_scope: 'post_stop_processing',
740
+ 'voice.latency_scope': 'post_stop_processing',
741
+ processing_start: 'transcript_finalized',
742
+ final_transcript_length: trimmed.length
743
+ }) || null;
744
+ const finalTranscriptStage = activeVoicePipelineRef.current?.startStage?.('stt.final_transcript', {
745
+ transcript_length: trimmed.length
746
+ }) || null;
747
+ finalTranscriptStage?.finish?.('ok', {
748
+ transcript_length: trimmed.length
749
+ });
750
+ let parseInput = trimmed;
751
+ let parsedCommand = null;
752
+ try {
753
+ if (latestTranslationRef.current) {
754
+ parseInput = latestTranslationRef.current;
755
+ }
756
+ const preParseSnapshot = await waitForStableInterfaceSnapshot();
757
+ if (preParseSnapshot.visibilityState === "transition_unstable") {
758
+ throw new VisibilityTransitionError(navigationSettlingMessage);
759
+ }
760
+ const preParseInterfaces = preParseSnapshot.interfaces;
761
+ const latestTap = getLatestUnblockedTap();
762
+ const runtimeUiContext = {
763
+ tapClassName: resolveTapClassName(preParseInterfaces, latestTap),
764
+ visibleClassNames: Array.from(new Set(preParseInterfaces.map(genieInterface => genieInterface.className))),
765
+ isDeicticUtterance: isDeicticReferenceUtterance(parseInput)
766
+ };
767
+ applyRuntimeUiContext(GenieInterpreter, runtimeUiContext);
768
+ _logger.default.info(`[VoicePipeline] runtime UI context: tapClass=${runtimeUiContext.tapClassName || "none"}; visible=${runtimeUiContext.visibleClassNames.join(",") || "none"}; deictic=${runtimeUiContext.isDeicticUtterance ? "yes" : "no"}`);
769
+ _logger.default.info('Start parsing transcript with GenieInterpreter');
770
+ const parseStage = activeVoicePipelineRef.current?.startStage?.('dsl.parse', {
771
+ parse_input_length: parseInput.length
772
+ }) || null;
773
+ const result = await GenieInterpreter.nlParser.parse(parseInput);
774
+ parseStage?.finish?.('ok', {
775
+ actionable: typeof result === 'string' && result.trim() !== ''
776
+ });
777
+ _logger.default.info('[VoicePipeline] parse success');
778
+ _logger.default.info(`parsed result: ${result}`);
779
+ if (typeof result !== "string" || result.trim() === "") {
780
+ recordInterpreterTurn(GenieInterpreter, {
781
+ utterance: parseInput,
782
+ success: false,
783
+ resultSummary: 'parse_empty'
784
+ });
785
+ activeVoicePipelineRef.current?.annotate?.({
786
+ command_outcome: 'no_actionable_command'
787
+ });
788
+ _logger.default.info('[VoicePipeline] parse returned no actionable command');
789
+ speechRecognition.setInterimTranscript("");
790
+ (0, _sonnerNative.toast)(noCommandMessage);
791
+ armSpeechResponseTimeout('no_actionable_command');
792
+ void speakVoiceResponse(noCommandMessage);
793
+ return;
794
+ }
795
+ parsedCommand = result.trim();
796
+ speechRecognition.setInterimTranscript('');
797
+ const navStackBeforeDisplay = navStackRef.current;
798
+ const executeStage = activeVoicePipelineRef.current?.startStage?.('dsl.execute', {
799
+ parsed_command_length: parsedCommand.length
800
+ }) || null;
801
+ const executionResult = await (0, _sharedStore.executeGenieCode)(parsedCommand, {
802
+ origin: 'voice',
803
+ shouldSpeakErrors: true
804
+ });
805
+ executeStage?.finish?.(executionResult.success ? 'ok' : 'error', {
806
+ execution_success: executionResult.success
807
+ });
808
+ if (executionResult.success) {
809
+ recordInterpreterTurn(GenieInterpreter, {
810
+ utterance: parseInput,
811
+ parsed: parsedCommand,
812
+ success: true,
813
+ resultSummary: 'execute_ok'
814
+ });
815
+ // Snapshot mounted interfaces after execution so onScreen matching
816
+ // reflects the latest native mount/unmount state.
817
+ const postExecutionSnapshot = await waitForStableInterfaceSnapshot();
818
+ const genieInterfaces = postExecutionSnapshot.visibilityState === "transition_unstable" ? [] : postExecutionSnapshot.interfaces;
819
+ _logger.default.info('[VoicePipeline] DSL execution success');
820
+ _logger.default.info('execution result: ', executionResult);
821
+ (0, _sharedStore.displayResult)(executionResult, trimmed, parsedCommand, genieInterfaces);
822
+ const displayStage = activeVoicePipelineRef.current?.startStage?.('ui.display', {
823
+ expected_navigation_event_id: navStackBeforeDisplay + 1
824
+ }) || null;
825
+ setTimeout(() => {
826
+ const navIntentObserved = navStackRef.current > navStackBeforeDisplay;
827
+ _logger.default.info(`[VoicePipeline] nav intent observed by adapter: ${navIntentObserved ? 'yes' : 'no'}`);
828
+ displayOutcomeRef.current = navIntentObserved ? 'rendered' : 'skipped_intentional';
829
+ displayStage?.finish?.(navIntentObserved ? 'ok' : 'skipped', {
830
+ nav_intent_observed: navIntentObserved
831
+ });
832
+ activeVoicePipelineRef.current?.annotate?.({
833
+ display_outcome: displayOutcomeRef.current,
834
+ nav_intent_observed: navIntentObserved
835
+ });
836
+ if (!navIntentObserved) {
837
+ _logger.default.warn('[VoicePipeline] likely_skipped_upstream_by_display_gate');
838
+ }
839
+ }, 350);
840
+ armSpeechResponseTimeout('post_display_response');
841
+ } else {
842
+ recordInterpreterTurn(GenieInterpreter, {
843
+ utterance: parseInput,
844
+ parsed: parsedCommand,
845
+ success: false,
846
+ resultSummary: 'execute_error:execution_failed'
847
+ });
848
+ finishVoicePipeline('error', {
849
+ reason: 'dsl_execution_failed'
850
+ });
851
+ }
852
+ _reactDecorators.ClickPoints.splice(0, _reactDecorators.ClickPoints.length);
853
+ } catch (error) {
854
+ const errorMessage = error instanceof Error ? error.message : String(error);
855
+ recordInterpreterTurn(GenieInterpreter, {
856
+ utterance: parseInput,
857
+ parsed: parsedCommand,
858
+ success: false,
859
+ resultSummary: parsedCommand ? `execute_error:${errorMessage}` : `parse_error:${errorMessage}`
860
+ });
861
+ if (isNoCommandParseError(error)) {
862
+ activeVoicePipelineRef.current?.annotate?.({
863
+ command_outcome: 'no_actionable_command'
864
+ });
865
+ _logger.default.info('No actionable command detected from transcript');
866
+ (0, _sonnerNative.toast)(noCommandMessage);
867
+ armSpeechResponseTimeout('no_actionable_command_error');
868
+ void speakVoiceResponse(noCommandMessage);
869
+ } else if (error instanceof VisibilityTransitionError) {
870
+ activeVoicePipelineRef.current?.annotate?.({
871
+ command_outcome: 'navigation_transition_unstable'
872
+ });
873
+ _logger.default.info('Deferred transcript processing while navigation was transitioning');
874
+ (0, _sonnerNative.toast)(navigationSettlingMessage);
875
+ armSpeechResponseTimeout('navigation_transition_unstable');
876
+ void speakVoiceResponse(navigationSettlingMessage);
877
+ } else {
878
+ finishVoicePipeline('error', {
879
+ reason: 'transcript_processing_failed'
880
+ });
881
+ _logger.default.error('Failed to process transcript', error);
882
+ }
883
+ } finally {
884
+ applyRuntimeUiContext(GenieInterpreter, null);
885
+ speechRecognition.setProcessing(false);
886
+ isProcessingTranscriptRef.current = false;
887
+ acceptingSpeechInputRef.current = false;
888
+ clearLateFinalFallback();
889
+ latestTranscriptRef.current = '';
890
+ latestTranslationRef.current = '';
891
+ try {
892
+ const monitor = (0, _reactgenieDsl.getLLMMonitor)();
893
+ monitor.setThread(null);
894
+ } catch (e) {
895
+ // ignore
896
+ }
897
+ }
898
+ }, [armSpeechResponseTimeout, clearLateFinalFallback, _sharedStore.displayResult, _sharedStore.executeGenieCode, finishListeningStage, finishVoicePipeline, getLatestUnblockedTap, speakVoiceResponse, speechRecognition]);
899
+
900
+ // ========== Event Handlers ==========
901
+
902
+ (0, _react.useEffect)(() => {
903
+ if (_reactNative.Platform.OS !== "web" || typeof document === "undefined") {
904
+ return;
905
+ }
906
+ if (listenerState !== _platform.ListenerState.Listening) {
907
+ touchStartPointRef.current = null;
908
+ blockedOverlayTapRef.current = false;
909
+ setIsPressed(false);
910
+ return;
911
+ }
912
+ const handlePointerDown = event => {
913
+ const startX = event?.clientX ?? 0;
914
+ const startY = event?.clientY ?? 0;
915
+ if (pointIsInBlockedSelectionRect(startX, startY)) {
916
+ touchStartPointRef.current = null;
917
+ blockedOverlayTapRef.current = true;
918
+ setIsPressed(false);
919
+ return;
920
+ }
921
+ blockedOverlayTapRef.current = false;
922
+ // Refresh wrapper geometry at touch start so later Current() resolution
923
+ // uses the card positions the user actually saw when tapping.
924
+ (0, _reactDecorators.RefreshDisplayedInstanceRects)();
925
+ touchStartPointRef.current = {
926
+ x: startX,
927
+ y: startY,
928
+ at: Date.now()
929
+ };
930
+ setIsPressed(true);
931
+ };
932
+ const handlePointerUp = event => {
933
+ const start = touchStartPointRef.current;
934
+ touchStartPointRef.current = null;
935
+ setIsPressed(false);
936
+ if (!start) {
937
+ return;
938
+ }
939
+ const endX = event?.clientX ?? start.x;
940
+ const endY = event?.clientY ?? start.y;
941
+ const dx = endX - start.x;
942
+ const dy = endY - start.y;
943
+ const movedDistanceSq = dx * dx + dy * dy;
944
+ const durationMs = Date.now() - start.at;
945
+ const isLikelyTap = movedDistanceSq <= 14 * 14 && durationMs <= 550;
946
+ if (!isLikelyTap) {
947
+ return;
948
+ }
949
+ const currentClickPoints = _reactDecorators.ClickPoints ?? [];
950
+ if (pointIsInBlockedSelectionRect(endX, endY)) {
951
+ _logger.default.debug(`[Voice] web tap ignored at (${endX}, ${endY}); overlaps voice UI occlusion zone`);
952
+ return;
953
+ }
954
+ _logger.default.debug(`[Voice] web tap captured at (${endX}, ${endY}); previous taps=${currentClickPoints.length}`);
955
+ blockedOverlayTapRef.current = false;
956
+ currentClickPoints.push({
957
+ x: endX,
958
+ y: endY
959
+ });
960
+ };
961
+ const handlePointerCancel = () => {
962
+ touchStartPointRef.current = null;
963
+ blockedOverlayTapRef.current = false;
964
+ setIsPressed(false);
965
+ };
966
+ const options = {
967
+ passive: true,
968
+ capture: true
969
+ };
970
+ document.addEventListener("pointerdown", handlePointerDown, options);
971
+ document.addEventListener("pointerup", handlePointerUp, options);
972
+ document.addEventListener("pointercancel", handlePointerCancel, options);
973
+ return () => {
974
+ document.removeEventListener("pointerdown", handlePointerDown, options);
975
+ document.removeEventListener("pointerup", handlePointerUp, options);
976
+ document.removeEventListener("pointercancel", handlePointerCancel, options);
977
+ touchStartPointRef.current = null;
978
+ blockedOverlayTapRef.current = false;
979
+ setIsPressed(false);
980
+ };
981
+ }, [listenerState, pointIsInBlockedSelectionRect]);
982
+
983
+ /**
984
+ * Handle press events on overlay (clicks/touches)
985
+ * Extracts coordinates for spatial interaction
986
+ */
987
+ const handleOverlayPress = (0, _react.useCallback)(event => {
988
+ if (_reactNative.Platform.OS === "web") {
989
+ setIsPressed(false);
990
+ const blockedTap = blockedOverlayTapRef.current;
991
+ blockedOverlayTapRef.current = false;
992
+ if (listenerState === _platform.ListenerState.Listening && blockedTap) {
993
+ handleMicrophonePressRef.current?.();
994
+ }
995
+ return;
996
+ }
997
+ const listening = listenerState === _platform.ListenerState.Listening;
998
+ const start = touchStartPointRef.current;
999
+ touchStartPointRef.current = null;
1000
+ setIsPressed(false);
1001
+ if (!listening || !start) {
1002
+ return;
1003
+ }
1004
+ const coords = (0, _platform.getCoordinates)(event);
1005
+ const dx = coords.x - start.x;
1006
+ const dy = coords.y - start.y;
1007
+ const movedDistanceSq = dx * dx + dy * dy;
1008
+ const durationMs = Date.now() - start.at;
1009
+ const isLikelyTap = movedDistanceSq <= 14 * 14 && durationMs <= 550;
1010
+ if (!isLikelyTap) {
1011
+ return;
1012
+ }
1013
+ const currentClickPoints = _reactDecorators.ClickPoints ?? [];
1014
+ if (pointIsInBlockedSelectionRect(coords.x, coords.y)) {
1015
+ _logger.default.debug(`[Voice] overlay tap ignored at (${coords.x}, ${coords.y}); overlaps voice UI occlusion zone`);
1016
+ return;
1017
+ }
1018
+ _logger.default.debug(`[Voice] overlay tap captured at (${coords.x}, ${coords.y}); previous taps=${currentClickPoints.length}`);
1019
+ currentClickPoints.push(coords);
1020
+ }, [listenerState, pointIsInBlockedSelectionRect]);
1021
+
1022
+ /**
1023
+ * Handle press down on overlay
1024
+ */
1025
+ const handleOverlayPressDown = (0, _react.useCallback)(event => {
1026
+ if (_reactNative.Platform.OS === "web") {
1027
+ setIsPressed(true);
1028
+ return;
1029
+ }
1030
+ if (listenerState === _platform.ListenerState.Listening) {
1031
+ // Native lists do not emit fresh onLayout coordinates while scrolling, so
1032
+ // force a measurement pass at press-in before storing the tap point.
1033
+ const coords = (0, _platform.getCoordinates)(event);
1034
+ if (pointIsInBlockedSelectionRect(coords.x, coords.y)) {
1035
+ touchStartPointRef.current = null;
1036
+ setIsPressed(false);
1037
+ return;
1038
+ }
1039
+ (0, _reactDecorators.RefreshDisplayedInstanceRects)();
1040
+ touchStartPointRef.current = {
1041
+ x: coords.x,
1042
+ y: coords.y,
1043
+ at: Date.now()
1044
+ };
1045
+ } else {
1046
+ touchStartPointRef.current = null;
1047
+ }
1048
+ setIsPressed(true);
1049
+ }, [listenerState, pointIsInBlockedSelectionRect]);
1050
+
1051
+ /**
1052
+ * Handle microphone button press
1053
+ * Toggles between idle and listening states
1054
+ */
1055
+ const handleMicrophonePress = (0, _react.useCallback)(() => {
1056
+ if (speechRecognition.isProcessing) {
1057
+ _logger.default.debug('Ignoring microphone toggle while transcript processing is active');
1058
+ return;
1059
+ }
1060
+ if (speechRecognition.isListening) {
1061
+ const pauseText = latestTranscriptRef.current.trim();
1062
+ if (pauseText) {
1063
+ _logger.default.info('Speech state toggled to: paused; processing latest transcript');
1064
+ processTranscript(activeSessionIdRef.current, pauseText);
1065
+ } else {
1066
+ speechRecognition.stopListening();
1067
+ beginLateFinalFallback('Manual mic pause with empty transcript');
1068
+ }
1069
+ return;
1070
+ }
1071
+ activeSessionIdRef.current += 1;
1072
+ if (activeVoicePipelineRef.current) {
1073
+ finishVoicePipeline('aborted', {
1074
+ reason: 'new_session_started'
1075
+ });
1076
+ }
1077
+ // Generate a unique per-interaction thread id (string) and attach to LLM monitor
1078
+ const interactionId = `interaction-${activeSessionIdRef.current}-${Date.now()}`;
1079
+ const turnId = `voice-turn-${activeSessionIdRef.current}-${Date.now()}`;
1080
+ activeThreadIdRef.current = interactionId;
1081
+ activeTurnIdRef.current = turnId;
1082
+ try {
1083
+ const monitor = (0, _reactgenieDsl.getLLMMonitor)();
1084
+ monitor.setThread(interactionId);
1085
+ } catch (e) {
1086
+ // ignore monitoring setup errors
1087
+ }
1088
+ const telemetryBridge = (0, _voicePipelineTelemetry.getVoicePipelineTelemetryBridge)();
1089
+ displayOutcomeRef.current = 'not_applicable';
1090
+ activeVoicePipelineRef.current = telemetryBridge?.startPipeline?.({
1091
+ sessionId: activeSessionIdRef.current,
1092
+ threadId: activeThreadIdRef.current,
1093
+ turnId: activeTurnIdRef.current,
1094
+ provider: resolvedSpeechConfig.provider,
1095
+ language: resolvedSpeechLanguage,
1096
+ platform: _reactNative.Platform.OS
1097
+ }) || null;
1098
+ activeListeningStageRef.current = activeVoicePipelineRef.current?.startStage?.('stt.listen', {
1099
+ session_id: activeSessionIdRef.current,
1100
+ thread_id: activeThreadIdRef.current,
1101
+ turn_id: activeTurnIdRef.current,
1102
+ provider: resolvedSpeechConfig.provider
1103
+ }) || null;
1104
+ finalizedSessionIdRef.current = -1;
1105
+ acceptingSpeechInputRef.current = true;
1106
+ clearLateFinalFallback();
1107
+ clearSpeechResponseTimeout();
1108
+ latestTranscriptRef.current = '';
1109
+ latestTranslationRef.current = '';
1110
+ const currentClickPoints = _reactDecorators.ClickPoints ?? [];
1111
+ if (currentClickPoints.length > 0) {
1112
+ _logger.default.debug(`[Voice] clearing ${currentClickPoints.length} stale tap(s) before starting new listening session`);
1113
+ currentClickPoints.splice(0, currentClickPoints.length);
1114
+ }
1115
+ speechRecognition.clearTranscript();
1116
+ if (isOpenAIProvider) {
1117
+ setIsOpenAISpeechReady(false);
1118
+ }
1119
+ speechRecognition.startListening();
1120
+ _logger.default.info(`Speech session started (session=${activeSessionIdRef.current})`);
1121
+ }, [clearLateFinalFallback, clearSpeechResponseTimeout, finishVoicePipeline, isOpenAIProvider, processTranscript, resolvedSpeechConfig.provider, resolvedSpeechLanguage, speechRecognition]);
1122
+ (0, _react.useEffect)(() => {
1123
+ handleMicrophonePressRef.current = handleMicrophonePress;
1124
+ }, [handleMicrophonePress]);
1125
+
1126
+ /**
1127
+ * Speech recognition status callback
1128
+ */
1129
+ const handleSpeechStatus = (0, _react.useCallback)((status, interim) => {
1130
+ if (!acceptingSpeechInputRef.current || isProcessingTranscriptRef.current) {
1131
+ _logger.default.debug(`[Voice] Ignoring speech status update (status=${status}) while session locked`);
1132
+ return;
1133
+ }
1134
+ _logger.default.debug(`[Voice] Speech status: ${status} (interim length=${interim.length})`);
1135
+ if (status && latestTranslationRef.current) {
1136
+ latestTranslationRef.current = '';
1137
+ }
1138
+ const trimmed = interim.trim();
1139
+ if (trimmed !== '' && trimmed !== latestTranscriptRef.current) {
1140
+ _logger.default.debug(`[Voice] ${status ? 'Interim' : 'Final'} transcript: ${trimmed}`);
1141
+ speechRecognition.setInterimTranscript(trimmed);
1142
+ latestTranscriptRef.current = trimmed;
1143
+ }
1144
+ if (!status) {
1145
+ const pauseText = latestTranscriptRef.current.trim();
1146
+ if (pauseText) {
1147
+ clearLateFinalFallback();
1148
+ _logger.default.info('[Voice] Mic pause detected; processing latest transcript immediately');
1149
+ processTranscript(activeSessionIdRef.current, pauseText);
1150
+ } else if (isOpenAIAutoStopEnabled) {
1151
+ // Ref-first auto-stop path: do not wait for final callbacks.
1152
+ speechRecognition.stopListening();
1153
+ clearLateFinalFallback();
1154
+ acceptingSpeechInputRef.current = false;
1155
+ finishListeningStage('cancelled', {
1156
+ reason: 'empty_pause_auto_stop'
1157
+ });
1158
+ finishVoicePipeline('aborted', {
1159
+ reason: 'empty_pause_auto_stop'
1160
+ });
1161
+ _logger.default.info('[Voice] VAD silence pause with empty ref transcript; stop finalized without waiting for final callback');
1162
+ } else if (awaitingLateFinalAfterPauseRef.current) {
1163
+ _logger.default.debug('[Voice] Mic pause received with empty transcript; awaiting late final callback');
1164
+ } else if (!speechRecognition.isListening) {
1165
+ acceptingSpeechInputRef.current = false;
1166
+ finishListeningStage('cancelled', {
1167
+ reason: 'pause_without_transcript'
1168
+ });
1169
+ finishVoicePipeline('aborted', {
1170
+ reason: 'pause_without_transcript'
1171
+ });
1172
+ }
1173
+ }
1174
+ }, [clearLateFinalFallback, finishListeningStage, finishVoicePipeline, isOpenAIAutoStopEnabled, processTranscript, speechRecognition]);
1175
+
1176
+ /**
1177
+ * Speech recognition translation callback
1178
+ */
1179
+ const handleSpeechTranslation = (0, _react.useCallback)(translation => {
1180
+ const trimmed = translation.trim();
1181
+ if (!trimmed) return;
1182
+ latestTranslationRef.current = trimmed;
1183
+ }, []);
1184
+
1185
+ /**
1186
+ * Speech recognition result callback
1187
+ */
1188
+ const handleSpeechResult = (0, _react.useCallback)(finalTranscript => {
1189
+ const trimmed = finalTranscript.trim();
1190
+ if (!trimmed) return;
1191
+ if (!acceptingSpeechInputRef.current && !awaitingLateFinalAfterPauseRef.current || isProcessingTranscriptRef.current) {
1192
+ _logger.default.debug('[Voice] Ignoring final transcript while session locked');
1193
+ return;
1194
+ }
1195
+
1196
+ // Fast-path contract: parsing only occurs on mic pause (status=false or manual stop).
1197
+ // Final callbacks only refresh the latest candidate transcript.
1198
+ _logger.default.debug('[Voice] Final transcript received; buffered until mic pause');
1199
+ speechRecognition.setInterimTranscript(trimmed);
1200
+ latestTranscriptRef.current = trimmed;
1201
+ activeVoicePipelineRef.current?.annotate?.({
1202
+ latest_transcript_length: trimmed.length,
1203
+ thread_id: activeThreadIdRef.current,
1204
+ session_id: activeSessionIdRef.current,
1205
+ turn_id: activeTurnIdRef.current
1206
+ });
1207
+ if (awaitingLateFinalAfterPauseRef.current) {
1208
+ clearLateFinalFallback();
1209
+ _logger.default.info('[Voice] Late final transcript received after mic pause; processing now');
1210
+ processTranscript(activeSessionIdRef.current, trimmed);
1211
+ }
1212
+ }, [clearLateFinalFallback, processTranscript, speechRecognition]);
1213
+
1214
+ /**
1215
+ * Waveform callback for mic-button visualization.
1216
+ */
1217
+ const handleWaveformPreview = (0, _react.useCallback)(waveform => {
1218
+ speechRecognition.setWaveformPreview(waveform);
1219
+ }, [speechRecognition.setWaveformPreview]);
1220
+ const handleSpeechReady = (0, _react.useCallback)(ready => {
1221
+ if (!isOpenAIProvider) {
1222
+ return;
1223
+ }
1224
+ setIsOpenAISpeechReady(ready);
1225
+ }, [isOpenAIProvider]);
1226
+ const getSpeechRequestContext = (0, _react.useCallback)(() => {
1227
+ const traceHeaders = activeVoicePipelineRef.current?.getRequestHeaders?.() || {};
1228
+ return {
1229
+ threadId: activeThreadIdRef.current,
1230
+ turnId: activeTurnIdRef.current,
1231
+ sessionId: activeSessionIdRef.current,
1232
+ sentryTrace: traceHeaders["sentry-trace"],
1233
+ baggage: traceHeaders.baggage
1234
+ };
1235
+ }, []);
1236
+
1237
+ // ========== Render ==========
1238
+
1239
+ const isOverlayVisible = isListeningForUi || listenerState === _platform.ListenerState.Processing;
1240
+ const isProcessing = listenerState === _platform.ListenerState.Processing;
1241
+ const isListening = isListeningForUi;
1242
+ const micButtonColor = isListening ? '#0000ff' : '#cccccc';
1243
+
1244
+ // logger.info('voiceMessage:', voiceMessage);
1245
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
1246
+ style: {
1247
+ flex: 1
1248
+ }
1249
+ }, gui, /*#__PURE__*/_react.default.createElement(_sonnerNative.Toaster, null), /*#__PURE__*/_react.default.createElement(_platform.PlatformOverlay, {
1250
+ visible: isOverlayVisible,
1251
+ onPress: handleOverlayPress,
1252
+ onPressDown: handleOverlayPressDown,
1253
+ interactive: true,
1254
+ backgroundColor: isPressed ? 'rgba(127, 127, 127, 0.5)' : 'rgba(204, 204, 204, 0.5)',
1255
+ opacity: 0.5,
1256
+ isProcessing: isProcessing,
1257
+ isListening: isListening,
1258
+ audioLevel: speechRecognition.audioLevel,
1259
+ transcriptText: speechRecognition.interimTranscript,
1260
+ showTranscript: false // Disabled in favor of VoiceRecognitionBar
1261
+ ,
1262
+ showAudioVisualizer: false // Disabled in favor of VoiceRecognitionBar
1263
+ }), showFloatingMicButton && /*#__PURE__*/_react.default.createElement(_platform.PlatformButton, {
1264
+ onPress: handleMicrophonePress,
1265
+ backgroundColor: micButtonColor,
1266
+ size: 50,
1267
+ disabled: isProcessing
1268
+ }, /*#__PURE__*/_react.default.createElement(_vectorIcons.Ionicons, {
1269
+ name: isListening ? "mic" : "mic-outline",
1270
+ size: 28,
1271
+ color: "#ffffff"
1272
+ })), _reactNative.Platform.OS === 'web' ? /*#__PURE__*/_react.default.createElement(_reactNative.View, {
1273
+ testID: VOICE_UI_OCCLUSION_TEST_ID,
1274
+ onLayout: handleVoiceUiLayout,
1275
+ collapsable: false,
1276
+ pointerEvents: "box-none"
1277
+ }, /*#__PURE__*/_react.default.createElement(VoiceUIComponent, {
1278
+ state: speechRecognition.state,
1279
+ isListening: isListeningForUi,
1280
+ isConnecting: isConnecting,
1281
+ isProcessing: speechRecognition.isProcessing,
1282
+ interimTranscript: speechRecognition.interimTranscript,
1283
+ transcript: speechRecognition.transcript,
1284
+ audioLevel: speechRecognition.audioLevel,
1285
+ waveformPreview: speechRecognition.waveformPreview,
1286
+ onToggle: handleMicrophonePress,
1287
+ showTranscript: displayTranscript,
1288
+ placeholderText: voicePlaceholder
1289
+ })) : /*#__PURE__*/_react.default.createElement(VoiceUIComponent, {
1290
+ state: speechRecognition.state,
1291
+ isListening: isListeningForUi,
1292
+ isConnecting: isConnecting,
1293
+ isProcessing: speechRecognition.isProcessing,
1294
+ interimTranscript: speechRecognition.interimTranscript,
1295
+ transcript: speechRecognition.transcript,
1296
+ audioLevel: speechRecognition.audioLevel,
1297
+ waveformPreview: speechRecognition.waveformPreview,
1298
+ onToggle: handleMicrophonePress,
1299
+ showTranscript: displayTranscript,
1300
+ placeholderText: voicePlaceholder
1301
+ }), /*#__PURE__*/_react.default.createElement(_speechRecognitionUnified.UnifiedSpeechRecognizer, {
1302
+ shouldListen: listenerState === _platform.ListenerState.Listening,
1303
+ speechStatusCallback: handleSpeechStatus,
1304
+ speechResultCallback: handleSpeechResult,
1305
+ speechTranslationCallback: handleSpeechTranslation,
1306
+ speechReadyCallback: handleSpeechReady,
1307
+ clientSecret: clientSecret,
1308
+ config: speechConfig,
1309
+ language: resolvedSpeechLanguage,
1310
+ requestContextProvider: getSpeechRequestContext,
1311
+ waveformPreviewCallback: handleWaveformPreview,
1312
+ onError: error => _logger.default.error("Speech recognition error at modality providerV2:", error)
1313
+
1314
+ // enableVAD={true}
1315
+ // silenceThreshold={10}
1316
+ // silenceDuration={1500}
1317
+ }));
1318
+ };
1319
+ exports.ModalityProvider = ModalityProvider;
1320
+ var _default = exports.default = ModalityProvider;
1321
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3RSZWR1eCIsIl9yZWFjdE5hdGl2ZSIsIl9uYXRpdmUiLCJfc3RhY2siLCJfdmVjdG9ySWNvbnMiLCJfc29ubmVyTmF0aXZlIiwiX25hdmlnYXRpb25BZGFwdGVyIiwiX3JlYWN0Z2VuaWVEc2wiLCJfcmVhY3REZWNvcmF0b3JzIiwiX3NoYXJlZFN0b3JlIiwiX3NwZWVjaFJlY29nbml0aW9uVW5pZmllZCIsIl91c2VTcGVlY2hSZWNvZ25pdGlvbiIsIl9Wb2ljZVJlY29nbml0aW9uQmFyIiwiX3BsYXRmb3JtIiwiX2xvZ2dlciIsIl92b2ljZVBpcGVsaW5lVGVsZW1ldHJ5IiwiZSIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJfX2VzTW9kdWxlIiwibyIsImkiLCJmIiwiX19wcm90b19fIiwiZGVmYXVsdCIsImhhcyIsImdldCIsInNldCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJmaWx0ZXIiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIl90b1Byb3BlcnR5S2V5IiwidmFsdWUiLCJjb25maWd1cmFibGUiLCJ3cml0YWJsZSIsIl90b1ByaW1pdGl2ZSIsIlN5bWJvbCIsInRvUHJpbWl0aXZlIiwiVHlwZUVycm9yIiwiU3RyaW5nIiwiTnVtYmVyIiwiU1BFRUNIX01JTklNQUxfVEVYVF9MSU1JVCIsIlZPSUNFX1VJX09DQ0xVU0lPTl9URVNUX0lEIiwidHJ1bmNhdGVUZXh0IiwibWF4TGVuZ3RoIiwic2xpY2UiLCJNYXRoIiwibWF4IiwidHJpbUVuZCIsIm5vcm1hbGl6ZUxhbmd1YWdlVGFnIiwibGFuZyIsIm5vcm1hbGl6ZWQiLCJ0cmltIiwidG9Mb3dlckNhc2UiLCJpc05vQ29tbWFuZFBhcnNlRXJyb3IiLCJlcnJvciIsIkVycm9yIiwibWVzc2FnZSIsImluY2x1ZGVzIiwiREVJQ1RJQ19SRUZFUkVOQ0VfUEFUVEVSTiIsImlzRGVpY3RpY1JlZmVyZW5jZVV0dGVyYW5jZSIsInV0dGVyYW5jZSIsInRlc3QiLCJwb2ludFRvUmVjdERpc3RhbmNlU3EiLCJwb2ludFgiLCJwb2ludFkiLCJyZWN0IiwiY2xvc2VzdFgiLCJ4IiwibWluIiwid2lkdGgiLCJjbG9zZXN0WSIsInkiLCJoZWlnaHQiLCJwb3ciLCJwb2ludEluUmVjdCIsInJlY3RGcm9tRG9tQm91bmRzIiwibGVmdCIsInRvcCIsImdldFdlYlZvaWNlVWlPY2NsdXNpb25SZWN0IiwiZWxlbWVudCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsIm1pbkxlZnQiLCJQT1NJVElWRV9JTkZJTklUWSIsIm1pblRvcCIsIm1heFJpZ2h0IiwiTkVHQVRJVkVfSU5GSU5JVFkiLCJtYXhCb3R0b20iLCJkZXNjZW5kYW50IiwiQXJyYXkiLCJmcm9tIiwicXVlcnlTZWxlY3RvckFsbCIsImRlc2NlbmRhbnRSZWN0IiwicmlnaHQiLCJib3R0b20iLCJpc0Zpbml0ZSIsInVuZGVmaW5lZCIsInJlc29sdmVUYXBDbGFzc05hbWUiLCJpbnRlcmZhY2VzIiwidGFwIiwibmVhcmVzdCIsIm5lYXJlc3REaXN0YW5jZSIsImluZGV4IiwiY2FuZGlkYXRlIiwiZGlzdGFuY2UiLCJjbGFzc05hbWUiLCJhcHBseVJ1bnRpbWVVaUNvbnRleHQiLCJpbnRlcnByZXRlciIsImNvbnRleHQiLCJtYXliZVJ1bnRpbWVDb250ZXh0U2V0dGVyIiwic2V0UnVudGltZUNvbnRleHQiLCJWaXNpYmlsaXR5VHJhbnNpdGlvbkVycm9yIiwiY29uc3RydWN0b3IiLCJuYW1lIiwid2FpdEZvck1zIiwibXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInNldFRpbWVvdXQiLCJ3YWl0Rm9yU3RhYmxlSW50ZXJmYWNlU25hcHNob3QiLCJ0aW1lb3V0TXMiLCJwb2xsSW50ZXJ2YWxNcyIsImRlYWRsaW5lIiwiRGF0ZSIsIm5vdyIsInNuYXBzaG90IiwiUmV0cmlldmVJbnRlcmZhY2VzU25hcHNob3QiLCJ2aXNpYmlsaXR5U3RhdGUiLCJyZWNvcmRJbnRlcnByZXRlclR1cm4iLCJyZWNvcmQiLCJtYXliZVR1cm5SZWNvcmRlciIsInJlY29yZFR1cm4iLCJyZWNvcmRJbnRlcmFjdGlvbiIsIlN0YWNrIiwiY3JlYXRlU3RhY2tOYXZpZ2F0b3IiLCJHZW5pZUludGVycHJldGVyIiwiZXhwb3J0cyIsImNhcmRTdHlsZSIsInByZXNlbnRhdGlvbiIsImhlYWRlclN0eWxlSW50ZXJwb2xhdG9yIiwiSGVhZGVyU3R5bGVJbnRlcnBvbGF0b3JzIiwiZm9yVUlLaXQiLCJjYXJkU3R5bGVJbnRlcnBvbGF0b3IiLCJDYXJkU3R5bGVJbnRlcnBvbGF0b3JzIiwiZm9ySG9yaXpvbnRhbElPUyIsIkRlZmF1bHRTY3JlZW4iLCJjaGlsZHJlbiIsIm5hdmlnYXRpb24iLCJ1c2VFZmZlY3QiLCJzZXRPcHRpb25zIiwiaGVhZGVyU2hvd24iLCJjcmVhdGVFbGVtZW50IiwiRnJhZ21lbnQiLCJPYmplY3RJbnRlcmZhY2VTY3JlZW4iLCJnZW5pZUludGVyZmFjZVN0b3JlRWxlbWVudCIsInJvdXRlIiwicGFyYW1zIiwidGl0bGUiLCJmdW5jdGlvbiIsIk1vZGFsaXR5UHJvdmlkZXIiLCJleGFtcGxlcyIsInByb3BzRXhhbXBsZXMiLCJjbGllbnRTZWNyZXQiLCJhcGlCYXNlVXJsIiwicGFyc2VyQ29uZmlnIiwic3BlZWNoQ29uZmlnIiwibG9nZ2VyQ29uZmlnIiwic3BlZWNoTGFuZ3VhZ2UiLCJsYW5nc21pdGhDb25maWciLCJkaXNwbGF5VHJhbnNjcmlwdCIsImV4dHJhUHJvbXB0IiwiVm9pY2VVSUNvbXBvbmVudCIsIlZvaWNlUmVjb2duaXRpb25CYXIiLCJzaG93RmxvYXRpbmdNaWNCdXR0b24iLCJ2b2ljZVBsYWNlaG9sZGVyIiwicmVzb2x2ZWRQcm94eUJhc2VVcmwiLCJzcGVlY2hSZWNvZ25pdGlvbiIsInVzZVNwZWVjaFJlY29nbml0aW9uIiwiY29uZmlndXJlTG9nZ2VyIiwiaXNQcmVzc2VkIiwic2V0SXNQcmVzc2VkIiwidXNlU3RhdGUiLCJpc09wZW5BSVNwZWVjaFJlYWR5Iiwic2V0SXNPcGVuQUlTcGVlY2hSZWFkeSIsInVzZUdlbmllU2VsZWN0b3IiLCJzaGFyZWRFeGFtcGxlcyIsInNoYXJlZFN0YXRlIiwibmF2U3RhdGUiLCJ1c2VTZWxlY3RvciIsInN0YXRlIiwibmF2U3RhY2siLCJ2b2ljZU1lc3NhZ2UiLCJyZXNvbHZlZFNwZWVjaExhbmd1YWdlIiwicmVzb2x2ZWRTcGVlY2hDb25maWciLCJ1c2VNZW1vIiwiZ2V0U3BlZWNoUmVjb2duaXRpb25Db25maWciLCJsYW5nc21pdGhBcGlLZXkiLCJhcGlLZXkiLCJsYW5nc21pdGhQcm9qZWN0IiwicHJvamVjdCIsImxhbmdzbWl0aEVuZHBvaW50IiwiZW5kcG9pbnQiLCJpc09wZW5BSUF1dG9TdG9wRW5hYmxlZCIsInByb3ZpZGVyIiwib3BlbmFpIiwiYXV0b1N0b3BPblZhZFNpbGVuY2UiLCJpc09wZW5BSVByb3ZpZGVyIiwibmF2aWdhdGlvblJlZiIsInVzZU5hdmlnYXRpb25Db250YWluZXJSZWYiLCJsYXN0VHJhbnNjcmlwdFJlZiIsIlJlYWN0IiwidXNlUmVmIiwibGF0ZXN0VHJhbnNjcmlwdFJlZiIsImxhdGVzdFRyYW5zbGF0aW9uUmVmIiwiaXNQcm9jZXNzaW5nVHJhbnNjcmlwdFJlZiIsImFjdGl2ZVNlc3Npb25JZFJlZiIsImZpbmFsaXplZFNlc3Npb25JZFJlZiIsImFjdGl2ZVRocmVhZElkUmVmIiwiYWN0aXZlVHVybklkUmVmIiwiYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYiLCJhd2FpdGluZ0xhdGVGaW5hbEFmdGVyUGF1c2VSZWYiLCJsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmIiwic3BlZWNoUmVzcG9uc2VUaW1lb3V0UmVmIiwiYWN0aXZlVm9pY2VQaXBlbGluZVJlZiIsImFjdGl2ZUxpc3RlbmluZ1N0YWdlUmVmIiwiYWN0aXZlUHJvY2Vzc2luZ1N0YWdlUmVmIiwiZGlzcGxheU91dGNvbWVSZWYiLCJuYXZTdGFja1JlZiIsIndlYlNwZWVjaFV0dGVyYW5jZVJlZiIsInRvdWNoU3RhcnRQb2ludFJlZiIsImJsb2NrZWRPdmVybGF5VGFwUmVmIiwiaGFuZGxlTWljcm9waG9uZVByZXNzUmVmIiwidm9pY2VVaUxheW91dFJlY3RSZWYiLCJjdXJyZW50IiwicmVzb2x2ZWRQYXJzZXJDb25maWciLCJncm9xIiwiYmFzZVVybCIsImRlc2NyaXB0b3JzIiwia2V5IiwiQWxsR2VuaWVPYmplY3RzIiwiQ2xhc3NEZXNjcmlwdG9yIiwiTmxJbnRlcnByZXRlciIsInBhcnNlciIsIm1vbml0b3JpbmciLCJ1aUxpc3QiLCJhbGxJbnRlcmZhY2VzIiwiQWxsR2VuaWVPYmplY3RJbnRlcmZhY2VzIiwibWFwIiwiaW50ZXJmYWNlU3RvcmVFbGVtZW50IiwiU2NyZWVuIiwiY29tcG9uZW50Iiwib3B0aW9ucyIsImd1aSIsImlzRXhwb1JvdXRlciIsIk5hdmlnYXRpb25Db250YWluZXIiLCJyZWYiLCJOYXZpZ2F0b3IiLCJpbml0aWFsUm91dGVOYW1lIiwib2JqZWN0Vmlld0NsYXNzTmFtZSIsImxvZ2dlciIsIndhcm4iLCJpc1JlYWR5IiwiZGlzcGF0Y2giLCJTdGFja0FjdGlvbnMiLCJvYmplY3RDb25zdHJ1Y3RvclBhcmFtcyIsImxpc3RlbmVyU3RhdGUiLCJTcGVlY2hTdGF0ZSIsIkxpc3RlbmluZyIsIkxpc3RlbmVyU3RhdGUiLCJQcm9jZXNzaW5nIiwiSWRsZSIsImlzQ29ubmVjdGluZyIsImlzUHJvY2Vzc2luZyIsImlzTGlzdGVuaW5nRm9yVWkiLCJzZXRTZWxlY3Rpb25CbG9ja2VkUmVjdHMiLCJ1c2VDYWxsYmFjayIsInJlY3RzIiwiQ3VycmVudFNlbGVjdGlvbkJsb2NrZWRSZWN0cyIsInNwbGljZSIsInBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0IiwiZ2V0TGF0ZXN0VW5ibG9ja2VkVGFwIiwidGFwcyIsIkNsaWNrUG9pbnRzIiwidXBkYXRlVm9pY2VVaUJsb2NrZWRSZWN0cyIsImZhbGxiYWNrUmVjdCIsImFwcGx5UmVjdCIsIlBsYXRmb3JtIiwiT1MiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJoYW5kbGVWb2ljZVVpTGF5b3V0IiwiZXZlbnQiLCJuYXRpdmVFdmVudCIsImxheW91dCIsImxheW91dFJlY3QiLCJ2b2ljZVVpVmlzaWJsZSIsImludGVyaW1UcmFuc2NyaXB0IiwidHJhbnNjcmlwdCIsInJhZklkIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiY2FuY2VsQW5pbWF0aW9uRnJhbWUiLCJ0b2FzdE1lc3NhZ2UiLCJmdWxsVGV4dCIsIm1pbmltYWxUZXh0IiwidG9hc3RNZXNzYWdlS2V5IiwidHlwZSIsIm9yaWdpbiIsImNsZWFyVm9pY2VNZXNzYWdlIiwiZ2VuaWVEaXNwYXRjaCIsInJlYWN0R2VuaWVTdGF0ZSIsImN1cnJlbnRNZXNzYWdlIiwiY3VycmVudFRvYXN0TWVzc2FnZSIsImN1cnJlbnRNZXNzYWdlS2V5Iiwic2hvdWxkU3BlYWsiLCJ0b2FzdE9wdGlvbnMiLCJvbkF1dG9DbG9zZSIsIm9uRGlzbWlzcyIsInRvYXN0Iiwic3VjY2VzcyIsImNsZWFyTGF0ZUZpbmFsRmFsbGJhY2siLCJjbGVhclRpbWVvdXQiLCJmaW5pc2hMaXN0ZW5pbmdTdGFnZSIsInN0YXR1cyIsInN0YWdlIiwiZmluaXNoIiwic2Vzc2lvbl9pZCIsInRocmVhZF9pZCIsInR1cm5faWQiLCJjbGVhclNwZWVjaFJlc3BvbnNlVGltZW91dCIsImdldFByb2Nlc3NpbmdTdGFnZVN0YXR1cyIsIm91dGNvbWUiLCJmaW5pc2hQcm9jZXNzaW5nU3RhZ2UiLCJsYXRlbmN5X3Njb3BlIiwiZmluaXNoVm9pY2VQaXBlbGluZSIsInBpcGVsaW5lIiwicHJvY2Vzc2luZ19vdXRjb21lIiwiZGlzcGxheV9vdXRjb21lIiwic3BlYWtWb2ljZVJlc3BvbnNlIiwidGV4dCIsIm5vcm1hbGl6ZWRUZXh0Iiwic3BlZWNoU3RhZ2UiLCJzdGFydFN0YWdlIiwidGV4dF9sZW5ndGgiLCJmaW5pc2hTcGVlY2hTdGFnZSIsInNwZWVjaFN5bnRoZXNpc0FwaSIsImdsb2JhbFRoaXMiLCJzcGVlY2hTeW50aGVzaXMiLCJ1dHRlcmFuY2VDb25zdHJ1Y3RvciIsIlNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZSIsInJlYXNvbiIsInBsYXRmb3JtIiwiY2FuY2VsIiwic3BlYWsiLCJzcGVlY2hfdGV4dF9sZW5ndGgiLCJzcGVlY2hNb2R1bGUiLCJ0aGVuIiwic3RvcCIsImFybVNwZWVjaFJlc3BvbnNlVGltZW91dCIsImJlZ2luTGF0ZUZpbmFsRmFsbGJhY2siLCJpbmZvIiwicHJvY2Vzc1RyYW5zY3JpcHQiLCJzZXNzaW9uSWQiLCJub0NvbW1hbmRNZXNzYWdlIiwibmF2aWdhdGlvblNldHRsaW5nTWVzc2FnZSIsInRyaW1tZWQiLCJzdG9wTGlzdGVuaW5nIiwic2V0UHJvY2Vzc2luZyIsImFubm90YXRlIiwiZmluYWxfdHJhbnNjcmlwdF9sZW5ndGgiLCJwcm9jZXNzaW5nX3N0YXJ0IiwiZmluYWxUcmFuc2NyaXB0U3RhZ2UiLCJ0cmFuc2NyaXB0X2xlbmd0aCIsInBhcnNlSW5wdXQiLCJwYXJzZWRDb21tYW5kIiwicHJlUGFyc2VTbmFwc2hvdCIsInByZVBhcnNlSW50ZXJmYWNlcyIsImxhdGVzdFRhcCIsInJ1bnRpbWVVaUNvbnRleHQiLCJ0YXBDbGFzc05hbWUiLCJ2aXNpYmxlQ2xhc3NOYW1lcyIsIlNldCIsImdlbmllSW50ZXJmYWNlIiwiaXNEZWljdGljVXR0ZXJhbmNlIiwiam9pbiIsInBhcnNlU3RhZ2UiLCJwYXJzZV9pbnB1dF9sZW5ndGgiLCJyZXN1bHQiLCJubFBhcnNlciIsInBhcnNlIiwiYWN0aW9uYWJsZSIsInJlc3VsdFN1bW1hcnkiLCJjb21tYW5kX291dGNvbWUiLCJzZXRJbnRlcmltVHJhbnNjcmlwdCIsIm5hdlN0YWNrQmVmb3JlRGlzcGxheSIsImV4ZWN1dGVTdGFnZSIsInBhcnNlZF9jb21tYW5kX2xlbmd0aCIsImV4ZWN1dGlvblJlc3VsdCIsImV4ZWN1dGVHZW5pZUNvZGUiLCJzaG91bGRTcGVha0Vycm9ycyIsImV4ZWN1dGlvbl9zdWNjZXNzIiwicGFyc2VkIiwicG9zdEV4ZWN1dGlvblNuYXBzaG90IiwiZ2VuaWVJbnRlcmZhY2VzIiwiZGlzcGxheVJlc3VsdCIsImRpc3BsYXlTdGFnZSIsImV4cGVjdGVkX25hdmlnYXRpb25fZXZlbnRfaWQiLCJuYXZJbnRlbnRPYnNlcnZlZCIsIm5hdl9pbnRlbnRfb2JzZXJ2ZWQiLCJlcnJvck1lc3NhZ2UiLCJtb25pdG9yIiwiZ2V0TExNTW9uaXRvciIsInNldFRocmVhZCIsImhhbmRsZVBvaW50ZXJEb3duIiwic3RhcnRYIiwiY2xpZW50WCIsInN0YXJ0WSIsImNsaWVudFkiLCJSZWZyZXNoRGlzcGxheWVkSW5zdGFuY2VSZWN0cyIsImF0IiwiaGFuZGxlUG9pbnRlclVwIiwic3RhcnQiLCJlbmRYIiwiZW5kWSIsImR4IiwiZHkiLCJtb3ZlZERpc3RhbmNlU3EiLCJkdXJhdGlvbk1zIiwiaXNMaWtlbHlUYXAiLCJjdXJyZW50Q2xpY2tQb2ludHMiLCJkZWJ1ZyIsImhhbmRsZVBvaW50ZXJDYW5jZWwiLCJwYXNzaXZlIiwiY2FwdHVyZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiaGFuZGxlT3ZlcmxheVByZXNzIiwiYmxvY2tlZFRhcCIsImxpc3RlbmluZyIsImNvb3JkcyIsImdldENvb3JkaW5hdGVzIiwiaGFuZGxlT3ZlcmxheVByZXNzRG93biIsImhhbmRsZU1pY3JvcGhvbmVQcmVzcyIsImlzTGlzdGVuaW5nIiwicGF1c2VUZXh0IiwiaW50ZXJhY3Rpb25JZCIsInR1cm5JZCIsInRlbGVtZXRyeUJyaWRnZSIsImdldFZvaWNlUGlwZWxpbmVUZWxlbWV0cnlCcmlkZ2UiLCJzdGFydFBpcGVsaW5lIiwidGhyZWFkSWQiLCJsYW5ndWFnZSIsImNsZWFyVHJhbnNjcmlwdCIsInN0YXJ0TGlzdGVuaW5nIiwiaGFuZGxlU3BlZWNoU3RhdHVzIiwiaW50ZXJpbSIsImhhbmRsZVNwZWVjaFRyYW5zbGF0aW9uIiwidHJhbnNsYXRpb24iLCJoYW5kbGVTcGVlY2hSZXN1bHQiLCJmaW5hbFRyYW5zY3JpcHQiLCJsYXRlc3RfdHJhbnNjcmlwdF9sZW5ndGgiLCJoYW5kbGVXYXZlZm9ybVByZXZpZXciLCJ3YXZlZm9ybSIsInNldFdhdmVmb3JtUHJldmlldyIsImhhbmRsZVNwZWVjaFJlYWR5IiwicmVhZHkiLCJnZXRTcGVlY2hSZXF1ZXN0Q29udGV4dCIsInRyYWNlSGVhZGVycyIsImdldFJlcXVlc3RIZWFkZXJzIiwic2VudHJ5VHJhY2UiLCJiYWdnYWdlIiwiaXNPdmVybGF5VmlzaWJsZSIsIm1pY0J1dHRvbkNvbG9yIiwiVmlldyIsInN0eWxlIiwiZmxleCIsIlRvYXN0ZXIiLCJQbGF0Zm9ybU92ZXJsYXkiLCJ2aXNpYmxlIiwib25QcmVzcyIsIm9uUHJlc3NEb3duIiwiaW50ZXJhY3RpdmUiLCJiYWNrZ3JvdW5kQ29sb3IiLCJvcGFjaXR5IiwiYXVkaW9MZXZlbCIsInRyYW5zY3JpcHRUZXh0Iiwic2hvd1RyYW5zY3JpcHQiLCJzaG93QXVkaW9WaXN1YWxpemVyIiwiUGxhdGZvcm1CdXR0b24iLCJzaXplIiwiZGlzYWJsZWQiLCJJb25pY29ucyIsImNvbG9yIiwidGVzdElEIiwib25MYXlvdXQiLCJjb2xsYXBzYWJsZSIsInBvaW50ZXJFdmVudHMiLCJ3YXZlZm9ybVByZXZpZXciLCJvblRvZ2dsZSIsInBsYWNlaG9sZGVyVGV4dCIsIlVuaWZpZWRTcGVlY2hSZWNvZ25pemVyIiwic2hvdWxkTGlzdGVuIiwic3BlZWNoU3RhdHVzQ2FsbGJhY2siLCJzcGVlY2hSZXN1bHRDYWxsYmFjayIsInNwZWVjaFRyYW5zbGF0aW9uQ2FsbGJhY2siLCJzcGVlY2hSZWFkeUNhbGxiYWNrIiwiY29uZmlnIiwicmVxdWVzdENvbnRleHRQcm92aWRlciIsIndhdmVmb3JtUHJldmlld0NhbGxiYWNrIiwib25FcnJvciIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vc3JjL21vZGFsaXR5LXByb3ZpZGVyLXYyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBsYXRmb3JtLWluZGVwZW5kZW50IE1vZGFsaXR5IFByb3ZpZGVyXG4gKiBQcm92aWRlcyB2b2ljZSByZWNvZ25pdGlvbiwgbmF2aWdhdGlvbiwgYW5kIG11bHRpbW9kYWwgaW50ZXJhY3Rpb25cbiAqIEZ1bGx5IHR5cGUtc2FmZSBhbmQgd29ya3Mgb24gV2ViLCBpT1MsIGFuZCBBbmRyb2lkXG4gKi9cblxuaW1wb3J0IFJlYWN0LCB7IHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlU3RhdGUsIHVzZUNhbGxiYWNrIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlU2VsZWN0b3IgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBQbGF0Zm9ybSwgVmlldywgdHlwZSBMYXlvdXRDaGFuZ2VFdmVudCB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5pbXBvcnQge1xuICBOYXZpZ2F0aW9uQ29udGFpbmVyLFxuICBTdGFja0FjdGlvbnMsXG4gIHVzZU5hdmlnYXRpb25Db250YWluZXJSZWYsXG59IGZyb20gJ0ByZWFjdC1uYXZpZ2F0aW9uL25hdGl2ZSc7XG5pbXBvcnQge1xuICBDYXJkU3R5bGVJbnRlcnBvbGF0b3JzLFxuICBjcmVhdGVTdGFja05hdmlnYXRvcixcbiAgSGVhZGVyU3R5bGVJbnRlcnBvbGF0b3JzLFxuICBTdGFja05hdmlnYXRpb25PcHRpb25zLFxufSBmcm9tICdAcmVhY3QtbmF2aWdhdGlvbi9zdGFjayc7XG5pbXBvcnQgeyBJb25pY29ucyB9IGZyb20gJ0BleHBvL3ZlY3Rvci1pY29ucyc7XG5pbXBvcnQgeyBUb2FzdGVyLCB0b2FzdCB9IGZyb20gJ3Nvbm5lci1uYXRpdmUnO1xuaW1wb3J0IHsgaXNFeHBvUm91dGVyIH0gZnJvbSAnLi9hZGFwdGVycy9uYXZpZ2F0aW9uLWFkYXB0ZXInO1xuXG5pbXBvcnQge1xuICBObEludGVycHJldGVyLFxuICBDbGFzc0Rlc2NyaXB0b3IsXG4gIEV4YW1wbGVQYXJzZSxcbiAgR2VuaWVPYmplY3QsXG4gIGdlbmllRGlzcGF0Y2gsXG4gIHR5cGUgTmxJbnRlcnByZXRlclBhcnNlckNvbmZpZyxcbiAgdHlwZSBQcm9tcHRSdW50aW1lQ29udGV4dFNldHRlciBhcyBzZXRJbnRlcnByZXRlclJ1bnRpbWVVaUNvbnRleHQsXG4gIFJ1bnRpbWVVaUNvbnRleHQsXG4gIHNoYXJlZFN0YXRlLFxufSBmcm9tICdAZ2Fycml4ODIvcmVhY3RnZW5pZS1kc2wnO1xuaW1wb3J0IHsgZ2V0TExNTW9uaXRvciB9IGZyb20gJ0BnYXJyaXg4Mi9yZWFjdGdlbmllLWRzbCc7XG5cbmltcG9ydCB7XG4gIEFsbEdlbmllT2JqZWN0SW50ZXJmYWNlcyxcbiAgQWxsR2VuaWVPYmplY3RzLFxuICBDbGlja1BvaW50cyxcbiAgQ3VycmVudFNlbGVjdGlvbkJsb2NrZWRSZWN0cyxcbiAgR2VuaWVJbnRlcmZhY2VTdG9yZUVsZW1lbnQsXG4gIFJlZnJlc2hEaXNwbGF5ZWRJbnN0YW5jZVJlY3RzLFxuICBSZXRyaWV2ZUludGVyZmFjZXNTbmFwc2hvdCxcbn0gZnJvbSAnLi9yZWFjdC1kZWNvcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgZGlzcGxheVJlc3VsdCxcbiAgZXhlY3V0ZUdlbmllQ29kZSxcbiAgTmF2aWdhdG9yU3RhdGUsXG4gIHVzZUdlbmllU2VsZWN0b3IsXG59IGZyb20gJy4vc2hhcmVkLXN0b3JlJztcblxuaW1wb3J0IHtcbiAgVW5pZmllZFNwZWVjaFJlY29nbml6ZXIsXG4gIGdldFNwZWVjaFJlY29nbml0aW9uQ29uZmlnLFxuICB0eXBlIFNwZWVjaFJlY29nbml0aW9uQ29uZmlnLFxufSBmcm9tICcuL3NwZWVjaC1yZWNvZ25pdGlvbi9zcGVlY2gtcmVjb2duaXRpb24tdW5pZmllZCc7XG5pbXBvcnQgeyB1c2VTcGVlY2hSZWNvZ25pdGlvbiwgU3BlZWNoU3RhdGUgfSBmcm9tICcuL2hvb2tzL3VzZVNwZWVjaFJlY29nbml0aW9uJztcbmltcG9ydCB7IFZvaWNlUmVjb2duaXRpb25CYXIsIFZvaWNlUmVjb2duaXRpb25CYXJQcm9wcyB9IGZyb20gJy4vcGxhdGZvcm0vVm9pY2VSZWNvZ25pdGlvbkJhcic7XG5cbi8vIFBsYXRmb3JtIGFic3RyYWN0aW9uIGltcG9ydHNcbmltcG9ydCB7XG4gIFBsYXRmb3JtT3ZlcmxheSxcbiAgUGxhdGZvcm1CdXR0b24sXG4gIExpc3RlbmVyU3RhdGUsXG4gIEZlZWRiYWNrTWVzc2FnZSxcbiAgUGxhdGZvcm1QcmVzc0V2ZW50LFxuICBDb29yZGluYXRlcyxcbiAgZ2V0Q29vcmRpbmF0ZXMsXG59IGZyb20gJy4vcGxhdGZvcm0nO1xuaW1wb3J0IGxvZ2dlciwgeyBjb25maWd1cmVMb2dnZXIsIHR5cGUgTG9nZ2VyUnVudGltZUNvbmZpZyB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7XG4gIGdldFZvaWNlUGlwZWxpbmVUZWxlbWV0cnlCcmlkZ2UsXG4gIHR5cGUgVm9pY2VQaXBlbGluZUhhbmRsZSxcbiAgdHlwZSBWb2ljZVBpcGVsaW5lT3V0Y29tZSxcbiAgdHlwZSBWb2ljZVBpcGVsaW5lU3RhZ2VIYW5kbGUsXG4gIHR5cGUgVm9pY2VQaXBlbGluZVN0YWdlU3RhdHVzLFxufSBmcm9tICcuL3ZvaWNlLXBpcGVsaW5lLXRlbGVtZXRyeSc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFR5cGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmludGVyZmFjZSBNb2RhbGl0eVByb3ZpZGVyUHJvcHMge1xuICBleGFtcGxlcz86IEV4YW1wbGVQYXJzZVtdO1xuICBjbGllbnRTZWNyZXQ6IHN0cmluZztcbiAgYXBpQmFzZVVybD86IHN0cmluZztcbiAgcGFyc2VyQ29uZmlnPzogTmxJbnRlcnByZXRlclBhcnNlckNvbmZpZztcbiAgc3BlZWNoQ29uZmlnPzogU3BlZWNoUmVjb2duaXRpb25Db25maWc7XG4gIC8qKiBPcHRpb25hbCBydW50aW1lIGxvZ2dlciBjb25maWd1cmF0aW9uIG92ZXJyaWRlIHN1cHBsaWVkIGJ5IHRoZSBob3N0IGFwcC4gKi9cbiAgbG9nZ2VyQ29uZmlnPzogTG9nZ2VyUnVudGltZUNvbmZpZztcbiAgLyoqIEN1cnJlbnQgc3BlZWNoIHJlY29nbml0aW9uIGxhbmd1YWdlIChVSS1zZWxlY3RlZCkuICovXG4gIHNwZWVjaExhbmd1YWdlPzogc3RyaW5nO1xuICBsYW5nc21pdGhDb25maWc/OiB7XG4gICAgYXBpS2V5Pzogc3RyaW5nO1xuICAgIHByb2plY3Q/OiBzdHJpbmc7XG4gICAgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIH07XG4gIGRpc3BsYXlUcmFuc2NyaXB0PzogYm9vbGVhbjtcbiAgZXh0cmFQcm9tcHQ/OiBzdHJpbmc7XG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdEVsZW1lbnRbXSB8IFJlYWN0LlJlYWN0RWxlbWVudDtcbiAgLyoqIEN1c3RvbSB2b2ljZSByZWNvZ25pdGlvbiBVSSBjb21wb25lbnQgKGRlZmF1bHQ6IFZvaWNlUmVjb2duaXRpb25CYXIpICovXG4gIFZvaWNlVUlDb21wb25lbnQ/OiBSZWFjdC5Db21wb25lbnRUeXBlPFZvaWNlUmVjb2duaXRpb25CYXJQcm9wcz47XG4gIC8qKiBTaG93IGRlZmF1bHQgZmxvYXRpbmcgbWljIGJ1dHRvbiAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgc2hvd0Zsb2F0aW5nTWljQnV0dG9uPzogYm9vbGVhbjtcbiAgLyoqIEN1c3RvbSBwbGFjZWhvbGRlciB0ZXh0IGZvciB2b2ljZSByZWNvZ25pdGlvbiAqL1xuICB2b2ljZVBsYWNlaG9sZGVyPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUm91dGVQYXJhbXMge1xuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbmludGVyZmFjZSBOYXZpZ2F0aW9uUHJvcHMge1xuICBuYXZpZ2F0aW9uOiBhbnk7XG4gIHJvdXRlPzoge1xuICAgIHBhcmFtcz86IFJvdXRlUGFyYW1zO1xuICB9O1xufVxuXG5pbnRlcmZhY2UgVm9pY2VNZXNzYWdlIGV4dGVuZHMgRmVlZGJhY2tNZXNzYWdlIHtcbiAgdHlwZTogJ2luZm8nIHwgJ2Vycm9yJyB8ICdzdWNjZXNzJyB8ICd3YXJuaW5nJztcbn1cblxuY29uc3QgU1BFRUNIX01JTklNQUxfVEVYVF9MSU1JVCA9IDEyMDtcbmNvbnN0IFZPSUNFX1VJX09DQ0xVU0lPTl9URVNUX0lEID0gJ3JlYWN0Z2VuaWUtdm9pY2UtdWktb2NjbHVzaW9uJztcblxuY29uc3QgdHJ1bmNhdGVUZXh0ID0gKHZhbHVlOiBzdHJpbmcsIG1heExlbmd0aDogbnVtYmVyKSA9PiB7XG4gIGlmICh2YWx1ZS5sZW5ndGggPD0gbWF4TGVuZ3RoKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiBgJHt2YWx1ZS5zbGljZSgwLCBNYXRoLm1heCgwLCBtYXhMZW5ndGggLSAxKSkudHJpbUVuZCgpfeKApmA7XG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBMYW5ndWFnZSBoZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNvbnN0IG5vcm1hbGl6ZUxhbmd1YWdlVGFnID0gKGxhbmc/OiBzdHJpbmcpID0+IHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IChsYW5nIHx8IFwiZW5cIikudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBub3JtYWxpemVkLmxlbmd0aCA+IDAgPyBub3JtYWxpemVkIDogXCJlblwiO1xufTtcblxuY29uc3QgaXNOb0NvbW1hbmRQYXJzZUVycm9yID0gKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gIGlmICghKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IG1lc3NhZ2UgPSAoZXJyb3IubWVzc2FnZSB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKFxuICAgIG1lc3NhZ2UuaW5jbHVkZXMoXCJtaXNzaW5nIGNvbW1hbmRcIikgfHxcbiAgICBtZXNzYWdlLmluY2x1ZGVzKFwic3RydWN0dXJlZCBvdXRwdXQgbWlzc2luZyBjb21tYW5kXCIpXG4gICk7XG59O1xuXG5jb25zdCBERUlDVElDX1JFRkVSRU5DRV9QQVRURVJOID0gL1xcYih0aGlzfGl0fGN1cnJlbnR8c2VsZWN0ZWR8dGhhdClcXGIvaTtcblxuY29uc3QgaXNEZWljdGljUmVmZXJlbmNlVXR0ZXJhbmNlID0gKHV0dGVyYW5jZTogc3RyaW5nKTogYm9vbGVhbiA9PlxuICBERUlDVElDX1JFRkVSRU5DRV9QQVRURVJOLnRlc3QodXR0ZXJhbmNlKTtcblxuY29uc3QgcG9pbnRUb1JlY3REaXN0YW5jZVNxID0gKFxuICBwb2ludFg6IG51bWJlcixcbiAgcG9pbnRZOiBudW1iZXIsXG4gIHJlY3Q6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH1cbikgPT4ge1xuICBjb25zdCBjbG9zZXN0WCA9IE1hdGgubWF4KHJlY3QueCwgTWF0aC5taW4ocG9pbnRYLCByZWN0LnggKyByZWN0LndpZHRoKSk7XG4gIGNvbnN0IGNsb3Nlc3RZID0gTWF0aC5tYXgocmVjdC55LCBNYXRoLm1pbihwb2ludFksIHJlY3QueSArIHJlY3QuaGVpZ2h0KSk7XG4gIHJldHVybiBNYXRoLnBvdyhwb2ludFggLSBjbG9zZXN0WCwgMikgKyBNYXRoLnBvdyhwb2ludFkgLSBjbG9zZXN0WSwgMik7XG59O1xuXG5jb25zdCBwb2ludEluUmVjdCA9IChcbiAgcG9pbnRYOiBudW1iZXIsXG4gIHBvaW50WTogbnVtYmVyLFxuICByZWN0OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9LFxuKTogYm9vbGVhbiA9PlxuICBwb2ludFggPj0gcmVjdC54ICYmXG4gIHBvaW50WCA8PSByZWN0LnggKyByZWN0LndpZHRoICYmXG4gIHBvaW50WSA+PSByZWN0LnkgJiZcbiAgcG9pbnRZIDw9IHJlY3QueSArIHJlY3QuaGVpZ2h0O1xuXG5jb25zdCByZWN0RnJvbURvbUJvdW5kcyA9IChcbiAgcmVjdDogUGljazxET01SZWN0LCBcImxlZnRcIiB8IFwidG9wXCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiIHwgXCJ3aWR0aFwiIHwgXCJoZWlnaHRcIj4sXG4pID0+ICh7XG4gIHg6IHJlY3QubGVmdCxcbiAgeTogcmVjdC50b3AsXG4gIHdpZHRoOiByZWN0LndpZHRoLFxuICBoZWlnaHQ6IHJlY3QuaGVpZ2h0LFxufSk7XG5cbmNvbnN0IGdldFdlYlZvaWNlVWlPY2NsdXNpb25SZWN0ID0gKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICBpZiAocmVjdC53aWR0aCA+IDAgJiYgcmVjdC5oZWlnaHQgPiAwKSB7XG4gICAgcmV0dXJuIHJlY3RGcm9tRG9tQm91bmRzKHJlY3QpO1xuICB9XG5cbiAgbGV0IG1pbkxlZnQgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gIGxldCBtaW5Ub3AgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gIGxldCBtYXhSaWdodCA9IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcbiAgbGV0IG1heEJvdHRvbSA9IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcblxuICBmb3IgKGNvbnN0IGRlc2NlbmRhbnQgb2YgQXJyYXkuZnJvbShlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KFwiKlwiKSkpIHtcbiAgICBjb25zdCBkZXNjZW5kYW50UmVjdCA9IGRlc2NlbmRhbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgaWYgKGRlc2NlbmRhbnRSZWN0LndpZHRoIDw9IDAgfHwgZGVzY2VuZGFudFJlY3QuaGVpZ2h0IDw9IDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBtaW5MZWZ0ID0gTWF0aC5taW4obWluTGVmdCwgZGVzY2VuZGFudFJlY3QubGVmdCk7XG4gICAgbWluVG9wID0gTWF0aC5taW4obWluVG9wLCBkZXNjZW5kYW50UmVjdC50b3ApO1xuICAgIG1heFJpZ2h0ID0gTWF0aC5tYXgobWF4UmlnaHQsIGRlc2NlbmRhbnRSZWN0LnJpZ2h0KTtcbiAgICBtYXhCb3R0b20gPSBNYXRoLm1heChtYXhCb3R0b20sIGRlc2NlbmRhbnRSZWN0LmJvdHRvbSk7XG4gIH1cblxuICBpZiAoXG4gICAgIU51bWJlci5pc0Zpbml0ZShtaW5MZWZ0KSB8fFxuICAgICFOdW1iZXIuaXNGaW5pdGUobWluVG9wKSB8fFxuICAgICFOdW1iZXIuaXNGaW5pdGUobWF4UmlnaHQpIHx8XG4gICAgIU51bWJlci5pc0Zpbml0ZShtYXhCb3R0b20pXG4gICkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IG1pbkxlZnQsXG4gICAgeTogbWluVG9wLFxuICAgIHdpZHRoOiBtYXhSaWdodCAtIG1pbkxlZnQsXG4gICAgaGVpZ2h0OiBtYXhCb3R0b20gLSBtaW5Ub3AsXG4gIH07XG59O1xuXG5jb25zdCByZXNvbHZlVGFwQ2xhc3NOYW1lID0gKFxuICBpbnRlcmZhY2VzOiBBcnJheTx7IGNsYXNzTmFtZTogc3RyaW5nOyByZWN0OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9IH0+LFxuICB0YXA/OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH1cbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmICghdGFwIHx8IGludGVyZmFjZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxldCBuZWFyZXN0ID0gaW50ZXJmYWNlc1swXTtcbiAgbGV0IG5lYXJlc3REaXN0YW5jZSA9IHBvaW50VG9SZWN0RGlzdGFuY2VTcSh0YXAueCwgdGFwLnksIG5lYXJlc3QucmVjdCk7XG5cbiAgZm9yIChsZXQgaW5kZXggPSAxOyBpbmRleCA8IGludGVyZmFjZXMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gaW50ZXJmYWNlc1tpbmRleF07XG4gICAgY29uc3QgZGlzdGFuY2UgPSBwb2ludFRvUmVjdERpc3RhbmNlU3EodGFwLngsIHRhcC55LCBjYW5kaWRhdGUucmVjdCk7XG4gICAgaWYgKGRpc3RhbmNlIDwgbmVhcmVzdERpc3RhbmNlKSB7XG4gICAgICBuZWFyZXN0ID0gY2FuZGlkYXRlO1xuICAgICAgbmVhcmVzdERpc3RhbmNlID0gZGlzdGFuY2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5lYXJlc3Q/LmNsYXNzTmFtZTtcbn07XG5cbmNvbnN0IGFwcGx5UnVudGltZVVpQ29udGV4dCA9IChcbiAgaW50ZXJwcmV0ZXI6IE5sSW50ZXJwcmV0ZXIsXG4gIGNvbnRleHQ6IFJ1bnRpbWVVaUNvbnRleHQgfCBudWxsXG4pID0+IHtcbiAgY29uc3QgbWF5YmVSdW50aW1lQ29udGV4dFNldHRlciA9XG4gICAgaW50ZXJwcmV0ZXIgYXMgdW5rbm93biBhcyBzZXRJbnRlcnByZXRlclJ1bnRpbWVVaUNvbnRleHQ7XG4gIG1heWJlUnVudGltZUNvbnRleHRTZXR0ZXIuc2V0UnVudGltZUNvbnRleHQ/Lihjb250ZXh0KTtcbn07XG5cbmNsYXNzIFZpc2liaWxpdHlUcmFuc2l0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdWaXNpYmlsaXR5VHJhbnNpdGlvbkVycm9yJztcbiAgfVxufVxuXG5jb25zdCB3YWl0Rm9yTXMgPSAobXM6IG51bWJlcikgPT5cbiAgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKTtcbiAgfSk7XG5cbmNvbnN0IHdhaXRGb3JTdGFibGVJbnRlcmZhY2VTbmFwc2hvdCA9IGFzeW5jIChcbiAgdGltZW91dE1zID0gNDUwLFxuICBwb2xsSW50ZXJ2YWxNcyA9IDE2LFxuKSA9PiB7XG4gIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIHRpbWVvdXRNcztcbiAgbGV0IHNuYXBzaG90ID0gUmV0cmlldmVJbnRlcmZhY2VzU25hcHNob3QoKTtcblxuICB3aGlsZSAoXG4gICAgc25hcHNob3QudmlzaWJpbGl0eVN0YXRlID09PSBcInRyYW5zaXRpb25fdW5zdGFibGVcIiAmJlxuICAgIERhdGUubm93KCkgPCBkZWFkbGluZVxuICApIHtcbiAgICBhd2FpdCB3YWl0Rm9yTXMocG9sbEludGVydmFsTXMpO1xuICAgIHNuYXBzaG90ID0gUmV0cmlldmVJbnRlcmZhY2VzU25hcHNob3QoKTtcbiAgfVxuXG4gIHJldHVybiBzbmFwc2hvdDtcbn07XG5cbnR5cGUgSW50ZXJwcmV0ZXJUdXJuUmVjb3JkID0ge1xuICB1dHRlcmFuY2U6IHN0cmluZztcbiAgcGFyc2VkPzogc3RyaW5nIHwgbnVsbDtcbiAgc3VjY2VzczogYm9vbGVhbjtcbiAgcmVzdWx0U3VtbWFyeT86IHN0cmluZztcbn07XG5cbnR5cGUgSW50ZXJwcmV0ZXJUdXJuUmVjb3JkZXIgPSB7XG4gIHJlY29yZFR1cm4/OiAocmVjb3JkOiBJbnRlcnByZXRlclR1cm5SZWNvcmQpID0+IHZvaWQ7XG4gIHJlY29yZEludGVyYWN0aW9uPzogKHJlY29yZDogSW50ZXJwcmV0ZXJUdXJuUmVjb3JkKSA9PiB2b2lkO1xufTtcblxuY29uc3QgcmVjb3JkSW50ZXJwcmV0ZXJUdXJuID0gKFxuICBpbnRlcnByZXRlcjogTmxJbnRlcnByZXRlcixcbiAgcmVjb3JkOiBJbnRlcnByZXRlclR1cm5SZWNvcmRcbikgPT4ge1xuICBjb25zdCBtYXliZVR1cm5SZWNvcmRlciA9IGludGVycHJldGVyIGFzIHVua25vd24gYXMgSW50ZXJwcmV0ZXJUdXJuUmVjb3JkZXI7XG4gIGlmICh0eXBlb2YgbWF5YmVUdXJuUmVjb3JkZXIucmVjb3JkVHVybiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgbWF5YmVUdXJuUmVjb3JkZXIucmVjb3JkVHVybihyZWNvcmQpO1xuICAgIHJldHVybjtcbiAgfVxuICBtYXliZVR1cm5SZWNvcmRlci5yZWNvcmRJbnRlcmFjdGlvbj8uKHJlY29yZCk7XG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBOYXZpZ2F0aW9uIFNldHVwXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNvbnN0IFN0YWNrID0gY3JlYXRlU3RhY2tOYXZpZ2F0b3IoKTtcbmV4cG9ydCBsZXQgR2VuaWVJbnRlcnByZXRlcjogTmxJbnRlcnByZXRlcjtcblxuY29uc3QgY2FyZFN0eWxlOiBTdGFja05hdmlnYXRpb25PcHRpb25zID0ge1xuICBwcmVzZW50YXRpb246ICdjYXJkJyxcbiAgaGVhZGVyU3R5bGVJbnRlcnBvbGF0b3I6IEhlYWRlclN0eWxlSW50ZXJwb2xhdG9ycy5mb3JVSUtpdCxcbiAgY2FyZFN0eWxlSW50ZXJwb2xhdG9yOiBDYXJkU3R5bGVJbnRlcnBvbGF0b3JzLmZvckhvcml6b250YWxJT1MsXG59O1xuXG4vKipcbiAqIERlZmF1bHQgc2NyZWVuIHdyYXBwZXIgLSByZW5kZXJzIGNoaWxkcmVuIHdpdGggaGlkZGVuIGhlYWRlclxuICovXG5jb25zdCBEZWZhdWx0U2NyZWVuID1cbiAgKGNoaWxkcmVuOiBSZWFjdC5SZWFjdEVsZW1lbnQgfCBSZWFjdC5SZWFjdEVsZW1lbnRbXSkgPT5cbiAgKHsgbmF2aWdhdGlvbiB9OiBOYXZpZ2F0aW9uUHJvcHMpID0+IHtcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgbmF2aWdhdGlvbi5zZXRPcHRpb25zKHsgaGVhZGVyU2hvd246IGZhbHNlIH0pO1xuICAgIH0sIFtuYXZpZ2F0aW9uXSk7XG4gICAgcmV0dXJuIDw+e2NoaWxkcmVufTwvPjtcbiAgfTtcblxuLyoqXG4gKiBPYmplY3QgaW50ZXJmYWNlIHNjcmVlbiB3cmFwcGVyIC0gcmVuZGVycyBnZW5pZSBvYmplY3RzIHdpdGggbmF2aWdhdGlvblxuICovXG5jb25zdCBPYmplY3RJbnRlcmZhY2VTY3JlZW4gPVxuICAoZ2VuaWVJbnRlcmZhY2VTdG9yZUVsZW1lbnQ6IEdlbmllSW50ZXJmYWNlU3RvcmVFbGVtZW50KSA9PlxuICAoeyByb3V0ZSwgbmF2aWdhdGlvbiB9OiBOYXZpZ2F0aW9uUHJvcHMpID0+IHtcbiAgICBjb25zdCBwYXJhbXMgPSByb3V0ZT8ucGFyYW1zIHx8IHt9O1xuICAgIGNvbnN0IHRpdGxlID0gZ2VuaWVJbnRlcmZhY2VTdG9yZUVsZW1lbnQudGl0bGUocGFyYW1zKTtcbiAgICBcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgbmF2aWdhdGlvbi5zZXRPcHRpb25zKHtcbiAgICAgICAgaGVhZGVyU2hvd246IHRydWUsXG4gICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgIH0pO1xuICAgIH0sIFtuYXZpZ2F0aW9uLCB0aXRsZV0pO1xuICAgIFxuICAgIHJldHVybiA8Z2VuaWVJbnRlcmZhY2VTdG9yZUVsZW1lbnQuZnVuY3Rpb24gey4uLnBhcmFtc30gLz47XG4gIH07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIE1haW4gQ29tcG9uZW50XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmV4cG9ydCBjb25zdCBNb2RhbGl0eVByb3ZpZGVyOiBSZWFjdC5GQzxNb2RhbGl0eVByb3ZpZGVyUHJvcHM+ID0gKHtcbiAgZXhhbXBsZXM6IHByb3BzRXhhbXBsZXMsXG4gIGNsaWVudFNlY3JldCxcbiAgYXBpQmFzZVVybCxcbiAgcGFyc2VyQ29uZmlnLFxuICBzcGVlY2hDb25maWcsXG4gIGxvZ2dlckNvbmZpZyxcbiAgc3BlZWNoTGFuZ3VhZ2UsXG4gIGxhbmdzbWl0aENvbmZpZyxcbiAgZGlzcGxheVRyYW5zY3JpcHQgPSBmYWxzZSxcbiAgZXh0cmFQcm9tcHQgPSAnJyxcbiAgY2hpbGRyZW4sXG4gIFZvaWNlVUlDb21wb25lbnQgPSBWb2ljZVJlY29nbml0aW9uQmFyLFxuICBzaG93RmxvYXRpbmdNaWNCdXR0b24gPSB0cnVlLFxuICB2b2ljZVBsYWNlaG9sZGVyLFxufSkgPT4ge1xuICBjb25zdCByZXNvbHZlZFByb3h5QmFzZVVybCA9IGFwaUJhc2VVcmw7XG5cbiAgLy8gPT09PT09PT09PSBTcGVlY2ggUmVjb2duaXRpb24gSG9vayA9PT09PT09PT09XG4gIGNvbnN0IHNwZWVjaFJlY29nbml0aW9uID0gdXNlU3BlZWNoUmVjb2duaXRpb24oKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChsb2dnZXJDb25maWcpIHtcbiAgICAgIGNvbmZpZ3VyZUxvZ2dlcihsb2dnZXJDb25maWcpO1xuICAgIH1cbiAgfSwgW2xvZ2dlckNvbmZpZ10pO1xuICBcbiAgLy8gPT09PT09PT09PSBMZWdhY3kgU3RhdGUgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KSA9PT09PT09PT09XG4gIGNvbnN0IFtpc1ByZXNzZWQsIHNldElzUHJlc3NlZF0gPSB1c2VTdGF0ZTxib29sZWFuPihmYWxzZSk7XG4gIGNvbnN0IFtpc09wZW5BSVNwZWVjaFJlYWR5LCBzZXRJc09wZW5BSVNwZWVjaFJlYWR5XSA9IHVzZVN0YXRlPGJvb2xlYW4+KHRydWUpO1xuXG4gIC8vID09PT09PT09PT0gU2VsZWN0b3JzID09PT09PT09PT1cbiAgY29uc3QgZXhhbXBsZXMgPSB1c2VHZW5pZVNlbGVjdG9yKCgpID0+IHtcbiAgICBjb25zdCBzaGFyZWRFeGFtcGxlcyA9IHNoYXJlZFN0YXRlWydfX0VYQU1QTEVTX18nXSB8fCBbXTtcbiAgICBpZiAocHJvcHNFeGFtcGxlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gc2hhcmVkRXhhbXBsZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbLi4ucHJvcHNFeGFtcGxlcywgLi4uc2hhcmVkRXhhbXBsZXNdO1xuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgbmF2U3RhdGU6IE5hdmlnYXRvclN0YXRlID0gdXNlU2VsZWN0b3IoKHN0YXRlOiBhbnkpID0+IHN0YXRlLm5hdlN0YXRlKTtcbiAgY29uc3QgbmF2U3RhY2sgPSB1c2VTZWxlY3Rvcigoc3RhdGU6IGFueSkgPT4gc3RhdGUubmF2U3RhY2spO1xuICBjb25zdCB2b2ljZU1lc3NhZ2U6IFZvaWNlTWVzc2FnZSA9IHVzZVNlbGVjdG9yKChzdGF0ZTogYW55KSA9PiBzdGF0ZS5tZXNzYWdlKTtcbiAgY29uc3QgcmVzb2x2ZWRTcGVlY2hMYW5ndWFnZSA9IG5vcm1hbGl6ZUxhbmd1YWdlVGFnKHNwZWVjaExhbmd1YWdlKTtcbiAgY29uc3QgcmVzb2x2ZWRTcGVlY2hDb25maWcgPSB1c2VNZW1vKFxuICAgICgpID0+IGdldFNwZWVjaFJlY29nbml0aW9uQ29uZmlnKHNwZWVjaENvbmZpZyksXG4gICAgW3NwZWVjaENvbmZpZ11cbiAgKTtcbiAgY29uc3QgbGFuZ3NtaXRoQXBpS2V5ID0gbGFuZ3NtaXRoQ29uZmlnPy5hcGlLZXk7XG4gIGNvbnN0IGxhbmdzbWl0aFByb2plY3QgPSBsYW5nc21pdGhDb25maWc/LnByb2plY3Q7XG4gIGNvbnN0IGxhbmdzbWl0aEVuZHBvaW50ID0gbGFuZ3NtaXRoQ29uZmlnPy5lbmRwb2ludDtcbiAgY29uc3QgaXNPcGVuQUlBdXRvU3RvcEVuYWJsZWQgPVxuICAgIHJlc29sdmVkU3BlZWNoQ29uZmlnLnByb3ZpZGVyID09PSBcIm9wZW5haVwiICYmXG4gICAgISFyZXNvbHZlZFNwZWVjaENvbmZpZy5vcGVuYWk/LmF1dG9TdG9wT25WYWRTaWxlbmNlO1xuICBjb25zdCBpc09wZW5BSVByb3ZpZGVyID0gcmVzb2x2ZWRTcGVlY2hDb25maWcucHJvdmlkZXIgPT09IFwib3BlbmFpXCI7XG5cbiAgLy8gPT09PT09PT09PSBSZWZzID09PT09PT09PT1cbiAgY29uc3QgbmF2aWdhdGlvblJlZiA9IHVzZU5hdmlnYXRpb25Db250YWluZXJSZWYoKTtcbiAgY29uc3QgbGFzdFRyYW5zY3JpcHRSZWYgPSBSZWFjdC51c2VSZWY8c3RyaW5nPignJyk7XG4gIGNvbnN0IGxhdGVzdFRyYW5zY3JpcHRSZWYgPSBSZWFjdC51c2VSZWY8c3RyaW5nPignJyk7XG4gIGNvbnN0IGxhdGVzdFRyYW5zbGF0aW9uUmVmID0gUmVhY3QudXNlUmVmPHN0cmluZz4oJycpO1xuICBjb25zdCBpc1Byb2Nlc3NpbmdUcmFuc2NyaXB0UmVmID0gUmVhY3QudXNlUmVmPGJvb2xlYW4+KGZhbHNlKTtcbiAgY29uc3QgYWN0aXZlU2Vzc2lvbklkUmVmID0gUmVhY3QudXNlUmVmPG51bWJlcj4oMCk7XG4gIGNvbnN0IGZpbmFsaXplZFNlc3Npb25JZFJlZiA9IFJlYWN0LnVzZVJlZjxudW1iZXI+KC0xKTtcbiAgY29uc3QgYWN0aXZlVGhyZWFkSWRSZWYgPSBSZWFjdC51c2VSZWY8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGFjdGl2ZVR1cm5JZFJlZiA9IFJlYWN0LnVzZVJlZjxzdHJpbmcgfCBudWxsPihudWxsKTtcbiAgY29uc3QgYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYgPSBSZWFjdC51c2VSZWY8Ym9vbGVhbj4oZmFsc2UpO1xuICBjb25zdCBhd2FpdGluZ0xhdGVGaW5hbEFmdGVyUGF1c2VSZWYgPSBSZWFjdC51c2VSZWY8Ym9vbGVhbj4oZmFsc2UpO1xuICBjb25zdCBsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmID0gUmVhY3QudXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHNwZWVjaFJlc3BvbnNlVGltZW91dFJlZiA9IFJlYWN0LnVzZVJlZjxSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGw+KG51bGwpO1xuICBjb25zdCBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmID0gUmVhY3QudXNlUmVmPFZvaWNlUGlwZWxpbmVIYW5kbGUgfCBudWxsPihudWxsKTtcbiAgY29uc3QgYWN0aXZlTGlzdGVuaW5nU3RhZ2VSZWYgPSBSZWFjdC51c2VSZWY8Vm9pY2VQaXBlbGluZVN0YWdlSGFuZGxlIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGFjdGl2ZVByb2Nlc3NpbmdTdGFnZVJlZiA9IFJlYWN0LnVzZVJlZjxWb2ljZVBpcGVsaW5lU3RhZ2VIYW5kbGUgfCBudWxsPihudWxsKTtcbiAgY29uc3QgZGlzcGxheU91dGNvbWVSZWYgPSBSZWFjdC51c2VSZWY8J3JlbmRlcmVkJyB8ICdza2lwcGVkX2ludGVudGlvbmFsJyB8ICdub3RfYXBwbGljYWJsZSc+KFxuICAgICdub3RfYXBwbGljYWJsZSdcbiAgKTtcbiAgY29uc3QgbmF2U3RhY2tSZWYgPSBSZWFjdC51c2VSZWY8bnVtYmVyPigwKTtcbiAgY29uc3Qgd2ViU3BlZWNoVXR0ZXJhbmNlUmVmID0gUmVhY3QudXNlUmVmPGFueT4obnVsbCk7XG4gIGNvbnN0IHRvdWNoU3RhcnRQb2ludFJlZiA9IFJlYWN0LnVzZVJlZjx7IHg6IG51bWJlcjsgeTogbnVtYmVyOyBhdDogbnVtYmVyIH0gfCBudWxsPihudWxsKTtcbiAgY29uc3QgYmxvY2tlZE92ZXJsYXlUYXBSZWYgPSBSZWFjdC51c2VSZWY8Ym9vbGVhbj4oZmFsc2UpO1xuICBjb25zdCBoYW5kbGVNaWNyb3Bob25lUHJlc3NSZWYgPSBSZWFjdC51c2VSZWY8KCgpID0+IHZvaWQpIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHZvaWNlVWlMYXlvdXRSZWN0UmVmID0gUmVhY3QudXNlUmVmPFxuICAgIHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gfCBudWxsXG4gID4obnVsbCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBuYXZTdGFja1JlZi5jdXJyZW50ID0gbmF2U3RhY2s7XG4gIH0sIFtuYXZTdGFja10pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFpc09wZW5BSVByb3ZpZGVyKSB7XG4gICAgICBzZXRJc09wZW5BSVNwZWVjaFJlYWR5KHRydWUpO1xuICAgIH1cbiAgfSwgW2lzT3BlbkFJUHJvdmlkZXJdKTtcblxuICBjb25zdCByZXNvbHZlZFBhcnNlckNvbmZpZyA9IHVzZU1lbW88TmxJbnRlcnByZXRlclBhcnNlckNvbmZpZz4oXG4gICAgKCkgPT4gKHtcbiAgICAgIHByb3ZpZGVyOiBwYXJzZXJDb25maWc/LnByb3ZpZGVyLFxuICAgICAgZ3JvcToge1xuICAgICAgICAuLi4ocGFyc2VyQ29uZmlnPy5ncm9xIHx8IHt9KSxcbiAgICAgICAgYmFzZVVybDogcGFyc2VyQ29uZmlnPy5ncm9xPy5iYXNlVXJsIHx8IHJlc29sdmVkUHJveHlCYXNlVXJsLFxuICAgICAgfSxcbiAgICAgIG9wZW5haToge1xuICAgICAgICAuLi4ocGFyc2VyQ29uZmlnPy5vcGVuYWkgfHwge30pLFxuICAgICAgICBiYXNlVXJsOiBwYXJzZXJDb25maWc/Lm9wZW5haT8uYmFzZVVybCB8fCByZXNvbHZlZFByb3h5QmFzZVVybCxcbiAgICAgIH0sXG4gICAgfSksXG4gICAgW3BhcnNlckNvbmZpZywgcmVzb2x2ZWRQcm94eUJhc2VVcmxdXG4gICk7XG5cbiAgLy8gPT09PT09PT09PSBJbml0aWFsaXplIEdlbmllIEludGVycHJldGVyID09PT09PT09PT1cbiAgR2VuaWVJbnRlcnByZXRlciA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IGRlc2NyaXB0b3JzOiBDbGFzc0Rlc2NyaXB0b3I8R2VuaWVPYmplY3Q+W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBBbGxHZW5pZU9iamVjdHMpIHtcbiAgICAgIGRlc2NyaXB0b3JzLnB1c2goQWxsR2VuaWVPYmplY3RzW2tleV0uQ2xhc3NEZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBObEludGVycHJldGVyKFxuICAgICAgZGVzY3JpcHRvcnMsXG4gICAgICBjbGllbnRTZWNyZXQsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBleGFtcGxlcyxcbiAgICAgIGV4dHJhUHJvbXB0LFxuICAgICAge1xuICAgICAgICBwYXJzZXI6IHJlc29sdmVkUGFyc2VyQ29uZmlnLFxuICAgICAgICBtb25pdG9yaW5nOiB7XG4gICAgICAgICAgbGFuZ3NtaXRoQXBpS2V5LFxuICAgICAgICAgIGxhbmdzbWl0aFByb2plY3QsXG4gICAgICAgICAgbGFuZ3NtaXRoRW5kcG9pbnQsXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfVxuICAgICk7XG4gIH0sIFtcbiAgICBjbGllbnRTZWNyZXQsXG4gICAgZXhhbXBsZXMsXG4gICAgZXh0cmFQcm9tcHQsXG4gICAgcmVzb2x2ZWRQYXJzZXJDb25maWcsXG4gICAgbGFuZ3NtaXRoQXBpS2V5LFxuICAgIGxhbmdzbWl0aFByb2plY3QsXG4gICAgbGFuZ3NtaXRoRW5kcG9pbnQsXG4gIF0pO1xuXG4gIC8vID09PT09PT09PT0gVUkgTGlzdCAoTmF2aWdhdGlvbiBTY3JlZW5zKSA9PT09PT09PT09XG4gIGNvbnN0IHVpTGlzdCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IGFsbEludGVyZmFjZXMgPSBBbGxHZW5pZU9iamVjdEludGVyZmFjZXMuYWxsSW50ZXJmYWNlcygpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhhbGxJbnRlcmZhY2VzKS5tYXAoKGtleSkgPT4ge1xuICAgICAgY29uc3QgaW50ZXJmYWNlU3RvcmVFbGVtZW50ID0gYWxsSW50ZXJmYWNlc1trZXldO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPFN0YWNrLlNjcmVlblxuICAgICAgICAgIG5hbWU9e2tleX1cbiAgICAgICAgICBjb21wb25lbnQ9e09iamVjdEludGVyZmFjZVNjcmVlbihpbnRlcmZhY2VTdG9yZUVsZW1lbnQpfVxuICAgICAgICAgIG9wdGlvbnM9e2NhcmRTdHlsZX1cbiAgICAgICAgLz5cbiAgICAgICk7XG4gICAgfSk7XG4gIH0sIFtdKTtcblxuICAvLyA9PT09PT09PT09IEdVSSBTdHJ1Y3R1cmUgPT09PT09PT09PVxuICBjb25zdCBndWkgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAvLyBJZiB1c2luZyBleHBvLXJvdXRlciwgc2tpcCBOYXZpZ2F0aW9uQ29udGFpbmVyIChpdCdzIHByb3ZpZGVkIGJ5IGV4cG8tcm91dGVyKVxuICAgIGlmIChpc0V4cG9Sb3V0ZXIoKSkge1xuICAgICAgLy8gSW4gZXhwby1yb3V0ZXIsIGNvbXBvbmVudHMgYXJlIHJlbmRlcmVkIGRpcmVjdGx5IHdpdGhvdXQgTmF2aWdhdGlvbkNvbnRhaW5lclxuICAgICAgLy8gVGhlIG5hdmlnYXRpb24gc3RydWN0dXJlIGlzIGZpbGUtYmFzZWRcbiAgICAgIHJldHVybiA8PntjaGlsZHJlbn08Lz47XG4gICAgfVxuICAgIFxuICAgIC8vIFRyYWRpdGlvbmFsIHJlYWN0LW5hdmlnYXRpb24gc2V0dXBcbiAgICByZXR1cm4gKFxuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIFJlYWN0IE5hdmlnYXRpb24gdjcgdHlwZXMgYXJlIG92ZXJseSBzdHJpY3Qgd2l0aCBSZWFjdCAxOTsgY2hpbGRyZW4gYXJlIHByb3Blcmx5IHByb3ZpZGVkIGJlbG93XG4gICAgICA8TmF2aWdhdGlvbkNvbnRhaW5lciByZWY9e25hdmlnYXRpb25SZWZ9PlxuICAgICAgICB7LyogQHRzLWV4cGVjdC1lcnJvciAtIFR5cGVTY3JpcHQgY2FuJ3QgaW5mZXIgY2hpbGRyZW4gZnJvbSBKU1gsIGJ1dCB0aGV5J3JlIHByb3ZpZGVkIGNvcnJlY3RseSAqL31cbiAgICAgICAgPFN0YWNrLk5hdmlnYXRvciBpbml0aWFsUm91dGVOYW1lPVwiRGVmYXVsdCBHVUlcIj5cbiAgICAgICAgICA8U3RhY2suU2NyZWVuXG4gICAgICAgICAgICBuYW1lPVwiRGVmYXVsdCBHVUlcIlxuICAgICAgICAgICAgY29tcG9uZW50PXtEZWZhdWx0U2NyZWVuKGNoaWxkcmVuKX1cbiAgICAgICAgICAgIG9wdGlvbnM9e2NhcmRTdHlsZX1cbiAgICAgICAgICAvPlxuICAgICAgICAgIHt1aUxpc3R9XG4gICAgICAgIDwvU3RhY2suTmF2aWdhdG9yPlxuICAgICAgPC9OYXZpZ2F0aW9uQ29udGFpbmVyPlxuICAgICk7XG4gIH0sIFtuYXZpZ2F0aW9uUmVmLCB1aUxpc3QsIGNoaWxkcmVuXSk7XG5cbiAgLy8gPT09PT09PT09PSBFZmZlY3RzID09PT09PT09PT1cblxuICAvLyBIYW5kbGUgbmF2aWdhdGlvbiBzdGF0ZSBjaGFuZ2VzXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gY29uc29sZS5sb2coJ25hdiBzdGF0ZSBjaGFuZ2VkJywgbmF2U3RhdGUpO1xuICAgIGlmIChuYXZTdGF0ZS5vYmplY3RWaWV3Q2xhc3NOYW1lICE9PSBudWxsKSB7XG4gICAgICBpZiAoaXNFeHBvUm91dGVyKCkpIHtcbiAgICAgICAgLy8gRm9yIGV4cG8tcm91dGVyLCB1c2UgZHluYW1pYyByb3V0aW5nXG4gICAgICAgIC8vIFRoaXMgcmVxdWlyZXMgZXhwby1yb3V0ZXIgdG8gYmUgc2V0IHVwIHdpdGggZHluYW1pYyByb3V0ZXNcbiAgICAgICAgbG9nZ2VyLndhcm4oJ2V4cG8tcm91dGVyIG5hdmlnYXRpb24gcmVxdWlyZXMgbWFudWFsIHJvdXRlIHNldHVwJyk7XG4gICAgICAgIC8vIFVzZXIgbmVlZHMgdG8gY3JlYXRlIGR5bmFtaWMgcm91dGVzIGluIHRoZWlyIGFwcCBkaXJlY3RvcnlcbiAgICAgIH0gZWxzZSBpZiAobmF2aWdhdGlvblJlZi5pc1JlYWR5KCkpIHtcbiAgICAgICAgLy8gVHJhZGl0aW9uYWwgbmF2aWdhdGlvblxuICAgICAgICBuYXZpZ2F0aW9uUmVmLmRpc3BhdGNoKFxuICAgICAgICAgIFN0YWNrQWN0aW9ucy5wdXNoKFxuICAgICAgICAgICAgbmF2U3RhdGUub2JqZWN0Vmlld0NsYXNzTmFtZSxcbiAgICAgICAgICAgIG5hdlN0YXRlLm9iamVjdENvbnN0cnVjdG9yUGFyYW1zXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSwgW25hdlN0YWNrLCBuYXZTdGF0ZSwgbmF2aWdhdGlvblJlZl0pO1xuXG4gIGNvbnN0IGxpc3RlbmVyU3RhdGUgPVxuICAgIHNwZWVjaFJlY29nbml0aW9uLnN0YXRlID09PSBTcGVlY2hTdGF0ZS5MaXN0ZW5pbmdcbiAgICAgID8gTGlzdGVuZXJTdGF0ZS5MaXN0ZW5pbmdcbiAgICAgIDogc3BlZWNoUmVjb2duaXRpb24uc3RhdGUgPT09IFNwZWVjaFN0YXRlLlByb2Nlc3NpbmdcbiAgICAgICAgPyBMaXN0ZW5lclN0YXRlLlByb2Nlc3NpbmdcbiAgICAgICAgOiBMaXN0ZW5lclN0YXRlLklkbGU7XG4gIGNvbnN0IGlzQ29ubmVjdGluZyA9XG4gICAgaXNPcGVuQUlQcm92aWRlciAmJlxuICAgIHNwZWVjaFJlY29nbml0aW9uLnN0YXRlID09PSBTcGVlY2hTdGF0ZS5MaXN0ZW5pbmcgJiZcbiAgICAhc3BlZWNoUmVjb2duaXRpb24uaXNQcm9jZXNzaW5nICYmXG4gICAgIWlzT3BlbkFJU3BlZWNoUmVhZHk7XG4gIGNvbnN0IGlzTGlzdGVuaW5nRm9yVWkgPVxuICAgIHNwZWVjaFJlY29nbml0aW9uLnN0YXRlID09PSBTcGVlY2hTdGF0ZS5MaXN0ZW5pbmcgJiYgIWlzQ29ubmVjdGluZztcblxuICBjb25zdCBzZXRTZWxlY3Rpb25CbG9ja2VkUmVjdHMgPSB1c2VDYWxsYmFjayhcbiAgICAocmVjdHM6IEFycmF5PHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0+KSA9PiB7XG4gICAgICBDdXJyZW50U2VsZWN0aW9uQmxvY2tlZFJlY3RzLnNwbGljZSgwLCBDdXJyZW50U2VsZWN0aW9uQmxvY2tlZFJlY3RzLmxlbmd0aCk7XG4gICAgICByZWN0cy5mb3JFYWNoKChyZWN0KSA9PiB7XG4gICAgICAgIGlmIChyZWN0LndpZHRoIDw9IDAgfHwgcmVjdC5oZWlnaHQgPD0gMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBDdXJyZW50U2VsZWN0aW9uQmxvY2tlZFJlY3RzLnB1c2gocmVjdCk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIFtdLFxuICApO1xuXG4gIGNvbnN0IHBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0ID0gdXNlQ2FsbGJhY2soKHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiA9PiB7XG4gICAgZm9yIChjb25zdCByZWN0IG9mIEN1cnJlbnRTZWxlY3Rpb25CbG9ja2VkUmVjdHMpIHtcbiAgICAgIGlmIChwb2ludEluUmVjdCh4LCB5LCByZWN0KSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LCBbXSk7XG5cbiAgY29uc3QgZ2V0TGF0ZXN0VW5ibG9ja2VkVGFwID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IHRhcHMgPSBDbGlja1BvaW50cyA/PyBbXTtcbiAgICBmb3IgKGxldCBpbmRleCA9IHRhcHMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXggLT0gMSkge1xuICAgICAgY29uc3QgdGFwID0gdGFwc1tpbmRleF07XG4gICAgICBpZiAoIXBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0KHRhcC54LCB0YXAueSkpIHtcbiAgICAgICAgcmV0dXJuIHRhcDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSwgW3BvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0XSk7XG5cbiAgY29uc3QgdXBkYXRlVm9pY2VVaUJsb2NrZWRSZWN0cyA9IHVzZUNhbGxiYWNrKFxuICAgIChmYWxsYmFja1JlY3Q/OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9KSA9PiB7XG4gICAgICBjb25zdCBhcHBseVJlY3QgPSAocmVjdD86IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0pID0+IHtcbiAgICAgICAgaWYgKCFyZWN0IHx8IHJlY3Qud2lkdGggPD0gMCB8fCByZWN0LmhlaWdodCA8PSAwKSB7XG4gICAgICAgICAgc2V0U2VsZWN0aW9uQmxvY2tlZFJlY3RzKFtdKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2V0U2VsZWN0aW9uQmxvY2tlZFJlY3RzKFtyZWN0XSk7XG4gICAgICB9O1xuXG4gICAgICBpZiAoUGxhdGZvcm0uT1MgPT09ICd3ZWInICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgYFtkYXRhLXRlc3RpZD1cIiR7Vk9JQ0VfVUlfT0NDTFVTSU9OX1RFU1RfSUR9XCJdYCxcbiAgICAgICAgKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgYXBwbHlSZWN0KGdldFdlYlZvaWNlVWlPY2NsdXNpb25SZWN0KGVsZW1lbnQpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXBwbHlSZWN0KGZhbGxiYWNrUmVjdCA/PyB2b2ljZVVpTGF5b3V0UmVjdFJlZi5jdXJyZW50ID8/IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBbc2V0U2VsZWN0aW9uQmxvY2tlZFJlY3RzXSxcbiAgKTtcblxuICBjb25zdCBoYW5kbGVWb2ljZVVpTGF5b3V0ID0gdXNlQ2FsbGJhY2soXG4gICAgKGV2ZW50OiBMYXlvdXRDaGFuZ2VFdmVudCkgPT4ge1xuICAgICAgY29uc3QgeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0gPSBldmVudC5uYXRpdmVFdmVudC5sYXlvdXQ7XG4gICAgICBjb25zdCBsYXlvdXRSZWN0ID0geyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH07XG4gICAgICB2b2ljZVVpTGF5b3V0UmVjdFJlZi5jdXJyZW50ID0gbGF5b3V0UmVjdDtcbiAgICAgIHVwZGF0ZVZvaWNlVWlCbG9ja2VkUmVjdHMobGF5b3V0UmVjdCk7XG4gICAgfSxcbiAgICBbdXBkYXRlVm9pY2VVaUJsb2NrZWRSZWN0c10sXG4gICk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCB2b2ljZVVpVmlzaWJsZSA9XG4gICAgICBpc0xpc3RlbmluZ0ZvclVpIHx8XG4gICAgICBzcGVlY2hSZWNvZ25pdGlvbi5pc1Byb2Nlc3NpbmcgfHxcbiAgICAgIGlzQ29ubmVjdGluZyB8fFxuICAgICAgKGRpc3BsYXlUcmFuc2NyaXB0ICYmXG4gICAgICAgIChzcGVlY2hSZWNvZ25pdGlvbi5pbnRlcmltVHJhbnNjcmlwdC50cmltKCkubGVuZ3RoID4gMCB8fFxuICAgICAgICAgIHNwZWVjaFJlY29nbml0aW9uLnRyYW5zY3JpcHQudHJpbSgpLmxlbmd0aCA+IDApKTtcblxuICAgIGlmICghdm9pY2VVaVZpc2libGUpIHtcbiAgICAgIHNldFNlbGVjdGlvbkJsb2NrZWRSZWN0cyhbXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmFmSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdXBkYXRlVm9pY2VVaUJsb2NrZWRSZWN0cygpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZklkKTtcbiAgICB9O1xuICB9LCBbXG4gICAgZGlzcGxheVRyYW5zY3JpcHQsXG4gICAgaXNDb25uZWN0aW5nLFxuICAgIGlzTGlzdGVuaW5nRm9yVWksXG4gICAgc2V0U2VsZWN0aW9uQmxvY2tlZFJlY3RzLFxuICAgIHNwZWVjaFJlY29nbml0aW9uLmludGVyaW1UcmFuc2NyaXB0LFxuICAgIHNwZWVjaFJlY29nbml0aW9uLmlzUHJvY2Vzc2luZyxcbiAgICBzcGVlY2hSZWNvZ25pdGlvbi50cmFuc2NyaXB0LFxuICAgIHVwZGF0ZVZvaWNlVWlCbG9ja2VkUmVjdHMsXG4gIF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHNldFNlbGVjdGlvbkJsb2NrZWRSZWN0cyhbXSk7XG4gICAgfTtcbiAgfSwgW3NldFNlbGVjdGlvbkJsb2NrZWRSZWN0c10pO1xuXG4gIC8vIEhhbmRsZSB2b2ljZSBtZXNzYWdlIHRvYXN0IG5vdGlmaWNhdGlvbnNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCB0b2FzdE1lc3NhZ2UgPVxuICAgICAgdm9pY2VNZXNzYWdlPy5mdWxsVGV4dD8udHJpbSgpIHx8XG4gICAgICB2b2ljZU1lc3NhZ2U/Lm1lc3NhZ2U/LnRyaW0oKSB8fFxuICAgICAgdm9pY2VNZXNzYWdlPy5taW5pbWFsVGV4dD8udHJpbSgpO1xuICAgIGlmICghdG9hc3RNZXNzYWdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRvYXN0TWVzc2FnZUtleSA9IGAke3ZvaWNlTWVzc2FnZT8udHlwZSA/PyAnaW5mbyd9fCR7dm9pY2VNZXNzYWdlPy5vcmlnaW4gPz8gJyd9fCR7dG9hc3RNZXNzYWdlfWA7XG4gICAgY29uc3QgY2xlYXJWb2ljZU1lc3NhZ2UgPSAoKSA9PiB7XG4gICAgICBnZW5pZURpc3BhdGNoKCgpID0+IHtcbiAgICAgICAgY29uc3QgcmVhY3RHZW5pZVN0YXRlID0gc2hhcmVkU3RhdGUgYXMgeyBtZXNzYWdlPzogVm9pY2VNZXNzYWdlIHwgbnVsbCB9O1xuICAgICAgICBjb25zdCBjdXJyZW50TWVzc2FnZSA9IHJlYWN0R2VuaWVTdGF0ZS5tZXNzYWdlO1xuICAgICAgICBjb25zdCBjdXJyZW50VG9hc3RNZXNzYWdlID1cbiAgICAgICAgICBjdXJyZW50TWVzc2FnZT8uZnVsbFRleHQ/LnRyaW0oKSB8fFxuICAgICAgICAgIGN1cnJlbnRNZXNzYWdlPy5tZXNzYWdlPy50cmltKCkgfHxcbiAgICAgICAgICBjdXJyZW50TWVzc2FnZT8ubWluaW1hbFRleHQ/LnRyaW0oKSB8fFxuICAgICAgICAgICcnO1xuICAgICAgICBjb25zdCBjdXJyZW50TWVzc2FnZUtleSA9IGAke2N1cnJlbnRNZXNzYWdlPy50eXBlID8/ICdpbmZvJ318JHtjdXJyZW50TWVzc2FnZT8ub3JpZ2luID8/ICcnfXwke2N1cnJlbnRUb2FzdE1lc3NhZ2V9YDtcbiAgICAgICAgaWYgKGN1cnJlbnRNZXNzYWdlS2V5ICE9PSB0b2FzdE1lc3NhZ2VLZXkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmVhY3RHZW5pZVN0YXRlLm1lc3NhZ2UgPSB7XG4gICAgICAgICAgbWluaW1hbFRleHQ6ICcnLFxuICAgICAgICAgIGZ1bGxUZXh0OiAnJyxcbiAgICAgICAgICBtZXNzYWdlOiAnJyxcbiAgICAgICAgICB0eXBlOiAnaW5mbycsXG4gICAgICAgICAgc2hvdWxkU3BlYWs6IGZhbHNlLFxuICAgICAgICAgIG9yaWdpbjogJ3N5c3RlbScsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGNvbnN0IHRvYXN0T3B0aW9ucyA9IHtcbiAgICAgIG9uQXV0b0Nsb3NlOiBjbGVhclZvaWNlTWVzc2FnZSxcbiAgICAgIG9uRGlzbWlzczogY2xlYXJWb2ljZU1lc3NhZ2UsXG4gICAgfTtcblxuICAgIHN3aXRjaCAodm9pY2VNZXNzYWdlLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgdG9hc3QuZXJyb3IodG9hc3RNZXNzYWdlLCB0b2FzdE9wdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOlxuICAgICAgICB0b2FzdC5zdWNjZXNzKHRvYXN0TWVzc2FnZSwgdG9hc3RPcHRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3YXJuaW5nJzpcbiAgICAgIGNhc2UgJ2luZm8nOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdG9hc3QodG9hc3RNZXNzYWdlLCB0b2FzdE9wdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0sIFt2b2ljZU1lc3NhZ2VdKTtcblxuICBjb25zdCBjbGVhckxhdGVGaW5hbEZhbGxiYWNrID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGF3YWl0aW5nTGF0ZUZpbmFsQWZ0ZXJQYXVzZVJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgaWYgKGxhdGVGaW5hbEZhbGxiYWNrVGltZXJSZWYuY3VycmVudCkge1xuICAgICAgY2xlYXJUaW1lb3V0KGxhdGVGaW5hbEZhbGxiYWNrVGltZXJSZWYuY3VycmVudCk7XG4gICAgICBsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IGZpbmlzaExpc3RlbmluZ1N0YWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHN0YXR1czogVm9pY2VQaXBlbGluZVN0YWdlU3RhdHVzLCBjb250ZXh0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgIGNvbnN0IHN0YWdlID0gYWN0aXZlTGlzdGVuaW5nU3RhZ2VSZWYuY3VycmVudDtcbiAgICAgIGlmICghc3RhZ2UpIHJldHVybjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN0YWdlLmZpbmlzaD8uKHN0YXR1cywge1xuICAgICAgICAgIHNlc3Npb25faWQ6IGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50LFxuICAgICAgICAgIHRocmVhZF9pZDogYWN0aXZlVGhyZWFkSWRSZWYuY3VycmVudCxcbiAgICAgICAgICB0dXJuX2lkOiBhY3RpdmVUdXJuSWRSZWYuY3VycmVudCxcbiAgICAgICAgICAuLi4oY29udGV4dCB8fCB7fSksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIG5vb3BcbiAgICAgIH1cbiAgICAgIGFjdGl2ZUxpc3RlbmluZ1N0YWdlUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIH0sXG4gICAgW11cbiAgKTtcblxuICBjb25zdCBjbGVhclNwZWVjaFJlc3BvbnNlVGltZW91dCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoc3BlZWNoUmVzcG9uc2VUaW1lb3V0UmVmLmN1cnJlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dChzcGVlY2hSZXNwb25zZVRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBzcGVlY2hSZXNwb25zZVRpbWVvdXRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3QgZ2V0UHJvY2Vzc2luZ1N0YWdlU3RhdHVzID0gdXNlQ2FsbGJhY2soXG4gICAgKG91dGNvbWU6IFZvaWNlUGlwZWxpbmVPdXRjb21lKTogVm9pY2VQaXBlbGluZVN0YWdlU3RhdHVzID0+IHtcbiAgICAgIGlmIChvdXRjb21lID09PSAnc3BlZWNoX3Jlc3BvbnNlX3NlbnQnKSByZXR1cm4gJ29rJztcbiAgICAgIGlmIChvdXRjb21lID09PSAnZXJyb3InKSByZXR1cm4gJ2Vycm9yJztcbiAgICAgIHJldHVybiAnY2FuY2VsbGVkJztcbiAgICB9LFxuICAgIFtdXG4gICk7XG5cbiAgY29uc3QgZmluaXNoUHJvY2Vzc2luZ1N0YWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHN0YXR1czogVm9pY2VQaXBlbGluZVN0YWdlU3RhdHVzLCBjb250ZXh0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgIGNvbnN0IHN0YWdlID0gYWN0aXZlUHJvY2Vzc2luZ1N0YWdlUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIXN0YWdlKSByZXR1cm47XG4gICAgICB0cnkge1xuICAgICAgICBzdGFnZS5maW5pc2g/LihzdGF0dXMsIHtcbiAgICAgICAgICBzZXNzaW9uX2lkOiBhY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudCxcbiAgICAgICAgICB0aHJlYWRfaWQ6IGFjdGl2ZVRocmVhZElkUmVmLmN1cnJlbnQsXG4gICAgICAgICAgdHVybl9pZDogYWN0aXZlVHVybklkUmVmLmN1cnJlbnQsXG4gICAgICAgICAgbGF0ZW5jeV9zY29wZTogJ3Bvc3Rfc3RvcF9wcm9jZXNzaW5nJyxcbiAgICAgICAgICAndm9pY2UubGF0ZW5jeV9zY29wZSc6ICdwb3N0X3N0b3BfcHJvY2Vzc2luZycsXG4gICAgICAgICAgLi4uKGNvbnRleHQgfHwge30pLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBub29wXG4gICAgICB9XG4gICAgICBhY3RpdmVQcm9jZXNzaW5nU3RhZ2VSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfSxcbiAgICBbXVxuICApO1xuXG4gIGNvbnN0IGZpbmlzaFZvaWNlUGlwZWxpbmUgPSB1c2VDYWxsYmFjayhcbiAgICAob3V0Y29tZTogVm9pY2VQaXBlbGluZU91dGNvbWUsIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgY2xlYXJTcGVlY2hSZXNwb25zZVRpbWVvdXQoKTtcbiAgICAgIGNvbnN0IHBpcGVsaW5lID0gYWN0aXZlVm9pY2VQaXBlbGluZVJlZi5jdXJyZW50O1xuICAgICAgZmluaXNoUHJvY2Vzc2luZ1N0YWdlKFxuICAgICAgICBnZXRQcm9jZXNzaW5nU3RhZ2VTdGF0dXMob3V0Y29tZSksXG4gICAgICAgIHtcbiAgICAgICAgICBvdXRjb21lLFxuICAgICAgICAgIHByb2Nlc3Npbmdfb3V0Y29tZTogb3V0Y29tZSxcbiAgICAgICAgICAndm9pY2UucHJvY2Vzc2luZ19vdXRjb21lJzogb3V0Y29tZSxcbiAgICAgICAgICAuLi4oY29udGV4dCB8fCB7fSksXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICBpZiAoIXBpcGVsaW5lKSByZXR1cm47XG4gICAgICB0cnkge1xuICAgICAgICBwaXBlbGluZS5maW5pc2g/LihvdXRjb21lLCB7XG4gICAgICAgICAgc2Vzc2lvbl9pZDogYWN0aXZlU2Vzc2lvbklkUmVmLmN1cnJlbnQsXG4gICAgICAgICAgdGhyZWFkX2lkOiBhY3RpdmVUaHJlYWRJZFJlZi5jdXJyZW50LFxuICAgICAgICAgIHR1cm5faWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgICAgIGRpc3BsYXlfb3V0Y29tZTogZGlzcGxheU91dGNvbWVSZWYuY3VycmVudCxcbiAgICAgICAgICAuLi4oY29udGV4dCB8fCB7fSksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIG5vb3BcbiAgICAgIH1cbiAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBhY3RpdmVMaXN0ZW5pbmdTdGFnZVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGFjdGl2ZVByb2Nlc3NpbmdTdGFnZVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIGRpc3BsYXlPdXRjb21lUmVmLmN1cnJlbnQgPSAnbm90X2FwcGxpY2FibGUnO1xuICAgICAgYWN0aXZlVGhyZWFkSWRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBhY3RpdmVUdXJuSWRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfSxcbiAgICBbY2xlYXJTcGVlY2hSZXNwb25zZVRpbWVvdXQsIGZpbmlzaFByb2Nlc3NpbmdTdGFnZSwgZ2V0UHJvY2Vzc2luZ1N0YWdlU3RhdHVzXVxuICApO1xuXG4gIGNvbnN0IHNwZWFrVm9pY2VSZXNwb25zZSA9IHVzZUNhbGxiYWNrKGFzeW5jICh0ZXh0OiBzdHJpbmcpID0+IHtcbiAgICBpZiAoIXRleHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkVGV4dCA9IHRydW5jYXRlVGV4dCh0ZXh0LCBTUEVFQ0hfTUlOSU1BTF9URVhUX0xJTUlUKTtcbiAgICBpZiAoIW5vcm1hbGl6ZWRUZXh0LnRyaW0oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwaXBlbGluZSA9IGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudDtcbiAgICBjb25zdCBzcGVlY2hTdGFnZSA9XG4gICAgICBwaXBlbGluZT8uc3RhcnRTdGFnZT8uKCdzcGVlY2gucmVzcG9uZCcsIHtcbiAgICAgICAgc2Vzc2lvbl9pZDogYWN0aXZlU2Vzc2lvbklkUmVmLmN1cnJlbnQsXG4gICAgICAgIHRocmVhZF9pZDogYWN0aXZlVGhyZWFkSWRSZWYuY3VycmVudCxcbiAgICAgICAgdHVybl9pZDogYWN0aXZlVHVybklkUmVmLmN1cnJlbnQsXG4gICAgICAgIHRleHRfbGVuZ3RoOiBub3JtYWxpemVkVGV4dC5sZW5ndGgsXG4gICAgICB9KSB8fCBudWxsO1xuICAgIGNvbnN0IGZpbmlzaFNwZWVjaFN0YWdlID0gKFxuICAgICAgc3RhdHVzOiBWb2ljZVBpcGVsaW5lU3RhZ2VTdGF0dXMsXG4gICAgICBjb250ZXh0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgICApID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNwZWVjaFN0YWdlPy5maW5pc2g/LihzdGF0dXMsIHtcbiAgICAgICAgICB0ZXh0X2xlbmd0aDogbm9ybWFsaXplZFRleHQubGVuZ3RoLFxuICAgICAgICAgIC4uLihjb250ZXh0IHx8IHt9KSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gbm9vcFxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoUGxhdGZvcm0uT1MgPT09ICd3ZWInKSB7XG4gICAgICBjb25zdCBzcGVlY2hTeW50aGVzaXNBcGkgPSAoZ2xvYmFsVGhpcyBhcyBhbnkpPy5zcGVlY2hTeW50aGVzaXM7XG4gICAgICBjb25zdCB1dHRlcmFuY2VDb25zdHJ1Y3RvciA9IChnbG9iYWxUaGlzIGFzIGFueSk/LlNwZWVjaFN5bnRoZXNpc1V0dGVyYW5jZTtcbiAgICAgIGlmICghc3BlZWNoU3ludGhlc2lzQXBpIHx8ICF1dHRlcmFuY2VDb25zdHJ1Y3Rvcikge1xuICAgICAgICBmaW5pc2hTcGVlY2hTdGFnZSgnZXJyb3InLCB7IHJlYXNvbjogJ3NwZWVjaF9hcGlfdW5hdmFpbGFibGUnLCBwbGF0Zm9ybTogJ3dlYicgfSk7XG4gICAgICAgIGlmIChwaXBlbGluZSkge1xuICAgICAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Vycm9yJywge1xuICAgICAgICAgICAgcmVhc29uOiAnc3BlZWNoX2FwaV91bmF2YWlsYWJsZScsXG4gICAgICAgICAgICBwbGF0Zm9ybTogJ3dlYicsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAod2ViU3BlZWNoVXR0ZXJhbmNlUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgc3BlZWNoU3ludGhlc2lzQXBpLmNhbmNlbCgpO1xuICAgICAgICB3ZWJTcGVlY2hVdHRlcmFuY2VSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHV0dGVyYW5jZSA9IG5ldyB1dHRlcmFuY2VDb25zdHJ1Y3Rvcihub3JtYWxpemVkVGV4dCk7XG4gICAgICB3ZWJTcGVlY2hVdHRlcmFuY2VSZWYuY3VycmVudCA9IHV0dGVyYW5jZTtcbiAgICAgIHNwZWVjaFN5bnRoZXNpc0FwaS5zcGVhayh1dHRlcmFuY2UpO1xuICAgICAgZmluaXNoU3BlZWNoU3RhZ2UoJ29rJywgeyBwbGF0Zm9ybTogJ3dlYicgfSk7XG4gICAgICBpZiAocGlwZWxpbmUpIHtcbiAgICAgICAgZmluaXNoVm9pY2VQaXBlbGluZSgnc3BlZWNoX3Jlc3BvbnNlX3NlbnQnLCB7XG4gICAgICAgICAgcGxhdGZvcm06ICd3ZWInLFxuICAgICAgICAgIHNwZWVjaF90ZXh0X2xlbmd0aDogbm9ybWFsaXplZFRleHQubGVuZ3RoLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3BlZWNoTW9kdWxlID0gYXdhaXQgaW1wb3J0KCdleHBvLXNwZWVjaCcpO1xuICAgICAgc3BlZWNoTW9kdWxlLnN0b3AoKTtcbiAgICAgIHNwZWVjaE1vZHVsZS5zcGVhayhub3JtYWxpemVkVGV4dCk7XG4gICAgICBmaW5pc2hTcGVlY2hTdGFnZSgnb2snLCB7IHBsYXRmb3JtOiAnbmF0aXZlJyB9KTtcbiAgICAgIGlmIChwaXBlbGluZSkge1xuICAgICAgICBmaW5pc2hWb2ljZVBpcGVsaW5lKCdzcGVlY2hfcmVzcG9uc2Vfc2VudCcsIHtcbiAgICAgICAgICBwbGF0Zm9ybTogJ25hdGl2ZScsXG4gICAgICAgICAgc3BlZWNoX3RleHRfbGVuZ3RoOiBub3JtYWxpemVkVGV4dC5sZW5ndGgsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmaW5pc2hTcGVlY2hTdGFnZSgnZXJyb3InLCB7IHBsYXRmb3JtOiAnbmF0aXZlJywgcmVhc29uOiAnc3BlZWNoX21vZHVsZV9lcnJvcicgfSk7XG4gICAgICBpZiAocGlwZWxpbmUpIHtcbiAgICAgICAgZmluaXNoVm9pY2VQaXBlbGluZSgnZXJyb3InLCB7XG4gICAgICAgICAgcGxhdGZvcm06ICduYXRpdmUnLFxuICAgICAgICAgIHJlYXNvbjogJ3NwZWVjaF9tb2R1bGVfZXJyb3InLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gcGxheSBzcGVlY2ggcmVzcG9uc2UnLCBlcnJvcik7XG4gICAgfVxuICB9LCBbZmluaXNoVm9pY2VQaXBlbGluZV0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgbWluaW1hbFRleHQgPVxuICAgICAgdm9pY2VNZXNzYWdlPy5taW5pbWFsVGV4dD8udHJpbSgpIHx8XG4gICAgICB2b2ljZU1lc3NhZ2U/Lm1lc3NhZ2U/LnRyaW0oKSB8fFxuICAgICAgJyc7XG4gICAgaWYgKCFtaW5pbWFsVGV4dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodm9pY2VNZXNzYWdlPy5vcmlnaW4gIT09ICd2b2ljZScgfHwgIXZvaWNlTWVzc2FnZT8uc2hvdWxkU3BlYWspIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2b2lkIHNwZWFrVm9pY2VSZXNwb25zZShtaW5pbWFsVGV4dCk7XG4gIH0sIFt2b2ljZU1lc3NhZ2UsIHNwZWFrVm9pY2VSZXNwb25zZV0pO1xuXG4gIGNvbnN0IGFybVNwZWVjaFJlc3BvbnNlVGltZW91dCA9IHVzZUNhbGxiYWNrKFxuICAgIChyZWFzb246IHN0cmluZykgPT4ge1xuICAgICAgY2xlYXJTcGVlY2hSZXNwb25zZVRpbWVvdXQoKTtcbiAgICAgIHNwZWVjaFJlc3BvbnNlVGltZW91dFJlZi5jdXJyZW50ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ3NwZWVjaF9yZXNwb25zZV90aW1lb3V0Jywge1xuICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgfSk7XG4gICAgICB9LCA1MDAwKTtcbiAgICB9LFxuICAgIFtjbGVhclNwZWVjaFJlc3BvbnNlVGltZW91dCwgZmluaXNoVm9pY2VQaXBlbGluZV1cbiAgKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAobGF0ZUZpbmFsRmFsbGJhY2tUaW1lclJlZi5jdXJyZW50KSB7XG4gICAgICAgIGNsZWFyVGltZW91dChsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQpO1xuICAgICAgICBsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfVxuICAgICAgY2xlYXJTcGVlY2hSZXNwb25zZVRpbWVvdXQoKTtcbiAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Fib3J0ZWQnLCB7IHJlYXNvbjogJ3Byb3ZpZGVyX3VubW91bnRlZCcgfSk7XG4gICAgICBjb25zdCBzcGVlY2hTeW50aGVzaXNBcGkgPSAoZ2xvYmFsVGhpcyBhcyBhbnkpPy5zcGVlY2hTeW50aGVzaXM7XG4gICAgICBpZiAoc3BlZWNoU3ludGhlc2lzQXBpKSB7XG4gICAgICAgIHNwZWVjaFN5bnRoZXNpc0FwaS5jYW5jZWwoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbY2xlYXJTcGVlY2hSZXNwb25zZVRpbWVvdXQsIGZpbmlzaFZvaWNlUGlwZWxpbmVdKTtcblxuICBjb25zdCBiZWdpbkxhdGVGaW5hbEZhbGxiYWNrID0gdXNlQ2FsbGJhY2soKHJlYXNvbjogc3RyaW5nKSA9PiB7XG4gICAgYXdhaXRpbmdMYXRlRmluYWxBZnRlclBhdXNlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIGlmIChsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dChsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgICBsYXRlRmluYWxGYWxsYmFja1RpbWVyUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGxhdGVGaW5hbEZhbGxiYWNrVGltZXJSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBpZiAoIWF3YWl0aW5nTGF0ZUZpbmFsQWZ0ZXJQYXVzZVJlZi5jdXJyZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChsYXRlc3RUcmFuc2NyaXB0UmVmLmN1cnJlbnQudHJpbSgpICE9PSAnJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdGluZ0xhdGVGaW5hbEFmdGVyUGF1c2VSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgZmluaXNoTGlzdGVuaW5nU3RhZ2UoJ2NhbmNlbGxlZCcsIHsgcmVhc29uOiAnbGF0ZV9maW5hbF9taXNzaW5nJyB9KTtcbiAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Fib3J0ZWQnLCB7IHJlYXNvbjogJ2xhdGVfZmluYWxfbWlzc2luZycgfSk7XG4gICAgICBsb2dnZXIuaW5mbyhgW1ZvaWNlXSAke3JlYXNvbn07IG5vIGxhdGUgZmluYWwgdHJhbnNjcmlwdDsgc3RvcCBmaW5hbGl6ZWRgKTtcbiAgICB9LCAzNTApO1xuICAgIGxvZ2dlci5pbmZvKGBbVm9pY2VdICR7cmVhc29ufTsgd2FpdGluZyBicmllZmx5IGZvciBsYXRlIGZpbmFsYCk7XG4gIH0sIFtmaW5pc2hMaXN0ZW5pbmdTdGFnZSwgZmluaXNoVm9pY2VQaXBlbGluZV0pO1xuXG4gIC8vIFBhcnNlIHRyYW5zY3JpcHQgb25jZSByZWNvcmRpbmcgZmluaXNoZXNcbiAgY29uc3QgcHJvY2Vzc1RyYW5zY3JpcHQgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAoc2Vzc2lvbklkOiBudW1iZXIsIHRleHQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3Qgbm9Db21tYW5kTWVzc2FnZSA9IFwiTm8gY29tbWFuZCB0byBydW4uXCI7XG4gICAgICBjb25zdCBuYXZpZ2F0aW9uU2V0dGxpbmdNZXNzYWdlID1cbiAgICAgICAgXCJOYXZpZ2F0aW9uIGlzIHN0aWxsIHNldHRsaW5nLiBQbGVhc2UgdHJ5IGFnYWluIGluIGEgbW9tZW50LlwiO1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHRleHQudHJpbSgpO1xuICAgICAgaWYgKFxuICAgICAgICB0cmltbWVkID09PSAnJyB8fFxuICAgICAgICBpc1Byb2Nlc3NpbmdUcmFuc2NyaXB0UmVmLmN1cnJlbnQgfHxcbiAgICAgICAgc2Vzc2lvbklkICE9PSBhY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudCB8fFxuICAgICAgICBmaW5hbGl6ZWRTZXNzaW9uSWRSZWYuY3VycmVudCA9PT0gc2Vzc2lvbklkXG4gICAgICApIHtcbiAgICAgICAgaWYgKHRyaW1tZWQgPT09ICcnKSB7XG4gICAgICAgICAgbGF0ZXN0VHJhbnNjcmlwdFJlZi5jdXJyZW50ID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmaW5pc2hMaXN0ZW5pbmdTdGFnZSgnb2snLCB7IHJlYXNvbjogJ3RyYW5zY3JpcHRfcHJvY2Vzc2luZ19zdGFydGVkJyB9KTtcbiAgICAgIGlzUHJvY2Vzc2luZ1RyYW5zY3JpcHRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgICBmaW5hbGl6ZWRTZXNzaW9uSWRSZWYuY3VycmVudCA9IHNlc3Npb25JZDtcbiAgICAgIGFjY2VwdGluZ1NwZWVjaElucHV0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIGNsZWFyTGF0ZUZpbmFsRmFsbGJhY2soKTtcbiAgICAgIGxhc3RUcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSB0cmltbWVkO1xuICAgICAgc3BlZWNoUmVjb2duaXRpb24uc3RvcExpc3RlbmluZygpO1xuICAgICAgc3BlZWNoUmVjb2duaXRpb24uc2V0UHJvY2Vzc2luZyh0cnVlKTtcbiAgICAgIGxvZ2dlci5pbmZvKCdMaXN0ZW5lciBzdGF0ZSBzZXQgdG8gUHJvY2Vzc2luZycpO1xuICAgICAgbG9nZ2VyLmluZm8oYEZpbmFsIHRyYW5zY3JpcHQgcmVjZWl2ZWQ6ICR7dHJpbW1lZH1gKTtcbiAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudD8uYW5ub3RhdGU/Lih7XG4gICAgICAgIHNlc3Npb25faWQ6IGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50LFxuICAgICAgICB0aHJlYWRfaWQ6IGFjdGl2ZVRocmVhZElkUmVmLmN1cnJlbnQsXG4gICAgICAgIHR1cm5faWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgICBmaW5hbF90cmFuc2NyaXB0X2xlbmd0aDogdHJpbW1lZC5sZW5ndGgsXG4gICAgICB9KTtcbiAgICAgIGFjdGl2ZVByb2Nlc3NpbmdTdGFnZVJlZi5jdXJyZW50ID1cbiAgICAgICAgYWN0aXZlVm9pY2VQaXBlbGluZVJlZi5jdXJyZW50Py5zdGFydFN0YWdlPy4oJ3ZvaWNlLnByb2Nlc3NpbmcnLCB7XG4gICAgICAgICAgc2Vzc2lvbl9pZDogYWN0aXZlU2Vzc2lvbklkUmVmLmN1cnJlbnQsXG4gICAgICAgICAgdGhyZWFkX2lkOiBhY3RpdmVUaHJlYWRJZFJlZi5jdXJyZW50LFxuICAgICAgICAgIHR1cm5faWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgICAgIGxhdGVuY3lfc2NvcGU6ICdwb3N0X3N0b3BfcHJvY2Vzc2luZycsXG4gICAgICAgICAgJ3ZvaWNlLmxhdGVuY3lfc2NvcGUnOiAncG9zdF9zdG9wX3Byb2Nlc3NpbmcnLFxuICAgICAgICAgIHByb2Nlc3Npbmdfc3RhcnQ6ICd0cmFuc2NyaXB0X2ZpbmFsaXplZCcsXG4gICAgICAgICAgZmluYWxfdHJhbnNjcmlwdF9sZW5ndGg6IHRyaW1tZWQubGVuZ3RoLFxuICAgICAgICB9KSB8fCBudWxsO1xuICAgICAgY29uc3QgZmluYWxUcmFuc2NyaXB0U3RhZ2UgPVxuICAgICAgICBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmLmN1cnJlbnQ/LnN0YXJ0U3RhZ2U/Lignc3R0LmZpbmFsX3RyYW5zY3JpcHQnLCB7XG4gICAgICAgICAgdHJhbnNjcmlwdF9sZW5ndGg6IHRyaW1tZWQubGVuZ3RoLFxuICAgICAgICB9KSB8fCBudWxsO1xuICAgICAgZmluYWxUcmFuc2NyaXB0U3RhZ2U/LmZpbmlzaD8uKCdvaycsIHtcbiAgICAgICAgdHJhbnNjcmlwdF9sZW5ndGg6IHRyaW1tZWQubGVuZ3RoLFxuICAgICAgfSk7XG5cbiAgICAgIGxldCBwYXJzZUlucHV0ID0gdHJpbW1lZDtcbiAgICAgIGxldCBwYXJzZWRDb21tYW5kOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGxhdGVzdFRyYW5zbGF0aW9uUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgICBwYXJzZUlucHV0ID0gbGF0ZXN0VHJhbnNsYXRpb25SZWYuY3VycmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByZVBhcnNlU25hcHNob3QgPSBhd2FpdCB3YWl0Rm9yU3RhYmxlSW50ZXJmYWNlU25hcHNob3QoKTtcbiAgICAgICAgaWYgKHByZVBhcnNlU25hcHNob3QudmlzaWJpbGl0eVN0YXRlID09PSBcInRyYW5zaXRpb25fdW5zdGFibGVcIikge1xuICAgICAgICAgIHRocm93IG5ldyBWaXNpYmlsaXR5VHJhbnNpdGlvbkVycm9yKG5hdmlnYXRpb25TZXR0bGluZ01lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByZVBhcnNlSW50ZXJmYWNlcyA9IHByZVBhcnNlU25hcHNob3QuaW50ZXJmYWNlcztcbiAgICAgICAgY29uc3QgbGF0ZXN0VGFwID0gZ2V0TGF0ZXN0VW5ibG9ja2VkVGFwKCk7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVVaUNvbnRleHQ6IFJ1bnRpbWVVaUNvbnRleHQgPSB7XG4gICAgICAgICAgdGFwQ2xhc3NOYW1lOiByZXNvbHZlVGFwQ2xhc3NOYW1lKHByZVBhcnNlSW50ZXJmYWNlcywgbGF0ZXN0VGFwKSxcbiAgICAgICAgICB2aXNpYmxlQ2xhc3NOYW1lczogQXJyYXkuZnJvbShcbiAgICAgICAgICAgIG5ldyBTZXQocHJlUGFyc2VJbnRlcmZhY2VzLm1hcCgoZ2VuaWVJbnRlcmZhY2UpID0+IGdlbmllSW50ZXJmYWNlLmNsYXNzTmFtZSkpXG4gICAgICAgICAgKSxcbiAgICAgICAgICBpc0RlaWN0aWNVdHRlcmFuY2U6IGlzRGVpY3RpY1JlZmVyZW5jZVV0dGVyYW5jZShwYXJzZUlucHV0KSxcbiAgICAgICAgfTtcbiAgICAgICAgYXBwbHlSdW50aW1lVWlDb250ZXh0KEdlbmllSW50ZXJwcmV0ZXIsIHJ1bnRpbWVVaUNvbnRleHQpO1xuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgW1ZvaWNlUGlwZWxpbmVdIHJ1bnRpbWUgVUkgY29udGV4dDogdGFwQ2xhc3M9JHtcbiAgICAgICAgICAgIHJ1bnRpbWVVaUNvbnRleHQudGFwQ2xhc3NOYW1lIHx8IFwibm9uZVwiXG4gICAgICAgICAgfTsgdmlzaWJsZT0ke3J1bnRpbWVVaUNvbnRleHQudmlzaWJsZUNsYXNzTmFtZXMuam9pbihcIixcIikgfHwgXCJub25lXCJ9OyBkZWljdGljPSR7XG4gICAgICAgICAgICBydW50aW1lVWlDb250ZXh0LmlzRGVpY3RpY1V0dGVyYW5jZSA/IFwieWVzXCIgOiBcIm5vXCJcbiAgICAgICAgICB9YFxuICAgICAgICApO1xuXG4gICAgICAgIGxvZ2dlci5pbmZvKCdTdGFydCBwYXJzaW5nIHRyYW5zY3JpcHQgd2l0aCBHZW5pZUludGVycHJldGVyJyk7XG4gICAgICAgIGNvbnN0IHBhcnNlU3RhZ2UgPVxuICAgICAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudD8uc3RhcnRTdGFnZT8uKCdkc2wucGFyc2UnLCB7XG4gICAgICAgICAgICBwYXJzZV9pbnB1dF9sZW5ndGg6IHBhcnNlSW5wdXQubGVuZ3RoLFxuICAgICAgICAgIH0pIHx8IG51bGw7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEdlbmllSW50ZXJwcmV0ZXIubmxQYXJzZXIucGFyc2UocGFyc2VJbnB1dCk7XG4gICAgICAgIHBhcnNlU3RhZ2U/LmZpbmlzaD8uKCdvaycsIHtcbiAgICAgICAgICBhY3Rpb25hYmxlOiB0eXBlb2YgcmVzdWx0ID09PSAnc3RyaW5nJyAmJiByZXN1bHQudHJpbSgpICE9PSAnJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdbVm9pY2VQaXBlbGluZV0gcGFyc2Ugc3VjY2VzcycpO1xuICAgICAgICBsb2dnZXIuaW5mbyhgcGFyc2VkIHJlc3VsdDogJHtyZXN1bHR9YCk7XG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcInN0cmluZ1wiIHx8IHJlc3VsdC50cmltKCkgPT09IFwiXCIpIHtcbiAgICAgICAgICByZWNvcmRJbnRlcnByZXRlclR1cm4oR2VuaWVJbnRlcnByZXRlciwge1xuICAgICAgICAgICAgdXR0ZXJhbmNlOiBwYXJzZUlucHV0LFxuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICByZXN1bHRTdW1tYXJ5OiAncGFyc2VfZW1wdHknLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudD8uYW5ub3RhdGU/Lih7XG4gICAgICAgICAgICBjb21tYW5kX291dGNvbWU6ICdub19hY3Rpb25hYmxlX2NvbW1hbmQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdbVm9pY2VQaXBlbGluZV0gcGFyc2UgcmV0dXJuZWQgbm8gYWN0aW9uYWJsZSBjb21tYW5kJyk7XG4gICAgICAgICAgc3BlZWNoUmVjb2duaXRpb24uc2V0SW50ZXJpbVRyYW5zY3JpcHQoXCJcIik7XG4gICAgICAgICAgdG9hc3Qobm9Db21tYW5kTWVzc2FnZSk7XG4gICAgICAgICAgYXJtU3BlZWNoUmVzcG9uc2VUaW1lb3V0KCdub19hY3Rpb25hYmxlX2NvbW1hbmQnKTtcbiAgICAgICAgICB2b2lkIHNwZWFrVm9pY2VSZXNwb25zZShub0NvbW1hbmRNZXNzYWdlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcGFyc2VkQ29tbWFuZCA9IHJlc3VsdC50cmltKCk7XG4gICAgICAgIHNwZWVjaFJlY29nbml0aW9uLnNldEludGVyaW1UcmFuc2NyaXB0KCcnKTtcbiAgICAgICAgY29uc3QgbmF2U3RhY2tCZWZvcmVEaXNwbGF5ID0gbmF2U3RhY2tSZWYuY3VycmVudDtcbiAgICAgICAgY29uc3QgZXhlY3V0ZVN0YWdlID1cbiAgICAgICAgICBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmLmN1cnJlbnQ/LnN0YXJ0U3RhZ2U/LignZHNsLmV4ZWN1dGUnLCB7XG4gICAgICAgICAgICBwYXJzZWRfY29tbWFuZF9sZW5ndGg6IHBhcnNlZENvbW1hbmQubGVuZ3RoLFxuICAgICAgICAgIH0pIHx8IG51bGw7XG4gICAgICAgIGNvbnN0IGV4ZWN1dGlvblJlc3VsdCA9IGF3YWl0IGV4ZWN1dGVHZW5pZUNvZGUocGFyc2VkQ29tbWFuZCwge1xuICAgICAgICAgIG9yaWdpbjogJ3ZvaWNlJyxcbiAgICAgICAgICBzaG91bGRTcGVha0Vycm9yczogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGV4ZWN1dGVTdGFnZT8uZmluaXNoPy4oZXhlY3V0aW9uUmVzdWx0LnN1Y2Nlc3MgPyAnb2snIDogJ2Vycm9yJywge1xuICAgICAgICAgIGV4ZWN1dGlvbl9zdWNjZXNzOiBleGVjdXRpb25SZXN1bHQuc3VjY2VzcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGV4ZWN1dGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgcmVjb3JkSW50ZXJwcmV0ZXJUdXJuKEdlbmllSW50ZXJwcmV0ZXIsIHtcbiAgICAgICAgICAgIHV0dGVyYW5jZTogcGFyc2VJbnB1dCxcbiAgICAgICAgICAgIHBhcnNlZDogcGFyc2VkQ29tbWFuZCxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICByZXN1bHRTdW1tYXJ5OiAnZXhlY3V0ZV9vaycsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gU25hcHNob3QgbW91bnRlZCBpbnRlcmZhY2VzIGFmdGVyIGV4ZWN1dGlvbiBzbyBvblNjcmVlbiBtYXRjaGluZ1xuICAgICAgICAgIC8vIHJlZmxlY3RzIHRoZSBsYXRlc3QgbmF0aXZlIG1vdW50L3VubW91bnQgc3RhdGUuXG4gICAgICAgICAgY29uc3QgcG9zdEV4ZWN1dGlvblNuYXBzaG90ID0gYXdhaXQgd2FpdEZvclN0YWJsZUludGVyZmFjZVNuYXBzaG90KCk7XG4gICAgICAgICAgY29uc3QgZ2VuaWVJbnRlcmZhY2VzID1cbiAgICAgICAgICAgIHBvc3RFeGVjdXRpb25TbmFwc2hvdC52aXNpYmlsaXR5U3RhdGUgPT09IFwidHJhbnNpdGlvbl91bnN0YWJsZVwiXG4gICAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgICAgOiBwb3N0RXhlY3V0aW9uU25hcHNob3QuaW50ZXJmYWNlcztcbiAgICAgICAgICBsb2dnZXIuaW5mbygnW1ZvaWNlUGlwZWxpbmVdIERTTCBleGVjdXRpb24gc3VjY2VzcycpO1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdleGVjdXRpb24gcmVzdWx0OiAnLCBleGVjdXRpb25SZXN1bHQpO1xuICAgICAgICAgIGRpc3BsYXlSZXN1bHQoXG4gICAgICAgICAgICBleGVjdXRpb25SZXN1bHQsXG4gICAgICAgICAgICB0cmltbWVkLFxuICAgICAgICAgICAgcGFyc2VkQ29tbWFuZCxcbiAgICAgICAgICAgIGdlbmllSW50ZXJmYWNlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgZGlzcGxheVN0YWdlID1cbiAgICAgICAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudD8uc3RhcnRTdGFnZT8uKCd1aS5kaXNwbGF5Jywge1xuICAgICAgICAgICAgICBleHBlY3RlZF9uYXZpZ2F0aW9uX2V2ZW50X2lkOiBuYXZTdGFja0JlZm9yZURpc3BsYXkgKyAxLFxuICAgICAgICAgICAgfSkgfHwgbnVsbDtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5hdkludGVudE9ic2VydmVkID0gbmF2U3RhY2tSZWYuY3VycmVudCA+IG5hdlN0YWNrQmVmb3JlRGlzcGxheTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBbVm9pY2VQaXBlbGluZV0gbmF2IGludGVudCBvYnNlcnZlZCBieSBhZGFwdGVyOiAke25hdkludGVudE9ic2VydmVkID8gJ3llcycgOiAnbm8nfWApO1xuICAgICAgICAgICAgZGlzcGxheU91dGNvbWVSZWYuY3VycmVudCA9IG5hdkludGVudE9ic2VydmVkID8gJ3JlbmRlcmVkJyA6ICdza2lwcGVkX2ludGVudGlvbmFsJztcbiAgICAgICAgICAgIGRpc3BsYXlTdGFnZT8uZmluaXNoPy4obmF2SW50ZW50T2JzZXJ2ZWQgPyAnb2snIDogJ3NraXBwZWQnLCB7XG4gICAgICAgICAgICAgIG5hdl9pbnRlbnRfb2JzZXJ2ZWQ6IG5hdkludGVudE9ic2VydmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmLmN1cnJlbnQ/LmFubm90YXRlPy4oe1xuICAgICAgICAgICAgICBkaXNwbGF5X291dGNvbWU6IGRpc3BsYXlPdXRjb21lUmVmLmN1cnJlbnQsXG4gICAgICAgICAgICAgIG5hdl9pbnRlbnRfb2JzZXJ2ZWQ6IG5hdkludGVudE9ic2VydmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIW5hdkludGVudE9ic2VydmVkKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdbVm9pY2VQaXBlbGluZV0gbGlrZWx5X3NraXBwZWRfdXBzdHJlYW1fYnlfZGlzcGxheV9nYXRlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMzUwKTtcbiAgICAgICAgICBhcm1TcGVlY2hSZXNwb25zZVRpbWVvdXQoJ3Bvc3RfZGlzcGxheV9yZXNwb25zZScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlY29yZEludGVycHJldGVyVHVybihHZW5pZUludGVycHJldGVyLCB7XG4gICAgICAgICAgICB1dHRlcmFuY2U6IHBhcnNlSW5wdXQsXG4gICAgICAgICAgICBwYXJzZWQ6IHBhcnNlZENvbW1hbmQsXG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIHJlc3VsdFN1bW1hcnk6ICdleGVjdXRlX2Vycm9yOmV4ZWN1dGlvbl9mYWlsZWQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Vycm9yJywge1xuICAgICAgICAgICAgcmVhc29uOiAnZHNsX2V4ZWN1dGlvbl9mYWlsZWQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgQ2xpY2tQb2ludHMuc3BsaWNlKDAsIENsaWNrUG9pbnRzLmxlbmd0aCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICAgIHJlY29yZEludGVycHJldGVyVHVybihHZW5pZUludGVycHJldGVyLCB7XG4gICAgICAgICAgdXR0ZXJhbmNlOiBwYXJzZUlucHV0LFxuICAgICAgICAgIHBhcnNlZDogcGFyc2VkQ29tbWFuZCxcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICByZXN1bHRTdW1tYXJ5OiBwYXJzZWRDb21tYW5kXG4gICAgICAgICAgICA/IGBleGVjdXRlX2Vycm9yOiR7ZXJyb3JNZXNzYWdlfWBcbiAgICAgICAgICAgIDogYHBhcnNlX2Vycm9yOiR7ZXJyb3JNZXNzYWdlfWAsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaXNOb0NvbW1hbmRQYXJzZUVycm9yKGVycm9yKSkge1xuICAgICAgICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudD8uYW5ub3RhdGU/Lih7XG4gICAgICAgICAgICBjb21tYW5kX291dGNvbWU6ICdub19hY3Rpb25hYmxlX2NvbW1hbmQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdObyBhY3Rpb25hYmxlIGNvbW1hbmQgZGV0ZWN0ZWQgZnJvbSB0cmFuc2NyaXB0Jyk7XG4gICAgICAgICAgdG9hc3Qobm9Db21tYW5kTWVzc2FnZSk7XG4gICAgICAgICAgYXJtU3BlZWNoUmVzcG9uc2VUaW1lb3V0KCdub19hY3Rpb25hYmxlX2NvbW1hbmRfZXJyb3InKTtcbiAgICAgICAgICB2b2lkIHNwZWFrVm9pY2VSZXNwb25zZShub0NvbW1hbmRNZXNzYWdlKTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciBpbnN0YW5jZW9mIFZpc2liaWxpdHlUcmFuc2l0aW9uRXJyb3IpIHtcbiAgICAgICAgICBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmLmN1cnJlbnQ/LmFubm90YXRlPy4oe1xuICAgICAgICAgICAgY29tbWFuZF9vdXRjb21lOiAnbmF2aWdhdGlvbl90cmFuc2l0aW9uX3Vuc3RhYmxlJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBsb2dnZXIuaW5mbygnRGVmZXJyZWQgdHJhbnNjcmlwdCBwcm9jZXNzaW5nIHdoaWxlIG5hdmlnYXRpb24gd2FzIHRyYW5zaXRpb25pbmcnKTtcbiAgICAgICAgICB0b2FzdChuYXZpZ2F0aW9uU2V0dGxpbmdNZXNzYWdlKTtcbiAgICAgICAgICBhcm1TcGVlY2hSZXNwb25zZVRpbWVvdXQoJ25hdmlnYXRpb25fdHJhbnNpdGlvbl91bnN0YWJsZScpO1xuICAgICAgICAgIHZvaWQgc3BlYWtWb2ljZVJlc3BvbnNlKG5hdmlnYXRpb25TZXR0bGluZ01lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Vycm9yJywge1xuICAgICAgICAgICAgcmVhc29uOiAndHJhbnNjcmlwdF9wcm9jZXNzaW5nX2ZhaWxlZCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdGYWlsZWQgdG8gcHJvY2VzcyB0cmFuc2NyaXB0JywgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhcHBseVJ1bnRpbWVVaUNvbnRleHQoR2VuaWVJbnRlcnByZXRlciwgbnVsbCk7XG4gICAgICAgIHNwZWVjaFJlY29nbml0aW9uLnNldFByb2Nlc3NpbmcoZmFsc2UpO1xuICAgICAgICBpc1Byb2Nlc3NpbmdUcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgICBjbGVhckxhdGVGaW5hbEZhbGxiYWNrKCk7XG4gICAgICAgIGxhdGVzdFRyYW5zY3JpcHRSZWYuY3VycmVudCA9ICcnO1xuICAgICAgICBsYXRlc3RUcmFuc2xhdGlvblJlZi5jdXJyZW50ID0gJyc7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbW9uaXRvciA9IGdldExMTU1vbml0b3IoKTtcbiAgICAgICAgICBtb25pdG9yLnNldFRocmVhZChudWxsKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8vIGlnbm9yZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBbXG4gICAgICBhcm1TcGVlY2hSZXNwb25zZVRpbWVvdXQsXG4gICAgICBjbGVhckxhdGVGaW5hbEZhbGxiYWNrLFxuICAgICAgZGlzcGxheVJlc3VsdCxcbiAgICAgIGV4ZWN1dGVHZW5pZUNvZGUsXG4gICAgICBmaW5pc2hMaXN0ZW5pbmdTdGFnZSxcbiAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUsXG4gICAgICBnZXRMYXRlc3RVbmJsb2NrZWRUYXAsXG4gICAgICBzcGVha1ZvaWNlUmVzcG9uc2UsXG4gICAgICBzcGVlY2hSZWNvZ25pdGlvbixcbiAgICBdXG4gICk7XG5cbiAgLy8gPT09PT09PT09PSBFdmVudCBIYW5kbGVycyA9PT09PT09PT09XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoUGxhdGZvcm0uT1MgIT09IFwid2ViXCIgfHwgdHlwZW9mIGRvY3VtZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGxpc3RlbmVyU3RhdGUgIT09IExpc3RlbmVyU3RhdGUuTGlzdGVuaW5nKSB7XG4gICAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBibG9ja2VkT3ZlcmxheVRhcFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZVBvaW50ZXJEb3duID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0WCA9IGV2ZW50Py5jbGllbnRYID8/IDA7XG4gICAgICBjb25zdCBzdGFydFkgPSBldmVudD8uY2xpZW50WSA/PyAwO1xuICAgICAgaWYgKHBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0KHN0YXJ0WCwgc3RhcnRZKSkge1xuICAgICAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIGJsb2NrZWRPdmVybGF5VGFwUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGJsb2NrZWRPdmVybGF5VGFwUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIC8vIFJlZnJlc2ggd3JhcHBlciBnZW9tZXRyeSBhdCB0b3VjaCBzdGFydCBzbyBsYXRlciBDdXJyZW50KCkgcmVzb2x1dGlvblxuICAgICAgLy8gdXNlcyB0aGUgY2FyZCBwb3NpdGlvbnMgdGhlIHVzZXIgYWN0dWFsbHkgc2F3IHdoZW4gdGFwcGluZy5cbiAgICAgIFJlZnJlc2hEaXNwbGF5ZWRJbnN0YW5jZVJlY3RzKCk7XG4gICAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IHtcbiAgICAgICAgeDogc3RhcnRYLFxuICAgICAgICB5OiBzdGFydFksXG4gICAgICAgIGF0OiBEYXRlLm5vdygpLFxuICAgICAgfTtcbiAgICAgIHNldElzUHJlc3NlZCh0cnVlKTtcbiAgICB9O1xuXG4gICAgY29uc3QgaGFuZGxlUG9pbnRlclVwID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdG91Y2hTdGFydFBvaW50UmVmLmN1cnJlbnQ7XG4gICAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgICAgaWYgKCFzdGFydCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVuZFggPSBldmVudD8uY2xpZW50WCA/PyBzdGFydC54O1xuICAgICAgY29uc3QgZW5kWSA9IGV2ZW50Py5jbGllbnRZID8/IHN0YXJ0Lnk7XG4gICAgICBjb25zdCBkeCA9IGVuZFggLSBzdGFydC54O1xuICAgICAgY29uc3QgZHkgPSBlbmRZIC0gc3RhcnQueTtcbiAgICAgIGNvbnN0IG1vdmVkRGlzdGFuY2VTcSA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgICAgY29uc3QgZHVyYXRpb25NcyA9IERhdGUubm93KCkgLSBzdGFydC5hdDtcbiAgICAgIGNvbnN0IGlzTGlrZWx5VGFwID0gbW92ZWREaXN0YW5jZVNxIDw9IDE0ICogMTQgJiYgZHVyYXRpb25NcyA8PSA1NTA7XG4gICAgICBpZiAoIWlzTGlrZWx5VGFwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY3VycmVudENsaWNrUG9pbnRzID0gQ2xpY2tQb2ludHMgPz8gW107XG4gICAgICBpZiAocG9pbnRJc0luQmxvY2tlZFNlbGVjdGlvblJlY3QoZW5kWCwgZW5kWSkpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGBbVm9pY2VdIHdlYiB0YXAgaWdub3JlZCBhdCAoJHtlbmRYfSwgJHtlbmRZfSk7IG92ZXJsYXBzIHZvaWNlIFVJIG9jY2x1c2lvbiB6b25lYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgW1ZvaWNlXSB3ZWIgdGFwIGNhcHR1cmVkIGF0ICgke2VuZFh9LCAke2VuZFl9KTsgcHJldmlvdXMgdGFwcz0ke2N1cnJlbnRDbGlja1BvaW50cy5sZW5ndGh9YCxcbiAgICAgICk7XG4gICAgICBibG9ja2VkT3ZlcmxheVRhcFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBjdXJyZW50Q2xpY2tQb2ludHMucHVzaCh7IHg6IGVuZFgsIHk6IGVuZFkgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGhhbmRsZVBvaW50ZXJDYW5jZWwgPSAoKSA9PiB7XG4gICAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBibG9ja2VkT3ZlcmxheVRhcFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgIH07XG5cbiAgICBjb25zdCBvcHRpb25zID0geyBwYXNzaXZlOiB0cnVlLCBjYXB0dXJlOiB0cnVlIH0gYXMgQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnM7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJkb3duXCIsIGhhbmRsZVBvaW50ZXJEb3duLCBvcHRpb25zKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcnVwXCIsIGhhbmRsZVBvaW50ZXJVcCwgb3B0aW9ucyk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJjYW5jZWxcIiwgaGFuZGxlUG9pbnRlckNhbmNlbCwgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJkb3duXCIsIGhhbmRsZVBvaW50ZXJEb3duLCBvcHRpb25zKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgaGFuZGxlUG9pbnRlclVwLCBvcHRpb25zKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVyY2FuY2VsXCIsIGhhbmRsZVBvaW50ZXJDYW5jZWwsIG9wdGlvbnMpO1xuICAgICAgdG91Y2hTdGFydFBvaW50UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgYmxvY2tlZE92ZXJsYXlUYXBSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgc2V0SXNQcmVzc2VkKGZhbHNlKTtcbiAgICB9O1xuICB9LCBbbGlzdGVuZXJTdGF0ZSwgcG9pbnRJc0luQmxvY2tlZFNlbGVjdGlvblJlY3RdKTtcblxuICAvKipcbiAgICogSGFuZGxlIHByZXNzIGV2ZW50cyBvbiBvdmVybGF5IChjbGlja3MvdG91Y2hlcylcbiAgICogRXh0cmFjdHMgY29vcmRpbmF0ZXMgZm9yIHNwYXRpYWwgaW50ZXJhY3Rpb25cbiAgICovXG4gIGNvbnN0IGhhbmRsZU92ZXJsYXlQcmVzcyA9IHVzZUNhbGxiYWNrKChldmVudDogUGxhdGZvcm1QcmVzc0V2ZW50KSA9PiB7XG4gICAgaWYgKFBsYXRmb3JtLk9TID09PSBcIndlYlwiKSB7XG4gICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgICAgY29uc3QgYmxvY2tlZFRhcCA9IGJsb2NrZWRPdmVybGF5VGFwUmVmLmN1cnJlbnQ7XG4gICAgICBibG9ja2VkT3ZlcmxheVRhcFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBpZiAobGlzdGVuZXJTdGF0ZSA9PT0gTGlzdGVuZXJTdGF0ZS5MaXN0ZW5pbmcgJiYgYmxvY2tlZFRhcCkge1xuICAgICAgICBoYW5kbGVNaWNyb3Bob25lUHJlc3NSZWYuY3VycmVudD8uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGlzdGVuaW5nID0gbGlzdGVuZXJTdGF0ZSA9PT0gTGlzdGVuZXJTdGF0ZS5MaXN0ZW5pbmc7XG4gICAgY29uc3Qgc3RhcnQgPSB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudDtcbiAgICB0b3VjaFN0YXJ0UG9pbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgc2V0SXNQcmVzc2VkKGZhbHNlKTtcbiAgICBpZiAoIWxpc3RlbmluZyB8fCAhc3RhcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb29yZHM6IENvb3JkaW5hdGVzID0gZ2V0Q29vcmRpbmF0ZXMoZXZlbnQpO1xuICAgIGNvbnN0IGR4ID0gY29vcmRzLnggLSBzdGFydC54O1xuICAgIGNvbnN0IGR5ID0gY29vcmRzLnkgLSBzdGFydC55O1xuICAgIGNvbnN0IG1vdmVkRGlzdGFuY2VTcSA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBEYXRlLm5vdygpIC0gc3RhcnQuYXQ7XG4gICAgY29uc3QgaXNMaWtlbHlUYXAgPSBtb3ZlZERpc3RhbmNlU3EgPD0gMTQgKiAxNCAmJiBkdXJhdGlvbk1zIDw9IDU1MDtcbiAgICBpZiAoIWlzTGlrZWx5VGFwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudENsaWNrUG9pbnRzID0gQ2xpY2tQb2ludHMgPz8gW107XG4gICAgaWYgKHBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0KGNvb3Jkcy54LCBjb29yZHMueSkpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYFtWb2ljZV0gb3ZlcmxheSB0YXAgaWdub3JlZCBhdCAoJHtjb29yZHMueH0sICR7Y29vcmRzLnl9KTsgb3ZlcmxhcHMgdm9pY2UgVUkgb2NjbHVzaW9uIHpvbmVgLFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYFtWb2ljZV0gb3ZlcmxheSB0YXAgY2FwdHVyZWQgYXQgKCR7Y29vcmRzLnh9LCAke2Nvb3Jkcy55fSk7IHByZXZpb3VzIHRhcHM9JHtjdXJyZW50Q2xpY2tQb2ludHMubGVuZ3RofWAsXG4gICAgKTtcbiAgICBjdXJyZW50Q2xpY2tQb2ludHMucHVzaChjb29yZHMpO1xuICB9LCBbbGlzdGVuZXJTdGF0ZSwgcG9pbnRJc0luQmxvY2tlZFNlbGVjdGlvblJlY3RdKTtcblxuICAvKipcbiAgICogSGFuZGxlIHByZXNzIGRvd24gb24gb3ZlcmxheVxuICAgKi9cbiAgY29uc3QgaGFuZGxlT3ZlcmxheVByZXNzRG93biA9IHVzZUNhbGxiYWNrKChldmVudDogUGxhdGZvcm1QcmVzc0V2ZW50KSA9PiB7XG4gICAgaWYgKFBsYXRmb3JtLk9TID09PSBcIndlYlwiKSB7XG4gICAgICBzZXRJc1ByZXNzZWQodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGxpc3RlbmVyU3RhdGUgPT09IExpc3RlbmVyU3RhdGUuTGlzdGVuaW5nKSB7XG4gICAgICAvLyBOYXRpdmUgbGlzdHMgZG8gbm90IGVtaXQgZnJlc2ggb25MYXlvdXQgY29vcmRpbmF0ZXMgd2hpbGUgc2Nyb2xsaW5nLCBzb1xuICAgICAgLy8gZm9yY2UgYSBtZWFzdXJlbWVudCBwYXNzIGF0IHByZXNzLWluIGJlZm9yZSBzdG9yaW5nIHRoZSB0YXAgcG9pbnQuXG4gICAgICBjb25zdCBjb29yZHM6IENvb3JkaW5hdGVzID0gZ2V0Q29vcmRpbmF0ZXMoZXZlbnQpO1xuICAgICAgaWYgKHBvaW50SXNJbkJsb2NrZWRTZWxlY3Rpb25SZWN0KGNvb3Jkcy54LCBjb29yZHMueSkpIHtcbiAgICAgICAgdG91Y2hTdGFydFBvaW50UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICBzZXRJc1ByZXNzZWQoZmFsc2UpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBSZWZyZXNoRGlzcGxheWVkSW5zdGFuY2VSZWN0cygpO1xuICAgICAgdG91Y2hTdGFydFBvaW50UmVmLmN1cnJlbnQgPSB7IHg6IGNvb3Jkcy54LCB5OiBjb29yZHMueSwgYXQ6IERhdGUubm93KCkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdG91Y2hTdGFydFBvaW50UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIH1cbiAgICBzZXRJc1ByZXNzZWQodHJ1ZSk7XG4gIH0sIFtsaXN0ZW5lclN0YXRlLCBwb2ludElzSW5CbG9ja2VkU2VsZWN0aW9uUmVjdF0pO1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgbWljcm9waG9uZSBidXR0b24gcHJlc3NcbiAgICogVG9nZ2xlcyBiZXR3ZWVuIGlkbGUgYW5kIGxpc3RlbmluZyBzdGF0ZXNcbiAgICovXG4gIGNvbnN0IGhhbmRsZU1pY3JvcGhvbmVQcmVzcyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoc3BlZWNoUmVjb2duaXRpb24uaXNQcm9jZXNzaW5nKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0lnbm9yaW5nIG1pY3JvcGhvbmUgdG9nZ2xlIHdoaWxlIHRyYW5zY3JpcHQgcHJvY2Vzc2luZyBpcyBhY3RpdmUnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3BlZWNoUmVjb2duaXRpb24uaXNMaXN0ZW5pbmcpIHtcbiAgICAgIGNvbnN0IHBhdXNlVGV4dCA9IGxhdGVzdFRyYW5zY3JpcHRSZWYuY3VycmVudC50cmltKCk7XG4gICAgICBpZiAocGF1c2VUZXh0KSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdTcGVlY2ggc3RhdGUgdG9nZ2xlZCB0bzogcGF1c2VkOyBwcm9jZXNzaW5nIGxhdGVzdCB0cmFuc2NyaXB0Jyk7XG4gICAgICAgIHByb2Nlc3NUcmFuc2NyaXB0KGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50LCBwYXVzZVRleHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3BlZWNoUmVjb2duaXRpb24uc3RvcExpc3RlbmluZygpO1xuICAgICAgICBiZWdpbkxhdGVGaW5hbEZhbGxiYWNrKCdNYW51YWwgbWljIHBhdXNlIHdpdGggZW1wdHkgdHJhbnNjcmlwdCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50ICs9IDE7XG4gICAgaWYgKGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudCkge1xuICAgICAgZmluaXNoVm9pY2VQaXBlbGluZSgnYWJvcnRlZCcsIHsgcmVhc29uOiAnbmV3X3Nlc3Npb25fc3RhcnRlZCcgfSk7XG4gICAgfVxuICAgIC8vIEdlbmVyYXRlIGEgdW5pcXVlIHBlci1pbnRlcmFjdGlvbiB0aHJlYWQgaWQgKHN0cmluZykgYW5kIGF0dGFjaCB0byBMTE0gbW9uaXRvclxuICAgIGNvbnN0IGludGVyYWN0aW9uSWQgPSBgaW50ZXJhY3Rpb24tJHthY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudH0tJHtEYXRlLm5vdygpfWA7XG4gICAgY29uc3QgdHVybklkID0gYHZvaWNlLXR1cm4tJHthY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudH0tJHtEYXRlLm5vdygpfWA7XG4gICAgYWN0aXZlVGhyZWFkSWRSZWYuY3VycmVudCA9IGludGVyYWN0aW9uSWQ7XG4gICAgYWN0aXZlVHVybklkUmVmLmN1cnJlbnQgPSB0dXJuSWQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1vbml0b3IgPSBnZXRMTE1Nb25pdG9yKCk7XG4gICAgICBtb25pdG9yLnNldFRocmVhZChpbnRlcmFjdGlvbklkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBpZ25vcmUgbW9uaXRvcmluZyBzZXR1cCBlcnJvcnNcbiAgICB9XG4gICAgY29uc3QgdGVsZW1ldHJ5QnJpZGdlID0gZ2V0Vm9pY2VQaXBlbGluZVRlbGVtZXRyeUJyaWRnZSgpO1xuICAgIGRpc3BsYXlPdXRjb21lUmVmLmN1cnJlbnQgPSAnbm90X2FwcGxpY2FibGUnO1xuICAgIGFjdGl2ZVZvaWNlUGlwZWxpbmVSZWYuY3VycmVudCA9XG4gICAgICB0ZWxlbWV0cnlCcmlkZ2U/LnN0YXJ0UGlwZWxpbmU/Lih7XG4gICAgICAgIHNlc3Npb25JZDogYWN0aXZlU2Vzc2lvbklkUmVmLmN1cnJlbnQsXG4gICAgICAgIHRocmVhZElkOiBhY3RpdmVUaHJlYWRJZFJlZi5jdXJyZW50LFxuICAgICAgICB0dXJuSWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgICBwcm92aWRlcjogcmVzb2x2ZWRTcGVlY2hDb25maWcucHJvdmlkZXIsXG4gICAgICAgIGxhbmd1YWdlOiByZXNvbHZlZFNwZWVjaExhbmd1YWdlLFxuICAgICAgICBwbGF0Zm9ybTogUGxhdGZvcm0uT1MsXG4gICAgICB9KSB8fCBudWxsO1xuICAgIGFjdGl2ZUxpc3RlbmluZ1N0YWdlUmVmLmN1cnJlbnQgPVxuICAgICAgYWN0aXZlVm9pY2VQaXBlbGluZVJlZi5jdXJyZW50Py5zdGFydFN0YWdlPy4oJ3N0dC5saXN0ZW4nLCB7XG4gICAgICAgIHNlc3Npb25faWQ6IGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50LFxuICAgICAgICB0aHJlYWRfaWQ6IGFjdGl2ZVRocmVhZElkUmVmLmN1cnJlbnQsXG4gICAgICAgIHR1cm5faWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgICBwcm92aWRlcjogcmVzb2x2ZWRTcGVlY2hDb25maWcucHJvdmlkZXIsXG4gICAgICB9KSB8fCBudWxsO1xuICAgIGZpbmFsaXplZFNlc3Npb25JZFJlZi5jdXJyZW50ID0gLTE7XG4gICAgYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgY2xlYXJMYXRlRmluYWxGYWxsYmFjaygpO1xuICAgIGNsZWFyU3BlZWNoUmVzcG9uc2VUaW1lb3V0KCk7XG4gICAgbGF0ZXN0VHJhbnNjcmlwdFJlZi5jdXJyZW50ID0gJyc7XG4gICAgbGF0ZXN0VHJhbnNsYXRpb25SZWYuY3VycmVudCA9ICcnO1xuICAgIGNvbnN0IGN1cnJlbnRDbGlja1BvaW50cyA9IENsaWNrUG9pbnRzID8/IFtdO1xuICAgIGlmIChjdXJyZW50Q2xpY2tQb2ludHMubGVuZ3RoID4gMCkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgW1ZvaWNlXSBjbGVhcmluZyAke2N1cnJlbnRDbGlja1BvaW50cy5sZW5ndGh9IHN0YWxlIHRhcChzKSBiZWZvcmUgc3RhcnRpbmcgbmV3IGxpc3RlbmluZyBzZXNzaW9uYCxcbiAgICAgICk7XG4gICAgICBjdXJyZW50Q2xpY2tQb2ludHMuc3BsaWNlKDAsIGN1cnJlbnRDbGlja1BvaW50cy5sZW5ndGgpO1xuICAgIH1cbiAgICBzcGVlY2hSZWNvZ25pdGlvbi5jbGVhclRyYW5zY3JpcHQoKTtcbiAgICBpZiAoaXNPcGVuQUlQcm92aWRlcikge1xuICAgICAgc2V0SXNPcGVuQUlTcGVlY2hSZWFkeShmYWxzZSk7XG4gICAgfVxuICAgIHNwZWVjaFJlY29nbml0aW9uLnN0YXJ0TGlzdGVuaW5nKCk7XG4gICAgbG9nZ2VyLmluZm8oYFNwZWVjaCBzZXNzaW9uIHN0YXJ0ZWQgKHNlc3Npb249JHthY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudH0pYCk7XG4gIH0sIFtcbiAgICBjbGVhckxhdGVGaW5hbEZhbGxiYWNrLFxuICAgIGNsZWFyU3BlZWNoUmVzcG9uc2VUaW1lb3V0LFxuICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUsXG4gICAgaXNPcGVuQUlQcm92aWRlcixcbiAgICBwcm9jZXNzVHJhbnNjcmlwdCxcbiAgICByZXNvbHZlZFNwZWVjaENvbmZpZy5wcm92aWRlcixcbiAgICByZXNvbHZlZFNwZWVjaExhbmd1YWdlLFxuICAgIHNwZWVjaFJlY29nbml0aW9uLFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGhhbmRsZU1pY3JvcGhvbmVQcmVzc1JlZi5jdXJyZW50ID0gaGFuZGxlTWljcm9waG9uZVByZXNzO1xuICB9LCBbaGFuZGxlTWljcm9waG9uZVByZXNzXSk7XG5cbiAgLyoqXG4gICAqIFNwZWVjaCByZWNvZ25pdGlvbiBzdGF0dXMgY2FsbGJhY2tcbiAgICovXG4gIGNvbnN0IGhhbmRsZVNwZWVjaFN0YXR1cyA9IHVzZUNhbGxiYWNrKChzdGF0dXM6IGJvb2xlYW4sIGludGVyaW06IHN0cmluZykgPT4ge1xuICAgIGlmICghYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYuY3VycmVudCB8fCBpc1Byb2Nlc3NpbmdUcmFuc2NyaXB0UmVmLmN1cnJlbnQpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW1ZvaWNlXSBJZ25vcmluZyBzcGVlY2ggc3RhdHVzIHVwZGF0ZSAoc3RhdHVzPSR7c3RhdHVzfSkgd2hpbGUgc2Vzc2lvbiBsb2NrZWRgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoYFtWb2ljZV0gU3BlZWNoIHN0YXR1czogJHtzdGF0dXN9IChpbnRlcmltIGxlbmd0aD0ke2ludGVyaW0ubGVuZ3RofSlgKTtcblxuICAgIGlmIChzdGF0dXMgJiYgbGF0ZXN0VHJhbnNsYXRpb25SZWYuY3VycmVudCkge1xuICAgICAgbGF0ZXN0VHJhbnNsYXRpb25SZWYuY3VycmVudCA9ICcnO1xuICAgIH1cblxuICAgIGNvbnN0IHRyaW1tZWQgPSBpbnRlcmltLnRyaW0oKTtcbiAgICBpZiAodHJpbW1lZCAhPT0gJycgJiYgdHJpbW1lZCAhPT0gbGF0ZXN0VHJhbnNjcmlwdFJlZi5jdXJyZW50KSB7XG4gICAgICBsb2dnZXIuZGVidWcoYFtWb2ljZV0gJHtzdGF0dXMgPyAnSW50ZXJpbScgOiAnRmluYWwnfSB0cmFuc2NyaXB0OiAke3RyaW1tZWR9YCk7XG4gICAgICBzcGVlY2hSZWNvZ25pdGlvbi5zZXRJbnRlcmltVHJhbnNjcmlwdCh0cmltbWVkKTtcbiAgICAgIGxhdGVzdFRyYW5zY3JpcHRSZWYuY3VycmVudCA9IHRyaW1tZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFzdGF0dXMpIHtcbiAgICAgIGNvbnN0IHBhdXNlVGV4dCA9IGxhdGVzdFRyYW5zY3JpcHRSZWYuY3VycmVudC50cmltKCk7XG4gICAgICBpZiAocGF1c2VUZXh0KSB7XG4gICAgICAgIGNsZWFyTGF0ZUZpbmFsRmFsbGJhY2soKTtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1tWb2ljZV0gTWljIHBhdXNlIGRldGVjdGVkOyBwcm9jZXNzaW5nIGxhdGVzdCB0cmFuc2NyaXB0IGltbWVkaWF0ZWx5Jyk7XG4gICAgICAgIHByb2Nlc3NUcmFuc2NyaXB0KGFjdGl2ZVNlc3Npb25JZFJlZi5jdXJyZW50LCBwYXVzZVRleHQpO1xuICAgICAgfSBlbHNlIGlmIChpc09wZW5BSUF1dG9TdG9wRW5hYmxlZCkge1xuICAgICAgICAvLyBSZWYtZmlyc3QgYXV0by1zdG9wIHBhdGg6IGRvIG5vdCB3YWl0IGZvciBmaW5hbCBjYWxsYmFja3MuXG4gICAgICAgIHNwZWVjaFJlY29nbml0aW9uLnN0b3BMaXN0ZW5pbmcoKTtcbiAgICAgICAgY2xlYXJMYXRlRmluYWxGYWxsYmFjaygpO1xuICAgICAgICBhY2NlcHRpbmdTcGVlY2hJbnB1dFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIGZpbmlzaExpc3RlbmluZ1N0YWdlKCdjYW5jZWxsZWQnLCB7IHJlYXNvbjogJ2VtcHR5X3BhdXNlX2F1dG9fc3RvcCcgfSk7XG4gICAgICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUoJ2Fib3J0ZWQnLCB7IHJlYXNvbjogJ2VtcHR5X3BhdXNlX2F1dG9fc3RvcCcgfSk7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdbVm9pY2VdIFZBRCBzaWxlbmNlIHBhdXNlIHdpdGggZW1wdHkgcmVmIHRyYW5zY3JpcHQ7IHN0b3AgZmluYWxpemVkIHdpdGhvdXQgd2FpdGluZyBmb3IgZmluYWwgY2FsbGJhY2snKTtcbiAgICAgIH0gZWxzZSBpZiAoYXdhaXRpbmdMYXRlRmluYWxBZnRlclBhdXNlUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdbVm9pY2VdIE1pYyBwYXVzZSByZWNlaXZlZCB3aXRoIGVtcHR5IHRyYW5zY3JpcHQ7IGF3YWl0aW5nIGxhdGUgZmluYWwgY2FsbGJhY2snKTtcbiAgICAgIH0gZWxzZSBpZiAoIXNwZWVjaFJlY29nbml0aW9uLmlzTGlzdGVuaW5nKSB7XG4gICAgICAgIGFjY2VwdGluZ1NwZWVjaElucHV0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgZmluaXNoTGlzdGVuaW5nU3RhZ2UoJ2NhbmNlbGxlZCcsIHsgcmVhc29uOiAncGF1c2Vfd2l0aG91dF90cmFuc2NyaXB0JyB9KTtcbiAgICAgICAgZmluaXNoVm9pY2VQaXBlbGluZSgnYWJvcnRlZCcsIHsgcmVhc29uOiAncGF1c2Vfd2l0aG91dF90cmFuc2NyaXB0JyB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtcbiAgICBjbGVhckxhdGVGaW5hbEZhbGxiYWNrLFxuICAgIGZpbmlzaExpc3RlbmluZ1N0YWdlLFxuICAgIGZpbmlzaFZvaWNlUGlwZWxpbmUsXG4gICAgaXNPcGVuQUlBdXRvU3RvcEVuYWJsZWQsXG4gICAgcHJvY2Vzc1RyYW5zY3JpcHQsXG4gICAgc3BlZWNoUmVjb2duaXRpb24sXG4gIF0pO1xuXG4gIC8qKlxuICAgKiBTcGVlY2ggcmVjb2duaXRpb24gdHJhbnNsYXRpb24gY2FsbGJhY2tcbiAgICovXG4gIGNvbnN0IGhhbmRsZVNwZWVjaFRyYW5zbGF0aW9uID0gdXNlQ2FsbGJhY2soKHRyYW5zbGF0aW9uOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCB0cmltbWVkID0gdHJhbnNsYXRpb24udHJpbSgpO1xuICAgIGlmICghdHJpbW1lZCkgcmV0dXJuO1xuICAgIGxhdGVzdFRyYW5zbGF0aW9uUmVmLmN1cnJlbnQgPSB0cmltbWVkO1xuICB9LCBbXSk7XG5cbiAgLyoqXG4gICAqIFNwZWVjaCByZWNvZ25pdGlvbiByZXN1bHQgY2FsbGJhY2tcbiAgICovXG4gIGNvbnN0IGhhbmRsZVNwZWVjaFJlc3VsdCA9IHVzZUNhbGxiYWNrKChmaW5hbFRyYW5zY3JpcHQ6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBmaW5hbFRyYW5zY3JpcHQudHJpbSgpO1xuICAgIGlmICghdHJpbW1lZCkgcmV0dXJuO1xuICAgIGlmIChcbiAgICAgICghYWNjZXB0aW5nU3BlZWNoSW5wdXRSZWYuY3VycmVudCAmJiAhYXdhaXRpbmdMYXRlRmluYWxBZnRlclBhdXNlUmVmLmN1cnJlbnQpIHx8XG4gICAgICBpc1Byb2Nlc3NpbmdUcmFuc2NyaXB0UmVmLmN1cnJlbnRcbiAgICApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnW1ZvaWNlXSBJZ25vcmluZyBmaW5hbCB0cmFuc2NyaXB0IHdoaWxlIHNlc3Npb24gbG9ja2VkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRmFzdC1wYXRoIGNvbnRyYWN0OiBwYXJzaW5nIG9ubHkgb2NjdXJzIG9uIG1pYyBwYXVzZSAoc3RhdHVzPWZhbHNlIG9yIG1hbnVhbCBzdG9wKS5cbiAgICAvLyBGaW5hbCBjYWxsYmFja3Mgb25seSByZWZyZXNoIHRoZSBsYXRlc3QgY2FuZGlkYXRlIHRyYW5zY3JpcHQuXG4gICAgbG9nZ2VyLmRlYnVnKCdbVm9pY2VdIEZpbmFsIHRyYW5zY3JpcHQgcmVjZWl2ZWQ7IGJ1ZmZlcmVkIHVudGlsIG1pYyBwYXVzZScpO1xuICAgIHNwZWVjaFJlY29nbml0aW9uLnNldEludGVyaW1UcmFuc2NyaXB0KHRyaW1tZWQpO1xuICAgIGxhdGVzdFRyYW5zY3JpcHRSZWYuY3VycmVudCA9IHRyaW1tZWQ7XG4gICAgYWN0aXZlVm9pY2VQaXBlbGluZVJlZi5jdXJyZW50Py5hbm5vdGF0ZT8uKHtcbiAgICAgIGxhdGVzdF90cmFuc2NyaXB0X2xlbmd0aDogdHJpbW1lZC5sZW5ndGgsXG4gICAgICB0aHJlYWRfaWQ6IGFjdGl2ZVRocmVhZElkUmVmLmN1cnJlbnQsXG4gICAgICBzZXNzaW9uX2lkOiBhY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudCxcbiAgICAgIHR1cm5faWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgIH0pO1xuXG4gICAgaWYgKGF3YWl0aW5nTGF0ZUZpbmFsQWZ0ZXJQYXVzZVJlZi5jdXJyZW50KSB7XG4gICAgICBjbGVhckxhdGVGaW5hbEZhbGxiYWNrKCk7XG4gICAgICBsb2dnZXIuaW5mbygnW1ZvaWNlXSBMYXRlIGZpbmFsIHRyYW5zY3JpcHQgcmVjZWl2ZWQgYWZ0ZXIgbWljIHBhdXNlOyBwcm9jZXNzaW5nIG5vdycpO1xuICAgICAgcHJvY2Vzc1RyYW5zY3JpcHQoYWN0aXZlU2Vzc2lvbklkUmVmLmN1cnJlbnQsIHRyaW1tZWQpO1xuICAgIH1cbiAgfSwgW2NsZWFyTGF0ZUZpbmFsRmFsbGJhY2ssIHByb2Nlc3NUcmFuc2NyaXB0LCBzcGVlY2hSZWNvZ25pdGlvbl0pO1xuXG4gIC8qKlxuICAgKiBXYXZlZm9ybSBjYWxsYmFjayBmb3IgbWljLWJ1dHRvbiB2aXN1YWxpemF0aW9uLlxuICAgKi9cbiAgY29uc3QgaGFuZGxlV2F2ZWZvcm1QcmV2aWV3ID0gdXNlQ2FsbGJhY2soKHdhdmVmb3JtOiBudW1iZXJbXSkgPT4ge1xuICAgIHNwZWVjaFJlY29nbml0aW9uLnNldFdhdmVmb3JtUHJldmlldyh3YXZlZm9ybSk7XG4gIH0sIFtzcGVlY2hSZWNvZ25pdGlvbi5zZXRXYXZlZm9ybVByZXZpZXddKTtcblxuICBjb25zdCBoYW5kbGVTcGVlY2hSZWFkeSA9IHVzZUNhbGxiYWNrKChyZWFkeTogYm9vbGVhbikgPT4ge1xuICAgIGlmICghaXNPcGVuQUlQcm92aWRlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRJc09wZW5BSVNwZWVjaFJlYWR5KHJlYWR5KTtcbiAgfSwgW2lzT3BlbkFJUHJvdmlkZXJdKTtcblxuICBjb25zdCBnZXRTcGVlY2hSZXF1ZXN0Q29udGV4dCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCB0cmFjZUhlYWRlcnMgPSBhY3RpdmVWb2ljZVBpcGVsaW5lUmVmLmN1cnJlbnQ/LmdldFJlcXVlc3RIZWFkZXJzPy4oKSB8fCB7fTtcbiAgICByZXR1cm4ge1xuICAgICAgdGhyZWFkSWQ6IGFjdGl2ZVRocmVhZElkUmVmLmN1cnJlbnQsXG4gICAgICB0dXJuSWQ6IGFjdGl2ZVR1cm5JZFJlZi5jdXJyZW50LFxuICAgICAgc2Vzc2lvbklkOiBhY3RpdmVTZXNzaW9uSWRSZWYuY3VycmVudCxcbiAgICAgIHNlbnRyeVRyYWNlOiB0cmFjZUhlYWRlcnNbXCJzZW50cnktdHJhY2VcIl0sXG4gICAgICBiYWdnYWdlOiB0cmFjZUhlYWRlcnMuYmFnZ2FnZSxcbiAgICB9O1xuICB9LCBbXSk7XG5cbiAgLy8gPT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PVxuXG4gIGNvbnN0IGlzT3ZlcmxheVZpc2libGUgPVxuICAgIGlzTGlzdGVuaW5nRm9yVWkgfHxcbiAgICBsaXN0ZW5lclN0YXRlID09PSBMaXN0ZW5lclN0YXRlLlByb2Nlc3Npbmc7XG5cbiAgY29uc3QgaXNQcm9jZXNzaW5nID0gbGlzdGVuZXJTdGF0ZSA9PT0gTGlzdGVuZXJTdGF0ZS5Qcm9jZXNzaW5nO1xuICBjb25zdCBpc0xpc3RlbmluZyA9IGlzTGlzdGVuaW5nRm9yVWk7XG4gIGNvbnN0IG1pY0J1dHRvbkNvbG9yID0gaXNMaXN0ZW5pbmcgPyAnIzAwMDBmZicgOiAnI2NjY2NjYyc7XG5cbiAgLy8gbG9nZ2VyLmluZm8oJ3ZvaWNlTWVzc2FnZTonLCB2b2ljZU1lc3NhZ2UpO1xuICByZXR1cm4gKFxuICAgIDxWaWV3IHN0eWxlPXt7IGZsZXg6IDEgfX0+XG4gICAgICB7LyogTWFpbiBHVUkgKi99XG4gICAgICB7Z3VpfVxuICAgICAgPFRvYXN0ZXIgLz5cblxuICAgICAgey8qIE92ZXJsYXkgZm9yIGxpc3RlbmluZy9wcm9jZXNzaW5nIHN0YXRlcyAoYmFja3dhcmQgY29tcGF0aWJpbGl0eSkgKi99XG4gICAgICA8UGxhdGZvcm1PdmVybGF5XG4gICAgICAgIHZpc2libGU9e2lzT3ZlcmxheVZpc2libGV9XG4gICAgICAgIG9uUHJlc3M9e2hhbmRsZU92ZXJsYXlQcmVzc31cbiAgICAgICAgb25QcmVzc0Rvd249e2hhbmRsZU92ZXJsYXlQcmVzc0Rvd259XG4gICAgICAgIGludGVyYWN0aXZlXG4gICAgICAgIGJhY2tncm91bmRDb2xvcj17aXNQcmVzc2VkID8gJ3JnYmEoMTI3LCAxMjcsIDEyNywgMC41KScgOiAncmdiYSgyMDQsIDIwNCwgMjA0LCAwLjUpJ31cbiAgICAgICAgb3BhY2l0eT17MC41fVxuICAgICAgICBpc1Byb2Nlc3Npbmc9e2lzUHJvY2Vzc2luZ31cbiAgICAgICAgaXNMaXN0ZW5pbmc9e2lzTGlzdGVuaW5nfVxuICAgICAgICBhdWRpb0xldmVsPXtzcGVlY2hSZWNvZ25pdGlvbi5hdWRpb0xldmVsfVxuICAgICAgICB0cmFuc2NyaXB0VGV4dD17c3BlZWNoUmVjb2duaXRpb24uaW50ZXJpbVRyYW5zY3JpcHR9XG4gICAgICAgIHNob3dUcmFuc2NyaXB0PXtmYWxzZX0gLy8gRGlzYWJsZWQgaW4gZmF2b3Igb2YgVm9pY2VSZWNvZ25pdGlvbkJhclxuICAgICAgICBzaG93QXVkaW9WaXN1YWxpemVyPXtmYWxzZX0gLy8gRGlzYWJsZWQgaW4gZmF2b3Igb2YgVm9pY2VSZWNvZ25pdGlvbkJhclxuICAgICAgLz5cblxuICAgICAgey8qIE9wdGlvbmFsIEZsb2F0aW5nIE1pY3JvcGhvbmUgQnV0dG9uIChiYWNrd2FyZCBjb21wYXRpYmlsaXR5KSAqL31cbiAgICAgIHtzaG93RmxvYXRpbmdNaWNCdXR0b24gJiYgKFxuICAgICAgICA8UGxhdGZvcm1CdXR0b25cbiAgICAgICAgICBvblByZXNzPXtoYW5kbGVNaWNyb3Bob25lUHJlc3N9XG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yPXttaWNCdXR0b25Db2xvcn1cbiAgICAgICAgICBzaXplPXs1MH1cbiAgICAgICAgICBkaXNhYmxlZD17aXNQcm9jZXNzaW5nfVxuICAgICAgICA+XG4gICAgICAgICAgPElvbmljb25zIFxuICAgICAgICAgICAgbmFtZT17aXNMaXN0ZW5pbmcgPyBcIm1pY1wiIDogXCJtaWMtb3V0bGluZVwifSBcbiAgICAgICAgICAgIHNpemU9ezI4fSBcbiAgICAgICAgICAgIGNvbG9yPVwiI2ZmZmZmZlwiIFxuICAgICAgICAgIC8+XG4gICAgICAgIDwvUGxhdGZvcm1CdXR0b24+XG4gICAgICApfVxuXG4gICAgICB7LyogTmV3IFZvaWNlIFJlY29nbml0aW9uIEJhciAoZGVmYXVsdCBvciBjdXN0b20pICovfVxuICAgICAge1BsYXRmb3JtLk9TID09PSAnd2ViJyA/IChcbiAgICAgICAgPFZpZXdcbiAgICAgICAgICB0ZXN0SUQ9e1ZPSUNFX1VJX09DQ0xVU0lPTl9URVNUX0lEfVxuICAgICAgICAgIG9uTGF5b3V0PXtoYW5kbGVWb2ljZVVpTGF5b3V0fVxuICAgICAgICAgIGNvbGxhcHNhYmxlPXtmYWxzZX1cbiAgICAgICAgICBwb2ludGVyRXZlbnRzPVwiYm94LW5vbmVcIlxuICAgICAgICA+XG4gICAgICAgICAgPFZvaWNlVUlDb21wb25lbnRcbiAgICAgICAgICAgIHN0YXRlPXtzcGVlY2hSZWNvZ25pdGlvbi5zdGF0ZX1cbiAgICAgICAgICAgIGlzTGlzdGVuaW5nPXtpc0xpc3RlbmluZ0ZvclVpfVxuICAgICAgICAgICAgaXNDb25uZWN0aW5nPXtpc0Nvbm5lY3Rpbmd9XG4gICAgICAgICAgICBpc1Byb2Nlc3Npbmc9e3NwZWVjaFJlY29nbml0aW9uLmlzUHJvY2Vzc2luZ31cbiAgICAgICAgICAgIGludGVyaW1UcmFuc2NyaXB0PXtzcGVlY2hSZWNvZ25pdGlvbi5pbnRlcmltVHJhbnNjcmlwdH1cbiAgICAgICAgICAgIHRyYW5zY3JpcHQ9e3NwZWVjaFJlY29nbml0aW9uLnRyYW5zY3JpcHR9XG4gICAgICAgICAgICBhdWRpb0xldmVsPXtzcGVlY2hSZWNvZ25pdGlvbi5hdWRpb0xldmVsfVxuICAgICAgICAgICAgd2F2ZWZvcm1QcmV2aWV3PXtzcGVlY2hSZWNvZ25pdGlvbi53YXZlZm9ybVByZXZpZXd9XG4gICAgICAgICAgICBvblRvZ2dsZT17aGFuZGxlTWljcm9waG9uZVByZXNzfVxuICAgICAgICAgICAgc2hvd1RyYW5zY3JpcHQ9e2Rpc3BsYXlUcmFuc2NyaXB0fVxuICAgICAgICAgICAgcGxhY2Vob2xkZXJUZXh0PXt2b2ljZVBsYWNlaG9sZGVyfVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvVmlldz5cbiAgICAgICkgOiAoXG4gICAgICAgIDxWb2ljZVVJQ29tcG9uZW50XG4gICAgICAgICAgc3RhdGU9e3NwZWVjaFJlY29nbml0aW9uLnN0YXRlfVxuICAgICAgICAgIGlzTGlzdGVuaW5nPXtpc0xpc3RlbmluZ0ZvclVpfVxuICAgICAgICAgIGlzQ29ubmVjdGluZz17aXNDb25uZWN0aW5nfVxuICAgICAgICAgIGlzUHJvY2Vzc2luZz17c3BlZWNoUmVjb2duaXRpb24uaXNQcm9jZXNzaW5nfVxuICAgICAgICAgIGludGVyaW1UcmFuc2NyaXB0PXtzcGVlY2hSZWNvZ25pdGlvbi5pbnRlcmltVHJhbnNjcmlwdH1cbiAgICAgICAgICB0cmFuc2NyaXB0PXtzcGVlY2hSZWNvZ25pdGlvbi50cmFuc2NyaXB0fVxuICAgICAgICAgIGF1ZGlvTGV2ZWw9e3NwZWVjaFJlY29nbml0aW9uLmF1ZGlvTGV2ZWx9XG4gICAgICAgICAgd2F2ZWZvcm1QcmV2aWV3PXtzcGVlY2hSZWNvZ25pdGlvbi53YXZlZm9ybVByZXZpZXd9XG4gICAgICAgICAgb25Ub2dnbGU9e2hhbmRsZU1pY3JvcGhvbmVQcmVzc31cbiAgICAgICAgICBzaG93VHJhbnNjcmlwdD17ZGlzcGxheVRyYW5zY3JpcHR9XG4gICAgICAgICAgcGxhY2Vob2xkZXJUZXh0PXt2b2ljZVBsYWNlaG9sZGVyfVxuICAgICAgICAvPlxuICAgICAgKX1cblxuICAgICAgey8qIFNwZWVjaCBSZWNvZ25pdGlvbiBDb21wb25lbnQgKi99XG4gICAgICA8VW5pZmllZFNwZWVjaFJlY29nbml6ZXJcbiAgICAgICAgc2hvdWxkTGlzdGVuPXtsaXN0ZW5lclN0YXRlID09PSBMaXN0ZW5lclN0YXRlLkxpc3RlbmluZ31cbiAgICAgICAgc3BlZWNoU3RhdHVzQ2FsbGJhY2s9e2hhbmRsZVNwZWVjaFN0YXR1c31cbiAgICAgICAgc3BlZWNoUmVzdWx0Q2FsbGJhY2s9e2hhbmRsZVNwZWVjaFJlc3VsdH1cbiAgICAgICAgc3BlZWNoVHJhbnNsYXRpb25DYWxsYmFjaz17aGFuZGxlU3BlZWNoVHJhbnNsYXRpb259XG4gICAgICAgIHNwZWVjaFJlYWR5Q2FsbGJhY2s9e2hhbmRsZVNwZWVjaFJlYWR5fVxuICAgICAgICBjbGllbnRTZWNyZXQ9e2NsaWVudFNlY3JldH1cbiAgICAgICAgY29uZmlnPXtzcGVlY2hDb25maWd9XG4gICAgICAgIGxhbmd1YWdlPXtyZXNvbHZlZFNwZWVjaExhbmd1YWdlfVxuICAgICAgICByZXF1ZXN0Q29udGV4dFByb3ZpZGVyPXtnZXRTcGVlY2hSZXF1ZXN0Q29udGV4dH1cbiAgICAgICAgd2F2ZWZvcm1QcmV2aWV3Q2FsbGJhY2s9e2hhbmRsZVdhdmVmb3JtUHJldmlld31cbiAgICAgICAgb25FcnJvcj17KGVycm9yKSA9PlxuICAgICAgICAgIGxvZ2dlci5lcnJvcihcIlNwZWVjaCByZWNvZ25pdGlvbiBlcnJvciBhdCBtb2RhbGl0eSBwcm92aWRlclYyOlwiLCBlcnJvcilcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gZW5hYmxlVkFEPXt0cnVlfVxuICAgICAgICAvLyBzaWxlbmNlVGhyZXNob2xkPXsxMH1cbiAgICAgICAgLy8gc2lsZW5jZUR1cmF0aW9uPXsxNTAwfVxuICAgICAgLz5cblxuICAgIDwvVmlldz5cbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IE1vZGFsaXR5UHJvdmlkZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQU1BLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFdBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFlBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLE9BQUEsR0FBQUgsT0FBQTtBQUtBLElBQUFJLE1BQUEsR0FBQUosT0FBQTtBQU1BLElBQUFLLFlBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLGFBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLGtCQUFBLEdBQUFQLE9BQUE7QUFFQSxJQUFBUSxjQUFBLEdBQUFSLE9BQUE7QUFhQSxJQUFBUyxnQkFBQSxHQUFBVCxPQUFBO0FBVUEsSUFBQVUsWUFBQSxHQUFBVixPQUFBO0FBT0EsSUFBQVcseUJBQUEsR0FBQVgsT0FBQTtBQUtBLElBQUFZLHFCQUFBLEdBQUFaLE9B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