@agentshouse/mdruntime 0.1.0-c8ca66ac9e99d → 0.1.0-c8e865ef64c82

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 (380) hide show
  1. package/README.md +23 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +187 -97
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +6 -10
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +35 -41
  16. package/dist/binary.d.ts +0 -5
  17. package/dist/binary.d.ts.map +1 -1
  18. package/dist/binary.js +1 -1
  19. package/dist/bootstrap.d.ts +31 -11
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +311 -89
  22. package/dist/cell.d.ts +6 -0
  23. package/dist/cell.d.ts.map +1 -0
  24. package/dist/cell.js +9 -0
  25. package/dist/chain.d.ts +12 -0
  26. package/dist/chain.d.ts.map +1 -0
  27. package/dist/chain.js +64 -0
  28. package/dist/change-set.d.ts +13 -14
  29. package/dist/change-set.d.ts.map +1 -1
  30. package/dist/change-set.js +17 -63
  31. package/dist/change.d.ts +32 -1
  32. package/dist/change.d.ts.map +1 -1
  33. package/dist/change.js +14 -3
  34. package/dist/chat-types.d.ts +3 -0
  35. package/dist/chat-types.d.ts.map +1 -0
  36. package/dist/chat-types.js +11 -0
  37. package/dist/client.d.ts +48 -29
  38. package/dist/client.d.ts.map +1 -1
  39. package/dist/client.js +133 -28
  40. package/dist/collection.d.ts +31 -9
  41. package/dist/collection.d.ts.map +1 -1
  42. package/dist/collection.js +49 -80
  43. package/dist/compile.d.ts +18 -0
  44. package/dist/compile.d.ts.map +1 -0
  45. package/dist/compile.js +724 -0
  46. package/dist/connection.d.ts +8 -116
  47. package/dist/connection.d.ts.map +1 -1
  48. package/dist/connection.js +111 -2411
  49. package/dist/context.d.ts +2 -0
  50. package/dist/context.d.ts.map +1 -0
  51. package/dist/{chat/context.js → context.js} +1 -4
  52. package/dist/conversation-live.d.ts +147 -0
  53. package/dist/conversation-live.d.ts.map +1 -0
  54. package/dist/conversation-live.js +258 -0
  55. package/dist/conversation-row.d.ts +33 -0
  56. package/dist/conversation-row.d.ts.map +1 -0
  57. package/dist/conversation-row.js +53 -0
  58. package/dist/conversation.d.ts +83 -45
  59. package/dist/conversation.d.ts.map +1 -1
  60. package/dist/conversation.js +1105 -584
  61. package/dist/declaration.d.ts +10 -0
  62. package/dist/declaration.d.ts.map +1 -0
  63. package/dist/declaration.js +24 -0
  64. package/dist/digest.d.ts +7 -0
  65. package/dist/digest.d.ts.map +1 -0
  66. package/dist/digest.js +113 -0
  67. package/dist/discovery.d.ts +10 -0
  68. package/dist/discovery.d.ts.map +1 -0
  69. package/dist/discovery.js +150 -0
  70. package/dist/durability.d.ts +23 -1
  71. package/dist/durability.d.ts.map +1 -1
  72. package/dist/durability.js +9 -0
  73. package/dist/entry.d.ts +20 -0
  74. package/dist/entry.d.ts.map +1 -0
  75. package/dist/entry.js +161 -0
  76. package/dist/expectation.d.ts +26 -13
  77. package/dist/expectation.d.ts.map +1 -1
  78. package/dist/expectation.js +72 -19
  79. package/dist/failure.d.ts +3 -0
  80. package/dist/failure.d.ts.map +1 -1
  81. package/dist/failure.js +6 -0
  82. package/dist/figures.d.ts +49 -0
  83. package/dist/figures.d.ts.map +1 -0
  84. package/dist/figures.js +197 -0
  85. package/dist/file.d.ts +2 -19
  86. package/dist/file.d.ts.map +1 -1
  87. package/dist/file.js +8 -122
  88. package/dist/holdings.d.ts +29 -0
  89. package/dist/holdings.d.ts.map +1 -0
  90. package/dist/holdings.js +95 -0
  91. package/dist/host.d.ts +28 -3
  92. package/dist/host.d.ts.map +1 -1
  93. package/dist/host.js +170 -25
  94. package/dist/index.d.ts +41 -13
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +19 -2
  97. package/dist/install.d.ts +54 -0
  98. package/dist/install.d.ts.map +1 -0
  99. package/dist/install.js +530 -0
  100. package/dist/lifecycle.d.ts +7 -0
  101. package/dist/lifecycle.d.ts.map +1 -0
  102. package/dist/lifecycle.js +277 -0
  103. package/dist/listing.d.ts +48 -0
  104. package/dist/listing.d.ts.map +1 -0
  105. package/dist/listing.js +139 -0
  106. package/dist/live.d.ts +23 -0
  107. package/dist/live.d.ts.map +1 -0
  108. package/dist/live.js +165 -0
  109. package/dist/locks.d.ts +7 -0
  110. package/dist/locks.d.ts.map +1 -0
  111. package/dist/locks.js +32 -0
  112. package/dist/lost.d.ts +5 -0
  113. package/dist/lost.d.ts.map +1 -0
  114. package/dist/lost.js +49 -0
  115. package/dist/media.d.ts +8 -0
  116. package/dist/media.d.ts.map +1 -0
  117. package/dist/media.js +215 -0
  118. package/dist/memory.d.ts +24 -6
  119. package/dist/memory.d.ts.map +1 -1
  120. package/dist/memory.js +291 -101
  121. package/dist/messages.d.ts +56 -0
  122. package/dist/messages.d.ts.map +1 -0
  123. package/dist/messages.js +158 -0
  124. package/dist/model.d.ts +11 -12
  125. package/dist/model.d.ts.map +1 -1
  126. package/dist/model.js +7 -15
  127. package/dist/models.d.ts +10 -0
  128. package/dist/models.d.ts.map +1 -0
  129. package/dist/models.js +153 -0
  130. package/dist/name.d.ts +4 -0
  131. package/dist/name.d.ts.map +1 -0
  132. package/dist/name.js +122 -0
  133. package/dist/observation.d.ts +24 -5
  134. package/dist/observation.d.ts.map +1 -1
  135. package/dist/observation.js +135 -28
  136. package/dist/opened.d.ts +22 -0
  137. package/dist/opened.d.ts.map +1 -0
  138. package/dist/opened.js +107 -0
  139. package/dist/opening.d.ts +4 -0
  140. package/dist/opening.d.ts.map +1 -0
  141. package/dist/opening.js +53 -0
  142. package/dist/outcome.d.ts +60 -8
  143. package/dist/outcome.d.ts.map +1 -1
  144. package/dist/outcome.js +64 -0
  145. package/dist/overlay.d.ts +8 -4
  146. package/dist/overlay.d.ts.map +1 -1
  147. package/dist/overlay.js +136 -192
  148. package/dist/page-metadata.d.ts +8 -0
  149. package/dist/page-metadata.d.ts.map +1 -0
  150. package/dist/page-metadata.js +19 -0
  151. package/dist/parts.d.ts +4 -0
  152. package/dist/parts.d.ts.map +1 -0
  153. package/dist/parts.js +13 -0
  154. package/dist/paths.d.ts +2 -0
  155. package/dist/paths.d.ts.map +1 -1
  156. package/dist/paths.js +26 -0
  157. package/dist/preparation.d.ts +20 -0
  158. package/dist/preparation.d.ts.map +1 -0
  159. package/dist/preparation.js +227 -0
  160. package/dist/presence.d.ts +52 -0
  161. package/dist/presence.d.ts.map +1 -0
  162. package/dist/presence.js +220 -0
  163. package/dist/queries.d.ts +16 -0
  164. package/dist/queries.d.ts.map +1 -0
  165. package/dist/queries.js +282 -0
  166. package/dist/query.d.ts +49 -183
  167. package/dist/query.d.ts.map +1 -1
  168. package/dist/query.js +3 -464
  169. package/dist/{chat/questions.d.ts → questions.d.ts} +5 -7
  170. package/dist/questions.d.ts.map +1 -0
  171. package/dist/{chat/questions.js → questions.js} +11 -7
  172. package/dist/queue.d.ts +40 -0
  173. package/dist/queue.d.ts.map +1 -0
  174. package/dist/queue.js +450 -0
  175. package/dist/reach.d.ts +21 -7
  176. package/dist/reach.d.ts.map +1 -1
  177. package/dist/reach.js +343 -98
  178. package/dist/react.d.ts +23 -7
  179. package/dist/react.d.ts.map +1 -1
  180. package/dist/react.js +40 -18
  181. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  182. package/dist/read.d.ts.map +1 -0
  183. package/dist/{chat/read.js → read.js} +4 -0
  184. package/dist/readiness.d.ts +49 -0
  185. package/dist/readiness.d.ts.map +1 -0
  186. package/dist/readiness.js +27 -0
  187. package/dist/reads.d.ts +39 -0
  188. package/dist/reads.d.ts.map +1 -0
  189. package/dist/reads.js +178 -0
  190. package/dist/recovery.d.ts +28 -0
  191. package/dist/recovery.d.ts.map +1 -0
  192. package/dist/recovery.js +254 -0
  193. package/dist/refresh.d.ts +17 -14
  194. package/dist/refresh.d.ts.map +1 -1
  195. package/dist/refresh.js +145 -53
  196. package/dist/refusal.d.ts +5 -0
  197. package/dist/refusal.d.ts.map +1 -0
  198. package/dist/refusal.js +55 -0
  199. package/dist/replica.d.ts +50 -33
  200. package/dist/replica.d.ts.map +1 -1
  201. package/dist/replica.js +339 -162
  202. package/dist/retried.d.ts +30 -0
  203. package/dist/retried.d.ts.map +1 -0
  204. package/dist/retried.js +72 -0
  205. package/dist/room-draft.d.ts +39 -10
  206. package/dist/room-draft.d.ts.map +1 -1
  207. package/dist/room-draft.js +196 -120
  208. package/dist/room-drafts.d.ts +24 -0
  209. package/dist/room-drafts.d.ts.map +1 -0
  210. package/dist/room-drafts.js +217 -0
  211. package/dist/rows.d.ts +30 -37
  212. package/dist/rows.d.ts.map +1 -1
  213. package/dist/rows.js +60 -128
  214. package/dist/runtime.d.ts +34 -0
  215. package/dist/runtime.d.ts.map +1 -0
  216. package/dist/runtime.js +1 -0
  217. package/dist/save.d.ts +42 -43
  218. package/dist/save.d.ts.map +1 -1
  219. package/dist/save.js +800 -259
  220. package/dist/saves.d.ts +32 -0
  221. package/dist/saves.d.ts.map +1 -0
  222. package/dist/saves.js +410 -0
  223. package/dist/search.d.ts +15 -55
  224. package/dist/search.d.ts.map +1 -1
  225. package/dist/search.js +10 -121
  226. package/dist/seed.d.ts +25 -0
  227. package/dist/seed.d.ts.map +1 -0
  228. package/dist/seed.js +145 -0
  229. package/dist/shared.d.ts +10 -0
  230. package/dist/shared.d.ts.map +1 -0
  231. package/dist/shared.js +339 -0
  232. package/dist/shown.d.ts +33 -0
  233. package/dist/shown.d.ts.map +1 -0
  234. package/dist/shown.js +302 -0
  235. package/dist/socket/admission.d.ts +7 -0
  236. package/dist/socket/admission.d.ts.map +1 -0
  237. package/dist/socket/admission.js +39 -0
  238. package/dist/socket/answers.d.ts +6 -0
  239. package/dist/socket/answers.d.ts.map +1 -0
  240. package/dist/socket/answers.js +20 -0
  241. package/dist/socket/lanes.d.ts +28 -0
  242. package/dist/socket/lanes.d.ts.map +1 -0
  243. package/dist/socket/lanes.js +103 -0
  244. package/dist/socket/reads.d.ts +10 -0
  245. package/dist/socket/reads.d.ts.map +1 -0
  246. package/dist/socket/reads.js +31 -0
  247. package/dist/socket/session.d.ts +38 -0
  248. package/dist/socket/session.d.ts.map +1 -0
  249. package/dist/socket/session.js +23 -0
  250. package/dist/socket.d.ts +67 -0
  251. package/dist/socket.d.ts.map +1 -0
  252. package/dist/socket.js +164 -0
  253. package/dist/source.d.ts +54 -0
  254. package/dist/source.d.ts.map +1 -0
  255. package/dist/source.js +82 -0
  256. package/dist/status.d.ts +5 -2
  257. package/dist/status.d.ts.map +1 -1
  258. package/dist/status.js +3 -7
  259. package/dist/store/installs.d.ts +30 -0
  260. package/dist/store/installs.d.ts.map +1 -0
  261. package/dist/store/installs.js +34 -0
  262. package/dist/store/readiness.d.ts +10 -0
  263. package/dist/store/readiness.d.ts.map +1 -0
  264. package/dist/store/readiness.js +52 -0
  265. package/dist/store/records.d.ts +215 -0
  266. package/dist/store/records.d.ts.map +1 -0
  267. package/dist/store/records.js +439 -0
  268. package/dist/store/room-held.d.ts +8 -0
  269. package/dist/store/room-held.d.ts.map +1 -0
  270. package/dist/store/room-held.js +17 -0
  271. package/dist/store/space.d.ts +11 -0
  272. package/dist/store/space.d.ts.map +1 -0
  273. package/dist/store/space.js +41 -0
  274. package/dist/store/watchers.d.ts +17 -0
  275. package/dist/store/watchers.d.ts.map +1 -0
  276. package/dist/store/watchers.js +56 -0
  277. package/dist/store/writes.d.ts +24 -0
  278. package/dist/store/writes.d.ts.map +1 -0
  279. package/dist/store/writes.js +125 -0
  280. package/dist/store.d.ts +111 -119
  281. package/dist/store.d.ts.map +1 -1
  282. package/dist/store.js +158 -522
  283. package/dist/stored.d.ts +157 -0
  284. package/dist/stored.d.ts.map +1 -0
  285. package/dist/stored.js +649 -0
  286. package/dist/surface.d.ts +89 -0
  287. package/dist/surface.d.ts.map +1 -0
  288. package/dist/surface.js +222 -0
  289. package/dist/sync.d.ts +19 -0
  290. package/dist/sync.d.ts.map +1 -0
  291. package/dist/sync.js +535 -0
  292. package/dist/tables.d.ts +415 -0
  293. package/dist/tables.d.ts.map +1 -0
  294. package/dist/tables.js +761 -0
  295. package/dist/tallies.d.ts +18 -0
  296. package/dist/tallies.d.ts.map +1 -0
  297. package/dist/tallies.js +128 -0
  298. package/dist/transfer.d.ts +0 -5
  299. package/dist/transfer.d.ts.map +1 -1
  300. package/dist/turn.d.ts +9 -0
  301. package/dist/turn.d.ts.map +1 -0
  302. package/dist/turn.js +75 -0
  303. package/dist/validation.d.ts +29 -0
  304. package/dist/validation.d.ts.map +1 -0
  305. package/dist/validation.js +104 -0
  306. package/dist/windows.d.ts +11 -0
  307. package/dist/windows.d.ts.map +1 -0
  308. package/dist/windows.js +16 -0
  309. package/dist/wire.d.ts +229 -36
  310. package/dist/wire.d.ts.map +1 -1
  311. package/dist/wire.js +76 -33
  312. package/package.json +23 -19
  313. package/AGENTS.md +0 -299
  314. package/dist/attempt.d.ts +0 -16
  315. package/dist/attempt.d.ts.map +0 -1
  316. package/dist/attempt.js +0 -70
  317. package/dist/chat/acts.d.ts +0 -34
  318. package/dist/chat/acts.d.ts.map +0 -1
  319. package/dist/chat/acts.js +0 -36
  320. package/dist/chat/context.d.ts +0 -3
  321. package/dist/chat/context.d.ts.map +0 -1
  322. package/dist/chat/input.d.ts +0 -9
  323. package/dist/chat/input.d.ts.map +0 -1
  324. package/dist/chat/input.js +0 -99
  325. package/dist/chat/kit.d.ts +0 -60
  326. package/dist/chat/kit.d.ts.map +0 -1
  327. package/dist/chat/kit.js +0 -123
  328. package/dist/chat/lasting.d.ts +0 -6
  329. package/dist/chat/lasting.d.ts.map +0 -1
  330. package/dist/chat/lasting.js +0 -19
  331. package/dist/chat/list.d.ts +0 -26
  332. package/dist/chat/list.d.ts.map +0 -1
  333. package/dist/chat/list.js +0 -62
  334. package/dist/chat/markdown.d.ts +0 -20
  335. package/dist/chat/markdown.d.ts.map +0 -1
  336. package/dist/chat/markdown.js +0 -188
  337. package/dist/chat/message.d.ts +0 -6
  338. package/dist/chat/message.d.ts.map +0 -1
  339. package/dist/chat/message.js +0 -192
  340. package/dist/chat/messages.d.ts +0 -21
  341. package/dist/chat/messages.d.ts.map +0 -1
  342. package/dist/chat/messages.js +0 -151
  343. package/dist/chat/name.d.ts +0 -6
  344. package/dist/chat/name.d.ts.map +0 -1
  345. package/dist/chat/name.js +0 -37
  346. package/dist/chat/opened.d.ts +0 -11
  347. package/dist/chat/opened.d.ts.map +0 -1
  348. package/dist/chat/opened.js +0 -17
  349. package/dist/chat/overlay.d.ts +0 -31
  350. package/dist/chat/overlay.d.ts.map +0 -1
  351. package/dist/chat/overlay.js +0 -97
  352. package/dist/chat/parts.d.ts +0 -57
  353. package/dist/chat/parts.d.ts.map +0 -1
  354. package/dist/chat/parts.js +0 -119
  355. package/dist/chat/process.d.ts +0 -20
  356. package/dist/chat/process.d.ts.map +0 -1
  357. package/dist/chat/process.js +0 -32
  358. package/dist/chat/provider.d.ts +0 -63
  359. package/dist/chat/provider.d.ts.map +0 -1
  360. package/dist/chat/provider.js +0 -645
  361. package/dist/chat/question.d.ts +0 -9
  362. package/dist/chat/question.d.ts.map +0 -1
  363. package/dist/chat/question.js +0 -80
  364. package/dist/chat/questions.d.ts.map +0 -1
  365. package/dist/chat/read.d.ts.map +0 -1
  366. package/dist/chat/ready.d.ts +0 -33
  367. package/dist/chat/ready.d.ts.map +0 -1
  368. package/dist/chat/ready.js +0 -91
  369. package/dist/chat/style.d.ts +0 -4
  370. package/dist/chat/style.d.ts.map +0 -1
  371. package/dist/chat/style.js +0 -302
  372. package/dist/chat.d.ts +0 -14
  373. package/dist/chat.d.ts.map +0 -1
  374. package/dist/chat.js +0 -8
  375. package/dist/log.d.ts +0 -5
  376. package/dist/log.d.ts.map +0 -1
  377. package/dist/log.js +0 -14
  378. package/dist/read-side.d.ts +0 -18
  379. package/dist/read-side.d.ts.map +0 -1
  380. package/dist/read-side.js +0 -440
@@ -1,60 +1,70 @@
1
- import { apply, equalValue, frontmatterValue, parse, serialize } from '@agentshouse/mdmodel';
1
+ import { apply, create, equalValue, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
2
+ import { governing } from './collection.js';
2
3
  import { runtimeError } from './failure.js';
3
- import { hexDigest } from './file.js';
4
+ import { sha256 } from './digest.js';
5
+ import { declaredType } from './outcome.js';
4
6
  import { binaryLocalId } from './identity.js';
5
7
  import { normalize } from './paths.js';
6
- export function returnedBy(kind) {
7
- return { kind, code: kind, fields: {}, retryable: false };
8
+ export function returnedBy() {
9
+ return { kind: 'withdrawn', code: 'withdrawn', fields: {}, retryable: false };
8
10
  }
9
11
  export function staleWrite(current) {
10
- return { outcome: 'stale', code: 'stale', retryable: false, current };
12
+ return { outcome: 'stale', current };
11
13
  }
12
- function malformed() {
13
- throw runtimeError('room-draft-malformed');
14
+ function malformed(at, needs) {
15
+ throw runtimeError('room-draft-malformed', at === undefined ? 'room-draft-malformed' : `room-draft-malformed at ${at}: ${needs}`);
14
16
  }
15
17
  function plain(value) {
16
18
  return typeof value === 'object' && value !== null && !Array.isArray(value);
17
19
  }
18
- function text(value) {
19
- return typeof value === 'string' ? value : malformed();
20
+ function text(value, at) {
21
+ return typeof value === 'string' ? value : malformed(at, 'text');
20
22
  }
21
- function optionalText(value) {
22
- return value === undefined ? undefined : text(value);
23
+ function optionalText(value, at) {
24
+ return value === undefined ? undefined : text(value, at);
23
25
  }
24
- function markdownBase(value) {
25
- return value === null ? null : optionalText(value);
26
+ function markdownBase(value, at) {
27
+ return value === null ? null : optionalText(value, at);
26
28
  }
27
- function entries(value, each) {
29
+ function entries(value, at, each) {
28
30
  if (!plain(value))
29
- malformed();
31
+ malformed(at, 'an object of named values');
30
32
  const read = {};
31
33
  for (const [name, item] of Object.entries(value))
32
- read[name] = each(item);
34
+ read[name] = each(item, `${at}.${name}`);
33
35
  return read;
34
36
  }
35
- function fieldValue(value) {
37
+ function frontmatter(item, at) {
38
+ return frontmatterValue(item) ? item : malformed(at, 'a frontmatter value');
39
+ }
40
+ function fieldValue(value, at) {
36
41
  if (value === null)
37
42
  return null;
38
43
  if (!plain(value) || !Object.hasOwn(value, 'value') || !frontmatterValue(value.value)) {
39
- malformed();
44
+ malformed(at, '{ value } with a frontmatter value, or null where the document lacks it');
40
45
  }
41
46
  return { value: value.value };
42
47
  }
43
- function textPart(value) {
48
+ function textPart(value, at) {
44
49
  if (!plain(value))
45
- malformed();
46
- const base = optionalText(value.base);
47
- return { value: text(value.value), ...(base === undefined ? {} : { base }) };
50
+ malformed(at, '{ value, base }');
51
+ const base = optionalText(value.base, `${at}.base`);
52
+ return { value: text(value.value, `${at}.value`), ...(base === undefined ? {} : { base }) };
48
53
  }
49
- function creationOf(value) {
54
+ function creationOf(value, at) {
50
55
  if (!plain(value))
51
- malformed();
56
+ malformed(at, '{ type, fields, sections }, or { markdown }');
52
57
  if (Object.hasOwn(value, 'markdown'))
53
- return { markdown: text(value.markdown) };
54
- const fields = entries(value.fields, (item) => (frontmatterValue(item) ? item : malformed()));
55
- return { type: text(value.type), fields, sections: entries(value.sections, text) };
58
+ return { markdown: text(value.markdown, `${at}.markdown`) };
59
+ if (typeof value.type !== 'string')
60
+ malformed(`${at}.type`, 'a type name, or markdown in place of type, fields and sections');
61
+ return {
62
+ type: value.type,
63
+ fields: entries(value.fields, `${at}.fields`, frontmatter),
64
+ sections: entries(value.sections, `${at}.sections`, text),
65
+ };
56
66
  }
57
- const PART_NAMES = new Set([
67
+ const PART_NAMES = [
58
68
  'fields',
59
69
  'sections',
60
70
  'preamble',
@@ -63,47 +73,57 @@ const PART_NAMES = new Set([
63
73
  'move',
64
74
  'removal',
65
75
  'file',
66
- ]);
67
- export function readParts(value) {
68
- if (!plain(value) || Object.keys(value).some((name) => !PART_NAMES.has(name)))
69
- malformed();
76
+ ];
77
+ const NAMED_PARTS = `a part named ${PART_NAMES.slice(0, -1).join(', ')} or ${PART_NAMES.slice(-1).join('')}`;
78
+ export function readParts(value, path) {
79
+ if (!plain(value))
80
+ malformed(path, 'an object of parts');
81
+ const unknown = Object.keys(value).find((name) => !PART_NAMES.includes(name));
82
+ if (unknown !== undefined)
83
+ malformed(`${path} ${unknown}`, NAMED_PARTS);
70
84
  const parts = {};
71
85
  if (value.fields !== undefined) {
72
- parts.fields = entries(value.fields, (item) => {
86
+ parts.fields = entries(value.fields, `${path} fields`, (item, at) => {
73
87
  if (!plain(item) || !Object.hasOwn(item, 'value') || !frontmatterValue(item.value)) {
74
- malformed();
88
+ malformed(at, '{ value, base } with a frontmatter value');
75
89
  }
76
90
  return item.base === undefined
77
91
  ? { value: item.value }
78
- : { value: item.value, base: fieldValue(item.base) };
92
+ : { value: item.value, base: fieldValue(item.base, `${at}.base`) };
79
93
  });
80
94
  }
81
95
  if (value.sections !== undefined)
82
- parts.sections = entries(value.sections, textPart);
96
+ parts.sections = entries(value.sections, `${path} sections`, textPart);
83
97
  if (value.preamble !== undefined)
84
- parts.preamble = textPart(value.preamble);
98
+ parts.preamble = textPart(value.preamble, `${path} preamble`);
85
99
  if (value.markdown !== undefined)
86
- parts.markdown = textPart(value.markdown);
100
+ parts.markdown = textPart(value.markdown, `${path} markdown`);
87
101
  if (value.creation !== undefined)
88
- parts.creation = creationOf(value.creation);
102
+ parts.creation = creationOf(value.creation, `${path} creation`);
89
103
  if (value.move !== undefined) {
90
104
  if (!plain(value.move))
91
- malformed();
92
- const base = markdownBase(value.move.base);
93
- parts.move = { to: text(value.move.to), ...(base === undefined ? {} : { base }) };
105
+ malformed(`${path} move`, '{ to, room, base }');
106
+ const base = markdownBase(value.move.base, `${path} move.base`);
107
+ const room = optionalText(value.move.room, `${path} move.room`);
108
+ parts.move = {
109
+ to: text(value.move.to, `${path} move.to`),
110
+ ...(room === undefined ? {} : { room }),
111
+ ...(base === undefined ? {} : { base }),
112
+ };
94
113
  }
95
114
  if (value.removal !== undefined) {
96
115
  if (!plain(value.removal))
97
- malformed();
98
- const base = markdownBase(value.removal.base);
116
+ malformed(`${path} removal`, '{ base }');
117
+ const base = markdownBase(value.removal.base, `${path} removal.base`);
99
118
  parts.removal = base === undefined ? {} : { base };
100
119
  }
101
120
  if (value.file !== undefined) {
102
121
  if (!plain(value.file) || !(value.file.blob instanceof Blob))
103
- malformed();
122
+ malformed(`${path} file`, '{ blob, base } with a Blob');
104
123
  if (Object.keys(value).length > 1)
105
124
  throw runtimeError('room-draft-file-exclusive');
106
- parts.file = { blob: value.file.blob };
125
+ const base = markdownBase(value.file.base, `${path} file.base`);
126
+ parts.file = base === undefined ? { blob: value.file.blob } : { blob: value.file.blob, base };
107
127
  }
108
128
  return parts;
109
129
  }
@@ -120,11 +140,51 @@ function kept(prior, base) {
120
140
  throw runtimeError('room-draft-base-missing');
121
141
  return base;
122
142
  }
143
+ function movePart(current, move) {
144
+ return {
145
+ to: move.to,
146
+ ...(move.room === undefined ? {} : { room: move.room }),
147
+ base: kept(current, move.base),
148
+ };
149
+ }
123
150
  function editsText(parts) {
124
151
  return (parts.preamble !== undefined ||
125
152
  named(parts.fields).length > 0 ||
126
153
  named(parts.sections).length > 0);
127
154
  }
155
+ function partNames(parts) {
156
+ const names = [];
157
+ for (const [name, part] of Object.entries(parts)) {
158
+ if (name === 'preamble' || name === 'markdown')
159
+ names.push(name);
160
+ else if ((name === 'fields' || name === 'sections') && plain(part))
161
+ names.push(...Object.keys(part).map((one) => `${name}/${one}`));
162
+ else
163
+ return null;
164
+ }
165
+ return names.sort().join('\u0000');
166
+ }
167
+ function withBaseOf(prior, part) {
168
+ return plain(part) && plain(prior) && Object.hasOwn(prior, 'base')
169
+ ? { ...part, base: prior.base }
170
+ : part;
171
+ }
172
+ export function gatheredParts(earlier, later) {
173
+ if (!plain(earlier) || !plain(later))
174
+ return null;
175
+ const named = partNames(earlier);
176
+ if (named === null || named !== partNames(later))
177
+ return null;
178
+ return Object.fromEntries(Object.entries(later).map(([name, part]) => [
179
+ name,
180
+ name === 'fields' || name === 'sections'
181
+ ? Object.fromEntries(Object.entries(part).map(([one, value]) => [
182
+ one,
183
+ withBaseOf(earlier[name][one], value),
184
+ ]))
185
+ : withBaseOf(earlier[name], part),
186
+ ]));
187
+ }
128
188
  export function held(current, parts, file) {
129
189
  if (parts.markdown !== undefined && editsText(parts)) {
130
190
  throw runtimeError('room-draft-markdown-exclusive');
@@ -144,9 +204,7 @@ export function held(current, parts, file) {
144
204
  }
145
205
  return {
146
206
  file: current.file,
147
- ...(parts.move === undefined
148
- ? {}
149
- : { move: { to: parts.move.to, base: kept(current.move, parts.move.base) } }),
207
+ ...(parts.move === undefined ? {} : { move: movePart(current.move, parts.move) }),
150
208
  ...(parts.removal === undefined
151
209
  ? {}
152
210
  : { removal: { base: kept(current.removal, parts.removal.base) } }),
@@ -181,9 +239,8 @@ export function held(current, parts, file) {
181
239
  }
182
240
  if (parts.creation !== undefined)
183
241
  next.creation = parts.creation;
184
- if (parts.move !== undefined) {
185
- next.move = { to: parts.move.to, base: kept(current?.move, parts.move.base) };
186
- }
242
+ if (parts.move !== undefined)
243
+ next.move = movePart(current?.move, parts.move);
187
244
  if (parts.removal !== undefined) {
188
245
  next.removal = { base: kept(current?.removal, parts.removal.base) };
189
246
  }
@@ -200,8 +257,10 @@ export function underneath(parts, path, visible) {
200
257
  const markdown = visible?.documents[path] ?? null;
201
258
  const document = visible?.collection.document(path);
202
259
  const report = {};
260
+ const unread = document?.type !== undefined &&
261
+ governing(visible.collection.composition, path).status === 'unavailable';
203
262
  const fields = {};
204
- for (const [name, part] of named(parts.fields)) {
263
+ for (const [name, part] of unread ? [] : named(parts.fields)) {
205
264
  const current = document !== undefined && Object.hasOwn(document.fields, name)
206
265
  ? { value: document.fields[name] }
207
266
  : null;
@@ -211,7 +270,7 @@ export function underneath(parts, path, visible) {
211
270
  if (Object.keys(fields).length > 0)
212
271
  report.fields = fields;
213
272
  const sections = {};
214
- for (const [name, part] of named(parts.sections)) {
273
+ for (const [name, part] of unread ? [] : named(parts.sections)) {
215
274
  const current = document !== undefined && Object.hasOwn(document.sections, name)
216
275
  ? document.sections[name]
217
276
  : null;
@@ -221,8 +280,9 @@ export function underneath(parts, path, visible) {
221
280
  if (Object.keys(sections).length > 0)
222
281
  report.sections = sections;
223
282
  const preamble = document?.preamble ?? null;
224
- if (parts.preamble !== undefined && preamble !== parts.preamble.base)
283
+ if (!unread && parts.preamble !== undefined && preamble !== parts.preamble.base) {
225
284
  report.preamble = preamble;
285
+ }
226
286
  if (parts.markdown !== undefined && markdown !== parts.markdown.base)
227
287
  report.markdown = markdown;
228
288
  if (parts.creation !== undefined && markdown !== null)
@@ -238,31 +298,33 @@ export function underneath(parts, path, visible) {
238
298
  }
239
299
  return report;
240
300
  }
241
- const UNTYPED_MEDIA_TYPE = 'application/octet-stream';
242
301
  export async function heldFile(blob, base) {
243
- const bytes = await blob.arrayBuffer();
244
302
  return {
245
- blob,
246
303
  localId: binaryLocalId(),
247
- byteLength: bytes.byteLength,
248
- mediaType: blob.type === '' ? UNTYPED_MEDIA_TYPE : blob.type,
249
- sha256: hexDigest(await crypto.subtle.digest('SHA-256', bytes)),
304
+ ...(blob instanceof File ? { name: blob.name } : {}),
305
+ byteLength: blob.size,
306
+ mediaType: declaredType(blob),
307
+ sha256: await sha256(blob),
250
308
  base,
251
309
  };
252
310
  }
253
311
  export function binaryBase(visible, path) {
254
- return visible?.binaries[path] === undefined ? null : (visible.revisions[path] ?? null);
312
+ const binary = visible?.binaries[path];
313
+ if (binary === undefined)
314
+ return null;
315
+ return visible?.revisions[path] ?? (binary.state === 'pending' ? binary.localId : null);
255
316
  }
256
- export function changedParts(path, report) {
317
+ export function changedParts(path, parts, visible) {
318
+ const report = underneath(parts, path, visible);
319
+ const made = parts.file?.base === null;
257
320
  return [
258
- ...(report.creation === undefined ? [] : [{ path, part: 'creation' }]),
259
321
  ...named(report.fields).map(([name]) => ({ path, part: 'field', name })),
260
322
  ...named(report.sections).map(([name]) => ({ path, part: 'section', name })),
261
323
  ...(report.preamble === undefined ? [] : [{ path, part: 'preamble' }]),
262
324
  ...(report.markdown === undefined ? [] : [{ path, part: 'markdown' }]),
263
325
  ...(report.move === undefined ? [] : [{ path, part: 'move' }]),
264
326
  ...(report.removal === undefined ? [] : [{ path, part: 'removal' }]),
265
- ...(report.file === undefined ? [] : [{ path, part: 'file' }]),
327
+ ...(report.file === undefined || made ? [] : [{ path, part: 'file' }]),
266
328
  ];
267
329
  }
268
330
  function joined(existing, returned) {
@@ -272,34 +334,45 @@ function joined(existing, returned) {
272
334
  merged[name] = part;
273
335
  return Object.keys(merged).length === 0 ? undefined : merged;
274
336
  }
275
- function ended(text) {
337
+ export function lineEnded(text) {
276
338
  return text === '' || text.endsWith('\n') ? text : `${text}\n`;
277
339
  }
278
- function frontmatterOf(fields) {
279
- const opened = parse('---\n---\n');
280
- if (!opened.ok)
281
- return malformed();
282
- let document = opened.document;
283
- for (const [name, part] of fields) {
284
- const next = apply(document, { kind: 'field', name, value: part.value, prior: undefined });
285
- if (next.outcome !== 'applied')
286
- return malformed();
287
- document = next.document;
288
- }
289
- return serialize(document);
340
+ function written(start, changes, definition) {
341
+ const next = apply(start, changes, definition);
342
+ return next.outcome === 'applied' ? next.document : malformed();
290
343
  }
291
- function concatenated(markdown, parts) {
344
+ function empty(definition) {
345
+ const parsed = parse('', '', definition);
346
+ return parsed.ok ? parsed.document : malformed();
347
+ }
348
+ export function partsAfter(markdown, parts, definitions) {
292
349
  const fields = named(parts.fields);
350
+ const sections = named(parts.sections);
351
+ if (fields.length === 0 && sections.length === 0 && parts.preamble === undefined)
352
+ return markdown;
353
+ const whole = parse(markdown, '', definitions);
354
+ const type = whole.ok ? whole.document.type : undefined;
355
+ const definition = definitions?.(type);
356
+ if (type !== undefined && definition === undefined)
357
+ return null;
358
+ const valued = fields.length === 0
359
+ ? empty(definition)
360
+ : written(create(type, definition), fields.map(([name, part]) => ({
361
+ kind: 'field',
362
+ name,
363
+ value: part.value,
364
+ prior: undefined,
365
+ })), definition);
366
+ const head = parts.preamble === undefined
367
+ ? valued
368
+ : written(valued, [{ kind: 'preamble', value: lineEnded(parts.preamble.value), prior: valued.preamble }], definition);
293
369
  const pieces = [
294
- ...(fields.length === 0 ? [] : [frontmatterOf(fields)]),
295
- ...(parts.preamble === undefined ? [] : [parts.preamble.value]),
296
- ...named(parts.sections).map(([name, part]) => `## ${name}\n${part.value}`),
370
+ ...(fields.length === 0 && parts.preamble === undefined ? [] : [serialize(head)]),
371
+ ...sections.map(([name, part]) => serialize(written(empty(definition), [{ kind: 'section', name, value: lineEnded(part.value), prior: undefined }], definition))),
297
372
  ];
298
- if (pieces.length === 0)
299
- return markdown;
300
- return `${ended(markdown)}\n${pieces.map(ended).join('')}`;
373
+ return `${lineEnded(markdown)}\n${pieces.join('')}`;
301
374
  }
302
- export function returnedInto(existing, returned) {
375
+ export function returnedInto(existing, returned, definitions) {
303
376
  if (existing === undefined)
304
377
  return returned;
305
378
  const next = { ...existing };
@@ -319,7 +392,9 @@ export function returnedInto(existing, returned) {
319
392
  delete next.fields;
320
393
  delete next.sections;
321
394
  delete next.preamble;
322
- const value = concatenated(whole.value, existing.markdown === undefined ? existing : returned);
395
+ const value = partsAfter(whole.value, existing.markdown === undefined ? existing : returned, definitions);
396
+ if (value === null)
397
+ return null;
323
398
  next.markdown = { value, base: whole.base };
324
399
  }
325
400
  const creation = existing.creation ?? returned.creation;
@@ -340,6 +415,36 @@ export function moveTarget(move) {
340
415
  const to = normalize(move.to);
341
416
  return to === null || to === '' ? move.to : to;
342
417
  }
418
+ export function readSavedParts(named) {
419
+ const read = named.map(({ path, parts }) => ({ path, parts: readParts(parts, path) }));
420
+ read.forEach(({ path }, at) => {
421
+ if (path === '' || normalize(path) !== path)
422
+ malformed(path, 'a path inside the Room, such as notes/a.md');
423
+ if (read.findIndex((one) => one.path === path) !== at)
424
+ malformed(path, 'each path once in one save');
425
+ });
426
+ return read;
427
+ }
428
+ export function partsChanges(named) {
429
+ const changes = [];
430
+ const preconditions = [];
431
+ for (const { path, parts } of readSavedParts(named)) {
432
+ const parted = held(undefined, parts);
433
+ const made = changesOf(path, parted);
434
+ changes.push(...made.changes);
435
+ preconditions.push(...made.bases);
436
+ for (const change of made.changes) {
437
+ if (change.kind === 'create')
438
+ preconditions.push({ kind: 'absent', path });
439
+ if (change.kind === 'move')
440
+ preconditions.push({ kind: 'absent', path: change.to });
441
+ }
442
+ const revision = parted.markdown?.base ?? parted.move?.base ?? parted.removal?.base;
443
+ if (typeof revision === 'string')
444
+ preconditions.push({ kind: 'revision', path, revision });
445
+ }
446
+ return { changes, preconditions };
447
+ }
343
448
  export function changesOf(path, parts) {
344
449
  const changes = [];
345
450
  const bases = [];
@@ -359,23 +464,23 @@ export function changesOf(path, parts) {
359
464
  bases.push({ kind: 'field', path, name, value: part.base?.value });
360
465
  }
361
466
  for (const [name, part] of named(parts.sections)) {
362
- changes.push({ kind: 'section', path, name, value: part.value });
467
+ changes.push({ kind: 'section', path, name, value: lineEnded(part.value) });
363
468
  bases.push({ kind: 'section', path, name, value: part.base });
364
469
  }
365
470
  if (parts.preamble !== undefined) {
366
- changes.push({ kind: 'preamble', path, value: parts.preamble.value });
471
+ changes.push({ kind: 'preamble', path, value: lineEnded(parts.preamble.value) });
367
472
  bases.push({ kind: 'preamble', path, value: parts.preamble.base });
368
473
  }
369
474
  if (parts.markdown !== undefined) {
370
475
  changes.push({ kind: 'replace', path, content: parts.markdown.value });
371
476
  }
372
477
  if (parts.file !== undefined && parts.removal === undefined) {
373
- const { base, ...file } = parts.file;
478
+ const { base, name: _name, ...file } = parts.file;
374
479
  const at = parts.move === undefined ? path : moveTarget(parts.move);
375
480
  if (base !== null && at !== path)
376
481
  changes.push({ kind: 'move', path, to: at });
377
482
  changes.push({ kind: 'binary', path: at, ...file });
378
- if (base === null && at !== path)
483
+ if (base === null)
379
484
  bases.push({ kind: 'absent', path: at });
380
485
  return { changes, bases };
381
486
  }
@@ -387,35 +492,6 @@ export function changesOf(path, parts) {
387
492
  changes.push({ kind: 'remove', path });
388
493
  return { changes, bases };
389
494
  }
390
- function rebased(before, after) {
391
- return before === undefined ? after : { ...after, base: before.base };
392
- }
393
- function rebasedAll(before, after) {
394
- return {
395
- ...before,
396
- ...Object.fromEntries(Object.entries(after).map(([name, part]) => [name, rebased(before?.[name], part)])),
397
- };
398
- }
399
- export function joinedDraft(carried, saved) {
400
- const draft = saved.find((item) => item.path === carried.path);
401
- if (draft === undefined)
402
- return carried;
403
- const held = carried.parts;
404
- const next = draft.parts;
405
- return {
406
- path: carried.path,
407
- parts: {
408
- ...held,
409
- ...next,
410
- ...(next.fields === undefined ? {} : { fields: rebasedAll(held.fields, next.fields) }),
411
- ...(next.sections === undefined
412
- ? {}
413
- : { sections: rebasedAll(held.sections, next.sections) }),
414
- ...(next.preamble === undefined ? {} : { preamble: rebased(held.preamble, next.preamble) }),
415
- ...(next.markdown === undefined ? {} : { markdown: rebased(held.markdown, next.markdown) }),
416
- },
417
- };
418
- }
419
495
  export function withdrawnDrafts(drafts, changes) {
420
496
  return drafts.flatMap((draft) => {
421
497
  const file = draft.parts.file;
@@ -0,0 +1,24 @@
1
+ import { type ChangeSet } from './change-set.js';
2
+ import { type VisibleLayer } from './replica.js';
3
+ import { type RoomDraft, type RoomDraftWrite } from './room-draft.js';
4
+ import type { Runtime } from './runtime.js';
5
+ import type { Store } from './store.js';
6
+ export type RoomDraftSurface = {
7
+ list(): Promise<readonly RoomDraft[]>;
8
+ read(room: string, path: string): Promise<RoomDraft | null>;
9
+ write(room: string, path: string, revision: string | null, parts: unknown, next?: string): Promise<RoomDraftWrite>;
10
+ discard(room: string, path: string, revision: string): Promise<RoomDraftWrite>;
11
+ };
12
+ export type PresentationSurface = {
13
+ read(app: string): Promise<unknown>;
14
+ write(app: string, value: unknown): Promise<void>;
15
+ edit(app: string, members: Readonly<Record<string, unknown>>): Promise<void>;
16
+ };
17
+ export declare function visibleOf(store: Store, locator: string, paths: readonly string[]): Promise<VisibleLayer | undefined>;
18
+ export declare function publishRoomDrafts({ store, socket }: Runtime, waitingOnly: boolean, touched?: ChangeSet['documents'] | null): Promise<void>;
19
+ export declare function emitPresentation({ store, socket }: Runtime, app: string): Promise<void>;
20
+ export declare function roomDraftSurface(runtime: Runtime): RoomDraftSurface;
21
+ export declare function presentationSurface(runtime: Runtime): PresentationSurface;
22
+ export declare function watchRoomDrafts({ store, socket }: Runtime, deliver: (value: unknown) => void): () => void;
23
+ export declare function watchPresentation({ store, socket }: Runtime, app: string, deliver: (value: unknown) => void): () => void;
24
+ //# sourceMappingURL=room-drafts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-drafts.d.ts","sourceRoot":"","sources":["../src/room-drafts.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5D,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAQL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,KAAK,EAAE,OAAO,EACd,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAChF,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E,CAAC;AAMF,wBAAsB,SAAS,CAC7B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAMnC;AA0CD,wBAAgB,iBAAiB,CAC/B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,OAAO,GAAE,SAAS,CAAC,WAAW,CAAC,GAAG,IAAW,GAC5C,OAAO,CAAC,IAAI,CAAC,CAuBf;AAOD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvF;AAoDD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAkDnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,CA8BzE;AAED,wBAAgB,eAAe,CAC7B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CAiBZ;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,MAAM,IAAI,CASZ"}