@taloswork/ose-shared 0.1.10 → 0.1.12
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/package.json +3 -3
- package/skills/document/SKILL.md +143 -215
- package/skills/document/art-directions/base.css +27 -2
- package/skills/document/art-directions/cinematic-depth.css +3 -1
- package/skills/document/art-directions/collage-paper.css +5 -1
- package/skills/document/art-directions/editorial-cut.css +5 -1
- package/skills/document/art-directions/geometric-pop.css +6 -0
- package/skills/document/art-directions/gradient-mesh.css +5 -1
- package/skills/document/art-directions/illustrated-doodle.css +5 -0
- package/skills/document/art-directions/luxury-ornament.css +4 -1
- package/skills/document/art-directions/maximalist-blocks.css +6 -0
- package/skills/document/art-directions/technical-grid.css +4 -0
- package/skills/document/assets/fonts/fonts.json +2 -2
- package/skills/document/assets/pdf-fonts/NotoSansSC-PDF-Bold.ttf +0 -0
- package/skills/document/assets/pdf-fonts/NotoSansSC-PDF-Regular.ttf +0 -0
- package/skills/document/assets/pdf-fonts/OFL.txt +93 -0
- package/skills/document/assets/pdf-fonts/README.md +35 -0
- package/skills/document/assets/tessdata/LICENSE-Apache-2.0.txt +202 -0
- package/skills/document/assets/tessdata/README.md +21 -0
- package/skills/document/assets/tessdata/chi_sim.traineddata.gz +0 -0
- package/skills/document/assets/tessdata/eng.traineddata.gz +0 -0
- package/skills/document/bin/deck-build.cjs +2311 -41
- package/skills/document/bin/deck-chart.cjs +762 -0
- package/skills/document/bin/deck-plan.cjs +802 -0
- package/skills/document/bin/deck-qa.cjs +984 -249
- package/skills/document/bin/deck-scenario.cjs +1346 -0
- package/skills/document/bin/doc-convert.cjs +130 -39
- package/skills/document/bin/doc-fill.cjs +73121 -170
- package/skills/document/bin/doc-gen.cjs +625 -68
- package/skills/document/bin/doc-run.cjs +162 -24
- package/skills/document/bin/doc-scan.cjs +13 -0
- package/skills/document/bin/doc-text.cjs +13 -0
- package/skills/document/bin/doc-validate.cjs +718 -23
- package/skills/document/bin/doc-xml.cjs +9 -5
- package/skills/document/bin/docx-annotate.cjs +95 -19
- package/skills/document/bin/fontkit.cjs +1 -0
- package/skills/document/bin/html2pptx.cjs +1372 -121
- package/skills/document/bin/ocr-worker.cjs +1 -0
- package/skills/document/bin/ocr.cjs +131 -40
- package/skills/document/bin/pdf-form.cjs +674 -177
- package/skills/document/bin/pdf-images.cjs +13 -0
- package/skills/document/bin/pdf-ops.cjs +634 -199
- package/skills/document/bin/pdf-render.cjs +19 -3
- package/skills/document/bin/pdf-tables.cjs +13 -0
- package/skills/document/bin/pptx-clone.cjs +3 -3
- package/skills/document/bin/pptx-slide.cjs +3 -3
- package/skills/document/bin/xlsx-query.cjs +192 -61
- package/skills/document/bin-reference.md +56 -33
- package/skills/document/content-pipeline.md +129 -242
- package/skills/document/deck-design.md +355 -638
- package/skills/document/layouts/README.md +46 -33
- package/skills/document/layouts/capacity.json +1 -0
- package/skills/document/layouts/slots.json +1 -1
- package/skills/document/layouts/toc-panel.tpl +1 -1
- package/skills/document/motion/README.md +3 -2
- package/skills/document/office.md +3 -3
- package/skills/document/packs/board-brief/backdrop.html +2 -0
- package/skills/document/packs/board-brief/pack.css +2 -1
- package/skills/document/packs/mckinsey-photo/backdrop.html +2 -0
- package/skills/document/packs/mckinsey-photo/pack.css +2 -1
- package/skills/document/packs/press-room/backdrop.html +2 -0
- package/skills/document/packs/press-room/pack.css +2 -1
- package/skills/document/packs/prismatic-3d/backdrop.html +2 -0
- package/skills/document/packs/prismatic-3d/pack.css +4 -1
- package/skills/document/pdf.md +53 -49
- package/skills/document/rewrite.md +241 -308
- package/skills/document/scenarios.json +1290 -0
- package/skills/document/scenarios.schema.json +103 -0
- package/skills/document/styles/README.md +15 -25
- package/skills/document/styles/_contract-defaults.css +25 -1
- package/skills/document/styles/anthropic/skin.css +6 -3
- package/skills/document/styles/apple/skin.css +4 -3
- package/skills/document/styles/bistro-warm/backdrop.html +2 -0
- package/skills/document/styles/bistro-warm/skin.css +4 -1
- package/skills/document/styles/black-gold/skin.css +6 -5
- package/skills/document/styles/bold-clash/backdrop.html +2 -0
- package/skills/document/styles/bold-clash/skin.css +2 -1
- package/skills/document/styles/branding/skin.css +4 -4
- package/skills/document/styles/campus-teal/backdrop.html +2 -0
- package/skills/document/styles/campus-teal/skin.css +2 -1
- package/skills/document/styles/cinereel/skin.css +7 -3
- package/skills/document/styles/clinic-care/backdrop.html +2 -0
- package/skills/document/styles/clinic-care/skin.css +2 -1
- package/skills/document/styles/cool/skin.css +6 -5
- package/skills/document/styles/dark-glass/backdrop.html +2 -0
- package/skills/document/styles/dark-glass/skin.css +2 -1
- package/skills/document/styles/gov-brief/backdrop.html +2 -0
- package/skills/document/styles/gov-brief/skin.css +2 -1
- package/skills/document/styles/grid-tech/backdrop.html +2 -0
- package/skills/document/styles/grid-tech/skin.css +2 -1
- package/skills/document/styles/hand-drawn/skin.css +3 -3
- package/skills/document/styles/ivory-gold/skin.css +7 -6
- package/skills/document/styles/legal-slate/backdrop.html +2 -0
- package/skills/document/styles/legal-slate/skin.css +2 -1
- package/skills/document/styles/magazine-ink/skin.css +4 -3
- package/skills/document/styles/mckinsey/skin.css +2 -1
- package/skills/document/styles/memphis/backdrop.html +2 -0
- package/skills/document/styles/memphis/skin.css +2 -1
- package/skills/document/styles/mono/skin.css +6 -2
- package/skills/document/styles/neon-cyber/backdrop.html +2 -0
- package/skills/document/styles/neon-cyber/skin.css +2 -1
- package/skills/document/styles/olive-gold/skin.css +7 -6
- package/skills/document/styles/organic-earth/backdrop.html +2 -0
- package/skills/document/styles/organic-earth/skin.css +2 -1
- package/skills/document/styles/pastel-saas/backdrop.html +2 -0
- package/skills/document/styles/pastel-saas/skin.css +2 -1
- package/skills/document/styles/portfolio-noir/backdrop.html +2 -0
- package/skills/document/styles/portfolio-noir/skin.css +2 -1
- package/skills/document/styles/retro-press/backdrop.html +2 -0
- package/skills/document/styles/retro-press/skin.css +2 -1
- package/skills/document/styles/sport-arena/backdrop.html +2 -0
- package/skills/document/styles/sport-arena/skin.css +4 -1
- package/skills/document/styles/swiss-grid/skin.css +10 -5
- package/skills/document/styles/wedding-blush/backdrop.html +2 -0
- package/skills/document/styles/wedding-blush/skin.css +4 -1
- package/skills/document/theme-system.md +85 -77
- package/skills/document/themes/README.md +7 -5
- package/skills/document/vision.md +8 -5
- package/skills/document/xlsx.md +15 -25
- package/skills/cozy-static-svg/SKILL.md +0 -76
- package/skills/cozy-static-svg/references/approved-preview.png +0 -0
- package/skills/cozy-static-svg/references/cross-platform.md +0 -73
- package/skills/cozy-static-svg/references/moon_keeps_watch.svg +0 -229
- package/skills/cozy-static-svg/references/style-anchor.md +0 -271
- package/skills/cozy-static-svg/scripts/artkit.py +0 -321
- package/skills/cozy-static-svg/scripts/to_png.py +0 -333
|
@@ -4320,7 +4320,7 @@ var require_BufferList = __commonJS({
|
|
|
4320
4320
|
this.head = this.tail = null;
|
|
4321
4321
|
this.length = 0;
|
|
4322
4322
|
};
|
|
4323
|
-
BufferList.prototype.join = function
|
|
4323
|
+
BufferList.prototype.join = function join5(s) {
|
|
4324
4324
|
if (this.length === 0) return "";
|
|
4325
4325
|
var p = this.head;
|
|
4326
4326
|
var ret2 = "" + p.data;
|
|
@@ -13959,7 +13959,7 @@ var require_buffer_list2 = __commonJS({
|
|
|
13959
13959
|
}
|
|
13960
13960
|
}, {
|
|
13961
13961
|
key: "join",
|
|
13962
|
-
value: function
|
|
13962
|
+
value: function join5(s) {
|
|
13963
13963
|
if (this.length === 0) return "";
|
|
13964
13964
|
var p = this.head;
|
|
13965
13965
|
var ret2 = "" + p.data;
|
|
@@ -41204,7 +41204,7 @@ var require_buffer_list3 = __commonJS({
|
|
|
41204
41204
|
}
|
|
41205
41205
|
}, {
|
|
41206
41206
|
key: "join",
|
|
41207
|
-
value: function
|
|
41207
|
+
value: function join5(s) {
|
|
41208
41208
|
if (this.length === 0) return "";
|
|
41209
41209
|
var p = this.head;
|
|
41210
41210
|
var ret2 = "" + p.data;
|
|
@@ -44570,7 +44570,7 @@ var require_buffer_list4 = __commonJS({
|
|
|
44570
44570
|
}
|
|
44571
44571
|
}, {
|
|
44572
44572
|
key: "join",
|
|
44573
|
-
value: function
|
|
44573
|
+
value: function join5(s) {
|
|
44574
44574
|
if (this.length === 0) return "";
|
|
44575
44575
|
var p = this.head;
|
|
44576
44576
|
var ret2 = "" + p.data;
|
|
@@ -47366,7 +47366,7 @@ var require_buffer_list5 = __commonJS({
|
|
|
47366
47366
|
}
|
|
47367
47367
|
}, {
|
|
47368
47368
|
key: "join",
|
|
47369
|
-
value: function
|
|
47369
|
+
value: function join5(s) {
|
|
47370
47370
|
if (this.length === 0) return "";
|
|
47371
47371
|
var p = this.head;
|
|
47372
47372
|
var ret2 = "" + p.data;
|
|
@@ -50236,7 +50236,7 @@ var require_buffer_list6 = __commonJS({
|
|
|
50236
50236
|
}
|
|
50237
50237
|
}, {
|
|
50238
50238
|
key: "join",
|
|
50239
|
-
value: function
|
|
50239
|
+
value: function join5(s) {
|
|
50240
50240
|
if (this.length === 0) return "";
|
|
50241
50241
|
var p = this.head;
|
|
50242
50242
|
var ret2 = "" + p.data;
|
|
@@ -53025,7 +53025,7 @@ var require_buffer_list7 = __commonJS({
|
|
|
53025
53025
|
}
|
|
53026
53026
|
}, {
|
|
53027
53027
|
key: "join",
|
|
53028
|
-
value: function
|
|
53028
|
+
value: function join5(s) {
|
|
53029
53029
|
if (this.length === 0) return "";
|
|
53030
53030
|
var p = this.head;
|
|
53031
53031
|
var ret2 = "" + p.data;
|
|
@@ -56015,7 +56015,7 @@ var require_buffer_list8 = __commonJS({
|
|
|
56015
56015
|
}
|
|
56016
56016
|
}, {
|
|
56017
56017
|
key: "join",
|
|
56018
|
-
value: function
|
|
56018
|
+
value: function join5(s) {
|
|
56019
56019
|
if (this.length === 0) return "";
|
|
56020
56020
|
var p = this.head;
|
|
56021
56021
|
var ret2 = "" + p.data;
|
|
@@ -66273,7 +66273,7 @@ var require_BufferList3 = __commonJS({
|
|
|
66273
66273
|
this.head = this.tail = null;
|
|
66274
66274
|
this.length = 0;
|
|
66275
66275
|
};
|
|
66276
|
-
BufferList.prototype.join = function
|
|
66276
|
+
BufferList.prototype.join = function join5(s) {
|
|
66277
66277
|
if (this.length === 0) return "";
|
|
66278
66278
|
var p = this.head;
|
|
66279
66279
|
var ret2 = "" + p.data;
|
|
@@ -90687,6 +90687,393 @@ var require_cjs = __commonJS({
|
|
|
90687
90687
|
}
|
|
90688
90688
|
});
|
|
90689
90689
|
|
|
90690
|
+
// packages/core/dist/document/pdf-encrypted.js
|
|
90691
|
+
var ENCRYPTED_PDF_MESSAGE, PdfEncryptedError;
|
|
90692
|
+
var init_pdf_encrypted = __esm({
|
|
90693
|
+
"packages/core/dist/document/pdf-encrypted.js"() {
|
|
90694
|
+
"use strict";
|
|
90695
|
+
ENCRYPTED_PDF_MESSAGE = "PDF is password-protected (encrypted); decrypt first: pdf-ops decrypt <in> <password> <out>";
|
|
90696
|
+
PdfEncryptedError = class extends Error {
|
|
90697
|
+
constructor() {
|
|
90698
|
+
super(ENCRYPTED_PDF_MESSAGE);
|
|
90699
|
+
this.name = "PdfEncryptedError";
|
|
90700
|
+
}
|
|
90701
|
+
};
|
|
90702
|
+
}
|
|
90703
|
+
});
|
|
90704
|
+
|
|
90705
|
+
// packages/core/dist/document/pdf-extract.js
|
|
90706
|
+
var pdf_extract_exports = {};
|
|
90707
|
+
__export(pdf_extract_exports, {
|
|
90708
|
+
analyzePdfDocument: () => analyzePdfDocument,
|
|
90709
|
+
countVectorOperators: () => countVectorOperators,
|
|
90710
|
+
decryptPdf: () => decryptPdf,
|
|
90711
|
+
encryptPdf: () => encryptPdf,
|
|
90712
|
+
extractPdfImages: () => extractPdfImages,
|
|
90713
|
+
extractPdfTables: () => extractPdfTables,
|
|
90714
|
+
extractPdfText: () => extractPdfText,
|
|
90715
|
+
extractPdfTextLines: () => extractPdfTextLines,
|
|
90716
|
+
pdfNeedsPassword: () => pdfNeedsPassword,
|
|
90717
|
+
renderPdfPages: () => renderPdfPages,
|
|
90718
|
+
scanPdfSignals: () => scanPdfSignals,
|
|
90719
|
+
textMathHint: () => textMathHint,
|
|
90720
|
+
textTableHint: () => textTableHint
|
|
90721
|
+
});
|
|
90722
|
+
function loadMupdf() {
|
|
90723
|
+
if (!_mupdf) {
|
|
90724
|
+
const deps = process.env.TALOS_SKILL_DEPS;
|
|
90725
|
+
const spec = deps ? (0, import_node_url.pathToFileURL)((0, import_node_path.join)(deps, "mupdf", "dist", "mupdf.js")).href : "mupdf";
|
|
90726
|
+
_mupdf = import(spec);
|
|
90727
|
+
}
|
|
90728
|
+
return _mupdf;
|
|
90729
|
+
}
|
|
90730
|
+
function textMathHint(text) {
|
|
90731
|
+
if (!text)
|
|
90732
|
+
return false;
|
|
90733
|
+
const hits = (text.match(MATH_CHARS) || []).length;
|
|
90734
|
+
return hits >= 3 || hits / Math.max(text.length, 1) > 0.02;
|
|
90735
|
+
}
|
|
90736
|
+
function textTableHint(text) {
|
|
90737
|
+
if (!text)
|
|
90738
|
+
return false;
|
|
90739
|
+
const gaps = (text.match(/ {2,}|\t/g) || []).length;
|
|
90740
|
+
return gaps >= 6;
|
|
90741
|
+
}
|
|
90742
|
+
async function openDoc(bytes) {
|
|
90743
|
+
const mupdf = await loadMupdf();
|
|
90744
|
+
const doc = mupdf.Document.openDocument(bytes, "application/pdf");
|
|
90745
|
+
if (doc.needsPassword())
|
|
90746
|
+
throw new PdfEncryptedError();
|
|
90747
|
+
if (doc.countPages() === 0) {
|
|
90748
|
+
throw new Error("PDF has no readable pages (corrupt, encrypted, or empty)");
|
|
90749
|
+
}
|
|
90750
|
+
return { mupdf, doc };
|
|
90751
|
+
}
|
|
90752
|
+
async function analyzePdfDocument(bytes, options = {}) {
|
|
90753
|
+
const wantText = options.text !== false;
|
|
90754
|
+
const wantSignals = options.signals === true;
|
|
90755
|
+
const { doc } = await openDoc(bytes);
|
|
90756
|
+
const pageCount = doc.countPages();
|
|
90757
|
+
const signals = [];
|
|
90758
|
+
let out = "";
|
|
90759
|
+
for (let i = 0; i < pageCount; i++) {
|
|
90760
|
+
const page = doc.loadPage(i);
|
|
90761
|
+
if (wantText) {
|
|
90762
|
+
out += `
|
|
90763
|
+
[page ${i + 1}]
|
|
90764
|
+
${page.toStructuredText().asText()}`;
|
|
90765
|
+
}
|
|
90766
|
+
if (wantSignals) {
|
|
90767
|
+
signals.push(pageSignalsFrom(page, i + 1));
|
|
90768
|
+
}
|
|
90769
|
+
}
|
|
90770
|
+
return { text: wantText ? out.trim() : "", pageCount, signals };
|
|
90771
|
+
}
|
|
90772
|
+
async function extractPdfText(bytes) {
|
|
90773
|
+
const { text, pageCount } = await analyzePdfDocument(bytes, { text: true });
|
|
90774
|
+
return { text, pageCount };
|
|
90775
|
+
}
|
|
90776
|
+
function countVectorOperators(content) {
|
|
90777
|
+
let ops = 0;
|
|
90778
|
+
let curves = 0;
|
|
90779
|
+
let fills = 0;
|
|
90780
|
+
let i = 0;
|
|
90781
|
+
const n = content.length;
|
|
90782
|
+
while (i < n) {
|
|
90783
|
+
const ch = content[i];
|
|
90784
|
+
if (ch === "(") {
|
|
90785
|
+
let depth = 1;
|
|
90786
|
+
i++;
|
|
90787
|
+
while (i < n && depth > 0) {
|
|
90788
|
+
if (content[i] === "\\")
|
|
90789
|
+
i++;
|
|
90790
|
+
else if (content[i] === "(")
|
|
90791
|
+
depth++;
|
|
90792
|
+
else if (content[i] === ")")
|
|
90793
|
+
depth--;
|
|
90794
|
+
i++;
|
|
90795
|
+
}
|
|
90796
|
+
continue;
|
|
90797
|
+
}
|
|
90798
|
+
if (ch === "<" && content[i + 1] !== "<") {
|
|
90799
|
+
while (i < n && content[i] !== ">")
|
|
90800
|
+
i++;
|
|
90801
|
+
i++;
|
|
90802
|
+
continue;
|
|
90803
|
+
}
|
|
90804
|
+
if (ch === "I" && content[i + 1] === "D" && isDelimiter(content[i + 2])) {
|
|
90805
|
+
const end = content.indexOf("EI", i + 2);
|
|
90806
|
+
i = end === -1 ? n : end + 2;
|
|
90807
|
+
continue;
|
|
90808
|
+
}
|
|
90809
|
+
if (!isDelimiter(ch)) {
|
|
90810
|
+
const start = i;
|
|
90811
|
+
while (i < n && !isDelimiter(content[i]))
|
|
90812
|
+
i++;
|
|
90813
|
+
const token = content.slice(start, i);
|
|
90814
|
+
switch (token) {
|
|
90815
|
+
case "m":
|
|
90816
|
+
case "l":
|
|
90817
|
+
case "re":
|
|
90818
|
+
ops++;
|
|
90819
|
+
break;
|
|
90820
|
+
case "c":
|
|
90821
|
+
case "v":
|
|
90822
|
+
case "y":
|
|
90823
|
+
ops++;
|
|
90824
|
+
curves++;
|
|
90825
|
+
break;
|
|
90826
|
+
case "f":
|
|
90827
|
+
case "F":
|
|
90828
|
+
case "f*":
|
|
90829
|
+
fills++;
|
|
90830
|
+
break;
|
|
90831
|
+
case "B":
|
|
90832
|
+
case "B*":
|
|
90833
|
+
case "b":
|
|
90834
|
+
case "b*":
|
|
90835
|
+
fills++;
|
|
90836
|
+
break;
|
|
90837
|
+
default:
|
|
90838
|
+
break;
|
|
90839
|
+
}
|
|
90840
|
+
continue;
|
|
90841
|
+
}
|
|
90842
|
+
i++;
|
|
90843
|
+
}
|
|
90844
|
+
return { ops, curves, fills };
|
|
90845
|
+
}
|
|
90846
|
+
function isDelimiter(ch) {
|
|
90847
|
+
return ch === void 0 || ch === " " || ch === "\n" || ch === "\r" || ch === " " || ch === "\f" || ch === "\0" || ch === "[" || ch === "]" || ch === "/" || ch === "{" || ch === "}";
|
|
90848
|
+
}
|
|
90849
|
+
function pageContentStream(page) {
|
|
90850
|
+
try {
|
|
90851
|
+
const obj2 = page.getObject?.();
|
|
90852
|
+
const contents = obj2?.get?.("Contents");
|
|
90853
|
+
if (!contents)
|
|
90854
|
+
return "";
|
|
90855
|
+
const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_2, i) => contents.get(i)) : [contents];
|
|
90856
|
+
let out = "";
|
|
90857
|
+
for (const stream of streams) {
|
|
90858
|
+
const buf = stream?.readStream?.();
|
|
90859
|
+
const bytes = buf?.asUint8Array?.();
|
|
90860
|
+
if (bytes)
|
|
90861
|
+
out += Buffer.from(bytes).toString("latin1");
|
|
90862
|
+
}
|
|
90863
|
+
return out;
|
|
90864
|
+
} catch {
|
|
90865
|
+
return "";
|
|
90866
|
+
}
|
|
90867
|
+
}
|
|
90868
|
+
function pageSignalsFrom(page, pageNumber) {
|
|
90869
|
+
const json = JSON.parse(page.toStructuredText("preserve-images").asJSON());
|
|
90870
|
+
const blocks = json.blocks ?? [];
|
|
90871
|
+
const text = blocks.flatMap((b) => (b.lines ?? []).map((l2) => l2.text ?? "")).join(" ");
|
|
90872
|
+
const [x0, y0, x1, y1] = page.getBounds();
|
|
90873
|
+
const pageArea = Math.max((x1 - x0) * (y1 - y0), 1);
|
|
90874
|
+
const imgArea = blocks.filter((b) => b.type === "image").reduce((a, b) => a + Math.max((b.bbox?.w ?? 0) * (b.bbox?.h ?? 0), 0), 0);
|
|
90875
|
+
const vector = countVectorOperators(pageContentStream(page));
|
|
90876
|
+
return {
|
|
90877
|
+
page: pageNumber,
|
|
90878
|
+
textChars: text.trim().length,
|
|
90879
|
+
imageCoverage: Math.min(imgArea / pageArea, 1),
|
|
90880
|
+
vectorOps: vector.ops,
|
|
90881
|
+
vectorCurves: vector.curves,
|
|
90882
|
+
vectorFills: vector.fills,
|
|
90883
|
+
mathHint: textMathHint(text),
|
|
90884
|
+
tableHint: textTableHint(text)
|
|
90885
|
+
};
|
|
90886
|
+
}
|
|
90887
|
+
async function scanPdfSignals(bytes) {
|
|
90888
|
+
const { signals } = await analyzePdfDocument(bytes, { text: false, signals: true });
|
|
90889
|
+
return signals;
|
|
90890
|
+
}
|
|
90891
|
+
function median(nums) {
|
|
90892
|
+
if (!nums.length)
|
|
90893
|
+
return 0;
|
|
90894
|
+
const s = [...nums].sort((a, b) => a - b);
|
|
90895
|
+
return s[Math.floor(s.length / 2)];
|
|
90896
|
+
}
|
|
90897
|
+
async function extractPdfTables(bytes, pageNum, minColumns = 2) {
|
|
90898
|
+
const { doc } = await openDoc(bytes);
|
|
90899
|
+
const total = doc.countPages();
|
|
90900
|
+
const from = pageNum ? pageNum : 1;
|
|
90901
|
+
const to = pageNum ? pageNum : total;
|
|
90902
|
+
const out = [];
|
|
90903
|
+
for (let p = from; p <= to; p++) {
|
|
90904
|
+
if (p < 1 || p > total)
|
|
90905
|
+
continue;
|
|
90906
|
+
const json = JSON.parse(doc.loadPage(p - 1).toStructuredText().asJSON());
|
|
90907
|
+
const cells = [];
|
|
90908
|
+
for (const b of json.blocks ?? []) {
|
|
90909
|
+
if (b.type === "image")
|
|
90910
|
+
continue;
|
|
90911
|
+
for (const l2 of b.lines ?? []) {
|
|
90912
|
+
const text = (l2.text ?? "").trim();
|
|
90913
|
+
if (!text)
|
|
90914
|
+
continue;
|
|
90915
|
+
cells.push({ text, x: l2.bbox?.x ?? 0, y: l2.bbox?.y ?? 0, h: l2.bbox?.h ?? 12 });
|
|
90916
|
+
}
|
|
90917
|
+
}
|
|
90918
|
+
if (cells.length < 2)
|
|
90919
|
+
continue;
|
|
90920
|
+
const medH = median(cells.map((c) => c.h)) || 12;
|
|
90921
|
+
const rowTol = Math.max(4, medH * 0.6);
|
|
90922
|
+
const colTol = Math.max(6, medH * 0.9);
|
|
90923
|
+
const byY = [...cells].sort((a, b) => a.y - b.y);
|
|
90924
|
+
const rowGroups = [];
|
|
90925
|
+
let rowRef = Number.NEGATIVE_INFINITY;
|
|
90926
|
+
for (const c of byY) {
|
|
90927
|
+
if (c.y - rowRef > rowTol) {
|
|
90928
|
+
rowGroups.push([]);
|
|
90929
|
+
rowRef = c.y;
|
|
90930
|
+
}
|
|
90931
|
+
rowGroups[rowGroups.length - 1].push(c);
|
|
90932
|
+
}
|
|
90933
|
+
const colRefs = [];
|
|
90934
|
+
for (const x of cells.map((c) => c.x).sort((a, b) => a - b)) {
|
|
90935
|
+
if (!colRefs.length || x - colRefs[colRefs.length - 1] > colTol)
|
|
90936
|
+
colRefs.push(x);
|
|
90937
|
+
}
|
|
90938
|
+
const colIndex = (x) => {
|
|
90939
|
+
let best = 0, bd = Infinity;
|
|
90940
|
+
colRefs.forEach((r, i) => {
|
|
90941
|
+
const d = Math.abs(x - r);
|
|
90942
|
+
if (d < bd) {
|
|
90943
|
+
bd = d;
|
|
90944
|
+
best = i;
|
|
90945
|
+
}
|
|
90946
|
+
});
|
|
90947
|
+
return best;
|
|
90948
|
+
};
|
|
90949
|
+
const rows = [];
|
|
90950
|
+
for (const group of rowGroups) {
|
|
90951
|
+
const arr = Array(colRefs.length).fill("");
|
|
90952
|
+
for (const c of group.sort((a, b) => a.x - b.x)) {
|
|
90953
|
+
const i = colIndex(c.x);
|
|
90954
|
+
arr[i] = arr[i] ? `${arr[i]} ${c.text}` : c.text;
|
|
90955
|
+
}
|
|
90956
|
+
if (arr.filter((v) => v).length >= minColumns)
|
|
90957
|
+
rows.push(arr);
|
|
90958
|
+
}
|
|
90959
|
+
if (rows.length)
|
|
90960
|
+
out.push({ page: p, rows });
|
|
90961
|
+
}
|
|
90962
|
+
return out;
|
|
90963
|
+
}
|
|
90964
|
+
async function extractPdfTextLines(bytes) {
|
|
90965
|
+
const { doc } = await openDoc(bytes);
|
|
90966
|
+
const out = [];
|
|
90967
|
+
for (let p = 1; p <= doc.countPages(); p++) {
|
|
90968
|
+
const page = doc.loadPage(p - 1);
|
|
90969
|
+
const [x0, y0, x1, y1] = page.getBounds();
|
|
90970
|
+
const json = JSON.parse(page.toStructuredText().asJSON());
|
|
90971
|
+
const lines = [];
|
|
90972
|
+
for (const b of json.blocks ?? []) {
|
|
90973
|
+
if (b.type === "image")
|
|
90974
|
+
continue;
|
|
90975
|
+
for (const l2 of b.lines ?? []) {
|
|
90976
|
+
const text = l2.text ?? "";
|
|
90977
|
+
if (!text.trim() || !l2.bbox)
|
|
90978
|
+
continue;
|
|
90979
|
+
lines.push({
|
|
90980
|
+
x: l2.bbox.x ?? 0,
|
|
90981
|
+
y: l2.bbox.y ?? 0,
|
|
90982
|
+
w: l2.bbox.w ?? 0,
|
|
90983
|
+
h: l2.bbox.h ?? 0,
|
|
90984
|
+
size: l2.font?.size ?? 12,
|
|
90985
|
+
text
|
|
90986
|
+
});
|
|
90987
|
+
}
|
|
90988
|
+
}
|
|
90989
|
+
out.push({ page: p, width: x1 - x0, height: y1 - y0, lines });
|
|
90990
|
+
}
|
|
90991
|
+
return out;
|
|
90992
|
+
}
|
|
90993
|
+
async function renderPdfPages(bytes, pages, scale = 2, maxEdge) {
|
|
90994
|
+
const { mupdf, doc } = await openDoc(bytes);
|
|
90995
|
+
const total = doc.countPages();
|
|
90996
|
+
const wanted = pages === "all" ? Array.from({ length: total }, (_2, i) => i + 1) : pages;
|
|
90997
|
+
const out = [];
|
|
90998
|
+
for (const p of wanted) {
|
|
90999
|
+
if (p < 1 || p > total)
|
|
91000
|
+
continue;
|
|
91001
|
+
const page = doc.loadPage(p - 1);
|
|
91002
|
+
const [x0, y0, x1, y1] = page.getBounds();
|
|
91003
|
+
const longest = Math.max(x1 - x0, y1 - y0);
|
|
91004
|
+
const s = maxEdge && longest > 0 ? Math.min(scale, maxEdge / longest) : scale;
|
|
91005
|
+
const pix = page.toPixmap(mupdf.Matrix.scale(s, s), mupdf.ColorSpace.DeviceRGB, false, true);
|
|
91006
|
+
out.push({ page: p, png: pix.asPNG() });
|
|
91007
|
+
}
|
|
91008
|
+
return out;
|
|
91009
|
+
}
|
|
91010
|
+
async function extractPdfImages(bytes, pages) {
|
|
91011
|
+
const { doc } = await openDoc(bytes);
|
|
91012
|
+
const total = doc.countPages();
|
|
91013
|
+
const wanted = pages && pages.length ? pages : Array.from({ length: total }, (_2, i) => i + 1);
|
|
91014
|
+
const images = [];
|
|
91015
|
+
let skipped = 0;
|
|
91016
|
+
for (const p of wanted) {
|
|
91017
|
+
if (p < 1 || p > total)
|
|
91018
|
+
continue;
|
|
91019
|
+
const stext = doc.loadPage(p - 1).toStructuredText("preserve-images");
|
|
91020
|
+
let index = 0;
|
|
91021
|
+
stext.walk({
|
|
91022
|
+
onImageBlock(bbox, _matrix, image) {
|
|
91023
|
+
const slot = index++;
|
|
91024
|
+
try {
|
|
91025
|
+
const png = image.toPixmap().asPNG();
|
|
91026
|
+
images.push({
|
|
91027
|
+
page: p,
|
|
91028
|
+
index: slot,
|
|
91029
|
+
bbox: [bbox[0], bbox[1], bbox[2], bbox[3]],
|
|
91030
|
+
width: image.getWidth(),
|
|
91031
|
+
height: image.getHeight(),
|
|
91032
|
+
png
|
|
91033
|
+
});
|
|
91034
|
+
} catch {
|
|
91035
|
+
skipped++;
|
|
91036
|
+
}
|
|
91037
|
+
}
|
|
91038
|
+
});
|
|
91039
|
+
}
|
|
91040
|
+
return { images, skipped };
|
|
91041
|
+
}
|
|
91042
|
+
async function encryptPdf(bytes, userPassword, ownerPassword) {
|
|
91043
|
+
if (!userPassword)
|
|
91044
|
+
throw new Error("a non-empty user password is required");
|
|
91045
|
+
const { doc } = await openDoc(bytes);
|
|
91046
|
+
const opts = `encrypt=aes-256,user-password=${userPassword},owner-password=${ownerPassword || userPassword}`;
|
|
91047
|
+
return doc.saveToBuffer(opts).asUint8Array();
|
|
91048
|
+
}
|
|
91049
|
+
async function pdfNeedsPassword(bytes) {
|
|
91050
|
+
const mupdf = await loadMupdf();
|
|
91051
|
+
const doc = mupdf.Document.openDocument(bytes, "application/pdf");
|
|
91052
|
+
return doc.needsPassword();
|
|
91053
|
+
}
|
|
91054
|
+
async function decryptPdf(bytes, password) {
|
|
91055
|
+
const mupdf = await loadMupdf();
|
|
91056
|
+
const doc = mupdf.Document.openDocument(bytes, "application/pdf");
|
|
91057
|
+
if (doc.needsPassword()) {
|
|
91058
|
+
if (doc.authenticatePassword(password) === 0)
|
|
91059
|
+
throw new Error("wrong password");
|
|
91060
|
+
}
|
|
91061
|
+
if (doc.countPages() === 0)
|
|
91062
|
+
throw new Error("PDF has no readable pages (corrupt or empty)");
|
|
91063
|
+
return doc.saveToBuffer("encrypt=none").asUint8Array();
|
|
91064
|
+
}
|
|
91065
|
+
var import_node_path, import_node_url, _mupdf, MATH_CHARS;
|
|
91066
|
+
var init_pdf_extract = __esm({
|
|
91067
|
+
"packages/core/dist/document/pdf-extract.js"() {
|
|
91068
|
+
"use strict";
|
|
91069
|
+
import_node_path = require("node:path");
|
|
91070
|
+
import_node_url = require("node:url");
|
|
91071
|
+
init_pdf_encrypted();
|
|
91072
|
+
_mupdf = null;
|
|
91073
|
+
MATH_CHARS = /[=∑∫√≤≥≠±∞πθλμσΩ×÷∂∇→←↔∈∉⊂⊃∀∃]/g;
|
|
91074
|
+
}
|
|
91075
|
+
});
|
|
91076
|
+
|
|
90690
91077
|
// apps/admin/data/skills.lib/document/bin-src/doc-gen.mjs
|
|
90691
91078
|
var import_promises2 = require("node:fs/promises");
|
|
90692
91079
|
|
|
@@ -94311,7 +94698,7 @@ var require_buffer_list = /* @__PURE__ */ __commonJSMin(((exports2, module2) =>
|
|
|
94311
94698
|
},
|
|
94312
94699
|
{
|
|
94313
94700
|
key: "join",
|
|
94314
|
-
value: function
|
|
94701
|
+
value: function join5(s) {
|
|
94315
94702
|
if (this.length === 0) return "";
|
|
94316
94703
|
var p = this.head;
|
|
94317
94704
|
var ret2 = "" + p.data;
|
|
@@ -98748,6 +99135,46 @@ var createShading = ({ fill, color, type }) => new BuilderElement({
|
|
|
98748
99135
|
}
|
|
98749
99136
|
}
|
|
98750
99137
|
});
|
|
99138
|
+
var ShadingType = {
|
|
99139
|
+
/** Clear shading - no pattern, fill color only */
|
|
99140
|
+
CLEAR: "clear",
|
|
99141
|
+
DIAGONAL_CROSS: "diagCross",
|
|
99142
|
+
DIAGONAL_STRIPE: "diagStripe",
|
|
99143
|
+
HORIZONTAL_CROSS: "horzCross",
|
|
99144
|
+
HORIZONTAL_STRIPE: "horzStripe",
|
|
99145
|
+
NIL: "nil",
|
|
99146
|
+
PERCENT_5: "pct5",
|
|
99147
|
+
PERCENT_10: "pct10",
|
|
99148
|
+
PERCENT_12: "pct12",
|
|
99149
|
+
PERCENT_15: "pct15",
|
|
99150
|
+
PERCENT_20: "pct20",
|
|
99151
|
+
PERCENT_25: "pct25",
|
|
99152
|
+
PERCENT_30: "pct30",
|
|
99153
|
+
PERCENT_35: "pct35",
|
|
99154
|
+
PERCENT_37: "pct37",
|
|
99155
|
+
PERCENT_40: "pct40",
|
|
99156
|
+
PERCENT_45: "pct45",
|
|
99157
|
+
PERCENT_50: "pct50",
|
|
99158
|
+
PERCENT_55: "pct55",
|
|
99159
|
+
PERCENT_60: "pct60",
|
|
99160
|
+
PERCENT_62: "pct62",
|
|
99161
|
+
PERCENT_65: "pct65",
|
|
99162
|
+
PERCENT_70: "pct70",
|
|
99163
|
+
PERCENT_75: "pct75",
|
|
99164
|
+
PERCENT_80: "pct80",
|
|
99165
|
+
PERCENT_85: "pct85",
|
|
99166
|
+
PERCENT_87: "pct87",
|
|
99167
|
+
PERCENT_90: "pct90",
|
|
99168
|
+
PERCENT_95: "pct95",
|
|
99169
|
+
REVERSE_DIAGONAL_STRIPE: "reverseDiagStripe",
|
|
99170
|
+
SOLID: "solid",
|
|
99171
|
+
THIN_DIAGONAL_CROSS: "thinDiagCross",
|
|
99172
|
+
THIN_DIAGONAL_STRIPE: "thinDiagStripe",
|
|
99173
|
+
THIN_HORIZONTAL_CROSS: "thinHorzCross",
|
|
99174
|
+
THIN_REVERSE_DIAGONAL_STRIPE: "thinReverseDiagStripe",
|
|
99175
|
+
THIN_VERTICAL_STRIPE: "thinVertStripe",
|
|
99176
|
+
VERTICAL_STRIPE: "vertStripe"
|
|
99177
|
+
};
|
|
98751
99178
|
var ChangeAttributes = class extends XmlAttributeComponent {
|
|
98752
99179
|
constructor(..._args) {
|
|
98753
99180
|
super(..._args);
|
|
@@ -110210,8 +110637,9 @@ function docxBlock(b, theme) {
|
|
|
110210
110637
|
const isHeader = Boolean(b.header && i === 0);
|
|
110211
110638
|
return new TableCell({
|
|
110212
110639
|
width: { size: columnWidths[columnIndex] ?? 0, type: WidthType.DXA },
|
|
110213
|
-
// Themed header row background (the visible "not cheap" cue).
|
|
110214
|
-
|
|
110640
|
+
// Themed header row background (the visible "not cheap" cue). w:shd
|
|
110641
|
+
// requires w:val — a fill-only shading fails the strict XSD gate.
|
|
110642
|
+
...isHeader ? { shading: { type: ShadingType.CLEAR, color: "auto", fill: bareHex(theme.colors.tableHeaderBg) } } : {},
|
|
110215
110643
|
children: [new Paragraph({ children: [new TextRun({ text: String(c), bold: isHeader })] })]
|
|
110216
110644
|
});
|
|
110217
110645
|
})
|
|
@@ -110424,6 +110852,17 @@ async function validatePdf(bytes) {
|
|
|
110424
110852
|
try {
|
|
110425
110853
|
const doc = await import_pdf_lib.PDFDocument.load(bytes, { ignoreEncryption: true, throwOnInvalidObject: true, updateMetadata: false });
|
|
110426
110854
|
pages = doc.getPageCount();
|
|
110855
|
+
if (doc.isEncrypted) {
|
|
110856
|
+
const { pdfNeedsPassword: pdfNeedsPassword2 } = await Promise.resolve().then(() => (init_pdf_extract(), pdf_extract_exports));
|
|
110857
|
+
if (await pdfNeedsPassword2(bytes).catch(() => true)) {
|
|
110858
|
+
errors.push({
|
|
110859
|
+
code: "pdf-encrypted",
|
|
110860
|
+
message: "the PDF needs a password to open, so its content cannot be checked or rendered \u2014 validate (and render) the unencrypted file before `pdf-ops encrypt`; to inspect this one, `pdf-ops decrypt <in> <password> <out>` first"
|
|
110861
|
+
});
|
|
110862
|
+
return { ok: false, kind: "pdf", errors, warnings, pages };
|
|
110863
|
+
}
|
|
110864
|
+
warnings.push({ code: "pdf-encrypted", message: 'the PDF is encrypted with an owner password only: it opens without a password, but pdf-form / pdf-ops cannot edit it until `pdf-ops decrypt <in> "" <out>`' });
|
|
110865
|
+
}
|
|
110427
110866
|
if (pages === 0)
|
|
110428
110867
|
errors.push({ code: "pdf-no-pages", message: "the PDF parses but has no pages" });
|
|
110429
110868
|
else
|
|
@@ -110652,40 +111091,8 @@ async function validateOoxml(bytes) {
|
|
|
110652
111091
|
return result(root.kind);
|
|
110653
111092
|
}
|
|
110654
111093
|
|
|
110655
|
-
//
|
|
110656
|
-
|
|
110657
|
-
var import_node_url = require("node:url");
|
|
110658
|
-
var _mupdf = null;
|
|
110659
|
-
function loadMupdf() {
|
|
110660
|
-
if (!_mupdf) {
|
|
110661
|
-
const deps = process.env.TALOS_SKILL_DEPS;
|
|
110662
|
-
const spec = deps ? (0, import_node_url.pathToFileURL)((0, import_node_path.join)(deps, "mupdf", "dist", "mupdf.js")).href : "mupdf";
|
|
110663
|
-
_mupdf = import(spec);
|
|
110664
|
-
}
|
|
110665
|
-
return _mupdf;
|
|
110666
|
-
}
|
|
110667
|
-
async function openDoc(bytes) {
|
|
110668
|
-
const mupdf = await loadMupdf();
|
|
110669
|
-
const doc = mupdf.Document.openDocument(bytes, "application/pdf");
|
|
110670
|
-
if (doc.countPages() === 0) {
|
|
110671
|
-
throw new Error("PDF has no readable pages (corrupt, encrypted, or empty)");
|
|
110672
|
-
}
|
|
110673
|
-
return { mupdf, doc };
|
|
110674
|
-
}
|
|
110675
|
-
async function renderPdfPages(bytes, pages, scale = 2) {
|
|
110676
|
-
const { mupdf, doc } = await openDoc(bytes);
|
|
110677
|
-
const total = doc.countPages();
|
|
110678
|
-
const wanted = pages === "all" ? Array.from({ length: total }, (_2, i) => i + 1) : pages;
|
|
110679
|
-
const out = [];
|
|
110680
|
-
const matrix = mupdf.Matrix.scale(scale, scale);
|
|
110681
|
-
for (const p of wanted) {
|
|
110682
|
-
if (p < 1 || p > total)
|
|
110683
|
-
continue;
|
|
110684
|
-
const pix = doc.loadPage(p - 1).toPixmap(matrix, mupdf.ColorSpace.DeviceRGB, false, true);
|
|
110685
|
-
out.push({ page: p, png: pix.asPNG() });
|
|
110686
|
-
}
|
|
110687
|
-
return out;
|
|
110688
|
-
}
|
|
111094
|
+
// apps/admin/data/skills.lib/document/bin-src/doc-gen.mjs
|
|
111095
|
+
init_pdf_extract();
|
|
110689
111096
|
|
|
110690
111097
|
// packages/core/dist/document/html-escape.js
|
|
110691
111098
|
function escapeHtml(value) {
|
|
@@ -110870,6 +111277,11 @@ async function fontManifest() {
|
|
|
110870
111277
|
}
|
|
110871
111278
|
return _fontManifest;
|
|
110872
111279
|
}
|
|
111280
|
+
var _faceB64 = /* @__PURE__ */ new Map();
|
|
111281
|
+
async function faceBase64(path) {
|
|
111282
|
+
if (!_faceB64.has(path)) _faceB64.set(path, (await (0, import_promises.readFile)(path).catch(() => null))?.toString("base64") ?? null);
|
|
111283
|
+
return _faceB64.get(path);
|
|
111284
|
+
}
|
|
110873
111285
|
async function faceCss(entries, range, doc) {
|
|
110874
111286
|
const { dir } = await fontManifest();
|
|
110875
111287
|
const rules = [];
|
|
@@ -110878,7 +111290,7 @@ async function faceCss(entries, range, doc) {
|
|
|
110878
111290
|
if (!families.length) continue;
|
|
110879
111291
|
const path = (0, import_node_path2.join)(dir, entry.file);
|
|
110880
111292
|
if (!(0, import_node_fs.existsSync)(path)) continue;
|
|
110881
|
-
const b64 =
|
|
111293
|
+
const b64 = await faceBase64(path);
|
|
110882
111294
|
if (!b64) continue;
|
|
110883
111295
|
for (const family of families) {
|
|
110884
111296
|
rules.push(
|
|
@@ -110888,22 +111300,21 @@ async function faceCss(entries, range, doc) {
|
|
|
110888
111300
|
}
|
|
110889
111301
|
return rules.join("");
|
|
110890
111302
|
}
|
|
110891
|
-
var
|
|
111303
|
+
var _faceCssBySet = /* @__PURE__ */ new Map();
|
|
111304
|
+
async function cachedFaceCss(group, entries, range, doc) {
|
|
111305
|
+
const named = (entries ?? []).flatMap((e) => (e.families ?? []).filter((f) => doc.includes(f)));
|
|
111306
|
+
const key = `${group}|${named.join("|")}`;
|
|
111307
|
+
if (!_faceCssBySet.has(key)) _faceCssBySet.set(key, await faceCss(entries, range, doc));
|
|
111308
|
+
return _faceCssBySet.get(key);
|
|
111309
|
+
}
|
|
110892
111310
|
async function cjkFontFaceCss(doc) {
|
|
110893
|
-
if (
|
|
110894
|
-
|
|
110895
|
-
|
|
110896
|
-
}
|
|
110897
|
-
return _cjkFontCss;
|
|
111311
|
+
if (process.env.TALOS_CJK_FONTS === "system") return "";
|
|
111312
|
+
const m = await fontManifest();
|
|
111313
|
+
return cachedFaceCss("cjk", m.cjk, m.cjkUnicodeRange, doc);
|
|
110898
111314
|
}
|
|
110899
|
-
var _latinFontCss;
|
|
110900
111315
|
async function latinFontFaceCss(doc) {
|
|
110901
|
-
|
|
110902
|
-
|
|
110903
|
-
const wanted = (m.latin ?? []).filter((e) => (e.families ?? []).some((f) => doc.includes(f)));
|
|
110904
|
-
_latinFontCss = await faceCss(wanted, void 0);
|
|
110905
|
-
}
|
|
110906
|
-
return _latinFontCss;
|
|
111316
|
+
const m = await fontManifest();
|
|
111317
|
+
return cachedFaceCss("latin", m.latin, void 0, doc);
|
|
110907
111318
|
}
|
|
110908
111319
|
function injectStyle(html, css) {
|
|
110909
111320
|
const tag = `<style>${css}</style>`;
|
|
@@ -110927,8 +111338,8 @@ async function renderPdfHeadless(html, print = {}) {
|
|
|
110927
111338
|
}
|
|
110928
111339
|
|
|
110929
111340
|
// apps/admin/data/skills.lib/document/bin-src/doc-gen.mjs
|
|
110930
|
-
var
|
|
110931
|
-
var
|
|
111341
|
+
var import_node_path4 = require("node:path");
|
|
111342
|
+
var import_node_fs3 = require("node:fs");
|
|
110932
111343
|
var import_node_crypto = require("node:crypto");
|
|
110933
111344
|
|
|
110934
111345
|
// packages/core/dist/document/doc-palette.js
|
|
@@ -111166,6 +111577,142 @@ function listPalettes() {
|
|
|
111166
111577
|
return PALETTE_LIBRARY.map(({ name, mood, dark }) => ({ name, mood, dark }));
|
|
111167
111578
|
}
|
|
111168
111579
|
|
|
111580
|
+
// packages/core/dist/document/deck-catalog.js
|
|
111581
|
+
var KINDS = ["skin", "pack"];
|
|
111582
|
+
var MODES = ["light", "dark"];
|
|
111583
|
+
var RENDER_MODES = ["classic-v1", "theme-v2"];
|
|
111584
|
+
var ID_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
111585
|
+
var COMMIT_RE = /^[0-9a-f]{7,40}$/;
|
|
111586
|
+
function isStr(v) {
|
|
111587
|
+
return typeof v === "string" && v.length > 0;
|
|
111588
|
+
}
|
|
111589
|
+
function isStrArr(v) {
|
|
111590
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
111591
|
+
}
|
|
111592
|
+
function parseCatalog(raw) {
|
|
111593
|
+
const errors = [];
|
|
111594
|
+
const o = raw;
|
|
111595
|
+
if (!o || typeof o !== "object")
|
|
111596
|
+
return { catalog: null, errors: ["catalog is not an object"] };
|
|
111597
|
+
const groups = [];
|
|
111598
|
+
const rawGroups = Array.isArray(o.groups) ? o.groups : [];
|
|
111599
|
+
if (!Array.isArray(o.groups))
|
|
111600
|
+
errors.push("catalog.groups must be an array");
|
|
111601
|
+
rawGroups.forEach((g, i) => {
|
|
111602
|
+
const at = `group[${i}]`;
|
|
111603
|
+
if (!isStr(g?.id) || !ID_RE.test(g.id))
|
|
111604
|
+
errors.push(`${at}: bad id`);
|
|
111605
|
+
if (!isStr(g?.name_cn))
|
|
111606
|
+
errors.push(`${at}: missing name_cn`);
|
|
111607
|
+
if (!isStr(g?.sample))
|
|
111608
|
+
errors.push(`${at}: missing sample`);
|
|
111609
|
+
if (!isStrArr(g?.scenarios))
|
|
111610
|
+
errors.push(`${at}: scenarios must be a string array`);
|
|
111611
|
+
if (isStr(g?.id) && isStr(g?.name_cn) && isStr(g?.sample) && isStrArr(g?.scenarios)) {
|
|
111612
|
+
groups.push({ id: g.id, name_cn: g.name_cn, sample: g.sample, scenarios: g.scenarios });
|
|
111613
|
+
}
|
|
111614
|
+
});
|
|
111615
|
+
const collections = [];
|
|
111616
|
+
const rawCollections = o.collections === void 0 ? [] : Array.isArray(o.collections) ? o.collections : [];
|
|
111617
|
+
if (o.collections !== void 0 && !Array.isArray(o.collections))
|
|
111618
|
+
errors.push("catalog.collections must be an array when present");
|
|
111619
|
+
rawCollections.forEach((c, i) => {
|
|
111620
|
+
const at = `collection[${i}]`;
|
|
111621
|
+
const before = errors.length;
|
|
111622
|
+
if (!isStr(c?.id) || !ID_RE.test(c.id))
|
|
111623
|
+
errors.push(`${at}: bad id`);
|
|
111624
|
+
if (!isStr(c?.name_cn))
|
|
111625
|
+
errors.push(`${at}: missing name_cn`);
|
|
111626
|
+
if (!isStr(c?.renderMode) || !RENDER_MODES.includes(c.renderMode))
|
|
111627
|
+
errors.push(`${at}: bad renderMode`);
|
|
111628
|
+
if (!isStrArr(c?.entryIds) || c.entryIds.length === 0)
|
|
111629
|
+
errors.push(`${at}: entryIds must be a non-empty string array`);
|
|
111630
|
+
if (c?.sourceCommit !== void 0 && (!isStr(c.sourceCommit) || !COMMIT_RE.test(c.sourceCommit)))
|
|
111631
|
+
errors.push(`${at}: bad sourceCommit`);
|
|
111632
|
+
if (c?.renderMode === "classic-v1" && c?.sourceCommit === void 0)
|
|
111633
|
+
errors.push(`${at}: classic-v1 requires sourceCommit`);
|
|
111634
|
+
if (errors.length === before) {
|
|
111635
|
+
collections.push({
|
|
111636
|
+
id: c.id,
|
|
111637
|
+
name_cn: c.name_cn,
|
|
111638
|
+
renderMode: c.renderMode,
|
|
111639
|
+
entryIds: c.entryIds,
|
|
111640
|
+
...c.sourceCommit !== void 0 ? { sourceCommit: c.sourceCommit } : {}
|
|
111641
|
+
});
|
|
111642
|
+
}
|
|
111643
|
+
});
|
|
111644
|
+
const entries = [];
|
|
111645
|
+
const rawEntries = Array.isArray(o.entries) ? o.entries : [];
|
|
111646
|
+
if (!Array.isArray(o.entries))
|
|
111647
|
+
errors.push("catalog.entries must be an array");
|
|
111648
|
+
rawEntries.forEach((e, i) => {
|
|
111649
|
+
const at = `entry[${i}]${isStr(e?.id) ? ` (${e.id})` : ""}`;
|
|
111650
|
+
const before = errors.length;
|
|
111651
|
+
if (!isStr(e?.id) || !ID_RE.test(e.id))
|
|
111652
|
+
errors.push(`${at}: bad id`);
|
|
111653
|
+
if (!isStr(e?.kind) || !KINDS.includes(e.kind))
|
|
111654
|
+
errors.push(`${at}: kind must be "skin" or "pack"`);
|
|
111655
|
+
if (!isStr(e?.group))
|
|
111656
|
+
errors.push(`${at}: missing group`);
|
|
111657
|
+
if (!isStr(e?.name_cn))
|
|
111658
|
+
errors.push(`${at}: missing name_cn`);
|
|
111659
|
+
if (!isStr(e?.oneliner))
|
|
111660
|
+
errors.push(`${at}: missing oneliner`);
|
|
111661
|
+
if (!isStrArr(e?.scenarios))
|
|
111662
|
+
errors.push(`${at}: scenarios must be a string array`);
|
|
111663
|
+
if (!isStr(e?.mode) || !MODES.includes(e.mode))
|
|
111664
|
+
errors.push(`${at}: mode must be "light" or "dark"`);
|
|
111665
|
+
if (!isStr(e?.sample))
|
|
111666
|
+
errors.push(`${at}: missing sample`);
|
|
111667
|
+
if (e?.motion !== void 0 && !isStr(e.motion))
|
|
111668
|
+
errors.push(`${at}: motion must be a string when present`);
|
|
111669
|
+
if (errors.length === before) {
|
|
111670
|
+
entries.push({
|
|
111671
|
+
id: e.id,
|
|
111672
|
+
kind: e.kind,
|
|
111673
|
+
group: e.group,
|
|
111674
|
+
name_cn: e.name_cn,
|
|
111675
|
+
oneliner: e.oneliner,
|
|
111676
|
+
scenarios: e.scenarios,
|
|
111677
|
+
mode: e.mode,
|
|
111678
|
+
sample: e.sample,
|
|
111679
|
+
...e.motion !== void 0 ? { motion: e.motion } : {}
|
|
111680
|
+
});
|
|
111681
|
+
}
|
|
111682
|
+
});
|
|
111683
|
+
return { catalog: errors.length ? null : { groups, ...collections.length ? { collections } : {}, entries }, errors };
|
|
111684
|
+
}
|
|
111685
|
+
function resolveEntry(catalog, id) {
|
|
111686
|
+
return catalog.entries.find((e) => e.id === id) ?? null;
|
|
111687
|
+
}
|
|
111688
|
+
function assetDirOf(entry) {
|
|
111689
|
+
return entry.kind === "skin" ? `styles/${entry.id}` : `packs/${entry.id}`;
|
|
111690
|
+
}
|
|
111691
|
+
function cssFileOf(entry) {
|
|
111692
|
+
return entry.kind === "skin" ? "skin.css" : "pack.css";
|
|
111693
|
+
}
|
|
111694
|
+
|
|
111695
|
+
// apps/admin/data/skills.lib/document/bin-src/lib/user-styles.mjs
|
|
111696
|
+
var import_node_fs2 = require("node:fs");
|
|
111697
|
+
var import_node_path3 = require("node:path");
|
|
111698
|
+
var SAFE_NAME = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
111699
|
+
function userStylesDir() {
|
|
111700
|
+
return process.env.TALOS_DOC_STYLES_DIR?.trim() || null;
|
|
111701
|
+
}
|
|
111702
|
+
function userSkinDir(name) {
|
|
111703
|
+
const root = userStylesDir();
|
|
111704
|
+
if (!root || !SAFE_NAME.test(name)) return null;
|
|
111705
|
+
const dir = (0, import_node_path3.join)(root, "styles", name);
|
|
111706
|
+
return (0, import_node_fs2.existsSync)((0, import_node_path3.join)(dir, "skin.css")) ? dir : null;
|
|
111707
|
+
}
|
|
111708
|
+
function userThemePath(name) {
|
|
111709
|
+
const root = userStylesDir();
|
|
111710
|
+
const base = name.replace(/\.json$/i, "");
|
|
111711
|
+
if (!root || !SAFE_NAME.test(base)) return null;
|
|
111712
|
+
const path = (0, import_node_path3.join)(root, "themes", `${base}.json`);
|
|
111713
|
+
return (0, import_node_fs2.existsSync)(path) ? path : null;
|
|
111714
|
+
}
|
|
111715
|
+
|
|
111169
111716
|
// apps/admin/data/skills.lib/document/bin-src/doc-gen.mjs
|
|
111170
111717
|
function die(msg, code = 1) {
|
|
111171
111718
|
process.stderr.write(`doc-gen: ${msg}
|
|
@@ -111173,7 +111720,7 @@ function die(msg, code = 1) {
|
|
|
111173
111720
|
process.exit(code);
|
|
111174
111721
|
}
|
|
111175
111722
|
async function writeArtifactAtomically(out, bytes) {
|
|
111176
|
-
const temp = (0,
|
|
111723
|
+
const temp = (0, import_node_path4.join)((0, import_node_path4.dirname)(out), `.${(0, import_node_path4.basename)(out)}.${process.pid}.${(0, import_node_crypto.randomUUID)()}.tmp`);
|
|
111177
111724
|
try {
|
|
111178
111725
|
await (0, import_promises2.writeFile)(temp, Buffer.from(bytes), { flag: "wx" });
|
|
111179
111726
|
await (0, import_promises2.rename)(temp, out);
|
|
@@ -111237,6 +111784,7 @@ async function main() {
|
|
|
111237
111784
|
themePath = args[themeIdx + 1];
|
|
111238
111785
|
if (!themePath) die("--theme needs a path to a theme.json", 64);
|
|
111239
111786
|
args.splice(themeIdx, 2);
|
|
111787
|
+
if (!(0, import_node_fs3.existsSync)(themePath)) themePath = userThemePath(themePath) ?? themePath;
|
|
111240
111788
|
}
|
|
111241
111789
|
const topicFlag = takeFlag(args, "--topic");
|
|
111242
111790
|
const paletteFlag = takeFlag(args, "--palette");
|
|
@@ -111272,9 +111820,18 @@ async function main() {
|
|
|
111272
111820
|
} else if (accentFlag || styleFlag) {
|
|
111273
111821
|
let accent = accentFlag;
|
|
111274
111822
|
if (!accent && styleFlag) {
|
|
111275
|
-
const skillDir = (0,
|
|
111276
|
-
|
|
111277
|
-
|
|
111823
|
+
const skillDir = (0, import_node_path4.dirname)((0, import_node_path4.dirname)(process.argv[1] || ""));
|
|
111824
|
+
let skinPath = (0, import_node_path4.join)(styleFlag, "skin.css");
|
|
111825
|
+
if (!(0, import_node_fs3.existsSync)(skinPath)) {
|
|
111826
|
+
const user = userSkinDir(styleFlag);
|
|
111827
|
+
skinPath = user ? (0, import_node_path4.join)(user, "skin.css") : (0, import_node_path4.join)(skillDir, "styles", styleFlag, "skin.css");
|
|
111828
|
+
try {
|
|
111829
|
+
const { catalog } = parseCatalog(JSON.parse(await (0, import_promises2.readFile)((0, import_node_path4.join)(skillDir, "catalog.json"), "utf-8")));
|
|
111830
|
+
const entry = catalog ? resolveEntry(catalog, styleFlag) : null;
|
|
111831
|
+
if (entry) skinPath = (0, import_node_path4.join)(skillDir, assetDirOf(entry), cssFileOf(entry));
|
|
111832
|
+
} catch {
|
|
111833
|
+
}
|
|
111834
|
+
}
|
|
111278
111835
|
let skinCss;
|
|
111279
111836
|
try {
|
|
111280
111837
|
skinCss = await (0, import_promises2.readFile)(skinPath, "utf-8");
|
|
@@ -111282,7 +111839,7 @@ async function main() {
|
|
|
111282
111839
|
die(`--style: cannot read ${skinPath}`, 66);
|
|
111283
111840
|
}
|
|
111284
111841
|
accent = skinAccentColor(skinCss);
|
|
111285
|
-
if (!accent) die(`--style ${styleFlag}: no hex --accent in
|
|
111842
|
+
if (!accent) die(`--style ${styleFlag}: no hex --accent in ${skinPath}`, 65);
|
|
111286
111843
|
}
|
|
111287
111844
|
rawTheme = accentOnlyTheme(accent);
|
|
111288
111845
|
if (!rawTheme.colors) process.stderr.write(`doc-gen: --accent ${accent}: not a #rrggbb hex; using plain black-on-white
|
|
@@ -111333,7 +111890,7 @@ async function reportPdf(out, bytes, spec, noPreview) {
|
|
|
111333
111890
|
if (!noPreview && validation.ok) {
|
|
111334
111891
|
try {
|
|
111335
111892
|
for (const r of await renderPdfPages(bytes, "all", 1)) {
|
|
111336
|
-
const dest = (0,
|
|
111893
|
+
const dest = (0, import_node_path4.join)((0, import_node_path4.dirname)(out), `${(0, import_node_path4.basename)(out).replace(/\.[^.]+$/, "")}_p${r.page}.png`);
|
|
111337
111894
|
await (0, import_promises2.writeFile)(dest, Buffer.from(r.png));
|
|
111338
111895
|
previews.push(dest);
|
|
111339
111896
|
}
|