@zhixuan92/multi-model-agent-core 4.7.19 → 4.8.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 (219) hide show
  1. package/README.md +4 -4
  2. package/dist/config/schema.d.ts +2 -20
  3. package/dist/config/schema.d.ts.map +1 -1
  4. package/dist/config/schema.js +9 -80
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/events/task-envelope.d.ts +10 -1
  7. package/dist/events/task-envelope.d.ts.map +1 -1
  8. package/dist/events/task-envelope.js +4 -1
  9. package/dist/events/task-envelope.js.map +1 -1
  10. package/dist/events/wire-schema.d.ts +4 -0
  11. package/dist/events/wire-schema.d.ts.map +1 -1
  12. package/dist/events/wire-schema.js +3 -3
  13. package/dist/events/wire-schema.js.map +1 -1
  14. package/dist/journal/default-schema.d.ts +2 -0
  15. package/dist/journal/default-schema.d.ts.map +1 -0
  16. package/dist/journal/default-schema.js +27 -0
  17. package/dist/journal/default-schema.js.map +1 -0
  18. package/dist/journal/types.d.ts +22 -0
  19. package/dist/journal/types.d.ts.map +1 -0
  20. package/dist/journal/types.js +5 -0
  21. package/dist/journal/types.js.map +1 -0
  22. package/dist/lifecycle/annotate-parser.js +1 -1
  23. package/dist/lifecycle/annotate-parser.js.map +1 -1
  24. package/dist/lifecycle/derive-completion.js +1 -1
  25. package/dist/lifecycle/derive-completion.js.map +1 -1
  26. package/dist/lifecycle/handlers/annotate-stage.d.ts.map +1 -1
  27. package/dist/lifecycle/handlers/annotate-stage.js +9 -3
  28. package/dist/lifecycle/handlers/annotate-stage.js.map +1 -1
  29. package/dist/lifecycle/handlers/baseline-handlers.d.ts.map +1 -1
  30. package/dist/lifecycle/handlers/baseline-handlers.js +10 -0
  31. package/dist/lifecycle/handlers/baseline-handlers.js.map +1 -1
  32. package/dist/lifecycle/handlers/compose-commit-message.d.ts +15 -0
  33. package/dist/lifecycle/handlers/compose-commit-message.d.ts.map +1 -0
  34. package/dist/lifecycle/handlers/compose-commit-message.js +227 -0
  35. package/dist/lifecycle/handlers/compose-commit-message.js.map +1 -0
  36. package/dist/lifecycle/handlers/enrich-runtime-result.d.ts.map +1 -1
  37. package/dist/lifecycle/handlers/enrich-runtime-result.js +31 -0
  38. package/dist/lifecycle/handlers/enrich-runtime-result.js.map +1 -1
  39. package/dist/lifecycle/handlers/git-commit-handler.d.ts.map +1 -1
  40. package/dist/lifecycle/handlers/git-commit-handler.js +2 -15
  41. package/dist/lifecycle/handlers/git-commit-handler.js.map +1 -1
  42. package/dist/lifecycle/handlers/implement-stage.d.ts.map +1 -1
  43. package/dist/lifecycle/handlers/implement-stage.js +4 -1
  44. package/dist/lifecycle/handlers/implement-stage.js.map +1 -1
  45. package/dist/lifecycle/handlers/journal-review-prompt.d.ts +7 -0
  46. package/dist/lifecycle/handlers/journal-review-prompt.d.ts.map +1 -0
  47. package/dist/lifecycle/handlers/journal-review-prompt.js +54 -0
  48. package/dist/lifecycle/handlers/journal-review-prompt.js.map +1 -0
  49. package/dist/lifecycle/handlers/quality-review-prompt.d.ts +1 -0
  50. package/dist/lifecycle/handlers/quality-review-prompt.d.ts.map +1 -1
  51. package/dist/lifecycle/handlers/quality-review-prompt.js +8 -0
  52. package/dist/lifecycle/handlers/quality-review-prompt.js.map +1 -1
  53. package/dist/lifecycle/handlers/review-stage.d.ts.map +1 -1
  54. package/dist/lifecycle/handlers/review-stage.js +57 -13
  55. package/dist/lifecycle/handlers/review-stage.js.map +1 -1
  56. package/dist/lifecycle/handlers/rework-stage.d.ts.map +1 -1
  57. package/dist/lifecycle/handlers/rework-stage.js +3 -0
  58. package/dist/lifecycle/handlers/rework-stage.js.map +1 -1
  59. package/dist/lifecycle/handlers/spec-review-prompt.d.ts +1 -0
  60. package/dist/lifecycle/handlers/spec-review-prompt.d.ts.map +1 -1
  61. package/dist/lifecycle/handlers/spec-review-prompt.js +8 -0
  62. package/dist/lifecycle/handlers/spec-review-prompt.js.map +1 -1
  63. package/dist/lifecycle/handlers/terminal-handlers.d.ts +25 -1
  64. package/dist/lifecycle/handlers/terminal-handlers.d.ts.map +1 -1
  65. package/dist/lifecycle/handlers/terminal-handlers.js +55 -19
  66. package/dist/lifecycle/handlers/terminal-handlers.js.map +1 -1
  67. package/dist/lifecycle/perform-implementation.d.ts.map +1 -1
  68. package/dist/lifecycle/perform-implementation.js +7 -4
  69. package/dist/lifecycle/perform-implementation.js.map +1 -1
  70. package/dist/lifecycle/read-route-criteria.d.ts +3 -2
  71. package/dist/lifecycle/read-route-criteria.d.ts.map +1 -1
  72. package/dist/lifecycle/read-route-criteria.js +2 -0
  73. package/dist/lifecycle/read-route-criteria.js.map +1 -1
  74. package/dist/lifecycle/research-pre-loop.d.ts +5 -4
  75. package/dist/lifecycle/research-pre-loop.d.ts.map +1 -1
  76. package/dist/lifecycle/research-pre-loop.js +7 -10
  77. package/dist/lifecycle/research-pre-loop.js.map +1 -1
  78. package/dist/lifecycle/stage-io.d.ts +8 -4
  79. package/dist/lifecycle/stage-io.d.ts.map +1 -1
  80. package/dist/lifecycle/stage-io.js +2 -2
  81. package/dist/lifecycle/stage-io.js.map +1 -1
  82. package/dist/lifecycle/stage-plan-types.d.ts +1 -1
  83. package/dist/lifecycle/stage-plan-types.d.ts.map +1 -1
  84. package/dist/lifecycle/stage-progression.d.ts.map +1 -1
  85. package/dist/lifecycle/stage-progression.js +2 -0
  86. package/dist/lifecycle/stage-progression.js.map +1 -1
  87. package/dist/lifecycle/task-runner.d.ts.map +1 -1
  88. package/dist/lifecycle/task-runner.js +6 -1
  89. package/dist/lifecycle/task-runner.js.map +1 -1
  90. package/dist/lifecycle/worker-output-contract.d.ts +3 -1
  91. package/dist/lifecycle/worker-output-contract.d.ts.map +1 -1
  92. package/dist/lifecycle/worker-output-contract.js +4 -1
  93. package/dist/lifecycle/worker-output-contract.js.map +1 -1
  94. package/dist/reporting/headline-templates/journal-recall.d.ts +3 -0
  95. package/dist/reporting/headline-templates/journal-recall.d.ts.map +1 -0
  96. package/dist/reporting/headline-templates/journal-recall.js +9 -0
  97. package/dist/reporting/headline-templates/journal-recall.js.map +1 -0
  98. package/dist/reporting/headline-templates/journal.d.ts +3 -0
  99. package/dist/reporting/headline-templates/journal.d.ts.map +1 -0
  100. package/dist/reporting/headline-templates/journal.js +17 -0
  101. package/dist/reporting/headline-templates/journal.js.map +1 -0
  102. package/dist/reporting/report-parser-slots/journal-report.d.ts +8 -0
  103. package/dist/reporting/report-parser-slots/journal-report.d.ts.map +1 -0
  104. package/dist/reporting/report-parser-slots/journal-report.js +12 -0
  105. package/dist/reporting/report-parser-slots/journal-report.js.map +1 -0
  106. package/dist/reporting/terminal-report-markdown.d.ts +13 -0
  107. package/dist/reporting/terminal-report-markdown.d.ts.map +1 -0
  108. package/dist/reporting/terminal-report-markdown.js +31 -0
  109. package/dist/reporting/terminal-report-markdown.js.map +1 -0
  110. package/dist/research/adapters/index.d.ts +0 -1
  111. package/dist/research/adapters/index.d.ts.map +1 -1
  112. package/dist/research/adapters/index.js +0 -3
  113. package/dist/research/adapters/index.js.map +1 -1
  114. package/dist/research/adapters/types.d.ts +1 -1
  115. package/dist/research/adapters/types.d.ts.map +1 -1
  116. package/dist/research/evidence-pack.d.ts +19 -1
  117. package/dist/research/evidence-pack.d.ts.map +1 -1
  118. package/dist/research/evidence-pack.js +36 -1
  119. package/dist/research/evidence-pack.js.map +1 -1
  120. package/dist/research/orchestrator.d.ts +0 -4
  121. package/dist/research/orchestrator.d.ts.map +1 -1
  122. package/dist/research/orchestrator.js +4 -53
  123. package/dist/research/orchestrator.js.map +1 -1
  124. package/dist/research/query-plan.d.ts +0 -2
  125. package/dist/research/query-plan.d.ts.map +1 -1
  126. package/dist/research/query-plan.js +1 -8
  127. package/dist/research/query-plan.js.map +1 -1
  128. package/dist/research/user-agent.js +1 -1
  129. package/dist/research/user-agent.js.map +1 -1
  130. package/dist/research/web-search.d.ts +2 -1
  131. package/dist/research/web-search.d.ts.map +1 -1
  132. package/dist/research/web-search.js +31 -7
  133. package/dist/research/web-search.js.map +1 -1
  134. package/dist/stores/batch-registry.d.ts +1 -1
  135. package/dist/stores/batch-registry.d.ts.map +1 -1
  136. package/dist/stores/batch-registry.js +4 -4
  137. package/dist/stores/batch-registry.js.map +1 -1
  138. package/dist/tool-surface/register-all-tools.d.ts.map +1 -1
  139. package/dist/tool-surface/register-all-tools.js +4 -0
  140. package/dist/tool-surface/register-all-tools.js.map +1 -1
  141. package/dist/tools/delegate/brief-slot.d.ts +3 -0
  142. package/dist/tools/delegate/brief-slot.d.ts.map +1 -1
  143. package/dist/tools/delegate/brief-slot.js +1 -0
  144. package/dist/tools/delegate/brief-slot.js.map +1 -1
  145. package/dist/tools/delegate/tool-config.d.ts.map +1 -1
  146. package/dist/tools/delegate/tool-config.js +1 -0
  147. package/dist/tools/delegate/tool-config.js.map +1 -1
  148. package/dist/tools/execute-plan/tool-config.d.ts.map +1 -1
  149. package/dist/tools/execute-plan/tool-config.js +3 -0
  150. package/dist/tools/execute-plan/tool-config.js.map +1 -1
  151. package/dist/tools/journal/recall/brief-slot.d.ts +7 -0
  152. package/dist/tools/journal/recall/brief-slot.d.ts.map +1 -0
  153. package/dist/tools/journal/recall/brief-slot.js +5 -0
  154. package/dist/tools/journal/recall/brief-slot.js.map +1 -0
  155. package/dist/tools/journal/recall/implementer-criteria.d.ts +9 -0
  156. package/dist/tools/journal/recall/implementer-criteria.d.ts.map +1 -0
  157. package/dist/tools/journal/recall/implementer-criteria.js +23 -0
  158. package/dist/tools/journal/recall/implementer-criteria.js.map +1 -0
  159. package/dist/tools/journal/recall/schema.d.ts +54 -0
  160. package/dist/tools/journal/recall/schema.d.ts.map +1 -0
  161. package/dist/tools/journal/recall/schema.js +10 -0
  162. package/dist/tools/journal/recall/schema.js.map +1 -0
  163. package/dist/tools/journal/recall/subtypes.d.ts +4 -0
  164. package/dist/tools/journal/recall/subtypes.d.ts.map +1 -0
  165. package/dist/tools/journal/recall/subtypes.js +25 -0
  166. package/dist/tools/journal/recall/subtypes.js.map +1 -0
  167. package/dist/tools/journal/recall/tool-config.d.ts +8 -0
  168. package/dist/tools/journal/recall/tool-config.d.ts.map +1 -0
  169. package/dist/tools/journal/recall/tool-config.js +46 -0
  170. package/dist/tools/journal/recall/tool-config.js.map +1 -0
  171. package/dist/tools/journal/record/brief-slot.d.ts +14 -0
  172. package/dist/tools/journal/record/brief-slot.d.ts.map +1 -0
  173. package/dist/tools/journal/record/brief-slot.js +18 -0
  174. package/dist/tools/journal/record/brief-slot.js.map +1 -0
  175. package/dist/tools/journal/record/implementer-criteria.d.ts +6 -0
  176. package/dist/tools/journal/record/implementer-criteria.d.ts.map +1 -0
  177. package/dist/tools/journal/record/implementer-criteria.js +17 -0
  178. package/dist/tools/journal/record/implementer-criteria.js.map +1 -0
  179. package/dist/tools/journal/record/schema.d.ts +55 -0
  180. package/dist/tools/journal/record/schema.d.ts.map +1 -0
  181. package/dist/tools/journal/record/schema.js +13 -0
  182. package/dist/tools/journal/record/schema.js.map +1 -0
  183. package/dist/tools/journal/record/tool-config.d.ts +7 -0
  184. package/dist/tools/journal/record/tool-config.d.ts.map +1 -0
  185. package/dist/tools/journal/record/tool-config.js +40 -0
  186. package/dist/tools/journal/record/tool-config.js.map +1 -0
  187. package/dist/tools/research/brief-slot.d.ts +0 -2
  188. package/dist/tools/research/brief-slot.d.ts.map +1 -1
  189. package/dist/tools/research/brief-slot.js.map +1 -1
  190. package/dist/tools/research/implementer-criteria.d.ts +0 -1
  191. package/dist/tools/research/implementer-criteria.d.ts.map +1 -1
  192. package/dist/tools/research/implementer-criteria.js +3 -15
  193. package/dist/tools/research/implementer-criteria.js.map +1 -1
  194. package/dist/tools/research/tool-config.d.ts.map +1 -1
  195. package/dist/tools/research/tool-config.js +0 -1
  196. package/dist/tools/research/tool-config.js.map +1 -1
  197. package/dist/types/task-spec.d.ts +2 -1
  198. package/dist/types/task-spec.d.ts.map +1 -1
  199. package/package.json +17 -1
  200. package/dist/research/adapters/generic-rss.d.ts +0 -8
  201. package/dist/research/adapters/generic-rss.d.ts.map +0 -1
  202. package/dist/research/adapters/generic-rss.js +0 -26
  203. package/dist/research/adapters/generic-rss.js.map +0 -1
  204. package/dist/research/ssrf-guard.d.ts +0 -12
  205. package/dist/research/ssrf-guard.d.ts.map +0 -1
  206. package/dist/research/ssrf-guard.js +0 -209
  207. package/dist/research/ssrf-guard.js.map +0 -1
  208. package/dist/research/untrusted-content.d.ts +0 -13
  209. package/dist/research/untrusted-content.d.ts.map +0 -1
  210. package/dist/research/untrusted-content.js +0 -9
  211. package/dist/research/untrusted-content.js.map +0 -1
  212. package/dist/research/web-fetch-helpers.d.ts +0 -44
  213. package/dist/research/web-fetch-helpers.d.ts.map +0 -1
  214. package/dist/research/web-fetch-helpers.js +0 -209
  215. package/dist/research/web-fetch-helpers.js.map +0 -1
  216. package/dist/research/web-fetch.d.ts +0 -55
  217. package/dist/research/web-fetch.d.ts.map +0 -1
  218. package/dist/research/web-fetch.js +0 -236
  219. package/dist/research/web-fetch.js.map +0 -1
@@ -1,209 +0,0 @@
1
- import { isIP } from 'node:net';
2
- import { promises as dns } from 'node:dns';
3
- export class SsrfBlocked extends Error {
4
- code;
5
- constructor(code, message) {
6
- super(message);
7
- this.code = code;
8
- this.name = 'SsrfBlocked';
9
- }
10
- }
11
- function ipv4ToInt(ip) {
12
- const parts = ip.split('.').map(Number);
13
- if (parts.length !== 4 || parts.some(p => Number.isNaN(p) || p < 0 || p > 255))
14
- return null;
15
- return ((parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]) >>> 0;
16
- }
17
- const inRange = (n, base, mask) => {
18
- const b = ipv4ToInt(base);
19
- if (b === null)
20
- return false;
21
- const m = mask === 0 ? 0 : (~0 << (32 - mask)) >>> 0;
22
- return (n & m) === (b & m);
23
- };
24
- const IPV4_SPECIAL_RANGES = [
25
- ['0.0.0.0', 8, 'unspecified'],
26
- ['127.0.0.0', 8, 'loopback'],
27
- ['10.0.0.0', 8, 'private'],
28
- ['172.16.0.0', 12, 'private'],
29
- ['192.168.0.0', 16, 'private'],
30
- ['100.64.0.0', 10, 'private'], // RFC 6598 CGNAT; opt-in allowable with private hosts.
31
- ['169.254.0.0', 16, 'link-local-or-metadata'],
32
- // IANA IPv4 special-purpose ranges that are not normal public internet destinations.
33
- ['192.0.0.0', 24, 'broadcast-or-reserved'],
34
- ['192.0.2.0', 24, 'broadcast-or-reserved'], // TEST-NET-1
35
- ['198.18.0.0', 15, 'broadcast-or-reserved'], // benchmarking
36
- ['198.51.100.0', 24, 'broadcast-or-reserved'], // TEST-NET-2
37
- ['203.0.113.0', 24, 'broadcast-or-reserved'], // TEST-NET-3
38
- ['224.0.0.0', 4, 'multicast'],
39
- ['240.0.0.0', 4, 'broadcast-or-reserved'],
40
- ];
41
- /**
42
- * Extract a 32-bit unsigned int from a 4-hex-group region of an expanded IPv6
43
- * address (used for IPv4-mapped and 6to4 embedded-IPv4 extraction).
44
- *
45
- * Returns null on malformed input. The caller stringifies back to dotted-quad
46
- * via classifyIP, so we don't need pretty formatting here.
47
- */
48
- function expandIPv6Groups(addr) {
49
- // Split on '::' (at most once); pad missing groups with '0'.
50
- const halves = addr.split('::');
51
- if (halves.length > 2)
52
- return null;
53
- const left = halves[0] ? halves[0].split(':') : [];
54
- const right = halves.length === 2 && halves[1] ? halves[1].split(':') : [];
55
- const fill = 8 - (left.length + right.length);
56
- if (fill < 0)
57
- return null;
58
- if (halves.length === 1 && left.length !== 8)
59
- return null;
60
- return [...left, ...Array(fill).fill('0'), ...right]
61
- .map((g) => g.padStart(4, '0').toLowerCase());
62
- }
63
- function groupsToIPv4(g, startGroup) {
64
- if (g.length < startGroup + 2)
65
- return null;
66
- const hi = parseInt(g[startGroup], 16);
67
- const lo = parseInt(g[startGroup + 1], 16);
68
- if (Number.isNaN(hi) || Number.isNaN(lo))
69
- return null;
70
- const a = (hi >> 8) & 0xff, b = hi & 0xff, c = (lo >> 8) & 0xff, d = lo & 0xff;
71
- return `${a}.${b}.${c}.${d}`;
72
- }
73
- export function classifyIP(ip) {
74
- const lower = ip.toLowerCase();
75
- // Cloud-metadata ULAs (informal cloud-provider conventions; not IANA-registered)
76
- // Checked before isIP because these patterns may use non-hex tokens like 'gcp'/'az'.
77
- if (/^fd00:(ec2|gcp|az):/.test(lower))
78
- return 'link-local-or-metadata';
79
- const v = isIP(ip);
80
- if (v === 4) {
81
- const n = ipv4ToInt(ip);
82
- if (n === null)
83
- return 'broadcast-or-reserved';
84
- if (n === 0xffffffff)
85
- return 'broadcast-or-reserved';
86
- for (const [base, mask, klass] of IPV4_SPECIAL_RANGES) {
87
- if (inRange(n, base, mask))
88
- return klass;
89
- }
90
- return 'public';
91
- }
92
- if (v === 6) {
93
- if (lower === '::')
94
- return 'unspecified';
95
- if (lower === '::1')
96
- return 'loopback';
97
- // IPv4-mapped IPv6 (::ffff:a.b.c.d or ::ffff:HEXHEX:HEXHEX) — recurse on embedded IPv4
98
- const v4mapped = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
99
- if (v4mapped)
100
- return classifyIP(v4mapped[1]);
101
- const groups = expandIPv6Groups(lower);
102
- if (groups && groups[0] === '0000' && groups[1] === '0000' && groups[2] === '0000'
103
- && groups[3] === '0000' && groups[4] === '0000' && groups[5] === 'ffff') {
104
- const embedded = groupsToIPv4(groups, 6);
105
- if (embedded)
106
- return classifyIP(embedded);
107
- }
108
- // 6to4 (2002::/16) — embeds IPv4 at bits 16–47 (groups 1 + 2). Recurse.
109
- if (groups && groups[0] === '2002') {
110
- const embedded = groupsToIPv4(groups, 1);
111
- if (embedded)
112
- return classifyIP(embedded);
113
- }
114
- // fe80::/10 link-local (covers fe80–febf when interpreted strictly).
115
- if (groups && /^fe[89ab]/.test(groups[0]))
116
- return 'link-local-or-metadata';
117
- // Locally-assigned ULA (fc00::/8) and randomly-assigned ULA (fd00::/8) → 'private'.
118
- // The opt-in policy in spec §7.1 step 8 distinguishes these two halves;
119
- // classifyIP only reports membership in the conditional-reject set.
120
- if (groups && (groups[0].startsWith('fc') || groups[0].startsWith('fd'))) {
121
- return 'private';
122
- }
123
- if (lower.startsWith('ff'))
124
- return 'multicast';
125
- // IANA IPv6 special-purpose ranges that are not normal public internet destinations.
126
- if (groups && groups[0] === '2001' && groups[1] === '0db8')
127
- return 'broadcast-or-reserved';
128
- if (groups && groups[0] === '2001' && /^0[0-1]/.test(groups[1] ?? ''))
129
- return 'broadcast-or-reserved';
130
- // Note: `fec0::/10` was a deprecated site-local block (RFC 3879). Modern
131
- // unicast addresses outside fc00::/7 (e.g. `fec1::1`) are **routable**
132
- // under current IANA allocations — classify as public, NOT link-local.
133
- return 'public';
134
- }
135
- return 'broadcast-or-reserved';
136
- }
137
- const isNoRecordsError = (error) => {
138
- const code = error?.code;
139
- return code === 'ENODATA' || code === 'ENOTFOUND' || code === 'ESERVFAIL';
140
- };
141
- const defaultResolve = async (host) => {
142
- const [v4, v6] = await Promise.allSettled([
143
- dns.resolve4(host),
144
- dns.resolve6(host),
145
- ]);
146
- const results = [];
147
- if (v4.status === 'fulfilled')
148
- results.push(...v4.value);
149
- if (v6.status === 'fulfilled')
150
- results.push(...v6.value);
151
- if (results.length > 0)
152
- return results;
153
- const failures = [v4, v6].filter((r) => r.status === 'rejected');
154
- if (failures.length > 0 && failures.some((r) => !isNoRecordsError(r.reason))) {
155
- throw new Error('DNS resolution failed');
156
- }
157
- return results;
158
- };
159
- const BLOCKED_CLASSES_STRICT = new Set([
160
- 'loopback',
161
- 'private',
162
- 'link-local-or-metadata',
163
- 'unspecified',
164
- 'multicast',
165
- 'broadcast-or-reserved',
166
- ]);
167
- const BLOCKED_CLASSES_PERMISSIVE = new Set([
168
- 'loopback',
169
- 'link-local-or-metadata',
170
- 'unspecified',
171
- 'multicast',
172
- 'broadcast-or-reserved',
173
- ]);
174
- function isLocallyAssignedULA(ip) {
175
- if (isIP(ip) !== 6)
176
- return false;
177
- const groups = expandIPv6Groups(ip.toLowerCase());
178
- if (!groups)
179
- return false;
180
- return groups[0].startsWith('fc');
181
- }
182
- export async function resolveAndPin(host, options) {
183
- const resolve = options.resolve ?? defaultResolve;
184
- let ips;
185
- try {
186
- ips = await resolve(host);
187
- }
188
- catch {
189
- throw new SsrfBlocked('web_fetch_dns_resolution_failed', `web_fetch_dns_resolution_failed: DNS resolution failed for host '${host}'`);
190
- }
191
- if (ips.length === 0) {
192
- throw new SsrfBlocked('web_fetch_no_addresses', `web_fetch_no_addresses: no addresses resolved for host '${host}'`);
193
- }
194
- const blocked = options.allowPrivateForHost
195
- ? BLOCKED_CLASSES_PERMISSIVE
196
- : BLOCKED_CLASSES_STRICT;
197
- for (const ip of ips) {
198
- const klass = classifyIP(ip);
199
- if (blocked.has(klass)) {
200
- throw new SsrfBlocked('web_fetch_private_ip_blocked', `web_fetch_private_ip_blocked: resolved IP class '${klass}' is not allowed for host '${host}'`);
201
- }
202
- // fc00::/8 locally-assigned ULA is always-reject, even in permissive mode
203
- if (isLocallyAssignedULA(ip)) {
204
- throw new SsrfBlocked('web_fetch_private_ip_blocked', `web_fetch_private_ip_blocked: resolved IP is locally-assigned ULA (fc00::/8), which is never allowed for host '${host}'`);
205
- }
206
- }
207
- return ips[0];
208
- }
209
- //# sourceMappingURL=ssrf-guard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ssrf-guard.js","sourceRoot":"","sources":["../../src/research/ssrf-guard.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- export interface FetchedContent {
2
- url: string;
3
- host: string;
4
- content: string;
5
- }
6
- export declare function wrapFetchedContent(c: FetchedContent): string;
7
- export interface SearchHit {
8
- title: string;
9
- url: string;
10
- snippet: string;
11
- }
12
- export declare function wrapSearchResults(hits: readonly SearchHit[]): string;
13
- //# sourceMappingURL=untrusted-content.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"untrusted-content.d.ts","sourceRoot":"","sources":["../../src/research/untrusted-content.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAEpE"}
@@ -1,9 +0,0 @@
1
- const escapeAttr = (s) => s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
2
- const escapeBody = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
3
- export function wrapFetchedContent(c) {
4
- return `<external-content url="${escapeAttr(c.url)}" host="${escapeAttr(c.host)}" trustLevel="untrusted">${escapeBody(c.content)}</external-content>`;
5
- }
6
- export function wrapSearchResults(hits) {
7
- return `<external-search-results trustLevel="untrusted">${escapeBody(JSON.stringify(hits))}</external-search-results>`;
8
- }
9
- //# sourceMappingURL=untrusted-content.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"untrusted-content.js","sourceRoot":"","sources":["../../src/research/untrusted-content.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,EAAE,CAC/B,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAE/F,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,EAAE,CAC/B,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAQvE,MAAM,UAAU,kBAAkB,CAAC,CAAiB;IAClD,OAAO,0BAA0B,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;AACxJ,CAAC;AAQD,MAAM,UAAU,iBAAiB,CAAC,IAA0B;IAC1D,OAAO,mDAAmD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,4BAA4B,CAAC;AACzH,CAAC"}
@@ -1,44 +0,0 @@
1
- import type { WebFetchInput, WebFetchErr } from './web-fetch.js';
2
- /** Max bytes to drain from a redirect response body before giving up. */
3
- export declare const REDIRECT_DRAIN_CAP: number;
4
- export declare const REDIRECT_ERR_CODE_MAP: Record<string, string>;
5
- export interface ValidatedURL {
6
- ok: true;
7
- url: URL;
8
- host: string;
9
- pinnedIP: string;
10
- }
11
- export interface ValidationFailed {
12
- ok: false;
13
- reasonCode: string;
14
- host?: string;
15
- }
16
- /**
17
- * Races a promise against an AbortSignal. If the signal fires first, throws
18
- * a DOMException with name 'AbortError' so callers can map it to timeout.
19
- */
20
- export declare function withDeadline<T>(promise: Promise<T>, signal: AbortSignal): Promise<T>;
21
- export declare function validateAndPinURL(raw: string, hostAllowlist: ReadonlySet<string>, privateNetworkHosts: ReadonlySet<string>, resolveIP: WebFetchInput['resolveIP'], signal: AbortSignal): Promise<ValidatedURL | ValidationFailed>;
22
- export declare function extractContentType(headers: Record<string, string | string[] | undefined>): string;
23
- export declare function isRedirect(status: number): boolean;
24
- export declare function extractLocation(headers: Record<string, string | string[] | undefined>): string | null;
25
- export declare function extractBodyFromHTML(html: string): string;
26
- export declare function stripCredentialsFromURL(url: URL): boolean;
27
- /**
28
- * Read a response body with a byte cap and abort-signal awareness.
29
- * Stream errors (non-abort) are re-thrown so the caller can map them to
30
- * web_fetch_body_read_failed rather than silently returning partial content.
31
- */
32
- export declare function readBody(body: AsyncIterable<Uint8Array | string> | null, maxBytes: number, signal: AbortSignal): Promise<{
33
- text: string;
34
- bytesReturned: number;
35
- truncated: boolean;
36
- }>;
37
- /**
38
- * Drain a response body with a size cap and abort-signal awareness.
39
- * Used for redirect responses and rejected content types.
40
- */
41
- export declare function drainBody(body: AsyncIterable<unknown> | null, signal: AbortSignal): Promise<void>;
42
- export declare function isUndiciTimeout(err: unknown): boolean;
43
- export declare function mapRequestError(err: unknown, signal: AbortSignal, host: string): WebFetchErr;
44
- //# sourceMappingURL=web-fetch-helpers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-fetch-helpers.d.ts","sourceRoot":"","sources":["../../src/research/web-fetch-helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEjE,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAE5C,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOxD,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,IAAI,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAgB1F;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,EAClC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,EACxC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,EACrC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,GAAG,gBAAgB,CAAC,CAsC1C;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM,CASjG;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,CAKrG;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBxD;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAKzD;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,aAAa,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,EAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAkCtE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,EACnC,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMrD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAW5F"}
@@ -1,209 +0,0 @@
1
- import { isIP } from 'node:net';
2
- import { Readability } from '@mozilla/readability';
3
- import { JSDOM } from 'jsdom';
4
- import { resolveAndPin, SsrfBlocked } from './ssrf-guard.js';
5
- /** Max bytes to drain from a redirect response body before giving up. */
6
- export const REDIRECT_DRAIN_CAP = 64 * 1024;
7
- export const REDIRECT_ERR_CODE_MAP = {
8
- web_fetch_off_allowlist: 'web_fetch_redirect_off_allowlist',
9
- web_fetch_invalid_url: 'web_fetch_redirect_invalid_url',
10
- web_fetch_invalid_scheme: 'web_fetch_redirect_scheme_downgrade',
11
- web_fetch_ip_literal_blocked: 'web_fetch_redirect_ip_literal_blocked',
12
- web_fetch_private_ip_blocked: 'web_fetch_redirect_private_ip_blocked',
13
- web_fetch_reserved_ip_blocked: 'web_fetch_redirect_reserved_ip_blocked',
14
- };
15
- /**
16
- * Races a promise against an AbortSignal. If the signal fires first, throws
17
- * a DOMException with name 'AbortError' so callers can map it to timeout.
18
- */
19
- export async function withDeadline(promise, signal) {
20
- if (signal.aborted)
21
- throw new DOMException('Aborted', 'AbortError');
22
- return new Promise((resolve, reject) => {
23
- const onAbort = () => reject(new DOMException('Aborted', 'AbortError'));
24
- signal.addEventListener('abort', onAbort, { once: true });
25
- promise.then((result) => {
26
- signal.removeEventListener('abort', onAbort);
27
- resolve(result);
28
- }, (err) => {
29
- signal.removeEventListener('abort', onAbort);
30
- reject(err);
31
- });
32
- });
33
- }
34
- export async function validateAndPinURL(raw, hostAllowlist, privateNetworkHosts, resolveIP, signal) {
35
- let url;
36
- try {
37
- url = new URL(raw);
38
- }
39
- catch {
40
- return { ok: false, reasonCode: 'web_fetch_invalid_url' };
41
- }
42
- if (url.protocol !== 'https:') {
43
- return { ok: false, reasonCode: 'web_fetch_invalid_scheme' };
44
- }
45
- const stripped = url.hostname.replace(/^\[|\]$/g, '');
46
- if (isIP(stripped) !== 0) {
47
- return { ok: false, reasonCode: 'web_fetch_ip_literal_blocked' };
48
- }
49
- const host = url.hostname.toLowerCase();
50
- if (!hostAllowlist.has(host)) {
51
- return { ok: false, reasonCode: 'web_fetch_off_allowlist', host };
52
- }
53
- const allowPrivate = privateNetworkHosts.has(host);
54
- let pinnedIP;
55
- try {
56
- pinnedIP = await withDeadline(resolveAndPin(host, {
57
- resolve: resolveIP ? async (h) => [await resolveIP(h)] : undefined,
58
- allowPrivateForHost: allowPrivate,
59
- }), signal);
60
- }
61
- catch (e) {
62
- if (e instanceof DOMException && e.name === 'AbortError') {
63
- throw e;
64
- }
65
- if (e instanceof SsrfBlocked) {
66
- return { ok: false, reasonCode: e.code, host };
67
- }
68
- return { ok: false, reasonCode: 'web_fetch_dns_resolution_failed', host };
69
- }
70
- return { ok: true, url, host, pinnedIP };
71
- }
72
- export function extractContentType(headers) {
73
- const raw = headers['content-type'];
74
- if (typeof raw === 'string') {
75
- return raw.split(';')[0].trim().toLowerCase();
76
- }
77
- if (Array.isArray(raw) && raw.length > 0) {
78
- return String(raw[0]).split(';')[0].trim().toLowerCase();
79
- }
80
- return '';
81
- }
82
- export function isRedirect(status) {
83
- return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
84
- }
85
- export function extractLocation(headers) {
86
- const loc = headers['location'];
87
- if (typeof loc === 'string')
88
- return loc;
89
- if (Array.isArray(loc) && loc.length > 0)
90
- return String(loc[0]);
91
- return null;
92
- }
93
- export function extractBodyFromHTML(html) {
94
- let dom;
95
- try {
96
- dom = new JSDOM(html, { url: 'https://localhost/' });
97
- const reader = new Readability(dom.window.document);
98
- const article = reader.parse();
99
- if (article?.textContent) {
100
- return article.textContent;
101
- }
102
- return dom.window.document.body?.textContent?.trim() ?? html;
103
- }
104
- catch {
105
- try {
106
- return dom?.window.document.body?.textContent?.trim() || html;
107
- }
108
- catch {
109
- return html;
110
- }
111
- }
112
- }
113
- export function stripCredentialsFromURL(url) {
114
- if (!url.username && !url.password)
115
- return false;
116
- url.username = '';
117
- url.password = '';
118
- return true;
119
- }
120
- /**
121
- * Read a response body with a byte cap and abort-signal awareness.
122
- * Stream errors (non-abort) are re-thrown so the caller can map them to
123
- * web_fetch_body_read_failed rather than silently returning partial content.
124
- */
125
- export async function readBody(body, maxBytes, signal) {
126
- if (!body)
127
- return { text: '', bytesReturned: 0, truncated: false };
128
- const chunks = [];
129
- let total = 0;
130
- let truncated = false;
131
- for await (const chunk of body) {
132
- if (signal.aborted) {
133
- throw new DOMException('Aborted', 'AbortError');
134
- }
135
- const remaining = maxBytes - total;
136
- if (remaining <= 0) {
137
- truncated = true;
138
- break;
139
- }
140
- const value = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
141
- if (value.length > remaining) {
142
- chunks.push(value.subarray(0, remaining));
143
- total += remaining;
144
- truncated = true;
145
- break;
146
- }
147
- chunks.push(value);
148
- total += value.length;
149
- }
150
- const decoder = new TextDecoder();
151
- let text = '';
152
- for (const chunk of chunks) {
153
- text += decoder.decode(chunk, { stream: true });
154
- }
155
- text += decoder.decode();
156
- return { text, bytesReturned: total, truncated };
157
- }
158
- /**
159
- * Drain a response body with a size cap and abort-signal awareness.
160
- * Used for redirect responses and rejected content types.
161
- */
162
- export async function drainBody(body, signal) {
163
- if (!body)
164
- return;
165
- let drained = 0;
166
- try {
167
- for await (const chunk of body) {
168
- if (signal.aborted)
169
- break;
170
- let len = 0;
171
- if (typeof chunk === 'string') {
172
- len = Buffer.byteLength(chunk);
173
- }
174
- else if (chunk instanceof Uint8Array) {
175
- len = chunk.length;
176
- }
177
- else if (Buffer.isBuffer(chunk)) {
178
- len = chunk.length;
179
- }
180
- drained += len;
181
- if (drained > REDIRECT_DRAIN_CAP)
182
- break;
183
- }
184
- }
185
- catch {
186
- // drain errors are ignorable
187
- }
188
- }
189
- export function isUndiciTimeout(err) {
190
- if (!(err instanceof Error))
191
- return false;
192
- const code = err.code;
193
- return code === 'UND_ERR_CONNECT_TIMEOUT'
194
- || code === 'UND_ERR_HEADERS_TIMEOUT'
195
- || code === 'UND_ERR_BODY_TIMEOUT';
196
- }
197
- export function mapRequestError(err, signal, host) {
198
- if (signal.aborted) {
199
- return { status: 'error', reasonCode: 'web_fetch_timeout', host, credentialsStripped: false };
200
- }
201
- if (err instanceof DOMException && err.name === 'AbortError') {
202
- return { status: 'error', reasonCode: 'web_fetch_timeout', host, credentialsStripped: false };
203
- }
204
- if (isUndiciTimeout(err)) {
205
- return { status: 'error', reasonCode: 'web_fetch_timeout', host, credentialsStripped: false };
206
- }
207
- return { status: 'error', reasonCode: 'web_fetch_request_failed', host, credentialsStripped: false };
208
- }
209
- //# sourceMappingURL=web-fetch-helpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-fetch-helpers.js","sourceRoot":"","sources":["../../src/research/web-fetch-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,55 +0,0 @@
1
- import type { LookupFunction } from 'node:net';
2
- import type { ResearchConfig } from '../config/schema.js';
3
- export interface WebFetchInput {
4
- url: string;
5
- cfg: ResearchConfig['fetch'];
6
- hostAllowlist: ReadonlySet<string>;
7
- privateNetworkHosts?: ReadonlySet<string>;
8
- resolveIP?: (host: string) => Promise<string>;
9
- /** Test seam — when present, treated as the IP that the connect callback
10
- * "resolved" at request time. Production must not pass this. */
11
- _testConnectResolvedIp?: string;
12
- /** Test-only injection seam. When set, webFetch uses the returned dispatcher
13
- * (or, if it returns undefined, no dispatcher — so undici's global MockAgent
14
- * can intercept). Production never sets this: it always uses the connect-guard
15
- * agent built in webFetch(). */
16
- createDispatcher?: (host: string, pinnedIP: string, cfg: ResearchConfig['fetch']) => import('undici').Dispatcher | undefined;
17
- }
18
- export type WebFetchOk = {
19
- status: 'ok';
20
- body: string;
21
- rawText: string;
22
- host: string;
23
- bytesReturned: number;
24
- truncated: boolean;
25
- textTruncated: boolean;
26
- credentialsStripped: boolean;
27
- };
28
- export type WebFetchErr = {
29
- status: 'error';
30
- reasonCode: string;
31
- host?: string;
32
- credentialsStripped: boolean;
33
- };
34
- export type WebFetchResult = WebFetchOk | WebFetchErr;
35
- /**
36
- * Build the SSRF-revalidating `connect.lookup` for the guard agent.
37
- *
38
- * undici invokes `connect.lookup` with `{ all: true }` and expects the callback
39
- * to receive an ARRAY of `{ address, family }` entries — NOT the single-result
40
- * `dns.lookup(host, (err, address, family) => ...)` form. Returning a bare
41
- * address string makes undici read `addresses[0].address === undefined`, throw
42
- * `ERR_INVALID_IP_ADDRESS`, and surface as `web_fetch_request_failed`. Every
43
- * callback path here therefore returns the array form.
44
- *
45
- * Typed as `net.LookupFunction` — the exact type undici's `connect.lookup`
46
- * field accepts. On error paths we pass an empty address array (undici reads
47
- * `err` first and never consumes the addresses), which keeps the runtime
48
- * contract while satisfying the callback's required address argument.
49
- *
50
- * Exported for unit testing — it locks the undici lookup contract without
51
- * requiring real network (see tests/research/web-fetch.test.ts).
52
- */
53
- export declare function makeConnectGuardLookup(allowPrivateNetwork: boolean, testResolvedIp: string | undefined): LookupFunction;
54
- export declare function webFetch(input: WebFetchInput): Promise<WebFetchResult>;
55
- //# sourceMappingURL=web-fetch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/research/web-fetch.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAW1D,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAkB,MAAM,CAAC;IAC5B,GAAG,EAAkB,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,aAAa,EAAQ,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAW,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD;qEACiE;IACjE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;qCAGiC;IACjC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,OAAO,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;CAC9H;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAC1D,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAClE,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,OAAO,CAAC;CAClF,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAStD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,mBAAmB,EAAE,OAAO,EAC5B,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,cAAc,CAkChB;AAeD,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAoJ5E"}