@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.
124 lines • 18.3 kB
JavaScript
/**
* Shared constants for Agent elements
*/
// Internal symbols for cross-class communication (not exported from package)
// These provide runtime privacy for methods that need to be called between
// Agent and AgentManager but should not be accessible to external code.
/**
* Symbol for committing persisted state version.
* Used by AgentManager to sync Agent's internal stateVersion after successful save.
* @internal
*/
export const COMMIT_PERSISTED_VERSION = Symbol('commitPersistedVersion');
// Security limits
export const AGENT_LIMITS = {
MAX_GOALS: 50,
MAX_GOAL_LENGTH: 1000,
MAX_STATE_SIZE: 100 * 1024, // 100KB
MAX_DECISION_HISTORY: 100,
MAX_CONTEXT_LENGTH: 5000,
MAX_RENDERED_GOAL_LENGTH: 5000,
MAX_AGENT_NAME_LENGTH: 100,
MAX_SPECIALIZATION_LENGTH: 50,
MAX_CONCURRENT_GOALS_DEFAULT: 10,
MAX_FILE_SIZE: 100 * 1024, // 100KB
MAX_YAML_SIZE: 64 * 1024 // 64KB
};
// File extensions
export const AGENT_FILE_EXTENSION = '.md';
export const STATE_FILE_EXTENSION = '.state.yaml';
export const STATE_DIRECTORY = '.state';
// Decision frameworks
export const DECISION_FRAMEWORKS = ['rule_based', 'ml_based', 'programmatic', 'hybrid', 'llm_driven'];
// Risk tolerance levels
export const RISK_TOLERANCE_LEVELS = ['conservative', 'moderate', 'aggressive'];
// Resilience policy enums (Issue #727: shared between read and write validation)
export const STEP_LIMIT_ACTIONS = ['pause', 'continue', 'restart'];
export const EXECUTION_FAILURE_ACTIONS = ['pause', 'retry', 'restart-fresh'];
export const BACKOFF_STRATEGIES = ['none', 'linear', 'exponential'];
// Goal priorities
export const GOAL_PRIORITIES = ['critical', 'high', 'medium', 'low'];
// Goal statuses
export const GOAL_STATUSES = ['pending', 'in_progress', 'completed', 'failed', 'cancelled'];
// Eisenhower quadrants
export const EISENHOWER_QUADRANTS = ['do_first', 'schedule', 'delegate', 'eliminate'];
// Eisenhower matrix thresholds for quadrant classification
// Importance and urgency are on a 1-10 scale
export const EISENHOWER_THRESHOLDS = {
/** Threshold for high importance/urgency (>= this value is considered "high") */
HIGH_PRIORITY: 7,
};
// Agent behavior thresholds
export const AGENT_THRESHOLDS = {
/** Percentage of max concurrent goals that triggers a risk warning (0.8 = 80%) */
CONCURRENT_GOAL_WARNING: 0.8,
};
// Decision outcomes
export const DECISION_OUTCOMES = ['success', 'failure', 'partial', 'unknown'];
// Risk levels
export const RISK_LEVELS = ['low', 'medium', 'high'];
// ============================================================================
// Issue #730: Shared validation & normalization helpers
// ============================================================================
/**
* Type-safe membership check against a readonly string tuple.
* Centralizes the `(ARRAY as readonly string[]).includes(value as string)` cast pattern.
*/
export function isOneOf(value, options) {
return typeof value === 'string' && options.includes(value);
}
/**
* Promote a snake_case key to its camelCase equivalent on an object.
* If the camelCase key already exists, the snake_case key is just deleted
* (camelCase takes precedence, no clobber).
*/
function promoteSnakeCase(obj, snake, camel) {
if (obj[snake] !== undefined && obj[camel] === undefined) {
obj[camel] = obj[snake];
}
delete obj[snake];
}
/**
* Normalize snake_case keys in an autonomy config object to camelCase.
* Mutates the object in place. Safe to call on already-normalized objects.
*/
export function normalizeAutonomyKeys(obj) {
promoteSnakeCase(obj, 'risk_tolerance', 'riskTolerance');
// Order matters: max_autonomous_steps (canonical snake_case) takes precedence
// over maxSteps (short form) when both are present — promoteSnakeCase is no-clobber.
promoteSnakeCase(obj, 'max_autonomous_steps', 'maxAutonomousSteps');
// Issue #697: LLMs and older agents may use the shorter `maxSteps` form
promoteSnakeCase(obj, 'maxSteps', 'maxAutonomousSteps');
promoteSnakeCase(obj, 'requires_approval', 'requiresApproval');
promoteSnakeCase(obj, 'auto_approve', 'autoApprove');
}
/**
* Normalize snake_case keys in a resilience config object to camelCase.
* Mutates the object in place. Safe to call on already-normalized objects.
*/
export function normalizeResilienceKeys(obj) {
promoteSnakeCase(obj, 'on_step_limit_reached', 'onStepLimitReached');
promoteSnakeCase(obj, 'on_execution_failure', 'onExecutionFailure');
promoteSnakeCase(obj, 'max_retries', 'maxRetries');
promoteSnakeCase(obj, 'max_continuations', 'maxContinuations');
promoteSnakeCase(obj, 'retry_backoff', 'retryBackoff');
promoteSnakeCase(obj, 'preserve_state', 'preserveState');
}
/**
* Normalize snake_case keys in a goal config object to camelCase.
* Mutates the object in place. Safe to call on already-normalized objects.
*/
export function normalizeGoalKeys(obj) {
promoteSnakeCase(obj, 'success_criteria', 'successCriteria');
}
// Default values
export const AGENT_DEFAULTS = {
DECISION_FRAMEWORK: 'rule_based',
RISK_TOLERANCE: 'moderate',
LEARNING_ENABLED: true,
MAX_CONCURRENT_GOALS: 10,
GOAL_PRIORITY: 'medium',
GOAL_IMPORTANCE: 5,
GOAL_URGENCY: 5
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VsZW1lbnRzL2FnZW50cy9jb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCw2RUFBNkU7QUFDN0UsMkVBQTJFO0FBQzNFLHdFQUF3RTtBQUV4RTs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFFekUsa0JBQWtCO0FBQ2xCLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRztJQUMxQixTQUFTLEVBQUUsRUFBRTtJQUNiLGVBQWUsRUFBRSxJQUFJO0lBQ3JCLGNBQWMsRUFBRSxHQUFHLEdBQUcsSUFBSSxFQUFFLFFBQVE7SUFDcEMsb0JBQW9CLEVBQUUsR0FBRztJQUN6QixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLHdCQUF3QixFQUFFLElBQUk7SUFDOUIscUJBQXFCLEVBQUUsR0FBRztJQUMxQix5QkFBeUIsRUFBRSxFQUFFO0lBQzdCLDRCQUE0QixFQUFFLEVBQUU7SUFDaEMsYUFBYSxFQUFFLEdBQUcsR0FBRyxJQUFJLEVBQUUsUUFBUTtJQUNuQyxhQUFhLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBRSxPQUFPO0NBQ3pCLENBQUM7QUFFWCxrQkFBa0I7QUFDbEIsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLGFBQWEsQ0FBQztBQUNsRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBRXhDLHNCQUFzQjtBQUN0QixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxZQUFZLENBQVUsQ0FBQztBQUcvRyx3QkFBd0I7QUFDeEIsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcs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QixDQUFDLEdBQUcsRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3JFLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3BFLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDbkQsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixDQUFDLENBQUM7SUFDL0QsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLGVBQWUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN2RCxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUE0QjtJQUM1RCxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBRUQsaUJBQWlCO0FBQ2pCLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRztJQUM1QixrQkFBa0IsRUFBRSxZQUFpQztJQUNyRCxjQUFjLEVBQUUsVUFBMkI7SUFDM0MsZ0JBQWdCLEVBQUUsSUFBSTtJQUN0QixvQkFBb0IsRUFBRSxFQUFFO0lBQ3hCLGFBQWEsRUFBRSxRQUF3QjtJQUN2QyxlQUFlLEVBQUUsQ0FBQztJQUNsQixZQUFZLEVBQUUsQ0FBQztDQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNoYXJlZCBjb25zdGFudHMgZm9yIEFnZW50IGVsZW1lbnRzXG4gKi9cblxuLy8gSW50ZXJuYWwgc3ltYm9scyBmb3IgY3Jvc3MtY2xhc3MgY29tbXVuaWNhdGlvbiAobm90IGV4cG9ydGVkIGZyb20gcGFja2FnZSlcbi8vIFRoZXNlIHByb3ZpZGUgcnVudGltZSBwcml2YWN5IGZvciBtZXRob2RzIHRoYXQgbmVlZCB0byBiZSBjYWxsZWQgYmV0d2VlblxuLy8gQWdlbnQgYW5kIEFnZW50TWFuYWdlciBidXQgc2hvdWxkIG5vdCBiZSBhY2Nlc3NpYmxlIHRvIGV4dGVybmFsIGNvZGUuXG5cbi8qKlxuICogU3ltYm9sIGZvciBjb21taXR0aW5nIHBlcnNpc3RlZCBzdGF0ZSB2ZXJzaW9uLlxuICogVXNlZCBieSBBZ2VudE1hbmFnZXIgdG8gc3luYyBBZ2VudCdzIGludGVybmFsIHN0YXRlVmVyc2lvbiBhZnRlciBzdWNjZXNzZnVsIHNhdmUuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGNvbnN0IENPTU1JVF9QRVJTSVNURURfVkVSU0lPTiA9IFN5bWJvbCgnY29tbWl0UGVyc2lzdGVkVmVyc2lvbicpO1xuXG4vLyBTZWN1cml0eSBsaW1pdHNcbmV4cG9ydCBjb25zdCBBR0VOVF9MSU1JVFMgPSB7XG4gIE1BWF9HT0FMUzogNTAsXG4gIE1BWF9HT0FMX0xFTkdUSDogMTAwMCxcbiAgTUFYX1NUQVRFX1NJWkU6IDEwMCAqIDEwMjQsIC8vIDEwMEtCXG4gIE1BWF9ERUNJU0lPTl9ISVNUT1JZOiAxMDAsXG4gIE1BWF9DT05URVhUX0xFTkdUSDogNTAwMCxcbiAgTUFYX1JFTkRFUkVEX0dPQUxfTEVOR1RIOiA1MDAwLFxuICBNQVhfQUdFTlRfTkFNRV9MRU5HVEg6IDEwMCxcbiAgTUFYX1NQRUNJQUxJWkFUSU9OX0xFTkdUSDogNTAsXG4gIE1BWF9DT05DVVJSRU5UX0dPQUxTX0RFRkFVTFQ6IDEwLFxuICBNQVhfRklMRV9TSVpFOiAxMDAgKiAxMDI0LCAvLyAxMDBLQlxuICBNQVhfWUFNTF9TSVpFOiA2NCAqIDEwMjQgIC8vIDY0S0Jcbn0gYXMgY29uc3Q7XG5cbi8vIEZpbGUgZXh0ZW5zaW9uc1xuZXhwb3J0IGNvbnN0IEFHRU5UX0ZJTEVfRVhURU5TSU9OID0gJy5tZCc7XG5leHBvcnQgY29uc3QgU1RBVEVfRklMRV9FWFRFTlNJT04gPSAnLnN0YXRlLnlhbWwnO1xuZXhwb3J0IGNvbnN0IFNUQVRFX0RJUkVDVE9SWSA9ICcuc3RhdGUnO1xuXG4vLyBEZWNpc2lvbiBmcmFtZXdvcmtzXG5leHBvcnQgY29uc3QgREVDSVNJT05fRlJBTUVXT1JLUyA9IFsncnVsZV9iYXNlZCcsICdtbF9iYXNlZCcsICdwcm9ncmFtbWF0aWMnLCAnaHlicmlkJywgJ2xsbV9kcml2ZW4nXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIERlY2lzaW9uRnJhbWV3b3JrID0gdHlwZW9mIERFQ0lTSU9OX0ZSQU1FV09SS1NbbnVtYmVyXTtcblxuLy8gUmlzayB0b2xlcmFuY2UgbGV2ZWxzXG5leHBvcnQgY29uc3QgUklTS19UT0xFUkFOQ0VfTEVWRUxTID0gWydjb25zZXJ2YXRpdmUnLCAnbW9kZXJhdGUnLCAnYWdncmVzc2l2ZSddIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgUmlza1RvbGVyYW5jZSA9IHR5cGVvZiBSSVNLX1RPTEVSQU5DRV9MRVZFTFNbbnVtYmVyXTtcblxuLy8gUmVzaWxpZW5jZSBwb2xpY3kgZW51bXMgKElzc3VlICM3Mjc6IHNoYXJlZCBiZXR3ZWVuIHJlYWQgYW5kIHdyaXRlIHZhbGlkYXRpb24pXG5leHBvcnQgY29uc3QgU1RFUF9MSU1JVF9BQ1RJT05TID0gWydwYXVzZScsICdjb250aW51ZScsICdyZXN0YXJ0J10gYXMgY29uc3Q7XG5leHBvcnQgdHlwZSBTdGVwTGltaXRBY3Rpb24gPSB0eXBlb2YgU1RFUF9MSU1JVF9BQ1RJT05TW251bWJlcl07XG5cbmV4cG9ydCBjb25zdCBFWEVDVVRJT05fRkFJTFVSRV9BQ1RJT05TID0gWydwYXVzZScsICdyZXRyeScsICdyZXN0YXJ0LWZyZXNoJ10gYXMgY29uc3Q7XG5leHBvcnQgdHlwZSBFeGVjdXRpb25GYWlsdXJlQWN0aW9uID0gdHlwZW9mIEVYRUNVVElPTl9GQUlMVVJFX0FDVElPTlNbbnVtYmVyXTtcblxuZXhwb3J0IGNvbnN0IEJBQ0tPRkZfU1RSQVRFR0lFUyA9IFsnbm9uZScsICdsaW5lYXInLCAnZXhwb25lbnRpYWwnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEJhY2tvZmZTdHJhdGVneSA9IHR5cGVvZiBCQUNLT0ZGX1NUUkFURUdJRVNbbnVtYmVyXTtcblxuLy8gR29hbCBwcmlvcml0aWVzXG5leHBvcnQgY29uc3QgR09BTF9QUklPUklUSUVTID0gWydjcml0aWNhbCcsICdoaWdoJywgJ21lZGl1bScsICdsb3cnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEdvYWxQcmlvcml0eSA9IHR5cGVvZiBHT0FMX1BSSU9SSVRJRVNbbnVtYmVyXTtcblxuLy8gR29hbCBzdGF0dXNlc1xuZXhwb3J0IGNvbnN0IEdPQUxfU1RBVFVTRVMgPSBbJ3BlbmRpbmcnLCAnaW5fcHJvZ3Jlc3MnLCAnY29tcGxldGVkJywgJ2ZhaWxlZCcsICdjYW5jZWxsZWQnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEdvYWxTdGF0dXMgPSB0eXBlb2YgR09BTF9TVEFUVVNFU1tudW1iZXJdO1xuXG4vLyBFaXNlbmhvd2VyIHF1YWRyYW50c1xuZXhwb3J0IGNvbnN0IEVJU0VOSE9XRVJfUVVBRFJBTlRTID0gWydkb19maXJzdCcsICdzY2hlZHVsZScsICdkZWxlZ2F0ZScsICdlbGltaW5hdGUnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEVpc2VuaG93ZXJRdWFkcmFudCA9IHR5cGVvZiBFSVNFTkhPV0VSX1FVQURSQU5UU1tudW1iZXJdO1xuXG4vLyBFaXNlbmhvd2VyIG1hdHJpeCB0aHJlc2hvbGRzIGZvciBxdWFkcmFudCBjbGFzc2lmaWNhdGlvblxuLy8gSW1wb3J0YW5jZSBhbmQgdXJnZW5jeSBhcmUgb24gYSAxLTEwIHNjYWxlXG5leHBvcnQgY29uc3QgRUlTRU5IT1dFUl9USFJFU0hPTERTID0ge1xuICAvKiogVGhyZXNob2xkIGZvciBoaWdoIGltcG9ydGFuY2UvdXJnZW5jeSAoPj0gdGhpcyB2YWx1ZSBpcyBjb25zaWRlcmVkIFwiaGlnaFwiKSAqL1xuICBISUdIX1BSSU9SSVRZOiA3LFxufSBhcyBjb25zdDtcblxuLy8gQWdlbnQgYmVoYXZpb3IgdGhyZXNob2xkc1xuZXhwb3J0IGNvbnN0IEFHRU5UX1RIUkVTSE9MRFMgPSB7XG4gIC8qKiBQZXJjZW50YWdlIG9mIG1heCBjb25jdXJyZW50IGdvYWxzIHRoYXQgdHJpZ2dlcnMgYSByaXNrIHdhcm5pbmcgKDAuOCA9IDgwJSkgKi9cbiAgQ09OQ1VSUkVOVF9HT0FMX1dBUk5JTkc6IDAuOCxcbn0gYXMgY29uc3Q7XG5cbi8vIERlY2lzaW9uIG91dGNvbWVzXG5leHBvcnQgY29uc3QgREVDSVNJT05fT1VUQ09NRVMgPSBbJ3N1Y2Nlc3MnLCAnZmFpbHVyZScsICdwYXJ0aWFsJywgJ3Vua25vd24nXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIERlY2lzaW9uT3V0Y29tZSA9IHR5cGVvZiBERUNJU0lPTl9PVVRDT01FU1tudW1iZXJdO1xuXG4vLyBSaXNrIGxldmVsc1xuZXhwb3J0IGNvbnN0IFJJU0tfTEVWRUxTID0gWydsb3cnLCAnbWVkaXVtJywgJ2hpZ2gnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIFJpc2tMZXZlbCA9IHR5cGVvZiBSSVNLX0xFVkVMU1tudW1iZXJdO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBJc3N1ZSAjNzMwOiBTaGFyZWQgdmFsaWRhdGlvbiAmIG5vcm1hbGl6YXRpb24gaGVscGVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFR5cGUtc2FmZSBtZW1iZXJzaGlwIGNoZWNrIGFnYWluc3QgYSByZWFkb25seSBzdHJpbmcgdHVwbGUuXG4gKiBDZW50cmFsaXplcyB0aGUgYChBUlJBWSBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXModmFsdWUgYXMgc3RyaW5nKWAgY2FzdCBwYXR0ZXJuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPbmVPZih2YWx1ZTogdW5rbm93biwgb3B0aW9uczogcmVhZG9ubHkgc3RyaW5nW10pOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgb3B0aW9ucy5pbmNsdWRlcyh2YWx1ZSk7XG59XG5cbi8qKlxuICogUHJvbW90ZSBhIHNuYWtlX2Nhc2Uga2V5IHRvIGl0cyBjYW1lbENhc2UgZXF1aXZhbGVudCBvbiBhbiBvYmplY3QuXG4gKiBJZiB0aGUgY2FtZWxDYXNlIGtleSBhbHJlYWR5IGV4aXN0cywgdGhlIHNuYWtlX2Nhc2Uga2V5IGlzIGp1c3QgZGVsZXRlZFxuICogKGNhbWVsQ2FzZSB0YWtlcyBwcmVjZWRlbmNlLCBubyBjbG9iYmVyKS5cbiAqL1xuZnVuY3Rpb24gcHJvbW90ZVNuYWtlQ2FzZShvYmo6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBzbmFrZTogc3RyaW5nLCBjYW1lbDogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChvYmpbc25ha2VdICE9PSB1bmRlZmluZWQgJiYgb2JqW2NhbWVsXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgb2JqW2NhbWVsXSA9IG9ialtzbmFrZV07XG4gIH1cbiAgZGVsZXRlIG9ialtzbmFrZV07XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHNuYWtlX2Nhc2Uga2V5cyBpbiBhbiBhdXRvbm9teSBjb25maWcgb2JqZWN0IHRvIGNhbWVsQ2FzZS5cbiAqIE11dGF0ZXMgdGhlIG9iamVjdCBpbiBwbGFjZS4gU2FmZSB0byBjYWxsIG9uIGFscmVhZHktbm9ybWFsaXplZCBvYmplY3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQXV0b25vbXlLZXlzKG9iajogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkIHtcbiAgcHJvbW90ZVNuYWtlQ2FzZShvYmosICdyaXNrX3RvbGVyYW5jZScsICdyaXNrVG9sZXJhbmNlJyk7XG4gIC8vIE9yZGVyIG1hdHRlcnM6IG1heF9hdXRvbm9tb3VzX3N0ZXBzIChjYW5vbmljYWwgc25ha2VfY2FzZSkgdGFrZXMgcHJlY2VkZW5jZVxuICAvLyBvdmVyIG1heFN0ZXBzIChzaG9ydCBmb3JtKSB3aGVuIGJvdGggYXJlIHByZXNlbnQg4oCUIHByb21vdGVTbmFrZUNhc2UgaXMgbm8tY2xvYmJlci5cbiAgcHJvbW90ZVNuYWtlQ2FzZShvYmosICdtYXhfYXV0b25vbW91c19zdGVwcycsICdtYXhBdXRvbm9tb3VzU3RlcHMnKTtcbiAgLy8gSXNzdWUgIzY5NzogTExNcyBhbmQgb2xkZXIgYWdlbnRzIG1heSB1c2UgdGhlIHNob3J0ZXIgYG1heFN0ZXBzYCBmb3JtXG4gIHByb21vdGVTbmFrZUNhc2Uob2JqLCAnbWF4U3RlcHMnLCAnbWF4QXV0b25vbW91c1N0ZXBzJyk7XG4gIHByb21vdGVTbmFrZUNhc2Uob2JqLCAncmVxdWlyZXNfYXBwcm92YWwnLCAncmVxdWlyZXNBcHByb3ZhbCcpO1xuICBwcm9tb3RlU25ha2VDYXNlKG9iaiwgJ2F1dG9fYXBwcm92ZScsICdhdXRvQXBwcm92ZScpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBzbmFrZV9jYXNlIGtleXMgaW4gYSByZXNpbGllbmNlIGNvbmZpZyBvYmplY3QgdG8gY2FtZWxDYXNlLlxuICogTXV0YXRlcyB0aGUgb2JqZWN0IGluIHBsYWNlLiBTYWZlIHRvIGNhbGwgb24gYWxyZWFkeS1ub3JtYWxpemVkIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSZXNpbGllbmNlS2V5cyhvYmo6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gIHByb21vdGVTbmFrZUNhc2Uob2JqLCAnb25fc3RlcF9saW1pdF9yZWFjaGVkJywgJ29uU3RlcExpbWl0UmVhY2hlZCcpO1xuICBwcm9tb3RlU25ha2VDYXNlKG9iaiwgJ29uX2V4ZWN1dGlvbl9mYWlsdXJlJywgJ29uRXhlY3V0aW9uRmFpbHVyZScpO1xuICBwcm9tb3RlU25ha2VDYXNlKG9iaiwgJ21heF9yZXRyaWVzJywgJ21heFJldHJpZXMnKTtcbiAgcHJvbW90ZVNuYWtlQ2FzZShvYmosICdtYXhfY29udGludWF0aW9ucycsICdtYXhDb250aW51YXRpb25zJyk7XG4gIHByb21vdGVTbmFrZUNhc2Uob2JqLCAncmV0cnlfYmFja29mZicsICdyZXRyeUJhY2tvZmYnKTtcbiAgcHJvbW90ZVNuYWtlQ2FzZShvYmosICdwcmVzZXJ2ZV9zdGF0ZScsICdwcmVzZXJ2ZVN0YXRlJyk7XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHNuYWtlX2Nhc2Uga2V5cyBpbiBhIGdvYWwgY29uZmlnIG9iamVjdCB0byBjYW1lbENhc2UuXG4gKiBNdXRhdGVzIHRoZSBvYmplY3QgaW4gcGxhY2UuIFNhZmUgdG8gY2FsbCBvbiBhbHJlYWR5LW5vcm1hbGl6ZWQgb2JqZWN0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUdvYWxLZXlzKG9iajogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkIHtcbiAgcHJvbW90ZVNuYWtlQ2FzZShvYmosICdzdWNjZXNzX2NyaXRlcmlhJywgJ3N1Y2Nlc3NDcml0ZXJpYScpO1xufVxuXG4vLyBEZWZhdWx0IHZhbHVlc1xuZXhwb3J0IGNvbnN0IEFHRU5UX0RFRkFVTFRTID0ge1xuICBERUNJU0lPTl9GUkFNRVdPUks6ICdydWxlX2Jhc2VkJyBhcyBEZWNpc2lvbkZyYW1ld29yayxcbiAgUklTS19UT0xFUkFOQ0U6ICdtb2RlcmF0ZScgYXMgUmlza1RvbGVyYW5jZSxcbiAgTEVBUk5JTkdfRU5BQkxFRDogdHJ1ZSxcbiAgTUFYX0NPTkNVUlJFTlRfR09BTFM6IDEwLFxuICBHT0FMX1BSSU9SSVRZOiAnbWVkaXVtJyBhcyBHb2FsUHJpb3JpdHksXG4gIEdPQUxfSU1QT1JUQU5DRTogNSxcbiAgR09BTF9VUkdFTkNZOiA1XG59IGFzIGNvbnN0O1xuIl19