@agentshouse/mdruntime 0.1.0-c7bd7ca3faee4 → 0.1.0-c7dd6612b99d5
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.
- package/README.md +21 -8
- package/dist/adapter.d.ts +139 -32
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +38 -4
- package/dist/attempt.d.ts +16 -0
- package/dist/attempt.d.ts.map +1 -0
- package/dist/attempt.js +70 -0
- package/dist/binary.d.ts +18 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +8 -0
- package/dist/bootstrap.d.ts +37 -6
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +196 -48
- package/dist/chain.d.ts +11 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +68 -0
- package/dist/change-set.d.ts +9 -14
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -56
- package/dist/change.d.ts +45 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +34 -0
- package/dist/client.d.ts +33 -14
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +123 -21
- package/dist/collection.d.ts +14 -13
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +66 -54
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +771 -0
- package/dist/connection.d.ts +61 -20
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +3883 -746
- package/dist/conversation.d.ts +44 -15
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +690 -192
- package/dist/digest.d.ts +7 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +113 -0
- package/dist/durability.d.ts +5 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +20 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +151 -0
- package/dist/expectation.d.ts +21 -0
- package/dist/expectation.d.ts.map +1 -0
- package/dist/expectation.js +70 -0
- package/dist/failure.d.ts +13 -0
- package/dist/failure.d.ts.map +1 -0
- package/dist/failure.js +19 -0
- package/dist/fence.d.ts +6 -0
- package/dist/fence.d.ts.map +1 -0
- package/dist/fence.js +10 -0
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +7 -122
- package/dist/fulltext.d.ts +27 -0
- package/dist/fulltext.d.ts.map +1 -0
- package/dist/fulltext.js +370 -0
- package/dist/host.d.ts +15 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +134 -22
- package/dist/identity.d.ts +4 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +16 -1
- package/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/live.d.ts +22 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +124 -0
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +208 -0
- package/dist/memory.d.ts +13 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +137 -34
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +90 -0
- package/dist/model.d.ts +13 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +17 -2
- package/dist/name.d.ts +4 -0
- package/dist/name.d.ts.map +1 -0
- package/dist/name.js +122 -0
- package/dist/observation.d.ts +20 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +113 -12
- package/dist/open.d.ts +2 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +1 -0
- package/dist/opened.d.ts +22 -0
- package/dist/opened.d.ts.map +1 -0
- package/dist/opened.js +107 -0
- package/dist/outcome.d.ts +73 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +81 -1
- package/dist/overlay.d.ts +15 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +136 -180
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -0
- package/dist/query.d.ts +70 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +51 -7
- package/dist/reach.d.ts +18 -4
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +246 -68
- package/dist/react.d.ts +12 -8
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +8 -17
- package/dist/readiness.d.ts +63 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +33 -0
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +91 -0
- package/dist/recovery.d.ts +25 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +198 -0
- package/dist/refresh.d.ts +19 -8
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +125 -57
- package/dist/replica.d.ts +59 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +321 -155
- package/dist/room-draft.d.ts +57 -10
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +222 -39
- package/dist/rows.d.ts +39 -35
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +176 -99
- package/dist/save.d.ts +73 -4
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +825 -150
- package/dist/search.d.ts +41 -29
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +37 -105
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +75 -0
- package/dist/shared.d.ts +16 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +431 -0
- package/dist/status.d.ts +11 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -9
- package/dist/store.d.ts +121 -61
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +352 -354
- package/dist/stored.d.ts +135 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +568 -0
- package/dist/tables.d.ts +352 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +621 -0
- package/dist/turn.d.ts +9 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +75 -0
- package/dist/validation.d.ts +30 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +162 -0
- package/dist/windows.d.ts +22 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +89 -0
- package/dist/wire.d.ts +172 -33
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +68 -31
- package/dist/words.d.ts +19 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +156 -0
- package/package.json +26 -15
- package/AGENTS.md +0 -253
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
- package/dist/read-side.d.ts +0 -18
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -433
package/dist/media.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
export const ROOM_MEDIA = 'room-media';
|
|
2
|
+
const ATTRIBUTES = ['room', 'path', 'revision', 'width', 'height', 'alt'];
|
|
3
|
+
const LOADING = new Set(['room', 'path', 'revision']);
|
|
4
|
+
const NEARING = '600px 0px';
|
|
5
|
+
const RELINKS = 2;
|
|
6
|
+
// The Room's stream brings a file seconds after the text that links it, minutes after on a first open, and a page's reach of its Rooms settles seconds after it opens, so a file not shown yet is asked for again every three seconds.
|
|
7
|
+
const UNSHOWN_MS = 3_000;
|
|
8
|
+
const SHAPE = '16 / 9';
|
|
9
|
+
const STYLE = `:host{display:block}
|
|
10
|
+
[part=box]{position:relative;overflow:hidden}
|
|
11
|
+
[part=box]>img,[part=box]>video,[part=box]>audio{display:block;width:100%;height:100%;object-fit:contain}
|
|
12
|
+
[part=box]>slot{display:flex;align-items:center;justify-content:center;width:100%;height:100%;text-align:center}`;
|
|
13
|
+
const shows = new WeakMap();
|
|
14
|
+
export function shownBy(show, client) {
|
|
15
|
+
shows.set(client, show);
|
|
16
|
+
return client;
|
|
17
|
+
}
|
|
18
|
+
function ratioOf(width, height) {
|
|
19
|
+
const across = Number(width);
|
|
20
|
+
const down = Number(height);
|
|
21
|
+
return Number.isFinite(across) && Number.isFinite(down) && across > 0 && down > 0
|
|
22
|
+
? `${across} / ${down}`
|
|
23
|
+
: SHAPE;
|
|
24
|
+
}
|
|
25
|
+
function refusedForGood(shown) {
|
|
26
|
+
if (shown.kind === 'revoked-authorization')
|
|
27
|
+
return true;
|
|
28
|
+
return (shown.kind === 'rejected' || shown.kind === 'scoped-refusal') && !shown.retryable;
|
|
29
|
+
}
|
|
30
|
+
function drawnFor(mediaType) {
|
|
31
|
+
if (mediaType.startsWith('image/'))
|
|
32
|
+
return 'img';
|
|
33
|
+
if (mediaType.startsWith('video/'))
|
|
34
|
+
return 'video';
|
|
35
|
+
if (mediaType.startsWith('audio/'))
|
|
36
|
+
return 'audio';
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
export function defineRoomMedia(client, registry = customElements) {
|
|
40
|
+
if (registry.get(ROOM_MEDIA) !== undefined)
|
|
41
|
+
return;
|
|
42
|
+
const connected = Promise.resolve(client);
|
|
43
|
+
class RoomMedia extends HTMLElement {
|
|
44
|
+
static observedAttributes = ATTRIBUTES;
|
|
45
|
+
#root = this.attachShadow({ mode: 'open' });
|
|
46
|
+
#box = document.createElement('div');
|
|
47
|
+
#fallback = document.createElement('slot');
|
|
48
|
+
#watching = null;
|
|
49
|
+
#near = false;
|
|
50
|
+
#asked = 0;
|
|
51
|
+
#shown = null;
|
|
52
|
+
#drawn = null;
|
|
53
|
+
#loaded = false;
|
|
54
|
+
#relinked = 0;
|
|
55
|
+
constructor() {
|
|
56
|
+
super();
|
|
57
|
+
this.#box.setAttribute('part', 'box');
|
|
58
|
+
this.#root.append(Object.assign(document.createElement('style'), { textContent: STYLE }), this.#box);
|
|
59
|
+
this.#shape();
|
|
60
|
+
}
|
|
61
|
+
connectedCallback() {
|
|
62
|
+
this.#label();
|
|
63
|
+
this.#watching ??= new IntersectionObserver((seen) => {
|
|
64
|
+
if (!seen.some((entry) => entry.isIntersecting) || this.#near)
|
|
65
|
+
return;
|
|
66
|
+
this.#near = true;
|
|
67
|
+
void this.#load();
|
|
68
|
+
}, { rootMargin: NEARING });
|
|
69
|
+
this.#watching.observe(this);
|
|
70
|
+
}
|
|
71
|
+
disconnectedCallback() {
|
|
72
|
+
this.#watching?.disconnect();
|
|
73
|
+
this.#watching = null;
|
|
74
|
+
this.#near = false;
|
|
75
|
+
this.#asked += 1;
|
|
76
|
+
this.#show(null);
|
|
77
|
+
}
|
|
78
|
+
attributeChangedCallback(name, before, after) {
|
|
79
|
+
if (before === after)
|
|
80
|
+
return;
|
|
81
|
+
this.#shape();
|
|
82
|
+
if (this.isConnected)
|
|
83
|
+
this.#label();
|
|
84
|
+
if (!LOADING.has(name) || !this.#near)
|
|
85
|
+
return;
|
|
86
|
+
this.#relinked = 0;
|
|
87
|
+
void this.#load();
|
|
88
|
+
}
|
|
89
|
+
#shape() {
|
|
90
|
+
this.#box.style.aspectRatio = ratioOf(this.getAttribute('width'), this.getAttribute('height'));
|
|
91
|
+
}
|
|
92
|
+
#label() {
|
|
93
|
+
const alt = this.getAttribute('alt') ?? '';
|
|
94
|
+
const drawn = this.#drawn;
|
|
95
|
+
if (drawn instanceof HTMLMediaElement) {
|
|
96
|
+
this.removeAttribute('role');
|
|
97
|
+
this.removeAttribute('aria-label');
|
|
98
|
+
drawn.setAttribute('aria-label', alt);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.setAttribute('role', 'img');
|
|
102
|
+
this.setAttribute('aria-label', alt);
|
|
103
|
+
if (drawn !== null)
|
|
104
|
+
drawn.alt = '';
|
|
105
|
+
}
|
|
106
|
+
async #load() {
|
|
107
|
+
const asked = (this.#asked += 1);
|
|
108
|
+
this.#loaded = false;
|
|
109
|
+
const room = this.getAttribute('room');
|
|
110
|
+
const path = this.getAttribute('path');
|
|
111
|
+
const revision = this.getAttribute('revision') ?? undefined;
|
|
112
|
+
if (room === null || path === null) {
|
|
113
|
+
this.#unreadable();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const show = shows.get(await connected);
|
|
117
|
+
const shown = show === undefined ? null : await show(room, path, revision);
|
|
118
|
+
if (asked !== this.#asked)
|
|
119
|
+
return;
|
|
120
|
+
if (shown?.kind === 'link') {
|
|
121
|
+
this.#draw({ url: shown.url, copy: false }, shown.mediaType);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (shown?.kind !== 'binary') {
|
|
125
|
+
this.#unreadable();
|
|
126
|
+
if (shown === null || refusedForGood(shown))
|
|
127
|
+
return;
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
if (asked === this.#asked && this.#near)
|
|
130
|
+
void this.#load();
|
|
131
|
+
}, UNSHOWN_MS);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const copy = await new Response(shown.stream, {
|
|
135
|
+
headers: { 'content-type': shown.mediaType },
|
|
136
|
+
}).blob();
|
|
137
|
+
if (asked !== this.#asked)
|
|
138
|
+
return;
|
|
139
|
+
this.#draw({ url: URL.createObjectURL(copy), copy: true }, shown.mediaType);
|
|
140
|
+
}
|
|
141
|
+
#show(shown, content = null) {
|
|
142
|
+
if (this.#shown?.copy === true)
|
|
143
|
+
URL.revokeObjectURL(this.#shown.url);
|
|
144
|
+
this.#shown = shown;
|
|
145
|
+
if (content !== this.#drawn)
|
|
146
|
+
this.#drawn = null;
|
|
147
|
+
if (content === null)
|
|
148
|
+
this.#box.replaceChildren();
|
|
149
|
+
else if (content.parentNode !== this.#box)
|
|
150
|
+
this.#box.replaceChildren(content);
|
|
151
|
+
this.#label();
|
|
152
|
+
}
|
|
153
|
+
#unreadable() {
|
|
154
|
+
this.#show(null, this.#fallback);
|
|
155
|
+
}
|
|
156
|
+
#draw(shown, mediaType) {
|
|
157
|
+
const tag = drawnFor(mediaType);
|
|
158
|
+
if (tag === null) {
|
|
159
|
+
if (shown.copy)
|
|
160
|
+
URL.revokeObjectURL(shown.url);
|
|
161
|
+
this.#unreadable();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const kept = this.#drawn?.localName === tag ? this.#drawn : null;
|
|
165
|
+
const drawn = kept ?? document.createElement(tag);
|
|
166
|
+
if (kept === null) {
|
|
167
|
+
if (drawn instanceof HTMLImageElement)
|
|
168
|
+
drawn.decoding = 'async';
|
|
169
|
+
if (drawn instanceof HTMLMediaElement) {
|
|
170
|
+
drawn.controls = true;
|
|
171
|
+
drawn.preload = 'metadata';
|
|
172
|
+
if (drawn instanceof HTMLVideoElement)
|
|
173
|
+
drawn.playsInline = true;
|
|
174
|
+
}
|
|
175
|
+
drawn.addEventListener(drawn instanceof HTMLImageElement ? 'load' : 'loadedmetadata', () => {
|
|
176
|
+
if (drawn !== this.#drawn)
|
|
177
|
+
return;
|
|
178
|
+
this.#loaded = true;
|
|
179
|
+
this.#relinked = 0;
|
|
180
|
+
});
|
|
181
|
+
drawn.addEventListener('error', () => this.#failed(drawn));
|
|
182
|
+
}
|
|
183
|
+
this.#drawn = drawn;
|
|
184
|
+
this.#show(shown, drawn);
|
|
185
|
+
drawn.src = shown.url;
|
|
186
|
+
}
|
|
187
|
+
#failed(drawn) {
|
|
188
|
+
if (drawn !== this.#drawn)
|
|
189
|
+
return;
|
|
190
|
+
if (this.#shown?.copy !== false || !this.#loaded || this.#relinked >= RELINKS) {
|
|
191
|
+
this.#unreadable();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
this.#relinked += 1;
|
|
195
|
+
if (drawn instanceof HTMLMediaElement) {
|
|
196
|
+
const at = drawn.currentTime;
|
|
197
|
+
const playing = !drawn.paused;
|
|
198
|
+
drawn.addEventListener('loadedmetadata', () => {
|
|
199
|
+
drawn.currentTime = at;
|
|
200
|
+
if (playing)
|
|
201
|
+
void drawn.play().catch(() => undefined);
|
|
202
|
+
}, { once: true });
|
|
203
|
+
}
|
|
204
|
+
void this.#load();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
registry.define(ROOM_MEDIA, RoomMedia);
|
|
208
|
+
}
|
package/dist/memory.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import type { ModelResult } from './model.js';
|
|
2
|
-
import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type HeadChange, type ListedConversation, type Member, type ProviderLimit, type Retention, type
|
|
2
|
+
import { type AcceptedMessage, type ActionResult, type Adapter, type BinaryFile, type Capability, type ConversationAction, type ConversationEvent, type DiscoveryScope, type DiscoveredRoom, type HeadChange, type ListedConversation, type Member, type ProviderLimit, type Retention, type ServiceMode } from './adapter.js';
|
|
3
3
|
export type MemoryRoom = DiscoveredRoom & {
|
|
4
4
|
model?: ModelResult;
|
|
5
|
-
selectionModel?: ModelResult;
|
|
6
5
|
documents?: Readonly<Record<string, string>>;
|
|
7
6
|
revisions?: Readonly<Record<string, string>>;
|
|
7
|
+
fileIds?: Readonly<Record<string, string>>;
|
|
8
8
|
changes?: Readonly<Record<string, HeadChange>>;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
binaryFiles?: Readonly<Record<string, BinaryFile>>;
|
|
10
|
+
folders?: readonly string[];
|
|
11
|
+
blobs?: Readonly<Record<string, Blob>>;
|
|
11
12
|
};
|
|
12
13
|
export type MemoryConversation = {
|
|
13
14
|
conversation: string;
|
|
14
|
-
listed?: Omit<ListedConversation, 'conversation'>;
|
|
15
|
+
listed?: Omit<ListedConversation, 'conversation' | 'newest'>;
|
|
15
16
|
messages?: readonly AcceptedMessage[];
|
|
16
17
|
outcomes?: Partial<Record<ConversationAction, ActionResult>>;
|
|
17
18
|
};
|
|
@@ -25,18 +26,24 @@ export type MemoryAdapterOptions = {
|
|
|
25
26
|
retention?: Retention;
|
|
26
27
|
member?: Member;
|
|
27
28
|
unopened?: boolean;
|
|
29
|
+
exhaustiveDiscovery?: true;
|
|
30
|
+
roomTypes?: string;
|
|
28
31
|
};
|
|
29
32
|
export type MemoryAdapter = Adapter & {
|
|
30
33
|
setRooms(rooms: readonly MemoryRoom[]): void;
|
|
31
34
|
setConversations(conversations: readonly MemoryConversation[]): void;
|
|
32
35
|
script(operation: keyof Adapter, answer: unknown): void;
|
|
33
36
|
open(): void;
|
|
34
|
-
close(
|
|
37
|
+
close(closing?: {
|
|
38
|
+
revoked?: boolean;
|
|
39
|
+
lost?: boolean;
|
|
40
|
+
}): void;
|
|
35
41
|
expire(locators: readonly string[]): void;
|
|
36
42
|
notifyRoomVersion(notification: {
|
|
37
43
|
locator: string;
|
|
38
44
|
roomVersion: string;
|
|
39
45
|
}): void;
|
|
46
|
+
notifyAuthorityChanged(scope?: DiscoveryScope): void;
|
|
40
47
|
notifyConversation(event: ConversationEvent): void;
|
|
41
48
|
notifyServiceMode(mode: ServiceMode): void;
|
|
42
49
|
heldRooms(): readonly string[];
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAItB,KAAK,cAAc,EACnB,KAAK,UAAU,EAGf,KAAK,kBAAkB,EACvB,KAAK,MAAM,EAGX,KAAK,aAAa,EAGlB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/memory.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { sameChange } from './overlay.js';
|
|
2
|
+
const ATTACHMENTS = 'attachments';
|
|
3
|
+
function lastName(path) {
|
|
4
|
+
return path.slice(path.lastIndexOf('/') + 1);
|
|
5
|
+
}
|
|
2
6
|
const FIXTURE_RETENTION = {
|
|
3
7
|
history: { kind: 'duration', seconds: 1 },
|
|
4
|
-
outcome:
|
|
8
|
+
outcome: 604_800,
|
|
5
9
|
refreshHorizon: 1,
|
|
6
10
|
};
|
|
7
11
|
function declaredRetention(value) {
|
|
@@ -15,12 +19,7 @@ function declaredRetention(value) {
|
|
|
15
19
|
}
|
|
16
20
|
const MODEL_ABSENT = { kind: 'model-unavailable', reason: 'not-readable' };
|
|
17
21
|
function modelsOf(room) {
|
|
18
|
-
return {
|
|
19
|
-
collection: room.model ?? MODEL_ABSENT,
|
|
20
|
-
...(room.typedSelection === undefined
|
|
21
|
-
? {}
|
|
22
|
-
: { selection: room.selectionModel ?? MODEL_ABSENT }),
|
|
23
|
-
};
|
|
22
|
+
return { collection: room.model ?? MODEL_ABSENT };
|
|
24
23
|
}
|
|
25
24
|
function changedModels(room, from) {
|
|
26
25
|
const now = modelsOf(room);
|
|
@@ -55,7 +54,10 @@ export function createMemoryAdapter(options = {}) {
|
|
|
55
54
|
const scripted = new Map();
|
|
56
55
|
const unsealed = new Map();
|
|
57
56
|
const sealed = new Set();
|
|
57
|
+
const sentTurns = new Map();
|
|
58
58
|
const historyPageSize = options.historyPageSize;
|
|
59
|
+
const attached = new Map();
|
|
60
|
+
const linked = new WeakMap();
|
|
59
61
|
let held = [];
|
|
60
62
|
let expiring = [];
|
|
61
63
|
let replicated = [];
|
|
@@ -86,6 +88,19 @@ export function createMemoryAdapter(options = {}) {
|
|
|
86
88
|
const wanted = ordinals.get(`${locator}\u0000${target}`);
|
|
87
89
|
return held !== undefined && wanted !== undefined && held >= wanted;
|
|
88
90
|
}
|
|
91
|
+
function heldBlob(room, path) {
|
|
92
|
+
return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
|
|
93
|
+
}
|
|
94
|
+
function freePath(room, name) {
|
|
95
|
+
const dot = name.lastIndexOf('.');
|
|
96
|
+
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
97
|
+
const extension = dot > 0 ? name.slice(dot) : '';
|
|
98
|
+
for (let count = 1;; count += 1) {
|
|
99
|
+
const path = `${ATTACHMENTS}/${count === 1 ? stem : `${stem}-${count}`}${extension}`;
|
|
100
|
+
if (heldBlob(room, path) === undefined && room.documents?.[path] === undefined)
|
|
101
|
+
return path;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
89
104
|
function retain(entries) {
|
|
90
105
|
for (const room of entries) {
|
|
91
106
|
note(room.locator, room);
|
|
@@ -107,30 +122,46 @@ export function createMemoryAdapter(options = {}) {
|
|
|
107
122
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
108
123
|
};
|
|
109
124
|
}
|
|
110
|
-
function page(room,
|
|
125
|
+
function page(room, after) {
|
|
111
126
|
const paths = Object.keys(room.documents ?? {}).sort();
|
|
127
|
+
const opening = after === undefined;
|
|
128
|
+
const from = opening ? 0 : paths.filter((path) => path <= after).length;
|
|
112
129
|
const size = pageSize ?? paths.length;
|
|
113
130
|
const taken = paths.slice(from, from + size);
|
|
114
131
|
const next = from + taken.length;
|
|
115
|
-
const targets =
|
|
132
|
+
const targets = opening ? Object.keys(room.binaryFiles ?? {}) : [];
|
|
116
133
|
return {
|
|
117
134
|
kind: 'bootstrap',
|
|
118
135
|
roomVersion: room.roomVersion,
|
|
119
|
-
...(
|
|
136
|
+
...(opening ? { models: modelsOf(room) } : {}),
|
|
120
137
|
documents: named(room.documents ?? {}, taken),
|
|
121
|
-
revisions: named(room.revisions ?? {}, taken),
|
|
138
|
+
revisions: named(room.revisions ?? {}, [...taken, ...targets]),
|
|
139
|
+
...(room.fileIds === undefined
|
|
140
|
+
? {}
|
|
141
|
+
: { fileIds: named(room.fileIds, [...taken, ...targets]) }),
|
|
122
142
|
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
123
|
-
|
|
124
|
-
...(
|
|
125
|
-
...(next < paths.length ? { pageToken:
|
|
143
|
+
binaryFiles: named(room.binaryFiles ?? {}, targets),
|
|
144
|
+
...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
|
|
145
|
+
...(next < paths.length ? { pageToken: taken.at(-1) } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function foldersMoved(room, from) {
|
|
149
|
+
const now = new Set(room.folders ?? []);
|
|
150
|
+
const before = new Set(from.folders ?? []);
|
|
151
|
+
const folders = [...now].filter((folder) => !before.has(folder)).sort();
|
|
152
|
+
const folderRemovals = [...before].filter((folder) => !now.has(folder)).sort();
|
|
153
|
+
return {
|
|
154
|
+
...(folders.length === 0 ? {} : { folders }),
|
|
155
|
+
...(folderRemovals.length === 0 ? {} : { folderRemovals }),
|
|
126
156
|
};
|
|
127
157
|
}
|
|
128
158
|
function advancement(room, from, at) {
|
|
129
159
|
const current = room.documents ?? {};
|
|
130
160
|
const previous = from.documents ?? {};
|
|
131
|
-
const currentTargets = new Set(room.
|
|
132
|
-
const previousTargets = new Set(from.
|
|
161
|
+
const currentTargets = new Set(Object.keys(room.binaryFiles ?? {}));
|
|
162
|
+
const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
|
|
133
163
|
const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
|
|
164
|
+
room.fileIds?.[path] !== from.fileIds?.[path] ||
|
|
134
165
|
!sameChange(room.changes?.[path], from.changes?.[path]);
|
|
135
166
|
const changed = Object.keys(current)
|
|
136
167
|
.filter((path) => current[path] !== previous[path] || headMoved(path))
|
|
@@ -145,24 +176,25 @@ export function createMemoryAdapter(options = {}) {
|
|
|
145
176
|
const targets = opening
|
|
146
177
|
? [...currentTargets].filter((target) => !previousTargets.has(target) || headMoved(target))
|
|
147
178
|
: [];
|
|
148
|
-
const attachments = room.attachments ?? [];
|
|
149
|
-
const declared = opening && JSON.stringify(attachments) !== JSON.stringify(from.attachments ?? []);
|
|
150
179
|
const models = opening ? changedModels(room, from) : undefined;
|
|
151
180
|
return {
|
|
152
181
|
kind: 'net-advancement',
|
|
153
182
|
roomVersion: room.roomVersion,
|
|
154
183
|
...(models === undefined ? {} : { models }),
|
|
155
184
|
documents: named(current, taken),
|
|
156
|
-
revisions: named(room.revisions ?? {}, taken),
|
|
185
|
+
revisions: named(room.revisions ?? {}, [...taken, ...targets]),
|
|
186
|
+
...(room.fileIds === undefined
|
|
187
|
+
? {}
|
|
188
|
+
: { fileIds: named(room.fileIds, [...taken, ...targets]) }),
|
|
157
189
|
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
158
|
-
|
|
190
|
+
binaryFiles: named(room.binaryFiles ?? {}, targets),
|
|
191
|
+
...(opening ? foldersMoved(room, from) : {}),
|
|
159
192
|
removals: opening
|
|
160
193
|
? [
|
|
161
194
|
...Object.keys(previous).filter((path) => !(path in current) && !currentTargets.has(path)),
|
|
162
195
|
...[...previousTargets].filter((target) => !currentTargets.has(target) && !(target in current)),
|
|
163
196
|
].sort()
|
|
164
197
|
: [],
|
|
165
|
-
...(declared ? { attachments } : {}),
|
|
166
198
|
...(pageToken === undefined ? {} : { pageToken }),
|
|
167
199
|
};
|
|
168
200
|
}
|
|
@@ -183,7 +215,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
183
215
|
function historiesOf(input) {
|
|
184
216
|
const asked = input?.conversations;
|
|
185
217
|
if (!Array.isArray(asked))
|
|
186
|
-
return { kind: 'rejected', code: 'invalid_request', fields: {} };
|
|
218
|
+
return { kind: 'rejected', code: 'invalid_request', fields: {}, retryable: false };
|
|
187
219
|
const histories = [];
|
|
188
220
|
for (const entry of asked) {
|
|
189
221
|
const conversation = typeof entry.conversation === 'string' ? scripted.get(entry.conversation) : undefined;
|
|
@@ -211,21 +243,32 @@ export function createMemoryAdapter(options = {}) {
|
|
|
211
243
|
const named = typeof input.conversation === 'string' ? input.conversation : '';
|
|
212
244
|
const conversation = scripted.get(named);
|
|
213
245
|
if (conversation === undefined) {
|
|
214
|
-
return {
|
|
246
|
+
return {
|
|
247
|
+
kind: 'rejected',
|
|
248
|
+
code: 'unknown-conversation',
|
|
249
|
+
fields: { conversation: named },
|
|
250
|
+
retryable: false,
|
|
251
|
+
};
|
|
215
252
|
}
|
|
216
253
|
const outcome = conversation.outcomes?.[name];
|
|
217
254
|
if (outcome !== undefined)
|
|
218
255
|
return outcome;
|
|
219
256
|
if (name === 'conversation.send') {
|
|
257
|
+
const operation = typeof input.operation_id === 'string' ? input.operation_id : null;
|
|
258
|
+
const answered = operation === null ? undefined : sentTurns.get(operation);
|
|
259
|
+
if (answered !== undefined)
|
|
260
|
+
return { kind: 'action', result: { turn: answered } };
|
|
220
261
|
issued += 1;
|
|
221
262
|
const turn = `turn-${issued}`;
|
|
222
263
|
unsealed.set(turn, named);
|
|
264
|
+
if (operation !== null)
|
|
265
|
+
sentTurns.set(operation, turn);
|
|
223
266
|
return { kind: 'action', result: { turn } };
|
|
224
267
|
}
|
|
225
268
|
if (name === 'conversation.cancel') {
|
|
226
269
|
const turn = typeof input.turn === 'string' ? input.turn : '';
|
|
227
270
|
if (sealed.has(turn) || !unsealed.has(turn)) {
|
|
228
|
-
return { kind: 'rejected', code: 'turn-sealed', fields: { turn } };
|
|
271
|
+
return { kind: 'rejected', code: 'turn-sealed', fields: { turn }, retryable: false };
|
|
229
272
|
}
|
|
230
273
|
unsealed.delete(turn);
|
|
231
274
|
return { kind: 'action', result: { turn, cancelled: true } };
|
|
@@ -235,7 +278,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
235
278
|
return { kind: 'action', result: { conversation: named } };
|
|
236
279
|
}
|
|
237
280
|
function announceList() {
|
|
238
|
-
const entries = [...scripted.values()].flatMap(({ conversation, listed }) => listed === undefined
|
|
281
|
+
const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
|
|
282
|
+
? []
|
|
283
|
+
: [{ conversation, ...listed, newest: messages.at(-1)?.position ?? null }]);
|
|
239
284
|
for (const listener of listeners)
|
|
240
285
|
listener({ kind: 'list', entries });
|
|
241
286
|
}
|
|
@@ -250,6 +295,8 @@ export function createMemoryAdapter(options = {}) {
|
|
|
250
295
|
};
|
|
251
296
|
}
|
|
252
297
|
return {
|
|
298
|
+
...(options.exhaustiveDiscovery === undefined ? {} : { exhaustiveDiscovery: true }),
|
|
299
|
+
...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
|
|
253
300
|
setRooms(next) {
|
|
254
301
|
rooms = [...next];
|
|
255
302
|
retain(rooms);
|
|
@@ -262,9 +309,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
262
309
|
for (const observer of observers)
|
|
263
310
|
observer({ kind: 'opened' });
|
|
264
311
|
},
|
|
265
|
-
close(revoked = false) {
|
|
312
|
+
close({ revoked = false, lost = !revoked } = {}) {
|
|
266
313
|
for (const observer of observers)
|
|
267
|
-
observer({ kind: 'closed', revoked });
|
|
314
|
+
observer({ kind: 'closed', revoked, lost });
|
|
268
315
|
},
|
|
269
316
|
expire(locators) {
|
|
270
317
|
expiring = [...locators];
|
|
@@ -273,6 +320,13 @@ export function createMemoryAdapter(options = {}) {
|
|
|
273
320
|
for (const observer of observers)
|
|
274
321
|
observer({ kind: 'room-version', locator, roomVersion });
|
|
275
322
|
},
|
|
323
|
+
notifyAuthorityChanged(scope) {
|
|
324
|
+
for (const observer of observers) {
|
|
325
|
+
observer(scope === undefined
|
|
326
|
+
? { kind: 'authority-changed' }
|
|
327
|
+
: { kind: 'authority-changed', scope });
|
|
328
|
+
}
|
|
329
|
+
},
|
|
276
330
|
notifyConversation(event) {
|
|
277
331
|
if (event.kind === 'accepted-message') {
|
|
278
332
|
sealed.add(event.message.turn);
|
|
@@ -333,17 +387,19 @@ export function createMemoryAdapter(options = {}) {
|
|
|
333
387
|
},
|
|
334
388
|
reopen() {
|
|
335
389
|
queueMicrotask(() => {
|
|
336
|
-
for (const observer of observers)
|
|
337
|
-
observer({ kind: 'closed', revoked: false });
|
|
390
|
+
for (const observer of observers) {
|
|
391
|
+
observer({ kind: 'closed', revoked: false, lost: false });
|
|
392
|
+
}
|
|
338
393
|
});
|
|
339
394
|
},
|
|
395
|
+
published() { },
|
|
340
396
|
observe(notify) {
|
|
341
397
|
observers.add(notify);
|
|
342
398
|
queueMicrotask(() => {
|
|
343
399
|
if (!observers.has(notify))
|
|
344
400
|
return;
|
|
345
401
|
if (options.unopened === true) {
|
|
346
|
-
notify({ kind: 'closed', revoked: false });
|
|
402
|
+
notify({ kind: 'closed', revoked: false, lost: true });
|
|
347
403
|
return;
|
|
348
404
|
}
|
|
349
405
|
announceList();
|
|
@@ -386,7 +442,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
386
442
|
if (room === undefined) {
|
|
387
443
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
388
444
|
}
|
|
389
|
-
return page(room, request.pageToken
|
|
445
|
+
return page(room, request.pageToken);
|
|
390
446
|
}, request).then((answer) => note(request.locator, answer));
|
|
391
447
|
},
|
|
392
448
|
async refresh(_authorization, request) {
|
|
@@ -419,8 +475,20 @@ export function createMemoryAdapter(options = {}) {
|
|
|
419
475
|
if (room === undefined) {
|
|
420
476
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
421
477
|
}
|
|
422
|
-
return {
|
|
423
|
-
|
|
478
|
+
return {
|
|
479
|
+
kind: 'rejected',
|
|
480
|
+
code: 'unscripted-mutation',
|
|
481
|
+
fields: {},
|
|
482
|
+
retryable: false,
|
|
483
|
+
affected: {},
|
|
484
|
+
};
|
|
485
|
+
}, request).then((answer) => {
|
|
486
|
+
const destination = request.changeBatch.between?.destination.room;
|
|
487
|
+
if (answer.kind === 'accepted' && answer.destination !== undefined && destination) {
|
|
488
|
+
note(destination, answer.destination);
|
|
489
|
+
}
|
|
490
|
+
return note(request.locator, answer);
|
|
491
|
+
});
|
|
424
492
|
},
|
|
425
493
|
async history(_authorization, request) {
|
|
426
494
|
return resolveScript(scripts.history, () => {
|
|
@@ -434,11 +502,46 @@ export function createMemoryAdapter(options = {}) {
|
|
|
434
502
|
};
|
|
435
503
|
}, request);
|
|
436
504
|
},
|
|
505
|
+
async binary(_authorization, request) {
|
|
506
|
+
return resolveScript(scripts.binary, () => {
|
|
507
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
508
|
+
if (room === undefined)
|
|
509
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
510
|
+
const blob = heldBlob(room, request.path);
|
|
511
|
+
return blob === undefined
|
|
512
|
+
? { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false }
|
|
513
|
+
: { kind: 'binary', body: blob.stream(), mediaType: blob.type };
|
|
514
|
+
}, request);
|
|
515
|
+
},
|
|
516
|
+
async link(_authorization, request) {
|
|
517
|
+
return resolveScript(scripts.link, () => {
|
|
518
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
519
|
+
if (room === undefined)
|
|
520
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
521
|
+
const blob = heldBlob(room, request.path);
|
|
522
|
+
if (blob === undefined) {
|
|
523
|
+
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
524
|
+
}
|
|
525
|
+
const url = linked.get(blob) ?? URL.createObjectURL(blob);
|
|
526
|
+
linked.set(blob, url);
|
|
527
|
+
return { kind: 'link', url, name: lastName(request.path), mediaType: blob.type };
|
|
528
|
+
}, request);
|
|
529
|
+
},
|
|
530
|
+
async attach(_authorization, request) {
|
|
531
|
+
return resolveScript(scripts.attach, () => {
|
|
532
|
+
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
533
|
+
if (room === undefined)
|
|
534
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
535
|
+
const path = freePath(room, request.name);
|
|
536
|
+
attached.set(`${room.locator}\u0000${path}`, request.blob);
|
|
537
|
+
return { kind: 'attached', path, revision: `attached-${attached.size}` };
|
|
538
|
+
}, request);
|
|
539
|
+
},
|
|
437
540
|
async action(_authorization, request) {
|
|
438
541
|
return resolveScript(scripts.action, () => {
|
|
439
542
|
if (request.name.startsWith('conversation.'))
|
|
440
543
|
return conversationAction(request);
|
|
441
|
-
return { kind: 'rejected', code: 'unscripted-action', fields: {} };
|
|
544
|
+
return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
|
|
442
545
|
}, request).then((answer) => {
|
|
443
546
|
if (answer.kind === 'action' && answer.at !== undefined)
|
|
444
547
|
note(answer.at.locator, answer.at);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AcceptedMessage } from './adapter.js';
|
|
2
|
+
import type { Connection } from './tables.js';
|
|
3
|
+
export declare const MESSAGE_TABLES: readonly string[];
|
|
4
|
+
export type HeldConversation = {
|
|
5
|
+
readonly conversation: string;
|
|
6
|
+
readonly read: string | null | undefined;
|
|
7
|
+
readonly partial: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type MessageWindow = {
|
|
10
|
+
readonly messages: AcceptedMessage[];
|
|
11
|
+
readonly more: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type ConversationWrite = {
|
|
14
|
+
readonly conversation: string;
|
|
15
|
+
readonly messages: readonly AcceptedMessage[];
|
|
16
|
+
readonly read?: {
|
|
17
|
+
readonly at: string | null;
|
|
18
|
+
readonly partial: boolean;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function heldConversations(connection: Connection): HeldConversation[];
|
|
22
|
+
export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
|
|
23
|
+
export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null): MessageWindow;
|
|
24
|
+
export declare function messageCount(connection: Connection, conversation: string): number;
|
|
25
|
+
export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
|
|
26
|
+
export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
|
|
27
|
+
export declare function forgottenMessages(connection: Connection): void;
|
|
28
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAM3C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3E,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAmB5E;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,GAClD,IAAI,CAoCN;AAYD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GACvC,aAAa,CAUf;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMjF;AAED,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAW9F;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAG9D"}
|