@taloswork/ose-shared 0.1.15 → 0.1.17

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 (33) hide show
  1. package/package.json +3 -3
  2. package/skills/document/SKILL.md +20 -15
  3. package/skills/document/assets/fonts/fonts.json +1 -1
  4. package/skills/document/bin/deck-build.cjs +2 -1
  5. package/skills/document/bin/deck-chart.cjs +2 -1
  6. package/skills/document/bin/deck-qa.cjs +58 -43
  7. package/skills/document/bin/doc-convert.cjs +53971 -14710
  8. package/skills/document/bin/doc-fill.cjs +7 -5
  9. package/skills/document/bin/doc-gen.cjs +66172 -27127
  10. package/skills/document/bin/doc-scan.cjs +13 -9
  11. package/skills/document/bin/doc-text.cjs +13 -9
  12. package/skills/document/bin/doc-validate.cjs +15 -12
  13. package/skills/document/bin/html2pptx.cjs +84 -40
  14. package/skills/document/bin/ocr.cjs +14 -4
  15. package/skills/document/bin/pdf-form.cjs +31 -14
  16. package/skills/document/bin/pdf-images.cjs +22 -4
  17. package/skills/document/bin/pdf-ops.cjs +31 -14
  18. package/skills/document/bin/pdf-render.cjs +21 -3
  19. package/skills/document/bin/pdf-tables.cjs +7 -1
  20. package/skills/document/bin/pptx-clone.cjs +9 -16
  21. package/skills/document/bin/pptx-slide.cjs +9 -16
  22. package/skills/document/bin/template-skin.cjs +7 -1
  23. package/skills/document/bin/xlsx-recalc.cjs +9 -2
  24. package/skills/document/bin-reference.md +5 -5
  25. package/skills/document/content-pipeline.md +18 -21
  26. package/skills/document/deck-design.md +2 -2
  27. package/skills/document/rewrite.md +21 -16
  28. package/skills/document/vision.md +1 -1
  29. package/skills/expert-create/LICENSE.txt +7 -0
  30. package/skills/expert-create/SKILL.md +106 -0
  31. package/skills/expert-create/bin/expert-create.cjs +96 -0
  32. package/skills/expert-create/references/role-guide.md +24 -0
  33. package/skills/image-layout/SKILL.md +3 -3
@@ -46,9 +46,15 @@ function textTableHint(text) {
46
46
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
47
47
  return gaps >= 6;
48
48
  }
49
+ function openPdf(mupdf, bytes) {
50
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
51
+ if (!doc)
52
+ throw new Error("not a PDF document");
53
+ return doc;
54
+ }
49
55
  async function openDoc(bytes) {
50
56
  const mupdf = await loadMupdf();
51
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
57
+ const doc = openPdf(mupdf, bytes);
52
58
  if (doc.needsPassword())
53
59
  throw new PdfEncryptedError();
54
60
  if (doc.countPages() === 0) {
@@ -151,17 +157,15 @@ function isDelimiter(ch) {
151
157
  }
152
158
  function pageContentStream(page) {
153
159
  try {
154
- const obj = page.getObject?.();
155
- const contents = obj?.get?.("Contents");
156
- if (!contents)
160
+ const contents = page.getObject().get("Contents");
161
+ if (contents.isNull())
157
162
  return "";
158
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
163
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
159
164
  let out = "";
160
165
  for (const stream of streams) {
161
- const buf = stream?.readStream?.();
162
- const bytes = buf?.asUint8Array?.();
163
- if (bytes)
164
- out += Buffer.from(bytes).toString("latin1");
166
+ if (!stream.isStream())
167
+ continue;
168
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
165
169
  }
166
170
  return out;
167
171
  } catch {
@@ -46,9 +46,15 @@ function textTableHint(text) {
46
46
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
47
47
  return gaps >= 6;
48
48
  }
49
+ function openPdf(mupdf, bytes) {
50
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
51
+ if (!doc)
52
+ throw new Error("not a PDF document");
53
+ return doc;
54
+ }
49
55
  async function openDoc(bytes) {
50
56
  const mupdf = await loadMupdf();
51
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
57
+ const doc = openPdf(mupdf, bytes);
52
58
  if (doc.needsPassword())
53
59
  throw new PdfEncryptedError();
54
60
  if (doc.countPages() === 0) {
@@ -155,17 +161,15 @@ function isDelimiter(ch) {
155
161
  }
156
162
  function pageContentStream(page) {
157
163
  try {
158
- const obj = page.getObject?.();
159
- const contents = obj?.get?.("Contents");
160
- if (!contents)
164
+ const contents = page.getObject().get("Contents");
165
+ if (contents.isNull())
161
166
  return "";
162
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
167
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
163
168
  let out = "";
164
169
  for (const stream of streams) {
165
- const buf = stream?.readStream?.();
166
- const bytes = buf?.asUint8Array?.();
167
- if (bytes)
168
- out += Buffer.from(bytes).toString("latin1");
170
+ if (!stream.isStream())
171
+ continue;
172
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
169
173
  }
170
174
  return out;
171
175
  } catch {
@@ -27639,9 +27639,15 @@ function textTableHint(text) {
27639
27639
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
27640
27640
  return gaps >= 6;
27641
27641
  }
27642
+ function openPdf(mupdf, bytes) {
27643
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
27644
+ if (!doc)
27645
+ throw new Error("not a PDF document");
27646
+ return doc;
27647
+ }
27642
27648
  async function openDoc(bytes) {
27643
27649
  const mupdf = await loadMupdf();
27644
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
27650
+ const doc = openPdf(mupdf, bytes);
27645
27651
  if (doc.needsPassword())
27646
27652
  throw new PdfEncryptedError();
27647
27653
  if (doc.countPages() === 0) {
@@ -27748,17 +27754,15 @@ function isDelimiter(ch) {
27748
27754
  }
27749
27755
  function pageContentStream(page) {
27750
27756
  try {
27751
- const obj = page.getObject?.();
27752
- const contents = obj?.get?.("Contents");
27753
- if (!contents)
27757
+ const contents = page.getObject().get("Contents");
27758
+ if (contents.isNull())
27754
27759
  return "";
27755
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
27760
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
27756
27761
  let out = "";
27757
27762
  for (const stream of streams) {
27758
- const buf = stream?.readStream?.();
27759
- const bytes = buf?.asUint8Array?.();
27760
- if (bytes)
27761
- out += Buffer.from(bytes).toString("latin1");
27763
+ if (!stream.isStream())
27764
+ continue;
27765
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
27762
27766
  }
27763
27767
  return out;
27764
27768
  } catch {
@@ -27955,12 +27959,11 @@ async function encryptPdf(bytes, userPassword, ownerPassword) {
27955
27959
  }
27956
27960
  async function pdfNeedsPassword(bytes) {
27957
27961
  const mupdf = await loadMupdf();
27958
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
27959
- return doc.needsPassword();
27962
+ return openPdf(mupdf, bytes).needsPassword();
27960
27963
  }
27961
27964
  async function decryptPdf(bytes, password) {
27962
27965
  const mupdf = await loadMupdf();
27963
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
27966
+ const doc = openPdf(mupdf, bytes);
27964
27967
  if (doc.needsPassword()) {
27965
27968
  if (doc.authenticatePassword(password) === 0)
27966
27969
  throw new Error("wrong password");
@@ -33260,9 +33260,15 @@ function textTableHint(text) {
33260
33260
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
33261
33261
  return gaps >= 6;
33262
33262
  }
33263
+ function openPdf(mupdf, bytes) {
33264
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
33265
+ if (!doc)
33266
+ throw new Error("not a PDF document");
33267
+ return doc;
33268
+ }
33263
33269
  async function openDoc(bytes) {
33264
33270
  const mupdf = await loadMupdf();
33265
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
33271
+ const doc = openPdf(mupdf, bytes);
33266
33272
  if (doc.needsPassword())
33267
33273
  throw new PdfEncryptedError();
33268
33274
  if (doc.countPages() === 0) {
@@ -33369,17 +33375,15 @@ function isDelimiter(ch) {
33369
33375
  }
33370
33376
  function pageContentStream(page) {
33371
33377
  try {
33372
- const obj = page.getObject?.();
33373
- const contents = obj?.get?.("Contents");
33374
- if (!contents)
33378
+ const contents = page.getObject().get("Contents");
33379
+ if (contents.isNull())
33375
33380
  return "";
33376
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
33381
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
33377
33382
  let out = "";
33378
33383
  for (const stream of streams) {
33379
- const buf = stream?.readStream?.();
33380
- const bytes = buf?.asUint8Array?.();
33381
- if (bytes)
33382
- out += Buffer.from(bytes).toString("latin1");
33384
+ if (!stream.isStream())
33385
+ continue;
33386
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
33383
33387
  }
33384
33388
  return out;
33385
33389
  } catch {
@@ -33576,12 +33580,11 @@ async function encryptPdf(bytes, userPassword, ownerPassword) {
33576
33580
  }
33577
33581
  async function pdfNeedsPassword(bytes) {
33578
33582
  const mupdf = await loadMupdf();
33579
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
33580
- return doc.needsPassword();
33583
+ return openPdf(mupdf, bytes).needsPassword();
33581
33584
  }
33582
33585
  async function decryptPdf(bytes, password) {
33583
33586
  const mupdf = await loadMupdf();
33584
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
33587
+ const doc = openPdf(mupdf, bytes);
33585
33588
  if (doc.needsPassword()) {
33586
33589
  if (doc.authenticatePassword(password) === 0)
33587
33590
  throw new Error("wrong password");
@@ -35945,6 +35948,21 @@ async function stripDanglingOverrides(bytes) {
35945
35948
  return new Uint8Array(await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" }));
35946
35949
  }
35947
35950
 
35951
+ // packages/core/dist/shared/cjs-interop.js
35952
+ function cjsExport(mod, is, name) {
35953
+ const fromDefault = typeof mod === "object" && mod !== null && "default" in mod ? mod.default : void 0;
35954
+ if (is(fromDefault))
35955
+ return fromDefault;
35956
+ if (is(mod))
35957
+ return mod;
35958
+ throw new Error(`${name}: its API is on neither the module's default export nor its namespace`);
35959
+ }
35960
+
35961
+ // packages/core/dist/shared/guards.js
35962
+ function isRecord(value) {
35963
+ return value !== null && typeof value === "object" && !Array.isArray(value);
35964
+ }
35965
+
35948
35966
  // packages/core/dist/document/text-slack.js
35949
35967
  var SLACK_CJK_RE = /[\u3000-\u303F\u3400-\u9FFF\uF900-\uFAFF\uFF00-\uFFEF]/;
35950
35968
  var PCT = { single: { cjk: 0.22, latin: 0.16 }, multi: { cjk: 0.1, latin: 0.06 } };
@@ -36228,6 +36246,7 @@ function debandRaster(src) {
36228
36246
  }
36229
36247
 
36230
36248
  // packages/core/dist/document/html-pptx.js
36249
+ var NATIVE_CHART_TYPES = ["bar", "line", "pie", "doughnut", "area", "radar", "scatter"];
36231
36250
  var DEFAULT_CHART_RAMP = ["2563EB", "10B981", "F59E0B", "EF4444", "8B5CF6", "06B6D4"];
36232
36251
  var BAKED_INK_MIN = 0.03;
36233
36252
  var BAKED_INK_DELTA = 48;
@@ -36678,8 +36697,7 @@ async function convertLayoutToPptx(snapshot) {
36678
36697
  }
36679
36698
  const sx = SLIDE_W_IN / snapshot.width;
36680
36699
  const sy = SLIDE_H_IN / snapshot.height;
36681
- const mod = await Promise.resolve().then(() => __toESM(require_pptxgen_cjs(), 1));
36682
- const PptxGen = mod.default ?? mod;
36700
+ const PptxGen = await loadPptxGenJS();
36683
36701
  const pptx = new PptxGen();
36684
36702
  pptx.defineLayout({ name: "TALOS_HTML_WIDE", width: SLIDE_W_IN, height: SLIDE_H_IN });
36685
36703
  pptx.layout = "TALOS_HTML_WIDE";
@@ -36853,21 +36871,22 @@ async function convertLayoutToPptx(snapshot) {
36853
36871
  break;
36854
36872
  }
36855
36873
  case "chart": {
36856
- let spec;
36874
+ let parsed;
36857
36875
  try {
36858
- spec = JSON.parse(el.chart);
36876
+ parsed = JSON.parse(el.chart);
36859
36877
  } catch {
36860
36878
  warnings.push(`${where} (chart): invalid data-chart JSON \u2014 dropped`);
36861
36879
  break;
36862
36880
  }
36863
- const labels = Array.isArray(spec?.labels) ? spec.labels.map(String) : [];
36864
- const series = Array.isArray(spec?.series) ? spec.series.filter((s) => s && Array.isArray(s.values)) : [];
36881
+ const spec = isRecord(parsed) ? parsed : {};
36882
+ const labels = Array.isArray(spec.labels) ? spec.labels.map(String) : [];
36883
+ const series = Array.isArray(spec.series) ? spec.series.filter((s) => isRecord(s) && Array.isArray(s.values)) : [];
36865
36884
  if (!labels.length || !series.length) {
36866
36885
  warnings.push(`${where} (chart): needs labels + a series with values \u2014 dropped`);
36867
36886
  break;
36868
36887
  }
36869
36888
  const points = series.map((s, si) => {
36870
- const name = s.name ?? "";
36889
+ const name = s.name == null ? "" : String(s.name);
36871
36890
  const raw = s.values;
36872
36891
  const at = `${where} (chart): series ${si + 1}${name ? ` "${name}"` : ""}`;
36873
36892
  if (raw.length !== labels.length) {
@@ -36881,9 +36900,9 @@ async function convertLayoutToPptx(snapshot) {
36881
36900
  });
36882
36901
  const horizontal = spec.type === "barH" || spec.horizontal === true;
36883
36902
  const rawType = spec.type === "barH" ? "bar" : spec.type;
36884
- const type = ["bar", "line", "pie", "doughnut", "area", "radar", "scatter"].includes(rawType) ? rawType : "bar";
36885
- const ramp = (Array.isArray(spec.colors) && spec.colors.length ? spec.colors : DEFAULT_CHART_RAMP).map((c) => cssColorToHex(c) ?? String(c).replace("#", "")).filter(Boolean);
36886
- const axis = cssColorToHex(spec.axisColor) ?? "44474F";
36903
+ const type = NATIVE_CHART_TYPES.find((t) => t === rawType) ?? "bar";
36904
+ const ramp = (Array.isArray(spec.colors) && spec.colors.length ? spec.colors : DEFAULT_CHART_RAMP).map((c) => cssColorToHex(String(c)) ?? String(c).replace("#", "")).filter(Boolean);
36905
+ const axis = cssColorToHex(typeof spec.axisColor === "string" ? spec.axisColor : void 0) ?? "44474F";
36887
36906
  const multi = series.length > 1;
36888
36907
  slide.addChart(type, points, {
36889
36908
  x: frame.x,
@@ -36920,7 +36939,7 @@ async function convertLayoutToPptx(snapshot) {
36920
36939
  perSlideAnims.push(slideAnims);
36921
36940
  perSlideTransitions.push(slideSpec.transition);
36922
36941
  }
36923
- let buf = await pptx.write("nodebuffer");
36942
+ let buf = await pptx.write({ outputType: "nodebuffer" });
36924
36943
  if (gradients.length)
36925
36944
  buf = await injectGradients(buf, gradients);
36926
36945
  buf = await withCjkThemeFont(buf, deckLangs, deckZh);
@@ -36933,12 +36952,14 @@ async function convertLayoutToPptx(snapshot) {
36933
36952
  ...heal.missing.length ? { missingText: heal.missing } : {}
36934
36953
  };
36935
36954
  }
36955
+ async function loadPptxGenJS() {
36956
+ return cjsExport(await Promise.resolve().then(() => __toESM(require_pptxgen_cjs(), 1)), (m) => typeof m === "function", "pptxgenjs");
36957
+ }
36936
36958
  async function imagesToPptx(imagesBase64Png) {
36937
36959
  if (!Array.isArray(imagesBase64Png) || imagesBase64Png.length === 0) {
36938
36960
  throw new Error("imagesToPptx needs at least one PNG");
36939
36961
  }
36940
- const mod = await Promise.resolve().then(() => __toESM(require_pptxgen_cjs(), 1));
36941
- const PptxGen = mod.default ?? mod;
36962
+ const PptxGen = await loadPptxGenJS();
36942
36963
  const pptx = new PptxGen();
36943
36964
  pptx.defineLayout({ name: "TALOS_HTML_WIDE", width: SLIDE_W_IN, height: SLIDE_H_IN });
36944
36965
  pptx.layout = "TALOS_HTML_WIDE";
@@ -36947,7 +36968,7 @@ async function imagesToPptx(imagesBase64Png) {
36947
36968
  throw new Error("imagesToPptx: every entry must be a base64 PNG string");
36948
36969
  pptx.addSlide().addImage({ data: `data:image/png;base64,${b64}`, x: 0, y: 0, w: SLIDE_W_IN, h: SLIDE_H_IN });
36949
36970
  }
36950
- const buf = await pptx.write("nodebuffer");
36971
+ const buf = await pptx.write({ outputType: "nodebuffer" });
36951
36972
  return finalizePptx(new Uint8Array(buf));
36952
36973
  }
36953
36974
 
@@ -37042,6 +37063,13 @@ var DECOR_RELEASE_JS = `(() => {
37042
37063
  document.querySelectorAll("[data-talos-decor-wrap]").forEach((el) => el.removeAttribute("data-talos-decor-wrap"));
37043
37064
  return true;
37044
37065
  })()`;
37066
+ function captureClip(frame) {
37067
+ const x = Math.max(0, Math.round(frame?.x ?? NaN));
37068
+ const y = Math.max(0, Math.round(frame?.y ?? NaN));
37069
+ const w = Math.min(1280 - x, Math.round(frame?.w ?? NaN));
37070
+ const h = Math.min(720 - y, Math.round(frame?.h ?? NaN));
37071
+ return w > 0 && h > 0 ? { x, y, w, h } : void 0;
37072
+ }
37045
37073
  function placeDecorPicture(elements, dataUri) {
37046
37074
  const rest = elements.filter((e) => !e || e.kind !== "decor");
37047
37075
  return dataUri ? [{ kind: "image", frame: { x: 0, y: 0, w: 1280, h: 720 }, data: dataUri }, ...rest] : rest;
@@ -37319,8 +37347,31 @@ ${TEMPLATE_CENTER_JS}
37319
37347
  continue;
37320
37348
  }
37321
37349
  const fill = color(cs.backgroundColor);
37322
- const bw = parseFloat(cs.borderTopWidth);
37323
- const borderColor = bw > 0 && cs.borderTopStyle !== "none" ? color(cs.borderTopColor) : undefined;
37350
+ // Borders, per side. Four equal sides \u2192 the rect's own outline. Otherwise
37351
+ // each painted side is its own bar filled with the border color, on the
37352
+ // border-box edge (a lone left rule on a takeaway, a top rule on a card):
37353
+ // reading the top side alone dropped a left rule and outlined all four
37354
+ // sides of a top-only one. The bars are square-ended \u2014 a rounded corner's
37355
+ // curve is not followed.
37356
+ const sides = ["Top", "Right", "Bottom", "Left"].map((s) => {
37357
+ const w = parseFloat(cs["border" + s + "Width"]);
37358
+ const st = cs["border" + s + "Style"];
37359
+ const c = w > 0 && st !== "none" && st !== "hidden" ? color(cs["border" + s + "Color"]) : undefined;
37360
+ return c ? { w, st, c } : null;
37361
+ });
37362
+ const s0 = sides[0];
37363
+ const uniform = s0 && sides.every((s) => s && s.w === s0.w && s.st === s0.st && s.c === s0.c);
37364
+ const borderColor = uniform ? s0.c : undefined;
37365
+ const bw = uniform ? s0.w : 0;
37366
+ const borderBars = uniform ? [] : sides.flatMap((s, i) => {
37367
+ if (!s) return [];
37368
+ const f = rel(r);
37369
+ const bar = i === 0 ? { x: f.x, y: f.y, w: f.w, h: s.w }
37370
+ : i === 1 ? { x: f.x + f.w - s.w, y: f.y, w: s.w, h: f.h }
37371
+ : i === 2 ? { x: f.x, y: f.y + f.h - s.w, w: f.w, h: s.w }
37372
+ : { x: f.x, y: f.y, w: s.w, h: f.h };
37373
+ return [{ kind: "rect", frame: bar, fill: s.c, radiusPx: 0, ...(ea ? { anim: ea } : {}) }];
37374
+ });
37324
37375
  // box-shadow \u2192 native pptx outer shadow: the FIRST NON-INSET layer (computed
37325
37376
  // serialization is "color offX offY blur spread[ inset]", layers comma-joined).
37326
37377
  // An inset layer beside it (cool/apple cards' 1px top highlight) is dropped \u2014
@@ -37358,13 +37409,14 @@ ${TEMPLATE_CENTER_JS}
37358
37409
  elements.push({
37359
37410
  kind: "rect", frame: rel(r), fill, borderColor,
37360
37411
  ...(borderColor ? { borderWidthPx: bw } : {}),
37361
- ...(borderColor && (cs.borderTopStyle === "dashed" || cs.borderTopStyle === "dotted") ? { borderDash: true } : {}),
37412
+ ...(borderColor && (s0.st === "dashed" || s0.st === "dotted") ? { borderDash: true } : {}),
37362
37413
  ...(shadow ? { shadow } : {}),
37363
37414
  ...(gradient ? { gradient } : {}),
37364
37415
  radiusPx: parseFloat(cs.borderTopLeftRadius) || 0,
37365
37416
  ...(ea ? { anim: ea } : {}),
37366
37417
  });
37367
37418
  }
37419
+ elements.push(...borderBars);
37368
37420
  walk(child);
37369
37421
  }
37370
37422
  };
@@ -37551,15 +37603,12 @@ async function snapshotHeadless(page, opts = {}) {
37551
37603
  for (const el of els) {
37552
37604
  if (!el || el.kind !== "capture")
37553
37605
  continue;
37554
- const f = el.frame ?? {};
37555
- const x = Math.max(0, Math.round(f.x));
37556
- const y = Math.max(0, Math.round(f.y));
37557
- const w = Math.min(1280 - x, Math.round(f.w));
37558
- const h = Math.min(720 - y, Math.round(f.h));
37559
- if (w <= 0 || h <= 0) {
37606
+ const clip = captureClip(el.frame);
37607
+ if (!clip) {
37560
37608
  el.kind = "__drop";
37561
37609
  continue;
37562
37610
  }
37611
+ const { x, y, w, h } = clip;
37563
37612
  try {
37564
37613
  if (el.capId && await page.evaluate(captureIsolateJs(String(el.capId))))
37565
37614
  await sleep(CAPTURE_SETTLE_MS);
@@ -39303,11 +39352,6 @@ function cssFileOf(entry) {
39303
39352
  return entry.kind === "skin" ? "skin.css" : "pack.css";
39304
39353
  }
39305
39354
 
39306
- // packages/core/dist/shared/guards.js
39307
- function isRecord(value) {
39308
- return value !== null && typeof value === "object" && !Array.isArray(value);
39309
- }
39310
-
39311
39355
  // packages/core/dist/document/deck-theme-system.js
39312
39356
  var ID_RE2 = /^[a-z0-9][a-z0-9-]*$/;
39313
39357
  var PATH_RE = /^[a-z0-9_./-]+\.css$/i;
@@ -8061,6 +8061,19 @@ function getTalosOsCacheDir() {
8061
8061
  return (0, import_node_path.join)(xdg ? xdg : (0, import_node_path.join)((0, import_node_os.homedir)(), ".cache"), "talos");
8062
8062
  }
8063
8063
 
8064
+ // packages/core/dist/shared/cjs-interop.js
8065
+ function cjsExport(mod, is, name) {
8066
+ const fromDefault = typeof mod === "object" && mod !== null && "default" in mod ? mod.default : void 0;
8067
+ if (is(fromDefault))
8068
+ return fromDefault;
8069
+ if (is(mod))
8070
+ return mod;
8071
+ throw new Error(`${name}: its API is on neither the module's default export nor its namespace`);
8072
+ }
8073
+ function hasFunctions(...names) {
8074
+ return (candidate) => (typeof candidate === "object" || typeof candidate === "function") && candidate !== null && names.every((n) => typeof Reflect.get(candidate, n) === "function");
8075
+ }
8076
+
8064
8077
  // packages/core/dist/document/ocr.js
8065
8078
  var LANG_RE = /^[a-z]{3}(_[a-z]+)*(\+[a-z]{3}(_[a-z]+)*)*$/;
8066
8079
  function isValidOcrLang(lang) {
@@ -8112,10 +8125,7 @@ async function ocrImage(image, opts = {}) {
8112
8125
  } catch {
8113
8126
  }
8114
8127
  }
8115
- const mod = await Promise.resolve().then(() => __toESM(require_src(), 1));
8116
- const createWorker = mod.createWorker ?? mod.default?.createWorker;
8117
- if (typeof createWorker !== "function")
8118
- throw new Error("tesseract.js is unavailable (createWorker not found)");
8128
+ const { createWorker } = cjsExport(await Promise.resolve().then(() => __toESM(require_src(), 1)), hasFunctions("createWorker"), "tesseract.js");
8119
8129
  let fail;
8120
8130
  const failed = new Promise((_, reject) => {
8121
8131
  fail = reject;
@@ -22074,9 +22074,15 @@ function textTableHint(text) {
22074
22074
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
22075
22075
  return gaps >= 6;
22076
22076
  }
22077
+ function openPdf(mupdf, bytes) {
22078
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
22079
+ if (!doc)
22080
+ throw new Error("not a PDF document");
22081
+ return doc;
22082
+ }
22077
22083
  async function openDoc(bytes) {
22078
22084
  const mupdf = await loadMupdf();
22079
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22085
+ const doc = openPdf(mupdf, bytes);
22080
22086
  if (doc.needsPassword())
22081
22087
  throw new PdfEncryptedError();
22082
22088
  if (doc.countPages() === 0) {
@@ -22183,17 +22189,15 @@ function isDelimiter(ch) {
22183
22189
  }
22184
22190
  function pageContentStream(page) {
22185
22191
  try {
22186
- const obj = page.getObject?.();
22187
- const contents = obj?.get?.("Contents");
22188
- if (!contents)
22192
+ const contents = page.getObject().get("Contents");
22193
+ if (contents.isNull())
22189
22194
  return "";
22190
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
22195
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
22191
22196
  let out = "";
22192
22197
  for (const stream of streams) {
22193
- const buf = stream?.readStream?.();
22194
- const bytes = buf?.asUint8Array?.();
22195
- if (bytes)
22196
- out += Buffer.from(bytes).toString("latin1");
22198
+ if (!stream.isStream())
22199
+ continue;
22200
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
22197
22201
  }
22198
22202
  return out;
22199
22203
  } catch {
@@ -22390,12 +22394,11 @@ async function encryptPdf(bytes, userPassword, ownerPassword) {
22390
22394
  }
22391
22395
  async function pdfNeedsPassword(bytes) {
22392
22396
  const mupdf = await loadMupdf();
22393
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22394
- return doc.needsPassword();
22397
+ return openPdf(mupdf, bytes).needsPassword();
22395
22398
  }
22396
22399
  async function decryptPdf(bytes, password) {
22397
22400
  const mupdf = await loadMupdf();
22398
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22401
+ const doc = openPdf(mupdf, bytes);
22399
22402
  if (doc.needsPassword()) {
22400
22403
  if (doc.authenticatePassword(password) === 0)
22401
22404
  throw new Error("wrong password");
@@ -22443,9 +22446,23 @@ async function loadEditablePdf(bytes) {
22443
22446
  var import_promises = require("node:fs/promises");
22444
22447
  var import_node_path2 = require("node:path");
22445
22448
  var import_pdf_lib2 = __toESM(require_cjs(), 1);
22449
+
22450
+ // packages/core/dist/shared/cjs-interop.js
22451
+ function cjsExport(mod, is, name) {
22452
+ const fromDefault = typeof mod === "object" && mod !== null && "default" in mod ? mod.default : void 0;
22453
+ if (is(fromDefault))
22454
+ return fromDefault;
22455
+ if (is(mod))
22456
+ return mod;
22457
+ throw new Error(`${name}: its API is on neither the module's default export nor its namespace`);
22458
+ }
22459
+ function hasFunctions(...names) {
22460
+ return (candidate) => (typeof candidate === "object" || typeof candidate === "function") && candidate !== null && names.every((n) => typeof Reflect.get(candidate, n) === "function");
22461
+ }
22462
+
22463
+ // packages/core/dist/document/pdf-text-font.js
22446
22464
  async function loadFontkit() {
22447
- const mod = await import("./fontkit.cjs");
22448
- return mod.default?.create ? mod.default : mod;
22465
+ return cjsExport(await import("./fontkit.cjs"), hasFunctions("create"), "@pdf-lib/fontkit");
22449
22466
  }
22450
22467
  var PDF_CJK_FONT_FILES = {
22451
22468
  regular: "NotoSansSC-PDF-Regular.ttf",
@@ -3,7 +3,7 @@
3
3
 
4
4
  // apps/admin/data/skills.lib/document/bin-src/pdf-images.mjs
5
5
  var import_promises = require("node:fs/promises");
6
- var import_node_path2 = require("node:path");
6
+ var import_node_path3 = require("node:path");
7
7
 
8
8
  // packages/core/dist/document/pdf-extract.js
9
9
  var import_node_path = require("node:path");
@@ -33,9 +33,15 @@ function loadMupdf() {
33
33
  }
34
34
  return _mupdf;
35
35
  }
36
+ function openPdf(mupdf, bytes) {
37
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
38
+ if (!doc)
39
+ throw new Error("not a PDF document");
40
+ return doc;
41
+ }
36
42
  async function openDoc(bytes) {
37
43
  const mupdf = await loadMupdf();
38
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
44
+ const doc = openPdf(mupdf, bytes);
39
45
  if (doc.needsPassword())
40
46
  throw new PdfEncryptedError();
41
47
  if (doc.countPages() === 0) {
@@ -76,6 +82,17 @@ async function extractPdfImages(bytes, pages) {
76
82
  return { images, skipped };
77
83
  }
78
84
 
85
+ // apps/admin/data/skills.lib/document/bin-src/lib/derived-path.mjs
86
+ var import_node_path2 = require("node:path");
87
+ var SCRATCH_ENV = "TALOS_SCRATCH_DIR";
88
+ function derivedDir(source, env = process.env) {
89
+ const scratch = env[SCRATCH_ENV];
90
+ return scratch ? (0, import_node_path2.join)(scratch, "derived") : (0, import_node_path2.dirname)((0, import_node_path2.resolve)(source));
91
+ }
92
+ function derivedPath(source, name, env = process.env) {
93
+ return (0, import_node_path2.join)(derivedDir(source, env), name);
94
+ }
95
+
79
96
  // apps/admin/data/skills.lib/document/bin-src/pdf-images.mjs
80
97
  function die(msg, code = 1) {
81
98
  process.stderr.write(`pdf-images: ${msg}
@@ -109,10 +126,11 @@ async function main() {
109
126
  } catch (e) {
110
127
  die(`extract failed: ${e.message}`);
111
128
  }
112
- const stem = (0, import_node_path2.basename)(file).replace(/\.[^.]+$/, "");
129
+ const stem = (0, import_node_path3.basename)(file).replace(/\.[^.]+$/, "");
113
130
  const out = [];
131
+ if (result.images.length) await (0, import_promises.mkdir)(derivedDir(file), { recursive: true });
114
132
  for (const img of result.images) {
115
- const dest = (0, import_node_path2.join)((0, import_node_path2.dirname)(file), `${stem}_p${img.page}_i${img.index}.png`);
133
+ const dest = derivedPath(file, `${stem}_p${img.page}_i${img.index}.png`);
116
134
  await (0, import_promises.writeFile)(dest, Buffer.from(img.png));
117
135
  out.push({ page: img.page, index: img.index, bbox: img.bbox, width: img.width, height: img.height, path: dest });
118
136
  }
@@ -22074,9 +22074,15 @@ function textTableHint(text) {
22074
22074
  const gaps = (text.match(/ {2,}|\t/g) || []).length;
22075
22075
  return gaps >= 6;
22076
22076
  }
22077
+ function openPdf(mupdf, bytes) {
22078
+ const doc = mupdf.Document.openDocument(bytes, "application/pdf").asPDF();
22079
+ if (!doc)
22080
+ throw new Error("not a PDF document");
22081
+ return doc;
22082
+ }
22077
22083
  async function openDoc(bytes) {
22078
22084
  const mupdf = await loadMupdf();
22079
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22085
+ const doc = openPdf(mupdf, bytes);
22080
22086
  if (doc.needsPassword())
22081
22087
  throw new PdfEncryptedError();
22082
22088
  if (doc.countPages() === 0) {
@@ -22183,17 +22189,15 @@ function isDelimiter(ch) {
22183
22189
  }
22184
22190
  function pageContentStream(page) {
22185
22191
  try {
22186
- const obj = page.getObject?.();
22187
- const contents = obj?.get?.("Contents");
22188
- if (!contents)
22192
+ const contents = page.getObject().get("Contents");
22193
+ if (contents.isNull())
22189
22194
  return "";
22190
- const streams = contents.isArray?.() && contents.get ? Array.from({ length: contents.length ?? 0 }, (_, i) => contents.get(i)) : [contents];
22195
+ const streams = contents.isArray() ? Array.from({ length: contents.length }, (_, i) => contents.get(i)) : [contents];
22191
22196
  let out = "";
22192
22197
  for (const stream of streams) {
22193
- const buf = stream?.readStream?.();
22194
- const bytes = buf?.asUint8Array?.();
22195
- if (bytes)
22196
- out += Buffer.from(bytes).toString("latin1");
22198
+ if (!stream.isStream())
22199
+ continue;
22200
+ out += Buffer.from(stream.readStream().asUint8Array()).toString("latin1");
22197
22201
  }
22198
22202
  return out;
22199
22203
  } catch {
@@ -22390,12 +22394,11 @@ async function encryptPdf(bytes, userPassword, ownerPassword) {
22390
22394
  }
22391
22395
  async function pdfNeedsPassword(bytes) {
22392
22396
  const mupdf = await loadMupdf();
22393
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22394
- return doc.needsPassword();
22397
+ return openPdf(mupdf, bytes).needsPassword();
22395
22398
  }
22396
22399
  async function decryptPdf(bytes, password) {
22397
22400
  const mupdf = await loadMupdf();
22398
- const doc = mupdf.Document.openDocument(bytes, "application/pdf");
22401
+ const doc = openPdf(mupdf, bytes);
22399
22402
  if (doc.needsPassword()) {
22400
22403
  if (doc.authenticatePassword(password) === 0)
22401
22404
  throw new Error("wrong password");
@@ -22443,9 +22446,23 @@ async function loadEditablePdf(bytes) {
22443
22446
  var import_promises = require("node:fs/promises");
22444
22447
  var import_node_path2 = require("node:path");
22445
22448
  var import_pdf_lib2 = __toESM(require_cjs(), 1);
22449
+
22450
+ // packages/core/dist/shared/cjs-interop.js
22451
+ function cjsExport(mod, is, name) {
22452
+ const fromDefault = typeof mod === "object" && mod !== null && "default" in mod ? mod.default : void 0;
22453
+ if (is(fromDefault))
22454
+ return fromDefault;
22455
+ if (is(mod))
22456
+ return mod;
22457
+ throw new Error(`${name}: its API is on neither the module's default export nor its namespace`);
22458
+ }
22459
+ function hasFunctions(...names) {
22460
+ return (candidate) => (typeof candidate === "object" || typeof candidate === "function") && candidate !== null && names.every((n) => typeof Reflect.get(candidate, n) === "function");
22461
+ }
22462
+
22463
+ // packages/core/dist/document/pdf-text-font.js
22446
22464
  async function loadFontkit() {
22447
- const mod = await import("./fontkit.cjs");
22448
- return mod.default?.create ? mod.default : mod;
22465
+ return cjsExport(await import("./fontkit.cjs"), hasFunctions("create"), "@pdf-lib/fontkit");
22449
22466
  }
22450
22467
  var PDF_CJK_FONT_FILES = {
22451
22468
  regular: "NotoSansSC-PDF-Regular.ttf",