@agentshouse/mdruntime 0.1.0-c49444f2a8fc6 → 0.1.0-c4c5934c45f21

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 (261) hide show
  1. package/README.md +8 -8
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +308 -0
  5. package/dist/act-lanes.d.ts +33 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +177 -0
  8. package/dist/actions.d.ts +20 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +251 -0
  11. package/dist/adapter.d.ts +31 -44
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/bootstrap.d.ts +1 -1
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +6 -18
  16. package/dist/cell.d.ts +6 -0
  17. package/dist/cell.d.ts.map +1 -0
  18. package/dist/cell.js +9 -0
  19. package/dist/change-set.d.ts +4 -0
  20. package/dist/change-set.d.ts.map +1 -1
  21. package/dist/change-set.js +6 -0
  22. package/dist/change.d.ts.map +1 -1
  23. package/dist/change.js +4 -2
  24. package/dist/chat-types.d.ts +5 -0
  25. package/dist/chat-types.d.ts.map +1 -0
  26. package/dist/chat-types.js +13 -0
  27. package/dist/client.d.ts +19 -13
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +30 -14
  30. package/dist/collection.d.ts +22 -4
  31. package/dist/collection.d.ts.map +1 -1
  32. package/dist/collection.js +12 -2
  33. package/dist/compile.d.ts +5 -0
  34. package/dist/compile.d.ts.map +1 -1
  35. package/dist/compile.js +200 -75
  36. package/dist/connection.d.ts +5 -143
  37. package/dist/connection.d.ts.map +1 -1
  38. package/dist/connection.js +104 -5308
  39. package/dist/conversation-live.d.ts +136 -0
  40. package/dist/conversation-live.d.ts.map +1 -0
  41. package/dist/conversation-live.js +249 -0
  42. package/dist/conversation-row.d.ts.map +1 -1
  43. package/dist/conversation-row.js +7 -1
  44. package/dist/conversation.d.ts +43 -44
  45. package/dist/conversation.d.ts.map +1 -1
  46. package/dist/conversation.js +906 -1024
  47. package/dist/declaration.d.ts +10 -0
  48. package/dist/declaration.d.ts.map +1 -0
  49. package/dist/declaration.js +24 -0
  50. package/dist/discovery.d.ts +10 -0
  51. package/dist/discovery.d.ts.map +1 -0
  52. package/dist/discovery.js +148 -0
  53. package/dist/durability.d.ts +9 -0
  54. package/dist/durability.d.ts.map +1 -1
  55. package/dist/expectation.d.ts +4 -2
  56. package/dist/expectation.d.ts.map +1 -1
  57. package/dist/expectation.js +33 -11
  58. package/dist/failure.d.ts +1 -0
  59. package/dist/failure.d.ts.map +1 -1
  60. package/dist/failure.js +3 -0
  61. package/dist/figures.d.ts +49 -0
  62. package/dist/figures.d.ts.map +1 -0
  63. package/dist/figures.js +197 -0
  64. package/dist/holdings.d.ts +29 -0
  65. package/dist/holdings.d.ts.map +1 -0
  66. package/dist/holdings.js +95 -0
  67. package/dist/host.d.ts +18 -2
  68. package/dist/host.d.ts.map +1 -1
  69. package/dist/host.js +45 -12
  70. package/dist/index.d.ts +22 -8
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +7 -2
  73. package/dist/install.d.ts +54 -0
  74. package/dist/install.d.ts.map +1 -0
  75. package/dist/install.js +538 -0
  76. package/dist/lifecycle.d.ts +7 -0
  77. package/dist/lifecycle.d.ts.map +1 -0
  78. package/dist/lifecycle.js +272 -0
  79. package/dist/listing.d.ts +48 -0
  80. package/dist/listing.d.ts.map +1 -0
  81. package/dist/listing.js +139 -0
  82. package/dist/live.d.ts.map +1 -1
  83. package/dist/live.js +3 -3
  84. package/dist/locks.d.ts +7 -0
  85. package/dist/locks.d.ts.map +1 -0
  86. package/dist/locks.js +33 -0
  87. package/dist/log.d.ts +1 -0
  88. package/dist/log.d.ts.map +1 -1
  89. package/dist/lost.d.ts +5 -0
  90. package/dist/lost.d.ts.map +1 -0
  91. package/dist/lost.js +50 -0
  92. package/dist/media.d.ts +1 -1
  93. package/dist/media.d.ts.map +1 -1
  94. package/dist/media.js +4 -4
  95. package/dist/memory.d.ts +4 -2
  96. package/dist/memory.d.ts.map +1 -1
  97. package/dist/memory.js +38 -20
  98. package/dist/messages.d.ts +1 -4
  99. package/dist/messages.d.ts.map +1 -1
  100. package/dist/messages.js +14 -32
  101. package/dist/model.d.ts +0 -1
  102. package/dist/model.d.ts.map +1 -1
  103. package/dist/model.js +0 -5
  104. package/dist/models.d.ts +10 -0
  105. package/dist/models.d.ts.map +1 -0
  106. package/dist/models.js +156 -0
  107. package/dist/observation.d.ts.map +1 -1
  108. package/dist/observation.js +12 -17
  109. package/dist/opened.d.ts +1 -1
  110. package/dist/opened.d.ts.map +1 -1
  111. package/dist/opened.js +5 -5
  112. package/dist/opening.d.ts +4 -0
  113. package/dist/opening.d.ts.map +1 -0
  114. package/dist/opening.js +59 -0
  115. package/dist/outcome.d.ts +4 -1
  116. package/dist/outcome.d.ts.map +1 -1
  117. package/dist/outcome.js +3 -0
  118. package/dist/overlay.d.ts +2 -1
  119. package/dist/overlay.d.ts.map +1 -1
  120. package/dist/overlay.js +32 -21
  121. package/dist/page-metadata.d.ts +8 -0
  122. package/dist/page-metadata.d.ts.map +1 -0
  123. package/dist/page-metadata.js +19 -0
  124. package/dist/parts.d.ts +3 -51
  125. package/dist/parts.d.ts.map +1 -1
  126. package/dist/parts.js +14 -111
  127. package/dist/paths.d.ts +1 -0
  128. package/dist/paths.d.ts.map +1 -1
  129. package/dist/paths.js +22 -0
  130. package/dist/preparation.d.ts +20 -0
  131. package/dist/preparation.d.ts.map +1 -0
  132. package/dist/preparation.js +233 -0
  133. package/dist/presence.d.ts +52 -0
  134. package/dist/presence.d.ts.map +1 -0
  135. package/dist/presence.js +220 -0
  136. package/dist/queries.d.ts +16 -0
  137. package/dist/queries.d.ts.map +1 -0
  138. package/dist/queries.js +270 -0
  139. package/dist/query.d.ts +10 -1
  140. package/dist/query.d.ts.map +1 -1
  141. package/dist/questions.d.ts +2 -0
  142. package/dist/questions.d.ts.map +1 -1
  143. package/dist/questions.js +5 -1
  144. package/dist/queue.d.ts +40 -0
  145. package/dist/queue.d.ts.map +1 -0
  146. package/dist/queue.js +455 -0
  147. package/dist/reach.d.ts +3 -1
  148. package/dist/reach.d.ts.map +1 -1
  149. package/dist/reach.js +38 -8
  150. package/dist/react.d.ts +18 -1
  151. package/dist/react.d.ts.map +1 -1
  152. package/dist/react.js +15 -1
  153. package/dist/readiness.d.ts +0 -1
  154. package/dist/readiness.d.ts.map +1 -1
  155. package/dist/reads.d.ts +37 -0
  156. package/dist/reads.d.ts.map +1 -0
  157. package/dist/reads.js +174 -0
  158. package/dist/refresh.js +2 -2
  159. package/dist/refusal.d.ts +5 -0
  160. package/dist/refusal.d.ts.map +1 -0
  161. package/dist/refusal.js +57 -0
  162. package/dist/replica.d.ts +5 -13
  163. package/dist/replica.d.ts.map +1 -1
  164. package/dist/replica.js +15 -16
  165. package/dist/room-draft.d.ts +4 -6
  166. package/dist/room-draft.d.ts.map +1 -1
  167. package/dist/room-draft.js +36 -52
  168. package/dist/room-drafts.d.ts +24 -0
  169. package/dist/room-drafts.d.ts.map +1 -0
  170. package/dist/room-drafts.js +217 -0
  171. package/dist/rows.d.ts.map +1 -1
  172. package/dist/rows.js +3 -4
  173. package/dist/runtime.d.ts +34 -0
  174. package/dist/runtime.d.ts.map +1 -0
  175. package/dist/runtime.js +1 -0
  176. package/dist/save.d.ts +41 -86
  177. package/dist/save.d.ts.map +1 -1
  178. package/dist/save.js +232 -112
  179. package/dist/saves.d.ts +32 -0
  180. package/dist/saves.d.ts.map +1 -0
  181. package/dist/saves.js +413 -0
  182. package/dist/seed.d.ts +11 -2
  183. package/dist/seed.d.ts.map +1 -1
  184. package/dist/seed.js +71 -1
  185. package/dist/shared.d.ts +1 -6
  186. package/dist/shared.d.ts.map +1 -1
  187. package/dist/shared.js +13 -95
  188. package/dist/shown.d.ts +32 -0
  189. package/dist/shown.d.ts.map +1 -0
  190. package/dist/shown.js +290 -0
  191. package/dist/socket/admission.d.ts +7 -0
  192. package/dist/socket/admission.d.ts.map +1 -0
  193. package/dist/socket/admission.js +39 -0
  194. package/dist/socket/answers.d.ts +6 -0
  195. package/dist/socket/answers.d.ts.map +1 -0
  196. package/dist/socket/answers.js +20 -0
  197. package/dist/socket/lanes.d.ts +20 -0
  198. package/dist/socket/lanes.d.ts.map +1 -0
  199. package/dist/socket/lanes.js +77 -0
  200. package/dist/socket/reads.d.ts +10 -0
  201. package/dist/socket/reads.d.ts.map +1 -0
  202. package/dist/socket/reads.js +31 -0
  203. package/dist/socket/session.d.ts +38 -0
  204. package/dist/socket/session.d.ts.map +1 -0
  205. package/dist/socket/session.js +23 -0
  206. package/dist/socket.d.ts +67 -0
  207. package/dist/socket.d.ts.map +1 -0
  208. package/dist/socket.js +170 -0
  209. package/dist/source.d.ts.map +1 -1
  210. package/dist/source.js +5 -4
  211. package/dist/store/installs.d.ts +30 -0
  212. package/dist/store/installs.d.ts.map +1 -0
  213. package/dist/store/installs.js +34 -0
  214. package/dist/store/readiness.d.ts +10 -0
  215. package/dist/store/readiness.d.ts.map +1 -0
  216. package/dist/store/readiness.js +52 -0
  217. package/dist/store/records.d.ts +212 -0
  218. package/dist/store/records.d.ts.map +1 -0
  219. package/dist/store/records.js +430 -0
  220. package/dist/store/room-held.d.ts +8 -0
  221. package/dist/store/room-held.d.ts.map +1 -0
  222. package/dist/store/room-held.js +17 -0
  223. package/dist/store/space.d.ts +11 -0
  224. package/dist/store/space.d.ts.map +1 -0
  225. package/dist/store/space.js +41 -0
  226. package/dist/store/watchers.d.ts +17 -0
  227. package/dist/store/watchers.d.ts.map +1 -0
  228. package/dist/store/watchers.js +56 -0
  229. package/dist/store/writes.d.ts +24 -0
  230. package/dist/store/writes.d.ts.map +1 -0
  231. package/dist/store/writes.js +125 -0
  232. package/dist/store.d.ts +112 -204
  233. package/dist/store.d.ts.map +1 -1
  234. package/dist/store.js +158 -394
  235. package/dist/stored.d.ts +1 -1
  236. package/dist/stored.d.ts.map +1 -1
  237. package/dist/stored.js +28 -14
  238. package/dist/surface.d.ts +88 -0
  239. package/dist/surface.d.ts.map +1 -0
  240. package/dist/surface.js +223 -0
  241. package/dist/sync.d.ts +19 -0
  242. package/dist/sync.d.ts.map +1 -0
  243. package/dist/sync.js +521 -0
  244. package/dist/tables.d.ts +32 -8
  245. package/dist/tables.d.ts.map +1 -1
  246. package/dist/tables.js +43 -12
  247. package/dist/tallies.d.ts +18 -0
  248. package/dist/tallies.d.ts.map +1 -0
  249. package/dist/tallies.js +129 -0
  250. package/dist/validation.d.ts.map +1 -1
  251. package/dist/validation.js +2 -2
  252. package/dist/wire.d.ts +48 -5
  253. package/dist/wire.d.ts.map +1 -1
  254. package/dist/wire.js +16 -3
  255. package/package.json +3 -2
  256. package/dist/attempt.d.ts +0 -16
  257. package/dist/attempt.d.ts.map +0 -1
  258. package/dist/attempt.js +0 -70
  259. package/dist/job.d.ts +0 -33
  260. package/dist/job.d.ts.map +0 -1
  261. package/dist/job.js +0 -54
package/dist/save.js CHANGED
@@ -1,11 +1,11 @@
1
- import { definitionOf } from './model.js';
2
- import { apply, ARRAY_INDEX, ATTACHMENT, links, parse, pointerSegments, references, relative, relativize, retarget, roomReferences, serialize, target, } from '@agentshouse/mdmodel';
1
+ import { apply, ARRAY_INDEX, ATTACHMENT, create, links, parse, pointerSegments, references, relative, relativize, retarget, roomReferences, serialize, target, } from '@agentshouse/mdmodel';
3
2
  import { immutable, leaving, queuedFile, departure, } from './change.js';
4
- import { collectionOf, documentsOf, governing, } from './collection.js';
5
- import { changeBatchIdentity } from './identity.js';
3
+ import { collectionOf, definitionsAt, documentsOf, governing, } from './collection.js';
4
+ import { changeBatchIdentity, roomDraftRevision } from './identity.js';
6
5
  import { overlaying } from './overlay.js';
7
- import { ancestors, covered, normalize } from './paths.js';
8
- import { sorting } from './shared.js';
6
+ import { ancestors } from './paths.js';
7
+ import { entriesIn, sorting } from './shared.js';
8
+ import { changedParts, changesOf, moveTarget, withdrawnDrafts, } from './room-draft.js';
9
9
  import { paced, ROW_WEIGHT, stepped } from './turn.js';
10
10
  import { validatedCollection } from './validation.js';
11
11
  function refuse(code, file, location) {
@@ -20,9 +20,6 @@ function refuse(code, file, location) {
20
20
  };
21
21
  }
22
22
  function repointed(document, definition, from, to, moves, settled) {
23
- const parsed = parse(document.content, from);
24
- if (!parsed.ok)
25
- return [];
26
23
  const changes = [];
27
24
  const names = new Set();
28
25
  for (const { pointer, value } of definition === undefined
@@ -45,13 +42,13 @@ function repointed(document, definition, from, to, moves, settled) {
45
42
  }
46
43
  if (changes.length === 0)
47
44
  return [];
48
- const applied = apply(parsed.document, changes);
45
+ const applied = apply(document, changes, definition);
49
46
  if (applied.outcome !== 'applied')
50
47
  return [];
51
48
  const next = applied.document;
52
49
  return [...names].map((name) => ({ kind: 'field', path: from, name, value: next.fields[name] }));
53
50
  }
54
- function edited(document, changes) {
51
+ function edited(document, changes, definition) {
55
52
  const parts = new Map();
56
53
  for (const change of changes) {
57
54
  if (change.kind === 'preamble')
@@ -66,7 +63,7 @@ function edited(document, changes) {
66
63
  }
67
64
  if (parts.size === 0)
68
65
  return document;
69
- const applied = apply(document, [...parts.values()]);
66
+ const applied = apply(document, [...parts.values()], definition);
70
67
  return applied.outcome === 'applied' ? applied.document : document;
71
68
  }
72
69
  function bodies(path, before, after) {
@@ -81,7 +78,7 @@ function bodies(path, before, after) {
81
78
  }
82
79
  return changes;
83
80
  }
84
- function relinks(path, moved, before, moves) {
81
+ function relinks(path, moved, before, moves, definition) {
85
82
  const changes = [];
86
83
  for (const link of links(before, path)) {
87
84
  const destination = moves.get(link.target) ?? link.target;
@@ -94,7 +91,7 @@ function relinks(path, moved, before, moves) {
94
91
  }
95
92
  if (changes.length === 0)
96
93
  return { kind: 'changes', changes: [] };
97
- const applied = apply(before, changes);
94
+ const applied = apply(before, changes, definition);
98
95
  if (applied.outcome === 'refuse') {
99
96
  return {
100
97
  kind: 'refused',
@@ -117,6 +114,15 @@ function relinks(path, moved, before, moves) {
117
114
  function partKey(change) {
118
115
  return change.kind === 'section' ? `section ${change.name}` : change.kind;
119
116
  }
117
+ const NAMES_A_SKIP_TESTS = 64;
118
+ const ENCODED = /[%&\\]/u;
119
+ function movedNames(moves) {
120
+ const names = new Set([...moves.keys()].map((path) => path.slice(path.lastIndexOf('/') + 1)));
121
+ return names.size > NAMES_A_SKIP_TESTS ? null : [...names];
122
+ }
123
+ function cannotLink(text, names) {
124
+ return names !== null && !ENCODED.test(text) && !names.some((name) => text.includes(name));
125
+ }
120
126
  function* rewrites(changes, visible) {
121
127
  const moves = new Map();
122
128
  const settled = new Set();
@@ -142,17 +148,20 @@ function* rewrites(changes, visible) {
142
148
  }
143
149
  if (moves.size === 0)
144
150
  return { kind: 'changes', changes };
151
+ const names = movedNames(moves);
145
152
  const merged = [...changes];
146
153
  const added = [];
147
154
  for (const [path, document] of yield* documentsOf(visible.collection)) {
148
155
  if (settled.has(path))
149
156
  continue;
150
157
  const moved = moves.get(path) ?? path;
151
- const definition = definitionOf(governing(visible.collection.composition, path), document.type);
158
+ const definition = definitionsAt(visible.collection.composition, path)(document.type);
152
159
  const repointing = repointed(document, definition, path, moved, moves, settled);
153
160
  added.push(...repointing);
154
161
  const own = parts.get(path) ?? [];
155
- const relinked = relinks(path, moved, edited(document, own.map((index) => merged[index])), moves);
162
+ const relinked = moved === path && own.length === 0 && cannotLink(document.content, names)
163
+ ? { kind: 'changes', changes: [] }
164
+ : relinks(path, moved, edited(document, own.map((index) => merged[index]), definition), moves, definition);
156
165
  if (relinked.kind === 'refused')
157
166
  return relinked;
158
167
  const keyed = new Map();
@@ -221,10 +230,10 @@ function crossed(document, definition, path, to) {
221
230
  }
222
231
  return changes;
223
232
  }
224
- function rewritten(path, document, changes) {
233
+ function rewritten(path, document, changes, definition) {
225
234
  if (changes.length === 0)
226
235
  return [];
227
- const applied = apply(document, changes);
236
+ const applied = apply(document, changes, definition);
228
237
  if (applied.outcome !== 'applied')
229
238
  return [];
230
239
  const after = applied.document;
@@ -239,7 +248,7 @@ function rewritten(path, document, changes) {
239
248
  function roomPathOf(handle, path) {
240
249
  return `/rooms/${handle}/${path}`;
241
250
  }
242
- export function* leavingRewritten(batch, visible) {
251
+ function* leavingRewritten(batch, visible) {
243
252
  const between = batch.between;
244
253
  if (between === undefined)
245
254
  return batch;
@@ -248,8 +257,8 @@ export function* leavingRewritten(batch, visible) {
248
257
  for (const [path, document] of yield* documentsOf(visible.collection)) {
249
258
  if (moved.has(path))
250
259
  continue;
251
- const definition = definitionOf(governing(visible.collection.composition, path), document.type);
252
- derived.push(...rewritten(path, document, crossed(document, definition, path, (named) => moved.get(named))));
260
+ const definition = definitionsAt(visible.collection.composition, path)(document.type);
261
+ derived.push(...rewritten(path, document, crossed(document, definition, path, (named) => moved.get(named)), definition));
253
262
  yield ROW_WEIGHT + visible.collection.text[path].length;
254
263
  }
255
264
  if (derived.length === 0)
@@ -291,7 +300,7 @@ function* incoming(collection, removed, candidates) {
291
300
  for (const [path, document] of candidates === null
292
301
  ? yield* documentsOf(collection)
293
302
  : read(candidates)) {
294
- const definition = definitionOf(governing(collection.composition, path), document.type);
303
+ const definition = definitionsAt(collection.composition, path)(document.type);
295
304
  for (const { value, to } of definition === undefined ? [] : references(document, definition)) {
296
305
  if (to.includes(ATTACHMENT))
297
306
  continue;
@@ -334,15 +343,9 @@ function guard(changes, input, removing) {
334
343
  const occupied = (path) => input.folders.has(path) ? path : (ancestors(path).find((one) => existing.has(one)) ?? null);
335
344
  for (const [index, change] of changes.entries()) {
336
345
  for (const path of affected(change)) {
337
- const normalized = normalize(path);
338
- if (normalized === null || normalized === '')
339
- return refuse('room-root', path);
340
- if (covered(input.providerOwnedPaths, normalized)) {
341
- return refuse('provider-owned-path', normalized);
342
- }
343
- for (const operation of change.kind === 'remove' ? removing : WRITE)
344
- if (!input.local && !covered(input.operations[operation], normalized))
345
- return refuse(`${operation}-grant`, normalized);
346
+ const refused = input.rule(path, change.kind === 'remove' ? removing : WRITE);
347
+ if (refused !== null)
348
+ return refuse(refused.code, refused.path);
346
349
  }
347
350
  if (change.kind === 'create' || change.kind === 'arrival') {
348
351
  const taken = existing.has(change.path) ? change.path : occupied(change.path);
@@ -403,9 +406,9 @@ function guard(changes, input, removing) {
403
406
  return null;
404
407
  }
405
408
  function unrevised(input, path) {
406
- return (!input.local && input.queued?.has(path) !== true && input.visible.revisions[path] === undefined);
409
+ return !input.local && !input.queued.has(path) && input.visible.revisions[path] === undefined;
407
410
  }
408
- export function queuedDocuments(queue) {
411
+ function queuedDocuments(queue) {
409
412
  const paths = new Set();
410
413
  for (const batch of queue) {
411
414
  for (const change of batch.changes) {
@@ -541,19 +544,16 @@ function* exceeding(limits, changes, effective, resulting) {
541
544
  function shellRelative(text, path, handle, definition) {
542
545
  if (!text.includes(`/rooms/${handle}/`))
543
546
  return null;
544
- const parsed = parse(text, path);
547
+ const parsed = parse(text, path, definition);
545
548
  if (!parsed.ok)
546
549
  return null;
547
550
  const result = relativize(parsed.document, path, handle, definition(parsed.document.type));
548
551
  return result.outcome === 'applied' && result.document.content !== text ? result.document : null;
549
552
  }
550
553
  function relativeField(path, name, value, handle, definition) {
551
- const opened = parse('---\n---\n');
552
- if (definition === undefined ||
553
- !opened.ok ||
554
- !JSON.stringify(value ?? null).includes(`/rooms/${handle}/`))
554
+ if (definition === undefined || !JSON.stringify(value ?? null).includes(`/rooms/${handle}/`))
555
555
  return value;
556
- const held = apply(opened.document, [{ kind: 'field', name, value, prior: undefined }]);
556
+ const held = apply(create(definition.name, definition), [{ kind: 'field', name, value, prior: undefined }], definition);
557
557
  if (held.outcome !== 'applied')
558
558
  return value;
559
559
  const result = relativize(held.document, path, handle, definition);
@@ -561,7 +561,7 @@ function relativeField(path, name, value, handle, definition) {
561
561
  }
562
562
  function relativeChanges(input) {
563
563
  const { handle, composition, visible } = input;
564
- const typed = (path) => (type) => definitionOf(governing(composition, path), type);
564
+ const typed = (path) => definitionsAt(composition, path);
565
565
  const body = (path, text) => shellRelative(text, path, handle, () => undefined)?.content ?? text;
566
566
  return input.changes.map((change) => {
567
567
  const definition = typed(change.path);
@@ -590,7 +590,7 @@ function relativeChanges(input) {
590
590
  });
591
591
  }
592
592
  function unqueueable(file) {
593
- return { kind: 'refused', refusal: { code: 'unknown-revision', retryable: false, file } };
593
+ return refuse('unknown-revision', file);
594
594
  }
595
595
  function isPart(change) {
596
596
  return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
@@ -598,8 +598,9 @@ function isPart(change) {
598
598
  function touched(change) {
599
599
  return change.kind === 'move' ? [change.path, change.to] : [change.path];
600
600
  }
601
- function partsApplied(content, path, changes) {
602
- const parsed = parse(content, path);
601
+ function partsApplied(content, path, changes, composition) {
602
+ const definitions = definitionsAt(composition, path);
603
+ const parsed = parse(content, path, definitions);
603
604
  if (!parsed.ok)
604
605
  return null;
605
606
  const document = parsed.document;
@@ -622,12 +623,12 @@ function partsApplied(content, path, changes) {
622
623
  else
623
624
  parts.set('preamble', { kind: 'preamble', value: change.value, prior: document.preamble });
624
625
  }
625
- const applied = apply(document, [...parts.values()]);
626
+ const applied = apply(document, [...parts.values()], definitions(document.type));
626
627
  return applied.outcome === 'applied' ? serialize(applied.document) : null;
627
628
  }
628
- function settledParts(changes, deferred) {
629
+ function settledParts(changes, deferred, composition) {
629
630
  for (const [held, parts] of deferred) {
630
- const content = partsApplied(held.content, held.path, parts);
631
+ const content = partsApplied(held.content, held.path, parts, composition);
631
632
  if (content === null)
632
633
  return held.path;
633
634
  changes[changes.indexOf(held)] = { ...held, content };
@@ -702,7 +703,9 @@ function* relinked(batch, move, before, after, appending) {
702
703
  for (const change of derived.changes) {
703
704
  if (change === move)
704
705
  continue;
705
- const unsettled = isPart(change) ? null : settledParts(changes, deferred);
706
+ const unsettled = isPart(change)
707
+ ? null
708
+ : settledParts(changes, deferred, after.collection.composition);
706
709
  if (unsettled !== null)
707
710
  return unqueueable(unsettled);
708
711
  const outcome = folded(changes, change, appending, deferred);
@@ -713,7 +716,7 @@ function* relinked(batch, move, before, after, appending) {
713
716
  if (outcome !== 'skipped')
714
717
  changed = true;
715
718
  }
716
- const unsettled = settledParts(changes, deferred);
719
+ const unsettled = settledParts(changes, deferred, after.collection.composition);
717
720
  if (unsettled !== null)
718
721
  return unqueueable(unsettled);
719
722
  if (!changed)
@@ -774,11 +777,10 @@ function withdrawnFile(batch, change, at) {
774
777
  ];
775
778
  return immutable({ ...batch, id: changeBatchIdentity(), changes, preconditions });
776
779
  }
777
- export function* requeuing(queue, changes, visible, changeable, state) {
780
+ function* requeuing(queue, changes, visible, changeable, state) {
778
781
  const next = [...queue];
779
782
  const origins = new Map();
780
783
  const withdrawn = new Map();
781
- const owners = new Set();
782
784
  const queued = new Set();
783
785
  const kept = [];
784
786
  const originOf = (batch) => origins.get(batch) ?? batch.id;
@@ -824,7 +826,6 @@ export function* requeuing(queue, changes, visible, changeable, state) {
824
826
  if (replaced !== null)
825
827
  origins.set(replaced, origin);
826
828
  }
827
- owners.add(originOf(owner));
828
829
  next.splice(index, following.length, ...rebuilt.filter((batch) => batch !== null));
829
830
  queued.add(change.path);
830
831
  }
@@ -834,56 +835,13 @@ export function* requeuing(queue, changes, visible, changeable, state) {
834
835
  changes: kept,
835
836
  queued,
836
837
  withdrawn,
837
- owners,
838
838
  };
839
839
  }
840
- function covering(precondition) {
841
- return precondition.kind === 'field' ||
842
- precondition.kind === 'section' ||
843
- precondition.kind === 'preamble'
844
- ? identity(precondition)
845
- : `path ${precondition.path}`;
846
- }
847
- export function joined(queue, owner, extra) {
848
- const later = new Set(queue.slice(queue.indexOf(owner) + 1).flatMap((batch) => batch.changes.flatMap(touched)));
849
- const clash = extra.changes.flatMap(touched).find((path) => later.has(path));
850
- if (clash !== undefined)
851
- return unqueueable(clash);
852
- const changes = [...owner.changes];
853
- const deferred = new Map();
854
- for (const change of extra.changes) {
855
- const unsettled = isPart(change) ? null : settledParts(changes, deferred);
856
- if (unsettled !== null)
857
- return unqueueable(unsettled);
858
- if (folded(changes, change, true, deferred) === 'refused')
859
- return unqueueable(change.path);
860
- }
861
- const unsettled = settledParts(changes, deferred);
862
- if (unsettled !== null)
863
- return unqueueable(unsettled);
864
- const held = new Set(owner.preconditions.map(covering));
865
- const written = new Set(owner.changes.flatMap((change) => change.kind === 'create' || change.kind === 'replace' ? [change.path] : []));
866
- const preconditions = [
867
- ...owner.preconditions,
868
- ...extra.preconditions.filter((precondition) => {
869
- const key = covering(precondition);
870
- return (!held.has(key) && (key === `path ${precondition.path}` || !written.has(precondition.path)));
871
- }),
872
- ];
873
- const batch = immutable({
874
- ...owner,
875
- ...(extra.validation === undefined ? {} : { validation: extra.validation }),
876
- id: changeBatchIdentity(),
877
- changes,
878
- preconditions,
879
- });
880
- return { kind: 'joined', batch, queue: queue.map((item) => (item === owner ? batch : item)) };
881
- }
882
- export function* limiting(queue, batch, limits, state) {
840
+ function* limiting(queue, batch, limits, state) {
883
841
  const at = queue.indexOf(batch);
884
842
  const rewritten = yield* providerRewritten(batch, yield* state(queue.slice(0, at)));
885
843
  const limited = yield* exceeding(limits, batch.changes, rewritten.changes, yield* state(queue.slice(0, at + 1)));
886
- return limited?.kind === 'refused' ? limited.refusal : null;
844
+ return limited?.refusal ?? null;
887
845
  }
888
846
  function typedText(content) {
889
847
  if (content === undefined)
@@ -900,7 +858,7 @@ function touchedLibrary(resulting, touched, composition) {
900
858
  })
901
859
  .sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));
902
860
  const contents = new Map(entries.map(({ path, content }) => [path, content]));
903
- const binaries = new Set(Object.keys(resulting.binaries).filter((path) => resulting.binaries[path] !== undefined));
861
+ const binaries = new Set(Array.from(entriesIn(resulting.binaries), ([path]) => path));
904
862
  return validatedCollection(() => Promise.resolve({ entries, next: null }), async (paths) => {
905
863
  const known = new Map();
906
864
  const pace = paced();
@@ -909,7 +867,7 @@ function touchedLibrary(resulting, touched, composition) {
909
867
  if (binaries.has(path))
910
868
  known.set(path, { type: undefined, binary: true });
911
869
  else if (content !== undefined && content !== null) {
912
- const read = parse(content, path);
870
+ const read = parse(content, path, definitionsAt(composition, path));
913
871
  if (read.ok)
914
872
  known.set(path, { type: read.document.type ?? 'any', binary: false });
915
873
  await pace(content.length + ROW_WEIGHT);
@@ -973,10 +931,11 @@ function placed(reference) {
973
931
  function roomReferencesIn(path, content, composition) {
974
932
  if (content === undefined)
975
933
  return [];
976
- const parsed = parse(content, path);
934
+ const definitions = definitionsAt(composition, path);
935
+ const parsed = parse(content, path, definitions);
977
936
  if (!parsed.ok)
978
937
  return [];
979
- return roomReferences(parsed.document, definitionOf(governing(composition, path), parsed.document.type));
938
+ return roomReferences(parsed.document, definitions(parsed.document.type));
980
939
  }
981
940
  function* admittedRooms(changes, visible, resulting, composition) {
982
941
  const from = new Map();
@@ -1027,7 +986,7 @@ async function batching(input) {
1027
986
  return refusal;
1028
987
  const preconditions = await stepped(preconditionsOf(changes, input.visible, input.bases));
1029
988
  const predicted = await stepped(anticipated(changes, preconditions, rewritten.changes, input.visible));
1030
- const resulting = await stepped(overlaying(input.visible, [{ id: '', baseRoomVersion: input.baseRoomVersion, ...predicted }]));
989
+ const resulting = await stepped(overlaying(input.visible, [{ id: '', baseRoomVersion: input.baseRoomVersion, ...predicted }], input.composition));
1031
990
  const judged = await judging(input.visible, resulting, input.composition, input.validate, new Set(changes.filter((change) => change.kind === 'remove').map((change) => change.path)), [...new Set(predicted.changes.flatMap(affected))]);
1032
991
  if (judged.kind === 'refused')
1033
992
  return judged;
@@ -1049,7 +1008,7 @@ async function batching(input) {
1049
1008
  }),
1050
1009
  };
1051
1010
  }
1052
- export const MOVE_DOCUMENTS = 'move-documents';
1011
+ const MOVE_DOCUMENTS = 'move-documents';
1053
1012
  function heldAt(visible, path) {
1054
1013
  return visible.documents[path] !== undefined || visible.binaries[path] !== undefined;
1055
1014
  }
@@ -1058,7 +1017,7 @@ function arrivingText(path, to, source, moved) {
1058
1017
  const document = source.visible.collection.document(path);
1059
1018
  if (document === undefined)
1060
1019
  return content;
1061
- const definition = definitionOf(governing(source.composition, path), document.type);
1020
+ const definition = definitionsAt(source.composition, path)(document.type);
1062
1021
  const changes = crossed(document, definition, path, (named, href) => {
1063
1022
  const at = moved.get(named);
1064
1023
  if (at !== undefined)
@@ -1067,7 +1026,7 @@ function arrivingText(path, to, source, moved) {
1067
1026
  });
1068
1027
  if (changes.length === 0)
1069
1028
  return content;
1070
- const applied = apply(document, changes);
1029
+ const applied = apply(document, changes, definition);
1071
1030
  return applied.outcome === 'applied' ? serialize(applied.document) : content;
1072
1031
  }
1073
1032
  function arrivalOf({ path, to }, source, moved) {
@@ -1101,8 +1060,6 @@ function arrivalOf({ path, to }, source, moved) {
1101
1060
  }
1102
1061
  async function moving(input) {
1103
1062
  const { source, destination, moves } = input;
1104
- if (moves.length === 0)
1105
- return refuse('no-change');
1106
1063
  const removals = moves.map(({ path }) => ({ kind: 'remove', path }));
1107
1064
  const leaves = guard(removals, { ...source, local: input.local, bases: [] }, MOVE_OUT);
1108
1065
  if (leaves !== null)
@@ -1141,7 +1098,7 @@ async function moving(input) {
1141
1098
  between,
1142
1099
  };
1143
1100
  const effective = await stepped(leavingRewritten(leavingBatch, source.visible));
1144
- const left = await stepped(overlaying(source.visible, [effective]));
1101
+ const left = await stepped(overlaying(source.visible, [effective], source.composition));
1145
1102
  const sourceJudged = await judging(source.visible, left, source.composition, source.validate, new Set(moves.map(({ path }) => path)), [...new Set(effective.changes.map((change) => change.path))]);
1146
1103
  if (sourceJudged.kind === 'refused')
1147
1104
  return sourceJudged;
@@ -1153,7 +1110,7 @@ async function moving(input) {
1153
1110
  ...written,
1154
1111
  between,
1155
1112
  };
1156
- const arrived = await stepped(overlaying(destination.visible, [arrivingBatch]));
1113
+ const arrived = await stepped(overlaying(destination.visible, [arrivingBatch], destination.composition));
1157
1114
  const destinationJudged = await judging(destination.visible, arrived, destination.composition, destination.validate, new Set(), moves.map(({ to }) => to));
1158
1115
  if (destinationJudged.kind === 'refused')
1159
1116
  return destinationJudged;
@@ -1163,9 +1120,172 @@ async function moving(input) {
1163
1120
  return limited;
1164
1121
  return { kind: 'moved', leaving: immutable(leavingBatch), arriving: immutable(arrivingBatch) };
1165
1122
  }
1166
- export function buildMove(input) {
1167
- return moving(input);
1123
+ function changedUnderneath(saved, visible) {
1124
+ const parts = saved.flatMap(({ path, parts: held }) => changedParts(path, held, visible));
1125
+ return parts.length === 0
1126
+ ? null
1127
+ : { kind: 'refused', refusal: { code: 'changed-underneath', retryable: false, parts } };
1128
+ }
1129
+ function sideOf(room, visible) {
1130
+ const { record } = room;
1131
+ return {
1132
+ room: record.locator,
1133
+ handle: record.declaration.handle,
1134
+ baseRoomVersion: record.roomVersion,
1135
+ composition: room.composition,
1136
+ rule: room.rule,
1137
+ visible,
1138
+ folders: room.folders,
1139
+ queued: queuedDocuments(room.queue),
1140
+ unmodeled: !room.modelled,
1141
+ validate: room.validate,
1142
+ };
1143
+ }
1144
+ function carriedDrafts(ask, from, into) {
1145
+ return new Map(ask.saved.flatMap(({ path, parts }) => {
1146
+ const record = from.drafts.get(path);
1147
+ if (parts.move === undefined || record === undefined || ask.consumed.has(path))
1148
+ return [];
1149
+ const to = moveTarget(parts.move);
1150
+ if (into.drafts.has(to))
1151
+ return [];
1152
+ const locator = into.record.locator;
1153
+ return [[path, { ...record, locator, path: to, revision: roomDraftRevision() }]];
1154
+ }));
1155
+ }
1156
+ async function plannedMove(ask, source, into) {
1157
+ const destination = into.record.locator;
1158
+ const mixed = ask.saved.find(({ parts }) => Object.keys(parts).length !== 1 || parts.move?.room !== destination);
1159
+ if (mixed !== undefined)
1160
+ return refuse('mixed-room-move', mixed.path);
1161
+ const leavingVisible = await stepped(source.replay(source.queue));
1162
+ const changed = changedUnderneath(ask.saved, leavingVisible);
1163
+ if (changed !== null)
1164
+ return changed;
1165
+ const moves = ask.saved.map(({ path, parts }) => ({ path, to: moveTarget(parts.move) }));
1166
+ const built = await moving({
1167
+ source: sideOf(source, leavingVisible),
1168
+ destination: sideOf(into, await stepped(into.replay(into.queue))),
1169
+ moves,
1170
+ providerLimits: ask.providerLimits,
1171
+ local: ask.local,
1172
+ ...(ask.writtenBy === undefined ? {} : { writtenBy: ask.writtenBy }),
1173
+ });
1174
+ if (built.kind === 'refused')
1175
+ return built;
1176
+ const { id } = built.leaving;
1177
+ const carried = carriedDrafts(ask, source, into);
1178
+ return {
1179
+ kind: 'planned',
1180
+ identifier: id,
1181
+ rooms: [
1182
+ {
1183
+ locator: source.record.locator,
1184
+ queue: [...source.queue, built.leaving],
1185
+ saved: new Map([[id, ask.saved]]),
1186
+ consumed: [...ask.consumed, ...carried.keys()],
1187
+ carried: [],
1188
+ },
1189
+ {
1190
+ locator: destination,
1191
+ queue: [...into.queue, built.arriving],
1192
+ saved: new Map([
1193
+ [id, [...carried.values()].map(({ path }) => ({ path, parts: {} }))],
1194
+ ]),
1195
+ consumed: [],
1196
+ carried: [...carried.values()],
1197
+ },
1198
+ ],
1199
+ };
1200
+ }
1201
+ async function plannedWithin(ask, room) {
1202
+ const { record } = room;
1203
+ const visible = await stepped(room.replay(room.queue));
1204
+ const changed = changedUnderneath(ask.saved, visible);
1205
+ if (changed !== null)
1206
+ return changed;
1207
+ const parts = ask.saved.map(({ path, parts: held }) => changesOf(path, held));
1208
+ const changes = parts.flatMap(({ changes: made }) => made);
1209
+ const requeue = await stepped(requeuing(room.queue, changes, visible, (batch) => room.changeable.has(batch.id), room.replay));
1210
+ if (requeue.kind === 'refused')
1211
+ return requeue;
1212
+ const foreign = [...requeue.withdrawn.keys()].some((origin) => {
1213
+ const writer = room.queue.find((batch) => batch.id === origin)?.writtenBy;
1214
+ return writer?.app !== ask.writtenBy?.app || writer?.release !== ask.writtenBy?.release;
1215
+ });
1216
+ if (foreign)
1217
+ return unqueueable([...requeue.queued].at(-1));
1218
+ const input = {
1219
+ local: ask.local,
1220
+ baseRoomVersion: record.roomVersion,
1221
+ composition: room.composition,
1222
+ rule: room.rule,
1223
+ providerLimits: ask.providerLimits,
1224
+ handle: record.declaration.handle,
1225
+ visible,
1226
+ folders: room.folders,
1227
+ changes,
1228
+ bases: parts.flatMap(({ bases }) => bases),
1229
+ queued: queuedDocuments(room.queue),
1230
+ writtenBy: ask.writtenBy,
1231
+ unmodeled: !room.modelled,
1232
+ validate: room.validate,
1233
+ };
1234
+ const rewritten = requeue.withdrawn.size > 0;
1235
+ if (rewritten) {
1236
+ const whole = await batching({
1237
+ ...input,
1238
+ providerLimits: [],
1239
+ queued: new Set([...input.queued, ...requeue.queued]),
1240
+ });
1241
+ if (whole.kind === 'refused')
1242
+ return whole;
1243
+ }
1244
+ const own = !rewritten
1245
+ ? await batching(input)
1246
+ : requeue.changes.length === 0
1247
+ ? null
1248
+ : await batching({
1249
+ ...input,
1250
+ visible: await stepped(room.replay(requeue.queue)),
1251
+ changes: requeue.changes,
1252
+ queued: queuedDocuments(requeue.queue),
1253
+ });
1254
+ if (own?.kind === 'refused')
1255
+ return own;
1256
+ const queue = own === null ? requeue.queue : [...requeue.queue, own.batch];
1257
+ const saved = new Map();
1258
+ for (const [origin, rebuilt] of requeue.withdrawn) {
1259
+ if (rebuilt === null)
1260
+ continue;
1261
+ const limited = await stepped(limiting(queue, rebuilt, ask.providerLimits, room.replay));
1262
+ if (limited !== null)
1263
+ return { kind: 'refused', refusal: limited };
1264
+ saved.set(rebuilt.id, withdrawnDrafts(room.saved.get(origin) ?? [], changes));
1265
+ }
1266
+ if (own !== null) {
1267
+ saved.set(own.batch.id, ask.saved.filter(({ path }) => !requeue.queued.has(path)));
1268
+ }
1269
+ const carried = carriedDrafts(ask, room, room);
1270
+ return {
1271
+ kind: 'planned',
1272
+ identifier: own?.batch.id ??
1273
+ [...requeue.withdrawn].map(([origin, rebuilt]) => rebuilt?.id ?? origin).at(-1),
1274
+ rooms: [
1275
+ {
1276
+ locator: record.locator,
1277
+ queue,
1278
+ saved,
1279
+ consumed: [...ask.consumed, ...carried.keys()],
1280
+ carried: [...carried.values()],
1281
+ },
1282
+ ],
1283
+ };
1284
+ }
1285
+ export function destination(locator, saved) {
1286
+ const into = saved.find(({ parts }) => parts.move?.room !== undefined && parts.move.room !== locator);
1287
+ return into?.parts.move?.room ?? null;
1168
1288
  }
1169
- export function buildBatch(input) {
1170
- return batching(input);
1289
+ export function planSave(ask, room, into) {
1290
+ return into === undefined ? plannedWithin(ask, room) : plannedMove(ask, room, into);
1171
1291
  }
@@ -0,0 +1,32 @@
1
+ import { type ChangeBatch, type WrittenBy } from './change.js';
2
+ import { type AttachAnswer, type BinaryLinkAnswer, type HeldBinaryAnswer, type HeldShownAnswer } from './outcome.js';
3
+ import { type RoomDraftParts } from './room-draft.js';
4
+ import type { Runtime } from './runtime.js';
5
+ import { type SaveRefusal } from './save.js';
6
+ import type { Store } from './store.js';
7
+ export type SaveResult = {
8
+ outcome: 'saved';
9
+ identifier: string;
10
+ } | ({
11
+ outcome: 'refused';
12
+ } & SaveRefusal);
13
+ export type SavedRoomDraft = {
14
+ readonly path: string;
15
+ readonly revision: string;
16
+ };
17
+ export type SavedParts = {
18
+ readonly path: string;
19
+ readonly parts: RoomDraftParts;
20
+ };
21
+ export type BinaryFileSurface = {
22
+ read(room: string, path: string, revision?: string): Promise<HeldBinaryAnswer>;
23
+ link(room: string, path: string, revision?: string): Promise<BinaryLinkAnswer>;
24
+ show(room: string, path: string, revision?: string): Promise<HeldShownAnswer>;
25
+ attach(room: string, file: File): Promise<AttachAnswer>;
26
+ part(file: string, part: number): Promise<Uint8Array | null>;
27
+ };
28
+ export declare function saveRoomDrafts(runtime: Runtime, locator: string, named: readonly SavedRoomDraft[], writtenBy: WrittenBy | undefined): Promise<SaveResult>;
29
+ export declare function saveParts(runtime: Runtime, locator: string, named: readonly SavedParts[], writtenBy: WrittenBy | undefined): Promise<SaveResult>;
30
+ export declare function batchFile(store: Store, batch: ChangeBatch): (localId: string) => Promise<Blob>;
31
+ export declare function binaryFileSurface(runtime: Runtime): BinaryFileSurface;
32
+ //# sourceMappingURL=saves.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saves.d.ts","sourceRoot":"","sources":["../src/saves.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxF,OAAO,EAQL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EAErB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAatB,OAAO,EAOL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAsB,KAAK,EAAoB,MAAM,YAAY,CAAC;AAK9E,MAAM,MAAM,UAAU,GAClB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxC,CAAC;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,GAAG,WAAW,CAAC,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAElF,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CAC9D,CAAC;AAYF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B,OAAO,CAAC,UAAU,CAAC,CAyBrB;AAiOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAK9F;AAkPD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAQrE"}