@wirecat/cli-memo 0.0.0 → 0.5.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 (191) hide show
  1. package/LICENSE +204 -0
  2. package/README.md +315 -0
  3. package/dist/answers/command.d.ts +35 -0
  4. package/dist/answers/command.d.ts.map +1 -0
  5. package/dist/answers/command.js +117 -0
  6. package/dist/answers/command.js.map +1 -0
  7. package/dist/app.d.ts +9 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +10 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/bin/memo.d.ts +3 -0
  12. package/dist/bin/memo.d.ts.map +1 -0
  13. package/dist/bin/memo.js +14 -0
  14. package/dist/bin/memo.js.map +1 -0
  15. package/dist/config.d.ts +39 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +40 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/context/command.d.ts +6 -0
  20. package/dist/context/command.d.ts.map +1 -0
  21. package/dist/context/command.js +73 -0
  22. package/dist/context/command.js.map +1 -0
  23. package/dist/context/context.d.ts +28 -0
  24. package/dist/context/context.d.ts.map +1 -0
  25. package/dist/context/context.js +49 -0
  26. package/dist/context/context.js.map +1 -0
  27. package/dist/knowledge/command.d.ts +4 -0
  28. package/dist/knowledge/command.d.ts.map +1 -0
  29. package/dist/knowledge/command.js +158 -0
  30. package/dist/knowledge/command.js.map +1 -0
  31. package/dist/mail/command.d.ts +4 -0
  32. package/dist/mail/command.d.ts.map +1 -0
  33. package/dist/mail/command.js +61 -0
  34. package/dist/mail/command.js.map +1 -0
  35. package/dist/mail/gmail.d.ts +18 -0
  36. package/dist/mail/gmail.d.ts.map +1 -0
  37. package/dist/mail/gmail.js +103 -0
  38. package/dist/mail/gmail.js.map +1 -0
  39. package/dist/mail/himalaya.d.ts +4 -0
  40. package/dist/mail/himalaya.d.ts.map +1 -0
  41. package/dist/mail/himalaya.js +13 -0
  42. package/dist/mail/himalaya.js.map +1 -0
  43. package/dist/mail/import.d.ts +53 -0
  44. package/dist/mail/import.d.ts.map +1 -0
  45. package/dist/mail/import.js +170 -0
  46. package/dist/mail/import.js.map +1 -0
  47. package/dist/mail/parse.d.ts +21 -0
  48. package/dist/mail/parse.d.ts.map +1 -0
  49. package/dist/mail/parse.js +86 -0
  50. package/dist/mail/parse.js.map +1 -0
  51. package/dist/notes/about.d.ts +31 -0
  52. package/dist/notes/about.d.ts.map +1 -0
  53. package/dist/notes/about.js +69 -0
  54. package/dist/notes/about.js.map +1 -0
  55. package/dist/notes/bound.d.ts +24 -0
  56. package/dist/notes/bound.d.ts.map +1 -0
  57. package/dist/notes/bound.js +57 -0
  58. package/dist/notes/bound.js.map +1 -0
  59. package/dist/notes/command.d.ts +4 -0
  60. package/dist/notes/command.d.ts.map +1 -0
  61. package/dist/notes/command.js +222 -0
  62. package/dist/notes/command.js.map +1 -0
  63. package/dist/notes/dialects/common.d.ts +18 -0
  64. package/dist/notes/dialects/common.d.ts.map +1 -0
  65. package/dist/notes/dialects/common.js +79 -0
  66. package/dist/notes/dialects/common.js.map +1 -0
  67. package/dist/notes/dialects/index.d.ts +5 -0
  68. package/dist/notes/dialects/index.d.ts.map +1 -0
  69. package/dist/notes/dialects/index.js +6 -0
  70. package/dist/notes/dialects/index.js.map +1 -0
  71. package/dist/notes/dialects/markdown.d.ts +7 -0
  72. package/dist/notes/dialects/markdown.d.ts.map +1 -0
  73. package/dist/notes/dialects/markdown.js +51 -0
  74. package/dist/notes/dialects/markdown.js.map +1 -0
  75. package/dist/notes/dialects/obsidian.d.ts +6 -0
  76. package/dist/notes/dialects/obsidian.d.ts.map +1 -0
  77. package/dist/notes/dialects/obsidian.js +33 -0
  78. package/dist/notes/dialects/obsidian.js.map +1 -0
  79. package/dist/notes/dialects/types.d.ts +39 -0
  80. package/dist/notes/dialects/types.d.ts.map +1 -0
  81. package/dist/notes/dialects/types.js +2 -0
  82. package/dist/notes/dialects/types.js.map +1 -0
  83. package/dist/notes/embed.d.ts +51 -0
  84. package/dist/notes/embed.d.ts.map +1 -0
  85. package/dist/notes/embed.js +109 -0
  86. package/dist/notes/embed.js.map +1 -0
  87. package/dist/notes/export.d.ts +27 -0
  88. package/dist/notes/export.d.ts.map +1 -0
  89. package/dist/notes/export.js +76 -0
  90. package/dist/notes/export.js.map +1 -0
  91. package/dist/notes/files.d.ts +14 -0
  92. package/dist/notes/files.d.ts.map +1 -0
  93. package/dist/notes/files.js +77 -0
  94. package/dist/notes/files.js.map +1 -0
  95. package/dist/notes/folders-command.d.ts +4 -0
  96. package/dist/notes/folders-command.d.ts.map +1 -0
  97. package/dist/notes/folders-command.js +113 -0
  98. package/dist/notes/folders-command.js.map +1 -0
  99. package/dist/notes/folders.d.ts +27 -0
  100. package/dist/notes/folders.d.ts.map +1 -0
  101. package/dist/notes/folders.js +46 -0
  102. package/dist/notes/folders.js.map +1 -0
  103. package/dist/notes/import.d.ts +33 -0
  104. package/dist/notes/import.d.ts.map +1 -0
  105. package/dist/notes/import.js +183 -0
  106. package/dist/notes/import.js.map +1 -0
  107. package/dist/notes/internal.d.ts +17 -0
  108. package/dist/notes/internal.d.ts.map +1 -0
  109. package/dist/notes/internal.js +47 -0
  110. package/dist/notes/internal.js.map +1 -0
  111. package/dist/notes/links.d.ts +18 -0
  112. package/dist/notes/links.d.ts.map +1 -0
  113. package/dist/notes/links.js +44 -0
  114. package/dist/notes/links.js.map +1 -0
  115. package/dist/notes/renames.d.ts +11 -0
  116. package/dist/notes/renames.d.ts.map +1 -0
  117. package/dist/notes/renames.js +24 -0
  118. package/dist/notes/renames.js.map +1 -0
  119. package/dist/notes/search.d.ts +5 -0
  120. package/dist/notes/search.d.ts.map +1 -0
  121. package/dist/notes/search.js +20 -0
  122. package/dist/notes/search.js.map +1 -0
  123. package/dist/notes/state.d.ts +14 -0
  124. package/dist/notes/state.d.ts.map +1 -0
  125. package/dist/notes/state.js +21 -0
  126. package/dist/notes/state.js.map +1 -0
  127. package/dist/options.d.ts +4 -0
  128. package/dist/options.d.ts.map +1 -0
  129. package/dist/options.js +12 -0
  130. package/dist/options.js.map +1 -0
  131. package/dist/people/command.d.ts +5 -0
  132. package/dist/people/command.d.ts.map +1 -0
  133. package/dist/people/command.js +57 -0
  134. package/dist/people/command.js.map +1 -0
  135. package/dist/people/identity.d.ts +4 -0
  136. package/dist/people/identity.d.ts.map +1 -0
  137. package/dist/people/identity.js +13 -0
  138. package/dist/people/identity.js.map +1 -0
  139. package/dist/people/notes-map.d.ts +13 -0
  140. package/dist/people/notes-map.d.ts.map +1 -0
  141. package/dist/people/notes-map.js +49 -0
  142. package/dist/people/notes-map.js.map +1 -0
  143. package/dist/people/subject.d.ts +8 -0
  144. package/dist/people/subject.d.ts.map +1 -0
  145. package/dist/people/subject.js +19 -0
  146. package/dist/people/subject.js.map +1 -0
  147. package/dist/program.d.ts +7 -0
  148. package/dist/program.d.ts.map +1 -0
  149. package/dist/program.js +34 -0
  150. package/dist/program.js.map +1 -0
  151. package/dist/run/auto.d.ts +20 -0
  152. package/dist/run/auto.d.ts.map +1 -0
  153. package/dist/run/auto.js +139 -0
  154. package/dist/run/auto.js.map +1 -0
  155. package/dist/run/import.d.ts +18 -0
  156. package/dist/run/import.d.ts.map +1 -0
  157. package/dist/run/import.js +114 -0
  158. package/dist/run/import.js.map +1 -0
  159. package/dist/search/command.d.ts +38 -0
  160. package/dist/search/command.d.ts.map +1 -0
  161. package/dist/search/command.js +269 -0
  162. package/dist/search/command.js.map +1 -0
  163. package/dist/store/gone.d.ts +17 -0
  164. package/dist/store/gone.d.ts.map +1 -0
  165. package/dist/store/gone.js +52 -0
  166. package/dist/store/gone.js.map +1 -0
  167. package/dist/store/scope.d.ts +19 -0
  168. package/dist/store/scope.d.ts.map +1 -0
  169. package/dist/store/scope.js +34 -0
  170. package/dist/store/scope.js.map +1 -0
  171. package/dist/store/source-target.d.ts +18 -0
  172. package/dist/store/source-target.d.ts.map +1 -0
  173. package/dist/store/source-target.js +28 -0
  174. package/dist/store/source-target.js.map +1 -0
  175. package/dist/tags/command.d.ts +4 -0
  176. package/dist/tags/command.d.ts.map +1 -0
  177. package/dist/tags/command.js +166 -0
  178. package/dist/tags/command.js.map +1 -0
  179. package/dist/tasks/command.d.ts +4 -0
  180. package/dist/tasks/command.d.ts.map +1 -0
  181. package/dist/tasks/command.js +83 -0
  182. package/dist/tasks/command.js.map +1 -0
  183. package/dist/tasks/context.d.ts +16 -0
  184. package/dist/tasks/context.d.ts.map +1 -0
  185. package/dist/tasks/context.js +68 -0
  186. package/dist/tasks/context.js.map +1 -0
  187. package/dist/version.d.ts +2 -0
  188. package/dist/version.d.ts.map +1 -0
  189. package/dist/version.js +2 -0
  190. package/dist/version.js.map +1 -0
  191. package/package.json +48 -3
@@ -0,0 +1,158 @@
1
+ import { CliError, createRenderer } from "@wirecat/cli-core";
2
+ import { openStore, } from "@wirecat/cli-messaging/store";
3
+ import { notesAbout } from "../notes/about.js";
4
+ import { accountOptions, positive } from "../options.js";
5
+ import { selectAccount } from "../store/scope.js";
6
+ export const knowledgeCommands = (program, streams, env) => {
7
+ const execute = async (options, work) => {
8
+ const store = await openStore({ env });
9
+ try {
10
+ const answer = await work(store, await selectAccount(store, options));
11
+ if (options.json)
12
+ createRenderer({ format: "json", color: false, streams }).result(answer);
13
+ else
14
+ streams.data(`${JSON.stringify(answer, null, 2)}\n`);
15
+ }
16
+ finally {
17
+ await store.close();
18
+ }
19
+ };
20
+ /** Organisations and relations are the owner's, not an account's. */
21
+ const owned = async (options, work) => {
22
+ const store = await openStore({ env });
23
+ try {
24
+ const answer = await work(store);
25
+ if (options.json)
26
+ createRenderer({ format: "json", color: false, streams }).result(answer);
27
+ else
28
+ streams.data(`${JSON.stringify(answer, null, 2)}\n`);
29
+ }
30
+ finally {
31
+ await store.close();
32
+ }
33
+ };
34
+ const entities = program.command("entities").description("Organizations, families, projects and groups of yours");
35
+ entities
36
+ .command("add")
37
+ .argument("<name>")
38
+ .requiredOption("--kind <kind>", "organization, family, project or group")
39
+ .option("--json", "print JSON")
40
+ .action((name, options) => owned(options, (store) => store.notes.addEntity(options.kind, name)));
41
+ entities
42
+ .command("list")
43
+ .option("--json", "print JSON")
44
+ .action((options) => owned(options, (store) => store.notes.entities()));
45
+ entities
46
+ .command("context")
47
+ .argument("<id>")
48
+ .option("--json", "print JSON")
49
+ .action((id, options) => owned(options, async (store) => {
50
+ const ref = `entity:${id}`;
51
+ return {
52
+ entity: (await store.notes.entities()).find((entity) => entity.id === id) ?? null,
53
+ relationships: (await store.notes.links({ to: ref }))
54
+ .concat(await store.notes.links({ from: ref }))
55
+ .filter((link) => link.kind !== "about" && link.kind !== "links-to"),
56
+ notes: await notesAbout(store, { ref }),
57
+ tags: await store.knowledge.tags(null, { type: "entity", id }),
58
+ };
59
+ }));
60
+ const relations = program
61
+ .command("relationships")
62
+ .description("Explicit relations between person:<uid> and entity:<uid>; this never links identities");
63
+ relations
64
+ .command("add")
65
+ .argument("<from>")
66
+ .argument("<to>")
67
+ .option("--json", "print JSON")
68
+ .option("--kind <kind>", "member-of or related-to", "member-of")
69
+ .option("--role <role>")
70
+ .option("--evidence <text>")
71
+ .action((from, to, options) => owned(options, (store) => store.knowledge.relate(null, {
72
+ from,
73
+ to,
74
+ kind: options.kind,
75
+ ...(options.role === undefined ? {} : { role: options.role }),
76
+ ...(options.evidence === undefined ? {} : { evidence: options.evidence }),
77
+ })));
78
+ relations
79
+ .command("list")
80
+ .option("--reference <reference>")
81
+ .option("--json", "print JSON")
82
+ .action((options) => owned(options, (store) => store.knowledge.relations(null, options.reference)));
83
+ relations
84
+ .command("remove")
85
+ .argument("<id>")
86
+ .option("--json", "print JSON")
87
+ .action((id, options) => owned(options, (store) => store.knowledge.removeRelation(null, id)));
88
+ relations
89
+ .command("confirm")
90
+ .argument("<id>")
91
+ .option("--json", "print JSON")
92
+ .action((id, options) => owned(options, (store) => store.knowledge.confirmRelation(null, id)));
93
+ accountOptions(relations
94
+ .command("suggest")
95
+ .description("Store weak shared-domain suggestions for direct email contacts; confirmation is explicit"))
96
+ .option("--limit <n>", "most suggestions, at most 100", positive, 20)
97
+ .action((options) => execute(options, async (store, key) => {
98
+ if (key.provider !== "email" || options.limit > 100)
99
+ throw new CliError("validation_error", "suggestions require an email account and limit 1–100");
100
+ const contacts = await store.contacts(key, { order: "name", limit: 500, offset: 0 });
101
+ const domains = new Map();
102
+ const free = new Set([
103
+ "gmail.com",
104
+ "outlook.com",
105
+ "hotmail.com",
106
+ "yahoo.com",
107
+ "icloud.com",
108
+ "proton.me",
109
+ "protonmail.com",
110
+ ]);
111
+ for (const contact of contacts.items) {
112
+ const domain = contact.id.split("@")[1]?.toLowerCase();
113
+ if (!domain || free.has(domain))
114
+ continue;
115
+ const person = await store.personOf({ provider: key.provider, id: contact.id });
116
+ if (person)
117
+ domains.set(domain, [...new Set([...(domains.get(domain) ?? []), person.uid])]);
118
+ }
119
+ const suggestions = [];
120
+ for (const [domain, people] of domains)
121
+ for (let left = 0; left < people.length; left++)
122
+ for (let right = left + 1; right < people.length; right++) {
123
+ if (suggestions.length >= options.limit)
124
+ return { suggestions, complete: false, scope: "stored-direct-email-contacts" };
125
+ suggestions.push(await store.knowledge.relate(key, {
126
+ from: `person:${people[left]}`,
127
+ to: `person:${people[right]}`,
128
+ kind: "related-to",
129
+ confirmed: false,
130
+ evidence: `Shared email domain ${domain}; this does not prove organization membership`,
131
+ provenance: "rule:email-domain-v1;confidence:weak",
132
+ }));
133
+ }
134
+ return { suggestions, complete: !contacts.hasMore, scope: "stored-direct-email-contacts" };
135
+ }));
136
+ const reminders = program
137
+ .command("reminders")
138
+ .description("Durable local reminders; poll leases a delivery and ack confirms it");
139
+ accountOptions(reminders.command("schedule").argument("<task>"))
140
+ .requiredOption("--at <timestamp>", "ISO timestamp with UTC offset")
141
+ .option("--timezone <zone>", "IANA timezone", "UTC")
142
+ .action((task, options) => execute(options, (store, key) => store.knowledge.schedule(key, task, options.at, options.timezone)));
143
+ accountOptions(reminders.command("list")).action((options) => execute(options, (store, key) => store.knowledge.reminders(key)));
144
+ accountOptions(reminders.command("poll"))
145
+ .option("--limit <n>", "most due reminders, at most 500", positive, 100)
146
+ .action((options) => execute(options, async (store, key) => (await store.knowledge.claimReminders(key, { limit: options.limit })).map((reminder) => ({
147
+ ...reminder,
148
+ deliveryId: `${reminder.id}:${reminder.revision}`,
149
+ delivery: "local",
150
+ }))));
151
+ accountOptions(reminders.command("ack").argument("<id>").argument("<receipt>")).action((id, receipt, options) => execute(options, (store, key) => store.knowledge.acknowledgeReminder(key, id, receipt)));
152
+ accountOptions(reminders.command("cancel").argument("<id>")).action((id, options) => execute(options, (store, key) => store.knowledge.cancelReminder(key, id)));
153
+ accountOptions(reminders.command("snooze").argument("<id>"))
154
+ .requiredOption("--at <timestamp>")
155
+ .requiredOption("--revision <n>", "current revision", positive)
156
+ .action((id, options) => execute(options, (store, key) => store.knowledge.snoozeReminder(key, id, options.at, options.revision)));
157
+ };
158
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/knowledge/command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type Streams } from "@wirecat/cli-core";
2
+ import { type Command } from "commander";
3
+ export declare const mailCommand: (program: Command, streams: Streams, env: NodeJS.ProcessEnv) => void;
4
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/mail/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE1E,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,WAAW,CAAA;AAuB9D,eAAO,MAAM,WAAW,YAAa,OAAO,WAAW,OAAO,OAAO,MAAM,CAAC,UAAU,KAAG,IAkDxF,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { CliError, createRenderer } from "@wirecat/cli-core";
2
+ import { openStore } from "@wirecat/cli-messaging/store";
3
+ import { InvalidArgumentError } from "commander";
4
+ import { loadConfig } from "../config.js";
5
+ import { positive } from "../options.js";
6
+ import { himalaya } from "./himalaya.js";
7
+ import { importMail } from "./import.js";
8
+ const DAY = 86_400_000;
9
+ const day = (value) => {
10
+ const date = new Date(`${value}T00:00:00Z`);
11
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value) || Number.isNaN(date.getTime()))
12
+ throw new InvalidArgumentError("a date as YYYY-MM-DD");
13
+ return date;
14
+ };
15
+ const text = (result) => [
16
+ `${result.account}: ${result.listed} in All Mail since ${result.since.slice(0, 10)}, ` +
17
+ `${result.saved} saved, ${result.alreadyStored} already stored, ${result.deleted} marked deleted.`,
18
+ ...(result.complete ? [] : ["Not every new message was read — run it again to continue."]),
19
+ ...(result.deletionsSkipped === undefined ? [] : [`Deletions skipped: ${result.deletionsSkipped}`]),
20
+ ].join("\n");
21
+ export const mailCommand = (program, streams, env) => {
22
+ const mail = program.command("mail").description("Mail, read through Himalaya into the shared message store");
23
+ mail
24
+ .command("import")
25
+ .description("Read a Gmail account's All Mail into the store, and drop the text of mail deleted at the source")
26
+ .option("--account <name>", "the account's name in Himalaya's config (default: the first in mail.accounts)")
27
+ .option("--since <date>", "first day to read, YYYY-MM-DD (default: 30 days ago)", day)
28
+ .option("--max <n>", "most new messages to read in this run", positive, 200)
29
+ .option("--json", "print JSON")
30
+ .option("--no-embed", "skip semantic embedding; local words remain searchable")
31
+ .option("--retry-attachments", "reread bounded stored messages after installing an extraction engine")
32
+ .action(async (options) => {
33
+ const accounts = loadConfig(env).mail?.accounts ?? [];
34
+ const account = options.account === undefined ? accounts[0] : accounts.find(({ name }) => name === options.account);
35
+ if (account === undefined)
36
+ throw new CliError("configuration_error", options.account === undefined
37
+ ? "no mail account: add mail.accounts [{ name, address }] to the config"
38
+ : `no mail account "${options.account}" in mail.accounts of the config`);
39
+ const store = await openStore({ env });
40
+ try {
41
+ const result = await importMail({
42
+ store,
43
+ run: himalaya(env),
44
+ account,
45
+ since: options.since ?? new Date(Date.now() - 30 * DAY),
46
+ max: options.max,
47
+ env,
48
+ embed: options.embed,
49
+ retryAttachments: options.retryAttachments,
50
+ });
51
+ if (options.json)
52
+ createRenderer({ format: "json", color: false, streams }).result(result);
53
+ else
54
+ streams.data(`${text(result)}\n`);
55
+ }
56
+ finally {
57
+ await store.close();
58
+ }
59
+ });
60
+ };
61
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/mail/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAgB,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAgB,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAqB,UAAU,EAAE,MAAM,aAAa,CAAA;AAE3D,MAAM,GAAG,GAAG,UAAU,CAAA;AAEtB,MAAM,GAAG,GAAG,CAAC,KAAa,EAAQ,EAAE;IAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,YAAY,CAAC,CAAA;IAC3C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpE,MAAM,IAAI,oBAAoB,CAAC,sBAAsB,CAAC,CAAA;IACxD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CAAC,MAAoB,EAAU,EAAE,CAC5C;IACE,GAAG,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,sBAAsB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI;QACpF,GAAG,MAAM,CAAC,KAAK,WAAW,MAAM,CAAC,aAAa,oBAAoB,MAAM,CAAC,OAAO,kBAAkB;IACpG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,4DAA4D,CAAC,CAAC;IAC1F,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,sBAAsB,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;CACpG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAgB,EAAE,OAAgB,EAAE,GAAsB,EAAQ,EAAE;IAC9F,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,2DAA2D,CAAC,CAAA;IAE7G,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iGAAiG,CAAC;SAC9G,MAAM,CAAC,kBAAkB,EAAE,+EAA+E,CAAC;SAC3G,MAAM,CAAC,gBAAgB,EAAE,sDAAsD,EAAE,GAAG,CAAC;SACrF,MAAM,CAAC,WAAW,EAAE,uCAAuC,EAAE,QAAQ,EAAE,GAAG,CAAC;SAC3E,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;SAC9B,MAAM,CAAC,YAAY,EAAE,wDAAwD,CAAC;SAC9E,MAAM,CAAC,qBAAqB,EAAE,sEAAsE,CAAC;SACrG,MAAM,CACL,KAAK,EAAE,OAON,EAAE,EAAE;QACH,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAA;QACrD,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;QACrG,IAAI,OAAO,KAAK,SAAS;YACvB,MAAM,IAAI,QAAQ,CAChB,qBAAqB,EACrB,OAAO,CAAC,OAAO,KAAK,SAAS;gBAC3B,CAAC,CAAC,sEAAsE;gBACxE,CAAC,CAAC,oBAAoB,OAAO,CAAC,OAAO,kCAAkC,CAC1E,CAAA;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;gBAC9B,KAAK;gBACL,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC;gBAClB,OAAO;gBACP,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;gBACvD,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,GAAG;gBACH,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;aAC3C,CAAC,CAAA;YACF,IAAI,OAAO,CAAC,IAAI;gBAAE,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;;gBACrF,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxC,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAA;QACrB,CAAC;IACH,CAAC,CACF,CAAA;AACL,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { Himalaya } from "./himalaya.js";
2
+ export interface Listed {
3
+ uid: string;
4
+ /** Gmail's own ids: the same in every folder, and they survive a UID reset. */
5
+ messageId: string;
6
+ threadId: string;
7
+ receivedAt: string;
8
+ folder?: string;
9
+ scopeFolder?: string;
10
+ }
11
+ /**
12
+ * Every message in All Mail received since `since`, read with EXAMINE so nothing can change a flag.
13
+ * All Mail rather than INBOX: an archived message leaves INBOX but is not deleted.
14
+ */
15
+ export declare const listAllMail: (run: Himalaya, account: string, since: Date, folder?: string) => Promise<Listed[]>;
16
+ /** Message-ID is stable across folders; absent headers fall back to a UIDVALIDITY-scoped identity. */
17
+ export declare const listImapMail: (run: Himalaya, account: string, since: Date, folder: string) => Promise<Listed[]>;
18
+ //# sourceMappingURL=gmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../src/mail/gmail.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAA;IACX,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAkCD;;;GAGG;AACH,eAAO,MAAM,WAAW,QACjB,QAAQ,WACJ,MAAM,SACR,IAAI,sBAEV,OAAO,CAAC,MAAM,EAAE,CAqClB,CAAA;AAED,sGAAsG;AACtG,eAAO,MAAM,YAAY,QAAe,QAAQ,WAAW,MAAM,SAAS,IAAI,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAkDhH,CAAA"}
@@ -0,0 +1,103 @@
1
+ import { createHash } from "node:crypto";
2
+ import { CliError } from "@wirecat/cli-core";
3
+ const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
4
+ const FETCH_BATCH = 500;
5
+ const imapDate = (day) => `${day.getUTCDate()}-${MONTHS[day.getUTCMonth()]}-${day.getUTCFullYear()}`;
6
+ /** IMAP's `INTERNALDATE`: `"04-Oct-2026 19:51:09 +0000"`. */
7
+ const isoOf = (internal) => {
8
+ const match = /^\s*(\d{1,2})-(\w{3})-(\d{4}) (\d{2}):(\d{2}):(\d{2}) ([+-])(\d{2})(\d{2})$/.exec(internal);
9
+ if (match === null)
10
+ throw new CliError("invalid_response", `unexpected IMAP date "${internal}"`);
11
+ const [, day, month, year, hour, minute, second, sign, offsetHours, offsetMinutes] = match;
12
+ const local = Date.UTC(Number(year), MONTHS.indexOf(month ?? ""), Number(day), Number(hour), Number(minute), Number(second));
13
+ const offset = (Number(offsetHours) * 60 + Number(offsetMinutes)) * 60_000 * (sign === "-" ? -1 : 1);
14
+ return new Date(local - offset).toISOString();
15
+ };
16
+ /** A tagged NO or BAD comes back as output, not as an error, so every tag must end in OK. */
17
+ const assertCompleted = (output, tags) => {
18
+ for (const tag of tags) {
19
+ if (!new RegExp(`^${tag} OK`, "m").test(output)) {
20
+ const line = output.split(/\r?\n/).find((text) => text.startsWith(`${tag} `)) ?? "no answer";
21
+ throw new CliError("provider_error", `IMAP command ${tag} did not complete: ${line}`);
22
+ }
23
+ }
24
+ };
25
+ /**
26
+ * Every message in All Mail received since `since`, read with EXAMINE so nothing can change a flag.
27
+ * All Mail rather than INBOX: an archived message leaves INBOX but is not deleted.
28
+ */
29
+ export const listAllMail = async (run, account, since, folder = "[Gmail]/All Mail") => {
30
+ if (/[\r\n]/.test(folder) || folder.includes(String.fromCharCode(0)))
31
+ throw new CliError("validation_error", "invalid mailbox name");
32
+ const mailbox = JSON.stringify(folder);
33
+ const search = await run(["imap", "raw", "-a", account], `a EXAMINE ${mailbox}\r\nb UID SEARCH SINCE ${imapDate(since)}\r\n`);
34
+ assertCompleted(search, ["a", "b"]);
35
+ const uids = (/^\* SEARCH(.*)$/m.exec(search)?.[1] ?? "").trim().split(/\s+/).filter(Boolean);
36
+ if (uids.length === 0)
37
+ return [];
38
+ const batches = [];
39
+ for (let start = 0; start < uids.length; start += FETCH_BATCH)
40
+ batches.push(uids.slice(start, start + FETCH_BATCH).join(","));
41
+ const tags = batches.map((_, index) => `f${index}`);
42
+ const fetched = await run(["imap", "raw", "-a", account], `a EXAMINE ${mailbox}\r\n${batches
43
+ .map((set, index) => `${tags[index]} UID FETCH ${set} (UID X-GM-MSGID X-GM-THRID INTERNALDATE)\r\n`)
44
+ .join("")}`);
45
+ assertCompleted(fetched, ["a", ...tags]);
46
+ const listed = [...fetched.matchAll(/^\* \d+ FETCH \((.*)\)\s*$/gm)].map(([, items = ""]) => {
47
+ const item = (name) => new RegExp(`${name} (\\d+)`).exec(items)?.[1];
48
+ const internal = /INTERNALDATE "([^"]+)"/.exec(items)?.[1];
49
+ const uid = item("UID");
50
+ const messageId = item("X-GM-MSGID");
51
+ const threadId = item("X-GM-THRID");
52
+ if (!uid || !messageId || !threadId || !internal)
53
+ throw new CliError("invalid_response", `IMAP FETCH answer without the Gmail ids: ${items}`);
54
+ return { uid, messageId, threadId, receivedAt: isoOf(internal) };
55
+ });
56
+ if (listed.length !== uids.length)
57
+ throw new CliError("invalid_response", `IMAP listed ${uids.length} messages but fetched ${listed.length}`);
58
+ return listed;
59
+ };
60
+ /** Message-ID is stable across folders; absent headers fall back to a UIDVALIDITY-scoped identity. */
61
+ export const listImapMail = async (run, account, since, folder) => {
62
+ if (!folder || /[\r\n]/.test(folder) || folder.includes(String.fromCharCode(0)))
63
+ throw new CliError("validation_error", "invalid mailbox name");
64
+ const mailbox = JSON.stringify(folder);
65
+ const searched = await run(["imap", "raw", "-a", account], `a EXAMINE ${mailbox}\r\nb UID SEARCH SINCE ${imapDate(since)}\r\n`);
66
+ assertCompleted(searched, ["a", "b"]);
67
+ const validity = /\[UIDVALIDITY (\d+)\]/.exec(searched)?.[1];
68
+ if (!validity)
69
+ throw new CliError("invalid_response", "IMAP did not report UIDVALIDITY");
70
+ const uids = [...new Set((/^\* SEARCH(.*)$/m.exec(searched)?.[1] ?? "").trim().split(/\s+/).filter(Boolean))];
71
+ if (!uids.every((uid) => /^\d+$/.test(uid)))
72
+ throw new CliError("invalid_response", "invalid IMAP UID listing");
73
+ const listed = [];
74
+ const digest = (id) => `imap:${createHash("sha256").update(id).digest("hex")}`;
75
+ for (let start = 0; start < uids.length; start += FETCH_BATCH) {
76
+ const batch = uids.slice(start, start + FETCH_BATCH);
77
+ const before = listed.length;
78
+ const output = await run(["imap", "raw", "-a", account], `a EXAMINE ${mailbox}\r\nf UID FETCH ${batch.join(",")} (UID INTERNALDATE BODY.PEEK[HEADER.FIELDS (MESSAGE-ID REFERENCES IN-REPLY-TO)])\r\n`);
79
+ assertCompleted(output, ["a", "f"]);
80
+ for (const match of output.matchAll(/^\* \d+ FETCH \(([\s\S]*?)(?=^\* \d+ FETCH|^[af] (?:OK|NO|BAD)|$(?![\s\S]))/gm)) {
81
+ const fields = match[1] ?? "", uid = /(?:^|\s)UID (\d+)/.exec(fields)?.[1], internal = /INTERNALDATE "([^"]+)"/.exec(fields)?.[1];
82
+ if (!uid || !internal || !batch.includes(uid))
83
+ throw new CliError("invalid_response", "incomplete IMAP envelope");
84
+ const unfolded = fields.replace(/\r?\n[ \t]+/g, " ");
85
+ const messageId = /^Message-ID:\s*(.+)$/im.exec(unfolded)?.[1]?.trim();
86
+ const refs = /^References:\s*(.+)$/im.exec(unfolded)?.[1]?.match(/<[^>]+>/g);
87
+ const parent = /^In-Reply-To:\s*(<[^>]+>)/im.exec(unfolded)?.[1];
88
+ const identity = messageId ?? `uid:${folder}:${validity}:${uid}`;
89
+ listed.push({
90
+ uid,
91
+ messageId: digest(identity),
92
+ threadId: digest(refs?.[0] ?? parent ?? identity),
93
+ receivedAt: isoOf(internal),
94
+ folder,
95
+ });
96
+ }
97
+ if (listed.length - before !== batch.length ||
98
+ new Set(listed.slice(before).map((item) => item.uid)).size !== batch.length)
99
+ throw new CliError("invalid_response", "IMAP returned a partial envelope batch; deletions were not checked");
100
+ }
101
+ return listed;
102
+ };
103
+ //# sourceMappingURL=gmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/mail/gmail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type Himalaya = (args: string[], input?: string) => Promise<string>;
2
+ /** `MEMO_HIMALAYA` names the program, so the test sandbox can point it at a fake. */
3
+ export declare const himalaya: (env?: NodeJS.ProcessEnv) => Himalaya;
4
+ //# sourceMappingURL=himalaya.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"himalaya.d.ts","sourceRoot":"","sources":["../../src/mail/himalaya.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAE1E,qFAAqF;AACrF,eAAO,MAAM,QAAQ,SACb,MAAM,CAAC,UAAU,KAAiB,QAgBpC,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { execFile } from "node:child_process";
2
+ import { CliError } from "@wirecat/cli-core";
3
+ /** `MEMO_HIMALAYA` names the program, so the test sandbox can point it at a fake. */
4
+ export const himalaya = (env = process.env) => (args, input) => new Promise((resolve, reject) => {
5
+ const child = execFile(env.MEMO_HIMALAYA ?? "himalaya", args, { env, maxBuffer: 64 * 1024 * 1024 }, (error, stdout, stderr) => {
6
+ if (error === null)
7
+ resolve(stdout);
8
+ else
9
+ reject(new CliError("provider_error", `himalaya ${args[0] ?? ""} failed: ${stderr.trim() || error.message}`));
10
+ });
11
+ child.stdin?.end(input ?? "");
12
+ });
13
+ //# sourceMappingURL=himalaya.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"himalaya.js","sourceRoot":"","sources":["../../src/mail/himalaya.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAI5C,qFAAqF;AACrF,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAY,EAAE,CACnD,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACd,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,MAAM,KAAK,GAAG,QAAQ,CACpB,GAAG,CAAC,aAAa,IAAI,UAAU,EAC/B,IAAI,EACJ,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EACpC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACxB,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,CAAC,MAAM,CAAC,CAAA;;YAEjC,MAAM,CACJ,IAAI,QAAQ,CAAC,gBAAgB,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CACtG,CAAA;IACL,CAAC,CACF,CAAA;IACD,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;AAC/B,CAAC,CAAC,CAAA"}
@@ -0,0 +1,53 @@
1
+ import { type LoadEngine } from "@wirecat/cli-messaging/documents";
2
+ import type { MessageStore } from "@wirecat/cli-messaging/store";
3
+ import { embedChanged, type NotesEmbedded } from "../notes/embed.js";
4
+ import type { Himalaya } from "./himalaya.js";
5
+ export interface MailAccount {
6
+ /** The account's name in Himalaya's config. */
7
+ name: string;
8
+ /** The mailbox address: the store's account id. */
9
+ address: string;
10
+ mode?: "gmail" | "imap";
11
+ folders?: string[];
12
+ embed?: boolean;
13
+ }
14
+ export interface ImportResult {
15
+ account: string;
16
+ since: string;
17
+ listed: number;
18
+ saved: number;
19
+ alreadyStored: number;
20
+ deleted: number;
21
+ /** False when `max` stopped the run before every new message was read; the next run continues. */
22
+ complete: boolean;
23
+ /** Why stored messages missing at the source were left alone, when they were. */
24
+ deletionsSkipped?: string;
25
+ indexed?: NotesEmbedded;
26
+ coverage?: {
27
+ folders: string[];
28
+ since: string;
29
+ until: string;
30
+ state: "window" | "partial";
31
+ identity: string;
32
+ };
33
+ attachments?: {
34
+ message: string;
35
+ part: number;
36
+ status: string;
37
+ locatorId?: string;
38
+ }[];
39
+ }
40
+ export declare const importMail: ({ store, run, account, since, max, now, env, embed, loadEngine, retryAttachments, indexThreads, }: {
41
+ store: MessageStore;
42
+ run: Himalaya;
43
+ account: MailAccount;
44
+ since: Date;
45
+ max?: number;
46
+ now?: () => number;
47
+ env?: NodeJS.ProcessEnv;
48
+ embed?: boolean;
49
+ loadEngine?: LoadEngine;
50
+ retryAttachments?: boolean;
51
+ indexThreads?: typeof embedChanged;
52
+ }) => Promise<ImportResult>;
53
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/mail/import.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC5E,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG7C,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,kGAAkG;IAClG,QAAQ,EAAE,OAAO,CAAA;IACjB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7G,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACtF;AAUD,eAAO,MAAM,UAAU,sGAYpB;IACD,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,QAAQ,CAAA;IACb,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,IAAI,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,OAAO,YAAY,CAAA;CACnC,KAAG,OAAO,CAAC,YAAY,CAgLvB,CAAA"}