UNPKG

@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.

148 lines 19 kB
/** * MemoryActivationStrategy - Strategy for memory element activation * * Handles activation, deactivation, and status tracking for memory elements. * Issue #18 Phase 4: Context-loading strategy with state management */ import { BaseActivationStrategy } from './BaseActivationStrategy.js'; export class MemoryActivationStrategy extends BaseActivationStrategy { memoryManager; constructor(memoryManager) { super(); this.memoryManager = memoryManager; } /** * Activate a memory * Issue #18 Phase 4: Context-loading activation strategy * - Load memory entries into active context * - Apply retention policies if configured * - Track activation in manager's active set */ async activate(name, context) { // Use the manager's activation method which tracks active memories const result = await this.memoryManager.activateMemory(name); if (!result.success || !result.memory) { return this.createNotFoundResponse(name, 'Memory'); } const memory = result.memory; // Get memory statistics for context loading information const stats = memory.getStats(); const retentionDays = memory.metadata.retentionDays || 'permanent'; const tags = memory.metadata.tags?.join(', ') || 'none'; // Build activation response with context-loading information const parts = [ `✅ Memory '${memory.metadata.name}' activated - ${stats.totalEntries} entries loaded into context`, '' ]; // Check if context was provided for additional activation options const hasActivationContext = context && Object.keys(context).length > 0; const autoLoadRequested = context?.autoLoad === true; if (autoLoadRequested) { // Auto-load activation context parts.push('Memory activates and automatically loads entries'); } else if (hasActivationContext) { // Other activation contexts parts.push('Memory context loaded and applied with specified options'); } else { // Default activation parts.push('Memory becomes active, context loaded into working set'); } parts.push(''); parts.push(`**Retention**: ${retentionDays} days`); parts.push(`**Tags**: ${tags}`); parts.push(`**Entries**: ${stats.totalEntries}`); if (stats.totalSize > 0) { parts.push(`**Size**: ${stats.totalSize} bytes`); } parts.push(''); parts.push('This memory is now available for context and will be used to enhance responses.'); const gatekeeperWarning = this.formatGatekeeperValidityWarning(memory.metadata); if (gatekeeperWarning) { parts.push(gatekeeperWarning); } return { content: [{ type: "text", text: parts.join('\n') }] }; } /** * Deactivate a memory * Issue #18 Phase 4: Use manager's deactivation method * * @throws {ElementNotFoundError} When memory does not exist * @see Issue #275 - Handlers return success=true for missing elements */ async deactivate(name) { const result = await this.memoryManager.deactivateMemory(name); if (!result.success) { this.throwNotFoundError(name, 'Memory'); } return this.createSuccessResponse(result.message); } /** * Get all active memories * Issue #18 Phase 4: Use manager's getActiveMemories method */ async getActiveElements() { // Use the manager's method to get active memories directly const activeMemories = await this.memoryManager.getActiveMemories(); if (activeMemories.length === 0) { return { content: [{ type: "text", text: "🧠 No active memories" }] }; } const memoryList = activeMemories.map(m => { const tags = m.metadata.tags?.join(', ') || 'none'; const retentionDays = m.metadata.retentionDays || 'permanent'; return `🧠 ${m.metadata.name} (Tags: ${tags}) - ${retentionDays} days retention`; }).join('\n'); return { content: [{ type: "text", text: `Active memories:\n${memoryList}` }] }; } /** * Get detailed information about a memory * Extracted from ElementCRUDHandler.ts lines 772-805 * * @throws {ElementNotFoundError} When memory does not exist * @see Issue #275 - Handlers return success=true for missing elements */ async getElementDetails(name) { // Use flexible finding to support both display name and filename const allMemories = await this.memoryManager.list(); const memory = await this.findElementFlexibly(name, allMemories); if (!memory) { this.throwNotFoundError(name, 'Memory'); } const details = [ `🧠 **${memory.metadata.name}**`, `${memory.metadata.description}`, ``, `**Status**: ${memory.getStatus()}`, `**Retention**: ${memory.metadata.retentionDays || 'permanent'} days`, `**Tags**: ${memory.metadata.tags?.join(', ') || 'none'}`, `**Storage Backend**: ${memory.metadata.storageBackend || 'file'}`, `**Privacy Level**: ${memory.metadata.privacyLevel || 'private'}`, ``, `**Content**:`, memory.content || 'No content stored' ]; return { content: [{ type: "text", text: details.join('\n') }] }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVtb3J5QWN0aXZhdGlvblN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hhbmRsZXJzL3N0cmF0ZWdpZXMvTWVtb3J5QWN0aXZhdGlvblN0cmF0ZWd5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBR0gsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFHckUsTUFBTSxPQUFPLHdCQUF5QixTQUFRLHNCQUFzQjtJQUNyQztJQUE3QixZQUE2QixhQUE0QjtRQUN2RCxLQUFLLEVBQUUsQ0FBQztRQURtQixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtJQUV6RCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFZLEVBQUUsT0FBNkI7UUFDeEQsbUVBQW1FO1FBQ25FLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEMsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBRTdCLHdEQUF3RDtRQUN4RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEMsTUFBTSxhQUFhLEdBQUksTUFBTSxDQUFDLFFBQWdCLENBQUMsYUFBYSxJQUFJLFdBQVcsQ0FBQztRQUM1RSxNQUFNLElBQUksR0FBSSxNQUFNLENBQUMsUUFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQztRQUVqRSw2REFBNkQ7UUFDN0QsTUFBTSxLQUFLLEdBQUc7WUFD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QUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNLEVBQUU7WUFDbEUsd0JBQXlCLE1BQU0sQ0FBQyxRQUFnQixDQUFDLGNBQWMsSUFBSSxNQUFNLEVBQUU7WUFDM0Usc0JBQXVCLE1BQU0sQ0FBQyxRQUFnQixDQUFDLFlBQVksSUFBSSxTQUFTLEVBQUU7WUFDMUUsRUFBRTtZQUNGLGNBQWM7WUFDZCxNQUFNLENBQUMsT0FBTyxJQUFJLG1CQUFtQjtTQUN0QyxDQUFDO1FBRUYsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDO29CQUNSLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztpQkFDekIsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1lbW9yeUFjdGl2YXRpb25TdHJhdGVneSAtIFN0cmF0ZWd5IGZvciBtZW1vcnkgZWxlbWVudCBhY3RpdmF0aW9uXG4gKlxuICogSGFuZGxlcyBhY3RpdmF0aW9uLCBkZWFjdGl2YXRpb24sIGFuZCBzdGF0dXMgdHJhY2tpbmcgZm9yIG1lbW9yeSBlbGVtZW50cy5cbiAqIElzc3VlICMxOCBQaGFzZSA0OiBDb250ZXh0LWxvYWRpbmcgc3RyYXRlZ3kgd2l0aCBzdGF0ZSBtYW5hZ2VtZW50XG4gKi9cblxuaW1wb3J0IHsgTWVtb3J5TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL21lbW9yaWVzL01lbW9yeU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgQmFzZUFjdGl2YXRpb25TdHJhdGVneSB9IGZyb20gJy4vQmFzZUFjdGl2YXRpb25TdHJhdGVneS5qcyc7XG5pbXBvcnQgeyBFbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5LCBNQ1BSZXNwb25zZSB9IGZyb20gJy4vRWxlbWVudEFjdGl2YXRpb25TdHJhdGVneS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNZW1vcnlBY3RpdmF0aW9uU3RyYXRlZ3kgZXh0ZW5kcyBCYXNlQWN0aXZhdGlvblN0cmF0ZWd5IGltcGxlbWVudHMgRWxlbWVudEFjdGl2YXRpb25TdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgbWVtb3J5TWFuYWdlcjogTWVtb3J5TWFuYWdlcikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQWN0aXZhdGUgYSBtZW1vcnlcbiAgICogSXNzdWUgIzE4IFBoYXNlIDQ6IENvbnRleHQtbG9hZGluZyBhY3RpdmF0aW9uIHN0cmF0ZWd5XG4gICAqIC0gTG9hZCBtZW1vcnkgZW50cmllcyBpbnRvIGFjdGl2ZSBjb250ZXh0XG4gICAqIC0gQXBwbHkgcmV0ZW50aW9uIHBvbGljaWVzIGlmIGNvbmZpZ3VyZWRcbiAgICogLSBUcmFjayBhY3RpdmF0aW9uIGluIG1hbmFnZXIncyBhY3RpdmUgc2V0XG4gICAqL1xuICBhc3luYyBhY3RpdmF0ZShuYW1lOiBzdHJpbmcsIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIFVzZSB0aGUgbWFuYWdlcidzIGFjdGl2YXRpb24gbWV0aG9kIHdoaWNoIHRyYWNrcyBhY3RpdmUgbWVtb3JpZXNcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm1lbW9yeU1hbmFnZXIuYWN0aXZhdGVNZW1vcnkobmFtZSk7XG5cbiAgICBpZiAoIXJlc3VsdC5zdWNjZXNzIHx8ICFyZXN1bHQubWVtb3J5KSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVOb3RGb3VuZFJlc3BvbnNlKG5hbWUsICdNZW1vcnknKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZW1vcnkgPSByZXN1bHQubWVtb3J5O1xuXG4gICAgLy8gR2V0IG1lbW9yeSBzdGF0aXN0aWNzIGZvciBjb250ZXh0IGxvYWRpbmcgaW5mb3JtYXRpb25cbiAgICBjb25zdCBzdGF0cyA9IG1lbW9yeS5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHJldGVudGlvbkRheXMgPSAobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50JztcbiAgICBjb25zdCB0YWdzID0gKG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnO1xuXG4gICAgLy8gQnVpbGQgYWN0aXZhdGlvbiByZXNwb25zZSB3aXRoIGNvbnRleHQtbG9hZGluZyBpbmZvcm1hdGlvblxuICAgIGNvbnN0IHBhcnRzID0gW1xuICAgICAgYOKchSBNZW1vcnkgJyR7bWVtb3J5Lm1ldGFkYXRhLm5hbWV9JyBhY3RpdmF0ZWQgLSAke3N0YXRzLnRvdGFsRW50cmllc30gZW50cmllcyBsb2FkZWQgaW50byBjb250ZXh0YCxcbiAgICAgICcnXG4gICAgXTtcblxuICAgIC8vIENoZWNrIGlmIGNvbnRleHQgd2FzIHByb3ZpZGVkIGZvciBhZGRpdGlvbmFsIGFjdGl2YXRpb24gb3B0aW9uc1xuICAgIGNvbnN0IGhhc0FjdGl2YXRpb25Db250ZXh0ID0gY29udGV4dCAmJiBPYmplY3Qua2V5cyhjb250ZXh0KS5sZW5ndGggPiAwO1xuICAgIGNvbnN0IGF1dG9Mb2FkUmVxdWVzdGVkID0gY29udGV4dD8uYXV0b0xvYWQgPT09IHRydWU7XG5cbiAgICBpZiAoYXV0b0xvYWRSZXF1ZXN0ZWQpIHtcbiAgICAgIC8vIEF1dG8tbG9hZCBhY3RpdmF0aW9uIGNvbnRleHRcbiAgICAgIHBhcnRzLnB1c2goJ01lbW9yeSBhY3RpdmF0ZXMgYW5kIGF1dG9tYXRpY2FsbHkgbG9hZHMgZW50cmllcycpO1xuICAgIH0gZWxzZSBpZiAoaGFzQWN0aXZhdGlvbkNvbnRleHQpIHtcbiAgICAgIC8vIE90aGVyIGFjdGl2YXRpb24gY29udGV4dHNcbiAgICAgIHBhcnRzLnB1c2goJ01lbW9yeSBjb250ZXh0IGxvYWRlZCBhbmQgYXBwbGllZCB3aXRoIHNwZWNpZmllZCBvcHRpb25zJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgYWN0aXZhdGlvblxuICAgICAgcGFydHMucHVzaCgnTWVtb3J5IGJlY29tZXMgYWN0aXZlLCBjb250ZXh0IGxvYWRlZCBpbnRvIHdvcmtpbmcgc2V0Jyk7XG4gICAgfVxuXG4gICAgcGFydHMucHVzaCgnJyk7XG4gICAgcGFydHMucHVzaChgKipSZXRlbnRpb24qKjogJHtyZXRlbnRpb25EYXlzfSBkYXlzYCk7XG4gICAgcGFydHMucHVzaChgKipUYWdzKio6ICR7dGFnc31gKTtcbiAgICBwYXJ0cy5wdXNoKGAqKkVudHJpZXMqKjogJHtzdGF0cy50b3RhbEVudHJpZXN9YCk7XG5cbiAgICBpZiAoc3RhdHMudG90YWxTaXplID4gMCkge1xuICAgICAgcGFydHMucHVzaChgKipTaXplKio6ICR7c3RhdHMudG90YWxTaXplfSBieXRlc2ApO1xuICAgIH1cblxuICAgIHBhcnRzLnB1c2goJycpO1xuICAgIHBhcnRzLnB1c2goJ1RoaXMgbWVtb3J5IGlzIG5vdyBhdmFpbGFibGUgZm9yIGNvbnRleHQgYW5kIHdpbGwgYmUgdXNlZCB0byBlbmhhbmNlIHJlc3BvbnNlcy4nKTtcblxuICAgIGNvbnN0IGdhdGVrZWVwZXJXYXJuaW5nID0gdGhpcy5mb3JtYXRHYXRla2VlcGVyVmFsaWRpdHlXYXJuaW5nKG1lbW9yeS5tZXRhZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICBpZiAoZ2F0ZWtlZXBlcldhcm5pbmcpIHtcbiAgICAgIHBhcnRzLnB1c2goZ2F0ZWtlZXBlcldhcm5pbmcpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogcGFydHMuam9pbignXFxuJylcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWFjdGl2YXRlIGEgbWVtb3J5XG4gICAqIElzc3VlICMxOCBQaGFzZSA0OiBVc2UgbWFuYWdlcidzIGRlYWN0aXZhdGlvbiBtZXRob2RcbiAgICpcbiAgICogQHRocm93cyB7RWxlbWVudE5vdEZvdW5kRXJyb3J9IFdoZW4gbWVtb3J5IGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGRlYWN0aXZhdGUobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubWVtb3J5TWFuYWdlci5kZWFjdGl2YXRlTWVtb3J5KG5hbWUpO1xuXG4gICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgdGhpcy50aHJvd05vdEZvdW5kRXJyb3IobmFtZSwgJ01lbW9yeScpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZVN1Y2Nlc3NSZXNwb25zZShyZXN1bHQubWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBhY3RpdmUgbWVtb3JpZXNcbiAgICogSXNzdWUgIzE4IFBoYXNlIDQ6IFVzZSBtYW5hZ2VyJ3MgZ2V0QWN0aXZlTWVtb3JpZXMgbWV0aG9kXG4gICAqL1xuICBhc3luYyBnZXRBY3RpdmVFbGVtZW50cygpOiBQcm9taXNlPE1DUFJlc3BvbnNlPiB7XG4gICAgLy8gVXNlIHRoZSBtYW5hZ2VyJ3MgbWV0aG9kIHRvIGdldCBhY3RpdmUgbWVtb3JpZXMgZGlyZWN0bHlcbiAgICBjb25zdCBhY3RpdmVNZW1vcmllcyA9IGF3YWl0IHRoaXMubWVtb3J5TWFuYWdlci5nZXRBY3RpdmVNZW1vcmllcygpO1xuXG4gICAgaWYgKGFjdGl2ZU1lbW9yaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBcIvCfp6AgTm8gYWN0aXZlIG1lbW9yaWVzXCJcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgbWVtb3J5TGlzdCA9IGFjdGl2ZU1lbW9yaWVzLm1hcChtID0+IHtcbiAgICAgIGNvbnN0IHRhZ3MgPSAobS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnO1xuICAgICAgY29uc3QgcmV0ZW50aW9uRGF5cyA9IChtLm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50JztcbiAgICAgIHJldHVybiBg8J+noCAke20ubWV0YWRhdGEubmFtZX0gKFRhZ3M6ICR7dGFnc30pIC0gJHtyZXRlbnRpb25EYXlzfSBkYXlzIHJldGVudGlvbmA7XG4gICAgfSkuam9pbignXFxuJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IGBBY3RpdmUgbWVtb3JpZXM6XFxuJHttZW1vcnlMaXN0fWBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBtZW1vcnlcbiAgICogRXh0cmFjdGVkIGZyb20gRWxlbWVudENSVURIYW5kbGVyLnRzIGxpbmVzIDc3Mi04MDVcbiAgICpcbiAgICogQHRocm93cyB7RWxlbWVudE5vdEZvdW5kRXJyb3J9IFdoZW4gbWVtb3J5IGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGdldEVsZW1lbnREZXRhaWxzKG5hbWU6IHN0cmluZyk6IFByb21pc2U8TUNQUmVzcG9uc2U+IHtcbiAgICAvLyBVc2UgZmxleGlibGUgZmluZGluZyB0byBzdXBwb3J0IGJvdGggZGlzcGxheSBuYW1lIGFuZCBmaWxlbmFtZVxuICAgIGNvbnN0IGFsbE1lbW9yaWVzID0gYXdhaXQgdGhpcy5tZW1vcnlNYW5hZ2VyLmxpc3QoKTtcbiAgICBjb25zdCBtZW1vcnkgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50RmxleGlibHkobmFtZSwgYWxsTWVtb3JpZXMpO1xuICAgIGlmICghbWVtb3J5KSB7XG4gICAgICB0aGlzLnRocm93Tm90Rm91bmRFcnJvcihuYW1lLCAnTWVtb3J5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGV0YWlscyA9IFtcbiAgICAgIGDwn6egICoqJHttZW1vcnkubWV0YWRhdGEubmFtZX0qKmAsXG4gICAgICBgJHttZW1vcnkubWV0YWRhdGEuZGVzY3JpcHRpb259YCxcbiAgICAgIGBgLFxuICAgICAgYCoqU3RhdHVzKio6ICR7bWVtb3J5LmdldFN0YXR1cygpfWAsXG4gICAgICBgKipSZXRlbnRpb24qKjogJHsobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50J30gZGF5c2AsXG4gICAgICBgKipUYWdzKio6ICR7KG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnfWAsXG4gICAgICBgKipTdG9yYWdlIEJhY2tlbmQqKjogJHsobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkuc3RvcmFnZUJhY2tlbmQgfHwgJ2ZpbGUnfWAsXG4gICAgICBgKipQcml2YWN5IExldmVsKio6ICR7KG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnByaXZhY3lMZXZlbCB8fCAncHJpdmF0ZSd9YCxcbiAgICAgIGBgLFxuICAgICAgYCoqQ29udGVudCoqOmAsXG4gICAgICBtZW1vcnkuY29udGVudCB8fCAnTm8gY29udGVudCBzdG9yZWQnXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogZGV0YWlscy5qb2luKCdcXG4nKVxuICAgICAgfV1cbiAgICB9O1xuICB9XG59XG4iXX0=