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.

124 lines 18.3 kB
/** * 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