pdfjs-reader-core 0.5.7 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +98 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -31
- package/dist/index.d.ts +14 -31
- package/dist/index.js +80 -147
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9191,7 +9191,7 @@ var init_DocumentContainer = __esm({
|
|
|
9191
9191
|
const containerRef = (0, import_react37.useRef)(null);
|
|
9192
9192
|
const documentRef = (0, import_react37.useRef)(null);
|
|
9193
9193
|
const baseScaleRef = (0, import_react37.useRef)(scale);
|
|
9194
|
-
const
|
|
9194
|
+
const isTouchDevice = useIsTouchDevice();
|
|
9195
9195
|
const documentLoadingState = useViewerStore((s) => s.documentLoadingState);
|
|
9196
9196
|
const { selection, clearSelection, copySelection } = useTextSelection();
|
|
9197
9197
|
const handlePinchZoom = (0, import_react37.useCallback)(
|
|
@@ -9222,7 +9222,7 @@ var init_DocumentContainer = __esm({
|
|
|
9222
9222
|
onSwipeLeft: handleSwipeLeft,
|
|
9223
9223
|
onSwipeRight: handleSwipeRight,
|
|
9224
9224
|
onDoubleTap: handleDoubleTap,
|
|
9225
|
-
enabled: enableTouchGestures &&
|
|
9225
|
+
enabled: enableTouchGestures && isTouchDevice,
|
|
9226
9226
|
swipeThreshold: 50,
|
|
9227
9227
|
doubleTapInterval: 300
|
|
9228
9228
|
});
|
|
@@ -9466,7 +9466,7 @@ var init_VirtualizedDocumentContainer = __esm({
|
|
|
9466
9466
|
const pageCache = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
|
|
9467
9467
|
const pageDimensionsCache = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
|
|
9468
9468
|
const baseScaleRef = (0, import_react38.useRef)(scale);
|
|
9469
|
-
const
|
|
9469
|
+
const isTouchDevice = useIsTouchDevice();
|
|
9470
9470
|
const [visiblePages, setVisiblePages] = (0, import_react38.useState)([1]);
|
|
9471
9471
|
const [pageObjects, setPageObjects] = (0, import_react38.useState)(/* @__PURE__ */ new Map());
|
|
9472
9472
|
const [totalHeight, setTotalHeight] = (0, import_react38.useState)(0);
|
|
@@ -9669,7 +9669,7 @@ var init_VirtualizedDocumentContainer = __esm({
|
|
|
9669
9669
|
onPinchZoom: handlePinchZoom,
|
|
9670
9670
|
onSwipeLeft: nextPage,
|
|
9671
9671
|
onSwipeRight: previousPage,
|
|
9672
|
-
enabled: enableTouchGestures &&
|
|
9672
|
+
enabled: enableTouchGestures && isTouchDevice
|
|
9673
9673
|
});
|
|
9674
9674
|
const setContainerRef = (0, import_react38.useCallback)(
|
|
9675
9675
|
(element) => {
|
|
@@ -9877,7 +9877,7 @@ var init_DualPageContainer = __esm({
|
|
|
9877
9877
|
const containerRef = (0, import_react40.useRef)(null);
|
|
9878
9878
|
const documentRef = (0, import_react40.useRef)(null);
|
|
9879
9879
|
const baseScaleRef = (0, import_react40.useRef)(scale);
|
|
9880
|
-
const
|
|
9880
|
+
const isTouchDevice = useIsTouchDevice();
|
|
9881
9881
|
const [leftPage, setLeftPage] = (0, import_react40.useState)(null);
|
|
9882
9882
|
const [rightPage, setRightPage] = (0, import_react40.useState)(null);
|
|
9883
9883
|
const [isLoading, setIsLoading] = (0, import_react40.useState)(false);
|
|
@@ -10020,7 +10020,7 @@ var init_DualPageContainer = __esm({
|
|
|
10020
10020
|
onPinchZoom: handlePinchZoom,
|
|
10021
10021
|
onSwipeLeft: goToNextSpread,
|
|
10022
10022
|
onSwipeRight: goToPreviousSpread,
|
|
10023
|
-
enabled: enableTouchGestures &&
|
|
10023
|
+
enabled: enableTouchGestures && isTouchDevice
|
|
10024
10024
|
});
|
|
10025
10025
|
const setContainerRef = (0, import_react40.useCallback)(
|
|
10026
10026
|
(element) => {
|
|
@@ -13268,7 +13268,7 @@ function withErrorBoundary({ component, ...props }) {
|
|
|
13268
13268
|
init_PDFLoadingScreen2();
|
|
13269
13269
|
|
|
13270
13270
|
// src/components/TutorMode/TutorModeContainer.tsx
|
|
13271
|
-
var
|
|
13271
|
+
var import_react57 = require("react");
|
|
13272
13272
|
var import_zustand2 = require("zustand");
|
|
13273
13273
|
init_PDFPage2();
|
|
13274
13274
|
init_hooks();
|
|
@@ -13559,13 +13559,13 @@ function AnimatedUnderline({ bbox, action }) {
|
|
|
13559
13559
|
const blotX = x2 + 4;
|
|
13560
13560
|
const blotY = y;
|
|
13561
13561
|
const strokeWeight = action.style === "wavy" ? 3 : 4;
|
|
13562
|
-
const
|
|
13563
|
-
const
|
|
13564
|
-
const
|
|
13565
|
-
const svgX = x1 -
|
|
13566
|
-
const svgY = y -
|
|
13567
|
-
const svgW = x2 - x1 + 2 *
|
|
13568
|
-
const svgH =
|
|
13562
|
+
const uxPad = 8;
|
|
13563
|
+
const uAbove = 8;
|
|
13564
|
+
const uBelow = 24;
|
|
13565
|
+
const svgX = x1 - uxPad;
|
|
13566
|
+
const svgY = y - uAbove;
|
|
13567
|
+
const svgW = x2 - x1 + 2 * uxPad;
|
|
13568
|
+
const svgH = uAbove + uBelow;
|
|
13569
13569
|
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
13570
13570
|
"svg",
|
|
13571
13571
|
{
|
|
@@ -13640,7 +13640,12 @@ function AnimatedUnderline({ bbox, action }) {
|
|
|
13640
13640
|
// src/components/TutorMode/AnimatedHighlight.tsx
|
|
13641
13641
|
var import_framer_motion4 = require("framer-motion");
|
|
13642
13642
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
13643
|
-
var
|
|
13643
|
+
var DEFAULT_HUE = "rgb(230, 180, 34)";
|
|
13644
|
+
var WASH_OPACITY = 0.28;
|
|
13645
|
+
function stripAlpha(color) {
|
|
13646
|
+
const m = color.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
|
|
13647
|
+
return m ? `rgb(${m[1]}, ${m[2]}, ${m[3]})` : color;
|
|
13648
|
+
}
|
|
13644
13649
|
function AnimatedHighlight({ bbox, action }) {
|
|
13645
13650
|
const [x1, y1, x2, y2] = bbox;
|
|
13646
13651
|
const h = Math.max(1, y2 - y1);
|
|
@@ -13649,7 +13654,7 @@ function AnimatedHighlight({ bbox, action }) {
|
|
|
13649
13654
|
const yBot = y2 + bleed;
|
|
13650
13655
|
const duration = action.draw_duration_ms / 1e3;
|
|
13651
13656
|
const isDefaultColour = !action.color || action.color === "rgba(250, 204, 21, 0.35)" || action.color === "rgba(250,204,21,0.35)";
|
|
13652
|
-
const fill = isDefaultColour ?
|
|
13657
|
+
const fill = stripAlpha(isDefaultColour ? DEFAULT_HUE : action.color);
|
|
13653
13658
|
const taper = Math.min(6, h * 0.2);
|
|
13654
13659
|
const pathD = `
|
|
13655
13660
|
M ${x1 - 2} ${yTop + taper}
|
|
@@ -13662,11 +13667,11 @@ function AnimatedHighlight({ bbox, action }) {
|
|
|
13662
13667
|
L ${x1 - 2} ${yBot - taper}
|
|
13663
13668
|
Z
|
|
13664
13669
|
`;
|
|
13665
|
-
const
|
|
13666
|
-
const svgX = x1 -
|
|
13667
|
-
const svgY = yTop -
|
|
13668
|
-
const svgW = x2 - x1 + 2 *
|
|
13669
|
-
const svgH = yBot - yTop + 2 *
|
|
13670
|
+
const svgPad = 8;
|
|
13671
|
+
const svgX = x1 - svgPad;
|
|
13672
|
+
const svgY = yTop - svgPad;
|
|
13673
|
+
const svgW = x2 - x1 + 2 * svgPad;
|
|
13674
|
+
const svgH = yBot - yTop + 2 * svgPad;
|
|
13670
13675
|
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
13671
13676
|
"svg",
|
|
13672
13677
|
{
|
|
@@ -13686,6 +13691,7 @@ function AnimatedHighlight({ bbox, action }) {
|
|
|
13686
13691
|
{
|
|
13687
13692
|
d: pathD,
|
|
13688
13693
|
fill,
|
|
13694
|
+
fillOpacity: WASH_OPACITY,
|
|
13689
13695
|
initial: { clipPath: `inset(0 100% 0 0)` },
|
|
13690
13696
|
animate: { clipPath: `inset(0 0% 0 0)` },
|
|
13691
13697
|
exit: { opacity: 0 },
|
|
@@ -13697,7 +13703,6 @@ function AnimatedHighlight({ bbox, action }) {
|
|
|
13697
13703
|
}
|
|
13698
13704
|
|
|
13699
13705
|
// src/components/TutorMode/PulseOverlay.tsx
|
|
13700
|
-
var import_react56 = require("react");
|
|
13701
13706
|
var import_framer_motion5 = require("framer-motion");
|
|
13702
13707
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
13703
13708
|
var INTENSITY = {
|
|
@@ -13706,7 +13711,6 @@ var INTENSITY = {
|
|
|
13706
13711
|
strong: { bracketLen: 26, strokeWeight: 3, coreOpacity: 1, ringScale: 1.22 }
|
|
13707
13712
|
};
|
|
13708
13713
|
function PulseOverlay({ bbox, action }) {
|
|
13709
|
-
const pulseId = (0, import_react56.useId)();
|
|
13710
13714
|
const [x1, y1, x2, y2] = bbox;
|
|
13711
13715
|
const w = Math.max(1, x2 - x1);
|
|
13712
13716
|
const h = Math.max(1, y2 - y1);
|
|
@@ -13715,13 +13719,13 @@ function PulseOverlay({ bbox, action }) {
|
|
|
13715
13719
|
const spec = INTENSITY[action.intensity] ?? INTENSITY.normal;
|
|
13716
13720
|
const L = Math.min(spec.bracketLen, Math.min(w, h) / 2.5);
|
|
13717
13721
|
const PAD = 6;
|
|
13722
|
+
const ringExtentX = (w / 2 + PAD) * spec.ringScale - w / 2;
|
|
13723
|
+
const ringExtentY = (h / 2 + PAD) * spec.ringScale - h / 2;
|
|
13724
|
+
const glowExtentX = (w / 2 + 10) * spec.ringScale - w / 2 + 24;
|
|
13725
|
+
const glowExtentY = (h / 2 + 10) * spec.ringScale - h / 2 + 24;
|
|
13718
13726
|
const bracketExtent = PAD + L + 8;
|
|
13719
|
-
const
|
|
13720
|
-
const
|
|
13721
|
-
const glowExtentV = (h / 2 + 24) * spec.ringScale - h / 2;
|
|
13722
|
-
const ringExtentV = (h / 2 + PAD) * spec.ringScale - h / 2;
|
|
13723
|
-
const svgPadX = Math.ceil(Math.max(bracketExtent, glowExtent, ringExtent) + 4);
|
|
13724
|
-
const svgPadY = Math.ceil(Math.max(bracketExtent, glowExtentV, ringExtentV) + 4);
|
|
13727
|
+
const svgPadX = Math.ceil(Math.max(40, ringExtentX, glowExtentX, bracketExtent));
|
|
13728
|
+
const svgPadY = Math.ceil(Math.max(40, ringExtentY, glowExtentY, bracketExtent));
|
|
13725
13729
|
const svgX = x1 - svgPadX;
|
|
13726
13730
|
const svgY = y1 - svgPadY;
|
|
13727
13731
|
const svgW = w + 2 * svgPadX;
|
|
@@ -13741,22 +13745,18 @@ function PulseOverlay({ bbox, action }) {
|
|
|
13741
13745
|
},
|
|
13742
13746
|
"data-role": "pulse",
|
|
13743
13747
|
children: [
|
|
13744
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("radialGradient", { id: `${pulseId}-glow`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
13745
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("stop", { offset: "0%", stopColor: ACCENT_GLOW, stopOpacity: 1 }),
|
|
13746
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("stop", { offset: "60%", stopColor: ACCENT_GLOW, stopOpacity: 0.45 }),
|
|
13747
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("stop", { offset: "100%", stopColor: ACCENT_GLOW, stopOpacity: 0 })
|
|
13748
|
-
] }) }),
|
|
13749
13748
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
13750
13749
|
import_framer_motion5.motion.ellipse,
|
|
13751
13750
|
{
|
|
13752
13751
|
cx,
|
|
13753
13752
|
cy,
|
|
13754
|
-
rx: w / 2 +
|
|
13755
|
-
ry: h / 2 +
|
|
13756
|
-
fill:
|
|
13753
|
+
rx: w / 2 + 10,
|
|
13754
|
+
ry: h / 2 + 10,
|
|
13755
|
+
fill: ACCENT_GLOW,
|
|
13757
13756
|
style: {
|
|
13758
13757
|
transformOrigin: `${cx}px ${cy}px`,
|
|
13759
|
-
transformBox: "fill-box"
|
|
13758
|
+
transformBox: "fill-box",
|
|
13759
|
+
filter: "blur(16px)"
|
|
13760
13760
|
},
|
|
13761
13761
|
initial: { opacity: 0, scale: 0.95 },
|
|
13762
13762
|
animate: {
|
|
@@ -13887,7 +13887,7 @@ function Bracket({
|
|
|
13887
13887
|
}
|
|
13888
13888
|
|
|
13889
13889
|
// src/components/TutorMode/CalloutArrow.tsx
|
|
13890
|
-
var
|
|
13890
|
+
var import_react56 = require("react");
|
|
13891
13891
|
var import_framer_motion6 = require("framer-motion");
|
|
13892
13892
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
13893
13893
|
function centerOf(b) {
|
|
@@ -13925,7 +13925,7 @@ function arrowPath(from, to, curve) {
|
|
|
13925
13925
|
return `M ${from.x} ${from.y} Q ${cx} ${cy} ${to.x} ${to.y}`;
|
|
13926
13926
|
}
|
|
13927
13927
|
function CalloutArrow({ fromBbox, toBbox, action }) {
|
|
13928
|
-
const markerId = (0,
|
|
13928
|
+
const markerId = (0, import_react56.useId)();
|
|
13929
13929
|
const glowId = `${markerId}-glow`;
|
|
13930
13930
|
const { from, to } = edgePoints(fromBbox, toBbox);
|
|
13931
13931
|
const d = arrowPath(from, to, action.curve);
|
|
@@ -14098,9 +14098,8 @@ function CinemaLayer({
|
|
|
14098
14098
|
page,
|
|
14099
14099
|
index,
|
|
14100
14100
|
overlays,
|
|
14101
|
-
|
|
14101
|
+
scale
|
|
14102
14102
|
}) {
|
|
14103
|
-
if (overlays.length === 0) return null;
|
|
14104
14103
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
14105
14104
|
"div",
|
|
14106
14105
|
{
|
|
@@ -14109,7 +14108,7 @@ function CinemaLayer({
|
|
|
14109
14108
|
position: "absolute",
|
|
14110
14109
|
inset: 0,
|
|
14111
14110
|
transformOrigin: "0 0",
|
|
14112
|
-
transform: `scale(${
|
|
14111
|
+
transform: `scale(${scale})`,
|
|
14113
14112
|
width: page.page_dimensions.width,
|
|
14114
14113
|
height: page.page_dimensions.height,
|
|
14115
14114
|
pointerEvents: "none",
|
|
@@ -14699,8 +14698,7 @@ function LabelOverlay({
|
|
|
14699
14698
|
index,
|
|
14700
14699
|
currentPage,
|
|
14701
14700
|
camera,
|
|
14702
|
-
viewport
|
|
14703
|
-
coordScale
|
|
14701
|
+
viewport
|
|
14704
14702
|
}) {
|
|
14705
14703
|
const labels = overlays.filter((o) => o.kind === "label");
|
|
14706
14704
|
const page = index.byPage.get(currentPage);
|
|
@@ -14727,8 +14725,7 @@ function LabelOverlay({
|
|
|
14727
14725
|
a.position,
|
|
14728
14726
|
page,
|
|
14729
14727
|
camera,
|
|
14730
|
-
viewport
|
|
14731
|
-
coordScale
|
|
14728
|
+
viewport
|
|
14732
14729
|
);
|
|
14733
14730
|
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
14734
14731
|
StickyLabel,
|
|
@@ -14742,7 +14739,7 @@ function LabelOverlay({
|
|
|
14742
14739
|
}
|
|
14743
14740
|
);
|
|
14744
14741
|
}
|
|
14745
|
-
function computeScreenAnchor(bbox, where, page, camera, viewport
|
|
14742
|
+
function computeScreenAnchor(bbox, where, page, camera, viewport) {
|
|
14746
14743
|
const [x1, y1, x2, y2] = bbox;
|
|
14747
14744
|
const pageCX = page.page_dimensions.width / 2;
|
|
14748
14745
|
const pageCY = page.page_dimensions.height / 2;
|
|
@@ -14768,8 +14765,8 @@ function computeScreenAnchor(bbox, where, page, camera, viewport, coordScale) {
|
|
|
14768
14765
|
px = (x1 + x2) / 2;
|
|
14769
14766
|
py = y1;
|
|
14770
14767
|
}
|
|
14771
|
-
const screenX = viewport.width / 2 + camera.x + (px - pageCX) *
|
|
14772
|
-
const screenY = viewport.height / 2 + camera.y + (py - pageCY) *
|
|
14768
|
+
const screenX = viewport.width / 2 + camera.x + (px - pageCX) * camera.scale;
|
|
14769
|
+
const screenY = viewport.height / 2 + camera.y + (py - pageCY) * camera.scale;
|
|
14773
14770
|
return { x: screenX, y: screenY };
|
|
14774
14771
|
}
|
|
14775
14772
|
|
|
@@ -14781,8 +14778,7 @@ function CalloutLabelOverlay({
|
|
|
14781
14778
|
index,
|
|
14782
14779
|
currentPage,
|
|
14783
14780
|
camera,
|
|
14784
|
-
viewport
|
|
14785
|
-
coordScale
|
|
14781
|
+
viewport
|
|
14786
14782
|
}) {
|
|
14787
14783
|
const callouts = overlays.filter(
|
|
14788
14784
|
(o) => o.kind === "callout" && o.action.label
|
|
@@ -14811,8 +14807,7 @@ function CalloutLabelOverlay({
|
|
|
14811
14807
|
toHit.block.bbox,
|
|
14812
14808
|
page,
|
|
14813
14809
|
camera,
|
|
14814
|
-
viewport
|
|
14815
|
-
coordScale
|
|
14810
|
+
viewport
|
|
14816
14811
|
);
|
|
14817
14812
|
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
14818
14813
|
CalloutLabelPill,
|
|
@@ -14827,7 +14822,7 @@ function CalloutLabelOverlay({
|
|
|
14827
14822
|
}
|
|
14828
14823
|
);
|
|
14829
14824
|
}
|
|
14830
|
-
function computePillAnchor(fromBbox, toBbox, page, camera, viewport
|
|
14825
|
+
function computePillAnchor(fromBbox, toBbox, page, camera, viewport) {
|
|
14831
14826
|
const aCX = (fromBbox[0] + fromBbox[2]) / 2;
|
|
14832
14827
|
const aCY = (fromBbox[1] + fromBbox[3]) / 2;
|
|
14833
14828
|
const bCX = (toBbox[0] + toBbox[2]) / 2;
|
|
@@ -14844,8 +14839,8 @@ function computePillAnchor(fromBbox, toBbox, page, camera, viewport, coordScale)
|
|
|
14844
14839
|
const toY = bCY - uy * bOff;
|
|
14845
14840
|
const pageCX = page.page_dimensions.width / 2;
|
|
14846
14841
|
const pageCY = page.page_dimensions.height / 2;
|
|
14847
|
-
const tipScreenX = viewport.width / 2 + camera.x + (toX - pageCX) *
|
|
14848
|
-
const tipScreenY = viewport.height / 2 + camera.y + (toY - pageCY) *
|
|
14842
|
+
const tipScreenX = viewport.width / 2 + camera.x + (toX - pageCX) * camera.scale;
|
|
14843
|
+
const tipScreenY = viewport.height / 2 + camera.y + (toY - pageCY) * camera.scale;
|
|
14849
14844
|
const isVertical = Math.abs(dy) >= Math.abs(dx);
|
|
14850
14845
|
const OFFSET = resolvePillOffset(viewport.width);
|
|
14851
14846
|
const MAX_PILL_W = resolveMaxPillW(viewport.width);
|
|
@@ -14988,41 +14983,6 @@ function SubtitleBar({ text }) {
|
|
|
14988
14983
|
) : null });
|
|
14989
14984
|
}
|
|
14990
14985
|
|
|
14991
|
-
// src/utils/render-scale.ts
|
|
14992
|
-
function computeFitScale(input) {
|
|
14993
|
-
const { pageWidthPt, pageHeightPt, viewport, paddingFactor = 0.95 } = input;
|
|
14994
|
-
if (!Number.isFinite(pageWidthPt) || !Number.isFinite(pageHeightPt) || pageWidthPt <= 0 || pageHeightPt <= 0) {
|
|
14995
|
-
return 1;
|
|
14996
|
-
}
|
|
14997
|
-
const w = Math.max(1, viewport.width);
|
|
14998
|
-
const h = Math.max(1, viewport.height);
|
|
14999
|
-
const fit = Math.min(w / pageWidthPt, h / pageHeightPt) * paddingFactor;
|
|
15000
|
-
return Number.isFinite(fit) && fit > 0 ? fit : 1;
|
|
15001
|
-
}
|
|
15002
|
-
function computeCoordScale(input) {
|
|
15003
|
-
const { renderScale, dpi } = input;
|
|
15004
|
-
if (!Number.isFinite(renderScale) || renderScale <= 0) return 0;
|
|
15005
|
-
if (!Number.isFinite(dpi) || dpi <= 0) return 1;
|
|
15006
|
-
return renderScale * 72 / dpi;
|
|
15007
|
-
}
|
|
15008
|
-
function isTouchDevice() {
|
|
15009
|
-
if (typeof window === "undefined") return false;
|
|
15010
|
-
if (typeof window.matchMedia !== "function") return false;
|
|
15011
|
-
try {
|
|
15012
|
-
return window.matchMedia("(pointer: coarse)").matches;
|
|
15013
|
-
} catch {
|
|
15014
|
-
return false;
|
|
15015
|
-
}
|
|
15016
|
-
}
|
|
15017
|
-
function resolveRenderScale(input) {
|
|
15018
|
-
const { renderScaleProp, scaleProp, defaultRenderScale } = input;
|
|
15019
|
-
if (Number.isFinite(renderScaleProp) && renderScaleProp > 0) {
|
|
15020
|
-
return renderScaleProp;
|
|
15021
|
-
}
|
|
15022
|
-
const multiplier = Number.isFinite(scaleProp) && scaleProp > 0 ? scaleProp : 1;
|
|
15023
|
-
return defaultRenderScale * multiplier;
|
|
15024
|
-
}
|
|
15025
|
-
|
|
15026
14986
|
// src/director/storyboard-engine.ts
|
|
15027
14987
|
init_narration_store();
|
|
15028
14988
|
init_camera_math();
|
|
@@ -15119,14 +15079,18 @@ var StoryboardEngine = class {
|
|
|
15119
15079
|
this.overlayRemovalTimers.clear();
|
|
15120
15080
|
}
|
|
15121
15081
|
/**
|
|
15122
|
-
* Full destructor — cancels
|
|
15123
|
-
* timers. Use this in component unmount/cleanup.
|
|
15124
|
-
*
|
|
15125
|
-
*
|
|
15126
|
-
*
|
|
15082
|
+
* Full destructor — cancels BOTH pending step timers AND overlay
|
|
15083
|
+
* removal timers. Use this in component unmount / cleanup.
|
|
15084
|
+
*
|
|
15085
|
+
* The per-storyboard `cancelPending()` deliberately leaves overlay
|
|
15086
|
+
* removal timers alone so a mid-flight overlay doesn't get stranded
|
|
15087
|
+
* when a new storyboard arrives (see `overlayRemovalTimers` doc).
|
|
15088
|
+
* That invariant is correct inside a session, but at teardown we
|
|
15089
|
+
* must release every timer — otherwise their setTimeout closures
|
|
15127
15090
|
* keep `deps` (narrationStore, the full bboxIndex) alive beyond the
|
|
15128
|
-
* lifetime of this engine.
|
|
15129
|
-
*
|
|
15091
|
+
* lifetime of this engine. Over many component recreations on iOS
|
|
15092
|
+
* Safari (viewport state churns during address-bar scroll
|
|
15093
|
+
* animation), that cumulative retention contributes to tab reloads.
|
|
15130
15094
|
*/
|
|
15131
15095
|
destroy() {
|
|
15132
15096
|
this.cancelPending();
|
|
@@ -16279,70 +16243,42 @@ function TutorModeContainer({
|
|
|
16279
16243
|
loadingComponent,
|
|
16280
16244
|
onPageChange,
|
|
16281
16245
|
storyboardProvider,
|
|
16282
|
-
renderScale,
|
|
16283
16246
|
className
|
|
16284
16247
|
}) {
|
|
16285
|
-
const containerRef = (0,
|
|
16286
|
-
const index = (0,
|
|
16248
|
+
const containerRef = (0, import_react57.useRef)(null);
|
|
16249
|
+
const index = (0, import_react57.useMemo)(() => buildBBoxIndex(bboxData), [bboxData]);
|
|
16287
16250
|
const {
|
|
16288
16251
|
document: document2,
|
|
16289
16252
|
currentPage: viewerCurrentPage,
|
|
16290
16253
|
numPages,
|
|
16291
16254
|
goToPage: viewerGoToPage
|
|
16292
16255
|
} = usePDFViewer();
|
|
16293
|
-
const [pageProxy, setPageProxy] = (0,
|
|
16294
|
-
const [viewport, setViewport] = (0,
|
|
16256
|
+
const [pageProxy, setPageProxy] = (0, import_react57.useState)(null);
|
|
16257
|
+
const [viewport, setViewport] = (0, import_react57.useState)({ width: 800, height: 1e3 });
|
|
16295
16258
|
const camera = (0, import_zustand2.useStore)(narrationStore, (s) => s.camera);
|
|
16296
16259
|
const activeOverlays = (0, import_zustand2.useStore)(narrationStore, (s) => s.activeOverlays);
|
|
16297
|
-
|
|
16298
|
-
const pagePointsW = page ? page.page_dimensions.width * 72 / page.page_dimensions.dpi : 0;
|
|
16299
|
-
const pagePointsH = page ? page.page_dimensions.height * 72 / page.page_dimensions.dpi : 0;
|
|
16300
|
-
const touch = isTouchDevice();
|
|
16301
|
-
const defaultRenderScale = page ? touch ? computeFitScale({
|
|
16302
|
-
pageWidthPt: pagePointsW,
|
|
16303
|
-
pageHeightPt: pagePointsH,
|
|
16304
|
-
viewport
|
|
16305
|
-
}) : page.page_dimensions.dpi / 72 : 1;
|
|
16306
|
-
const effectiveRenderScale = resolveRenderScale({
|
|
16307
|
-
renderScaleProp: renderScale,
|
|
16308
|
-
scaleProp: scale,
|
|
16309
|
-
defaultRenderScale
|
|
16310
|
-
});
|
|
16311
|
-
const coordScale = page ? computeCoordScale({
|
|
16312
|
-
renderScale: effectiveRenderScale,
|
|
16313
|
-
dpi: page.page_dimensions.dpi
|
|
16314
|
-
}) : 1;
|
|
16315
|
-
const rasterScale = effectiveRenderScale;
|
|
16316
|
-
const baseW = pagePointsW * effectiveRenderScale;
|
|
16317
|
-
const baseH = pagePointsH * effectiveRenderScale;
|
|
16318
|
-
(0, import_react58.useEffect)(() => {
|
|
16260
|
+
(0, import_react57.useEffect)(() => {
|
|
16319
16261
|
if (numPages <= 0) return;
|
|
16320
16262
|
if (pageNumber < 1 || pageNumber > numPages) return;
|
|
16321
16263
|
if (viewerCurrentPage === pageNumber) return;
|
|
16322
16264
|
viewerGoToPage(pageNumber);
|
|
16323
16265
|
}, [pageNumber, numPages, viewerCurrentPage, viewerGoToPage]);
|
|
16324
|
-
(0,
|
|
16266
|
+
(0, import_react57.useEffect)(() => {
|
|
16325
16267
|
if (!onPageChange) return;
|
|
16326
16268
|
if (viewerCurrentPage === pageNumber) return;
|
|
16327
16269
|
if (viewerCurrentPage < 1) return;
|
|
16328
16270
|
onPageChange(viewerCurrentPage);
|
|
16329
16271
|
}, [viewerCurrentPage, pageNumber, onPageChange]);
|
|
16330
|
-
(0,
|
|
16272
|
+
(0, import_react57.useEffect)(() => {
|
|
16331
16273
|
if (!containerRef.current) return;
|
|
16332
16274
|
const el = containerRef.current;
|
|
16333
|
-
const update = () => {
|
|
16334
|
-
const w = el.clientWidth;
|
|
16335
|
-
const h = el.clientHeight;
|
|
16336
|
-
setViewport(
|
|
16337
|
-
(prev) => prev.width === w && prev.height === h ? prev : { width: w, height: h }
|
|
16338
|
-
);
|
|
16339
|
-
};
|
|
16275
|
+
const update = () => setViewport({ width: el.clientWidth, height: el.clientHeight });
|
|
16340
16276
|
update();
|
|
16341
16277
|
const ro = new ResizeObserver(update);
|
|
16342
16278
|
ro.observe(el);
|
|
16343
16279
|
return () => ro.disconnect();
|
|
16344
16280
|
}, []);
|
|
16345
|
-
(0,
|
|
16281
|
+
(0, import_react57.useEffect)(() => {
|
|
16346
16282
|
if (!document2) {
|
|
16347
16283
|
setPageProxy(null);
|
|
16348
16284
|
return;
|
|
@@ -16357,40 +16293,34 @@ function TutorModeContainer({
|
|
|
16357
16293
|
cancelled = true;
|
|
16358
16294
|
};
|
|
16359
16295
|
}, [document2, pageNumber]);
|
|
16360
|
-
(0,
|
|
16296
|
+
(0, import_react57.useEffect)(() => {
|
|
16361
16297
|
narrationStore.getState().setCurrentPage(pageNumber);
|
|
16362
16298
|
}, [pageNumber, narrationStore]);
|
|
16363
|
-
(0,
|
|
16299
|
+
(0, import_react57.useEffect)(() => {
|
|
16364
16300
|
const page2 = index.byPage.get(pageNumber);
|
|
16365
16301
|
if (!page2) return;
|
|
16366
16302
|
if (viewport.width === 0 || viewport.height === 0) return;
|
|
16367
|
-
if (baseW === 0 || baseH === 0) return;
|
|
16368
16303
|
if (narrationStore.getState().activeOverlays.length > 0) return;
|
|
16369
|
-
const fit = Math.min(
|
|
16304
|
+
const fit = Math.min(
|
|
16305
|
+
viewport.width / page2.page_dimensions.width,
|
|
16306
|
+
viewport.height / page2.page_dimensions.height
|
|
16307
|
+
) * 0.95;
|
|
16370
16308
|
narrationStore.getState().setCamera({ scale: fit, x: 0, y: 0 });
|
|
16371
|
-
}, [pageNumber, viewport, index, narrationStore
|
|
16372
|
-
const
|
|
16373
|
-
(0,
|
|
16374
|
-
|
|
16375
|
-
}, [viewport]);
|
|
16376
|
-
const engineRef = (0, import_react58.useRef)(null);
|
|
16377
|
-
(0, import_react58.useEffect)(() => {
|
|
16378
|
-
const engine = new StoryboardEngine({
|
|
16309
|
+
}, [pageNumber, viewport, index, narrationStore]);
|
|
16310
|
+
const engineRef = (0, import_react57.useRef)(null);
|
|
16311
|
+
(0, import_react57.useEffect)(() => {
|
|
16312
|
+
engineRef.current = new StoryboardEngine({
|
|
16379
16313
|
narrationStore,
|
|
16380
16314
|
bboxIndex: index,
|
|
16381
|
-
getViewport: () =>
|
|
16315
|
+
getViewport: () => viewport,
|
|
16382
16316
|
minOverlayDurationMs
|
|
16383
16317
|
});
|
|
16384
|
-
engineRef.current
|
|
16385
|
-
|
|
16386
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
const abortRef = (0, import_react58.useRef)(null);
|
|
16391
|
-
const debounceRef = (0, import_react58.useRef)(null);
|
|
16392
|
-
const lastChunkRef = (0, import_react58.useRef)(null);
|
|
16393
|
-
(0, import_react58.useEffect)(() => {
|
|
16318
|
+
return () => engineRef.current?.destroy();
|
|
16319
|
+
}, [narrationStore, index, viewport, minOverlayDurationMs]);
|
|
16320
|
+
const abortRef = (0, import_react57.useRef)(null);
|
|
16321
|
+
const debounceRef = (0, import_react57.useRef)(null);
|
|
16322
|
+
const lastChunkRef = (0, import_react57.useRef)(null);
|
|
16323
|
+
(0, import_react57.useEffect)(() => {
|
|
16394
16324
|
if (!storyboardProvider && !llm) return;
|
|
16395
16325
|
if (!currentChunk || currentChunk === lastChunkRef.current) return;
|
|
16396
16326
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
@@ -16555,7 +16485,7 @@ function TutorModeContainer({
|
|
|
16555
16485
|
embeddingProvider,
|
|
16556
16486
|
llmTimeoutMs
|
|
16557
16487
|
]);
|
|
16558
|
-
(0,
|
|
16488
|
+
(0, import_react57.useEffect)(() => {
|
|
16559
16489
|
if (!currentChunk) return;
|
|
16560
16490
|
const t = setTimeout(() => {
|
|
16561
16491
|
if (!engineRef.current) return;
|
|
@@ -16567,6 +16497,11 @@ function TutorModeContainer({
|
|
|
16567
16497
|
}, idleTimeoutMs + 100);
|
|
16568
16498
|
return () => clearTimeout(t);
|
|
16569
16499
|
}, [currentChunk, idleTimeoutMs, narrationStore]);
|
|
16500
|
+
const page = index.byPage.get(pageNumber);
|
|
16501
|
+
const dpiScale = page ? page.page_dimensions.dpi / 72 : 1;
|
|
16502
|
+
const rasterScale = dpiScale * (scale || 1);
|
|
16503
|
+
const baseW = page ? page.page_dimensions.width * (scale || 1) : 0;
|
|
16504
|
+
const baseH = page ? page.page_dimensions.height * (scale || 1) : 0;
|
|
16570
16505
|
const isReady = !!page && !!pageProxy;
|
|
16571
16506
|
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
16572
16507
|
"div",
|
|
@@ -16645,7 +16580,7 @@ function TutorModeContainer({
|
|
|
16645
16580
|
page,
|
|
16646
16581
|
index,
|
|
16647
16582
|
overlays: activeOverlays,
|
|
16648
|
-
|
|
16583
|
+
scale: scale || 1
|
|
16649
16584
|
}
|
|
16650
16585
|
)
|
|
16651
16586
|
]
|
|
@@ -16658,8 +16593,7 @@ function TutorModeContainer({
|
|
|
16658
16593
|
index,
|
|
16659
16594
|
currentPage: pageNumber,
|
|
16660
16595
|
camera,
|
|
16661
|
-
viewport
|
|
16662
|
-
coordScale
|
|
16596
|
+
viewport
|
|
16663
16597
|
}
|
|
16664
16598
|
),
|
|
16665
16599
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
@@ -16669,8 +16603,7 @@ function TutorModeContainer({
|
|
|
16669
16603
|
index,
|
|
16670
16604
|
currentPage: pageNumber,
|
|
16671
16605
|
camera,
|
|
16672
|
-
viewport
|
|
16673
|
-
coordScale
|
|
16606
|
+
viewport
|
|
16674
16607
|
}
|
|
16675
16608
|
),
|
|
16676
16609
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(GhostReferenceOverlay, { overlays: activeOverlays, index })
|