reamkit 1.14.0 → 1.15.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/README.md +34 -8
- package/dist/esm/core/converter/facade.d.ts +8 -1
- package/dist/esm/core/converter/facade.js +34 -8
- package/dist/esm/core/converter/ream.d.ts +1 -0
- package/dist/esm/core/converter/ream.js +13 -8
- package/dist/esm/core/ir/features.d.ts +1 -0
- package/dist/esm/core/ir/features.js +1 -0
- package/dist/esm/core/ir/sheet.d.ts +7 -0
- package/dist/esm/core/ole/cfb.d.ts +19 -0
- package/dist/esm/core/ole/cfb.js +188 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +20 -1
- package/dist/esm/excel/activex-parser.d.ts +9 -0
- package/dist/esm/excel/activex-parser.js +188 -0
- package/dist/esm/excel/conditional-format.d.ts +4 -2
- package/dist/esm/excel/conditional-format.js +138 -4
- package/dist/esm/excel/formula/context.d.ts +11 -0
- package/dist/esm/excel/formula/dates.d.ts +11 -0
- package/dist/esm/excel/formula/dates.js +46 -0
- package/dist/esm/excel/formula/eval.d.ts +11 -0
- package/dist/esm/excel/formula/eval.js +196 -0
- package/dist/esm/excel/formula/functions.d.ts +7 -0
- package/dist/esm/excel/formula/functions.js +1359 -0
- package/dist/esm/excel/formula/index.d.ts +14 -0
- package/dist/esm/excel/formula/index.js +17 -0
- package/dist/esm/excel/formula/lexer.d.ts +8 -0
- package/dist/esm/excel/formula/lexer.js +163 -0
- package/dist/esm/excel/formula/parser.d.ts +57 -0
- package/dist/esm/excel/formula/parser.js +274 -0
- package/dist/esm/excel/formula/value.d.ts +52 -0
- package/dist/esm/excel/formula/value.js +102 -0
- package/dist/esm/excel/number-format.d.ts +2 -0
- package/dist/esm/excel/number-format.js +5 -1
- package/dist/esm/excel/print-model.d.ts +3 -0
- package/dist/esm/excel/print-model.js +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +4 -1
- package/dist/esm/excel/sheet-to-flow.js +46 -2
- package/dist/esm/excel/worksheet-parser.js +66 -0
- package/dist/esm/excel/xls/biff-chart.d.ts +8 -0
- package/dist/esm/excel/xls/biff-chart.js +121 -0
- package/dist/esm/excel/xls/biff-reader.d.ts +4 -0
- package/dist/esm/excel/xls/biff-reader.js +1418 -0
- package/dist/esm/excel/xls/biff-styles.d.ts +8 -0
- package/dist/esm/excel/xls/biff-styles.js +299 -0
- package/dist/esm/excel/xls/escher.d.ts +24 -0
- package/dist/esm/excel/xls/escher.js +171 -0
- package/dist/esm/excel/xls/xls-reader.d.ts +3 -0
- package/dist/esm/excel/xls/xls-reader.js +30 -0
- package/dist/esm/excel/xlsx-reader.d.ts +2 -1
- package/dist/esm/excel/xlsx-reader.js +28 -3
- package/dist/esm/excel/xlsx-to-pdf.d.ts +1 -0
- package/dist/esm/excel/xlsx-to-pdf.js +2 -2
- package/dist/esm/excel/xlsx-writer.js +2 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +4 -2
- package/dist/esm/pdf-reader/flow-build.js +25 -2
- package/dist/esm/pdf-reader/layout.js +2 -2
- package/dist/esm/pdf-reader/tagged.js +2 -2
- package/dist/esm/pptx/ppt/ppt-reader.d.ts +4 -0
- package/dist/esm/pptx/ppt/ppt-reader.js +337 -0
- package/dist/esm/pptx/ppt/ppt-text.d.ts +69 -0
- package/dist/esm/pptx/ppt/ppt-text.js +756 -0
- package/dist/esm/pptx/pptx-reader.js +16 -1
- package/dist/esm/word/doc/doc-reader.d.ts +4 -0
- package/dist/esm/word/doc/doc-reader.js +427 -0
- package/dist/esm/word/doc/doc-text.d.ts +83 -0
- package/dist/esm/word/doc/doc-text.js +731 -0
- package/package.json +1 -1
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
import { isCfb, openCfb } from "../../core/ole/cfb.js";
|
|
2
|
+
//#region src/pptx/ppt/ppt-text.ts
|
|
3
|
+
var RT_DOCUMENT = 1e3;
|
|
4
|
+
var RT_DOCUMENT_ATOM = 1001;
|
|
5
|
+
var RT_SLIDE_LIST_WITH_TEXT = 4080;
|
|
6
|
+
var RT_SLIDE_PERSIST_ATOM = 1011;
|
|
7
|
+
var RT_SLIDE = 1006;
|
|
8
|
+
var RT_USER_EDIT_ATOM = 4085;
|
|
9
|
+
var RT_PERSIST_DIRECTORY_ATOM = 6002;
|
|
10
|
+
var RT_DRAWING_GROUP = 1035;
|
|
11
|
+
var RT_TEXT_HEADER_ATOM = 3999;
|
|
12
|
+
var RT_TEXT_CHARS_ATOM = 4e3;
|
|
13
|
+
var RT_STYLE_TEXT_PROP_ATOM = 4001;
|
|
14
|
+
var RT_TEXT_BYTES_ATOM = 4008;
|
|
15
|
+
var RT_SLIDE_ATOM = 1007;
|
|
16
|
+
var RT_MAIN_MASTER = 1016;
|
|
17
|
+
var RT_COLOR_SCHEME_ATOM = 2032;
|
|
18
|
+
var FBT_BSTORE_CONTAINER = 61441;
|
|
19
|
+
var FBT_BSE = 61447;
|
|
20
|
+
var FBT_SP_CONTAINER = 61444;
|
|
21
|
+
var FBT_FSP = 61450;
|
|
22
|
+
var FBT_OPT = 61451;
|
|
23
|
+
var FBT_CLIENT_TEXTBOX = 61453;
|
|
24
|
+
var FBT_CLIENT_ANCHOR = 61456;
|
|
25
|
+
var PROP_PIB = 260;
|
|
26
|
+
var PROP_FILL_COLOR = 385;
|
|
27
|
+
var PROP_LINE_COLOR = 448;
|
|
28
|
+
var PROP_GEO_LEFT = 320;
|
|
29
|
+
var PROP_GEO_TOP = 321;
|
|
30
|
+
var PROP_GEO_RIGHT = 322;
|
|
31
|
+
var PROP_GEO_BOTTOM = 323;
|
|
32
|
+
var PROP_VERTICES = 325;
|
|
33
|
+
var PROP_SEGMENT_INFO = 326;
|
|
34
|
+
var COLOR_SCHEME_INSTANCE = 1;
|
|
35
|
+
var SLIDE_FLAG_MASTER_SCHEME = 2;
|
|
36
|
+
var COLORREF_SCHEME_INDEX = 8;
|
|
37
|
+
var COLORREF_SYS_INDEX = 16;
|
|
38
|
+
var FBSE_FODELAY_OFFSET = 28;
|
|
39
|
+
var FSP_FLAG_PATRIARCH = 4;
|
|
40
|
+
var TOKEN_ENCRYPTED = 4090610911;
|
|
41
|
+
var SLWT_INSTANCE_SLIDES = 0;
|
|
42
|
+
var MAX_EDITS = 4096;
|
|
43
|
+
var MAX_DEPTH = 24;
|
|
44
|
+
function recordAt(stream, off) {
|
|
45
|
+
if (off < 0 || off + 8 > stream.length) return void 0;
|
|
46
|
+
const verInstance = u16(stream, off);
|
|
47
|
+
const type = u16(stream, off + 2);
|
|
48
|
+
const recLen = u32(stream, off + 4);
|
|
49
|
+
const start = off + 8;
|
|
50
|
+
const end = Math.min(stream.length, start + recLen);
|
|
51
|
+
return {
|
|
52
|
+
type,
|
|
53
|
+
instance: verInstance >> 4,
|
|
54
|
+
isContainer: (verInstance & 15) === 15,
|
|
55
|
+
data: stream.subarray(start, end)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function* records(d) {
|
|
59
|
+
let off = 0;
|
|
60
|
+
while (off + 8 <= d.length) {
|
|
61
|
+
const rec = recordAt(d, off);
|
|
62
|
+
if (!rec) break;
|
|
63
|
+
yield rec;
|
|
64
|
+
const consumed = 8 + rec.data.length;
|
|
65
|
+
if (consumed <= 0) break;
|
|
66
|
+
off += consumed;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function extractPptContent(bytes) {
|
|
70
|
+
const empty = {
|
|
71
|
+
slides: [],
|
|
72
|
+
encrypted: false
|
|
73
|
+
};
|
|
74
|
+
if (!isCfb(bytes)) return empty;
|
|
75
|
+
let cfb;
|
|
76
|
+
try {
|
|
77
|
+
cfb = openCfb(bytes);
|
|
78
|
+
} catch {
|
|
79
|
+
return empty;
|
|
80
|
+
}
|
|
81
|
+
const stream = cfb.readStream("PowerPoint Document");
|
|
82
|
+
if (!stream) return empty;
|
|
83
|
+
const currentUser = cfb.readStream("Current User");
|
|
84
|
+
if (currentUser && currentUser.length >= 16) {
|
|
85
|
+
if (u32(currentUser, 12) === TOKEN_ENCRYPTED) return {
|
|
86
|
+
slides: [],
|
|
87
|
+
encrypted: true
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
let currentEditOffset = currentUser && currentUser.length >= 20 ? u32(currentUser, 16) : 0;
|
|
91
|
+
if (currentEditOffset === 0 || currentEditOffset + 8 > stream.length) currentEditOffset = findLastUserEdit(stream);
|
|
92
|
+
const { persist, docPersistId } = buildPersistDirectory(stream, currentEditOffset);
|
|
93
|
+
const docOffset = docPersistId !== void 0 ? persist.get(docPersistId) : void 0;
|
|
94
|
+
const docRec = docOffset !== void 0 ? recordAt(stream, docOffset) : findDocument(stream);
|
|
95
|
+
const noImages = {
|
|
96
|
+
foDelays: [],
|
|
97
|
+
pictures: new Uint8Array(0)
|
|
98
|
+
};
|
|
99
|
+
if (!docRec || docRec.type !== RT_DOCUMENT) return {
|
|
100
|
+
slides: slidesByScan(stream, noImages),
|
|
101
|
+
encrypted: false
|
|
102
|
+
};
|
|
103
|
+
const img = {
|
|
104
|
+
foDelays: parseFbseStore(docRec.data),
|
|
105
|
+
pictures: cfb.readStream("Pictures") ?? new Uint8Array(0)
|
|
106
|
+
};
|
|
107
|
+
const slides = readSlideList(stream, docRec.data, persist, img);
|
|
108
|
+
const hasContent = slides.some(slideHasContent);
|
|
109
|
+
const size = readSlideSize(docRec.data);
|
|
110
|
+
return {
|
|
111
|
+
slides: hasContent ? slides : slidesByScan(stream, img),
|
|
112
|
+
...size ?? {},
|
|
113
|
+
encrypted: false
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function slideHasContent(s) {
|
|
117
|
+
return s.shapes.some((sh) => shapeHasText(sh) || sh.image !== void 0 || sh.autoShape !== void 0);
|
|
118
|
+
}
|
|
119
|
+
function shapeHasText(sh) {
|
|
120
|
+
return sh.paragraphs?.some((p) => paragraphText(p).length > 0) ?? false;
|
|
121
|
+
}
|
|
122
|
+
function slideShapes(slideData, img, outline, scheme) {
|
|
123
|
+
const shapes = collectShapes(slideData, img, scheme);
|
|
124
|
+
if (!shapes.some(shapeHasText)) {
|
|
125
|
+
const inline = collectParagraphs(slideData, 0);
|
|
126
|
+
const text = inline.some((p) => paragraphText(p).length > 0) ? inline : outline;
|
|
127
|
+
if (text.some((p) => paragraphText(p).length > 0)) shapes.push({ paragraphs: text });
|
|
128
|
+
}
|
|
129
|
+
return shapes;
|
|
130
|
+
}
|
|
131
|
+
function buildPersistDirectory(stream, currentEditOffset) {
|
|
132
|
+
const persist = /* @__PURE__ */ new Map();
|
|
133
|
+
let docPersistId;
|
|
134
|
+
let editOff = currentEditOffset;
|
|
135
|
+
for (let guard = 0; editOff !== 0 && guard < MAX_EDITS; guard++) {
|
|
136
|
+
const edit = recordAt(stream, editOff);
|
|
137
|
+
if (!edit || edit.type !== RT_USER_EDIT_ATOM || edit.data.length < 20) break;
|
|
138
|
+
const offsetLastEdit = u32(edit.data, 8);
|
|
139
|
+
const offsetPersistDir = u32(edit.data, 12);
|
|
140
|
+
if (docPersistId === void 0) docPersistId = u32(edit.data, 16);
|
|
141
|
+
mergePersistDirectory(stream, offsetPersistDir, persist);
|
|
142
|
+
if (offsetLastEdit >= editOff) break;
|
|
143
|
+
editOff = offsetLastEdit;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
persist,
|
|
147
|
+
docPersistId
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function mergePersistDirectory(stream, offset, persist) {
|
|
151
|
+
const dir = recordAt(stream, offset);
|
|
152
|
+
if (!dir || dir.type !== RT_PERSIST_DIRECTORY_ATOM) return;
|
|
153
|
+
const d = dir.data;
|
|
154
|
+
let p = 0;
|
|
155
|
+
while (p + 4 <= d.length) {
|
|
156
|
+
const persistIdAndCnt = u32(d, p);
|
|
157
|
+
p += 4;
|
|
158
|
+
const startId = persistIdAndCnt & 1048575;
|
|
159
|
+
const count = persistIdAndCnt >>> 20 & 4095;
|
|
160
|
+
for (let i = 0; i < count && p + 4 <= d.length; i++) {
|
|
161
|
+
const off = u32(d, p);
|
|
162
|
+
p += 4;
|
|
163
|
+
if (!persist.has(startId + i)) persist.set(startId + i, off);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function readSlideList(stream, docData, persist, img) {
|
|
168
|
+
const slwt = findChild(docData, (r) => r.type === RT_SLIDE_LIST_WITH_TEXT && r.instance === SLWT_INSTANCE_SLIDES);
|
|
169
|
+
if (!slwt) return [];
|
|
170
|
+
const slides = [];
|
|
171
|
+
let outline = [];
|
|
172
|
+
let pendingRef;
|
|
173
|
+
const flush = () => {
|
|
174
|
+
if (pendingRef === void 0) return;
|
|
175
|
+
const slideOff = persist.get(pendingRef);
|
|
176
|
+
const slideRec = slideOff !== void 0 ? recordAt(stream, slideOff) : void 0;
|
|
177
|
+
const shapes = slideRec !== void 0 && slideRec.type === RT_SLIDE ? slideShapes(slideRec.data, img, outline, resolveScheme(slideRec.data, persist, stream)) : outline.some((p) => paragraphText(p).length > 0) ? [{ paragraphs: outline }] : [];
|
|
178
|
+
slides.push({ shapes });
|
|
179
|
+
outline = [];
|
|
180
|
+
pendingRef = void 0;
|
|
181
|
+
};
|
|
182
|
+
const recs = [...records(slwt)];
|
|
183
|
+
for (let i = 0; i < recs.length; i++) {
|
|
184
|
+
const rec = recs[i];
|
|
185
|
+
if (rec.type === RT_SLIDE_PERSIST_ATOM) {
|
|
186
|
+
flush();
|
|
187
|
+
pendingRef = rec.data.length >= 4 ? u32(rec.data, 0) : void 0;
|
|
188
|
+
} else if (rec.type === RT_TEXT_CHARS_ATOM || rec.type === RT_TEXT_BYTES_ATOM) outline.push(...styledParagraphs(rec, findFollowingStyle(recs, i)));
|
|
189
|
+
}
|
|
190
|
+
flush();
|
|
191
|
+
return slides;
|
|
192
|
+
}
|
|
193
|
+
function collectParagraphs(d, depth) {
|
|
194
|
+
if (depth > MAX_DEPTH) return [];
|
|
195
|
+
const out = [];
|
|
196
|
+
const recs = [...records(d)];
|
|
197
|
+
for (let i = 0; i < recs.length; i++) {
|
|
198
|
+
const rec = recs[i];
|
|
199
|
+
if (rec.type === RT_TEXT_CHARS_ATOM || rec.type === RT_TEXT_BYTES_ATOM) out.push(...styledParagraphs(rec, findFollowingStyle(recs, i)));
|
|
200
|
+
else if (rec.isContainer) out.push(...collectParagraphs(rec.data, depth + 1));
|
|
201
|
+
}
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
function findFollowingStyle(recs, i) {
|
|
205
|
+
for (let j = i + 1; j < recs.length; j++) {
|
|
206
|
+
const t = recs[j].type;
|
|
207
|
+
if (t === RT_STYLE_TEXT_PROP_ATOM) return recs[j].data;
|
|
208
|
+
if (t === RT_TEXT_CHARS_ATOM || t === RT_TEXT_BYTES_ATOM || t === RT_TEXT_HEADER_ATOM) break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function styledParagraphs(textRec, styleData) {
|
|
212
|
+
return buildStyledParagraphs(textRec.type === RT_TEXT_CHARS_ATOM ? decodeUtf16(textRec.data) : decodeCp1252(textRec.data), styleData);
|
|
213
|
+
}
|
|
214
|
+
function slidesByScan(stream, img) {
|
|
215
|
+
const slides = [];
|
|
216
|
+
collectSlides(stream, slides, img, 0);
|
|
217
|
+
return slides;
|
|
218
|
+
}
|
|
219
|
+
function collectSlides(d, out, img, depth) {
|
|
220
|
+
if (depth > MAX_DEPTH) return;
|
|
221
|
+
for (const rec of records(d)) if (rec.type === RT_SLIDE) out.push({ shapes: slideShapes(rec.data, img, [], resolveScheme(rec.data)) });
|
|
222
|
+
else if (rec.isContainer) collectSlides(rec.data, out, img, depth + 1);
|
|
223
|
+
}
|
|
224
|
+
function findChild(d, pred) {
|
|
225
|
+
for (const rec of records(d)) if (pred(rec)) return rec.data;
|
|
226
|
+
}
|
|
227
|
+
function findDocument(stream) {
|
|
228
|
+
for (const rec of records(stream)) if (rec.type === RT_DOCUMENT) return rec;
|
|
229
|
+
}
|
|
230
|
+
function findLastUserEdit(stream) {
|
|
231
|
+
let off = 0;
|
|
232
|
+
let last = 0;
|
|
233
|
+
while (off + 8 <= stream.length) {
|
|
234
|
+
const rec = recordAt(stream, off);
|
|
235
|
+
if (!rec) break;
|
|
236
|
+
if (rec.type === RT_USER_EDIT_ATOM) last = off;
|
|
237
|
+
const consumed = 8 + rec.data.length;
|
|
238
|
+
if (consumed <= 0) break;
|
|
239
|
+
off += consumed;
|
|
240
|
+
}
|
|
241
|
+
return last;
|
|
242
|
+
}
|
|
243
|
+
var MASTER_UNITS_PER_INCH = 576;
|
|
244
|
+
var POINTS_PER_INCH = 72;
|
|
245
|
+
function readSlideSize(docData) {
|
|
246
|
+
const atom = findChild(docData, (r) => r.type === RT_DOCUMENT_ATOM);
|
|
247
|
+
if (!atom || atom.length < 8) return void 0;
|
|
248
|
+
const cx = i32(atom, 0);
|
|
249
|
+
const cy = i32(atom, 4);
|
|
250
|
+
const toPt = (u) => u / MASTER_UNITS_PER_INCH * POINTS_PER_INCH;
|
|
251
|
+
const w = toPt(cx);
|
|
252
|
+
const h = toPt(cy);
|
|
253
|
+
if (w < 216 || w > 4320 || h < 216 || h > 4320) return void 0;
|
|
254
|
+
return {
|
|
255
|
+
slideWidthPt: w,
|
|
256
|
+
slideHeightPt: h
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function parseFbseStore(docData) {
|
|
260
|
+
const group = findChild(docData, (r) => r.type === RT_DRAWING_GROUP);
|
|
261
|
+
if (!group) return [];
|
|
262
|
+
const store = findDescendantContainer(group, FBT_BSTORE_CONTAINER, 0);
|
|
263
|
+
if (!store) return [];
|
|
264
|
+
const foDelays = [];
|
|
265
|
+
for (const r of records(store)) if (r.type === FBT_BSE) foDelays.push(r.data.length >= FBSE_FODELAY_OFFSET + 4 ? u32(r.data, FBSE_FODELAY_OFFSET) : 0);
|
|
266
|
+
return foDelays;
|
|
267
|
+
}
|
|
268
|
+
function findDescendantContainer(d, type, depth) {
|
|
269
|
+
if (depth > MAX_DEPTH) return void 0;
|
|
270
|
+
for (const r of records(d)) {
|
|
271
|
+
if (r.type === type) return r.data;
|
|
272
|
+
if (r.isContainer) {
|
|
273
|
+
const found = findDescendantContainer(r.data, type, depth + 1);
|
|
274
|
+
if (found) return found;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function collectShapes(slideData, img, scheme) {
|
|
279
|
+
const out = [];
|
|
280
|
+
collectShapeContainers(slideData, img, out, 0, scheme);
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
283
|
+
function collectShapeContainers(d, img, out, depth, scheme) {
|
|
284
|
+
if (depth > MAX_DEPTH) return;
|
|
285
|
+
for (const r of records(d)) if (r.type === FBT_SP_CONTAINER) {
|
|
286
|
+
let rectPt;
|
|
287
|
+
let paragraphs;
|
|
288
|
+
let pib;
|
|
289
|
+
let shapeType = 0;
|
|
290
|
+
let fspFlags = 0;
|
|
291
|
+
let fillColorHex;
|
|
292
|
+
let lineColorHex;
|
|
293
|
+
let geometry;
|
|
294
|
+
for (const child of records(r.data)) if (child.type === FBT_FSP) {
|
|
295
|
+
shapeType = child.instance;
|
|
296
|
+
fspFlags = child.data.length >= 8 ? u32(child.data, 4) : 0;
|
|
297
|
+
} else if (child.type === FBT_CLIENT_ANCHOR) rectPt = parseAnchor(child.data);
|
|
298
|
+
else if (child.type === FBT_CLIENT_TEXTBOX) paragraphs = collectParagraphs(child.data, 0);
|
|
299
|
+
else if (child.type === FBT_OPT) {
|
|
300
|
+
pib = optProperty(child.data, child.instance, PROP_PIB);
|
|
301
|
+
fillColorHex = optColor(child.data, child.instance, PROP_FILL_COLOR, scheme);
|
|
302
|
+
lineColorHex = optColor(child.data, child.instance, PROP_LINE_COLOR, scheme);
|
|
303
|
+
geometry = parseFreeformGeometry(child.data, child.instance);
|
|
304
|
+
}
|
|
305
|
+
let image;
|
|
306
|
+
if (pib !== void 0 && pib >= 1 && pib <= img.foDelays.length) {
|
|
307
|
+
const bytes = readBlipBytes(img.pictures, img.foDelays[pib - 1]);
|
|
308
|
+
if (bytes) image = { bytes };
|
|
309
|
+
}
|
|
310
|
+
const textParas = paragraphs && paragraphs.some((p) => paragraphText(p).length > 0) ? paragraphs : void 0;
|
|
311
|
+
const decorative = (fspFlags & (FSP_FLAG_PATRIARCH | 1025)) === 0;
|
|
312
|
+
const autoShape = !textParas && !image && rectPt && (shapeType > 0 || geometry) && decorative && (fillColorHex || lineColorHex) ? {
|
|
313
|
+
shapeType,
|
|
314
|
+
...fillColorHex ? { fillColorHex } : {},
|
|
315
|
+
...lineColorHex ? { lineColorHex } : {},
|
|
316
|
+
...geometry ? { geometry } : {}
|
|
317
|
+
} : void 0;
|
|
318
|
+
if (textParas || image || autoShape) out.push({
|
|
319
|
+
...rectPt ? { rectPt } : {},
|
|
320
|
+
...textParas ? { paragraphs: textParas } : {},
|
|
321
|
+
...image ? { image } : {},
|
|
322
|
+
...autoShape ? { autoShape } : {}
|
|
323
|
+
});
|
|
324
|
+
} else if (r.isContainer) collectShapeContainers(r.data, img, out, depth + 1, scheme);
|
|
325
|
+
}
|
|
326
|
+
function parseAnchor(data) {
|
|
327
|
+
let top;
|
|
328
|
+
let left;
|
|
329
|
+
let right;
|
|
330
|
+
let bottom;
|
|
331
|
+
if (data.length >= 16) {
|
|
332
|
+
top = i32(data, 0);
|
|
333
|
+
left = i32(data, 4);
|
|
334
|
+
right = i32(data, 8);
|
|
335
|
+
bottom = i32(data, 12);
|
|
336
|
+
} else if (data.length >= 8) {
|
|
337
|
+
top = i16(data, 0);
|
|
338
|
+
left = i16(data, 2);
|
|
339
|
+
right = i16(data, 4);
|
|
340
|
+
bottom = i16(data, 6);
|
|
341
|
+
} else return;
|
|
342
|
+
const x = left / 8;
|
|
343
|
+
const y = top / 8;
|
|
344
|
+
const w = (right - left) / 8;
|
|
345
|
+
const h = (bottom - top) / 8;
|
|
346
|
+
if (!(w > 0 && h > 0) || w > 5e3 || h > 5e3 || Math.abs(x) > 5e3 || Math.abs(y) > 5e3) return;
|
|
347
|
+
return {
|
|
348
|
+
x,
|
|
349
|
+
y,
|
|
350
|
+
w,
|
|
351
|
+
h
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function optProperty(d, count, wantId) {
|
|
355
|
+
for (let i = 0; i < count && i * 6 + 6 <= d.length; i++) {
|
|
356
|
+
const id = u16(d, i * 6);
|
|
357
|
+
if ((id & 16383) === wantId && (id & 32768) === 0) return u32(d, i * 6 + 2);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function optComplex(d, count, wantId) {
|
|
361
|
+
let offset = count * 6;
|
|
362
|
+
for (let i = 0; i < count && i * 6 + 6 <= d.length; i++) {
|
|
363
|
+
const id = u16(d, i * 6);
|
|
364
|
+
if ((id & 32768) === 0) continue;
|
|
365
|
+
const len = u32(d, i * 6 + 2);
|
|
366
|
+
if ((id & 16383) === wantId) return offset + len <= d.length && len > 0 ? d.subarray(offset, offset + len) : void 0;
|
|
367
|
+
offset += len;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function arrayHeader(blob) {
|
|
371
|
+
if (blob.length < 6) return void 0;
|
|
372
|
+
const raw = u16(blob, 4);
|
|
373
|
+
const signed = raw >= 32768 ? raw - 65536 : raw;
|
|
374
|
+
const size = signed < 0 ? -signed >> 2 : signed;
|
|
375
|
+
if (size <= 0) return void 0;
|
|
376
|
+
return {
|
|
377
|
+
count: u16(blob, 0),
|
|
378
|
+
size,
|
|
379
|
+
base: 6
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function signedLong(v) {
|
|
383
|
+
return v === void 0 ? void 0 : v >= 2147483648 ? v - 4294967296 : v;
|
|
384
|
+
}
|
|
385
|
+
var MAX_PATH_ELEMS = 2e4;
|
|
386
|
+
function parseFreeformGeometry(d, count) {
|
|
387
|
+
const vBlob = optComplex(d, count, PROP_VERTICES);
|
|
388
|
+
const sBlob = optComplex(d, count, PROP_SEGMENT_INFO);
|
|
389
|
+
if (!vBlob || !sBlob) return void 0;
|
|
390
|
+
const vh = arrayHeader(vBlob);
|
|
391
|
+
if (!vh || vh.count > MAX_PATH_ELEMS) return void 0;
|
|
392
|
+
const verts = [];
|
|
393
|
+
for (let i = 0; i < vh.count; i++) {
|
|
394
|
+
const off = vh.base + i * vh.size;
|
|
395
|
+
if (off + vh.size > vBlob.length) break;
|
|
396
|
+
if (vh.size >= 8) verts.push({
|
|
397
|
+
x: i32(vBlob, off),
|
|
398
|
+
y: i32(vBlob, off + 4)
|
|
399
|
+
});
|
|
400
|
+
else if (vh.size >= 4) verts.push({
|
|
401
|
+
x: i16(vBlob, off),
|
|
402
|
+
y: i16(vBlob, off + 2)
|
|
403
|
+
});
|
|
404
|
+
else return void 0;
|
|
405
|
+
}
|
|
406
|
+
if (verts.length === 0) return void 0;
|
|
407
|
+
const sh = arrayHeader(sBlob);
|
|
408
|
+
if (!sh || sh.size < 2 || sh.count > MAX_PATH_ELEMS) return void 0;
|
|
409
|
+
let minX = Infinity;
|
|
410
|
+
let minY = Infinity;
|
|
411
|
+
let maxX = -Infinity;
|
|
412
|
+
let maxY = -Infinity;
|
|
413
|
+
for (const v of verts) {
|
|
414
|
+
if (v.x < minX) minX = v.x;
|
|
415
|
+
if (v.x > maxX) maxX = v.x;
|
|
416
|
+
if (v.y < minY) minY = v.y;
|
|
417
|
+
if (v.y > maxY) maxY = v.y;
|
|
418
|
+
}
|
|
419
|
+
const left = signedLong(optProperty(d, count, PROP_GEO_LEFT)) ?? minX;
|
|
420
|
+
const top = signedLong(optProperty(d, count, PROP_GEO_TOP)) ?? minY;
|
|
421
|
+
const right = signedLong(optProperty(d, count, PROP_GEO_RIGHT)) ?? maxX;
|
|
422
|
+
const bottom = signedLong(optProperty(d, count, PROP_GEO_BOTTOM)) ?? maxY;
|
|
423
|
+
const pathWidth = right - left;
|
|
424
|
+
const pathHeight = bottom - top;
|
|
425
|
+
if (!(pathWidth > 0) || !(pathHeight > 0) || pathWidth > 1e7 || pathHeight > 1e7) return void 0;
|
|
426
|
+
const commands = [];
|
|
427
|
+
let vi = 0;
|
|
428
|
+
let drew = false;
|
|
429
|
+
for (let i = 0; i < sh.count; i++) {
|
|
430
|
+
const off = sh.base + i * sh.size;
|
|
431
|
+
if (off + 2 > sBlob.length) break;
|
|
432
|
+
const type = u16(sBlob, off) >> 13 & 7;
|
|
433
|
+
if (type === 2) {
|
|
434
|
+
const v = verts[vi++];
|
|
435
|
+
if (!v) break;
|
|
436
|
+
commands.push({
|
|
437
|
+
kind: "move",
|
|
438
|
+
x: v.x - left,
|
|
439
|
+
y: v.y - top
|
|
440
|
+
});
|
|
441
|
+
} else if (type === 0) {
|
|
442
|
+
const v = verts[vi++];
|
|
443
|
+
if (!v) break;
|
|
444
|
+
commands.push({
|
|
445
|
+
kind: "line",
|
|
446
|
+
x: v.x - left,
|
|
447
|
+
y: v.y - top
|
|
448
|
+
});
|
|
449
|
+
drew = true;
|
|
450
|
+
} else if (type === 1) {
|
|
451
|
+
const c1 = verts[vi++];
|
|
452
|
+
const c2 = verts[vi++];
|
|
453
|
+
const e = verts[vi++];
|
|
454
|
+
if (!c1 || !c2 || !e) break;
|
|
455
|
+
commands.push({
|
|
456
|
+
kind: "cubic",
|
|
457
|
+
x1: c1.x - left,
|
|
458
|
+
y1: c1.y - top,
|
|
459
|
+
x2: c2.x - left,
|
|
460
|
+
y2: c2.y - top,
|
|
461
|
+
x: e.x - left,
|
|
462
|
+
y: e.y - top
|
|
463
|
+
});
|
|
464
|
+
drew = true;
|
|
465
|
+
} else if (type === 3) commands.push({ kind: "close" });
|
|
466
|
+
else if (type === 4) break;
|
|
467
|
+
else if (type === 5) {
|
|
468
|
+
if ((u16(sBlob, off) >> 8 & 31) < 10) return void 0;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return drew ? {
|
|
472
|
+
pathWidth,
|
|
473
|
+
pathHeight,
|
|
474
|
+
commands
|
|
475
|
+
} : void 0;
|
|
476
|
+
}
|
|
477
|
+
var SYS_COLORS = new Map([
|
|
478
|
+
[5, "FFFFFF"],
|
|
479
|
+
[6, "000000"],
|
|
480
|
+
[7, "000000"],
|
|
481
|
+
[8, "000000"],
|
|
482
|
+
[13, "0078D7"],
|
|
483
|
+
[14, "FFFFFF"],
|
|
484
|
+
[15, "F0F0F0"],
|
|
485
|
+
[16, "A0A0A0"],
|
|
486
|
+
[18, "000000"],
|
|
487
|
+
[20, "FFFFFF"],
|
|
488
|
+
[23, "000000"],
|
|
489
|
+
[24, "FFFFE1"]
|
|
490
|
+
]);
|
|
491
|
+
function optColor(d, count, wantId, scheme) {
|
|
492
|
+
const v = optProperty(d, count, wantId);
|
|
493
|
+
if (v === void 0) return void 0;
|
|
494
|
+
const flags = v >>> 24;
|
|
495
|
+
if (flags === 0) return `${hex2(v & 255)}${hex2(v >> 8 & 255)}${hex2(v >> 16 & 255)}`;
|
|
496
|
+
if (flags === COLORREF_SCHEME_INDEX && scheme) {
|
|
497
|
+
const idx = v & 255;
|
|
498
|
+
if (idx < scheme.length) return scheme[idx];
|
|
499
|
+
}
|
|
500
|
+
if (flags === COLORREF_SYS_INDEX) return SYS_COLORS.get(v & 65535);
|
|
501
|
+
}
|
|
502
|
+
function resolveScheme(slideData, persist, stream) {
|
|
503
|
+
let schemeData = findColorScheme(slideData);
|
|
504
|
+
const slideAtom = findChild(slideData, (r) => r.type === RT_SLIDE_ATOM);
|
|
505
|
+
if (slideAtom && slideAtom.length >= 22 && persist && stream) {
|
|
506
|
+
if ((u16(slideAtom, 20) & SLIDE_FLAG_MASTER_SCHEME) !== 0) {
|
|
507
|
+
const masterOff = persist.get(u32(slideAtom, 12));
|
|
508
|
+
const masterRec = masterOff !== void 0 ? recordAt(stream, masterOff) : void 0;
|
|
509
|
+
if (masterRec && masterRec.type === RT_MAIN_MASTER) {
|
|
510
|
+
const masterScheme = findColorScheme(masterRec.data);
|
|
511
|
+
if (masterScheme) schemeData = masterScheme;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return schemeData ? parseColorScheme(schemeData) : void 0;
|
|
516
|
+
}
|
|
517
|
+
function findColorScheme(containerData) {
|
|
518
|
+
return findChild(containerData, (r) => r.type === RT_COLOR_SCHEME_ATOM && r.instance === COLOR_SCHEME_INSTANCE);
|
|
519
|
+
}
|
|
520
|
+
function parseColorScheme(d) {
|
|
521
|
+
if (d.length < 32) return void 0;
|
|
522
|
+
const colors = [];
|
|
523
|
+
for (let i = 0; i < 8; i++) {
|
|
524
|
+
const o = i * 4;
|
|
525
|
+
colors.push(`${hex2(d[o])}${hex2(d[o + 1])}${hex2(d[o + 2])}`);
|
|
526
|
+
}
|
|
527
|
+
return colors;
|
|
528
|
+
}
|
|
529
|
+
function readBlipBytes(pictures, foDelay) {
|
|
530
|
+
if (foDelay < 0 || foDelay + 8 > pictures.length) return void 0;
|
|
531
|
+
const recLen = u32(pictures, foDelay + 4);
|
|
532
|
+
const start = foDelay + 8;
|
|
533
|
+
const blip = pictures.subarray(start, Math.min(pictures.length, start + recLen));
|
|
534
|
+
const limit = Math.min(blip.length, 80);
|
|
535
|
+
for (let off = 0; off < limit; off++) for (const magic of IMAGE_MAGICS) if (matchesMagic(blip, off, magic)) return blip.subarray(off);
|
|
536
|
+
}
|
|
537
|
+
var IMAGE_MAGICS = [[
|
|
538
|
+
137,
|
|
539
|
+
80,
|
|
540
|
+
78,
|
|
541
|
+
71
|
|
542
|
+
], [
|
|
543
|
+
255,
|
|
544
|
+
216,
|
|
545
|
+
255
|
|
546
|
+
]];
|
|
547
|
+
function matchesMagic(d, off, magic) {
|
|
548
|
+
if (off + magic.length > d.length) return false;
|
|
549
|
+
for (let i = 0; i < magic.length; i++) if (d[off + i] !== magic[i]) return false;
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
function paragraphText(p) {
|
|
553
|
+
return p.runs.map((r) => r.text).join("");
|
|
554
|
+
}
|
|
555
|
+
function buildStyledParagraphs(text, styleData) {
|
|
556
|
+
const style = styleData ? parseStyleTextProp(styleData, text.length) : void 0;
|
|
557
|
+
const charProps = style ? expandCharProps(style.charRuns, text.length) : void 0;
|
|
558
|
+
const paraRuns = style?.paraRuns ?? [];
|
|
559
|
+
const paras = [];
|
|
560
|
+
let runs = [];
|
|
561
|
+
let cur = "";
|
|
562
|
+
let curProps;
|
|
563
|
+
let paraIndex = 0;
|
|
564
|
+
const pushRun = () => {
|
|
565
|
+
if (cur.length > 0) runs.push(toRun(cur, curProps));
|
|
566
|
+
cur = "";
|
|
567
|
+
};
|
|
568
|
+
const endParagraph = () => {
|
|
569
|
+
pushRun();
|
|
570
|
+
const meta = paraRuns[paraIndex];
|
|
571
|
+
paras.push({
|
|
572
|
+
runs,
|
|
573
|
+
...meta?.align !== void 0 ? { align: meta.align } : {},
|
|
574
|
+
...meta?.level !== void 0 ? { level: meta.level } : {}
|
|
575
|
+
});
|
|
576
|
+
runs = [];
|
|
577
|
+
paraIndex++;
|
|
578
|
+
};
|
|
579
|
+
for (let i = 0; i < text.length; i++) {
|
|
580
|
+
const c = text.charCodeAt(i);
|
|
581
|
+
if (c === 13) {
|
|
582
|
+
endParagraph();
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
const props = charProps?.[i];
|
|
586
|
+
if (cur.length > 0 && !sameProps(props, curProps)) pushRun();
|
|
587
|
+
if (cur.length === 0) curProps = props;
|
|
588
|
+
if (c === 11 || c === 10 || c === 9) cur += " ";
|
|
589
|
+
else if (c !== 65279 && c >= 32) cur += text[i];
|
|
590
|
+
}
|
|
591
|
+
endParagraph();
|
|
592
|
+
if (paras.length > 1 && paragraphText(paras[paras.length - 1]).length === 0) paras.pop();
|
|
593
|
+
return paras;
|
|
594
|
+
}
|
|
595
|
+
function toRun(text, props) {
|
|
596
|
+
if (!props) return { text };
|
|
597
|
+
return {
|
|
598
|
+
text,
|
|
599
|
+
...props.bold ? { bold: true } : {},
|
|
600
|
+
...props.italic ? { italic: true } : {},
|
|
601
|
+
...props.underline ? { underline: true } : {},
|
|
602
|
+
...props.sizePt ? { sizePt: props.sizePt } : {},
|
|
603
|
+
...props.colorHex ? { colorHex: props.colorHex } : {}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function sameProps(a, b) {
|
|
607
|
+
if (a === b) return true;
|
|
608
|
+
if (!a || !b) return false;
|
|
609
|
+
return !!a.bold === !!b.bold && !!a.italic === !!b.italic && !!a.underline === !!b.underline && a.sizePt === b.sizePt && a.colorHex === b.colorHex;
|
|
610
|
+
}
|
|
611
|
+
function expandCharProps(charRuns, textLen) {
|
|
612
|
+
const out = [];
|
|
613
|
+
for (const run of charRuns) for (let i = 0; i < run.count && out.length < textLen; i++) out.push(run);
|
|
614
|
+
while (out.length < textLen) out.push(charRuns[charRuns.length - 1] ?? { count: 0 });
|
|
615
|
+
return out;
|
|
616
|
+
}
|
|
617
|
+
function parseStyleTextProp(data, textLen) {
|
|
618
|
+
const target = textLen + 1;
|
|
619
|
+
let off = 0;
|
|
620
|
+
const paraRuns = [];
|
|
621
|
+
let consumed = 0;
|
|
622
|
+
while (consumed < target && off + 10 <= data.length) {
|
|
623
|
+
const count = u32(data, off);
|
|
624
|
+
const level = u16(data, off + 4);
|
|
625
|
+
const mask = u32(data, off + 6);
|
|
626
|
+
off += 10;
|
|
627
|
+
let align;
|
|
628
|
+
if ((mask & 15) !== 0) off += 2;
|
|
629
|
+
if ((mask & 128) !== 0) off += 2;
|
|
630
|
+
if ((mask & 16) !== 0) off += 2;
|
|
631
|
+
if ((mask & 64) !== 0) off += 2;
|
|
632
|
+
if ((mask & 32) !== 0) off += 4;
|
|
633
|
+
if ((mask & 2048) !== 0) {
|
|
634
|
+
align = u16(data, off);
|
|
635
|
+
off += 2;
|
|
636
|
+
}
|
|
637
|
+
if ((mask & 4096) !== 0) off += 2;
|
|
638
|
+
if ((mask & 8192) !== 0) off += 2;
|
|
639
|
+
if ((mask & 16384) !== 0) off += 2;
|
|
640
|
+
if ((mask & 256) !== 0) off += 2;
|
|
641
|
+
if ((mask & 1024) !== 0) off += 2;
|
|
642
|
+
if ((mask & 32768) !== 0) off += 2;
|
|
643
|
+
if ((mask & 1048576) !== 0) off += 2 + (off + 2 <= data.length ? u16(data, off) : 0) * 4;
|
|
644
|
+
if ((mask & 65536) !== 0) off += 2;
|
|
645
|
+
if ((mask & 917504) !== 0) off += 2;
|
|
646
|
+
if ((mask & 2097152) !== 0) off += 2;
|
|
647
|
+
paraRuns.push({
|
|
648
|
+
count,
|
|
649
|
+
level,
|
|
650
|
+
...align !== void 0 ? { align } : {}
|
|
651
|
+
});
|
|
652
|
+
consumed += count;
|
|
653
|
+
if (count <= 0) break;
|
|
654
|
+
}
|
|
655
|
+
const charRuns = [];
|
|
656
|
+
consumed = 0;
|
|
657
|
+
while (consumed < target && off + 8 <= data.length) {
|
|
658
|
+
const count = u32(data, off);
|
|
659
|
+
const mask = u32(data, off + 4);
|
|
660
|
+
off += 8;
|
|
661
|
+
const run = { count };
|
|
662
|
+
if ((mask & 16055) !== 0) {
|
|
663
|
+
const style = u16(data, off);
|
|
664
|
+
off += 2;
|
|
665
|
+
if ((mask & 1) !== 0 && (style & 1) !== 0) run.bold = true;
|
|
666
|
+
if ((mask & 2) !== 0 && (style & 2) !== 0) run.italic = true;
|
|
667
|
+
if ((mask & 4) !== 0 && (style & 4) !== 0) run.underline = true;
|
|
668
|
+
}
|
|
669
|
+
if ((mask & 65536) !== 0) off += 2;
|
|
670
|
+
if ((mask & 2097152) !== 0) off += 2;
|
|
671
|
+
if ((mask & 4194304) !== 0) off += 2;
|
|
672
|
+
if ((mask & 8388608) !== 0) off += 2;
|
|
673
|
+
if ((mask & 131072) !== 0) {
|
|
674
|
+
const sz = u16(data, off);
|
|
675
|
+
off += 2;
|
|
676
|
+
if (sz > 0) run.sizePt = sz;
|
|
677
|
+
}
|
|
678
|
+
if ((mask & 262144) !== 0) {
|
|
679
|
+
if (off + 4 <= data.length && data[off + 3] === 254) run.colorHex = hex2(data[off]) + hex2(data[off + 1]) + hex2(data[off + 2]);
|
|
680
|
+
off += 4;
|
|
681
|
+
}
|
|
682
|
+
if ((mask & 524288) !== 0) off += 2;
|
|
683
|
+
charRuns.push(run);
|
|
684
|
+
consumed += count;
|
|
685
|
+
if (count <= 0) break;
|
|
686
|
+
}
|
|
687
|
+
return paraRuns.length > 0 || charRuns.length > 0 ? {
|
|
688
|
+
paraRuns,
|
|
689
|
+
charRuns
|
|
690
|
+
} : void 0;
|
|
691
|
+
}
|
|
692
|
+
function hex2(n) {
|
|
693
|
+
return n.toString(16).padStart(2, "0").toUpperCase();
|
|
694
|
+
}
|
|
695
|
+
function decodeUtf16(d) {
|
|
696
|
+
let out = "";
|
|
697
|
+
for (let i = 0; i + 1 < d.length; i += 2) out += String.fromCharCode(d[i] | d[i + 1] << 8);
|
|
698
|
+
return out;
|
|
699
|
+
}
|
|
700
|
+
var CP1252_HIGH = [
|
|
701
|
+
8364,
|
|
702
|
+
129,
|
|
703
|
+
8218,
|
|
704
|
+
402,
|
|
705
|
+
8222,
|
|
706
|
+
8230,
|
|
707
|
+
8224,
|
|
708
|
+
8225,
|
|
709
|
+
710,
|
|
710
|
+
8240,
|
|
711
|
+
352,
|
|
712
|
+
8249,
|
|
713
|
+
338,
|
|
714
|
+
141,
|
|
715
|
+
381,
|
|
716
|
+
143,
|
|
717
|
+
144,
|
|
718
|
+
8216,
|
|
719
|
+
8217,
|
|
720
|
+
8220,
|
|
721
|
+
8221,
|
|
722
|
+
8226,
|
|
723
|
+
8211,
|
|
724
|
+
8212,
|
|
725
|
+
732,
|
|
726
|
+
8482,
|
|
727
|
+
353,
|
|
728
|
+
8250,
|
|
729
|
+
339,
|
|
730
|
+
157,
|
|
731
|
+
382,
|
|
732
|
+
376
|
|
733
|
+
];
|
|
734
|
+
function decodeCp1252(d) {
|
|
735
|
+
let out = "";
|
|
736
|
+
for (let i = 0; i < d.length; i++) {
|
|
737
|
+
const c = d[i];
|
|
738
|
+
out += String.fromCharCode(c >= 128 && c <= 159 ? CP1252_HIGH[c - 128] : c);
|
|
739
|
+
}
|
|
740
|
+
return out;
|
|
741
|
+
}
|
|
742
|
+
function u16(d, off) {
|
|
743
|
+
return (d[off] ?? 0) | (d[off + 1] ?? 0) << 8;
|
|
744
|
+
}
|
|
745
|
+
function u32(d, off) {
|
|
746
|
+
return ((d[off] ?? 0) | (d[off + 1] ?? 0) << 8 | (d[off + 2] ?? 0) << 16 | (d[off + 3] ?? 0) << 24) >>> 0;
|
|
747
|
+
}
|
|
748
|
+
function i32(d, off) {
|
|
749
|
+
return u32(d, off) | 0;
|
|
750
|
+
}
|
|
751
|
+
function i16(d, off) {
|
|
752
|
+
const v = u16(d, off);
|
|
753
|
+
return v >= 32768 ? v - 65536 : v;
|
|
754
|
+
}
|
|
755
|
+
//#endregion
|
|
756
|
+
export { extractPptContent, paragraphText };
|