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.

161 lines 22 kB
/** * Persona validation and quality checks */ import { VALID_CATEGORIES } from '../config/constants.js'; export class PersonaValidator { /** * Validate a persona's metadata and content * * Note: Category validation has been changed from error to warning * to support the transition to a flat directory structure. */ validatePersona(persona) { const issues = []; const warnings = []; const metadata = persona.metadata; // Required field checks if (!metadata.name || metadata.name.trim().length === 0) { issues.push("Missing or empty 'name' field"); } if (!metadata.description || metadata.description.trim().length === 0) { issues.push("Missing or empty 'description' field"); } if (!persona.content || persona.content.trim().length < 50) { issues.push("Persona content is too short (minimum 50 characters)"); } // Category validation (optional) if (metadata.category && !VALID_CATEGORIES.includes(metadata.category)) { warnings.push(`Invalid category '${metadata.category}'. Valid categories are: ${VALID_CATEGORIES.join(', ')}`); } // Age rating validation const validAgeRatings = ['all', '13+', '18+']; if (metadata.age_rating && !validAgeRatings.includes(metadata.age_rating)) { warnings.push(`Invalid age_rating '${metadata.age_rating}'. Should be one of: ${validAgeRatings.join(', ')}`); } // Optional field warnings if (!metadata.triggers || metadata.triggers.length === 0) { warnings.push("No trigger keywords defined - users may have difficulty finding this persona"); } if (!metadata.version) { warnings.push("No version specified - defaulting to '1.0'"); } if (!metadata.unique_id) { warnings.push("No unique_id - one will be generated automatically"); } // Content quality checks if (persona.content.length > 5000) { warnings.push("Persona content is very long - consider breaking it into sections"); } if (metadata.name && metadata.name.length > 50) { warnings.push("Persona name is very long - consider shortening for better display"); } if (metadata.description && metadata.description.length > 200) { warnings.push("Description is very long - consider keeping it under 200 characters"); } // Generate validation report const report = this.generateReport(persona, issues, warnings); return { valid: issues.length === 0, issues, warnings, report }; } /** * Validate persona metadata only * * Note: Category validation has been changed from error to warning * to support the transition to a flat directory structure. */ validateMetadata(metadata) { const issues = []; const warnings = []; if (!metadata.name || metadata.name.trim().length === 0) { issues.push("Missing or empty 'name' field"); } if (!metadata.description || metadata.description.trim().length === 0) { issues.push("Missing or empty 'description' field"); } if (metadata.category && !VALID_CATEGORIES.includes(metadata.category)) { warnings.push(`Invalid category '${metadata.category}'. Valid categories are: ${VALID_CATEGORIES.join(', ')}`); } return { valid: issues.length === 0, issues, warnings, report: '' }; } /** * Generate a validation report */ generateReport(persona, issues, warnings) { const metadata = persona.metadata; let report = `📋 **Validation Report: ${metadata.name}**\n\n`; if (issues.length === 0 && warnings.length === 0) { report += `✅ **All Checks Passed!**\n\n` + `🎭 **Persona:** ${metadata.name}\n` + `📁 **Category:** ${metadata.category || 'general'}\n` + `📊 **Version:** ${metadata.version || '1.0'}\n` + `📝 **Content Length:** ${persona.content.length} characters\n` + `🔗 **Triggers:** ${metadata.triggers?.length || 0} keywords\n\n` + `This persona meets all validation requirements and is ready for use!`; } else { if (issues.length > 0) { report += `❌ **Issues Found (${issues.length}):**\n`; issues.forEach((issue, i) => { report += ` ${i + 1}. ${issue}\n`; }); report += '\n'; } if (warnings.length > 0) { report += `⚠️ **Warnings (${warnings.length}):**\n`; warnings.forEach((warning, i) => { report += ` ${i + 1}. ${warning}\n`; }); report += '\n'; } if (issues.length > 0) { report += `💡 **Fix Required:** Please address the issues above before using this persona.\n`; } else { report += `💚 **Status:** This persona is valid but could be improved. Consider addressing the warnings.\n`; } } return report; } /** * Check if a persona name is valid */ isValidPersonaName(name) { if (!name || name.trim().length === 0) return false; if (name.length > 50) return false; // Check for invalid characters return !/[<>:"/\\|?*]/.test(name); } /** * Suggest improvements for a persona */ suggestImprovements(persona) { const suggestions = []; const metadata = persona.metadata; if (!metadata.triggers || metadata.triggers.length < 3) { suggestions.push("Add more trigger keywords to improve discoverability"); } if (!metadata.author) { suggestions.push("Add an author field for proper attribution"); } if (persona.content.length < 200) { suggestions.push("Expand the persona instructions for better AI guidance"); } if (!metadata.version) { suggestions.push("Add a version number for tracking updates"); } // Category is now optional - removed suggestion return suggestions; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYVZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wZXJzb25hL1BlcnNvbmFWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFHSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVMxRCxNQUFNLE9BQU8sZ0JBQWdCO0lBRTNCOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLE9BQWdCO1FBQzlCLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUVsQyx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEQsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0RSxNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQzNELE1BQU0sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsaUNBQWlDO1FBQ2pDLElBQUksUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN2RSxRQUFRLENBQUMsSUFBSSxDQUFDLHFCQUFxQixRQUFRLENBQUMsUUFBUSw0QkFBNEIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqSCxDQUFDO1FBRUQsd0JBQXdCO1FBQ3hCLE1BQU0sZUFBZSxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUFJLFFBQVEsQ0FBQyxVQUFVLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLFFBQVEsQ0FBQyxVQUFVLHdCQUF3QixlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoSCxDQUFDO1FBRUQsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pELFFBQVEsQ0FBQyxJQUFJLENBQUMsOEVBQThFLENBQUMsQ0FBQztRQUNoRyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDeEIsUUFBUSxDQUFDLElBQUksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFFRCx5QkFBeUI7UUFDekIsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxRQUFRLENBQUMsSUFBSSxDQUFDLG1FQUFtRSxDQUFDLENBQUM7UUFDckYsQ0FBQztRQUNELElBQUksUUFBUSxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUMvQyxRQUFRLENBQUMsSUFBSSxDQUFDLG9FQUFvRSxDQUFDLENBQUM7UUFDdEYsQ0FBQztRQUNELElBQUksUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUM5RCxRQUFRLENBQUMsSUFBSSxDQUFDLHFFQUFxRSxDQUFDLENBQUM7UUFDdkYsQ0FBQztRQUVELDZCQUE2QjtRQUM3QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFOUQsT0FBTztZQUNMLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7WUFDMUIsTUFBTTtZQUNOLFFBQVE7WUFDUixNQUFNO1NBQ1AsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdCQUFnQixDQUFDLFFBQXlCO1FBQ3hDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFFOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEQsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0RSxNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELElBQUksUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUN2RSxRQUFRLENBQUMsSUFBSSxDQUFDLHFCQUFxQixRQUFRLENBQUMsUUFBUSw0QkFBNEIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqSCxDQUFDO1FBRUQsT0FBTztZQUNMLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7WUFDMUIsTUFBTTtZQUNOLFFBQVE7WUFDUixNQUFNLEVBQUUsRUFBRTtTQUNYLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxjQUFjLENBQUMsT0FBZ0IsRUFBRSxNQUFnQixFQUFFLFFBQWtCO1FBQzNFLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsSUFBSSxNQUFNLEdBQUcsMkJBQTJCLFFBQVEsQ0FBQyxJQUFJLFFBQVEsQ0FBQztRQUU5RCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDakQsTUFBTSxJQUFJLDhCQUE4QjtnQkFDdEMsbUJBQW1CLFFBQVEsQ0FBQyxJQUFJLElBQUk7Z0JBQ3BDLG9CQUFvQixRQUFRLENBQUMsUUFBUSxJQUFJLFNBQVMsSUFBSTtnQkFDdEQsbUJBQW1CLFFBQVEsQ0FBQyxPQUFPLElBQUksS0FBSyxJQUFJO2dCQUNoRCwwQkFBMEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLGVBQWU7Z0JBQy9ELG9CQUFvQixRQUFRLENBQUMsUUFBUSxFQUFFLE1BQU0sSUFBSSxDQUFDLGVBQWU7Z0JBQ2pFLHNFQUFzRSxDQUFDO1FBQzNFLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN0QixNQUFNLElBQUkscUJBQXFCLE1BQU0sQ0FBQyxNQUFNLFFBQVEsQ0FBQztnQkFDckQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDMUIsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQztnQkFDdEMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLElBQUksQ0FBQztZQUNqQixDQUFDO1lBRUQsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN4QixNQUFNLElBQUksa0JBQWtCLFFBQVEsQ0FBQyxNQUFNLFFBQVEsQ0FBQztnQkFDcEQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDOUIsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQztnQkFDeEMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLElBQUksQ0FBQztZQUNqQixDQUFDO1lBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN0QixNQUFNLElBQUksbUZBQW1GLENBQUM7WUFDaEcsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sSUFBSSxpR0FBaUcsQ0FBQztZQUM5RyxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNILGtCQUFrQixDQUFDLElBQVk7UUFDN0IsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNwRCxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ25DLCtCQUErQjtRQUMvQixPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxtQkFBbUIsQ0FBQyxPQUFnQjtRQUNsQyxNQUFNLFdBQVcsR0FBYSxFQUFFLENBQUM7UUFDakMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUVsQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxXQUFXLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsV0FBVyxDQUFDLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQ2pDLFdBQVcsQ0FBQyxJQUFJLENBQUMsd0RBQXdELENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN0QixXQUFXLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUVELGdEQUFnRDtRQUVoRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBlcnNvbmEgdmFsaWRhdGlvbiBhbmQgcXVhbGl0eSBjaGVja3NcbiAqL1xuXG5pbXBvcnQgeyBQZXJzb25hLCBQZXJzb25hTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wZXJzb25hLmpzJztcbmltcG9ydCB7IFZBTElEX0NBVEVHT1JJRVMgfSBmcm9tICcuLi9jb25maWcvY29uc3RhbnRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBQZXJzb25hVmFsaWRhdGlvblJlc3VsdCB7XG4gIHZhbGlkOiBib29sZWFuO1xuICBpc3N1ZXM6IHN0cmluZ1tdO1xuICB3YXJuaW5nczogc3RyaW5nW107XG4gIHJlcG9ydDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgUGVyc29uYVZhbGlkYXRvciB7XG4gIFxuICAvKipcbiAgICogVmFsaWRhdGUgYSBwZXJzb25hJ3MgbWV0YWRhdGEgYW5kIGNvbnRlbnRcbiAgICogXG4gICAqIE5vdGU6IENhdGVnb3J5IHZhbGlkYXRpb24gaGFzIGJlZW4gY2hhbmdlZCBmcm9tIGVycm9yIHRvIHdhcm5pbmdcbiAgICogdG8gc3VwcG9ydCB0aGUgdHJhbnNpdGlvbiB0byBhIGZsYXQgZGlyZWN0b3J5IHN0cnVjdHVyZS5cbiAgICovXG4gIHZhbGlkYXRlUGVyc29uYShwZXJzb25hOiBQZXJzb25hKTogUGVyc29uYVZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IGlzc3Vlczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCB3YXJuaW5nczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHBlcnNvbmEubWV0YWRhdGE7XG4gICAgXG4gICAgLy8gUmVxdWlyZWQgZmllbGQgY2hlY2tzXG4gICAgaWYgKCFtZXRhZGF0YS5uYW1lIHx8IG1ldGFkYXRhLm5hbWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaXNzdWVzLnB1c2goXCJNaXNzaW5nIG9yIGVtcHR5ICduYW1lJyBmaWVsZFwiKTtcbiAgICB9XG4gICAgaWYgKCFtZXRhZGF0YS5kZXNjcmlwdGlvbiB8fCBtZXRhZGF0YS5kZXNjcmlwdGlvbi50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICBpc3N1ZXMucHVzaChcIk1pc3Npbmcgb3IgZW1wdHkgJ2Rlc2NyaXB0aW9uJyBmaWVsZFwiKTtcbiAgICB9XG4gICAgaWYgKCFwZXJzb25hLmNvbnRlbnQgfHwgcGVyc29uYS5jb250ZW50LnRyaW0oKS5sZW5ndGggPCA1MCkge1xuICAgICAgaXNzdWVzLnB1c2goXCJQZXJzb25hIGNvbnRlbnQgaXMgdG9vIHNob3J0IChtaW5pbXVtIDUwIGNoYXJhY3RlcnMpXCIpO1xuICAgIH1cbiAgICBcbiAgICAvLyBDYXRlZ29yeSB2YWxpZGF0aW9uIChvcHRpb25hbClcbiAgICBpZiAobWV0YWRhdGEuY2F0ZWdvcnkgJiYgIVZBTElEX0NBVEVHT1JJRVMuaW5jbHVkZXMobWV0YWRhdGEuY2F0ZWdvcnkpKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKGBJbnZhbGlkIGNhdGVnb3J5ICcke21ldGFkYXRhLmNhdGVnb3J5fScuIFZhbGlkIGNhdGVnb3JpZXMgYXJlOiAke1ZBTElEX0NBVEVHT1JJRVMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgXG4gICAgLy8gQWdlIHJhdGluZyB2YWxpZGF0aW9uXG4gICAgY29uc3QgdmFsaWRBZ2VSYXRpbmdzID0gWydhbGwnLCAnMTMrJywgJzE4KyddO1xuICAgIGlmIChtZXRhZGF0YS5hZ2VfcmF0aW5nICYmICF2YWxpZEFnZVJhdGluZ3MuaW5jbHVkZXMobWV0YWRhdGEuYWdlX3JhdGluZykpIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goYEludmFsaWQgYWdlX3JhdGluZyAnJHttZXRhZGF0YS5hZ2VfcmF0aW5nfScuIFNob3VsZCBiZSBvbmUgb2Y6ICR7dmFsaWRBZ2VSYXRpbmdzLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIFxuICAgIC8vIE9wdGlvbmFsIGZpZWxkIHdhcm5pbmdzXG4gICAgaWYgKCFtZXRhZGF0YS50cmlnZ2VycyB8fCBtZXRhZGF0YS50cmlnZ2Vycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB0cmlnZ2VyIGtleXdvcmRzIGRlZmluZWQgLSB1c2VycyBtYXkgaGF2ZSBkaWZmaWN1bHR5IGZpbmRpbmcgdGhpcyBwZXJzb25hXCIpO1xuICAgIH1cbiAgICBpZiAoIW1ldGFkYXRhLnZlcnNpb24pIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB2ZXJzaW9uIHNwZWNpZmllZCAtIGRlZmF1bHRpbmcgdG8gJzEuMCdcIik7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEudW5pcXVlX2lkKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFwiTm8gdW5pcXVlX2lkIC0gb25lIHdpbGwgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHlcIik7XG4gICAgfVxuICAgIFxuICAgIC8vIENvbnRlbnQgcXVhbGl0eSBjaGVja3NcbiAgICBpZiAocGVyc29uYS5jb250ZW50Lmxlbmd0aCA+IDUwMDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJQZXJzb25hIGNvbnRlbnQgaXMgdmVyeSBsb25nIC0gY29uc2lkZXIgYnJlYWtpbmcgaXQgaW50byBzZWN0aW9uc1wiKTtcbiAgICB9XG4gICAgaWYgKG1ldGFkYXRhLm5hbWUgJiYgbWV0YWRhdGEubmFtZS5sZW5ndGggPiA1MCkge1xuICAgICAgd2FybmluZ3MucHVzaChcIlBlcnNvbmEgbmFtZSBpcyB2ZXJ5IGxvbmcgLSBjb25zaWRlciBzaG9ydGVuaW5nIGZvciBiZXR0ZXIgZGlzcGxheVwiKTtcbiAgICB9XG4gICAgaWYgKG1ldGFkYXRhLmRlc2NyaXB0aW9uICYmIG1ldGFkYXRhLmRlc2NyaXB0aW9uLmxlbmd0aCA+IDIwMCkge1xuICAgICAgd2FybmluZ3MucHVzaChcIkRlc2NyaXB0aW9uIGlzIHZlcnkgbG9uZyAtIGNvbnNpZGVyIGtlZXBpbmcgaXQgdW5kZXIgMjAwIGNoYXJhY3RlcnNcIik7XG4gICAgfVxuICAgIFxuICAgIC8vIEdlbmVyYXRlIHZhbGlkYXRpb24gcmVwb3J0XG4gICAgY29uc3QgcmVwb3J0ID0gdGhpcy5nZW5lcmF0ZVJlcG9ydChwZXJzb25hLCBpc3N1ZXMsIHdhcm5pbmdzKTtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGlzc3Vlcy5sZW5ndGggPT09IDAsXG4gICAgICBpc3N1ZXMsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIHJlcG9ydFxuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwZXJzb25hIG1ldGFkYXRhIG9ubHlcbiAgICogXG4gICAqIE5vdGU6IENhdGVnb3J5IHZhbGlkYXRpb24gaGFzIGJlZW4gY2hhbmdlZCBmcm9tIGVycm9yIHRvIHdhcm5pbmdcbiAgICogdG8gc3VwcG9ydCB0aGUgdHJhbnNpdGlvbiB0byBhIGZsYXQgZGlyZWN0b3J5IHN0cnVjdHVyZS5cbiAgICovXG4gIHZhbGlkYXRlTWV0YWRhdGEobWV0YWRhdGE6IFBlcnNvbmFNZXRhZGF0YSk6IFBlcnNvbmFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBpc3N1ZXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG4gICAgXG4gICAgaWYgKCFtZXRhZGF0YS5uYW1lIHx8IG1ldGFkYXRhLm5hbWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaXNzdWVzLnB1c2goXCJNaXNzaW5nIG9yIGVtcHR5ICduYW1lJyBmaWVsZFwiKTtcbiAgICB9XG4gICAgaWYgKCFtZXRhZGF0YS5kZXNjcmlwdGlvbiB8fCBtZXRhZGF0YS5kZXNjcmlwdGlvbi50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICBpc3N1ZXMucHVzaChcIk1pc3Npbmcgb3IgZW1wdHkgJ2Rlc2NyaXB0aW9uJyBmaWVsZFwiKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKG1ldGFkYXRhLmNhdGVnb3J5ICYmICFWQUxJRF9DQVRFR09SSUVTLmluY2x1ZGVzKG1ldGFkYXRhLmNhdGVnb3J5KSkge1xuICAgICAgd2FybmluZ3MucHVzaChgSW52YWxpZCBjYXRlZ29yeSAnJHttZXRhZGF0YS5jYXRlZ29yeX0nLiBWYWxpZCBjYXRlZ29yaWVzIGFyZTogJHtWQUxJRF9DQVRFR09SSUVTLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogaXNzdWVzLmxlbmd0aCA9PT0gMCxcbiAgICAgIGlzc3VlcyxcbiAgICAgIHdhcm5pbmdzLFxuICAgICAgcmVwb3J0OiAnJ1xuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIHZhbGlkYXRpb24gcmVwb3J0XG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlUmVwb3J0KHBlcnNvbmE6IFBlcnNvbmEsIGlzc3Vlczogc3RyaW5nW10sIHdhcm5pbmdzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBwZXJzb25hLm1ldGFkYXRhO1xuICAgIGxldCByZXBvcnQgPSBg8J+TiyAqKlZhbGlkYXRpb24gUmVwb3J0OiAke21ldGFkYXRhLm5hbWV9KipcXG5cXG5gO1xuICAgIFxuICAgIGlmIChpc3N1ZXMubGVuZ3RoID09PSAwICYmIHdhcm5pbmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmVwb3J0ICs9IGDinIUgKipBbGwgQ2hlY2tzIFBhc3NlZCEqKlxcblxcbmAgK1xuICAgICAgICBg8J+OrSAqKlBlcnNvbmE6KiogJHttZXRhZGF0YS5uYW1lfVxcbmAgK1xuICAgICAgICBg8J+TgSAqKkNhdGVnb3J5OioqICR7bWV0YWRhdGEuY2F0ZWdvcnkgfHwgJ2dlbmVyYWwnfVxcbmAgK1xuICAgICAgICBg8J+TiiAqKlZlcnNpb246KiogJHttZXRhZGF0YS52ZXJzaW9uIHx8ICcxLjAnfVxcbmAgK1xuICAgICAgICBg8J+TnSAqKkNvbnRlbnQgTGVuZ3RoOioqICR7cGVyc29uYS5jb250ZW50Lmxlbmd0aH0gY2hhcmFjdGVyc1xcbmAgK1xuICAgICAgICBg8J+UlyAqKlRyaWdnZXJzOioqICR7bWV0YWRhdGEudHJpZ2dlcnM/Lmxlbmd0aCB8fCAwfSBrZXl3b3Jkc1xcblxcbmAgK1xuICAgICAgICBgVGhpcyBwZXJzb25hIG1lZXRzIGFsbCB2YWxpZGF0aW9uIHJlcXVpcmVtZW50cyBhbmQgaXMgcmVhZHkgZm9yIHVzZSFgO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVwb3J0ICs9IGDinYwgKipJc3N1ZXMgRm91bmQgKCR7aXNzdWVzLmxlbmd0aH0pOioqXFxuYDtcbiAgICAgICAgaXNzdWVzLmZvckVhY2goKGlzc3VlLCBpKSA9PiB7XG4gICAgICAgICAgcmVwb3J0ICs9IGAgICAke2kgKyAxfS4gJHtpc3N1ZX1cXG5gO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVwb3J0ICs9ICdcXG4nO1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAod2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgICByZXBvcnQgKz0gYOKaoO+4jyAqKldhcm5pbmdzICgke3dhcm5pbmdzLmxlbmd0aH0pOioqXFxuYDtcbiAgICAgICAgd2FybmluZ3MuZm9yRWFjaCgod2FybmluZywgaSkgPT4ge1xuICAgICAgICAgIHJlcG9ydCArPSBgICAgJHtpICsgMX0uICR7d2FybmluZ31cXG5gO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVwb3J0ICs9ICdcXG4nO1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVwb3J0ICs9IGDwn5KhICoqRml4IFJlcXVpcmVkOioqIFBsZWFzZSBhZGRyZXNzIHRoZSBpc3N1ZXMgYWJvdmUgYmVmb3JlIHVzaW5nIHRoaXMgcGVyc29uYS5cXG5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVwb3J0ICs9IGDwn5KaICoqU3RhdHVzOioqIFRoaXMgcGVyc29uYSBpcyB2YWxpZCBidXQgY291bGQgYmUgaW1wcm92ZWQuIENvbnNpZGVyIGFkZHJlc3NpbmcgdGhlIHdhcm5pbmdzLlxcbmA7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiByZXBvcnQ7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHBlcnNvbmEgbmFtZSBpcyB2YWxpZFxuICAgKi9cbiAgaXNWYWxpZFBlcnNvbmFOYW1lKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghbmFtZSB8fCBuYW1lLnRyaW0oKS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICBpZiAobmFtZS5sZW5ndGggPiA1MCkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIENoZWNrIGZvciBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICByZXR1cm4gIS9bPD46XCIvXFxcXHw/Kl0vLnRlc3QobmFtZSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBTdWdnZXN0IGltcHJvdmVtZW50cyBmb3IgYSBwZXJzb25hXG4gICAqL1xuICBzdWdnZXN0SW1wcm92ZW1lbnRzKHBlcnNvbmE6IFBlcnNvbmEpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgc3VnZ2VzdGlvbnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgbWV0YWRhdGEgPSBwZXJzb25hLm1ldGFkYXRhO1xuICAgIFxuICAgIGlmICghbWV0YWRhdGEudHJpZ2dlcnMgfHwgbWV0YWRhdGEudHJpZ2dlcnMubGVuZ3RoIDwgMykge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChcIkFkZCBtb3JlIHRyaWdnZXIga2V5d29yZHMgdG8gaW1wcm92ZSBkaXNjb3ZlcmFiaWxpdHlcIik7XG4gICAgfVxuICAgIFxuICAgIGlmICghbWV0YWRhdGEuYXV0aG9yKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFwiQWRkIGFuIGF1dGhvciBmaWVsZCBmb3IgcHJvcGVyIGF0dHJpYnV0aW9uXCIpO1xuICAgIH1cbiAgICBcbiAgICBpZiAocGVyc29uYS5jb250ZW50Lmxlbmd0aCA8IDIwMCkge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChcIkV4cGFuZCB0aGUgcGVyc29uYSBpbnN0cnVjdGlvbnMgZm9yIGJldHRlciBBSSBndWlkYW5jZVwiKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKCFtZXRhZGF0YS52ZXJzaW9uKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFwiQWRkIGEgdmVyc2lvbiBudW1iZXIgZm9yIHRyYWNraW5nIHVwZGF0ZXNcIik7XG4gICAgfVxuICAgIFxuICAgIC8vIENhdGVnb3J5IGlzIG5vdyBvcHRpb25hbCAtIHJlbW92ZWQgc3VnZ2VzdGlvblxuICAgIFxuICAgIHJldHVybiBzdWdnZXN0aW9ucztcbiAgfVxufSJdfQ==