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.

223 lines 30.6 kB
/** * Persona element class implementing IElement interface. * Represents a behavioral profile that defines AI personality and interaction style. */ import { BaseElement } from '../elements/BaseElement.js'; import { ElementType } from '../portfolio/types.js'; import { logger } from '../utils/logger.js'; import matter from 'gray-matter'; export class PersonaElement extends BaseElement { content; filename; constructor(metadata, content = '', filename = '') { super(ElementType.PERSONA, metadata); this.content = content; this.filename = filename; // Ensure persona-specific metadata this.metadata = { ...this.metadata, triggers: metadata.triggers || [], category: metadata.category || 'personal', age_rating: metadata.age_rating || 'all', content_flags: metadata.content_flags || [], ai_generated: metadata.ai_generated || false, generation_method: metadata.generation_method || 'human', price: metadata.price || 'free', license: metadata.license || 'CC-BY-SA-4.0', created_date: metadata.created_date || new Date().toISOString().split('T')[0] }; } /** * Create PersonaElement from legacy Persona interface */ static fromLegacy(legacyPersona) { const metadata = { name: legacyPersona.metadata.name, description: legacyPersona.metadata.description, author: legacyPersona.metadata.author, version: legacyPersona.metadata.version, triggers: legacyPersona.metadata.triggers, category: legacyPersona.metadata.category, age_rating: legacyPersona.metadata.age_rating, content_flags: legacyPersona.metadata.content_flags, ai_generated: legacyPersona.metadata.ai_generated, generation_method: legacyPersona.metadata.generation_method, price: legacyPersona.metadata.price, revenue_split: legacyPersona.metadata.revenue_split, license: legacyPersona.metadata.license, created_date: legacyPersona.metadata.created_date }; const persona = new PersonaElement(metadata, legacyPersona.content, legacyPersona.filename); // Preserve the legacy unique_id as the element id persona.id = legacyPersona.unique_id; return persona; } /** * Convert to legacy Persona interface for backward compatibility */ toLegacy() { const legacyMetadata = { name: this.metadata.name, description: this.metadata.description, unique_id: this.id, author: this.metadata.author, triggers: this.metadata.triggers, version: this.metadata.version, category: this.metadata.category, age_rating: this.metadata.age_rating, content_flags: this.metadata.content_flags, ai_generated: this.metadata.ai_generated, generation_method: this.metadata.generation_method, price: this.metadata.price, revenue_split: this.metadata.revenue_split, license: this.metadata.license, created_date: this.metadata.created_date }; return { metadata: legacyMetadata, content: this.content, filename: this.filename, unique_id: this.id }; } /** * Persona-specific validation */ validate() { const result = super.validate(); // Initialize arrays if not present if (!result.errors) result.errors = []; if (!result.warnings) result.warnings = []; // Add persona-specific validation rules // Content should not be empty if (!this.content || this.content.trim().length === 0) { result.errors.push({ field: 'content', message: 'Persona content cannot be empty', code: 'EMPTY_CONTENT' }); } // Content should be reasonable length if (this.content && this.content.length > 10000) { result.warnings.push({ field: 'content', message: 'Persona content is very long, consider breaking it down', severity: 'medium' }); } // Triggers should be reasonable if (this.metadata.triggers && this.metadata.triggers.length > 10) { result.warnings.push({ field: 'triggers', message: 'Many triggers may cause activation conflicts', severity: 'medium' }); } // Check for adult content flags if (this.metadata.age_rating === '18+' && !this.metadata.content_flags?.includes('adult')) { result.warnings.push({ field: 'content_flags', message: '18+ content should include "adult" in content_flags', severity: 'low' }); } // Update the valid flag based on final errors result.valid = (result.errors?.length || 0) === 0; return result; } /** * Serialize persona to markdown format */ serialize() { const frontmatter = { name: this.metadata.name, description: this.metadata.description, unique_id: this.id, author: this.metadata.author, triggers: this.metadata.triggers, version: this.metadata.version, category: this.metadata.category, age_rating: this.metadata.age_rating, content_flags: this.metadata.content_flags, ai_generated: this.metadata.ai_generated, generation_method: this.metadata.generation_method, price: this.metadata.price, revenue_split: this.metadata.revenue_split, license: this.metadata.license, created_date: this.metadata.created_date }; // Remove undefined values const cleanFrontmatter = Object.fromEntries(Object.entries(frontmatter).filter(([_, value]) => value !== undefined)); const yamlFrontmatter = Object.entries(cleanFrontmatter) .map(([key, value]) => { if (Array.isArray(value)) { if (value.length === 0) return `${key}: []`; return `${key}:\n${value.map(item => ` - ${item}`).join('\n')}`; } return `${key}: ${JSON.stringify(value)}`; }) .join('\n'); return `---\n${yamlFrontmatter}\n---\n\n${this.content}`; } /** * Deserialize persona from markdown format */ deserialize(data) { try { const parsed = matter(data); const metadata = parsed.data; // Update metadata this.metadata = { ...this.metadata, name: metadata.name, description: metadata.description, author: metadata.author, version: metadata.version, triggers: metadata.triggers, category: metadata.category, age_rating: metadata.age_rating, content_flags: metadata.content_flags, ai_generated: metadata.ai_generated, generation_method: metadata.generation_method, price: metadata.price, revenue_split: metadata.revenue_split, license: metadata.license, created_date: metadata.created_date }; // Update content (trim to remove leading/trailing whitespace) this.content = parsed.content.trim(); // Update ID if provided if (metadata.unique_id) { this.id = metadata.unique_id; } this._isDirty = true; logger.debug(`Deserialized persona: ${this.metadata.name}`); } catch (error) { logger.error(`Failed to deserialize persona: ${error}`); throw new Error(`Deserialization failed: ${error}`); } } /** * Persona activation lifecycle */ async activate() { logger.info(`Activating persona: ${this.metadata.name} (${this.id})`); // Personas don't need special activation logic currently // But this provides a hook for future enhancements await super.activate?.(); } /** * Persona deactivation lifecycle */ async deactivate() { logger.info(`Deactivating persona: ${this.metadata.name} (${this.id})`); // Personas don't need special deactivation logic currently // But this provides a hook for future enhancements await super.deactivate?.(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYUVsZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGVyc29uYS9QZXJzb25hRWxlbWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXBELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QyxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFnQmpDLE1BQU0sT0FBTyxjQUFlLFNBQVEsV0FBVztJQUN0QyxPQUFPLENBQVM7SUFDaEIsUUFBUSxDQUFTO0lBR3hCLFlBQVksUUFBeUMsRUFBRSxVQUFrQixFQUFFLEVBQUUsV0FBbUIsRUFBRTtRQUNoRyxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDaEIsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLElBQUksRUFBRTtZQUNqQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsSUFBSSxVQUFVO1lBQ3pDLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVSxJQUFJLEtBQUs7WUFDeEMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxhQUFhLElBQUksRUFBRTtZQUMzQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVksSUFBSSxLQUFLO1lBQzVDLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxpQkFBaUIsSUFBSSxPQUFPO1lBQ3hELEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLE1BQU07WUFDL0IsT0FB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QVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTlELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDYSxLQUFLLENBQUMsUUFBUTtRQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUV0RSx5REFBeUQ7UUFDekQsbURBQW1EO1FBRW5ELE1BQU0sS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ2EsS0FBSyxDQUFDLFVBQVU7UUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFeEUsMkRBQTJEO1FBQzNELG1EQUFtRDtRQUVuRCxNQUFNLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO0lBQzdCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGVyc29uYSBlbGVtZW50IGNsYXNzIGltcGxlbWVudGluZyBJRWxlbWVudCBpbnRlcmZhY2UuXG4gKiBSZXByZXNlbnRzIGEgYmVoYXZpb3JhbCBwcm9maWxlIHRoYXQgZGVmaW5lcyBBSSBwZXJzb25hbGl0eSBhbmQgaW50ZXJhY3Rpb24gc3R5bGUuXG4gKi9cblxuaW1wb3J0IHsgQmFzZUVsZW1lbnQgfSBmcm9tICcuLi9lbGVtZW50cy9CYXNlRWxlbWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudCwgSUVsZW1lbnRNZXRhZGF0YSwgRWxlbWVudFZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi90eXBlcy9lbGVtZW50cy9pbmRleC5qcyc7XG5pbXBvcnQgeyBFbGVtZW50VHlwZSB9IGZyb20gJy4uL3BvcnRmb2xpby90eXBlcy5qcyc7XG5pbXBvcnQgeyBQZXJzb25hTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wZXJzb25hLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgbWF0dGVyIGZyb20gJ2dyYXktbWF0dGVyJztcblxuLy8gRXh0ZW5kIElFbGVtZW50TWV0YWRhdGEgd2l0aCBwZXJzb25hLXNwZWNpZmljIGZpZWxkc1xuZXhwb3J0IGludGVyZmFjZSBQZXJzb25hRWxlbWVudE1ldGFkYXRhIGV4dGVuZHMgSUVsZW1lbnRNZXRhZGF0YSB7XG4gIHRyaWdnZXJzPzogc3RyaW5nW107XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICBhZ2VfcmF0aW5nPzogJ2FsbCcgfCAnMTMrJyB8ICcxOCsnO1xuICBjb250ZW50X2ZsYWdzPzogc3RyaW5nW107XG4gIGFpX2dlbmVyYXRlZD86IGJvb2xlYW47XG4gIGdlbmVyYXRpb25fbWV0aG9kPzogJ2h1bWFuJyB8ICdDaGF0R1BUJyB8ICdDbGF1ZGUnIHwgJ2h5YnJpZCc7XG4gIHByaWNlPzogc3RyaW5nO1xuICByZXZlbnVlX3NwbGl0Pzogc3RyaW5nO1xuICBsaWNlbnNlPzogc3RyaW5nO1xuICBjcmVhdGVkX2RhdGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQZXJzb25hRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IGltcGxlbWVudHMgSUVsZW1lbnQge1xuICBwdWJsaWMgY29udGVudDogc3RyaW5nO1xuICBwdWJsaWMgZmlsZW5hbWU6IHN0cmluZztcbiAgcHVibGljIGRlY2xhcmUgbWV0YWRhdGE6IFBlcnNvbmFFbGVtZW50TWV0YWRhdGE7XG5cbiAgY29uc3RydWN0b3IobWV0YWRhdGE6IFBhcnRpYWw8UGVyc29uYUVsZW1lbnRNZXRhZGF0YT4sIGNvbnRlbnQ6IHN0cmluZyA9ICcnLCBmaWxlbmFtZTogc3RyaW5nID0gJycpIHtcbiAgICBzdXBlcihFbGVtZW50VHlwZS5QRVJTT05BLCBtZXRhZGF0YSk7XG4gICAgdGhpcy5jb250ZW50ID0gY29udGVudDtcbiAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWU7XG4gICAgXG4gICAgLy8gRW5zdXJlIHBlcnNvbmEtc3BlY2lmaWMgbWV0YWRhdGFcbiAgICB0aGlzLm1ldGFkYXRhID0ge1xuICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIHRyaWdnZXJzOiBtZXRhZGF0YS50cmlnZ2VycyB8fCBbXSxcbiAgICAgIGNhdGVnb3J5OiBtZXRhZGF0YS5jYXRlZ29yeSB8fCAncGVyc29uYWwnLFxuICAgICAgYWdlX3JhdGluZzogbWV0YWRhdGEuYWdlX3JhdGluZyB8fCAnYWxsJyxcbiAgICAgIGNvbnRlbnRfZmxhZ3M6IG1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MgfHwgW10sXG4gICAgICBhaV9nZW5lcmF0ZWQ6IG1ldGFkYXRhLmFpX2dlbmVyYXRlZCB8fCBmYWxzZSxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiBtZXRhZGF0YS5nZW5lcmF0aW9uX21ldGhvZCB8fCAnaHVtYW4nLFxuICAgICAgcHJpY2U6IG1ldGFkYXRhLnByaWNlIHx8ICdmcmVlJyxcbiAgICAgIGxpY2Vuc2U6IG1ldGFkYXRhLmxpY2Vuc2UgfHwgJ0NDLUJZLVNBLTQuMCcsXG4gICAgICBjcmVhdGVkX2RhdGU6IG1ldGFkYXRhLmNyZWF0ZWRfZGF0ZSB8fCBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIFBlcnNvbmFFbGVtZW50IGZyb20gbGVnYWN5IFBlcnNvbmEgaW50ZXJmYWNlXG4gICAqL1xuICBzdGF0aWMgZnJvbUxlZ2FjeShsZWdhY3lQZXJzb25hOiB7IG1ldGFkYXRhOiBQZXJzb25hTWV0YWRhdGE7IGNvbnRlbnQ6IHN0cmluZzsgZmlsZW5hbWU6IHN0cmluZzsgdW5pcXVlX2lkOiBzdHJpbmcgfSk6IFBlcnNvbmFFbGVtZW50IHtcbiAgICBjb25zdCBtZXRhZGF0YTogUGFydGlhbDxQZXJzb25hRWxlbWVudE1ldGFkYXRhPiA9IHtcbiAgICAgIG5hbWU6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEubmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgYXV0aG9yOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmF1dGhvcixcbiAgICAgIHZlcnNpb246IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIHRyaWdnZXJzOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLnRyaWdnZXJzLFxuICAgICAgY2F0ZWdvcnk6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuY2F0ZWdvcnksXG4gICAgICBhZ2VfcmF0aW5nOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmFnZV9yYXRpbmcsXG4gICAgICBjb250ZW50X2ZsYWdzOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MsXG4gICAgICBhaV9nZW5lcmF0ZWQ6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuYWlfZ2VuZXJhdGVkLFxuICAgICAgZ2VuZXJhdGlvbl9tZXRob2Q6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuZ2VuZXJhdGlvbl9tZXRob2QsXG4gICAgICBwcmljZTogbGVnYWN5UGVyc29uYS5tZXRhZGF0YS5wcmljZSxcbiAgICAgIHJldmVudWVfc3BsaXQ6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEucmV2ZW51ZV9zcGxpdCxcbiAgICAgIGxpY2Vuc2U6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEubGljZW5zZSxcbiAgICAgIGNyZWF0ZWRfZGF0ZTogbGVnYWN5UGVyc29uYS5tZXRhZGF0YS5jcmVhdGVkX2RhdGVcbiAgICB9O1xuXG4gICAgY29uc3QgcGVyc29uYSA9IG5ldyBQZXJzb25hRWxlbWVudChtZXRhZGF0YSwgbGVnYWN5UGVyc29uYS5jb250ZW50LCBsZWdhY3lQZXJzb25hLmZpbGVuYW1lKTtcbiAgICBcbiAgICAvLyBQcmVzZXJ2ZSB0aGUgbGVnYWN5IHVuaXF1ZV9pZCBhcyB0aGUgZWxlbWVudCBpZFxuICAgIHBlcnNvbmEuaWQgPSBsZWdhY3lQZXJzb25hLnVuaXF1ZV9pZDtcbiAgICBcbiAgICByZXR1cm4gcGVyc29uYTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IHRvIGxlZ2FjeSBQZXJzb25hIGludGVyZmFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgKi9cbiAgdG9MZWdhY3koKTogeyBtZXRhZGF0YTogUGVyc29uYU1ldGFkYXRhOyBjb250ZW50OiBzdHJpbmc7IGZpbGVuYW1lOiBzdHJpbmc7IHVuaXF1ZV9pZDogc3RyaW5nIH0ge1xuICAgIGNvbnN0IGxlZ2FjeU1ldGFkYXRhOiBQZXJzb25hTWV0YWRhdGEgPSB7XG4gICAgICBuYW1lOiB0aGlzLm1ldGFkYXRhLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZCxcbiAgICAgIGF1dGhvcjogdGhpcy5tZXRhZGF0YS5hdXRob3IsXG4gICAgICB0cmlnZ2VyczogdGhpcy5tZXRhZGF0YS50cmlnZ2VycyxcbiAgICAgIHZlcnNpb246IHRoaXMubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIGNhdGVnb3J5OiB0aGlzLm1ldGFkYXRhLmNhdGVnb3J5LFxuICAgICAgYWdlX3JhdGluZzogdGhpcy5tZXRhZGF0YS5hZ2VfcmF0aW5nLFxuICAgICAgY29udGVudF9mbGFnczogdGhpcy5tZXRhZGF0YS5jb250ZW50X2ZsYWdzLFxuICAgICAgYWlfZ2VuZXJhdGVkOiB0aGlzLm1ldGFkYXRhLmFpX2dlbmVyYXRlZCxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiB0aGlzLm1ldGFkYXRhLmdlbmVyYXRpb25fbWV0aG9kLFxuICAgICAgcHJpY2U6IHRoaXMubWV0YWRhdGEucHJpY2UsXG4gICAgICByZXZlbnVlX3NwbGl0OiB0aGlzLm1ldGFkYXRhLnJldmVudWVfc3BsaXQsXG4gICAgICBsaWNlbnNlOiB0aGlzLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgICBjcmVhdGVkX2RhdGU6IHRoaXMubWV0YWRhdGEuY3JlYXRlZF9kYXRlXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBtZXRhZGF0YTogbGVnYWN5TWV0YWRhdGEsXG4gICAgICBjb250ZW50OiB0aGlzLmNvbnRlbnQsXG4gICAgICBmaWxlbmFtZTogdGhpcy5maWxlbmFtZSxcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUGVyc29uYS1zcGVjaWZpYyB2YWxpZGF0aW9uXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgdmFsaWRhdGUoKTogRWxlbWVudFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLnZhbGlkYXRlKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheXMgaWYgbm90IHByZXNlbnRcbiAgICBpZiAoIXJlc3VsdC5lcnJvcnMpIHJlc3VsdC5lcnJvcnMgPSBbXTtcbiAgICBpZiAoIXJlc3VsdC53YXJuaW5ncykgcmVzdWx0Lndhcm5pbmdzID0gW107XG4gICAgXG4gICAgLy8gQWRkIHBlcnNvbmEtc3BlY2lmaWMgdmFsaWRhdGlvbiBydWxlc1xuICAgIFxuICAgIC8vIENvbnRlbnQgc2hvdWxkIG5vdCBiZSBlbXB0eVxuICAgIGlmICghdGhpcy5jb250ZW50IHx8IHRoaXMuY29udGVudC50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXN1bHQuZXJyb3JzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2NvbnRlbnQnLFxuICAgICAgICBtZXNzYWdlOiAnUGVyc29uYSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScsXG4gICAgICAgIGNvZGU6ICdFTVBUWV9DT05URU5UJ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29udGVudCBzaG91bGQgYmUgcmVhc29uYWJsZSBsZW5ndGhcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5sZW5ndGggPiAxMDAwMCkge1xuICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2NvbnRlbnQnLFxuICAgICAgICBtZXNzYWdlOiAnUGVyc29uYSBjb250ZW50IGlzIHZlcnkgbG9uZywgY29uc2lkZXIgYnJlYWtpbmcgaXQgZG93bicsXG4gICAgICAgIHNldmVyaXR5OiAnbWVkaXVtJ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVHJpZ2dlcnMgc2hvdWxkIGJlIHJlYXNvbmFibGVcbiAgICBpZiAodGhpcy5tZXRhZGF0YS50cmlnZ2VycyAmJiB0aGlzLm1ldGFkYXRhLnRyaWdnZXJzLmxlbmd0aCA+IDEwKSB7XG4gICAgICByZXN1bHQud2FybmluZ3MucHVzaCh7XG4gICAgICAgIGZpZWxkOiAndHJpZ2dlcnMnLFxuICAgICAgICBtZXNzYWdlOiAnTWFueSB0cmlnZ2VycyBtYXkgY2F1c2UgYWN0aXZhdGlvbiBjb25mbGljdHMnLFxuICAgICAgICBzZXZlcml0eTogJ21lZGl1bSdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBhZHVsdCBjb250ZW50IGZsYWdzXG4gICAgaWYgKHRoaXMubWV0YWRhdGEuYWdlX3JhdGluZyA9PT0gJzE4KycgJiYgIXRoaXMubWV0YWRhdGEuY29udGVudF9mbGFncz8uaW5jbHVkZXMoJ2FkdWx0JykpIHtcbiAgICAgIHJlc3VsdC53YXJuaW5ncy5wdXNoKHtcbiAgICAgICAgZmllbGQ6ICdjb250ZW50X2ZsYWdzJyxcbiAgICAgICAgbWVzc2FnZTogJzE4KyBjb250ZW50IHNob3VsZCBpbmNsdWRlIFwiYWR1bHRcIiBpbiBjb250ZW50X2ZsYWdzJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdsb3cnXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgdGhlIHZhbGlkIGZsYWcgYmFzZWQgb24gZmluYWwgZXJyb3JzXG4gICAgcmVzdWx0LnZhbGlkID0gKHJlc3VsdC5lcnJvcnM/Lmxlbmd0aCB8fCAwKSA9PT0gMDtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogU2VyaWFsaXplIHBlcnNvbmEgdG8gbWFya2Rvd24gZm9ybWF0XG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZnJvbnRtYXR0ZXIgPSB7XG4gICAgICBuYW1lOiB0aGlzLm1ldGFkYXRhLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZCxcbiAgICAgIGF1dGhvcjogdGhpcy5tZXRhZGF0YS5hdXRob3IsXG4gICAgICB0cmlnZ2VyczogdGhpcy5tZXRhZGF0YS50cmlnZ2VycyxcbiAgICAgIHZlcnNpb246IHRoaXMubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIGNhdGVnb3J5OiB0aGlzLm1ldGFkYXRhLmNhdGVnb3J5LFxuICAgICAgYWdlX3JhdGluZzogdGhpcy5tZXRhZGF0YS5hZ2VfcmF0aW5nLFxuICAgICAgY29udGVudF9mbGFnczogdGhpcy5tZXRhZGF0YS5jb250ZW50X2ZsYWdzLFxuICAgICAgYWlfZ2VuZXJhdGVkOiB0aGlzLm1ldGFkYXRhLmFpX2dlbmVyYXRlZCxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiB0aGlzLm1ldGFkYXRhLmdlbmVyYXRpb25fbWV0aG9kLFxuICAgICAgcHJpY2U6IHRoaXMubWV0YWRhdGEucHJpY2UsXG4gICAgICByZXZlbnVlX3NwbGl0OiB0aGlzLm1ldGFkYXRhLnJldmVudWVfc3BsaXQsXG4gICAgICBsaWNlbnNlOiB0aGlzLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgICBjcmVhdGVkX2RhdGU6IHRoaXMubWV0YWRhdGEuY3JlYXRlZF9kYXRlXG4gICAgfTtcblxuICAgIC8vIFJlbW92ZSB1bmRlZmluZWQgdmFsdWVzXG4gICAgY29uc3QgY2xlYW5Gcm9udG1hdHRlciA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGZyb250bWF0dGVyKS5maWx0ZXIoKFtfLCB2YWx1ZV0pID0+IHZhbHVlICE9PSB1bmRlZmluZWQpXG4gICAgKTtcblxuICAgIGNvbnN0IHlhbWxGcm9udG1hdHRlciA9IE9iamVjdC5lbnRyaWVzKGNsZWFuRnJvbnRtYXR0ZXIpXG4gICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGAke2tleX06IFtdYDtcbiAgICAgICAgICByZXR1cm4gYCR7a2V5fTpcXG4ke3ZhbHVlLm1hcChpdGVtID0+IGAgIC0gJHtpdGVtfWApLmpvaW4oJ1xcbicpfWA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGAke2tleX06ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfWA7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJ1xcbicpO1xuXG4gICAgcmV0dXJuIGAtLS1cXG4ke3lhbWxGcm9udG1hdHRlcn1cXG4tLS1cXG5cXG4ke3RoaXMuY29udGVudH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIERlc2VyaWFsaXplIHBlcnNvbmEgZnJvbSBtYXJrZG93biBmb3JtYXRcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBkZXNlcmlhbGl6ZShkYXRhOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gbWF0dGVyKGRhdGEpO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBwYXJzZWQuZGF0YSBhcyBQZXJzb25hTWV0YWRhdGE7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBtZXRhZGF0YVxuICAgICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgICAgbmFtZTogbWV0YWRhdGEubmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb246IG1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgICBhdXRob3I6IG1ldGFkYXRhLmF1dGhvcixcbiAgICAgICAgdmVyc2lvbjogbWV0YWRhdGEudmVyc2lvbixcbiAgICAgICAgdHJpZ2dlcnM6IG1ldGFkYXRhLnRyaWdnZXJzLFxuICAgICAgICBjYXRlZ29yeTogbWV0YWRhdGEuY2F0ZWdvcnksXG4gICAgICAgIGFnZV9yYXRpbmc6IG1ldGFkYXRhLmFnZV9yYXRpbmcsXG4gICAgICAgIGNvbnRlbnRfZmxhZ3M6IG1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MsXG4gICAgICAgIGFpX2dlbmVyYXRlZDogbWV0YWRhdGEuYWlfZ2VuZXJhdGVkLFxuICAgICAgICBnZW5lcmF0aW9uX21ldGhvZDogbWV0YWRhdGEuZ2VuZXJhdGlvbl9tZXRob2QsXG4gICAgICAgIHByaWNlOiBtZXRhZGF0YS5wcmljZSxcbiAgICAgICAgcmV2ZW51ZV9zcGxpdDogbWV0YWRhdGEucmV2ZW51ZV9zcGxpdCxcbiAgICAgICAgbGljZW5zZTogbWV0YWRhdGEubGljZW5zZSxcbiAgICAgICAgY3JlYXRlZF9kYXRlOiBtZXRhZGF0YS5jcmVhdGVkX2RhdGVcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBjb250ZW50ICh0cmltIHRvIHJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UpXG4gICAgICB0aGlzLmNvbnRlbnQgPSBwYXJzZWQuY29udGVudC50cmltKCk7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBJRCBpZiBwcm92aWRlZFxuICAgICAgaWYgKG1ldGFkYXRhLnVuaXF1ZV9pZCkge1xuICAgICAgICB0aGlzLmlkID0gbWV0YWRhdGEudW5pcXVlX2lkO1xuICAgICAgfVxuICAgICAgXG4gICAgICB0aGlzLl9pc0RpcnR5ID0gdHJ1ZTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRGVzZXJpYWxpemVkIHBlcnNvbmE6ICR7dGhpcy5tZXRhZGF0YS5uYW1lfWApO1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlc2VyaWFsaXplIHBlcnNvbmE6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYERlc2VyaWFsaXphdGlvbiBmYWlsZWQ6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNvbmEgYWN0aXZhdGlvbiBsaWZlY3ljbGVcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBhY3RpdmF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuaW5mbyhgQWN0aXZhdGluZyBwZXJzb25hOiAke3RoaXMubWV0YWRhdGEubmFtZX0gKCR7dGhpcy5pZH0pYCk7XG4gICAgXG4gICAgLy8gUGVyc29uYXMgZG9uJ3QgbmVlZCBzcGVjaWFsIGFjdGl2YXRpb24gbG9naWMgY3VycmVudGx5XG4gICAgLy8gQnV0IHRoaXMgcHJvdmlkZXMgYSBob29rIGZvciBmdXR1cmUgZW5oYW5jZW1lbnRzXG4gICAgXG4gICAgYXdhaXQgc3VwZXIuYWN0aXZhdGU/LigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNvbmEgZGVhY3RpdmF0aW9uIGxpZmVjeWNsZVxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGRlYWN0aXZhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmluZm8oYERlYWN0aXZhdGluZyBwZXJzb25hOiAke3RoaXMubWV0YWRhdGEubmFtZX0gKCR7dGhpcy5pZH0pYCk7XG4gICAgXG4gICAgLy8gUGVyc29uYXMgZG9uJ3QgbmVlZCBzcGVjaWFsIGRlYWN0aXZhdGlvbiBsb2dpYyBjdXJyZW50bHlcbiAgICAvLyBCdXQgdGhpcyBwcm92aWRlcyBhIGhvb2sgZm9yIGZ1dHVyZSBlbmhhbmNlbWVudHNcbiAgICBcbiAgICBhd2FpdCBzdXBlci5kZWFjdGl2YXRlPy4oKTtcbiAgfVxufSJdfQ==