@a9i5k4/dsh-literature 0.2.11 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/lib/client.js +10 -10
  2. package/lib/index.js +1406 -455
  3. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -2626,6 +2626,183 @@ var init_importer = __esm({
2626
2626
  }
2627
2627
  });
2628
2628
 
2629
+ // src/node/courseware/pptx.js
2630
+ var pptx_exports = {};
2631
+ __export(pptx_exports, {
2632
+ deckToText: () => deckToText,
2633
+ parsePptx: () => parsePptx
2634
+ });
2635
+ import { readFileSync } from "node:fs";
2636
+ import { inflateRawSync } from "node:zlib";
2637
+ function readZipEntries(bytes) {
2638
+ let eocd = -1;
2639
+ for (let i = bytes.length - 22; i >= 0 && i > bytes.length - 66e3; i -= 1) {
2640
+ if (bytes.readUInt32LE(i) === EOCD_SIG) {
2641
+ eocd = i;
2642
+ break;
2643
+ }
2644
+ }
2645
+ if (eocd < 0) throw new Error("not a zip archive");
2646
+ const count = bytes.readUInt16LE(eocd + 10);
2647
+ let off = bytes.readUInt32LE(eocd + 16);
2648
+ const entries = /* @__PURE__ */ new Map();
2649
+ for (let i = 0; i < count; i += 1) {
2650
+ if (bytes.readUInt32LE(off) !== CD_SIG) break;
2651
+ const method = bytes.readUInt16LE(off + 10);
2652
+ const compSize = bytes.readUInt32LE(off + 20);
2653
+ const nameLen = bytes.readUInt16LE(off + 28);
2654
+ const extraLen = bytes.readUInt16LE(off + 30);
2655
+ const commentLen = bytes.readUInt16LE(off + 32);
2656
+ const localOff = bytes.readUInt32LE(off + 42);
2657
+ const name2 = bytes.slice(off + 46, off + 46 + nameLen).toString("utf8");
2658
+ if (bytes.readUInt32LE(localOff) === LOCAL_SIG) {
2659
+ const lNameLen = bytes.readUInt16LE(localOff + 26);
2660
+ const lExtraLen = bytes.readUInt16LE(localOff + 28);
2661
+ const dataStart = localOff + 30 + lNameLen + lExtraLen;
2662
+ const raw = bytes.slice(dataStart, dataStart + compSize);
2663
+ let data;
2664
+ try {
2665
+ data = method === 0 ? Buffer.from(raw) : inflateRawSync(raw);
2666
+ } catch {
2667
+ data = null;
2668
+ }
2669
+ entries.set(name2, data);
2670
+ }
2671
+ off += 46 + nameLen + extraLen + commentLen;
2672
+ }
2673
+ return entries;
2674
+ }
2675
+ function paragraphsFromSlideXml(xml) {
2676
+ const out = [];
2677
+ const re = /<a:p>([\s\S]*?)<\/a:p>/g;
2678
+ let m;
2679
+ while (m = re.exec(xml)) {
2680
+ const runs = [...m[1].matchAll(/<a:t>([\s\S]*?)<\/a:t>/g)].map((r) => r[1]);
2681
+ const text = runs.join("").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").trim();
2682
+ if (text) out.push(text);
2683
+ }
2684
+ return out;
2685
+ }
2686
+ function isTitleShape(shapeXml) {
2687
+ return /<p:ph[^>]*type="(?:title|ctrTitle)"/.test(shapeXml);
2688
+ }
2689
+ function aspectOf(cx, cy) {
2690
+ const r = cx / cy;
2691
+ if (r > 1.7) return "16:9";
2692
+ if (r > 1.2) return "4:3";
2693
+ return `${r.toFixed(2)}:1`;
2694
+ }
2695
+ function parseChartXml(xml) {
2696
+ const cats = [...xml.matchAll(/<c:pt idx="(\d+)">\s*<c:v>([\s\S]*?)<\/c:v>/g)];
2697
+ const catMatch = xml.match(/<c:cat>([\s\S]*?)<\/c:cat>/);
2698
+ const categories = catMatch ? [...catMatch[1].matchAll(/<c:v>([\s\S]*?)<\/c:v>/g)].map((m) => m[1].trim()) : [];
2699
+ const series = [];
2700
+ for (const m of xml.matchAll(/<c:ser>([\s\S]*?)<\/c:ser>/g)) {
2701
+ const name2 = m[1].match(/<c:tx>[\s\S]*?<c:v>([\s\S]*?)<\/c:v>/)?.[1]?.trim() ?? "";
2702
+ const valBlock = m[1].match(/<c:val>([\s\S]*?)<\/c:val>/)?.[1] ?? "";
2703
+ const values = [...valBlock.matchAll(/<c:v>([\s\S]*?)<\/c:v>/g)].map((v) => Number(v[1]) || 0);
2704
+ if (values.length) series.push({ name: name2, values });
2705
+ }
2706
+ return { categories, series, rawPts: cats.length };
2707
+ }
2708
+ function naturalSlideIndex(name2) {
2709
+ const m = name2.match(/slide(\d+)\.xml$/);
2710
+ return m ? Number(m[1]) : 0;
2711
+ }
2712
+ function parsePptx(input) {
2713
+ const bytes = Buffer.isBuffer(input) ? input : readFileSync(input);
2714
+ const warnings = [];
2715
+ let entries;
2716
+ try {
2717
+ entries = readZipEntries(bytes);
2718
+ } catch (e) {
2719
+ throw new Error(`\u65E0\u6CD5\u89E3\u6790\u8BE5\u6587\u4EF6\uFF1A${e.message}\uFF08\u82E5\u4E3A\u65E7\u7248 .ppt\uFF0C\u8BF7\u53E6\u5B58\u4E3A .pptx \u6216\u5BFC\u51FA PDF\uFF09`);
2720
+ }
2721
+ if (!entries.has("[Content_Types].xml")) throw new Error("\u4E0D\u662F\u6709\u6548\u7684 .pptx\uFF08\u7F3A\u5C11 OOXML \u5185\u5BB9\u7C7B\u578B\u6E05\u5355\uFF09");
2722
+ const slideNames = [...entries.keys()].filter((n) => /^ppt\/slides\/slide\d+\.xml$/.test(n)).sort((a, b) => naturalSlideIndex(a) - naturalSlideIndex(b));
2723
+ if (!slideNames.length) throw new Error("\u8BE5 .pptx \u4E2D\u6CA1\u6709\u5E7B\u706F\u7247");
2724
+ const pres = entries.get("ppt/presentation.xml")?.toString("utf8") ?? "";
2725
+ const size = pres.match(/<p:sldSz cx="(\d+)" cy="(\d+)"/);
2726
+ const aspect = size ? aspectOf(Number(size[1]), Number(size[2])) : "";
2727
+ const notesOf = /* @__PURE__ */ new Map();
2728
+ for (const name2 of entries.keys()) {
2729
+ const m = name2.match(/^ppt\/notesSlides\/notesSlide(\d+)\.xml$/);
2730
+ if (m) notesOf.set(Number(m[1]), entries.get(name2)?.toString("utf8") ?? "");
2731
+ }
2732
+ const charts = [];
2733
+ for (const name2 of [...entries.keys()].sort()) {
2734
+ const m = name2.match(/^ppt\/charts\/chart(\d+)\.xml$/);
2735
+ if (!m) continue;
2736
+ const xml = entries.get(name2)?.toString("utf8") ?? "";
2737
+ if (!xml) continue;
2738
+ const parsed = parseChartXml(xml);
2739
+ charts.push({ name: name2, ...parsed });
2740
+ }
2741
+ const slides = slideNames.map((name2) => {
2742
+ const n = naturalSlideIndex(name2);
2743
+ const xml = entries.get(name2)?.toString("utf8") ?? "";
2744
+ const shapes = [...xml.matchAll(/<p:sp>[\s\S]*?<\/p:sp>/g)].map((s) => s[0]);
2745
+ let title = "";
2746
+ const body = [];
2747
+ for (const shape of shapes) {
2748
+ const paras = paragraphsFromSlideXml(shape);
2749
+ if (!paras.length) continue;
2750
+ if (!title && isTitleShape(shape)) title = paras.join(" ");
2751
+ else body.push(...paras);
2752
+ }
2753
+ if (!title && body.length) {
2754
+ title = body.shift();
2755
+ }
2756
+ const images = [...xml.matchAll(/<p:pic>[\s\S]*?<\/p:pic>/g)].length;
2757
+ return {
2758
+ index: n,
2759
+ title: title || `\u7B2C ${n} \u9875`,
2760
+ paragraphs: body,
2761
+ notes: (() => {
2762
+ const nx = notesOf.get(n) ?? "";
2763
+ return nx ? paragraphsFromSlideXml(nx) : [];
2764
+ })(),
2765
+ images
2766
+ };
2767
+ });
2768
+ const media = [...entries.keys()].filter((n) => n.startsWith("ppt/media/")).map((n) => ({ name: n }));
2769
+ return {
2770
+ kind: "pptx",
2771
+ slideCount: slides.length,
2772
+ aspect,
2773
+ slides,
2774
+ media,
2775
+ charts,
2776
+ warnings
2777
+ };
2778
+ }
2779
+ function deckToText(parsed, { maxChars = 4e4 } = {}) {
2780
+ const parts = [];
2781
+ let total = 0;
2782
+ for (const slide of parsed.slides) {
2783
+ const lines = [`## \u7B2C ${slide.index} \u9875 \xB7 ${slide.title}`];
2784
+ lines.push(...slide.paragraphs.map((p) => `- ${p}`));
2785
+ if (slide.notes.length) lines.push(`\uFF08\u8BB2\u8005\u5907\u6CE8\uFF1A${slide.notes.join("\uFF1B")}\uFF09`);
2786
+ if (slide.images) lines.push(`\uFF08\u672C\u9875\u63D2\u56FE ${slide.images} \u5F20\uFF09`);
2787
+ const block = lines.join("\n");
2788
+ if (total + block.length > maxChars) {
2789
+ parts.push("\u2026\uFF08\u8D85\u51FA\u957F\u5EA6\u4E0A\u9650\uFF0C\u5176\u4F59\u9875\u672A\u5305\u542B\uFF09");
2790
+ break;
2791
+ }
2792
+ parts.push(block);
2793
+ total += block.length;
2794
+ }
2795
+ return parts.join("\n\n");
2796
+ }
2797
+ var EOCD_SIG, CD_SIG, LOCAL_SIG;
2798
+ var init_pptx = __esm({
2799
+ "src/node/courseware/pptx.js"() {
2800
+ EOCD_SIG = 101010256;
2801
+ CD_SIG = 33639248;
2802
+ LOCAL_SIG = 67324752;
2803
+ }
2804
+ });
2805
+
2629
2806
  // src/node/pipeline.js
2630
2807
  var pipeline_exports = {};
2631
2808
  __export(pipeline_exports, {
@@ -2633,6 +2810,7 @@ __export(pipeline_exports, {
2633
2810
  arxivBase: () => arxivBase,
2634
2811
  discardItem: () => discardItem,
2635
2812
  fetchItemPdf: () => fetchItemPdf,
2813
+ importDroppedCourseware: () => importDroppedCourseware,
2636
2814
  importDroppedPdf: () => importDroppedPdf,
2637
2815
  importPdf: () => importPdf,
2638
2816
  log: () => log,
@@ -2933,8 +3111,8 @@ async function saveItem(key, { mode, tags } = {}) {
2933
3111
  if (wantMode === "dir") {
2934
3112
  let buffer = null;
2935
3113
  if (current.pdf?.path) {
2936
- const { readFile: readFile6 } = await import("node:fs/promises");
2937
- buffer = await readFile6(current.pdf.path).catch(() => null);
3114
+ const { readFile: readFile7 } = await import("node:fs/promises");
3115
+ buffer = await readFile7(current.pdf.path).catch(() => null);
2938
3116
  }
2939
3117
  result = await exportToDirectory(current.record, buffer);
2940
3118
  const updated2 = await patchItem(key, { state: "saved", saveMode: "dir", export: result, error: null, updatedAt: Date.now() });
@@ -2944,14 +3122,14 @@ async function saveItem(key, { mode, tags } = {}) {
2944
3122
  }
2945
3123
  let pdfBuffer = null;
2946
3124
  if (current.pdf?.path) {
2947
- const { readFile: readFile6 } = await import("node:fs/promises");
2948
- pdfBuffer = await readFile6(current.pdf.path).catch(() => null);
3125
+ const { readFile: readFile7 } = await import("node:fs/promises");
3126
+ pdfBuffer = await readFile7(current.pdf.path).catch(() => null);
2949
3127
  }
2950
3128
  if (!pdfBuffer) {
2951
3129
  const fetched = await fetchItemPdf(key);
2952
3130
  if (fetched?.pdf?.path) {
2953
- const { readFile: readFile6 } = await import("node:fs/promises");
2954
- pdfBuffer = await readFile6(fetched.pdf.path).catch(() => null);
3131
+ const { readFile: readFile7 } = await import("node:fs/promises");
3132
+ pdfBuffer = await readFile7(fetched.pdf.path).catch(() => null);
2955
3133
  } else {
2956
3134
  const err = fetched?.error ?? failure("fetch_failed", "\u65E0\u6CD5\u83B7\u53D6\u5168\u6587 PDF\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u5230\u6587\u732E\u5E93");
2957
3135
  throw Object.assign(new Error(err.message), { code: err.code ?? "fetch_failed", detail: err.detail });
@@ -3088,6 +3266,48 @@ async function importDroppedPdf(buffer, { filename = "dropped.pdf" } = {}) {
3088
3266
  emitItem(saved);
3089
3267
  return saved;
3090
3268
  }
3269
+ async function importDroppedCourseware(buffer, { filename = "deck.pptx" } = {}) {
3270
+ if (!buffer || buffer.length < 4 || buffer.subarray(0, 2).toString("latin1") !== "PK") {
3271
+ throw failure("network", "\u62D6\u5165\u7684\u6587\u4EF6\u4E0D\u662F\u6709\u6548\u7684 .pptx\uFF08\u65E7\u7248 .ppt \u8BF7\u5148\u53E6\u5B58\u4E3A .pptx \u6216\u5BFC\u51FA PDF\uFF09");
3272
+ }
3273
+ const { parsePptx: parsePptx2, deckToText: deckToText2 } = await Promise.resolve().then(() => (init_pptx(), pptx_exports));
3274
+ let parsed;
3275
+ try {
3276
+ parsed = parsePptx2(buffer);
3277
+ } catch (e) {
3278
+ throw failure("network", e?.message ?? "\u8BFE\u4EF6\u89E3\u6790\u5931\u8D25");
3279
+ }
3280
+ const base = String(filename).replace(/\.pptx$/i, "");
3281
+ const title = parsed.slides[0]?.title && parsed.slides[0].title !== "\u7B2C 1 \u9875" ? parsed.slides[0].title : base;
3282
+ const key = `cw_${randomUUID2().slice(0, 8)}`;
3283
+ const path = join5(PDF_DIR, `${key.replace(/[^\w.-]+/g, "_")}.pptx`);
3284
+ await mkdir4(dirname3(path), { recursive: true });
3285
+ await writeFile4(path, buffer);
3286
+ const item = await putItem({
3287
+ key,
3288
+ kind: "courseware",
3289
+ display: title,
3290
+ title,
3291
+ sourceFile: filename,
3292
+ state: "fetched",
3293
+ courseware: {
3294
+ format: "pptx",
3295
+ path,
3296
+ filename,
3297
+ slideCount: parsed.slideCount,
3298
+ aspect: parsed.aspect,
3299
+ outline: parsed.slides.map((s) => ({ index: s.index, title: s.title })),
3300
+ charts: parsed.charts.map((c) => ({ name: c.name, categories: c.categories, series: c.series })),
3301
+ mediaCount: parsed.media.length,
3302
+ text: deckToText2(parsed, { maxChars: 6e4 })
3303
+ },
3304
+ pdf: { path, size: buffer.length, source: "courseware-import", url: "", filename },
3305
+ tags: ["\u8BFE\u4EF6"],
3306
+ createdAt: Date.now()
3307
+ });
3308
+ emitItem(item);
3309
+ return item;
3310
+ }
3091
3311
  var FAILURE_MESSAGES;
3092
3312
  var init_pipeline = __esm({
3093
3313
  "src/node/pipeline.js"() {
@@ -3136,6 +3356,118 @@ var init_session_track = __esm({
3136
3356
  }
3137
3357
  });
3138
3358
 
3359
+ // src/node/pyenv.js
3360
+ var pyenv_exports = {};
3361
+ __export(pyenv_exports, {
3362
+ detectPythons: () => detectPythons,
3363
+ figureInterpreter: () => figureInterpreter,
3364
+ installFigureDeps: () => installFigureDeps,
3365
+ venvDir: () => venvDir,
3366
+ venvExists: () => venvExists
3367
+ });
3368
+ import { execFile } from "node:child_process";
3369
+ import { existsSync, readdirSync } from "node:fs";
3370
+ import { join as join6 } from "node:path";
3371
+ import { homedir as homedir3 } from "node:os";
3372
+ function run(cmd, args, { timeout = 2e4 } = {}) {
3373
+ return new Promise((resolve6) => {
3374
+ execFile(cmd, args, { timeout, windowsHide: true }, (err, stdout, stderr) => {
3375
+ resolve6({ ok: !err, out: String(stdout ?? "").trim(), err: String(stderr ?? "").trim(), code: err?.code });
3376
+ });
3377
+ });
3378
+ }
3379
+ async function probe(exe) {
3380
+ const v = await run(exe, ["--version"]);
3381
+ if (!v.ok) return null;
3382
+ const cap = await run(exe, ["-c", 'import venv, ensurepip; print("ok")']);
3383
+ const mpl = await run(exe, ["-c", "import matplotlib; print(matplotlib.__version__)"]);
3384
+ return {
3385
+ exe,
3386
+ version: v.out.split(" ").pop() ?? "",
3387
+ venvCapable: cap.ok,
3388
+ hasMatplotlib: mpl.ok,
3389
+ matplotlibVersion: mpl.ok ? mpl.out : ""
3390
+ };
3391
+ }
3392
+ async function detectPythons({ force = false } = {}) {
3393
+ if (!force && cache.pythons.length && Date.now() - cache.at < CACHE_MS) return cache.pythons;
3394
+ const candidates2 = [];
3395
+ const tryPush = async (exe) => {
3396
+ if (!exe || candidates2.some((c) => c.exe === exe)) return;
3397
+ const p = await probe(exe);
3398
+ if (p) candidates2.push(p);
3399
+ };
3400
+ if (process.platform === "win32") {
3401
+ const py = await run("py", ["-0p"]);
3402
+ if (py.ok) {
3403
+ for (const line of py.out.split("\n")) {
3404
+ const m = line.match(/[-*]\s*(?:Version: .*)?(?:\|\s*)?(.+\.exe)\s*$/i) ?? line.match(/([A-Za-z]:\\[^\s]+python\.exe)/i);
3405
+ if (m?.[1]) await tryPush(m[1].trim());
3406
+ }
3407
+ }
3408
+ }
3409
+ await tryPush("python");
3410
+ await tryPush("python3");
3411
+ if (process.env.WORKBUDDY_PY) await tryPush(process.env.WORKBUDDY_PY);
3412
+ const managed = join6(homedir3(), ".workbuddy", "binaries", "python", "versions");
3413
+ if (existsSync(managed)) {
3414
+ try {
3415
+ for (const v of readdirSync(managed).sort().reverse()) {
3416
+ await tryPush(join6(managed, v, "python.exe"));
3417
+ await tryPush(join6(managed, v, "bin", "python3"));
3418
+ }
3419
+ } catch {
3420
+ }
3421
+ }
3422
+ cache = { at: Date.now(), pythons: candidates2 };
3423
+ return candidates2;
3424
+ }
3425
+ function venvDir() {
3426
+ return join6(homedir3(), ".dsh", "dsh-literature", "pyvenv");
3427
+ }
3428
+ function venvPython(dir = venvDir()) {
3429
+ return process.platform === "win32" ? join6(dir, "Scripts", "python.exe") : join6(dir, "bin", "python");
3430
+ }
3431
+ function venvExists(dir = venvDir()) {
3432
+ return existsSync(venvPython(dir));
3433
+ }
3434
+ async function figureInterpreter() {
3435
+ if (venvExists()) {
3436
+ const p = await probe(venvPython());
3437
+ if (p?.hasMatplotlib) return { ...p, source: "venv" };
3438
+ if (p) return { ...p, source: "venv", hasMatplotlib: false };
3439
+ }
3440
+ for (const p of await detectPythons()) {
3441
+ if (p.hasMatplotlib) return { ...p, source: "system" };
3442
+ }
3443
+ return null;
3444
+ }
3445
+ async function installFigureDeps(onLog = () => {
3446
+ }) {
3447
+ const pythons = await detectPythons({ force: true });
3448
+ const base = pythons.find((p) => p.venvCapable);
3449
+ if (!base) return { ok: false, error: "\u672A\u627E\u5230\u53EF\u7528\u7684 Python\uFF08\u9700\u8981\u5E26 venv \u6A21\u5757\u7684 Python 3.8+\uFF09" };
3450
+ const dir = venvDir();
3451
+ if (!venvExists(dir)) {
3452
+ onLog("\u521B\u5EFA\u865A\u62DF\u73AF\u5883\u2026");
3453
+ const r2 = await run(base.exe, ["-m", "venv", dir], { timeout: 12e4 });
3454
+ if (!r2.ok) return { ok: false, error: "venv \u521B\u5EFA\u5931\u8D25\uFF1A" + (r2.err || r2.out) };
3455
+ }
3456
+ const py = venvPython(dir);
3457
+ onLog("\u5B89\u88C5 matplotlib\u2026");
3458
+ const r = await run(py, ["-m", "pip", "install", "--disable-pip-version-check", "matplotlib"], { timeout: 3e5 });
3459
+ if (!r.ok) return { ok: false, error: "matplotlib \u5B89\u88C5\u5931\u8D25\uFF1A" + (r.err || r.out).slice(0, 400) };
3460
+ cache = { at: 0, pythons: [] };
3461
+ return { ok: true, python: py, dir };
3462
+ }
3463
+ var CACHE_MS, cache;
3464
+ var init_pyenv = __esm({
3465
+ "src/node/pyenv.js"() {
3466
+ CACHE_MS = 6e4;
3467
+ cache = { at: 0, pythons: [] };
3468
+ }
3469
+ });
3470
+
3139
3471
  // node_modules/pdfjs-dist/legacy/build/pdf.mjs
3140
3472
  var pdf_exports = {};
3141
3473
  __export(pdf_exports, {
@@ -3583,7 +3915,7 @@ function getColorValues(colors) {
3583
3915
  }
3584
3916
  span.remove();
3585
3917
  }
3586
- function getCurrentTransform(ctx) {
3918
+ function getCurrentTransform(ctx2) {
3587
3919
  const {
3588
3920
  a,
3589
3921
  b,
@@ -3591,10 +3923,10 @@ function getCurrentTransform(ctx) {
3591
3923
  d,
3592
3924
  e,
3593
3925
  f
3594
- } = ctx.getTransform();
3926
+ } = ctx2.getTransform();
3595
3927
  return [a, b, c, d, e, f];
3596
3928
  }
3597
- function getCurrentTransformInverse(ctx) {
3929
+ function getCurrentTransformInverse(ctx2) {
3598
3930
  const {
3599
3931
  a,
3600
3932
  b,
@@ -3602,7 +3934,7 @@ function getCurrentTransformInverse(ctx) {
3602
3934
  d,
3603
3935
  e,
3604
3936
  f
3605
- } = ctx.getTransform().invertSelf();
3937
+ } = ctx2.getTransform().invertSelf();
3606
3938
  return [a, b, c, d, e, f];
3607
3939
  }
3608
3940
  function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) {
@@ -4050,7 +4382,7 @@ function loadMeshShader() {
4050
4382
  function drawMeshWithGPU(posData, colData, vertexCount, context, backgroundColor, paddedWidth, paddedHeight, borderSize) {
4051
4383
  return _webGPU.draw(posData, colData, vertexCount, context, backgroundColor, paddedWidth, paddedHeight, borderSize);
4052
4384
  }
4053
- function applyBoundingBox(ctx, bbox) {
4385
+ function applyBoundingBox(ctx2, bbox) {
4054
4386
  if (!bbox) {
4055
4387
  return;
4056
4388
  }
@@ -4058,7 +4390,7 @@ function applyBoundingBox(ctx, bbox) {
4058
4390
  const height = bbox[3] - bbox[1];
4059
4391
  const region = new Path2D();
4060
4392
  region.rect(bbox[0], bbox[1], width, height);
4061
- ctx.clip(region);
4393
+ ctx2.clip(region);
4062
4394
  }
4063
4395
  function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {
4064
4396
  const coords = context.coords, colors = context.colors;
@@ -4164,31 +4496,31 @@ function getShadingPattern(IR) {
4164
4496
  }
4165
4497
  throw new Error(`Unknown IR type: ${IR[0]}`);
4166
4498
  }
4167
- function mirrorContextOperations(ctx, destCtx) {
4168
- if (ctx._removeMirroring) {
4499
+ function mirrorContextOperations(ctx2, destCtx) {
4500
+ if (ctx2._removeMirroring) {
4169
4501
  throw new Error("Context is already forwarding operations.");
4170
4502
  }
4171
4503
  const originalMethods = /* @__PURE__ */ new Map();
4172
4504
  for (const name2 of ["save", "restore", "rotate", "scale", "translate", "transform", "setTransform", "resetTransform", "clip", "moveTo", "lineTo", "bezierCurveTo", "quadraticCurveTo", "arc", "arcTo", "ellipse", "rect", "roundRect", "closePath", "beginPath"]) {
4173
- const original = ctx[name2];
4505
+ const original = ctx2[name2];
4174
4506
  if (typeof original !== "function" || typeof destCtx[name2] !== "function") {
4175
4507
  continue;
4176
4508
  }
4177
4509
  originalMethods.set(name2, original);
4178
- ctx[name2] = function(...args) {
4510
+ ctx2[name2] = function(...args) {
4179
4511
  destCtx[name2](...args);
4180
4512
  return original.apply(this, args);
4181
4513
  };
4182
4514
  }
4183
- ctx._removeMirroring = () => {
4515
+ ctx2._removeMirroring = () => {
4184
4516
  for (const [name2, original] of originalMethods) {
4185
- ctx[name2] = original;
4517
+ ctx2[name2] = original;
4186
4518
  }
4187
- delete ctx._removeMirroring;
4519
+ delete ctx2._removeMirroring;
4188
4520
  };
4189
4521
  }
4190
- function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {
4191
- const [a, b, c, d, tx, ty] = getCurrentTransform(ctx);
4522
+ function drawImageAtIntegerCoords(ctx2, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {
4523
+ const [a, b, c, d, tx, ty] = getCurrentTransform(ctx2);
4192
4524
  if (b === 0 && c === 0) {
4193
4525
  const tlX = destX * a + tx;
4194
4526
  const rTlX = Math.round(tlX);
@@ -4198,9 +4530,9 @@ function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, de
4198
4530
  const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;
4199
4531
  const brY = (destY + destH) * d + ty;
4200
4532
  const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;
4201
- ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY);
4202
- ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight);
4203
- ctx.setTransform(a, b, c, d, tx, ty);
4533
+ ctx2.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY);
4534
+ ctx2.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight);
4535
+ ctx2.setTransform(a, b, c, d, tx, ty);
4204
4536
  return [rWidth, rHeight];
4205
4537
  }
4206
4538
  if (a === 0 && d === 0) {
@@ -4212,17 +4544,17 @@ function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, de
4212
4544
  const rWidth = Math.abs(Math.round(brX) - rTlX) || 1;
4213
4545
  const brY = (destX + destW) * b + ty;
4214
4546
  const rHeight = Math.abs(Math.round(brY) - rTlY) || 1;
4215
- ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY);
4216
- ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth);
4217
- ctx.setTransform(a, b, c, d, tx, ty);
4547
+ ctx2.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY);
4548
+ ctx2.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth);
4549
+ ctx2.setTransform(a, b, c, d, tx, ty);
4218
4550
  return [rHeight, rWidth];
4219
4551
  }
4220
- ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH);
4552
+ ctx2.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH);
4221
4553
  const scaleX = Math.hypot(a, b);
4222
4554
  const scaleY = Math.hypot(c, d);
4223
4555
  return [scaleX * destW, scaleY * destH];
4224
4556
  }
4225
- function putBinaryImageData(ctx, imgData) {
4557
+ function putBinaryImageData(ctx2, imgData) {
4226
4558
  const {
4227
4559
  width,
4228
4560
  height,
@@ -4231,7 +4563,7 @@ function putBinaryImageData(ctx, imgData) {
4231
4563
  const partialChunkHeight = height % FULL_CHUNK_HEIGHT;
4232
4564
  const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;
4233
4565
  const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;
4234
- const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);
4566
+ const chunkImgData = ctx2.createImageData(width, FULL_CHUNK_HEIGHT);
4235
4567
  let srcPos = 0;
4236
4568
  const src = imgData.data;
4237
4569
  const dest = chunkImgData.data;
@@ -4247,7 +4579,7 @@ function putBinaryImageData(ctx, imgData) {
4247
4579
  width,
4248
4580
  height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight
4249
4581
  }));
4250
- ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4582
+ ctx2.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4251
4583
  }
4252
4584
  } else if (kind === ImageKind.RGBA_32BPP) {
4253
4585
  let j = 0;
@@ -4255,13 +4587,13 @@ function putBinaryImageData(ctx, imgData) {
4255
4587
  for (i = 0; i < fullChunks; i++) {
4256
4588
  dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));
4257
4589
  srcPos += elemsInThisChunk;
4258
- ctx.putImageData(chunkImgData, 0, j);
4590
+ ctx2.putImageData(chunkImgData, 0, j);
4259
4591
  j += FULL_CHUNK_HEIGHT;
4260
4592
  }
4261
4593
  if (i < totalChunks) {
4262
4594
  elemsInThisChunk = width * partialChunkHeight * 4;
4263
4595
  dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk));
4264
- ctx.putImageData(chunkImgData, 0, j);
4596
+ ctx2.putImageData(chunkImgData, 0, j);
4265
4597
  }
4266
4598
  } else if (kind === ImageKind.RGB_24BPP) {
4267
4599
  for (i = 0; i < totalChunks; i++) {
@@ -4274,15 +4606,15 @@ function putBinaryImageData(ctx, imgData) {
4274
4606
  width,
4275
4607
  height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight
4276
4608
  }));
4277
- ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4609
+ ctx2.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4278
4610
  }
4279
4611
  } else {
4280
4612
  throw new Error(`bad image kind: ${kind}`);
4281
4613
  }
4282
4614
  }
4283
- function putBinaryImageMask(ctx, imgData) {
4615
+ function putBinaryImageMask(ctx2, imgData) {
4284
4616
  if (imgData.bitmap) {
4285
- ctx.drawImage(imgData.bitmap, 0, 0);
4617
+ ctx2.drawImage(imgData.bitmap, 0, 0);
4286
4618
  return;
4287
4619
  }
4288
4620
  const {
@@ -4292,7 +4624,7 @@ function putBinaryImageMask(ctx, imgData) {
4292
4624
  const partialChunkHeight = height % FULL_CHUNK_HEIGHT;
4293
4625
  const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT;
4294
4626
  const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1;
4295
- const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT);
4627
+ const chunkImgData = ctx2.createImageData(width, FULL_CHUNK_HEIGHT);
4296
4628
  let srcPos = 0;
4297
4629
  const src = imgData.data;
4298
4630
  const dest = chunkImgData.data;
@@ -4307,7 +4639,7 @@ function putBinaryImageMask(ctx, imgData) {
4307
4639
  height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight,
4308
4640
  nonBlackColor: 0
4309
4641
  }));
4310
- ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4642
+ ctx2.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT);
4311
4643
  }
4312
4644
  }
4313
4645
  function copyCtxState(sourceCtx, destCtx) {
@@ -4322,25 +4654,25 @@ function copyCtxState(sourceCtx, destCtx) {
4322
4654
  destCtx.lineDashOffset = sourceCtx.lineDashOffset;
4323
4655
  }
4324
4656
  }
4325
- function resetCtxToDefault(ctx) {
4326
- ctx.strokeStyle = ctx.fillStyle = "#000000";
4327
- ctx.fillRule = "nonzero";
4328
- ctx.globalAlpha = 1;
4329
- ctx.lineWidth = 1;
4330
- ctx.lineCap = "butt";
4331
- ctx.lineJoin = "miter";
4332
- ctx.miterLimit = 10;
4333
- ctx.globalCompositeOperation = "source-over";
4334
- ctx.font = "10px sans-serif";
4335
- if (ctx.setLineDash !== void 0) {
4336
- ctx.setLineDash([]);
4337
- ctx.lineDashOffset = 0;
4657
+ function resetCtxToDefault(ctx2) {
4658
+ ctx2.strokeStyle = ctx2.fillStyle = "#000000";
4659
+ ctx2.fillRule = "nonzero";
4660
+ ctx2.globalAlpha = 1;
4661
+ ctx2.lineWidth = 1;
4662
+ ctx2.lineCap = "butt";
4663
+ ctx2.lineJoin = "miter";
4664
+ ctx2.miterLimit = 10;
4665
+ ctx2.globalCompositeOperation = "source-over";
4666
+ ctx2.font = "10px sans-serif";
4667
+ if (ctx2.setLineDash !== void 0) {
4668
+ ctx2.setLineDash([]);
4669
+ ctx2.lineDashOffset = 0;
4338
4670
  }
4339
4671
  const {
4340
4672
  filter
4341
- } = ctx;
4673
+ } = ctx2;
4342
4674
  if (filter !== "none" && filter !== "") {
4343
- ctx.filter = "none";
4675
+ ctx2.filter = "none";
4344
4676
  }
4345
4677
  }
4346
4678
  function getImageSmoothingEnabled(transform, interpolate) {
@@ -5990,10 +6322,10 @@ var init_pdf2 = __esm({
5990
6322
  var isCallable = __webpack_require__2(4901);
5991
6323
  var replacement = /#|\.prototype\./;
5992
6324
  var isForced = function(feature, detection) {
5993
- var value = data[normalize(feature)];
6325
+ var value = data[normalize2(feature)];
5994
6326
  return value === POLYFILL ? true : value === NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;
5995
6327
  };
5996
- var normalize = isForced.normalize = function(string) {
6328
+ var normalize2 = isForced.normalize = function(string) {
5997
6329
  return String(string).replace(replacement, ".").toLowerCase();
5998
6330
  };
5999
6331
  var data = isForced.data = {};
@@ -6363,7 +6695,7 @@ var init_pdf2 = __esm({
6363
6695
  var defineProperty = Object.defineProperty;
6364
6696
  var stringSlice = uncurryThis("".slice);
6365
6697
  var replace = uncurryThis("".replace);
6366
- var join7 = uncurryThis([].join);
6698
+ var join9 = uncurryThis([].join);
6367
6699
  var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {
6368
6700
  return defineProperty(function() {
6369
6701
  }, "length", { value: 8 }).length !== 8;
@@ -6390,7 +6722,7 @@ var init_pdf2 = __esm({
6390
6722
  }
6391
6723
  var state2 = enforceInternalState(value);
6392
6724
  if (!hasOwn(state2, "source")) {
6393
- state2.source = join7(TEMPLATE, typeof name2 == "string" ? name2 : "");
6725
+ state2.source = join9(TEMPLATE, typeof name2 == "string" ? name2 : "");
6394
6726
  }
6395
6727
  return value;
6396
6728
  };
@@ -8913,7 +9245,7 @@ var init_pdf2 = __esm({
8913
9245
  var charAt = uncurryThis("".charAt);
8914
9246
  var Uint8Array2 = globalThis2.Uint8Array;
8915
9247
  var $Array = globalThis2.Array;
8916
- var join7 = uncurryThis([].join);
9248
+ var join9 = uncurryThis([].join);
8917
9249
  var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toBase64 || !(function() {
8918
9250
  try {
8919
9251
  var target = new Uint8Array2();
@@ -8959,7 +9291,7 @@ var init_pdf2 = __esm({
8959
9291
  result[written++] = "=";
8960
9292
  }
8961
9293
  }
8962
- return join7(result, "");
9294
+ return join9(result, "");
8963
9295
  }
8964
9296
  });
8965
9297
  },
@@ -8971,7 +9303,7 @@ var init_pdf2 = __esm({
8971
9303
  var anUint8Array = __webpack_require__2(4154);
8972
9304
  var notDetached = __webpack_require__2(5169);
8973
9305
  var numberToString = uncurryThis(1.1.toString);
8974
- var join7 = uncurryThis([].join);
9306
+ var join9 = uncurryThis([].join);
8975
9307
  var $Array = Array;
8976
9308
  var Uint8Array2 = globalThis2.Uint8Array;
8977
9309
  var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array2 || !Uint8Array2.prototype.toHex || !(function() {
@@ -8991,7 +9323,7 @@ var init_pdf2 = __esm({
8991
9323
  var hex = numberToString(this[i], 16);
8992
9324
  result[i] = hex.length === 1 ? "0" + hex : hex;
8993
9325
  }
8994
- return join7(result, "");
9326
+ return join9(result, "");
8995
9327
  }
8996
9328
  });
8997
9329
  },
@@ -9470,13 +9802,13 @@ var init_pdf2 = __esm({
9470
9802
  });
9471
9803
  }
9472
9804
  static get isCanvasFilterSupported() {
9473
- let ctx;
9805
+ let ctx2;
9474
9806
  if (this.isOffscreenCanvasSupported) {
9475
- ctx = new OffscreenCanvas(1, 1).getContext("2d");
9807
+ ctx2 = new OffscreenCanvas(1, 1).getContext("2d");
9476
9808
  } else if (typeof document !== "undefined") {
9477
- ctx = document.createElement("canvas").getContext("2d");
9809
+ ctx2 = document.createElement("canvas").getContext("2d");
9478
9810
  }
9479
- return shadow(this, "isCanvasFilterSupported", ctx?.filter !== void 0);
9811
+ return shadow(this, "isCanvasFilterSupported", ctx2?.filter !== void 0);
9480
9812
  }
9481
9813
  static get isAlphaColorInputSupported() {
9482
9814
  if (typeof document === "undefined") {
@@ -10623,14 +10955,14 @@ var init_pdf2 = __esm({
10623
10955
  static get _isSVGFittingCanvas() {
10624
10956
  const svg = `data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 1 1" width="1" height="1" xmlns="${SVG_NS}"><rect width="1" height="1" style="fill:red;"/></svg>`;
10625
10957
  const canvas = new OffscreenCanvas(1, 3);
10626
- const ctx = canvas.getContext("2d", {
10958
+ const ctx2 = canvas.getContext("2d", {
10627
10959
  willReadFrequently: true
10628
10960
  });
10629
10961
  const image = new Image();
10630
10962
  image.src = svg;
10631
10963
  const promise = image.decode().then(() => {
10632
- ctx.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3);
10633
- return new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer)[0] === 0;
10964
+ ctx2.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3);
10965
+ return new Uint32Array(ctx2.getImageData(0, 0, 1, 1).data.buffer)[0] === 0;
10634
10966
  });
10635
10967
  return shadow(this, "_isSVGFittingCanvas", promise);
10636
10968
  }
@@ -10738,8 +11070,8 @@ var init_pdf2 = __esm({
10738
11070
  return data;
10739
11071
  }
10740
11072
  const offscreen = new OffscreenCanvas(canvas.width, canvas.height);
10741
- const ctx = offscreen.getContext("2d");
10742
- ctx.drawImage(canvas, 0, 0);
11073
+ const ctx2 = offscreen.getContext("2d");
11074
+ ctx2.drawImage(canvas, 0, 0);
10743
11075
  data = {
10744
11076
  bitmap: offscreen.transferToImageBitmap(),
10745
11077
  id: `image_${this.#baseId}_${this.#id++}`,
@@ -10772,8 +11104,8 @@ var init_pdf2 = __esm({
10772
11104
  } = data;
10773
11105
  if (!data.url && !data.file) {
10774
11106
  const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
10775
- const ctx = canvas.getContext("bitmaprenderer");
10776
- ctx.transferFromImageBitmap(bitmap);
11107
+ const ctx2 = canvas.getContext("bitmaprenderer");
11108
+ ctx2.transferFromImageBitmap(bitmap);
10777
11109
  data.blobPromise = canvas.convertToBlob();
10778
11110
  }
10779
11111
  bitmap.close?.();
@@ -15670,8 +16002,8 @@ var init_pdf2 = __esm({
15670
16002
  }
15671
16003
  return this;
15672
16004
  }
15673
- pushBaseTransform(ctx) {
15674
- this.#baseTransformStack.push(Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform()));
16005
+ pushBaseTransform(ctx2) {
16006
+ this.#baseTransformStack.push(Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx2.getTransform()));
15675
16007
  return this;
15676
16008
  }
15677
16009
  popBaseTransform() {
@@ -15687,8 +16019,8 @@ var init_pdf2 = __esm({
15687
16019
  }
15688
16020
  return this;
15689
16021
  }
15690
- recordClipBox(idx, ctx, minX, maxX, minY, maxY) {
15691
- const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform());
16022
+ recordClipBox(idx, ctx2, minX, maxX, minY, maxY) {
16023
+ const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx2.getTransform());
15692
16024
  const clipBox = BBOX_INIT.slice();
15693
16025
  Util.axialAlignedBoundingBox([minX, minY, maxX, maxY], transform, clipBox);
15694
16026
  const intersection = Util.intersect(this.#clipBox, clipBox);
@@ -15703,12 +16035,12 @@ var init_pdf2 = __esm({
15703
16035
  }
15704
16036
  return this;
15705
16037
  }
15706
- recordBBox(idx, ctx, minX, maxX, minY, maxY) {
16038
+ recordBBox(idx, ctx2, minX, maxX, minY, maxY) {
15707
16039
  const clipBox = this.#clipBox;
15708
16040
  if (clipBox[0] === Infinity) {
15709
16041
  return this;
15710
16042
  }
15711
- const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform());
16043
+ const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx2.getTransform());
15712
16044
  if (clipBox[0] === -Infinity) {
15713
16045
  Util.axialAlignedBoundingBox([minX, minY, maxX, maxY], transform, this.#pendingBBox);
15714
16046
  return this;
@@ -15791,7 +16123,7 @@ var init_pdf2 = __esm({
15791
16123
  inheritPendingDependenciesAsFutureForcedDependencies() {
15792
16124
  return this;
15793
16125
  }
15794
- recordCharacterBBox(idx, ctx, font, scale = 1, x = 0, y = 0, getMeasure) {
16126
+ recordCharacterBBox(idx, ctx2, font, scale = 1, x = 0, y = 0, getMeasure) {
15795
16127
  return this;
15796
16128
  }
15797
16129
  getSimpleIndex(dependencyName) {
@@ -15890,8 +16222,8 @@ var init_pdf2 = __esm({
15890
16222
  this.#bboxTracker.endMarkedContent(opIdx, this.#recordDebugMetadataDepenencyAfterRestore);
15891
16223
  return this;
15892
16224
  }
15893
- pushBaseTransform(ctx) {
15894
- this.#bboxTracker.pushBaseTransform(ctx);
16225
+ pushBaseTransform(ctx2) {
16226
+ this.#bboxTracker.pushBaseTransform(ctx2);
15895
16227
  return this;
15896
16228
  }
15897
16229
  popBaseTransform() {
@@ -15939,15 +16271,15 @@ var init_pdf2 = __esm({
15939
16271
  this.#bboxTracker.resetBBox(idx);
15940
16272
  return this;
15941
16273
  }
15942
- recordClipBox(idx, ctx, minX, maxX, minY, maxY) {
15943
- this.#bboxTracker.recordClipBox(idx, ctx, minX, maxX, minY, maxY);
16274
+ recordClipBox(idx, ctx2, minX, maxX, minY, maxY) {
16275
+ this.#bboxTracker.recordClipBox(idx, ctx2, minX, maxX, minY, maxY);
15944
16276
  return this;
15945
16277
  }
15946
- recordBBox(idx, ctx, minX, maxX, minY, maxY) {
15947
- this.#bboxTracker.recordBBox(idx, ctx, minX, maxX, minY, maxY);
16278
+ recordBBox(idx, ctx2, minX, maxX, minY, maxY) {
16279
+ this.#bboxTracker.recordBBox(idx, ctx2, minX, maxX, minY, maxY);
15948
16280
  return this;
15949
16281
  }
15950
- recordCharacterBBox(idx, ctx, font, scale = 1, x = 0, y = 0, getMeasure) {
16282
+ recordCharacterBBox(idx, ctx2, font, scale = 1, x = 0, y = 0, getMeasure) {
15951
16283
  const fontBBox = font.bbox;
15952
16284
  let isBBoxTrustworthy;
15953
16285
  let computedBBox;
@@ -15960,7 +16292,7 @@ var init_pdf2 = __esm({
15960
16292
  scaleCharBBox(scale, -scale, x, y, computedBBox);
15961
16293
  }
15962
16294
  if (isBBoxTrustworthy) {
15963
- return this.recordBBox(idx, ctx, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]);
16295
+ return this.recordBBox(idx, ctx2, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]);
15964
16296
  }
15965
16297
  }
15966
16298
  }
@@ -15972,10 +16304,10 @@ var init_pdf2 = __esm({
15972
16304
  isBBoxTrustworthy = computedBBox[0] <= x - measure.actualBoundingBoxLeft && computedBBox[2] >= x + measure.actualBoundingBoxRight && computedBBox[1] <= y - measure.actualBoundingBoxAscent && computedBBox[3] >= y + measure.actualBoundingBoxDescent;
15973
16305
  this.#fontBBoxTrustworthy.set(font, isBBoxTrustworthy);
15974
16306
  if (isBBoxTrustworthy) {
15975
- return this.recordBBox(idx, ctx, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]);
16307
+ return this.recordBBox(idx, ctx2, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]);
15976
16308
  }
15977
16309
  }
15978
- return this.recordBBox(idx, ctx, x - measure.actualBoundingBoxLeft, x + measure.actualBoundingBoxRight, y - measure.actualBoundingBoxAscent, y + measure.actualBoundingBoxDescent);
16310
+ return this.recordBBox(idx, ctx2, x - measure.actualBoundingBoxLeft, x + measure.actualBoundingBoxRight, y - measure.actualBoundingBoxAscent, y + measure.actualBoundingBoxDescent);
15979
16311
  }
15980
16312
  recordFullPageBBox(idx) {
15981
16313
  this.#bboxTracker.recordFullPageBBox(idx);
@@ -16097,8 +16429,8 @@ var init_pdf2 = __esm({
16097
16429
  endMarkedContent(opIdx) {
16098
16430
  return this;
16099
16431
  }
16100
- pushBaseTransform(ctx) {
16101
- this.#dependencyTracker.pushBaseTransform(ctx);
16432
+ pushBaseTransform(ctx2) {
16433
+ this.#dependencyTracker.pushBaseTransform(ctx2);
16102
16434
  return this;
16103
16435
  }
16104
16436
  popBaseTransform() {
@@ -16142,21 +16474,21 @@ var init_pdf2 = __esm({
16142
16474
  }
16143
16475
  return this;
16144
16476
  }
16145
- recordClipBox(idx, ctx, minX, maxX, minY, maxY) {
16477
+ recordClipBox(idx, ctx2, minX, maxX, minY, maxY) {
16146
16478
  if (!this.#ignoreBBoxes) {
16147
- this.#dependencyTracker.recordClipBox(this.#opIdx, ctx, minX, maxX, minY, maxY);
16479
+ this.#dependencyTracker.recordClipBox(this.#opIdx, ctx2, minX, maxX, minY, maxY);
16148
16480
  }
16149
16481
  return this;
16150
16482
  }
16151
- recordBBox(idx, ctx, minX, maxX, minY, maxY) {
16483
+ recordBBox(idx, ctx2, minX, maxX, minY, maxY) {
16152
16484
  if (!this.#ignoreBBoxes) {
16153
- this.#dependencyTracker.recordBBox(this.#opIdx, ctx, minX, maxX, minY, maxY);
16485
+ this.#dependencyTracker.recordBBox(this.#opIdx, ctx2, minX, maxX, minY, maxY);
16154
16486
  }
16155
16487
  return this;
16156
16488
  }
16157
- recordCharacterBBox(idx, ctx, font, scale, x, y, getMeasure) {
16489
+ recordCharacterBBox(idx, ctx2, font, scale, x, y, getMeasure) {
16158
16490
  if (!this.#ignoreBBoxes) {
16159
- this.#dependencyTracker.recordCharacterBBox(this.#opIdx, ctx, font, scale, x, y, getMeasure);
16491
+ this.#dependencyTracker.recordCharacterBBox(this.#opIdx, ctx2, font, scale, x, y, getMeasure);
16160
16492
  }
16161
16493
  return this;
16162
16494
  }
@@ -16218,14 +16550,14 @@ var init_pdf2 = __esm({
16218
16550
  this.#canvasWidth = canvas.width;
16219
16551
  this.#canvasHeight = canvas.height;
16220
16552
  }
16221
- record(ctx, width, height, clipBox) {
16553
+ record(ctx2, width, height, clipBox) {
16222
16554
  if (this.#count === this.#capacity) {
16223
16555
  this.#capacity *= 2;
16224
16556
  const newCoords = new _CanvasImagesTracker.#CoordsArray(this.#capacity * 6);
16225
16557
  newCoords.set(this.#coords);
16226
16558
  this.#coords = newCoords;
16227
16559
  }
16228
- const transform = getCurrentTransform(ctx);
16560
+ const transform = getCurrentTransform(ctx2);
16229
16561
  let coords;
16230
16562
  if (clipBox[0] !== Infinity) {
16231
16563
  const bbox = BBOX_INIT.slice();
@@ -16451,7 +16783,7 @@ var init_pdf2 = __esm({
16451
16783
  const canvas = this._document.createElement("canvas");
16452
16784
  canvas.width = 1;
16453
16785
  canvas.height = 1;
16454
- const ctx = canvas.getContext("2d");
16786
+ const ctx2 = canvas.getContext("2d");
16455
16787
  let called = 0;
16456
16788
  function isFontReady(name2, callback) {
16457
16789
  if (++called > 30) {
@@ -16459,9 +16791,9 @@ var init_pdf2 = __esm({
16459
16791
  callback();
16460
16792
  return;
16461
16793
  }
16462
- ctx.font = "30px " + name2;
16463
- ctx.fillText(".", 0, 20);
16464
- const imageData = ctx.getImageData(0, 0, 1, 1);
16794
+ ctx2.font = "30px " + name2;
16795
+ ctx2.fillText(".", 0, 20);
16796
+ const imageData = ctx2.getImageData(0, 0, 1, 1);
16465
16797
  if (imageData.data[3] > 0) {
16466
16798
  callback();
16467
16799
  return;
@@ -18200,7 +18532,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18200
18532
  const dist = Math.hypot(this._p0[0] - this._p1[0], this._p0[1] - this._p1[1]);
18201
18533
  return dist + this._r1 > this._r0 && dist + this._r0 > this._r1;
18202
18534
  }
18203
- _createGradient(ctx, transform = null) {
18535
+ _createGradient(ctx2, transform = null) {
18204
18536
  let grad;
18205
18537
  let firstPoint = this._p0;
18206
18538
  let secondPoint = this._p1;
@@ -18211,7 +18543,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18211
18543
  Util.applyTransform(secondPoint, transform);
18212
18544
  }
18213
18545
  if (this._type === "axial") {
18214
- grad = ctx.createLinearGradient(firstPoint[0], firstPoint[1], secondPoint[0], secondPoint[1]);
18546
+ grad = ctx2.createLinearGradient(firstPoint[0], firstPoint[1], secondPoint[0], secondPoint[1]);
18215
18547
  } else if (this._type === "radial") {
18216
18548
  let r0 = this._r0;
18217
18549
  let r1 = this._r1;
@@ -18221,14 +18553,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18221
18553
  r0 *= scale[0];
18222
18554
  r1 *= scale[0];
18223
18555
  }
18224
- grad = ctx.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1);
18556
+ grad = ctx2.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1);
18225
18557
  }
18226
18558
  for (const colorStop of this._colorStops) {
18227
18559
  grad.addColorStop(colorStop[0], colorStop[1]);
18228
18560
  }
18229
18561
  return grad;
18230
18562
  }
18231
- _createReversedGradient(ctx, transform = null) {
18563
+ _createReversedGradient(ctx2, transform = null) {
18232
18564
  let firstPoint = this._p1;
18233
18565
  let secondPoint = this._p0;
18234
18566
  if (transform) {
@@ -18245,14 +18577,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18245
18577
  r0 *= scale[0];
18246
18578
  r1 *= scale[0];
18247
18579
  }
18248
- const grad = ctx.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1);
18580
+ const grad = ctx2.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1);
18249
18581
  const reversedStops = this._colorStops.map(([t, c]) => [1 - t, c]).reverse();
18250
18582
  for (const [t, c] of reversedStops) {
18251
18583
  grad.addColorStop(t, c);
18252
18584
  }
18253
18585
  return grad;
18254
18586
  }
18255
- getPattern(ctx, owner, inverse, pathType) {
18587
+ getPattern(ctx2, owner, inverse, pathType) {
18256
18588
  let pattern;
18257
18589
  if (pathType === PathType.STROKE || pathType === PathType.FILL) {
18258
18590
  if (this.isOriginBased()) {
@@ -18267,14 +18599,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18267
18599
  if (Math.abs(ps) < precision) {
18268
18600
  if (this.isRadial()) {
18269
18601
  if (Math.abs(n1 - n2) < precision) {
18270
- return this._createGradient(ctx, transf);
18602
+ return this._createGradient(ctx2, transf);
18271
18603
  }
18272
18604
  } else {
18273
- return this._createGradient(ctx, transf);
18605
+ return this._createGradient(ctx2, transf);
18274
18606
  }
18275
18607
  }
18276
18608
  }
18277
- const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, getCurrentTransform(ctx)) || [0, 0, 0, 0];
18609
+ const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, getCurrentTransform(ctx2)) || [0, 0, 0, 0];
18278
18610
  const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1;
18279
18611
  const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1;
18280
18612
  const tmpCanvas = owner.canvasFactory.create(width, height);
@@ -18295,20 +18627,20 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18295
18627
  }
18296
18628
  tmpCtx.fillStyle = this._createGradient(tmpCtx);
18297
18629
  tmpCtx.fill();
18298
- pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat");
18630
+ pattern = ctx2.createPattern(tmpCanvas.canvas, "no-repeat");
18299
18631
  owner.canvasFactory.destroy(tmpCanvas);
18300
18632
  const domMatrix = new DOMMatrix(inverse);
18301
18633
  pattern.setTransform(domMatrix);
18302
18634
  } else {
18303
18635
  if (this.areConic()) {
18304
- ctx.save();
18305
- applyBoundingBox(ctx, this._bbox);
18306
- ctx.fillStyle = this._createReversedGradient(ctx);
18307
- ctx.fillRect(-1e10, -1e10, 2e10, 2e10);
18308
- ctx.restore();
18636
+ ctx2.save();
18637
+ applyBoundingBox(ctx2, this._bbox);
18638
+ ctx2.fillStyle = this._createReversedGradient(ctx2);
18639
+ ctx2.fillRect(-1e10, -1e10, 2e10, 2e10);
18640
+ ctx2.restore();
18309
18641
  }
18310
- applyBoundingBox(ctx, this._bbox);
18311
- pattern = this._createGradient(ctx);
18642
+ applyBoundingBox(ctx2, this._bbox);
18643
+ pattern = this._createGradient(ctx2);
18312
18644
  }
18313
18645
  return pattern;
18314
18646
  }
@@ -18376,11 +18708,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18376
18708
  isModifyingCurrentTransform() {
18377
18709
  return true;
18378
18710
  }
18379
- getPattern(ctx, owner, inverse, pathType) {
18380
- applyBoundingBox(ctx, this._bbox);
18711
+ getPattern(ctx2, owner, inverse, pathType) {
18712
+ applyBoundingBox(ctx2, this._bbox);
18381
18713
  const scale = new Float32Array(2);
18382
18714
  if (pathType === PathType.SHADING) {
18383
- Util.singularValueDecompose2dScale(getCurrentTransform(ctx), scale);
18715
+ Util.singularValueDecompose2dScale(getCurrentTransform(ctx2), scale);
18384
18716
  } else if (this.matrix) {
18385
18717
  Util.singularValueDecompose2dScale(this.matrix, scale);
18386
18718
  const [matrixScaleX, matrixScaleY] = scale;
@@ -18392,14 +18724,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18392
18724
  }
18393
18725
  const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.canvasFactory);
18394
18726
  if (pathType !== PathType.SHADING) {
18395
- ctx.setTransform(...owner.baseTransform);
18727
+ ctx2.setTransform(...owner.baseTransform);
18396
18728
  if (this.matrix) {
18397
- ctx.transform(...this.matrix);
18729
+ ctx2.transform(...this.matrix);
18398
18730
  }
18399
18731
  }
18400
- ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);
18401
- ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);
18402
- const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat");
18732
+ ctx2.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);
18733
+ ctx2.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);
18734
+ const pattern = ctx2.createPattern(temporaryPatternCanvas.canvas, "no-repeat");
18403
18735
  owner.canvasFactory.destroy(temporaryPatternCanvas);
18404
18736
  return pattern;
18405
18737
  }
@@ -18415,7 +18747,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18415
18747
  };
18416
18748
  TilingPattern = class _TilingPattern {
18417
18749
  static MAX_PATTERN_SIZE = 3e3;
18418
- constructor(IR, ctx, canvasGraphicsFactory, baseTransform) {
18750
+ constructor(IR, ctx2, canvasGraphicsFactory, baseTransform) {
18419
18751
  this.color = IR[1];
18420
18752
  this.operatorList = IR[2];
18421
18753
  this.matrix = IR[3];
@@ -18425,7 +18757,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18425
18757
  this.paintType = IR[7];
18426
18758
  this.tilingType = IR[8];
18427
18759
  this.needsIsolation = IR[9] ?? true;
18428
- this.ctx = ctx;
18760
+ this.ctx = ctx2;
18429
18761
  this.canvasGraphicsFactory = canvasGraphicsFactory;
18430
18762
  this.baseTransform = baseTransform;
18431
18763
  this.patternBaseMatrix = this.matrix ? Util.transform(baseTransform, this.matrix) : baseTransform;
@@ -18627,13 +18959,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18627
18959
  isModifyingCurrentTransform() {
18628
18960
  return false;
18629
18961
  }
18630
- getPattern(ctx, owner, inverse, pathType, opIdx) {
18962
+ getPattern(ctx2, owner, inverse, pathType, opIdx) {
18631
18963
  const matrix = pathType !== PathType.SHADING ? Util.transform(inverse, this.patternBaseMatrix) : inverse;
18632
18964
  const temporaryPatternCanvas = this.createPatternCanvas(owner, opIdx);
18633
18965
  let domMatrix = new DOMMatrix(matrix);
18634
18966
  domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);
18635
18967
  domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY);
18636
- const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat");
18968
+ const pattern = ctx2.createPattern(temporaryPatternCanvas.canvas, "repeat");
18637
18969
  owner.canvasFactory.destroy(temporaryPatternCanvas.canvasEntry);
18638
18970
  pattern.setTransform(domMatrix);
18639
18971
  return pattern;
@@ -18910,13 +19242,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
18910
19242
  this.#knockoutElementDepth = 0;
18911
19243
  this.#knockoutGroupLevel = 0;
18912
19244
  this.cachedPatterns.clear();
18913
- for (const cache2 of this._cachedBitmapsMap.values()) {
18914
- for (const canvas of cache2.values()) {
19245
+ for (const cache3 of this._cachedBitmapsMap.values()) {
19246
+ for (const canvas of cache3.values()) {
18915
19247
  if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) {
18916
19248
  canvas.width = canvas.height = 0;
18917
19249
  }
18918
19250
  }
18919
- cache2.clear();
19251
+ cache3.clear();
18920
19252
  }
18921
19253
  this._cachedBitmapsMap.clear();
18922
19254
  this.#drawFilter();
@@ -19002,20 +19334,20 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19002
19334
  };
19003
19335
  }
19004
19336
  _createMaskCanvas(opIdx, img) {
19005
- const ctx = this.ctx;
19337
+ const ctx2 = this.ctx;
19006
19338
  const {
19007
19339
  width,
19008
19340
  height
19009
19341
  } = img;
19010
19342
  const fillColor = this.current.fillColor;
19011
19343
  const isPatternFill = this.current.patternFill;
19012
- const currentTransform = getCurrentTransform(ctx);
19013
- let cache2, cacheKey, scaled, maskCanvas;
19344
+ const currentTransform = getCurrentTransform(ctx2);
19345
+ let cache3, cacheKey, scaled, maskCanvas;
19014
19346
  if ((img.bitmap || img.data) && img.count > 1) {
19015
19347
  const mainKey = img.bitmap || img.data.buffer;
19016
19348
  cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]);
19017
- cache2 = this._cachedBitmapsMap.getOrInsertComputed(mainKey, makeMap);
19018
- const cachedImage = cache2.get(cacheKey);
19349
+ cache3 = this._cachedBitmapsMap.getOrInsertComputed(mainKey, makeMap);
19350
+ const cachedImage = cache3.get(cacheKey);
19019
19351
  if (cachedImage && !isPatternFill) {
19020
19352
  const offsetX2 = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]);
19021
19353
  const offsetY2 = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]);
@@ -19054,8 +19386,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19054
19386
  this.canvasFactory.destroy(maskCanvas);
19055
19387
  maskCanvas = null;
19056
19388
  }
19057
- if (cache2 && isPatternFill) {
19058
- cache2.set(cacheKey, scaled);
19389
+ if (cache3 && isPatternFill) {
19390
+ cache3.set(cacheKey, scaled);
19059
19391
  scaledEntry = null;
19060
19392
  maskCanvas = null;
19061
19393
  }
@@ -19070,15 +19402,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19070
19402
  }
19071
19403
  fillCtx.globalCompositeOperation = "source-in";
19072
19404
  const inverse = Util.transform(getCurrentTransformInverse(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]);
19073
- fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, PathType.FILL, opIdx) : fillColor;
19405
+ fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx2, this, inverse, PathType.FILL, opIdx) : fillColor;
19074
19406
  fillCtx.fillRect(0, 0, width, height);
19075
- if (cache2 && !isPatternFill) {
19076
- cache2.set(cacheKey, fillCanvas.canvas);
19407
+ if (cache3 && !isPatternFill) {
19408
+ cache3.set(cacheKey, fillCanvas.canvas);
19077
19409
  }
19078
19410
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.transformAndFill);
19079
19411
  return {
19080
19412
  canvas: fillCanvas.canvas,
19081
- canvasEntry: cache2 && !isPatternFill ? null : fillCanvas,
19413
+ canvasEntry: cache3 && !isPatternFill ? null : fillCanvas,
19082
19414
  offsetX: Math.round(offsetX),
19083
19415
  offsetY: Math.round(offsetY)
19084
19416
  };
@@ -19105,10 +19437,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19105
19437
  }
19106
19438
  setDash(opIdx, dashArray, dashPhase) {
19107
19439
  this.dependencyTracker?.recordSimpleData("dash", opIdx);
19108
- const ctx = this.ctx;
19109
- if (ctx.setLineDash !== void 0) {
19110
- ctx.setLineDash(dashArray);
19111
- ctx.lineDashOffset = dashPhase;
19440
+ const ctx2 = this.ctx;
19441
+ if (ctx2.setLineDash !== void 0) {
19442
+ ctx2.setLineDash(dashArray);
19443
+ ctx2.lineDashOffset = dashPhase;
19112
19444
  }
19113
19445
  }
19114
19446
  setRenderingIntent(opIdx, intent) {
@@ -19307,10 +19639,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19307
19639
  const scratchCanvas = this.canvasFactory.create(drawnWidth, drawnHeight);
19308
19640
  this.smaskScratchCanvas = scratchCanvas;
19309
19641
  this.suspendedCtx = this.ctx;
19310
- const ctx = this.ctx = scratchCanvas.context;
19311
- ctx.setTransform(this.suspendedCtx.getTransform());
19312
- copyCtxState(this.suspendedCtx, ctx);
19313
- mirrorContextOperations(ctx, this.suspendedCtx);
19642
+ const ctx2 = this.ctx = scratchCanvas.context;
19643
+ ctx2.setTransform(this.suspendedCtx.getTransform());
19644
+ copyCtxState(this.suspendedCtx, ctx2);
19645
+ mirrorContextOperations(ctx2, this.suspendedCtx);
19314
19646
  this._ensurePreparedSMask(this.current.activeSMask);
19315
19647
  this.setGState(opIdx, [["BM", "source-over"]]);
19316
19648
  }
@@ -19379,11 +19711,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19379
19711
  }
19380
19712
  return entry;
19381
19713
  }
19382
- const ctx = entry.context;
19383
- ctx.save();
19384
- ctx.setTransform(1, 0, 0, 1, 0, 0);
19385
- ctx.clearRect(0, 0, width, height);
19386
- ctx.restore();
19714
+ const ctx2 = entry.context;
19715
+ ctx2.save();
19716
+ ctx2.setTransform(1, 0, 0, 1, 0, 0);
19717
+ ctx2.clearRect(0, 0, width, height);
19718
+ ctx2.restore();
19387
19719
  return entry;
19388
19720
  }
19389
19721
  #compositeKnockoutSurface(destCtx, surfaceCanvas, options = {}) {
@@ -19523,7 +19855,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19523
19855
  this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
19524
19856
  this.ctx.restore();
19525
19857
  }
19526
- composeSMask(ctx, smask, layerCtx, layerBox) {
19858
+ composeSMask(ctx2, smask, layerCtx, layerBox) {
19527
19859
  const layerOffsetX = layerBox[0];
19528
19860
  const layerOffsetY = layerBox[1];
19529
19861
  const layerWidth = layerBox[2] - layerOffsetX;
@@ -19566,15 +19898,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19566
19898
  } else {
19567
19899
  this.genericComposeSMask(smask, layerCtx, layerWidth, layerHeight, layerOffsetX, layerOffsetY);
19568
19900
  }
19569
- if (!ctx) {
19901
+ if (!ctx2) {
19570
19902
  return;
19571
19903
  }
19572
- ctx.save();
19573
- ctx.globalAlpha = 1;
19574
- ctx.globalCompositeOperation = smask.blendMode || "source-over";
19575
- ctx.setTransform(1, 0, 0, 1, 0, 0);
19576
- ctx.drawImage(layerCtx.canvas, layerOffsetX, layerOffsetY, layerWidth, layerHeight, layerOffsetX, layerOffsetY, layerWidth, layerHeight);
19577
- ctx.restore();
19904
+ ctx2.save();
19905
+ ctx2.globalAlpha = 1;
19906
+ ctx2.globalCompositeOperation = smask.blendMode || "source-over";
19907
+ ctx2.setTransform(1, 0, 0, 1, 0, 0);
19908
+ ctx2.drawImage(layerCtx.canvas, layerOffsetX, layerOffsetY, layerWidth, layerHeight, layerOffsetX, layerOffsetY, layerWidth, layerHeight);
19909
+ ctx2.restore();
19578
19910
  }
19579
19911
  _applySMaskOOBAlpha(layerCtx, layerOffsetX, layerOffsetY, layerWidth, layerHeight, maskX0, maskY0, maskX1, maskY1, alpha) {
19580
19912
  const hasInnerCutout = maskX0 < maskX1 && maskY0 < maskY1;
@@ -19681,21 +20013,21 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19681
20013
  }
19682
20014
  stroke(opIdx, path, consumePath = true) {
19683
20015
  const started = consumePath && this.#beginKnockoutElement(this.current.strokeAlpha);
19684
- const ctx = this.ctx;
20016
+ const ctx2 = this.ctx;
19685
20017
  const strokeColor = this.current.strokeColor;
19686
- ctx.globalAlpha = this.current.strokeAlpha;
20018
+ ctx2.globalAlpha = this.current.strokeAlpha;
19687
20019
  if (this.contentVisible) {
19688
20020
  if (typeof strokeColor === "object" && strokeColor?.getPattern) {
19689
- const baseTransform = strokeColor.isModifyingCurrentTransform() ? ctx.getTransform() : null;
19690
- ctx.save();
19691
- ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
20021
+ const baseTransform = strokeColor.isModifyingCurrentTransform() ? ctx2.getTransform() : null;
20022
+ ctx2.save();
20023
+ ctx2.strokeStyle = strokeColor.getPattern(ctx2, this, getCurrentTransformInverse(ctx2), PathType.STROKE, opIdx);
19692
20024
  if (baseTransform) {
19693
20025
  const newPath = new Path2D();
19694
- newPath.addPath(path, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
20026
+ newPath.addPath(path, ctx2.getTransform().invertSelf().multiplySelf(baseTransform));
19695
20027
  path = newPath;
19696
20028
  }
19697
20029
  this.rescaleAndStroke(path, false);
19698
- ctx.restore();
20030
+ ctx2.restore();
19699
20031
  } else {
19700
20032
  this.rescaleAndStroke(path, true);
19701
20033
  }
@@ -19704,7 +20036,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19704
20036
  if (consumePath) {
19705
20037
  this.consumePath(opIdx, path, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
19706
20038
  }
19707
- ctx.globalAlpha = this.current.fillAlpha;
20039
+ ctx2.globalAlpha = this.current.fillAlpha;
19708
20040
  this.#endKnockoutElement(started);
19709
20041
  }
19710
20042
  closeStroke(opIdx, path) {
@@ -19712,7 +20044,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19712
20044
  }
19713
20045
  fill(opIdx, path, consumePath = true) {
19714
20046
  const started = consumePath && this.#beginKnockoutElement(this.current.fillAlpha);
19715
- const ctx = this.ctx;
20047
+ const ctx2 = this.ctx;
19716
20048
  const fillColor = this.current.fillColor;
19717
20049
  const isPatternFill = this.current.patternFill;
19718
20050
  let needRestore = false;
@@ -19731,27 +20063,27 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19731
20063
  this.#endKnockoutElement(started);
19732
20064
  return;
19733
20065
  }
19734
- const baseTransform = fillColor.isModifyingCurrentTransform() ? ctx.getTransform() : null;
20066
+ const baseTransform = fillColor.isModifyingCurrentTransform() ? ctx2.getTransform() : null;
19735
20067
  this.dependencyTracker?.save(opIdx);
19736
- ctx.save();
19737
- ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
20068
+ ctx2.save();
20069
+ ctx2.fillStyle = fillColor.getPattern(ctx2, this, getCurrentTransformInverse(ctx2), PathType.FILL, opIdx);
19738
20070
  if (baseTransform) {
19739
20071
  const newPath = new Path2D();
19740
- newPath.addPath(path, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
20072
+ newPath.addPath(path, ctx2.getTransform().invertSelf().multiplySelf(baseTransform));
19741
20073
  path = newPath;
19742
20074
  }
19743
20075
  needRestore = true;
19744
20076
  }
19745
20077
  if (this.contentVisible && intersect !== null) {
19746
20078
  if (this.pendingEOFill) {
19747
- ctx.fill(path, "evenodd");
20079
+ ctx2.fill(path, "evenodd");
19748
20080
  this.pendingEOFill = false;
19749
20081
  } else {
19750
- ctx.fill(path);
20082
+ ctx2.fill(path);
19751
20083
  }
19752
20084
  }
19753
20085
  if (needRestore) {
19754
- ctx.restore();
20086
+ ctx2.restore();
19755
20087
  this.dependencyTracker?.restore(opIdx);
19756
20088
  }
19757
20089
  if (consumePath) {
@@ -19807,7 +20139,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19807
20139
  }
19808
20140
  endText(opIdx) {
19809
20141
  const paths = this.pendingTextPaths;
19810
- const ctx = this.ctx;
20142
+ const ctx2 = this.ctx;
19811
20143
  if (this.dependencyTracker) {
19812
20144
  const {
19813
20145
  dependencyTracker
@@ -19819,7 +20151,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19819
20151
  }
19820
20152
  if (paths !== void 0) {
19821
20153
  const newPath = new Path2D();
19822
- const invTransf = ctx.getTransform().invertSelf();
20154
+ const invTransf = ctx2.getTransform().invertSelf();
19823
20155
  for (const {
19824
20156
  transform,
19825
20157
  x,
@@ -19832,7 +20164,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19832
20164
  }
19833
20165
  newPath.addPath(path, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize));
19834
20166
  }
19835
- ctx.clip(newPath);
20167
+ ctx2.clip(newPath);
19836
20168
  }
19837
20169
  delete this.pendingTextPaths;
19838
20170
  }
@@ -19924,7 +20256,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19924
20256
  return newPath;
19925
20257
  }
19926
20258
  paintChar(opIdx, character, x, y, patternFillTransform, patternStrokeTransform) {
19927
- const ctx = this.ctx;
20259
+ const ctx2 = this.ctx;
19928
20260
  const current = this.current;
19929
20261
  const font = current.font;
19930
20262
  const textRenderingMode = current.textRenderingMode;
@@ -19938,25 +20270,25 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19938
20270
  path = font.getPathGenerator(this.commonObjs, character);
19939
20271
  }
19940
20272
  if (path && (font.disableFontFace || patternFill || patternStroke)) {
19941
- ctx.save();
19942
- ctx.translate(x, y);
19943
- ctx.scale(fontSize, -fontSize);
19944
- this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font);
20273
+ ctx2.save();
20274
+ ctx2.translate(x, y);
20275
+ ctx2.scale(fontSize, -fontSize);
20276
+ this.dependencyTracker?.recordCharacterBBox(opIdx, ctx2, font);
19945
20277
  let currentTransform;
19946
20278
  if (fillStrokeMode === TextRenderingMode.FILL || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
19947
20279
  if (patternFillTransform) {
19948
- currentTransform = ctx.getTransform();
19949
- ctx.setTransform(...patternFillTransform);
20280
+ currentTransform = ctx2.getTransform();
20281
+ ctx2.setTransform(...patternFillTransform);
19950
20282
  const scaledPath = this.#getScaledPath(path, currentTransform, patternFillTransform);
19951
- ctx.fill(scaledPath);
20283
+ ctx2.fill(scaledPath);
19952
20284
  } else {
19953
- ctx.fill(path);
20285
+ ctx2.fill(path);
19954
20286
  }
19955
20287
  }
19956
20288
  if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
19957
20289
  if (patternStrokeTransform) {
19958
- currentTransform ||= ctx.getTransform();
19959
- ctx.setTransform(...patternStrokeTransform);
20290
+ currentTransform ||= ctx2.getTransform();
20291
+ ctx2.setTransform(...patternStrokeTransform);
19960
20292
  const {
19961
20293
  a,
19962
20294
  b,
@@ -19966,44 +20298,44 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
19966
20298
  const invPatternTransform = Util.inverseTransform(patternStrokeTransform);
19967
20299
  const transf = Util.transform([a, b, c, d, 0, 0], invPatternTransform);
19968
20300
  Util.singularValueDecompose2dScale(transf, XY);
19969
- ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
19970
- ctx.stroke(this.#getScaledPath(path, currentTransform, patternStrokeTransform));
20301
+ ctx2.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
20302
+ ctx2.stroke(this.#getScaledPath(path, currentTransform, patternStrokeTransform));
19971
20303
  } else {
19972
- ctx.lineWidth /= fontSize;
19973
- ctx.stroke(path);
20304
+ ctx2.lineWidth /= fontSize;
20305
+ ctx2.stroke(path);
19974
20306
  }
19975
20307
  }
19976
- ctx.restore();
20308
+ ctx2.restore();
19977
20309
  } else {
19978
20310
  if (fillStrokeMode === TextRenderingMode.FILL || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
19979
- ctx.fillText(character, x, y);
19980
- this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y, () => ctx.measureText(character));
20311
+ ctx2.fillText(character, x, y);
20312
+ this.dependencyTracker?.recordCharacterBBox(opIdx, ctx2, font, fontSize, x, y, () => ctx2.measureText(character));
19981
20313
  }
19982
20314
  if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
19983
20315
  if (this.dependencyTracker) {
19984
- this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y, () => ctx.measureText(character)).recordDependencies(opIdx, Dependencies.stroke);
20316
+ this.dependencyTracker?.recordCharacterBBox(opIdx, ctx2, font, fontSize, x, y, () => ctx2.measureText(character)).recordDependencies(opIdx, Dependencies.stroke);
19985
20317
  }
19986
- ctx.strokeText(character, x, y);
20318
+ ctx2.strokeText(character, x, y);
19987
20319
  }
19988
20320
  }
19989
20321
  if (isAddToPathSet) {
19990
20322
  const paths = this.pendingTextPaths ||= [];
19991
20323
  paths.push({
19992
- transform: getCurrentTransform(ctx),
20324
+ transform: getCurrentTransform(ctx2),
19993
20325
  x,
19994
20326
  y,
19995
20327
  fontSize,
19996
20328
  path
19997
20329
  });
19998
- this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y);
20330
+ this.dependencyTracker?.recordCharacterBBox(opIdx, ctx2, font, fontSize, x, y);
19999
20331
  }
20000
20332
  }
20001
20333
  get isFontSubpixelAAEnabled() {
20002
20334
  const tmpCanvas = this.canvasFactory.create(10, 10);
20003
- const ctx = tmpCanvas.context;
20004
- ctx.scale(1.5, 1);
20005
- ctx.fillText("I", 0, 10);
20006
- const data = ctx.getImageData(0, 0, 10, 10).data;
20335
+ const ctx2 = tmpCanvas.context;
20336
+ ctx2.scale(1.5, 1);
20337
+ ctx2.fillText("I", 0, 10);
20338
+ const data = ctx2.getImageData(0, 0, 10, 10).data;
20007
20339
  this.canvasFactory.destroy(tmpCanvas);
20008
20340
  let enabled = false;
20009
20341
  for (let i = 3; i < data.length; i += 4) {
@@ -20036,7 +20368,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20036
20368
  return;
20037
20369
  }
20038
20370
  const started = this.#beginKnockoutElement(current.fillAlpha);
20039
- const ctx = this.ctx;
20371
+ const ctx2 = this.ctx;
20040
20372
  const fontSizeScale = current.fontSizeScale;
20041
20373
  const charSpacing = current.charSpacing;
20042
20374
  const wordSpacing = current.wordSpacing;
@@ -20048,15 +20380,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20048
20380
  const defaultVMetrics = font.defaultVMetrics;
20049
20381
  const widthAdvanceScale = fontSize * current.fontMatrix[0];
20050
20382
  const simpleFillText = current.textRenderingMode === TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill;
20051
- ctx.save();
20383
+ ctx2.save();
20052
20384
  if (current.textMatrix) {
20053
- ctx.transform(...current.textMatrix);
20385
+ ctx2.transform(...current.textMatrix);
20054
20386
  }
20055
- ctx.translate(current.x, current.y + current.textRise);
20387
+ ctx2.translate(current.x, current.y + current.textRise);
20056
20388
  if (fontDirection > 0) {
20057
- ctx.scale(textHScale, -1);
20389
+ ctx2.scale(textHScale, -1);
20058
20390
  } else {
20059
- ctx.scale(textHScale, 1);
20391
+ ctx2.scale(textHScale, 1);
20060
20392
  }
20061
20393
  let patternFillTransform, patternStrokeTransform;
20062
20394
  const fillStrokeMode = current.textRenderingMode & TextRenderingMode.FILL_STROKE_MASK;
@@ -20072,23 +20404,23 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20072
20404
  lineWidth /= scale;
20073
20405
  }
20074
20406
  if (fontSizeScale !== 1) {
20075
- ctx.scale(fontSizeScale, fontSizeScale);
20407
+ ctx2.scale(fontSizeScale, fontSizeScale);
20076
20408
  lineWidth /= fontSizeScale;
20077
20409
  }
20078
- ctx.lineWidth = lineWidth;
20410
+ ctx2.lineWidth = lineWidth;
20079
20411
  if (needsFill && current.patternFill) {
20080
- ctx.save();
20081
- const pattern = current.fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
20082
- patternFillTransform = getCurrentTransform(ctx);
20083
- ctx.restore();
20084
- ctx.fillStyle = pattern;
20412
+ ctx2.save();
20413
+ const pattern = current.fillColor.getPattern(ctx2, this, getCurrentTransformInverse(ctx2), PathType.FILL, opIdx);
20414
+ patternFillTransform = getCurrentTransform(ctx2);
20415
+ ctx2.restore();
20416
+ ctx2.fillStyle = pattern;
20085
20417
  }
20086
20418
  if (needsStroke && current.patternStroke) {
20087
- ctx.save();
20088
- const pattern = current.strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
20089
- patternStrokeTransform = getCurrentTransform(ctx);
20090
- ctx.restore();
20091
- ctx.strokeStyle = pattern;
20419
+ ctx2.save();
20420
+ const pattern = current.strokeColor.getPattern(ctx2, this, getCurrentTransformInverse(ctx2), PathType.STROKE, opIdx);
20421
+ patternStrokeTransform = getCurrentTransform(ctx2);
20422
+ ctx2.restore();
20423
+ ctx2.strokeStyle = pattern;
20092
20424
  }
20093
20425
  if (font.isInvalidPDFjsFont) {
20094
20426
  const chars = [];
@@ -20098,13 +20430,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20098
20430
  width += glyph.width;
20099
20431
  }
20100
20432
  const joinedChars = chars.join("");
20101
- ctx.fillText(joinedChars, 0, 0);
20433
+ ctx2.fillText(joinedChars, 0, 0);
20102
20434
  if (this.dependencyTracker !== null) {
20103
- const measure = ctx.measureText(joinedChars);
20435
+ const measure = ctx2.measureText(joinedChars);
20104
20436
  this.dependencyTracker.recordBBox(opIdx, this.ctx, -measure.actualBoundingBoxLeft, measure.actualBoundingBoxRight, -measure.actualBoundingBoxAscent, measure.actualBoundingBoxDescent).recordShowTextOperation(opIdx);
20105
20437
  }
20106
20438
  current.x += width * widthAdvanceScale * textHScale;
20107
- ctx.restore();
20439
+ ctx2.restore();
20108
20440
  this.compose();
20109
20441
  this.#endKnockoutElement(started);
20110
20442
  return;
@@ -20135,13 +20467,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20135
20467
  }
20136
20468
  let measure;
20137
20469
  if (font.remeasure && width > 0) {
20138
- measure = ctx.measureText(character);
20470
+ measure = ctx2.measureText(character);
20139
20471
  const measuredWidth = measure.width * 1e3 / fontSize * fontSizeScale;
20140
20472
  if (width < measuredWidth && this.isFontSubpixelAAEnabled) {
20141
20473
  const characterScaleX = width / measuredWidth;
20142
20474
  restoreNeeded = true;
20143
- ctx.save();
20144
- ctx.scale(characterScaleX, 1);
20475
+ ctx2.save();
20476
+ ctx2.scale(characterScaleX, 1);
20145
20477
  scaledX /= characterScaleX;
20146
20478
  } else if (width !== measuredWidth) {
20147
20479
  scaledX += (width - measuredWidth) / 2e3 * fontSize / fontSizeScale;
@@ -20149,10 +20481,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20149
20481
  }
20150
20482
  if (this.contentVisible && (glyph.isInFont || font.missingFile)) {
20151
20483
  if (simpleFillText && !accent) {
20152
- ctx.fillText(character, scaledX, scaledY);
20153
- this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, measure ? {
20484
+ ctx2.fillText(character, scaledX, scaledY);
20485
+ this.dependencyTracker?.recordCharacterBBox(opIdx, ctx2, measure ? {
20154
20486
  bbox: null
20155
- } : font, fontSize / fontSizeScale, scaledX, scaledY, () => measure ?? ctx.measureText(character));
20487
+ } : font, fontSize / fontSizeScale, scaledX, scaledY, () => measure ?? ctx2.measureText(character));
20156
20488
  } else {
20157
20489
  this.paintChar(opIdx, character, scaledX, scaledY, patternFillTransform, patternStrokeTransform);
20158
20490
  if (accent) {
@@ -20165,7 +20497,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20165
20497
  const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection;
20166
20498
  x += charWidth;
20167
20499
  if (restoreNeeded) {
20168
- ctx.restore();
20500
+ ctx2.restore();
20169
20501
  }
20170
20502
  }
20171
20503
  if (vertical) {
@@ -20173,13 +20505,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20173
20505
  } else {
20174
20506
  current.x += x * textHScale;
20175
20507
  }
20176
- ctx.restore();
20508
+ ctx2.restore();
20177
20509
  this.compose();
20178
20510
  this.dependencyTracker?.recordShowTextOperation(opIdx);
20179
20511
  this.#endKnockoutElement(started);
20180
20512
  }
20181
20513
  showType3Text(opIdx, glyphs) {
20182
- const ctx = this.ctx;
20514
+ const ctx2 = this.ctx;
20183
20515
  const current = this.current;
20184
20516
  const font = current.font;
20185
20517
  const fontSize = current.fontSize;
@@ -20197,12 +20529,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20197
20529
  }
20198
20530
  this._cachedScaleForStroking[0] = -1;
20199
20531
  this._cachedGetSinglePixelWidth = null;
20200
- ctx.save();
20532
+ ctx2.save();
20201
20533
  if (current.textMatrix) {
20202
- ctx.transform(...current.textMatrix);
20534
+ ctx2.transform(...current.textMatrix);
20203
20535
  }
20204
- ctx.translate(current.x, current.y + current.textRise);
20205
- ctx.scale(textHScale, fontDirection);
20536
+ ctx2.translate(current.x, current.y + current.textRise);
20537
+ ctx2.scale(textHScale, fontDirection);
20206
20538
  const dependencyTracker = this.dependencyTracker;
20207
20539
  this.dependencyTracker = dependencyTracker ? new CanvasNestedDependencyTracker(dependencyTracker, opIdx) : null;
20208
20540
  for (i = 0; i < glyphsLength; ++i) {
@@ -20221,20 +20553,20 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20221
20553
  this.save();
20222
20554
  if (operatorList.fnArray[0] === OPS.setCharWidth) {
20223
20555
  current.fillAlpha = current.strokeAlpha = 1;
20224
- ctx.globalAlpha = 1;
20556
+ ctx2.globalAlpha = 1;
20225
20557
  }
20226
- ctx.scale(fontSize, fontSize);
20227
- ctx.transform(...fontMatrix);
20558
+ ctx2.scale(fontSize, fontSize);
20559
+ ctx2.transform(...fontMatrix);
20228
20560
  this.executeOperatorList(operatorList);
20229
20561
  this.restore();
20230
20562
  }
20231
20563
  const p = [glyph.width, 0];
20232
20564
  Util.applyTransform(p, fontMatrix);
20233
20565
  width = p[0] * fontSize + spacing;
20234
- ctx.translate(width, 0);
20566
+ ctx2.translate(width, 0);
20235
20567
  current.x += width * textHScale;
20236
20568
  }
20237
- ctx.restore();
20569
+ ctx2.restore();
20238
20570
  if (dependencyTracker) {
20239
20571
  this.dependencyTracker = dependencyTracker;
20240
20572
  }
@@ -20253,7 +20585,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20253
20585
  if (IR[0] === "TilingPattern") {
20254
20586
  const baseTransform = this.baseTransform || getCurrentTransform(this.ctx);
20255
20587
  const canvasGraphicsFactory = {
20256
- createCanvasGraphics: (ctx, renderingOpIdx) => new _CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, {
20588
+ createCanvasGraphics: (ctx2, renderingOpIdx) => new _CanvasGraphics(ctx2, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, {
20257
20589
  optionalContentConfig: this.optionalContentConfig,
20258
20590
  markedContentStack: this.markedContentStack
20259
20591
  }, void 0, void 0, this.dependencyTracker ? new CanvasNestedDependencyTracker(this.dependencyTracker, renderingOpIdx, true) : null)
@@ -20309,16 +20641,16 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20309
20641
  return;
20310
20642
  }
20311
20643
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20312
- const ctx = this.ctx;
20644
+ const ctx2 = this.ctx;
20313
20645
  this.save(opIdx);
20314
20646
  const pattern = this._getPattern(opIdx, objId);
20315
- ctx.fillStyle = pattern.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.SHADING, opIdx);
20316
- const inv = getCurrentTransformInverse(ctx);
20647
+ ctx2.fillStyle = pattern.getPattern(ctx2, this, getCurrentTransformInverse(ctx2), PathType.SHADING, opIdx);
20648
+ const inv = getCurrentTransformInverse(ctx2);
20317
20649
  if (inv) {
20318
20650
  const {
20319
20651
  width,
20320
20652
  height
20321
- } = ctx.canvas;
20653
+ } = ctx2.canvas;
20322
20654
  const minMax = F32_BBOX_INIT.slice();
20323
20655
  Util.axialAlignedBoundingBox([0, 0, width, height], inv, minMax);
20324
20656
  const [x0, y0, x1, y1] = minMax;
@@ -20490,19 +20822,19 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20490
20822
  }
20491
20823
  this.groupLevel--;
20492
20824
  const groupCtx = this.ctx;
20493
- const ctx = this.groupStack.pop();
20825
+ const ctx2 = this.groupStack.pop();
20494
20826
  const groupMeta = this.#groupStackMeta.pop();
20495
20827
  if (groupMeta) {
20496
20828
  this.#knockoutGroupLevel = groupMeta.savedKnockoutLevel;
20497
20829
  }
20498
- if (ctx === null) {
20830
+ if (ctx2 === null) {
20499
20831
  this.restore(opIdx);
20500
20832
  return;
20501
20833
  }
20502
20834
  if (group.isGray) {
20503
20835
  this.#convertGroupToGray(groupCtx);
20504
20836
  }
20505
- this.ctx = ctx;
20837
+ this.ctx = ctx2;
20506
20838
  this.ctx.imageSmoothingEnabled = false;
20507
20839
  this.dependencyTracker?.popBaseTransform();
20508
20840
  if (group.smask) {
@@ -20532,7 +20864,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20532
20864
  } = groupCtx.canvas;
20533
20865
  const colorEntry = this.canvasFactory.create(width, height);
20534
20866
  const colorCtx = colorEntry.context;
20535
- colorCtx.drawImage(ctx.canvas, groupMeta.offsetX, groupMeta.offsetY, width, height, 0, 0, width, height);
20867
+ colorCtx.drawImage(ctx2.canvas, groupMeta.offsetX, groupMeta.offsetY, width, height, 0, 0, width, height);
20536
20868
  colorCtx.globalCompositeOperation = "source-over";
20537
20869
  colorCtx.drawImage(groupCtx.canvas, 0, 0);
20538
20870
  const shapeMaskEntry = this.#createKnockoutMaskCanvas(groupCtx.canvas);
@@ -20706,14 +21038,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20706
21038
  img = this.getObject(opIdx, img.data, img);
20707
21039
  img.count = count;
20708
21040
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20709
- const ctx = this.ctx;
21041
+ const ctx2 = this.ctx;
20710
21042
  const mask = this._createMaskCanvas(opIdx, img);
20711
21043
  const maskCanvas = mask.canvas;
20712
- ctx.save();
20713
- ctx.setTransform(1, 0, 0, 1, 0, 0);
20714
- ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY);
21044
+ ctx2.save();
21045
+ ctx2.setTransform(1, 0, 0, 1, 0, 0);
21046
+ ctx2.drawImage(maskCanvas, mask.offsetX, mask.offsetY);
20715
21047
  this.dependencyTracker?.resetBBox(opIdx).recordBBox(opIdx, this.ctx, mask.offsetX, mask.offsetX + maskCanvas.width, mask.offsetY, mask.offsetY + maskCanvas.height).recordOperation(opIdx);
20716
- ctx.restore();
21048
+ ctx2.restore();
20717
21049
  if (mask.canvasEntry) {
20718
21050
  this.canvasFactory.destroy(mask.canvasEntry);
20719
21051
  }
@@ -20726,19 +21058,19 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20726
21058
  }
20727
21059
  img = this.getObject(opIdx, img.data, img);
20728
21060
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20729
- const ctx = this.ctx;
20730
- ctx.save();
20731
- const currentTransform = getCurrentTransform(ctx);
20732
- ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
21061
+ const ctx2 = this.ctx;
21062
+ ctx2.save();
21063
+ const currentTransform = getCurrentTransform(ctx2);
21064
+ ctx2.transform(scaleX, skewX, skewY, scaleY, 0, 0);
20733
21065
  const mask = this._createMaskCanvas(opIdx, img);
20734
- ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]);
21066
+ ctx2.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]);
20735
21067
  this.dependencyTracker?.resetBBox(opIdx);
20736
21068
  for (let i = 0, ii = positions.length; i < ii; i += 2) {
20737
21069
  const trans = Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);
20738
- ctx.drawImage(mask.canvas, trans[4], trans[5]);
21070
+ ctx2.drawImage(mask.canvas, trans[4], trans[5]);
20739
21071
  this.dependencyTracker?.recordBBox(opIdx, this.ctx, trans[4], trans[4] + mask.canvas.width, trans[5], trans[5] + mask.canvas.height);
20740
21072
  }
20741
- ctx.restore();
21073
+ ctx2.restore();
20742
21074
  if (mask.canvasEntry) {
20743
21075
  this.canvasFactory.destroy(mask.canvasEntry);
20744
21076
  }
@@ -20751,7 +21083,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20751
21083
  return;
20752
21084
  }
20753
21085
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20754
- const ctx = this.ctx;
21086
+ const ctx2 = this.ctx;
20755
21087
  const fillColor = this.current.fillColor;
20756
21088
  const isPatternFill = this.current.patternFill;
20757
21089
  this.dependencyTracker?.resetBBox(opIdx).recordDependencies(opIdx, Dependencies.transformAndFill);
@@ -20768,16 +21100,16 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20768
21100
  const img = this.getObject(opIdx, data, image);
20769
21101
  putBinaryImageMask(maskCtx, img);
20770
21102
  maskCtx.globalCompositeOperation = "source-in";
20771
- maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx) : fillColor;
21103
+ maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, getCurrentTransformInverse(ctx2), PathType.FILL, opIdx) : fillColor;
20772
21104
  maskCtx.fillRect(0, 0, width, height);
20773
21105
  maskCtx.restore();
20774
- ctx.save();
20775
- ctx.transform(...transform);
20776
- ctx.scale(1, -1);
20777
- drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);
21106
+ ctx2.save();
21107
+ ctx2.transform(...transform);
21108
+ ctx2.scale(1, -1);
21109
+ drawImageAtIntegerCoords(ctx2, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);
20778
21110
  this.canvasFactory.destroy(maskCanvas);
20779
- this.dependencyTracker?.recordBBox(opIdx, ctx, 0, width, 0, height);
20780
- ctx.restore();
21111
+ this.dependencyTracker?.recordBBox(opIdx, ctx2, 0, width, 0, height);
21112
+ ctx2.restore();
20781
21113
  }
20782
21114
  this.compose();
20783
21115
  this.dependencyTracker?.recordOperation(opIdx);
@@ -20817,13 +21149,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20817
21149
  }
20818
21150
  this.paintInlineImageXObjectGroup(opIdx, imgData, map);
20819
21151
  }
20820
- applyTransferMapsToCanvas(ctx) {
21152
+ applyTransferMapsToCanvas(ctx2) {
20821
21153
  if (this.current.transferMaps !== "none") {
20822
- ctx.filter = this.current.transferMaps;
20823
- ctx.drawImage(ctx.canvas, 0, 0);
20824
- ctx.filter = "none";
21154
+ ctx2.filter = this.current.transferMaps;
21155
+ ctx2.drawImage(ctx2.canvas, 0, 0);
21156
+ ctx2.filter = "none";
20825
21157
  }
20826
- return ctx.canvas;
21158
+ return ctx2.canvas;
20827
21159
  }
20828
21160
  applyTransferMapsToBitmap(imgData) {
20829
21161
  if (this.current.transferMaps === "none") {
@@ -20854,15 +21186,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20854
21186
  const width = imgData.width;
20855
21187
  const height = imgData.height;
20856
21188
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20857
- const ctx = this.ctx;
21189
+ const ctx2 = this.ctx;
20858
21190
  this.save(opIdx);
20859
21191
  const {
20860
21192
  filter
20861
- } = ctx;
21193
+ } = ctx2;
20862
21194
  if (filter !== "none" && filter !== "") {
20863
- ctx.filter = "none";
21195
+ ctx2.filter = "none";
20864
21196
  }
20865
- ctx.scale(1 / width, -1 / height);
21197
+ ctx2.scale(1 / width, -1 / height);
20866
21198
  let imgToPaint;
20867
21199
  let inlineImgCanvas = null;
20868
21200
  if (imgData.bitmap) {
@@ -20875,13 +21207,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20875
21207
  imgToPaint = this.applyTransferMapsToCanvas(tmpCanvas.context);
20876
21208
  inlineImgCanvas = tmpCanvas;
20877
21209
  }
20878
- const scaled = this._scaleImage(imgToPaint, getCurrentTransformInverse(ctx));
20879
- ctx.imageSmoothingEnabled = getImageSmoothingEnabled(getCurrentTransform(ctx), imgData.interpolate);
21210
+ const scaled = this._scaleImage(imgToPaint, getCurrentTransformInverse(ctx2));
21211
+ ctx2.imageSmoothingEnabled = getImageSmoothingEnabled(getCurrentTransform(ctx2), imgData.interpolate);
20880
21212
  if (this.dependencyTracker) {
20881
- this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, ctx, 0, width, -height, 0).recordDependencies(opIdx, Dependencies.imageXObject).recordOperation(opIdx);
20882
- this.imagesTracker?.record(ctx, width, height, this.dependencyTracker.clipBox);
21213
+ this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, ctx2, 0, width, -height, 0).recordDependencies(opIdx, Dependencies.imageXObject).recordOperation(opIdx);
21214
+ this.imagesTracker?.record(ctx2, width, height, this.dependencyTracker.clipBox);
20883
21215
  }
20884
- drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);
21216
+ drawImageAtIntegerCoords(ctx2, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);
20885
21217
  if (scaled.tmpCanvas) {
20886
21218
  this.canvasFactory.destroy(scaled.tmpCanvas);
20887
21219
  }
@@ -20897,7 +21229,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20897
21229
  return;
20898
21230
  }
20899
21231
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
20900
- const ctx = this.ctx;
21232
+ const ctx2 = this.ctx;
20901
21233
  let imgToPaint;
20902
21234
  let inlineImgCanvas = null;
20903
21235
  if (imgData.bitmap) {
@@ -20912,12 +21244,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20912
21244
  }
20913
21245
  this.dependencyTracker?.resetBBox(opIdx);
20914
21246
  for (const entry of map) {
20915
- ctx.save();
20916
- ctx.transform(...entry.transform);
20917
- ctx.scale(1, -1);
20918
- drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);
20919
- this.dependencyTracker?.recordBBox(opIdx, ctx, 0, 1, -1, 0);
20920
- ctx.restore();
21247
+ ctx2.save();
21248
+ ctx2.transform(...entry.transform);
21249
+ ctx2.scale(1, -1);
21250
+ drawImageAtIntegerCoords(ctx2, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);
21251
+ this.dependencyTracker?.recordBBox(opIdx, ctx2, 0, 1, -1, 0);
21252
+ ctx2.restore();
20921
21253
  }
20922
21254
  if (inlineImgCanvas) {
20923
21255
  this.canvasFactory.destroy(inlineImgCanvas);
@@ -20976,13 +21308,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
20976
21308
  if (!this.pendingClip) {
20977
21309
  this.compose(clipBox);
20978
21310
  }
20979
- const ctx = this.ctx;
21311
+ const ctx2 = this.ctx;
20980
21312
  if (this.pendingClip) {
20981
21313
  if (!isEmpty) {
20982
21314
  if (this.pendingClip === EO_CLIP) {
20983
- ctx.clip(path, "evenodd");
21315
+ ctx2.clip(path, "evenodd");
20984
21316
  } else {
20985
- ctx.clip(path);
21317
+ ctx2.clip(path);
20986
21318
  }
20987
21319
  }
20988
21320
  this.pendingClip = null;
@@ -21057,36 +21389,36 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
21057
21389
  }
21058
21390
  rescaleAndStroke(path, saveRestore) {
21059
21391
  const {
21060
- ctx,
21392
+ ctx: ctx2,
21061
21393
  current: {
21062
21394
  lineWidth
21063
21395
  }
21064
21396
  } = this;
21065
21397
  const [scaleX, scaleY] = this.getScaleForStroking();
21066
21398
  if (scaleX === scaleY) {
21067
- ctx.lineWidth = (lineWidth || 1) * scaleX;
21068
- ctx.stroke(path);
21399
+ ctx2.lineWidth = (lineWidth || 1) * scaleX;
21400
+ ctx2.stroke(path);
21069
21401
  return;
21070
21402
  }
21071
21403
  const SCALE_MATRIX = _CanvasGraphics.#SCALE_MATRIX ??= new DOMMatrix();
21072
- const dashes = ctx.getLineDash();
21404
+ const dashes = ctx2.getLineDash();
21073
21405
  if (saveRestore) {
21074
- ctx.save();
21406
+ ctx2.save();
21075
21407
  }
21076
- ctx.scale(scaleX, scaleY);
21408
+ ctx2.scale(scaleX, scaleY);
21077
21409
  SCALE_MATRIX.a = 1 / scaleX;
21078
21410
  SCALE_MATRIX.d = 1 / scaleY;
21079
21411
  const newPath = new Path2D();
21080
21412
  newPath.addPath(path, SCALE_MATRIX);
21081
21413
  if (dashes.length > 0) {
21082
21414
  const scale = Math.max(scaleX, scaleY);
21083
- ctx.setLineDash(dashes.map((x) => x / scale));
21084
- ctx.lineDashOffset /= scale;
21415
+ ctx2.setLineDash(dashes.map((x) => x / scale));
21416
+ ctx2.lineDashOffset /= scale;
21085
21417
  }
21086
- ctx.lineWidth = lineWidth || 1;
21087
- ctx.stroke(newPath);
21418
+ ctx2.lineWidth = lineWidth || 1;
21419
+ ctx2.stroke(newPath);
21088
21420
  if (saveRestore) {
21089
- ctx.restore();
21421
+ ctx2.restore();
21090
21422
  }
21091
21423
  }
21092
21424
  isContentVisible() {
@@ -22785,7 +23117,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
22785
23117
  const {
22786
23118
  div,
22787
23119
  properties,
22788
- ctx
23120
+ ctx: ctx2
22789
23121
  } = params;
22790
23122
  const {
22791
23123
  style
@@ -22798,10 +23130,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
22798
23130
  canvasWidth,
22799
23131
  fontSize
22800
23132
  } = properties;
22801
- _TextLayer.#ensureCtxFont(ctx, fontSize * this.#scale, fontFamily);
23133
+ _TextLayer.#ensureCtxFont(ctx2, fontSize * this.#scale, fontFamily);
22802
23134
  const {
22803
23135
  width
22804
- } = ctx.measureText(div.textContent);
23136
+ } = ctx2.measureText(div.textContent);
22805
23137
  if (width > 0) {
22806
23138
  style.setProperty("--scale-x", canvasWidth * this.#scale / width);
22807
23139
  }
@@ -22823,30 +23155,30 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
22823
23155
  this.#canvasContexts.clear();
22824
23156
  }
22825
23157
  static #getCtx(lang = null) {
22826
- let ctx = this.#canvasContexts.get(lang ||= "");
22827
- if (!ctx) {
23158
+ let ctx2 = this.#canvasContexts.get(lang ||= "");
23159
+ if (!ctx2) {
22828
23160
  const canvas = document.createElement("canvas");
22829
23161
  canvas.style.cssText = "position:absolute;top:0;left:0;width:0;height:0;display:none;letter-spacing:normal;word-spacing:normal";
22830
23162
  canvas.lang = lang;
22831
23163
  document.body.append(canvas);
22832
- ctx = canvas.getContext("2d", {
23164
+ ctx2 = canvas.getContext("2d", {
22833
23165
  alpha: false,
22834
23166
  willReadFrequently: true
22835
23167
  });
22836
- this.#canvasContexts.set(lang, ctx);
22837
- this.#canvasCtxFonts.set(ctx, {
23168
+ this.#canvasContexts.set(lang, ctx2);
23169
+ this.#canvasCtxFonts.set(ctx2, {
22838
23170
  size: 0,
22839
23171
  family: ""
22840
23172
  });
22841
23173
  }
22842
- return ctx;
23174
+ return ctx2;
22843
23175
  }
22844
- static #ensureCtxFont(ctx, size, family) {
22845
- const cached3 = this.#canvasCtxFonts.get(ctx);
23176
+ static #ensureCtxFont(ctx2, size, family) {
23177
+ const cached3 = this.#canvasCtxFonts.get(ctx2);
22846
23178
  if (size === cached3.size && family === cached3.family) {
22847
23179
  return;
22848
23180
  }
22849
- ctx.font = `${size}px ${family}`;
23181
+ ctx2.font = `${size}px ${family}`;
22850
23182
  cached3.size = size;
22851
23183
  cached3.family = family;
22852
23184
  }
@@ -22869,13 +23201,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
22869
23201
  if (cachedAscent) {
22870
23202
  return cachedAscent;
22871
23203
  }
22872
- const ctx = this.#getCtx(lang);
22873
- ctx.canvas.width = ctx.canvas.height = DEFAULT_FONT_SIZE;
22874
- this.#ensureCtxFont(ctx, DEFAULT_FONT_SIZE, fontFamily);
22875
- const metrics = ctx.measureText("");
23204
+ const ctx2 = this.#getCtx(lang);
23205
+ ctx2.canvas.width = ctx2.canvas.height = DEFAULT_FONT_SIZE;
23206
+ this.#ensureCtxFont(ctx2, DEFAULT_FONT_SIZE, fontFamily);
23207
+ const metrics = ctx2.measureText("");
22876
23208
  const ascent = metrics.fontBoundingBoxAscent;
22877
23209
  const descent = Math.abs(metrics.fontBoundingBoxDescent);
22878
- ctx.canvas.width = ctx.canvas.height = 0;
23210
+ ctx2.canvas.width = ctx2.canvas.height = 0;
22879
23211
  let ratio = 0.8;
22880
23212
  if (ascent) {
22881
23213
  ratio = ascent / (ascent + descent);
@@ -32615,8 +32947,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32615
32947
  newWidth = Math.ceil(prevWidth / 2);
32616
32948
  newHeight = Math.ceil(prevHeight / 2);
32617
32949
  const offscreen2 = new OffscreenCanvas(newWidth, newHeight);
32618
- const ctx2 = offscreen2.getContext("2d");
32619
- ctx2.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
32950
+ const ctx3 = offscreen2.getContext("2d");
32951
+ ctx3.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
32620
32952
  prevWidth = newWidth;
32621
32953
  prevHeight = newHeight;
32622
32954
  if (bitmap !== originalBitmap) {
@@ -32629,14 +32961,14 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32629
32961
  newHeight = Math.round(newHeight * ratio);
32630
32962
  }
32631
32963
  const offscreen = new OffscreenCanvas(newWidth, newHeight);
32632
- const ctx = offscreen.getContext("2d", {
32964
+ const ctx2 = offscreen.getContext("2d", {
32633
32965
  willReadFrequently: true
32634
32966
  });
32635
- ctx.fillStyle = "white";
32636
- ctx.fillRect(0, 0, newWidth, newHeight);
32637
- ctx.filter = "grayscale(1)";
32638
- ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight);
32639
- const grayImage = ctx.getImageData(0, 0, newWidth, newHeight).data;
32967
+ ctx2.fillStyle = "white";
32968
+ ctx2.fillRect(0, 0, newWidth, newHeight);
32969
+ ctx2.filter = "grayscale(1)";
32970
+ ctx2.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight);
32971
+ const grayImage = ctx2.getImageData(0, 0, newWidth, newHeight).data;
32640
32972
  const uint8Buf = this.#toUint8(grayImage);
32641
32973
  return [uint8Buf, newWidth, newHeight];
32642
32974
  }
@@ -32646,11 +32978,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32646
32978
  fontWeight
32647
32979
  }, pageWidth, pageHeight, rotation, innerMargin) {
32648
32980
  let canvas = new OffscreenCanvas(1, 1);
32649
- let ctx = canvas.getContext("2d", {
32981
+ let ctx2 = canvas.getContext("2d", {
32650
32982
  alpha: false
32651
32983
  });
32652
32984
  const fontSize = 200;
32653
- const font = ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
32985
+ const font = ctx2.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
32654
32986
  const {
32655
32987
  actualBoundingBoxLeft,
32656
32988
  actualBoundingBoxRight,
@@ -32659,22 +32991,22 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32659
32991
  fontBoundingBoxAscent,
32660
32992
  fontBoundingBoxDescent,
32661
32993
  width
32662
- } = ctx.measureText(text);
32994
+ } = ctx2.measureText(text);
32663
32995
  const SCALE = 1.5;
32664
32996
  const canvasWidth = Math.ceil(Math.max(Math.abs(actualBoundingBoxLeft) + Math.abs(actualBoundingBoxRight) || 0, width) * SCALE);
32665
32997
  const canvasHeight = Math.ceil(Math.max(Math.abs(actualBoundingBoxAscent) + Math.abs(actualBoundingBoxDescent) || fontSize, Math.abs(fontBoundingBoxAscent) + Math.abs(fontBoundingBoxDescent) || fontSize) * SCALE);
32666
32998
  canvas = new OffscreenCanvas(canvasWidth, canvasHeight);
32667
- ctx = canvas.getContext("2d", {
32999
+ ctx2 = canvas.getContext("2d", {
32668
33000
  alpha: true,
32669
33001
  willReadFrequently: true
32670
33002
  });
32671
- ctx.font = font;
32672
- ctx.filter = "grayscale(1)";
32673
- ctx.fillStyle = "white";
32674
- ctx.fillRect(0, 0, canvasWidth, canvasHeight);
32675
- ctx.fillStyle = "black";
32676
- ctx.fillText(text, canvasWidth * (SCALE - 1) / 2, canvasHeight * (3 - SCALE) / 2);
32677
- const uint8Buf = this.#toUint8(ctx.getImageData(0, 0, canvasWidth, canvasHeight).data);
33003
+ ctx2.font = font;
33004
+ ctx2.filter = "grayscale(1)";
33005
+ ctx2.fillStyle = "white";
33006
+ ctx2.fillRect(0, 0, canvasWidth, canvasHeight);
33007
+ ctx2.fillStyle = "black";
33008
+ ctx2.fillText(text, canvasWidth * (SCALE - 1) / 2, canvasHeight * (3 - SCALE) / 2);
33009
+ const uint8Buf = this.#toUint8(ctx2.getImageData(0, 0, canvasWidth, canvasHeight).data);
32678
33010
  const histogram = this.#getHistogram(uint8Buf);
32679
33011
  const threshold = this.#guessThreshold(histogram);
32680
33012
  const contourList = this.#findContours(uint8Buf, canvasWidth, canvasHeight, threshold);
@@ -33640,8 +33972,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33640
33972
  if (!this.#isSvg) {
33641
33973
  bitmap = this.#scaleBitmap(scaledWidth, scaledHeight);
33642
33974
  }
33643
- const ctx = canvas.getContext("2d");
33644
- ctx.filter = this._uiManager.hcmFilter;
33975
+ const ctx2 = canvas.getContext("2d");
33976
+ ctx2.filter = this._uiManager.hcmFilter;
33645
33977
  let white = "white", black = "#cfcfd8";
33646
33978
  if (this._uiManager.hcmFilter !== "none") {
33647
33979
  black = "black";
@@ -33659,9 +33991,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33659
33991
  patternCtx.fillStyle = black;
33660
33992
  patternCtx.fillRect(0, 0, boxDimWidth, boxDimHeight);
33661
33993
  patternCtx.fillRect(boxDimWidth, boxDimHeight, boxDimWidth, boxDimHeight);
33662
- ctx.fillStyle = ctx.createPattern(pattern, "repeat");
33663
- ctx.fillRect(0, 0, scaledWidth, scaledHeight);
33664
- ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight);
33994
+ ctx2.fillStyle = ctx2.createPattern(pattern, "repeat");
33995
+ ctx2.fillRect(0, 0, scaledWidth, scaledHeight);
33996
+ ctx2.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight);
33665
33997
  }
33666
33998
  let imageData = null;
33667
33999
  if (createImageData) {
@@ -33716,8 +34048,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33716
34048
  newHeight = Math.ceil(newHeight / 2);
33717
34049
  }
33718
34050
  const offscreen = new OffscreenCanvas(newWidth, newHeight);
33719
- const ctx = offscreen.getContext("2d");
33720
- ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
34051
+ const ctx2 = offscreen.getContext("2d");
34052
+ ctx2.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
33721
34053
  bitmap = offscreen.transferToImageBitmap();
33722
34054
  }
33723
34055
  return bitmap;
@@ -33738,9 +34070,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33738
34070
  canvas.width = scaledWidth;
33739
34071
  canvas.height = scaledHeight;
33740
34072
  const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(scaledWidth, scaledHeight);
33741
- const ctx = canvas.getContext("2d");
33742
- ctx.filter = this._uiManager.hcmFilter;
33743
- ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight);
34073
+ const ctx2 = canvas.getContext("2d");
34074
+ ctx2.filter = this._uiManager.hcmFilter;
34075
+ ctx2.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight);
33744
34076
  }
33745
34077
  #serializeBitmap(toUrl) {
33746
34078
  if (toUrl) {
@@ -33755,8 +34087,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33755
34087
  width: canvas.width,
33756
34088
  height: canvas.height
33757
34089
  } = this.#bitmap);
33758
- const ctx = canvas.getContext("2d");
33759
- ctx.drawImage(this.#bitmap, 0, 0);
34090
+ const ctx2 = canvas.getContext("2d");
34091
+ ctx2.drawImage(this.#bitmap, 0, 0);
33760
34092
  return canvas.toDataURL();
33761
34093
  }
33762
34094
  if (this.#isSvg) {
@@ -33764,8 +34096,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
33764
34096
  const width = Math.round(this.width * pageWidth * PixelsPerInch.PDF_TO_CSS_UNITS);
33765
34097
  const height = Math.round(this.height * pageHeight * PixelsPerInch.PDF_TO_CSS_UNITS);
33766
34098
  const offscreen = new OffscreenCanvas(width, height);
33767
- const ctx = offscreen.getContext("2d");
33768
- ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height);
34099
+ const ctx2 = offscreen.getContext("2d");
34100
+ ctx2.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height);
33769
34101
  return offscreen.transferToImageBitmap();
33770
34102
  }
33771
34103
  return structuredClone(this.#bitmap);
@@ -35264,10 +35596,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
35264
35596
  const imageY2 = Math.floor((y1 + height / this.#pageHeight) * pageCanvas.height);
35265
35597
  imgElement.width = imageX2 - imageX1;
35266
35598
  imgElement.height = imageY2 - imageY1;
35267
- const ctx = imgElement.getContext("2d");
35268
- ctx.setTransform(...inverseTransform);
35269
- ctx.translate(-imageX1, -imageY1);
35270
- ctx.drawImage(pageCanvas, 0, 0);
35599
+ const ctx2 = imgElement.getContext("2d");
35600
+ ctx2.setTransform(...inverseTransform);
35601
+ ctx2.translate(-imageX1, -imageY1);
35602
+ ctx2.drawImage(pageCanvas, 0, 0);
35271
35603
  });
35272
35604
  return container;
35273
35605
  }
@@ -35385,7 +35717,7 @@ async function pdfjs() {
35385
35717
  return pdfjsPromise;
35386
35718
  }
35387
35719
  async function extractPdfText(pdfPath, { maxChars = DEFAULT_MAX_CHARS, force = false } = {}) {
35388
- const hit = cache.get(pdfPath);
35720
+ const hit = cache2.get(pdfPath);
35389
35721
  if (!force && hit && Date.now() - hit.at < CACHE_TTL_MS) return hit.text;
35390
35722
  const data = new Uint8Array(await readFile4(pdfPath));
35391
35723
  const getDocument2 = (await pdfjs()).getDocument;
@@ -35407,16 +35739,16 @@ async function extractPdfText(pdfPath, { maxChars = DEFAULT_MAX_CHARS, force = f
35407
35739
  doc.cleanup?.();
35408
35740
  }
35409
35741
  const text = chunks.join("\n").trim();
35410
- cache.set(pdfPath, { text, at: Date.now() });
35742
+ cache2.set(pdfPath, { text, at: Date.now() });
35411
35743
  return text;
35412
35744
  }
35413
- var DEFAULT_MAX_CHARS, CACHE_TTL_MS, cache, pdfjsPromise;
35745
+ var DEFAULT_MAX_CHARS, CACHE_TTL_MS, cache2, pdfjsPromise;
35414
35746
  var init_pdf_text = __esm({
35415
35747
  "src/node/pdf-text.js"() {
35416
35748
  init_log();
35417
35749
  DEFAULT_MAX_CHARS = 12e4;
35418
35750
  CACHE_TTL_MS = 10 * 60 * 1e3;
35419
- cache = /* @__PURE__ */ new Map();
35751
+ cache2 = /* @__PURE__ */ new Map();
35420
35752
  pdfjsPromise = null;
35421
35753
  }
35422
35754
  });
@@ -35425,7 +35757,8 @@ var init_pdf_text = __esm({
35425
35757
  var ai_exports = {};
35426
35758
  __export(ai_exports, {
35427
35759
  askAi: () => askAi,
35428
- buildPrompt: () => buildPrompt
35760
+ buildPrompt: () => buildPrompt,
35761
+ sendFigure: () => sendFigure
35429
35762
  });
35430
35763
  function buildPrompt({ title, action, question = "", selection = "", text = "" }) {
35431
35764
  const head = `\u3010\u6587\u732E\u52A9\u624B \xB7 ${title}\u3011`;
@@ -35472,7 +35805,7 @@ ${text}
35472
35805
  """`;
35473
35806
  }
35474
35807
  }
35475
- async function askAi(ctx, { key, action = "ask", question = "", selection = "", sessionId = null } = {}) {
35808
+ async function askAi(ctx2, { key, action = "ask", question = "", selection = "", sessionId = null } = {}) {
35476
35809
  const entry = await getItem(String(key ?? ""));
35477
35810
  if (!entry) throw Object.assign(new Error("\u6761\u76EE\u4E0D\u5B58\u5728"), { code: "not_found" });
35478
35811
  if (!["translate", "explain", "summarize", "tldr", "ask"].includes(action)) action = "ask";
@@ -35480,7 +35813,7 @@ async function askAi(ctx, { key, action = "ask", question = "", selection = "",
35480
35813
  if (!sid) {
35481
35814
  throw Object.assign(new Error("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u5BF9\u8BDD\uFF0C\u8BF7\u5148\u5F00\u59CB\u4E00\u4E2A\u5BF9\u8BDD\u518D\u8BD5"), { code: "no_session" });
35482
35815
  }
35483
- const agent = ctx?.agents?.get?.(sid);
35816
+ const agent = ctx2?.agents?.get?.(sid);
35484
35817
  if (!agent || typeof agent.steer !== "function") {
35485
35818
  throw Object.assign(new Error("\u5F53\u524D\u5BF9\u8BDD\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5"), { code: "no_session" });
35486
35819
  }
@@ -35517,6 +35850,38 @@ async function askAi(ctx, { key, action = "ask", question = "", selection = "",
35517
35850
  log(`ai ask steered (${action}) into session ${sid}`);
35518
35851
  return { ok: true, sessionId: sid, action };
35519
35852
  }
35853
+ async function sendFigure(ctx2, { png, caption = "", title = "\u793A\u610F\u56FE", sessionId = null } = {}) {
35854
+ if (!png || !png.length) throw Object.assign(new Error("\u6CA1\u6709\u56FE\u7247\u6570\u636E"), { code: "no_image" });
35855
+ const sid = sessionId && String(sessionId) || recentSession();
35856
+ if (!sid) throw Object.assign(new Error("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u5BF9\u8BDD\uFF0C\u8BF7\u5148\u5F00\u59CB\u4E00\u4E2A\u5BF9\u8BDD\u518D\u8BD5"), { code: "no_session" });
35857
+ const agent = ctx2?.agents?.get?.(sid);
35858
+ if (!agent || typeof agent.steer !== "function") {
35859
+ throw Object.assign(new Error("\u5F53\u524D\u5BF9\u8BDD\u4E0D\u53EF\u7528\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5"), { code: "no_session" });
35860
+ }
35861
+ if (!ctx2?.attachments?.saveImages) {
35862
+ throw Object.assign(new Error("\u5BBF\u4E3B\u4E0D\u652F\u6301\u56FE\u7247\u9644\u4EF6"), { code: "no_attachments" });
35863
+ }
35864
+ let bytes = png;
35865
+ const limits = ctx2.attachments.imageLimits ?? {};
35866
+ const maxBytes = limits.maxImageBytes ?? 5 * 1024 * 1024;
35867
+ if (bytes.length > maxBytes) {
35868
+ throw Object.assign(new Error(`\u56FE\u7247\u8D85\u8FC7\u5BBF\u4E3B\u5927\u5C0F\u9650\u5236\uFF08${bytes.length} > ${maxBytes} \u5B57\u8282\uFF09`), { code: "too_large" });
35869
+ }
35870
+ const mediaType = limits.mediaTypes?.length ? limits.mediaTypes.includes("image/png") ? "image/png" : limits.mediaTypes[0] : "image/png";
35871
+ const [ref] = await ctx2.attachments.saveImages([{ data: new Uint8Array(bytes), mediaType, name: title.slice(0, 60) }]);
35872
+ if (!ref) throw Object.assign(new Error("\u56FE\u7247\u9644\u4EF6\u521B\u5EFA\u5931\u8D25"), { code: "no_attachments" });
35873
+ const text = `\u3010\u6587\u732E\u52A9\u624B \xB7 ${title}\u3011
35874
+ ${caption || "\u6839\u636E\u6570\u636E\u751F\u6210\u7684\u793A\u610F\u56FE\u3002"}
35875
+ \uFF08\u56FE\u7531\u63D2\u4EF6\u6839\u636E\u539F\u59CB\u6570\u636E\u7ED8\u5236\uFF0C\u975E\u539F\u6587\u63D2\u56FE\uFF09`;
35876
+ try {
35877
+ const { createUserMessage } = await import("@deepseek-ai/dsh-llm");
35878
+ agent.steer(createUserMessage({ content: [{ type: "text", text }, { type: "image", attachment: ref }], source: { kind: "user" } }));
35879
+ } catch {
35880
+ agent.steer({ content: [{ type: "text", text }, { type: "image", attachment: ref }], source: { kind: "user" }, role: "user", id: `lit_fig_${Date.now()}` });
35881
+ }
35882
+ log(`figure steered into session ${sid}`);
35883
+ return { ok: true, sessionId: sid };
35884
+ }
35520
35885
  var FULLTEXT_ACTIONS, MAX_CONTEXT_CHARS;
35521
35886
  var init_ai = __esm({
35522
35887
  "src/node/ai.js"() {
@@ -35538,13 +35903,13 @@ __export(doctor_selfheal_exports, {
35538
35903
  pipeAvailable: () => pipeAvailable
35539
35904
  });
35540
35905
  import { createHash } from "node:crypto";
35541
- import { existsSync, readdirSync } from "node:fs";
35542
- import { join as join6 } from "node:path";
35543
- import { homedir as homedir3 } from "node:os";
35906
+ import { existsSync as existsSync2, readdirSync as readdirSync2 } from "node:fs";
35907
+ import { join as join8 } from "node:path";
35908
+ import { homedir as homedir4 } from "node:os";
35544
35909
  import { spawn } from "node:child_process";
35545
35910
  import net from "node:net";
35546
35911
  function doctorRoot() {
35547
- return process.env.DSH_DOCTOR_HOME?.trim() || join6(homedir3(), ".dsh-doctor");
35912
+ return process.env.DSH_DOCTOR_HOME?.trim() || join8(homedir4(), ".dsh-doctor");
35548
35913
  }
35549
35914
  function doctorPipeName(root = doctorRoot()) {
35550
35915
  const hash = createHash("sha256").update(root).digest("hex").slice(0, 16);
@@ -35569,16 +35934,16 @@ function pipeAvailable(pipe, timeoutMs = 1500) {
35569
35934
  });
35570
35935
  }
35571
35936
  function findDoctorCli() {
35572
- const profilesDir = join6(homedir3(), ".dsh", "profiles");
35937
+ const profilesDir = join8(homedir4(), ".dsh", "profiles");
35573
35938
  let entries = [];
35574
35939
  try {
35575
- entries = readdirSync(profilesDir);
35940
+ entries = readdirSync2(profilesDir);
35576
35941
  } catch {
35577
35942
  return "";
35578
35943
  }
35579
35944
  for (const name2 of entries) {
35580
- const candidate = join6(profilesDir, name2, "node_modules", "@linxin666", "dsh-doctor", "lib", "cli.mjs");
35581
- if (existsSync(candidate)) return candidate;
35945
+ const candidate = join8(profilesDir, name2, "node_modules", "@linxin666", "dsh-doctor", "lib", "cli.mjs");
35946
+ if (existsSync2(candidate)) return candidate;
35582
35947
  }
35583
35948
  return "";
35584
35949
  }
@@ -35769,7 +36134,7 @@ async function readJsonBody2(req) {
35769
36134
  const { readJsonBody: read } = await Promise.resolve().then(() => (init_http(), http_exports));
35770
36135
  return read(req);
35771
36136
  }
35772
- async function handler(req, res, ctx) {
36137
+ async function handler(req, res, ctx2) {
35773
36138
  if (!isLoopbackRequest(req)) {
35774
36139
  writeJson(res, 403, { error: "forbidden: loopback-only", code: "forbidden" });
35775
36140
  return;
@@ -35787,6 +36152,29 @@ async function handler(req, res, ctx) {
35787
36152
  await handleEvents(req, res);
35788
36153
  return;
35789
36154
  }
36155
+ if (head === "activate" && activation) {
36156
+ activation.activate("panel-open");
36157
+ writeJson(res, 200, { ok: true, active: true });
36158
+ return;
36159
+ }
36160
+ if (head === "pyenv" && methodOk(req, "GET")) {
36161
+ const { detectPythons: detectPythons2, figureInterpreter: figureInterpreter2, venvExists: venvExists2, venvDir: venvDir2 } = await Promise.resolve().then(() => (init_pyenv(), pyenv_exports));
36162
+ const pythons = await detectPythons2();
36163
+ const fig = await figureInterpreter2();
36164
+ writeJson(res, 200, {
36165
+ pythons,
36166
+ venv: { exists: venvExists2(), dir: venvDir2() },
36167
+ figure: fig ? { exe: fig.exe, version: fig.version, source: fig.source, hasMatplotlib: fig.hasMatplotlib } : null
36168
+ });
36169
+ return;
36170
+ }
36171
+ if (head === "install-deps" && methodOk(req, "POST")) {
36172
+ const { installFigureDeps: installFigureDeps2 } = await Promise.resolve().then(() => (init_pyenv(), pyenv_exports));
36173
+ const logs = [];
36174
+ const result = await installFigureDeps2((m) => logs.push(m));
36175
+ writeJson(res, result.ok ? 200 : 500, { ...result, logs });
36176
+ return;
36177
+ }
35790
36178
  if (head === "state" && methodOk(req, "GET")) {
35791
36179
  await handleState(res);
35792
36180
  return;
@@ -35936,6 +36324,11 @@ async function handler(req, res, ctx) {
35936
36324
  const url = new URL(req.url ?? "/", "http://127.0.0.1");
35937
36325
  const filename = url.searchParams.get("filename") || "dropped.pdf";
35938
36326
  const buffer = await readRawBody(req, 128 * 1024 * 1024);
36327
+ if (buffer.length > 4 && buffer.subarray(0, 2).toString("latin1") === "PK" && /\.pptx$/i.test(filename)) {
36328
+ const item2 = await importDroppedCourseware(buffer, { filename });
36329
+ writeJson(res, 200, { item: item2 });
36330
+ return;
36331
+ }
35939
36332
  const item = await importDroppedPdf(buffer, { filename });
35940
36333
  writeJson(res, 200, { item });
35941
36334
  return;
@@ -35999,7 +36392,7 @@ async function handler(req, res, ctx) {
35999
36392
  if (sub === "ask" && methodOk(req, "POST")) {
36000
36393
  const body = await readJsonBody2(req);
36001
36394
  const { askAi: askAi2 } = await Promise.resolve().then(() => (init_ai(), ai_exports));
36002
- const result = await askAi2(ctx, {
36395
+ const result = await askAi2(ctx2, {
36003
36396
  key: String(body?.key ?? ""),
36004
36397
  action: String(body?.action ?? "ask"),
36005
36398
  question: String(body?.question ?? ""),
@@ -36022,11 +36415,11 @@ async function handler(req, res, ctx) {
36022
36415
  else res.end();
36023
36416
  }
36024
36417
  }
36025
- function registerRoutes(ctx) {
36026
- const disposers = [ctx.webServer.register({ kind: "prefix", path: PREFIX2, handler: (req, res) => handler(req, res, ctx) })];
36027
- if (typeof ctx.on === "function") {
36418
+ function registerRoutes(ctx2, { activation: activation2 } = {}) {
36419
+ const disposers = [ctx2.webServer.register({ kind: "prefix", path: PREFIX2, handler: (req, res) => handler(req, res, ctx2) })];
36420
+ if (typeof ctx2.on === "function") {
36028
36421
  disposers.push(
36029
- ctx.on("session/event", (session) => {
36422
+ ctx2.on("session/event", (session) => {
36030
36423
  noteSession(session);
36031
36424
  })
36032
36425
  );
@@ -36038,76 +36431,472 @@ function registerRoutes(ctx) {
36038
36431
  // src/node/tools.js
36039
36432
  init_pipeline();
36040
36433
  init_db();
36434
+
36435
+ // src/node/store/search.js
36436
+ function tokenize(text) {
36437
+ const s = String(text ?? "").toLowerCase();
36438
+ const out = /* @__PURE__ */ new Set();
36439
+ for (const m of s.matchAll(/[a-z0-9][a-z0-9._-]*/g)) {
36440
+ if (m[0].length >= 2) out.add(m[0]);
36441
+ }
36442
+ const cjkRuns = s.match(/[\u3400-\u4dbf\u4e00-\u9fff\u3040-\u30ff]+/g) ?? [];
36443
+ for (const run2 of cjkRuns) {
36444
+ for (let i = 0; i < run2.length; i += 1) {
36445
+ out.add(run2[i]);
36446
+ if (i + 1 < run2.length) out.add(run2.slice(i, i + 2));
36447
+ }
36448
+ }
36449
+ return [...out];
36450
+ }
36451
+ var WEIGHTS = {
36452
+ title: 3,
36453
+ authors: 2,
36454
+ container: 2,
36455
+ abstract: 1,
36456
+ tags: 1
36457
+ };
36458
+ function fieldText(item, field) {
36459
+ const rec = item.record ?? {};
36460
+ switch (field) {
36461
+ case "title":
36462
+ return rec.title ?? item.title ?? item.display ?? "";
36463
+ case "authors":
36464
+ return (rec.authors ?? []).map((a) => `${a.lastName ?? ""} ${a.firstName ?? ""}`.trim()).join(" ");
36465
+ case "container":
36466
+ return rec.container ?? "";
36467
+ case "abstract":
36468
+ return rec.abstract ?? "";
36469
+ case "tags":
36470
+ return (item.tags ?? []).join(" ");
36471
+ default:
36472
+ return "";
36473
+ }
36474
+ }
36475
+ function searchItems2(items, query, { limit = 20 } = {}) {
36476
+ const terms = tokenize(query);
36477
+ if (!terms.length) return [];
36478
+ const scored = [];
36479
+ for (const item of items) {
36480
+ let score = 0;
36481
+ let matched = false;
36482
+ for (const [field, weight] of Object.entries(WEIGHTS)) {
36483
+ const text = String(fieldText(item, field)).toLowerCase();
36484
+ if (!text) continue;
36485
+ for (const t of terms) {
36486
+ if (text.includes(t)) {
36487
+ matched = true;
36488
+ score += weight * (t.length >= 2 ? 2 : 1);
36489
+ }
36490
+ }
36491
+ }
36492
+ if (!matched) continue;
36493
+ const rec = item.record ?? {};
36494
+ scored.push({
36495
+ key: item.key,
36496
+ title: rec.title ?? item.title ?? item.display ?? "(\u65E0\u6807\u9898)",
36497
+ authors: (rec.authors ?? []).slice(0, 3).map((a) => a.lastName ?? "").filter(Boolean).join(", "),
36498
+ year: rec.year ?? item.year ?? null,
36499
+ container: rec.container ?? "",
36500
+ snippet: snippetFor(item, terms),
36501
+ state: item.state ?? "",
36502
+ score
36503
+ });
36504
+ }
36505
+ scored.sort((a, b) => b.score !== a.score ? b.score - a.score : a.key < b.key ? -1 : 1);
36506
+ return scored.slice(0, Math.max(1, Math.min(limit, 50)));
36507
+ }
36508
+ function snippetFor(item, terms) {
36509
+ const rec = item.record ?? {};
36510
+ const source = rec.abstract || rec.title || "";
36511
+ if (!source) return "";
36512
+ const lower = source.toLowerCase();
36513
+ let at = -1;
36514
+ for (const t of terms) {
36515
+ const i = lower.indexOf(t);
36516
+ if (i >= 0 && (at < 0 || i < at)) at = i;
36517
+ }
36518
+ if (at < 0) return String(source).slice(0, 160);
36519
+ const start = Math.max(0, at - 60);
36520
+ const head = start > 0 ? "\u2026" : "";
36521
+ return head + String(source).slice(start, start + 220).trim();
36522
+ }
36523
+
36524
+ // src/node/tools.js
36041
36525
  init_normalize();
36042
36526
  init_log();
36527
+ import { writeFile as writeFile5, mkdtemp, readFile as readFile6, rm } from "node:fs/promises";
36528
+ import { tmpdir } from "node:os";
36529
+ import { join as join7 } from "node:path";
36043
36530
  function textResult(value) {
36044
36531
  return {
36045
36532
  schema: { type: "string" },
36046
36533
  render: (_args, v) => [{ type: "text", text: String(v) }]
36047
36534
  };
36048
36535
  }
36049
- function registerTools(ctx) {
36050
- const disposers = [];
36051
- disposers.push(
36052
- ctx.tools.register({
36053
- name: "zotero_lookup",
36054
- description: "\u4ECE\u6587\u672C\u6216\u6807\u8BC6\u7B26\u4E2D\u8BC6\u522B\u5B66\u672F\u6587\u732E\uFF08DOI\u3001arXiv ID\u3001PMID\u3001ISBN\u3001\u6807\u9898\uFF09\uFF0C\u89E3\u6790\u5143\u6570\u636E\u5E76\u751F\u6210\u4FA7\u7A97\u6761\u76EE\u3002\u5F53\u4F60\u68C0\u7D22\u6216\u5F15\u7528\u6587\u732E\u5E76\u5E0C\u671B\u7528\u6237\u80FD\u5728\u4FA7\u8FB9\u680F\u9884\u89C8/\u4FDD\u5B58\u5168\u6587\u65F6\u8C03\u7528\u3002",
36055
- parameters: {
36056
- type: "object",
36057
- properties: {
36058
- text: { type: "string", description: "\u5305\u542B\u6587\u732E\u6807\u8BC6\u7B26\u6216\u5F15\u7528\u6587\u672C\u7684\u7247\u6BB5" },
36059
- resolve: { type: "string", description: "\u662F\u5426\u7ACB\u5373\u8054\u7F51\u89E3\u6790\u5143\u6570\u636E\uFF0C\u9ED8\u8BA4 yes" }
36060
- },
36061
- required: []
36062
- },
36063
- output: textResult(),
36064
- timeoutMs: 12e4,
36065
- async execute(args) {
36066
- const text = String(args?.text ?? "");
36067
- if (!text.trim()) return "\u6CA1\u6709\u63D0\u4F9B\u6587\u672C\u3002";
36068
- const created = await scanText(text);
36069
- if (!created.length) return "\u672A\u8BC6\u522B\u5230\u65B0\u7684\u6587\u732E\u6761\u76EE\uFF08\u53EF\u80FD\u5DF2\u5B58\u5728\u4E8E\u4FA7\u7A97\uFF09\u3002";
36070
- const wantResolve = String(args?.resolve ?? "yes").toLowerCase() !== "no";
36071
- if (wantResolve) {
36072
- await Promise.all(created.map((i) => resolveItem(i.key).catch((e) => warn("resolve failed", e.message))));
36073
- }
36074
- const items = await Promise.all(created.map((i) => getItem(i.key)));
36075
- const lines = items.filter(Boolean).map((i) => `- ${i.record?.title || i.display} [${i.key}]`);
36076
- return `\u5DF2\u52A0\u5165\u4FA7\u7A97 ${items.length} \u6761\uFF1A
36077
- ${lines.join("\n")}`;
36536
+ function toolDefs() {
36537
+ return [lookupTool(), searchTool(), getTool(), citeTool(), noteTool(), statusTool(), saveTool(), figureTool()];
36538
+ }
36539
+ function registerTools(ctx2) {
36540
+ let mounted = [];
36541
+ return {
36542
+ mount() {
36543
+ if (mounted.length) return;
36544
+ mounted = toolDefs().map((def) => {
36545
+ try {
36546
+ return ctx2.tools.register(def);
36547
+ } catch (e) {
36548
+ warn("tool registration failed:", def.name, e?.message);
36549
+ return null;
36550
+ }
36551
+ });
36552
+ log(`tools mounted: ${toolDefs().map((d) => d.name).join(", ")}`);
36553
+ },
36554
+ unmount() {
36555
+ if (!mounted.length) return;
36556
+ for (const dispose of mounted) {
36557
+ try {
36558
+ dispose?.();
36559
+ } catch (e) {
36560
+ warn("tool dispose failed:", e?.message);
36561
+ }
36078
36562
  }
36079
- })
36080
- );
36081
- disposers.push(
36082
- ctx.tools.register({
36083
- name: "zotero_save",
36084
- description: "\u628A\u4FA7\u7A97\u4E2D\u5DF2\u8BC6\u522B\u7684\u6587\u732E\u4FDD\u5B58\u5230\u672C\u5730 Zotero \u5E93\u6216\u5BFC\u51FA\u76EE\u5F55\uFF08\u4F1A\u81EA\u52A8\u4E0B\u8F7D\u5168\u6587 PDF\uFF09\u3002",
36085
- parameters: {
36086
- type: "object",
36087
- properties: {
36088
- key: { type: "string", description: "\u6761\u76EE key\uFF08\u6765\u81EA zotero_lookup \u7684\u8FD4\u56DE\uFF09" },
36089
- mode: { type: "string", description: "\u4FDD\u5B58\u65B9\u5F0F\uFF1Azotero \u6216 dir\uFF0C\u7F3A\u7701\u7528\u914D\u7F6E\u503C" },
36090
- tags: { type: "string", description: "\u9017\u53F7\u5206\u9694\u7684\u6807\u7B7E" }
36563
+ mounted = [];
36564
+ log("tools unmounted");
36565
+ },
36566
+ isMounted: () => mounted.length > 0,
36567
+ dispose() {
36568
+ this.unmount();
36569
+ }
36570
+ };
36571
+ }
36572
+ function formatHit(h) {
36573
+ const bits = [h.title];
36574
+ if (h.authors) bits.push(h.authors);
36575
+ if (h.year) bits.push(String(h.year));
36576
+ if (h.container) bits.push(h.container);
36577
+ const line = bits.join(" | ") + ` [key=${h.key}]`;
36578
+ return h.snippet ? `${line}
36579
+ ${h.snippet.slice(0, 160)}` : line;
36580
+ }
36581
+ var NEXT_STEP = "\n[\u4E0B\u4E00\u6B65] literature_get(key=\u2026) \u770B\u8BE6\u60C5 \xB7 literature_cite \u751F\u6210\u5F15\u7528 \xB7 literature_search \u7EE7\u7EED\u68C0\u7D22";
36582
+ function lookupTool() {
36583
+ return {
36584
+ name: "literature_lookup",
36585
+ description: "\u4ECE\u6587\u672C\u6216\u6807\u8BC6\u7B26\u4E2D\u8BC6\u522B\u5B66\u672F\u6587\u732E\uFF08DOI\u3001arXiv ID\u3001PMID\u3001ISBN\u3001\u6807\u9898\uFF09\uFF0C\u89E3\u6790\u5143\u6570\u636E\u5E76\u751F\u6210\u4FA7\u7A97\u6761\u76EE\u3002\u5F53\u4F60\u68C0\u7D22\u6216\u5F15\u7528\u6587\u732E\u5E76\u5E0C\u671B\u7528\u6237\u80FD\u5728\u4FA7\u8FB9\u680F\u9884\u89C8/\u4FDD\u5B58\u5168\u6587\u65F6\u8C03\u7528\u3002",
36586
+ parameters: {
36587
+ type: "object",
36588
+ properties: {
36589
+ text: { type: "string", description: "\u5305\u542B\u6587\u732E\u6807\u8BC6\u7B26\u6216\u5F15\u7528\u6587\u672C\u7684\u7247\u6BB5" },
36590
+ resolve: { type: "string", description: "\u662F\u5426\u7ACB\u5373\u8054\u7F51\u89E3\u6790\u5143\u6570\u636E\uFF0C\u9ED8\u8BA4 yes" }
36591
+ },
36592
+ required: []
36593
+ },
36594
+ output: textResult(),
36595
+ timeoutMs: 12e4,
36596
+ async execute(args) {
36597
+ const text = String(args?.text ?? "");
36598
+ if (!text.trim()) return "\u6CA1\u6709\u63D0\u4F9B\u6587\u672C\u3002";
36599
+ const created = await scanText(text);
36600
+ if (!created.length) return "\u672A\u8BC6\u522B\u5230\u65B0\u7684\u6587\u732E\u6761\u76EE\uFF08\u53EF\u80FD\u5DF2\u5B58\u5728\u4E8E\u4FA7\u7A97\uFF09\u3002";
36601
+ const wantResolve = String(args?.resolve ?? "yes").toLowerCase() !== "no";
36602
+ if (wantResolve) {
36603
+ await Promise.all(created.map((i) => resolveItem(i.key).catch((e) => warn("resolve failed", e.message))));
36604
+ }
36605
+ const items = await Promise.all(created.map((i) => getItem(i.key)));
36606
+ const lines = items.filter(Boolean).map((i) => `- ${i.record?.title || i.display} [key=${i.key}]`);
36607
+ return `\u5DF2\u52A0\u5165\u4FA7\u7A97 ${items.length} \u6761\uFF1A
36608
+ ${lines.join("\n")}${NEXT_STEP}`;
36609
+ }
36610
+ };
36611
+ }
36612
+ function searchTool() {
36613
+ return {
36614
+ name: "literature_search",
36615
+ description: "\u5728\u7528\u6237\u7684\u6587\u732E\u5E93\u4E2D\u68C0\u7D22\u5DF2\u4FDD\u5B58\u7684\u6587\u732E\uFF08\u6807\u9898/\u4F5C\u8005/\u671F\u520A/\u6458\u8981/\u6807\u7B7E\u7684\u5173\u952E\u8BCD\u5339\u914D\uFF09\u3002\u5F53\u7528\u6237\u95EE\u300C\u6211\u4E4B\u524D\u5B58\u7684\u90A3\u7BC7\u300D\u300C\u6211\u5E93\u91CC\u6709\u6CA1\u6709\u8BB2 X \u7684\u300D\u300C\u6709\u4EC0\u4E48\u6587\u732E\u53EF\u4EE5\u7528\u300D\u65F6\u8C03\u7528\u3002\u8FD4\u56DE\u7CBE\u7B80\u6761\u76EE\uFF0C\u9700\u8981\u5B8C\u6574\u4FE1\u606F\u518D\u7528 literature_get\u3002",
36616
+ parameters: {
36617
+ type: "object",
36618
+ properties: {
36619
+ query: { type: "string", description: "\u68C0\u7D22\u8BCD\uFF1A\u4E3B\u9898\u3001\u6807\u9898\u7247\u6BB5\u3001\u4F5C\u8005\u59D3\u6C0F\u6216\u671F\u520A\u540D" },
36620
+ limit: { type: "number", description: "\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4 8\uFF0C\u6700\u5927 20" }
36621
+ },
36622
+ required: ["query"]
36623
+ },
36624
+ output: textResult(),
36625
+ timeoutMs: 15e3,
36626
+ async execute(args) {
36627
+ const query = String(args?.query ?? "").trim();
36628
+ if (!query) return "\u7F3A\u5C11\u68C0\u7D22\u8BCD\u3002";
36629
+ const limit = Math.max(1, Math.min(Number(args?.limit) || 8, 20));
36630
+ const items = await listItems();
36631
+ const hits = searchItems2(items, query, { limit });
36632
+ if (!hits.length) return `\u672A\u5728\u5E93\u4E2D\u627E\u5230\u4E0E\u300C${query}\u300D\u5339\u914D\u7684\u6761\u76EE\u3002\u53EF\u5148\u7528 literature_lookup \u6DFB\u52A0\uFF0C\u6216\u6362\u66F4\u5BBD\u6CDB\u7684\u68C0\u7D22\u8BCD\u3002`;
36633
+ return `\u547D\u4E2D ${hits.length} \u6761\uFF1A
36634
+ ${hits.map((h) => `- ${formatHit(h)}`).join("\n")}${NEXT_STEP}`;
36635
+ }
36636
+ };
36637
+ }
36638
+ function getTool() {
36639
+ return {
36640
+ name: "literature_get",
36641
+ description: "\u6309 key \u83B7\u53D6\u6761\u76EE\u7684\u5B8C\u6574\u4FE1\u606F\uFF1A\u5143\u6570\u636E\u3001\u6458\u8981\u3001\u6279\u6CE8\u4E0E\u7B14\u8BB0\u3002\u4EC5\u5728 literature_search \u8FD4\u56DE\u8FC7\u8BE5 key \u65F6\u4F7F\u7528\u2014\u2014\u4E0D\u8981\u51ED\u731C\u6D4B\u7F16\u9020 key\u3002",
36642
+ parameters: {
36643
+ type: "object",
36644
+ properties: {
36645
+ key: { type: "string", description: "\u6761\u76EE key" },
36646
+ includeAnnotations: { type: "boolean", description: "\u662F\u5426\u5305\u542B\u6279\u6CE8\uFF0C\u9ED8\u8BA4 true" }
36647
+ },
36648
+ required: ["key"]
36649
+ },
36650
+ output: textResult(),
36651
+ timeoutMs: 15e3,
36652
+ async execute(args) {
36653
+ const key = String(args?.key ?? "");
36654
+ if (!key) return "\u7F3A\u5C11\u6761\u76EE key\u3002";
36655
+ const item = await getItem(key);
36656
+ if (!item) return `\u672A\u627E\u5230\u6761\u76EE ${key}\u3002\u8BF7\u5148\u7528 literature_search \u83B7\u53D6\u6B63\u786E\u7684 key\u3002`;
36657
+ const rec = item.record ?? {};
36658
+ const lines = [
36659
+ `\u6807\u9898\uFF1A${rec.title ?? item.title ?? item.display ?? "(\u65E0\u6807\u9898)"}`,
36660
+ `\u4F5C\u8005\uFF1A${(rec.authors ?? []).map((a) => `${a.lastName ?? ""} ${a.firstName ?? ""}`.trim()).filter(Boolean).join("; ") || "\u2014"}`,
36661
+ `\u5E74\u4EFD\uFF1A${rec.year ?? "\u2014"}`,
36662
+ `\u671F\u520A/\u4F1A\u8BAE\uFF1A${rec.container ?? "\u2014"}`,
36663
+ `DOI\uFF1A${rec.doi ?? "\u2014"}`,
36664
+ `\u72B6\u6001\uFF1A${item.state ?? "\u2014"}${item.pdf ? "\uFF08\u5DF2\u6709\u5168\u6587\uFF09" : "\uFF08\u65E0\u5168\u6587\uFF09"}`
36665
+ ];
36666
+ if (rec.abstract) lines.push(`\u6458\u8981\uFF1A${String(rec.abstract).slice(0, 600)}`);
36667
+ if (String(args?.includeAnnotations ?? true) !== "false") {
36668
+ const anns = await getAnnotations(key);
36669
+ if (anns.length) {
36670
+ const shown = anns.slice(0, 50);
36671
+ lines.push(`\u6279\u6CE8\uFF08${anns.length} \u6761${anns.length > shown.length ? `\uFF0C\u5C55\u793A\u524D ${shown.length} \u6761` : ""}\uFF09\uFF1A`);
36672
+ for (const a of shown) lines.push(` - p.${a.pageIndex ?? "?"} ${String(a.text ?? "").slice(0, 120)}${a.note ? ` \uFF5C \u7B14\u8BB0\uFF1A${String(a.note).slice(0, 120)}` : ""}`);
36673
+ }
36674
+ }
36675
+ return lines.join("\n") + "\n[\u4E0B\u4E00\u6B65] literature_cite \u751F\u6210\u5F15\u7528 \xB7 literature_note \u8BB0\u5F55\u5173\u7CFB";
36676
+ }
36677
+ };
36678
+ }
36679
+ function citeTool() {
36680
+ return {
36681
+ name: "literature_cite",
36682
+ description: "\u751F\u6210\u89C4\u8303\u5316\u7684\u5F15\u7528\u6587\u672C\uFF08APA 7 / GB/T 7714 / MLA 9 / Chicago 17 / BibTeX\uFF09\uFF0C\u652F\u6301\u53C2\u8003\u6587\u732E\u6761\u76EE\u3001\u6587\u5185\u5F15\u7528\u4E0E\u5E26\u9875\u7801\u7684\u76F4\u63A5\u5F15\u7528\u3002\u5199\u4F5C\u4E2D\u9700\u8981\u5F15\u7528\u6587\u732E\u65F6\u76F4\u63A5\u8C03\u7528\uFF0C\u4E0D\u8981\u624B\u5DE5\u62FC\u88C5\u4F5C\u8005\u4E0E\u5E74\u4EFD\u3002",
36683
+ parameters: {
36684
+ type: "object",
36685
+ properties: {
36686
+ key: { type: "string", description: "\u6761\u76EE key" },
36687
+ style: { type: "string", description: "apa | gb | mla | chicago | bibtex\uFF0C\u9ED8\u8BA4 apa" },
36688
+ mode: { type: "string", description: "reference\uFF08\u9ED8\u8BA4\uFF09| intext | direct" },
36689
+ pages: { type: "string", description: "\u76F4\u63A5\u5F15\u7528\u7684\u9875\u7801\uFF0C\u5982 12 \u6216 12-15" }
36690
+ },
36691
+ required: ["key"]
36692
+ },
36693
+ output: textResult(),
36694
+ timeoutMs: 15e3,
36695
+ async execute(args) {
36696
+ const key = String(args?.key ?? "");
36697
+ if (!key) return "\u7F3A\u5C11\u6761\u76EE key\u3002";
36698
+ const item = await getItem(key);
36699
+ if (!item?.record) return `\u6761\u76EE ${key} \u7F3A\u5C11\u5143\u6570\u636E\uFF0C\u65E0\u6CD5\u751F\u6210\u5F15\u7528\u3002\u8BF7\u5148\u7528 literature_lookup \u89E3\u6790\u5143\u6570\u636E\u3002`;
36700
+ const { citeDetailed: citeDetailed2 } = await Promise.resolve().then(() => (init_cite(), cite_exports));
36701
+ const d = citeDetailed2(item.record, {
36702
+ style: args?.style ?? "apa",
36703
+ mode: args?.mode ?? "reference",
36704
+ pages: args?.pages
36705
+ });
36706
+ return `${d.text}
36707
+ \uFF08${d.style} \xB7 ${d.mode}\uFF09
36708
+ [\u4E0B\u4E00\u6B65] literature_verify \u6838\u9A8C\u5F15\u7528\u771F\u5B9E\u6027 \xB7 literature_note \u8BB0\u5F55\u5B83\u548C\u5F53\u524D\u5199\u4F5C\u7684\u5173\u7CFB`;
36709
+ }
36710
+ };
36711
+ }
36712
+ function noteTool() {
36713
+ return {
36714
+ name: "literature_note",
36715
+ description: "\u628A\u4E00\u6761\u7B14\u8BB0\u5199\u56DE\u6587\u732E\u6761\u76EE\uFF1A\u8FD9\u7BC7\u6587\u732E\u4E0E\u7528\u6237\u5F53\u524D\u5199\u4F5C/\u7814\u7A76\u7684\u5173\u7CFB\u3001\u53EF\u7528\u8BBA\u70B9\u3001\u5F85\u9A8C\u8BC1\u4E4B\u5904\u3002\u4F1A\u8FFD\u52A0\u4FDD\u5B58\uFF0C\u4E0B\u6B21\u68C0\u7D22\u8BE5\u6761\u76EE\u65F6\u80FD\u88AB\u627E\u56DE\u3002",
36716
+ parameters: {
36717
+ type: "object",
36718
+ properties: {
36719
+ key: { type: "string", description: "\u6761\u76EE key" },
36720
+ note: { type: "string", description: "\u8981\u8BB0\u5F55\u7684\u7B14\u8BB0\u5185\u5BB9" }
36721
+ },
36722
+ required: ["key", "note"]
36723
+ },
36724
+ output: textResult(),
36725
+ timeoutMs: 15e3,
36726
+ async execute(args) {
36727
+ const key = String(args?.key ?? "");
36728
+ const note = String(args?.note ?? "").trim();
36729
+ if (!key) return "\u7F3A\u5C11\u6761\u76EE key\u3002";
36730
+ if (!note) return "\u7B14\u8BB0\u5185\u5BB9\u4E3A\u7A7A\uFF0C\u672A\u5199\u5165\u3002";
36731
+ const item = await getItem(key);
36732
+ if (!item) return `\u672A\u627E\u5230\u6761\u76EE ${key}\u3002`;
36733
+ const notes = Array.isArray(item.notes) ? item.notes : [];
36734
+ if (notes.some((n) => (typeof n === "string" ? n : n.text) === note)) return "\u8BE5\u7B14\u8BB0\u5DF2\u5B58\u5728\uFF0C\u672A\u91CD\u590D\u5199\u5165\u3002";
36735
+ const entry = { text: note, at: (/* @__PURE__ */ new Date()).toISOString() };
36736
+ await patchItem(key, { notes: [...notes, entry] });
36737
+ return `\u5DF2\u8BB0\u5F55\u5230\u6761\u76EE ${key}\uFF08\u5171 ${notes.length + 1} \u6761\u7B14\u8BB0\uFF09\u3002`;
36738
+ }
36739
+ };
36740
+ }
36741
+ function statusTool() {
36742
+ return {
36743
+ name: "literature_status",
36744
+ description: "\u67E5\u770B\u6587\u732E\u5E93\u7684\u5F53\u524D\u72B6\u6001\uFF1A\u6761\u76EE\u603B\u6570\u3001\u5404\u72B6\u6001\u5206\u5E03\u3001\u6700\u8FD1\u6DFB\u52A0\u7684\u6761\u76EE\u3001\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u3002\u5728\u5F00\u59CB\u6587\u732E\u5DE5\u4F5C\u524D\u4E86\u89E3\u5E93\u91CC\u6709\u4EC0\u4E48\u65F6\u8C03\u7528\u3002",
36745
+ parameters: { type: "object", properties: {}, required: [] },
36746
+ output: textResult(),
36747
+ timeoutMs: 15e3,
36748
+ async execute() {
36749
+ const items = await listItems();
36750
+ const byState = {};
36751
+ for (const i of items) {
36752
+ const s = i.state ?? "unknown";
36753
+ byState[s] = (byState[s] ?? 0) + 1;
36754
+ }
36755
+ const recent = [...items].sort((a, b) => Number(b.createdAt ?? 0) - Number(a.createdAt ?? 0)).slice(0, 5).map((i) => `- ${i.record?.title ?? i.title ?? i.display ?? "(\u65E0\u6807\u9898)"} [key=${i.key}]`);
36756
+ const running = (await listTasks()).filter((t) => t.status === "running");
36757
+ return [
36758
+ `\u6761\u76EE\u603B\u6570\uFF1A${items.length}`,
36759
+ `\u72B6\u6001\u5206\u5E03\uFF1A${Object.entries(byState).map(([k, v]) => `${k}=${v}`).join(", ") || "\u2014"}`,
36760
+ running.length ? `\u8FDB\u884C\u4E2D\u4EFB\u52A1\uFF1A${running.map((t) => `${t.key}(${t.progress ?? 0}%)`).join(", ")}` : "\u8FDB\u884C\u4E2D\u4EFB\u52A1\uFF1A\u65E0",
36761
+ recent.length ? `\u6700\u8FD1\u6DFB\u52A0\uFF1A
36762
+ ${recent.join("\n")}` : "\u5E93\u662F\u7A7A\u7684\u3002"
36763
+ ].join("\n") + NEXT_STEP;
36764
+ }
36765
+ };
36766
+ }
36767
+ function figureTool() {
36768
+ const CHART_TYPES = /* @__PURE__ */ new Set(["bar", "line", "pie"]);
36769
+ return {
36770
+ name: "literature_figure",
36771
+ description: "\u6839\u636E\u8868\u683C\u6570\u636E\u7ED8\u5236\u793A\u610F\u56FE\u5E76\u63D2\u5165\u5F53\u524D\u5BF9\u8BDD\uFF08\u67F1\u72B6\u56FE/\u6298\u7EBF\u56FE/\u997C\u56FE\uFF09\u3002\u4EC5\u5728\u7528\u6237\u660E\u786E\u8981\u6C42\u300C\u753B\u4E2A\u56FE/\u53EF\u89C6\u5316/\u505A\u793A\u610F\u56FE\u300D\u65F6\u8C03\u7528\uFF1B\u4E0D\u8981\u5728\u6CA1\u6709\u6570\u636E\u4F9D\u636E\u65F6\u51ED\u7A7A\u7F16\u9020\u6570\u503C\u3002",
36772
+ parameters: {
36773
+ type: "object",
36774
+ properties: {
36775
+ title: { type: "string", description: "\u56FE\u8868\u6807\u9898\uFF08\u4E5F\u4F1A\u4F5C\u4E3A\u6D88\u606F\u6807\u9898\uFF09" },
36776
+ categories: { type: "array", items: { type: "string" }, description: '\u6A2A\u8F74\u7C7B\u522B\uFF0C\u5982 ["2023","2024","2025"]' },
36777
+ series: {
36778
+ type: "array",
36779
+ description: "\u6570\u636E\u7CFB\u5217\uFF0C\u6BCF\u9879 { name, values }\uFF0Cvalues \u4E0E categories \u7B49\u957F",
36780
+ items: {
36781
+ type: "object",
36782
+ properties: {
36783
+ name: { type: "string" },
36784
+ values: { type: "array", items: { type: "number" } }
36785
+ },
36786
+ required: ["name", "values"]
36787
+ }
36091
36788
  },
36092
- required: ["key"]
36789
+ chartType: { type: "string", description: "bar\uFF08\u9ED8\u8BA4\uFF09| line | pie" },
36790
+ caption: { type: "string", description: "\u56FE\u4E0B\u8BF4\u660E\u6587\u5B57" },
36791
+ key: { type: "string", description: "\u53EF\u9009\uFF1A\u6570\u636E\u6765\u6E90\u6761\u76EE key\uFF08\u4FBF\u4E8E\u6807\u6CE8\u51FA\u5904\uFF09" }
36093
36792
  },
36094
- output: textResult(),
36095
- timeoutMs: 3e5,
36096
- async execute(args) {
36097
- const key = String(args?.key ?? "");
36098
- if (!key) return "\u7F3A\u5C11\u6761\u76EE key\u3002";
36099
- const tags = String(args?.tags ?? "").split(",").map((t) => t.trim()).filter(Boolean);
36100
- const item = await saveItem(key, { mode: args?.mode, tags });
36101
- if (!item) return `\u627E\u4E0D\u5230\u6761\u76EE ${key}\u3002`;
36102
- if (item.state === "saved") {
36103
- return `\u5DF2\u4FDD\u5B58\uFF1A${shortLabel(item.record ?? {})}\uFF08${item.saveMode === "dir" ? item.export?.pdfPath : "Zotero \u5E93"}\uFF09`;
36104
- }
36105
- return `\u4FDD\u5B58\u5931\u8D25\uFF1A${item.error?.message ?? "\u672A\u77E5\u9519\u8BEF"}\uFF08${item.error?.code ?? "unknown"}\uFF09`;
36793
+ required: ["title", "categories", "series"]
36794
+ },
36795
+ output: textResult(),
36796
+ timeoutMs: 12e4,
36797
+ async execute(args, exec) {
36798
+ const title = String(args?.title ?? "").trim() || "\u793A\u610F\u56FE";
36799
+ const categories = Array.isArray(args?.categories) ? args.categories.map(String) : [];
36800
+ const series = Array.isArray(args?.series) ? args.series.map((s) => ({ name: String(s?.name ?? "series"), values: (Array.isArray(s?.values) ? s.values : []).map((v) => Number(v)) })).filter((s) => s.values.length) : [];
36801
+ const chartType = CHART_TYPES.has(args?.chartType) ? args.chartType : "bar";
36802
+ if (!categories.length || !series.length) return "\u7F3A\u5C11\u6570\u636E\uFF08categories \u6216 series \u4E3A\u7A7A\uFF09\u3002\u793A\u610F\u56FE\u9700\u8981\u771F\u5B9E\u6570\u636E\uFF0C\u4E0D\u80FD\u51ED\u7A7A\u7ED8\u5236\u3002";
36803
+ const { figureInterpreter: figureInterpreter2 } = await Promise.resolve().then(() => (init_pyenv(), pyenv_exports));
36804
+ const fig = await figureInterpreter2();
36805
+ if (!fig || !fig.hasMatplotlib) {
36806
+ return "\u793A\u610F\u56FE\u5F15\u64CE\u5C1A\u672A\u5C31\u7EEA\uFF1A\u672C\u673A\u7F3A\u5C11 Python + matplotlib\u3002\u8BF7\u5728\u4FA7\u7A97\u8BBE\u7F6E\u9875\u300C\u793A\u610F\u56FE\u5F15\u64CE\u300D\u4E2D\u70B9\u51FB\u300C\u5B89\u88C5\u4F9D\u8D56\u300D\u540E\u91CD\u8BD5\uFF1B\u671F\u95F4\u53EF\u4EE5\u8BA9\u6211\u8F93\u51FA\u6570\u636E\u8868\u683C\u4EE3\u66FF\u56FE\u8868\u3002";
36807
+ }
36808
+ const { mkdtemp: _mk, writeFile: _w, readFile: _r, rm: _rm } = { mkdtemp, writeFile: writeFile5, readFile: readFile6, rm };
36809
+ const dir = await mkdtemp(join7(tmpdir(), "lit-fig-"));
36810
+ const pyFile = join7(dir, "fig.py");
36811
+ const pngFile = join7(dir, "fig.png");
36812
+ const script = [
36813
+ "import matplotlib",
36814
+ "matplotlib.use('Agg')",
36815
+ "import matplotlib.pyplot as plt",
36816
+ // CJK glyphs are missing from matplotlib's default font (DejaVu Sans),
36817
+ // which turns Chinese labels into tofu boxes. Pick the first installed
36818
+ // CJK-capable font; degrade silently on non-CJK systems.
36819
+ "from matplotlib import font_manager",
36820
+ "_available = {f.name for f in font_manager.fontManager.ttflist}",
36821
+ "for _name in ['Microsoft YaHei', 'SimHei', 'PingFang SC', 'Noto Sans CJK SC', 'Source Han Sans SC', 'WenQuanYi Zen Hei']:",
36822
+ " if _name in _available:",
36823
+ " plt.rcParams['font.sans-serif'] = [_name]",
36824
+ " break",
36825
+ "plt.rcParams['axes.unicode_minus'] = False",
36826
+ `categories = ${JSON.stringify(categories)}`,
36827
+ `series = ${JSON.stringify(series)}`,
36828
+ `chart_type = ${JSON.stringify(chartType)}`,
36829
+ `title = ${JSON.stringify(title)}`,
36830
+ "fig, ax = plt.subplots(figsize=(7, 4.2), dpi=150)",
36831
+ "if chart_type == 'pie':",
36832
+ " vals = series[0]['values']",
36833
+ " ax.pie(vals, labels=categories, autopct='%1.1f%%', startangle=90)",
36834
+ " ax.axis('equal')",
36835
+ "elif chart_type == 'line':",
36836
+ " for s in series: ax.plot(categories, s['values'], marker='o', label=s['name'])",
36837
+ " ax.legend()",
36838
+ "else:",
36839
+ " import numpy as np",
36840
+ " x = np.arange(len(categories)); w = 0.8 / max(len(series), 1)",
36841
+ " for i, s in enumerate(series): ax.bar(x + i * w, s['values'], w, label=s['name'])",
36842
+ " ax.set_xticks(x + w * (len(series) - 1) / 2); ax.set_xticklabels(categories)",
36843
+ " ax.legend()",
36844
+ "ax.set_title(title)",
36845
+ "plt.tight_layout()",
36846
+ `plt.savefig(${JSON.stringify(pngFile)})`
36847
+ ].join("\n");
36848
+ await writeFile5(pyFile, script, "utf8");
36849
+ const { execFile: execFile2 } = await import("node:child_process");
36850
+ const run2 = () => new Promise((resolve6) => execFile2(fig.exe, [pyFile], { timeout: 6e4, windowsHide: true }, (err, stdout, stderr) => resolve6({ err, stdout, stderr })));
36851
+ const r = await run2();
36852
+ let png = null;
36853
+ try {
36854
+ png = await readFile6(pngFile);
36855
+ } catch {
36106
36856
  }
36107
- })
36108
- );
36109
- log("tools registered: zotero_lookup, zotero_save");
36110
- return disposers;
36857
+ await rm(dir, { recursive: true, force: true }).catch(() => {
36858
+ });
36859
+ if (!png) return "\u7ED8\u56FE\u5931\u8D25\uFF1A" + (r.stderr || r.stdout || "\u672A\u77E5\u9519\u8BEF").slice(0, 300);
36860
+ const { sendFigure: sendFigure2 } = await Promise.resolve().then(() => (init_ai(), ai_exports));
36861
+ const sourceNote = args?.key ? `\uFF08\u6570\u636E\u6765\u6E90\uFF1A\u6761\u76EE ${args.key}\uFF09` : "";
36862
+ try {
36863
+ await sendFigure2(ctx, { png, title, caption: `${args?.caption ?? ""}${sourceNote}`.trim(), sessionId: exec?.agent?.sessionId ?? null });
36864
+ return `\u793A\u610F\u56FE\u300C${title}\u300D\u5DF2\u751F\u6210\u5E76\u63D2\u5165\u5F53\u524D\u5BF9\u8BDD\u3002`;
36865
+ } catch (e) {
36866
+ if (e?.code === "no_session") return "\u793A\u610F\u56FE\u5DF2\u751F\u6210\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u5BF9\u8BDD\u53EF\u63D2\u5165\u3002\u8BF7\u5148\u6253\u5F00\u4E00\u4E2A\u5BF9\u8BDD\u518D\u8BA9\u6211\u753B\u56FE\u3002";
36867
+ return "\u56FE\u7247\u63D2\u5165\u5BF9\u8BDD\u5931\u8D25\uFF1A" + (e?.message ?? "\u672A\u77E5\u9519\u8BEF");
36868
+ }
36869
+ }
36870
+ };
36871
+ }
36872
+ function saveTool() {
36873
+ return {
36874
+ name: "literature_save",
36875
+ description: "\u628A\u4FA7\u7A97\u4E2D\u5DF2\u8BC6\u522B\u7684\u6587\u732E\u4FDD\u5B58\u5230\u672C\u5730\u6587\u732E\u5E93\u6216\u5BFC\u51FA\u76EE\u5F55\uFF08\u4F1A\u81EA\u52A8\u4E0B\u8F7D\u5168\u6587 PDF\uFF09\u3002",
36876
+ parameters: {
36877
+ type: "object",
36878
+ properties: {
36879
+ key: { type: "string", description: "\u6761\u76EE key\uFF08\u6765\u81EA literature_lookup \u6216 literature_search \u7684\u8FD4\u56DE\uFF09" },
36880
+ mode: { type: "string", description: "\u4FDD\u5B58\u65B9\u5F0F\uFF1Azotero \u6216 dir\uFF0C\u7F3A\u7701\u7528\u914D\u7F6E\u503C" },
36881
+ tags: { type: "string", description: "\u9017\u53F7\u5206\u9694\u7684\u6807\u7B7E" }
36882
+ },
36883
+ required: ["key"]
36884
+ },
36885
+ output: textResult(),
36886
+ timeoutMs: 3e5,
36887
+ async execute(args) {
36888
+ const key = String(args?.key ?? "");
36889
+ if (!key) return "\u7F3A\u5C11\u6761\u76EE key\u3002";
36890
+ const tags = String(args?.tags ?? "").split(",").map((t) => t.trim()).filter(Boolean);
36891
+ const item = await saveItem(key, { mode: args?.mode, tags });
36892
+ if (!item) return `\u627E\u4E0D\u5230\u6761\u76EE ${key}\u3002`;
36893
+ if (item.state === "saved") {
36894
+ return `\u5DF2\u4FDD\u5B58\uFF1A${shortLabel(item.record ?? {})}\uFF08${item.saveMode === "dir" ? item.export?.pdfPath : "\u672C\u5730\u6587\u732E\u5E93"}\uFF09
36895
+ [\u4E0B\u4E00\u6B65] literature_get \u67E5\u770B\u8BE6\u60C5 \xB7 literature_cite \u751F\u6210\u5F15\u7528`;
36896
+ }
36897
+ return `\u4FDD\u5B58\u5931\u8D25\uFF1A${item.error?.message ?? "\u672A\u77E5\u9519\u8BEF"}\uFF08${item.error?.code ?? "unknown"}\uFF09`;
36898
+ }
36899
+ };
36111
36900
  }
36112
36901
 
36113
36902
  // src/node/session-hook.js
@@ -36144,11 +36933,15 @@ function textFromSessionEvent(event) {
36144
36933
  }
36145
36934
  return "";
36146
36935
  }
36147
- function registerSessionHook(ctx) {
36936
+ function registerSessionHook(ctx2, { activation: activation2, detectIntent: detectIntent2 } = {}) {
36148
36937
  const disposers = [];
36149
36938
  disposers.push(
36150
- ctx.on("session/event", (session, event) => {
36939
+ ctx2.on("session/event", (session, event) => {
36151
36940
  const text = textFromSessionEvent(event);
36941
+ if (activation2 && detectIntent2 && event?.type === "user/message") {
36942
+ const verdict = detectIntent2(textFromSessionEvent(event));
36943
+ if (verdict.active) activation2.activate(verdict.reason);
36944
+ }
36152
36945
  if (!text || text.length < 20) return;
36153
36946
  if (!extractIdentifiers(text).length) return;
36154
36947
  checkConfig().then((config) => {
@@ -36170,26 +36963,184 @@ async function checkConfig() {
36170
36963
  return cachedConfig;
36171
36964
  }
36172
36965
 
36966
+ // src/node/activation.js
36967
+ var IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
36968
+ var STRONG = [
36969
+ "\u6587\u732E",
36970
+ "\u8BBA\u6587",
36971
+ "\u53C2\u8003\u6587\u732E",
36972
+ "\u5F15\u7528\u683C\u5F0F",
36973
+ "\u5F15\u6587",
36974
+ "\u7EFC\u8FF0",
36975
+ "\u5F00\u9898",
36976
+ "\u7EC4\u4F1A",
36977
+ "doi",
36978
+ "arxiv",
36979
+ "pmid",
36980
+ "isbn",
36981
+ "bibtex",
36982
+ "apa",
36983
+ "mla",
36984
+ "chicago",
36985
+ "gb/t 7714",
36986
+ "gbt7714",
36987
+ "abstract",
36988
+ "citation",
36989
+ "reference list",
36990
+ "related work",
36991
+ "literature review",
36992
+ "paper",
36993
+ "preprint",
36994
+ "thesis",
36995
+ " dissertation"
36996
+ ];
36997
+ var WEAK = ["\u641C\u96C6", "\u6536\u96C6", "\u68C0\u7D22", "\u67E5\u9605", "\u6574\u7406", "\u51C6\u5907", "\u8C03\u7814", "\u67E5\u4E00\u4E0B", "\u627E\u51E0\u7BC7", "search", "collect", "gather", "find some"];
36998
+ var ACADEMIC_COMPANION = [
36999
+ "\u6587\u732E",
37000
+ "\u8BBA\u6587",
37001
+ "\u8D44\u6599",
37002
+ "\u7814\u7A76",
37003
+ "\u5B66\u672F",
37004
+ "\u671F\u520A",
37005
+ "\u4F1A\u8BAE",
37006
+ "\u5B9E\u9A8C",
37007
+ "\u65B9\u6CD5",
37008
+ "\u7ED3\u8BBA",
37009
+ "research",
37010
+ "study",
37011
+ "studies",
37012
+ "academic",
37013
+ "journal",
37014
+ "conference",
37015
+ "survey"
37016
+ ];
37017
+ var NEGATIVE = [
37018
+ "\u62A5\u9519",
37019
+ "\u5D29\u6E83",
37020
+ "\u7F16\u8BD1",
37021
+ "\u6784\u5EFA",
37022
+ "\u90E8\u7F72",
37023
+ "\u5355\u5143\u6D4B\u8BD5",
37024
+ "commit",
37025
+ "merge",
37026
+ "\u91CD\u6784",
37027
+ "debug",
37028
+ "stack trace",
37029
+ "segfault",
37030
+ "npm ",
37031
+ "pnpm ",
37032
+ "yarn ",
37033
+ "git ",
37034
+ "build failed",
37035
+ "regression"
37036
+ ];
37037
+ function normalize(text) {
37038
+ return String(text ?? "").toLowerCase();
37039
+ }
37040
+ function hitCount(text, list) {
37041
+ let n = 0;
37042
+ for (const w of list) if (text.includes(w)) n += 1;
37043
+ return n;
37044
+ }
37045
+ function detectIntent(text) {
37046
+ const t = normalize(text);
37047
+ if (!t || t.length < 6) return { active: false, score: 0, reason: "empty" };
37048
+ const strong = hitCount(t, STRONG);
37049
+ if (strong > 0) {
37050
+ const neg = hitCount(t, NEGATIVE);
37051
+ if (neg > 0 && neg >= strong) return { active: false, score: 0, reason: "coding-context" };
37052
+ return { active: true, score: 1, reason: "strong-signal" };
37053
+ }
37054
+ const weak = hitCount(t, WEAK);
37055
+ if (weak > 0 && hitCount(t, ACADEMIC_COMPANION) > 0) {
37056
+ return { active: true, score: 0.6, reason: "weak+academic" };
37057
+ }
37058
+ return { active: false, score: 0, reason: "no-signal" };
37059
+ }
37060
+ function createActivation({ idleTimeoutMs = IDLE_TIMEOUT_MS } = {}) {
37061
+ const listeners = /* @__PURE__ */ new Set();
37062
+ let active = false;
37063
+ let reason = "";
37064
+ let timer = null;
37065
+ let lastActivityAt = 0;
37066
+ function emit2(next) {
37067
+ active = next;
37068
+ for (const fn of listeners) {
37069
+ try {
37070
+ fn({ active, reason });
37071
+ } catch {
37072
+ }
37073
+ }
37074
+ }
37075
+ function clearTimer() {
37076
+ if (timer) {
37077
+ clearTimeout(timer);
37078
+ timer = null;
37079
+ }
37080
+ }
37081
+ function armIdle() {
37082
+ clearTimer();
37083
+ timer = setTimeout(() => {
37084
+ if (!active) return;
37085
+ reason = "idle-timeout";
37086
+ emit2(false);
37087
+ }, idleTimeoutMs);
37088
+ timer.unref?.();
37089
+ }
37090
+ return {
37091
+ /** Mount the tools. Safe to call repeatedly — it just refreshes the idle timer. */
37092
+ activate(why = "manual") {
37093
+ lastActivityAt = Date.now();
37094
+ if (!active) {
37095
+ reason = why;
37096
+ emit2(true);
37097
+ }
37098
+ armIdle();
37099
+ },
37100
+ deactivate(why = "manual") {
37101
+ clearTimer();
37102
+ if (active) {
37103
+ reason = why;
37104
+ emit2(false);
37105
+ }
37106
+ },
37107
+ onTransition(fn) {
37108
+ listeners.add(fn);
37109
+ return () => listeners.delete(fn);
37110
+ },
37111
+ isActive: () => active,
37112
+ reason: () => reason,
37113
+ lastActivityAt: () => lastActivityAt,
37114
+ dispose() {
37115
+ clearTimer();
37116
+ listeners.clear();
37117
+ }
37118
+ };
37119
+ }
37120
+
36173
37121
  // src/node/index.js
36174
37122
  init_log();
36175
37123
  var name = "dsh-literature-pre";
36176
37124
  var inject = ["webServer", "tools"];
36177
- function apply(ctx, config) {
37125
+ function apply(ctx2, config) {
36178
37126
  const onUncaught = (e) => error("uncaught exception:", e?.stack ?? e);
36179
37127
  const onUnhandled = (e) => error("unhandled rejection:", e?.stack ?? e);
36180
37128
  process.on("uncaughtException", onUncaught);
36181
37129
  process.on("unhandledRejection", onUnhandled);
36182
37130
  const disposers = [];
36183
- ctx.effect(() => {
37131
+ ctx2.effect(() => {
36184
37132
  ensureDirs().then(() => init()).catch((e) => error("storage init failed:", e.message));
36185
37133
  }, "dsh-literature: storage");
36186
37134
  const ready = (async () => {
36187
37135
  await ensureDirs();
36188
37136
  await init();
36189
- disposers.push(...registerRoutes(ctx));
36190
- disposers.push(...registerTools(ctx));
37137
+ const activation2 = createActivation();
37138
+ const toolsCtl = registerTools(ctx2);
37139
+ disposers.push(activation2.onTransition(({ active }) => active ? toolsCtl.mount() : toolsCtl.unmount()));
37140
+ disposers.push(() => activation2.dispose());
37141
+ disposers.push(...registerRoutes(ctx2, { activation: activation2 }));
36191
37142
  try {
36192
- disposers.push(...registerSessionHook(ctx));
37143
+ disposers.push(...registerSessionHook(ctx2, { activation: activation2, detectIntent }));
36193
37144
  } catch (e) {
36194
37145
  error("session hook unavailable:", e.message);
36195
37146
  }