@geekity/cms 0.3.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 (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +870 -0
  3. package/admin/layouts/_flash.njk +5 -0
  4. package/admin/layouts/base.njk +27 -0
  5. package/admin/layouts/dashboard.njk +78 -0
  6. package/admin/layouts/document-conflict.njk +49 -0
  7. package/admin/layouts/document-editor.njk +167 -0
  8. package/admin/layouts/document-list.njk +92 -0
  9. package/admin/layouts/federation.njk +145 -0
  10. package/admin/layouts/login.njk +23 -0
  11. package/admin/layouts/placeholder.njk +10 -0
  12. package/admin/layouts/settings.njk +116 -0
  13. package/admin/layouts/setup.njk +27 -0
  14. package/admin/layouts/shell.njk +37 -0
  15. package/admin/layouts/users.njk +91 -0
  16. package/admin/static/admin.css +726 -0
  17. package/admin/static/editor.js +30 -0
  18. package/dist/admin/assets.d.ts +26 -0
  19. package/dist/admin/assets.d.ts.map +1 -0
  20. package/dist/admin/assets.js +38 -0
  21. package/dist/admin/assets.js.map +1 -0
  22. package/dist/admin/credentials.d.ts +28 -0
  23. package/dist/admin/credentials.d.ts.map +1 -0
  24. package/dist/admin/credentials.js +39 -0
  25. package/dist/admin/credentials.js.map +1 -0
  26. package/dist/admin/documents.d.ts +134 -0
  27. package/dist/admin/documents.d.ts.map +1 -0
  28. package/dist/admin/documents.js +613 -0
  29. package/dist/admin/documents.js.map +1 -0
  30. package/dist/admin/federation.d.ts +194 -0
  31. package/dist/admin/federation.d.ts.map +1 -0
  32. package/dist/admin/federation.js +299 -0
  33. package/dist/admin/federation.js.map +1 -0
  34. package/dist/admin/flash.d.ts +24 -0
  35. package/dist/admin/flash.d.ts.map +1 -0
  36. package/dist/admin/flash.js +31 -0
  37. package/dist/admin/flash.js.map +1 -0
  38. package/dist/admin/index.d.ts +23 -0
  39. package/dist/admin/index.d.ts.map +1 -0
  40. package/dist/admin/index.js +15 -0
  41. package/dist/admin/index.js.map +1 -0
  42. package/dist/admin/passwords.d.ts +49 -0
  43. package/dist/admin/passwords.d.ts.map +1 -0
  44. package/dist/admin/passwords.js +122 -0
  45. package/dist/admin/passwords.js.map +1 -0
  46. package/dist/admin/preview.d.ts +18 -0
  47. package/dist/admin/preview.d.ts.map +1 -0
  48. package/dist/admin/preview.js +83 -0
  49. package/dist/admin/preview.js.map +1 -0
  50. package/dist/admin/routes.d.ts +54 -0
  51. package/dist/admin/routes.d.ts.map +1 -0
  52. package/dist/admin/routes.js +383 -0
  53. package/dist/admin/routes.js.map +1 -0
  54. package/dist/admin/session.d.ts +44 -0
  55. package/dist/admin/session.d.ts.map +1 -0
  56. package/dist/admin/session.js +69 -0
  57. package/dist/admin/session.js.map +1 -0
  58. package/dist/admin/settings.d.ts +194 -0
  59. package/dist/admin/settings.d.ts.map +1 -0
  60. package/dist/admin/settings.js +470 -0
  61. package/dist/admin/settings.js.map +1 -0
  62. package/dist/admin/store.d.ts +407 -0
  63. package/dist/admin/store.d.ts.map +1 -0
  64. package/dist/admin/store.js +704 -0
  65. package/dist/admin/store.js.map +1 -0
  66. package/dist/admin/templates.d.ts +36 -0
  67. package/dist/admin/templates.d.ts.map +1 -0
  68. package/dist/admin/templates.js +43 -0
  69. package/dist/admin/templates.js.map +1 -0
  70. package/dist/admin/uploads.d.ts +96 -0
  71. package/dist/admin/uploads.d.ts.map +1 -0
  72. package/dist/admin/uploads.js +179 -0
  73. package/dist/admin/uploads.js.map +1 -0
  74. package/dist/admin/users.d.ts +95 -0
  75. package/dist/admin/users.d.ts.map +1 -0
  76. package/dist/admin/users.js +233 -0
  77. package/dist/admin/users.js.map +1 -0
  78. package/dist/cli.d.ts +85 -0
  79. package/dist/cli.d.ts.map +1 -0
  80. package/dist/cli.js +424 -0
  81. package/dist/cli.js.map +1 -0
  82. package/dist/config.d.ts +172 -0
  83. package/dist/config.d.ts.map +1 -0
  84. package/dist/config.js +184 -0
  85. package/dist/config.js.map +1 -0
  86. package/dist/content/document.d.ts +66 -0
  87. package/dist/content/document.d.ts.map +1 -0
  88. package/dist/content/document.js +13 -0
  89. package/dist/content/document.js.map +1 -0
  90. package/dist/content/index.d.ts +17 -0
  91. package/dist/content/index.d.ts.map +1 -0
  92. package/dist/content/index.js +10 -0
  93. package/dist/content/index.js.map +1 -0
  94. package/dist/content/markdown.d.ts +3 -0
  95. package/dist/content/markdown.d.ts.map +1 -0
  96. package/dist/content/markdown.js +39 -0
  97. package/dist/content/markdown.js.map +1 -0
  98. package/dist/content/media.d.ts +65 -0
  99. package/dist/content/media.d.ts.map +1 -0
  100. package/dist/content/media.js +143 -0
  101. package/dist/content/media.js.map +1 -0
  102. package/dist/content/parser.d.ts +24 -0
  103. package/dist/content/parser.d.ts.map +1 -0
  104. package/dist/content/parser.js +165 -0
  105. package/dist/content/parser.js.map +1 -0
  106. package/dist/content/save.d.ts +60 -0
  107. package/dist/content/save.d.ts.map +1 -0
  108. package/dist/content/save.js +103 -0
  109. package/dist/content/save.js.map +1 -0
  110. package/dist/content/slug.d.ts +25 -0
  111. package/dist/content/slug.d.ts.map +1 -0
  112. package/dist/content/slug.js +75 -0
  113. package/dist/content/slug.js.map +1 -0
  114. package/dist/content/store.d.ts +133 -0
  115. package/dist/content/store.d.ts.map +1 -0
  116. package/dist/content/store.js +411 -0
  117. package/dist/content/store.js.map +1 -0
  118. package/dist/content/sync.d.ts +146 -0
  119. package/dist/content/sync.d.ts.map +1 -0
  120. package/dist/content/sync.js +421 -0
  121. package/dist/content/sync.js.map +1 -0
  122. package/dist/content/writer.d.ts +37 -0
  123. package/dist/content/writer.d.ts.map +1 -0
  124. package/dist/content/writer.js +97 -0
  125. package/dist/content/writer.js.map +1 -0
  126. package/dist/env.d.ts +48 -0
  127. package/dist/env.d.ts.map +1 -0
  128. package/dist/env.js +2 -0
  129. package/dist/env.js.map +1 -0
  130. package/dist/federation/actor.d.ts +55 -0
  131. package/dist/federation/actor.d.ts.map +1 -0
  132. package/dist/federation/actor.js +101 -0
  133. package/dist/federation/actor.js.map +1 -0
  134. package/dist/federation/article.d.ts +83 -0
  135. package/dist/federation/article.d.ts.map +1 -0
  136. package/dist/federation/article.js +169 -0
  137. package/dist/federation/article.js.map +1 -0
  138. package/dist/federation/delivery.d.ts +90 -0
  139. package/dist/federation/delivery.d.ts.map +1 -0
  140. package/dist/federation/delivery.js +289 -0
  141. package/dist/federation/delivery.js.map +1 -0
  142. package/dist/federation/federation.d.ts +75 -0
  143. package/dist/federation/federation.d.ts.map +1 -0
  144. package/dist/federation/federation.js +190 -0
  145. package/dist/federation/federation.js.map +1 -0
  146. package/dist/federation/followers.d.ts +43 -0
  147. package/dist/federation/followers.d.ts.map +1 -0
  148. package/dist/federation/followers.js +69 -0
  149. package/dist/federation/followers.js.map +1 -0
  150. package/dist/federation/inbox.d.ts +68 -0
  151. package/dist/federation/inbox.d.ts.map +1 -0
  152. package/dist/federation/inbox.js +171 -0
  153. package/dist/federation/inbox.js.map +1 -0
  154. package/dist/federation/index.d.ts +14 -0
  155. package/dist/federation/index.d.ts.map +1 -0
  156. package/dist/federation/index.js +10 -0
  157. package/dist/federation/index.js.map +1 -0
  158. package/dist/federation/keys.d.ts +27 -0
  159. package/dist/federation/keys.d.ts.map +1 -0
  160. package/dist/federation/keys.js +60 -0
  161. package/dist/federation/keys.js.map +1 -0
  162. package/dist/federation/mount.d.ts +23 -0
  163. package/dist/federation/mount.d.ts.map +1 -0
  164. package/dist/federation/mount.js +71 -0
  165. package/dist/federation/mount.js.map +1 -0
  166. package/dist/federation/paths.d.ts +85 -0
  167. package/dist/federation/paths.d.ts.map +1 -0
  168. package/dist/federation/paths.js +97 -0
  169. package/dist/federation/paths.js.map +1 -0
  170. package/dist/index.d.ts +106 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +148 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/init.d.ts +71 -0
  175. package/dist/init.d.ts.map +1 -0
  176. package/dist/init.js +125 -0
  177. package/dist/init.js.map +1 -0
  178. package/dist/web/assets.d.ts +65 -0
  179. package/dist/web/assets.d.ts.map +1 -0
  180. package/dist/web/assets.js +152 -0
  181. package/dist/web/assets.js.map +1 -0
  182. package/dist/web/context.d.ts +121 -0
  183. package/dist/web/context.d.ts.map +1 -0
  184. package/dist/web/context.js +112 -0
  185. package/dist/web/context.js.map +1 -0
  186. package/dist/web/documents.d.ts +28 -0
  187. package/dist/web/documents.d.ts.map +1 -0
  188. package/dist/web/documents.js +39 -0
  189. package/dist/web/documents.js.map +1 -0
  190. package/dist/web/feeds.d.ts +122 -0
  191. package/dist/web/feeds.d.ts.map +1 -0
  192. package/dist/web/feeds.js +229 -0
  193. package/dist/web/feeds.js.map +1 -0
  194. package/dist/web/index.d.ts +17 -0
  195. package/dist/web/index.d.ts.map +1 -0
  196. package/dist/web/index.js +10 -0
  197. package/dist/web/index.js.map +1 -0
  198. package/dist/web/negotiate.d.ts +219 -0
  199. package/dist/web/negotiate.d.ts.map +1 -0
  200. package/dist/web/negotiate.js +409 -0
  201. package/dist/web/negotiate.js.map +1 -0
  202. package/dist/web/pagination.d.ts +48 -0
  203. package/dist/web/pagination.d.ts.map +1 -0
  204. package/dist/web/pagination.js +30 -0
  205. package/dist/web/pagination.js.map +1 -0
  206. package/dist/web/render.d.ts +72 -0
  207. package/dist/web/render.d.ts.map +1 -0
  208. package/dist/web/render.js +73 -0
  209. package/dist/web/render.js.map +1 -0
  210. package/dist/web/routes.d.ts +31 -0
  211. package/dist/web/routes.d.ts.map +1 -0
  212. package/dist/web/routes.js +366 -0
  213. package/dist/web/routes.js.map +1 -0
  214. package/dist/web/templates.d.ts +34 -0
  215. package/dist/web/templates.d.ts.map +1 -0
  216. package/dist/web/templates.js +106 -0
  217. package/dist/web/templates.js.map +1 -0
  218. package/package.json +68 -0
  219. package/templates/site/content/_data/site.json +8 -0
  220. package/templates/site/content/pages/about.md +11 -0
  221. package/templates/site/content/pages/pages.json +3 -0
  222. package/templates/site/content/posts/2026-01-01-hello-world.md +34 -0
  223. package/templates/site/content/posts/posts.json +4 -0
  224. package/templates/site/geekity.config.ts +11 -0
  225. package/templates/site/gitignore +3 -0
  226. package/templates/site/server.ts +20 -0
  227. package/templates/site/tsconfig.json +18 -0
  228. package/themes/default/README.md +148 -0
  229. package/themes/default/layouts/404.njk +9 -0
  230. package/themes/default/layouts/base.njk +59 -0
  231. package/themes/default/layouts/home.njk +9 -0
  232. package/themes/default/layouts/page.njk +13 -0
  233. package/themes/default/layouts/post.njk +30 -0
  234. package/themes/default/layouts/tag.njk +19 -0
  235. package/themes/default/partials/pagination.njk +14 -0
  236. package/themes/default/partials/post-list.njk +24 -0
  237. package/themes/default/partials/tags.njk +12 -0
  238. package/themes/default/static/style.css +327 -0
@@ -0,0 +1,194 @@
1
+ import type { Hono } from 'hono';
2
+ import type { ContentStore } from '../content/store.ts';
3
+ import type { GeekityEnv } from '../env.ts';
4
+ import type { DeliveryReport } from '../federation/delivery.ts';
5
+ import type { AdminRender } from './documents.ts';
6
+ import type { SiteSettings } from './settings.ts';
7
+ import type { DeliveryStatus, Follower, InboxActivity, OutboundActivity } from './store.ts';
8
+ /** Where the federation screen lives. */
9
+ export declare const FEDERATION_PATH = "/admin/federation";
10
+ /** Where a post's Redeliver button posts. */
11
+ export declare const REDELIVER_PATH = "/admin/federation/redeliver";
12
+ /** The field the Redeliver form submits. */
13
+ export declare const FEDERATION_FIELDS: {
14
+ readonly activityId: 'activity_id';
15
+ };
16
+ /**
17
+ * How many rows each of the screen's lists holds.
18
+ *
19
+ * One number for all of them, because the screen is a look at what is
20
+ * happening now rather than an archive: the store pages, and a site that wants
21
+ * the whole log has `cms.admin` to read it with.
22
+ */
23
+ export declare const FEDERATION_RECENT = 50;
24
+ /** What {@link mountFederationScreen} needs from the admin around it. */
25
+ export interface MountFederationScreenOptions {
26
+ /** The admin's renderer, which injects the chrome, the CSRF token and the flash. */
27
+ render: AdminRender;
28
+ }
29
+ /**
30
+ * Register `/admin/federation`: who the site is to the fediverse, who follows
31
+ * it, what arrived in the inbox, and how the posts that went out landed.
32
+ *
33
+ * Everything on it is read out of SQLite rather than fetched: doc-4 keeps the
34
+ * followers, the inbox log and the delivery log there precisely so the admin
35
+ * can show them without dereferencing a remote actor per row.
36
+ */
37
+ export declare function mountFederationScreen(app: Hono<GeekityEnv>, options: MountFederationScreenOptions): void;
38
+ /**
39
+ * What a redelivery came to, in one line.
40
+ *
41
+ * The failures are counted even when there are none, because that zero is the
42
+ * answer to the question the button was pressed to ask.
43
+ */
44
+ export declare function redeliveryMessage(report: DeliveryReport): string;
45
+ /** One post that has been federated, and how its latest activity landed. */
46
+ export interface DeliveryRow {
47
+ /** The post, or its slug when the file has since gone. */
48
+ readonly post: LocalPost;
49
+ /** The activity the Redeliver button would send. */
50
+ readonly activityId: string;
51
+ /** `Create`, `Update` or `Delete`. */
52
+ readonly activityType: string;
53
+ /** When that activity was first built. */
54
+ readonly createdAt: string;
55
+ /** How many followers it reached, is still queued for, and failed for. */
56
+ readonly counts: Record<DeliveryStatus, number>;
57
+ }
58
+ /** What {@link deliveryRows} needs to fill a row in. */
59
+ export interface DeliveryRowsContext {
60
+ /** How one activity's deliveries ended, by status. */
61
+ readonly counts: (activityId: string) => Record<DeliveryStatus, number>;
62
+ /** Resolve one of the site's ActivityStreams object ids to a post. */
63
+ readonly post: (objectId: string | null) => LocalPost | null;
64
+ }
65
+ /**
66
+ * One row per post, holding the newest activity that post has: what the screen
67
+ * shows and what its Redeliver button sends.
68
+ *
69
+ * A post is usually several activities — a `Create` and every `Update` since —
70
+ * and listing all of them would make the panel a log rather than a status. The
71
+ * newest is the one that matters, because it is the version a follower who
72
+ * missed everything is owed. The activities arrive newest first, so the first
73
+ * one seen for an object is that one.
74
+ */
75
+ export declare function deliveryRows(activities: readonly OutboundActivity[], context: DeliveryRowsContext): DeliveryRow[];
76
+ /** The site's own actor, as the top of the screen describes it. */
77
+ export interface ActorSummary {
78
+ /** `@handle@host`, the way somebody would type it into a search box. */
79
+ readonly handle: string;
80
+ /** `Person` or `Service`. */
81
+ readonly type: string;
82
+ /** The display name, which is the site title. */
83
+ readonly name: string;
84
+ /** The summary, which is the tagline. May be empty. */
85
+ readonly summary: string;
86
+ /** The actor's ActivityStreams id, which is also where it is served. */
87
+ readonly actorId: string;
88
+ /** The profile a human would open, which is the site itself. */
89
+ readonly url: string;
90
+ /**
91
+ * The avatar the actor's `icon` carries, absolute, or `null` when the site
92
+ * has none — which is what the screen draws a placeholder for.
93
+ */
94
+ readonly avatarUrl: string | null;
95
+ /** How many actors follow it. */
96
+ readonly followers: number;
97
+ }
98
+ /**
99
+ * The site's actor as the screen shows it.
100
+ *
101
+ * The handle's host and the actor's id both come from the base URL's origin
102
+ * rather than from the whole of it, because that is where the federation
103
+ * endpoints are served: a site under `/blog` is still `@blog@example.com`.
104
+ */
105
+ export declare function actorSummary(settings: SiteSettings, context: {
106
+ /** The base URL actually in effect, which the settings' own may not be. */
107
+ baseUrl: string;
108
+ followers: number;
109
+ }): ActorSummary;
110
+ /**
111
+ * The inbox types the screen shows, and the word each of them reads as.
112
+ *
113
+ * The follow traffic is deliberately not here. `Follow`, `Undo` and `Delete`
114
+ * are already in the log because doc-4 records everything the inbox was told,
115
+ * but their effect is the follower list a few centimetres up the page: showing
116
+ * them again would bury the three things that have nowhere else to appear.
117
+ */
118
+ export declare const INBOX_INTERACTIONS: Readonly<Record<string, string>>;
119
+ /** One inbound interaction, as the list renders it. */
120
+ export interface InboxRow {
121
+ /** The log's row id, which is also the order things arrived in. */
122
+ readonly id: number;
123
+ /** `Like`, `Announce` or `Create`. */
124
+ readonly type: string;
125
+ /** What that type reads as: "liked", "boosted", "replied to". */
126
+ readonly action: string;
127
+ /** Who did it. */
128
+ readonly actorId: string;
129
+ /** Their name or handle when they follow the site, else their id. */
130
+ readonly actorLabel: string;
131
+ /** When it arrived. */
132
+ readonly receivedAt: string;
133
+ /**
134
+ * Where the remote thing lives: the reply itself, or the activity that
135
+ * carried the like or the boost. `null` when it arrived without an id.
136
+ */
137
+ readonly remoteUrl: string | null;
138
+ /** The site's own post it was about, when it was about one. */
139
+ readonly post: LocalPost | null;
140
+ }
141
+ /** One of the site's posts, as an inbound activity or a delivery names it. */
142
+ export interface LocalPost {
143
+ readonly slug: string;
144
+ /** The post's title, or its slug when the file is no longer there. */
145
+ readonly title: string;
146
+ /** Where its editor is. */
147
+ readonly editUrl: string;
148
+ }
149
+ /** What {@link inboxRows} needs to turn ids into names. */
150
+ export interface InboxRowsContext {
151
+ /** The site's followers, so a familiar actor is shown by name. */
152
+ readonly followers: readonly Follower[];
153
+ /** Resolve one of the site's ActivityStreams object ids to a post. */
154
+ readonly post: (objectId: string | null) => LocalPost | null;
155
+ }
156
+ /**
157
+ * The inbox log as the screen's "recent activity" list, newest first.
158
+ *
159
+ * Only {@link INBOX_INTERACTIONS} survive, and only as much of each row as the
160
+ * screen shows: doc-4 stores the whole JSON-LD because it could not know what
161
+ * a later phase would want, and this is that phase deciding.
162
+ */
163
+ export declare function inboxRows(activities: readonly InboxActivity[], context: InboxRowsContext): InboxRow[];
164
+ /**
165
+ * Resolve one of the site's own ActivityStreams ids to the post behind it.
166
+ *
167
+ * An id from anywhere else — a like of somebody else's post that reached the
168
+ * shared inbox, a reply to a reply — is `null` rather than a guess, and so is
169
+ * one whose slug the index has never heard of.
170
+ */
171
+ export declare function localPosts(store: ContentStore, baseUrl: string): (objectId: string | null) => LocalPost | null;
172
+ /** One follower, as the table renders it. */
173
+ export interface FollowerRow {
174
+ readonly actorId: string;
175
+ /** The display name, or the handle, or the id: whichever the actor gave. */
176
+ readonly name: string;
177
+ /** `@name@host`, or the id when the actor published no username. */
178
+ readonly handle: string;
179
+ /** The avatar, or `null` for the initial the template draws instead. */
180
+ readonly iconUrl: string | null;
181
+ /** Where a click on the row goes: the actor's profile, else its id. */
182
+ readonly url: string;
183
+ readonly followedAt: string;
184
+ }
185
+ /**
186
+ * One stored follower as the screen shows it.
187
+ *
188
+ * Every display column is nullable, because they are a copy of what the actor
189
+ * said about itself and an actor need say none of it. The id is the fallback
190
+ * for all of them: it is the one thing a follower always has, and it is
191
+ * usually legible enough to recognise an instance by.
192
+ */
193
+ export declare function followerRow(follower: Follower): FollowerRow;
194
+ //# sourceMappingURL=federation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.d.ts","sourceRoot":"","sources":["../../src/admin/federation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,299 @@
1
+ import { avatarUrl } from '../federation/actor.js';
2
+ import { SITE_ACTOR_IDENTIFIER } from '../federation/keys.js';
3
+ import { ACTOR_PATH, federationOrigin, FEDERATION_PREFIX } from '../federation/paths.js';
4
+ import { editorPath, POST_KIND } from './documents.js';
5
+ import { flash } from './flash.js';
6
+ import { readSiteSettings } from './settings.js';
7
+ import { ADMIN_PREFIX } from './session.js';
8
+ import { ADMIN_TEMPLATES } from './templates.js';
9
+ /** Where the federation screen lives. */
10
+ export const FEDERATION_PATH = `${ADMIN_PREFIX}/federation`;
11
+ /** Where a post's Redeliver button posts. */
12
+ export const REDELIVER_PATH = `${FEDERATION_PATH}/redeliver`;
13
+ /** The field the Redeliver form submits. */
14
+ export const FEDERATION_FIELDS = { activityId: 'activity_id' };
15
+ /**
16
+ * How many rows each of the screen's lists holds.
17
+ *
18
+ * One number for all of them, because the screen is a look at what is
19
+ * happening now rather than an archive: the store pages, and a site that wants
20
+ * the whole log has `cms.admin` to read it with.
21
+ */
22
+ export const FEDERATION_RECENT = 50;
23
+ /**
24
+ * Register `/admin/federation`: who the site is to the fediverse, who follows
25
+ * it, what arrived in the inbox, and how the posts that went out landed.
26
+ *
27
+ * Everything on it is read out of SQLite rather than fetched: doc-4 keeps the
28
+ * followers, the inbox log and the delivery log there precisely so the admin
29
+ * can show them without dereferencing a remote actor per row.
30
+ */
31
+ export function mountFederationScreen(app, options) {
32
+ const { render } = options;
33
+ app.get(FEDERATION_PATH, (c) => {
34
+ const admin = c.var.admin;
35
+ const baseUrl = c.var.config.baseUrl;
36
+ const post = localPosts(c.var.store, baseUrl);
37
+ return render(c, ADMIN_TEMPLATES.federation, {
38
+ section: 'federation',
39
+ redeliverUrl: REDELIVER_PATH,
40
+ fields: FEDERATION_FIELDS,
41
+ actor: actorSummary(readSiteSettings(admin), {
42
+ baseUrl,
43
+ followers: admin.countFollowers(),
44
+ }),
45
+ followers: admin
46
+ .listFollowers({ limit: FEDERATION_RECENT })
47
+ .map((follower) => followerRow(follower)),
48
+ // The inbox log holds the follow traffic as well, and only a fraction of
49
+ // it survives {@link inboxRows}, so more is read than is shown.
50
+ inbox: inboxRows(admin.listInboxActivities({ limit: FEDERATION_RECENT * 4 }), {
51
+ followers: admin.listFollowers(),
52
+ post,
53
+ }),
54
+ posts: deliveryRows(admin.listOutboundActivities({ limit: FEDERATION_RECENT * 4 }), {
55
+ counts: (activityId) => admin.countDeliveriesByStatus(activityId),
56
+ post,
57
+ }).slice(0, FEDERATION_RECENT),
58
+ });
59
+ });
60
+ /**
61
+ * Send one post's latest activity to every follower the site has now.
62
+ *
63
+ * The activity is named rather than the post, so the button sends exactly
64
+ * what the row it sits in says it will: a post edited between the page load
65
+ * and the click has a newer activity, and re-sending that one instead would
66
+ * be a different thing from what was asked for.
67
+ */
68
+ app.post(REDELIVER_PATH, async (c) => {
69
+ const body = await c.req.parseBody();
70
+ const activityId = body[FEDERATION_FIELDS.activityId];
71
+ const report = typeof activityId === 'string' ? await c.var.delivery.redeliver(activityId) : undefined;
72
+ if (report === undefined) {
73
+ flash(c, 'error', 'There is no record of that activity, so it cannot be sent again.');
74
+ }
75
+ else {
76
+ flash(c, report.deliveries.some(failed) ? 'error' : 'notice', redeliveryMessage(report));
77
+ }
78
+ return c.redirect(FEDERATION_PATH, 303);
79
+ });
80
+ }
81
+ /** Whether one delivery is a failure, for deciding how a flash reads. */
82
+ function failed(delivery) {
83
+ return delivery.status === 'failed';
84
+ }
85
+ /**
86
+ * What a redelivery came to, in one line.
87
+ *
88
+ * The failures are counted even when there are none, because that zero is the
89
+ * answer to the question the button was pressed to ask.
90
+ */
91
+ export function redeliveryMessage(report) {
92
+ const total = report.deliveries.length;
93
+ if (total === 0) {
94
+ return `Nobody follows the site, so the ${report.activityType} had nowhere to go.`;
95
+ }
96
+ const counts = { sent: 0, queued: 0, failed: 0 };
97
+ for (const delivery of report.deliveries)
98
+ counts[delivery.status] += 1;
99
+ const parts = [`${String(counts.sent)} sent`];
100
+ if (counts.queued > 0)
101
+ parts.push(`${String(counts.queued)} queued`);
102
+ parts.push(`${String(counts.failed)} failed`);
103
+ const followers = total === 1 ? '1 follower' : `${String(total)} followers`;
104
+ return `Redelivered ${report.activityType} to ${followers}: ${parts.join(', ')}.`;
105
+ }
106
+ /**
107
+ * One row per post, holding the newest activity that post has: what the screen
108
+ * shows and what its Redeliver button sends.
109
+ *
110
+ * A post is usually several activities — a `Create` and every `Update` since —
111
+ * and listing all of them would make the panel a log rather than a status. The
112
+ * newest is the one that matters, because it is the version a follower who
113
+ * missed everything is owed. The activities arrive newest first, so the first
114
+ * one seen for an object is that one.
115
+ */
116
+ export function deliveryRows(activities, context) {
117
+ const rows = [];
118
+ const seen = new Set();
119
+ for (const activity of activities) {
120
+ if (seen.has(activity.objectId))
121
+ continue;
122
+ seen.add(activity.objectId);
123
+ // A `Delete` is about a post that is no longer in the index, so the slug
124
+ // the activity was built with is the only name left for it.
125
+ const post = context.post(activity.objectId) ?? slugOnlyPost(activity.slug);
126
+ if (post === null)
127
+ continue;
128
+ rows.push({
129
+ post,
130
+ activityId: activity.activityId,
131
+ activityType: activity.activityType,
132
+ createdAt: activity.createdAt,
133
+ counts: context.counts(activity.activityId),
134
+ });
135
+ }
136
+ return rows;
137
+ }
138
+ /** A post the index no longer holds, named by the slug the activity kept. */
139
+ function slugOnlyPost(slug) {
140
+ if (slug === null || slug === '')
141
+ return null;
142
+ return { slug, title: slug, editUrl: editorPath(POST_KIND, slug) };
143
+ }
144
+ /**
145
+ * The site's actor as the screen shows it.
146
+ *
147
+ * The handle's host and the actor's id both come from the base URL's origin
148
+ * rather than from the whole of it, because that is where the federation
149
+ * endpoints are served: a site under `/blog` is still `@blog@example.com`.
150
+ */
151
+ export function actorSummary(settings, context) {
152
+ const baseUrl = context.baseUrl === '' ? 'http://localhost' : context.baseUrl;
153
+ const origin = federationOrigin(baseUrl);
154
+ return {
155
+ handle: `@${settings.actorHandle}@${origin.handleHost}`,
156
+ avatarUrl: avatarUrl(settings.avatar, baseUrl) ?? null,
157
+ type: settings.actorType,
158
+ name: settings.title,
159
+ summary: settings.tagline,
160
+ actorId: new URL(ACTOR_PATH.replace('{identifier}', SITE_ACTOR_IDENTIFIER), origin.webOrigin)
161
+ .href,
162
+ url: baseUrl,
163
+ followers: context.followers,
164
+ };
165
+ }
166
+ /**
167
+ * The inbox types the screen shows, and the word each of them reads as.
168
+ *
169
+ * The follow traffic is deliberately not here. `Follow`, `Undo` and `Delete`
170
+ * are already in the log because doc-4 records everything the inbox was told,
171
+ * but their effect is the follower list a few centimetres up the page: showing
172
+ * them again would bury the three things that have nowhere else to appear.
173
+ */
174
+ export const INBOX_INTERACTIONS = {
175
+ Like: 'liked',
176
+ Announce: 'boosted',
177
+ Create: 'replied to',
178
+ };
179
+ /**
180
+ * The inbox log as the screen's "recent activity" list, newest first.
181
+ *
182
+ * Only {@link INBOX_INTERACTIONS} survive, and only as much of each row as the
183
+ * screen shows: doc-4 stores the whole JSON-LD because it could not know what
184
+ * a later phase would want, and this is that phase deciding.
185
+ */
186
+ export function inboxRows(activities, context) {
187
+ const names = new Map(context.followers.map((follower) => [
188
+ follower.actorId,
189
+ follower.name ?? follower.handle ?? follower.actorId,
190
+ ]));
191
+ const rows = [];
192
+ for (const activity of activities) {
193
+ const action = INBOX_INTERACTIONS[activity.activityType];
194
+ if (action === undefined)
195
+ continue;
196
+ const object = replyObject(activity);
197
+ rows.push({
198
+ id: activity.id,
199
+ type: activity.activityType,
200
+ action,
201
+ actorId: activity.actorId,
202
+ actorLabel: names.get(activity.actorId) ?? activity.actorId,
203
+ receivedAt: activity.receivedAt,
204
+ // A reply is a thing of its own with a page of its own; a like or a
205
+ // boost is only ever the activity that announced it.
206
+ remoteUrl: object === null ? activity.activityId : (object.url ?? object.id),
207
+ post: context.post(object === null ? activity.objectId : object.inReplyTo),
208
+ });
209
+ }
210
+ return rows;
211
+ }
212
+ /**
213
+ * The Note a `Create` carried: where it can be read, and what it replied to.
214
+ *
215
+ * `null` for anything that is not a `Create` with an embedded object, which
216
+ * includes a `Create` whose object arrived as a bare id — there is nothing to
217
+ * link to there but the activity, and that is what the caller falls back to.
218
+ */
219
+ function replyObject(activity) {
220
+ if (activity.activityType !== 'Create')
221
+ return null;
222
+ let json;
223
+ try {
224
+ json = JSON.parse(activity.json);
225
+ }
226
+ catch {
227
+ return null;
228
+ }
229
+ const object = property(json, 'object');
230
+ if (typeof object !== 'object' || object === null)
231
+ return null;
232
+ return {
233
+ id: text(property(object, 'id')),
234
+ url: text(property(object, 'url')),
235
+ inReplyTo: text(property(object, 'inReplyTo')),
236
+ };
237
+ }
238
+ /**
239
+ * Resolve one of the site's own ActivityStreams ids to the post behind it.
240
+ *
241
+ * An id from anywhere else — a like of somebody else's post that reached the
242
+ * shared inbox, a reply to a reply — is `null` rather than a guess, and so is
243
+ * one whose slug the index has never heard of.
244
+ */
245
+ export function localPosts(store, baseUrl) {
246
+ const origin = federationOrigin(baseUrl === '' ? 'http://localhost' : baseUrl).webOrigin;
247
+ const prefix = `${FEDERATION_PREFIX}/posts/`;
248
+ return (objectId) => {
249
+ if (objectId === null)
250
+ return null;
251
+ let url;
252
+ try {
253
+ url = new URL(objectId);
254
+ }
255
+ catch {
256
+ return null;
257
+ }
258
+ if (url.origin !== origin || !url.pathname.startsWith(prefix))
259
+ return null;
260
+ const slug = decodeURIComponent(url.pathname.slice(prefix.length));
261
+ if (slug === '')
262
+ return null;
263
+ const document = store.getBySlug(slug);
264
+ return {
265
+ slug,
266
+ title: document?.title ?? slug,
267
+ editUrl: editorPath(POST_KIND, slug),
268
+ };
269
+ };
270
+ }
271
+ /** One property of a value that may not be an object at all. */
272
+ function property(value, key) {
273
+ if (typeof value !== 'object' || value === null)
274
+ return undefined;
275
+ return value[key];
276
+ }
277
+ /** A JSON-LD value as a string, or `null` for anything else. */
278
+ function text(value) {
279
+ return typeof value === 'string' && value !== '' ? value : null;
280
+ }
281
+ /**
282
+ * One stored follower as the screen shows it.
283
+ *
284
+ * Every display column is nullable, because they are a copy of what the actor
285
+ * said about itself and an actor need say none of it. The id is the fallback
286
+ * for all of them: it is the one thing a follower always has, and it is
287
+ * usually legible enough to recognise an instance by.
288
+ */
289
+ export function followerRow(follower) {
290
+ return {
291
+ actorId: follower.actorId,
292
+ name: follower.name ?? follower.handle ?? follower.actorId,
293
+ handle: follower.handle ?? follower.actorId,
294
+ iconUrl: follower.iconUrl,
295
+ url: follower.url ?? follower.actorId,
296
+ followedAt: follower.followedAt,
297
+ };
298
+ }
299
+ //# sourceMappingURL=federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.js","sourceRoot":"","sources":["../../src/admin/federation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Context } from 'hono';
2
+ import type { GeekityEnv } from '../env.ts';
3
+ import type { FlashKind, FlashMessage } from './store.ts';
4
+ /**
5
+ * Queue a message for the next page this visitor asks for.
6
+ *
7
+ * A handler that changes something answers with a redirect, so the message it
8
+ * wants to show has to outlive the response. It is kept on the session row
9
+ * rather than in a cookie: nothing to sign, nothing to forge, and it goes when
10
+ * the session does.
11
+ *
12
+ * Does nothing when there is no session, which is what a message queued right
13
+ * after a logout is.
14
+ */
15
+ export declare function flash(c: Context<GeekityEnv>, kind: FlashKind, message: string): void;
16
+ /**
17
+ * Every message queued for this visitor, removed as it is read.
18
+ *
19
+ * Called once while a page is being rendered, which is what makes a flash
20
+ * survive exactly one redirect: the page that shows it is the page that
21
+ * clears it.
22
+ */
23
+ export declare function takeFlash(c: Context<GeekityEnv>): FlashMessage[];
24
+ //# sourceMappingURL=flash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flash.d.ts","sourceRoot":"","sources":["../../src/admin/flash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIpF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,YAAY,EAAE,CAIhE"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Queue a message for the next page this visitor asks for.
3
+ *
4
+ * A handler that changes something answers with a redirect, so the message it
5
+ * wants to show has to outlive the response. It is kept on the session row
6
+ * rather than in a cookie: nothing to sign, nothing to forge, and it goes when
7
+ * the session does.
8
+ *
9
+ * Does nothing when there is no session, which is what a message queued right
10
+ * after a logout is.
11
+ */
12
+ export function flash(c, kind, message) {
13
+ const session = c.var.session;
14
+ if (session === undefined)
15
+ return;
16
+ c.var.admin.pushFlash(session.id, { kind, message });
17
+ }
18
+ /**
19
+ * Every message queued for this visitor, removed as it is read.
20
+ *
21
+ * Called once while a page is being rendered, which is what makes a flash
22
+ * survive exactly one redirect: the page that shows it is the page that
23
+ * clears it.
24
+ */
25
+ export function takeFlash(c) {
26
+ const session = c.var.session;
27
+ if (session === undefined)
28
+ return [];
29
+ return c.var.admin.takeFlash(session.id);
30
+ }
31
+ //# sourceMappingURL=flash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/admin/flash.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,KAAK,CAAC,CAAsB,EAAE,IAAe,EAAE,OAAe;IAC5E,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAClC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,CAAsB;IAC9C,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,23 @@
1
+ export { ADMIN_ASSET_MAX_AGE, ADMIN_ASSET_PREFIX, ADMIN_STATIC_DIR, adminAssetResponse, findAdminAsset, } from './assets.ts';
2
+ export { credentialProblem, MAXIMUM_USERNAME_LENGTH, MINIMUM_PASSWORD_LENGTH, passwordProblem, USERNAME_PATTERN, usernameProblem, } from './credentials.ts';
3
+ export { blankForm, DOCUMENT_FILTERS, DOCUMENTS_PER_PAGE, documentFilter, editorPath, EXCLUDE_KEY, findBySlug, formFor, listingUrl, listOptionsFor, mountDocumentScreens, newEditorPath, PAGE_KIND, POST_KIND, returnPath, splitTags, } from './documents.ts';
4
+ export type { AdminRender, DocumentFilter, DocumentKind, DocumentRow, EditorForm, MountDocumentScreensOptions, } from './documents.ts';
5
+ export { actorSummary, deliveryRows, FEDERATION_FIELDS, FEDERATION_PATH, FEDERATION_RECENT, followerRow, INBOX_INTERACTIONS, inboxRows, localPosts, mountFederationScreen, REDELIVER_PATH, redeliveryMessage, } from './federation.ts';
6
+ export type { ActorSummary, DeliveryRow, DeliveryRowsContext, FollowerRow, InboxRow, InboxRowsContext, LocalPost, MountFederationScreenOptions, } from './federation.ts';
7
+ export { flash, takeFlash } from './flash.ts';
8
+ export { mountPreview, PREVIEW_PATH } from './preview.ts';
9
+ export { ARGON2_PARAMETERS, hashPassword, verifyPasswordHash } from './passwords.ts';
10
+ export { ADMIN_SECTIONS, DASHBOARD_RECENT_POSTS, guard, LOGIN_PATH, LOGOUT_PATH, mountAdmin, postEditorPath, QUICK_DRAFT_PATH, SETUP_PATH, } from './routes.ts';
11
+ export type { AdminSection } from './routes.ts';
12
+ export { ACTOR_HANDLE_PATTERN, ACTOR_TYPES, AVATAR_FIELDS, AVATAR_PATH, AVATAR_REMOVE, DEFAULT_SITE_SETTINGS, effectiveBaseUrl, formFromSettings, mountSettings, profileChanged, readSiteSettings, seedSiteSettings, SETTINGS_FIELDS, SETTINGS_PATH, settingsFromForm, settingsProblems, settingsSiteData, siteDataPath, siteJsonFor, writeSiteJson, writeSiteSettings, } from './settings.ts';
13
+ export type { MountSettingsOptions, SettingsField, SettingsForm, SettingsProblems, SiteSettings, } from './settings.ts';
14
+ export { addUserProblems, changePasswordProblems, CHANGE_PASSWORD_PATH, deleteUserRefusal, DELETE_USER_PATH, generatePassword, GENERATED_PASSWORD_ALPHABET, GENERATED_PASSWORD_LENGTH, mountUsers, USER_FIELDS, USERS_PATH, } from './users.ts';
15
+ export type { AddUserProblems, ChangePasswordProblems, MountUsersOptions } from './users.ts';
16
+ export { ADMIN_PREFIX, clearSessionCookie, CSRF_FIELD, csrfTokenMatches, SESSION_COOKIE, sessionIdFrom, setSessionCookie, usesSecureCookies, } from './session.ts';
17
+ export { ACTOR_KEY_ALGORITHMS, DELIVERY_STATUSES, DuplicateUsernameError, openAdminStore, SESSION_ID_BYTES, } from './store.ts';
18
+ export type { ActorKey, ActorKeyAlgorithm, AdminStore, CreateSessionInput, CreateUserInput, Delivery, DeliveryStatus, FlashKind, FlashMessage, Follower, InboxActivity, ListPageOptions, NewActorKey, NewDelivery, NewFollower, NewInboxActivity, NewOutboundActivity, OpenAdminStoreOptions, OutboundActivity, Session, StoredUser, User, } from './store.ts';
19
+ export { ADMIN_TEMPLATES, createAdminTemplateEnvironment, PACKAGED_ADMIN_DIR, } from './templates.ts';
20
+ export type { CreateAdminTemplateEnvironmentOptions } from './templates.ts';
21
+ export { mountUploads, refuseOversizedUpload, refusedUpload, storeUpload, tooLargeMessage, UPLOAD_ENVELOPE_BYTES, UPLOAD_FIELD, UPLOADS_PATH, } from './uploads.ts';
22
+ export type { StoredUpload, StoreUploadOptions, UploadConfig, UploadRefusal, UploadResult, } from './uploads.ts';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export { ADMIN_ASSET_MAX_AGE, ADMIN_ASSET_PREFIX, ADMIN_STATIC_DIR, adminAssetResponse, findAdminAsset, } from './assets.js';
2
+ export { credentialProblem, MAXIMUM_USERNAME_LENGTH, MINIMUM_PASSWORD_LENGTH, passwordProblem, USERNAME_PATTERN, usernameProblem, } from './credentials.js';
3
+ export { blankForm, DOCUMENT_FILTERS, DOCUMENTS_PER_PAGE, documentFilter, editorPath, EXCLUDE_KEY, findBySlug, formFor, listingUrl, listOptionsFor, mountDocumentScreens, newEditorPath, PAGE_KIND, POST_KIND, returnPath, splitTags, } from './documents.js';
4
+ export { actorSummary, deliveryRows, FEDERATION_FIELDS, FEDERATION_PATH, FEDERATION_RECENT, followerRow, INBOX_INTERACTIONS, inboxRows, localPosts, mountFederationScreen, REDELIVER_PATH, redeliveryMessage, } from './federation.js';
5
+ export { flash, takeFlash } from './flash.js';
6
+ export { mountPreview, PREVIEW_PATH } from './preview.js';
7
+ export { ARGON2_PARAMETERS, hashPassword, verifyPasswordHash } from './passwords.js';
8
+ export { ADMIN_SECTIONS, DASHBOARD_RECENT_POSTS, guard, LOGIN_PATH, LOGOUT_PATH, mountAdmin, postEditorPath, QUICK_DRAFT_PATH, SETUP_PATH, } from './routes.js';
9
+ export { ACTOR_HANDLE_PATTERN, ACTOR_TYPES, AVATAR_FIELDS, AVATAR_PATH, AVATAR_REMOVE, DEFAULT_SITE_SETTINGS, effectiveBaseUrl, formFromSettings, mountSettings, profileChanged, readSiteSettings, seedSiteSettings, SETTINGS_FIELDS, SETTINGS_PATH, settingsFromForm, settingsProblems, settingsSiteData, siteDataPath, siteJsonFor, writeSiteJson, writeSiteSettings, } from './settings.js';
10
+ export { addUserProblems, changePasswordProblems, CHANGE_PASSWORD_PATH, deleteUserRefusal, DELETE_USER_PATH, generatePassword, GENERATED_PASSWORD_ALPHABET, GENERATED_PASSWORD_LENGTH, mountUsers, USER_FIELDS, USERS_PATH, } from './users.js';
11
+ export { ADMIN_PREFIX, clearSessionCookie, CSRF_FIELD, csrfTokenMatches, SESSION_COOKIE, sessionIdFrom, setSessionCookie, usesSecureCookies, } from './session.js';
12
+ export { ACTOR_KEY_ALGORITHMS, DELIVERY_STATUSES, DuplicateUsernameError, openAdminStore, SESSION_ID_BYTES, } from './store.js';
13
+ export { ADMIN_TEMPLATES, createAdminTemplateEnvironment, PACKAGED_ADMIN_DIR, } from './templates.js';
14
+ export { mountUploads, refuseOversizedUpload, refusedUpload, storeUpload, tooLargeMessage, UPLOAD_ENVELOPE_BYTES, UPLOAD_FIELD, UPLOADS_PATH, } from './uploads.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,GACV,MAAM,gBAAgB,CAAC;AASxB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,KAAK,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAQvB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,2BAA2B,EAC3B,yBAAyB,EACzB,UAAU,EACV,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAyBpB,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC"}