@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,237 @@
1
+ import { Client } from "ssh2";
2
+ // Output size limit (10MB)
3
+ const MAX_OUTPUT_SIZE = 10 * 1024 * 1024;
4
+ export class SSHConnector {
5
+ config;
6
+ client = null;
7
+ constructor(config) {
8
+ this.config = config;
9
+ }
10
+ async connect() {
11
+ if (this.client)
12
+ return this.client;
13
+ return new Promise((resolve, reject) => {
14
+ const client = new Client();
15
+ client.on("ready", () => {
16
+ this.client = client;
17
+ resolve(client);
18
+ });
19
+ client.on("error", reject);
20
+ // Try to connect with private key first, then password
21
+ const connectConfig = {
22
+ host: this.config.host,
23
+ port: this.config.port,
24
+ username: this.config.user,
25
+ };
26
+ if (this.config.privateKey) {
27
+ connectConfig.privateKey = this.config.privateKey;
28
+ }
29
+ else if (this.config.password) {
30
+ connectConfig.password = this.config.password;
31
+ }
32
+ else {
33
+ // Use SSH agent
34
+ connectConfig.agent = process.env.SSH_AUTH_SOCK;
35
+ }
36
+ client.connect(connectConfig);
37
+ });
38
+ }
39
+ async execute(command, options = {}) {
40
+ const client = await this.connect();
41
+ const timeout = options.timeout || 300000;
42
+ // Validate command array is not empty
43
+ if (command.length === 0) {
44
+ throw new Error("Command array cannot be empty");
45
+ }
46
+ // Proper shell escaping using single quotes
47
+ // Single quotes preserve everything literally except single quotes themselves
48
+ // To include a single quote: end single quote, add escaped single quote, start single quote again
49
+ const cmdString = command
50
+ .map((arg) => `'${arg.replace(/'/g, "'\\''")}'`)
51
+ .join(" ");
52
+ // Also escape cwd path if provided
53
+ const escapedCwd = options.cwd ? `'${options.cwd.replace(/'/g, "'\\''")}'` : null;
54
+ const fullCmd = escapedCwd ? `cd ${escapedCwd} && ${cmdString}` : cmdString;
55
+ return new Promise((resolve, reject) => {
56
+ let timedOut = false;
57
+ const timer = setTimeout(() => {
58
+ timedOut = true;
59
+ // Clean up the SSH connection on timeout
60
+ this.client?.end();
61
+ this.client = null;
62
+ reject(new Error(`Command timed out after ${timeout / 1000} seconds`));
63
+ }, timeout);
64
+ client.exec(fullCmd, (err, stream) => {
65
+ if (err) {
66
+ clearTimeout(timer);
67
+ return reject(err);
68
+ }
69
+ let stdout = "";
70
+ let stderr = "";
71
+ let outputTruncated = false;
72
+ stream.on("data", (data) => {
73
+ if (stdout.length < MAX_OUTPUT_SIZE) {
74
+ stdout += data.toString();
75
+ if (stdout.length >= MAX_OUTPUT_SIZE) {
76
+ stdout = stdout.slice(0, MAX_OUTPUT_SIZE);
77
+ outputTruncated = true;
78
+ }
79
+ }
80
+ });
81
+ stream.stderr.on("data", (data) => {
82
+ if (stderr.length < MAX_OUTPUT_SIZE) {
83
+ stderr += data.toString();
84
+ if (stderr.length >= MAX_OUTPUT_SIZE) {
85
+ stderr = stderr.slice(0, MAX_OUTPUT_SIZE);
86
+ outputTruncated = true;
87
+ }
88
+ }
89
+ });
90
+ stream.on("close", (code) => {
91
+ if (timedOut)
92
+ return;
93
+ clearTimeout(timer);
94
+ let finalStdout = stdout.trim();
95
+ if (outputTruncated) {
96
+ finalStdout += "\n\n[OUTPUT TRUNCATED - exceeded 10MB limit]";
97
+ }
98
+ resolve({
99
+ stdout: finalStdout,
100
+ stderr: stderr.trim(),
101
+ exitCode: code,
102
+ });
103
+ });
104
+ });
105
+ });
106
+ }
107
+ async executeShell(command, options = {}) {
108
+ const client = await this.connect();
109
+ const timeout = options.timeout || 300000;
110
+ // Build the full command with optional cwd
111
+ const escapedCwd = options.cwd ? `'${options.cwd.replace(/'/g, "'\\''")}'` : null;
112
+ const fullCmd = escapedCwd ? `cd ${escapedCwd} && ${command}` : command;
113
+ return new Promise((resolve, reject) => {
114
+ let timedOut = false;
115
+ const timer = setTimeout(() => {
116
+ timedOut = true;
117
+ this.client?.end();
118
+ this.client = null;
119
+ reject(new Error(`Command timed out after ${timeout / 1000} seconds`));
120
+ }, timeout);
121
+ client.exec(fullCmd, (err, stream) => {
122
+ if (err) {
123
+ clearTimeout(timer);
124
+ return reject(err);
125
+ }
126
+ let stdout = "";
127
+ let stderr = "";
128
+ let outputTruncated = false;
129
+ stream.on("data", (data) => {
130
+ if (stdout.length < MAX_OUTPUT_SIZE) {
131
+ stdout += data.toString();
132
+ if (stdout.length >= MAX_OUTPUT_SIZE) {
133
+ stdout = stdout.slice(0, MAX_OUTPUT_SIZE);
134
+ outputTruncated = true;
135
+ }
136
+ }
137
+ });
138
+ stream.stderr.on("data", (data) => {
139
+ if (stderr.length < MAX_OUTPUT_SIZE) {
140
+ stderr += data.toString();
141
+ if (stderr.length >= MAX_OUTPUT_SIZE) {
142
+ stderr = stderr.slice(0, MAX_OUTPUT_SIZE);
143
+ outputTruncated = true;
144
+ }
145
+ }
146
+ });
147
+ stream.on("close", (code) => {
148
+ if (timedOut)
149
+ return;
150
+ clearTimeout(timer);
151
+ let finalStdout = stdout.trim();
152
+ if (outputTruncated) {
153
+ finalStdout += "\n\n[OUTPUT TRUNCATED - exceeded 10MB limit]";
154
+ }
155
+ resolve({
156
+ stdout: finalStdout,
157
+ stderr: stderr.trim(),
158
+ exitCode: code,
159
+ });
160
+ });
161
+ });
162
+ });
163
+ }
164
+ async writeFile(remotePath, content) {
165
+ const client = await this.connect();
166
+ return new Promise((resolve, reject) => {
167
+ client.sftp((err, sftp) => {
168
+ if (err) {
169
+ return reject(new Error(`SFTP error: ${err.message}`));
170
+ }
171
+ const writeStream = sftp.createWriteStream(remotePath);
172
+ writeStream.on("error", (writeErr) => {
173
+ sftp.end();
174
+ reject(new Error(`SFTP write error: ${writeErr.message}`));
175
+ });
176
+ writeStream.on("close", () => {
177
+ sftp.end();
178
+ resolve();
179
+ });
180
+ writeStream.end(content);
181
+ });
182
+ });
183
+ }
184
+ async writeFileFromPath(remotePath, hostPath) {
185
+ const client = await this.connect();
186
+ const { createReadStream } = await import("fs");
187
+ const { pipeline } = await import("stream/promises");
188
+ return new Promise((resolve, reject) => {
189
+ client.sftp((err, sftp) => {
190
+ if (err) {
191
+ return reject(new Error(`SFTP error: ${err.message}`));
192
+ }
193
+ const readStream = createReadStream(hostPath);
194
+ const writeStream = sftp.createWriteStream(remotePath);
195
+ pipeline(readStream, writeStream)
196
+ .then(() => {
197
+ sftp.end();
198
+ resolve();
199
+ })
200
+ .catch((pipeErr) => {
201
+ sftp.end();
202
+ reject(new Error(`SFTP write error: ${pipeErr.message}`));
203
+ });
204
+ });
205
+ });
206
+ }
207
+ async readFileToPath(remotePath, hostPath) {
208
+ const client = await this.connect();
209
+ const { createWriteStream } = await import("fs");
210
+ const { pipeline } = await import("stream/promises");
211
+ return new Promise((resolve, reject) => {
212
+ client.sftp((err, sftp) => {
213
+ if (err) {
214
+ return reject(new Error(`SFTP error: ${err.message}`));
215
+ }
216
+ const readStream = sftp.createReadStream(remotePath);
217
+ const writeStream = createWriteStream(hostPath);
218
+ pipeline(readStream, writeStream)
219
+ .then(() => {
220
+ sftp.end();
221
+ resolve();
222
+ })
223
+ .catch((pipeErr) => {
224
+ sftp.end();
225
+ reject(new Error(`SFTP read error: ${pipeErr.message}`));
226
+ });
227
+ });
228
+ });
229
+ }
230
+ async disconnect() {
231
+ if (this.client) {
232
+ this.client.end();
233
+ this.client = null;
234
+ }
235
+ }
236
+ }
237
+ //# sourceMappingURL=ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/connectors/ssh.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Maps raw/unknown errors into structured REMnuxError instances.
3
+ *
4
+ * Catch blocks can call `toREMnuxError(err)` to get a typed error
5
+ * with code, category, and remediation hint.
6
+ */
7
+ import { REMnuxError } from "./remnux-error.js";
8
+ export declare function toREMnuxError(raw: unknown): REMnuxError;
9
+ //# sourceMappingURL=error-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/errors/error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAmCvD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Maps raw/unknown errors into structured REMnuxError instances.
3
+ *
4
+ * Catch blocks can call `toREMnuxError(err)` to get a typed error
5
+ * with code, category, and remediation hint.
6
+ */
7
+ import { REMnuxError } from "./remnux-error.js";
8
+ export function toREMnuxError(raw) {
9
+ if (raw instanceof REMnuxError) {
10
+ return raw;
11
+ }
12
+ const msg = raw instanceof Error ? raw.message : String(raw);
13
+ if (/is not running|not running/i.test(msg)) {
14
+ return new REMnuxError(msg, "CONNECTION_FAILED", "connection", "Run `docker start remnux` or check the container status");
15
+ }
16
+ if (/ECONNREFUSED/i.test(msg)) {
17
+ return new REMnuxError(msg, "CONNECTION_FAILED", "connection", "Check SSH host/port configuration");
18
+ }
19
+ if (/timeout/i.test(msg)) {
20
+ return new REMnuxError(msg, "COMMAND_TIMEOUT", "timeout", "Increase --timeout or simplify the command");
21
+ }
22
+ return new REMnuxError(msg, "UNKNOWN_ERROR", "tool_failure");
23
+ }
24
+ //# sourceMappingURL=error-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-mapper.js","sourceRoot":"","sources":["../../src/errors/error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAE7D,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,IAAI,WAAW,CACpB,GAAG,EACH,mBAAmB,EACnB,YAAY,EACZ,yDAAyD,CAC1D,CAAC;IACJ,CAAC;IAED,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,WAAW,CACpB,GAAG,EACH,mBAAmB,EACnB,YAAY,EACZ,mCAAmC,CACpC,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,WAAW,CACpB,GAAG,EACH,iBAAiB,EACjB,SAAS,EACT,4CAA4C,CAC7C,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Structured error type for REMnux MCP tools.
3
+ *
4
+ * Carries a machine-readable code, category, and optional
5
+ * remediation hint so callers can programmatically handle errors.
6
+ */
7
+ export type ErrorCategory = "validation" | "security" | "connection" | "timeout" | "not_found" | "tool_failure";
8
+ export declare class REMnuxError extends Error {
9
+ readonly code: string;
10
+ readonly category: ErrorCategory;
11
+ readonly remediation?: string;
12
+ constructor(message: string, code: string, category: ErrorCategory, remediation?: string);
13
+ }
14
+ //# sourceMappingURL=remnux-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remnux-error.d.ts","sourceRoot":"","sources":["../../src/errors/remnux-error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,SAAS,GACT,WAAW,GACX,cAAc,CAAC;AAEnB,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,EACvB,WAAW,CAAC,EAAE,MAAM;CAQvB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Structured error type for REMnux MCP tools.
3
+ *
4
+ * Carries a machine-readable code, category, and optional
5
+ * remediation hint so callers can programmatically handle errors.
6
+ */
7
+ export class REMnuxError extends Error {
8
+ code;
9
+ category;
10
+ remediation;
11
+ constructor(message, code, category, remediation) {
12
+ super(message);
13
+ this.name = "REMnuxError";
14
+ this.code = code;
15
+ this.category = category;
16
+ this.remediation = remediation;
17
+ }
18
+ }
19
+ //# sourceMappingURL=remnux-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remnux-error.js","sourceRoot":"","sources":["../../src/errors/remnux-error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAS;IACb,QAAQ,CAAgB;IACxB,WAAW,CAAU;IAE9B,YACE,OAAe,EACf,IAAY,EACZ,QAAuB,EACvB,WAAoB;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * File type detection patterns.
3
+ *
4
+ * Maps `file` command output patterns to analysis categories.
5
+ * Tool lists are derived from the tool registry via tags — not duplicated here.
6
+ *
7
+ * Derived from:
8
+ * - https://zeltser.com/remnux-malware-analysis-tips
9
+ * - https://zeltser.com/analyzing-malicious-documents
10
+ */
11
+ /** Depth tiers for analysis. Canonical definition — import from here. */
12
+ export type DepthTier = "quick" | "standard" | "deep";
13
+ /** Ordered list of depth tiers from shallowest to deepest. */
14
+ export declare const DEPTH_TIER_ORDER: readonly DepthTier[];
15
+ export interface FileTypeCategory {
16
+ /** Category name (e.g., "PE", "PDF") */
17
+ name: string;
18
+ /** Patterns matched against `file` command output (case-insensitive) */
19
+ patterns: RegExp[];
20
+ }
21
+ export declare const FILE_TYPE_CATEGORIES: FileTypeCategory[];
22
+ /** Maps category names to their primary registry tag. */
23
+ export declare const CATEGORY_TAG_MAP: Record<string, string>;
24
+ /**
25
+ * Match `file` command output to a category. Returns the first match or fallback.
26
+ * @param fileOutput - Output from the `file` command
27
+ * @param filename - Optional filename for extension-based fallback (e.g., when `file` says "Zip archive")
28
+ */
29
+ export declare function matchFileType(fileOutput: string, filename?: string): FileTypeCategory;
30
+ //# sourceMappingURL=file-type-mappings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-type-mappings.d.ts","sourceRoot":"","sources":["../src/file-type-mappings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,yEAAyE;AACzE,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtD,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,EAAE,SAAS,SAAS,EAA2C,CAAC;AAE7F,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,EA6DlD,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAgBnD,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAmCrF"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * File type detection patterns.
3
+ *
4
+ * Maps `file` command output patterns to analysis categories.
5
+ * Tool lists are derived from the tool registry via tags — not duplicated here.
6
+ *
7
+ * Derived from:
8
+ * - https://zeltser.com/remnux-malware-analysis-tips
9
+ * - https://zeltser.com/analyzing-malicious-documents
10
+ */
11
+ /** Ordered list of depth tiers from shallowest to deepest. */
12
+ export const DEPTH_TIER_ORDER = ["quick", "standard", "deep"];
13
+ export const FILE_TYPE_CATEGORIES = [
14
+ // DOTNET must precede PE: both match "PE32" but DOTNET patterns are more
15
+ // specific (Mono/.Net, .Net assembly). First-match wins in matchFileType().
16
+ {
17
+ name: "DOTNET",
18
+ patterns: [/Mono\/\.Net/i, /\.Net assembly/i, /PE32.*\.NET/i],
19
+ },
20
+ {
21
+ name: "PE",
22
+ patterns: [/PE32\+?/i, /MS-DOS executable/i],
23
+ },
24
+ {
25
+ name: "PDF",
26
+ patterns: [/\bPDF\b/i],
27
+ },
28
+ {
29
+ name: "OLE2",
30
+ patterns: [
31
+ /Composite Document File/i,
32
+ /OLE 2/i,
33
+ /Microsoft Word(?! 2007)/i,
34
+ /Microsoft Excel(?! 2007)/i,
35
+ /Microsoft PowerPoint(?! 2007)/i,
36
+ ],
37
+ },
38
+ {
39
+ name: "OOXML",
40
+ patterns: [
41
+ /Microsoft Word 2007/i,
42
+ /Microsoft Excel 2007/i,
43
+ /\bOOXML\b/i,
44
+ ],
45
+ },
46
+ {
47
+ name: "RTF",
48
+ patterns: [/Rich Text Format/i, /\bRTF\b/],
49
+ },
50
+ {
51
+ name: "ELF",
52
+ patterns: [/\bELF\b/],
53
+ },
54
+ {
55
+ name: "OneNote",
56
+ patterns: [/OneNote/i],
57
+ },
58
+ {
59
+ name: "Script",
60
+ patterns: [/shell script/i, /script text/i, /ASCII text/i, /UTF-8.*text/i],
61
+ },
62
+ {
63
+ name: "JAR",
64
+ patterns: [/Java archive/i, /\bJAR\b/i],
65
+ },
66
+ {
67
+ name: "Email",
68
+ patterns: [/\bmail\b/i, /RFC 822/i, /\bSMTP\b/i],
69
+ },
70
+ {
71
+ name: "APK",
72
+ patterns: [/\bAndroid\b/i],
73
+ },
74
+ ];
75
+ /** Maps category names to their primary registry tag. */
76
+ export const CATEGORY_TAG_MAP = {
77
+ DOTNET: "dotnet",
78
+ PE: "pe",
79
+ PDF: "pdf",
80
+ OLE2: "ole2",
81
+ OOXML: "ooxml",
82
+ RTF: "rtf",
83
+ ELF: "elf",
84
+ OneNote: "onenote",
85
+ Script: "script",
86
+ JAR: "jar",
87
+ Email: "email",
88
+ APK: "apk",
89
+ Memory: "memory",
90
+ Shellcode: "shellcode",
91
+ Unknown: "fallback",
92
+ };
93
+ /** Memory image extensions — used as fallback when `file` reports "data". */
94
+ const MEMORY_EXTENSIONS = /\.(img|raw|mem|vmem|dmp|lime)$/i;
95
+ /** Shellcode extensions — used as fallback when `file` reports "data". */
96
+ const SHELLCODE_EXTENSIONS = /\.(bin|sc|shellcode|payload)$/i;
97
+ /** OOXML file extensions — used as fallback when `file` reports "Zip archive". */
98
+ const OOXML_EXTENSIONS = /\.(docx|docm|xlsx|xlsm|pptx|pptm)$/i;
99
+ /** OLE2 macro-enabled extensions that `file` may misidentify. */
100
+ const OLE2_EXTENSIONS = /\.(doc|xls|ppt)$/i;
101
+ /**
102
+ * Match `file` command output to a category. Returns the first match or fallback.
103
+ * @param fileOutput - Output from the `file` command
104
+ * @param filename - Optional filename for extension-based fallback (e.g., when `file` says "Zip archive")
105
+ */
106
+ export function matchFileType(fileOutput, filename) {
107
+ // Strip "<path>: " prefix from `file` command output (e.g., "/home/remnux/files/samples/foo.img: data" → "data")
108
+ const typeOutput = fileOutput.includes(":") ? fileOutput.split(":").slice(1).join(":").trim() : fileOutput.trim();
109
+ for (const category of FILE_TYPE_CATEGORIES) {
110
+ for (const pattern of category.patterns) {
111
+ if (pattern.test(typeOutput)) {
112
+ return category;
113
+ }
114
+ }
115
+ }
116
+ // Fallback: if `file` says "Zip archive" and filename has OOXML extension, classify as OOXML
117
+ if (filename && /zip archive/i.test(typeOutput)) {
118
+ if (OOXML_EXTENSIONS.test(filename)) {
119
+ return FILE_TYPE_CATEGORIES.find((c) => c.name === "OOXML");
120
+ }
121
+ }
122
+ // Fallback: if filename has OLE2 extension and `file` output is ambiguous (e.g., "data", "CDF")
123
+ if (filename && OLE2_EXTENSIONS.test(filename) && /^data$|^CDF/i.test(typeOutput)) {
124
+ return FILE_TYPE_CATEGORIES.find((c) => c.name === "OLE2");
125
+ }
126
+ // Fallback: memory images — `file` reports "data" for raw memory dumps
127
+ if (filename && MEMORY_EXTENSIONS.test(filename) && /^data$/i.test(typeOutput)) {
128
+ return { name: "Memory", patterns: [] };
129
+ }
130
+ // Fallback: shellcode — `file` reports "data" and filename has shellcode extension
131
+ if (filename && SHELLCODE_EXTENSIONS.test(filename) && /^data$/i.test(typeOutput)) {
132
+ return { name: "Shellcode", patterns: [] };
133
+ }
134
+ return { name: "Unknown", patterns: [] };
135
+ }
136
+ //# sourceMappingURL=file-type-mappings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-type-mappings.js","sourceRoot":"","sources":["../src/file-type-mappings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAyB,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAU,CAAC;AAS7F,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,yEAAyE;IACzE,4EAA4E;IAC5E;QACE,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,cAAc,EAAE,iBAAiB,EAAE,cAAc,CAAC;KAC9D;IACD;QACE,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,CAAC;KAC7C;IACD;QACE,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB;IACD;QACE,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE;YACR,0BAA0B;YAC1B,QAAQ;YACR,0BAA0B;YAC1B,2BAA2B;YAC3B,gCAAgC;SACjC;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE;YACR,sBAAsB;YACtB,uBAAuB;YACvB,YAAY;SACb;KACF;IACD;QACE,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC;KAC3C;IACD;QACE,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC,SAAS,CAAC;KACtB;IACD;QACE,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB;IACD;QACE,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,CAAC;KAC3E;IACD;QACE,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;KACxC;IACD;QACE,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC;KACjD;IACD;QACE,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,CAAC,cAAc,CAAC;KAC3B;CACF,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,UAAU;CACpB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,iBAAiB,GAAG,iCAAiC,CAAC;AAE5D,0EAA0E;AAC1E,MAAM,oBAAoB,GAAG,gCAAgC,CAAC;AAE9D,kFAAkF;AAClF,MAAM,gBAAgB,GAAG,qCAAqC,CAAC;AAE/D,iEAAiE;AACjE,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,QAAiB;IACjE,iHAAiH;IACjH,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAElH,KAAK,MAAM,QAAQ,IAAI,oBAAoB,EAAE,CAAC;QAC5C,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7B,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,6FAA6F;IAC7F,IAAI,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAChD,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,gGAAgG;IAChG,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAClF,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;IAC9D,CAAC;IAED,uEAAuE;IACvE,IAAI,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1C,CAAC;IAED,mFAAmF;IACnF,IAAI,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAClF,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * File upload module for REMnux MCP server
3
+ *
4
+ * Allows AI assistants to upload files from the host filesystem to the
5
+ * samples directory via MCP. Reads files locally — no base64 in context.
6
+ */
7
+ import type { Connector } from "./connectors/index.js";
8
+ export interface UploadResult {
9
+ success: boolean;
10
+ path?: string;
11
+ size_bytes?: number;
12
+ sha256?: string;
13
+ error?: string;
14
+ }
15
+ /**
16
+ * Validate filename for security
17
+ * - No path separators (/, \)
18
+ * - No path traversal (..)
19
+ * - No null bytes
20
+ * - Reasonable length
21
+ */
22
+ export declare function validateFilename(filename: string): {
23
+ valid: boolean;
24
+ error?: string;
25
+ };
26
+ /**
27
+ * Validate a host filesystem path for security
28
+ */
29
+ export declare function validateHostPath(hostPath: string): {
30
+ valid: boolean;
31
+ error?: string;
32
+ };
33
+ /**
34
+ * Upload a file from the host filesystem to the samples directory
35
+ *
36
+ * @param connector - Connector to write files on REMnux
37
+ * @param samplesDir - Base samples directory on REMnux
38
+ * @param hostPath - Absolute path on the host filesystem
39
+ * @param filename - Override filename (defaults to basename of hostPath)
40
+ * @param overwrite - Whether to overwrite if file exists (default: false)
41
+ * @returns Upload result with file path, size, and SHA256 hash
42
+ */
43
+ export declare function uploadSampleFromHost(connector: Connector, samplesDir: string, hostPath: string, filename?: string, overwrite?: boolean): Promise<UploadResult>;
44
+ //# sourceMappingURL=file-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../src/file-upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKvD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2BrF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBrF;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAsGvB"}