@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
JavaScript
/**
* 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=