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.

212 lines 28.6 kB
/** * GatheredData — Read-side aggregation over agent execution state. * * Provides structured views of agent execution data by querying existing * decision history and goal state. This is NOT a new write pipeline — * it aggregates data that's already captured by the agent state system * and decision recording. * * Part of the Agentic Loop Completion (Epic #380, Issue #68). * * @since v2.0.0 */ // ============================================================================= // Aggregation // ============================================================================= /** * Build gathered data for a specific goalId from agent state. * * Queries the agent's decision history and goal state to produce * a chronological timeline of events. This is a read-side view — * the underlying data was already recorded by recordDecision() and * goal lifecycle methods. * * @param agentName - Name of the agent * @param goalId - Goal ID to gather data for * @param state - Agent's current state (from Agent.getState()) * @returns GatheredData aggregation, or null if goal not found */ export function getGatheredData(agentName, goalId, state) { // Find the target goal const goal = state.goals.find(g => g.id === goalId); if (!goal) { return null; } // Filter decisions for this goal const goalDecisions = state.decisions.filter(d => d.goalId === goalId); // Build the chronological timeline const entries = []; // 1. Goal creation event entries.push(buildGoalCreatedEntry(goal)); // 2. Decision entries (chronological) for (const decision of goalDecisions) { entries.push(buildDecisionEntry(decision, goalId)); // If the decision has findings in the reasoning, add a finding entry if (decision.reasoning && decision.reasoning.length > 0) { entries.push(buildFindingEntry(decision, goalId)); } } // 3. Goal completion event (if completed or failed) if (goal.status === 'completed') { entries.push(buildGoalCompletedEntry(goal)); } else if (goal.status === 'failed') { entries.push(buildGoalFailedEntry(goal)); } // Sort by timestamp (chronological) entries.sort((a, b) => a.timestamp.localeCompare(b.timestamp)); // Compute summary statistics const summary = computeSummary(goalDecisions, goal); return { goalId, agentName, gatheredAt: new Date().toISOString(), entries, summary, goal: { description: goal.description, status: goal.status, createdAt: goal.createdAt instanceof Date ? goal.createdAt.toISOString() : String(goal.createdAt), completedAt: goal.completedAt instanceof Date ? goal.completedAt.toISOString() : goal.completedAt ? String(goal.completedAt) : undefined, }, }; } // ============================================================================= // Entry Builders // ============================================================================= function buildGoalCreatedEntry(goal) { const timestamp = goal.createdAt instanceof Date ? goal.createdAt.toISOString() : String(goal.createdAt); return { type: 'goal_created', timestamp, source: 'AgentManager.executeAgent', goalId: goal.id, content: { summary: `Goal created: ${goal.description.substring(0, 100)}`, details: { priority: goal.priority, importance: goal.importance, urgency: goal.urgency, }, }, }; } function buildDecisionEntry(decision, goalId) { const timestamp = decision.timestamp instanceof Date ? decision.timestamp.toISOString() : String(decision.timestamp); return { type: 'decision', timestamp, source: 'Agent.recordDecision', goalId, content: { summary: decision.decision, details: { confidence: decision.confidence, outcome: decision.outcome, framework: decision.framework, riskLevel: decision.riskAssessment?.level, }, }, }; } function buildFindingEntry(decision, goalId) { const timestamp = decision.timestamp instanceof Date ? decision.timestamp.toISOString() : String(decision.timestamp); return { type: 'finding', timestamp, source: 'Agent.recordDecision', goalId, content: { summary: decision.reasoning.substring(0, 200), details: { fullReasoning: decision.reasoning, decisionId: decision.id, }, }, }; } function buildGoalCompletedEntry(goal) { const timestamp = goal.completedAt instanceof Date ? goal.completedAt.toISOString() : goal.completedAt ? String(goal.completedAt) : new Date().toISOString(); return { type: 'goal_completed', timestamp, source: 'AgentManager.completeAgentGoal', goalId: goal.id, content: { summary: `Goal completed: ${goal.description.substring(0, 100)}`, details: { actualEffort: goal.actualEffort, estimatedEffort: goal.estimatedEffort, }, }, }; } function buildGoalFailedEntry(goal) { const timestamp = goal.completedAt instanceof Date ? goal.completedAt.toISOString() : goal.completedAt ? String(goal.completedAt) : new Date().toISOString(); return { type: 'goal_failed', timestamp, source: 'AgentManager.completeAgentGoal', goalId: goal.id, content: { summary: `Goal failed: ${goal.description.substring(0, 100)}`, details: { notes: goal.notes, }, }, }; } // ============================================================================= // Summary Statistics // ============================================================================= function computeSummary(decisions, goal) { const successfulSteps = decisions.filter(d => d.outcome === 'success').length; const failedSteps = decisions.filter(d => d.outcome === 'failure').length; const partialSteps = decisions.filter(d => d.outcome === 'partial').length; const confidences = decisions.map(d => d.confidence).filter(c => typeof c === 'number'); const averageConfidence = confidences.length > 0 ? confidences.reduce((sum, c) => sum + c, 0) / confidences.length : 0; // Duration from goal creation to last decision or completion const createdAt = goal.createdAt instanceof Date ? goal.createdAt.getTime() : new Date(String(goal.createdAt)).getTime(); let endTime; if (goal.completedAt) { endTime = goal.completedAt instanceof Date ? goal.completedAt.getTime() : new Date(String(goal.completedAt)).getTime(); } else if (decisions.length > 0) { const lastDecision = decisions[decisions.length - 1]; endTime = lastDecision.timestamp instanceof Date ? lastDecision.timestamp.getTime() : new Date(String(lastDecision.timestamp)).getTime(); } else { endTime = Date.now(); } return { totalSteps: decisions.length, successfulSteps, failedSteps, partialSteps, averageConfidence: parseFloat(averageConfidence.toFixed(3)), durationMs: Math.max(0, endTime - createdAt), }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0aGVyZWREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VsZW1lbnRzL2FnZW50cy9nYXRoZXJlZERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUE2REgsZ0ZBQWdGO0FBQ2hGLGNBQWM7QUFDZCxnRkFBZ0Y7QUFFaEY7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsU0FBaUIsRUFDakIsTUFBYyxFQUNkLEtBQTJCO0lBRTNCLHVCQUF1QjtJQUN2QixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsaUNBQWlDO0lBQ2pDLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQztJQUV2RSxtQ0FBbUM7SUFDbkMsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztJQUV4Qyx5QkFBeUI7SUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBRTFDLHNDQUFzQztJQUN0QyxLQUFLLE1BQU0sUUFBUSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFbkQscUVBQXFFO1FBQ3JFLElBQUksUUFBUSxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4RCxP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SSxPQUFlLENBQUM7SUFDcEIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLFlBQVksSUFBSTtZQUN4QyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUU7WUFDNUIsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNuRCxDQUFDO1NBQU0sSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JELE9BQU8sR0FBRyxZQUFZLENBQUMsU0FBUyxZQUFZLElBQUk7WUFDOUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFO1lBQ2xDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekQsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxPQUFPO1FBQ0wsVUFBVSxFQUFFLFNBQVMsQ0FBQyxNQUFNO1FBQzVCLGVBQWU7UUFDZixXQUFXO1FBQ1gsWUFBWTtRQUNaLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0QsVUFBVSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sR0FBRyxTQUFTLENBQUM7S0FDN0MsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdhdGhlcmVkRGF0YSDigJQgUmVhZC1zaWRlIGFnZ3JlZ2F0aW9uIG92ZXIgYWdlbnQgZXhlY3V0aW9uIHN0YXRlLlxuICpcbiAqIFByb3ZpZGVzIHN0cnVjdHVyZWQgdmlld3Mgb2YgYWdlbnQgZXhlY3V0aW9uIGRhdGEgYnkgcXVlcnlpbmcgZXhpc3RpbmdcbiAqIGRlY2lzaW9uIGhpc3RvcnkgYW5kIGdvYWwgc3RhdGUuIFRoaXMgaXMgTk9UIGEgbmV3IHdyaXRlIHBpcGVsaW5lIOKAlFxuICogaXQgYWdncmVnYXRlcyBkYXRhIHRoYXQncyBhbHJlYWR5IGNhcHR1cmVkIGJ5IHRoZSBhZ2VudCBzdGF0ZSBzeXN0ZW1cbiAqIGFuZCBkZWNpc2lvbiByZWNvcmRpbmcuXG4gKlxuICogUGFydCBvZiB0aGUgQWdlbnRpYyBMb29wIENvbXBsZXRpb24gKEVwaWMgIzM4MCwgSXNzdWUgIzY4KS5cbiAqXG4gKiBAc2luY2UgdjIuMC4wXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBBZ2VudFN0YXRlLCBBZ2VudEdvYWwsIEFnZW50RGVjaXNpb24gfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFR5cGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEEgc2luZ2xlIGVudHJ5IGluIHRoZSBnYXRoZXJlZCBkYXRhIHRpbWVsaW5lLlxuICogUmVwcmVzZW50cyBhIGRpc2NyZXRlIGV2ZW50IGR1cmluZyBhZ2VudCBleGVjdXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyZWREYXRhRW50cnkge1xuICAvKiogRW50cnkgdHlwZSBmb3IgZmlsdGVyaW5nIGFuZCBwcmVzZW50YXRpb24gKi9cbiAgdHlwZTogJ2RlY2lzaW9uJyB8ICdnb2FsX2NyZWF0ZWQnIHwgJ2dvYWxfY29tcGxldGVkJyB8ICdnb2FsX2ZhaWxlZCcgfCAnZmluZGluZycgfCAnbWV0cmljJztcbiAgLyoqIElTTyA4NjAxIHRpbWVzdGFtcCBvZiB3aGVuIHRoaXMgZW50cnkgb2NjdXJyZWQgKi9cbiAgdGltZXN0YW1wOiBzdHJpbmc7XG4gIC8qKiBDb21wb25lbnQgb3Igc3Vic3lzdGVtIHRoYXQgZ2VuZXJhdGVkIHRoaXMgZW50cnkgKi9cbiAgc291cmNlOiBzdHJpbmc7XG4gIC8qKiBHb2FsIElEIHRoaXMgZW50cnkgcmVsYXRlcyB0byAqL1xuICBnb2FsSWQ6IHN0cmluZztcbiAgLyoqIFN0cnVjdHVyZWQgY29udGVudCAqL1xuICBjb250ZW50OiB7XG4gICAgLyoqIEh1bWFuLXJlYWRhYmxlIHN1bW1hcnkgb2YgdGhlIGVudHJ5ICovXG4gICAgc3VtbWFyeTogc3RyaW5nO1xuICAgIC8qKiBBZGRpdGlvbmFsIHN0cnVjdHVyZWQgZGV0YWlscyAqL1xuICAgIGRldGFpbHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBBZ2dyZWdhdGVkIGdhdGhlcmVkIGRhdGEgZm9yIGEgc3BlY2lmaWMgZ29hbCBleGVjdXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyZWREYXRhIHtcbiAgLyoqIEdvYWwgSUQgdGhlIGRhdGEgd2FzIGdhdGhlcmVkIGZvciAqL1xuICBnb2FsSWQ6IHN0cmluZztcbiAgLyoqIEFnZW50IG5hbWUgKi9cbiAgYWdlbnROYW1lOiBzdHJpbmc7XG4gIC8qKiBJU08gODYwMSB0aW1lc3RhbXAgd2hlbiB0aGlzIGRhdGEgd2FzIGdhdGhlcmVkICovXG4gIGdhdGhlcmVkQXQ6IHN0cmluZztcbiAgLyoqIFRpbWVsaW5lIG9mIGV2ZW50cyBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyICovXG4gIGVudHJpZXM6IEdhdGhlcmVkRGF0YUVudHJ5W107XG4gIC8qKiBTdW1tYXJ5IHN0YXRpc3RpY3MgKi9cbiAgc3VtbWFyeToge1xuICAgIHRvdGFsU3RlcHM6IG51bWJlcjtcbiAgICBzdWNjZXNzZnVsU3RlcHM6IG51bWJlcjtcbiAgICBmYWlsZWRTdGVwczogbnVtYmVyO1xuICAgIHBhcnRpYWxTdGVwczogbnVtYmVyO1xuICAgIGF2ZXJhZ2VDb25maWRlbmNlOiBudW1iZXI7XG4gICAgLyoqIER1cmF0aW9uIGZyb20gZ29hbCBjcmVhdGlvbiB0byBsYXN0IGRlY2lzaW9uIChvciBub3cpICovXG4gICAgZHVyYXRpb25NczogbnVtYmVyO1xuICB9O1xuICAvKiogR29hbCBtZXRhZGF0YSBzbmFwc2hvdCAqL1xuICBnb2FsOiB7XG4gICAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgICBzdGF0dXM6IHN0cmluZztcbiAgICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgICBjb21wbGV0ZWRBdD86IHN0cmluZztcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEFnZ3JlZ2F0aW9uXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEJ1aWxkIGdhdGhlcmVkIGRhdGEgZm9yIGEgc3BlY2lmaWMgZ29hbElkIGZyb20gYWdlbnQgc3RhdGUuXG4gKlxuICogUXVlcmllcyB0aGUgYWdlbnQncyBkZWNpc2lvbiBoaXN0b3J5IGFuZCBnb2FsIHN0YXRlIHRvIHByb2R1Y2VcbiAqIGEgY2hyb25vbG9naWNhbCB0aW1lbGluZSBvZiBldmVudHMuIFRoaXMgaXMgYSByZWFkLXNpZGUgdmlldyDigJRcbiAqIHRoZSB1bmRlcmx5aW5nIGRhdGEgd2FzIGFscmVhZHkgcmVjb3JkZWQgYnkgcmVjb3JkRGVjaXNpb24oKSBhbmRcbiAqIGdvYWwgbGlmZWN5Y2xlIG1ldGhvZHMuXG4gKlxuICogQHBhcmFtIGFnZW50TmFtZSAtIE5hbWUgb2YgdGhlIGFnZW50XG4gKiBAcGFyYW0gZ29hbElkIC0gR29hbCBJRCB0byBnYXRoZXIgZGF0YSBmb3JcbiAqIEBwYXJhbSBzdGF0ZSAtIEFnZW50J3MgY3VycmVudCBzdGF0ZSAoZnJvbSBBZ2VudC5nZXRTdGF0ZSgpKVxuICogQHJldHVybnMgR2F0aGVyZWREYXRhIGFnZ3JlZ2F0aW9uLCBvciBudWxsIGlmIGdvYWwgbm90IGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRHYXRoZXJlZERhdGEoXG4gIGFnZW50TmFtZTogc3RyaW5nLFxuICBnb2FsSWQ6IHN0cmluZyxcbiAgc3RhdGU6IFJlYWRvbmx5PEFnZW50U3RhdGU+XG4pOiBHYXRoZXJlZERhdGEgfCBudWxsIHtcbiAgLy8gRmluZCB0aGUgdGFyZ2V0IGdvYWxcbiAgY29uc3QgZ29hbCA9IHN0YXRlLmdvYWxzLmZpbmQoZyA9PiBnLmlkID09PSBnb2FsSWQpO1xuICBpZiAoIWdvYWwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEZpbHRlciBkZWNpc2lvbnMgZm9yIHRoaXMgZ29hbFxuICBjb25zdCBnb2FsRGVjaXNpb25zID0gc3RhdGUuZGVjaXNpb25zLmZpbHRlcihkID0+IGQuZ29hbElkID09PSBnb2FsSWQpO1xuXG4gIC8vIEJ1aWxkIHRoZSBjaHJvbm9sb2dpY2FsIHRpbWVsaW5lXG4gIGNvbnN0IGVudHJpZXM6IEdhdGhlcmVkRGF0YUVudHJ5W10gPSBbXTtcblxuICAvLyAxLiBHb2FsIGNyZWF0aW9uIGV2ZW50XG4gIGVudHJpZXMucHVzaChidWlsZEdvYWxDcmVhdGVkRW50cnkoZ29hbCkpO1xuXG4gIC8vIDIuIERlY2lzaW9uIGVudHJpZXMgKGNocm9ub2xvZ2ljYWwpXG4gIGZvciAoY29uc3QgZGVjaXNpb24gb2YgZ29hbERlY2lzaW9ucykge1xuICAgIGVudHJpZXMucHVzaChidWlsZERlY2lzaW9uRW50cnkoZGVjaXNpb24sIGdvYWxJZCkpO1xuXG4gICAgLy8gSWYgdGhlIGRlY2lzaW9uIGhhcyBmaW5kaW5ncyBpbiB0aGUgcmVhc29uaW5nLCBhZGQgYSBmaW5kaW5nIGVudHJ5XG4gICAgaWYgKGRlY2lzaW9uLnJlYXNvbmluZyAmJiBkZWNpc2lvbi5yZWFzb25pbmcubGVuZ3RoID4gMCkge1xuICAgICAgZW50cmllcy5wdXNoKGJ1aWxkRmluZGluZ0VudHJ5KGRlY2lzaW9uLCBnb2FsSWQpKTtcbiAgICB9XG4gIH1cblxuICAvLyAzLiBHb2FsIGNvbXBsZXRpb24gZXZlbnQgKGlmIGNvbXBsZXRlZCBvciBmYWlsZWQpXG4gIGlmIChnb2FsLnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICBlbnRyaWVzLnB1c2goYnVpbGRHb2FsQ29tcGxldGVkRW50cnkoZ29hbCkpO1xuICB9IGVsc2UgaWYgKGdvYWwuc3RhdHVzID09PSAnZmFpbGVkJykge1xuICAgIGVudHJpZXMucHVzaChidWlsZEdvYWxGYWlsZWRFbnRyeShnb2FsKSk7XG4gIH1cblxuICAvLyBTb3J0IGJ5IHRpbWVzdGFtcCAoY2hyb25vbG9naWNhbClcbiAgZW50cmllcy5zb3J0KChhLCBiKSA9PiBhLnRpbWVzdGFtcC5sb2NhbGVDb21wYXJlKGIudGltZXN0YW1wKSk7XG5cbiAgLy8gQ29tcHV0ZSBzdW1tYXJ5IHN0YXRpc3RpY3NcbiAgY29uc3Qgc3VtbWFyeSA9IGNvbXB1dGVTdW1tYXJ5KGdvYWxEZWNpc2lvbnMsIGdvYWwpO1xuXG4gIHJldHVybiB7XG4gICAgZ29hbElkLFxuICAgIGFnZW50TmFtZSxcbiAgICBnYXRoZXJlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgZW50cmllcyxcbiAgICBzdW1tYXJ5LFxuICAgIGdvYWw6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBnb2FsLmRlc2NyaXB0aW9uLFxuICAgICAgc3RhdHVzOiBnb2FsLnN0YXR1cyxcbiAgICAgIGNyZWF0ZWRBdDogZ29hbC5jcmVhdGVkQXQgaW5zdGFuY2VvZiBEYXRlXG4gICAgICAgID8gZ29hbC5jcmVhdGVkQXQudG9JU09TdHJpbmcoKVxuICAgICAgICA6IFN0cmluZyhnb2FsLmNyZWF0ZWRBdCksXG4gICAgICBjb21wbGV0ZWRBdDogZ29hbC5jb21wbGV0ZWRBdCBpbnN0YW5jZW9mIERhdGVcbiAgICAgICAgPyBnb2FsLmNvbXBsZXRlZEF0LnRvSVNPU3RyaW5nKClcbiAgICAgICAgOiBnb2FsLmNvbXBsZXRlZEF0ID8gU3RyaW5nKGdvYWwuY29tcGxldGVkQXQpIDogdW5kZWZpbmVkLFxuICAgIH0sXG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBFbnRyeSBCdWlsZGVyc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gYnVpbGRHb2FsQ3JlYXRlZEVudHJ5KGdvYWw6IEFnZW50R29hbCk6IEdhdGhlcmVkRGF0YUVudHJ5IHtcbiAgY29uc3QgdGltZXN0YW1wID0gZ29hbC5jcmVhdGVkQXQgaW5zdGFuY2VvZiBEYXRlXG4gICAgPyBnb2FsLmNyZWF0ZWRBdC50b0lTT1N0cmluZygpXG4gICAgOiBTdHJpbmcoZ29hbC5jcmVhdGVkQXQpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2dvYWxfY3JlYXRlZCcsXG4gICAgdGltZXN0YW1wLFxuICAgIHNvdXJjZTogJ0FnZW50TWFuYWdlci5leGVjdXRlQWdlbnQnLFxuICAgIGdvYWxJZDogZ29hbC5pZCxcbiAgICBjb250ZW50OiB7XG4gICAgICBzdW1tYXJ5OiBgR29hbCBjcmVhdGVkOiAke2dvYWwuZGVzY3JpcHRpb24uc3Vic3RyaW5nKDAsIDEwMCl9YCxcbiAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgcHJpb3JpdHk6IGdvYWwucHJpb3JpdHksXG4gICAgICAgIGltcG9ydGFuY2U6IGdvYWwuaW1wb3J0YW5jZSxcbiAgICAgICAgdXJnZW5jeTogZ29hbC51cmdlbmN5LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZERlY2lzaW9uRW50cnkoZGVjaXNpb246IEFnZW50RGVjaXNpb24sIGdvYWxJZDogc3RyaW5nKTogR2F0aGVyZWREYXRhRW50cnkge1xuICBjb25zdCB0aW1lc3RhbXAgPSBkZWNpc2lvbi50aW1lc3RhbXAgaW5zdGFuY2VvZiBEYXRlXG4gICAgPyBkZWNpc2lvbi50aW1lc3RhbXAudG9JU09TdHJpbmcoKVxuICAgIDogU3RyaW5nKGRlY2lzaW9uLnRpbWVzdGFtcCk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnZGVjaXNpb24nLFxuICAgIHRpbWVzdGFtcCxcbiAgICBzb3VyY2U6ICdBZ2VudC5yZWNvcmREZWNpc2lvbicsXG4gICAgZ29hbElkLFxuICAgIGNvbnRlbnQ6IHtcbiAgICAgIHN1bW1hcnk6IGRlY2lzaW9uLmRlY2lzaW9uLFxuICAgICAgZGV0YWlsczoge1xuICAgICAgICBjb25maWRlbmNlOiBkZWNpc2lvbi5jb25maWRlbmNlLFxuICAgICAgICBvdXRjb21lOiBkZWNpc2lvbi5vdXRjb21lLFxuICAgICAgICBmcmFtZXdvcms6IGRlY2lzaW9uLmZyYW1ld29yayxcbiAgICAgICAgcmlza0xldmVsOiBkZWNpc2lvbi5yaXNrQXNzZXNzbWVudD8ubGV2ZWwsXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRmluZGluZ0VudHJ5KGRlY2lzaW9uOiBBZ2VudERlY2lzaW9uLCBnb2FsSWQ6IHN0cmluZyk6IEdhdGhlcmVkRGF0YUVudHJ5IHtcbiAgY29uc3QgdGltZXN0YW1wID0gZGVjaXNpb24udGltZXN0YW1wIGluc3RhbmNlb2YgRGF0ZVxuICAgID8gZGVjaXNpb24udGltZXN0YW1wLnRvSVNPU3RyaW5nKClcbiAgICA6IFN0cmluZyhkZWNpc2lvbi50aW1lc3RhbXApO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2ZpbmRpbmcnLFxuICAgIHRpbWVzdGFtcCxcbiAgICBzb3VyY2U6ICdBZ2VudC5yZWNvcmREZWNpc2lvbicsXG4gICAgZ29hbElkLFxuICAgIGNvbnRlbnQ6IHtcbiAgICAgIHN1bW1hcnk6IGRlY2lzaW9uLnJlYXNvbmluZy5zdWJzdHJpbmcoMCwgMjAwKSxcbiAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgZnVsbFJlYXNvbmluZzogZGVjaXNpb24ucmVhc29uaW5nLFxuICAgICAgICBkZWNpc2lvbklkOiBkZWNpc2lvbi5pZCxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGRHb2FsQ29tcGxldGVkRW50cnkoZ29hbDogQWdlbnRHb2FsKTogR2F0aGVyZWREYXRhRW50cnkge1xuICBjb25zdCB0aW1lc3RhbXAgPSBnb2FsLmNvbXBsZXRlZEF0IGluc3RhbmNlb2YgRGF0ZVxuICAgID8gZ29hbC5jb21wbGV0ZWRBdC50b0lTT1N0cmluZygpXG4gICAgOiBnb2FsLmNvbXBsZXRlZEF0ID8gU3RyaW5nKGdvYWwuY29tcGxldGVkQXQpIDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2dvYWxfY29tcGxldGVkJyxcbiAgICB0aW1lc3RhbXAsXG4gICAgc291cmNlOiAnQWdlbnRNYW5hZ2VyLmNvbXBsZXRlQWdlbnRHb2FsJyxcbiAgICBnb2FsSWQ6IGdvYWwuaWQsXG4gICAgY29udGVudDoge1xuICAgICAgc3VtbWFyeTogYEdvYWwgY29tcGxldGVkOiAke2dvYWwuZGVzY3JpcHRpb24uc3Vic3RyaW5nKDAsIDEwMCl9YCxcbiAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgYWN0dWFsRWZmb3J0OiBnb2FsLmFjdHVhbEVmZm9ydCxcbiAgICAgICAgZXN0aW1hdGVkRWZmb3J0OiBnb2FsLmVzdGltYXRlZEVmZm9ydCxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGRHb2FsRmFpbGVkRW50cnkoZ29hbDogQWdlbnRHb2FsKTogR2F0aGVyZWREYXRhRW50cnkge1xuICBjb25zdCB0aW1lc3RhbXAgPSBnb2FsLmNvbXBsZXRlZEF0IGluc3RhbmNlb2YgRGF0ZVxuICAgID8gZ29hbC5jb21wbGV0ZWRBdC50b0lTT1N0cmluZygpXG4gICAgOiBnb2FsLmNvbXBsZXRlZEF0ID8gU3RyaW5nKGdvYWwuY29tcGxldGVkQXQpIDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2dvYWxfZmFpbGVkJyxcbiAgICB0aW1lc3RhbXAsXG4gICAgc291cmNlOiAnQWdlbnRNYW5hZ2VyLmNvbXBsZXRlQWdlbnRHb2FsJyxcbiAgICBnb2FsSWQ6IGdvYWwuaWQsXG4gICAgY29udGVudDoge1xuICAgICAgc3VtbWFyeTogYEdvYWwgZmFpbGVkOiAke2dvYWwuZGVzY3JpcHRpb24uc3Vic3RyaW5nKDAsIDEwMCl9YCxcbiAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgbm90ZXM6IGdvYWwubm90ZXMsXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBTdW1tYXJ5IFN0YXRpc3RpY3Ncbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmZ1bmN0aW9uIGNvbXB1dGVTdW1tYXJ5KFxuICBkZWNpc2lvbnM6IEFnZW50RGVjaXNpb25bXSxcbiAgZ29hbDogQWdlbnRHb2FsXG4pOiBHYXRoZXJlZERhdGFbJ3N1bW1hcnknXSB7XG4gIGNvbnN0IHN1Y2Nlc3NmdWxTdGVwcyA9IGRlY2lzaW9ucy5maWx0ZXIoZCA9PiBkLm91dGNvbWUgPT09ICdzdWNjZXNzJykubGVuZ3RoO1xuICBjb25zdCBmYWlsZWRTdGVwcyA9IGRlY2lzaW9ucy5maWx0ZXIoZCA9PiBkLm91dGNvbWUgPT09ICdmYWlsdXJlJykubGVuZ3RoO1xuICBjb25zdCBwYXJ0aWFsU3RlcHMgPSBkZWNpc2lvbnMuZmlsdGVyKGQgPT4gZC5vdXRjb21lID09PSAncGFydGlhbCcpLmxlbmd0aDtcblxuICBjb25zdCBjb25maWRlbmNlcyA9IGRlY2lzaW9ucy5tYXAoZCA9PiBkLmNvbmZpZGVuY2UpLmZpbHRlcihjID0+IHR5cGVvZiBjID09PSAnbnVtYmVyJyk7XG4gIGNvbnN0IGF2ZXJhZ2VDb25maWRlbmNlID0gY29uZmlkZW5jZXMubGVuZ3RoID4gMFxuICAgID8gY29uZmlkZW5jZXMucmVkdWNlKChzdW0sIGMpID0+IHN1bSArIGMsIDApIC8gY29uZmlkZW5jZXMubGVuZ3RoXG4gICAgOiAwO1xuXG4gIC8vIER1cmF0aW9uIGZyb20gZ29hbCBjcmVhdGlvbiB0byBsYXN0IGRlY2lzaW9uIG9yIGNvbXBsZXRpb25cbiAgY29uc3QgY3JlYXRlZEF0ID0gZ29hbC5jcmVhdGVkQXQgaW5zdGFuY2VvZiBEYXRlXG4gICAgPyBnb2FsLmNyZWF0ZWRBdC5nZXRUaW1lKClcbiAgICA6IG5ldyBEYXRlKFN0cmluZyhnb2FsLmNyZWF0ZWRBdCkpLmdldFRpbWUoKTtcblxuICBsZXQgZW5kVGltZTogbnVtYmVyO1xuICBpZiAoZ29hbC5jb21wbGV0ZWRBdCkge1xuICAgIGVuZFRpbWUgPSBnb2FsLmNvbXBsZXRlZEF0IGluc3RhbmNlb2YgRGF0ZVxuICAgICAgPyBnb2FsLmNvbXBsZXRlZEF0LmdldFRpbWUoKVxuICAgICAgOiBuZXcgRGF0ZShTdHJpbmcoZ29hbC5jb21wbGV0ZWRBdCkpLmdldFRpbWUoKTtcbiAgfSBlbHNlIGlmIChkZWNpc2lvbnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGxhc3REZWNpc2lvbiA9IGRlY2lzaW9uc1tkZWNpc2lvbnMubGVuZ3RoIC0gMV07XG4gICAgZW5kVGltZSA9IGxhc3REZWNpc2lvbi50aW1lc3RhbXAgaW5zdGFuY2VvZiBEYXRlXG4gICAgICA/IGxhc3REZWNpc2lvbi50aW1lc3RhbXAuZ2V0VGltZSgpXG4gICAgICA6IG5ldyBEYXRlKFN0cmluZyhsYXN0RGVjaXNpb24udGltZXN0YW1wKSkuZ2V0VGltZSgpO1xuICB9IGVsc2Uge1xuICAgIGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3RhbFN0ZXBzOiBkZWNpc2lvbnMubGVuZ3RoLFxuICAgIHN1Y2Nlc3NmdWxTdGVwcyxcbiAgICBmYWlsZWRTdGVwcyxcbiAgICBwYXJ0aWFsU3RlcHMsXG4gICAgYXZlcmFnZUNvbmZpZGVuY2U6IHBhcnNlRmxvYXQoYXZlcmFnZUNvbmZpZGVuY2UudG9GaXhlZCgzKSksXG4gICAgZHVyYXRpb25NczogTWF0aC5tYXgoMCwgZW5kVGltZSAtIGNyZWF0ZWRBdCksXG4gIH07XG59XG4iXX0=