xls-codec 4.7.6 → 4.8.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 +7 -2
- package/dist/biff/record-types.cjs +21 -0
- package/dist/biff/record-types.d.cts +15 -1
- package/dist/biff/record-types.d.ts +15 -1
- package/dist/biff/record-types.js +15 -1
- package/dist/biff/substreams.cjs +7 -8
- package/dist/biff/substreams.d.cts +1 -1
- package/dist/biff/substreams.d.ts +1 -1
- package/dist/biff/substreams.js +7 -8
- package/dist/{conditional-format-12-DBhe7Zo6.d.cts → conditional-format-12-CZ43-CR4.d.cts} +2 -2
- package/dist/{conditional-format-12-D-X5g_O3.d.ts → conditional-format-12-Xl52VBCj.d.ts} +2 -2
- package/dist/{conditional-format-Czh2oTzQ.d.cts → conditional-format-Bt1vRWgc.d.cts} +1 -1
- package/dist/{conditional-format-DOdazxWe.d.ts → conditional-format-Cqcjnm7O.d.ts} +1 -1
- package/dist/content.cjs +40 -18
- package/dist/content.js +40 -18
- package/dist/{data-validation-BXvIVU0e.d.ts → data-validation-BeYpL3Nb.d.ts} +1 -1
- package/dist/{data-validation-DfpjUN-N.d.cts → data-validation-lJWM9-AP.d.cts} +1 -1
- package/dist/drawing/blips.cjs +83 -0
- package/dist/drawing/blips.d.cts +10 -0
- package/dist/drawing/blips.d.ts +10 -0
- package/dist/drawing/blips.js +82 -0
- package/dist/drawing/bytes.cjs +15 -0
- package/dist/drawing/bytes.d.cts +5 -0
- package/dist/drawing/bytes.d.ts +5 -0
- package/dist/drawing/bytes.js +14 -0
- package/dist/drawing/escher-constants.cjs +52 -0
- package/dist/drawing/escher-constants.d.cts +34 -0
- package/dist/drawing/escher-constants.d.ts +34 -0
- package/dist/drawing/escher-constants.js +34 -0
- package/dist/drawing/escher.cjs +84 -0
- package/dist/drawing/escher.d.cts +30 -0
- package/dist/drawing/escher.d.ts +30 -0
- package/dist/drawing/escher.js +80 -0
- package/dist/drawing/shapes.cjs +80 -0
- package/dist/drawing/shapes.d.cts +24 -0
- package/dist/drawing/shapes.d.ts +24 -0
- package/dist/drawing/shapes.js +79 -0
- package/dist/index.cjs +10 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/{print-names-CCwUHAoL.d.cts → print-names-B2OR0fvs.d.cts} +1 -1
- package/dist/{print-names-CxAbgcjB.d.ts → print-names-BXcmmwVi.d.ts} +1 -1
- package/dist/{substreams-Dp5cZoUo.d.ts → substreams-CgTHx5kX.d.ts} +1 -1
- package/dist/{substreams-CHv3oWmn.d.cts → substreams-XDNgDvRJ.d.cts} +1 -1
- package/dist/units.cjs +7 -0
- package/dist/units.d.cts +6 -1
- package/dist/units.d.ts +6 -1
- package/dist/units.js +6 -1
- package/dist/workbook/chart.cjs +230 -0
- package/dist/workbook/chart.d.cts +19 -0
- package/dist/workbook/chart.d.ts +19 -0
- package/dist/workbook/chart.js +229 -0
- package/dist/workbook/comments.cjs +2 -1
- package/dist/workbook/comments.d.cts +7 -2
- package/dist/workbook/comments.d.ts +7 -2
- package/dist/workbook/comments.js +2 -2
- package/dist/workbook/conditional-format-12.d.cts +1 -1
- package/dist/workbook/conditional-format-12.d.ts +1 -1
- package/dist/workbook/conditional-format.d.cts +1 -1
- package/dist/workbook/conditional-format.d.ts +1 -1
- package/dist/workbook/data-validation.d.cts +1 -1
- package/dist/workbook/data-validation.d.ts +1 -1
- package/dist/workbook/drawing.cjs +270 -0
- package/dist/workbook/drawing.d.cts +31 -0
- package/dist/workbook/drawing.d.ts +31 -0
- package/dist/workbook/drawing.js +268 -0
- package/dist/workbook/globals-writer.d.cts +1 -1
- package/dist/workbook/globals-writer.d.ts +1 -1
- package/dist/workbook/globals.d.cts +2 -2
- package/dist/workbook/globals.d.ts +2 -2
- package/dist/workbook/print-names.d.cts +1 -1
- package/dist/workbook/print-names.d.ts +1 -1
- package/dist/workbook/sheet-writer.cjs +1 -1
- package/dist/workbook/sheet-writer.js +1 -1
- package/dist/workbook/sheet.d.cts +4 -4
- package/dist/workbook/sheet.d.ts +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_biff_cursor = require("../biff/cursor.cjs");
|
|
3
|
+
const require_drawing_escher_constants = require("./escher-constants.cjs");
|
|
4
|
+
const require_drawing_escher = require("./escher.cjs");
|
|
5
|
+
//#region src/drawing/blips.ts
|
|
6
|
+
const RGB_UID_SIZE = 16;
|
|
7
|
+
const BLIP_TAG_SIZE = 1;
|
|
8
|
+
/** [MS-ODRAW] OfficeArtFBSE's own fixed fields up to and including unused3, before the optional nameData and the nested embedded blip -- btWin32(1) + btMacOS(1) + rgbUid(16) + tag(2) + size(4) + cRef(4) + foDelay(4) + unused1(1) + cbName(1) + unused2(1) + unused3(1). */
|
|
9
|
+
const BSE_FIXED_SIZE = 36;
|
|
10
|
+
/** A Blip record's own recInstance, mapped to how many 16-byte rgbUid fields precede its `tag` byte and the raw file bytes -- one UID for a blip embedded once, two when [MS-ODRAW] also records a second, "printer" representation's own hash. Only PNG/JPEG instances are named: every other blip type resolves to no image at all (see readBlipImage), so its own UID count is never needed. */
|
|
11
|
+
const BLIP_UID_COUNTS = /* @__PURE__ */ new Map([
|
|
12
|
+
[1760, 1],
|
|
13
|
+
[1761, 2],
|
|
14
|
+
[1130, 1],
|
|
15
|
+
[1131, 2],
|
|
16
|
+
[1762, 1],
|
|
17
|
+
[1763, 2]
|
|
18
|
+
]);
|
|
19
|
+
/** Reads every BSE entry the workbook's own drawing-group Escher stream declares, keyed by its 1-based position in the Blip Store array -- the same index a picture shape's `pib` property names. A BSE this reader cannot turn into a real image (no embedded blip, or a blip type document-schema.js's ContentImageBlockSchema has no lossless slot for -- DIB, EMF, WMF, PICT, TIFF) is simply absent from the map, exactly like any other unsupported construct elsewhere in this package: a picture shape whose `pib` resolves to one of these is recognised as a picture but produces no ContentSheetImage, rather than a fabricated or mistranscoded one. */
|
|
20
|
+
function readBlipStore(drawingGroupBytes) {
|
|
21
|
+
const store = /* @__PURE__ */ new Map();
|
|
22
|
+
if (drawingGroupBytes.length === 0) return store;
|
|
23
|
+
const dgg = require_drawing_escher.readEscherRecords(drawingGroupBytes).find((record) => record.kind === "container" && record.recType === 61440);
|
|
24
|
+
if (dgg === void 0) return store;
|
|
25
|
+
const bstore = require_drawing_escher.childrenOfType(dgg, require_drawing_escher_constants.ESCHER_BSTORE_CONTAINER)[0];
|
|
26
|
+
if (bstore?.kind !== "container") return store;
|
|
27
|
+
require_drawing_escher.childrenOfType(bstore, require_drawing_escher_constants.ESCHER_BSE).forEach((bse, index) => {
|
|
28
|
+
if (bse.kind !== "atom") return;
|
|
29
|
+
const image = readBseImage(bse.data);
|
|
30
|
+
if (image !== void 0) store.set(index + 1, image);
|
|
31
|
+
});
|
|
32
|
+
return store;
|
|
33
|
+
}
|
|
34
|
+
/** One BSE atom's own body ([MS-ODRAW] OfficeArtFBSE): the fixed fields, an optional nameData string, then the nested embedded blip record -- present whenever the image is stored inline rather than only linked externally (foDelay !== 0xFFFFFFFF), which is the only case this reader can recover bytes for at all. */
|
|
35
|
+
function readBseImage(data) {
|
|
36
|
+
if (data.length < BSE_FIXED_SIZE) return;
|
|
37
|
+
const cursor = new require_biff_cursor.BlockCursor([data]);
|
|
38
|
+
cursor.skip(1);
|
|
39
|
+
cursor.skip(1);
|
|
40
|
+
cursor.skip(RGB_UID_SIZE);
|
|
41
|
+
cursor.skip(2);
|
|
42
|
+
cursor.skip(4);
|
|
43
|
+
cursor.skip(4);
|
|
44
|
+
cursor.skip(4);
|
|
45
|
+
cursor.skip(1);
|
|
46
|
+
const cbName = cursor.u8();
|
|
47
|
+
cursor.skip(1);
|
|
48
|
+
cursor.skip(1);
|
|
49
|
+
const embeddedStart = BSE_FIXED_SIZE + (cbName > 0 ? cbName : 0);
|
|
50
|
+
if (embeddedStart >= data.length) return;
|
|
51
|
+
const embeddedBytes = data.subarray(embeddedStart);
|
|
52
|
+
const blip = require_drawing_escher.readEscherRecords(embeddedBytes)[0];
|
|
53
|
+
if (blip?.kind !== "atom") return;
|
|
54
|
+
return readBlipImage(blip.recType, blip.recInstance, blip.data);
|
|
55
|
+
}
|
|
56
|
+
/** One embedded OfficeArtBlip record's own body -- one or two 16-byte rgbUid fields, a one-byte tag, then the literal image file bytes to the end of the record. PNG and JPEG blips carry their literal file bytes verbatim ([MS-ODRAW] OfficeArtBlipPNG/OfficeArtBlipJPEG); every other recognised blip type (DIB -- an in-memory Windows DIB, not a standalone .bmp file, and carrying no BITMAPFILEHEADER of its own to become one) has no lossless target in document-schema.js's ContentImageBlockSchema (png/jpeg/svg/gif only) and resolves to undefined rather than a mistranscoded image. */
|
|
57
|
+
function readBlipImage(recType, recInstance, data) {
|
|
58
|
+
const format = blipFormatOf(recType);
|
|
59
|
+
if (format === void 0) return;
|
|
60
|
+
const uidCount = BLIP_UID_COUNTS.get(recInstance);
|
|
61
|
+
if (uidCount === void 0) return;
|
|
62
|
+
const headerSize = uidCount * RGB_UID_SIZE + BLIP_TAG_SIZE;
|
|
63
|
+
if (data.length < headerSize) return;
|
|
64
|
+
return {
|
|
65
|
+
format,
|
|
66
|
+
base64: bytesToBase64(data.subarray(headerSize))
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function blipFormatOf(recType) {
|
|
70
|
+
if (recType === 61470) return "png";
|
|
71
|
+
if (recType === 61469 || recType === 61482) return "jpeg";
|
|
72
|
+
}
|
|
73
|
+
function bytesToBase64(bytes) {
|
|
74
|
+
let binary = "";
|
|
75
|
+
const chunkSize = 32768;
|
|
76
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) {
|
|
77
|
+
const chunk = bytes.subarray(offset, offset + chunkSize);
|
|
78
|
+
binary += String.fromCharCode(...chunk);
|
|
79
|
+
}
|
|
80
|
+
return btoa(binary);
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
exports.readBlipStore = readBlipStore;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/drawing/blips.d.ts
|
|
2
|
+
/** One resolved image: the bytes document-schema.js's ContentImageBlockSchema can actually carry (png/jpeg only -- see readBlipImage below), base64-encoded. */
|
|
3
|
+
interface BlipImage {
|
|
4
|
+
readonly format: "png" | "jpeg";
|
|
5
|
+
readonly base64: string;
|
|
6
|
+
}
|
|
7
|
+
/** Reads every BSE entry the workbook's own drawing-group Escher stream declares, keyed by its 1-based position in the Blip Store array -- the same index a picture shape's `pib` property names. A BSE this reader cannot turn into a real image (no embedded blip, or a blip type document-schema.js's ContentImageBlockSchema has no lossless slot for -- DIB, EMF, WMF, PICT, TIFF) is simply absent from the map, exactly like any other unsupported construct elsewhere in this package: a picture shape whose `pib` resolves to one of these is recognised as a picture but produces no ContentSheetImage, rather than a fabricated or mistranscoded one. */
|
|
8
|
+
declare function readBlipStore(drawingGroupBytes: Uint8Array<ArrayBuffer>): ReadonlyMap<number, BlipImage>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { BlipImage, readBlipStore };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/drawing/blips.d.ts
|
|
2
|
+
/** One resolved image: the bytes document-schema.js's ContentImageBlockSchema can actually carry (png/jpeg only -- see readBlipImage below), base64-encoded. */
|
|
3
|
+
interface BlipImage {
|
|
4
|
+
readonly format: "png" | "jpeg";
|
|
5
|
+
readonly base64: string;
|
|
6
|
+
}
|
|
7
|
+
/** Reads every BSE entry the workbook's own drawing-group Escher stream declares, keyed by its 1-based position in the Blip Store array -- the same index a picture shape's `pib` property names. A BSE this reader cannot turn into a real image (no embedded blip, or a blip type document-schema.js's ContentImageBlockSchema has no lossless slot for -- DIB, EMF, WMF, PICT, TIFF) is simply absent from the map, exactly like any other unsupported construct elsewhere in this package: a picture shape whose `pib` resolves to one of these is recognised as a picture but produces no ContentSheetImage, rather than a fabricated or mistranscoded one. */
|
|
8
|
+
declare function readBlipStore(drawingGroupBytes: Uint8Array<ArrayBuffer>): ReadonlyMap<number, BlipImage>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { BlipImage, readBlipStore };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { BlockCursor } from "../biff/cursor.js";
|
|
2
|
+
import { ESCHER_BSE, ESCHER_BSTORE_CONTAINER } from "./escher-constants.js";
|
|
3
|
+
import { childrenOfType, readEscherRecords } from "./escher.js";
|
|
4
|
+
//#region src/drawing/blips.ts
|
|
5
|
+
const RGB_UID_SIZE = 16;
|
|
6
|
+
const BLIP_TAG_SIZE = 1;
|
|
7
|
+
/** [MS-ODRAW] OfficeArtFBSE's own fixed fields up to and including unused3, before the optional nameData and the nested embedded blip -- btWin32(1) + btMacOS(1) + rgbUid(16) + tag(2) + size(4) + cRef(4) + foDelay(4) + unused1(1) + cbName(1) + unused2(1) + unused3(1). */
|
|
8
|
+
const BSE_FIXED_SIZE = 36;
|
|
9
|
+
/** A Blip record's own recInstance, mapped to how many 16-byte rgbUid fields precede its `tag` byte and the raw file bytes -- one UID for a blip embedded once, two when [MS-ODRAW] also records a second, "printer" representation's own hash. Only PNG/JPEG instances are named: every other blip type resolves to no image at all (see readBlipImage), so its own UID count is never needed. */
|
|
10
|
+
const BLIP_UID_COUNTS = /* @__PURE__ */ new Map([
|
|
11
|
+
[1760, 1],
|
|
12
|
+
[1761, 2],
|
|
13
|
+
[1130, 1],
|
|
14
|
+
[1131, 2],
|
|
15
|
+
[1762, 1],
|
|
16
|
+
[1763, 2]
|
|
17
|
+
]);
|
|
18
|
+
/** Reads every BSE entry the workbook's own drawing-group Escher stream declares, keyed by its 1-based position in the Blip Store array -- the same index a picture shape's `pib` property names. A BSE this reader cannot turn into a real image (no embedded blip, or a blip type document-schema.js's ContentImageBlockSchema has no lossless slot for -- DIB, EMF, WMF, PICT, TIFF) is simply absent from the map, exactly like any other unsupported construct elsewhere in this package: a picture shape whose `pib` resolves to one of these is recognised as a picture but produces no ContentSheetImage, rather than a fabricated or mistranscoded one. */
|
|
19
|
+
function readBlipStore(drawingGroupBytes) {
|
|
20
|
+
const store = /* @__PURE__ */ new Map();
|
|
21
|
+
if (drawingGroupBytes.length === 0) return store;
|
|
22
|
+
const dgg = readEscherRecords(drawingGroupBytes).find((record) => record.kind === "container" && record.recType === 61440);
|
|
23
|
+
if (dgg === void 0) return store;
|
|
24
|
+
const bstore = childrenOfType(dgg, ESCHER_BSTORE_CONTAINER)[0];
|
|
25
|
+
if (bstore?.kind !== "container") return store;
|
|
26
|
+
childrenOfType(bstore, ESCHER_BSE).forEach((bse, index) => {
|
|
27
|
+
if (bse.kind !== "atom") return;
|
|
28
|
+
const image = readBseImage(bse.data);
|
|
29
|
+
if (image !== void 0) store.set(index + 1, image);
|
|
30
|
+
});
|
|
31
|
+
return store;
|
|
32
|
+
}
|
|
33
|
+
/** One BSE atom's own body ([MS-ODRAW] OfficeArtFBSE): the fixed fields, an optional nameData string, then the nested embedded blip record -- present whenever the image is stored inline rather than only linked externally (foDelay !== 0xFFFFFFFF), which is the only case this reader can recover bytes for at all. */
|
|
34
|
+
function readBseImage(data) {
|
|
35
|
+
if (data.length < BSE_FIXED_SIZE) return;
|
|
36
|
+
const cursor = new BlockCursor([data]);
|
|
37
|
+
cursor.skip(1);
|
|
38
|
+
cursor.skip(1);
|
|
39
|
+
cursor.skip(RGB_UID_SIZE);
|
|
40
|
+
cursor.skip(2);
|
|
41
|
+
cursor.skip(4);
|
|
42
|
+
cursor.skip(4);
|
|
43
|
+
cursor.skip(4);
|
|
44
|
+
cursor.skip(1);
|
|
45
|
+
const cbName = cursor.u8();
|
|
46
|
+
cursor.skip(1);
|
|
47
|
+
cursor.skip(1);
|
|
48
|
+
const embeddedStart = BSE_FIXED_SIZE + (cbName > 0 ? cbName : 0);
|
|
49
|
+
if (embeddedStart >= data.length) return;
|
|
50
|
+
const embeddedBytes = data.subarray(embeddedStart);
|
|
51
|
+
const blip = readEscherRecords(embeddedBytes)[0];
|
|
52
|
+
if (blip?.kind !== "atom") return;
|
|
53
|
+
return readBlipImage(blip.recType, blip.recInstance, blip.data);
|
|
54
|
+
}
|
|
55
|
+
/** One embedded OfficeArtBlip record's own body -- one or two 16-byte rgbUid fields, a one-byte tag, then the literal image file bytes to the end of the record. PNG and JPEG blips carry their literal file bytes verbatim ([MS-ODRAW] OfficeArtBlipPNG/OfficeArtBlipJPEG); every other recognised blip type (DIB -- an in-memory Windows DIB, not a standalone .bmp file, and carrying no BITMAPFILEHEADER of its own to become one) has no lossless target in document-schema.js's ContentImageBlockSchema (png/jpeg/svg/gif only) and resolves to undefined rather than a mistranscoded image. */
|
|
56
|
+
function readBlipImage(recType, recInstance, data) {
|
|
57
|
+
const format = blipFormatOf(recType);
|
|
58
|
+
if (format === void 0) return;
|
|
59
|
+
const uidCount = BLIP_UID_COUNTS.get(recInstance);
|
|
60
|
+
if (uidCount === void 0) return;
|
|
61
|
+
const headerSize = uidCount * RGB_UID_SIZE + BLIP_TAG_SIZE;
|
|
62
|
+
if (data.length < headerSize) return;
|
|
63
|
+
return {
|
|
64
|
+
format,
|
|
65
|
+
base64: bytesToBase64(data.subarray(headerSize))
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function blipFormatOf(recType) {
|
|
69
|
+
if (recType === 61470) return "png";
|
|
70
|
+
if (recType === 61469 || recType === 61482) return "jpeg";
|
|
71
|
+
}
|
|
72
|
+
function bytesToBase64(bytes) {
|
|
73
|
+
let binary = "";
|
|
74
|
+
const chunkSize = 32768;
|
|
75
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) {
|
|
76
|
+
const chunk = bytes.subarray(offset, offset + chunkSize);
|
|
77
|
+
binary += String.fromCharCode(...chunk);
|
|
78
|
+
}
|
|
79
|
+
return btoa(binary);
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { readBlipStore };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/drawing/bytes.ts
|
|
3
|
+
/** Concatenates several byte chunks into one contiguous array -- shared by every reader that joins BIFF8's own MsoDrawing/MsoDrawingGroup record chunks into one Escher stream (content.ts's own workbook-wide MsoDrawingGroup concatenation, workbook/drawing.ts's per-sheet MsoDrawing concatenation). */
|
|
4
|
+
function concatBytes(chunks) {
|
|
5
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
6
|
+
const out = new Uint8Array(total);
|
|
7
|
+
let offset = 0;
|
|
8
|
+
for (const chunk of chunks) {
|
|
9
|
+
out.set(chunk, offset);
|
|
10
|
+
offset += chunk.length;
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.concatBytes = concatBytes;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/drawing/bytes.d.ts
|
|
2
|
+
/** Concatenates several byte chunks into one contiguous array -- shared by every reader that joins BIFF8's own MsoDrawing/MsoDrawingGroup record chunks into one Escher stream (content.ts's own workbook-wide MsoDrawingGroup concatenation, workbook/drawing.ts's per-sheet MsoDrawing concatenation). */
|
|
3
|
+
declare function concatBytes(chunks: readonly Uint8Array<ArrayBuffer>[]): Uint8Array<ArrayBuffer>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { concatBytes };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/drawing/bytes.d.ts
|
|
2
|
+
/** Concatenates several byte chunks into one contiguous array -- shared by every reader that joins BIFF8's own MsoDrawing/MsoDrawingGroup record chunks into one Escher stream (content.ts's own workbook-wide MsoDrawingGroup concatenation, workbook/drawing.ts's per-sheet MsoDrawing concatenation). */
|
|
3
|
+
declare function concatBytes(chunks: readonly Uint8Array<ArrayBuffer>[]): Uint8Array<ArrayBuffer>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { concatBytes };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/drawing/bytes.ts
|
|
2
|
+
/** Concatenates several byte chunks into one contiguous array -- shared by every reader that joins BIFF8's own MsoDrawing/MsoDrawingGroup record chunks into one Escher stream (content.ts's own workbook-wide MsoDrawingGroup concatenation, workbook/drawing.ts's per-sheet MsoDrawing concatenation). */
|
|
3
|
+
function concatBytes(chunks) {
|
|
4
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
5
|
+
const out = new Uint8Array(total);
|
|
6
|
+
let offset = 0;
|
|
7
|
+
for (const chunk of chunks) {
|
|
8
|
+
out.set(chunk, offset);
|
|
9
|
+
offset += chunk.length;
|
|
10
|
+
}
|
|
11
|
+
return out;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { concatBytes };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/drawing/escher-constants.ts
|
|
3
|
+
/** The workbook-wide drawing group's own root container, from the MsoDrawingGroup stream: holds the Blip Store and the drawing document's shared shape-id state ([MS-ODRAW] OfficeArtDggContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/dd7133b6-ed10-4bcb-be29-67b0544f884f). */
|
|
4
|
+
const ESCHER_DGG_CONTAINER = 61440;
|
|
5
|
+
/** The Blip Store: one BSE atom per distinct embedded/linked image the drawing group references ([MS-ODRAW] OfficeArtBstoreContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/561cb6d4-d38b-4666-b2b4-10abc1dce44c). */
|
|
6
|
+
const ESCHER_BSTORE_CONTAINER = 61441;
|
|
7
|
+
/** One worksheet's own drawing container, from that sheet's MsoDrawing records: wraps the Dg atom and the sheet's own shape tree. */
|
|
8
|
+
const ESCHER_DG_CONTAINER = 61442;
|
|
9
|
+
/** A group of shapes -- the sheet's own root shape group (the "patriarch", holding every top-level shape as a child) and any nested shape group a real drawing groups shapes into. */
|
|
10
|
+
const ESCHER_SPGR_CONTAINER = 61443;
|
|
11
|
+
/** One shape: wraps its Sp atom (type/id/flags), its Opt property table, and its anchor/text/client-data atoms ([MS-ODRAW] OfficeArtSpContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/16194cb9-b4b0-476c-9678-a6ac1f06b034). */
|
|
12
|
+
const ESCHER_SP_CONTAINER = 61444;
|
|
13
|
+
/** A single Blip Store Entry: one embedded or linked image's own metadata plus, when embedded, the image bytes themselves nested inside its own body ([MS-ODRAW] OfficeArtFBSE, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/2f2d7f5e-d5c4-4cb7-b230-59b3fe8f10d6). */
|
|
14
|
+
const ESCHER_BSE = 61447;
|
|
15
|
+
/** A shape's own fixed fields: its shape-type ID (carried in the record header's own `recInstance`, an MSOSPT value -- see the SHAPE_TYPE_* constants below) plus its own group/flip/anchor flags ([MS-ODRAW] OfficeArtFSP, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/8a7e7be3-0582-4461-9400-29d7eda8497d). */
|
|
16
|
+
const ESCHER_SP = 61450;
|
|
17
|
+
/** A shape's own property table (fopt): a run of fixed-size property entries this reader consults for exactly one property, `pib` -- see FOPT_PROPERTY_PIB below ([MS-ODRAW] OfficeArtFOPT, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/10dc2fe1-9e69-48dc-a1d1-2921dfb9c28e). */
|
|
18
|
+
const ESCHER_OPT = 61451;
|
|
19
|
+
/** A shape's cell-anchor placement in a worksheet, macro sheet, or dialog sheet substream -- [MS-ODRAW]'s own generic ClientAnchor atom carries a host-defined payload, and [MS-XLS] 2.5.163 OfficeArtClientAnchorSheet (https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd656a2c-d5ee-4171-8f65-17a08b9f2262) is what that payload actually is here (a chart-sheet substream uses the distinct OfficeArtClientAnchorChart instead, not read by this package). */
|
|
20
|
+
const ESCHER_CLIENT_ANCHOR = 61456;
|
|
21
|
+
const ESCHER_BLIP_JPEG_A = 61469;
|
|
22
|
+
const ESCHER_BLIP_JPEG_B = 61482;
|
|
23
|
+
const ESCHER_BLIP_PNG = 61470;
|
|
24
|
+
const ESCHER_BLIP_DIB = 61471;
|
|
25
|
+
/** A custom/freeform shape with no named geometry preset -- MS-ODRAW's own escape value, not a shape type this reader has anything special to say about. */
|
|
26
|
+
const SHAPE_TYPE_NOT_PRIMITIVE = 0;
|
|
27
|
+
/** A picture frame: the shape carries an image via its own `pib` property rather than vector geometry. */
|
|
28
|
+
const SHAPE_TYPE_PICTURE_FRAME = 75;
|
|
29
|
+
/** A text box shape. */
|
|
30
|
+
const SHAPE_TYPE_TEXT_BOX = 202;
|
|
31
|
+
/** The `pib` property ([MS-ODRAW] https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/a12e8c5e-a764-49d5-b407-c27bf933920d): a picture shape's own 1-based index into the Blip Store's BSE array, carried in the FOPTE's plain `op` field when `fComplex` (the opid's own top bit) is clear. */
|
|
32
|
+
const FOPT_OPID_PIB = 260;
|
|
33
|
+
const FOPT_FCOMPLEX_MASK = 32768;
|
|
34
|
+
//#endregion
|
|
35
|
+
exports.ESCHER_BLIP_DIB = ESCHER_BLIP_DIB;
|
|
36
|
+
exports.ESCHER_BLIP_JPEG_A = ESCHER_BLIP_JPEG_A;
|
|
37
|
+
exports.ESCHER_BLIP_JPEG_B = ESCHER_BLIP_JPEG_B;
|
|
38
|
+
exports.ESCHER_BLIP_PNG = ESCHER_BLIP_PNG;
|
|
39
|
+
exports.ESCHER_BSE = ESCHER_BSE;
|
|
40
|
+
exports.ESCHER_BSTORE_CONTAINER = ESCHER_BSTORE_CONTAINER;
|
|
41
|
+
exports.ESCHER_CLIENT_ANCHOR = ESCHER_CLIENT_ANCHOR;
|
|
42
|
+
exports.ESCHER_DGG_CONTAINER = ESCHER_DGG_CONTAINER;
|
|
43
|
+
exports.ESCHER_DG_CONTAINER = ESCHER_DG_CONTAINER;
|
|
44
|
+
exports.ESCHER_OPT = ESCHER_OPT;
|
|
45
|
+
exports.ESCHER_SP = ESCHER_SP;
|
|
46
|
+
exports.ESCHER_SPGR_CONTAINER = ESCHER_SPGR_CONTAINER;
|
|
47
|
+
exports.ESCHER_SP_CONTAINER = ESCHER_SP_CONTAINER;
|
|
48
|
+
exports.FOPT_FCOMPLEX_MASK = FOPT_FCOMPLEX_MASK;
|
|
49
|
+
exports.FOPT_OPID_PIB = FOPT_OPID_PIB;
|
|
50
|
+
exports.SHAPE_TYPE_NOT_PRIMITIVE = SHAPE_TYPE_NOT_PRIMITIVE;
|
|
51
|
+
exports.SHAPE_TYPE_PICTURE_FRAME = SHAPE_TYPE_PICTURE_FRAME;
|
|
52
|
+
exports.SHAPE_TYPE_TEXT_BOX = SHAPE_TYPE_TEXT_BOX;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/drawing/escher-constants.d.ts
|
|
2
|
+
/** The workbook-wide drawing group's own root container, from the MsoDrawingGroup stream: holds the Blip Store and the drawing document's shared shape-id state ([MS-ODRAW] OfficeArtDggContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/dd7133b6-ed10-4bcb-be29-67b0544f884f). */
|
|
3
|
+
declare const ESCHER_DGG_CONTAINER = 61440;
|
|
4
|
+
/** The Blip Store: one BSE atom per distinct embedded/linked image the drawing group references ([MS-ODRAW] OfficeArtBstoreContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/561cb6d4-d38b-4666-b2b4-10abc1dce44c). */
|
|
5
|
+
declare const ESCHER_BSTORE_CONTAINER = 61441;
|
|
6
|
+
/** One worksheet's own drawing container, from that sheet's MsoDrawing records: wraps the Dg atom and the sheet's own shape tree. */
|
|
7
|
+
declare const ESCHER_DG_CONTAINER = 61442;
|
|
8
|
+
/** A group of shapes -- the sheet's own root shape group (the "patriarch", holding every top-level shape as a child) and any nested shape group a real drawing groups shapes into. */
|
|
9
|
+
declare const ESCHER_SPGR_CONTAINER = 61443;
|
|
10
|
+
/** One shape: wraps its Sp atom (type/id/flags), its Opt property table, and its anchor/text/client-data atoms ([MS-ODRAW] OfficeArtSpContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/16194cb9-b4b0-476c-9678-a6ac1f06b034). */
|
|
11
|
+
declare const ESCHER_SP_CONTAINER = 61444;
|
|
12
|
+
/** A single Blip Store Entry: one embedded or linked image's own metadata plus, when embedded, the image bytes themselves nested inside its own body ([MS-ODRAW] OfficeArtFBSE, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/2f2d7f5e-d5c4-4cb7-b230-59b3fe8f10d6). */
|
|
13
|
+
declare const ESCHER_BSE = 61447;
|
|
14
|
+
/** A shape's own fixed fields: its shape-type ID (carried in the record header's own `recInstance`, an MSOSPT value -- see the SHAPE_TYPE_* constants below) plus its own group/flip/anchor flags ([MS-ODRAW] OfficeArtFSP, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/8a7e7be3-0582-4461-9400-29d7eda8497d). */
|
|
15
|
+
declare const ESCHER_SP = 61450;
|
|
16
|
+
/** A shape's own property table (fopt): a run of fixed-size property entries this reader consults for exactly one property, `pib` -- see FOPT_PROPERTY_PIB below ([MS-ODRAW] OfficeArtFOPT, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/10dc2fe1-9e69-48dc-a1d1-2921dfb9c28e). */
|
|
17
|
+
declare const ESCHER_OPT = 61451;
|
|
18
|
+
/** A shape's cell-anchor placement in a worksheet, macro sheet, or dialog sheet substream -- [MS-ODRAW]'s own generic ClientAnchor atom carries a host-defined payload, and [MS-XLS] 2.5.163 OfficeArtClientAnchorSheet (https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd656a2c-d5ee-4171-8f65-17a08b9f2262) is what that payload actually is here (a chart-sheet substream uses the distinct OfficeArtClientAnchorChart instead, not read by this package). */
|
|
19
|
+
declare const ESCHER_CLIENT_ANCHOR = 61456;
|
|
20
|
+
declare const ESCHER_BLIP_JPEG_A = 61469;
|
|
21
|
+
declare const ESCHER_BLIP_JPEG_B = 61482;
|
|
22
|
+
declare const ESCHER_BLIP_PNG = 61470;
|
|
23
|
+
declare const ESCHER_BLIP_DIB = 61471;
|
|
24
|
+
/** A custom/freeform shape with no named geometry preset -- MS-ODRAW's own escape value, not a shape type this reader has anything special to say about. */
|
|
25
|
+
declare const SHAPE_TYPE_NOT_PRIMITIVE = 0;
|
|
26
|
+
/** A picture frame: the shape carries an image via its own `pib` property rather than vector geometry. */
|
|
27
|
+
declare const SHAPE_TYPE_PICTURE_FRAME = 75;
|
|
28
|
+
/** A text box shape. */
|
|
29
|
+
declare const SHAPE_TYPE_TEXT_BOX = 202;
|
|
30
|
+
/** The `pib` property ([MS-ODRAW] https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/a12e8c5e-a764-49d5-b407-c27bf933920d): a picture shape's own 1-based index into the Blip Store's BSE array, carried in the FOPTE's plain `op` field when `fComplex` (the opid's own top bit) is clear. */
|
|
31
|
+
declare const FOPT_OPID_PIB = 260;
|
|
32
|
+
declare const FOPT_FCOMPLEX_MASK = 32768;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ESCHER_BLIP_DIB, ESCHER_BLIP_JPEG_A, ESCHER_BLIP_JPEG_B, ESCHER_BLIP_PNG, ESCHER_BSE, ESCHER_BSTORE_CONTAINER, ESCHER_CLIENT_ANCHOR, ESCHER_DGG_CONTAINER, ESCHER_DG_CONTAINER, ESCHER_OPT, ESCHER_SP, ESCHER_SPGR_CONTAINER, ESCHER_SP_CONTAINER, FOPT_FCOMPLEX_MASK, FOPT_OPID_PIB, SHAPE_TYPE_NOT_PRIMITIVE, SHAPE_TYPE_PICTURE_FRAME, SHAPE_TYPE_TEXT_BOX };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/drawing/escher-constants.d.ts
|
|
2
|
+
/** The workbook-wide drawing group's own root container, from the MsoDrawingGroup stream: holds the Blip Store and the drawing document's shared shape-id state ([MS-ODRAW] OfficeArtDggContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/dd7133b6-ed10-4bcb-be29-67b0544f884f). */
|
|
3
|
+
declare const ESCHER_DGG_CONTAINER = 61440;
|
|
4
|
+
/** The Blip Store: one BSE atom per distinct embedded/linked image the drawing group references ([MS-ODRAW] OfficeArtBstoreContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/561cb6d4-d38b-4666-b2b4-10abc1dce44c). */
|
|
5
|
+
declare const ESCHER_BSTORE_CONTAINER = 61441;
|
|
6
|
+
/** One worksheet's own drawing container, from that sheet's MsoDrawing records: wraps the Dg atom and the sheet's own shape tree. */
|
|
7
|
+
declare const ESCHER_DG_CONTAINER = 61442;
|
|
8
|
+
/** A group of shapes -- the sheet's own root shape group (the "patriarch", holding every top-level shape as a child) and any nested shape group a real drawing groups shapes into. */
|
|
9
|
+
declare const ESCHER_SPGR_CONTAINER = 61443;
|
|
10
|
+
/** One shape: wraps its Sp atom (type/id/flags), its Opt property table, and its anchor/text/client-data atoms ([MS-ODRAW] OfficeArtSpContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/16194cb9-b4b0-476c-9678-a6ac1f06b034). */
|
|
11
|
+
declare const ESCHER_SP_CONTAINER = 61444;
|
|
12
|
+
/** A single Blip Store Entry: one embedded or linked image's own metadata plus, when embedded, the image bytes themselves nested inside its own body ([MS-ODRAW] OfficeArtFBSE, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/2f2d7f5e-d5c4-4cb7-b230-59b3fe8f10d6). */
|
|
13
|
+
declare const ESCHER_BSE = 61447;
|
|
14
|
+
/** A shape's own fixed fields: its shape-type ID (carried in the record header's own `recInstance`, an MSOSPT value -- see the SHAPE_TYPE_* constants below) plus its own group/flip/anchor flags ([MS-ODRAW] OfficeArtFSP, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/8a7e7be3-0582-4461-9400-29d7eda8497d). */
|
|
15
|
+
declare const ESCHER_SP = 61450;
|
|
16
|
+
/** A shape's own property table (fopt): a run of fixed-size property entries this reader consults for exactly one property, `pib` -- see FOPT_PROPERTY_PIB below ([MS-ODRAW] OfficeArtFOPT, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/10dc2fe1-9e69-48dc-a1d1-2921dfb9c28e). */
|
|
17
|
+
declare const ESCHER_OPT = 61451;
|
|
18
|
+
/** A shape's cell-anchor placement in a worksheet, macro sheet, or dialog sheet substream -- [MS-ODRAW]'s own generic ClientAnchor atom carries a host-defined payload, and [MS-XLS] 2.5.163 OfficeArtClientAnchorSheet (https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd656a2c-d5ee-4171-8f65-17a08b9f2262) is what that payload actually is here (a chart-sheet substream uses the distinct OfficeArtClientAnchorChart instead, not read by this package). */
|
|
19
|
+
declare const ESCHER_CLIENT_ANCHOR = 61456;
|
|
20
|
+
declare const ESCHER_BLIP_JPEG_A = 61469;
|
|
21
|
+
declare const ESCHER_BLIP_JPEG_B = 61482;
|
|
22
|
+
declare const ESCHER_BLIP_PNG = 61470;
|
|
23
|
+
declare const ESCHER_BLIP_DIB = 61471;
|
|
24
|
+
/** A custom/freeform shape with no named geometry preset -- MS-ODRAW's own escape value, not a shape type this reader has anything special to say about. */
|
|
25
|
+
declare const SHAPE_TYPE_NOT_PRIMITIVE = 0;
|
|
26
|
+
/** A picture frame: the shape carries an image via its own `pib` property rather than vector geometry. */
|
|
27
|
+
declare const SHAPE_TYPE_PICTURE_FRAME = 75;
|
|
28
|
+
/** A text box shape. */
|
|
29
|
+
declare const SHAPE_TYPE_TEXT_BOX = 202;
|
|
30
|
+
/** The `pib` property ([MS-ODRAW] https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/a12e8c5e-a764-49d5-b407-c27bf933920d): a picture shape's own 1-based index into the Blip Store's BSE array, carried in the FOPTE's plain `op` field when `fComplex` (the opid's own top bit) is clear. */
|
|
31
|
+
declare const FOPT_OPID_PIB = 260;
|
|
32
|
+
declare const FOPT_FCOMPLEX_MASK = 32768;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ESCHER_BLIP_DIB, ESCHER_BLIP_JPEG_A, ESCHER_BLIP_JPEG_B, ESCHER_BLIP_PNG, ESCHER_BSE, ESCHER_BSTORE_CONTAINER, ESCHER_CLIENT_ANCHOR, ESCHER_DGG_CONTAINER, ESCHER_DG_CONTAINER, ESCHER_OPT, ESCHER_SP, ESCHER_SPGR_CONTAINER, ESCHER_SP_CONTAINER, FOPT_FCOMPLEX_MASK, FOPT_OPID_PIB, SHAPE_TYPE_NOT_PRIMITIVE, SHAPE_TYPE_PICTURE_FRAME, SHAPE_TYPE_TEXT_BOX };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/drawing/escher-constants.ts
|
|
2
|
+
/** The workbook-wide drawing group's own root container, from the MsoDrawingGroup stream: holds the Blip Store and the drawing document's shared shape-id state ([MS-ODRAW] OfficeArtDggContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/dd7133b6-ed10-4bcb-be29-67b0544f884f). */
|
|
3
|
+
const ESCHER_DGG_CONTAINER = 61440;
|
|
4
|
+
/** The Blip Store: one BSE atom per distinct embedded/linked image the drawing group references ([MS-ODRAW] OfficeArtBstoreContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/561cb6d4-d38b-4666-b2b4-10abc1dce44c). */
|
|
5
|
+
const ESCHER_BSTORE_CONTAINER = 61441;
|
|
6
|
+
/** One worksheet's own drawing container, from that sheet's MsoDrawing records: wraps the Dg atom and the sheet's own shape tree. */
|
|
7
|
+
const ESCHER_DG_CONTAINER = 61442;
|
|
8
|
+
/** A group of shapes -- the sheet's own root shape group (the "patriarch", holding every top-level shape as a child) and any nested shape group a real drawing groups shapes into. */
|
|
9
|
+
const ESCHER_SPGR_CONTAINER = 61443;
|
|
10
|
+
/** One shape: wraps its Sp atom (type/id/flags), its Opt property table, and its anchor/text/client-data atoms ([MS-ODRAW] OfficeArtSpContainer, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/16194cb9-b4b0-476c-9678-a6ac1f06b034). */
|
|
11
|
+
const ESCHER_SP_CONTAINER = 61444;
|
|
12
|
+
/** A single Blip Store Entry: one embedded or linked image's own metadata plus, when embedded, the image bytes themselves nested inside its own body ([MS-ODRAW] OfficeArtFBSE, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/2f2d7f5e-d5c4-4cb7-b230-59b3fe8f10d6). */
|
|
13
|
+
const ESCHER_BSE = 61447;
|
|
14
|
+
/** A shape's own fixed fields: its shape-type ID (carried in the record header's own `recInstance`, an MSOSPT value -- see the SHAPE_TYPE_* constants below) plus its own group/flip/anchor flags ([MS-ODRAW] OfficeArtFSP, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/8a7e7be3-0582-4461-9400-29d7eda8497d). */
|
|
15
|
+
const ESCHER_SP = 61450;
|
|
16
|
+
/** A shape's own property table (fopt): a run of fixed-size property entries this reader consults for exactly one property, `pib` -- see FOPT_PROPERTY_PIB below ([MS-ODRAW] OfficeArtFOPT, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/10dc2fe1-9e69-48dc-a1d1-2921dfb9c28e). */
|
|
17
|
+
const ESCHER_OPT = 61451;
|
|
18
|
+
/** A shape's cell-anchor placement in a worksheet, macro sheet, or dialog sheet substream -- [MS-ODRAW]'s own generic ClientAnchor atom carries a host-defined payload, and [MS-XLS] 2.5.163 OfficeArtClientAnchorSheet (https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd656a2c-d5ee-4171-8f65-17a08b9f2262) is what that payload actually is here (a chart-sheet substream uses the distinct OfficeArtClientAnchorChart instead, not read by this package). */
|
|
19
|
+
const ESCHER_CLIENT_ANCHOR = 61456;
|
|
20
|
+
const ESCHER_BLIP_JPEG_A = 61469;
|
|
21
|
+
const ESCHER_BLIP_JPEG_B = 61482;
|
|
22
|
+
const ESCHER_BLIP_PNG = 61470;
|
|
23
|
+
const ESCHER_BLIP_DIB = 61471;
|
|
24
|
+
/** A custom/freeform shape with no named geometry preset -- MS-ODRAW's own escape value, not a shape type this reader has anything special to say about. */
|
|
25
|
+
const SHAPE_TYPE_NOT_PRIMITIVE = 0;
|
|
26
|
+
/** A picture frame: the shape carries an image via its own `pib` property rather than vector geometry. */
|
|
27
|
+
const SHAPE_TYPE_PICTURE_FRAME = 75;
|
|
28
|
+
/** A text box shape. */
|
|
29
|
+
const SHAPE_TYPE_TEXT_BOX = 202;
|
|
30
|
+
/** The `pib` property ([MS-ODRAW] https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-odraw/a12e8c5e-a764-49d5-b407-c27bf933920d): a picture shape's own 1-based index into the Blip Store's BSE array, carried in the FOPTE's plain `op` field when `fComplex` (the opid's own top bit) is clear. */
|
|
31
|
+
const FOPT_OPID_PIB = 260;
|
|
32
|
+
const FOPT_FCOMPLEX_MASK = 32768;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ESCHER_BLIP_DIB, ESCHER_BLIP_JPEG_A, ESCHER_BLIP_JPEG_B, ESCHER_BLIP_PNG, ESCHER_BSE, ESCHER_BSTORE_CONTAINER, ESCHER_CLIENT_ANCHOR, ESCHER_DGG_CONTAINER, ESCHER_DG_CONTAINER, ESCHER_OPT, ESCHER_SP, ESCHER_SPGR_CONTAINER, ESCHER_SP_CONTAINER, FOPT_FCOMPLEX_MASK, FOPT_OPID_PIB, SHAPE_TYPE_NOT_PRIMITIVE, SHAPE_TYPE_PICTURE_FRAME, SHAPE_TYPE_TEXT_BOX };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_biff_records = require("../biff/records.cjs");
|
|
3
|
+
//#region src/drawing/escher.ts
|
|
4
|
+
const HEADER_SIZE = 8;
|
|
5
|
+
const CONTAINER_REC_VER = 15;
|
|
6
|
+
/**
|
|
7
|
+
* Reads every top-level Escher record in `bytes`, recursing into containers.
|
|
8
|
+
*
|
|
9
|
+
* `bytes` is the whole concatenated Escher stream one worksheet's MsoDrawing records (or the workbook globals substream's MsoDrawingGroup records) build up in stream order -- BIFF8 splits one logical Escher byte sequence across as many of those BIFF records as it needs, and [MS-XLS] states plainly that their own data simply concatenates; nothing about the record framing itself lives at that BIFF layer, so by the time this function runs the split is already invisible.
|
|
10
|
+
*/
|
|
11
|
+
function readEscherRecords(bytes) {
|
|
12
|
+
const records = [];
|
|
13
|
+
let offset = 0;
|
|
14
|
+
while (offset < bytes.length) {
|
|
15
|
+
const { record, nextOffset } = readOneRecord(bytes, offset);
|
|
16
|
+
records.push(record);
|
|
17
|
+
offset = nextOffset;
|
|
18
|
+
}
|
|
19
|
+
return records;
|
|
20
|
+
}
|
|
21
|
+
function readOneRecord(bytes, offset) {
|
|
22
|
+
if (offset + HEADER_SIZE > bytes.length) throw new require_biff_records.BiffFormatError(`Escher record header at offset ${offset} runs past the end of the ${bytes.length}-byte stream`);
|
|
23
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
24
|
+
const verInstance = view.getUint16(offset, true);
|
|
25
|
+
const recVer = verInstance & 15;
|
|
26
|
+
const recInstance = verInstance >> 4;
|
|
27
|
+
const recType = view.getUint16(offset + 2, true);
|
|
28
|
+
const recLen = view.getUint32(offset + 4, true);
|
|
29
|
+
const bodyStart = offset + HEADER_SIZE;
|
|
30
|
+
const bodyEnd = bodyStart + recLen;
|
|
31
|
+
if (bodyEnd > bytes.length) throw new require_biff_records.BiffFormatError(`Escher record 0x${recType.toString(16)} at offset ${offset} declares ${recLen} bytes of body, running past the end of the ${bytes.length}-byte stream`);
|
|
32
|
+
if (recVer === CONTAINER_REC_VER) return {
|
|
33
|
+
record: {
|
|
34
|
+
kind: "container",
|
|
35
|
+
recInstance,
|
|
36
|
+
recType,
|
|
37
|
+
children: readChildren(bytes, bodyStart, bodyEnd)
|
|
38
|
+
},
|
|
39
|
+
nextOffset: bodyEnd
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
record: {
|
|
43
|
+
kind: "atom",
|
|
44
|
+
recInstance,
|
|
45
|
+
recType,
|
|
46
|
+
data: bytes.subarray(bodyStart, bodyEnd)
|
|
47
|
+
},
|
|
48
|
+
nextOffset: bodyEnd
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function readChildren(bytes, start, end) {
|
|
52
|
+
const children = [];
|
|
53
|
+
let offset = start;
|
|
54
|
+
while (offset < end) {
|
|
55
|
+
const { record, nextOffset } = readOneRecord(bytes, offset);
|
|
56
|
+
if (nextOffset > end) throw new require_biff_records.BiffFormatError(`Escher child record at offset ${offset} extends past its own container's declared end`);
|
|
57
|
+
children.push(record);
|
|
58
|
+
offset = nextOffset;
|
|
59
|
+
}
|
|
60
|
+
return children;
|
|
61
|
+
}
|
|
62
|
+
/** The first direct child of `container` with the given `recType`, container or atom alike -- undefined when none matches. */
|
|
63
|
+
function firstChild(container, recType) {
|
|
64
|
+
return container.children.find((child) => child.recType === recType);
|
|
65
|
+
}
|
|
66
|
+
/** Every direct child of `container` with the given `recType`, in document order. */
|
|
67
|
+
function childrenOfType(container, recType) {
|
|
68
|
+
return container.children.filter((child) => child.recType === recType);
|
|
69
|
+
}
|
|
70
|
+
/** Recursively finds the first descendant record (depth-first, this container's own children before their children) with the given `recType` -- for a record known to appear exactly once at an unspecified depth (the Blip Store, the drawing group's own Dgg), as opposed to childrenOfType's direct-children-only contract. */
|
|
71
|
+
function findDescendant(container, recType) {
|
|
72
|
+
for (const child of container.children) {
|
|
73
|
+
if (child.recType === recType) return child;
|
|
74
|
+
if (child.kind === "container") {
|
|
75
|
+
const found = findDescendant(child, recType);
|
|
76
|
+
if (found !== void 0) return found;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.childrenOfType = childrenOfType;
|
|
82
|
+
exports.findDescendant = findDescendant;
|
|
83
|
+
exports.firstChild = firstChild;
|
|
84
|
+
exports.readEscherRecords = readEscherRecords;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/drawing/escher.d.ts
|
|
2
|
+
/** One Escher atom: `recLen` bytes of record-specific data this module leaves opaque. */
|
|
3
|
+
interface EscherAtom {
|
|
4
|
+
readonly kind: "atom";
|
|
5
|
+
readonly recInstance: number;
|
|
6
|
+
readonly recType: number;
|
|
7
|
+
readonly data: Uint8Array<ArrayBuffer>;
|
|
8
|
+
}
|
|
9
|
+
/** One Escher container: its own children, read the identical way, recursively. */
|
|
10
|
+
interface EscherContainer {
|
|
11
|
+
readonly kind: "container";
|
|
12
|
+
readonly recInstance: number;
|
|
13
|
+
readonly recType: number;
|
|
14
|
+
readonly children: readonly EscherRecord[];
|
|
15
|
+
}
|
|
16
|
+
type EscherRecord = EscherAtom | EscherContainer;
|
|
17
|
+
/**
|
|
18
|
+
* Reads every top-level Escher record in `bytes`, recursing into containers.
|
|
19
|
+
*
|
|
20
|
+
* `bytes` is the whole concatenated Escher stream one worksheet's MsoDrawing records (or the workbook globals substream's MsoDrawingGroup records) build up in stream order -- BIFF8 splits one logical Escher byte sequence across as many of those BIFF records as it needs, and [MS-XLS] states plainly that their own data simply concatenates; nothing about the record framing itself lives at that BIFF layer, so by the time this function runs the split is already invisible.
|
|
21
|
+
*/
|
|
22
|
+
declare function readEscherRecords(bytes: Uint8Array<ArrayBuffer>): readonly EscherRecord[];
|
|
23
|
+
/** The first direct child of `container` with the given `recType`, container or atom alike -- undefined when none matches. */
|
|
24
|
+
declare function firstChild(container: EscherContainer, recType: number): EscherRecord | undefined;
|
|
25
|
+
/** Every direct child of `container` with the given `recType`, in document order. */
|
|
26
|
+
declare function childrenOfType(container: EscherContainer, recType: number): readonly EscherRecord[];
|
|
27
|
+
/** Recursively finds the first descendant record (depth-first, this container's own children before their children) with the given `recType` -- for a record known to appear exactly once at an unspecified depth (the Blip Store, the drawing group's own Dgg), as opposed to childrenOfType's direct-children-only contract. */
|
|
28
|
+
declare function findDescendant(container: EscherContainer, recType: number): EscherRecord | undefined;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { EscherAtom, EscherContainer, EscherRecord, childrenOfType, findDescendant, firstChild, readEscherRecords };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/drawing/escher.d.ts
|
|
2
|
+
/** One Escher atom: `recLen` bytes of record-specific data this module leaves opaque. */
|
|
3
|
+
interface EscherAtom {
|
|
4
|
+
readonly kind: "atom";
|
|
5
|
+
readonly recInstance: number;
|
|
6
|
+
readonly recType: number;
|
|
7
|
+
readonly data: Uint8Array<ArrayBuffer>;
|
|
8
|
+
}
|
|
9
|
+
/** One Escher container: its own children, read the identical way, recursively. */
|
|
10
|
+
interface EscherContainer {
|
|
11
|
+
readonly kind: "container";
|
|
12
|
+
readonly recInstance: number;
|
|
13
|
+
readonly recType: number;
|
|
14
|
+
readonly children: readonly EscherRecord[];
|
|
15
|
+
}
|
|
16
|
+
type EscherRecord = EscherAtom | EscherContainer;
|
|
17
|
+
/**
|
|
18
|
+
* Reads every top-level Escher record in `bytes`, recursing into containers.
|
|
19
|
+
*
|
|
20
|
+
* `bytes` is the whole concatenated Escher stream one worksheet's MsoDrawing records (or the workbook globals substream's MsoDrawingGroup records) build up in stream order -- BIFF8 splits one logical Escher byte sequence across as many of those BIFF records as it needs, and [MS-XLS] states plainly that their own data simply concatenates; nothing about the record framing itself lives at that BIFF layer, so by the time this function runs the split is already invisible.
|
|
21
|
+
*/
|
|
22
|
+
declare function readEscherRecords(bytes: Uint8Array<ArrayBuffer>): readonly EscherRecord[];
|
|
23
|
+
/** The first direct child of `container` with the given `recType`, container or atom alike -- undefined when none matches. */
|
|
24
|
+
declare function firstChild(container: EscherContainer, recType: number): EscherRecord | undefined;
|
|
25
|
+
/** Every direct child of `container` with the given `recType`, in document order. */
|
|
26
|
+
declare function childrenOfType(container: EscherContainer, recType: number): readonly EscherRecord[];
|
|
27
|
+
/** Recursively finds the first descendant record (depth-first, this container's own children before their children) with the given `recType` -- for a record known to appear exactly once at an unspecified depth (the Blip Store, the drawing group's own Dgg), as opposed to childrenOfType's direct-children-only contract. */
|
|
28
|
+
declare function findDescendant(container: EscherContainer, recType: number): EscherRecord | undefined;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { EscherAtom, EscherContainer, EscherRecord, childrenOfType, findDescendant, firstChild, readEscherRecords };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { BiffFormatError } from "../biff/records.js";
|
|
2
|
+
//#region src/drawing/escher.ts
|
|
3
|
+
const HEADER_SIZE = 8;
|
|
4
|
+
const CONTAINER_REC_VER = 15;
|
|
5
|
+
/**
|
|
6
|
+
* Reads every top-level Escher record in `bytes`, recursing into containers.
|
|
7
|
+
*
|
|
8
|
+
* `bytes` is the whole concatenated Escher stream one worksheet's MsoDrawing records (or the workbook globals substream's MsoDrawingGroup records) build up in stream order -- BIFF8 splits one logical Escher byte sequence across as many of those BIFF records as it needs, and [MS-XLS] states plainly that their own data simply concatenates; nothing about the record framing itself lives at that BIFF layer, so by the time this function runs the split is already invisible.
|
|
9
|
+
*/
|
|
10
|
+
function readEscherRecords(bytes) {
|
|
11
|
+
const records = [];
|
|
12
|
+
let offset = 0;
|
|
13
|
+
while (offset < bytes.length) {
|
|
14
|
+
const { record, nextOffset } = readOneRecord(bytes, offset);
|
|
15
|
+
records.push(record);
|
|
16
|
+
offset = nextOffset;
|
|
17
|
+
}
|
|
18
|
+
return records;
|
|
19
|
+
}
|
|
20
|
+
function readOneRecord(bytes, offset) {
|
|
21
|
+
if (offset + HEADER_SIZE > bytes.length) throw new BiffFormatError(`Escher record header at offset ${offset} runs past the end of the ${bytes.length}-byte stream`);
|
|
22
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
23
|
+
const verInstance = view.getUint16(offset, true);
|
|
24
|
+
const recVer = verInstance & 15;
|
|
25
|
+
const recInstance = verInstance >> 4;
|
|
26
|
+
const recType = view.getUint16(offset + 2, true);
|
|
27
|
+
const recLen = view.getUint32(offset + 4, true);
|
|
28
|
+
const bodyStart = offset + HEADER_SIZE;
|
|
29
|
+
const bodyEnd = bodyStart + recLen;
|
|
30
|
+
if (bodyEnd > bytes.length) throw new BiffFormatError(`Escher record 0x${recType.toString(16)} at offset ${offset} declares ${recLen} bytes of body, running past the end of the ${bytes.length}-byte stream`);
|
|
31
|
+
if (recVer === CONTAINER_REC_VER) return {
|
|
32
|
+
record: {
|
|
33
|
+
kind: "container",
|
|
34
|
+
recInstance,
|
|
35
|
+
recType,
|
|
36
|
+
children: readChildren(bytes, bodyStart, bodyEnd)
|
|
37
|
+
},
|
|
38
|
+
nextOffset: bodyEnd
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
record: {
|
|
42
|
+
kind: "atom",
|
|
43
|
+
recInstance,
|
|
44
|
+
recType,
|
|
45
|
+
data: bytes.subarray(bodyStart, bodyEnd)
|
|
46
|
+
},
|
|
47
|
+
nextOffset: bodyEnd
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function readChildren(bytes, start, end) {
|
|
51
|
+
const children = [];
|
|
52
|
+
let offset = start;
|
|
53
|
+
while (offset < end) {
|
|
54
|
+
const { record, nextOffset } = readOneRecord(bytes, offset);
|
|
55
|
+
if (nextOffset > end) throw new BiffFormatError(`Escher child record at offset ${offset} extends past its own container's declared end`);
|
|
56
|
+
children.push(record);
|
|
57
|
+
offset = nextOffset;
|
|
58
|
+
}
|
|
59
|
+
return children;
|
|
60
|
+
}
|
|
61
|
+
/** The first direct child of `container` with the given `recType`, container or atom alike -- undefined when none matches. */
|
|
62
|
+
function firstChild(container, recType) {
|
|
63
|
+
return container.children.find((child) => child.recType === recType);
|
|
64
|
+
}
|
|
65
|
+
/** Every direct child of `container` with the given `recType`, in document order. */
|
|
66
|
+
function childrenOfType(container, recType) {
|
|
67
|
+
return container.children.filter((child) => child.recType === recType);
|
|
68
|
+
}
|
|
69
|
+
/** Recursively finds the first descendant record (depth-first, this container's own children before their children) with the given `recType` -- for a record known to appear exactly once at an unspecified depth (the Blip Store, the drawing group's own Dgg), as opposed to childrenOfType's direct-children-only contract. */
|
|
70
|
+
function findDescendant(container, recType) {
|
|
71
|
+
for (const child of container.children) {
|
|
72
|
+
if (child.recType === recType) return child;
|
|
73
|
+
if (child.kind === "container") {
|
|
74
|
+
const found = findDescendant(child, recType);
|
|
75
|
+
if (found !== void 0) return found;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { childrenOfType, findDescendant, firstChild, readEscherRecords };
|