@dollhousemcp/mcp-server 1.4.1 → 1.4.2
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/README.md +54 -9
- package/dist/config/updateConfig.d.ts +84 -0
- package/dist/config/updateConfig.d.ts.map +1 -0
- package/dist/config/updateConfig.js +148 -0
- package/dist/generated/version.d.ts +9 -0
- package/dist/generated/version.d.ts.map +1 -0
- package/dist/generated/version.js +9 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -6
- package/dist/portfolio/DefaultElementProvider.d.ts +78 -0
- package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -0
- package/dist/portfolio/DefaultElementProvider.js +398 -0
- package/dist/portfolio/PortfolioManager.d.ts +7 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
- package/dist/portfolio/PortfolioManager.js +44 -3
- package/dist/security/commandValidator.d.ts.map +1 -1
- package/dist/security/commandValidator.js +5 -2
- package/dist/security/securityMonitor.d.ts +2 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +1 -1
- package/dist/server/tools/UpdateTools.d.ts.map +1 -1
- package/dist/server/tools/UpdateTools.js +22 -1
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -1
- package/dist/update/BackupManager.d.ts +17 -0
- package/dist/update/BackupManager.d.ts.map +1 -1
- package/dist/update/BackupManager.js +112 -3
- package/dist/update/UpdateManager.d.ts +19 -0
- package/dist/update/UpdateManager.d.ts.map +1 -1
- package/dist/update/UpdateManager.js +485 -15
- package/dist/update/VersionManager.d.ts +1 -1
- package/dist/update/VersionManager.d.ts.map +1 -1
- package/dist/update/VersionManager.js +62 -15
- package/dist/utils/fileOperations.d.ts +83 -0
- package/dist/utils/fileOperations.d.ts.map +1 -0
- package/dist/utils/fileOperations.js +291 -0
- package/dist/utils/installation.d.ts +30 -0
- package/dist/utils/installation.d.ts.map +1 -0
- package/dist/utils/installation.js +160 -0
- package/package.json +3 -1
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manage server updates and rollbacks
|
|
3
3
|
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as fs from 'fs/promises';
|
|
4
6
|
import { safeExec } from '../utils/git.js';
|
|
5
7
|
import { VersionManager } from './VersionManager.js';
|
|
6
8
|
import { UpdateChecker } from './UpdateChecker.js';
|
|
7
9
|
import { DependencyChecker } from './DependencyChecker.js';
|
|
8
10
|
import { BackupManager } from './BackupManager.js';
|
|
11
|
+
import { InstallationDetector } from '../utils/installation.js';
|
|
12
|
+
import { logger } from '../utils/logger.js';
|
|
13
|
+
import { compareVersions } from '../utils/version.js';
|
|
14
|
+
import { FileOperations } from '../utils/fileOperations.js';
|
|
15
|
+
import { UpdateConfigManager } from '../config/updateConfig.js';
|
|
9
16
|
export class UpdateManager {
|
|
10
17
|
versionManager;
|
|
11
18
|
updateChecker;
|
|
@@ -39,6 +46,14 @@ export class UpdateManager {
|
|
|
39
46
|
async updateServer(createBackup = true, personaIndicator = '') {
|
|
40
47
|
const progress = [];
|
|
41
48
|
try {
|
|
49
|
+
// Detect installation type
|
|
50
|
+
const installationType = InstallationDetector.getInstallationType();
|
|
51
|
+
logger.info(`[UpdateManager] Detected installation type: ${installationType}`);
|
|
52
|
+
// Handle npm installations differently
|
|
53
|
+
if (installationType === 'npm') {
|
|
54
|
+
return this.updateNpmInstallation(createBackup, personaIndicator);
|
|
55
|
+
}
|
|
56
|
+
// For git installations, proceed with existing logic
|
|
42
57
|
// Step 1: Check dependencies
|
|
43
58
|
progress.push({ step: 'dependencies', message: 'Checking system dependencies...', isComplete: false });
|
|
44
59
|
const dependencies = await this.dependencyChecker.checkDependencies();
|
|
@@ -138,6 +153,12 @@ export class UpdateManager {
|
|
|
138
153
|
*/
|
|
139
154
|
async rollbackUpdate(force = false, personaIndicator = '') {
|
|
140
155
|
try {
|
|
156
|
+
// Check installation type
|
|
157
|
+
const installationType = InstallationDetector.getInstallationType();
|
|
158
|
+
if (installationType === 'npm') {
|
|
159
|
+
return this.rollbackNpmInstallation(force, personaIndicator);
|
|
160
|
+
}
|
|
161
|
+
// For git installations, use existing logic
|
|
141
162
|
// Get latest backup
|
|
142
163
|
const latestBackup = await this.backupManager.getLatestBackup();
|
|
143
164
|
if (!latestBackup) {
|
|
@@ -199,6 +220,449 @@ export class UpdateManager {
|
|
|
199
220
|
};
|
|
200
221
|
}
|
|
201
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Update npm installation
|
|
225
|
+
*/
|
|
226
|
+
async updateNpmInstallation(createBackup, personaIndicator = '') {
|
|
227
|
+
try {
|
|
228
|
+
logger.info('[UpdateManager] Starting npm update process');
|
|
229
|
+
// Check npm is available
|
|
230
|
+
const dependencies = await this.dependencyChecker.checkDependencies();
|
|
231
|
+
if (!dependencies.npm.installed || dependencies.npm.error) {
|
|
232
|
+
return {
|
|
233
|
+
text: personaIndicator + '❌ **Update Failed**\n\n' +
|
|
234
|
+
'npm is required for updates but is not available.\n' +
|
|
235
|
+
dependencies.npm.error || 'npm is not installed.'
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// Get current version
|
|
239
|
+
const currentVersion = await this.versionManager.getCurrentVersion();
|
|
240
|
+
logger.info(`[UpdateManager] Current version: ${currentVersion}`);
|
|
241
|
+
// Check latest version from npm registry
|
|
242
|
+
logger.info('[UpdateManager] Checking npm registry for latest version');
|
|
243
|
+
// Security: Validate package name to prevent any potential injection
|
|
244
|
+
const packageName = '@dollhousemcp/mcp-server';
|
|
245
|
+
if (!/^@[a-z0-9-]+\/[a-z0-9-]+$/.test(packageName)) {
|
|
246
|
+
throw new Error('Invalid package name format');
|
|
247
|
+
}
|
|
248
|
+
const { stdout: npmViewOutput } = await safeExec('npm', ['view', packageName, 'version'], {
|
|
249
|
+
cwd: this.rootDir,
|
|
250
|
+
timeout: 30000
|
|
251
|
+
});
|
|
252
|
+
const latestVersion = npmViewOutput.trim();
|
|
253
|
+
logger.info(`[UpdateManager] Latest npm version: ${latestVersion}`);
|
|
254
|
+
// Compare versions
|
|
255
|
+
const comparison = compareVersions(currentVersion, latestVersion);
|
|
256
|
+
if (comparison >= 0) {
|
|
257
|
+
return {
|
|
258
|
+
text: personaIndicator + '✅ **Already up to date!**\n\n' +
|
|
259
|
+
`Current version: ${currentVersion}\n` +
|
|
260
|
+
`Latest version: ${latestVersion}\n\n` +
|
|
261
|
+
'No update needed.'
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
// Get configuration
|
|
265
|
+
const config = UpdateConfigManager.getInstance();
|
|
266
|
+
// Progress tracking
|
|
267
|
+
let progressMessage = personaIndicator + '🔄 **NPM Update in Progress**\n\n';
|
|
268
|
+
progressMessage += '**Steps:**\n';
|
|
269
|
+
progressMessage += '✅ Version check complete\n';
|
|
270
|
+
progressMessage += '⏳ Creating backup...\n';
|
|
271
|
+
// For npm installations, backup is mandatory for safety
|
|
272
|
+
logger.info('[UpdateManager] Creating backup before npm update');
|
|
273
|
+
try {
|
|
274
|
+
// For npm installations, we backup the global installation directory
|
|
275
|
+
const npmGlobalPath = InstallationDetector.getNpmGlobalPath();
|
|
276
|
+
if (!npmGlobalPath) {
|
|
277
|
+
throw new Error('Could not determine npm global installation path');
|
|
278
|
+
}
|
|
279
|
+
// Create npm-specific backup with progress
|
|
280
|
+
const backupPath = await this.backupManager.createNpmBackup(npmGlobalPath, currentVersion);
|
|
281
|
+
logger.info(`[UpdateManager] Backup created at: ${backupPath}`);
|
|
282
|
+
progressMessage = progressMessage.replace('⏳ Creating backup...', '✅ Backup created');
|
|
283
|
+
progressMessage += '⏳ Downloading and installing update...\n';
|
|
284
|
+
}
|
|
285
|
+
catch (backupError) {
|
|
286
|
+
logger.error('[UpdateManager] Backup failed:', backupError);
|
|
287
|
+
return {
|
|
288
|
+
text: personaIndicator + '❌ **Update Failed**\n\n' +
|
|
289
|
+
'Failed to create backup before update.\n' +
|
|
290
|
+
'Error: ' + (backupError instanceof Error ? backupError.message : String(backupError)) + '\n\n' +
|
|
291
|
+
'**Note:** Backup is mandatory for npm installations to ensure safe rollback.\n' +
|
|
292
|
+
'Please check disk space and permissions.'
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
// Perform npm update with progress
|
|
296
|
+
logger.info('[UpdateManager] Running npm update -g @dollhousemcp/mcp-server');
|
|
297
|
+
progressMessage += '\n**Progress:**\n';
|
|
298
|
+
progressMessage += '```\n';
|
|
299
|
+
progressMessage += 'Running: npm update -g @dollhousemcp/mcp-server\n';
|
|
300
|
+
progressMessage += 'This may take a few minutes...\n';
|
|
301
|
+
progressMessage += '```\n';
|
|
302
|
+
const updateResult = await safeExec('npm', ['update', '-g', '@dollhousemcp/mcp-server'], {
|
|
303
|
+
cwd: this.rootDir,
|
|
304
|
+
timeout: config.getNpmUpdateTimeout()
|
|
305
|
+
});
|
|
306
|
+
logger.info('[UpdateManager] npm update completed', updateResult);
|
|
307
|
+
// Verify update succeeded
|
|
308
|
+
const { stdout: verifyOutput } = await safeExec('npm', ['list', '-g', '@dollhousemcp/mcp-server', '--depth=0'], {
|
|
309
|
+
cwd: this.rootDir,
|
|
310
|
+
timeout: 30000
|
|
311
|
+
});
|
|
312
|
+
const versionMatch = verifyOutput.match(/@dollhousemcp\/mcp-server@(\d+\.\d+\.\d+)/);
|
|
313
|
+
const installedVersion = versionMatch ? versionMatch[1] : 'unknown';
|
|
314
|
+
if (installedVersion !== latestVersion) {
|
|
315
|
+
logger.warn(`[UpdateManager] Version mismatch after update. Expected: ${latestVersion}, Got: ${installedVersion}`);
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
text: personaIndicator + '✅ **Update Complete!**\n\n' +
|
|
319
|
+
`Updated from v${currentVersion} to v${latestVersion}\n\n` +
|
|
320
|
+
'**What was updated:**\n' +
|
|
321
|
+
'• DollhouseMCP server package\n' +
|
|
322
|
+
'• All dependencies\n\n' +
|
|
323
|
+
'**Next Steps:**\n' +
|
|
324
|
+
'1. The server will restart automatically\n' +
|
|
325
|
+
'2. Check `get_server_status` to verify the new version\n' +
|
|
326
|
+
'3. Test your personas to ensure everything works\n\n' +
|
|
327
|
+
'💡 **Tip:** If you encounter issues, use `rollback_update true` to restore the previous version.'
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
logger.error('[UpdateManager] npm update failed:', error);
|
|
332
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
333
|
+
return {
|
|
334
|
+
text: personaIndicator + '❌ **Update Failed**\n\n' +
|
|
335
|
+
'Error: ' + errorMessage + '\n\n' +
|
|
336
|
+
'**Troubleshooting:**\n' +
|
|
337
|
+
'1. Ensure you have permission to update global npm packages\n' +
|
|
338
|
+
'2. Try running with sudo if on macOS/Linux\n' +
|
|
339
|
+
'3. Check your internet connection\n' +
|
|
340
|
+
'4. Verify npm registry is accessible\n\n' +
|
|
341
|
+
'**Manual Update:**\n' +
|
|
342
|
+
'```\n' +
|
|
343
|
+
'npm update -g @dollhousemcp/mcp-server\n' +
|
|
344
|
+
'```'
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Rollback npm installation
|
|
350
|
+
*/
|
|
351
|
+
async rollbackNpmInstallation(force, personaIndicator = '') {
|
|
352
|
+
try {
|
|
353
|
+
logger.info('[UpdateManager] Starting npm rollback process');
|
|
354
|
+
// Get npm backup manifest from configuration
|
|
355
|
+
const config = UpdateConfigManager.getInstance();
|
|
356
|
+
const npmBackupsDir = config.getNpmBackupDir();
|
|
357
|
+
const manifestPath = path.join(npmBackupsDir, 'manifest.json');
|
|
358
|
+
let manifest;
|
|
359
|
+
try {
|
|
360
|
+
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
361
|
+
manifest = JSON.parse(content);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
return {
|
|
365
|
+
text: personaIndicator + '❌ **No NPM Backups Found**\n\n' +
|
|
366
|
+
'There are no npm backups available to restore.\n\n' +
|
|
367
|
+
'Backups are created automatically when you run `update_server true` with npm installations.'
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
if (!manifest.backups || manifest.backups.length === 0) {
|
|
371
|
+
return {
|
|
372
|
+
text: personaIndicator + '❌ **No NPM Backups Found**\n\n' +
|
|
373
|
+
'The backup manifest is empty.\n\n' +
|
|
374
|
+
'Backups are created automatically when you run `update_server true`.'
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
// Get latest backup
|
|
378
|
+
const latestBackup = manifest.backups[0];
|
|
379
|
+
// Check if rollback is needed
|
|
380
|
+
if (!force) {
|
|
381
|
+
try {
|
|
382
|
+
// Test if the server is working
|
|
383
|
+
await this.versionManager.getCurrentVersion();
|
|
384
|
+
return {
|
|
385
|
+
text: personaIndicator + '⚠️ **Rollback Confirmation Required**\n\n' +
|
|
386
|
+
'The server appears to be working normally.\n\n' +
|
|
387
|
+
`**Latest Backup:** ${latestBackup.timestamp}\n` +
|
|
388
|
+
`**Backup Version:** ${latestBackup.version || 'Unknown'}\n\n` +
|
|
389
|
+
'To force rollback anyway, use: `rollback_update true`\n\n' +
|
|
390
|
+
'⚠️ **Warning:** This will restore the npm package to the backup state.'
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
// Server is broken, proceed with rollback
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// Get npm global path
|
|
398
|
+
const npmGlobalPath = InstallationDetector.getNpmGlobalPath();
|
|
399
|
+
if (!npmGlobalPath) {
|
|
400
|
+
return {
|
|
401
|
+
text: personaIndicator + '❌ **Rollback Failed**\n\n' +
|
|
402
|
+
'Could not determine npm global installation path.\n\n' +
|
|
403
|
+
'Please reinstall manually:\n' +
|
|
404
|
+
'```\n' +
|
|
405
|
+
'npm install -g @dollhousemcp/mcp-server@' + (latestBackup.version || 'latest') + '\n' +
|
|
406
|
+
'```'
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
logger.info(`[UpdateManager] Restoring npm backup from: ${latestBackup.path}`);
|
|
410
|
+
// First validate that the backup is restorable
|
|
411
|
+
const backupPackagePath = path.join(latestBackup.path, 'package');
|
|
412
|
+
try {
|
|
413
|
+
await fs.access(backupPackagePath);
|
|
414
|
+
const packageJsonPath = path.join(backupPackagePath, 'package.json');
|
|
415
|
+
await fs.access(packageJsonPath);
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
return {
|
|
419
|
+
text: personaIndicator + '❌ **Backup Validation Failed**\n\n' +
|
|
420
|
+
'The backup appears to be corrupted or incomplete.\n\n' +
|
|
421
|
+
'**Details:**\n' +
|
|
422
|
+
`Backup path: ${latestBackup.path}\n` +
|
|
423
|
+
`Error: ${error instanceof Error ? error.message : String(error)}\n\n` +
|
|
424
|
+
'**Manual Recovery:**\n' +
|
|
425
|
+
'Try another backup or reinstall manually:\n' +
|
|
426
|
+
'```bash\n' +
|
|
427
|
+
'npm install -g @dollhousemcp/mcp-server@' + (latestBackup.version || '1.4.0') + '\n' +
|
|
428
|
+
'```'
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
// Use transaction for atomic operations
|
|
432
|
+
const tempPath = `${npmGlobalPath}.tmp-${Date.now()}`;
|
|
433
|
+
const backupPath = `${npmGlobalPath}.backup-${Date.now()}`;
|
|
434
|
+
const transaction = FileOperations.createTransaction();
|
|
435
|
+
try {
|
|
436
|
+
// Step 1: Copy backup to temporary location
|
|
437
|
+
await transaction.addCopy(backupPackagePath, tempPath);
|
|
438
|
+
// Step 2: Move current installation to backup (atomic)
|
|
439
|
+
await transaction.addMove(npmGlobalPath, backupPath);
|
|
440
|
+
// Step 3: Move temp to final location (atomic)
|
|
441
|
+
await transaction.addMove(tempPath, npmGlobalPath);
|
|
442
|
+
// All operations successful, commit the transaction
|
|
443
|
+
transaction.commit();
|
|
444
|
+
// Step 4: Clean up old backup (not part of transaction)
|
|
445
|
+
await fs.rm(backupPath, { recursive: true, force: true }).catch(() => {
|
|
446
|
+
logger.warn(`[UpdateManager] Failed to cleanup backup at: ${backupPath}`);
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
catch (rollbackError) {
|
|
450
|
+
logger.error('[UpdateManager] Rollback operation failed, attempting recovery:', rollbackError);
|
|
451
|
+
// Rollback all operations
|
|
452
|
+
if (transaction.hasOperations()) {
|
|
453
|
+
await transaction.rollback();
|
|
454
|
+
}
|
|
455
|
+
// Additional recovery attempt
|
|
456
|
+
try {
|
|
457
|
+
// Check if npm path exists and is accessible
|
|
458
|
+
await fs.access(npmGlobalPath);
|
|
459
|
+
logger.info('[UpdateManager] NPM installation appears intact after rollback');
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// Try to restore from backup if main path is missing
|
|
463
|
+
try {
|
|
464
|
+
await fs.rename(backupPath, npmGlobalPath);
|
|
465
|
+
logger.info('[UpdateManager] Restored from backup path');
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
logger.error('[UpdateManager] Complete rollback failure - manual intervention required');
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
throw rollbackError;
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
text: personaIndicator + '✅ **NPM Rollback Complete!**\n\n' +
|
|
475
|
+
`Restored from backup: ${latestBackup.timestamp}\n` +
|
|
476
|
+
`Backup version: ${latestBackup.version || 'Unknown'}\n\n` +
|
|
477
|
+
'**What was restored:**\n' +
|
|
478
|
+
'• NPM package files\n' +
|
|
479
|
+
'• All dependencies\n\n' +
|
|
480
|
+
'**Next Steps:**\n' +
|
|
481
|
+
'1. The server will restart automatically\n' +
|
|
482
|
+
'2. Check `get_server_status` to verify the version\n' +
|
|
483
|
+
'3. Test your personas to ensure everything works'
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
logger.error('[UpdateManager] npm rollback failed:', error);
|
|
488
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
489
|
+
return {
|
|
490
|
+
text: personaIndicator + '❌ **NPM Rollback Failed**\n\n' +
|
|
491
|
+
'Error: ' + errorMessage + '\n\n' +
|
|
492
|
+
'**Manual Recovery:**\n' +
|
|
493
|
+
'1. Check the backups directory: ~/.dollhouse/backups/npm/\n' +
|
|
494
|
+
'2. Reinstall a specific version:\n' +
|
|
495
|
+
' ```\n' +
|
|
496
|
+
' npm install -g @dollhousemcp/mcp-server@1.4.0\n' +
|
|
497
|
+
' ```\n' +
|
|
498
|
+
'3. Contact support if issues persist'
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Copy directory recursively with progress reporting
|
|
504
|
+
* @deprecated Use FileOperations.copyDirectory instead
|
|
505
|
+
*/
|
|
506
|
+
async copyDirectory(src, dest) {
|
|
507
|
+
await FileOperations.copyDirectory(src, dest, {
|
|
508
|
+
excludePatterns: ['.git', 'node_modules'],
|
|
509
|
+
onProgress: (copied, total, file) => {
|
|
510
|
+
logger.debug(`[UpdateManager] Copying files: ${copied}/${total} - ${path.basename(file)}`);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Convert npm installation to git installation
|
|
516
|
+
*/
|
|
517
|
+
async convertToGitInstallation(targetDir, confirm = false, personaIndicator = '') {
|
|
518
|
+
try {
|
|
519
|
+
const installationType = InstallationDetector.getInstallationType();
|
|
520
|
+
if (installationType === 'git') {
|
|
521
|
+
return {
|
|
522
|
+
text: personaIndicator + '⚠️ **Already a Git Installation**\n\n' +
|
|
523
|
+
'This server is already running from a git installation.\n' +
|
|
524
|
+
'No conversion needed.'
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
if (installationType === 'unknown') {
|
|
528
|
+
return {
|
|
529
|
+
text: personaIndicator + '❌ **Installation Type Unknown**\n\n' +
|
|
530
|
+
'Cannot determine the current installation type.\n' +
|
|
531
|
+
'Please check your installation manually.'
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
// Default target directory
|
|
535
|
+
const defaultTargetDir = path.join(process.env.HOME || '', '.dollhouse', 'mcp-server-git');
|
|
536
|
+
const gitTargetDir = targetDir || defaultTargetDir;
|
|
537
|
+
if (!confirm) {
|
|
538
|
+
return {
|
|
539
|
+
text: personaIndicator + '🔄 **Convert to Git Installation**\n\n' +
|
|
540
|
+
'**This will:**\n' +
|
|
541
|
+
`1. Clone DollhouseMCP to: ${gitTargetDir}\n` +
|
|
542
|
+
'2. Copy your portfolio and settings\n' +
|
|
543
|
+
'3. Build the TypeScript code\n' +
|
|
544
|
+
'4. Provide Claude Desktop configuration\n\n' +
|
|
545
|
+
'**Benefits of Git Installation:**\n' +
|
|
546
|
+
'• Full control over updates\n' +
|
|
547
|
+
'• Access to development branches\n' +
|
|
548
|
+
'• Ability to contribute changes\n' +
|
|
549
|
+
'• Rollback to any commit\n\n' +
|
|
550
|
+
'**To proceed:**\n' +
|
|
551
|
+
'`convert_to_git_installation true`\n\n' +
|
|
552
|
+
'**To use custom directory:**\n' +
|
|
553
|
+
'`convert_to_git_installation "/path/to/dir" true`'
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
logger.info(`[UpdateManager] Starting conversion to git installation at: ${gitTargetDir}`);
|
|
557
|
+
// Check if target directory already exists
|
|
558
|
+
try {
|
|
559
|
+
await fs.access(gitTargetDir);
|
|
560
|
+
return {
|
|
561
|
+
text: personaIndicator + '❌ **Target Directory Exists**\n\n' +
|
|
562
|
+
`The directory ${gitTargetDir} already exists.\n\n` +
|
|
563
|
+
'**Options:**\n' +
|
|
564
|
+
'1. Remove the existing directory first\n' +
|
|
565
|
+
'2. Choose a different target directory\n' +
|
|
566
|
+
'3. Use the existing git installation'
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
catch {
|
|
570
|
+
// Directory doesn't exist, good to proceed
|
|
571
|
+
}
|
|
572
|
+
// Progress message builder
|
|
573
|
+
let progressSteps = personaIndicator + '🔄 **Git Installation Progress**\n\n';
|
|
574
|
+
progressSteps += '**Steps:**\n';
|
|
575
|
+
progressSteps += '⏳ Cloning repository...\n';
|
|
576
|
+
progressSteps += '⏳ Installing dependencies...\n';
|
|
577
|
+
progressSteps += '⏳ Building TypeScript...\n';
|
|
578
|
+
progressSteps += '⏳ Setting up configuration...\n\n';
|
|
579
|
+
progressSteps += '**Current Step:** Cloning repository\n';
|
|
580
|
+
progressSteps += '```\n';
|
|
581
|
+
progressSteps += `Target: ${gitTargetDir}\n`;
|
|
582
|
+
progressSteps += 'This may take a few minutes depending on your connection...\n';
|
|
583
|
+
progressSteps += '```\n';
|
|
584
|
+
// Get configuration
|
|
585
|
+
const config = UpdateConfigManager.getInstance();
|
|
586
|
+
// Step 1: Clone the repository
|
|
587
|
+
logger.info('[UpdateManager] Cloning repository...');
|
|
588
|
+
// SECURITY FIX: Validate gitTargetDir to prevent command injection
|
|
589
|
+
// Previously: gitTargetDir passed directly to git clone command
|
|
590
|
+
// Now: Reject paths starting with '--' to prevent git option injection
|
|
591
|
+
if (gitTargetDir.startsWith('--')) {
|
|
592
|
+
throw new Error('Invalid target directory: cannot start with git options');
|
|
593
|
+
}
|
|
594
|
+
await safeExec('git', ['clone', 'https://github.com/DollhouseMCP/mcp-server.git', gitTargetDir], {
|
|
595
|
+
timeout: config.getGitCloneTimeout()
|
|
596
|
+
});
|
|
597
|
+
progressSteps = progressSteps.replace('⏳ Cloning repository...', '✅ Repository cloned');
|
|
598
|
+
progressSteps = progressSteps.replace('**Current Step:** Cloning repository', '**Current Step:** Installing dependencies');
|
|
599
|
+
// Step 2: Install dependencies
|
|
600
|
+
logger.info('[UpdateManager] Installing dependencies...');
|
|
601
|
+
await safeExec('npm', ['install'], {
|
|
602
|
+
cwd: gitTargetDir,
|
|
603
|
+
timeout: config.getNpmInstallTimeout()
|
|
604
|
+
});
|
|
605
|
+
progressSteps = progressSteps.replace('⏳ Installing dependencies...', '✅ Dependencies installed');
|
|
606
|
+
progressSteps = progressSteps.replace('**Current Step:** Installing dependencies', '**Current Step:** Building TypeScript');
|
|
607
|
+
// Step 3: Build TypeScript
|
|
608
|
+
logger.info('[UpdateManager] Building TypeScript...');
|
|
609
|
+
await safeExec('npm', ['run', 'build'], {
|
|
610
|
+
cwd: gitTargetDir,
|
|
611
|
+
timeout: config.getBuildTimeout()
|
|
612
|
+
});
|
|
613
|
+
progressSteps = progressSteps.replace('⏳ Building TypeScript...', '✅ TypeScript built');
|
|
614
|
+
progressSteps = progressSteps.replace('**Current Step:** Building TypeScript', '**Current Step:** Configuration');
|
|
615
|
+
// Step 4: Copy portfolio
|
|
616
|
+
const portfolioSource = path.join(process.env.HOME || '', '.dollhouse', 'portfolio');
|
|
617
|
+
const portfolioTarget = path.join(process.env.HOME || '', '.dollhouse', 'portfolio');
|
|
618
|
+
logger.info('[UpdateManager] Portfolio will remain at: ' + portfolioTarget);
|
|
619
|
+
// Step 5: Generate Claude Desktop config
|
|
620
|
+
const configPath = path.join(gitTargetDir, 'dist', 'index.js');
|
|
621
|
+
const claudeConfig = {
|
|
622
|
+
mcpServers: {
|
|
623
|
+
dollhousemcp: {
|
|
624
|
+
command: 'node',
|
|
625
|
+
args: [configPath]
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
return {
|
|
630
|
+
text: personaIndicator + '✅ **Git Installation Complete!**\n\n' +
|
|
631
|
+
`**Installation Location:** ${gitTargetDir}\n\n` +
|
|
632
|
+
'**Next Steps:**\n\n' +
|
|
633
|
+
'1. **Update Claude Desktop configuration:**\n' +
|
|
634
|
+
' ```json\n' +
|
|
635
|
+
JSON.stringify(claudeConfig, null, 2) + '\n' +
|
|
636
|
+
' ```\n\n' +
|
|
637
|
+
'2. **Restart Claude Desktop**\n\n' +
|
|
638
|
+
'3. **Verify installation:**\n' +
|
|
639
|
+
' After restart, run `get_server_status` to confirm\n\n' +
|
|
640
|
+
'**Your portfolio remains at:**\n' +
|
|
641
|
+
` ${portfolioTarget}\n\n` +
|
|
642
|
+
'**To update in the future:**\n' +
|
|
643
|
+
' ```bash\n' +
|
|
644
|
+
` cd ${gitTargetDir}\n` +
|
|
645
|
+
' git pull\n' +
|
|
646
|
+
' npm install\n' +
|
|
647
|
+
' npm run build\n' +
|
|
648
|
+
' ```\n\n' +
|
|
649
|
+
'💡 **Tip:** You can now use `update_server` to update via git!'
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
catch (error) {
|
|
653
|
+
logger.error('[UpdateManager] Git conversion failed:', error);
|
|
654
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
655
|
+
return {
|
|
656
|
+
text: personaIndicator + '❌ **Conversion Failed**\n\n' +
|
|
657
|
+
'Error: ' + errorMessage + '\n\n' +
|
|
658
|
+
'**Troubleshooting:**\n' +
|
|
659
|
+
'1. Ensure git is installed\n' +
|
|
660
|
+
'2. Check internet connection\n' +
|
|
661
|
+
'3. Verify you have write permissions\n' +
|
|
662
|
+
'4. Try a different target directory'
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
}
|
|
202
666
|
/**
|
|
203
667
|
* Get current server status
|
|
204
668
|
*/
|
|
@@ -208,25 +672,31 @@ export class UpdateManager {
|
|
|
208
672
|
const dependencies = await this.dependencyChecker.checkDependencies();
|
|
209
673
|
const backups = await this.backupManager.listBackups();
|
|
210
674
|
const rateLimitStatus = this.updateChecker.getRateLimitStatus();
|
|
211
|
-
// Get
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
675
|
+
// Get installation type
|
|
676
|
+
const installationType = InstallationDetector.getInstallationType();
|
|
677
|
+
const installationDesc = InstallationDetector.getInstallationDescription();
|
|
678
|
+
// Get git status (only for git installations)
|
|
679
|
+
let gitStatus = 'N/A';
|
|
680
|
+
let gitBranch = 'N/A';
|
|
681
|
+
let lastCommit = 'N/A';
|
|
682
|
+
if (installationType === 'git') {
|
|
683
|
+
try {
|
|
684
|
+
const { stdout: branchOutput } = await safeExec('git', ['branch', '--show-current'], { cwd: this.rootDir });
|
|
685
|
+
gitBranch = branchOutput.trim() || 'detached';
|
|
686
|
+
const { stdout: statusOutput } = await safeExec('git', ['status', '--porcelain'], { cwd: this.rootDir });
|
|
687
|
+
gitStatus = statusOutput.trim() ? 'Modified' : 'Clean';
|
|
688
|
+
const { stdout: logOutput } = await safeExec('git', ['log', '-1', '--oneline'], { cwd: this.rootDir });
|
|
689
|
+
lastCommit = logOutput.trim();
|
|
690
|
+
}
|
|
691
|
+
catch {
|
|
692
|
+
// Git commands failed, use defaults
|
|
693
|
+
}
|
|
225
694
|
}
|
|
226
695
|
const statusParts = [
|
|
227
696
|
personaIndicator + '📊 **DollhouseMCP Server Status**\n\n',
|
|
228
697
|
'**Version Information:**\n',
|
|
229
698
|
`• Current Version: ${currentVersion}\n`,
|
|
699
|
+
`• Installation Type: ${installationType} (${installationDesc})\n`,
|
|
230
700
|
`• Git Branch: ${gitBranch}\n`,
|
|
231
701
|
`• Git Status: ${gitStatus}\n`,
|
|
232
702
|
`• Last Commit: ${lastCommit}\n\n`,
|
|
@@ -257,4 +727,4 @@ export class UpdateManager {
|
|
|
257
727
|
}
|
|
258
728
|
}
|
|
259
729
|
}
|
|
260
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXBkYXRlTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91cGRhdGUvVXBkYXRlTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUdILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQVFuRCxNQUFNLE9BQU8sYUFBYTtJQUNoQixjQUFjLENBQWlCO0lBQy9CLGFBQWEsQ0FBZ0I7SUFDN0IsaUJBQWlCLENBQW9CO0lBQ3JDLGFBQWEsQ0FBZ0I7SUFDN0IsT0FBTyxDQUFTO0lBRXhCLFlBQVksT0FBZ0I7UUFDMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGVBQWU7UUFDbkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsRUFBRSxD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a0RBQWtELENBQ25ELENBQUM7WUFFRixPQUFPLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUV4QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sWUFBWSxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUU1RSxPQUFPO2dCQUNMLElBQUksRUFBRSxnQkFBZ0IsR0FBRywrQkFBK0I7b0JBQ3RELFNBQVMsR0FBRyxZQUFZLEdBQUcsTUFBTTtvQkFDakMsK0NBQStDO29CQUMvQyxpREFBaUQ7YUFDcEQsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1hbmFnZSBzZXJ2ZXIgdXBkYXRlcyBhbmQgcm9sbGJhY2tzXG4gKi9cblxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHNhZmVFeGVjIH0gZnJvbSAnLi4vdXRpbHMvZ2l0LmpzJztcbmltcG9ydCB7IFZlcnNpb25NYW5hZ2VyIH0gZnJvbSAnLi9WZXJzaW9uTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBVcGRhdGVDaGVja2VyIH0gZnJvbSAnLi9VcGRhdGVDaGVja2VyLmpzJztcbmltcG9ydCB7IERlcGVuZGVuY3lDaGVja2VyIH0gZnJvbSAnLi9EZXBlbmRlbmN5Q2hlY2tlci5qcyc7XG5pbXBvcnQgeyBCYWNrdXBNYW5hZ2VyIH0gZnJvbSAnLi9CYWNrdXBNYW5hZ2VyLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBVcGRhdGVQcm9ncmVzcyB7XG4gIHN0ZXA6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBpc0NvbXBsZXRlOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgVXBkYXRlTWFuYWdlciB7XG4gIHByaXZhdGUgdmVyc2lvbk1hbmFnZXI6IFZlcnNpb25NYW5hZ2VyO1xuICBwcml2YXRlIHVwZGF0ZUNoZWNrZXI6IFVwZGF0ZUNoZWNrZXI7XG4gIHByaXZhdGUgZGVwZW5kZW5jeUNoZWNrZXI6IERlcGVuZGVuY3lDaGVja2VyO1xuICBwcml2YXRlIGJhY2t1cE1hbmFnZXI6IEJhY2t1cE1hbmFnZXI7XG4gIHByaXZhdGUgcm9vdERpcjogc3RyaW5nO1xuICBcbiAgY29uc3RydWN0b3Iocm9vdERpcj86IHN0cmluZykge1xuICAgIHRoaXMucm9vdERpciA9IHJvb3REaXIgfHwgcHJvY2Vzcy5jd2QoKTtcbiAgICB0aGlzLnZlcnNpb25NYW5hZ2VyID0gbmV3IFZlcnNpb25NYW5hZ2VyKCk7XG4gICAgdGhpcy51cGRhdGVDaGVja2VyID0gbmV3IFVwZGF0ZUNoZWNrZXIodGhpcy52ZXJzaW9uTWFuYWdlcik7XG4gICAgdGhpcy5kZXBlbmRlbmN5Q2hlY2tlciA9IG5ldyBEZXBlbmRlbmN5Q2hlY2tlcih0aGlzLnZlcnNpb25NYW5hZ2VyKTtcbiAgICB0aGlzLmJhY2t1cE1hbmFnZXIgPSBuZXcgQmFja3VwTWFuYWdlcih0aGlzLnJvb3REaXIpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgZm9yIGF2YWlsYWJsZSB1cGRhdGVzXG4gICAqL1xuICBhc3luYyBjaGVja0ZvclVwZGF0ZXMoKTogUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudXBkYXRlQ2hlY2tlci5jaGVja0ZvclVwZGF0ZXMoKTtcbiAgICAgIGNvbnN0IHRleHQgPSB0aGlzLnVwZGF0ZUNoZWNrZXIuZm9ybWF0VXBkYXRlQ2hlY2tSZXN1bHQocmVzdWx0KTtcbiAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgdGV4dCA9IHRoaXMudXBkYXRlQ2hlY2tlci5mb3JtYXRVcGRhdGVDaGVja1Jlc3VsdChudWxsLCBlcnJvciBhcyBFcnJvcik7XG4gICAgICByZXR1cm4geyB0ZXh0IH07XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogUGVyZm9ybSBzZXJ2ZXIgdXBkYXRlXG4gICAqL1xuICBhc3luYyB1cGRhdGVTZXJ2ZXIoY3JlYXRlQmFja3VwOiBib29sZWFuID0gdHJ1ZSwgcGVyc29uYUluZGljYXRvcjogc3RyaW5nID0gJycpOiBQcm9taXNlPHsgdGV4dDogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBwcm9ncmVzczogVXBkYXRlUHJvZ3Jlc3NbXSA9IFtdO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICAvLyBTdGVwIDE6IENoZWNrIGRlcGVuZGVuY2llc1xuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdkZXBlbmRlbmNpZXMnLCBtZXNzYWdlOiAnQ2hlY2tpbmcgc3lzdGVtIGRlcGVuZGVuY2llcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gYXdhaXQgdGhpcy5kZXBlbmRlbmN5Q2hlY2tlci5jaGVja0RlcGVuZGVuY2llcygpO1xuICAgICAgXG4gICAgICBpZiAoIWRlcGVuZGVuY2llcy5naXQuaW5zdGFsbGVkIHx8IGRlcGVuZGVuY2llcy5naXQuZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKlVwZGF0ZSBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICAgJ0dpdCBpcyByZXF1aXJlZCBmb3IgdXBkYXRlcyBidXQgaXMgbm90IGF2YWlsYWJsZS5cXG4nICtcbiAgICAgICAgICAgIGRlcGVuZGVuY2llcy5naXQuZXJyb3IgfHwgJ0dpdCBpcyBub3QgaW5zdGFsbGVkLidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKCFkZXBlbmRlbmNpZXMubnBtLmluc3RhbGxlZCB8fCBkZXBlbmRlbmNpZXMubnBtLmVycm9yKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICducG0gaXMgcmVxdWlyZWQgZm9yIHVwZGF0ZXMgYnV0IGlzIG5vdCBhdmFpbGFibGUuXFxuJyArXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXMubnBtLmVycm9yIHx8ICducG0gaXMgbm90IGluc3RhbGxlZC4nXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIHByb2dyZXNzWzBdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDI6IENyZWF0ZSBiYWNrdXAgaWYgcmVxdWVzdGVkXG4gICAgICBpZiAoY3JlYXRlQmFja3VwKSB7XG4gICAgICAgIHByb2dyZXNzLnB1c2goeyBzdGVwOiAnYmFja3VwJywgbWVzc2FnZTogJ0NyZWF0aW5nIGJhY2t1cC4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgY3VycmVudFZlcnNpb24gPSBhd2FpdCB0aGlzLnZlcnNpb25NYW5hZ2VyLmdldEN1cnJlbnRWZXJzaW9uKCk7XG4gICAgICAgIGNvbnN0IGJhY2t1cCA9IGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5jcmVhdGVCYWNrdXAoY3VycmVudFZlcnNpb24pO1xuICAgICAgICBcbiAgICAgICAgcHJvZ3Jlc3NbMV0uaXNDb21wbGV0ZSA9IHRydWU7XG4gICAgICAgIHByb2dyZXNzWzFdLm1lc3NhZ2UgPSBgQmFja3VwIGNyZWF0ZWQgYXQ6ICR7YmFja3VwLnRpbWVzdGFtcH1gO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBTdGVwIDM6IEdpdCBmZXRjaFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdmZXRjaCcsIG1lc3NhZ2U6ICdGZXRjaGluZyBsYXRlc3QgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnZmV0Y2gnLCAnb3JpZ2luJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCA0OiBDaGVjayBmb3IgdW5jb21taXR0ZWQgY2hhbmdlc1xuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdjaGVjaycsIG1lc3NhZ2U6ICdDaGVja2luZyBmb3IgdW5jb21taXR0ZWQgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgeyBzdGRvdXQ6IHN0YXR1c091dHB1dCB9ID0gYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnc3RhdHVzJywgJy0tcG9yY2VsYWluJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBcbiAgICAgIGlmIChzdGF0dXNPdXRwdXQudHJpbSgpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICdZb3UgaGF2ZSB1bmNvbW1pdHRlZCBjaGFuZ2VzLiBQbGVhc2UgY29tbWl0IG9yIHN0YXNoIHRoZW0gYmVmb3JlIHVwZGF0aW5nLlxcblxcbicgK1xuICAgICAgICAgICAgJ01vZGlmaWVkIGZpbGVzOlxcbicgKyBzdGF0dXNPdXRwdXRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDU6IEdpdCBwdWxsXG4gICAgICBwcm9ncmVzcy5wdXNoKHsgc3RlcDogJ3B1bGwnLCBtZXNzYWdlOiAnUHVsbGluZyBsYXRlc3QgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgeyBzdGRvdXQ6IHB1bGxPdXRwdXQgfSA9IGF3YWl0IHNhZmVFeGVjKCdnaXQnLCBbJ3B1bGwnLCAnb3JpZ2luJywgJ21haW4nXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBhbHJlYWR5IHVwIHRvIGRhdGVcbiAgICAgIGlmIChwdWxsT3V0cHV0LmluY2x1ZGVzKCdBbHJlYWR5IHVwIHRvIGRhdGUnKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pyFICoqQWxyZWFkeSBVcCB0byBEYXRlKipcXG5cXG4nICtcbiAgICAgICAgICAgICdZb3VyIERvbGxob3VzZU1DUCBpbnN0YWxsYXRpb24gaXMgYWxyZWFkeSBhdCB0aGUgbGF0ZXN0IHZlcnNpb24uXFxuXFxuJyArXG4gICAgICAgICAgICAnTm8gY2hhbmdlcyB3ZXJlIHB1bGxlZCBmcm9tIHRoZSByZXBvc2l0b3J5LidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gU3RlcCA2OiBucG0gaW5zdGFsbFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdpbnN0YWxsJywgbWVzc2FnZTogJ0luc3RhbGxpbmcgZGVwZW5kZW5jaWVzLi4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydpbnN0YWxsJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCA3OiBCdWlsZFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdidWlsZCcsIG1lc3NhZ2U6ICdCdWlsZGluZyBUeXBlU2NyaXB0Li4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydydW4nLCAnYnVpbGQnXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDg6IENsZWFudXAgb2xkIGJhY2t1cHNcbiAgICAgIGlmIChjcmVhdGVCYWNrdXApIHtcbiAgICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdjbGVhbnVwJywgbWVzc2FnZTogJ0NsZWFuaW5nIHVwIG9sZCBiYWNrdXBzLi4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICAgIGNvbnN0IGRlbGV0ZWRDb3VudCA9IGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5jbGVhbnVwT2xkQmFja3VwcygpO1xuICAgICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgcHJvZ3Jlc3NbcHJvZ3Jlc3MubGVuZ3RoIC0gMV0ubWVzc2FnZSA9IGBDbGVhbmVkIHVwICR7ZGVsZXRlZENvdW50fSBvbGQgYmFja3VwKHMpYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRm9ybWF0IHN1Y2Nlc3MgbWVzc2FnZVxuICAgICAgY29uc3Qgc3VjY2Vzc1BhcnRzID0gW1xuICAgICAgICBwZXJzb25hSW5kaWNhdG9yICsgJ+KchSAqKlVwZGF0ZSBDb21wbGV0ZSEqKlxcblxcbicsXG4gICAgICAgICcqKlVwZGF0ZSBTdW1tYXJ5OioqXFxuJ1xuICAgICAgXTtcbiAgICAgIFxuICAgICAgcHJvZ3Jlc3MuZm9yRWFjaChwID0+IHtcbiAgICAgICAgc3VjY2Vzc1BhcnRzLnB1c2goYCR7cC5pc0NvbXBsZXRlID8gJ+KchScgOiAn4p2MJ30gJHtwLm1lc3NhZ2V9XFxuYCk7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgc3VjY2Vzc1BhcnRzLnB1c2goXG4gICAgICAgICdcXG4qKk5leHQgU3RlcHM6KipcXG4nLFxuICAgICAgICAnMS4gVGhlIHNlcnZlciB3aWxsIHJlc3RhcnQgYXV0b21hdGljYWxseVxcbicsXG4gICAgICAgICcyLiBBbGwgcGVyc29uYXMgd2lsbCBiZSByZWxvYWRlZFxcbicsXG4gICAgICAgICczLiBDaGVjayBgZ2V0X3NlcnZlcl9zdGF0dXNgIHRvIHZlcmlmeSB0aGUgbmV3IHZlcnNpb25cXG5cXG4nLFxuICAgICAgICAn8J+SoSAqKlRpcDoqKiBJZiB5b3UgZW5jb3VudGVyIGlzc3VlcywgdXNlIGByb2xsYmFja191cGRhdGUgdHJ1ZWAgdG8gcmVzdG9yZSB0aGUgcHJldmlvdXMgdmVyc2lvbi4nXG4gICAgICApO1xuICAgICAgXG4gICAgICByZXR1cm4geyB0ZXh0OiBzdWNjZXNzUGFydHMuam9pbignJykgfTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqVXBkYXRlIEZhaWxlZCoqXFxuXFxuJyArXG4gICAgICAgICAgJ0Vycm9yOiAnICsgZXJyb3JNZXNzYWdlICsgJ1xcblxcbicgK1xuICAgICAgICAgICcqKlByb2dyZXNzOioqXFxuJyArIFxuICAgICAgICAgIHByb2dyZXNzLm1hcChwID0+IGAke3AuaXNDb21wbGV0ZSA/ICfinIUnIDogJ+KdjCd9ICR7cC5tZXNzYWdlfWApLmpvaW4oJ1xcbicpICsgJ1xcblxcbicgK1xuICAgICAgICAgICcqKlJlY292ZXJ5IE9wdGlvbnM6KipcXG4nICtcbiAgICAgICAgICAn4oCiIFRyeSBydW5uaW5nIHRoZSB1cGRhdGUgYWdhaW5cXG4nICtcbiAgICAgICAgICAn4oCiIENoZWNrIHlvdXIgaW50ZXJuZXQgY29ubmVjdGlvblxcbicgK1xuICAgICAgICAgICfigKIgRW5zdXJlIHlvdSBoYXZlIHByb3BlciBwZXJtaXNzaW9uc1xcbicgK1xuICAgICAgICAgICfigKIgSWYgYSBiYWNrdXAgd2FzIGNyZWF0ZWQsIHVzZSBgcm9sbGJhY2tfdXBkYXRlIHRydWVgIHRvIHJlc3RvcmUnXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFJvbGxiYWNrIHRvIHByZXZpb3VzIHZlcnNpb25cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrVXBkYXRlKGZvcmNlOiBib29sZWFuID0gZmFsc2UsIHBlcnNvbmFJbmRpY2F0b3I6IHN0cmluZyA9ICcnKTogUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEdldCBsYXRlc3QgYmFja3VwXG4gICAgICBjb25zdCBsYXRlc3RCYWNrdXAgPSBhd2FpdCB0aGlzLmJhY2t1cE1hbmFnZXIuZ2V0TGF0ZXN0QmFja3VwKCk7XG4gICAgICBcbiAgICAgIGlmICghbGF0ZXN0QmFja3VwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipObyBCYWNrdXBzIEZvdW5kKipcXG5cXG4nICtcbiAgICAgICAgICAgICdUaGVyZSBhcmUgbm8gYmFja3VwcyBhdmFpbGFibGUgdG8gcmVzdG9yZS5cXG5cXG4nICtcbiAgICAgICAgICAgICdCYWNrdXBzIGFyZSBjcmVhdGVkIGF1dG9tYXRpY2FsbHkgd2hlbiB5b3UgcnVuIGB1cGRhdGVfc2VydmVyIHRydWVgLidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgaWYgcm9sbGJhY2sgaXMgbmVlZGVkXG4gICAgICBpZiAoIWZvcmNlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGVzdCBpZiB0aGUgc2VydmVyIGlzIHdvcmtpbmcgYnkgY2hlY2tpbmcgdmVyc2lvblxuICAgICAgICAgIGF3YWl0IHRoaXMudmVyc2lvbk1hbmFnZXIuZ2V0Q3VycmVudFZlcnNpb24oKTtcbiAgICAgICAgICBcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfimqDvuI8gKipSb2xsYmFjayBDb25maXJtYXRpb24gUmVxdWlyZWQqKlxcblxcbicgK1xuICAgICAgICAgICAgICAnVGhlIHNlcnZlciBhcHBlYXJzIHRvIGJlIHdvcmtpbmcgbm9ybWFsbHkuXFxuXFxuJyArXG4gICAgICAgICAgICAgIGAqKkxhdGVzdCBCYWNrdXA6KiogJHtsYXRlc3RCYWNrdXAudGltZXN0YW1wfVxcbmAgK1xuICAgICAgICAgICAgICBgKipCYWNrdXAgVmVyc2lvbjoqKiAke2xhdGVzdEJhY2t1cC52ZXJzaW9uIHx8ICdVbmtub3duJ31cXG5cXG5gICtcbiAgICAgICAgICAgICAgJ1RvIGZvcmNlIHJvbGxiYWNrIGFueXdheSwgdXNlOiBgcm9sbGJhY2tfdXBkYXRlIHRydWVgXFxuXFxuJyArXG4gICAgICAgICAgICAgICfimqDvuI8gKipXYXJuaW5nOioqIFRoaXMgd2lsbCByZXN0b3JlIGFsbCBmaWxlcyB0byB0aGUgYmFja3VwIHN0YXRlLidcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBTZXJ2ZXIgaXMgYnJva2VuLCBwcm9jZWVkIHdpdGggcm9sbGJhY2tcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQZXJmb3JtIHJvbGxiYWNrXG4gICAgICBhd2FpdCB0aGlzLmJhY2t1cE1hbmFnZXIucmVzdG9yZUJhY2t1cChsYXRlc3RCYWNrdXAucGF0aCk7XG4gICAgICBcbiAgICAgIC8vIFJlaW5zdGFsbCBkZXBlbmRlbmNpZXNcbiAgICAgIGF3YWl0IHNhZmVFeGVjKCducG0nLCBbJ2luc3RhbGwnXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIFxuICAgICAgLy8gUmVidWlsZFxuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ25wbScsIFsncnVuJywgJ2J1aWxkJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pyFICoqUm9sbGJhY2sgQ29tcGxldGUhKipcXG5cXG4nICtcbiAgICAgICAgICBgUmVzdG9yZWQgZnJvbSBiYWNrdXA6ICR7bGF0ZXN0QmFja3VwLnRpbWVzdGFtcH1cXG5gICtcbiAgICAgICAgICBgQmFja3VwIHZlcnNpb246ICR7bGF0ZXN0QmFja3VwLnZlcnNpb24gfHwgJ1Vua25vd24nfVxcblxcbmAgK1xuICAgICAgICAgICcqKldoYXQgd2FzIHJlc3RvcmVkOioqXFxuJyArXG4gICAgICAgICAgJ+KAoiBBbGwgc291cmNlIGZpbGVzXFxuJyArXG4gICAgICAgICAgJ+KAoiBDb25maWd1cmF0aW9uIGZpbGVzXFxuJyArXG4gICAgICAgICAgJ+KAoiBEZXBlbmRlbmNpZXMgcmVpbnN0YWxsZWRcXG4nICtcbiAgICAgICAgICAn4oCiIFR5cGVTY3JpcHQgcmVidWlsdFxcblxcbicgK1xuICAgICAgICAgICcqKk5leHQgU3RlcHM6KipcXG4nICtcbiAgICAgICAgICAnMS4gVGhlIHNlcnZlciB3aWxsIHJlc3RhcnQgYXV0b21hdGljYWxseVxcbicgK1xuICAgICAgICAgICcyLiBDaGVjayBgZ2V0X3NlcnZlcl9zdGF0dXNgIHRvIHZlcmlmeSB0aGUgdmVyc2lvblxcbicgK1xuICAgICAgICAgICczLiBUZXN0IHlvdXIgcGVyc29uYXMgdG8gZW5zdXJlIGV2ZXJ5dGhpbmcgd29ya3MnXG4gICAgICB9O1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipSb2xsYmFjayBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICdFcnJvcjogJyArIGVycm9yTWVzc2FnZSArICdcXG5cXG4nICtcbiAgICAgICAgICAnKipNYW51YWwgUmVjb3Zlcnk6KipcXG4nICtcbiAgICAgICAgICAnMS4gQ2hlY2sgdGhlIGJhY2t1cHMgZGlyZWN0b3J5OiAuLi9kb2xsaG91c2VtY3AtYmFja3Vwcy9cXG4nICtcbiAgICAgICAgICAnMi4gTWFudWFsbHkgcmVzdG9yZSBmaWxlcyBpZiBuZWVkZWRcXG4nICtcbiAgICAgICAgICAnMy4gUnVuIGBucG0gaW5zdGFsbGAgYW5kIGBucG0gcnVuIGJ1aWxkYFxcbicgK1xuICAgICAgICAgICc0LiBDb250YWN0IHN1cHBvcnQgaWYgaXNzdWVzIHBlcnNpc3QnXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHNlcnZlciBzdGF0dXNcbiAgICovXG4gIGFzeW5jIGdldFNlcnZlclN0YXR1cyhwZXJzb25hSW5kaWNhdG9yOiBzdHJpbmcgPSAnJyk6IFByb21pc2U8eyB0ZXh0OiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjdXJyZW50VmVyc2lvbiA9IGF3YWl0IHRoaXMudmVyc2lvbk1hbmFnZXIuZ2V0Q3VycmVudFZlcnNpb24oKTtcbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGF3YWl0IHRoaXMuZGVwZW5kZW5jeUNoZWNrZXIuY2hlY2tEZXBlbmRlbmNpZXMoKTtcbiAgICAgIGNvbnN0IGJhY2t1cHMgPSBhd2FpdCB0aGlzLmJhY2t1cE1hbmFnZXIubGlzdEJhY2t1cHMoKTtcbiAgICAgIGNvbnN0IHJhdGVMaW1pdFN0YXR1cyA9IHRoaXMudXBkYXRlQ2hlY2tlci5nZXRSYXRlTGltaXRTdGF0dXMoKTtcbiAgICAgIFxuICAgICAgLy8gR2V0IGdpdCBzdGF0dXNcbiAgICAgIGxldCBnaXRTdGF0dXMgPSAnVW5rbm93bic7XG4gICAgICBsZXQgZ2l0QnJhbmNoID0gJ1Vua25vd24nO1xuICAgICAgbGV0IGxhc3RDb21taXQgPSAnVW5rbm93bic7XG4gICAgICBcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgc3Rkb3V0OiBicmFuY2hPdXRwdXQgfSA9IGF3YWl0IHNhZmVFeGVjKCdnaXQnLCBbJ2JyYW5jaCcsICctLXNob3ctY3VycmVudCddLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pO1xuICAgICAgICBnaXRCcmFuY2ggPSBicmFuY2hPdXRwdXQudHJpbSgpIHx8ICdkZXRhY2hlZCc7XG4gICAgICAgIFxuICAgICAgICBjb25zdCB7IHN0ZG91dDogc3RhdHVzT3V0cHV0IH0gPSBhd2FpdCBzYWZlRXhlYygnZ2l0JywgWydzdGF0dXMnLCAnLS1wb3JjZWxhaW4nXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgICAgZ2l0U3RhdHVzID0gc3RhdHVzT3V0cHV0LnRyaW0oKSA/ICdNb2RpZmllZCcgOiAnQ2xlYW4nO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgeyBzdGRvdXQ6IGxvZ091dHB1dCB9ID0gYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnbG9nJywgJy0xJywgJy0tb25lbGluZSddLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pO1xuICAgICAgICBsYXN0Q29tbWl0ID0gbG9nT3V0cHV0LnRyaW0oKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBHaXQgY29tbWFuZHMgZmFpbGVkLCB1c2UgZGVmYXVsdHNcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3Qgc3RhdHVzUGFydHMgPSBbXG4gICAgICAgIHBlcnNvbmFJbmRpY2F0b3IgKyAn8J+TiiAqKkRvbGxob3VzZU1DUCBTZXJ2ZXIgU3RhdHVzKipcXG5cXG4nLFxuICAgICAgICAnKipWZXJzaW9uIEluZm9ybWF0aW9uOioqXFxuJyxcbiAgICAgICAgYOKAoiBDdXJyZW50IFZlcnNpb246ICR7Y3VycmVudFZlcnNpb259XFxuYCxcbiAgICAgICAgYOKAoiBHaXQgQnJhbmNoOiAke2dpdEJyYW5jaH1cXG5gLFxuICAgICAgICBg4oCiIEdpdCBTdGF0dXM6ICR7Z2l0U3RhdHVzfVxcbmAsXG4gICAgICAgIGDigKIgTGFzdCBDb21taXQ6ICR7bGFzdENvbW1pdH1cXG5cXG5gLFxuICAgICAgICAnKipEZXBlbmRlbmNpZXM6KipcXG4nLFxuICAgICAgICB0aGlzLmRlcGVuZGVuY3lDaGVja2VyLmZvcm1hdERlcGVuZGVuY3lTdGF0dXMoZGVwZW5kZW5jaWVzKSxcbiAgICAgICAgJ1xcblxcbioqQmFja3VwczoqKlxcbicsXG4gICAgICAgIGDigKIgVG90YWwgQmFja3VwczogJHtiYWNrdXBzLmxlbmd0aH1cXG5gXG4gICAgICBdO1xuICAgICAgXG4gICAgICBpZiAoYmFja3Vwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHN0YXR1c1BhcnRzLnB1c2goYOKAoiBMYXRlc3QgQmFja3VwOiAke2JhY2t1cHNbMF0udGltZXN0YW1wfSAodiR7YmFja3Vwc1swXS52ZXJzaW9uIHx8ICd1bmtub3duJ30pXFxuYCk7XG4gICAgICAgIHN0YXR1c1BhcnRzLnB1c2goYOKAoiBPbGRlc3QgQmFja3VwOiAke2JhY2t1cHNbYmFja3Vwcy5sZW5ndGggLSAxXS50aW1lc3RhbXB9XFxuYCk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHN0YXR1c1BhcnRzLnB1c2goXG4gICAgICAgICdcXG4qKlJhdGUgTGltaXQgU3RhdHVzOioqXFxuJyxcbiAgICAgICAgYOKAoiBVcGRhdGUgQ2hlY2tzIFJlbWFpbmluZzogJHtyYXRlTGltaXRTdGF0dXMucmVtYWluaW5nUmVxdWVzdHN9LzEwIHBlciBob3VyXFxuYCxcbiAgICAgICAgYOKAoiBSYXRlIExpbWl0IFJlc2V0czogJHtyYXRlTGltaXRTdGF0dXMucmVzZXRUaW1lLnRvTG9jYWxlVGltZVN0cmluZygpfVxcbmBcbiAgICAgICk7XG4gICAgICBcbiAgICAgIGlmICghcmF0ZUxpbWl0U3RhdHVzLmFsbG93ZWQgJiYgcmF0ZUxpbWl0U3RhdHVzLndhaXRUaW1lU2Vjb25kcykge1xuICAgICAgICBzdGF0dXNQYXJ0cy5wdXNoKGDigKIg4o+zIFdhaXQgJHtyYXRlTGltaXRTdGF0dXMud2FpdFRpbWVTZWNvbmRzfSBzZWNvbmRzIGJlZm9yZSBuZXh0IGNoZWNrXFxuYCk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHN0YXR1c1BhcnRzLnB1c2goXG4gICAgICAgICdcXG4qKkF2YWlsYWJsZSBDb21tYW5kczoqKlxcbicsXG4gICAgICAgICfigKIgYGNoZWNrX2Zvcl91cGRhdGVzYCAtIENoZWNrIGZvciBuZXcgdmVyc2lvbnNcXG4nLFxuICAgICAgICAn4oCiIGB1cGRhdGVfc2VydmVyIHRydWVgIC0gVXBkYXRlIHRvIGxhdGVzdCB2ZXJzaW9uXFxuJyxcbiAgICAgICAgJ+KAoiBgcm9sbGJhY2tfdXBkYXRlIHRydWVgIC0gUmVzdG9yZSBmcm9tIGJhY2t1cFxcbidcbiAgICAgICk7XG4gICAgICBcbiAgICAgIHJldHVybiB7IHRleHQ6IHN0YXR1c1BhcnRzLmpvaW4oJycpIH07XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKlN0YXR1cyBDaGVjayBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICdFcnJvcjogJyArIGVycm9yTWVzc2FnZSArICdcXG5cXG4nICtcbiAgICAgICAgICAnVGhlIHNlcnZlciBtYXkgYmUgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLlxcbicgK1xuICAgICAgICAgICdUcnkgcnVubmluZyBgdXBkYXRlX3NlcnZlciB0cnVlYCB0byBmaXggaXNzdWVzLidcbiAgICAgIH07XG4gICAgfVxuICB9XG59Il19
|
|
730
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXBkYXRlTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91cGRhdGUvVXBkYXRlTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQW1CLE1BQU0sNEJBQTRCLENBQUM7QUFDN0UsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFRaEUsTUFBTSxPQUFPLGFBQWE7SUFDaEIsY0FBYyxDQUFpQjtJQUMvQixhQUFhLENBQWdCO0lBQzdCLGlCQUFpQixDQUFvQjtJQUNyQyxhQUFhLENBQWdCO0lBQzdCLE9BQU8sQ0FBUztJQUV4QixZQUFZLE9BQWdCO1FBQzFCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN4QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLGFBQWEsR0FB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S0FBSyxDQUFDLENBQUM7Z0JBQ3JHLFdBQVcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUM7WUFDbEYsQ0FBQztZQUVELFdBQVcsQ0FBQyxJQUFJLENBQ2QsNEJBQTRCLEVBQzVCLDhCQUE4QixlQUFlLENBQUMsaUJBQWlCLGdCQUFnQixFQUMvRSx3QkFBd0IsZUFBZSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQzNFLENBQUM7WUFFRixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sSUFBSSxlQUFlLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ2hFLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxlQUFlLENBQUMsZUFBZSw4QkFBOEIsQ0FBQyxDQUFDO1lBQzlGLENBQUM7WUFFRCxXQUFXLENBQUMsSUFBSSxDQUNkLDZCQUE2QixFQUM3QixrREFBa0QsRUFDbEQscURBQXFELEVBQ3JELGtEQUFrRCxDQUNuRCxDQUFDO1lBRUYsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLFlBQVksR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFNUUsT0FBTztnQkFDTCxJQUFJLEVBQUUsZ0JBQWdCLEdBQUcsK0JBQStCO29CQUN0RCxTQUFTLEdBQUcsWUFBWSxHQUFHLE1BQU07b0JBQ2pDLCtDQUErQztvQkFDL0MsaURBQWlEO2FBQ3BELENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYW5hZ2Ugc2VydmVyIHVwZGF0ZXMgYW5kIHJvbGxiYWNrc1xuICovXG5cbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBzYWZlRXhlYyB9IGZyb20gJy4uL3V0aWxzL2dpdC5qcyc7XG5pbXBvcnQgeyBWZXJzaW9uTWFuYWdlciB9IGZyb20gJy4vVmVyc2lvbk1hbmFnZXIuanMnO1xuaW1wb3J0IHsgVXBkYXRlQ2hlY2tlciB9IGZyb20gJy4vVXBkYXRlQ2hlY2tlci5qcyc7XG5pbXBvcnQgeyBEZXBlbmRlbmN5Q2hlY2tlciB9IGZyb20gJy4vRGVwZW5kZW5jeUNoZWNrZXIuanMnO1xuaW1wb3J0IHsgQmFja3VwTWFuYWdlciB9IGZyb20gJy4vQmFja3VwTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBJbnN0YWxsYXRpb25EZXRlY3RvciB9IGZyb20gJy4uL3V0aWxzL2luc3RhbGxhdGlvbi5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgY29tcGFyZVZlcnNpb25zIH0gZnJvbSAnLi4vdXRpbHMvdmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBGaWxlT3BlcmF0aW9ucywgRmlsZVRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vdXRpbHMvZmlsZU9wZXJhdGlvbnMuanMnO1xuaW1wb3J0IHsgVXBkYXRlQ29uZmlnTWFuYWdlciB9IGZyb20gJy4uL2NvbmZpZy91cGRhdGVDb25maWcuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZVByb2dyZXNzIHtcbiAgc3RlcDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGlzQ29tcGxldGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBVcGRhdGVNYW5hZ2VyIHtcbiAgcHJpdmF0ZSB2ZXJzaW9uTWFuYWdlcjogVmVyc2lvbk1hbmFnZXI7XG4gIHByaXZhdGUgdXBkYXRlQ2hlY2tlcjogVXBkYXRlQ2hlY2tlcjtcbiAgcHJpdmF0ZSBkZXBlbmRlbmN5Q2hlY2tlcjogRGVwZW5kZW5jeUNoZWNrZXI7XG4gIHByaXZhdGUgYmFja3VwTWFuYWdlcjogQmFja3VwTWFuYWdlcjtcbiAgcHJpdmF0ZSByb290RGlyOiBzdHJpbmc7XG4gIFxuICBjb25zdHJ1Y3Rvcihyb290RGlyPzogc3RyaW5nKSB7XG4gICAgdGhpcy5yb290RGlyID0gcm9vdERpciB8fCBwcm9jZXNzLmN3ZCgpO1xuICAgIHRoaXMudmVyc2lvbk1hbmFnZXIgPSBuZXcgVmVyc2lvbk1hbmFnZXIoKTtcbiAgICB0aGlzLnVwZGF0ZUNoZWNrZXIgPSBuZXcgVXBkYXRlQ2hlY2tlcih0aGlzLnZlcnNpb25NYW5hZ2VyKTtcbiAgICB0aGlzLmRlcGVuZGVuY3lDaGVja2VyID0gbmV3IERlcGVuZGVuY3lDaGVja2VyKHRoaXMudmVyc2lvbk1hbmFnZXIpO1xuICAgIHRoaXMuYmFja3VwTWFuYWdlciA9IG5ldyBCYWNrdXBNYW5hZ2VyKHRoaXMucm9vdERpcik7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDaGVjayBmb3IgYXZhaWxhYmxlIHVwZGF0ZXNcbiAgICovXG4gIGFzeW5jIGNoZWNrRm9yVXBkYXRlcygpOiBQcm9taXNlPHsgdGV4dDogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy51cGRhdGVDaGVja2VyLmNoZWNrRm9yVXBkYXRlcygpO1xuICAgICAgY29uc3QgdGV4dCA9IHRoaXMudXBkYXRlQ2hlY2tlci5mb3JtYXRVcGRhdGVDaGVja1Jlc3VsdChyZXN1bHQpO1xuICAgICAgcmV0dXJuIHsgdGV4dCB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy51cGRhdGVDaGVja2VyLmZvcm1hdFVwZGF0ZUNoZWNrUmVzdWx0KG51bGwsIGVycm9yIGFzIEVycm9yKTtcbiAgICAgIHJldHVybiB7IHRleHQgfTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBQZXJmb3JtIHNlcnZlciB1cGRhdGVcbiAgICovXG4gIGFzeW5jIHVwZGF0ZVNlcnZlcihjcmVhdGVCYWNrdXA6IGJvb2xlYW4gPSB0cnVlLCBwZXJzb25hSW5kaWNhdG9yOiBzdHJpbmcgPSAnJyk6IFByb21pc2U8eyB0ZXh0OiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IHByb2dyZXNzOiBVcGRhdGVQcm9ncmVzc1tdID0gW107XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIC8vIERldGVjdCBpbnN0YWxsYXRpb24gdHlwZVxuICAgICAgY29uc3QgaW5zdGFsbGF0aW9uVHlwZSA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldEluc3RhbGxhdGlvblR5cGUoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBbVXBkYXRlTWFuYWdlcl0gRGV0ZWN0ZWQgaW5zdGFsbGF0aW9uIHR5cGU6ICR7aW5zdGFsbGF0aW9uVHlwZX1gKTtcbiAgICAgIFxuICAgICAgLy8gSGFuZGxlIG5wbSBpbnN0YWxsYXRpb25zIGRpZmZlcmVudGx5XG4gICAgICBpZiAoaW5zdGFsbGF0aW9uVHlwZSA9PT0gJ25wbScpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudXBkYXRlTnBtSW5zdGFsbGF0aW9uKGNyZWF0ZUJhY2t1cCwgcGVyc29uYUluZGljYXRvcik7XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIEZvciBnaXQgaW5zdGFsbGF0aW9ucywgcHJvY2VlZCB3aXRoIGV4aXN0aW5nIGxvZ2ljXG4gICAgICAvLyBTdGVwIDE6IENoZWNrIGRlcGVuZGVuY2llc1xuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdkZXBlbmRlbmNpZXMnLCBtZXNzYWdlOiAnQ2hlY2tpbmcgc3lzdGVtIGRlcGVuZGVuY2llcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gYXdhaXQgdGhpcy5kZXBlbmRlbmN5Q2hlY2tlci5jaGVja0RlcGVuZGVuY2llcygpO1xuICAgICAgXG4gICAgICBpZiAoIWRlcGVuZGVuY2llcy5naXQuaW5zdGFsbGVkIHx8IGRlcGVuZGVuY2llcy5naXQuZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKlVwZGF0ZSBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICAgJ0dpdCBpcyByZXF1aXJlZCBmb3IgdXBkYXRlcyBidXQgaXMgbm90IGF2YWlsYWJsZS5cXG4nICtcbiAgICAgICAgICAgIGRlcGVuZGVuY2llcy5naXQuZXJyb3IgfHwgJ0dpdCBpcyBub3QgaW5zdGFsbGVkLidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKCFkZXBlbmRlbmNpZXMubnBtLmluc3RhbGxlZCB8fCBkZXBlbmRlbmNpZXMubnBtLmVycm9yKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICducG0gaXMgcmVxdWlyZWQgZm9yIHVwZGF0ZXMgYnV0IGlzIG5vdCBhdmFpbGFibGUuXFxuJyArXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXMubnBtLmVycm9yIHx8ICducG0gaXMgbm90IGluc3RhbGxlZC4nXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIHByb2dyZXNzWzBdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDI6IENyZWF0ZSBiYWNrdXAgaWYgcmVxdWVzdGVkXG4gICAgICBpZiAoY3JlYXRlQmFja3VwKSB7XG4gICAgICAgIHByb2dyZXNzLnB1c2goeyBzdGVwOiAnYmFja3VwJywgbWVzc2FnZTogJ0NyZWF0aW5nIGJhY2t1cC4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgY3VycmVudFZlcnNpb24gPSBhd2FpdCB0aGlzLnZlcnNpb25NYW5hZ2VyLmdldEN1cnJlbnRWZXJzaW9uKCk7XG4gICAgICAgIGNvbnN0IGJhY2t1cCA9IGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5jcmVhdGVCYWNrdXAoY3VycmVudFZlcnNpb24pO1xuICAgICAgICBcbiAgICAgICAgcHJvZ3Jlc3NbMV0uaXNDb21wbGV0ZSA9IHRydWU7XG4gICAgICAgIHByb2dyZXNzWzFdLm1lc3NhZ2UgPSBgQmFja3VwIGNyZWF0ZWQgYXQ6ICR7YmFja3VwLnRpbWVzdGFtcH1gO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBTdGVwIDM6IEdpdCBmZXRjaFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdmZXRjaCcsIG1lc3NhZ2U6ICdGZXRjaGluZyBsYXRlc3QgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnZmV0Y2gnLCAnb3JpZ2luJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCA0OiBDaGVjayBmb3IgdW5jb21taXR0ZWQgY2hhbmdlc1xuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdjaGVjaycsIG1lc3NhZ2U6ICdDaGVja2luZyBmb3IgdW5jb21taXR0ZWQgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgeyBzdGRvdXQ6IHN0YXR1c091dHB1dCB9ID0gYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnc3RhdHVzJywgJy0tcG9yY2VsYWluJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBcbiAgICAgIGlmIChzdGF0dXNPdXRwdXQudHJpbSgpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICdZb3UgaGF2ZSB1bmNvbW1pdHRlZCBjaGFuZ2VzLiBQbGVhc2UgY29tbWl0IG9yIHN0YXNoIHRoZW0gYmVmb3JlIHVwZGF0aW5nLlxcblxcbicgK1xuICAgICAgICAgICAgJ01vZGlmaWVkIGZpbGVzOlxcbicgKyBzdGF0dXNPdXRwdXRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDU6IEdpdCBwdWxsXG4gICAgICBwcm9ncmVzcy5wdXNoKHsgc3RlcDogJ3B1bGwnLCBtZXNzYWdlOiAnUHVsbGluZyBsYXRlc3QgY2hhbmdlcy4uLicsIGlzQ29tcGxldGU6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgeyBzdGRvdXQ6IHB1bGxPdXRwdXQgfSA9IGF3YWl0IHNhZmVFeGVjKCdnaXQnLCBbJ3B1bGwnLCAnb3JpZ2luJywgJ21haW4nXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBhbHJlYWR5IHVwIHRvIGRhdGVcbiAgICAgIGlmIChwdWxsT3V0cHV0LmluY2x1ZGVzKCdBbHJlYWR5IHVwIHRvIGRhdGUnKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pyFICoqQWxyZWFkeSBVcCB0byBEYXRlKipcXG5cXG4nICtcbiAgICAgICAgICAgICdZb3VyIERvbGxob3VzZU1DUCBpbnN0YWxsYXRpb24gaXMgYWxyZWFkeSBhdCB0aGUgbGF0ZXN0IHZlcnNpb24uXFxuXFxuJyArXG4gICAgICAgICAgICAnTm8gY2hhbmdlcyB3ZXJlIHB1bGxlZCBmcm9tIHRoZSByZXBvc2l0b3J5LidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gU3RlcCA2OiBucG0gaW5zdGFsbFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdpbnN0YWxsJywgbWVzc2FnZTogJ0luc3RhbGxpbmcgZGVwZW5kZW5jaWVzLi4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydpbnN0YWxsJ10sIHsgY3dkOiB0aGlzLnJvb3REaXIgfSk7XG4gICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCA3OiBCdWlsZFxuICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdidWlsZCcsIG1lc3NhZ2U6ICdCdWlsZGluZyBUeXBlU2NyaXB0Li4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydydW4nLCAnYnVpbGQnXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIHByb2dyZXNzW3Byb2dyZXNzLmxlbmd0aCAtIDFdLmlzQ29tcGxldGUgPSB0cnVlO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDg6IENsZWFudXAgb2xkIGJhY2t1cHNcbiAgICAgIGlmIChjcmVhdGVCYWNrdXApIHtcbiAgICAgICAgcHJvZ3Jlc3MucHVzaCh7IHN0ZXA6ICdjbGVhbnVwJywgbWVzc2FnZTogJ0NsZWFuaW5nIHVwIG9sZCBiYWNrdXBzLi4uJywgaXNDb21wbGV0ZTogZmFsc2UgfSk7XG4gICAgICAgIGNvbnN0IGRlbGV0ZWRDb3VudCA9IGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5jbGVhbnVwT2xkQmFja3VwcygpO1xuICAgICAgICBwcm9ncmVzc1twcm9ncmVzcy5sZW5ndGggLSAxXS5pc0NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgcHJvZ3Jlc3NbcHJvZ3Jlc3MubGVuZ3RoIC0gMV0ubWVzc2FnZSA9IGBDbGVhbmVkIHVwICR7ZGVsZXRlZENvdW50fSBvbGQgYmFja3VwKHMpYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRm9ybWF0IHN1Y2Nlc3MgbWVzc2FnZVxuICAgICAgY29uc3Qgc3VjY2Vzc1BhcnRzID0gW1xuICAgICAgICBwZXJzb25hSW5kaWNhdG9yICsgJ+KchSAqKlVwZGF0ZSBDb21wbGV0ZSEqKlxcblxcbicsXG4gICAgICAgICcqKlVwZGF0ZSBTdW1tYXJ5OioqXFxuJ1xuICAgICAgXTtcbiAgICAgIFxuICAgICAgcHJvZ3Jlc3MuZm9yRWFjaChwID0+IHtcbiAgICAgICAgc3VjY2Vzc1BhcnRzLnB1c2goYCR7cC5pc0NvbXBsZXRlID8gJ+KchScgOiAn4p2MJ30gJHtwLm1lc3NhZ2V9XFxuYCk7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgc3VjY2Vzc1BhcnRzLnB1c2goXG4gICAgICAgICdcXG4qKk5leHQgU3RlcHM6KipcXG4nLFxuICAgICAgICAnMS4gVGhlIHNlcnZlciB3aWxsIHJlc3RhcnQgYXV0b21hdGljYWxseVxcbicsXG4gICAgICAgICcyLiBBbGwgcGVyc29uYXMgd2lsbCBiZSByZWxvYWRlZFxcbicsXG4gICAgICAgICczLiBDaGVjayBgZ2V0X3NlcnZlcl9zdGF0dXNgIHRvIHZlcmlmeSB0aGUgbmV3IHZlcnNpb25cXG5cXG4nLFxuICAgICAgICAn8J+SoSAqKlRpcDoqKiBJZiB5b3UgZW5jb3VudGVyIGlzc3VlcywgdXNlIGByb2xsYmFja191cGRhdGUgdHJ1ZWAgdG8gcmVzdG9yZSB0aGUgcHJldmlvdXMgdmVyc2lvbi4nXG4gICAgICApO1xuICAgICAgXG4gICAgICByZXR1cm4geyB0ZXh0OiBzdWNjZXNzUGFydHMuam9pbignJykgfTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqVXBkYXRlIEZhaWxlZCoqXFxuXFxuJyArXG4gICAgICAgICAgJ0Vycm9yOiAnICsgZXJyb3JNZXNzYWdlICsgJ1xcblxcbicgK1xuICAgICAgICAgICcqKlByb2dyZXNzOioqXFxuJyArIFxuICAgICAgICAgIHByb2dyZXNzLm1hcChwID0+IGAke3AuaXNDb21wbGV0ZSA/ICfinIUnIDogJ+KdjCd9ICR7cC5tZXNzYWdlfWApLmpvaW4oJ1xcbicpICsgJ1xcblxcbicgK1xuICAgICAgICAgICcqKlJlY292ZXJ5IE9wdGlvbnM6KipcXG4nICtcbiAgICAgICAgICAn4oCiIFRyeSBydW5uaW5nIHRoZSB1cGRhdGUgYWdhaW5cXG4nICtcbiAgICAgICAgICAn4oCiIENoZWNrIHlvdXIgaW50ZXJuZXQgY29ubmVjdGlvblxcbicgK1xuICAgICAgICAgICfigKIgRW5zdXJlIHlvdSBoYXZlIHByb3BlciBwZXJtaXNzaW9uc1xcbicgK1xuICAgICAgICAgICfigKIgSWYgYSBiYWNrdXAgd2FzIGNyZWF0ZWQsIHVzZSBgcm9sbGJhY2tfdXBkYXRlIHRydWVgIHRvIHJlc3RvcmUnXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFJvbGxiYWNrIHRvIHByZXZpb3VzIHZlcnNpb25cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrVXBkYXRlKGZvcmNlOiBib29sZWFuID0gZmFsc2UsIHBlcnNvbmFJbmRpY2F0b3I6IHN0cmluZyA9ICcnKTogUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGluc3RhbGxhdGlvbiB0eXBlXG4gICAgICBjb25zdCBpbnN0YWxsYXRpb25UeXBlID0gSW5zdGFsbGF0aW9uRGV0ZWN0b3IuZ2V0SW5zdGFsbGF0aW9uVHlwZSgpO1xuICAgICAgXG4gICAgICBpZiAoaW5zdGFsbGF0aW9uVHlwZSA9PT0gJ25wbScpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucm9sbGJhY2tOcG1JbnN0YWxsYXRpb24oZm9yY2UsIHBlcnNvbmFJbmRpY2F0b3IpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBGb3IgZ2l0IGluc3RhbGxhdGlvbnMsIHVzZSBleGlzdGluZyBsb2dpY1xuICAgICAgLy8gR2V0IGxhdGVzdCBiYWNrdXBcbiAgICAgIGNvbnN0IGxhdGVzdEJhY2t1cCA9IGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5nZXRMYXRlc3RCYWNrdXAoKTtcbiAgICAgIFxuICAgICAgaWYgKCFsYXRlc3RCYWNrdXApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKk5vIEJhY2t1cHMgRm91bmQqKlxcblxcbicgK1xuICAgICAgICAgICAgJ1RoZXJlIGFyZSBubyBiYWNrdXBzIGF2YWlsYWJsZSB0byByZXN0b3JlLlxcblxcbicgK1xuICAgICAgICAgICAgJ0JhY2t1cHMgYXJlIGNyZWF0ZWQgYXV0b21hdGljYWxseSB3aGVuIHlvdSBydW4gYHVwZGF0ZV9zZXJ2ZXIgdHJ1ZWAuJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiByb2xsYmFjayBpcyBuZWVkZWRcbiAgICAgIGlmICghZm9yY2UpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUZXN0IGlmIHRoZSBzZXJ2ZXIgaXMgd29ya2luZyBieSBjaGVja2luZyB2ZXJzaW9uXG4gICAgICAgICAgYXdhaXQgdGhpcy52ZXJzaW9uTWFuYWdlci5nZXRDdXJyZW50VmVyc2lvbigpO1xuICAgICAgICAgIFxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KaoO+4jyAqKlJvbGxiYWNrIENvbmZpcm1hdGlvbiBSZXF1aXJlZCoqXFxuXFxuJyArXG4gICAgICAgICAgICAgICdUaGUgc2VydmVyIGFwcGVhcnMgdG8gYmUgd29ya2luZyBub3JtYWxseS5cXG5cXG4nICtcbiAgICAgICAgICAgICAgYCoqTGF0ZXN0IEJhY2t1cDoqKiAke2xhdGVzdEJhY2t1cC50aW1lc3RhbXB9XFxuYCArXG4gICAgICAgICAgICAgIGAqKkJhY2t1cCBWZXJzaW9uOioqICR7bGF0ZXN0QmFja3VwLnZlcnNpb24gfHwgJ1Vua25vd24nfVxcblxcbmAgK1xuICAgICAgICAgICAgICAnVG8gZm9yY2Ugcm9sbGJhY2sgYW55d2F5LCB1c2U6IGByb2xsYmFja191cGRhdGUgdHJ1ZWBcXG5cXG4nICtcbiAgICAgICAgICAgICAgJ+KaoO+4jyAqKldhcm5pbmc6KiogVGhpcyB3aWxsIHJlc3RvcmUgYWxsIGZpbGVzIHRvIHRoZSBiYWNrdXAgc3RhdGUuJ1xuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIFNlcnZlciBpcyBicm9rZW4sIHByb2NlZWQgd2l0aCByb2xsYmFja1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFBlcmZvcm0gcm9sbGJhY2tcbiAgICAgIGF3YWl0IHRoaXMuYmFja3VwTWFuYWdlci5yZXN0b3JlQmFja3VwKGxhdGVzdEJhY2t1cC5wYXRoKTtcbiAgICAgIFxuICAgICAgLy8gUmVpbnN0YWxsIGRlcGVuZGVuY2llc1xuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ25wbScsIFsnaW5zdGFsbCddLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pO1xuICAgICAgXG4gICAgICAvLyBSZWJ1aWxkXG4gICAgICBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydydW4nLCAnYnVpbGQnXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinIUgKipSb2xsYmFjayBDb21wbGV0ZSEqKlxcblxcbicgK1xuICAgICAgICAgIGBSZXN0b3JlZCBmcm9tIGJhY2t1cDogJHtsYXRlc3RCYWNrdXAudGltZXN0YW1wfVxcbmAgK1xuICAgICAgICAgIGBCYWNrdXAgdmVyc2lvbjogJHtsYXRlc3RCYWNrdXAudmVyc2lvbiB8fCAnVW5rbm93bid9XFxuXFxuYCArXG4gICAgICAgICAgJyoqV2hhdCB3YXMgcmVzdG9yZWQ6KipcXG4nICtcbiAgICAgICAgICAn4oCiIEFsbCBzb3VyY2UgZmlsZXNcXG4nICtcbiAgICAgICAgICAn4oCiIENvbmZpZ3VyYXRpb24gZmlsZXNcXG4nICtcbiAgICAgICAgICAn4oCiIERlcGVuZGVuY2llcyByZWluc3RhbGxlZFxcbicgK1xuICAgICAgICAgICfigKIgVHlwZVNjcmlwdCByZWJ1aWx0XFxuXFxuJyArXG4gICAgICAgICAgJyoqTmV4dCBTdGVwczoqKlxcbicgK1xuICAgICAgICAgICcxLiBUaGUgc2VydmVyIHdpbGwgcmVzdGFydCBhdXRvbWF0aWNhbGx5XFxuJyArXG4gICAgICAgICAgJzIuIENoZWNrIGBnZXRfc2VydmVyX3N0YXR1c2AgdG8gdmVyaWZ5IHRoZSB2ZXJzaW9uXFxuJyArXG4gICAgICAgICAgJzMuIFRlc3QgeW91ciBwZXJzb25hcyB0byBlbnN1cmUgZXZlcnl0aGluZyB3b3JrcydcbiAgICAgIH07XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKlJvbGxiYWNrIEZhaWxlZCoqXFxuXFxuJyArXG4gICAgICAgICAgJ0Vycm9yOiAnICsgZXJyb3JNZXNzYWdlICsgJ1xcblxcbicgK1xuICAgICAgICAgICcqKk1hbnVhbCBSZWNvdmVyeToqKlxcbicgK1xuICAgICAgICAgICcxLiBDaGVjayB0aGUgYmFja3VwcyBkaXJlY3Rvcnk6IC4uL2RvbGxob3VzZW1jcC1iYWNrdXBzL1xcbicgK1xuICAgICAgICAgICcyLiBNYW51YWxseSByZXN0b3JlIGZpbGVzIGlmIG5lZWRlZFxcbicgK1xuICAgICAgICAgICczLiBSdW4gYG5wbSBpbnN0YWxsYCBhbmQgYG5wbSBydW4gYnVpbGRgXFxuJyArXG4gICAgICAgICAgJzQuIENvbnRhY3Qgc3VwcG9ydCBpZiBpc3N1ZXMgcGVyc2lzdCdcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogVXBkYXRlIG5wbSBpbnN0YWxsYXRpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlTnBtSW5zdGFsbGF0aW9uKGNyZWF0ZUJhY2t1cDogYm9vbGVhbiwgcGVyc29uYUluZGljYXRvcjogc3RyaW5nID0gJycpOiBQcm9taXNlPHsgdGV4dDogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgbG9nZ2VyLmluZm8oJ1tVcGRhdGVNYW5hZ2VyXSBTdGFydGluZyBucG0gdXBkYXRlIHByb2Nlc3MnKTtcbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgbnBtIGlzIGF2YWlsYWJsZVxuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gYXdhaXQgdGhpcy5kZXBlbmRlbmN5Q2hlY2tlci5jaGVja0RlcGVuZGVuY2llcygpO1xuICAgICAgaWYgKCFkZXBlbmRlbmNpZXMubnBtLmluc3RhbGxlZCB8fCBkZXBlbmRlbmNpZXMubnBtLmVycm9yKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICducG0gaXMgcmVxdWlyZWQgZm9yIHVwZGF0ZXMgYnV0IGlzIG5vdCBhdmFpbGFibGUuXFxuJyArXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXMubnBtLmVycm9yIHx8ICducG0gaXMgbm90IGluc3RhbGxlZC4nXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIEdldCBjdXJyZW50IHZlcnNpb25cbiAgICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uID0gYXdhaXQgdGhpcy52ZXJzaW9uTWFuYWdlci5nZXRDdXJyZW50VmVyc2lvbigpO1xuICAgICAgbG9nZ2VyLmluZm8oYFtVcGRhdGVNYW5hZ2VyXSBDdXJyZW50IHZlcnNpb246ICR7Y3VycmVudFZlcnNpb259YCk7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGxhdGVzdCB2ZXJzaW9uIGZyb20gbnBtIHJlZ2lzdHJ5XG4gICAgICBsb2dnZXIuaW5mbygnW1VwZGF0ZU1hbmFnZXJdIENoZWNraW5nIG5wbSByZWdpc3RyeSBmb3IgbGF0ZXN0IHZlcnNpb24nKTtcbiAgICAgIFxuICAgICAgLy8gU2VjdXJpdHk6IFZhbGlkYXRlIHBhY2thZ2UgbmFtZSB0byBwcmV2ZW50IGFueSBwb3RlbnRpYWwgaW5qZWN0aW9uXG4gICAgICBjb25zdCBwYWNrYWdlTmFtZSA9ICdAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInO1xuICAgICAgaWYgKCEvXkBbYS16MC05LV0rXFwvW2EtejAtOS1dKyQvLnRlc3QocGFja2FnZU5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYWNrYWdlIG5hbWUgZm9ybWF0Jyk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IHsgc3Rkb3V0OiBucG1WaWV3T3V0cHV0IH0gPSBhd2FpdCBzYWZlRXhlYygnbnBtJywgWyd2aWV3JywgcGFja2FnZU5hbWUsICd2ZXJzaW9uJ10sIHtcbiAgICAgICAgY3dkOiB0aGlzLnJvb3REaXIsXG4gICAgICAgIHRpbWVvdXQ6IDMwMDAwXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgY29uc3QgbGF0ZXN0VmVyc2lvbiA9IG5wbVZpZXdPdXRwdXQudHJpbSgpO1xuICAgICAgbG9nZ2VyLmluZm8oYFtVcGRhdGVNYW5hZ2VyXSBMYXRlc3QgbnBtIHZlcnNpb246ICR7bGF0ZXN0VmVyc2lvbn1gKTtcbiAgICAgIFxuICAgICAgLy8gQ29tcGFyZSB2ZXJzaW9uc1xuICAgICAgY29uc3QgY29tcGFyaXNvbiA9IGNvbXBhcmVWZXJzaW9ucyhjdXJyZW50VmVyc2lvbiwgbGF0ZXN0VmVyc2lvbik7XG4gICAgICBcbiAgICAgIGlmIChjb21wYXJpc29uID49IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KchSAqKkFscmVhZHkgdXAgdG8gZGF0ZSEqKlxcblxcbicgK1xuICAgICAgICAgICAgYEN1cnJlbnQgdmVyc2lvbjogJHtjdXJyZW50VmVyc2lvbn1cXG5gICtcbiAgICAgICAgICAgIGBMYXRlc3QgdmVyc2lvbjogJHtsYXRlc3RWZXJzaW9ufVxcblxcbmAgK1xuICAgICAgICAgICAgJ05vIHVwZGF0ZSBuZWVkZWQuJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBHZXQgY29uZmlndXJhdGlvblxuICAgICAgY29uc3QgY29uZmlnID0gVXBkYXRlQ29uZmlnTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICAgICAgXG4gICAgICAvLyBQcm9ncmVzcyB0cmFja2luZ1xuICAgICAgbGV0IHByb2dyZXNzTWVzc2FnZSA9IHBlcnNvbmFJbmRpY2F0b3IgKyAn8J+UhCAqKk5QTSBVcGRhdGUgaW4gUHJvZ3Jlc3MqKlxcblxcbic7XG4gICAgICBwcm9ncmVzc01lc3NhZ2UgKz0gJyoqU3RlcHM6KipcXG4nO1xuICAgICAgcHJvZ3Jlc3NNZXNzYWdlICs9ICfinIUgVmVyc2lvbiBjaGVjayBjb21wbGV0ZVxcbic7XG4gICAgICBwcm9ncmVzc01lc3NhZ2UgKz0gJ+KPsyBDcmVhdGluZyBiYWNrdXAuLi5cXG4nO1xuICAgICAgXG4gICAgICAvLyBGb3IgbnBtIGluc3RhbGxhdGlvbnMsIGJhY2t1cCBpcyBtYW5kYXRvcnkgZm9yIHNhZmV0eVxuICAgICAgbG9nZ2VyLmluZm8oJ1tVcGRhdGVNYW5hZ2VyXSBDcmVhdGluZyBiYWNrdXAgYmVmb3JlIG5wbSB1cGRhdGUnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEZvciBucG0gaW5zdGFsbGF0aW9ucywgd2UgYmFja3VwIHRoZSBnbG9iYWwgaW5zdGFsbGF0aW9uIGRpcmVjdG9yeVxuICAgICAgICBjb25zdCBucG1HbG9iYWxQYXRoID0gSW5zdGFsbGF0aW9uRGV0ZWN0b3IuZ2V0TnBtR2xvYmFsUGF0aCgpO1xuICAgICAgICBpZiAoIW5wbUdsb2JhbFBhdGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBkZXRlcm1pbmUgbnBtIGdsb2JhbCBpbnN0YWxsYXRpb24gcGF0aCcpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBDcmVhdGUgbnBtLXNwZWNpZmljIGJhY2t1cCB3aXRoIHByb2dyZXNzXG4gICAgICAgIGNvbnN0IGJhY2t1cFBhdGggPSBhd2FpdCB0aGlzLmJhY2t1cE1hbmFnZXIuY3JlYXRlTnBtQmFja3VwKG5wbUdsb2JhbFBhdGgsIGN1cnJlbnRWZXJzaW9uKTtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFtVcGRhdGVNYW5hZ2VyXSBCYWNrdXAgY3JlYXRlZCBhdDogJHtiYWNrdXBQYXRofWApO1xuICAgICAgICBcbiAgICAgICAgcHJvZ3Jlc3NNZXNzYWdlID0gcHJvZ3Jlc3NNZXNzYWdlLnJlcGxhY2UoJ+KPsyBDcmVhdGluZyBiYWNrdXAuLi4nLCAn4pyFIEJhY2t1cCBjcmVhdGVkJyk7XG4gICAgICAgIHByb2dyZXNzTWVzc2FnZSArPSAn4o+zIERvd25sb2FkaW5nIGFuZCBpbnN0YWxsaW5nIHVwZGF0ZS4uLlxcbic7XG4gICAgICAgIFxuICAgICAgfSBjYXRjaCAoYmFja3VwRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdbVXBkYXRlTWFuYWdlcl0gQmFja3VwIGZhaWxlZDonLCBiYWNrdXBFcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipVcGRhdGUgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICdGYWlsZWQgdG8gY3JlYXRlIGJhY2t1cCBiZWZvcmUgdXBkYXRlLlxcbicgK1xuICAgICAgICAgICAgJ0Vycm9yOiAnICsgKGJhY2t1cEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBiYWNrdXBFcnJvci5tZXNzYWdlIDogU3RyaW5nKGJhY2t1cEVycm9yKSkgKyAnXFxuXFxuJyArXG4gICAgICAgICAgICAnKipOb3RlOioqIEJhY2t1cCBpcyBtYW5kYXRvcnkgZm9yIG5wbSBpbnN0YWxsYXRpb25zIHRvIGVuc3VyZSBzYWZlIHJvbGxiYWNrLlxcbicgK1xuICAgICAgICAgICAgJ1BsZWFzZSBjaGVjayBkaXNrIHNwYWNlIGFuZCBwZXJtaXNzaW9ucy4nXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFBlcmZvcm0gbnBtIHVwZGF0ZSB3aXRoIHByb2dyZXNzXG4gICAgICBsb2dnZXIuaW5mbygnW1VwZGF0ZU1hbmFnZXJdIFJ1bm5pbmcgbnBtIHVwZGF0ZSAtZyBAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInKTtcbiAgICAgIHByb2dyZXNzTWVzc2FnZSArPSAnXFxuKipQcm9ncmVzczoqKlxcbic7XG4gICAgICBwcm9ncmVzc01lc3NhZ2UgKz0gJ2BgYFxcbic7XG4gICAgICBwcm9ncmVzc01lc3NhZ2UgKz0gJ1J1bm5pbmc6IG5wbSB1cGRhdGUgLWcgQGRvbGxob3VzZW1jcC9tY3Atc2VydmVyXFxuJztcbiAgICAgIHByb2dyZXNzTWVzc2FnZSArPSAnVGhpcyBtYXkgdGFrZSBhIGZldyBtaW51dGVzLi4uXFxuJztcbiAgICAgIHByb2dyZXNzTWVzc2FnZSArPSAnYGBgXFxuJztcbiAgICAgIFxuICAgICAgY29uc3QgdXBkYXRlUmVzdWx0ID0gYXdhaXQgc2FmZUV4ZWMoJ25wbScsIFsndXBkYXRlJywgJy1nJywgJ0Bkb2xsaG91c2VtY3AvbWNwLXNlcnZlciddLCB7XG4gICAgICAgIGN3ZDogdGhpcy5yb290RGlyLFxuICAgICAgICB0aW1lb3V0OiBjb25maWcuZ2V0TnBtVXBkYXRlVGltZW91dCgpXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmluZm8oJ1tVcGRhdGVNYW5hZ2VyXSBucG0gdXBkYXRlIGNvbXBsZXRlZCcsIHVwZGF0ZVJlc3VsdCk7XG4gICAgICBcbiAgICAgIC8vIFZlcmlmeSB1cGRhdGUgc3VjY2VlZGVkXG4gICAgICBjb25zdCB7IHN0ZG91dDogdmVyaWZ5T3V0cHV0IH0gPSBhd2FpdCBzYWZlRXhlYygnbnBtJywgWydsaXN0JywgJy1nJywgJ0Bkb2xsaG91c2VtY3AvbWNwLXNlcnZlcicsICctLWRlcHRoPTAnXSwge1xuICAgICAgICBjd2Q6IHRoaXMucm9vdERpcixcbiAgICAgICAgdGltZW91dDogMzAwMDBcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICBjb25zdCB2ZXJzaW9uTWF0Y2ggPSB2ZXJpZnlPdXRwdXQubWF0Y2goL0Bkb2xsaG91c2VtY3BcXC9tY3Atc2VydmVyQChcXGQrXFwuXFxkK1xcLlxcZCspLyk7XG4gICAgICBjb25zdCBpbnN0YWxsZWRWZXJzaW9uID0gdmVyc2lvbk1hdGNoID8gdmVyc2lvbk1hdGNoWzFdIDogJ3Vua25vd24nO1xuICAgICAgXG4gICAgICBpZiAoaW5zdGFsbGVkVmVyc2lvbiAhPT0gbGF0ZXN0VmVyc2lvbikge1xuICAgICAgICBsb2dnZXIud2FybihgW1VwZGF0ZU1hbmFnZXJdIFZlcnNpb24gbWlzbWF0Y2ggYWZ0ZXIgdXBkYXRlLiBFeHBlY3RlZDogJHtsYXRlc3RWZXJzaW9ufSwgR290OiAke2luc3RhbGxlZFZlcnNpb259YCk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pyFICoqVXBkYXRlIENvbXBsZXRlISoqXFxuXFxuJyArXG4gICAgICAgICAgYFVwZGF0ZWQgZnJvbSB2JHtjdXJyZW50VmVyc2lvbn0gdG8gdiR7bGF0ZXN0VmVyc2lvbn1cXG5cXG5gICtcbiAgICAgICAgICAnKipXaGF0IHdhcyB1cGRhdGVkOioqXFxuJyArXG4gICAgICAgICAgJ+KAoiBEb2xsaG91c2VNQ1Agc2VydmVyIHBhY2thZ2VcXG4nICtcbiAgICAgICAgICAn4oCiIEFsbCBkZXBlbmRlbmNpZXNcXG5cXG4nICtcbiAgICAgICAgICAnKipOZXh0IFN0ZXBzOioqXFxuJyArXG4gICAgICAgICAgJzEuIFRoZSBzZXJ2ZXIgd2lsbCByZXN0YXJ0IGF1dG9tYXRpY2FsbHlcXG4nICtcbiAgICAgICAgICAnMi4gQ2hlY2sgYGdldF9zZXJ2ZXJfc3RhdHVzYCB0byB2ZXJpZnkgdGhlIG5ldyB2ZXJzaW9uXFxuJyArXG4gICAgICAgICAgJzMuIFRlc3QgeW91ciBwZXJzb25hcyB0byBlbnN1cmUgZXZlcnl0aGluZyB3b3Jrc1xcblxcbicgK1xuICAgICAgICAgICfwn5KhICoqVGlwOioqIElmIHlvdSBlbmNvdW50ZXIgaXNzdWVzLCB1c2UgYHJvbGxiYWNrX3VwZGF0ZSB0cnVlYCB0byByZXN0b3JlIHRoZSBwcmV2aW91cyB2ZXJzaW9uLidcbiAgICAgIH07XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdbVXBkYXRlTWFuYWdlcl0gbnBtIHVwZGF0ZSBmYWlsZWQ6JywgZXJyb3IpO1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKlVwZGF0ZSBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICdFcnJvcjogJyArIGVycm9yTWVzc2FnZSArICdcXG5cXG4nICtcbiAgICAgICAgICAnKipUcm91Ymxlc2hvb3Rpbmc6KipcXG4nICtcbiAgICAgICAgICAnMS4gRW5zdXJlIHlvdSBoYXZlIHBlcm1pc3Npb24gdG8gdXBkYXRlIGdsb2JhbCBucG0gcGFja2FnZXNcXG4nICtcbiAgICAgICAgICAnMi4gVHJ5IHJ1bm5pbmcgd2l0aCBzdWRvIGlmIG9uIG1hY09TL0xpbnV4XFxuJyArXG4gICAgICAgICAgJzMuIENoZWNrIHlvdXIgaW50ZXJuZXQgY29ubmVjdGlvblxcbicgK1xuICAgICAgICAgICc0LiBWZXJpZnkgbnBtIHJlZ2lzdHJ5IGlzIGFjY2Vzc2libGVcXG5cXG4nICtcbiAgICAgICAgICAnKipNYW51YWwgVXBkYXRlOioqXFxuJyArXG4gICAgICAgICAgJ2BgYFxcbicgK1xuICAgICAgICAgICducG0gdXBkYXRlIC1nIEBkb2xsaG91c2VtY3AvbWNwLXNlcnZlclxcbicgK1xuICAgICAgICAgICdgYGAnXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFJvbGxiYWNrIG5wbSBpbnN0YWxsYXRpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcm9sbGJhY2tOcG1JbnN0YWxsYXRpb24oZm9yY2U6IGJvb2xlYW4sIHBlcnNvbmFJbmRpY2F0b3I6IHN0cmluZyA9ICcnKTogUHJvbWlzZTx7IHRleHQ6IHN0cmluZyB9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZ2dlci5pbmZvKCdbVXBkYXRlTWFuYWdlcl0gU3RhcnRpbmcgbnBtIHJvbGxiYWNrIHByb2Nlc3MnKTtcbiAgICAgIFxuICAgICAgLy8gR2V0IG5wbSBiYWNrdXAgbWFuaWZlc3QgZnJvbSBjb25maWd1cmF0aW9uXG4gICAgICBjb25zdCBjb25maWcgPSBVcGRhdGVDb25maWdNYW5hZ2VyLmdldEluc3RhbmNlKCk7XG4gICAgICBjb25zdCBucG1CYWNrdXBzRGlyID0gY29uZmlnLmdldE5wbUJhY2t1cERpcigpO1xuICAgICAgY29uc3QgbWFuaWZlc3RQYXRoID0gcGF0aC5qb2luKG5wbUJhY2t1cHNEaXIsICdtYW5pZmVzdC5qc29uJyk7XG4gICAgICBcbiAgICAgIGxldCBtYW5pZmVzdDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShtYW5pZmVzdFBhdGgsICd1dGYtOCcpO1xuICAgICAgICBtYW5pZmVzdCA9IEpTT04ucGFyc2UoY29udGVudCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqTm8gTlBNIEJhY2t1cHMgRm91bmQqKlxcblxcbicgK1xuICAgICAgICAgICAgJ1RoZXJlIGFyZSBubyBucG0gYmFja3VwcyBhdmFpbGFibGUgdG8gcmVzdG9yZS5cXG5cXG4nICtcbiAgICAgICAgICAgICdCYWNrdXBzIGFyZSBjcmVhdGVkIGF1dG9tYXRpY2FsbHkgd2hlbiB5b3UgcnVuIGB1cGRhdGVfc2VydmVyIHRydWVgIHdpdGggbnBtIGluc3RhbGxhdGlvbnMuJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAoIW1hbmlmZXN0LmJhY2t1cHMgfHwgbWFuaWZlc3QuYmFja3Vwcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KdjCAqKk5vIE5QTSBCYWNrdXBzIEZvdW5kKipcXG5cXG4nICtcbiAgICAgICAgICAgICdUaGUgYmFja3VwIG1hbmlmZXN0IGlzIGVtcHR5LlxcblxcbicgK1xuICAgICAgICAgICAgJ0JhY2t1cHMgYXJlIGNyZWF0ZWQgYXV0b21hdGljYWxseSB3aGVuIHlvdSBydW4gYHVwZGF0ZV9zZXJ2ZXIgdHJ1ZWAuJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBHZXQgbGF0ZXN0IGJhY2t1cFxuICAgICAgY29uc3QgbGF0ZXN0QmFja3VwID0gbWFuaWZlc3QuYmFja3Vwc1swXTtcbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgaWYgcm9sbGJhY2sgaXMgbmVlZGVkXG4gICAgICBpZiAoIWZvcmNlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGVzdCBpZiB0aGUgc2VydmVyIGlzIHdvcmtpbmdcbiAgICAgICAgICBhd2FpdCB0aGlzLnZlcnNpb25NYW5hZ2VyLmdldEN1cnJlbnRWZXJzaW9uKCk7XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pqg77iPICoqUm9sbGJhY2sgQ29uZmlybWF0aW9uIFJlcXVpcmVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICAgJ1RoZSBzZXJ2ZXIgYXBwZWFycyB0byBiZSB3b3JraW5nIG5vcm1hbGx5LlxcblxcbicgK1xuICAgICAgICAgICAgICBgKipMYXRlc3QgQmFja3VwOioqICR7bGF0ZXN0QmFja3VwLnRpbWVzdGFtcH1cXG5gICtcbiAgICAgICAgICAgICAgYCoqQmFja3VwIFZlcnNpb246KiogJHtsYXRlc3RCYWNrdXAudmVyc2lvbiB8fCAnVW5rbm93bid9XFxuXFxuYCArXG4gICAgICAgICAgICAgICdUbyBmb3JjZSByb2xsYmFjayBhbnl3YXksIHVzZTogYHJvbGxiYWNrX3VwZGF0ZSB0cnVlYFxcblxcbicgK1xuICAgICAgICAgICAgICAn4pqg77iPICoqV2FybmluZzoqKiBUaGlzIHdpbGwgcmVzdG9yZSB0aGUgbnBtIHBhY2thZ2UgdG8gdGhlIGJhY2t1cCBzdGF0ZS4nXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gU2VydmVyIGlzIGJyb2tlbiwgcHJvY2VlZCB3aXRoIHJvbGxiYWNrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gR2V0IG5wbSBnbG9iYWwgcGF0aFxuICAgICAgY29uc3QgbnBtR2xvYmFsUGF0aCA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldE5wbUdsb2JhbFBhdGgoKTtcbiAgICAgIGlmICghbnBtR2xvYmFsUGF0aCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqUm9sbGJhY2sgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAgICdDb3VsZCBub3QgZGV0ZXJtaW5lIG5wbSBnbG9iYWwgaW5zdGFsbGF0aW9uIHBhdGguXFxuXFxuJyArXG4gICAgICAgICAgICAnUGxlYXNlIHJlaW5zdGFsbCBtYW51YWxseTpcXG4nICtcbiAgICAgICAgICAgICdgYGBcXG4nICtcbiAgICAgICAgICAgICducG0gaW5zdGFsbCAtZyBAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXJAJyArIChsYXRlc3RCYWNrdXAudmVyc2lvbiB8fCAnbGF0ZXN0JykgKyAnXFxuJyArXG4gICAgICAgICAgICAnYGBgJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICBsb2dnZXIuaW5mbyhgW1VwZGF0ZU1hbmFnZXJdIFJlc3RvcmluZyBucG0gYmFja3VwIGZyb206ICR7bGF0ZXN0QmFja3VwLnBhdGh9YCk7XG4gICAgICBcbiAgICAgIC8vIEZpcnN0IHZhbGlkYXRlIHRoYXQgdGhlIGJhY2t1cCBpcyByZXN0b3JhYmxlXG4gICAgICBjb25zdCBiYWNrdXBQYWNrYWdlUGF0aCA9IHBhdGguam9pbihsYXRlc3RCYWNrdXAucGF0aCwgJ3BhY2thZ2UnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmFjY2VzcyhiYWNrdXBQYWNrYWdlUGF0aCk7XG4gICAgICAgIGNvbnN0IHBhY2thZ2VKc29uUGF0aCA9IHBhdGguam9pbihiYWNrdXBQYWNrYWdlUGF0aCwgJ3BhY2thZ2UuanNvbicpO1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3MocGFja2FnZUpzb25QYXRoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipCYWNrdXAgVmFsaWRhdGlvbiBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICAgJ1RoZSBiYWNrdXAgYXBwZWFycyB0byBiZSBjb3JydXB0ZWQgb3IgaW5jb21wbGV0ZS5cXG5cXG4nICtcbiAgICAgICAgICAgICcqKkRldGFpbHM6KipcXG4nICtcbiAgICAgICAgICAgIGBCYWNrdXAgcGF0aDogJHtsYXRlc3RCYWNrdXAucGF0aH1cXG5gICtcbiAgICAgICAgICAgIGBFcnJvcjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9XFxuXFxuYCArXG4gICAgICAgICAgICAnKipNYW51YWwgUmVjb3Zlcnk6KipcXG4nICtcbiAgICAgICAgICAgICdUcnkgYW5vdGhlciBiYWNrdXAgb3IgcmVpbnN0YWxsIG1hbnVhbGx5OlxcbicgK1xuICAgICAgICAgICAgJ2BgYGJhc2hcXG4nICtcbiAgICAgICAgICAgICducG0gaW5zdGFsbCAtZyBAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXJAJyArIChsYXRlc3RCYWNrdXAudmVyc2lvbiB8fCAnMS40LjAnKSArICdcXG4nICtcbiAgICAgICAgICAgICdgYGAnXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFVzZSB0cmFuc2FjdGlvbiBmb3IgYXRvbWljIG9wZXJhdGlvbnNcbiAgICAgIGNvbnN0IHRlbXBQYXRoID0gYCR7bnBtR2xvYmFsUGF0aH0udG1wLSR7RGF0ZS5ub3coKX1gO1xuICAgICAgY29uc3QgYmFja3VwUGF0aCA9IGAke25wbUdsb2JhbFBhdGh9LmJhY2t1cC0ke0RhdGUubm93KCl9YDtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gRmlsZU9wZXJhdGlvbnMuY3JlYXRlVHJhbnNhY3Rpb24oKTtcbiAgICAgIFxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gU3RlcCAxOiBDb3B5IGJhY2t1cCB0byB0ZW1wb3JhcnkgbG9jYXRpb25cbiAgICAgICAgYXdhaXQgdHJhbnNhY3Rpb24uYWRkQ29weShiYWNrdXBQYWNrYWdlUGF0aCwgdGVtcFBhdGgpO1xuICAgICAgICBcbiAgICAgICAgLy8gU3RlcCAyOiBNb3ZlIGN1cnJlbnQgaW5zdGFsbGF0aW9uIHRvIGJhY2t1cCAoYXRvbWljKVxuICAgICAgICBhd2FpdCB0cmFuc2FjdGlvbi5hZGRNb3ZlKG5wbUdsb2JhbFBhdGgsIGJhY2t1cFBhdGgpO1xuICAgICAgICBcbiAgICAgICAgLy8gU3RlcCAzOiBNb3ZlIHRlbXAgdG8gZmluYWwgbG9jYXRpb24gKGF0b21pYylcbiAgICAgICAgYXdhaXQgdHJhbnNhY3Rpb24uYWRkTW92ZSh0ZW1wUGF0aCwgbnBtR2xvYmFsUGF0aCk7XG4gICAgICAgIFxuICAgICAgICAvLyBBbGwgb3BlcmF0aW9ucyBzdWNjZXNzZnVsLCBjb21taXQgdGhlIHRyYW5zYWN0aW9uXG4gICAgICAgIHRyYW5zYWN0aW9uLmNvbW1pdCgpO1xuICAgICAgICBcbiAgICAgICAgLy8gU3RlcCA0OiBDbGVhbiB1cCBvbGQgYmFja3VwIChub3QgcGFydCBvZiB0cmFuc2FjdGlvbilcbiAgICAgICAgYXdhaXQgZnMucm0oYmFja3VwUGF0aCwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIud2FybihgW1VwZGF0ZU1hbmFnZXJdIEZhaWxlZCB0byBjbGVhbnVwIGJhY2t1cCBhdDogJHtiYWNrdXBQYXRofWApO1xuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKHJvbGxiYWNrRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdbVXBkYXRlTWFuYWdlcl0gUm9sbGJhY2sgb3BlcmF0aW9uIGZhaWxlZCwgYXR0ZW1wdGluZyByZWNvdmVyeTonLCByb2xsYmFja0Vycm9yKTtcbiAgICAgICAgXG4gICAgICAgIC8vIFJvbGxiYWNrIGFsbCBvcGVyYXRpb25zXG4gICAgICAgIGlmICh0cmFuc2FjdGlvbi5oYXNPcGVyYXRpb25zKCkpIHtcbiAgICAgICAgICBhd2FpdCB0cmFuc2FjdGlvbi5yb2xsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBBZGRpdGlvbmFsIHJlY292ZXJ5IGF0dGVtcHRcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBDaGVjayBpZiBucG0gcGF0aCBleGlzdHMgYW5kIGlzIGFjY2Vzc2libGVcbiAgICAgICAgICBhd2FpdCBmcy5hY2Nlc3MobnBtR2xvYmFsUGF0aCk7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oJ1tVcGRhdGVNYW5hZ2VyXSBOUE0gaW5zdGFsbGF0aW9uIGFwcGVhcnMgaW50YWN0IGFmdGVyIHJvbGxiYWNrJyk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIFRyeSB0byByZXN0b3JlIGZyb20gYmFja3VwIGlmIG1haW4gcGF0aCBpcyBtaXNzaW5nXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGZzLnJlbmFtZShiYWNrdXBQYXRoLCBucG1HbG9iYWxQYXRoKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdbVXBkYXRlTWFuYWdlcl0gUmVzdG9yZWQgZnJvbSBiYWNrdXAgcGF0aCcpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdbVXBkYXRlTWFuYWdlcl0gQ29tcGxldGUgcm9sbGJhY2sgZmFpbHVyZSAtIG1hbnVhbCBpbnRlcnZlbnRpb24gcmVxdWlyZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHRocm93IHJvbGxiYWNrRXJyb3I7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4pyFICoqTlBNIFJvbGxiYWNrIENvbXBsZXRlISoqXFxuXFxuJyArXG4gICAgICAgICAgYFJlc3RvcmVkIGZyb20gYmFja3VwOiAke2xhdGVzdEJhY2t1cC50aW1lc3RhbXB9XFxuYCArXG4gICAgICAgICAgYEJhY2t1cCB2ZXJzaW9uOiAke2xhdGVzdEJhY2t1cC52ZXJzaW9uIHx8ICdVbmtub3duJ31cXG5cXG5gICtcbiAgICAgICAgICAnKipXaGF0IHdhcyByZXN0b3JlZDoqKlxcbicgK1xuICAgICAgICAgICfigKIgTlBNIHBhY2thZ2UgZmlsZXNcXG4nICtcbiAgICAgICAgICAn4oCiIEFsbCBkZXBlbmRlbmNpZXNcXG5cXG4nICtcbiAgICAgICAgICAnKipOZXh0IFN0ZXBzOioqXFxuJyArXG4gICAgICAgICAgJzEuIFRoZSBzZXJ2ZXIgd2lsbCByZXN0YXJ0IGF1dG9tYXRpY2FsbHlcXG4nICtcbiAgICAgICAgICAnMi4gQ2hlY2sgYGdldF9zZXJ2ZXJfc3RhdHVzYCB0byB2ZXJpZnkgdGhlIHZlcnNpb25cXG4nICtcbiAgICAgICAgICAnMy4gVGVzdCB5b3VyIHBlcnNvbmFzIHRvIGVuc3VyZSBldmVyeXRoaW5nIHdvcmtzJ1xuICAgICAgfTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ1tVcGRhdGVNYW5hZ2VyXSBucG0gcm9sbGJhY2sgZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipOUE0gUm9sbGJhY2sgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAnRXJyb3I6ICcgKyBlcnJvck1lc3NhZ2UgKyAnXFxuXFxuJyArXG4gICAgICAgICAgJyoqTWFudWFsIFJlY292ZXJ5OioqXFxuJyArXG4gICAgICAgICAgJzEuIENoZWNrIHRoZSBiYWNrdXBzIGRpcmVjdG9yeTogfi8uZG9sbGhvdXNlL2JhY2t1cHMvbnBtL1xcbicgK1xuICAgICAgICAgICcyLiBSZWluc3RhbGwgYSBzcGVjaWZpYyB2ZXJzaW9uOlxcbicgK1xuICAgICAgICAgICcgICBgYGBcXG4nICtcbiAgICAgICAgICAnICAgbnBtIGluc3RhbGwgLWcgQGRvbGxob3VzZW1jcC9tY3Atc2VydmVyQDEuNC4wXFxuJyArXG4gICAgICAgICAgJyAgIGBgYFxcbicgK1xuICAgICAgICAgICczLiBDb250YWN0IHN1cHBvcnQgaWYgaXNzdWVzIHBlcnNpc3QnXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIENvcHkgZGlyZWN0b3J5IHJlY3Vyc2l2ZWx5IHdpdGggcHJvZ3Jlc3MgcmVwb3J0aW5nXG4gICAqIEBkZXByZWNhdGVkIFVzZSBGaWxlT3BlcmF0aW9ucy5jb3B5RGlyZWN0b3J5IGluc3RlYWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY29weURpcmVjdG9yeShzcmM6IHN0cmluZywgZGVzdDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgRmlsZU9wZXJhdGlvbnMuY29weURpcmVjdG9yeShzcmMsIGRlc3QsIHtcbiAgICAgIGV4Y2x1ZGVQYXR0ZXJuczogWycuZ2l0JywgJ25vZGVfbW9kdWxlcyddLFxuICAgICAgb25Qcm9ncmVzczogKGNvcGllZCwgdG90YWwsIGZpbGUpID0+IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBbVXBkYXRlTWFuYWdlcl0gQ29weWluZyBmaWxlczogJHtjb3BpZWR9LyR7dG90YWx9IC0gJHtwYXRoLmJhc2VuYW1lKGZpbGUpfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogQ29udmVydCBucG0gaW5zdGFsbGF0aW9uIHRvIGdpdCBpbnN0YWxsYXRpb25cbiAgICovXG4gIGFzeW5jIGNvbnZlcnRUb0dpdEluc3RhbGxhdGlvbih0YXJnZXREaXI/OiBzdHJpbmcsIGNvbmZpcm06IGJvb2xlYW4gPSBmYWxzZSwgcGVyc29uYUluZGljYXRvcjogc3RyaW5nID0gJycpOiBQcm9taXNlPHsgdGV4dDogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9uVHlwZSA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldEluc3RhbGxhdGlvblR5cGUoKTtcbiAgICAgIFxuICAgICAgaWYgKGluc3RhbGxhdGlvblR5cGUgPT09ICdnaXQnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfimqDvuI8gKipBbHJlYWR5IGEgR2l0IEluc3RhbGxhdGlvbioqXFxuXFxuJyArXG4gICAgICAgICAgICAnVGhpcyBzZXJ2ZXIgaXMgYWxyZWFkeSBydW5uaW5nIGZyb20gYSBnaXQgaW5zdGFsbGF0aW9uLlxcbicgK1xuICAgICAgICAgICAgJ05vIGNvbnZlcnNpb24gbmVlZGVkLidcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGluc3RhbGxhdGlvblR5cGUgPT09ICd1bmtub3duJykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqSW5zdGFsbGF0aW9uIFR5cGUgVW5rbm93bioqXFxuXFxuJyArXG4gICAgICAgICAgICAnQ2Fubm90IGRldGVybWluZSB0aGUgY3VycmVudCBpbnN0YWxsYXRpb24gdHlwZS5cXG4nICtcbiAgICAgICAgICAgICdQbGVhc2UgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24gbWFudWFsbHkuJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBEZWZhdWx0IHRhcmdldCBkaXJlY3RvcnlcbiAgICAgIGNvbnN0IGRlZmF1bHRUYXJnZXREaXIgPSBwYXRoLmpvaW4ocHJvY2Vzcy5lbnYuSE9NRSB8fCAnJywgJy5kb2xsaG91c2UnLCAnbWNwLXNlcnZlci1naXQnKTtcbiAgICAgIGNvbnN0IGdpdFRhcmdldERpciA9IHRhcmdldERpciB8fCBkZWZhdWx0VGFyZ2V0RGlyO1xuICAgICAgXG4gICAgICBpZiAoIWNvbmZpcm0pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ/CflIQgKipDb252ZXJ0IHRvIEdpdCBJbnN0YWxsYXRpb24qKlxcblxcbicgK1xuICAgICAgICAgICAgJyoqVGhpcyB3aWxsOioqXFxuJyArXG4gICAgICAgICAgICBgMS4gQ2xvbmUgRG9sbGhvdXNlTUNQIHRvOiAke2dpdFRhcmdldERpcn1cXG5gICtcbiAgICAgICAgICAgICcyLiBDb3B5IHlvdXIgcG9ydGZvbGlvIGFuZCBzZXR0aW5nc1xcbicgK1xuICAgICAgICAgICAgJzMuIEJ1aWxkIHRoZSBUeXBlU2NyaXB0IGNvZGVcXG4nICtcbiAgICAgICAgICAgICc0LiBQcm92aWRlIENsYXVkZSBEZXNrdG9wIGNvbmZpZ3VyYXRpb25cXG5cXG4nICtcbiAgICAgICAgICAgICcqKkJlbmVmaXRzIG9mIEdpdCBJbnN0YWxsYXRpb246KipcXG4nICtcbiAgICAgICAgICAgICfigKIgRnVsbCBjb250cm9sIG92ZXIgdXBkYXRlc1xcbicgK1xuICAgICAgICAgICAgJ+KAoiBBY2Nlc3MgdG8gZGV2ZWxvcG1lbnQgYnJhbmNoZXNcXG4nICtcbiAgICAgICAgICAgICfigKIgQWJpbGl0eSB0byBjb250cmlidXRlIGNoYW5nZXNcXG4nICtcbiAgICAgICAgICAgICfigKIgUm9sbGJhY2sgdG8gYW55IGNvbW1pdFxcblxcbicgK1xuICAgICAgICAgICAgJyoqVG8gcHJvY2VlZDoqKlxcbicgK1xuICAgICAgICAgICAgJ2Bjb252ZXJ0X3RvX2dpdF9pbnN0YWxsYXRpb24gdHJ1ZWBcXG5cXG4nICtcbiAgICAgICAgICAgICcqKlRvIHVzZSBjdXN0b20gZGlyZWN0b3J5OioqXFxuJyArXG4gICAgICAgICAgICAnYGNvbnZlcnRfdG9fZ2l0X2luc3RhbGxhdGlvbiBcIi9wYXRoL3RvL2RpclwiIHRydWVgJ1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICBsb2dnZXIuaW5mbyhgW1VwZGF0ZU1hbmFnZXJdIFN0YXJ0aW5nIGNvbnZlcnNpb24gdG8gZ2l0IGluc3RhbGxhdGlvbiBhdDogJHtnaXRUYXJnZXREaXJ9YCk7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIHRhcmdldCBkaXJlY3RvcnkgYWxyZWFkeSBleGlzdHNcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmFjY2VzcyhnaXRUYXJnZXREaXIpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqVGFyZ2V0IERpcmVjdG9yeSBFeGlzdHMqKlxcblxcbicgK1xuICAgICAgICAgICAgYFRoZSBkaXJlY3RvcnkgJHtnaXRUYXJnZXREaXJ9IGFscmVhZHkgZXhpc3RzLlxcblxcbmAgK1xuICAgICAgICAgICAgJyoqT3B0aW9uczoqKlxcbicgK1xuICAgICAgICAgICAgJzEuIFJlbW92ZSB0aGUgZXhpc3RpbmcgZGlyZWN0b3J5IGZpcnN0XFxuJyArXG4gICAgICAgICAgICAnMi4gQ2hvb3NlIGEgZGlmZmVyZW50IHRhcmdldCBkaXJlY3RvcnlcXG4nICtcbiAgICAgICAgICAgICczLiBVc2UgdGhlIGV4aXN0aW5nIGdpdCBpbnN0YWxsYXRpb24nXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gRGlyZWN0b3J5IGRvZXNuJ3QgZXhpc3QsIGdvb2QgdG8gcHJvY2VlZFxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQcm9ncmVzcyBtZXNzYWdlIGJ1aWxkZXJcbiAgICAgIGxldCBwcm9ncmVzc1N0ZXBzID0gcGVyc29uYUluZGljYXRvciArICfwn5SEICoqR2l0IEluc3RhbGxhdGlvbiBQcm9ncmVzcyoqXFxuXFxuJztcbiAgICAgIHByb2dyZXNzU3RlcHMgKz0gJyoqU3RlcHM6KipcXG4nO1xuICAgICAgcHJvZ3Jlc3NTdGVwcyArPSAn4o+zIENsb25pbmcgcmVwb3NpdG9yeS4uLlxcbic7XG4gICAgICBwcm9ncmVzc1N0ZXBzICs9ICfij7MgSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMuLi5cXG4nO1xuICAgICAgcHJvZ3Jlc3NTdGVwcyArPSAn4o+zIEJ1aWxkaW5nIFR5cGVTY3JpcHQuLi5cXG4nO1xuICAgICAgcHJvZ3Jlc3NTdGVwcyArPSAn4o+zIFNldHRpbmcgdXAgY29uZmlndXJhdGlvbi4uLlxcblxcbic7XG4gICAgICBwcm9ncmVzc1N0ZXBzICs9ICcqKkN1cnJlbnQgU3RlcDoqKiBDbG9uaW5nIHJlcG9zaXRvcnlcXG4nO1xuICAgICAgcHJvZ3Jlc3NTdGVwcyArPSAnYGBgXFxuJztcbiAgICAgIHByb2dyZXNzU3RlcHMgKz0gYFRhcmdldDogJHtnaXRUYXJnZXREaXJ9XFxuYDtcbiAgICAgIHByb2dyZXNzU3RlcHMgKz0gJ1RoaXMgbWF5IHRha2UgYSBmZXcgbWludXRlcyBkZXBlbmRpbmcgb24geW91ciBjb25uZWN0aW9uLi4uXFxuJztcbiAgICAgIHByb2dyZXNzU3RlcHMgKz0gJ2BgYFxcbic7XG4gICAgICBcbiAgICAgIC8vIEdldCBjb25maWd1cmF0aW9uXG4gICAgICBjb25zdCBjb25maWcgPSBVcGRhdGVDb25maWdNYW5hZ2VyLmdldEluc3RhbmNlKCk7XG4gICAgICBcbiAgICAgIC8vIFN0ZXAgMTogQ2xvbmUgdGhlIHJlcG9zaXRvcnlcbiAgICAgIGxvZ2dlci5pbmZvKCdbVXBkYXRlTWFuYWdlcl0gQ2xvbmluZyByZXBvc2l0b3J5Li4uJyk7XG4gICAgICBcbiAgICAgIC8vIFNFQ1VSSVRZIEZJWDogVmFsaWRhdGUgZ2l0VGFyZ2V0RGlyIHRvIHByZXZlbnQgY29tbWFuZCBpbmplY3Rpb25cbiAgICAgIC8vIFByZXZpb3VzbHk6IGdpdFRhcmdldERpciBwYXNzZWQgZGlyZWN0bHkgdG8gZ2l0IGNsb25lIGNvbW1hbmRcbiAgICAgIC8vIE5vdzogUmVqZWN0IHBhdGhzIHN0YXJ0aW5nIHdpdGggJy0tJyB0byBwcmV2ZW50IGdpdCBvcHRpb24gaW5qZWN0aW9uXG4gICAgICBpZiAoZ2l0VGFyZ2V0RGlyLnN0YXJ0c1dpdGgoJy0tJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRhcmdldCBkaXJlY3Rvcnk6IGNhbm5vdCBzdGFydCB3aXRoIGdpdCBvcHRpb25zJyk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGF3YWl0IHNhZmVFeGVjKCdnaXQnLCBbJ2Nsb25lJywgJ2h0dHBzOi8vZ2l0aHViLmNvbS9Eb2xsaG91c2VNQ1AvbWNwLXNlcnZlci5naXQnLCBnaXRUYXJnZXREaXJdLCB7XG4gICAgICAgIHRpbWVvdXQ6IGNvbmZpZy5nZXRHaXRDbG9uZVRpbWVvdXQoKVxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHByb2dyZXNzU3RlcHMgPSBwcm9ncmVzc1N0ZXBzLnJlcGxhY2UoJ+KPsyBDbG9uaW5nIHJlcG9zaXRvcnkuLi4nLCAn4pyFIFJlcG9zaXRvcnkgY2xvbmVkJyk7XG4gICAgICBwcm9ncmVzc1N0ZXBzID0gcHJvZ3Jlc3NTdGVwcy5yZXBsYWNlKCcqKkN1cnJlbnQgU3RlcDoqKiBDbG9uaW5nIHJlcG9zaXRvcnknLCAnKipDdXJyZW50IFN0ZXA6KiogSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMnKTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCAyOiBJbnN0YWxsIGRlcGVuZGVuY2llc1xuICAgICAgbG9nZ2VyLmluZm8oJ1tVcGRhdGVNYW5hZ2VyXSBJbnN0YWxsaW5nIGRlcGVuZGVuY2llcy4uLicpO1xuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ25wbScsIFsnaW5zdGFsbCddLCB7XG4gICAgICAgIGN3ZDogZ2l0VGFyZ2V0RGlyLFxuICAgICAgICB0aW1lb3V0OiBjb25maWcuZ2V0TnBtSW5zdGFsbFRpbWVvdXQoKVxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHByb2dyZXNzU3RlcHMgPSBwcm9ncmVzc1N0ZXBzLnJlcGxhY2UoJ+KPsyBJbnN0YWxsaW5nIGRlcGVuZGVuY2llcy4uLicsICfinIUgRGVwZW5kZW5jaWVzIGluc3RhbGxlZCcpO1xuICAgICAgcHJvZ3Jlc3NTdGVwcyA9IHByb2dyZXNzU3RlcHMucmVwbGFjZSgnKipDdXJyZW50IFN0ZXA6KiogSW5zdGFsbGluZyBkZXBlbmRlbmNpZXMnLCAnKipDdXJyZW50IFN0ZXA6KiogQnVpbGRpbmcgVHlwZVNjcmlwdCcpO1xuICAgICAgXG4gICAgICAvLyBTdGVwIDM6IEJ1aWxkIFR5cGVTY3JpcHRcbiAgICAgIGxvZ2dlci5pbmZvKCdbVXBkYXRlTWFuYWdlcl0gQnVpbGRpbmcgVHlwZVNjcmlwdC4uLicpO1xuICAgICAgYXdhaXQgc2FmZUV4ZWMoJ25wbScsIFsncnVuJywgJ2J1aWxkJ10sIHtcbiAgICAgICAgY3dkOiBnaXRUYXJnZXREaXIsXG4gICAgICAgIHRpbWVvdXQ6IGNvbmZpZy5nZXRCdWlsZFRpbWVvdXQoKVxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHByb2dyZXNzU3RlcHMgPSBwcm9ncmVzc1N0ZXBzLnJlcGxhY2UoJ+KPsyBCdWlsZGluZyBUeXBlU2NyaXB0Li4uJywgJ+KchSBUeXBlU2NyaXB0IGJ1aWx0Jyk7XG4gICAgICBwcm9ncmVzc1N0ZXBzID0gcHJvZ3Jlc3NTdGVwcy5yZXBsYWNlKCcqKkN1cnJlbnQgU3RlcDoqKiBCdWlsZGluZyBUeXBlU2NyaXB0JywgJyoqQ3VycmVudCBTdGVwOioqIENvbmZpZ3VyYXRpb24nKTtcbiAgICAgIFxuICAgICAgLy8gU3RlcCA0OiBDb3B5IHBvcnRmb2xpb1xuICAgICAgY29uc3QgcG9ydGZvbGlvU291cmNlID0gcGF0aC5qb2luKHByb2Nlc3MuZW52LkhPTUUgfHwgJycsICcuZG9sbGhvdXNlJywgJ3BvcnRmb2xpbycpO1xuICAgICAgY29uc3QgcG9ydGZvbGlvVGFyZ2V0ID0gcGF0aC5qb2luKHByb2Nlc3MuZW52LkhPTUUgfHwgJycsICcuZG9sbGhvdXNlJywgJ3BvcnRmb2xpbycpO1xuICAgICAgXG4gICAgICBsb2dnZXIuaW5mbygnW1VwZGF0ZU1hbmFnZXJdIFBvcnRmb2xpbyB3aWxsIHJlbWFpbiBhdDogJyArIHBvcnRmb2xpb1RhcmdldCk7XG4gICAgICBcbiAgICAgIC8vIFN0ZXAgNTogR2VuZXJhdGUgQ2xhdWRlIERlc2t0b3AgY29uZmlnXG4gICAgICBjb25zdCBjb25maWdQYXRoID0gcGF0aC5qb2luKGdpdFRhcmdldERpciwgJ2Rpc3QnLCAnaW5kZXguanMnKTtcbiAgICAgIGNvbnN0IGNsYXVkZUNvbmZpZyA9IHtcbiAgICAgICAgbWNwU2VydmVyczoge1xuICAgICAgICAgIGRvbGxob3VzZW1jcDoge1xuICAgICAgICAgICAgY29tbWFuZDogJ25vZGUnLFxuICAgICAgICAgICAgYXJnczogW2NvbmZpZ1BhdGhdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBwZXJzb25hSW5kaWNhdG9yICsgJ+KchSAqKkdpdCBJbnN0YWxsYXRpb24gQ29tcGxldGUhKipcXG5cXG4nICtcbiAgICAgICAgICBgKipJbnN0YWxsYXRpb24gTG9jYXRpb246KiogJHtnaXRUYXJnZXREaXJ9XFxuXFxuYCArXG4gICAgICAgICAgJyoqTmV4dCBTdGVwczoqKlxcblxcbicgK1xuICAgICAgICAgICcxLiAqKlVwZGF0ZSBDbGF1ZGUgRGVza3RvcCBjb25maWd1cmF0aW9uOioqXFxuJyArXG4gICAgICAgICAgJyAgIGBgYGpzb25cXG4nICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShjbGF1ZGVDb25maWcsIG51bGwsIDIpICsgJ1xcbicgK1xuICAgICAgICAgICcgICBgYGBcXG5cXG4nICtcbiAgICAgICAgICAnMi4gKipSZXN0YXJ0IENsYXVkZSBEZXNrdG9wKipcXG5cXG4nICtcbiAgICAgICAgICAnMy4gKipWZXJpZnkgaW5zdGFsbGF0aW9uOioqXFxuJyArXG4gICAgICAgICAgJyAgIEFmdGVyIHJlc3RhcnQsIHJ1biBgZ2V0X3NlcnZlcl9zdGF0dXNgIHRvIGNvbmZpcm1cXG5cXG4nICtcbiAgICAgICAgICAnKipZb3VyIHBvcnRmb2xpbyByZW1haW5zIGF0OioqXFxuJyArXG4gICAgICAgICAgYCAgICR7cG9ydGZvbGlvVGFyZ2V0fVxcblxcbmAgK1xuICAgICAgICAgICcqKlRvIHVwZGF0ZSBpbiB0aGUgZnV0dXJlOioqXFxuJyArXG4gICAgICAgICAgJyAgIGBgYGJhc2hcXG4nICtcbiAgICAgICAgICBgICAgY2QgJHtnaXRUYXJnZXREaXJ9XFxuYCArXG4gICAgICAgICAgJyAgIGdpdCBwdWxsXFxuJyArXG4gICAgICAgICAgJyAgIG5wbSBpbnN0YWxsXFxuJyArXG4gICAgICAgICAgJyAgIG5wbSBydW4gYnVpbGRcXG4nICtcbiAgICAgICAgICAnICAgYGBgXFxuXFxuJyArXG4gICAgICAgICAgJ/CfkqEgKipUaXA6KiogWW91IGNhbiBub3cgdXNlIGB1cGRhdGVfc2VydmVyYCB0byB1cGRhdGUgdmlhIGdpdCEnXG4gICAgICB9O1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignW1VwZGF0ZU1hbmFnZXJdIEdpdCBjb252ZXJzaW9uIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRleHQ6IHBlcnNvbmFJbmRpY2F0b3IgKyAn4p2MICoqQ29udmVyc2lvbiBGYWlsZWQqKlxcblxcbicgK1xuICAgICAgICAgICdFcnJvcjogJyArIGVycm9yTWVzc2FnZSArICdcXG5cXG4nICtcbiAgICAgICAgICAnKipUcm91Ymxlc2hvb3Rpbmc6KipcXG4nICtcbiAgICAgICAgICAnMS4gRW5zdXJlIGdpdCBpcyBpbnN0YWxsZWRcXG4nICtcbiAgICAgICAgICAnMi4gQ2hlY2sgaW50ZXJuZXQgY29ubmVjdGlvblxcbicgK1xuICAgICAgICAgICczLiBWZXJpZnkgeW91IGhhdmUgd3JpdGUgcGVybWlzc2lvbnNcXG4nICtcbiAgICAgICAgICAnNC4gVHJ5IGEgZGlmZmVyZW50IHRhcmdldCBkaXJlY3RvcnknXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHNlcnZlciBzdGF0dXNcbiAgICovXG4gIGFzeW5jIGdldFNlcnZlclN0YXR1cyhwZXJzb25hSW5kaWNhdG9yOiBzdHJpbmcgPSAnJyk6IFByb21pc2U8eyB0ZXh0OiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjdXJyZW50VmVyc2lvbiA9IGF3YWl0IHRoaXMudmVyc2lvbk1hbmFnZXIuZ2V0Q3VycmVudFZlcnNpb24oKTtcbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGF3YWl0IHRoaXMuZGVwZW5kZW5jeUNoZWNrZXIuY2hlY2tEZXBlbmRlbmNpZXMoKTtcbiAgICAgIGNvbnN0IGJhY2t1cHMgPSBhd2FpdCB0aGlzLmJhY2t1cE1hbmFnZXIubGlzdEJhY2t1cHMoKTtcbiAgICAgIGNvbnN0IHJhdGVMaW1pdFN0YXR1cyA9IHRoaXMudXBkYXRlQ2hlY2tlci5nZXRSYXRlTGltaXRTdGF0dXMoKTtcbiAgICAgIFxuICAgICAgLy8gR2V0IGluc3RhbGxhdGlvbiB0eXBlXG4gICAgICBjb25zdCBpbnN0YWxsYXRpb25UeXBlID0gSW5zdGFsbGF0aW9uRGV0ZWN0b3IuZ2V0SW5zdGFsbGF0aW9uVHlwZSgpO1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9uRGVzYyA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldEluc3RhbGxhdGlvbkRlc2NyaXB0aW9uKCk7XG4gICAgICBcbiAgICAgIC8vIEdldCBnaXQgc3RhdHVzIChvbmx5IGZvciBnaXQgaW5zdGFsbGF0aW9ucylcbiAgICAgIGxldCBnaXRTdGF0dXMgPSAnTi9BJztcbiAgICAgIGxldCBnaXRCcmFuY2ggPSAnTi9BJztcbiAgICAgIGxldCBsYXN0Q29tbWl0ID0gJ04vQSc7XG4gICAgICBcbiAgICAgIGlmIChpbnN0YWxsYXRpb25UeXBlID09PSAnZ2l0Jykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgc3Rkb3V0OiBicmFuY2hPdXRwdXQgfSA9IGF3YWl0IHNhZmVFeGVjKCdnaXQnLCBbJ2JyYW5jaCcsICctLXNob3ctY3VycmVudCddLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pO1xuICAgICAgICAgIGdpdEJyYW5jaCA9IGJyYW5jaE91dHB1dC50cmltKCkgfHwgJ2RldGFjaGVkJztcbiAgICAgICAgICBcbiAgICAgICAgICBjb25zdCB7IHN0ZG91dDogc3RhdHVzT3V0cHV0IH0gPSBhd2FpdCBzYWZlRXhlYygnZ2l0JywgWydzdGF0dXMnLCAnLS1wb3JjZWxhaW4nXSwgeyBjd2Q6IHRoaXMucm9vdERpciB9KTtcbiAgICAgICAgICBnaXRTdGF0dXMgPSBzdGF0dXNPdXRwdXQudHJpbSgpID8gJ01vZGlmaWVkJyA6ICdDbGVhbic7XG4gICAgICAgICAgXG4gICAgICAgICAgY29uc3QgeyBzdGRvdXQ6IGxvZ091dHB1dCB9ID0gYXdhaXQgc2FmZUV4ZWMoJ2dpdCcsIFsnbG9nJywgJy0xJywgJy0tb25lbGluZSddLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pO1xuICAgICAgICAgIGxhc3RDb21taXQgPSBsb2dPdXRwdXQudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBHaXQgY29tbWFuZHMgZmFpbGVkLCB1c2UgZGVmYXVsdHNcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zdCBzdGF0dXNQYXJ0cyA9IFtcbiAgICAgICAgcGVyc29uYUluZGljYXRvciArICfwn5OKICoqRG9sbGhvdXNlTUNQIFNlcnZlciBTdGF0dXMqKlxcblxcbicsXG4gICAgICAgICcqKlZlcnNpb24gSW5mb3JtYXRpb246KipcXG4nLFxuICAgICAgICBg4oCiIEN1cnJlbnQgVmVyc2lvbjogJHtjdXJyZW50VmVyc2lvbn1cXG5gLFxuICAgICAgICBg4oCiIEluc3RhbGxhdGlvbiBUeXBlOiAke2luc3RhbGxhdGlvblR5cGV9ICgke2luc3RhbGxhdGlvbkRlc2N9KVxcbmAsXG4gICAgICAgIGDigKIgR2l0IEJyYW5jaDogJHtnaXRCcmFuY2h9XFxuYCxcbiAgICAgICAgYOKAoiBHaXQgU3RhdHVzOiAke2dpdFN0YXR1c31cXG5gLFxuICAgICAgICBg4oCiIExhc3QgQ29tbWl0OiAke2xhc3RDb21taXR9XFxuXFxuYCxcbiAgICAgICAgJyoqRGVwZW5kZW5jaWVzOioqXFxuJyxcbiAgICAgICAgdGhpcy5kZXBlbmRlbmN5Q2hlY2tlci5mb3JtYXREZXBlbmRlbmN5U3RhdHVzKGRlcGVuZGVuY2llcyksXG4gICAgICAgICdcXG5cXG4qKkJhY2t1cHM6KipcXG4nLFxuICAgICAgICBg4oCiIFRvdGFsIEJhY2t1cHM6ICR7YmFja3Vwcy5sZW5ndGh9XFxuYFxuICAgICAgXTtcbiAgICAgIFxuICAgICAgaWYgKGJhY2t1cHMubGVuZ3RoID4gMCkge1xuICAgICAgICBzdGF0dXNQYXJ0cy5wdXNoKGDigKIgTGF0ZXN0IEJhY2t1cDogJHtiYWNrdXBzWzBdLnRpbWVzdGFtcH0gKHYke2JhY2t1cHNbMF0udmVyc2lvbiB8fCAndW5rbm93bid9KVxcbmApO1xuICAgICAgICBzdGF0dXNQYXJ0cy5wdXNoKGDigKIgT2xkZXN0IEJhY2t1cDogJHtiYWNrdXBzW2JhY2t1cHMubGVuZ3RoIC0gMV0udGltZXN0YW1wfVxcbmApO1xuICAgICAgfVxuICAgICAgXG4gICAgICBzdGF0dXNQYXJ0cy5wdXNoKFxuICAgICAgICAnXFxuKipSYXRlIExpbWl0IFN0YXR1czoqKlxcbicsXG4gICAgICAgIGDigKIgVXBkYXRlIENoZWNrcyBSZW1haW5pbmc6ICR7cmF0ZUxpbWl0U3RhdHVzLnJlbWFpbmluZ1JlcXVlc3RzfS8xMCBwZXIgaG91clxcbmAsXG4gICAgICAgIGDigKIgUmF0ZSBMaW1pdCBSZXNldHM6ICR7cmF0ZUxpbWl0U3RhdHVzLnJlc2V0VGltZS50b0xvY2FsZVRpbWVTdHJpbmcoKX1cXG5gXG4gICAgICApO1xuICAgICAgXG4gICAgICBpZiAoIXJhdGVMaW1pdFN0YXR1cy5hbGxvd2VkICYmIHJhdGVMaW1pdFN0YXR1cy53YWl0VGltZVNlY29uZHMpIHtcbiAgICAgICAgc3RhdHVzUGFydHMucHVzaChg4oCiIOKPsyBXYWl0ICR7cmF0ZUxpbWl0U3RhdHVzLndhaXRUaW1lU2Vjb25kc30gc2Vjb25kcyBiZWZvcmUgbmV4dCBjaGVja1xcbmApO1xuICAgICAgfVxuICAgICAgXG4gICAgICBzdGF0dXNQYXJ0cy5wdXNoKFxuICAgICAgICAnXFxuKipBdmFpbGFibGUgQ29tbWFuZHM6KipcXG4nLFxuICAgICAgICAn4oCiIGBjaGVja19mb3JfdXBkYXRlc2AgLSBDaGVjayBmb3IgbmV3IHZlcnNpb25zXFxuJyxcbiAgICAgICAgJ+KAoiBgdXBkYXRlX3NlcnZlciB0cnVlYCAtIFVwZGF0ZSB0byBsYXRlc3QgdmVyc2lvblxcbicsXG4gICAgICAgICfigKIgYHJvbGxiYWNrX3VwZGF0ZSB0cnVlYCAtIFJlc3RvcmUgZnJvbSBiYWNrdXBcXG4nXG4gICAgICApO1xuICAgICAgXG4gICAgICByZXR1cm4geyB0ZXh0OiBzdGF0dXNQYXJ0cy5qb2luKCcnKSB9O1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogcGVyc29uYUluZGljYXRvciArICfinYwgKipTdGF0dXMgQ2hlY2sgRmFpbGVkKipcXG5cXG4nICtcbiAgICAgICAgICAnRXJyb3I6ICcgKyBlcnJvck1lc3NhZ2UgKyAnXFxuXFxuJyArXG4gICAgICAgICAgJ1RoZSBzZXJ2ZXIgbWF5IGJlIGluIGFuIGluY29uc2lzdGVudCBzdGF0ZS5cXG4nICtcbiAgICAgICAgICAnVHJ5IHJ1bm5pbmcgYHVwZGF0ZV9zZXJ2ZXIgdHJ1ZWAgdG8gZml4IGlzc3Vlcy4nXG4gICAgICB9O1xuICAgIH1cbiAgfVxufSJdfQ==
|