@heycys/gallery 0.1.0 → 0.1.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.
- package/THIRD-PARTY-NOTICES.md +51 -1
- package/browser/editor/components/callout/index.mjs +40 -15
- package/browser/editor/components/columns/page.mjs +41 -28
- package/browser/editor/components/details/index.mjs +2 -1
- package/browser/editor/components/dialog/index.mjs +2 -1
- package/browser/editor/components/dialog/page.mjs +0 -18
- package/browser/editor/components/divider/index.mjs +1 -1
- package/browser/editor/components/figure/page.mjs +10 -1
- package/browser/editor/components/file/page.mjs +2 -2
- package/browser/editor/components/flowchart/add.mjs +2 -2
- package/browser/editor/components/heading/index.mjs +2 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +4 -20
- package/browser/editor/components/icons.mjs +5 -2
- package/browser/editor/components/image/page.mjs +2 -2
- package/browser/editor/components/installed/index.mjs +71 -25
- package/browser/editor/components/installed/page.mjs +122 -21
- package/browser/editor/components/kit.mjs +3 -0
- package/browser/editor/components/media/page.mjs +44 -14
- package/browser/editor/components/pages.mjs +2 -2
- package/browser/editor/components/registry.mjs +56 -30
- package/browser/editor/components/section/index.mjs +2 -1
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/table/index.mjs +5 -3
- package/browser/editor/components/table/page.mjs +29 -18
- package/browser/editor/page/annotate/anchors.mjs +4 -3
- package/browser/editor/page/annotate/index.mjs +61 -34
- package/browser/editor/page/autosave.mjs +50 -4
- package/browser/editor/page/beside.mjs +5 -5
- package/browser/editor/page/block-menu/colors.mjs +3 -1
- package/browser/editor/page/block-menu/index.mjs +8 -6
- package/browser/editor/page/blocks.mjs +16 -7
- package/browser/editor/page/caret.mjs +4 -1
- package/browser/editor/page/changes/bar.mjs +102 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/clipboard/import/colors.mjs +3 -3
- package/browser/editor/page/clipboard/index.mjs +32 -13
- package/browser/editor/page/clipboard/own/blocks.mjs +14 -5
- package/browser/editor/page/clipboard/own/describe.mjs +16 -7
- package/browser/editor/page/clipboard/own/export.mjs +6 -6
- package/browser/editor/page/clipboard/own/selection.mjs +2 -2
- package/browser/editor/page/clipboard/own/writers.mjs +0 -11
- package/browser/editor/page/columns/index.mjs +1 -1
- package/browser/editor/page/commit.mjs +19 -4
- package/browser/editor/page/conflicts.mjs +6 -26
- package/browser/editor/page/convert.mjs +8 -7
- package/browser/editor/page/core.mjs +55 -17
- package/browser/editor/page/drag/index.mjs +40 -24
- package/browser/editor/page/drag/preview.mjs +9 -4
- package/browser/editor/page/editor.mjs +70 -15
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
- package/browser/editor/page/emoji-picker/grid.mjs +7 -5
- package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
- package/browser/editor/page/emoji-picker/icons.mjs +0 -1
- package/browser/editor/page/emoji-picker/index.mjs +11 -9
- package/browser/editor/page/emoji-picker/styles.mjs +161 -2
- package/browser/editor/page/emoji-picker/support.mjs +6 -4
- package/browser/editor/page/emoji-picker/upload.mjs +12 -11
- package/browser/editor/page/fills.mjs +5 -3
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +2 -1
- package/browser/editor/page/format-bar/index.mjs +1 -1
- package/browser/editor/page/geometry.mjs +8 -6
- package/browser/editor/page/handle/index.mjs +17 -6
- package/browser/editor/page/hints/index.mjs +1 -1
- package/browser/editor/page/insert/index.mjs +30 -17
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +15 -3
- package/browser/editor/page/margin.mjs +45 -24
- package/browser/editor/page/menu.mjs +69 -25
- package/browser/editor/page/merge.mjs +24 -0
- package/browser/editor/page/notices.mjs +1 -1
- package/browser/editor/page/offered.mjs +1 -1
- package/browser/editor/page/outline/folds.mjs +11 -10
- package/browser/editor/page/outline/index.mjs +131 -45
- package/browser/editor/page/outline/list.mjs +23 -11
- package/browser/editor/page/outline/read.mjs +1 -1
- package/browser/editor/page/outline/strip.mjs +7 -1
- package/browser/editor/page/panel.mjs +5 -4
- package/browser/editor/page/resize/index.mjs +1 -1
- package/browser/editor/page/selection/delete.mjs +8 -6
- package/browser/editor/page/selection/index.mjs +10 -3
- package/browser/editor/page/session.mjs +54 -3
- package/browser/editor/page/table/cell-bar.mjs +4 -1
- package/browser/editor/page/table/cells.mjs +1 -1
- package/browser/editor/page/table/icons.mjs +1 -1
- package/browser/editor/page/table/index.mjs +13 -8
- package/browser/editor/page/table/widths.mjs +9 -4
- package/browser/editor/page/text-select/index.mjs +18 -3
- package/browser/editor/page/tooltip.mjs +1 -1
- package/browser/editor/page/type-grid.mjs +4 -3
- package/browser/editor/page/typing/code-edges.mjs +63 -17
- package/browser/editor/page/typing/index.mjs +12 -6
- package/browser/editor/page/typing/leave.mjs +1 -1
- package/browser/shared/annotations.mjs +8 -10
- package/browser/shared/code-folds.mjs +5 -1
- package/browser/shared/colors.mjs +15 -13
- package/browser/shared/component-catalog.mjs +24 -10
- package/browser/shared/components/callout.mjs +4 -2
- package/browser/shared/components/index.mjs +61 -7
- package/browser/shared/components/installed.mjs +75 -5
- package/browser/shared/components/page.mjs +10 -1
- package/browser/shared/components/table.mjs +1 -1
- package/browser/shared/components/text.mjs +2 -2
- package/browser/shared/document-look.mjs +178 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/README.md +4 -2
- package/browser/shared/emoji/data/categories.json +1 -1
- package/browser/shared/emoji/data/keywords-en.json +1 -1
- package/browser/shared/emoji/data/keywords-zh.json +1 -1
- package/browser/shared/emoji/data/names.json +1 -1
- package/browser/shared/emoji/data/positions.json +1 -1
- package/browser/shared/emoji/data/twemoji-index.json +1 -1
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +10 -12
- package/browser/shared/emoji/emoji.mjs +8 -7
- package/browser/shared/emoji/icon-value.mjs +4 -3
- package/browser/shared/html-tree.mjs +11 -5
- package/browser/shared/i18n/en.mjs +67 -8
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/new-names.mjs +5 -2
- package/browser/shared/outline.mjs +194 -0
- package/browser/shared/preferences.mjs +10 -4
- package/browser/shared/session.mjs +5 -4
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/zoom.mjs +5 -5
- package/dist/chunk-3HIRPVLU.mjs +2 -0
- package/dist/chunk-4FS7Z7WR.mjs +2 -0
- package/dist/{chunk-LHTFLRB6.mjs → chunk-5MHMDLZD.mjs} +2 -2
- package/dist/{chunk-YXAUQPVK.mjs → chunk-5ZKJ3H4P.mjs} +3 -3
- package/dist/{chunk-ZBIM6ARY.mjs → chunk-64K7IPLO.mjs} +55 -16
- package/dist/{chunk-QYKCJ7FG.mjs → chunk-6QXGZM36.mjs} +1 -1
- package/dist/chunk-6RGJOMJP.mjs +16 -0
- package/dist/{chunk-EUX7IC5J.mjs → chunk-7DTINW6U.mjs} +2 -2
- package/dist/{chunk-6CYG3Z4V.mjs → chunk-AJ73XJF3.mjs} +1 -1
- package/dist/chunk-AUZGSZJH.mjs +13 -0
- package/dist/{chunk-7QQBR7PB.mjs → chunk-BFE45AKL.mjs} +1 -1
- package/dist/chunk-BGGDRNYQ.mjs +10 -0
- package/dist/{chunk-L4DVONOG.mjs → chunk-BXO2ZY5P.mjs} +1 -1
- package/dist/chunk-CEH4MRCC.mjs +2 -0
- package/dist/chunk-CY2FNNAB.mjs +16 -0
- package/dist/{chunk-LC7YNQFG.mjs → chunk-DFUDV4LX.mjs} +1 -1
- package/dist/chunk-DKXG4XDG.mjs +2 -0
- package/dist/chunk-E7LWZRXY.mjs +4 -0
- package/dist/chunk-EZQ34M3F.mjs +124 -0
- package/dist/chunk-FDLXYYG4.mjs +4 -0
- package/dist/chunk-FUKQNOQS.mjs +9 -0
- package/dist/{chunk-DB4WKGYF.mjs → chunk-GB5SOYQJ.mjs} +2 -2
- package/dist/{chunk-ACOPDCNB.mjs → chunk-IVDLMMBD.mjs} +1 -1
- package/dist/chunk-JPOSLGOC.mjs +6 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-L3QKH4OK.mjs +26 -0
- package/dist/{chunk-B3VTYBYR.mjs → chunk-LCTHTZIL.mjs} +2 -2
- package/dist/chunk-LEF6DRCK.mjs +59 -0
- package/dist/chunk-LS4F7JUM.mjs +2 -0
- package/dist/chunk-NO5NJCHO.mjs +2 -0
- package/dist/{chunk-UNUEWH4S.mjs → chunk-NQPVAU63.mjs} +1 -1
- package/dist/chunk-O35FIXRB.mjs +2 -0
- package/dist/chunk-PL6GHLGD.mjs +15 -0
- package/dist/{chunk-G7TOXONE.mjs → chunk-QJIR2BLP.mjs} +1 -1
- package/dist/chunk-QUPLVPB2.mjs +7 -0
- package/dist/chunk-R7BNENLY.mjs +4 -0
- package/dist/chunk-S6O4UHLC.mjs +2 -0
- package/dist/{chunk-HMHK3EQ6.mjs → chunk-SGJWQKEI.mjs} +1 -1
- package/dist/chunk-SYGN7GLU.mjs +2 -0
- package/dist/chunk-TYK6VNAB.mjs +10 -0
- package/dist/{chunk-EVJ3BX3M.mjs → chunk-U6KNPJPR.mjs} +1 -1
- package/dist/{chunk-YZ5Z6H4W.mjs → chunk-UALRNVSE.mjs} +1 -1
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-V3HXVQEM.mjs +2 -0
- package/dist/{chunk-UXUK4PMC.mjs → chunk-V5JTW2LH.mjs} +1 -1
- package/dist/chunk-V5VXUJKG.mjs +2 -0
- package/dist/chunk-VBXMADMP.mjs +2 -0
- package/dist/chunk-VNV55RUA.mjs +2 -0
- package/dist/chunk-VPD2PS35.mjs +2 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-W4VKN3GF.mjs +7 -0
- package/dist/chunk-W5BXXPDJ.mjs +3 -0
- package/dist/{chunk-Z52HTUW7.mjs → chunk-XNROSH2T.mjs} +2 -2
- package/dist/chunk-XUNHRCOG.mjs +6 -0
- package/dist/{chunk-6U2SLSDN.mjs → chunk-Y6RLRPG3.mjs} +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/math.js +18 -2
- package/kit/report.css +248 -137
- package/kit/runtime.js +126 -51
- package/kit/tables.js +51 -1
- package/kit/ui.js +97 -0
- package/package.json +1 -1
- package/release.json +8 -8
- package/sdk/doc-kit.d.ts +9 -3
- package/skill/SKILL.md +22 -10
- package/skill/references/building-components.md +46 -6
- package/skill/references/example-report.html +1 -1
- package/skill/references/writing-html.md +4 -4
- package/skill/sdk/doc-kit.d.ts +9 -3
- package/web/assets/index-Bh74DfsV.css +1 -0
- package/web/assets/index-UW0RyFFt.js +13 -0
- package/web/index.html +2 -2
- package/browser/editor/components/callout/page.mjs +0 -13
- package/dist/chunk-2PBALTR3.mjs +0 -57
- package/dist/chunk-3LA3EMDE.mjs +0 -15
- package/dist/chunk-5FRMCDPY.mjs +0 -16
- package/dist/chunk-5LEK2CBS.mjs +0 -2
- package/dist/chunk-5OFN5AHC.mjs +0 -2
- package/dist/chunk-5SIYS5HN.mjs +0 -2
- package/dist/chunk-5TEK3RAD.mjs +0 -2
- package/dist/chunk-7GHT2UCA.mjs +0 -15
- package/dist/chunk-ATCJYAR4.mjs +0 -2
- package/dist/chunk-C7HWOBIF.mjs +0 -2
- package/dist/chunk-E7VYDG2X.mjs +0 -2
- package/dist/chunk-FQGQH4KM.mjs +0 -2
- package/dist/chunk-GPF4YWWB.mjs +0 -9
- package/dist/chunk-GYQV7Y4J.mjs +0 -120
- package/dist/chunk-HQQMJCQJ.mjs +0 -10
- package/dist/chunk-IERUOGC3.mjs +0 -6
- package/dist/chunk-ITNLYXXV.mjs +0 -3
- package/dist/chunk-NFIBI4IP.mjs +0 -26
- package/dist/chunk-O52JMOCZ.mjs +0 -2
- package/dist/chunk-QMQUXTU4.mjs +0 -12
- package/dist/chunk-QVWVFC5K.mjs +0 -6
- package/dist/chunk-QZY6Q64C.mjs +0 -2
- package/dist/chunk-TDQP3DKQ.mjs +0 -10
- package/dist/chunk-V4CPWKMZ.mjs +0 -2
- package/dist/chunk-VACRB2NE.mjs +0 -3
- package/dist/chunk-W63L7367.mjs +0 -7
- package/dist/chunk-W7CXPCRV.mjs +0 -6
- package/dist/chunk-XINNG4F2.mjs +0 -4
- package/dist/chunk-YL2DPWVS.mjs +0 -4
- package/web/assets/index-B6Ai3wsa.js +0 -13
- package/web/assets/index-SYPC3EZy.css +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { effectiveLook, lookOf, withLookField } from "./document-look.mjs";
|
|
4
|
+
import { writeAtomic } from "./files.mjs";
|
|
5
|
+
import { refusal, said } from "./i18n/index.mjs";
|
|
6
|
+
import { WORKSPACE_MARK, documentDirectory, documentFiles, layoutOf, markerOf } from "./workspace.mjs";
|
|
7
|
+
|
|
8
|
+
// The workspace's default look (字体与布局's 应用到全部文档, src/shared/document-look.mjs): `look` in its
|
|
9
|
+
// gallery.json, beside what the file says of the components, each choice that is not the default
|
|
10
|
+
// kept and the field gone when none is. A document shows its own choices (doc.json's `look`) over it,
|
|
11
|
+
// choice by choice, and a document with none of its own, a new one among them, shows it whole. A
|
|
12
|
+
// workspace without it, an older one's, has every choice at its default. The 写作偏好 page (a doc.json
|
|
13
|
+
// marked "instructions": true) has no look, the workspace's or its own. Here for the server alone: the
|
|
14
|
+
// render, the workbench's service and the preview's watcher read it from disk; a page and the
|
|
15
|
+
// workbench's app are told the look a document shows.
|
|
16
|
+
|
|
17
|
+
// gallery.json as it reads now: what it holds when it is ours (a workspace without one holds nothing),
|
|
18
|
+
// else why it cannot be taken (its components' messages: src/shared/component-catalog.mjs).
|
|
19
|
+
const UNREAD = said("gallery.json 读不出来:改好这个文件后再试");
|
|
20
|
+
const NOT_OURS = said("gallery.json 不是 Gallery 的文件");
|
|
21
|
+
const NOT_WRITABLE = ["EPERM", "EACCES", "EBUSY", "EROFS"];
|
|
22
|
+
function settingsOf(text) {
|
|
23
|
+
if (text === null) return { value: null };
|
|
24
|
+
const { value, ours, reads } = markerOf(text);
|
|
25
|
+
return ours ? { value } : { problem: reads ? NOT_OURS : UNREAD };
|
|
26
|
+
}
|
|
27
|
+
const readText = (file) => {
|
|
28
|
+
try {
|
|
29
|
+
return readFileSync(file, "utf8");
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return error.code === "ENOENT" ? null : undefined;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** The workspace's default look at `root` (lookOf's form), {} for none, for no gallery.json and for one that does not read or is not ours. */
|
|
36
|
+
export function workspaceLook(root) {
|
|
37
|
+
const text = readText(layoutOf(root).marker);
|
|
38
|
+
return text === undefined ? {} : lookOf(settingsOf(text).value?.look);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* What document `slug`'s doc.json says of its look at `root`: { own: its `look` as written (null for
|
|
43
|
+
* none, for a doc.json that does not read and for none at all), instructions: whether it is the 写作偏好
|
|
44
|
+
* page's, reads: whether what it says can be taken, which a doc.json an Agent is writing may not, a
|
|
45
|
+
* moment; a document with no doc.json at all (one made by hand: its doc.html alone) says it has no look
|
|
46
|
+
* of its own, and reads, while one whose folder is gone says nothing }.
|
|
47
|
+
*/
|
|
48
|
+
export function ownLookAt(slug, root) {
|
|
49
|
+
const files = documentFiles(documentDirectory(slug, root));
|
|
50
|
+
try {
|
|
51
|
+
const metadata = JSON.parse(readFileSync(files.json, "utf8"));
|
|
52
|
+
const reads = Boolean(metadata) && typeof metadata === "object" && !Array.isArray(metadata);
|
|
53
|
+
return { own: reads ? (metadata.look ?? null) : null, instructions: reads && metadata.instructions === true, reads };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return { own: null, instructions: false, reads: error.code === "ENOENT" && existsSync(files.html) };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The look document `slug` of the workspace at `root` shows (lookOf's form, {} for the default): its
|
|
61
|
+
* own over the workspace's (effectiveLook); the workspace's for a doc.json that does not read, none
|
|
62
|
+
* for the 写作偏好 page.
|
|
63
|
+
*/
|
|
64
|
+
export function documentLook(slug, root) {
|
|
65
|
+
const { own, instructions } = ownLookAt(slug, root);
|
|
66
|
+
return instructions ? {} : effectiveLook(own, workspaceLook(root));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* gallery.json with `look` as the workspace's default look (lookOf: each default left out, the field
|
|
71
|
+
* gone when all are), written at once and with all else it holds kept, made when there is none. A
|
|
72
|
+
* file that does not read, is another program's, changed under this write or cannot be written is
|
|
73
|
+
* refused (an error that says why: refusal), and stays as it is.
|
|
74
|
+
*/
|
|
75
|
+
export async function writeWorkspaceLook(root, look) {
|
|
76
|
+
const file = layoutOf(root).marker;
|
|
77
|
+
const text = await fs.readFile(file, "utf8").catch((error) => {
|
|
78
|
+
if (error.code === "ENOENT") return null;
|
|
79
|
+
throw refusal(UNREAD);
|
|
80
|
+
});
|
|
81
|
+
const { value, problem } = settingsOf(text);
|
|
82
|
+
if (problem) throw refusal(problem);
|
|
83
|
+
if (value === null && Object.keys(lookOf(look)).length === 0) return; // no file, and none needed for the default
|
|
84
|
+
const written = withLookField(value ?? WORKSPACE_MARK, lookOf(look)); // in its place, else last; gone for the default
|
|
85
|
+
if (JSON.stringify(written) === JSON.stringify(value)) return;
|
|
86
|
+
const done = await writeAtomic(file, `${JSON.stringify(written, null, 2)}\n`, { expect: text }).catch((error) => {
|
|
87
|
+
if (NOT_WRITABLE.includes(error.code)) throw refusal(said("gallery.json 写不进去:可能是只读的,或被别的程序占着"));
|
|
88
|
+
throw error;
|
|
89
|
+
});
|
|
90
|
+
if (!done) throw refusal(said("gallery.json 刚刚被改过:再试一次"));
|
|
91
|
+
}
|
package/browser/shared/zoom.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INSTANCE } from "./components/installed.mjs";
|
|
1
|
+
import { INSTANCE, componentAt } from "./components/installed.mjs";
|
|
2
2
|
|
|
3
3
|
// 图片放大: which pictures of a report open large when clicked (docs/render.md, "Opening a picture
|
|
4
4
|
// large"). One rule for both ways in: the kit's viewer for a reader (src/render/kit/runtime/zoom.js:
|
|
@@ -10,8 +10,8 @@ import { INSTANCE } from "./components/installed.mjs";
|
|
|
10
10
|
// A picture is an <img> of the page (main.doc-page), whatever holds it: an image block, a table's
|
|
11
11
|
// cell, a card (one of the kit's or a drawing of the report's own), a column, a flowchart's node, a
|
|
12
12
|
// list item, a detail card. Not one that is a control's or a link's (a click there is theirs: it
|
|
13
|
-
// follows the link, opens the disclosure, chooses the tab), nor one in
|
|
14
|
-
// package (its component's), nor an icon: the page's icon and a panel's or a node's (.doc-icon, emoji
|
|
13
|
+
// follows the link, opens the disclosure, chooses the tab), nor one in the own region of an instance
|
|
14
|
+
// of a component package (its component's; one in its slot is the document's: componentAt), nor an icon: the page's icon and a panel's or a node's (.doc-icon, emoji
|
|
15
15
|
// pictures among them), a link's icon, a bookmark's pictures, a file's; nor a picture shown smaller
|
|
16
16
|
// than ZOOM_LEAST each way (an icon's or an emoji's size in a line of text), nor one that did not load.
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@ import { INSTANCE } from "./components/installed.mjs";
|
|
|
19
19
|
export const ZOOM_SKIP = [
|
|
20
20
|
"a[href]", "button", "summary", "label", "select", "[role=button]", "[role=link]", "[role=tab]", "[data-doc-dialog-open]",
|
|
21
21
|
".doc-icon", ".doc-link-mention", ".doc-bookmark", ".doc-file",
|
|
22
|
-
".doc-zoom", "[data-doc-dev]",
|
|
22
|
+
".doc-zoom", "[data-doc-dev]",
|
|
23
23
|
].join(", ");
|
|
24
24
|
|
|
25
25
|
/** The pictures the reader's runtime watches to offer to the keyboard (runtime/zoom.js), those of the rule among them. */
|
|
@@ -43,7 +43,7 @@ const loaded = (img) => img.complete && (img.naturalWidth > 0 || /^data:image\/s
|
|
|
43
43
|
/** Whether `img` opens large when clicked (or double-clicked in the page editor). */
|
|
44
44
|
export function zoomable(img) {
|
|
45
45
|
const holder = img?.hasAttribute?.(ZOOM_MARK) ? img.parentElement : img; // the runtime's own role is no control's
|
|
46
|
-
if (img?.localName !== "img" || !img.closest(".doc-page") || holder?.closest(ZOOM_SKIP) || !loaded(img)) return false;
|
|
46
|
+
if (img?.localName !== "img" || !img.closest(".doc-page") || holder?.closest(ZOOM_SKIP) || holder.matches(INSTANCE) || componentAt(holder) || !loaded(img)) return false;
|
|
47
47
|
const box = img.getBoundingClientRect();
|
|
48
48
|
return box.width >= ZOOM_LEAST || box.height >= ZOOM_LEAST;
|
|
49
49
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
+
import{b as a,g as c,h as m}from"./chunk-5ZKJ3H4P.mjs";import{b as r,f as i,i as l}from"./chunk-NSKUTQ5J.mjs";import"./chunk-5L7RYZCL.mjs";import{reportsDirectory as p}from"../browser/shared/paths.mjs";var f=5e3;async function h(u){let{positional:e,options:w}=i({options:["--no-browser"],argv:u});if(e.length>1)throw new r("Name one document at most.");let{slug:n=null,block:g=null}=e.length?await l(e[0]):{};console.log(`\u5DE5\u4F5C\u533A\uFF1A${p}`);let o=await c({slug:n,baseline:n!==null});if(o.ok||console.error(o.message),n!==null&&o.reason!=="missing"){let{roundBegins:s}=await import("./chunk-CEH4MRCC.mjs");await s(n,o.ok?{}:{wait:f})}o.ok||process.exit(1);let t=await m(n,o,g);for(let s of t)console.log(s);console.log(await a(t,w))}export{h as run};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
+
import{e as p}from"./chunk-6RGJOMJP.mjs";import{f as b}from"./chunk-AUZGSZJH.mjs";import{k as d}from"./chunk-6QXGZM36.mjs";import{g as k}from"./chunk-CY2FNNAB.mjs";import v from"node:fs/promises";import h from"node:path";import{editStateDirectory as m,reportsDirectory as f}from"../browser/shared/paths.mjs";import{findPreviewServer as $}from"../browser/shared/preview-server.mjs";import{documentDirectory as S,documentFiles as g,isDocumentSource as j}from"../browser/shared/workspace.mjs";var u=e=>h.resolve(e),D=e=>h.basename(g(h.dirname(e)).json),N={busy:"it kept changing while it was being written (an Agent writing it?); nothing written. Run the export again.",timeout:"the workspace's Gallery server did not answer in 30s; nothing written. Run the export again."};async function w(e,n,o="hand-in",l=3e4){let t=`127.0.0.1:${e.port}`,s;try{s=await fetch(`http://${t}/__gallery/edit/${o}`,{method:"POST",headers:{"Content-Type":"application/json",Origin:`http://${t}`,"X-Gallery-Token":e.token},body:JSON.stringify({slug:n,workspace:f}),signal:AbortSignal.timeout(l)})}catch(a){return a.name==="TimeoutError"?{ok:!1,reason:"timeout"}:null}let i=await s.json().catch(()=>null);return typeof i?.ok!="boolean"||["elsewhere","token","host","origin"].includes(i.reason)?null:i}async function P(e){let n=await $({reportsDirectory:f}),o=null,l=[],t=new Map,s=[];for(let i of e){let{html:a,json:c}=g(S(i,f)),r=n?await w(n,i):null;if(r===null&&(o??=p({reportsDirectory:f,stateDirectory:m,finish:d}),r=await o.handIn(i),r.ok&&await o.settleNotes(i)),!r.ok){r.reason!=="missing"&&t.set(i,[`${u(a)} was not handed in: ${N[r.reason]??r.message??r.reason}`]);continue}if(r.repeated?.length){t.set(i,b(r.repeated));continue}s.push(...L(a,r)),r.written&&(r.changes.length&&s.push(...k(a,r.changes,{reread:!1})),r.added&&s.push(...T(a,r.given,r.added)),l.push(u(a))),O(r)&&l.push(u(c))}return{written:l,failures:t,lines:s}}async function _(e){let n=await $({reportsDirectory:f});if(n){for(let o of e)if(await w(n,o,"settle")===null)return}}async function C(e,{wait:n=3e4}={}){try{let o=await $({reportsDirectory:f}),l=o?await w(o,e,"round",n):null;return l!==null?l.ok?l.ended===!0:null:await p({reportsDirectory:f,stateDirectory:m,finish:d}).beginRound(e)}catch{return null}}async function H(e){try{let n=p({reportsDirectory:f,stateDirectory:m,finish:d}),{html:o}=g(S(e,f));await n.noteTaken(e,await v.readFile(o,"utf8"))}catch{}}var O=({title:e=null,icon:n=null})=>!!(e&&typeof e.from=="string"&&e.from!==e.to||n&&!n.missing),x=10;function T(e,n,o=n?.length??0,{pending:l=!1}={}){let t=`${o} block${o===1?"":"s"}`;if(l){let i=[`ids ${u(e)}: ${t} without an id yet: the export gives ${o===1?"it":"each"} one`];return o>x?i:[...i,...n.map(({line:a,tag:c})=>` line ${a} ${c}`)]}let s=[`ids ${u(e)}: ${t} given an id`];return!n||o>x?s:[...s,...n.map(({line:i,tag:a,id:c})=>` line ${i} ${a} \u2192 ${c}`)]}function L(e,{title:n=null,icon:o=null}={},{pending:l=!1}={}){let t=u(h.dirname(e)),s=D(e),i=(c,r,y)=>l?`${c} not ${r} yet (${y}): the export writes ${c.includes(" and ")?"them":"it"}`:`${c} written ${r}: ${y}`,a=[];if(n){let c=[...n.page?["<title>"]:[],...typeof n.from=="string"&&n.from!==n.to?[`${s}'s title`]:[]];c.length&&a.push(`title ${t}: ${i(c.join(" and "),"as its h1 says it",JSON.stringify(n.to))}`)}return o?.missing?a.push(`icon ${t}: ${s} has the icon ${JSON.stringify(o.from)} and the page's header none: write it there (<div class="doc-icon">\u2026</div> before the h1) or take "icon" out of ${s} (the export leaves ${s}'s as it is)`):o&&a.push(`icon ${t}: ${i(`${s}'s icon`,"as its header has it",o.to===null?"none":JSON.stringify(o.to))}`),a}function K(e,{by:n="this export"}={}){let o=e.length===1,l=[...e.filter(t=>j(h.basename(t))).map(t=>h.basename(t)).filter((t,s,i)=>i.indexOf(t)===s).map(t=>`${t}: the kit's markup, block ids`),...e.filter(t=>/^(doc|report)\.json$/.test(h.basename(t))).map(t=>h.basename(t)).filter((t,s,i)=>i.indexOf(t)===s).map(t=>`${t}: the title or icon said above`)];return`Re-read ${e.join(", ")} before editing ${o?"it":"them"}: ${n} wrote ${o?"it":"them"} (${l.join("; ")}).`}export{P as a,_ as b,C as c,H as d,T as e,L as f,K as g};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
-
import{a as d,b as m,d as f}from"./chunk-
|
|
2
|
+
import{a as d,b as m,d as f}from"./chunk-64K7IPLO.mjs";import{readFileSync as $,realpathSync as O}from"node:fs";import l from"node:path";import{fileURLToPath as k}from"node:url";var x=l.dirname(k(import.meta.url));function g(t=x){for(let e=t;;e=l.dirname(e)){try{let i=JSON.parse($(l.join(e,"package.json"),"utf8"));if(i.name==="@heycys/gallery")return i.version}catch{}if(l.dirname(e)===e)return"0.0.0"}}var y={init:()=>import("./chunk-U6KNPJPR.mjs"),new:()=>import("./chunk-VBXMADMP.mjs"),import:()=>import("./chunk-XUNHRCOG.mjs"),open:()=>import("./chunk-3HIRPVLU.mjs"),serve:()=>import("./chunk-XNROSH2T.mjs"),stop:()=>import("./chunk-TMYZB6AV.mjs"),check:()=>import("./chunk-V5VXUJKG.mjs"),export:()=>import("./chunk-DKXG4XDG.mjs"),qa:()=>import("./chunk-JPOSLGOC.mjs"),list:()=>import("./chunk-V3HXVQEM.mjs"),move:()=>import("./chunk-LS4F7JUM.mjs"),set:()=>import("./chunk-W5BXXPDJ.mjs"),component:()=>import("./chunk-AJ73XJF3.mjs"),skill:()=>import("./chunk-BXO2ZY5P.mjs")},E=new Set(["stop","init","skill"]),S=(t,e)=>`${t.split(`
|
|
3
3
|
`)[0]} (gallery ${e?`${e} --help`:"help"} says more)`,w=t=>/^--.|^-[A-Za-z]/.test(t);function j(t){let e=t.indexOf("--"),i=e===-1?t:t.slice(0,e),u=e===-1?[]:t.slice(e),n=[],s=null;for(let o=0;o<i.length;o++){let r=i[o];if(r==="--workspace"||r.startsWith("--workspace=")){let a=r.includes("=")?r.slice(r.indexOf("=")+1):o+1<i.length&&!w(i[o+1])?i[++o]:"";if(!a)return{error:"--workspace takes a folder: --workspace <dir>",usage:f};if(s!==null&&l.resolve(s)!==l.resolve(a))return{error:`Two workspaces named: ${s} and ${a}.`,usage:f};s=a;continue}n.push(r)}if(n[0]==="--version"||n[0]==="-v"||n[0]==="-V")return n.length===1&&u.length===0?{version:!0}:{error:"--version takes nothing else.",usage:f};if(n.length===0||n[0]==="help"||n[0]==="--help"||n[0]==="-h"){let o=n[0]==="help"?n[1]:void 0;return o===void 0?{help:f}:Object.hasOwn(m,o)?{help:m[o]}:{error:`No such command: ${o} (${d.join(", ")}).`,usage:f}}let[c,...p]=n;if(!Object.hasOwn(y,c))return{error:w(c)?`Unknown option: ${c} (the command comes first: gallery <command> [options]).`:`No such command: ${c} (${d.join(", ")}).`,usage:f};let h=[...p,...u];if(p.some(o=>o==="--help"||o==="-h"))return{help:m[c]};if(c==="init"){let o=new Set(["--from"]),r=[];for(let a=0;a<p.length;a++)o.has(p[a])?a++:w(p[a])||r.push(p[a]);if(r.push(...u.slice(1)),r.length>1)return{error:"Name one folder at most.",usage:m.init,command:c};if(r.length===1){if(s!==null&&l.resolve(s)!==l.resolve(r[0]))return{error:`Two workspaces named: ${r[0]} and --workspace ${s}.`,usage:m.init,command:c};s=r[0]}}return{command:c,argv:h,flag:s}}var N=(t,e)=>`Cannot write the workspace ${t} (${e}): allow Gallery to write there, or pass --workspace <a folder you may write>.`,A=(t,e=!0)=>e?`${l.join(t,"gallery.json")} is not Gallery's (another program's file of that name): pass --workspace <another folder> for Gallery's documents.`:`${l.join(t,"gallery.json")} does not read as JSON: mend the file, or pass --workspace <another folder> for Gallery's documents.`;async function G(t=process.argv.slice(2)){process.stdout.on("error",o=>{throw o.code==="EPIPE"&&process.exit(process.exitCode??0),o});let e=j(t);if(e.version)return void console.log(g());if(e.help)return void console.log(e.help);e.error&&(console.error(`${e.error}
|
|
4
|
-
${S(e.usage,e.command)}`),process.exit(2));let{command:i,flag:u}=e,{findWorkspace:n}=await import("../browser/shared/workspace.mjs"),s=n({flag:u});if(process.env.GALLERY_WORKSPACE=s.root,!E.has(i)){let{ensureWorkspace:o}=await import("../browser/shared/workspace.mjs");try{let{ours:r,reads:a}=await o(s.root);r||(console.error(A(s.root,a)),process.exit(1))}catch(r){if(!r.code)throw r;console.error(N(s.root,r.code)),process.exit(1)}}let{UsageError:c,usageFailureText:p}=await import("./chunk-2B5E4CDJ.mjs"),h=await y[i]();try{await h.run(e.argv,{command:i,workspace:s.root,how:s.how,version:g()})}catch(o){if(!(o instanceof c))throw o;console.error(p(m[i],o.message,o.synopsis)),process.exit(2)}}var
|
|
4
|
+
${S(e.usage,e.command)}`),process.exit(2));let{command:i,flag:u}=e,{findWorkspace:n}=await import("../browser/shared/workspace.mjs"),s=n({flag:u});if(process.env.GALLERY_WORKSPACE=s.root,!E.has(i)){let{ensureWorkspace:o}=await import("../browser/shared/workspace.mjs");try{let{ours:r,reads:a}=await o(s.root);r||(console.error(A(s.root,a)),process.exit(1))}catch(r){if(!r.code)throw r;console.error(N(s.root,r.code)),process.exit(1)}}let{UsageError:c,usageFailureText:p}=await import("./chunk-2B5E4CDJ.mjs"),h=await y[i]();try{await h.run(e.argv,{command:i,workspace:s.root,how:s.how,version:g()})}catch(o){if(!(o instanceof c))throw o;console.error(p(m[i],o.message,o.synopsis)),process.exit(2)}}var v=t=>{try{return O.native(t)}catch{return null}};process.argv[1]&&v(process.argv[1])===v(k(import.meta.url))&&G();export{g as a,j as b,N as c,A as d,G as e};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
-
import{spawn as J}from"node:child_process";import P from"node:fs";import m from"node:fs/promises";import Q from"node:os";import k from"node:path";import{escapeMarkup as X}from"../browser/shared/escape.mjs";import{spawn as C}from"node:child_process";import{existsSync as H,readFileSync as M}from"node:fs";import w from"node:path";var V=e=>!["","0",void 0].includes(e),z=(e,r)=>(r.PATH??"").split(w.delimiter).some(t=>t&&H(w.join(t,e))),U=()=>{try{return process.platform==="linux"&&/microsoft/i.test(M("/proc/version","utf8"))}catch{return!1}};function K(e,{platform:r=process.platform,env:t=process.env,wsl:s=U()}={}){let n=encodeURI(e);return V(t.GALLERY_NO_BROWSER)?{skip:"GALLERY_NO_BROWSER is set"}:r==="win32"?{command:w.join(t.SystemRoot||t.windir||"C:\\Windows","System32","rundll32.exe"),args:["url.dll,FileProtocolHandler",n]}:r==="darwin"?{command:"open",args:[n]}:s?{command:"cmd.exe",args:["/c","start",'""',n.replace(/[&^]/g,"^$&")]}:!t.DISPLAY&&!t.WAYLAND_DISPLAY?{skip:"no display here (neither DISPLAY nor WAYLAND_DISPLAY is set)"}:z("xdg-open",t)?{command:"xdg-open",args:[n]}:{skip:"xdg-open is not installed"}}var q="Opened it in the default browser (if that is not Chrome or Edge, open the address there to edit).",T=e=>e.opened?q:`Not opened in a browser: ${e.why}.`;async function O(e,r){let t=K(e,r);return t.skip?{opened:!1,why:t.skip}:new Promise(s=>{let n;try{n=C(t.command,t.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(o){return s({opened:!1,why:`${w.basename(t.command)} did not start (${o.code??o.message})`})}n.once("error",o=>s({opened:!1,why:`${w.basename(t.command)} did not start (${o.code??o.message})`})),n.once("spawn",()=>{n.unref(),s({opened:!0})})})}import{packageRoot as Z,previewLogFile as f,projectRoot as G,release as I,reportsDirectory as h}from"../browser/shared/paths.mjs";import{fullAddress as ee}from"../browser/shared/page-address.mjs";import{findPreviewServer as te,galleryVersion as F,portIsFree as re,previewServerFor as ne,readAnnouncement as oe}from"../browser/shared/preview-server.mjs";import{documentLinks as se}from"../browser/shared/reports.mjs";import{documentDirectory as ie,documentFiles as ae,layoutOf as ce}from"../browser/shared/workspace.mjs";var $="\u4EA4\u7ED9\u7528\u6237\uFF08\u73B0\u5728\u5C31\u628A\u8FD9\u4E2A\u5730\u5740\u7ED9\u7528\u6237\uFF1B\u7528 Chrome \u6216 Edge \u6253\u5F00\uFF09\uFF1A",le="Agent \u81EA\u7528\uFF08\u53EA\u6709\u6587\u6863\u9875\uFF0C\u4E0D\u4EA4\u7ED9\u7528\u6237\uFF09\uFF1A",de=e=>`send the user ${e} now, in a message of its own, before any other step; then `;function
|
|
2
|
+
import{spawn as J}from"node:child_process";import P from"node:fs";import m from"node:fs/promises";import Q from"node:os";import k from"node:path";import{escapeMarkup as X}from"../browser/shared/escape.mjs";import{spawn as C}from"node:child_process";import{existsSync as H,readFileSync as M}from"node:fs";import w from"node:path";var V=e=>!["","0",void 0].includes(e),z=(e,r)=>(r.PATH??"").split(w.delimiter).some(t=>t&&H(w.join(t,e))),U=()=>{try{return process.platform==="linux"&&/microsoft/i.test(M("/proc/version","utf8"))}catch{return!1}};function K(e,{platform:r=process.platform,env:t=process.env,wsl:s=U()}={}){let n=encodeURI(e);return V(t.GALLERY_NO_BROWSER)?{skip:"GALLERY_NO_BROWSER is set"}:r==="win32"?{command:w.join(t.SystemRoot||t.windir||"C:\\Windows","System32","rundll32.exe"),args:["url.dll,FileProtocolHandler",n]}:r==="darwin"?{command:"open",args:[n]}:s?{command:"cmd.exe",args:["/c","start",'""',n.replace(/[&^]/g,"^$&")]}:!t.DISPLAY&&!t.WAYLAND_DISPLAY?{skip:"no display here (neither DISPLAY nor WAYLAND_DISPLAY is set)"}:z("xdg-open",t)?{command:"xdg-open",args:[n]}:{skip:"xdg-open is not installed"}}var q="Opened it in the default browser (if that is not Chrome or Edge, open the address there to edit).",T=e=>e.opened?q:`Not opened in a browser: ${e.why}.`;async function O(e,r){let t=K(e,r);return t.skip?{opened:!1,why:t.skip}:new Promise(s=>{let n;try{n=C(t.command,t.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(o){return s({opened:!1,why:`${w.basename(t.command)} did not start (${o.code??o.message})`})}n.once("error",o=>s({opened:!1,why:`${w.basename(t.command)} did not start (${o.code??o.message})`})),n.once("spawn",()=>{n.unref(),s({opened:!0})})})}import{packageRoot as Z,previewLogFile as f,projectRoot as G,release as I,reportsDirectory as h}from"../browser/shared/paths.mjs";import{fullAddress as ee}from"../browser/shared/page-address.mjs";import{findPreviewServer as te,galleryVersion as F,portIsFree as re,previewServerFor as ne,readAnnouncement as oe}from"../browser/shared/preview-server.mjs";import{documentLinks as se}from"../browser/shared/reports.mjs";import{documentDirectory as ie,documentFiles as ae,layoutOf as ce}from"../browser/shared/workspace.mjs";var $="\u4EA4\u7ED9\u7528\u6237\uFF08\u73B0\u5728\u5C31\u628A\u8FD9\u4E2A\u5730\u5740\u7ED9\u7528\u6237\uFF1B\u7528 Chrome \u6216 Edge \u6253\u5F00\uFF09\uFF1A",le="Agent \u81EA\u7528\uFF08\u53EA\u6709\u6587\u6863\u9875\uFF0C\u4E0D\u4EA4\u7ED9\u7528\u6237\uFF09\uFF1A",de=e=>`send the user ${e} now, in a message of its own, before any other step; then `;function Ve(e,r){let t=e.at(-1)??"";return`Next: ${t.startsWith($)?de(t.slice($.length)):""}${r}`}async function ze(e,r){let t=e.at(-1)??"";return t.startsWith($)?r.has("--no-browser")?"Not opened in a browser (--no-browser).":T(await O(t.slice($.length))):null}var D="GALLERY_NO_PREVIEW",pe=e=>!["","0",void 0].includes(e),Ue=e=>e.has("--no-preview")||pe(process.env[D]),ue=4317,fe=20,me=(e=process.env)=>{let r=Number(e.GALLERY_PORT);return Number.isInteger(r)&&r>0&&r<65536?r:ue},we=6e4,he=5*1024*1024,$e=k.join(G,"node_modules","vite","bin","vite.js"),ye=k.join(Z,"dist","server.mjs"),ge=e=>new Promise(r=>setTimeout(r,e)),A={reportsDirectory:h},Y=ce(h),R=(e,r)=>`http://127.0.0.1:${e}/generated/${r}.html`,ve=(e,r)=>`${R(e,r)}?agent`,j=e=>`http://127.0.0.1:${e}/`,xe=(e,r)=>se().then(({links:t})=>t,()=>null).then(t=>ee(`http://127.0.0.1:${e}`,r,t));async function ke({first:e=me(),count:r=fe}={}){let t=Number((await m.readFile(Y.lastPortFile,"utf8").catch(()=>"")).trim()),s=Array.from({length:Math.max(0,r)},(n,o)=>e+o);return Number.isInteger(t)&&t>0&&t<65536?[t,...s.filter(n=>n!==t)]:s}async function Le(){return await m.mkdir(k.dirname(f),{recursive:!0}),await m.stat(f).then(r=>r.size,()=>0)>he&&await m.rename(f,`${f}.1`).catch(()=>{}),P.openSync(f,"a")}async function Se(e,r){if(!I){let{writeSharedAssets:p}=await import("./chunk-VNV55RUA.mjs");await p()}let t=await Le();P.writeSync(t,`
|
|
3
3
|
[${new Date().toISOString()}] ${r}: Gallery ${F} on 127.0.0.1:${e} for ${h}
|
|
4
|
-
`);let[s,n]=I?[[ye,"--port",String(e)],Q.homedir()]:[[$e,"--host","127.0.0.1","--port",String(e),"--strictPort"],G],o=J(process.execPath,s,{cwd:n,env:{...process.env,GALLERY_WORKSPACE:k.resolve(h),GALLERY_SERVER_KIND:"cli"},detached:!0,stdio:["ignore",t,t],windowsHide:!0});return P.closeSync(t),o.unref(),o}async function
|
|
4
|
+
`);let[s,n]=I?[[ye,"--port",String(e)],Q.homedir()]:[[$e,"--host","127.0.0.1","--port",String(e),"--strictPort"],G],o=J(process.execPath,s,{cwd:n,env:{...process.env,GALLERY_WORKSPACE:k.resolve(h),GALLERY_SERVER_KIND:"cli"},detached:!0,stdio:["ignore",t,t],windowsHide:!0});return P.closeSync(t),o.unref(),o}async function be({slug:e=null,command:r=`gallery open${e?` ${e}`:""}`,ports:t=null,starting:s=we,baseline:n=!1}={}){let o=()=>!0;if(e){let a=ae(ie(e,h)),c=await m.readFile(a.html,"utf8").catch(()=>null);if(c===null)return{ok:!1,reason:"missing",message:`No document "${e}": ${a.html} does not exist (gallery new ${e} "<\u6807\u9898>" makes one; gallery list lists those there are).`};n&&await import("./chunk-SGJWQKEI.mjs").then(({previewBaseline:x})=>x(e,c));let i=await m.readFile(a.json,"utf8").then(JSON.parse).catch(()=>({})),v=[/<title>([^<]*)<\/title>/i.exec(c)?.[1]?.trim(),typeof i.title=="string"?i.title.trim():""].filter(Boolean);o=x=>v.length===0||v.some(_=>x.includes(_)||x.includes(X(_)))}let p=t??await ke(),L=p.length?`${Math.min(...p)} to ${Math.max(...p)}`:"none",S=`gallery open${e?` ${e}`:""}`,E=async(a,c=[])=>{let i=await ne({...A,ports:p.slice(a),start:v=>Se(v,r)});return i.busy?.newer?{failed:{ok:!1,reason:"newer",message:`A newer Gallery (${i.busy.version}) serves this workspace (port ${i.busy.port}, pid ${i.busy.pid}) and gave no answer in 10s; this is Gallery ${F}. Update this one (npm i -g @heycys/gallery@latest), or run ${S} again in a while.`}}:i.busy?{failed:{ok:!1,reason:"busy",message:`This workspace's Gallery server (port ${i.busy.port}, pid ${i.busy.pid}) took the request and gave no answer in 10s: it is busy or stuck. Run ${S} again in a while, or stop that process first (gallery stop): a second server of this workspace is not started beside it.`}}:i.stuck?{failed:{ok:!1,reason:"stuck",message:`An older Gallery's server serves this workspace and did not stop: ${i.stuck.message}`}}:i.port===null?{failed:{ok:!1,reason:"ports",message:`No server of this workspace runs, and no port from ${L} is free to start one on: stop a server on one of them (or name another first port: GALLERY_PORT=<n>), then run ${S}.`}}:{...i,passed:[...c,...i.passed]}},u=await E(0);if(u.failed)return u.failed;let{port:l,started:d,passed:b,replaced:W}=u,y=u.running??null,N=Date.now()+s,g="",B=async()=>{if(e){let c=await fetch(`${R(l,e)}?present`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null),i=c?.ok?await c.text():"";return g=c?i?`HTTP ${c.status} without the title`:`HTTP ${c.status}`:"no answer",!!(i&&o(i))}let a=await fetch(`http://127.0.0.1:${l}/__gallery/workspace/info`,{signal:AbortSignal.timeout(5e3)}).catch(()=>null);return g=a?`HTTP ${a.status}`:"no answer",!!a?.ok};for(;;await ge(300)){if(Date.now()>N)return{ok:!1,reason:"timeout",message:`${e?R(l,e):j(l)} did not answer${e?" with the document's title":""} in ${s/1e3}s (${g})${d?`; the server's output is in ${f}`:""}.`};if(d){let a=await te({...A,answering:!0});if(a&&a.pid!==d.pid){if(d.exitCode===null)try{process.kill(d.pid)}catch{}({port:l}=a),y={pid:a.pid,kind:(await oe(A))?.kind??"cli",version:null},d=null;continue}if(!a&&d.exitCode===null){g="the server started has not announced itself yet";continue}if(!a){if(!await re(l)){if(u=await E(p.indexOf(l)+1,[...b,`${l} (taken by another program while the server started)`]),u.failed)return u.failed;({port:l,started:d,passed:b}=u),y=u.running??null,N=Date.now()+s;continue}let c=await m.readFile(f,"utf8").catch(()=>"");return{ok:!1,reason:"stopped",message:`The Gallery server on port ${l} stopped (exit ${d.exitCode}). Its last words (${f}):
|
|
5
5
|
${c.split(`
|
|
6
6
|
`).slice(-15).join(`
|
|
7
7
|
`)}`}}}if(await B())break}return await m.writeFile(Y.lastPortFile,`${l}
|
|
8
|
-
`).catch(()=>{}),{ok:!0,port:l,pid:d?.pid??y?.pid??null,kind:y?.kind??"cli",started:!!d,replaced:W??null,passed:b}}var
|
|
8
|
+
`).catch(()=>{}),{ok:!0,port:l,pid:d?.pid??y?.pid??null,kind:y?.kind??"cli",started:!!d,replaced:W??null,passed:b}}var Ae=e=>e.length<2?e.join(""):`${e.slice(0,-1).join(", ")} and ${e.at(-1)}`;function Pe({port:e,pid:r,kind:t,started:s,replaced:n,passed:o=[]}){let p=[`pid ${r}`,...t==="dev"?["npm run dev's"]:[],...s?[`started now${o.length?`, after passing over ${Ae(o)}`:""}`]:[],...n?[`it replaced Gallery ${n.version??"an older version"}'s server, pid ${n.pid}`]:[]],L=s?`; its log: ${f}`:"";return`This workspace's Gallery server runs on port ${e} (${p.join(", ")}${L}). This command is done; the server runs on after it (nothing to wait for or keep running).`}async function Re(e,r,t=null){return[Pe(r),...e?[`${le}${ve(r.port,e)}`]:[],`${$}${e?await xe(r.port,{slug:e,block:t}):j(r.port)}`]}async function Ke(e,{skipped:r,command:t,ports:s=null}){let n=`gallery open ${e} starts it and prints the address to give the user`;if(r)return[`Preview: not started (--no-preview or ${D}): ${n}.`];let o=await be({slug:e,command:t,ports:s});return o.ok?Re(e,o):[`Preview: not started: ${o.message}`,`When that is fixed, ${n}.`]}export{Ve as a,ze as b,Ue as c,ve as d,j as e,ke as f,be as g,Re as h,Ke as i};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
-
var n=["init","new","import","open","serve","stop","check","export","qa","list","component","skill"],a=`The workspace (the folder of your documents) is --workspace <dir>, else GALLERY_WORKSPACE, else the
|
|
2
|
+
var n=["init","new","import","open","serve","stop","check","export","qa","list","move","set","component","skill"],a=`The workspace (the folder of your documents) is --workspace <dir>, else GALLERY_WORKSPACE, else the
|
|
3
3
|
nearest folder up from here holding gallery.json (gallery init makes one), else ~/Documents/Gallery (on Windows
|
|
4
4
|
the Documents folder Explorer shows, OneDrive's when OneDrive backs it up).`,e=`A document is named by its slug, by its link (\u5468\u62A5-k3xv9q2a, what gallery list shows after /#) or by a
|
|
5
5
|
whole address, as a user hands one over (http://127.0.0.1:4317/#\u5468\u62A5-k3xv9q2a, a block's id after a / or not): the
|
|
@@ -11,10 +11,13 @@ holding report.html or doc.html) into the workspace: every document whose slug i
|
|
|
11
11
|
others listed as skipped), its preferences.md when the workspace has none, the sidebar's order, the
|
|
12
12
|
\u5199\u4F5C\u504F\u597D page, the custom emoji and the documents' recent versions. The old folder is only read:
|
|
13
13
|
nothing there is changed, moved or deleted.
|
|
14
|
-
Exits 1 when the workspace cannot be written or --from names no folder.`,new:`Usage: gallery new <slug> "<title>" ["<description>"] [--no-preview] [--no-browser]
|
|
14
|
+
Exits 1 when the workspace cannot be written or --from names no folder.`,new:`Usage: gallery new <slug> "<title>" ["<description>"] [--under <document>] [--after <document> | --first] [--no-preview] [--no-browser]
|
|
15
15
|
A new document in <workspace>/<slug>/ from the starter: its doc.html, holding the starter's section
|
|
16
|
-
to replace, and doc.json, with the title and the description (\u65B0\u6587\u6863 when none is given).
|
|
17
|
-
|
|
16
|
+
to replace, and doc.json, with the title and the description (\u65B0\u6587\u6863 when none is given). Where it goes
|
|
17
|
+
in the sidebar's tree: under --under's document, last (first with --first), or right after --after's
|
|
18
|
+
(at that one's level); neither, at the top level, last. A document is named there by its slug, link
|
|
19
|
+
or address (gallery help says how), and must be there, not in the trash; the \u5199\u4F5C\u504F\u597D page holds none.
|
|
20
|
+
Then says where it went (Placed it \u2026), where it wrote (the workspace), where the user's writing preferences are (\u5199\u4F5C\u504F\u597D,
|
|
18
21
|
<workspace>/preferences.md, to read first: made from Gallery's default when there are none yet) and
|
|
19
22
|
the next steps (the first: send the user the address now), and last starts this workspace's Gallery
|
|
20
23
|
server (or uses the one running: it runs on after this command), opens the default browser at the
|
|
@@ -24,7 +27,8 @@ browser. Editing needs Chrome or Edge.
|
|
|
24
27
|
A title or a description that starts with "-" and a letter would be read as an option: put "--"
|
|
25
28
|
before the arguments (gallery new q3-review -- "-Q3 \u56DE\u987E").
|
|
26
29
|
Exits 1 when the document exists, or the slug is the workspace's own (exports, the \u5199\u4F5C\u504F\u597D page's) or
|
|
27
|
-
a document's in the trash
|
|
30
|
+
a document's in the trash, or a document --under or --after names is not there (nothing made), or
|
|
31
|
+
the new one could not be placed (made, at the top level); 2 for a document named that is in the trash.`,import:`Usage: gallery import <file> [<slug> ["<title>"]] [--no-preview] [--no-browser]
|
|
28
32
|
New documents made of a file, as the workbench's \u5BFC\u5165 makes them: Markdown (.md .markdown .mdx .txt
|
|
29
33
|
.text), HTML (.html .htm .xhtml, a Gallery export too), a table (.csv .tsv), Word (.docx), PDF (.pdf,
|
|
30
34
|
its text), EPUB (.epub) or a .zip of them (a Notion export: one document a page, nested as there).
|
|
@@ -99,13 +103,44 @@ with a fresh profile.
|
|
|
99
103
|
Exits 1 when anything fails (or the export it ran first did), 3 when something could not be
|
|
100
104
|
verified (UNVERIFIED: no browser, or one that did not start), 2 when an export is missing or stale
|
|
101
105
|
with --no-export or --blocks names an id the document has not, else 0. A warning never fails.`,list:`Usage: gallery list [<words>...]
|
|
106
|
+
gallery list --tree [<document>]
|
|
102
107
|
The workspace's documents, for an Agent to find the one the user means: each one's slug and title,
|
|
103
|
-
its description,
|
|
108
|
+
its description, where it is in the sidebar's tree when it is under another (\u4F4D\u7F6E\uFF1Athe documents above
|
|
109
|
+
it, from the top), its address (\u5730\u5740\uFF1A/#<link>, after the port of the workspace's server), when its file
|
|
104
110
|
was last written and where that file is, the one edited last first.
|
|
105
111
|
With words, only those whose title, description or slug holds any of them (case alike, Chinese found
|
|
106
|
-
inside words), the best first
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
inside words), the best first, then those whose text holds them, each with its first place there
|
|
113
|
+
(\u6B63\u6587\uFF1A\u2026); with a document's link or whole address, that document, or that it is in the trash.
|
|
114
|
+
--tree lists them as the sidebar shows them, in its order, each under the one it is under, indented
|
|
115
|
+
two spaces a level: a line each, its slug, its title (its emoji before it), its description and its
|
|
116
|
+
last edit. --tree <document>: that document and the documents under it, after its \u4F4D\u7F6E line.
|
|
117
|
+
${e}
|
|
118
|
+
First, the workspace and where \u5199\u4F5C\u504F\u597D is (made from Gallery's default when there is none yet).
|
|
119
|
+
Exits 1 when --tree names a document that is not there, 2 one in the trash.`,move:`Usage: gallery move <document> (--under <document> | --top) [--after <document> | --first]
|
|
120
|
+
Moves a document in the sidebar's tree, with the documents under it: under --under's document, to the
|
|
121
|
+
top level (--top), or where it is now (neither); right after --after's document (one at that level,
|
|
122
|
+
whose level it is when neither --under nor --top says one), first (--first), else last. Written
|
|
123
|
+
through the workspace's running server when there is one (an open workbench shows it at once), else
|
|
124
|
+
here. Nothing in the documents' files changes: links between documents go by their folders, which
|
|
125
|
+
stay where they are.
|
|
126
|
+
${e}
|
|
127
|
+
Prints where it went and where it was, then its place (\u4F4D\u7F6E\uFF1A\u2026, as gallery list says it).
|
|
128
|
+
Exits 0 when it moved or is there already; 1 when a document named is not there or is the \u5199\u4F5C\u504F\u597D page
|
|
129
|
+
(listed apart: it moves nowhere and holds none), when the place is under itself or a document under
|
|
130
|
+
it, or --after names one at another level; 2 for a document in the trash.`,set:`Usage: gallery set <document> [--title "<title>"] [--icon <icon>|none] [--description "<text>"]
|
|
131
|
+
Changes a document's title, page icon or description as the workbench's \u91CD\u547D\u540D and the page's icon
|
|
132
|
+
picker do: the title in doc.html (the h1 of its header, and <title> where that holds the h1's words,
|
|
133
|
+
else the whole of it) and in doc.json; the icon in the header (div.doc-icon before the h1: made,
|
|
134
|
+
changed, or taken away with none) and in doc.json; the description in doc.json. An icon is an emoji,
|
|
135
|
+
an icon of the \u56FE\u6807 tab (/icons/<name>_<color>.svg, Tabler's /icons/tabler/<name>_<color>.svg, the
|
|
136
|
+
colors gray, lightgray, brown, yellow, orange, green, blue, purple, pink, red) or a picture of the
|
|
137
|
+
document's folder (assets/<file>). doc.html is written as an Agent writes it, the rest of it as it
|
|
138
|
+
is: the page open in the browser shows it, and the workbench's sidebar the new title and icon.
|
|
139
|
+
A title that starts with "-" and a letter is written --title="-Q3 \u56DE\u987E".
|
|
140
|
+
${e}
|
|
141
|
+
Prints what changed, then the files to re-read before editing them.
|
|
142
|
+
Exits 1 when the document is not there or is the \u5199\u4F5C\u504F\u597D page, its page has no h1.doc-title, its
|
|
143
|
+
doc.json does not read, or the picture is not in its folder; 2 for an icon that is none of these.`,component:`Usage: gallery component new <id> [--script] [--flow]
|
|
109
144
|
gallery component list
|
|
110
145
|
gallery component show <id>
|
|
111
146
|
gallery component check <id>
|
|
@@ -115,7 +150,8 @@ yet).`,component:`Usage: gallery component new <id> [--script]
|
|
|
115
150
|
A component package is a block to use again, kept in the workspace: components/<scope>/<name>/. An id
|
|
116
151
|
is <scope>/<name>, or a <name> alone in the scope local; a document uses one by an element naming it.
|
|
117
152
|
new starts a package: component.json, template.html, example.html, writing.md and style.css, and with
|
|
118
|
-
--script a kit.js
|
|
153
|
+
--script a kit.js; with --flow a slot, body, in place of its paragraph, where a document writes blocks
|
|
154
|
+
of its own. It passes check as it stands, and says what to write next.
|
|
119
155
|
Exits 1 when the id is taken.
|
|
120
156
|
list says what the workspace has now: the components to write with, each with its version, then those
|
|
121
157
|
not to write with now and why: hidden, disabled, one that does not load, a manifest one level too shallow;
|
|
@@ -127,14 +163,15 @@ never a failure, in five sections: 1 the manifest, with template.html there, tex
|
|
|
127
163
|
words and marks alone, and a note on a Chinese name no word of its words spells whole in pinyin, a
|
|
128
164
|
syllable a character, by how many syllables a word reads as; 2 kit.js: what a browser refuses, what
|
|
129
165
|
an export refuses, what it registers, a type check against sdk/; 3 style.css: every selector in the
|
|
130
|
-
instance, what an export cannot hold
|
|
131
|
-
by what gallery check runs, and template.html as what
|
|
166
|
+
instance, what an export cannot hold, and a note on one that goes down into a slot; 4 template.html
|
|
167
|
+
and example.html, each read as a document's page by what gallery check runs, and template.html as what
|
|
168
|
+
a menu can put in; 5
|
|
132
169
|
both in a temporary document, exported and opened as gallery qa opens one, in Chrome or Edge under the export's
|
|
133
170
|
policy: what the console and the policy say, a dialog or a window it opens, mount then dehydrate then
|
|
134
171
|
mount and copies put back giving the same DOM (a drawing neither the manifest's runtime nor dehydrate
|
|
135
|
-
names piles up, and what piles up outside the instance is named too), a
|
|
136
|
-
redraws, a data part a mount changes, a write with no gesture
|
|
137
|
-
to the file (a way back line: what the component's example wrote, each part with how many of its
|
|
172
|
+
names piles up, and what piles up outside the instance is named too), a slot the component writes in
|
|
173
|
+
or moves, a text part the component redraws, a data part a mount changes, a write with no gesture
|
|
174
|
+
once the page takes edits, the way back to the file (a way back line: what the component's example wrote, each part with how many of its
|
|
138
175
|
lines the write took out and put in, and that the server took it; a note on a write that lays a part
|
|
139
176
|
out anew, and on a list a card is dropped on that listens for dragover and not for dragenter), a page
|
|
140
177
|
wider than the window, and the pictures, in <workspace>/.gallery/qa/components/<id>/, its absolute
|
|
@@ -204,7 +241,9 @@ Gallery: documents written as HTML, edited in the browser, exported as one offli
|
|
|
204
241
|
gallery check [<slug>...] check documents (none named: all)
|
|
205
242
|
gallery export <slug>... | --all write <workspace>/exports/<slug>.html
|
|
206
243
|
gallery qa <slug>... [--blocks a,b] [--tiles] look at exports in Chrome or Edge
|
|
207
|
-
gallery list [<words>...]
|
|
244
|
+
gallery list [<words>...] | --tree [<slug>] the documents, those the words name, or the tree
|
|
245
|
+
gallery move <slug> --under <slug> | --top move a document (and those under it) in the tree
|
|
246
|
+
gallery set <slug> --title|--icon|--description change a document's title, icon or description
|
|
208
247
|
gallery component new|list|show|check [<id>] make, list, read and check component packages
|
|
209
248
|
gallery component try <slug> --press <selector> a reader's gesture on an instance, and what it wrote
|
|
210
249
|
gallery skill install [--agent claude|codex] write the Agent's skill for this version
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
-
import{a as g}from"./chunk-HYMEEXKN.mjs";import{createRequire as re}from"node:module";import{typescriptFile as ae}from"../browser/shared/paths.mjs";var ce=re(import.meta.url),B=null;function fe(){return B??=ce(ae??"typescript"),B}var $=new Proxy({},{get:(e,n)=>fe()[n]});import _ from"node:fs/promises";import h from"node:path";import{COMPONENTS as D,instancesOf as ue}from"../browser/shared/components/index.mjs";import{PACKAGE_MARK as q}from"../browser/shared/components/installed.mjs";import{MATH_IGNORED_TAGS as pe}from"../browser/shared/components/math.mjs";import{attr as x,elementsOf as b,walk as y}from"../browser/shared/html-tree.mjs";import I from"node:path";import de from"node:vm";var L=()=>{throw new Error("esbuild is not in the release: Gallery 0.1.
|
|
2
|
+
import{a as g}from"./chunk-HYMEEXKN.mjs";import{createRequire as re}from"node:module";import{typescriptFile as ae}from"../browser/shared/paths.mjs";var ce=re(import.meta.url),B=null;function fe(){return B??=ce(ae??"typescript"),B}var $=new Proxy({},{get:(e,n)=>fe()[n]});import _ from"node:fs/promises";import h from"node:path";import{COMPONENTS as D,instancesOf as ue}from"../browser/shared/components/index.mjs";import{PACKAGE_MARK as q}from"../browser/shared/components/installed.mjs";import{MATH_IGNORED_TAGS as pe}from"../browser/shared/components/math.mjs";import{attr as x,elementsOf as b,walk as y}from"../browser/shared/html-tree.mjs";import I from"node:path";import de from"node:vm";var L=()=>{throw new Error("esbuild is not in the release: Gallery 0.1.1 calls it only in a source checkout")},Le=L,J=L;var Te=new Proxy({},{get:L});import{projectRoot as le}from"../browser/shared/paths.mjs";var T=I.join(le,"src","shared","components","index.mjs");function F(e){let{outputFiles:n}=J({stdin:{contents:`import { FLOWS, FLOW_BLOCKS, runtimeDescriptions } from ${JSON.stringify(e)}; module.exports = { descriptions: runtimeDescriptions(), flows: FLOWS, blockFlows: FLOW_BLOCKS };`,resolveDir:I.dirname(e),loader:"js"},bundle:!0,write:!1,format:"cjs",platform:"node",logLevel:"silent"}),s={module:{exports:null}};return de.runInNewContext(n[0].text,s),JSON.parse(JSON.stringify(s.module.exports))}var W=(e=T)=>F(e).descriptions,G=(e=T)=>F(e).flows,U=(e=T)=>F(e).blockFlows;import{kitPublicDirectory as me,projectRoot as H,release as Y,vendorDirectory as z}from"../browser/shared/paths.mjs";var P=h.join(H,"node_modules"),he=h.join(P,"d3","dist","d3.min.js"),S=Y?h.join(z,"katex"):h.join(P,"katex","dist"),xe=h.join(S,"fonts"),He=h.join(S,"contrib","mhchem.min.js"),u=[{id:"styles",file:"report.css",build:{styles:"styles/index.css"},always:!0},{id:"katex-styles",vendor:{path:"/vendor/katex/katex.min.css",source:h.join(S,"katex.min.css")}},{id:"runtime",file:"runtime.js",build:{bundle:"runtime/index.js",options:()=>({minify:!1,define:{__COMPONENT_RUNTIME__:JSON.stringify(W()),__COMPONENT_FLOWS__:JSON.stringify(G()),__COMPONENT_BLOCK_FLOWS__:JSON.stringify(U())}})},api:"DocKit",always:!0},{id:"code",file:"code.js",build:{bundle:"code.js",options:{minify:!0,legalComments:"inline"}},api:"DocCode",after:["runtime"]},{id:"state",file:"state.js",build:{read:"state.js"},api:"DocState",always:!0},{id:"sheets",file:"sheets.js",build:{read:"sheets.js"},api:"DocSheets",after:["runtime","state"]},{id:"tokens",file:"tokens.js",build:{read:"tokens.js"},api:"DocTokens",always:!0},{id:"ui",file:"ui.js",build:{bundle:"ui.js",options:{minify:!1}},added:!0,after:["runtime","state","tokens"]},{id:"dialogs",file:"dialogs.js",build:{read:"dialogs.js"},api:"DocDialogs",after:["runtime"]},{id:"katex",vendor:{path:"/vendor/katex/katex.min.js",source:h.join(S,"katex.min.js")},umd:!0},{id:"katex-auto-render",vendor:{path:"/vendor/katex/auto-render.min.js",source:h.join(S,"contrib","auto-render.min.js")},umd:!0,after:["katex"]},{id:"math",file:"math.js",build:{bundle:"math-bundle.js",options:{minify:!1,legalComments:"inline",alias:{katex:h.join(H,"src","render","kit","page-katex.js")},nodePaths:[h.join(P,"katex")]}},api:"DocMath",after:["runtime","katex-styles","katex","katex-auto-render"]},{id:"d3",vendor:{path:"/vendor/d3.v7.9.0.min.js",source:he},api:"d3",umd:!0},{id:"charts",file:"charts.js",build:{bundle:"charts/index.js",options:{minify:!1}},api:"DocCharts",after:["runtime","tokens"]},{id:"tables",file:"tables.js",build:{bundle:"tables/index.js",options:{minify:!1}},api:"DocTables",after:["runtime"]}],m=e=>e.file?`/kit/${e.file}`:e.vendor.path,ge=e=>e.file?h.join(me,e.file):h.join(z,...e.vendor.path.split("/").slice(2));if(Y)for(let e of u)e.vendor&&(e.vendor.source=ge(e));var O=e=>m(e).endsWith(".css"),E=e=>e.file?"data-doc-kit":"data-doc-vendor",C=e=>u.find(n=>n.id===e),w=(e,n=m(e))=>O(e)?`<link rel="stylesheet" href="${n}" ${E(e)}="${e.id}">`:`<script src="${n}" ${E(e)}="${e.id}"></script>`,we=u.map(e=>({id:e.id,tag:w(e),always:!!e.always,element:O(e)?"style":"script",attribute:E(e)}));function Ye(e,n=m){let s=new Set,i=t=>{s.has(t)||(s.add(t),C(t)?.after?.forEach(i))};return e.forEach(i),u.filter(t=>s.has(t.id)&&!t.always&&!t.added).map(t=>w(t,n(t)))}function ye(e=u,n=D){let s=[],i=e.map(t=>t.id);for(let t of new Set(i.filter((a,o)=>i.indexOf(a)!==o)))s.push(`the asset "${t}" is listed twice`);for(let t of e){!!t.file==!!t.vendor&&s.push(`the asset "${t.id}" is a kit file (file) or a vendor file (vendor), one of them`),t.file&&!["read","bundle","styles"].some(o=>typeof t.build?.[o]=="string")&&s.push(`the kit file "${t.file}" does not say how it is made (build: read, bundle or styles)`),t.vendor&&!(t.vendor.path&&t.vendor.source)&&s.push(`the vendor asset "${t.id}" needs its public path and its source`);for(let o of t.after??[])i.includes(o)?i.indexOf(o)>i.indexOf(t.id)&&s.push(`the asset "${t.id}" loads after "${o}", which the list puts after it`):s.push(`the asset "${t.id}" loads after "${o}", which is no asset`);let a=n.filter(o=>(o.assets??[]).includes(t.id));!t.always&&!t.api&&!t.added&&a.length===0&&s.push(`no report would keep the asset "${t.id}": it is not always kept, defines no global and no component needs it`)}for(let t of n)for(let a of t.assets??[])i.includes(a)||s.push(`the component "${t.id}" needs "${a}", which is no asset`);return s}{let e=ye();if(e.length>0)throw new Error(`src/render/assets.mjs: ${e.join("; ")}`)}var K=/^(?:|module|(?:text|application)\/(?:x-)?(?:javascript|ecmascript)|text\/javascript1\.[0-5]|text\/(?:jscript|livescript))$/,$e=/^application\/(?:\S+\+)?json$/,N=e=>(x(e,"type")??"").trim().toLowerCase();function V(e){let n=$.createSourceFile("report.js",e,$.ScriptTarget.Latest,!1,$.ScriptKind.JS),s=[],i=[n];for(;i.length>0;){let t=i.pop();if(t.kind>=$.SyntaxKind.FirstJSDocNode&&t.kind<=$.SyntaxKind.LastJSDocNode)continue;let a=t.getChildren(n);a.length===0&&s.push(e.slice(t.getStart(n),t.end));for(let o=a.length-1;o>=0;o-=1)i.push(a[o])}return s.join(" ")}var Q=e=>new RegExp(`\\b(?:${e.filter(n=>n.api).map(n=>n.api).join("|")})\\b`);function ke(e,n){let s=[],i=t=>{n.test(t)&&s.push(V(t))};return y(e,t=>{t.tagName==="script"&&x(t,"src")===void 0&&K.test(N(t))&&i(t.childNodes.map(a=>a.value??"").join(""));for(let{name:a,value:o}of t.attrs??[]){if(/^on/.test(a)){i(o);continue}let f=o.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(!/^javascript:/i.test(f))continue;let r=f.slice(11);try{r=decodeURIComponent(r)}catch{}i(r)}}),s.join(`
|
|
3
3
|
`)}function je(e,n){let s=[],i=(o,f)=>{for(let r of o.childNodes??[]){let c=r.sourceCodeLocation;r.nodeName==="#comment"||f&&r.nodeName==="#text"?c&&s.push([c.startOffset,c.endOffset]):r.tagName==="script"?i(r,$e.test(N(r))):r.tagName&&i(r.content??r,f||pe.includes(r.tagName))}};i(e,!1);let t="",a=0;for(let[o,f]of s.sort((r,c)=>r[0]-c[0]))o<a||(t+=`${n.slice(a,o)} `,a=f);return t+n.slice(a)}function R(e,n=u,s=D){let i=n.reduce((c,d)=>c.replaceAll(w(d),""),e),t=g(i),a=je(t,i),o=ke(t,Q(n)),f=new Set,r=c=>{f.has(c)||(f.add(c),(n.find(d=>d.id===c)?.after??[]).forEach(r))};for(let c of s){if(!(c.assets??[]).length)continue;((c.uses??[]).some(l=>l.test(a))||c.match&&ue(t,c).length>0)&&c.assets.forEach(r)}for(let c of n)c.api&&new RegExp(`\\b${c.api}\\b`).test(o)&&r(c.id);return f}function ze(e,n=D){let s=R(e,u,n),i=[];for(let t of u){let a=w(t);if(t.always||t.added||s.has(t.id)||!e.includes(a))continue;let o=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");e=e.replace(new RegExp(`[ \\t]*${o}[ \\t]*\\r?\\n?`),""),i.push(t.id)}return{html:e,removed:i,used:s}}function M(e,n){let s=[];return y(n,i=>{let t=Z(i),a=t===void 0?void 0:u.find(f=>m(f)===t.trim()),o=i.sourceCodeLocation;!a||!o||s.push({asset:a,start:o.startOffset,end:o.endOffset,line:o.startLine,exact:e.slice(o.startOffset,o.endOffset)===w(a)})},{inTemplates:!1}),s}var X=e=>e.tagName==="style"||e.tagName==="link"&&(x(e,"rel")??"").toLowerCase().split(/\s+/).includes("stylesheet"),Z=e=>e.tagName==="script"?x(e,"src"):X(e)?x(e,"href"):void 0,j=e=>!!e.sourceCodeLocation,A=e=>e.includes(`\r
|
|
4
4
|
`)?`\r
|
|
5
5
|
`:`
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
|
|
2
|
+
import{d as je,e as Oe}from"./chunk-QJIR2BLP.mjs";import{d as ve}from"./chunk-P2CAZPDP.mjs";import{a as de,c as lt,d as $e,e as xe,f as Se}from"./chunk-E7LWZRXY.mjs";import{a as me,d as pe,e as we,f as he,g as ye}from"./chunk-TYK6VNAB.mjs";import{b as ge,c as ke,e as be,g as Bt}from"./chunk-CY2FNNAB.mjs";import{a as ie}from"./chunk-UMHUSOPJ.mjs";import{F as le,G as ue,H as Ut,a as W}from"./chunk-L3QKH4OK.mjs";import{d as ce,q as fe}from"./chunk-W4VKN3GF.mjs";import{createHmac as _n,randomBytes as Gt}from"node:crypto";import{existsSync as Ln,mkdirSync as Un,readFileSync as Bn,writeFileSync as Wn}from"node:fs";import Y from"node:fs/promises";import I from"node:path";import{FILE as Yn}from"../browser/shared/annotations.mjs";import{escapeTyped as Zn}from"../browser/shared/escape.mjs";import{writeAtomic as Tt}from"../browser/shared/files.mjs";import{sendJson as _}from"../browser/shared/http.mjs";import{REQUEST_ID as Ct}from"../browser/shared/ids.mjs";import{UPLOAD_REQUEST_LIMIT as Cn}from"../browser/shared/media.mjs";import{reportsDirectory as zn}from"../browser/shared/paths.mjs";import{sameDirectory as Gn}from"../browser/shared/preview-server.mjs";import{slugPattern as et}from"../browser/shared/reports.mjs";import{documentDirectory as Hn,documentFiles as jt,isDocumentSource as Kn}from"../browser/shared/workspace.mjs";import Wt from"node:fs/promises";import Ne from"node:path";import{checkAnnotations as pn,cleanAnchor as wn,cleanItem as Ae,FILE as hn,itemsText as yn,readItems as gn,treeText as Ee}from"../browser/shared/annotations.mjs";import{writeAtomic as kn}from"../browser/shared/files.mjs";import{slugPattern as bn}from"../browser/shared/reports.mjs";import{documentDirectory as Re,documentFiles as $n}from"../browser/shared/workspace.mjs";var xn=600*1e3,Sn=600*1e3;function vn(f){let{units:c,boxes:g}=ue(f),m=[...c].sort((p,y)=>p.elStart-y.elStart),$=new Map(m.map((p,y)=>[p.id,y])),u=new Map(m.map(p=>[p.id,Ee(p.node)])),O={h2:null,h3:null,h4:null};return m.map(p=>{let y=[];for(let E=p;E;E=E.parent===null?null:c[E.parent]){let v=g[E.box];if(v?.kind==="panel"&&v.key!==null){let J=c.find(U=>U.kind==="tab"&&U.parent===v.unit&&U.key===v.key);J&&y.unshift({tab:u.get(J.id)})}let G=v?.unit===null||v?.unit===void 0?null:c[v.unit];if(G?.tag==="details"&&v.kind==="details"){let J=G.node.childNodes.find(U=>U.tagName==="summary");J&&y.push({details:Ee(J)})}}let M=y.find(E=>E.tab)?.tab,T=y.find(E=>E.details)?.details,L=[M,O.h2,O.h3,O.h4,T].filter(Boolean);return p.tag==="h2"?Object.assign(O,{h2:u.get(p.id),h3:null,h4:null}):p.tag==="h3"?Object.assign(O,{h3:u.get(p.id),h4:null}):p.tag==="h4"&&(O.h4=u.get(p.id)),{id:p.blockId,text:u.get(p.id),parent:p.parent===null?null:$.get(p.parent)??null,where:L,heading:/^h[2-4]$/.test(p.tag)}})}function Te({reportsDirectory:f,read:c,write:g=kn,dropped:m=()=>{},now:$=Date.now}){let u=new Map,O=new Map,p=new Map,y=(s,w)=>{let r=p.get(s);if(r?.text===w)return r.units;let o=vn(w);return p.set(s,{text:w,units:o}),o},M=s=>Ne.join(Re(s,f),hn),T=s=>typeof s=="string"&&bn.test(s);async function L(s){let w=await Wt.readFile(M(s),"utf8").catch(()=>null);return{text:w,items:w===null?[]:gn(w)}}async function E(s,w,r){let o=yn(w);return o===r||(o===null?await Wt.rm(M(s),{force:!0}):await g(M(s),o)),v(o)}let v=s=>s===null?"":W(s),G=s=>{let w=u.get(s)??new Map;for(let[r,o]of w)$()-o>xn&&w.delete(r);return[...w.keys()]},J=(s,w)=>w.forEach(r=>u.get(s)?.delete(r)),U=s=>{let w=O.get(s)??O.set(s,new Map).get(s);for(let[r,o]of w)$()-o>Sn&&w.delete(r);return w};async function D(s,{keep:w=null,items:r=null,before:o=void 0}={}){let k=r?{items:r,text:o}:await L(s),b=await c(s).catch(()=>null);if(!b)return{items:k.items,units:[],places:new Map,version:v(k.text),missing:!0};let R=y(s,b.text),N=U(s),h=pn(k.items,R,{keep:new Set([...N.keys(),w])});for(let j of N.keys())h.waiting.has(j)||N.delete(j);if(h.dropped.length>0){let j=u.get(s)??u.set(s,new Map).get(s);for(let F of h.dropped)j.set(F.id,$())}let x=h.changed||r?await E(s,h.items,k.text):v(k.text);return h.dropped.length>0&&m(s,h.dropped),{items:h.items,units:R,places:h.places,version:x,missing:!1}}let B=(s,{items:w,version:r})=>({ok:!0,version:r,items:w,dropped:G(s)});async function H(s){if(!T(s))return[400,{ok:!1,reason:"body"}];let w=await D(s);return w.missing?[404,{ok:!1,reason:"missing"}]:[200,B(s,w)]}async function nt(s){if(!T(s))return[400,{ok:!1,reason:"body"}];let w=await D(s);if(w.missing)return[404,{ok:!1,reason:"missing"}];let r=null,o=$n(Re(s,f));try{r=JSON.parse(await Wt.readFile(o.json,"utf8"))}catch{}let k=await c(s).catch(()=>null),b=/<h1\b[^>]*>([\s\S]*?)<\/h1>/i.exec(k?.text??"")?.[1]?.replace(/<[^>]*>/g,"").trim(),R=typeof r?.title=="string"&&r.title.trim()?r.title.trim():b||s,N=w.units.some(x=>x.heading),h=w.items.map(x=>{let j=w.units[w.places.get(x.id)?.at],F=j?.where?.length?j.where:j?.heading?[j.text]:[];return{where:F,top:N&&F.length===0,blocks:x.anchor.blocks.filter(X=>w.units.some(rt=>rt.id===X)),whole:x.anchor.kind==="blocks",quote:x.anchor.quote,text:x.text}});return[200,{ok:!0,title:R,path:Ne.resolve(o.html),items:h}]}async function K(s){let{slug:w}=s??{};if(!T(w))return[400,{ok:!1,reason:"body"}];if(!await c(w).catch(()=>null))return[404,{ok:!1,reason:"missing"}];let r=await L(w);if(s.anchors&&typeof s.anchors=="object"&&!Array.isArray(s.anchors)){let N=r.items.map(x=>{let j=Object.hasOwn(s.anchors,x.id)?wn(s.anchors[x.id]):null;return j&&j.kind===x.anchor.kind?{...x,anchor:j}:x}),h=await E(w,N,r.text);return[200,B(w,{items:N,version:h})]}let o=r.items,k=null,b=null;if(s.put!==void 0){let N=o.find(x=>x.id===s.put?.id),h=Ae({...s.put,created:N?.created??s.put?.created});if(!h)return[400,{ok:!1,reason:"item"}];o=N?o.map(x=>x.id===h.id?h:x):[...o,h],k=h.id,N||U(w).set(h.id,$()),J(w,[h.id])}else if(typeof s.remove=="string")o=o.filter(N=>N.id!==s.remove);else if(s.clear===!0)b=o,o=[];else if(Array.isArray(s.restore)){let N=new Map(o.map(j=>[j.id,j])),h=s.restore.map(j=>Ae(j,j?.updated)).filter(j=>j&&!(N.get(j.id)?.updated>j.updated)),x=new Set(h.map(j=>j.id));for(let j of x)N.has(j)||U(w).set(j,$());o=[...o.filter(j=>!x.has(j.id)),...h],J(w,[...x])}else return[400,{ok:!1,reason:"body"}];let R=await D(w,{keep:k,items:o,before:r.text});return[200,{...B(w,R),...b?{removed:b}:{}}]}async function q(s){if(!T(s))return;let{text:w}=await L(s);w!==null&&await D(s)}return{list:H,copy:nt,change:K,afterWrite:q}}import ut from"node:fs/promises";import dt from"node:path";import{writeAtomic as Me}from"../browser/shared/files.mjs";import{slugPattern as Yt}from"../browser/shared/reports.mjs";var Rt=1,St={seen:"seen.html",base:"base.html",state:"state.json"},jn=4,On=1800*1e3;function Fe({stateDirectory:f=null,shown:c,folderOf:g,isPage:m=()=>!1,log:$=null,now:u=Date.now,quiet:O=On}){let p=new Map,y=r=>dt.join(f,"changes",r),M=Promise.resolve(),T=r=>{let o=M.then(r);return M=o.catch(k=>$?.(`changes: ${k.message}`)),o};async function L(r){if(!f)return p.get(r)?.state??null;try{let o=JSON.parse(await ut.readFile(dt.join(y(r),St.state),"utf8"));return o?.v===Rt&&typeof o.seen=="string"?o:null}catch{return null}}async function E(r,o){return f?ut.readFile(dt.join(y(r),St[o]),"utf8").catch(()=>null):p.get(r)?.[o]??null}async function v(r,o,k={}){if(!f){let b=p.get(r)??{};p.set(r,{...b,...k,state:o});return}await ut.mkdir(y(r),{recursive:!0});for(let[b,R]of Object.entries(k))R===null?await ut.rm(dt.join(y(r),St[b]),{force:!0}):await Me(dt.join(y(r),St[b]),R);await Me(dt.join(y(r),St.state),`${JSON.stringify(o)}
|
|
3
|
+
`)}async function G(r){p.delete(r),f&&await ut.rm(y(r),{recursive:!0,force:!0,maxRetries:3})}let J=async r=>Math.round((await ut.stat(g(r)).catch(()=>null))?.birthtimeMs??0),U=r=>r?.base?`${r.since}|${r.writes}`:null,D=r=>Number.isFinite(r?.draft)&&u()-r.draft<O?r.draft:null,B=(r,o,k,b=D(r))=>[{v:Rt,born:r?.born??0,seen:o,...b===null?{}:{draft:b}},{seen:k,base:null}];async function H(r){let o=await L(r);if(!o)return null;let k=await J(r);return o.born&&k&&o.born!==k?(await G(r),null):o}async function nt(r,o){if(typeof o!="string"||!Yt.test(r)||m(r))return!1;let k=W(o),b=await H(r);if(!b)return await v(r,{v:Rt,born:await J(r),seen:k},{seen:o}),!1;if(b.seen===k)return!1;let R=await E(r,"seen"),N=new Date(u()).toISOString();if(R===null)return await v(r,...B(b,k,o)),!1;let h=c(R),x=c(o);if(!b.base){if(!lt(h,x))return await v(r,...B(b,k,o)),!1;if(D(b)!==null||$e(h))return await v(r,...B(b,k,o,u())),!1;let{draft:X,...rt}=b;return await v(r,{...rt,seen:k,base:W(h),since:N,at:N,writes:1},{seen:o,base:h}),!0}let j=await E(r,"base");if(j===null||!lt(j,x))return await v(r,...B(b,k,o)),!0;let F=lt(h,x)!==null;return await v(r,{...b,seen:k,...F?{at:N,writes:b.writes+1}:{}},{seen:o}),F}async function K(r,o,k,b){if(!Yt.test(r)||m(r))return!1;let R=await H(r),N=W(o);if(!R?.base)return await v(r,...B(R??{born:await J(r)},N,o,b?null:D(R))),!1;let h=await E(r,"base");if(h!==null&&k)try{h=k(h)}catch(x){$?.(`changes: ${r}: the baseline did not take the edit (${x.message})`)}return h===null||!lt(h,c(o))?(await v(r,...B(R,N,o)),!0):(await v(r,{...R,seen:N,base:W(h)},{seen:o,base:h}),!1)}async function q(r,o){if(!Yt.test(r)||m(r))return{ended:!1,moved:!1};let k=typeof o=="string"?await nt(r,o):!1,b=await H(r);if(b?.draft===void 0)return{ended:!1,moved:k};let{draft:R,...N}=b;return await v(r,N),{ended:D(b)!==null,moved:k}}let s=new Map;async function w(r,o){await nt(r,o);let k=c(o),b=W(k),R=await H(r);if(!R?.base)return{pending:!1,version:b};let N=`${r} ${R.base} ${b}`,h=s.get(N);if(h===void 0){let x=await E(r,"base");for(h=x===null?null:lt(x,k),s.set(N,h);s.size>jn;)s.delete(s.keys().next().value)}return h?{pending:!0,version:b,stamp:U(R),since:R.since,writes:R.writes,...h}:{pending:!1,version:b}}return{look:(r,o)=>T(()=>nt(r,o)),wrote:(r,o,k=null,{reader:b=!1}={})=>T(()=>K(r,o,k,b)),endDraft:(r,o=null)=>T(()=>q(r,o)),read:(r,o)=>T(()=>w(r,o)),stamp:r=>T(async()=>U(await H(r))),snapshot:r=>T(async()=>{let o=await H(r);return o?{state:o,seen:await E(r,"seen"),base:await E(r,"base")}:null}),clear:r=>T(async()=>{let o=await H(r);o?.base&&await v(r,{v:Rt,born:o.born,seen:o.seen},{base:null})}),restore:(r,o)=>T(async()=>{o?.state&&await v(r,o.state,{seen:o.seen,base:o.base})}),forget:r=>T(()=>G(r)),idle:()=>T(async()=>{})}}import{randomBytes as Nn}from"node:crypto";import ot from"node:fs/promises";import mt from"node:path";import{FILE as An,readItems as En}from"../browser/shared/annotations.mjs";import{writeAtomic as Rn}from"../browser/shared/files.mjs";import{documentDirectory as Tn}from"../browser/shared/workspace.mjs";var Mn=20,Pe=/^\d{8}T\d{6}Z-[a-f0-9]{8}\.json$/,Ie=80,Je=({stateDirectory:f,slug:c})=>mt.join(f,"dropped-annotations",c),_e=f=>({id:f.id,text:f.text,quote:f.anchor?.quote??"",kind:f.anchor?.kind??"text"});async function Le({stateDirectory:f,reportsDirectory:c,slug:g,time:m,items:$}){let u=Je({stateDirectory:f,reportsDirectory:c,slug:g});await ot.mkdir(u,{recursive:!0});let O=m.replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Rn(mt.join(u,`${O}-${Nn(4).toString("hex")}.json`),JSON.stringify({time:m,items:$}));let p=(await ot.readdir(u)).filter(y=>Pe.test(y)).sort();await Promise.all(p.slice(0,Math.max(0,p.length-Mn)).map(y=>ot.rm(mt.join(u,y),{force:!0})))}async function Mr({stateDirectory:f,reportsDirectory:c,slug:g}){let m=Je({stateDirectory:f,reportsDirectory:c,slug:g}),$=(await ot.readdir(m).catch(()=>[])).filter(p=>Pe.test(p)).sort();if($.length===0)return[];let u=new Set(En(await ot.readFile(mt.join(Tn(g,c),An),"utf8").catch(()=>"")).map(p=>p.id)),O=[];for(let p of $){let y=mt.join(m,p);try{let M=JSON.parse(await ot.readFile(y,"utf8")),T=Array.isArray(M?.items)?M.items.filter(L=>typeof L?.id=="string"&&!u.has(L.id)):[];typeof M?.time=="string"&&T.length&&O.push({time:M.time,items:T})}catch{}await ot.rm(y,{force:!0}).catch(()=>{})}return O}var Fn=(f,c=new Date)=>{let g=new Date(f),m=u=>String(u).padStart(2,"0"),$=`${m(g.getHours())}:${m(g.getMinutes())}`;return g.toDateString()===c.toDateString()?$:`${g.getFullYear()}-${m(g.getMonth()+1)}-${m(g.getDate())} ${$}`},De=f=>{let c=String(f??"").replace(/\s+/g," ").trim();return JSON.stringify(c.length>Ie?`${c.slice(0,Ie-1)}\u2026`:c)};function Zt(f,{time:c=null,items:g},{today:m=new Date}={}){let $=mt.resolve(f),u=`${g.length} \u6279\u6CE8 (annotation${g.length===1?"":"s"})`;return[`annotations ${$}: ${c?`at ${Fn(c,m)}, `:""}Gallery deleted ${u} whose words are gone from the document (rewritten or deleted):`,...g.map(({id:O,text:p,quote:y,kind:M})=>` ${O} ${De(p)} on ${M==="blocks"?"the blocks ":""}${De(y)}`)]}function Fr(f,c,{today:g=new Date}={}){return c.length?[...c.flatMap(m=>Zt(f,m,{today:g}))," they were the reader's: say in your hand-off which your edit carried out and which you left, and never write them back"]:[]}import{randomBytes as In}from"node:crypto";import pt from"node:fs/promises";import vt from"node:path";import{writeAtomic as Dn}from"../browser/shared/files.mjs";var Pn=20,Ue=/^\d{8}T\d{6}Z-[a-f0-9]{8}\.json$/,Be=({stateDirectory:f,slug:c})=>vt.join(f,"rewrites",c);async function We({stateDirectory:f,reportsDirectory:c,slug:g,time:m,changes:$}){let u=Be({stateDirectory:f,reportsDirectory:c,slug:g});await pt.mkdir(u,{recursive:!0});let O=m.replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Dn(vt.join(u,`${O}-${In(4).toString("hex")}.json`),JSON.stringify({time:m,changes:$}));let p=(await pt.readdir(u)).filter(y=>Ue.test(y)).sort();await Promise.all(p.slice(0,Math.max(0,p.length-Pn)).map(y=>pt.rm(vt.join(u,y),{force:!0})))}async function Ye({stateDirectory:f,reportsDirectory:c,slug:g}){let m=Be({stateDirectory:f,reportsDirectory:c,slug:g}),$=(await pt.readdir(m).catch(()=>[])).filter(O=>Ue.test(O)).sort(),u=[];for(let O of $){let p=vt.join(m,O);try{let y=JSON.parse(await pt.readFile(p,"utf8"));typeof y?.time=="string"&&Array.isArray(y.changes)&&u.push(y)}catch{}await pt.rm(p,{force:!0}).catch(()=>{})}return u}var Jn=(f,c=new Date)=>{let g=new Date(f),m=u=>String(u).padStart(2,"0"),$=`${m(g.getHours())}:${m(g.getMinutes())}`;return g.toDateString()===c.toDateString()?$:`${g.getFullYear()}-${m(g.getMonth()+1)}-${m(g.getDate())} ${$}`};function Lr(f,c,{today:g=new Date}={}){if(!c.length)return[];let m=vt.resolve(f),$=[];for(let{time:u,changes:O}of c){let p=[];for(let{line:y,rule:M,key:T}of[...O].sort((L,E)=>L.line-E.line)){let L=`line ${y} ${M}${T?` ${T}`:""}`;p.includes(L)||p.push(L)}$.push(`preview ${m}: at ${Jn(u,g)}, when the reader edited the page, the preview wrote your natural HTML as the kit's markup: ${p.join(", ")}`),$.push(...O.filter(y=>y.note).map(({line:y,rule:M,note:T})=>` line ${y}, ${M}: ${T}`))}return $.push(" re-read the file before editing it (those lines are the file's as you had left it)"),$}import{EMPTY_STYLE as Qn,emptyWordsScript as Vn,showEmpty as qn}from"../browser/editor/components/placeholder.mjs";import{TOKENS as Xn}from"../browser/editor/page/look.mjs";import{MARGIN_STYLE as tr,earlyMarginScript as er}from"../browser/editor/page/margin.mjs";var zt=/^[a-f0-9]{16}$/,Ht=2*1024*1024,nr=Cn,Ze=50,Ce=/^\d{8}T\d{6}Z-[a-f0-9]{16}\.html$/,rr=30,ze=3,Ge=200,wt="\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u7A0D\u540E\u518D\u540C\u6B65",ar="\u8FD9\u6B21\u7684\u4FEE\u6539\u592A\u5927\uFF0C\u4E00\u6B21\u5B58\u4E0D\u4E0B",or=250,Mt=Symbol("again"),sr="/__gallery/edit/src/editor/page/editor.mjs",ir=f=>new Promise(c=>setTimeout(c,f));function cr(f,c=Ht){return new Promise((g,m)=>{let $=[],u=0;f.on("data",O=>{u+=O.length,u>c?$.length=0:$.push(O)}),f.on("end",()=>u>c?m(new Error("too-large")):g(Buffer.concat($).toString("utf8"))),f.on("error",m)})}function fr(f){if(!f)return Gt(16).toString("hex");let c=I.join(f,"token");try{let m=Bn(c,"utf8").trim();if(/^[a-f0-9]{32}$/.test(m))return m}catch{}let g=Gt(16).toString("hex");try{Un(f,{recursive:!0,mode:448}),Wn(c,g,{mode:384})}catch{}return g}function ma({reportsDirectory:f=zn,stateDirectory:c=null,write:g=Tt,ids:m=!0,finish:$=M=>M,log:u=null,settling:O={},reviewing:p={},onChanges:y=()=>{}}={}){let M=fr(c),T=Oe(O),L=O.wait??je,E=async(t,n,e)=>{let a=await g(t,n,e);return a!==!1&&Kn(I.basename(t))&&T.wrote(I.basename(I.dirname(t)),n),a},v=t=>Hn(t,f),G=t=>jt(v(t)).html,J=new Map,U=c&&I.join(c,"snapshots"),D=Promise.resolve(),B=Promise.resolve(),H=async(t,n,e,{by:a="time"}={})=>{let i=(await Y.readdir(t)).filter(l=>n.test(l));if(i.length<=e)return;let d=a==="name"?i.sort():(await Promise.all(i.map(async l=>({name:l,time:(await Y.stat(I.join(t,l))).mtimeMs})))).sort((l,S)=>l.time-S.time).map(({name:l})=>l);await Promise.all(d.slice(0,d.length-e).map(l=>Y.rm(I.join(t,l),{force:!0})))},nt=(t,n)=>{U&&(D=D.then(async()=>{let e=I.join(U,`${t}.html`),a=new Date;try{await Y.utimes(e,a,a);return}catch{}await Y.mkdir(U,{recursive:!0}),await Tt(e,n),await H(U,/^[a-f0-9]{16}\.html$/,Ze)}).catch(()=>{}))},K=(t,n)=>{c&&(D=D.then(async()=>{let e=I.join(c,"history",t),a=W(n);if(await Y.mkdir(e,{recursive:!0}),(await Y.readdir(e)).filter(l=>Ce.test(l)).sort().at(-1)?.endsWith(`-${a}.html`))return;let d=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");await Tt(I.join(e,`${d}-${a}.html`),n),await H(e,Ce,rr,{by:"name"})}).catch(()=>{}))},q=new Map,s=t=>c&&I.join(c,"receipts",t),w=(t,n,e,a)=>{for(q.set(`${t} ${n}`,{digest:e,answer:a});q.size>Ge*4;)q.delete(q.keys().next().value);let i=s(t);i&&(D=D.then(async()=>{await Y.mkdir(i,{recursive:!0}),await Tt(I.join(i,`${n}.json`),JSON.stringify({digest:e,answer:a})),await H(i,{test:d=>d.endsWith(".json")&&Ct.test(d.slice(0,-5))},Ge)}).catch(()=>{}))},r=async(t,n)=>{let e=q.get(`${t} ${n}`);if(e)return e;let a=s(t);if(!a)return null;await D;try{let i=JSON.parse(await Y.readFile(I.join(a,`${n}.json`),"utf8"));return typeof i?.digest=="string"&&i.answer?.ok?i:null}catch{return null}},o=new Map,k=(t,n)=>{let e=new Date().toISOString();if(!c)return void o.set(t,[...o.get(t)??[],{time:e,changes:n}].slice(-20));D=D.then(()=>We({stateDirectory:c,reportsDirectory:f,slug:t,time:e,changes:n})).catch(()=>{})},b=async t=>{if(!c){let n=o.get(t)??[];return o.delete(t),n}return await D,Ye({stateDirectory:c,reportsDirectory:f,slug:t})},R=(t,n)=>{for(J.delete(t),J.set(t,n);J.size>Ze;)J.delete(J.keys().next().value);nt(t,n)},N=async t=>{if(J.has(t))return J.get(t);if(!U||!zt.test(t))return null;await D;let n=await Y.readFile(I.join(U,`${t}.html`),"utf8").catch(()=>null);return n===null||W(n)!==t?null:(R(t,n),n)},h=new Map,x=t=>{let n=h.get(t);if(n)return n;let e=ge(t,{finish:$});for(h.set(t,e);h.size>8;)h.delete(h.keys().next().value);return e},j=I.join(I.resolve(f),".gallery","pages"),F=Fe({...p,stateDirectory:c,shown:t=>x(t).text,folderOf:v,log:u,isPage:t=>I.resolve(v(t)).startsWith(j+I.sep)}),X=(t,n)=>n.then(e=>{e&&y(t)},e=>u?.(`${t}: the Agent's changes not kept (${e.message})`));async function rt(t,n=void 0){if(typeof t!="string"||!et.test(t))return null;let e=G(t),a=n!==void 0?n:await Y.readFile(e,"utf8").catch(()=>null);if(a===null)return null;let{text:i,changes:d}=x(a);return{file:e,source:a,text:i,version:W(i),changes:d}}async function st(t){if(typeof t!="string"||!et.test(t))return{source:null,held:!1,signs:[],wait:0,own:!1};let n=G(t),e=await Y.readFile(n,"utf8").catch(()=>null),a=(await Y.stat(n).catch(()=>null))?.mtimeMs??0;return{source:e,...T.judge(t,{source:e,mtime:a})}}async function ht(t,n=Date.now()+L){for(;;){let e=await st(t);if(!e.held||Date.now()>=n)return e;await ir(Math.max(0,Math.min(or,n-Date.now())))}}async function Ft(t,{wait:n=L}={}){let e=await ht(t,Date.now()+n);return rt(t,e.held&&e.taken!==void 0?e.taken:e.source)}function He(t,n,{editor:e=sr,kitTags:a=()=>[]}={}){let{html:i,map:d}=de(n);R(d.version,n);let l=ce(f),S=fe(l).map(({assets:C,...V})=>({...V,kit:a(C)})),A=`<script type="application/json" id="doc-edit-map" data-doc-dev>${JSON.stringify({slug:t,token:M,...d,components:S,hidden:l.settings.hidden}).replace(/</g,"\\u003c")}</script>
|
|
4
|
+
<script data-doc-dev>document.currentScript.remove(); import(${JSON.stringify(e)});</script>`,Z=`<style data-doc-dev>.doc-display { display: none; }</style>
|
|
5
|
+
<style data-doc-dev data-ge-palette>${Xn}</style>
|
|
6
|
+
<style data-doc-dev>${Qn}</style>
|
|
7
|
+
<script data-doc-dev>${Vn()}</script>
|
|
8
|
+
<script data-doc-dev>document.currentScript.remove(); document.documentElement.setAttribute("data-ge-order", "file");</script>
|
|
9
|
+
<style data-doc-dev data-ge-margin-style>${tr}</style>
|
|
10
|
+
<script data-doc-dev>document.currentScript.remove(); ${er(t,{notes:Ln(I.join(v(t),Yn))})}</script>`;return{html:qn(i),snippet:A,head:Z}}let Ke=t=>R(W(t),t);async function it(t,n=Ht){if(t.method!=="POST")return{error:[405,{ok:!1,reason:"method"}]};let e=t.headers.host??"",a=t.socket.localPort;if(e!==`127.0.0.1:${a}`&&e!==`localhost:${a}`)return{error:[403,{ok:!1,reason:"host"}]};if(t.headers.origin!==`http://${e}`)return{error:[403,{ok:!1,reason:"origin"}]};if(t.headers["x-gallery-token"]!==M)return{error:[403,{ok:!1,reason:"token"}]};if(!/^application\/json\b/i.test(t.headers["content-type"]??""))return{error:[415,{ok:!1,reason:"type"}]};try{return{body:JSON.parse(await cr(t,n))}}catch(i){return{error:i.message==="too-large"?[413,{ok:!1,reason:"body",message:ar}]:[400,{ok:!1,reason:"body"}]}}}async function Qe(t,n){let{slug:e,opening:a,known:i=null,texts:d=[],units:l=[],touch:S=[],pageIds:P=null,request:A=null,agent:Z=!1}=t;if(typeof e!="string"||!et.test(e)||![d,l,S].every(Array.isArray))return[400,{ok:!1,reason:"body"}];if(A!==null&&(typeof A!="string"||!Ct.test(A)))return[400,{ok:!1,reason:"body"}];let C=A===null?null:W(JSON.stringify([a??null,d,l,S])),V=await Kt(t);if(V)return V;let z=at=>(A!==null&&w(e,A,C,at),[200,at]),Q=G(e),tt=typeof a=="string"&&zt.test(a)?await N(a):null,ee=at=>_n("sha256",M).update(`${e}
|
|
11
|
+
${at}`).digest("hex").slice(0,32);for(let at=1;;at++){let{source:$t,held:un}=await st(e);if($t===null)return[404,{ok:!1,reason:"missing"}];if(un)return Date.now()<n?Mt:[409,{ok:!1,reason:"busy",message:wt}];X(e,F.look(e,$t));let{text:xt,changes:Lt}=x($t),ne=[],At=pe({current:xt,opening:tt,texts:d,units:l,touch:S,ids:m?()=>{let Et=typeof m=="function"?m():Ut();return ne.push(Et),Et}:!1,seal:ee,pageIds:P}),{title:re,icon:ae,...oe}=At,ft=At.text===xt?xt:$(At.text);ft!==At.text&&(oe.version=W(ft));let se={...oe,foreign:typeof i=="string"&&W(xt)!==i};if(ft===xt)return z({ok:!0,...se,wrote:!1,notes:[]});if(K(e,$t),!await E(Q,ft,{expect:$t})){if(at===ze)return[409,{ok:!1,reason:"busy",message:wt}];continue}K(e,ft),X(e,F.wrote(e,ft,Et=>{let mn=0;return xe(Et,{opening:tt,texts:d,units:l,touch:S,pageIds:P,seal:ee,ids:m?()=>ne[mn++]??(typeof m=="function"?m():Ut()):!1})},{reader:Z!==!0})),Lt.length&&(u&&u(Bt(Q,Lt).join(`
|
|
12
|
+
`)),k(e,Lt));let dn=[...re?await Ot(I.dirname(Q),re):[],...ae!==void 0?await It(I.dirname(Q),ae):[]];return z({ok:!0,...se,wrote:!0,notes:dn})}}async function Kt({slug:t,opening:n,texts:e=[],units:a=[],touch:i=[],request:d=null}){if(typeof t!="string"||!et.test(t)||typeof d!="string"||!Ct.test(d)||![e,a,i].every(Array.isArray))return null;let l=await r(t,d);return l?l.digest===W(JSON.stringify([n??null,e,a,i]))?[200,{...l.answer,again:!0}]:[409,{ok:!1,reason:"request",message:"\u540C\u4E00\u6B21\u4FDD\u5B58\u7684\u5185\u5BB9\u4E0D\u4E00\u81F4"}]:null}async function Ve(t,n){let{slug:e,opening:a,texts:i=[],units:d=[],instances:l=[],pageIds:S=null}=t;if(typeof e!="string"||!et.test(e)||!Array.isArray(i)||!Array.isArray(d)||!Array.isArray(l))return[400,{ok:!1,reason:"body"}];let{source:P,held:A}=await st(e);if(A)return Date.now()<n?Mt:[409,{ok:!1,reason:"busy",message:wt}];let Z=await rt(e,P);if(Z===null)return[404,{ok:!1,reason:"missing"}];let{text:C,version:V}=Z,z=typeof a=="string"&&zt.test(a)?await N(a):null;return[200,{ok:!0,version:V,reverted:ye({current:C,opening:z,texts:i,pageIds:S}),units:we({current:C,units:d}),parts:he({current:C,instances:l,pageIds:S})}]}let qe=600*1e3,yt=new Map;async function Qt(t,n){let e=v(t),a=null;try{a=JSON.parse(await Y.readFile(jt(e).json,"utf8"))}catch{}let{title:i,icon:d}=be(n,a);i&&typeof a?.title=="string"&&a.title!==i.to&&await Ot(e,{from:a.title,to:i.to,synced:!0}),d&&!d.missing&&await It(e,d.to)}async function Xe(t,n){let{slug:e,action:a,stamp:i=null,undo:d=null}=t;if(typeof e!="string"||!et.test(e)||!["accept","revert","undo"].includes(a))return[400,{ok:!1,reason:"body"}];let l=G(e),{source:S,held:P}=await st(e);if(S===null)return[404,{ok:!1,reason:"missing"}];if(P)return Date.now()<n?Mt:[409,{ok:!1,reason:"busy",message:wt}];if(a==="undo"){for(let[Q,tt]of yt)Date.now()-tt.at>qe&&yt.delete(Q);let z=typeof d=="string"?yt.get(d):null;return!z||z.slug!==e?[404,{ok:!1,reason:"gone",message:"\u64A4\u9500\u5DF2\u7ECF\u8FC7\u671F"}]:S!==z.after?[409,{ok:!1,reason:"moved-on",message:"\u64A4\u56DE\u4E4B\u540E\u6587\u6863\u53C8\u6539\u8FC7\u4E86\uFF0C\u6CA1\u6CD5\u64A4\u9500"}]:(K(e,S),await E(l,z.before,{expect:S})?(K(e,z.before),yt.delete(d),await Qt(e,z.before),await F.restore(e,z.saved),await F.wrote(e,z.before),y(e),[200,{ok:!0,version:W(x(z.before).text)}]):[409,{ok:!1,reason:"busy",message:wt}])}await F.look(e,S);let A=await F.snapshot(e),Z=A?.state?.base?`${A.state.since}|${A.state.writes}`:null;if(Z===null)return[200,{ok:!0,none:!0}];if(Z!==i)return[409,{ok:!1,reason:"changed",message:"Agent \u521A\u521A\u53C8\u6539\u4E86\u6587\u6863\uFF0C\u518D\u770B\u4E00\u773C"}];if(a==="accept")return await F.clear(e),y(e),[200,{ok:!0}];let C=A.base;if(K(e,S),!await E(l,C,{expect:S}))return[409,{ok:!1,reason:"busy",message:wt}];K(e,C),await Qt(e,C);let V=Gt(8).toString("hex");return yt.set(V,{slug:e,before:S,after:C,saved:A,at:Date.now()}),await F.clear(e),await F.wrote(e,C),y(e),[200,{ok:!0,version:W(x(C).text),undo:V}]}async function tn(t,n){let e=await it(t);if(e.error)return _(n,...e.error);let a=e.body??{};try{if(a.action!=="read")return _(n,...await qt(a,Xe));if(typeof a.slug!="string"||!et.test(a.slug))return _(n,400,{ok:!1,reason:"body"});let i=await Ft(a.slug,{wait:0});return i===null?_(n,404,{ok:!1,reason:"missing"}):_(n,200,{ok:!0,...await F.read(a.slug,i.source)})}catch(i){return _(n,500,{ok:!1,reason:"write",message:i.message})}}async function Ot(t,{from:n,to:e,synced:a}){let i=["\u6807\u9898\u5DF2\u66F4\u65B0",...a?[]:["\u5355\u72EC\u6253\u5F00\u6216\u5BFC\u51FA\u65F6\u7684\u9875\u9762\u540D\u79F0\u539F\u672C\u5C31\u548C\u6807\u9898\u4E0D\u540C\uFF0C\u6CA1\u6709\u8DDF\u7740\u6539"]],d=jt(t).json,l=await Y.readFile(d,"utf8").catch(()=>""),S=null;try{S=JSON.parse(l)}catch{}if(S?.title!==n)return[...i,"\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u6587\u6863\u540D\u539F\u672C\u5C31\u548C\u6807\u9898\u4E0D\u540C\uFF0C\u6CA1\u6709\u8DDF\u7740\u6539"];let P=new RegExp(`("title"\\s*:\\s*)${JSON.stringify(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}`),A=P.test(l)?l.replace(P,(Z,C)=>C+JSON.stringify(e)):`${JSON.stringify({...S,title:e},null,2)}
|
|
13
|
+
`;try{await E(d,A)}catch(Z){return u?.(`${I.basename(d)}'s title was not written (${Z.code??Z.message}): ${d}`),[...i,"\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u6587\u6863\u540D\u6CA1\u80FD\u8DDF\u7740\u6539"]}return i}async function It(t,n){let e=jt(t).json,a=null;try{a=JSON.parse(await Y.readFile(e,"utf8"))}catch{}if(!a||typeof a!="object")return u?.(`${I.basename(e)} could not be read, so its icon was not written: ${e}`),["\u9875\u9762\u56FE\u6807\u5DF2\u66F4\u6362\uFF0C\u4F46\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u56FE\u6807\u6CA1\u80FD\u8DDF\u7740\u6362"];if((a.icon??null)===n)return[];let{icon:i,...d}=a,l=n===null?d:{...d,icon:n};try{await E(e,`${JSON.stringify(l,null,2)}
|
|
14
|
+
`)}catch(S){return u?.(`${I.basename(e)}'s icon was not written (${S.code??S.message}): ${e}`),["\u9875\u9762\u56FE\u6807\u5DF2\u66F4\u6362\uFF0C\u4F46\u641C\u7D22\u548C\u4FA7\u680F\u91CC\uFF08\u6CA1\u6253\u5F00\u8FD9\u4EFD\u6587\u6863\u65F6\uFF09\u7684\u56FE\u6807\u6CA1\u80FD\u8DDF\u7740\u6362"]}return[]}async function en(t,n){let e=typeof n=="string"?n.replace(/\s+/g," ").trim():"";if(!e)return{ok:!1,reason:"title",message:"\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A"};let a=G(t),i=await Y.readFile(a,"utf8").catch(()=>null);if(i===null)return{ok:!1,reason:"missing"};X(t,F.look(t,i));let d=ie(i),l=le(d).find(A=>A.kind==="title");if(!l)return{ok:!1,reason:"no-title",message:"\u8FD9\u4EFD\u6587\u6863\u6CA1\u6709\u6807\u9898"};let S=Zn(e),P=me({current:d,edits:[{id:l.id,parts:[{keep:!0,html:S}]}],ids:m});return P.ok?P.text!==i&&!await E(a,P.text,{expect:i})?{ok:!1,reason:"changed-again"}:(P.text!==i&&X(t,F.wrote(t,P.text,A=>Se(A,S))),{ok:!0,title:e,notes:P.title?await Ot(I.dirname(a),P.title):[]}):{ok:!1,reason:"conflict"}}let gt=t=>(n,e)=>{let a=B.then(()=>t(n));return B=a.catch(()=>{}),a.then(([i,d])=>_(e,i,d),i=>_(e,500,{ok:!1,reason:"write",message:i.message}))},Vt=(t,{early:n=null}={})=>async(e,a)=>{let i=await it(e);if(i.error)return _(a,...i.error);let d=i.body??{};try{let l=n&&await n(d);return l?_(a,...l):_(a,...await qt(d,t))}catch(l){return _(a,500,{ok:!1,reason:"write",message:l.message})}};async function qt(t,n){let e=Date.now()+L;for(;;){await ht(t.slug,e);let a=B.then(()=>n(t,e));B=a.catch(()=>{});let i=await a;if(i!==Mt)return i}}async function Dt(t,{reader:n=!1}={}){if(typeof t!="string"||!et.test(t))return{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"};let e=v(t),{html:a,json:i}=jt(e);for(let d=1;;d++){let{source:l,held:S}=n?await st(t):{source:await Y.readFile(a,"utf8").catch(()=>null),held:!1};if(l===null)return{ok:!1,reason:"missing",message:"\u627E\u4E0D\u5230\u8FD9\u4EFD\u6587\u6863"};if(S)return{ok:!1,reason:"busy",message:"\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u6CA1\u6709\u5199\u5165"};X(t,F.look(t,l));let P=null;try{P=JSON.parse(await Y.readFile(i,"utf8"))}catch{}let{text:A,changes:Z,added:C,given:V,repeated:z,title:Q,icon:tt}=ke(l,{finish:$,next:typeof m=="function"?m:void 0,metadata:P});if(A!==l){if(K(t,l),!await E(a,A,{expect:l})){if(d===ze)return{ok:!1,reason:"busy",message:"\u6587\u4EF6\u4E00\u518D\u88AB\u4FEE\u6539\uFF08\u4F8B\u5982 AI \u6B63\u5728\u5199\u5165\uFF09\uFF0C\u6CA1\u6709\u5199\u5165"};continue}K(t,A),X(t,F.wrote(t,A)),n&&Z.length&&(u&&u(Bt(a,Z).join(`
|
|
15
|
+
`)),k(t,Z))}return Q&&typeof P?.title=="string"&&P.title!==Q.to&&await Ot(e,{from:P.title,to:Q.to,synced:Q.page}),tt&&!tt.missing&&await It(e,tt.to),{ok:!0,changes:A===l?[]:Z,added:A===l?0:C,given:A===l?[]:V,repeated:z,written:A!==l,title:Q,icon:tt}}}let nn=async(t,{reader:n=!1}={})=>{n&&await ht(t);let e=B.then(()=>Dt(t,{reader:n}));return B=e.catch(()=>{}),e};async function Pt(t){let n=await it(t);if(n.error)return{refused:n.error};let{slug:e,workspace:a}=n.body??{};return typeof e!="string"||!et.test(e)||typeof a!="string"?{refused:[400,{ok:!1,reason:"body"}]}:Gn(a,f)?{slug:e}:{refused:[409,{ok:!1,reason:"elsewhere",message:"\u8FD9\u4E2A\u9884\u89C8\u670D\u52A1\u5668\u7BA1\u7684\u662F\u53E6\u4E00\u4E2A\u76EE\u5F55\u7684\u6587\u6863"}]}}async function rn(t,n){try{let e=B.then(async()=>{let{slug:d,refused:l}=await Pt(t);if(l)return{answer:l};let S=await Dt(d);return{slug:S.ok?d:null,answer:[S.ok?200:S.reason==="missing"?404:409,S]}});B=e.catch(()=>{});let{slug:a,answer:i}=await e;return a&&await _t(a),_(n,...i)}catch(e){return _(n,500,{ok:!1,reason:"write",message:e.message})}}async function an(t){let{slug:n,refused:e}=await Pt(t);return e||(await _t(n),[200,{ok:!0}])}async function Xt(t){let{source:n}=await ht(t),{ended:e,moved:a}=await F.endDraft(t,n);return a&&y(t),e}async function on(t){let{slug:n,refused:e}=await Pt(t);return e||[200,{ok:!0,ended:await Xt(n)}]}let ct=ve({reportsDirectory:f}),kt=Te({reportsDirectory:f,read:t=>Ft(t,{wait:0}),write:E,dropped:(t,n)=>{let e=n.map(_e);u&&u(Zt(I.join(v(t),"annotations.json"),{items:e}).join(`
|
|
16
|
+
`)),c&&(D=D.then(()=>Le({stateDirectory:c,reportsDirectory:f,slug:t,time:new Date().toISOString(),items:e})).catch(()=>{}))}}),te=Promise.resolve(),Jt=t=>{let n=te.then(t);return te=n.catch(()=>{}),n},sn=t=>(n,e)=>Jt(()=>t(n)).then(([a,i])=>_(e,a,i),a=>_(e,500,{ok:!1,reason:"write",message:a.message})),cn=300,bt=new Map;async function _t(t){let n=bt.get(t);n&&(clearTimeout(n.timer),bt.delete(t));let e=Jt(()=>kt.afterWrite(t));n&&e.then(n.resolve,n.reject),await e.catch(a=>u?.(`${t}: annotations not checked: ${a.message}`)),await D}let fn=t=>{let n=t.headers.host??"",e=t.socket.localPort;return n!==`127.0.0.1:${e}`&&n!==`localhost:${e}`?[403,{ok:!1,reason:"host"}]:t.headers["x-gallery-token"]!==M?[403,{ok:!1,reason:"token"}]:null};async function ln(t){if(t.method==="GET"){let e=fn(t);if(e)return e;let a=new URL(t.url??"/","http://localhost").searchParams;return a.get("as")==="copy"?kt.copy(a.get("slug")):kt.list(a.get("slug"))}let n=await it(t);return n.error??kt.change(n.body)}let Nt=(t,n=Ht)=>async e=>{let a=await it(e,n);return a.error??t(a.body)};return{token:M,preview:He,opened:Ke,check:it,upload:gt(Nt(ct.upload,nr)),addEmoji:gt(Nt(ct.addEmoji)),unfurl:gt(Nt(ct.unfurl)),annotations:sn(ln),checkAnnotations(t){let n=bt.get(t);return n||(n={timer:0},n.done=new Promise((e,a)=>Object.assign(n,{resolve:e,reject:a})),bt.set(t,n)),clearTimeout(n.timer),n.timer=setTimeout(()=>{bt.delete(t),Jt(()=>kt.afterWrite(t)).then(n.resolve,n.reject)},cn),n.done},frameable:gt(Nt(ct.frameable)),listEmojis:ct.listEmojis,readEmoji:ct.readEmoji,respond:gt,keepVersion:K,renameReport:en,read:rt,settled:st,whenTaken:ht,readTaken:Ft,takeRewrites:b,handIn:nn,handInReport:Dt,handInRequest:rn,settleRequest:(t,n)=>an(t).then(([e,a])=>_(n,e,a),e=>_(n,500,{ok:!1,reason:"write",message:e.message})),settleNotes:_t,roundRequest:(t,n)=>on(t).then(([e,a])=>_(n,e,a),e=>_(n,500,{ok:!1,reason:"write",message:e.message})),beginRound:Xt,commit:Vt(Qe,{early:Kt}),reverted:Vt(Ve),changes:tn,noteTaken:(t,n)=>F.look(t,n),forgetChanges:t=>F.forget(t),stored:async()=>{await F.idle(),await D}}}export{Mr as a,Fr as b,Ye as c,Lr as d,ma as e};
|