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.

300 lines 34.1 kB
/** * Goal Template System for Agent Goal Management * * Provides pre-configured goal templates for common patterns, * making it easier to create well-structured goals with appropriate * settings for different scenarios. */ import { EISENHOWER_THRESHOLDS } from './constants.js'; import { SecurityMonitor } from '../../security/securityMonitor.js'; // Pre-defined goal templates export const GOAL_TEMPLATES = { // Development templates 'feature-implementation': { id: 'feature-implementation', name: 'Feature Implementation', description: 'Implement a new feature with proper testing and documentation', category: 'development', defaultValues: { priority: 'high', importance: 8, urgency: 5, estimatedEffort: 8, riskLevel: 'medium', tags: ['feature', 'development', 'implementation'] }, requiredFields: ['featureName', 'specifications'], successCriteria: [ 'Code implemented and tested', 'Unit tests passing', 'Documentation updated', 'Code reviewed' ], riskMitigations: [ 'Break down into smaller tasks', 'Early prototype validation', 'Regular progress reviews' ] }, 'bug-fix-critical': { id: 'bug-fix-critical', name: 'Critical Bug Fix', description: 'Fix a critical production bug affecting users', category: 'maintenance', defaultValues: { priority: 'critical', importance: 10, urgency: 10, estimatedEffort: 2, riskLevel: 'high', tags: ['bug', 'critical', 'production'] }, requiredFields: ['bugId', 'impactDescription'], successCriteria: [ 'Bug identified and reproduced', 'Fix implemented and tested', 'Regression tests added', 'Deployed to production' ], riskMitigations: [ 'Rollback plan prepared', 'Thorough testing in staging', 'Monitor after deployment' ] }, 'research-spike': { id: 'research-spike', name: 'Research Spike', description: 'Time-boxed research to explore technical options', category: 'research', defaultValues: { priority: 'medium', importance: 7, urgency: 3, estimatedEffort: 4, riskLevel: 'low', tags: ['research', 'spike', 'exploration'] }, requiredFields: ['researchQuestion', 'timeBox'], successCriteria: [ 'Research question answered', 'Options documented', 'Recommendations provided', 'Decision criteria established' ] }, 'security-audit': { id: 'security-audit', name: 'Security Audit', description: 'Conduct security audit of system or component', category: 'operations', defaultValues: { priority: 'high', importance: 9, urgency: 6, estimatedEffort: 6, riskLevel: 'medium', tags: ['security', 'audit', 'compliance'] }, requiredFields: ['auditScope', 'complianceFramework'], successCriteria: [ 'Vulnerabilities identified', 'Risk assessment completed', 'Remediation plan created', 'Report generated' ] }, 'performance-optimization': { id: 'performance-optimization', name: 'Performance Optimization', description: 'Optimize system performance based on metrics', category: 'maintenance', defaultValues: { priority: 'medium', importance: 6, urgency: 4, estimatedEffort: 8, riskLevel: 'medium', tags: ['performance', 'optimization', 'metrics'] }, requiredFields: ['performanceMetrics', 'targetImprovement'], successCriteria: [ 'Baseline metrics captured', 'Optimizations implemented', 'Performance improved by target %', 'No regression in functionality' ] }, 'documentation-update': { id: 'documentation-update', name: 'Documentation Update', description: 'Update technical or user documentation', category: 'maintenance', defaultValues: { priority: 'low', importance: 5, urgency: 2, estimatedEffort: 3, riskLevel: 'low', tags: ['documentation', 'maintenance'] }, requiredFields: ['documentType', 'sections'], successCriteria: [ 'Documentation reviewed', 'Updates completed', 'Reviewed by stakeholders', 'Published to appropriate location' ] }, 'quarterly-planning': { id: 'quarterly-planning', name: 'Quarterly Planning', description: 'Plan goals and priorities for the quarter', category: 'planning', defaultValues: { priority: 'high', importance: 9, urgency: 7, estimatedEffort: 12, riskLevel: 'low', tags: ['planning', 'quarterly', 'strategy'] }, requiredFields: ['quarter', 'objectives'], successCriteria: [ 'Goals defined and prioritized', 'Resources allocated', 'Timeline established', 'Stakeholder alignment' ] }, 'custom-goal': { id: 'custom-goal', name: 'Custom Goal', description: 'Create a custom goal with your own parameters', category: 'custom', defaultValues: { priority: 'medium', importance: 5, urgency: 5, riskLevel: 'medium', tags: ['custom'] } } }; /** * Apply a goal template to create a new goal */ export function applyGoalTemplate(templateId, customFields) { // SECURITY FIX: Add audit logging for goal template usage SecurityMonitor.logSecurityEvent({ type: 'GOAL_TEMPLATE_APPLIED', severity: 'LOW', source: 'applyGoalTemplate', details: `Goal template '${templateId}' applied` }); const template = GOAL_TEMPLATES[templateId]; if (!template) { throw new Error(`Goal template '${templateId}' not found`); } // Validate required fields if (template.requiredFields) { for (const field of template.requiredFields) { if (!customFields[field]) { throw new Error(`Required field '${field}' missing for template '${template.name}'`); } } } // Calculate Eisenhower quadrant based on template defaults const importance = customFields.importance || template.defaultValues.importance; const urgency = customFields.urgency || template.defaultValues.urgency; const eisenhowerQuadrant = calculateEisenhowerQuadrant(importance, urgency); // Ensure description is provided const description = customFields.description || `${template.name}: ${template.requiredFields?.map(f => customFields[f]).filter(Boolean).join(' - ') || template.description}`; return { ...template.defaultValues, ...customFields, description, eisenhowerQuadrant, templateId, createdAt: new Date(), updatedAt: new Date() }; } /** * Calculate Eisenhower quadrant from importance and urgency. * Uses the threshold from EISENHOWER_THRESHOLDS.HIGH_PRIORITY to classify goals. */ export function calculateEisenhowerQuadrant(importance, urgency) { const threshold = EISENHOWER_THRESHOLDS.HIGH_PRIORITY; if (importance >= threshold && urgency >= threshold) return 'do_first'; if (importance >= threshold && urgency < threshold) return 'schedule'; if (importance < threshold && urgency >= threshold) return 'delegate'; return 'eliminate'; } /** * Get template recommendations based on goal description */ export function recommendGoalTemplate(description) { const lowercaseDesc = description.toLowerCase(); const recommendations = []; // Keywords mapping to templates const keywordMap = { 'feature-implementation': ['feature', 'implement', 'develop', 'build'], 'bug-fix-critical': ['bug', 'fix', 'critical', 'urgent', 'broken', 'error'], 'research-spike': ['research', 'explore', 'investigate', 'spike', 'evaluate'], 'security-audit': ['security', 'audit', 'vulnerability', 'compliance'], 'performance-optimization': ['performance', 'optimize', 'speed', 'slow', 'latency'], 'documentation-update': ['document', 'docs', 'readme', 'guide', 'manual'], 'quarterly-planning': ['plan', 'quarter', 'roadmap', 'strategy'] }; // Check for keyword matches for (const [templateId, keywords] of Object.entries(keywordMap)) { if (keywords.some(keyword => lowercaseDesc.includes(keyword))) { recommendations.push(templateId); } } // Always include custom as an option if (recommendations.length === 0) { recommendations.push('custom-goal'); } return recommendations; } /** * Validate goal against its template */ export function validateGoalAgainstTemplate(goal, // AgentGoal type templateId) { if (!templateId || !GOAL_TEMPLATES[templateId]) { return { valid: true, errors: [] }; } // SECURITY FIX: Add audit logging for template validation SecurityMonitor.logSecurityEvent({ type: 'GOAL_TEMPLATE_VALIDATION', severity: 'LOW', source: 'validateGoalAgainstTemplate', details: `Validating goal against template '${templateId}'` }); const template = GOAL_TEMPLATES[templateId]; const errors = []; // Check required fields if (template.requiredFields) { for (const field of template.requiredFields) { if (!goal[field]) { errors.push(`Missing required field: ${field}`); } } } // Validate risk level matches template category if (template.category === 'operations' && goal.riskLevel === 'high') { errors.push('High risk operations goals require additional approval'); } return { valid: errors.length === 0, errors }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29hbFRlbXBsYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbGVtZW50cy9hZ2VudHMvZ29hbFRlbXBsYXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFHSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFxQnBFLDZCQUE2QjtBQUM3QixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQWlDO0lBQzFELHdCQUF3QjtJQUN4Qix3QkFBd0IsRUFBRTtRQUN4QixFQUFFLEVBQUUsd0JBQXdCO1FBQzVCLElBQUksRUFBRSx3QkFBd0I7UUFDOUIsV0FBVyxFQUFFLCtEQUErRDtRQUM1RSxRQUFRLEVBQUUsYUFBYTtRQUN2QixhQUFhLEVBQUU7WUFDYixRQUFRLEVBQUUsTUFBTTtZQUNoQixVQUFVLEVBQUUsQ0FBQztZQUNiLE9BQU8sRUFBRSxDQUFDO1lBQ1YsZUFBZSxFQUFFLENBQUM7WUFDbEIsU0FBUyxFQUFFLFFBQVE7WUFDbkIsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQztTQUNuRDtRQUNELGNBQWMsRUFBRSxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQztRQUNqRCxlQUFlLEVBQUU7WUFDZiw2QkFBNkI7WUFDN0Isb0JBQW9CO1lBQ3BCLHVCQUF1QjtZQUN2QixlQUFlO1NBQ2hCO1FBQ0QsZUFBZSxFQUFFO1lBQ2YsK0JBQStCO1lBQy9CLDRCQUE0QjtZQUM1QiwwQkFBMEI7U0FDM0I7S0FDRjtJQUVELGtCQUFrQixFQUFFO1FBQ2xCLEVBQUUsRUFBRSxrQkFBa0I7UUFDdEIsSUFBSSxFQUFFLGtCQUFrQjtRQUN4QixXQUFXLEVBQUUsK0NBQStDO1FBQzVELFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLGFBQWEsRUFBRTtZQUNiLFFBQVEsRUFBRSxV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Z0JBQWdCLENBQUM7UUFDL0IsSUFBSSxFQUFFLDBCQUEwQjtRQUNoQyxRQUFRLEVBQUUsS0FBSztRQUNmLE1BQU0sRUFBRSw2QkFBNkI7UUFDckMsT0FBTyxFQUFFLHFDQUFxQyxVQUFVLEdBQUc7S0FDNUQsQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUU1Qix3QkFBd0I7SUFDeEIsSUFBSSxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDNUIsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxJQUFJLFFBQVEsQ0FBQyxRQUFRLEtBQUssWUFBWSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDcEUsTUFBTSxDQUFDLElBQUksQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxPQUFPO1FBQ0wsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUMxQixNQUFNO0tBQ1AsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdvYWwgVGVtcGxhdGUgU3lzdGVtIGZvciBBZ2VudCBHb2FsIE1hbmFnZW1lbnRcbiAqIFxuICogUHJvdmlkZXMgcHJlLWNvbmZpZ3VyZWQgZ29hbCB0ZW1wbGF0ZXMgZm9yIGNvbW1vbiBwYXR0ZXJucyxcbiAqIG1ha2luZyBpdCBlYXNpZXIgdG8gY3JlYXRlIHdlbGwtc3RydWN0dXJlZCBnb2FscyB3aXRoIGFwcHJvcHJpYXRlXG4gKiBzZXR0aW5ncyBmb3IgZGlmZmVyZW50IHNjZW5hcmlvcy5cbiAqL1xuXG5pbXBvcnQgeyBHb2FsUHJpb3JpdHksIEVpc2VuaG93ZXJRdWFkcmFudCB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgRUlTRU5IT1dFUl9USFJFU0hPTERTIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgU2VjdXJpdHlNb25pdG9yIH0gZnJvbSAnLi4vLi4vc2VjdXJpdHkvc2VjdXJpdHlNb25pdG9yLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBHb2FsVGVtcGxhdGUge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiAnZGV2ZWxvcG1lbnQnIHwgJ29wZXJhdGlvbnMnIHwgJ3Jlc2VhcmNoJyB8ICdwbGFubmluZycgfCAnbWFpbnRlbmFuY2UnIHwgJ2N1c3RvbSc7XG4gIGRlZmF1bHRWYWx1ZXM6IHtcbiAgICBwcmlvcml0eTogR29hbFByaW9yaXR5O1xuICAgIGltcG9ydGFuY2U6IG51bWJlcjsgIC8vIDEtMTBcbiAgICB1cmdlbmN5OiBudW1iZXI7ICAgICAvLyAxLTEwXG4gICAgZXN0aW1hdGVkRWZmb3J0PzogbnVtYmVyOyAgLy8gaG91cnNcbiAgICByaXNrTGV2ZWw/OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnO1xuICAgIHRhZ3M/OiBzdHJpbmdbXTtcbiAgfTtcbiAgcmVxdWlyZWRGaWVsZHM/OiBzdHJpbmdbXTtcbiAgc3VnZ2VzdGVkRGVwZW5kZW5jaWVzPzogc3RyaW5nW107XG4gIHN1Y2Nlc3NDcml0ZXJpYT86IHN0cmluZ1tdO1xuICByaXNrTWl0aWdhdGlvbnM/OiBzdHJpbmdbXTtcbn1cblxuLy8gUHJlLWRlZmluZWQgZ29hbCB0ZW1wbGF0ZXNcbmV4cG9ydCBjb25zdCBHT0FMX1RFTVBMQVRFUzogUmVjb3JkPHN0cmluZywgR29hbFRlbXBsYXRlPiA9IHtcbiAgLy8gRGV2ZWxvcG1lbnQgdGVtcGxhdGVzXG4gICdmZWF0dXJlLWltcGxlbWVudGF0aW9uJzoge1xuICAgIGlkOiAnZmVhdHVyZS1pbXBsZW1lbnRhdGlvbicsXG4gICAgbmFtZTogJ0ZlYXR1cmUgSW1wbGVtZW50YXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOiAnSW1wbGVtZW50IGEgbmV3IGZlYXR1cmUgd2l0aCBwcm9wZXIgdGVzdGluZyBhbmQgZG9jdW1lbnRhdGlvbicsXG4gICAgY2F0ZWdvcnk6ICdkZXZlbG9wbWVudCcsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdoaWdoJyxcbiAgICAgIGltcG9ydGFuY2U6IDgsXG4gICAgICB1cmdlbmN5OiA1LFxuICAgICAgZXN0aW1hdGVkRWZmb3J0OiA4LFxuICAgICAgcmlza0xldmVsOiAnbWVkaXVtJyxcbiAgICAgIHRhZ3M6IFsnZmVhdHVyZScsICdkZXZlbG9wbWVudCcsICdpbXBsZW1lbnRhdGlvbiddXG4gICAgfSxcbiAgICByZXF1aXJlZEZpZWxkczogWydmZWF0dXJlTmFtZScsICdzcGVjaWZpY2F0aW9ucyddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ0NvZGUgaW1wbGVtZW50ZWQgYW5kIHRlc3RlZCcsXG4gICAgICAnVW5pdCB0ZXN0cyBwYXNzaW5nJyxcbiAgICAgICdEb2N1bWVudGF0aW9uIHVwZGF0ZWQnLFxuICAgICAgJ0NvZGUgcmV2aWV3ZWQnXG4gICAgXSxcbiAgICByaXNrTWl0aWdhdGlvbnM6IFtcbiAgICAgICdCcmVhayBkb3duIGludG8gc21hbGxlciB0YXNrcycsXG4gICAgICAnRWFybHkgcHJvdG90eXBlIHZhbGlkYXRpb24nLFxuICAgICAgJ1JlZ3VsYXIgcHJvZ3Jlc3MgcmV2aWV3cydcbiAgICBdXG4gIH0sXG5cbiAgJ2J1Zy1maXgtY3JpdGljYWwnOiB7XG4gICAgaWQ6ICdidWctZml4LWNyaXRpY2FsJyxcbiAgICBuYW1lOiAnQ3JpdGljYWwgQnVnIEZpeCcsXG4gICAgZGVzY3JpcHRpb246ICdGaXggYSBjcml0aWNhbCBwcm9kdWN0aW9uIGJ1ZyBhZmZlY3RpbmcgdXNlcnMnLFxuICAgIGNhdGVnb3J5OiAnbWFpbnRlbmFuY2UnLFxuICAgIGRlZmF1bHRWYWx1ZXM6IHtcbiAgICAgIHByaW9yaXR5OiAnY3JpdGljYWwnLFxuICAgICAgaW1wb3J0YW5jZTogMTAsXG4gICAgICB1cmdlbmN5OiAxMCxcbiAgICAgIGVzdGltYXRlZEVmZm9ydDogMixcbiAgICAgIHJpc2tMZXZlbDogJ2hpZ2gnLFxuICAgICAgdGFnczogWydidWcnLCAnY3JpdGljYWwnLCAncHJvZHVjdGlvbiddXG4gICAgfSxcbiAgICByZXF1aXJlZEZpZWxkczogWydidWdJZCcsICdpbXBhY3REZXNjcmlwdGlvbiddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ0J1ZyBpZGVudGlmaWVkIGFuZCByZXByb2R1Y2VkJyxcbiAgICAgICdGaXggaW1wbGVtZW50ZWQgYW5kIHRlc3RlZCcsXG4gICAgICAnUmVncmVzc2lvbiB0ZXN0cyBhZGRlZCcsXG4gICAgICAnRGVwbG95ZWQgdG8gcHJvZHVjdGlvbidcbiAgICBdLFxuICAgIHJpc2tNaXRpZ2F0aW9uczogW1xuICAgICAgJ1JvbGxiYWNrIHBsYW4gcHJlcGFyZWQnLFxuICAgICAgJ1Rob3JvdWdoIHRlc3RpbmcgaW4gc3RhZ2luZycsXG4gICAgICAnTW9uaXRvciBhZnRlciBkZXBsb3ltZW50J1xuICAgIF1cbiAgfSxcblxuICAncmVzZWFyY2gtc3Bpa2UnOiB7XG4gICAgaWQ6ICdyZXNlYXJjaC1zcGlrZScsXG4gICAgbmFtZTogJ1Jlc2VhcmNoIFNwaWtlJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RpbWUtYm94ZWQgcmVzZWFyY2ggdG8gZXhwbG9yZSB0ZWNobmljYWwgb3B0aW9ucycsXG4gICAgY2F0ZWdvcnk6ICdyZXNlYXJjaCcsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdtZWRpdW0nLFxuICAgICAgaW1wb3J0YW5jZTogNyxcbiAgICAgIHVyZ2VuY3k6IDMsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDQsXG4gICAgICByaXNrTGV2ZWw6ICdsb3cnLFxuICAgICAgdGFnczogWydyZXNlYXJjaCcsICdzcGlrZScsICdleHBsb3JhdGlvbiddXG4gICAgfSxcbiAgICByZXF1aXJlZEZpZWxkczogWydyZXNlYXJjaFF1ZXN0aW9uJywgJ3RpbWVCb3gnXSxcbiAgICBzdWNjZXNzQ3JpdGVyaWE6IFtcbiAgICAgICdSZXNlYXJjaCBxdWVzdGlvbiBhbnN3ZXJlZCcsXG4gICAgICAnT3B0aW9ucyBkb2N1bWVudGVkJyxcbiAgICAgICdSZWNvbW1lbmRhdGlvbnMgcHJvdmlkZWQnLFxuICAgICAgJ0RlY2lzaW9uIGNyaXRlcmlhIGVzdGFibGlzaGVkJ1xuICAgIF1cbiAgfSxcblxuICAnc2VjdXJpdHktYXVkaXQnOiB7XG4gICAgaWQ6ICdzZWN1cml0eS1hdWRpdCcsXG4gICAgbmFtZTogJ1NlY3VyaXR5IEF1ZGl0JyxcbiAgICBkZXNjcmlwdGlvbjogJ0NvbmR1Y3Qgc2VjdXJpdHkgYXVkaXQgb2Ygc3lzdGVtIG9yIGNvbXBvbmVudCcsXG4gICAgY2F0ZWdvcnk6ICdvcGVyYXRpb25zJyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgaW1wb3J0YW5jZTogOSxcbiAgICAgIHVyZ2VuY3k6IDYsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDYsXG4gICAgICByaXNrTGV2ZWw6ICdtZWRpdW0nLFxuICAgICAgdGFnczogWydzZWN1cml0eScsICdhdWRpdCcsICdjb21wbGlhbmNlJ11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ2F1ZGl0U2NvcGUnLCAnY29tcGxpYW5jZUZyYW1ld29yayddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ1Z1bG5lcmFiaWxpdGllcyBpZGVudGlmaWVkJyxcbiAgICAgICdSaXNrIGFzc2Vzc21lbnQgY29tcGxldGVkJyxcbiAgICAgICdSZW1lZGlhdGlvbiBwbGFuIGNyZWF0ZWQnLFxuICAgICAgJ1JlcG9ydCBnZW5lcmF0ZWQnXG4gICAgXVxuICB9LFxuXG4gICdwZXJmb3JtYW5jZS1vcHRpbWl6YXRpb24nOiB7XG4gICAgaWQ6ICdwZXJmb3JtYW5jZS1vcHRpbWl6YXRpb24nLFxuICAgIG5hbWU6ICdQZXJmb3JtYW5jZSBPcHRpbWl6YXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOiAnT3B0aW1pemUgc3lzdGVtIHBlcmZvcm1hbmNlIGJhc2VkIG9uIG1ldHJpY3MnLFxuICAgIGNhdGVnb3J5OiAnbWFpbnRlbmFuY2UnLFxuICAgIGRlZmF1bHRWYWx1ZXM6IHtcbiAgICAgIHByaW9yaXR5OiAnbWVkaXVtJyxcbiAgICAgIGltcG9ydGFuY2U6IDYsXG4gICAgICB1cmdlbmN5OiA0LFxuICAgICAgZXN0aW1hdGVkRWZmb3J0OiA4LFxuICAgICAgcmlza0xldmVsOiAnbWVkaXVtJyxcbiAgICAgIHRhZ3M6IFsncGVyZm9ybWFuY2UnLCAnb3B0aW1pemF0aW9uJywgJ21ldHJpY3MnXVxuICAgIH0sXG4gICAgcmVxdWlyZWRGaWVsZHM6IFsncGVyZm9ybWFuY2VNZXRyaWNzJywgJ3RhcmdldEltcHJvdmVtZW50J10sXG4gICAgc3VjY2Vzc0NyaXRlcmlhOiBbXG4gICAgICAnQmFzZWxpbmUgbWV0cmljcyBjYXB0dXJlZCcsXG4gICAgICAnT3B0aW1pemF0aW9ucyBpbXBsZW1lbnRlZCcsXG4gICAgICAnUGVyZm9ybWFuY2UgaW1wcm92ZWQgYnkgdGFyZ2V0ICUnLFxuICAgICAgJ05vIHJlZ3Jlc3Npb24gaW4gZnVuY3Rpb25hbGl0eSdcbiAgICBdXG4gIH0sXG5cbiAgJ2RvY3VtZW50YXRpb24tdXBkYXRlJzoge1xuICAgIGlkOiAnZG9jdW1lbnRhdGlvbi11cGRhdGUnLFxuICAgIG5hbWU6ICdEb2N1bWVudGF0aW9uIFVwZGF0ZScsXG4gICAgZGVzY3JpcHRpb246ICdVcGRhdGUgdGVjaG5pY2FsIG9yIHVzZXIgZG9jdW1lbnRhdGlvbicsXG4gICAgY2F0ZWdvcnk6ICdtYWludGVuYW5jZScsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdsb3cnLFxuICAgICAgaW1wb3J0YW5jZTogNSxcbiAgICAgIHVyZ2VuY3k6IDIsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDMsXG4gICAgICByaXNrTGV2ZWw6ICdsb3cnLFxuICAgICAgdGFnczogWydkb2N1bWVudGF0aW9uJywgJ21haW50ZW5hbmNlJ11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ2RvY3VtZW50VHlwZScsICdzZWN0aW9ucyddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ0RvY3VtZW50YXRpb24gcmV2aWV3ZWQnLFxuICAgICAgJ1VwZGF0ZXMgY29tcGxldGVkJyxcbiAgICAgICdSZXZpZXdlZCBieSBzdGFrZWhvbGRlcnMnLFxuICAgICAgJ1B1Ymxpc2hlZCB0byBhcHByb3ByaWF0ZSBsb2NhdGlvbidcbiAgICBdXG4gIH0sXG5cbiAgJ3F1YXJ0ZXJseS1wbGFubmluZyc6IHtcbiAgICBpZDogJ3F1YXJ0ZXJseS1wbGFubmluZycsXG4gICAgbmFtZTogJ1F1YXJ0ZXJseSBQbGFubmluZycsXG4gICAgZGVzY3JpcHRpb246ICdQbGFuIGdvYWxzIGFuZCBwcmlvcml0aWVzIGZvciB0aGUgcXVhcnRlcicsXG4gICAgY2F0ZWdvcnk6ICdwbGFubmluZycsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdoaWdoJyxcbiAgICAgIGltcG9ydGFuY2U6IDksXG4gICAgICB1cmdlbmN5OiA3LFxuICAgICAgZXN0aW1hdGVkRWZmb3J0OiAxMixcbiAgICAgIHJpc2tMZXZlbDogJ2xvdycsXG4gICAgICB0YWdzOiBbJ3BsYW5uaW5nJywgJ3F1YXJ0ZXJseScsICdzdHJhdGVneSddXG4gICAgfSxcbiAgICByZXF1aXJlZEZpZWxkczogWydxdWFydGVyJywgJ29iamVjdGl2ZXMnXSxcbiAgICBzdWNjZXNzQ3JpdGVyaWE6IFtcbiAgICAgICdHb2FscyBkZWZpbmVkIGFuZCBwcmlvcml0aXplZCcsXG4gICAgICAnUmVzb3VyY2VzIGFsbG9jYXRlZCcsXG4gICAgICAnVGltZWxpbmUgZXN0YWJsaXNoZWQnLFxuICAgICAgJ1N0YWtlaG9sZGVyIGFsaWdubWVudCdcbiAgICBdXG4gIH0sXG5cbiAgJ2N1c3RvbS1nb2FsJzoge1xuICAgIGlkOiAnY3VzdG9tLWdvYWwnLFxuICAgIG5hbWU6ICdDdXN0b20gR29hbCcsXG4gICAgZGVzY3JpcHRpb246ICdDcmVhdGUgYSBjdXN0b20gZ29hbCB3aXRoIHlvdXIgb3duIHBhcmFtZXRlcnMnLFxuICAgIGNhdGVnb3J5OiAnY3VzdG9tJyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ21lZGl1bScsXG4gICAgICBpbXBvcnRhbmNlOiA1LFxuICAgICAgdXJnZW5jeTogNSxcbiAgICAgIHJpc2tMZXZlbDogJ21lZGl1bScsXG4gICAgICB0YWdzOiBbJ2N1c3RvbSddXG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEFwcGx5IGEgZ29hbCB0ZW1wbGF0ZSB0byBjcmVhdGUgYSBuZXcgZ29hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlHb2FsVGVtcGxhdGUoXG4gIHRlbXBsYXRlSWQ6IHN0cmluZyxcbiAgY3VzdG9tRmllbGRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4pOiBQYXJ0aWFsPGFueT4geyAgLy8gUmV0dXJucyBwYXJ0aWFsIEFnZW50R29hbFxuICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBnb2FsIHRlbXBsYXRlIHVzYWdlXG4gIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICB0eXBlOiAnR09BTF9URU1QTEFURV9BUFBMSUVEJyxcbiAgICBzZXZlcml0eTogJ0xPVycsXG4gICAgc291cmNlOiAnYXBwbHlHb2FsVGVtcGxhdGUnLFxuICAgIGRldGFpbHM6IGBHb2FsIHRlbXBsYXRlICcke3RlbXBsYXRlSWR9JyBhcHBsaWVkYFxuICB9KTtcblxuICBjb25zdCB0ZW1wbGF0ZSA9IEdPQUxfVEVNUExBVEVTW3RlbXBsYXRlSWRdO1xuICBpZiAoIXRlbXBsYXRlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBHb2FsIHRlbXBsYXRlICcke3RlbXBsYXRlSWR9JyBub3QgZm91bmRgKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHJlcXVpcmVkIGZpZWxkc1xuICBpZiAodGVtcGxhdGUucmVxdWlyZWRGaWVsZHMpIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRlbXBsYXRlLnJlcXVpcmVkRmllbGRzKSB7XG4gICAgICBpZiAoIWN1c3RvbUZpZWxkc1tmaWVsZF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXF1aXJlZCBmaWVsZCAnJHtmaWVsZH0nIG1pc3NpbmcgZm9yIHRlbXBsYXRlICcke3RlbXBsYXRlLm5hbWV9J2ApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSBFaXNlbmhvd2VyIHF1YWRyYW50IGJhc2VkIG9uIHRlbXBsYXRlIGRlZmF1bHRzXG4gIGNvbnN0IGltcG9ydGFuY2UgPSBjdXN0b21GaWVsZHMuaW1wb3J0YW5jZSB8fCB0ZW1wbGF0ZS5kZWZhdWx0VmFsdWVzLmltcG9ydGFuY2U7XG4gIGNvbnN0IHVyZ2VuY3kgPSBjdXN0b21GaWVsZHMudXJnZW5jeSB8fCB0ZW1wbGF0ZS5kZWZhdWx0VmFsdWVzLnVyZ2VuY3k7XG4gIGNvbnN0IGVpc2VuaG93ZXJRdWFkcmFudCA9IGNhbGN1bGF0ZUVpc2VuaG93ZXJRdWFkcmFudChpbXBvcnRhbmNlLCB1cmdlbmN5KTtcblxuICAvLyBFbnN1cmUgZGVzY3JpcHRpb24gaXMgcHJvdmlkZWRcbiAgY29uc3QgZGVzY3JpcHRpb24gPSBjdXN0b21GaWVsZHMuZGVzY3JpcHRpb24gfHwgXG4gICAgYCR7dGVtcGxhdGUubmFtZX06ICR7dGVtcGxhdGUucmVxdWlyZWRGaWVsZHM/Lm1hcChmID0+IGN1c3RvbUZpZWxkc1tmXSkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oJyAtICcpIHx8IHRlbXBsYXRlLmRlc2NyaXB0aW9ufWA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi50ZW1wbGF0ZS5kZWZhdWx0VmFsdWVzLFxuICAgIC4uLmN1c3RvbUZpZWxkcyxcbiAgICBkZXNjcmlwdGlvbixcbiAgICBlaXNlbmhvd2VyUXVhZHJhbnQsXG4gICAgdGVtcGxhdGVJZCxcbiAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpXG4gIH07XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIEVpc2VuaG93ZXIgcXVhZHJhbnQgZnJvbSBpbXBvcnRhbmNlIGFuZCB1cmdlbmN5LlxuICogVXNlcyB0aGUgdGhyZXNob2xkIGZyb20gRUlTRU5IT1dFUl9USFJFU0hPTERTLkhJR0hfUFJJT1JJVFkgdG8gY2xhc3NpZnkgZ29hbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVFaXNlbmhvd2VyUXVhZHJhbnQoaW1wb3J0YW5jZTogbnVtYmVyLCB1cmdlbmN5OiBudW1iZXIpOiBFaXNlbmhvd2VyUXVhZHJhbnQge1xuICBjb25zdCB0aHJlc2hvbGQgPSBFSVNFTkhPV0VSX1RIUkVTSE9MRFMuSElHSF9QUklPUklUWTtcbiAgaWYgKGltcG9ydGFuY2UgPj0gdGhyZXNob2xkICYmIHVyZ2VuY3kgPj0gdGhyZXNob2xkKSByZXR1cm4gJ2RvX2ZpcnN0JztcbiAgaWYgKGltcG9ydGFuY2UgPj0gdGhyZXNob2xkICYmIHVyZ2VuY3kgPCB0aHJlc2hvbGQpIHJldHVybiAnc2NoZWR1bGUnO1xuICBpZiAoaW1wb3J0YW5jZSA8IHRocmVzaG9sZCAmJiB1cmdlbmN5ID49IHRocmVzaG9sZCkgcmV0dXJuICdkZWxlZ2F0ZSc7XG4gIHJldHVybiAnZWxpbWluYXRlJztcbn1cblxuLyoqXG4gKiBHZXQgdGVtcGxhdGUgcmVjb21tZW5kYXRpb25zIGJhc2VkIG9uIGdvYWwgZGVzY3JpcHRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29tbWVuZEdvYWxUZW1wbGF0ZShkZXNjcmlwdGlvbjogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBsb3dlcmNhc2VEZXNjID0gZGVzY3JpcHRpb24udG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgcmVjb21tZW5kYXRpb25zOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIEtleXdvcmRzIG1hcHBpbmcgdG8gdGVtcGxhdGVzXG4gIGNvbnN0IGtleXdvcmRNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHtcbiAgICAnZmVhdHVyZS1pbXBsZW1lbnRhdGlvbic6IFsnZmVhdHVyZScsICdpbXBsZW1lbnQnLCAnZGV2ZWxvcCcsICdidWlsZCddLFxuICAgICdidWctZml4LWNyaXRpY2FsJzogWydidWcnLCAnZml4JywgJ2NyaXRpY2FsJywgJ3VyZ2VudCcsICdicm9rZW4nLCAnZXJyb3InXSxcbiAgICAncmVzZWFyY2gtc3Bpa2UnOiBbJ3Jlc2VhcmNoJywgJ2V4cGxvcmUnLCAnaW52ZXN0aWdhdGUnLCAnc3Bpa2UnLCAnZXZhbHVhdGUnXSxcbiAgICAnc2VjdXJpdHktYXVkaXQnOiBbJ3NlY3VyaXR5JywgJ2F1ZGl0JywgJ3Z1bG5lcmFiaWxpdHknLCAnY29tcGxpYW5jZSddLFxuICAgICdwZXJmb3JtYW5jZS1vcHRpbWl6YXRpb24nOiBbJ3BlcmZvcm1hbmNlJywgJ29wdGltaXplJywgJ3NwZWVkJywgJ3Nsb3cnLCAnbGF0ZW5jeSddLFxuICAgICdkb2N1bWVudGF0aW9uLXVwZGF0ZSc6IFsnZG9jdW1lbnQnLCAnZG9jcycsICdyZWFkbWUnLCAnZ3VpZGUnLCAnbWFudWFsJ10sXG4gICAgJ3F1YXJ0ZXJseS1wbGFubmluZyc6IFsncGxhbicsICdxdWFydGVyJywgJ3JvYWRtYXAnLCAnc3RyYXRlZ3knXVxuICB9O1xuXG4gIC8vIENoZWNrIGZvciBrZXl3b3JkIG1hdGNoZXNcbiAgZm9yIChjb25zdCBbdGVtcGxhdGVJZCwga2V5d29yZHNdIG9mIE9iamVjdC5lbnRyaWVzKGtleXdvcmRNYXApKSB7XG4gICAgaWYgKGtleXdvcmRzLnNvbWUoa2V5d29yZCA9PiBsb3dlcmNhc2VEZXNjLmluY2x1ZGVzKGtleXdvcmQpKSkge1xuICAgICAgcmVjb21tZW5kYXRpb25zLnB1c2godGVtcGxhdGVJZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQWx3YXlzIGluY2x1ZGUgY3VzdG9tIGFzIGFuIG9wdGlvblxuICBpZiAocmVjb21tZW5kYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJlY29tbWVuZGF0aW9ucy5wdXNoKCdjdXN0b20tZ29hbCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlY29tbWVuZGF0aW9ucztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBnb2FsIGFnYWluc3QgaXRzIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUdvYWxBZ2FpbnN0VGVtcGxhdGUoXG4gIGdvYWw6IGFueSwgIC8vIEFnZW50R29hbCB0eXBlXG4gIHRlbXBsYXRlSWQ/OiBzdHJpbmdcbik6IHsgdmFsaWQ6IGJvb2xlYW47IGVycm9yczogc3RyaW5nW10gfSB7XG4gIGlmICghdGVtcGxhdGVJZCB8fCAhR09BTF9URU1QTEFURVNbdGVtcGxhdGVJZF0pIHtcbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZXJyb3JzOiBbXSB9O1xuICB9XG5cbiAgLy8gU0VDVVJJVFkgRklYOiBBZGQgYXVkaXQgbG9nZ2luZyBmb3IgdGVtcGxhdGUgdmFsaWRhdGlvblxuICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgdHlwZTogJ0dPQUxfVEVNUExBVEVfVkFMSURBVElPTicsXG4gICAgc2V2ZXJpdHk6ICdMT1cnLFxuICAgIHNvdXJjZTogJ3ZhbGlkYXRlR29hbEFnYWluc3RUZW1wbGF0ZScsXG4gICAgZGV0YWlsczogYFZhbGlkYXRpbmcgZ29hbCBhZ2FpbnN0IHRlbXBsYXRlICcke3RlbXBsYXRlSWR9J2BcbiAgfSk7XG5cbiAgY29uc3QgdGVtcGxhdGUgPSBHT0FMX1RFTVBMQVRFU1t0ZW1wbGF0ZUlkXTtcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkc1xuICBpZiAodGVtcGxhdGUucmVxdWlyZWRGaWVsZHMpIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRlbXBsYXRlLnJlcXVpcmVkRmllbGRzKSB7XG4gICAgICBpZiAoIWdvYWxbZmllbGRdKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkOiAke2ZpZWxkfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHJpc2sgbGV2ZWwgbWF0Y2hlcyB0ZW1wbGF0ZSBjYXRlZ29yeVxuICBpZiAodGVtcGxhdGUuY2F0ZWdvcnkgPT09ICdvcGVyYXRpb25zJyAmJiBnb2FsLnJpc2tMZXZlbCA9PT0gJ2hpZ2gnKSB7XG4gICAgZXJyb3JzLnB1c2goJ0hpZ2ggcmlzayBvcGVyYXRpb25zIGdvYWxzIHJlcXVpcmUgYWRkaXRpb25hbCBhcHByb3ZhbCcpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICBlcnJvcnNcbiAgfTtcbn0iXX0=