@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.
Files changed (42) hide show
  1. package/README.md +54 -9
  2. package/dist/config/updateConfig.d.ts +84 -0
  3. package/dist/config/updateConfig.d.ts.map +1 -0
  4. package/dist/config/updateConfig.js +148 -0
  5. package/dist/generated/version.d.ts +9 -0
  6. package/dist/generated/version.d.ts.map +1 -0
  7. package/dist/generated/version.js +9 -0
  8. package/dist/index.d.ts +6 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +34 -6
  11. package/dist/portfolio/DefaultElementProvider.d.ts +78 -0
  12. package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -0
  13. package/dist/portfolio/DefaultElementProvider.js +398 -0
  14. package/dist/portfolio/PortfolioManager.d.ts +7 -0
  15. package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
  16. package/dist/portfolio/PortfolioManager.js +44 -3
  17. package/dist/security/commandValidator.d.ts.map +1 -1
  18. package/dist/security/commandValidator.js +5 -2
  19. package/dist/security/securityMonitor.d.ts +2 -1
  20. package/dist/security/securityMonitor.d.ts.map +1 -1
  21. package/dist/security/securityMonitor.js +1 -1
  22. package/dist/server/tools/UpdateTools.d.ts.map +1 -1
  23. package/dist/server/tools/UpdateTools.js +22 -1
  24. package/dist/server/types.d.ts +1 -0
  25. package/dist/server/types.d.ts.map +1 -1
  26. package/dist/server/types.js +1 -1
  27. package/dist/update/BackupManager.d.ts +17 -0
  28. package/dist/update/BackupManager.d.ts.map +1 -1
  29. package/dist/update/BackupManager.js +112 -3
  30. package/dist/update/UpdateManager.d.ts +19 -0
  31. package/dist/update/UpdateManager.d.ts.map +1 -1
  32. package/dist/update/UpdateManager.js +485 -15
  33. package/dist/update/VersionManager.d.ts +1 -1
  34. package/dist/update/VersionManager.d.ts.map +1 -1
  35. package/dist/update/VersionManager.js +62 -15
  36. package/dist/utils/fileOperations.d.ts +83 -0
  37. package/dist/utils/fileOperations.d.ts.map +1 -0
  38. package/dist/utils/fileOperations.js +291 -0
  39. package/dist/utils/installation.d.ts +30 -0
  40. package/dist/utils/installation.d.ts.map +1 -0
  41. package/dist/utils/installation.js +160 -0
  42. 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 git status
212
- let gitStatus = 'Unknown';
213
- let gitBranch = 'Unknown';
214
- let lastCommit = 'Unknown';
215
- try {
216
- const { stdout: branchOutput } = await safeExec('git', ['branch', '--show-current'], { cwd: this.rootDir });
217
- gitBranch = branchOutput.trim() || 'detached';
218
- const { stdout: statusOutput } = await safeExec('git', ['status', '--porcelain'], { cwd: this.rootDir });
219
- gitStatus = statusOutput.trim() ? 'Modified' : 'Clean';
220
- const { stdout: logOutput } = await safeExec('git', ['log', '-1', '--oneline'], { cwd: this.rootDir });
221
- lastCommit = logOutput.trim();
222
- }
223
- catch {
224
- // Git commands failed, use defaults
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==