@jant/core 0.7.0 → 0.7.1

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 (158) hide show
  1. package/bin/commands/export.js +3 -1
  2. package/bin/commands/import-site.js +689 -216
  3. package/bin/commands/setup.js +136 -0
  4. package/bin/commands/site/export.js +71 -34
  5. package/bin/commands/site/pull-media.js +2 -6
  6. package/bin/commands/site/snapshot/export.js +18 -60
  7. package/bin/commands/site/snapshot/import.js +22 -23
  8. package/bin/lib/d1-query.js +87 -2
  9. package/bin/lib/hugo-markdown.js +4 -0
  10. package/bin/lib/site-pull-media.js +21 -28
  11. package/bin/lib/site-selection.js +10 -1
  12. package/bin/lib/site-snapshot.js +338 -3
  13. package/bin/lib/sql-export.js +68 -5
  14. package/bin/lib/wrangler-cli.js +9 -0
  15. package/bin/lib/zip-archive.js +187 -0
  16. package/dist/{app-K_Aa1MMn.js → app-ZcaI1kPN.js} +732 -217
  17. package/dist/client/.vite/manifest.json +20 -20
  18. package/dist/client/_assets/chunks/{create-editor-CD3FhrOB.js → create-editor-B-m7X7S5.js} +50 -46
  19. package/dist/client/_assets/chunks/{sortable-list-CgaL2jCs.js → sortable-list-BJyd-LXE.js} +1 -1
  20. package/dist/client/_assets/chunks/{unsafe-svg-0QCkP0vZ.js → unsafe-svg-BkscJx69.js} +2 -2
  21. package/dist/client/_assets/{client-GiYENVw8.css → client-DAhoqPdr.css} +1 -1
  22. package/dist/client/_assets/{client-auth-k8gJ6QJj.js → client-auth-CAMfTrKW.js} +1 -1
  23. package/dist/client/_assets/{client-compose-B_kDtWkW.js → client-compose-D6rExKVK.js} +1 -1
  24. package/dist/client/_assets/{client-VnFxJN7G.js → client-knSEyUJO.js} +1 -1
  25. package/dist/client/_assets/{client-manage-M90aSTOk.js → client-manage-sVOkqVbH.js} +1 -1
  26. package/dist/client/_assets/{client-settings-DfYs9n1F.js → client-settings-CGR_nZ78.js} +7 -7
  27. package/dist/{github-sync-BPAvT999.js → github-sync-Gw4orAHk.js} +799 -110
  28. package/dist/index.js +2 -2
  29. package/dist/node.js +9 -5
  30. package/package.json +13 -3
  31. package/src/__tests__/dev-scripts.test.ts +203 -0
  32. package/src/__tests__/export-collection-order.test.ts +276 -0
  33. package/src/__tests__/export-feed-ids.test.ts +184 -0
  34. package/src/__tests__/export-feed-order.test.ts +294 -0
  35. package/src/__tests__/export-hugo-build.test.ts +130 -0
  36. package/src/__tests__/export-import-roundtrip.test.ts +94 -0
  37. package/src/__tests__/export-service.test.ts +611 -28
  38. package/src/__tests__/export-smart-collection.test.ts +329 -0
  39. package/src/__tests__/helpers/hugo-site.ts +146 -0
  40. package/src/__tests__/import-site-command.test.ts +487 -1
  41. package/src/__tests__/mise-config.test.ts +75 -4
  42. package/src/__tests__/node-dev-tasks.test.ts +264 -0
  43. package/src/__tests__/site-export-canonical-import.test.ts +149 -0
  44. package/src/__tests__/snapshot-canonical-replay.test.ts +179 -0
  45. package/src/__tests__/snapshot-settings.test.ts +97 -0
  46. package/src/__tests__/snapshot-tables.test.ts +219 -0
  47. package/src/__tests__/sql-export.test.ts +173 -0
  48. package/src/__tests__/zip-archive.test.ts +106 -0
  49. package/src/app.tsx +15 -6
  50. package/src/client/components/__tests__/jant-settings-avatar.test.ts +1 -1
  51. package/src/client/components/__tests__/jant-settings-general.test.ts +21 -1
  52. package/src/client/components/jant-repo-picker-types.ts +6 -1
  53. package/src/client/components/jant-repo-picker.ts +4 -7
  54. package/src/client/components/jant-settings-general.ts +17 -12
  55. package/src/client/tiptap/__tests__/list-editing.test.ts +224 -86
  56. package/src/client/tiptap/__tests__/mark-exit.test.ts +1 -2
  57. package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +26 -0
  58. package/src/client/tiptap/extensions.ts +0 -3
  59. package/src/client/tiptap/structural-keymap.ts +158 -47
  60. package/src/db/__tests__/d1-query.test.ts +56 -1
  61. package/src/i18n/locales/settings/en.po +8 -8
  62. package/src/i18n/locales/settings/en.ts +1 -1
  63. package/src/i18n/locales/settings/zh-Hans.po +8 -8
  64. package/src/i18n/locales/settings/zh-Hans.ts +1 -1
  65. package/src/i18n/locales/settings/zh-Hant.po +8 -8
  66. package/src/i18n/locales/settings/zh-Hant.ts +1 -1
  67. package/src/lib/__tests__/github-sync-repo-name.test.ts +40 -0
  68. package/src/lib/__tests__/image.test.ts +27 -1
  69. package/src/lib/__tests__/markdown-to-tiptap.test.ts +105 -0
  70. package/src/lib/__tests__/markdown.test.ts +10 -0
  71. package/src/lib/__tests__/resolve-config.test.ts +67 -0
  72. package/src/lib/__tests__/schemas.test.ts +27 -1
  73. package/src/lib/__tests__/timeline.test.ts +87 -0
  74. package/src/lib/__tests__/tiptap-to-markdown.test.ts +172 -4
  75. package/src/lib/discover.ts +3 -1
  76. package/src/lib/github-sync-repo-name.ts +45 -0
  77. package/src/lib/hugo-markdown.ts +46 -0
  78. package/src/lib/image.ts +17 -4
  79. package/src/lib/markdown-manager.ts +392 -2
  80. package/src/lib/post-body-html.ts +11 -4
  81. package/src/lib/resolve-config.ts +58 -1
  82. package/src/lib/schemas.ts +50 -5
  83. package/src/lib/thread-fold.ts +3 -3
  84. package/src/lib/timeline.ts +1 -1
  85. package/src/lib/tiptap-to-markdown.ts +13 -7
  86. package/src/lib/url.ts +20 -0
  87. package/src/lib/view.ts +2 -2
  88. package/src/node/__tests__/cli-setup.test.ts +163 -0
  89. package/src/node/__tests__/cli-site-snapshot.test.ts +67 -0
  90. package/src/node/__tests__/cli-snapshot-meta.test.ts +20 -0
  91. package/src/node/__tests__/runtime.test.ts +38 -0
  92. package/src/node/index.ts +2 -0
  93. package/src/node/request-handler.ts +3 -1
  94. package/src/routes/api/__tests__/posts.test.ts +24 -0
  95. package/src/routes/api/__tests__/upload.test.ts +34 -0
  96. package/src/routes/api/export.ts +3 -3
  97. package/src/routes/api/internal/sites.ts +0 -1
  98. package/src/routes/api/posts.ts +2 -0
  99. package/src/routes/api/public/posts.ts +21 -1
  100. package/src/routes/api/upload.ts +10 -3
  101. package/src/routes/compose.tsx +4 -0
  102. package/src/routes/dash/__tests__/github-sync-app.test.ts +365 -0
  103. package/src/routes/dash/settings.tsx +212 -70
  104. package/src/routes/pages/__tests__/post-page-round-trips.test.ts +211 -0
  105. package/src/routes/pages/__tests__/thread-order.test.ts +179 -0
  106. package/src/routes/pages/archive.tsx +17 -11
  107. package/src/routes/pages/featured.tsx +11 -5
  108. package/src/routes/pages/page.tsx +53 -31
  109. package/src/routes/pages/search.tsx +4 -2
  110. package/src/runtime/__tests__/readiness.test.ts +23 -0
  111. package/src/runtime/node.ts +49 -0
  112. package/src/runtime/readiness.ts +15 -0
  113. package/src/services/__tests__/bootstrap-setup-instance.test.ts +230 -0
  114. package/src/services/__tests__/custom-url.test.ts +34 -0
  115. package/src/services/__tests__/github-app-installations.test.ts +153 -0
  116. package/src/services/__tests__/github-sync-push.test.ts +46 -0
  117. package/src/services/__tests__/media.test.ts +31 -0
  118. package/src/services/__tests__/path.test.ts +56 -0
  119. package/src/services/__tests__/post-timeline.test.ts +127 -0
  120. package/src/services/__tests__/post.test.ts +74 -0
  121. package/src/services/bootstrap.ts +263 -44
  122. package/src/services/custom-url.ts +2 -2
  123. package/src/services/export-theme/layouts/_default/alias.html +27 -1
  124. package/src/services/export-theme/layouts/_default/list.html +2 -63
  125. package/src/services/export-theme/layouts/_default/rss.xml +27 -38
  126. package/src/services/export-theme/layouts/collections/list.html +3 -3
  127. package/src/services/export-theme/layouts/featured/list.html +1 -4
  128. package/src/services/export-theme/layouts/index.html +40 -26
  129. package/src/services/export-theme/layouts/partials/collection-members.html +100 -0
  130. package/src/services/export-theme/layouts/partials/collection-threads.html +33 -0
  131. package/src/services/export-theme/layouts/partials/featured-members.html +35 -0
  132. package/src/services/export-theme/layouts/partials/featured-thread.html +1 -1
  133. package/src/services/export-theme/layouts/partials/footer.html +1 -1
  134. package/src/services/export-theme/layouts/partials/head.html +1 -1
  135. package/src/services/export-theme/layouts/partials/header.html +5 -3
  136. package/src/services/export-theme/layouts/partials/jant-data.html +23 -0
  137. package/src/services/export-theme/layouts/partials/latest-members.html +48 -0
  138. package/src/services/export-theme/layouts/partials/smart-collection-members.html +129 -0
  139. package/src/services/export-theme/layouts/partials/thread-preview.html +1 -1
  140. package/src/services/export-theme/layouts/post/list.html +1 -1
  141. package/src/services/export-theme/layouts/smart_collection/list.html +24 -0
  142. package/src/services/export-theme/styles/main.css +0 -1
  143. package/src/services/export-theme/theme.toml +1 -1
  144. package/src/services/export.ts +620 -71
  145. package/src/services/github-app-installations.ts +171 -4
  146. package/src/services/github-sync.ts +69 -15
  147. package/src/services/mcp.ts +19 -1
  148. package/src/services/media.ts +8 -1
  149. package/src/services/path.ts +34 -1
  150. package/src/services/post.ts +214 -39
  151. package/src/services/site-admin.ts +3 -7
  152. package/src/services/site.ts +83 -31
  153. package/src/styles/ui.css +7 -1
  154. package/src/types/app-context.ts +16 -0
  155. package/src/types/bindings.ts +5 -0
  156. package/src/types/operations.ts +10 -0
  157. package/src/ui/dash/settings/GeneralContent.tsx +10 -8
  158. package/src/client/tiptap/exitable-marks.ts +0 -73
@@ -1,12 +1,37 @@
1
1
  /**
2
2
  * Compose Structural Keymap
3
3
  *
4
- * Keeps Jant's small set of product-specific block-boundary decisions in one
5
- * place while delegating every unowned case to Tiptap's official keymaps.
4
+ * Block boundaries follow the editing model shared by Notion and Google Docs,
5
+ * mapped onto what Markdown can represent. Tiptap's official keymaps already
6
+ * implement most of it; this extension owns only the cases where they differ,
7
+ * and delegates everything else.
8
+ *
9
+ * Backspace at the start of a line removes one layer at a time:
10
+ * - A list item loses its marker first and becomes a paragraph where it
11
+ * stands. Tiptap does this for top-level items. A nested item stays inside
12
+ * its parent item instead of being outdented, which is Tiptap's default;
13
+ * Shift-Tab and Enter on an empty item remain the outdent keys.
14
+ * - A paragraph then merges into the line visually above it, however deep
15
+ * that line is nested.
16
+ *
17
+ * Delete at the end of a line always pulls the next line's text up, whatever
18
+ * its list depth. The two keys are intentionally not symmetric: Backspace
19
+ * deletes the marker just before the caret, Delete deletes the line break.
20
+ *
21
+ * Markdown differs from Notion in one place: a paragraph cannot own a nested
22
+ * list. When an item loses its marker, or its text merges into a shallower
23
+ * line, its children move up one level instead of staying indented.
6
24
  */
7
25
 
8
26
  import { Extension, type Editor } from "@tiptap/core";
9
- import type { Node as ProseMirrorNode, ResolvedPos } from "@tiptap/pm/model";
27
+ import {
28
+ Fragment,
29
+ NodeRange,
30
+ type Node as ProseMirrorNode,
31
+ type ResolvedPos,
32
+ } from "@tiptap/pm/model";
33
+ import { TextSelection } from "@tiptap/pm/state";
34
+ import { liftTarget } from "@tiptap/pm/transform";
10
35
 
11
36
  type Direction = "backward" | "forward";
12
37
 
@@ -101,6 +126,11 @@ function joinBlockquoteParagraphBoundary(
101
126
  : editor.commands.joinTextblockForward();
102
127
  }
103
128
 
129
+ function isListNode(node: ProseMirrorNode | null | undefined): boolean {
130
+ const name = node?.type.name;
131
+ return name === "bulletList" || name === "orderedList";
132
+ }
133
+
104
134
  function findDirectListItemDepth($cursor: ResolvedPos): number | null {
105
135
  const listItemDepth = $cursor.depth - 1;
106
136
  if (
@@ -110,55 +140,48 @@ function findDirectListItemDepth($cursor: ResolvedPos): number | null {
110
140
  return null;
111
141
  }
112
142
 
113
- const listDepth = listItemDepth - 1;
114
- const listName = $cursor.node(listDepth).type.name;
115
- return listName === "bulletList" || listName === "orderedList"
116
- ? listItemDepth
117
- : null;
143
+ return isListNode($cursor.node(listItemDepth - 1)) ? listItemDepth : null;
118
144
  }
119
145
 
120
- function joinListItemBackward(editor: Editor): boolean {
121
- const { selection } = editor.state;
122
- if (!selection.empty) return false;
146
+ /**
147
+ * Removes a nested item's marker while keeping it inside its parent item: the
148
+ * item's content becomes blocks of the parent item, splitting the nested list
149
+ * around it.
150
+ * Top-level items are left to the official ListKeymap, which does the same
151
+ * against the document or blockquote.
152
+ */
153
+ function unwrapNestedListItem(editor: Editor, listItemDepth: number): boolean {
154
+ const { state } = editor;
155
+ const { $from } = state.selection;
156
+ if ($from.node(listItemDepth - 2).type.name !== "listItem") return false;
157
+
158
+ const range = new NodeRange(
159
+ state.doc.resolve($from.start(listItemDepth)),
160
+ state.doc.resolve($from.end(listItemDepth)),
161
+ listItemDepth,
162
+ );
163
+ const target = liftTarget(range);
164
+ if (target === null) return false;
123
165
 
124
- const { $from } = selection;
125
- if ($from.parentOffset !== 0 || !$from.parent.isTextblock) return false;
166
+ editor.view.dispatch(state.tr.lift(range, target).scrollIntoView());
167
+ return true;
168
+ }
126
169
 
170
+ function handleListBackspace(editor: Editor): boolean {
171
+ const { $from } = editor.state.selection;
127
172
  const listItemDepth = findDirectListItemDepth($from);
128
173
  if (listItemDepth === null) return false;
129
174
 
130
- const listItem = $from.node(listItemDepth);
131
175
  const childIndex = $from.index(listItemDepth);
176
+ if (childIndex === 0) return unwrapNestedListItem(editor, listItemDepth);
132
177
 
133
- if (childIndex > 0) {
134
- const previousChild = listItem.child(childIndex - 1);
135
- if (previousChild.isTextblock) {
136
- return editor.commands.joinTextblockBackward();
137
- }
178
+ // A markerless paragraph after an adjacent textblock is joined by the
179
+ // official keymap. After a nested list the official fallback would wrap the
180
+ // paragraph into that list instead, so merge into the line visually above.
181
+ const previousChild = $from.node(listItemDepth).child(childIndex - 1);
182
+ if (previousChild.isTextblock) return false;
138
183
 
139
- // A paragraph following a nested structural block has no unambiguous
140
- // one-key merge target. Consume Backspace instead of letting ListKeymap
141
- // lift and split the entire list item.
142
- return true;
143
- }
144
-
145
- const listDepth = listItemDepth - 1;
146
- const itemIndex = $from.index(listDepth);
147
- if (itemIndex === 0) {
148
- // Let the official ListKeymap lift a first/nested-first item.
149
- return false;
150
- }
151
-
152
- if (editor.commands.joinItemBackward()) return true;
153
-
154
- // `joinItemBackward` cannot join when the previous item already owns a
155
- // nested list. The official textblock join safely removes the current marker
156
- // while preserving both subtrees in their existing document order.
157
- if (editor.commands.joinBackward()) return true;
158
-
159
- // A same-level previous item exists, so never fall through to the official
160
- // lift behavior, which would split the surrounding list into top-level blocks.
161
- return true;
184
+ return editor.commands.joinTextblockBackward();
162
185
  }
163
186
 
164
187
  function handleBackspace(editor: Editor): boolean {
@@ -176,11 +199,101 @@ function handleBackspace(editor: Editor): boolean {
176
199
  if (editor.commands.undoInputRule()) return true;
177
200
 
178
201
  return (
179
- joinListItemBackward(editor) ||
202
+ handleListBackspace(editor) ||
180
203
  joinBlockquoteParagraphBoundary(editor, "backward")
181
204
  );
182
205
  }
183
206
 
207
+ /** Mirrors ProseMirror's `findCutAfter`, which prosemirror-commands keeps private. */
208
+ function findCutAfter($pos: ResolvedPos): ResolvedPos | null {
209
+ if ($pos.parent.type.spec.isolating) return null;
210
+
211
+ for (let depth = $pos.depth - 1; depth >= 0; depth -= 1) {
212
+ const parent = $pos.node(depth);
213
+ if ($pos.index(depth) + 1 < parent.childCount) {
214
+ return $pos.doc.resolve($pos.after(depth + 1));
215
+ }
216
+ if (parent.type.spec.isolating) break;
217
+ }
218
+
219
+ return null;
220
+ }
221
+
222
+ /**
223
+ * Pulls the first item of a directly following deeper list up into the
224
+ * caret's line. The item's text joins the line; its children cannot stay
225
+ * nested under a line that is no longer there, so they move up one level and
226
+ * sit between the joined line and the rest of the list.
227
+ */
228
+ function pullUpFirstItemOfNestedList(
229
+ editor: Editor,
230
+ $cut: ResolvedPos,
231
+ ): boolean {
232
+ const { state } = editor;
233
+ const { $from } = state.selection;
234
+ const list = $cut.nodeAfter;
235
+ const item = list?.firstChild;
236
+ const itemText = item?.firstChild;
237
+ if (!list || !item || item.childCount < 2 || !itemText?.isTextblock) {
238
+ return false;
239
+ }
240
+ if ($from.parent.type.spec.code) return false;
241
+
242
+ const children = item.content.cut(itemText.nodeSize);
243
+ const remainingItems = list.content.cut(item.nodeSize);
244
+ const replacement =
245
+ remainingItems.size > 0
246
+ ? children.addToEnd(list.copy(remainingItems))
247
+ : children;
248
+ const index = $cut.index();
249
+ if (!$cut.parent.canReplace(index, index + 1, replacement)) return false;
250
+
251
+ const tr = state.tr
252
+ .replaceWith($cut.pos, $cut.pos + list.nodeSize, replacement)
253
+ .insert($from.pos, Fragment.from(itemText.content));
254
+ tr.setSelection(TextSelection.create(tr.doc, $from.pos));
255
+ editor.view.dispatch(tr.scrollIntoView());
256
+ return true;
257
+ }
258
+
259
+ function handleListDelete(editor: Editor): boolean {
260
+ const { selection } = editor.state;
261
+ if (!selection.empty) return false;
262
+
263
+ const { $from } = selection;
264
+ if (
265
+ !$from.parent.isTextblock ||
266
+ $from.parentOffset !== $from.parent.content.size
267
+ ) {
268
+ return false;
269
+ }
270
+
271
+ const $cut = findCutAfter($from);
272
+ if (!$cut) return false;
273
+
274
+ // Only boundaries that cross list structure are Jant's. Between plain
275
+ // blocks the official Delete already joins the next textblock.
276
+ const { nodeBefore, nodeAfter } = $cut;
277
+ const crossesList =
278
+ isListNode(nodeBefore) ||
279
+ isListNode(nodeAfter) ||
280
+ nodeBefore?.type.name === "listItem";
281
+ if (!crossesList) return false;
282
+
283
+ if ($cut.pos === $from.after() && isListNode(nodeAfter)) {
284
+ if (pullUpFirstItemOfNestedList(editor, $cut)) return true;
285
+ }
286
+
287
+ return editor.commands.joinTextblockForward();
288
+ }
289
+
290
+ function handleDelete(editor: Editor): boolean {
291
+ return (
292
+ joinBlockquoteParagraphBoundary(editor, "forward") ||
293
+ handleListDelete(editor)
294
+ );
295
+ }
296
+
184
297
  export const StructuralKeymap = Extension.create({
185
298
  name: "structuralKeymap",
186
299
  priority: 1000,
@@ -190,10 +303,8 @@ export const StructuralKeymap = Extension.create({
190
303
  Backspace: ({ editor }) => handleBackspace(editor),
191
304
  "Mod-Backspace": ({ editor }) => handleBackspace(editor),
192
305
  "Shift-Backspace": ({ editor }) => handleBackspace(editor),
193
- Delete: ({ editor }) =>
194
- joinBlockquoteParagraphBoundary(editor, "forward"),
195
- "Mod-Delete": ({ editor }) =>
196
- joinBlockquoteParagraphBoundary(editor, "forward"),
306
+ Delete: ({ editor }) => handleDelete(editor),
307
+ "Mod-Delete": ({ editor }) => handleDelete(editor),
197
308
  Tab: ({ editor }) => {
198
309
  if (!editor.isActive("listItem")) return false;
199
310
 
@@ -1,3 +1,4 @@
1
+ import { existsSync, readFileSync } from "node:fs";
1
2
  import { beforeEach, describe, expect, it, vi } from "vitest";
2
3
 
3
4
  const { runLocalWranglerMock } = vi.hoisted(() => ({
@@ -8,7 +9,7 @@ vi.mock("../../../bin/lib/wrangler-cli.js", () => ({
8
9
  runLocalWrangler: runLocalWranglerMock,
9
10
  }));
10
11
 
11
- const { executeD1, parseWranglerError, queryD1 } =
12
+ const { exceedsInlineCommandLimit, executeD1, parseWranglerError, queryD1 } =
12
13
  await import("../../../bin/lib/d1-query.js");
13
14
 
14
15
  function createWranglerError(stderr) {
@@ -124,3 +125,57 @@ describe("d1-query Wrangler error parsing", () => {
124
125
  );
125
126
  });
126
127
  });
128
+
129
+ /**
130
+ * Oversized statement batches.
131
+ *
132
+ * A batch travels to Wrangler as one `--command=` argument, and Linux caps a
133
+ * single argv entry at 128 KiB (`MAX_ARG_STRLEN`). macOS has no such cap, so
134
+ * the first snapshot whose `db.sql` grew past it imported fine on a Mac and
135
+ * failed CI with `E2BIG`. Anything that large has to go through `--file`.
136
+ */
137
+ describe("d1-query oversized batches", () => {
138
+ beforeEach(() => {
139
+ runLocalWranglerMock.mockReset();
140
+ });
141
+
142
+ it("sends a small batch inline", () => {
143
+ runLocalWranglerMock.mockReturnValue(JSON.stringify([{ success: true }]));
144
+
145
+ executeD1("SELECT 1;", "d1-local", { quiet: true, retryAttempts: 1 });
146
+
147
+ expect(runLocalWranglerMock).toHaveBeenCalledWith(
148
+ expect.arrayContaining(["--command=SELECT 1;"]),
149
+ expect.anything(),
150
+ );
151
+ });
152
+
153
+ it("writes a batch too large for one argument to a file", () => {
154
+ const sql = `${"INSERT INTO t VALUES ('x');".repeat(8000)}\n`;
155
+ expect(exceedsInlineCommandLimit(sql)).toBe(true);
156
+
157
+ let seenPath: string | undefined;
158
+ let seenContents: string | undefined;
159
+ runLocalWranglerMock.mockImplementation((args: string[]) => {
160
+ const index = args.indexOf("--file");
161
+ seenPath = args[index + 1];
162
+ seenContents = readFileSync(seenPath as string, "utf8");
163
+ return JSON.stringify([{ success: true }]);
164
+ });
165
+
166
+ executeD1(sql, "d1-local", { quiet: true, retryAttempts: 1 });
167
+
168
+ const args = runLocalWranglerMock.mock.calls[0]?.[0] as string[];
169
+ expect(args).toContain("--file");
170
+ expect(args.some((arg) => arg.startsWith("--command="))).toBe(false);
171
+ expect(seenContents).toBe(sql);
172
+ // The temp file is Wrangler's to read and ours to clean up.
173
+ expect(existsSync(seenPath as string)).toBe(false);
174
+ });
175
+
176
+ it("keeps the threshold under the Linux single-argument cap", () => {
177
+ const MAX_ARG_STRLEN = 128 * 1024;
178
+ const justUnder = "a".repeat(MAX_ARG_STRLEN - 1);
179
+ expect(exceedsInlineCommandLimit(justUnder)).toBe(true);
180
+ });
181
+ });
@@ -1012,10 +1012,10 @@ msgstr "Demo mode hides sessions, password changes, and account deletion. Export
1012
1012
  msgid "Demo sites always stay hidden from search engines."
1013
1013
  msgstr "Demo sites always stay hidden from search engines."
1014
1014
 
1015
- #. @context: Help text explaining that Discover is locked off in demo mode
1015
+ #. @context: Help text under the Jant Discover checkbox explaining that Discover is locked off in demo mode, shown in place of the usual help line. {name} is the directory's name and is rendered as the link to it, so keep it as one run of text.
1016
1016
  #: src/ui/dash/settings/GeneralContent.tsx
1017
- msgid "Demo sites are never listed in Discover."
1018
- msgstr "Demo sites are never listed in Discover."
1017
+ msgid "Demo sites are never listed in {name}."
1018
+ msgstr "Demo sites are never listed in {name}."
1019
1019
 
1020
1020
  #. @context: Color theme preview collection label
1021
1021
  #: src/ui/dash/appearance/ColorThemeContent.tsx
@@ -1683,6 +1683,11 @@ msgstr "Muted red-brown background, earthy and warm."
1683
1683
  msgid "My Collection"
1684
1684
  msgstr "My Collection"
1685
1685
 
1686
+ #. @context: GitHub sync picker — hint under the create-on-github entry. Placeholder {name} is the suggested repo name.
1687
+ #: src/routes/dash/settings.tsx
1688
+ msgid "Name prefilled as {name}. The list refreshes when you return."
1689
+ msgstr "Name prefilled as {name}. The list refreshes when you return."
1690
+
1686
1691
  #. @context: Settings item description for general
1687
1692
  #: src/ui/dash/settings/SettingsRootContent.tsx
1688
1693
  msgid "Name, visibility, feeds, and time zone"
@@ -3013,11 +3018,6 @@ msgstr "Warm terracotta"
3013
3018
  msgid "Warm-neutral and easy for long reading."
3014
3019
  msgstr "Warm-neutral and easy for long reading."
3015
3020
 
3016
- #. @context: GitHub sync picker — hint under the create-on-github entry. Placeholder {name} is the suggested repo name.
3017
- #: src/routes/dash/settings.tsx
3018
- msgid "We'll prefill the name {name}. The list refreshes on return."
3019
- msgstr "We'll prefill the name {name}. The list refreshes on return."
3020
-
3021
3021
  #. @context: Setup page welcome heading
3022
3022
  #: src/routes/auth/setup.tsx
3023
3023
  msgid "Welcome to Jant"
@@ -1 +1 @@
1
- /*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"+4Z6iP\":[\"Create the repository on GitHub first — it can be empty.\"],\"+9JI/F\":[\"Connecting will sync your site onto \",[\"repo\"],\"'s default branch on top of its existing history. Existing files outside Jant's managed paths are kept. This can't be undone.\"],\"+AXdXp\":[\"Label and URL are required\"],\"+K0AvT\":[\"Disconnect\"],\"+V/jXc\":[\"Links straight to /feed — the raw Atom file, currently your \",[\"feed\"],\" feed. Best for readers who already use a feed reader.\"],\"+VEqyj\":[\"Make primary\"],\"+jXHMG\":[[\"count\",\"plural\",{\"one\":[\"#\",\" post is\"],\"other\":[\"#\",\" posts are\"]}],\" still written in \",[\"language\"],\". Change their language, or keep the language.\"],\"+wgt7C\":[\"Muted red-brown background, earthy and warm.\"],\"+zy2Nq\":[\"Type\"],\"/0D1Xp\":[\"Edit Collection\"],\"/3H2/s\":[\"This hosted site signs in through \",[\"providerLabel\"],\". Manage password and hosted access there.\"],\"/PXXBT\":[\"Nearly white, with a touch of warmth.\"],\"/PoNoq\":[\"Edit link\"],\"/zOUxl\":[\"QR code linking to the Telegram bot\"],\"05DXsb\":[\"Connect or manage the bot used to post from Telegram.\"],\"0OGSSc\":[\"Avatar display updated.\"],\"0UzCUX\":[\"Update the password you use to sign in\"],\"0VVvqu\":[\"Multilingual content is on.\"],\"0bdA9b\":[\"Open Telegram to connect\"],\"0dieZ/\":[\"Which layout /archive opens with. Readers can switch layouts from the page.\"],\"0gECZD\":[\"Want to write a fuller introduction?\"],\"0uIjy/\":[\"Light sage-green with a matching green accent.\"],\"1DahsC\":[\"Search settings\"],\"1F6Mzc\":[\"No navigation items yet. Add links or enable system items below.\"],\"1H7gng\":[\"Dashboard language\"],\"1MYU3o\":[\"Couldn't create the page. Check the details and try again.\"],\"1mbBbL\":[\"Connect manually\"],\"1njn7W\":[\"Light\"],\"1qGdnL\":[\"The default. Calm and easy for long reading.\"],\"1wdDm9\":[\"Add language\"],\"21mg6u\":[\"Choose a titled note that isn't already in navigation, or create a new page.\"],\"2C7mSG\":[\"Collection link\"],\"2DoBvq\":[\"Feeds\"],\"2Et8jU\":[\"Set results per search page; reset to inherit the main page size.\"],\"2FYpfJ\":[\"More\"],\"2Ithfh\":[\"Message the bot any text and it's published as a note.\"],\"2PTjMB\":[\"I want to delete \",[\"siteName\"]],\"2QRni+\":[\"Time zone updated.\"],\"2UrpGC\":[\"Feed address sent. A directory reads a newly announced feed within \",[\"hours\"],\" hours.\"],\"2ZqpRB\":[\"Turn off\"],\"2cFU6q\":[\"Site Footer\"],\"2fPEPI\":[\"A calm, cool backdrop.\"],\"2lkk2l\":[\"Yellow-tinted paper with an olive-green accent.\"],\"2oWZo7\":[\"Last commit\"],\"2r8pkt\":[\"Couldn't load pages. Try again in a moment.\"],\"2uuy4H\":[\"Connected via Personal Access Token\"],\"2wK4BX\":[\"Edit About page\"],\"35x8eZ\":[\"Showing \",[\"shown\"],\" of \",[\"total\"]],\"39QGku\":[\"Open the bot and send the binding code, then anything you message it becomes a note.\"],\"3B0RD1\":[\"Upload the profile image and generated site icons.\"],\"3Cw1AI\":[\"Add Collection\"],\"3VrybB\":[\"Redirect\"],\"3Yvsaz\":[\"302 (Temporary)\"],\"3n0zbB\":[\"Session management is off in demo mode. Use the shared demo session instead.\"],\"3sYJi5\":[\"Download a Hugo-compatible archive — host it statically or move to another Jant.\"],\"3vMdv3\":[\"This link is reserved. Choose something else.\"],\"3wKq0C\":[\"Couldn't save. Try again in a moment.\"],\"49Bsal\":[\"Feed settings updated.\"],\"4D09NB\":[\"Link to your collections page\"],\"4J/OYU\":[\"Collection created.\"],\"4Jge8E\":[\"Active Sessions\"],\"4KIa+q\":[\"Export downloaded.\"],\"4Q0iPK\":[\"Follow the device appearance or force a light or dark theme.\"],\"4cEClj\":[\"Sessions\"],\"4n7WY4\":[\"Name, visibility, feeds, and time zone\"],\"4tcgrg\":[\"View these posts\"],\"4yyXWu\":[\"Pale bone-white with a muted green accent.\"],\"4zGJ5E\":[\"Delete Account Permanently\"],\"5QlUIt\":[\"Empty repository. Ready to connect.\"],\"5VQnR3\":[\"Use these when you want a feed URL that never changes.\"],\"5dpcN1\":[\"type to search all\"],\"5f1Wo9\":[\"Connected as \",[\"account\"]],\"5o8R81\":[\"Very light ivory with a faint tea-green accent.\"],\"6ArdBh\":[\"Uses featured posts for /feed.\"],\"6DjeBT\":[\"Demo sites always stay hidden from search engines.\"],\"6E3aK4\":[\"Manage Hosting\"],\"6FFB7q\":[\"Uses the latest public posts for /feed.\"],\"6K1Vef\":[\"Delete this blog permanently? This cannot be undone.\"],\"6NpNLc\":[\"This repository has existing content.\"],\"6Pa5AP\":[\"Connect or manage automatic content backups to GitHub.\"],\"6V3Ea3\":[\"Copied\"],\"6WdDG7\":[\"Page\"],\"71WIgc\":[\"Get a new code\"],\"71of4k\":[\"Limit posts included in each RSS feed.\"],\"746NHh\":[\"this blog\"],\"7811AW\":[\"This repository is already backing up this site.\"],\"7FCZPo\":[\"Content language\"],\"7FaY4u\":[\"Usage\"],\"7G9YLi\":[\"Allow search engines to index my site\"],\"7GISOt\":[\"Save bot token\"],\"7MZxzw\":[\"Password changed.\"],\"7p5kLi\":[\"Dashboard\"],\"7vhWI8\":[\"New Password\"],\"81nFIS\":[\"Passwords don't match. Make sure both fields are identical.\"],\"87a/t/\":[\"Label\"],\"89Upyo\":[\"That theme isn't available. Pick another one.\"],\"8BfEpW\":[\"Hosted account\"],\"8NIu3g\":[\"That page has no title yet, so a menu has nothing to show.\"],\"8T46pB\":[\"Bot token\"],\"8U2Z7f\":[\"New Custom URL\"],\"8ZsakT\":[\"Password\"],\"8bpHix\":[\"Couldn't create your account. Check the details and try again.\"],\"8gEghq\":[\"Bright warm-white with a moss-green accent.\"],\"9+vGLh\":[\"Custom CSS\"],\"9As8Nu\":[\"Create one on GitHub\"],\"9EjI4j\":[\"Warm sand\"],\"9Fa2Ns\":[\"The root address goes back to showing every language, and addresses like \",[\"prefix\"],\" redirect to it, so existing links and feed subscriptions keep working. Post addresses and each post's language are unchanged, so you can turn this back on any time.\"],\"9FctRm\":[\"Use lowercase letters, numbers, and hyphens.\"],\"9J6wUO\":[\"Suggested links\"],\"9Lsvt5\":[\"Signed in \",[\"date\"]],\"9SHZas\":[\"Shows 'Settings' when logged in, 'Sign in' when logged out\"],\"9T7Cwm\":[\"Redirects, vanity paths, and URL control\"],\"9aUyym\":[\"See where you're signed in and revoke old sessions\"],\"9mqQnx\":[\"Limit paragraphs used in automatically generated summaries.\"],\"A7tRC9\":[\"Which post stream the canonical /feed URL returns.\"],\"ADTn/D\":[\"Allow published content to be read without an API token.\"],\"AELGTd\":[\"Add it to navigation now or open the editor to add details.\"],\"ANzR96\":[\"Config Editor\"],\"AQL8b1\":[\"What language do you write in?\"],\"AeXO77\":[\"Account\"],\"AnY+O9\":[\"Show \\\"Build with Jant\\\" at the bottom of the home page\"],\"ApZDMk\":[\"This is used for your favicon and apple-touch-icon. For best results, upload a square PNG with a solid background at least 512x512 pixels.\"],\"Aysjjh\":[\"Choose the color palette used across Jant.\"],\"B495Gs\":[\"Archive\"],\"B4ESok\":[\"API reference\"],\"B5P9HE\":[\"Announce my site\"],\"BJ0tsF\":[\"Search runtime settings and open advanced configuration\"],\"BTYdze\":[\"Link added to navigation.\"],\"BszQc4\":[\"The root address (/, /feed) shows this language.\"],\"BzEFor\":[\"or\"],\"C0/57J\":[\"This is the last part of the collection link.\"],\"CDAdlf\":[\"Remove bot\"],\"CTAEes\":[\"Select a repository\"],\"CjZZgz\":[\"This repository already has commits\"],\"Cl92kR\":[\"Create new collection\"],\"D35jh6\":[\"The language of your admin pages. Only you see this.\"],\"D8k2s6\":[\"Connect Telegram\"],\"DCKkhU\":[\"Current Password\"],\"DKKKeF\":[\"Manage password and hosted access in \",[\"providerLabel\"]],\"DVFXa6\":[\"The cleanest, most neutral option.\"],\"DdXUay\":[\"Show the site avatar in the public header.\"],\"E3hjKv\":[\"Add as link\"],\"EKvXGx\":[\"That address is on another site. Navigation holds it as a link.\"],\"EO3I6h\":[\"Upload didn't go through. Try again in a moment.\"],\"Eax/et\":[\"Accent\"],\"EbDLD+\":[\"Choose the typography used across Jant.\"],\"Enslfm\":[\"Destination\"],\"F53UDu\":[\"Cool white\"],\"F7FKwe\":[\"Anything you paste here has full access to your visitors' browsers. Only use code from sources you trust.\"],\"F8SNqr\":[\"Warm orange\"],\"FBgjRN\":[\"Search pages, or paste an address\"],\"FMUJSP\":[\"Account & Data\"],\"FUfPPw\":[[\"next\"],\" will be served at the root address (/, /feed, /archive), and \",[\"previous\"],\" moves to \",[\"prefix\"],\". Post addresses do not change, but anyone subscribed to /feed starts receiving \",[\"next\"],\" posts.\"],\"Fe1cvJ\":[\"Delay new posts and replies before they appear in feeds. Use 0 to turn this off.\"],\"Fk3SSD\":[\"Calm and natural, easy on the eyes.\"],\"FkMol5\":[\"Featured\"],\"FwL2Zk\":[[\"count\",\"plural\",{\"one\":[\"#\",\" post is\"],\"other\":[\"#\",\" posts are\"]}],\" written in \",[\"language\"],\", which is not on this list. Add it back, or change their language first.\"],\"G/1oP+\":[\"Remove the webhook and stop syncing. Your repository content will not be deleted.\"],\"G0qJsQ\":[\"Security token missing. Refresh the page and try again.\"],\"G0tHaW\":[\"Create a public page that won't appear in Latest.\"],\"G2fuEb\":[\"Locked\"],\"G39wnK\":[\"Back up and sync content with a GitHub repository\"],\"G5oCui\":[\"URL structure, per-language feeds, and linking translations.\"],\"G9peMt\":[\"Create the account you write from.\"],\"GAmD3h\":[\"Languages\"],\"GBkMNw\":[[\"name\"],\" is a directory of Jant blogs, curated by hand by the Jant community to help people find new Jant blogs and posts.\"],\"GXsAby\":[\"Revoke\"],\"GdGiNi\":[\"Step \",[\"current\"],\" of \",[\"total\"]],\"GorKul\":[\"Welcome to Jant\"],\"GxkJXS\":[\"Uploading...\"],\"GzKzUa\":[\"Demo limits\"],\"HCNlq3\":[\"Clean and high-contrast, close to white.\"],\"HHDyGw\":[\"Soft green\"],\"HKH+W+\":[\"Data\"],\"Hf/w/z\":[\"Demo sites are never listed in Discover.\"],\"Hp1l6f\":[\"Current\"],\"HxTUmw\":[\"Add \",[\"language\"]],\"HxlY7t\":[\"Changing this updates what subscribers get from /feed.\"],\"HxuOlm\":[\"Site Header\"],\"I0ijRI\":[\"All feed addresses\"],\"I4HRxU\":[\"Every published post, including ones hidden from Latest.\"],\"I6gXOa\":[\"Path\"],\"I76CzF\":[\"Neutral gray\"],\"ID38tA\":[\"Account deletion is off in demo mode. The shared demo resets separately.\"],\"IF9tPu\":[\"When to use site export, database backups, and recovery drills.\"],\"IW5PBo\":[\"Copy Token\"],\"IagCbF\":[\"URL\"],\"IreQBq\":[\"Repository\"],\"J36Xsm\":[\"Nothing at \",[\"address\"],\". Check it, or search by title.\"],\"J6bLeg\":[\"Add a custom link to any URL\"],\"JL7LF5\":[\"available CSS variables, data attributes, and examples.\"],\"JcD7qf\":[\"More actions\"],\"JjX0OO\":[\"Copy your token now — it won't be shown again.\"],\"JrFTcr\":[\"Connecting…\"],\"JuN5GC\":[\"No file selected. Choose a file to upload.\"],\"K+0Hu0\":[\"No matching pages available to add. Try another title or create a new page.\"],\"K/F6pa\":[\"Saving…\"],\"KDw4GX\":[\"Try again\"],\"KSgo21\":[\"Pick a repository\"],\"KVVYBh\":[\"Add collection to navigation\"],\"KiJn9B\":[\"Note\"],\"Kk7jwL\":[\"Set posts per archive page; reset to inherit the main page size.\"],\"KwOLJF\":[\"The original Jant palette, and a solid everyday pick.\"],\"L+rMC9\":[\"Reset to default\"],\"L27RpE\":[\"Page created.\"],\"L3DEwT\":[\"Remove this avatar? Your favicon and header icon will go back to the default.\"],\"L4t4/q\":[\"March 14\"],\"L86zmP\":[\"Edit the multi-line introduction used on your home page and in metadata.\"],\"LdyooL\":[\"link\"],\"LhMjLm\":[\"Time\"],\"LjwaJ/\":[\"Sign-in, export, and deletion\"],\"M/D8PK\":[\"+ Install on another account\"],\"M/haSd\":[\"Always show the light version of the theme.\"],\"M/kDIW\":[\"The language your readers and search engines see.\"],\"M1co/O\":[\"Configured\"],\"M2hGyf\":[\"Links to /subscribe, a page listing your feeds with copy buttons. Best for readers who don't already use one.\"],\"M2kIWU\":[\"Font theme\"],\"M4tzVU\":[\"Latest posts\"],\"M6CbAU\":[\"Toggle edit panel\"],\"M7wPsD\":[\"Switch\"],\"MHrjPM\":[\"Title\"],\"MKIM3K\":[\"Search pages\"],\"MaYYE6\":[\"Post notes by messaging a Telegram bot\"],\"Me5t5H\":[\"Connect a GitHub repository to automatically back up your posts as Markdown files. Edits on GitHub sync back to your site.\"],\"MeCJlL\":[\"Announcing your site. Reload to see the result.\"],\"MnbH31\":[\"page\"],\"Mq9FZ1\":[\"Creating page…\"],\"Mr4QPw\":[\"Disconnect Telegram? You can reconnect any time with a new binding code.\"],\"MtENL9\":[\"Tune how your site looks, reads, and runs.\"],\"N/8NPV\":[\"Before deleting, download a site export. You won't be able to recover this account after deletion.\"],\"N7UNHY\":[\"Featured feed\"],\"NHnUHF\":[\"Favicon and the profile mark in your header\"],\"NU2Fqi\":[\"Save CSS\"],\"NVjhde\":[\"Warm parchment\"],\"Nldjdr\":[\"No custom URLs yet. Create one to add redirects or custom paths for posts.\"],\"O3oNi5\":[\"Email\"],\"OJxdgi\":[\"Keep this link under 200 characters.\"],\"OSJXFg\":[\"Applies to your entire site, including admin pages. Pick a palette, then choose whether it follows the system or stays fixed.\"],\"OeUWA7\":[\"Add Page\"],\"OuuMXJ\":[\"Add site-wide HTML before the closing body tag.\"],\"Ox3+3h\":[\"No matches.\"],\"P7Eeay\":[\"Full posts\"],\"PEUV5I\":[\"Code injection updated.\"],\"PHh52z\":[\"Warm and rich, with strong brown tones.\"],\"PXj9lw\":[\"Stop accepting posts from Telegram. Your existing notes stay published.\"],\"PZ7HJ8\":[\"Blog Avatar\"],\"Pbm2/N\":[\"Create Collection\"],\"Pwqkdw\":[\"Loading…\"],\"PxJ9W6\":[\"Generate Token\"],\"Q/6Y+2\":[\"Needs Contents (read/write) and Webhooks (read/write) on the target repository.\"],\"Q/O0X4\":[\"This setting wasn't saved. Check the value and try again.\"],\"Q30z/l\":[\"Remove this collection from navigation? The collection itself won't be deleted.\"],\"Q99OtV\":[\"Pin a collection to your navigation bar. An asterisk (*) appears next to collections updated in the last 48 hours.\"],\"QCwsv1\":[\"Warm off-white\"],\"QKvrmL\":[\"Warm-neutral and easy for long reading.\"],\"QZmz0H\":[\"Built-in links\"],\"Qnrzvb\":[\"Active Tokens\"],\"R6Z4LE\":[\"Download failed. Please try again.\"],\"R9Khdg\":[\"Auto\"],\"RDjuBN\":[\"Setup\"],\"RRo9kN\":[\"Language updated.\"],\"RcdDOS\":[\"Create a bot by messaging @BotFather on Telegram, then paste the token it gives you.\"],\"RdVIcf\":[\"Cream and coffee brown\"],\"Ri/9PY\":[\"This site still limits Discover to featured posts, and no post is marked Featured, so your feed carries nothing to show. Untick and tick the box to let Discover read every public post.\"],\"Rn2p1h\":[\"Nothing matches this search. Try a different name or description.\"],\"RxsRD6\":[\"Time Zone\"],\"SDND4q\":[\"Not configured\"],\"SJmfuf\":[\"Site Name\"],\"SKZhW9\":[\"Token name\"],\"SSsoa4\":[\"Add to Navigation\"],\"SVQQPe\":[\"Couldn't connect. Check the error and try again.\"],\"SWb0z+\":[\"That address is reserved. Choose another one.\"],\"SYGk01\":[\"The languages served under a URL prefix. Managed on the Language page.\"],\"SchpMp\":[\"Telegram\"],\"SeY4vo\":[[\"language\"],\" is the only other language on this site, so removing it turns multilingual content off. The root address goes back to showing every language, \",[\"prefix\"],\" stops working, and each post keeps the language it is written in.\"],\"SqKp3o\":[\"The title used across your site, browser tabs, and feeds.\"],\"SrGs4T\":[\"Light blue-gray background, cool and even.\"],\"T/R+Qz\":[\"Primary\"],\"T17dXm\":[\"Whether each language gets its own home page, archive, and feed. Managed on the Language page.\"],\"T41PG1\":[\"Limit characters used in automatically generated summaries.\"],\"TN0mN4\":[\"Search and edit runtime settings. Changes apply immediately; reset restores the environment or built-in default.\"],\"TSCeuF\":[\"Couldn't create the collection. Check the details and try again.\"],\"TpF3v+\":[\"Injected before </head>. Use for analytics, custom meta tags, and styles that must load early.\"],\"Tu6bMZ\":[\"Create About page\"],\"Tz0i8g\":[\"Settings\"],\"U5J7jI\":[\"Site visibility updated.\"],\"U5v6Gh\":[\"Edit Page\"],\"UFK415\":[\"Site-wide HTML for analytics and widgets\"],\"UTvFQq\":[\"Open \",[\"linkOpen\"],\"@\",[\"botUsername\"],[\"linkClose\"],\" and send:\"],\"UUn+Y5\":[\"Open setting\"],\"UaZwcz\":[\"More options are available after you create it.\"],\"Uj/btJ\":[\"Display avatar in my site header\"],\"UsODUn\":[\"Select an account\"],\"UxKoFf\":[\"Navigation\"],\"UyMSeQ\":[\"At that address\"],\"V+bhUy\":[\"Install GitHub App\"],\"V0fyg5\":[\"Collection added to navigation.\"],\"V4WsyL\":[\"Add Link\"],\"V5pZwT\":[\"Search settings updated.\"],\"V7dQi9\":[\"Language removed.\"],\"VXUPla\":[\"Connect with GitHub App\"],\"Vh+JIV\":[\"Multilingual guide\"],\"VhMDMg\":[\"Change Password\"],\"Vn3jYy\":[\"Navigation items\"],\"VoZYGU\":[\"This will permanently delete all your data — posts, media, collections, settings, and your account. Your blog will be reset to its initial setup state. This cannot be undone.\"],\"VoarBQ\":[\"Post addresses do not change, and you can turn this off again at any time.\"],\"VqyJ7Y\":[\"Primary language changed.\"],\"WL7KjI\":[\"Tile grid\"],\"WUnFK2\":[\"Pale cool-white with deep indigo text. High contrast.\"],\"Wa9q4P\":[\"Pure white\"],\"Wb7EHo\":[\"About page\"],\"Weq9zb\":[\"General\"],\"Wi9i06\":[\"Follow each visitor's system preference.\"],\"Wildi8\":[\"No pages available. Create one to add it to navigation.\"],\"Wx1M8N\":[\"Install the GitHub App to grant access without managing personal tokens. Permissions are scoped per repository and revocable from GitHub.\"],\"X+8FMk\":[\"Current password doesn't match. Try again.\"],\"X1G9eY\":[\"Navigation Preview\"],\"X2Cbc2\":[\"Archive feed\"],\"X5P6yv\":[\"Recently updated\"],\"X9Hujr\":[\"Manual Push\"],\"XQQOyj\":[\"That page is a draft. Publish it, then add it.\"],\"XeRkls\":[[\"count\",\"plural\",{\"one\":[\"#\",\" existing post\"],\"other\":[\"#\",\" existing posts\"]}],\" with no language yet will be marked as \",[\"language\"],\".\"],\"Xsu5WL\":[\"Add site-wide CSS in the dedicated code editor.\"],\"XtBJV8\":[\"Checking repository…\"],\"Xtc16w\":[\"Refresh repository list\"],\"Y+7JGK\":[\"Create Page\"],\"Y/F35r\":[\"Create a post with curl:\"],\"Y/N5N7\":[\"Soft cream background with a muted green accent.\"],\"YF6zHf\":[\"Site settings updated.\"],\"YVcVlW\":[\"Remove and turn off\"],\"Ya/FAk\":[\"Add at least one more language to turn this on.\"],\"YdG2RF\":[\"Export Site\"],\"YkgZi7\":[\"Connect a Telegram bot, then anything you message it gets published as a note.\"],\"YwhjRx\":[\"Manage Account\"],\"Yxp859\":[\"Warm cream\"],\"Z5HWHd\":[\"On\"],\"ZDY7Fy\":[\"Syncing…\"],\"ZQKLI1\":[\"Danger Zone\"],\"ZS/CBL\":[\"Delete this navigation link? Visitors won't see it in your site header anymore.\"],\"ZXZrAo\":[\"Keep the page address under 200 characters.\"],\"ZgZX+d\":[\"Pure white with neutral grays. No color tint.\"],\"Zgq+c2\":[\"Set the default number of items shown per page.\"],\"ZhhOwV\":[\"Quote\"],\"ZiooJI\":[\"API Tokens\"],\"Zm7Qb0\":[\"Backup & Restore Guide\"],\"ZmUkwN\":[\"Add custom link to navigation\"],\"a14mj8\":[\"Unknown device\"],\"a1iEgy\":[\"Warm cream background with deep coffee-brown accents.\"],\"a3LDKx\":[\"Security\"],\"aAIQg2\":[\"Appearance\"],\"aFkzVF\":[\"The slug of the target post or collection\"],\"aR3U86\":[\"Multilingual content is on. \",[\"count\",\"plural\",{\"one\":[\"#\",\" post was marked\"],\"other\":[\"#\",\" posts were marked\"]}],\" as \",[\"language\"],\".\"],\"aV6XWN\":[\"Multilingual content is off. Your languages are still saved.\"],\"alKG0+\":[\"Font Theme\"],\"anibOb\":[\"About this blog\"],\"any7NR\":[\"Theming guide\"],\"asq0vL\":[\"The language you write in.\"],\"b+/jO6\":[\"301 (Permanent)\"],\"b+FyBD\":[\"Add page to navigation\"],\"b1FYSK\":[\"Primary language\"],\"bHOiy1\":[\"Password changes are off in demo mode. Sign in with the shared demo credentials.\"],\"bHYIks\":[\"Sign Out\"],\"bV2vng\":[\"Warm terracotta\"],\"bbR5vW\":[\"This palette\"],\"bbzY7X\":[\"Manage sign-in security, site exports, and irreversible actions.\"],\"bfHZ7r\":[\"Choose the time zone used to display dates and times.\"],\"bi10qS\":[\"Add it to navigation now or open the editor to add content.\"],\"bkMuwo\":[\"Link to posts you've marked as featured.\"],\"bmrL08\":[\"Demo mode hides sessions, password changes, and account deletion. Export still works.\"],\"bph1Dd\":[\"Search engine indexing is off, so this site is not listed by default. Ticking the box above lists it anyway.\"],\"brfpw9\":[\"Edit the multi-line footer rendered at the bottom of public pages.\"],\"bviiKV\":[\"Headings, body text, and links in this theme.\"],\"c1BGrV\":[\"Already in navigation. Drag it in the list above to move it.\"],\"c1iSrq\":[\"Discover community rules\"],\"c3MN2z\":[\"all available endpoints and request formats.\"],\"cHh/Zu\":[\"Turn on multilingual content\"],\"cS7/bk\":[\"Remove the saved bot token? Its webhook is deleted and any connected account is disconnected.\"],\"cSDy01\":[\"Custom CSS updated.\"],\"clzoNp\":[\"Always show the dark version of the theme.\"],\"cnGeoo\":[\"Delete\"],\"cwaLCZ\":[\"Page added to navigation.\"],\"d1lzY/\":[\"Language added.\"],\"d3FRkY\":[\"Could not copy. Try again.\"],\"d5oGUo\":[\"Create a new repository on GitHub\"],\"dB1Nr4\":[\"Start writing\"],\"dEgA5A\":[\"Cancel\"],\"dTXUY+\":[\"Confirm account deletion\"],\"dYKrp3\":[\"Hidden from Latest\"],\"dk7TCH\":[\"Permanently delete all data and reset the blog\"],\"ds0nJk\":[\"Add site-wide HTML before the closing head tag.\"],\"dsWkIw\":[\"Disconnect from GitHub? The webhook will be removed. Your repository content will not be deleted.\"],\"dwcK1n\":[\"Or submit your address by hand\"],\"e/tSI5\":[\"Navigation order updated.\"],\"eOL7vn\":[\"Minimal color, low distraction.\"],\"ePK91l\":[\"Edit\"],\"ebQKK7\":[\"Site\"],\"eeamrQ\":[\"Discover reads your Atom feed, so it needs feeds turned on.\"],\"egK+Yy\":[\"Bearer tokens for scripts and automation\"],\"egOXl0\":[\"Jant Discover\"],\"ehj/zN\":[\"Redirect Type\"],\"ej6Rji\":[\"Any post written in another language can be corrected from its own menu afterwards.\"],\"eneWvv\":[\"Draft\"],\"erTMh7\":[\"Last synced\"],\"f+m8jj\":[\"Feed URL copied.\"],\"f8fH8W\":[\"Design\"],\"fDz6PV\":[\"Choose the repository used for content backups.\"],\"fKRAwQ\":[\"Sandy background with a green accent.\"],\"fWYqkz\":[\"Code Injection\"],\"fYXQnC\":[\"Cozy and bold among the warm tones.\"],\"fttd2R\":[\"My Collection\"],\"gZ5owP\":[\"Search repositories\"],\"gbqbh6\":[\"Safe to leave this page — syncing continues in the background.\"],\"gkFvVN\":[\"Injected before </body>. Use for chat widgets and scripts that should not block page load.\"],\"gtQsRO\":[\"Create Custom URL\"],\"hBO/y4\":[\"Security token expired. Refresh the page and try again.\"],\"hGmyDl\":[\"Tokens let you access the API from scripts, shortcuts, and other tools without signing in.\"],\"hIHkRy\":[\"Connected via GitHub App\"],\"hJHHsU\":[\"Publish Atom feeds for the site, archive, and collections.\"],\"hcH8MY\":[\"Set up your site\"],\"hdSi1b\":[\"Type \",[\"repo\"],\" to confirm\"],\"he3ygx\":[\"Copy\"],\"hjeS3W\":[\"Link to your latest posts. Your homepage shows this feed.\"],\"hjvSlw\":[\"Language removed. Multilingual content is off.\"],\"hvGGMK\":[\"Remove this page from navigation? The page itself won't be deleted.\"],\"i0qMbr\":[\"Home\"],\"iEUzMn\":[\"system\"],\"iH8pgl\":[\"Back\"],\"iMkWoF\":[\"Turn on\"],\"iSLIjg\":[\"Connect\"],\"iVOMRi\":[\"Home settings updated.\"],\"icB4Cv\":[\"Drag links here to show them under the More menu\"],\"id3vuh\":[\"Telegram is set up, but the bot couldn't be reached. Check the bot token and try again.\"],\"idD8Ev\":[\"Saved\"],\"ihn4zD\":[\"Search…\"],\"iiDXZc\":[\"Displayed at the bottom of all posts and pages.\"],\"itS31B\":[\"A warmer look, like slightly aged paper.\"],\"iwQZvS\":[\"Cool blue-gray\"],\"j4VrG6\":[\"Download Export ZIP\"],\"j5nQL2\":[\"e.g. iOS Shortcuts\"],\"jNE7O+\":[\"Nothing published yet. jant.me lists a blog once it has \",[\"minCount\",\"plural\",{\"one\":[\"one public post\"],\"other\":[\"#\",\" public posts\"]}],\".\"],\"jUV7CU\":[\"Upload Avatar\"],\"jVUmOK\":[\"Markdown supported\"],\"jdVYS8\":[\"Pick the one that fits your writing.\"],\"jgBjXJ\":[\"Revoke this token? Any scripts using it will stop working.\"],\"jpctdh\":[\"View\"],\"k1ifdL\":[\"Processing...\"],\"kLw03Y\":[\"Bright paper white\"],\"kMXclu\":[\"Download a site export\"],\"kNiQp6\":[\"Pinned\"],\"kQ3Otm\":[\"Create new page\"],\"kRhzWq\":[\"GitHub Sync\"],\"kVQs7s\":[\"Fine-grained styling overrides\"],\"ke1gWS\":[\"Custom URLs\"],\"kfcRb0\":[\"Avatar\"],\"kp8wiR\":[\"Checking address…\"],\"kxDZ2i\":[\"This code runs on every page of your site.\"],\"kzvWob\":[\"Link to the post archive\"],\"lLW3vJ\":[\"Target Slug\"],\"lLsfOE\":[\"Turn off multilingual content?\"],\"lV04bQ\":[\"Warm and earthy, but still light.\"],\"lYHJih\":[\"Revoke this session? That device will need to sign in again.\"],\"m16xKo\":[\"Add\"],\"mLOk1i\":[\"Push all posts to GitHub right now instead of waiting for the next automatic sync.\"],\"mSNmrX\":[\"List posts:\"],\"n8+EXe\":[\"Add common destinations that already exist on your site.\"],\"nG2qTk\":[\"Example link\"],\"nK07ni\":[\"Choose a typographic direction for your site. Each theme changes both the font pairing and the reading rhythm.\"],\"nbfdhU\":[\"Integrations\"],\"ntJYyh\":[\"Domains, plan, and billing in \",[\"providerLabel\"]],\"o/vNDE\":[\"lets you override any theme variable.\"],\"o5rj+L\":[\"No collections yet. Create one here to add it to navigation.\"],\"oGC9uP\":[\"owner/repo\"],\"oH2JHg\":[\"We'll prefill the name \",[\"name\"],\". The list refreshes on return.\"],\"oKOOsY\":[\"Color Theme\"],\"oL535e\":[\"Not synced yet\"],\"oNA4If\":[\"All collections are already in your navigation.\"],\"oUn9Z7\":[\"Near-neutral light gray with a steel-blue accent.\"],\"ofdy2l\":[\"Orange-tinted background. The warmest palette.\"],\"olouYg\":[\"Navigation holds that address as a link.\"],\"oxj6Pk\":[\"Other languages\"],\"pIpTqF\":[\"Give each language its own home page, archive, and feed. Once it's on, you pick a language when you publish, and can link an existing post to a version of it in another language.\"],\"pNXxtS\":[\"Choose the content language announced to readers and search engines.\"],\"pZq3aX\":[\"Upload failed. Please try again.\"],\"pgJImo\":[\"Change the primary language?\"],\"pgTIrt\":[\"Choose the GitHub account and repository to sync with this site.\"],\"psoxDF\":[\"That font theme isn't available. Pick another one.\"],\"pt4OhQ\":[\"/about is already used. Rename that item before creating an About page.\"],\"pvnfJD\":[\"Dark\"],\"q+hNag\":[\"Collection\"],\"q/T5GS\":[\"The language used by the private Jant dashboard.\"],\"qSgO/Y\":[\"Follow content language\"],\"qZ9jzv\":[\"Site visibility\"],\"qdcESc\":[\"Create a new repository\"],\"qkSJzV\":[\"Searching pages…\"],\"r5EW6f\":[\"This repository is already backing up another Jant site (\",[\"host\"],\"). Pick a different repository.\"],\"rCPrbS\":[\"Options for \",[\"language\"]],\"rEspiY\":[\"Navigation placement updated.\"],\"rFmBG3\":[\"Color theme\"],\"re0mF0\":[\"The page is public but stays out of Latest.\"],\"rlonmB\":[\"Couldn't delete. Try again in a moment.\"],\"s3jOk7\":[\"Enter a page title.\"],\"sROtqR\":[\"The directory could not be reached: \",[\"reason\"]],\"sRmGLp\":[\"You can change all of this later in Settings.\"],\"satWc6\":[\"Main RSS feed\"],\"sgr2wQ\":[\"collection\"],\"sj4LLc\":[\"Show only modified\"],\"sjej3N\":[\"Remove \",[\"language\"]],\"slujBW\":[\"Use lowercase letters, numbers, and hyphens only.\"],\"soRdOu\":[\"Off-white paper with a deep forest-green accent.\"],\"sqxcaY\":[\"Created \",[\"date\"]],\"sxkWRg\":[\"Advanced\"],\"t/YqKh\":[\"Remove\"],\"t3hvHq\":[\"Sync Now\"],\"tJ4H0O\":[\"your Telegram account\"],\"tfDRzk\":[\"Save\"],\"tgWuMB\":[\"Modified\"],\"tvgAq5\":[\"No accounts authorized yet\"],\"u1VTd3\":[\"Palette, surface tone, and overall mood\"],\"u3wRF+\":[\"Published\"],\"u6KOjV\":[\"Want more control?\"],\"uKLe0J\":[[\"count\"],\" settings shown\"],\"uVZcIA\":[\"That address is already in use. Choose another one.\"],\"udPwLB\":[\"Header\"],\"ugHDtd\":[[\"about\"],\" A post you mark Featured appears on the Discover home page \",[\"hours\"],\" hours later, and link and quote posts appear on the \",[\"links\"],\" and \",[\"quotes\"],\" lists \",[\"hours\"],\" hours after they are published. You can keep editing them in the meantime. See the \",[\"rules\"],\".\"],\"ui6aMF\":[\"These devices are currently signed in to your account. Revoke any session you don't recognize.\"],\"vBEKwo\":[\"Manage this site's active sessions here. Password and hosted access are managed through \",[\"providerLabel\"],\".\"],\"vOnuOa\":[\"Show or hide built-in destinations in the header and More menu.\"],\"vRldcl\":[\"Typography choices and reading texture\"],\"vSYKYI\":[\"Main feed\"],\"vTuib7\":[\"This controls what /feed returns.\"],\"vXCC6J\":[\"Something doesn't look right. Check the form and try again.\"],\"vXIe7J\":[\"Language\"],\"vXsx3x\":[\"That page is private, so nobody could open it from a menu.\"],\"vdFnYM\":[\"Reset link\"],\"vmQmHx\":[\"Add custom CSS to override any styles. Use data attributes like [data-page], [data-post], [data-format] to target specific elements.\"],\"vpSPA1\":[\"Auth secret is missing. Check your environment variables.\"],\"vzX5FB\":[\"Delete Account\"],\"w615zC\":[\"Multilingual content\"],\"w8Rv8T\":[\"Label is required\"],\"wL3cK8\":[\"Latest\"],\"wW6NCp\":[\"Last error\"],\"wc+17X\":[\"/* Your custom CSS here */\"],\"wuLtXn\":[\"No active sessions right now. Signed-in devices show up here.\"],\"x+HGBk\":[\"Ask search engines not to index public pages or include them in results.\"],\"xCWek4\":[\"File storage isn't set up. Check your server config.\"],\"xCbjQn\":[\"Allow \",[\"name\"],\" to list my site\"],\"xGVfLh\":[\"Continue\"],\"xHt036\":[\"Personal Access Token\"],\"xKeZ0l\":[\"An earthier, warmer tone.\"],\"xYbozN\":[\"Soft ivory\"],\"xqViCq\":[\"Warm ivory\"],\"xxaahd\":[\"When you want a cooler, sharper look.\"],\"y/awtV\":[\"Header links, built-in destinations, and overflow menu\"],\"y28hnO\":[\"Post\"],\"y9W9vo\":[\"Creating collection…\"],\"yNCqOt\":[\"Latest feed\"],\"yQ3kNF\":[\"Type the following phrase to confirm:\"],\"ydq1k2\":[\"Pick an account first\"],\"yjjCV8\":[\"Fixed feed URLs\"],\"yjkELF\":[\"Confirm New Password\"],\"ym+ccl\":[\"Show the Jant credit on the home page.\"],\"yzF66j\":[\"Link\"],\"z6wakA\":[\"A short intro shown on your home page.\"],\"zEizrk\":[\"Last used \",[\"date\"]],\"zPqly9\":[\"This site has no directory to announce to.\"],\"zSURJW\":[\"No repositories match.\"],\"zUlHGd\":[\"Page address\"],\"zYRGIR\":[\"Not announced yet. No directory has been told this site exists.\"],\"zcDmsG\":[\"Featured posts\"],\"zlcDd2\":[\"Delete this custom URL? Visitors using it won't be redirected anymore.\"],\"ztPYIR\":[\"One-time change to your existing posts\"],\"zwBp5t\":[\"Private\"],\"zxexio\":[\"Content language, dashboard language, multilingual\"]}")as Messages;
1
+ /*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"+4Z6iP\":[\"Create the repository on GitHub first — it can be empty.\"],\"+9JI/F\":[\"Connecting will sync your site onto \",[\"repo\"],\"'s default branch on top of its existing history. Existing files outside Jant's managed paths are kept. This can't be undone.\"],\"+AXdXp\":[\"Label and URL are required\"],\"+K0AvT\":[\"Disconnect\"],\"+V/jXc\":[\"Links straight to /feed — the raw Atom file, currently your \",[\"feed\"],\" feed. Best for readers who already use a feed reader.\"],\"+VEqyj\":[\"Make primary\"],\"+jXHMG\":[[\"count\",\"plural\",{\"one\":[\"#\",\" post is\"],\"other\":[\"#\",\" posts are\"]}],\" still written in \",[\"language\"],\". Change their language, or keep the language.\"],\"+wgt7C\":[\"Muted red-brown background, earthy and warm.\"],\"+zy2Nq\":[\"Type\"],\"/0D1Xp\":[\"Edit Collection\"],\"/3H2/s\":[\"This hosted site signs in through \",[\"providerLabel\"],\". Manage password and hosted access there.\"],\"/PXXBT\":[\"Nearly white, with a touch of warmth.\"],\"/PoNoq\":[\"Edit link\"],\"/zOUxl\":[\"QR code linking to the Telegram bot\"],\"05DXsb\":[\"Connect or manage the bot used to post from Telegram.\"],\"0OGSSc\":[\"Avatar display updated.\"],\"0UzCUX\":[\"Update the password you use to sign in\"],\"0VVvqu\":[\"Multilingual content is on.\"],\"0bdA9b\":[\"Open Telegram to connect\"],\"0dieZ/\":[\"Which layout /archive opens with. Readers can switch layouts from the page.\"],\"0gECZD\":[\"Want to write a fuller introduction?\"],\"0uIjy/\":[\"Light sage-green with a matching green accent.\"],\"1DahsC\":[\"Search settings\"],\"1F6Mzc\":[\"No navigation items yet. Add links or enable system items below.\"],\"1H7gng\":[\"Dashboard language\"],\"1MYU3o\":[\"Couldn't create the page. Check the details and try again.\"],\"1mbBbL\":[\"Connect manually\"],\"1njn7W\":[\"Light\"],\"1pD+7W\":[\"Demo sites are never listed in \",[\"name\"],\".\"],\"1qGdnL\":[\"The default. Calm and easy for long reading.\"],\"1wdDm9\":[\"Add language\"],\"21mg6u\":[\"Choose a titled note that isn't already in navigation, or create a new page.\"],\"2C7mSG\":[\"Collection link\"],\"2DoBvq\":[\"Feeds\"],\"2Et8jU\":[\"Set results per search page; reset to inherit the main page size.\"],\"2FYpfJ\":[\"More\"],\"2Ithfh\":[\"Message the bot any text and it's published as a note.\"],\"2PTjMB\":[\"I want to delete \",[\"siteName\"]],\"2QRni+\":[\"Time zone updated.\"],\"2UrpGC\":[\"Feed address sent. A directory reads a newly announced feed within \",[\"hours\"],\" hours.\"],\"2ZqpRB\":[\"Turn off\"],\"2cFU6q\":[\"Site Footer\"],\"2fPEPI\":[\"A calm, cool backdrop.\"],\"2lkk2l\":[\"Yellow-tinted paper with an olive-green accent.\"],\"2oWZo7\":[\"Last commit\"],\"2r8pkt\":[\"Couldn't load pages. Try again in a moment.\"],\"2uuy4H\":[\"Connected via Personal Access Token\"],\"2wK4BX\":[\"Edit About page\"],\"35x8eZ\":[\"Showing \",[\"shown\"],\" of \",[\"total\"]],\"39QGku\":[\"Open the bot and send the binding code, then anything you message it becomes a note.\"],\"3B0RD1\":[\"Upload the profile image and generated site icons.\"],\"3Cw1AI\":[\"Add Collection\"],\"3VrybB\":[\"Redirect\"],\"3Yvsaz\":[\"302 (Temporary)\"],\"3n0zbB\":[\"Session management is off in demo mode. Use the shared demo session instead.\"],\"3sYJi5\":[\"Download a Hugo-compatible archive — host it statically or move to another Jant.\"],\"3vMdv3\":[\"This link is reserved. Choose something else.\"],\"3wKq0C\":[\"Couldn't save. Try again in a moment.\"],\"49Bsal\":[\"Feed settings updated.\"],\"4D09NB\":[\"Link to your collections page\"],\"4J/OYU\":[\"Collection created.\"],\"4Jge8E\":[\"Active Sessions\"],\"4KIa+q\":[\"Export downloaded.\"],\"4Q0iPK\":[\"Follow the device appearance or force a light or dark theme.\"],\"4cEClj\":[\"Sessions\"],\"4n7WY4\":[\"Name, visibility, feeds, and time zone\"],\"4tcgrg\":[\"View these posts\"],\"4yyXWu\":[\"Pale bone-white with a muted green accent.\"],\"4zGJ5E\":[\"Delete Account Permanently\"],\"5QlUIt\":[\"Empty repository. Ready to connect.\"],\"5VQnR3\":[\"Use these when you want a feed URL that never changes.\"],\"5dpcN1\":[\"type to search all\"],\"5f1Wo9\":[\"Connected as \",[\"account\"]],\"5o8R81\":[\"Very light ivory with a faint tea-green accent.\"],\"6ArdBh\":[\"Uses featured posts for /feed.\"],\"6DjeBT\":[\"Demo sites always stay hidden from search engines.\"],\"6E3aK4\":[\"Manage Hosting\"],\"6FFB7q\":[\"Uses the latest public posts for /feed.\"],\"6K1Vef\":[\"Delete this blog permanently? This cannot be undone.\"],\"6NpNLc\":[\"This repository has existing content.\"],\"6Pa5AP\":[\"Connect or manage automatic content backups to GitHub.\"],\"6V3Ea3\":[\"Copied\"],\"6WdDG7\":[\"Page\"],\"71WIgc\":[\"Get a new code\"],\"71of4k\":[\"Limit posts included in each RSS feed.\"],\"746NHh\":[\"this blog\"],\"7811AW\":[\"This repository is already backing up this site.\"],\"7FCZPo\":[\"Content language\"],\"7FaY4u\":[\"Usage\"],\"7G9YLi\":[\"Allow search engines to index my site\"],\"7GISOt\":[\"Save bot token\"],\"7MZxzw\":[\"Password changed.\"],\"7p5kLi\":[\"Dashboard\"],\"7vhWI8\":[\"New Password\"],\"81nFIS\":[\"Passwords don't match. Make sure both fields are identical.\"],\"87a/t/\":[\"Label\"],\"89Upyo\":[\"That theme isn't available. Pick another one.\"],\"8BfEpW\":[\"Hosted account\"],\"8NIu3g\":[\"That page has no title yet, so a menu has nothing to show.\"],\"8T46pB\":[\"Bot token\"],\"8U2Z7f\":[\"New Custom URL\"],\"8ZsakT\":[\"Password\"],\"8bpHix\":[\"Couldn't create your account. Check the details and try again.\"],\"8gEghq\":[\"Bright warm-white with a moss-green accent.\"],\"9+vGLh\":[\"Custom CSS\"],\"9As8Nu\":[\"Create one on GitHub\"],\"9EjI4j\":[\"Warm sand\"],\"9Fa2Ns\":[\"The root address goes back to showing every language, and addresses like \",[\"prefix\"],\" redirect to it, so existing links and feed subscriptions keep working. Post addresses and each post's language are unchanged, so you can turn this back on any time.\"],\"9FctRm\":[\"Use lowercase letters, numbers, and hyphens.\"],\"9J6wUO\":[\"Suggested links\"],\"9Lsvt5\":[\"Signed in \",[\"date\"]],\"9SHZas\":[\"Shows 'Settings' when logged in, 'Sign in' when logged out\"],\"9T7Cwm\":[\"Redirects, vanity paths, and URL control\"],\"9aUyym\":[\"See where you're signed in and revoke old sessions\"],\"9mqQnx\":[\"Limit paragraphs used in automatically generated summaries.\"],\"A7tRC9\":[\"Which post stream the canonical /feed URL returns.\"],\"ADTn/D\":[\"Allow published content to be read without an API token.\"],\"AELGTd\":[\"Add it to navigation now or open the editor to add details.\"],\"ANzR96\":[\"Config Editor\"],\"AQL8b1\":[\"What language do you write in?\"],\"AeXO77\":[\"Account\"],\"AnY+O9\":[\"Show \\\"Build with Jant\\\" at the bottom of the home page\"],\"ApZDMk\":[\"This is used for your favicon and apple-touch-icon. For best results, upload a square PNG with a solid background at least 512x512 pixels.\"],\"Aysjjh\":[\"Choose the color palette used across Jant.\"],\"B495Gs\":[\"Archive\"],\"B4ESok\":[\"API reference\"],\"B5P9HE\":[\"Announce my site\"],\"BJ0tsF\":[\"Search runtime settings and open advanced configuration\"],\"BTYdze\":[\"Link added to navigation.\"],\"BszQc4\":[\"The root address (/, /feed) shows this language.\"],\"BzEFor\":[\"or\"],\"C0/57J\":[\"This is the last part of the collection link.\"],\"CDAdlf\":[\"Remove bot\"],\"CTAEes\":[\"Select a repository\"],\"CjZZgz\":[\"This repository already has commits\"],\"Cl92kR\":[\"Create new collection\"],\"D35jh6\":[\"The language of your admin pages. Only you see this.\"],\"D8k2s6\":[\"Connect Telegram\"],\"DCKkhU\":[\"Current Password\"],\"DKKKeF\":[\"Manage password and hosted access in \",[\"providerLabel\"]],\"DVFXa6\":[\"The cleanest, most neutral option.\"],\"DdXUay\":[\"Show the site avatar in the public header.\"],\"E3hjKv\":[\"Add as link\"],\"EKvXGx\":[\"That address is on another site. Navigation holds it as a link.\"],\"EO3I6h\":[\"Upload didn't go through. Try again in a moment.\"],\"Eax/et\":[\"Accent\"],\"EbDLD+\":[\"Choose the typography used across Jant.\"],\"Enslfm\":[\"Destination\"],\"F53UDu\":[\"Cool white\"],\"F7FKwe\":[\"Anything you paste here has full access to your visitors' browsers. Only use code from sources you trust.\"],\"F8SNqr\":[\"Warm orange\"],\"FBgjRN\":[\"Search pages, or paste an address\"],\"FMUJSP\":[\"Account & Data\"],\"FUfPPw\":[[\"next\"],\" will be served at the root address (/, /feed, /archive), and \",[\"previous\"],\" moves to \",[\"prefix\"],\". Post addresses do not change, but anyone subscribed to /feed starts receiving \",[\"next\"],\" posts.\"],\"Fe1cvJ\":[\"Delay new posts and replies before they appear in feeds. Use 0 to turn this off.\"],\"Fk3SSD\":[\"Calm and natural, easy on the eyes.\"],\"FkMol5\":[\"Featured\"],\"FwL2Zk\":[[\"count\",\"plural\",{\"one\":[\"#\",\" post is\"],\"other\":[\"#\",\" posts are\"]}],\" written in \",[\"language\"],\", which is not on this list. Add it back, or change their language first.\"],\"G/1oP+\":[\"Remove the webhook and stop syncing. Your repository content will not be deleted.\"],\"G0qJsQ\":[\"Security token missing. Refresh the page and try again.\"],\"G0tHaW\":[\"Create a public page that won't appear in Latest.\"],\"G2fuEb\":[\"Locked\"],\"G39wnK\":[\"Back up and sync content with a GitHub repository\"],\"G5oCui\":[\"URL structure, per-language feeds, and linking translations.\"],\"G9peMt\":[\"Create the account you write from.\"],\"GAmD3h\":[\"Languages\"],\"GBkMNw\":[[\"name\"],\" is a directory of Jant blogs, curated by hand by the Jant community to help people find new Jant blogs and posts.\"],\"GXsAby\":[\"Revoke\"],\"GdGiNi\":[\"Step \",[\"current\"],\" of \",[\"total\"]],\"GorKul\":[\"Welcome to Jant\"],\"GxkJXS\":[\"Uploading...\"],\"GzKzUa\":[\"Demo limits\"],\"HCNlq3\":[\"Clean and high-contrast, close to white.\"],\"HHDyGw\":[\"Soft green\"],\"HKH+W+\":[\"Data\"],\"Hp1l6f\":[\"Current\"],\"HxTUmw\":[\"Add \",[\"language\"]],\"HxlY7t\":[\"Changing this updates what subscribers get from /feed.\"],\"HxuOlm\":[\"Site Header\"],\"I0ijRI\":[\"All feed addresses\"],\"I4HRxU\":[\"Every published post, including ones hidden from Latest.\"],\"I6gXOa\":[\"Path\"],\"I76CzF\":[\"Neutral gray\"],\"ID38tA\":[\"Account deletion is off in demo mode. The shared demo resets separately.\"],\"IF9tPu\":[\"When to use site export, database backups, and recovery drills.\"],\"IW5PBo\":[\"Copy Token\"],\"IagCbF\":[\"URL\"],\"IreQBq\":[\"Repository\"],\"J36Xsm\":[\"Nothing at \",[\"address\"],\". Check it, or search by title.\"],\"J6bLeg\":[\"Add a custom link to any URL\"],\"JL7LF5\":[\"available CSS variables, data attributes, and examples.\"],\"JcD7qf\":[\"More actions\"],\"JjX0OO\":[\"Copy your token now — it won't be shown again.\"],\"JrFTcr\":[\"Connecting…\"],\"JuN5GC\":[\"No file selected. Choose a file to upload.\"],\"K+0Hu0\":[\"No matching pages available to add. Try another title or create a new page.\"],\"K/F6pa\":[\"Saving…\"],\"KDw4GX\":[\"Try again\"],\"KSgo21\":[\"Pick a repository\"],\"KVVYBh\":[\"Add collection to navigation\"],\"KiJn9B\":[\"Note\"],\"Kk7jwL\":[\"Set posts per archive page; reset to inherit the main page size.\"],\"KwOLJF\":[\"The original Jant palette, and a solid everyday pick.\"],\"L+rMC9\":[\"Reset to default\"],\"L27RpE\":[\"Page created.\"],\"L3DEwT\":[\"Remove this avatar? Your favicon and header icon will go back to the default.\"],\"L4t4/q\":[\"March 14\"],\"L86zmP\":[\"Edit the multi-line introduction used on your home page and in metadata.\"],\"LdyooL\":[\"link\"],\"LhMjLm\":[\"Time\"],\"LjwaJ/\":[\"Sign-in, export, and deletion\"],\"M/D8PK\":[\"+ Install on another account\"],\"M/haSd\":[\"Always show the light version of the theme.\"],\"M/kDIW\":[\"The language your readers and search engines see.\"],\"M1co/O\":[\"Configured\"],\"M2hGyf\":[\"Links to /subscribe, a page listing your feeds with copy buttons. Best for readers who don't already use one.\"],\"M2kIWU\":[\"Font theme\"],\"M4tzVU\":[\"Latest posts\"],\"M6CbAU\":[\"Toggle edit panel\"],\"M7wPsD\":[\"Switch\"],\"MHrjPM\":[\"Title\"],\"MKIM3K\":[\"Search pages\"],\"MaYYE6\":[\"Post notes by messaging a Telegram bot\"],\"Me5t5H\":[\"Connect a GitHub repository to automatically back up your posts as Markdown files. Edits on GitHub sync back to your site.\"],\"MeCJlL\":[\"Announcing your site. Reload to see the result.\"],\"MnbH31\":[\"page\"],\"Mq9FZ1\":[\"Creating page…\"],\"Mr4QPw\":[\"Disconnect Telegram? You can reconnect any time with a new binding code.\"],\"MtENL9\":[\"Tune how your site looks, reads, and runs.\"],\"N/8NPV\":[\"Before deleting, download a site export. You won't be able to recover this account after deletion.\"],\"N7UNHY\":[\"Featured feed\"],\"NHnUHF\":[\"Favicon and the profile mark in your header\"],\"NU2Fqi\":[\"Save CSS\"],\"NVjhde\":[\"Warm parchment\"],\"Nldjdr\":[\"No custom URLs yet. Create one to add redirects or custom paths for posts.\"],\"O3oNi5\":[\"Email\"],\"OJxdgi\":[\"Keep this link under 200 characters.\"],\"OSJXFg\":[\"Applies to your entire site, including admin pages. Pick a palette, then choose whether it follows the system or stays fixed.\"],\"OeUWA7\":[\"Add Page\"],\"OuuMXJ\":[\"Add site-wide HTML before the closing body tag.\"],\"Ox3+3h\":[\"No matches.\"],\"P7Eeay\":[\"Full posts\"],\"PEUV5I\":[\"Code injection updated.\"],\"PHh52z\":[\"Warm and rich, with strong brown tones.\"],\"PXj9lw\":[\"Stop accepting posts from Telegram. Your existing notes stay published.\"],\"PZ7HJ8\":[\"Blog Avatar\"],\"Pbm2/N\":[\"Create Collection\"],\"Pwqkdw\":[\"Loading…\"],\"PxJ9W6\":[\"Generate Token\"],\"Q/6Y+2\":[\"Needs Contents (read/write) and Webhooks (read/write) on the target repository.\"],\"Q/O0X4\":[\"This setting wasn't saved. Check the value and try again.\"],\"Q30z/l\":[\"Remove this collection from navigation? The collection itself won't be deleted.\"],\"Q99OtV\":[\"Pin a collection to your navigation bar. An asterisk (*) appears next to collections updated in the last 48 hours.\"],\"QCwsv1\":[\"Warm off-white\"],\"QKvrmL\":[\"Warm-neutral and easy for long reading.\"],\"QZmz0H\":[\"Built-in links\"],\"Qnrzvb\":[\"Active Tokens\"],\"R6Z4LE\":[\"Download failed. Please try again.\"],\"R9Khdg\":[\"Auto\"],\"RDjuBN\":[\"Setup\"],\"RRo9kN\":[\"Language updated.\"],\"RcdDOS\":[\"Create a bot by messaging @BotFather on Telegram, then paste the token it gives you.\"],\"RdVIcf\":[\"Cream and coffee brown\"],\"Ri/9PY\":[\"This site still limits Discover to featured posts, and no post is marked Featured, so your feed carries nothing to show. Untick and tick the box to let Discover read every public post.\"],\"Rn2p1h\":[\"Nothing matches this search. Try a different name or description.\"],\"RxsRD6\":[\"Time Zone\"],\"SDND4q\":[\"Not configured\"],\"SJmfuf\":[\"Site Name\"],\"SKZhW9\":[\"Token name\"],\"SSsoa4\":[\"Add to Navigation\"],\"SVQQPe\":[\"Couldn't connect. Check the error and try again.\"],\"SWb0z+\":[\"That address is reserved. Choose another one.\"],\"SYGk01\":[\"The languages served under a URL prefix. Managed on the Language page.\"],\"SchpMp\":[\"Telegram\"],\"SeY4vo\":[[\"language\"],\" is the only other language on this site, so removing it turns multilingual content off. The root address goes back to showing every language, \",[\"prefix\"],\" stops working, and each post keeps the language it is written in.\"],\"SqKp3o\":[\"The title used across your site, browser tabs, and feeds.\"],\"SrGs4T\":[\"Light blue-gray background, cool and even.\"],\"T/R+Qz\":[\"Primary\"],\"T17dXm\":[\"Whether each language gets its own home page, archive, and feed. Managed on the Language page.\"],\"T41PG1\":[\"Limit characters used in automatically generated summaries.\"],\"TN0mN4\":[\"Search and edit runtime settings. Changes apply immediately; reset restores the environment or built-in default.\"],\"TSCeuF\":[\"Couldn't create the collection. Check the details and try again.\"],\"TpF3v+\":[\"Injected before </head>. Use for analytics, custom meta tags, and styles that must load early.\"],\"Tu6bMZ\":[\"Create About page\"],\"Tz0i8g\":[\"Settings\"],\"U5J7jI\":[\"Site visibility updated.\"],\"U5v6Gh\":[\"Edit Page\"],\"UFK415\":[\"Site-wide HTML for analytics and widgets\"],\"UTvFQq\":[\"Open \",[\"linkOpen\"],\"@\",[\"botUsername\"],[\"linkClose\"],\" and send:\"],\"UUn+Y5\":[\"Open setting\"],\"UaZwcz\":[\"More options are available after you create it.\"],\"Uj/btJ\":[\"Display avatar in my site header\"],\"UsODUn\":[\"Select an account\"],\"UxKoFf\":[\"Navigation\"],\"UyMSeQ\":[\"At that address\"],\"V+bhUy\":[\"Install GitHub App\"],\"V0fyg5\":[\"Collection added to navigation.\"],\"V4WsyL\":[\"Add Link\"],\"V5pZwT\":[\"Search settings updated.\"],\"V7dQi9\":[\"Language removed.\"],\"VXUPla\":[\"Connect with GitHub App\"],\"Vh+JIV\":[\"Multilingual guide\"],\"VhMDMg\":[\"Change Password\"],\"Vn3jYy\":[\"Navigation items\"],\"VoZYGU\":[\"This will permanently delete all your data — posts, media, collections, settings, and your account. Your blog will be reset to its initial setup state. This cannot be undone.\"],\"VoarBQ\":[\"Post addresses do not change, and you can turn this off again at any time.\"],\"VqyJ7Y\":[\"Primary language changed.\"],\"WL7KjI\":[\"Tile grid\"],\"WUnFK2\":[\"Pale cool-white with deep indigo text. High contrast.\"],\"Wa9q4P\":[\"Pure white\"],\"Wb7EHo\":[\"About page\"],\"Weq9zb\":[\"General\"],\"Wi9i06\":[\"Follow each visitor's system preference.\"],\"Wildi8\":[\"No pages available. Create one to add it to navigation.\"],\"Wx1M8N\":[\"Install the GitHub App to grant access without managing personal tokens. Permissions are scoped per repository and revocable from GitHub.\"],\"X+8FMk\":[\"Current password doesn't match. Try again.\"],\"X1G9eY\":[\"Navigation Preview\"],\"X2Cbc2\":[\"Archive feed\"],\"X5P6yv\":[\"Recently updated\"],\"X9Hujr\":[\"Manual Push\"],\"XQQOyj\":[\"That page is a draft. Publish it, then add it.\"],\"XeRkls\":[[\"count\",\"plural\",{\"one\":[\"#\",\" existing post\"],\"other\":[\"#\",\" existing posts\"]}],\" with no language yet will be marked as \",[\"language\"],\".\"],\"Xsu5WL\":[\"Add site-wide CSS in the dedicated code editor.\"],\"XtBJV8\":[\"Checking repository…\"],\"Xtc16w\":[\"Refresh repository list\"],\"Y+7JGK\":[\"Create Page\"],\"Y/F35r\":[\"Create a post with curl:\"],\"Y/N5N7\":[\"Soft cream background with a muted green accent.\"],\"Y4oXje\":[\"Name prefilled as \",[\"name\"],\". The list refreshes when you return.\"],\"YF6zHf\":[\"Site settings updated.\"],\"YVcVlW\":[\"Remove and turn off\"],\"Ya/FAk\":[\"Add at least one more language to turn this on.\"],\"YdG2RF\":[\"Export Site\"],\"YkgZi7\":[\"Connect a Telegram bot, then anything you message it gets published as a note.\"],\"YwhjRx\":[\"Manage Account\"],\"Yxp859\":[\"Warm cream\"],\"Z5HWHd\":[\"On\"],\"ZDY7Fy\":[\"Syncing…\"],\"ZQKLI1\":[\"Danger Zone\"],\"ZS/CBL\":[\"Delete this navigation link? Visitors won't see it in your site header anymore.\"],\"ZXZrAo\":[\"Keep the page address under 200 characters.\"],\"ZgZX+d\":[\"Pure white with neutral grays. No color tint.\"],\"Zgq+c2\":[\"Set the default number of items shown per page.\"],\"ZhhOwV\":[\"Quote\"],\"ZiooJI\":[\"API Tokens\"],\"Zm7Qb0\":[\"Backup & Restore Guide\"],\"ZmUkwN\":[\"Add custom link to navigation\"],\"a14mj8\":[\"Unknown device\"],\"a1iEgy\":[\"Warm cream background with deep coffee-brown accents.\"],\"a3LDKx\":[\"Security\"],\"aAIQg2\":[\"Appearance\"],\"aFkzVF\":[\"The slug of the target post or collection\"],\"aR3U86\":[\"Multilingual content is on. \",[\"count\",\"plural\",{\"one\":[\"#\",\" post was marked\"],\"other\":[\"#\",\" posts were marked\"]}],\" as \",[\"language\"],\".\"],\"aV6XWN\":[\"Multilingual content is off. Your languages are still saved.\"],\"alKG0+\":[\"Font Theme\"],\"anibOb\":[\"About this blog\"],\"any7NR\":[\"Theming guide\"],\"asq0vL\":[\"The language you write in.\"],\"b+/jO6\":[\"301 (Permanent)\"],\"b+FyBD\":[\"Add page to navigation\"],\"b1FYSK\":[\"Primary language\"],\"bHOiy1\":[\"Password changes are off in demo mode. Sign in with the shared demo credentials.\"],\"bHYIks\":[\"Sign Out\"],\"bV2vng\":[\"Warm terracotta\"],\"bbR5vW\":[\"This palette\"],\"bbzY7X\":[\"Manage sign-in security, site exports, and irreversible actions.\"],\"bfHZ7r\":[\"Choose the time zone used to display dates and times.\"],\"bi10qS\":[\"Add it to navigation now or open the editor to add content.\"],\"bkMuwo\":[\"Link to posts you've marked as featured.\"],\"bmrL08\":[\"Demo mode hides sessions, password changes, and account deletion. Export still works.\"],\"bph1Dd\":[\"Search engine indexing is off, so this site is not listed by default. Ticking the box above lists it anyway.\"],\"brfpw9\":[\"Edit the multi-line footer rendered at the bottom of public pages.\"],\"bviiKV\":[\"Headings, body text, and links in this theme.\"],\"c1BGrV\":[\"Already in navigation. Drag it in the list above to move it.\"],\"c1iSrq\":[\"Discover community rules\"],\"c3MN2z\":[\"all available endpoints and request formats.\"],\"cHh/Zu\":[\"Turn on multilingual content\"],\"cS7/bk\":[\"Remove the saved bot token? Its webhook is deleted and any connected account is disconnected.\"],\"cSDy01\":[\"Custom CSS updated.\"],\"clzoNp\":[\"Always show the dark version of the theme.\"],\"cnGeoo\":[\"Delete\"],\"cwaLCZ\":[\"Page added to navigation.\"],\"d1lzY/\":[\"Language added.\"],\"d3FRkY\":[\"Could not copy. Try again.\"],\"d5oGUo\":[\"Create a new repository on GitHub\"],\"dB1Nr4\":[\"Start writing\"],\"dEgA5A\":[\"Cancel\"],\"dTXUY+\":[\"Confirm account deletion\"],\"dYKrp3\":[\"Hidden from Latest\"],\"dk7TCH\":[\"Permanently delete all data and reset the blog\"],\"ds0nJk\":[\"Add site-wide HTML before the closing head tag.\"],\"dsWkIw\":[\"Disconnect from GitHub? The webhook will be removed. Your repository content will not be deleted.\"],\"dwcK1n\":[\"Or submit your address by hand\"],\"e/tSI5\":[\"Navigation order updated.\"],\"eOL7vn\":[\"Minimal color, low distraction.\"],\"ePK91l\":[\"Edit\"],\"ebQKK7\":[\"Site\"],\"eeamrQ\":[\"Discover reads your Atom feed, so it needs feeds turned on.\"],\"egK+Yy\":[\"Bearer tokens for scripts and automation\"],\"egOXl0\":[\"Jant Discover\"],\"ehj/zN\":[\"Redirect Type\"],\"ej6Rji\":[\"Any post written in another language can be corrected from its own menu afterwards.\"],\"eneWvv\":[\"Draft\"],\"erTMh7\":[\"Last synced\"],\"f+m8jj\":[\"Feed URL copied.\"],\"f8fH8W\":[\"Design\"],\"fDz6PV\":[\"Choose the repository used for content backups.\"],\"fKRAwQ\":[\"Sandy background with a green accent.\"],\"fWYqkz\":[\"Code Injection\"],\"fYXQnC\":[\"Cozy and bold among the warm tones.\"],\"fttd2R\":[\"My Collection\"],\"gZ5owP\":[\"Search repositories\"],\"gbqbh6\":[\"Safe to leave this page — syncing continues in the background.\"],\"gkFvVN\":[\"Injected before </body>. Use for chat widgets and scripts that should not block page load.\"],\"gtQsRO\":[\"Create Custom URL\"],\"hBO/y4\":[\"Security token expired. Refresh the page and try again.\"],\"hGmyDl\":[\"Tokens let you access the API from scripts, shortcuts, and other tools without signing in.\"],\"hIHkRy\":[\"Connected via GitHub App\"],\"hJHHsU\":[\"Publish Atom feeds for the site, archive, and collections.\"],\"hcH8MY\":[\"Set up your site\"],\"hdSi1b\":[\"Type \",[\"repo\"],\" to confirm\"],\"he3ygx\":[\"Copy\"],\"hjeS3W\":[\"Link to your latest posts. Your homepage shows this feed.\"],\"hjvSlw\":[\"Language removed. Multilingual content is off.\"],\"hvGGMK\":[\"Remove this page from navigation? The page itself won't be deleted.\"],\"i0qMbr\":[\"Home\"],\"iEUzMn\":[\"system\"],\"iH8pgl\":[\"Back\"],\"iMkWoF\":[\"Turn on\"],\"iSLIjg\":[\"Connect\"],\"iVOMRi\":[\"Home settings updated.\"],\"icB4Cv\":[\"Drag links here to show them under the More menu\"],\"id3vuh\":[\"Telegram is set up, but the bot couldn't be reached. Check the bot token and try again.\"],\"idD8Ev\":[\"Saved\"],\"ihn4zD\":[\"Search…\"],\"iiDXZc\":[\"Displayed at the bottom of all posts and pages.\"],\"itS31B\":[\"A warmer look, like slightly aged paper.\"],\"iwQZvS\":[\"Cool blue-gray\"],\"j4VrG6\":[\"Download Export ZIP\"],\"j5nQL2\":[\"e.g. iOS Shortcuts\"],\"jNE7O+\":[\"Nothing published yet. jant.me lists a blog once it has \",[\"minCount\",\"plural\",{\"one\":[\"one public post\"],\"other\":[\"#\",\" public posts\"]}],\".\"],\"jUV7CU\":[\"Upload Avatar\"],\"jVUmOK\":[\"Markdown supported\"],\"jdVYS8\":[\"Pick the one that fits your writing.\"],\"jgBjXJ\":[\"Revoke this token? Any scripts using it will stop working.\"],\"jpctdh\":[\"View\"],\"k1ifdL\":[\"Processing...\"],\"kLw03Y\":[\"Bright paper white\"],\"kMXclu\":[\"Download a site export\"],\"kNiQp6\":[\"Pinned\"],\"kQ3Otm\":[\"Create new page\"],\"kRhzWq\":[\"GitHub Sync\"],\"kVQs7s\":[\"Fine-grained styling overrides\"],\"ke1gWS\":[\"Custom URLs\"],\"kfcRb0\":[\"Avatar\"],\"kp8wiR\":[\"Checking address…\"],\"kxDZ2i\":[\"This code runs on every page of your site.\"],\"kzvWob\":[\"Link to the post archive\"],\"lLW3vJ\":[\"Target Slug\"],\"lLsfOE\":[\"Turn off multilingual content?\"],\"lV04bQ\":[\"Warm and earthy, but still light.\"],\"lYHJih\":[\"Revoke this session? That device will need to sign in again.\"],\"m16xKo\":[\"Add\"],\"mLOk1i\":[\"Push all posts to GitHub right now instead of waiting for the next automatic sync.\"],\"mSNmrX\":[\"List posts:\"],\"n8+EXe\":[\"Add common destinations that already exist on your site.\"],\"nG2qTk\":[\"Example link\"],\"nK07ni\":[\"Choose a typographic direction for your site. Each theme changes both the font pairing and the reading rhythm.\"],\"nbfdhU\":[\"Integrations\"],\"ntJYyh\":[\"Domains, plan, and billing in \",[\"providerLabel\"]],\"o/vNDE\":[\"lets you override any theme variable.\"],\"o5rj+L\":[\"No collections yet. Create one here to add it to navigation.\"],\"oGC9uP\":[\"owner/repo\"],\"oKOOsY\":[\"Color Theme\"],\"oL535e\":[\"Not synced yet\"],\"oNA4If\":[\"All collections are already in your navigation.\"],\"oUn9Z7\":[\"Near-neutral light gray with a steel-blue accent.\"],\"ofdy2l\":[\"Orange-tinted background. The warmest palette.\"],\"olouYg\":[\"Navigation holds that address as a link.\"],\"oxj6Pk\":[\"Other languages\"],\"pIpTqF\":[\"Give each language its own home page, archive, and feed. Once it's on, you pick a language when you publish, and can link an existing post to a version of it in another language.\"],\"pNXxtS\":[\"Choose the content language announced to readers and search engines.\"],\"pZq3aX\":[\"Upload failed. Please try again.\"],\"pgJImo\":[\"Change the primary language?\"],\"pgTIrt\":[\"Choose the GitHub account and repository to sync with this site.\"],\"psoxDF\":[\"That font theme isn't available. Pick another one.\"],\"pt4OhQ\":[\"/about is already used. Rename that item before creating an About page.\"],\"pvnfJD\":[\"Dark\"],\"q+hNag\":[\"Collection\"],\"q/T5GS\":[\"The language used by the private Jant dashboard.\"],\"qSgO/Y\":[\"Follow content language\"],\"qZ9jzv\":[\"Site visibility\"],\"qdcESc\":[\"Create a new repository\"],\"qkSJzV\":[\"Searching pages…\"],\"r5EW6f\":[\"This repository is already backing up another Jant site (\",[\"host\"],\"). Pick a different repository.\"],\"rCPrbS\":[\"Options for \",[\"language\"]],\"rEspiY\":[\"Navigation placement updated.\"],\"rFmBG3\":[\"Color theme\"],\"re0mF0\":[\"The page is public but stays out of Latest.\"],\"rlonmB\":[\"Couldn't delete. Try again in a moment.\"],\"s3jOk7\":[\"Enter a page title.\"],\"sROtqR\":[\"The directory could not be reached: \",[\"reason\"]],\"sRmGLp\":[\"You can change all of this later in Settings.\"],\"satWc6\":[\"Main RSS feed\"],\"sgr2wQ\":[\"collection\"],\"sj4LLc\":[\"Show only modified\"],\"sjej3N\":[\"Remove \",[\"language\"]],\"slujBW\":[\"Use lowercase letters, numbers, and hyphens only.\"],\"soRdOu\":[\"Off-white paper with a deep forest-green accent.\"],\"sqxcaY\":[\"Created \",[\"date\"]],\"sxkWRg\":[\"Advanced\"],\"t/YqKh\":[\"Remove\"],\"t3hvHq\":[\"Sync Now\"],\"tJ4H0O\":[\"your Telegram account\"],\"tfDRzk\":[\"Save\"],\"tgWuMB\":[\"Modified\"],\"tvgAq5\":[\"No accounts authorized yet\"],\"u1VTd3\":[\"Palette, surface tone, and overall mood\"],\"u3wRF+\":[\"Published\"],\"u6KOjV\":[\"Want more control?\"],\"uKLe0J\":[[\"count\"],\" settings shown\"],\"uVZcIA\":[\"That address is already in use. Choose another one.\"],\"udPwLB\":[\"Header\"],\"ugHDtd\":[[\"about\"],\" A post you mark Featured appears on the Discover home page \",[\"hours\"],\" hours later, and link and quote posts appear on the \",[\"links\"],\" and \",[\"quotes\"],\" lists \",[\"hours\"],\" hours after they are published. You can keep editing them in the meantime. See the \",[\"rules\"],\".\"],\"ui6aMF\":[\"These devices are currently signed in to your account. Revoke any session you don't recognize.\"],\"vBEKwo\":[\"Manage this site's active sessions here. Password and hosted access are managed through \",[\"providerLabel\"],\".\"],\"vOnuOa\":[\"Show or hide built-in destinations in the header and More menu.\"],\"vRldcl\":[\"Typography choices and reading texture\"],\"vSYKYI\":[\"Main feed\"],\"vTuib7\":[\"This controls what /feed returns.\"],\"vXCC6J\":[\"Something doesn't look right. Check the form and try again.\"],\"vXIe7J\":[\"Language\"],\"vXsx3x\":[\"That page is private, so nobody could open it from a menu.\"],\"vdFnYM\":[\"Reset link\"],\"vmQmHx\":[\"Add custom CSS to override any styles. Use data attributes like [data-page], [data-post], [data-format] to target specific elements.\"],\"vpSPA1\":[\"Auth secret is missing. Check your environment variables.\"],\"vzX5FB\":[\"Delete Account\"],\"w615zC\":[\"Multilingual content\"],\"w8Rv8T\":[\"Label is required\"],\"wL3cK8\":[\"Latest\"],\"wW6NCp\":[\"Last error\"],\"wc+17X\":[\"/* Your custom CSS here */\"],\"wuLtXn\":[\"No active sessions right now. Signed-in devices show up here.\"],\"x+HGBk\":[\"Ask search engines not to index public pages or include them in results.\"],\"xCWek4\":[\"File storage isn't set up. Check your server config.\"],\"xCbjQn\":[\"Allow \",[\"name\"],\" to list my site\"],\"xGVfLh\":[\"Continue\"],\"xHt036\":[\"Personal Access Token\"],\"xKeZ0l\":[\"An earthier, warmer tone.\"],\"xYbozN\":[\"Soft ivory\"],\"xqViCq\":[\"Warm ivory\"],\"xxaahd\":[\"When you want a cooler, sharper look.\"],\"y/awtV\":[\"Header links, built-in destinations, and overflow menu\"],\"y28hnO\":[\"Post\"],\"y9W9vo\":[\"Creating collection…\"],\"yNCqOt\":[\"Latest feed\"],\"yQ3kNF\":[\"Type the following phrase to confirm:\"],\"ydq1k2\":[\"Pick an account first\"],\"yjjCV8\":[\"Fixed feed URLs\"],\"yjkELF\":[\"Confirm New Password\"],\"ym+ccl\":[\"Show the Jant credit on the home page.\"],\"yzF66j\":[\"Link\"],\"z6wakA\":[\"A short intro shown on your home page.\"],\"zEizrk\":[\"Last used \",[\"date\"]],\"zPqly9\":[\"This site has no directory to announce to.\"],\"zSURJW\":[\"No repositories match.\"],\"zUlHGd\":[\"Page address\"],\"zYRGIR\":[\"Not announced yet. No directory has been told this site exists.\"],\"zcDmsG\":[\"Featured posts\"],\"zlcDd2\":[\"Delete this custom URL? Visitors using it won't be redirected anymore.\"],\"ztPYIR\":[\"One-time change to your existing posts\"],\"zwBp5t\":[\"Private\"],\"zxexio\":[\"Content language, dashboard language, multilingual\"]}")as Messages;
@@ -1012,10 +1012,10 @@ msgstr "演示模式会隐藏会话、密码更改和账号删除。导出仍然
1012
1012
  msgid "Demo sites always stay hidden from search engines."
1013
1013
  msgstr "演示站点始终对搜索引擎隐藏。"
1014
1014
 
1015
- #. @context: Help text explaining that Discover is locked off in demo mode
1015
+ #. @context: Help text under the Jant Discover checkbox explaining that Discover is locked off in demo mode, shown in place of the usual help line. {name} is the directory's name and is rendered as the link to it, so keep it as one run of text.
1016
1016
  #: src/ui/dash/settings/GeneralContent.tsx
1017
- msgid "Demo sites are never listed in Discover."
1018
- msgstr "演示站点不会出现在 Discover 中。"
1017
+ msgid "Demo sites are never listed in {name}."
1018
+ msgstr "演示站点不会出现在 {name} 中。"
1019
1019
 
1020
1020
  #. @context: Color theme preview collection label
1021
1021
  #: src/ui/dash/appearance/ColorThemeContent.tsx
@@ -1683,6 +1683,11 @@ msgstr "低饱和的红棕底,温暖、有泥土感。"
1683
1683
  msgid "My Collection"
1684
1684
  msgstr "我的合集"
1685
1685
 
1686
+ #. @context: GitHub sync picker — hint under the create-on-github entry. Placeholder {name} is the suggested repo name.
1687
+ #: src/routes/dash/settings.tsx
1688
+ msgid "Name prefilled as {name}. The list refreshes when you return."
1689
+ msgstr "名称预填为 {name}。返回后列表会刷新。"
1690
+
1686
1691
  #. @context: Settings item description for general
1687
1692
  #: src/ui/dash/settings/SettingsRootContent.tsx
1688
1693
  msgid "Name, visibility, feeds, and time zone"
@@ -3013,11 +3018,6 @@ msgstr "暖陶土色"
3013
3018
  msgid "Warm-neutral and easy for long reading."
3014
3019
  msgstr "暖中性,适合长读。"
3015
3020
 
3016
- #. @context: GitHub sync picker — hint under the create-on-github entry. Placeholder {name} is the suggested repo name.
3017
- #: src/routes/dash/settings.tsx
3018
- msgid "We'll prefill the name {name}. The list refreshes on return."
3019
- msgstr "我们会预先填充名称 {name}。返回时列表会刷新。"
3020
-
3021
3021
  #. @context: Setup page welcome heading
3022
3022
  #: src/routes/auth/setup.tsx
3023
3023
  msgid "Welcome to Jant"