{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-zoom.ts","../../src/shared/utils/zoom-gesture-logic.ts","../../src/shared/hooks/use-zoom-gesture.ts","../../src/shared/components/marquee-zoom.tsx","../../src/shared/components/zoom-gesture-wrapper.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialDocumentState, ZoomDocumentState, ZoomPlugin } from '@embedpdf/plugin-zoom';\nimport { useEffect, useState } from '@framework';\n\nexport const useZoomCapability = () => useCapability<ZoomPlugin>(ZoomPlugin.id);\nexport const useZoomPlugin = () => usePlugin<ZoomPlugin>(ZoomPlugin.id);\n\n/**\n * Hook for zoom state for a specific document\n * @param documentId Document ID\n */\nexport const useZoom = (documentId: string) => {\n  const { provides } = useZoomCapability();\n  const [state, setState] = useState<ZoomDocumentState>(initialDocumentState);\n\n  useEffect(() => {\n    if (!provides) return;\n\n    const scope = provides.forDocument(documentId);\n\n    // Get initial state\n    setState(scope.getState());\n\n    // Subscribe to state changes\n    return scope.onStateChange((newState) => {\n      setState(newState);\n    });\n  }, [provides, documentId]);\n\n  return {\n    state,\n    provides: provides?.forDocument(documentId) ?? null,\n  };\n};\n","import type { ZoomCapability } from '@embedpdf/plugin-zoom';\n\nexport interface ZoomGestureOptions {\n  /** Enable pinch-to-zoom gesture (default: true) */\n  enablePinch?: boolean;\n  /** Enable wheel zoom with ctrl/cmd key (default: true) */\n  enableWheel?: boolean;\n}\n\nexport interface ZoomGestureDeps {\n  element: HTMLDivElement;\n  /** Viewport container element for attaching events */\n  container: HTMLElement;\n  documentId: string;\n  zoomProvides: ZoomCapability;\n  /** Viewport gap in pixels (default: 0) */\n  viewportGap?: number;\n  options?: ZoomGestureOptions;\n}\n\nfunction getTouchDistance(touches: TouchList): number {\n  const [t1, t2] = [touches[0], touches[1]];\n  const dx = t2.clientX - t1.clientX;\n  const dy = t2.clientY - t1.clientY;\n  return Math.hypot(dx, dy);\n}\n\nfunction getTouchCenter(touches: TouchList): { x: number; y: number } {\n  const [t1, t2] = [touches[0], touches[1]];\n  return {\n    x: (t1.clientX + t2.clientX) / 2,\n    y: (t1.clientY + t2.clientY) / 2,\n  };\n}\n\nexport function setupZoomGestures({\n  element,\n  container,\n  documentId,\n  zoomProvides,\n  viewportGap = 0,\n  options = {},\n}: ZoomGestureDeps) {\n  const { enablePinch = true, enableWheel = true } = options;\n  if (typeof window === 'undefined') {\n    return () => {};\n  }\n\n  const zoomScope = zoomProvides.forDocument(documentId);\n  const getState = () => zoomScope.getState();\n\n  // Shared state\n  let initialZoom = 0;\n  let currentScale = 1;\n  let isPinching = false;\n  let initialDistance = 0;\n\n  // Wheel state\n  let wheelZoomTimeout: ReturnType<typeof setTimeout> | null = null;\n  let accumulatedWheelScale = 1;\n\n  // Gesture state\n  let initialElementWidth = 0;\n  let initialElementHeight = 0;\n  let initialElementLeft = 0;\n  let initialElementTop = 0;\n\n  // Container Dimensions (Bounding Box)\n  let containerRectWidth = 0;\n  let containerRectHeight = 0;\n\n  // Layout Dimensions (Client Box from Metrics)\n  let layoutWidth = 0;\n  let layoutCenterX = 0;\n\n  let pointerLocalY = 0;\n  let pointerContainerX = 0;\n  let pointerContainerY = 0;\n\n  let currentGap = 0;\n  let pivotLocalX = 0;\n\n  const clamp = (val: number, min: number, max: number) => Math.min(Math.max(val, min), max);\n\n  // --- Margin calculation ---\n  const updateMargin = () => {\n    const availableWidth = container.clientWidth - 2 * viewportGap;\n    const elementWidth = element.offsetWidth;\n\n    const newMargin = elementWidth < availableWidth ? (availableWidth - elementWidth) / 2 : 0;\n    element.style.marginLeft = `${newMargin}px`;\n  };\n\n  const calculateTransform = (scale: number) => {\n    const finalWidth = initialElementWidth * scale;\n    const finalHeight = initialElementHeight * scale;\n\n    let ty = pointerLocalY * (1 - scale);\n\n    const targetX = layoutCenterX - finalWidth / 2;\n    const txCenter = targetX - initialElementLeft;\n    const txMouse = pointerContainerX - pivotLocalX * scale - initialElementLeft;\n\n    const overflow = Math.max(0, finalWidth - layoutWidth);\n    const blendRange = layoutWidth * 0.3;\n    const blend = Math.min(1, overflow / blendRange);\n\n    let tx = txCenter + (txMouse - txCenter) * blend;\n\n    const safeHeight = containerRectHeight - currentGap * 2;\n    if (finalHeight > safeHeight) {\n      const currentTop = initialElementTop + ty;\n      const maxTop = currentGap;\n      const minTop = containerRectHeight - currentGap - finalHeight;\n      const constrainedTop = clamp(currentTop, minTop, maxTop);\n      ty = constrainedTop - initialElementTop;\n    }\n\n    const safeWidth = containerRectWidth - currentGap * 2;\n    if (finalWidth > safeWidth) {\n      const currentLeft = initialElementLeft + tx;\n      const maxLeft = currentGap;\n      const minLeft = containerRectWidth - currentGap - finalWidth;\n      const constrainedLeft = clamp(currentLeft, minLeft, maxLeft);\n      tx = constrainedLeft - initialElementLeft;\n    }\n\n    return { tx, ty, blend, finalWidth };\n  };\n\n  const updateTransform = (scale: number) => {\n    currentScale = scale;\n    const { tx, ty } = calculateTransform(scale);\n    element.style.transformOrigin = '0 0';\n    element.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;\n  };\n\n  const resetTransform = () => {\n    element.style.transform = 'none';\n    element.style.transformOrigin = '0 0';\n    currentScale = 1;\n  };\n\n  const commitZoom = () => {\n    const { tx, finalWidth } = calculateTransform(currentScale);\n    const delta = (currentScale - 1) * initialZoom;\n\n    let anchorX: number;\n    let anchorY: number = pointerContainerY;\n\n    if (finalWidth <= layoutWidth) {\n      anchorX = layoutCenterX;\n    } else {\n      const scaleDiff = 1 - currentScale;\n      anchorX =\n        Math.abs(scaleDiff) > 0.001 ? initialElementLeft + tx / scaleDiff : pointerContainerX;\n    }\n\n    zoomScope.requestZoomBy(delta, { vx: anchorX, vy: anchorY });\n    resetTransform();\n    initialZoom = 0;\n  };\n\n  const initializeGestureState = (clientX: number, clientY: number) => {\n    const containerRect = container.getBoundingClientRect();\n    const innerRect = element.getBoundingClientRect();\n\n    currentGap = viewportGap;\n    initialElementWidth = innerRect.width;\n    initialElementHeight = innerRect.height;\n    initialElementLeft = innerRect.left - containerRect.left;\n    initialElementTop = innerRect.top - containerRect.top;\n\n    containerRectWidth = containerRect.width;\n    containerRectHeight = containerRect.height;\n\n    // Layout dimensions from container's client area\n    layoutWidth = container.clientWidth;\n    layoutCenterX = container.clientLeft + layoutWidth / 2;\n\n    const rawPointerLocalX = clientX - innerRect.left;\n    pointerLocalY = clientY - innerRect.top;\n    pointerContainerX = clientX - containerRect.left;\n    pointerContainerY = clientY - containerRect.top;\n\n    if (initialElementWidth < layoutWidth) {\n      pivotLocalX = (pointerContainerX * initialElementWidth) / layoutWidth;\n    } else {\n      pivotLocalX = rawPointerLocalX;\n    }\n  };\n\n  // --- Handlers ---\n  const handleTouchStart = (e: TouchEvent) => {\n    if (e.touches.length !== 2) return;\n    isPinching = true;\n    initialZoom = getState().currentZoomLevel;\n    initialDistance = getTouchDistance(e.touches);\n    const center = getTouchCenter(e.touches);\n    initializeGestureState(center.x, center.y);\n    e.preventDefault();\n  };\n\n  const handleTouchMove = (e: TouchEvent) => {\n    if (!isPinching || e.touches.length !== 2) return;\n    const currentDistance = getTouchDistance(e.touches);\n    const scale = currentDistance / initialDistance;\n    updateTransform(scale);\n    e.preventDefault();\n  };\n\n  const handleTouchEnd = (e: TouchEvent) => {\n    if (!isPinching) return;\n    if (e.touches.length >= 2) return;\n    isPinching = false;\n    commitZoom();\n  };\n\n  const handleWheel = (e: WheelEvent) => {\n    if (!e.ctrlKey && !e.metaKey) return;\n    e.preventDefault();\n\n    if (wheelZoomTimeout === null) {\n      initialZoom = getState().currentZoomLevel;\n      accumulatedWheelScale = 1;\n      initializeGestureState(e.clientX, e.clientY);\n    } else {\n      clearTimeout(wheelZoomTimeout);\n    }\n\n    const zoomFactor = 1 - e.deltaY * 0.01;\n    accumulatedWheelScale *= zoomFactor;\n    accumulatedWheelScale = Math.max(0.1, Math.min(10, accumulatedWheelScale));\n    updateTransform(accumulatedWheelScale);\n\n    wheelZoomTimeout = setTimeout(() => {\n      wheelZoomTimeout = null;\n      commitZoom();\n      accumulatedWheelScale = 1;\n    }, 150);\n  };\n\n  // Subscribe to zoom changes to update margin\n  const unsubZoom = zoomScope.onStateChange(() => updateMargin());\n\n  // Use ResizeObserver to update margin when element or container size changes\n  const resizeObserver = new ResizeObserver(() => updateMargin());\n  resizeObserver.observe(element);\n  resizeObserver.observe(container);\n\n  // Initial margin calculation\n  updateMargin();\n\n  // Attach events to the viewport container for better UX\n  // (gestures work anywhere in viewport, not just on the PDF)\n  if (enablePinch) {\n    container.addEventListener('touchstart', handleTouchStart, { passive: false });\n    container.addEventListener('touchmove', handleTouchMove, { passive: false });\n    container.addEventListener('touchend', handleTouchEnd);\n    container.addEventListener('touchcancel', handleTouchEnd);\n  }\n  if (enableWheel) {\n    container.addEventListener('wheel', handleWheel, { passive: false });\n  }\n\n  return () => {\n    if (enablePinch) {\n      container.removeEventListener('touchstart', handleTouchStart);\n      container.removeEventListener('touchmove', handleTouchMove);\n      container.removeEventListener('touchend', handleTouchEnd);\n      container.removeEventListener('touchcancel', handleTouchEnd);\n    }\n    if (enableWheel) {\n      container.removeEventListener('wheel', handleWheel);\n    }\n    if (wheelZoomTimeout) {\n      clearTimeout(wheelZoomTimeout);\n    }\n    unsubZoom();\n    resizeObserver.disconnect();\n    resetTransform();\n    element.style.marginLeft = '';\n  };\n}\n","import { useLayoutEffect, useRef } from '@framework';\nimport { useCapability } from '@embedpdf/core/@framework';\nimport { ViewportPlugin, useViewportElement } from '@embedpdf/plugin-viewport/@framework';\nimport { setupZoomGestures, ZoomGestureOptions } from '../utils/zoom-gesture-logic';\nimport { useZoomCapability } from './use-zoom';\n\nexport type { ZoomGestureOptions };\n\nexport function useZoomGesture(documentId: string, options: ZoomGestureOptions = {}) {\n  const { provides: viewportProvides } = useCapability<ViewportPlugin>('viewport');\n  const { provides: zoomProvides } = useZoomCapability();\n  const viewportElementRef = useViewportElement();\n  const elementRef = useRef<HTMLDivElement>(null);\n\n  // Use useLayoutEffect to set up zoom gestures synchronously before paint\n  // This prevents flashing and layout jumps that occur with useEffect\n  useLayoutEffect(() => {\n    const element = elementRef.current;\n    const container = viewportElementRef?.current;\n\n    if (!element || !container || !zoomProvides) {\n      return;\n    }\n\n    return setupZoomGestures({\n      element,\n      container,\n      documentId,\n      zoomProvides,\n      viewportGap: viewportProvides?.getViewportGap() || 0,\n      options,\n    });\n  }, [\n    viewportProvides,\n    zoomProvides,\n    documentId,\n    viewportElementRef,\n    options.enablePinch,\n    options.enableWheel,\n  ]);\n\n  return { elementRef };\n}\n","import { useEffect, useMemo, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\nimport { useZoomCapability } from '../hooks/use-zoom';\nimport { useDocumentState } from '@embedpdf/core/@framework';\n\ninterface MarqueeZoomProps {\n  documentId: string;\n  pageIndex: number;\n  scale?: number;\n  className?: string;\n  stroke?: string;\n  fill?: string;\n}\n\nexport const MarqueeZoom = ({\n  documentId,\n  pageIndex,\n  scale: scaleOverride,\n  className,\n  stroke = 'rgba(33,150,243,0.8)',\n  fill = 'rgba(33,150,243,0.15)',\n}: MarqueeZoomProps) => {\n  const { provides: zoomPlugin } = useZoomCapability();\n  const documentState = useDocumentState(documentId);\n  const [rect, setRect] = useState<Rect | null>(null);\n\n  const actualScale = useMemo(() => {\n    if (scaleOverride !== undefined) return scaleOverride;\n    return documentState?.scale ?? 1;\n  }, [scaleOverride, documentState?.scale]);\n\n  useEffect(() => {\n    if (!zoomPlugin) return;\n    return zoomPlugin.registerMarqueeOnPage({\n      documentId,\n      pageIndex,\n      scale: actualScale,\n      callback: {\n        onPreview: setRect,\n      },\n    });\n  }, [zoomPlugin, documentId, pageIndex, actualScale]);\n\n  if (!rect) return null;\n\n  return (\n    <div\n      style={{\n        position: 'absolute',\n        pointerEvents: 'none',\n        left: rect.origin.x * actualScale,\n        top: rect.origin.y * actualScale,\n        width: rect.size.width * actualScale,\n        height: rect.size.height * actualScale,\n        border: `1px solid ${stroke}`,\n        background: fill,\n        boxSizing: 'border-box',\n      }}\n      className={className}\n    />\n  );\n};\n","import { ReactNode, HTMLAttributes, CSSProperties, useMemo } from '@framework';\nimport { useZoomGesture, ZoomGestureOptions } from '../hooks';\n\ntype ZoomGestureWrapperProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n  children: ReactNode;\n  documentId: string;\n  style?: CSSProperties;\n  /** Enable pinch-to-zoom gesture (default: true) */\n  enablePinch?: boolean;\n  /** Enable wheel zoom with ctrl/cmd key (default: true) */\n  enableWheel?: boolean;\n};\n\nexport function ZoomGestureWrapper({\n  children,\n  documentId,\n  style,\n  enablePinch = true,\n  enableWheel = true,\n  ...props\n}: ZoomGestureWrapperProps) {\n  const options = useMemo<ZoomGestureOptions>(\n    () => ({ enablePinch, enableWheel }),\n    [enablePinch, enableWheel],\n  );\n  const { elementRef } = useZoomGesture(documentId, options);\n\n  return (\n    <div\n      ref={elementRef}\n      {...props}\n      style={{\n        ...style,\n        display: 'inline-block',\n        overflow: 'visible',\n        boxSizing: 'border-box',\n      }}\n    >\n      {children}\n    </div>\n  );\n}\n"],"names":["useZoomCapability","useCapability","ZoomPlugin","id","getTouchDistance","touches","t1","t2","dx","clientX","dy","clientY","Math","hypot","useZoomGesture","documentId","options","provides","viewportProvides","zoomProvides","viewportElementRef","useViewportElement","elementRef","useRef","useLayoutEffect","element","current","container","viewportGap","enablePinch","enableWheel","window","zoomScope","forDocument","getState","initialZoom","currentScale","isPinching","initialDistance","wheelZoomTimeout","accumulatedWheelScale","initialElementWidth","initialElementHeight","initialElementLeft","initialElementTop","containerRectWidth","containerRectHeight","layoutWidth","layoutCenterX","pointerLocalY","pointerContainerX","pointerContainerY","currentGap","pivotLocalX","clamp","val","min","max","updateMargin","availableWidth","clientWidth","elementWidth","offsetWidth","newMargin","style","marginLeft","calculateTransform","scale","finalWidth","finalHeight","ty","txCenter","txMouse","overflow","blendRange","blend","tx","updateTransform","transformOrigin","transform","resetTransform","commitZoom","delta","anchorX","anchorY","scaleDiff","abs","requestZoomBy","vx","vy","initializeGestureState","containerRect","getBoundingClientRect","innerRect","width","height","left","top","clientLeft","rawPointerLocalX","handleTouchStart","e","length","currentZoomLevel","center","x","y","getTouchCenter","preventDefault","handleTouchMove","currentDistance","handleTouchEnd","handleWheel","ctrlKey","metaKey","clearTimeout","zoomFactor","deltaY","setTimeout","unsubZoom","onStateChange","resizeObserver","ResizeObserver","observe","addEventListener","passive","removeEventListener","disconnect","setupZoomGestures","getViewportGap","pageIndex","scaleOverride","className","stroke","fill","zoomPlugin","documentState","useDocumentState","rect","setRect","useState","actualScale","useMemo","useEffect","registerMarqueeOnPage","callback","onPreview","jsx","position","pointerEvents","origin","size","border","background","boxSizing","children","props","ref","display","state","setState","initialDocumentState","scope","newState","usePlugin"],"mappings":"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"}