@dollhousemcp/mcp-server 2.0.29 → 2.0.31

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 (34) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/generated/version.d.ts +2 -2
  3. package/dist/generated/version.js +3 -3
  4. package/dist/handlers/mcp-aql/OperationSchema.js +2 -2
  5. package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -1
  6. package/dist/handlers/mcp-aql/evaluatePermission.js +6 -3
  7. package/dist/services/BuildInfoService.d.ts +5 -0
  8. package/dist/services/BuildInfoService.d.ts.map +1 -1
  9. package/dist/services/BuildInfoService.js +44 -8
  10. package/dist/utils/permissionHookInstallers.d.ts +27 -0
  11. package/dist/utils/permissionHookInstallers.d.ts.map +1 -0
  12. package/dist/utils/permissionHookInstallers.js +465 -0
  13. package/dist/utils/permissionHookShared.d.ts +165 -0
  14. package/dist/utils/permissionHookShared.d.ts.map +1 -0
  15. package/dist/utils/permissionHookShared.js +425 -0
  16. package/dist/utils/permissionHookStatus.d.ts +10 -0
  17. package/dist/utils/permissionHookStatus.d.ts.map +1 -0
  18. package/dist/utils/permissionHookStatus.js +260 -0
  19. package/dist/utils/permissionHooks.d.ts +3 -91
  20. package/dist/utils/permissionHooks.d.ts.map +1 -1
  21. package/dist/utils/permissionHooks.js +4 -947
  22. package/dist/web/routes/healthRoutes.d.ts +3 -0
  23. package/dist/web/routes/healthRoutes.d.ts.map +1 -1
  24. package/dist/web/routes/healthRoutes.js +24 -2
  25. package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
  26. package/dist/web/routes/permissionRoutes.js +21 -2
  27. package/dist/web/server.d.ts.map +1 -1
  28. package/dist/web/server.js +9 -2
  29. package/package.json +3 -1
  30. package/scripts/permission-hook-config.sh +67 -0
  31. package/scripts/pretooluse-dollhouse.sh +185 -38
  32. package/scripts/pretooluse-vscode.sh +23 -10
  33. package/scripts/pretooluse-windsurf.sh +6 -6
  34. package/server.json +2 -2
@@ -0,0 +1,425 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { access, chmod, copyFile, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { homedir, platform } from 'node:os';
6
+ import { UnicodeValidator } from '../security/validators/unicodeValidator.js';
7
+ import { logger } from './logger.js';
8
+ export const MANAGED_HOOK_WRAPPER_BASENAMES = {
9
+ 'vscode': 'pretooluse-vscode.sh',
10
+ 'cursor': 'pretooluse-cursor.sh',
11
+ 'windsurf': 'pretooluse-windsurf.sh',
12
+ 'gemini-cli': 'pretooluse-gemini.sh',
13
+ 'codex': 'pretooluse-codex.sh',
14
+ };
15
+ export const WRAPPER_HOOK_HOSTS = Object.keys(MANAGED_HOOK_WRAPPER_BASENAMES);
16
+ export const AUTO_REPAIRABLE_HOOK_HOSTS = ['claude-code', ...WRAPPER_HOOK_HOSTS];
17
+ function repoRootFromModule() {
18
+ const currentFile = fileURLToPath(import.meta.url);
19
+ return dirname(dirname(dirname(currentFile)));
20
+ }
21
+ export function isMissingFileError(error) {
22
+ return Boolean(error
23
+ && typeof error === 'object'
24
+ && 'code' in error
25
+ && error.code === 'ENOENT');
26
+ }
27
+ export function detectIndent(raw) {
28
+ for (const line of raw.split('\n')) {
29
+ if (line.length === 0 || line.startsWith('{') || line.startsWith('}'))
30
+ continue;
31
+ if (line.startsWith('\t'))
32
+ return '\t';
33
+ if (line.startsWith(' ')) {
34
+ const spaces = line.length - line.trimStart().length;
35
+ if (spaces >= 2)
36
+ return spaces;
37
+ }
38
+ }
39
+ return 2;
40
+ }
41
+ export function getPermissionHookScriptPath(homeDir = homedir()) {
42
+ return join(homeDir, '.dollhouse', 'hooks', 'pretooluse-dollhouse.sh');
43
+ }
44
+ function getPermissionHookRunDir(homeDir = homedir()) {
45
+ return join(homeDir, '.dollhouse', 'run');
46
+ }
47
+ export function getPermissionHookDiagnosticsPath(homeDir = homedir()) {
48
+ return join(getPermissionHookRunDir(homeDir), 'permission-hook-diagnostics.jsonl');
49
+ }
50
+ export function normalizeHookHost(host) {
51
+ return UnicodeValidator.normalize(host).normalizedContent.trim().toLowerCase();
52
+ }
53
+ function isHookMarkerFilename(entry) {
54
+ return entry.startsWith('hook-installed-') && entry.endsWith('.json');
55
+ }
56
+ export function readHostSpecificHookStatus(homeDir, host) {
57
+ const normalized = normalizeHookHost(host);
58
+ const status = readMarkerStatus(getPermissionHookMarkerPath(homeDir, normalized));
59
+ if (status.installed || status.assetsPrepared) {
60
+ return status;
61
+ }
62
+ if (normalized === 'claude-code') {
63
+ return readMarkerStatus(getPermissionHookMarkerPath(homeDir));
64
+ }
65
+ return { installed: false };
66
+ }
67
+ export function collectHookMarkerPaths(homeDir) {
68
+ const markerPaths = new Set([getPermissionHookMarkerPath(homeDir)]);
69
+ const runDir = getPermissionHookRunDir(homeDir);
70
+ try {
71
+ for (const entry of readdirSync(runDir)) {
72
+ if (isHookMarkerFilename(entry)) {
73
+ markerPaths.add(join(runDir, entry));
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ // No run dir yet — fall through to default false.
79
+ }
80
+ return markerPaths;
81
+ }
82
+ export async function collectHookMarkerPathsAsync(homeDir) {
83
+ const markerPaths = new Set([getPermissionHookMarkerPath(homeDir)]);
84
+ const runDir = getPermissionHookRunDir(homeDir);
85
+ try {
86
+ for (const entry of await readdir(runDir)) {
87
+ if (isHookMarkerFilename(entry)) {
88
+ markerPaths.add(join(runDir, entry));
89
+ }
90
+ }
91
+ }
92
+ catch {
93
+ // No run dir yet — fall through to default false.
94
+ }
95
+ return markerPaths;
96
+ }
97
+ export function summarizeMarkerStatuses(markerPaths) {
98
+ let fallback = { installed: false };
99
+ for (const markerPath of markerPaths) {
100
+ const status = readMarkerStatus(markerPath);
101
+ if (status.installed)
102
+ return status;
103
+ if (!fallback.assetsPrepared && status.assetsPrepared)
104
+ fallback = status;
105
+ }
106
+ return fallback;
107
+ }
108
+ export function getHookWrapperBasename(host) {
109
+ const normalizedHost = normalizeHookHost(host);
110
+ return MANAGED_HOOK_WRAPPER_BASENAMES[normalizedHost] ?? null;
111
+ }
112
+ export function getHookWrapperPath(host, homeDir = homedir()) {
113
+ const basename = getHookWrapperBasename(host);
114
+ return basename ? join(homeDir, '.dollhouse', 'hooks', basename) : null;
115
+ }
116
+ export function getHookSourcePath(host) {
117
+ const root = repoRootFromModule();
118
+ const basename = getHookWrapperBasename(host);
119
+ return basename ? join(root, 'scripts', basename) : join(root, 'scripts', 'pretooluse-dollhouse.sh');
120
+ }
121
+ export function supportsManagedHookAssets(host) {
122
+ const normalized = normalizeHookHost(host);
123
+ return normalized === 'claude-code' || getHookWrapperBasename(normalized) !== null;
124
+ }
125
+ export function getPrimaryHookScriptPath(host, homeDir = homedir()) {
126
+ return getHookWrapperPath(host, homeDir) ?? getPermissionHookScriptPath(homeDir);
127
+ }
128
+ export async function readLastPermissionHookDiagnostic(homeDir = homedir()) {
129
+ const diagnosticsPath = getPermissionHookDiagnosticsPath(homeDir);
130
+ try {
131
+ const raw = await readFile(diagnosticsPath, 'utf-8');
132
+ const lines = raw
133
+ .split('\n')
134
+ .map((line) => line.trim())
135
+ .filter((line) => line.length > 0);
136
+ const lastLine = lines.at(-1);
137
+ if (!lastLine) {
138
+ return null;
139
+ }
140
+ let parsed;
141
+ try {
142
+ parsed = JSON.parse(lastLine);
143
+ }
144
+ catch (error) {
145
+ logger.warn(`[PermissionHooks] Failed to parse hook diagnostics JSON from ${diagnosticsPath}: ${error instanceof Error ? error.message : String(error)}`);
146
+ return null;
147
+ }
148
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
149
+ logger.warn(`[PermissionHooks] Ignoring malformed hook diagnostics entry from ${diagnosticsPath}: expected JSON object.`);
150
+ return null;
151
+ }
152
+ return parsed;
153
+ }
154
+ catch (error) {
155
+ if (isMissingFileError(error)) {
156
+ return null;
157
+ }
158
+ logger.warn(`[PermissionHooks] Failed to read hook diagnostics from ${diagnosticsPath}: ${error instanceof Error ? error.message : String(error)}`);
159
+ return null;
160
+ }
161
+ }
162
+ export function getManagedHookAssets(host, homeDir = homedir(), sourceScriptPath) {
163
+ const normalized = normalizeHookHost(host);
164
+ const hooksDir = dirname(getPermissionHookScriptPath(homeDir));
165
+ const assets = [
166
+ {
167
+ kind: 'bridge',
168
+ sourcePath: sourceScriptPath ?? join(repoRootFromModule(), 'scripts', 'pretooluse-dollhouse.sh'),
169
+ targetPath: getPermissionHookScriptPath(homeDir),
170
+ },
171
+ {
172
+ kind: 'port-helper',
173
+ sourcePath: join(repoRootFromModule(), 'scripts', 'permission-port-discovery.sh'),
174
+ targetPath: join(hooksDir, 'permission-port-discovery.sh'),
175
+ },
176
+ {
177
+ kind: 'config-helper',
178
+ sourcePath: join(repoRootFromModule(), 'scripts', 'permission-hook-config.sh'),
179
+ targetPath: join(hooksDir, 'permission-hook-config.sh'),
180
+ },
181
+ ];
182
+ const wrapperTargetPath = getHookWrapperPath(normalized, homeDir);
183
+ if (wrapperTargetPath) {
184
+ assets.push({
185
+ kind: 'wrapper',
186
+ sourcePath: getHookSourcePath(normalized),
187
+ targetPath: wrapperTargetPath,
188
+ });
189
+ }
190
+ return assets;
191
+ }
192
+ async function readOptionalUtf8File(filePath) {
193
+ try {
194
+ return await readFile(filePath, 'utf-8');
195
+ }
196
+ catch (error) {
197
+ if (isMissingFileError(error)) {
198
+ return undefined;
199
+ }
200
+ throw error;
201
+ }
202
+ }
203
+ export async function auditHookAssets(host, homeDir = homedir(), sourceScriptPath) {
204
+ const assets = getManagedHookAssets(host, homeDir, sourceScriptPath);
205
+ const staleAssets = [];
206
+ let assetsPrepared = true;
207
+ for (const asset of assets) {
208
+ const sourceRaw = await readFile(asset.sourcePath, 'utf-8');
209
+ const targetRaw = await readOptionalUtf8File(asset.targetPath);
210
+ if (targetRaw === undefined) {
211
+ assetsPrepared = false;
212
+ staleAssets.push(asset);
213
+ continue;
214
+ }
215
+ if (targetRaw !== sourceRaw) {
216
+ staleAssets.push(asset);
217
+ }
218
+ }
219
+ return {
220
+ assetsPrepared,
221
+ assetsCurrent: staleAssets.length === 0,
222
+ staleAssets,
223
+ };
224
+ }
225
+ export function getPermissionHookMarkerPath(homeDir = homedir(), host) {
226
+ if (!host) {
227
+ return join(getPermissionHookRunDir(homeDir), 'hook-installed.json');
228
+ }
229
+ return join(getPermissionHookRunDir(homeDir), `hook-installed-${normalizeHookHost(host)}.json`);
230
+ }
231
+ export function getClaudeHookSettingsPath(homeDir = homedir()) {
232
+ return join(homeDir, '.claude', 'settings.json');
233
+ }
234
+ export function getVsCodeHookSettingsPath(homeDir = homedir()) {
235
+ return join(homeDir, '.copilot', 'hooks', 'dollhouse-permissions.json');
236
+ }
237
+ export function getVsCodeUserSettingsPath(homeDir = homedir()) {
238
+ const currentPlatform = platform();
239
+ if (currentPlatform === 'darwin') {
240
+ return join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'settings.json');
241
+ }
242
+ if (currentPlatform === 'win32') {
243
+ const appData = process.env.APPDATA || join(homeDir, 'AppData', 'Roaming');
244
+ return join(appData, 'Code', 'User', 'settings.json');
245
+ }
246
+ return join(homeDir, '.config', 'Code', 'User', 'settings.json');
247
+ }
248
+ export function getGeminiHookSettingsPath(homeDir = homedir()) {
249
+ return join(homeDir, '.gemini', 'settings.json');
250
+ }
251
+ export function getCursorHookSettingsPath(homeDir = homedir()) {
252
+ return join(homeDir, '.cursor', 'hooks.json');
253
+ }
254
+ export function getWindsurfHookSettingsPath(homeDir = homedir()) {
255
+ return join(homeDir, '.codeium', 'windsurf', 'hooks.json');
256
+ }
257
+ export function getCodexHookSettingsPath(homeDir = homedir()) {
258
+ return join(homeDir, '.codex', 'hooks.json');
259
+ }
260
+ export function getCodexConfigPath(homeDir = homedir()) {
261
+ return join(homeDir, '.codex', 'config.toml');
262
+ }
263
+ function toPermissionHookStatus(raw) {
264
+ if (typeof raw.host !== 'string' ||
265
+ typeof raw.scriptPath !== 'string') {
266
+ return { installed: false };
267
+ }
268
+ const scriptReady = existsSync(raw.scriptPath);
269
+ const settingsReady = !raw.settingsPath || existsSync(raw.settingsPath);
270
+ const additionalPathsReady = !raw.additionalPaths || raw.additionalPaths.every((path) => existsSync(path));
271
+ const assetsPrepared = (raw.assetsPrepared ?? raw.configured ?? true) && scriptReady;
272
+ const configured = (raw.configured ?? true) && scriptReady && settingsReady && additionalPathsReady;
273
+ return {
274
+ installed: configured,
275
+ configured,
276
+ assetsPrepared,
277
+ host: raw.host,
278
+ scriptPath: raw.scriptPath,
279
+ settingsPath: raw.settingsPath,
280
+ additionalPaths: raw.additionalPaths,
281
+ };
282
+ }
283
+ function readMarkerStatus(markerPath) {
284
+ try {
285
+ const raw = readFileSync(markerPath, 'utf-8');
286
+ return toPermissionHookStatus(JSON.parse(raw));
287
+ }
288
+ catch (error) {
289
+ if (!isMissingFileError(error)) {
290
+ logger.warn(`[Permissions] Failed to read hook marker at ${markerPath}: ${String(error)}`);
291
+ }
292
+ return { installed: false };
293
+ }
294
+ }
295
+ export function normalizeHooksRoot(parsed) {
296
+ const hooksValue = parsed.hooks;
297
+ if (!hooksValue || typeof hooksValue !== 'object' || Array.isArray(hooksValue)) {
298
+ parsed.hooks = {};
299
+ }
300
+ return parsed.hooks;
301
+ }
302
+ export function ensureCommandHook(parsed, eventName, command, matcher, extraHookFields = {}) {
303
+ const hooksRoot = normalizeHooksRoot(parsed);
304
+ const existingEntries = Array.isArray(hooksRoot[eventName])
305
+ ? hooksRoot[eventName].filter((entry) => typeof entry === 'object' && entry !== null)
306
+ : [];
307
+ hooksRoot[eventName] = existingEntries;
308
+ const commandExists = existingEntries.some((entry) => {
309
+ const hooks = Array.isArray(entry?.hooks) ? entry.hooks : [];
310
+ return hooks.some((hook) => hook?.type === 'command' && hook?.command === command);
311
+ });
312
+ if (commandExists) {
313
+ return { changed: false, parsed };
314
+ }
315
+ const wildcardEntry = existingEntries.find((entry) => (entry?.matcher === matcher || entry?.matcher === undefined) && Array.isArray(entry?.hooks));
316
+ if (wildcardEntry) {
317
+ const hooks = wildcardEntry.hooks;
318
+ hooks.push({
319
+ type: 'command',
320
+ command,
321
+ ...extraHookFields,
322
+ });
323
+ }
324
+ else {
325
+ existingEntries.push({
326
+ matcher,
327
+ hooks: [
328
+ {
329
+ type: 'command',
330
+ command,
331
+ ...extraHookFields,
332
+ },
333
+ ],
334
+ });
335
+ }
336
+ return { changed: true, parsed };
337
+ }
338
+ async function copyHookAsset(sourcePath, targetPath) {
339
+ await mkdir(dirname(targetPath), { recursive: true });
340
+ const sourceRaw = await readFile(sourcePath, 'utf-8');
341
+ let targetRaw;
342
+ try {
343
+ targetRaw = await readFile(targetPath, 'utf-8');
344
+ }
345
+ catch (error) {
346
+ if (!isMissingFileError(error)) {
347
+ throw error;
348
+ }
349
+ }
350
+ const changed = targetRaw === undefined || sourceRaw !== targetRaw;
351
+ if (changed) {
352
+ await copyFile(sourcePath, targetPath);
353
+ }
354
+ else {
355
+ await access(targetPath);
356
+ }
357
+ await chmod(targetPath, 0o755);
358
+ return changed;
359
+ }
360
+ export async function readOptionalUtf8(filePath, fallback) {
361
+ try {
362
+ return await readFile(filePath, 'utf-8');
363
+ }
364
+ catch (error) {
365
+ if (isMissingFileError(error)) {
366
+ return fallback;
367
+ }
368
+ throw error;
369
+ }
370
+ }
371
+ export async function writeBackupIfPresent(filePath, raw) {
372
+ if (!existsSync(filePath)) {
373
+ return undefined;
374
+ }
375
+ const backupPath = `${filePath}.dollhouse.bak`;
376
+ await writeFile(backupPath, raw, 'utf-8');
377
+ return backupPath;
378
+ }
379
+ export async function writeHookMarker(homeDir, marker) {
380
+ const markerPath = getPermissionHookMarkerPath(homeDir, marker.host);
381
+ await mkdir(dirname(markerPath), { recursive: true });
382
+ await writeFile(markerPath, JSON.stringify(marker, null, 2) + '\n', 'utf-8');
383
+ return markerPath;
384
+ }
385
+ export async function installHookAssetsForHost(client, homeDir, sourceScriptPath) {
386
+ const normalizedClient = normalizeHookHost(client);
387
+ const hooksDir = dirname(getPermissionHookScriptPath(homeDir));
388
+ const sharedTargetPath = getPermissionHookScriptPath(homeDir);
389
+ const sharedSourcePath = sourceScriptPath ?? join(repoRootFromModule(), 'scripts', 'pretooluse-dollhouse.sh');
390
+ const portHelperSourcePath = join(repoRootFromModule(), 'scripts', 'permission-port-discovery.sh');
391
+ const portHelperTargetPath = join(hooksDir, 'permission-port-discovery.sh');
392
+ const configHelperSourcePath = join(repoRootFromModule(), 'scripts', 'permission-hook-config.sh');
393
+ const configHelperTargetPath = join(hooksDir, 'permission-hook-config.sh');
394
+ const sharedStat = statSync(sharedSourcePath);
395
+ if (!sharedStat.isFile()) {
396
+ logger.warn(`[PermissionHooks] Shared hook bridge missing for ${normalizedClient}: ${sharedSourcePath}`);
397
+ throw new Error(`Permission hook source script not found: ${sharedSourcePath}`);
398
+ }
399
+ await copyHookAsset(sharedSourcePath, sharedTargetPath);
400
+ const portHelperStat = statSync(portHelperSourcePath);
401
+ if (!portHelperStat.isFile()) {
402
+ logger.warn(`[PermissionHooks] Port discovery helper missing for ${normalizedClient}: ${portHelperSourcePath}`);
403
+ throw new Error(`Permission hook helper script not found: ${portHelperSourcePath}`);
404
+ }
405
+ await copyHookAsset(portHelperSourcePath, portHelperTargetPath);
406
+ const configHelperStat = statSync(configHelperSourcePath);
407
+ if (!configHelperStat.isFile()) {
408
+ logger.warn(`[PermissionHooks] Config helper missing for ${normalizedClient}: ${configHelperSourcePath}`);
409
+ throw new Error(`Permission hook config helper not found: ${configHelperSourcePath}`);
410
+ }
411
+ await copyHookAsset(configHelperSourcePath, configHelperTargetPath);
412
+ const wrapperTargetPath = getHookWrapperPath(normalizedClient, homeDir);
413
+ if (!wrapperTargetPath) {
414
+ return { scriptPath: sharedTargetPath };
415
+ }
416
+ const wrapperSourcePath = getHookSourcePath(normalizedClient);
417
+ const wrapperStat = statSync(wrapperSourcePath);
418
+ if (!wrapperStat.isFile()) {
419
+ logger.warn(`[PermissionHooks] Wrapper hook script missing for ${normalizedClient}: ${wrapperSourcePath}`);
420
+ throw new Error(`Permission hook wrapper script not found: ${wrapperSourcePath}`);
421
+ }
422
+ await copyHookAsset(wrapperSourcePath, wrapperTargetPath);
423
+ return { scriptPath: wrapperTargetPath };
424
+ }
425
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbkhvb2tTaGFyZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvcGVybWlzc2lvbkhvb2tTaGFyZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEcsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBb0lyQyxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRztJQUM1QyxRQUFRLEVBQUUsc0JBQXNCO0lBQ2hDLFFBQVEsRUFBRSxzQkFBc0I7SUFDaEMsVUFBVSxFQUFFLHdCQUF3QjtJQUNwQyxZQUFZLEVBQUUsc0JBQXNCO0lBQ3BDLE9BQU8sRUFBRSxxQkFBcUI7Q0FDdEIsQ0FBQztBQUVYLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQXVELENBQUM7QUFFcEksTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxhQUFhLEVBQUUsR0FBRyxrQkFBa0IsQ0FBVSxDQUFDO0FBRTFGLFNBQVMsa0JBQWtCO0lBQ3pCLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMs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QUFNLGFBQWEsQ0FBQyxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBRXBFLE1BQU0saUJBQWlCLEdBQUcsa0JBQWtCLENBQUMsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDdkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxNQUFNLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDOUQsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDaEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQzFCLE1BQU0sQ0FBQyxJQUFJLENBQUMscURBQXFELGdCQUFnQixLQUFLLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUMzRyxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUNELE1BQU0sYUFBYSxDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDMUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDO0FBQzNDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMsIHJlYWRkaXJTeW5jLCBzdGF0U3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHsgYWNjZXNzLCBjaG1vZCwgY29weUZpbGUsIG1rZGlyLCByZWFkRmlsZSwgcmVhZGRpciwgd3JpdGVGaWxlIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICdub2RlOnVybCc7XG5pbXBvcnQgeyBob21lZGlyLCBwbGF0Zm9ybSB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tNYXJrZXIge1xuICBob3N0OiBzdHJpbmc7XG4gIHNjcmlwdFBhdGg6IHN0cmluZztcbiAgc2V0dGluZ3NQYXRoPzogc3RyaW5nO1xuICBhZGRpdGlvbmFsUGF0aHM/OiBzdHJpbmdbXTtcbiAgY29uZmlndXJlZD86IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgaW5zdGFsbGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGluc3RhbGxlZDogYm9vbGVhbjtcbiAgY29uZmlndXJlZD86IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgYXNzZXRzQ3VycmVudD86IGJvb2xlYW47XG4gIGF1dG9SZXBhaXJlZD86IGJvb2xlYW47XG4gIG5lZWRzUmVwYWlyPzogYm9vbGVhbjtcbiAgcmVwYWlyRXJyb3I/OiBzdHJpbmc7XG4gIGhvc3Q/OiBzdHJpbmc7XG4gIHNjcmlwdFBhdGg/OiBzdHJpbmc7XG4gIHNldHRpbmdzUGF0aD86IHN0cmluZztcbiAgYWRkaXRpb25hbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qKiBMYXRlc3QgSlNPTkwgZGlhZ25vc3RpYyBldmVudCBlbWl0dGVkIGJ5IGEgbG9jYWwgcGVybWlzc2lvbiBob29rIHdyYXBwZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25Ib29rRGlhZ25vc3RpY1JlY29yZCB7XG4gIHRpbWVzdGFtcDogc3RyaW5nO1xuICBpbnZvY2F0aW9uSWQ6IHN0cmluZztcbiAgZXZlbnQ6IHN0cmluZztcbiAgcGxhdGZvcm06IHN0cmluZztcbiAgc3RhZ2U6IHN0cmluZztcbiAgb3V0Y29tZT86IHN0cmluZztcbiAgcmVhc29uPzogc3RyaW5nO1xuICBob29rUGF0aD86IHN0cmluZztcbiAgZGlhZ25vc3RpY3NMb2dQYXRoPzogc3RyaW5nO1xuICBzZXNzaW9uSWQ/OiBzdHJpbmc7XG4gIHRvb2xOYW1lPzogc3RyaW5nO1xuICB0b29sSW5wdXQ/OiBzdHJpbmc7XG4gIHJhd0lucHV0Pzogc3RyaW5nO1xuICBhdXRob3JpdHlIb3N0Pzogc3RyaW5nO1xuICBhdXRob3JpdHlNb2RlPzogc3RyaW5nO1xuICBlbmRwb2ludD86IHN0cmluZztcbiAgcG9ydD86IHN0cmluZztcbiAgcGF5bG9hZD86IHN0cmluZztcbiAgcmVzcG9uc2U/OiBzdHJpbmc7XG4gIG5vcm1hbGl6ZWRSZXNwb25zZT86IHN0cmluZztcbiAgZW1pdHRlZFJlc3BvbnNlPzogc3RyaW5nO1xuICBhdHRlbXB0Pzogc3RyaW5nO1xuICBtYXhSZXRyaWVzPzogc3RyaW5nO1xuICB0aW1lb3V0U2Vjb25kcz86IHN0cmluZztcbiAgY3VybEV4aXQ/OiBzdHJpbmc7XG4gIHJhd0lucHV0TGVuZ3RoPzogbnVtYmVyO1xuICBub3JtYWxpemVkUmVzcG9uc2VMZW5ndGg/OiBudW1iZXI7XG4gIGVtaXR0ZWRSZXNwb25zZUxlbmd0aD86IG51bWJlcjtcbiAgcmVzcG9uc2VMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFsbFBlcm1pc3Npb25Ib29rUmVzdWx0IHtcbiAgc3VwcG9ydGVkOiBib29sZWFuO1xuICBpbnN0YWxsZWQ6IGJvb2xlYW47XG4gIGNvbmZpZ3VyZWQ6IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgaG9zdDogc3RyaW5nO1xuICBzY3JpcHRQYXRoPzogc3RyaW5nO1xuICBzZXR0aW5nc1BhdGg/OiBzdHJpbmc7XG4gIGFkZGl0aW9uYWxQYXRocz86IHN0cmluZ1tdO1xuICBtYXJrZXJQYXRoPzogc3RyaW5nO1xuICBiYWNrdXBQYXRoPzogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFsbFBlcm1pc3Npb25Ib29rT3B0aW9ucyB7XG4gIGhvbWVEaXI/OiBzdHJpbmc7XG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmc7XG4gIG5vdz86IERhdGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb25jaWxlUGVybWlzc2lvbkhvb2tPcHRpb25zIHtcbiAgaG9tZURpcj86IHN0cmluZztcbiAgc291cmNlU2NyaXB0UGF0aD86IHN0cmluZztcbiAgYXV0b1JlcGFpcj86IGJvb2xlYW47XG59XG5cbi8qKiBBZ2dyZWdhdGUgaGVhbHRoIGFuZCByZXBhaXIgc3RhdGUgZm9yIGFsbCBtYW5hZ2VkIGxvY2FsIGhvb2sgaG9zdHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5IHtcbiAgaW5zdGFsbGVkSG9zdHM6IHN0cmluZ1tdO1xuICBjdXJyZW50SG9zdHM6IHN0cmluZ1tdO1xuICByZXBhaXJlZEhvc3RzOiBzdHJpbmdbXTtcbiAgbmVlZHNSZXBhaXJIb3N0czogc3RyaW5nW107XG4gIGRpYWdub3N0aWNzUGF0aDogc3RyaW5nO1xuICBsYXN0RGlhZ25vc3RpYzogUGVybWlzc2lvbkhvb2tEaWFnbm9zdGljUmVjb3JkIHwgbnVsbDtcbiAgbGFzdFN0YXJ0dXBSZXBhaXI6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgfCBudWxsO1xufVxuXG4vKiogQ29uZGVuc2VkIGhlYWx0aCB2aWV3IHN1cmZhY2VkIGluIHNldHVwLCBwZXJtaXNzaW9ucywgYW5kIGJ1aWxkIGluZm8uICovXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25Ib29rSGVhbHRoU3VtbWFyeSB7XG4gIHN0YXR1czogJ29rJyB8ICd3YXJuaW5nJyB8ICdlcnJvcic7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgcmVwYWlyZWRDb3VudDogbnVtYmVyO1xuICBuZWVkc1JlcGFpckNvdW50OiBudW1iZXI7XG4gIGxhc3RDaGVja2VkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdCBleHRlbmRzIFBlcm1pc3Npb25Ib29rU3RhdHVzIHtcbiAgaG9zdDogc3RyaW5nO1xuICBvdXRjb21lOiAnY3VycmVudCcgfCAncmVwYWlyZWQnIHwgJ25lZWRzX3JlcGFpcicgfCAnbm90X2luc3RhbGxlZCcgfCAnZXJyb3InO1xufVxuXG4vKiogUmVzdWx0IHN1bW1hcnkgZm9yIHRoZSBtb3N0IHJlY2VudCBzdGFydHVwLXRpbWUgaG9vayBhc3NldCByZXBhaXIgcGFzcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSB7XG4gIHN0YXJ0ZWRBdDogc3RyaW5nO1xuICBjb21wbGV0ZWRBdDogc3RyaW5nO1xuICBkdXJhdGlvbk1zOiBudW1iZXI7XG4gIHJlcGFpcmVkQ291bnQ6IG51bWJlcjtcbiAgbmVlZHNSZXBhaXJDb3VudDogbnVtYmVyO1xuICBob3N0UmVzdWx0czogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhvb2tBc3NldERlc2NyaXB0b3Ige1xuICBraW5kOiAnYnJpZGdlJyB8ICdwb3J0LWhlbHBlcicgfCAnY29uZmlnLWhlbHBlcicgfCAnd3JhcHBlcic7XG4gIHNvdXJjZVBhdGg6IHN0cmluZztcbiAgdGFyZ2V0UGF0aDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhvb2tBc3NldEF1ZGl0UmVzdWx0IHtcbiAgYXNzZXRzUHJlcGFyZWQ6IGJvb2xlYW47XG4gIGFzc2V0c0N1cnJlbnQ6IGJvb2xlYW47XG4gIHN0YWxlQXNzZXRzOiBIb29rQXNzZXREZXNjcmlwdG9yW107XG59XG5cbmV4cG9ydCBjb25zdCBNQU5BR0VEX0hPT0tfV1JBUFBFUl9CQVNFTkFNRVMgPSB7XG4gICd2c2NvZGUnOiAncHJldG9vbHVzZS12c2NvZGUuc2gnLFxuICAnY3Vyc29yJzogJ3ByZXRvb2x1c2UtY3Vyc29yLnNoJyxcbiAgJ3dpbmRzdXJmJzogJ3ByZXRvb2x1c2Utd2luZHN1cmYuc2gnLFxuICAnZ2VtaW5pLWNsaSc6ICdwcmV0b29sdXNlLWdlbWluaS5zaCcsXG4gICdjb2RleCc6ICdwcmV0b29sdXNlLWNvZGV4LnNoJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBXUkFQUEVSX0hPT0tfSE9TVFMgPSBPYmplY3Qua2V5cyhNQU5BR0VEX0hPT0tfV1JBUFBFUl9CQVNFTkFNRVMpIGFzIEFycmF5PGtleW9mIHR5cGVvZiBNQU5BR0VEX0hPT0tfV1JBUFBFUl9CQVNFTkFNRVM+O1xuXG5leHBvcnQgY29uc3QgQVVUT19SRVBBSVJBQkxFX0hPT0tfSE9TVFMgPSBbJ2NsYXVkZS1jb2RlJywgLi4uV1JBUFBFUl9IT09LX0hPU1RTXSBhcyBjb25zdDtcblxuZnVuY3Rpb24gcmVwb1Jvb3RGcm9tTW9kdWxlKCk6IHN0cmluZyB7XG4gIGNvbnN0IGN1cnJlbnRGaWxlID0gZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpO1xuICByZXR1cm4gZGlybmFtZShkaXJuYW1lKGRpcm5hbWUoY3VycmVudEZpbGUpKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01pc3NpbmdGaWxlRXJyb3IoZXJyb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgZXJyb3JcbiAgICAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnXG4gICAgJiYgJ2NvZGUnIGluIGVycm9yXG4gICAgJiYgKGVycm9yIGFzIHsgY29kZT86IHN0cmluZyB9KS5jb2RlID09PSAnRU5PRU5UJyxcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdEluZGVudChyYXc6IHN0cmluZyk6IG51bWJlciB8IHN0cmluZyB7XG4gIGZvciAoY29uc3QgbGluZSBvZiByYXcuc3BsaXQoJ1xcbicpKSB7XG4gICAgaWYgKGxpbmUubGVuZ3RoID09PSAwIHx8IGxpbmUuc3RhcnRzV2l0aCgneycpIHx8IGxpbmUuc3RhcnRzV2l0aCgnfScpKSBjb250aW51ZTtcbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCdcXHQnKSkgcmV0dXJuICdcXHQnO1xuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoJyAnKSkge1xuICAgICAgY29uc3Qgc3BhY2VzID0gbGluZS5sZW5ndGggLSBsaW5lLnRyaW1TdGFydCgpLmxlbmd0aDtcbiAgICAgIGlmIChzcGFjZXMgPj0gMikgcmV0dXJuIHNwYWNlcztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIDI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQZXJtaXNzaW9uSG9va1NjcmlwdFBhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuZG9sbGhvdXNlJywgJ2hvb2tzJywgJ3ByZXRvb2x1c2UtZG9sbGhvdXNlLnNoJyk7XG59XG5cbmZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rUnVuRGlyKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmRvbGxob3VzZScsICdydW4nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rRGlhZ25vc3RpY3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihnZXRQZXJtaXNzaW9uSG9va1J1bkRpcihob21lRGlyKSwgJ3Blcm1pc3Npb24taG9vay1kaWFnbm9zdGljcy5qc29ubCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplSG9va0hvc3QoaG9zdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIFVuaWNvZGVWYWxpZGF0b3Iubm9ybWFsaXplKGhvc3QpLm5vcm1hbGl6ZWRDb250ZW50LnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBpc0hvb2tNYXJrZXJGaWxlbmFtZShlbnRyeTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBlbnRyeS5zdGFydHNXaXRoKCdob29rLWluc3RhbGxlZC0nKSAmJiBlbnRyeS5lbmRzV2l0aCgnLmpzb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRIb3N0U3BlY2lmaWNIb29rU3RhdHVzKGhvbWVEaXI6IHN0cmluZywgaG9zdDogc3RyaW5nKTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplSG9va0hvc3QoaG9zdCk7XG4gIGNvbnN0IHN0YXR1cyA9IHJlYWRNYXJrZXJTdGF0dXMoZ2V0UGVybWlzc2lvbkhvb2tNYXJrZXJQYXRoKGhvbWVEaXIsIG5vcm1hbGl6ZWQpKTtcbiAgaWYgKHN0YXR1cy5pbnN0YWxsZWQgfHwgc3RhdHVzLmFzc2V0c1ByZXBhcmVkKSB7XG4gICAgcmV0dXJuIHN0YXR1cztcbiAgfVxuICBpZiAobm9ybWFsaXplZCA9PT0gJ2NsYXVkZS1jb2RlJykge1xuICAgIHJldHVybiByZWFkTWFya2VyU3RhdHVzKGdldFBlcm1pc3Npb25Ib29rTWFya2VyUGF0aChob21lRGlyKSk7XG4gIH1cbiAgcmV0dXJuIHsgaW5zdGFsbGVkOiBmYWxzZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdEhvb2tNYXJrZXJQYXRocyhob21lRGlyOiBzdHJpbmcpOiBTZXQ8c3RyaW5nPiB7XG4gIGNvbnN0IG1hcmtlclBhdGhzID0gbmV3IFNldDxzdHJpbmc+KFtnZXRQZXJtaXNzaW9uSG9va01hcmtlclBhdGgoaG9tZURpcildKTtcbiAgY29uc3QgcnVuRGlyID0gZ2V0UGVybWlzc2lvbkhvb2tSdW5EaXIoaG9tZURpcik7XG4gIHRyeSB7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiByZWFkZGlyU3luYyhydW5EaXIpKSB7XG4gICAgICBpZiAoaXNIb29rTWFya2VyRmlsZW5hbWUoZW50cnkpKSB7XG4gICAgICAgIG1hcmtlclBhdGhzLmFkZChqb2luKHJ1bkRpciwgZW50cnkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vIHJ1biBkaXIgeWV0IOKAlCBmYWxsIHRocm91Z2ggdG8gZGVmYXVsdCBmYWxzZS5cbiAgfVxuICByZXR1cm4gbWFya2VyUGF0aHM7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb2xsZWN0SG9va01hcmtlclBhdGhzQXN5bmMoaG9tZURpcjogc3RyaW5nKTogUHJvbWlzZTxTZXQ8c3RyaW5nPj4ge1xuICBjb25zdCBtYXJrZXJQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPihbZ2V0UGVybWlzc2lvbkhvb2tNYXJrZXJQYXRoKGhvbWVEaXIpXSk7XG4gIGNvbnN0IHJ1bkRpciA9IGdldFBlcm1pc3Npb25Ib29rUnVuRGlyKGhvbWVEaXIpO1xuICB0cnkge1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgYXdhaXQgcmVhZGRpcihydW5EaXIpKSB7XG4gICAgICBpZiAoaXNIb29rTWFya2VyRmlsZW5hbWUoZW50cnkpKSB7XG4gICAgICAgIG1hcmtlclBhdGhzLmFkZChqb2luKHJ1bkRpciwgZW50cnkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vIHJ1biBkaXIgeWV0IOKAlCBmYWxsIHRocm91Z2ggdG8gZGVmYXVsdCBmYWxzZS5cbiAgfVxuICByZXR1cm4gbWFya2VyUGF0aHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdW1tYXJpemVNYXJrZXJTdGF0dXNlcyhtYXJrZXJQYXRoczogSXRlcmFibGU8c3RyaW5nPik6IFBlcm1pc3Npb25Ib29rU3RhdHVzIHtcbiAgbGV0IGZhbGxiYWNrOiBQZXJtaXNzaW9uSG9va1N0YXR1cyA9IHsgaW5zdGFsbGVkOiBmYWxzZSB9O1xuICBmb3IgKGNvbnN0IG1hcmtlclBhdGggb2YgbWFya2VyUGF0aHMpIHtcbiAgICBjb25zdCBzdGF0dXMgPSByZWFkTWFya2VyU3RhdHVzKG1hcmtlclBhdGgpO1xuICAgIGlmIChzdGF0dXMuaW5zdGFsbGVkKSByZXR1cm4gc3RhdHVzO1xuICAgIGlmICghZmFsbGJhY2suYXNzZXRzUHJlcGFyZWQgJiYgc3RhdHVzLmFzc2V0c1ByZXBhcmVkKSBmYWxsYmFjayA9IHN0YXR1cztcbiAgfVxuICByZXR1cm4gZmFsbGJhY2s7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIb29rV3JhcHBlckJhc2VuYW1lKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBub3JtYWxpemVkSG9zdCA9IG5vcm1hbGl6ZUhvb2tIb3N0KGhvc3QpO1xuICByZXR1cm4gTUFOQUdFRF9IT09LX1dSQVBQRVJfQkFTRU5BTUVTW25vcm1hbGl6ZWRIb3N0IGFzIGtleW9mIHR5cGVvZiBNQU5BR0VEX0hPT0tfV1JBUFBFUl9CQVNFTkFNRVNdID8/IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIb29rV3JhcHBlclBhdGgoaG9zdDogc3RyaW5nLCBob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGJhc2VuYW1lID0gZ2V0SG9va1dyYXBwZXJCYXNlbmFtZShob3N0KTtcbiAgcmV0dXJuIGJhc2VuYW1lID8gam9pbihob21lRGlyLCAnLmRvbGxob3VzZScsICdob29rcycsIGJhc2VuYW1lKSA6IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIb29rU291cmNlUGF0aChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByb290ID0gcmVwb1Jvb3RGcm9tTW9kdWxlKCk7XG4gIGNvbnN0IGJhc2VuYW1lID0gZ2V0SG9va1dyYXBwZXJCYXNlbmFtZShob3N0KTtcbiAgcmV0dXJuIGJhc2VuYW1lID8gam9pbihyb290LCAnc2NyaXB0cycsIGJhc2VuYW1lKSA6IGpvaW4ocm9vdCwgJ3NjcmlwdHMnLCAncHJldG9vbHVzZS1kb2xsaG91c2Uuc2gnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRzTWFuYWdlZEhvb2tBc3NldHMoaG9zdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVIb29rSG9zdChob3N0KTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgPT09ICdjbGF1ZGUtY29kZScgfHwgZ2V0SG9va1dyYXBwZXJCYXNlbmFtZShub3JtYWxpemVkKSAhPT0gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByaW1hcnlIb29rU2NyaXB0UGF0aChob3N0OiBzdHJpbmcsIGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gZ2V0SG9va1dyYXBwZXJQYXRoKGhvc3QsIGhvbWVEaXIpID8/IGdldFBlcm1pc3Npb25Ib29rU2NyaXB0UGF0aChob21lRGlyKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRMYXN0UGVybWlzc2lvbkhvb2tEaWFnbm9zdGljKFxuICBob21lRGlyID0gaG9tZWRpcigpLFxuKTogUHJvbWlzZTxQZXJtaXNzaW9uSG9va0RpYWdub3N0aWNSZWNvcmQgfCBudWxsPiB7XG4gIGNvbnN0IGRpYWdub3N0aWNzUGF0aCA9IGdldFBlcm1pc3Npb25Ib29rRGlhZ25vc3RpY3NQYXRoKGhvbWVEaXIpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgcmF3ID0gYXdhaXQgcmVhZEZpbGUoZGlhZ25vc3RpY3NQYXRoLCAndXRmLTgnKTtcbiAgICBjb25zdCBsaW5lcyA9IHJhd1xuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lLmxlbmd0aCA+IDApO1xuICAgIGNvbnN0IGxhc3RMaW5lID0gbGluZXMuYXQoLTEpO1xuICAgIGlmICghbGFzdExpbmUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCBwYXJzZWQ6IHVua25vd247XG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZCA9IEpTT04ucGFyc2UobGFzdExpbmUpIGFzIHVua25vd247XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICBgW1Blcm1pc3Npb25Ib29rc10gRmFpbGVkIHRvIHBhcnNlIGhvb2sgZGlhZ25vc3RpY3MgSlNPTiBmcm9tICR7ZGlhZ25vc3RpY3NQYXRofTogJHtcbiAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgICAgfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJzZWQgfHwgdHlwZW9mIHBhcnNlZCAhPT0gJ29iamVjdCcgfHwgQXJyYXkuaXNBcnJheShwYXJzZWQpKSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgYFtQZXJtaXNzaW9uSG9va3NdIElnbm9yaW5nIG1hbGZvcm1lZCBob29rIGRpYWdub3N0aWNzIGVudHJ5IGZyb20gJHtkaWFnbm9zdGljc1BhdGh9OiBleHBlY3RlZCBKU09OIG9iamVjdC5gLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWQgYXMgUGVybWlzc2lvbkhvb2tEaWFnbm9zdGljUmVjb3JkO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChpc01pc3NpbmdGaWxlRXJyb3IoZXJyb3IpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBsb2dnZXIud2FybihcbiAgICAgIGBbUGVybWlzc2lvbkhvb2tzXSBGYWlsZWQgdG8gcmVhZCBob29rIGRpYWdub3N0aWNzIGZyb20gJHtkaWFnbm9zdGljc1BhdGh9OiAke1xuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgIH1gLFxuICAgICk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hbmFnZWRIb29rQXNzZXRzKFxuICBob3N0OiBzdHJpbmcsXG4gIGhvbWVEaXIgPSBob21lZGlyKCksXG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmcsXG4pOiBIb29rQXNzZXREZXNjcmlwdG9yW10ge1xuICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplSG9va0hvc3QoaG9zdCk7XG4gIGNvbnN0IGhvb2tzRGlyID0gZGlybmFtZShnZXRQZXJtaXNzaW9uSG9va1NjcmlwdFBhdGgoaG9tZURpcikpO1xuICBjb25zdCBhc3NldHM6IEhvb2tBc3NldERlc2NyaXB0b3JbXSA9IFtcbiAgICB7XG4gICAgICBraW5kOiAnYnJpZGdlJyxcbiAgICAgIHNvdXJjZVBhdGg6IHNvdXJjZVNjcmlwdFBhdGggPz8gam9pbihyZXBvUm9vdEZyb21Nb2R1bGUoKSwgJ3NjcmlwdHMnLCAncHJldG9vbHVzZS1kb2xsaG91c2Uuc2gnKSxcbiAgICAgIHRhcmdldFBhdGg6IGdldFBlcm1pc3Npb25Ib29rU2NyaXB0UGF0aChob21lRGlyKSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtpbmQ6ICdwb3J0LWhlbHBlcicsXG4gICAgICBzb3VyY2VQYXRoOiBqb2luKHJlcG9Sb290RnJvbU1vZHVsZSgpLCAnc2NyaXB0cycsICdwZXJtaXNzaW9uLXBvcnQtZGlzY292ZXJ5LnNoJyksXG4gICAgICB0YXJnZXRQYXRoOiBqb2luKGhvb2tzRGlyLCAncGVybWlzc2lvbi1wb3J0LWRpc2NvdmVyeS5zaCcpLFxuICAgIH0sXG4gICAge1xuICAgICAga2luZDogJ2NvbmZpZy1oZWxwZXInLFxuICAgICAgc291cmNlUGF0aDogam9pbihyZXBvUm9vdEZyb21Nb2R1bGUoKSwgJ3NjcmlwdHMnLCAncGVybWlzc2lvbi1ob29rLWNvbmZpZy5zaCcpLFxuICAgICAgdGFyZ2V0UGF0aDogam9pbihob29rc0RpciwgJ3Blcm1pc3Npb24taG9vay1jb25maWcuc2gnKSxcbiAgICB9LFxuICBdO1xuXG4gIGNvbnN0IHdyYXBwZXJUYXJnZXRQYXRoID0gZ2V0SG9va1dyYXBwZXJQYXRoKG5vcm1hbGl6ZWQsIGhvbWVEaXIpO1xuICBpZiAod3JhcHBlclRhcmdldFBhdGgpIHtcbiAgICBhc3NldHMucHVzaCh7XG4gICAgICBraW5kOiAnd3JhcHBlcicsXG4gICAgICBzb3VyY2VQYXRoOiBnZXRIb29rU291cmNlUGF0aChub3JtYWxpemVkKSxcbiAgICAgIHRhcmdldFBhdGg6IHdyYXBwZXJUYXJnZXRQYXRoLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGFzc2V0cztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZE9wdGlvbmFsVXRmOEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaXNNaXNzaW5nRmlsZUVycm9yKGVycm9yKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF1ZGl0SG9va0Fzc2V0cyhcbiAgaG9zdDogc3RyaW5nLFxuICBob21lRGlyID0gaG9tZWRpcigpLFxuICBzb3VyY2VTY3JpcHRQYXRoPzogc3RyaW5nLFxuKTogUHJvbWlzZTxIb29rQXNzZXRBdWRpdFJlc3VsdD4ge1xuICBjb25zdCBhc3NldHMgPSBnZXRNYW5hZ2VkSG9va0Fzc2V0cyhob3N0LCBob21lRGlyLCBzb3VyY2VTY3JpcHRQYXRoKTtcbiAgY29uc3Qgc3RhbGVBc3NldHM6IEhvb2tBc3NldERlc2NyaXB0b3JbXSA9IFtdO1xuICBsZXQgYXNzZXRzUHJlcGFyZWQgPSB0cnVlO1xuXG4gIGZvciAoY29uc3QgYXNzZXQgb2YgYXNzZXRzKSB7XG4gICAgY29uc3Qgc291cmNlUmF3ID0gYXdhaXQgcmVhZEZpbGUoYXNzZXQuc291cmNlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgY29uc3QgdGFyZ2V0UmF3ID0gYXdhaXQgcmVhZE9wdGlvbmFsVXRmOEZpbGUoYXNzZXQudGFyZ2V0UGF0aCk7XG4gICAgaWYgKHRhcmdldFJhdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhc3NldHNQcmVwYXJlZCA9IGZhbHNlO1xuICAgICAgc3RhbGVBc3NldHMucHVzaChhc3NldCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKHRhcmdldFJhdyAhPT0gc291cmNlUmF3KSB7XG4gICAgICBzdGFsZUFzc2V0cy5wdXNoKGFzc2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzc2V0c1ByZXBhcmVkLFxuICAgIGFzc2V0c0N1cnJlbnQ6IHN0YWxlQXNzZXRzLmxlbmd0aCA9PT0gMCxcbiAgICBzdGFsZUFzc2V0cyxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rTWFya2VyUGF0aChob21lRGlyID0gaG9tZWRpcigpLCBob3N0Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFob3N0KSB7XG4gICAgcmV0dXJuIGpvaW4oZ2V0UGVybWlzc2lvbkhvb2tSdW5EaXIoaG9tZURpciksICdob29rLWluc3RhbGxlZC5qc29uJyk7XG4gIH1cbiAgcmV0dXJuIGpvaW4oZ2V0UGVybWlzc2lvbkhvb2tSdW5EaXIoaG9tZURpciksIGBob29rLWluc3RhbGxlZC0ke25vcm1hbGl6ZUhvb2tIb3N0KGhvc3QpfS5qc29uYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGF1ZGVIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNsYXVkZScsICdzZXR0aW5ncy5qc29uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWc0NvZGVIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNvcGlsb3QnLCAnaG9va3MnLCAnZG9sbGhvdXNlLXBlcm1pc3Npb25zLmpzb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZzQ29kZVVzZXJTZXR0aW5nc1BhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIGNvbnN0IGN1cnJlbnRQbGF0Zm9ybSA9IHBsYXRmb3JtKCk7XG4gIGlmIChjdXJyZW50UGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XG4gICAgcmV0dXJuIGpvaW4oaG9tZURpciwgJ0xpYnJhcnknLCAnQXBwbGljYXRpb24gU3VwcG9ydCcsICdDb2RlJywgJ1VzZXInLCAnc2V0dGluZ3MuanNvbicpO1xuICB9XG4gIGlmIChjdXJyZW50UGxhdGZvcm0gPT09ICd3aW4zMicpIHtcbiAgICBjb25zdCBhcHBEYXRhID0gcHJvY2Vzcy5lbnYuQVBQREFUQSB8fCBqb2luKGhvbWVEaXIsICdBcHBEYXRhJywgJ1JvYW1pbmcnKTtcbiAgICByZXR1cm4gam9pbihhcHBEYXRhLCAnQ29kZScsICdVc2VyJywgJ3NldHRpbmdzLmpzb24nKTtcbiAgfVxuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNvbmZpZycsICdDb2RlJywgJ1VzZXInLCAnc2V0dGluZ3MuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2VtaW5pSG9va1NldHRpbmdzUGF0aChob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oaG9tZURpciwgJy5nZW1pbmknLCAnc2V0dGluZ3MuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3Vyc29ySG9va1NldHRpbmdzUGF0aChob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oaG9tZURpciwgJy5jdXJzb3InLCAnaG9va3MuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V2luZHN1cmZIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNvZGVpdW0nLCAnd2luZHN1cmYnLCAnaG9va3MuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29kZXhIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNvZGV4JywgJ2hvb2tzLmpzb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvZGV4Q29uZmlnUGF0aChob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oaG9tZURpciwgJy5jb2RleCcsICdjb25maWcudG9tbCcpO1xufVxuXG5mdW5jdGlvbiB0b1Blcm1pc3Npb25Ib29rU3RhdHVzKHJhdzogUGVybWlzc2lvbkhvb2tNYXJrZXIpOiBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGlmIChcbiAgICB0eXBlb2YgcmF3Lmhvc3QgIT09ICdzdHJpbmcnIHx8XG4gICAgdHlwZW9mIHJhdy5zY3JpcHRQYXRoICE9PSAnc3RyaW5nJ1xuICApIHtcbiAgICByZXR1cm4geyBpbnN0YWxsZWQ6IGZhbHNlIH07XG4gIH1cblxuICBjb25zdCBzY3JpcHRSZWFkeSA9IGV4aXN0c1N5bmMocmF3LnNjcmlwdFBhdGgpO1xuICBjb25zdCBzZXR0aW5nc1JlYWR5ID0gIXJhdy5zZXR0aW5nc1BhdGggfHwgZXhpc3RzU3luYyhyYXcuc2V0dGluZ3NQYXRoKTtcbiAgY29uc3QgYWRkaXRpb25hbFBhdGhzUmVhZHkgPSAhcmF3LmFkZGl0aW9uYWxQYXRocyB8fCByYXcuYWRkaXRpb25hbFBhdGhzLmV2ZXJ5KChwYXRoKSA9PiBleGlzdHNTeW5jKHBhdGgpKTtcbiAgY29uc3QgYXNzZXRzUHJlcGFyZWQgPSAocmF3LmFzc2V0c1ByZXBhcmVkID8/IHJhdy5jb25maWd1cmVkID8/IHRydWUpICYmIHNjcmlwdFJlYWR5O1xuICBjb25zdCBjb25maWd1cmVkID0gKHJhdy5jb25maWd1cmVkID8/IHRydWUpICYmIHNjcmlwdFJlYWR5ICYmIHNldHRpbmdzUmVhZHkgJiYgYWRkaXRpb25hbFBhdGhzUmVhZHk7XG5cbiAgcmV0dXJuIHtcbiAgICBpbnN0YWxsZWQ6IGNvbmZpZ3VyZWQsXG4gICAgY29uZmlndXJlZCxcbiAgICBhc3NldHNQcmVwYXJlZCxcbiAgICBob3N0OiByYXcuaG9zdCxcbiAgICBzY3JpcHRQYXRoOiByYXcuc2NyaXB0UGF0aCxcbiAgICBzZXR0aW5nc1BhdGg6IHJhdy5zZXR0aW5nc1BhdGgsXG4gICAgYWRkaXRpb25hbFBhdGhzOiByYXcuYWRkaXRpb25hbFBhdGhzLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZWFkTWFya2VyU3RhdHVzKG1hcmtlclBhdGg6IHN0cmluZyk6IFBlcm1pc3Npb25Ib29rU3RhdHVzIHtcbiAgdHJ5IHtcbiAgICBjb25zdCByYXcgPSByZWFkRmlsZVN5bmMobWFya2VyUGF0aCwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIHRvUGVybWlzc2lvbkhvb2tTdGF0dXMoSlNPTi5wYXJzZShyYXcpIGFzIFBlcm1pc3Npb25Ib29rTWFya2VyKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIWlzTWlzc2luZ0ZpbGVFcnJvcihlcnJvcikpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBbUGVybWlzc2lvbnNdIEZhaWxlZCB0byByZWFkIGhvb2sgbWFya2VyIGF0ICR7bWFya2VyUGF0aH06ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgaW5zdGFsbGVkOiBmYWxzZSB9O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVIb29rc1Jvb3QocGFyc2VkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlY29yZDxzdHJpbmcsIHVua25vd25bXT4ge1xuICBjb25zdCBob29rc1ZhbHVlID0gcGFyc2VkLmhvb2tzO1xuICBpZiAoIWhvb2tzVmFsdWUgfHwgdHlwZW9mIGhvb2tzVmFsdWUgIT09ICdvYmplY3QnIHx8IEFycmF5LmlzQXJyYXkoaG9va3NWYWx1ZSkpIHtcbiAgICBwYXJzZWQuaG9va3MgPSB7fTtcbiAgfVxuICByZXR1cm4gcGFyc2VkLmhvb2tzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd25bXT47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVDb21tYW5kSG9vayhcbiAgcGFyc2VkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgZXZlbnROYW1lOiBzdHJpbmcsXG4gIGNvbW1hbmQ6IHN0cmluZyxcbiAgbWF0Y2hlcjogc3RyaW5nLFxuICBleHRyYUhvb2tGaWVsZHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiB7IGNoYW5nZWQ6IGJvb2xlYW47IHBhcnNlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfSB7XG4gIGNvbnN0IGhvb2tzUm9vdCA9IG5vcm1hbGl6ZUhvb2tzUm9vdChwYXJzZWQpO1xuICBjb25zdCBleGlzdGluZ0VudHJpZXM6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA9IEFycmF5LmlzQXJyYXkoaG9va3NSb290W2V2ZW50TmFtZV0pXG4gICAgPyBob29rc1Jvb3RbZXZlbnROYW1lXS5maWx0ZXIoKGVudHJ5KTogZW50cnkgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4gdHlwZW9mIGVudHJ5ID09PSAnb2JqZWN0JyAmJiBlbnRyeSAhPT0gbnVsbClcbiAgICA6IFtdO1xuICBob29rc1Jvb3RbZXZlbnROYW1lXSA9IGV4aXN0aW5nRW50cmllcztcblxuICBjb25zdCBjb21tYW5kRXhpc3RzID0gZXhpc3RpbmdFbnRyaWVzLnNvbWUoKGVudHJ5KSA9PiB7XG4gICAgY29uc3QgaG9va3MgPSBBcnJheS5pc0FycmF5KGVudHJ5Py5ob29rcykgPyBlbnRyeS5ob29rcyBhcyBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gOiBbXTtcbiAgICByZXR1cm4gaG9va3Muc29tZSgoaG9vaykgPT4gaG9vaz8udHlwZSA9PT0gJ2NvbW1hbmQnICYmIGhvb2s/LmNvbW1hbmQgPT09IGNvbW1hbmQpO1xuICB9KTtcbiAgaWYgKGNvbW1hbmRFeGlzdHMpIHtcbiAgICByZXR1cm4geyBjaGFuZ2VkOiBmYWxzZSwgcGFyc2VkIH07XG4gIH1cblxuICBjb25zdCB3aWxkY2FyZEVudHJ5ID0gZXhpc3RpbmdFbnRyaWVzLmZpbmQoKGVudHJ5KTogZW50cnkgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgICAoZW50cnk/Lm1hdGNoZXIgPT09IG1hdGNoZXIgfHwgZW50cnk/Lm1hdGNoZXIgPT09IHVuZGVmaW5lZCkgJiYgQXJyYXkuaXNBcnJheShlbnRyeT8uaG9va3MpLFxuICApO1xuXG4gIGlmICh3aWxkY2FyZEVudHJ5KSB7XG4gICAgY29uc3QgaG9va3MgPSB3aWxkY2FyZEVudHJ5Lmhvb2tzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgICBob29rcy5wdXNoKHtcbiAgICAgIHR5cGU6ICdjb21tYW5kJyxcbiAgICAgIGNvbW1hbmQsXG4gICAgICAuLi5leHRyYUhvb2tGaWVsZHMsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZXhpc3RpbmdFbnRyaWVzLnB1c2goe1xuICAgICAgbWF0Y2hlcixcbiAgICAgIGhvb2tzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnY29tbWFuZCcsXG4gICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICAuLi5leHRyYUhvb2tGaWVsZHMsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHsgY2hhbmdlZDogdHJ1ZSwgcGFyc2VkIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNvcHlIb29rQXNzZXQoc291cmNlUGF0aDogc3RyaW5nLCB0YXJnZXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZSh0YXJnZXRQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3Qgc291cmNlUmF3ID0gYXdhaXQgcmVhZEZpbGUoc291cmNlUGF0aCwgJ3V0Zi04Jyk7XG5cbiAgbGV0IHRhcmdldFJhdzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB0cnkge1xuICAgIHRhcmdldFJhdyA9IGF3YWl0IHJlYWRGaWxlKHRhcmdldFBhdGgsICd1dGYtOCcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICghaXNNaXNzaW5nRmlsZUVycm9yKGVycm9yKSkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG4gIGNvbnN0IGNoYW5nZWQgPSB0YXJnZXRSYXcgPT09IHVuZGVmaW5lZCB8fCBzb3VyY2VSYXcgIT09IHRhcmdldFJhdztcblxuICBpZiAoY2hhbmdlZCkge1xuICAgIGF3YWl0IGNvcHlGaWxlKHNvdXJjZVBhdGgsIHRhcmdldFBhdGgpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGFjY2Vzcyh0YXJnZXRQYXRoKTtcbiAgfVxuXG4gIGF3YWl0IGNobW9kKHRhcmdldFBhdGgsIDBvNzU1KTtcbiAgcmV0dXJuIGNoYW5nZWQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkT3B0aW9uYWxVdGY4KGZpbGVQYXRoOiBzdHJpbmcsIGZhbGxiYWNrOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGlzTWlzc2luZ0ZpbGVFcnJvcihlcnJvcikpIHtcbiAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlQmFja3VwSWZQcmVzZW50KGZpbGVQYXRoOiBzdHJpbmcsIHJhdzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgaWYgKCFleGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBiYWNrdXBQYXRoID0gYCR7ZmlsZVBhdGh9LmRvbGxob3VzZS5iYWtgO1xuICBhd2FpdCB3cml0ZUZpbGUoYmFja3VwUGF0aCwgcmF3LCAndXRmLTgnKTtcbiAgcmV0dXJuIGJhY2t1cFBhdGg7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZUhvb2tNYXJrZXIoXG4gIGhvbWVEaXI6IHN0cmluZyxcbiAgbWFya2VyOiBQZXJtaXNzaW9uSG9va01hcmtlcixcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG1hcmtlclBhdGggPSBnZXRQZXJtaXNzaW9uSG9va01hcmtlclBhdGgoaG9tZURpciwgbWFya2VyLmhvc3QpO1xuICBhd2FpdCBta2RpcihkaXJuYW1lKG1hcmtlclBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKG1hcmtlclBhdGgsIEpTT04uc3RyaW5naWZ5KG1hcmtlciwgbnVsbCwgMikgKyAnXFxuJywgJ3V0Zi04Jyk7XG4gIHJldHVybiBtYXJrZXJQYXRoO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5zdGFsbEhvb2tBc3NldHNGb3JIb3N0KFxuICBjbGllbnQ6IHN0cmluZyxcbiAgaG9tZURpcjogc3RyaW5nLFxuICBzb3VyY2VTY3JpcHRQYXRoPzogc3RyaW5nLFxuKTogUHJvbWlzZTx7IHNjcmlwdFBhdGg6IHN0cmluZyB9PiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRDbGllbnQgPSBub3JtYWxpemVIb29rSG9zdChjbGllbnQpO1xuICBjb25zdCBob29rc0RpciA9IGRpcm5hbWUoZ2V0UGVybWlzc2lvbkhvb2tTY3JpcHRQYXRoKGhvbWVEaXIpKTtcbiAgY29uc3Qgc2hhcmVkVGFyZ2V0UGF0aCA9IGdldFBlcm1pc3Npb25Ib29rU2NyaXB0UGF0aChob21lRGlyKTtcbiAgY29uc3Qgc2hhcmVkU291cmNlUGF0aCA9IHNvdXJjZVNjcmlwdFBhdGggPz8gam9pbihyZXBvUm9vdEZyb21Nb2R1bGUoKSwgJ3NjcmlwdHMnLCAncHJldG9vbHVzZS1kb2xsaG91c2Uuc2gnKTtcbiAgY29uc3QgcG9ydEhlbHBlclNvdXJjZVBhdGggPSBqb2luKHJlcG9Sb290RnJvbU1vZHVsZSgpLCAnc2NyaXB0cycsICdwZXJtaXNzaW9uLXBvcnQtZGlzY292ZXJ5LnNoJyk7XG4gIGNvbnN0IHBvcnRIZWxwZXJUYXJnZXRQYXRoID0gam9pbihob29rc0RpciwgJ3Blcm1pc3Npb24tcG9ydC1kaXNjb3Zlcnkuc2gnKTtcbiAgY29uc3QgY29uZmlnSGVscGVyU291cmNlUGF0aCA9IGpvaW4ocmVwb1Jvb3RGcm9tTW9kdWxlKCksICdzY3JpcHRzJywgJ3Blcm1pc3Npb24taG9vay1jb25maWcuc2gnKTtcbiAgY29uc3QgY29uZmlnSGVscGVyVGFyZ2V0UGF0aCA9IGpvaW4oaG9va3NEaXIsICdwZXJtaXNzaW9uLWhvb2stY29uZmlnLnNoJyk7XG5cbiAgY29uc3Qgc2hhcmVkU3RhdCA9IHN0YXRTeW5jKHNoYXJlZFNvdXJjZVBhdGgpO1xuICBpZiAoIXNoYXJlZFN0YXQuaXNGaWxlKCkpIHtcbiAgICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gU2hhcmVkIGhvb2sgYnJpZGdlIG1pc3NpbmcgZm9yICR7bm9ybWFsaXplZENsaWVudH06ICR7c2hhcmVkU291cmNlUGF0aH1gKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFBlcm1pc3Npb24gaG9vayBzb3VyY2Ugc2NyaXB0IG5vdCBmb3VuZDogJHtzaGFyZWRTb3VyY2VQYXRofWApO1xuICB9XG4gIGF3YWl0IGNvcHlIb29rQXNzZXQoc2hhcmVkU291cmNlUGF0aCwgc2hhcmVkVGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgcG9ydEhlbHBlclN0YXQgPSBzdGF0U3luYyhwb3J0SGVscGVyU291cmNlUGF0aCk7XG4gIGlmICghcG9ydEhlbHBlclN0YXQuaXNGaWxlKCkpIHtcbiAgICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gUG9ydCBkaXNjb3ZlcnkgaGVscGVyIG1pc3NpbmcgZm9yICR7bm9ybWFsaXplZENsaWVudH06ICR7cG9ydEhlbHBlclNvdXJjZVBhdGh9YCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBQZXJtaXNzaW9uIGhvb2sgaGVscGVyIHNjcmlwdCBub3QgZm91bmQ6ICR7cG9ydEhlbHBlclNvdXJjZVBhdGh9YCk7XG4gIH1cbiAgYXdhaXQgY29weUhvb2tBc3NldChwb3J0SGVscGVyU291cmNlUGF0aCwgcG9ydEhlbHBlclRhcmdldFBhdGgpO1xuXG4gIGNvbnN0IGNvbmZpZ0hlbHBlclN0YXQgPSBzdGF0U3luYyhjb25maWdIZWxwZXJTb3VyY2VQYXRoKTtcbiAgaWYgKCFjb25maWdIZWxwZXJTdGF0LmlzRmlsZSgpKSB7XG4gICAgbG9nZ2VyLndhcm4oYFtQZXJtaXNzaW9uSG9va3NdIENvbmZpZyBoZWxwZXIgbWlzc2luZyBmb3IgJHtub3JtYWxpemVkQ2xpZW50fTogJHtjb25maWdIZWxwZXJTb3VyY2VQYXRofWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgUGVybWlzc2lvbiBob29rIGNvbmZpZyBoZWxwZXIgbm90IGZvdW5kOiAke2NvbmZpZ0hlbHBlclNvdXJjZVBhdGh9YCk7XG4gIH1cbiAgYXdhaXQgY29weUhvb2tBc3NldChjb25maWdIZWxwZXJTb3VyY2VQYXRoLCBjb25maWdIZWxwZXJUYXJnZXRQYXRoKTtcblxuICBjb25zdCB3cmFwcGVyVGFyZ2V0UGF0aCA9IGdldEhvb2tXcmFwcGVyUGF0aChub3JtYWxpemVkQ2xpZW50LCBob21lRGlyKTtcbiAgaWYgKCF3cmFwcGVyVGFyZ2V0UGF0aCkge1xuICAgIHJldHVybiB7IHNjcmlwdFBhdGg6IHNoYXJlZFRhcmdldFBhdGggfTtcbiAgfVxuXG4gIGNvbnN0IHdyYXBwZXJTb3VyY2VQYXRoID0gZ2V0SG9va1NvdXJjZVBhdGgobm9ybWFsaXplZENsaWVudCk7XG4gIGNvbnN0IHdyYXBwZXJTdGF0ID0gc3RhdFN5bmMod3JhcHBlclNvdXJjZVBhdGgpO1xuICBpZiAoIXdyYXBwZXJTdGF0LmlzRmlsZSgpKSB7XG4gICAgbG9nZ2VyLndhcm4oYFtQZXJtaXNzaW9uSG9va3NdIFdyYXBwZXIgaG9vayBzY3JpcHQgbWlzc2luZyBmb3IgJHtub3JtYWxpemVkQ2xpZW50fTogJHt3cmFwcGVyU291cmNlUGF0aH1gKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFBlcm1pc3Npb24gaG9vayB3cmFwcGVyIHNjcmlwdCBub3QgZm91bmQ6ICR7d3JhcHBlclNvdXJjZVBhdGh9YCk7XG4gIH1cbiAgYXdhaXQgY29weUhvb2tBc3NldCh3cmFwcGVyU291cmNlUGF0aCwgd3JhcHBlclRhcmdldFBhdGgpO1xuICByZXR1cm4geyBzY3JpcHRQYXRoOiB3cmFwcGVyVGFyZ2V0UGF0aCB9O1xufVxuIl19
@@ -0,0 +1,10 @@
1
+ import { type PermissionHookAuditSummary, type PermissionHookHealthSummary, type PermissionHookStartupRepairSummary, type PermissionHookStatus, type ReconcilePermissionHookOptions } from './permissionHookShared.js';
2
+ export declare function getPermissionHookStatus(homeDir?: string, host?: string): PermissionHookStatus;
3
+ export declare function getPermissionHookStatusAsync(homeDir?: string, host?: string): Promise<PermissionHookStatus>;
4
+ export declare function getLastPermissionHookStartupRepairSummary(): PermissionHookStartupRepairSummary | null;
5
+ export declare function _resetPermissionHookStartupRepairSummaryForTests(): void;
6
+ export declare function reconcilePermissionHookStatus(host: string, options?: ReconcilePermissionHookOptions): Promise<PermissionHookStatus>;
7
+ export declare function getPermissionHookAuditSummary(homeDir?: string): Promise<PermissionHookAuditSummary>;
8
+ export declare function summarizePermissionHookHealth(summary: PermissionHookAuditSummary): PermissionHookHealthSummary;
9
+ export declare function repairPermissionHooksOnStartup(homeDir?: string, sourceScriptPath?: string): Promise<PermissionHookStartupRepairSummary>;
10
+ //# sourceMappingURL=permissionHookStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionHookStatus.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHookStatus.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAGhC,KAAK,kCAAkC,EACvC,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EAapC,MAAM,2BAA2B,CAAC;AAInC,wBAAgB,uBAAuB,CAAC,OAAO,SAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAMhG;AAED,wBAAsB,4BAA4B,CAAC,OAAO,SAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAMpH;AA2FD,wBAAgB,yCAAyC,IAAI,kCAAkC,GAAG,IAAI,CAErG;AAED,wBAAgB,gDAAgD,IAAI,IAAI,CAEvE;AAED,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,wBAAsB,6BAA6B,CAAC,OAAO,SAAY,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAgC5G;AA4CD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,0BAA0B,GAClC,2BAA2B,CAmD7B;AAED,wBAAsB,8BAA8B,CAClD,OAAO,SAAY,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,kCAAkC,CAAC,CA0D7C"}