@agentshouse/mdruntime-adapter 0.1.0-cc1bdabaf4e28 → 0.1.0-cc34762b70bb0

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 (55) hide show
  1. package/dist/actions.d.ts +4 -59
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +7 -289
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +134 -327
  6. package/dist/discovery.d.ts +19 -6
  7. package/dist/discovery.d.ts.map +1 -1
  8. package/dist/discovery.js +63 -30
  9. package/dist/history.d.ts +12 -0
  10. package/dist/history.d.ts.map +1 -0
  11. package/dist/history.js +92 -0
  12. package/dist/house-model.d.ts +718 -1
  13. package/dist/house-model.d.ts.map +1 -1
  14. package/dist/house-model.js +393 -442
  15. package/dist/index.d.ts +8 -4
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +7 -3
  18. package/dist/model.d.ts +2 -3
  19. package/dist/model.d.ts.map +1 -1
  20. package/dist/model.js +0 -17
  21. package/dist/part.d.ts +11 -12
  22. package/dist/part.d.ts.map +1 -1
  23. package/dist/part.js +63 -55
  24. package/dist/read.d.ts +10 -58
  25. package/dist/read.d.ts.map +1 -1
  26. package/dist/read.js +37 -220
  27. package/dist/refusal.d.ts +0 -3
  28. package/dist/refusal.d.ts.map +1 -1
  29. package/dist/refusal.js +0 -5
  30. package/dist/room-stream.d.ts +19 -0
  31. package/dist/room-stream.d.ts.map +1 -0
  32. package/dist/room-stream.js +57 -0
  33. package/dist/room-types.d.ts +3 -3
  34. package/dist/room-types.d.ts.map +1 -1
  35. package/dist/room-types.js +8 -7
  36. package/dist/search.d.ts +5 -0
  37. package/dist/search.d.ts.map +1 -0
  38. package/dist/search.js +47 -0
  39. package/dist/site.d.ts.map +1 -1
  40. package/dist/site.js +75 -158
  41. package/dist/stream.d.ts +13 -14
  42. package/dist/stream.d.ts.map +1 -1
  43. package/dist/stream.js +163 -425
  44. package/dist/transport.d.ts +48 -35
  45. package/dist/transport.d.ts.map +1 -1
  46. package/dist/transport.js +54 -11
  47. package/dist/upload.d.ts.map +1 -1
  48. package/dist/upload.js +2 -2
  49. package/dist/write.d.ts +6 -1
  50. package/dist/write.d.ts.map +1 -1
  51. package/dist/write.js +17 -24
  52. package/package.json +2 -2
  53. package/dist/gather.d.ts +0 -4
  54. package/dist/gather.d.ts.map +0 -1
  55. package/dist/gather.js +0 -35
package/dist/site.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { stepped } from '@agentshouse/mdruntime';
2
- import { actionOutcome, SITE_SUBMIT } from './actions.js';
2
+ import { actionOutcome } from './actions.js';
3
3
  import { mapDiscovery, parseSiteDiscovery, siteCapabilities, siteTracked, } from './discovery.js';
4
- import { manifestedModels, 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';
7
- import { classifyDoor, classifyRead, discoveryFailure } from './refusal.js';
4
+ import { bootstrapping } from './read.js';
5
+ import { roomStreams } from './room-stream.js';
6
+ import { classifyDoor, discoveryFailure } from './refusal.js';
7
+ import { HOUSE_TYPED_PATHS } from './house-model.js';
8
8
  import { HOUSE_NAMEABLE_ROOM_TYPES, HOUSE_ROOM_TYPES } from './room-types.js';
9
9
  import { houseNotifications } from './stream.js';
10
- import { SITE_DOOR_BOOTSTRAP, SITE_DOOR_DISCOVER, SITE_DOOR_ENUMERATE, SITE_DOOR_SUBMIT, SITE_FILES, } from './transport.js';
11
- import { followsVersion, logPosition, presented, reachedVersion, roomVersion, } from './version.js';
10
+ import { houseSiteRoute, SITE_DOOR_SUBMIT, SITE_FILES, SITE_SUBMISSION, } from './transport.js';
11
+ import { followsVersion, logPosition, presented, reachedVersion, roomVersion } from './version.js';
12
12
  const UNCERTAIN = { kind: 'transport-uncertainty' };
13
13
  function unfound() {
14
14
  return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
@@ -25,171 +25,97 @@ function siteRoom(tracked) {
25
25
  };
26
26
  }
27
27
  export function createSiteAdapter(transport, snapshot = false) {
28
- const notifications = houseNotifications(transport, 'site');
28
+ const notifications = houseNotifications(transport, 'site', {
29
+ opened: async () => {
30
+ const found = await discovered();
31
+ return found.kind === 'discovery' ? found : null;
32
+ },
33
+ changed: () => null,
34
+ });
29
35
  const tracked = new Map();
30
- const expired = new Map();
36
+ const read = new Map();
37
+ const rooms = roomStreams('site');
31
38
  function fileRoute(request) {
32
39
  const entry = tracked.get(request.locator);
33
40
  if (entry === undefined)
34
41
  return { kind: 'room-not-readable', locator: request.locator };
35
42
  return `${SITE_FILES}${entry.authority}/${encodeURIComponent(request.revision)}/${encodeURIComponent(request.path)}`;
36
43
  }
37
- async function enumerated(entry, from, page) {
38
- const answer = await transport.door(SITE_DOOR_ENUMERATE, {
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
- ],
47
- });
48
- const classified = classifyRead(answer.status, answer.body, entry.locator);
49
- if (classified !== null)
50
- return classified;
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));
44
+ async function openedRoom(entry, arriving, signal) {
45
+ const cut = read.get(entry.locator);
46
+ const answered = await transport.streamed(`${houseSiteRoute('bootstrap')}/${entry.authority}${cut === undefined ? '' : `?expired=${cut}`}`, signal ?? new AbortController().signal);
47
+ if (answered.room === null)
48
+ return classifyDoor(answered.status, answered.body, entry.locator) ?? UNCERTAIN;
49
+ const head = await rooms.head(entry, answered.room, arriving, signal);
50
+ const at = head.kind === 'bootstrap' ? logPosition(head.roomVersion) : null;
51
+ if (at !== null)
52
+ read.set(entry.locator, at.position);
53
+ return head;
59
54
  }
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}`}`);
63
- const classified = classifyDoor(answer.status, answer.body, entry.locator);
64
- if (classified !== null)
65
- return classified;
66
- const room = parseSiteParted(answer.body);
67
- return room === null || room.anchor !== entry.authority ? UNCERTAIN : room;
55
+ async function streamedPage(entry, token) {
56
+ const part = await rooms.part(entry, token);
57
+ if ('kind' in part)
58
+ return part;
59
+ const { folders: _folders, ...page } = await stepped(bootstrapping(part.scope));
60
+ return {
61
+ ...page,
62
+ ...(part.models === undefined ? {} : { models: part.models }),
63
+ ...(part.pageToken === undefined ? {} : { pageToken: part.pageToken }),
64
+ bytes: part.bytes,
65
+ };
68
66
  }
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);
91
- }
92
- async function refreshed(entry, fromRoomVersion) {
93
- const from = logPosition(fromRoomVersion);
94
- if (from === null)
95
- return { kind: 'beyond-horizon' };
96
- const streamed = await stepped(notifications.advance(entry, from));
97
- if (streamed !== null) {
98
- const models = await streamedModels(streamed.schemas, entry, 'site');
99
- return models === undefined ? streamed.page : { ...streamed.page, models };
100
- }
101
- const view = await enumeration(entry, from);
102
- if ('kind' in view)
103
- return view;
104
- notifications.reach(entry.authority, view);
105
- const answer = await refreshFrom(view, fromRoomVersion);
106
- if (answer.kind !== 'net-advancement')
107
- return answer;
108
- const models = await viewModels(view, entry);
109
- return models === undefined ? answer : { ...answer, models };
67
+ async function discovered() {
68
+ const answer = await transport.read(houseSiteRoute('discover'));
69
+ const failed = discoveryFailure(answer.status, answer.body);
70
+ if (failed !== null)
71
+ return failed;
72
+ const document = parseSiteDiscovery(answer.body);
73
+ if (document === null)
74
+ return UNCERTAIN;
75
+ const entries = siteTracked(document);
76
+ tracked.clear();
77
+ for (const entry of entries)
78
+ tracked.set(entry.locator, entry);
79
+ notifications.track(entries);
80
+ return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
110
81
  }
111
82
  return {
112
83
  localSaves: true,
113
- exhaustiveDiscovery: true,
114
84
  roomTypes: HOUSE_ROOM_TYPES,
115
85
  nameableRoomTypes: HOUSE_NAMEABLE_ROOM_TYPES,
86
+ typedPaths: HOUSE_TYPED_PATHS,
116
87
  async authorize() {
117
88
  return {};
118
89
  },
119
- async discover() {
120
- const answer = await transport.read(SITE_DOOR_DISCOVER);
121
- const failed = discoveryFailure(answer.status, answer.body);
122
- if (failed !== null)
123
- return failed;
124
- const document = parseSiteDiscovery(answer.body);
125
- if (document === null)
126
- return UNCERTAIN;
127
- const entries = siteTracked(document);
128
- tracked.clear();
129
- for (const entry of entries)
130
- tracked.set(entry.locator, entry);
131
- notifications.track(entries);
132
- return mapDiscovery(document, entries.map(siteRoom), siteCapabilities());
133
- },
134
90
  async bootstrap(_authorization, request) {
135
91
  const entry = tracked.get(request.locator);
136
92
  if (entry === undefined)
137
93
  return { kind: 'room-not-readable', locator: request.locator };
138
- let continued;
139
- let inventory;
140
- if (request.pageToken === undefined) {
141
- const room = await partedRoom(entry);
142
- if ('kind' in room)
143
- return room;
144
- const { models, seen } = await manifestedModels(room, entry);
145
- continued = { room, next: 0, seen };
146
- inventory = partInventory(room);
147
- if (inventory.parts > 0) {
148
- return manifested(room, inventory, JSON.stringify(continued), models);
149
- }
150
- }
151
- else
152
- continued = JSON.parse(request.pageToken);
153
- const listed = continued.room.parts[continued.next];
154
- const sent = listed === undefined
155
- ? { scope: emptyScope(continued.room), frame: null }
156
- : await fetchedPart(entry, continued.room, listed, request.received, request.arriving);
157
- if ('kind' in sent)
158
- return sent;
159
- const { scope } = sent;
160
- notifications.reach(entry.authority, scope);
161
- const next = continued.next + 1;
162
- const more = next < continued.room.parts.length;
163
- const seen = [
164
- ...continued.seen,
165
- ...(scope.files.some((file) => file.path === entry.schema) ? [entry.schema] : []),
166
- ];
167
- const models = await partModels(scope, entry, new Set(seen), !more);
168
- const { folders: _folders, ...page } = await stepped(bootstrapping(scope));
169
- return {
170
- ...page,
171
- ...(models === undefined ? {} : { models }),
172
- ...(more ? { pageToken: JSON.stringify({ ...continued, next, seen }) } : {}),
173
- ...(inventory === undefined ? {} : { inventory }),
174
- ...(sent.frame === null ? {} : { received: sent.frame }),
175
- };
94
+ return request.pageToken === undefined
95
+ ? openedRoom(entry, request.arriving, request.signal)
96
+ : streamedPage(entry, request.pageToken);
176
97
  },
177
- async refresh(_authorization, request) {
178
- const entry = tracked.get(request.locator);
179
- if (entry === undefined)
180
- return { kind: 'room-not-readable', locator: request.locator };
181
- if (request.pageToken !== undefined)
182
- return UNCERTAIN;
183
- if (snapshot) {
184
- return request.fromRoomVersion === roomVersion(entry)
185
- ? { kind: 'still-current' }
186
- : { kind: 'beyond-horizon' };
98
+ ...(snapshot
99
+ ? {
100
+ discover: discovered,
101
+ async refresh(_authorization, request) {
102
+ const entry = tracked.get(request.locator);
103
+ if (entry === undefined)
104
+ return { kind: 'room-not-readable', locator: request.locator };
105
+ if (request.pageToken !== undefined)
106
+ return UNCERTAIN;
107
+ return request.fromRoomVersion === roomVersion(entry)
108
+ ? { kind: 'still-current' }
109
+ : { kind: 'beyond-horizon' };
110
+ },
187
111
  }
188
- return refreshed(entry, request.fromRoomVersion);
189
- },
112
+ : {}),
190
113
  async mutate() {
191
114
  return { kind: 'rejected', affected: {}, code: 'write-grant', fields: {}, retryable: false };
192
115
  },
116
+ async attach() {
117
+ return { kind: 'rejected', code: 'write-grant', fields: {}, retryable: false };
118
+ },
193
119
  async history() {
194
120
  return { kind: 'no-history' };
195
121
  },
@@ -221,7 +147,7 @@ export function createSiteAdapter(transport, snapshot = false) {
221
147
  return followsVersion(version, next);
222
148
  },
223
149
  async action(_authorization, request) {
224
- if (request.name !== SITE_SUBMIT) {
150
+ if (request.name !== SITE_SUBMISSION) {
225
151
  return {
226
152
  kind: 'rejected',
227
153
  code: 'action-unimplemented',
@@ -231,7 +157,7 @@ export function createSiteAdapter(transport, snapshot = false) {
231
157
  }
232
158
  if (!transport.online())
233
159
  return UNCERTAIN;
234
- return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMIT);
160
+ return actionOutcome(await transport.door(SITE_DOOR_SUBMIT, request.input), SITE_SUBMISSION, request.input);
235
161
  },
236
162
  roomStream: snapshot
237
163
  ? undefined
@@ -240,19 +166,10 @@ export function createSiteAdapter(transport, snapshot = false) {
240
166
  notifications.send(rooms.flatMap((room) => {
241
167
  const entry = tracked.get(room.locator);
242
168
  const at = logPosition(room.roomVersion);
243
- if (entry === undefined || at === null)
244
- return [];
245
- notifications.reach(entry.authority, at);
246
- return [presented(entry.authority, at)];
169
+ return entry === undefined || at === null ? [] : [presented(entry.authority, at)];
247
170
  }));
248
171
  },
249
- reopen: notifications.reopen,
250
172
  observe: notifications.observe,
251
- published(locator, roomVersion) {
252
- const at = logPosition(roomVersion);
253
- if (at !== null)
254
- notifications.published(locator, at);
255
- },
256
173
  },
257
174
  serviceMode: notifications.serviceMode,
258
175
  };
package/dist/stream.d.ts CHANGED
@@ -1,24 +1,23 @@
1
- import { type ConversationStream, type RefreshPage, type RoomStreamEvent, type ServiceModeSignal, type StreamReceipts } from '@agentshouse/mdruntime';
1
+ import { type AuthorityChange, type Discovery, type ConversationStream, type RoomStreamEvent, type ServiceModeSignal } from '@agentshouse/mdruntime';
2
2
  import type { TrackedAuthority } from './discovery.js';
3
- import type { HouseDoor, HouseHeldRoom, HouseMode, HouseStreamEntry } from './transport.js';
4
- import { type LogPosition } from './version.js';
5
- export type HeldRevision = (path: string, revision: string) => boolean;
6
- export type StreamedAdvancement = {
7
- page: RefreshPage;
8
- schemas: ReadonlyMap<string, HouseStreamEntry>;
3
+ import { type HouseDoor, type HouseHeldRoom, type HouseMode, type HouseStreamFrame } from './transport.js';
4
+ export type HouseOpeningFrame = Extract<HouseStreamFrame, {
5
+ type: 'opening';
6
+ }>;
7
+ export type HouseAuthorityChangedFrame = Extract<HouseStreamFrame, {
8
+ type: 'authority_changed';
9
+ }>;
10
+ export type HouseDiscovering = {
11
+ opened(frame: HouseOpeningFrame | null): Promise<Discovery | null>;
12
+ changed(frame: HouseAuthorityChangedFrame): AuthorityChange | null;
9
13
  };
10
14
  export type HouseNotifications = {
11
15
  runtime: string;
12
- observe(notify: (event: RoomStreamEvent) => void, receipts: StreamReceipts): () => void;
16
+ observe(notify: (event: RoomStreamEvent) => void): () => void;
13
17
  send(rooms: readonly HouseHeldRoom[]): void;
14
- published(locator: string, at: LogPosition): void;
15
- reopen(): void;
16
18
  track(authorities: readonly TrackedAuthority[]): void;
17
- reach(authority: string, at: LogPosition): void;
18
- edited(tracked: TrackedAuthority, from: LogPosition): readonly string[];
19
- advance(tracked: TrackedAuthority, from: LogPosition, holds?: HeldRevision): Generator<number, StreamedAdvancement | null, void>;
20
19
  conversations: ConversationStream;
21
20
  serviceMode: ServiceModeSignal;
22
21
  };
23
- export declare function houseNotifications(transport: HouseDoor, mode: HouseMode): HouseNotifications;
22
+ export declare function houseNotifications(transport: HouseDoor, mode: HouseMode, discovering: HouseDiscovering): HouseNotifications;
24
23
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,SAAS,EACd,KAAK,kBAAkB,EAIvB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EAEvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAWvD,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,aAAa,EAElB,KAAK,SAAS,EAGd,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAaxB,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAAC;AAElG,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,KAAK,EAAE,0BAA0B,GAAG,eAAe,GAAG,IAAI,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACtD,aAAa,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAmFF,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,SAAS,EACf,WAAW,EAAE,gBAAgB,GAC5B,kBAAkB,CA6TpB"}