@ruvector/ruvllm 0.2.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +379 -739
  2. package/bin/cli.js +619 -2
  3. package/dist/cjs/benchmarks/embedding-benchmark.d.ts +102 -0
  4. package/dist/cjs/benchmarks/embedding-benchmark.d.ts.map +1 -0
  5. package/dist/cjs/benchmarks/embedding-benchmark.js +436 -0
  6. package/dist/cjs/benchmarks/index.d.ts +34 -0
  7. package/dist/cjs/benchmarks/index.d.ts.map +1 -0
  8. package/dist/cjs/benchmarks/index.js +132 -0
  9. package/dist/cjs/benchmarks/model-comparison.d.ts +71 -0
  10. package/dist/cjs/benchmarks/model-comparison.d.ts.map +1 -0
  11. package/dist/cjs/benchmarks/model-comparison.js +476 -0
  12. package/dist/cjs/benchmarks/routing-benchmark.d.ts +70 -0
  13. package/dist/cjs/benchmarks/routing-benchmark.d.ts.map +1 -0
  14. package/dist/cjs/benchmarks/routing-benchmark.js +289 -0
  15. package/dist/cjs/contrastive.d.ts +229 -0
  16. package/dist/cjs/contrastive.d.ts.map +1 -0
  17. package/dist/cjs/contrastive.js +589 -0
  18. package/dist/cjs/engine.d.ts +3 -0
  19. package/dist/cjs/engine.d.ts.map +1 -1
  20. package/dist/cjs/engine.js +29 -9
  21. package/dist/cjs/index.d.ts +4 -0
  22. package/dist/cjs/index.d.ts.map +1 -1
  23. package/dist/cjs/index.js +9 -1
  24. package/dist/cjs/models.d.ts +129 -0
  25. package/dist/cjs/models.d.ts.map +1 -0
  26. package/dist/cjs/models.js +323 -0
  27. package/dist/cjs/rlm/controller.d.ts +245 -0
  28. package/dist/cjs/rlm/controller.d.ts.map +1 -0
  29. package/dist/cjs/rlm/controller.js +554 -0
  30. package/dist/cjs/rlm/index.d.ts +62 -0
  31. package/dist/cjs/rlm/index.d.ts.map +1 -0
  32. package/dist/cjs/rlm/index.js +97 -0
  33. package/dist/cjs/rlm/training.d.ts +333 -0
  34. package/dist/cjs/rlm/training.d.ts.map +1 -0
  35. package/dist/cjs/rlm/training.js +680 -0
  36. package/dist/cjs/rlm/types.d.ts +189 -0
  37. package/dist/cjs/rlm/types.d.ts.map +1 -0
  38. package/dist/cjs/rlm/types.js +10 -0
  39. package/dist/esm/benchmarks/embedding-benchmark.d.ts +102 -0
  40. package/dist/esm/benchmarks/embedding-benchmark.d.ts.map +1 -0
  41. package/dist/esm/benchmarks/embedding-benchmark.js +427 -0
  42. package/dist/esm/benchmarks/index.d.ts +34 -0
  43. package/dist/esm/benchmarks/index.d.ts.map +1 -0
  44. package/dist/esm/benchmarks/index.js +110 -0
  45. package/dist/esm/benchmarks/model-comparison.d.ts +71 -0
  46. package/dist/esm/benchmarks/model-comparison.d.ts.map +1 -0
  47. package/dist/esm/benchmarks/model-comparison.js +434 -0
  48. package/dist/esm/benchmarks/routing-benchmark.d.ts +70 -0
  49. package/dist/esm/benchmarks/routing-benchmark.d.ts.map +1 -0
  50. package/dist/esm/benchmarks/routing-benchmark.js +283 -0
  51. package/dist/esm/contrastive.d.ts +229 -0
  52. package/dist/esm/contrastive.d.ts.map +1 -0
  53. package/dist/esm/contrastive.js +578 -0
  54. package/dist/esm/engine.d.ts +3 -0
  55. package/dist/esm/engine.d.ts.map +1 -1
  56. package/dist/esm/engine.js +29 -9
  57. package/dist/esm/index.d.ts +4 -0
  58. package/dist/esm/index.d.ts.map +1 -1
  59. package/dist/esm/index.js +9 -1
  60. package/dist/esm/models.d.ts +129 -0
  61. package/dist/esm/models.d.ts.map +1 -0
  62. package/dist/esm/models.js +282 -0
  63. package/dist/esm/rlm/controller.d.ts +245 -0
  64. package/dist/esm/rlm/controller.d.ts.map +1 -0
  65. package/dist/esm/rlm/controller.js +550 -0
  66. package/dist/esm/rlm/index.d.ts +62 -0
  67. package/dist/esm/rlm/index.d.ts.map +1 -0
  68. package/dist/esm/rlm/index.js +71 -0
  69. package/dist/esm/rlm/training.d.ts +333 -0
  70. package/dist/esm/rlm/training.d.ts.map +1 -0
  71. package/dist/esm/rlm/training.js +672 -0
  72. package/dist/esm/rlm/types.d.ts +189 -0
  73. package/dist/esm/rlm/types.d.ts.map +1 -0
  74. package/dist/esm/rlm/types.js +9 -0
  75. package/package.json +13 -11
  76. package/scripts/ensemble-model-compare.js +287 -0
  77. package/scripts/huggingface/README.md +537 -0
  78. package/scripts/huggingface/publish.sh +112 -0
  79. package/scripts/hybrid-model-compare.js +373 -0
  80. package/scripts/improved-model-compare.js +288 -0
  81. package/scripts/optimized-model-compare.js +364 -0
  82. package/scripts/real-model-compare.js +280 -0
  83. package/scripts/training/agentic-flow-capabilities.json +329 -0
  84. package/scripts/training/claude-code-synth.js +505 -0
  85. package/scripts/training/claude-flow-capabilities.json +1322 -0
  86. package/scripts/training/claude-hard-negatives.js +222 -0
  87. package/scripts/training/contrastive-finetune.js +517 -0
  88. package/scripts/training/ecosystem-triplets.jsonl +1467 -0
  89. package/scripts/training/generate-ecosystem-triplets.js +1324 -0
  90. package/scripts/training/rlm-dataset.js +671 -0
  91. package/scripts/training/routing-dataset.js +634 -0
  92. package/scripts/training/ruvector-capabilities.json +798 -0
  93. package/scripts/training/validate-ecosystem.js +381 -0
  94. package/scripts/training/validation-results.json +23 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Routing Benchmark for RuvLTRA Models
3
+ *
4
+ * Tests whether the model correctly routes tasks to appropriate agents.
5
+ * This measures the actual value proposition for Claude Code workflows.
6
+ */
7
+ /**
8
+ * Agent types in Claude Code / claude-flow ecosystem
9
+ */
10
+ export const AGENT_TYPES = [
11
+ 'coder',
12
+ 'researcher',
13
+ 'reviewer',
14
+ 'tester',
15
+ 'architect',
16
+ 'security-architect',
17
+ 'debugger',
18
+ 'documenter',
19
+ 'refactorer',
20
+ 'optimizer',
21
+ 'devops',
22
+ 'api-docs',
23
+ 'planner',
24
+ ];
25
+ /**
26
+ * Ground truth test dataset for routing
27
+ * 100 tasks with expected agent assignments
28
+ */
29
+ export const ROUTING_TEST_CASES = [
30
+ // === CODER tasks (write new code) ===
31
+ { id: 'C001', task: 'Implement a binary search function in TypeScript', expectedAgent: 'coder', category: 'implementation', difficulty: 'easy' },
32
+ { id: 'C002', task: 'Write a React component for user authentication', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
33
+ { id: 'C003', task: 'Create a REST API endpoint for user registration', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
34
+ { id: 'C004', task: 'Implement a WebSocket server for real-time chat', expectedAgent: 'coder', category: 'implementation', difficulty: 'hard' },
35
+ { id: 'C005', task: 'Write a function to parse CSV files', expectedAgent: 'coder', category: 'implementation', difficulty: 'easy' },
36
+ { id: 'C006', task: 'Create a middleware for request logging', expectedAgent: 'coder', category: 'implementation', difficulty: 'easy' },
37
+ { id: 'C007', task: 'Implement pagination for the API responses', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
38
+ { id: 'C008', task: 'Write a custom React hook for form validation', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
39
+ { id: 'C009', task: 'Create a database migration script', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
40
+ { id: 'C010', task: 'Implement a rate limiter for the API', expectedAgent: 'coder', category: 'implementation', difficulty: 'medium' },
41
+ // === RESEARCHER tasks (investigate, explore) ===
42
+ { id: 'R001', task: 'Research best practices for GraphQL schema design', expectedAgent: 'researcher', category: 'research', difficulty: 'medium' },
43
+ { id: 'R002', task: 'Find out how the authentication flow works in this codebase', expectedAgent: 'researcher', category: 'research', difficulty: 'easy' },
44
+ { id: 'R003', task: 'Investigate why the build is failing on CI', expectedAgent: 'researcher', category: 'research', difficulty: 'medium' },
45
+ { id: 'R004', task: 'Research alternatives to Redux for state management', expectedAgent: 'researcher', category: 'research', difficulty: 'medium' },
46
+ { id: 'R005', task: 'Find all usages of the deprecated API in the codebase', expectedAgent: 'researcher', category: 'research', difficulty: 'easy' },
47
+ { id: 'R006', task: 'Analyze the performance characteristics of our database queries', expectedAgent: 'researcher', category: 'research', difficulty: 'hard' },
48
+ { id: 'R007', task: 'Research GDPR compliance requirements for user data', expectedAgent: 'researcher', category: 'research', difficulty: 'medium' },
49
+ { id: 'R008', task: 'Find examples of similar implementations in open source', expectedAgent: 'researcher', category: 'research', difficulty: 'easy' },
50
+ // === REVIEWER tasks (code review, quality) ===
51
+ { id: 'V001', task: 'Review this pull request for code quality', expectedAgent: 'reviewer', category: 'review', difficulty: 'medium' },
52
+ { id: 'V002', task: 'Check if this code follows our style guidelines', expectedAgent: 'reviewer', category: 'review', difficulty: 'easy' },
53
+ { id: 'V003', task: 'Review the API design for consistency', expectedAgent: 'reviewer', category: 'review', difficulty: 'medium' },
54
+ { id: 'V004', task: 'Evaluate the error handling in this module', expectedAgent: 'reviewer', category: 'review', difficulty: 'medium' },
55
+ { id: 'V005', task: 'Review the database schema changes', expectedAgent: 'reviewer', category: 'review', difficulty: 'hard' },
56
+ { id: 'V006', task: 'Check for potential memory leaks in this code', expectedAgent: 'reviewer', category: 'review', difficulty: 'hard' },
57
+ { id: 'V007', task: 'Review the accessibility of the UI components', expectedAgent: 'reviewer', category: 'review', difficulty: 'medium' },
58
+ // === TESTER tasks (write tests, QA) ===
59
+ { id: 'T001', task: 'Write unit tests for the user service', expectedAgent: 'tester', category: 'testing', difficulty: 'medium' },
60
+ { id: 'T002', task: 'Create integration tests for the checkout flow', expectedAgent: 'tester', category: 'testing', difficulty: 'hard' },
61
+ { id: 'T003', task: 'Add test coverage for edge cases in the parser', expectedAgent: 'tester', category: 'testing', difficulty: 'medium' },
62
+ { id: 'T004', task: 'Write E2E tests for the login page', expectedAgent: 'tester', category: 'testing', difficulty: 'medium' },
63
+ { id: 'T005', task: 'Create performance tests for the API', expectedAgent: 'tester', category: 'testing', difficulty: 'hard' },
64
+ { id: 'T006', task: 'Add snapshot tests for React components', expectedAgent: 'tester', category: 'testing', difficulty: 'easy' },
65
+ { id: 'T007', task: 'Write tests for the authentication middleware', expectedAgent: 'tester', category: 'testing', difficulty: 'medium' },
66
+ { id: 'T008', task: 'Create mock data for testing', expectedAgent: 'tester', category: 'testing', difficulty: 'easy' },
67
+ // === ARCHITECT tasks (design, system) ===
68
+ { id: 'A001', task: 'Design the microservices architecture for the platform', expectedAgent: 'architect', category: 'architecture', difficulty: 'hard' },
69
+ { id: 'A002', task: 'Create a system design for the notification service', expectedAgent: 'architect', category: 'architecture', difficulty: 'hard' },
70
+ { id: 'A003', task: 'Plan the database schema for the new feature', expectedAgent: 'architect', category: 'architecture', difficulty: 'medium' },
71
+ { id: 'A004', task: 'Design the API contract for the mobile app', expectedAgent: 'architect', category: 'architecture', difficulty: 'medium' },
72
+ { id: 'A005', task: 'Create an ADR for the caching strategy', expectedAgent: 'architect', category: 'architecture', difficulty: 'medium' },
73
+ { id: 'A006', task: 'Design the event-driven architecture for order processing', expectedAgent: 'architect', category: 'architecture', difficulty: 'hard' },
74
+ { id: 'A007', task: 'Plan the migration strategy from monolith to microservices', expectedAgent: 'architect', category: 'architecture', difficulty: 'hard' },
75
+ // === SECURITY tasks ===
76
+ { id: 'S001', task: 'Audit the authentication implementation for vulnerabilities', expectedAgent: 'security-architect', category: 'security', difficulty: 'hard' },
77
+ { id: 'S002', task: 'Review the code for SQL injection vulnerabilities', expectedAgent: 'security-architect', category: 'security', difficulty: 'medium' },
78
+ { id: 'S003', task: 'Check for XSS vulnerabilities in the frontend', expectedAgent: 'security-architect', category: 'security', difficulty: 'medium' },
79
+ { id: 'S004', task: 'Implement secure password hashing', expectedAgent: 'security-architect', category: 'security', difficulty: 'medium' },
80
+ { id: 'S005', task: 'Review the API for authorization bypass issues', expectedAgent: 'security-architect', category: 'security', difficulty: 'hard' },
81
+ { id: 'S006', task: 'Audit third-party dependencies for known CVEs', expectedAgent: 'security-architect', category: 'security', difficulty: 'medium' },
82
+ { id: 'S007', task: 'Design the secrets management strategy', expectedAgent: 'security-architect', category: 'security', difficulty: 'hard' },
83
+ // === DEBUGGER tasks ===
84
+ { id: 'D001', task: 'Fix the null pointer exception in the user controller', expectedAgent: 'debugger', category: 'debugging', difficulty: 'easy' },
85
+ { id: 'D002', task: 'Debug why the API returns 500 intermittently', expectedAgent: 'debugger', category: 'debugging', difficulty: 'hard' },
86
+ { id: 'D003', task: 'Find the cause of the memory leak', expectedAgent: 'debugger', category: 'debugging', difficulty: 'hard' },
87
+ { id: 'D004', task: 'Fix the race condition in the checkout process', expectedAgent: 'debugger', category: 'debugging', difficulty: 'hard' },
88
+ { id: 'D005', task: 'Debug the failing test in CI', expectedAgent: 'debugger', category: 'debugging', difficulty: 'medium' },
89
+ { id: 'D006', task: 'Fix the timezone issue in date handling', expectedAgent: 'debugger', category: 'debugging', difficulty: 'medium' },
90
+ { id: 'D007', task: 'Resolve the circular dependency error', expectedAgent: 'debugger', category: 'debugging', difficulty: 'medium' },
91
+ { id: 'D008', task: 'Fix the broken build after the merge', expectedAgent: 'debugger', category: 'debugging', difficulty: 'easy' },
92
+ // === DOCUMENTER tasks ===
93
+ { id: 'O001', task: 'Write documentation for the API endpoints', expectedAgent: 'documenter', category: 'documentation', difficulty: 'medium' },
94
+ { id: 'O002', task: 'Create a README for the new package', expectedAgent: 'documenter', category: 'documentation', difficulty: 'easy' },
95
+ { id: 'O003', task: 'Document the deployment process', expectedAgent: 'documenter', category: 'documentation', difficulty: 'medium' },
96
+ { id: 'O004', task: 'Write JSDoc comments for the utility functions', expectedAgent: 'documenter', category: 'documentation', difficulty: 'easy' },
97
+ { id: 'O005', task: 'Create a migration guide for v2 to v3', expectedAgent: 'documenter', category: 'documentation', difficulty: 'medium' },
98
+ { id: 'O006', task: 'Document the architecture decisions', expectedAgent: 'documenter', category: 'documentation', difficulty: 'medium' },
99
+ // === REFACTORER tasks ===
100
+ { id: 'F001', task: 'Refactor the user service to use dependency injection', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'medium' },
101
+ { id: 'F002', task: 'Extract common logic into a shared utility', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'easy' },
102
+ { id: 'F003', task: 'Split the large component into smaller ones', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'medium' },
103
+ { id: 'F004', task: 'Rename the ambiguous variable names in this module', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'easy' },
104
+ { id: 'F005', task: 'Convert the callbacks to async/await', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'medium' },
105
+ { id: 'F006', task: 'Remove dead code from the legacy module', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'easy' },
106
+ { id: 'F007', task: 'Consolidate duplicate API handlers', expectedAgent: 'refactorer', category: 'refactoring', difficulty: 'medium' },
107
+ // === OPTIMIZER tasks ===
108
+ { id: 'P001', task: 'Optimize the slow database query', expectedAgent: 'optimizer', category: 'performance', difficulty: 'hard' },
109
+ { id: 'P002', task: 'Reduce the bundle size of the frontend', expectedAgent: 'optimizer', category: 'performance', difficulty: 'medium' },
110
+ { id: 'P003', task: 'Improve the API response time', expectedAgent: 'optimizer', category: 'performance', difficulty: 'hard' },
111
+ { id: 'P004', task: 'Add caching to reduce database load', expectedAgent: 'optimizer', category: 'performance', difficulty: 'medium' },
112
+ { id: 'P005', task: 'Optimize the image loading performance', expectedAgent: 'optimizer', category: 'performance', difficulty: 'medium' },
113
+ { id: 'P006', task: 'Profile and optimize memory usage', expectedAgent: 'optimizer', category: 'performance', difficulty: 'hard' },
114
+ { id: 'P007', task: 'Implement lazy loading for the dashboard', expectedAgent: 'optimizer', category: 'performance', difficulty: 'medium' },
115
+ // === DEVOPS tasks ===
116
+ { id: 'E001', task: 'Set up the CI/CD pipeline for the new service', expectedAgent: 'devops', category: 'devops', difficulty: 'medium' },
117
+ { id: 'E002', task: 'Configure Kubernetes deployment for production', expectedAgent: 'devops', category: 'devops', difficulty: 'hard' },
118
+ { id: 'E003', task: 'Set up monitoring and alerting', expectedAgent: 'devops', category: 'devops', difficulty: 'medium' },
119
+ { id: 'E004', task: 'Create Docker containers for the microservices', expectedAgent: 'devops', category: 'devops', difficulty: 'medium' },
120
+ { id: 'E005', task: 'Configure auto-scaling for the API servers', expectedAgent: 'devops', category: 'devops', difficulty: 'hard' },
121
+ { id: 'E006', task: 'Set up the staging environment', expectedAgent: 'devops', category: 'devops', difficulty: 'medium' },
122
+ { id: 'E007', task: 'Implement blue-green deployment strategy', expectedAgent: 'devops', category: 'devops', difficulty: 'hard' },
123
+ // === API-DOCS tasks ===
124
+ { id: 'I001', task: 'Generate OpenAPI spec for the REST API', expectedAgent: 'api-docs', category: 'api-documentation', difficulty: 'medium' },
125
+ { id: 'I002', task: 'Create Swagger documentation for the endpoints', expectedAgent: 'api-docs', category: 'api-documentation', difficulty: 'medium' },
126
+ { id: 'I003', task: 'Document the GraphQL schema', expectedAgent: 'api-docs', category: 'api-documentation', difficulty: 'medium' },
127
+ { id: 'I004', task: 'Add example requests and responses to API docs', expectedAgent: 'api-docs', category: 'api-documentation', difficulty: 'easy' },
128
+ // === PLANNER tasks ===
129
+ { id: 'L001', task: 'Break down the feature into implementation tasks', expectedAgent: 'planner', category: 'planning', difficulty: 'medium' },
130
+ { id: 'L002', task: 'Create a sprint plan for the next milestone', expectedAgent: 'planner', category: 'planning', difficulty: 'medium' },
131
+ { id: 'L003', task: 'Estimate effort for the refactoring project', expectedAgent: 'planner', category: 'planning', difficulty: 'medium' },
132
+ { id: 'L004', task: 'Prioritize the bug fixes for the release', expectedAgent: 'planner', category: 'planning', difficulty: 'easy' },
133
+ { id: 'L005', task: 'Plan the technical debt reduction roadmap', expectedAgent: 'planner', category: 'planning', difficulty: 'hard' },
134
+ // === AMBIGUOUS / EDGE CASES ===
135
+ { id: 'X001', task: 'The login is broken, users cannot sign in', expectedAgent: 'debugger', category: 'ambiguous', difficulty: 'medium' },
136
+ { id: 'X002', task: 'We need better error messages', expectedAgent: 'coder', category: 'ambiguous', difficulty: 'easy' },
137
+ { id: 'X003', task: 'Make the app faster', expectedAgent: 'optimizer', category: 'ambiguous', difficulty: 'hard' },
138
+ { id: 'X004', task: 'The code is a mess, clean it up', expectedAgent: 'refactorer', category: 'ambiguous', difficulty: 'medium' },
139
+ { id: 'X005', task: 'Is this implementation secure?', expectedAgent: 'security-architect', category: 'ambiguous', difficulty: 'medium' },
140
+ ];
141
+ /**
142
+ * Simple keyword-based routing for baseline comparison
143
+ */
144
+ export function baselineKeywordRouter(task) {
145
+ const taskLower = task.toLowerCase();
146
+ const patterns = [
147
+ { keywords: ['implement', 'create', 'write', 'add', 'build'], agent: 'coder', weight: 1 },
148
+ { keywords: ['research', 'find', 'investigate', 'analyze', 'explore'], agent: 'researcher', weight: 1 },
149
+ { keywords: ['review', 'check', 'evaluate', 'assess'], agent: 'reviewer', weight: 1 },
150
+ { keywords: ['test', 'unit test', 'integration test', 'e2e', 'coverage'], agent: 'tester', weight: 1.2 },
151
+ { keywords: ['design', 'architect', 'schema', 'adr', 'system design'], agent: 'architect', weight: 1.2 },
152
+ { keywords: ['security', 'vulnerability', 'xss', 'sql injection', 'audit', 'cve'], agent: 'security-architect', weight: 1.5 },
153
+ { keywords: ['debug', 'fix', 'bug', 'error', 'broken', 'issue'], agent: 'debugger', weight: 1.2 },
154
+ { keywords: ['document', 'readme', 'jsdoc', 'comment'], agent: 'documenter', weight: 1 },
155
+ { keywords: ['refactor', 'extract', 'rename', 'consolidate', 'split'], agent: 'refactorer', weight: 1.2 },
156
+ { keywords: ['optimize', 'performance', 'slow', 'cache', 'faster'], agent: 'optimizer', weight: 1.2 },
157
+ { keywords: ['deploy', 'ci/cd', 'kubernetes', 'docker', 'pipeline'], agent: 'devops', weight: 1.2 },
158
+ { keywords: ['openapi', 'swagger', 'api doc', 'graphql schema'], agent: 'api-docs', weight: 1.3 },
159
+ { keywords: ['plan', 'estimate', 'prioritize', 'sprint', 'roadmap'], agent: 'planner', weight: 1 },
160
+ ];
161
+ let bestMatch = { agent: 'coder', score: 0 };
162
+ for (const pattern of patterns) {
163
+ let score = 0;
164
+ for (const keyword of pattern.keywords) {
165
+ if (taskLower.includes(keyword)) {
166
+ score += pattern.weight;
167
+ }
168
+ }
169
+ if (score > bestMatch.score) {
170
+ bestMatch = { agent: pattern.agent, score };
171
+ }
172
+ }
173
+ return {
174
+ agent: bestMatch.agent,
175
+ confidence: Math.min(bestMatch.score / 3, 1), // Normalize to 0-1
176
+ };
177
+ }
178
+ /**
179
+ * Run the routing benchmark
180
+ */
181
+ export function runRoutingBenchmark(router) {
182
+ const results = [];
183
+ const latencies = [];
184
+ for (const testCase of ROUTING_TEST_CASES) {
185
+ const start = performance.now();
186
+ const prediction = router(testCase.task);
187
+ const latencyMs = performance.now() - start;
188
+ latencies.push(latencyMs);
189
+ results.push({
190
+ testId: testCase.id,
191
+ task: testCase.task,
192
+ expectedAgent: testCase.expectedAgent,
193
+ predictedAgent: prediction.agent,
194
+ confidence: prediction.confidence,
195
+ correct: prediction.agent === testCase.expectedAgent,
196
+ latencyMs,
197
+ });
198
+ }
199
+ // Calculate metrics
200
+ const correct = results.filter(r => r.correct).length;
201
+ const accuracy = correct / results.length;
202
+ // Accuracy by category
203
+ const categories = [...new Set(ROUTING_TEST_CASES.map(t => t.category))];
204
+ const accuracyByCategory = {};
205
+ for (const cat of categories) {
206
+ const catResults = results.filter((r, i) => ROUTING_TEST_CASES[i].category === cat);
207
+ accuracyByCategory[cat] = catResults.filter(r => r.correct).length / catResults.length;
208
+ }
209
+ // Accuracy by difficulty
210
+ const difficulties = ['easy', 'medium', 'hard'];
211
+ const accuracyByDifficulty = {};
212
+ for (const diff of difficulties) {
213
+ const diffResults = results.filter((r, i) => ROUTING_TEST_CASES[i].difficulty === diff);
214
+ accuracyByDifficulty[diff] = diffResults.filter(r => r.correct).length / diffResults.length;
215
+ }
216
+ // Latency percentiles
217
+ const sortedLatencies = [...latencies].sort((a, b) => a - b);
218
+ const p50 = sortedLatencies[Math.floor(sortedLatencies.length * 0.5)];
219
+ const p95 = sortedLatencies[Math.floor(sortedLatencies.length * 0.95)];
220
+ const avgLatency = latencies.reduce((a, b) => a + b, 0) / latencies.length;
221
+ return {
222
+ accuracy,
223
+ accuracyByCategory,
224
+ accuracyByDifficulty,
225
+ avgLatencyMs: avgLatency,
226
+ p50LatencyMs: p50,
227
+ p95LatencyMs: p95,
228
+ totalTests: results.length,
229
+ correct,
230
+ results,
231
+ };
232
+ }
233
+ /**
234
+ * Format benchmark results for display
235
+ */
236
+ export function formatRoutingResults(results) {
237
+ const lines = [];
238
+ lines.push('');
239
+ lines.push('╔══════════════════════════════════════════════════════════════╗');
240
+ lines.push('║ ROUTING BENCHMARK RESULTS ║');
241
+ lines.push('╠══════════════════════════════════════════════════════════════╣');
242
+ lines.push(`║ Overall Accuracy: ${(results.accuracy * 100).toFixed(1)}% (${results.correct}/${results.totalTests})`.padEnd(63) + '║');
243
+ lines.push('╠══════════════════════════════════════════════════════════════╣');
244
+ lines.push('║ By Category: ║');
245
+ for (const [cat, acc] of Object.entries(results.accuracyByCategory).sort((a, b) => b[1] - a[1])) {
246
+ const bar = '█'.repeat(Math.floor(acc * 20)) + '░'.repeat(20 - Math.floor(acc * 20));
247
+ lines.push(`║ ${cat.padEnd(18)} [${bar}] ${(acc * 100).toFixed(0).padStart(3)}% ║`);
248
+ }
249
+ lines.push('╠══════════════════════════════════════════════════════════════╣');
250
+ lines.push('║ By Difficulty: ║');
251
+ for (const [diff, acc] of Object.entries(results.accuracyByDifficulty)) {
252
+ const bar = '█'.repeat(Math.floor(acc * 20)) + '░'.repeat(20 - Math.floor(acc * 20));
253
+ lines.push(`║ ${diff.padEnd(18)} [${bar}] ${(acc * 100).toFixed(0).padStart(3)}% ║`);
254
+ }
255
+ lines.push('╠══════════════════════════════════════════════════════════════╣');
256
+ lines.push('║ Latency: ║');
257
+ lines.push(`║ Average: ${results.avgLatencyMs.toFixed(2)}ms`.padEnd(63) + '║');
258
+ lines.push(`║ P50: ${results.p50LatencyMs.toFixed(2)}ms`.padEnd(63) + '║');
259
+ lines.push(`║ P95: ${results.p95LatencyMs.toFixed(2)}ms`.padEnd(63) + '║');
260
+ lines.push('╚══════════════════════════════════════════════════════════════╝');
261
+ // Show failures
262
+ const failures = results.results.filter(r => !r.correct);
263
+ if (failures.length > 0 && failures.length <= 20) {
264
+ lines.push('');
265
+ lines.push('Misrouted tasks:');
266
+ for (const f of failures.slice(0, 10)) {
267
+ lines.push(` [${f.testId}] "${f.task.slice(0, 50)}..."`);
268
+ lines.push(` Expected: ${f.expectedAgent}, Got: ${f.predictedAgent}`);
269
+ }
270
+ if (failures.length > 10) {
271
+ lines.push(` ... and ${failures.length - 10} more`);
272
+ }
273
+ }
274
+ return lines.join('\n');
275
+ }
276
+ export default {
277
+ ROUTING_TEST_CASES,
278
+ AGENT_TYPES,
279
+ baselineKeywordRouter,
280
+ runRoutingBenchmark,
281
+ formatRoutingResults,
282
+ };
283
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZy1iZW5jaG1hcmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmVuY2htYXJrcy9yb3V0aW5nLWJlbmNobWFyay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQWdDSDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRztJQUN6QixPQUFPO0lBQ1AsWUFBWTtJQUNaLFVBQVU7SUFDVixRQUFRO0lBQ1IsV0FBVztJQUNYLG9CQUFvQjtJQUNwQixVQUFVO0lBQ1YsWUFBWTtJQUNaLFlBQVk7SUFDWixXQUFXO0lBQ1gsUUFBUTtJQUNSLFVBQVU7SUFDVixTQUFTO0NBQ0QsQ0FBQztBQUlYOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFzQjtJQUNuRCx1Q0FBdUM7SUFDdkMsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxrREFBa0QsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFO0lBQ2hKLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsaURBQWlELEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRTtJQUNqSixFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGtEQUFrRCxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUU7SUFDbEosRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxpREFBaUQsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFO0lBQy9JLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUs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bEIsV0FBVztJQUNYLHFCQUFxQjtJQUNyQixtQkFBbUI7SUFDbkIsb0JBQW9CO0NBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJvdXRpbmcgQmVuY2htYXJrIGZvciBSdXZMVFJBIE1vZGVsc1xuICpcbiAqIFRlc3RzIHdoZXRoZXIgdGhlIG1vZGVsIGNvcnJlY3RseSByb3V0ZXMgdGFza3MgdG8gYXBwcm9wcmlhdGUgYWdlbnRzLlxuICogVGhpcyBtZWFzdXJlcyB0aGUgYWN0dWFsIHZhbHVlIHByb3Bvc2l0aW9uIGZvciBDbGF1ZGUgQ29kZSB3b3JrZmxvd3MuXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0aW5nVGVzdENhc2Uge1xuICBpZDogc3RyaW5nO1xuICB0YXNrOiBzdHJpbmc7XG4gIGV4cGVjdGVkQWdlbnQ6IHN0cmluZztcbiAgY2F0ZWdvcnk6IHN0cmluZztcbiAgZGlmZmljdWx0eTogJ2Vhc3knIHwgJ21lZGl1bScgfCAnaGFyZCc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGluZ1Jlc3VsdCB7XG4gIHRlc3RJZDogc3RyaW5nO1xuICB0YXNrOiBzdHJpbmc7XG4gIGV4cGVjdGVkQWdlbnQ6IHN0cmluZztcbiAgcHJlZGljdGVkQWdlbnQ6IHN0cmluZztcbiAgY29uZmlkZW5jZTogbnVtYmVyO1xuICBjb3JyZWN0OiBib29sZWFuO1xuICBsYXRlbmN5TXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSb3V0aW5nQmVuY2htYXJrUmVzdWx0cyB7XG4gIGFjY3VyYWN5OiBudW1iZXI7XG4gIGFjY3VyYWN5QnlDYXRlZ29yeTogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgYWNjdXJhY3lCeURpZmZpY3VsdHk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG4gIGF2Z0xhdGVuY3lNczogbnVtYmVyO1xuICBwNTBMYXRlbmN5TXM6IG51bWJlcjtcbiAgcDk1TGF0ZW5jeU1zOiBudW1iZXI7XG4gIHRvdGFsVGVzdHM6IG51bWJlcjtcbiAgY29ycmVjdDogbnVtYmVyO1xuICByZXN1bHRzOiBSb3V0aW5nUmVzdWx0W107XG59XG5cbi8qKlxuICogQWdlbnQgdHlwZXMgaW4gQ2xhdWRlIENvZGUgLyBjbGF1ZGUtZmxvdyBlY29zeXN0ZW1cbiAqL1xuZXhwb3J0IGNvbnN0IEFHRU5UX1RZUEVTID0gW1xuICAnY29kZXInLFxuICAncmVzZWFyY2hlcicsXG4gICdyZXZpZXdlcicsXG4gICd0ZXN0ZXInLFxuICAnYXJjaGl0ZWN0JyxcbiAgJ3NlY3VyaXR5LWFyY2hpdGVjdCcsXG4gICdkZWJ1Z2dlcicsXG4gICdkb2N1bWVudGVyJyxcbiAgJ3JlZmFjdG9yZXInLFxuICAnb3B0aW1pemVyJyxcbiAgJ2Rldm9wcycsXG4gICdhcGktZG9jcycsXG4gICdwbGFubmVyJyxcbl0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIEFnZW50VHlwZSA9ICh0eXBlb2YgQUdFTlRfVFlQRVMpW251bWJlcl07XG5cbi8qKlxuICogR3JvdW5kIHRydXRoIHRlc3QgZGF0YXNldCBmb3Igcm91dGluZ1xuICogMTAwIHRhc2tzIHdpdGggZXhwZWN0ZWQgYWdlbnQgYXNzaWdubWVudHNcbiAqL1xuZXhwb3J0IGNvbnN0IFJPVVRJTkdfVEVTVF9DQVNFUzogUm91dGluZ1Rlc3RDYXNlW10gPSBbXG4gIC8vID09PSBDT0RFUiB0YXNrcyAod3JpdGUgbmV3IGNvZGUpID09PVxuICB7IGlkOiAnQzAwMScsIHRhc2s6ICdJbXBsZW1lbnQgYSBiaW5hcnkgc2VhcmNoIGZ1bmN0aW9uIGluIFR5cGVTY3JpcHQnLCBleHBlY3RlZEFnZW50OiAnY29kZXInLCBjYXRlZ29yeTogJ2ltcGxlbWVudGF0aW9uJywgZGlmZmljdWx0eTogJ2Vhc3knIH0sXG4gIHsgaWQ6ICdDMDAyJywgdGFzazogJ1dyaXRlIGEgUmVhY3QgY29tcG9uZW50IGZvciB1c2VyIGF1dGhlbnRpY2F0aW9uJywgZXhwZWN0ZWRBZ2VudDogJ2NvZGVyJywgY2F0ZWdvcnk6ICdpbXBsZW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdDMDAzJywgdGFzazogJ0NyZWF0ZSBhIFJFU1QgQVBJIGVuZHBvaW50IGZvciB1c2VyIHJlZ2lzdHJhdGlvbicsIGV4cGVjdGVkQWdlbnQ6ICdjb2RlcicsIGNhdGVnb3J5OiAnaW1wbGVtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnQzAwNCcsIHRhc2s6ICdJbXBsZW1lbnQgYSBXZWJTb2NrZXQgc2VydmVyIGZvciByZWFsLXRpbWUgY2hhdCcsIGV4cGVjdGVkQWdlbnQ6ICdjb2RlcicsIGNhdGVnb3J5OiAnaW1wbGVtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcbiAgeyBpZDogJ0MwMDUnLCB0YXNrOiAnV3JpdGUgYSBmdW5jdGlvbiB0byBwYXJzZSBDU1YgZmlsZXMnLCBleHBlY3RlZEFnZW50OiAnY29kZXInLCBjYXRlZ29yeTogJ2ltcGxlbWVudGF0aW9uJywgZGlmZmljdWx0eTogJ2Vhc3knIH0sXG4gIHsgaWQ6ICdDMDA2JywgdGFzazogJ0NyZWF0ZSBhIG1pZGRsZXdhcmUgZm9yIHJlcXVlc3QgbG9nZ2luZycsIGV4cGVjdGVkQWdlbnQ6ICdjb2RlcicsIGNhdGVnb3J5OiAnaW1wbGVtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnZWFzeScgfSxcbiAgeyBpZDogJ0MwMDcnLCB0YXNrOiAnSW1wbGVtZW50IHBhZ2luYXRpb24gZm9yIHRoZSBBUEkgcmVzcG9uc2VzJywgZXhwZWN0ZWRBZ2VudDogJ2NvZGVyJywgY2F0ZWdvcnk6ICdpbXBsZW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdDMDA4JywgdGFzazogJ1dyaXRlIGEgY3VzdG9tIFJlYWN0IGhvb2sgZm9yIGZvcm0gdmFsaWRhdGlvbicsIGV4cGVjdGVkQWdlbnQ6ICdjb2RlcicsIGNhdGVnb3J5OiAnaW1wbGVtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnQzAwOScsIHRhc2s6ICdDcmVhdGUgYSBkYXRhYmFzZSBtaWdyYXRpb24gc2NyaXB0JywgZXhwZWN0ZWRBZ2VudDogJ2NvZGVyJywgY2F0ZWdvcnk6ICdpbXBsZW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdDMDEwJywgdGFzazogJ0ltcGxlbWVudCBhIHJhdGUgbGltaXRlciBmb3IgdGhlIEFQSScsIGV4cGVjdGVkQWdlbnQ6ICdjb2RlcicsIGNhdGVnb3J5OiAnaW1wbGVtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuXG4gIC8vID09PSBSRVNFQVJDSEVSIHRhc2tzIChpbnZlc3RpZ2F0ZSwgZXhwbG9yZSkgPT09XG4gIHsgaWQ6ICdSMDAxJywgdGFzazogJ1Jlc2VhcmNoIGJlc3QgcHJhY3RpY2VzIGZvciBHcmFwaFFMIHNjaGVtYSBkZXNpZ24nLCBleHBlY3RlZEFnZW50OiAncmVzZWFyY2hlcicsIGNhdGVnb3J5OiAncmVzZWFyY2gnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnUjAwMicsIHRhc2s6ICdGaW5kIG91dCBob3cgdGhlIGF1dGhlbnRpY2F0aW9uIGZsb3cgd29ya3MgaW4gdGhpcyBjb2RlYmFzZScsIGV4cGVjdGVkQWdlbnQ6ICdyZXNlYXJjaGVyJywgY2F0ZWdvcnk6ICdyZXNlYXJjaCcsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnUjAwMycsIHRhc2s6ICdJbnZlc3RpZ2F0ZSB3aHkgdGhlIGJ1aWxkIGlzIGZhaWxpbmcgb24gQ0knLCBleHBlY3RlZEFnZW50OiAncmVzZWFyY2hlcicsIGNhdGVnb3J5OiAncmVzZWFyY2gnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnUjAwNCcsIHRhc2s6ICdSZXNlYXJjaCBhbHRlcm5hdGl2ZXMgdG8gUmVkdXggZm9yIHN0YXRlIG1hbmFnZW1lbnQnLCBleHBlY3RlZEFnZW50OiAncmVzZWFyY2hlcicsIGNhdGVnb3J5OiAncmVzZWFyY2gnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnUjAwNScsIHRhc2s6ICdGaW5kIGFsbCB1c2FnZXMgb2YgdGhlIGRlcHJlY2F0ZWQgQVBJIGluIHRoZSBjb2RlYmFzZScsIGV4cGVjdGVkQWdlbnQ6ICdyZXNlYXJjaGVyJywgY2F0ZWdvcnk6ICdyZXNlYXJjaCcsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnUjAwNicsIHRhc2s6ICdBbmFseXplIHRoZSBwZXJmb3JtYW5jZSBjaGFyYWN0ZXJpc3RpY3Mgb2Ygb3VyIGRhdGFiYXNlIHF1ZXJpZXMnLCBleHBlY3RlZEFnZW50OiAncmVzZWFyY2hlcicsIGNhdGVnb3J5OiAncmVzZWFyY2gnLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcbiAgeyBpZDogJ1IwMDcnLCB0YXNrOiAnUmVzZWFyY2ggR0RQUiBjb21wbGlhbmNlIHJlcXVpcmVtZW50cyBmb3IgdXNlciBkYXRhJywgZXhwZWN0ZWRBZ2VudDogJ3Jlc2VhcmNoZXInLCBjYXRlZ29yeTogJ3Jlc2VhcmNoJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1IwMDgnLCB0YXNrOiAnRmluZCBleGFtcGxlcyBvZiBzaW1pbGFyIGltcGxlbWVudGF0aW9ucyBpbiBvcGVuIHNvdXJjZScsIGV4cGVjdGVkQWdlbnQ6ICdyZXNlYXJjaGVyJywgY2F0ZWdvcnk6ICdyZXNlYXJjaCcsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuXG4gIC8vID09PSBSRVZJRVdFUiB0YXNrcyAoY29kZSByZXZpZXcsIHF1YWxpdHkpID09PVxuICB7IGlkOiAnVjAwMScsIHRhc2s6ICdSZXZpZXcgdGhpcyBwdWxsIHJlcXVlc3QgZm9yIGNvZGUgcXVhbGl0eScsIGV4cGVjdGVkQWdlbnQ6ICdyZXZpZXdlcicsIGNhdGVnb3J5OiAncmV2aWV3JywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1YwMDInLCB0YXNrOiAnQ2hlY2sgaWYgdGhpcyBjb2RlIGZvbGxvd3Mgb3VyIHN0eWxlIGd1aWRlbGluZXMnLCBleHBlY3RlZEFnZW50OiAncmV2aWV3ZXInLCBjYXRlZ29yeTogJ3JldmlldycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnVjAwMycsIHRhc2s6ICdSZXZpZXcgdGhlIEFQSSBkZXNpZ24gZm9yIGNvbnNpc3RlbmN5JywgZXhwZWN0ZWRBZ2VudDogJ3Jldmlld2VyJywgY2F0ZWdvcnk6ICdyZXZpZXcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnVjAwNCcsIHRhc2s6ICdFdmFsdWF0ZSB0aGUgZXJyb3IgaGFuZGxpbmcgaW4gdGhpcyBtb2R1bGUnLCBleHBlY3RlZEFnZW50OiAncmV2aWV3ZXInLCBjYXRlZ29yeTogJ3JldmlldycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdWMDA1JywgdGFzazogJ1JldmlldyB0aGUgZGF0YWJhc2Ugc2NoZW1hIGNoYW5nZXMnLCBleHBlY3RlZEFnZW50OiAncmV2aWV3ZXInLCBjYXRlZ29yeTogJ3JldmlldycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnVjAwNicsIHRhc2s6ICdDaGVjayBmb3IgcG90ZW50aWFsIG1lbW9yeSBsZWFrcyBpbiB0aGlzIGNvZGUnLCBleHBlY3RlZEFnZW50OiAncmV2aWV3ZXInLCBjYXRlZ29yeTogJ3JldmlldycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnVjAwNycsIHRhc2s6ICdSZXZpZXcgdGhlIGFjY2Vzc2liaWxpdHkgb2YgdGhlIFVJIGNvbXBvbmVudHMnLCBleHBlY3RlZEFnZW50OiAncmV2aWV3ZXInLCBjYXRlZ29yeTogJ3JldmlldycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG5cbiAgLy8gPT09IFRFU1RFUiB0YXNrcyAod3JpdGUgdGVzdHMsIFFBKSA9PT1cbiAgeyBpZDogJ1QwMDEnLCB0YXNrOiAnV3JpdGUgdW5pdCB0ZXN0cyBmb3IgdGhlIHVzZXIgc2VydmljZScsIGV4cGVjdGVkQWdlbnQ6ICd0ZXN0ZXInLCBjYXRlZ29yeTogJ3Rlc3RpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnVDAwMicsIHRhc2s6ICdDcmVhdGUgaW50ZWdyYXRpb24gdGVzdHMgZm9yIHRoZSBjaGVja291dCBmbG93JywgZXhwZWN0ZWRBZ2VudDogJ3Rlc3RlcicsIGNhdGVnb3J5OiAndGVzdGluZycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnVDAwMycsIHRhc2s6ICdBZGQgdGVzdCBjb3ZlcmFnZSBmb3IgZWRnZSBjYXNlcyBpbiB0aGUgcGFyc2VyJywgZXhwZWN0ZWRBZ2VudDogJ3Rlc3RlcicsIGNhdGVnb3J5OiAndGVzdGluZycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdUMDA0JywgdGFzazogJ1dyaXRlIEUyRSB0ZXN0cyBmb3IgdGhlIGxvZ2luIHBhZ2UnLCBleHBlY3RlZEFnZW50OiAndGVzdGVyJywgY2F0ZWdvcnk6ICd0ZXN0aW5nJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1QwMDUnLCB0YXNrOiAnQ3JlYXRlIHBlcmZvcm1hbmNlIHRlc3RzIGZvciB0aGUgQVBJJywgZXhwZWN0ZWRBZ2VudDogJ3Rlc3RlcicsIGNhdGVnb3J5OiAndGVzdGluZycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnVDAwNicsIHRhc2s6ICdBZGQgc25hcHNob3QgdGVzdHMgZm9yIFJlYWN0IGNvbXBvbmVudHMnLCBleHBlY3RlZEFnZW50OiAndGVzdGVyJywgY2F0ZWdvcnk6ICd0ZXN0aW5nJywgZGlmZmljdWx0eTogJ2Vhc3knIH0sXG4gIHsgaWQ6ICdUMDA3JywgdGFzazogJ1dyaXRlIHRlc3RzIGZvciB0aGUgYXV0aGVudGljYXRpb24gbWlkZGxld2FyZScsIGV4cGVjdGVkQWdlbnQ6ICd0ZXN0ZXInLCBjYXRlZ29yeTogJ3Rlc3RpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnVDAwOCcsIHRhc2s6ICdDcmVhdGUgbW9jayBkYXRhIGZvciB0ZXN0aW5nJywgZXhwZWN0ZWRBZ2VudDogJ3Rlc3RlcicsIGNhdGVnb3J5OiAndGVzdGluZycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuXG4gIC8vID09PSBBUkNISVRFQ1QgdGFza3MgKGRlc2lnbiwgc3lzdGVtKSA9PT1cbiAgeyBpZDogJ0EwMDEnLCB0YXNrOiAnRGVzaWduIHRoZSBtaWNyb3NlcnZpY2VzIGFyY2hpdGVjdHVyZSBmb3IgdGhlIHBsYXRmb3JtJywgZXhwZWN0ZWRBZ2VudDogJ2FyY2hpdGVjdCcsIGNhdGVnb3J5OiAnYXJjaGl0ZWN0dXJlJywgZGlmZmljdWx0eTogJ2hhcmQnIH0sXG4gIHsgaWQ6ICdBMDAyJywgdGFzazogJ0NyZWF0ZSBhIHN5c3RlbSBkZXNpZ24gZm9yIHRoZSBub3RpZmljYXRpb24gc2VydmljZScsIGV4cGVjdGVkQWdlbnQ6ICdhcmNoaXRlY3QnLCBjYXRlZ29yeTogJ2FyY2hpdGVjdHVyZScsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnQTAwMycsIHRhc2s6ICdQbGFuIHRoZSBkYXRhYmFzZSBzY2hlbWEgZm9yIHRoZSBuZXcgZmVhdHVyZScsIGV4cGVjdGVkQWdlbnQ6ICdhcmNoaXRlY3QnLCBjYXRlZ29yeTogJ2FyY2hpdGVjdHVyZScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdBMDA0JywgdGFzazogJ0Rlc2lnbiB0aGUgQVBJIGNvbnRyYWN0IGZvciB0aGUgbW9iaWxlIGFwcCcsIGV4cGVjdGVkQWdlbnQ6ICdhcmNoaXRlY3QnLCBjYXRlZ29yeTogJ2FyY2hpdGVjdHVyZScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdBMDA1JywgdGFzazogJ0NyZWF0ZSBhbiBBRFIgZm9yIHRoZSBjYWNoaW5nIHN0cmF0ZWd5JywgZXhwZWN0ZWRBZ2VudDogJ2FyY2hpdGVjdCcsIGNhdGVnb3J5OiAnYXJjaGl0ZWN0dXJlJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0EwMDYnLCB0YXNrOiAnRGVzaWduIHRoZSBldmVudC1kcml2ZW4gYXJjaGl0ZWN0dXJlIGZvciBvcmRlciBwcm9jZXNzaW5nJywgZXhwZWN0ZWRBZ2VudDogJ2FyY2hpdGVjdCcsIGNhdGVnb3J5OiAnYXJjaGl0ZWN0dXJlJywgZGlmZmljdWx0eTogJ2hhcmQnIH0sXG4gIHsgaWQ6ICdBMDA3JywgdGFzazogJ1BsYW4gdGhlIG1pZ3JhdGlvbiBzdHJhdGVneSBmcm9tIG1vbm9saXRoIHRvIG1pY3Jvc2VydmljZXMnLCBleHBlY3RlZEFnZW50OiAnYXJjaGl0ZWN0JywgY2F0ZWdvcnk6ICdhcmNoaXRlY3R1cmUnLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcblxuICAvLyA9PT0gU0VDVVJJVFkgdGFza3MgPT09XG4gIHsgaWQ6ICdTMDAxJywgdGFzazogJ0F1ZGl0IHRoZSBhdXRoZW50aWNhdGlvbiBpbXBsZW1lbnRhdGlvbiBmb3IgdnVsbmVyYWJpbGl0aWVzJywgZXhwZWN0ZWRBZ2VudDogJ3NlY3VyaXR5LWFyY2hpdGVjdCcsIGNhdGVnb3J5OiAnc2VjdXJpdHknLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcbiAgeyBpZDogJ1MwMDInLCB0YXNrOiAnUmV2aWV3IHRoZSBjb2RlIGZvciBTUUwgaW5qZWN0aW9uIHZ1bG5lcmFiaWxpdGllcycsIGV4cGVjdGVkQWdlbnQ6ICdzZWN1cml0eS1hcmNoaXRlY3QnLCBjYXRlZ29yeTogJ3NlY3VyaXR5JywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1MwMDMnLCB0YXNrOiAnQ2hlY2sgZm9yIFhTUyB2dWxuZXJhYmlsaXRpZXMgaW4gdGhlIGZyb250ZW5kJywgZXhwZWN0ZWRBZ2VudDogJ3NlY3VyaXR5LWFyY2hpdGVjdCcsIGNhdGVnb3J5OiAnc2VjdXJpdHknLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnUzAwNCcsIHRhc2s6ICdJbXBsZW1lbnQgc2VjdXJlIHBhc3N3b3JkIGhhc2hpbmcnLCBleHBlY3RlZEFnZW50OiAnc2VjdXJpdHktYXJjaGl0ZWN0JywgY2F0ZWdvcnk6ICdzZWN1cml0eScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdTMDA1JywgdGFzazogJ1JldmlldyB0aGUgQVBJIGZvciBhdXRob3JpemF0aW9uIGJ5cGFzcyBpc3N1ZXMnLCBleHBlY3RlZEFnZW50OiAnc2VjdXJpdHktYXJjaGl0ZWN0JywgY2F0ZWdvcnk6ICdzZWN1cml0eScsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnUzAwNicsIHRhc2s6ICdBdWRpdCB0aGlyZC1wYXJ0eSBkZXBlbmRlbmNpZXMgZm9yIGtub3duIENWRXMnLCBleHBlY3RlZEFnZW50OiAnc2VjdXJpdHktYXJjaGl0ZWN0JywgY2F0ZWdvcnk6ICdzZWN1cml0eScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdTMDA3JywgdGFzazogJ0Rlc2lnbiB0aGUgc2VjcmV0cyBtYW5hZ2VtZW50IHN0cmF0ZWd5JywgZXhwZWN0ZWRBZ2VudDogJ3NlY3VyaXR5LWFyY2hpdGVjdCcsIGNhdGVnb3J5OiAnc2VjdXJpdHknLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcblxuICAvLyA9PT0gREVCVUdHRVIgdGFza3MgPT09XG4gIHsgaWQ6ICdEMDAxJywgdGFzazogJ0ZpeCB0aGUgbnVsbCBwb2ludGVyIGV4Y2VwdGlvbiBpbiB0aGUgdXNlciBjb250cm9sbGVyJywgZXhwZWN0ZWRBZ2VudDogJ2RlYnVnZ2VyJywgY2F0ZWdvcnk6ICdkZWJ1Z2dpbmcnLCBkaWZmaWN1bHR5OiAnZWFzeScgfSxcbiAgeyBpZDogJ0QwMDInLCB0YXNrOiAnRGVidWcgd2h5IHRoZSBBUEkgcmV0dXJucyA1MDAgaW50ZXJtaXR0ZW50bHknLCBleHBlY3RlZEFnZW50OiAnZGVidWdnZXInLCBjYXRlZ29yeTogJ2RlYnVnZ2luZycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnRDAwMycsIHRhc2s6ICdGaW5kIHRoZSBjYXVzZSBvZiB0aGUgbWVtb3J5IGxlYWsnLCBleHBlY3RlZEFnZW50OiAnZGVidWdnZXInLCBjYXRlZ29yeTogJ2RlYnVnZ2luZycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnRDAwNCcsIHRhc2s6ICdGaXggdGhlIHJhY2UgY29uZGl0aW9uIGluIHRoZSBjaGVja291dCBwcm9jZXNzJywgZXhwZWN0ZWRBZ2VudDogJ2RlYnVnZ2VyJywgY2F0ZWdvcnk6ICdkZWJ1Z2dpbmcnLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcbiAgeyBpZDogJ0QwMDUnLCB0YXNrOiAnRGVidWcgdGhlIGZhaWxpbmcgdGVzdCBpbiBDSScsIGV4cGVjdGVkQWdlbnQ6ICdkZWJ1Z2dlcicsIGNhdGVnb3J5OiAnZGVidWdnaW5nJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0QwMDYnLCB0YXNrOiAnRml4IHRoZSB0aW1lem9uZSBpc3N1ZSBpbiBkYXRlIGhhbmRsaW5nJywgZXhwZWN0ZWRBZ2VudDogJ2RlYnVnZ2VyJywgY2F0ZWdvcnk6ICdkZWJ1Z2dpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnRDAwNycsIHRhc2s6ICdSZXNvbHZlIHRoZSBjaXJjdWxhciBkZXBlbmRlbmN5IGVycm9yJywgZXhwZWN0ZWRBZ2VudDogJ2RlYnVnZ2VyJywgY2F0ZWdvcnk6ICdkZWJ1Z2dpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnRDAwOCcsIHRhc2s6ICdGaXggdGhlIGJyb2tlbiBidWlsZCBhZnRlciB0aGUgbWVyZ2UnLCBleHBlY3RlZEFnZW50OiAnZGVidWdnZXInLCBjYXRlZ29yeTogJ2RlYnVnZ2luZycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuXG4gIC8vID09PSBET0NVTUVOVEVSIHRhc2tzID09PVxuICB7IGlkOiAnTzAwMScsIHRhc2s6ICdXcml0ZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgQVBJIGVuZHBvaW50cycsIGV4cGVjdGVkQWdlbnQ6ICdkb2N1bWVudGVyJywgY2F0ZWdvcnk6ICdkb2N1bWVudGF0aW9uJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ08wMDInLCB0YXNrOiAnQ3JlYXRlIGEgUkVBRE1FIGZvciB0aGUgbmV3IHBhY2thZ2UnLCBleHBlY3RlZEFnZW50OiAnZG9jdW1lbnRlcicsIGNhdGVnb3J5OiAnZG9jdW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnTzAwMycsIHRhc2s6ICdEb2N1bWVudCB0aGUgZGVwbG95bWVudCBwcm9jZXNzJywgZXhwZWN0ZWRBZ2VudDogJ2RvY3VtZW50ZXInLCBjYXRlZ29yeTogJ2RvY3VtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnTzAwNCcsIHRhc2s6ICdXcml0ZSBKU0RvYyBjb21tZW50cyBmb3IgdGhlIHV0aWxpdHkgZnVuY3Rpb25zJywgZXhwZWN0ZWRBZ2VudDogJ2RvY3VtZW50ZXInLCBjYXRlZ29yeTogJ2RvY3VtZW50YXRpb24nLCBkaWZmaWN1bHR5OiAnZWFzeScgfSxcbiAgeyBpZDogJ08wMDUnLCB0YXNrOiAnQ3JlYXRlIGEgbWlncmF0aW9uIGd1aWRlIGZvciB2MiB0byB2MycsIGV4cGVjdGVkQWdlbnQ6ICdkb2N1bWVudGVyJywgY2F0ZWdvcnk6ICdkb2N1bWVudGF0aW9uJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ08wMDYnLCB0YXNrOiAnRG9jdW1lbnQgdGhlIGFyY2hpdGVjdHVyZSBkZWNpc2lvbnMnLCBleHBlY3RlZEFnZW50OiAnZG9jdW1lbnRlcicsIGNhdGVnb3J5OiAnZG9jdW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG5cbiAgLy8gPT09IFJFRkFDVE9SRVIgdGFza3MgPT09XG4gIHsgaWQ6ICdGMDAxJywgdGFzazogJ1JlZmFjdG9yIHRoZSB1c2VyIHNlcnZpY2UgdG8gdXNlIGRlcGVuZGVuY3kgaW5qZWN0aW9uJywgZXhwZWN0ZWRBZ2VudDogJ3JlZmFjdG9yZXInLCBjYXRlZ29yeTogJ3JlZmFjdG9yaW5nJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0YwMDInLCB0YXNrOiAnRXh0cmFjdCBjb21tb24gbG9naWMgaW50byBhIHNoYXJlZCB1dGlsaXR5JywgZXhwZWN0ZWRBZ2VudDogJ3JlZmFjdG9yZXInLCBjYXRlZ29yeTogJ3JlZmFjdG9yaW5nJywgZGlmZmljdWx0eTogJ2Vhc3knIH0sXG4gIHsgaWQ6ICdGMDAzJywgdGFzazogJ1NwbGl0IHRoZSBsYXJnZSBjb21wb25lbnQgaW50byBzbWFsbGVyIG9uZXMnLCBleHBlY3RlZEFnZW50OiAncmVmYWN0b3JlcicsIGNhdGVnb3J5OiAncmVmYWN0b3JpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnRjAwNCcsIHRhc2s6ICdSZW5hbWUgdGhlIGFtYmlndW91cyB2YXJpYWJsZSBuYW1lcyBpbiB0aGlzIG1vZHVsZScsIGV4cGVjdGVkQWdlbnQ6ICdyZWZhY3RvcmVyJywgY2F0ZWdvcnk6ICdyZWZhY3RvcmluZycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnRjAwNScsIHRhc2s6ICdDb252ZXJ0IHRoZSBjYWxsYmFja3MgdG8gYXN5bmMvYXdhaXQnLCBleHBlY3RlZEFnZW50OiAncmVmYWN0b3JlcicsIGNhdGVnb3J5OiAncmVmYWN0b3JpbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnRjAwNicsIHRhc2s6ICdSZW1vdmUgZGVhZCBjb2RlIGZyb20gdGhlIGxlZ2FjeSBtb2R1bGUnLCBleHBlY3RlZEFnZW50OiAncmVmYWN0b3JlcicsIGNhdGVnb3J5OiAncmVmYWN0b3JpbmcnLCBkaWZmaWN1bHR5OiAnZWFzeScgfSxcbiAgeyBpZDogJ0YwMDcnLCB0YXNrOiAnQ29uc29saWRhdGUgZHVwbGljYXRlIEFQSSBoYW5kbGVycycsIGV4cGVjdGVkQWdlbnQ6ICdyZWZhY3RvcmVyJywgY2F0ZWdvcnk6ICdyZWZhY3RvcmluZycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG5cbiAgLy8gPT09IE9QVElNSVpFUiB0YXNrcyA9PT1cbiAgeyBpZDogJ1AwMDEnLCB0YXNrOiAnT3B0aW1pemUgdGhlIHNsb3cgZGF0YWJhc2UgcXVlcnknLCBleHBlY3RlZEFnZW50OiAnb3B0aW1pemVyJywgY2F0ZWdvcnk6ICdwZXJmb3JtYW5jZScsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnUDAwMicsIHRhc2s6ICdSZWR1Y2UgdGhlIGJ1bmRsZSBzaXplIG9mIHRoZSBmcm9udGVuZCcsIGV4cGVjdGVkQWdlbnQ6ICdvcHRpbWl6ZXInLCBjYXRlZ29yeTogJ3BlcmZvcm1hbmNlJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1AwMDMnLCB0YXNrOiAnSW1wcm92ZSB0aGUgQVBJIHJlc3BvbnNlIHRpbWUnLCBleHBlY3RlZEFnZW50OiAnb3B0aW1pemVyJywgY2F0ZWdvcnk6ICdwZXJmb3JtYW5jZScsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnUDAwNCcsIHRhc2s6ICdBZGQgY2FjaGluZyB0byByZWR1Y2UgZGF0YWJhc2UgbG9hZCcsIGV4cGVjdGVkQWdlbnQ6ICdvcHRpbWl6ZXInLCBjYXRlZ29yeTogJ3BlcmZvcm1hbmNlJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1AwMDUnLCB0YXNrOiAnT3B0aW1pemUgdGhlIGltYWdlIGxvYWRpbmcgcGVyZm9ybWFuY2UnLCBleHBlY3RlZEFnZW50OiAnb3B0aW1pemVyJywgY2F0ZWdvcnk6ICdwZXJmb3JtYW5jZScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdQMDA2JywgdGFzazogJ1Byb2ZpbGUgYW5kIG9wdGltaXplIG1lbW9yeSB1c2FnZScsIGV4cGVjdGVkQWdlbnQ6ICdvcHRpbWl6ZXInLCBjYXRlZ29yeTogJ3BlcmZvcm1hbmNlJywgZGlmZmljdWx0eTogJ2hhcmQnIH0sXG4gIHsgaWQ6ICdQMDA3JywgdGFzazogJ0ltcGxlbWVudCBsYXp5IGxvYWRpbmcgZm9yIHRoZSBkYXNoYm9hcmQnLCBleHBlY3RlZEFnZW50OiAnb3B0aW1pemVyJywgY2F0ZWdvcnk6ICdwZXJmb3JtYW5jZScsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG5cbiAgLy8gPT09IERFVk9QUyB0YXNrcyA9PT1cbiAgeyBpZDogJ0UwMDEnLCB0YXNrOiAnU2V0IHVwIHRoZSBDSS9DRCBwaXBlbGluZSBmb3IgdGhlIG5ldyBzZXJ2aWNlJywgZXhwZWN0ZWRBZ2VudDogJ2Rldm9wcycsIGNhdGVnb3J5OiAnZGV2b3BzJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0UwMDInLCB0YXNrOiAnQ29uZmlndXJlIEt1YmVybmV0ZXMgZGVwbG95bWVudCBmb3IgcHJvZHVjdGlvbicsIGV4cGVjdGVkQWdlbnQ6ICdkZXZvcHMnLCBjYXRlZ29yeTogJ2Rldm9wcycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuICB7IGlkOiAnRTAwMycsIHRhc2s6ICdTZXQgdXAgbW9uaXRvcmluZyBhbmQgYWxlcnRpbmcnLCBleHBlY3RlZEFnZW50OiAnZGV2b3BzJywgY2F0ZWdvcnk6ICdkZXZvcHMnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnRTAwNCcsIHRhc2s6ICdDcmVhdGUgRG9ja2VyIGNvbnRhaW5lcnMgZm9yIHRoZSBtaWNyb3NlcnZpY2VzJywgZXhwZWN0ZWRBZ2VudDogJ2Rldm9wcycsIGNhdGVnb3J5OiAnZGV2b3BzJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0UwMDUnLCB0YXNrOiAnQ29uZmlndXJlIGF1dG8tc2NhbGluZyBmb3IgdGhlIEFQSSBzZXJ2ZXJzJywgZXhwZWN0ZWRBZ2VudDogJ2Rldm9wcycsIGNhdGVnb3J5OiAnZGV2b3BzJywgZGlmZmljdWx0eTogJ2hhcmQnIH0sXG4gIHsgaWQ6ICdFMDA2JywgdGFzazogJ1NldCB1cCB0aGUgc3RhZ2luZyBlbnZpcm9ubWVudCcsIGV4cGVjdGVkQWdlbnQ6ICdkZXZvcHMnLCBjYXRlZ29yeTogJ2Rldm9wcycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdFMDA3JywgdGFzazogJ0ltcGxlbWVudCBibHVlLWdyZWVuIGRlcGxveW1lbnQgc3RyYXRlZ3knLCBleHBlY3RlZEFnZW50OiAnZGV2b3BzJywgY2F0ZWdvcnk6ICdkZXZvcHMnLCBkaWZmaWN1bHR5OiAnaGFyZCcgfSxcblxuICAvLyA9PT0gQVBJLURPQ1MgdGFza3MgPT09XG4gIHsgaWQ6ICdJMDAxJywgdGFzazogJ0dlbmVyYXRlIE9wZW5BUEkgc3BlYyBmb3IgdGhlIFJFU1QgQVBJJywgZXhwZWN0ZWRBZ2VudDogJ2FwaS1kb2NzJywgY2F0ZWdvcnk6ICdhcGktZG9jdW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdJMDAyJywgdGFzazogJ0NyZWF0ZSBTd2FnZ2VyIGRvY3VtZW50YXRpb24gZm9yIHRoZSBlbmRwb2ludHMnLCBleHBlY3RlZEFnZW50OiAnYXBpLWRvY3MnLCBjYXRlZ29yeTogJ2FwaS1kb2N1bWVudGF0aW9uJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0kwMDMnLCB0YXNrOiAnRG9jdW1lbnQgdGhlIEdyYXBoUUwgc2NoZW1hJywgZXhwZWN0ZWRBZ2VudDogJ2FwaS1kb2NzJywgY2F0ZWdvcnk6ICdhcGktZG9jdW1lbnRhdGlvbicsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdJMDA0JywgdGFzazogJ0FkZCBleGFtcGxlIHJlcXVlc3RzIGFuZCByZXNwb25zZXMgdG8gQVBJIGRvY3MnLCBleHBlY3RlZEFnZW50OiAnYXBpLWRvY3MnLCBjYXRlZ29yeTogJ2FwaS1kb2N1bWVudGF0aW9uJywgZGlmZmljdWx0eTogJ2Vhc3knIH0sXG5cbiAgLy8gPT09IFBMQU5ORVIgdGFza3MgPT09XG4gIHsgaWQ6ICdMMDAxJywgdGFzazogJ0JyZWFrIGRvd24gdGhlIGZlYXR1cmUgaW50byBpbXBsZW1lbnRhdGlvbiB0YXNrcycsIGV4cGVjdGVkQWdlbnQ6ICdwbGFubmVyJywgY2F0ZWdvcnk6ICdwbGFubmluZycsIGRpZmZpY3VsdHk6ICdtZWRpdW0nIH0sXG4gIHsgaWQ6ICdMMDAyJywgdGFzazogJ0NyZWF0ZSBhIHNwcmludCBwbGFuIGZvciB0aGUgbmV4dCBtaWxlc3RvbmUnLCBleHBlY3RlZEFnZW50OiAncGxhbm5lcicsIGNhdGVnb3J5OiAncGxhbm5pbmcnLCBkaWZmaWN1bHR5OiAnbWVkaXVtJyB9LFxuICB7IGlkOiAnTDAwMycsIHRhc2s6ICdFc3RpbWF0ZSBlZmZvcnQgZm9yIHRoZSByZWZhY3RvcmluZyBwcm9qZWN0JywgZXhwZWN0ZWRBZ2VudDogJ3BsYW5uZXInLCBjYXRlZ29yeTogJ3BsYW5uaW5nJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ0wwMDQnLCB0YXNrOiAnUHJpb3JpdGl6ZSB0aGUgYnVnIGZpeGVzIGZvciB0aGUgcmVsZWFzZScsIGV4cGVjdGVkQWdlbnQ6ICdwbGFubmVyJywgY2F0ZWdvcnk6ICdwbGFubmluZycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnTDAwNScsIHRhc2s6ICdQbGFuIHRoZSB0ZWNobmljYWwgZGVidCByZWR1Y3Rpb24gcm9hZG1hcCcsIGV4cGVjdGVkQWdlbnQ6ICdwbGFubmVyJywgY2F0ZWdvcnk6ICdwbGFubmluZycsIGRpZmZpY3VsdHk6ICdoYXJkJyB9LFxuXG4gIC8vID09PSBBTUJJR1VPVVMgLyBFREdFIENBU0VTID09PVxuICB7IGlkOiAnWDAwMScsIHRhc2s6ICdUaGUgbG9naW4gaXMgYnJva2VuLCB1c2VycyBjYW5ub3Qgc2lnbiBpbicsIGV4cGVjdGVkQWdlbnQ6ICdkZWJ1Z2dlcicsIGNhdGVnb3J5OiAnYW1iaWd1b3VzJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1gwMDInLCB0YXNrOiAnV2UgbmVlZCBiZXR0ZXIgZXJyb3IgbWVzc2FnZXMnLCBleHBlY3RlZEFnZW50OiAnY29kZXInLCBjYXRlZ29yeTogJ2FtYmlndW91cycsIGRpZmZpY3VsdHk6ICdlYXN5JyB9LFxuICB7IGlkOiAnWDAwMycsIHRhc2s6ICdNYWtlIHRoZSBhcHAgZmFzdGVyJywgZXhwZWN0ZWRBZ2VudDogJ29wdGltaXplcicsIGNhdGVnb3J5OiAnYW1iaWd1b3VzJywgZGlmZmljdWx0eTogJ2hhcmQnIH0sXG4gIHsgaWQ6ICdYMDA0JywgdGFzazogJ1RoZSBjb2RlIGlzIGEgbWVzcywgY2xlYW4gaXQgdXAnLCBleHBlY3RlZEFnZW50OiAncmVmYWN0b3JlcicsIGNhdGVnb3J5OiAnYW1iaWd1b3VzJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbiAgeyBpZDogJ1gwMDUnLCB0YXNrOiAnSXMgdGhpcyBpbXBsZW1lbnRhdGlvbiBzZWN1cmU/JywgZXhwZWN0ZWRBZ2VudDogJ3NlY3VyaXR5LWFyY2hpdGVjdCcsIGNhdGVnb3J5OiAnYW1iaWd1b3VzJywgZGlmZmljdWx0eTogJ21lZGl1bScgfSxcbl07XG5cbi8qKlxuICogU2ltcGxlIGtleXdvcmQtYmFzZWQgcm91dGluZyBmb3IgYmFzZWxpbmUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFzZWxpbmVLZXl3b3JkUm91dGVyKHRhc2s6IHN0cmluZyk6IHsgYWdlbnQ6IEFnZW50VHlwZTsgY29uZmlkZW5jZTogbnVtYmVyIH0ge1xuICBjb25zdCB0YXNrTG93ZXIgPSB0YXNrLnRvTG93ZXJDYXNlKCk7XG5cbiAgY29uc3QgcGF0dGVybnM6IHsga2V5d29yZHM6IHN0cmluZ1tdOyBhZ2VudDogQWdlbnRUeXBlOyB3ZWlnaHQ6IG51bWJlciB9W10gPSBbXG4gICAgeyBrZXl3b3JkczogWydpbXBsZW1lbnQnLCAnY3JlYXRlJywgJ3dyaXRlJywgJ2FkZCcsICdidWlsZCddLCBhZ2VudDogJ2NvZGVyJywgd2VpZ2h0OiAxIH0sXG4gICAgeyBrZXl3b3JkczogWydyZXNlYXJjaCcsICdmaW5kJywgJ2ludmVzdGlnYXRlJywgJ2FuYWx5emUnLCAnZXhwbG9yZSddLCBhZ2VudDogJ3Jlc2VhcmNoZXInLCB3ZWlnaHQ6IDEgfSxcbiAgICB7IGtleXdvcmRzOiBbJ3JldmlldycsICdjaGVjaycsICdldmFsdWF0ZScsICdhc3Nlc3MnXSwgYWdlbnQ6ICdyZXZpZXdlcicsIHdlaWdodDogMSB9LFxuICAgIHsga2V5d29yZHM6IFsndGVzdCcsICd1bml0IHRlc3QnLCAnaW50ZWdyYXRpb24gdGVzdCcsICdlMmUnLCAnY292ZXJhZ2UnXSwgYWdlbnQ6ICd0ZXN0ZXInLCB3ZWlnaHQ6IDEuMiB9LFxuICAgIHsga2V5d29yZHM6IFsnZGVzaWduJywgJ2FyY2hpdGVjdCcsICdzY2hlbWEnLCAnYWRyJywgJ3N5c3RlbSBkZXNpZ24nXSwgYWdlbnQ6ICdhcmNoaXRlY3QnLCB3ZWlnaHQ6IDEuMiB9LFxuICAgIHsga2V5d29yZHM6IFsnc2VjdXJpdHknLCAndnVsbmVyYWJpbGl0eScsICd4c3MnLCAnc3FsIGluamVjdGlvbicsICdhdWRpdCcsICdjdmUnXSwgYWdlbnQ6ICdzZWN1cml0eS1hcmNoaXRlY3QnLCB3ZWlnaHQ6IDEuNSB9LFxuICAgIHsga2V5d29yZHM6IFsnZGVidWcnLCAnZml4JywgJ2J1ZycsICdlcnJvcicsICdicm9rZW4nLCAnaXNzdWUnXSwgYWdlbnQ6ICdkZWJ1Z2dlcicsIHdlaWdodDogMS4yIH0sXG4gICAgeyBrZXl3b3JkczogWydkb2N1bWVudCcsICdyZWFkbWUnLCAnanNkb2MnLCAnY29tbWVudCddLCBhZ2VudDogJ2RvY3VtZW50ZXInLCB3ZWlnaHQ6IDEgfSxcbiAgICB7IGtleXdvcmRzOiBbJ3JlZmFjdG9yJywgJ2V4dHJhY3QnLCAncmVuYW1lJywgJ2NvbnNvbGlkYXRlJywgJ3NwbGl0J10sIGFnZW50OiAncmVmYWN0b3JlcicsIHdlaWdodDogMS4yIH0sXG4gICAgeyBrZXl3b3JkczogWydvcHRpbWl6ZScsICdwZXJmb3JtYW5jZScsICdzbG93JywgJ2NhY2hlJywgJ2Zhc3RlciddLCBhZ2VudDogJ29wdGltaXplcicsIHdlaWdodDogMS4yIH0sXG4gICAgeyBrZXl3b3JkczogWydkZXBsb3knLCAnY2kvY2QnLCAna3ViZXJuZXRlcycsICdkb2NrZXInLCAncGlwZWxpbmUnXSwgYWdlbnQ6ICdkZXZvcHMnLCB3ZWlnaHQ6IDEuMiB9LFxuICAgIHsga2V5d29yZHM6IFsnb3BlbmFwaScsICdzd2FnZ2VyJywgJ2FwaSBkb2MnLCAnZ3JhcGhxbCBzY2hlbWEnXSwgYWdlbnQ6ICdhcGktZG9jcycsIHdlaWdodDogMS4zIH0sXG4gICAgeyBrZXl3b3JkczogWydwbGFuJywgJ2VzdGltYXRlJywgJ3ByaW9yaXRpemUnLCAnc3ByaW50JywgJ3JvYWRtYXAnXSwgYWdlbnQ6ICdwbGFubmVyJywgd2VpZ2h0OiAxIH0sXG4gIF07XG5cbiAgbGV0IGJlc3RNYXRjaDogeyBhZ2VudDogQWdlbnRUeXBlOyBzY29yZTogbnVtYmVyIH0gPSB7IGFnZW50OiAnY29kZXInLCBzY29yZTogMCB9O1xuXG4gIGZvciAoY29uc3QgcGF0dGVybiBvZiBwYXR0ZXJucykge1xuICAgIGxldCBzY29yZSA9IDA7XG4gICAgZm9yIChjb25zdCBrZXl3b3JkIG9mIHBhdHRlcm4ua2V5d29yZHMpIHtcbiAgICAgIGlmICh0YXNrTG93ZXIuaW5jbHVkZXMoa2V5d29yZCkpIHtcbiAgICAgICAgc2NvcmUgKz0gcGF0dGVybi53ZWlnaHQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzY29yZSA+IGJlc3RNYXRjaC5zY29yZSkge1xuICAgICAgYmVzdE1hdGNoID0geyBhZ2VudDogcGF0dGVybi5hZ2VudCwgc2NvcmUgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFnZW50OiBiZXN0TWF0Y2guYWdlbnQsXG4gICAgY29uZmlkZW5jZTogTWF0aC5taW4oYmVzdE1hdGNoLnNjb3JlIC8gMywgMSksIC8vIE5vcm1hbGl6ZSB0byAwLTFcbiAgfTtcbn1cblxuLyoqXG4gKiBSdW4gdGhlIHJvdXRpbmcgYmVuY2htYXJrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5Sb3V0aW5nQmVuY2htYXJrKFxuICByb3V0ZXI6ICh0YXNrOiBzdHJpbmcpID0+IHsgYWdlbnQ6IHN0cmluZzsgY29uZmlkZW5jZTogbnVtYmVyIH1cbik6IFJvdXRpbmdCZW5jaG1hcmtSZXN1bHRzIHtcbiAgY29uc3QgcmVzdWx0czogUm91dGluZ1Jlc3VsdFtdID0gW107XG4gIGNvbnN0IGxhdGVuY2llczogbnVtYmVyW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHRlc3RDYXNlIG9mIFJPVVRJTkdfVEVTVF9DQVNFUykge1xuICAgIGNvbnN0IHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgcHJlZGljdGlvbiA9IHJvdXRlcih0ZXN0Q2FzZS50YXNrKTtcbiAgICBjb25zdCBsYXRlbmN5TXMgPSBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0O1xuXG4gICAgbGF0ZW5jaWVzLnB1c2gobGF0ZW5jeU1zKTtcblxuICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICB0ZXN0SWQ6IHRlc3RDYXNlLmlkLFxuICAgICAgdGFzazogdGVzdENhc2UudGFzayxcbiAgICAgIGV4cGVjdGVkQWdlbnQ6IHRlc3RDYXNlLmV4cGVjdGVkQWdlbnQsXG4gICAgICBwcmVkaWN0ZWRBZ2VudDogcHJlZGljdGlvbi5hZ2VudCxcbiAgICAgIGNvbmZpZGVuY2U6IHByZWRpY3Rpb24uY29uZmlkZW5jZSxcbiAgICAgIGNvcnJlY3Q6IHByZWRpY3Rpb24uYWdlbnQgPT09IHRlc3RDYXNlLmV4cGVjdGVkQWdlbnQsXG4gICAgICBsYXRlbmN5TXMsXG4gICAgfSk7XG4gIH1cblxuICAvLyBDYWxjdWxhdGUgbWV0cmljc1xuICBjb25zdCBjb3JyZWN0ID0gcmVzdWx0cy5maWx0ZXIociA9PiByLmNvcnJlY3QpLmxlbmd0aDtcbiAgY29uc3QgYWNjdXJhY3kgPSBjb3JyZWN0IC8gcmVzdWx0cy5sZW5ndGg7XG5cbiAgLy8gQWNjdXJhY3kgYnkgY2F0ZWdvcnlcbiAgY29uc3QgY2F0ZWdvcmllcyA9IFsuLi5uZXcgU2V0KFJPVVRJTkdfVEVTVF9DQVNFUy5tYXAodCA9PiB0LmNhdGVnb3J5KSldO1xuICBjb25zdCBhY2N1cmFjeUJ5Q2F0ZWdvcnk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgZm9yIChjb25zdCBjYXQgb2YgY2F0ZWdvcmllcykge1xuICAgIGNvbnN0IGNhdFJlc3VsdHMgPSByZXN1bHRzLmZpbHRlcigociwgaSkgPT4gUk9VVElOR19URVNUX0NBU0VTW2ldLmNhdGVnb3J5ID09PSBjYXQpO1xuICAgIGFjY3VyYWN5QnlDYXRlZ29yeVtjYXRdID0gY2F0UmVzdWx0cy5maWx0ZXIociA9PiByLmNvcnJlY3QpLmxlbmd0aCAvIGNhdFJlc3VsdHMubGVuZ3RoO1xuICB9XG5cbiAgLy8gQWNjdXJhY3kgYnkgZGlmZmljdWx0eVxuICBjb25zdCBkaWZmaWN1bHRpZXMgPSBbJ2Vhc3knLCAnbWVkaXVtJywgJ2hhcmQnXTtcbiAgY29uc3QgYWNjdXJhY3lCeURpZmZpY3VsdHk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgZm9yIChjb25zdCBkaWZmIG9mIGRpZmZpY3VsdGllcykge1xuICAgIGNvbnN0IGRpZmZSZXN1bHRzID0gcmVzdWx0cy5maWx0ZXIoKHIsIGkpID0+IFJPVVRJTkdfVEVTVF9DQVNFU1tpXS5kaWZmaWN1bHR5ID09PSBkaWZmKTtcbiAgICBhY2N1cmFjeUJ5RGlmZmljdWx0eVtkaWZmXSA9IGRpZmZSZXN1bHRzLmZpbHRlcihyID0+IHIuY29ycmVjdCkubGVuZ3RoIC8gZGlmZlJlc3VsdHMubGVuZ3RoO1xuICB9XG5cbiAgLy8gTGF0ZW5jeSBwZXJjZW50aWxlc1xuICBjb25zdCBzb3J0ZWRMYXRlbmNpZXMgPSBbLi4ubGF0ZW5jaWVzXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gIGNvbnN0IHA1MCA9IHNvcnRlZExhdGVuY2llc1tNYXRoLmZsb29yKHNvcnRlZExhdGVuY2llcy5sZW5ndGggKiAwLjUpXTtcbiAgY29uc3QgcDk1ID0gc29ydGVkTGF0ZW5jaWVzW01hdGguZmxvb3Ioc29ydGVkTGF0ZW5jaWVzLmxlbmd0aCAqIDAuOTUpXTtcbiAgY29uc3QgYXZnTGF0ZW5jeSA9IGxhdGVuY2llcy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSAvIGxhdGVuY2llcy5sZW5ndGg7XG5cbiAgcmV0dXJuIHtcbiAgICBhY2N1cmFjeSxcbiAgICBhY2N1cmFjeUJ5Q2F0ZWdvcnksXG4gICAgYWNjdXJhY3lCeURpZmZpY3VsdHksXG4gICAgYXZnTGF0ZW5jeU1zOiBhdmdMYXRlbmN5LFxuICAgIHA1MExhdGVuY3lNczogcDUwLFxuICAgIHA5NUxhdGVuY3lNczogcDk1LFxuICAgIHRvdGFsVGVzdHM6IHJlc3VsdHMubGVuZ3RoLFxuICAgIGNvcnJlY3QsXG4gICAgcmVzdWx0cyxcbiAgfTtcbn1cblxuLyoqXG4gKiBGb3JtYXQgYmVuY2htYXJrIHJlc3VsdHMgZm9yIGRpc3BsYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFJvdXRpbmdSZXN1bHRzKHJlc3VsdHM6IFJvdXRpbmdCZW5jaG1hcmtSZXN1bHRzKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgbGluZXMucHVzaCgnJyk7XG4gIGxpbmVzLnB1c2goJ+KVlOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVlycpO1xuICBsaW5lcy5wdXNoKCfilZEgICAgICAgICAgICAgIFJPVVRJTkcgQkVOQ0hNQVJLIFJFU1VMVFMgICAgICAgICAgICAgICAgICAgICAgIOKVkScpO1xuICBsaW5lcy5wdXNoKCfilaDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilaMnKTtcbiAgbGluZXMucHVzaChg4pWRICBPdmVyYWxsIEFjY3VyYWN5OiAkeyhyZXN1bHRzLmFjY3VyYWN5ICogMTAwKS50b0ZpeGVkKDEpfSUgKCR7cmVzdWx0cy5jb3JyZWN0fS8ke3Jlc3VsdHMudG90YWxUZXN0c30pYC5wYWRFbmQoNjMpICsgJ+KVkScpO1xuICBsaW5lcy5wdXNoKCfilaDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilaMnKTtcbiAgbGluZXMucHVzaCgn4pWRICBCeSBDYXRlZ29yeTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilZEnKTtcblxuICBmb3IgKGNvbnN0IFtjYXQsIGFjY10gb2YgT2JqZWN0LmVudHJpZXMocmVzdWx0cy5hY2N1cmFjeUJ5Q2F0ZWdvcnkpLnNvcnQoKGEsIGIpID0+IGJbMV0gLSBhWzFdKSkge1xuICAgIGNvbnN0IGJhciA9ICfilognLnJlcGVhdChNYXRoLmZsb29yKGFjYyAqIDIwKSkgKyAn4paRJy5yZXBlYXQoMjAgLSBNYXRoLmZsb29yKGFjYyAqIDIwKSk7XG4gICAgbGluZXMucHVzaChg4pWRICAgICR7Y2F0LnBhZEVuZCgxOCl9IFske2Jhcn1dICR7KGFjYyAqIDEwMCkudG9GaXhlZCgwKS5wYWRTdGFydCgzKX0lICDilZFgKTtcbiAgfVxuXG4gIGxpbmVzLnB1c2goJ+KVoOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVoycpO1xuICBsaW5lcy5wdXNoKCfilZEgIEJ5IERpZmZpY3VsdHk6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKVkScpO1xuXG4gIGZvciAoY29uc3QgW2RpZmYsIGFjY10gb2YgT2JqZWN0LmVudHJpZXMocmVzdWx0cy5hY2N1cmFjeUJ5RGlmZmljdWx0eSkpIHtcbiAgICBjb25zdCBiYXIgPSAn4paIJy5yZXBlYXQoTWF0aC5mbG9vcihhY2MgKiAyMCkpICsgJ+KWkScucmVwZWF0KDIwIC0gTWF0aC5mbG9vcihhY2MgKiAyMCkpO1xuICAgIGxpbmVzLnB1c2goYOKVkSAgICAke2RpZmYucGFkRW5kKDE4KX0gWyR7YmFyfV0gJHsoYWNjICogMTAwKS50b0ZpeGVkKDApLnBhZFN0YXJ0KDMpfSUgIOKVkWApO1xuICB9XG5cbiAgbGluZXMucHVzaCgn4pWg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWjJyk7XG4gIGxpbmVzLnB1c2goJ+KVkSAgTGF0ZW5jeTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pWRJyk7XG4gIGxpbmVzLnB1c2goYOKVkSAgICBBdmVyYWdlOiAke3Jlc3VsdHMuYXZnTGF0ZW5jeU1zLnRvRml4ZWQoMil9bXNgLnBhZEVuZCg2MykgKyAn4pWRJyk7XG4gIGxpbmVzLnB1c2goYOKVkSAgICBQNTA6ICAgICAke3Jlc3VsdHMucDUwTGF0ZW5jeU1zLnRvRml4ZWQoMil9bXNgLnBhZEVuZCg2MykgKyAn4pWRJyk7XG4gIGxpbmVzLnB1c2goYOKVkSAgICBQOTU6ICAgICAke3Jlc3VsdHMucDk1TGF0ZW5jeU1zLnRvRml4ZWQoMil9bXNgLnBhZEVuZCg2MykgKyAn4pWRJyk7XG4gIGxpbmVzLnB1c2goJ+KVmuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVnScpO1xuXG4gIC8vIFNob3cgZmFpbHVyZXNcbiAgY29uc3QgZmFpbHVyZXMgPSByZXN1bHRzLnJlc3VsdHMuZmlsdGVyKHIgPT4gIXIuY29ycmVjdCk7XG4gIGlmIChmYWlsdXJlcy5sZW5ndGggPiAwICYmIGZhaWx1cmVzLmxlbmd0aCA8PSAyMCkge1xuICAgIGxpbmVzLnB1c2goJycpO1xuICAgIGxpbmVzLnB1c2goJ01pc3JvdXRlZCB0YXNrczonKTtcbiAgICBmb3IgKGNvbnN0IGYgb2YgZmFpbHVyZXMuc2xpY2UoMCwgMTApKSB7XG4gICAgICBsaW5lcy5wdXNoKGAgIFske2YudGVzdElkfV0gXCIke2YudGFzay5zbGljZSgwLCA1MCl9Li4uXCJgKTtcbiAgICAgIGxpbmVzLnB1c2goYCAgICAgICAgIEV4cGVjdGVkOiAke2YuZXhwZWN0ZWRBZ2VudH0sIEdvdDogJHtmLnByZWRpY3RlZEFnZW50fWApO1xuICAgIH1cbiAgICBpZiAoZmFpbHVyZXMubGVuZ3RoID4gMTApIHtcbiAgICAgIGxpbmVzLnB1c2goYCAgLi4uIGFuZCAke2ZhaWx1cmVzLmxlbmd0aCAtIDEwfSBtb3JlYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIFJPVVRJTkdfVEVTVF9DQVNFUyxcbiAgQUdFTlRfVFlQRVMsXG4gIGJhc2VsaW5lS2V5d29yZFJvdXRlcixcbiAgcnVuUm91dGluZ0JlbmNobWFyayxcbiAgZm9ybWF0Um91dGluZ1Jlc3VsdHMsXG59O1xuIl19