@remnux/mcp-server 0.1.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 (220) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +720 -0
  3. package/dist/archive-extractor.d.ts +46 -0
  4. package/dist/archive-extractor.d.ts.map +1 -0
  5. package/dist/archive-extractor.js +268 -0
  6. package/dist/archive-extractor.js.map +1 -0
  7. package/dist/catalog/index.d.ts +40 -0
  8. package/dist/catalog/index.d.ts.map +1 -0
  9. package/dist/catalog/index.js +114 -0
  10. package/dist/catalog/index.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +154 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config/archive-passwords.txt +3 -0
  16. package/dist/connectors/docker.d.ts +13 -0
  17. package/dist/connectors/docker.d.ts.map +1 -0
  18. package/dist/connectors/docker.js +201 -0
  19. package/dist/connectors/docker.js.map +1 -0
  20. package/dist/connectors/index.d.ts +27 -0
  21. package/dist/connectors/index.d.ts.map +1 -0
  22. package/dist/connectors/index.js +23 -0
  23. package/dist/connectors/index.js.map +1 -0
  24. package/dist/connectors/local.d.ts +10 -0
  25. package/dist/connectors/local.d.ts.map +1 -0
  26. package/dist/connectors/local.js +105 -0
  27. package/dist/connectors/local.js.map +1 -0
  28. package/dist/connectors/ssh.d.ts +21 -0
  29. package/dist/connectors/ssh.d.ts.map +1 -0
  30. package/dist/connectors/ssh.js +237 -0
  31. package/dist/connectors/ssh.js.map +1 -0
  32. package/dist/errors/error-mapper.d.ts +9 -0
  33. package/dist/errors/error-mapper.d.ts.map +1 -0
  34. package/dist/errors/error-mapper.js +24 -0
  35. package/dist/errors/error-mapper.js.map +1 -0
  36. package/dist/errors/remnux-error.d.ts +14 -0
  37. package/dist/errors/remnux-error.d.ts.map +1 -0
  38. package/dist/errors/remnux-error.js +19 -0
  39. package/dist/errors/remnux-error.js.map +1 -0
  40. package/dist/file-type-mappings.d.ts +30 -0
  41. package/dist/file-type-mappings.d.ts.map +1 -0
  42. package/dist/file-type-mappings.js +136 -0
  43. package/dist/file-type-mappings.js.map +1 -0
  44. package/dist/file-upload.d.ts +44 -0
  45. package/dist/file-upload.d.ts.map +1 -0
  46. package/dist/file-upload.js +170 -0
  47. package/dist/file-upload.js.map +1 -0
  48. package/dist/handlers/analyze-file.d.ts +10 -0
  49. package/dist/handlers/analyze-file.d.ts.map +1 -0
  50. package/dist/handlers/analyze-file.js +149 -0
  51. package/dist/handlers/analyze-file.js.map +1 -0
  52. package/dist/handlers/check-tools.d.ts +9 -0
  53. package/dist/handlers/check-tools.d.ts.map +1 -0
  54. package/dist/handlers/check-tools.js +47 -0
  55. package/dist/handlers/check-tools.js.map +1 -0
  56. package/dist/handlers/download-file.d.ts +10 -0
  57. package/dist/handlers/download-file.d.ts.map +1 -0
  58. package/dist/handlers/download-file.js +113 -0
  59. package/dist/handlers/download-file.js.map +1 -0
  60. package/dist/handlers/download-from-url.d.ts +30 -0
  61. package/dist/handlers/download-from-url.d.ts.map +1 -0
  62. package/dist/handlers/download-from-url.js +295 -0
  63. package/dist/handlers/download-from-url.js.map +1 -0
  64. package/dist/handlers/extract-archive.d.ts +10 -0
  65. package/dist/handlers/extract-archive.d.ts.map +1 -0
  66. package/dist/handlers/extract-archive.js +57 -0
  67. package/dist/handlers/extract-archive.js.map +1 -0
  68. package/dist/handlers/extract-iocs.d.ts +10 -0
  69. package/dist/handlers/extract-iocs.d.ts.map +1 -0
  70. package/dist/handlers/extract-iocs.js +21 -0
  71. package/dist/handlers/extract-iocs.js.map +1 -0
  72. package/dist/handlers/get-file-info.d.ts +10 -0
  73. package/dist/handlers/get-file-info.d.ts.map +1 -0
  74. package/dist/handlers/get-file-info.js +89 -0
  75. package/dist/handlers/get-file-info.js.map +1 -0
  76. package/dist/handlers/list-files.d.ts +10 -0
  77. package/dist/handlers/list-files.d.ts.map +1 -0
  78. package/dist/handlers/list-files.js +60 -0
  79. package/dist/handlers/list-files.js.map +1 -0
  80. package/dist/handlers/run-tool.d.ts +10 -0
  81. package/dist/handlers/run-tool.d.ts.map +1 -0
  82. package/dist/handlers/run-tool.js +99 -0
  83. package/dist/handlers/run-tool.js.map +1 -0
  84. package/dist/handlers/suggest-tools.d.ts +10 -0
  85. package/dist/handlers/suggest-tools.d.ts.map +1 -0
  86. package/dist/handlers/suggest-tools.js +202 -0
  87. package/dist/handlers/suggest-tools.js.map +1 -0
  88. package/dist/handlers/types.d.ts +15 -0
  89. package/dist/handlers/types.d.ts.map +1 -0
  90. package/dist/handlers/types.js +2 -0
  91. package/dist/handlers/types.js.map +1 -0
  92. package/dist/handlers/upload-file.d.ts +10 -0
  93. package/dist/handlers/upload-file.d.ts.map +1 -0
  94. package/dist/handlers/upload-file.js +33 -0
  95. package/dist/handlers/upload-file.js.map +1 -0
  96. package/dist/handlers/upload-from-host.d.ts +10 -0
  97. package/dist/handlers/upload-from-host.d.ts.map +1 -0
  98. package/dist/handlers/upload-from-host.js +33 -0
  99. package/dist/handlers/upload-from-host.js.map +1 -0
  100. package/dist/handlers/upload-sample.d.ts +10 -0
  101. package/dist/handlers/upload-sample.d.ts.map +1 -0
  102. package/dist/handlers/upload-sample.js +26 -0
  103. package/dist/handlers/upload-sample.js.map +1 -0
  104. package/dist/index.d.ts +15 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +254 -0
  107. package/dist/index.js.map +1 -0
  108. package/dist/ioc/extractor.d.ts +21 -0
  109. package/dist/ioc/extractor.d.ts.map +1 -0
  110. package/dist/ioc/extractor.js +91 -0
  111. package/dist/ioc/extractor.js.map +1 -0
  112. package/dist/ioc/known-values.d.ts +7 -0
  113. package/dist/ioc/known-values.d.ts.map +1 -0
  114. package/dist/ioc/known-values.js +43 -0
  115. package/dist/ioc/known-values.js.map +1 -0
  116. package/dist/ioc/noise.d.ts +6 -0
  117. package/dist/ioc/noise.d.ts.map +1 -0
  118. package/dist/ioc/noise.js +170 -0
  119. package/dist/ioc/noise.js.map +1 -0
  120. package/dist/ioc/patterns.d.ts +10 -0
  121. package/dist/ioc/patterns.d.ts.map +1 -0
  122. package/dist/ioc/patterns.js +65 -0
  123. package/dist/ioc/patterns.js.map +1 -0
  124. package/dist/ioc/scoring.d.ts +6 -0
  125. package/dist/ioc/scoring.d.ts.map +1 -0
  126. package/dist/ioc/scoring.js +69 -0
  127. package/dist/ioc/scoring.js.map +1 -0
  128. package/dist/parsers/capa.d.ts +9 -0
  129. package/dist/parsers/capa.d.ts.map +1 -0
  130. package/dist/parsers/capa.js +55 -0
  131. package/dist/parsers/capa.js.map +1 -0
  132. package/dist/parsers/diec.d.ts +9 -0
  133. package/dist/parsers/diec.d.ts.map +1 -0
  134. package/dist/parsers/diec.js +53 -0
  135. package/dist/parsers/diec.js.map +1 -0
  136. package/dist/parsers/floss.d.ts +14 -0
  137. package/dist/parsers/floss.d.ts.map +1 -0
  138. package/dist/parsers/floss.js +89 -0
  139. package/dist/parsers/floss.js.map +1 -0
  140. package/dist/parsers/index.d.ts +16 -0
  141. package/dist/parsers/index.d.ts.map +1 -0
  142. package/dist/parsers/index.js +46 -0
  143. package/dist/parsers/index.js.map +1 -0
  144. package/dist/parsers/oleid.d.ts +8 -0
  145. package/dist/parsers/oleid.d.ts.map +1 -0
  146. package/dist/parsers/oleid.js +94 -0
  147. package/dist/parsers/oleid.js.map +1 -0
  148. package/dist/parsers/olevba.d.ts +8 -0
  149. package/dist/parsers/olevba.d.ts.map +1 -0
  150. package/dist/parsers/olevba.js +83 -0
  151. package/dist/parsers/olevba.js.map +1 -0
  152. package/dist/parsers/passthrough.d.ts +6 -0
  153. package/dist/parsers/passthrough.d.ts.map +1 -0
  154. package/dist/parsers/passthrough.js +13 -0
  155. package/dist/parsers/passthrough.js.map +1 -0
  156. package/dist/parsers/pdf-parser.d.ts +9 -0
  157. package/dist/parsers/pdf-parser.d.ts.map +1 -0
  158. package/dist/parsers/pdf-parser.js +76 -0
  159. package/dist/parsers/pdf-parser.js.map +1 -0
  160. package/dist/parsers/pdfid.d.ts +9 -0
  161. package/dist/parsers/pdfid.d.ts.map +1 -0
  162. package/dist/parsers/pdfid.js +56 -0
  163. package/dist/parsers/pdfid.js.map +1 -0
  164. package/dist/parsers/peframe.d.ts +8 -0
  165. package/dist/parsers/peframe.d.ts.map +1 -0
  166. package/dist/parsers/peframe.js +76 -0
  167. package/dist/parsers/peframe.js.map +1 -0
  168. package/dist/parsers/readelf.d.ts +8 -0
  169. package/dist/parsers/readelf.d.ts.map +1 -0
  170. package/dist/parsers/readelf.js +50 -0
  171. package/dist/parsers/readelf.js.map +1 -0
  172. package/dist/parsers/types.d.ts +30 -0
  173. package/dist/parsers/types.d.ts.map +1 -0
  174. package/dist/parsers/types.js +5 -0
  175. package/dist/parsers/types.js.map +1 -0
  176. package/dist/parsers/yara.d.ts +8 -0
  177. package/dist/parsers/yara.d.ts.map +1 -0
  178. package/dist/parsers/yara.js +88 -0
  179. package/dist/parsers/yara.js.map +1 -0
  180. package/dist/response.d.ts +44 -0
  181. package/dist/response.d.ts.map +1 -0
  182. package/dist/response.js +48 -0
  183. package/dist/response.js.map +1 -0
  184. package/dist/schemas/tools.d.ts +135 -0
  185. package/dist/schemas/tools.d.ts.map +1 -0
  186. package/dist/schemas/tools.js +53 -0
  187. package/dist/schemas/tools.js.map +1 -0
  188. package/dist/security/blocklist.d.ts +69 -0
  189. package/dist/security/blocklist.d.ts.map +1 -0
  190. package/dist/security/blocklist.js +148 -0
  191. package/dist/security/blocklist.js.map +1 -0
  192. package/dist/state/session.d.ts +35 -0
  193. package/dist/state/session.d.ts.map +1 -0
  194. package/dist/state/session.js +45 -0
  195. package/dist/state/session.js.map +1 -0
  196. package/dist/tools/definitions.d.ts +9 -0
  197. package/dist/tools/definitions.d.ts.map +1 -0
  198. package/dist/tools/definitions.js +708 -0
  199. package/dist/tools/definitions.js.map +1 -0
  200. package/dist/tools/invoker.d.ts +17 -0
  201. package/dist/tools/invoker.d.ts.map +1 -0
  202. package/dist/tools/invoker.js +44 -0
  203. package/dist/tools/invoker.js.map +1 -0
  204. package/dist/tools/registry.d.ts +62 -0
  205. package/dist/tools/registry.d.ts.map +1 -0
  206. package/dist/tools/registry.js +53 -0
  207. package/dist/tools/registry.js.map +1 -0
  208. package/dist/workflows/engine.d.ts +27 -0
  209. package/dist/workflows/engine.d.ts.map +1 -0
  210. package/dist/workflows/engine.js +224 -0
  211. package/dist/workflows/engine.js.map +1 -0
  212. package/dist/workflows/loader.d.ts +33 -0
  213. package/dist/workflows/loader.d.ts.map +1 -0
  214. package/dist/workflows/loader.js +130 -0
  215. package/dist/workflows/loader.js.map +1 -0
  216. package/dist/workflows/types.d.ts +109 -0
  217. package/dist/workflows/types.d.ts.map +1 -0
  218. package/dist/workflows/types.js +5 -0
  219. package/dist/workflows/types.js.map +1 -0
  220. package/package.json +68 -0
@@ -0,0 +1,295 @@
1
+ import { validateFilename } from "../file-upload.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ import { toREMnuxError } from "../errors/error-mapper.js";
5
+ import { posix } from "path";
6
+ /** Max download size (200MB) */
7
+ const MAX_FILESIZE = 200 * 1024 * 1024;
8
+ /** Max redirects */
9
+ const MAX_REDIRS = 10;
10
+ /** Default thug timeout (seconds) */
11
+ const DEFAULT_THUG_TIMEOUT = 120;
12
+ /** Curl exit code descriptions */
13
+ const CURL_ERRORS = {
14
+ 6: "Could not resolve host (DNS failure)",
15
+ 7: "Failed to connect to host",
16
+ 22: "HTTP error (4xx/5xx response)",
17
+ 28: "Download timed out",
18
+ 35: "SSL/TLS handshake failed",
19
+ 47: "Too many redirects",
20
+ 56: "Failure receiving data (connection reset)",
21
+ 63: "File exceeds maximum size limit (200MB)",
22
+ };
23
+ /**
24
+ * Validate a URL for download: must be http(s), no control chars, no single quotes.
25
+ */
26
+ export function validateUrl(url) {
27
+ let parsed;
28
+ try {
29
+ parsed = new URL(url);
30
+ }
31
+ catch {
32
+ return { valid: false, error: "Invalid URL" };
33
+ }
34
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
35
+ return { valid: false, error: `Unsupported protocol: ${parsed.protocol} (only http and https allowed)` };
36
+ }
37
+ // Reject control characters and single quotes (shell injection vectors)
38
+ if (/[\x00-\x1f']/.test(url)) {
39
+ return { valid: false, error: "URL contains invalid characters (control chars or single quotes)" };
40
+ }
41
+ return { valid: true };
42
+ }
43
+ /**
44
+ * Validate a single HTTP header string.
45
+ * Must be "Name: value" with no injection characters.
46
+ */
47
+ export function validateHeader(header) {
48
+ // Reject newlines, carriage returns, null bytes, single quotes first (security)
49
+ if (/[\x00\n\r']/.test(header)) {
50
+ return { valid: false, error: `Header contains invalid characters: "${header}"` };
51
+ }
52
+ // Must match "HeaderName: value"
53
+ if (!/^[\w-]+:\s*.+$/.test(header)) {
54
+ return { valid: false, error: `Invalid header format: "${header}". Expected "Name: value"` };
55
+ }
56
+ return { valid: true };
57
+ }
58
+ /**
59
+ * Derive a filename from a URL path.
60
+ * Falls back to "downloaded_sample" if no basename can be extracted.
61
+ */
62
+ export function deriveFilename(url) {
63
+ try {
64
+ const parsed = new URL(url);
65
+ const base = posix.basename(parsed.pathname);
66
+ // Filter out empty strings and index-like names
67
+ if (base && base !== "/" && base !== "." && !base.startsWith("?")) {
68
+ // Strip query params that might be part of the basename
69
+ const cleaned = base.split("?")[0] || "downloaded_sample";
70
+ try {
71
+ return decodeURIComponent(cleaned);
72
+ }
73
+ catch {
74
+ return cleaned;
75
+ }
76
+ }
77
+ }
78
+ catch {
79
+ // fall through
80
+ }
81
+ return "downloaded_sample";
82
+ }
83
+ export async function handleDownloadFromUrl(deps, args) {
84
+ const startTime = Date.now();
85
+ const { connector, config } = deps;
86
+ const method = args.method ?? "curl";
87
+ try {
88
+ // Validate URL
89
+ const urlValidation = validateUrl(args.url);
90
+ if (!urlValidation.valid) {
91
+ return formatError("download_from_url", new REMnuxError(urlValidation.error, "INVALID_URL", "validation", "Provide a valid http:// or https:// URL"), startTime);
92
+ }
93
+ // Validate headers if provided
94
+ const headers = args.headers ?? [];
95
+ for (const h of headers) {
96
+ const hv = validateHeader(h);
97
+ if (!hv.valid) {
98
+ return formatError("download_from_url", new REMnuxError(hv.error, "INVALID_HEADER", "validation", "Headers must be 'Name: value' format without control characters or single quotes"), startTime);
99
+ }
100
+ }
101
+ // Determine filename
102
+ const filename = args.filename ?? deriveFilename(args.url);
103
+ const fnValidation = validateFilename(filename);
104
+ if (!fnValidation.valid) {
105
+ return formatError("download_from_url", new REMnuxError(fnValidation.error || "Invalid filename", "INVALID_FILENAME", "validation", "Use alphanumeric characters, hyphens, underscores, and dots only"), startTime);
106
+ }
107
+ const filePath = `${config.samplesDir}/${filename}`;
108
+ // Check if file exists (unless overwrite)
109
+ if (!args.overwrite) {
110
+ try {
111
+ const checkResult = await connector.execute(["test", "-e", filePath], { timeout: 5000 });
112
+ if (checkResult.exitCode === 0) {
113
+ return formatError("download_from_url", new REMnuxError(`File already exists: ${filename}. Use overwrite=true to replace.`, "FILE_EXISTS", "validation", "Set overwrite=true or choose a different filename"), startTime);
114
+ }
115
+ }
116
+ catch {
117
+ // test command failed — file doesn't exist, proceed
118
+ }
119
+ }
120
+ // Ensure samples dir exists
121
+ try {
122
+ await connector.execute(["mkdir", "-p", config.samplesDir], { timeout: 5000 });
123
+ }
124
+ catch {
125
+ // ignore — real errors surface below
126
+ }
127
+ if (method === "thug") {
128
+ return await handleThugDownload(deps, args, headers, filename, filePath, startTime);
129
+ }
130
+ // ── Curl path ──────────────────────────────────────────────────────────
131
+ const timeoutSecs = args.timeout ?? config.timeout;
132
+ // Build curl command
133
+ const headerFlags = headers.map(h => `-H '${h}'`).join(" ");
134
+ const curlCmd = [
135
+ "curl -sSfL",
136
+ `--max-filesize ${MAX_FILESIZE}`,
137
+ `--max-redirs ${MAX_REDIRS}`,
138
+ `--max-time ${timeoutSecs}`,
139
+ headerFlags,
140
+ `-o '${filePath}'`,
141
+ `'${args.url}'`,
142
+ ].filter(Boolean).join(" ");
143
+ const result = await connector.executeShell(curlCmd, {
144
+ timeout: (timeoutSecs + 10) * 1000, // shell timeout slightly longer than curl timeout
145
+ cwd: config.samplesDir,
146
+ });
147
+ if (result.exitCode !== 0) {
148
+ // Clean up partial file left by curl
149
+ try {
150
+ await connector.execute(["rm", "-f", filePath], { timeout: 5000 });
151
+ }
152
+ catch { /* ignore cleanup errors */ }
153
+ const curlError = CURL_ERRORS[result.exitCode] || `curl failed with exit code ${result.exitCode}`;
154
+ const stderr = result.stderr?.trim() || "";
155
+ return formatError("download_from_url", new REMnuxError(`Download failed: ${curlError}${stderr ? ` — ${stderr}` : ""}`, "DOWNLOAD_FAILED", "tool_failure", "Check that the URL is accessible and the server is responding"), startTime);
156
+ }
157
+ // Gather file info (same pattern as get-file-info.ts)
158
+ const info = await gatherFileInfo(connector, filePath, filename);
159
+ return formatResponse("download_from_url", {
160
+ method: "curl",
161
+ url: args.url,
162
+ ...info,
163
+ }, startTime);
164
+ }
165
+ catch (error) {
166
+ return formatError("download_from_url", toREMnuxError(error), startTime);
167
+ }
168
+ }
169
+ /**
170
+ * Handle download via thug honeyclient.
171
+ */
172
+ async function handleThugDownload(deps, args, headers, filename, filePath, startTime) {
173
+ const { connector, config } = deps;
174
+ const timeoutSecs = args.timeout ?? DEFAULT_THUG_TIMEOUT;
175
+ // Parse supported thug flags from headers
176
+ let userAgent;
177
+ let referer;
178
+ const unsupportedHeaders = [];
179
+ for (const h of headers) {
180
+ const [name, ...rest] = h.split(":");
181
+ const headerName = name.trim().toLowerCase();
182
+ const headerValue = rest.join(":").trim();
183
+ if (headerName === "user-agent") {
184
+ userAgent = headerValue;
185
+ }
186
+ else if (headerName === "referer") {
187
+ referer = headerValue;
188
+ }
189
+ else {
190
+ unsupportedHeaders.push(name.trim());
191
+ }
192
+ }
193
+ // Build thug command
194
+ const thugOutputDir = `${config.outputDir}/thug-${Date.now()}`;
195
+ const parts = ["thug"];
196
+ if (userAgent)
197
+ parts.push(`-u '${userAgent}'`);
198
+ if (referer)
199
+ parts.push(`-r '${referer}'`);
200
+ parts.push(`-n '${thugOutputDir}'`);
201
+ parts.push(`'${args.url}'`);
202
+ const thugCmd = parts.join(" ");
203
+ const result = await connector.executeShell(thugCmd, {
204
+ timeout: (timeoutSecs + 30) * 1000,
205
+ cwd: config.samplesDir,
206
+ });
207
+ // Thug may exit non-zero but still produce output; check for downloaded files
208
+ // Find files in thug output (skip HTML and log files)
209
+ const findCmd = `find '${thugOutputDir}' -type f ! -name '*.html' ! -name '*.log' ! -name 'analysis.json' 2>/dev/null | head -20`;
210
+ let downloadedFiles = [];
211
+ try {
212
+ const findResult = await connector.executeShell(findCmd, { timeout: 15000 });
213
+ if (findResult.stdout) {
214
+ downloadedFiles = findResult.stdout.trim().split("\n").filter(Boolean);
215
+ }
216
+ }
217
+ catch {
218
+ // no files found
219
+ }
220
+ if (downloadedFiles.length === 0) {
221
+ const stderr = result.stderr?.trim() || "";
222
+ return formatError("download_from_url", new REMnuxError(`Thug did not download any files${stderr ? ` — ${stderr}` : ""}`, "DOWNLOAD_FAILED", "tool_failure", "The URL may not serve downloadable content, or thug encountered an error"), startTime);
223
+ }
224
+ // Copy first file to samples dir (or use provided filename)
225
+ const firstFile = downloadedFiles[0];
226
+ const copyCmd = `cp '${firstFile}' '${filePath}'`;
227
+ await connector.executeShell(copyCmd, { timeout: 10000 });
228
+ // Gather file info
229
+ const info = await gatherFileInfo(connector, filePath, filename);
230
+ const warnings = [];
231
+ if (unsupportedHeaders.length > 0) {
232
+ warnings.push(`Thug does not support custom headers: ${unsupportedHeaders.join(", ")}. Only User-Agent and Referer are supported.`);
233
+ }
234
+ if (downloadedFiles.length > 1) {
235
+ warnings.push(`Thug downloaded ${downloadedFiles.length} files. Only the first was copied to samples. Others available in: ${thugOutputDir}`);
236
+ }
237
+ return formatResponse("download_from_url", {
238
+ method: "thug",
239
+ url: args.url,
240
+ thug_output_dir: thugOutputDir,
241
+ thug_exit_code: result.exitCode,
242
+ ...(warnings.length > 0 ? { warnings } : {}),
243
+ ...info,
244
+ }, startTime);
245
+ }
246
+ /**
247
+ * Gather file metadata (type, hashes, size) — mirrors get-file-info pattern.
248
+ */
249
+ async function gatherFileInfo(connector, filePath, filename) {
250
+ let fileType = "";
251
+ let sha256 = "";
252
+ let md5 = "";
253
+ let sha1 = "";
254
+ let sizeBytes = null;
255
+ try {
256
+ const r = await connector.execute(["file", filePath], { timeout: 30000 });
257
+ if (r.stdout)
258
+ fileType = r.stdout.trim();
259
+ }
260
+ catch { /* skip */ }
261
+ try {
262
+ const r = await connector.execute(["sha256sum", filePath], { timeout: 30000 });
263
+ if (r.stdout)
264
+ sha256 = r.stdout.trim().split(/\s+/)[0] || "";
265
+ }
266
+ catch { /* skip */ }
267
+ try {
268
+ const r = await connector.execute(["md5sum", filePath], { timeout: 30000 });
269
+ if (r.stdout)
270
+ md5 = r.stdout.trim().split(/\s+/)[0] || "";
271
+ }
272
+ catch { /* skip */ }
273
+ try {
274
+ const r = await connector.execute(["sha1sum", filePath], { timeout: 30000 });
275
+ if (r.stdout)
276
+ sha1 = r.stdout.trim().split(/\s+/)[0] || "";
277
+ }
278
+ catch { /* skip */ }
279
+ try {
280
+ const r = await connector.execute(["stat", "-c", "%s", filePath], { timeout: 30000 });
281
+ if (r.stdout && r.exitCode === 0) {
282
+ sizeBytes = parseInt(r.stdout.trim(), 10);
283
+ }
284
+ }
285
+ catch { /* skip */ }
286
+ return {
287
+ file: filename,
288
+ file_type: fileType,
289
+ sha256,
290
+ sha1,
291
+ md5,
292
+ ...(sizeBytes !== null ? { size_bytes: sizeBytes } : {}),
293
+ };
294
+ }
295
+ //# sourceMappingURL=download-from-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-from-url.js","sourceRoot":"","sources":["../../src/handlers/download-from-url.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { ExtractArchiveArgs } from "../schemas/tools.js";
3
+ export declare function handleExtractArchive(deps: HandlerDeps, args: ExtractArchiveArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=extract-archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-archive.d.ts","sourceRoot":"","sources":["../../src/handlers/extract-archive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAO9D,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,kBAAkB;;;;;;GAiGzB"}
@@ -0,0 +1,57 @@
1
+ import { validateFilePath } from "../security/blocklist.js";
2
+ import { extractArchive, detectArchiveType } from "../archive-extractor.js";
3
+ import { formatResponse, formatError } from "../response.js";
4
+ import { REMnuxError } from "../errors/remnux-error.js";
5
+ import { toREMnuxError } from "../errors/error-mapper.js";
6
+ export async function handleExtractArchive(deps, args) {
7
+ const startTime = Date.now();
8
+ const { connector, config } = deps;
9
+ // Validate archive file path (skip unless --sandbox)
10
+ if (!config.noSandbox) {
11
+ const validation = validateFilePath(args.archive_file, config.samplesDir);
12
+ if (!validation.safe) {
13
+ return formatError("extract_archive", new REMnuxError(validation.error || "Invalid archive file path", "INVALID_PATH", "validation", "Use a relative path within the samples directory"), startTime);
14
+ }
15
+ }
16
+ // Security: Validate output subdirectory if provided
17
+ if (args.output_subdir && !config.noSandbox) {
18
+ if (args.output_subdir.trim() === "") {
19
+ return formatError("extract_archive", new REMnuxError("output_subdir cannot be blank", "INVALID_SUBDIR", "validation", "Provide a non-empty subdirectory name without special characters"), startTime);
20
+ }
21
+ if (args.output_subdir.includes("..") || args.output_subdir.includes("/") || args.output_subdir.includes("\\")) {
22
+ return formatError("extract_archive", new REMnuxError("Invalid output subdirectory name", "INVALID_SUBDIR", "validation", "Subdirectory must not contain path separators or '..'"), startTime);
23
+ }
24
+ if (/[;&|`$\n\r'"\\]/.test(args.output_subdir)) {
25
+ return formatError("extract_archive", new REMnuxError("Output subdirectory contains invalid characters", "INVALID_SUBDIR", "validation", "Use only alphanumeric characters, hyphens, and underscores"), startTime);
26
+ }
27
+ }
28
+ // Verify archive type is supported
29
+ const archiveType = detectArchiveType(args.archive_file);
30
+ if (!archiveType) {
31
+ return formatError("extract_archive", new REMnuxError("Unsupported archive format. Supported: .zip, .7z, .rar", "UNSUPPORTED_FORMAT", "validation", "Rename the file with a supported extension or use a different tool"), startTime);
32
+ }
33
+ // Build full archive path
34
+ const archivePath = `${config.samplesDir}/${args.archive_file}`;
35
+ try {
36
+ const result = await extractArchive(connector, archivePath, config.samplesDir, args.password, args.output_subdir);
37
+ if (result.success) {
38
+ // Store archive metadata for download_file to reuse
39
+ if (result.password && archiveType) {
40
+ deps.sessionState.storeArchiveInfo(args.archive_file, result.files, archiveType, result.password);
41
+ }
42
+ return formatResponse("extract_archive", {
43
+ extracted_to: result.outputDir,
44
+ files: result.files,
45
+ file_count: result.files.length,
46
+ password_used: result.password || "(none - archive was not encrypted)",
47
+ }, startTime);
48
+ }
49
+ else {
50
+ return formatError("extract_archive", new REMnuxError(result.error || "Extraction failed", "EXTRACTION_FAILED", "tool_failure", "Check that the archive is valid and not corrupted"), startTime);
51
+ }
52
+ }
53
+ catch (error) {
54
+ return formatError("extract_archive", toREMnuxError(error), startTime);
55
+ }
56
+ }
57
+ //# sourceMappingURL=extract-archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-archive.js","sourceRoot":"","sources":["../../src/handlers/extract-archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { ExtractIOCsArgs } from "../schemas/tools.js";
3
+ export declare function handleExtractIOCs(_deps: HandlerDeps, args: ExtractIOCsArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=extract-iocs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-iocs.d.ts","sourceRoot":"","sources":["../../src/handlers/extract-iocs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAK3D,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,eAAe;;;;;;GAoBtB"}
@@ -0,0 +1,21 @@
1
+ import { extractIOCs } from "../ioc/extractor.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { toREMnuxError } from "../errors/error-mapper.js";
4
+ export async function handleExtractIOCs(_deps, args) {
5
+ const startTime = Date.now();
6
+ try {
7
+ const result = extractIOCs(args.text);
8
+ const data = {
9
+ iocs: result.iocs,
10
+ summary: result.summary,
11
+ };
12
+ if (args.include_noise) {
13
+ data.noise = result.noise;
14
+ }
15
+ return formatResponse("extract_iocs", data, startTime);
16
+ }
17
+ catch (error) {
18
+ return formatError("extract_iocs", toREMnuxError(error), startTime);
19
+ }
20
+ }
21
+ //# sourceMappingURL=extract-iocs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-iocs.js","sourceRoot":"","sources":["../../src/handlers/extract-iocs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAkB,EAClB,IAAqB;IAErB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtC,MAAM,IAAI,GAA4B;YACpC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;QAEF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC5B,CAAC;QAED,OAAO,cAAc,CAAC,cAAc,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,cAAc,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { GetFileInfoArgs } from "../schemas/tools.js";
3
+ export declare function handleGetFileInfo(deps: HandlerDeps, args: GetFileInfoArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=get-file-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-file-info.d.ts","sourceRoot":"","sources":["../../src/handlers/get-file-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAM3D,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,eAAe;;;;;;GA4FtB"}
@@ -0,0 +1,89 @@
1
+ import { validateFilePath } from "../security/blocklist.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ import { toREMnuxError } from "../errors/error-mapper.js";
5
+ export async function handleGetFileInfo(deps, args) {
6
+ const startTime = Date.now();
7
+ try {
8
+ const { connector, config } = deps;
9
+ // Validate file path (skip unless --sandbox)
10
+ if (!config.noSandbox) {
11
+ const validation = validateFilePath(args.file, config.samplesDir);
12
+ if (!validation.safe) {
13
+ return formatError("get_file_info", new REMnuxError(validation.error || "Invalid file path", "INVALID_PATH", "validation", "Use a relative path within the samples directory"), startTime);
14
+ }
15
+ }
16
+ const filePath = `${config.samplesDir}/${args.file}`;
17
+ let fileType = "";
18
+ let sha256 = "";
19
+ let md5 = "";
20
+ let sizeBytes = null;
21
+ // file command
22
+ try {
23
+ const result = await connector.execute(["file", filePath], { timeout: 30000 });
24
+ if (result.stdout)
25
+ fileType = result.stdout.trim();
26
+ }
27
+ catch (error) {
28
+ const mapped = toREMnuxError(error);
29
+ if (mapped.code === "CONNECTION_FAILED") {
30
+ return formatError("get_file_info", mapped, startTime);
31
+ }
32
+ // Non-connection errors: continue (file command failure is non-fatal)
33
+ }
34
+ // sha256sum
35
+ try {
36
+ const result = await connector.execute(["sha256sum", filePath], { timeout: 30000 });
37
+ if (result.stdout)
38
+ sha256 = result.stdout.trim().split(/\s+/)[0] || "";
39
+ }
40
+ catch { /* skip */ }
41
+ // md5sum
42
+ try {
43
+ const result = await connector.execute(["md5sum", filePath], { timeout: 30000 });
44
+ if (result.stdout)
45
+ md5 = result.stdout.trim().split(/\s+/)[0] || "";
46
+ }
47
+ catch { /* skip */ }
48
+ // sha1sum
49
+ let sha1 = "";
50
+ try {
51
+ const result = await connector.execute(["sha1sum", filePath], { timeout: 30000 });
52
+ if (result.stdout)
53
+ sha1 = result.stdout.trim().split(/\s+/)[0] || "";
54
+ }
55
+ catch { /* skip */ }
56
+ // file size (stat -c works on Linux/REMnux; wc -c as fallback)
57
+ try {
58
+ const result = await connector.execute(["stat", "-c", "%s", filePath], { timeout: 30000 });
59
+ if (result.stdout && result.exitCode === 0) {
60
+ sizeBytes = parseInt(result.stdout.trim(), 10);
61
+ }
62
+ }
63
+ catch { /* skip */ }
64
+ if (sizeBytes === null) {
65
+ try {
66
+ const result = await connector.execute(["wc", "-c", filePath], { timeout: 30000 });
67
+ if (result.stdout && result.exitCode === 0) {
68
+ sizeBytes = parseInt(result.stdout.trim().split(/\s+/)[0] || "0", 10);
69
+ }
70
+ }
71
+ catch { /* skip */ }
72
+ }
73
+ if (!fileType && !sha256 && !md5) {
74
+ return formatError("get_file_info", new REMnuxError("Could not get file info", "EMPTY_OUTPUT", "tool_failure", "Check that the file exists and is readable"), startTime);
75
+ }
76
+ return formatResponse("get_file_info", {
77
+ file: args.file,
78
+ file_type: fileType,
79
+ sha256,
80
+ sha1,
81
+ md5,
82
+ ...(sizeBytes !== null ? { size_bytes: sizeBytes } : {}),
83
+ }, startTime);
84
+ }
85
+ catch (error) {
86
+ return formatError("get_file_info", toREMnuxError(error), startTime);
87
+ }
88
+ }
89
+ //# sourceMappingURL=get-file-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-file-info.js","sourceRoot":"","sources":["../../src/handlers/get-file-info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { ListFilesArgs } from "../schemas/tools.js";
3
+ export declare function handleListFiles(deps: HandlerDeps, args: ListFilesArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=list-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-files.d.ts","sourceRoot":"","sources":["../../src/handlers/list-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,wBAAsB,eAAe,CACnC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,aAAa;;;;;;GAoEpB"}
@@ -0,0 +1,60 @@
1
+ import { formatResponse, formatError } from "../response.js";
2
+ import { toREMnuxError } from "../errors/error-mapper.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ export async function handleListFiles(deps, args) {
5
+ const startTime = Date.now();
6
+ const { connector, config } = deps;
7
+ const dir = args.directory === "samples" ? config.samplesDir : config.outputDir;
8
+ try {
9
+ const result = await connector.execute(["ls", "-la", dir], { timeout: 30000 });
10
+ if (result.exitCode !== 0) {
11
+ const stderr = result.stderr || "";
12
+ const notFound = stderr.includes("No such file") || stderr.includes("cannot access");
13
+ return formatError("list_files", new REMnuxError(notFound ? `Directory does not exist: ${dir}` : `ls failed: ${stderr}`, notFound ? "DIR_NOT_FOUND" : "COMMAND_FAILED", notFound ? "not_found" : "tool_failure", notFound ? "Upload a file first, or check the directory path" : undefined), startTime);
14
+ }
15
+ const raw = result.stdout || "";
16
+ // Parse ls -la output into structured entries
17
+ const lines = raw.split("\n").filter((l) => l.trim() !== "");
18
+ const entries = [];
19
+ for (const line of lines) {
20
+ // Skip "total N" line
21
+ if (line.startsWith("total "))
22
+ continue;
23
+ // ls -la format: permissions links owner group size month day time/year name
24
+ const match = line.match(/^([drwxlsStT\-]+)\s+\d+\s+\S+\s+\S+\s+(\d+)\s+(\w+\s+\d+\s+\S+)\s+(.+)$/);
25
+ if (match) {
26
+ const [, permissions, size, date, name] = match;
27
+ // Skip . and ..
28
+ if (name === "." || name === "..")
29
+ continue;
30
+ // Strip symlink target (e.g., "link -> /outside/sandbox/target")
31
+ let cleanName = name;
32
+ if (permissions.startsWith("l") && name.includes(" -> ")) {
33
+ cleanName = name.split(" -> ")[0];
34
+ }
35
+ let type = "file";
36
+ if (permissions.startsWith("d"))
37
+ type = "directory";
38
+ else if (permissions.startsWith("l"))
39
+ type = "symlink";
40
+ entries.push({
41
+ name: cleanName,
42
+ size: parseInt(size, 10),
43
+ date,
44
+ type,
45
+ permissions,
46
+ });
47
+ }
48
+ }
49
+ return formatResponse("list_files", {
50
+ directory: args.directory,
51
+ path: dir,
52
+ entries,
53
+ entry_count: entries.length,
54
+ }, startTime);
55
+ }
56
+ catch (error) {
57
+ return formatError("list_files", toREMnuxError(error), startTime);
58
+ }
59
+ }
60
+ //# sourceMappingURL=list-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-files.js","sourceRoot":"","sources":["../../src/handlers/list-files.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAiB,EACjB,IAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IAEhF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAE/E,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;YACrF,OAAO,WAAW,CAAC,YAAY,EAAE,IAAI,WAAW,CAC9C,QAAQ,CAAC,CAAC,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,EACtE,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,EAC7C,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,EACvC,QAAQ,CAAC,CAAC,CAAC,kDAAkD,CAAC,CAAC,CAAC,SAAS,CAC1E,EAAE,SAAS,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QAEhC,8CAA8C;QAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,MAAM,OAAO,GAA2F,EAAE,CAAC;QAE3G,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,sBAAsB;YACtB,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAExC,6EAA6E;YAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CACtB,yEAAyE,CAC1E,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;gBAChD,gBAAgB;gBAChB,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;oBAAE,SAAS;gBAE5C,iEAAiE;gBACjE,IAAI,SAAS,GAAG,IAAI,CAAC;gBACrB,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,CAAC;gBAED,IAAI,IAAI,GAAG,MAAM,CAAC;gBAClB,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,GAAG,WAAW,CAAC;qBAC/C,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,IAAI,GAAG,SAAS,CAAC;gBAEvD,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;oBACxB,IAAI;oBACJ,IAAI;oBACJ,WAAW;iBACZ,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,cAAc,CAAC,YAAY,EAAE;YAClC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,GAAG;YACT,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,MAAM;SAC5B,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}