@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
209 lines • 29.3 kB
JavaScript
/**
* EnsembleActivationStrategy - Strategy for ensemble element activation
*
* Handles activation, deactivation, and status tracking for ensemble elements.
* Ensembles coordinate multiple elements and require all managers for activation.
*/
import { BaseActivationStrategy } from './BaseActivationStrategy.js';
export class EnsembleActivationStrategy extends BaseActivationStrategy {
ensembleManager;
portfolioManager;
skillManager;
templateManager;
agentManager;
memoryManager;
personaManager;
constructor(ensembleManager, portfolioManager, skillManager, templateManager, agentManager, memoryManager, personaManager) {
super();
this.ensembleManager = ensembleManager;
this.portfolioManager = portfolioManager;
this.skillManager = skillManager;
this.templateManager = templateManager;
this.agentManager = agentManager;
this.memoryManager = memoryManager;
this.personaManager = personaManager;
}
/**
* Activate an ensemble with all its constituent elements
* Extracted from ElementCRUDHandler.ts lines 281-345
*/
async activate(name) {
// Activate via manager (which handles name tracking)
const activationResult = await this.ensembleManager.activateEnsemble(name);
if (!activationResult.success) {
return this.createNotFoundResponse(name, 'Ensemble');
}
const ensemble = activationResult.ensemble;
// Activate the ensemble with all managers (orchestration)
try {
const result = await ensemble.activateEnsemble(this.portfolioManager, this.getManagers());
const statusEmoji = result.success ? '✅' : '⚠️';
const details = [
`${statusEmoji} Ensemble '${ensemble.metadata.name}' activated`,
``,
`**Strategy**: ${ensemble.metadata.activationStrategy}`,
`**Activated**: ${result.activatedElements.length} elements`,
`**Failed**: ${result.failedElements.length} elements`,
`**Duration**: ${result.totalDuration}ms`,
];
if (result.activatedElements.length > 0) {
details.push(``, `**Active Elements**:`);
result.activatedElements.forEach((elem) => {
details.push(` - ${elem}`);
});
}
if (result.failedElements.length > 0) {
details.push(``, `**Failed Elements**:`);
result.failedElements.forEach((elem) => {
const elementResult = result.elementResults.find((r) => r.elementName === elem && !r.success);
const errorMsg = elementResult?.error?.message || 'Unknown error';
details.push(` - ${elem}: ${errorMsg}`);
});
}
// Issue #642: Fail-safe warning for CLI restrictions
const restrictionWarning = this.formatRestrictionWarning(ensemble.metadata);
if (restrictionWarning) {
details.push(restrictionWarning);
}
const gatekeeperWarning = this.formatGatekeeperValidityWarning(ensemble.metadata);
if (gatekeeperWarning) {
details.push(gatekeeperWarning);
}
return {
content: [{
type: "text",
text: details.join('\n')
}]
};
}
catch (activationError) {
return {
content: [{
type: "text",
text: `❌ Failed to activate ensemble: ${activationError instanceof Error ? activationError.message : 'Unknown error'}`
}]
};
}
}
/**
* Deactivate an ensemble
* NOTE: This was missing in the original implementation - adding it now
*
* @throws {ElementNotFoundError} When ensemble does not exist
* @see Issue #275 - Handlers return success=true for missing elements
*/
async deactivate(name) {
// Deactivate via manager (which handles name tracking)
const deactivationResult = await this.ensembleManager.deactivateEnsemble(name);
if (!deactivationResult.success) {
this.throwNotFoundError(name, 'Ensemble');
}
if (deactivationResult.ensemble) {
await this.deactivateMembers(deactivationResult.ensemble);
}
return this.createSuccessResponse(`✅ Ensemble '${name}' deactivated`);
}
getManagers() {
return {
skillManager: this.skillManager,
templateManager: this.templateManager,
agentManager: this.agentManager,
memoryManager: this.memoryManager,
personaManager: this.personaManager,
ensembleManager: this.ensembleManager
};
}
async deactivateMembers(ensemble) {
const deactivationPromises = (ensemble.metadata.elements || []).map((element) => this.deactivateMember(element));
await Promise.all(deactivationPromises);
}
async deactivateMember(element) {
const normalizedType = element.element_type.toLowerCase();
switch (normalizedType) {
case 'skill':
case 'skills':
await this.skillManager.deactivateSkill(element.element_name);
return;
case 'persona':
case 'personas':
await Promise.resolve(this.personaManager.deactivatePersona(element.element_name));
return;
case 'agent':
case 'agents':
await this.agentManager.deactivateAgent(element.element_name);
return;
case 'memory':
case 'memories':
await this.memoryManager.deactivateMemory(element.element_name);
return;
case 'ensemble':
case 'ensembles':
await this.ensembleManager.deactivateEnsemble(element.element_name);
return;
case 'template':
case 'templates':
default:
return;
}
}
/**
* Get all active ensembles
* NOTE: This was missing in the original implementation - adding basic version
*/
async getActiveElements() {
const activeEnsembles = await this.ensembleManager.getActiveEnsembles();
if (activeEnsembles.length === 0) {
return {
content: [{
type: "text",
text: "🎭 No active ensembles"
}]
};
}
const ensembleList = activeEnsembles.map(e => {
const elementCount = e.metadata.elements?.length || 0;
return `🎭 ${e.metadata.name} (${elementCount} elements)`;
}).join('\n');
return {
content: [{
type: "text",
text: `Active ensembles:\n${ensembleList}`
}]
};
}
/**
* Get detailed information about an ensemble
* Extracted from ElementCRUDHandler.ts lines 807-846
*/
async getElementDetails(name) {
// Use flexible finding to support both display name and filename
const allEnsembles = await this.ensembleManager.list();
const ensemble = await this.findElementFlexibly(name, allEnsembles);
if (!ensemble) {
this.throwNotFoundError(name, 'Ensemble');
}
const elementsList = ensemble.metadata.elements?.map((elem) => `- ${elem.element_name} (${elem.element_type}) - ${elem.role}, priority: ${elem.priority}, activation: ${elem.activation}`).join('\n') || 'No elements configured';
const details = [
`🎭 **${ensemble.metadata.name}**`,
`${ensemble.metadata.description}`,
``,
`**Status**: ${ensemble.getStatus()}`,
`**Version**: ${ensemble.metadata.version || '1.0.0'}`,
`**Activation Strategy**: ${ensemble.metadata.activationStrategy || 'sequential'}`,
`**Conflict Resolution**: ${ensemble.metadata.conflictResolution || 'last-write'}`,
`**Context Sharing**: ${ensemble.metadata.contextSharing || 'selective'}`,
`**Allows Nesting**: ${ensemble.metadata.allowNested ? 'Yes' : 'No'}`,
`**Max Nesting Depth**: ${ensemble.metadata.maxNestingDepth || 5}`,
``,
`**Elements** (${ensemble.metadata.elements?.length || 0}):`,
elementsList
];
return {
content: [{
type: "text",
text: details.join('\n')
}]
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW5zZW1ibGVBY3RpdmF0aW9uU3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaGFuZGxlcnMvc3RyYXRlZ2llcy9FbnNlbWJsZUFjdGl2YXRpb25TdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQVNILE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBS3JFLE1BQU0sT0FBTywwQkFBMkIsU0FBUSxzQkFBc0I7SUFFakQ7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFQbkIsWUFDbUIsZUFBZ0MsRUFDaEMsZ0JBQWtDLEVBQ2xDLFlBQTBCLEVBQzFCLGVBQWdDLEVBQ2hDLFlBQTBCLEVBQzFCLGFBQTRCLEVBQzVCLGNBQThCO1FBRS9DLEtBQUssRUFBRSxDQUFDO1FBUlMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtJQUdqRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFZO1FBQ3pCLHFEQUFxRDtRQUNyRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUzRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFTLENBQUM7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WyIvKipcbiAqIEVuc2VtYmxlQWN0aXZhdGlvblN0cmF0ZWd5IC0gU3RyYXRlZ3kgZm9yIGVuc2VtYmxlIGVsZW1lbnQgYWN0aXZhdGlvblxuICpcbiAqIEhhbmRsZXMgYWN0aXZhdGlvbiwgZGVhY3RpdmF0aW9uLCBhbmQgc3RhdHVzIHRyYWNraW5nIGZvciBlbnNlbWJsZSBlbGVtZW50cy5cbiAqIEVuc2VtYmxlcyBjb29yZGluYXRlIG11bHRpcGxlIGVsZW1lbnRzIGFuZCByZXF1aXJlIGFsbCBtYW5hZ2VycyBmb3IgYWN0aXZhdGlvbi5cbiAqL1xuXG5pbXBvcnQgeyBFbnNlbWJsZU1hbmFnZXIgfSBmcm9tICcuLi8uLi9lbGVtZW50cy9lbnNlbWJsZXMvRW5zZW1ibGVNYW5hZ2VyLmpzJztcbmltcG9ydCB7IFNraWxsTWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL3NraWxscy9pbmRleC5qcyc7XG5pbXBvcnQgeyBUZW1wbGF0ZU1hbmFnZXIgfSBmcm9tICcuLi8uLi9lbGVtZW50cy90ZW1wbGF0ZXMvVGVtcGxhdGVNYW5hZ2VyLmpzJztcbmltcG9ydCB7IEFnZW50TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2FnZW50cy9BZ2VudE1hbmFnZXIuanMnO1xuaW1wb3J0IHsgTWVtb3J5TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL21lbW9yaWVzL01lbW9yeU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgUGVyc29uYU1hbmFnZXIgfSBmcm9tICcuLi8uLi9wZXJzb25hL1BlcnNvbmFNYW5hZ2VyLmpzJztcbmltcG9ydCB7IFBvcnRmb2xpb01hbmFnZXIgfSBmcm9tICcuLi8uLi9wb3J0Zm9saW8vUG9ydGZvbGlvTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBCYXNlQWN0aXZhdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9CYXNlQWN0aXZhdGlvblN0cmF0ZWd5LmpzJztcbmltcG9ydCB7IEVsZW1lbnRBY3RpdmF0aW9uU3RyYXRlZ3ksIE1DUFJlc3BvbnNlIH0gZnJvbSAnLi9FbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5LmpzJztcbmltcG9ydCB0eXBlIHsgRW5zZW1ibGUgfSBmcm9tICcuLi8uLi9lbGVtZW50cy9lbnNlbWJsZXMvRW5zZW1ibGUuanMnO1xuaW1wb3J0IHR5cGUgeyBFbGVtZW50TWFuYWdlcnMsIEVuc2VtYmxlRWxlbWVudCB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2Vuc2VtYmxlcy90eXBlcy5qcyc7XG5cbmV4cG9ydCBjbGFzcyBFbnNlbWJsZUFjdGl2YXRpb25TdHJhdGVneSBleHRlbmRzIEJhc2VBY3RpdmF0aW9uU3RyYXRlZ3kgaW1wbGVtZW50cyBFbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBlbnNlbWJsZU1hbmFnZXI6IEVuc2VtYmxlTWFuYWdlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBvcnRmb2xpb01hbmFnZXI6IFBvcnRmb2xpb01hbmFnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBza2lsbE1hbmFnZXI6IFNraWxsTWFuYWdlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRlbXBsYXRlTWFuYWdlcjogVGVtcGxhdGVNYW5hZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWdlbnRNYW5hZ2VyOiBBZ2VudE1hbmFnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBtZW1vcnlNYW5hZ2VyOiBNZW1vcnlNYW5hZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGVyc29uYU1hbmFnZXI6IFBlcnNvbmFNYW5hZ2VyXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQWN0aXZhdGUgYW4gZW5zZW1ibGUgd2l0aCBhbGwgaXRzIGNvbnN0aXR1ZW50IGVsZW1lbnRzXG4gICAqIEV4dHJhY3RlZCBmcm9tIEVsZW1lbnRDUlVESGFuZGxlci50cyBsaW5lcyAyODEtMzQ1XG4gICAqL1xuICBhc3luYyBhY3RpdmF0ZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE1DUFJlc3BvbnNlPiB7XG4gICAgLy8gQWN0aXZhdGUgdmlhIG1hbmFnZXIgKHdoaWNoIGhhbmRsZXMgbmFtZSB0cmFja2luZylcbiAgICBjb25zdCBhY3RpdmF0aW9uUmVzdWx0ID0gYXdhaXQgdGhpcy5lbnNlbWJsZU1hbmFnZXIuYWN0aXZhdGVFbnNlbWJsZShuYW1lKTtcblxuICAgIGlmICghYWN0aXZhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVOb3RGb3VuZFJlc3BvbnNlKG5hbWUsICdFbnNlbWJsZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGVuc2VtYmxlID0gYWN0aXZhdGlvblJlc3VsdC5lbnNlbWJsZSE7XG5cbiAgICAvLyBBY3RpdmF0ZSB0aGUgZW5zZW1ibGUgd2l0aCBhbGwgbWFuYWdlcnMgKG9yY2hlc3RyYXRpb24pXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVuc2VtYmxlLmFjdGl2YXRlRW5zZW1ibGUodGhpcy5wb3J0Zm9saW9NYW5hZ2VyLCB0aGlzLmdldE1hbmFnZXJzKCkpO1xuXG4gICAgICBjb25zdCBzdGF0dXNFbW9qaSA9IHJlc3VsdC5zdWNjZXNzID8gJ+KchScgOiAn4pqg77iPJztcbiAgICAgIGNvbnN0IGRldGFpbHMgPSBbXG4gICAgICAgIGAke3N0YXR1c0Vtb2ppfSBFbnNlbWJsZSAnJHtlbnNlbWJsZS5tZXRhZGF0YS5uYW1lfScgYWN0aXZhdGVkYCxcbiAgICAgICAgYGAsXG4gICAgICAgIGAqKlN0cmF0ZWd5Kio6ICR7ZW5zZW1ibGUubWV0YWRhdGEuYWN0aXZhdGlvblN0cmF0ZWd5fWAsXG4gICAgICAgIGAqKkFjdGl2YXRlZCoqOiAke3Jlc3VsdC5hY3RpdmF0ZWRFbGVtZW50cy5sZW5ndGh9IGVsZW1lbnRzYCxcbiAgICAgICAgYCoqRmFpbGVkKio6ICR7cmVzdWx0LmZhaWxlZEVsZW1lbnRzLmxlbmd0aH0gZWxlbWVudHNgLFxuICAgICAgICBgKipEdXJhdGlvbioqOiAke3Jlc3VsdC50b3RhbER1cmF0aW9ufW1zYCxcbiAgICAgIF07XG5cbiAgICAgIGlmIChyZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBkZXRhaWxzLnB1c2goYGAsIGAqKkFjdGl2ZSBFbGVtZW50cyoqOmApO1xuICAgICAgICByZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKGAgIC0gJHtlbGVtfWApO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdC5mYWlsZWRFbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGRldGFpbHMucHVzaChgYCwgYCoqRmFpbGVkIEVsZW1lbnRzKio6YCk7XG4gICAgICAgIHJlc3VsdC5mYWlsZWRFbGVtZW50cy5mb3JFYWNoKChlbGVtOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50UmVzdWx0ID0gcmVzdWx0LmVsZW1lbnRSZXN1bHRzLmZpbmQoKHI6IGFueSkgPT4gci5lbGVtZW50TmFtZSA9PT0gZWxlbSAmJiAhci5zdWNjZXNzKTtcbiAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGVsZW1lbnRSZXN1bHQ/LmVycm9yPy5tZXNzYWdlIHx8ICdVbmtub3duIGVycm9yJztcbiAgICAgICAgICBkZXRhaWxzLnB1c2goYCAgLSAke2VsZW19OiAke2Vycm9yTXNnfWApO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gSXNzdWUgIzY0MjogRmFpbC1zYWZlIHdhcm5pbmcgZm9yIENMSSByZXN0cmljdGlvbnNcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uV2FybmluZyA9IHRoaXMuZm9ybWF0UmVzdHJpY3Rpb25XYXJuaW5nKGVuc2VtYmxlLm1ldGFkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICAgICAgaWYgKHJlc3RyaWN0aW9uV2FybmluZykge1xuICAgICAgICBkZXRhaWxzLnB1c2gocmVzdHJpY3Rpb25XYXJuaW5nKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2F0ZWtlZXBlcldhcm5pbmcgPSB0aGlzLmZvcm1hdEdhdGVrZWVwZXJWYWxpZGl0eVdhcm5pbmcoZW5zZW1ibGUubWV0YWRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG4gICAgICBpZiAoZ2F0ZWtlZXBlcldhcm5pbmcpIHtcbiAgICAgICAgZGV0YWlscy5wdXNoKGdhdGVrZWVwZXJXYXJuaW5nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBkZXRhaWxzLmpvaW4oJ1xcbicpXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGFjdGl2YXRpb25FcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBg4p2MIEZhaWxlZCB0byBhY3RpdmF0ZSBlbnNlbWJsZTogJHthY3RpdmF0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGFjdGl2YXRpb25FcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InfWBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlYWN0aXZhdGUgYW4gZW5zZW1ibGVcbiAgICogTk9URTogVGhpcyB3YXMgbWlzc2luZyBpbiB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gLSBhZGRpbmcgaXQgbm93XG4gICAqXG4gICAqIEB0aHJvd3Mge0VsZW1lbnROb3RGb3VuZEVycm9yfSBXaGVuIGVuc2VtYmxlIGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGRlYWN0aXZhdGUobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIERlYWN0aXZhdGUgdmlhIG1hbmFnZXIgKHdoaWNoIGhhbmRsZXMgbmFtZSB0cmFja2luZylcbiAgICBjb25zdCBkZWFjdGl2YXRpb25SZXN1bHQgPSBhd2FpdCB0aGlzLmVuc2VtYmxlTWFuYWdlci5kZWFjdGl2YXRlRW5zZW1ibGUobmFtZSk7XG5cbiAgICBpZiAoIWRlYWN0aXZhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLnRocm93Tm90Rm91bmRFcnJvcihuYW1lLCAnRW5zZW1ibGUnKTtcbiAgICB9XG5cbiAgICBpZiAoZGVhY3RpdmF0aW9uUmVzdWx0LmVuc2VtYmxlKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlYWN0aXZhdGVNZW1iZXJzKGRlYWN0aXZhdGlvblJlc3VsdC5lbnNlbWJsZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU3VjY2Vzc1Jlc3BvbnNlKGDinIUgRW5zZW1ibGUgJyR7bmFtZX0nIGRlYWN0aXZhdGVkYCk7XG4gIH1cblxuICBwcml2YXRlIGdldE1hbmFnZXJzKCk6IEVsZW1lbnRNYW5hZ2VycyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNraWxsTWFuYWdlcjogdGhpcy5za2lsbE1hbmFnZXIsXG4gICAgICB0ZW1wbGF0ZU1hbmFnZXI6IHRoaXMudGVtcGxhdGVNYW5hZ2VyLFxuICAgICAgYWdlbnRNYW5hZ2VyOiB0aGlzLmFnZW50TWFuYWdlcixcbiAgICAgIG1lbW9yeU1hbmFnZXI6IHRoaXMubWVtb3J5TWFuYWdlcixcbiAgICAgIHBlcnNvbmFNYW5hZ2VyOiB0aGlzLnBlcnNvbmFNYW5hZ2VyLFxuICAgICAgZW5zZW1ibGVNYW5hZ2VyOiB0aGlzLmVuc2VtYmxlTWFuYWdlclxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlYWN0aXZhdGVNZW1iZXJzKGVuc2VtYmxlOiBFbnNlbWJsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRlYWN0aXZhdGlvblByb21pc2VzID0gKGVuc2VtYmxlLm1ldGFkYXRhLmVsZW1lbnRzIHx8IFtdKS5tYXAoKGVsZW1lbnQpID0+XG4gICAgICB0aGlzLmRlYWN0aXZhdGVNZW1iZXIoZWxlbWVudClcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKGRlYWN0aXZhdGlvblByb21pc2VzKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGVhY3RpdmF0ZU1lbWJlcihlbGVtZW50OiBFbnNlbWJsZUVsZW1lbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBub3JtYWxpemVkVHlwZSA9IGVsZW1lbnQuZWxlbWVudF90eXBlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBzd2l0Y2ggKG5vcm1hbGl6ZWRUeXBlKSB7XG4gICAgICBjYXNlICdza2lsbCc6XG4gICAgICBjYXNlICdza2lsbHMnOlxuICAgICAgICBhd2FpdCB0aGlzLnNraWxsTWFuYWdlci5kZWFjdGl2YXRlU2tpbGwoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICdwZXJzb25hJzpcbiAgICAgIGNhc2UgJ3BlcnNvbmFzJzpcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMucGVyc29uYU1hbmFnZXIuZGVhY3RpdmF0ZVBlcnNvbmEoZWxlbWVudC5lbGVtZW50X25hbWUpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgY2FzZSAnYWdlbnQnOlxuICAgICAgY2FzZSAnYWdlbnRzJzpcbiAgICAgICAgYXdhaXQgdGhpcy5hZ2VudE1hbmFnZXIuZGVhY3RpdmF0ZUFnZW50KGVsZW1lbnQuZWxlbWVudF9uYW1lKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgY2FzZSAnbWVtb3J5JzpcbiAgICAgIGNhc2UgJ21lbW9yaWVzJzpcbiAgICAgICAgYXdhaXQgdGhpcy5tZW1vcnlNYW5hZ2VyLmRlYWN0aXZhdGVNZW1vcnkoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICdlbnNlbWJsZSc6XG4gICAgICBjYXNlICdlbnNlbWJsZXMnOlxuICAgICAgICBhd2FpdCB0aGlzLmVuc2VtYmxlTWFuYWdlci5kZWFjdGl2YXRlRW5zZW1ibGUoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICd0ZW1wbGF0ZSc6XG4gICAgICBjYXNlICd0ZW1wbGF0ZXMnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGFjdGl2ZSBlbnNlbWJsZXNcbiAgICogTk9URTogVGhpcyB3YXMgbWlzc2luZyBpbiB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gLSBhZGRpbmcgYmFzaWMgdmVyc2lvblxuICAgKi9cbiAgYXN5bmMgZ2V0QWN0aXZlRWxlbWVudHMoKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIGNvbnN0IGFjdGl2ZUVuc2VtYmxlcyA9IGF3YWl0IHRoaXMuZW5zZW1ibGVNYW5hZ2VyLmdldEFjdGl2ZUVuc2VtYmxlcygpO1xuXG4gICAgaWYgKGFjdGl2ZUVuc2VtYmxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogXCLwn46tIE5vIGFjdGl2ZSBlbnNlbWJsZXNcIlxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBlbnNlbWJsZUxpc3QgPSBhY3RpdmVFbnNlbWJsZXMubWFwKGUgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudENvdW50ID0gZS5tZXRhZGF0YS5lbGVtZW50cz8ubGVuZ3RoIHx8IDA7XG4gICAgICByZXR1cm4gYPCfjq0gJHtlLm1ldGFkYXRhLm5hbWV9ICgke2VsZW1lbnRDb3VudH0gZWxlbWVudHMpYDtcbiAgICB9KS5qb2luKCdcXG4nKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogYEFjdGl2ZSBlbnNlbWJsZXM6XFxuJHtlbnNlbWJsZUxpc3R9YFxuICAgICAgfV1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhbiBlbnNlbWJsZVxuICAgKiBFeHRyYWN0ZWQgZnJvbSBFbGVtZW50Q1JVREhhbmRsZXIudHMgbGluZXMgODA3LTg0NlxuICAgKi9cbiAgYXN5bmMgZ2V0RWxlbWVudERldGFpbHMobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIFVzZSBmbGV4aWJsZSBmaW5kaW5nIHRvIHN1cHBvcnQgYm90aCBkaXNwbGF5IG5hbWUgYW5kIGZpbGVuYW1lXG4gICAgY29uc3QgYWxsRW5zZW1ibGVzID0gYXdhaXQgdGhpcy5lbnNlbWJsZU1hbmFnZXIubGlzdCgpO1xuICAgIGNvbnN0IGVuc2VtYmxlID0gYXdhaXQgdGhpcy5maW5kRWxlbWVudEZsZXhpYmx5KG5hbWUsIGFsbEVuc2VtYmxlcyk7XG4gICAgaWYgKCFlbnNlbWJsZSkge1xuICAgICAgdGhpcy50aHJvd05vdEZvdW5kRXJyb3IobmFtZSwgJ0Vuc2VtYmxlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHNMaXN0ID0gZW5zZW1ibGUubWV0YWRhdGEuZWxlbWVudHM/Lm1hcCgoZWxlbTogYW55KSA9PlxuICAgICAgYC0gJHtlbGVtLmVsZW1lbnRfbmFtZX0gKCR7ZWxlbS5lbGVtZW50X3R5cGV9KSAtICR7ZWxlbS5yb2xlfSwgcHJpb3JpdHk6ICR7ZWxlbS5wcmlvcml0eX0sIGFjdGl2YXRpb246ICR7ZWxlbS5hY3RpdmF0aW9ufWBcbiAgICApLmpvaW4oJ1xcbicpIHx8ICdObyBlbGVtZW50cyBjb25maWd1cmVkJztcblxuICAgIGNvbnN0IGRldGFpbHMgPSBbXG4gICAgICBg8J+OrSAqKiR7ZW5zZW1ibGUubWV0YWRhdGEubmFtZX0qKmAsXG4gICAgICBgJHtlbnNlbWJsZS5tZXRhZGF0YS5kZXNjcmlwdGlvbn1gLFxuICAgICAgYGAsXG4gICAgICBgKipTdGF0dXMqKjogJHtlbnNlbWJsZS5nZXRTdGF0dXMoKX1gLFxuICAgICAgYCoqVmVyc2lvbioqOiAke2Vuc2VtYmxlLm1ldGFkYXRhLnZlcnNpb24gfHwgJzEuMC4wJ31gLFxuICAgICAgYCoqQWN0aXZhdGlvbiBTdHJhdGVneSoqOiAkeyhlbnNlbWJsZS5tZXRhZGF0YSBhcyBhbnkpLmFjdGl2YXRpb25TdHJhdGVneSB8fCAnc2VxdWVudGlhbCd9YCxcbiAgICAgIGAqKkNvbmZsaWN0IFJlc29sdXRpb24qKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5jb25mbGljdFJlc29sdXRpb24gfHwgJ2xhc3Qtd3JpdGUnfWAsXG4gICAgICBgKipDb250ZXh0IFNoYXJpbmcqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5jb250ZXh0U2hhcmluZyB8fCAnc2VsZWN0aXZlJ31gLFxuICAgICAgYCoqQWxsb3dzIE5lc3RpbmcqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5hbGxvd05lc3RlZCA/ICdZZXMnIDogJ05vJ31gLFxuICAgICAgYCoqTWF4IE5lc3RpbmcgRGVwdGgqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5tYXhOZXN0aW5nRGVwdGggfHwgNX1gLFxuICAgICAgYGAsXG4gICAgICBgKipFbGVtZW50cyoqICgke2Vuc2VtYmxlLm1ldGFkYXRhLmVsZW1lbnRzPy5sZW5ndGggfHwgMH0pOmAsXG4gICAgICBlbGVtZW50c0xpc3RcbiAgICBdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBkZXRhaWxzLmpvaW4oJ1xcbicpXG4gICAgICB9XVxuICAgIH07XG4gIH1cbn1cbiJdfQ==