document-outline.js 0.0.0 → 1.0.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/LICENSE +21 -0
- package/README.md +121 -0
- package/dist/index.cjs +551 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +542 -0
- package/package.json +91 -2
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let document_schema_js = require("document-schema.js");
|
|
3
|
+
let zod = require("zod");
|
|
4
|
+
//#region src/outline/build.ts
|
|
5
|
+
function buildOutline(pkg) {
|
|
6
|
+
switch (pkg.kind) {
|
|
7
|
+
case "wordprocessing": return wordprocessingOutline(pkg.children);
|
|
8
|
+
case "presentation": return presentationOutline(pkg.children);
|
|
9
|
+
case "spreadsheet": return spreadsheetOutline(pkg.children);
|
|
10
|
+
case "drawing": return drawingOutline(pkg.children);
|
|
11
|
+
case "formula": return formulaOutline(pkg.children[0]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function freshSectionFlowScope() {
|
|
15
|
+
return {
|
|
16
|
+
root: [],
|
|
17
|
+
headingStack: [],
|
|
18
|
+
listStack: []
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function headingScopeOf(scope) {
|
|
22
|
+
return scope.headingStack.at(-1)?.children ?? scope.root;
|
|
23
|
+
}
|
|
24
|
+
function walkSectionFlow(scope, children) {
|
|
25
|
+
for (const child of children) if ((0, document_schema_js.isHeadingGroupNode)(child)) {
|
|
26
|
+
scope.listStack.length = 0;
|
|
27
|
+
const level = child.node.headingLevel;
|
|
28
|
+
for (let top = scope.headingStack.at(-1); top !== void 0 && top.level >= level; top = scope.headingStack.at(-1)) scope.headingStack.pop();
|
|
29
|
+
const node = {
|
|
30
|
+
text: paragraphText(child.node),
|
|
31
|
+
level,
|
|
32
|
+
children: []
|
|
33
|
+
};
|
|
34
|
+
const parent = scope.headingStack.at(-1);
|
|
35
|
+
(parent !== void 0 ? parent.children : scope.root).push(node);
|
|
36
|
+
scope.headingStack.push(node);
|
|
37
|
+
walkSectionFlow(scope, child.children);
|
|
38
|
+
} else if ((0, document_schema_js.isListGroupNode)(child)) {
|
|
39
|
+
openListGroup(scope.listStack, headingScopeOf(scope), paragraphText(child.node), child.node.list.level);
|
|
40
|
+
walkSectionFlow(scope, child.children);
|
|
41
|
+
} else if ((0, document_schema_js.isSectionConstructGroupNode)(child)) {
|
|
42
|
+
const parent = scope.listStack.at(-1);
|
|
43
|
+
(parent !== void 0 ? parent.children : headingScopeOf(scope)).push(...projectSectionFlow(child.children));
|
|
44
|
+
} else if (child.kind === "paragraph") {
|
|
45
|
+
scope.listStack.length = 0;
|
|
46
|
+
headingScopeOf(scope).push(child);
|
|
47
|
+
} else {
|
|
48
|
+
const parent = scope.listStack.at(-1);
|
|
49
|
+
(parent !== void 0 ? parent.children : headingScopeOf(scope)).push(child);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function projectSectionFlow(children) {
|
|
53
|
+
const scope = freshSectionFlowScope();
|
|
54
|
+
walkSectionFlow(scope, children);
|
|
55
|
+
return scope.root;
|
|
56
|
+
}
|
|
57
|
+
function wordprocessingOutline(sections) {
|
|
58
|
+
const scope = freshSectionFlowScope();
|
|
59
|
+
for (const section of sections) walkSectionFlow(scope, section.children);
|
|
60
|
+
return scope.root;
|
|
61
|
+
}
|
|
62
|
+
function walkShapeFlow(listStack, scope, children) {
|
|
63
|
+
for (const child of children) if ((0, document_schema_js.isListGroupNode)(child)) {
|
|
64
|
+
openListGroup(listStack, scope, paragraphText(child.node), child.node.list.level);
|
|
65
|
+
walkShapeFlow(listStack, scope, child.children);
|
|
66
|
+
} else if ((0, document_schema_js.isShapeConstructGroupNode)(child)) {
|
|
67
|
+
const parent = listStack.at(-1);
|
|
68
|
+
(parent !== void 0 ? parent.children : scope).push(...projectShapeFlow(child.children));
|
|
69
|
+
} else if (child.kind === "paragraph") {
|
|
70
|
+
listStack.length = 0;
|
|
71
|
+
scope.push(child);
|
|
72
|
+
} else {
|
|
73
|
+
const parent = listStack.at(-1);
|
|
74
|
+
(parent !== void 0 ? parent.children : scope).push(child);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function projectShapeFlow(children) {
|
|
78
|
+
const scope = [];
|
|
79
|
+
walkShapeFlow([], scope, children);
|
|
80
|
+
return scope;
|
|
81
|
+
}
|
|
82
|
+
function presentationOutline(slides) {
|
|
83
|
+
return slides.map((slide, index) => {
|
|
84
|
+
const group = {
|
|
85
|
+
text: `Slide ${String(index + 1)}`,
|
|
86
|
+
level: 1,
|
|
87
|
+
children: []
|
|
88
|
+
};
|
|
89
|
+
const listStack = [];
|
|
90
|
+
for (const shape of slide.children) walkShapeFlow(listStack, group.children, shape.children);
|
|
91
|
+
return group;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function spreadsheetOutline(sheets) {
|
|
95
|
+
return sheets.map((sheet) => ({
|
|
96
|
+
text: sheet.node.name,
|
|
97
|
+
level: 1,
|
|
98
|
+
children: [...sheet.children]
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
function drawingOutline(pages) {
|
|
102
|
+
return pages.map((page, index) => ({
|
|
103
|
+
text: `Page ${String(index + 1)}`,
|
|
104
|
+
level: 1,
|
|
105
|
+
children: page.children.flatMap((child) => (0, document_schema_js.isShapeGroupNode)(child) ? flattenShapeChildren(child) : [child])
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
function flattenShapeChildren(group) {
|
|
109
|
+
return flattenListFlow(group.children);
|
|
110
|
+
}
|
|
111
|
+
function flattenListFlow(children) {
|
|
112
|
+
const leaves = [];
|
|
113
|
+
for (const child of children) if ((0, document_schema_js.isListGroupNode)(child)) leaves.push(child.node, ...flattenListFlow(child.children));
|
|
114
|
+
else if ((0, document_schema_js.isShapeConstructGroupNode)(child)) leaves.push(...flattenListFlow(child.children));
|
|
115
|
+
else leaves.push(child);
|
|
116
|
+
return leaves;
|
|
117
|
+
}
|
|
118
|
+
function formulaOutline(formula) {
|
|
119
|
+
return [{
|
|
120
|
+
text: formula.presentation?.latex ?? "",
|
|
121
|
+
level: 1,
|
|
122
|
+
children: [formula]
|
|
123
|
+
}];
|
|
124
|
+
}
|
|
125
|
+
function openListGroup(listStack, scopeChildren, text, level) {
|
|
126
|
+
for (let top = listStack.at(-1); top !== void 0 && top.level >= level; top = listStack.at(-1)) listStack.pop();
|
|
127
|
+
const node = {
|
|
128
|
+
text,
|
|
129
|
+
level,
|
|
130
|
+
children: []
|
|
131
|
+
};
|
|
132
|
+
const parent = listStack.at(-1);
|
|
133
|
+
(parent !== void 0 ? parent.children : scopeChildren).push(node);
|
|
134
|
+
listStack.push(node);
|
|
135
|
+
}
|
|
136
|
+
function paragraphText(paragraph) {
|
|
137
|
+
return paragraph.runs.map((run) => run.text).join("");
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/outline/effective.ts
|
|
141
|
+
function effectivePackage(pkg) {
|
|
142
|
+
const styles = pkg.styles;
|
|
143
|
+
if (styles === void 0) return pkg;
|
|
144
|
+
switch (pkg.kind) {
|
|
145
|
+
case "wordprocessing": return withoutStyles({
|
|
146
|
+
...pkg,
|
|
147
|
+
children: pkg.children.map((group) => resolveSectionGroup(styles, [], group))
|
|
148
|
+
});
|
|
149
|
+
case "presentation": return withoutStyles({
|
|
150
|
+
...pkg,
|
|
151
|
+
children: pkg.children.map((group) => resolveSlideGroup(styles, [], group))
|
|
152
|
+
});
|
|
153
|
+
case "spreadsheet": return withoutStyles({
|
|
154
|
+
...pkg,
|
|
155
|
+
children: pkg.children.map(resolveSheetGroup)
|
|
156
|
+
});
|
|
157
|
+
case "drawing": return withoutStyles({
|
|
158
|
+
...pkg,
|
|
159
|
+
children: pkg.children.map((group) => resolveDrawPageGroup(styles, [], group))
|
|
160
|
+
});
|
|
161
|
+
case "formula": return withoutStyles({ ...pkg });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function withoutStyles(pkg) {
|
|
165
|
+
const copy = { ...pkg };
|
|
166
|
+
delete copy.styles;
|
|
167
|
+
return copy;
|
|
168
|
+
}
|
|
169
|
+
function chainWithRef(chain, group) {
|
|
170
|
+
return group.style === void 0 ? chain : [...chain, group.style];
|
|
171
|
+
}
|
|
172
|
+
function resolveSectionGroup(styles, chain, group) {
|
|
173
|
+
const children = resolveSectionChildren(styles, chainWithRef(chain, group), group.children);
|
|
174
|
+
if (group.style === void 0 && children === group.children) return group;
|
|
175
|
+
return {
|
|
176
|
+
node: group.node,
|
|
177
|
+
children
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function resolveSlideGroup(styles, chain, group) {
|
|
181
|
+
const own = chainWithRef(chain, group);
|
|
182
|
+
let changed = group.style !== void 0;
|
|
183
|
+
const children = [];
|
|
184
|
+
for (const shape of group.children) {
|
|
185
|
+
const resolved = resolveShapeGroup(styles, own, shape);
|
|
186
|
+
changed ||= resolved !== shape;
|
|
187
|
+
children.push(resolved);
|
|
188
|
+
}
|
|
189
|
+
if (!changed) return group;
|
|
190
|
+
return {
|
|
191
|
+
node: group.node,
|
|
192
|
+
children
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function resolveSheetGroup(group) {
|
|
196
|
+
return group.style === void 0 ? group : {
|
|
197
|
+
node: group.node,
|
|
198
|
+
children: group.children
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function resolveDrawPageGroup(styles, chain, group) {
|
|
202
|
+
const own = chainWithRef(chain, group);
|
|
203
|
+
let changed = group.style !== void 0;
|
|
204
|
+
const children = [];
|
|
205
|
+
for (const child of group.children) {
|
|
206
|
+
const resolved = isShapeGroup(child) ? resolveShapeGroup(styles, own, child) : child;
|
|
207
|
+
changed ||= resolved !== child;
|
|
208
|
+
children.push(resolved);
|
|
209
|
+
}
|
|
210
|
+
if (!changed) return group;
|
|
211
|
+
return {
|
|
212
|
+
node: group.node,
|
|
213
|
+
children
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function resolveShapeGroup(styles, chain, group) {
|
|
217
|
+
const children = resolveListChildren(styles, chainWithRef(chain, group), group.children);
|
|
218
|
+
if (group.style === void 0 && children === group.children) return group;
|
|
219
|
+
return {
|
|
220
|
+
node: group.node,
|
|
221
|
+
children
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function resolveSectionConstructGroup(styles, chain, group) {
|
|
225
|
+
const children = resolveSectionChildren(styles, chainWithRef(chain, group), group.children);
|
|
226
|
+
if (group.style === void 0 && children === group.children) return group;
|
|
227
|
+
return {
|
|
228
|
+
node: group.node,
|
|
229
|
+
children
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function resolveShapeConstructGroup(styles, chain, group) {
|
|
233
|
+
const children = resolveListChildren(styles, chainWithRef(chain, group), group.children);
|
|
234
|
+
if (group.style === void 0 && children === group.children) return group;
|
|
235
|
+
return {
|
|
236
|
+
node: group.node,
|
|
237
|
+
children
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function resolveHeadingGroup(styles, chain, group) {
|
|
241
|
+
const own = chainWithRef(chain, group);
|
|
242
|
+
const entry = own.length > 0 ? (0, document_schema_js.resolveStyleChain)(styles, own) : void 0;
|
|
243
|
+
let anchor = group.node;
|
|
244
|
+
if (entry !== void 0) {
|
|
245
|
+
const applied = applyEntry(entry, group.node);
|
|
246
|
+
assertResolvedHeadingAnchor(applied);
|
|
247
|
+
anchor = applied;
|
|
248
|
+
}
|
|
249
|
+
const children = resolveSectionChildren(styles, own, group.children);
|
|
250
|
+
if (group.style === void 0 && anchor === group.node && children === group.children) return group;
|
|
251
|
+
return {
|
|
252
|
+
node: anchor,
|
|
253
|
+
children
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function resolveListGroup(styles, chain, group) {
|
|
257
|
+
const own = chainWithRef(chain, group);
|
|
258
|
+
const entry = own.length > 0 ? (0, document_schema_js.resolveStyleChain)(styles, own) : void 0;
|
|
259
|
+
let anchor = group.node;
|
|
260
|
+
if (entry !== void 0) {
|
|
261
|
+
const applied = applyEntry(entry, group.node);
|
|
262
|
+
assertResolvedListAnchor(applied);
|
|
263
|
+
anchor = applied;
|
|
264
|
+
}
|
|
265
|
+
const children = resolveListChildren(styles, own, group.children);
|
|
266
|
+
if (group.style === void 0 && anchor === group.node && children === group.children) return group;
|
|
267
|
+
return {
|
|
268
|
+
node: anchor,
|
|
269
|
+
children
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function assertResolvedHeadingAnchor(paragraph) {
|
|
273
|
+
if (paragraph.headingLevel === void 0) throw new Error("effectivePackage: resolution dropped a heading anchor's headingLevel");
|
|
274
|
+
}
|
|
275
|
+
function assertResolvedListAnchor(paragraph) {
|
|
276
|
+
if (paragraph.list === void 0) throw new Error("effectivePackage: resolution dropped a list anchor's list membership");
|
|
277
|
+
}
|
|
278
|
+
function resolveSectionChildren(styles, chain, children) {
|
|
279
|
+
let changed = false;
|
|
280
|
+
const out = [];
|
|
281
|
+
for (const child of children) {
|
|
282
|
+
let resolved;
|
|
283
|
+
if ((0, document_schema_js.isHeadingGroupNode)(child)) resolved = resolveHeadingGroup(styles, chain, child);
|
|
284
|
+
else if ((0, document_schema_js.isListGroupNode)(child)) resolved = resolveListGroup(styles, chain, child);
|
|
285
|
+
else if ((0, document_schema_js.isSectionConstructGroupNode)(child)) resolved = resolveSectionConstructGroup(styles, chain, child);
|
|
286
|
+
else if (child.kind === "paragraph") resolved = resolveParagraphLeaf(styles, chain, child);
|
|
287
|
+
else resolved = child;
|
|
288
|
+
changed ||= resolved !== child;
|
|
289
|
+
out.push(resolved);
|
|
290
|
+
}
|
|
291
|
+
return changed ? out : children;
|
|
292
|
+
}
|
|
293
|
+
function resolveListChildren(styles, chain, children) {
|
|
294
|
+
let changed = false;
|
|
295
|
+
const out = [];
|
|
296
|
+
for (const child of children) {
|
|
297
|
+
let resolved;
|
|
298
|
+
if ((0, document_schema_js.isListGroupNode)(child)) resolved = resolveListGroup(styles, chain, child);
|
|
299
|
+
else if ((0, document_schema_js.isShapeConstructGroupNode)(child)) resolved = resolveShapeConstructGroup(styles, chain, child);
|
|
300
|
+
else if (child.kind === "paragraph") resolved = resolveParagraphLeaf(styles, chain, child);
|
|
301
|
+
else resolved = child;
|
|
302
|
+
changed ||= resolved !== child;
|
|
303
|
+
out.push(resolved);
|
|
304
|
+
}
|
|
305
|
+
return changed ? out : children;
|
|
306
|
+
}
|
|
307
|
+
function resolveParagraphLeaf(styles, chain, leaf) {
|
|
308
|
+
if (chain.length === 0) return leaf;
|
|
309
|
+
return applyEntry((0, document_schema_js.resolveStyleChain)(styles, chain), leaf);
|
|
310
|
+
}
|
|
311
|
+
function applyEntry(entry, paragraph) {
|
|
312
|
+
const withParagraph = (0, document_schema_js.applyParagraphStyleProperties)(entry.paragraph, paragraph);
|
|
313
|
+
const runProperties = entry.run;
|
|
314
|
+
if (runProperties === void 0) return withParagraph;
|
|
315
|
+
return {
|
|
316
|
+
...withParagraph,
|
|
317
|
+
runs: withParagraph.runs.map((run) => (0, document_schema_js.applyRunStyleProperties)(runProperties, run))
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function isShapeGroup(child) {
|
|
321
|
+
return "node" in child;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/outline/node.ts
|
|
325
|
+
function isOutlineLeaf(value) {
|
|
326
|
+
return (0, document_schema_js.isPackageLeaf)(value);
|
|
327
|
+
}
|
|
328
|
+
function isOutlineChild(value) {
|
|
329
|
+
return isOutlineNode(value) || isOutlineLeaf(value);
|
|
330
|
+
}
|
|
331
|
+
function isOutlineNode(value) {
|
|
332
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
333
|
+
if (!("text" in value) || typeof value.text !== "string") return false;
|
|
334
|
+
if (!("level" in value) || typeof value.level !== "number" || !Number.isFinite(value.level)) return false;
|
|
335
|
+
if (!("children" in value) || !Array.isArray(value.children)) return false;
|
|
336
|
+
return value.children.every(isOutlineChild);
|
|
337
|
+
}
|
|
338
|
+
const OutlineNodeSchema = zod.z.custom(isOutlineNode);
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region src/outline/hash.ts
|
|
341
|
+
function stableContentHash(value) {
|
|
342
|
+
return sha256Hex(new TextEncoder().encode(JSON.stringify(canonicalise(stripSchemaKeys(value)))));
|
|
343
|
+
}
|
|
344
|
+
function isRecord(value) {
|
|
345
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
346
|
+
}
|
|
347
|
+
function stripSchemaKeys(value) {
|
|
348
|
+
if (Array.isArray(value)) return value.map(stripSchemaKeys);
|
|
349
|
+
if (isRecord(value)) {
|
|
350
|
+
const stripped = {};
|
|
351
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
352
|
+
if (key === "$schema") continue;
|
|
353
|
+
stripped[key] = stripSchemaKeys(entry);
|
|
354
|
+
}
|
|
355
|
+
return stripped;
|
|
356
|
+
}
|
|
357
|
+
return value;
|
|
358
|
+
}
|
|
359
|
+
function canonicalise(value) {
|
|
360
|
+
if (Array.isArray(value)) return value.map(canonicalise);
|
|
361
|
+
if (isRecord(value)) {
|
|
362
|
+
const sorted = {};
|
|
363
|
+
for (const key of Object.keys(value).sort()) sorted[key] = canonicalise(value[key]);
|
|
364
|
+
return sorted;
|
|
365
|
+
}
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
function sha256Hex(bytes) {
|
|
369
|
+
const digest = sha256(bytes);
|
|
370
|
+
let hex = "";
|
|
371
|
+
for (const byte of digest) hex += byte.toString(16).padStart(2, "0");
|
|
372
|
+
return hex;
|
|
373
|
+
}
|
|
374
|
+
const K = [
|
|
375
|
+
1116352408,
|
|
376
|
+
1899447441,
|
|
377
|
+
3049323471,
|
|
378
|
+
3921009573,
|
|
379
|
+
961987163,
|
|
380
|
+
1508970993,
|
|
381
|
+
2453635748,
|
|
382
|
+
2870763221,
|
|
383
|
+
3624381080,
|
|
384
|
+
310598401,
|
|
385
|
+
607225278,
|
|
386
|
+
1426881987,
|
|
387
|
+
1925078388,
|
|
388
|
+
2162078206,
|
|
389
|
+
2614888103,
|
|
390
|
+
3248222580,
|
|
391
|
+
3835390401,
|
|
392
|
+
4022224774,
|
|
393
|
+
264347078,
|
|
394
|
+
604807628,
|
|
395
|
+
770255983,
|
|
396
|
+
1249150122,
|
|
397
|
+
1555081692,
|
|
398
|
+
1996064986,
|
|
399
|
+
2554220882,
|
|
400
|
+
2821834349,
|
|
401
|
+
2952996808,
|
|
402
|
+
3210313671,
|
|
403
|
+
3336571891,
|
|
404
|
+
3584528711,
|
|
405
|
+
113926993,
|
|
406
|
+
338241895,
|
|
407
|
+
666307205,
|
|
408
|
+
773529912,
|
|
409
|
+
1294757372,
|
|
410
|
+
1396182291,
|
|
411
|
+
1695183700,
|
|
412
|
+
1986661051,
|
|
413
|
+
2177026350,
|
|
414
|
+
2456956037,
|
|
415
|
+
2730485921,
|
|
416
|
+
2820302411,
|
|
417
|
+
3259730800,
|
|
418
|
+
3345764771,
|
|
419
|
+
3516065817,
|
|
420
|
+
3600352804,
|
|
421
|
+
4094571909,
|
|
422
|
+
275423344,
|
|
423
|
+
430227734,
|
|
424
|
+
506948616,
|
|
425
|
+
659060556,
|
|
426
|
+
883997877,
|
|
427
|
+
958139571,
|
|
428
|
+
1322822218,
|
|
429
|
+
1537002063,
|
|
430
|
+
1747873779,
|
|
431
|
+
1955562222,
|
|
432
|
+
2024104815,
|
|
433
|
+
2227730452,
|
|
434
|
+
2361852424,
|
|
435
|
+
2428436474,
|
|
436
|
+
2756734187,
|
|
437
|
+
3204031479,
|
|
438
|
+
3329325298
|
|
439
|
+
];
|
|
440
|
+
function rotr(x, n) {
|
|
441
|
+
return (x >>> n | x << 32 - n) >>> 0;
|
|
442
|
+
}
|
|
443
|
+
function sha256(bytes) {
|
|
444
|
+
const bitLength = bytes.length * 8;
|
|
445
|
+
const paddedLength = (bytes.length + 8 >> 6) + 1 << 6;
|
|
446
|
+
const padded = new Uint8Array(paddedLength);
|
|
447
|
+
padded.set(bytes);
|
|
448
|
+
padded[bytes.length] = 128;
|
|
449
|
+
const view = new DataView(padded.buffer);
|
|
450
|
+
view.setUint32(paddedLength - 8, Math.floor(bitLength / 4294967296));
|
|
451
|
+
view.setUint32(paddedLength - 4, bitLength >>> 0);
|
|
452
|
+
let h0 = 1779033703;
|
|
453
|
+
let h1 = 3144134277;
|
|
454
|
+
let h2 = 1013904242;
|
|
455
|
+
let h3 = 2773480762;
|
|
456
|
+
let h4 = 1359893119;
|
|
457
|
+
let h5 = 2600822924;
|
|
458
|
+
let h6 = 528734635;
|
|
459
|
+
let h7 = 1541459225;
|
|
460
|
+
const w = /* @__PURE__ */ new Uint32Array(64);
|
|
461
|
+
for (let offset = 0; offset < paddedLength; offset += 64) {
|
|
462
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4);
|
|
463
|
+
for (let i = 16; i < 64; i++) {
|
|
464
|
+
const w15 = w[i - 15];
|
|
465
|
+
const w2 = w[i - 2];
|
|
466
|
+
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
467
|
+
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
468
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
469
|
+
}
|
|
470
|
+
let a = h0;
|
|
471
|
+
let b = h1;
|
|
472
|
+
let c = h2;
|
|
473
|
+
let d = h3;
|
|
474
|
+
let e = h4;
|
|
475
|
+
let f = h5;
|
|
476
|
+
let g = h6;
|
|
477
|
+
let h = h7;
|
|
478
|
+
for (let i = 0; i < 64; i++) {
|
|
479
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
480
|
+
const ch = e & f ^ ~e & g;
|
|
481
|
+
const temp1 = h + s1 + ch + K[i] + w[i] >>> 0;
|
|
482
|
+
const temp2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
|
|
483
|
+
h = g;
|
|
484
|
+
g = f;
|
|
485
|
+
f = e;
|
|
486
|
+
e = d + temp1 >>> 0;
|
|
487
|
+
d = c;
|
|
488
|
+
c = b;
|
|
489
|
+
b = a;
|
|
490
|
+
a = temp1 + temp2 >>> 0;
|
|
491
|
+
}
|
|
492
|
+
h0 = h0 + a >>> 0;
|
|
493
|
+
h1 = h1 + b >>> 0;
|
|
494
|
+
h2 = h2 + c >>> 0;
|
|
495
|
+
h3 = h3 + d >>> 0;
|
|
496
|
+
h4 = h4 + e >>> 0;
|
|
497
|
+
h5 = h5 + f >>> 0;
|
|
498
|
+
h6 = h6 + g >>> 0;
|
|
499
|
+
h7 = h7 + h >>> 0;
|
|
500
|
+
}
|
|
501
|
+
const digest = /* @__PURE__ */ new Uint8Array(32);
|
|
502
|
+
const out = new DataView(digest.buffer);
|
|
503
|
+
out.setUint32(0, h0);
|
|
504
|
+
out.setUint32(4, h1);
|
|
505
|
+
out.setUint32(8, h2);
|
|
506
|
+
out.setUint32(12, h3);
|
|
507
|
+
out.setUint32(16, h4);
|
|
508
|
+
out.setUint32(20, h5);
|
|
509
|
+
out.setUint32(24, h6);
|
|
510
|
+
out.setUint32(28, h7);
|
|
511
|
+
return digest;
|
|
512
|
+
}
|
|
513
|
+
//#endregion
|
|
514
|
+
//#region src/outline/helpers.ts
|
|
515
|
+
function flattenOutline(children) {
|
|
516
|
+
const leaves = [];
|
|
517
|
+
const walk = (subtree) => {
|
|
518
|
+
for (const child of subtree) if (isOutlineNode(child)) walk(child.children);
|
|
519
|
+
else leaves.push(child);
|
|
520
|
+
};
|
|
521
|
+
walk(children);
|
|
522
|
+
return leaves;
|
|
523
|
+
}
|
|
524
|
+
function outlineLeafText(leaf) {
|
|
525
|
+
if ("runs" in leaf) return leaf.runs.map((run) => run.text).join("");
|
|
526
|
+
if ("rows" in leaf) return leaf.rows.map((row) => row.cells.map((cell) => blockTexts(cell.blocks).join(" ")).join(" ")).join("\n");
|
|
527
|
+
if ("base64" in leaf) return leaf.altText ?? "";
|
|
528
|
+
if ("mathml" in leaf) return leaf.presentation?.latex ?? "";
|
|
529
|
+
return "";
|
|
530
|
+
}
|
|
531
|
+
function blockTexts(blocks) {
|
|
532
|
+
const parts = [];
|
|
533
|
+
for (const block of blocks) {
|
|
534
|
+
if (block.kind === "paragraph") parts.push(block.runs.map((run) => run.text).join(""));
|
|
535
|
+
if (block.kind === "table") parts.push(...block.rows.flatMap((row) => row.cells.map((cell) => blockTexts(cell.blocks).join(" "))));
|
|
536
|
+
}
|
|
537
|
+
return parts;
|
|
538
|
+
}
|
|
539
|
+
function leafContentHash(leaf) {
|
|
540
|
+
return stableContentHash(leaf);
|
|
541
|
+
}
|
|
542
|
+
//#endregion
|
|
543
|
+
exports.OutlineNodeSchema = OutlineNodeSchema;
|
|
544
|
+
exports.buildOutline = buildOutline;
|
|
545
|
+
exports.effectivePackage = effectivePackage;
|
|
546
|
+
exports.flattenOutline = flattenOutline;
|
|
547
|
+
exports.isOutlineChild = isOutlineChild;
|
|
548
|
+
exports.isOutlineLeaf = isOutlineLeaf;
|
|
549
|
+
exports.isOutlineNode = isOutlineNode;
|
|
550
|
+
exports.leafContentHash = leafContentHash;
|
|
551
|
+
exports.outlineLeafText = outlineLeafText;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DocumentPackage, PackageLeaf } from "document-schema.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/outline/node.d.ts
|
|
4
|
+
type OutlineLeaf = PackageLeaf;
|
|
5
|
+
type OutlineChild = OutlineNode | OutlineLeaf;
|
|
6
|
+
interface OutlineNode {
|
|
7
|
+
readonly text: string;
|
|
8
|
+
readonly level: number;
|
|
9
|
+
children: OutlineChild[];
|
|
10
|
+
}
|
|
11
|
+
declare function isOutlineLeaf(value: unknown): value is OutlineLeaf;
|
|
12
|
+
declare function isOutlineChild(value: unknown): value is OutlineChild;
|
|
13
|
+
declare function isOutlineNode(value: unknown): value is OutlineNode;
|
|
14
|
+
declare const OutlineNodeSchema: z.ZodCustom<OutlineNode, OutlineNode>;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/outline/build.d.ts
|
|
17
|
+
declare function buildOutline(pkg: DocumentPackage): OutlineChild[];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/outline/effective.d.ts
|
|
20
|
+
declare function effectivePackage(pkg: DocumentPackage): DocumentPackage;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/outline/helpers.d.ts
|
|
23
|
+
declare function flattenOutline(children: readonly OutlineChild[]): OutlineLeaf[];
|
|
24
|
+
declare function outlineLeafText(leaf: OutlineLeaf): string;
|
|
25
|
+
declare function leafContentHash(leaf: OutlineLeaf): string;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { OutlineChild, OutlineLeaf, OutlineNode, OutlineNodeSchema, buildOutline, effectivePackage, flattenOutline, isOutlineChild, isOutlineLeaf, isOutlineNode, leafContentHash, outlineLeafText };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DocumentPackage, PackageLeaf } from "document-schema.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/outline/node.d.ts
|
|
4
|
+
type OutlineLeaf = PackageLeaf;
|
|
5
|
+
type OutlineChild = OutlineNode | OutlineLeaf;
|
|
6
|
+
interface OutlineNode {
|
|
7
|
+
readonly text: string;
|
|
8
|
+
readonly level: number;
|
|
9
|
+
children: OutlineChild[];
|
|
10
|
+
}
|
|
11
|
+
declare function isOutlineLeaf(value: unknown): value is OutlineLeaf;
|
|
12
|
+
declare function isOutlineChild(value: unknown): value is OutlineChild;
|
|
13
|
+
declare function isOutlineNode(value: unknown): value is OutlineNode;
|
|
14
|
+
declare const OutlineNodeSchema: z.ZodCustom<OutlineNode, OutlineNode>;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/outline/build.d.ts
|
|
17
|
+
declare function buildOutline(pkg: DocumentPackage): OutlineChild[];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/outline/effective.d.ts
|
|
20
|
+
declare function effectivePackage(pkg: DocumentPackage): DocumentPackage;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/outline/helpers.d.ts
|
|
23
|
+
declare function flattenOutline(children: readonly OutlineChild[]): OutlineLeaf[];
|
|
24
|
+
declare function outlineLeafText(leaf: OutlineLeaf): string;
|
|
25
|
+
declare function leafContentHash(leaf: OutlineLeaf): string;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { OutlineChild, OutlineLeaf, OutlineNode, OutlineNodeSchema, buildOutline, effectivePackage, flattenOutline, isOutlineChild, isOutlineLeaf, isOutlineNode, leafContentHash, outlineLeafText };
|