@agentshouse/mdruntime-adapter 0.1.0-cfd03209dcd82 → 0.1.0-cfded86738bb2
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/AGENTS.md +294 -276
- package/dist/actions.d.ts +16 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +92 -141
- package/dist/adapter.d.ts +1 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +307 -138
- package/dist/discovery.d.ts +5 -3
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +29 -10
- package/dist/gather.d.ts +1 -1
- package/dist/gather.d.ts.map +1 -1
- package/dist/gather.js +4 -14
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/model.d.ts +0 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -3
- package/dist/part.d.ts +15 -0
- package/dist/part.d.ts.map +1 -0
- package/dist/part.js +82 -0
- package/dist/read.d.ts +65 -18
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +302 -122
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +2 -1
- package/dist/room-types.d.ts +6 -0
- package/dist/room-types.d.ts.map +1 -0
- package/dist/room-types.js +66 -0
- package/dist/site.d.ts +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +149 -82
- package/dist/stream.d.ts +5 -4
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +349 -43
- package/dist/transport.d.ts +58 -13
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +1 -1
- package/dist/upload.d.ts +12 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +52 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/write.d.ts +12 -1
- package/dist/write.d.ts.map +1 -1
- package/dist/write.js +98 -57
- package/package.json +2 -2
- package/dist/handed.d.ts +0 -15
- package/dist/handed.d.ts.map +0 -1
- package/dist/handed.js +0 -38
- package/dist/referrer.d.ts +0 -7
- package/dist/referrer.d.ts.map +0 -1
- package/dist/referrer.js +0 -35
package/dist/site.js
CHANGED
|
@@ -1,78 +1,108 @@
|
|
|
1
|
+
import { stepped } from '@agentshouse/mdruntime';
|
|
1
2
|
import { actionOutcome, SITE_SUBMIT } from './actions.js';
|
|
2
3
|
import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { partModels, streamedModels, viewModels } from './model.js';
|
|
5
|
+
import { bootstrapping, emptyScope, housePart, manifested, parseEnumeration, parseSiteParted, partInventory, refreshFrom, viewOf, wholeView, } from './read.js';
|
|
6
|
+
import { PART_ATTEMPTS, partArrival, partFrame, unverifiedPart } from './part.js';
|
|
5
7
|
import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
|
|
8
|
+
import { HOUSE_ROOM_TYPES } from './room-types.js';
|
|
6
9
|
import { houseNotifications } from './stream.js';
|
|
7
|
-
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT,
|
|
8
|
-
import { houseReferrer } from './referrer.js';
|
|
10
|
+
import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILES, } from './transport.js';
|
|
9
11
|
import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
|
|
10
12
|
const UNCERTAIN = { kind: 'transport-uncertainty' };
|
|
13
|
+
function unfound() {
|
|
14
|
+
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
15
|
+
}
|
|
11
16
|
function siteRoom(tracked) {
|
|
12
17
|
return {
|
|
13
18
|
name: tracked.handle,
|
|
14
19
|
locator: tracked.locator,
|
|
15
20
|
handle: tracked.handle,
|
|
16
21
|
roomVersion: roomVersion(tracked),
|
|
17
|
-
operations: {
|
|
18
|
-
replica: { selection: tracked.locator, admission: 'admitted' },
|
|
22
|
+
operations: { write: [], delete: [] },
|
|
23
|
+
replica: { selection: tracked.locator, admission: 'admitted', offline: 'open' },
|
|
19
24
|
providerOwnedPaths: [],
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
|
-
function
|
|
23
|
-
return refused.kind === 'beyond-horizon' ? UNCERTAIN : refused;
|
|
24
|
-
}
|
|
25
|
-
export function createSiteAdapter(transport) {
|
|
27
|
+
export function createSiteAdapter(transport, snapshot = false) {
|
|
26
28
|
const notifications = houseNotifications(transport, 'site');
|
|
27
29
|
const tracked = new Map();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const expired = new Map();
|
|
31
|
+
function fileRoute(request) {
|
|
32
|
+
const entry = tracked.get(request.locator);
|
|
33
|
+
if (entry === undefined)
|
|
34
|
+
return { kind: 'room-not-readable', locator: request.locator };
|
|
35
|
+
return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
|
|
31
36
|
}
|
|
32
|
-
async function
|
|
37
|
+
async function enumerated(entry, from, page) {
|
|
33
38
|
const answer = await transport.door(SITE_DOOR_ENUMERATE, {
|
|
34
|
-
positions: [
|
|
39
|
+
positions: [
|
|
40
|
+
page === undefined
|
|
41
|
+
? presented(entry.authority, from)
|
|
42
|
+
: {
|
|
43
|
+
...presented(entry.authority, { position: page.after, logEpoch: from.logEpoch }),
|
|
44
|
+
page: { through: page.through, read: page.read },
|
|
45
|
+
},
|
|
46
|
+
],
|
|
35
47
|
});
|
|
36
48
|
const classified = classifyRead(answer.status, answer.body, entry.locator);
|
|
37
49
|
if (classified !== null)
|
|
38
50
|
return classified;
|
|
39
|
-
|
|
51
|
+
const found = parseEnumeration(answer.body, 'site');
|
|
52
|
+
if (found === null)
|
|
53
|
+
return UNCERTAIN;
|
|
54
|
+
return viewOf(found, entry) ?? { kind: 'room-not-readable', locator: entry.locator };
|
|
55
|
+
}
|
|
56
|
+
async function enumeration(entry, from) {
|
|
57
|
+
const first = await enumerated(entry, from);
|
|
58
|
+
return 'kind' in first ? first : wholeView(first, (page) => enumerated(entry, from, page));
|
|
40
59
|
}
|
|
41
|
-
async function
|
|
42
|
-
const
|
|
60
|
+
async function partedRoom(entry) {
|
|
61
|
+
const cut = expired.get(entry.locator);
|
|
62
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`);
|
|
43
63
|
const classified = classifyDoor(answer.status, answer.body, entry.locator);
|
|
44
64
|
if (classified !== null)
|
|
45
|
-
return
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
return classified;
|
|
66
|
+
const room = parseSiteParted(answer.body);
|
|
67
|
+
return room === null || room.anchor !== entry.authority ? UNCERTAIN : room;
|
|
68
|
+
}
|
|
69
|
+
async function fetchedPart(entry, room, listed, received, arriving) {
|
|
70
|
+
if (received !== undefined) {
|
|
71
|
+
const kept = new Uint8Array(received);
|
|
72
|
+
const held = await housePart(room, kept, listed, 'site');
|
|
73
|
+
if (held !== null)
|
|
74
|
+
return 'kind' in held ? held : { scope: held, frame: kept };
|
|
75
|
+
}
|
|
76
|
+
for (let attempt = 0; attempt < PART_ATTEMPTS; attempt += 1) {
|
|
77
|
+
const answer = await transport.read(`${SITE_DOOR_BOOTSTRAP}${entry.authority}?part=${encodeURIComponent(listed.part)}`, partArrival(listed, arriving));
|
|
78
|
+
const failure = classifyRead(answer.status, answer.body, entry.locator);
|
|
79
|
+
if (failure?.kind === 'beyond-horizon')
|
|
80
|
+
expired.set(entry.locator, room.position);
|
|
81
|
+
if (failure !== null)
|
|
82
|
+
return failure;
|
|
83
|
+
const frame = partFrame(answer.body);
|
|
84
|
+
if (frame === null)
|
|
85
|
+
continue;
|
|
86
|
+
const scope = await housePart(room, frame, listed, 'site');
|
|
87
|
+
if (scope !== null)
|
|
88
|
+
return 'kind' in scope ? scope : { scope, frame };
|
|
89
|
+
}
|
|
90
|
+
return unverifiedPart(entry.locator);
|
|
58
91
|
}
|
|
59
92
|
async function refreshed(entry, fromRoomVersion) {
|
|
60
93
|
const from = logPosition(fromRoomVersion);
|
|
61
94
|
if (from === null)
|
|
62
95
|
return { kind: 'beyond-horizon' };
|
|
63
|
-
const streamed = notifications.advance(entry, from);
|
|
96
|
+
const streamed = await stepped(notifications.advance(entry, from));
|
|
64
97
|
if (streamed !== null) {
|
|
65
98
|
const models = await streamedModels(streamed.schemas, entry, 'site');
|
|
66
99
|
return models === undefined ? streamed.page : { ...streamed.page, models };
|
|
67
100
|
}
|
|
68
|
-
const
|
|
69
|
-
if ('kind' in
|
|
70
|
-
return
|
|
71
|
-
const view = viewOf(found, entry);
|
|
72
|
-
if (view === undefined)
|
|
73
|
-
return { kind: 'room-not-readable', locator: entry.locator };
|
|
101
|
+
const view = await enumeration(entry, from);
|
|
102
|
+
if ('kind' in view)
|
|
103
|
+
return view;
|
|
74
104
|
notifications.reach(entry.authority, view);
|
|
75
|
-
const answer = refreshFrom(view, fromRoomVersion);
|
|
105
|
+
const answer = await refreshFrom(view, fromRoomVersion);
|
|
76
106
|
if (answer.kind !== 'net-advancement')
|
|
77
107
|
return answer;
|
|
78
108
|
const models = await viewModels(view, entry);
|
|
@@ -80,6 +110,8 @@ export function createSiteAdapter(transport) {
|
|
|
80
110
|
}
|
|
81
111
|
return {
|
|
82
112
|
localSaves: true,
|
|
113
|
+
exhaustiveDiscovery: true,
|
|
114
|
+
roomTypes: HOUSE_ROOM_TYPES,
|
|
83
115
|
async authorize() {
|
|
84
116
|
return {};
|
|
85
117
|
},
|
|
@@ -102,14 +134,42 @@ export function createSiteAdapter(transport) {
|
|
|
102
134
|
const entry = tracked.get(request.locator);
|
|
103
135
|
if (entry === undefined)
|
|
104
136
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
137
|
+
let continued;
|
|
138
|
+
let inventory;
|
|
139
|
+
if (request.pageToken === undefined) {
|
|
140
|
+
const room = await partedRoom(entry);
|
|
141
|
+
if ('kind' in room)
|
|
142
|
+
return room;
|
|
143
|
+
continued = { room, next: 0, seen: [] };
|
|
144
|
+
inventory = partInventory(room);
|
|
145
|
+
if (inventory.parts > 0)
|
|
146
|
+
return manifested(room, inventory, JSON.stringify(continued));
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
continued = JSON.parse(request.pageToken);
|
|
150
|
+
const listed = continued.room.parts[continued.next];
|
|
151
|
+
const sent = listed === undefined
|
|
152
|
+
? { scope: emptyScope(continued.room), frame: null }
|
|
153
|
+
: await fetchedPart(entry, continued.room, listed, request.received, request.arriving);
|
|
154
|
+
if ('kind' in sent)
|
|
155
|
+
return sent;
|
|
156
|
+
const { scope } = sent;
|
|
157
|
+
notifications.reach(entry.authority, scope);
|
|
158
|
+
const next = continued.next + 1;
|
|
159
|
+
const more = next < continued.room.parts.length;
|
|
160
|
+
const seen = [
|
|
161
|
+
...continued.seen,
|
|
162
|
+
...entry.schemas.filter((schema) => scope.files.some((file) => file.path === schema)),
|
|
163
|
+
];
|
|
164
|
+
const models = await partModels(scope, entry, new Set(seen), !more);
|
|
165
|
+
const { folders: _folders, ...page } = await stepped(bootstrapping(scope));
|
|
166
|
+
return {
|
|
167
|
+
...page,
|
|
168
|
+
...(models === undefined ? {} : { models }),
|
|
169
|
+
...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
|
|
170
|
+
...(inventory === undefined ? {} : { inventory }),
|
|
171
|
+
...(sent.frame === null ? {} : { received: sent.frame }),
|
|
172
|
+
};
|
|
113
173
|
},
|
|
114
174
|
async refresh(_authorization, request) {
|
|
115
175
|
const entry = tracked.get(request.locator);
|
|
@@ -117,6 +177,11 @@ export function createSiteAdapter(transport) {
|
|
|
117
177
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
118
178
|
if (request.pageToken !== undefined)
|
|
119
179
|
return UNCERTAIN;
|
|
180
|
+
if (snapshot) {
|
|
181
|
+
return request.fromRoomVersion === roomVersion(entry)
|
|
182
|
+
? { kind: 'still-current' }
|
|
183
|
+
: { kind: 'beyond-horizon' };
|
|
184
|
+
}
|
|
120
185
|
return refreshed(entry, request.fromRoomVersion);
|
|
121
186
|
},
|
|
122
187
|
async mutate() {
|
|
@@ -126,30 +191,25 @@ export function createSiteAdapter(transport) {
|
|
|
126
191
|
return { kind: 'no-history' };
|
|
127
192
|
},
|
|
128
193
|
async binary(_authorization, request) {
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
return
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const read = await transport.download(`${SITE_FILES}${room_ref}/${encodeURIComponent(request.fileRef)}/${path === undefined
|
|
138
|
-
? `${SITE_FILE_RECORD}/${encodeURIComponent(record)}`
|
|
139
|
-
: encodeURIComponent(path)}`);
|
|
140
|
-
if (read.status === 404) {
|
|
141
|
-
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
142
|
-
}
|
|
143
|
-
return read.status === 200 && read.blob !== null
|
|
144
|
-
? { kind: 'binary', blob: read.blob }
|
|
194
|
+
const route = fileRoute(request);
|
|
195
|
+
if (typeof route !== 'string')
|
|
196
|
+
return route;
|
|
197
|
+
const read = await transport.download(route);
|
|
198
|
+
if (read.status === 404)
|
|
199
|
+
return unfound();
|
|
200
|
+
return read.status === 200 && read.body !== null
|
|
201
|
+
? { kind: 'binary', body: read.body, mediaType: read.mediaType }
|
|
145
202
|
: UNCERTAIN;
|
|
146
203
|
},
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
if (
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
204
|
+
async link(_authorization, request) {
|
|
205
|
+
const route = fileRoute(request);
|
|
206
|
+
if (typeof route !== 'string')
|
|
207
|
+
return route;
|
|
208
|
+
return {
|
|
209
|
+
kind: 'link',
|
|
210
|
+
url: route,
|
|
211
|
+
name: request.path.slice(request.path.lastIndexOf('/') + 1),
|
|
212
|
+
};
|
|
153
213
|
},
|
|
154
214
|
reached(locator, version, target) {
|
|
155
215
|
return reachedVersion(version, target, tracked.get(locator)?.logEpoch);
|
|
@@ -170,20 +230,27 @@ export function createSiteAdapter(transport) {
|
|
|
170
230
|
return UNCERTAIN;
|
|
171
231
|
return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMIT);
|
|
172
232
|
},
|
|
173
|
-
roomStream:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
233
|
+
roomStream: snapshot
|
|
234
|
+
? undefined
|
|
235
|
+
: {
|
|
236
|
+
hold(rooms) {
|
|
237
|
+
notifications.send(rooms.flatMap((room) => {
|
|
238
|
+
const entry = tracked.get(room.locator);
|
|
239
|
+
const at = logPosition(room.roomVersion);
|
|
240
|
+
if (entry === undefined || at === null)
|
|
241
|
+
return [];
|
|
242
|
+
notifications.reach(entry.authority, at);
|
|
243
|
+
return [presented(entry.authority, at)];
|
|
244
|
+
}));
|
|
245
|
+
},
|
|
246
|
+
reopen: notifications.reopen,
|
|
247
|
+
observe: notifications.observe,
|
|
248
|
+
published(locator, roomVersion) {
|
|
249
|
+
const at = logPosition(roomVersion);
|
|
250
|
+
if (at !== null)
|
|
251
|
+
notifications.published(locator, at);
|
|
252
|
+
},
|
|
183
253
|
},
|
|
184
|
-
reopen: notifications.reopen,
|
|
185
|
-
observe: notifications.observe,
|
|
186
|
-
},
|
|
187
254
|
serviceMode: notifications.serviceMode,
|
|
188
255
|
};
|
|
189
256
|
}
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ConversationStream, type RefreshPage, type RoomStreamEvent, type ServiceModeSignal, type StreamReceipts } from '@agentshouse/mdruntime';
|
|
2
2
|
import type { TrackedAuthority } from './discovery.js';
|
|
3
3
|
import type { HouseDoor, HouseHeldRoom, HouseMode, HouseStreamEntry } from './transport.js';
|
|
4
4
|
import { type LogPosition } from './version.js';
|
|
5
5
|
export type HeldRevision = (path: string, revision: string) => boolean;
|
|
6
6
|
export type StreamedAdvancement = {
|
|
7
7
|
page: RefreshPage;
|
|
8
|
-
entries: readonly HouseStreamEntry[];
|
|
9
8
|
schemas: ReadonlyMap<string, HouseStreamEntry>;
|
|
10
9
|
};
|
|
11
10
|
export type HouseNotifications = {
|
|
12
11
|
runtime: string;
|
|
13
|
-
observe(notify: (event: RoomStreamEvent) => void): () => void;
|
|
12
|
+
observe(notify: (event: RoomStreamEvent) => void, receipts: StreamReceipts): () => void;
|
|
14
13
|
send(rooms: readonly HouseHeldRoom[]): void;
|
|
14
|
+
published(locator: string, at: LogPosition): void;
|
|
15
15
|
reopen(): void;
|
|
16
16
|
track(authorities: readonly TrackedAuthority[]): void;
|
|
17
17
|
reach(authority: string, at: LogPosition): void;
|
|
18
|
-
|
|
18
|
+
edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
|
|
19
|
+
advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
|
|
19
20
|
conversations: ConversationStream;
|
|
20
21
|
serviceMode: ServiceModeSignal;
|
|
21
22
|
};
|
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAUvD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EAEb,SAAS,EAET,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AA0C7D,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IACxF,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAClD,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAAC;IACxE,OAAO,CACL,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,EACjB,KAAK,CAAC,EAAE,YAAY,GACnB,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAmFF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,kBAAkB,CA8jB5F"}
|