@aiquants/markdown-explorer 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +121 -0
- package/LICENSE +21 -0
- package/README.md +606 -2
- package/dist/ExplorerSplit-D2plJRRe.cjs +1 -0
- package/dist/ExplorerSplit-DB37U7Kh.js +1362 -0
- package/dist/MultiLayout-DCPDu1-l.js +909 -0
- package/dist/MultiLayout-UyWxs6Xy.cjs +1 -0
- package/dist/TreeLayout-BoyFelK2.js +22 -0
- package/dist/TreeLayout-CLWbWjOc.cjs +1 -0
- package/dist/client/MarkdownExplorer.d.cts +30 -0
- package/dist/client/MarkdownExplorer.d.ts +30 -0
- package/dist/client/storage.d.cts +11 -0
- package/dist/client/storage.d.ts +11 -0
- package/dist/core/config.d.cts +77 -0
- package/dist/core/config.d.ts +77 -0
- package/dist/core/contracts.d.cts +155 -0
- package/dist/core/contracts.d.ts +155 -0
- package/dist/core/geometry.d.cts +51 -0
- package/dist/core/geometry.d.ts +51 -0
- package/dist/core/labels.d.cts +180 -0
- package/dist/core/labels.d.ts +180 -0
- package/dist/core/location.d.cts +82 -0
- package/dist/core/location.d.ts +82 -0
- package/dist/core/paths.d.cts +17 -0
- package/dist/core/paths.d.ts +17 -0
- package/dist/core/revalidation.d.cts +2 -0
- package/dist/core/revalidation.d.ts +2 -0
- package/dist/core/theme.d.cts +6 -0
- package/dist/core/theme.d.ts +6 -0
- package/dist/core/treeSettings.d.cts +48 -0
- package/dist/core/treeSettings.d.ts +48 -0
- package/dist/core/viewSettings.d.cts +15 -0
- package/dist/core/viewSettings.d.ts +15 -0
- package/dist/dataRoute-Bkfwfp1R.js +194 -0
- package/dist/dataRoute-CKbdwkQ7.cjs +1 -0
- package/dist/index-BfuAu2GV.js +2107 -0
- package/dist/index-Cx3-jSna.cjs +3 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +44 -0
- package/dist/location-Oo21lTyV.cjs +1 -0
- package/dist/location-fVl2R1ee.js +395 -0
- package/dist/sanitizeWorker.cjs +1 -0
- package/dist/sanitizeWorker.js +281 -0
- package/dist/server/anonymous.d.cts +10 -0
- package/dist/server/anonymous.d.ts +10 -0
- package/dist/server/createMarkdownExplorer.d.cts +12 -0
- package/dist/server/createMarkdownExplorer.d.ts +12 -0
- package/dist/server/errors.d.cts +26 -0
- package/dist/server/errors.d.ts +26 -0
- package/dist/server/fileSystemSource.d.cts +38 -0
- package/dist/server/fileSystemSource.d.ts +38 -0
- package/dist/server/ports.d.cts +107 -0
- package/dist/server/ports.d.ts +107 -0
- package/dist/server/sanitizeProtocol.d.cts +17 -0
- package/dist/server/sanitizeProtocol.d.ts +17 -0
- package/dist/server/sanitizer.d.cts +51 -0
- package/dist/server/sanitizer.d.ts +51 -0
- package/dist/server/workerPool.d.cts +42 -0
- package/dist/server/workerPool.d.ts +42 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +7 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +1253 -0
- package/dist/storage-Bkb2Axdi.cjs +1 -0
- package/dist/storage-DA4ItHzl.js +60 -0
- package/dist/storage.cjs +1 -0
- package/dist/storage.d.cts +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +4 -0
- package/dist/styles/markdown-explorer.css +3 -0
- package/docs/behavior/dom-hooks.md +95 -0
- package/docs/behavior/layout.md +215 -0
- package/docs/behavior/localization.md +48 -0
- package/docs/behavior/security.md +138 -0
- package/docs/behavior/url-contract.md +135 -0
- package/package.json +141 -3
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { NO_EMBEDS as Y, isEmbedProviderId as Q, EMBED_PROVIDER_IDS as ee, isLinkCardEndpoint as te } from "@aiquants/markdown/embeds";
|
|
2
|
+
import { CONTENT_ALIGNS as b, DEFAULT_MARKDOWN_STYLES as re } from "@aiquants/markdown/viewer-settings";
|
|
3
|
+
import { i as k } from "./dataRoute-Bkfwfp1R.js";
|
|
4
|
+
const F = (e) => {
|
|
5
|
+
if (e === null || typeof e != "object") return !1;
|
|
6
|
+
const t = Object.getPrototypeOf(e);
|
|
7
|
+
return t === Object.prototype || t === null;
|
|
8
|
+
}, v = new Intl.Collator("en", { numeric: !0, sensitivity: "variant" }), P = Object.freeze({
|
|
9
|
+
sortMode: "native",
|
|
10
|
+
directoriesFirst: !1,
|
|
11
|
+
selectionMode: "single",
|
|
12
|
+
doubleClickAction: "recursive",
|
|
13
|
+
expandIconSize: 8,
|
|
14
|
+
alwaysExpanded: !1,
|
|
15
|
+
removeRootIndent: !1,
|
|
16
|
+
lines: !0,
|
|
17
|
+
expandIcons: !0,
|
|
18
|
+
directoryIcons: !0,
|
|
19
|
+
fileIcons: !0
|
|
20
|
+
}), ne = [!0, !1], oe = (e, t) => t ? e.settingOn : e.settingOff, g = (e, t) => ({ key: e, labelKey: t, values: ne, formatValue: oe, requiresItemSelection: !1 }), p = Object.freeze([
|
|
21
|
+
{
|
|
22
|
+
key: "sortMode",
|
|
23
|
+
labelKey: "settingSortMode",
|
|
24
|
+
values: ["native", "asc", "desc"],
|
|
25
|
+
formatValue: (e, t) => t === "native" ? e.sortNative : t === "asc" ? e.sortAscending : e.sortDescending,
|
|
26
|
+
requiresItemSelection: !1
|
|
27
|
+
},
|
|
28
|
+
g("directoriesFirst", "settingDirectoriesFirst"),
|
|
29
|
+
{
|
|
30
|
+
key: "selectionMode",
|
|
31
|
+
labelKey: "settingSelectionMode",
|
|
32
|
+
values: ["single", "multiple", "none"],
|
|
33
|
+
formatValue: (e, t) => t === "single" ? e.selectionSingle : t === "multiple" ? e.selectionMultiple : e.selectionNone,
|
|
34
|
+
requiresItemSelection: !0
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: "doubleClickAction",
|
|
38
|
+
labelKey: "settingDoubleClick",
|
|
39
|
+
values: ["recursive", "toggle"],
|
|
40
|
+
formatValue: (e, t) => t === "recursive" ? e.doubleClickRecursive : e.doubleClickToggle,
|
|
41
|
+
requiresItemSelection: !1
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: "expandIconSize",
|
|
45
|
+
labelKey: "settingExpandIconSize",
|
|
46
|
+
values: [8, 13, 5],
|
|
47
|
+
formatValue: (e, t) => e.expandIconSizeValue(t),
|
|
48
|
+
requiresItemSelection: !1
|
|
49
|
+
},
|
|
50
|
+
g("alwaysExpanded", "settingAlwaysExpanded"),
|
|
51
|
+
g("removeRootIndent", "settingRemoveRootIndent"),
|
|
52
|
+
g("lines", "settingTreeLines"),
|
|
53
|
+
g("expandIcons", "settingExpandIcons"),
|
|
54
|
+
g("directoryIcons", "settingDirectoryIcons"),
|
|
55
|
+
g("fileIcons", "settingFileIcons")
|
|
56
|
+
]), Ge = (e) => e ? p : p.filter((t) => !t.requiresItemSelection), V = (e) => {
|
|
57
|
+
const t = p.find((r) => r.key === e);
|
|
58
|
+
if (t === void 0) throw new RangeError(`[markdown-explorer] no tree setting descriptor for ${e}`);
|
|
59
|
+
return t;
|
|
60
|
+
}, Je = (e, t) => {
|
|
61
|
+
const r = V(t).values, n = r[(r.indexOf(e[t]) + 1) % r.length];
|
|
62
|
+
return { ...e, [t]: n };
|
|
63
|
+
}, Xe = (e, t, r) => V(r).formatValue(e, t[r]), U = 2, M = Object.freeze({}), $ = (e, t) => Object.freeze(Object.fromEntries(p.filter((r) => t(r, e[r.key])).map((r) => [r.key, e[r.key]]))), We = (e) => {
|
|
64
|
+
if (e === null || typeof e != "object" || Array.isArray(e)) return M;
|
|
65
|
+
const t = e;
|
|
66
|
+
return t.version !== U || t.settings === null || typeof t.settings != "object" || Array.isArray(t.settings) ? M : $(t.settings, (r, n) => r.values.includes(n));
|
|
67
|
+
}, He = (e, t) => {
|
|
68
|
+
const r = $(t, (n, o) => o !== void 0 && o !== e[n.key]);
|
|
69
|
+
return Object.keys(r).length === 0 ? e : Object.freeze({ ...e, ...r });
|
|
70
|
+
}, qe = (e, t, r, n) => $({ ...e, [t]: r }, (o, s) => s !== void 0 && !(o.key === t && s === n[t])), Be = (e) => JSON.stringify({ version: U, settings: e }), Ke = (e) => {
|
|
71
|
+
if (e.sortMode === "native" && !e.directoriesFirst) return;
|
|
72
|
+
const t = e.sortMode === "desc" ? -1 : 1;
|
|
73
|
+
return (r, n) => {
|
|
74
|
+
if (e.directoriesFirst && r.type !== n.type) return r.type === "directory" ? -1 : 1;
|
|
75
|
+
if (e.sortMode === "native") return 0;
|
|
76
|
+
const o = v.compare(r.name, n.name);
|
|
77
|
+
return t * (o !== 0 ? o : v.compare(r.path, n.path));
|
|
78
|
+
};
|
|
79
|
+
}, w = (1 + Math.sqrt(5)) / 2, Ze = 100 / w ** 3, Ye = 100 / w ** 4, G = 100 / w ** 2, se = 13, Qe = 16, et = Object.freeze({ gripThickness: 5, gripLength: 34, barThickness: 2, barLength: 21 }), ie = Object.freeze([89, 144, 233, 377]), tt = 34, rt = 44, nt = 24, ot = 1 / w, st = 1 / w ** 3, it = "40ch", ae = (e) => {
|
|
80
|
+
if (!Number.isFinite(e) || e <= 0)
|
|
81
|
+
throw new RangeError(`[markdown-explorer] rootFontPixels must be a finite number > 0; got ${String(e)}`);
|
|
82
|
+
}, ce = (e) => (ae(e), se * e), at = (e) => ce(e) * w ** 2, ct = 233, lt = ie[0], L = (e, t) => {
|
|
83
|
+
if (!Number.isFinite(t) || t < 0)
|
|
84
|
+
throw new RangeError(`[markdown-explorer] ${e} must be a finite number >= 0; got ${String(t)}`);
|
|
85
|
+
}, le = ({ trackInlineSize: e, gap: t, minColumnInlineSize: r, logicalColumns: n }) => {
|
|
86
|
+
if (L("trackInlineSize", e), L("gap", t), !Number.isFinite(r) || r <= 0)
|
|
87
|
+
throw new RangeError(`[markdown-explorer] minColumnInlineSize must be a finite number > 0; got ${String(r)}`);
|
|
88
|
+
if (!Number.isInteger(n) || n < 1)
|
|
89
|
+
throw new RangeError(`[markdown-explorer] logicalColumns must be a positive integer; got ${String(n)}`);
|
|
90
|
+
const o = Math.floor((e + t) / (r + t));
|
|
91
|
+
return Math.min(n, Math.max(1, o));
|
|
92
|
+
}, dt = (e, t) => {
|
|
93
|
+
const { trackInlineSize: r, gap: n, minColumnInlineSize: o, logicalColumns: s } = t;
|
|
94
|
+
if (!([r, n, o].every(Number.isFinite) && r > 0 && n >= 0 && o > 0)) return e;
|
|
95
|
+
const i = le(t);
|
|
96
|
+
if (e === null || i === e) return i;
|
|
97
|
+
const l = Math.min(s, Math.max(1, e));
|
|
98
|
+
if (i > l) {
|
|
99
|
+
const _ = (l + 1) * o + l * n + n / w;
|
|
100
|
+
return r >= _ ? i : l;
|
|
101
|
+
}
|
|
102
|
+
return r >= l * o + (l - 1) * n ? l : i;
|
|
103
|
+
}, mt = (e, t) => {
|
|
104
|
+
if (!(Number.isInteger(e) && Number.isInteger(t)) || t < 1 || t > e)
|
|
105
|
+
throw new RangeError(`[markdown-explorer] visible columns must be an integer in 1..${String(e)}; got ${String(t)}`);
|
|
106
|
+
return Array.from({ length: t }, (r, n) => [Math.floor(n * e / t), Math.floor((n + 1) * e / t)]);
|
|
107
|
+
}, de = 31536e3, me = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/u, fe = (e) => {
|
|
108
|
+
if (typeof e != "string" || !me.test(e))
|
|
109
|
+
throw new RangeError(`[markdown-explorer] settingsCookie must be a cookie-name token; got ${JSON.stringify(e)}`);
|
|
110
|
+
}, z = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 && e <= G, ue = (e, t) => {
|
|
111
|
+
if (e === null || typeof e != "object" || Array.isArray(e)) return {};
|
|
112
|
+
const r = e, { treeExplorer: n, multiExplorer: o, style: s, align: a } = r;
|
|
113
|
+
return {
|
|
114
|
+
...z(n) ? { treeExplorer: n } : {},
|
|
115
|
+
...z(o) ? { multiExplorer: o } : {},
|
|
116
|
+
...typeof s == "string" && t.includes(s) ? { style: s } : {},
|
|
117
|
+
...typeof a == "string" && b.includes(a) ? { align: a } : {}
|
|
118
|
+
};
|
|
119
|
+
}, ft = (e, t) => {
|
|
120
|
+
if (e !== null)
|
|
121
|
+
for (const r of e.split(";")) {
|
|
122
|
+
const n = r.indexOf("=");
|
|
123
|
+
if (!(n < 0) && r.slice(0, n).trim() === t)
|
|
124
|
+
return r.slice(n + 1).trim();
|
|
125
|
+
}
|
|
126
|
+
}, ut = (e, t) => {
|
|
127
|
+
if (e === void 0 || e === "") return {};
|
|
128
|
+
try {
|
|
129
|
+
return ue(JSON.parse(decodeURIComponent(e)), t);
|
|
130
|
+
} catch {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
}, O = 100, ge = Math.floor(G * O) / O, we = (e) => {
|
|
134
|
+
const t = (r) => Math.min(ge, Math.max(1, Math.round(r * O)) / O);
|
|
135
|
+
return encodeURIComponent(
|
|
136
|
+
JSON.stringify({
|
|
137
|
+
...e.treeExplorer === void 0 ? {} : { treeExplorer: t(e.treeExplorer) },
|
|
138
|
+
...e.multiExplorer === void 0 ? {} : { multiExplorer: t(e.multiExplorer) },
|
|
139
|
+
...e.style === void 0 ? {} : { style: e.style },
|
|
140
|
+
...e.align === void 0 ? {} : { align: e.align }
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
}, gt = (e, t, r) => `${e}=${we(t)}; Path=/; Max-Age=${String(de)}; SameSite=Lax${r ? "; Secure" : ""}`, j = Object.freeze({ tree: "tree", multi: "multi", single: "single" }), pe = Object.freeze({ default: 12, min: 1, max: 64 }), he = Object.freeze({ default: 4, min: 1, max: 6 }), Ee = Object.freeze({ default: 500, min: 1, max: 1e4 }), Se = Object.freeze({ default: 16, min: 1, max: 64 }), ye = /^\/(?:[A-Za-z0-9._~-]+\/)*[A-Za-z0-9._~-]+$/u, xe = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u, be = /^[a-z0-9][a-z0-9-]*$/u, Oe = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/u, D = (e, t) => {
|
|
144
|
+
if (typeof t != "string") throw new TypeError(`[markdown-explorer] ${e} must be a string; got ${typeof t}`);
|
|
145
|
+
if (!ye.test(t) || t.split("/").some((r) => r === "." || r === ".."))
|
|
146
|
+
throw new RangeError(`[markdown-explorer] ${e} must start with "/", have no trailing "/", and use only letters, digits and "._~-" in each segment; got ${JSON.stringify(t)}`);
|
|
147
|
+
}, d = (e) => typeof e == "string" ? JSON.stringify(e) : typeof e == "bigint" ? `${String(e)}n` : Object.is(e, -0) ? "-0" : typeof e == "function" ? "a function" : Array.isArray(e) ? "an array" : e !== null && typeof e == "object" ? F(e) ? "a plain object" : `a non-plain object (${Object.prototype.toString.call(e)})` : String(e), S = (e, t, r) => {
|
|
148
|
+
if (t === void 0) return [];
|
|
149
|
+
if (!F(t)) throw new TypeError(`[markdown-explorer] ${e} must be a plain object; got ${d(t)}`);
|
|
150
|
+
const n = Object.entries(t);
|
|
151
|
+
for (const [o] of n)
|
|
152
|
+
if (!r.includes(o)) throw new RangeError(`[markdown-explorer] ${e}.${o} is not an option; expected ${r.join(", ")}`);
|
|
153
|
+
return n.filter(([, o]) => o !== void 0);
|
|
154
|
+
}, _e = (e) => {
|
|
155
|
+
const t = { ...j };
|
|
156
|
+
for (const [r, n] of S("views", e, Object.keys(j))) t[r] = n;
|
|
157
|
+
for (const [r, n] of Object.entries(t))
|
|
158
|
+
if (typeof n != "string" || !xe.test(n))
|
|
159
|
+
throw new RangeError(`[markdown-explorer] views.${r} must start with a letter or digit and use only letters, digits, "_" and "-"; got ${JSON.stringify(n)}`);
|
|
160
|
+
return Object.freeze(t);
|
|
161
|
+
}, x = (e, t, r) => {
|
|
162
|
+
if (t === void 0) return r.default;
|
|
163
|
+
if (typeof t != "number" || !Number.isInteger(t) || t < r.min || t > r.max)
|
|
164
|
+
throw new RangeError(`[markdown-explorer] ${e} must be an integer in ${String(r.min)}..${String(r.max)}; got ${d(t)}`);
|
|
165
|
+
return t;
|
|
166
|
+
}, Re = (e) => {
|
|
167
|
+
const t = new Map(S("embeds", e, ["providers", "linkCardEndpoint"]));
|
|
168
|
+
if (t.size === 0) return Y;
|
|
169
|
+
const r = t.has("providers") ? t.get("providers") : [];
|
|
170
|
+
if (!Array.isArray(r)) throw new RangeError(`[markdown-explorer] embeds.providers must be an array of provider ids; got ${d(r)}`);
|
|
171
|
+
for (const o of r)
|
|
172
|
+
if (!Q(o)) throw new RangeError(`[markdown-explorer] embeds.providers must hold only ${ee.join(", ")}; got ${d(o)}`);
|
|
173
|
+
const n = t.has("linkCardEndpoint") ? t.get("linkCardEndpoint") : null;
|
|
174
|
+
if (n !== null && !te(n))
|
|
175
|
+
throw new RangeError(`[markdown-explorer] embeds.linkCardEndpoint must start with "/", have no trailing "/", and use only letters, digits and "._~-" in each segment; got ${d(n)}`);
|
|
176
|
+
return Object.freeze({ providers: Object.freeze([...new Set(r)]), linkCardEndpoint: n });
|
|
177
|
+
}, Te = (e) => {
|
|
178
|
+
const t = new Map(
|
|
179
|
+
S(
|
|
180
|
+
"defaultTreeSettings",
|
|
181
|
+
e,
|
|
182
|
+
p.map((n) => n.key)
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
if (t.size === 0) return P;
|
|
186
|
+
const r = { ...P };
|
|
187
|
+
for (const n of p) {
|
|
188
|
+
if (!t.has(n.key)) continue;
|
|
189
|
+
const o = t.get(n.key), s = n.values;
|
|
190
|
+
if (!s.includes(o)) throw new RangeError(`[markdown-explorer] defaultTreeSettings.${n.key} must be one of ${s.map(d).join(", ")}; got ${d(o)}`);
|
|
191
|
+
r[n.key] = o;
|
|
192
|
+
}
|
|
193
|
+
return Object.freeze(r);
|
|
194
|
+
}, wt = (e) => {
|
|
195
|
+
if (e === null || typeof e != "object") throw new TypeError("[markdown-explorer] the explorer configuration must be an object");
|
|
196
|
+
D("basePath", e.basePath), D("dataPath", e.dataPath);
|
|
197
|
+
const t = _e(e.views);
|
|
198
|
+
if ((/* @__PURE__ */ new Set([t.tree, t.multi, t.single])).size !== 3)
|
|
199
|
+
throw new RangeError(`[markdown-explorer] the view slugs must differ; got ${JSON.stringify(t)}`);
|
|
200
|
+
if (e.dataPath === e.basePath) throw new RangeError("[markdown-explorer] dataPath must differ from basePath");
|
|
201
|
+
if (e.dataPath.startsWith(`${e.basePath}/`)) {
|
|
202
|
+
const i = e.dataPath.slice(e.basePath.length + 1).split("/")[0];
|
|
203
|
+
if (i === t.tree || i === t.multi || i === t.single)
|
|
204
|
+
throw new RangeError(`[markdown-explorer] dataPath must not start with a view slug under basePath; got ${JSON.stringify(e.dataPath)}`);
|
|
205
|
+
}
|
|
206
|
+
fe(e.settingsCookie);
|
|
207
|
+
const r = e.iframeHosts ?? [];
|
|
208
|
+
if (!Array.isArray(r) || r.some((i) => typeof i != "string" || !Oe.test(i)))
|
|
209
|
+
throw new RangeError(`[markdown-explorer] iframeHosts must be lowercase host names without scheme, port or path; got ${JSON.stringify(r)}`);
|
|
210
|
+
const n = Object.fromEntries(S("multiView", e.multiView, ["maxPanels", "columns"])), o = Object.fromEntries(S("expandAll", e.expandAll, ["maxFolders", "maxDepth"])), s = e.documentStyles ?? re;
|
|
211
|
+
if (!Array.isArray(s) || s.length === 0) throw new RangeError("[markdown-explorer] documentStyles must be a non-empty array");
|
|
212
|
+
const a = /* @__PURE__ */ new Set();
|
|
213
|
+
for (const i of s) {
|
|
214
|
+
if (i === null || typeof i != "object" || typeof i.name != "string" || i.name.trim() === "" || typeof i.className != "string")
|
|
215
|
+
throw new RangeError("[markdown-explorer] each document style needs a non-blank name and a className string");
|
|
216
|
+
if (a.has(i.name)) throw new RangeError(`[markdown-explorer] document style names must be unique; ${JSON.stringify(i.name)} repeats`);
|
|
217
|
+
a.add(i.name);
|
|
218
|
+
}
|
|
219
|
+
return Object.freeze({
|
|
220
|
+
basePath: e.basePath,
|
|
221
|
+
dataPath: e.dataPath,
|
|
222
|
+
settingsCookie: e.settingsCookie,
|
|
223
|
+
views: t,
|
|
224
|
+
multiView: Object.freeze({
|
|
225
|
+
maxPanels: x("multiView.maxPanels", n.maxPanels, pe),
|
|
226
|
+
columns: x("multiView.columns", n.columns, he)
|
|
227
|
+
}),
|
|
228
|
+
expandAll: Object.freeze({
|
|
229
|
+
maxFolders: x("expandAll.maxFolders", o.maxFolders, Ee),
|
|
230
|
+
maxDepth: x("expandAll.maxDepth", o.maxDepth, Se)
|
|
231
|
+
}),
|
|
232
|
+
documentStyles: Object.freeze(s.map((i) => Object.freeze({ name: i.name, className: i.className }))),
|
|
233
|
+
iframeHosts: Object.freeze([...new Set(r)]),
|
|
234
|
+
embeds: Re(e.embeds),
|
|
235
|
+
defaultTreeSettings: Te(e.defaultTreeSettings)
|
|
236
|
+
});
|
|
237
|
+
}, Ne = (e) => typeof e == "string" && be.test(e), pt = (e, t) => {
|
|
238
|
+
if (e === null || typeof e != "object") throw new TypeError(`[markdown-explorer] withExplorerSources needs the configuration of defineExplorerConfig; got ${d(e)}`);
|
|
239
|
+
if (!Array.isArray(t) || t.length === 0) throw new RangeError(`[markdown-explorer] sourceIds must be a non-empty array; got ${d(t)}`);
|
|
240
|
+
for (const r of t)
|
|
241
|
+
if (!Ne(r)) throw new RangeError(`[markdown-explorer] each source id must use lowercase letters, digits and "-" and start with a letter or digit; got ${d(r)}`);
|
|
242
|
+
if (new Set(t).size !== t.length) throw new RangeError(`[markdown-explorer] source ids must be unique; got ${JSON.stringify(t)}`);
|
|
243
|
+
return Object.freeze({ ...e, sourceIds: Object.freeze([...t]) });
|
|
244
|
+
}, ht = (e) => e.documentStyles.map((t) => t.name), c = Object.freeze({
|
|
245
|
+
source: "source",
|
|
246
|
+
doc: "doc",
|
|
247
|
+
maximized: "maximized",
|
|
248
|
+
style: "style",
|
|
249
|
+
align: "align",
|
|
250
|
+
showToc: "showToc",
|
|
251
|
+
showStyle: "showStyle",
|
|
252
|
+
showAlign: "showAlign",
|
|
253
|
+
padding: "padding",
|
|
254
|
+
width: "width",
|
|
255
|
+
maxWidth: "maxWidth"
|
|
256
|
+
}), C = ".data", J = 256, X = /^\d+(?:\.\d+)?$/u, I = /^\d+(?:\.\d+)?(?:px|rem|em|ch|vw|%)$/u, W = Object.freeze(["showToc", "showStyle", "showAlign"]), Ae = (e) => {
|
|
257
|
+
const t = encodeURIComponent(e.replaceAll("%", "%25"));
|
|
258
|
+
return t.endsWith(C) ? `${t.slice(0, -C.length)}%2Edata` : t;
|
|
259
|
+
}, Ie = (e) => e.replaceAll("%25", "%"), H = (e) => {
|
|
260
|
+
const { sourceIds: t } = e;
|
|
261
|
+
if (t === void 0) throw new TypeError("[markdown-explorer] the configuration has no source ids; join the server's sources with withExplorerSources(config, sourceIds)");
|
|
262
|
+
return t;
|
|
263
|
+
}, ke = (e, t, r) => {
|
|
264
|
+
const n = r.getAll(c.source);
|
|
265
|
+
if (n.length === 0) return t;
|
|
266
|
+
const [o] = n;
|
|
267
|
+
return n.length > 1 || o === void 0 || o === t || !e.includes(o) ? null : o;
|
|
268
|
+
}, $e = (e, t) => {
|
|
269
|
+
const r = t.get(c.style), n = t.get(c.align);
|
|
270
|
+
return {
|
|
271
|
+
...r !== null && e.documentStyles.some((o) => o.name === r) ? { style: r } : {},
|
|
272
|
+
...n !== null && b.includes(n) ? { align: n } : {}
|
|
273
|
+
};
|
|
274
|
+
}, q = (e) => Number.isFinite(e) && e >= 0 && e <= J && X.test(String(e)), ve = (e) => {
|
|
275
|
+
const t = e.get(c.padding), r = t !== null && X.test(t) ? Number(t) : Number.NaN, n = e.get(c.width), o = e.get(c.maxWidth);
|
|
276
|
+
return {
|
|
277
|
+
...e.get(c.showToc) === "false" ? { showToc: !1 } : {},
|
|
278
|
+
...e.get(c.showStyle) === "false" ? { showStyle: !1 } : {},
|
|
279
|
+
...e.get(c.showAlign) === "false" ? { showAlign: !1 } : {},
|
|
280
|
+
...q(r) ? { padding: r } : {},
|
|
281
|
+
...n !== null && I.test(n) ? { width: n } : {},
|
|
282
|
+
...o !== null && I.test(o) ? { maxWidth: o } : {}
|
|
283
|
+
};
|
|
284
|
+
}, Pe = (e, t) => [...new Set(t.filter(k))].slice(0, e.multiView.maxPanels), Me = (e, t, r) => {
|
|
285
|
+
for (const n of t) B(n);
|
|
286
|
+
if (new Set(t).size !== t.length) throw new RangeError(`[markdown-explorer] multi-view documents must each appear once; got ${String(t.length)} with repeats`);
|
|
287
|
+
if (t.length > e.multiView.maxPanels) throw new RangeError(`[markdown-explorer] the multi view opens at most ${String(e.multiView.maxPanels)} documents; got ${String(t.length)}`);
|
|
288
|
+
if (r !== null && !t.includes(r)) throw new RangeError(`[markdown-explorer] the maximized document must be one of the open documents; got ${JSON.stringify(r.slice(0, 80))}`);
|
|
289
|
+
}, B = (e) => {
|
|
290
|
+
if (!k(e)) throw new RangeError(`[markdown-explorer] not an acceptable document path: ${JSON.stringify(String(e).slice(0, 80))}`);
|
|
291
|
+
return e;
|
|
292
|
+
}, Le = (e, t) => {
|
|
293
|
+
if (t.style !== void 0 && !e.documentStyles.some((r) => r.name === t.style))
|
|
294
|
+
throw new RangeError(`[markdown-explorer] overrides.style must name a configured document style (${e.documentStyles.map((r) => JSON.stringify(r.name)).join(", ")}); got ${JSON.stringify(t.style)}`);
|
|
295
|
+
if (t.align !== void 0 && !b.includes(t.align))
|
|
296
|
+
throw new RangeError(`[markdown-explorer] overrides.align must be one of ${b.join(", ")}; got ${JSON.stringify(t.align)}`);
|
|
297
|
+
}, ze = (e) => {
|
|
298
|
+
for (const t of W)
|
|
299
|
+
if (e[t] !== void 0 && typeof e[t] != "boolean") throw new RangeError(`[markdown-explorer] embed.${t} must be a boolean; got ${JSON.stringify(e[t])}`);
|
|
300
|
+
if (e.padding !== void 0 && !q(e.padding)) throw new RangeError(`[markdown-explorer] embed.padding must be 0..${String(J)} px in plain decimal digits; got ${String(e.padding)}`);
|
|
301
|
+
for (const t of ["width", "maxWidth"]) {
|
|
302
|
+
const r = e[t];
|
|
303
|
+
if (r !== void 0 && !I.test(r)) throw new RangeError(`[markdown-explorer] embed.${t} must be a CSS length in px, rem, em, ch, vw or %; got ${JSON.stringify(r)}`);
|
|
304
|
+
}
|
|
305
|
+
}, je = (e, t) => {
|
|
306
|
+
const r = new URLSearchParams();
|
|
307
|
+
let n = `${e.basePath}/${e.views[t.view]}`;
|
|
308
|
+
if (t.view === "multi") {
|
|
309
|
+
const s = t.docs ?? [], a = t.maximized ?? null;
|
|
310
|
+
Me(e, s, a);
|
|
311
|
+
for (const i of s) r.append(c.doc, i);
|
|
312
|
+
a !== null && r.set(c.maximized, a);
|
|
313
|
+
} else t.doc !== void 0 && t.doc !== null && (n += `/${Ae(B(t.doc))}`);
|
|
314
|
+
if (t.source !== void 0) {
|
|
315
|
+
const s = H(e);
|
|
316
|
+
if (!s.includes(t.source)) throw new RangeError(`[markdown-explorer] unknown source ${JSON.stringify(t.source)}; expected one of ${s.join(", ")}`);
|
|
317
|
+
t.source !== s[0] && r.set(c.source, t.source);
|
|
318
|
+
}
|
|
319
|
+
if (t.view !== "multi" && t.overrides !== void 0 && (Le(e, t.overrides), t.overrides.style !== void 0 && r.set(c.style, t.overrides.style), t.overrides.align !== void 0 && r.set(c.align, t.overrides.align)), t.view === "single" && t.embed !== void 0) {
|
|
320
|
+
const { embed: s } = t;
|
|
321
|
+
ze(s);
|
|
322
|
+
for (const a of W) s[a] === !1 && r.set(c[a], "false");
|
|
323
|
+
s.padding !== void 0 && r.set(c.padding, String(s.padding)), s.width !== void 0 && r.set(c.width, s.width), s.maxWidth !== void 0 && r.set(c.maxWidth, s.maxWidth);
|
|
324
|
+
}
|
|
325
|
+
const o = r.toString();
|
|
326
|
+
return o === "" ? n : `${n}?${o}`;
|
|
327
|
+
}, De = (e, t) => Object.keys(e.views).find((r) => e.views[r] === t), Et = (e, t, r) => {
|
|
328
|
+
const n = H(e), [o] = n;
|
|
329
|
+
if (o === void 0) throw new RangeError("[markdown-explorer] the configuration has no source");
|
|
330
|
+
const s = ke(n, o, r), a = s === null ? o : s, i = (m) => ({ kind: "redirect", href: je(e, m), location: m }), l = () => i({ view: "tree", source: a, doc: null, overrides: {} });
|
|
331
|
+
if (t === void 0 || t === "") return l();
|
|
332
|
+
const h = t.indexOf("/"), _ = h < 0 ? t : t.slice(0, h), R = h < 0 ? null : t.slice(h + 1), f = De(e, _);
|
|
333
|
+
if (f === void 0) return l();
|
|
334
|
+
if (f === "multi") {
|
|
335
|
+
const m = r.getAll(c.doc), E = Pe(e, m), T = r.getAll(c.maximized), [N] = T, A = T.length === 1 && N !== void 0 && E.includes(N) ? N : null;
|
|
336
|
+
return R === null && s !== null && E.length === m.length && E.every((K, Z) => K === m[Z]) && (T.length === 0 || A !== null) ? { kind: "location", location: { view: "multi", source: a, docs: E, maximized: A } } : i({ view: "multi", source: a, docs: E, maximized: A });
|
|
337
|
+
}
|
|
338
|
+
const u = R === null ? null : Ie(R);
|
|
339
|
+
if (u !== null && !k(u)) return l();
|
|
340
|
+
const y = $e(e, r);
|
|
341
|
+
if (f === "single") {
|
|
342
|
+
if (u === null) return l();
|
|
343
|
+
const m = ve(r);
|
|
344
|
+
return s === null ? i({ view: f, source: a, doc: u, overrides: y, embed: m }) : { kind: "location", location: { view: f, source: a, doc: u, overrides: y, embed: m } };
|
|
345
|
+
}
|
|
346
|
+
return s === null ? i({ view: f, source: a, doc: u, overrides: y }) : { kind: "location", location: { view: f, source: a, doc: u, overrides: y } };
|
|
347
|
+
};
|
|
348
|
+
export {
|
|
349
|
+
Qe as A,
|
|
350
|
+
Be as B,
|
|
351
|
+
tt as C,
|
|
352
|
+
M as D,
|
|
353
|
+
ct as E,
|
|
354
|
+
nt as F,
|
|
355
|
+
w as G,
|
|
356
|
+
We as H,
|
|
357
|
+
gt as I,
|
|
358
|
+
it as J,
|
|
359
|
+
P as K,
|
|
360
|
+
j as L,
|
|
361
|
+
Se as M,
|
|
362
|
+
v as N,
|
|
363
|
+
Ee as O,
|
|
364
|
+
ot as P,
|
|
365
|
+
se as Q,
|
|
366
|
+
he as R,
|
|
367
|
+
et as S,
|
|
368
|
+
pe as T,
|
|
369
|
+
wt as a,
|
|
370
|
+
ft as b,
|
|
371
|
+
Pe as c,
|
|
372
|
+
ht as d,
|
|
373
|
+
je as e,
|
|
374
|
+
F as f,
|
|
375
|
+
mt as g,
|
|
376
|
+
dt as h,
|
|
377
|
+
Ne as i,
|
|
378
|
+
st as j,
|
|
379
|
+
Ke as k,
|
|
380
|
+
Xe as l,
|
|
381
|
+
at as m,
|
|
382
|
+
ce as n,
|
|
383
|
+
G as o,
|
|
384
|
+
ut as p,
|
|
385
|
+
Ze as q,
|
|
386
|
+
Et as r,
|
|
387
|
+
Ye as s,
|
|
388
|
+
rt as t,
|
|
389
|
+
lt as u,
|
|
390
|
+
Ge as v,
|
|
391
|
+
pt as w,
|
|
392
|
+
qe as x,
|
|
393
|
+
Je as y,
|
|
394
|
+
He as z
|
|
395
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const te=require("node:worker_threads"),_=require("parse5"),R=require("@aiquants/markdown/embeds"),S=require("isomorphic-dompurify"),F=require("./dataRoute-CKbdwkQ7.cjs"),G=512,re=4096,j=1024,V=Symbol("placement"),$=2,ne=3,se=new Set(["html","head","body"]),b=0,M=1,U=2,W=3,z=4,O=5,k=6,N=7,Q=8,y=9,X=10,w=-1,oe=0,ae=1,ie=2,le=3,ce=4,ue=5,J=6,fe=7,de=t=>{switch(t){case 9:case 10:case 12:case 13:case 32:return oe;case 47:return ae;case 62:return ie;case 61:return le;case 34:return ce;case 39:return ue;default:return J}},Ee=Uint8Array.from({length:128},(t,i)=>de(i)),B=60,q=47,pe=/[\t\n\f\r />="'<]/g,Te=/["<]/g,Ae=/['<]/g,m=-1-U,he=Int8Array.from([[M,y,w,b,b,b,b],[M,y,w,m,m,m,m],[W,y,w,z,U,U,U],[W,y,w,z,m,m,m],[z,N,w,N,O,k,N],[O,O,O,O,Q,O,O],[k,k,k,k,k,Q,k],[M,N,w,N,N,N,N],[M,y,w,m,m,m,m],[M,y,w,m,m,m,m]].flat()),K=t=>t>=65&&t<=90||t>=97&&t<=122,me=(t,i)=>{let u=new Int32Array(X),f=new Int32Array(X),l=0,A=0,n=0;for(;n<t.length;){if(l===0){const E=t.indexOf("<",n);if(E<0)return!1;n=E+1,t.charCodeAt(n)===q&&(n+=1),K(t.charCodeAt(n))&&(u[b]=0,l=1<<b,n+=1);continue}if((l&-230)===0&&n>=A){const E=l===1<<O?Te:l===1<<k?Ae:pe;E.lastIndex=n;const a=E.exec(t);if(a===null)return!1;n=a.index,t.charCodeAt(n)===B&&(A=n+3)}const T=t.charCodeAt(n),g=T<128?Ee[T]:J;let h=0;for(let E=l;E!==0;E&=E-1){const a=31-Math.clz32(E&-E);let r=he[a*fe+g],s=u[a];if(r<w&&(r=-1-r,s+=1,s>i))return!0;if(r===w)continue;const p=1<<r;((h&p)===0||s>f[r])&&(f[r]=s),h|=p}K(T)&&(t.charCodeAt(n-1)===B||t.charCodeAt(n-1)===q&&t.charCodeAt(n-2)===B)&&(h&1<<b)===0&&(f[b]=0,h|=1<<b);const C=u;u=f,f=C,l=h,n+=1}return!1};class L extends Error{status;constructor(i){super(`[markdown-explorer] the nesting guard stopped the parse: ${i}`),this.name="ParseStop",this.status=i}}const ge=(t,i,u,f)=>{if(!Number.isSafeInteger(i)||i<=0)throw new RangeError(`[markdown-explorer] the nesting guard's depth limit must be a positive safe integer; got ${String(i)}`);if(!Number.isSafeInteger(u)||u<=0)throw new RangeError(`[markdown-explorer] the nesting guard's node budget must be a positive safe integer; got ${String(u)}`);if(!Number.isSafeInteger(f)||f<=0)throw new RangeError(`[markdown-explorer] the nesting guard's attribute character budget must be a positive safe integer; got ${String(f)}`);if(me(t,j))return{status:"too-many-attributes"};const l=i+$,A=t.length+ne;let n=null,T=0,g=0,h=0,C=0;const E=e=>{if(g+=e,g>u)throw new L("too-many-nodes")},a=e=>{for(const o of e)C+=o.name.length+o.value.length;if(C>f)throw new L("too-many-attribute-characters")},r=(e,o,c,d)=>{const P={node:e,above:null,levels:o,height:0,keepsChildren:c,attributes:d,first:null,next:null,previous:null},ee=e;return ee[V]=P,P},s=e=>{const c=e[V];if(c===void 0)throw new Error("[markdown-explorer] the nesting guard was handed a node it did not create");return c},p=(e,o)=>{let c=o;for(let d=e;d!==null&&c>d.height;d=d.above)d.height=c,c+=d.levels;if(n!==null&&n.height>l)throw new L("too-deep")},D=e=>{const o=e.above;o?.keepsChildren&&(e.previous===null?o.first=e.next:e.previous.next=e.next,e.next!==null&&(e.next.previous=e.previous)),e.above=null,e.next=null,e.previous=null},I=(e,o)=>{if(!_.defaultTreeAdapter.isElementNode(o))return;const c=s(o),d=s(e);D(c),c.above=d,d.keepsChildren&&(c.next=d.first,d.first!==null&&(d.first.previous=c),d.first=c),o.parentNode=e,p(d,c.height+c.levels)},H={..._.defaultTreeAdapter,createDocument:()=>{const e=_.defaultTreeAdapter.createDocument();return n=r(e,0,!1,0),e},createDocumentFragment:()=>{const e=_.defaultTreeAdapter.createDocumentFragment();return r(e,0,!1,0),e},createElement:(e,o,c)=>{if(T+=1,T>A)throw new L("too-many-elements");E(1+c.length),a(c);const d=_.defaultTreeAdapter.createElement(e,o,c);return r(d,1,!(o===_.html.NS.HTML&&se.has(e)),c.length),d},createCommentNode:e=>{if(h+=1,h>re)throw new L("too-many-comments");return E(1),_.defaultTreeAdapter.createCommentNode(e)},setTemplateContent:(e,o)=>{_.defaultTreeAdapter.setTemplateContent(e,o);const c=s(o);c.above=s(e),p(c.above,c.height)},appendChild:I,insertBefore:(e,o)=>I(e,o),detachNode:e=>{_.defaultTreeAdapter.isElementNode(e)&&(D(s(e)),e.parentNode=null)},getFirstChild:e=>{const o=s(e);if(!o.keepsChildren)throw new Error("[markdown-explorer] the nesting guard was asked for the children of a node whose children it does not keep");return o.first===null?null:o.first.node},getChildNodes:()=>{throw new Error("[markdown-explorer] the nesting guard keeps no child lists for source locations")},onItemPop:e=>{const o=s(e);o.keepsChildren=!1,o.first=null},insertText:()=>{},insertTextBefore:()=>{},adoptAttributes:(e,o)=>{E(o.length),a(o);const c=s(e);if(c.attributes+=o.length,c.attributes>j)throw new L("too-many-attributes")}};let v;try{v=_.parse(t,{scriptingEnabled:!1,treeAdapter:H})}catch(e){if(e instanceof L)return{status:e.status};throw e}return{status:"within",depth:s(v).height-$,elements:T,nodes:g}};class Y extends RangeError{constructor(i){super(`[markdown-explorer] the HTML nests deeper than ${String(i)} levels`),this.name="HtmlNestingLimitError"}}const _e=["script","style","noscript","template","form","button","textarea","select","option","object","embed","base","meta","link","frame","frameset"],Se=["srcdoc","formaction"],we=/^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/iu,be=new Set(["left","right","center","justify","start","end"]),Ne=new Set(["h1","h2","h3","h4","h5","h6"]),x=1,Oe=3,ke=7,Re=8,Z=Object.freeze({a:Object.freeze(["target","data-link-kind","data-doc-path","data-doc-exists","data-footnote-ref","data-footnote-backref"]),area:Object.freeze(["target"]),img:Object.freeze(["data-asset-src","data-asset-exists"]),section:Object.freeze(["data-footnotes"]),iframe:Object.freeze(["allow","allowfullscreen","frameborder","referrerpolicy"])}),Le=[...new Set(Object.values(Z).flatMap(t=>t.filter(i=>i.startsWith("data-"))))],Ce=new Set(["src","href","xlink:href"]),Ie=/^data:/iu,ye=Object.freeze({FORBID_TAGS:_e,FORBID_ATTR:Se,ADD_TAGS:["iframe"],ADD_ATTR:(t,i)=>Z[i]?.includes(t)===!0,ADD_URI_SAFE_ATTR:Le,ALLOWED_URI_REGEXP:we,ALLOW_DATA_ATTR:!1}),De=t=>{let i=null;for(const u of t.split(";")){const f=u.indexOf(":");if(f<0||u.slice(0,f).trim().toLowerCase()!=="text-align")continue;const l=u.slice(f+1).trim().toLowerCase();be.has(l)&&(i=l)}return i===null?null:`text-align: ${i}`},Me=t=>t.nodeType===Oe?{kind:"text",text:t.nodeValue??""}:t.nodeType===Re||t.nodeType===ke?{kind:"ignored"}:t.nodeType===x&&t.nodeName.toLowerCase()==="a"?{kind:"link",href:t.getAttribute("href")}:{kind:"element"},Ue=t=>{const i=t.getAttribute("type");return i!==null&&i.trim().toLowerCase()==="checkbox"&&t.hasAttribute("disabled")},xe=(t,i,u)=>{if(S.isSupported!==!0)throw new Error("[markdown-explorer] the HTML sanitizer cannot run in this environment");if(!Number.isSafeInteger(u)||u<=0)throw new RangeError(`[markdown-explorer] the HTML sanitizer's depth limit must be a positive integer; got ${String(u)}`);const f=Object.freeze([...t]);let l=new WeakMap,A=new WeakMap;const n=a=>{const r=a.parentNode===null?void 0:l.get(a.parentNode),s=r===void 0?0:r+1;if(l.set(a,s),a.nodeType===x&&s>u)throw new Y(u)},T=(a,r)=>{if(a.nodeType!==x)return;const s=a;(r.tagName==="input"&&!Ue(s)||r.tagName==="iframe"&&R.allowedFrameUrlOf(s.getAttribute("src")?.trim(),f)===null)&&s.parentNode?.removeChild(s)},g=(a,r)=>{const s=a.nodeName.toLowerCase();if(r.attrName==="style"){const p=De(r.attrValue);p===null?r.keepAttr=!1:r.attrValue=p}else if(r.attrName==="allow"&&s==="iframe"){const p=R.reduceFrameFeatures(r.attrValue);p===null?r.keepAttr=!1:r.attrValue=p}else if(r.attrName==="referrerpolicy"&&s==="iframe"){const p=r.attrValue.trim().toLowerCase();R.EMBED_FRAME_REFERRER_POLICIES.has(p)?r.attrValue=p:r.keepAttr=!1}else r.attrName===R.EMBED_LINK_ATTRIBUTE&&s==="p"?A.set(a,a.getAttribute(R.EMBED_LINK_ATTRIBUTE)):Ce.has(r.attrName)&&Ie.test(r.attrValue)?r.keepAttr=!1:r.attrName==="id"&&Ne.has(s)&&(r.forceKeepAttr=!0)},h=a=>{const r=a.getAttribute("data-asset-src");r!==null&&(a.getAttribute("data-asset-exists")!=="false"&&F.isAcceptableDocumentPath(r)?a.setAttribute("src",F.explorerAssetHref(i,r,null)):a.removeAttribute("src"))},C=a=>{const r=a.parentNode;if(r===null)return;const s=A.get(r);s!=null&&R.placeholderLinkOf(s,[...r.childNodes].map(Me))!==null&&r.setAttribute(R.EMBED_LINK_ATTRIBUTE,s)},E=a=>{if(a.nodeType!==x)return;const r=a,s=r.nodeName.toLowerCase();s==="img"?h(r):s==="a"&&C(r);const p=r.getAttribute("target");if(p===null||p.trim().toLowerCase()==="_self")return;const D=r.getAttribute("rel"),I=new Set(D===null?[]:D.split(/\s+/u).filter(H=>H!==""));I.add("noopener"),I.add("noreferrer"),r.setAttribute("rel",[...I].join(" "))};return a=>{l=new WeakMap,A=new WeakMap,S.addHook("beforeSanitizeElements",n),S.addHook("uponSanitizeElement",T),S.addHook("uponSanitizeAttribute",g),S.addHook("afterSanitizeAttributes",E);try{return S.sanitize(a,ye)}finally{S.removeHook("beforeSanitizeElements",n),S.removeHook("uponSanitizeElement",T),S.removeHook("uponSanitizeAttribute",g),S.removeHook("afterSanitizeAttributes",E)}}},He=t=>{if(t===null||typeof t!="object")return!1;const{id:i,input:u}=t;if(typeof i!="number"||u===null||typeof u!="object")return!1;const{html:f,iframeHosts:l,dataPath:A,maxNodes:n,maxAttributeChars:T,maxSanitizedChars:g}=u;return typeof f=="string"&&Array.isArray(l)&&l.every(h=>typeof h=="string")&&typeof A=="string"&&A!==""&&[n,T,g].every(h=>Number.isSafeInteger(h)&&h>0)},ze=()=>{const t=te.parentPort;if(t===null)throw new Error("[markdown-explorer] the sanitizer worker must run in a worker thread");const i=new Map;t.on("message",u=>{if(!He(u))throw new TypeError("[markdown-explorer] the sanitizer worker received a message that is not a job");const{id:f,input:l}=u;let A;try{if(ge(l.html,G,l.maxNodes,l.maxAttributeChars).status!=="within"){t.postMessage({id:f,output:{status:"too-large"}});return}const n=JSON.stringify([l.iframeHosts,l.dataPath]);let T=i.get(n);T===void 0&&(T=xe(l.iframeHosts,l.dataPath,G),i.set(n,T));const g=T(l.html);A=g.length>l.maxSanitizedChars?{status:"too-large"}:{status:"sanitized",html:g}}catch(n){A=n instanceof Y?{status:"too-large"}:{status:"error",message:n instanceof Error?`${n.name}: ${n.message}`:String(n)}}t.postMessage({id:f,output:A})}),t.postMessage({ready:!0})};ze();
|