token-goat 2.9.13 → 2.9.15

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.
Files changed (52) hide show
  1. package/README.md +28 -1
  2. package/dist/token-goat-chunk-2X2EBBC6.mjs +277 -0
  3. package/dist/token-goat-chunk-3BTK54F3.mjs +1733 -0
  4. package/dist/token-goat-chunk-3NSDDTGL.mjs +34 -0
  5. package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
  6. package/dist/token-goat-chunk-5V7DAC7V.mjs +123 -0
  7. package/dist/token-goat-chunk-6DLVZDB6.mjs +34 -0
  8. package/dist/token-goat-chunk-7ZYK25AO.mjs +24 -0
  9. package/dist/token-goat-chunk-A4JYKD5H.mjs +144 -0
  10. package/dist/token-goat-chunk-AH6QILZM.mjs +26 -0
  11. package/dist/token-goat-chunk-ASYEPR3S.mjs +212 -0
  12. package/dist/{token-goat-chunk-RDITECDL.mjs → token-goat-chunk-ATIFTMRC.mjs} +31 -13
  13. package/dist/{token-goat-chunk-ZZI3IDQZ.mjs → token-goat-chunk-BL5LNGBG.mjs} +3935 -11949
  14. package/dist/{token-goat-chunk-4NXUKV7D.mjs → token-goat-chunk-C5JIO6HK.mjs} +8 -4
  15. package/dist/{token-goat-chunk-FZU7GMUS.mjs → token-goat-chunk-DQ4J5AFF.mjs} +50 -18
  16. package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
  17. package/dist/{token-goat-chunk-6B44WLIF.mjs → token-goat-chunk-GIIHUSZX.mjs} +142 -21
  18. package/dist/token-goat-chunk-GMOUBOX4.mjs +386 -0
  19. package/dist/{token-goat-chunk-3ESRORNM.mjs → token-goat-chunk-GMQQA7E4.mjs} +12576 -12326
  20. package/dist/token-goat-chunk-IVUQLQWN.mjs +2046 -0
  21. package/dist/token-goat-chunk-K7F2BFIK.mjs +2430 -0
  22. package/dist/{token-goat-chunk-U7X6LQD2.mjs → token-goat-chunk-LCZBPOIN.mjs} +10197 -9717
  23. package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
  24. package/dist/token-goat-chunk-LT7JRU6K.mjs +22 -0
  25. package/dist/token-goat-chunk-MZDIJJ3R.mjs +420 -0
  26. package/dist/token-goat-chunk-NDPO7GAH.mjs +177 -0
  27. package/dist/token-goat-chunk-NDRP4KJQ.mjs +4371 -0
  28. package/dist/token-goat-chunk-NEI4NC54.mjs +424 -0
  29. package/dist/token-goat-chunk-NU7TLMQK.mjs +585 -0
  30. package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
  31. package/dist/token-goat-chunk-OUGNPMDA.mjs +959 -0
  32. package/dist/token-goat-chunk-PM76YS22.mjs +1341 -0
  33. package/dist/token-goat-chunk-S4XRY446.mjs +2637 -0
  34. package/dist/{token-goat-chunk-YOA4N6WA.mjs → token-goat-chunk-SFAS46RE.mjs} +5 -3
  35. package/dist/{token-goat-chunk-QWSUZWFP.mjs → token-goat-chunk-SZWYESBS.mjs} +793 -650
  36. package/dist/{token-goat-chunk-B3CTCQTH.mjs → token-goat-chunk-XEPXYDPI.mjs} +3 -2
  37. package/dist/token-goat-chunk-XTQAOTSO.mjs +89 -0
  38. package/dist/token-goat-chunk-Y4AFKTHK.mjs +22 -0
  39. package/dist/token-goat-chunk-YKG35VHC.mjs +228 -0
  40. package/dist/{token-goat-chunk-JOXLE672.mjs → token-goat-chunk-YQ7WI2CO.mjs} +990 -106
  41. package/dist/{token-goat-chunk-2WC4ZUXN.mjs → token-goat-chunk-YZX7EFG4.mjs} +1 -1
  42. package/dist/token-goat-chunk-Z6UXPYJA.mjs +62 -0
  43. package/dist/token-goat-hook.mjs +16 -8
  44. package/dist/token-goat.core.mjs +27 -10
  45. package/docs/cli.md +9 -6
  46. package/package.json +4 -2
  47. package/dist/token-goat-chunk-FQCNJV4V.mjs +0 -693
  48. package/dist/token-goat-chunk-JVNPCQB7.mjs +0 -31
  49. package/dist/token-goat-chunk-P2PU4CR5.mjs +0 -26
  50. package/dist/token-goat-chunk-QKXBGBQR.mjs +0 -3653
  51. package/dist/token-goat-chunk-UM47DRD3.mjs +0 -242
  52. package/dist/token-goat-chunk-UMXJN7DI.mjs +0 -5521
@@ -0,0 +1,34 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ XlsxScanTooLargeError,
5
+ allSheetsHeadText,
6
+ formatXlsxColumns,
7
+ formatXlsxRange,
8
+ headSheet,
9
+ listSheets,
10
+ querySheet,
11
+ rangeSheet,
12
+ xlsxColumns
13
+ } from "./token-goat-chunk-NU7TLMQK.mjs";
14
+ import "./token-goat-chunk-YKG35VHC.mjs";
15
+ import "./token-goat-chunk-3BTK54F3.mjs";
16
+ import "./token-goat-chunk-MZDIJJ3R.mjs";
17
+ import "./token-goat-chunk-XTQAOTSO.mjs";
18
+ import "./token-goat-chunk-AH6QILZM.mjs";
19
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
20
+ import "./token-goat-chunk-PM76YS22.mjs";
21
+ import "./token-goat-chunk-ERTXEKB6.mjs";
22
+ import "./token-goat-chunk-GMOUBOX4.mjs";
23
+ import "./token-goat-chunk-A37V4PBF.mjs";
24
+ export {
25
+ XlsxScanTooLargeError,
26
+ allSheetsHeadText,
27
+ formatXlsxColumns,
28
+ formatXlsxRange,
29
+ headSheet,
30
+ listSheets,
31
+ querySheet,
32
+ rangeSheet,
33
+ xlsxColumns
34
+ };
@@ -0,0 +1,29 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ SQLITE_QUERY_ROW_CAP,
5
+ formatSqliteQueryTable,
6
+ formatSqliteSchema,
7
+ formatSqliteTables,
8
+ getSqliteSchema,
9
+ getSqliteTables,
10
+ isSqliteFile,
11
+ openReadonlySqlite,
12
+ runReadOnlySqliteQuery,
13
+ validateReadOnlySelect
14
+ } from "./token-goat-chunk-LMFO66YD.mjs";
15
+ import "./token-goat-chunk-OSUFN2FV.mjs";
16
+ import "./token-goat-chunk-ERTXEKB6.mjs";
17
+ import "./token-goat-chunk-A37V4PBF.mjs";
18
+ export {
19
+ SQLITE_QUERY_ROW_CAP,
20
+ formatSqliteQueryTable,
21
+ formatSqliteSchema,
22
+ formatSqliteTables,
23
+ getSqliteSchema,
24
+ getSqliteTables,
25
+ isSqliteFile,
26
+ openReadonlySqlite,
27
+ runReadOnlySqliteQuery,
28
+ validateReadOnlySelect
29
+ };
@@ -0,0 +1,123 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ NotAnOfficeDocumentError,
5
+ collectElements,
6
+ collectParagraphTexts,
7
+ collectTextRuns,
8
+ decodeZipEntry,
9
+ ooxmlPartBudget,
10
+ parseOoxmlPart,
11
+ readOoxmlZip
12
+ } from "./token-goat-chunk-MZDIJJ3R.mjs";
13
+ import {
14
+ displaySafeText
15
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
16
+ import {
17
+ init_define_import_meta_env
18
+ } from "./token-goat-chunk-A37V4PBF.mjs";
19
+
20
+ // src/docx_extract.ts
21
+ init_define_import_meta_env();
22
+ function paragraphStyleVal(p) {
23
+ return p["w:pPr"]?.["w:pStyle"]?.["@_w:val"];
24
+ }
25
+ function headingLevel(styleVal) {
26
+ if (styleVal === void 0) return null;
27
+ if (/^title$/i.test(styleVal)) return 1;
28
+ const m = /^heading\s*(\d)$/i.exec(styleVal);
29
+ return m?.[1] !== void 0 ? parseInt(m[1], 10) : null;
30
+ }
31
+ async function loadDocumentBody(filePath) {
32
+ const entries = await readOoxmlZip(filePath, ".docx");
33
+ const xml = decodeZipEntry(entries, "word/document.xml", ooxmlPartBudget());
34
+ if (xml === null) throw new NotAnOfficeDocumentError(`no word/document.xml found in ${filePath} (not a valid .docx?)`);
35
+ return parseOoxmlPart(xml);
36
+ }
37
+ async function docxOutline(filePath) {
38
+ const parsed = await loadDocumentBody(filePath);
39
+ const paragraphs = collectElements(parsed, "w:p");
40
+ const out = [];
41
+ for (const p of paragraphs) {
42
+ const level = headingLevel(paragraphStyleVal(p));
43
+ if (level === null) continue;
44
+ const text = collectTextRuns(p, "w:t").join("").trim();
45
+ if (text.length > 0) out.push({ level, text });
46
+ }
47
+ return out;
48
+ }
49
+ async function docxText(filePath) {
50
+ const parsed = await loadDocumentBody(filePath);
51
+ const paragraphs = collectElements(parsed, "w:p");
52
+ const lines = paragraphs.map((p) => collectTextRuns(p, "w:t").join("")).filter((t) => t.trim().length > 0);
53
+ return lines.join("\n\n");
54
+ }
55
+ async function docxTables(filePath) {
56
+ const parsed = await loadDocumentBody(filePath);
57
+ const tbls = collectElements(parsed, "w:tbl", { includeNested: true });
58
+ const out = [];
59
+ for (let i = 0; i < tbls.length; i++) {
60
+ const tbl = tbls[i];
61
+ const trElements = collectElements(tbl, "w:tr");
62
+ const rows = [];
63
+ let maxCols = 0;
64
+ for (const tr of trElements) {
65
+ const tcElements = collectElements(tr, "w:tc");
66
+ const rowCells = [];
67
+ for (const tc of tcElements) {
68
+ const cellText = collectParagraphTexts(tc, "w:p", "w:t", ["w:tbl"], "w:br").map((t) => t.replace(/\r?\n/g, " ").trim()).filter((t) => t.length > 0).join(" ");
69
+ rowCells.push(cellText);
70
+ }
71
+ if (rowCells.length > maxCols) maxCols = rowCells.length;
72
+ rows.push(rowCells);
73
+ }
74
+ if (rows.length > 0) {
75
+ out.push({
76
+ tableIndex: i + 1,
77
+ rowCount: rows.length,
78
+ colCount: maxCols,
79
+ rows
80
+ });
81
+ }
82
+ }
83
+ return out;
84
+ }
85
+ function formatDocxTables(tables, opts) {
86
+ if (tables.length === 0) return "no tables found in document";
87
+ const selected = opts?.tableIndex !== void 0 ? tables.filter((t) => t.tableIndex === opts.tableIndex) : tables;
88
+ if (selected.length === 0) {
89
+ return `table ${opts?.tableIndex} not found (document has ${tables.length} table${tables.length === 1 ? "" : "s"})`;
90
+ }
91
+ const sections = [];
92
+ for (const table of selected) {
93
+ const lines = [
94
+ `Table ${table.tableIndex} (${table.rowCount} row${table.rowCount === 1 ? "" : "s"} x ${table.colCount} col${table.colCount === 1 ? "" : "s"}):`
95
+ ];
96
+ if (table.rows.length === 0) {
97
+ lines.push(" (empty)");
98
+ sections.push(lines.join("\n"));
99
+ continue;
100
+ }
101
+ const header = table.rows[0];
102
+ const padCols = Math.max(table.colCount, 1);
103
+ const paddedHeader = [...header];
104
+ while (paddedHeader.length < padCols) paddedHeader.push("");
105
+ lines.push("| " + paddedHeader.map((c) => displaySafeText(c.replace(/\|/g, "\\|"))).join(" | ") + " |");
106
+ lines.push("| " + Array.from({ length: padCols }, () => "---").join(" | ") + " |");
107
+ for (let r = 1; r < table.rows.length; r++) {
108
+ const row = table.rows[r];
109
+ const paddedRow = [...row];
110
+ while (paddedRow.length < padCols) paddedRow.push("");
111
+ lines.push("| " + paddedRow.map((c) => displaySafeText(c.replace(/\|/g, "\\|"))).join(" | ") + " |");
112
+ }
113
+ sections.push(lines.join("\n"));
114
+ }
115
+ return sections.join("\n\n");
116
+ }
117
+
118
+ export {
119
+ docxOutline,
120
+ docxText,
121
+ docxTables,
122
+ formatDocxTables
123
+ };
@@ -0,0 +1,34 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ buildEvent,
5
+ relay,
6
+ relayInProcess
7
+ } from "./token-goat-chunk-SZWYESBS.mjs";
8
+ import "./token-goat-chunk-YZX7EFG4.mjs";
9
+ import {
10
+ MAX_STDIN_BYTES,
11
+ readStdinJson
12
+ } from "./token-goat-chunk-OUGNPMDA.mjs";
13
+ import "./token-goat-chunk-BL5LNGBG.mjs";
14
+ import "./token-goat-chunk-YQ7WI2CO.mjs";
15
+ import "./token-goat-chunk-3BTK54F3.mjs";
16
+ import "./token-goat-chunk-NDRP4KJQ.mjs";
17
+ import "./token-goat-chunk-2X2EBBC6.mjs";
18
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
19
+ import "./token-goat-chunk-IVUQLQWN.mjs";
20
+ import "./token-goat-chunk-K7F2BFIK.mjs";
21
+ import "./token-goat-chunk-S4XRY446.mjs";
22
+ import "./token-goat-chunk-EEIDFMEM.mjs";
23
+ import "./token-goat-chunk-OSUFN2FV.mjs";
24
+ import "./token-goat-chunk-PM76YS22.mjs";
25
+ import "./token-goat-chunk-ERTXEKB6.mjs";
26
+ import "./token-goat-chunk-GMOUBOX4.mjs";
27
+ import "./token-goat-chunk-A37V4PBF.mjs";
28
+ export {
29
+ MAX_STDIN_BYTES,
30
+ buildEvent,
31
+ readStdinJson,
32
+ relay,
33
+ relayInProcess
34
+ };
@@ -0,0 +1,24 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ pptxAllSlidesText,
5
+ pptxNotesText,
6
+ pptxOutline,
7
+ pptxSlideText,
8
+ pptxTextGrep
9
+ } from "./token-goat-chunk-ASYEPR3S.mjs";
10
+ import "./token-goat-chunk-MZDIJJ3R.mjs";
11
+ import "./token-goat-chunk-XTQAOTSO.mjs";
12
+ import "./token-goat-chunk-AH6QILZM.mjs";
13
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
14
+ import "./token-goat-chunk-PM76YS22.mjs";
15
+ import "./token-goat-chunk-ERTXEKB6.mjs";
16
+ import "./token-goat-chunk-GMOUBOX4.mjs";
17
+ import "./token-goat-chunk-A37V4PBF.mjs";
18
+ export {
19
+ pptxAllSlidesText,
20
+ pptxNotesText,
21
+ pptxOutline,
22
+ pptxSlideText,
23
+ pptxTextGrep
24
+ };
@@ -0,0 +1,144 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ loadConfig
5
+ } from "./token-goat-chunk-S4XRY446.mjs";
6
+ import "./token-goat-chunk-EEIDFMEM.mjs";
7
+ import {
8
+ VERSION
9
+ } from "./token-goat-chunk-PM76YS22.mjs";
10
+ import {
11
+ displaySafeJson
12
+ } from "./token-goat-chunk-ERTXEKB6.mjs";
13
+ import "./token-goat-chunk-GMOUBOX4.mjs";
14
+ import {
15
+ init_define_import_meta_env
16
+ } from "./token-goat-chunk-A37V4PBF.mjs";
17
+
18
+ // src/cli_upgrade.ts
19
+ init_define_import_meta_env();
20
+ import { spawnSync } from "node:child_process";
21
+ import * as fs from "node:fs";
22
+ import * as path from "node:path";
23
+ import * as https from "node:https";
24
+ async function fetchLatestVersion(timeoutMs = 3500) {
25
+ if (loadConfig().network.offline) {
26
+ return null;
27
+ }
28
+ return new Promise((resolve) => {
29
+ const req = https.get(
30
+ "https://registry.npmjs.org/token-goat/latest",
31
+ {
32
+ headers: { "User-Agent": `token-goat/${VERSION} (node/${process.version})` },
33
+ timeout: timeoutMs
34
+ },
35
+ (res) => {
36
+ if (res.statusCode !== 200) {
37
+ res.resume();
38
+ resolve(null);
39
+ return;
40
+ }
41
+ let data = "";
42
+ res.setEncoding("utf8");
43
+ res.on("data", (chunk) => {
44
+ data += chunk;
45
+ if (data.length > 32768) {
46
+ req.destroy();
47
+ resolve(null);
48
+ }
49
+ });
50
+ res.on("end", () => {
51
+ try {
52
+ const parsed = JSON.parse(data);
53
+ resolve(typeof parsed.version === "string" ? parsed.version : null);
54
+ } catch {
55
+ resolve(null);
56
+ }
57
+ });
58
+ }
59
+ );
60
+ req.on("timeout", () => {
61
+ req.destroy();
62
+ resolve(null);
63
+ });
64
+ req.on("error", () => {
65
+ resolve(null);
66
+ });
67
+ });
68
+ }
69
+ function compareSemver(a, b) {
70
+ const pa = a.split("-")[0].split(".").map((x) => parseInt(x, 10) || 0);
71
+ const pb = b.split("-")[0].split(".").map((x) => parseInt(x, 10) || 0);
72
+ for (let i = 0; i < 3; i++) {
73
+ const na = pa[i] ?? 0;
74
+ const nb = pb[i] ?? 0;
75
+ if (na > nb) return 1;
76
+ if (na < nb) return -1;
77
+ }
78
+ return 0;
79
+ }
80
+ async function checkUpdateStatus(timeoutMs = 3500) {
81
+ const latest = await fetchLatestVersion(timeoutMs);
82
+ if (!latest) {
83
+ return {
84
+ current: VERSION,
85
+ latest: null,
86
+ updateAvailable: false,
87
+ error: "Could not reach npm registry (offline or request timed out)"
88
+ };
89
+ }
90
+ const updateAvailable = compareSemver(latest, VERSION) > 0;
91
+ return {
92
+ current: VERSION,
93
+ latest,
94
+ updateAvailable
95
+ };
96
+ }
97
+ async function cmdUpgrade(opts = {}, onSyncHooks) {
98
+ const status = await checkUpdateStatus();
99
+ if (opts.check) {
100
+ if (opts.json) {
101
+ console.log(displaySafeJson(status, 2));
102
+ return;
103
+ }
104
+ if (status.error) {
105
+ console.log(`Current version: v${status.current}`);
106
+ console.log(`[!] ${status.error}`);
107
+ return;
108
+ }
109
+ if (status.updateAvailable && status.latest) {
110
+ console.log(`Update available: v${status.current} -> v${status.latest}`);
111
+ console.log(`Run 'token-goat upgrade' to update.`);
112
+ } else {
113
+ console.log(`token-goat is up to date (v${status.current})`);
114
+ }
115
+ return;
116
+ }
117
+ const isLocalGitRepo = fs.existsSync(path.join(process.cwd(), ".git")) && fs.existsSync(path.join(process.cwd(), "esbuild.config.mjs"));
118
+ if (isLocalGitRepo) {
119
+ console.log(`Detected local token-goat development repository.`);
120
+ console.log(`To update your local build, run:`);
121
+ console.log(` git pull && npm run build && token-goat install`);
122
+ return;
123
+ }
124
+ console.log(`Upgrading token-goat to latest...`);
125
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
126
+ const npmRes = spawnSync(npmCmd, ["install", "-g", "token-goat@latest"], {
127
+ stdio: "inherit"
128
+ });
129
+ if (npmRes.status !== 0) {
130
+ console.error(`npm install failed with exit code ${npmRes.status ?? 1}.`);
131
+ process.exit(npmRes.status ?? 1);
132
+ }
133
+ console.log(`Syncing token-goat hooks and integration manifests...`);
134
+ if (onSyncHooks) {
135
+ await onSyncHooks();
136
+ }
137
+ console.log(`[\u2713] token-goat successfully updated.`);
138
+ }
139
+ export {
140
+ checkUpdateStatus,
141
+ cmdUpgrade,
142
+ compareSemver,
143
+ fetchLatestVersion
144
+ };
@@ -0,0 +1,26 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ init_define_import_meta_env
5
+ } from "./token-goat-chunk-A37V4PBF.mjs";
6
+
7
+ // src/lazy_module.ts
8
+ init_define_import_meta_env();
9
+ function createLazyModuleLoader(load, errorLabel) {
10
+ let cache;
11
+ return async () => {
12
+ if (cache !== void 0) return cache;
13
+ try {
14
+ cache = await load();
15
+ } catch (err) {
16
+ process.stderr.write(`token-goat: ${errorLabel}: ${String(err)}
17
+ `);
18
+ cache = null;
19
+ }
20
+ return cache;
21
+ };
22
+ }
23
+
24
+ export {
25
+ createLazyModuleLoader
26
+ };
@@ -0,0 +1,212 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ NotAnOfficeDocumentError,
5
+ assertOoxmlWithinDeadline,
6
+ collectElements,
7
+ collectParagraphTexts,
8
+ decodeZipEntry,
9
+ ooxmlPartBudget,
10
+ ooxmlWorkDeadline,
11
+ parseOoxmlPart,
12
+ readOoxmlZip,
13
+ sortNumberedParts
14
+ } from "./token-goat-chunk-MZDIJJ3R.mjs";
15
+ import {
16
+ compileGuardedRegex
17
+ } from "./token-goat-chunk-GMOUBOX4.mjs";
18
+ import {
19
+ init_define_import_meta_env
20
+ } from "./token-goat-chunk-A37V4PBF.mjs";
21
+
22
+ // src/pptx_extract.ts
23
+ init_define_import_meta_env();
24
+ function shapePlaceholderType(shape) {
25
+ const sp = shape;
26
+ return sp["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"]?.["@_type"];
27
+ }
28
+ function slideShapes(parsedSlide) {
29
+ return collectElements(parsedSlide, "p:sp");
30
+ }
31
+ function flatSlideText(node) {
32
+ return collectParagraphTexts(node, "a:p", "a:t", [], "a:br").map((t) => t.trim()).filter((t) => t.length > 0).join(" ");
33
+ }
34
+ function shapeText(shape) {
35
+ return flatSlideText(shape);
36
+ }
37
+ function tableRowBlocks(parsedSlide) {
38
+ const blocks = [];
39
+ for (const tbl of collectElements(parsedSlide, "a:tbl")) {
40
+ for (const row of collectElements(tbl, "a:tr")) {
41
+ const cellTexts = collectElements(row, "a:tc").map((cell) => flatSlideText(cell));
42
+ const rowText = cellTexts.join(" | ").trim();
43
+ if (rowText.length > 0) blocks.push(rowText);
44
+ }
45
+ }
46
+ return blocks;
47
+ }
48
+ async function slidePathsInPresentationOrder(entries, budget) {
49
+ const presXml = decodeZipEntry(entries, "ppt/presentation.xml", budget);
50
+ const relsXml = decodeZipEntry(entries, "ppt/_rels/presentation.xml.rels", budget);
51
+ if (presXml === null || relsXml === null) return null;
52
+ const presParsed = await parseOoxmlPart(presXml);
53
+ const relsParsed = await parseOoxmlPart(relsXml);
54
+ const ridToTarget = /* @__PURE__ */ new Map();
55
+ for (const rel of collectElements(relsParsed, "Relationship")) {
56
+ if (rel["@_Id"] !== void 0 && rel["@_Target"] !== void 0) {
57
+ ridToTarget.set(rel["@_Id"], rel["@_Target"]);
58
+ }
59
+ }
60
+ const ordered = [];
61
+ const seen = /* @__PURE__ */ new Set();
62
+ for (const sldId of collectElements(presParsed, "p:sldId")) {
63
+ const rid = sldId["@_r:id"];
64
+ if (rid === void 0) continue;
65
+ const target = ridToTarget.get(rid);
66
+ if (target === void 0) continue;
67
+ const normalized = target.startsWith("slides/") ? `ppt/${target}` : `ppt/slides/${target}`;
68
+ if (entries[normalized] === void 0 || seen.has(normalized)) continue;
69
+ seen.add(normalized);
70
+ ordered.push(normalized);
71
+ }
72
+ return ordered.length > 0 ? ordered : null;
73
+ }
74
+ async function listSlideParts(filePath) {
75
+ const entries = await readOoxmlZip(filePath, ".pptx");
76
+ const budget = ooxmlPartBudget();
77
+ const slidePaths = await slidePathsInPresentationOrder(entries, budget) ?? sortNumberedParts(
78
+ Object.keys(entries).filter((p) => /^ppt\/slides\/slide\d+\.xml$/.test(p)),
79
+ /slide(\d+)\.xml$/
80
+ );
81
+ if (slidePaths.length === 0) throw new NotAnOfficeDocumentError(`no slides found in ${filePath} (not a valid .pptx?)`);
82
+ return { entries, slidePaths, budget };
83
+ }
84
+ function relsPathFor(slidePath) {
85
+ const idx = slidePath.lastIndexOf("/");
86
+ return `${slidePath.slice(0, idx)}/_rels/${slidePath.slice(idx + 1)}.rels`;
87
+ }
88
+ function resolveRelativeTarget(basePath, target) {
89
+ const baseDir = basePath.slice(0, basePath.lastIndexOf("/"));
90
+ const segments = `${baseDir}/${target}`.split("/");
91
+ const resolved = [];
92
+ for (const segment of segments) {
93
+ if (segment === "" || segment === ".") continue;
94
+ if (segment === "..") resolved.pop();
95
+ else resolved.push(segment);
96
+ }
97
+ return resolved.join("/");
98
+ }
99
+ async function notesPathFor(entries, slidePath, budget) {
100
+ const relsXml = decodeZipEntry(entries, relsPathFor(slidePath), budget);
101
+ if (relsXml === null) return null;
102
+ const relsParsed = await parseOoxmlPart(relsXml);
103
+ for (const rel of collectElements(relsParsed, "Relationship")) {
104
+ if (rel["@_Target"] !== void 0 && rel["@_Type"]?.endsWith("/notesSlide") === true) {
105
+ return resolveRelativeTarget(slidePath, rel["@_Target"]);
106
+ }
107
+ }
108
+ return null;
109
+ }
110
+ async function parseSlide(entries, path, budget) {
111
+ const xml = decodeZipEntry(entries, path, budget);
112
+ if (xml === null) throw new Error(`missing part: ${path}`);
113
+ return parseOoxmlPart(xml);
114
+ }
115
+ async function notesTextFor(entries, notesPath, budget) {
116
+ if (notesPath === null) return "";
117
+ const xml = decodeZipEntry(entries, notesPath, budget);
118
+ if (xml === null) return "";
119
+ const parsed = await parseOoxmlPart(xml);
120
+ const shapes = collectElements(parsed, "p:sp");
121
+ const bodyShape = shapes.find((s) => shapePlaceholderType(s) === "body");
122
+ return bodyShape !== void 0 ? shapeText(bodyShape) : flatSlideText(parsed);
123
+ }
124
+ async function pptxOutline(filePath, deadline = ooxmlWorkDeadline()) {
125
+ const { entries, slidePaths, budget } = await listSlideParts(filePath);
126
+ const out = [];
127
+ for (let i = 0; i < slidePaths.length; i++) {
128
+ assertOoxmlWithinDeadline(deadline, "Narrow the read to specific slides with pptx-slide, or use a smaller deck.");
129
+ const path = slidePaths[i];
130
+ const parsed = await parseSlide(entries, path, budget);
131
+ const shapes = slideShapes(parsed);
132
+ const titleShape = shapes.find((s) => {
133
+ const t = shapePlaceholderType(s);
134
+ return t === "title" || t === "ctrTitle";
135
+ });
136
+ const title = titleShape !== void 0 ? shapeText(titleShape) : "";
137
+ const allText = flatSlideText(parsed);
138
+ const bodyChars = Math.max(0, allText.length - title.length);
139
+ const hasNotes = (await notesTextFor(entries, await notesPathFor(entries, path, budget), budget)).length > 0;
140
+ out.push({ slide: i + 1, title, bodyChars, hasNotes });
141
+ }
142
+ return out;
143
+ }
144
+ async function slideTextFromParts(entries, slidePaths, slideNumber, includeNotes, budget) {
145
+ if (slideNumber < 1 || slideNumber > slidePaths.length) {
146
+ throw new Error(`slide ${slideNumber} out of range (this deck has ${slidePaths.length} slides)`);
147
+ }
148
+ const path = slidePaths[slideNumber - 1];
149
+ const parsed = await parseSlide(entries, path, budget);
150
+ const shapes = slideShapes(parsed);
151
+ const blocks = [...shapes.map(shapeText).filter((t) => t.length > 0), ...tableRowBlocks(parsed)];
152
+ const lines = [`# Slide ${slideNumber}`, ...blocks];
153
+ if (includeNotes) {
154
+ const notes = await notesTextFor(entries, await notesPathFor(entries, path, budget), budget);
155
+ if (notes.length > 0) lines.push("", "## Speaker notes", notes);
156
+ }
157
+ return lines.join("\n\n");
158
+ }
159
+ async function pptxSlideText(filePath, slideNumber, includeNotes) {
160
+ const { entries, slidePaths, budget } = await listSlideParts(filePath);
161
+ return slideTextFromParts(entries, slidePaths, slideNumber, includeNotes, budget);
162
+ }
163
+ async function pptxAllSlidesText(filePath, includeNotes, deadline = ooxmlWorkDeadline()) {
164
+ const { entries, slidePaths, budget } = await listSlideParts(filePath);
165
+ const slideTexts = [];
166
+ for (let i = 1; i <= slidePaths.length; i++) {
167
+ assertOoxmlWithinDeadline(deadline, "Narrow the read to specific slides with pptx-slide, or use a smaller deck.");
168
+ slideTexts.push(await slideTextFromParts(entries, slidePaths, i, includeNotes, budget));
169
+ }
170
+ return slideTexts.join("\n\n");
171
+ }
172
+ async function pptxNotesText(filePath, slideNumber, deadline = ooxmlWorkDeadline()) {
173
+ const { entries, slidePaths, budget } = await listSlideParts(filePath);
174
+ const targets = slideNumber !== void 0 ? [slideNumber] : slidePaths.map((_, i) => i + 1);
175
+ const sections = [];
176
+ for (const n of targets) {
177
+ assertOoxmlWithinDeadline(deadline, "Narrow the read to one slide with the slide-number argument, or use a smaller deck.");
178
+ if (n < 1 || n > slidePaths.length) throw new Error(`slide ${n} out of range (this deck has ${slidePaths.length} slides)`);
179
+ const notesPath = await notesPathFor(entries, slidePaths[n - 1], budget);
180
+ const text = await notesTextFor(entries, notesPath, budget);
181
+ if (text.length > 0) sections.push(`# Slide ${n} notes
182
+
183
+ ${text}`);
184
+ }
185
+ return sections.join("\n\n");
186
+ }
187
+ async function pptxTextGrep(filePath, pattern, deadline = ooxmlWorkDeadline()) {
188
+ const { entries, slidePaths, budget } = await listSlideParts(filePath);
189
+ const guarded = compileGuardedRegex(pattern, "i");
190
+ if (!guarded.ok) throw new Error(`invalid --grep pattern: ${pattern} -- the pattern ${guarded.reason}`);
191
+ const re = guarded.re;
192
+ const out = [];
193
+ for (let i = 0; i < slidePaths.length; i++) {
194
+ assertOoxmlWithinDeadline(deadline, "Narrow the read to specific slides with pptx-slide, or use a smaller deck.");
195
+ const parsed = await parseSlide(entries, slidePaths[i], budget);
196
+ const text = flatSlideText(parsed);
197
+ if (re.test(text)) {
198
+ const idx = text.search(re);
199
+ const snippet = text.slice(Math.max(0, idx - 40), idx + 80).trim();
200
+ out.push({ slide: i + 1, snippet });
201
+ }
202
+ }
203
+ return out;
204
+ }
205
+
206
+ export {
207
+ pptxOutline,
208
+ pptxSlideText,
209
+ pptxAllSlidesText,
210
+ pptxNotesText,
211
+ pptxTextGrep
212
+ };