@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.
- package/.env.example +22 -0
- package/.github/workflows/publish.yml +20 -0
- package/LICENSE.txt +201 -0
- package/README.md +621 -0
- package/babel.config.js +29 -0
- package/dist/adapters/__tests__/expo-router-adapter.test.d.ts +1 -0
- package/dist/adapters/expo-router-adapter.d.ts +16 -0
- package/dist/adapters/expo-router-adapter.js +521 -0
- package/dist/adapters/navigation-adapter.d.ts +20 -0
- package/dist/adapters/navigation-adapter.js +137 -0
- package/dist/audio-visualizer.d.ts +14 -0
- package/dist/audio-visualizer.js +123 -0
- package/dist/current-selection.d.ts +27 -0
- package/dist/current-selection.js +94 -0
- package/dist/errors.d.ts +19 -0
- package/dist/errors.js +37 -0
- package/dist/genie/DateTime.d.ts +66 -0
- package/dist/genie/DateTime.js +399 -0
- package/dist/genie/TimeDelta.d.ts +35 -0
- package/dist/genie/TimeDelta.js +169 -0
- package/dist/genie-view-wrapper.d.ts +1 -0
- package/dist/genie-view-wrapper.js +377 -0
- package/dist/hooks/__tests__/useSpeechRecognition.test.d.ts +1 -0
- package/dist/hooks/useSpeechRecognition.d.ts +28 -0
- package/dist/hooks/useSpeechRecognition.js +118 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +469 -0
- package/dist/logger.d.ts +23 -0
- package/dist/logger.js +597 -0
- package/dist/logger.remote.test.d.ts +0 -0
- package/dist/modality-provider-v2.d.ts +28 -0
- package/dist/modality-provider-v2.js +1321 -0
- package/dist/modality-provider.d.ts +22 -0
- package/dist/modality-provider.js +373 -0
- package/dist/native-visibility.d.ts +28 -0
- package/dist/native-visibility.js +50 -0
- package/dist/platform/VoiceRecognitionBar.d.ts +17 -0
- package/dist/platform/VoiceRecognitionBar.js +332 -0
- package/dist/platform/components.d.ts +32 -0
- package/dist/platform/components.js +351 -0
- package/dist/platform/events.d.ts +31 -0
- package/dist/platform/events.js +274 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +39 -0
- package/dist/platform/types.d.ts +79 -0
- package/dist/platform/types.js +97 -0
- package/dist/react-decorators.d.ts +87 -0
- package/dist/react-decorators.js +368 -0
- package/dist/shared-store.d.ts +74 -0
- package/dist/shared-store.js +589 -0
- package/dist/speech-recognition/__tests__/speech-recognition-groq-transport.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified-import.test.d.ts +0 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified.test.d.ts +1 -0
- package/dist/speech-recognition/speech-recognition-groq.d.ts +21 -0
- package/dist/speech-recognition/speech-recognition-groq.js +409 -0
- package/dist/speech-recognition/speech-recognition-mlx.d.ts +15 -0
- package/dist/speech-recognition/speech-recognition-mlx.js +393 -0
- package/dist/speech-recognition/speech-recognition-native.d.ts +24 -0
- package/dist/speech-recognition/speech-recognition-native.js +632 -0
- package/dist/speech-recognition/speech-recognition-openai-native.d.ts +40 -0
- package/dist/speech-recognition/speech-recognition-openai-native.js +653 -0
- package/dist/speech-recognition/speech-recognition-openai.d.ts +39 -0
- package/dist/speech-recognition/speech-recognition-openai.js +718 -0
- package/dist/speech-recognition/speech-recognition-unified.d.ts +93 -0
- package/dist/speech-recognition/speech-recognition-unified.js +589 -0
- package/dist/speech-recognition/utils/groq-transcription.d.ts +41 -0
- package/dist/speech-recognition/utils/groq-transcription.js +382 -0
- package/dist/speech-recognition.d.ts +7 -0
- package/dist/speech-recognition.js +61 -0
- package/dist/voice-pipeline-telemetry.d.ts +26 -0
- package/dist/voice-pipeline-telemetry.js +15 -0
- package/garrix82-reactgenie-lib-1.3.0.tgz +0 -0
- package/metro/index.js +3 -0
- package/metro/with-genie-registry.js +47 -0
- package/package.json +111 -0
- package/scripts/dry-run.js +23 -0
- package/scripts/generate-genie-registry.js +278 -0
- package/scripts/log-file-test.js +51 -0
- package/scripts/parse.js +26 -0
- package/scripts/prompt.js +19 -0
- package/scripts/set-script.js +200 -0
- package/tsconfig.json +36 -0
package/dist/logger.js
ADDED
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.configureLogger = configureLogger;
|
|
7
|
+
exports.logger = exports.default = void 0;
|
|
8
|
+
exports.setLogLevel = setLogLevel;
|
|
9
|
+
exports.setLoggerTelemetryBridge = setLoggerTelemetryBridge;
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
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; }
|
|
12
|
+
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; }
|
|
13
|
+
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; }
|
|
14
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
15
|
+
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); } // Environment-aware logger utility
|
|
16
|
+
// Uses react-native-logs for React Native, winston for Node.js/web, console as fallback
|
|
17
|
+
// Determine environment first
|
|
18
|
+
// Treat Node as its own runtime even if react-native Platform.OS is ios/android in tests
|
|
19
|
+
const getRuntimeProcess = () => {
|
|
20
|
+
const globalObj = globalThis;
|
|
21
|
+
return globalObj?.process ?? null;
|
|
22
|
+
};
|
|
23
|
+
const isNodeEnvironment = Boolean(getRuntimeProcess()?.versions?.node);
|
|
24
|
+
const isReactNative = _reactNative.Platform.OS !== 'web' && !isNodeEnvironment;
|
|
25
|
+
const isWeb = _reactNative.Platform.OS === 'web';
|
|
26
|
+
|
|
27
|
+
// Try to require libraries based on environment
|
|
28
|
+
let rnLogs = null;
|
|
29
|
+
let winston = null;
|
|
30
|
+
|
|
31
|
+
// Only try to require react-native-logs in React Native environments
|
|
32
|
+
if (isReactNative) {
|
|
33
|
+
try {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
35
|
+
rnLogs = require('react-native-logs');
|
|
36
|
+
} catch (e) {
|
|
37
|
+
rnLogs = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// For winston, use runtime detection without static requires
|
|
42
|
+
const getWinston = () => {
|
|
43
|
+
if (winston !== null) return winston;
|
|
44
|
+
if (!isNodeEnvironment) return null;
|
|
45
|
+
try {
|
|
46
|
+
// Use eval to dynamically construct the require call
|
|
47
|
+
// This prevents static analysis from finding 'winston' in require()
|
|
48
|
+
const winstonModule = eval('require')('winston');
|
|
49
|
+
winston = winstonModule;
|
|
50
|
+
return winston;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
winston = null;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
// Read desired log level from env/config
|
|
57
|
+
function getDefaultLogLevel() {
|
|
58
|
+
const env = getRuntimeProcess()?.env ?? {};
|
|
59
|
+
const level = env.REACT_APP_LOG_LEVEL || env.EXPO_PUBLIC_LOG_LEVEL || env.LOG_LEVEL;
|
|
60
|
+
if (!level) return isNodeEnvironment || isWeb ? 'info' : 'warn';
|
|
61
|
+
const normalized = level.toLowerCase();
|
|
62
|
+
if (['error', 'warn', 'info', 'debug', 'silent'].includes(normalized)) {
|
|
63
|
+
return normalized;
|
|
64
|
+
}
|
|
65
|
+
return 'info';
|
|
66
|
+
}
|
|
67
|
+
let currentLevel = getDefaultLogLevel();
|
|
68
|
+
let runtimeLoggerConfig = {};
|
|
69
|
+
let loggerTelemetryBridge = null;
|
|
70
|
+
const pad2 = n => String(n).padStart(2, '0');
|
|
71
|
+
const formatLocalDate = (date = new Date()) => `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
72
|
+
const buildDailyFileName = (date = new Date()) => `logs-${formatLocalDate(date)}.log`;
|
|
73
|
+
const getEnvConfig = () => {
|
|
74
|
+
return getRuntimeProcess()?.env ?? {};
|
|
75
|
+
};
|
|
76
|
+
const isValidLogLevel = level => {
|
|
77
|
+
return typeof level === 'string' && ['error', 'warn', 'info', 'debug', 'silent'].includes(level);
|
|
78
|
+
};
|
|
79
|
+
const isFileLoggingEnabled = () => {
|
|
80
|
+
if (typeof runtimeLoggerConfig.enableFileLogging === 'boolean') {
|
|
81
|
+
return runtimeLoggerConfig.enableFileLogging;
|
|
82
|
+
}
|
|
83
|
+
const env = getEnvConfig();
|
|
84
|
+
const raw = env.REACT_APP_ENABLE_WINSTON_FILE || env.EXPO_PUBLIC_ENABLE_WINSTON_FILE || env.REACT_APP_ENABLE_FILE_LOGS || env.EXPO_PUBLIC_ENABLE_FILE_LOGS || env.LOG_FILE_ENABLED;
|
|
85
|
+
if (raw === undefined) return true;
|
|
86
|
+
return raw === 'true' || raw === '1';
|
|
87
|
+
};
|
|
88
|
+
const getConfiguredLogDir = () => {
|
|
89
|
+
if (runtimeLoggerConfig.logFileDir && runtimeLoggerConfig.logFileDir.trim()) {
|
|
90
|
+
return runtimeLoggerConfig.logFileDir;
|
|
91
|
+
}
|
|
92
|
+
const env = getEnvConfig();
|
|
93
|
+
return env.REACT_APP_LOG_FILE_DIR || env.EXPO_PUBLIC_LOG_FILE_DIR || env.LOG_FILE_DIR || '.';
|
|
94
|
+
};
|
|
95
|
+
const formatLogLine = (level, args) => {
|
|
96
|
+
const ts = new Date().toISOString();
|
|
97
|
+
const serialize = value => {
|
|
98
|
+
if (value instanceof Error) {
|
|
99
|
+
const stack = value.stack ? `\n${value.stack}` : '';
|
|
100
|
+
return `${value.message}${stack}`;
|
|
101
|
+
}
|
|
102
|
+
if (typeof value === 'string') return value;
|
|
103
|
+
try {
|
|
104
|
+
return JSON.stringify(value);
|
|
105
|
+
} catch {
|
|
106
|
+
return String(value);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const payload = args.map(serialize).join(' ');
|
|
110
|
+
return `${ts} [${level.toUpperCase()}] ${payload}\n`;
|
|
111
|
+
};
|
|
112
|
+
let fileSink = undefined;
|
|
113
|
+
let remoteSink = undefined;
|
|
114
|
+
const getConfiguredRemoteUrl = () => {
|
|
115
|
+
if (runtimeLoggerConfig.remoteUrl && runtimeLoggerConfig.remoteUrl.trim()) {
|
|
116
|
+
return runtimeLoggerConfig.remoteUrl;
|
|
117
|
+
}
|
|
118
|
+
const env = getEnvConfig();
|
|
119
|
+
return env.REACT_APP_LOG_REMOTE_URL || env.EXPO_PUBLIC_LOG_REMOTE_URL || env.LOG_REMOTE_URL || '';
|
|
120
|
+
};
|
|
121
|
+
const getConfiguredRemoteToken = () => {
|
|
122
|
+
if (runtimeLoggerConfig.remoteToken && runtimeLoggerConfig.remoteToken.trim()) {
|
|
123
|
+
return runtimeLoggerConfig.remoteToken;
|
|
124
|
+
}
|
|
125
|
+
const env = getEnvConfig();
|
|
126
|
+
return env.REACT_APP_LOG_INGEST_TOKEN || env.EXPO_PUBLIC_LOG_INGEST_TOKEN || env.LOG_INGEST_TOKEN || '';
|
|
127
|
+
};
|
|
128
|
+
const isRemoteLoggingEnabled = () => {
|
|
129
|
+
if (typeof runtimeLoggerConfig.remoteEnabled === 'boolean') {
|
|
130
|
+
return runtimeLoggerConfig.remoteEnabled && Boolean(getConfiguredRemoteUrl());
|
|
131
|
+
}
|
|
132
|
+
const remoteUrl = getConfiguredRemoteUrl();
|
|
133
|
+
if (!remoteUrl) return false;
|
|
134
|
+
const env = getEnvConfig();
|
|
135
|
+
const raw = env.REACT_APP_ENABLE_REMOTE_LOGS || env.EXPO_PUBLIC_ENABLE_REMOTE_LOGS || env.LOG_REMOTE_ENABLED;
|
|
136
|
+
if (raw === undefined) return true;
|
|
137
|
+
return raw === 'true' || raw === '1';
|
|
138
|
+
};
|
|
139
|
+
const serializeArgForJson = value => {
|
|
140
|
+
if (value instanceof Error) {
|
|
141
|
+
return {
|
|
142
|
+
name: value.name,
|
|
143
|
+
message: value.message,
|
|
144
|
+
stack: value.stack
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (value === null || value === undefined) return value;
|
|
148
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
|
|
149
|
+
try {
|
|
150
|
+
return JSON.parse(JSON.stringify(value));
|
|
151
|
+
} catch {
|
|
152
|
+
return String(value);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const buildRemotePayload = (level, args) => {
|
|
156
|
+
const normalizedArgs = args.map(arg => serializeArgForJson(arg));
|
|
157
|
+
const firstArg = normalizedArgs[0];
|
|
158
|
+
const message = typeof firstArg === 'string' ? firstArg : normalizedArgs.map(arg => typeof arg === 'string' ? arg : JSON.stringify(arg)).join(' ');
|
|
159
|
+
return {
|
|
160
|
+
timestamp: new Date().toISOString(),
|
|
161
|
+
level,
|
|
162
|
+
message: message || '[empty]',
|
|
163
|
+
source: isWeb ? 'web' : 'mobile',
|
|
164
|
+
runtime: isNodeEnvironment ? 'node' : 'client',
|
|
165
|
+
args: normalizedArgs
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
const buildTelemetryMessage = args => {
|
|
169
|
+
if (!Array.isArray(args) || args.length === 0) return "[empty]";
|
|
170
|
+
const [first] = args;
|
|
171
|
+
if (typeof first === "string" && first.trim()) return first;
|
|
172
|
+
return args.map(arg => {
|
|
173
|
+
if (arg instanceof Error) return arg.message;
|
|
174
|
+
if (typeof arg === "string") return arg;
|
|
175
|
+
try {
|
|
176
|
+
return JSON.stringify(arg);
|
|
177
|
+
} catch {
|
|
178
|
+
return String(arg);
|
|
179
|
+
}
|
|
180
|
+
}).join(" ").trim() || "[empty]";
|
|
181
|
+
};
|
|
182
|
+
const emitTelemetryBridge = (level, args) => {
|
|
183
|
+
if (!loggerTelemetryBridge) return;
|
|
184
|
+
const errorArg = args.find(arg => arg instanceof Error);
|
|
185
|
+
const context = {
|
|
186
|
+
level,
|
|
187
|
+
runtime: isNodeEnvironment ? "node" : isWeb ? "web" : "native"
|
|
188
|
+
};
|
|
189
|
+
if (errorArg && typeof loggerTelemetryBridge.captureException === "function") {
|
|
190
|
+
loggerTelemetryBridge.captureException(errorArg, context);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (typeof loggerTelemetryBridge.captureMessage === "function") {
|
|
194
|
+
loggerTelemetryBridge.captureMessage(buildTelemetryMessage(args), level, context);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const getRemoteSink = () => {
|
|
198
|
+
if (remoteSink !== undefined) return remoteSink ?? null;
|
|
199
|
+
if (!isRemoteLoggingEnabled()) {
|
|
200
|
+
remoteSink = null;
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
if (typeof fetch !== 'function') {
|
|
204
|
+
remoteSink = null;
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const url = getConfiguredRemoteUrl();
|
|
208
|
+
const token = getConfiguredRemoteToken();
|
|
209
|
+
let sendChain = Promise.resolve();
|
|
210
|
+
const sendOne = async (level, args) => {
|
|
211
|
+
const headers = {
|
|
212
|
+
'content-type': 'application/json'
|
|
213
|
+
};
|
|
214
|
+
if (token) {
|
|
215
|
+
headers['x-log-token'] = token;
|
|
216
|
+
}
|
|
217
|
+
const payload = buildRemotePayload(level, args);
|
|
218
|
+
await fetch(url, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
headers,
|
|
221
|
+
body: JSON.stringify(payload)
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
remoteSink = {
|
|
225
|
+
write: (level, args) => {
|
|
226
|
+
sendChain = sendChain.then(() => sendOne(level, args)).catch(() => {});
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
return remoteSink;
|
|
230
|
+
};
|
|
231
|
+
const invalidateDerivedLoggerState = () => {
|
|
232
|
+
fileSink = undefined;
|
|
233
|
+
remoteSink = undefined;
|
|
234
|
+
};
|
|
235
|
+
const getNodeFileSink = () => {
|
|
236
|
+
if (!isNodeEnvironment) return null;
|
|
237
|
+
let fs = null;
|
|
238
|
+
let path = null;
|
|
239
|
+
try {
|
|
240
|
+
fs = eval('require')('fs');
|
|
241
|
+
path = eval('require')('path');
|
|
242
|
+
} catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
let currentDate = '';
|
|
246
|
+
let filePath = '';
|
|
247
|
+
const ensureFilePath = () => {
|
|
248
|
+
const today = formatLocalDate(new Date());
|
|
249
|
+
if (today === currentDate && filePath) return;
|
|
250
|
+
currentDate = today;
|
|
251
|
+
const logDir = getConfiguredLogDir() || '.';
|
|
252
|
+
const cwd = getRuntimeProcess()?.cwd?.() ?? '.';
|
|
253
|
+
const resolvedDir = path.resolve(cwd, logDir);
|
|
254
|
+
if (!fs.existsSync(resolvedDir)) {
|
|
255
|
+
try {
|
|
256
|
+
fs.mkdirSync(resolvedDir, {
|
|
257
|
+
recursive: true
|
|
258
|
+
});
|
|
259
|
+
} catch {/* ignore */}
|
|
260
|
+
}
|
|
261
|
+
filePath = path.join(resolvedDir, buildDailyFileName(new Date()));
|
|
262
|
+
};
|
|
263
|
+
return {
|
|
264
|
+
write: (level, args) => {
|
|
265
|
+
try {
|
|
266
|
+
ensureFilePath();
|
|
267
|
+
fs.appendFile(filePath, formatLogLine(level, args), () => {});
|
|
268
|
+
} catch {
|
|
269
|
+
// ignore file logging errors
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
const getExpoFileSystem = () => {
|
|
275
|
+
try {
|
|
276
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
277
|
+
return require('expo-file-system/legacy');
|
|
278
|
+
} catch {
|
|
279
|
+
try {
|
|
280
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
281
|
+
return require('expo-file-system');
|
|
282
|
+
} catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const getExpoFileSink = () => {
|
|
288
|
+
const FileSystem = getExpoFileSystem();
|
|
289
|
+
if (!FileSystem || typeof FileSystem.writeAsStringAsync !== 'function') return null;
|
|
290
|
+
const baseDir = FileSystem.documentDirectory || FileSystem.cacheDirectory;
|
|
291
|
+
if (!baseDir) return null;
|
|
292
|
+
const encoding = FileSystem.EncodingType?.UTF8 ?? 'utf8';
|
|
293
|
+
const normalizeDir = dir => dir.replace(/\/?$/, '/');
|
|
294
|
+
const logDir = getConfiguredLogDir();
|
|
295
|
+
const subDir = logDir && logDir !== '.' ? logDir.replace(/^\.\/+/, '').replace(/\/+$/, '') : '';
|
|
296
|
+
const basePath = subDir ? `${normalizeDir(baseDir)}${subDir}/` : normalizeDir(baseDir);
|
|
297
|
+
let currentDate = '';
|
|
298
|
+
let fileUri = '';
|
|
299
|
+
let writeChain = Promise.resolve();
|
|
300
|
+
const ensureFileUri = async () => {
|
|
301
|
+
const today = formatLocalDate(new Date());
|
|
302
|
+
if (today === currentDate && fileUri) return;
|
|
303
|
+
currentDate = today;
|
|
304
|
+
fileUri = `${basePath}${buildDailyFileName(new Date())}`;
|
|
305
|
+
if (subDir) {
|
|
306
|
+
try {
|
|
307
|
+
await FileSystem.makeDirectoryAsync(basePath, {
|
|
308
|
+
intermediates: true
|
|
309
|
+
});
|
|
310
|
+
} catch {/* ignore */}
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
const info = await FileSystem.getInfoAsync(fileUri);
|
|
314
|
+
if (!info?.exists) {
|
|
315
|
+
await FileSystem.writeAsStringAsync(fileUri, '', {
|
|
316
|
+
encoding
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
try {
|
|
321
|
+
await FileSystem.writeAsStringAsync(fileUri, '', {
|
|
322
|
+
encoding
|
|
323
|
+
});
|
|
324
|
+
} catch {/* ignore */}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
const appendLine = async line => {
|
|
328
|
+
await ensureFileUri();
|
|
329
|
+
try {
|
|
330
|
+
await FileSystem.writeAsStringAsync(fileUri, line, {
|
|
331
|
+
encoding,
|
|
332
|
+
append: true
|
|
333
|
+
});
|
|
334
|
+
return;
|
|
335
|
+
} catch {
|
|
336
|
+
// fall through to read/append fallback
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
const existing = await FileSystem.readAsStringAsync(fileUri, {
|
|
340
|
+
encoding
|
|
341
|
+
});
|
|
342
|
+
await FileSystem.writeAsStringAsync(fileUri, `${existing}${line}`, {
|
|
343
|
+
encoding
|
|
344
|
+
});
|
|
345
|
+
} catch {
|
|
346
|
+
// ignore
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
return {
|
|
350
|
+
write: (level, args) => {
|
|
351
|
+
const line = formatLogLine(level, args);
|
|
352
|
+
writeChain = writeChain.then(() => appendLine(line)).catch(() => {});
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
};
|
|
356
|
+
const getFileSink = () => {
|
|
357
|
+
if (fileSink !== undefined) return fileSink ?? null;
|
|
358
|
+
if (!isFileLoggingEnabled()) {
|
|
359
|
+
fileSink = null;
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
const nodeSink = getNodeFileSink();
|
|
363
|
+
if (nodeSink) {
|
|
364
|
+
fileSink = nodeSink;
|
|
365
|
+
return nodeSink;
|
|
366
|
+
}
|
|
367
|
+
const expoSink = getExpoFileSink();
|
|
368
|
+
if (expoSink) {
|
|
369
|
+
fileSink = expoSink;
|
|
370
|
+
return expoSink;
|
|
371
|
+
}
|
|
372
|
+
fileSink = null;
|
|
373
|
+
return null;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// Create logger instance based on environment - LAZY LOADING
|
|
377
|
+
let rnLogger = null;
|
|
378
|
+
let winstonLogger = null;
|
|
379
|
+
|
|
380
|
+
// Lazy initialization functions
|
|
381
|
+
const getRnLogger = () => {
|
|
382
|
+
if (rnLogger !== null) return rnLogger;
|
|
383
|
+
if (!isReactNative || !rnLogs) return null;
|
|
384
|
+
try {
|
|
385
|
+
const {
|
|
386
|
+
logger: createLogger
|
|
387
|
+
} = rnLogs;
|
|
388
|
+
const config = {
|
|
389
|
+
severity: currentLevel,
|
|
390
|
+
transport: (msg, level, _options) => {
|
|
391
|
+
const prefix = `[${level.toUpperCase()}]`;
|
|
392
|
+
switch (level) {
|
|
393
|
+
case 'error':
|
|
394
|
+
// eslint-disable-next-line no-console
|
|
395
|
+
console.error(prefix, ...msg);
|
|
396
|
+
break;
|
|
397
|
+
case 'warn':
|
|
398
|
+
// eslint-disable-next-line no-console
|
|
399
|
+
console.warn(prefix, ...msg);
|
|
400
|
+
break;
|
|
401
|
+
case 'info':
|
|
402
|
+
// eslint-disable-next-line no-console
|
|
403
|
+
console.log(prefix, ...msg);
|
|
404
|
+
break;
|
|
405
|
+
case 'debug':
|
|
406
|
+
// eslint-disable-next-line no-console
|
|
407
|
+
console.debug ? console.debug(prefix, ...msg) : console.log(prefix, ...msg);
|
|
408
|
+
break;
|
|
409
|
+
default:
|
|
410
|
+
// eslint-disable-next-line no-console
|
|
411
|
+
console.log(prefix, ...msg);
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
transportOptions: {
|
|
415
|
+
colors: {
|
|
416
|
+
error: 'red',
|
|
417
|
+
warn: 'yellow',
|
|
418
|
+
info: 'blue',
|
|
419
|
+
debug: 'gray'
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
rnLogger = createLogger(config);
|
|
424
|
+
return rnLogger;
|
|
425
|
+
} catch (e) {
|
|
426
|
+
rnLogger = null;
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
const getWinstonLogger = () => {
|
|
431
|
+
if (winstonLogger !== null) return winstonLogger;
|
|
432
|
+
if (!isNodeEnvironment) return null;
|
|
433
|
+
const winston = getWinston();
|
|
434
|
+
if (!winston) return null;
|
|
435
|
+
try {
|
|
436
|
+
const {
|
|
437
|
+
createLogger,
|
|
438
|
+
format,
|
|
439
|
+
transports
|
|
440
|
+
} = winston;
|
|
441
|
+
const transportInstances = [new transports.Console({
|
|
442
|
+
level: currentLevel
|
|
443
|
+
})];
|
|
444
|
+
winstonLogger = createLogger({
|
|
445
|
+
level: currentLevel,
|
|
446
|
+
format: format.combine(format.timestamp(), format.errors({
|
|
447
|
+
stack: true
|
|
448
|
+
}), format.splat(), format.json()),
|
|
449
|
+
transports: transportInstances
|
|
450
|
+
});
|
|
451
|
+
return winstonLogger;
|
|
452
|
+
} catch (e) {
|
|
453
|
+
winstonLogger = null;
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
// Initialize RN logger immediately if in React Native
|
|
459
|
+
if (isReactNative) {
|
|
460
|
+
getRnLogger();
|
|
461
|
+
}
|
|
462
|
+
function setLogLevel(level) {
|
|
463
|
+
currentLevel = level;
|
|
464
|
+
// Update logger severity if available
|
|
465
|
+
const rnLogger = getRnLogger();
|
|
466
|
+
if (rnLogger && rnLogger.setSeverity) {
|
|
467
|
+
rnLogger.setSeverity(level);
|
|
468
|
+
}
|
|
469
|
+
const winstonLogger = getWinstonLogger();
|
|
470
|
+
if (winstonLogger) {
|
|
471
|
+
winstonLogger.level = level;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
function configureLogger(config = {}) {
|
|
475
|
+
runtimeLoggerConfig = _objectSpread(_objectSpread({}, runtimeLoggerConfig), config);
|
|
476
|
+
if (isValidLogLevel(config.level)) {
|
|
477
|
+
currentLevel = config.level;
|
|
478
|
+
}
|
|
479
|
+
invalidateDerivedLoggerState();
|
|
480
|
+
|
|
481
|
+
// Keep active logger instances aligned with the updated effective level.
|
|
482
|
+
const rnLogger = getRnLogger();
|
|
483
|
+
if (rnLogger && rnLogger.setSeverity) {
|
|
484
|
+
rnLogger.setSeverity(currentLevel);
|
|
485
|
+
}
|
|
486
|
+
const winstonLogger = getWinstonLogger();
|
|
487
|
+
if (winstonLogger) {
|
|
488
|
+
winstonLogger.level = currentLevel;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function setLoggerTelemetryBridge(bridge) {
|
|
492
|
+
loggerTelemetryBridge = bridge ?? null;
|
|
493
|
+
}
|
|
494
|
+
function levelPriority(l) {
|
|
495
|
+
switch (l) {
|
|
496
|
+
case 'silent':
|
|
497
|
+
return 0;
|
|
498
|
+
case 'error':
|
|
499
|
+
return 1;
|
|
500
|
+
case 'warn':
|
|
501
|
+
return 2;
|
|
502
|
+
case 'info':
|
|
503
|
+
return 3;
|
|
504
|
+
case 'debug':
|
|
505
|
+
return 4;
|
|
506
|
+
default:
|
|
507
|
+
return 3;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Lightweight logger API used across the app
|
|
512
|
+
const logger = exports.logger = {
|
|
513
|
+
error: (...args) => {
|
|
514
|
+
if (levelPriority(currentLevel) >= levelPriority('error')) {
|
|
515
|
+
const rnLogger = getRnLogger();
|
|
516
|
+
if (rnLogger) {
|
|
517
|
+
rnLogger.error(...args);
|
|
518
|
+
} else {
|
|
519
|
+
const winstonLogger = getWinstonLogger();
|
|
520
|
+
if (winstonLogger) {
|
|
521
|
+
winstonLogger.error(...args);
|
|
522
|
+
} else {
|
|
523
|
+
// eslint-disable-next-line no-console
|
|
524
|
+
console.error('[error]', ...args);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const sink = getFileSink();
|
|
528
|
+
if (sink) sink.write('error', args);
|
|
529
|
+
const remote = getRemoteSink();
|
|
530
|
+
if (remote) remote.write('error', args);
|
|
531
|
+
emitTelemetryBridge("error", args);
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
warn: (...args) => {
|
|
535
|
+
if (levelPriority(currentLevel) >= levelPriority('warn')) {
|
|
536
|
+
const rnLogger = getRnLogger();
|
|
537
|
+
if (rnLogger) {
|
|
538
|
+
rnLogger.warn(...args);
|
|
539
|
+
} else {
|
|
540
|
+
const winstonLogger = getWinstonLogger();
|
|
541
|
+
if (winstonLogger) {
|
|
542
|
+
winstonLogger.warn(...args);
|
|
543
|
+
} else {
|
|
544
|
+
// eslint-disable-next-line no-console
|
|
545
|
+
console.warn('[warn]', ...args);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
const sink = getFileSink();
|
|
549
|
+
if (sink) sink.write('warn', args);
|
|
550
|
+
const remote = getRemoteSink();
|
|
551
|
+
if (remote) remote.write('warn', args);
|
|
552
|
+
emitTelemetryBridge("warn", args);
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
info: (...args) => {
|
|
556
|
+
if (levelPriority(currentLevel) >= levelPriority('info')) {
|
|
557
|
+
const rnLogger = getRnLogger();
|
|
558
|
+
if (rnLogger) {
|
|
559
|
+
rnLogger.info(...args);
|
|
560
|
+
} else {
|
|
561
|
+
const winstonLogger = getWinstonLogger();
|
|
562
|
+
if (winstonLogger) {
|
|
563
|
+
winstonLogger.info(...args);
|
|
564
|
+
} else {
|
|
565
|
+
// eslint-disable-next-line no-console
|
|
566
|
+
console.log('[info]', ...args);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
const sink = getFileSink();
|
|
570
|
+
if (sink) sink.write('info', args);
|
|
571
|
+
const remote = getRemoteSink();
|
|
572
|
+
if (remote) remote.write('info', args);
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
debug: (...args) => {
|
|
576
|
+
if (levelPriority(currentLevel) >= levelPriority('debug')) {
|
|
577
|
+
const rnLogger = getRnLogger();
|
|
578
|
+
if (rnLogger) {
|
|
579
|
+
rnLogger.debug(...args);
|
|
580
|
+
} else {
|
|
581
|
+
const winstonLogger = getWinstonLogger();
|
|
582
|
+
if (winstonLogger) {
|
|
583
|
+
winstonLogger.debug(...args);
|
|
584
|
+
} else {
|
|
585
|
+
// eslint-disable-next-line no-console
|
|
586
|
+
console.debug ? console.debug('[debug]', ...args) : console.log('[debug]', ...args);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
const sink = getFileSink();
|
|
590
|
+
if (sink) sink.write('debug', args);
|
|
591
|
+
const remote = getRemoteSink();
|
|
592
|
+
if (remote) remote.write('debug', args);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var _default = exports.default = logger;
|
|
597
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3ROYXRpdmUiLCJyZXF1aXJlIiwib3duS2V5cyIsImUiLCJyIiwidCIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIl90b1Byb3BlcnR5S2V5IiwidmFsdWUiLCJjb25maWd1cmFibGUiLCJ3cml0YWJsZSIsImkiLCJfdG9QcmltaXRpdmUiLCJTeW1ib2wiLCJ0b1ByaW1pdGl2ZSIsImNhbGwiLCJUeXBlRXJyb3IiLCJTdHJpbmciLCJOdW1iZXIiLCJnZXRSdW50aW1lUHJvY2VzcyIsImdsb2JhbE9iaiIsImdsb2JhbFRoaXMiLCJwcm9jZXNzIiwiaXNOb2RlRW52aXJvbm1lbnQiLCJCb29sZWFuIiwidmVyc2lvbnMiLCJub2RlIiwiaXNSZWFjdE5hdGl2ZSIsIlBsYXRmb3JtIiwiT1MiLCJpc1dlYiIsInJuTG9ncyIsIndpbnN0b24iLCJnZXRXaW5zdG9uIiwid2luc3Rvbk1vZHVsZSIsImV2YWwiLCJnZXREZWZhdWx0TG9nTGV2ZWwiLCJlbnYiLCJsZXZlbCIsIlJFQUNUX0FQUF9MT0dfTEVWRUwiLCJFWFBPX1BVQkxJQ19MT0dfTEVWRUwiLCJMT0dfTEVWRUwiLCJub3JtYWxpemVkIiwidG9Mb3dlckNhc2UiLCJpbmNsdWRlcyIsImN1cnJlbnRMZXZlbCIsInJ1bnRpbWVMb2dnZXJDb25maWciLCJsb2dnZXJUZWxlbWV0cnlCcmlkZ2UiLCJwYWQyIiwibiIsInBhZFN0YXJ0IiwiZm9ybWF0TG9jYWxEYXRlIiwiZGF0ZSIsIkRhdGUiLCJnZXRGdWxsWWVhciIsImdldE1vbnRoIiwiZ2V0RGF0ZSIsImJ1aWxkRGFpbHlGaWxlTmFtZSIsImdldEVudkNvbmZpZyIsImlzVmFsaWRMb2dMZXZlbCIsImlzRmlsZUxvZ2dpbmdFbmFibGVkIiwiZW5hYmxlRmlsZUxvZ2dpbmciLCJyYXciLCJSRUFDVF9BUFBfRU5BQkxFX1dJTlNUT05fRklMRSIsIkVYUE9fUFVCTElDX0VOQUJMRV9XSU5TVE9OX0ZJTEUiLCJSRUFDVF9BUFBfRU5BQkxFX0ZJTEVfTE9HUyIsIkVYUE9fUFVCTElDX0VOQUJMRV9GSUxFX0xPR1MiLCJMT0dfRklMRV9FTkFCTEVEIiwidW5kZWZpbmVkIiwiZ2V0Q29uZmlndXJlZExvZ0RpciIsImxvZ0ZpbGVEaXIiLCJ0cmltIiwiUkVBQ1RfQVBQX0xPR19GSUxFX0RJUiIsIkVYUE9fUFVCTElDX0xPR19GSUxFX0RJUiIsIkxPR19GSUxFX0RJUiIsImZvcm1hdExvZ0xpbmUiLCJhcmdzIiwidHMiLCJ0b0lTT1N0cmluZyIsInNlcmlhbGl6ZSIsIkVycm9yIiwic3RhY2siLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsInBheWxvYWQiLCJtYXAiLCJqb2luIiwidG9VcHBlckNhc2UiLCJmaWxlU2luayIsInJlbW90ZVNpbmsiLCJnZXRDb25maWd1cmVkUmVtb3RlVXJsIiwicmVtb3RlVXJsIiwiUkVBQ1RfQVBQX0xPR19SRU1PVEVfVVJMIiwiRVhQT19QVUJMSUNfTE9HX1JFTU9URV9VUkwiLCJMT0dfUkVNT1RFX1VSTCIsImdldENvbmZpZ3VyZWRSZW1vdGVUb2tlbiIsInJlbW90ZVRva2VuIiwiUkVBQ1RfQVBQX0xPR19JTkdFU1RfVE9LRU4iLCJFWFBPX1BVQkxJQ19MT0dfSU5HRVNUX1RPS0VOIiwiTE9HX0lOR0VTVF9UT0tFTiIsImlzUmVtb3RlTG9nZ2luZ0VuYWJsZWQiLCJyZW1vdGVFbmFibGVkIiwiUkVBQ1RfQVBQX0VOQUJMRV9SRU1PVEVfTE9HUyIsIkVYUE9fUFVCTElDX0VOQUJMRV9SRU1PVEVfTE9HUyIsIkxPR19SRU1PVEVfRU5BQkxFRCIsInNlcmlhbGl6ZUFyZ0Zvckpzb24iLCJuYW1lIiwicGFyc2UiLCJidWlsZFJlbW90ZVBheWxvYWQiLCJub3JtYWxpemVkQXJncyIsImFyZyIsImZpcnN0QXJnIiwidGltZXN0YW1wIiwic291cmNlIiwicnVudGltZSIsImJ1aWxkVGVsZW1ldHJ5TWVzc2FnZSIsIkFycmF5IiwiaXNBcnJheSIsImZpcnN0IiwiZW1pdFRlbGVtZXRyeUJyaWRnZSIsImVycm9yQXJnIiwiZmluZCIsImNvbnRleHQiLCJjYXB0dXJlRXhjZXB0aW9uIiwiY2FwdHVyZU1lc3NhZ2UiLCJnZXRSZW1vdGVTaW5rIiwiZmV0Y2giLCJ1cmwiLCJ0b2tlbiIsInNlbmRDaGFpbiIsIlByb21pc2UiLCJyZXNvbHZlIiwic2VuZE9uZSIsImhlYWRlcnMiLCJtZXRob2QiLCJib2R5Iiwid3JpdGUiLCJ0aGVuIiwiY2F0Y2giLCJpbnZhbGlkYXRlRGVyaXZlZExvZ2dlclN0YXRlIiwiZ2V0Tm9kZUZpbGVTaW5rIiwiZnMiLCJwYXRoIiwiY3VycmVudERhdGUiLCJmaWxlUGF0aCIsImVuc3VyZUZpbGVQYXRoIiwidG9kYXkiLCJsb2dEaXIiLCJjd2QiLCJyZXNvbHZlZERpciIsImV4aXN0c1N5bmMiLCJta2RpclN5bmMiLCJyZWN1cnNpdmUiLCJhcHBlbmRGaWxlIiwiZ2V0RXhwb0ZpbGVTeXN0ZW0iLCJnZXRFeHBvRmlsZVNpbmsiLCJGaWxlU3lzdGVtIiwid3JpdGVBc1N0cmluZ0FzeW5jIiwiYmFzZURpciIsImRvY3VtZW50RGlyZWN0b3J5IiwiY2FjaGVEaXJlY3RvcnkiLCJlbmNvZGluZyIsIkVuY29kaW5nVHlwZSIsIlVURjgiLCJub3JtYWxpemVEaXIiLCJkaXIiLCJyZXBsYWNlIiwic3ViRGlyIiwiYmFzZVBhdGgiLCJmaWxlVXJpIiwid3JpdGVDaGFpbiIsImVuc3VyZUZpbGVVcmkiLCJtYWtlRGlyZWN0b3J5QXN5bmMiLCJpbnRlcm1lZGlhdGVzIiwiaW5mbyIsImdldEluZm9Bc3luYyIsImV4aXN0cyIsImFwcGVuZExpbmUiLCJsaW5lIiwiYXBwZW5kIiwiZXhpc3RpbmciLCJyZWFkQXNTdHJpbmdBc3luYyIsImdldEZpbGVTaW5rIiwibm9kZVNpbmsiLCJleHBvU2luayIsInJuTG9nZ2VyIiwid2luc3RvbkxvZ2dlciIsImdldFJuTG9nZ2VyIiwibG9nZ2VyIiwiY3JlYXRlTG9nZ2VyIiwiY29uZmlnIiwic2V2ZXJpdHkiLCJ0cmFuc3BvcnQiLCJtc2ciLCJfb3B0aW9ucyIsInByZWZpeCIsImNvbnNvbGUiLCJlcnJvciIsIndhcm4iLCJsb2ciLCJkZWJ1ZyIsInRyYW5zcG9ydE9wdGlvbnMiLCJjb2xvcnMiLCJnZXRXaW5zdG9uTG9nZ2VyIiwiZm9ybWF0IiwidHJhbnNwb3J0cyIsInRyYW5zcG9ydEluc3RhbmNlcyIsIkNvbnNvbGUiLCJjb21iaW5lIiwiZXJyb3JzIiwic3BsYXQiLCJqc29uIiwic2V0TG9nTGV2ZWwiLCJzZXRTZXZlcml0eSIsImNvbmZpZ3VyZUxvZ2dlciIsInNldExvZ2dlclRlbGVtZXRyeUJyaWRnZSIsImJyaWRnZSIsImxldmVsUHJpb3JpdHkiLCJsIiwiZXhwb3J0cyIsInNpbmsiLCJyZW1vdGUiLCJfZGVmYXVsdCIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi9zcmMvbG9nZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEVudmlyb25tZW50LWF3YXJlIGxvZ2dlciB1dGlsaXR5XG4vLyBVc2VzIHJlYWN0LW5hdGl2ZS1sb2dzIGZvciBSZWFjdCBOYXRpdmUsIHdpbnN0b24gZm9yIE5vZGUuanMvd2ViLCBjb25zb2xlIGFzIGZhbGxiYWNrXG5cbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxuLy8gRGV0ZXJtaW5lIGVudmlyb25tZW50IGZpcnN0XG4vLyBUcmVhdCBOb2RlIGFzIGl0cyBvd24gcnVudGltZSBldmVuIGlmIHJlYWN0LW5hdGl2ZSBQbGF0Zm9ybS5PUyBpcyBpb3MvYW5kcm9pZCBpbiB0ZXN0c1xuY29uc3QgZ2V0UnVudGltZVByb2Nlc3MgPSAoKToge1xuICB2ZXJzaW9ucz86IHsgbm9kZT86IHN0cmluZyB9O1xuICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICBjd2Q/OiAoKSA9PiBzdHJpbmc7XG59IHwgbnVsbCA9PiB7XG4gIGNvbnN0IGdsb2JhbE9iaiA9IGdsb2JhbFRoaXMgYXMgYW55O1xuICByZXR1cm4gZ2xvYmFsT2JqPy5wcm9jZXNzID8/IG51bGw7XG59O1xuXG5jb25zdCBpc05vZGVFbnZpcm9ubWVudCA9IEJvb2xlYW4oZ2V0UnVudGltZVByb2Nlc3MoKT8udmVyc2lvbnM/Lm5vZGUpO1xuY29uc3QgaXNSZWFjdE5hdGl2ZSA9IFBsYXRmb3JtLk9TICE9PSAnd2ViJyAmJiAhaXNOb2RlRW52aXJvbm1lbnQ7XG5jb25zdCBpc1dlYiA9IFBsYXRmb3JtLk9TID09PSAnd2ViJztcblxuLy8gVHJ5IHRvIHJlcXVpcmUgbGlicmFyaWVzIGJhc2VkIG9uIGVudmlyb25tZW50XG5sZXQgcm5Mb2dzOiBhbnkgPSBudWxsO1xubGV0IHdpbnN0b246IGFueSA9IG51bGw7XG5cbi8vIE9ubHkgdHJ5IHRvIHJlcXVpcmUgcmVhY3QtbmF0aXZlLWxvZ3MgaW4gUmVhY3QgTmF0aXZlIGVudmlyb25tZW50c1xuaWYgKGlzUmVhY3ROYXRpdmUpIHtcbiAgdHJ5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIHJuTG9ncyA9IHJlcXVpcmUoJ3JlYWN0LW5hdGl2ZS1sb2dzJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBybkxvZ3MgPSBudWxsO1xuICB9XG59XG5cbi8vIEZvciB3aW5zdG9uLCB1c2UgcnVudGltZSBkZXRlY3Rpb24gd2l0aG91dCBzdGF0aWMgcmVxdWlyZXNcbmNvbnN0IGdldFdpbnN0b24gPSAoKSA9PiB7XG4gIGlmICh3aW5zdG9uICE9PSBudWxsKSByZXR1cm4gd2luc3RvbjtcbiAgaWYgKCFpc05vZGVFbnZpcm9ubWVudCkgcmV0dXJuIG51bGw7XG5cbiAgdHJ5IHtcbiAgICAvLyBVc2UgZXZhbCB0byBkeW5hbWljYWxseSBjb25zdHJ1Y3QgdGhlIHJlcXVpcmUgY2FsbFxuICAgIC8vIFRoaXMgcHJldmVudHMgc3RhdGljIGFuYWx5c2lzIGZyb20gZmluZGluZyAnd2luc3RvbicgaW4gcmVxdWlyZSgpXG4gICAgY29uc3Qgd2luc3Rvbk1vZHVsZSA9IGV2YWwoJ3JlcXVpcmUnKSgnd2luc3RvbicpO1xuICAgIHdpbnN0b24gPSB3aW5zdG9uTW9kdWxlO1xuICAgIHJldHVybiB3aW5zdG9uO1xuICB9IGNhdGNoIChlKSB7XG4gICAgd2luc3RvbiA9IG51bGw7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gJ2Vycm9yJyB8ICd3YXJuJyB8ICdpbmZvJyB8ICdkZWJ1ZycgfCAnc2lsZW50JztcbmV4cG9ydCB0eXBlIExvZ2dlclJ1bnRpbWVDb25maWcgPSB7XG4gIGxldmVsPzogTG9nTGV2ZWw7XG4gIGVuYWJsZUZpbGVMb2dnaW5nPzogYm9vbGVhbjtcbiAgbG9nRmlsZURpcj86IHN0cmluZztcbiAgcmVtb3RlRW5hYmxlZD86IGJvb2xlYW47XG4gIHJlbW90ZVVybD86IHN0cmluZztcbiAgcmVtb3RlVG9rZW4/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBMb2dnZXJUZWxlbWV0cnlCcmlkZ2UgPSB7XG4gIGNhcHR1cmVFeGNlcHRpb24/OiAoZXJyb3I6IEVycm9yLCBjb250ZXh0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHZvaWQ7XG4gIGNhcHR1cmVNZXNzYWdlPzogKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBsZXZlbD86IFwiZXJyb3JcIiB8IFwid2FyblwiIHwgXCJpbmZvXCIgfCBcImRlYnVnXCIsXG4gICAgY29udGV4dD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICkgPT4gdm9pZDtcbn07XG5cbi8vIFJlYWQgZGVzaXJlZCBsb2cgbGV2ZWwgZnJvbSBlbnYvY29uZmlnXG5mdW5jdGlvbiBnZXREZWZhdWx0TG9nTGV2ZWwoKTogTG9nTGV2ZWwge1xuICBjb25zdCBlbnYgPSBnZXRSdW50aW1lUHJvY2VzcygpPy5lbnYgPz8ge307XG4gIGNvbnN0IGxldmVsID0gZW52LlJFQUNUX0FQUF9MT0dfTEVWRUwgfHwgZW52LkVYUE9fUFVCTElDX0xPR19MRVZFTCB8fCBlbnYuTE9HX0xFVkVMO1xuICBpZiAoIWxldmVsKSByZXR1cm4gKGlzTm9kZUVudmlyb25tZW50IHx8IGlzV2ViKSA/ICdpbmZvJyA6ICd3YXJuJztcbiAgY29uc3Qgbm9ybWFsaXplZCA9IGxldmVsLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChbJ2Vycm9yJywgJ3dhcm4nLCAnaW5mbycsICdkZWJ1ZycsICdzaWxlbnQnXS5pbmNsdWRlcyhub3JtYWxpemVkKSkge1xuICAgIHJldHVybiBub3JtYWxpemVkIGFzIExvZ0xldmVsO1xuICB9XG4gIHJldHVybiAnaW5mbyc7XG59XG5cbmxldCBjdXJyZW50TGV2ZWw6IExvZ0xldmVsID0gZ2V0RGVmYXVsdExvZ0xldmVsKCk7XG5sZXQgcnVudGltZUxvZ2dlckNvbmZpZzogTG9nZ2VyUnVudGltZUNvbmZpZyA9IHt9O1xubGV0IGxvZ2dlclRlbGVtZXRyeUJyaWRnZTogTG9nZ2VyVGVsZW1ldHJ5QnJpZGdlIHwgbnVsbCA9IG51bGw7XG5cbmNvbnN0IHBhZDIgPSAobjogbnVtYmVyKSA9PiBTdHJpbmcobikucGFkU3RhcnQoMiwgJzAnKTtcbmNvbnN0IGZvcm1hdExvY2FsRGF0ZSA9IChkYXRlID0gbmV3IERhdGUoKSkgPT5cbiAgYCR7ZGF0ZS5nZXRGdWxsWWVhcigpfS0ke3BhZDIoZGF0ZS5nZXRNb250aCgpICsgMSl9LSR7cGFkMihkYXRlLmdldERhdGUoKSl9YDtcbmNvbnN0IGJ1aWxkRGFpbHlGaWxlTmFtZSA9IChkYXRlID0gbmV3IERhdGUoKSkgPT4gYGxvZ3MtJHtmb3JtYXRMb2NhbERhdGUoZGF0ZSl9LmxvZ2A7XG5cbmNvbnN0IGdldEVudkNvbmZpZyA9ICgpID0+IHtcbiAgcmV0dXJuIGdldFJ1bnRpbWVQcm9jZXNzKCk/LmVudiA/PyB7fTtcbn07XG5cbmNvbnN0IGlzVmFsaWRMb2dMZXZlbCA9IChsZXZlbDogdW5rbm93bik6IGxldmVsIGlzIExvZ0xldmVsID0+IHtcbiAgcmV0dXJuIHR5cGVvZiBsZXZlbCA9PT0gJ3N0cmluZycgJiYgWydlcnJvcicsICd3YXJuJywgJ2luZm8nLCAnZGVidWcnLCAnc2lsZW50J10uaW5jbHVkZXMobGV2ZWwpO1xufTtcblxuY29uc3QgaXNGaWxlTG9nZ2luZ0VuYWJsZWQgPSAoKSA9PiB7XG4gIGlmICh0eXBlb2YgcnVudGltZUxvZ2dlckNvbmZpZy5lbmFibGVGaWxlTG9nZ2luZyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgcmV0dXJuIHJ1bnRpbWVMb2dnZXJDb25maWcuZW5hYmxlRmlsZUxvZ2dpbmc7XG4gIH1cbiAgY29uc3QgZW52ID0gZ2V0RW52Q29uZmlnKCk7XG4gIGNvbnN0IHJhdyA9XG4gICAgZW52LlJFQUNUX0FQUF9FTkFCTEVfV0lOU1RPTl9GSUxFIHx8XG4gICAgZW52LkVYUE9fUFVCTElDX0VOQUJMRV9XSU5TVE9OX0ZJTEUgfHxcbiAgICBlbnYuUkVBQ1RfQVBQX0VOQUJMRV9GSUxFX0xPR1MgfHxcbiAgICBlbnYuRVhQT19QVUJMSUNfRU5BQkxFX0ZJTEVfTE9HUyB8fFxuICAgIGVudi5MT0dfRklMRV9FTkFCTEVEO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuICByZXR1cm4gcmF3ID09PSAndHJ1ZScgfHwgcmF3ID09PSAnMSc7XG59O1xuXG5jb25zdCBnZXRDb25maWd1cmVkTG9nRGlyID0gKCkgPT4ge1xuICBpZiAocnVudGltZUxvZ2dlckNvbmZpZy5sb2dGaWxlRGlyICYmIHJ1bnRpbWVMb2dnZXJDb25maWcubG9nRmlsZURpci50cmltKCkpIHtcbiAgICByZXR1cm4gcnVudGltZUxvZ2dlckNvbmZpZy5sb2dGaWxlRGlyO1xuICB9XG4gIGNvbnN0IGVudiA9IGdldEVudkNvbmZpZygpO1xuICByZXR1cm4gZW52LlJFQUNUX0FQUF9MT0dfRklMRV9ESVIgfHwgZW52LkVYUE9fUFVCTElDX0xPR19GSUxFX0RJUiB8fCBlbnYuTE9HX0ZJTEVfRElSIHx8ICcuJztcbn07XG5cbmNvbnN0IGZvcm1hdExvZ0xpbmUgPSAobGV2ZWw6IExvZ0xldmVsLCBhcmdzOiBhbnlbXSkgPT4ge1xuICBjb25zdCB0cyA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgY29uc3Qgc2VyaWFsaXplID0gKHZhbHVlOiBhbnkpID0+IHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc3Qgc3RhY2sgPSB2YWx1ZS5zdGFjayA/IGBcXG4ke3ZhbHVlLnN0YWNrfWAgOiAnJztcbiAgICAgIHJldHVybiBgJHt2YWx1ZS5tZXNzYWdlfSR7c3RhY2t9YDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgfTtcbiAgY29uc3QgcGF5bG9hZCA9IGFyZ3MubWFwKHNlcmlhbGl6ZSkuam9pbignICcpO1xuICByZXR1cm4gYCR7dHN9IFske2xldmVsLnRvVXBwZXJDYXNlKCl9XSAke3BheWxvYWR9XFxuYDtcbn07XG5cbnR5cGUgRmlsZVNpbmsgPSB7IHdyaXRlOiAobGV2ZWw6IExvZ0xldmVsLCBhcmdzOiBhbnlbXSkgPT4gdm9pZCB9O1xubGV0IGZpbGVTaW5rOiBGaWxlU2luayB8IG51bGwgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG50eXBlIFJlbW90ZVNpbmsgPSB7IHdyaXRlOiAobGV2ZWw6IExvZ0xldmVsLCBhcmdzOiBhbnlbXSkgPT4gdm9pZCB9O1xubGV0IHJlbW90ZVNpbms6IFJlbW90ZVNpbmsgfCBudWxsIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG5jb25zdCBnZXRDb25maWd1cmVkUmVtb3RlVXJsID0gKCkgPT4ge1xuICBpZiAocnVudGltZUxvZ2dlckNvbmZpZy5yZW1vdGVVcmwgJiYgcnVudGltZUxvZ2dlckNvbmZpZy5yZW1vdGVVcmwudHJpbSgpKSB7XG4gICAgcmV0dXJuIHJ1bnRpbWVMb2dnZXJDb25maWcucmVtb3RlVXJsO1xuICB9XG4gIGNvbnN0IGVudiA9IGdldEVudkNvbmZpZygpO1xuICByZXR1cm4gZW52LlJFQUNUX0FQUF9MT0dfUkVNT1RFX1VSTCB8fCBlbnYuRVhQT19QVUJMSUNfTE9HX1JFTU9URV9VUkwgfHwgZW52LkxPR19SRU1PVEVfVVJMIHx8ICcnO1xufTtcblxuY29uc3QgZ2V0Q29uZmlndXJlZFJlbW90ZVRva2VuID0gKCkgPT4ge1xuICBpZiAocnVudGltZUxvZ2dlckNvbmZpZy5yZW1vdGVUb2tlbiAmJiBydW50aW1lTG9nZ2VyQ29uZmlnLnJlbW90ZVRva2VuLnRyaW0oKSkge1xuICAgIHJldHVybiBydW50aW1lTG9nZ2VyQ29uZmlnLnJlbW90ZVRva2VuO1xuICB9XG4gIGNvbnN0IGVudiA9IGdldEVudkNvbmZpZygpO1xuICByZXR1cm4gZW52LlJFQUNUX0FQUF9MT0dfSU5HRVNUX1RPS0VOIHx8IGVudi5FWFBPX1BVQkxJQ19MT0dfSU5HRVNUX1RPS0VOIHx8IGVudi5MT0dfSU5HRVNUX1RPS0VOIHx8ICcnO1xufTtcblxuY29uc3QgaXNSZW1vdGVMb2dnaW5nRW5hYmxlZCA9ICgpID0+IHtcbiAgaWYgKHR5cGVvZiBydW50aW1lTG9nZ2VyQ29uZmlnLnJlbW90ZUVuYWJsZWQgPT09ICdib29sZWFuJykge1xuICAgIHJldHVybiBydW50aW1lTG9nZ2VyQ29uZmlnLnJlbW90ZUVuYWJsZWQgJiYgQm9vbGVhbihnZXRDb25maWd1cmVkUmVtb3RlVXJsKCkpO1xuICB9XG4gIGNvbnN0IHJlbW90ZVVybCA9IGdldENvbmZpZ3VyZWRSZW1vdGVVcmwoKTtcbiAgaWYgKCFyZW1vdGVVcmwpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgZW52ID0gZ2V0RW52Q29uZmlnKCk7XG4gIGNvbnN0IHJhdyA9XG4gICAgZW52LlJFQUNUX0FQUF9FTkFCTEVfUkVNT1RFX0xPR1MgfHxcbiAgICBlbnYuRVhQT19QVUJMSUNfRU5BQkxFX1JFTU9URV9MT0dTIHx8XG4gICAgZW52LkxPR19SRU1PVEVfRU5BQkxFRDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIHJhdyA9PT0gJ3RydWUnIHx8IHJhdyA9PT0gJzEnO1xufTtcblxuY29uc3Qgc2VyaWFsaXplQXJnRm9ySnNvbiA9ICh2YWx1ZTogYW55KTogYW55ID0+IHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogdmFsdWUubmFtZSxcbiAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsXG4gICAgICBzdGFjazogdmFsdWUuc3RhY2ssXG4gICAgfTtcbiAgfVxuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gdmFsdWU7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gIH1cbn07XG5cbmNvbnN0IGJ1aWxkUmVtb3RlUGF5bG9hZCA9IChsZXZlbDogTG9nTGV2ZWwsIGFyZ3M6IGFueVtdKSA9PiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRBcmdzID0gYXJncy5tYXAoKGFyZykgPT4gc2VyaWFsaXplQXJnRm9ySnNvbihhcmcpKTtcbiAgY29uc3QgZmlyc3RBcmcgPSBub3JtYWxpemVkQXJnc1swXTtcbiAgY29uc3QgbWVzc2FnZSA9XG4gICAgdHlwZW9mIGZpcnN0QXJnID09PSAnc3RyaW5nJ1xuICAgICAgPyBmaXJzdEFyZ1xuICAgICAgOiBub3JtYWxpemVkQXJncy5tYXAoKGFyZykgPT4gKHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnID8gYXJnIDogSlNPTi5zdHJpbmdpZnkoYXJnKSkpLmpvaW4oJyAnKTtcblxuICByZXR1cm4ge1xuICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIGxldmVsLFxuICAgIG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ1tlbXB0eV0nLFxuICAgIHNvdXJjZTogaXNXZWIgPyAnd2ViJyA6ICdtb2JpbGUnLFxuICAgIHJ1bnRpbWU6IGlzTm9kZUVudmlyb25tZW50ID8gJ25vZGUnIDogJ2NsaWVudCcsXG4gICAgYXJnczogbm9ybWFsaXplZEFyZ3MsXG4gIH07XG59O1xuXG5jb25zdCBidWlsZFRlbGVtZXRyeU1lc3NhZ2UgPSAoYXJnczogYW55W10pOiBzdHJpbmcgPT4ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYXJncykgfHwgYXJncy5sZW5ndGggPT09IDApIHJldHVybiBcIltlbXB0eV1cIjtcbiAgY29uc3QgW2ZpcnN0XSA9IGFyZ3M7XG4gIGlmICh0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIgJiYgZmlyc3QudHJpbSgpKSByZXR1cm4gZmlyc3Q7XG4gIHJldHVybiBhcmdzXG4gICAgLm1hcCgoYXJnKSA9PiB7XG4gICAgICBpZiAoYXJnIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBhcmcubWVzc2FnZTtcbiAgICAgIGlmICh0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiKSByZXR1cm4gYXJnO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyhhcmcpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLmpvaW4oXCIgXCIpXG4gICAgLnRyaW0oKSB8fCBcIltlbXB0eV1cIjtcbn07XG5cbmNvbnN0IGVtaXRUZWxlbWV0cnlCcmlkZ2UgPSAoXG4gIGxldmVsOiBcImVycm9yXCIgfCBcIndhcm5cIiB8IFwiaW5mb1wiIHwgXCJkZWJ1Z1wiLFxuICBhcmdzOiBhbnlbXVxuKSA9PiB7XG4gIGlmICghbG9nZ2VyVGVsZW1ldHJ5QnJpZGdlKSByZXR1cm47XG5cbiAgY29uc3QgZXJyb3JBcmcgPSBhcmdzLmZpbmQoKGFyZykgPT4gYXJnIGluc3RhbmNlb2YgRXJyb3IpIGFzIEVycm9yIHwgdW5kZWZpbmVkO1xuICBjb25zdCBjb250ZXh0ID0geyBsZXZlbCwgcnVudGltZTogaXNOb2RlRW52aXJvbm1lbnQgPyBcIm5vZGVcIiA6IGlzV2ViID8gXCJ3ZWJcIiA6IFwibmF0aXZlXCIgfTtcblxuICBpZiAoZXJyb3JBcmcgJiYgdHlwZW9mIGxvZ2dlclRlbGVtZXRyeUJyaWRnZS5jYXB0dXJlRXhjZXB0aW9uID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBsb2dnZXJUZWxlbWV0cnlCcmlkZ2UuY2FwdHVyZUV4Y2VwdGlvbihlcnJvckFyZywgY29udGV4dCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBsb2dnZXJUZWxlbWV0cnlCcmlkZ2UuY2FwdHVyZU1lc3NhZ2UgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGxvZ2dlclRlbGVtZXRyeUJyaWRnZS5jYXB0dXJlTWVzc2FnZShidWlsZFRlbGVtZXRyeU1lc3NhZ2UoYXJncyksIGxldmVsLCBjb250ZXh0KTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UmVtb3RlU2luayA9ICgpOiBSZW1vdGVTaW5rIHwgbnVsbCA9PiB7XG4gIGlmIChyZW1vdGVTaW5rICE9PSB1bmRlZmluZWQpIHJldHVybiByZW1vdGVTaW5rID8/IG51bGw7XG4gIGlmICghaXNSZW1vdGVMb2dnaW5nRW5hYmxlZCgpKSB7XG4gICAgcmVtb3RlU2luayA9IG51bGw7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKHR5cGVvZiBmZXRjaCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJlbW90ZVNpbmsgPSBudWxsO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdXJsID0gZ2V0Q29uZmlndXJlZFJlbW90ZVVybCgpO1xuICBjb25zdCB0b2tlbiA9IGdldENvbmZpZ3VyZWRSZW1vdGVUb2tlbigpO1xuICBsZXQgc2VuZENoYWluID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgY29uc3Qgc2VuZE9uZSA9IGFzeW5jIChsZXZlbDogTG9nTGV2ZWwsIGFyZ3M6IGFueVtdKSA9PiB7XG4gICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfTtcbiAgICBpZiAodG9rZW4pIHtcbiAgICAgIGhlYWRlcnNbJ3gtbG9nLXRva2VuJ10gPSB0b2tlbjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXlsb2FkID0gYnVpbGRSZW1vdGVQYXlsb2FkKGxldmVsLCBhcmdzKTtcbiAgICBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpLFxuICAgIH0pO1xuICB9O1xuXG4gIHJlbW90ZVNpbmsgPSB7XG4gICAgd3JpdGU6IChsZXZlbCwgYXJncykgPT4ge1xuICAgICAgc2VuZENoYWluID0gc2VuZENoYWluLnRoZW4oKCkgPT4gc2VuZE9uZShsZXZlbCwgYXJncykpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9LFxuICB9O1xuICByZXR1cm4gcmVtb3RlU2luaztcbn07XG5cbmNvbnN0IGludmFsaWRhdGVEZXJpdmVkTG9nZ2VyU3RhdGUgPSAoKSA9PiB7XG4gIGZpbGVTaW5rID0gdW5kZWZpbmVkO1xuICByZW1vdGVTaW5rID0gdW5kZWZpbmVkO1xufTtcblxuY29uc3QgZ2V0Tm9kZUZpbGVTaW5rID0gKCk6IEZpbGVTaW5rIHwgbnVsbCA9PiB7XG4gIGlmICghaXNOb2RlRW52aXJvbm1lbnQpIHJldHVybiBudWxsO1xuICBsZXQgZnM6IGFueSA9IG51bGw7XG4gIGxldCBwYXRoOiBhbnkgPSBudWxsO1xuICB0cnkge1xuICAgIGZzID0gZXZhbCgncmVxdWlyZScpKCdmcycpO1xuICAgIHBhdGggPSBldmFsKCdyZXF1aXJlJykoJ3BhdGgnKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZXQgY3VycmVudERhdGUgPSAnJztcbiAgbGV0IGZpbGVQYXRoID0gJyc7XG4gIGNvbnN0IGVuc3VyZUZpbGVQYXRoID0gKCkgPT4ge1xuICAgIGNvbnN0IHRvZGF5ID0gZm9ybWF0TG9jYWxEYXRlKG5ldyBEYXRlKCkpO1xuICAgIGlmICh0b2RheSA9PT0gY3VycmVudERhdGUgJiYgZmlsZVBhdGgpIHJldHVybjtcbiAgICBjdXJyZW50RGF0ZSA9IHRvZGF5O1xuICAgIGNvbnN0IGxvZ0RpciA9IGdldENvbmZpZ3VyZWRMb2dEaXIoKSB8fCAnLic7XG4gICAgY29uc3QgY3dkID0gZ2V0UnVudGltZVByb2Nlc3MoKT8uY3dkPy4oKSA/PyAnLic7XG4gICAgY29uc3QgcmVzb2x2ZWREaXIgPSBwYXRoLnJlc29sdmUoY3dkLCBsb2dEaXIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXNvbHZlZERpcikpIHtcbiAgICAgIHRyeSB7IGZzLm1rZGlyU3luYyhyZXNvbHZlZERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7IH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxuICAgIH1cbiAgICBmaWxlUGF0aCA9IHBhdGguam9pbihyZXNvbHZlZERpciwgYnVpbGREYWlseUZpbGVOYW1lKG5ldyBEYXRlKCkpKTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHdyaXRlOiAobGV2ZWwsIGFyZ3MpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGVuc3VyZUZpbGVQYXRoKCk7XG4gICAgICAgIGZzLmFwcGVuZEZpbGUoZmlsZVBhdGgsIGZvcm1hdExvZ0xpbmUobGV2ZWwsIGFyZ3MpLCAoKSA9PiB7fSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gaWdub3JlIGZpbGUgbG9nZ2luZyBlcnJvcnNcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufTtcblxuY29uc3QgZ2V0RXhwb0ZpbGVTeXN0ZW0gPSAoKSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcbiAgICByZXR1cm4gcmVxdWlyZSgnZXhwby1maWxlLXN5c3RlbS9sZWdhY3knKTtcbiAgfSBjYXRjaCB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICByZXR1cm4gcmVxdWlyZSgnZXhwby1maWxlLXN5c3RlbScpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5jb25zdCBnZXRFeHBvRmlsZVNpbmsgPSAoKTogRmlsZVNpbmsgfCBudWxsID0+IHtcbiAgY29uc3QgRmlsZVN5c3RlbSA9IGdldEV4cG9GaWxlU3lzdGVtKCk7XG4gIGlmICghRmlsZVN5c3RlbSB8fCB0eXBlb2YgRmlsZVN5c3RlbS53cml0ZUFzU3RyaW5nQXN5bmMgIT09ICdmdW5jdGlvbicpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGJhc2VEaXIgPSBGaWxlU3lzdGVtLmRvY3VtZW50RGlyZWN0b3J5IHx8IEZpbGVTeXN0ZW0uY2FjaGVEaXJlY3Rvcnk7XG4gIGlmICghYmFzZURpcikgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGVuY29kaW5nID0gRmlsZVN5c3RlbS5FbmNvZGluZ1R5cGU/LlVURjggPz8gJ3V0ZjgnO1xuXG4gIGNvbnN0IG5vcm1hbGl6ZURpciA9IChkaXI6IHN0cmluZykgPT4gZGlyLnJlcGxhY2UoL1xcLz8kLywgJy8nKTtcbiAgY29uc3QgbG9nRGlyID0gZ2V0Q29uZmlndXJlZExvZ0RpcigpO1xuICBjb25zdCBzdWJEaXIgPSBsb2dEaXIgJiYgbG9nRGlyICE9PSAnLicgPyBsb2dEaXIucmVwbGFjZSgvXlxcLlxcLysvLCAnJykucmVwbGFjZSgvXFwvKyQvLCAnJykgOiAnJztcbiAgY29uc3QgYmFzZVBhdGggPSBzdWJEaXIgPyBgJHtub3JtYWxpemVEaXIoYmFzZURpcil9JHtzdWJEaXJ9L2AgOiBub3JtYWxpemVEaXIoYmFzZURpcik7XG5cbiAgbGV0IGN1cnJlbnREYXRlID0gJyc7XG4gIGxldCBmaWxlVXJpID0gJyc7XG4gIGxldCB3cml0ZUNoYWluID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgY29uc3QgZW5zdXJlRmlsZVVyaSA9IGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0b2RheSA9IGZvcm1hdExvY2FsRGF0ZShuZXcgRGF0ZSgpKTtcbiAgICBpZiAodG9kYXkgPT09IGN1cnJlbnREYXRlICYmIGZpbGVVcmkpIHJldHVybjtcbiAgICBjdXJyZW50RGF0ZSA9IHRvZGF5O1xuICAgIGZpbGVVcmkgPSBgJHtiYXNlUGF0aH0ke2J1aWxkRGFpbHlGaWxlTmFtZShuZXcgRGF0ZSgpKX1gO1xuICAgIGlmIChzdWJEaXIpIHtcbiAgICAgIHRyeSB7IGF3YWl0IEZpbGVTeXN0ZW0ubWFrZURpcmVjdG9yeUFzeW5jKGJhc2VQYXRoLCB7IGludGVybWVkaWF0ZXM6IHRydWUgfSk7IH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgaW5mbyA9IGF3YWl0IEZpbGVTeXN0ZW0uZ2V0SW5mb0FzeW5jKGZpbGVVcmkpO1xuICAgICAgaWYgKCFpbmZvPy5leGlzdHMpIHtcbiAgICAgICAgYXdhaXQgRmlsZVN5c3RlbS53cml0ZUFzU3RyaW5nQXN5bmMoZmlsZVVyaSwgJycsIHsgZW5jb2RpbmcgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICB0cnkgeyBhd2FpdCBGaWxlU3lzdGVtLndyaXRlQXNTdHJpbmdBc3luYyhmaWxlVXJpLCAnJywgeyBlbmNvZGluZyB9KTsgfSBjYXRjaCB7IC8qIGlnbm9yZSAqLyB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGFwcGVuZExpbmUgPSBhc3luYyAobGluZTogc3RyaW5nKSA9PiB7XG4gICAgYXdhaXQgZW5zdXJlRmlsZVVyaSgpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBGaWxlU3lzdGVtLndyaXRlQXNTdHJpbmdBc3luYyhmaWxlVXJpLCBsaW5lLCB7XG4gICAgICAgIGVuY29kaW5nLFxuICAgICAgICBhcHBlbmQ6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGZhbGwgdGhyb3VnaCB0byByZWFkL2FwcGVuZCBmYWxsYmFja1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBGaWxlU3lzdGVtLnJlYWRBc1N0cmluZ0FzeW5jKGZpbGVVcmksIHsgZW5jb2RpbmcgfSk7XG4gICAgICBhd2FpdCBGaWxlU3lzdGVtLndyaXRlQXNTdHJpbmdBc3luYyhmaWxlVXJpLCBgJHtleGlzdGluZ30ke2xpbmV9YCwgeyBlbmNvZGluZyB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlnbm9yZVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHdyaXRlOiAobGV2ZWwsIGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IGxpbmUgPSBmb3JtYXRMb2dMaW5lKGxldmVsLCBhcmdzKTtcbiAgICAgIHdyaXRlQ2hhaW4gPSB3cml0ZUNoYWluLnRoZW4oKCkgPT4gYXBwZW5kTGluZShsaW5lKSkuY2F0Y2goKCkgPT4ge30pO1xuICAgIH0sXG4gIH07XG59O1xuXG5jb25zdCBnZXRGaWxlU2luayA9ICgpOiBGaWxlU2luayB8IG51bGwgPT4ge1xuICBpZiAoZmlsZVNpbmsgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGZpbGVTaW5rID8/IG51bGw7XG4gIGlmICghaXNGaWxlTG9nZ2luZ0VuYWJsZWQoKSkge1xuICAgIGZpbGVTaW5rID0gbnVsbDtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBub2RlU2luayA9IGdldE5vZGVGaWxlU2luaygpO1xuICBpZiAobm9kZVNpbmspIHtcbiAgICBmaWxlU2luayA9IG5vZGVTaW5rO1xuICAgIHJldHVybiBub2RlU2luaztcbiAgfVxuICBjb25zdCBleHBvU2luayA9IGdldEV4cG9GaWxlU2luaygpO1xuICBpZiAoZXhwb1NpbmspIHtcbiAgICBmaWxlU2luayA9IGV4cG9TaW5rO1xuICAgIHJldHVybiBleHBvU2luaztcbiAgfVxuICBmaWxlU2luayA9IG51bGw7XG4gIHJldHVybiBudWxsO1xufTtcblxuLy8gQ3JlYXRlIGxvZ2dlciBpbnN0YW5jZSBiYXNlZCBvbiBlbnZpcm9ubWVudCAtIExBWlkgTE9BRElOR1xubGV0IHJuTG9nZ2VyOiBhbnkgPSBudWxsO1xubGV0IHdpbnN0b25Mb2dnZXI6IGFueSA9IG51bGw7XG5cbi8vIExhenkgaW5pdGlhbGl6YXRpb24gZnVuY3Rpb25zXG5jb25zdCBnZXRSbkxvZ2dlciA9ICgpID0+IHtcbiAgaWYgKHJuTG9nZ2VyICE9PSBudWxsKSByZXR1cm4gcm5Mb2dnZXI7XG4gIGlmICghaXNSZWFjdE5hdGl2ZSB8fCAhcm5Mb2dzKSByZXR1cm4gbnVsbDtcblxuICB0cnkge1xuICAgIGNvbnN0IHsgbG9nZ2VyOiBjcmVhdGVMb2dnZXIgfSA9IHJuTG9ncztcblxuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIHNldmVyaXR5OiBjdXJyZW50TGV2ZWwsXG4gICAgICB0cmFuc3BvcnQ6IChtc2c6IGFueSwgbGV2ZWw6IHN0cmluZywgX29wdGlvbnM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBwcmVmaXggPSBgWyR7bGV2ZWwudG9VcHBlckNhc2UoKX1dYDtcbiAgICAgICAgc3dpdGNoIChsZXZlbCkge1xuICAgICAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKHByZWZpeCwgLi4ubXNnKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3dhcm4nOlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihwcmVmaXgsIC4uLm1zZyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhwcmVmaXgsIC4uLm1zZyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkZWJ1Zyc6XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyA/IGNvbnNvbGUuZGVidWcocHJlZml4LCAuLi5tc2cpIDogY29uc29sZS5sb2cocHJlZml4LCAuLi5tc2cpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhwcmVmaXgsIC4uLm1zZyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0cmFuc3BvcnRPcHRpb25zOiB7XG4gICAgICAgIGNvbG9yczoge1xuICAgICAgICAgIGVycm9yOiAncmVkJyxcbiAgICAgICAgICB3YXJuOiAneWVsbG93JyxcbiAgICAgICAgICBpbmZvOiAnYmx1ZScsXG4gICAgICAgICAgZGVidWc6ICdncmF5JyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHJuTG9nZ2VyID0gY3JlYXRlTG9nZ2VyKGNvbmZpZyk7XG4gICAgcmV0dXJuIHJuTG9nZ2VyO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcm5Mb2dnZXIgPSBudWxsO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG5jb25zdCBnZXRXaW5zdG9uTG9nZ2VyID0gKCkgPT4ge1xuICBpZiAod2luc3RvbkxvZ2dlciAhPT0gbnVsbCkgcmV0dXJuIHdpbnN0b25Mb2dnZXI7XG4gIGlmICghaXNOb2RlRW52aXJvbm1lbnQpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IHdpbnN0b24gPSBnZXRXaW5zdG9uKCk7XG4gIGlmICghd2luc3RvbikgcmV0dXJuIG51bGw7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IGNyZWF0ZUxvZ2dlciwgZm9ybWF0LCB0cmFuc3BvcnRzIH0gPSB3aW5zdG9uO1xuICAgIGNvbnN0IHRyYW5zcG9ydEluc3RhbmNlczogYW55W10gPSBbbmV3IHRyYW5zcG9ydHMuQ29uc29sZSh7IGxldmVsOiBjdXJyZW50TGV2ZWwgfSldO1xuXG4gICAgd2luc3RvbkxvZ2dlciA9IGNyZWF0ZUxvZ2dlcih7XG4gICAgICBsZXZlbDogY3VycmVudExldmVsLFxuICAgICAgZm9ybWF0OiBmb3JtYXQuY29tYmluZShcbiAgICAgICAgZm9ybWF0LnRpbWVzdGFtcCgpLFxuICAgICAgICBmb3JtYXQuZXJyb3JzKHsgc3RhY2s6IHRydWUgfSksXG4gICAgICAgIGZvcm1hdC5zcGxhdCgpLFxuICAgICAgICBmb3JtYXQuanNvbigpXG4gICAgICApLFxuICAgICAgdHJhbnNwb3J0czogdHJhbnNwb3J0SW5zdGFuY2VzLFxuICAgIH0pO1xuICAgIHJldHVybiB3aW5zdG9uTG9nZ2VyO1xuICB9IGNhdGNoIChlKSB7XG4gICAgd2luc3RvbkxvZ2dlciA9IG51bGw7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbi8vIEluaXRpYWxpemUgUk4gbG9nZ2VyIGltbWVkaWF0ZWx5IGlmIGluIFJlYWN0IE5hdGl2ZVxuaWYgKGlzUmVhY3ROYXRpdmUpIHtcbiAgZ2V0Um5Mb2dnZXIoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ0xldmVsKGxldmVsOiBMb2dMZXZlbCkge1xuICBjdXJyZW50TGV2ZWwgPSBsZXZlbDtcbiAgLy8gVXBkYXRlIGxvZ2dlciBzZXZlcml0eSBpZiBhdmFpbGFibGVcbiAgY29uc3Qgcm5Mb2dnZXIgPSBnZXRSbkxvZ2dlcigpO1xuICBpZiAocm5Mb2dnZXIgJiYgcm5Mb2dnZXIuc2V0U2V2ZXJpdHkpIHtcbiAgICBybkxvZ2dlci5zZXRTZXZlcml0eShsZXZlbCk7XG4gIH1cbiAgY29uc3Qgd2luc3RvbkxvZ2dlciA9IGdldFdpbnN0b25Mb2dnZXIoKTtcbiAgaWYgKHdpbnN0b25Mb2dnZXIpIHtcbiAgICB3aW5zdG9uTG9nZ2VyLmxldmVsID0gbGV2ZWw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmZpZ3VyZUxvZ2dlcihjb25maWc6IExvZ2dlclJ1bnRpbWVDb25maWcgPSB7fSkge1xuICBydW50aW1lTG9nZ2VyQ29uZmlnID0ge1xuICAgIC4uLnJ1bnRpbWVMb2dnZXJDb25maWcsXG4gICAgLi4uY29uZmlnLFxuICB9O1xuXG4gIGlmIChpc1ZhbGlkTG9nTGV2ZWwoY29uZmlnLmxldmVsKSkge1xuICAgIGN1cnJlbnRMZXZlbCA9IGNvbmZpZy5sZXZlbDtcbiAgfVxuXG4gIGludmFsaWRhdGVEZXJpdmVkTG9nZ2VyU3RhdGUoKTtcblxuICAvLyBLZWVwIGFjdGl2ZSBsb2dnZXIgaW5zdGFuY2VzIGFsaWduZWQgd2l0aCB0aGUgdXBkYXRlZCBlZmZlY3RpdmUgbGV2ZWwuXG4gIGNvbnN0IHJuTG9nZ2VyID0gZ2V0Um5Mb2dnZXIoKTtcbiAgaWYgKHJuTG9nZ2VyICYmIHJuTG9nZ2VyLnNldFNldmVyaXR5KSB7XG4gICAgcm5Mb2dnZXIuc2V0U2V2ZXJpdHkoY3VycmVudExldmVsKTtcbiAgfVxuICBjb25zdCB3aW5zdG9uTG9nZ2VyID0gZ2V0V2luc3RvbkxvZ2dlcigpO1xuICBpZiAod2luc3RvbkxvZ2dlcikge1xuICAgIHdpbnN0b25Mb2dnZXIubGV2ZWwgPSBjdXJyZW50TGV2ZWw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlclRlbGVtZXRyeUJyaWRnZShicmlkZ2U/OiBMb2dnZXJUZWxlbWV0cnlCcmlkZ2UgfCBudWxsKSB7XG4gIGxvZ2dlclRlbGVtZXRyeUJyaWRnZSA9IGJyaWRnZSA/PyBudWxsO1xufVxuXG5mdW5jdGlvbiBsZXZlbFByaW9yaXR5KGw6IExvZ0xldmVsKSB7XG4gIHN3aXRjaCAobCkge1xuICAgIGNhc2UgJ3NpbGVudCc6IHJldHVybiAwO1xuICAgIGNhc2UgJ2Vycm9yJzogcmV0dXJuIDE7XG4gICAgY2FzZSAnd2Fybic6IHJldHVybiAyO1xuICAgIGNhc2UgJ2luZm8nOiByZXR1cm4gMztcbiAgICBjYXNlICdkZWJ1Zyc6IHJldHVybiA0O1xuICAgIGRlZmF1bHQ6IHJldHVybiAzO1xuICB9XG59XG5cbi8vIExpZ2h0d2VpZ2h0IGxvZ2dlciBBUEkgdXNlZCBhY3Jvc3MgdGhlIGFwcFxuZXhwb3J0IGNvbnN0IGxvZ2dlciA9IHtcbiAgZXJyb3I6ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIGlmIChsZXZlbFByaW9yaXR5KGN1cnJlbnRMZXZlbCkgPj0gbGV2ZWxQcmlvcml0eSgnZXJyb3InKSkge1xuICAgICAgY29uc3Qgcm5Mb2dnZXIgPSBnZXRSbkxvZ2dlcigpO1xuICAgICAgaWYgKHJuTG9nZ2VyKSB7XG4gICAgICAgIHJuTG9nZ2VyLmVycm9yKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2luc3RvbkxvZ2dlciA9IGdldFdpbnN0b25Mb2dnZXIoKTtcbiAgICAgICAgaWYgKHdpbnN0b25Mb2dnZXIpIHtcbiAgICAgICAgICB3aW5zdG9uTG9nZ2VyLmVycm9yKC4uLmFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignW2Vycm9yXScsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBzaW5rID0gZ2V0RmlsZVNpbmsoKTtcbiAgICAgIGlmIChzaW5rKSBzaW5rLndyaXRlKCdlcnJvcicsIGFyZ3MpO1xuICAgICAgY29uc3QgcmVtb3RlID0gZ2V0UmVtb3RlU2luaygpO1xuICAgICAgaWYgKHJlbW90ZSkgcmVtb3RlLndyaXRlKCdlcnJvcicsIGFyZ3MpO1xuICAgICAgZW1pdFRlbGVtZXRyeUJyaWRnZShcImVycm9yXCIsIGFyZ3MpO1xuICAgIH1cbiAgfSxcbiAgd2FybjogKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgaWYgKGxldmVsUHJpb3JpdHkoY3VycmVudExldmVsKSA+PSBsZXZlbFByaW9yaXR5KCd3YXJuJykpIHtcbiAgICAgIGNvbnN0IHJuTG9nZ2VyID0gZ2V0Um5Mb2dnZXIoKTtcbiAgICAgIGlmIChybkxvZ2dlcikge1xuICAgICAgICBybkxvZ2dlci53YXJuKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2luc3RvbkxvZ2dlciA9IGdldFdpbnN0b25Mb2dnZXIoKTtcbiAgICAgICAgaWYgKHdpbnN0b25Mb2dnZXIpIHtcbiAgICAgICAgICB3aW5zdG9uTG9nZ2VyLndhcm4oLi4uYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1t3YXJuXScsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBzaW5rID0gZ2V0RmlsZVNpbmsoKTtcbiAgICAgIGlmIChzaW5rKSBzaW5rLndyaXRlKCd3YXJuJywgYXJncyk7XG4gICAgICBjb25zdCByZW1vdGUgPSBnZXRSZW1vdGVTaW5rKCk7XG4gICAgICBpZiAocmVtb3RlKSByZW1vdGUud3JpdGUoJ3dhcm4nLCBhcmdzKTtcbiAgICAgIGVtaXRUZWxlbWV0cnlCcmlkZ2UoXCJ3YXJuXCIsIGFyZ3MpO1xuICAgIH1cbiAgfSxcbiAgaW5mbzogKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgaWYgKGxldmVsUHJpb3JpdHkoY3VycmVudExldmVsKSA+PSBsZXZlbFByaW9yaXR5KCdpbmZvJykpIHtcbiAgICAgIGNvbnN0IHJuTG9nZ2VyID0gZ2V0Um5Mb2dnZXIoKTtcbiAgICAgIGlmIChybkxvZ2dlcikge1xuICAgICAgICBybkxvZ2dlci5pbmZvKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2luc3RvbkxvZ2dlciA9IGdldFdpbnN0b25Mb2dnZXIoKTtcbiAgICAgICAgaWYgKHdpbnN0b25Mb2dnZXIpIHtcbiAgICAgICAgICB3aW5zdG9uTG9nZ2VyLmluZm8oLi4uYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmxvZygnW2luZm9dJywgLi4uYXJncyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpbmsgPSBnZXRGaWxlU2luaygpO1xuICAgICAgaWYgKHNpbmspIHNpbmsud3JpdGUoJ2luZm8nLCBhcmdzKTtcbiAgICAgIGNvbnN0IHJlbW90ZSA9IGdldFJlbW90ZVNpbmsoKTtcbiAgICAgIGlmIChyZW1vdGUpIHJlbW90ZS53cml0ZSgnaW5mbycsIGFyZ3MpO1xuICAgIH1cbiAgfSxcbiAgZGVidWc6ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIGlmIChsZXZlbFByaW9yaXR5KGN1cnJlbnRMZXZlbCkgPj0gbGV2ZWxQcmlvcml0eSgnZGVidWcnKSkge1xuICAgICAgY29uc3Qgcm5Mb2dnZXIgPSBnZXRSbkxvZ2dlcigpO1xuICAgICAgaWYgKHJuTG9nZ2VyKSB7XG4gICAgICAgIHJuTG9nZ2VyLmRlYnVnKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2luc3RvbkxvZ2dlciA9IGdldFdpbnN0b25Mb2dnZXIoKTtcbiAgICAgICAgaWYgKHdpbnN0b25Mb2dnZXIpIHtcbiAgICAgICAgICB3aW5zdG9uTG9nZ2VyLmRlYnVnKC4uLmFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5kZWJ1ZyA/IGNvbnNvbGUuZGVidWcoJ1tkZWJ1Z10nLCAuLi5hcmdzKSA6IGNvbnNvbGUubG9nKCdbZGVidWddJywgLi4uYXJncyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpbmsgPSBnZXRGaWxlU2luaygpO1xuICAgICAgaWYgKHNpbmspIHNpbmsud3JpdGUoJ2RlYnVnJywgYXJncyk7XG4gICAgICBjb25zdCByZW1vdGUgPSBnZXRSZW1vdGVTaW5rKCk7XG4gICAgICBpZiAocmVtb3RlKSByZW1vdGUud3JpdGUoJ2RlYnVnJywgYXJncyk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBsb2dnZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUdBLElBQUFBLFlBQUEsR0FBQUMsT0FBQTtBQUF3QyxTQUFBQyxRQUFBQyxDQUFBLEVBQUFDLENBQUEsUUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLElBQUEsQ0FBQUosQ0FBQSxPQUFBRyxNQUFBLENBQUFFLHFCQUFBLFFBQUFDLENBQUEsR0FBQUgsTUFBQSxDQUFBRSxxQkFBQSxDQUFBTCxDQUFBLEdBQUFDLENBQUEsS0FBQUssQ0FBQSxHQUFBQSxDQUFBLENBQUFDLE1BQUEsV0FBQU4sQ0FBQSxXQUFBRSxNQUFBLENBQUFL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
|