mneme-ai 0.27.1 → 0.32.1

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 (88) hide show
  1. package/dist/commands/adversarial.d.ts +14 -0
  2. package/dist/commands/adversarial.d.ts.map +1 -0
  3. package/dist/commands/adversarial.js +273 -0
  4. package/dist/commands/adversarial.js.map +1 -0
  5. package/dist/commands/atrophy.d.ts +53 -0
  6. package/dist/commands/atrophy.d.ts.map +1 -0
  7. package/dist/commands/atrophy.js +405 -0
  8. package/dist/commands/atrophy.js.map +1 -0
  9. package/dist/commands/black-sheep.smoke.test.d.ts +10 -0
  10. package/dist/commands/black-sheep.smoke.test.d.ts.map +1 -0
  11. package/dist/commands/black-sheep.smoke.test.js +186 -0
  12. package/dist/commands/black-sheep.smoke.test.js.map +1 -0
  13. package/dist/commands/bot.d.ts +47 -0
  14. package/dist/commands/bot.d.ts.map +1 -0
  15. package/dist/commands/bot.js +242 -0
  16. package/dist/commands/bot.js.map +1 -0
  17. package/dist/commands/bot.smoke.test.d.ts +2 -0
  18. package/dist/commands/bot.smoke.test.d.ts.map +1 -0
  19. package/dist/commands/bot.smoke.test.js +28 -0
  20. package/dist/commands/bot.smoke.test.js.map +1 -0
  21. package/dist/commands/bot.test.d.ts +2 -0
  22. package/dist/commands/bot.test.d.ts.map +1 -0
  23. package/dist/commands/bot.test.js +277 -0
  24. package/dist/commands/bot.test.js.map +1 -0
  25. package/dist/commands/completion.d.ts +65 -0
  26. package/dist/commands/completion.d.ts.map +1 -0
  27. package/dist/commands/completion.js +385 -0
  28. package/dist/commands/completion.js.map +1 -0
  29. package/dist/commands/completion.smoke.test.d.ts +2 -0
  30. package/dist/commands/completion.smoke.test.d.ts.map +1 -0
  31. package/dist/commands/completion.smoke.test.js +112 -0
  32. package/dist/commands/completion.smoke.test.js.map +1 -0
  33. package/dist/commands/completion.test.d.ts +2 -0
  34. package/dist/commands/completion.test.d.ts.map +1 -0
  35. package/dist/commands/completion.test.js +196 -0
  36. package/dist/commands/completion.test.js.map +1 -0
  37. package/dist/commands/counterfactual.d.ts +10 -0
  38. package/dist/commands/counterfactual.d.ts.map +1 -0
  39. package/dist/commands/counterfactual.js +191 -0
  40. package/dist/commands/counterfactual.js.map +1 -0
  41. package/dist/commands/dashboard.d.ts +37 -0
  42. package/dist/commands/dashboard.d.ts.map +1 -0
  43. package/dist/commands/dashboard.js +230 -0
  44. package/dist/commands/dashboard.js.map +1 -0
  45. package/dist/commands/dashboard.test.d.ts +2 -0
  46. package/dist/commands/dashboard.test.d.ts.map +1 -0
  47. package/dist/commands/dashboard.test.js +135 -0
  48. package/dist/commands/dashboard.test.js.map +1 -0
  49. package/dist/commands/influence.d.ts +9 -0
  50. package/dist/commands/influence.d.ts.map +1 -0
  51. package/dist/commands/influence.js +196 -0
  52. package/dist/commands/influence.js.map +1 -0
  53. package/dist/commands/lineage.d.ts +8 -0
  54. package/dist/commands/lineage.d.ts.map +1 -0
  55. package/dist/commands/lineage.js +187 -0
  56. package/dist/commands/lineage.js.map +1 -0
  57. package/dist/commands/nemesis.d.ts +39 -0
  58. package/dist/commands/nemesis.d.ts.map +1 -0
  59. package/dist/commands/nemesis.js +207 -0
  60. package/dist/commands/nemesis.js.map +1 -0
  61. package/dist/commands/nervous-system.d.ts +12 -0
  62. package/dist/commands/nervous-system.d.ts.map +1 -0
  63. package/dist/commands/nervous-system.js +297 -0
  64. package/dist/commands/nervous-system.js.map +1 -0
  65. package/dist/commands/nervous-system.smoke.test.d.ts +9 -0
  66. package/dist/commands/nervous-system.smoke.test.d.ts.map +1 -0
  67. package/dist/commands/nervous-system.smoke.test.js +110 -0
  68. package/dist/commands/nervous-system.smoke.test.js.map +1 -0
  69. package/dist/commands/org.d.ts +30 -0
  70. package/dist/commands/org.d.ts.map +1 -0
  71. package/dist/commands/org.js +349 -0
  72. package/dist/commands/org.js.map +1 -0
  73. package/dist/commands/passport.d.ts +15 -0
  74. package/dist/commands/passport.d.ts.map +1 -0
  75. package/dist/commands/passport.js +324 -0
  76. package/dist/commands/passport.js.map +1 -0
  77. package/dist/commands/promise.d.ts +42 -0
  78. package/dist/commands/promise.d.ts.map +1 -0
  79. package/dist/commands/promise.js +282 -0
  80. package/dist/commands/promise.js.map +1 -0
  81. package/dist/commands/telepathy.d.ts +39 -0
  82. package/dist/commands/telepathy.d.ts.map +1 -0
  83. package/dist/commands/telepathy.js +214 -0
  84. package/dist/commands/telepathy.js.map +1 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +330 -0
  87. package/dist/index.js.map +1 -1
  88. package/package.json +5 -5
@@ -0,0 +1,14 @@
1
+ export interface AdversarialOptions {
2
+ cwd: string;
3
+ /** Number of probes (rounded down to multiple of 3). */
4
+ probes?: number;
5
+ /** Output markdown path; defaults to .mneme/adversarial-probes.md */
6
+ out?: string;
7
+ /** Path to a JSON responses file; switches to grading mode. */
8
+ grade?: string;
9
+ /** Deterministic seed. */
10
+ seed?: string;
11
+ json?: boolean;
12
+ }
13
+ export declare function adversarialCommand(opts: AdversarialOptions): Promise<number>;
14
+ //# sourceMappingURL=adversarial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adversarial.d.ts","sourceRoot":"","sources":["../../src/commands/adversarial.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlF"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * `mneme adversarial` — meta-evaluation of AI clients against repo memory.
3
+ *
4
+ * Two modes:
5
+ * default Generate a markdown probe bundle (paste into your AI client).
6
+ * --grade <file> Score a JSON responses file against the previously-generated bundle.
7
+ *
8
+ * --json shape (stable):
9
+ * When generating: { generatedAt, repo, probes, answerKey, outPath, answerKeyPath }
10
+ * When grading: { trustScore, totalProbes, correctProbes, perVariant, missed, summary }
11
+ */
12
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
+ import { dirname, join } from "node:path";
14
+ import kleur from "kleur";
15
+ import { git, store as storeNs, adversarial } from "@mneme-ai/core";
16
+ const { generateProbes, gradeResponses, renderProbeMarkdown, serializeAnswerKey, deserializeAnswerKey, } = adversarial;
17
+ import { dbPath, mnemeDir } from "../paths.js";
18
+ import { ui, pill } from "../ui.js";
19
+ import { iris } from "../iris/index.js";
20
+ const DEFAULT_OUT = "adversarial-probes.md";
21
+ const ANSWER_KEY_NAME = "adversarial-answer-key.json";
22
+ export async function adversarialCommand(opts) {
23
+ if (!(await git.isGitRepo(opts.cwd))) {
24
+ ui.error("Not in a git repo. Run `mneme init` first.");
25
+ return 1;
26
+ }
27
+ const meta = await git.getRepoMeta(opts.cwd);
28
+ if (opts.grade) {
29
+ return runGrade(opts, meta.rootPath);
30
+ }
31
+ return runGenerate(opts, meta.rootPath);
32
+ }
33
+ // ─── generate ──────────────────────────────────────────────────────────
34
+ function runGenerate(opts, repoRoot) {
35
+ const s = new storeNs.MnemeStore(dbPath(repoRoot));
36
+ let bundle;
37
+ try {
38
+ bundle = generateProbes(s, {
39
+ probes: opts.probes ?? 12,
40
+ seed: opts.seed,
41
+ repoName: deriveRepoName(repoRoot),
42
+ });
43
+ }
44
+ finally {
45
+ s.close();
46
+ }
47
+ const outPath = opts.out ?? join(mnemeDir(repoRoot), DEFAULT_OUT);
48
+ const answerKeyPath = join(mnemeDir(repoRoot), ANSWER_KEY_NAME);
49
+ if (bundle.probes.length === 0) {
50
+ if (opts.json) {
51
+ process.stdout.write(JSON.stringify({ generatedAt: bundle.generatedAt, probes: [], outPath: null }, null, 2) +
52
+ "\n");
53
+ return 0;
54
+ }
55
+ ui.banner();
56
+ process.stdout.write(iris.render({
57
+ headline: "🐑 Adversarial probes — no HTC abstracts available",
58
+ sections: [
59
+ {
60
+ tier: "lede",
61
+ lines: [
62
+ ` ${pill("HEADS UP", "warn")} ${kleur.gray("the HTC index has no abstracts yet. Probes need ~30-token summaries to mutate.")}`,
63
+ ],
64
+ },
65
+ {
66
+ tier: "sources",
67
+ title: "→ Try next",
68
+ lines: [
69
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme htc-build")} ${kleur.gray("(generate Layer-1 abstracts first; takes a few minutes)")}`,
70
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial")} ${kleur.gray("(re-run after htc-build completes)")}`,
71
+ ],
72
+ },
73
+ ],
74
+ }) + "\n");
75
+ return 0;
76
+ }
77
+ const md = renderProbeMarkdown(bundle);
78
+ writeWithMkdir(outPath, md);
79
+ writeWithMkdir(answerKeyPath, serializeAnswerKey(bundle));
80
+ if (opts.json) {
81
+ process.stdout.write(JSON.stringify({
82
+ generatedAt: bundle.generatedAt,
83
+ repo: bundle.repo,
84
+ probes: bundle.probes,
85
+ answerKey: bundle.answerKey,
86
+ outPath,
87
+ answerKeyPath,
88
+ }, null, 2) + "\n");
89
+ return 0;
90
+ }
91
+ // Iris terminal output.
92
+ const variantCounts = { truth: 0, "subtle-lie": 0, "wholesale-lie": 0 };
93
+ for (const v of Object.values(bundle.answerKey))
94
+ variantCounts[v]++;
95
+ const headline = `🐑 Adversarial probes generated — ${bundle.probes.length} questions in ${shortPath(outPath, repoRoot)}`;
96
+ const ledeLines = [
97
+ ` ${kleur.gray("repo:")} ${kleur.bold(bundle.repo.name ?? "(unnamed)")}`,
98
+ ` ${kleur.gray("HTC abstracts:")} ${kleur.bold(String(bundle.repo.commitsAvailable))}`,
99
+ ` ${kleur.gray("variants:")} ${kleur.green("truth")} ×${variantCounts.truth} · ${kleur.yellow("subtle-lie")} ×${variantCounts["subtle-lie"]} · ${kleur.red("wholesale-lie")} ×${variantCounts["wholesale-lie"]}`,
100
+ ];
101
+ const sampleLines = [];
102
+ for (const p of bundle.probes.slice(0, 5)) {
103
+ const claim = p.claim.length > 60 ? p.claim.slice(0, 57) + "..." : p.claim;
104
+ sampleLines.push(` ${kleur.gray(p.id)} ${kleur.bold(p.shortHash)} ${kleur.gray(claim)}`);
105
+ }
106
+ if (bundle.probes.length > 5) {
107
+ sampleLines.push(` ${kleur.gray(`… and ${bundle.probes.length - 5} more in ${outPath}`)}`);
108
+ }
109
+ const sections = [
110
+ { tier: "lede", title: "✦ Probe bundle", lines: ledeLines },
111
+ { tier: "key-facts", title: "◆ Sample probes", lines: sampleLines },
112
+ {
113
+ tier: "sources",
114
+ title: "→ Try next",
115
+ lines: [
116
+ ` ${kleur.cyan("$")} ${kleur.bold("# 1. Paste " + outPath + " into your AI client")}`,
117
+ ` ${kleur.cyan("$")} ${kleur.bold("# 2. Save the AI's verdicts as responses.json")}`,
118
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial --grade responses.json")} ${kleur.gray("(compute trust score)")}`,
119
+ "",
120
+ ` ${kleur.gray("📘 How to read:")} the AI must answer ${kleur.green("`true`")} for genuine probes,`,
121
+ ` ${kleur.gray("`false` for lies. The AI's job on a fabricated claim is to refuse with reason.")}`,
122
+ ` ${kleur.gray("`uncertain` on a lie counts as a miss — a trustworthy AI commits to refusal.")}`,
123
+ ],
124
+ },
125
+ {
126
+ tier: "details",
127
+ title: "∎ Honest scope",
128
+ lines: [
129
+ ` ${kleur.gray("• This audits the AI client, not Mneme itself.")}`,
130
+ ` ${kleur.gray("• Probes are deliberately deceptive — that is the point.")}`,
131
+ ` ${kleur.gray("• Answer key persisted to: " + answerKeyPath)}`,
132
+ ],
133
+ },
134
+ ];
135
+ ui.banner();
136
+ process.stdout.write(iris.render({ headline, sections }) + "\n");
137
+ return 0;
138
+ }
139
+ // ─── grade ─────────────────────────────────────────────────────────────
140
+ function runGrade(opts, repoRoot) {
141
+ const answerKeyPath = join(mnemeDir(repoRoot), ANSWER_KEY_NAME);
142
+ let bundle;
143
+ try {
144
+ bundle = deserializeAnswerKey(readFileSync(answerKeyPath, "utf8"));
145
+ }
146
+ catch (err) {
147
+ ui.error(`No answer key at ${answerKeyPath} — run \`mneme adversarial\` first to generate one.`);
148
+ if (process.env.DEBUG)
149
+ process.stderr.write(String(err) + "\n");
150
+ return 1;
151
+ }
152
+ let raw;
153
+ try {
154
+ raw = readFileSync(opts.grade, "utf8");
155
+ }
156
+ catch (err) {
157
+ ui.error(`Could not read responses file: ${opts.grade} (${err.message})`);
158
+ return 1;
159
+ }
160
+ let parsed;
161
+ try {
162
+ parsed = JSON.parse(raw);
163
+ }
164
+ catch (err) {
165
+ ui.error(`Responses file is not valid JSON: ${err.message}`);
166
+ return 1;
167
+ }
168
+ const responses = (parsed.responses ?? []).map((r) => ({
169
+ id: String(r.id),
170
+ verdict: normalizeVerdict(String(r.verdict)),
171
+ note: r.note,
172
+ }));
173
+ const report = gradeResponses(bundle, { responses });
174
+ if (opts.json) {
175
+ process.stdout.write(JSON.stringify(report, null, 2) + "\n");
176
+ return 0;
177
+ }
178
+ const headline = `🎯 AI trust score: ${report.trustScore}% — caught ${report.correctProbes}/${report.totalProbes} contradictions`;
179
+ const verdictPill = report.trustScore >= 90
180
+ ? pill("TRUSTWORTHY", "ok")
181
+ : report.trustScore >= 70
182
+ ? pill("MOSTLY OK", "ok")
183
+ : report.trustScore >= 50
184
+ ? pill("SHAKY", "warn")
185
+ : pill("UNTRUSTED", "high");
186
+ const ledeLines = [
187
+ ` ${kleur.gray("verdict:")} ${verdictPill}`,
188
+ ` ${kleur.gray("score:")} ${kleur.bold(report.trustScore + "%")} ${kleur.gray(`(${report.correctProbes} of ${report.totalProbes})`)}`,
189
+ ` ${kleur.gray("truth:")} ${kleur.green(`${report.perVariant.truth.correct}/${report.perVariant.truth.total}`)} caught`,
190
+ ` ${kleur.gray("subtle-lie:")} ${kleur.yellow(`${report.perVariant["subtle-lie"].correct}/${report.perVariant["subtle-lie"].total}`)} caught`,
191
+ ` ${kleur.gray("wholesale:")} ${kleur.red(`${report.perVariant["wholesale-lie"].correct}/${report.perVariant["wholesale-lie"].total}`)} caught`,
192
+ ];
193
+ const missedLines = [];
194
+ for (const m of report.missed.slice(0, 8)) {
195
+ const v = labelForVariant(m.variant);
196
+ missedLines.push(` ${v} ${kleur.gray(m.id)} ${kleur.gray(`expected ${m.expected}, got ${m.got}`)}`);
197
+ missedLines.push(` ${kleur.gray(m.claim.slice(0, 80))}`);
198
+ }
199
+ if (report.missed.length > 8) {
200
+ missedLines.push(` ${kleur.gray(`… and ${report.missed.length - 8} more`)}`);
201
+ }
202
+ const sections = [
203
+ { tier: "lede", title: "✦ Trust grade", lines: ledeLines },
204
+ {
205
+ tier: "body",
206
+ title: "◆ Plain-English summary",
207
+ lines: [` ${kleur.gray(report.summary)}`],
208
+ },
209
+ ];
210
+ if (missedLines.length > 0) {
211
+ sections.push({
212
+ tier: "body",
213
+ title: `⚠ Missed probes (top ${Math.min(8, report.missed.length)})`,
214
+ lines: missedLines,
215
+ });
216
+ }
217
+ sections.push({
218
+ tier: "sources",
219
+ title: "→ Try next",
220
+ lines: [
221
+ ` ${kleur.cyan("$")} ${kleur.bold("mneme adversarial --probes 24")} ${kleur.gray("(re-test with a bigger sample)")}`,
222
+ "",
223
+ ` ${kleur.gray("📘 How to read:")} truth probes test recall — does the AI confirm real history?`,
224
+ ` ${kleur.gray("Subtle and wholesale probes test refusal — does it push back on contradictions?")}`,
225
+ ],
226
+ });
227
+ ui.banner();
228
+ process.stdout.write(iris.render({ headline, sections }) + "\n");
229
+ return 0;
230
+ }
231
+ // ─── helpers ───────────────────────────────────────────────────────────
232
+ function normalizeVerdict(v) {
233
+ const lower = v.trim().toLowerCase();
234
+ if (lower === "true" || lower === "yes" || lower === "verified")
235
+ return "true";
236
+ if (lower === "false" || lower === "no" || lower === "contradicted")
237
+ return "false";
238
+ return "uncertain";
239
+ }
240
+ function labelForVariant(v) {
241
+ switch (v) {
242
+ case "truth":
243
+ return kleur.green().bold("TRUTH ");
244
+ case "subtle-lie":
245
+ return kleur.yellow().bold("SUBTLE ");
246
+ case "wholesale-lie":
247
+ return kleur.red().bold("WHOLESALE");
248
+ }
249
+ }
250
+ function deriveRepoName(rootPath) {
251
+ const parts = rootPath.replace(/\\/g, "/").split("/").filter(Boolean);
252
+ return parts[parts.length - 1] ?? "this repository";
253
+ }
254
+ function shortPath(path, repoRoot) {
255
+ const norm = path.replace(/\\/g, "/");
256
+ const root = repoRoot.replace(/\\/g, "/");
257
+ if (norm.startsWith(root))
258
+ return norm.slice(root.length).replace(/^\/+/, "");
259
+ return path;
260
+ }
261
+ function writeWithMkdir(path, contents) {
262
+ const dir = dirname(path);
263
+ if (dir) {
264
+ try {
265
+ mkdirSync(dir, { recursive: true });
266
+ }
267
+ catch {
268
+ /* ignore */
269
+ }
270
+ }
271
+ writeFileSync(path, contents, "utf8");
272
+ }
273
+ //# sourceMappingURL=adversarial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adversarial.js","sourceRoot":"","sources":["../../src/commands/adversarial.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `mneme atrophy [author]` — knowledge half-life clock.
3
+ *
4
+ * Three modes:
5
+ * 1. (no args) → repo-wide heatmap (top authors + at-risk files)
6
+ * 2. <author email> → that author's knowledge map across files
7
+ * 3. --file <path> → who still remembers this file?
8
+ *
9
+ * --json shape (stable):
10
+ *
11
+ * Mode 1 (repo-wide):
12
+ * {
13
+ * "mode": "repo",
14
+ * "authors": Array<{
15
+ * "name": string, "email": string,
16
+ * "knowledgeMass": number, // sum of knowledge_score across all files
17
+ * "filesKnown": number,
18
+ * "filesStillFresh": number,
19
+ * "lastActiveAt": string
20
+ * }>,
21
+ * "atRiskFiles": Array<{
22
+ * "filePath": string, "totalTouches": number,
23
+ * "tier": "safe" | "warn" | "at-risk",
24
+ * "freshestKnowledge": number,
25
+ * "liveExperts": Array<{ name, email, knowledge, lastTouchDaysAgo, touchCount }>,
26
+ * "allKnowers": Array<{ name, email, knowledge, lastTouchDaysAgo, touchCount }>
27
+ * }>,
28
+ * "stats": {
29
+ * "halfLifeDays": number, "asOf": string,
30
+ * "authorCount": number, "fileCount": number, "totalCommits": number,
31
+ * "filesWithLiveExpert": number, "ghostedFiles": number
32
+ * }
33
+ * }
34
+ *
35
+ * Mode 2 (per author):
36
+ * { "mode": "author", "author": AuthorKnowledge,
37
+ * "topFiles": Array<{ filePath, knowledge, lastTouchDaysAgo, touchCount, band }> }
38
+ *
39
+ * Mode 3 (per file):
40
+ * { "mode": "file", "file": FileKnowledge }
41
+ */
42
+ export interface AtrophyOptions {
43
+ cwd: string;
44
+ /** Optional positional — author email to focus on. */
45
+ author?: string;
46
+ /** Optional --file flag — show "who knows this file?" view. */
47
+ file?: string;
48
+ halfLifeDays?: number;
49
+ topN?: number;
50
+ json?: boolean;
51
+ }
52
+ export declare function atrophyCommand(opts: AtrophyOptions): Promise<number>;
53
+ //# sourceMappingURL=atrophy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atrophy.d.ts","sourceRoot":"","sources":["../../src/commands/atrophy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAgBH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB1E"}