@dollhousemcp/mcp-server 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -0
- package/LICENSE +51 -0
- package/README.md +1124 -0
- package/data/agents/code-reviewer.md +296 -0
- package/data/agents/research-assistant.md +259 -0
- package/data/agents/task-manager.md +206 -0
- package/data/ensembles/business-advisor.md +354 -0
- package/data/ensembles/creative-studio.md +288 -0
- package/data/ensembles/development-team.md +292 -0
- package/data/ensembles/security-analysis-team.md +438 -0
- package/data/memories/conversation-history.md +146 -0
- package/data/memories/learning-progress.md +376 -0
- package/data/memories/project-context.md +268 -0
- package/data/personas/business-consultant.md +50 -0
- package/data/personas/creative-writer.md +44 -0
- package/data/personas/debug-detective.md +59 -0
- package/data/personas/eli5-explainer.md +49 -0
- package/data/personas/security-analyst.md +161 -0
- package/data/personas/technical-analyst.md +43 -0
- package/data/skills/code-review.md +112 -0
- package/data/skills/creative-writing.md +174 -0
- package/data/skills/data-analysis.md +160 -0
- package/data/skills/penetration-testing.md +374 -0
- package/data/skills/research.md +181 -0
- package/data/skills/threat-modeling.md +469 -0
- package/data/skills/translation.md +148 -0
- package/data/templates/code-documentation.md +409 -0
- package/data/templates/email-professional.md +158 -0
- package/data/templates/meeting-notes.md +141 -0
- package/data/templates/penetration-test-report.md +608 -0
- package/data/templates/project-brief.md +234 -0
- package/data/templates/report-executive.md +258 -0
- package/data/templates/security-vulnerability-report.md +457 -0
- package/data/templates/threat-assessment-report.md +774 -0
- package/dist/cache/APICache.d.ts +23 -0
- package/dist/cache/APICache.d.ts.map +1 -0
- package/dist/cache/APICache.js +42 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +5 -0
- package/dist/collection/CollectionBrowser.d.ts +24 -0
- package/dist/collection/CollectionBrowser.d.ts.map +1 -0
- package/dist/collection/CollectionBrowser.js +120 -0
- package/dist/collection/CollectionSearch.d.ts +18 -0
- package/dist/collection/CollectionSearch.d.ts.map +1 -0
- package/dist/collection/CollectionSearch.js +48 -0
- package/dist/collection/ElementInstaller.d.ts +33 -0
- package/dist/collection/ElementInstaller.d.ts.map +1 -0
- package/dist/collection/ElementInstaller.js +142 -0
- package/dist/collection/GitHubClient.d.ts +22 -0
- package/dist/collection/GitHubClient.d.ts.map +1 -0
- package/dist/collection/GitHubClient.js +114 -0
- package/dist/collection/MarketplaceBrowser.d.ts +24 -0
- package/dist/collection/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/collection/MarketplaceBrowser.js +115 -0
- package/dist/collection/MarketplaceSearch.d.ts +18 -0
- package/dist/collection/MarketplaceSearch.d.ts.map +1 -0
- package/dist/collection/MarketplaceSearch.js +48 -0
- package/dist/collection/PersonaDetails.d.ts +22 -0
- package/dist/collection/PersonaDetails.d.ts.map +1 -0
- package/dist/collection/PersonaDetails.js +71 -0
- package/dist/collection/PersonaInstaller.d.ts +26 -0
- package/dist/collection/PersonaInstaller.d.ts.map +1 -0
- package/dist/collection/PersonaInstaller.js +103 -0
- package/dist/collection/PersonaSubmitter.d.ts +19 -0
- package/dist/collection/PersonaSubmitter.d.ts.map +1 -0
- package/dist/collection/PersonaSubmitter.js +57 -0
- package/dist/collection/index.d.ts +10 -0
- package/dist/collection/index.d.ts.map +1 -0
- package/dist/collection/index.js +10 -0
- package/dist/config/constants.d.ts +25 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +34 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/indicator-config.d.ts +107 -0
- package/dist/config/indicator-config.d.ts.map +1 -0
- package/dist/config/indicator-config.js +158 -0
- package/dist/constants/defaultPersonas.d.ts +10 -0
- package/dist/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/constants/defaultPersonas.js +18 -0
- package/dist/constants/limits.d.ts +10 -0
- package/dist/constants/limits.d.ts.map +1 -0
- package/dist/constants/limits.js +13 -0
- package/dist/elements/BaseElement.d.ts +81 -0
- package/dist/elements/BaseElement.d.ts.map +1 -0
- package/dist/elements/BaseElement.js +381 -0
- package/dist/elements/FeedbackProcessor.d.ts +57 -0
- package/dist/elements/FeedbackProcessor.d.ts.map +1 -0
- package/dist/elements/FeedbackProcessor.js +418 -0
- package/dist/elements/agents/Agent.d.ts +145 -0
- package/dist/elements/agents/Agent.d.ts.map +1 -0
- package/dist/elements/agents/Agent.js +848 -0
- package/dist/elements/agents/AgentManager.d.ts +125 -0
- package/dist/elements/agents/AgentManager.d.ts.map +1 -0
- package/dist/elements/agents/AgentManager.js +615 -0
- package/dist/elements/agents/constants.d.ts +42 -0
- package/dist/elements/agents/constants.d.ts.map +1 -0
- package/dist/elements/agents/constants.js +45 -0
- package/dist/elements/agents/goalTemplates.d.ts +44 -0
- package/dist/elements/agents/goalTemplates.d.ts.map +1 -0
- package/dist/elements/agents/goalTemplates.js +297 -0
- package/dist/elements/agents/index.d.ts +8 -0
- package/dist/elements/agents/index.d.ts.map +1 -0
- package/dist/elements/agents/index.js +8 -0
- package/dist/elements/agents/ruleEngineConfig.d.ts +76 -0
- package/dist/elements/agents/ruleEngineConfig.d.ts.map +1 -0
- package/dist/elements/agents/ruleEngineConfig.js +143 -0
- package/dist/elements/agents/types.d.ts +97 -0
- package/dist/elements/agents/types.d.ts.map +1 -0
- package/dist/elements/agents/types.js +5 -0
- package/dist/elements/ensembles/Ensemble.d.ts +144 -0
- package/dist/elements/ensembles/Ensemble.d.ts.map +1 -0
- package/dist/elements/ensembles/Ensemble.js +860 -0
- package/dist/elements/ensembles/EnsembleManager.d.ts +85 -0
- package/dist/elements/ensembles/EnsembleManager.d.ts.map +1 -0
- package/dist/elements/ensembles/EnsembleManager.js +378 -0
- package/dist/elements/ensembles/constants.d.ts +73 -0
- package/dist/elements/ensembles/constants.d.ts.map +1 -0
- package/dist/elements/ensembles/constants.js +92 -0
- package/dist/elements/ensembles/index.d.ts +8 -0
- package/dist/elements/ensembles/index.d.ts.map +1 -0
- package/dist/elements/ensembles/index.js +8 -0
- package/dist/elements/ensembles/types.d.ts +92 -0
- package/dist/elements/ensembles/types.d.ts.map +1 -0
- package/dist/elements/ensembles/types.js +8 -0
- package/dist/elements/index.d.ts +11 -0
- package/dist/elements/index.d.ts.map +1 -0
- package/dist/elements/index.js +12 -0
- package/dist/elements/memories/Memory.d.ts +110 -0
- package/dist/elements/memories/Memory.d.ts.map +1 -0
- package/dist/elements/memories/Memory.js +470 -0
- package/dist/elements/memories/MemoryManager.d.ts +86 -0
- package/dist/elements/memories/MemoryManager.d.ts.map +1 -0
- package/dist/elements/memories/MemoryManager.js +435 -0
- package/dist/elements/memories/constants.d.ts +42 -0
- package/dist/elements/memories/constants.d.ts.map +1 -0
- package/dist/elements/memories/constants.js +49 -0
- package/dist/elements/memories/index.d.ts +6 -0
- package/dist/elements/memories/index.d.ts.map +1 -0
- package/dist/elements/memories/index.js +6 -0
- package/dist/elements/skills/Skill.d.ts +109 -0
- package/dist/elements/skills/Skill.d.ts.map +1 -0
- package/dist/elements/skills/Skill.js +381 -0
- package/dist/elements/skills/index.d.ts +5 -0
- package/dist/elements/skills/index.d.ts.map +1 -0
- package/dist/elements/skills/index.js +5 -0
- package/dist/elements/templates/Template.d.ts +138 -0
- package/dist/elements/templates/Template.d.ts.map +1 -0
- package/dist/elements/templates/Template.js +673 -0
- package/dist/elements/templates/TemplateManager.d.ts +104 -0
- package/dist/elements/templates/TemplateManager.d.ts.map +1 -0
- package/dist/elements/templates/TemplateManager.js +501 -0
- package/dist/elements/templates/index.d.ts +6 -0
- package/dist/elements/templates/index.d.ts.map +1 -0
- package/dist/elements/templates/index.js +6 -0
- package/dist/errors/SecurityError.d.ts +29 -0
- package/dist/errors/SecurityError.d.ts.map +1 -0
- package/dist/errors/SecurityError.js +47 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/index.barrel.d.ts +21 -0
- package/dist/index.barrel.d.ts.map +1 -0
- package/dist/index.barrel.js +31 -0
- package/dist/index.d.ts +223 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1606 -0
- package/dist/marketplace/GitHubClient.d.ts +22 -0
- package/dist/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/marketplace/GitHubClient.js +112 -0
- package/dist/marketplace/MarketplaceBrowser.d.ts +24 -0
- package/dist/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/marketplace/MarketplaceBrowser.js +115 -0
- package/dist/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/marketplace/MarketplaceSearch.js +48 -0
- package/dist/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/marketplace/PersonaDetails.js +71 -0
- package/dist/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/marketplace/PersonaInstaller.js +100 -0
- package/dist/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/marketplace/PersonaSubmitter.js +57 -0
- package/dist/marketplace/index.d.ts +10 -0
- package/dist/marketplace/index.d.ts.map +1 -0
- package/dist/marketplace/index.js +10 -0
- package/dist/persona/PersonaElement.d.ts +64 -0
- package/dist/persona/PersonaElement.d.ts.map +1 -0
- package/dist/persona/PersonaElement.js +223 -0
- package/dist/persona/PersonaElementManager.d.ts +97 -0
- package/dist/persona/PersonaElementManager.d.ts.map +1 -0
- package/dist/persona/PersonaElementManager.js +348 -0
- package/dist/persona/PersonaLoader.d.ts +34 -0
- package/dist/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/persona/PersonaLoader.js +145 -0
- package/dist/persona/PersonaManager.d.ts +112 -0
- package/dist/persona/PersonaManager.d.ts.map +1 -0
- package/dist/persona/PersonaManager.js +341 -0
- package/dist/persona/PersonaValidator.d.ts +39 -0
- package/dist/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/persona/PersonaValidator.js +161 -0
- package/dist/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaExporter.js +99 -0
- package/dist/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaImporter.js +315 -0
- package/dist/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaSharer.js +502 -0
- package/dist/persona/export-import/index.d.ts +10 -0
- package/dist/persona/export-import/index.d.ts.map +1 -0
- package/dist/persona/export-import/index.js +7 -0
- package/dist/persona/index.d.ts +7 -0
- package/dist/persona/index.d.ts.map +1 -0
- package/dist/persona/index.js +7 -0
- package/dist/portfolio/MigrationManager.d.ts +44 -0
- package/dist/portfolio/MigrationManager.d.ts.map +1 -0
- package/dist/portfolio/MigrationManager.js +163 -0
- package/dist/portfolio/PortfolioManager.d.ts +54 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioManager.js +224 -0
- package/dist/portfolio/types.d.ts +18 -0
- package/dist/portfolio/types.d.ts.map +1 -0
- package/dist/portfolio/types.js +13 -0
- package/dist/security/InputValidator.d.ts +80 -0
- package/dist/security/InputValidator.d.ts.map +1 -0
- package/dist/security/InputValidator.js +448 -0
- package/dist/security/audit/SecurityAuditor.d.ts +44 -0
- package/dist/security/audit/SecurityAuditor.d.ts.map +1 -0
- package/dist/security/audit/SecurityAuditor.js +274 -0
- package/dist/security/audit/config/suppressions.d.ts +34 -0
- package/dist/security/audit/config/suppressions.d.ts.map +1 -0
- package/dist/security/audit/config/suppressions.js +575 -0
- package/dist/security/audit/index.d.ts +14 -0
- package/dist/security/audit/index.d.ts.map +1 -0
- package/dist/security/audit/index.js +15 -0
- package/dist/security/audit/reporters/ConsoleReporter.d.ts +46 -0
- package/dist/security/audit/reporters/ConsoleReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/ConsoleReporter.js +174 -0
- package/dist/security/audit/reporters/JsonReporter.d.ts +13 -0
- package/dist/security/audit/reporters/JsonReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/JsonReporter.js +25 -0
- package/dist/security/audit/reporters/MarkdownReporter.d.ts +13 -0
- package/dist/security/audit/reporters/MarkdownReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/MarkdownReporter.js +79 -0
- package/dist/security/audit/rules/SecurityRules.d.ts +20 -0
- package/dist/security/audit/rules/SecurityRules.d.ts.map +1 -0
- package/dist/security/audit/rules/SecurityRules.js +244 -0
- package/dist/security/audit/scanners/CodeScanner.d.ts +47 -0
- package/dist/security/audit/scanners/CodeScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/CodeScanner.js +174 -0
- package/dist/security/audit/scanners/ConfigurationScanner.d.ts +13 -0
- package/dist/security/audit/scanners/ConfigurationScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/ConfigurationScanner.js +22 -0
- package/dist/security/audit/scanners/DependencyScanner.d.ts +13 -0
- package/dist/security/audit/scanners/DependencyScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/DependencyScanner.js +22 -0
- package/dist/security/audit/types.d.ts +94 -0
- package/dist/security/audit/types.d.ts.map +1 -0
- package/dist/security/audit/types.js +6 -0
- package/dist/security/commandValidator.d.ts +7 -0
- package/dist/security/commandValidator.d.ts.map +1 -0
- package/dist/security/commandValidator.js +78 -0
- package/dist/security/constants.d.ts +24 -0
- package/dist/security/constants.d.ts.map +1 -0
- package/dist/security/constants.js +26 -0
- package/dist/security/contentValidator.d.ts +47 -0
- package/dist/security/contentValidator.d.ts.map +1 -0
- package/dist/security/contentValidator.js +301 -0
- package/dist/security/errorHandler.d.ts +42 -0
- package/dist/security/errorHandler.d.ts.map +1 -0
- package/dist/security/errorHandler.js +166 -0
- package/dist/security/errors.d.ts +14 -0
- package/dist/security/errors.d.ts.map +1 -0
- package/dist/security/errors.js +28 -0
- package/dist/security/fileLockManager.d.ts +70 -0
- package/dist/security/fileLockManager.d.ts.map +1 -0
- package/dist/security/fileLockManager.js +187 -0
- package/dist/security/index.d.ts +12 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +14 -0
- package/dist/security/pathValidator.d.ts +9 -0
- package/dist/security/pathValidator.d.ts.map +1 -0
- package/dist/security/pathValidator.js +102 -0
- package/dist/security/regexValidator.d.ts +59 -0
- package/dist/security/regexValidator.d.ts.map +1 -0
- package/dist/security/regexValidator.js +214 -0
- package/dist/security/secureYamlParser.d.ts +46 -0
- package/dist/security/secureYamlParser.d.ts.map +1 -0
- package/dist/security/secureYamlParser.js +203 -0
- package/dist/security/securityMonitor.d.ts +58 -0
- package/dist/security/securityMonitor.d.ts.map +1 -0
- package/dist/security/securityMonitor.js +108 -0
- package/dist/security/tokenManager.d.ts +85 -0
- package/dist/security/tokenManager.d.ts.map +1 -0
- package/dist/security/tokenManager.js +286 -0
- package/dist/security/validators/unicodeValidator.d.ts +97 -0
- package/dist/security/validators/unicodeValidator.d.ts.map +1 -0
- package/dist/security/validators/unicodeValidator.js +312 -0
- package/dist/security/yamlValidator.d.ts +21 -0
- package/dist/security/yamlValidator.d.ts.map +1 -0
- package/dist/security/yamlValidator.js +164 -0
- package/dist/server/ServerSetup.d.ts +35 -0
- package/dist/server/ServerSetup.d.ts.map +1 -0
- package/dist/server/ServerSetup.js +116 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +7 -0
- package/dist/server/startup.d.ts +31 -0
- package/dist/server/startup.d.ts.map +1 -0
- package/dist/server/startup.js +67 -0
- package/dist/server/tools/CollectionTools.d.ts +10 -0
- package/dist/server/tools/CollectionTools.d.ts.map +1 -0
- package/dist/server/tools/CollectionTools.js +96 -0
- package/dist/server/tools/ConfigTools.d.ts +10 -0
- package/dist/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/server/tools/ConfigTools.js +63 -0
- package/dist/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/server/tools/MarketplaceTools.js +96 -0
- package/dist/server/tools/PersonaTools.d.ts +10 -0
- package/dist/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/server/tools/PersonaTools.js +257 -0
- package/dist/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/server/tools/ToolRegistry.js +40 -0
- package/dist/server/tools/UpdateTools.d.ts +10 -0
- package/dist/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/server/tools/UpdateTools.js +64 -0
- package/dist/server/tools/UserTools.d.ts +10 -0
- package/dist/server/tools/UserTools.d.ts.map +1 -0
- package/dist/server/tools/UserTools.js +51 -0
- package/dist/server/tools/index.d.ts +10 -0
- package/dist/server/tools/index.d.ts.map +1 -0
- package/dist/server/tools/index.js +10 -0
- package/dist/server/types.d.ts +34 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +5 -0
- package/dist/src/cache/APICache.d.ts +23 -0
- package/dist/src/cache/APICache.d.ts.map +1 -0
- package/dist/src/cache/APICache.js +42 -0
- package/dist/src/cache/index.d.ts +5 -0
- package/dist/src/cache/index.d.ts.map +1 -0
- package/dist/src/cache/index.js +5 -0
- package/dist/src/config/constants.d.ts +25 -0
- package/dist/src/config/constants.d.ts.map +1 -0
- package/dist/src/config/constants.js +30 -0
- package/dist/src/config/index.d.ts +6 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +6 -0
- package/dist/src/config/indicator-config.d.ts +107 -0
- package/dist/src/config/indicator-config.d.ts.map +1 -0
- package/dist/src/config/indicator-config.js +158 -0
- package/dist/src/constants/defaultPersonas.d.ts +10 -0
- package/dist/src/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/src/constants/defaultPersonas.js +18 -0
- package/dist/src/constants/limits.d.ts +10 -0
- package/dist/src/constants/limits.d.ts.map +1 -0
- package/dist/src/constants/limits.js +13 -0
- package/dist/src/errors/SecurityError.d.ts +29 -0
- package/dist/src/errors/SecurityError.d.ts.map +1 -0
- package/dist/src/errors/SecurityError.js +47 -0
- package/dist/src/errors/index.d.ts +2 -0
- package/dist/src/errors/index.d.ts.map +1 -0
- package/dist/src/errors/index.js +2 -0
- package/dist/src/index.barrel.d.ts +21 -0
- package/dist/src/index.barrel.d.ts.map +1 -0
- package/dist/src/index.barrel.js +31 -0
- package/dist/src/index.d.ts +220 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +1559 -0
- package/dist/src/marketplace/GitHubClient.d.ts +22 -0
- package/dist/src/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/src/marketplace/GitHubClient.js +112 -0
- package/dist/src/marketplace/MarketplaceBrowser.d.ts +21 -0
- package/dist/src/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/src/marketplace/MarketplaceBrowser.js +45 -0
- package/dist/src/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/src/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/src/marketplace/MarketplaceSearch.js +36 -0
- package/dist/src/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/src/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaDetails.js +71 -0
- package/dist/src/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/src/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaInstaller.js +100 -0
- package/dist/src/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/src/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaSubmitter.js +57 -0
- package/dist/src/marketplace/index.d.ts +10 -0
- package/dist/src/marketplace/index.d.ts.map +1 -0
- package/dist/src/marketplace/index.js +10 -0
- package/dist/src/persona/PersonaLoader.d.ts +33 -0
- package/dist/src/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/src/persona/PersonaLoader.js +139 -0
- package/dist/src/persona/PersonaManager.d.ts +112 -0
- package/dist/src/persona/PersonaManager.d.ts.map +1 -0
- package/dist/src/persona/PersonaManager.js +341 -0
- package/dist/src/persona/PersonaValidator.d.ts +33 -0
- package/dist/src/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/src/persona/PersonaValidator.js +157 -0
- package/dist/src/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/src/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaExporter.js +99 -0
- package/dist/src/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/src/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaImporter.js +313 -0
- package/dist/src/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/src/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaSharer.js +363 -0
- package/dist/src/persona/export-import/index.d.ts +10 -0
- package/dist/src/persona/export-import/index.d.ts.map +1 -0
- package/dist/src/persona/export-import/index.js +7 -0
- package/dist/src/persona/index.d.ts +7 -0
- package/dist/src/persona/index.d.ts.map +1 -0
- package/dist/src/persona/index.js +7 -0
- package/dist/src/security/InputValidator.d.ts +69 -0
- package/dist/src/security/InputValidator.d.ts.map +1 -0
- package/dist/src/security/InputValidator.js +381 -0
- package/dist/src/security/commandValidator.d.ts +7 -0
- package/dist/src/security/commandValidator.d.ts.map +1 -0
- package/dist/src/security/commandValidator.js +77 -0
- package/dist/src/security/constants.d.ts +21 -0
- package/dist/src/security/constants.d.ts.map +1 -0
- package/dist/src/security/constants.js +23 -0
- package/dist/src/security/contentValidator.d.ts +47 -0
- package/dist/src/security/contentValidator.d.ts.map +1 -0
- package/dist/src/security/contentValidator.js +188 -0
- package/dist/src/security/fileLockManager.d.ts +70 -0
- package/dist/src/security/fileLockManager.d.ts.map +1 -0
- package/dist/src/security/fileLockManager.js +187 -0
- package/dist/src/security/index.d.ts +12 -0
- package/dist/src/security/index.d.ts.map +1 -0
- package/dist/src/security/index.js +14 -0
- package/dist/src/security/pathValidator.d.ts +9 -0
- package/dist/src/security/pathValidator.d.ts.map +1 -0
- package/dist/src/security/pathValidator.js +97 -0
- package/dist/src/security/secureYamlParser.d.ts +46 -0
- package/dist/src/security/secureYamlParser.d.ts.map +1 -0
- package/dist/src/security/secureYamlParser.js +203 -0
- package/dist/src/security/securityMonitor.d.ts +58 -0
- package/dist/src/security/securityMonitor.d.ts.map +1 -0
- package/dist/src/security/securityMonitor.js +108 -0
- package/dist/src/security/tokenManager.d.ts +59 -0
- package/dist/src/security/tokenManager.d.ts.map +1 -0
- package/dist/src/security/tokenManager.js +216 -0
- package/dist/src/security/yamlValidator.d.ts +20 -0
- package/dist/src/security/yamlValidator.d.ts.map +1 -0
- package/dist/src/security/yamlValidator.js +138 -0
- package/dist/src/server/ServerSetup.d.ts +31 -0
- package/dist/src/server/ServerSetup.d.ts.map +1 -0
- package/dist/src/server/ServerSetup.js +79 -0
- package/dist/src/server/index.d.ts +7 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +7 -0
- package/dist/src/server/tools/ConfigTools.d.ts +10 -0
- package/dist/src/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/src/server/tools/ConfigTools.js +63 -0
- package/dist/src/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/src/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/src/server/tools/MarketplaceTools.js +92 -0
- package/dist/src/server/tools/PersonaTools.d.ts +10 -0
- package/dist/src/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/src/server/tools/PersonaTools.js +257 -0
- package/dist/src/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/src/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/src/server/tools/ToolRegistry.js +40 -0
- package/dist/src/server/tools/UpdateTools.d.ts +10 -0
- package/dist/src/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/src/server/tools/UpdateTools.js +64 -0
- package/dist/src/server/tools/UserTools.d.ts +10 -0
- package/dist/src/server/tools/UserTools.d.ts.map +1 -0
- package/dist/src/server/tools/UserTools.js +51 -0
- package/dist/src/server/tools/index.d.ts +10 -0
- package/dist/src/server/tools/index.d.ts.map +1 -0
- package/dist/src/server/tools/index.js +10 -0
- package/dist/src/server/types.d.ts +34 -0
- package/dist/src/server/types.d.ts.map +1 -0
- package/dist/src/server/types.js +5 -0
- package/dist/src/tools/debug.d.ts +20 -0
- package/dist/src/tools/debug.d.ts.map +1 -0
- package/dist/src/tools/debug.js +37 -0
- package/dist/src/types/cache.d.ts +8 -0
- package/dist/src/types/cache.d.ts.map +1 -0
- package/dist/src/types/cache.js +5 -0
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +8 -0
- package/dist/src/types/marketplace.d.ts +23 -0
- package/dist/src/types/marketplace.d.ts.map +1 -0
- package/dist/src/types/marketplace.js +5 -0
- package/dist/src/types/mcp.d.ts +161 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +75 -0
- package/dist/src/types/persona.d.ts +30 -0
- package/dist/src/types/persona.d.ts.map +1 -0
- package/dist/src/types/persona.js +5 -0
- package/dist/src/update/BackupManager.d.ts +46 -0
- package/dist/src/update/BackupManager.d.ts.map +1 -0
- package/dist/src/update/BackupManager.js +261 -0
- package/dist/src/update/DependencyChecker.d.ts +41 -0
- package/dist/src/update/DependencyChecker.d.ts.map +1 -0
- package/dist/src/update/DependencyChecker.js +132 -0
- package/dist/src/update/RateLimiter.d.ts +80 -0
- package/dist/src/update/RateLimiter.d.ts.map +1 -0
- package/dist/src/update/RateLimiter.js +172 -0
- package/dist/src/update/SignatureVerifier.d.ts +71 -0
- package/dist/src/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/src/update/SignatureVerifier.js +214 -0
- package/dist/src/update/UpdateChecker.d.ts +127 -0
- package/dist/src/update/UpdateChecker.d.ts.map +1 -0
- package/dist/src/update/UpdateChecker.js +460 -0
- package/dist/src/update/UpdateManager.d.ts +41 -0
- package/dist/src/update/UpdateManager.d.ts.map +1 -0
- package/dist/src/update/UpdateManager.js +260 -0
- package/dist/src/update/VersionManager.d.ts +31 -0
- package/dist/src/update/VersionManager.d.ts.map +1 -0
- package/dist/src/update/VersionManager.js +134 -0
- package/dist/src/update/index.d.ts +9 -0
- package/dist/src/update/index.d.ts.map +1 -0
- package/dist/src/update/index.js +9 -0
- package/dist/src/utils/filesystem.d.ts +32 -0
- package/dist/src/utils/filesystem.d.ts.map +1 -0
- package/dist/src/utils/filesystem.js +73 -0
- package/dist/src/utils/git.d.ts +32 -0
- package/dist/src/utils/git.d.ts.map +1 -0
- package/dist/src/utils/git.js +65 -0
- package/dist/src/utils/index.d.ts +7 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +7 -0
- package/dist/src/utils/logger.d.ts +45 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +91 -0
- package/dist/src/utils/version.d.ts +25 -0
- package/dist/src/utils/version.d.ts.map +1 -0
- package/dist/src/utils/version.js +97 -0
- package/dist/test/src/cache/APICache.d.ts +23 -0
- package/dist/test/src/cache/APICache.d.ts.map +1 -0
- package/dist/test/src/cache/APICache.js +42 -0
- package/dist/test/src/cache/index.d.ts +5 -0
- package/dist/test/src/cache/index.d.ts.map +1 -0
- package/dist/test/src/cache/index.js +5 -0
- package/dist/test/src/collection/CollectionBrowser.d.ts +24 -0
- package/dist/test/src/collection/CollectionBrowser.d.ts.map +1 -0
- package/dist/test/src/collection/CollectionBrowser.js +115 -0
- package/dist/test/src/collection/CollectionSearch.d.ts +18 -0
- package/dist/test/src/collection/CollectionSearch.d.ts.map +1 -0
- package/dist/test/src/collection/CollectionSearch.js +48 -0
- package/dist/test/src/collection/GitHubClient.d.ts +22 -0
- package/dist/test/src/collection/GitHubClient.d.ts.map +1 -0
- package/dist/test/src/collection/GitHubClient.js +114 -0
- package/dist/test/src/collection/PersonaDetails.d.ts +22 -0
- package/dist/test/src/collection/PersonaDetails.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaDetails.js +71 -0
- package/dist/test/src/collection/PersonaInstaller.d.ts +26 -0
- package/dist/test/src/collection/PersonaInstaller.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaInstaller.js +103 -0
- package/dist/test/src/collection/PersonaSubmitter.d.ts +19 -0
- package/dist/test/src/collection/PersonaSubmitter.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaSubmitter.js +57 -0
- package/dist/test/src/collection/index.d.ts +10 -0
- package/dist/test/src/collection/index.d.ts.map +1 -0
- package/dist/test/src/collection/index.js +10 -0
- package/dist/test/src/config/constants.d.ts +25 -0
- package/dist/test/src/config/constants.d.ts.map +1 -0
- package/dist/test/src/config/constants.js +30 -0
- package/dist/test/src/config/index.d.ts +6 -0
- package/dist/test/src/config/index.d.ts.map +1 -0
- package/dist/test/src/config/index.js +6 -0
- package/dist/test/src/config/indicator-config.d.ts +107 -0
- package/dist/test/src/config/indicator-config.d.ts.map +1 -0
- package/dist/test/src/config/indicator-config.js +158 -0
- package/dist/test/src/constants/defaultPersonas.d.ts +10 -0
- package/dist/test/src/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/test/src/constants/defaultPersonas.js +18 -0
- package/dist/test/src/constants/limits.d.ts +10 -0
- package/dist/test/src/constants/limits.d.ts.map +1 -0
- package/dist/test/src/constants/limits.js +13 -0
- package/dist/test/src/elements/BaseElement.d.ts +81 -0
- package/dist/test/src/elements/BaseElement.d.ts.map +1 -0
- package/dist/test/src/elements/BaseElement.js +381 -0
- package/dist/test/src/elements/FeedbackProcessor.d.ts +57 -0
- package/dist/test/src/elements/FeedbackProcessor.d.ts.map +1 -0
- package/dist/test/src/elements/FeedbackProcessor.js +418 -0
- package/dist/test/src/elements/agents/Agent.d.ts +145 -0
- package/dist/test/src/elements/agents/Agent.d.ts.map +1 -0
- package/dist/test/src/elements/agents/Agent.js +848 -0
- package/dist/test/src/elements/agents/AgentManager.d.ts +125 -0
- package/dist/test/src/elements/agents/AgentManager.d.ts.map +1 -0
- package/dist/test/src/elements/agents/AgentManager.js +608 -0
- package/dist/test/src/elements/agents/constants.d.ts +42 -0
- package/dist/test/src/elements/agents/constants.d.ts.map +1 -0
- package/dist/test/src/elements/agents/constants.js +45 -0
- package/dist/test/src/elements/agents/goalTemplates.d.ts +44 -0
- package/dist/test/src/elements/agents/goalTemplates.d.ts.map +1 -0
- package/dist/test/src/elements/agents/goalTemplates.js +297 -0
- package/dist/test/src/elements/agents/index.d.ts +8 -0
- package/dist/test/src/elements/agents/index.d.ts.map +1 -0
- package/dist/test/src/elements/agents/index.js +8 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.d.ts +76 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.d.ts.map +1 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.js +143 -0
- package/dist/test/src/elements/agents/types.d.ts +97 -0
- package/dist/test/src/elements/agents/types.d.ts.map +1 -0
- package/dist/test/src/elements/agents/types.js +5 -0
- package/dist/test/src/elements/index.d.ts +6 -0
- package/dist/test/src/elements/index.d.ts.map +1 -0
- package/dist/test/src/elements/index.js +6 -0
- package/dist/test/src/elements/memories/Memory.d.ts +110 -0
- package/dist/test/src/elements/memories/Memory.d.ts.map +1 -0
- package/dist/test/src/elements/memories/Memory.js +470 -0
- package/dist/test/src/elements/memories/MemoryManager.d.ts +86 -0
- package/dist/test/src/elements/memories/MemoryManager.d.ts.map +1 -0
- package/dist/test/src/elements/memories/MemoryManager.js +435 -0
- package/dist/test/src/elements/memories/constants.d.ts +42 -0
- package/dist/test/src/elements/memories/constants.d.ts.map +1 -0
- package/dist/test/src/elements/memories/constants.js +49 -0
- package/dist/test/src/elements/memories/index.d.ts +6 -0
- package/dist/test/src/elements/memories/index.d.ts.map +1 -0
- package/dist/test/src/elements/memories/index.js +6 -0
- package/dist/test/src/elements/skills/Skill.d.ts +109 -0
- package/dist/test/src/elements/skills/Skill.d.ts.map +1 -0
- package/dist/test/src/elements/skills/Skill.js +381 -0
- package/dist/test/src/elements/templates/Template.d.ts +138 -0
- package/dist/test/src/elements/templates/Template.d.ts.map +1 -0
- package/dist/test/src/elements/templates/Template.js +673 -0
- package/dist/test/src/elements/templates/TemplateManager.d.ts +104 -0
- package/dist/test/src/elements/templates/TemplateManager.d.ts.map +1 -0
- package/dist/test/src/elements/templates/TemplateManager.js +496 -0
- package/dist/test/src/elements/templates/index.d.ts +6 -0
- package/dist/test/src/elements/templates/index.d.ts.map +1 -0
- package/dist/test/src/elements/templates/index.js +6 -0
- package/dist/test/src/errors/SecurityError.d.ts +29 -0
- package/dist/test/src/errors/SecurityError.d.ts.map +1 -0
- package/dist/test/src/errors/SecurityError.js +47 -0
- package/dist/test/src/errors/index.d.ts +2 -0
- package/dist/test/src/errors/index.d.ts.map +1 -0
- package/dist/test/src/errors/index.js +2 -0
- package/dist/test/src/index.barrel.d.ts +21 -0
- package/dist/test/src/index.barrel.d.ts.map +1 -0
- package/dist/test/src/index.barrel.js +31 -0
- package/dist/test/src/index.d.ts +223 -0
- package/dist/test/src/index.d.ts.map +1 -0
- package/dist/test/src/index.js +1594 -0
- package/dist/test/src/marketplace/GitHubClient.d.ts +22 -0
- package/dist/test/src/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/test/src/marketplace/GitHubClient.js +112 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.d.ts +21 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.js +45 -0
- package/dist/test/src/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/test/src/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/test/src/marketplace/MarketplaceSearch.js +36 -0
- package/dist/test/src/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/test/src/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaDetails.js +71 -0
- package/dist/test/src/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/test/src/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaInstaller.js +100 -0
- package/dist/test/src/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/test/src/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaSubmitter.js +57 -0
- package/dist/test/src/marketplace/index.d.ts +10 -0
- package/dist/test/src/marketplace/index.d.ts.map +1 -0
- package/dist/test/src/marketplace/index.js +10 -0
- package/dist/test/src/persona/PersonaElement.d.ts +64 -0
- package/dist/test/src/persona/PersonaElement.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaElement.js +223 -0
- package/dist/test/src/persona/PersonaElementManager.d.ts +97 -0
- package/dist/test/src/persona/PersonaElementManager.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaElementManager.js +342 -0
- package/dist/test/src/persona/PersonaLoader.d.ts +34 -0
- package/dist/test/src/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaLoader.js +145 -0
- package/dist/test/src/persona/PersonaManager.d.ts +112 -0
- package/dist/test/src/persona/PersonaManager.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaManager.js +341 -0
- package/dist/test/src/persona/PersonaValidator.d.ts +33 -0
- package/dist/test/src/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaValidator.js +157 -0
- package/dist/test/src/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/test/src/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaExporter.js +99 -0
- package/dist/test/src/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/test/src/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaImporter.js +315 -0
- package/dist/test/src/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/test/src/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaSharer.js +502 -0
- package/dist/test/src/persona/export-import/index.d.ts +10 -0
- package/dist/test/src/persona/export-import/index.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/index.js +7 -0
- package/dist/test/src/persona/index.d.ts +7 -0
- package/dist/test/src/persona/index.d.ts.map +1 -0
- package/dist/test/src/persona/index.js +7 -0
- package/dist/test/src/portfolio/MigrationManager.d.ts +44 -0
- package/dist/test/src/portfolio/MigrationManager.d.ts.map +1 -0
- package/dist/test/src/portfolio/MigrationManager.js +163 -0
- package/dist/test/src/portfolio/PortfolioManager.d.ts +54 -0
- package/dist/test/src/portfolio/PortfolioManager.d.ts.map +1 -0
- package/dist/test/src/portfolio/PortfolioManager.js +224 -0
- package/dist/test/src/portfolio/types.d.ts +18 -0
- package/dist/test/src/portfolio/types.d.ts.map +1 -0
- package/dist/test/src/portfolio/types.js +13 -0
- package/dist/test/src/security/InputValidator.d.ts +80 -0
- package/dist/test/src/security/InputValidator.d.ts.map +1 -0
- package/dist/test/src/security/InputValidator.js +436 -0
- package/dist/test/src/security/audit/SecurityAuditor.d.ts +44 -0
- package/dist/test/src/security/audit/SecurityAuditor.d.ts.map +1 -0
- package/dist/test/src/security/audit/SecurityAuditor.js +274 -0
- package/dist/test/src/security/audit/config/suppressions.d.ts +34 -0
- package/dist/test/src/security/audit/config/suppressions.d.ts.map +1 -0
- package/dist/test/src/security/audit/config/suppressions.js +575 -0
- package/dist/test/src/security/audit/index.d.ts +14 -0
- package/dist/test/src/security/audit/index.d.ts.map +1 -0
- package/dist/test/src/security/audit/index.js +15 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts +46 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.js +174 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.d.ts +13 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.js +25 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts +13 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.js +79 -0
- package/dist/test/src/security/audit/rules/SecurityRules.d.ts +20 -0
- package/dist/test/src/security/audit/rules/SecurityRules.d.ts.map +1 -0
- package/dist/test/src/security/audit/rules/SecurityRules.js +244 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.d.ts +47 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.js +174 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts +13 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.js +22 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts +13 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.js +22 -0
- package/dist/test/src/security/audit/types.d.ts +94 -0
- package/dist/test/src/security/audit/types.d.ts.map +1 -0
- package/dist/test/src/security/audit/types.js +6 -0
- package/dist/test/src/security/commandValidator.d.ts +7 -0
- package/dist/test/src/security/commandValidator.d.ts.map +1 -0
- package/dist/test/src/security/commandValidator.js +78 -0
- package/dist/test/src/security/constants.d.ts +24 -0
- package/dist/test/src/security/constants.d.ts.map +1 -0
- package/dist/test/src/security/constants.js +26 -0
- package/dist/test/src/security/contentValidator.d.ts +47 -0
- package/dist/test/src/security/contentValidator.d.ts.map +1 -0
- package/dist/test/src/security/contentValidator.js +301 -0
- package/dist/test/src/security/errors.d.ts +14 -0
- package/dist/test/src/security/errors.d.ts.map +1 -0
- package/dist/test/src/security/errors.js +28 -0
- package/dist/test/src/security/fileLockManager.d.ts +70 -0
- package/dist/test/src/security/fileLockManager.d.ts.map +1 -0
- package/dist/test/src/security/fileLockManager.js +187 -0
- package/dist/test/src/security/index.d.ts +12 -0
- package/dist/test/src/security/index.d.ts.map +1 -0
- package/dist/test/src/security/index.js +14 -0
- package/dist/test/src/security/pathValidator.d.ts +9 -0
- package/dist/test/src/security/pathValidator.d.ts.map +1 -0
- package/dist/test/src/security/pathValidator.js +98 -0
- package/dist/test/src/security/regexValidator.d.ts +59 -0
- package/dist/test/src/security/regexValidator.d.ts.map +1 -0
- package/dist/test/src/security/regexValidator.js +214 -0
- package/dist/test/src/security/secureYamlParser.d.ts +46 -0
- package/dist/test/src/security/secureYamlParser.d.ts.map +1 -0
- package/dist/test/src/security/secureYamlParser.js +203 -0
- package/dist/test/src/security/securityMonitor.d.ts +58 -0
- package/dist/test/src/security/securityMonitor.d.ts.map +1 -0
- package/dist/test/src/security/securityMonitor.js +108 -0
- package/dist/test/src/security/tokenManager.d.ts +85 -0
- package/dist/test/src/security/tokenManager.d.ts.map +1 -0
- package/dist/test/src/security/tokenManager.js +286 -0
- package/dist/test/src/security/validators/unicodeValidator.d.ts +97 -0
- package/dist/test/src/security/validators/unicodeValidator.d.ts.map +1 -0
- package/dist/test/src/security/validators/unicodeValidator.js +312 -0
- package/dist/test/src/security/yamlValidator.d.ts +21 -0
- package/dist/test/src/security/yamlValidator.d.ts.map +1 -0
- package/dist/test/src/security/yamlValidator.js +164 -0
- package/dist/test/src/server/ServerSetup.d.ts +35 -0
- package/dist/test/src/server/ServerSetup.d.ts.map +1 -0
- package/dist/test/src/server/ServerSetup.js +116 -0
- package/dist/test/src/server/index.d.ts +7 -0
- package/dist/test/src/server/index.d.ts.map +1 -0
- package/dist/test/src/server/index.js +7 -0
- package/dist/test/src/server/startup.d.ts +31 -0
- package/dist/test/src/server/startup.d.ts.map +1 -0
- package/dist/test/src/server/startup.js +67 -0
- package/dist/test/src/server/tools/CollectionTools.d.ts +10 -0
- package/dist/test/src/server/tools/CollectionTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/CollectionTools.js +96 -0
- package/dist/test/src/server/tools/ConfigTools.d.ts +10 -0
- package/dist/test/src/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/ConfigTools.js +63 -0
- package/dist/test/src/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/test/src/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/MarketplaceTools.js +92 -0
- package/dist/test/src/server/tools/PersonaTools.d.ts +10 -0
- package/dist/test/src/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/PersonaTools.js +257 -0
- package/dist/test/src/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/test/src/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/test/src/server/tools/ToolRegistry.js +40 -0
- package/dist/test/src/server/tools/UpdateTools.d.ts +10 -0
- package/dist/test/src/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/UpdateTools.js +64 -0
- package/dist/test/src/server/tools/UserTools.d.ts +10 -0
- package/dist/test/src/server/tools/UserTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/UserTools.js +51 -0
- package/dist/test/src/server/tools/index.d.ts +10 -0
- package/dist/test/src/server/tools/index.d.ts.map +1 -0
- package/dist/test/src/server/tools/index.js +10 -0
- package/dist/test/src/server/types.d.ts +34 -0
- package/dist/test/src/server/types.d.ts.map +1 -0
- package/dist/test/src/server/types.js +5 -0
- package/dist/test/src/tools/debug.d.ts +20 -0
- package/dist/test/src/tools/debug.d.ts.map +1 -0
- package/dist/test/src/tools/debug.js +37 -0
- package/dist/test/src/types/cache.d.ts +8 -0
- package/dist/test/src/types/cache.d.ts.map +1 -0
- package/dist/test/src/types/cache.js +5 -0
- package/dist/test/src/types/collection.d.ts +23 -0
- package/dist/test/src/types/collection.d.ts.map +1 -0
- package/dist/test/src/types/collection.js +5 -0
- package/dist/test/src/types/elements/IElement.d.ts +123 -0
- package/dist/test/src/types/elements/IElement.d.ts.map +1 -0
- package/dist/test/src/types/elements/IElement.js +30 -0
- package/dist/test/src/types/elements/IElementManager.d.ts +65 -0
- package/dist/test/src/types/elements/IElementManager.d.ts.map +1 -0
- package/dist/test/src/types/elements/IElementManager.js +6 -0
- package/dist/test/src/types/elements/IRatingManager.d.ts +109 -0
- package/dist/test/src/types/elements/IRatingManager.d.ts.map +1 -0
- package/dist/test/src/types/elements/IRatingManager.js +6 -0
- package/dist/test/src/types/elements/IReferenceResolver.d.ts +52 -0
- package/dist/test/src/types/elements/IReferenceResolver.d.ts.map +1 -0
- package/dist/test/src/types/elements/IReferenceResolver.js +6 -0
- package/dist/test/src/types/elements/RatingBreakdowns.d.ts +49 -0
- package/dist/test/src/types/elements/RatingBreakdowns.d.ts.map +1 -0
- package/dist/test/src/types/elements/RatingBreakdowns.js +6 -0
- package/dist/test/src/types/elements/index.d.ts +9 -0
- package/dist/test/src/types/elements/index.d.ts.map +1 -0
- package/dist/test/src/types/elements/index.js +11 -0
- package/dist/test/src/types/index.d.ts +9 -0
- package/dist/test/src/types/index.d.ts.map +1 -0
- package/dist/test/src/types/index.js +9 -0
- package/dist/test/src/types/marketplace.d.ts +23 -0
- package/dist/test/src/types/marketplace.d.ts.map +1 -0
- package/dist/test/src/types/marketplace.js +5 -0
- package/dist/test/src/types/mcp.d.ts +84 -0
- package/dist/test/src/types/mcp.d.ts.map +1 -0
- package/dist/test/src/types/mcp.js +80 -0
- package/dist/test/src/types/persona.d.ts +30 -0
- package/dist/test/src/types/persona.d.ts.map +1 -0
- package/dist/test/src/types/persona.js +5 -0
- package/dist/test/src/update/BackupManager.d.ts +46 -0
- package/dist/test/src/update/BackupManager.d.ts.map +1 -0
- package/dist/test/src/update/BackupManager.js +261 -0
- package/dist/test/src/update/DependencyChecker.d.ts +41 -0
- package/dist/test/src/update/DependencyChecker.d.ts.map +1 -0
- package/dist/test/src/update/DependencyChecker.js +132 -0
- package/dist/test/src/update/RateLimiter.d.ts +80 -0
- package/dist/test/src/update/RateLimiter.d.ts.map +1 -0
- package/dist/test/src/update/RateLimiter.js +172 -0
- package/dist/test/src/update/SignatureVerifier.d.ts +71 -0
- package/dist/test/src/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/test/src/update/SignatureVerifier.js +214 -0
- package/dist/test/src/update/UpdateChecker.d.ts +127 -0
- package/dist/test/src/update/UpdateChecker.d.ts.map +1 -0
- package/dist/test/src/update/UpdateChecker.js +469 -0
- package/dist/test/src/update/UpdateManager.d.ts +41 -0
- package/dist/test/src/update/UpdateManager.d.ts.map +1 -0
- package/dist/test/src/update/UpdateManager.js +260 -0
- package/dist/test/src/update/VersionManager.d.ts +31 -0
- package/dist/test/src/update/VersionManager.d.ts.map +1 -0
- package/dist/test/src/update/VersionManager.js +134 -0
- package/dist/test/src/update/index.d.ts +9 -0
- package/dist/test/src/update/index.d.ts.map +1 -0
- package/dist/test/src/update/index.js +9 -0
- package/dist/test/src/utils/filesystem.d.ts +29 -0
- package/dist/test/src/utils/filesystem.d.ts.map +1 -0
- package/dist/test/src/utils/filesystem.js +94 -0
- package/dist/test/src/utils/git.d.ts +32 -0
- package/dist/test/src/utils/git.d.ts.map +1 -0
- package/dist/test/src/utils/git.js +65 -0
- package/dist/test/src/utils/index.d.ts +7 -0
- package/dist/test/src/utils/index.d.ts.map +1 -0
- package/dist/test/src/utils/index.js +7 -0
- package/dist/test/src/utils/logger.d.ts +45 -0
- package/dist/test/src/utils/logger.d.ts.map +1 -0
- package/dist/test/src/utils/logger.js +91 -0
- package/dist/test/src/utils/version.d.ts +25 -0
- package/dist/test/src/utils/version.d.ts.map +1 -0
- package/dist/test/src/utils/version.js +97 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts +33 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.js +83 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts +26 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.js +95 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.d.ts +26 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.js +41 -0
- package/dist/test/test/__tests__/integration/setup.d.ts +8 -0
- package/dist/test/test/__tests__/integration/setup.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/setup.js +31 -0
- package/dist/test/test/__tests__/integration/teardown.d.ts +5 -0
- package/dist/test/test/__tests__/integration/teardown.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/teardown.js +23 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts +34 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.js +224 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts +89 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.js +543 -0
- package/dist/test/test/__tests__/security/index.d.ts +46 -0
- package/dist/test/test/__tests__/security/index.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/index.js +98 -0
- package/dist/test/test/__tests__/security/setup.d.ts +3 -0
- package/dist/test/test/__tests__/security/setup.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/setup.js +23 -0
- package/dist/tools/debug.d.ts +20 -0
- package/dist/tools/debug.d.ts.map +1 -0
- package/dist/tools/debug.js +37 -0
- package/dist/types/cache.d.ts +8 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +5 -0
- package/dist/types/collection.d.ts +23 -0
- package/dist/types/collection.d.ts.map +1 -0
- package/dist/types/collection.js +5 -0
- package/dist/types/elements/IElement.d.ts +123 -0
- package/dist/types/elements/IElement.d.ts.map +1 -0
- package/dist/types/elements/IElement.js +30 -0
- package/dist/types/elements/IElementManager.d.ts +65 -0
- package/dist/types/elements/IElementManager.d.ts.map +1 -0
- package/dist/types/elements/IElementManager.js +6 -0
- package/dist/types/elements/IRatingManager.d.ts +109 -0
- package/dist/types/elements/IRatingManager.d.ts.map +1 -0
- package/dist/types/elements/IRatingManager.js +6 -0
- package/dist/types/elements/IReferenceResolver.d.ts +52 -0
- package/dist/types/elements/IReferenceResolver.d.ts.map +1 -0
- package/dist/types/elements/IReferenceResolver.js +6 -0
- package/dist/types/elements/RatingBreakdowns.d.ts +49 -0
- package/dist/types/elements/RatingBreakdowns.d.ts.map +1 -0
- package/dist/types/elements/RatingBreakdowns.js +6 -0
- package/dist/types/elements/index.d.ts +9 -0
- package/dist/types/elements/index.d.ts.map +1 -0
- package/dist/types/elements/index.js +11 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/marketplace.d.ts +23 -0
- package/dist/types/marketplace.d.ts.map +1 -0
- package/dist/types/marketplace.js +5 -0
- package/dist/types/mcp.d.ts +84 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +80 -0
- package/dist/types/persona.d.ts +30 -0
- package/dist/types/persona.d.ts.map +1 -0
- package/dist/types/persona.js +5 -0
- package/dist/update/BackupManager.d.ts +46 -0
- package/dist/update/BackupManager.d.ts.map +1 -0
- package/dist/update/BackupManager.js +261 -0
- package/dist/update/DependencyChecker.d.ts +41 -0
- package/dist/update/DependencyChecker.d.ts.map +1 -0
- package/dist/update/DependencyChecker.js +132 -0
- package/dist/update/RateLimiter.d.ts +80 -0
- package/dist/update/RateLimiter.d.ts.map +1 -0
- package/dist/update/RateLimiter.js +172 -0
- package/dist/update/SignatureVerifier.d.ts +71 -0
- package/dist/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/update/SignatureVerifier.js +214 -0
- package/dist/update/UpdateChecker.d.ts +127 -0
- package/dist/update/UpdateChecker.d.ts.map +1 -0
- package/dist/update/UpdateChecker.js +469 -0
- package/dist/update/UpdateManager.d.ts +41 -0
- package/dist/update/UpdateManager.d.ts.map +1 -0
- package/dist/update/UpdateManager.js +260 -0
- package/dist/update/VersionManager.d.ts +31 -0
- package/dist/update/VersionManager.d.ts.map +1 -0
- package/dist/update/VersionManager.js +134 -0
- package/dist/update/index.d.ts +9 -0
- package/dist/update/index.d.ts.map +1 -0
- package/dist/update/index.js +9 -0
- package/dist/utils/filesystem.d.ts +29 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +94 -0
- package/dist/utils/git.d.ts +32 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +65 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/version.d.ts +25 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +97 -0
- package/package.json +128 -0
|
@@ -0,0 +1,1594 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import * as fs from "fs/promises";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import { loadIndicatorConfig, formatIndicator, validateCustomFormat } from './config/indicator-config.js';
|
|
8
|
+
import { SecureYamlParser } from './security/secureYamlParser.js';
|
|
9
|
+
import { SecurityError } from './errors/SecurityError.js';
|
|
10
|
+
import { APICache } from './cache/APICache.js';
|
|
11
|
+
import { validateFilename, sanitizeInput, validateContentSize, validateUsername, validateCategory, MCPInputValidator } from './security/InputValidator.js';
|
|
12
|
+
import { SECURITY_LIMITS, VALIDATION_PATTERNS } from './security/constants.js';
|
|
13
|
+
import { ContentValidator } from './security/contentValidator.js';
|
|
14
|
+
import { PathValidator } from './security/pathValidator.js';
|
|
15
|
+
import { FileLockManager } from './security/fileLockManager.js';
|
|
16
|
+
import { generateAnonymousId, generateUniqueId, slugify } from './utils/filesystem.js';
|
|
17
|
+
import { PersonaManager } from './persona/PersonaManager.js';
|
|
18
|
+
import { GitHubClient, CollectionBrowser, CollectionSearch, PersonaDetails, PersonaInstaller, PersonaSubmitter } from './collection/index.js';
|
|
19
|
+
import { UpdateManager } from './update/index.js';
|
|
20
|
+
import { ServerSetup } from './server/index.js';
|
|
21
|
+
import { logger } from './utils/logger.js';
|
|
22
|
+
import { PersonaExporter, PersonaImporter, PersonaSharer } from './persona/export-import/index.js';
|
|
23
|
+
import { isDefaultPersona } from './constants/defaultPersonas.js';
|
|
24
|
+
import { PortfolioManager, ElementType } from './portfolio/PortfolioManager.js';
|
|
25
|
+
import { MigrationManager } from './portfolio/MigrationManager.js';
|
|
26
|
+
export class DollhouseMCPServer {
|
|
27
|
+
server;
|
|
28
|
+
personasDir;
|
|
29
|
+
personas = new Map();
|
|
30
|
+
activePersona = null;
|
|
31
|
+
currentUser = null;
|
|
32
|
+
apiCache = new APICache();
|
|
33
|
+
rateLimitTracker = new Map();
|
|
34
|
+
indicatorConfig;
|
|
35
|
+
personaManager;
|
|
36
|
+
githubClient;
|
|
37
|
+
collectionBrowser;
|
|
38
|
+
collectionSearch;
|
|
39
|
+
personaDetails;
|
|
40
|
+
personaInstaller;
|
|
41
|
+
personaSubmitter;
|
|
42
|
+
updateManager;
|
|
43
|
+
serverSetup;
|
|
44
|
+
personaExporter;
|
|
45
|
+
personaImporter;
|
|
46
|
+
personaSharer;
|
|
47
|
+
portfolioManager;
|
|
48
|
+
migrationManager;
|
|
49
|
+
constructor() {
|
|
50
|
+
this.server = new Server({
|
|
51
|
+
name: "dollhousemcp",
|
|
52
|
+
version: "1.0.0",
|
|
53
|
+
}, {
|
|
54
|
+
capabilities: {
|
|
55
|
+
tools: {},
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Initialize portfolio system
|
|
59
|
+
this.portfolioManager = PortfolioManager.getInstance();
|
|
60
|
+
this.migrationManager = new MigrationManager(this.portfolioManager);
|
|
61
|
+
// Use portfolio personas directory
|
|
62
|
+
this.personasDir = this.portfolioManager.getElementDir(ElementType.PERSONA);
|
|
63
|
+
// Log resolved path for debugging
|
|
64
|
+
logger.info(`Personas directory resolved to: ${this.personasDir}`);
|
|
65
|
+
// Initialize PathValidator with the personas directory
|
|
66
|
+
PathValidator.initialize(this.personasDir);
|
|
67
|
+
// Load user identity from environment variables
|
|
68
|
+
this.currentUser = process.env.DOLLHOUSE_USER || null;
|
|
69
|
+
// Load indicator configuration
|
|
70
|
+
this.indicatorConfig = loadIndicatorConfig();
|
|
71
|
+
// Initialize persona manager
|
|
72
|
+
this.personaManager = new PersonaManager(this.personasDir, this.indicatorConfig);
|
|
73
|
+
// Initialize collection modules
|
|
74
|
+
this.githubClient = new GitHubClient(this.apiCache, this.rateLimitTracker);
|
|
75
|
+
this.collectionBrowser = new CollectionBrowser(this.githubClient);
|
|
76
|
+
this.collectionSearch = new CollectionSearch(this.githubClient);
|
|
77
|
+
this.personaDetails = new PersonaDetails(this.githubClient);
|
|
78
|
+
this.personaInstaller = new PersonaInstaller(this.githubClient);
|
|
79
|
+
this.personaSubmitter = new PersonaSubmitter();
|
|
80
|
+
// Initialize update manager
|
|
81
|
+
this.updateManager = new UpdateManager();
|
|
82
|
+
// Initialize export/import/share modules
|
|
83
|
+
this.personaExporter = new PersonaExporter(this.currentUser);
|
|
84
|
+
this.personaImporter = new PersonaImporter(this.personasDir, this.currentUser);
|
|
85
|
+
this.personaSharer = new PersonaSharer(this.githubClient, this.currentUser);
|
|
86
|
+
// Initialize server setup
|
|
87
|
+
this.serverSetup = new ServerSetup();
|
|
88
|
+
this.serverSetup.setupServer(this.server, this);
|
|
89
|
+
// Initialize portfolio and perform migration if needed
|
|
90
|
+
this.initializePortfolio().then(() => {
|
|
91
|
+
this.loadPersonas();
|
|
92
|
+
}).catch(error => {
|
|
93
|
+
logger.error(`Failed to initialize portfolio: ${error}`);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async initializePortfolio() {
|
|
97
|
+
// Check if migration is needed
|
|
98
|
+
const needsMigration = await this.migrationManager.needsMigration();
|
|
99
|
+
if (needsMigration) {
|
|
100
|
+
logger.info('Legacy personas detected. Starting migration...');
|
|
101
|
+
const result = await this.migrationManager.migrate({ backup: true });
|
|
102
|
+
if (result.success) {
|
|
103
|
+
logger.info(`Successfully migrated ${result.migratedCount} personas`);
|
|
104
|
+
if (result.backedUp && result.backupPath) {
|
|
105
|
+
logger.info(`Backup created at: ${result.backupPath}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
logger.error('Migration completed with errors:');
|
|
110
|
+
result.errors.forEach(err => logger.error(` - ${err}`));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Ensure portfolio structure exists
|
|
114
|
+
const portfolioExists = await this.portfolioManager.exists();
|
|
115
|
+
if (!portfolioExists) {
|
|
116
|
+
logger.info('Creating portfolio directory structure...');
|
|
117
|
+
await this.portfolioManager.initialize();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Tool handler methods - now public for access from tool modules
|
|
121
|
+
getPersonaIndicator() {
|
|
122
|
+
if (!this.activePersona) {
|
|
123
|
+
return "";
|
|
124
|
+
}
|
|
125
|
+
const persona = this.personas.get(this.activePersona);
|
|
126
|
+
if (!persona) {
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
return formatIndicator(this.indicatorConfig, {
|
|
130
|
+
name: persona.metadata.name,
|
|
131
|
+
version: persona.metadata.version,
|
|
132
|
+
author: persona.metadata.author,
|
|
133
|
+
category: persona.metadata.category
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async loadPersonas() {
|
|
137
|
+
// Validate the personas directory path
|
|
138
|
+
if (!path.isAbsolute(this.personasDir)) {
|
|
139
|
+
logger.warn(`Personas directory path is not absolute: ${this.personasDir}`);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
await fs.access(this.personasDir);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
// Create personas directory if it doesn't exist
|
|
146
|
+
try {
|
|
147
|
+
await fs.mkdir(this.personasDir, { recursive: true });
|
|
148
|
+
logger.info(`Created personas directory at: ${this.personasDir}`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
catch (mkdirError) {
|
|
152
|
+
logger.error(`Failed to create personas directory at ${this.personasDir}: ${mkdirError.message}`);
|
|
153
|
+
throw new Error(`Cannot create personas directory: ${mkdirError.message}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const files = await fs.readdir(this.personasDir);
|
|
158
|
+
const markdownFiles = files.filter(file => file.endsWith('.md'));
|
|
159
|
+
this.personas.clear();
|
|
160
|
+
for (const file of markdownFiles) {
|
|
161
|
+
try {
|
|
162
|
+
const filePath = path.join(this.personasDir, file);
|
|
163
|
+
const fileContent = await PathValidator.safeReadFile(filePath);
|
|
164
|
+
// Use secure YAML parser
|
|
165
|
+
let parsed;
|
|
166
|
+
try {
|
|
167
|
+
parsed = SecureYamlParser.safeMatter(fileContent);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error instanceof SecurityError) {
|
|
171
|
+
logger.warn(`Security threat detected in persona ${file}: ${error.message}`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
const metadata = parsed.data;
|
|
177
|
+
const content = parsed.content;
|
|
178
|
+
if (!metadata.name) {
|
|
179
|
+
metadata.name = path.basename(file, '.md');
|
|
180
|
+
}
|
|
181
|
+
// Generate unique ID if not present
|
|
182
|
+
let uniqueId = metadata.unique_id;
|
|
183
|
+
if (!uniqueId) {
|
|
184
|
+
const authorForId = metadata.author || this.getCurrentUserForAttribution();
|
|
185
|
+
uniqueId = generateUniqueId(metadata.name, authorForId);
|
|
186
|
+
logger.debug(`Generated unique ID for ${metadata.name}: ${uniqueId}`);
|
|
187
|
+
}
|
|
188
|
+
// Set default values for new metadata fields
|
|
189
|
+
if (!metadata.category)
|
|
190
|
+
metadata.category = 'general';
|
|
191
|
+
if (!metadata.age_rating)
|
|
192
|
+
metadata.age_rating = 'all';
|
|
193
|
+
if (!metadata.content_flags)
|
|
194
|
+
metadata.content_flags = [];
|
|
195
|
+
if (metadata.ai_generated === undefined)
|
|
196
|
+
metadata.ai_generated = false;
|
|
197
|
+
if (!metadata.generation_method)
|
|
198
|
+
metadata.generation_method = 'human';
|
|
199
|
+
if (!metadata.price)
|
|
200
|
+
metadata.price = 'free';
|
|
201
|
+
if (!metadata.license)
|
|
202
|
+
metadata.license = 'CC-BY-SA-4.0';
|
|
203
|
+
const persona = {
|
|
204
|
+
metadata,
|
|
205
|
+
content,
|
|
206
|
+
filename: file,
|
|
207
|
+
unique_id: uniqueId,
|
|
208
|
+
};
|
|
209
|
+
this.personas.set(file, persona);
|
|
210
|
+
logger.debug(`Loaded persona: ${metadata.name} (${uniqueId}`);
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
logger.error(`Error loading persona ${file}: ${error}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
logger.error(`Error reading personas directory: ${error}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async listPersonas() {
|
|
222
|
+
const personaList = Array.from(this.personas.values()).map(persona => ({
|
|
223
|
+
filename: persona.filename,
|
|
224
|
+
unique_id: persona.unique_id,
|
|
225
|
+
name: persona.metadata.name,
|
|
226
|
+
description: persona.metadata.description,
|
|
227
|
+
triggers: persona.metadata.triggers || [],
|
|
228
|
+
version: persona.metadata.version || "1.0",
|
|
229
|
+
author: persona.metadata.author || "Unknown",
|
|
230
|
+
category: persona.metadata.category || 'general',
|
|
231
|
+
age_rating: persona.metadata.age_rating || 'all',
|
|
232
|
+
price: persona.metadata.price || 'free',
|
|
233
|
+
ai_generated: persona.metadata.ai_generated || false,
|
|
234
|
+
active: this.activePersona === persona.filename,
|
|
235
|
+
}));
|
|
236
|
+
return {
|
|
237
|
+
content: [
|
|
238
|
+
{
|
|
239
|
+
type: "text",
|
|
240
|
+
text: `${this.getPersonaIndicator()}Available Personas (${personaList.length}):\n\n` +
|
|
241
|
+
personaList.map(p => `${p.active ? '🔹 ' : '▫️ '}**${p.name}** (${p.unique_id})\n` +
|
|
242
|
+
` ${p.description}\n` +
|
|
243
|
+
` 📁 ${p.category} | 🎭 ${p.author} | 🔖 ${p.price} | ${p.ai_generated ? '🤖 AI' : '👤 Human'}\n` +
|
|
244
|
+
` Age: ${p.age_rating} | Version: ${p.version}\n` +
|
|
245
|
+
` Triggers: ${p.triggers.join(', ') || 'None'}\n`).join('\n'),
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
async activatePersona(personaIdentifier) {
|
|
251
|
+
// Enhanced input validation for persona identifier
|
|
252
|
+
const validatedIdentifier = MCPInputValidator.validatePersonaIdentifier(personaIdentifier);
|
|
253
|
+
// Try to find persona by filename first, then by name
|
|
254
|
+
let persona = this.personas.get(validatedIdentifier);
|
|
255
|
+
if (!persona) {
|
|
256
|
+
// Search by name
|
|
257
|
+
persona = Array.from(this.personas.values()).find(p => p.metadata.name.toLowerCase() === validatedIdentifier.toLowerCase());
|
|
258
|
+
}
|
|
259
|
+
if (!persona) {
|
|
260
|
+
throw new McpError(ErrorCode.InvalidParams, `Persona not found: ${personaIdentifier}`);
|
|
261
|
+
}
|
|
262
|
+
this.activePersona = persona.filename;
|
|
263
|
+
return {
|
|
264
|
+
content: [
|
|
265
|
+
{
|
|
266
|
+
type: "text",
|
|
267
|
+
text: `${this.getPersonaIndicator()}Persona Activated: **${persona.metadata.name}**\n\n` +
|
|
268
|
+
`${persona.metadata.description}\n\n` +
|
|
269
|
+
`**Instructions:**\n${persona.content}`,
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
async getActivePersona() {
|
|
275
|
+
if (!this.activePersona) {
|
|
276
|
+
return {
|
|
277
|
+
content: [
|
|
278
|
+
{
|
|
279
|
+
type: "text",
|
|
280
|
+
text: `${this.getPersonaIndicator()}No persona is currently active.`,
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
const persona = this.personas.get(this.activePersona);
|
|
286
|
+
if (!persona) {
|
|
287
|
+
this.activePersona = null;
|
|
288
|
+
return {
|
|
289
|
+
content: [
|
|
290
|
+
{
|
|
291
|
+
type: "text",
|
|
292
|
+
text: `${this.getPersonaIndicator()}Active persona not found. Deactivated.`,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
content: [
|
|
299
|
+
{
|
|
300
|
+
type: "text",
|
|
301
|
+
text: `${this.getPersonaIndicator()}Active Persona: **${persona.metadata.name}**\n\n` +
|
|
302
|
+
`${persona.metadata.description}\n\n` +
|
|
303
|
+
`File: ${persona.filename}\n` +
|
|
304
|
+
`Version: ${persona.metadata.version || '1.0'}\n` +
|
|
305
|
+
`Author: ${persona.metadata.author || 'Unknown'}`,
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
async deactivatePersona() {
|
|
311
|
+
const wasActive = this.activePersona !== null;
|
|
312
|
+
const indicator = this.getPersonaIndicator();
|
|
313
|
+
this.activePersona = null;
|
|
314
|
+
return {
|
|
315
|
+
content: [
|
|
316
|
+
{
|
|
317
|
+
type: "text",
|
|
318
|
+
text: wasActive
|
|
319
|
+
? `${indicator}✅ Persona deactivated. Back to default mode.`
|
|
320
|
+
: "No persona was active.",
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
async getPersonaDetails(personaIdentifier) {
|
|
326
|
+
// Try to find persona by filename first, then by name
|
|
327
|
+
let persona = this.personas.get(personaIdentifier);
|
|
328
|
+
if (!persona) {
|
|
329
|
+
// Search by name
|
|
330
|
+
persona = Array.from(this.personas.values()).find(p => p.metadata.name.toLowerCase() === personaIdentifier.toLowerCase());
|
|
331
|
+
}
|
|
332
|
+
if (!persona) {
|
|
333
|
+
throw new McpError(ErrorCode.InvalidParams, `Persona not found: ${personaIdentifier}`);
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
content: [
|
|
337
|
+
{
|
|
338
|
+
type: "text",
|
|
339
|
+
text: `${this.getPersonaIndicator()}📋 **${persona.metadata.name}** Details\n\n` +
|
|
340
|
+
`**Description:** ${persona.metadata.description}\n` +
|
|
341
|
+
`**File:** ${persona.filename}\n` +
|
|
342
|
+
`**Version:** ${persona.metadata.version || '1.0'}\n` +
|
|
343
|
+
`**Author:** ${persona.metadata.author || 'Unknown'}\n` +
|
|
344
|
+
`**Triggers:** ${persona.metadata.triggers?.join(', ') || 'None'}\n\n` +
|
|
345
|
+
`**Full Content:**\n\`\`\`\n${persona.content}\n\`\`\``,
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
async reloadPersonas() {
|
|
351
|
+
await this.loadPersonas();
|
|
352
|
+
return {
|
|
353
|
+
content: [
|
|
354
|
+
{
|
|
355
|
+
type: "text",
|
|
356
|
+
text: `${this.getPersonaIndicator()}🔄 Reloaded ${this.personas.size} personas from ${this.personasDir}`,
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
// checkRateLimit and fetchFromGitHub are now handled by GitHubClient
|
|
362
|
+
async browseCollection(section, category) {
|
|
363
|
+
try {
|
|
364
|
+
// Enhanced input validation for section and category
|
|
365
|
+
const validatedSection = section ? validateCategory(section) : undefined;
|
|
366
|
+
const validatedCategory = category ? validateCategory(category) : undefined;
|
|
367
|
+
const result = await this.collectionBrowser.browseCollection(validatedSection, validatedCategory);
|
|
368
|
+
// Handle sections view
|
|
369
|
+
const items = result.items;
|
|
370
|
+
const categories = result.sections || result.categories;
|
|
371
|
+
const text = this.collectionBrowser.formatBrowseResults(items, categories, validatedSection, validatedCategory, this.getPersonaIndicator());
|
|
372
|
+
return {
|
|
373
|
+
content: [
|
|
374
|
+
{
|
|
375
|
+
type: "text",
|
|
376
|
+
text: text,
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
return {
|
|
383
|
+
content: [
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
text: `${this.getPersonaIndicator()}❌ Error browsing collection: ${error}`,
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async searchCollection(query) {
|
|
393
|
+
try {
|
|
394
|
+
// Enhanced input validation for search query
|
|
395
|
+
const validatedQuery = MCPInputValidator.validateSearchQuery(query);
|
|
396
|
+
const items = await this.collectionSearch.searchCollection(validatedQuery);
|
|
397
|
+
const text = this.collectionSearch.formatSearchResults(items, validatedQuery, this.getPersonaIndicator());
|
|
398
|
+
return {
|
|
399
|
+
content: [
|
|
400
|
+
{
|
|
401
|
+
type: "text",
|
|
402
|
+
text: text,
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
return {
|
|
409
|
+
content: [
|
|
410
|
+
{
|
|
411
|
+
type: "text",
|
|
412
|
+
text: `${this.getPersonaIndicator()}❌ Error searching collection: ${error}`,
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
async getCollectionContent(path) {
|
|
419
|
+
try {
|
|
420
|
+
const { metadata, content } = await this.personaDetails.getCollectionContent(path);
|
|
421
|
+
const text = this.personaDetails.formatPersonaDetails(metadata, content, path, this.getPersonaIndicator());
|
|
422
|
+
return {
|
|
423
|
+
content: [
|
|
424
|
+
{
|
|
425
|
+
type: "text",
|
|
426
|
+
text: text,
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
return {
|
|
433
|
+
content: [
|
|
434
|
+
{
|
|
435
|
+
type: "text",
|
|
436
|
+
text: `${this.getPersonaIndicator()}❌ Error fetching content: ${error}`,
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async installContent(inputPath) {
|
|
443
|
+
try {
|
|
444
|
+
const result = await this.personaInstaller.installContent(inputPath);
|
|
445
|
+
if (!result.success) {
|
|
446
|
+
return {
|
|
447
|
+
content: [
|
|
448
|
+
{
|
|
449
|
+
type: "text",
|
|
450
|
+
text: `${this.getPersonaIndicator()}⚠️ ${result.message}`,
|
|
451
|
+
},
|
|
452
|
+
],
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
// Reload personas to include the new one
|
|
456
|
+
await this.loadPersonas();
|
|
457
|
+
const text = this.personaInstaller.formatInstallSuccess(result.metadata, result.filename, this.personas.size, this.getPersonaIndicator());
|
|
458
|
+
return {
|
|
459
|
+
content: [
|
|
460
|
+
{
|
|
461
|
+
type: "text",
|
|
462
|
+
text: text,
|
|
463
|
+
},
|
|
464
|
+
],
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
return {
|
|
469
|
+
content: [
|
|
470
|
+
{
|
|
471
|
+
type: "text",
|
|
472
|
+
text: `${this.getPersonaIndicator()}❌ Error installing persona: ${error}`,
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
async submitContent(contentIdentifier) {
|
|
479
|
+
// Find the content in local collection
|
|
480
|
+
let persona = this.personas.get(contentIdentifier);
|
|
481
|
+
if (!persona) {
|
|
482
|
+
// Search by name
|
|
483
|
+
persona = Array.from(this.personas.values()).find(p => p.metadata.name.toLowerCase() === contentIdentifier.toLowerCase());
|
|
484
|
+
}
|
|
485
|
+
if (!persona) {
|
|
486
|
+
return {
|
|
487
|
+
content: [
|
|
488
|
+
{
|
|
489
|
+
type: "text",
|
|
490
|
+
text: `${this.getPersonaIndicator()}❌ Content not found: ${contentIdentifier}`,
|
|
491
|
+
},
|
|
492
|
+
],
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
// Validate persona content before submission
|
|
496
|
+
try {
|
|
497
|
+
// Read the full persona file content
|
|
498
|
+
const fullPath = path.join(this.personasDir, persona.filename);
|
|
499
|
+
const fileContent = await PathValidator.safeReadFile(fullPath);
|
|
500
|
+
// Validate content for security threats
|
|
501
|
+
const contentValidation = ContentValidator.validateAndSanitize(fileContent);
|
|
502
|
+
if (!contentValidation.isValid && contentValidation.severity === 'critical') {
|
|
503
|
+
return {
|
|
504
|
+
content: [
|
|
505
|
+
{
|
|
506
|
+
type: "text",
|
|
507
|
+
text: `${this.getPersonaIndicator()}❌ **Security Validation Failed**\n\n` +
|
|
508
|
+
`This persona contains content that could be used for prompt injection attacks:\n` +
|
|
509
|
+
`• ${contentValidation.detectedPatterns?.join('\n• ')}\n\n` +
|
|
510
|
+
`Please remove these patterns before submitting to the collection.`,
|
|
511
|
+
},
|
|
512
|
+
],
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
// Validate metadata
|
|
516
|
+
const metadataValidation = ContentValidator.validateMetadata(persona.metadata);
|
|
517
|
+
if (!metadataValidation.isValid) {
|
|
518
|
+
return {
|
|
519
|
+
content: [
|
|
520
|
+
{
|
|
521
|
+
type: "text",
|
|
522
|
+
text: `${this.getPersonaIndicator()}⚠️ **Metadata Security Warning**\n\n` +
|
|
523
|
+
`The persona metadata contains potentially problematic content:\n` +
|
|
524
|
+
`• ${metadataValidation.detectedPatterns?.join('\n• ')}\n\n` +
|
|
525
|
+
`Please fix these issues before submitting.`,
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
return {
|
|
533
|
+
content: [
|
|
534
|
+
{
|
|
535
|
+
type: "text",
|
|
536
|
+
text: `${this.getPersonaIndicator()}❌ Error validating persona: ${error}`,
|
|
537
|
+
},
|
|
538
|
+
],
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
const { githubIssueUrl } = this.personaSubmitter.generateSubmissionIssue(persona);
|
|
542
|
+
const text = this.personaSubmitter.formatSubmissionResponse(persona, githubIssueUrl, this.getPersonaIndicator());
|
|
543
|
+
return {
|
|
544
|
+
content: [
|
|
545
|
+
{
|
|
546
|
+
type: "text",
|
|
547
|
+
text: text,
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
// User identity management
|
|
553
|
+
async setUserIdentity(username, email) {
|
|
554
|
+
try {
|
|
555
|
+
if (!username || username.trim().length === 0) {
|
|
556
|
+
return {
|
|
557
|
+
content: [
|
|
558
|
+
{
|
|
559
|
+
type: "text",
|
|
560
|
+
text: `${this.getPersonaIndicator()}❌ Username cannot be empty`,
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
// Validate and sanitize username
|
|
566
|
+
const validatedUsername = validateUsername(username);
|
|
567
|
+
// Validate email if provided
|
|
568
|
+
let validatedEmail;
|
|
569
|
+
if (email) {
|
|
570
|
+
const sanitizedEmail = sanitizeInput(email, 100);
|
|
571
|
+
if (!VALIDATION_PATTERNS.SAFE_EMAIL.test(sanitizedEmail)) {
|
|
572
|
+
throw new Error('Invalid email format');
|
|
573
|
+
}
|
|
574
|
+
validatedEmail = sanitizedEmail;
|
|
575
|
+
}
|
|
576
|
+
// Set the validated user identity
|
|
577
|
+
this.currentUser = validatedUsername;
|
|
578
|
+
if (validatedEmail) {
|
|
579
|
+
process.env.DOLLHOUSE_EMAIL = validatedEmail;
|
|
580
|
+
}
|
|
581
|
+
return {
|
|
582
|
+
content: [
|
|
583
|
+
{
|
|
584
|
+
type: "text",
|
|
585
|
+
text: `${this.getPersonaIndicator()}✅ **User Identity Set**\n\n` +
|
|
586
|
+
`👤 **Username:** ${validatedUsername}\n` +
|
|
587
|
+
`${validatedEmail ? `📧 **Email:** ${validatedEmail}\n` : ''}` +
|
|
588
|
+
`\n🎯 **Next Steps:**\n` +
|
|
589
|
+
`• New personas you create will be attributed to "${validatedUsername}"\n` +
|
|
590
|
+
`• Set environment variable \`DOLLHOUSE_USER=${validatedUsername}\` to persist this setting\n` +
|
|
591
|
+
`${validatedEmail ? `• Set environment variable \`DOLLHOUSE_EMAIL=${validatedEmail}\` for contact info\n` : ''}` +
|
|
592
|
+
`• Use \`clear_user_identity\` to return to anonymous mode`,
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
return {
|
|
599
|
+
content: [
|
|
600
|
+
{
|
|
601
|
+
type: "text",
|
|
602
|
+
text: `${this.getPersonaIndicator()}❌ **Validation Error**\n\n` +
|
|
603
|
+
`${error}\n\n` +
|
|
604
|
+
`Please provide a valid username (alphanumeric characters, hyphens, underscores, dots only).`,
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async getUserIdentity() {
|
|
611
|
+
const email = process.env.DOLLHOUSE_EMAIL;
|
|
612
|
+
if (!this.currentUser) {
|
|
613
|
+
return {
|
|
614
|
+
content: [
|
|
615
|
+
{
|
|
616
|
+
type: "text",
|
|
617
|
+
text: `${this.getPersonaIndicator()}👤 **User Identity: Anonymous**\n\n` +
|
|
618
|
+
`🔒 **Status:** Anonymous mode\n` +
|
|
619
|
+
`📝 **Attribution:** Personas will use anonymous IDs\n\n` +
|
|
620
|
+
`**To set your identity:**\n` +
|
|
621
|
+
`• Use: \`set_user_identity "your-username"\`\n` +
|
|
622
|
+
`• Or set environment variable: \`DOLLHOUSE_USER=your-username\``,
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
content: [
|
|
629
|
+
{
|
|
630
|
+
type: "text",
|
|
631
|
+
text: `${this.getPersonaIndicator()}👤 **User Identity: ${this.currentUser}**\n\n` +
|
|
632
|
+
`✅ **Status:** Authenticated\n` +
|
|
633
|
+
`👤 **Username:** ${this.currentUser}\n` +
|
|
634
|
+
`${email ? `📧 **Email:** ${email}\n` : ''}` +
|
|
635
|
+
`📝 **Attribution:** New personas will be credited to "${this.currentUser}"\n\n` +
|
|
636
|
+
`**Environment Variables:**\n` +
|
|
637
|
+
`• \`DOLLHOUSE_USER=${this.currentUser}\`\n` +
|
|
638
|
+
`${email ? `• \`DOLLHOUSE_EMAIL=${email}\`\n` : ''}` +
|
|
639
|
+
`\n**Management:**\n` +
|
|
640
|
+
`• Use \`clear_user_identity\` to return to anonymous mode\n` +
|
|
641
|
+
`• Use \`set_user_identity "new-username"\` to change username`,
|
|
642
|
+
},
|
|
643
|
+
],
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
async clearUserIdentity() {
|
|
647
|
+
const wasSet = this.currentUser !== null;
|
|
648
|
+
const previousUser = this.currentUser;
|
|
649
|
+
this.currentUser = null;
|
|
650
|
+
return {
|
|
651
|
+
content: [
|
|
652
|
+
{
|
|
653
|
+
type: "text",
|
|
654
|
+
text: wasSet
|
|
655
|
+
? `${this.getPersonaIndicator()}✅ **User Identity Cleared**\n\n` +
|
|
656
|
+
`👤 **Previous:** ${previousUser}\n` +
|
|
657
|
+
`🔒 **Current:** Anonymous mode\n\n` +
|
|
658
|
+
`📝 **Effect:** New personas will use anonymous IDs\n\n` +
|
|
659
|
+
`⚠️ **Note:** This only affects the current session.\n` +
|
|
660
|
+
`To persist this change, unset the \`DOLLHOUSE_USER\` environment variable.`
|
|
661
|
+
: `${this.getPersonaIndicator()}ℹ️ **Already in Anonymous Mode**\n\n` +
|
|
662
|
+
`👤 No user identity was set.\n\n` +
|
|
663
|
+
`Use \`set_user_identity "username"\` to set your identity.`,
|
|
664
|
+
},
|
|
665
|
+
],
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
getCurrentUserForAttribution() {
|
|
669
|
+
return this.currentUser || generateAnonymousId();
|
|
670
|
+
}
|
|
671
|
+
// Chat-based persona management tools
|
|
672
|
+
async createPersona(name, description, category, instructions, triggers) {
|
|
673
|
+
try {
|
|
674
|
+
// Validate required fields
|
|
675
|
+
if (!name || !description || !category || !instructions) {
|
|
676
|
+
return {
|
|
677
|
+
content: [
|
|
678
|
+
{
|
|
679
|
+
type: "text",
|
|
680
|
+
text: `${this.getPersonaIndicator()}❌ **Missing Required Fields**\n\n` +
|
|
681
|
+
`Please provide all required fields:\n` +
|
|
682
|
+
`• **name**: Display name for the persona\n` +
|
|
683
|
+
`• **description**: Brief description of what it does\n` +
|
|
684
|
+
`• **category**: creative, professional, educational, gaming, or personal\n` +
|
|
685
|
+
`• **instructions**: The persona's behavioral guidelines\n\n` +
|
|
686
|
+
`**Optional:**\n` +
|
|
687
|
+
`• **triggers**: Comma-separated keywords for activation`,
|
|
688
|
+
},
|
|
689
|
+
],
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
// Sanitize and validate inputs
|
|
693
|
+
const sanitizedName = sanitizeInput(name, 100);
|
|
694
|
+
const sanitizedDescription = sanitizeInput(description, 500);
|
|
695
|
+
const sanitizedInstructions = sanitizeInput(instructions);
|
|
696
|
+
const sanitizedTriggers = triggers ? sanitizeInput(triggers, 200) : '';
|
|
697
|
+
// Validate name length and format
|
|
698
|
+
if (sanitizedName.length < 2) {
|
|
699
|
+
throw new Error('Persona name must be at least 2 characters long');
|
|
700
|
+
}
|
|
701
|
+
// Validate category
|
|
702
|
+
const validatedCategory = validateCategory(category);
|
|
703
|
+
// Validate content sizes
|
|
704
|
+
validateContentSize(sanitizedInstructions, SECURITY_LIMITS.MAX_CONTENT_LENGTH);
|
|
705
|
+
validateContentSize(sanitizedDescription, 2000); // 2KB max for description
|
|
706
|
+
// Validate content for security threats
|
|
707
|
+
const nameValidation = ContentValidator.validateAndSanitize(sanitizedName);
|
|
708
|
+
if (!nameValidation.isValid) {
|
|
709
|
+
throw new Error(`Name contains prohibited content: ${nameValidation.detectedPatterns?.join(', ')}`);
|
|
710
|
+
}
|
|
711
|
+
const descValidation = ContentValidator.validateAndSanitize(sanitizedDescription);
|
|
712
|
+
if (!descValidation.isValid) {
|
|
713
|
+
throw new Error(`Description contains prohibited content: ${descValidation.detectedPatterns?.join(', ')}`);
|
|
714
|
+
}
|
|
715
|
+
const instructionsValidation = ContentValidator.validateAndSanitize(sanitizedInstructions);
|
|
716
|
+
if (!instructionsValidation.isValid && instructionsValidation.severity === 'critical') {
|
|
717
|
+
throw new Error(`Instructions contain security threats: ${instructionsValidation.detectedPatterns?.join(', ')}`);
|
|
718
|
+
}
|
|
719
|
+
// Generate metadata
|
|
720
|
+
const author = this.getCurrentUserForAttribution();
|
|
721
|
+
const uniqueId = generateUniqueId(sanitizedName, this.currentUser || undefined);
|
|
722
|
+
const filename = validateFilename(`${slugify(sanitizedName)}.md`);
|
|
723
|
+
const filePath = path.join(this.personasDir, filename);
|
|
724
|
+
// Check if file already exists
|
|
725
|
+
try {
|
|
726
|
+
await PathValidator.validatePersonaPath(filePath);
|
|
727
|
+
await fs.access(filePath);
|
|
728
|
+
return {
|
|
729
|
+
content: [
|
|
730
|
+
{
|
|
731
|
+
type: "text",
|
|
732
|
+
text: `${this.getPersonaIndicator()}⚠️ **Persona Already Exists**\n\n` +
|
|
733
|
+
`A persona file named "${filename}" already exists.\n` +
|
|
734
|
+
`Use \`edit_persona\` to modify it, or choose a different name.`,
|
|
735
|
+
},
|
|
736
|
+
],
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
catch {
|
|
740
|
+
// File doesn't exist, proceed with creation
|
|
741
|
+
}
|
|
742
|
+
// Parse and sanitize triggers
|
|
743
|
+
const triggerList = sanitizedTriggers ?
|
|
744
|
+
sanitizedTriggers.split(',').map(t => sanitizeInput(t.trim(), 50)).filter(t => t.length > 0) :
|
|
745
|
+
[];
|
|
746
|
+
// Create persona metadata with sanitized values
|
|
747
|
+
const metadata = {
|
|
748
|
+
name: sanitizedName,
|
|
749
|
+
description: sanitizedDescription,
|
|
750
|
+
unique_id: uniqueId,
|
|
751
|
+
author,
|
|
752
|
+
triggers: triggerList,
|
|
753
|
+
version: "1.0",
|
|
754
|
+
category: validatedCategory,
|
|
755
|
+
age_rating: "all",
|
|
756
|
+
content_flags: ["user-created"],
|
|
757
|
+
ai_generated: true,
|
|
758
|
+
generation_method: "Claude",
|
|
759
|
+
price: "free",
|
|
760
|
+
revenue_split: "80/20",
|
|
761
|
+
license: "CC-BY-SA-4.0",
|
|
762
|
+
created_date: new Date().toISOString().slice(0, 10)
|
|
763
|
+
};
|
|
764
|
+
// Create full persona content with sanitized values
|
|
765
|
+
const frontmatter = Object.entries(metadata)
|
|
766
|
+
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
767
|
+
.join('\n');
|
|
768
|
+
const personaContent = `---
|
|
769
|
+
${frontmatter}
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
# ${sanitizedName}
|
|
773
|
+
|
|
774
|
+
${sanitizedInstructions}
|
|
775
|
+
|
|
776
|
+
## Response Style
|
|
777
|
+
- Follow the behavioral guidelines above
|
|
778
|
+
- Maintain consistency with the persona's character
|
|
779
|
+
- Adapt responses to match the intended purpose
|
|
780
|
+
|
|
781
|
+
## Usage Notes
|
|
782
|
+
- Created via DollhouseMCP chat interface
|
|
783
|
+
- Author: ${author}
|
|
784
|
+
- Version: 1.0`;
|
|
785
|
+
// Validate final content size
|
|
786
|
+
validateContentSize(personaContent, SECURITY_LIMITS.MAX_PERSONA_SIZE_BYTES);
|
|
787
|
+
try {
|
|
788
|
+
// Use file locking to prevent race conditions
|
|
789
|
+
await FileLockManager.withLock(`persona:${sanitizedName}`, async () => {
|
|
790
|
+
// Double-check file doesn't exist (in case of race condition)
|
|
791
|
+
try {
|
|
792
|
+
await fs.access(filePath);
|
|
793
|
+
throw new Error(`Persona file "${filename}" already exists`);
|
|
794
|
+
}
|
|
795
|
+
catch (error) {
|
|
796
|
+
// If error is not ENOENT (file not found), re-throw it
|
|
797
|
+
if (error.code !== 'ENOENT' && error.message?.includes('already exists')) {
|
|
798
|
+
throw error;
|
|
799
|
+
}
|
|
800
|
+
// File doesn't exist, proceed
|
|
801
|
+
}
|
|
802
|
+
// Write the file atomically
|
|
803
|
+
await FileLockManager.atomicWriteFile(filePath, personaContent);
|
|
804
|
+
});
|
|
805
|
+
// Reload personas to include the new one
|
|
806
|
+
await this.loadPersonas();
|
|
807
|
+
return {
|
|
808
|
+
content: [
|
|
809
|
+
{
|
|
810
|
+
type: "text",
|
|
811
|
+
text: `${this.getPersonaIndicator()}✅ **Persona Created Successfully!**\n\n` +
|
|
812
|
+
`🎭 **${sanitizedName}** by ${author}\n` +
|
|
813
|
+
`📁 Category: ${category}\n` +
|
|
814
|
+
`🆔 Unique ID: ${uniqueId}\n` +
|
|
815
|
+
`📄 Saved as: ${filename}\n` +
|
|
816
|
+
`📊 Total personas: ${this.personas.size}\n\n` +
|
|
817
|
+
`🎯 **Ready to use:** \`activate_persona "${sanitizedName}"\`\n` +
|
|
818
|
+
`📤 **Share it:** \`submit_content "${sanitizedName}"\`\n` +
|
|
819
|
+
`✏️ **Edit it:** \`edit_persona "${sanitizedName}" "field" "new value"\``,
|
|
820
|
+
},
|
|
821
|
+
],
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
catch (error) {
|
|
825
|
+
return {
|
|
826
|
+
content: [
|
|
827
|
+
{
|
|
828
|
+
type: "text",
|
|
829
|
+
text: `${this.getPersonaIndicator()}❌ **Error Creating Persona**\n\n` +
|
|
830
|
+
`Failed to write persona file: ${error}\n\n` +
|
|
831
|
+
`Please check permissions and try again.`,
|
|
832
|
+
},
|
|
833
|
+
],
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
catch (error) {
|
|
838
|
+
return {
|
|
839
|
+
content: [
|
|
840
|
+
{
|
|
841
|
+
type: "text",
|
|
842
|
+
text: `${this.getPersonaIndicator()}❌ **Validation Error**\n\n` +
|
|
843
|
+
`${error}\n\n` +
|
|
844
|
+
`Please fix the issue and try again.`,
|
|
845
|
+
},
|
|
846
|
+
],
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
async editPersona(personaIdentifier, field, value) {
|
|
851
|
+
if (!personaIdentifier || !field || !value) {
|
|
852
|
+
return {
|
|
853
|
+
content: [
|
|
854
|
+
{
|
|
855
|
+
type: "text",
|
|
856
|
+
text: `${this.getPersonaIndicator()}❌ **Missing Parameters**\n\n` +
|
|
857
|
+
`Usage: \`edit_persona "persona_name" "field" "new_value"\`\n\n` +
|
|
858
|
+
`**Editable fields:**\n` +
|
|
859
|
+
`• **name** - Display name\n` +
|
|
860
|
+
`• **description** - Brief description\n` +
|
|
861
|
+
`• **category** - creative, professional, educational, gaming, personal\n` +
|
|
862
|
+
`• **instructions** - Main persona content\n` +
|
|
863
|
+
`• **triggers** - Comma-separated keywords\n` +
|
|
864
|
+
`• **version** - Version number`,
|
|
865
|
+
},
|
|
866
|
+
],
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
// Find the persona
|
|
870
|
+
let persona = this.personas.get(personaIdentifier);
|
|
871
|
+
if (!persona) {
|
|
872
|
+
// Search by name
|
|
873
|
+
persona = Array.from(this.personas.values()).find(p => p.metadata.name.toLowerCase() === personaIdentifier.toLowerCase());
|
|
874
|
+
}
|
|
875
|
+
if (!persona) {
|
|
876
|
+
return {
|
|
877
|
+
content: [
|
|
878
|
+
{
|
|
879
|
+
type: "text",
|
|
880
|
+
text: `${this.getPersonaIndicator()}❌ **Persona Not Found**\n\n` +
|
|
881
|
+
`Could not find persona: "${personaIdentifier}"\n\n` +
|
|
882
|
+
`Use \`list_personas\` to see available personas.`,
|
|
883
|
+
},
|
|
884
|
+
],
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
const validFields = ['name', 'description', 'category', 'instructions', 'triggers', 'version'];
|
|
888
|
+
if (!validFields.includes(field.toLowerCase())) {
|
|
889
|
+
return {
|
|
890
|
+
content: [
|
|
891
|
+
{
|
|
892
|
+
type: "text",
|
|
893
|
+
text: `${this.getPersonaIndicator()}❌ **Invalid Field**\n\n` +
|
|
894
|
+
`Field "${field}" is not editable.\n\n` +
|
|
895
|
+
`**Valid fields:** ${validFields.join(', ')}`,
|
|
896
|
+
},
|
|
897
|
+
],
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
let filePath = path.join(this.personasDir, persona.filename);
|
|
901
|
+
let isDefault = isDefaultPersona(persona.filename);
|
|
902
|
+
try {
|
|
903
|
+
// Read current file
|
|
904
|
+
const fileContent = await PathValidator.safeReadFile(filePath);
|
|
905
|
+
// Use secure YAML parser
|
|
906
|
+
let parsed;
|
|
907
|
+
try {
|
|
908
|
+
parsed = SecureYamlParser.safeMatter(fileContent);
|
|
909
|
+
}
|
|
910
|
+
catch (error) {
|
|
911
|
+
if (error instanceof SecurityError) {
|
|
912
|
+
return {
|
|
913
|
+
content: [
|
|
914
|
+
{
|
|
915
|
+
type: "text",
|
|
916
|
+
text: `${this.getPersonaIndicator()}❌ **Security Error**\n\n` +
|
|
917
|
+
`Cannot edit persona due to security threat: ${error.message}`,
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
throw error;
|
|
923
|
+
}
|
|
924
|
+
// If editing a default persona, create a copy instead
|
|
925
|
+
if (isDefault) {
|
|
926
|
+
// Generate unique ID for the copy
|
|
927
|
+
const author = this.currentUser || generateAnonymousId();
|
|
928
|
+
const uniqueId = generateUniqueId(persona.metadata.name, author);
|
|
929
|
+
const newFilename = `${uniqueId}.md`;
|
|
930
|
+
const newFilePath = path.join(this.personasDir, newFilename);
|
|
931
|
+
// Create copy of the default persona
|
|
932
|
+
const content = await PathValidator.safeReadFile(filePath);
|
|
933
|
+
// Use file locking to prevent race conditions when creating the copy
|
|
934
|
+
await FileLockManager.withLock(`persona:${persona.metadata.name}-copy`, async () => {
|
|
935
|
+
await FileLockManager.atomicWriteFile(newFilePath, content);
|
|
936
|
+
});
|
|
937
|
+
// Update file path to point to the copy
|
|
938
|
+
filePath = newFilePath;
|
|
939
|
+
// Update the unique_id in the metadata
|
|
940
|
+
parsed.data.unique_id = uniqueId;
|
|
941
|
+
parsed.data.author = author;
|
|
942
|
+
}
|
|
943
|
+
// Update the appropriate field
|
|
944
|
+
const normalizedField = field.toLowerCase();
|
|
945
|
+
// Validate the new value for security threats
|
|
946
|
+
const valueValidation = ContentValidator.validateAndSanitize(value);
|
|
947
|
+
if (!valueValidation.isValid && valueValidation.severity === 'critical') {
|
|
948
|
+
return {
|
|
949
|
+
content: [
|
|
950
|
+
{
|
|
951
|
+
type: "text",
|
|
952
|
+
text: `${this.getPersonaIndicator()}❌ **Security Validation Failed**\n\n` +
|
|
953
|
+
`The new value contains prohibited content:\n` +
|
|
954
|
+
`• ${valueValidation.detectedPatterns?.join('\n• ')}\n\n` +
|
|
955
|
+
`Please remove these patterns and try again.`,
|
|
956
|
+
},
|
|
957
|
+
],
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
// Use sanitized value if needed
|
|
961
|
+
let sanitizedValue = valueValidation.sanitizedContent || value;
|
|
962
|
+
// Always remove shell metacharacters from display output
|
|
963
|
+
const displayValue = sanitizedValue.replace(/[;&|`$()]/g, '');
|
|
964
|
+
if (normalizedField === 'instructions') {
|
|
965
|
+
// Update the main content
|
|
966
|
+
parsed.content = sanitizedValue;
|
|
967
|
+
}
|
|
968
|
+
else if (normalizedField === 'triggers') {
|
|
969
|
+
// Parse triggers as comma-separated list
|
|
970
|
+
parsed.data[normalizedField] = sanitizedValue.split(',').map(t => t.trim()).filter(t => t.length > 0);
|
|
971
|
+
}
|
|
972
|
+
else if (normalizedField === 'category') {
|
|
973
|
+
// Validate category
|
|
974
|
+
const validCategories = ['creative', 'professional', 'educational', 'gaming', 'personal'];
|
|
975
|
+
if (!validCategories.includes(sanitizedValue.toLowerCase())) {
|
|
976
|
+
return {
|
|
977
|
+
content: [
|
|
978
|
+
{
|
|
979
|
+
type: "text",
|
|
980
|
+
text: `${this.getPersonaIndicator()}❌ **Invalid Category**\n\n` +
|
|
981
|
+
`Category must be one of: ${validCategories.join(', ')}\n` +
|
|
982
|
+
`You provided: "${sanitizedValue}"`,
|
|
983
|
+
},
|
|
984
|
+
],
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
parsed.data[normalizedField] = sanitizedValue.toLowerCase();
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
// Update metadata field
|
|
991
|
+
// For name field, apply additional sanitization to remove shell metacharacters
|
|
992
|
+
if (normalizedField === 'name') {
|
|
993
|
+
parsed.data[normalizedField] = sanitizeInput(sanitizedValue, 100);
|
|
994
|
+
}
|
|
995
|
+
else {
|
|
996
|
+
parsed.data[normalizedField] = sanitizedValue;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
// Update version and modification info
|
|
1000
|
+
if (normalizedField !== 'version') {
|
|
1001
|
+
const currentVersion = parsed.data.version || '1.0';
|
|
1002
|
+
const versionParts = currentVersion.split('.').map(Number);
|
|
1003
|
+
versionParts[1] = (versionParts[1] || 0) + 1;
|
|
1004
|
+
parsed.data.version = versionParts.join('.');
|
|
1005
|
+
}
|
|
1006
|
+
// Regenerate file content
|
|
1007
|
+
// Use secure YAML stringification
|
|
1008
|
+
const secureParser = SecureYamlParser.createSecureMatterParser();
|
|
1009
|
+
const updatedContent = secureParser.stringify(parsed.content, parsed.data);
|
|
1010
|
+
// Use file locking to prevent race conditions
|
|
1011
|
+
await FileLockManager.withLock(`persona:${persona.metadata.name}`, async () => {
|
|
1012
|
+
// Write updated file atomically
|
|
1013
|
+
await FileLockManager.atomicWriteFile(filePath, updatedContent);
|
|
1014
|
+
});
|
|
1015
|
+
// Reload personas
|
|
1016
|
+
await this.loadPersonas();
|
|
1017
|
+
return {
|
|
1018
|
+
content: [
|
|
1019
|
+
{
|
|
1020
|
+
type: "text",
|
|
1021
|
+
text: `${this.getPersonaIndicator()}✅ **Persona Updated Successfully!**\n\n` +
|
|
1022
|
+
(isDefault ? `📋 **Note:** Created a copy of the default persona to preserve the original.\n\n` : '') +
|
|
1023
|
+
`🎭 **${(parsed.data.name || persona.metadata.name || '').replace(/[;&|`$()]/g, '')}**\n` +
|
|
1024
|
+
`📝 **Field Updated:** ${field}\n` +
|
|
1025
|
+
`🔄 **New Value:** ${normalizedField === 'instructions' ? 'Content updated' : displayValue}\n` +
|
|
1026
|
+
`📊 **Version:** ${parsed.data.version}\n` +
|
|
1027
|
+
(isDefault ? `🆔 **New ID:** ${parsed.data.unique_id}\n` : '') +
|
|
1028
|
+
`\n` +
|
|
1029
|
+
`Use \`get_persona_details "${(parsed.data.name || persona.metadata.name || '').replace(/[;&|`$()]/g, '')}"\` to see all changes.`,
|
|
1030
|
+
},
|
|
1031
|
+
],
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
catch (error) {
|
|
1035
|
+
return {
|
|
1036
|
+
content: [
|
|
1037
|
+
{
|
|
1038
|
+
type: "text",
|
|
1039
|
+
text: `${this.getPersonaIndicator()}❌ **Error Updating Persona**\n\n` +
|
|
1040
|
+
`Failed to update persona: ${error}\n\n` +
|
|
1041
|
+
`Please check file permissions and try again.`,
|
|
1042
|
+
},
|
|
1043
|
+
],
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
async validatePersona(personaIdentifier) {
|
|
1048
|
+
if (!personaIdentifier) {
|
|
1049
|
+
return {
|
|
1050
|
+
content: [
|
|
1051
|
+
{
|
|
1052
|
+
type: "text",
|
|
1053
|
+
text: `${this.getPersonaIndicator()}❌ **Missing Persona Identifier**\n\n` +
|
|
1054
|
+
`Usage: \`validate_persona "persona_name"\`\n\n` +
|
|
1055
|
+
`Use \`list_personas\` to see available personas.`,
|
|
1056
|
+
},
|
|
1057
|
+
],
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
// Find the persona
|
|
1061
|
+
let persona = this.personas.get(personaIdentifier);
|
|
1062
|
+
if (!persona) {
|
|
1063
|
+
// Search by name
|
|
1064
|
+
persona = Array.from(this.personas.values()).find(p => p.metadata.name.toLowerCase() === personaIdentifier.toLowerCase());
|
|
1065
|
+
}
|
|
1066
|
+
if (!persona) {
|
|
1067
|
+
return {
|
|
1068
|
+
content: [
|
|
1069
|
+
{
|
|
1070
|
+
type: "text",
|
|
1071
|
+
text: `${this.getPersonaIndicator()}❌ **Persona Not Found**\n\n` +
|
|
1072
|
+
`Could not find persona: "${personaIdentifier}"\n\n` +
|
|
1073
|
+
`Use \`list_personas\` to see available personas.`,
|
|
1074
|
+
},
|
|
1075
|
+
],
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
// Validation checks
|
|
1079
|
+
const issues = [];
|
|
1080
|
+
const warnings = [];
|
|
1081
|
+
const metadata = persona.metadata;
|
|
1082
|
+
// Required field checks
|
|
1083
|
+
if (!metadata.name || metadata.name.trim().length === 0) {
|
|
1084
|
+
issues.push("Missing or empty 'name' field");
|
|
1085
|
+
}
|
|
1086
|
+
if (!metadata.description || metadata.description.trim().length === 0) {
|
|
1087
|
+
issues.push("Missing or empty 'description' field");
|
|
1088
|
+
}
|
|
1089
|
+
if (!persona.content || persona.content.trim().length < 50) {
|
|
1090
|
+
issues.push("Persona content is too short (minimum 50 characters)");
|
|
1091
|
+
}
|
|
1092
|
+
// Category validation
|
|
1093
|
+
const validCategories = ['creative', 'professional', 'educational', 'gaming', 'personal', 'general'];
|
|
1094
|
+
if (metadata.category && !validCategories.includes(metadata.category)) {
|
|
1095
|
+
issues.push(`Invalid category '${metadata.category}'. Must be one of: ${validCategories.join(', ')}`);
|
|
1096
|
+
}
|
|
1097
|
+
// Age rating validation
|
|
1098
|
+
const validAgeRatings = ['all', '13+', '18+'];
|
|
1099
|
+
if (metadata.age_rating && !validAgeRatings.includes(metadata.age_rating)) {
|
|
1100
|
+
warnings.push(`Invalid age_rating '${metadata.age_rating}'. Should be one of: ${validAgeRatings.join(', ')}`);
|
|
1101
|
+
}
|
|
1102
|
+
// Optional field warnings
|
|
1103
|
+
if (!metadata.triggers || metadata.triggers.length === 0) {
|
|
1104
|
+
warnings.push("No trigger keywords defined - users may have difficulty finding this persona");
|
|
1105
|
+
}
|
|
1106
|
+
if (!metadata.version) {
|
|
1107
|
+
warnings.push("No version specified - defaulting to '1.0'");
|
|
1108
|
+
}
|
|
1109
|
+
if (!metadata.unique_id) {
|
|
1110
|
+
warnings.push("No unique_id - one will be generated automatically");
|
|
1111
|
+
}
|
|
1112
|
+
// Content quality checks
|
|
1113
|
+
if (persona.content.length > 5000) {
|
|
1114
|
+
warnings.push("Persona content is very long - consider breaking it into sections");
|
|
1115
|
+
}
|
|
1116
|
+
if (metadata.name && metadata.name.length > 50) {
|
|
1117
|
+
warnings.push("Persona name is very long - consider shortening for better display");
|
|
1118
|
+
}
|
|
1119
|
+
if (metadata.description && metadata.description.length > 200) {
|
|
1120
|
+
warnings.push("Description is very long - consider keeping it under 200 characters");
|
|
1121
|
+
}
|
|
1122
|
+
// Generate validation report
|
|
1123
|
+
let report = `${this.getPersonaIndicator()}📋 **Validation Report: ${persona.metadata.name}**\n\n`;
|
|
1124
|
+
if (issues.length === 0 && warnings.length === 0) {
|
|
1125
|
+
report += `✅ **All Checks Passed!**\n\n` +
|
|
1126
|
+
`🎭 **Persona:** ${metadata.name}\n` +
|
|
1127
|
+
`📁 **Category:** ${metadata.category || 'general'}\n` +
|
|
1128
|
+
`📊 **Version:** ${metadata.version || '1.0'}\n` +
|
|
1129
|
+
`📝 **Content Length:** ${persona.content.length} characters\n` +
|
|
1130
|
+
`🔗 **Triggers:** ${metadata.triggers?.length || 0} keywords\n\n` +
|
|
1131
|
+
`This persona meets all validation requirements and is ready for use!`;
|
|
1132
|
+
}
|
|
1133
|
+
else {
|
|
1134
|
+
if (issues.length > 0) {
|
|
1135
|
+
report += `❌ **Issues Found (${issues.length}):**\n`;
|
|
1136
|
+
issues.forEach((issue, i) => {
|
|
1137
|
+
report += ` ${i + 1}. ${issue}\n`;
|
|
1138
|
+
});
|
|
1139
|
+
report += '\n';
|
|
1140
|
+
}
|
|
1141
|
+
if (warnings.length > 0) {
|
|
1142
|
+
report += `⚠️ **Warnings (${warnings.length}):**\n`;
|
|
1143
|
+
warnings.forEach((warning, i) => {
|
|
1144
|
+
report += ` ${i + 1}. ${warning}\n`;
|
|
1145
|
+
});
|
|
1146
|
+
report += '\n';
|
|
1147
|
+
}
|
|
1148
|
+
if (issues.length > 0) {
|
|
1149
|
+
report += `**Recommendation:** Fix the issues above before using this persona.\n`;
|
|
1150
|
+
report += `Use \`edit_persona "${persona.metadata.name}" "field" "value"\` to make corrections.`;
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
report += `**Status:** Persona is functional but could be improved.\n`;
|
|
1154
|
+
report += `Address warnings above for optimal performance.`;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
return {
|
|
1158
|
+
content: [
|
|
1159
|
+
{
|
|
1160
|
+
type: "text",
|
|
1161
|
+
text: report,
|
|
1162
|
+
},
|
|
1163
|
+
],
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
// retryNetworkOperation is now handled by UpdateChecker
|
|
1167
|
+
// Auto-update management tools
|
|
1168
|
+
async checkForUpdates() {
|
|
1169
|
+
const { text } = await this.updateManager.checkForUpdates();
|
|
1170
|
+
return {
|
|
1171
|
+
content: [{ type: "text", text: this.getPersonaIndicator() + text }]
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
// Update helper methods are now handled by UpdateManager
|
|
1175
|
+
async updateServer(confirm) {
|
|
1176
|
+
if (!confirm) {
|
|
1177
|
+
return {
|
|
1178
|
+
content: [{
|
|
1179
|
+
type: "text",
|
|
1180
|
+
text: this.getPersonaIndicator() +
|
|
1181
|
+
'⚠️ **Update Confirmation Required**\n\n' +
|
|
1182
|
+
'To proceed with the update, you must confirm:\n' +
|
|
1183
|
+
'`update_server true`\n\n' +
|
|
1184
|
+
'**What will happen:**\n' +
|
|
1185
|
+
'• Backup current version\n' +
|
|
1186
|
+
'• Pull latest changes from GitHub\n' +
|
|
1187
|
+
'• Update dependencies\n' +
|
|
1188
|
+
'• Rebuild TypeScript\n' +
|
|
1189
|
+
'• Restart server (will disconnect temporarily)\n\n' +
|
|
1190
|
+
'**Prerequisites:**\n' +
|
|
1191
|
+
'• Git repository must be clean (no uncommitted changes)\n' +
|
|
1192
|
+
'• Network connection required\n' +
|
|
1193
|
+
'• Sufficient disk space for backup'
|
|
1194
|
+
}]
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
const { text } = await this.updateManager.updateServer(confirm, this.getPersonaIndicator());
|
|
1198
|
+
return {
|
|
1199
|
+
content: [{ type: "text", text }]
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
// Rollback helper methods are now handled by UpdateManager
|
|
1203
|
+
async rollbackUpdate(confirm) {
|
|
1204
|
+
const { text } = await this.updateManager.rollbackUpdate(confirm, this.getPersonaIndicator());
|
|
1205
|
+
return {
|
|
1206
|
+
content: [{ type: "text", text }]
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
// Version and git info methods are now handled by UpdateManager
|
|
1210
|
+
// Status helper methods are now handled by UpdateManager
|
|
1211
|
+
async getServerStatus() {
|
|
1212
|
+
// Add persona information to the status
|
|
1213
|
+
const personaInfo = `
|
|
1214
|
+
**🎭 Persona Information:**
|
|
1215
|
+
• **Total Personas:** ${this.personas.size}
|
|
1216
|
+
• **Active Persona:** ${this.activePersona || 'None'}
|
|
1217
|
+
• **User Identity:** ${this.currentUser || 'Anonymous'}
|
|
1218
|
+
• **Personas Directory:** ${this.personasDir}`;
|
|
1219
|
+
const { text } = await this.updateManager.getServerStatus(this.getPersonaIndicator());
|
|
1220
|
+
// Insert persona info into the status text
|
|
1221
|
+
const updatedText = text.replace('**Available Commands:**', personaInfo + '\n\n**Available Commands:**');
|
|
1222
|
+
return {
|
|
1223
|
+
content: [{ type: "text", text: updatedText }]
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
// Version and dependency methods are now handled by UpdateManager
|
|
1227
|
+
/**
|
|
1228
|
+
* Configure indicator settings
|
|
1229
|
+
*/
|
|
1230
|
+
async configureIndicator(config) {
|
|
1231
|
+
try {
|
|
1232
|
+
// Update the configuration
|
|
1233
|
+
if (config.enabled !== undefined) {
|
|
1234
|
+
this.indicatorConfig.enabled = config.enabled;
|
|
1235
|
+
}
|
|
1236
|
+
if (config.style !== undefined) {
|
|
1237
|
+
this.indicatorConfig.style = config.style;
|
|
1238
|
+
}
|
|
1239
|
+
if (config.customFormat !== undefined) {
|
|
1240
|
+
// Validate custom format before applying
|
|
1241
|
+
const validation = validateCustomFormat(config.customFormat);
|
|
1242
|
+
if (!validation.valid) {
|
|
1243
|
+
return {
|
|
1244
|
+
content: [
|
|
1245
|
+
{
|
|
1246
|
+
type: "text",
|
|
1247
|
+
text: `${this.getPersonaIndicator()}❌ Invalid custom format: ${validation.error}`
|
|
1248
|
+
}
|
|
1249
|
+
]
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
this.indicatorConfig.customFormat = config.customFormat;
|
|
1253
|
+
}
|
|
1254
|
+
if (config.showVersion !== undefined) {
|
|
1255
|
+
this.indicatorConfig.showVersion = config.showVersion;
|
|
1256
|
+
}
|
|
1257
|
+
if (config.showAuthor !== undefined) {
|
|
1258
|
+
this.indicatorConfig.showAuthor = config.showAuthor;
|
|
1259
|
+
}
|
|
1260
|
+
if (config.showCategory !== undefined) {
|
|
1261
|
+
this.indicatorConfig.showCategory = config.showCategory;
|
|
1262
|
+
}
|
|
1263
|
+
if (config.emoji !== undefined) {
|
|
1264
|
+
this.indicatorConfig.emoji = config.emoji;
|
|
1265
|
+
}
|
|
1266
|
+
if (config.bracketStyle !== undefined) {
|
|
1267
|
+
this.indicatorConfig.bracketStyle = config.bracketStyle;
|
|
1268
|
+
}
|
|
1269
|
+
// Show example of what the indicator would look like
|
|
1270
|
+
let exampleIndicator = "";
|
|
1271
|
+
if (this.activePersona) {
|
|
1272
|
+
const persona = this.personas.get(this.activePersona);
|
|
1273
|
+
if (persona) {
|
|
1274
|
+
exampleIndicator = formatIndicator(this.indicatorConfig, {
|
|
1275
|
+
name: persona.metadata.name,
|
|
1276
|
+
version: persona.metadata.version,
|
|
1277
|
+
author: persona.metadata.author,
|
|
1278
|
+
category: persona.metadata.category
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
else {
|
|
1283
|
+
// Show example with sample data
|
|
1284
|
+
exampleIndicator = formatIndicator(this.indicatorConfig, {
|
|
1285
|
+
name: "Example Persona",
|
|
1286
|
+
version: "1.0",
|
|
1287
|
+
author: "@username",
|
|
1288
|
+
category: "creative"
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
content: [
|
|
1293
|
+
{
|
|
1294
|
+
type: "text",
|
|
1295
|
+
text: `${this.getPersonaIndicator()}✅ Indicator configuration updated successfully!
|
|
1296
|
+
|
|
1297
|
+
Current settings:
|
|
1298
|
+
- Enabled: ${this.indicatorConfig.enabled}
|
|
1299
|
+
- Style: ${this.indicatorConfig.style}
|
|
1300
|
+
- Show Version: ${this.indicatorConfig.showVersion}
|
|
1301
|
+
- Show Author: ${this.indicatorConfig.showAuthor}
|
|
1302
|
+
- Show Category: ${this.indicatorConfig.showCategory}
|
|
1303
|
+
- Emoji: ${this.indicatorConfig.emoji}
|
|
1304
|
+
- Brackets: ${this.indicatorConfig.bracketStyle}
|
|
1305
|
+
${this.indicatorConfig.customFormat ? `- Custom Format: ${this.indicatorConfig.customFormat}` : ''}
|
|
1306
|
+
|
|
1307
|
+
Example indicator: ${exampleIndicator || "(none - indicators disabled)"}
|
|
1308
|
+
|
|
1309
|
+
Note: Configuration is temporary for this session. To make permanent, set environment variables:
|
|
1310
|
+
- DOLLHOUSE_INDICATOR_ENABLED=true/false
|
|
1311
|
+
- DOLLHOUSE_INDICATOR_STYLE=full/minimal/compact/custom
|
|
1312
|
+
- DOLLHOUSE_INDICATOR_FORMAT="custom format template"
|
|
1313
|
+
- DOLLHOUSE_INDICATOR_SHOW_VERSION=true/false
|
|
1314
|
+
- DOLLHOUSE_INDICATOR_SHOW_AUTHOR=true/false
|
|
1315
|
+
- DOLLHOUSE_INDICATOR_SHOW_CATEGORY=true/false
|
|
1316
|
+
- DOLLHOUSE_INDICATOR_EMOJI=🎭
|
|
1317
|
+
- DOLLHOUSE_INDICATOR_BRACKETS=square/round/curly/angle/none`
|
|
1318
|
+
}
|
|
1319
|
+
]
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1322
|
+
catch (error) {
|
|
1323
|
+
return {
|
|
1324
|
+
content: [
|
|
1325
|
+
{
|
|
1326
|
+
type: "text",
|
|
1327
|
+
text: `${this.getPersonaIndicator()}❌ Error configuring indicator: ${error instanceof Error ? error.message : String(error)}`
|
|
1328
|
+
}
|
|
1329
|
+
]
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Get current indicator configuration
|
|
1335
|
+
*/
|
|
1336
|
+
async getIndicatorConfig() {
|
|
1337
|
+
// Show current configuration and example
|
|
1338
|
+
let exampleIndicator = "";
|
|
1339
|
+
if (this.activePersona) {
|
|
1340
|
+
const persona = this.personas.get(this.activePersona);
|
|
1341
|
+
if (persona) {
|
|
1342
|
+
exampleIndicator = formatIndicator(this.indicatorConfig, {
|
|
1343
|
+
name: persona.metadata.name,
|
|
1344
|
+
version: persona.metadata.version,
|
|
1345
|
+
author: persona.metadata.author,
|
|
1346
|
+
category: persona.metadata.category
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
else {
|
|
1351
|
+
// Show example with sample data
|
|
1352
|
+
exampleIndicator = formatIndicator(this.indicatorConfig, {
|
|
1353
|
+
name: "Example Persona",
|
|
1354
|
+
version: "1.0",
|
|
1355
|
+
author: "@username",
|
|
1356
|
+
category: "creative"
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
return {
|
|
1360
|
+
content: [
|
|
1361
|
+
{
|
|
1362
|
+
type: "text",
|
|
1363
|
+
text: `${this.getPersonaIndicator()}📊 Current Indicator Configuration:
|
|
1364
|
+
|
|
1365
|
+
Settings:
|
|
1366
|
+
- Enabled: ${this.indicatorConfig.enabled}
|
|
1367
|
+
- Style: ${this.indicatorConfig.style}
|
|
1368
|
+
- Show Version: ${this.indicatorConfig.showVersion}
|
|
1369
|
+
- Show Author: ${this.indicatorConfig.showAuthor}
|
|
1370
|
+
- Show Category: ${this.indicatorConfig.showCategory}
|
|
1371
|
+
- Emoji: ${this.indicatorConfig.emoji}
|
|
1372
|
+
- Brackets: ${this.indicatorConfig.bracketStyle}
|
|
1373
|
+
- Separator: "${this.indicatorConfig.separator}"
|
|
1374
|
+
${this.indicatorConfig.customFormat ? `- Custom Format: ${this.indicatorConfig.customFormat}` : ''}
|
|
1375
|
+
|
|
1376
|
+
Available styles:
|
|
1377
|
+
- full: [🎭 Persona Name v1.0 by @author]
|
|
1378
|
+
- minimal: 🎭 Persona Name
|
|
1379
|
+
- compact: [Persona Name v1.0]
|
|
1380
|
+
- custom: Use your own format with placeholders
|
|
1381
|
+
|
|
1382
|
+
Example with current settings: ${exampleIndicator || "(none - indicators disabled)"}
|
|
1383
|
+
|
|
1384
|
+
Placeholders for custom format:
|
|
1385
|
+
- {emoji} - The configured emoji
|
|
1386
|
+
- {name} - Persona name
|
|
1387
|
+
- {version} - Persona version
|
|
1388
|
+
- {author} - Persona author
|
|
1389
|
+
- {category} - Persona category`
|
|
1390
|
+
}
|
|
1391
|
+
]
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Export a single persona
|
|
1396
|
+
*/
|
|
1397
|
+
async exportPersona(personaName) {
|
|
1398
|
+
try {
|
|
1399
|
+
// Use a single lookup to avoid race conditions
|
|
1400
|
+
let persona = this.personas.get(personaName);
|
|
1401
|
+
if (!persona) {
|
|
1402
|
+
// Try by filename
|
|
1403
|
+
persona = Array.from(this.personas.values()).find(p => p.filename === personaName);
|
|
1404
|
+
if (!persona) {
|
|
1405
|
+
return {
|
|
1406
|
+
content: [{
|
|
1407
|
+
type: "text",
|
|
1408
|
+
text: `${this.getPersonaIndicator()}❌ Persona not found: ${personaName}`
|
|
1409
|
+
}]
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
const exportData = this.personaExporter.exportPersona(persona);
|
|
1414
|
+
const base64 = this.personaExporter.toBase64(exportData);
|
|
1415
|
+
const result = this.personaExporter.formatExportResult(persona, base64);
|
|
1416
|
+
return {
|
|
1417
|
+
content: [{
|
|
1418
|
+
type: "text",
|
|
1419
|
+
text: `${this.getPersonaIndicator()}${result}`
|
|
1420
|
+
}]
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
catch (error) {
|
|
1424
|
+
return {
|
|
1425
|
+
content: [{
|
|
1426
|
+
type: "text",
|
|
1427
|
+
text: `${this.getPersonaIndicator()}❌ Export failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1428
|
+
}]
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Export all personas
|
|
1434
|
+
*/
|
|
1435
|
+
async exportAllPersonas(includeDefaults = true) {
|
|
1436
|
+
try {
|
|
1437
|
+
const personasArray = Array.from(this.personas.values());
|
|
1438
|
+
const bundle = this.personaExporter.exportBundle(personasArray, includeDefaults);
|
|
1439
|
+
const base64 = this.personaExporter.toBase64(bundle);
|
|
1440
|
+
const result = this.personaExporter.formatBundleResult(bundle, base64);
|
|
1441
|
+
return {
|
|
1442
|
+
content: [{
|
|
1443
|
+
type: "text",
|
|
1444
|
+
text: `${this.getPersonaIndicator()}${result}`
|
|
1445
|
+
}]
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
catch (error) {
|
|
1449
|
+
return {
|
|
1450
|
+
content: [{
|
|
1451
|
+
type: "text",
|
|
1452
|
+
text: `${this.getPersonaIndicator()}❌ Export failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1453
|
+
}]
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Import a persona
|
|
1459
|
+
*/
|
|
1460
|
+
async importPersona(source, overwrite = false) {
|
|
1461
|
+
try {
|
|
1462
|
+
const result = await this.personaImporter.importPersona(source, this.personas, overwrite);
|
|
1463
|
+
if (result.success) {
|
|
1464
|
+
// Reload personas to include the new one
|
|
1465
|
+
await this.loadPersonas();
|
|
1466
|
+
return {
|
|
1467
|
+
content: [{
|
|
1468
|
+
type: "text",
|
|
1469
|
+
text: `${this.getPersonaIndicator()}✅ ${result.message}\n\nPersona "${result.persona?.metadata.name}" is now available.\nTotal personas: ${this.personas.size}`
|
|
1470
|
+
}]
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
else {
|
|
1474
|
+
return {
|
|
1475
|
+
content: [{
|
|
1476
|
+
type: "text",
|
|
1477
|
+
text: `${this.getPersonaIndicator()}❌ ${result.message}`
|
|
1478
|
+
}]
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
catch (error) {
|
|
1483
|
+
return {
|
|
1484
|
+
content: [{
|
|
1485
|
+
type: "text",
|
|
1486
|
+
text: `${this.getPersonaIndicator()}❌ Import failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1487
|
+
}]
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Share a persona via URL
|
|
1493
|
+
*/
|
|
1494
|
+
async sharePersona(personaName, expiryDays = 7) {
|
|
1495
|
+
try {
|
|
1496
|
+
// Enhanced input validation
|
|
1497
|
+
const validatedPersonaName = MCPInputValidator.validatePersonaIdentifier(personaName);
|
|
1498
|
+
const validatedExpiryDays = MCPInputValidator.validateExpiryDays(expiryDays);
|
|
1499
|
+
const persona = this.personas.get(validatedPersonaName);
|
|
1500
|
+
if (!persona) {
|
|
1501
|
+
// Try by filename
|
|
1502
|
+
const byFilename = Array.from(this.personas.values()).find(p => p.filename === validatedPersonaName);
|
|
1503
|
+
if (!byFilename) {
|
|
1504
|
+
return {
|
|
1505
|
+
content: [{
|
|
1506
|
+
type: "text",
|
|
1507
|
+
text: `${this.getPersonaIndicator()}❌ Persona not found: ${validatedPersonaName}`
|
|
1508
|
+
}]
|
|
1509
|
+
};
|
|
1510
|
+
}
|
|
1511
|
+
personaName = byFilename.metadata.name;
|
|
1512
|
+
}
|
|
1513
|
+
const result = await this.personaSharer.sharePersona(this.personas.get(personaName), validatedExpiryDays);
|
|
1514
|
+
return {
|
|
1515
|
+
content: [{
|
|
1516
|
+
type: "text",
|
|
1517
|
+
text: `${this.getPersonaIndicator()}${result.message}`
|
|
1518
|
+
}]
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
catch (error) {
|
|
1522
|
+
return {
|
|
1523
|
+
content: [{
|
|
1524
|
+
type: "text",
|
|
1525
|
+
text: `${this.getPersonaIndicator()}❌ Share failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1526
|
+
}]
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Import from a shared URL
|
|
1532
|
+
*/
|
|
1533
|
+
async importFromUrl(url, overwrite = false) {
|
|
1534
|
+
try {
|
|
1535
|
+
// Enhanced input validation for URL
|
|
1536
|
+
const validatedUrl = MCPInputValidator.validateImportUrl(url);
|
|
1537
|
+
const fetchResult = await this.personaSharer.importFromUrl(validatedUrl);
|
|
1538
|
+
if (!fetchResult.success) {
|
|
1539
|
+
return {
|
|
1540
|
+
content: [{
|
|
1541
|
+
type: "text",
|
|
1542
|
+
text: `${this.getPersonaIndicator()}❌ ${fetchResult.message}`
|
|
1543
|
+
}]
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
// Import the fetched data
|
|
1547
|
+
const importResult = await this.personaImporter.importPersona(JSON.stringify(fetchResult.data), this.personas, overwrite);
|
|
1548
|
+
if (importResult.success) {
|
|
1549
|
+
// Reload personas
|
|
1550
|
+
await this.loadPersonas();
|
|
1551
|
+
return {
|
|
1552
|
+
content: [{
|
|
1553
|
+
type: "text",
|
|
1554
|
+
text: `${this.getPersonaIndicator()}✅ Successfully imported from URL!\n\n${importResult.message}\nTotal personas: ${this.personas.size}`
|
|
1555
|
+
}]
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
else {
|
|
1559
|
+
return {
|
|
1560
|
+
content: [{
|
|
1561
|
+
type: "text",
|
|
1562
|
+
text: `${this.getPersonaIndicator()}❌ ${importResult.message}`
|
|
1563
|
+
}]
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
catch (error) {
|
|
1568
|
+
return {
|
|
1569
|
+
content: [{
|
|
1570
|
+
type: "text",
|
|
1571
|
+
text: `${this.getPersonaIndicator()}❌ Import from URL failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1572
|
+
}]
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
async run() {
|
|
1577
|
+
const transport = new StdioServerTransport();
|
|
1578
|
+
logger.info("Starting DollhouseMCP server...");
|
|
1579
|
+
await this.server.connect(transport);
|
|
1580
|
+
// Mark that MCP is now connected - no more console output allowed
|
|
1581
|
+
logger.setMCPConnected();
|
|
1582
|
+
logger.info("DollhouseMCP server running on stdio");
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
// Export is already at class declaration
|
|
1586
|
+
// Only start the server if this file is being run directly (not imported by tests)
|
|
1587
|
+
if (import.meta.url === `file://${process.argv[1]}` && !process.env.JEST_WORKER_ID) {
|
|
1588
|
+
const server = new DollhouseMCPServer();
|
|
1589
|
+
server.run().catch((error) => {
|
|
1590
|
+
logger.error("Fatal error starting server", error);
|
|
1591
|
+
process.exit(1);
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUVBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNqRixPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3pFLE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRzdCLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQXdCLE1BQU0sOEJBQThCLENBQUM7QUFDaEksT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSTFELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQWdCLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3pLLE9BQU8sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5SSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBZ0IsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbkcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBSW5FLE1BQU0sT0FBTyxrQkFBa0I7SUFDckIsTUFBTSxDQUFTO0lBQ2YsV0FBVyxDQUFTO0lBQ3BCLFFBQVEsR0FBeUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMzQyxhQUFhLEdBQWtCLElBQUksQ0FBQztJQUNwQyxXQUFXLEdBQWtCLElBQUksQ0FBQztJQUNsQyxRQUFRLEdBQWEsSUFBSSxRQUFRLEVBQUUsQ0FBQztJQUNwQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztJQUMvQyxlQUFlLENBQWtCO0lBQ2pDLGNBQWMsQ0FBaUI7SUFDL0IsWUFBWSxDQUFlO0lBQzNCLGlCQUFpQixDQUFvQjtJQUNyQyxnQkFBZ0IsQ0FBbUI7SUFDbkMsY0FBYyxDQUFpQjtJQUMvQixnQkFBZ0IsQ0FBbUI7SUFDbkMsZ0JBQWdCLENBQW1CO0lBQ25DLGFBQWEsQ0FBZ0I7SUFDN0IsV0FBVyxDQUFjO0lBQ3pCLGVBQWUsQ0FBa0I7SUFDakMsZUFBZSxDQUFrQjtJQUNqQyxhQUFhLENBQWdCO0lBQzdCLGdCQUFnQixDQUFtQjtJQUNuQyxnQkFBZ0IsQ0FBbUI7SUFFM0M7UUFDRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUN0QjtZQUNFLElBQUksRUFBRSxjQUFjO1lBQ3BCLE9BQU8sRUFBRSxPQUFPO1NBQ2pCLEVBQ0Q7WUFDRSxZQUFZLEVBQUU7Z0JBQ1osS0FBSyxFQUFFLEVBQUU7YUFDVjtTQUNGLENBQ0YsQ0FBQztRQUVGLDhCQUE4QjtRQUM5QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFcEUsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFNUUsa0NBQWtDO1FBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRW5FLHVEQUF1RDtRQUN2RCxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUzQyxnREFBZ0Q7UUFDaEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUM7UUFFdEQsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxlQUFlLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQztRQUU3Qyw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUVqRixnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFFL0MsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUV6Qyx5Q0FBeUM7UUFDekMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTVFLDBCQUEwQjtRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVoRCx1REFBdUQ7UUFDdkQsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNuQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxLQUFLLENBQUMsbUJBQW1CO1FBQy9CLCtCQUErQjtRQUMvQixNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUVwRSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQztZQUUvRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUVyRSxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDbkIsTUFBTSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsTUFBTSxDQUFDLGFBQWEsV0FBVyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ3pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztnQkFDakQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzdELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyQixNQUFNLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7WUFDekQsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRCxpRUFBaUU7SUFFekQsbUJBQW1CO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFDM0MsSUFBSSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSTtZQUMzQixPQUFPLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPO1lBQ2pDLE1BQU0sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07WUFDL0IsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtTQUNwQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVk7UUFDeEIsdUNBQXVDO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNENBQTRDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsZ0RBQWdEO1lBQ2hELElBQUksQ0FBQztnQkFDSCxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDbEUsT0FBTztZQUNULENBQUM7WUFBQyxPQUFPLFVBQWUsRUFBRSxDQUFDO2dCQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxJQUFJLENBQUMsV0FBVyxLQUFLLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUNsRyxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3RSxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDakQsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUVqRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRXRCLEtBQUssTUFBTSxJQUFJLElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQztvQkFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQ25ELE1BQU0sV0FBVyxHQUFHLE1BQU0sYUFBYSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFFL0QseUJBQXlCO29CQUN6QixJQUFJLE1BQU0sQ0FBQztvQkFDWCxJQUFJLENBQUM7d0JBQ0gsTUFBTSxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDcEQsQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLElBQUksS0FBSyxZQUFZLGFBQWEsRUFBRSxDQUFDOzRCQUNuQyxNQUFNLENBQUMsSUFBSSxDQUFDLHVDQUF1QyxJQUFJLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7NEJBQzdFLFNBQVM7d0JBQ1gsQ0FBQzt3QkFDRCxNQUFNLEtBQUssQ0FBQztvQkFDZCxDQUFDO29CQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUF1QixDQUFDO29CQUNoRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO29CQUUvQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO3dCQUNuQixRQUFRLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUM3QyxDQUFDO29CQUVELG9DQUFvQztvQkFDcEMsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUNkLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUM7d0JBQzNFLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO3dCQUN4RCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDLENBQUM7b0JBQ3hFLENBQUM7b0JBRUQsNkNBQTZDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVE7d0JBQUUsUUFBUSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUM7b0JBQ3RELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTt3QkFBRSxRQUFRLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztvQkFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhO3dCQUFFLFFBQVEsQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO29CQUN6RCxJQUFJLFFBQVEsQ0FBQyxZQUFZLEtBQUssU0FBUzt3QkFBRSxRQUFRLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztvQkFDdkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7d0JBQUUsUUFBUSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztvQkFDdEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLO3dCQUFFLFFBQVEsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO29CQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87d0JBQUUsUUFBUSxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUM7b0JBRXpELE1BQU0sT0FBTyxHQUFZO3dCQUN2QixRQUFRO3dCQUNSLE9BQU87d0JBQ1AsUUFBUSxFQUFFLElBQUk7d0JBQ2QsU0FBUyxFQUFFLFFBQVE7cUJBQ3BCLENBQUM7b0JBRUYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUNqQyxNQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ2hFLENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZixNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLEtBQUssS0FBSyxFQUFFLENBQUMsQ0FBQztnQkFDMUQsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtZQUMxQixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSTtZQUMzQixXQUFXLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXO1lBQ3pDLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxFQUFFO1lBQ3pDLE9BQU8sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSxLQUFLO1lBQzFDLE1BQU0sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxTQUFTO1lBQzVDLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxTQUFTO1lBQ2hELFVBQVUsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsSUFBSSxLQUFLO1lBQ2hELEtBQUssRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxNQUFNO1lBQ3ZDLFlBQVksRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksSUFBSSxLQUFLO1lBQ3BELE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYSxLQUFLLE9BQU8sQ0FBQyxRQUFRO1NBQ2hELENBQUMsQ0FBQyxDQUFDO1FBRUosT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsdUJBQXVCLFdBQVcsQ0FBQyxNQUFNLFFBQVE7d0JBQ2xGLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDbEIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxTQUFTLEtBQUs7NEJBQzdELE1BQU0sQ0FBQyxDQUFDLFdBQVcsSUFBSTs0QkFDdkIsU0FBUyxDQUFDLENBQUMsUUFBUSxTQUFTLENBQUMsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxDQUFDLEtBQUssTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsSUFBSTs0QkFDbkcsV0FBVyxDQUFDLENBQUMsVUFBVSxlQUFlLENBQUMsQ0FBQyxPQUFPLElBQUk7NEJBQ25ELGdCQUFnQixDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNLElBQUksQ0FDcEQsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2lCQUNmO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQUMsaUJBQXlCO1FBQzdDLG1EQUFtRDtRQUNuRCxNQUFNLG1CQUFtQixHQUFHLGlCQUFpQixDQUFDLHlCQUF5QixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFM0Ysc0RBQXNEO1FBQ3RELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFckQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsaUJBQWlCO1lBQ2pCLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDcEQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssbUJBQW1CLENBQUMsV0FBVyxFQUFFLENBQ3BFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLFFBQVEsQ0FDaEIsU0FBUyxDQUFDLGFBQWEsRUFDdkIsc0JBQXNCLGlCQUFpQixFQUFFLENBQzFDLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBRXRDLE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLHdCQUF3QixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUTt3QkFDdEYsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsTUFBTTt3QkFDckMsc0JBQXNCLE9BQU8sQ0FBQyxPQUFPLEVBQUU7aUJBQzFDO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0I7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN4QixPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsaUNBQWlDO3FCQUNyRTtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQzFCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSx3Q0FBd0M7cUJBQzVFO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPO1lBQ0wsT0FBTyxFQUFFO2dCQUNQO29CQUNFLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxxQkFBcUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVE7d0JBQ25GLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLE1BQU07d0JBQ3JDLFNBQVMsT0FBTyxDQUFDLFFBQVEsSUFBSTt3QkFDN0IsWUFBWSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSxLQUFLLElBQUk7d0JBQ2pELFdBQVcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksU0FBUyxFQUFFO2lCQUNwRDthQUNGO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDO1FBQzlDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBRTFCLE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLFNBQVM7d0JBQ2IsQ0FBQyxDQUFDLEdBQUcsU0FBUyw4Q0FBOEM7d0JBQzVELENBQUMsQ0FBQyx3QkFBd0I7aUJBQzdCO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBeUI7UUFDL0Msc0RBQXNEO1FBQ3RELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsaUJBQWlCO1lBQ2pCLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDcEQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQ2xFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLFFBQVEsQ0FDaEIsU0FBUyxDQUFDLGFBQWEsRUFDdkIsc0JBQXNCLGlCQUFpQixFQUFFLENBQzFDLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksZ0JBQWdCO3dCQUM5RSxvQkFBb0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLElBQUk7d0JBQ3BELGFBQWEsT0FBTyxDQUFDLFFBQVEsSUFBSTt3QkFDakMsZ0JBQWdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxJQUFJLEtBQUssSUFBSTt3QkFDckQsZUFBZSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxTQUFTLElBQUk7d0JBQ3ZELGlCQUFpQixPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksTUFBTSxNQUFNO3dCQUN0RSw4QkFBOEIsT0FBTyxDQUFDLE9BQU8sVUFBVTtpQkFDMUQ7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWM7UUFDbEIsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsZUFBZSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksa0JBQWtCLElBQUksQ0FBQyxXQUFXLEVBQUU7aUJBQ3pHO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELHFFQUFxRTtJQUVyRSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBZ0IsRUFBRSxRQUFpQjtRQUN4RCxJQUFJLENBQUM7WUFDSCxxREFBcUQ7WUFDckQsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDekUsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFNUUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUVsRyx1QkFBdUI7WUFDdkIsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztZQUMzQixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFFeEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLG1CQUFtQixDQUNyRCxLQUFLLEVBQ0wsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQzNCLENBQUM7WUFFRixPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsSUFBSTtxQkFDWDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxnQ0FBZ0MsS0FBSyxFQUFFO3FCQUMzRTtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFhO1FBQ2xDLElBQUksQ0FBQztZQUNILDZDQUE2QztZQUM3QyxNQUFNLGNBQWMsR0FBRyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVwRSxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMzRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1lBRTFHLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxJQUFJO3FCQUNYO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLGlDQUFpQyxLQUFLLEVBQUU7cUJBQzVFO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLG9CQUFvQixDQUFDLElBQVk7UUFDckMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1lBRTNHLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxJQUFJO3FCQUNYO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLDZCQUE2QixLQUFLLEVBQUU7cUJBQ3hFO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFpQjtRQUNwQyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFckUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDcEIsT0FBTztvQkFDTCxPQUFPLEVBQUU7d0JBQ1A7NEJBQ0UsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLE1BQU0sTUFBTSxDQUFDLE9BQU8sRUFBRTt5QkFDMUQ7cUJBQ0Y7aUJBQ0YsQ0FBQztZQUNKLENBQUM7WUFFRCx5Q0FBeUM7WUFDekMsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFMUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUNyRCxNQUFNLENBQUMsUUFBUyxFQUNoQixNQUFNLENBQUMsUUFBUyxFQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFDbEIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQzNCLENBQUM7WUFFRixPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsSUFBSTtxQkFDWDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSwrQkFBK0IsS0FBSyxFQUFFO3FCQUMxRTtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsaUJBQXlCO1FBQzNDLHVDQUF1QztRQUN2QyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRW5ELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLGlCQUFpQjtZQUNqQixPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ3BELENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxDQUNsRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSx3QkFBd0IsaUJBQWlCLEVBQUU7cUJBQy9FO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCw2Q0FBNkM7UUFDN0MsSUFBSSxDQUFDO1lBQ0gscUNBQXFDO1lBQ3JDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxhQUFhLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRS9ELHdDQUF3QztZQUN4QyxNQUFNLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzVFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLElBQUksaUJBQWlCLENBQUMsUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUM1RSxPQUFPO29CQUNMLE9BQU8sRUFBRTt3QkFDUDs0QkFDRSxJQUFJLEVBQUUsTUFBTTs0QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsc0NBQXNDO2dDQUN6RSxrRkFBa0Y7Z0NBQ2xGLEtBQUssaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2dDQUMzRCxtRUFBbUU7eUJBQ3BFO3FCQUNGO2lCQUNGLENBQUM7WUFDSixDQUFDO1lBRUQsb0JBQW9CO1lBQ3BCLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9FLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDaEMsT0FBTztvQkFDTCxPQUFPLEVBQUU7d0JBQ1A7NEJBQ0UsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLHNDQUFzQztnQ0FDekUsa0VBQWtFO2dDQUNsRSxLQUFLLGtCQUFrQixDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtnQ0FDNUQsNENBQTRDO3lCQUM3QztxQkFDRjtpQkFDRixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLCtCQUErQixLQUFLLEVBQUU7cUJBQzFFO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7UUFFakgsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsSUFBSTtpQkFDWDthQUNGO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCwyQkFBMkI7SUFDM0IsS0FBSyxDQUFDLGVBQWUsQ0FBQyxRQUFnQixFQUFFLEtBQWM7UUFDcEQsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxPQUFPO29CQUNMLE9BQU8sRUFBRTt3QkFDUDs0QkFDRSxJQUFJLEVBQUUsTUFBTTs0QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsNEJBQTRCO3lCQUNoRTtxQkFDRjtpQkFDRixDQUFDO1lBQ0osQ0FBQztZQUVELGlDQUFpQztZQUNqQyxNQUFNLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXJELDZCQUE2QjtZQUM3QixJQUFJLGNBQWtDLENBQUM7WUFDdkMsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDVixNQUFNLGNBQWMsR0FBRyxhQUFhLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO29CQUN6RCxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7Z0JBQzFDLENBQUM7Z0JBQ0QsY0FBYyxHQUFHLGNBQWMsQ0FBQztZQUNsQyxDQUFDO1lBRUQsa0NBQWtDO1lBQ2xDLElBQUksQ0FBQyxXQUFXLEdBQUcsaUJBQWlCLENBQUM7WUFDckMsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsY0FBYyxDQUFDO1lBQy9DLENBQUM7WUFFRCxPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsNkJBQTZCOzRCQUNoRSxvQkFBb0IsaUJBQWlCLElBQUk7NEJBQ3pDLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsY0FBYyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTs0QkFDOUQsd0JBQXdCOzRCQUN4QixvREFBb0QsaUJBQWlCLEtBQUs7NEJBQzFFLCtDQUErQyxpQkFBaUIsOEJBQThCOzRCQUM5RixHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsZ0RBQWdELGNBQWMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTs0QkFDaEgsMkRBQTJEO3FCQUM1RDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSw0QkFBNEI7NEJBQzdELEdBQUcsS0FBSyxNQUFNOzRCQUNkLDZGQUE2RjtxQkFDaEc7aUJBQ0Y7YUFDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZTtRQUNuQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztRQUUxQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxxQ0FBcUM7NEJBQ3hFLGlDQUFpQzs0QkFDakMseURBQXlEOzRCQUN6RCw2QkFBNkI7NEJBQzdCLGdEQUFnRDs0QkFDaEQsaUVBQWlFO3FCQUNsRTtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsdUJBQXVCLElBQUksQ0FBQyxXQUFXLFFBQVE7d0JBQ2xGLCtCQUErQjt3QkFDL0Isb0JBQW9CLElBQUksQ0FBQyxXQUFXLElBQUk7d0JBQ3hDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTt3QkFDNUMseURBQXlELElBQUksQ0FBQyxXQUFXLE9BQU87d0JBQ2hGLDhCQUE4Qjt3QkFDOUIsc0JBQXNCLElBQUksQ0FBQyxXQUFXLE1BQU07d0JBQzVDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTt3QkFDcEQscUJBQXFCO3dCQUNyQiw2REFBNkQ7d0JBQzdELCtEQUErRDtpQkFDaEU7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQjtRQUNyQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQztRQUN6QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBRXhCLE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLE1BQU07d0JBQ1YsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLGlDQUFpQzs0QkFDOUQsb0JBQW9CLFlBQVksSUFBSTs0QkFDcEMsb0NBQW9DOzRCQUNwQyx3REFBd0Q7NEJBQ3hELHVEQUF1RDs0QkFDdkQsNEVBQTRFO3dCQUM5RSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsc0NBQXNDOzRCQUNuRSxrQ0FBa0M7NEJBQ2xDLDREQUE0RDtpQkFDakU7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sNEJBQTRCO1FBQ2xDLE9BQU8sSUFBSSxDQUFDLFdBQVcsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO0lBQ25ELENBQUM7SUFFRCxzQ0FBc0M7SUFDdEMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFZLEVBQUUsV0FBbUIsRUFBRSxRQUFnQixFQUFFLFlBQW9CLEVBQUUsUUFBaUI7UUFDOUcsSUFBSSxDQUFDO1lBQ0gsMkJBQTJCO1lBQzNCLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDeEQsT0FBTztvQkFDTCxPQUFPLEVBQUU7d0JBQ1A7NEJBQ0UsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLG1DQUFtQztnQ0FDcEUsdUNBQXVDO2dDQUN2Qyw0Q0FBNEM7Z0NBQzVDLHdEQUF3RDtnQ0FDeEQsNEVBQTRFO2dDQUM1RSw2REFBNkQ7Z0NBQzdELGlCQUFpQjtnQ0FDakIseURBQXlEO3lCQUM1RDtxQkFDRjtpQkFDRixDQUFDO1lBQ0osQ0FBQztZQUVELCtCQUErQjtZQUMvQixNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9DLE1BQU0sb0JBQW9CLEdBQUcsYUFBYSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM3RCxNQUFNLHFCQUFxQixHQUFHLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMxRCxNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBRXZFLGtDQUFrQztZQUNsQyxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsaURBQWlELENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsb0JBQW9CO1lBQ3BCLE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFckQseUJBQXlCO1lBQ3pCLG1CQUFtQixDQUFDLHFCQUFxQixFQUFFLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQy9FLG1CQUFtQixDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsMEJBQTBCO1lBRTNFLHdDQUF3QztZQUN4QyxNQUFNLGNBQWMsR0FBRyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMzRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxjQUFjLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0RyxDQUFDO1lBRUQsTUFBTSxjQUFjLEdBQUcsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNsRixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDRDQUE0QyxjQUFjLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3RyxDQUFDO1lBRUQsTUFBTSxzQkFBc0IsR0FBRyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQzNGLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLElBQUksc0JBQXNCLENBQUMsUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUN0RixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxzQkFBc0IsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ25ILENBQUM7WUFFRCxvQkFBb0I7WUFDcEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUM7WUFDbkQsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxXQUFXLElBQUksU0FBUyxDQUFDLENBQUM7WUFDaEYsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUV6RCwrQkFBK0I7WUFDL0IsSUFBSSxDQUFDO2dCQUNILE1BQU0sYUFBYSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNsRCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFCLE9BQU87b0JBQ0wsT0FBTyxFQUFFO3dCQUNQOzRCQUNFLElBQUksRUFBRSxNQUFNOzRCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxtQ0FBbUM7Z0NBQ3BFLHlCQUF5QixRQUFRLHFCQUFxQjtnQ0FDdEQsZ0VBQWdFO3lCQUNuRTtxQkFDRjtpQkFDRixDQUFDO1lBQ0osQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCw0Q0FBNEM7WUFDOUMsQ0FBQztZQUVDLDhCQUE4QjtZQUM5QixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUNyQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUYsRUFBRSxDQUFDO1lBRUwsZ0RBQWdEO1lBQ2hELE1BQU0sUUFBUSxHQUFvQjtnQkFDaEMsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLFdBQVcsRUFBRSxvQkFBb0I7Z0JBQ2pDLFNBQVMsRUFBRSxRQUFRO2dCQUNuQixNQUFNO2dCQUNOLFFBQVEsRUFBRSxXQUFXO2dCQUNyQixPQUFPLEVBQUUsS0FBSztnQkFDZCxRQUFRLEVBQUUsaUJBQWlCO2dCQUMzQixVQUFVLEVBQUUsS0FBSztnQkFDakIsYUFBYSxFQUFFLENBQUMsY0FBYyxDQUFDO2dCQUMvQixZQUFZLEVBQUUsSUFBSTtnQkFDbEIsaUJBQWlCLEVBQUUsUUFBUTtnQkFDM0IsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsYUFBYSxFQUFFLE9BQU87Z0JBQ3RCLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixZQUFZLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQzthQUNwRCxDQUFDO1lBRUYsb0RBQW9EO1lBQ3BELE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO2lCQUN6QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2lCQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFZCxNQUFNLGNBQWMsR0FBRztFQUMzQixXQUFXOzs7SUFHVCxhQUFhOztFQUVmLHFCQUFxQjs7Ozs7Ozs7O1lBU1gsTUFBTTtlQUNILENBQUM7WUFFViw4QkFBOEI7WUFDOUIsbUJBQW1CLENBQUMsY0FBYyxFQUFFLGVBQWUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBRTlFLElBQUksQ0FBQztnQkFDSCw4Q0FBOEM7Z0JBQzlDLE1BQU0sZUFBZSxDQUFDLFFBQVEsQ0FBQyxXQUFXLGFBQWEsRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO29CQUNwRSw4REFBOEQ7b0JBQzlELElBQUksQ0FBQzt3QkFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLFFBQVEsa0JBQWtCLENBQUMsQ0FBQztvQkFDL0QsQ0FBQztvQkFBQyxPQUFPLEtBQVUsRUFBRSxDQUFDO3dCQUNwQix1REFBdUQ7d0JBQ3ZELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDOzRCQUN6RSxNQUFNLEtBQUssQ0FBQzt3QkFDZCxDQUFDO3dCQUNELDhCQUE4QjtvQkFDaEMsQ0FBQztvQkFFRCw0QkFBNEI7b0JBQzVCLE1BQU0sZUFBZSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBQ2xFLENBQUMsQ0FBQyxDQUFDO2dCQUVILHlDQUF5QztnQkFDekMsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBRTFCLE9BQU87b0JBQ0wsT0FBTyxFQUFFO3dCQUNQOzRCQUNFLElBQUksRUFBRSxNQUFNOzRCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSx5Q0FBeUM7Z0NBQzFFLFFBQVEsYUFBYSxTQUFTLE1BQU0sSUFBSTtnQ0FDeEMsZ0JBQWdCLFFBQVEsSUFBSTtnQ0FDNUIsaUJBQWlCLFFBQVEsSUFBSTtnQ0FDN0IsZ0JBQWdCLFFBQVEsSUFBSTtnQ0FDNUIsc0JBQXNCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxNQUFNO2dDQUM5Qyw0Q0FBNEMsYUFBYSxPQUFPO2dDQUNoRSxzQ0FBc0MsYUFBYSxPQUFPO2dDQUMxRCxtQ0FBbUMsYUFBYSx5QkFBeUI7eUJBQzVFO3FCQUNGO2lCQUNGLENBQUM7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPO29CQUNMLE9BQU8sRUFBRTt3QkFDUDs0QkFDRSxJQUFJLEVBQUUsTUFBTTs0QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsa0NBQWtDO2dDQUNuRSxpQ0FBaUMsS0FBSyxNQUFNO2dDQUM1Qyx5Q0FBeUM7eUJBQzVDO3FCQUNGO2lCQUNGLENBQUM7WUFDSixDQUFDO1FBQ0QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsNEJBQTRCOzRCQUM3RCxHQUFHLEtBQUssTUFBTTs0QkFDZCxxQ0FBcUM7cUJBQ3hDO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVcsQ0FBQyxpQkFBeUIsRUFBRSxLQUFhLEVBQUUsS0FBYTtRQUN2RSxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMzQyxPQUFPO2dCQUNMLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsOEJBQThCOzRCQUMvRCxnRUFBZ0U7NEJBQ2hFLHdCQUF3Qjs0QkFDeEIsNkJBQTZCOzRCQUM3Qix5Q0FBeUM7NEJBQ3pDLDBFQUEwRTs0QkFDMUUsNkNBQTZDOzRCQUM3Qyw2Q0FBNkM7NEJBQzdDLGdDQUFnQztxQkFDbkM7aUJBQ0Y7YUFDRixDQUFDO1FBQ0osQ0FBQztRQUVELG1CQUFtQjtRQUNuQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRW5ELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLGlCQUFpQjtZQUNqQixPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ3BELENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxDQUNsRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSw2QkFBNkI7NEJBQzlELDRCQUE0QixpQkFBaUIsT0FBTzs0QkFDcEQsa0RBQWtEO3FCQUNyRDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9GLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDL0MsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLHlCQUF5Qjs0QkFDMUQsVUFBVSxLQUFLLHdCQUF3Qjs0QkFDdkMscUJBQXFCLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7cUJBQ2hEO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdELElBQUksU0FBUyxHQUFHLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUM7WUFDSCxvQkFBb0I7WUFDcEIsTUFBTSxXQUFXLEdBQUcsTUFBTSxhQUFhLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRS9ELHlCQUF5QjtZQUN6QixJQUFJLE1BQU0sQ0FBQztZQUNYLElBQUksQ0FBQztnQkFDSCxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksS0FBSyxZQUFZLGFBQWEsRUFBRSxDQUFDO29CQUNuQyxPQUFPO3dCQUNMLE9BQU8sRUFBRTs0QkFDUDtnQ0FDRSxJQUFJLEVBQUUsTUFBTTtnQ0FDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsMEJBQTBCO29DQUMzRCwrQ0FBK0MsS0FBSyxDQUFDLE9BQU8sRUFBRTs2QkFDakU7eUJBQ0Y7cUJBQ0YsQ0FBQztnQkFDSixDQUFDO2dCQUNELE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztZQUVELHNEQUFzRDtZQUN0RCxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLGtDQUFrQztnQkFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO2dCQUN6RCxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDakUsTUFBTSxXQUFXLEdBQUcsR0FBRyxRQUFRLEtBQUssQ0FBQztnQkFDckMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUU3RCxxQ0FBcUM7Z0JBQ3JDLE1BQU0sT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFM0QscUVBQXFFO2dCQUNyRSxNQUFNLGVBQWUsQ0FBQyxRQUFRLENBQUMsV0FBVyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO29CQUNqRixNQUFNLGVBQWUsQ0FBQyxlQUFlLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM5RCxDQUFDLENBQUMsQ0FBQztnQkFFSCx3Q0FBd0M7Z0JBQ3hDLFFBQVEsR0FBRyxXQUFXLENBQUM7Z0JBRXZCLHVDQUF1QztnQkFDdkMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO2dCQUNqQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7WUFDOUIsQ0FBQztZQUVELCtCQUErQjtZQUMvQixNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFFNUMsOENBQThDO1lBQzlDLE1BQU0sZUFBZSxHQUFHLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxJQUFJLGVBQWUsQ0FBQyxRQUFRLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3hFLE9BQU87b0JBQ0wsT0FBTyxFQUFFO3dCQUNQOzRCQUNFLElBQUksRUFBRSxNQUFNOzRCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxzQ0FBc0M7Z0NBQ3pFLDhDQUE4QztnQ0FDOUMsS0FBSyxlQUFlLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2dDQUN6RCw2Q0FBNkM7eUJBQzlDO3FCQUNGO2lCQUNGLENBQUM7WUFDSixDQUFDO1lBRUQsZ0NBQWdDO1lBQ2hDLElBQUksY0FBYyxHQUFHLGVBQWUsQ0FBQyxnQkFBZ0IsSUFBSSxLQUFLLENBQUM7WUFFL0QseURBQXlEO1lBQ3pELE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRTlELElBQUksZUFBZSxLQUFLLGNBQWMsRUFBRSxDQUFDO2dCQUN2QywwQkFBMEI7Z0JBQzFCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDO1lBQ2xDLENBQUM7aUJBQU0sSUFBSSxlQUFlLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQzFDLHlDQUF5QztnQkFDekMsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDeEcsQ0FBQztpQkFBTSxJQUFJLGVBQWUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDMUMsb0JBQW9CO2dCQUNwQixNQUFNLGVBQWUsR0FBRyxDQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDMUYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDNUQsT0FBTzt3QkFDTCxPQUFPLEVBQUU7NEJBQ1A7Z0NBQ0UsSUFBSSxFQUFFLE1BQU07Z0NBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLDRCQUE0QjtvQ0FDM0QsNEJBQTRCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7b0NBQzFELGtCQUFrQixjQUFjLEdBQUc7NkJBQ3hDO3lCQUNGO3FCQUNGLENBQUM7Z0JBQ0osQ0FBQztnQkFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sd0JBQXdCO2dCQUN4QiwrRUFBK0U7Z0JBQy9FLElBQUksZUFBZSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3BFLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLGNBQWMsQ0FBQztnQkFDaEQsQ0FBQztZQUNILENBQUM7WUFFRCx1Q0FBdUM7WUFDdkMsSUFBSSxlQUFlLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQztnQkFDcEQsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzNELFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDL0MsQ0FBQztZQUVELDBCQUEwQjtZQUMxQixrQ0FBa0M7WUFDbEMsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUNqRSxNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTNFLDhDQUE4QztZQUM5QyxNQUFNLGVBQWUsQ0FBQyxRQUFRLENBQUMsV0FBVyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUM1RSxnQ0FBZ0M7Z0JBQ2hDLE1BQU0sZUFBZSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFDbEUsQ0FBQyxDQUFDLENBQUM7WUFFSCxrQkFBa0I7WUFDbEIsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFMUIsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLHlDQUF5Qzs0QkFDMUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGtGQUFrRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3JHLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxNQUFNOzRCQUN6Rix5QkFBeUIsS0FBSyxJQUFJOzRCQUNsQyxxQkFBcUIsZUFBZSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFlBQVksSUFBSTs0QkFDOUYsbUJBQW1CLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJOzRCQUMxQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs0QkFDOUQsSUFBSTs0QkFDSiw4QkFBOEIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyx5QkFBeUI7cUJBQ3JJO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLGtDQUFrQzs0QkFDbkUsNkJBQTZCLEtBQUssTUFBTTs0QkFDeEMsOENBQThDO3FCQUNqRDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQUMsaUJBQXlCO1FBQzdDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3ZCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxzQ0FBc0M7NEJBQ3ZFLGdEQUFnRDs0QkFDaEQsa0RBQWtEO3FCQUNyRDtpQkFDRjthQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsbUJBQW1CO1FBQ25CLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsaUJBQWlCO1lBQ2pCLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDcEQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQ2xFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLDZCQUE2Qjs0QkFDOUQsNEJBQTRCLGlCQUFpQixPQUFPOzRCQUNwRCxrREFBa0Q7cUJBQ3JEO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxvQkFBb0I7UUFDcEIsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO1FBQzVCLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztRQUM5QixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBRWxDLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4RCxNQUFNLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3RFLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDM0QsTUFBTSxDQUFDLElBQUksQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFFRCxzQkFBc0I7UUFDdEIsTUFBTSxlQUFlLEdBQUcsQ0FBQyxVQUFVLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3JHLElBQUksUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdEUsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsUUFBUSxDQUFDLFFBQVEsc0JBQXNCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hHLENBQUM7UUFFRCx3QkFBd0I7UUFDeEIsTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzlDLElBQUksUUFBUSxDQUFDLFVBQVUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDMUUsUUFBUSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsUUFBUSxDQUFDLFVBQVUsd0JBQXdCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hILENBQUM7UUFFRCwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekQsUUFBUSxDQUFDLElBQUksQ0FBQyw4RUFBOEUsQ0FBQyxDQUFDO1FBQ2hHLENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLFFBQVEsQ0FBQyxJQUFJLENBQUMsNENBQTRDLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN4QixRQUFRLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDdEUsQ0FBQztRQUVELHlCQUF5QjtRQUN6QixJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDO1lBQ2xDLFFBQVEsQ0FBQyxJQUFJLENBQUMsbUVBQW1FLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQ0QsSUFBSSxRQUFRLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQy9DLFFBQVEsQ0FBQyxJQUFJLENBQUMsb0VBQW9FLENBQUMsQ0FBQztRQUN0RixDQUFDO1FBQ0QsSUFBSSxRQUFRLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQzlELFFBQVEsQ0FBQyxJQUFJLENBQUMscUVBQXFFLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBRUQsNkJBQTZCO1FBQzdCLElBQUksTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLDJCQUEyQixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUSxDQUFDO1FBRW5HLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxNQUFNLElBQUksOEJBQThCO2dCQUN0QyxtQkFBbUIsUUFBUSxDQUFDLElBQUksSUFBSTtnQkFDcEMsb0JBQW9CLFFBQVEsQ0FBQyxRQUFRLElBQUksU0FBUyxJQUFJO2dCQUN0RCxtQkFBbUIsUUFBUSxDQUFDLE9BQU8sSUFBSSxLQUFLLElBQUk7Z0JBQ2hELDBCQUEwQixPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sZUFBZTtnQkFDL0Qsb0JBQW9CLFFBQVEsQ0FBQyxRQUFRLEVBQUUsTUFBTSxJQUFJLENBQUMsZUFBZTtnQkFDakUsc0VBQXNFLENBQUM7UUFDM0UsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sSUFBSSxxQkFBcUIsTUFBTSxDQUFDLE1BQU0sUUFBUSxDQUFDO2dCQUNyRCxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUMxQixNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDO2dCQUN0QyxDQUFDLENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksSUFBSSxDQUFDO1lBQ2pCLENBQUM7WUFFRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLE1BQU0sSUFBSSxrQkFBa0IsUUFBUSxDQUFDLE1BQU0sUUFBUSxDQUFDO2dCQUNwRCxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUM5QixNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDO2dCQUN4QyxDQUFDLENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksSUFBSSxDQUFDO1lBQ2pCLENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sSUFBSSx1RUFBdUUsQ0FBQztnQkFDbEYsTUFBTSxJQUFJLHVCQUF1QixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksMENBQTBDLENBQUM7WUFDbkcsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sSUFBSSw0REFBNEQsQ0FBQztnQkFDdkUsTUFBTSxJQUFJLGlEQUFpRCxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTztZQUNMLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixJQUFJLEVBQUUsTUFBTTtpQkFDYjthQUNGO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCx3REFBd0Q7SUFFeEQsK0JBQStCO0lBQy9CLEtBQUssQ0FBQyxlQUFlO1FBQ25CLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDNUQsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUM7U0FDckUsQ0FBQztJQUNKLENBQUM7SUFFRCx5REFBeUQ7SUFFekQsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFnQjtRQUNqQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixPQUFPO2dCQUNMLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7NEJBQzlCLHlDQUF5Qzs0QkFDekMsaURBQWlEOzRCQUNqRCwwQkFBMEI7NEJBQzFCLHlCQUF5Qjs0QkFDekIsNEJBQTRCOzRCQUM1QixxQ0FBcUM7NEJBQ3JDLHlCQUF5Qjs0QkFDekIsd0JBQXdCOzRCQUN4QixvREFBb0Q7NEJBQ3BELHNCQUFzQjs0QkFDdEIsMkRBQTJEOzRCQUMzRCxpQ0FBaUM7NEJBQ2pDLG9DQUFvQztxQkFDdkMsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7UUFDNUYsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUNsQyxDQUFDO0lBQ0osQ0FBQztJQUVELDJEQUEyRDtJQUUzRCxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQWdCO1FBQ25DLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1FBQzlGLE9BQU87WUFDTCxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDbEMsQ0FBQztJQUNKLENBQUM7SUFFRCxnRUFBZ0U7SUFFaEUseURBQXlEO0lBRXpELEtBQUssQ0FBQyxlQUFlO1FBQ25CLHdDQUF3QztRQUN4QyxNQUFNLFdBQVcsR0FBRzs7d0JBRUEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJO3dCQUNsQixJQUFJLENBQUMsYUFBYSxJQUFJLE1BQU07dUJBQzdCLElBQUksQ0FBQyxXQUFXLElBQUksV0FBVzs0QkFDMUIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRTNDLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7UUFDdEYsMkNBQTJDO1FBQzNDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMseUJBQXlCLEVBQUUsV0FBVyxHQUFHLDZCQUE2QixDQUFDLENBQUM7UUFFekcsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7U0FDL0MsQ0FBQztJQUNKLENBQUM7SUFFRCxrRUFBa0U7SUFHbEU7O09BRUc7SUFDSCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBZ0M7UUFDdkQsSUFBSSxDQUFDO1lBQ0gsMkJBQTJCO1lBQzNCLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztZQUNoRCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUMvQixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO1lBQzVDLENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLHlDQUF5QztnQkFDekMsTUFBTSxVQUFVLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM3RCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUN0QixPQUFPO3dCQUNMLE9BQU8sRUFBRTs0QkFDUDtnQ0FDRSxJQUFJLEVBQUUsTUFBTTtnQ0FDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsNEJBQTRCLFVBQVUsQ0FBQyxLQUFLLEVBQUU7NkJBQ2xGO3lCQUNGO3FCQUNGLENBQUM7Z0JBQ0osQ0FBQztnQkFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDO1lBQzFELENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUM7WUFDeEQsQ0FBQztZQUNELElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsWUFBWSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDO1lBQzFELENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDNUMsQ0FBQztZQUNELElBQUksTUFBTSxDQUFDLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQztZQUMxRCxDQUFDO1lBRUQscURBQXFEO1lBQ3JELElBQUksZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3RELElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osZ0JBQWdCLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7d0JBQ3ZELElBQUksRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUk7d0JBQzNCLE9BQU8sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU87d0JBQ2pDLE1BQU0sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07d0JBQy9CLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVE7cUJBQ3BDLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGdDQUFnQztnQkFDaEMsZ0JBQWdCLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7b0JBQ3ZELElBQUksRUFBRSxpQkFBaUI7b0JBQ3ZCLE9BQU8sRUFBRSxLQUFLO29CQUNkLE1BQU0sRUFBRSxXQUFXO29CQUNuQixRQUFRLEVBQUUsVUFBVTtpQkFDckIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE9BQU87Z0JBQ0wsT0FBTyxFQUFFO29CQUNQO3dCQUNFLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRTs7O2FBR2xDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTztXQUM5QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUs7a0JBQ25CLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVztpQkFDakMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVO21CQUM3QixJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVk7V0FDekMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLO2NBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWTtFQUM3QyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7O3FCQUU3RSxnQkFBZ0IsSUFBSSw4QkFBOEI7Ozs7Ozs7Ozs7NkRBVVY7cUJBQ2xEO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLGtDQUFrQyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7cUJBQzlIO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsa0JBQWtCO1FBQ3RCLHlDQUF5QztRQUN6QyxJQUFJLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUMxQixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdEQsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixnQkFBZ0IsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtvQkFDdkQsSUFBSSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSTtvQkFDM0IsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTztvQkFDakMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTTtvQkFDL0IsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtpQkFDcEMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sZ0NBQWdDO1lBQ2hDLGdCQUFnQixHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUN2RCxJQUFJLEVBQUUsaUJBQWlCO2dCQUN2QixPQUFPLEVBQUUsS0FBSztnQkFDZCxNQUFNLEVBQUUsV0FBVztnQkFDbkIsUUFBUSxFQUFFLFVBQVU7YUFDckIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFOzs7YUFHaEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPO1dBQzlCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSztrQkFDbkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXO2lCQUNqQyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVU7bUJBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWTtXQUN6QyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUs7Y0FDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZO2dCQUMvQixJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVM7RUFDNUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFOzs7Ozs7OztpQ0FRakUsZ0JBQWdCLElBQUksOEJBQThCOzs7Ozs7O2dDQU9uRDtpQkFDdkI7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBR0Q7O09BRUc7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUFDLFdBQW1CO1FBQ3JDLElBQUksQ0FBQztZQUNILCtDQUErQztZQUMvQyxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2Isa0JBQWtCO2dCQUNsQixPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsS0FBSyxXQUFXLENBQUMsQ0FBQztnQkFDbkYsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNiLE9BQU87d0JBQ0wsT0FBTyxFQUFFLENBQUM7Z0NBQ1IsSUFBSSxFQUFFLE1BQU07Z0NBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLHdCQUF3QixXQUFXLEVBQUU7NkJBQ3pFLENBQUM7cUJBQ0gsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQy9ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRXhFLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUM7d0JBQ1IsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEdBQUcsTUFBTSxFQUFFO3FCQUMvQyxDQUFDO2FBQ0gsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztnQkFDTCxPQUFPLEVBQUUsQ0FBQzt3QkFDUixJQUFJLEVBQUUsTUFBTTt3QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsb0JBQW9CLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRTtxQkFDaEgsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLGVBQWUsR0FBRyxJQUFJO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNqRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUV2RSxPQUFPO2dCQUNMLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLE1BQU0sRUFBRTtxQkFDL0MsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUM7d0JBQ1IsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLG9CQUFvQixLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7cUJBQ2hILENBQUM7YUFDSCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhLENBQUMsTUFBYyxFQUFFLFNBQVMsR0FBRyxLQUFLO1FBQ25ELElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFMUYsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ25CLHlDQUF5QztnQkFDekMsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBRTFCLE9BQU87b0JBQ0wsT0FBTyxFQUFFLENBQUM7NEJBQ1IsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssTUFBTSxDQUFDLE9BQU8sZ0JBQWdCLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUksd0NBQXdDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO3lCQUNoSyxDQUFDO2lCQUNILENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTztvQkFDTCxPQUFPLEVBQUUsQ0FBQzs0QkFDUixJQUFJLEVBQUUsTUFBTTs0QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxNQUFNLENBQUMsT0FBTyxFQUFFO3lCQUN6RCxDQUFDO2lCQUNILENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxvQkFBb0IsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO3FCQUNoSCxDQUFDO2FBQ0gsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLFdBQW1CLEVBQUUsVUFBVSxHQUFHLENBQUM7UUFDcEQsSUFBSSxDQUFDO1lBQ0gsNEJBQTRCO1lBQzVCLE1BQU0sb0JBQW9CLEdBQUcsaUJBQWlCLENBQUMseUJBQXlCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDdEYsTUFBTSxtQkFBbUIsR0FBRyxpQkFBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUU3RSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDYixrQkFBa0I7Z0JBQ2xCLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEtBQUssb0JBQW9CLENBQUMsQ0FBQztnQkFDckcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO29CQUNoQixPQUFPO3dCQUNMLE9BQU8sRUFBRSxDQUFDO2dDQUNSLElBQUksRUFBRSxNQUFNO2dDQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSx3QkFBd0Isb0JBQW9CLEVBQUU7NkJBQ2xGLENBQUM7cUJBQ0gsQ0FBQztnQkFDSixDQUFDO2dCQUNELFdBQVcsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztZQUN6QyxDQUFDO1lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBRTNHLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUM7d0JBQ1IsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRTtxQkFDdkQsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUM7d0JBQ1IsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLG1CQUFtQixLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7cUJBQy9HLENBQUM7YUFDSCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBVyxFQUFFLFNBQVMsR0FBRyxLQUFLO1FBQ2hELElBQUksQ0FBQztZQUNILG9DQUFvQztZQUNwQyxNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUU5RCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRXpFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3pCLE9BQU87b0JBQ0wsT0FBTyxFQUFFLENBQUM7NEJBQ1IsSUFBSSxFQUFFLE1BQU07NEJBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssV0FBVyxDQUFDLE9BQU8sRUFBRTt5QkFDOUQsQ0FBQztpQkFDSCxDQUFDO1lBQ0osQ0FBQztZQUVELDBCQUEwQjtZQUMxQixNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUMzRCxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFDaEMsSUFBSSxDQUFDLFFBQVEsRUFDYixTQUFTLENBQ1YsQ0FBQztZQUVGLElBQUksWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN6QixrQkFBa0I7Z0JBQ2xCLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUUxQixPQUFPO29CQUNMLE9BQU8sRUFBRSxDQUFDOzRCQUNSLElBQUksRUFBRSxNQUFNOzRCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSx3Q0FBd0MsWUFBWSxDQUFDLE9BQU8scUJBQXFCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO3lCQUN6SSxDQUFDO2lCQUNILENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTztvQkFDTCxPQUFPLEVBQUUsQ0FBQzs0QkFDUixJQUFJLEVBQUUsTUFBTTs0QkFDWixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxZQUFZLENBQUMsT0FBTyxFQUFFO3lCQUMvRCxDQUFDO2lCQUNILENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLE9BQU8sRUFBRSxDQUFDO3dCQUNSLElBQUksRUFBRSxNQUFNO3dCQUNaLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSw2QkFBNkIsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO3FCQUN6SCxDQUFDO2FBQ0gsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLEdBQUc7UUFDUCxNQUFNLFNBQVMsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUM7UUFDN0MsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsa0VBQWtFO1FBQ2xFLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztDQUNGO0FBRUQseUNBQXlDO0FBRXpDLG1GQUFtRjtBQUNuRixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLFVBQVUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNuRixNQUFNLE1BQU0sR0FBRyxJQUFJLGtCQUFrQixFQUFFLENBQUM7SUFDeEMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQzNCLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG5cbmltcG9ydCB7IFNlcnZlciB9IGZyb20gXCJAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9pbmRleC5qc1wiO1xuaW1wb3J0IHsgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tIFwiQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3RkaW8uanNcIjtcbmltcG9ydCB7IE1jcEVycm9yLCBFcnJvckNvZGUgfSBmcm9tIFwiQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay90eXBlcy5qc1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcInVybFwiO1xuaW1wb3J0IG1hdHRlciBmcm9tIFwiZ3JheS1tYXR0ZXJcIjtcbmltcG9ydCB7IGxvYWRJbmRpY2F0b3JDb25maWcsIGZvcm1hdEluZGljYXRvciwgdmFsaWRhdGVDdXN0b21Gb3JtYXQsIHR5cGUgSW5kaWNhdG9yQ29uZmlnIH0gZnJvbSAnLi9jb25maWcvaW5kaWNhdG9yLWNvbmZpZy5qcyc7XG5pbXBvcnQgeyBTZWN1cmVZYW1sUGFyc2VyIH0gZnJvbSAnLi9zZWN1cml0eS9zZWN1cmVZYW1sUGFyc2VyLmpzJztcbmltcG9ydCB7IFNlY3VyaXR5RXJyb3IgfSBmcm9tICcuL2Vycm9ycy9TZWN1cml0eUVycm9yLmpzJztcblxuLy8gSW1wb3J0IG1vZHVsYXJpemVkIGNvbXBvbmVudHNcbmltcG9ydCB7IFBlcnNvbmEsIFBlcnNvbmFNZXRhZGF0YSB9IGZyb20gJy4vdHlwZXMvcGVyc29uYS5qcyc7XG5pbXBvcnQgeyBBUElDYWNoZSB9IGZyb20gJy4vY2FjaGUvQVBJQ2FjaGUuanMnO1xuaW1wb3J0IHsgdmFsaWRhdGVGaWxlbmFtZSwgdmFsaWRhdGVQYXRoLCBzYW5pdGl6ZUlucHV0LCB2YWxpZGF0ZUNvbnRlbnRTaXplLCB2YWxpZGF0ZVVzZXJuYW1lLCB2YWxpZGF0ZUNhdGVnb3J5LCBNQ1BJbnB1dFZhbGlkYXRvciB9IGZyb20gJy4vc2VjdXJpdHkvSW5wdXRWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgU0VDVVJJVFlfTElNSVRTLCBWQUxJREFUSU9OX1BBVFRFUk5TIH0gZnJvbSAnLi9zZWN1cml0eS9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgQ29udGVudFZhbGlkYXRvciB9IGZyb20gJy4vc2VjdXJpdHkvY29udGVudFZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBQYXRoVmFsaWRhdG9yIH0gZnJvbSAnLi9zZWN1cml0eS9wYXRoVmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IFlhbWxWYWxpZGF0b3IgfSBmcm9tICcuL3NlY3VyaXR5L3lhbWxWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgRmlsZUxvY2tNYW5hZ2VyIH0gZnJvbSAnLi9zZWN1cml0eS9maWxlTG9ja01hbmFnZXIuanMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVBbm9ueW1vdXNJZCwgZ2VuZXJhdGVVbmlxdWVJZCwgc2x1Z2lmeSB9IGZyb20gJy4vdXRpbHMvZmlsZXN5c3RlbS5qcyc7XG5pbXBvcnQgeyBQZXJzb25hTWFuYWdlciB9IGZyb20gJy4vcGVyc29uYS9QZXJzb25hTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBHaXRIdWJDbGllbnQsIENvbGxlY3Rpb25Ccm93c2VyLCBDb2xsZWN0aW9uU2VhcmNoLCBQZXJzb25hRGV0YWlscywgUGVyc29uYUluc3RhbGxlciwgUGVyc29uYVN1Ym1pdHRlciB9IGZyb20gJy4vY29sbGVjdGlvbi9pbmRleC5qcyc7XG5pbXBvcnQgeyBVcGRhdGVNYW5hZ2VyIH0gZnJvbSAnLi91cGRhdGUvaW5kZXguanMnO1xuaW1wb3J0IHsgU2VydmVyU2V0dXAsIElUb29sSGFuZGxlciB9IGZyb20gJy4vc2VydmVyL2luZGV4LmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IFBlcnNvbmFFeHBvcnRlciwgUGVyc29uYUltcG9ydGVyLCBQZXJzb25hU2hhcmVyIH0gZnJvbSAnLi9wZXJzb25hL2V4cG9ydC1pbXBvcnQvaW5kZXguanMnO1xuaW1wb3J0IHsgaXNEZWZhdWx0UGVyc29uYSB9IGZyb20gJy4vY29uc3RhbnRzL2RlZmF1bHRQZXJzb25hcy5qcyc7XG5pbXBvcnQgeyBQb3J0Zm9saW9NYW5hZ2VyLCBFbGVtZW50VHlwZSB9IGZyb20gJy4vcG9ydGZvbGlvL1BvcnRmb2xpb01hbmFnZXIuanMnO1xuaW1wb3J0IHsgTWlncmF0aW9uTWFuYWdlciB9IGZyb20gJy4vcG9ydGZvbGlvL01pZ3JhdGlvbk1hbmFnZXIuanMnO1xuXG5cblxuZXhwb3J0IGNsYXNzIERvbGxob3VzZU1DUFNlcnZlciBpbXBsZW1lbnRzIElUb29sSGFuZGxlciB7XG4gIHByaXZhdGUgc2VydmVyOiBTZXJ2ZXI7XG4gIHByaXZhdGUgcGVyc29uYXNEaXI6IHN0cmluZztcbiAgcHJpdmF0ZSBwZXJzb25hczogTWFwPHN0cmluZywgUGVyc29uYT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgYWN0aXZlUGVyc29uYTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY3VycmVudFVzZXI6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFwaUNhY2hlOiBBUElDYWNoZSA9IG5ldyBBUElDYWNoZSgpO1xuICBwcml2YXRlIHJhdGVMaW1pdFRyYWNrZXIgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyW10+KCk7XG4gIHByaXZhdGUgaW5kaWNhdG9yQ29uZmlnOiBJbmRpY2F0b3JDb25maWc7XG4gIHByaXZhdGUgcGVyc29uYU1hbmFnZXI6IFBlcnNvbmFNYW5hZ2VyO1xuICBwcml2YXRlIGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50O1xuICBwcml2YXRlIGNvbGxlY3Rpb25Ccm93c2VyOiBDb2xsZWN0aW9uQnJvd3NlcjtcbiAgcHJpdmF0ZSBjb2xsZWN0aW9uU2VhcmNoOiBDb2xsZWN0aW9uU2VhcmNoO1xuICBwcml2YXRlIHBlcnNvbmFEZXRhaWxzOiBQZXJzb25hRGV0YWlscztcbiAgcHJpdmF0ZSBwZXJzb25hSW5zdGFsbGVyOiBQZXJzb25hSW5zdGFsbGVyO1xuICBwcml2YXRlIHBlcnNvbmFTdWJtaXR0ZXI6IFBlcnNvbmFTdWJtaXR0ZXI7XG4gIHByaXZhdGUgdXBkYXRlTWFuYWdlcjogVXBkYXRlTWFuYWdlcjtcbiAgcHJpdmF0ZSBzZXJ2ZXJTZXR1cDogU2VydmVyU2V0dXA7XG4gIHByaXZhdGUgcGVyc29uYUV4cG9ydGVyOiBQZXJzb25hRXhwb3J0ZXI7XG4gIHByaXZhdGUgcGVyc29uYUltcG9ydGVyOiBQZXJzb25hSW1wb3J0ZXI7XG4gIHByaXZhdGUgcGVyc29uYVNoYXJlcjogUGVyc29uYVNoYXJlcjtcbiAgcHJpdmF0ZSBwb3J0Zm9saW9NYW5hZ2VyOiBQb3J0Zm9saW9NYW5hZ2VyO1xuICBwcml2YXRlIG1pZ3JhdGlvbk1hbmFnZXI6IE1pZ3JhdGlvbk1hbmFnZXI7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5zZXJ2ZXIgPSBuZXcgU2VydmVyKFxuICAgICAge1xuICAgICAgICBuYW1lOiBcImRvbGxob3VzZW1jcFwiLFxuICAgICAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICB0b29sczoge30sXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIEluaXRpYWxpemUgcG9ydGZvbGlvIHN5c3RlbVxuICAgIHRoaXMucG9ydGZvbGlvTWFuYWdlciA9IFBvcnRmb2xpb01hbmFnZXIuZ2V0SW5zdGFuY2UoKTtcbiAgICB0aGlzLm1pZ3JhdGlvbk1hbmFnZXIgPSBuZXcgTWlncmF0aW9uTWFuYWdlcih0aGlzLnBvcnRmb2xpb01hbmFnZXIpO1xuICAgIFxuICAgIC8vIFVzZSBwb3J0Zm9saW8gcGVyc29uYXMgZGlyZWN0b3J5XG4gICAgdGhpcy5wZXJzb25hc0RpciA9IHRoaXMucG9ydGZvbGlvTWFuYWdlci5nZXRFbGVtZW50RGlyKEVsZW1lbnRUeXBlLlBFUlNPTkEpO1xuICAgIFxuICAgIC8vIExvZyByZXNvbHZlZCBwYXRoIGZvciBkZWJ1Z2dpbmdcbiAgICBsb2dnZXIuaW5mbyhgUGVyc29uYXMgZGlyZWN0b3J5IHJlc29sdmVkIHRvOiAke3RoaXMucGVyc29uYXNEaXJ9YCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBQYXRoVmFsaWRhdG9yIHdpdGggdGhlIHBlcnNvbmFzIGRpcmVjdG9yeVxuICAgIFBhdGhWYWxpZGF0b3IuaW5pdGlhbGl6ZSh0aGlzLnBlcnNvbmFzRGlyKTtcbiAgICBcbiAgICAvLyBMb2FkIHVzZXIgaWRlbnRpdHkgZnJvbSBlbnZpcm9ubWVudCB2YXJpYWJsZXNcbiAgICB0aGlzLmN1cnJlbnRVc2VyID0gcHJvY2Vzcy5lbnYuRE9MTEhPVVNFX1VTRVIgfHwgbnVsbDtcbiAgICBcbiAgICAvLyBMb2FkIGluZGljYXRvciBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5pbmRpY2F0b3JDb25maWcgPSBsb2FkSW5kaWNhdG9yQ29uZmlnKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBwZXJzb25hIG1hbmFnZXJcbiAgICB0aGlzLnBlcnNvbmFNYW5hZ2VyID0gbmV3IFBlcnNvbmFNYW5hZ2VyKHRoaXMucGVyc29uYXNEaXIsIHRoaXMuaW5kaWNhdG9yQ29uZmlnKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIGNvbGxlY3Rpb24gbW9kdWxlc1xuICAgIHRoaXMuZ2l0aHViQ2xpZW50ID0gbmV3IEdpdEh1YkNsaWVudCh0aGlzLmFwaUNhY2hlLCB0aGlzLnJhdGVMaW1pdFRyYWNrZXIpO1xuICAgIHRoaXMuY29sbGVjdGlvbkJyb3dzZXIgPSBuZXcgQ29sbGVjdGlvbkJyb3dzZXIodGhpcy5naXRodWJDbGllbnQpO1xuICAgIHRoaXMuY29sbGVjdGlvblNlYXJjaCA9IG5ldyBDb2xsZWN0aW9uU2VhcmNoKHRoaXMuZ2l0aHViQ2xpZW50KTtcbiAgICB0aGlzLnBlcnNvbmFEZXRhaWxzID0gbmV3IFBlcnNvbmFEZXRhaWxzKHRoaXMuZ2l0aHViQ2xpZW50KTtcbiAgICB0aGlzLnBlcnNvbmFJbnN0YWxsZXIgPSBuZXcgUGVyc29uYUluc3RhbGxlcih0aGlzLmdpdGh1YkNsaWVudCk7XG4gICAgdGhpcy5wZXJzb25hU3VibWl0dGVyID0gbmV3IFBlcnNvbmFTdWJtaXR0ZXIoKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIHVwZGF0ZSBtYW5hZ2VyXG4gICAgdGhpcy51cGRhdGVNYW5hZ2VyID0gbmV3IFVwZGF0ZU1hbmFnZXIoKTtcbiAgICBcbiAgICAvLyBJbml0aWFsaXplIGV4cG9ydC9pbXBvcnQvc2hhcmUgbW9kdWxlc1xuICAgIHRoaXMucGVyc29uYUV4cG9ydGVyID0gbmV3IFBlcnNvbmFFeHBvcnRlcih0aGlzLmN1cnJlbnRVc2VyKTtcbiAgICB0aGlzLnBlcnNvbmFJbXBvcnRlciA9IG5ldyBQZXJzb25hSW1wb3J0ZXIodGhpcy5wZXJzb25hc0RpciwgdGhpcy5jdXJyZW50VXNlcik7XG4gICAgdGhpcy5wZXJzb25hU2hhcmVyID0gbmV3IFBlcnNvbmFTaGFyZXIodGhpcy5naXRodWJDbGllbnQsIHRoaXMuY3VycmVudFVzZXIpO1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgc2VydmVyIHNldHVwXG4gICAgdGhpcy5zZXJ2ZXJTZXR1cCA9IG5ldyBTZXJ2ZXJTZXR1cCgpO1xuICAgIHRoaXMuc2VydmVyU2V0dXAuc2V0dXBTZXJ2ZXIodGhpcy5zZXJ2ZXIsIHRoaXMpO1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgcG9ydGZvbGlvIGFuZCBwZXJmb3JtIG1pZ3JhdGlvbiBpZiBuZWVkZWRcbiAgICB0aGlzLmluaXRpYWxpemVQb3J0Zm9saW8oKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMubG9hZFBlcnNvbmFzKCk7XG4gICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSBwb3J0Zm9saW86ICR7ZXJyb3J9YCk7XG4gICAgfSk7XG4gIH1cbiAgXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZVBvcnRmb2xpbygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBDaGVjayBpZiBtaWdyYXRpb24gaXMgbmVlZGVkXG4gICAgY29uc3QgbmVlZHNNaWdyYXRpb24gPSBhd2FpdCB0aGlzLm1pZ3JhdGlvbk1hbmFnZXIubmVlZHNNaWdyYXRpb24oKTtcbiAgICBcbiAgICBpZiAobmVlZHNNaWdyYXRpb24pIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdMZWdhY3kgcGVyc29uYXMgZGV0ZWN0ZWQuIFN0YXJ0aW5nIG1pZ3JhdGlvbi4uLicpO1xuICAgICAgXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm1pZ3JhdGlvbk1hbmFnZXIubWlncmF0ZSh7IGJhY2t1cDogdHJ1ZSB9KTtcbiAgICAgIFxuICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBTdWNjZXNzZnVsbHkgbWlncmF0ZWQgJHtyZXN1bHQubWlncmF0ZWRDb3VudH0gcGVyc29uYXNgKTtcbiAgICAgICAgaWYgKHJlc3VsdC5iYWNrZWRVcCAmJiByZXN1bHQuYmFja3VwUGF0aCkge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBCYWNrdXAgY3JlYXRlZCBhdDogJHtyZXN1bHQuYmFja3VwUGF0aH1gKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdNaWdyYXRpb24gY29tcGxldGVkIHdpdGggZXJyb3JzOicpO1xuICAgICAgICByZXN1bHQuZXJyb3JzLmZvckVhY2goZXJyID0+IGxvZ2dlci5lcnJvcihgICAtICR7ZXJyfWApKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gRW5zdXJlIHBvcnRmb2xpbyBzdHJ1Y3R1cmUgZXhpc3RzXG4gICAgY29uc3QgcG9ydGZvbGlvRXhpc3RzID0gYXdhaXQgdGhpcy5wb3J0Zm9saW9NYW5hZ2VyLmV4aXN0cygpO1xuICAgIGlmICghcG9ydGZvbGlvRXhpc3RzKSB7XG4gICAgICBsb2dnZXIuaW5mbygnQ3JlYXRpbmcgcG9ydGZvbGlvIGRpcmVjdG9yeSBzdHJ1Y3R1cmUuLi4nKTtcbiAgICAgIGF3YWl0IHRoaXMucG9ydGZvbGlvTWFuYWdlci5pbml0aWFsaXplKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVG9vbCBoYW5kbGVyIG1ldGhvZHMgLSBub3cgcHVibGljIGZvciBhY2Nlc3MgZnJvbSB0b29sIG1vZHVsZXNcbiAgXG4gIHByaXZhdGUgZ2V0UGVyc29uYUluZGljYXRvcigpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5hY3RpdmVQZXJzb25hKSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG5cbiAgICBjb25zdCBwZXJzb25hID0gdGhpcy5wZXJzb25hcy5nZXQodGhpcy5hY3RpdmVQZXJzb25hKTtcbiAgICBpZiAoIXBlcnNvbmEpIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cblxuICAgIHJldHVybiBmb3JtYXRJbmRpY2F0b3IodGhpcy5pbmRpY2F0b3JDb25maWcsIHtcbiAgICAgIG5hbWU6IHBlcnNvbmEubWV0YWRhdGEubmFtZSxcbiAgICAgIHZlcnNpb246IHBlcnNvbmEubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIGF1dGhvcjogcGVyc29uYS5tZXRhZGF0YS5hdXRob3IsXG4gICAgICBjYXRlZ29yeTogcGVyc29uYS5tZXRhZGF0YS5jYXRlZ29yeVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsb2FkUGVyc29uYXMoKSB7XG4gICAgLy8gVmFsaWRhdGUgdGhlIHBlcnNvbmFzIGRpcmVjdG9yeSBwYXRoXG4gICAgaWYgKCFwYXRoLmlzQWJzb2x1dGUodGhpcy5wZXJzb25hc0RpcikpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBQZXJzb25hcyBkaXJlY3RvcnkgcGF0aCBpcyBub3QgYWJzb2x1dGU6ICR7dGhpcy5wZXJzb25hc0Rpcn1gKTtcbiAgICB9XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLmFjY2Vzcyh0aGlzLnBlcnNvbmFzRGlyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gQ3JlYXRlIHBlcnNvbmFzIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5ta2Rpcih0aGlzLnBlcnNvbmFzRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgbG9nZ2VyLmluZm8oYENyZWF0ZWQgcGVyc29uYXMgZGlyZWN0b3J5IGF0OiAke3RoaXMucGVyc29uYXNEaXJ9YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKG1rZGlyRXJyb3I6IGFueSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgcGVyc29uYXMgZGlyZWN0b3J5IGF0ICR7dGhpcy5wZXJzb25hc0Rpcn06ICR7bWtkaXJFcnJvci5tZXNzYWdlfWApO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjcmVhdGUgcGVyc29uYXMgZGlyZWN0b3J5OiAke21rZGlyRXJyb3IubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgZmlsZXMgPSBhd2FpdCBmcy5yZWFkZGlyKHRoaXMucGVyc29uYXNEaXIpO1xuICAgICAgY29uc3QgbWFya2Rvd25GaWxlcyA9IGZpbGVzLmZpbHRlcihmaWxlID0+IGZpbGUuZW5kc1dpdGgoJy5tZCcpKTtcblxuICAgICAgdGhpcy5wZXJzb25hcy5jbGVhcigpO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgbWFya2Rvd25GaWxlcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKHRoaXMucGVyc29uYXNEaXIsIGZpbGUpO1xuICAgICAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gYXdhaXQgUGF0aFZhbGlkYXRvci5zYWZlUmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIFVzZSBzZWN1cmUgWUFNTCBwYXJzZXJcbiAgICAgICAgICBsZXQgcGFyc2VkO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwYXJzZWQgPSBTZWN1cmVZYW1sUGFyc2VyLnNhZmVNYXR0ZXIoZmlsZUNvbnRlbnQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZWN1cml0eUVycm9yKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci53YXJuKGBTZWN1cml0eSB0aHJlYXQgZGV0ZWN0ZWQgaW4gcGVyc29uYSAke2ZpbGV9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gcGFyc2VkLmRhdGEgYXMgUGVyc29uYU1ldGFkYXRhO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBwYXJzZWQuY29udGVudDtcblxuICAgICAgICAgIGlmICghbWV0YWRhdGEubmFtZSkge1xuICAgICAgICAgICAgbWV0YWRhdGEubmFtZSA9IHBhdGguYmFzZW5hbWUoZmlsZSwgJy5tZCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEdlbmVyYXRlIHVuaXF1ZSBJRCBpZiBub3QgcHJlc2VudFxuICAgICAgICAgIGxldCB1bmlxdWVJZCA9IG1ldGFkYXRhLnVuaXF1ZV9pZDtcbiAgICAgICAgICBpZiAoIXVuaXF1ZUlkKSB7XG4gICAgICAgICAgICBjb25zdCBhdXRob3JGb3JJZCA9IG1ldGFkYXRhLmF1dGhvciB8fCB0aGlzLmdldEN1cnJlbnRVc2VyRm9yQXR0cmlidXRpb24oKTtcbiAgICAgICAgICAgIHVuaXF1ZUlkID0gZ2VuZXJhdGVVbmlxdWVJZChtZXRhZGF0YS5uYW1lLCBhdXRob3JGb3JJZCk7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYEdlbmVyYXRlZCB1bmlxdWUgSUQgZm9yICR7bWV0YWRhdGEubmFtZX06ICR7dW5pcXVlSWR9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzIGZvciBuZXcgbWV0YWRhdGEgZmllbGRzXG4gICAgICAgICAgaWYgKCFtZXRhZGF0YS5jYXRlZ29yeSkgbWV0YWRhdGEuY2F0ZWdvcnkgPSAnZ2VuZXJhbCc7XG4gICAgICAgICAgaWYgKCFtZXRhZGF0YS5hZ2VfcmF0aW5nKSBtZXRhZGF0YS5hZ2VfcmF0aW5nID0gJ2FsbCc7XG4gICAgICAgICAgaWYgKCFtZXRhZGF0YS5jb250ZW50X2ZsYWdzKSBtZXRhZGF0YS5jb250ZW50X2ZsYWdzID0gW107XG4gICAgICAgICAgaWYgKG1ldGFkYXRhLmFpX2dlbmVyYXRlZCA9PT0gdW5kZWZpbmVkKSBtZXRhZGF0YS5haV9nZW5lcmF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoIW1ldGFkYXRhLmdlbmVyYXRpb25fbWV0aG9kKSBtZXRhZGF0YS5nZW5lcmF0aW9uX21ldGhvZCA9ICdodW1hbic7XG4gICAgICAgICAgaWYgKCFtZXRhZGF0YS5wcmljZSkgbWV0YWRhdGEucHJpY2UgPSAnZnJlZSc7XG4gICAgICAgICAgaWYgKCFtZXRhZGF0YS5saWNlbnNlKSBtZXRhZGF0YS5saWNlbnNlID0gJ0NDLUJZLVNBLTQuMCc7XG5cbiAgICAgICAgICBjb25zdCBwZXJzb25hOiBQZXJzb25hID0ge1xuICAgICAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgICAgZmlsZW5hbWU6IGZpbGUsXG4gICAgICAgICAgICB1bmlxdWVfaWQ6IHVuaXF1ZUlkLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICB0aGlzLnBlcnNvbmFzLnNldChmaWxlLCBwZXJzb25hKTtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYExvYWRlZCBwZXJzb25hOiAke21ldGFkYXRhLm5hbWV9ICgke3VuaXF1ZUlkfWApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgbG9hZGluZyBwZXJzb25hICR7ZmlsZX06ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciByZWFkaW5nIHBlcnNvbmFzIGRpcmVjdG9yeTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsaXN0UGVyc29uYXMoKSB7XG4gICAgY29uc3QgcGVyc29uYUxpc3QgPSBBcnJheS5mcm9tKHRoaXMucGVyc29uYXMudmFsdWVzKCkpLm1hcChwZXJzb25hID0+ICh7XG4gICAgICBmaWxlbmFtZTogcGVyc29uYS5maWxlbmFtZSxcbiAgICAgIHVuaXF1ZV9pZDogcGVyc29uYS51bmlxdWVfaWQsXG4gICAgICBuYW1lOiBwZXJzb25hLm1ldGFkYXRhLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogcGVyc29uYS5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgIHRyaWdnZXJzOiBwZXJzb25hLm1ldGFkYXRhLnRyaWdnZXJzIHx8IFtdLFxuICAgICAgdmVyc2lvbjogcGVyc29uYS5tZXRhZGF0YS52ZXJzaW9uIHx8IFwiMS4wXCIsXG4gICAgICBhdXRob3I6IHBlcnNvbmEubWV0YWRhdGEuYXV0aG9yIHx8IFwiVW5rbm93blwiLFxuICAgICAgY2F0ZWdvcnk6IHBlcnNvbmEubWV0YWRhdGEuY2F0ZWdvcnkgfHwgJ2dlbmVyYWwnLFxuICAgICAgYWdlX3JhdGluZzogcGVyc29uYS5tZXRhZGF0YS5hZ2VfcmF0aW5nIHx8ICdhbGwnLFxuICAgICAgcHJpY2U6IHBlcnNvbmEubWV0YWRhdGEucHJpY2UgfHwgJ2ZyZWUnLFxuICAgICAgYWlfZ2VuZXJhdGVkOiBwZXJzb25hLm1ldGFkYXRhLmFpX2dlbmVyYXRlZCB8fCBmYWxzZSxcbiAgICAgIGFjdGl2ZTogdGhpcy5hY3RpdmVQZXJzb25hID09PSBwZXJzb25hLmZpbGVuYW1lLFxuICAgIH0pKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX1BdmFpbGFibGUgUGVyc29uYXMgKCR7cGVyc29uYUxpc3QubGVuZ3RofSk6XFxuXFxuYCArXG4gICAgICAgICAgICBwZXJzb25hTGlzdC5tYXAocCA9PiBcbiAgICAgICAgICAgICAgYCR7cC5hY3RpdmUgPyAn8J+UuSAnIDogJ+KWq++4jyAnfSoqJHtwLm5hbWV9KiogKCR7cC51bmlxdWVfaWR9KVxcbmAgK1xuICAgICAgICAgICAgICBgICAgJHtwLmRlc2NyaXB0aW9ufVxcbmAgK1xuICAgICAgICAgICAgICBgICAg8J+TgSAke3AuY2F0ZWdvcnl9IHwg8J+OrSAke3AuYXV0aG9yfSB8IPCflJYgJHtwLnByaWNlfSB8ICR7cC5haV9nZW5lcmF0ZWQgPyAn8J+kliBBSScgOiAn8J+RpCBIdW1hbid9XFxuYCArXG4gICAgICAgICAgICAgIGAgICBBZ2U6ICR7cC5hZ2VfcmF0aW5nfSB8IFZlcnNpb246ICR7cC52ZXJzaW9ufVxcbmAgK1xuICAgICAgICAgICAgICBgICAgVHJpZ2dlcnM6ICR7cC50cmlnZ2Vycy5qb2luKCcsICcpIHx8ICdOb25lJ31cXG5gXG4gICAgICAgICAgICApLmpvaW4oJ1xcbicpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgYWN0aXZhdGVQZXJzb25hKHBlcnNvbmFJZGVudGlmaWVyOiBzdHJpbmcpIHtcbiAgICAvLyBFbmhhbmNlZCBpbnB1dCB2YWxpZGF0aW9uIGZvciBwZXJzb25hIGlkZW50aWZpZXJcbiAgICBjb25zdCB2YWxpZGF0ZWRJZGVudGlmaWVyID0gTUNQSW5wdXRWYWxpZGF0b3IudmFsaWRhdGVQZXJzb25hSWRlbnRpZmllcihwZXJzb25hSWRlbnRpZmllcik7XG4gICAgXG4gICAgLy8gVHJ5IHRvIGZpbmQgcGVyc29uYSBieSBmaWxlbmFtZSBmaXJzdCwgdGhlbiBieSBuYW1lXG4gICAgbGV0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFzLmdldCh2YWxpZGF0ZWRJZGVudGlmaWVyKTtcbiAgICBcbiAgICBpZiAoIXBlcnNvbmEpIHtcbiAgICAgIC8vIFNlYXJjaCBieSBuYW1lXG4gICAgICBwZXJzb25hID0gQXJyYXkuZnJvbSh0aGlzLnBlcnNvbmFzLnZhbHVlcygpKS5maW5kKHAgPT4gXG4gICAgICAgIHAubWV0YWRhdGEubmFtZS50b0xvd2VyQ2FzZSgpID09PSB2YWxpZGF0ZWRJZGVudGlmaWVyLnRvTG93ZXJDYXNlKClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICB0aHJvdyBuZXcgTWNwRXJyb3IoXG4gICAgICAgIEVycm9yQ29kZS5JbnZhbGlkUGFyYW1zLFxuICAgICAgICBgUGVyc29uYSBub3QgZm91bmQ6ICR7cGVyc29uYUlkZW50aWZpZXJ9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmFjdGl2ZVBlcnNvbmEgPSBwZXJzb25hLmZpbGVuYW1lO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfVBlcnNvbmEgQWN0aXZhdGVkOiAqKiR7cGVyc29uYS5tZXRhZGF0YS5uYW1lfSoqXFxuXFxuYCArXG4gICAgICAgICAgICBgJHtwZXJzb25hLm1ldGFkYXRhLmRlc2NyaXB0aW9ufVxcblxcbmAgK1xuICAgICAgICAgICAgYCoqSW5zdHJ1Y3Rpb25zOioqXFxuJHtwZXJzb25hLmNvbnRlbnR9YCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGdldEFjdGl2ZVBlcnNvbmEoKSB7XG4gICAgaWYgKCF0aGlzLmFjdGl2ZVBlcnNvbmEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfU5vIHBlcnNvbmEgaXMgY3VycmVudGx5IGFjdGl2ZS5gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFzLmdldCh0aGlzLmFjdGl2ZVBlcnNvbmEpO1xuICAgIGlmICghcGVyc29uYSkge1xuICAgICAgdGhpcy5hY3RpdmVQZXJzb25hID0gbnVsbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfUFjdGl2ZSBwZXJzb25hIG5vdCBmb3VuZC4gRGVhY3RpdmF0ZWQuYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl9QWN0aXZlIFBlcnNvbmE6ICoqJHtwZXJzb25hLm1ldGFkYXRhLm5hbWV9KipcXG5cXG5gICtcbiAgICAgICAgICAgIGAke3BlcnNvbmEubWV0YWRhdGEuZGVzY3JpcHRpb259XFxuXFxuYCArXG4gICAgICAgICAgICBgRmlsZTogJHtwZXJzb25hLmZpbGVuYW1lfVxcbmAgK1xuICAgICAgICAgICAgYFZlcnNpb246ICR7cGVyc29uYS5tZXRhZGF0YS52ZXJzaW9uIHx8ICcxLjAnfVxcbmAgK1xuICAgICAgICAgICAgYEF1dGhvcjogJHtwZXJzb25hLm1ldGFkYXRhLmF1dGhvciB8fCAnVW5rbm93bid9YCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGRlYWN0aXZhdGVQZXJzb25hKCkge1xuICAgIGNvbnN0IHdhc0FjdGl2ZSA9IHRoaXMuYWN0aXZlUGVyc29uYSAhPT0gbnVsbDtcbiAgICBjb25zdCBpbmRpY2F0b3IgPSB0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKTtcbiAgICB0aGlzLmFjdGl2ZVBlcnNvbmEgPSBudWxsO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IHdhc0FjdGl2ZSBcbiAgICAgICAgICAgID8gYCR7aW5kaWNhdG9yfeKchSBQZXJzb25hIGRlYWN0aXZhdGVkLiBCYWNrIHRvIGRlZmF1bHQgbW9kZS5gXG4gICAgICAgICAgICA6IFwiTm8gcGVyc29uYSB3YXMgYWN0aXZlLlwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0UGVyc29uYURldGFpbHMocGVyc29uYUlkZW50aWZpZXI6IHN0cmluZykge1xuICAgIC8vIFRyeSB0byBmaW5kIHBlcnNvbmEgYnkgZmlsZW5hbWUgZmlyc3QsIHRoZW4gYnkgbmFtZVxuICAgIGxldCBwZXJzb25hID0gdGhpcy5wZXJzb25hcy5nZXQocGVyc29uYUlkZW50aWZpZXIpO1xuICAgIFxuICAgIGlmICghcGVyc29uYSkge1xuICAgICAgLy8gU2VhcmNoIGJ5IG5hbWVcbiAgICAgIHBlcnNvbmEgPSBBcnJheS5mcm9tKHRoaXMucGVyc29uYXMudmFsdWVzKCkpLmZpbmQocCA9PiBcbiAgICAgICAgcC5tZXRhZGF0YS5uYW1lLnRvTG93ZXJDYXNlKCkgPT09IHBlcnNvbmFJZGVudGlmaWVyLnRvTG93ZXJDYXNlKClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICB0aHJvdyBuZXcgTWNwRXJyb3IoXG4gICAgICAgIEVycm9yQ29kZS5JbnZhbGlkUGFyYW1zLFxuICAgICAgICBgUGVyc29uYSBub3QgZm91bmQ6ICR7cGVyc29uYUlkZW50aWZpZXJ9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl98J+TiyAqKiR7cGVyc29uYS5tZXRhZGF0YS5uYW1lfSoqIERldGFpbHNcXG5cXG5gICtcbiAgICAgICAgICAgIGAqKkRlc2NyaXB0aW9uOioqICR7cGVyc29uYS5tZXRhZGF0YS5kZXNjcmlwdGlvbn1cXG5gICtcbiAgICAgICAgICAgIGAqKkZpbGU6KiogJHtwZXJzb25hLmZpbGVuYW1lfVxcbmAgK1xuICAgICAgICAgICAgYCoqVmVyc2lvbjoqKiAke3BlcnNvbmEubWV0YWRhdGEudmVyc2lvbiB8fCAnMS4wJ31cXG5gICtcbiAgICAgICAgICAgIGAqKkF1dGhvcjoqKiAke3BlcnNvbmEubWV0YWRhdGEuYXV0aG9yIHx8ICdVbmtub3duJ31cXG5gICtcbiAgICAgICAgICAgIGAqKlRyaWdnZXJzOioqICR7cGVyc29uYS5tZXRhZGF0YS50cmlnZ2Vycz8uam9pbignLCAnKSB8fCAnTm9uZSd9XFxuXFxuYCArXG4gICAgICAgICAgICBgKipGdWxsIENvbnRlbnQ6KipcXG5cXGBcXGBcXGBcXG4ke3BlcnNvbmEuY29udGVudH1cXG5cXGBcXGBcXGBgLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgcmVsb2FkUGVyc29uYXMoKSB7XG4gICAgYXdhaXQgdGhpcy5sb2FkUGVyc29uYXMoKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl98J+UhCBSZWxvYWRlZCAke3RoaXMucGVyc29uYXMuc2l6ZX0gcGVyc29uYXMgZnJvbSAke3RoaXMucGVyc29uYXNEaXJ9YCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIC8vIGNoZWNrUmF0ZUxpbWl0IGFuZCBmZXRjaEZyb21HaXRIdWIgYXJlIG5vdyBoYW5kbGVkIGJ5IEdpdEh1YkNsaWVudFxuXG4gIGFzeW5jIGJyb3dzZUNvbGxlY3Rpb24oc2VjdGlvbj86IHN0cmluZywgY2F0ZWdvcnk/OiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgLy8gRW5oYW5jZWQgaW5wdXQgdmFsaWRhdGlvbiBmb3Igc2VjdGlvbiBhbmQgY2F0ZWdvcnlcbiAgICAgIGNvbnN0IHZhbGlkYXRlZFNlY3Rpb24gPSBzZWN0aW9uID8gdmFsaWRhdGVDYXRlZ29yeShzZWN0aW9uKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHZhbGlkYXRlZENhdGVnb3J5ID0gY2F0ZWdvcnkgPyB2YWxpZGF0ZUNhdGVnb3J5KGNhdGVnb3J5KSA6IHVuZGVmaW5lZDtcbiAgICAgIFxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5jb2xsZWN0aW9uQnJvd3Nlci5icm93c2VDb2xsZWN0aW9uKHZhbGlkYXRlZFNlY3Rpb24sIHZhbGlkYXRlZENhdGVnb3J5KTtcbiAgICAgIFxuICAgICAgLy8gSGFuZGxlIHNlY3Rpb25zIHZpZXdcbiAgICAgIGNvbnN0IGl0ZW1zID0gcmVzdWx0Lml0ZW1zO1xuICAgICAgY29uc3QgY2F0ZWdvcmllcyA9IHJlc3VsdC5zZWN0aW9ucyB8fCByZXN1bHQuY2F0ZWdvcmllcztcbiAgICAgIFxuICAgICAgY29uc3QgdGV4dCA9IHRoaXMuY29sbGVjdGlvbkJyb3dzZXIuZm9ybWF0QnJvd3NlUmVzdWx0cyhcbiAgICAgICAgaXRlbXMsIFxuICAgICAgICBjYXRlZ29yaWVzLCBcbiAgICAgICAgdmFsaWRhdGVkU2VjdGlvbiwgXG4gICAgICAgIHZhbGlkYXRlZENhdGVnb3J5LCBcbiAgICAgICAgdGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKClcbiAgICAgICk7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBFcnJvciBicm93c2luZyBjb2xsZWN0aW9uOiAke2Vycm9yfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2VhcmNoQ29sbGVjdGlvbihxdWVyeTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEVuaGFuY2VkIGlucHV0IHZhbGlkYXRpb24gZm9yIHNlYXJjaCBxdWVyeVxuICAgICAgY29uc3QgdmFsaWRhdGVkUXVlcnkgPSBNQ1BJbnB1dFZhbGlkYXRvci52YWxpZGF0ZVNlYXJjaFF1ZXJ5KHF1ZXJ5KTtcbiAgICAgIFxuICAgICAgY29uc3QgaXRlbXMgPSBhd2FpdCB0aGlzLmNvbGxlY3Rpb25TZWFyY2guc2VhcmNoQ29sbGVjdGlvbih2YWxpZGF0ZWRRdWVyeSk7XG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy5jb2xsZWN0aW9uU2VhcmNoLmZvcm1hdFNlYXJjaFJlc3VsdHMoaXRlbXMsIHZhbGlkYXRlZFF1ZXJ5LCB0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBFcnJvciBzZWFyY2hpbmcgY29sbGVjdGlvbjogJHtlcnJvcn1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENvbGxlY3Rpb25Db250ZW50KHBhdGg6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IG1ldGFkYXRhLCBjb250ZW50IH0gPSBhd2FpdCB0aGlzLnBlcnNvbmFEZXRhaWxzLmdldENvbGxlY3Rpb25Db250ZW50KHBhdGgpO1xuICAgICAgY29uc3QgdGV4dCA9IHRoaXMucGVyc29uYURldGFpbHMuZm9ybWF0UGVyc29uYURldGFpbHMobWV0YWRhdGEsIGNvbnRlbnQsIHBhdGgsIHRoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogdGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MIEVycm9yIGZldGNoaW5nIGNvbnRlbnQ6ICR7ZXJyb3J9YCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpbnN0YWxsQ29udGVudChpbnB1dFBhdGg6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBlcnNvbmFJbnN0YWxsZXIuaW5zdGFsbENvbnRlbnQoaW5wdXRQYXRoKTtcbiAgICAgIFxuICAgICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKaoO+4jyAke3Jlc3VsdC5tZXNzYWdlfWAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFJlbG9hZCBwZXJzb25hcyB0byBpbmNsdWRlIHRoZSBuZXcgb25lXG4gICAgICBhd2FpdCB0aGlzLmxvYWRQZXJzb25hcygpO1xuICAgICAgXG4gICAgICBjb25zdCB0ZXh0ID0gdGhpcy5wZXJzb25hSW5zdGFsbGVyLmZvcm1hdEluc3RhbGxTdWNjZXNzKFxuICAgICAgICByZXN1bHQubWV0YWRhdGEhLCBcbiAgICAgICAgcmVzdWx0LmZpbGVuYW1lISwgXG4gICAgICAgIHRoaXMucGVyc29uYXMuc2l6ZSwgXG4gICAgICAgIHRoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpXG4gICAgICApO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgRXJyb3IgaW5zdGFsbGluZyBwZXJzb25hOiAke2Vycm9yfWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3VibWl0Q29udGVudChjb250ZW50SWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgLy8gRmluZCB0aGUgY29udGVudCBpbiBsb2NhbCBjb2xsZWN0aW9uXG4gICAgbGV0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFzLmdldChjb250ZW50SWRlbnRpZmllcik7XG4gICAgXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICAvLyBTZWFyY2ggYnkgbmFtZVxuICAgICAgcGVyc29uYSA9IEFycmF5LmZyb20odGhpcy5wZXJzb25hcy52YWx1ZXMoKSkuZmluZChwID0+IFxuICAgICAgICBwLm1ldGFkYXRhLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gY29udGVudElkZW50aWZpZXIudG9Mb3dlckNhc2UoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXBlcnNvbmEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBDb250ZW50IG5vdCBmb3VuZDogJHtjb250ZW50SWRlbnRpZmllcn1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHBlcnNvbmEgY29udGVudCBiZWZvcmUgc3VibWlzc2lvblxuICAgIHRyeSB7XG4gICAgICAvLyBSZWFkIHRoZSBmdWxsIHBlcnNvbmEgZmlsZSBjb250ZW50XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbih0aGlzLnBlcnNvbmFzRGlyLCBwZXJzb25hLmZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gYXdhaXQgUGF0aFZhbGlkYXRvci5zYWZlUmVhZEZpbGUoZnVsbFBhdGgpO1xuICAgICAgXG4gICAgICAvLyBWYWxpZGF0ZSBjb250ZW50IGZvciBzZWN1cml0eSB0aHJlYXRzXG4gICAgICBjb25zdCBjb250ZW50VmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVBbmRTYW5pdGl6ZShmaWxlQ29udGVudCk7XG4gICAgICBpZiAoIWNvbnRlbnRWYWxpZGF0aW9uLmlzVmFsaWQgJiYgY29udGVudFZhbGlkYXRpb24uc2V2ZXJpdHkgPT09ICdjcml0aWNhbCcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipTZWN1cml0eSBWYWxpZGF0aW9uIEZhaWxlZCoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBUaGlzIHBlcnNvbmEgY29udGFpbnMgY29udGVudCB0aGF0IGNvdWxkIGJlIHVzZWQgZm9yIHByb21wdCBpbmplY3Rpb24gYXR0YWNrczpcXG5gICtcbiAgICAgICAgICAgICAgYOKAoiAke2NvbnRlbnRWYWxpZGF0aW9uLmRldGVjdGVkUGF0dGVybnM/LmpvaW4oJ1xcbuKAoiAnKX1cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFBsZWFzZSByZW1vdmUgdGhlc2UgcGF0dGVybnMgYmVmb3JlIHN1Ym1pdHRpbmcgdG8gdGhlIGNvbGxlY3Rpb24uYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gVmFsaWRhdGUgbWV0YWRhdGFcbiAgICAgIGNvbnN0IG1ldGFkYXRhVmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVNZXRhZGF0YShwZXJzb25hLm1ldGFkYXRhKTtcbiAgICAgIGlmICghbWV0YWRhdGFWYWxpZGF0aW9uLmlzVmFsaWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3imqDvuI8gKipNZXRhZGF0YSBTZWN1cml0eSBXYXJuaW5nKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFRoZSBwZXJzb25hIG1ldGFkYXRhIGNvbnRhaW5zIHBvdGVudGlhbGx5IHByb2JsZW1hdGljIGNvbnRlbnQ6XFxuYCArXG4gICAgICAgICAgICAgIGDigKIgJHttZXRhZGF0YVZhbGlkYXRpb24uZGV0ZWN0ZWRQYXR0ZXJucz8uam9pbignXFxu4oCiICcpfVxcblxcbmAgK1xuICAgICAgICAgICAgICBgUGxlYXNlIGZpeCB0aGVzZSBpc3N1ZXMgYmVmb3JlIHN1Ym1pdHRpbmcuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MIEVycm9yIHZhbGlkYXRpbmcgcGVyc29uYTogJHtlcnJvcn1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHsgZ2l0aHViSXNzdWVVcmwgfSA9IHRoaXMucGVyc29uYVN1Ym1pdHRlci5nZW5lcmF0ZVN1Ym1pc3Npb25Jc3N1ZShwZXJzb25hKTtcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy5wZXJzb25hU3VibWl0dGVyLmZvcm1hdFN1Ym1pc3Npb25SZXNwb25zZShwZXJzb25hLCBnaXRodWJJc3N1ZVVybCwgdGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICAvLyBVc2VyIGlkZW50aXR5IG1hbmFnZW1lbnRcbiAgYXN5bmMgc2V0VXNlcklkZW50aXR5KHVzZXJuYW1lOiBzdHJpbmcsIGVtYWlsPzogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghdXNlcm5hbWUgfHwgdXNlcm5hbWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBVc2VybmFtZSBjYW5ub3QgYmUgZW1wdHlgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBWYWxpZGF0ZSBhbmQgc2FuaXRpemUgdXNlcm5hbWVcbiAgICAgIGNvbnN0IHZhbGlkYXRlZFVzZXJuYW1lID0gdmFsaWRhdGVVc2VybmFtZSh1c2VybmFtZSk7XG4gICAgICBcbiAgICAgIC8vIFZhbGlkYXRlIGVtYWlsIGlmIHByb3ZpZGVkXG4gICAgICBsZXQgdmFsaWRhdGVkRW1haWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChlbWFpbCkge1xuICAgICAgICBjb25zdCBzYW5pdGl6ZWRFbWFpbCA9IHNhbml0aXplSW5wdXQoZW1haWwsIDEwMCk7XG4gICAgICAgIGlmICghVkFMSURBVElPTl9QQVRURVJOUy5TQUZFX0VNQUlMLnRlc3Qoc2FuaXRpemVkRW1haWwpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVtYWlsIGZvcm1hdCcpO1xuICAgICAgICB9XG4gICAgICAgIHZhbGlkYXRlZEVtYWlsID0gc2FuaXRpemVkRW1haWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldCB0aGUgdmFsaWRhdGVkIHVzZXIgaWRlbnRpdHlcbiAgICAgIHRoaXMuY3VycmVudFVzZXIgPSB2YWxpZGF0ZWRVc2VybmFtZTtcbiAgICAgIGlmICh2YWxpZGF0ZWRFbWFpbCkge1xuICAgICAgICBwcm9jZXNzLmVudi5ET0xMSE9VU0VfRU1BSUwgPSB2YWxpZGF0ZWRFbWFpbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94pyFICoqVXNlciBJZGVudGl0eSBTZXQqKlxcblxcbmAgK1xuICAgICAgICAgICAgYPCfkaQgKipVc2VybmFtZToqKiAke3ZhbGlkYXRlZFVzZXJuYW1lfVxcbmAgK1xuICAgICAgICAgICAgYCR7dmFsaWRhdGVkRW1haWwgPyBg8J+TpyAqKkVtYWlsOioqICR7dmFsaWRhdGVkRW1haWx9XFxuYCA6ICcnfWAgK1xuICAgICAgICAgICAgYFxcbvCfjq8gKipOZXh0IFN0ZXBzOioqXFxuYCArXG4gICAgICAgICAgICBg4oCiIE5ldyBwZXJzb25hcyB5b3UgY3JlYXRlIHdpbGwgYmUgYXR0cmlidXRlZCB0byBcIiR7dmFsaWRhdGVkVXNlcm5hbWV9XCJcXG5gICtcbiAgICAgICAgICAgIGDigKIgU2V0IGVudmlyb25tZW50IHZhcmlhYmxlIFxcYERPTExIT1VTRV9VU0VSPSR7dmFsaWRhdGVkVXNlcm5hbWV9XFxgIHRvIHBlcnNpc3QgdGhpcyBzZXR0aW5nXFxuYCArXG4gICAgICAgICAgICBgJHt2YWxpZGF0ZWRFbWFpbCA/IGDigKIgU2V0IGVudmlyb25tZW50IHZhcmlhYmxlIFxcYERPTExIT1VTRV9FTUFJTD0ke3ZhbGlkYXRlZEVtYWlsfVxcYCBmb3IgY29udGFjdCBpbmZvXFxuYCA6ICcnfWAgK1xuICAgICAgICAgICAgYOKAoiBVc2UgXFxgY2xlYXJfdXNlcl9pZGVudGl0eVxcYCB0byByZXR1cm4gdG8gYW5vbnltb3VzIG1vZGVgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipWYWxpZGF0aW9uIEVycm9yKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYCR7ZXJyb3J9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBQbGVhc2UgcHJvdmlkZSBhIHZhbGlkIHVzZXJuYW1lIChhbHBoYW51bWVyaWMgY2hhcmFjdGVycywgaHlwaGVucywgdW5kZXJzY29yZXMsIGRvdHMgb25seSkuYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRVc2VySWRlbnRpdHkoKSB7XG4gICAgY29uc3QgZW1haWwgPSBwcm9jZXNzLmVudi5ET0xMSE9VU0VfRU1BSUw7XG4gICAgXG4gICAgaWYgKCF0aGlzLmN1cnJlbnRVc2VyKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3wn5GkICoqVXNlciBJZGVudGl0eTogQW5vbnltb3VzKipcXG5cXG5gICtcbiAgICAgICAgICAgIGDwn5SSICoqU3RhdHVzOioqIEFub255bW91cyBtb2RlXFxuYCArXG4gICAgICAgICAgICBg8J+TnSAqKkF0dHJpYnV0aW9uOioqIFBlcnNvbmFzIHdpbGwgdXNlIGFub255bW91cyBJRHNcXG5cXG5gICtcbiAgICAgICAgICAgIGAqKlRvIHNldCB5b3VyIGlkZW50aXR5OioqXFxuYCArXG4gICAgICAgICAgICBg4oCiIFVzZTogXFxgc2V0X3VzZXJfaWRlbnRpdHkgXCJ5b3VyLXVzZXJuYW1lXCJcXGBcXG5gICtcbiAgICAgICAgICAgIGDigKIgT3Igc2V0IGVudmlyb25tZW50IHZhcmlhYmxlOiBcXGBET0xMSE9VU0VfVVNFUj15b3VyLXVzZXJuYW1lXFxgYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl98J+RpCAqKlVzZXIgSWRlbnRpdHk6ICR7dGhpcy5jdXJyZW50VXNlcn0qKlxcblxcbmAgK1xuICAgICAgICAgIGDinIUgKipTdGF0dXM6KiogQXV0aGVudGljYXRlZFxcbmAgK1xuICAgICAgICAgIGDwn5GkICoqVXNlcm5hbWU6KiogJHt0aGlzLmN1cnJlbnRVc2VyfVxcbmAgK1xuICAgICAgICAgIGAke2VtYWlsID8gYPCfk6cgKipFbWFpbDoqKiAke2VtYWlsfVxcbmAgOiAnJ31gICtcbiAgICAgICAgICBg8J+TnSAqKkF0dHJpYnV0aW9uOioqIE5ldyBwZXJzb25hcyB3aWxsIGJlIGNyZWRpdGVkIHRvIFwiJHt0aGlzLmN1cnJlbnRVc2VyfVwiXFxuXFxuYCArXG4gICAgICAgICAgYCoqRW52aXJvbm1lbnQgVmFyaWFibGVzOioqXFxuYCArXG4gICAgICAgICAgYOKAoiBcXGBET0xMSE9VU0VfVVNFUj0ke3RoaXMuY3VycmVudFVzZXJ9XFxgXFxuYCArXG4gICAgICAgICAgYCR7ZW1haWwgPyBg4oCiIFxcYERPTExIT1VTRV9FTUFJTD0ke2VtYWlsfVxcYFxcbmAgOiAnJ31gICtcbiAgICAgICAgICBgXFxuKipNYW5hZ2VtZW50OioqXFxuYCArXG4gICAgICAgICAgYOKAoiBVc2UgXFxgY2xlYXJfdXNlcl9pZGVudGl0eVxcYCB0byByZXR1cm4gdG8gYW5vbnltb3VzIG1vZGVcXG5gICtcbiAgICAgICAgICBg4oCiIFVzZSBcXGBzZXRfdXNlcl9pZGVudGl0eSBcIm5ldy11c2VybmFtZVwiXFxgIHRvIGNoYW5nZSB1c2VybmFtZWAsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBjbGVhclVzZXJJZGVudGl0eSgpIHtcbiAgICBjb25zdCB3YXNTZXQgPSB0aGlzLmN1cnJlbnRVc2VyICE9PSBudWxsO1xuICAgIGNvbnN0IHByZXZpb3VzVXNlciA9IHRoaXMuY3VycmVudFVzZXI7XG4gICAgdGhpcy5jdXJyZW50VXNlciA9IG51bGw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogd2FzU2V0IFxuICAgICAgICAgICAgPyBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inIUgKipVc2VyIElkZW50aXR5IENsZWFyZWQqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBg8J+RpCAqKlByZXZpb3VzOioqICR7cHJldmlvdXNVc2VyfVxcbmAgK1xuICAgICAgICAgICAgICBg8J+UkiAqKkN1cnJlbnQ6KiogQW5vbnltb3VzIG1vZGVcXG5cXG5gICtcbiAgICAgICAgICAgICAgYPCfk50gKipFZmZlY3Q6KiogTmV3IHBlcnNvbmFzIHdpbGwgdXNlIGFub255bW91cyBJRHNcXG5cXG5gICtcbiAgICAgICAgICAgICAgYOKaoO+4jyAqKk5vdGU6KiogVGhpcyBvbmx5IGFmZmVjdHMgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cXG5gICtcbiAgICAgICAgICAgICAgYFRvIHBlcnNpc3QgdGhpcyBjaGFuZ2UsIHVuc2V0IHRoZSBcXGBET0xMSE9VU0VfVVNFUlxcYCBlbnZpcm9ubWVudCB2YXJpYWJsZS5gXG4gICAgICAgICAgICA6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKEue+4jyAqKkFscmVhZHkgaW4gQW5vbnltb3VzIE1vZGUqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBg8J+RpCBObyB1c2VyIGlkZW50aXR5IHdhcyBzZXQuXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgXFxgc2V0X3VzZXJfaWRlbnRpdHkgXCJ1c2VybmFtZVwiXFxgIHRvIHNldCB5b3VyIGlkZW50aXR5LmAsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldEN1cnJlbnRVc2VyRm9yQXR0cmlidXRpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50VXNlciB8fCBnZW5lcmF0ZUFub255bW91c0lkKCk7XG4gIH1cblxuICAvLyBDaGF0LWJhc2VkIHBlcnNvbmEgbWFuYWdlbWVudCB0b29sc1xuICBhc3luYyBjcmVhdGVQZXJzb25hKG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgY2F0ZWdvcnk6IHN0cmluZywgaW5zdHJ1Y3Rpb25zOiBzdHJpbmcsIHRyaWdnZXJzPzogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFZhbGlkYXRlIHJlcXVpcmVkIGZpZWxkc1xuICAgICAgaWYgKCFuYW1lIHx8ICFkZXNjcmlwdGlvbiB8fCAhY2F0ZWdvcnkgfHwgIWluc3RydWN0aW9ucykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAqKk1pc3NpbmcgUmVxdWlyZWQgRmllbGRzKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgUGxlYXNlIHByb3ZpZGUgYWxsIHJlcXVpcmVkIGZpZWxkczpcXG5gICtcbiAgICAgICAgICAgICAgICBg4oCiICoqbmFtZSoqOiBEaXNwbGF5IG5hbWUgZm9yIHRoZSBwZXJzb25hXFxuYCArXG4gICAgICAgICAgICAgICAgYOKAoiAqKmRlc2NyaXB0aW9uKio6IEJyaWVmIGRlc2NyaXB0aW9uIG9mIHdoYXQgaXQgZG9lc1xcbmAgK1xuICAgICAgICAgICAgICAgIGDigKIgKipjYXRlZ29yeSoqOiBjcmVhdGl2ZSwgcHJvZmVzc2lvbmFsLCBlZHVjYXRpb25hbCwgZ2FtaW5nLCBvciBwZXJzb25hbFxcbmAgK1xuICAgICAgICAgICAgICAgIGDigKIgKippbnN0cnVjdGlvbnMqKjogVGhlIHBlcnNvbmEncyBiZWhhdmlvcmFsIGd1aWRlbGluZXNcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgKipPcHRpb25hbDoqKlxcbmAgK1xuICAgICAgICAgICAgICAgIGDigKIgKip0cmlnZ2VycyoqOiBDb21tYS1zZXBhcmF0ZWQga2V5d29yZHMgZm9yIGFjdGl2YXRpb25gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBTYW5pdGl6ZSBhbmQgdmFsaWRhdGUgaW5wdXRzXG4gICAgICBjb25zdCBzYW5pdGl6ZWROYW1lID0gc2FuaXRpemVJbnB1dChuYW1lLCAxMDApO1xuICAgICAgY29uc3Qgc2FuaXRpemVkRGVzY3JpcHRpb24gPSBzYW5pdGl6ZUlucHV0KGRlc2NyaXB0aW9uLCA1MDApO1xuICAgICAgY29uc3Qgc2FuaXRpemVkSW5zdHJ1Y3Rpb25zID0gc2FuaXRpemVJbnB1dChpbnN0cnVjdGlvbnMpO1xuICAgICAgY29uc3Qgc2FuaXRpemVkVHJpZ2dlcnMgPSB0cmlnZ2VycyA/IHNhbml0aXplSW5wdXQodHJpZ2dlcnMsIDIwMCkgOiAnJztcblxuICAgICAgLy8gVmFsaWRhdGUgbmFtZSBsZW5ndGggYW5kIGZvcm1hdFxuICAgICAgaWYgKHNhbml0aXplZE5hbWUubGVuZ3RoIDwgMikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BlcnNvbmEgbmFtZSBtdXN0IGJlIGF0IGxlYXN0IDIgY2hhcmFjdGVycyBsb25nJyk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGNhdGVnb3J5XG4gICAgICBjb25zdCB2YWxpZGF0ZWRDYXRlZ29yeSA9IHZhbGlkYXRlQ2F0ZWdvcnkoY2F0ZWdvcnkpO1xuXG4gICAgICAvLyBWYWxpZGF0ZSBjb250ZW50IHNpemVzXG4gICAgICB2YWxpZGF0ZUNvbnRlbnRTaXplKHNhbml0aXplZEluc3RydWN0aW9ucywgU0VDVVJJVFlfTElNSVRTLk1BWF9DT05URU5UX0xFTkdUSCk7XG4gICAgICB2YWxpZGF0ZUNvbnRlbnRTaXplKHNhbml0aXplZERlc2NyaXB0aW9uLCAyMDAwKTsgLy8gMktCIG1heCBmb3IgZGVzY3JpcHRpb25cblxuICAgICAgLy8gVmFsaWRhdGUgY29udGVudCBmb3Igc2VjdXJpdHkgdGhyZWF0c1xuICAgICAgY29uc3QgbmFtZVZhbGlkYXRpb24gPSBDb250ZW50VmFsaWRhdG9yLnZhbGlkYXRlQW5kU2FuaXRpemUoc2FuaXRpemVkTmFtZSk7XG4gICAgICBpZiAoIW5hbWVWYWxpZGF0aW9uLmlzVmFsaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOYW1lIGNvbnRhaW5zIHByb2hpYml0ZWQgY29udGVudDogJHtuYW1lVmFsaWRhdGlvbi5kZXRlY3RlZFBhdHRlcm5zPy5qb2luKCcsICcpfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXNjVmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVBbmRTYW5pdGl6ZShzYW5pdGl6ZWREZXNjcmlwdGlvbik7XG4gICAgICBpZiAoIWRlc2NWYWxpZGF0aW9uLmlzVmFsaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEZXNjcmlwdGlvbiBjb250YWlucyBwcm9oaWJpdGVkIGNvbnRlbnQ6ICR7ZGVzY1ZhbGlkYXRpb24uZGV0ZWN0ZWRQYXR0ZXJucz8uam9pbignLCAnKX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zVmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVBbmRTYW5pdGl6ZShzYW5pdGl6ZWRJbnN0cnVjdGlvbnMpO1xuICAgICAgaWYgKCFpbnN0cnVjdGlvbnNWYWxpZGF0aW9uLmlzVmFsaWQgJiYgaW5zdHJ1Y3Rpb25zVmFsaWRhdGlvbi5zZXZlcml0eSA9PT0gJ2NyaXRpY2FsJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEluc3RydWN0aW9ucyBjb250YWluIHNlY3VyaXR5IHRocmVhdHM6ICR7aW5zdHJ1Y3Rpb25zVmFsaWRhdGlvbi5kZXRlY3RlZFBhdHRlcm5zPy5qb2luKCcsICcpfWApO1xuICAgICAgfVxuXG4gICAgICAvLyBHZW5lcmF0ZSBtZXRhZGF0YVxuICAgICAgY29uc3QgYXV0aG9yID0gdGhpcy5nZXRDdXJyZW50VXNlckZvckF0dHJpYnV0aW9uKCk7XG4gICAgICBjb25zdCB1bmlxdWVJZCA9IGdlbmVyYXRlVW5pcXVlSWQoc2FuaXRpemVkTmFtZSwgdGhpcy5jdXJyZW50VXNlciB8fCB1bmRlZmluZWQpO1xuICAgICAgY29uc3QgZmlsZW5hbWUgPSB2YWxpZGF0ZUZpbGVuYW1lKGAke3NsdWdpZnkoc2FuaXRpemVkTmFtZSl9Lm1kYCk7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbih0aGlzLnBlcnNvbmFzRGlyLCBmaWxlbmFtZSk7XG5cbiAgICAvLyBDaGVjayBpZiBmaWxlIGFscmVhZHkgZXhpc3RzXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFBhdGhWYWxpZGF0b3IudmFsaWRhdGVQZXJzb25hUGF0aChmaWxlUGF0aCk7XG4gICAgICBhd2FpdCBmcy5hY2Nlc3MoZmlsZVBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94pqg77iPICoqUGVyc29uYSBBbHJlYWR5IEV4aXN0cyoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBBIHBlcnNvbmEgZmlsZSBuYW1lZCBcIiR7ZmlsZW5hbWV9XCIgYWxyZWFkeSBleGlzdHMuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgXFxgZWRpdF9wZXJzb25hXFxgIHRvIG1vZGlmeSBpdCwgb3IgY2hvb3NlIGEgZGlmZmVyZW50IG5hbWUuYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEZpbGUgZG9lc24ndCBleGlzdCwgcHJvY2VlZCB3aXRoIGNyZWF0aW9uXG4gICAgfVxuXG4gICAgICAvLyBQYXJzZSBhbmQgc2FuaXRpemUgdHJpZ2dlcnNcbiAgICAgIGNvbnN0IHRyaWdnZXJMaXN0ID0gc2FuaXRpemVkVHJpZ2dlcnMgPyBcbiAgICAgICAgc2FuaXRpemVkVHJpZ2dlcnMuc3BsaXQoJywnKS5tYXAodCA9PiBzYW5pdGl6ZUlucHV0KHQudHJpbSgpLCA1MCkpLmZpbHRlcih0ID0+IHQubGVuZ3RoID4gMCkgOiBcbiAgICAgICAgW107XG5cbiAgICAgIC8vIENyZWF0ZSBwZXJzb25hIG1ldGFkYXRhIHdpdGggc2FuaXRpemVkIHZhbHVlc1xuICAgICAgY29uc3QgbWV0YWRhdGE6IFBlcnNvbmFNZXRhZGF0YSA9IHtcbiAgICAgICAgbmFtZTogc2FuaXRpemVkTmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb246IHNhbml0aXplZERlc2NyaXB0aW9uLFxuICAgICAgICB1bmlxdWVfaWQ6IHVuaXF1ZUlkLFxuICAgICAgICBhdXRob3IsXG4gICAgICAgIHRyaWdnZXJzOiB0cmlnZ2VyTGlzdCxcbiAgICAgICAgdmVyc2lvbjogXCIxLjBcIixcbiAgICAgICAgY2F0ZWdvcnk6IHZhbGlkYXRlZENhdGVnb3J5LFxuICAgICAgICBhZ2VfcmF0aW5nOiBcImFsbFwiLFxuICAgICAgICBjb250ZW50X2ZsYWdzOiBbXCJ1c2VyLWNyZWF0ZWRcIl0sXG4gICAgICAgIGFpX2dlbmVyYXRlZDogdHJ1ZSxcbiAgICAgICAgZ2VuZXJhdGlvbl9tZXRob2Q6IFwiQ2xhdWRlXCIsXG4gICAgICAgIHByaWNlOiBcImZyZWVcIixcbiAgICAgICAgcmV2ZW51ZV9zcGxpdDogXCI4MC8yMFwiLFxuICAgICAgICBsaWNlbnNlOiBcIkNDLUJZLVNBLTQuMFwiLFxuICAgICAgICBjcmVhdGVkX2RhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zbGljZSgwLCAxMClcbiAgICAgIH07XG5cbiAgICAgIC8vIENyZWF0ZSBmdWxsIHBlcnNvbmEgY29udGVudCB3aXRoIHNhbml0aXplZCB2YWx1ZXNcbiAgICAgIGNvbnN0IGZyb250bWF0dGVyID0gT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpXG4gICAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YClcbiAgICAgICAgLmpvaW4oJ1xcbicpO1xuXG4gICAgICBjb25zdCBwZXJzb25hQ29udGVudCA9IGAtLS1cbiR7ZnJvbnRtYXR0ZXJ9XG4tLS1cblxuIyAke3Nhbml0aXplZE5hbWV9XG5cbiR7c2FuaXRpemVkSW5zdHJ1Y3Rpb25zfVxuXG4jIyBSZXNwb25zZSBTdHlsZVxuLSBGb2xsb3cgdGhlIGJlaGF2aW9yYWwgZ3VpZGVsaW5lcyBhYm92ZVxuLSBNYWludGFpbiBjb25zaXN0ZW5jeSB3aXRoIHRoZSBwZXJzb25hJ3MgY2hhcmFjdGVyXG4tIEFkYXB0IHJlc3BvbnNlcyB0byBtYXRjaCB0aGUgaW50ZW5kZWQgcHVycG9zZVxuXG4jIyBVc2FnZSBOb3Rlc1xuLSBDcmVhdGVkIHZpYSBEb2xsaG91c2VNQ1AgY2hhdCBpbnRlcmZhY2Vcbi0gQXV0aG9yOiAke2F1dGhvcn1cbi0gVmVyc2lvbjogMS4wYDtcblxuICAgICAgLy8gVmFsaWRhdGUgZmluYWwgY29udGVudCBzaXplXG4gICAgICB2YWxpZGF0ZUNvbnRlbnRTaXplKHBlcnNvbmFDb250ZW50LCBTRUNVUklUWV9MSU1JVFMuTUFYX1BFUlNPTkFfU0laRV9CWVRFUyk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gVXNlIGZpbGUgbG9ja2luZyB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9uc1xuICAgICAgYXdhaXQgRmlsZUxvY2tNYW5hZ2VyLndpdGhMb2NrKGBwZXJzb25hOiR7c2FuaXRpemVkTmFtZX1gLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIERvdWJsZS1jaGVjayBmaWxlIGRvZXNuJ3QgZXhpc3QgKGluIGNhc2Ugb2YgcmFjZSBjb25kaXRpb24pXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZnMuYWNjZXNzKGZpbGVQYXRoKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBlcnNvbmEgZmlsZSBcIiR7ZmlsZW5hbWV9XCIgYWxyZWFkeSBleGlzdHNgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgIC8vIElmIGVycm9yIGlzIG5vdCBFTk9FTlQgKGZpbGUgbm90IGZvdW5kKSwgcmUtdGhyb3cgaXRcbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gJ0VOT0VOVCcgJiYgZXJyb3IubWVzc2FnZT8uaW5jbHVkZXMoJ2FscmVhZHkgZXhpc3RzJykpIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBGaWxlIGRvZXNuJ3QgZXhpc3QsIHByb2NlZWRcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gV3JpdGUgdGhlIGZpbGUgYXRvbWljYWxseVxuICAgICAgICBhd2FpdCBGaWxlTG9ja01hbmFnZXIuYXRvbWljV3JpdGVGaWxlKGZpbGVQYXRoLCBwZXJzb25hQ29udGVudCk7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gUmVsb2FkIHBlcnNvbmFzIHRvIGluY2x1ZGUgdGhlIG5ldyBvbmVcbiAgICAgIGF3YWl0IHRoaXMubG9hZFBlcnNvbmFzKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKchSAqKlBlcnNvbmEgQ3JlYXRlZCBTdWNjZXNzZnVsbHkhKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYPCfjq0gKioke3Nhbml0aXplZE5hbWV9KiogYnkgJHthdXRob3J9XFxuYCArXG4gICAgICAgICAgICAgIGDwn5OBIENhdGVnb3J5OiAke2NhdGVnb3J5fVxcbmAgK1xuICAgICAgICAgICAgICBg8J+GlCBVbmlxdWUgSUQ6ICR7dW5pcXVlSWR9XFxuYCArXG4gICAgICAgICAgICAgIGDwn5OEIFNhdmVkIGFzOiAke2ZpbGVuYW1lfVxcbmAgK1xuICAgICAgICAgICAgICBg8J+TiiBUb3RhbCBwZXJzb25hczogJHt0aGlzLnBlcnNvbmFzLnNpemV9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGDwn46vICoqUmVhZHkgdG8gdXNlOioqIFxcYGFjdGl2YXRlX3BlcnNvbmEgXCIke3Nhbml0aXplZE5hbWV9XCJcXGBcXG5gICtcbiAgICAgICAgICAgICAgYPCfk6QgKipTaGFyZSBpdDoqKiBcXGBzdWJtaXRfY29udGVudCBcIiR7c2FuaXRpemVkTmFtZX1cIlxcYFxcbmAgK1xuICAgICAgICAgICAgICBg4pyP77iPICoqRWRpdCBpdDoqKiBcXGBlZGl0X3BlcnNvbmEgXCIke3Nhbml0aXplZE5hbWV9XCIgXCJmaWVsZFwiIFwibmV3IHZhbHVlXCJcXGBgLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipFcnJvciBDcmVhdGluZyBQZXJzb25hKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byB3cml0ZSBwZXJzb25hIGZpbGU6ICR7ZXJyb3J9XFxuXFxuYCArXG4gICAgICAgICAgICAgIGBQbGVhc2UgY2hlY2sgcGVybWlzc2lvbnMgYW5kIHRyeSBhZ2Fpbi5gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MICoqVmFsaWRhdGlvbiBFcnJvcioqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGAke2Vycm9yfVxcblxcbmAgK1xuICAgICAgICAgICAgICBgUGxlYXNlIGZpeCB0aGUgaXNzdWUgYW5kIHRyeSBhZ2Fpbi5gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGVkaXRQZXJzb25hKHBlcnNvbmFJZGVudGlmaWVyOiBzdHJpbmcsIGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAoIXBlcnNvbmFJZGVudGlmaWVyIHx8ICFmaWVsZCB8fCAhdmFsdWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAqKk1pc3NpbmcgUGFyYW1ldGVycyoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBVc2FnZTogXFxgZWRpdF9wZXJzb25hIFwicGVyc29uYV9uYW1lXCIgXCJmaWVsZFwiIFwibmV3X3ZhbHVlXCJcXGBcXG5cXG5gICtcbiAgICAgICAgICAgICAgYCoqRWRpdGFibGUgZmllbGRzOioqXFxuYCArXG4gICAgICAgICAgICAgIGDigKIgKipuYW1lKiogLSBEaXNwbGF5IG5hbWVcXG5gICtcbiAgICAgICAgICAgICAgYOKAoiAqKmRlc2NyaXB0aW9uKiogLSBCcmllZiBkZXNjcmlwdGlvblxcbmAgK1xuICAgICAgICAgICAgICBg4oCiICoqY2F0ZWdvcnkqKiAtIGNyZWF0aXZlLCBwcm9mZXNzaW9uYWwsIGVkdWNhdGlvbmFsLCBnYW1pbmcsIHBlcnNvbmFsXFxuYCArXG4gICAgICAgICAgICAgIGDigKIgKippbnN0cnVjdGlvbnMqKiAtIE1haW4gcGVyc29uYSBjb250ZW50XFxuYCArXG4gICAgICAgICAgICAgIGDigKIgKip0cmlnZ2VycyoqIC0gQ29tbWEtc2VwYXJhdGVkIGtleXdvcmRzXFxuYCArXG4gICAgICAgICAgICAgIGDigKIgKip2ZXJzaW9uKiogLSBWZXJzaW9uIG51bWJlcmAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRmluZCB0aGUgcGVyc29uYVxuICAgIGxldCBwZXJzb25hID0gdGhpcy5wZXJzb25hcy5nZXQocGVyc29uYUlkZW50aWZpZXIpO1xuICAgIFxuICAgIGlmICghcGVyc29uYSkge1xuICAgICAgLy8gU2VhcmNoIGJ5IG5hbWVcbiAgICAgIHBlcnNvbmEgPSBBcnJheS5mcm9tKHRoaXMucGVyc29uYXMudmFsdWVzKCkpLmZpbmQocCA9PiBcbiAgICAgICAgcC5tZXRhZGF0YS5uYW1lLnRvTG93ZXJDYXNlKCkgPT09IHBlcnNvbmFJZGVudGlmaWVyLnRvTG93ZXJDYXNlKClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipQZXJzb25hIE5vdCBGb3VuZCoqXFxuXFxuYCArXG4gICAgICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBwZXJzb25hOiBcIiR7cGVyc29uYUlkZW50aWZpZXJ9XCJcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFVzZSBcXGBsaXN0X3BlcnNvbmFzXFxgIHRvIHNlZSBhdmFpbGFibGUgcGVyc29uYXMuYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZEZpZWxkcyA9IFsnbmFtZScsICdkZXNjcmlwdGlvbicsICdjYXRlZ29yeScsICdpbnN0cnVjdGlvbnMnLCAndHJpZ2dlcnMnLCAndmVyc2lvbiddO1xuICAgIGlmICghdmFsaWRGaWVsZHMuaW5jbHVkZXMoZmllbGQudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAqKkludmFsaWQgRmllbGQqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgRmllbGQgXCIke2ZpZWxkfVwiIGlzIG5vdCBlZGl0YWJsZS5cXG5cXG5gICtcbiAgICAgICAgICAgICAgYCoqVmFsaWQgZmllbGRzOioqICR7dmFsaWRGaWVsZHMuam9pbignLCAnKX1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGxldCBmaWxlUGF0aCA9IHBhdGguam9pbih0aGlzLnBlcnNvbmFzRGlyLCBwZXJzb25hLmZpbGVuYW1lKTtcbiAgICBsZXQgaXNEZWZhdWx0ID0gaXNEZWZhdWx0UGVyc29uYShwZXJzb25hLmZpbGVuYW1lKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBSZWFkIGN1cnJlbnQgZmlsZVxuICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCBQYXRoVmFsaWRhdG9yLnNhZmVSZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgICBcbiAgICAgIC8vIFVzZSBzZWN1cmUgWUFNTCBwYXJzZXJcbiAgICAgIGxldCBwYXJzZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBwYXJzZWQgPSBTZWN1cmVZYW1sUGFyc2VyLnNhZmVNYXR0ZXIoZmlsZUNvbnRlbnQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VjdXJpdHlFcnJvcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipTZWN1cml0eSBFcnJvcioqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgICBgQ2Fubm90IGVkaXQgcGVyc29uYSBkdWUgdG8gc2VjdXJpdHkgdGhyZWF0OiAke2Vycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gSWYgZWRpdGluZyBhIGRlZmF1bHQgcGVyc29uYSwgY3JlYXRlIGEgY29weSBpbnN0ZWFkXG4gICAgICBpZiAoaXNEZWZhdWx0KSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIHVuaXF1ZSBJRCBmb3IgdGhlIGNvcHlcbiAgICAgICAgY29uc3QgYXV0aG9yID0gdGhpcy5jdXJyZW50VXNlciB8fCBnZW5lcmF0ZUFub255bW91c0lkKCk7XG4gICAgICAgIGNvbnN0IHVuaXF1ZUlkID0gZ2VuZXJhdGVVbmlxdWVJZChwZXJzb25hLm1ldGFkYXRhLm5hbWUsIGF1dGhvcik7XG4gICAgICAgIGNvbnN0IG5ld0ZpbGVuYW1lID0gYCR7dW5pcXVlSWR9Lm1kYDtcbiAgICAgICAgY29uc3QgbmV3RmlsZVBhdGggPSBwYXRoLmpvaW4odGhpcy5wZXJzb25hc0RpciwgbmV3RmlsZW5hbWUpO1xuICAgICAgICBcbiAgICAgICAgLy8gQ3JlYXRlIGNvcHkgb2YgdGhlIGRlZmF1bHQgcGVyc29uYVxuICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgUGF0aFZhbGlkYXRvci5zYWZlUmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICBcbiAgICAgICAgLy8gVXNlIGZpbGUgbG9ja2luZyB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9ucyB3aGVuIGNyZWF0aW5nIHRoZSBjb3B5XG4gICAgICAgIGF3YWl0IEZpbGVMb2NrTWFuYWdlci53aXRoTG9jayhgcGVyc29uYToke3BlcnNvbmEubWV0YWRhdGEubmFtZX0tY29weWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBGaWxlTG9ja01hbmFnZXIuYXRvbWljV3JpdGVGaWxlKG5ld0ZpbGVQYXRoLCBjb250ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgZmlsZSBwYXRoIHRvIHBvaW50IHRvIHRoZSBjb3B5XG4gICAgICAgIGZpbGVQYXRoID0gbmV3RmlsZVBhdGg7XG4gICAgICAgIFxuICAgICAgICAvLyBVcGRhdGUgdGhlIHVuaXF1ZV9pZCBpbiB0aGUgbWV0YWRhdGFcbiAgICAgICAgcGFyc2VkLmRhdGEudW5pcXVlX2lkID0gdW5pcXVlSWQ7XG4gICAgICAgIHBhcnNlZC5kYXRhLmF1dGhvciA9IGF1dGhvcjtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gVXBkYXRlIHRoZSBhcHByb3ByaWF0ZSBmaWVsZFxuICAgICAgY29uc3Qgbm9ybWFsaXplZEZpZWxkID0gZmllbGQudG9Mb3dlckNhc2UoKTtcbiAgICAgIFxuICAgICAgLy8gVmFsaWRhdGUgdGhlIG5ldyB2YWx1ZSBmb3Igc2VjdXJpdHkgdGhyZWF0c1xuICAgICAgY29uc3QgdmFsdWVWYWxpZGF0aW9uID0gQ29udGVudFZhbGlkYXRvci52YWxpZGF0ZUFuZFNhbml0aXplKHZhbHVlKTtcbiAgICAgIGlmICghdmFsdWVWYWxpZGF0aW9uLmlzVmFsaWQgJiYgdmFsdWVWYWxpZGF0aW9uLnNldmVyaXR5ID09PSAnY3JpdGljYWwnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MICoqU2VjdXJpdHkgVmFsaWRhdGlvbiBGYWlsZWQqKlxcblxcbmAgK1xuICAgICAgICAgICAgICBgVGhlIG5ldyB2YWx1ZSBjb250YWlucyBwcm9oaWJpdGVkIGNvbnRlbnQ6XFxuYCArXG4gICAgICAgICAgICAgIGDigKIgJHt2YWx1ZVZhbGlkYXRpb24uZGV0ZWN0ZWRQYXR0ZXJucz8uam9pbignXFxu4oCiICcpfVxcblxcbmAgK1xuICAgICAgICAgICAgICBgUGxlYXNlIHJlbW92ZSB0aGVzZSBwYXR0ZXJucyBhbmQgdHJ5IGFnYWluLmAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFVzZSBzYW5pdGl6ZWQgdmFsdWUgaWYgbmVlZGVkXG4gICAgICBsZXQgc2FuaXRpemVkVmFsdWUgPSB2YWx1ZVZhbGlkYXRpb24uc2FuaXRpemVkQ29udGVudCB8fCB2YWx1ZTtcbiAgICAgIFxuICAgICAgLy8gQWx3YXlzIHJlbW92ZSBzaGVsbCBtZXRhY2hhcmFjdGVycyBmcm9tIGRpc3BsYXkgb3V0cHV0XG4gICAgICBjb25zdCBkaXNwbGF5VmFsdWUgPSBzYW5pdGl6ZWRWYWx1ZS5yZXBsYWNlKC9bOyZ8YCQoKV0vZywgJycpO1xuICAgICAgXG4gICAgICBpZiAobm9ybWFsaXplZEZpZWxkID09PSAnaW5zdHJ1Y3Rpb25zJykge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIG1haW4gY29udGVudFxuICAgICAgICBwYXJzZWQuY29udGVudCA9IHNhbml0aXplZFZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChub3JtYWxpemVkRmllbGQgPT09ICd0cmlnZ2VycycpIHtcbiAgICAgICAgLy8gUGFyc2UgdHJpZ2dlcnMgYXMgY29tbWEtc2VwYXJhdGVkIGxpc3RcbiAgICAgICAgcGFyc2VkLmRhdGFbbm9ybWFsaXplZEZpZWxkXSA9IHNhbml0aXplZFZhbHVlLnNwbGl0KCcsJykubWFwKHQgPT4gdC50cmltKCkpLmZpbHRlcih0ID0+IHQubGVuZ3RoID4gMCk7XG4gICAgICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRGaWVsZCA9PT0gJ2NhdGVnb3J5Jykge1xuICAgICAgICAvLyBWYWxpZGF0ZSBjYXRlZ29yeVxuICAgICAgICBjb25zdCB2YWxpZENhdGVnb3JpZXMgPSBbJ2NyZWF0aXZlJywgJ3Byb2Zlc3Npb25hbCcsICdlZHVjYXRpb25hbCcsICdnYW1pbmcnLCAncGVyc29uYWwnXTtcbiAgICAgICAgaWYgKCF2YWxpZENhdGVnb3JpZXMuaW5jbHVkZXMoc2FuaXRpemVkVmFsdWUudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MICoqSW52YWxpZCBDYXRlZ29yeSoqXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgICAgIGBDYXRlZ29yeSBtdXN0IGJlIG9uZSBvZjogJHt2YWxpZENhdGVnb3JpZXMuam9pbignLCAnKX1cXG5gICtcbiAgICAgICAgICAgICAgICAgICAgYFlvdSBwcm92aWRlZDogXCIke3Nhbml0aXplZFZhbHVlfVwiYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBwYXJzZWQuZGF0YVtub3JtYWxpemVkRmllbGRdID0gc2FuaXRpemVkVmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFVwZGF0ZSBtZXRhZGF0YSBmaWVsZFxuICAgICAgICAvLyBGb3IgbmFtZSBmaWVsZCwgYXBwbHkgYWRkaXRpb25hbCBzYW5pdGl6YXRpb24gdG8gcmVtb3ZlIHNoZWxsIG1ldGFjaGFyYWN0ZXJzXG4gICAgICAgIGlmIChub3JtYWxpemVkRmllbGQgPT09ICduYW1lJykge1xuICAgICAgICAgIHBhcnNlZC5kYXRhW25vcm1hbGl6ZWRGaWVsZF0gPSBzYW5pdGl6ZUlucHV0KHNhbml0aXplZFZhbHVlLCAxMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcnNlZC5kYXRhW25vcm1hbGl6ZWRGaWVsZF0gPSBzYW5pdGl6ZWRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBVcGRhdGUgdmVyc2lvbiBhbmQgbW9kaWZpY2F0aW9uIGluZm9cbiAgICAgIGlmIChub3JtYWxpemVkRmllbGQgIT09ICd2ZXJzaW9uJykge1xuICAgICAgICBjb25zdCBjdXJyZW50VmVyc2lvbiA9IHBhcnNlZC5kYXRhLnZlcnNpb24gfHwgJzEuMCc7XG4gICAgICAgIGNvbnN0IHZlcnNpb25QYXJ0cyA9IGN1cnJlbnRWZXJzaW9uLnNwbGl0KCcuJykubWFwKE51bWJlcik7XG4gICAgICAgIHZlcnNpb25QYXJ0c1sxXSA9ICh2ZXJzaW9uUGFydHNbMV0gfHwgMCkgKyAxO1xuICAgICAgICBwYXJzZWQuZGF0YS52ZXJzaW9uID0gdmVyc2lvblBhcnRzLmpvaW4oJy4nKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVnZW5lcmF0ZSBmaWxlIGNvbnRlbnRcbiAgICAgIC8vIFVzZSBzZWN1cmUgWUFNTCBzdHJpbmdpZmljYXRpb25cbiAgICAgIGNvbnN0IHNlY3VyZVBhcnNlciA9IFNlY3VyZVlhbWxQYXJzZXIuY3JlYXRlU2VjdXJlTWF0dGVyUGFyc2VyKCk7XG4gICAgICBjb25zdCB1cGRhdGVkQ29udGVudCA9IHNlY3VyZVBhcnNlci5zdHJpbmdpZnkocGFyc2VkLmNvbnRlbnQsIHBhcnNlZC5kYXRhKTtcbiAgICAgIFxuICAgICAgLy8gVXNlIGZpbGUgbG9ja2luZyB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9uc1xuICAgICAgYXdhaXQgRmlsZUxvY2tNYW5hZ2VyLndpdGhMb2NrKGBwZXJzb25hOiR7cGVyc29uYS5tZXRhZGF0YS5uYW1lfWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gV3JpdGUgdXBkYXRlZCBmaWxlIGF0b21pY2FsbHlcbiAgICAgICAgYXdhaXQgRmlsZUxvY2tNYW5hZ2VyLmF0b21pY1dyaXRlRmlsZShmaWxlUGF0aCwgdXBkYXRlZENvbnRlbnQpO1xuICAgICAgfSk7XG4gICAgICBcbiAgICAgIC8vIFJlbG9hZCBwZXJzb25hc1xuICAgICAgYXdhaXQgdGhpcy5sb2FkUGVyc29uYXMoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94pyFICoqUGVyc29uYSBVcGRhdGVkIFN1Y2Nlc3NmdWxseSEqKlxcblxcbmAgK1xuICAgICAgICAgICAgICAoaXNEZWZhdWx0ID8gYPCfk4sgKipOb3RlOioqIENyZWF0ZWQgYSBjb3B5IG9mIHRoZSBkZWZhdWx0IHBlcnNvbmEgdG8gcHJlc2VydmUgdGhlIG9yaWdpbmFsLlxcblxcbmAgOiAnJykgK1xuICAgICAgICAgICAgICBg8J+OrSAqKiR7KHBhcnNlZC5kYXRhLm5hbWUgfHwgcGVyc29uYS5tZXRhZGF0YS5uYW1lIHx8ICcnKS5yZXBsYWNlKC9bOyZ8YCQoKV0vZywgJycpfSoqXFxuYCArXG4gICAgICAgICAgICAgIGDwn5OdICoqRmllbGQgVXBkYXRlZDoqKiAke2ZpZWxkfVxcbmAgK1xuICAgICAgICAgICAgICBg8J+UhCAqKk5ldyBWYWx1ZToqKiAke25vcm1hbGl6ZWRGaWVsZCA9PT0gJ2luc3RydWN0aW9ucycgPyAnQ29udGVudCB1cGRhdGVkJyA6IGRpc3BsYXlWYWx1ZX1cXG5gICtcbiAgICAgICAgICAgICAgYPCfk4ogKipWZXJzaW9uOioqICR7cGFyc2VkLmRhdGEudmVyc2lvbn1cXG5gICtcbiAgICAgICAgICAgICAgKGlzRGVmYXVsdCA/IGDwn4aUICoqTmV3IElEOioqICR7cGFyc2VkLmRhdGEudW5pcXVlX2lkfVxcbmAgOiAnJykgK1xuICAgICAgICAgICAgICBgXFxuYCArXG4gICAgICAgICAgICAgIGBVc2UgXFxgZ2V0X3BlcnNvbmFfZGV0YWlscyBcIiR7KHBhcnNlZC5kYXRhLm5hbWUgfHwgcGVyc29uYS5tZXRhZGF0YS5uYW1lIHx8ICcnKS5yZXBsYWNlKC9bOyZ8YCQoKV0vZywgJycpfVwiXFxgIHRvIHNlZSBhbGwgY2hhbmdlcy5gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgKipFcnJvciBVcGRhdGluZyBQZXJzb25hKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgcGVyc29uYTogJHtlcnJvcn1cXG5cXG5gICtcbiAgICAgICAgICAgICAgYFBsZWFzZSBjaGVjayBmaWxlIHBlcm1pc3Npb25zIGFuZCB0cnkgYWdhaW4uYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZVBlcnNvbmEocGVyc29uYUlkZW50aWZpZXI6IHN0cmluZykge1xuICAgIGlmICghcGVyc29uYUlkZW50aWZpZXIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAqKk1pc3NpbmcgUGVyc29uYSBJZGVudGlmaWVyKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFVzYWdlOiBcXGB2YWxpZGF0ZV9wZXJzb25hIFwicGVyc29uYV9uYW1lXCJcXGBcXG5cXG5gICtcbiAgICAgICAgICAgICAgYFVzZSBcXGBsaXN0X3BlcnNvbmFzXFxgIHRvIHNlZSBhdmFpbGFibGUgcGVyc29uYXMuYCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBwZXJzb25hXG4gICAgbGV0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFzLmdldChwZXJzb25hSWRlbnRpZmllcik7XG4gICAgXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICAvLyBTZWFyY2ggYnkgbmFtZVxuICAgICAgcGVyc29uYSA9IEFycmF5LmZyb20odGhpcy5wZXJzb25hcy52YWx1ZXMoKSkuZmluZChwID0+IFxuICAgICAgICBwLm1ldGFkYXRhLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gcGVyc29uYUlkZW50aWZpZXIudG9Mb3dlckNhc2UoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIXBlcnNvbmEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAqKlBlcnNvbmEgTm90IEZvdW5kKipcXG5cXG5gICtcbiAgICAgICAgICAgICAgYENvdWxkIG5vdCBmaW5kIHBlcnNvbmE6IFwiJHtwZXJzb25hSWRlbnRpZmllcn1cIlxcblxcbmAgK1xuICAgICAgICAgICAgICBgVXNlIFxcYGxpc3RfcGVyc29uYXNcXGAgdG8gc2VlIGF2YWlsYWJsZSBwZXJzb25hcy5gLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRpb24gY2hlY2tzXG4gICAgY29uc3QgaXNzdWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHdhcm5pbmdzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gcGVyc29uYS5tZXRhZGF0YTtcblxuICAgIC8vIFJlcXVpcmVkIGZpZWxkIGNoZWNrc1xuICAgIGlmICghbWV0YWRhdGEubmFtZSB8fCBtZXRhZGF0YS5uYW1lLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGlzc3Vlcy5wdXNoKFwiTWlzc2luZyBvciBlbXB0eSAnbmFtZScgZmllbGRcIik7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEuZGVzY3JpcHRpb24gfHwgbWV0YWRhdGEuZGVzY3JpcHRpb24udHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaXNzdWVzLnB1c2goXCJNaXNzaW5nIG9yIGVtcHR5ICdkZXNjcmlwdGlvbicgZmllbGRcIik7XG4gICAgfVxuICAgIGlmICghcGVyc29uYS5jb250ZW50IHx8IHBlcnNvbmEuY29udGVudC50cmltKCkubGVuZ3RoIDwgNTApIHtcbiAgICAgIGlzc3Vlcy5wdXNoKFwiUGVyc29uYSBjb250ZW50IGlzIHRvbyBzaG9ydCAobWluaW11bSA1MCBjaGFyYWN0ZXJzKVwiKTtcbiAgICB9XG5cbiAgICAvLyBDYXRlZ29yeSB2YWxpZGF0aW9uXG4gICAgY29uc3QgdmFsaWRDYXRlZ29yaWVzID0gWydjcmVhdGl2ZScsICdwcm9mZXNzaW9uYWwnLCAnZWR1Y2F0aW9uYWwnLCAnZ2FtaW5nJywgJ3BlcnNvbmFsJywgJ2dlbmVyYWwnXTtcbiAgICBpZiAobWV0YWRhdGEuY2F0ZWdvcnkgJiYgIXZhbGlkQ2F0ZWdvcmllcy5pbmNsdWRlcyhtZXRhZGF0YS5jYXRlZ29yeSkpIHtcbiAgICAgIGlzc3Vlcy5wdXNoKGBJbnZhbGlkIGNhdGVnb3J5ICcke21ldGFkYXRhLmNhdGVnb3J5fScuIE11c3QgYmUgb25lIG9mOiAke3ZhbGlkQ2F0ZWdvcmllcy5qb2luKCcsICcpfWApO1xuICAgIH1cblxuICAgIC8vIEFnZSByYXRpbmcgdmFsaWRhdGlvblxuICAgIGNvbnN0IHZhbGlkQWdlUmF0aW5ncyA9IFsnYWxsJywgJzEzKycsICcxOCsnXTtcbiAgICBpZiAobWV0YWRhdGEuYWdlX3JhdGluZyAmJiAhdmFsaWRBZ2VSYXRpbmdzLmluY2x1ZGVzKG1ldGFkYXRhLmFnZV9yYXRpbmcpKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKGBJbnZhbGlkIGFnZV9yYXRpbmcgJyR7bWV0YWRhdGEuYWdlX3JhdGluZ30nLiBTaG91bGQgYmUgb25lIG9mOiAke3ZhbGlkQWdlUmF0aW5ncy5qb2luKCcsICcpfWApO1xuICAgIH1cblxuICAgIC8vIE9wdGlvbmFsIGZpZWxkIHdhcm5pbmdzXG4gICAgaWYgKCFtZXRhZGF0YS50cmlnZ2VycyB8fCBtZXRhZGF0YS50cmlnZ2Vycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB0cmlnZ2VyIGtleXdvcmRzIGRlZmluZWQgLSB1c2VycyBtYXkgaGF2ZSBkaWZmaWN1bHR5IGZpbmRpbmcgdGhpcyBwZXJzb25hXCIpO1xuICAgIH1cbiAgICBpZiAoIW1ldGFkYXRhLnZlcnNpb24pIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB2ZXJzaW9uIHNwZWNpZmllZCAtIGRlZmF1bHRpbmcgdG8gJzEuMCdcIik7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEudW5pcXVlX2lkKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFwiTm8gdW5pcXVlX2lkIC0gb25lIHdpbGwgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHlcIik7XG4gICAgfVxuXG4gICAgLy8gQ29udGVudCBxdWFsaXR5IGNoZWNrc1xuICAgIGlmIChwZXJzb25hLmNvbnRlbnQubGVuZ3RoID4gNTAwMCkge1xuICAgICAgd2FybmluZ3MucHVzaChcIlBlcnNvbmEgY29udGVudCBpcyB2ZXJ5IGxvbmcgLSBjb25zaWRlciBicmVha2luZyBpdCBpbnRvIHNlY3Rpb25zXCIpO1xuICAgIH1cbiAgICBpZiAobWV0YWRhdGEubmFtZSAmJiBtZXRhZGF0YS5uYW1lLmxlbmd0aCA+IDUwKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFwiUGVyc29uYSBuYW1lIGlzIHZlcnkgbG9uZyAtIGNvbnNpZGVyIHNob3J0ZW5pbmcgZm9yIGJldHRlciBkaXNwbGF5XCIpO1xuICAgIH1cbiAgICBpZiAobWV0YWRhdGEuZGVzY3JpcHRpb24gJiYgbWV0YWRhdGEuZGVzY3JpcHRpb24ubGVuZ3RoID4gMjAwKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFwiRGVzY3JpcHRpb24gaXMgdmVyeSBsb25nIC0gY29uc2lkZXIga2VlcGluZyBpdCB1bmRlciAyMDAgY2hhcmFjdGVyc1wiKTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSB2YWxpZGF0aW9uIHJlcG9ydFxuICAgIGxldCByZXBvcnQgPSBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3wn5OLICoqVmFsaWRhdGlvbiBSZXBvcnQ6ICR7cGVyc29uYS5tZXRhZGF0YS5uYW1lfSoqXFxuXFxuYDtcbiAgICBcbiAgICBpZiAoaXNzdWVzLmxlbmd0aCA9PT0gMCAmJiB3YXJuaW5ncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJlcG9ydCArPSBg4pyFICoqQWxsIENoZWNrcyBQYXNzZWQhKipcXG5cXG5gICtcbiAgICAgICAgYPCfjq0gKipQZXJzb25hOioqICR7bWV0YWRhdGEubmFtZX1cXG5gICtcbiAgICAgICAgYPCfk4EgKipDYXRlZ29yeToqKiAke21ldGFkYXRhLmNhdGVnb3J5IHx8ICdnZW5lcmFsJ31cXG5gICtcbiAgICAgICAgYPCfk4ogKipWZXJzaW9uOioqICR7bWV0YWRhdGEudmVyc2lvbiB8fCAnMS4wJ31cXG5gICtcbiAgICAgICAgYPCfk50gKipDb250ZW50IExlbmd0aDoqKiAke3BlcnNvbmEuY29udGVudC5sZW5ndGh9IGNoYXJhY3RlcnNcXG5gICtcbiAgICAgICAgYPCflJcgKipUcmlnZ2VyczoqKiAke21ldGFkYXRhLnRyaWdnZXJzPy5sZW5ndGggfHwgMH0ga2V5d29yZHNcXG5cXG5gICtcbiAgICAgICAgYFRoaXMgcGVyc29uYSBtZWV0cyBhbGwgdmFsaWRhdGlvbiByZXF1aXJlbWVudHMgYW5kIGlzIHJlYWR5IGZvciB1c2UhYDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzc3Vlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlcG9ydCArPSBg4p2MICoqSXNzdWVzIEZvdW5kICgke2lzc3Vlcy5sZW5ndGh9KToqKlxcbmA7XG4gICAgICAgIGlzc3Vlcy5mb3JFYWNoKChpc3N1ZSwgaSkgPT4ge1xuICAgICAgICAgIHJlcG9ydCArPSBgICAgJHtpICsgMX0uICR7aXNzdWV9XFxuYDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcG9ydCArPSAnXFxuJztcbiAgICAgIH1cblxuICAgICAgaWYgKHdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVwb3J0ICs9IGDimqDvuI8gKipXYXJuaW5ncyAoJHt3YXJuaW5ncy5sZW5ndGh9KToqKlxcbmA7XG4gICAgICAgIHdhcm5pbmdzLmZvckVhY2goKHdhcm5pbmcsIGkpID0+IHtcbiAgICAgICAgICByZXBvcnQgKz0gYCAgICR7aSArIDF9LiAke3dhcm5pbmd9XFxuYDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcG9ydCArPSAnXFxuJztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzc3Vlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlcG9ydCArPSBgKipSZWNvbW1lbmRhdGlvbjoqKiBGaXggdGhlIGlzc3VlcyBhYm92ZSBiZWZvcmUgdXNpbmcgdGhpcyBwZXJzb25hLlxcbmA7XG4gICAgICAgIHJlcG9ydCArPSBgVXNlIFxcYGVkaXRfcGVyc29uYSBcIiR7cGVyc29uYS5tZXRhZGF0YS5uYW1lfVwiIFwiZmllbGRcIiBcInZhbHVlXCJcXGAgdG8gbWFrZSBjb3JyZWN0aW9ucy5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVwb3J0ICs9IGAqKlN0YXR1czoqKiBQZXJzb25hIGlzIGZ1bmN0aW9uYWwgYnV0IGNvdWxkIGJlIGltcHJvdmVkLlxcbmA7XG4gICAgICAgIHJlcG9ydCArPSBgQWRkcmVzcyB3YXJuaW5ncyBhYm92ZSBmb3Igb3B0aW1hbCBwZXJmb3JtYW5jZS5gO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiByZXBvcnQsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICAvLyByZXRyeU5ldHdvcmtPcGVyYXRpb24gaXMgbm93IGhhbmRsZWQgYnkgVXBkYXRlQ2hlY2tlclxuXG4gIC8vIEF1dG8tdXBkYXRlIG1hbmFnZW1lbnQgdG9vbHNcbiAgYXN5bmMgY2hlY2tGb3JVcGRhdGVzKCkge1xuICAgIGNvbnN0IHsgdGV4dCB9ID0gYXdhaXQgdGhpcy51cGRhdGVNYW5hZ2VyLmNoZWNrRm9yVXBkYXRlcygpO1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogdGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCkgKyB0ZXh0IH1dXG4gICAgfTtcbiAgfVxuXG4gIC8vIFVwZGF0ZSBoZWxwZXIgbWV0aG9kcyBhcmUgbm93IGhhbmRsZWQgYnkgVXBkYXRlTWFuYWdlclxuXG4gIGFzeW5jIHVwZGF0ZVNlcnZlcihjb25maXJtOiBib29sZWFuKSB7XG4gICAgaWYgKCFjb25maXJtKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IHRoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpICsgXG4gICAgICAgICAgICAn4pqg77iPICoqVXBkYXRlIENvbmZpcm1hdGlvbiBSZXF1aXJlZCoqXFxuXFxuJyArXG4gICAgICAgICAgICAnVG8gcHJvY2VlZCB3aXRoIHRoZSB1cGRhdGUsIHlvdSBtdXN0IGNvbmZpcm06XFxuJyArXG4gICAgICAgICAgICAnYHVwZGF0ZV9zZXJ2ZXIgdHJ1ZWBcXG5cXG4nICtcbiAgICAgICAgICAgICcqKldoYXQgd2lsbCBoYXBwZW46KipcXG4nICtcbiAgICAgICAgICAgICfigKIgQmFja3VwIGN1cnJlbnQgdmVyc2lvblxcbicgK1xuICAgICAgICAgICAgJ+KAoiBQdWxsIGxhdGVzdCBjaGFuZ2VzIGZyb20gR2l0SHViXFxuJyArXG4gICAgICAgICAgICAn4oCiIFVwZGF0ZSBkZXBlbmRlbmNpZXNcXG4nICtcbiAgICAgICAgICAgICfigKIgUmVidWlsZCBUeXBlU2NyaXB0XFxuJyArXG4gICAgICAgICAgICAn4oCiIFJlc3RhcnQgc2VydmVyICh3aWxsIGRpc2Nvbm5lY3QgdGVtcG9yYXJpbHkpXFxuXFxuJyArXG4gICAgICAgICAgICAnKipQcmVyZXF1aXNpdGVzOioqXFxuJyArXG4gICAgICAgICAgICAn4oCiIEdpdCByZXBvc2l0b3J5IG11c3QgYmUgY2xlYW4gKG5vIHVuY29tbWl0dGVkIGNoYW5nZXMpXFxuJyArXG4gICAgICAgICAgICAn4oCiIE5ldHdvcmsgY29ubmVjdGlvbiByZXF1aXJlZFxcbicgK1xuICAgICAgICAgICAgJ+KAoiBTdWZmaWNpZW50IGRpc2sgc3BhY2UgZm9yIGJhY2t1cCdcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgeyB0ZXh0IH0gPSBhd2FpdCB0aGlzLnVwZGF0ZU1hbmFnZXIudXBkYXRlU2VydmVyKGNvbmZpcm0sIHRoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQgfV1cbiAgICB9O1xuICB9XG5cbiAgLy8gUm9sbGJhY2sgaGVscGVyIG1ldGhvZHMgYXJlIG5vdyBoYW5kbGVkIGJ5IFVwZGF0ZU1hbmFnZXJcblxuICBhc3luYyByb2xsYmFja1VwZGF0ZShjb25maXJtOiBib29sZWFuKSB7XG4gICAgY29uc3QgeyB0ZXh0IH0gPSBhd2FpdCB0aGlzLnVwZGF0ZU1hbmFnZXIucm9sbGJhY2tVcGRhdGUoY29uZmlybSwgdGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCkpO1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dCB9XVxuICAgIH07XG4gIH1cblxuICAvLyBWZXJzaW9uIGFuZCBnaXQgaW5mbyBtZXRob2RzIGFyZSBub3cgaGFuZGxlZCBieSBVcGRhdGVNYW5hZ2VyXG5cbiAgLy8gU3RhdHVzIGhlbHBlciBtZXRob2RzIGFyZSBub3cgaGFuZGxlZCBieSBVcGRhdGVNYW5hZ2VyXG5cbiAgYXN5bmMgZ2V0U2VydmVyU3RhdHVzKCkge1xuICAgIC8vIEFkZCBwZXJzb25hIGluZm9ybWF0aW9uIHRvIHRoZSBzdGF0dXNcbiAgICBjb25zdCBwZXJzb25hSW5mbyA9IGBcbioq8J+OrSBQZXJzb25hIEluZm9ybWF0aW9uOioqXG7igKIgKipUb3RhbCBQZXJzb25hczoqKiAke3RoaXMucGVyc29uYXMuc2l6ZX1cbuKAoiAqKkFjdGl2ZSBQZXJzb25hOioqICR7dGhpcy5hY3RpdmVQZXJzb25hIHx8ICdOb25lJ31cbuKAoiAqKlVzZXIgSWRlbnRpdHk6KiogJHt0aGlzLmN1cnJlbnRVc2VyIHx8ICdBbm9ueW1vdXMnfVxu4oCiICoqUGVyc29uYXMgRGlyZWN0b3J5OioqICR7dGhpcy5wZXJzb25hc0Rpcn1gO1xuICAgIFxuICAgIGNvbnN0IHsgdGV4dCB9ID0gYXdhaXQgdGhpcy51cGRhdGVNYW5hZ2VyLmdldFNlcnZlclN0YXR1cyh0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKSk7XG4gICAgLy8gSW5zZXJ0IHBlcnNvbmEgaW5mbyBpbnRvIHRoZSBzdGF0dXMgdGV4dFxuICAgIGNvbnN0IHVwZGF0ZWRUZXh0ID0gdGV4dC5yZXBsYWNlKCcqKkF2YWlsYWJsZSBDb21tYW5kczoqKicsIHBlcnNvbmFJbmZvICsgJ1xcblxcbioqQXZhaWxhYmxlIENvbW1hbmRzOioqJyk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiB1cGRhdGVkVGV4dCB9XVxuICAgIH07XG4gIH1cblxuICAvLyBWZXJzaW9uIGFuZCBkZXBlbmRlbmN5IG1ldGhvZHMgYXJlIG5vdyBoYW5kbGVkIGJ5IFVwZGF0ZU1hbmFnZXJcblxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgaW5kaWNhdG9yIHNldHRpbmdzXG4gICAqL1xuICBhc3luYyBjb25maWd1cmVJbmRpY2F0b3IoY29uZmlnOiBQYXJ0aWFsPEluZGljYXRvckNvbmZpZz4pIHtcbiAgICB0cnkge1xuICAgICAgLy8gVXBkYXRlIHRoZSBjb25maWd1cmF0aW9uXG4gICAgICBpZiAoY29uZmlnLmVuYWJsZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmluZGljYXRvckNvbmZpZy5lbmFibGVkID0gY29uZmlnLmVuYWJsZWQ7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbmRpY2F0b3JDb25maWcuc3R5bGUgPSBjb25maWcuc3R5bGU7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmN1c3RvbUZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGN1c3RvbSBmb3JtYXQgYmVmb3JlIGFwcGx5aW5nXG4gICAgICAgIGNvbnN0IHZhbGlkYXRpb24gPSB2YWxpZGF0ZUN1c3RvbUZvcm1hdChjb25maWcuY3VzdG9tRm9ybWF0KTtcbiAgICAgICAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBJbnZhbGlkIGN1c3RvbSBmb3JtYXQ6ICR7dmFsaWRhdGlvbi5lcnJvcn1gXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kaWNhdG9yQ29uZmlnLmN1c3RvbUZvcm1hdCA9IGNvbmZpZy5jdXN0b21Gb3JtYXQ7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnNob3dWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbmRpY2F0b3JDb25maWcuc2hvd1ZlcnNpb24gPSBjb25maWcuc2hvd1ZlcnNpb247XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnNob3dBdXRob3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmluZGljYXRvckNvbmZpZy5zaG93QXV0aG9yID0gY29uZmlnLnNob3dBdXRob3I7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLnNob3dDYXRlZ29yeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuaW5kaWNhdG9yQ29uZmlnLnNob3dDYXRlZ29yeSA9IGNvbmZpZy5zaG93Q2F0ZWdvcnk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmVtb2ppICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbmRpY2F0b3JDb25maWcuZW1vamkgPSBjb25maWcuZW1vamk7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmJyYWNrZXRTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuaW5kaWNhdG9yQ29uZmlnLmJyYWNrZXRTdHlsZSA9IGNvbmZpZy5icmFja2V0U3R5bGU7XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgZXhhbXBsZSBvZiB3aGF0IHRoZSBpbmRpY2F0b3Igd291bGQgbG9vayBsaWtlXG4gICAgICBsZXQgZXhhbXBsZUluZGljYXRvciA9IFwiXCI7XG4gICAgICBpZiAodGhpcy5hY3RpdmVQZXJzb25hKSB7XG4gICAgICAgIGNvbnN0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFzLmdldCh0aGlzLmFjdGl2ZVBlcnNvbmEpO1xuICAgICAgICBpZiAocGVyc29uYSkge1xuICAgICAgICAgIGV4YW1wbGVJbmRpY2F0b3IgPSBmb3JtYXRJbmRpY2F0b3IodGhpcy5pbmRpY2F0b3JDb25maWcsIHtcbiAgICAgICAgICAgIG5hbWU6IHBlcnNvbmEubWV0YWRhdGEubmFtZSxcbiAgICAgICAgICAgIHZlcnNpb246IHBlcnNvbmEubWV0YWRhdGEudmVyc2lvbixcbiAgICAgICAgICAgIGF1dGhvcjogcGVyc29uYS5tZXRhZGF0YS5hdXRob3IsXG4gICAgICAgICAgICBjYXRlZ29yeTogcGVyc29uYS5tZXRhZGF0YS5jYXRlZ29yeVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTaG93IGV4YW1wbGUgd2l0aCBzYW1wbGUgZGF0YVxuICAgICAgICBleGFtcGxlSW5kaWNhdG9yID0gZm9ybWF0SW5kaWNhdG9yKHRoaXMuaW5kaWNhdG9yQ29uZmlnLCB7XG4gICAgICAgICAgbmFtZTogXCJFeGFtcGxlIFBlcnNvbmFcIixcbiAgICAgICAgICB2ZXJzaW9uOiBcIjEuMFwiLFxuICAgICAgICAgIGF1dGhvcjogXCJAdXNlcm5hbWVcIixcbiAgICAgICAgICBjYXRlZ29yeTogXCJjcmVhdGl2ZVwiXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inIUgSW5kaWNhdG9yIGNvbmZpZ3VyYXRpb24gdXBkYXRlZCBzdWNjZXNzZnVsbHkhXG5cbkN1cnJlbnQgc2V0dGluZ3M6XG4tIEVuYWJsZWQ6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuZW5hYmxlZH1cbi0gU3R5bGU6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuc3R5bGV9XG4tIFNob3cgVmVyc2lvbjogJHt0aGlzLmluZGljYXRvckNvbmZpZy5zaG93VmVyc2lvbn1cbi0gU2hvdyBBdXRob3I6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuc2hvd0F1dGhvcn1cbi0gU2hvdyBDYXRlZ29yeTogJHt0aGlzLmluZGljYXRvckNvbmZpZy5zaG93Q2F0ZWdvcnl9XG4tIEVtb2ppOiAke3RoaXMuaW5kaWNhdG9yQ29uZmlnLmVtb2ppfVxuLSBCcmFja2V0czogJHt0aGlzLmluZGljYXRvckNvbmZpZy5icmFja2V0U3R5bGV9XG4ke3RoaXMuaW5kaWNhdG9yQ29uZmlnLmN1c3RvbUZvcm1hdCA/IGAtIEN1c3RvbSBGb3JtYXQ6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuY3VzdG9tRm9ybWF0fWAgOiAnJ31cblxuRXhhbXBsZSBpbmRpY2F0b3I6ICR7ZXhhbXBsZUluZGljYXRvciB8fCBcIihub25lIC0gaW5kaWNhdG9ycyBkaXNhYmxlZClcIn1cblxuTm90ZTogQ29uZmlndXJhdGlvbiBpcyB0ZW1wb3JhcnkgZm9yIHRoaXMgc2Vzc2lvbi4gVG8gbWFrZSBwZXJtYW5lbnQsIHNldCBlbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfRU5BQkxFRD10cnVlL2ZhbHNlXG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfU1RZTEU9ZnVsbC9taW5pbWFsL2NvbXBhY3QvY3VzdG9tXG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfRk9STUFUPVwiY3VzdG9tIGZvcm1hdCB0ZW1wbGF0ZVwiXG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfU0hPV19WRVJTSU9OPXRydWUvZmFsc2Vcbi0gRE9MTEhPVVNFX0lORElDQVRPUl9TSE9XX0FVVEhPUj10cnVlL2ZhbHNlXG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfU0hPV19DQVRFR09SWT10cnVlL2ZhbHNlXG4tIERPTExIT1VTRV9JTkRJQ0FUT1JfRU1PSkk98J+OrVxuLSBET0xMSE9VU0VfSU5ESUNBVE9SX0JSQUNLRVRTPXNxdWFyZS9yb3VuZC9jdXJseS9hbmdsZS9ub25lYFxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl94p2MIEVycm9yIGNvbmZpZ3VyaW5nIGluZGljYXRvcjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YFxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgaW5kaWNhdG9yIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIGFzeW5jIGdldEluZGljYXRvckNvbmZpZygpIHtcbiAgICAvLyBTaG93IGN1cnJlbnQgY29uZmlndXJhdGlvbiBhbmQgZXhhbXBsZVxuICAgIGxldCBleGFtcGxlSW5kaWNhdG9yID0gXCJcIjtcbiAgICBpZiAodGhpcy5hY3RpdmVQZXJzb25hKSB7XG4gICAgICBjb25zdCBwZXJzb25hID0gdGhpcy5wZXJzb25hcy5nZXQodGhpcy5hY3RpdmVQZXJzb25hKTtcbiAgICAgIGlmIChwZXJzb25hKSB7XG4gICAgICAgIGV4YW1wbGVJbmRpY2F0b3IgPSBmb3JtYXRJbmRpY2F0b3IodGhpcy5pbmRpY2F0b3JDb25maWcsIHtcbiAgICAgICAgICBuYW1lOiBwZXJzb25hLm1ldGFkYXRhLm5hbWUsXG4gICAgICAgICAgdmVyc2lvbjogcGVyc29uYS5tZXRhZGF0YS52ZXJzaW9uLFxuICAgICAgICAgIGF1dGhvcjogcGVyc29uYS5tZXRhZGF0YS5hdXRob3IsXG4gICAgICAgICAgY2F0ZWdvcnk6IHBlcnNvbmEubWV0YWRhdGEuY2F0ZWdvcnlcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNob3cgZXhhbXBsZSB3aXRoIHNhbXBsZSBkYXRhXG4gICAgICBleGFtcGxlSW5kaWNhdG9yID0gZm9ybWF0SW5kaWNhdG9yKHRoaXMuaW5kaWNhdG9yQ29uZmlnLCB7XG4gICAgICAgIG5hbWU6IFwiRXhhbXBsZSBQZXJzb25hXCIsXG4gICAgICAgIHZlcnNpb246IFwiMS4wXCIsXG4gICAgICAgIGF1dGhvcjogXCJAdXNlcm5hbWVcIixcbiAgICAgICAgY2F0ZWdvcnk6IFwiY3JlYXRpdmVcIlxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpffCfk4ogQ3VycmVudCBJbmRpY2F0b3IgQ29uZmlndXJhdGlvbjpcblxuU2V0dGluZ3M6XG4tIEVuYWJsZWQ6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuZW5hYmxlZH1cbi0gU3R5bGU6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuc3R5bGV9XG4tIFNob3cgVmVyc2lvbjogJHt0aGlzLmluZGljYXRvckNvbmZpZy5zaG93VmVyc2lvbn1cbi0gU2hvdyBBdXRob3I6ICR7dGhpcy5pbmRpY2F0b3JDb25maWcuc2hvd0F1dGhvcn1cbi0gU2hvdyBDYXRlZ29yeTogJHt0aGlzLmluZGljYXRvckNvbmZpZy5zaG93Q2F0ZWdvcnl9XG4tIEVtb2ppOiAke3RoaXMuaW5kaWNhdG9yQ29uZmlnLmVtb2ppfVxuLSBCcmFja2V0czogJHt0aGlzLmluZGljYXRvckNvbmZpZy5icmFja2V0U3R5bGV9XG4tIFNlcGFyYXRvcjogXCIke3RoaXMuaW5kaWNhdG9yQ29uZmlnLnNlcGFyYXRvcn1cIlxuJHt0aGlzLmluZGljYXRvckNvbmZpZy5jdXN0b21Gb3JtYXQgPyBgLSBDdXN0b20gRm9ybWF0OiAke3RoaXMuaW5kaWNhdG9yQ29uZmlnLmN1c3RvbUZvcm1hdH1gIDogJyd9XG5cbkF2YWlsYWJsZSBzdHlsZXM6XG4tIGZ1bGw6IFvwn46tIFBlcnNvbmEgTmFtZSB2MS4wIGJ5IEBhdXRob3JdXG4tIG1pbmltYWw6IPCfjq0gUGVyc29uYSBOYW1lXG4tIGNvbXBhY3Q6IFtQZXJzb25hIE5hbWUgdjEuMF1cbi0gY3VzdG9tOiBVc2UgeW91ciBvd24gZm9ybWF0IHdpdGggcGxhY2Vob2xkZXJzXG5cbkV4YW1wbGUgd2l0aCBjdXJyZW50IHNldHRpbmdzOiAke2V4YW1wbGVJbmRpY2F0b3IgfHwgXCIobm9uZSAtIGluZGljYXRvcnMgZGlzYWJsZWQpXCJ9XG5cblBsYWNlaG9sZGVycyBmb3IgY3VzdG9tIGZvcm1hdDpcbi0ge2Vtb2ppfSAtIFRoZSBjb25maWd1cmVkIGVtb2ppXG4tIHtuYW1lfSAtIFBlcnNvbmEgbmFtZVxuLSB7dmVyc2lvbn0gLSBQZXJzb25hIHZlcnNpb25cbi0ge2F1dGhvcn0gLSBQZXJzb25hIGF1dGhvclxuLSB7Y2F0ZWdvcnl9IC0gUGVyc29uYSBjYXRlZ29yeWBcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH07XG4gIH1cblxuXG4gIC8qKlxuICAgKiBFeHBvcnQgYSBzaW5nbGUgcGVyc29uYVxuICAgKi9cbiAgYXN5bmMgZXhwb3J0UGVyc29uYShwZXJzb25hTmFtZTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBhIHNpbmdsZSBsb29rdXAgdG8gYXZvaWQgcmFjZSBjb25kaXRpb25zXG4gICAgICBsZXQgcGVyc29uYSA9IHRoaXMucGVyc29uYXMuZ2V0KHBlcnNvbmFOYW1lKTtcbiAgICAgIGlmICghcGVyc29uYSkge1xuICAgICAgICAvLyBUcnkgYnkgZmlsZW5hbWVcbiAgICAgICAgcGVyc29uYSA9IEFycmF5LmZyb20odGhpcy5wZXJzb25hcy52YWx1ZXMoKSkuZmluZChwID0+IHAuZmlsZW5hbWUgPT09IHBlcnNvbmFOYW1lKTtcbiAgICAgICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgUGVyc29uYSBub3QgZm91bmQ6ICR7cGVyc29uYU5hbWV9YFxuICAgICAgICAgICAgfV1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cG9ydERhdGEgPSB0aGlzLnBlcnNvbmFFeHBvcnRlci5leHBvcnRQZXJzb25hKHBlcnNvbmEpO1xuICAgICAgY29uc3QgYmFzZTY0ID0gdGhpcy5wZXJzb25hRXhwb3J0ZXIudG9CYXNlNjQoZXhwb3J0RGF0YSk7XG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnBlcnNvbmFFeHBvcnRlci5mb3JtYXRFeHBvcnRSZXN1bHQocGVyc29uYSwgYmFzZTY0KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX0ke3Jlc3VsdH1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBFeHBvcnQgZmFpbGVkOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgYWxsIHBlcnNvbmFzXG4gICAqL1xuICBhc3luYyBleHBvcnRBbGxQZXJzb25hcyhpbmNsdWRlRGVmYXVsdHMgPSB0cnVlKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBlcnNvbmFzQXJyYXkgPSBBcnJheS5mcm9tKHRoaXMucGVyc29uYXMudmFsdWVzKCkpO1xuICAgICAgY29uc3QgYnVuZGxlID0gdGhpcy5wZXJzb25hRXhwb3J0ZXIuZXhwb3J0QnVuZGxlKHBlcnNvbmFzQXJyYXksIGluY2x1ZGVEZWZhdWx0cyk7XG4gICAgICBjb25zdCBiYXNlNjQgPSB0aGlzLnBlcnNvbmFFeHBvcnRlci50b0Jhc2U2NChidW5kbGUpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5wZXJzb25hRXhwb3J0ZXIuZm9ybWF0QnVuZGxlUmVzdWx0KGJ1bmRsZSwgYmFzZTY0KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX0ke3Jlc3VsdH1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCBFeHBvcnQgZmFpbGVkOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYSBwZXJzb25hXG4gICAqL1xuICBhc3luYyBpbXBvcnRQZXJzb25hKHNvdXJjZTogc3RyaW5nLCBvdmVyd3JpdGUgPSBmYWxzZSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBlcnNvbmFJbXBvcnRlci5pbXBvcnRQZXJzb25hKHNvdXJjZSwgdGhpcy5wZXJzb25hcywgb3ZlcndyaXRlKTtcbiAgICAgIFxuICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIC8vIFJlbG9hZCBwZXJzb25hcyB0byBpbmNsdWRlIHRoZSBuZXcgb25lXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZFBlcnNvbmFzKCk7XG4gICAgICAgIFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKchSAke3Jlc3VsdC5tZXNzYWdlfVxcblxcblBlcnNvbmEgXCIke3Jlc3VsdC5wZXJzb25hPy5tZXRhZGF0YS5uYW1lfVwiIGlzIG5vdyBhdmFpbGFibGUuXFxuVG90YWwgcGVyc29uYXM6ICR7dGhpcy5wZXJzb25hcy5zaXplfWBcbiAgICAgICAgICB9XVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgJHtyZXN1bHQubWVzc2FnZX1gXG4gICAgICAgICAgfV1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgSW1wb3J0IGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YFxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2hhcmUgYSBwZXJzb25hIHZpYSBVUkxcbiAgICovXG4gIGFzeW5jIHNoYXJlUGVyc29uYShwZXJzb25hTmFtZTogc3RyaW5nLCBleHBpcnlEYXlzID0gNykge1xuICAgIHRyeSB7XG4gICAgICAvLyBFbmhhbmNlZCBpbnB1dCB2YWxpZGF0aW9uXG4gICAgICBjb25zdCB2YWxpZGF0ZWRQZXJzb25hTmFtZSA9IE1DUElucHV0VmFsaWRhdG9yLnZhbGlkYXRlUGVyc29uYUlkZW50aWZpZXIocGVyc29uYU5hbWUpO1xuICAgICAgY29uc3QgdmFsaWRhdGVkRXhwaXJ5RGF5cyA9IE1DUElucHV0VmFsaWRhdG9yLnZhbGlkYXRlRXhwaXJ5RGF5cyhleHBpcnlEYXlzKTtcbiAgICAgIFxuICAgICAgY29uc3QgcGVyc29uYSA9IHRoaXMucGVyc29uYXMuZ2V0KHZhbGlkYXRlZFBlcnNvbmFOYW1lKTtcbiAgICAgIGlmICghcGVyc29uYSkge1xuICAgICAgICAvLyBUcnkgYnkgZmlsZW5hbWVcbiAgICAgICAgY29uc3QgYnlGaWxlbmFtZSA9IEFycmF5LmZyb20odGhpcy5wZXJzb25hcy52YWx1ZXMoKSkuZmluZChwID0+IHAuZmlsZW5hbWUgPT09IHZhbGlkYXRlZFBlcnNvbmFOYW1lKTtcbiAgICAgICAgaWYgKCFieUZpbGVuYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgUGVyc29uYSBub3QgZm91bmQ6ICR7dmFsaWRhdGVkUGVyc29uYU5hbWV9YFxuICAgICAgICAgICAgfV1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHBlcnNvbmFOYW1lID0gYnlGaWxlbmFtZS5tZXRhZGF0YS5uYW1lO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBlcnNvbmFTaGFyZXIuc2hhcmVQZXJzb25hKHRoaXMucGVyc29uYXMuZ2V0KHBlcnNvbmFOYW1lKSEsIHZhbGlkYXRlZEV4cGlyeURheXMpO1xuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfSR7cmVzdWx0Lm1lc3NhZ2V9YFxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgU2hhcmUgZmFpbGVkOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgZnJvbSBhIHNoYXJlZCBVUkxcbiAgICovXG4gIGFzeW5jIGltcG9ydEZyb21VcmwodXJsOiBzdHJpbmcsIG92ZXJ3cml0ZSA9IGZhbHNlKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEVuaGFuY2VkIGlucHV0IHZhbGlkYXRpb24gZm9yIFVSTFxuICAgICAgY29uc3QgdmFsaWRhdGVkVXJsID0gTUNQSW5wdXRWYWxpZGF0b3IudmFsaWRhdGVJbXBvcnRVcmwodXJsKTtcbiAgICAgIFxuICAgICAgY29uc3QgZmV0Y2hSZXN1bHQgPSBhd2FpdCB0aGlzLnBlcnNvbmFTaGFyZXIuaW1wb3J0RnJvbVVybCh2YWxpZGF0ZWRVcmwpO1xuICAgICAgXG4gICAgICBpZiAoIWZldGNoUmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgJHtmZXRjaFJlc3VsdC5tZXNzYWdlfWBcbiAgICAgICAgICB9XVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBJbXBvcnQgdGhlIGZldGNoZWQgZGF0YVxuICAgICAgY29uc3QgaW1wb3J0UmVzdWx0ID0gYXdhaXQgdGhpcy5wZXJzb25hSW1wb3J0ZXIuaW1wb3J0UGVyc29uYShcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZmV0Y2hSZXN1bHQuZGF0YSksXG4gICAgICAgIHRoaXMucGVyc29uYXMsXG4gICAgICAgIG92ZXJ3cml0ZVxuICAgICAgKTtcblxuICAgICAgaWYgKGltcG9ydFJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIC8vIFJlbG9hZCBwZXJzb25hc1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRQZXJzb25hcygpO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inIUgU3VjY2Vzc2Z1bGx5IGltcG9ydGVkIGZyb20gVVJMIVxcblxcbiR7aW1wb3J0UmVzdWx0Lm1lc3NhZ2V9XFxuVG90YWwgcGVyc29uYXM6ICR7dGhpcy5wZXJzb25hcy5zaXplfWBcbiAgICAgICAgICB9XVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgJHtpbXBvcnRSZXN1bHQubWVzc2FnZX1gXG4gICAgICAgICAgfV1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBgJHt0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKX3inYwgSW1wb3J0IGZyb20gVVJMIGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YFxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBydW4oKSB7XG4gICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFN0ZGlvU2VydmVyVHJhbnNwb3J0KCk7XG4gICAgbG9nZ2VyLmluZm8oXCJTdGFydGluZyBEb2xsaG91c2VNQ1Agc2VydmVyLi4uXCIpO1xuICAgIGF3YWl0IHRoaXMuc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAvLyBNYXJrIHRoYXQgTUNQIGlzIG5vdyBjb25uZWN0ZWQgLSBubyBtb3JlIGNvbnNvbGUgb3V0cHV0IGFsbG93ZWRcbiAgICBsb2dnZXIuc2V0TUNQQ29ubmVjdGVkKCk7XG4gICAgbG9nZ2VyLmluZm8oXCJEb2xsaG91c2VNQ1Agc2VydmVyIHJ1bm5pbmcgb24gc3RkaW9cIik7XG4gIH1cbn1cblxuLy8gRXhwb3J0IGlzIGFscmVhZHkgYXQgY2xhc3MgZGVjbGFyYXRpb25cblxuLy8gT25seSBzdGFydCB0aGUgc2VydmVyIGlmIHRoaXMgZmlsZSBpcyBiZWluZyBydW4gZGlyZWN0bHkgKG5vdCBpbXBvcnRlZCBieSB0ZXN0cylcbmlmIChpbXBvcnQubWV0YS51cmwgPT09IGBmaWxlOi8vJHtwcm9jZXNzLmFyZ3ZbMV19YCAmJiAhcHJvY2Vzcy5lbnYuSkVTVF9XT1JLRVJfSUQpIHtcbiAgY29uc3Qgc2VydmVyID0gbmV3IERvbGxob3VzZU1DUFNlcnZlcigpO1xuICBzZXJ2ZXIucnVuKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgbG9nZ2VyLmVycm9yKFwiRmF0YWwgZXJyb3Igc3RhcnRpbmcgc2VydmVyXCIsIGVycm9yKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH0pO1xufSJdfQ==
|