@geekity/cms 0.3.0 → 0.4.0

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 (637) hide show
  1. package/README.md +2091 -214
  2. package/admin/components/fields.njk +165 -0
  3. package/admin/layouts/base.njk +1 -1
  4. package/admin/layouts/settings-page.njk +26 -0
  5. package/admin/layouts/shell.njk +17 -3
  6. package/admin/pages/account/forgot.njk +47 -0
  7. package/admin/pages/account/login.njk +26 -0
  8. package/admin/pages/account/reset.njk +38 -0
  9. package/admin/pages/account/setup.njk +28 -0
  10. package/admin/pages/appearance/themes.njk +69 -0
  11. package/admin/pages/comments/all.njk +133 -0
  12. package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
  13. package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
  14. package/admin/pages/documents/editor.njk +196 -0
  15. package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
  16. package/admin/pages/documents/taxonomy.njk +95 -0
  17. package/admin/pages/federation/followers.njk +238 -0
  18. package/admin/pages/media/library.njk +160 -0
  19. package/admin/pages/messages/all.njk +110 -0
  20. package/admin/{layouts → pages}/placeholder.njk +5 -1
  21. package/admin/pages/settings/discussion.njk +99 -0
  22. package/admin/pages/settings/email.njk +203 -0
  23. package/admin/pages/settings/federation.njk +75 -0
  24. package/admin/pages/settings/general.njk +29 -0
  25. package/admin/pages/settings/permalinks.njk +50 -0
  26. package/admin/pages/settings/reading.njk +72 -0
  27. package/admin/pages/users/edit.njk +239 -0
  28. package/admin/pages/users/list.njk +48 -0
  29. package/admin/pages/users/new.njk +41 -0
  30. package/admin/static/admin.css +498 -3
  31. package/admin/static/copy.js +52 -0
  32. package/admin/static/editor.js +16 -16
  33. package/admin/static/slug.js +61 -0
  34. package/dist/admin/accounts.d.ts +413 -0
  35. package/dist/admin/accounts.d.ts.map +1 -0
  36. package/dist/admin/accounts.js +680 -0
  37. package/dist/admin/accounts.js.map +1 -0
  38. package/dist/admin/appearance.d.ts +80 -0
  39. package/dist/admin/appearance.d.ts.map +1 -0
  40. package/dist/admin/appearance.js +136 -0
  41. package/dist/admin/appearance.js.map +1 -0
  42. package/dist/admin/comments.d.ts +90 -0
  43. package/dist/admin/comments.d.ts.map +1 -0
  44. package/dist/admin/comments.js +244 -0
  45. package/dist/admin/comments.js.map +1 -0
  46. package/dist/admin/credentials.d.ts +26 -2
  47. package/dist/admin/credentials.d.ts.map +1 -1
  48. package/dist/admin/credentials.js +35 -2
  49. package/dist/admin/credentials.js.map +1 -1
  50. package/dist/admin/documents.d.ts +127 -10
  51. package/dist/admin/documents.d.ts.map +1 -1
  52. package/dist/admin/documents.js +360 -41
  53. package/dist/admin/documents.js.map +1 -1
  54. package/dist/admin/federation.d.ts +151 -50
  55. package/dist/admin/federation.d.ts.map +1 -1
  56. package/dist/admin/federation.js +225 -93
  57. package/dist/admin/federation.js.map +1 -1
  58. package/dist/admin/formatting.d.ts +20 -0
  59. package/dist/admin/formatting.d.ts.map +1 -0
  60. package/dist/admin/formatting.js +72 -0
  61. package/dist/admin/formatting.js.map +1 -0
  62. package/dist/admin/headers.d.ts +65 -0
  63. package/dist/admin/headers.d.ts.map +1 -0
  64. package/dist/admin/headers.js +104 -0
  65. package/dist/admin/headers.js.map +1 -0
  66. package/dist/admin/index.d.ts +38 -12
  67. package/dist/admin/index.d.ts.map +1 -1
  68. package/dist/admin/index.js +25 -7
  69. package/dist/admin/index.js.map +1 -1
  70. package/dist/admin/media.d.ts +168 -0
  71. package/dist/admin/media.d.ts.map +1 -0
  72. package/dist/admin/media.js +295 -0
  73. package/dist/admin/media.js.map +1 -0
  74. package/dist/admin/menu.d.ts +79 -0
  75. package/dist/admin/menu.d.ts.map +1 -0
  76. package/dist/admin/menu.js +126 -0
  77. package/dist/admin/menu.js.map +1 -0
  78. package/dist/admin/messages.d.ts +80 -0
  79. package/dist/admin/messages.d.ts.map +1 -0
  80. package/dist/admin/messages.js +152 -0
  81. package/dist/admin/messages.js.map +1 -0
  82. package/dist/admin/preview.d.ts.map +1 -1
  83. package/dist/admin/preview.js +31 -7
  84. package/dist/admin/preview.js.map +1 -1
  85. package/dist/admin/recovery.d.ts +92 -0
  86. package/dist/admin/recovery.d.ts.map +1 -0
  87. package/dist/admin/recovery.js +229 -0
  88. package/dist/admin/recovery.js.map +1 -0
  89. package/dist/admin/routes.d.ts +0 -20
  90. package/dist/admin/routes.d.ts.map +1 -1
  91. package/dist/admin/routes.js +155 -105
  92. package/dist/admin/routes.js.map +1 -1
  93. package/dist/admin/settings-discussion.d.ts +37 -0
  94. package/dist/admin/settings-discussion.d.ts.map +1 -0
  95. package/dist/admin/settings-discussion.js +117 -0
  96. package/dist/admin/settings-discussion.js.map +1 -0
  97. package/dist/admin/settings-email.d.ts +54 -0
  98. package/dist/admin/settings-email.d.ts.map +1 -0
  99. package/dist/admin/settings-email.js +189 -0
  100. package/dist/admin/settings-email.js.map +1 -0
  101. package/dist/admin/settings-federation.d.ts +39 -0
  102. package/dist/admin/settings-federation.d.ts.map +1 -0
  103. package/dist/admin/settings-federation.js +103 -0
  104. package/dist/admin/settings-federation.js.map +1 -0
  105. package/dist/admin/settings-general.d.ts +12 -0
  106. package/dist/admin/settings-general.d.ts.map +1 -0
  107. package/dist/admin/settings-general.js +48 -0
  108. package/dist/admin/settings-general.js.map +1 -0
  109. package/dist/admin/settings-page.d.ts +102 -0
  110. package/dist/admin/settings-page.d.ts.map +1 -0
  111. package/dist/admin/settings-page.js +126 -0
  112. package/dist/admin/settings-page.js.map +1 -0
  113. package/dist/admin/settings-pages.d.ts +19 -0
  114. package/dist/admin/settings-pages.d.ts.map +1 -0
  115. package/dist/admin/settings-pages.js +33 -0
  116. package/dist/admin/settings-pages.js.map +1 -0
  117. package/dist/admin/settings-permalinks.d.ts +16 -0
  118. package/dist/admin/settings-permalinks.d.ts.map +1 -0
  119. package/dist/admin/settings-permalinks.js +32 -0
  120. package/dist/admin/settings-permalinks.js.map +1 -0
  121. package/dist/admin/settings-reading.d.ts +33 -0
  122. package/dist/admin/settings-reading.d.ts.map +1 -0
  123. package/dist/admin/settings-reading.js +48 -0
  124. package/dist/admin/settings-reading.js.map +1 -0
  125. package/dist/admin/settings.d.ts +325 -96
  126. package/dist/admin/settings.d.ts.map +1 -1
  127. package/dist/admin/settings.js +650 -308
  128. package/dist/admin/settings.js.map +1 -1
  129. package/dist/admin/store.d.ts +606 -152
  130. package/dist/admin/store.d.ts.map +1 -1
  131. package/dist/admin/store.js +863 -268
  132. package/dist/admin/store.js.map +1 -1
  133. package/dist/admin/taxonomy.d.ts +114 -0
  134. package/dist/admin/taxonomy.d.ts.map +1 -0
  135. package/dist/admin/taxonomy.js +289 -0
  136. package/dist/admin/taxonomy.js.map +1 -0
  137. package/dist/admin/templates.d.ts +44 -14
  138. package/dist/admin/templates.d.ts.map +1 -1
  139. package/dist/admin/templates.js +44 -14
  140. package/dist/admin/templates.js.map +1 -1
  141. package/dist/admin/throttle.d.ts +84 -0
  142. package/dist/admin/throttle.d.ts.map +1 -0
  143. package/dist/admin/throttle.js +143 -0
  144. package/dist/admin/throttle.js.map +1 -0
  145. package/dist/admin/uploads.d.ts +28 -2
  146. package/dist/admin/uploads.d.ts.map +1 -1
  147. package/dist/admin/uploads.js +43 -4
  148. package/dist/admin/uploads.js.map +1 -1
  149. package/dist/admin/users.d.ts +100 -13
  150. package/dist/admin/users.d.ts.map +1 -1
  151. package/dist/admin/users.js +412 -39
  152. package/dist/admin/users.js.map +1 -1
  153. package/dist/cache.d.ts +141 -0
  154. package/dist/cache.d.ts.map +1 -0
  155. package/dist/cache.js +207 -0
  156. package/dist/cache.js.map +1 -0
  157. package/dist/cli.d.ts +14 -2
  158. package/dist/cli.d.ts.map +1 -1
  159. package/dist/cli.js +424 -21
  160. package/dist/cli.js.map +1 -1
  161. package/dist/comments/akismet.d.ts +130 -0
  162. package/dist/comments/akismet.d.ts.map +1 -0
  163. package/dist/comments/akismet.js +274 -0
  164. package/dist/comments/akismet.js.map +1 -0
  165. package/dist/comments/conversation.d.ts +29 -0
  166. package/dist/comments/conversation.d.ts.map +1 -0
  167. package/dist/comments/conversation.js +60 -0
  168. package/dist/comments/conversation.js.map +1 -0
  169. package/dist/comments/form.d.ts +75 -0
  170. package/dist/comments/form.d.ts.map +1 -0
  171. package/dist/comments/form.js +64 -0
  172. package/dist/comments/form.js.map +1 -0
  173. package/dist/comments/index.d.ts +15 -0
  174. package/dist/comments/index.d.ts.map +1 -0
  175. package/dist/comments/index.js +9 -0
  176. package/dist/comments/index.js.map +1 -0
  177. package/dist/comments/markdown.d.ts +8 -0
  178. package/dist/comments/markdown.d.ts.map +1 -0
  179. package/dist/comments/markdown.js +85 -0
  180. package/dist/comments/markdown.js.map +1 -0
  181. package/dist/comments/moderate.d.ts +71 -0
  182. package/dist/comments/moderate.d.ts.map +1 -0
  183. package/dist/comments/moderate.js +88 -0
  184. package/dist/comments/moderate.js.map +1 -0
  185. package/dist/comments/policy.d.ts +57 -0
  186. package/dist/comments/policy.d.ts.map +1 -0
  187. package/dist/comments/policy.js +80 -0
  188. package/dist/comments/policy.js.map +1 -0
  189. package/dist/comments/records.d.ts +266 -0
  190. package/dist/comments/records.d.ts.map +1 -0
  191. package/dist/comments/records.js +487 -0
  192. package/dist/comments/records.js.map +1 -0
  193. package/dist/comments/routes.d.ts +58 -0
  194. package/dist/comments/routes.d.ts.map +1 -0
  195. package/dist/comments/routes.js +177 -0
  196. package/dist/comments/routes.js.map +1 -0
  197. package/dist/comments/submission.d.ts +263 -0
  198. package/dist/comments/submission.d.ts.map +1 -0
  199. package/dist/comments/submission.js +241 -0
  200. package/dist/comments/submission.js.map +1 -0
  201. package/dist/config.d.ts +190 -5
  202. package/dist/config.d.ts.map +1 -1
  203. package/dist/config.js +118 -6
  204. package/dist/config.js.map +1 -1
  205. package/dist/contact/delivery.d.ts +60 -0
  206. package/dist/contact/delivery.d.ts.map +1 -0
  207. package/dist/contact/delivery.js +87 -0
  208. package/dist/contact/delivery.js.map +1 -0
  209. package/dist/contact/form.d.ts +130 -0
  210. package/dist/contact/form.d.ts.map +1 -0
  211. package/dist/contact/form.js +163 -0
  212. package/dist/contact/form.js.map +1 -0
  213. package/dist/contact/index.d.ts +17 -0
  214. package/dist/contact/index.d.ts.map +1 -0
  215. package/dist/contact/index.js +13 -0
  216. package/dist/contact/index.js.map +1 -0
  217. package/dist/contact/records.d.ts +124 -0
  218. package/dist/contact/records.d.ts.map +1 -0
  219. package/dist/contact/records.js +218 -0
  220. package/dist/contact/records.js.map +1 -0
  221. package/dist/contact/routes.d.ts +17 -0
  222. package/dist/contact/routes.d.ts.map +1 -0
  223. package/dist/contact/routes.js +127 -0
  224. package/dist/contact/routes.js.map +1 -0
  225. package/dist/contact/submission.d.ts +103 -0
  226. package/dist/contact/submission.d.ts.map +1 -0
  227. package/dist/contact/submission.js +166 -0
  228. package/dist/contact/submission.js.map +1 -0
  229. package/dist/content/document.d.ts +7 -2
  230. package/dist/content/document.d.ts.map +1 -1
  231. package/dist/content/document.js +1 -0
  232. package/dist/content/document.js.map +1 -1
  233. package/dist/content/index.d.ts +7 -2
  234. package/dist/content/index.d.ts.map +1 -1
  235. package/dist/content/index.js +4 -1
  236. package/dist/content/index.js.map +1 -1
  237. package/dist/content/markdown.d.ts.map +1 -1
  238. package/dist/content/markdown.js +24 -2
  239. package/dist/content/markdown.js.map +1 -1
  240. package/dist/content/parser.d.ts.map +1 -1
  241. package/dist/content/parser.js +11 -4
  242. package/dist/content/parser.js.map +1 -1
  243. package/dist/content/save.d.ts +5 -0
  244. package/dist/content/save.d.ts.map +1 -1
  245. package/dist/content/save.js +44 -1
  246. package/dist/content/save.js.map +1 -1
  247. package/dist/content/schedule.d.ts +125 -0
  248. package/dist/content/schedule.d.ts.map +1 -0
  249. package/dist/content/schedule.js +207 -0
  250. package/dist/content/schedule.js.map +1 -0
  251. package/dist/content/search.d.ts +64 -0
  252. package/dist/content/search.d.ts.map +1 -0
  253. package/dist/content/search.js +136 -0
  254. package/dist/content/search.js.map +1 -0
  255. package/dist/content/store.d.ts +202 -7
  256. package/dist/content/store.d.ts.map +1 -1
  257. package/dist/content/store.js +374 -67
  258. package/dist/content/store.js.map +1 -1
  259. package/dist/content/sync.d.ts +7 -1
  260. package/dist/content/sync.d.ts.map +1 -1
  261. package/dist/content/sync.js +18 -10
  262. package/dist/content/sync.js.map +1 -1
  263. package/dist/content/time.d.ts +56 -0
  264. package/dist/content/time.d.ts.map +1 -0
  265. package/dist/content/time.js +141 -0
  266. package/dist/content/time.js.map +1 -0
  267. package/dist/content/writer.d.ts.map +1 -1
  268. package/dist/content/writer.js +3 -0
  269. package/dist/content/writer.js.map +1 -1
  270. package/dist/env.d.ts +58 -4
  271. package/dist/env.d.ts.map +1 -1
  272. package/dist/federation/actor.d.ts +95 -41
  273. package/dist/federation/actor.d.ts.map +1 -1
  274. package/dist/federation/actor.js +180 -53
  275. package/dist/federation/actor.js.map +1 -1
  276. package/dist/federation/article.d.ts +44 -17
  277. package/dist/federation/article.d.ts.map +1 -1
  278. package/dist/federation/article.js +98 -46
  279. package/dist/federation/article.js.map +1 -1
  280. package/dist/federation/delivery.d.ts +63 -15
  281. package/dist/federation/delivery.d.ts.map +1 -1
  282. package/dist/federation/delivery.js +154 -80
  283. package/dist/federation/delivery.js.map +1 -1
  284. package/dist/federation/federation.d.ts +22 -17
  285. package/dist/federation/federation.d.ts.map +1 -1
  286. package/dist/federation/federation.js +98 -77
  287. package/dist/federation/federation.js.map +1 -1
  288. package/dist/federation/followers.d.ts +3 -2
  289. package/dist/federation/followers.d.ts.map +1 -1
  290. package/dist/federation/followers.js +6 -5
  291. package/dist/federation/followers.js.map +1 -1
  292. package/dist/federation/import-wordpress.d.ts +128 -0
  293. package/dist/federation/import-wordpress.d.ts.map +1 -0
  294. package/dist/federation/import-wordpress.js +426 -0
  295. package/dist/federation/import-wordpress.js.map +1 -0
  296. package/dist/federation/inbox.d.ts +36 -13
  297. package/dist/federation/inbox.d.ts.map +1 -1
  298. package/dist/federation/inbox.js +120 -49
  299. package/dist/federation/inbox.js.map +1 -1
  300. package/dist/federation/index.d.ts +22 -10
  301. package/dist/federation/index.d.ts.map +1 -1
  302. package/dist/federation/index.js +13 -8
  303. package/dist/federation/index.js.map +1 -1
  304. package/dist/federation/keys.d.ts +98 -20
  305. package/dist/federation/keys.d.ts.map +1 -1
  306. package/dist/federation/keys.js +269 -39
  307. package/dist/federation/keys.js.map +1 -1
  308. package/dist/federation/mount.d.ts +42 -10
  309. package/dist/federation/mount.d.ts.map +1 -1
  310. package/dist/federation/mount.js +266 -26
  311. package/dist/federation/mount.js.map +1 -1
  312. package/dist/federation/paths.d.ts +23 -35
  313. package/dist/federation/paths.d.ts.map +1 -1
  314. package/dist/federation/paths.js +26 -39
  315. package/dist/federation/paths.js.map +1 -1
  316. package/dist/federation/records.d.ts +223 -0
  317. package/dist/federation/records.d.ts.map +1 -0
  318. package/dist/federation/records.js +506 -0
  319. package/dist/federation/records.js.map +1 -0
  320. package/dist/federation/relays.d.ts +114 -0
  321. package/dist/federation/relays.d.ts.map +1 -0
  322. package/dist/federation/relays.js +290 -0
  323. package/dist/federation/relays.js.map +1 -0
  324. package/dist/federation/replies.d.ts +80 -0
  325. package/dist/federation/replies.d.ts.map +1 -0
  326. package/dist/federation/replies.js +166 -0
  327. package/dist/federation/replies.js.map +1 -0
  328. package/dist/federation/wordpress.d.ts +131 -0
  329. package/dist/federation/wordpress.d.ts.map +1 -0
  330. package/dist/federation/wordpress.js +341 -0
  331. package/dist/federation/wordpress.js.map +1 -0
  332. package/dist/files/atomic.d.ts +103 -0
  333. package/dist/files/atomic.d.ts.map +1 -0
  334. package/dist/files/atomic.js +150 -0
  335. package/dist/files/atomic.js.map +1 -0
  336. package/dist/files/index.d.ts +3 -0
  337. package/dist/files/index.d.ts.map +1 -0
  338. package/dist/files/index.js +2 -0
  339. package/dist/files/index.js.map +1 -0
  340. package/dist/forms/protection.d.ts +85 -0
  341. package/dist/forms/protection.d.ts.map +1 -0
  342. package/dist/forms/protection.js +116 -0
  343. package/dist/forms/protection.js.map +1 -0
  344. package/dist/images/icons.d.ts +59 -0
  345. package/dist/images/icons.d.ts.map +1 -0
  346. package/dist/images/icons.js +131 -0
  347. package/dist/images/icons.js.map +1 -0
  348. package/dist/images/index.d.ts +7 -0
  349. package/dist/images/index.d.ts.map +1 -0
  350. package/dist/images/index.js +4 -0
  351. package/dist/images/index.js.map +1 -0
  352. package/dist/images/markup.d.ts +47 -0
  353. package/dist/images/markup.d.ts.map +1 -0
  354. package/dist/images/markup.js +175 -0
  355. package/dist/images/markup.js.map +1 -0
  356. package/dist/images/paths.d.ts +34 -0
  357. package/dist/images/paths.d.ts.map +1 -0
  358. package/dist/images/paths.js +41 -0
  359. package/dist/images/paths.js.map +1 -0
  360. package/dist/images/variants.d.ts +104 -0
  361. package/dist/images/variants.d.ts.map +1 -0
  362. package/dist/images/variants.js +320 -0
  363. package/dist/images/variants.js.map +1 -0
  364. package/dist/index.d.ts +123 -19
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +327 -25
  367. package/dist/index.js.map +1 -1
  368. package/dist/init.d.ts +18 -0
  369. package/dist/init.d.ts.map +1 -1
  370. package/dist/init.js +34 -3
  371. package/dist/init.js.map +1 -1
  372. package/dist/mail/brevo.d.ts +35 -0
  373. package/dist/mail/brevo.d.ts.map +1 -0
  374. package/dist/mail/brevo.js +85 -0
  375. package/dist/mail/brevo.js.map +1 -0
  376. package/dist/mail/credentials.d.ts +62 -0
  377. package/dist/mail/credentials.d.ts.map +1 -0
  378. package/dist/mail/credentials.js +86 -0
  379. package/dist/mail/credentials.js.map +1 -0
  380. package/dist/mail/index.d.ts +15 -0
  381. package/dist/mail/index.d.ts.map +1 -0
  382. package/dist/mail/index.js +8 -0
  383. package/dist/mail/index.js.map +1 -0
  384. package/dist/mail/memory.d.ts +35 -0
  385. package/dist/mail/memory.d.ts.map +1 -0
  386. package/dist/mail/memory.js +29 -0
  387. package/dist/mail/memory.js.map +1 -0
  388. package/dist/mail/provider.d.ts +80 -0
  389. package/dist/mail/provider.d.ts.map +1 -0
  390. package/dist/mail/provider.js +23 -0
  391. package/dist/mail/provider.js.map +1 -0
  392. package/dist/mail/service.d.ts +156 -0
  393. package/dist/mail/service.d.ts.map +1 -0
  394. package/dist/mail/service.js +265 -0
  395. package/dist/mail/service.js.map +1 -0
  396. package/dist/mail/smtp.d.ts +39 -0
  397. package/dist/mail/smtp.d.ts.map +1 -0
  398. package/dist/mail/smtp.js +58 -0
  399. package/dist/mail/smtp.js.map +1 -0
  400. package/dist/mail/templates.d.ts +91 -0
  401. package/dist/mail/templates.d.ts.map +1 -0
  402. package/dist/mail/templates.js +69 -0
  403. package/dist/mail/templates.js.map +1 -0
  404. package/dist/notifications/comments.d.ts +66 -0
  405. package/dist/notifications/comments.d.ts.map +1 -0
  406. package/dist/notifications/comments.js +151 -0
  407. package/dist/notifications/comments.js.map +1 -0
  408. package/dist/notifications/digest.d.ts +135 -0
  409. package/dist/notifications/digest.d.ts.map +1 -0
  410. package/dist/notifications/digest.js +287 -0
  411. package/dist/notifications/digest.js.map +1 -0
  412. package/dist/notifications/index.d.ts +13 -0
  413. package/dist/notifications/index.d.ts.map +1 -0
  414. package/dist/notifications/index.js +8 -0
  415. package/dist/notifications/index.js.map +1 -0
  416. package/dist/notifications/links.d.ts +60 -0
  417. package/dist/notifications/links.d.ts.map +1 -0
  418. package/dist/notifications/links.js +63 -0
  419. package/dist/notifications/links.js.map +1 -0
  420. package/dist/notifications/optouts.d.ts +48 -0
  421. package/dist/notifications/optouts.d.ts.map +1 -0
  422. package/dist/notifications/optouts.js +93 -0
  423. package/dist/notifications/optouts.js.map +1 -0
  424. package/dist/notifications/preferences.d.ts +158 -0
  425. package/dist/notifications/preferences.d.ts.map +1 -0
  426. package/dist/notifications/preferences.js +195 -0
  427. package/dist/notifications/preferences.js.map +1 -0
  428. package/dist/notifications/routes.d.ts +28 -0
  429. package/dist/notifications/routes.d.ts.map +1 -0
  430. package/dist/notifications/routes.js +184 -0
  431. package/dist/notifications/routes.js.map +1 -0
  432. package/dist/notifications/tokens.d.ts +60 -0
  433. package/dist/notifications/tokens.d.ts.map +1 -0
  434. package/dist/notifications/tokens.js +125 -0
  435. package/dist/notifications/tokens.js.map +1 -0
  436. package/dist/notify.d.ts +84 -0
  437. package/dist/notify.d.ts.map +1 -0
  438. package/dist/notify.js +149 -0
  439. package/dist/notify.js.map +1 -0
  440. package/dist/web/archive.d.ts +49 -0
  441. package/dist/web/archive.d.ts.map +1 -0
  442. package/dist/web/archive.js +59 -0
  443. package/dist/web/archive.js.map +1 -0
  444. package/dist/web/assets.d.ts +6 -5
  445. package/dist/web/assets.d.ts.map +1 -1
  446. package/dist/web/assets.js +5 -7
  447. package/dist/web/assets.js.map +1 -1
  448. package/dist/web/authors.d.ts +143 -0
  449. package/dist/web/authors.d.ts.map +1 -0
  450. package/dist/web/authors.js +178 -0
  451. package/dist/web/authors.js.map +1 -0
  452. package/dist/web/comments.d.ts +60 -0
  453. package/dist/web/comments.d.ts.map +1 -0
  454. package/dist/web/comments.js +207 -0
  455. package/dist/web/comments.js.map +1 -0
  456. package/dist/web/context.d.ts +162 -28
  457. package/dist/web/context.d.ts.map +1 -1
  458. package/dist/web/context.js +123 -26
  459. package/dist/web/context.js.map +1 -1
  460. package/dist/web/conversation.d.ts +209 -0
  461. package/dist/web/conversation.d.ts.map +1 -0
  462. package/dist/web/conversation.js +557 -0
  463. package/dist/web/conversation.js.map +1 -0
  464. package/dist/web/documents.d.ts +36 -6
  465. package/dist/web/documents.d.ts.map +1 -1
  466. package/dist/web/documents.js +52 -10
  467. package/dist/web/documents.js.map +1 -1
  468. package/dist/web/feed-atom.d.ts +22 -0
  469. package/dist/web/feed-atom.d.ts.map +1 -0
  470. package/dist/web/feed-atom.js +83 -0
  471. package/dist/web/feed-atom.js.map +1 -0
  472. package/dist/web/feed-item.d.ts +145 -0
  473. package/dist/web/feed-item.d.ts.map +1 -0
  474. package/dist/web/feed-item.js +120 -0
  475. package/dist/web/feed-item.js.map +1 -0
  476. package/dist/web/feed-json.d.ts +79 -0
  477. package/dist/web/feed-json.d.ts.map +1 -0
  478. package/dist/web/feed-json.js +53 -0
  479. package/dist/web/feed-json.js.map +1 -0
  480. package/dist/web/feed-rss.d.ts +26 -0
  481. package/dist/web/feed-rss.d.ts.map +1 -0
  482. package/dist/web/feed-rss.js +203 -0
  483. package/dist/web/feed-rss.js.map +1 -0
  484. package/dist/web/feed-source.d.ts +244 -0
  485. package/dist/web/feed-source.d.ts.map +1 -0
  486. package/dist/web/feed-source.js +201 -0
  487. package/dist/web/feed-source.js.map +1 -0
  488. package/dist/web/feed-xml.d.ts +63 -0
  489. package/dist/web/feed-xml.d.ts.map +1 -0
  490. package/dist/web/feed-xml.js +116 -0
  491. package/dist/web/feed-xml.js.map +1 -0
  492. package/dist/web/feeds.d.ts +31 -96
  493. package/dist/web/feeds.d.ts.map +1 -1
  494. package/dist/web/feeds.js +94 -198
  495. package/dist/web/feeds.js.map +1 -1
  496. package/dist/web/health.d.ts +31 -0
  497. package/dist/web/health.d.ts.map +1 -0
  498. package/dist/web/health.js +44 -0
  499. package/dist/web/health.js.map +1 -0
  500. package/dist/web/index.d.ts +30 -10
  501. package/dist/web/index.d.ts.map +1 -1
  502. package/dist/web/index.js +18 -7
  503. package/dist/web/index.js.map +1 -1
  504. package/dist/web/navigation.d.ts +73 -0
  505. package/dist/web/navigation.d.ts.map +1 -0
  506. package/dist/web/navigation.js +110 -0
  507. package/dist/web/navigation.js.map +1 -0
  508. package/dist/web/negotiate.d.ts +9 -0
  509. package/dist/web/negotiate.d.ts.map +1 -1
  510. package/dist/web/negotiate.js +6 -1
  511. package/dist/web/negotiate.js.map +1 -1
  512. package/dist/web/recent.d.ts +43 -0
  513. package/dist/web/recent.d.ts.map +1 -0
  514. package/dist/web/recent.js +37 -0
  515. package/dist/web/recent.js.map +1 -0
  516. package/dist/web/render.d.ts +197 -9
  517. package/dist/web/render.d.ts.map +1 -1
  518. package/dist/web/render.js +334 -17
  519. package/dist/web/render.js.map +1 -1
  520. package/dist/web/routes.d.ts +25 -8
  521. package/dist/web/routes.d.ts.map +1 -1
  522. package/dist/web/routes.js +845 -93
  523. package/dist/web/routes.js.map +1 -1
  524. package/dist/web/sanitize.d.ts +19 -0
  525. package/dist/web/sanitize.d.ts.map +1 -0
  526. package/dist/web/sanitize.js +272 -0
  527. package/dist/web/sanitize.js.map +1 -0
  528. package/dist/web/search.d.ts +79 -0
  529. package/dist/web/search.d.ts.map +1 -0
  530. package/dist/web/search.js +94 -0
  531. package/dist/web/search.js.map +1 -0
  532. package/dist/web/sitemap.d.ts +120 -0
  533. package/dist/web/sitemap.d.ts.map +1 -0
  534. package/dist/web/sitemap.js +199 -0
  535. package/dist/web/sitemap.js.map +1 -0
  536. package/dist/web/taxonomy.d.ts +152 -0
  537. package/dist/web/taxonomy.d.ts.map +1 -0
  538. package/dist/web/taxonomy.js +237 -0
  539. package/dist/web/taxonomy.js.map +1 -0
  540. package/dist/web/templates.d.ts +54 -16
  541. package/dist/web/templates.d.ts.map +1 -1
  542. package/dist/web/templates.js +109 -28
  543. package/dist/web/templates.js.map +1 -1
  544. package/dist/web/themes.d.ts +205 -0
  545. package/dist/web/themes.d.ts.map +1 -0
  546. package/dist/web/themes.js +277 -0
  547. package/dist/web/themes.js.map +1 -0
  548. package/dist/webmention/discovery.d.ts +51 -0
  549. package/dist/webmention/discovery.d.ts.map +1 -0
  550. package/dist/webmention/discovery.js +176 -0
  551. package/dist/webmention/discovery.js.map +1 -0
  552. package/dist/webmention/html.d.ts +71 -0
  553. package/dist/webmention/html.d.ts.map +1 -0
  554. package/dist/webmention/html.js +285 -0
  555. package/dist/webmention/html.js.map +1 -0
  556. package/dist/webmention/index.d.ts +12 -0
  557. package/dist/webmention/index.d.ts.map +1 -0
  558. package/dist/webmention/index.js +8 -0
  559. package/dist/webmention/index.js.map +1 -0
  560. package/dist/webmention/links.d.ts +18 -0
  561. package/dist/webmention/links.d.ts.map +1 -0
  562. package/dist/webmention/links.js +64 -0
  563. package/dist/webmention/links.js.map +1 -0
  564. package/dist/webmention/microformats.d.ts +93 -0
  565. package/dist/webmention/microformats.d.ts.map +1 -0
  566. package/dist/webmention/microformats.js +376 -0
  567. package/dist/webmention/microformats.js.map +1 -0
  568. package/dist/webmention/receive.d.ts +141 -0
  569. package/dist/webmention/receive.d.ts.map +1 -0
  570. package/dist/webmention/receive.js +264 -0
  571. package/dist/webmention/receive.js.map +1 -0
  572. package/dist/webmention/routes.d.ts +37 -0
  573. package/dist/webmention/routes.d.ts.map +1 -0
  574. package/dist/webmention/routes.js +75 -0
  575. package/dist/webmention/routes.js.map +1 -0
  576. package/dist/webmention/service.d.ts +94 -0
  577. package/dist/webmention/service.d.ts.map +1 -0
  578. package/dist/webmention/service.js +207 -0
  579. package/dist/webmention/service.js.map +1 -0
  580. package/package.json +11 -6
  581. package/templates/site/content/_data/site.json +1 -0
  582. package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
  583. package/templates/site/geekity.config.ts +11 -1
  584. package/templates/site/tsconfig.json +1 -1
  585. package/themes/default/README.md +1096 -50
  586. package/themes/default/layouts/404.njk +2 -3
  587. package/themes/default/layouts/author.njk +37 -0
  588. package/themes/default/layouts/base.njk +172 -31
  589. package/themes/default/layouts/category.njk +27 -0
  590. package/themes/default/layouts/front-page.njk +57 -0
  591. package/themes/default/layouts/home.njk +17 -1
  592. package/themes/default/layouts/page.njk +57 -5
  593. package/themes/default/layouts/post.njk +78 -19
  594. package/themes/default/layouts/search.njk +57 -0
  595. package/themes/default/layouts/tag.njk +3 -6
  596. package/themes/default/mail/comment-digest.html.njk +37 -0
  597. package/themes/default/mail/comment-digest.subject.njk +3 -0
  598. package/themes/default/mail/comment-digest.txt.njk +40 -0
  599. package/themes/default/mail/comment-pending.html.njk +27 -0
  600. package/themes/default/mail/comment-pending.subject.njk +2 -0
  601. package/themes/default/mail/comment-pending.txt.njk +24 -0
  602. package/themes/default/mail/comment-reply.html.njk +21 -0
  603. package/themes/default/mail/comment-reply.subject.njk +2 -0
  604. package/themes/default/mail/comment-reply.txt.njk +22 -0
  605. package/themes/default/mail/contact-message.html.njk +24 -0
  606. package/themes/default/mail/contact-message.subject.njk +5 -0
  607. package/themes/default/mail/contact-message.txt.njk +20 -0
  608. package/themes/default/mail/password-changed.html.njk +18 -0
  609. package/themes/default/mail/password-changed.subject.njk +2 -0
  610. package/themes/default/mail/password-changed.txt.njk +17 -0
  611. package/themes/default/mail/password-reset.html.njk +22 -0
  612. package/themes/default/mail/password-reset.subject.njk +2 -0
  613. package/themes/default/mail/password-reset.txt.njk +18 -0
  614. package/themes/default/mail/test.html.njk +14 -0
  615. package/themes/default/mail/test.subject.njk +2 -0
  616. package/themes/default/mail/test.txt.njk +12 -0
  617. package/themes/default/partials/archive.njk +27 -0
  618. package/themes/default/partials/bio.njk +77 -0
  619. package/themes/default/partials/comment-form.njk +109 -0
  620. package/themes/default/partials/contact-form.njk +88 -0
  621. package/themes/default/partials/conversation.njk +139 -0
  622. package/themes/default/partials/feeds.njk +26 -0
  623. package/themes/default/partials/jsonld.njk +120 -0
  624. package/themes/default/partials/pagination.njk +12 -6
  625. package/themes/default/partials/post-list.njk +51 -18
  626. package/themes/default/partials/search-form.njk +17 -0
  627. package/themes/default/partials/tags.njk +26 -5
  628. package/themes/default/static/highlight.js +4 -0
  629. package/themes/default/static/style.css +1119 -194
  630. package/themes/default/theme.json +5 -0
  631. package/admin/layouts/document-editor.njk +0 -167
  632. package/admin/layouts/federation.njk +0 -145
  633. package/admin/layouts/login.njk +0 -23
  634. package/admin/layouts/settings.njk +0 -116
  635. package/admin/layouts/setup.njk +0 -27
  636. package/admin/layouts/users.njk +0 -91
  637. /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
@@ -1,55 +1,109 @@
1
- import type { Context, RequestContext } from '@fedify/fedify';
2
- import { Application, Group, Organization, Person, Service } from '@fedify/vocab';
1
+ import type { Context, RequestContext, SenderKeyPair } from '@fedify/fedify';
3
2
  import type { Actor } from '@fedify/vocab';
4
- import type { SiteSettings } from '../admin/settings.ts';
5
- /**
6
- * The vocabulary class behind each of {@link ACTOR_TYPES}.
7
- *
8
- * The setting is a string, because it is a form field and a SQLite row; this
9
- * is where it becomes the class the actor document is built from.
10
- */
11
- export declare const ACTOR_CLASSES: {
12
- readonly Person: typeof Person;
13
- readonly Organization: typeof Organization;
14
- readonly Service: typeof Service;
15
- readonly Group: typeof Group;
16
- readonly Application: typeof Application;
17
- };
18
- /** What {@link siteActor} needs beyond the Fedify context. */
19
- export interface SiteActorOptions {
20
- /** The settings the profile is built from. */
21
- settings: SiteSettings;
22
- /**
23
- * The base URL actually in effect, which the settings' own may not be: it is
24
- * what the avatar's path is resolved against. Defaults to the setting.
25
- */
26
- baseUrl?: string | undefined;
27
- }
3
+ import type { User } from '../admin/accounts.ts';
28
4
  /**
29
- * The site's avatar as the absolute URL an `icon` carries, or `undefined` when
30
- * the site has none.
5
+ * A user as the fediverse sees them (decision-14).
31
6
  *
32
- * The setting holds what the upload endpoint handed back —
7
+ * Everything a peer reads about a person is built here, off one rule: an
8
+ * actor's id is decided once, in {@link actorId}, and every other id — the
9
+ * key, the multikey, the aliases, the `actor` of every activity — hangs off
10
+ * that same value rather than being spelled again. That is what lets a user
11
+ * published elsewhere be served under the id their followers already hold
12
+ * (decision-14) without a second spelling of anything.
13
+ */
14
+ /**
15
+ * One user by their username, or `undefined` when nobody has it.
16
+ *
17
+ * The username is the Fedify identifier (decision-14), so this is what every
18
+ * dispatcher and every inbox handler starts with: an identifier nobody answers
19
+ * to is `null` back to Fedify, which is a 404, rather than an empty collection.
20
+ */
21
+ export declare function userByUsername(dataDir: string, username: string): User | undefined;
22
+ /**
23
+ * An avatar as the absolute URL an `icon` carries, or `undefined` when there
24
+ * is none.
25
+ *
26
+ * A profile holds what the upload endpoint handed back —
33
27
  * `/uploads/2026/09/me.png` — because that is where the site serves the file
34
28
  * and where an Eleventy build of the same content copies it through to. A peer
35
29
  * reading the actor has no site to resolve that against, so it is made
36
- * absolute here. An avatar already given as an absolute URL is left alone.
30
+ * absolute here. One already given as an absolute URL is left alone.
37
31
  */
38
32
  export declare function avatarUrl(avatar: string, baseUrl: string): string | undefined;
39
33
  /**
40
- * The site's ActivityPub actor, as doc-4 describes it: one actor for the whole
41
- * site, whose profile fields are the settings.
34
+ * One user's ActivityStreams id.
35
+ *
36
+ * The author URL, which is what Fedify derives from the dispatcher path —
37
+ * unless the user's record carries the id they were published under somewhere
38
+ * else, in which case that is who they are (decision-14). A stored id is
39
+ * identity rather than cache: a follower's server keys the account by it, and
40
+ * answering under a different one would read as a different person rather than
41
+ * as the same person moved.
42
42
  *
43
- * Every URL comes from the Fedify context rather than from string
44
- * concatenation, so the ids stay in step with the paths the dispatchers are
45
- * registered under. The keys come from the key pairs dispatcher: `publicKey`
46
- * is the RSA one Mastodon verifies HTTP Signatures with, `assertionMethods`
47
- * are the multikeys FEP-8b32 proofs are checked against.
43
+ * This is the only place that choice is made, and every id built from it — the
44
+ * key id, the multikeys, the `actor` of every activity, the sender key pairs,
45
+ * the WebFinger `self` — follows from here without spelling the rule again
46
+ * (doc-8). What does *not* follow is `url`: the archive is still where a
47
+ * person is sent, and the actor's collections are still its dispatcher path's
48
+ * children, because those are cache and a peer refetches them.
48
49
  */
49
- export declare function siteActor(context: RequestContext<unknown> | Context<unknown>, identifier: string, options: SiteActorOptions): Promise<Actor>;
50
+ export declare function actorId(context: Context<unknown>, user: User): URL;
50
51
  /**
51
- * The class for an actor type, falling back to the default when the stored
52
- * setting is one this version does not know.
52
+ * The keys a user signs with, as the sender Fedify is handed.
53
+ *
54
+ * An explicit list rather than `{ identifier }`, which is the whole point:
55
+ * Fedify derives a key id from the dispatcher path and would go on doing so
56
+ * under a stored actor id, signing with a key id no peer could dereference.
57
+ * Built from {@link actorId} instead, so the `Signature-Input` header and the
58
+ * integrity proof name keys the actor document really publishes.
59
+ *
60
+ * The order is {@link ACTOR_KEY_ALGORITHMS}: RSA first, which Mastodon
61
+ * verifies HTTP Signatures with and which is `#main-key`; then Ed25519, whose
62
+ * multikey Fedify numbers `#multikey-1` because RSA took slot zero.
63
+ */
64
+ export declare function senderKeyPairs(context: Context<unknown>, user: User): Promise<SenderKeyPair[]>;
65
+ /**
66
+ * The id a signature names for one of an actor's keys.
67
+ *
68
+ * The RSA pair signs HTTP Signatures and is published as `publicKey`, which
69
+ * every peer looks for at `#main-key`; the rest sign FEP-8b32 proofs and are
70
+ * named by the multikey they are published as.
71
+ */
72
+ export declare function keyIdFor(id: URL, index: number): URL;
73
+ /** `{actor}#main-key`: the RSA key a peer verifies an HTTP Signature with. */
74
+ export declare function mainKeyId(id: URL): URL;
75
+ /**
76
+ * `{actor}#multikey-{n}`: one entry of `assertionMethod`.
77
+ *
78
+ * Fedify numbers its own multikeys in `ACTOR_KEY_ALGORITHMS` order, so RSA is
79
+ * 0 and Ed25519 is 1 (doc-8), and the numbering is kept because a peer that
80
+ * cached the document holds these ids.
81
+ */
82
+ export declare function multikeyId(id: URL, index: number): URL;
83
+ /** The three URLs a user answers to, which WebFinger and `alsoKnownAs` list. */
84
+ export declare function actorAliases(context: Context<unknown>, user: User, baseUrl: string): URL[];
85
+ /** What {@link userActor} needs beyond the Fedify context. */
86
+ export interface UserActorOptions {
87
+ /**
88
+ * The base URL actually in effect, which is what the archive URL and the
89
+ * avatar's path are resolved against.
90
+ */
91
+ baseUrl: string;
92
+ }
93
+ /**
94
+ * One user's ActivityPub actor, as decision-14 describes it.
95
+ *
96
+ * A `Person`, always: a user is a person, and the site is no longer an actor
97
+ * at all, so there is nothing left for the old `actorType` setting to choose
98
+ * between. The profile fields are exactly what the archive prints — the same
99
+ * {@link profileContext} a theme is handed — so the page and the actor cannot
100
+ * say different things about somebody.
101
+ *
102
+ * The keys are built by hand rather than taken from `getActorKeyPairs`, whose
103
+ * `cryptographicKey` and `multikey` carry ids Fedify derived from the
104
+ * dispatcher path. Under a stored actor id those would name keys the document
105
+ * does not publish, and a peer that cannot dereference the key id in a
106
+ * signature rejects the signature (doc-8).
53
107
  */
54
- export declare function actorClassFor(actorType: string): (typeof ACTOR_CLASSES)[keyof typeof ACTOR_CLASSES];
108
+ export declare function userActor(context: RequestContext<unknown> | Context<unknown>, user: User, options: UserActorOptions): Promise<Actor>;
55
109
  //# sourceMappingURL=actor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/federation/actor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAa,KAAK,EAAS,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;;;;CAMuD,CAAC;AAElF,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,QAAQ,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EACnD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,KAAK,CAAC,CA8BhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAChB,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAGpD"}
1
+ {"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/federation/actor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE7E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAKjD;;;;;;;;;GASG;AAEH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAElF;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,CAYlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EACzB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,aAAa,EAAE,CAAC,CAQ1B;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAEpD;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,EAAE,EAAE,GAAG,GAAG,GAAG,CAEtC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAEtD;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,EAAE,CAQ1F;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EACnD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,KAAK,CAAC,CAkEhB"}
@@ -1,28 +1,37 @@
1
- import { Application, Endpoints, Group, Image, Organization, Person, Service } from '@fedify/vocab';
2
- import { ACTOR_TYPES, DEFAULT_SITE_SETTINGS } from '../admin/settings.js';
1
+ import { CryptographicKey, Endpoints, Image, Multikey, Person, PropertyValue } from '@fedify/vocab';
2
+ import { listUsers } from '../admin/accounts.js';
3
+ import { authorHref, profileContext } from '../web/authors.js';
3
4
  import { absoluteUrl } from '../web/negotiate.js';
5
+ import { handleHref } from './paths.js';
4
6
  /**
5
- * The vocabulary class behind each of {@link ACTOR_TYPES}.
7
+ * A user as the fediverse sees them (decision-14).
6
8
  *
7
- * The setting is a string, because it is a form field and a SQLite row; this
8
- * is where it becomes the class the actor document is built from.
9
+ * Everything a peer reads about a person is built here, off one rule: an
10
+ * actor's id is decided once, in {@link actorId}, and every other id — the
11
+ * key, the multikey, the aliases, the `actor` of every activity — hangs off
12
+ * that same value rather than being spelled again. That is what lets a user
13
+ * published elsewhere be served under the id their followers already hold
14
+ * (decision-14) without a second spelling of anything.
9
15
  */
10
- export const ACTOR_CLASSES = {
11
- Person,
12
- Organization,
13
- Service,
14
- Group,
15
- Application,
16
- };
17
16
  /**
18
- * The site's avatar as the absolute URL an `icon` carries, or `undefined` when
19
- * the site has none.
17
+ * One user by their username, or `undefined` when nobody has it.
20
18
  *
21
- * The setting holds what the upload endpoint handed back —
19
+ * The username is the Fedify identifier (decision-14), so this is what every
20
+ * dispatcher and every inbox handler starts with: an identifier nobody answers
21
+ * to is `null` back to Fedify, which is a 404, rather than an empty collection.
22
+ */
23
+ export function userByUsername(dataDir, username) {
24
+ return listUsers(dataDir).find((user) => user.username === username);
25
+ }
26
+ /**
27
+ * An avatar as the absolute URL an `icon` carries, or `undefined` when there
28
+ * is none.
29
+ *
30
+ * A profile holds what the upload endpoint handed back —
22
31
  * `/uploads/2026/09/me.png` — because that is where the site serves the file
23
32
  * and where an Eleventy build of the same content copies it through to. A peer
24
33
  * reading the actor has no site to resolve that against, so it is made
25
- * absolute here. An avatar already given as an absolute URL is left alone.
34
+ * absolute here. One already given as an absolute URL is left alone.
26
35
  */
27
36
  export function avatarUrl(avatar, baseUrl) {
28
37
  const value = avatar.trim();
@@ -40,52 +49,170 @@ export function avatarUrl(avatar, baseUrl) {
40
49
  }
41
50
  }
42
51
  /**
43
- * The site's ActivityPub actor, as doc-4 describes it: one actor for the whole
44
- * site, whose profile fields are the settings.
52
+ * One user's ActivityStreams id.
53
+ *
54
+ * The author URL, which is what Fedify derives from the dispatcher path —
55
+ * unless the user's record carries the id they were published under somewhere
56
+ * else, in which case that is who they are (decision-14). A stored id is
57
+ * identity rather than cache: a follower's server keys the account by it, and
58
+ * answering under a different one would read as a different person rather than
59
+ * as the same person moved.
60
+ *
61
+ * This is the only place that choice is made, and every id built from it — the
62
+ * key id, the multikeys, the `actor` of every activity, the sender key pairs,
63
+ * the WebFinger `self` — follows from here without spelling the rule again
64
+ * (doc-8). What does *not* follow is `url`: the archive is still where a
65
+ * person is sent, and the actor's collections are still its dispatcher path's
66
+ * children, because those are cache and a peer refetches them.
67
+ */
68
+ export function actorId(context, user) {
69
+ const stored = user.actorId;
70
+ if (stored !== undefined) {
71
+ try {
72
+ return new URL(stored);
73
+ }
74
+ catch {
75
+ // Unreachable through the users file, which drops an id that is not a
76
+ // URL on the way in; a caller that built a `User` by hand falls back to
77
+ // the derived id rather than taking the actor down.
78
+ }
79
+ }
80
+ return context.getActorUri(user.username);
81
+ }
82
+ /**
83
+ * The keys a user signs with, as the sender Fedify is handed.
84
+ *
85
+ * An explicit list rather than `{ identifier }`, which is the whole point:
86
+ * Fedify derives a key id from the dispatcher path and would go on doing so
87
+ * under a stored actor id, signing with a key id no peer could dereference.
88
+ * Built from {@link actorId} instead, so the `Signature-Input` header and the
89
+ * integrity proof name keys the actor document really publishes.
90
+ *
91
+ * The order is {@link ACTOR_KEY_ALGORITHMS}: RSA first, which Mastodon
92
+ * verifies HTTP Signatures with and which is `#main-key`; then Ed25519, whose
93
+ * multikey Fedify numbers `#multikey-1` because RSA took slot zero.
94
+ */
95
+ export async function senderKeyPairs(context, user) {
96
+ const id = actorId(context, user);
97
+ const keys = await context.getActorKeyPairs(user.username);
98
+ return keys.map((key, index) => ({
99
+ keyId: keyIdFor(id, index),
100
+ privateKey: key.privateKey,
101
+ }));
102
+ }
103
+ /**
104
+ * The id a signature names for one of an actor's keys.
45
105
  *
46
- * Every URL comes from the Fedify context rather than from string
47
- * concatenation, so the ids stay in step with the paths the dispatchers are
48
- * registered under. The keys come from the key pairs dispatcher: `publicKey`
49
- * is the RSA one Mastodon verifies HTTP Signatures with, `assertionMethods`
50
- * are the multikeys FEP-8b32 proofs are checked against.
106
+ * The RSA pair signs HTTP Signatures and is published as `publicKey`, which
107
+ * every peer looks for at `#main-key`; the rest sign FEP-8b32 proofs and are
108
+ * named by the multikey they are published as.
51
109
  */
52
- export async function siteActor(context, identifier, options) {
53
- const { settings } = options;
54
- // The base URL in effect, which is what the profile's own URL and the
55
- // avatar's are built on; the setting is the fallback for a caller that has
56
- // no resolved config in hand.
57
- const baseUrl = options.baseUrl ?? settings.baseUrl;
58
- const icon = avatarUrl(settings.avatar, baseUrl);
59
- const keys = await context.getActorKeyPairs(identifier);
60
- const ActorClass = actorClassFor(settings.actorType);
61
- return new ActorClass({
62
- id: context.getActorUri(identifier),
63
- preferredUsername: settings.actorHandle,
64
- name: settings.title,
65
- summary: settings.tagline === '' ? null : settings.tagline,
66
- url: urlOrNull(baseUrl),
110
+ export function keyIdFor(id, index) {
111
+ return index === 0 ? mainKeyId(id) : multikeyId(id, index);
112
+ }
113
+ /** `{actor}#main-key`: the RSA key a peer verifies an HTTP Signature with. */
114
+ export function mainKeyId(id) {
115
+ return new URL(`${id.href}#main-key`, id);
116
+ }
117
+ /**
118
+ * `{actor}#multikey-{n}`: one entry of `assertionMethod`.
119
+ *
120
+ * Fedify numbers its own multikeys in `ACTOR_KEY_ALGORITHMS` order, so RSA is
121
+ * 0 and Ed25519 is 1 (doc-8), and the numbering is kept because a peer that
122
+ * cached the document holds these ids.
123
+ */
124
+ export function multikeyId(id, index) {
125
+ return new URL(`${id.href}#multikey-${String(index)}`, id);
126
+ }
127
+ /** The three URLs a user answers to, which WebFinger and `alsoKnownAs` list. */
128
+ export function actorAliases(context, user, baseUrl) {
129
+ const aliases = [
130
+ actorId(context, user),
131
+ new URL(absoluteUrl(handleHref(user.username), baseUrl)),
132
+ ];
133
+ const archive = new URL(absoluteUrl(authorHref(user.username), baseUrl));
134
+ if (!aliases.some((alias) => alias.href === archive.href))
135
+ aliases.splice(1, 0, archive);
136
+ return aliases;
137
+ }
138
+ /**
139
+ * One user's ActivityPub actor, as decision-14 describes it.
140
+ *
141
+ * A `Person`, always: a user is a person, and the site is no longer an actor
142
+ * at all, so there is nothing left for the old `actorType` setting to choose
143
+ * between. The profile fields are exactly what the archive prints — the same
144
+ * {@link profileContext} a theme is handed — so the page and the actor cannot
145
+ * say different things about somebody.
146
+ *
147
+ * The keys are built by hand rather than taken from `getActorKeyPairs`, whose
148
+ * `cryptographicKey` and `multikey` carry ids Fedify derived from the
149
+ * dispatcher path. Under a stored actor id those would name keys the document
150
+ * does not publish, and a peer that cannot dereference the key id in a
151
+ * signature rejects the signature (doc-8).
152
+ */
153
+ export async function userActor(context, user, options) {
154
+ const { baseUrl } = options;
155
+ const profile = profileContext(user);
156
+ const id = actorId(context, user);
157
+ const icon = profile.avatar === undefined ? undefined : avatarUrl(profile.avatar, baseUrl);
158
+ const keys = await context.getActorKeyPairs(user.username);
159
+ // Fedify catches whatever the key pairs dispatcher throws and hands back an
160
+ // empty list, so this is the only place a key file damaged since boot can be
161
+ // noticed. An actor document with no `publicKey` is worse than no answer: a
162
+ // peer caches it, and every signature that user makes fails to verify
163
+ // against what the peer holds. Failing the request keeps the last good
164
+ // document in the peer's cache instead.
165
+ if (keys.length === 0) {
166
+ throw new Error(`The actor ${user.username} has no usable key pairs. Its key files under the ` +
167
+ 'data directory could not be read; see the error the key loader raised. ' +
168
+ 'Restore them from a backup, or delete them to ask for new keys on purpose.');
169
+ }
170
+ const rsa = keys[0];
171
+ return new Person({
172
+ id,
173
+ preferredUsername: user.username,
174
+ name: profile.name,
175
+ summary: profile.bio ?? null,
176
+ url: new URL(absoluteUrl(authorHref(user.username), baseUrl)),
67
177
  icon: icon === undefined ? null : new Image({ url: new URL(icon) }),
68
- inbox: context.getInboxUri(identifier),
69
- outbox: context.getOutboxUri(identifier),
70
- followers: context.getFollowersUri(identifier),
71
- following: context.getFollowingUri(identifier),
178
+ inbox: context.getInboxUri(user.username),
179
+ outbox: context.getOutboxUri(user.username),
180
+ followers: context.getFollowersUri(user.username),
181
+ following: context.getFollowingUri(user.username),
72
182
  endpoints: new Endpoints({ sharedInbox: context.getInboxUri() }),
73
- publicKey: keys[0]?.cryptographicKey ?? null,
74
- assertionMethods: keys.map((key) => key.multikey),
75
- // A blog actor accepts every follower, and says so, rather than leaving a
76
- // client to guess whether a follow will ever be answered.
183
+ // Every URL this person answers to, which is what a peer reads to know
184
+ // that two ids are one account. WordPress's plugin publishes exactly this
185
+ // list, and `@fedify/vocab` serialises it as `alsoKnownAs`.
186
+ aliases: actorAliases(context, user, baseUrl),
187
+ publicKey: rsa === undefined
188
+ ? null
189
+ : new CryptographicKey({
190
+ id: mainKeyId(id),
191
+ owner: id,
192
+ publicKey: rsa.publicKey,
193
+ }),
194
+ assertionMethods: keys.map((key, index) => new Multikey({ id: multikeyId(id, index), controller: id, publicKey: key.publicKey })),
195
+ // Somewhere else this person is, as the property attachments every
196
+ // fediverse client renders under a profile.
197
+ attachments: (profile.links ?? []).map((link) => new PropertyValue({
198
+ name: link.label,
199
+ value: `<a href="${escapeHtml(link.href)}" rel="me nofollow noopener">${escapeHtml(link.href)}</a>`,
200
+ })),
201
+ // A blog's author accepts every follower, and says so, rather than leaving
202
+ // a client to guess whether a follow will ever be answered.
77
203
  manuallyApprovesFollowers: false,
78
204
  discoverable: true,
79
205
  indexable: true,
80
206
  });
81
207
  }
82
- /**
83
- * The class for an actor type, falling back to the default when the stored
84
- * setting is one this version does not know.
85
- */
86
- export function actorClassFor(actorType) {
87
- const known = ACTOR_TYPES.includes(actorType) ? actorType : DEFAULT_SITE_SETTINGS.actorType;
88
- return ACTOR_CLASSES[known] ?? Person;
208
+ /** The five characters that cannot travel unescaped inside an attribute. */
209
+ function escapeHtml(value) {
210
+ return value
211
+ .replaceAll('&', '&amp;')
212
+ .replaceAll('<', '&lt;')
213
+ .replaceAll('>', '&gt;')
214
+ .replaceAll('"', '&quot;')
215
+ .replaceAll("'", '&#39;');
89
216
  }
90
217
  /** A URL, or `null` when the string is empty or is not one. */
91
218
  function urlOrNull(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"actor.js","sourceRoot":"","sources":["../../src/federation/actor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actor.js","sourceRoot":"","sources":["../../src/federation/actor.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,51 @@
1
1
  import type { Context } from '@fedify/fedify';
2
2
  import { Article, Create, Delete, Update } from '@fedify/vocab';
3
+ import type { User } from '../admin/accounts.ts';
3
4
  import type { Document } from '../content/document.ts';
4
5
  import type { FederationContextData } from './federation.ts';
6
+ /**
7
+ * The user a post is announced by: the one its `author` names, and the site's
8
+ * first account for one that names nobody.
9
+ *
10
+ * decision-14 attributes a post to a person rather than to the site, and
11
+ * `userForAuthor` is the one rule that decides which — a username exactly, a
12
+ * display name only when exactly one person answers to it (TASK-67). The
13
+ * fallback matters because an `author` is free text in a file: a post that
14
+ * names a person who has since been deleted, or names nobody at all, is still
15
+ * a post this site has to be able to announce, and the first account is the
16
+ * only actor that can be chosen without guessing between people.
17
+ *
18
+ * `undefined` only for a site with no accounts, which is one in first-run
19
+ * setup and federates nothing.
20
+ */
21
+ export declare function documentAuthor(context: Context<FederationContextData>, document: Document): User | undefined;
5
22
  /** The media type an `Article`'s `source` is labelled with. */
6
23
  export declare const SOURCE_MEDIA_TYPE = "text/markdown";
7
24
  /**
8
25
  * Whether a document is one of the objects this site federates.
9
26
  *
10
27
  * doc-4 federates published posts and nothing else: pages are standing
11
- * content with no place in a timeline, and a draft or a trashed post is not
12
- * public at all. This is the one rule, so the object dispatcher, the outbox
13
- * and the permalink all agree about what exists.
28
+ * content with no place in a timeline, and a draft, a trashed post or one
29
+ * whose date has not arrived is not public at all. This is the one rule, so
30
+ * the object dispatcher, the outbox and the permalink all agree about what
31
+ * exists.
14
32
  */
15
- export declare function isFederatedDocument(document: Document): boolean;
33
+ export declare function isFederatedDocument(document: Document, now?: Date): boolean;
16
34
  /**
17
35
  * One post as the `Article` doc-4 describes.
18
36
  *
19
- * The id comes from the Fedify context rather than from string concatenation,
20
- * so it stays in step with the path the object dispatcher is registered under,
21
- * and it is built from the slug rather than from the permalink, so moving a
22
- * post does not mint a second object. `url` is the permalink, which is the
23
- * page a human should land on.
37
+ * Its `id` and its `url` are the same URL — the permalink — because
38
+ * decision-13 gives a post one name for both audiences: a browser asking for
39
+ * HTML gets the page, a peer asking for ActivityStreams gets this. The
40
+ * exception is a post whose file already names an `activitypub.id`, which
41
+ * keeps it; see {@link articleObjectId}.
24
42
  *
25
43
  * `source` carries the Markdown the file holds, so a peer that wants to quote
26
44
  * or re-render the post has the text rather than only the rendering of it.
45
+ *
46
+ * `attributedTo` is the actor of the user the post's `author` names
47
+ * (decision-14), and `cc` is that user's followers: a post belongs to a person
48
+ * on this site, not to the site.
27
49
  */
28
50
  export declare function postArticle(context: Context<FederationContextData>, document: Document): Article;
29
51
  /**
@@ -42,8 +64,14 @@ export declare function postCreateActivity(context: Context<FederationContextDat
42
64
  * ActivityPub offers and all a peer can apply. Its id carries the document's
43
65
  * hash, so two edits are two activities and the same edit delivered twice is
44
66
  * one; see {@link updateActivityId}.
67
+ *
68
+ * `revision` overrides that. A resend (decision-9) is asking for a revision
69
+ * the followers have already been offered to be offered again, and an activity
70
+ * id a peer has seen is one it is entitled to drop, so a resend passes the
71
+ * moment instead of the hash. Everything else about the activity is the same,
72
+ * which is what makes a resent `Update` and a saved one the same shape.
45
73
  */
46
- export declare function postUpdateActivity(context: Context<FederationContextData>, document: Document): Update;
74
+ export declare function postUpdateActivity(context: Context<FederationContextData>, document: Document, revision?: string): Update;
47
75
  /**
48
76
  * The `Delete` that withdraws a post: a `Tombstone` where the `Article` was.
49
77
  *
@@ -58,14 +86,13 @@ export declare function postUpdateActivity(context: Context<FederationContextDat
58
86
  */
59
87
  export declare function postDeleteActivity(context: Context<FederationContextData>, document: Document, deleted: string): Delete;
60
88
  /**
61
- * A post's ActivityStreams object id: the one written into its front matter if
62
- * it has been federated, and the one its slug implies if it has not.
89
+ * A post's ActivityStreams object id, off the Fedify context: its permalink,
90
+ * or the id its file already names (decision-13).
63
91
  *
64
- * The stored id is what makes a rename invisible to a follower. Ids are minted
65
- * from the slug, so a post renamed after it was announced would otherwise
66
- * become a second object and be delivered as a `Create` all over again; doc-4
67
- * asks the `activitypub.id` key to prevent exactly that. The object dispatcher
68
- * resolves a stored id back to its post, so the old URL keeps answering.
92
+ * A thin wrapper over {@link postObjectId} so everything in this module reads
93
+ * the id the same way and off the same base URL the article's `url` is built
94
+ * on. The rule itself lives in `web/documents.ts`, because the page, the feed
95
+ * item and the object are one identity now rather than three.
69
96
  */
70
97
  export declare function articleObjectId(context: Context<FederationContextData>, document: Document): URL;
71
98
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"article.d.ts","sourceRoot":"","sources":["../../src/federation/article.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,OAAO,EACP,MAAM,EACN,MAAM,EAKN,MAAM,EACP,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAI7D,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAwBhG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAWR;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAWR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAcR;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAWhG;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,OAAO,GAAG,SAAS,CAOjF"}
1
+ {"version":3,"file":"article.d.ts","sourceRoot":"","sources":["../../src/federation/article.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,OAAO,EACP,MAAM,EACN,MAAM,EAKN,MAAM,EACP,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAMvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,GACjB,IAAI,GAAG,SAAS,CAGlB;AAwBD,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAEvF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CA8BhG;AAOD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAYR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,GAAE,MAA6B,GACtC,MAAM,CAYR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAeR;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAEhG;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,OAAO,GAAG,SAAS,CAOjF"}