pdf-codec 3.3.0 → 3.4.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/README.md +1 -1
- package/dist/codec.d.cts +8 -1
- package/dist/codec.d.ts +8 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/interpret.cjs +26 -9
- package/dist/interpret.d.cts +5 -0
- package/dist/interpret.d.ts +5 -0
- package/dist/interpret.js +26 -9
- package/dist/layout.cjs +17 -0
- package/dist/layout.d.cts +36 -1
- package/dist/layout.d.ts +36 -1
- package/dist/layout.js +17 -1
- package/dist/read.cjs +15 -3
- package/dist/read.js +15 -3
- package/dist/structure.cjs +184 -0
- package/dist/structure.d.cts +12 -0
- package/dist/structure.d.ts +12 -0
- package/dist/structure.js +183 -0
- package/package.json +2 -2
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_pdf_text = require("./pdf-text.cjs");
|
|
4
|
+
//#region src/structure.ts
|
|
5
|
+
function readStructure(catalog, pages, resolver, sink) {
|
|
6
|
+
const root = resolver.resolveDict(require_objects.dictGet(catalog, "StructTreeRoot"));
|
|
7
|
+
if (root === void 0) return {
|
|
8
|
+
tree: [],
|
|
9
|
+
ownerOf: () => void 0
|
|
10
|
+
};
|
|
11
|
+
const roleMap = /* @__PURE__ */ new Map();
|
|
12
|
+
const roleMapDict = resolver.resolveDict(require_objects.dictGet(root, "RoleMap"));
|
|
13
|
+
for (const [custom, standard] of roleMapDict?.entries ?? []) {
|
|
14
|
+
const target = require_objects.asName(standard);
|
|
15
|
+
if (target !== void 0) roleMap.set(custom, target);
|
|
16
|
+
}
|
|
17
|
+
const classAttributes = /* @__PURE__ */ new Map();
|
|
18
|
+
const classMapDict = resolver.resolveDict(require_objects.dictGet(root, "ClassMap"));
|
|
19
|
+
for (const [className, value] of classMapDict?.entries ?? []) {
|
|
20
|
+
const attributes = elementAttributes(resolver.resolveDict(value));
|
|
21
|
+
if (attributes !== void 0) classAttributes.set(className, attributes);
|
|
22
|
+
}
|
|
23
|
+
const idByDict = /* @__PURE__ */ new Map();
|
|
24
|
+
const tree = [];
|
|
25
|
+
const visited = /* @__PURE__ */ new Set();
|
|
26
|
+
let minted = 0;
|
|
27
|
+
const readElement = (dict) => {
|
|
28
|
+
if (visited.has(dict)) {
|
|
29
|
+
sink({
|
|
30
|
+
code: "pdf/structure-cycle",
|
|
31
|
+
severity: "warning",
|
|
32
|
+
message: "the structure tree contains a cycle; stopping descent at the repeated element"
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
visited.add(dict);
|
|
37
|
+
const ownType = require_objects.asName(require_objects.dictGet(dict, "S"));
|
|
38
|
+
if (ownType === void 0) {
|
|
39
|
+
sink({
|
|
40
|
+
code: "pdf/structure-element-invalid",
|
|
41
|
+
severity: "warning",
|
|
42
|
+
message: "a structure element carries no /S type; skipping it"
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
minted += 1;
|
|
47
|
+
const id = `struct${minted}`;
|
|
48
|
+
idByDict.set(dict, id);
|
|
49
|
+
const children = [];
|
|
50
|
+
for (const kid of elementKids(dict, resolver)) {
|
|
51
|
+
const child = readElement(kid);
|
|
52
|
+
if (child !== void 0) children.push(child);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
id,
|
|
56
|
+
type: roleMap.get(ownType) ?? ownType,
|
|
57
|
+
...mergedAttributes(dict, resolver, classAttributes),
|
|
58
|
+
children
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
for (const kid of elementKids(root, resolver)) {
|
|
62
|
+
const element = readElement(kid);
|
|
63
|
+
if (element !== void 0) tree.push(element);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
tree,
|
|
67
|
+
ownerOf: parentTreeOwners(root, pages, resolver, idByDict, sink)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const ATTRIBUTE_KEYS = [
|
|
71
|
+
"title",
|
|
72
|
+
"language",
|
|
73
|
+
"alt",
|
|
74
|
+
"actualText"
|
|
75
|
+
];
|
|
76
|
+
const ATTRIBUTE_SOURCES = [
|
|
77
|
+
["title", "T"],
|
|
78
|
+
["language", "Lang"],
|
|
79
|
+
["alt", "Alt"],
|
|
80
|
+
["actualText", "ActualText"]
|
|
81
|
+
];
|
|
82
|
+
function elementAttributes(dict) {
|
|
83
|
+
if (dict === void 0) return;
|
|
84
|
+
const stringField = (key) => {
|
|
85
|
+
const obj = require_objects.dictGet(dict, key);
|
|
86
|
+
return obj?.kind === "string" ? require_pdf_text.decodePdfString(obj.bytes) : void 0;
|
|
87
|
+
};
|
|
88
|
+
const values = /* @__PURE__ */ new Map();
|
|
89
|
+
for (const [field, source] of ATTRIBUTE_SOURCES) {
|
|
90
|
+
const value = stringField(source);
|
|
91
|
+
if (value !== void 0) values.set(field, value);
|
|
92
|
+
}
|
|
93
|
+
if (values.size === 0) return;
|
|
94
|
+
return Object.fromEntries(values);
|
|
95
|
+
}
|
|
96
|
+
function mergedAttributes(dict, resolver, classAttributes) {
|
|
97
|
+
const own = elementAttributes(dict);
|
|
98
|
+
const classAttributeList = [];
|
|
99
|
+
for (const classObj of require_objects.asArray(require_objects.dictGet(dict, "C")) ?? []) {
|
|
100
|
+
const name = require_objects.asName(classObj);
|
|
101
|
+
const attributes = name !== void 0 ? classAttributes.get(name) : elementAttributes(resolver.resolveDict(classObj));
|
|
102
|
+
if (attributes !== void 0) classAttributeList.push(attributes);
|
|
103
|
+
}
|
|
104
|
+
const values = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const key of ATTRIBUTE_KEYS) {
|
|
106
|
+
const ownValue = own?.[key];
|
|
107
|
+
if (ownValue !== void 0) {
|
|
108
|
+
values.set(key, ownValue);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
for (const attributes of classAttributeList) {
|
|
112
|
+
const value = attributes[key];
|
|
113
|
+
if (value !== void 0) {
|
|
114
|
+
values.set(key, value);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return Object.fromEntries(values);
|
|
120
|
+
}
|
|
121
|
+
function elementKids(dict, resolver) {
|
|
122
|
+
const kids = [];
|
|
123
|
+
const k = require_objects.dictGet(dict, "K");
|
|
124
|
+
for (const kid of require_objects.asArray(k) ?? (k !== void 0 ? [k] : [])) {
|
|
125
|
+
const resolved = resolver.resolveDict(kid);
|
|
126
|
+
if (resolved !== void 0 && require_objects.dictGet(resolved, "S") !== void 0) kids.push(resolved);
|
|
127
|
+
}
|
|
128
|
+
return kids;
|
|
129
|
+
}
|
|
130
|
+
function numberTreeEntries(node, resolver, visited) {
|
|
131
|
+
if (visited.has(node)) return [];
|
|
132
|
+
visited.add(node);
|
|
133
|
+
const entries = [];
|
|
134
|
+
const nums = require_objects.asArray(require_objects.dictGet(node, "Nums"));
|
|
135
|
+
for (let i = 0; nums !== void 0 && i + 1 < nums.length; i += 2) {
|
|
136
|
+
const key = require_objects.asNumber(nums[i]);
|
|
137
|
+
if (key !== void 0) entries.push([key, nums[i + 1]]);
|
|
138
|
+
}
|
|
139
|
+
for (const kid of require_objects.asArray(require_objects.dictGet(node, "Kids")) ?? []) {
|
|
140
|
+
const dict = resolver.resolveDict(kid);
|
|
141
|
+
if (dict !== void 0) entries.push(...numberTreeEntries(dict, resolver, visited));
|
|
142
|
+
}
|
|
143
|
+
return entries;
|
|
144
|
+
}
|
|
145
|
+
function parentTreeOwners(root, pages, resolver, idByDict, sink) {
|
|
146
|
+
const documentTree = resolver.resolveDict(require_objects.dictGet(root, "ParentTree"));
|
|
147
|
+
if (documentTree === void 0) {
|
|
148
|
+
if (require_objects.dictGet(root, "ParentTree") !== void 0) sink({
|
|
149
|
+
code: "pdf/parent-tree-unresolved",
|
|
150
|
+
severity: "warning",
|
|
151
|
+
message: "the /ParentTree did not resolve to a dictionary; no marked-content ownership can be associated"
|
|
152
|
+
});
|
|
153
|
+
return () => void 0;
|
|
154
|
+
}
|
|
155
|
+
const entries = new Map(numberTreeEntries(documentTree, resolver, /* @__PURE__ */ new Set()));
|
|
156
|
+
const owners = /* @__PURE__ */ new Map();
|
|
157
|
+
pages.forEach((page, pageIndex) => {
|
|
158
|
+
const structParents = require_objects.asNumber(require_objects.dictGet(page, "StructParents"));
|
|
159
|
+
if (structParents === void 0) return;
|
|
160
|
+
const entry = entries.get(structParents);
|
|
161
|
+
if (entry === void 0) {
|
|
162
|
+
sink({
|
|
163
|
+
code: "pdf/parent-tree-missing-entry",
|
|
164
|
+
severity: "warning",
|
|
165
|
+
pageIndex,
|
|
166
|
+
message: `page ${pageIndex} declares /StructParents ${structParents} but the /ParentTree carries no entry for that key; its marked content resolves to no owner`
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const mcidOwners = require_objects.asArray(entry);
|
|
171
|
+
if (mcidOwners === void 0) return;
|
|
172
|
+
mcidOwners.forEach((element, mcid) => {
|
|
173
|
+
const id = idByDict.get(resolver.resolveDict(element) ?? NEVER_DICT);
|
|
174
|
+
if (id !== void 0) owners.set(`${pageIndex}:${mcid}`, id);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
return (pageIndex, mcid) => owners.get(`${pageIndex}:${mcid}`);
|
|
178
|
+
}
|
|
179
|
+
const NEVER_DICT = {
|
|
180
|
+
kind: "dict",
|
|
181
|
+
entries: /* @__PURE__ */ new Map()
|
|
182
|
+
};
|
|
183
|
+
//#endregion
|
|
184
|
+
exports.readStructure = readStructure;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
+
import { PdfDict } from "./objects.cjs";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.cjs";
|
|
4
|
+
import { LayoutStructureElement } from "./layout.cjs";
|
|
5
|
+
//#region src/structure.d.ts
|
|
6
|
+
interface StructureContext {
|
|
7
|
+
readonly tree: readonly LayoutStructureElement[];
|
|
8
|
+
readonly ownerOf: (pageIndex: number, mcid: number) => string | undefined;
|
|
9
|
+
}
|
|
10
|
+
declare function readStructure(catalog: PdfDict, pages: readonly PdfDict[], resolver: PdfObjectResolver, sink: PdfDiagnosticSink): StructureContext;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { StructureContext, readStructure };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
+
import { PdfDict } from "./objects.js";
|
|
3
|
+
import { PdfObjectResolver } from "./interpret.js";
|
|
4
|
+
import { LayoutStructureElement } from "./layout.js";
|
|
5
|
+
//#region src/structure.d.ts
|
|
6
|
+
interface StructureContext {
|
|
7
|
+
readonly tree: readonly LayoutStructureElement[];
|
|
8
|
+
readonly ownerOf: (pageIndex: number, mcid: number) => string | undefined;
|
|
9
|
+
}
|
|
10
|
+
declare function readStructure(catalog: PdfDict, pages: readonly PdfDict[], resolver: PdfObjectResolver, sink: PdfDiagnosticSink): StructureContext;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { StructureContext, readStructure };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { asArray, asName, asNumber, dictGet } from "./objects.js";
|
|
2
|
+
import { decodePdfString } from "./pdf-text.js";
|
|
3
|
+
//#region src/structure.ts
|
|
4
|
+
function readStructure(catalog, pages, resolver, sink) {
|
|
5
|
+
const root = resolver.resolveDict(dictGet(catalog, "StructTreeRoot"));
|
|
6
|
+
if (root === void 0) return {
|
|
7
|
+
tree: [],
|
|
8
|
+
ownerOf: () => void 0
|
|
9
|
+
};
|
|
10
|
+
const roleMap = /* @__PURE__ */ new Map();
|
|
11
|
+
const roleMapDict = resolver.resolveDict(dictGet(root, "RoleMap"));
|
|
12
|
+
for (const [custom, standard] of roleMapDict?.entries ?? []) {
|
|
13
|
+
const target = asName(standard);
|
|
14
|
+
if (target !== void 0) roleMap.set(custom, target);
|
|
15
|
+
}
|
|
16
|
+
const classAttributes = /* @__PURE__ */ new Map();
|
|
17
|
+
const classMapDict = resolver.resolveDict(dictGet(root, "ClassMap"));
|
|
18
|
+
for (const [className, value] of classMapDict?.entries ?? []) {
|
|
19
|
+
const attributes = elementAttributes(resolver.resolveDict(value));
|
|
20
|
+
if (attributes !== void 0) classAttributes.set(className, attributes);
|
|
21
|
+
}
|
|
22
|
+
const idByDict = /* @__PURE__ */ new Map();
|
|
23
|
+
const tree = [];
|
|
24
|
+
const visited = /* @__PURE__ */ new Set();
|
|
25
|
+
let minted = 0;
|
|
26
|
+
const readElement = (dict) => {
|
|
27
|
+
if (visited.has(dict)) {
|
|
28
|
+
sink({
|
|
29
|
+
code: "pdf/structure-cycle",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: "the structure tree contains a cycle; stopping descent at the repeated element"
|
|
32
|
+
});
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
visited.add(dict);
|
|
36
|
+
const ownType = asName(dictGet(dict, "S"));
|
|
37
|
+
if (ownType === void 0) {
|
|
38
|
+
sink({
|
|
39
|
+
code: "pdf/structure-element-invalid",
|
|
40
|
+
severity: "warning",
|
|
41
|
+
message: "a structure element carries no /S type; skipping it"
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
minted += 1;
|
|
46
|
+
const id = `struct${minted}`;
|
|
47
|
+
idByDict.set(dict, id);
|
|
48
|
+
const children = [];
|
|
49
|
+
for (const kid of elementKids(dict, resolver)) {
|
|
50
|
+
const child = readElement(kid);
|
|
51
|
+
if (child !== void 0) children.push(child);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
id,
|
|
55
|
+
type: roleMap.get(ownType) ?? ownType,
|
|
56
|
+
...mergedAttributes(dict, resolver, classAttributes),
|
|
57
|
+
children
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
for (const kid of elementKids(root, resolver)) {
|
|
61
|
+
const element = readElement(kid);
|
|
62
|
+
if (element !== void 0) tree.push(element);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
tree,
|
|
66
|
+
ownerOf: parentTreeOwners(root, pages, resolver, idByDict, sink)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const ATTRIBUTE_KEYS = [
|
|
70
|
+
"title",
|
|
71
|
+
"language",
|
|
72
|
+
"alt",
|
|
73
|
+
"actualText"
|
|
74
|
+
];
|
|
75
|
+
const ATTRIBUTE_SOURCES = [
|
|
76
|
+
["title", "T"],
|
|
77
|
+
["language", "Lang"],
|
|
78
|
+
["alt", "Alt"],
|
|
79
|
+
["actualText", "ActualText"]
|
|
80
|
+
];
|
|
81
|
+
function elementAttributes(dict) {
|
|
82
|
+
if (dict === void 0) return;
|
|
83
|
+
const stringField = (key) => {
|
|
84
|
+
const obj = dictGet(dict, key);
|
|
85
|
+
return obj?.kind === "string" ? decodePdfString(obj.bytes) : void 0;
|
|
86
|
+
};
|
|
87
|
+
const values = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const [field, source] of ATTRIBUTE_SOURCES) {
|
|
89
|
+
const value = stringField(source);
|
|
90
|
+
if (value !== void 0) values.set(field, value);
|
|
91
|
+
}
|
|
92
|
+
if (values.size === 0) return;
|
|
93
|
+
return Object.fromEntries(values);
|
|
94
|
+
}
|
|
95
|
+
function mergedAttributes(dict, resolver, classAttributes) {
|
|
96
|
+
const own = elementAttributes(dict);
|
|
97
|
+
const classAttributeList = [];
|
|
98
|
+
for (const classObj of asArray(dictGet(dict, "C")) ?? []) {
|
|
99
|
+
const name = asName(classObj);
|
|
100
|
+
const attributes = name !== void 0 ? classAttributes.get(name) : elementAttributes(resolver.resolveDict(classObj));
|
|
101
|
+
if (attributes !== void 0) classAttributeList.push(attributes);
|
|
102
|
+
}
|
|
103
|
+
const values = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const key of ATTRIBUTE_KEYS) {
|
|
105
|
+
const ownValue = own?.[key];
|
|
106
|
+
if (ownValue !== void 0) {
|
|
107
|
+
values.set(key, ownValue);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
for (const attributes of classAttributeList) {
|
|
111
|
+
const value = attributes[key];
|
|
112
|
+
if (value !== void 0) {
|
|
113
|
+
values.set(key, value);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return Object.fromEntries(values);
|
|
119
|
+
}
|
|
120
|
+
function elementKids(dict, resolver) {
|
|
121
|
+
const kids = [];
|
|
122
|
+
const k = dictGet(dict, "K");
|
|
123
|
+
for (const kid of asArray(k) ?? (k !== void 0 ? [k] : [])) {
|
|
124
|
+
const resolved = resolver.resolveDict(kid);
|
|
125
|
+
if (resolved !== void 0 && dictGet(resolved, "S") !== void 0) kids.push(resolved);
|
|
126
|
+
}
|
|
127
|
+
return kids;
|
|
128
|
+
}
|
|
129
|
+
function numberTreeEntries(node, resolver, visited) {
|
|
130
|
+
if (visited.has(node)) return [];
|
|
131
|
+
visited.add(node);
|
|
132
|
+
const entries = [];
|
|
133
|
+
const nums = asArray(dictGet(node, "Nums"));
|
|
134
|
+
for (let i = 0; nums !== void 0 && i + 1 < nums.length; i += 2) {
|
|
135
|
+
const key = asNumber(nums[i]);
|
|
136
|
+
if (key !== void 0) entries.push([key, nums[i + 1]]);
|
|
137
|
+
}
|
|
138
|
+
for (const kid of asArray(dictGet(node, "Kids")) ?? []) {
|
|
139
|
+
const dict = resolver.resolveDict(kid);
|
|
140
|
+
if (dict !== void 0) entries.push(...numberTreeEntries(dict, resolver, visited));
|
|
141
|
+
}
|
|
142
|
+
return entries;
|
|
143
|
+
}
|
|
144
|
+
function parentTreeOwners(root, pages, resolver, idByDict, sink) {
|
|
145
|
+
const documentTree = resolver.resolveDict(dictGet(root, "ParentTree"));
|
|
146
|
+
if (documentTree === void 0) {
|
|
147
|
+
if (dictGet(root, "ParentTree") !== void 0) sink({
|
|
148
|
+
code: "pdf/parent-tree-unresolved",
|
|
149
|
+
severity: "warning",
|
|
150
|
+
message: "the /ParentTree did not resolve to a dictionary; no marked-content ownership can be associated"
|
|
151
|
+
});
|
|
152
|
+
return () => void 0;
|
|
153
|
+
}
|
|
154
|
+
const entries = new Map(numberTreeEntries(documentTree, resolver, /* @__PURE__ */ new Set()));
|
|
155
|
+
const owners = /* @__PURE__ */ new Map();
|
|
156
|
+
pages.forEach((page, pageIndex) => {
|
|
157
|
+
const structParents = asNumber(dictGet(page, "StructParents"));
|
|
158
|
+
if (structParents === void 0) return;
|
|
159
|
+
const entry = entries.get(structParents);
|
|
160
|
+
if (entry === void 0) {
|
|
161
|
+
sink({
|
|
162
|
+
code: "pdf/parent-tree-missing-entry",
|
|
163
|
+
severity: "warning",
|
|
164
|
+
pageIndex,
|
|
165
|
+
message: `page ${pageIndex} declares /StructParents ${structParents} but the /ParentTree carries no entry for that key; its marked content resolves to no owner`
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const mcidOwners = asArray(entry);
|
|
170
|
+
if (mcidOwners === void 0) return;
|
|
171
|
+
mcidOwners.forEach((element, mcid) => {
|
|
172
|
+
const id = idByDict.get(resolver.resolveDict(element) ?? NEVER_DICT);
|
|
173
|
+
if (id !== void 0) owners.set(`${pageIndex}:${mcid}`, id);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
return (pageIndex, mcid) => owners.get(`${pageIndex}:${mcid}`);
|
|
177
|
+
}
|
|
178
|
+
const NEVER_DICT = {
|
|
179
|
+
kind: "dict",
|
|
180
|
+
entries: /* @__PURE__ */ new Map()
|
|
181
|
+
};
|
|
182
|
+
//#endregion
|
|
183
|
+
export { readStructure };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-codec",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"packageManager": "pnpm@11.6.0",
|
|
99
99
|
"dependencies": {
|
|
100
100
|
"byte-codec": "^1.1.13",
|
|
101
|
-
"document-schema.js": "^4.
|
|
101
|
+
"document-schema.js": "^4.9.0",
|
|
102
102
|
"fflate": "^0.8.3",
|
|
103
103
|
"zod": "^4.4.3"
|
|
104
104
|
},
|