UNPKG

@mickdarling/dollhousemcp

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.

157 lines 21.5 kB
/** * Persona validation and quality checks */ import { VALID_CATEGORIES } from '../config/constants.js'; export class PersonaValidator { /** * Validate a persona's metadata and content */ 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 if (metadata.category && !VALID_CATEGORIES.includes(metadata.category)) { issues.push(`Invalid category '${metadata.category}'. Must be one of: ${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 */ 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)) { issues.push(`Invalid category '${metadata.category}'`); } 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"); } if (!metadata.category || metadata.category === 'general') { suggestions.push("Choose a specific category for better organization"); } return suggestions; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYVZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wZXJzb25hL1BlcnNvbmFWYWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFHSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVMxRCxNQUFNLE9BQU8sZ0JBQWdCO0lBRTNCOztPQUVHO0lBQ0gsZUFBZSxDQUFDLE9BQWdCO1FBQzlCLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUVsQyx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEQsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0RSxNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQzNELE1BQU0sQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsc0JBQXNCO1FBQ3RCLElBQUksUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFD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R0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxXQUFXLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsV0FBVyxDQUFDLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQ2pDLFdBQVcsQ0FBQyxJQUFJLENBQUMsd0RBQXdELENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN0QixXQUFXLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDMUQsV0FBVyxDQUFDLElBQUksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFFRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBlcnNvbmEgdmFsaWRhdGlvbiBhbmQgcXVhbGl0eSBjaGVja3NcbiAqL1xuXG5pbXBvcnQgeyBQZXJzb25hLCBQZXJzb25hTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wZXJzb25hLmpzJztcbmltcG9ydCB7IFZBTElEX0NBVEVHT1JJRVMgfSBmcm9tICcuLi9jb25maWcvY29uc3RhbnRzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIGlzc3Vlczogc3RyaW5nW107XG4gIHdhcm5pbmdzOiBzdHJpbmdbXTtcbiAgcmVwb3J0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQZXJzb25hVmFsaWRhdG9yIHtcbiAgXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIHBlcnNvbmEncyBtZXRhZGF0YSBhbmQgY29udGVudFxuICAgKi9cbiAgdmFsaWRhdGVQZXJzb25hKHBlcnNvbmE6IFBlcnNvbmEpOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBpc3N1ZXM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgbWV0YWRhdGEgPSBwZXJzb25hLm1ldGFkYXRhO1xuICAgIFxuICAgIC8vIFJlcXVpcmVkIGZpZWxkIGNoZWNrc1xuICAgIGlmICghbWV0YWRhdGEubmFtZSB8fCBtZXRhZGF0YS5uYW1lLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGlzc3Vlcy5wdXNoKFwiTWlzc2luZyBvciBlbXB0eSAnbmFtZScgZmllbGRcIik7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEuZGVzY3JpcHRpb24gfHwgbWV0YWRhdGEuZGVzY3JpcHRpb24udHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaXNzdWVzLnB1c2goXCJNaXNzaW5nIG9yIGVtcHR5ICdkZXNjcmlwdGlvbicgZmllbGRcIik7XG4gICAgfVxuICAgIGlmICghcGVyc29uYS5jb250ZW50IHx8IHBlcnNvbmEuY29udGVudC50cmltKCkubGVuZ3RoIDwgNTApIHtcbiAgICAgIGlzc3Vlcy5wdXNoKFwiUGVyc29uYSBjb250ZW50IGlzIHRvbyBzaG9ydCAobWluaW11bSA1MCBjaGFyYWN0ZXJzKVwiKTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2F0ZWdvcnkgdmFsaWRhdGlvblxuICAgIGlmIChtZXRhZGF0YS5jYXRlZ29yeSAmJiAhVkFMSURfQ0FURUdPUklFUy5pbmNsdWRlcyhtZXRhZGF0YS5jYXRlZ29yeSkpIHtcbiAgICAgIGlzc3Vlcy5wdXNoKGBJbnZhbGlkIGNhdGVnb3J5ICcke21ldGFkYXRhLmNhdGVnb3J5fScuIE11c3QgYmUgb25lIG9mOiAke1ZBTElEX0NBVEVHT1JJRVMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgXG4gICAgLy8gQWdlIHJhdGluZyB2YWxpZGF0aW9uXG4gICAgY29uc3QgdmFsaWRBZ2VSYXRpbmdzID0gWydhbGwnLCAnMTMrJywgJzE4KyddO1xuICAgIGlmIChtZXRhZGF0YS5hZ2VfcmF0aW5nICYmICF2YWxpZEFnZVJhdGluZ3MuaW5jbHVkZXMobWV0YWRhdGEuYWdlX3JhdGluZykpIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goYEludmFsaWQgYWdlX3JhdGluZyAnJHttZXRhZGF0YS5hZ2VfcmF0aW5nfScuIFNob3VsZCBiZSBvbmUgb2Y6ICR7dmFsaWRBZ2VSYXRpbmdzLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIFxuICAgIC8vIE9wdGlvbmFsIGZpZWxkIHdhcm5pbmdzXG4gICAgaWYgKCFtZXRhZGF0YS50cmlnZ2VycyB8fCBtZXRhZGF0YS50cmlnZ2Vycy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB0cmlnZ2VyIGtleXdvcmRzIGRlZmluZWQgLSB1c2VycyBtYXkgaGF2ZSBkaWZmaWN1bHR5IGZpbmRpbmcgdGhpcyBwZXJzb25hXCIpO1xuICAgIH1cbiAgICBpZiAoIW1ldGFkYXRhLnZlcnNpb24pIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJObyB2ZXJzaW9uIHNwZWNpZmllZCAtIGRlZmF1bHRpbmcgdG8gJzEuMCdcIik7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEudW5pcXVlX2lkKSB7XG4gICAgICB3YXJuaW5ncy5wdXNoKFwiTm8gdW5pcXVlX2lkIC0gb25lIHdpbGwgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHlcIik7XG4gICAgfVxuICAgIFxuICAgIC8vIENvbnRlbnQgcXVhbGl0eSBjaGVja3NcbiAgICBpZiAocGVyc29uYS5jb250ZW50Lmxlbmd0aCA+IDUwMDApIHtcbiAgICAgIHdhcm5pbmdzLnB1c2goXCJQZXJzb25hIGNvbnRlbnQgaXMgdmVyeSBsb25nIC0gY29uc2lkZXIgYnJlYWtpbmcgaXQgaW50byBzZWN0aW9uc1wiKTtcbiAgICB9XG4gICAgaWYgKG1ldGFkYXRhLm5hbWUgJiYgbWV0YWRhdGEubmFtZS5sZW5ndGggPiA1MCkge1xuICAgICAgd2FybmluZ3MucHVzaChcIlBlcnNvbmEgbmFtZSBpcyB2ZXJ5IGxvbmcgLSBjb25zaWRlciBzaG9ydGVuaW5nIGZvciBiZXR0ZXIgZGlzcGxheVwiKTtcbiAgICB9XG4gICAgaWYgKG1ldGFkYXRhLmRlc2NyaXB0aW9uICYmIG1ldGFkYXRhLmRlc2NyaXB0aW9uLmxlbmd0aCA+IDIwMCkge1xuICAgICAgd2FybmluZ3MucHVzaChcIkRlc2NyaXB0aW9uIGlzIHZlcnkgbG9uZyAtIGNvbnNpZGVyIGtlZXBpbmcgaXQgdW5kZXIgMjAwIGNoYXJhY3RlcnNcIik7XG4gICAgfVxuICAgIFxuICAgIC8vIEdlbmVyYXRlIHZhbGlkYXRpb24gcmVwb3J0XG4gICAgY29uc3QgcmVwb3J0ID0gdGhpcy5nZW5lcmF0ZVJlcG9ydChwZXJzb25hLCBpc3N1ZXMsIHdhcm5pbmdzKTtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGlzc3Vlcy5sZW5ndGggPT09IDAsXG4gICAgICBpc3N1ZXMsXG4gICAgICB3YXJuaW5ncyxcbiAgICAgIHJlcG9ydFxuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwZXJzb25hIG1ldGFkYXRhIG9ubHlcbiAgICovXG4gIHZhbGlkYXRlTWV0YWRhdGEobWV0YWRhdGE6IFBlcnNvbmFNZXRhZGF0YSk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IGlzc3Vlczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCB3YXJuaW5nczogc3RyaW5nW10gPSBbXTtcbiAgICBcbiAgICBpZiAoIW1ldGFkYXRhLm5hbWUgfHwgbWV0YWRhdGEubmFtZS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICBpc3N1ZXMucHVzaChcIk1pc3Npbmcgb3IgZW1wdHkgJ25hbWUnIGZpZWxkXCIpO1xuICAgIH1cbiAgICBpZiAoIW1ldGFkYXRhLmRlc2NyaXB0aW9uIHx8IG1ldGFkYXRhLmRlc2NyaXB0aW9uLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGlzc3Vlcy5wdXNoKFwiTWlzc2luZyBvciBlbXB0eSAnZGVzY3JpcHRpb24nIGZpZWxkXCIpO1xuICAgIH1cbiAgICBcbiAgICBpZiAobWV0YWRhdGEuY2F0ZWdvcnkgJiYgIVZBTElEX0NBVEVHT1JJRVMuaW5jbHVkZXMobWV0YWRhdGEuY2F0ZWdvcnkpKSB7XG4gICAgICBpc3N1ZXMucHVzaChgSW52YWxpZCBjYXRlZ29yeSAnJHttZXRhZGF0YS5jYXRlZ29yeX0nYCk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogaXNzdWVzLmxlbmd0aCA9PT0gMCxcbiAgICAgIGlzc3VlcyxcbiAgICAgIHdhcm5pbmdzLFxuICAgICAgcmVwb3J0OiAnJ1xuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIHZhbGlkYXRpb24gcmVwb3J0XG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlUmVwb3J0KHBlcnNvbmE6IFBlcnNvbmEsIGlzc3Vlczogc3RyaW5nW10sIHdhcm5pbmdzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBwZXJzb25hLm1ldGFkYXRhO1xuICAgIGxldCByZXBvcnQgPSBg8J+TiyAqKlZhbGlkYXRpb24gUmVwb3J0OiAke21ldGFkYXRhLm5hbWV9KipcXG5cXG5gO1xuICAgIFxuICAgIGlmIChpc3N1ZXMubGVuZ3RoID09PSAwICYmIHdhcm5pbmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmVwb3J0ICs9IGDinIUgKipBbGwgQ2hlY2tzIFBhc3NlZCEqKlxcblxcbmAgK1xuICAgICAgICBg8J+OrSAqKlBlcnNvbmE6KiogJHttZXRhZGF0YS5uYW1lfVxcbmAgK1xuICAgICAgICBg8J+TgSAqKkNhdGVnb3J5OioqICR7bWV0YWRhdGEuY2F0ZWdvcnkgfHwgJ2dlbmVyYWwnfVxcbmAgK1xuICAgICAgICBg8J+TiiAqKlZlcnNpb246KiogJHttZXRhZGF0YS52ZXJzaW9uIHx8ICcxLjAnfVxcbmAgK1xuICAgICAgICBg8J+TnSAqKkNvbnRlbnQgTGVuZ3RoOioqICR7cGVyc29uYS5jb250ZW50Lmxlbmd0aH0gY2hhcmFjdGVyc1xcbmAgK1xuICAgICAgICBg8J+UlyAqKlRyaWdnZXJzOioqICR7bWV0YWRhdGEudHJpZ2dlcnM/Lmxlbmd0aCB8fCAwfSBrZXl3b3Jkc1xcblxcbmAgK1xuICAgICAgICBgVGhpcyBwZXJzb25hIG1lZXRzIGFsbCB2YWxpZGF0aW9uIHJlcXVpcmVtZW50cyBhbmQgaXMgcmVhZHkgZm9yIHVzZSFgO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVwb3J0ICs9IGDinYwgKipJc3N1ZXMgRm91bmQgKCR7aXNzdWVzLmxlbmd0aH0pOioqXFxuYDtcbiAgICAgICAgaXNzdWVzLmZvckVhY2goKGlzc3VlLCBpKSA9PiB7XG4gICAgICAgICAgcmVwb3J0ICs9IGAgICAke2kgKyAxfS4gJHtpc3N1ZX1cXG5gO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVwb3J0ICs9ICdcXG4nO1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAod2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgICByZXBvcnQgKz0gYOKaoO+4jyAqKldhcm5pbmdzICgke3dhcm5pbmdzLmxlbmd0aH0pOioqXFxuYDtcbiAgICAgICAgd2FybmluZ3MuZm9yRWFjaCgod2FybmluZywgaSkgPT4ge1xuICAgICAgICAgIHJlcG9ydCArPSBgICAgJHtpICsgMX0uICR7d2FybmluZ31cXG5gO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVwb3J0ICs9ICdcXG4nO1xuICAgICAgfVxuICAgICAgXG4gICAgICBpZiAoaXNzdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVwb3J0ICs9IGDwn5KhICoqRml4IFJlcXVpcmVkOioqIFBsZWFzZSBhZGRyZXNzIHRoZSBpc3N1ZXMgYWJvdmUgYmVmb3JlIHVzaW5nIHRoaXMgcGVyc29uYS5cXG5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVwb3J0ICs9IGDwn5KaICoqU3RhdHVzOioqIFRoaXMgcGVyc29uYSBpcyB2YWxpZCBidXQgY291bGQgYmUgaW1wcm92ZWQuIENvbnNpZGVyIGFkZHJlc3NpbmcgdGhlIHdhcm5pbmdzLlxcbmA7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiByZXBvcnQ7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHBlcnNvbmEgbmFtZSBpcyB2YWxpZFxuICAgKi9cbiAgaXNWYWxpZFBlcnNvbmFOYW1lKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghbmFtZSB8fCBuYW1lLnRyaW0oKS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICBpZiAobmFtZS5sZW5ndGggPiA1MCkgcmV0dXJuIGZhbHNlO1xuICAgIC8vIENoZWNrIGZvciBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICByZXR1cm4gIS9bPD46XCIvXFxcXHw/Kl0vLnRlc3QobmFtZSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBTdWdnZXN0IGltcHJvdmVtZW50cyBmb3IgYSBwZXJzb25hXG4gICAqL1xuICBzdWdnZXN0SW1wcm92ZW1lbnRzKHBlcnNvbmE6IFBlcnNvbmEpOiBzdHJpbmdbXSB7XG4gICAgY29uc3Qgc3VnZ2VzdGlvbnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgbWV0YWRhdGEgPSBwZXJzb25hLm1ldGFkYXRhO1xuICAgIFxuICAgIGlmICghbWV0YWRhdGEudHJpZ2dlcnMgfHwgbWV0YWRhdGEudHJpZ2dlcnMubGVuZ3RoIDwgMykge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChcIkFkZCBtb3JlIHRyaWdnZXIga2V5d29yZHMgdG8gaW1wcm92ZSBkaXNjb3ZlcmFiaWxpdHlcIik7XG4gICAgfVxuICAgIFxuICAgIGlmICghbWV0YWRhdGEuYXV0aG9yKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFwiQWRkIGFuIGF1dGhvciBmaWVsZCBmb3IgcHJvcGVyIGF0dHJpYnV0aW9uXCIpO1xuICAgIH1cbiAgICBcbiAgICBpZiAocGVyc29uYS5jb250ZW50Lmxlbmd0aCA8IDIwMCkge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChcIkV4cGFuZCB0aGUgcGVyc29uYSBpbnN0cnVjdGlvbnMgZm9yIGJldHRlciBBSSBndWlkYW5jZVwiKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKCFtZXRhZGF0YS52ZXJzaW9uKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKFwiQWRkIGEgdmVyc2lvbiBudW1iZXIgZm9yIHRyYWNraW5nIHVwZGF0ZXNcIik7XG4gICAgfVxuICAgIFxuICAgIGlmICghbWV0YWRhdGEuY2F0ZWdvcnkgfHwgbWV0YWRhdGEuY2F0ZWdvcnkgPT09ICdnZW5lcmFsJykge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaChcIkNob29zZSBhIHNwZWNpZmljIGNhdGVnb3J5IGZvciBiZXR0ZXIgb3JnYW5pemF0aW9uXCIpO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gc3VnZ2VzdGlvbnM7XG4gIH1cbn0iXX0=