@agentshouse/mdruntime 0.1.0-c969b8dee6cc8 → 0.1.0-c96e80d38e5f0

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 (231) hide show
  1. package/README.md +19 -16
  2. package/dist/adapter.d.ts +134 -76
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/binary.d.ts +0 -5
  8. package/dist/binary.d.ts.map +1 -1
  9. package/dist/binary.js +1 -1
  10. package/dist/bootstrap.d.ts +25 -10
  11. package/dist/bootstrap.d.ts.map +1 -1
  12. package/dist/bootstrap.js +180 -103
  13. package/dist/chain.d.ts +11 -0
  14. package/dist/chain.d.ts.map +1 -0
  15. package/dist/chain.js +64 -0
  16. package/dist/change-set.d.ts +9 -16
  17. package/dist/change-set.d.ts.map +1 -1
  18. package/dist/change-set.js +11 -89
  19. package/dist/change.d.ts +31 -1
  20. package/dist/change.d.ts.map +1 -1
  21. package/dist/change.js +10 -1
  22. package/dist/client.d.ts +13 -9
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +80 -7
  25. package/dist/collection.d.ts +10 -21
  26. package/dist/collection.d.ts.map +1 -1
  27. package/dist/collection.js +39 -291
  28. package/dist/compile.d.ts +16 -0
  29. package/dist/compile.d.ts.map +1 -0
  30. package/dist/compile.js +789 -0
  31. package/dist/connection.d.ts +19 -15
  32. package/dist/connection.d.ts.map +1 -1
  33. package/dist/connection.js +3020 -1417
  34. package/dist/conversation.d.ts +23 -14
  35. package/dist/conversation.d.ts.map +1 -1
  36. package/dist/conversation.js +337 -179
  37. package/dist/digest.d.ts +7 -0
  38. package/dist/digest.d.ts.map +1 -0
  39. package/dist/digest.js +113 -0
  40. package/dist/durability.d.ts +2 -5
  41. package/dist/durability.d.ts.map +1 -1
  42. package/dist/durability.js +5 -0
  43. package/dist/entry.d.ts +4 -1
  44. package/dist/entry.d.ts.map +1 -1
  45. package/dist/entry.js +19 -23
  46. package/dist/file.d.ts +2 -19
  47. package/dist/file.d.ts.map +1 -1
  48. package/dist/file.js +7 -122
  49. package/dist/host.d.ts +4 -10
  50. package/dist/host.d.ts.map +1 -1
  51. package/dist/host.js +49 -31
  52. package/dist/identity.d.ts +0 -1
  53. package/dist/identity.d.ts.map +1 -1
  54. package/dist/identity.js +0 -3
  55. package/dist/index.d.ts +14 -11
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +6 -2
  58. package/dist/live.d.ts +22 -0
  59. package/dist/live.d.ts.map +1 -0
  60. package/dist/live.js +123 -0
  61. package/dist/media.d.ts +8 -0
  62. package/dist/media.d.ts.map +1 -0
  63. package/dist/media.js +218 -0
  64. package/dist/memory.d.ts +11 -7
  65. package/dist/memory.d.ts.map +1 -1
  66. package/dist/memory.js +198 -107
  67. package/dist/messages.d.ts +28 -0
  68. package/dist/messages.d.ts.map +1 -0
  69. package/dist/messages.js +89 -0
  70. package/dist/model.d.ts +6 -1
  71. package/dist/model.d.ts.map +1 -1
  72. package/dist/model.js +7 -10
  73. package/dist/name.d.ts +4 -0
  74. package/dist/name.d.ts.map +1 -0
  75. package/dist/name.js +122 -0
  76. package/dist/observation.d.ts +13 -0
  77. package/dist/observation.d.ts.map +1 -1
  78. package/dist/observation.js +84 -0
  79. package/dist/opened.d.ts +22 -0
  80. package/dist/opened.d.ts.map +1 -0
  81. package/dist/opened.js +107 -0
  82. package/dist/outcome.d.ts +40 -8
  83. package/dist/outcome.d.ts.map +1 -1
  84. package/dist/outcome.js +38 -2
  85. package/dist/overlay.d.ts +2 -5
  86. package/dist/overlay.d.ts.map +1 -1
  87. package/dist/overlay.js +87 -172
  88. package/dist/paths.d.ts +1 -0
  89. package/dist/paths.d.ts.map +1 -1
  90. package/dist/paths.js +4 -0
  91. package/dist/phrase.d.ts +3 -0
  92. package/dist/phrase.d.ts.map +1 -0
  93. package/dist/phrase.js +8 -0
  94. package/dist/query.d.ts +15 -1
  95. package/dist/query.d.ts.map +1 -1
  96. package/dist/query.js +33 -2
  97. package/dist/reach.d.ts +13 -4
  98. package/dist/reach.d.ts.map +1 -1
  99. package/dist/reach.js +200 -81
  100. package/dist/react.d.ts +1 -0
  101. package/dist/react.d.ts.map +1 -1
  102. package/dist/readiness.d.ts +14 -17
  103. package/dist/readiness.d.ts.map +1 -1
  104. package/dist/readiness.js +2 -8
  105. package/dist/recovery.d.ts +3 -2
  106. package/dist/recovery.d.ts.map +1 -1
  107. package/dist/recovery.js +34 -7
  108. package/dist/refresh.d.ts +18 -15
  109. package/dist/refresh.d.ts.map +1 -1
  110. package/dist/refresh.js +155 -58
  111. package/dist/replica.d.ts +54 -36
  112. package/dist/replica.d.ts.map +1 -1
  113. package/dist/replica.js +282 -189
  114. package/dist/room-draft.d.ts +22 -4
  115. package/dist/room-draft.d.ts.map +1 -1
  116. package/dist/room-draft.js +154 -67
  117. package/dist/rows.d.ts +39 -31
  118. package/dist/rows.d.ts.map +1 -1
  119. package/dist/rows.js +178 -101
  120. package/dist/save.d.ts +52 -14
  121. package/dist/save.d.ts.map +1 -1
  122. package/dist/save.js +513 -185
  123. package/dist/search.d.ts +12 -95
  124. package/dist/search.d.ts.map +1 -1
  125. package/dist/search.js +10 -266
  126. package/dist/shared.d.ts +7 -3
  127. package/dist/shared.d.ts.map +1 -1
  128. package/dist/shared.js +119 -66
  129. package/dist/status.d.ts +4 -3
  130. package/dist/status.d.ts.map +1 -1
  131. package/dist/status.js +3 -1
  132. package/dist/store.d.ts +91 -103
  133. package/dist/store.d.ts.map +1 -1
  134. package/dist/store.js +330 -693
  135. package/dist/stored.d.ts +162 -0
  136. package/dist/stored.d.ts.map +1 -0
  137. package/dist/stored.js +549 -0
  138. package/dist/tables.d.ts +353 -0
  139. package/dist/tables.d.ts.map +1 -0
  140. package/dist/tables.js +585 -0
  141. package/dist/transfer.d.ts +0 -5
  142. package/dist/transfer.d.ts.map +1 -1
  143. package/dist/turn.d.ts +5 -3
  144. package/dist/turn.d.ts.map +1 -1
  145. package/dist/turn.js +51 -21
  146. package/dist/validation.d.ts +29 -0
  147. package/dist/validation.d.ts.map +1 -0
  148. package/dist/validation.js +101 -0
  149. package/dist/windows.d.ts +2 -6
  150. package/dist/windows.d.ts.map +1 -1
  151. package/dist/windows.js +30 -34
  152. package/dist/wire.d.ts +18 -5
  153. package/dist/wire.d.ts.map +1 -1
  154. package/dist/wire.js +6 -2
  155. package/package.json +18 -19
  156. package/AGENTS.md +0 -305
  157. package/dist/acquisition.d.ts +0 -14
  158. package/dist/acquisition.d.ts.map +0 -1
  159. package/dist/acquisition.js +0 -24
  160. package/dist/chat/acts.d.ts +0 -33
  161. package/dist/chat/acts.d.ts.map +0 -1
  162. package/dist/chat/acts.js +0 -36
  163. package/dist/chat/context.d.ts +0 -3
  164. package/dist/chat/context.d.ts.map +0 -1
  165. package/dist/chat/context.js +0 -10
  166. package/dist/chat/earlier.d.ts +0 -10
  167. package/dist/chat/earlier.d.ts.map +0 -1
  168. package/dist/chat/earlier.js +0 -54
  169. package/dist/chat/input.d.ts +0 -9
  170. package/dist/chat/input.d.ts.map +0 -1
  171. package/dist/chat/input.js +0 -99
  172. package/dist/chat/kit.d.ts +0 -61
  173. package/dist/chat/kit.d.ts.map +0 -1
  174. package/dist/chat/kit.js +0 -123
  175. package/dist/chat/lasting.d.ts +0 -6
  176. package/dist/chat/lasting.d.ts.map +0 -1
  177. package/dist/chat/lasting.js +0 -19
  178. package/dist/chat/list.d.ts +0 -27
  179. package/dist/chat/list.d.ts.map +0 -1
  180. package/dist/chat/list.js +0 -99
  181. package/dist/chat/markdown.d.ts +0 -20
  182. package/dist/chat/markdown.d.ts.map +0 -1
  183. package/dist/chat/markdown.js +0 -188
  184. package/dist/chat/message.d.ts +0 -6
  185. package/dist/chat/message.d.ts.map +0 -1
  186. package/dist/chat/message.js +0 -192
  187. package/dist/chat/messages.d.ts +0 -22
  188. package/dist/chat/messages.d.ts.map +0 -1
  189. package/dist/chat/messages.js +0 -155
  190. package/dist/chat/name.d.ts +0 -6
  191. package/dist/chat/name.d.ts.map +0 -1
  192. package/dist/chat/name.js +0 -37
  193. package/dist/chat/opened.d.ts +0 -11
  194. package/dist/chat/opened.d.ts.map +0 -1
  195. package/dist/chat/opened.js +0 -17
  196. package/dist/chat/overlay.d.ts +0 -31
  197. package/dist/chat/overlay.d.ts.map +0 -1
  198. package/dist/chat/overlay.js +0 -97
  199. package/dist/chat/parts.d.ts +0 -57
  200. package/dist/chat/parts.d.ts.map +0 -1
  201. package/dist/chat/parts.js +0 -119
  202. package/dist/chat/process.d.ts +0 -20
  203. package/dist/chat/process.d.ts.map +0 -1
  204. package/dist/chat/process.js +0 -32
  205. package/dist/chat/provider.d.ts +0 -63
  206. package/dist/chat/provider.d.ts.map +0 -1
  207. package/dist/chat/provider.js +0 -628
  208. package/dist/chat/question.d.ts +0 -9
  209. package/dist/chat/question.d.ts.map +0 -1
  210. package/dist/chat/question.js +0 -69
  211. package/dist/chat/questions.d.ts +0 -31
  212. package/dist/chat/questions.d.ts.map +0 -1
  213. package/dist/chat/questions.js +0 -111
  214. package/dist/chat/read.d.ts +0 -5
  215. package/dist/chat/read.d.ts.map +0 -1
  216. package/dist/chat/read.js +0 -13
  217. package/dist/chat/ready.d.ts +0 -34
  218. package/dist/chat/ready.d.ts.map +0 -1
  219. package/dist/chat/ready.js +0 -91
  220. package/dist/chat/style.d.ts +0 -4
  221. package/dist/chat/style.d.ts.map +0 -1
  222. package/dist/chat/style.js +0 -302
  223. package/dist/chat.d.ts +0 -14
  224. package/dist/chat.d.ts.map +0 -1
  225. package/dist/chat.js +0 -8
  226. package/dist/read-side.d.ts +0 -25
  227. package/dist/read-side.d.ts.map +0 -1
  228. package/dist/read-side.js +0 -767
  229. package/dist/reads.d.ts +0 -11
  230. package/dist/reads.d.ts.map +0 -1
  231. package/dist/reads.js +0 -98
package/dist/reach.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import { unheldView } from './conversation.js';
2
2
  import { modelTypes, NO_MODEL } from './model.js';
3
- import { applied, observing } from './observation.js';
3
+ import { changeOf, digestApplied, digestOf, observing, } from './observation.js';
4
4
  import { runtimeError } from './failure.js';
5
- import { failure, undeclared, } from './outcome.js';
5
+ import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
6
6
  import { beneath } from './paths.js';
7
- import { reconciled } from './read-side.js';
8
7
  import { moveTarget, readParts, staleWrite, } from './room-draft.js';
9
8
  import { documentKey } from './rows.js';
10
- import { undeclaredSearch } from './search.js';
11
9
  const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
12
10
  function unconversed(name) {
13
11
  return () => Promise.resolve(undeclared(name));
@@ -15,19 +13,26 @@ function unconversed(name) {
15
13
  const NO_CONVERSATION = {
16
14
  list: () => Promise.resolve([]),
17
15
  read: (conversation) => Promise.resolve(unheldView(conversation)),
18
- create: unconversed('conversation.create'),
19
- send: unconversed('conversation.send'),
20
- answer: unconversed('conversation.answer'),
21
- interrupt: unconversed('conversation.interrupt'),
22
- kill: unconversed('conversation.kill'),
23
- cancel: unconversed('conversation.cancel'),
24
- delete: unconversed('conversation.delete'),
16
+ create: unconversed('conversations/create'),
17
+ send: unconversed('conversations/send'),
18
+ answer: unconversed('conversations/interaction/answer'),
19
+ interrupt: unconversed('conversations/interrupt'),
20
+ kill: unconversed('conversations/kill'),
21
+ delete: unconversed('conversations/delete'),
25
22
  };
26
23
  const NO_CHAT_DRAFT = {
27
24
  write: () => Promise.resolve(),
28
25
  prepend: () => Promise.resolve(),
29
26
  discard: () => Promise.resolve(),
30
27
  };
28
+ function areasOf(reach) {
29
+ return reach.areas ?? [];
30
+ }
31
+ function fenced(reach, room, path) {
32
+ return areasOf(reach).some((area) => area.room === room &&
33
+ beneath(area.path, path) &&
34
+ !area.open.some((open) => beneath(open, path)));
35
+ }
31
36
  export function holds(reach, room) {
32
37
  return (reach === null ||
33
38
  reach.rooms.includes(room) ||
@@ -48,26 +53,13 @@ export function governs(reach, room) {
48
53
  }
49
54
  function covers(reach, room, path) {
50
55
  return (reach === null ||
51
- reach.rooms.includes(room) ||
52
- reach.documents.some((document) => document.room === room && document.path === path));
56
+ (!fenced(reach, room, path) &&
57
+ (reach.rooms.includes(room) ||
58
+ reach.documents.some((document) => document.room === room && document.path === path))));
53
59
  }
54
60
  function conversing(reach) {
55
61
  return reach === null || reach.conversations;
56
62
  }
57
- function refers(reach, scope) {
58
- if (reach === null)
59
- return true;
60
- if (scope === null)
61
- return false;
62
- if (scope.kind === 'conversations')
63
- return reach.conversations;
64
- return scope.path === undefined
65
- ? wholly(reach, scope.locator)
66
- : covers(reach, scope.locator, scope.path);
67
- }
68
- function unreachedReference(fileRef) {
69
- return { kind: 'absent', code: 'binary-file-absent', fields: { fileRef }, retryable: false };
70
- }
71
63
  export function planReach(reach) {
72
64
  return reach === null
73
65
  ? null
@@ -76,6 +68,9 @@ export function planReach(reach) {
76
68
  documents: [
77
69
  ...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
78
70
  ].sort(),
71
+ areas: areasOf(reach)
72
+ .map(({ room, path, open }) => ({ room, path, open: [...new Set(open)].sort() }))
73
+ .sort((left, right) => documentKey(left.room, left.path) < documentKey(right.room, right.path) ? -1 : 1),
79
74
  };
80
75
  }
81
76
  function roomsWithin(reach, rooms) {
@@ -91,7 +86,7 @@ function typesWithin(reach, room, types) {
91
86
  };
92
87
  }
93
88
  function moves(reach, room, move) {
94
- return move === undefined || covers(reach, room, moveTarget(move));
89
+ return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
95
90
  }
96
91
  function draftWithin(reach, draft) {
97
92
  return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
@@ -124,33 +119,66 @@ function savedWithin(reach, room, result) {
124
119
  function statusWithin(reach, status) {
125
120
  return {
126
121
  ...status,
127
- attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
122
+ attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
123
+ unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
128
124
  };
129
125
  }
130
126
  function queueWithin(reach, room, entries) {
131
- return entries.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
132
- (change.kind !== 'move' || covers(reach, room, change.to))));
127
+ return entries
128
+ .filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
129
+ (change.kind !== 'move' || covers(reach, room, change.to))))
130
+ .map((entry) => {
131
+ const { between, ...batch } = entry.batch;
132
+ if (between === undefined)
133
+ return entry;
134
+ return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
135
+ ? entry
136
+ : { ...entry, batch };
137
+ });
133
138
  }
134
139
  function unreached(room) {
135
- return runtimeError('room-not-held', `No Local Replica for ${room}`);
140
+ return runtimeError('unknown-room', `Unknown Room ${room}`);
141
+ }
142
+ function lockedError(room) {
143
+ return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
144
+ }
145
+ function deviceUnreached() {
146
+ return runtimeError('device-unreached', 'Only the panel cleans up this device');
147
+ }
148
+ const ATTACH_REQUIRED = 'attach-required';
149
+ function attachRequired() {
150
+ return runtimeError(ATTACH_REQUIRED, 'App code takes a file in with binaryFile.attach');
151
+ }
152
+ function carriesFile(parts) {
153
+ return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
136
154
  }
137
155
  export function narrowed(runtime, given, told) {
138
156
  const { md, watch } = runtime;
139
157
  let reach = given;
140
158
  let port = told;
141
159
  const open = new Set();
142
- function following(begin) {
160
+ function following(begin, locking = false) {
143
161
  let stop = begin();
144
162
  const restart = () => {
145
163
  stop();
146
164
  stop = begin();
147
165
  };
148
166
  open.add(restart);
167
+ const unwatch = locking ? runtime.watchLocks(restart) : () => { };
149
168
  return () => {
150
169
  open.delete(restart);
170
+ unwatch();
151
171
  stop();
152
172
  };
153
173
  }
174
+ const unlocking = (rooms) => {
175
+ const locked = (rooms ?? []).filter((room) => runtime.locked(room));
176
+ return locked.length === 0
177
+ ? null
178
+ : { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
179
+ };
180
+ const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
181
+ const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
154
182
  const within = (topic, input, deliver) => {
155
183
  if (topic === 'rooms') {
156
184
  return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
@@ -159,45 +187,60 @@ export function narrowed(runtime, given, told) {
159
187
  return following(() => runtime.watchReadiness(port, reach, deliver));
160
188
  }
161
189
  if (topic === 'sync-status') {
162
- return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
190
+ return following(() => watch(topic, input, (status) => {
191
+ const within = statusWithin(reach, status);
192
+ deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
193
+ }), true);
163
194
  }
164
195
  if (topic === 'room-drafts') {
165
- return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
196
+ return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts)))), true);
166
197
  }
167
198
  if (topic === 'queue') {
168
199
  const room = input[0];
169
200
  return following(() => {
170
- if (!holds(reach, room)) {
201
+ if (!holds(reach, room) || runtime.locked(room)) {
171
202
  deliver([]);
172
203
  return () => { };
173
204
  }
174
205
  return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
175
- });
206
+ }, true);
176
207
  }
177
208
  if (topic === 'query') {
178
209
  const plan = runtime.plan(input[0], reach);
179
210
  let held = null;
180
211
  return following(() => {
212
+ const locked = unlocking(plan.rooms);
213
+ if (locked !== null) {
214
+ const answer = { result: locked, keys: [] };
215
+ if (held === null || changeOf(held, answer) !== null)
216
+ deliver(answer);
217
+ held = digestOf(answer);
218
+ return () => { };
219
+ }
181
220
  let first = true;
182
- return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
221
+ let open = true;
222
+ const heard = (message) => {
183
223
  if (!first) {
184
- held = applied(held, message);
224
+ held = digestApplied(held, message);
185
225
  deliver(message);
186
226
  return;
187
227
  }
188
228
  first = false;
189
- if (held === null) {
190
- held = message;
191
- deliver(message);
192
- return;
193
- }
194
- const next = reconciled(held, message);
195
- if (next === null)
196
- return;
197
- held = next.keyed;
198
- deliver(next.message);
229
+ const change = held === null ? message : changeOf(held, message);
230
+ held = digestOf(message);
231
+ if (change !== null)
232
+ deliver(change);
233
+ };
234
+ const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
235
+ const stop = runtime.watchPlan(current, (message) => {
236
+ if (open)
237
+ heard(message);
199
238
  });
200
- });
239
+ return () => {
240
+ open = false;
241
+ stop();
242
+ };
243
+ }, true);
201
244
  }
202
245
  if (topic === 'conversation') {
203
246
  return following(() => {
@@ -217,70 +260,147 @@ export function narrowed(runtime, given, told) {
217
260
  }
218
261
  return watch(topic, input, deliver);
219
262
  };
263
+ const files = new Map();
264
+ let handed = 0;
265
+ async function hand(reading) {
266
+ const answer = await reading;
267
+ if (answer.kind !== 'binary')
268
+ return answer;
269
+ handed += 1;
270
+ const file = String(handed);
271
+ files.set(file, answer.file);
272
+ return { ...answer, file };
273
+ }
220
274
  const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
221
275
  const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
222
276
  const view = {
223
277
  ...md,
224
- rooms: () => roomsWithin(reach, md.rooms()),
225
- query: ((input) => runtime.query(runtime.plan(input, reach))),
226
- search: (input) => port.search === 'required'
227
- ? runtime.search(input, reach)
228
- : Promise.resolve(undeclaredSearch()),
278
+ rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
279
+ query: ((input) => {
280
+ const plan = runtime.plan(input, reach);
281
+ return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
282
+ }),
283
+ search: (input) => runtime.search(input, reach),
229
284
  types(room) {
285
+ if (holds(reach, room) && runtime.locked(room))
286
+ throw lockedError(room);
230
287
  if (wholly(reach, room))
231
288
  return md.types(room);
232
289
  if (!holds(reach, room))
233
290
  return structuredClone(UNHELD_TYPES);
234
- const listed = md.rooms().find(({ locator }) => locator === room);
235
- return typesWithin(reach, listed, md.types(room));
291
+ return typesWithin(reach, runtime.room(room), md.types(room));
236
292
  },
237
293
  async save(room, roomDrafts, writtenBy) {
238
294
  if (!holds(reach, room))
239
295
  throw unreached(room);
240
- const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
241
- !moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
296
+ if (runtime.locked(room))
297
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
298
+ const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
299
+ const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
242
300
  if (outside !== undefined) {
243
301
  return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
244
302
  }
303
+ if (intoLocked(held))
304
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
245
305
  return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
246
306
  },
247
307
  async saveParts(room, parts, writtenBy) {
248
308
  if (!holds(reach, room))
249
309
  throw unreached(room);
250
- if (parts.some(({ path, parts: one }) => !covers(reach, room, path) || !moves(reach, room, readParts(one).move))) {
310
+ const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
311
+ if (filed !== undefined) {
312
+ return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
313
+ }
314
+ if (runtime.locked(room))
315
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
316
+ const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
317
+ if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
251
318
  throw unreached(room);
252
319
  }
320
+ if (intoLocked(held))
321
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
253
322
  return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
254
323
  },
255
- history: (room, path, query) => covers(reach, room, path)
256
- ? md.history(room, path, query)
257
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
324
+ resolve(room, path, destination) {
325
+ const at = runtime.located(room, path, destination);
326
+ return at !== null && !covers(reach, at.room, at.path)
327
+ ? Promise.resolve(UNREADABLE)
328
+ : md.resolve(room, path, destination);
329
+ },
330
+ history: (room, path, query) => !covers(reach, room, path)
331
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
332
+ : runtime.locked(room)
333
+ ? Promise.resolve(lockedRoom(room))
334
+ : md.history(room, path, query),
258
335
  binaryFile: {
259
- read: (room, path, revision) => covers(reach, room, path)
260
- ? md.binaryFile.read(room, path, revision)
261
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
262
- link: (room, path, revision) => covers(reach, room, path)
263
- ? md.binaryFile.link(room, path, revision)
264
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
265
- readReference: (reference) => refers(reach, runtime.referrerScope(reference.referrer))
266
- ? md.binaryFile.readReference(reference)
267
- : Promise.resolve(unreachedReference(reference.fileRef)),
336
+ read: (room, path, revision) => !covers(reach, room, path)
337
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
338
+ : runtime.locked(room)
339
+ ? Promise.resolve(lockedRoom(room))
340
+ : hand(md.binaryFile.read(room, path, revision)),
341
+ link: (room, path, revision) => !covers(reach, room, path)
342
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
343
+ : runtime.locked(room)
344
+ ? Promise.resolve(lockedRoom(room))
345
+ : md.binaryFile.link(room, path, revision),
346
+ show: (room, path, revision) => !covers(reach, room, path)
347
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
348
+ : runtime.locked(room)
349
+ ? Promise.resolve(lockedRoom(room))
350
+ : hand(md.binaryFile.show(room, path, revision)),
351
+ attach: (room, file) => !wholly(reach, room)
352
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
353
+ : runtime.locked(room)
354
+ ? Promise.resolve(lockedRoom(room))
355
+ : md.binaryFile.attach(room, file),
356
+ async part(file, part) {
357
+ const key = files.get(file);
358
+ if (key === undefined)
359
+ return null;
360
+ const bytes = await md.binaryFile.part(key, part);
361
+ if (bytes === null)
362
+ files.delete(file);
363
+ return bytes;
364
+ },
268
365
  },
269
- reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
270
- md.reached(room, roomVersion, path),
366
+ reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
367
+ !runtime.locked(room) &&
368
+ (await md.reached(room, roomVersion, path)),
271
369
  log: () => (reach === null ? md.log() : ''),
370
+ cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
272
371
  roomDraft: {
273
- list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
274
- read: (room, path) => covers(reach, room, path) ? shownDraft(reach, md.roomDraft.read(room, path)) : null,
275
- async write(room, path, revision, parts) {
276
- if (!covers(reach, room, path) || !moves(reach, room, readParts(parts).move)) {
277
- throw unreached(room);
372
+ list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
373
+ async read(room, path) {
374
+ if (!covers(reach, room, path))
375
+ return null;
376
+ if (runtime.locked(room))
377
+ throw lockedError(room);
378
+ return shownDraft(reach, await md.roomDraft.read(room, path));
379
+ },
380
+ write(room, path, revision, parts, next) {
381
+ try {
382
+ if (reach !== null && carriesFile(parts))
383
+ throw attachRequired();
384
+ const move = readParts(parts, path).move;
385
+ if (!covers(reach, room, path) || !moves(reach, room, move))
386
+ throw unreached(room);
387
+ if (runtime.locked(room))
388
+ throw lockedError(room);
389
+ if (intoLocked([move]))
390
+ throw lockedError(move.room);
391
+ }
392
+ catch (error) {
393
+ return Promise.reject(error);
278
394
  }
279
- return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
395
+ return md.roomDraft
396
+ .write(room, path, revision, parts, next)
397
+ .then((written) => writeWithin(reach, written));
280
398
  },
281
399
  async discard(room, path, revision) {
282
400
  if (!covers(reach, room, path))
283
401
  return staleWrite(null);
402
+ if (runtime.locked(room))
403
+ throw lockedError(room);
284
404
  return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
285
405
  },
286
406
  },
@@ -292,7 +412,6 @@ export function narrowed(runtime, given, told) {
292
412
  answer: (id, answer) => conversation().answer(id, answer),
293
413
  interrupt: (id) => conversation().interrupt(id),
294
414
  kill: (id) => conversation().kill(id),
295
- cancel: (id, turn) => conversation().cancel(id, turn),
296
415
  delete: (id) => conversation().delete(id),
297
416
  },
298
417
  chatDraft: {
package/dist/react.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare function useObserve(client: Client, topic: 'storage-loss'): Obser
23
23
  export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
24
24
  export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
25
25
  export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
26
+ export declare function useObserve(client: Client, topic: 'authority-changes'): Observed<number>;
26
27
  export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
27
28
  export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
28
29
  export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
@@ -1,35 +1,33 @@
1
1
  import type { Open } from './open.js';
2
2
  export type CodeAvailability = Open<'stored' | 'absent'>;
3
- export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'indexing' | 'refused' | 'unadmitted'>;
3
+ export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'unadmitted'>;
4
4
  export type RoomCoverage = {
5
5
  readonly room: string;
6
6
  readonly state: RoomPreparation;
7
7
  };
8
- export type ConversationCoverage = Open<'complete' | 'acquiring' | 'indexing' | 'undeclared'>;
9
- export type SearchObligation = Open<'required' | 'unused'>;
8
+ export type ConversationCoverage = Open<'complete' | 'acquiring' | 'undeclared'>;
10
9
  export type TargetCoverage = {
11
10
  readonly complete: boolean;
12
11
  readonly listed: boolean;
13
12
  readonly rooms: readonly RoomCoverage[];
14
13
  readonly conversations: ConversationCoverage;
15
- readonly search: SearchObligation;
16
14
  };
17
15
  export type Persistence = Open<'granted' | 'denied' | 'unavailable'>;
18
16
  export type Durability = Open<'persistent' | 'best-effort'>;
19
17
  export type ConnectionAvailability = Open<'connected' | 'connecting' | 'unreachable'>;
20
18
  export type HouseOutcome = Open<'open' | 'write-halted' | 'refused'>;
21
- export type CapacityCause = {
22
- readonly cause: Open<'insufficient-space' | 'quota-exceeded'>;
23
- readonly needed: number | null;
24
- readonly available: number | null;
19
+ export type Space = Open<'full'>;
20
+ export type InstallationStep = Open<'downloading' | 'writing' | 'replaying'>;
21
+ export type InstallationAmount = {
22
+ readonly done: number;
23
+ readonly total: number;
25
24
  };
26
- export type RefusedRoom = {
27
- readonly room: string;
28
- readonly file: string;
29
- readonly rule: string;
30
- readonly location: string | null;
25
+ export type Installation = {
26
+ readonly step: InstallationStep | null;
27
+ readonly rooms: InstallationAmount;
28
+ readonly bytes: InstallationAmount;
31
29
  };
32
- export type ReadinessStatus = Open<'preparing' | 'paused' | 'refused' | 'ready' | 'lost'>;
30
+ export type ReadinessStatus = Open<'preparing' | 'paused' | 'ready' | 'lost'>;
33
31
  export type Readiness = {
34
32
  readonly status: ReadinessStatus;
35
33
  readonly ready: boolean;
@@ -40,14 +38,13 @@ export type Readiness = {
40
38
  readonly persistence: Persistence;
41
39
  readonly connection: ConnectionAvailability;
42
40
  readonly house: HouseOutcome;
43
- readonly capacity: CapacityCause | null;
44
- readonly refused: readonly RefusedRoom[];
41
+ readonly space: Space | null;
42
+ readonly installation: Installation;
45
43
  readonly lost: boolean;
46
44
  };
47
45
  export type ReadinessFacts = Omit<Readiness, 'status' | 'ready' | 'usable' | 'durability' | 'coverage'> & {
48
46
  readonly coverage: Omit<TargetCoverage, 'complete'>;
49
47
  readonly established: boolean;
50
48
  };
51
- export declare const SETTLED_ROOMS: ReadonlySet<string>;
52
49
  export declare function readinessOf(facts: ReadinessFacts): Readiness;
53
50
  //# sourceMappingURL=readiness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC;AAE1F,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC;AAEjF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAC;AAErE,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,CAAC;AAE5D,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,WAAW,GAAG,YAAY,GAAG,aAAa,CAAC,CAAC;AAEtF,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC,CAAC;AAErE,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AAEjC,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC;AAE7E,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAE9E,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,SAAS,EACT,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAC1D,GAAG;IACF,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B,CAAC;AAIF,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CA2B5D"}
package/dist/readiness.js CHANGED
@@ -1,27 +1,21 @@
1
1
  const COMPLETE_ROOMS = new Set(['complete', 'unadmitted']);
2
- export const SETTLED_ROOMS = new Set([...COMPLETE_ROOMS, 'refused']);
3
2
  export function readinessOf(facts) {
4
3
  const { established, coverage: held, ...reported } = facts;
5
4
  const settledConversations = held.conversations === 'complete' || held.conversations === 'undeclared';
6
5
  const complete = held.listed &&
7
6
  settledConversations &&
8
7
  held.rooms.every((room) => COMPLETE_ROOMS.has(room.state));
9
- const settled = held.listed &&
10
- settledConversations &&
11
- held.rooms.every((room) => SETTLED_ROOMS.has(room.state));
12
8
  const coverage = { ...held, complete };
13
9
  const stored = facts.code === 'stored';
14
10
  const ready = stored && complete;
15
11
  const usable = stored && (ready || established);
16
12
  const status = ready
17
13
  ? 'ready'
18
- : facts.capacity !== null
14
+ : facts.space !== null
19
15
  ? 'paused'
20
16
  : facts.lost && !established
21
17
  ? 'lost'
22
- : settled && !complete
23
- ? 'refused'
24
- : 'preparing';
18
+ : 'preparing';
25
19
  return {
26
20
  ...reported,
27
21
  coverage,
@@ -8,7 +8,7 @@ export type AttemptOptions = {
8
8
  };
9
9
  export type RecoveryOptions = {
10
10
  readonly firstMs?: number;
11
- readonly ceilingMs?: number;
11
+ readonly maxMs?: number;
12
12
  readonly attempts?: number;
13
13
  readonly inFlight?: number;
14
14
  };
@@ -20,6 +20,7 @@ export type Recovery = {
20
20
  scope(inFlight?: number): Recovery;
21
21
  retire(): Promise<void>;
22
22
  };
23
- export declare function retryDelay(tries: number, firstMs?: number, ceilingMs?: number): number;
23
+ export declare function retryDelay(tries: number, firstMs?: number, maxMs?: number): number;
24
+ export declare function untilAnswered<T>(ask: () => Promise<T>, signal: AbortSignal, answered?: (answer: T) => boolean): Promise<T>;
24
25
  export declare function createRecovery(options?: RecoveryOptions): Recovery;
25
26
  //# sourceMappingURL=recovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAsBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAW,EAAE,SAAS,SAAa,GAAG,MAAM,CAG5F;AAuKD,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAStE"}
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAsBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAW,EAAE,KAAK,SAAS,GAAG,MAAM,CAGpF;AAED,wBAAsB,aAAa,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,MAAM,EAAE,WAAW,EACnB,QAAQ,GAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAoB,GAC5C,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAwKD,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAStE"}