oceanbus 0.3.3 → 0.4.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 (41) hide show
  1. package/dist/agent/identity.d.ts +2 -2
  2. package/dist/agent/identity.d.ts.map +1 -1
  3. package/dist/agent/identity.js +1 -1
  4. package/dist/agent/identity.js.map +1 -1
  5. package/dist/crypto/pow.d.ts +2 -2
  6. package/dist/crypto/pow.d.ts.map +1 -1
  7. package/dist/crypto/pow.js +17 -18
  8. package/dist/crypto/pow.js.map +1 -1
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +11 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/roster/auto-discovery.d.ts +18 -0
  14. package/dist/roster/auto-discovery.d.ts.map +1 -0
  15. package/dist/roster/auto-discovery.js +109 -0
  16. package/dist/roster/auto-discovery.js.map +1 -0
  17. package/dist/roster/index.d.ts +44 -0
  18. package/dist/roster/index.d.ts.map +1 -0
  19. package/dist/roster/index.js +278 -0
  20. package/dist/roster/index.js.map +1 -0
  21. package/dist/roster/indexes.d.ts +6 -0
  22. package/dist/roster/indexes.d.ts.map +1 -0
  23. package/dist/roster/indexes.js +70 -0
  24. package/dist/roster/indexes.js.map +1 -0
  25. package/dist/roster/search.d.ts +34 -0
  26. package/dist/roster/search.d.ts.map +1 -0
  27. package/dist/roster/search.js +272 -0
  28. package/dist/roster/search.js.map +1 -0
  29. package/dist/roster/store.d.ts +14 -0
  30. package/dist/roster/store.d.ts.map +1 -0
  31. package/dist/roster/store.js +154 -0
  32. package/dist/roster/store.js.map +1 -0
  33. package/dist/types/index.d.ts +1 -0
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/types/index.js +1 -0
  36. package/dist/types/index.js.map +1 -1
  37. package/dist/types/roster.d.ts +123 -0
  38. package/dist/types/roster.d.ts.map +1 -0
  39. package/dist/types/roster.js +4 -0
  40. package/dist/types/roster.js.map +1 -0
  41. package/package.json +1 -1
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RosterService = void 0;
4
+ const store_1 = require("./store");
5
+ const search_1 = require("./search");
6
+ const indexes_1 = require("./indexes");
7
+ const auto_discovery_1 = require("./auto-discovery");
8
+ class RosterService {
9
+ store;
10
+ data = null;
11
+ constructor(store) {
12
+ this.store = store || new store_1.RosterStore();
13
+ }
14
+ async ensureLoaded() {
15
+ if (!this.data) {
16
+ this.data = await this.store.load();
17
+ }
18
+ return this.data;
19
+ }
20
+ async save() {
21
+ if (!this.data)
22
+ return;
23
+ await this.store.save(this.data);
24
+ }
25
+ // ── Query ──
26
+ async search(query) {
27
+ const d = await this.ensureLoaded();
28
+ return (0, search_1.search)(d.contacts, query);
29
+ }
30
+ async get(id) {
31
+ const d = await this.ensureLoaded();
32
+ return (0, search_1.getById)(d.contacts, id);
33
+ }
34
+ async findByAgentId(agentId) {
35
+ const d = await this.ensureLoaded();
36
+ return (0, search_1.findByAgentId)(d.contacts, d.indexes, agentId);
37
+ }
38
+ async findByOpenId(openId) {
39
+ const d = await this.ensureLoaded();
40
+ return (0, search_1.findByOpenId)(d.contacts, d.indexes, openId);
41
+ }
42
+ async list(filter) {
43
+ const d = await this.ensureLoaded();
44
+ return (0, search_1.list)(d.contacts, filter);
45
+ }
46
+ // ── Write ──
47
+ async add(input) {
48
+ const d = await this.ensureLoaded();
49
+ const now = new Date().toISOString();
50
+ const id = input.id || (0, search_1.slugFromName)(input.name);
51
+ // Check uniqueness
52
+ if (d.contacts.some(c => c.id === id && c.status !== 'archived')) {
53
+ throw new Error(`Contact with id "${id}" already exists`);
54
+ }
55
+ const provenance = buildProvenance(input.source, null, now);
56
+ const contact = {
57
+ id,
58
+ name: input.name,
59
+ agents: input.agents || [],
60
+ tags: input.tags || [],
61
+ aliases: input.aliases || [],
62
+ notes: input.notes || '',
63
+ source: input.source,
64
+ provenance,
65
+ status: input.status || 'active',
66
+ lastContactAt: now,
67
+ createdAt: now,
68
+ updatedAt: now,
69
+ apps: {},
70
+ };
71
+ d.contacts.push(contact);
72
+ (0, indexes_1.addToIndexes)(d.indexes, contact);
73
+ // Auto-detect duplicates
74
+ const newHints = (0, search_1.findDuplicates)(contact, d.contacts, d.duplicateHints, now);
75
+ if (newHints.length > 0) {
76
+ d.duplicateHints.push(...newHints);
77
+ }
78
+ await this.save();
79
+ return { contact, duplicateHints: newHints };
80
+ }
81
+ async update(id, patch) {
82
+ const d = await this.ensureLoaded();
83
+ const contact = (0, search_1.getById)(d.contacts, id);
84
+ if (!contact)
85
+ throw new Error(`Contact "${id}" not found`);
86
+ const oldTags = [...contact.tags];
87
+ const oldAgentIds = contact.agents.map(a => a.agentId);
88
+ const oldOpenIds = contact.agents.map(a => a.openId);
89
+ if (patch.name !== undefined)
90
+ contact.name = patch.name;
91
+ if (patch.agents !== undefined)
92
+ contact.agents = patch.agents;
93
+ if (patch.tags !== undefined)
94
+ contact.tags = patch.tags;
95
+ if (patch.aliases !== undefined)
96
+ contact.aliases = patch.aliases;
97
+ if (patch.notes !== undefined)
98
+ contact.notes = patch.notes;
99
+ if (patch.source !== undefined)
100
+ contact.source = patch.source;
101
+ if (patch.status !== undefined)
102
+ contact.status = patch.status;
103
+ if (patch.lastContactAt !== undefined)
104
+ contact.lastContactAt = patch.lastContactAt;
105
+ contact.updatedAt = new Date().toISOString();
106
+ if (contact.provenance)
107
+ contact.provenance.lastVerifiedAt = contact.updatedAt;
108
+ // Update indexes
109
+ if (patch.tags) {
110
+ (0, indexes_1.updateTagsInIndexes)(d.indexes, contact, oldTags, patch.tags);
111
+ }
112
+ if (patch.agents) {
113
+ (0, indexes_1.updateAgentsInIndexes)(d.indexes, contact.id, oldAgentIds, oldOpenIds, contact.agents.map(a => a.agentId), contact.agents.map(a => a.openId));
114
+ }
115
+ await this.save();
116
+ return contact;
117
+ }
118
+ async updateAppData(id, appName, data) {
119
+ const d = await this.ensureLoaded();
120
+ const contact = (0, search_1.getById)(d.contacts, id);
121
+ if (!contact)
122
+ throw new Error(`Contact "${id}" not found`);
123
+ contact.apps[appName] = data;
124
+ contact.updatedAt = new Date().toISOString();
125
+ await this.save();
126
+ return contact;
127
+ }
128
+ async delete(id, soft = true) {
129
+ const d = await this.ensureLoaded();
130
+ const contact = (0, search_1.getById)(d.contacts, id);
131
+ if (!contact)
132
+ throw new Error(`Contact "${id}" not found`);
133
+ if (soft) {
134
+ contact.status = 'archived';
135
+ contact.updatedAt = new Date().toISOString();
136
+ (0, indexes_1.removeFromIndexes)(d.indexes, contact);
137
+ }
138
+ else {
139
+ (0, indexes_1.removeFromIndexes)(d.indexes, contact);
140
+ d.contacts = d.contacts.filter(c => c.id !== id);
141
+ }
142
+ await this.save();
143
+ }
144
+ async merge(keepId, discardId) {
145
+ const d = await this.ensureLoaded();
146
+ const keep = (0, search_1.getById)(d.contacts, keepId);
147
+ const discard = (0, search_1.getById)(d.contacts, discardId);
148
+ if (!keep)
149
+ throw new Error(`Contact "${keepId}" not found`);
150
+ if (!discard)
151
+ throw new Error(`Contact "${discardId}" not found`);
152
+ // Merge agents (dedup by openId — the one identifier we always have)
153
+ const seenOpenIds = new Set(keep.agents.map(a => a.openId));
154
+ for (const a of discard.agents) {
155
+ if (!seenOpenIds.has(a.openId)) {
156
+ keep.agents.push(a);
157
+ seenOpenIds.add(a.openId);
158
+ }
159
+ }
160
+ keep.aliases = [...new Set([...keep.aliases, ...discard.aliases, discard.name])];
161
+ keep.tags = [...new Set([...keep.tags, ...discard.tags])];
162
+ if (discard.notes)
163
+ keep.notes = keep.notes ? `${keep.notes}; ${discard.notes}` : discard.notes;
164
+ keep.lastContactAt = keep.lastContactAt > discard.lastContactAt ? keep.lastContactAt : discard.lastContactAt;
165
+ keep.updatedAt = new Date().toISOString();
166
+ if (keep.provenance)
167
+ keep.provenance.lastVerifiedAt = keep.updatedAt;
168
+ // Merge app data (keep wins on conflict)
169
+ for (const [app, appData] of Object.entries(discard.apps)) {
170
+ if (!keep.apps[app])
171
+ keep.apps[app] = appData;
172
+ }
173
+ // Dismiss duplicate hints involving either contact
174
+ d.duplicateHints = (0, search_1.dismissHintsForContact)(d.duplicateHints, keepId);
175
+ d.duplicateHints = (0, search_1.dismissHintsForContact)(d.duplicateHints, discardId);
176
+ // Soft-delete discard
177
+ (0, indexes_1.removeFromIndexes)(d.indexes, discard);
178
+ discard.status = 'archived';
179
+ discard.updatedAt = new Date().toISOString();
180
+ // Rebuild indexes for keep
181
+ (0, indexes_1.removeFromIndexes)(d.indexes, keep);
182
+ (0, indexes_1.addToIndexes)(d.indexes, keep);
183
+ await this.save();
184
+ return keep;
185
+ }
186
+ async addAlias(id, alias) {
187
+ const contact = await this.get(id);
188
+ if (!contact)
189
+ throw new Error(`Contact "${id}" not found`);
190
+ if (contact.aliases.includes(alias))
191
+ return contact;
192
+ return this.update(id, { aliases: [...contact.aliases, alias] });
193
+ }
194
+ async updateTags(id, tags) {
195
+ return this.update(id, { tags });
196
+ }
197
+ async touch(id) {
198
+ await this.update(id, { lastContactAt: new Date().toISOString() });
199
+ }
200
+ // ── Auto-discovery ──
201
+ async scanText(text) {
202
+ const d = await this.ensureLoaded();
203
+ const names = (0, auto_discovery_1.extractNames)(text, d.autoDiscovery.ignoreList, d.contacts);
204
+ const now = new Date().toISOString();
205
+ const added = (0, auto_discovery_1.processPending)(d.autoDiscovery, names, now);
206
+ if (added.length > 0)
207
+ await this.save();
208
+ return { newPending: added, totalPending: d.autoDiscovery.pending.length };
209
+ }
210
+ async getPending() {
211
+ const d = await this.ensureLoaded();
212
+ return d.autoDiscovery.pending;
213
+ }
214
+ async approvePending(pendingId) {
215
+ const d = await this.ensureLoaded();
216
+ const idx = d.autoDiscovery.pending.findIndex(p => p.id === pendingId);
217
+ if (idx === -1)
218
+ throw new Error(`Pending entry "${pendingId}" not found`);
219
+ const entry = d.autoDiscovery.pending[idx];
220
+ d.autoDiscovery.pending.splice(idx, 1);
221
+ const { contact } = await this.add({
222
+ name: entry.name,
223
+ source: 'auto-discovery',
224
+ notes: `Auto-discovered from: ${entry.contexts.join(' | ')}`,
225
+ });
226
+ await this.save();
227
+ return contact;
228
+ }
229
+ async rejectPending(pendingId) {
230
+ const d = await this.ensureLoaded();
231
+ const entry = d.autoDiscovery.pending.find(p => p.id === pendingId);
232
+ if (!entry)
233
+ throw new Error(`Pending entry "${pendingId}" not found`);
234
+ d.autoDiscovery.pending = d.autoDiscovery.pending.filter(p => p.id !== pendingId);
235
+ if (!d.autoDiscovery.ignoreList.includes(entry.name)) {
236
+ d.autoDiscovery.ignoreList.push(entry.name);
237
+ }
238
+ await this.save();
239
+ }
240
+ // ── Identities (self) ──
241
+ async getIdentities() {
242
+ const d = await this.ensureLoaded();
243
+ return d.identities;
244
+ }
245
+ // ── Duplicate hints ──
246
+ async getDuplicateHints() {
247
+ const d = await this.ensureLoaded();
248
+ return d.duplicateHints;
249
+ }
250
+ /** Dismiss a single hint (user chose "keep separate"). */
251
+ async dismissDuplicateHint(contactA, contactB) {
252
+ const d = await this.ensureLoaded();
253
+ d.duplicateHints = d.duplicateHints.filter(h => !(h.contactA === contactA && h.contactB === contactB) &&
254
+ !(h.contactA === contactB && h.contactB === contactA));
255
+ await this.save();
256
+ }
257
+ // ── Stats ──
258
+ async stats() {
259
+ const d = await this.ensureLoaded();
260
+ return {
261
+ total: d.contacts.length,
262
+ active: d.contacts.filter(c => c.status === 'active').length,
263
+ pending: d.contacts.filter(c => c.status === 'pending').length,
264
+ archived: d.contacts.filter(c => c.status === 'archived').length,
265
+ };
266
+ }
267
+ }
268
+ exports.RosterService = RosterService;
269
+ // ── Helpers ──
270
+ function buildProvenance(source, sourceId, now) {
271
+ return {
272
+ account: source,
273
+ sourceId,
274
+ firstSeenAt: now,
275
+ lastVerifiedAt: now,
276
+ };
277
+ }
278
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/roster/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Contact, RosterIndexes } from '../types/roster';
2
+ export declare function addToIndexes(indexes: RosterIndexes, contact: Contact): void;
3
+ export declare function removeFromIndexes(indexes: RosterIndexes, contact: Contact): void;
4
+ export declare function updateTagsInIndexes(indexes: RosterIndexes, contact: Contact, oldTags: string[], newTags: string[]): void;
5
+ export declare function updateAgentsInIndexes(indexes: RosterIndexes, contactId: string, oldAgentIds: string[], oldOpenIds: string[], newAgentIds: string[], newOpenIds: string[]): void;
6
+ //# sourceMappingURL=indexes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.d.ts","sourceRoot":"","sources":["../../src/roster/indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9D,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAU3E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAYhF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAexH;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAW/K"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addToIndexes = addToIndexes;
4
+ exports.removeFromIndexes = removeFromIndexes;
5
+ exports.updateTagsInIndexes = updateTagsInIndexes;
6
+ exports.updateAgentsInIndexes = updateAgentsInIndexes;
7
+ function addToIndexes(indexes, contact) {
8
+ for (const tag of contact.tags) {
9
+ if (!indexes.byTag[tag])
10
+ indexes.byTag[tag] = [];
11
+ if (!indexes.byTag[tag].includes(contact.id))
12
+ indexes.byTag[tag].push(contact.id);
13
+ }
14
+ for (const a of contact.agents) {
15
+ // OpenID is always known (it's the public address). agentId is only known for our own identities.
16
+ indexes.byOpenId[a.openId] = contact.id;
17
+ if (a.agentId)
18
+ indexes.byAgentId[a.agentId] = contact.id;
19
+ }
20
+ }
21
+ function removeFromIndexes(indexes, contact) {
22
+ for (const tag of contact.tags) {
23
+ const list = indexes.byTag[tag];
24
+ if (list) {
25
+ indexes.byTag[tag] = list.filter(id => id !== contact.id);
26
+ if (indexes.byTag[tag].length === 0)
27
+ delete indexes.byTag[tag];
28
+ }
29
+ }
30
+ for (const a of contact.agents) {
31
+ if (indexes.byOpenId[a.openId] === contact.id)
32
+ delete indexes.byOpenId[a.openId];
33
+ if (a.agentId && indexes.byAgentId[a.agentId] === contact.id)
34
+ delete indexes.byAgentId[a.agentId];
35
+ }
36
+ }
37
+ function updateTagsInIndexes(indexes, contact, oldTags, newTags) {
38
+ const added = newTags.filter(t => !oldTags.includes(t));
39
+ const removed = oldTags.filter(t => !newTags.includes(t));
40
+ for (const tag of added) {
41
+ if (!indexes.byTag[tag])
42
+ indexes.byTag[tag] = [];
43
+ if (!indexes.byTag[tag].includes(contact.id))
44
+ indexes.byTag[tag].push(contact.id);
45
+ }
46
+ for (const tag of removed) {
47
+ const list = indexes.byTag[tag];
48
+ if (list) {
49
+ indexes.byTag[tag] = list.filter(id => id !== contact.id);
50
+ if (indexes.byTag[tag].length === 0)
51
+ delete indexes.byTag[tag];
52
+ }
53
+ }
54
+ }
55
+ function updateAgentsInIndexes(indexes, contactId, oldAgentIds, oldOpenIds, newAgentIds, newOpenIds) {
56
+ for (const aid of oldAgentIds) {
57
+ if (indexes.byAgentId[aid] === contactId)
58
+ delete indexes.byAgentId[aid];
59
+ }
60
+ for (const oid of oldOpenIds) {
61
+ if (indexes.byOpenId[oid] === contactId)
62
+ delete indexes.byOpenId[oid];
63
+ }
64
+ for (let i = 0; i < newAgentIds.length; i++) {
65
+ indexes.byOpenId[newOpenIds[i]] = contactId;
66
+ if (newAgentIds[i])
67
+ indexes.byAgentId[newAgentIds[i]] = contactId;
68
+ }
69
+ }
70
+ //# sourceMappingURL=indexes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/roster/indexes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Contact, SearchResult, RosterFilter, DuplicateHint } from '../types/roster';
2
+ /**
3
+ * Search contacts with conservative fuzzy matching.
4
+ * Exact: query matches id, name, or any alias exactly (case-insensitive).
5
+ * Fuzzy: query is a substring of name or alias (after normalizing spaces/punctuation).
6
+ * byTag: query matches any tag.
7
+ * byNote: query appears in notes.
8
+ *
9
+ * The result is a structured candidate set — disambiguation is the LLM's job.
10
+ */
11
+ export declare function search(contacts: Contact[], query: string): SearchResult;
12
+ export declare function getById(contacts: Contact[], id: string): Contact | null;
13
+ export declare function findByAgentId(contacts: Contact[], indexes: {
14
+ byAgentId: Record<string, string>;
15
+ }, agentId: string): Contact | null;
16
+ export declare function findByOpenId(contacts: Contact[], indexes: {
17
+ byOpenId: Record<string, string>;
18
+ }, openId: string): Contact | null;
19
+ export declare function list(contacts: Contact[], filter?: RosterFilter): Contact[];
20
+ /** Generate a slug from a Chinese or English name */
21
+ export declare function slugFromName(name: string): string;
22
+ /**
23
+ * Check if a new or updated contact looks like a duplicate of an existing one.
24
+ * Rules (in priority order):
25
+ * 1. Same OpenID — high confidence (0.95)
26
+ * 2. Same AgentID — high confidence (0.90)
27
+ * 3. Name highly similar — medium confidence (0.60–0.85)
28
+ *
29
+ * Returns hints for NEW potential duplicates not already in existingHints.
30
+ */
31
+ export declare function findDuplicates(incoming: Contact, existingContacts: Contact[], existingHints: DuplicateHint[], now: string): DuplicateHint[];
32
+ /** Dismiss a hint (called after user decides keep-separate or after merge) */
33
+ export declare function dismissHintsForContact(hints: DuplicateHint[], contactId: string): DuplicateHint[];
34
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/roster/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAc,YAAY,EAAE,YAAY,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AA4BvH;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAuEvE;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAEvE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAIlI;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAI/H;AAED,wBAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,EAAE,CA4B1E;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQjD;AAID;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,OAAO,EACjB,gBAAgB,EAAE,OAAO,EAAE,EAC3B,aAAa,EAAE,aAAa,EAAE,EAC9B,GAAG,EAAE,MAAM,GACV,aAAa,EAAE,CA0DjB;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAEjG"}